Skip to main content
  1. Projects/

6809 Assembly

·10 mins· 0 · 0 · ·
link
Author
Link
Game Developer & Artifical Intelligence Engineer
Table of Contents

What is 6089? #

Well, the last time I was confused like this was when I seen the number 6502. I guess it is a microproc

jimbro1000/online6809

Online Motorola 6809 Emulator

HTML
7
5

Let’s do some assembly #

The best way to learn is to do. So let’s do some assembly. I am going to use the online 6809 assembler. And try to write programs as below.

Count From 0 To 9 #

Write a program that prints the digits from 0 to 9, one after another, in the top left of the text screen. That is, it prints a 0 in the top left, then it replaces the 0 with a 1, then it replaces the 1 with a 2, and so on until it has printed 9. It should return to the operating system (with an RTS) at the end of the program.

const text_screen = $0400

start:
    ldd #$0000      ; load the value 0                  | 
    std var         ; store the value 0 in var          | var = 0
loop:               ;                                   | do {
    ldd var         ; load the value of var             | 
    pshs d          ; save d                            | 
    jsr PrintDigit  ; print the value of var            | print(var)
    puls d          ; remove d from the stack           |

    ldd var         ; load the value of var             |
    addd #$0001     ; add 1 to the value of var,        | var += 1
    std var         ; store the new value of var        |
    
    cmpd #$000A     ; compare with the value 9 + 1 = A  | 
    bne loop        ; if not equal, go to loop          | } while (var != 10)
    rts             ; return from subroutine            | return
var:
    .word 0         ; reserve 2 bytes for the variable

PrintDigit:         ; This function prints the value in the stack
                    ; at the address of the user stack pointer u + 4, 
                    ; pshs <a>: push any register <a> to the stack 
    pshs u          ; save u, s = s - 2                 | 
    leau ,s         ; u = s                             | PrintDigit(int x) {
    
    ldd $04,u       ; d = mem[u + 4]                    | d = x
    addd #'0'       ; d = d + '0'                       | d += '0'
    stb text_screen ; mem[text_screen] = b              | print(d)

    leas ,u         ; s = u                             | }
    puls u          ; load u
    rts

To get the extra marks, your program must be 8 or fewer instructions in length.

start:
    lda #'0'    ; load the value 0                  | a = '0'
loop:                                               | do {
    sta $0400   ; print a                           |   print(a)
    inca        ; a = a + 1                         |   a = a + 1
    cmpa #':'   ; compare with the value '9' + 1    | 
    bne loop    ; if not equal, go to loop          | } while (a != '9' + 1)
    rts         ; return from subroutine            | return

Single Digit Fibonacci #

Write a program to compute and print each of the first 7 Fibonacci numbers. It must compute the numbers in the sequence. It must print each, one after the other, in the top left of the text screen in the emulator. The first 7 numbers in the sequence are: 0, 1, 1, 2, 3, 5, 8. These are all single digit numbers.

const text_screen = $0400

Start:  
    ldd #$0007          ; d = 7
    pshs d              ; save d
    lbsr Fibonacci      ; call Fibonacci
    puls d              ; load d
    rts

Fibonacci:              ; fib requires a parameter in a
    pshs u              ; mem[--s] = u
    leau ,s             ; u = s

    ldd #0              ; d = 0
    pshs d              ; mem[--s] = d          def a = 0
    ldd #1              ; d = 1
    pshs d              ; mem[--s] = d          def b = 1
fib_loop:
    ldd $04, u          ; d = mem[u + 4]
    cmpd #0             ; if d = 0              if n = 0
    beq fib_done        ; return 0
    subd #1             ; d = d - 1 
    std $04,u           ; mem[u + 4] = d        n = n - 1

    ldd $02,s           ; d = mem[s + 2]
    pshs d              ; mem[--s] = d          
    lbsr PrintDigit     ; call PrintDigit
    puls d              ; d = mem[s++]

    ldd ,s              ; d = mem[s]
    addd $02,s          ; d = mem[s + 2]        a = mem[s] + mem[s + 2]
    ldx ,s              ; x = mem[s]            x = mem[s]
    std ,s              ; mem[s] = d            mem[s] = a
    stx $02,s           ; mem[s + 2] = x        mem[s + 2] = x

    bra fib_loop        ; goto fib_loop
fib_done:
    leas ,u             ; s = u
    puls u              ; u = mem[s++]
    rts                 ; return

