home *** CD-ROM | disk | FTP | other *** search
- ; RXINT:
- ; version 1.1
- ; 2/2/86
- ;
- ; This is the main receive interrupt.
- ; It is called when the DART receives data.
- ; This version supports carry-over (running) status bytes
- ; as well as a translate table.
- ;
-
- DSEG
-
- ; These are C's globals
- PUBLIC r_segment_
- PUBLIC ptr_
- PUBLIC end_
- PUBLIC destbyte_
- PUBLIC clsb_
- PUBLIC cmsb_
- PUBLIC stop_
- PUBLIC LAST_STAT_
- PUBLIC C_O_F_ ; status carry-over flag
- PUBLIC clk_type_ ; 0=internal, 1=external
- PUBLIC counter_dec_
- PUBLIC in_filt_ ; the MIDI input filter
- ; bit:
- ; 0 = Note on filt
- ; 1 = Note off filt
- ; 2 = Prog change filt
- ; 3 = Channel after-touch
- ; 4 = Pitch wheel
- ; 5 = All other controllers
- ; 6 = Key after-touch
-
- CSEG ; ALL CODE
-
- PUBLIC rxint_
-
- rxint_:
- STI ; interrupts back on
- PUSH AX
- MOV AL,0B9H ; shut off counter interrupt
- OUT 021H,AL
- PUSH BX
- PUSH DX
- PUSH ES
- PUSH DS
- MOV AX,0 ; this will be new value for the
- ; DS so we can access the OLD DS
- MOV DS,AX
- MOV BX,WORD [04FAH] ; put new DS in BX
- MOV DS,BX ; put new DS in DS
- MOV AX,r_segment_
- MOV ES,AX ; set buffer segment
-
- sst:
- MOV DX,0FFA2H ; midi stat
- MOV AL,1 ; rd register 1
- OUT DX,AL
- IN AL,DX ; RD reg 1
- AND AL,32 ; Rx overrun error?
- JNZ finished ; if so, than we're REALLY done!
- _st: ; jumped to by _iret if another char is available
- IN AL,DX ; read status register
- AND AL,1 ; Rx char?
- JZ _iret ; if not, return
- MOV DX,0FFA0H ; MIDI data
- IN AL,DX ; now let's read it
- MOV DL,AL ; store in DL for later
- CMP AL,0F8H ; timing clock?
- JNZ C1 ; if not, check for stop
- MOV DL,counter_dec_ ; get amount to decrement counter
- MOV DH,0 ; we'll do a word subtract
- MOV AL,clsb_ ; get lsb
- MOV AH,cmsb_ ; get msb
- SUB AX,DX ; dcr word
- MOV clsb_,AL ; store lsb
- MOV cmsb_,AH ; store msb
- JMP _iret ; if is, all done
-
- C1:
- CMP AL,0FCH ; MIDI Stop?
- JNZ C4 ; if not, continue
- MOV BYTE stop_,1 ; else, set stop byte
- JMP _iret ; and return
- C4:
- AND AL,0F0H ; strip off top 4
- CMP AL,0F0H ; running status?
- JZ _iret ; if so, we're done
- MOV BYTE AL,destbyte_ ; get destbyte
- CMP AL,0FFH ; shall we continue?
- JZ _iret ; if not, then we're done
- MOV BL,AL ; keep for later
- AND AL,0F0H ; strip off top four
- JZ _newmsg ; first byte of a new message - What a revelation!
- contzz: ; branch point from carry-over status
- CMP AL,010H ; Note ON?
- JZ _nton ; yes?
- CMP AL,020H ; Note OFF?
- JZ _noff ; yes?
- CMP AL,070H ; Poly key pres?
- JZ _keypres
- CMP AL,040H ; Bender?
- JZ _bender ; yes?
- CMP AL,050H ; Control Change?
- JZ _cchan ; yes?
- CMP AL,060H ; Channel Velocity?
- JZ _cvel ; For now, throw away channel velocity
- CMP AL,030H ; Prog Change?
- JZ _pchan ; yes?
- JMP _iret ; This would fall through for FILTed out codes
-
- ; this routine (newmsg) processes the first byte of a given
- ; message, and also decides if it is an important message
-
- _newmsg: ; it's a new message
- MOV AL,DL ; retrieve
- AND AL,080H
- MOV AL,DL
- MOV BYTE C_O_F_,0 ; no carry-over
- JNZ contxx ; check for MIDI carry-over stat.
- MOV BYTE AL,LAST_STAT_ ; get previous status byte
- MOV BYTE C_O_F_,0FFH ; carry-over status
- contxx:
- MOV BYTE destbyte_,0 ; this is default in case code isn't
- ; supported or is filtered out
- MOV CL,in_filt_ ; this is input filter
- AND AL,0F0H ; strip off channel info.
- MOV LAST_STAT_,AL ; save new last stat
- CMP AL,090H ; Note ON?
- JZ _nnon ; yes?
- CMP AL,080H ; Note OFF?
- JZ _nnoff ; yes?
- CMP AL,0A0H ; Poly key press?
- JZ _nkeypres ; yes?
- CMP AL,0E0H ; Pitch Wheel
- JZ _npwch ; yes?
- CMP AL,0B0H ; Control Change?
- JZ _ncchan ; yes?
- CMP AL,0C0H ; Prog. Chan?
- JZ _npchan ; yes?
- CMP AL,0D0H ; Channel Velocity?
- JZ _nchanv ; yes?
- JMP _iret ; otherwise, it must be a code we don't support
-
- _nnon: ; first byte of a note on just came in
- AND CL,1 ; keep note-ons?
- JZ _iret ; no, then all done.
- CALL _stime ; store present time
- MOV BYTE ES:[BX],0 ; put 0 at *ptr - I.D. code for note on/off
- MOV BYTE destbyte_,011H ; note on in dest byte
- JMP _cco ; check carry-over
-
- _nnoff: ; first byte of note off just came in
- AND CL,2 ; keep note-offs?
- JZ _iret ; no, then all done
- CALL _stime ; same as _nnon (above)
- MOV BYTE ES:[BX],0 ; I.D.
- MOV BYTE destbyte_,021H ; note off in destbyte
- JMP _cco ; check carry-over
-
- _ncchan: ; first byte of control change
- AND CL,32 ; keep control changes?
- JZ _iret ; no
- CALL _stime
- MOV BYTE ES:[BX],0C0H ; I.D.
- MOV BYTE destbyte_,051H ; cchan in destbyte
- JMP _cco ; check carry-over
-
- _npchan: ; 1st byte of program change
- AND CL,4 ; keep prog. changes?
- JZ _iret
- CALL _stime
- MOV BYTE ES:[BX],040H ; I.D.
- MOV BYTE destbyte_,031H ; prog chan in destbyte
- JMP _cco ; check carry-over
-
- _nchanv: ; 1st byte of Channel pressure
- AND CL,8 ; keep channel pressure?
- JZ _iret
- CALL _stime
- MOV BYTE ES:[BX],041H ; I.D.
- MOV BYTE destbyte_,061H ; chan vel in dbyte
- JMP _cco ; check carry-over
-
- _nkeypres: ; 1st byte of Poly. key pres.
- AND CL,64 ; keep poly. key pres?
- JZ _iret
- CALL _stime
- MOV BYTE ES:[BX],060H ; I.D.
- MOV BYTE destbyte_,071H ; chan vel in dbyte
- JMP _cco ; check carry-over
-
- _npwch: ; first byte of pitch wheel change
- AND CL,16 ; keep pitch wheel?
- JZ _iret
- CALL _stime
- MOV BYTE ES:[BX],080H ; I.D.
- MOV BYTE destbyte_,041H ; pitch wheel in dbyte
- JMP _cco ; check carry-over
-
- _cco: ; check carry over flag
- MOV BYTE AL,C_O_F_ ; get carry over flag
- OR AL,AL ; set flags
- JZ _iret
- MOV BYTE AL,destbyte_
- MOV BL,AL
- AND AL,0F0H
- JMP contzz ; carry over
-
- ; now for the routines that are called while a message is in
- ; progress:
-
- _nton: ; note on processing routine
- AND BL,1 ; BL still has destbyte in it
- MOV WORD BX,ptr_ ; get pointer
- JZ _ntonvel ; must be a 2, so go and save velocity
- OR DL,080H ; set top bit of note
- ADD BX,3 ; inr pointer to note
- MOV BYTE ES:[BX],DL ; store it
- INC BYTE destbyte_ ; inr for velocity, which will come in next
- JMP _iret ; all done
- _ntonvel: ; must be a velocity byte
- SHR DL,1 ; shift velocity byte one to the right
- OR BYTE ES:[BX],DL ; OR it in
- MOV BYTE destbyte_,0 ; next byte will be a newmsg
- ADD WORD ptr_,4 ; inr ptr
- JMP _iret ; all done
-
- _noff: ; note off processing routine
- AND BL,1 ; BL still has destbyte in it
- MOV WORD BX,ptr_ ; get pointer into buff
- JZ _ntoffvel ; if destbyte=2, then it must be a velocity
- ADD BX,3 ; inr to where we'll store the note
- MOV BYTE ES:[BX],DL ; store note; top bit should already be 0
- INC BYTE destbyte_ ; inr destbyte for velocity
- JMP _iret ; all done
- _ntoffvel: ; must be a velocity byte
- SHR DL,1 ; shift DL logically right 1
- OR BYTE ES:[BX],DL ; OR it in
- MOV BYTE destbyte_,0 ; next byte will be a newmsg
- ADD WORD ptr_,4 ; now _ptr points to the next message spot
- JMP _iret ; all done
-
- _pchan: ; program change (new program)
- MOV WORD BX,ptr_ ; get pointer; no need to check byte number
- ; because only two bytes are transmitted
- ADD BX,3 ; this is where we'll store the new prog. #
- MOV BYTE ES:[BX],DL ; store data
- MOV BYTE destbyte_,0 ; reset to newmsg
- ADD WORD ptr_,4 ; inr to pstn. of next massage
- JMP _iret ; all done
-
- _bender: ; store bender data
- AND BL,1 ; first data byte?
- JZ _bmsb ; if not, than go and store the MSB
- INC BYTE destbyte_ ; inr for next pass
- JMP _iret ; all done
- _bmsb: ; store MSB of bender
- SHR DL,1 ; shift DL down 1
- MOV WORD BX,ptr_ ; get ptr
- OR BYTE ES:[BX],DL ; OR in top 6 of MSB of bender
- ADD WORD ptr_,3 ; inr pointer to next message
- MOV BYTE destbyte_,0 ; next message will newmsg
- JMP _iret ; all done
-
-
- _cchan: ; control change
- AND BL,1 ; control #?
- MOV WORD BX,ptr_ ; get ptr_
- JNZ _cnum ; if input is control #, then save it
- ADD BX,4 ; this is where we'll store the control value
- MOV BYTE ES:[BX],DL ; store control value
- MOV BYTE destbyte_,0 ; next byte will newmsg
- ADD WORD ptr_,5 ; inr to next message location
- JMP _iret ; all done
- _cnum: ; number
- ADD BX,3 ; address of control number
- MOV BYTE ES:[BX],DL ; store control number
- INC BYTE destbyte_ ; next byte will be control value
- JMP _iret ; all done
-
- _cvel: ; channel velocity
- MOV WORD BX,ptr_ ; load BX w/pointer
- MOV BYTE ES:[BX+3],DL ; store velocity
- ADD WORD ptr_,4 ; inr to next message pstn.
- MOV BYTE destbyte_,0 ; next byte will be new msg
- JMP _iret ; all done
-
- _keypres: ; poly. key pressure
- AND BL,1 ; amount?
- MOV WORD BX,ptr_
- JZ _storepres ; store key pressure
- ADD BX,3 ; this is where to store the note num.
- MOV BYTE ES:[BX],DL ; store it
- INC BYTE destbyte_ ; next byte will be val.
- JMP _iret
- _storepres: ; store key pressure
- SHR DL,1
- SHR DL,1 ; shift DL right 2 (/4)
- OR ES:[BX],DL ; OR it in
- MOV BYTE destbyte_,0 ; next byte new message
- JMP _iret ; all done
-
-
- _stime: ; routine to read the PIT and store the results
- ; in the buffer
- PUSH DX ; preserve data
- MOV WORD BX,ptr_ ; get pointer
- MOV AL,clk_type_ ; get clk type (0=int)
- OR AL,AL ; set flags
- JNZ ext_clk ; is clk_type=ext_clk??
- MOV AL,64 ; counter latching operation
- MOV DX,0FFA7H ; counter stat
- OUT DX,AL ; out to PIT
- NOP ; stall for time
- NOP
- MOV DX,0FFA5H ; counter 2
- IN AL,DX ; read _clsb
- MOV BYTE ES:[BX+1],AL ; store in buffer
- NOP
- NOP
- IN AL,DX ; read _cmsb
- MOV BYTE ES:[BX+2],AL
- POP DX ; restore data
- RET
-
- ext_clk: ; timing clock from MIDI
- MOV DL,clsb_
- MOV DH,cmsb_ ; get MSB & LSB
- MOV BYTE ES:[BX+1],DL
- MOV BYTE ES:[BX+2],DH ; store MSB & LSB
- POP DX ; restore DX
- RET ; all done
-
- _eoi: ; send EOI to PIC
- PUSH AX ; we'll be using this
- MOV AL,020H ; EOI
- OUT 020H,AL ; EOI
- POP AX ; restore AX
- RET ; all done
-
- _iret1: ; execute EOI and then return
- CALL _eoi
-
- finished: ; Rx overrun error
- MOV BYTE stop_,0FFH ; CRITICAL ERROR!!!
- JMP f2
-
- _iret: ; all done routine
- MOV DX,0FFA2H ; DART status reg
- IN AL,DX
- AND AL,1 ; RxD? (THIS WILL HAVE TO BE CHANGED TO CHECK
- ; FOR EXTERNAL STAT. ALSO)
- JNZ sst ; if so, than go to top of routine
- f2: ; C equivalent:
- ; if(end > ptr)
- ; goto okay;
- ; else
- ; stop=1;
- ; MOV BX,ptr_
- ; MOV DX,end_
- ; CMP DX,BX
- ; JG f3
- ; MOV BYTE stop_,1 ; Woaaaah!! Stop Everything!! - We're out of memory
- f3:
- mov al,0b8h
- out 021h,al
- POP DS
- POP ES
- POP DX
- POP BX
- POP AX ; retrieve registers
- call _eoi
- IRET ; ALL DONE!!!!!!!