So I’ve realized that my biggest stumbling block getting started with this stuff is that I have a difficult time writing “pseudo-code”. Pseudo-Code is code that is not really in any particular language format but contains your logical decision making and program flow in a native language like format.
That being said, coming up with a meaningful shorthand is beneficial for the future you looking at the meticulous notes you made in your notebook while you were crafting your code. We all do this, right? Right? OK, I get it… time is valuable… writing notes is annoying… But your future self will thank you for keeping some notes.
So what am I getting to? Well, lets start with this.
ORG $4000
START:
PSHS A,B
LDA #'H
LDB #'I
LDX #$400
STD ,X
PULS A,B
PULS PC
END
So, how did we get here… how about looking at my notes..
Screen memory begins at $400. Program should be out of the way... so maybe $4000
We will BASH registers A&B so save them
Then use registers A & B for the 2 letters in the word "HI"
Load the X register with the location of 32 column screen start in RAM
Store the contents of the D register (registers A and B combined) into X, displaying both chars to the screen
do cleanup
exit to basic
But what if things get more complex? Choosing standards for shorthand in my notes could help. How about the easy stuff like operators.
eq
Equal to
ne
Not equal to
gt
Check if the left operand is greater than the right operand
lt
Checks if the left operand is less than the right operand
ge
Check if the left operand is greater then or equal to right operand
le
Check if the left operand is less than or equal to the right operand
and
Equal to
or
Not equal to
not
Equal to
Labels: Naming labels so they are meaningful is a good idea. Granted, for simple local loops, you can even use the native shorthand described in the LWASM manual regarding `@` and `<` and `>`. For labels that leave the local scope, however, a meaningful label should be chosen.
Additionally, coming up with constructs similar to BASIC can be helpful, such as IF THEN and WHILE.
=====[Pseudo code]========================================
START:
WHILE A GT #0
Decrement A
ENDWHILE
==========================================================
Translates to:
=====[Actual code]========================================
START:
CMPA #0
BLE LEAVE
DECA
BRA START
LEAVE:
EQU *
If you are following along from part 1, you should have a Color Computer emulator, LWTOOLS, and TOOLSHED installed on your development system. By development system, I’m not talking about using a real 6809 based Color Computer from Tandy, but rather a laptop or desktop running Windows or even Linux.
My recommendations for a development environment are:
Microsoft VSCODE with the 6809 Assembly extension by Blair Leduc
Toolshed – For DECB copy, DECB dskini tools to create emulator DSK files.
LWTOOLS for MC6809 Assembler
All of these are available for Windows and Linux so no specific operating system is required.
To continue the commentary from part 1, I wanted to touch upon some added features of the MC6809 which were pretty novel for the time… like the movable direct page register. Direct Page normally referred to the lowest 8 bits of the address bus, or the first 256 bytes. Because these addresses do not require any of the upper 8 bits for addressing, you would only require 8 bits not 16 bits to acquire them but they were still a specific location in memory.
The 6809’s Direct Page Register enhancement allowed the ‘zero page’ to be relocated to any position within the 16-bit address space by defining a START block in the register, providing greater flexibility and optimization of memory utilization. As mentioned, direct page access uses only 1 byte versus 2 to define an address location, making access quicker.
While on the subject of adding features to a CPU, the design of the 6502 CPU took the opposite approach. The 6800 and 6809 were not cheap CPU’s in the 1970’s and they were rather complex 8-bit CPU designs. Motorola priced these accordingly, and in early days you might pay over $100 per CPU. On the other hand, the design of the 6502 was basically an attempt to take the 6800 design and strip it down to the bare essentials to get the cost to be 1/4 of the 6800 CPU. They managed to do this and thus the “very affordable” computers had arrived. By 1980, you might get a MC6809 for about $30, and it was clear that Motorola was getting less interested doing more development into the 8-bit general purpose CPU arena and ended up focusing more on the MC68000 as well as other simpler CPU’s that looked more like the 6502 in the end. This pretty much left the MC6809 at the end of its own branch on the 68 series tree. The MC68000, by comparison, became the future of the 68 series, offering 8,16 and 32 bit operations. It also introduced the idea of instruction suffixes, so you might see MOVE.B #14, D0 with the .B indicating that this is an 8-bit Byte instruction. Ah, the problems of complexity make themselves known…
In part one, the register layout of the 6809 and some of the mnemonics were mentioned but no real examples were shown. Its probably time to change that. Since the best example of the Color Computer is the Color Computer 3, this would be the best one to write some code for.
While the Instruction Set for the 6809 is big, most assemblers have a neat feature that allows one to create MACRO’s for certain tasks that can benefit from some shorthand. For example:
macro DEX
LEAX -1,X
.endm
This macro definition would allow you to enter DEX instead of LEAX -1,X for a DECREMENT X instruction.
and if you have a DEX, why not an INX?
macro INX
LEAX 1,X
.endm
I leave it up to you to make your own macro sets based on your own experience. You might want to make a similar set of macros to Set Interrupts Enabled or Clear Interrupts Enabled (Disabled) or maybe a pushall and pullall.
Some general Color Computer Information to keep handy.
The Extended Memory Map of the Color Computer 3. Note: To access 512K, it requires 19 BITS of addressing.
Page
19 bit address
Purpose
Default Logical 16 bit address
$00
$0
512k upgrade
$30
$60000
High Res Screen Ram
$34
$68000
High Res Buffer
$35
$6A000
Secontry Stack
$36
$6C000
High Res Text Screen
$37
$6E000
Unused
$38
$70000
Basic 32k
0
$3C
$78000
Extended Color Basic
$8000
$3D
$7A000
Color Basic
$A000
$3E
$7C000
Cartridge
$C000
$3F
$7E000
Super Extended Basic
$E000
–
$7FF00
Dedicated Addresses
$FF00
–
$7FFFF
–
$FFFF
In addition to the memory layout, here are some MMU Details.
MMU Bank Switching
Bank switching is performed by addresses $FFA0-FFAF
There are two sets of options Task 0 (Executive Set) and Task 1 (Task Set)… which of these is active is selected by bit 0 of $FF91… this allows for quick switching between two options
$FF91 Bit0=0
$FF91 Bit0=1
Bank
Address Range
Executive Set
Task Set
Default
0
$0
$FFA0
$FFA8
$38
1
$2000
$FFA1
$FFA9
$39
2
$4000
$FFA2
$FFAA
$3A
3
$6000
$FFA3
$FFAB
$3B
4
$8000
$FFA4
$FFAC
$3C
5
$A000
$FFA5
$FFAD
$3D
6
$C000
$FFA6
$FFAE
$3E
7
$E000
$FFA7
$FFAF
$3F
So how about some quick code to get us started? (Not my code, just stuff I collected and cobbled together)
;-------------------------------------------
; Use Color Computer 80 Column mode from ASM
;-------------------------------------------
; Defines color palette values for background and foreground colors
;-------------------------------------------
Black equ $00
Blue equ $08
Gray equ $38
Green equ $10
Orange equ $34
Red equ $20
White equ $3F
Yellow equ $36
;--------------------------------------------
; Palette information
;--------------------------------------------
; Background 0-7
; $FFB0 = $00 = Black
; $FFB1 = $08 = Blue
; $FFB2 = $07 = Gray
; $FFB3 = $10 = Green
; $FFB4 = $34 = Orange
; $FFB5 = $20 = Red
; $FFB6 = $3F = White
; $FFB7 = $36 = Yellow
;
; Foreground 8-F
; $FFB8 = $00 = Black
; $FFB9 = $08 = Blue
; $FFBA = $38 = Gray
; $FFBB = $10 = Green
; $FFBC = $34 = Orange
; $FFBD = $20 = Red
; $FFBE = $3F = White
; $FFBF = $36 = Yellow
;--------------------------------------------
; MMU REGS
;--------------------------------------------
MM0 equ $FFA0 ; $0000 - $1FFF
MM1 equ $FFA1 ; $2000 - $3FFF
MM2 equ $FFA2 ; $4000 - $5FFF
MM3 equ $FFA3 ; $6000 - $7FFF
MM4 equ $FFA4 ; $8000 - $9FFF
MM5 equ $FFA5 ; $A000 - $BFFF
MM6 equ $FFA6 ; $C000 - $DFFF
MM7 equ $FFA7 ; $E000 - $FFFF
;--------------------------------------------
org $E00 ; start of PMODE screen code
start clra ; set a register to 0
sta $FFB0 ; set palette register 0 to 0 9 (black)
lda #White ; Load the a register with 63
sta $FFB8 ; set the palette register 8 with 63 (white)
; Initialization complete, on to the screen
lda #$7E ; Value for 80 column mode
sta $FF90 ; hi res
lda #$7B
sta $FF98 ; video mode
lda #$1F ;
sta $FF99 ; video resolution
;--------------------------------------------
; Video display offset
lda #$36 ; MMU BLOCK ($6C000)
sta MM2 ; ($4000 area)
; Set video offset to $D8
; Clear accumulator and store to video offset high byte
;--------------------------------------------
lda #$D8
sta $FF9D ; Video Offset
clra
sta $FF9E
;--------------------------------------------
; clear screen routine
;--------------------------------------------
lda #$20 ; 20 = space character
ldb #$00 ; Attribute
ldx #$4000 ; Start of video area
cls std ,x++ ; D register = A+B. Store D to X register
cmpx #$4F00 ; end of screen reached?
bne cls ; Branch back to continue if "no"
;--------------------------------------------
ldx #TEXT ; Get what we want to print
ldy #$4000 ; Start of video area
ldb #$20 ; length of TEXT string below
; TLOOP Transfers bytes from address in X to address in Y,
; decrementing B after each byte, repeating until B=0
tloop lda ,x+
sta ,y++
decb
bne tloop
;--------------------------------------------
; infinite loop
;--------------------------------------------
loop jmp loop
;--------------------------------------------
; data
;---------------------------------------------
TEXT fcc 'This is a test of 80 column mode'
end start
If you can get this to work… you are all well on your way to learning 6809 Assembly.
If you are interested in a helper script, I have one…