; File MIDISEND.ASM ; Assembly code for a 10MHz PIC16F84 microcontroller ; ; Description: Send a midi message once every second
; 보낸다. 미디 메세지를 ; Author: Ross Bencina ; Last Modified: 25 / 8 / 99 ; ; CPU configuration processor 16f84 include <p16f84.inc> __config _HS_OSC & _WDT_OFF & _PWRTE_ON ; variables temp equ H'1F' xmit equ H'1D' i equ H'1C' j equ H'1B' k equ H'1A' ; Program org 0 ; start at address 0 ....시작주소 start: movlw B'00000000' tris PORTA ; init port A as output bsf PORTA, 0x02 ; init midi out pin state
;포트A의 2번째 bit를 set시킨다.
mainloop:
call secdelay ; 아래의 레이블 secdelay를 불러온다. (Return명령어를 만나면 다시 이자리로 돌아온다.) movlw 0x90 ; note on, channel 1 movwf xmit call sendmidi movlw 0x3C ; middle C movwf xmit call sendmidi movlw 0x7F ; velocity 127.....7F = 0111 1111 = 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 = 127 movwf xmit call sendmidi call secdelay movlw 0x80 ; note off, channel 1 movwf xmit call sendmidi movlw 0x3C ; middle C movwf xmit call sendmidi movlw 0x7F ; velocity 127 movwf xmit call sendmidi goto mainloop ; sendmidi transmits one midi byte on RA2 ; at 10mhz
; sendmidi는 전송한다. 하나의 midi바이트를 on RA2상에서
; at 10mhz의 속도로
;there are 80 instructions per midi bit
; 80개의 명령어들이있다. / 한 미디 비트당 ; xmit contains byte to send
; xmit은 포함한다. 바이트를 to 보내기위한 ; * this should be rewritten to support variable delays for ; * different clock speeds
sendmidi: startb: bcf PORTA, 0x02 ; start bit......포트A의 02번째 비트를 Clear시킨다. movlw D'24' ; delay 73 clocks: 2 + (23 * 3 + 1 * 2) movwf temp ; | loop1: decfsz temp,f ; | goto loop1 ; end delay movlw D'8' movwf j ;j에 8이 들어있다. sendloop: ; executes 5 instuctions before setting bit rrf xmit,f ;Rotate Right File, xmit값을 회전시키고 f에 저장 btfsc STATUS, C ;bit test file, STAUS의 Carry가 0이면 Skip한다. 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,f ; | goto loop2 ; end delay decfsz j,f ; 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,f ; | goto loop3 ; end delay return ; secdelay delays for one second ( 2500000 instructions ) ; kloop = (2 + 254 * 3 + 1 * 2) = 766 ; jloop = 2 + kloop * 255 + (3 * 254 + 1 * 2) = 196096 ; iloop = 2 + jloop * 13 + (3*254 + 1*2) = 2550014 = 1.02 seconds ; x = secdelay: movlw D'13' ;여기서의 D는 Decimal movwf i ;i=13 iloop: movlw D'255' movwf j ;j=255 jloop: movlw D'255' movwf k ;k=255 kloop: decfsz k,f ;k값을 1씩 줄인다.결과를 f에 저장.(Skip한다. 만약 값이 Zero라면) goto kloop ;k가 0이 아니라면 kloop 레이블로 향할것!!!......참고로 k값은 jloop에서 할당되었다. decfsz j,f ;j값을 1씩 줄인다. 결과를 f에 저장. (Skip한다. 만약 값이 Zero라면) goto jloop decfsz i,f ;i값을 1씩 줄인다. 결과를 f에 저장. (Skip한다. 마냥ㄱ 값이 Zero라면) goto iloop return ; 위에서 Call했던 곳으로 돌아간다. end