;**************************************************************** ;* MEMORY GAME - SIMON * ;* BY KEITH WILSON * ;**************************************************************** list p=16f84, ;microcontroller include "p16F84A.inc" ;register memory mapping file include "simonF84.inc" ;Simon definitions __Config 3FF3h ;**************************************************************** ;global variable memory ;**************************************************************** timera equ 0x0c ;general purpose timer timerb equ 0x0d ;general purpose timer timerc equ 0x0e ;general purpose timer timerd equ 0x0f ;general purpose timer note_select equ 0x10 ;selection of note note_tone equ 0x11 ;frequency of note note_length equ 0x12 ;length of note note_tempo equ 0x13 ;tempo of song random equ 0x14 ;random number key equ 0x15 ;key last pressed column_w equ 0x16 ;write pointer in sequence table X line_w equ 0x17 ;write pointer in sequence table Y column_r equ 0x18 ;read pointer in sequence table X line_r equ 0x19 ;read pointer in sequnece table Y steps0104 equ 0x1a ;step memory steps0508 equ 0x1b ;step memory steps0912 equ 0x1c ;step memory steps1316 equ 0x1d ;step memory steps1720 equ 0x1e ;step memory steps2124 equ 0x1f ;step memory steps2528 equ 0x20 ;step memory steps2932 equ 0x21 ;step memory steps3336 equ 0x22 ;step memory steps3740 equ 0x23 ;step memory steps4144 equ 0x24 ;step memory steps4548 equ 0x25 ;step memory steps4952 equ 0x26 ;step memory steptemp equ 0x27 ;temporary step memory stepsgood equ 0x28 ;successful steps by player ;**************************************************************** ;reset vector ;**************************************************************** reset: org 0x00 ;reset vector address goto start ;start program execution start: org 0x06 ;start of program goto Initialisation ;**************************************************************** ; Data tables for Songs ;**************************************************************** SongHeyJude: addwf pcl,f ;jump formward accoding 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 formward 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 : Initialisation ;Description : system initialisation and mainloop ;Inputs : none ;Outputs : none ;**************************************************************** Initialisation: ;system initialisation ;port A and port B initialisation bcf status,rp1 ;select bank1 register bsf status,rp0 movlw PORTA_CONFIG1 ;porta configuration movwf trisa movlw PORTB_CONFIG1 ;portb configuration movwf trisb movlw 0x88 ;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 ;add step memory offset movwf line_w call ClearRecord ;clear record steps? call Introduction ;introductory song & calibration ;**************************************************************** ;Name : Mainloop ;Description : ;Inputs : none ;Outputs : none ;**************************************************************** Mainloop: call GetStep ;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 ;Inputs : none ;Outputs : none ;**************************************************************** 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 ;Outputs : 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 ;Outputs : none ;**************************************************************** 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 special delay function used whenever sound ; : must be produced on the buzzer. 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 ;Outputs : none ;**************************************************************** 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 : GetRandom ;Description : reads the PIC's timer register at various ; : "random" intervals caused by the player ;Inputs : pressing one of the keys. ;Outputs : random number 0-3 ;**************************************************************** GetRandom: movf tmr0,w andlw 0x03 ;mask all but bit0,bit1 movwf random return ;**************************************************************** ;Name : GetStep ;Description : gets a random number and stores it into the ; : next available position in sequence table. ;Inputs : none ;Outputs : none ;**************************************************************** GetStep: call GetRandom ;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 GCol3: 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 sequence 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 sequence table? return ;no - return clrf column_w ;yes - select next memory byte in sequence table incf line_w,f return ;**************************************************************** ;Name : ShowSequence ;Description : displays the step sequence that the player ; : has to remember and repeat. ;Inputs : none ;Outputs : none ;**************************************************************** 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 SCol3: 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 sequence 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 sequence 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. ;Inputs : none ;Outputs : none ;**************************************************************** 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 ;get current record from EEPROM 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. ;Inputs : none ;Outputs : none ;**************************************************************** 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 to write 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? btfss status,z ;yes - skip next instruction goto Sr1 ;no - keep playing call Delay150 call Delay150 call Delay150 goto NewGame ;start new game ;**************************************************************** ;Name : Delay ;Description : causes a delay of 150msec with 4MHz crystal! ;Inputs : none ;Outputs : none ;**************************************************************** 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