Developing Software in Assembly Language
6812 Assembly Language Control 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

Control Examples on the 6812
      unsigned 8 bit if then
      signed 8 bit if then
      unsigned 16 bit if then
      signed 16 bit if then
      for loops
      gadfly loop
      while loops

Other Examples
      Arithmetic Examples
      Shift Examples on the 6812
      Stack Usage and Interrupts on the 6812
      Interpreters on the 6812
      FIFO Queue Examples on the 6812 

--------------------------------------------------------------------------------------
Unsigned 8-bit if statements on the 6812


      In these examples of unsigned if..else structures, the following global variables are defined in RAM

G1   rmb   1   Unsigned 8-bit global
G2   rmb   1   Unsigned 8-bit global
G3   rmb   1   Unsigned 8-bit global
G4   rmb   1   Unsigned 8-bit global

In the first example the compare immediate instruction is followed by the unsigned conditional branch to implement the module if(G2 > 100) isGreater();

;Implementation of if(G2 > 100) isGreater();
     ldaa  G2
     cmpa  #100
     bls   L0          ; branch if G2 <= 100
     jsr   isGreater   ; G2 > 100
L0

The second example implements the module if(G2>G1) isGreater();

; Implementation of if (G2>G1) isGreater();
      ldaa  G2
      cmpa  G1
      bls   L1          ; branch if G2<=G1
      jsr   isGreater   ; G2>G1
L1

The third example implements an if else program module.

; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
      ldaa  G2
      cmpa  G1
      bhi   L2                ; branch if G2>G1
      jsr   isLessThanEqual   ; G2<=G1
      bra   L3
L2    jsr   isGreater         ; G2>G1
L3

The fourth example implements a similar if else program module.

; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
      ldaa  G2
      cmpa  G1
      bhs   L4               ; branch if G2>=G1
      jsr   isLessThan       ; G2<G1
      bra   L5
L4    jsr   isGreaterEqual   ; G2>=G1
L5

The next example implements a simple compare module.

;Implementation of if (G2>=G1) isEqual(); else isNotEqual();
      ldaa  G2
      cmpa  G1
      beq   L6          ; branch if G1==G2
      jsr   isNotEqual  ; G1!=G2
      bra   L7
L6    jsr   isEqual     ; G1==G2
L7

In the next example we implement a compound boolean expression by testing one term at a time.

;Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
      ldaa   G2
      cmpa   G1
      bls    L8           ; branch if G2<=G1
      ldaa   G4
      cmpa   G3
      bls    L8           ; branch if G4<=G3
      jsr    isGreater    ; (G2>G1)&&(G4>G3)
L8

The last example implements a compound if else module.

; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
      ldaa  G2
      cmpa  G1
      beq   L9      ; true if G2==G1
      ldaa  G4
      cmpa  G3
      bhi   L9      ; true if G4>G3
      jsr   False   ; (G2!=G1)and(G4<=G3)
      bra   L10
L9    jsr   True    ; (G2==G1)||(G4>G3)
L10

--------------------------------------------------------------------------------------
Signed 8-bit if statements on the 6812

       In these examples of signed if..else structures, the following global variables are defined in RAM

G1   rmb   1   Signed 8-bit global
G2   rmb   1   Signed 8-bit global
G3   rmb   1   Signed 8-bit global
G4   rmb   1   Signed 8-bit global

In the first example the compare immediate instruction is followed by the signed conditional branch to implement the module if(G2 > -100) isGreater();

; Implementation of if(G2 > -1000) isGreater();
      
ldaa  G2
      cmpa  #-100
      ble   L0         ; branch if G2 <= -100
      jsr   isGreater  ; G2 > -100
L0

The second example implements the module if(G2>G1) isGreater();

; Implementation of if (G2>G1) isGreater();
      
ldaa  G2
     cmpa  G1
     ble   L1        ; branch if G2<=G1
     jsr   isGreater ; G2>G1
L1

The third example implements an if else program module.

; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
      
