/* * modem i/o for dos. This assumes you're gonna have a fossil driver * (from FIDO) of some sort or another and it will fail if it can't * find one */ #include #include #include #include #include "ttyio.h" extern int Debug; /* statics for conversing with the local fossil driver */ static int comport; static union REGS regs; #define FOSSIL 0x14 #define FOSSIL_FLAG 0x1954 #define TSPEED 0x00 #define TWRITE 0x01 #define TREAD 0x02 #define TSTAT 0x03 #define TOPEN 0x04 #define TCLOSE 0x05 #define TDTR 0x06 #define TFLUSH 0x0a #define TFLOW 0x0f #define TBREAK 0x1a /* variables used to track carrier and make sure we don't spend too * much time checking for it */ static time_t _cd_stale; /* when we need to check cd again */ static char _cd_checked; /* has cd been checked? */ static char _cd_state=0; /* what's cd now? */ /* * ttyopen() attaches ourself to a modem port */ int ttyopen(dev, flow) char *dev; int flow; { _cd_checked = 0; comport = dev[strlen(dev)-1]-'1'; /* perform fossil init */ regs.h.ah = TOPEN; regs.x.bx = 0; regs.x.cx = 0; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); if (regs.x.ax == FOSSIL_FLAG) { /* we can either do rts/cts flow control or none at * all */ if (flow == TTYF_RTSCTS) { regs.h.ah = TFLOW; regs.h.al = 0xf2; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); } return 1; } return 0; } /* ttyopen() */ /* * ttyclose() detaches ourself from a modem port and restores it to * the state it was in before we started hacking on it */ void ttyclose() { disable(); regs.h.ah = TCLOSE; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); } /* ttyclose() */ /* * ttystat() tells us if there are characters waiting on input */ int ttystat() { regs.h.ah = TSTAT; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); _cd_stale = clock() + (long)CLK_TCK; _cd_state = (regs.h.al & 0x80); _cd_checked = 1; return (regs.h.ah & 0x01); } /* ttystat */ /* * dobreak() set or clear a break condition */ void dobreak(setit) int setit; { regs.h.ah = TBREAK; regs.x.dx = comport; regs.h.al = setit ? 1 : 0; int86(FOSSIL, ®s, ®s); } /* dobreak */ /* * ttyspeed() set tty speed */ int ttyspeed(speed) long speed; { static unsigned long values[] = { 38400L, 0043, 19200L, 0003, 9600L, 0343, 4800L, 0303, 2400L, 0243, 1200L, 0203, 600L, 0143, 300L, 0103, 0 }; register i; for (i=0; values[i] != 0; i+=2) if (values[i] == speed) { regs.h.ah = TSPEED; regs.x.dx = comport; regs.h.al = (int)values[i+1]; int86(FOSSIL, ®s, ®s); return 1; } return 0; } /* * carrier() - detects carrier */ int carrier() { register time_t now = clock(); if (_cd_checked == 0 || now > _cd_stale) { regs.h.ah = TSTAT; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); _cd_stale = clock()+(long)CLK_TCK; _cd_state = (regs.h.al & 0x80); _cd_checked = 1; } return _cd_state; } /* carrier */ /* * disable the modem */ void disable() { regs.h.ah = TDTR; regs.h.al = 0; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); } /* disable */ /* * enable the modem */ void enable() { regs.h.ah = TDTR; regs.h.al = 1; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); } /* enable */ /* * flush() the modem input buffer */ void flush() { regs.h.ah = TFLUSH; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); } /* flush */ /* * receive() a character from the modem, timing out after a while */ int receive(timeout) int timeout; { time_t end; end = clock() + ((long)timeout*(long)CLK_TCK); while (clock() < end) if (ttystat()) return ttyin(); return -1; } /* receive */ /* * ttyin() gets a character from the modem */ int ttyin() { regs.h.ah = TREAD; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); return 0xff & (regs.h.al); } /* ttyin */ /* * slowputs() writes a string to modem s*l*o*w*l*y */ void slowputs(s) register char *s; { register long delay; while (*s) { if (*s & 0200) { /* anything > 127 causes delay */ delay = (0xff & *++s); nap(delay * 100L); if (Debug > 1) fprintf(stderr, "{%ld}", delay); } else { if (Debug > 1) putc((*s == '\r') ? '\n' : (*s), stderr); nap(80L); ttyout(*s); } ++s; } } /* slowputs */ /* * ttyout() writes a single character to the modem */ void ttyout(c) char c; { regs.h.ah = TWRITE; regs.h.al = c; regs.x.dx = comport; int86(FOSSIL, ®s, ®s); _cd_checked = 1; _cd_stale = clock() + (long)CLK_TCK; _cd_state = (regs.h.al & 0x80); } /* ttyout */ /* * ttywrite() writes a string to the modem as fast as possible */ void ttywrite(bfr, size) register char *bfr; register size; { while (size-- > 0) ttyout(*bfr++); } /* ttywrite */