; WRITTEN BY: TOM SCARFF ; DATE: 29/09/2002 ; ITERATION: 1.1 ; FILE SAVED AS: mid_chan.ASM ; MODIFICATION: ; ; FOR: PIC16F877 ; CLOCK: 4.00 MHz CRYSTAL ; INSTRUCTION CLOCK: 1.00 MHz T= luS ; PROGRAMME FUNCTION: To read MIDI in and change all to specific channel ; and to transmit it out. list p=16F877 ; tells the assembler which PIC #include "p16F877.inc" ; general register file __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_OFF & _LVP_OFF & _DEBUG_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;******************************** ; Variable Assignment Addresses ; ( from 20h) for PIC16F877 ;******************************** rcvreg equ 20h midich equ 21h ;************************************ ; PROGRAMME Reset Point ;************************************ org 00 ; reset vector goto init ;****************************************** ; Receive Data subroutine ;****************************************** rxdata btfss PIR1,RCIF ; test for incoming data goto $-1 movf RCREG,W movwf rcvreg return ;****************************************** ; transmission complete subroutine ;***************+************************** txchar bsf STATUS,RP0 btfss TXSTA,1 ; test for end of transmission goto $-1 bcf STATUS,RP0 return ;****************************************** ; initalise software ;****************************************** init bcf STATUS,RP0 ;page 0 clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE bsf STATUS,RP0 MOVLW 6 MOVWF ADCON1 ;set port A as digital CLRF TRISA ;all pins outputs CLRF TRISB ;all pins outputs CLRF TRISD ;all pins outputs movlw 04h ; 0000 0100 movwf TRISE ; bit 2 i/p bcf STATUS,RP0 ; return to page 0 ; Set up USART bsf STATUS,RP0 ; goto page 1 movlw b'10001111' ; RC7 is RX input movwf TRISC ; RC0-3 i/p MIDI Ch. movlw 01h ; 31250 baud for MIDI movwf SPBRG movlw b'00100000' ; async tx 8 bit movwf TXSTA bcf STATUS,RP0 ; return to page 0 movlw b'10010000' ; async rx 8 bit movwf RCSTA clrw movwf midich clrf PORTA ; set all outputs to '0000 0000' clrf PORTB clrf PORTD movlw 04h ; 0000 0100 movwf PORTE goto start ;************************************************ start movf PORTC,W ; read midich. switches andlw 0Fh movwf midich call rxdata ; is it status? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto start ; no system? movf rcvreg,W ; is it System Message? andlw 0F0h sublw 0F0h btfss STATUS,Z ; goto cont1 ; no movf rcvreg,W ; yes, so sublw 0F0h btfsc STATUS,Z ; is it System Exclusive goto sys_excl movf rcvreg,W ; yes, so sublw 0F3h btfsc STATUS,Z ; is it Song Select goto midi_3byte movf rcvreg,W ; yes, so sublw 0F2h btfsc STATUS,Z ; is it Song Position Pointer goto midi_2byte movf rcvreg,W ; yes, so sublw 0F1h btfsc STATUS,Z ; is it MIDI Time Code goto midi_2byte movf rcvreg,W movwf TXREG ; no, so transmit call txchar goto start sys_excl movf rcvreg,W movwf TXREG call txchar call rxdata ; is it End of System Exclusive movf rcvreg,W sublw 0F7h btfss STATUS,Z goto sys_excl ; no, keep outputting data movf rcvreg,W ; yes, so o/p 0F7h and re-start movwf TXREG call txchar goto start cont1 movf rcvreg,W andlw 0F0h ; set midi channel = 0 addwf midich,W ; add pre-set midich movwf TXREG ; transmit call txchar ;----------------------------- movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto midi_3byte movf rcvreg,W andlw 90h sublw 90h btfss STATUS,Z goto midi_3byte movf rcvreg,W andlw 0A0h sublw 0A0h btfss STATUS,Z goto midi_3byte movf rcvreg,W andlw 0B0h sublw 0B0h btfss STATUS,Z goto midi_3byte movf rcvreg,W andlw 0C0h sublw 0C0h btfss STATUS,Z goto midi_2byte movf rcvreg,W andlw 0D0h sublw 0D0h btfss STATUS,Z goto midi_2byte movf rcvreg,W andlw 0E0h sublw 0E0h btfss STATUS,Z goto midi_3byte goto start ;------------------------------------------------ midi_3byte call rxdata ; check 2nd value range1 movf rcvreg,W movwf TXREG ; transmit call txchar call rxdata ; check 3rd value movf rcvreg,W movwf TXREG ; transmit call txchar call rxdata ; status or note? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto range1 ; if in running status goto system? ;------------------------------------------------- midi_2byte call rxdata ; check 2nd value range2 movf rcvreg,W movwf TXREG ; transmit call txchar call rxdata ; status or note? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto range2 ; if in running status goto system? ;--------------------------------------------------- end