ldaa G2
     cmpa G1
     bgt  L2               ; branch if G2>G1
     jsr  isLessThanEqual  ; G2<=G1
     bra  L3
L2   jsr  isGreater        ; G2>G1
L3

The fourth example implements a similar if else program module.

; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
      
ldaa  G2
     cmpa  G1
     bge   L4             ; branch if G2>=G1
     jsr   isLessThan     ; G2<G1
     bra   L5
L4   jsr   isGreaterEqual ; G2>=G1
L5

The next example implements a simple compare module.

;. Implementation of if (G2>=G1) isEqual(); else isNotEqual();
      
ldaa  G2
     cmpa  G1
     beq   L6          ; branch if G1==G2
     jsr   isNotEqual  ; G1!=G2
     bra   L7
L6   jsr   isEqual     ; G1==G2
L7

In the next example we implement a compound boolean expression by testing one term at a time.

; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
      
ldaa  G2
     cmpa  G1
     ble   L8         ; branch if G2<=G1
     ldaa  G4
     cmpa  G3
     ble   L8         ; branch if G4<=G3
     jsr   isGreater  ; (G2>G1)&&(G4>G3)
L8

The last example implements a compound if else module.

; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
      
ldaa  G2
      cpd   G1
      beq   L9     ; true if G2==G1
      ldaa  G4
      cmpa  G3
      bgt   L9     ; true if G4>G3
      jsr   False  ; (G2!=G1)and(G4<=G3)
      bra   L10
L9    jsr   True   ; (G2==G1)||(G4>G3)
L10

 

--------------------------------------------------------------------------------------
Unsigned 16-bit if statements on the 6812

       In these examples of signed if..else structures, the following global variables are defined in RAM

G1   rmb   2   Unsigned 16-bit global
G2   rmb   2   Unsigned 16-bit global
G3   rmb   2   Unsigned 16-bit global
G4   rmb   2   Unsigned 16-bit global

In the first example the compare immediate instruction is followed by the unsigned conditional branch to implement the module if(G2 > 1000) isGreater();

; Implementation of if(G2 > -1000) isGreater();
      
ldd   G2
      cpd   #1000
      bls   L0   branch if G2 <= 1000
      jsr   isGreater   G2 > 1000
L0

The second example implements the module if(G2>G1) isGreater();

; Implementation of if (G2>G1) isGreater();
      
 ldd   G2
      cpd   G1
      bls   L1         ; branch if G2<=G1
      jsr   isGreater  ; G2>G1
L1

The third example implements an if else program module.

; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
      
ldd   G2
     cpd   G1
     bhi   L2               ; branch if G2>G1
     jsr   isLessThanEqual  ; G2<=G1
     bra   L3
L2   jsr   isGreater        ; G2>G1
L3

The fourth example implements a similar if else program module.

; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
      
ldd   G2
     cpd   G1
     bhs   L4              ; branch if G2>=G1
     jsr   isLessThan      ; G2<G1
     bra   L5
L4   jsr   isGreaterEqual  ; G2>=G1
L5

The next example implements a simple compare module.

;. Implementation of if (G2>=G1) isEqual(); else isNotEqual();
      
ldd   G2
     cpd   G1
     beq   L6          ; branch if G1==G2
     jsr   isNotEqual  ; G1!=G2
     bra   L7
L6   jsr   isEqual     ; G1==G2
L7

In the next example we implement a compound boolean expression by testing one term at a time.

; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
      
ldd   G2
     cpd   G1
     bls   L8          ; branch if G2<=G1
     ldd   G4
     cpd   G3
     bls   L8          ; branch if G4<=G3
     jsr   isGreater   ; (G2>G1)&&(G4>G3)
L8

The last example implements a compound if else module.

; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
      
ldd   G2
      cpd   G1
      beq   L9     ; true if G2==G1
      ldd   G4
      cpd   G3
      bhi   L9     ; true if G4>G3
      jsr   False  ; (G2!=G1)and(G4<=G3)
      bra   L10
