Developing Software in Assembly Language
6812 Assembly Language Arithmetic Examples
By Jonathan W. Valvano
This article, which discusses assembly language programming,
accompanies the book Embedded Microcomputer Systems: Real Time Interfacing published by Brooks-Cole 1999. This document has four overall
parts
Overview
Syntax (fields, pseudo ops)
Local variables
Examples
Arithmetic Examples on the 6812
32-bit addition
unsigned 8-bit addition with ceiling
signed 8-bit addition with ceiling/floor
unsigned 16-bit addition with ceiling
signed 16-bit addition with ceiling/floor
32-bit subtraction
unsigned 8-bit subtraction with ceiling
signed 8-bit subtraction with ceiling/floor
unsigned 16-bit subtraction with ceiling
signed 16-bit subtraction with ceiling/floor
8-bit unsigned multiply by 10
16-bit unsigned multiply by 10
digital filter
8-bit table lookup and interpolation
16-bit table lookup and interpolation
8-bit Fuzzy Logic example
16-bit Fuzzy Logic example
Other Examples
Stack Usage and Interrupts on the 6812
Interpreters on the 6812
Shift Examples on the 6812
FIFO Queue Examples on the 6812
Control Structure Examples on the 6812
--------------------------------------------------------------------------------------
32-bit addition P=N+M
org $0800
N .blkb 4 ; first 32-bit number
M .blkb 4 ; second 32-bit number
P .blkb 4 ; third 32-bit number
org $F000
; 32 bit addition P=N+M
; Input: Two 32-bit numbers N,M
; Output: One 32 bit sum P
; Error: C/V set for unsigned/signed overflow
add32 ldaa N+3 ; start with least significant byte
adda M+3
staa P+3
ldaa N+2 ; next byte
adca M+2 ; carry from previous addition
staa P+2
ldaa N+1 ; next byte
adca M+1 ; carry from previous addition
staa P+1
ldaa N ; last byte
adca M ; carry from previous addition
staa P
; C bit set if unsigned overflow
; V bit set if signed overflow
; Z bit set if result is zero
rts
--------------------------------------------------------------------------------------
32-bit subtraction P=N-M on the 6812
N ds 4 ; first 32-bit number
M ds 4 ; second 32-bit number
P ds 4 ; third 32-bit number
sub32 ldaa N+3 ; start with least significant byte
suba M+3
staa P+3
ldaa N+2 ; next byte
sbca M+2 ; carry from previous addition
staa P+2
ldaa N+1 ; next byte
sbca M+1 ; carry from previous addition
staa P+1
ldaa N ; last byte
sbca M ; carry from previous addition
staa P
; C bit set if unsigned overflow
; V bit set if signed overflow
; Z bit set if result is zero
rts
--------------------------------------------------------------------------------------
8-bit unsigned addition with overflow checking P=N+M on the 6812
N ds 1 ; first 8-bit number
M ds 1 ; second 8-bit number
P ds 1 ; third 8-bit number
add8 ldaa N ; first number
adda M ; add second number
; C bit set if unsigned overflow
bcc SetP ; skip if no overflow
ldaa #255 ; set at maximum (ceiling)
SetP staa P
rts
--------------------------------------------------------------------------------------
8-bit signed addition with overflow checking P=N+M on the 6812
N ds 1 ; first 8-bit number
M ds 1 ; second 8-bit number
P ds 1 ; third 8-bit number
add8s ldaa N ; first number
adda M ; add second number
; V bit set if signed overflow
bvc SetP ; skip if no overflow
bpl floor ; is positive, should be -128
ceil ldaa #127 ; set at maximum (ceiling)
bra SetP
floor ldaa #-128 ; set to minumum (floor)
SetP staa P
rts
--------------------------------------------------------------------------------------
16-bit unsigned addition with overflow checking P=N+M on the 6812
N ds 2 ; first 16-bit number
M ds 2 ; second 16-bit number
P ds 2 ; third 16-bit number
add16 ldd N ; first number
addd M ; add second number
; C bit set if unsigned overflow
bcc SetP ; skip if no overflow
ldd #65535 ; set at maximum (ceiling)
SetP std P
rts
--------------------------------------------------------------------------------------
16-bit signed addition with overflow checking P=N+M on the 6812
N ds 2 ; first 16-bit number
M ds 2 ; second 16-bit number
P ds 2 ; third 16-bit number
add16s ldd N ; first number
addd M ; add second number
; V bit set if signed overflow
bvc SetP ; skip if no overflow
bpl floor ; is positive, should be -32768
ceil ldd #32767 ; set at maximum (ceiling)
bra SetP
floor ldd #-32768 ; set to minumum (floor)
SetP std P
rts
--------------------------------------------------------------------------------------
8-bit unsigned subtraction with overflow checking P=N-M on the
6812
N ds 1 ; first 8-bit number
M ds 1 ; second 8-bit number
P ds 1 ; third 8-bit number
sub8 ldaa N ; first number
suba M ; subtract second number
; C bit set if unsigned overflow
bcc SetP ; skip if no overflow
ldaa #0 ; set at minimum (floor)
SetP staa P
rts
--------------------------------------------------------------------------------------
8-bit signed subtraction with overflow checking P=N-M on the 6812
N ds 1 ; first 8-bit number
M ds 1 ; second 8-bit number
P ds 1 ; third 8-bit number
sub8s ldaa N ; first number
suba M ; subtract second number
; V bit set if signed overflow
bvc SetP ; skip if no overflow
bpl floor ; is positive, should be -128
ceil ldaa #127 ; set at maximum (ceiling)
bra SetP
floor ldaa #-128 ; set to minumum (floor)
SetP staa P
rts
--------------------------------------------------------------------------------------
16-bit unsigned subtraction with overflow checking P=N-M on the
6812
N ds 2 ; first 16-bit number
M ds 2 ; second 16-bit number
P ds 2 ; third 16-bit number
sub16 ldd N ; first number
subd M ; subtract second number
; C bit set if unsigned overflow
bcc SetP ; skip if no overflow
ldd #0 ; set at minimum (floor)
SetP std P
rts
--------------------------------------------------------------------------------------
16-bit signed subtraction with overflow checking P=N-M on the
6812
N ds 2 ; first 16-bit number
M ds 2 ; second 16-bit number
P ds 2 ; third 16-bit number
sub16s ldd N ; first number
subd M ; subtract second number
; V bit set if signed overflow
bvc SetP ; skip if no overflow
bpl floor ; is positive, should be -32768
ceil ldd #32767 ; set at maximum (ceiling)
bra SetP
floor ldd #-32768 ; set to minumum (floor)
SetP std P
rts
--------------------------------------------------------------------------------------
High Q high pass digital filter on the 6812
; y(n)=0.9025x(n)-1.805x(n-1)+0.9025x(n-2)+1.8y(n-1)-0.81y(n-2)
; first we can convert this filter to fixed point
; without introducing any error:
; y(n)=(9025x(n)-18050x(n-1)+9025x(n-2)+18000y(n-1)-8100y(n-2))/10000
org $0800
XN ds 2 ; x(n) current 16-bit data point
XN1 ds 2 ; x(n-1) previous data point
XN2 ds 2 ; x(n-2) data point two samples ago
YN1 ds 2 ; y(n-1) previous filter output
YN2 ds 2 ; y(n-2) filter output two samples ago
YN ds 2 ; y(n) current 16-bit filter output
acc ds 4 ; temporary 32-bit result
org $F000
COEF dc.w 9025,-18050,9025,18000,-8100
DF ldx #XN ; data
ldy #COEF ; coef
ldd #0
std acc ; initially clear temporary result
std acc+2
ldaa #5 ; number of terms
loop emacs acc ;acc=acc+{X}*{Y}
leax 2,x
leay 2,y
dbne A,loop
ldy acc
ldd acc+2
;Y:D=9025x(n)-18050x(n-1)+9025x(n-2)+18000y(n-1)-8100y(n-2)
ldx #10000
edivs
sty YN
rts
--------------------------------------------------------------------------------------
16-bit unsigned multiply by 10 on the 6812
; Input: Reg D is an unsigned 16-bit input
; Output: Reg D = 10*input
; without overflow checking
umul10 lsld ; multiply by 2
pshd ; save 2*D
lsld ; 4*D
lsld ; 8*D
addd 2,sp+ ; 8*D+2*D=10*D
rts
; Input: Reg D is an unsigned 16-bit input
; Output: Reg D = 10*input
; with overflow checking
d2 equ 0 ; 2*D
umul10 leas -2,sp ; allocate space for d2
lsld ; multiply by 2
bcs over ; bigger than 65535
std d2,sp ; d2=2*D
lsld ; 4*D
bcs over ; bigger than 65535
lsld ; 8*D
bcs over ; bigger than 65535
addd d2,sp ; 8*D+2*D=10*D
bcc done
over ldd #65535
done leas 2,sp ; deallocate
rts
--------------------------------------------------------------------------------------
8-bit unsigned multiply by 10 on the 6812
; Input: Reg A is an unsigned 8-bit input
; Output: Reg A = 10*input
; without overflow checking
mul10 lsla ; multiply by 2
psha ; save 2*A
lsla ; 4*A
lsla ; 8*A
adda 1,sp+ ; 8*A+2*A=10*A
rts
; Input: Reg A is an unsigned 8-bit input
; Output: Reg A = 10*input
; with overflow checking
d2 equ 0 ; 2*A
mul10 leas -1,sp ; allocate space for d2
lsla ; multiply by 2
bcs over ; bigger than 255
staa d2,sp ; d2=2*A
lsla ; 4*A
bcs over ; bigger than 255
lsla ; 8*A
bcs over ; bigger than 255
adda d2,sp ; 8*A+2*A=10*A
bcc done
over ldaa #255
done leas 1,sp ; deallocate
rts
--------------------------------------------------------------------------------------
8-bit table access on the 6812
Many applications require the representation of complex waveforms
in digital form. A typical application is a calibration curves
which describe the input/output behavior of the system. The actual
hardware takes the measurand (y= position, pressure, temperature
etc.) as input and has the A/D conversion (x= 0 to 255) as output.
In this situation, the software algorithm is asked to reverse
the process, taking as input (x) the A/D measurement and giving
as output (y) is the measurand. One of the most efficient, yet
simple, techniques for describing nonlinear equations is to provide
a small table of (x,y) points then use linear interpolation between
the points. In this way the response is piece-wise linear. This
technique only works for any single-valued data set (a unique
y for each x). There is a clear tradeoff between accuracy and
software efficiency (static and dynamic). E.g., you can add more
points to improve accuracy, but it requires more memory and runs
slower.
org $800
in ds 1 ; 8-bit input
out ds 1 ; 8-bit output
org $F000
; The table consists of multiple unsigned (x,y)
; which define a piece-wise linear function
; first X entry must be less than or equal to minimum input
; last X entry must be bigger than maximum input
Xtable dc.b 0,10,100,150,255 ; must be monotonic
Ytable dc.b 20,0,200,100,150
Main lds #$0C00
clra
loop staa in ; ranges from 0 to 254
bsr Lookup
staa out
here ldaa in
inca
cmpa #255
bne loop
stop
;**********Lookup*******************
;Inputs: RegA is 0 to 254 Xdata point, xL
; RegA input must be greater than or equal to first Xdata point
; RegA input must be less than last Xdata point
;Output: RegA is 0 to 255 Ydata point
;Registers destroyed: X,Y,B,CCR
Lookup ldx #Xtable ; first find x1<=xL<x2
ldy #Ytable
lookx1 cmpa 1,x ; check xL<x2
blo found ; stops when X points to x1
inx
iny
bra lookx1
found suba 0,x ; xL-x1
clrb ; D=256*(xL-x1)
pshd
ldab 1,x ; x2
subb 0,x ; x2-x1
clra ; D=x2-x1
tfr D,X ; X=x2-x1
puld ; D=256*(xL-x1)
idiv ; X=(256*(xL-x1))/(x2-x1)
tfr X,D
; B=(256*(xL-x1))/(x2-x1)
; Y points to y1,y2
tbl 0,y
; A=Y1+B*(Y2-Y1)
rts
org $FFFE
fdb Main
--------------------------------------------------------------------------------------
16-bit table access on the 6812
Many applications require the representation of complex waveforms
in digital form. A typical application is a calibration curves
which describe the input/output behavior of the system. The actual
hardware takes the measurand (y=position, pressure, temperature
etc.) as input and has the A/D conversion (x= 0 to 65535) as output.
In this situation, the software algorithm is asked to reverse
the process, taking as input (x) the A/D measurement and giving
as output (y) is the measurand. One of the most efficient, yet
simple, techniques for describing nonlinear equations is to provide
a small table of (x,y) points then use linear interpolation between
the points. In this way the response is piece-wise linear. This
technique only works for any single-valued data set (a unique
y for each x). There is a clear tradeoff between accuracy and
software efficiency (static and dynamic). E.g., you can add more
points to improve accuracy, but it requires more memory and runs
slower.
; Examples of 16-bit table access
org $800
in ds 2 ; 16-bit input
out ds 2 ; 16-bit output
org $F000
; The table consists of multiple unsigned (x,y)
; which define a piece-wise linear function
; first X entry must be less than or equal to minimum input
; last X entry must be bigger than maximum input
Xtable dc.w 0,1000,10000,15000,25500 ; must be monotonic
Ytable dc.w 2000,0,20000,10000,15000
Main lds #$0C00
ldd #0
loop std in ; ranges from 0 to 25400
bsr Lookup
std out
here ldd in
addd #100
cpd #25500
bne loop
stop
;**********Lookup*******************
;Inputs: RegD is 0 to 65534 Xdata point, xL
; RegD input must be greater than or equal to first Xdata point
; RegD input must be less than last Xdata point
;Output: RegD is 0 to 65535 Ydata point
;Registers destroyed: X,Y,B,CCR
Lookup ldx #Xtable ; first find x1<=xL<x2
ldy #Ytable
lookx1 cpd 2,x ; check xL<x2
blo found ; stops when X points to x1
leax 2,x
leay 2,y
bra lookx1
found subd 0,x ; xL-x1
pshd
ldd 2,x ; x2
subd 0,x ; D=x2-x1
tfr D,X ; X=x2-x1
puld ; D=(xL-x1)
fdiv ; X=(65536*(xL-x1))/(x2-x1)
tfr X,D
tfr A,B
; B=(256*(xL-x1))/(x2-x1)
; Y points to y1,y2
etbl 0,y
; D=Y1+B*(Y2-Y1)
rts
org $FFFE
fdb Main
--------------------------------------------------------------------------------------
8-bit Fuzzy logic example on the 6812
For more information on Fuzzy Logic, see Chapter 13 in the book,
Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano, Brooks/Cole Publishing Co., December
1999.
TCNT equ $0084
TSCR equ $0086
org $800
; *******8-bit fuzzy example*********
; crisp inputs
speed: ds 1
acceleration: ds 1
fuzvar: ds 0 ; inputs
inFast: ds 1 ; speed too fast
inOk: ds 1 ; speed OK
inSlow: ds 1 ; speed too slow
inDown: ds 1 ; speed decreasing
inSame: ds 1 ; speed constant
inUp: ds 1 ; speed increasing
fuzout: ds 0 ; outputs
outAdd: ds 1 ; add power to system
outZero: ds 1 ; leave power as is
outSub: ds 1 ; subtract power from system
Break: ds 1 ; apply break
; input membership variables relative offsets
fast: equ 0 ; speed too fast
ok: equ 1 ; speed OK
slow: equ 2 ; speed too slow
down: equ 3 ; speed decreasing
same: equ 4 ; speed constant
up: equ 5 ; speed increasing
;output membership variables
add: equ 6 ; add power to system
zero: equ 7 ; leave power as is
sub: equ 8 ; subtract power from system
break: equ 9 ; apply break
;crisp outputs
dpower: ds 1
org $F000
s_tab: dc.b $90,$FF,$04,$00
dc.b $40,$D0,$08,$04
dc.b $00,$60,$00,$08
a_tab: dc.b $90,$FF,$04,$00
dc.b $40,$D0,$08,$04
dc.b $00,$60,$00,$08
rules: dc.b fast,same,$FE,sub,break,$FE
dc.b fast,up,$FE,sub,break,$FE
dc.b ok,up,$FE,sub,$FE
dc.b fast,down,$FE,zero,$FE
dc.b ok,same,$FE,zero,$FE
dc.b ok,down,$FE,add,$FE
dc.b slow,up,$FE,zero,$FE
dc.b slow,same,$FE,add,$FE
dc.b slow,down,$FE,add,$FE,$FF
addsingleton: dc.b 255,128,0 ; 128 subtracted, +127,0,-128
main: lds #$0C00
movb #$80,TSCR ; enable TCNT
ldaa #0 ; crisp input speed
staa speed
ldaa #128
staa acceleration
mloop: ldaa speed ; crisp to input membership
ldx #s_tab
ldy #fuzvar
mem
mem
mem
ldaa acceleration
ldx #a_tab ; crisp to input membership
mem
mem
mem
ldab #4
cloop: clr 1,y+ ; input to output membership
dbne b,cloop
ldx #rules
ldy #fuzvar
ldaa #$FF
rev ; rule evaluation
ldy #fuzout
ldx #addsingleton
ldab #3
wav
ediv
tfr y,d
subb #128
stab dpower
change: ldaa speed
adda #$04
staa speed
bne mloop
stop
lbra main
org $FFFE
dc.w main
end
--------------------------------------------------------------------------------------
16-bit Fuzzy logic example on the 6812
For more information on Fuzzy Logic, see Chapter 13 in the book,
Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano, Brooks/Cole Publishing Co., December
1999.
TCNT equ $0084
TSCR equ $0086
org $900
;crisp input
position: ds 1
;fuzzy input membership variables
veryleft: ds 1
left: ds 1
center: ds 1
right: ds 1
veryright: ds 1
;fuzzy output membership variables
goleft: ds 1
goright: ds 1
morepower: ds 1
lesspower: ds 1
;crisp output
lr: ds 1
power: ds 1
org $F400
memtab2: dc.b $00,$40,$00,$04
dc.b $20,$80,$04,$04
dc.b $40,$C0,$04,$04
dc.b $80,$E0,$04,$04
dc.b $C0,$FF,$04,$00
rules2: dc.w veryleft,$FFFE,goright,morepower,$FFFE
dc.w left,$FFFE,goright,$FFFE
dc.w center,$FFFE,lesspower,$FFFE
dc.w right,$FFFE,goleft,$FFFE
dc.w veryright,$FFFE,goleft,morepower,$FFFE,$FFFF
weights: dc.b $FF,$C0,$80,$FF,$FF
lrsingleton: dc.b 0,100
powersingleton: dc.b 0,255
main: lds #$0C00
movb #$80,TSCR ; enable TCNT
ldaa #0 ; crisp input position
staa position
nloop: ldaa position
ldx #memtab2
ldy #veryleft
mem ; crisp to input membership
mem
mem
mem
mem
ldab #4
dloop: clr 1,y+
dbne b,dloop
ldx #rules2
ldy #weights
sec
ldaa #$FF
revw ; input to output membership
ldy #goleft
ldx #lrsingleton
ldab #2
wav
ediv
tfr y,d
stab lr
ldy #morepower
ldx #powersingleton
ldab #2
wav
ediv
tfr y,d
subb #128 ; convert to signed
stab power
ldaa position
adda #$10
staa position
bne nloop
jmp main
org $FFFE
dc.w main
end
This document has four overall parts
Overview
Syntax (fields, pseudo ops)
Local variables
Examples