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