home *** CD-ROM | disk | FTP | other *** search
-
-
-
- /*This program implements the Ward Christensen assembly language
- program in C. All of the original modes are available, and a
- capture buffer was added to the terminal and computer modes.
- The UNIX and PDP10 modes were added to facilitate sending files
- to those systems. Note that the original version of this program
- was written for the D.C. Hayes modem board - however, this
- version is for the PMMI modem.
-
- original by Jack M. Wierda
- modified by Roderick W. Hart
- */
- #include <pmmi.h>
-
- #define FALSE 0
- #define TRUE 1
- #define NUL 0
- #define SOH 1
- #define CTRLB 2
- #define CTRLC 3
- #define EOT 4
- #define ERRORMAX 5
- #define RETRYMAX 5
- #define CTRLE 5
- #define ACK 6
- #define TAB 9
- #define LF 10
- #define CR 13
- #define CTRLQ 17
- #define SPS 2750 /*loops per second*/
- #define CTRLS 19
- #define NAK 21
- #define CTRLZ 26
- #define SPACE 32
- #define DELETE 127
- #define TIMEOUT -1
- #define SECSIZ 0x80
- #define DATAMASK 0x7f
- #define BUFSIZ 0x7f80 /*maximum size, 0x8000 will not work with
- with BDS C, reduce buffer size as necessary
- for smaller systems*/
-
- char cntrlw0, cntrlw1, cntrlw2, cntrlw3;
- char hangup, option, option2, mode, baudrate, display, system;
- char asciiflg, showtrans, showrecv, view, dtrr;
- char buffer[BUFSIZ];
-
- moready()
- {
- return (inp(STATPORT) & TBMT) == (MAHI ? TBMT : 0);
- }
- miready()
- {
- return (inp(STATPORT) & DAV) == (MAHI ? DAV : 0);
- }
- ctsready()
- {
- return (inp(MODEMCP2) & CTS) == (CTSHI ? CTS : 0);
- }
- sendline(data)
- char data;
- {
- while(!MOREADY());
- outp(DATAPORT,data);
- if(showtrans)
- { if(asciiflg)
- if(((data >= ' ') && (data <= 0x7f)) || data == LF || data == CR
- || data == TAB)
- putchar(data);
- else
- printf("[%0x]",data);
- if(option2 == 'H')
- printf("[%0x]",data);
- }
- }
-
- readline(seconds)
- int seconds;
- {
- char data;
- seconds = seconds * SPS;
- while (!MIREADY() && seconds--);
- if(seconds < 0)
- return(TIMEOUT);
- data = inp(DATAPORT);
- if(showrecv)
- { if(asciiflg)
- if(((data >= ' ') && (data <= 0x7f)) || data == LF || data == CR
- || data == TAB)
- putchar(data);
- else
- printf("[%0x]",data);
- if(option2 == 'H')
- printf("<%0x>",data);
- }
- return(data);
- }
-
- purgeline()
- {
- while (MIREADY())
- inp(DATAPORT); /*PURGE THE RECEIVE REGISTER*/
- }
-
- initializemodem()
- {
- char cdflg;
- cdflg = TRUE;
- if((option == 'R') || (option == 'S'))
- { cntrlw0 = ORIG + NB1 + NB2 + NP;
- cntrlw3 = dtrr;
- }
- else
- { cntrlw0 = ORIG + NB2 + EPS;
- cntrlw3 = dtrr;
- }
- if(!CTSREADY())
- { printf("Waiting for carrier\n");
- cdflg = FALSE;
- }
- while(!CTSREADY() && !bios(2))
- { outp(STATPORT,cntrlw0);
- outp(MODEMCP2,cntrlw2);
- outp(MODEMCP3,cntrlw3);
- outp(DATAPORT,cntrlw1);
- }
- if(CTSREADY() && !cdflg)
- printf("Carrier detected\n");
- outp(STATPORT, (cntrlw0 & 0xfe));
- purgeline();
- }
-
- sendstr(str)
- char *str;
- {
- while(*str)
- if(option == 'U')
- sendline(tolower(*str++));
- else
- sendline(*str++);
- }
-
- termcomp()
- {
- char bflag, kbdata, moddata;
- int fd;
- int bufctr;
- bflag = FALSE;
- bufctr = 0;
- initializemodem();
- while((CTSREADY()) && (kbdata !=CTRLE))
- { if(bios(2))
- switch(kbdata = bios(3))
- { case CTRLB:
- bflag = ~bflag;
- if(bflag)
- printf("Capture initiated");
- else
- printf("Capture terminated");
- printf(", %u bytes free\n",BUFSIZ - bufctr);
- break;
- case CTRLE:
- break;
- default:
- if(option == 'C')
- { putchar(kbdata);
- if(bflag && (bufctr < BUFSIZ))
- buffer[bufctr++] = kbdata;
- }
- outp(DATAPORT,kbdata);
- break;
- }
- if(MIREADY())
- { moddata = inp(DATAPORT);
- if(option == 'C')
- outp(DATAPORT,moddata);
- if(bflag && (bufctr < BUFSIZ))
- buffer[bufctr++] = moddata;
- else if(bflag)
- printf("Buffer overflow\n");
- putchar(moddata);
- }
- }
- if(bufctr)
- { buffer[bufctr] = CTRLZ;
- fd = creat("cmodem.tmp");
- if(fd == -1)
- { printf("Cannot create cmodem.tmp\n");
- exit();
- }
- write(fd,buffer,1 + (bufctr/SECSIZ));
- close(fd);
- }
- }
-
- putbuffer(buffer,sectors)
- char *buffer;
- int sectors;
- {
- char ch, moddata;
- unsigned k;
- ch = 0;
- k = 0;
- while((ch != CTRLZ) && (k < sectors * SECSIZ) && (CTSREADY()))
- { k = k+1;
- if((ch = *buffer++) == LF) /*don't send LF's*/
- putchar(LF);
- else
- if(ch != CTRLZ || option != 'U') /*don't send CTRLZ to UNIX*/
- sendline(ch);
- if(!(k & 0xff)) /*let other end catch-up*/
- while(readline(1) != TIMEOUT);
- }
- }
-
- pdp10(file)
- char *file;
- {
- char sectors;
- int fd;
- showrecv = FALSE;
- asciiflg = showtrans = TRUE;
- fd = open(file,0);
- if(fd == -1)
- { printf("Cannot open %s\n",file);
- exit();
- }
- initializemodem();
- if(option == 'P')
- { sendstr("\nR PIP\n");
- while((readline(1) != '*') && !bios(2));
- if(*(++file) != ':')
- sendstr(--file);
- else
- sendstr(++file);
- sendstr("=TTY:\n");
- }
- else
- { sendstr("\ncat > ");
- if(*(++file) != ':')
- sendstr(--file);
- else
- sendstr(++file);
- sendstr("\n");
- }
- while((sectors = read(fd,buffer,BUFSIZ/SECSIZ)) == BUFSIZ/SECSIZ)
- putbuffer(buffer,sectors);
- if(sectors)
- putbuffer(buffer,sectors);
- close(fd);
- while(readline(1) != TIMEOUT);
- if(option == 'P')
- sendline(CTRLC);
- else
- { sendline(CR);
- sendline(LF);
- sendline(EOT);
- }
- while(readline(10) != TIMEOUT);
- sendline(CR);
- sendline(LF);
- }
-
- readfile(file)
- char *file;
- { int j, firstchar, sectnum, sectcurr, sectcomp, errors;
- int checksum;
- int errorflag, fd;
- int bufctr;
-
- if(view)
- { showrecv = TRUE;
- showtrans = FALSE;
- }
- option2 = 'A';
- fd = creat(file);
- if(fd == -1)
- { printf("Cannot create %s\n",file);
- exit();
- }
- sectnum = 0;
- errors = 0;
- bufctr = 0;
- initializemodem();
- sendline(NAK);
- do
- { errorflag = FALSE;
- do
- firstchar = readline(6);
- while(firstchar != SOH && firstchar != EOT && firstchar != TIMEOUT);
- if(firstchar == TIMEOUT)
- { errorflag = TRUE;
- printf("SOH timeout\n");
- }
- if(firstchar == SOH)
- { sectcurr = readline(1);
- sectcomp = readline(1);
- if((sectcurr + sectcomp) == 255)
- { if(sectcurr == sectnum + 1)
- { checksum = 0;
- if(option2 == 'A')
- asciiflg = TRUE;
- for(j = bufctr;j < (bufctr + SECSIZ);j++)
- { buffer[j] = readline(1);
- checksum = (checksum + buffer[j]) & 0xff;
- }
- asciiflg = FALSE;
- if(checksum == readline(1))
- { errors = 0;
- sectnum = sectcurr;
- bufctr = bufctr + SECSIZ;
- if(bufctr == BUFSIZ)
- { bufctr = 0;
- write(fd,buffer,BUFSIZ/SECSIZ);
- }
- if(!showrecv)
- printf("Received sector %d\n",sectcurr);
- sendline(ACK);
- }
- else
- { printf("Checksum error, expected <%0x>\n",checksum);
- errorflag = TRUE;
- }
- }
- else
- if(sectcurr == sectnum)
- { do;
- while(readline(1) != TIMEOUT);
- printf("Received duplicate sector %d\n", sectcurr);
- sendline(ACK);
- }
- else
- { printf("Synchronization error\n");
- errorflag = TRUE;
- }
- }
- else
- { printf("Sector number error\n");
- errorflag = TRUE;
- }
- }
- if(errorflag == TRUE)
- { errors++;
- printf("Error %d\n",errors);
- while(readline(1) != TIMEOUT);
- sendline(NAK);
- }
- }
- while(firstchar != EOT && errors != ERRORMAX);
- if((firstchar == EOT) && (errors < ERRORMAX))
- { sendline(ACK);
- write(fd,buffer,1 + (bufctr/SECSIZ));
- close(fd);
- printf("Transfer complete\n");
- }
- else
- printf("Aborting\n");
- }
-
- sendfile(file)
- char *file;
- {
- int j, sectnum, sectors, attempts;
- int checksum;
- int bufctr, fd;
-
- if(view)
- { showrecv = FALSE;
- showtrans = TRUE;
- }
- option2 = 'A';
- fd = open(file,0);
- if(fd == -1)
- { printf("Cannot open %s\n",file);
- exit();
- }
- initializemodem();
- attempts = 0;
- sectnum = 1;
- while((sectors = read(fd,buffer,BUFSIZ/SECSIZ)) && (attempts != RETRYMAX))
- { if(sectors == -1)
- printf("\nFile read error\n");
- else
- { bufctr = 0;
- do
- { attempts = 0;
- do
- { if(!showtrans)
- printf("\nSending sector %d\n",sectnum);
- sendline(SOH);
- sendline(sectnum);
- sendline(-sectnum-1);
- checksum = 0;
- if(option2 == 'A')
- asciiflg = TRUE;
- for(j = bufctr;j < (bufctr + SECSIZ);j++)
- { sendline(buffer[j]);
- checksum = (checksum + buffer[j]) & 0xff;
- }
- asciiflg = FALSE;
- sendline(checksum);
- purgeline();
- attempts++;
- }
- while((readline(10) != ACK) && (attempts != RETRYMAX));
- bufctr = bufctr + SECSIZ;
- sectnum++;
- sectors--;
- }
- while((sectors != 0) && (attempts != RETRYMAX));
- }
- }
- if(attempts == RETRYMAX)
- printf("\nNo ACK on sector, aborting\n");
- else
- { attempts = 0;
- do
- { sendline(EOT);
- purgeline();
- attempts++;
- }
- while((readline(10) != ACK) && (attempts != RETRYMAX));
- if(attempts == RETRYMAX)
- printf("\nNo ACK on EOT, aborting\n");
- else
- printf("\nTransfer complete\n");
- }
- close(fd);
- }
-
- ckfile(argc) int argc;
- { if(!argc)
- { printf("File required\n");
- exit();
- }
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- { char *s;
- printf("Cmodem (Pmmi) ver 1.3 13-Apr-81\n");
- printf(" mod. by Rod Hart\n");
- cntrlw2 = 0;
- asciiflg = hangup = showrecv = showtrans = view = FALSE;
- if(**++argv != '-')
- { printf("Command line format: cmodem -options file1 file2 ... file14\n");
- printf("Available options are:\n");
- printf("\ta: answer t: terminal\n");
- printf("\tc: computer u: UNIX\n");
- printf("\th: auto-hangup v: view data\n");
- printf("\to: originate 1: 110 baud\n");
- printf("\tp: PDP10 3: 300 baud\n");
- printf("\tr: receive file 4: 450 baud\n");
- printf("\ts: send file 6: 600 baud\n");
- printf("The p, r, s, and u options require one or more files.\n");
- printf("Ctrl-B initiates and terminates data capture in file\n");
- printf("cmodem.tmp in the terminal and computer modes.\n");
- printf("Ctrl-E is used to initiate file transfers in the UNIX and\n");
- printf("PDP10 modes. In the terminal mode Ctrl-E escapes to the\n");
- printf("hangup question or CP/M.\n");
- printf("Any character escapes the no carrier condition.\n");
- exit();
- }
- --argv;
- while(--argc && **++argv == '-')
- for(s = *argv+1;*s;s++)
- switch(*s)
- { case 'C':
- case 'P':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- option = *s;
- break;
- case 'A':
- cntrlw0 = cntrlw0 + ANS;
- break;
- case 'H':
- hangup = TRUE;
- break;
- case 'V':
- view = TRUE;
- break;
- case 'O':
- cntrlw0 = cntrlw0 + ORIG;
- break;
- case '1':
- cntrlw2 = BR110;
- dtrr = UND300;
- break;
- case '3':
- cntrlw2 = BR300;
- dtrr = UND300;
- break;
- case '4':
- cntrlw2 = BR450;
- dtrr = OVR300;
- break;
- case '6':
- cntrlw2 = BR600;
- dtrr = OVR300;
- break;
- default:
- printf("Unimplemented option %c\n\n",*s);
- exit();
- break;
- }
- switch(option)
- { case 'C':
- case 'T':
- termcomp();
- break;
- case 'P':
- case 'U':
- ckfile(argc);
- termcomp();
- while(argc--)
- { printf("\nSending %s\n",*argv);
- pdp10(*argv++);
- }
- termcomp();
- break;
- case 'R':
- ckfile(argc);
- while(argc--)
- { printf("\nReceiving %s\n",*argv);
- readfile(*argv++);
- }
- break;
- case 'S':
- ckfile(argc);
- while(argc--)
- { printf("\nSending %s\n",*argv);
- sendfile(*argv++);
- }
- break;
- }
- if(hangup)
- outp(MODEMCP3,0x00);
- else
- { do
- { printf("\nHangup : Y(es), N(o) ? ");
- hangup = tolower(getchar());
- printf("\n");
- }
- while((hangup != 'y') && (hangup != 'n'));
- if(hangup == 'y')
- outp(MODEMCP3,0x00);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-