ERRORLEVEL -302 TITLE "Led Dice Simulation (c) 1999 Doug Jackson." ; ;************************************************************************************* ; ; LEDDice - A simulation of 2 dice using LEDS and a 16F84 PIC Microprocessor ; ; Copyright (c) 1999 ; Doug Jackson ; doug@stillhq.com ; ; Usage: When a button is pressed for a short period of time, the result of ; the last dice roll is displayed. ; If the button is held down, both dice roll. When the button is ; released, the dice roll slows till a final result is displayed. ; Revision: 1.0 ; Date: 05 Dec, 1999 ; Source: \\win95\My Documents\articles\LedDice\LedDice.asm ; Notes: None ; ;************************************************************************************* ; Revision History ;************************************************************************************* ; Date By What ;************************************************************************************* ; 19991205 DRJ Initial Creation ;************************************************************************************* ; ; CPU configuration ; (It's a 16F84, RC oscillator, ; watchdog timer off, power-up timer on) processor 16f84 include __config _RC_OSC & _WDT_OFF & _PWRTE_ON PAGE ; ;************************************************************************************* ; Hardware Constants ;************************************************************************************* ; LEDOne EQU B'00000001' ; some constants are defined LEDTwo EQU B'00000100' ; for the various LED Dice LEDThree EQU B'00000101' ; Bit Patterns. LEDFour EQU B'00001100' LEDFive EQU B'00001101' LEDSix EQU B'00001110' LEDOff EQU B'00000000' LEDTest EQU B'00001111' FALSE EQU 0 TRUE EQU 1 DieA EQU PORTA ; The connection for the First Die DieB EQU PORTB ; The connection for the Second Die ; ;************************************************************************************* ; Ram Variable assignments ;************************************************************************************* ; TEMP EQU 0x030 ; a temporary register J EQU 0x031 ; delay loop counter K EQU 0x032 ; delay loop counter DieAVal EQU 0x033 ; the last displayed value on Die A DieBVal EQU 0x034 ; the last displayed value on Die B RandomA EQU 0x035 ; Storage for our random number PAGE ; ;************************************************************************************* ; Code Starts Here ;************************************************************************************* ; org 0x0000 RESET GOTO START ; Reset vector location ; ;************************************************************************************* ; Interrupt Vectors ;************************************************************************************* ; ; No vectored interrupts are used in this system. PAGE ; ;************************************************************************************* ; Start: ; Set up all inputs and outputs as designed. ; and do a self test. ;************************************************************************************* ; START bsf STATUS, RP0 ; Bank 1 movlw b'00001111' ; the lower 4 bits of port b are inputs movwf TRISB movlw b'00000000' ; and all other bits are inputs movwf TRISA bcf STATUS, RP0 ; select bank 0 again.. clrf TMR0 ; clear Timer 0 clrf INTCON ; Dissable interrupts bsf STATUS, RP0 ; select bank 1 movlw B'11000000' ; port B pullups are dissabled movwf OPTION_REG ; Interrupt of rising edge of RB0 ; Timer 0 increment from internal clock ; with a prescaler of 1:2 bcf STATUS, RP0 ; bank 0 clrf DieAVal ; zero the dice values clrf DieBVal call LEDTEST ; do a short self test. PAGE ; ;************************************************************************************* ; Main Loop. This is where most of the work is done. ;************************************************************************************* ; MAINLOOP ; enable interrupts on port B movfw PORTB movlw B'00010000' ; Leave the GIE bit off, we simply want to ; wake from sleep, not jump to an interrupt ; routine. ; and enable INT (PB0) interrupts. movwf INTCON ; set the interrupt reg. sleep ; wait for an interrupt. ; yay, we have a button down... movfw PORTB call short_delay movlw b'00000000' ; dissable interrupts movwf INTCON Button_Test call delay ; do a delay btfss PORTB,0 ; is the button still down? goto Display ; no, jump out, and display the last result Button_Loop movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable btfss PORTB,0 ; is the button still down goto Roll_Down ; no, jump out and calculate the result Call Calculate_Result; yes, lets calsulate the result Call Display_Result ; and display it. call short_delay ; (causing a pleasing display) clrf DieA clrf DieB goto Button_Loop ; keep looping till they let go of the button PAGE Roll_Down ; they have let go of the button, simulate ; the slow down of the dice roll. movlw 0x20 ; medium delay call var_delay movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable call Calculate_Result Call Display_Result movlw 0x20 call var_delay movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable call Calculate_Result Call Display_Result movlw 0x30 ; slightly longet delay call var_delay movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable call Calculate_Result Call Display_Result movlw 0x30 call var_delay movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable call Calculate_Result Call Display_Result movlw 0x40 ; long delay call var_delay movfw TMR0 ; get the current timer value movwf RandomA ; Put it into the random variable call Calculate_Result Call Display_Result PAGE ; display the result of the dice roll Display call Display_Result movlw 0x80 ; very long delay Call var_delay Clrf DieA ; we have finished showing the value Clrf DieB ; turn off all leds, and jump ; back to the main loop. ; we will sleep shortly, till ; somebody wakes us up... goto MAINLOOP ; ;************************************************************************************* ; Calculate_Result - generate numbers for both dice, based on the most ; recent random number. ; Input: RandomA ; Output: Values for DieAVal, and DieBVal. ; Comments: This is slightly bodgy. we should limit the range of output ; values to 1 - 6. The case for 0 and 7 are dealt with by ; allowing display values for 1 and 7 in the display code. ;************************************************************************************* ; Calculate_Result movfw RandomA ; get the random number andlw 7 ; get the lower 3 bits movwf DieAVal ; make them the dice value swapf RandomA, 0 andlw 7 movwf DieBVal return PAGE ;************************************************************************************* ; Display_Result - Display the values stored in DieAVal, and DieBVal on the ; LED Display. Uses Disp_DieA, and Disp_DieB. ; Input: DieAVal, and DieBVal. ; Output: Various Dice patterns ; Comments: none ;************************************************************************************* Display_Result movfw DieAVal Call Disp_DieA movfw DieBVal Call Disp_DieB return PAGE ; ;************************************************************************************* ; LEDTEST - Test all LED display possibilities, validates all Display hardware ; and firmware. ; Input: none ; Output: Various Dice patterns ; Comments: none ;************************************************************************************* ; LEDTEST clrf DieA clrf DieB movlw 1 Call Disp_DieB Call short_delay movlw 2 Call Disp_DieB Call short_delay movlw 3 Call Disp_DieB Call short_delay movlw 4 Call Disp_DieB Call short_delay movlw 5 Call Disp_DieB Call short_delay movlw 6 Call Disp_DieB Call short_delay PAGE movlw 1 Call Disp_DieA Call short_delay movlw 2 Call Disp_DieA Call short_delay movlw 3 Call Disp_DieA Call short_delay movlw 4 Call Disp_DieA Call short_delay movlw 5 Call Disp_DieA Call short_delay movlw 6 Call Disp_DieA Call short_delay clrf DieB clrf DieA return PAGE ; ;************************************************************************************* ; Disp_DieA - Causes a particular number to be displayed on the face of Dice A ; Input: Register W ; Output: A LED Pattern on the Dice ; Comments: For the valueo os register 'W'; 0 = All LEDS off ; 1 - 6 = Display the pattern for 1 - 6 ; 7 = All LEDS on (Test Mode) ;************************************************************************************* ; Disp_DieA Call DIE_Bit_Lookup movwf DieA return ; ;************************************************************************************* ; Disp_DieB - Causes a particular number to be displayed on the face of Dice B ; Input: Register W ; Output: A LED Pattern on the Dice ; Comments: For the valueo os register 'W'; 0 = All LEDS off ; 1 - 6 = Display the pattern for 1 - 6 ; 7 = All LEDS on (Test Mode) ;************************************************************************************* ; Disp_DieB Call DIE_Bit_Lookup movwf TEMP swapf TEMP,0 Movwf DieB return PAGE ; ;************************************************************************************* ; var_delay - Variable delay routine. Waste some time executing a nested loop ; Input: 'W' - Delay period (Unitless...) ; Output: Time wasted. ; Comments: none ;************************************************************************************* ; var_delay movwf J jloop2 movwf K kloop2 decfsz K,f goto kloop2 decfsz J,f goto jloop2 return ; ;************************************************************************************* ; short_delay Fixed delay time wait. Waste some time executing a nested loop ; Input: None ; Output: Time wasted. ; Comments: none ;************************************************************************************* ; short_delay movlw d'20' ; 20 is a fairly short delay. movwf J jloop1 movwf K kloop1 decfsz K,f goto kloop1 decfsz J,f goto jloop1 return PAGE ; ;************************************************************************************* ; delay Fixed delay time wait. Waste some time executing a nested loop ; Input: None ; Output: Time wasted. ; Comments: none ;************************************************************************************* ; delay movlw d'50' ; A fiarly long delay. movwf J jloop movwf K kloop decfsz K,f goto kloop decfsz J,f goto jloop return ; ;************************************************************************************* ; DIE_Bit_Lookup - A lookup table for die patterns. ; Input: 'W' 1 - 7 ; Output: Appropriate bit patterns for the value of W ; Comments: none ;************************************************************************************* ; DIE_Bit_Lookup addwf PCL,1 retlw LEDFour ; a dummy to enforce a diaplay for 0 retlw LEDOne retlw LEDTwo retlw LEDThree retlw LEDFour retlw LEDFive retlw LEDSix retlw LEDSix ; a dummy to enforce a display for 7 end