;****************************************************************
;* 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
|