PrintDigit:
    pshs u              ; save u
    leau ,s             ; u = s
    
    ldd $04,u           ; d = mem[u + 4]
    addd #'0'           ; d = d + '0'
    stb text_screen     ; mem[text_screen] = b

    leas ,u             ; s = u
    puls u              ; load u
    rts

Extend your program to print the numbers one after the other on the top row of the text screen. That is, the top left corner of the screen should read “0112358” once your program has finished running.

const text_screen = $0400

Start:  
    ldx #text_screen    ; x = text_screen
    stx cursor          ; cursor = x
    ldd #$0007          ; d = 7
    pshs d              ; save d
    lbsr Fibonacci      ; call Fibonacci
    puls d              ; load d
    rts

Fibonacci:              ; fib requires a parameter in a
    pshs u              ; mem[--s] = u
    leau ,s             ; u = s

    ldd #0              ; d = 0
    pshs d              ; mem[--s] = d          def a = 0
    ldd #1              ; d = 1
    pshs d              ; mem[--s] = d          def b = 1
fib_loop:
    ldd $04, u          ; d = mem[u + 4]
    cmpd #0             ; if d = 0              if n = 0
    beq fib_done        ; return 0
    subd #1             ; d = d - 1 
    std $04,u           ; mem[u + 4] = d        n = n - 1

    ldd $02,s           ; d = mem[s + 2]
    pshs d              ; mem[--s] = d          
    lbsr PrintDigit     ; call PrintDigit
    puls d              ; d = mem[s++]

    ldd ,s              ; d = mem[s]
    addd $02,s          ; d = mem[s + 2]        a = mem[s] + mem[s + 2]
    ldx ,s              ; x = mem[s]            x = mem[s]
    std ,s              ; mem[s] = d            mem[s] = a
    stx $02,s           ; mem[s + 2] = x        mem[s + 2] = x

    bra fib_loop        ; goto fib_loop
fib_done:
    leas ,u             ; s = u
    puls u              ; u = mem[s++]
    rts                 ; return

PrintDigit:
    pshs u              ; save u
    leau ,s             ; u = s
    
    ldd $04,u           ; d = mem[u + 4]
    addd #'0'           ; d = d + '0'
    ldx cursor          ; x = cursor
    stb ,x+             ; mem[x + 1] = d
    stx cursor          ; cursor = x
    
    leas ,u             ; s = u
    puls u              ; load u
    rts
cursor:
    .word 0             ; cursor = 0

Hexadecimal Fibonacci #

Write a routine that, given a value in register D, will print the value in hexadecimal. It should print green on a black background. Hint: The emulator screen does not use ASCII, character 1 is ‘A’, character 2 is ‘B’, and so on. For this you might find it useful to write a routine that given a character in register A, will print it to the screen. With these routines, write a short test program to print the value FDBC then a space then 1234. The top left of the screen should read “FDBC 1234” once you have completed this.

const text_screen = $0400

Start:
	ldx #text_screen    ; 
	stx cursor          ; cursor = text_screen
	ldd #$FDCB          ; 
	lbsr PrintHex       ; PrintHex(d = FDCB)
	ldd #space		    ; 
	lbsr PrintStr       ; PrintStr(d = space)
	ldd #$1234          ; 
	lbsr PrintHex       ; PrintHex(d = 1234)
	rts

PrintStr:
	; the string is in the accumulator D
	pshs y              ; save y
	ldx cursor          ; x = cursor
	
	tfr d,y             ; y = d
print_str_loop:
	lda ,y+             ; a = mem[y++]
	cmpa #0             ; if (a == 0)
	beq print_str_done  ;   goto print_str_done
	sta ,x+             ; mem[x++] = a
	bra print_str_loop  ; goto print_str_loop
print_str_done:
	stx cursor          ; cursor = x
	puls y              ; restore y
	rts

PrintHex:
	; the number is in the accumulator D
	pshs y              ; save y
	ldx cursor          ; x = cursor

	tfr d,y             ; y = d
	lsra                
	lsra                 
	lsra
	lsra                ; a = y >> 8 >> 4
	bsr DigitOptimized  
	tfr y,d
	anda #$0F           ; a = y >> 8 & 0x0F
	bsr DigitOptimized  
	lsrb
	lsrb
	lsrb
	lsrb
	tfr b,a             ; a = y >> 4 & 0x0F
	bsr DigitOptimized
	tfr y,d
	andb #$0F
	tfr b,a             ; a = y & 0x0F
	bsr DigitOptimized  

	stx cursor
	puls y
	rts

