head 1.2; branch ; access ; symbols ; locks ; comment @@; 1.2 date 89.07.06.19.47.47; author pkern; state Exp; branches ; next 1.1; 1.1 date 89.02.03.13.35.43; author pkern; state Exp; branches ; next ; desc @@ 1.2 log @turboc 2.0 syntax fixes hang_up() added. @ text @/* * ports.pc * IBM PC serial port handling routines * (translated and adapted from Qkermit's Turbo Pascal code) */ static char rcsid[] = "$Header: ports.pc,v 1.1 89/02/03 13:35:43 pkern Exp $"; #include #include "cterm.h" #include "pc.h" extern int nbaud, n_port; extern uchar flowctl, bpc, stopbits, parity, m_prty, xoff; #ifdef LOCAL extern uchar local; #endif #ifdef ECHO extern uchar echo; #endif /* speed strings used in setups() */ char *bauds[EXTB+1] = { " 45.5", " 50", " 75", " 110", "134.5", " 150", " 200", " 300", " 600", " 1200", " 1800", " 2000", " 2400", " 3600", " 4800", " 7200", " 9600", "19200", "38400" }; /* INS8250A clock divisor table */ static int bdivs[EXTB+1] = { 0x09E4, 0x0900, 0x0600, 0x0417, 0x0359, 0x0300, 0x0240, 0x0180, 0x00C0, 0x0060, 0x0040, 0x003A, 0x0030, 0x0020, 0x0018, 0x0010, 0x000c, 0x0006, 0x0003 }; static unsigned int spdtab[] = { 45, B0, 46, B0, 50, B50, 75, B75, 110, B110, 134, B134, 135, B134, 150, B150, 200, B200, 300, B300, 600, B600, 1200, B1200, 1800, B1800, 2000, B2000, 2400, B2400, 3600, B3600, 4800, B4800, 7200, B7200, 9600, B9600, 19200, EXTA, 38400, EXTB, 0, B9600 }; static int speed(n) int n; { int i; for (i=0; spdtab[i]; i+=2) if (spdtab[i+1] == n) return(spdtab[i]); return(9600); } /* return index for speed n */ prtspd(n) unsigned int n; { int i; for (i=0; spdtab[i]; i+=2) if (spdtab[i] == n) return(spdtab[i+1]); return(nbaud); } #define Baudrate speed(nbaud) #define PrimaryPort (n_port==0) #define Parity ((parity << 1) | m_prty) #define delay(a) dsleep(a) #define Sound(a) honk(a, 64) #define BUFMAX 256 #define BUFC(a,b) ((a bufovfl) { xmit_chr(XOFF); flxoff=1; } } /* ---------------------------------------------------------------- */ /* init_prt - Initialize the modem and setup interrupt procedure. */ /* ---------------------------------------------------------------- */ init_prt() { int set_prt(); extern unsigned int sysconfig; if (n_port < 0) /* first time through */ /* pick a port number(n_port) based on sysconfig */ n_port = ((sysconfig >> 9) & 7)-1; Iin = 0; Iout = 0; IntVector = (PrimaryPort) ? 0x0030 : 0x002C; /* Initialize the Interrupt Procedure */ o_portisr = getvect(IntVector/4); setvect(IntVector/4, port_isr); set_prt(); } /* ---------------------------------------------------------------- */ /* reset_prt - Reset the Interrupt back to the original. */ /* ---------------------------------------------------------------- */ reset_prt() { setvect(IntVector/4, o_portisr); } /* ---------------------------------------------------------------- */ /* set_prt - Set the baud rate and parity for modem. */ /* Global variables - Modem,Clockrate,Baudrate,Parity */ /* ---------------------------------------------------------------- */ set_prt() { uchar lctl; unsigned int rate; if (PrimaryPort) { Modem = 0x3F8; EnableMask = 0xEF; ResetMask = 0x64; /* end of interrupt for IRQ4 */ } else { Modem = 0x2F8; EnableMask = 0xF7; ResetMask = 0x63; /* end of interrupt for IRQ3 */ } /* Enable serial port interrupt */ outportb(0x21, (inportb(0x21) & EnableMask)); outportb(0x20, ResetMask); /* DTR and RTS */ outportb(Modem+ModemControlReg, 0x0B); /* Data Avail. Interrupt set */ outportb(Modem+InterruptEnable, 0x01); /* Initialize baud rates and bits and parity */ rate = bdivs[nbaud]; lctl = (parity<<4) | (m_prty<<3) | (stopbits<<2) | (bpc+2); /* Enable baud rate setting */ outportb(Modem+LineControlReg, 0x80); outportb(Modem+LowOrderDiv, rate & 0x00FF); outportb(Modem+HiOrderDiv, rate >> 8); /* parity, stopbits, bits per char */ outportb(Modem+LineControlReg, lctl); } /* ---------------------------------------------------------------- */ /* dial - Check and waits for modem to be connected. */ /* It waits for DTR and CTS signals to be detected. */ /* side effect - global variable 'connected' is set true. */ /* ---------------------------------------------------------------- */ #ifdef notdef dial() { while ((inportb(Modem+ModemStatusReg) & 0x30) != 0x30) { #ifdef AUDIO if (audioFlag) { Sound(600); delay(100); Sound(2000); delay(200); nosound(); } #endif puts(" Please connect your modem "); delay (1000); if (kbhit() && getch() == 0x20) break; } connected = 1; #ifdef AUDIO if (audioFlag) { for (i=1;i<=50;i++) { sound(100*i); delay(5); } nosound(); } #endif puts(" Connection completed "); } #endif /* ---------------------------------------------------------------- */ /* recv_chr - Receive a Character from the modem port. */ /* -1 - if no character found . */ /* char - if there is a character from the modem */ /* ---------------------------------------------------------------- */ recv_chr() { int mchar; if (flxoff && !xoff && BUFC(Iin,Iout) < bufmpty) { xmit_chr(XON); flxoff=0; } mchar = -1; if (BUFC(Iin, Iout) > 0) { /* get char from buffer */ mchar = buffer[Iout++] & 0x7F; Iout %= MaxBuffsize; } return (mchar); } recv_byt() { int mchar; if (flxoff && !xoff && BUFC(Iin,Iout) < bufmpty) { xmit_chr(XON); flxoff=0; } mchar = -1; if (BUFC(Iin, Iout) > 0) { /* get char from buffer */ mchar = buffer[Iout++]; Iout %= MaxBuffsize; } return (mchar); } /* ---------------------------------------------------------------- */ /* xmit_chr - Send a character thru the modem port. */ /* Wait for the character to be sent. */ /* ---------------------------------------------------------------- */ xmit_chr(c) uchar c; { outportb(Modem, c); while ((inportb(Modem+LineStatusReg) & 0x40) != 0x40) delay(1); } xmit_lcl(c) uchar c; { buffer[Iin++] = c; Iin %= MaxBuffsize; } xmit_eko(c) uchar c; { xmit_lcl(c); xmit_chr(c); } /* ---------------------------------------------------------------- */ /* send_brk - Send a break via the modem port . */ /* ---------------------------------------------------------------- */ send_brk() { uchar Tbyte; /* save setting */ Tbyte = inportb(Modem+LineControlReg); /* break for 200 millsec */ outportb(Modem+LineControlReg, 0x40); delay(200); /* restore setting */ outportb(Modem+LineControlReg, Tbyte); } /* ================================================================= */ /* End of MODEM routines for IBMPC compatibles. */ /* ================================================================= */ /* end of Qkermit translation */ #ifndef ECHO /* put char into incoming data buffer (ie. simulate echo) */ loop_chr(c) int c; { disable(); buffer[Iin++] = c; Iin %= MaxBuffsize; enable(); } #endif /* * trns_chr: same as recv_chr but translate control chars */ trns_chr() { int mchar; if (flxoff && !xoff && BUFC(Iin,Iout) < bufmpty) { xmit_chr(XON); flxoff=0; } mchar = -1; if (BUFC(Iin,Iout) > 0) { /* get char from buffer */ mchar = buffer[Iout++] & 0x7F; if (mchar & 0x60) Iout %= MaxBuffsize; else { buffer[--Iout] = mchar | '@@'; mchar = '^'; } } return(mchar); } /* * hang_up: drop the comm port connection */ hang_up() { /* drop DTR and RTS */ outportb(Modem+ModemControlReg, 0x08); /* break for 200 millisecs */ delay(200); /* restore DTR and RTS */ outportb(Modem+ModemControlReg, 0x0B); } @ 1.1 log @Initial revision @ text @d6 1 a6 1 static char rcsid[] = "$Header$"; d30 1 a30 1 /* NS16450 clock divisor table */ d130 2 a131 2 buffer[Iin] = inportb(Modem); ++Iin %= MaxBuffsize; d147 1 d149 4 d258 2 a259 2 mchar = buffer[Iout] & 0x7F; ++Iout %= MaxBuffsize; d273 2 a274 2 mchar = buffer[Iout]; ++Iout %= MaxBuffsize; d295 2 a296 2 buffer[Iin] = c; ++Iin %= MaxBuffsize; a310 1 #ifdef notdef a319 8 #else /* drop DTR and RTS */ outportb(Modem+ModemControlReg, 0x08); /* break for 200 millisecs */ delay(200); /* restore DTR and RTS */ outportb(Modem+ModemControlReg, 0x0B); #endif d333 2 a334 2 buffer[Iin] = c; ++Iin %= MaxBuffsize; d351 1 a351 1 mchar = buffer[Iout] & 0x7F; d353 1 a353 1 ++Iout %= MaxBuffsize; d355 1 a355 1 buffer[Iout] = mchar | '@@'; d360 13 @