This utility (GTAsm) is intended for developing small 6809 machine language routines that enhance programs written mostly in Dragon Basic, for example a routine to scroll the graphics screen. The assembly source code is written in Basic comment statements. This documentation assumes a good working knowledge of the 6809 and the Dragon 32.
Download GTAsm Inline Basic Assembler (as a .cas file for the Dragon 32 - get the XRoar Emulator)
With any small micro with limited RAM there's a big problem: the source code, executable program, and the assembler program itself all have to occupy memory at the same time. As well as the limitation on total space, the executable and the assembler might want to occupy the same address space at the same time.
GTAsm deals with this problem by loading itself into the graphics pages by default; the assembled code can then freely use the high memory area. Obviously this means the assembler will be corrupted and have to be reloaded every time graphics are drawn. To avoid this, reserve extra pages with PCLEAR and load the assembler in these, or load it into the reserved high memory area. The assembler's workspace (for calculating labels etc.) is limited by the end of the graphics pages, or the top of RAM (&H8000) as appropriate.
A typical starter program might look like this:
10 PCLEAR7:CLEAR200,&H6FFF 500 'ORG$7000:CONST TXBASE=$0400,TXEND=$0600,BLANK=$F6:ON 510 'DEFUSR1:@CLRSCR LDX#TXBASE:LDA#BLANK 520 '@LOOP STA,X+:CMPX#TXEND:BLO LOOP 530 'RTS 540 'END
The PCLEAR statement clears an extra 3 graphics pages, or 4.5K of RAM. This should be enough for short routines, and leaves the first 4 pages untouched so hi-res modes (PMODE3,1 etc.) work as normal. The CLEAR statement sets the last byte of Basic RAM, so our machine code program can start at &H7000.
Run the Basic program. Now load GTAsm and execute it with:
CLOADM EXEC
That's if we're happy for the assembler to sit in graphics pages 1 to 3 and don't want to bother with offsets. The assembler can be loaded anywhere in RAM as long as it starts at a page boundary; the entry point is &H0900 bytes after the start of the code. To load the assembler with an offset to start at graphics page 5:
CLOADM "ASMB0600",&H1800 EXEC &H2700
A trace of addresses and assembled machine code should be listed to screen. If there are no errors, run the assembled routine with:
EXEC &H7000
Or, since we used the DEFUSR1 directive:
A=USR01(0)
EXEC remembers its last address, so as long as we don't use it (or DEFUSR0) for something else we can type plain EXEC to re-run the assembler.
GTAsm expects assembly language mnemonics and directives to be written in BASIC comments beginning with the single quote symbol. Use upper-case only, except for string constants. Multiple instructions on one line are separated by colons. Editing is done as per usual for lines of Basic.
All standard 6809 assembler mnemonics are available, with one exception:
TFR (use TRF instead - this is a simple error)
Use standard brackets rather than square to specify indirect addressing. Use the “<” and “>” symbols to force 8 and 16 bit offsets respectively.
JSR (,X++) call subroutine at address stored at X, then point to the next address in the list LDA (CURSPOS) load A from the address stored at CURSPOS LDB >$0034 load B from $0034 using extended mode rather than direct CLR <LINELEN,Y clear the byte at Y+LINELEN, forcing 8 bit offset mode (doesn't work!)
A useful selection of directives is available, though not all of the standard ones. There is no EQU - use CONST instead.
ORG <addr> set the program origin ORG $7C00 ON switch on trace output ON OFF switch off trace output OFF DEFUSR [0..9] define Basic USR entry point DEFUSR1 CONST <label>=<word> comma-separated list of constants CONST START=100,FINISH=250 VAR <byte>,<labellist> reserve comma-separated list VAR 1,TEXTPOSX,TEXTPOSY of variables of this size VAR 2,MASKADR,BITMAPADR FCB <bytelist> comma-separated list of bytes FCB $80,$40,$20,$10,"XVID",0 FCC <bytelist> .. or strings FDB <wordlist> comma-separated list of words FDB $BD52,%7C00 RMB <word> reserve bytes of memory RMB 1000 SETDP <byte> assume DP contains this value SETDP $7C END end of assembly language END
The assembler is very forgiving about using spaces. Just as in Basic, if a statement can be parsed left to right without ambiguity then spaces can be omitted to save memory.
Hexadecimal values should begin with the '$' character, rather than Basic's “&H” symbol. Strings should be enclosed in double quotes.
You can start a statement with an '@' symbol followed immediately by a label, a space, and an instruction or directive. Labels are alphanumeric (1st character must be a letter), and can be quite long; 16 characters is a useful maximum, bearing in mind memory is limited.
A comment can be added after any valid statement without preceding it with any special character.
When assembly fails there are a number of useful error messages. Beware that some errors can be missed; sometimes you can write garbage and have it silently interpreted as a comment.
Keep lines to a reasonable length to avoid a bug in Basic. Entering a line of the maximum length then trying to edit it can cause a system crash. This appears to be due to the single-quote being stored as a two-byte token.
Compatability: GTAsm is for the Dragon 32 only. If it works on any other system then that's a happy accident.
Included on the cassette download is a work in progress. It was intended to be a simple Defender-style space shooter, but for now just allows for scrolling of a spacefield with the up and down arrows. This is the Basic and inline assembly language listing:
5 PCLEAR8:CLEAR200,&H6FFF 10 PMODE4,1:PCLS:SCREEN1,1 20 LINE(31,0)-(31,191),PSET 22 LINE(26,0)-(26,191),PSET 30 C2$="BM3,67U0":C3$="BM3,74FGHE":C4$="BM3,81RFD2GL2HU2E":C5$="BM3,88RF2D2G2L2H2U2E2" 40 REMDRAWC2$+C3$+C4$+C5$+"BM3,97RFD2GL2HU2E"+"BM3,106FGHE"+"BM3,115U0" 50 A$="D2R1D2FD2BL4U2EU2BD6D3LNDNU2LNUDLNULDLNUL2BR16L2NULULNULNU2LU3LNUD2BR4UENUFD2BL14U2ENUFDBR5BU4NU5LNU3R2NU3BLBU2C0NU2NFNGBD8C1BRF2L2NUHGNUL2E2BRU2 60 REM DRAW"BM156,100XA$; 70 REM DRAW"BM156,50A2XA$; 90 DRAW"A2BM8,31XA$;A0BM8,0XA$; 200 B$="BR2FD3GHU3EBR2 220 DRAW"BM0,33XB$;XB$;XB$;XB$;XB$;XB$; 230 R2$="RNEFD2NFGL2NGHU2NHER":R5$="C0D2NR2NL2ND2C1NUNRNDNL":R2$=R2$+R5$ 235 R3$="RFNED2GNFL2HNGU2ENHR"+R5$ 240 R4$="NURFDNRDGLNDLHUNLUER"+R5$ 245 DRAW"BM3,65XR2$;BM3,73XR3$;BM3,81XR4$;BM3,89XR2$;BM3,97XR3$;BM3,105XR4$; 250 REM LINE(147,99)-(165,116),PSET,B 300 X=&H7E80:FORJ=0TO31 310 FORK=0TO2:POKEX,PEEK(&H600+J*32+K):X=X+1:NEXT:NEXT 320 X=&H7E00:FORJ=0TO63:POKEX+J,PEEK(&HE00+J*32):NEXT 400 A=USR0(0) 420 GOTO400 999 GOTO999 2000 'ORG$7000:CONST PLANE=$7E80,HPAT=$7E00 2005 'VAR2,POS,SHX,SHX1,SHY,SPD,SHP,OFS,COR 2010 'VAR1,UP,DOWN,LEFT,RIGHT,FIRE,DIR,CLK 2020 '@PUT LDXSHP:LDU#PLANE:LDADIR:BEQPT2:LEAU48,U:@PT2 LDY#4:@PLP LDD,U:EORA,X:EORB1,X:STD,X:LDD2,U:EORA2,X:EORB32,X:STA2,X:STB32,X:LDD4,U:EORA33,X:EORB34,X:STD33,X:LDD6,U:EORA64,X:EORB65,X:STD64,X:LDD8,U:EORA66,X:EORB96,X:STA66,X:STB96,X 2025 'LDD10,U:EORA97,X:EORB98,X:STD97,X:LEAU12,U:LEAX128,X:LEAY-1,Y:BNEPLP:RTS 2200 '@KEYS LDX#FIRE+1:CLR,-X:CLR,-X:CLR,-X:CLR,-X:CLR,-X:LDD#$F703:@KLOOP BSRKCHK:LSLA:ORA#1:DECB:BNEKLOOP:RTS:@KCHK PSHSA:STA$FF02:LDA$FF00:BITA#$20:BNEKNOT:INC,X+:PULSA,PC:@KNOT LEAX1,X:PULSA,PC 2220 '@SMOV BSRKEYS:LDDSPD:TSTUP:BEQNUP:CLRDIR:ADDD#16:CMPD#$0400:BLENUP:LDD#$0400:@NUP TSTDOWN:BEQNDOW:CLRDIR:INCDIR:SUBD#16:CMPD#$FC00:BGENDOW:LDD#$FC00:@NDOW STDSPD:BMISM2:ADDDSHX+1:STDSHX+1:BCCNUP1:INCSHX 2225 '@NUP1 LDDSHP:TSTDIR:BNESM5:CMPD#$1600:BHSSM6:ADDD#$20:INCOFS+1:STDSHP:@SM6 RTS:@SM5 CMPD#$1000:BLSSM6:SUBD#$20:DECOFS+1:STDSHP:RTS 2230 '@SM2 ADDDSHX+1:STDSHX+1:BCSNUP1:DECSHX:BRANUP1 3000 '@HPT CLRA:STA-128,X:STA-96,X:STA-64,X:STA-32,X:LDD,U:STA,X:STB32,X:LDD2,U:STA64,X:STB96,X:LEAX256,X:LDD4,U:STA-128,X:STB-96,X:LDD6,U:STA-64,X:STB-32,X:CLRA:STA,X:STA32,X:STA64,X:STA96,X:@HEND RTS 3020 '@HDO LDDSHX:SUBDOFS:STDCOR:LDBCOR+1:CMPB#240:BHIHEND:LDA#32:MUL:LDX#$405:LEAXD,X:LDU#HPAT:LDACLK:ADDA#4:CMPA#48:BLOHDO2:CLRA:@HDO2 STACLK:ANDA#$F8:LEAUA,U:BSRHPT:LEAX-231,X:BRAHPT 4000 'DEFUSR0:LDX#0:STXSHX:STXSHX1:STXSPD:LDX#$9000:STXSHY:CLR DIR:LDX#$1611:STXSHP:LDD#128:STDOFS 4020 'LBSRPUT:@MLOOP SYNC:LBSRPUT:LBSRSMOV:LBSRPUT:BSRHDO:BRAMLOOP
To have a look at this, start the Dragon with a cold boot, insert the tape, and load and run the program with:
CLOAD"SPACEDEF" RUN
The program will quit with an ?FC error because the USR routine hasn't been defined yet; we ran it simply for the memory reserving statements. Rewind the tape and load the assembler into graphics page 5 (we'll be drawing on the others) and execute it with:
CLOADM"ASMB1E00" EXEC
Note that there are two versions of the assembler on the tape, identical except for the load address (which is included in the file name). Also note that there is no machine code listing displayed during assembly as there is no “ON” directive in the code.
After a delay of a few seconds the OK prompt should reappear. Now again type RUN. You should see some simple smooth-moving space game graphics. All you can do is use the up and down arrows; your spaceship stays still while the background (just that pair of mines at the sides) moves. Soft reset to quit. Now experiment with debugging the program to remove the trails that the mines leave behind.
GTAsm was hand written in machine code by Gwilym Thomas and is copyright © 1985. It probably hasn't been debugged since then so don't expect it to be free of errors. But do feel free to have fun with it developing 6809 assembly language programs for your Dragon 32.