home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
cpgms.zip
/
LMODEM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1985-11-17
|
25KB
|
1,067 lines
#define CPM86 1
#define CPM80 0
#define DeSmet 1 /* using the DeSmet C compiler */
#define MSDOS 0 /* run under MSDOS op sys */
#if CPM86
#define CPM 1 /* run under CPM op sys */
#endif
#if CPM80
#define CPM 1 /* run under CPM op sys */
#endif
#define DOTS 50 /* sector counting dots per line */
#define SPS 9500 /* loops per second */
#define SECSIZ 0x80
#define DATMSK 0x7f
#define BUFSEC 128 /* number of filel sectors to buffer */
#define BUFSIZ 0x7f80 /* large text buffer (32k - 1 sector) */
#define ERRMAX 10 /* max errors before abort */
#define RETMAX 5 /* max retrys before abort */
#if CPM
#define DIRCIO 6 /* cpm bdos direct console io cmd */
#define INPUT 0xff /* direct-console io input */
#define GSUSER 31 /* cpm bdos get/set user */
#define GETUSR 0xff /* get user number */
#endif
#define ERROR 0 /* bad open return */
#define FALSE 0 /* universal evil */
#define TRUE 1 /* universal good */
#define NULL 0 /* end of string, etc */
/***********************************************************************/
/* */
/* Special characters used in the file transfer-protocol */
/* */
/***********************************************************************/
#define TIMOUT -1 /* timeout character */
#define SOH 1 /* start of sector character */
#define EOT 4 /* end of tranmission char */
#define ACK 6 /* Acknowledge sector transmission */
#define NAK 21 /* error in transmission detected */
#define CRCC 'C' /* respond to force CRC checking */
/***********************************************************************/
/* */
/* Miscellaneous ASCII characters */
/* */
/***********************************************************************/
#define ESC 0x1b
#define TAB 9
#define LF 10
#define CR 13
#define CTRLZ 26 /* eof char */
/***********************************************************************/
/* */
/* These defines determine which keys will be interpreted */
/* as command characters */
/* */
/***********************************************************************/
#define CTRLA 01
#define CTRLB 02
#define CTRLC 03
#define CTRLE 05
#define CTRLK 11
#define CTRLL 12
#define CTRLP 16
#define CTRLQ 17
#define CTRLR 18
#define CTRLS 19
#define CTRLV 22
#define CTRLX 24
#define CTRLY 25
/* commands */
#define CMND CTRLA
#define CAPTUR 'C' /* toggle text capture */
#define KEEP 'K' /* keep text buffer */
#define LITERL CTRLL /* send literal character */
#define BAUD 'B' /* change the baud rate */
#define ECHO CTRLE /* local echo of keyboard data */
#define PRINT CTRLP /* echo to printer */
#define CANCEL CTRLX /* cancel file trans/recv */
#define QUIT 'Q' /* quit */
#define RECV 'R' /* receive file by sectors */
#define SEND 'S' /* send file by sectors */
#define TERMNL 'T' /* enter terminal mode */
#if CPM
#define USER 'U' /* change user number */
#endif
#define VIEW CTRLV /* view data transferred */
char ViewMd, BFlag, KbData, ModDat, Echofl;
char ShowTr, ShowRc, View, Prntfl;
char Commok;
char *Bufr;
char FileNm[15];
#if CPM
int Curusr, Oldusr;
#endif
char CmdBuf[60], strng[20];
int Fd, PFd, CRCflg, Batflg;
int TxtPtr, Abort;
int brate = 1200;
main(argc,argv)
int argc;
char *argv[];
{
ShowRc = ShowTr = BFlag = View = Echofl = FALSE;
Prntfl = Commok = FALSE;
Fd = PFd = -1; /* show file not open */
TxtPtr = 0;
ViewMd = KbData = CmdBuf[0] = NULL;
#if CPM
Curusr = Oldusr = bdos(GSUSER, GETUSR); /* save user # on entry */
puts(" Current user # is ");
itoa(Curusr,strng);
puts(strng);
puts("\n");
#endif
if ((Bufr = calloc(BUFSIZ,1)) == ERROR) {
puts("Unable to acquire buffer\n");
return; /* exit if no space for buffer */
}
CmdBuf[0] = NULL;
evalcd(CmdBuf);
initmd();
/* the main loop */
while ((dcdrdy() || !Commok) && (CmdBuf[0] != QUIT)) {
if (!Commok && dcdrdy()) /* we have a connection */
Commok = TRUE;
if (KbData = kbdin()) /* get any char at kbd */
switch(KbData) { /* eval term mode cmds */
case CMND:
cmdmen();
evalcd(CmdBuf); /* eval cmd mode entry */
break;
case VIEW:
View = ~View;
if (View)
puts("Viewing enabled\n ");
else
puts("Viewing disabled\n");
break;
case LITERL:
while (!(KbData = kbdin()));
mcharo(KbData);
break;
case PRINT:
Prntfl = ~Prntfl;
if (Prntfl & (PFd == -1))
PFd = fopen("LST:", "w");
break;
case ECHO:
Echofl = ~Echofl;
break;
default:
mcharo(KbData);
if (Echofl) {
putchar(KbData);
if (Prntfl) {
if (KbData == CR)
KbData = '\n';
putc(KbData, PFd);
}
}
break;
}
if (minrdy()) {
ModDat = mchari();
if (BFlag && (TxtPtr < BUFSIZ))
Bufr[TxtPtr++] = ModDat;
else if (BFlag)
puts("Capture Bufr overflow\n");
putchar(ModDat);
if (ModDat == CR)
ModDat = '\n';
if (Prntfl)
putc(ModDat, PFd);
}
}
if (CmdBuf != QUIT)
puts("\nYou lost carrier detect");
#if CPM
Curusr = Oldusr = bdos(GSUSER, Oldusr); /* reset user # to entry */
#endif
}
evalcd(cbuf)
char *cbuf;
{
char Cmdchr, option[30], *savcbf;
int i, brate;
savcbf = cbuf; /* save start of original buffer */
Cmdchr = NULL;
while ((Cmdchr != QUIT) && (Cmdchr != TERMNL)) {
if (*cbuf == NULL) { /* need new cmd input */
cbuf = savcbf;
cmdmen();
getstr(60,cbuf);
for (i=0; cbuf[i] != NULL; i++) /* cmd is upper */
cbuf[i] = touppr(cbuf[i]);
}
Cmdchr = *cbuf;
/* skip command in buffer */
cbuf = skptok(cbuf);
switch(Cmdchr) { /* eval cmd mode cmds */
case BAUD:
brate = atoi(cbuf);
if (brate = baudst(brate))
initmd();
else
puts("Invalid baud rate -- Command terminated.\n");
break;
case CAPTUR:
BFlag = ~BFlag;
if (BFlag)
puts("Capture initiated");
else
puts("Capture terminated");
itoa(BUFSIZ - TxtPtr, strng);
puts(", ");
puts(strng);
puts(" bytes free\n");
break;
case KEEP:
if (!TxtPtr)
puts("Nothing to save\n");
else {
if (*cbuf == ' ') { /* user entered filename */
cbuf++;
mkstr(15,cbuf,FileNm);
}
else {
puts("Save as what file? \n");
getstr(15,FileNm);
}
Bufr[TxtPtr] = CTRLZ;
Fd = fopen(FileNm, "w");
if (Fd == ERROR) {
puts("Cannot create ");
puts(FileNm);
puts("\n");
}
else {
write(Fd, Bufr,
1+(TxtPtr));
fclose(Fd);
BFlag = FALSE;
TxtPtr = 0;
}
}
break;
case QUIT:
hangup();
break;
case RECV:
if (*cbuf == ' ') { /* check batch and CRC options */
while ((*cbuf == ' ') && !*cbuf) /* skip leading blanks */
cbuf++;
Batflg = (*cbuf == 'B') || (*(cbuf+1) == 'B');
CRCflg = (*cbuf == 'C') || (*(cbuf+1) == 'C');
cbuf += Batflg + CRCflg; /* skip options */
}
if (*cbuf == ' ') { /* user entered filename */
while ((*cbuf == ' ') && !*cbuf) /* skip leading blanks */
cbuf++;
mkstr(15,cbuf,FileNm);
}
else
if (!Batflg) {
puts("Receive what file? \n");
getstr(15, FileNm);
}
rdfile(FileNm);
break;
case SEND:
if (*cbuf == ' ') { /* check batch option */
while ((*cbuf == ' ') && !*cbuf) /* skip leading blanks */
cbuf++;
Batflg = (*cbuf == 'B');
cbuf += Batflg; /* skip options */
}
if (*cbuf == ' ') { /* user entered filename */
while ((*cbuf == ' ') && !*cbuf) /* skip leading blanks */
cbuf++;
mkstr(15,cbuf,FileNm);
}
else {
puts("Send what file? \n");
getstr(15, FileNm);
}
sdfile(FileNm);
break;
case TERMNL:
break;
#if CPM
case USER:
if ((Curusr = atoi(cbuf)) <= 15)
bdos(GSUSER, Curusr);
else
puts("User number must be between 0 and 15.\n");
break;
#endif
default:
puts("Invalid Command, try again\n");
}
cbuf = skptok(cbuf);
}
}
kbdin()
{
#if CPM
return(bdos(DIRCIO, INPUT));
#endif
}
skptok(cbuf)
char *cbuf;
{
/* skip token in buffer */
for(;(*cbuf != ' ') && (*cbuf != ';') &&
(*cbuf != NULL) && (*cbuf != CR);cbuf++)
;
return (cbuf);
}
cmdmen()
{
char OnOff[4];
clrscr(); /* clear screen */
puts("\t\t\t\tC Modem\n");
puts("\nCommand Mode Commands\n");
itoa(brate,strng);
puts("Baud [rate]\t(");
puts(strng);
puts(")\t\tSet baud rate\n");
if (BFlag)
strcpy(OnOff,"On ");
else
strcpy(OnOff,"Off");
puts("Capture\t\t(");
puts(OnOff);
puts(")\t\tCapture received data to buffer\n");
puts("Dir [drive/filename]\t\t\tList directory\n");
puts("Keep [drive/filename]\t\t\tSave captured data\n");
puts("Quit\t\t\t\t\tExit program\n");
puts("Receive [b][c] [drive/filename]\t\tReceive file\n");
puts("\t\t\t\t\t\tb - batch mode, c - CRC check\n");
puts("Send [b] [drive/filename]\t\tSend file\n");
puts("Terminal\t\t\t\tEnter terminal mode\n");
#if CPM
itoa(Curusr,strng);
puts("User #\t(");
puts(strng);
puts(")\t\t\tChange CPM user #\n");
#endif
puts("\nTerminal Mode Commands\n");
puts("^C\t\t\tEnter command mode\n");
if (Echofl)
strcpy(OnOff,"On ");
else
strcpy(OnOff,"Off");
puts("^E\t(");
puts(OnOff);
puts(")\tEcho On/Off\n");
puts("^L\t\t\tSend next char as-is\n");
if (Prntfl)
strcpy(OnOff,"On ");
else
strcpy(OnOff,"Off");
puts("^P\t(");
puts(OnOff);
puts(")\tPrinter On/Off\n");
if (View)
strcpy(OnOff,"On ");
else
strcpy(OnOff,"Off");
puts("^V\t(");
puts(OnOff);
puts(")\tView of send/recv On/Off\n");
puts("^X\t\t\tCancel send/recv\n");
puts("\n\tCommand: ");
return;
}
rdfile(file)
char *file;
{
int rfd;
if (View) {
ShowRc = TRUE;
ShowTr = FALSE;
}
initmd(); /* initialize modem */
if (Batflg) /* if batch mode, receive mult files w/names */
while (recfn(file))
if (!Abort)
if (rfd = recopn(file))
rdtxt(rfd);
else /* if not batch mode, receive one file */
if (rfd = recopn(file))
rdtxt(rfd);
return;
}
recsyn()
{
char chrin;
int errcnt;
errcnt = 0;
chrin = NULL;
while ((!Abort) && (chrin != ACK)) {
if (!CRCflg)
sdchar(NAK); /* declare checksumming */
else
sdchar('C'); /* declare CRC checking */
chrin = rdchar(2); /* wait for ACK */
if (chrin == CANCEL) {
Abort++;
puts("\n Receive cancelled by Sender \n");
}
if (CRCflg && (chrin != ACK)) {
errcnt++;
if (errcnt > 10) {
puts("\n CRC not acknowledged, switching to checksum \n");
CRCflg = 0;
}
}
if (kbdin() == CANCEL) {
Abort++;
puts("\n Receive cancelled by You \n");
}
}
}
rdtxt(rfd)
int rfd;
{
static int chrin, secnum, seccur, seccmp, errors;
static int chksum, tret;
static int errflg;
static int j, bufptr;
char itoaw[12];
recsyn(); /* send NAK/'C' until in sync w/xmitter */
if (Abort)
return FALSE;
else
puts("\n Awaiting Initial Sector ... ");
secnum = errors = bufptr = 0;
do {
while ((chrin = rdchar(10)) != SOH) { /* wait for SOH */
if (chrin == CANCEL) {
Abort++;
return FALSE;
}
if (chrin == EOT)
return TRUE;
if (chrin == TIMOUT)
puts("\n Timeout waiting for SOH ++ ");
if ((chrin != SOH) && (chrin != TIMOUT)) {
puts("\n Received ");
itoa(chrin,strng);
puts(strng);
puts(", not SOH\n");
purgln();
}
if (kbdin() == CANCEL) {
puts("\n Receive cancelled by You\n");
Abort++;
return FALSE;
}
}
if (chrin == SOH) {
seccur = rdchar(1);
seccmp = rdchar(1);
if ((seccur + seccmp) == 255) {
if (seccur == (secnum + 1 & 0xff)) {
chksum = 0;
for (j=bufptr; j<(bufptr+SECSIZ); j++) { /* read a sector */
Bufr[j] = rdchrc(1, chksum);
if (Bufr[j] == TIMOUT) {
errors++;
break;
}
}
if (!errors) {
if (CRCflg) { /* force the CRC through the bucket */
rdchrc(1, chksum);
rdchrc(1, chksum);
}
else
chksum = chksum - rdchar(1);
if (!chksum) {
errors = 0;
secnum++;
bufptr += SECSIZ;
if ((secnum % BUFSEC) == 0) {
bufptr = 0;
if (write(rfd,Bufr,BUFSEC*SECSIZ) == ERROR) {
puts("\n Error writing file, Aborting\n");
fclose(rfd);
Abort++;
return FALSE;
}
/* if sender times out while we
are writing the disk, it will
resend the sector. Hang here
until it's done, then fall
through and acknowledge */
do ; /* nothing */
while (rdchar(1) != TIMOUT);
}
sdchar(ACK);
}
else {
if (CRCflg == 0)
puts("\nCRC error ");
else
puts("\nChecksum error ");
}
}
}
else if (seccur == (secnum & 0xff)) {
puts("\nReceived duplicate sector ");
itoa(itoaw,secnum);
puts(itoaw);
/* wait for silence on the line */
do ; /* nothing */
while (rdchar(1) != TIMOUT);
sdchar(ACK);
}
else
puts("\nSynchronization error\n");
}
else
puts("\nSector number error\n");
}
if (kbdin() == CANCEL) {
errors = ERRMAX;
break;
}
if (errflg == TRUE) {
errors++;
puts("Error ");
itoa(errors,strng);
puts(strng);
puts("\n");
do ; /* nothing */
while (rdchar(1) != TIMOUT);
sdchar(NAK);
}
} while (chrin != EOT && errors != ERRMAX);
if ((chrin == EOT) && (errors < ERRMAX)) {
sdchar(ACK);
write(rfd, Bufr, 1 + bufptr);
fclose(rfd);
puts("\nTransfer complete\n");
}
else
puts("\n\nAborting\n");
}
recfn(file) /* receive filename in batch mode */
char *file; /* returns a FALSE if no more filenames */
{
char chrin, *fptr;
int errcnt, errs, chksum;
chrin = NULL;
errcnt = errs = 0;
fptr = file; /* save start of filename */
puts("\n Awaiting Filename from Sender ");
while ((errs < ERRMAX) && chrin != CTRLZ) {
recsyn(); /* send NAK/'C' until in sync */
/* may set Abort flag on error */
while ((!Abort) && (chrin != CTRLZ)) {
chrin = rdchar(5); /* get next filename character */
if (chrin == TIMOUT) {
errs++;
puts("\n Timeout on filename receive \n");
break;
}
else
errs = 0;
if (chrin != CTRLZ) {
*fptr++ = chrin; /* accumulate filename */
sdchar(ACK); /* tell sender I got it */
}
}
*fptr = NULL; /* end of string */
if ((!Abort) && (!errs)) {
sdchar(chksum); /* send received checksum (or CRC) */
chrin = rdchar(5); /* wait for ACK */
if (chrin == TIMOUT) {
errs++;
puts("\n Timeout on filename receive \n");
}
}
}
if (errs == 0)
return (TRUE);
else
return (FALSE);
}
recopn(file) /* open a file for receiving */
char *file;
{
int rfd;
char ans;
ans = ' ';
rfd = 0;
if(!(rfd = fopen(file, "r"))) { /* file exists, check w/ user */
while ((ans != 'D') && (ans != 'N')) {
puts("\n\t==> File exists. Enter D to delete or N for new filename: ");
getstr(1,ans);
ans = toupper(ans);
}
fclose(rfd);
rfd = 0;
if (ans == 'D') {
if (unlink(file) == -1) {
puts("\n ==> File delete failed, Aborting\n");
Abort++;
}
}
else if (ans == 'N') {
puts("\n Enter new filename: ");
getstr(15,file);
}
}
if (!Abort)
if ((rfd = creat(file)) == -1) {
puts("\n ==> Cannot create file ");
Abort++;
}
return rfd;
}
rdchrc(secs, chksum) /* read and compute checksum/CRC */
int secs, chksum;
{
int ret;
ret = rdchar(secs);
if (ret != TIMOUT)
if (CRCflg)
crc_update(chksum,ret);
else
chksum = (chksum + ret) & 0xff;
return (ret);
}
rdchar(secs)
int secs;
{
static char data;
secs = secs*SPS;
while (!minrdy() && secs) /* wait until input ready */
--secs;
if (!secs)
return TIMOUT; /* nothing arrived in time */
data = mchari(); /* else, get it */
if (ShowRc) {
if(((data >= ' ') && (data <= DATMSK))
|| data == LF || data == CR || data == TAB)
putchar(data);
else
puts(".");
}
return data;
}
sdfile(file)
char *file;
{
static int secnum, sects, tries;
static int chksum, sfd;
static int j, k, bufptr;
if (View) {
ShowRc = FALSE;
ShowTr = TRUE;
}
sfd = fopen(file, "r");
if (sfd == ERROR) {
puts("Cannot open ");
puts(file);
puts("\n");
return;
}
else
puts("Sending ");
puts("\n\n");
puts(file);
initmd();
tries = 0;
secnum = 1;
puts("\nWaiting a NAK\n\n");
do {
j = rdchar(10);
if (j == 'C')
CRCflg = 1;
else if (j == NAK)
CRCflg = 0;
} while ((j != NAK) && (j != 'C') && ((k = kbdin()) != CANCEL));
while ((sects = read(sfd, Bufr, BUFSIZ/SECSIZ)) && (tries != RETMAX)) {
if (sects == ERROR) {
puts("\nError reading file\n");
fclose(sfd);
return;
}
else {
bufptr = 0;
do {
tries = 0;
do {
if (!ShowTr)
if (((secnum - 1) % DOTS) == 0)
puts("\n<%4d>.", secnum);
else
puts(".");
sdchar(SOH);
sdchar(secnum);
sdchar(~secnum);
chksum = 0;
for (j = bufptr; j < (bufptr + SECSIZ); j++) {
sdchar(Bufr[j]);
if (CRCflg == 0)
chksum = (chksum + Bufr[j]) & 0xff;
}
if (CRCflg != 0)
chksum = cmpcrc(bufptr,SECSIZ);
sdchar(chksum);
prglne();
tries++;
} while ((rdchar(10) != ACK) &&
(tries != RETMAX));
bufptr += SECSIZ;
secnum++;
sects--;
} while (sects && (tries != RETMAX));
}
}
if (k == CANCEL)
puts("\nTransmission cancelled\n");
else if (tries == RETMAX)
puts("\nNo acknowledgment of sector, aborting\n");
else {
tries = 0;
do {
sdchar(EOT);
prglne();
tries++;
} while ((rdchar(10) != ACK) && (tries != RETMAX));
if (tries == RETMAX)
puts("\nNo acknowledgment of end of file, aborting\n");
else
puts("\nTransfer complete\n");
}
fclose(sfd);
return;
}
sdchar(data)
char data;
{
while (!motrdy()); /* wait until output ready */
mcharo(data); /* send it */
if (ShowTr) {
if (((data >= ' ') && (data <= DATMSK))
|| data == LF || data == CR || data == TAB)
putchar(data);
else
puts(".");
}
return;
}
touppr(ichar)
char ichar;
{
ichar = (ichar >= 'a' & ichar <= 'z') ? ichar - 32 : ichar;
}
/******************************************************************************
* *
* Cyclic Redundancy Check (CRC) functions *
* *
******************************************************************************/
/*
* crc_clear:
* This function clears the CRC to zero. It should be called prior to
* the start of the processing of a block for both received messages,
* and messages to be transmitted.
*
* Calling sequence:
*
* short crc;
* crc = crc_clear();
*/
short crc_clear()
{
return(0);
}
/*
* crc_update:
* this function must be called once for each character which is
* to be included in the CRC for messages to be transmitted.
* This function is called once for each character which is included
* in the CRC of a received message, AND once for each of the two CRC
* characters at the end of the received message. If the resulting
* CRC is zero, then the message has been correctly received.
*
* Calling sequence:
*
* crc = crc_update(crc,next_char);
*/
short crc_update(crc,crc_char)
short crc;
char crc_char;
{
long x;
short i;
/* "x" will contain the character to be processed in bits 0-7 and the CRC */
/* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared */
/* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not */
/* used. ("x" is treated as though it is a 32 bit register). */
x = ((long)crc << 8) + crc_char; /* Get the CRC and the character */
/* Repeat the following loop 8 times (for the 8 bits of the character). */
for(i = 0;i < 8;i++)
{
/* Shift the high-order bit of the character into the low-order bit of the */
/* CRC, and shift the high-order bit of the CRC into bit 24. */
x = x << 1; /* Shift "x" left one bit */
/* Test to see if the old high-order bit of the CRC was a 1. */
if(x & 0x01000000) /* Test bit 24 of "x" */
/* If the old high-order bit of the CRC was a 1, exclusive-or it with a one */
/* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the */
/* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce */
/* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from */
/* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005 */
/* and produce the same CRC that IBM uses for their synchronous transmission */
/* protocols. */
x = x ^ 0x01102100; /* Exclusive-or "x" with a...*/
/* ...constant of hex 01102100 */
/* And repeat 8 times. */
} /* End of "for" loop */
/* Return the CRC as the 16 low-order bits of this function's value. */
return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
/* ...shift the result 8 bits to the right */
}
/*
* crc_finish:
* This function must be called once after all the characters in a block
* have been processed for a message which is to be TRANSMITTED. It
* returns the calculated CRC bytes, which should be transmitted as the
* two characters following the block. The first of these 2 bytes
* must be taken from the high-order byte of the CRC, and the second
* must be taken from the low-order byte of the CRC. This routine is NOT
* called for a message which has been RECEIVED.
*
* Calling sequence:
*
* crc = crc_finish(crc);
*/
short crc_finish(crc)
short crc;
{
/* Call crc_update twice, passing it a character of hex 00 each time, to */
/* flush out the last 16 bits from the CRC calculation, and return the */
/* result as the value of this function. */
return(crc_update(crc_update(crc,NULL),NULL));
}
int baudrt = 05; /* index for 1200 baud (baudtb[5]="1200") */
baudst(baudin)
int baudin;
{
static baudtb[] = {110,150,300,600,1200,2400,4800,9600};
static int indx;
static char baudsi[5];
while (baudin == 0) {
puts("\n\t 110,150,300,600,1200,2400,4800,9600");
puts("\nEnter the required baud rate ");
getstr(5,baudsi);
baudin = atoi(baudsi);
}
for (indx=0; indx<=(sizeof(baudtb)/sizeof(baudtb[1])); indx++)
if (baudin == baudtb[indx]) {
baudrt = indx;
return baudin;
}
return FALSE;
}
clrscr()
{
scr_clr();
}
initmd()
{
sioint(baudrt);
prglne();
}
prglne()
{
while (minrdy()) /* while there are characters... */
mchari(); /* gobble them */
}
mchari()
{
while (!(inp(mstat) & rxrdy));
return inp(mdata);
}
mcharo(c)
char c;
{
while(!(inp(mstat) & txrdy));
outp(mdata,c);
}
motrdy()
{
return ((inp(mstat) & txrdy) > 0);
}
minrdy()
{
return ((inp(mstat) & rxrdy) > 0);
}
dcdrdy()
{
outp(mstat,rstext); /* ext reset must be done b4 dcd is ok */
return ((inp(mstat) & mdcd) > 0);
}