L9    jsr   True   ; (G2==G1)||(G4>G3)
L10

 

--------------------------------------------------------------------------------------
Signed 16-bit if statements on the 6812

      In these examples of signed if..else structures, the following global variables are defined in RAM

G1   rmb   2   Signed 16-bit global
G2   rmb   2   Signed 16-bit global
G3   rmb   2   Signed 16-bit global
G4   rmb   2   Signed 16-bit global

In the first example the compare immediate instruction is followed by the signed conditional branch to implement the module if(G2 > -1000) isGreater();

; Implementation of if(G2 > -1000) isGreater();
      
ldd   G2
      cpd   #-1000
      ble   L0   branch if G2 <= -1000
      jsr   isGreater   G2 > -1000
L0

The second example implements the module if(G2>G1) isGreater();

; Implementation of if (G2>G1) isGreater();
      
ldd   G2
      cpd   G1
      ble   L1   branch if G2<=G1
      jsr   isGreater   G2>G1
L1

The third example implements an if else program module.

; Implementation of if (G2>G1) isGreater(); else isLessThanEqual();
      
ldd   G2
      cpd   G1
      bgt   L2   branch if G2>G1
      jsr   isLessThanEqual   G2<=G1
      bra   L3
L2   jsr   isGreater   G2>G1
L3

The fourth example implements a similar if else program module.

; Implementation of if (G2>=G1) isGreaterEqual(); else isLessThan();
      
ldd   G2
     cpd   G1
     bge   L4              ; branch if G2>=G1
     jsr   isLessThan      ; G2<G1
     bra   L5
L4   jsr   isGreaterEqual  ; G2>=G1
L5

The next example implements a simple compare module.

; Implementation of if (G2>=G1) isEqual(); else isNotEqual();
      
ldd   G2
     cpd   G1
     beq   L6          ; branch if G1==G2
     jsr   isNotEqual  ; G1!=G2
     bra   L7
L6   jsr   isEqual     ; G1==G2
L7

In the next example we implement a compound boolean expression by testing one term at a time.

; Implementation of if ((G2>G1)&&(G4>G3)) isGreater();
      
ldd   G2
     cpd   G1
     ble   L8         ; branch if G2<=G1
     ldd   G4
     cpd   G3
     ble   L8         ; branch if G4<=G3
     jsr   isGreater  ; (G2>G1)&&(G4>G3)
L8

The last example implements a compound if else module.

; Implementation of if ((G2==G1)||(G4>G3)) True(); else False();
     
ldd   G2
     cpd   G1
     beq   L9     ; true if G2==G1
     ldd   G4
     cpd   G3
     bgt   L9     ; true if G4>G3
     jsr   False  ; (G2!=G1)and(G4<=G3)
     bra   L10
L9   jsr   True   ; (G2==G1)||(G4>G3)
L10

--------------------------------------------------------------------------------------
While statements on the 6812

      In these examples of while modules, the following global variables are defined in RAM. Although these are unsigned 8-bit compares, the examples of the previous sections could be used to implement signed and/or 16-bit comparisions.

G1   rmb   1   Unsigned 8-bit global
G2   rmb   1   Unsigned 8-bit global

This first example implements an unsigned while.

;Implementation of while (G2>G1) isGreater();
L1   ldaa  G2
     cmpa  G1
     bls   L2         ; stop when G2<=G1
     jsr   isGreater
     bra   L1
L2

The 8-bit PC relative branching can be converted to 16 absolute jmps to accomodate larger program segments. See also the section on condition branching far away. The 6812 has the long condition branches.

; Implementation of while (G2>G1) { lots and lots of stuff };
L3   ldaa   G2
     cmpa   G1
     lbls   L5   ; continue while G2>G1
; more than 128 bytes of object code
; { lots and lots of stuff }
     lbra   L3
L5

To implement the do while structure, we simply rearrange the order.

;Implementation of do isGreater(); while (G2>G1);
L6   jsr   isGreater
     ldaa  G2
     cmpa  G1
     bhi   L6   ; stop when G2<=G1

