;7 segment bit positions ; _ 7 ;| | 2 6 ; _ 1 ;| | 3 5 ; _ . 4 0 display bytetable %11111100,%01100000,%11011010,%11110010,%01100110,%10110110,%10111110,%11100000,%11111110,%11100110, | %11101110,%00111110,%10011100,%01111010,%10011110,%10001110 rbutton con 0x7F<<2 lbutton con 0x51<<2 ubutton con 0x17<<2 dbutton con 0x2E<<2 dataport var OUTL ;alias graph,seg1 and seg2 data port for interrupt handler muxport var OUTH ;alias multiplexer control pins port for interrupt handler graph var byte ;each bit sets the bar graph led states seg1 var byte ;each bit sets the segment led states seg2 var byte ;each bit sets the segment led states pressed var byte ;indicates which button is currently pressed seed var word ;random number seed light var word decimal var long ;init hardware and interrupt low p8 ;init mux pins used by interrupt handler low p9 low p13 dirl = 0 ;p0-7 outputs T1CON.bit0 = 1 ;timer1 starts counting PIE1.bit0 = 1 ;unmask timer1 int PEIE = 1 ;enable all unmasked peripheral interrupts GIE = 1 ;enable all unmasked interrupts mode var sbyte difficulty var byte playspeed var long failed_count var byte sequence_index var byte sequence var nib(256) start ;init graph,seg1 and seg2 states graph = 0 seg1 = 0 seg2 = 0 ;startup sound sound p12,[100\784,100\1047,100\1319,100\1568] waitstart graph = 0xFF pause 50 graph = 0 pause 50 gosub getpressed if pressed=0 then waitstart if pressed=1 then lightsense if pressed=2 then playsong if pressed=3 then simon if pressed=4 then cylon goto waitstart simon sound p12,[100\784,100\1047,100\1319,100\1568] graph = 0x01 difficulty = 3 mode = 0 playspeed = 1000 failed_count = 0 adin p11,seed seed = seed + ((TMR1H<<8)|TMR1L) ;Seed = A/D value of light and current Timer1 count main graph = mode+1 seed = random seed sequence(mode)=seed//4 repeatsequence pause 500 gosub playsequence seg1 = 0 seg2 = 0 gosub getuserplayback if(failed_count=1)then goto repeatsequence endif if(failed_count)then goto start endif mode = mode + 1 if(mode>difficulty)then ;play win song here sound p12,[100\784,100\0,100\784,100\0,100\784,100\0,100\1568,1000\0] difficulty = difficulty + 1 mode = 0 playspeed = playspeed - (playspeed/4) if(playspeed<50)then sound p12,[1250\784,100\0,1250\1568,100\0,1250\784,100\0,1250\1568,1000\0] goto start endif endif goto main playsequence for sequence_index = 0 to mode if(sequence(sequence_index)=0)then seg1 = %00000000 seg2 = %01100010 sound p12,[playspeed\784] endif if(sequence(sequence_index)=1)then seg1 = %00001110 seg2 = %00000000 sound p12,[playspeed\1047] endif if(sequence(sequence_index)=2)then seg1 = %11000000 seg2 = %10000100 sound p12,[playspeed\1319] endif if(sequence(sequence_index)=3)then seg1 = %00110000 seg2 = %00011000 sound p12,[playspeed\1568] endif seg1 = 0 seg2 = 0 sound p12,[playspeed/8\0] next return lastpressed var byte timeout var long getuserplayback for sequence_index = 0 to mode timeout=0 pressed=0 do lastpressed=pressed gosub getpressed if(pressed=0)then pause 1 timeout=timeout+1 if(timeout>1000)then goto failed endif endif if(pressed=1)then seg1 = %00000000 seg2 = %01100010 if(sequence(sequence_index)=0)then sound p12,[250\784] failed_count=0 else goto failed endif endif if(pressed=2)then seg1 = %00001110 seg2 = %00000000 if(sequence(sequence_index)=1)then sound p12,[250\1047] failed_count=0 else goto failed endif endif if(pressed=3)then seg1 = %11000000 seg2 = %10000100 if(sequence(sequence_index)=2)then sound p12,[250\1319] failed_count=0 else goto failed endif endif if(pressed=4)then seg1 = %00110000 seg2 = %00011000 if(sequence(sequence_index)=3)then sound p12,[250\1568] failed_count=0 else goto failed endif endif while(pressed=lastpressed) do gosub getpressed while(pressed) seg1 = 0 seg2 = 0 next return failed sound p12,[1250\150,1250\0] failed_count=failed_count+1 do gosub getpressed while(pressed) return lightsense adin p11,seed decimal=seed*100/0x3ff seg2=display(decimal//10) seg1=display(decimal/10//10) goto lightsense AH con 440*2 ;assigns a value for the note and octave AS con 466*2 ;the note is 466*2 = A sharp second octave BH con 494*2 CH con 523*2 CS con 554*2 DH con 587*2 DS con 622*2 EH con 659*2 FH con 698*2 FS con 740*2 GH con 784*2 GS con 831*2 temp var byte temp2 var long playsong for temp = 0 to 33 lookup temp,[CS,BH,AH,BH,CS,0,CS,0,CS,BH,0,BH,0,BH,0,CS,| EH, 0, EH,CS,BH,AH,BH,CS,0,CS,0,CS,BH,0,BH,CS,BH,AH],temp2 if temp2 then sound p12,[350\temp2] else pause 10 endif next pause 5000 goto playsong speed var word cylon light=75 graph=0x1 sound p12,[50\500] graph=0x2 sound p12,[50\600] graph=0x4 sound p12,[50\700] graph=0x8 sound p12,[50\800] graph=0x10 sound p12,[50\900] graph=0x20 sound p12,[50\1000] graph=0x40 sound p12,[50\1100] graph=0x80 sound p12,[50\1200] graph=0x40 sound p12,[50\1100] graph=0x20 sound p12,[50\1000] graph=0x10 sound p12,[50\900] graph=0x8 sound p12,[50\800] graph=0x4 sound p12,[50\700] graph=0x2 sound p12,[50\600] goto cylon getpressed_work var word getpressed adin p10,getpressed_work pressed=0 if(getpressed_work>(rbutton-5) AND getpressed_work<(rbutton+5))then pressed = 1 endif if(getpressed_work>(lbutton-5) AND getpressed_work<(lbutton+5))then pressed = 2 endif if(getpressed_work>(ubutton-5) AND getpressed_work<(ubutton+5))then pressed = 3 endif if(getpressed_work>(dbutton-5) AND getpressed_work<(dbutton+5))then pressed = 4 endif return ;This is the assembly interrupt handler to run the two 7 seg displays and the 8 led graph isr_mode var byte ;used by interrupt handler israsm{ bcf PIR1,0 ;clear Timer1 interrupt flag clrf DATAPORT&0x1FF ;clear current state of P0-P7 banksel ISR_MODE&0x1FF incf ISR_MODE&0x7F,f ;increment MODE movfw ISR_MODE&0x7F ;put MODE value in work register banksel 0 set_seg1 addlw -1 ;subtract 1 skpz ;if zero point to seg1 and load value into p0-p7 goto set_seg2 ;else check seg2 bsf MUXPORT&0x1FF,0 bcf MUXPORT&0x1FF,1 bcf MUXPORT&0x1FF,7 banksel SEG1&0x1FF movfw SEG1&0x7F banksel 0 movwf DATAPORT&0x1FF goto exitint set_seg2 addlw -1 ;subtract 1 skpz ;if zero point to seg2 and load value into p0-p7 goto set_graph ;else set graph bcf MUXPORT&0x1FF,0 bsf MUXPORT&0x1FF,1 bcf MUXPORT&0x1FF,7 banksel SEG2&0x1FF movfw SEG2&0x7F banksel 0 movwf DATAPORT&0x1FF goto exitint set_graph bcf MUXPORT&0x1FF,0 ;point to graph and load value unto p0-p7 bcf MUXPORT&0x1FF,1 bsf MUXPORT&0x1FF,7 banksel GRAPH&0x1FF movfw GRAPH&0x7F banksel 0 movwf DATAPORT&0x1FF banksel ISR_MODE&0x1FF clrf ISR_MODE&0x7F ;Clear MODE to point to seg1 on next interrupt exitint banksel 0 movlw 0xD5 ;set timer so interrupt executes 180 times a second(refreshes seg1,seg2 and graph 60 times a second each) movwf TMR1H }