SIMON
Program for PIC16F84A
P1 P2
P3 P4
P5
Program for PIC16F84A:
The program for Simon, using the numerical-value for each file (no equates):
LIST P=16F84A, F=INHX8M
include "P16F84A.inc"
ORG 0x0000
GOTO start
ORG 0x0006
start GOTO Initialisation
SongHeyJude
ADDWF PCL,f
RETLW 0x80
RETLW 0x08
RETLW 0x98
RETLW 0x10
RETLW 0x98
RETLW 0x04
RETLW 0x80
RETLW 0x04
RETLW 0x72
RETLW 0x04
RETLW 0xAA
RETLW 0x10
RETLW 0xAA
RETLW 0x04
RETLW 0x98
RETLW 0x04
RETLW 0x8F
RETLW 0x08
RETLW 0x5F
RETLW 0x10
RETLW 0x5F
RETLW 0x04
RETLW 0x65
RETLW 0x04
RETLW 0x80
RETLW 0x04
RETLW 0x72
RETLW 0x04
RETLW 0x80
RETLW 0x10
RETLW 0x80
RETLW 0x04
RETLW 0x72
RETLW 0x04
RETLW 0x72
RETLW 0x08
RETLW 0x72
RETLW 0x04
RETLW 0x55
RETLW 0x02
RETLW 0x5F
RETLW 0x08
RETLW 0x65
RETLW 0x04
RETLW 0x5F
RETLW 0x04
RETLW 0x72
RETLW 0x08
RETLW 0x80
RETLW 0x10
RETLW 0xBF
RETLW 0x04
RETLW 0xAA
RETLW 0x04
RETLW 0x98
RETLW 0x04
RETLW 0x72
RETLW 0x10
RETLW 0x80
RETLW 0x04
RETLW 0x8F
RETLW 0x04
RETLW 0x98
RETLW 0x04
RETLW 0xBF
RETLW 0x04
RETLW 0xBF
RETLW 0x10
SongoSusana
ADDWF PCL,f
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x04
RETLW 0x4C
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x04
RETLW 0x4C
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x55
RETLW 0x08
RETLW 0x5F
RETLW 0x08
RETLW 0x55
RETLW 0x10
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x04
RETLW 0x4C
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x10
RETLW 0x4C
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x55
RETLW 0x08
RETLW 0x5F
RETLW 0x10
RETLW 0x48
RETLW 0x08
RETLW 0x48
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x5F
RETLW 0x08
RETLW 0x55
RETLW 0x10
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x04
RETLW 0x4C
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x39
RETLW 0x08
RETLW 0x40
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x5F
RETLW 0x10
RETLW 0x55
RETLW 0x04
RETLW 0x4C
RETLW 0x08
RETLW 0x4C
RETLW 0x08
RETLW 0x55
RETLW 0x08
RETLW 0x55
RETLW 0x08
RETLW 0x5F
RETLW 0x20
SongDeathMarch:
ADDWF PCL,f
RETLW 0xBF
RETLW 0x10
RETLW 0xBF
RETLW 0x04
RETLW 0xBF
RETLW 0x08
RETLW 0xBF
RETLW 0x04
RETLW 0xBF
RETLW 0x08
RETLW 0x98
RETLW 0x04
RETLW 0xAA
RETLW 0x08
RETLW 0xBF
RETLW 0x04
RETLW 0xBF
RETLW 0x08
RETLW 0xCA
RETLW 0x08
RETLW 0xBF
RETLW 0x10
Initialisation:
BCF STATUS,RP1
BSF STATUS,RP0
MOVLW 0x11
MOVWF TRISA
MOVLW 0x0F
MOVWF TRISB
MOVLW 0x88
MOVWF OPTION_REG
BCF STATUS,RP0
NewGame CLRF PORTA
CLRF PORTB
MOVLW 0x0C
MOVWF FSR
S1 CLRF INDF
INCF FSR,f
BTFSS FSR,06
GOTO S1
MOVF 0x17,W
ADDLW 0x1A
MOVWF 0x17
CALL ClearRecord
CALL Introduction
Mainloop CALL GetStep
CALL ShowSequence
CALL GetUserSequence
XORLW 0x01
BTFSS STATUS,Z
GOTO SequenceBad
INCF 0x28,f
CALL Delay150
CALL Delay150
CALL Delay150
MOVF 0x17,W
XORLW 0x34
BTFSS STATUS,Z
GOTO Mainloop
MOVF 0x16,W
XORLW 0x03
BTFSS STATUS,Z
GOTO Mainloop
GOTO SequenceRecord
ClearRecord
MOVF PORTB,W
ANDLW 0x0F
XORLW 0x00
BTFSC STATUS,Z
RETURN
MOVLW 0x00
MOVWF EEADR
CLRF EEDATA
BSF STATUS,RP0
BSF EECON1,02
MOVLW 0x55
MOVWF EECON2
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,01
BCF EECON1,02
Crec BTFSC EECON1,01
GOTO Crec
BCF STATUS,RP0
MOVLW 0x02
MOVWF 0x13
CALL SoundRisingRocket
RETURN
Introduction:
CLRF 0x10
Intr1 INCF 0x27,f
MOVF 0x27,W
ANDLW 0x03
MOVWF 0x14
CALL Delay150
CALL ShowLed
MOVLW 0x10
MOVWF 0x13
MOVF 0x10,W
CALL SongHeyJude
MOVWF 0x11
INCF 0x10,f
MOVF 0x10,W
CALL SongHeyJude
MOVWF 0x12
CALL SoundPlay
CLRF PORTB
INCF 0x10,f
MOVF 0x10,W
XORLW 0x44
BTFSC STATUS,Z
CLRF 0x10
MOVF PORTB,W
ANDLW 0x0F
XORLW 0x00
BTFSC STATUS,Z
GOTO Intr1
MOVLW 0x02
MOVWF 0x13
CALL SoundRisingRocket
RETURN
SoundPlay
CLRF 0x0E
Sp1 MOVF 0x0E,W
XORWF 0x12,W
BTFSC STATUS,Z
RETURN
MOVF 0x13,W
MOVWF 0x0D
Sp2 MOVF 0x11,W
BSF PORTA,01
CALL SoundDelay
BCF PORTA,01
CALL SoundDelay
DECFSZ 0x0D,f
GOTO Sp2
INCF 0x0E,f
GOTO Sp1
SoundDelay
MOVWF 0x0C
Sd1 NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ 0x0C,f
GOTO Sd1
RETURN
SoundRisingRocket:
CLRF 0x11
COMF 0x11,f
Srr1 MOVLW 0x01
MOVWF 0x12
CALL SoundPlay
DECFSZ 0x11,f
GOTO Srr1
CALL Delay150
CALL Delay150
CALL Delay150
CALL Delay150
CALL Delay150
CALL Delay150
CALL Delay150
CALL Delay150
RETURN
GetRandom
MOVF TMR0,W
ANDLW 0x03
MOVWF 0x14
RETURN
GetStep BCF PORTA,03
BSF PORTA,02
CALL GetRandom
MOVF 0x17,W
MOVWF FSR
BCF STATUS,C
MOVF 0x16,W
XORLW 0x00
BTFSC STATUS,Z
GOTO GCol0
XORLW 0x01
BTFSC STATUS,Z
GOTO GCol1
XORLW 0x03
BTFSC STATUS,Z
GOTO GCol2
RLF 0x14,f
RLF 0x14,f
GCol2 RLF 0x14,f
RLF 0x14,f
GCol1 RLF 0x14,f
RLF 0x14,f
GCol0 MOVF INDF,W
IORWF 0x14,W
MOVWF INDF
INCF 0x16,f
BTFSS 0x16,02
RETURN
CLRF 0x16
INCF 0x17,f
RETURN
ShowSequence:
CLRF 0x18
MOVLW 0x1A
MOVWF 0x19
Ss1 MOVF 0x19,W
MOVWF FSR
MOVF INDF,W
MOVWF 0x27
MOVF 0x18,W
XORLW 0x00
BTFSC STATUS,Z
GOTO SCol0
XORLW 0x01
BTFSC STATUS,Z
GOTO SCol1
XORLW 0x03
BTFSC STATUS,Z
GOTO SCol2
RRF 0x27,f
RRF 0x27,f
SCol2 RRF 0x27,f
RRF 0x27,f
SCol1 RRF 0x27,f
RRF 0x27,f
SCol0 MOVF 0x27,W
ANDLW 0x03
MOVWF 0x14
CALL ShowStep
CALL Delay150
CALL Delay150
CALL Delay150
INCF 0x18,f
BTFSC 0x18,02
GOTO Colov1
Ss2 MOVF 0x18,W
XORWF 0x16,W
BTFSS STATUS,Z
GOTO Ss1
MOVF 0x19,W
XORWF 0x17,W
BTFSC STATUS,Z
RETURN
GOTO Ss1
Colov1 CLRF 0x18
INCF 0x19,f
GOTO Ss2
ShowStep
CALL ShowLed
MOVWF 0x11
MOVLW 0x20
MOVWF 0x12
MOVLW 0x10
BTFSS PORTA,04
MOVLW 0x01
MOVWF 0x13
CALL SoundPlay
CLRF PORTB
RETURN
ShowLed MOVF 0x14,W
XORLW 0x00
BTFSC STATUS,Z
GOTO ShowRed
XORLW 0x01
BTFSC STATUS,Z
GOTO ShowGreen
XORLW 0x03
BTFSC STATUS,Z
GOTO ShowYellow
GOTO ShowOrange
ShowRed BSF PORTB,04
RETLW 0x5F
ShowGreen BSF PORTB,05
RETLW 0x4C
ShowYellow BSF PORTB,06
RETLW 0x40
ShowOrange BSF PORTB,07
RETLW 0x33
GetUserSequence:
BCF PORTA,02
BSF PORTA,03
CLRF 0x18
MOVLW 0x1A
MOVWF 0x19
Us1 MOVF 0x19,W
MOVWF FSR
MOVF INDF,W
MOVWF 0x27
MOVF 0x18,W
XORLW 0x00
BTFSC STATUS,Z
GOTO UCol0
XORLW 0x01
BTFSC STATUS,Z
GOTO UCol1
XORLW 0x03
BTFSC STATUS,Z
GOTO UCol2
RRF 0x27,f
RRF 0x27,f
UCol2 RRF 0x27,f
RRF 0x27,f
UCol1 RRF 0x27,f
RRF 0x27,f
UCol0 MOVF 0x27,W
ANDLW 0x03
MOVWF 0x14
CALL Keypad
XORLW 0x00
BTFSC STATUS,Z
RETLW 0x00
MOVF 0x15,W
XORWF 0x14,W
BTFSS STATUS,Z
RETLW 0x00
INCF 0x18,f
BTFSC 0x18,02
GOTO Colov2
Us2 MOVF 0x18,W
XORWF 0x16,W
BTFSS STATUS,Z
GOTO Us1
MOVF 0x19,W
XORWF 0x17,W
BTFSC STATUS,Z
RETLW 0x01
GOTO Us1
Colov2 CLRF 0x18
INCF 0x19,f
GOTO Us2
Keypad CLRF 0x15
MOVLW 0x07
BTFSS PORTA,04
MOVLW 0x03
MOVWF 0x0E
Kp2 MOVLW 0xFF
MOVWF 0x0D
Kp1 MOVLW 0xFF
MOVWF 0x0C
Kwait BTFSC PORTB,00
GOTO KeyRed
BTFSC PORTB,01
GOTO KeyGreen
BTFSC PORTB,02
GOTO KeyYellow
BTFSC PORTB,03
GOTO KeyOrange
DECFSZ 0x0C,f
GOTO Kwait
DECFSZ 0x0D,f
GOTO Kp1
DECFSZ 0x0E,f
GOTO Kp2
RETLW 0x00
KeyRed BSF PORTB,04
CLRF 0x15
MOVLW 0x5F
GOTO Beep1
KeyGreen BSF PORTB,05
BSF 0x15,00
MOVLW 0x4C
GOTO Beep1
KeyYellow BSF PORTB,06
BSF 0x15,01
MOVLW 0x40
GOTO Beep1
KeyOrange BSF PORTB,07
BSF 0x15,00
BSF 0x15,01
MOVLW 0x33
Beep1 MOVWF 0x11
MOVLW 0x20
MOVWF 0x12
MOVLW 0x03
MOVWF 0x13
Beep2 CALL SoundPlay
MOVF PORTB,W
ANDLW 0x0F
XORLW 0x00
BTFSS STATUS,Z
GOTO Beep2
CLRF PORTB
RETLW 0x01
SequenceBad
MOVLW 0x01
MOVWF 0x13
CALL SoundRisingRocket
MOVLW 0x01
MOVWF 0x13
CALL SoundRisingRocket
CALL ShowSequence
MOVLW 0x01
MOVWF 0x13
CALL SoundRisingRocket
MOVLW 0x01
MOVWF 0x13
CALL SoundRisingRocket
CALL Delay150
CALL Delay150
CALL Delay150
MOVLW 0x00
MOVWF EEADR
BSF STATUS,RP0
BSF EECON1,00
BCF STATUS,RP0
MOVF EEDATA,W
SUBWF 0x28,W
BTFSC STATUS,C
GOTO SequenceRecord
CLRF 0x10
MOVLW 0x10
MOVWF 0x13
Sb1 CALL Delay150
MOVF 0x10,W
CALL SongDeathMarch
MOVWF 0x11
INCF 0x10,f
MOVF 0x10,W
CALL SongDeathMarch
MOVWF 0x12
CALL SoundPlay
INCF 0x10,f
MOVF 0x10,W
XORLW 0x16
BTFSS STATUS,Z
GOTO Sb1
CALL Delay150
CALL Delay150
CALL Delay150
GOTO NewGame
SequenceRecord:
MOVLW 0x00
MOVWF EEADR
MOVF 0x28,W
MOVWF EEDATA
BSF STATUS,RP0
BSF EECON1,02
MOVLW 0x55
MOVWF EECON2
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,01
BCF EECON1,02
Sre1 BTFSC EECON1,01
GOTO Sre1
BCF STATUS,RP0
CLRF 0x10
Sr1 INCF 0x27,f
MOVF 0x27,W
ANDLW 0x03
MOVWF 0x14
CALL Delay150
CALL ShowLed
MOVLW 0x05
MOVWF 0x13
MOVF 0x10,W
CALL Song0Susana
MOVWF 0x11
INCF 0x10,f
MOVF 0x10,W
CALL Song0Susana
MOVWF 0x12
CALL SoundPlay
CLRF PORTB
INCF 0x10,f
MOVF 0x10,W
XORLW 0x6C
BTFSS STATUS,Z
GOTO Sr1
CALL Delay150
CALL Delay150
CALL Delay150
GOTO NewGame
Delay150 MOVLW 0xC3
MOVWF 0x0D
L4 MOVLW 0xFF
MOVWF 0x0C
L5 DECFSZ 0x0C,f
GOTO L5
DECFSZ 0x0D,f
GOTO L4
RETURN
END
|
The equates for the musical notes for Simon:
;****************************************************************
;* MEMORY GAME - simon *
;****************************************************************
;Port A definitions
PORTA_CONFIG1 equ 0x1D ;bit4: in,in,in,out,in :bit0
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 0x0C ;start of global variable ram
LINE_OFFSET equ 0x1A ;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 program for Simon, with comments:
;****************************************************************
;* MEMORY GAME - SIMON *
;****************************************************************
list p=16f84,r=hex ;microcontroller & base
include "p16F84A.inc" ;register memory mapping file
include "simon.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 sequence 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 ;number of 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 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 : Initialisation
;Description : system initialisation and mainloop
;****************************************************************
Initialisation:
;system initialisation
;port A and port B initialisation
bcf status,rp1 ;select bank1 registers
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 :
;****************************************************************
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
;****************************************************************
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 : GetRandom
;Description : reads the PIC's timer register at various
; : "random" intervals caused by the player
;Inputs : pressing one of the keys.
;Outputs : random - random number 0-3
;****************************************************************
GetRandom:
movf tmr0,w
andlw 0x03 ;mask all but bit0 and bit1
movwf random
return
;****************************************************************
;Name : GetStep
;Description : gets a random number and stores it into the
; : next available position in sequence table.
;****************************************************************
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 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
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 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?
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!
;****************************************************************
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
|
P1 P3
|