Program for PIC16F628 micro
The following sets up the ports and the equates for the notes for the tunes:
;**************************************************************** ;* MEMORY GAME - Simon * ;**************************************************************** ;Port A definitions PORTA_CONFIG1 equ 0xFD ;1111 1110 0 ;not used BUZZER equ 1 ;buzzer output 2 ;not used 3 ;not used 4 ;not used ;Port B definitions PORTB_CONFIG1 equ 0x0F ;bit7: out,out,out,out,in,in,in,in :bit0 KEY_RED equ 0 ;red key input - bit0 KEY_GREEN equ 1 ;green key input - bit1 KEY_YELLOW equ 2 ;yellow key input - bit2 KEY_ORANGE equ 3 ;orange key input - bit3 LED_RED equ 4 ;red led output - bit4 LED_GREEN equ 5 ;green led output - bit5 LED_YELLOW equ 6 ;yellow led output- bit6 LED_ORANGE equ 7 ;orange led output- bit7 RAM_START equ 0x20 ;start of global variable ram LINE_OFFSET equ 0x3A ;start of step memory in ram area RECORD_STEPS equ 0x00 ;eeprom address for step record ;Data for song notes ;Value = 10's of microseconds ;octave 1 NOTE_G0 equ D'255' ;196 Hz NOTE_A0 equ D'227' ;220 Hz NOTE_B0 equ D'202' ;247 Hz ;octave 2 NOTE_C1 equ D'191' ;262 Hz NOTE_D1 equ D'170' ;294 Hz NOTE_E1 equ D'152' ;330 Hz NOTE_F1 equ D'143' ;349 Hz NOTE_G1 equ D'128' ;392 Hz NOTE_A1 equ D'114' ;440 Hz NOTE_B1 equ D'101' ;494 Hz ;octave 3 NOTE_C2 equ D'95' ;524 Hz NOTE_D2 equ D'85' ;588 Hz NOTE_E2 equ D'76' ;660 Hz NOTE_F2 equ D'72' ;698 Hz NOTE_G2 equ D'64' ;784 Hz NOTE_A2 equ D'57' ;880 Hz NOTE_B2 equ D'51' ;988 Hz ;octave 4 NOTE_C3 equ D'48' ;1048 Hz NOTE_D3 equ D'43' ;1176 Hz NOTE_E3 equ D'38' ;1320 Hz NOTE_F3 equ D'36' ;1396 Hz NOTE_G3 equ D'32' ;1568 Hz NOTE_A3 equ D'28' ;1760 Hz NOTE_B3 equ D'25' ;1976 Hz ;length of notes ;"tempo"(nomalized) length is set in SoundPlay function by timerb LENGTH_SEMIBREVE equ 0x20 ;tempo LENGTH_MINIM equ 0x10 ;tempo/2 LENGTH_CROTCHET equ 0x08 ;tempo/4 LENGTH_QUAVER equ 0x04 ;tempo/8 LENGTH_SEMIQUAVER equ 0x02 ;tempo/16 LENGTH_DEMISEMIQUAVER equ 0x01 ;tempo/32 SONG_HEY_JUDE_LEN equ D'68' ;total No of notes + lengths SONG_OSUSANA_LEN equ D'108' SONG_DEATHMARCH_LEN equ D'22' KEY_RED_SOUND equ NOTE_C2 KEY_GREEN_SOUND equ NOTE_E2 KEY_YELLOW_SOUND equ NOTE_G2 KEY_ORANGE_SOUND equ NOTE_B2
The following contains all the comments for the Simon program:
Note: __Config 3F18h covers the following:
_CP_off & _LVP_off & _PWRTE_off & Boden_off & _WDT_off & _IntRC_osc_I/O
where:
CP = code protection
LVP = low-voltage programming
PWRTE = power-up timer
Boden = Brown-out detector
WDT = watchdog timer
IntRC_osc_I/O = internal RC for 4MHz - all pins for in-out
You can simply write: __Config 3F18h
or:
__Config _CP_off & _LVP_off & _PWRTE_off & Boden_off & _WDT_off & _IntRC_osc_I/O
or select the boxes in IC Prog at the time of burning the chip.
In all cases the chip will get burnt with the correct configuration value and when it is copied, the copy will automatically have the correct configuration value.
;**************************************************************** ;* Memory Game - SIMON * ;**************************************************************** list p=16f628, ;microcontroller include "p16F628.inc" ;registers for F628 include "simon628.inc" ;Simon definitions for F628 __Config 3F18h ;**************************************************************** ;global variables ;Files for PIC16F628 start at 0x20 ;**************************************************************** timera equ 0x2c ;general purpose timer timerb equ 0x2d ;general purpose timer timerc equ 0x2e ;general purpose timer timerd equ 0x2f ;general purpose timer note_select equ 0x30 ;selection of note note_tone equ 0x31 ;frequency of note note_length equ 0x32 ;length of note note_tempo equ 0x33 ;tempo of song random equ 0x34 ;random number key equ 0x35 ;key last pressed column_w equ 0x36 ;write pointer in sequence table X line_w equ 0x37 ;write pointer in sequence table Y column_r equ 0x38 ;read pointer in sequence table X line_r equ 0x39 ;read pointer in sequence table Y steps0104 equ 0x3a ;step memory steps0508 equ 0x3b ;step memory steps0912 equ 0x3c ;step memory steps1316 equ 0x3d ;step memory steps1720 equ 0x3e ;step memory steps2124 equ 0x3f ;step memory steps2528 equ 0x40 ;step memory steps2932 equ 0x41 ;step memory steps3336 equ 0x42 ;step memory steps3740 equ 0x43 ;step memory steps4144 equ 0x44 ;step memory steps4548 equ 0x45 ;step memory steps4952 equ 0x46 ;step memory steptemp equ 0x47 ;temporary step memory stepsgood equ 0x48 ;number of successful steps by player ;**************************************************************** ;reset vector ;**************************************************************** reset: org 0x00 ;reset vector address goto Begin ;start program execution Begin: org 0x06 ;start of program goto start ;**************************************************************** ; Data tables for Songs ;**************************************************************** SongHeyJude: addwf pcl,f ;jump forward according to W value retlw NOTE_G1 ;Hey retlw LENGTH_CROTCHET retlw NOTE_E1 ;jude retlw LENGTH_MINIM retlw NOTE_E1 ;don't retlw LENGTH_QUAVER retlw NOTE_G1 ;make retlw LENGTH_QUAVER retlw NOTE_A1 ;it retlw LENGTH_QUAVER retlw NOTE_D1 ;bad, retlw LENGTH_MINIM retlw NOTE_D1 ;take retlw LENGTH_QUAVER retlw NOTE_E1 ;a retlw LENGTH_QUAVER retlw NOTE_F1 ;sad retlw LENGTH_CROTCHET retlw NOTE_C2 ;song retlw LENGTH_MINIM retlw NOTE_C2 ;and retlw LENGTH_QUAVER retlw NOTE_B1 ;make retlw LENGTH_QUAVER retlw NOTE_G1 ;it retlw LENGTH_QUAVER retlw NOTE_A1 ;bet- retlw LENGTH_QUAVER retlw NOTE_G1 ;ter. retlw LENGTH_MINIM retlw NOTE_G1 ;Re- retlw LENGTH_QUAVER retlw NOTE_A1 ;mem- retlw LENGTH_QUAVER retlw NOTE_A1 ;ber retlw LENGTH_CROTCHET retlw NOTE_A1 ;to retlw LENGTH_QUAVER retlw NOTE_D2 ;let retlw LENGTH_SEMIQUAVER retlw NOTE_C2 ;her retlw LENGTH_CROTCHET retlw NOTE_B1 ;in retlw LENGTH_QUAVER retlw NOTE_C2 ;to retlw LENGTH_QUAVER retlw NOTE_A1 ;your retlw LENGTH_CROTCHET retlw NOTE_G1 ;heart, retlw LENGTH_MINIM retlw NOTE_C1 ;then retlw LENGTH_QUAVER retlw NOTE_D1 ;you retlw LENGTH_QUAVER retlw NOTE_E1 ;can retlw LENGTH_QUAVER retlw NOTE_A1 ;start retlw LENGTH_MINIM retlw NOTE_G1 ;to retlw LENGTH_QUAVER retlw NOTE_F1 ;make retlw LENGTH_QUAVER retlw NOTE_E1 ;it retlw LENGTH_QUAVER retlw NOTE_C1 ;bet- retlw LENGTH_QUAVER retlw NOTE_C1 ;ter. retlw LENGTH_MINIM SongOSusana: addwf pcl,f ;jump forward according to W value retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_QUAVER retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_QUAVER retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_MINIM retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_QUAVER retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_MINIM retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_F2 retlw LENGTH_CROTCHET retlw NOTE_F2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_MINIM retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_QUAVER retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_A2 retlw LENGTH_CROTCHET retlw NOTE_G2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_MINIM retlw NOTE_D2 retlw LENGTH_QUAVER retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_E2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_CROTCHET retlw NOTE_D2 retlw LENGTH_CROTCHET retlw NOTE_C2 retlw LENGTH_SEMIBREVE SongDeathMarch: addwf pcl,f ;jump forward according to W value retlw NOTE_C1 retlw LENGTH_MINIM retlw NOTE_C1 retlw LENGTH_QUAVER retlw NOTE_C1 retlw LENGTH_CROTCHET retlw NOTE_C1 retlw LENGTH_QUAVER retlw NOTE_C1 retlw LENGTH_CROTCHET retlw NOTE_E1 retlw LENGTH_QUAVER retlw NOTE_D1 retlw LENGTH_CROTCHET retlw NOTE_C1 retlw LENGTH_QUAVER retlw NOTE_C1 retlw LENGTH_CROTCHET retlw NOTE_B0 retlw LENGTH_CROTCHET retlw NOTE_C1 retlw LENGTH_MINIM ;**************************************************************** ;Name : Start ;Description : set-up ports A and B ;**************************************************************** Start: MOVLW 07 ;to disable the comparators MOVWF 0x1F ;file 1F is the CMCON file bsf status,rp0 ;select bank1 register movlw PORTA_CONFIG1 ;porta configuration movwf 0x05 movlw PORTB_CONFIG1 ;portb configuration movwf 0x06 movlw 0x81 ;Fosc/4;No prescaler movwf 0x81 ;Timer configuration in option register bcf status,rp0 ;select bank0 registers NewGame: clrf porta ;turn off status leds clrf portb ;turn off all leds movlw RAM_START ;clear global variables movwf fsr S1: clrf indf incf fsr,f btfss fsr,6 goto S1 movf line_w,w ;initialise step memory base addlw LINE_OFFSET ;put 3Ah into file 37h at beginning movwf line_w call ClearRecord ;clear record steps? call Introduction ;introductory song & calibration ;**************************************************************** ;Name : Mainloop ;Description : ;**************************************************************** Mainloop: call MakeStep ;create a new step & add it to sequence call ShowSequence ;show sequence on LEDs call GetUserSequence ;player's sequence (result returned in W) ;W=1 - correct, W=0 - wrong xorlw 1 ;is player's sequence correct? btfss status,z ;yes - ignore next instruction goto SequenceBad ;no - it's wrong! incf stepsgood,f ;another successful step by player call Delay150 call Delay150 call Delay150 movf line_w,w ;max sequence reached (52 steps)? xorlw D'52' btfss status,z goto Mainloop ;no - do another step movf column_w,w xorlw D'3' btfss status,z goto Mainloop ;no - do another step goto SequenceRecord ;yes - max sequence correct! ;**************************************************************** ;Name : ClearRecord ;Description : allows the player to clear the current step ; : record. Player must press one of the keys ; : at power-on for EEPROM to be set to zero ;**************************************************************** ClearRecord: movf portb,w ;test for a key press andlw 0x0f ;mask keys xorlw 0x00 ;are any keys being pressed? btfsc status,z ;yes - skip next instruction return ;no - return! movlw RECORD_STEPS ;clear step record in EEPROM movwf eeadr clrf eedata bsf status,rp0 ;select bank1 bsf eecon1,wren ;enable write movlw 0x55 ;unlock codes movwf eecon2 movlw 0xaa movwf eecon2 bsf eecon1,wr ;write begins bcf eecon1,wren ;disable further writes Crec: btfsc eecon1,wr ;wait to write complete goto Crec bcf status,rp0 ;select bank0 movlw 0x02 movwf note_tempo call SoundRisingRocket ;cleared record indication return ;**************************************************************** ;Name : Introduction ;Description : plays the introductory "hey jude" song until ; : one of the keys is pressed. ;Inputs : none ;**************************************************************** Introduction: clrf note_select ;beginning of "hey jude" song Intr1: incf steptemp,f movf steptemp,w andlw 0x03 movwf random call Delay150 call ShowLed ;show it on leds movlw 0x10 movwf note_tempo ;speed of song movf note_select,w ;get next "hey jude" note call SongHeyJude ;returned in W movwf note_tone incf note_select,f movf note_select,w ;get length of note call SongHeyJude movwf note_length call SoundPlay ;play music clrf portb ;turn all leds off incf note_select,f ;select next note movf note_select,w xorlw SONG_HEY_JUDE_LEN ;end of song? btfsc status,z ;no - skip next instruction clrf note_select ;yes - play it again from beginning movf portb,w ;test for a key press andlw 0x0f ;mask keys xorlw 0x00 ;are any keys being pressed? btfsc status,z ;yes - skip next instruction goto Intr1 ;no - keep playing music! movlw 0x02 movwf note_tempo call SoundRisingRocket ;start new game indication return ;start new game ;**************************************************************** ;Name : SoundPlay ;Description : plays a tone on the buzzer ;Inputs : note_tone - frequency of the tone ; : note_length - length of note ; : note_tempo - speed of song ;**************************************************************** SoundPlay: clrf timerc ;initialise timer Sp1: movf timerc,w xorwf note_length,w ;end of note? btfsc status,z ;no - skip next instruction return ;yes - exit function movf note_tempo,w movwf timerb Sp2: movf note_tone,w ;frequency bsf porta,BUZZER ;high time call SoundDelay bcf porta,BUZZER ;low time call SoundDelay decfsz timerb,f goto Sp2 incf timerc,f goto Sp1 ;**************************************************************** ;Name : SoundDelay ;Description : a delay used whenever sound ; : must be produced on the piezo diaphragm. The W register ; : contains the number of cycles to wait (in 10's ; : of microseconds. ;Inputs : W - contains the note to be played ; : ie. W=191, delay==1,91msec ;**************************************************************** SoundDelay: movwf timera Sd1: nop nop nop nop nop nop nop decfsz timera,f goto Sd1 return ;**************************************************************** ;Name : SoundRisingRocket ;Description : rising rocket sound effect ;Inputs : note_tempo - speed of rocket ;Outputs : none ;**************************************************************** SoundRisingRocket: clrf note_tone ;make tone=255 - start comf note_tone,f ;with lowest frequency Srr1: movlw LENGTH_DEMISEMIQUAVER movwf note_length call SoundPlay decfsz note_tone,f ;do a "rising" sound goto Srr1 CALL Delay150 CALL Delay150 CALL Delay150 CALL Delay150 CALL Delay150 CALL Delay150 CALL Delay150 CALL Delay150 return ;**************************************************************** ;Name : MakeRandom ;Description : reads the PIC's timer register at various ; : "random" intervals caused by the player ;Inputs : pressing one of the keys. ;Outputs : random number will be 0, 1, 2, 3 ;**************************************************************** MakeRandom: movf tmr0,w andlw 0x03 ;mask all but bit0 and bit1 movwf random ;move random number into file 34h return ;**************************************************************** ;Name : MakeStep ;Description : gets a random number and stores it into the ; : next available position in table. ;**************************************************************** MakeStep: call MakeRandom ;ascertain random number movf line_w,w ;get current line movwf fsr ;pointer to next available memory bcf status,c ;initialise carry movf column_w,w ;get current column xorlw 0 BTFSC STATUS,Z GOTO GCol0 ;column=0 - don't shift xorlw 0x01 BTFSC STATUS,Z GOTO GCol1 ;column=1 - shift random 2 times XORLW 0x03 BTFSC STATUS,Z GOTO GCol2 ;column=2 - shift random 4 times rlf random,f ;column=3 - shift random 6 times rlf random,f GCol2: rlf random,f rlf random,f GCol1: rlf random,f rlf random,f GCol0: movf indf,w ;get current memory byte of table iorwf random,w ;merge new random number into table movwf indf ;restore in sequence table incf column_w,f ;update column btfss column_w,2 ;end of this memory byte in table? return ;no - return clrf column_w ;yes - select next memory byte in table incf line_w,f return ;**************************************************************** ;Name : ShowSequence ;Description : displays the step sequence that the player ; : has to remember and repeat. ;**************************************************************** ShowSequence: clrf column_r ;begin at start of step sequence movlw LINE_OFFSET movwf line_r Ss1: movf line_r,w movwf fsr movf indf,w movwf steptemp movf column_r,w ;get current column xorlw 0 BTFSC STATUS,Z GOTO SCol0 ;column=0 - don't shift xorlw 0x01 BTFSC STATUS,Z GOTO SCol1 ;column=1 - shift random 2 times XORLW 0x03 BTFSC STATUS,Z GOTO SCol2 ;column=2 - shift random 4 times rrf steptemp,f ;column=3 - shift random 6 times rrf steptemp,f SCol2: rrf steptemp,f rrf steptemp,f SCol1: rrf steptemp,f rrf steptemp,f SCol0: movf steptemp,w ;get current memory byte of table andlw 0x03 ;mask bits 2-7 movwf random call ShowStep ;display LED according to stored value call Delay150 ;wait a little after player call Delay150 ;has pressed a key call Delay150 incf column_r,f ;update column btfsc column_r,2 ;overflow? goto Colov1 ;yes Ss2: movf column_r,w ;no xorwf column_w,w ;column pointers the same? btfss status,z goto Ss1 ;no - at least another step to show movf line_r,w ;yes xorwf line_w,w ;reached the end of sequence? btfsc status,z ;no - jump next instruction return ;yes - sequence complete! goto Ss1 ;at least another step to show Colov1: clrf column_r incf line_r,f goto Ss2 ;**************************************************************** ;Name : ShowStep ;Description : turns on one of the LEDs and beeps according to ; : the random number & level of difficulty ;Inputs : random - random number ;Outputs : none ;**************************************************************** ShowStep: call ShowLed ;show random number on led movwf note_tone ;ShowLed returns with beep value in W movlw LENGTH_SEMIBREVE movwf note_length movlw 0x10 ;easy level btfss porta,LEVEL ;get level of difficulty movlw 0x01 ;hard level movwf note_tempo ;speed of beep call SoundPlay ;play button beep clrf portb ;turn all leds off return ;**************************************************************** ;Name : ShowLed ;Description : turns on one of the LEDs according to the random ; : number & prepares W with tone value ;Inputs : random - random number ;Outputs : W - value of tone frequency ;**************************************************************** ShowLed: movf random,w ;get random number xorlw 0 BTFSC STATUS,Z goto ShowRed ;random=0 xorlw 0x01 BTFSC STATUS,Z GOTO ShowGreen ;random=1 xorlw 0x03 BTFSC STATUS,Z GOTO ShowYellow ;random=2 goto ShowOrange ;random=3 ShowRed: bsf portb,LED_RED ;turn on red led retlw KEY_RED_SOUND ;tone frequency ShowGreen: bsf portb,LED_GREEN ;turn on green led retlw KEY_GREEN_SOUND ;tone frequency ShowYellow: bsf portb,LED_YELLOW ;turn on yellow led retlw KEY_YELLOW_SOUND ;tone frequency ShowOrange: bsf portb,LED_ORANGE ;turn on orange led retlw KEY_ORANGE_SOUND ;tone frequency ;**************************************************************** ;Name : GetUserSequence ;Description : checks the player's sequence to that required ;Inputs : none ;Outputs : W=0 : player has made a mistake ; : W=1 : player has successfully repeated sequence ;**************************************************************** GetUserSequence: clrf column_r ;begin at start of step sequence movlw LINE_OFFSET movwf line_r Us1: movf line_r,w movwf fsr movf indf,w movwf steptemp movf column_r,w ;get current column xorlw 0 BTFSC STATUS,Z GOTO UCol0 ;column=0 - don't shift xorlw 0x01 BTFSC STATUS,Z GOTO UCol1 ;column=1 - shift random 2 times xorlw 0x03 BTFSC STATUS,Z GOTO UCol2 ;column=2 - shift random 4 times UCol3: rrf steptemp,f ;column=3 - shift random 6 times rrf steptemp,f UCol2: rrf steptemp,f rrf steptemp,f UCol1: rrf steptemp,f rrf steptemp,f UCol0: movf steptemp,w ;get current memory byte of table andlw 0x03 ;mask bits 2-7 movwf random call Keypad ;get player's input - returned in W ;W=0 - no key pressed (timeout) ;W=1 - player has pressed a key xorlw 0 ;did player press a key? btfsc status,z ;yes - jump next instruction retlw 0 ;no - exit function movf key,w ;compare pressed key with step xorwf random,w ;is it the same? btfss status,z ;yes - jump next instruction retlw 0 ;no - incorrect, exit function incf column_r,f ;update column btfsc column_r,2 ;overflow? goto Colov2 ;yes Us2: movf column_r,w ;no xorwf column_w,w ;column pointers the same? btfss status,z goto Us1 ;no - at least another step to show movf line_r,w ;yes xorwf line_w,w ;reached the end of sequence? btfsc status,z ;no - jump next instruction retlw 1 ;yes - sequence complete! goto Us1 ;at least another step to show Colov2: clrf column_r incf line_r,f goto Us2 ;**************************************************************** ;Name : Keypad ;Description : scans the keys for a press and lights up the ; : corresponding LED and beeps. ;Inputs : none ;Outputs : W=0 : key timeout - no key has been pressed ; : W=1 : key has been pressed ; : key : 0=red,1=green,2=yellow,3=orange ;**************************************************************** Keypad: clrf key ;initialise key movlw 0x07 ;assume easy level - 5 sec timeout btfss porta,LEVEL ;get level of difficulty movlw 0x03 ;hard level - 2 sec timeout movwf timerc Kp2: movlw 0xff movwf timerb Kp1: movlw 0xff movwf timera Kwait: btfsc portb,KEY_RED goto KeyRed btfsc portb,KEY_GREEN goto KeyGreen btfsc portb,KEY_YELLOW goto KeyYellow btfsc portb,KEY_ORANGE goto KeyOrange decfsz timera,f goto Kwait decfsz timerb,f goto Kp1 decfsz timerc,f goto Kp2 retlw 0 ;player hasn't pressed key! KeyRed: bsf portb,LED_RED ;turn on red led clrf key ;key=0 movlw KEY_RED_SOUND ;tone frequency goto Beep1 KeyGreen: bsf portb,LED_GREEN ;turn on green led bsf key,0 ;key=1 movlw KEY_GREEN_SOUND ;tone frequency goto Beep1 KeyYellow: bsf portb,LED_YELLOW ;turn on yellow led bsf key,1 ;key=2 movlw KEY_YELLOW_SOUND ;tone frequency goto Beep1 KeyOrange: bsf portb,LED_ORANGE ;turn on orange led bsf key,0 ;key=3 bsf key,1 movlw KEY_ORANGE_SOUND ;tone frequency Beep1: movwf note_tone ;save tone movlw LENGTH_SEMIBREVE movwf note_length movlw 0x03 movwf note_tempo ;speed of beep Beep2: call SoundPlay ;play button beep movf portb,w ;test for a key press andlw 0x0f ;mask keys xorlw 0x00 ;are any keys being pressed? btfss status,z ;no - skip next instruction goto Beep2 ;yes - keep beeping! clrf portb ;turn off all leds retlw 1 ;return to calling function ;**************************************************************** ;Name : SequenceBad ;Description : player has made a mistake - show player the ; : correct sequence. Test to see if a record has ; : been made. ;**************************************************************** SequenceBad: movlw 0x01 movwf note_tempo call SoundRisingRocket movlw 0x01 movwf note_tempo call SoundRisingRocket call ShowSequence ;replay proper sequence again movlw 0x01 movwf note_tempo call SoundRisingRocket movlw 0x01 movwf note_tempo call SoundRisingRocket call Delay150 call Delay150 call Delay150 movlw RECORD_STEPS ;get current record from EEPROM movwf eeadr bsf status,rp0 ;select bank1 bsf eecon1,rd ;read eeprom bcf status,rp0 ;select bank0 movf eedata,w ;W=record number of steps subwf stepsgood,w ;a record sequence (or same)? btfsc status,c ;no - jump next instruction goto SequenceRecord ;yes - tell player about it! clrf note_select ;beginning of song movlw 0x10 ;slow movwf note_tempo ;speed of song Sb1: call Delay150 movf note_select,w ;get next note call SongDeathMarch ;returned in W movwf note_tone incf note_select,f movf note_select,w ;get length of note call SongDeathMarch movwf note_length call SoundPlay ;play music incf note_select,f ;select next note movf note_select,w xorlw SONG_DEATHMARCH_LEN ;end of song? btfss status,z ;yes - skip next instruction goto Sb1 ;no - keep playing call Delay150 call Delay150 call Delay150 goto NewGame ;start new game ;**************************************************************** ;Name : SequenceRecord ;Description : player has beaten the record, save new step ; : record in EEPROM and play record tune. ;**************************************************************** SequenceRecord: movlw RECORD_STEPS ;save new step record in EEPROM movwf eeadr movf stepsgood,w movwf eedata bsf status,rp0 ;select bank1 bsf eecon1,wren ;enable write movlw 0x55 ;unlock codes movwf eecon2 movlw 0xaa movwf eecon2 bsf eecon1,wr ;write begins bcf eecon1,wren ;disable other writes Sre1: btfsc eecon1,wr ;wait for "write" to complete goto Sre1 bcf status,rp0 ;select bank0 clrf note_select ;beginning of song Sr1: incf steptemp,f movf steptemp,w andlw 0x03 movwf random call Delay150 call ShowLed ;show it on leds movlw 0x5 ;fast movwf note_tempo ;speed of song movf note_select,w ;get next note call SongOSusana ;returned in W movwf note_tone incf note_select,f movf note_select,w ;get length of note call SongOSusana movwf note_length call SoundPlay ;play music clrf portb ;turn all leds off incf note_select,f ;select next note movf note_select,w xorlw SONG_OSUSANA_LEN ;end of song? btfsc status,z ;no - skip next instruction goto Sr2 ;yes - end playing movf portb,w ;test for a key press andlw 0x0f ;mask keys xorlw 0x00 ;are any keys being pressed? btfsc status,z ;yes - skip next instruction goto Sr1 ;no - keep playing music! goto NewGame ;start new game Sr2 call Delay150 call Delay150 call Delay150 goto NewGame ;start new game ;**************************************************************** ;Name : Delay ;Description : causes a delay of 150msec with 4MHz crystal! ;**************************************************************** Delay150: movlw 0xc3 ;number of wait states movwf timerb L4: movlw 0xff ;number of wait states movwf timera L5: decfsz timera,f goto L5 decfsz timerb,f goto L4 return END
Hex file for Simon PIC16F628:
:020000000628D0 :04000C00D02882076F :1000100080340834983410349834043480340434F0 :1000200072340434AA341034AA34043498340434B6 :100030008F3408345F3410345F340434653404344E :100040008034043472340434803410348034043402 :100050007234043472340834723404345534023443 :100060005F340834653404345F3404347234083443 :1000700080341034BF340434AA3404349834043443 :1000800072341034803404348F340434983404349B :10009000BF340434BF34103482075F341034553415 :1000A00004344C340834403408344034083439348F :1000B0000834403408344C3408345F341034553438 :1000C00004344C3408344C340834553408345F3428 :1000D0000834553410345F341034553404344C34FF :1000E0000834403408344034083439340834403457 :1000F00008344C3408345F341034553410344C34E4 :1001000008344C340834553408345F3410344834DF :10011000083448340834393408343934083439342C :10012000083440340834403408344C3408345F34E4 :100130000834553410345F341034553404344C349E :1001400008344034083440340834393408344034F6 :1001500008344C3408345F341034553404344C348F :1001600008344C34083455340834553408345F347A :1001700020348207BF341034BF340434BF34083411 :10018000BF340434BF34083498340434AA340834F7 :10019000BF340434BF340834CA340834BF34103494 :1001A00007309F008316FD3085000F3086008130B8 :1001B000810083128601203084008001840A041F9C :1001C000DD2837083A3EB700F92010215F217C2155 :1001D000C721013A031D2F2AC80A872287228722B6 :1001E0003708343A031DE6283608033A031DE6288B :1001F000572A06080F39003A0319080000309B00FF :100200009A0183161C1555309D00AA309D009C1440 :100210001C119C18092983120230B3004B210800DD :10022000B001C70A47080339B4008722B42110304F :10023000B30030080720B100B00A30080720B20030 :1002400030218601B00A3008443A0319B00106088B :100250000F39003A031911290230B3004B2108006D :10026000AE012E083206031908003308AD0031082C :100270008514402185104021AD0B3729AE0A312964 :10028000AC000000000000000000000000000000C2 :10029000AC0B41290800B101B1090130B200302195 :1002A000B10B4D2987228722872287228722872226 :1002B00087228722080001080339B40008005B2167 :1002C0003708840003103608003A03197329013AED :1002D00003197129033A03196F29B40DB40DB40D34 :1002E000B40DB40DB40D000834048000B60A361DF8 :1002F0000800B601B70A0800B8013A30B900390859 :1003000084000008C7003808003A03199329013A0D :1003100003199129033A03198F29C70CC70CC70C7D :10032000C70CC70CC70C47080339B400A9218722A2 :1003300087228722B80A3819A62938083606031DED :100340007F2939083706031908007F29B801B90A3F :100350009D29B421B1002030B2001030051E0130BB :10036000B3003021860108003408003A0319BF2980 :10037000013A0319C129033A0319C329C5290616ED :100380005F3486164C340617403486173334051113 :100390008515B8013A30B900390884000008C70053 :1003A0003808003A0319E029013A0319DE29033A13 :1003B0000319DC29C70CC70CC70CC70CC70CC70C2A :1003C00047080339B400FA21003A0319003435080C :1003D0003406031D0034B80A3819F72938083606E0 :1003E000031DCC293908370603190134CC29B8017B :1003F000B90AEE29B5010730051E0330AE00FF3003 :10040000AD00FF30AC000618122A8618162A06190D :100410001A2A86191E2AAC0B032AAD0B012AAE0B31 :10042000FF2900340616B5015F30222A86163514DE :100430004C30222A0617B5144030222A861735146C :10044000B5143330B1002030B2000330B300302196 :1004500006080F39003A031D272A860101340130AE :10046000B3004B210130B3004B217C21872287222E :10047000872200309B0083161C1483121A0848023E :100480000318572AB0011030B30087223008B92072 :10049000B100B00A3008B920B2003021B00A3008EB :1004A000163A031D452A872287228722DA28003040 :1004B0009B0048089A0083161C1555309D00AA30F1 :1004C0009D009C141C119C18632A8312B001C70A5A :1004D00047080339B4008722B4210530B30030083F :1004E0004C20B100B00A30084C20B2003021860107 :1004F000B00A30086C3A0319832A06080F39003A0B :100500000319672ADA28872287228722DA28C3304C :10051000AD00FF30AC00AC0B8B2AAD0B892A080074 :02400E00183F59 :00000001FF
Quick Links
Legal Stuff
Social Media