A simple Simon Says style game for use on a Moterolla HC11 processor.
*********************************************************************************** * Lab 9 - ECE 171 - Fall 2005 * * Simon Says * * * * Programmer: Sean P. O. MacCath-Moran * * Date: 07 Apr 2005 * * * * * *********************************************************************************** ******************** DATA ******************* DIPSWITCHES EQU $1003 *1 & 2 reserved for PC0 and PC1 DIPSWITCH1 EQU $01 DIPSWITCH2 EQU $02 *3 & 4 set nothing DIPSWITCH3 EQU $04 DIPSWITCH4 EQU $08 *5, 6 & 7 set nothing DIPSWITCH5 EQU $10 DIPSWITCH6 EQU $20 DIPSWITCH7 EQU $40 *Termination switch DIPSWITCH8 EQU $80 ********************* CODE ******************* ORG $AFFF RANDVAL RMB 1 ;randomizing value for next light SEQLENGTH RMB 1 ;current lengh of memorized sequence SEQUENCE RMB 40 ***************** MAIN PROGRAM *************** START ORG $8800 ;start out in timbucktoo LDS #$DFFF ;initialize stack pointer. JSR KEYSCANINIT ;initialize keypad usage JSR MIMICINIT ;initialize MIMIC usage LDY #MIMICFLAGS ;retrieve address of mimic flags WAITAGAIN JSR INITnWAIT ;wait for user to press key CLR SEQLENGTH ;init sequence length to 0 GETNEXTSEQ JSR INCSEQ ;get new value onto SEQUENCE stack JSR DISPLAY ;show the current sequence to the user JSR MIMIC ;accept sequence of button presses BRCLR 0,Y MIMICFLAGERR GETNEXTSEQ ;if no errorflag, then get next value JSR ERRORDISPLAY ;display error message to user ENDISNIGH LDAA #DIPSWITCH8 ;check for end switch BITA DIPSWITCHES BEQ ENDISWAYNEIGH JMP WAITAGAIN ;keep up with loop until switch set ENDISWAYNEIGH SWI ;ok - love ya - bye bye now * Main END ************************************************************************ *********************************************************************************** * Initialize and Wait * * * * PURPOSE: Setup for next game start and wait for user interaction * * * * USE: Call the function * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* INITPORTB EQU $1004 INITPAUSETIME EQU 2 ****************** CODE START **************** INITnWAIT PSHB ;save the B reg state PSHA ;save the A reg state PSHY ;save the X reg state CLR INITPORTB ;blank out the LEDs LDY #KEYPADFLAGS ;load X with address of flags INITnWAIT1 LDAA #INITPAUSETIME ;setup to pause for about 1/4 second JSR DELAY10X ;pause for x/10th second INC RANDVAL ;set random value to next digit JSR KEYSCAN ;check status of keypad BRCLR 0,Y KEYPADFLAGPRE INITnWAIT1 ;wait until a key is pressed LDAB KEYPADKEYCHK ;retrieve the key being pressed JSR DISPLAYKEY ;display this key to user while it's being pressed INITnWAIT2 JSR KEYSCAN ;check status of keypad BRSET 0,Y KEYPADFLAGPRE INITnWAIT2 ;wait until key is released CLR INITPORTB ;blank out the LEDs PULY ;restore the X reg state PULA ;restore the A reg state PULB ;restore the B reg state RTS ;return to sender *weg* * INITnWAIT END ******************************************************************* *********************************************************************************** * Increment Sequence * * * * PURPOSE: generate the next value in the sequence * * * * USE: Call the function * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* INCSEQVALMASK EQU %00000011 ;mask to retrieve bits used in random value ****************** CODE START **************** INCSEQ PSHX ;save the X reg state PSHB ;save the B reg state PSHA ;save the A reg state LDX #SEQUENCE ;retrieve memory position of SEQUENCE LDAB SEQLENGTH ;retrieve lench of SEQUENCE ABX ;move X to end of sequence LDAA RANDVAL ;retrieve the current random value ANDA #INCSEQVALMASK ;keep only those values in mask INCA ;add 1 to value for use as index STAA 0,X ;store new value at end of SEQUENCE INC SEQLENGTH ;increase length of sequence by 1 PULA ;restore the A reg state PULB ;restore the B reg state PULX ;restore the X reg state RTS ;return to sender *weg* * INITnWAIT END ******************************************************************* *********************************************************************************** * Accept Sequence * * * * PURPOSE: Accpept button presses from user and check them against the SEQUENCE. * * If a wrong key is pressed or if more than three seconds elapses in * * waiting for a button, then MIMIC will abort with an error. If all * * keys are pressed correctly, then MIMIC returns with no ERROR. * * * * USE: Call the function * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* MIMICFLAGERR EQU %00000001 ;flag for user error detected MIMICFLAGB EQU %00000010 ;flag for ? MIMICFLAGC EQU %00000100 ;flag for ? MIMICFLAGD EQU %00001000 ;flag for ? MIMICFLAGE EQU %00010000 ;flag for ? MIMICFLAGF EQU %00100000 ;flag for ? MIMICFLAGG EQU %01000000 ;flag for ? MIMICFLAGH EQU %10000000 ;flag for ? MIMICPAUSETIM EQU 2 MIMICBCNTRVAL EQU 15 MIMICPORTB EQU $1004 ****************** CODE ********************** MIMICFLAGS RMB 1 ;status flags for MIMIC ;0 = Error, ;1 = ?, 2 = ?, 3 = ?, 4 = ?, 5 = ?, 6 = ?, 7 = ? MIMICBCNTR RMB 1 ;BCounter value MIMICSCNTR RMB 1 ;SEQLENGTH value ****************** CODE INITIALIZATION ******* MIMICINIT CLR MIMICFLAGS ;clear all flags RTS ;return to sender *weg* ****************** CODE START **************** MIMIC PSHB ;save the B reg state PSHA ;save the A reg state PSHY ;save the X reg state PSHX ;save the X reg state LDY #MIMICFLAGS ;retrieve location of flags BSET 0,Y MIMICFLAGERR ;set the error flag LDY #KEYPADFLAGS ;load Y with address of flags LDX #SEQUENCE ;retrieve memory position of SEQUENCE LDAA SEQLENGTH ;retrieve the SEQLENGTH STAA MIMICSCNTR ;init the total sequence length count MIMICNEXTBUT LDAA #MIMICBCNTRVAL ;retrive BCOUNTER value STAA MIMICBCNTR ;initialize BCOUNTER value MIMICWAITBUT INC RANDVAL ;set random value to next digit LDAA #MIMICPAUSETIM ;setup pause count JSR DELAY10X ;pause for x/10th second DEC MIMICBCNTR ;count down pause timer BEQ MIMICEND ;if out of time, then end JSR KEYSCAN ;check status of keypad BRCLR 0,Y KEYPADFLAGPRE MIMICWAITBUT ;wait for button pressed status LDAA 0,X ;retrieve value pointed to by stack CMPA KEYPADKEYCHK ;check for match with value from KEYSCAN BNE MIMICEND ;wrong button pressed LDAB KEYPADKEYCHK ;retrieve the key being pressed JSR DISPLAYKEY ;display this key to user while it's being pressed MIMICWAITREL JSR KEYSCAN ;check status of keypad BRSET 0,Y KEYPADFLAGPRE MIMICWAITREL ;wait for button released status CLR MIMICPORTB ;blank out the LEDs INX ;point at next value DEC MIMICSCNTR ;count off another success BNE MIMICNEXTBUT ;go wait for next button press if not done LDY #MIMICFLAGS ;retrieve location of flags BCLR 0,Y MIMICFLAGERR ;clear the error flag MIMICEND PULX ;restore the X reg state PULY ;restore the X reg state PULA ;restore the A reg state PULB ;restore the B reg state RTS ;return to sender *weg* * INITnWAIT END ******************************************************************* *********************************************************************************** * Display Sequence * * * * PURPOSE: Display the required sequence to the user * * * * USE: Call the function * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* DISPLAYPORTB EQU $1004 DISPLAYPAUSE EQU 3 ****************** CODE ********************** DISPLAYINDEX RMB 1 ****************** CODE START **************** DISPLAY PSHB ;save the B reg state PSHA ;save the A reg state PSHX ;save the X reg state LDAA SEQLENGTH ;retrieve current length STAA DISPLAYINDEX ;init index to length LDAA #DISPLAYPAUSE ;init time to pause for each cycle LDX #SEQUENCE ;point at the next value to display DISPLAYNEXT CLR DISPLAYPORTB ;clear the LEDs JSR DELAY10X ;pause for DISPLAYPAUSE/10th sec LDAB 0,X ;retrieve the next value in SEQUENCE JSR DISPLAYKEY ;display the next value in SEQUENCE JSR DELAY10X ;pause for DISPLAYPAUSE/10th sec INX ;point at the next value to display DEC DISPLAYINDEX ;completed another loop BNE DISPLAYNEXT ;show next value if not done CLR DISPLAYPORTB ;clear the LEDs PULX ;restore the X reg state PULA ;restore the A reg state PULB ;restore the B reg state RTS ;return to sender *weg* * INITnWAIT END ******************************************************************* *********************************************************************************** * Check Next Key * * * * PURPOSE: Retrieve the next key being pressed, returning indicators via flags * * to determine if a key has been pressed, is being pressed, or was just * * pressed. * * * * USE: Call function and examine flags to determine keypad status. * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* KEYPADLAST EQU 3333 ;Holds the last key value pressed KEYPADPRTG EQU $6200 ;keypad memory address KEYPADPRTGMSK EQU $6202 ;keypad mask memory address KEYPADPRTGINI EQU %00001111 ;mask for DDRG KEYPADCNTROWS EQU 4 ;number of rows of buttons to initialize to KEYPADCNTCOLS EQU 4 ;number of columns of buttons to initialize to KEYPADCNTBUTS EQU 16 ;total number of buttons to initialize too KEYPADSCANPAT EQU %11110111 ;starting scan pattern for keypad KEYPADFLAGDET EQU %00000001 ;flag for no current activity detected KEYPADFLAGPRE EQU %00000010 ;flag for key is currenty being pressed by user KEYPADFLAGPRO EQU %00000100 ;flag for key has been released and is ready to be processed KEYPADFLAGD EQU %00001000 ;flag for ? KEYPADFLAGE EQU %00010000 ;flag for ? KEYPADFLAGF EQU %00100000 ;flag for ? KEYPADFLAGG EQU %01000000 ;flag for ? KEYPADFLAGH EQU %10000000 ;flag for ? ********************* CODE ******************* KEYPADFLAGS RMB 1 ;set of byte flags for use by Get Next Key function (0 = false, 1 = true) ;bit 0: No current activity detected ;bit 1: Key is currently being pressed ;bit 2: Key is ready to be processed ;bit 3: ;bit 4: ;bit 5: ;bit 6: ;bit 7: KEYPADSMASK RMB 1 ;scan pattern for keypad KEYPADCURRENT RMB 1 ; KEYPADKEYCHK RMB 1 ; KEYPADROWNUM RMB 1 ; KEYPADCOLNUM RMB 1 ; ****************** CODE INITIALIZATION ******* KEYSCANINIT PSHA ;save the A reg state LDAA #KEYPADPRTGINI ;retrieve the DDRG mask and ... STAA KEYPADPRTGMSK ;... initialize the DDRG mask CLR KEYPADFLAGS ;clear the flags register PULA ;restore the A reg state RTS ;return to sender *weg* ****************** CODE START **************** KEYSCAN PSHX ;save the X reg state PSHB ;save the B reg state PSHA ;save the A reg state LDAA #KEYPADCNTROWS ;retrieve the row count and ... STAA KEYPADROWNUM ;... initialize the number of rows LDAA #KEYPADCNTBUTS ;retrive the button count and ... STAA KEYPADCURRENT ;... initialize the current button position LDAA #KEYPADSCANPAT ;retrieve the starting scan pattern ... STAA KEYPADSMASK ;... initialize the current mask ;why isn't this working???? ;BCLR KEYPADFLAGS,KEYPADFLAGPRE ;clear the "key is being pressed" flag LDAB #KEYPADFLAGPRE ;retrieve the "key is being pressed" flag COMB ;reverse the flag to create a mask ANDB KEYPADFLAGS ;clear the "key is being pressed" flag if it was set STAB KEYPADFLAGS ;store the resulting flag set KEYPADOUTTER LDAA KEYPADSMASK ;Retrieve the current mask and ... STAA KEYPADPRTG ;... set the keypad mask to this value LDAA KEYPADPRTG ;retrieve the current row from the keypad (leave in A reg) *Start Process Row LDAB #KEYPADCNTCOLS ;retrieve the coloumn count and ... STAB KEYPADCOLNUM ;... initialize the number of columns KEYPADINNER LSLA ;rotate the PortG values to find if next bit is set BCS KEYPADSKIPKEYCAPTURE ;if carry isn't set then don't capture the key LDAB KEYPADCURRENT ;retrieve the current key value STAB KEYPADKEYCHK ;store the current key value LDAB KEYPADFLAGS ;retrieve the set of flags ORAB #KEYPADFLAGPRE ;set the "key is being pressed" flag ORAB #KEYPADFLAGPRO ;set the "ready to process" flag STAB KEYPADFLAGS ;store the resulting flag set KEYPADSKIPKEYCAPTURE ;target for jumping over the key kapture DEC KEYPADCURRENT ;decrement current key value DEC KEYPADCOLNUM ;decrement column number BNE KEYPADINNER ;check next column *End Process Row LSR KEYPADSMASK ;rotate the mask to set the next entry point DEC KEYPADROWNUM ;decrement row number BNE KEYPADOUTTER ;check next row PULA ;restore the A reg state PULB ;restore the B reg state PULX ;restore the X reg state RTS ;return to sender *weg* * KEYPADLAST END ****************************************************************** *********************************************************************************** * User Error * * * * PURPOSE: Indicates to the user that an error has occured * * * * USE: Call the function * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* ERRFLASHES EQU 4 ;20000 c / (3c + 3c) -- pause 1/100th sec ERRSHOWTIME EQU 2 ERRPORTB EQU $1004 ****************** CODE START **************** ERRORDISPLAY PSHB ;save the B reg state PSHA ;save the A reg state CLR ERRPORTB ;clear out the LED lights display LDAA #ERRSHOWTIME ;load the time (in x/100ths) to pause LDAB #ERRFLASHES ;load port B with number of flashes to execute DISPLAYERRLP JSR DELAY10X ;pause for x/10th second COM ERRPORTB ;turn on all port be lights JSR DELAY10X ;pause for x/10th second COM ERRPORTB ;turn off all port be lights DECB ;count off a completed loop BNE DISPLAYERRLP ;show next flash if not done PULA ;restore the A reg state PULB ;restore the A reg state RTS ;return to sender *weg* * Password Rejected END *********************************************************** *********************************************************************************** * Display LED Value At Pos * * * * PURPOSE: Display a specific value in LED * * * * USE: Reg B = what position value to display (0-4) * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* DISPLAYKEYPB EQU $1004 ********************* CODE ******************* DISPLAYKEYTABLE ;values of display mask FCB %00000000 ;dummey value FCB %10000000 ;1 (leftmost) FCB %01000000 ;2 (second from left) FCB %00100000 ;3 (second from right) FCB %00010000 ;4 (rightmost) ****************** CODE START **************** DISPLAYKEY PSHX ;save the X reg state PSHB ;save the B reg state CLR DISPLAYKEYPB ;clear the display in port B TSTB ;make sure position is not set to 0 BEQ DISPLAYKEYEND ;jump to end if it is LDX #DISPLAYKEYTABLE ABX LDAB 0, X ;retrieve the display mask of current digit STAB DISPLAYKEYPB ;store the digit mask to display into port B DISPLAYKEYEND PULB ;restore the B reg state PULX ;restore the X reg state RTS ;return to sender *weg* * Display LED Value At Pos END **************************************************** *********************************************************************************** * PAUSE BY X/100th SECOND * * * * PURPOSE: Pauses program execution for X/10th seconds. X is indicated by the * * value in the A register * * * * USE: Load the A register with the number of 1/10th seconds to pause * * * * MODIFIES: Flags * * * *********************************************************************************** ********************* DATA ******************* PAUSE100thVAL EQU 3333 ;20000 c / (3c + 3c) -- pause 1/100th sec PAUSE10thVAL EQU 10 ;bring pause time incrments up to a 10th ****************** CODE START **************** DELAY10X PSHX ;save the X reg state PSHB ;save the B reg state PSHA ;save the A reg state PAUSE10th LDAB #PAUSE10thVAL ;set B reg to count of 10 PAUSE100th LDX #PAUSE100thVAL ;load X with 1/100th worth of counter PAUSEINNER DEX ;count down one in pause loop BNE PAUSEINNER ;continue loop if not done with 1/100th pause DECB ;count down another 1/100 sec BNE PAUSE100th ;continue loop if not done with 1/10th pause DECA ;decrement user specified pause count BNE PAUSE10th ;continue loop if not done with this pause PULA ;restore the A reg state PULB ;restore the B reg state PULX ;restore the X reg state RTS ;return to sender *weg* * PAUSE END *********************************************************************** ENDOFCODE
Comments
Post new comment