/* this is a program to test out the playing of background midi sequences */ #include #include #include "midi.h" #define TRAPS 0x080 /* global variables */ kbdvecs *thevecs; long old_vec; long in_vec; long old_trap; int midi_stat; char om[512],im[4096]; /* input and output midi buffers */ extern midi_vec(); extern mout(); extern Mymidi(); extern jump_tab(); init_buffers() { MIDI_BUFFER *midi_buff; midi_buff = get_midi_out_rec(); midi_buff->head = 0; midi_buff->tail = 0; midi_buff->size = 512; midi_buff->buffer = om; midi_buff = get_midi_in_rec(); midi_buff->head = 0; midi_buff->tail = 0; midi_buff->buffer = im; midi_buff->size = 4096; } asm { /* this is the entry of midi IRQ handler */ uart_csr: dc.b 0; /* control shadow for urat CSR */ dc.b 0; inmidi: dc.l 0 dc.w 0 dc.w 0 dc.w 0 dc.w 0 outmidi: dc.l 0 dc.w 0 dc.w 0 dc.w 0 dc.w 0 /* ** The OS irq saves D0-D3,A0-A3,A5 so, I don't have to here ** as I had figured */ midi_vec: move.b MIDI_CSR,D3 /* get MIDI port status */ btst.b #7,D3 /* was it a MIDI interrupt */ beq.b exit /* no, do keyboard */ btst.b #0,D3 /* recieve interrupt */ beq.b next /* not recieve, check xmit */ bsr mim /* handle midi in interrupt */ next: btst.b #1,D3 /* transmit interrupt */ beq.b exit bsr mout /* do midi out */ exit: rts /* get out of here */ /* ** This is the midi in interrupt service routine */ get_inrec: lea inmidi(PC),A0 move.l A0,D0 rte mim: move.b MIDI_DATA,D0 lea inmidi(PC),A0 /* get the address of the input buffer des */ movea.l BUFFER(A0),A1 /* address of buffer */ move.w TAIL(A0),D2 /* index of data pointer */ addq.w #1,D2 /* i = t+1 */ cmp.w SIZE(A0),D2 /* i >= current size? */ bcs.b mim01 moveq #0,D2 mim01: cmp.w HEAD(A0),D2 /* do we need to wrap? */ beq.b mim_exit move.b D0,0(A1,D2) /* store data into buffer */ move.w D2,TAIL(A0) /* save the index */ mim_exit: rxit: rxit: rxit: rxit: r* get midi out descriptor */ ori.w #0x700,SR /* disable the interrupts */ move.b (A2),D0 btst.l #1,D0 /* is transmit buffer full? */ beq.b mio1 /* xmit full, put into circ buffer */ move.w HEAD(A0),D2 cmp.w TAIL(A0),D2 /* head == Tail? */ bne.b mio1 /* no, so branch */ move.b D1,MIDI_DATA /* put data into UART */ lea uart_csr(PC),A1 ori.b #ENABLE_TX,(A1) move.b (A1),(A2) bra mio3 mio1: move.w TAIL(A0),D2 /* get current tail pointer */ addq.w #1,D2 /* i = t+1 */ cmp.w SIZE(A0),D2 /* i >= current size? */ bcs.b mio01 moveq #0,D2 mio01: cmp.w HEAD(A0),D2 /* head = tail? */ beq.b mio2 /* no space left */ move.l BUFFER(A0),A1 /* pointer to Data Buffer */ move.b D1,0(A1,D2) /* store data to buffer */ move.w D2,TAIL(A0) /* SAVE tail pointer */ mio3: moveq #0,D0 move (A7)+,SR /* enable interrupts */ rte mio2: /* this means bad output */ moveq #-1,D0 move (A7)+,SR /* enable interrupts */ rte midinstat: rte midputstat: rte ms_write: /* ** this routine real fast like, put a midi string into the ** buffer for output on the midi port. Interrupts are disabled ** durring this operation, but we are going for all out speed ** here so this routine should not take long to execute ** ** A0 will contain the address of the output midi descriptor ** A1 is the base address of the UART ** A2 is the address of the output string ** A3 will point to the output buffer ** A4 used to point to CSR shadow ** D1 is the lenth of the string */ move SR,-(A7) /* save status reg */ lea MIDI_CSR,A1 lea outmidi(PC),A0 /* get midi out descriptor */ ori.w #0x700,SR /* disable the interrupts */ move.b (A1),D0 btst.l #1,D0 /* is transmit buffer full? */ beq.b msw1 /* xmit full, put into circ buffer */ move.w HEAD(A0),D2 cmp.w TAIL(A0),D2 /* head == Tail? */ bne.b msw1 /* no, so branch */ move.b (A2)+,2(A1) /* put data into UART */ subq #1,D1 /* subtract one from lenth */ lea uart_csr(PC),A4 ori.b #ENABLE_TX,(A4) move.b (A4),(A1) /* Enable Uart interrupts */ msw1: /* ** Ok, we can really scream here, so download this sucker, FAST! */ move.l BUFFER(A0),A3 /* pointer to Data Buffer */ move.w TAIL(A0),D2 /* get current tail pointer */ move.w SIZE(A0),D0 move.w HEAD(A0),D3 lmsw1: addq.w #1,D2 /* i = t+1 */ cmp.w D0,D2 /* i >= current size? */ bcs.b msw01 moveq #0,D2 msw01: cmp.w D3,D2 /* head = tail? */ beq.b msw2 /* no space left */ move.b (A2)+,0(A3,D2) /* move data */ dbf D1,lmsw1 /* keep on looping */ move.w D2,TAIL(A0) /* save index */ msw3: moveq #0,D0 move (A7)+,SR /* enable interrupts */ rte msw2: /* this means bad output */ moveq #-1,D0 move (A7)+,SR /* enable interrupts */ rte /* ** This is the jump table for the midi handler */ disable_interrupts: ori.w #0x700,SR /* disable the interrupts */ rte enable_interrupts: andi.w #0xf8ff,SR /* enable the interrupts */ rte jump_tab: dc.l midin dc.l midput dc.l midinstat dc.l midputstat dc.l get_inrec dc.l get_outrec dc.l ms_write dc.l disable_interrupts dc.l enable_interrupts } put_midi(a) int a; { asm { move.w a(A6),D1 moveq #MIDIPUT,D0 /* put function number */ trap #3 } } get_midi() { asm { moveq #MIDIGET,D0 /* get function number */ trap #3 } /* this will return with data in D0 */ } init_traps() { old_trap = Setexc(35,Mymidi); } restore_traps() { Setexc(35,old_trap); } midi_init() { init_traps(); /* enable trap 3 for our use */ init_buffers(); init_midput(); init_vecs(); } midi_cleanup() { restore_vecs(); restore_traps(); } init_vecs() { thevecs = (kbdvecs *)Kbdvbase(); /* get 6850 irq vectors */ old_vec = (long)thevecs->midisys; thevecs->midisys = midi_vec; } restore_vecs() { thevecs = (kbdvecs *)Kbdvbase(); thevecs->midisys = (int(*)())old_vec; } irq_en() { asm { moveq #ENABLE_INTERRUTS,D0 trap #3 } } irq_dis() { asm { moveq #DISABLE_INTERRUTS,D0 trap #3 } } midi_ws(len,buff) int len; char *buff; { asm { moveq #MIDIWS,D0 /* write string function # */ movea.l buff(A6),A2 /* pointer to midi buffer */ move.w len(A6),D1 /* lenth of midi buffer */ trap #3 } } MIDI_BUFFER *get_midi_out_rec() { asm { moveq # GET_MIDOUTREC,D0 /* get function number */ trap #3 } /* this will return with data in D0 */ } MIDI_BUFFER *get_midi_in_rec() { asm { moveq # GET_MIDINREC,D0 /* get function number */ trap #3 } /* this will return with data in D0 */ }