The 8-bit PC relative branching can be converted to 16 absolute jmps to accomodate larger program segments.

;Implementation of do { lots and lots of stuff }; while (G2>G1);
L7
; more than 128 bytes of object code
; { lots and lots of stuff }
      ldd   G2
      cpd   G1
      lbhi  L7   ; stop when G2<=G1

--------------------------------------------------------------------------------------
Gadfly Loops on the 6812

A very common application of a while loop is waiting for a particular bit in an I/O register to be set. The following example waits for bit 2 of PORTA to be set.

; Implementation of while((PORTA&0x40)==0){};
PORTA  equ    0
L9     brclr  PORTA,#$04,L9

;Implementation of while((PORTA&0x04)==0){};
PORTA equ   0
L9    ldaa  PORTA
      bita  #$04
      beq   L9

;Implementation of while((PORTA&0x04)==0){};
PORTA equ   0
      ldaa  #$04
L9    bita  PORTA
      beq   L9
   

#define RDRF 0x20 // Receive Data Register Full Bit
// Wait for new serial port input, return ASCII code for key typed
char InChar(void){
while ((SC0SR1 & RDRF) == 0){};
return(SC0DRL);}
   
; Read 8 bits from serial port
; Return 8-bit byte in RegA
RDRF   equ  $20
InChar ldaa SC0SR1 ; Reg A has the serial status
       anda #RDRF  ; new input available?
       beq  InChar ; wait for RDRF to be set
       ldaa SC0DRL ; read ASCII character
       rts

#define TDRE 0x80 // Transmit Data Register Empty Bit
// Wait for buffer to be empty, output ASCII to serial port
void OutChar(char data){
while ((SC0SR1 & TDRE) == 0){};
SC0DRL = data;
}

; Write 8 bits to serial port
; Input 8-bit byte in RegA
TDR     equ  $80
OutChar ldab SC0SR1  ; Reg B has the serial status
        andb #TDRE   ; output channel ready for transmission?
        beq  OutChar ; wait for TDRE to be set
        staa SC0DRL  ; write ASCII character
        rts

--------------------------------------------------------------------------------------
For loop statements on the 6812

      In these examples of for loop modules, the following global variables are defined in RAM. Many microcomputers have special op codes to facilate the implementation of 8-bit for loops.

I   rmb   1   Unsigned 8-bit global
J   rmb   2   Unsigned 16-bit global

It is efficient to implement the for loop with a decrementing index. The first implementation places the 8-bit index in a register

; Implementation of for(I=100;I>0;I--) process();
      
ldab   #100     ; I=100
L1    jsr    process
      dbne   B,L1     ; I=I-1

If a register is not available, this same for loop can be implemented by placing I in the global variable.
; Another implementation of for(I=100;I>0;I--) process();
      
movb  #100,I   ; I=100
L2    jsr   process
      dec   I        ; I=I-1
      bne   L21

If a register is not available and we wish to make it reentrant, this same for loop can be implemented by placing I as a local variable on the stack.
; A stack implementation of for(I=100;I>0;I--) process();
      
movb  #100,1,-SP  ; allocate, I=100
L3    jsr   process
      dec   0,sp        ; I=I-1
      bne   L3
      leas  1,sp        ; deallocate

The following example is more general.

; A global variable implementation of for(J=100;J<1000;J++) { process();}
     movw  #100,J     ; J=100
L4   ldd   J
     cpd   #1000
     bhs   L5         ; quit if J_1000
     jsr   process
     ldd   J          ; J=J+1
     addd  #1
     std   J
     bra   L4
L5

If a register can be used, the for loop will be more efficient.

;A register implementation of for(J=100;J<1000;J++) { process();}
     ldd   #100     ; J=100
L6   cpd   #1000
     bhs   L7       ; quit if J_1000
     jsr   process
     addd  #1       ; J=J+1
     bra   L6
L7

This document has four overall parts
     Overview
     Syntax (fields, pseudo ops)
     Local variables
     Examples