Playing with OSWORD &A

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Playing with OSWORD &A

Post by geraldholdsworth » Mon Apr 27, 2020 2:14 pm

So I decided to go back to 8 bit programming, which I do every so often, and have a play with OSWORD &A (read character definition). At first I wrote, in BASIC, a program to turn a string upside down and position it centrally on the screen. It was kinda slow, so I knocked up this, in assembler:

Code: Select all

   10MODE135
   20DIMcode%&73
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#8
  220.vdu
  230 LDAbuffer%,X
  240 JSR&FFEE
  250 DEX
  260 BNEvdu
  270 LDA#224
  280 JSR&FFEE
  290 PLY
  300 INY
  310 CPY#41
  320 BNEloop
  330.exit
  340 LDA#13
  350 JSR&FFEE
  360 LDA#10
  370 JSR&FFEE
  380 RTS
  390.buffer%EQUS STRING$(9," ")
  400.string%EQUS STRING$(40," "):EQUB13
  410]:NEXT
  420MODE132
  430s$="Upside Down"
  440$string%=s$
  450PRINTTAB((40-LENs$)/2);
  460CALLcode%
My original intention was for double height, so I just adjusted the above code:

Code: Select all

   10MODE135
   20DIMcode%&9D
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#1
  220.vdu
  230 LDAbuffer%,X
  240 JSR&FFEE
  250 JSR&FFEE
  260 CPX#4
  270 BNEcont
  280 LDA#224
  290 JSR&FFEE
  300 LDA#8
  310 JSR&FFEE
  320 LDA#10
  330 JSR&FFEE
  340 LDA#23
  350 JSR&FFEE
  360 LDA#224
  370 JSR&FFEE
  380.cont
  390 INX
  400 CPX#9
  410 BNEvdu
  420 LDA#224
  430 JSR&FFEE
  440 LDA#11
  450 JSR&FFEE
  460 PLY
  470 INY
  480 CPY#41
  490 BNEloop
  500.exit
  510 LDA#13
  520 JSR&FFEE
  530 LDA#10
  540 JSR&FFEE
  550 JSR&FFEE
  560 RTS
  570.buffer%EQUS STRING$(9," ")
  580.string%EQUS STRING$(40," "):EQUB13
  590]:NEXT
  600MODE132
  610s$="Double Height"
  620$string%=s$
  630PRINTTAB((40-LENs$)/2);
  640CALLcode%
And, finally, just for fun, in italics:

Code: Select all

   10MODE135
   20DIMcode%&7D
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#1
  220.vdu
  230 LDAbuffer%,X
  240 CPX#5
  250 BCCcont
  260 ASL A
  270.cont
  280 JSR&FFEE
  290 INX
  300 CPX#9
  310 BNEvdu
  320 LDA#224
  330 JSR&FFEE
  340 PLY
  350 INY
  360 CPY#41
  370 BNEloop
  380.exit
  390 LDA#13
  400 JSR&FFEE
  410 LDA#10
  420 JSR&FFEE
  430 JSR&FFEE
  440 RTS
  450.buffer%EQUS STRING$(9," ")
  460.string%EQUS STRING$(40," "):EQUB13
  470]:NEXT
  480MODE132
  490s$="Italics"
  500$string%=s$
  510PRINTTAB((40-LENs$)/2);
  520CALLcode%
This is all written on a BBC Master (hence the use of shadow screen modes), so I may have used some of the newer mnemonics. Anyway, feel free to pull apart and suggest alternatives/better ways of doing the above (apart from adding comments) - I'm a little rusty, but even when I was programming on a BBC, I still wasn't that great with assembler.
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk

User avatar
tricky
Posts: 4676
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Playing with OSWORD &A

Post by tricky » Mon Apr 27, 2020 2:59 pm

I used that to copy the font for my BasicSpaceInvaders as I was trying to be "legal" until it got too much work :oops:
In Jeltron, I used a similar technique for italics and shifting and anding the top and shifting and oring the bottom to give a "futuristic" font.
Image

User avatar
flaxcottage
Posts: 4256
Joined: Thu Dec 13, 2012 8:46 pm
Location: Derbyshire
Contact:

Re: Playing with OSWORD &A

Post by flaxcottage » Mon Apr 27, 2020 3:00 pm

Nice job.

The BASIC versions really fly when using the Pi 65C02 copro at the fastest setting and on a Pi in RISCOS the BASIC versions are almost instantaneous. Just shows how computing has progressed over the years.
- John

Image

User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Re: Playing with OSWORD &A

Post by geraldholdsworth » Tue Apr 28, 2020 11:58 am

tricky wrote:
Mon Apr 27, 2020 2:59 pm
In Jeltron, I used a similar technique for italics and shifting and anding the top and shifting and oring the bottom to give a "futuristic" font.
Like this?

