;*****************************************************************************
;* Coin Tosser Program Example (KEH) 8/5/2004 for 9S12C32 Module
;* Pushbutton SW on PM0, LED on PM1, PTAD holds nr. Heads, PTT holds nr. Tails
;*****************************************************************************
; export symbols
            	XDEF cointoss        		; export 'Entry' symbol
           		ABSENTRY cointoss    		; for absolute assembly: mark this as application entry point
           		nolist
            	INCLUDE 'mc9s12c32.inc'	; This include file has all the 9S12C32 register EQU's in it!
            	list
PushButton: equ PTM
LEDDisplay: equ PTM
ShowNumberOfHeads:   equ PTAD
ShowNumberOfTails:   equ PTT
; variable/data section
            	ORG RAMStart
nr_heads:   	ds.b 1      					;Allocate 1 byte of RAM: Number of head outcomes accumulated  here
nr_tails:   	ds.b 1     				 	  ;Allocate 1 byte of RAM: Number of tail outcomes accumulated  here
; code section
            	ORG ROM_4000Start
cointoss:
   lds   #RAMEnd 	      ; Initialize user stack near top of RAM,
						            ; just below the monitor stack
    bset  ATDDIEN,$FF	; Port AD is to be all digital I/O
    bset  DDRAD,$FF  	; Port AD will be output port to display (as an 8-bit binary nr) the nr of heads.
    bset  DDRT,$FF	  	; Port T is will be output port to display (as an 8-bit binary nr) the nr of tails.
    bset  DDRM,%00000010 ; PM1 is "Head/Tail" LED output.
    bclr  DDRM,%00000001 ; PM0 is pushbutton "die toss" switch input.
    bclr  PERM,%00000001	; Disable internal pull-up resistor on input PM0 (pushbutton SW)
    clr   nr_heads    	; Initialize statistics to 0.
    clr   nr_tails
    clr   PTT				    ; Set all output pins low.
    clr   PTM
    clr   PTAD		 
Top_of_loop:		        
    clrb    ; Use B as a 1-bit counter that will be stopped when the switch is depressed and 
            ;thereby will contain a random outcome: either 0 or 1.               
SW_wt_press:
    eorb #1     					; Toggle LSB of accumulator B (if high, make it low, and vice versa)
    ldaa  PushButton   			    ; Load accum A with the SW state (Bit #0)
    anda #$01   					; Accum A = $01 if SW not pressed, and $00 if SW pressed
    bne   SW_wt_press 	  ; Hang in this loop until SW is pressed
    jsr   delay_rtn  		  ; Wait for pushbutton switch to stop bouncing
SW_wt_release:                        
    ldaa  PushButton 					  ; Arrive here when SW is presed, with random outcome in accum B
    anda  #$01  
    beq   SW_wt_release	  ; Hang in this loop until switch is released.
    jsr   delay_rtn       ; Wait for pushbutton switch to stop bouncing by calling delay_rtn subroutine.
    lslb		     				  ; Shift Head/Tail outcome into proper position (from Bit 0 to Bit 1)
    stab  LEDDisplay    				  ; Send HEAD/TAIL result to LED on Bit 1 of Port M.
    cmpb  #2    				  ; If HEAD outcome, B = 2.  If TAIL outcome, B = 0.
    beq   heads_outcome
tails_outcome:
    inc   nr_tails			  ; Update nr_tails RAM location
    movb  nr_tails,ShowNumberOfTails   	; Mirror this value on Port T
    bra   Top_of_loop
heads_outcome:
    inc   nr_heads				; Update nr_heads RAM location
    movb  nr_heads,ShowNumberOfHeads  	; Mirror this on Port AD
    bra   Top_of_loop                  
;*********** End of main program*******************       
; Here is a short delay subroutine that delays for about
; 20 ms before returning.  It is used for pushbutton switch debouncing
delay_rtn:  
  ;  rts
    ldy   #$ffff
delay_more: dey									  ;
    bne   delay_more 		  ;Count y down from $ffff to 0.           
    rts          				  ;Return addr (pop return addr off stack into PC)
; Here we intialize the RESET vector to point to the 
; start of the cointoss program
    ORG       $FFFE
    dcw       cointoss              ; Intialize Reset Vector with starting address of coin toss program