;*****************************************************************************
;* Coin Tosser Program Example (KEH) 8/5/2008 for the CSMB12C128 Module
;* Pushbutton SW on PB1, LED on PB0, PTAD holds nr. Heads, PTT holds nr. Tails
;*****************************************************************************
; export symbols
            	XDEF diceroll        		; export 'Entry' symbol
           		ABSENTRY diceroll    		; for absolute assembly: mark this as application entry point
           		nolist
            	INCLUDE 'mc9s12c128.inc'	; This include file has all the 9S12C32 register EQU's in it!
            	list
PushButton: equ PORTB
LEDDisplay: equ PORTB
; variable/data section
            	ORG RAMStart
nr_1:   	ds.b 1      					;Allocate 1 byte of RAM: Number of 1 outcomes accumulated  here
nr_2:   	ds.b 1     				 	  ;Allocate 1 byte of RAM: Number of 2 outcomes accumulated  here
nr_3:   	ds.b 1      					;Allocate 1 byte of RAM: Number of 3 outcomes accumulated  here
nr_4:   	ds.b 1     				 	  ;Allocate 1 byte of RAM: Number of 4 outcomes accumulated  here
nr_5:   	ds.b 1      					;Allocate 1 byte of RAM: Number of 5 outcomes accumulated  here
nr_6:   	ds.b 1     				 	  ;Allocate 1 byte of RAM: Number of 6 outcomes accumulated  here
nr_total: ds.b 1     				 	  ;Allocate 1 byte of RAM: Number of total outcomes accumulated  here
; code section
            	ORG ROM_4000Start
diceroll:
   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  DDRB,%00000111 ;PB0-PB2 are binary LED output for dice #.
    bclr  DDRB,%00001000 ; PB3 is pushbutton "die toss" switch input.
    clr   nr_1    	; Initialize statistics to 0.
    clr   nr_2
    clr   nr_3
    clr   nr_4
    clr   nr_5
    clr   nr_6
    clr   PTT				    ; Set all output pins low.
    clr   PORTB
    clr   PTAD		 
    ldab #$0    ; Use B as a 1-bit counter that will be stopped when the switch is depressed and 
                ;thereby will contain a random outcome: one of 1 or 6.     
Top_of_loop:		        
              
SW_wt_press:
    incb     					    ; Increment B up one
    ldaa  PushButton   		; Load accum A with the SW state (Bit #0)
    cmpb  #$7             ; check if number incremented past 6

      ;*** Added by KEH ****

    bne   dont_wrap       ; handle if necessary
    ldab #1               ; Wrap B back to "1" when it hits state 7
dont_wrap:    

      ;**** End of code added by KEH***
      
    jsr   delay_rtn_2     ; delay other states than 7( really 1) for more fair roll
    anda  #$08            ; check for button press
   ; stab  PTT             ; watch incrementing
    bne   SW_wt_press 	  ; Hang in this loop until SW is pressed
    
    ;***** Removed by KEH ****
;   jmp   After_Press_wait  ;bypass if six
;Num_past_6:
;    ldab #$1              ; reset back to 1
;    anda  #$08            ; check for button press
;    bne   SW_wt_press 	  ; back to rest of loop until SW is pressed

    ;***** Removed by KEH ****
After_Press_wait:    
    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  #$08 
    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.
    inc   nr_total        ; Increment total number of rolls
    stab  LEDDisplay    	; Send dice # result to LED on PORTB.
    cmpb  #1    				  ; compare and branch to respective outcome
    beq   one_outcome
    cmpb  #2    				  ; compare and branch to respective outcome
    beq   two_outcome
    cmpb  #3    				  ; compare and branch to respective outcome
    beq   three_outcome
    cmpb  #4    				  ; compare and branch to respective outcome
    beq   four_outcome
    cmpb  #5    				  ; compare and branch to respective outcome
    beq   five_outcome
    cmpb  #6    				  ; compare and branch to respective outcome
    beq   six_outcome
one_outcome:
    inc   nr_1			  ; Update nr_1 RAM location
    bra   Top_of_loop
two_outcome:
    inc   nr_2				; Update nr_2 RAM location
    bra   Top_of_loop   
three_outcome:
    inc   nr_3			  ; Update nr_3 RAM location
    bra   Top_of_loop
four_outcome:
    inc   nr_4				; Update nr_4 RAM location
    bra   Top_of_loop   
five_outcome:
    inc   nr_5			  ; Update nr_5 RAM location
    bra   Top_of_loop
six_outcome:
    inc   nr_6				; Update nr_6 RAM location
    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)
delay_rtn_2:  
  ;  rts
    ldy   #$ffff
delay_more_2: dey									  ;
    bne   delay_more_2 		  ;Count y down 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
    dc.w       diceroll              ; Intialize Reset Vector with starting address of coin toss program