6812 Lab 7 - Stack and Subroutines

Introduction

The stack on the 6812 is an area of memory that is addressed by the stack pointer, sp. Data is placed on the stack with the use of a push instruction (psha, pshb, pshd, pshc). Keep in mind that the sp points to the last byte pushed onto the stack so when a push instruction is issued the sp must first decrease and then place the data into that memory location. Again decrease, store. The sp now points to the new top of the stack. The stack is grows towards low memory. Conversely when a pull instruction (pula, pulb, puld, pulc) is issued the data is pulled off the stack and placed in memory then the sp is increased. Sp is increased or decreased by 1 for acca, accb or the ccr (pula, pulb, pulc). Sp is increased or decreased by 2 for accd (pshd, puld) because accd is 2 bytes.

Subroutines are invoked with a jump to subroutine instruction (jsr). To end the subroutine the return from subroutine instruction (rts). After an rts the 6812 executed the instruction right after the jsr that called the subroutine.

Procedure

Part 0.

Connect the 6812 to the PC and hit the reset button. Do a rd in the comm window. What is the default value of the sp, stack pointer? If acca were to be pushed onto the stack right now what would be the new value of the sp?

Part 1.

Use rm in d-bug12 to initialize a,b,ix,iy to zero before running the program. Use t in d-bug12 to trace through this program line by line. Explain the result of each line. Notice that when acca is pushed onto the stack the sp is decremented first and then acca is put onto the stack. The instruction wai will push onto the stack the values of the registers.

     org  $800
     lds  #$85f
     ldx  #$c123
     ldy  #$c456
     ldaa #$ca
     ldab #$cb
     psha
     clra
     pula
     wai

 

Now examine the stack starting at $085f and explain the contents of the memory. Again what does the wai instruction do?

 

 

Part 2.

A Time delay is a common application for a subroutine. Here is an example. How many times is the dex instruction executed?

     *main program 1
               org   $800
               ldaa  #$aa
               jsr   $delay
               wai

     *delay routine
     delay     ldx   #$a
     delay1    nop
               nop
               dex
               bne   delay1
               rts

Loops can be nested to make a longer delay as shown in this next example.

     *main program 2
      portb 	equ    1
      ddrb  	equ    3
                org    $800
                movb   #$ff,ddrb
      	        ldaa   #0
      top   	staa   portb
           	jsr    delay
         	inca
         	jmp    top

     *delay routine
     delay 	pshb
         	pshx
      	        ldab   #$2a
     d2    	ldx    #$ffff
     d1    	dex
        	bne    d1
      	        decb
         	bne    d2
        	pulx
        	pulb
      	        rts












Another variation to achieve a long delay would be to write a delay routine that will delay for 1/100 second. Then call it 100 times from another subroutine.

     *main program 3
	     	...
		jsr delay1	;1 sec. delay
		...

   delay1	psha		
		ldaa 	#100	;for 100 loops	
   delay1a	jsr	delay2	; 1/100 sec. delay
		deca
		bne 	delay1a
		pula
		rts
	
   delay2	pshx		;1/100 sec. delay routine
		ldx	#????	;you calculate the value
   delay2a	nop
		dex
		bne 	delay2a
		pulx
		rts

 

Procedure for part 2. Connect port b to two 7447 and two 7 segment displays. Go to the comm window and make port b an output port and then send a number to port b. This will verify that the hardware is working. Hint:

     mm 3, enter, ff, enter, .
     mm 1, enter, 34, enter, .

If you send the #$34 to port b you will see a 34 on the display.

Type in one of the above programs. Make the delay for 1 second. Do a calculation of the time delay by counting the number of cycles in the delay routine and use the fact that the 6812 runs at 8 Mhz. Your main program is to do the following:

	load acca w/ #1
	infinite loop:
		store acca at port b
		delay for 1 sec.
		increment acca
		repeat

You must use subroutines. Run the program and notice how long the delay is. How does your calculation compare to the experimental measurement of the delay?

Part 3.

Modify the above program so that you display the numbers 00 to 59 like a clock. After 59 go back to 00 and repeat. Also change the delay so that it is very close to 1 second.