Code: Select all

   10MODE135
   20DIMcode%&83
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#1
  220.vdu
  230 LDAbuffer%,X
  240 ASL A
  250 CPX#5
  260 BCCtop
  270 ORA buffer%,X
  280 JMPcont
  290.top
  300 AND buffer%,X
  310.cont
  320 JSR&FFEE
  330 INX
  340 CPX#9
  350 BNEvdu
  360 LDA#224
  370 JSR&FFEE
  380 PLY
  390 INY
  400 CPY#41
  410 BNEloop
  420.exit
  430 LDA#13
  440 JSR&FFEE
  450 LDA#10
  460 JSR&FFEE
  470 RTS
  480.buffer%EQUS STRING$(9," ")
  490.string%EQUS STRING$(40," "):EQUB13
  500]:NEXT
  510MODE132
  520s$="Futuristic"
  530$string%=s$
  540PRINTTAB((40-LENs$)/2);
  550CALLcode%
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk

User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Re: Playing with OSWORD &A

Post by geraldholdsworth » Tue Apr 28, 2020 12:00 pm

I've been playing some more (spurred on by the Futuristic font)...

Bold font:

Code: Select all

   10MODE135
   20DIMcode%&79
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#1
  220.vdu
  230 LDAbuffer%,X
  240 ASL A
  250 ORA buffer%,X
  260 JSR&FFEE
  270 INX
  280 CPX#9
  290 BNEvdu
  300 LDA#224
  310 JSR&FFEE
  320 PLY
  330 INY
  340 CPY#41
  350 BNEloop
  360.exit
  370 LDA#13
  380 JSR&FFEE
  390 LDA#10
  400 JSR&FFEE
  410 RTS
  420.buffer%EQUS STRING$(9," ")
  430.string%EQUS STRING$(40," "):EQUB13
  440]:NEXT
  450MODE132
  460s$="Bold"
  470$string%=s$
  480PRINTTAB((40-LENs$)/2);
  490CALLcode%
Thin font:

Code: Select all

   10MODE135
   20DIMcode%&79
   30FORo%=0TO2STEP2
   40P%=code%
   50[OPTo%
   60 LDY#0
   70.loop
   80 LDA string%,Y
   90 CMP#13
  100 BEQexit
  110 STA buffer%
  120 PHY
  130 LDA#&A
  140 LDX#buffer% MOD256
  150 LDY#buffer% DIV256
  160 JSR&FFF1
  170 LDA#23
  180 JSR&FFEE
  190 LDA#224
  200 JSR&FFEE
  210 LDX#1
  220.vdu
  230 LDAbuffer%,X
  240 ASL A
  250 AND buffer%,X
  260 JSR&FFEE
  270 INX
  280 CPX#9
  290 BNEvdu
  300 LDA#224
  310 JSR&FFEE
  320 PLY
  330 INY
  340 CPY#41
  350 BNEloop
  360.exit
  370 LDA#13
  380 JSR&FFEE
  390 LDA#10
  400 JSR&FFEE
  410 RTS
  420.buffer%EQUS STRING$(9," ")
  430.string%EQUS STRING$(40," "):EQUB13
  440]:NEXT
  450MODE132
  460s$="Thin"
  470$string%=s$
  480PRINTTAB((40-LENs$)/2);
  490CALLcode%
I've also been working on putting them all together in one code block. Had a bit of an issue because the branching was too far at some points. Watch this space.
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk

User avatar
jgharston
Posts: 4121
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Playing with OSWORD &A

Post by jgharston » Tue Apr 28, 2020 3:50 pm

A tip, if you lay out your control block as:
.block0
EQUB 23
.block1
EQUB 0 :\ character
EQUD 0 :\ bitmap
EQUD 0 :\ bitmap
.charout
EQUB 0 :\ character

then after reading the bitmap with XY=>block1 you can then send it to the VDU driver to redefine the character and then output it by just looping from the previous byte pre-loaded with the VDU 23 to the byte pre-loaded with the character:
LDA wanted:STA block1
LDX #block1 AND 255:LDY #block1 DIV 256
LDA #10:JSR OSWORD
... fiddle with bytes block1+1 to block1+8
LDA #255:STA block1:STA charout
LDX #0
.loop
LDA block0,X:JSR OSWRCH
INX:CPX #11:BNE loop

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.32
(C) Copyright J.G.Harston 1989,2005-2020
>_

User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Re: Playing with OSWORD &A

Post by geraldholdsworth » Tue Apr 28, 2020 4:54 pm

Cheers - hadn't thought of doing it that way. I've been trying to combine all the routines into a single bit of code and my head is now hurting trying to reduce replication and code size. I'll have a play with this method and see if that works better for me.

So far, I've got:

