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.