/* * * (c) 2004 Laurent Vivier * */ #include #include #include #include #include #include #include "misc.h" #include "head.h" #include "driver.h" #include "config.h" #include "serial.h" static short out_refnum[SERIAL_PORT_NB]; #ifdef USE_CLI static short in_refnum[SERIAL_PORT_NB]; static char buffer; #endif /* * Technical Note TN1119 "Serial Port Apocrypha" * * from http://developer.apple.com/technotes/tn/tn1119.html * * Inside Macintosh, Devices, "Using the Serial Driver" : * * http://developer.apple.com/documentation/mac/Devices/Devices-315.html * */ /* * * ".AOut" Serial port A (modem) output * ".AIn" Serial port A (modem) input * ".BOut" Serial port B (printer) output * ".BIn" Serial port B (printer) input * */ static int setserial(short refNum, unsigned int bitrate, unsigned int datasize, int parity, int stopbits) { CntrlParam param; short seropts; int res; switch(bitrate) { case 150: seropts = baud150; break; case 300: seropts = baud300; break; case 600: seropts = baud600; break; case 1200: seropts = baud1200; break; case 1800: seropts = baud1800; break; case 2400: seropts = baud2400; break; case 3600: seropts = baud3600; break; case 4800: seropts = baud3600; break; case 7200: seropts = baud7200; break; case 9600: seropts = baud9600; break; case 14400: seropts = baud14400; break; case 19200: seropts = baud19200; break; case 28800: seropts = baud28800; break; case 38400: seropts = baud38400; break; case 57600: seropts = baud57600; break; default: seropts = baud9600; break; } switch(datasize) { case 5: seropts |= data5; break; case 6: seropts |= data6; break; case 7: seropts |= data7; break; case 8: seropts |= data8; break; default: seropts |= data8; break; } switch(parity) { case 0: seropts |= noParity; break; case 1: seropts |= oddParity; break; case 2: seropts |= evenParity; break; } switch(stopbits) { case 0: seropts |= stop10; break; case 1: seropts |= stop15; break; case 2: seropts |= stop20; break; } param.csCode = kSERDConfiguration; param.csParam[0] = seropts; param.ioCRefNum = refNum; param.ioVRefNum = 0; param.ioCompletion = 0; res = PBControlSync((ParmBlkPtr)¶m); return res; } int serial_is_available(unsigned int port) { if (port > SERIAL_PORT_NB) return 0; if (out_refnum[port] == -1) return 0; return 1; } void serial_put(unsigned int port, char c) { if (!serial_is_available(port)) return; if ( c == '\n' ) write(out_refnum[port], "\n\r", 2); else write(out_refnum[port], &c, 1); } void serial_init(void) { out_refnum[SERIAL_MODEM_PORT] = -1; in_refnum[SERIAL_MODEM_PORT] = -1; out_refnum[SERIAL_PRINTER_PORT] = -1; in_refnum[SERIAL_PRINTER_PORT] = -1; #ifdef USE_CLI buffer = 0; #endif } void serial_enable(int port, int bitrate, int parity, int datasize, int stopbits) { int res; res = OpenDriver(c2pstring(".AOut"), &out_refnum[port]); if (res != noErr) { printf("Cannot open output port (%d)\n", res); } else { res = setserial(out_refnum[port], bitrate, datasize, parity, stopbits); if (res != noErr) { printf("Cannot setup output port (%d)\n", res); } } #ifdef USE_CLI res = OpenDriver(c2pstring(".AIn"), &in_refnum[port]); if (res != noErr) { printf("Cannot open modem input port (%d)\n", res); } else { res = setserial(in_refnum[port], bitrate, datasize, parity, stopbits); if (res != noErr) { printf("Cannot setup modem input port (%d)\n", res); } } #endif /* USE_CLI */ } #ifdef USE_CLI int serial_getchar(unsigned int port) { int count; char c; if (!serial_is_available(port)) return 0; if (buffer != 0) { c = buffer; buffer = 0; return c; } count = read(in_refnum[port], &c, 1); if (count == 1) return c; return 0; } int serial_keypressed(unsigned int port) { int c; c = serial_getchar(port); if (c != 0) { buffer = c; return 1; } return 0; } #endif