; 10Mhz base clock ; Author : Ross Bencina ; last modified 25/8/99 ; code merge curious@pb194.luban.sdi.tpnet.pl ; CPU cofiguration processor 16f84a include __config _HS_OSC & _WDT_OFF & _PWRTE_ON ; variables potL equ H'1F' potH equ H'1E' ;ra.0 pin assigned to pot out_pot equ d'0' in_pot equ d'1' temp equ H'1D' xmit equ H'1C' i equ H'1B' j equ H'1A' k equ H'19' ; program org 0 ; start @ 0 start: ;-------------------->8------------------ mainloop: ;........................................ bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow call _pot ;wait until previous pic ends sending whole command; call flow_blocked ;wait for free bus movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x01 ; pitch wheel coarse movwf xmit call sendmidi clrf xmit rrf xmit,f rlf potL,f rlf potH,f rlf potH,f rrf xmit,f rrf potH,f rrf xmit,f rrf potL,f movfw potH ; higher nibble - coarse movwf xmit call sendmidi movlw 0xB2 ; controller movwf xmit call sendmidi movlw d'33' ; pitch wheel fine movwf xmit call sendmidi movfw potL ; lower nibble - fine movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call _pot1 ;wait until previous pic ends sending whole command call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x02 ; 02 movwf xmit call sendmidi clrf xmit rrf xmit,f rlf potL,f rlf potH,f rlf potH,f rrf xmit,f rrf potH,f rrf xmit,f rrf potL,f movfw potH ; higher nibble - coarse movwf xmit call sendmidi movlw 0xB2 ; controller -second channel movwf xmit call sendmidi movlw d'34' ; 34 movwf xmit call sendmidi movfw potL ; lower nibble - fine movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call _pot3 ;wait until previous pic ends sending whole command call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x03 ; 02 movwf xmit call sendmidi clrf xmit rrf xmit,f rlf potL,f rlf potH,f rlf potH,f rrf xmit,f rrf potH,f rrf xmit,f rrf potL,f movfw potH ; higher nibble - coarse movwf xmit call sendmidi movlw 0xB2 ; controller -second channel movwf xmit call sendmidi movlw d'35' ; 34 movwf xmit call sendmidi movfw potL ; lower nibble - fine movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.1 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x04 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.2 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x05 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.3 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x06 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.4 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x07 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.5 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x08 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.6 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x09 movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.7 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x0a movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi bsf PORTA,0x04 movlw b'00010100' TRIS PORTA ;unblock flow - we sent whole message! call pot.limited.8 call flow_blocked movlw 0xB2 ; controller movwf xmit call sendmidi movlw 0x0b movwf xmit call sendmidi movfw potL movwf xmit clrf xmit rrf xmit,f rlf potL,f movfw potL movwf xmit call sendmidi goto mainloop flow_blocked: btfss PORTA, 0x04 goto flow_blocked nop ;sync nop nop ;movlw nop ;tris nop ;bcf nop ;return ;check if we're first btfss PORTA, 0x04 goto flow_blocked ; no :( ;yes :) movlw B'00000100' TRIS PORTA ; init port A as output bcf PORTA,0x04 ; block flow - we send an Message! return ; sendmidi transmits one midi byte on RA2 ; at 10Mhz there are 80 instructions per midi bit ; xmit contains byte to send ; * this should be rewritten to support variable delays for ; * different clock speeds sendmidi: movlw B'00000000' TRIS PORTA ; init port A as output startb: bcf PORTA, 0x02 ; start bit movlw D'24' ; delay 73 clocks 2+ (23 *3 +1 *2) movwf temp ; | loop1: decfsz temp ; | goto loop1 movlw D'8' movwf j sendloop: ; executes 5 instructions before setting bit rrf xmit btfsc STATUS, C goto send1 ; remember midi bits are opposite from our representation send0: nop bcf PORTA, 0x02 ; send a 0 bit goto endloop send1: bsf PORTA, 0x02 ; send a 1 bit nop nop endloop: movlw D'23' ; delay 70 instructions 2+ (22 * 3 + 1 * 2) movwf temp ; | loop2: ; | decfsz temp ; | goto loop2 ; end delay decfsz j goto sendloop stopb: nop nop nop nop nop bsf PORTA, 0x02 ; stop bit movlw D'26' ; delay 79 clocks: 2+ (25 * 3 + 1 * 2) movwf temp ; | loop3: ; | decfsz temp ; | goto loop3 ; end delay return ; POT ; This program shows a technique for reading resistance. The pot input pin can ; only be changed during assembly, not once the program is running. _pot clrf potL clrf potH movlw b'00010101' TRIS PORTA bcf PORTA,d'0' ; clear output latch for pot bit. start_loop btfss PORTA,d'0' ; if pot = 0 then : done goto start_done incf potL ; increment potL btfsc STATUS, Z ; if zero then potl overflowed, so incfsz potH ; increment potH. if it overflows, exit goto start_loop ; overflowed? no:loop. start_done movlw b'00010100' TRIS PORTA bsf PORTA,d'0' ; start charging cap. return _pot1 clrf potL clrf potH movlw b'00010110' TRIS PORTA bcf PORTA,d'1' ; clear output latch for pot bit. start_loop1 btfss PORTA,d'1' ; if pot = 0 then : done goto start_done1 incf potL ; increment potL btfsc STATUS, Z ; if zero then potl overflowed, so incfsz potH ; increment potH. if it overflows, exit goto start_loop1 ; overflowed? no:loop. start_done1 movlw b'00010100' TRIS PORTA bsf PORTA,d'1' ; start charging cap. return getdelay movwf temp ; | getloop1: decfsz temp ; | goto getloop1 return _pot3 clrf potL clrf potH movlw b'00011100' TRIS PORTA bcf PORTA,d'3' ; clear output latch for pot bit. start_loop3 btfss PORTA,d'3' ; if pot = 0 then : done goto start_done3 incf potL ; increment potL btfsc STATUS, Z ; if zero then potl overflowed, so incfsz potH ; increment potH. if it overflows, exit goto start_loop3 ; overflowed? no:loop. start_done3 movlw b'00010100' TRIS PORTA bsf PORTA,d'3' ; start charging cap. return getmidi3: bcf PORTA,0x03 movlw b'00001000' TRIS PORTA clrf xmit btfss PORTA, 0x03 goto get_what_is3 nop nop nop nop nop nop nop nop nop nop nop nop get_what_is3 btfsc PORTA, 0x03 ; start bit? goto nothing_to_get3 ; no? so why we're doing this shit... movlw D'24' ; delay 73 clocks 2+ (23 *3 +1 *2) call getdelay movlw D'8' movwf j getloop3: ; executes 5 instructions before setting bit btfsc PORTA, 0x03 bsf temp,0x00 btfss PORTA, 0x03 bcf temp,0x00 rrf temp rrf xmit movlw D'24' ; delay 73 instructions 2+ (22 * 3 + 1 * 2) call getdelay decfsz j goto getloop3 nothing_to_get3 movlw 0x00 TRIS PORTA bsf PORTA,0x03 return pot.limited.1 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'1' ; get input from pot. TRIS PORTB bcf PORTB,d'0' ; clear output latch for pot bit. start_loop.limited.1 btfss PORTB,d'0' ; if pot = 0 then : done goto start_done.limited.1 incfsz potL ; increment potL goto start_loop.limited.1 ; overflowed? no:loop. start_done.limited.1 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'0' ; start charging cap. return pot.limited.2 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'2' ; get input from pot. TRIS PORTB bcf PORTB,d'1' ; clear output latch for pot bit. start_loop.limited.2 btfss PORTB,d'1' ; if pot = 0 then : done goto start_done.limited.2 incfsz potL ; increment potL goto start_loop.limited.2 ; overflowed? no:loop. start_done.limited.2 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'1' ; start charging cap. return pot.limited.3 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'4' ; get input from pot. TRIS PORTB bcf PORTB,d'2' ; clear output latch for pot bit. start_loop.limited.3 btfss PORTB,d'2' ; if pot = 0 then : done goto start_done.limited.3 incfsz potL ; increment potL goto start_loop.limited.3 ; overflowed? no:loop. start_done.limited.3 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'2' ; start charging cap. return pot.limited.4 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'8' ; get input from pot. TRIS PORTB bcf PORTB,d'3' ; clear output latch for pot bit. start_loop.limited.4 btfss PORTB,d'3' ; if pot = 0 then : done goto start_done.limited.4 incfsz potL ; increment potL goto start_loop.limited.4 ; overflowed? no:loop. start_done.limited.4 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'3' ; start charging cap. return pot.limited.5 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'16' ; get input from pot. TRIS PORTB bcf PORTB,d'4' ; clear output latch for pot bit. start_loop.limited.5 btfss PORTB,d'4' ; if pot = 0 then : done goto start_done.limited.5 incfsz potL ; increment potL goto start_loop.limited.5 ; overflowed? no:loop. start_done.limited.5 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'4' ; start charging cap. return pot.limited.6 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'32' ; get input from pot. TRIS PORTB bcf PORTB,d'5' ; clear output latch for pot bit. start_loop.limited.6 btfss PORTB,d'5' ; if pot = 0 then : done goto start_done.limited.6 incfsz potL ; increment potL goto start_loop.limited.6 ; overflowed? no:loop. start_done.limited.6 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'5' ; start charging cap. return pot.limited.7 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'64' ; get input from pot. TRIS PORTB bcf PORTB,d'6' ; clear output latch for pot bit. start_loop.limited.7 btfss PORTB,d'6' ; if pot = 0 then : done goto start_done.limited.7 incfsz potL ; increment potL goto start_loop.limited.7 ; overflowed? no:loop. start_done.limited.7 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'6' ; start charging cap. return pot.limited.8 ; movlw d'00' ; RA.0 to output ; TRIS PORTB ; movlw 0xFF ; movwf PORTB ; start charging caps (all) clrf potL movlw d'128' ; get input from pot. TRIS PORTB bcf PORTB,d'7' ; clear output latch for pot bit. start_loop.limited.8 btfss PORTB,d'7' ; if pot = 0 then : done goto start_done.limited.8 incfsz potL ; increment potL goto start_loop.limited.8 ; overflowed? no:loop. start_done.limited.8 movlw d'00' ; RA.0 to output TRIS PORTB bsf PORTB,d'7' ; start charging cap. return end