/* Special Raw console I/O for BDSC Steve Ward 1/81 * * Provides a reasonably flexible, device-independent interface: * * ch = getchar() Read a character * * putchar(ch) write a character * * kbhit() true iff input character waiting * * old = TTYMode(m) Sets tty mode bits to m, returning old * value. Mode bits: * 1 Echo mode: chars echoed as read. * 2 Quit: ^C causes an exit. * 4 Flow: ^S, ^Q flow control. * 8 Strip: input characters stripped to 7 bits. * 16 Expand: expand \n, \t on output. * * Hence for REALLY raw I/O, do TTYMode(0). * * NOTE: Program using CIO.C are NOT PORTABLE to systems lacking a C compiler! * If you really must use CIO, then compile this once (to get CIO.CRL) * and link your programs by saying: * * A>clink main DEFF CIO * */ #include "bdscio.h" /* Make sure BDSCIO.H has been customized for your system! */ /* Device-specific definitions... Input status flag: */ #define ISTAT ((CIMASK & inp(CSTAT)) == (CAHI ? CIMASK : 0)) /* character output status: */ #define OSTAT ((COMASK & inp(CSTAT)) == (CAHI ? COMASK : 0)) /* Internal static definitions. */ #define Freeze (static[1]) /* true if output frozen (^S) */ #define Pending (static[2]) /* true if input char waiting */ #define PendCh (static[3]) /* the pending input char */ #define Mode (static[4]) /* input mode bits: */ #define M_echo 1 /* echo mode bit */ #define M_quit 2 /* ^C (quit) mode bit */ #define M_flow 4 /* ^S/^Q flow control */ #define M_strip 8 /* strip to 7-bits */ #define M_expan 16 /* Expand \n on output. */ #define QuitC (static[5]) putchar(c) { rawio(1, c); } getchar() { return rawio(2); } kbhit() { return rawio(3); } TTYMode(mode) { return rawio(4, mode); } /* set mode bits, returns prev. */ rawio(key, arg) { char ch, *static, mode; static = "Nonsense!"; if (*static == 'N') /* Initialization ... */ { *static = Freeze = Pending = 0; Mode = M_echo | M_quit | M_flow | M_strip | M_expan; QuitC = 3; } Again: if (ISTAT) /* check for input pending. */ { ch = inp(CDATA); if ((mode=Mode) & M_strip) ch &= 0x7F; if ((mode & M_quit) && (ch == QuitC)) exit(); else if (mode & M_flow) { if (ch == ('S'-64)) { Freeze=1; goto brk; } if (ch == ('Q'-64)) { Freeze=0; goto brk; }} if (!Pending) { Pending = 1; PendCh = ch; if (mode & M_echo) outp(CDATA, ch); }} brk: switch(key) { case 0: return; case 1: if (Freeze || !OSTAT) goto Again; /* putchar(arg) */ outp(CDATA, arg); if ((arg == '\n') && (Mode & M_expan)) putchar('\r'); return arg; case 2: if (!Pending) goto Again; Pending = 0; return PendCh; case 3: return Pending; case 4: mode = Mode; Mode = arg; if (!(arg & M_flow)) Freeze = 0; return mode; default: return; } }  .