/**********************************************************************/ /* Low-Level I/O Routines with Carrier Detect */ /* */ /* By: Bryan D. Hall Date: 03/15/89 */ /* GEnie Address: BDHALL */ /* Fnet Address: Bryan Hall, Node 227 CO (719)543-1869 12/24/96 HST */ /* M-F 4PM-10AM, 24Hrs Weekends*/ /* */ /* Modified for Turbo C by Wolfgang Zweygart Date: 01/09/89 */ /**********************************************************************/ /** cd_check() ********************************************************/ /* INPUT: None (hardware) CD Line */ /* PROCESS: This is a routine to check for carrier. Exits program if */ /* no carrier */ /* OUTPUT: None. Exits with status 1 */ /**********************************************************************/ void cd_check(void) { long old_stack; char *gpip; char test; gpip=(char *)0xFFFFFA01L; old_stack = Super(0L); test= *gpip; Super((void *) old_stack); if (test & 2) exit(1); /* no carrier.. get out of this! */ } /** cd_bconin(int) ****************************************************/ /* INPUT: Device number. 0=prn:, 1=aux:, 2=con:, or 3=MIDI. See */ /* Bconin for more info. */ /* PROCESS: Same as for Bconin, but also checks for a carrier. */ /* OUTPUT: See Bconin */ /**********************************************************************/ int cd_bconin(int device) { switch(device) { case 1: while(1){ /* AUX: set as primary device */ cd_check(); /* first make sure there is a carrier */ if (Bconstat(2) != 0) return((int)Bconin(2)); /* then get char from console */ if (Bconstat(device) != 0) return((int)Bconin(device)); /* then get char from device */ } case 2: /* CON: set as primary device */ return((int)Bconin(device)); /* then get char from console */ case 3: /* MIDI: set as primary device */ if (Bconstat(2) != 0) return((int)Bconin(2)); /* then get char from console */ else return((int)Bconin(device)); /* then get char from device */ default: return(0); } } /** cd_bconout(int,int) ***********************************************/ /* INPUT: (1) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. see*/ /* Bconout for more info. */ /* (2) Character to output, in low byte. */ /* PROCESS: Same as for Bconout, except checks for a carrier, and also*/ /* sends the character to the keyboard if aux: is selected. */ /* OUTPUT: None */ /**********************************************************************/ void cd_bconout(int device, char character) { switch(device) { case 1: /* aux: set as the primary device */ cd_check(); /* first make sure there is a carrier */ Bconout(device,(int)character); /* sent to device and console */ Bconout(2,(int)character); break; case 0: /* Any other legal device */ case 2: case 3: case 4: case 5: Bconout(device,(int)character); /* send to device only */ break; } } /** cd_bconstat(int) **************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, or 3=MIDI. See */ /* Bconstat for more info. */ /* PROCESS: Same as for Bconstat, except checks for a carrier, and */ /* also checks the keyboard if aux: is selected. */ /* OUTPUT: Returns -1 if at least one character is ready, else 0 */ /**********************************************************************/ int cd_bconstat(int device) { switch(device) { case 1: /* AUX: set as primary device */ cd_check(); /* first make sure there is a carrier */ if (Bconstat(2) != 0) return((int)Bconstat(2)); /* then send "console is ready" */ else return((int)Bconstat(device)); /* otherwise check AUX: */ case 0: /* PRN:, CON:, or MIDI: */ case 2: case 3: return(Bconstat(device)); default: return(0); } } /** cd_bcostat(int) ***************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See */ /* Bcostat for more info. */ /* PROCESS: Same as for Bcostat, except it also checks for a carrier. */ /* OUTPUT: Returns -1 if device is ready, else 0. */ /**********************************************************************/ int cd_bcostat(int device) { switch(device) { case 1: /* AUX: set as primary device */ cd_check(); /* first make sure there is a carrier */ return((int)Bcostat(device)); case 0: /* Any other legal device */ case 2: case 3: case 4: case 5: return((int)Bcostat(device)); default: return(0); } } /** cd_getchar(int) ***************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, or 3=MIDI. See */ /* Bcostat for more info */ /* PROCESS: Waits for a character from the specified device. Then it */ /* checks to see if the chatacter is printable. If so, it */ /* is displayed and returned. However, if the character is */ /* a , the routine remembers this, and the next time */ /* called, will not echo the character, but will return it */ /* and cancel the pause. */ /* NOTE: If the device is not con:, it will also get the */ /* from the keyboard. */ /* OUTPUT: Returns the character, as an int. */ /**********************************************************************/ int cd_getchar(int device) { int temp; static int paused; while (cd_bconstat(device) == 0); /* wait for a character */ temp = cd_bconin(device); /* get character */ if ((isprint(temp) || (temp==10) || (temp==13) || (temp==8)) && !paused ) { cd_bconout(device,temp); /* echo out to device */ } else { if (temp == 19) /* CTRL-S */ paused = 1; /* set flag */ else paused = 0; /* not paused */ } return( temp ); /* return ASCII code */ } /** cd_hgetchar(int) **************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, or 3=MIDI. See */ /* Bcostat for more info. */ /* PROCESS: Waits for a character from the specified device. Does NOT*/ /* echo character to device or screen. */ /* OUTPUT: Returns the character as an int. */ /**********************************************************************/ int cd_hgetchar(int device) /* hidden get character (no echo) */ { while (cd_bconstat(device) == 0) ; /* wait for a character */ return( cd_bconin(device) ); /* return ASCII code */ } /** cd_putchar(char,int) **********************************************/ /* INPUT: (1) Character to output. */ /* (2) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See*/ /* Bcostat for more info. */ /* PROCESS: Sends out a character to the specified device. If the */ /* character is a LineFeed, then it also sends a . */ /* NOTE: If the device is not con:, it will also send the */ /* char. to the screen. */ /* OUTPUT: None */ /**********************************************************************/ void cd_putchar(char outchar, int device) { static int pause = 0; cd_bconout(device, outchar); /* send out character */ if (outchar == 10) /* LF */ cd_bconout(device, 13); /* send out CR */ do { if(cd_bconstat(device)==-1) { if(cd_bconin(device)==19) pause=-1; else pause=0; } } while(pause==-1); } /** cd_gets(char,int,int) *********************************************/ /* INPUT: (1) "String" pointer. */ /* (2) Maximum number of chars to get. */ /* (3) Device number 0=prn:, 1=aux:, 2=con:, or 3=MIDI. See */ /* Bcostat for more info. */ /* PROCESS: Works somewhat like gets(), except that you can set the */ /* maximum number of characters to be typed in, plus allows */ /* for non-redirectable input. It also sends out a */ /* character when a user tries to backspace past the */ /* beginning of the line, and also after the last acceptable */ /* character space has been filled. This allows the user to */ /* then backspace for corrections. */ /* NOTE: If the device is not con:, it will also get the */ /* "string" from the keyboard. */ /* OUTPUT: None. */ /**********************************************************************/ void cd_gets(char *s, int n, int device) { register int c; int at_now=0; while(1) { while (cd_bconstat(device) == 0) ; /* wait for a character */ c = cd_bconin(device); /* get character */ if (c == 8) /* BS */ { if (at_now > 0) { n+=1; at_now-=1; cd_bconout(device,c); /* echo out to device */ } else { cd_bconout(device,7); /* echo bell out to device */ } } else { if ((isprint(c) || (c == 10) || (c == 13) || (c == 8))) { s[at_now++] = c; if (!(n-2)) cd_bconout(device,7); /* echo bell out to device */ if ((--n <= 0) || (c == 13) || (s[at_now-1] == '\n')) { s[at_now-1] = '\0'; return; } cd_bconout(device,c); /* echo out to device */ } } } } /** cd_puts(char,int) *************************************************/ /* INPUT: (1) Pointer to "string" to output. */ /* (2) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See*/ /* Bcostat for more info. */ /* PROCESS: Works just like puts() (except for re-direction */ /* protection), plus adds the pause features found in the */ /* cd_putchar routine. */ /* NOTE: If the device is not con:, it will also send the */ /* "string" to the screen. */ /* OUTPUT: None. */ /**********************************************************************/ void cd_puts(char *s, int device) { char c; while ((c = *s++) !=0) cd_putchar(c, device); } /** cd_printf(int device, const char *format, ...) ********************/ /* INPUT: (1) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See*/ /* Bcostat for more info. */ /* (2) Format string like printf() */ /* (.) Parameters like printf() */ /* PROCESS: Works just like printf() (except for re-direction */ /* protection), plus adds the pause features found in the */ /* cd_putchar routine. */ /* NOTE: If the device is not con:, it will also send the */ /* "string" to the screen. */ /* OUTPUT: None. */ /**********************************************************************/ void cd_printf(int device, const char *format, ...) { va_list arg_point; char temp[255]; va_start(arg_point, format); vsprintf(temp, format, arg_point); cd_puts(temp, device); va_end(arg_point); } /** cd_nputs(char,int,int) ********************************************/ /* INPUT: (1) Pointer to "string" to be output. */ /* (2) Maximum number of chars to output. */ /* (3) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See*/ /* Bcostat for more info */ /* PROCESS: Works just like cd_puts() but allows you to specify the */ /* maximum number of characters to be output. */ /* NOTE: If the device is not con:, it will also send the */ /* "string" to the screen. */ /* OUTPUT: None. */ /**********************************************************************/ void cd_nputs(char *s, int n, int device) { char c; while (((c = *s++) !=0) && (--n)) cd_putchar(c, device); } /** clr_scrn(int) *****************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. see */ /* Bcostat for more info */ /* PROCESS: Sends both a VT-52 clear screen & home cursor, and a */ /* to the device, and just the VT-52 code to con: */ /* OUTPUT: None. */ /**********************************************************************/ void clr_scrn(int device) { cd_puts("\033E \f",device); /* clear screen */ cd_puts("\033E",2); } /** read_file(char,int) ***********************************************/ /* INPUT: (1) Pointer to file path\name. Exp: "c:\txt\read.me" */ /* (2) Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See*/ /* Bcostat for more info */ /* PROCESS: Opens an ASCII (non-binary) file in read-only mode and */ /* sends it one character at a time, to the device. If a */ /* is recieved (not echoed to device), it will pause*/ /* until any other character is received. If is */ /* recieved when not paused, it will close the file and */ /* abort. If the file cannot be opened, a message will be */ /* displayed and the function will abort. */ /* NOTE: If the device is not con:, it will also send the */ /* file to the screen. */ /* OUTPUT: None. */ /**********************************************************************/ void read_file(char filename[], int device) { FILE *fp; int stat =0; char ch; if ((fp = fopen(filename,"r")) != NULL) { while (((ch = fgetc(fp)) != EOF) && (stat != 1)) { cd_putchar(ch,device); /* send out char */ if (cd_bconstat(device) == -1L) /* If true, char is availible*/ { ch=cd_hgetchar(device); /* Get input */ if (ch == 19) /* CTRL - S */ { cd_hgetchar(device); /* wait for key */ stat = 0; } else if (ch == 3) /* CTRL - C */ stat = 1; } } } else { cd_puts("\nCannot open file: ", device); cd_puts(filename, device); return; } fclose(fp); } /** do_pushany(int) ***************************************************/ /* INPUT: Device number 0=prn:, 1=aux:, 2=con:, 3=MIDI, etc. See */ /* Bcostat for more info. */ /* PROCESS: Sends out a "Press any key message", then waits for a */ /* character. */ /* NOTE: If the device is not con:, it will also send the */ /* message to the screen. */ /* OUTPUT: None. */ /**********************************************************************/ void do_pushany(int device) { cd_puts("\n << Press ANY Key to Continue >>\n",device); cd_hgetchar(device); }