Code: Select all

   10MODE135
   20DIMcode&143
   30osword=&FFF1
   40oswrch=&FFEE
   50FORo%=0TO2STEP2
   60P%=code
   70[OPTo%
   80.exit
   90   LDX#8
  100   LDA#0
  110.endloop
  120   JSRoswrch
  130   DEX
  140   BNEendloop
  150   RTS
  160.start
  170   LDY#0
  180.loop
  190   CPY#41
  200   BEQexit
  210   LDA string,Y
  220   CMP#13
  230   BEQexit
  240   PHY
  250   STA buffer
  260   LDA#&A
  270   LDX#buffer MOD256
  280   LDY#buffer DIV256
  290   JSRosword
  300   JSRsetdef
  310   LDYstyle
  320   CPY#1
  330   BEQflip
  340   CPY#2
  350   BEQdbl
  360   CPY#3
  370   BEQitalic
  380   CPY#4
  390   BEQfuture
  400   CPY#5
  410   BEQbold
  420   CPY#6
  430   BEQthin
  440   CPY#7
  450   BEQthinitalic
  460   JMPexit
  470.thin
  480   JMPthinfn
  490.thinitalic
  500   JMPthinitalicfn
  510.flip
  520   LDX#8
  530.flipvdu
  540   JSRsetdefrow
  550   DEX
  560   BNEflipvdu
  570   JMPendofloop
  580.dbl
  590   LDX#1
  600.dblvdu
  610   JSRsetdefrow
  620   JSRoswrch
  630   CPX#4
  640   BNEdblcont
  650   JSRprtchr
  660   LDA#8
  670   JSRoswrch
  680   LDA#10
  690   JSRoswrch
  700   JSRsetdef
  710.dblcont
  720   INX
  730   CPX#9
  740   BNEdblvdu
  750   JSRprtchr
  760   LDA#11
  770   JSRoswrch
  780   JMPendofloop2
  790.italic
  800   LDX#1
  810.italvdu
  820   LDAbuffer,X
  830   CPX#5
  840   BCCitalcont
  850   ASL A
  860.italcont
  870   JSRoswrch
  880   INX
  890   CPX#9
  900   BNEitalvdu
  910   JMPendofloop
  920.future
  930   LDX#1
  940.futurevdu
  950   LDAbuffer,X
  960   ASL A
  970   CPX#5
  980   BCCfuturetop
  990   ORA buffer,X
 1000   JMPfuturecont
 1010.futuretop
 1020   AND buffer,X
 1030.futurecont
 1040   JSRoswrch
 1050   INX
 1060   CPX#9
 1070   BNEfuturevdu
 1080   JMPendofloop
 1090.bold
 1100   LDX#1
 1110.boldvdu
 1120   LDAbuffer,X
 1130   ASL A
 1140   ORA buffer,X
 1150   JSRoswrch
 1160   INX
 1170   CPX#9
 1180   BNEboldvdu
 1190   JMPendofloop
 1200.thinfn
 1210   LDX#1
 1220.thinvdu
 1230   LDAbuffer,X
 1240   ASL A
 1250   AND buffer,X
 1260   JSRoswrch
 1270   INX
 1280   CPX#9
 1290   BNEthinvdu
 1300   JMPendofloop
 1310.thinitalicfn
 1320   LDX#1
 1330.thinitavdu
 1340   LDAbuffer,X
 1350   ASL A
 1360   AND buffer,X
 1370   CPX#4
 1380   BCSthinitatop
 1390   LSR A
 1400.thinitatop
 1410   JSRoswrch
 1420   INX
 1430   CPX#9
 1440   BNEthinitavdu
 1450.endofloop
 1460   JSRprtchr
 1470.endofloop2
 1480   PLY
 1490   INY
 1500   JMPloop
 1510.setdef
 1520   LDA#23
 1530   JSRoswrch
 1540.prtchr
 1550   LDA#224
 1560   JMPoswrch
 1570.setdefrow
 1580   LDAbuffer,X
 1590   JMPoswrch
 1600.buffer
 1610   EQUS STRING$(9," ")
 1620.string
 1630   EQUS STRING$(40," ")
 1640   EQUB13
 1650.style
 1660   EQUB 0
 1670]:NEXT
 1680PRINT"Assembled code size is &";~P%-code;" bytes."'"Press a key to continue...";:A=GET
 1690MODE129
 1700COLOUR1:PROCfont(1,"Upside Down",TRUE)
 1710COLOUR2:PROCfont(2,"Double Height",TRUE)
 1720COLOUR1:PROCfont(3,"Italics",TRUE)
 1730COLOUR2:PROCfont(4,"Futuristic",TRUE)
 1740COLOUR1:PROCfont(5,"Bold",TRUE)
 1750COLOUR2:PROCfont(6,"Thin",TRUE)
 1760COLOUR1:PROCfont(7,"Thin Italics",TRUE)
 1770COLOUR3:PRINT"These fonts can also go inline: ";
 1780COLOUR1:PROCfont(1,"Upside  Down",FALSE):COLOUR3:PRINT", ";
 1790COLOUR2:PROCfont(3,"Italics",FALSE):COLOUR3:PRINT", ";
 1800COLOUR1:PROCfont(4,"Futuristic",FALSE):COLOUR3:PRINT", ";
 1810COLOUR2:PROCfont(5,"Bold",FALSE):COLOUR3:PRINT", ";
 1820COLOUR1:PROCfont(6,"Thin",FALSE):COLOUR3:PRINT",  and ";
 1830COLOUR2:PROCfont(7,"Thin Italics",FALSE):COLOUR3:PRINT"."
 1840END
 1850DEFPROCfont(s%,s$,c%)
 1860 $string=s$
 1870 ?style=s%
 1880 IFc%PRINTTAB((40-LENs$)/2);
 1890 CALLstart
 1900 IFc%PRINT:IFs%=2PRINT
 1910ENDPROC
