; Misc pic fiddling ; 16f877 PIC ; Copyright (c) 2002 Jesse Lackey, all rights reserved. ; jesse@celestialaudio.com ; ; ; PIC Microcontoller Input / Ouput Methods Title "misc pic fiddling" list p=p16f877, f=inhx16, mm=ON, st=ON, r=dec, w=0, n=0 include "p16f877.inc" ; use definition file for 16F877 ; LVP= low voltage program ; pwrte= 72msec startup delay ON/OFF ; boden= brown-out reset detect ; wrt= program mem can be written to from app if OFF ; cpd= EEPROM write protected of ON __CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _WDT_OFF & _HS_OSC & _PWRTE_ON & _BODEN_OFF & _WRT_ENABLE_ON & _CPD_OFF ; ; -------------------- ; USER RAM DEFINITIONS ; -------------------- ; CBLOCK 0x20 ; RAM starts at address 20h ;for Delay10msec_NumTimes Delay10msecNumTimes Delay10msecVar Delay10msecVarPlus1 ;general ; serialstuff: CharIn ; misc StrobeOnTimeMsec StrobeOffTimeMsec ;general ; serialstuff: LEDSelected LEDBrightness ; MIDI related MIDI_MessageByte ; last message byte received MIDI_NoteNum ; last note # we received MIDI_Velocity ; last velocity we received MIDI_ReceivePhase ; input stream state phase TranslateNoteInput tempMidi InputRange ; These get set based on config switch settings. MIDI_NoteMin ; Note# that corresponds to output 0 MIDI_NoteMax ; (see where this is set) MIDI_NoteOnMessageByte ; Hex code for note on (0x90= chanl1, 0x91= chan2) MIDI_NoteOffMessageByte ; Hex code for note off (0x80= chanl1, 0x81= chan2) ; outputs - if > 0, trigger is on. These are a #msec countdown, when they ; hit 0 we turn the trigger off. ; if 0xFF, that means that trigger is on via upper-range keys, waiting for ; note-off, so lower-range keys that do one flash should do nothing. LED_00 LED_01 LED_02 LED_03 LED_04 LED_05 LED_06 LED_07 LED_08 LED_09 LED_10 LED_11 LED_12 LED_13 ;interrupt handler state save and misc. used by parts of the ISR routine _status _fsr _pclath ENDC CBLOCK 0x70 ; "shadowed" across all banks, I believe. Damn picbook ; doesn't say how to do this essential part of an all-purpose ; ISR. _w _HeartbeatLedFlash_Low _HeartbeatLedFlash_High ENDC ; ; ; ; org 0x0000 ; start address = 0000h clrf PCLATH goto Initialize_Everything ; ---------------------------------------- ; interrupt skeleton routine from picbook p500 ; also from p848 org 4 Int movwf _w ; Save the Context Registers movf STATUS, w bcf STATUS, RP0 ; Change to Bank 0 bcf STATUS, RP1 movwf _status movf FSR, w movwf _fsr movf PCLATH, w movwf _pclath clrf PCLATH ; --- ; Heartbeat LED counter. Also used for timing in testmode seq code. incfsz _HeartbeatLedFlash_Low, f goto _hopOverInc ; didn't "rollover" - don't inc high part incf _HeartbeatLedFlash_High, f _hopOverInc ; reload timer with "68.5". do this by alternating 68 & 69. btfsc _HeartbeatLedFlash_Low, 0 movlw d'68' btfss _HeartbeatLedFlash_Low, 0 movlw d'69' movwf TMR0 bcf INTCON, T0IF ; reset timer0 interrupt flag ; Flash heartbeat led - alternate on/off each time thru here. a bit of btfsc _HeartbeatLedFlash_High, 0 bsf PORTA,0 ; on btfss _HeartbeatLedFlash_High, 0 bcf PORTA,0 ; Ok. Now do processing of triggers. ; If LED_XX is zero, its off, skip. ; Else, decrement. ; If it hit zero, turn off output. _check00 movlw d'255' subwf LED_00, w btfsc STATUS, Z goto _check01 movf LED_00,w btfsc STATUS, Z goto _check01 decfsz LED_00,f goto _check01 ; turn it off bcf PORTB, 7 _check01 movlw d'255' subwf LED_01, w btfsc STATUS, Z goto _check02 movf LED_01,w btfsc STATUS, Z goto _check02 decfsz LED_01,f goto _check02 ; turn it off bcf PORTB, 6 _check02 movlw d'255' subwf LED_02, w btfsc STATUS, Z goto _check03 movf LED_02,w btfsc STATUS, Z goto _check03 decfsz LED_02,f goto _check03 ; turn it off bcf PORTB, 5 _check03 movlw d'255' subwf LED_03, w btfsc STATUS, Z goto _check04 movf LED_03,w btfsc STATUS, Z goto _check04 decfsz LED_03,f goto _check04 ; turn it off bcf PORTB, 4 _check04 movlw d'255' subwf LED_04, w btfsc STATUS, Z goto _check05 movf LED_04,w btfsc STATUS, Z goto _check05 decfsz LED_04,f goto _check05 ; turn it off bcf PORTB, 3 _check05 movlw d'255' subwf LED_05, w btfsc STATUS, Z goto _check06 movf LED_05,w btfsc STATUS, Z goto _check06 decfsz LED_05,f goto _check06 ; turn it off bcf PORTB, 2 _check06 movlw d'255' subwf LED_06, w btfsc STATUS, Z goto _check07 movf LED_06,w btfsc STATUS, Z goto _check07 decfsz LED_06,f goto _check07 ; turn it off bcf PORTB, 1 _check07 movlw d'255' subwf LED_07, w btfsc STATUS, Z goto _check08 movf LED_07,w btfsc STATUS, Z goto _check08 decfsz LED_07,f goto _check08 ; turn it off bcf PORTB, 0 _check08 movlw d'255' subwf LED_08, w btfsc STATUS, Z goto _check09 movf LED_08,w btfsc STATUS, Z goto _check09 decfsz LED_08,f goto _check09 ; turn it off bcf PORTD, 7 _check09 movlw d'255' subwf LED_09, w btfsc STATUS, Z goto _check10 movf LED_09,w btfsc STATUS, Z goto _check10 decfsz LED_09,f goto _check10 ; turn it off bcf PORTD, 6 _check10 movlw d'255' subwf LED_10, w btfsc STATUS, Z goto _check11 movf LED_10,w btfsc STATUS, Z goto _check11 decfsz LED_10,f goto _check11 ; turn it off bcf PORTD, 5 _check11 movlw d'255' subwf LED_11, w btfsc STATUS, Z goto _check12 movf LED_11,w btfsc STATUS, Z goto _check12 decfsz LED_11,f goto _check12 ; turn it off bcf PORTD, 4 _check12 movlw d'255' subwf LED_12, w btfsc STATUS, Z goto _doneWithTriggers movf LED_12,w btfsc STATUS, Z goto _doneWithTriggers decfsz LED_12,f goto _doneWithTriggers ; turn it off bcf PORTC, 5 _doneWithTriggers ; --- ; restore & leave movf _pclath, w ; Restore the Context Registers movwf PCLATH movf _fsr, w movwf FSR movf _status, w movwf STATUS swapf _w, f ;trickery - load w w/o changing STATUS reg Z flag swapf _w, w retfie ; ; ; ---------------------------------------- ; Initialize_Everything movlw b'00000000' ; all port pins = low movwf PORTA movlw b'00000000' movwf PORTB movlw b'00000000' movwf PORTC movlw b'00000000' movwf PORTD movlw b'00000000' movwf PORTE bsf STATUS,RP0 ; set RAM Page 1 for TRIS registers ; Hardware usage: ; ; Switches are pulled up, so switch "ON" = input Low. ; ; PORTA, #0: Heartbeat LED ; PORTA, #1: pot input ; PORTA, #2-5: unused ; PORTB, #0-7: outputs ; PORTC, #0-3: switch input ; PORTC, #4: unused ; PORTC, #5: output ; PORTC, #6: serial out ; PORTC, #7: serial (midi) in ; PORTD, #0-1: switch input ; PORTD, #2-3: unused ; PORTD, #4-7: outputs ; PORTE, #0-2: unused ; Switch inputs: ; 1= PORTC, bit 0 -> "debug" pattern #1 ; 2= PORTC, bit 1 -> "debug" pattern #2 ; 3= PORTC, bit 2 ; 4= PORTC, bit 3 ; 5= PORTD, bit 0 ; 6= PORTD, bit 1 -> use 38400 for midi, not standard 32500 rate ; The 13 outputs, in order, top of board to bottom: ; 00: PORTB, 7 ; 01: PORTB, 6 ; 02: PORTB, 5 ; 03: PORTB, 4 ; 04: PORTB, 3 ; 05: PORTB, 2 ; 06: PORTB, 1 ; 07: PORTB, 0 ; 08: PORTD, 7 ; 09: PORTD, 6 ; 10: PORTD, 5 ; 11: PORTD, 4 ; 12: PORTC, 5 movlw b'00000010' ; 0 output, 1 analog in, 2-5 unused (output) movwf TRISA ^ 0x80 movlw b'00000000' ; all outputs movwf TRISB ^ 0x80 movlw b'10001111' ; PORTC bits 0,1,2,3 & 7 are inputs. movwf TRISC ^ 0x80 movlw b'00000011' ; PORTD bits 0,1 are inputs movwf TRISD ^ 0x80 movlw b'00000000' ; all outputs movwf TRISE ^ 0x80 movlw b'00000110' ; all analog pins = digital (for now) movwf ADCON1 ^ 0x80 bcf STATUS,RP0 ; back to RAM page 0 ; init stuff for interrupt routine code movlw 0 movwf _HeartbeatLedFlash_Low movwf _HeartbeatLedFlash_High ; ** ; setup timer - see p201 bsf STATUS, RP0 ; goto bank 1 movlw b'11010011' ; Timer0 instruction clock & prescaler (div 8) movwf OPTION_REG ^ 0x80 ; set timer bcf STATUS, RP0 movlw d'69' movwf TMR0 ;p197 for INTCON ;done below after everything initialized! ; movlw (1 << GIE) + (1 << T0IE) ; movlw b'10100000' ; movwf INTCON ; enable interrupts ; ** ; setup serial transmitter ; p231,235/236 with mods ; ; 12mhz, highspeedmode, 31250bps, Clockcount= 12Mhz/(DataRate * 16 * (4 ^ 0)) -1 ; clockcount= [12,000,000 / (31250 * 16)] -1 ; clockcount= (12,000,000 / 500000) -1 ; clockcount= 23.00 (d'23' goes into SPBRG) ; ; 12mhz, highspeedmode, 38400bps, Clockcount= 12Mhz/(DataRate * 16 * (4 ^ 0)) -1 ; clockcount= [12,000,000 / (38400 * 16)] -1 ; clockcount= (12,000,000 / 614400) -1 ; clockcount= 18.53 (d'19' goes into SPBRG) ; 6= PORTD, bit 1 -> use 38400 for midi, not standard 31250 rate bsf STATUS, RP0 ; goto bank 1 bcf TXSTA ^ 0x80, SYNC ; not in sync mode bsf TXSTA ^ 0x80, BRGH ; BRGH=1 (highspeed mode) ; btfsc PORTD, 1 movlw d'23' ; switch off, PORTD bit 1 reads high, normal midi rate ; btfss PORTD, 1 ; movlw d'19' ; swtich on, PORTD bit 1 reads low, use nonstandard 38400 bsf STATUS, RP0 ; goto bank 1 movwf SPBRG ^ 0x80 ; set USART data rate bcf STATUS, RP0 ; goto bank 0 bsf RCSTA, SPEN ; enable serial port bcf RCSTA, RX9 ; 8 bits to receive bsf RCSTA, CREN ; enable serial port receive bsf STATUS, RP0 ; goto bank 1 bcf TXSTA ^ 0x80, TX9 ; 8 bits to send bsf TXSTA ^ 0x80, TXEN ; enable data xmit bcf STATUS, RP0 ; goto bank 0 ; --------------------------------- call Init_MidiStuff movlw 0 movwf LED_00 movwf LED_01 movwf LED_02 movwf LED_03 movwf LED_04 movwf LED_05 movwf LED_06 movwf LED_07 movwf LED_08 movwf LED_09 movwf LED_10 movwf LED_11 movwf LED_12 movwf LED_13 ; timing constants movlw d'60' movwf StrobeOnTimeMsec movlw d'60' movwf StrobeOffTimeMsec ; now enable interrupts ; see p197 for INTCON movlw (1 << GIE) + (1 << T0IE) movwf INTCON ; enable interrupts ; ==== main loop ==== ; Loop ; ; Main code now ; ; if switch 1 is on, do debug stuff. on= tied to ground, not pulled-up btfss PORTC, 0 goto _debug_SW1 ; same for switch 2 btfss PORTC, 1 goto _debug_SW2 ; same for switch 3 btfss PORTC, 2 goto _debug_SW3 ; same for switch 4 btfss PORTC, 3 goto _debug_SW4 ; -------------------------- ; --- begin char receive --- ; overrun error ? btfss RCSTA, OERR goto _checkFrameErr ; yes, clear and start over bcf RCSTA, CREN bsf RCSTA, CREN ; call ShowMIDIError goto Loop ; framing error ? _checkFrameErr btfss RCSTA, FERR goto _checkForChar ; yes, clear and start over movf RCREG, w ; call ShowMIDIError goto Loop ; now check for char received... _checkForChar btfsc PIR1, RCIF goto _gotAChar ;no char, start over goto _Midi_Mainline_Done ; -- we have a char -- _gotAChar movf RCREG, w movwf CharIn ; ==debug hack checks movlw 0xA0 subwf CharIn, w btfss STATUS, Z goto _dbghack_check2 ; do debug op #1 here... goto _Midi_Mainline_Done _dbghack_check2 movlw 0xA1 subwf CharIn, w btfss STATUS, Z goto _Midi_DoStateMachine ; do debug op #2 here... goto _Midi_Mainline_Done ; --- MIDI state machine --- _Midi_DoStateMachine ; ; First: if it is a "real-time" message, just ignore it and wait for next ; char in. This is 0xF8-0xFF. ; 0xFF is "reset". We'll honor this one. movlw 0xFF subwf CharIn, w btfss STATUS, Z goto _realtime_midi_msg_check ; we got a reset ; TODO goto _Midi_Mainline_Done _realtime_midi_msg_check ; if CharIn >= 0xF8 ignore it. (see p471 for compare templates) movlw 0xF8 subwf CharIn, w btfsc STATUS, C goto _Midi_Mainline_Done ; do nothing with any of them _processMidi ; branch on what phase we are in movf MIDI_ReceivePhase, w btfss STATUS, Z goto _doPhase1 ; phase 0 movf MIDI_NoteOffMessageByte,w subwf CharIn, w btfss STATUS, Z goto _ph0_check_noteon ; received noteoff message. Save and stay in phase 0. _saveStat movf CharIn, w movwf MIDI_MessageByte goto _Midi_Mainline_Done _ph0_check_noteon movf MIDI_NoteOnMessageByte, w subwf CharIn, w btfss STATUS, Z goto _ph0_checkNoteByte ; received noteon message. Save and stay in phase 0. goto _saveStat _ph0_checkNoteByte ; TODO: ; if > 0x7F, its a message byte we don't interpret. Need to ignore it ; *and all note/velocity/whatever after it* until we get a 0x80/81/90/91. ; See the usenet midi document... ; ; check that it is within the octave-pair range selected by DIP switches. ; ; (p471 in book gives code for all types of comparison checks) ; ; ; If CharIn > MIDI_OctavePairMax, goto error ; movf CharIn, w ; subwf MIDI_OctavePairMax, w ; btfss STATUS, C ; goto _midiError_gotophase0 ; TODO - eat velocity byte ? ; ; ; If CharIn < MIDI_OctavePairMin, goto error ; movf MIDI_OctavePairMin, w ; subwf CharIn, w ; btfss STATUS, C ; goto _midiError_gotophase0 ; TODO - eat velocity byte ? ; ; ; okay. its legit. ;NEW CODE ;don't do the octave pair check now. Do it right before setting ;the triac. this way we handle the velocity whether or not the note ;is within range. if the note isn't in range for this board, we just ;ignore it then. movf CharIn, w movwf MIDI_NoteNum movlw 1 ; goto phase 1 -> expecting velocity movwf MIDI_ReceivePhase goto _Midi_Mainline_Done _doPhase1 ; CharIn is char we just received, and we are in phase 1. ; Check that it is <= 0x7F btfss CharIn, 7 goto _phase1_Ok ; Its not. Error. Go to phase 0. TODO - also attempt to interpret as ; a message? _midiError_gotophase0 call ShowMIDIError _gotoPhase0 movlw 0 movwf MIDI_ReceivePhase goto _Midi_Mainline_Done _phase1_Ok movf CharIn, w movwf MIDI_Velocity ; ; OK! We have a MIDI "message". Do it, and go back to phase 0 for the next. ; call DoMIDICommand goto _gotoPhase0 _Midi_Mainline_Done ;TODO - if switch set, then do sequence as debug ? ; nothing special needs to be done ... goto Loop ; ; Make the MIDI message happen. ; DoMIDICommand ; check that it is within the range selected by DIP switches. ; (p471 in book gives code for all types of comparison checks) ; "If MIDI_NoteNum > MIDI_NoteMax, goto error" movf MIDI_NoteNum, w subwf MIDI_NoteMax, w btfss STATUS, C return ; not in our range, do nothing ; "If MIDI_NoteNum < MIDI_NoteMin, goto error" movf MIDI_NoteMin, w subwf MIDI_NoteNum, w btfss STATUS, C return ; not in our range, do nothing ; ok. note # is in our range. Do it. ; subtract out the octave-pair we are using movf MIDI_NoteMin, w subwf MIDI_NoteNum, w movwf tempMidi ; ; ok. something slightly special. ; we have two ranges of 22 keys. NoteMin to NoteMin+21, and ; NoteMin+24 to NoteMax. Are we in the first range, the two in-between, ; or the second range? movlw d'22' subwf tempMidi, w btfsc STATUS, Z return ; in in-between movlw d'23' subwf tempMidi, w btfsc STATUS, Z return ; in in-between ; "If num < 22, goto first range handler" movlw d'22' subwf tempMidi, w btfss STATUS, C goto _firstRange_Handler ; todo - other range movlw d'1' movwf InputRange ; subtract out 24 so tempMidi is again 0->21 movlw d'24' subwf tempMidi, f goto _handleMidiEvent _firstRange_Handler movlw d'0' movwf InputRange goto _handleMidiEvent _handleMidiEvent ; translate 0-21 (13 white keys + 9 black keys) into strobe # (0-12) ; call with TranslateNoteInput set ; return value is in w movf tempMidi, w movwf TranslateNoteInput call TranslateNote movwf LEDSelected ; if MIDI_MessageByte is noteoff, or its noteon and MIDI_Velocity is 0, ; then turn LED off. movf MIDI_NoteOffMessageByte,w subwf MIDI_MessageByte, w btfsc STATUS, Z goto _doMIDI_turnoff ; its noteon. Check if velocity is zero. movf MIDI_Velocity, w btfsc STATUS, Z goto _doMIDI_turnoff ; we have note on with velocity > 0 movf MIDI_Velocity, w movwf LEDBrightness _doMIDI_doItAndLeave call UpdateLED return _doMIDI_turnoff movlw 0 movwf LEDBrightness goto _doMIDI_doItAndLeave ; macro for LED (trigger) code UPDATE_LED macro MACRO_PORT, MACRO_PORTBit, MACRO_LED, MACRO_hoplabel, MACRO_hoplabel2 movf InputRange,w btfss STATUS, Z goto MACRO_hoplabel ; do first range logic movlw d'255' subwf MACRO_LED, w btfsc STATUS, Z return ; already on from upper-range logic, do nothing movf StrobeOnTimeMsec,w movwf MACRO_LED bsf MACRO_PORT,MACRO_PORTBit return MACRO_hoplabel ; do upper range logic movf LEDBrightness,w btfsc STATUS, Z goto MACRO_hoplabel2 ;note-on movlw d'255' movwf MACRO_LED ; disable from lower range turn-off if in on state bsf MACRO_PORT,MACRO_PORTBit ; turn-on return MACRO_hoplabel2 ;note-off movlw d'0' movwf MACRO_LED ; re-enable lower-range on/off bcf MACRO_PORT,MACRO_PORTBit ; turn-off return endm ; -------------------------------------- ; LEDSelected is the LED to change (0-12) UpdateLED movf InputRange,w btfss STATUS, Z goto _hopOver1 ; in range 0... ignore note-off movf LEDBrightness,w btfsc STATUS, Z ; if LEDBrightness is 0, its note-off, do nothing for now return _hopOver1 movlw HIGH _UpdateLED_JumpTable ; get current 256 instruction block movwf PCLATH ; store it so next jump is correct movf LEDSelected, w ; compute offset within the addlw LOW _UpdateLED_JumpTable ; 256 instruction block btfsc STATUS, C incf PCLATH, f ; if in next, increment PCLATH movwf PCL ; write correct address to the program counter _UpdateLED_JumpTable goto _UpdateLED_Led00 goto _UpdateLED_Led01 goto _UpdateLED_Led02 goto _UpdateLED_Led03 goto _UpdateLED_Led04 goto _UpdateLED_Led05 goto _UpdateLED_Led06 goto _UpdateLED_Led07 goto _UpdateLED_Led08 goto _UpdateLED_Led09 goto _UpdateLED_Led10 goto _UpdateLED_Led11 goto _UpdateLED_Led12 _UpdateLED_Led00 UPDATE_LED PORTB, 7, LED_00, _ULED_00_hopover, _00_hop _UpdateLED_Led01 UPDATE_LED PORTB, 6, LED_01, _ULED_01_hopover, _01_hop _UpdateLED_Led02 UPDATE_LED PORTB, 5, LED_02, _ULED_02_hopover, _02_hop _UpdateLED_Led03 UPDATE_LED PORTB, 4, LED_03, _ULED_03_hopover, _03_hop _UpdateLED_Led04 UPDATE_LED PORTB, 3, LED_04, _ULED_04_hopover, _04_hop _UpdateLED_Led05 UPDATE_LED PORTB, 2, LED_05, _ULED_05_hopover, _05_hop _UpdateLED_Led06 UPDATE_LED PORTB, 1, LED_06, _ULED_06_hopover, _06_hop _UpdateLED_Led07 UPDATE_LED PORTB, 0, LED_07, _ULED_07_hopover, _07_hop _UpdateLED_Led08 UPDATE_LED PORTD, 7, LED_08, _ULED_08_hopover, _08_hop _UpdateLED_Led09 UPDATE_LED PORTD, 6, LED_09, _ULED_09_hopover, _09_hop _UpdateLED_Led10 UPDATE_LED PORTD, 5, LED_10, _ULED_10_hopover, _10_hop _UpdateLED_Led11 UPDATE_LED PORTD, 4, LED_11, _ULED_11_hopover, _11_hop _UpdateLED_Led12 UPDATE_LED PORTC, 5, LED_12, _ULED_12_hopover, _12_hop ShowMIDIError ; turn on heartbeat LED - of course it will just blink off shortly... bsf PORTA, 0 return ; translate 0-21 (13 white keys + 9 black keys) into strobe # (0-12) ; call with TranslateNoteInput set ; return value is in w TranslateNote movf TranslateNoteInput,w movlw HIGH _XlateNote_JumpTable ; get current 256 instruction block movwf PCLATH ; store it so next jump is correct movf TranslateNoteInput, w ; compute offset within the addlw LOW _XlateNote_JumpTable ; 256 instruction block btfsc STATUS, C incf PCLATH, f ; if in next, increment PCLATH movwf PCL ; write correct address to the program counter _XlateNote_JumpTable retlw d'0' ; "C" retlw d'1' ; black key = next white retlw d'1' retlw d'2' ; black key = next white retlw d'2' retlw d'3' retlw d'4' ; black retlw d'4' retlw d'5' ; black retlw d'5' retlw d'6' ; black retlw d'6' retlw d'7' ; "C" retlw d'8' ; black retlw d'8' retlw d'9' ; black retlw d'9' retlw d'10' retlw d'11' ; black retlw d'11' retlw d'12' ; black retlw d'12' Init_MidiStuff movlw 0x80 movwf MIDI_NoteOffMessageByte movlw 0x90 movwf MIDI_NoteOnMessageByte ; MIDI_NoteMin ; Note# that corresponds to output 0 ; MIDI_NoteMax ; Note# that corresponds to output 12 ; range 1: 22 keys (13 white ones), starting on a C ; 2 in-betweens ; range 2: 22 keys, starting on a C movlw d'36' movwf MIDI_NoteMin ; note - this should be a C movlw d'82' movwf MIDI_NoteMax ; new. start with note-on. the casio only sends one note-on message with ; the first keypress; after that, its all implied. if the casio is turned ; on, some keys hit, then the EL board is turned on, we interpret everything ; as note-off with the above. so. change stuff to work with the casio. movf MIDI_NoteOnMessageByte,w movwf MIDI_MessageByte movlw 0 movwf MIDI_NoteNum movwf MIDI_Velocity movwf MIDI_ReceivePhase return ; --------------------------------- ; from p486 in book... ; 12mhz: ; val= (10ms * 12mhz/4)/5 + 256 ; val= 6256 or 0x1870 ; we do the delay Delay10msecNumTimes times Delay10msec_NumTimes movwf Delay10msecNumTimes loopdelay1 movlw LOW 0x1870 movwf Delay10msecVar movlw HIGH 0x1870 movwf Delay10msecVar + 1 loopdelay2 decf Delay10msecVar, f btfsc STATUS, Z decfsz Delay10msecVar+1, f goto loopdelay2 decfsz Delay10msecNumTimes, f goto loopdelay1 return ; --------------------------------- ; this is approximate ; 12mhz: ; val= (1ms * 12mhz/4)/5 + 256 ; val= 856 or 0x358 ; we do the delay Delay1msecNumTimes times ; (recycle variables from the 10ms version) Delay1msec_NumTimes movwf Delay10msecNumTimes loopdelay1_1ms movlw LOW 0x358 movwf Delay10msecVar movlw HIGH 0x358 movwf Delay10msecVar + 1 loopdelay2_1ms decf Delay10msecVar, f btfsc STATUS, Z decfsz Delay10msecVar+1, f goto loopdelay2_1ms decfsz Delay10msecNumTimes, f goto loopdelay1_1ms return ; 00: PORTB, 7 ; 01: PORTB, 6 ; 02: PORTB, 5 ; 03: PORTB, 4 ; 04: PORTB, 3 ; 05: PORTB, 2 ; 06: PORTB, 1 ; 07: PORTB, 0 ; 08: PORTD, 7 ; 09: PORTD, 6 ; 10: PORTD, 5 ; 11: PORTD, 4 ; 12: PORTC, 5 _debug_SW1 bsf PORTB,7 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,7 bsf PORTB,6 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,6 bsf PORTB,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,5 bsf PORTB,4 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,4 bsf PORTB,3 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,3 bsf PORTB,2 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,2 bsf PORTB,1 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,1 bsf PORTB,0 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,0 bsf PORTD,7 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTD,7 bsf PORTD,6 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTD,6 bsf PORTD,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTD,5 bsf PORTD,4 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTD,4 bsf PORTC,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTC,5 goto Loop _debug_SW2 bsf PORTB,7 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,6 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,4 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,3 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,2 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,1 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTB,0 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTD,7 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTD,6 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTD,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTD,4 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bsf PORTC,5 movf StrobeOnTimeMsec, w call Delay1msec_NumTimes movf StrobeOnTimeMsec, w call Delay1msec_NumTimes bcf PORTB,7 bcf PORTB,6 bcf PORTB,5 bcf PORTB,4 bcf PORTB,3 bcf PORTB,2 bcf PORTB,1 bcf PORTB,0 bcf PORTD,7 bcf PORTD,6 bcf PORTD,5 bcf PORTD,4 bcf PORTC,5 movf StrobeOffTimeMsec, w call Delay1msec_NumTimes movf StrobeOffTimeMsec, w call Delay1msec_NumTimes goto Loop _debug_SW3 bsf PORTB,7 bsf PORTB,6 bsf PORTB,5 bsf PORTB,4 bsf PORTB,3 bsf PORTB,2 bsf PORTB,1 bsf PORTB,0 bsf PORTD,7 bsf PORTD,6 bsf PORTD,5 bsf PORTD,4 bsf PORTC,5 ; 5 sec on movlw d'100' call Delay10msec_NumTimes movlw d'100' call Delay10msec_NumTimes movlw d'100' call Delay10msec_NumTimes movlw d'100' call Delay10msec_NumTimes movlw d'100' call Delay10msec_NumTimes bcf PORTB,7 bcf PORTB,6 bcf PORTB,5 bcf PORTB,4 bcf PORTB,3 bcf PORTB,2 bcf PORTB,1 bcf PORTB,0 bcf PORTD,7 bcf PORTD,6 bcf PORTD,5 bcf PORTD,4 bcf PORTC,5 ; one sec off movlw d'100' call Delay10msec_NumTimes goto Loop ; 00: PORTB, 7 ; 01: PORTB, 6 ; 02: PORTB, 5 ; 03: PORTB, 4 ; 04: PORTB, 3 ; 05: PORTB, 2 ; 06: PORTB, 1 ; 07: PORTB, 0 ; 08: PORTD, 7 ; 09: PORTD, 6 ; 10: PORTD, 5 ; 11: PORTD, 4 ; 12: PORTC, 5 _debug_SW4 ; this assumes 60msec on bsf PORTB,7 movlw d'15' call Delay1msec_NumTimes bsf PORTB,6 bsf PORTB,5 bsf PORTB,4 movlw d'15' call Delay1msec_NumTimes bsf PORTB,3 bsf PORTB,2 bsf PORTB,1 bsf PORTB,0 bsf PORTD,7 movlw d'15' call Delay1msec_NumTimes bsf PORTD,6 bsf PORTD,5 bsf PORTD,4 movlw d'15' call Delay1msec_NumTimes bsf PORTC,5 ; now begin turn-off bcf PORTB, 7 movlw d'15' call Delay1msec_NumTimes bcf PORTB,6 bcf PORTB,5 bcf PORTB,4 movlw d'15' call Delay1msec_NumTimes bcf PORTB,3 bcf PORTB,2 bcf PORTB,1 bcf PORTB,0 bcf PORTD,7 movlw d'15' call Delay1msec_NumTimes bcf PORTD,6 bcf PORTD,5 bcf PORTD,4 movlw d'15' call Delay1msec_NumTimes bcf PORTC,5 ; one sec off movlw d'100' call Delay10msec_NumTimes goto Loop END