* * * * *
Interfacing 6809 assembly with Color BASIC is now easier
A typical way to extend Color BASIC (Beginner's All-purpose Symbolic
Instruction Code) is to write some assembly:
-----[ Assembly ]-----
INTCVT equ $B3ED ; put argument into D
GIVABF equ $B4F4 ; return D to BASIC
org $7F00
swapbyte jsr INTCVT ; get argument
exg a,b ; swap bytes
jmp GIVABF ; return it to BASIC
end
-----[ END OF LINE ]-----
Then assemble the code, transcribe the resulting object code into DATA
statements in a BASIC program, write the loop to poke the data into memory
and define the “user-defined machine language” subroutine. The result of all
this work would look something like this:
-----[ ColorBASIC ]-----
10 DATA189,179,237,30,137,126,180,244
20 CLEAR200,32511:FORA=32512TO32519:READB:POKEA,B:NEXT:POKE275,127:POKE276,0
-----[ END OF LINE ]-----
Line 10 contains the object code for the above subroutine. Line 20 starts
with reserving memory with the CLEAR statement. The first value, 200, is the
number of bytes BASIC can use for dynamic strings (200 being the default
value of Color BASIC in general). The second number is the highest address
Color BASIC can use; any address above that is off-limits to it. This memory,
at the top of RAM (Random Access Memory), is where we're storing our assembly
subroutine (and yes, we don't need that much memory). There's the loop to
load the object code into memory, and the final two statements,
POKE275,127:POKE276,0, informs Color BASIC were our assembly subroutine
resides in memory.
This is tedious.
So I decided to add support for a “basic” format that writes the code for us.
Just by adding the following to our source code:
-----[ Assembly ]-----
.opt basic usr swapbyte
-----[ END OF LINE ]-----
and using the -fbasic format, my 6809 assembler [1] will now generate the
BASIC code automatically. Of course, there are options to control the line
numbers that are generated—these are just the default values.
Extended Color BASIC changed how you define an assembly subroutine, and also
expanded BASIC to support up to 10 such subroutines. I support that as well.
It's just a variation on the .OPT directive:
-----[ Assembly ]-----
.opt basic defusr0 swapbyte
.opt basic defusr1 peekw
INTCVT equ $B3ED ; put argument into D
GIVABF equ $B4F4 ; return D to BASIC
org $7F00
swapbyte jsr INTCVT ; get argument
exg a,b ; swap bytes
jmp GIVABF ; return to BASIC
peekw jsr INTCVT ; get address
tfr d,x ; transfer to X
ldd ,x ; load word from given address
jmp GIVABF ; return to BASIC
end
-----[ END OF LINE ]-----
This defines two assembly subroutines, and this will generate the following
BASIC code:
-----[ ColorBASIC ]-----
10 DATA189,179,237,30,137,126,180,244,189,179,237,31,1,236,132,126,180,244
20 CLEAR200,32511:FORA=32512TO32529:READB:POKEA,B:NEXT:DEFUSR0=32512:DEFUSR1=32520
-----[ END OF LINE ]-----
The only difference, aside from the extra object code, are the calls to
DEFUSRn, which are variables used to define the address of each subroutine.
Disk Extended Color BASIC has a command MERGE, which is used to merge two
BASIC files into one. This is useful if you need to update the assembly
subroutines later on in an existing BASIC program, saving me the trouble of
adding such functionality to my assembler.
My assembler isn't the first to do this—after I started coding, I found out
that the LW Tool Chain [2] (another 6809 assembler and linker) does this as
well, although the online manual doesn't mention it.
[1]
https://github.com/spc476/a09
[2]
http://www.lwtools.ca/manual/
Email author at
[email protected]