list P=PIC16F84 #include p16f84.inc ;Program to RX. MIDI data with 4Mhz clock ;MIDI controlled relays (4 off) ;Filename: relay2.asm ;Iteration 1.3 ;Date: 22/10/2000 ;Program: Tom Scarff ;Modification: Addition of 'all notes off' ;******************************** ; Variable Assignment Addresses ; ( 0C to 2F) for PIC16C84 ;******************************** dlyreg equ 0C rcount equ 0D rcvreg equ 0E offsetreg equ 0F noteval1 equ 10h noteval2 equ 11h midich equ 12h count equ 13h relay equ 14h base_addr equ 15h val1 equ 16h val2 equ 17h val3 equ 18h val4 equ 19h note equ 1Ah ;NOTE: RAM addresses for relay 1-4 data start at 20h ;******************************** ; Constant Assignments ;******************************** CARRY equ 00 MSB equ 07 BORROW equ 00 LED1 equ 06 LED2 equ 07 W equ 00 F equ 01 Z equ 02 C equ 00 dx equ 05 ;******************************** ; Port Assignments ;******************************** PCL equ 02 STATUS equ 03 PORTA equ 05 PORTB equ 06 ;************************************ ; PROGRAMME Reset Point ;************************************ org 0 goto INIT ;************************************* ; Subroutines ;************************************* delay1 movlw .12 movwf dlyreg dly1 decfsz dlyreg goto dly1 return delay2 movlw .6 movwf dlyreg dly2 decfsz dlyreg goto dly2 return rxdata btfsc PORTA,4 goto rxdata movlw .8 movwf rcount clrf rcvreg call delay1 rnext bcf STATUS,CARRY rrf rcvreg btfsc PORTA,4 bsf rcvreg,MSB decfsz rcount,F goto loopx8 goto last_b loopx8 call delay2 goto rnext last_b movlw .1 movwf dlyreg dly3 decfsz dlyreg goto dly3 nop nop return ;*********************************** ; Compare note value with val1,2,3,4 ;*********************************** compare movf val1,W subwf rcvreg,W btfsc STATUS,Z retlw 1 movf val2,W subwf rcvreg,W btfsc STATUS,Z retlw 2 movf val3,W subwf rcvreg,W btfsc STATUS,Z retlw 4 movf val4,W subwf rcvreg,W btfsc STATUS,Z retlw 8 retlw 0 ;************************************ ; EEPROM Read ;************************************ ee_read movwf EEADR bsf STATUS,RP0 bsf EECON1,RD r1 btfsc EECON1,RD ; Wait to finish read. goto r1 bcf STATUS,RP0 movf EEDATA,W andlw 07Fh return ;************************************ ; Initialise Software ;************************************ INIT bsf STATUS,RP0 ;enable weak pull-up resistors movlw 07Fh movwf 01h ; Option Register bcf STATUS,RP0 clrf PORTB movlw 0F0H ; '1111 0000' MAKE PORTB 0-3 O/P'S TRIS PORTB ; and 3-7 I/P's movlw 00h ; '0000 0000' movwf PORTB ; Turn off all relays and LEDS clrf PORTA movlw 0FFH TRIS PORTA ;make PORTA all I/P's ;RA1 Prog. Sw. movf PORTB,W ; read midich. switches andlw 0F0h movwf midich swapf midich,F ;************************************** ; Programme EEPROM ;************************************** main0 btfsc PORTA,1 ; is prog. sw. pressed? goto main1 movlw 00h movwf base_addr movlw 04h movwf count movlw 01h movwf relay loop0 movf relay,W ;turn on LED/relay iorwf PORTB,W movwf PORTB start0 call rxdata ; is it status? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto start0 movf rcvreg,W; is it note-on? andlw 0F0h sublw 90h btfss STATUS,Z goto start0 call rxdata ;get note value(in rcvreg) movf rcvreg,W movwf note call rxdata ; get velocity value nop nop nop movf rcvreg,F btfsc STATUS,Z goto start0 ; if velocity=0 movf base_addr,W; start addr. EEPROM movwf EEADR movf note,W andlw 07Fh movwf EEDATA bsf STATUS,RP0 ;writing to eeprom bcf INTCON,GIE bsf EECON1,WREN movlw 55h movwf EECON2 movlw 0AAh movwf EECON2 bsf EECON1,WR nop nop test_wr btfsc EECON1,WR; is write finished? goto test_wr bcf STATUS,RP0 bsf INTCON,GIE comf relay movf PORTB,W andwf relay,W movwf PORTB ; switch off LED/relay 0 to 3 ? incf base_addr comf relay rlf relay,F ; from 0 to 3 bcf relay,0 decfsz count ;from 4 to 1 goto loop0 ;************************************** ; Main Programme Start ; Read EEPROM and write to val,1,2,3,4 ;************************************** main1 clrf base_addr ; start addr. of EEPROM at 00h? movf base_addr,W call ee_read movwf val1 incf base_addr,F movf base_addr,W call ee_read movwf val2 incf base_addr,F movf base_addr,W call ee_read movwf val3 incf base_addr,F movf base_addr,W call ee_read movwf val4 incf base_addr,F ;----------------------------------------- start call rxdata ; is it status? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto start midich? movf rcvreg,W ; correct MIDI Ch.? andlw 0Fh subwf midich,W btfss STATUS,Z goto start noteon? movf rcvreg,W andlw 0F0h sublw 90h btfsc STATUS,Z goto noteon noteoff? movf rcvreg,W andlw 0F0h sublw 80h btfsc STATUS,Z goto noteoff alloff? movf rcvreg,W andlw 0F0h sublw 0B0h btfsc STATUS,Z goto all2 goto start all2 call rxdata ; movf rcvreg,W sublw 7Bh btfss STATUS,Z goto start call rxdata ; movf rcvreg,W sublw 00h btfsc STATUS,Z goto alloff goto start ;------------------------------------------------ noteon call rxdata range1 call compare movwf relay movlw 00h subwf relay,W btfsc STATUS,Z goto start vel call rxdata; Zero velocity=note-off! movf rcvreg,F btfsc STATUS,Z goto zerovel movf relay,W iorwf PORTB,W ; switch on LED/relay 0 to 3 ? movwf PORTB runstat1 call rxdata ; status or note? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto range1 goto midich? zerovel comf relay ; switch off LED/relay 0 to 3 ? movf PORTB,W andwf relay,W movwf PORTB goto runstat1 ;------------------------------------------------- noteoff call rxdata ; note value? range2 call compare movwf relay movlw 00h subwf relay,W btfsc STATUS,Z goto start comf relay ; switch off LED/relay 0 to 3 ? movf PORTB,W andwf relay,W movwf PORTB offvel call rxdata ; vel-off value call rxdata ; status or note-off movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto range2 goto midich? ;---------------------------------------------------- alloff clrf PORTB ;all relays off goto start end