I've changed the exit procedure too so that the different styles can be placed inline with other text.
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk


User avatar
SimonSideburns
Posts: 564
Joined: Mon Aug 26, 2013 9:09 pm
Location: Purbrook, Hampshire
Contact:

Re: Playing with OSWORD &A

Post by SimonSideburns » Tue Apr 28, 2020 9:58 pm

I recall a font routine that could display a multitude of different styles: bold, thin, italics, underlined, inverse, rotated 90° in either direction, double width, and any combinations thereof.

Once loaded into memory each effect was called up by issuing *FX 1,n where you chose different bits of n for the styles. One of the modes was to issue *FX 1,1 and from then on, lesser-used ASCII characters would toggle the style on the fly. So, in a PRINT string one could have "|Thin|, \italics\, _underlined_." and all three would show in the one line on the screen. Very clever.

It is on "The Micro User best of graphics Utils" compilation.

Anyone else remember it?
Just remember kids, Beeb spelled backwards is Beeb!

User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Re: Playing with OSWORD &A

Post by geraldholdsworth » Wed Apr 29, 2020 9:46 am

SimonSideburns wrote:
Tue Apr 28, 2020 9:58 pm
I recall a font routine that could display a multitude of different styles: bold, thin, italics, underlined, inverse, rotated 90° in either direction, double width, and any combinations thereof.
Presumably this would require a redirection of OSWRCH to the font routine?
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk

User avatar
geraldholdsworth
Posts: 642
Joined: Tue Nov 04, 2014 9:42 pm
Location: Inverness, Scotland
Contact:

Re: Playing with OSWORD &A

Post by geraldholdsworth » Wed Apr 29, 2020 9:55 am

I have noticed that I have indeed used a couple of 65C02 mnemonics - PHY and PLY. If you do this on the BBC or Electron you'll need to use TYA:PHA and PLA:TAY. You'll also need to move the TYA:PHA to the other side of the STA buffer at the start of the loop.
Gerald Holdsworth
Repton Resource Page
www.reptonresourcepage.co.uk

User avatar
jgharston
Posts: 4121
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Playing with OSWORD &A

Post by jgharston » Wed Apr 29, 2020 12:14 pm

geraldholdsworth wrote:
Wed Apr 29, 2020 9:46 am
SimonSideburns wrote:
Tue Apr 28, 2020 9:58 pm
I recall a font routine that could display a multitude of different styles: bold, thin, italics, underlined, inverse, rotated 90° in either direction, double width, and any combinations thereof.
Presumably this would require a redirection of OSWRCH to the font routine?
That's essentially what my *disp, *lps and *man programs do which operate on embedded View highlights:

Image

See ScrMan.src

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.32
(C) Copyright J.G.Harston 1989,2005-2020
>_

User avatar
BeebMaster
Posts: 3627
Joined: Sun Aug 02, 2009 5:59 pm
Location: Lost in the BeebVault!
Contact:

Re: Playing with OSWORD &A

Post by BeebMaster » Wed Apr 29, 2020 12:17 pm

Not as much fun, but you can use VDU 23,16 on a Master to alter the vertical and horizontal direction of text (and some other effects), eg. VDU 23,16,6| will move backwards and up instead of forwards and down.
Image

User avatar
SimonSideburns
Posts: 564
Joined: Mon Aug 26, 2013 9:09 pm
Location: Purbrook, Hampshire
Contact:

Re: Playing with OSWORD &A

Post by SimonSideburns » Wed Apr 29, 2020 12:44 pm

A picture of the demo program showing the effects:
BBC Font Driver.png
Just remember kids, Beeb spelled backwards is Beeb!

Post Reply

Return to “programming”