; Chapter 2 9S12C32 assembly language programs ; Jonathan W. Valvano, 2/07/07 ; This software accompanies the book, ; Embedded Microcomputer Systems: Real Time Interfacing, Second Edition ; published by Thomson Engineering, 2006 ; ; MC9S12C32 org $4000 ;ROM Main ldaa #$0F ;make PT3-0 staa DDRT ;outputs Controller ldaa #5 staa PTT ;set 0101 ldaa #6 staa PTT ;set 0110 ldaa #10 staa PTT ;set 1010 ldaa #9 staa PTT ;set 1001 bra Controller org $FFFE fdb Main ;Reset vector ; Program 2.1 org $3800 ; rr=0.902*xx-1.81*yy+0.045*zz ; first we can convert this equation to fixed point ; without introducing any error: ; rr=(902*xx-1810*yy+45*zz)/1000 xx ds 2 yy ds 2 zz ds 2 rr ds 2 ; result acc ds 4 ; temporary 32-bit result org $4000 cc dc.w 902,-1810,45 Calc ldx #xx ; pointer to data ldy #cc ; pointer to coeficients movw #0,acc ; initially clear temporary result movw #0,acc+2 ldaa #3 ; 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=902*xx-1810*yy+45*zz ldx #1000 edivs sty rr rts ;Program 2.2. Fixed-point calculation using the 6812 emac instruction. org $4000 main lds #$4000 clra loop bsr Add1 ; branch to subroutine bra loop ;*******Add1********** ;Purpose: Subtract one from RegA ; Input: RegA ;Output: RegA=Input+1 Add1 inca ; adds one to RegA rts org $FFFE fdb main ;Program 2.3. Simple program showing how to use the bsr and rts instructions to implement a subroutine. ; MC9S12C32 org $3800 size equ 5 data rmb size org $4000 sum ldaa #size ldx #data clrb loop addb 1,x+ dbne A,loop rts ; Program 2.5. A constant implemented with equ might make the program easier to change. ; MC9S12C32 size equ 4 PTT equ $0240 DDRT equ $0242 org $4000 main movb #$FF,DDRT ;PT3-0 outputs run ldaa #size ldx #steps step movb 1,x+,PTT ;step motor dbne A,step bra run steps fcb 5,6,10,9 ;out sequence org $FFFE fdb main ; Program 2.6. A stepper motor controller using fcb. ; MC9S12C32 org $3800 ;RAM cnt rmb 1 ;global org $4000 ;EEPROM const fcb 5 ;amount to add init movb #$FF,DDRT ;outputs clr cnt rts main lds #$4000 ;sp=>RAM bsr init loop ldaa cnt staa PTT ;output adda const staa cnt bra loop org $FFFE ;EEPROM fdb main ;reset vector ;Program 2.7. Memory allocation places variables in RAM and programs in ROM. Timer_Init ; Enable TCNT at 1us movb #$80,TSCR1 movb #$04,TSCR2 ;prescale rts ; Reg D is the time to wait in cycles Timer_Wait addd TCNT ;end of wait time wloop cpd TCNT ;stop when RegD0;n--){ ; sum=sum+n; ; } ; return sum; ;} ; 6811 or 6812 ; *****binding phase*********** sum set 0 16-bit number n set 2 16-bit number ; *******allocation phase ***** calc pshx ;save old Reg X pshx ;allocate n pshx ;allocate sum tsx ;stack frame pointer ; ********access phase ******** ldd #0 std sum,x ;sum=0 ldd #100 std n,x ;n=100 loop ldd n,x ;RegD=n addd sum,x ;RegD=sum+n std sum,x ;sum=sum+n ldd n,x ;n=n-1 subd #1 std n,x bne loop ; ******deallocation phase *** txs ;deallocation pulx ;restore old X rts ;RegD=sum ; 6812 only ; *****binding phase************ sum set -4 16-bit number n set -2 16-bit number ; *******allocation phase ****** calc pshx ;save old Reg X tsx ;stack frame pointer leas -4,sp ;allocate n,sum ; ********access phase ********* movw #0,sum,x ;sum=0 movb #100,n,x ;n=100 loop ldd n,x ;RegD=I addd sum,x ;RegD=sum+n std sum,x ;sum=sum+n ldd n,x ;n=n-1 subd #1 std n,x bne loop ; *****deallocation phase ***** txs ;deallocation pulx ;restore old X rts ;RegD=sum ;Program 2.15. Assembly language implementation of a function with two local 16-bit variables. ;***************Abs************************* ; Input: RegA is signed 8 bit ; Output: Reg A is absolute value 0 to 127 Abs: tsta ; already positive? bpl ok nega ok rts ;* ------------end of Abs ----------------- ; Program 2.17 An assembly subroutine that uses comments to delineate its beginning and end. ; no conditional branch add16b ldaa u1+1 ;lsb adda u2+1 staa u3+1 ldaa u1 ;msb adca u2 staa u3 rts ; uses conditional branch add16a ldaa u1+1 ;lsb adda u2+1 staa u3+1 ldaa u1 ;msb bcc noc inca ;carry noc adda u2 staa u3 rts ; Program 2.18 Sometimes we can remove a conditional branch and simplify the program ; global variables in RAM size equ 20 buffer rmb size*2 cnt rmb 1 ; programs in EEPROM Save pshb pshx ;save ldab cnt cmpb #size*2 ; full? beq done ldx #buffer abx ; place to put next ldab happy stab 0,x ; save happy ldab sad stab 1,x ; save sad inc cnt inc cnt done pulx pulb rts ;Program 2.25. Instrumentation dump without filtering. Save pshb pshx ;save ldab sad cmpb #100 ble done ; only when sad >100 ldab cnt cmpb #size*2 ; full? beq done ldx #buffer abx ; place to put next ldab happy stab 0,x ; save happy ldab sad stab 1,x ; save sad inc cnt inc cnt done pulx pulb rts ;Program 2.26. Instrumentation dump with filter. Toggle psha ldaa PORTB eora #$40 staa PORTB pula rts ;Program 2.27. An LED monitor. ;6812 Set bset PORTB,#$40 rts Clr bclr PORTB,#$40 rts loop jsr Set jsr Calculate ; function under test jsr Clr bra loop ;Program 2.28. Instrumentation output port. before rmb 2 ; TCNT value before the call elasped rmb 2 ; number of cycles required to execute sqrt movw TCNT,before movb ss,1,-sp ; push parameter on the stack (binary fixed point) jsr sqrt ; subroutine call to the module "sqrt" ins stab tt ; save result ldd TCNT ; TCNT value after the call subd before std elasped ; execute time in cycles ; Program 2.30 Empirical measurement of dynamic efficiency in assembly language. bset DDRT,#$80 ; make PT7 an output loop bset PTT,#$80 ; set PT7 high ldaa #100 ; typical input jsr sqrt ; subroutine call to the module "sqrt" bclr PTT,#$80 ; clear PT7 low bra loop ;Program 2.32. Another empirical measurement of dynamic efficiency in assembly language. ;*******************programs from first edition********* ; Program 2.1. Memory allocation places variables in RAM and programs in ROM. org $0800 ;RAM cnt rmb 1 ;global org $F000 ;EEPROM const fcb 5 ;amount to add init movb #$FF,DDRA ;outputs clr cnt rts main lds #$0C00 ;sp=>RAM bsr init loop ldaa cnt staa PORTA ;output adda const staa cnt bra loop org $FFFE ;EEPROM fdb main ;reset vector Program 2.5. 6812 assembly implementation of a Mealy Finite State Machine. org $F000 Put in EEPROM so it can be changed * Finite State Machine Time equ 0 Index for time to wait in this state Out0 equ 1 Index for output pattern if input=0 Out1 equ 2 Index for output pattern if input=1 Next0 equ 3 Index for next state if input=0 Next1 equ 5 Index for next state if input=1 IS fdb SA Initial state SA fcb 100 Time to wait fcb 0,0 Outputs for inputs 0,1 fdb SB Next state if Input=0 fdb SD Next state if Input=1 SB fcb 100 Time to wait fcb 0,8 Outputs for inputs 0,1 fdb SC Next state if Input=0 fdb SA Next state if Input=1 SC fcb 15 Time to wait fcb 0,0 Outputs for inputs 0,1 fdb SB Next state if Input=0 fdb SD Next state if Input=1 SD fcb 15 Time to wait fcb 8,8 Outputs for inputs 0,1 fdb SC Next state if Input=0 fdb SA Next state if Input=1 * 6812 program * Initialization of 6812 and linked structure GO lds #$0C00 Initialize stack ldaa #$08 PC3=output, rest are input staa $1007 Set DDRC ldx IS Reg X => current state *Linked structure interpreter LL ldaa Time,X Time to wait bsr WAIT Reg A is call by value ldaa $1003 bita #$80 Test input PC7 bpl is0 Go to is0 if Input=0 is1 ldaa Out1,X Get desired output from linked structure staa $1003 Set PC3=output ldx Next1,X Input is 1 bra LL is0 ldaa Out0,X Get desired output from linked structure staa $1003 Set PC3=output ldx Next0,X Input is 0 bra LL Infinite loop org $FFFE fdb GO reset vector ; Program 2.8: An assembly subroutine that uses ; comments to delineate its beginning and end. ;***************Abs************************* ; Input: RegA is signed 8 bit ; Output: Reg A is absolute value 0 to 127 Abs: tsta ; already positive? bpl ok nega ok rts * ------------end of Abs ----------------- ; Program 2.9: Sometimes we can remove a conditional branch and simplify the program. ; 6811/6812 ; uses conditional branch add16a ldaa u1+1 ;lsb adda u2+1 staa u3+1 ldaa u1 ;msb bcc noc inca ;carry noc adda u2 staa u3 rts ; no conditional branch add16b ldaa u1+1 ;lsb adda u2+1 staa u3+1 ldaa u1 ;msb adca u2 staa u3 rts ; Program 2.10: Assembly implementation of a 3 layer software system. ***************************High level**************************** org $F000 ; High level routines start at $F000 main: lds #$0C00 bsr Initialize ; simple call to a function in the same layer loop: bsr PrintInfo ; simple call to a function in the same layer bra loop Initialize: ldaa #1 ; function code for InitPrinter swi ; call to middle level rts org $FFFE ; high level vector (reset) fdb main ***************************Middle level**************************** org $F400 ; Middle level routines start at $F400 swihandler: cmpa #1 ; function code for InitPrinter bne notIP bsr InitPrinter bra swidone notIP: cmpa #2 ; function code for PrintInfo bne notPI bsr PrintInfo bra swidone notPI: ; ****error swidone: rti InitPrinter: ldaa #1 ; function code for InitIEEE ldx $FF80 ; vector address into the lower level jsr 0,x ; call lower level rts org $FFF6 ; middle level vector (SWI) fdb swihandler ***************************Lower level**************************** org $F800 ; Lower level routines start at $F800 lowhandler: cmpa #1 ; function code for InitIEEE bne notInit bsr InitIEEE bra lowdone notInit: cmpa #2 ; function code for SetDAV bne notDAV bsr SetDAV bra lowdone notDAV: ; rest of the functions lowdone: rts InitIEEE: ; lower level implementation, access to hardware rts org $FF80 ; Lower level vector fdb lowhandler ; Program 2.11: Assembly implementation of SCI initialization. ; MC68HC812A4 init ldd #417 ;1200 baud std SC0BD ldaa #$00 ;mode staa SC0CR1 ldaa #$0C ;tie=rie=0, staa SC0CR2 ;te=re=1 rts ; Program 2.12: Assembly implementation of SCI input. ; MC68HC812A4 InChar brclr SC0SR1,#$20,InChar ldaa SC0DRL ;SCI data rts ; Program 2.13: Assembly implementation of SCI output. ; MC68HC812A4 OutChar brclr SC0SR1,#$80,OutChar staa SC0DRL ;sci data rts ; Program 2.15: Assembly implementation of input decimal number. ; MC68HC11A8 or MC68HC812A4 ; Input a byte from the SCI ; Inputs: none ; Outputs: Reg B 0 to 255 ; C=1 if error DIGIT rmb 1 ;global InUDec clrb ;N=0 InUDloop bsr InChar ;Next input bsr OutChar ;Echo cmpa #13 ;done if cr beq InUDret ;with C=0 cmpa #'0 blo InUDerr ;error? cmpa #'9 bhi InUDerr ;error? anda #$0F ;0-9 digit staa DIGIT ldaa #10 mul tsta ;overflow? bne InUDerr addb DIGIT ;N=10*N+DIGIT bra InUDloop InUDerr ldaa #'? bsr OutChar clrb sec ;error flag InUDret rts ; Program 2.16: Assembly implementation of SCI output string. ; MC68HC11A8 or MC68HC812A4 ; Output a string to the SCI ; Inputs: Reg X points to string ; String ends with 0 ; Outputs: none OutString ldaa 0,X beq OSdone ;0 at end bsr OutChar inx bra OutString OSdone rts ; Program 2.17: Assembly implementation of SCI output decimal number. ; MC68HC11A8 or MC68HC812A4 ; Output unsigned byte to the SCI ; Inputs: Reg B= 0 to 255, ; print as 3 digit ascii ; Outputs: none OutUDec clra ;Reg D=number ldx #100 idiv ;X=num/100, xgdx ;B=100s digit tba adda #'0 ;A=100's ascii bsr OutCh xgdx ;D=num ldx #10 idiv ;X=num/10, xgdx ;B=tens digit tba adda #'0 ;A=tens ascii bsr OutCh xgdx ;D=num tba adda #'0 ;A=ones ascii bsr OutCh rts ; Program 2.25. Assembly listing from TExaS of the sqrt subroutine. $F019 org * ;reset cycle counter $F019 35 [ 2]( 0)sqrt pshy $F01A B776 [ 1]( 2) tsy $F01C 1B9C [ 2]( 3) leas -4,sp ;allocate t,oldt,s16 $F01E C7 [ 1]( 5) clrb $F01F A644 [ 3]( 6) ldaa s8,y $F021 2723 [ 3]( 9) beq done $F023 C610 [ 1]( 12) ldab #16 $F025 12 [ 3]( 13) mul ;16*s $F026 6C5C [ 2]( 16) std s16,y ;s16=16*s $F028 18085F20 [ 4]( 18) movb #32,t,y ;t=2.0, initial guess $F02C 18085E03 [ 4]( 22) movb #3,cnt,y $F030 A65F [ 3]( 26)next ldaa t,y ;RegA=t $F032 180E [ 2]( 29) tab ;RegB=t $F034 B705 [ 1]( 31) tfr a,x ;RegX=t $F036 12 [ 3]( 32) mul ;RegD=t*t $F037 E35C [ 3]( 35) addd s16,y ;RegD=t*t+16*s $F039 1810 [12]( 38) idiv ;RegX=(t*t+16*s)/t $F03B B754 [ 1]( 50) tfr x,d $F03D 49 [ 1]( 51) lsrd ;RegB=((t*t+16*s)/t)/2 $F03E C900 [ 1]( 52) adcb #0 $F040 6B5F [ 2]( 53) stab t,y $F042 635E [ 3]( 55) dec cnt,y $F044 26EA [ 3]( 58) bne next $F046 B767 [ 1]( 61)done tys $F048 31 [ 3]( 62) puly $F049 3D [ 5]( 65) rts $F04A 183E [16]( 70) stop ; Program 2.26: Empirical measurement of dynamic efficiency in assembly. before rmb 2 ; TCNT value before the call elasped rmb 2 ; number of cycles required to execute sqrt movw TCNT,before movb ss,1,-sp ; push parameter on the stack (binary fixed point) jsr sqrt ; subroutine call to the module "sqrt" ins stab tt ; save result ldd TCNT ; TCNT value after the call subd before std elasped ; execute time in cycles ;Program 2.28: Another empirical measurement of dynamic efficiency in assembly. org $0800 ss rmb 1 tt rmb 1 org $F000 main lds #$0C00 movb #$FF,DDRB ; PB7 is connected to the scope movb #100,ss loop bset PORTB,#$80 ; set PB7 high movb ss,1,-sp ; push parameter on the stack (binary fixed point) jsr sqrt ; subroutine call to the module "sqrt" ins stab tt ; save result bclr PORTB,#$80 ; clear PB7 low bra loop ; repeat to trigger the scope