DigitOptimized:
    ; the digit is in the accumulator A
	; make sure: 
	; - ldx cursor before
	; - sdx cursor after
	cmpa #$0A           ; if (a >= 10)
	blo if_digit	    ;   goto if-digit
	suba #$9	    ; 
	bra if_merge	    ; goto if-merge
if_digit:
    	adda #'0'		; a += '0'
if_merge:
    	sta ,x+			; mem[x + 1] = d
    	rts

cursor:
    	.word 0			; cursor = 0

space:
	.byte ' ', 0

Write a program that prints a comma seperated list of the first 25 Fibonacci numbers in hexadecimal. You must compute the sequence. Once your program has return the text screen should look like this:

Fibonacci
const text_screen = $0400

Start:
    ldx #text_screen    ; x = text_screen
    stx cursor          ; cursor = x
    ldd #25             ; d = 25
    pshs d              ; mem[--s] = d
    lbsr Fibonacci      ; call Fibonacci
    puls d              ; d = mem[s++]
    rts

Fibonacci:              ; fib requires a parameter in a
    pshs u              ; mem[--s] = u
    leau ,s             ; u = s

    ldd #0              ; d = 0
    pshs d              ; mem[--s] = d          def a = 0
    ldd #1              ; d = 1
    pshs d              ; mem[--s] = d          def b = 1
fib_loop:
    ldd $04, u          ; d = mem[u + 4]
    cmpd #0             ; if d = 0              if n = 0
    beq fib_done        ; return 0
    subd #1             ; d = d - 1 
    std $04,u           ; mem[u + 4] = d        n = n - 1

    ldd $02,s           ; d = mem[s + 2]
    lbsr PrintHex       ; call PrintHex

    ldd $04,u           ; d = mem[u + 4]
    cmpd #0             ; if d = 0              if n = 0
    beq skip_comma      ; goto skip_comma
    ldd #comma          ; d = comma
    lbsr PrintStr       ; call PrintStr
skip_comma:
    ldd ,s              ; d = mem[s]
    addd $02,s          ; d = mem[s + 2]        a = mem[s] + mem[s + 2]
    ldx ,s              ; x = mem[s]            x = mem[s]
    std ,s              ; mem[s] = d            mem[s] = a
    stx $02,s           ; mem[s + 2] = x        mem[s + 2] = x

    bra fib_loop        ; goto fib_loop
fib_done:
    leas ,u             ; s = u
    puls u              ; u = mem[s++]
    rts                 ; return

PrintStr:
    ; the string is in the accumulator D
    pshs y              ; save y
    ldx cursor          ; x = cursor
    
    tfr d,y             ; y = d
print_str_loop:
    lda ,y+             ; a = mem[y++]
    cmpa #0             ; if (a == 0)
    beq print_str_done  ;   goto print_str_done
    sta ,x+             ; mem[x++] = a
    bra print_str_loop  ; goto print_str_loop
print_str_done:
    stx cursor          ; cursor = x
    puls y              ; restore y
    rts

PrintHex:
    ; the number is in the accumulator D
    pshs y              ; save y
    ldx cursor          ; x = cursor

    tfr d,y             ; y = d
    lsra
    lsra
    lsra
    lsra                ; a = y >> 8 >> 4
    bsr DigitOptimized
    tfr y,d
    anda #$0F           ; a = y >> 8 & 0x0F
    bsr DigitOptimized
    lsrb
    lsrb
    lsrb
    lsrb
    tfr b,a             ; a = y >> 4 & 0x0F
    bsr DigitOptimized
    tfr y,d
    andb #$0F
    tfr b,a             ; a = y & 0x0F
    bsr DigitOptimized

    stx cursor
    puls y
    rts

DigitOptimized:
    ; the digit is in the accumulator A
    ; make sure: 
    ; - ldx cursor before
    ; - sdx cursor after
    cmpa #$0A           ; if (a >= 10)
    blo if_digit		;   goto if-digit
    suba #$9			; 
    bra if_merge		; goto if-merge
if_digit:
    adda #'0'           ; a += '0'
if_merge:
    sta ,x+             ; mem[x + 1] = d
    rts

cursor:
    .word 0             ; cursor = 0

space:
    .byte ' ', 0
comma:
    .byte ',', 0

Download #

Warning! The source code is stored in the web site, not in a database.
  1. Download the source code.
Download code.zip
  1. Extract the zip file.
unzip code.zip