home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* Copyright 1989, Doug Boone FidoNet 119/5 */
- /* Copyright 1989, John Valentyn FidoNet 114/18 */
- /* */
- /* (916) 893-9019 Data */
- /* (916) 891-0748 voice */
- /* P.O. Box 5108, Chico, CA. 95928 */
- /* */
- /* Originally by John Vallentyn (FidoNet 114/15), so you'll need his */
- /* permission too. */
- /* */
- /* This program is not for sale. It is for the free use with Opus systems. */
- /* You may not sell it in ANY way. If you have an access charge to your */
- /* Bulletin Board, consider this to be like Opus, you can ONLY make it */
- /* available for download in an open area, where non-members can get access */
- /* */
- /* If you need to modify this source code, please send me a copy of the */
- /* changes you've made so that everyone can share in the updates. */
- /* */
- /* "Don't rip me off!" -- Tom Jennings, FidoNet's founder */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include <dos.h>
- #include <conio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #ifdef TURBOC
- #include <alloc.h>
- #include <sys\timeb.h>
- #else
- #include <malloc.h>
- #endif
- #include "archdr.h"
-
- extern int baud;
- extern int port;
- extern int flags;
- extern int line;
- extern int screen;
- extern int ctrl_err;
- extern long quit_time;
-
- extern int (cdecl * cdecl sdisplay)(char *); /* ptr to display function */
- extern int (cdecl * cdecl get_a_char)(void); /* instead of getch() */
- extern int (cdecl * cdecl chk_keyboard)(void); /* instead of kbhit() */
-
- int GetDriverInfo(void);
- int CkFossilCD(void);
- int Com_(unsigned,unsigned);
- int Comm_Set_Baud(int,int,int,int);
- void Comm_transmit(int);
- int Comm_Receive(void);
- int Get_Comm_Status(void);
- int Comm_Char_Avail(void);
- int Comm_Init(int,int,int,int);
- void Comm_De_Init(void);
- void Comm_Dtr(int);
- void Comm_flush_out(void);
- void Comm_Purge_out(void);
- void Comm_Purge_in(void);
- void Comm_Watch(int);
- char Comm_Peek(void);
- int Comm_CD(void);
- int locputs(register char *);
- int fosputs(register char *);
- int play(const char *,...);
- void sendbyte(byte);
- void ask_more(void);
-
- extern void terminate(int);
-
- struct fos_info { /* info avail via 0x1B function */
- int info_size; /* Offset 0 (word) = Structure size */
- char fos_spec; /* 2 (byte) = FOSSIL spec version */
- char drvr_rev; /* 3 (byte) = Driver rev level */
- char far *fos_id; /* 4 (dwrd) = Pointer to ASCII ID */
- int ibuf_sz; /* 8 (word) = Input buffer size */
- int ibuf_free; /* 0A (word) = Bytes avail (input) */
- int obuf_sz; /* 0C (word) = Output buffer size */
- int obuf_free; /* 0E (word) = Bytes avail (output) */
- char scrn_width; /* 10 (byte) = Screen width, chars */
- char scrn_height; /* 11 (byte) = Screen height, chars */
- char baud_msk; /* 12 (byte) = Baud rate mask */
- } fossil_info =
- { 0, 0, 0, 0L, 0, 0, 0, 0, 0, 0, 0 };
-
-
- /* ====================================================================
- * Fill in the fossil information block
- * ====================================================================
- */
- int GetDriverInfo(void)
- {
- union REGS regs;
- struct SREGS segregs;
- int result;
- char far *p;
-
- p = (char far *) &fossil_info;
- regs.h.al = 0;
- regs.h.ah = 0x1B; /* function = get driver info */
- regs.x.cx = sizeof(struct fos_info);
- regs.x.di = FP_OFF (p);
- segregs.es = segregs.ds = FP_SEG (p);
- regs.x.dx = port;
- result=int86x(FOSSIL_INT, ®s, ®s, &segregs);
- return(result);
- }
-
- /* ====================================================================
- * CkFossilCD() -- Check if Fossil initiallized and CD on
- * ====================================================================
- */
- int CkFossilCD(void)
- {
- union REGS regs;
- long far *INTword;
- int far *IDword;
-
- INTword = (long far *) 0x50; /* get interrupt pointer for INT 14h function */
- IDword = (int far *) *INTword+3; /* point to sig word 1954 and add offset */
- if(*IDword != 0x1954) { /* if FOSSIL not installed */
- printf("FOSSIL not installed...\n");
- return(FALSE);
- }
- regs.h.al = 0;
- regs.h.ah = 0x04; /* function = initialize driver */
- regs.x.dx = port;
- regs.x.bx = 0; /* no ^C */
- int86(FOSSIL_INT, ®s, ®s);
- if(regs.x.ax != 0x1954)
- return(FALSE); /* unable to initialize fossil */
- if (flags & FOSSIL) {
- Comm_Dtr(1); /* insure that DTR is on */
- return(Get_Comm_Status() & DCD); /* return DCD */
- }
- else
- return(TRUE);
- }
-
- /* ====================================================================
- * General purpose comm function
- * ====================================================================
- */
- int Com_(unsigned funct,unsigned chr)
- {
- union REGS regs;
- int result;
-
- regs.h.al = (byte)chr;
- regs.h.ah = (byte)funct;
- regs.x.dx = port;
- result=int86(FOSSIL_INT, ®s, ®s);
- return(result);
- }
-
- /* ====================================================================
- * fossil function 0 = Set baud rate
- * ====================================================================
- */
- int Comm_Set_Baud(int BaudRate,
- int DataBits,
- int StopBits,
- int Parity)
- {
- union REGS regs;
- register int value;
-
- switch(BaudRate/300) {
- case 1: value = 0x40; break;
- case 2: value = 0x60; break;
- case 4: value = 0x80; break;
- case 8: value = 0xA0; break;
- case 16: value = 0xC0; break;
- case 32: value = 0xE0; break;
- case 64: value = 0; break;
- default: return(FALSE);
- }
- switch (Parity) {
- case 0: break;
- case 1: value |= 0x8; break;
- case 2: value |= 0xA; break;
- default: return(FALSE);
- }
- switch(StopBits-1) {
- case 0: break;
- case 1: value |= 0x4; break;
- default: return(FALSE);
- }
- switch (DataBits-7) {
- case 0: value |= 0x2; break;
- case 1: value |= 0x3; break;
- default: return(FALSE);
- }
- regs.h.ah = 0x00;
- regs.h.al = (byte)value;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return(TRUE);
- }
-
- /* ====================================================================
- * fossil function 1 - transmit character with wait
- * ====================================================================
- */
- void Comm_transmit(int chr)
- {
- union REGS regs;
-
- regs.h.ah = 0x01;
- regs.h.al = (byte)chr;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * fossil function 2 - receive character with wait
- * ====================================================================
- */
- int Comm_Receive(void)
- {
- union REGS regs;
-
- do { /* Watch carrier while waiting for next charatcher */
- if (Comm_CD() == FALSE)
- terminate(3);
- if (kbhit()) /* Allows local keyboard over-ride */
- return(getch());
- } while (Comm_Peek() == 0xff);
-
- regs.h.ah = 0x02;
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- regs.h.ah = 0x00;
- return(regs.x.ax);
- }
-
- /* ====================================================================
- * get status of comm port
- * ====================================================================
- */
- int Get_Comm_Status(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x03; /* function = request status */
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
-
- if (!(regs.x.ax & DCD) && flags & FOSSIL)
- terminate(3);
-
- if (regs.x.ax == 0xffff) /* Hangs sometimes clear buffer */
- Comm_Purge_out();
-
- return(regs.x.ax);
- }
-
- /* ====================================================================
- * check if character available in input buffer
- * ====================================================================
- */
- int Comm_Char_Avail(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x03; /* function = request status */
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- regs.x.ax = regs.x.ax & 0x0100; /* check input data avail, ah bit 0 */
- if (regs.x.ax == 0)
- return(FALSE);
- return(TRUE);
- }
-
- /* ====================================================================
- * function 4 - initialize driver
- * ==================================================================== */
- int Comm_Init(int BaudRate,
- int DataBits,
- int StopBits,
- int Parity)
- {
- union REGS regs;
-
- regs.h.ah = 0x04;
- regs.h.al = (byte)(BaudRate | DataBits | StopBits | Parity);
- regs.x.dx = port;
- regs.x.bx = 0; /* no ^C code */
- int86(FOSSIL_INT, ®s, ®s);
- return(regs.x.ax);
- }
-
- /* ====================================================================
- * function 5 - deinitialize driver
- * ====================================================================
- */
- void Comm_De_Init(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x05;
- regs.h.al = 0;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * function 6 - Raise/Lower DTR
- * ====================================================================
- */
- void Comm_Dtr(int flag)
- {
- union REGS regs;
-
- regs.h.ah = 0x06;
- regs.h.al = (byte)flag; /* 01h=Raise 00h=Lower */
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * function 8 - flush output buffer
- * ====================================================================
- */
- void Comm_flush_out(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x08;
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * function 9 - purge output buffer
- * ====================================================================
- */
- void Comm_Purge_out(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x09;
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * function 10 (0Ah) - purge input buffer
- * ====================================================================
- */
- void Comm_Purge_in(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x0A;
- regs.h.al = 0x00;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
-
- /* ====================================================================
- * function 14 - Watchdog On/Off
- * ====================================================================
- */
- void Comm_Watch(int flag)
- {
- union REGS regs;
-
- regs.h.ah = 0x14;
- regs.h.al = (byte)flag; /* 01h=Watchdog on 00h=Watchdog off */
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s, ®s);
- return;
- }
- /*--------------------------------------------------------------------------*/
- /* Look ahead at input buffer, primarily to check for ^C */
- /*--------------------------------------------------------------------------*/
- char Comm_Peek(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x0C;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s,®s);
- return(regs.h.al);
- }
-
- /* ====================================================================
- * Check for carrier detect returns TRUE (1) while carrier is high
- * ====================================================================
- */
- int Comm_CD(void)
- {
- union REGS regs;
-
- regs.h.ah = 0x03;
- regs.x.dx = port;
- int86(FOSSIL_INT, ®s,®s);
- if (regs.h.al & DCD)
- return(TRUE);
- else
- return(FALSE);
- }
-
-
- /* ====================================================================
- * Local display function - access via display()
- * ====================================================================
- */
- int locputs(register char *str)
- {
- register int c;
-
- while (*str && ctrl_err) {
- c = *str++;
- putchar(c);
- if (c == '\n')
- line++;
- if (line > (screen-2) && flags & MORE)
- ask_more();
- }
- return(0);
- }
-
- /* ====================================================================
- * Fossil display function - access via display()
- * ====================================================================
- */
- int fosputs(register char *str)
- {
- register int c;
-
- while (*str && ctrl_err) {
- c = *str++;
- putchar(c); /* So what's going on will display locally!! */
- if(c == '\n') {
- Comm_transmit('\r');
- line++;
- if (Comm_Peek() == 0x13) {
- Comm_Purge_in();
- while (Comm_Peek() == 0xff);
- Comm_Purge_in();
- }
- else if (Comm_Peek() == 0x03) {
- Comm_Purge_in();
- Comm_Purge_out();
- ctrl_err = 0;
- }
- }
- Comm_transmit(c);
- if (line > (screen-2) && flags & MORE)
- ask_more();
- }
- while(!(Get_Comm_Status() & TSRE)); /* wait for output buffer to empty */
- return(0);
- }
-
- /* ====================================================================
- * display is a printf function to either the console or the comm port
- * note that the argument is variable (therefore must be cdecl convention)
- * ====================================================================
- */
- int play(const char *fmt,...)
- {
- char pbuf[BUFSIZ];
- va_list arg_ptr;
-
- va_start(arg_ptr, fmt);
- vsprintf(pbuf, fmt, arg_ptr);
- va_end(arg_ptr);
- sdisplay(pbuf);
- return(0);
- }
-
- /* ====================================================================
- * sendbyte outputs a character to either the console or the comm port
- * ====================================================================
- */
- void sendbyte(byte ch)
- {
-
- if(flags & FOSSIL) {
- if(ch == '\n') {
- Comm_transmit('\r');
- line++;
- if (!(Comm_CD()))
- terminate(3);
- }
- Comm_transmit(ch);
- putchar(ch);
- while(!(Get_Comm_Status() & TSRE)); /* wait for output buffer to empty */
- return;
- }
- else
- putchar(ch);
- return;
- }
- /*--------------------------------------------------------------------------*/
- /* If user has More? on in their user record */
- /*--------------------------------------------------------------------------*/
-
- void ask_more(void)
- {
- char ch;
-
- line = 0;
-
- if (quit_time < time(NULL)) /* Check the time */
- ctrl_err = 0;
-
- if (flags & FOSSIL) { /* Check carrier, exit(3) if lost */
- if (!(Comm_CD()))
- terminate(3);
-
- if (Comm_Peek() == 0x03) { /* Check for ^C inbound buffer */
- ctrl_err = 0;
- Comm_Purge_in(); /* Clear all buffers */
- Comm_Purge_out();
- }
- }
- sdisplay("More [Y,n,=]? ");
- ch = (char) get_a_char();
- sdisplay("\n");
- switch(ch) {
-
- case '\03':
- case 'n':
- case 'N': ctrl_err = 0;
- return;
-
- case '=':
- case '+': flags &= ~MORE;
- break;
-
- default: break;
- }
- return;
- }
-