#include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define EOS '\O' #define CONTROL(x) (x-0x40) #define EXIT_KEY CONTROL(']') #define CTRL_B CONTROL('B') #define CTRL_W CONTROL('W') #define CTRL_E CONTROL('E') #define ESC_KEY CONTROL('[') #define CTRL_Y CONTROL('Y') #define _COM_INIT 0 #define _COM_CHR8 0x03 #define _COM_STOP1 0x00 #define _COM_NOPARITY 0x00 #define _COM_1200 0x80 #define _COM_2400 0XA0 #define COM_PARAMS (_COM_CHR8 | _COM_STOP1 | _COM_NOPARITY |_COM_1200) #define RXQSIZE 8192 #define TXQSIZE 8192 #define P8259_0 0x20 #define P8259_1 0x21 #define END_OF_INT 0x20 #define XON_ASCII (0x11) #define XOFF_ASCII (0x13) #define BIOS_DATA ((int far *)(0x400000L)) #define IER (comport + 1) #define IIR (comport + 2) #define LCR (comport + 3) #define MCR (comport + 4) #define LSR (comport + 5) #define MSR (comport + 6) #define RDAINT 1 #define THREINT 2 #define RLSINT 4 #define MSINT 8 #define MCRALL 15 #define MCROFF 0 #define IERALL (RDAINT+THREINT+RLSINT+MSINT) #define IEROFF 0 #define THREOFF 0xfd #define MDMSTATUS 0 #define TXREGEMPTY 2 #define RXDATAREADY 4 #define RLINESTATUS 6 #define XON_RCVD 1 #define XOFF_RCVD 0 #define XON_SENT 1 #define XOFF_SENT 0 #define HI_TRIGGER(x) (3*x/4) #define LO_TRIGGER(x) (x/4) #define bit0(i) (i & 0x0001) #define turnon_int(i,j) \ if(((j=inp(IER))&i)==0)outp(IER,(j|i)) #define report_error(s) printf(s) typedef struct QTYPE { int count; int front; int rear; int maxsize; char *data; } QTYPE; static char rxbuf[RXQSIZE], txbuf[TXQSIZE]; static QTYPE rcvq = {0, -1, -1, RXQSIZE, rxbuf}, trmq = {0, -1, -1, TXQSIZE, txbuf}; int s_linestatus, s_modemstatus; static QTYPE *txq = &trmq, *rxq = &rcvq; static short comport=0, enable_xonxoff = 1, rcvd_xonxoff = XON_RCVD, sent_xonxoff = XON_SENT, send_xon = FALSE, send_xoff = FALSE, int_number = 12, int_enable_mask = 0xef, int_disable_mask = 0x10; int s_sendchar(int); int s_rcvchar(void); int s_setup(short,unsigned); int s_cleanup(void); char *q_getfrom( QTYPE *, char *); int q_puton( QTYPE *, char *); void interrupt far s_inthndlr(void); void print_menu(); void chat(); void dial(); void hangup(); void dtr(int i); void pr1(char *s); void wait(long l); void dosshell1(); void zmodemr(int port_number); int cdet(); static void s_rda(void); static void s_trmty(void); static void (interrupt far *old_handler)(); main(int argc, char **argv) { int ch, port_number = 0,stat; if (argc>1) port_number=atoi(argv[1]) -1; printf("\nCFHTerm : Serial I/O at 1200N81 using port COM%d\n", port_number+1); printf("\nConnecting...\n"); print_menu(); if (port_number==0) s_setup(port_number, (_COM_CHR8 | _COM_STOP1 | _COM_NOPARITY |_COM_1200)); if (port_number==1) s_setup(port_number, (_COM_CHR8 | _COM_STOP1 | _COM_NOPARITY |_COM_2400)); pr1("ATE0V1Q0M1X4{"); wait(20); dtr(0); while (TRUE) { if ((ch = s_rcvchar()) != -1) putchar(ch); if (kbhit() != 0) { ch=getch(); switch (ch) { case EXIT_KEY: s_cleanup(); return; case CTRL_B: dial(); break; case CTRL_W: chat(); break; case CTRL_E: hangup(); break; case ESC_KEY: dosshell1(); break; case CTRL_Y: zmodemr(port_number); break; default: s_sendchar(ch); } } } } long timer1() /* This function returns the time, in seconds since midnight. */ { unsigned short h,m; long l; m=peek(0x0040,0x006c); h=peek(0x0040,0x006e); l=((long)h)*65536 + ((long)m); return(l); } void wait(long l) { long l1; l1 = timer1()+l; enable(); while (timer1() 0; i++) if (s[i] == '{') { s_sendchar(13); return; } else s_sendchar(s[i]); } void interrupt far s_inthndlr(void) { register int int_id, intmask; enable(); while (TRUE) { int_id = inp(IIR); if (bit0(int_id) == 1) { outp(P8259_0, END_OF_INT); return; } if (int_id >=RXDATAREADY) turnon_int(THREINT, intmask); switch (int_id) { case MDMSTATUS: s_modemstatus = inp(MSR); break; case TXREGEMPTY: s_trmty(); break; case RXDATAREADY: s_rda(); break; case RLINESTATUS: s_linestatus = inp(LSR); break; } } } static void s_rda(void) { register int intmask; char c; c=inp(comport); if(enable_xonxoff){ if(c == XON_ASCII){ rcvd_xonxoff=XON_RCVD; turnon_int(THREINT, intmask); return; } if (c==XOFF_ASCII){ rcvd_xonxoff = XOFF_RCVD; intmask=inp(IER); if (intmask & THREINT) outp(IER, intmask & THREOFF); return; } } q_puton(rxq, &c); if(enable_xonxoff){ if(rxq->count >=HI_TRIGGER(RXQSIZE) && sent_xonxoff != XOFF_SENT) { send_xoff=TRUE; turnon_int(THREINT,intmask); } } } static void s_trmty(void) { char c; register int ierval; if (send_xoff == TRUE){ outp(comport, XOFF_ASCII); send_xoff = FALSE; sent_xonxoff = XOFF_SENT; return; } if (send_xon==TRUE){ outp(comport, XON_ASCII); send_xon = FALSE; sent_xonxoff=XON_SENT; return; } if(q_getfrom(txq, &c) != NULL){ outp(comport,c); return; } ierval = inp(IER); if (ierval & THREINT) outp(IER, ierval &THREOFF); } int s_setup(short port_number, unsigned commparams) { int intmask; if (port_number <0 || port_number >1) report_error("\nInvalid port number!\n"); if (port_number==0) comport = 0x03f8; if (port_number==1) comport = 0x02f8; if (comport == 0) { report_error("\nBIOS could not find port!\n"); return(0); } if(port_number==0) { int_enable_mask=0xef; int_disable_mask=0x10; int_number = 12; } if(port_number==1) { int_enable_mask=0xf7; int_disable_mask=8; int_number=11; } old_handler=getvect(int_number); disable(); setvect(int_number, s_inthndlr); enable(); bioscom(_COM_INIT, commparams, port_number); rcvd_xonxoff = XON_RCVD; if(sent_xonxoff == XOFF_SENT) send_xon=TRUE; else send_xon=FALSE; send_xoff=FALSE; disable(); outp(MCR, MCRALL); outp(IER,IERALL); intmask=inp(P8259_1) & int_enable_mask; outp(P8259_1,intmask); enable(); return(1); } int s_cleanup(void) { int intmask; disable(); outp(MCR,IEROFF); outp(MCR,MCROFF); intmask=inp(P8259_1) | int_disable_mask; outp(P8259_1, intmask); setvect(int_number, old_handler); enable(); return; } int s_sendchar(int ch) { int retval, intmask; disable(); retval= q_puton(txq, (char *)&ch); enable(); if (rcvd_xonxoff != XOFF_RCVD) turnon_int(THREINT, intmask); return(retval); } s_rcvchar(void) { int ch, intmask; if(enable_xonxoff) { if(rxq->count <=LO_TRIGGER(RXQSIZE) && sent_xonxoff !=XON_SENT) { send_xon=TRUE; turnon_int(THREINT,intmask); } } disable(); if(q_getfrom(rxq, (char *)&ch) == NULL) { enable(); return(-1); } else { enable(); return(ch); } } char *q_getfrom(QTYPE *queue, char *data) { char *current; current=NULL; if(queue->front == -1) return(current); current = &(queue->data[queue->front]); *data=*current; queue->count--; if (queue->count == 0) { queue->front = queue->rear = -1; return(current); } if(queue->front == queue->maxsize-1) queue->front=0; else queue->front++; return(current); } int q_puton(QTYPE *queue, char *data) { if(queue->count == queue->maxsize) return(0); if(queue->rear == queue->maxsize-1) queue->rear=0; else queue->rear++; queue->data[queue->rear]=*data; queue->count++; if(queue->front == -1) queue->front=0; return(1); }