mike@pixar.UUCP (Mike Russell) (10/26/88)
I'm posting the following code in response to recent questions re the ST ACIA registers. This code includes register bit definitions plus a set of functions for managing ACIA interrupts. Mike Russell ucbvax!pixar!mike Trust in Allah, but tie your camel first. ---------------------- include file for Atari ST/Mega ACIA /* aciareg.h - definitions for Atari ST serial communications chip */ #define ACIA_MIDI (aciareg *)0xfffffc04 typedef struct aciareg { char csr; char filler; char data; } aciareg; /* control bits, write only */ #define C_RESET 0x3 /* master reset */ #define C_DIV1 0x0 /* divide clock by 1 */ #define C_DIV16 0x1 /* divide clock by 16, normal for MIDI */ #define C_DIV64 0x2 /* divide clock by 64 */ #define C_7EVEN2 0x00 /* seven bits, even parity, 2 stop bits */ #define C_7ODD2 0x04 /* seven bits, odd parity, 2 stop bits */ #define C_7EVEN1 0x08 /* seven bits, even parity, 1 stop bit */ #define C_7ODD1 0x0c /* seven bits, even parity, 1 stop bit */ #define C_8NONE2 0x10 /* eight bits, no parity, 2 stop bits */ #define C_8NONE1 0x14 /* eight bits, no parity, 1 stop bits */ #define C_8EVEN1 0x18 /* eight bits, even parity, 1 stop bit */ #define C_8ODD1 0x1c /* eight bits, odd parity, 1 stop bit */ #define C_NO_RTS 0x40 /* disable RTS */ #define C_TIENA 0x20 /* enable transmit interrupts */ /* note: CTL_NO_RTS|CTL_TIENA sends a break */ #define C_RIENA 0x80 /* enable reveive interrupts */ #define INIT_MIDI (C_RIENA|C_8NONE1|C_DIV16) /* init MIDI */ #define INIT_KBD (C_RIENA|C_8NONE1|C_DIV64) /* init keyboard */ /* status bits, read only */ #define S_RDATA 0x01 /* received data is present */ #define S_XEMPTY 0x02 /* transmitter is ready */ #define S_NOCARR 0x04 /* no carrier */ #define S_CTS 0x08 /* no clear to send signal */ #define S_FE 0x10 /* framing error */ #define S_OVRN 0x20 /* reveive overrun */ #define S_PE 0x40 /* parity error */ #define S_IRQ 0x80 /* interrupt request */ #define S_ERROR (S_FE|S_OVRN|S_PE) /* a receive error has occurred */ ---------------------- interrupt handler for Atari ST/Mega MIDI #include <osbind.h> #include <aciareg.h> typedef int (func)(); static func *imidiin, *imidiout; /* i/o interrupt handlers */ static func *omidisys; /* original midi vector */ static nullfunc() {} midisys() /* MIDI interrupt handler */ { register aciareg *acia = ACIA_MIDI; char c; static xmitloop; /* transmitter interrupt loop detector */ #define XMITMAX 1000 if(acia->csr&S_RDATA && (c = acia->data) != (char)0xfe { (*imidiin)(c); } if(acia->csr&S_XEMPTY) { if(imidiout) { (*imidiout)(); /* guard against transmitter interrupt loop */ if(acia->csr&S_XEMPTY) { if(++xmitloop>XMITMAX) acia->csr = INIT_MIDI; } else { xmitloop = 0; } } else { acia->csr = INIT_MIDI; } } } func * MidiISubr() { return imidiin; } /* get current input interrupt func */ func * MidiOSubr() { return imidiout; } /* get current output interrupt func */ MidiSys(isubr, osubr) func *isubr; /* MIDI input interrupt handler or zero */ func *osubr; /* MIDI output interrupt handler or zero */ /* ** Set up the MIDI ACIA to call C function isubr for input interrupts ** and osubr() for output interrupts. May be called while MIDI is ** active (but be ready for lost characters). Call with both functions ** set to zero to reset the first existing MIDI vector. */ { register aciareg *acia = ACIA_MIDI; register kbdvecs *kv = Kbdvbase(); long osp; imidiin = isubr?isubr:nullfunc; imidiout = osubr?osubr:nullfunc; if(isubr || osubr) { if(!omidisys) omidisys = kv->midisys; /* save the original vector */ kv->midisys = midisys; /* replace it with our own */ } else { if(omidisys) kv->midisys = omidisys; /* restore the original vector */ } osp = Super(0L); /* if output function specified, enable transmit interrupts */ if(osubr) acia->csr = INIT_MIDI|C_TIENA; else acia->csr = INIT_MIDI; Super(osp); } #ifdef MAIN #include <stdio.h> int booby; ifunc() { booby++; } main() { int obooby = 0; setbuf(stdout, NULL); MidiSys(ifunc, 0L); while(booby < 30) { if(obooby != booby) printf("%d\n", obooby = booby); } MidiSys(0L, 0L); } #endif MAIN -- Mike Russell ucbvax!pixar!mike Trust in Allah, but tie your camel first.