Tuesday, November 26, 2024
Interfacing 6809 assembly with Color BASIC is now easier
A typical way to extend Color BASIC is to write some 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
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:
10 DATA189,179,237,30,137,126,180,244 20 CLEAR200,32511:FORA=32512TO32519:READB:POKEA,B:NEXT:POKE275,127:POKE276,0
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,
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:
.opt basic usr swapbyte
and using the -fbasic
format,
my 6809 assembler 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:
.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
This defines two assembly subroutines, and this will generate the following BASIC code:
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
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 (another 6809 assembler and linker) does this as well, although the online manual doesn't mention it.