Downloads are provided at the end of this article.
I have been experimenting with 6809 assembly on the Color Computer 3 for the past week, at last fulfilling a dream that began in the late ’80s. Every new programming adventure should begin with “Hello, world!”.
The easiest way to get text on the screen on a Coco 3 from assembly is to write to memory address $400 on the WIDTH 32 screen. The source code for HI.ASM demonstrates this concept, writing 2 character constants at $500. $500 = $400 + 32 * 8 + 0, which will write the text at row 8, column 0. The neat trick in this example is how the A and B registers get combined into the D register, sort of like how AH and AL become AX in 8086 assembly. Using this correctly should allow the text to be written twice as quickly, but take care if your string length isn’t a multiple of 2!
;---------------------------------------------------------------------------
; HI.ASM
;
; Print the messae "HI" in text memory.
; Text memory starts at $400. A single line is 32 characters ($20).
; $500 = $400 + $20 * 8, which will write the text
; at the beginning of row 8 (assuming the first row is 0).
;---------------------------------------------------------------------------
TextMemory EQU $400
CharactersPerLine EQU 32
; Every program must start somewhere. What are the options here?
ORG $4000
Start:
; Save the registers we are about to clobber.
PSHS A,B
LDA #'H ; Load A with a character constant.
LDB #'I ; Load B with a character constant.
; You can either write D directly to $500,
; ...or indirectly through the X index register.
;STD $500 ; $400 + 32 * 8
; D=A&B, so this writes 2 characters at once!
LDX #$500
STD ,X
PULS A,B ; Restore the A and B registers.
PULS PC ; Return control to BASIC.
END Start
The program will be loaded into memory at $4000. I copied this from another example. There are likely other places where programs can be stored; I just don’t know the rules yet. Hopefully the comments make this code self-explanatory; if not please write to me so I can make my examples easier to read!
A full-sized program could not rely on writing characters to the screen one constant at a time like this. I need to be able to copy values from a string table, ideally using a subroutine.
WriteMessage:
; Save the registers we're about to clobber.
PSHS D,X,U
WriteMessage_Loop:
LDA ,U+ ; A=contents pointed to by U; U+=1.
BEQ WriteMessage_End ; A=0 @ end of string.
LDB ,U+ ; B=contents pointed to by U; U+=1.
; B=0, but A contains data we still need to write.
BEQ WriteMessage_Finish
; Store the contents of D (A&B),
;...at the address pointed to by X; X+=2.
; X+=2 because each STD copies 2 characters of text.
STD ,X++
JMP WriteMessage_Loop
WriteMessage_Finish:
; Store contents of A to the address pointed to by X.
STA ,X
WriteMessage_End:
; Restore the prior contents of the registers.
PULS U,X,D
RTS ; Return to caller.
You can see the full example in HELLO32.ASM. A major problem I had to overcome here is the lack of increment operations for the U and X registers. At first I tried using some tricks with the stack to move the registers in-and-out of the accumulators, but the resulting code was awful. As it turns out, the U and X registers have built-in increment and double-increment ability built in to the LD* and ST* operations.
Another interesting bit is the logic to handle strings of odd-length. I have to test A and B separately; if A=0 then the string has an even length and we’re done. If B=0, then we’ve reached the end of the string, but A still has something that needs to be written. You can see at WriteMessage_Finish that the 8-bit value of A is being written to X instead of the 16-bit value of D.
I still have a lot to learn here and there may very well be a better way to write this program. Feedback is always welcome.
Look into the instructions leax, leau, leay, leas, and exg. Glad you figured out post-increment (and presumably pre-decrement)
LikeLike
Thanks! I’ve been reading a lot of old magazines with assembly code examples recently. I had not yet discovered pre-decrement; it’s nice to know that it’s available.
LikeLike
[…] KEYS2.ASM will run in an infinite loop, checking the status of all 4 arrow keys and the BREAK key. If the user presses the BREAK key, a friendly “Good bye!” message will be printed and the program will end (as one should expect). 4 rows on the display are used to display the pressed status of the 4 arrow keys, using the WriteMessage subroutine that I was able to drop into place from HELLO32.ASM. […]
LikeLike
[…] encouraging so far as I have embarked on the journey of learning 6809 assembly. A response to my first article on writing to the screen challenged me to try different methods of storing […]
LikeLike