mat@emcard.UUCP (Mat Waites) (01/03/89)
I had pretty good response for the source code to this terminal program, so I am posting it. It is for the C64 and Power C compiler. Note that two of the files are for Unix, not for the C64. I hope to add Punter protocol to this as I have time. #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # ReadMe # asctocbm.c # cbmtoasc.c # cmast.c # dial.c # dos.c # menus.c # screen.c # xmodem.c # sed 's/^X//' << 'SHAR_EOF' > ReadMe && XThis is the first UseNet distribution of the Cmaster terminal program. X XThese are the files in the distribution: X Xasctocbm.c Xcbmtoasc.c Xcmast.c Xdial.c Xdos.c Xmenus.c Xscreen.c Xxmodem.c X X Xasctocbm.c and cbmtoasc.c are unix utilities to convert to Commodore ascii Xand vice versa. X XThe rest are Power C source code for the terminal. X Xcmast.c - main program Xdial.c - hayes dialer Xdos.c - dos support, including serial port routines Xmenus.c - menu for setting parameters Xscreen.c - screen access routines, color, cursor positioning, etc. Xxmodem.c - xmodem protocol X XWhen linking, you will have to link libraries after linking 3 or so files, Xand then continue with the linking process. The linker cannot hold all of the Xreferences in one pass. X XHave fun and send me comments. X XW Mat Waites Xgatech!emcard!mat X8-5 ET: (404) 727-7197 SHAR_EOF chmod 0664 ReadMe || echo "restore of ReadMe fails" sed 's/^X//' << 'SHAR_EOF' > asctocbm.c && X/* asctocbm.c - convert real ascii to cbm ascii */ X X#include <stdio.h> X#include <strings.h> X#include <ctype.h> X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X FILE *infile, *outfile; X char *strchr(); X int i; X char nambuf[30]; X char stripped[30]; X X if(argc > 1) X { X for(i=1; i<argc; i++) X { X strcpy(stripped, argv[i]); X if(strchr(stripped, '.')) X { X *strchr(stripped, '.') = '\0'; X } X fprintf(stderr, "Translating %s\n", stripped); X X strcpy(nambuf, stripped); X strcat(nambuf, ".c"); X if(infile = fopen(nambuf, "r")) X { X strcpy(nambuf, stripped); X strcat(nambuf, ".cbm"); X if(outfile = fopen(nambuf, "w")) X { X convert(infile, outfile); X fclose(outfile); X } X else X { X fprintf(stderr, "Couldn't open %s\n", nambuf); X } X fclose(infile); X } X else X { X fprintf(stderr, "Couldn't open %s\n", nambuf); X } X } X } X else X { X convert(stdin, stdout); X } X X} X Xconvert(infile, outfile) XFILE *infile, *outfile; X{ X int c, a; X X while((c=getc(infile)) != EOF) X { X if(c == '\n') X { X a = '\r'; X } X else if(c >= 'a' && c <= 'z') X { X a = c - 'a' + 'A'; X } X else if(c >= 'A' && c <= 'Z') X { X a = c - 'A' + 193; X } X else if(c == '~') X { X a = 175; X } X else if(c == '{') X { X a = 219; X } X else if(c == '}') X { X a = 221; X } X else if(c == '|') X { X a = 223; X } X else if(isprint(c)) X { X a = c; X } X else if(c == 0) X { X continue; X } X else X { X fprintf(outfile, "{{%d}}", c); X continue; X } X putc(a, outfile); X } X} X SHAR_EOF chmod 0660 asctocbm.c || echo "restore of asctocbm.c fails" sed 's/^X//' << 'SHAR_EOF' > cbmtoasc.c && X/* cbmtoasc.c - convert cbm ascii to real ascii */ X X#include <stdio.h> X#include <strings.h> X#include <ctype.h> X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X FILE *infile, *outfile; X char *strchr(); X int i; X char nambuf[30]; X char stripped[30]; X X if(argc > 1) X { X for(i=1; i<argc; i++) X { X strcpy(stripped, argv[i]); X if(strchr(stripped, '.')) X { X *strchr(stripped, '.') = '\0'; X } X fprintf(stderr, "Translating %s\n", stripped); X X strcpy(nambuf, stripped); X strcat(nambuf, ".cbm"); X if(infile = fopen(nambuf, "r")) X { X strcpy(nambuf, stripped); X strcat(nambuf, ".c"); X if(outfile = fopen(nambuf, "w")) X { X convert(infile, outfile); X fclose(outfile); X } X else X { X fprintf(stderr, "Couldn't open %s\n", nambuf); X } X fclose(infile); X } X else X { X fprintf(stderr, "Couldn't open %s\n", nambuf); X } X } X } X else X { X convert(stdin, stdout); X } X X} X X Xconvert(infile, outfile) XFILE *infile, *outfile; X{ X int c, a; X X while((c=getc(infile)) != EOF) X { X if(c == '\r') X { X a = '\n'; X } X else if(c >= 'A' && c <= 'Z') X { X a = c - 'A' + 'a'; X } X else if(c >= 193 && c <= 218) X { X a = c - 193 + 'A'; X } X else if(c == 175) X { X a = '~'; X } X else if(c == 219) X { X a = '{'; X } X else if(c == 221) X { X a = '}'; X } X else if(c == 223) X { X a = '|'; X } X else if(isprint(c)) X { X a = c; X } X else if(c == 0) X { X continue; X } X else X { X /* fprintf(outfile, "{{%d}}", c); */ X continue; X } X putc(a, outfile); X } X} X SHAR_EOF chmod 0660 cbmtoasc.c || echo "restore of cbmtoasc.c fails" sed 's/^X//' << 'SHAR_EOF' > cmast.c && X/* cmast.c - main for cmaster */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X X#define DEFBAUD 1200 X#define DEFDRIVE 8 X#define DEFMODE 1 X#define DEFLF 0 X#define DEFFLOW 0 X X/* globals */ Xint echo; Xint baud; Xint bpchar; Xint stopbits; Xint parity; Xint ddrive; Xint done; Xint asciimode; Xint autolf; Xint flowcont; X X/* main() - main program for cmast */ Xmain(argc, argv) Xunsigned argc; Xchar *argv[]; X{ X int kbchar, serchar; X int outch; X char *qtsw = 0x00d4; X X /* initialization */ X done = 0; X echo = 0; X baud = DEFBAUD; X bpchar = 8; X stopbits = 1; X parity = 0; /* 0 - none */ X ddrive = DEFDRIVE; X asciimode = DEFMODE; X autolf = DEFLF; X flowcont = DEFFLOW; X X /* check for baud rate parameter */ X if(argc > 1) X { X baud = atoi(argv[1]); X switch(baud) X { X case 300: X case 450: X case 1200: X break; X default: X baud = DEFBAUD; X break; X } X } X X /* open files */ X openkb(); X openserial(); X setserial(baud, bpchar, X stopbits, parity); X X /* set colors */ X setborder(15); X setbg(0); X setfg(1); X X initscr(); X titlescr(); X sleep(2); X X erase(); X move(0, 0); X cursoron(); X updatecursor(); X X /* main loop */ X while(!done) X { X X /* check for <C=> key */ X if(chkstop()) X { X cursoroff(); X menu(); X updatecursor(); X cursoron(); X } X X /* check keyboard */ X while(charsinq() > 0 && !done) X { X kbchar = getkb(); X X if(kbchar >= 133 && X kbchar <= 140) X { X /* function keys */ X putfunct(kbchar); X } X else X { X /* non-function keys */ X if(echo) /* local echo */ X { X if(isprint(kbchar) || X iscntrl(kbchar)) X { X putchar(kbchar); X updatecursor(); X } X } X outch = cbmtoasc(kbchar); X if(outch) X { X putserial(outch); X } X } X } X X /* check serial port */ X if(!done) X { X while((serchar=getserial()) >= 0) X { X if(asciimode) X { X /* mask to 7 bits */ X serchar &= 0x7f; X switch(serchar) X { X case 7: /* BEL */ X break; X case 8: /* BS */ X putchar(157); X break; X case 9: /* TAB */ X putchar(' '); X putchar(' '); X break; X case 10: /* LF */ X putchar(17); X break; X case 12: /* FF */ X erase(); X break; X case 13: /* CR */ X putchar(13); X if(!autolf) X { X putchar(145); /* move up */ X } X break; X default: X outch=asctocbm(serchar); X if(outch) X { X putchar(outch); X } X else /* unexpected char */ X { X /*printf("[%d]", serchar);*/ X /*putchar(serchar);*/ X } X break; X } X } X else X { X putchar(serchar); X } X *qtsw = 0; X updatecursor(); X if(charsinq() > 0 || chkstop()) X { X break; X } X } X } X } X X /* shut down */ X cursoroff(); X erase(); X closekb(); X closeserial(); X move(23, 0); X} X X/* cmaster support routines */ X X/* titlescr() - initial display */ Xtitlescr() X{ X erase(); X center(5, "Cmaster Terminal"); X center(15, "Press <C=> for menu"); X} X X/* cbmtoasc() - convert cbm to ascii */ Xcbmtoasc(cbmchar) Xint cbmchar; X{ X if(!asciimode) X { X return(cbmchar); X } X X /* lower case */ X if(cbmchar >= 65 && cbmchar <= 90) X { X return(cbmchar + 32); X } X X /* upper case */ X if(cbmchar >= 193 && cbmchar <= 218) X { X return(cbmchar - 128); X } X X if(cbmchar == 20) /* backspace */ X { X return(8); X } X X return(cbmchar); X} X X/* asctocbm() - convert ascii to cbm */ Xasctocbm(ascchar) Xint ascchar; X{ X if(!asciimode) X { X return(ascchar); X } X X /* upper case */ X if(ascchar >= 65 && ascchar <= 90) X { X return(ascchar + 128); X } X X /* lower case */ X if(ascchar >= 97 && ascchar <= 122) X { X return(ascchar - 32); X } X X if(ascchar >= 32 && ascchar <= 64) X { X return(ascchar); X } X X if(ascchar >= 91 && ascchar <= 95) X { X return(ascchar); X } X X return 0; X} X X/* putserstr() - put string to port */ Xputserstr(str) Xchar *str; X{ X while(*str) X { X putserial(cbmtoasc((int)*str)); X str++; X } X} X Xstatic char *funcstr[8] = X { X "Function Key 1\n", X "Function Key 3\n", X "Function Key 5\n", X "Function Key 7\n", X "Function Key 2\n", X "Function Key 4\n", X "Function Key 6\n", X "Function Key 8\n" X }; X X/* putfunct() - put function key string */ Xputfunct(key) Xint key; X{ X unsigned lockey; X X if(key < 133 || key > 140) X { X return; X } X X lockey = key - 133; X X putserstr(funcstr[lockey]); X X} X/* end of file */ SHAR_EOF chmod 0664 cmast.c || echo "restore of cmast.c fails" sed 's/^X//' << 'SHAR_EOF' > dial.c && X/* dial.c - dial routines for cmaster */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X#include <strings.h> X X#define DIALTIME 20 X#define WAITTIME 5 X#define NUMTRIES 5 X Xchar *prefix = "atdt"; Xchar *suffix = "\r"; Xchar *attnstr = "+++"; Xchar *hangupstr = "ath\r"; Xchar *initstr = "ats7=45e0q0v1x4\r"; X Xchar *moddial(); X Xstatic int tmo; X X/* dial() - main dialing menu */ Xdial() X{ X int len, i, nt, wt, dt; X char numbuf[21]; X char *msg; X X nt = NUMTRIES; X wt = WAITTIME; X dt = DIALTIME; X X center(1, "Cmaster Dialing Menu"); X X putmodstr(initstr); X sleep(1); X while(getserial() >= 0) X { X } X X move(5, 5); X printf("Number: "); X len = getstring(numbuf, 20); X if(len <= 0) X { X return(0); X } X X move(8, 5); X printf("Trying %2d times:\n", nt); X X for(i=1; i<=nt; i++) X { X move(10, 5); X printf("Dialing %s try %2d\n", X numbuf, i); X while(getserial() >= 0) X { X } X msg = moddial(numbuf, dt); X X if(atoi(msg) > 0) X { X move(12, 5); X printf("Connected!\n"); X sleep(1); X return(1); X } X else X { X move(14, 5); X printf("Dial failed - %s\n", msg); X if(strcmp(msg, "ABORT") == 0) X { X sleep(3); X return(0); X } X if(i <= nt) /* tries left? */ X { X sleep(wt); X } X } X } X return(0); X} X X/* moddial() - main dialing menu */ Xstatic char *moddial(numstr, dtime) Xchar *numstr; Xint dtime; X{ X int i, skip, timer, modch, rc; X char s[50], number[40], rcbuf[60]; X char *n; X X s[0] = '\0'; X strcpy(s, prefix); X X /* clean up number */ X i = 0; X skip = 0; X n = numstr; X while (*n) X { X if(*n == '\\' && !skip) X { X skip++; X n++; X continue; X } X if(!index("-() ", *n) || skip) X number[i++] = *n; X n++; X skip = 0; X } X number[i] = '\0'; X X strcat(s, number); X strcat(s, suffix); X X putmodstr(s); X X rc=0; X timer=0; X rcbuf[0] = '\0'; X X while(rc < 59 && timer < dtime) X { X modch = getmodch(1); X if(!tmo) X { X /* ignore LF */ X if(modch == 0x0a) X { X continue; X } X X /* ignore leading CR */ X if(modch == 0x0d) X { X if(rc == 0) X { X continue; X } X modch = '!'; X } X X rcbuf[rc] = modch; X rcbuf[rc+1] = '\0'; X rc++; X } X else X { X timer++; X } X X /* printf("answer is '%s'\n", rcbuf); */ X X if(strcmp(rcbuf, "connect!") == 0) X return("300"); X X if(strcmp(rcbuf, "connect 1200!") == 0) X return("1200"); X X if(strcmp(rcbuf, "busy!") == 0) X return("BUSY"); X X if(strcmp(rcbuf, "voice!") == 0) X return("VOICE"); X X if(strcmp(rcbuf, "no carrier!") == 0) X return("NO CARRIER"); X X if(chkstop()) X { X /* aborted */ X putmodstr("\r"); X sleep(1); X while(getserial() >= 0) X { X } X return("ABORT"); X } X X } X X /* didn't connect */ X putmodstr("\r"); X sleep(1); X while(getserial() >= 0) X { X } X return("ERROR"); X} X X/* modhangup() - hangup modem */ Xmodhangup() X{ X char *match; X X sleep(2); X putmodstr(attnstr); X sleep(2); X putmodstr(hangupstr); X sleep(1); X while(getserial() >= 0) X { X } X} X X/* putmodstr() - put string to modem */ Xstatic putmodstr(str) Xchar *str; X{ X while(*str) X { X putserial(*str); X str++; X } X} X X/* getmodch() - get char w/timeout */ Xstatic getmodch(timlen) Xint timlen; X{ X int serchar; X X tmo = 0; X setclock((unsigned)0); /* start timer */ X X for(;;) X { X X serchar = getserial(); X if(serchar >= 0) X { X return(serchar); X } X X if(getclock() >= timlen) X { X tmo = 1; X return 0; X } X } X} X X/* end of file */ SHAR_EOF chmod 0664 dial.c || echo "restore of dial.c fails" sed 's/^X//' << 'SHAR_EOF' > dos.c && X/* dos2.c - operating system stuff: X disk support X serial i/o X kb i/o X timers */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X X/* 5-9 may be used with "basic" open */ X#define KB 5 X#define RS 6 X X/* kludge for reliable 1200 baud */ X#define KLUDGE 40 X X/* flow control params */ X#define FLOWON 30 X#define FLOWOFF 128 X#define XON 17 X#define XOFF 19 X X/* kernel routines */ X#define CHKIN 0xffc6 X#define GETIN 0xffe4 X#define TKSA 0xff96 X#define ACPTR 0xffa5 X#define TALK 0xffb4 X#define UNTLK 0xffab X X/* input and output serial buffers */ Xstatic char inbuf[256], otbuf[256]; X X/* flow control turned on? */ Xchar flowact = 1; X X/* serial interface functions */ X X/* openserial() - open serial port */ Xopenserial() X{ X short *ribuf = 0x00f7; X short *robuf = 0x00f9; X X /* open serial port */ X open(RS, 2, 0, ""); X X /* move pointers to buffers */ X *ribuf = inbuf; X *robuf = otbuf; X} X X/* closeserial() - close serial port */ Xcloseserial() X{ X close(RS); X} X X/* 300, 450, 1200 implemented */ X Xstatic short hibyte[3] = { 6, 4, 1}; Xstatic short lobyte[3] = {68, 12, 61}; X X/* setserial() - set serial port */ Xsetserial(bd, bpc, sb, par) Xint bd, bpc, sb, par; X{ X short *m51ajb = 0x0295; X short *baudof = 0x0299; X char *m51ctr = 0x0293; X char *m51cdr = 0x0294; X char *bitnum = 0x0298; X unsigned indx; X X switch(bd) X { X case 300: X indx = 0; X break; X case 450: X indx = 1; X break; X case 1200: X indx = 2; X break; X default: /* default to 300 baud */ X indx = 0; X break; X } X X /* set baud rate */ X *m51ajb = 256 * hibyte[indx] + X lobyte[indx]; X *baudof = (*m51ajb)*2 + 200; X X /* stopbits */ X if(sb < 1 || sb > 2) X { X sb = 1; X } X sb--; X X /* bits per char */ X if(bpc < 5 || bpc > 8) X { X bpc = 8; X } X *bitnum = (char)(bpc + 1); X bpc = 8 - bpc; X X /* parity */ X if(par < 0 || par > 7) X { X par = 0; X } X X /* put bpc, sb, and par in regs */ X *m51ctr = (char)((bpc << 5) X | (sb << 7)); X *m51cdr = (char)(par << 5); X} X X/* setflow() - set flowcontrol */ Xsetflow(mode) Xint mode; X{ X flowact = mode; X} X X X/* getserial() - char from serial port */ Xgetserial() X{ X int ch; X char diff; X static char *rsstat = 0x0297; X static char *ridbe = 0x029b; X static char *ridbs = 0x029c; X static char flowing = 1; X X ch = getonechar(RS); X X /* check for empty buffer */ X if((*rsstat & 0x08) == 0x08) X { X return -1; X } X else X { X if(flowact) X { X /* check for flow control */ X if(*ridbs > *ridbe) X { X diff = *ridbs - *ridbe; X } X else X { X diff = *ridbe - *ridbs; X } X X if(flowing) X { X if(diff > FLOWOFF) X { X putserial(XOFF); X flowing = 0; X } X } X else X { X if(diff < FLOWON) X { X putserial(XON); X flowing = 1; X } X } X } X return ch; X } X} X X/* putserial() - char to serial port */ Xputserial(ch) Xchar ch; X{ X int i; X X putc(ch, RS); X X /* delay loop for 1200 baud kludge */ X for(i=0; i<KLUDGE; i++) X { X } X} X X X/* keyboard interface functions */ X X/* openkb() - open keyboard */ Xopenkb() X{ X char *rptflg = 0x028a; X X open(KB, 0, 0, ""); X /* let the keyboard repeat */ X *rptflg = 0x80; X} X X/* closekb() - close keyboard */ Xclosekb() X{ X close(KB); X} X X/* getkb() - get char from keyboard */ Xgetkb() X{ X return getonechar(KB); X} X X/* charsinq() - # available kb chars */ Xcharsinq() X{ X char *ndx = 0x00c6; X X return (int)*ndx; X} X X/* chkstop() - check for <C=> key */ Xchkstop() X{ X char *shflag = 0x028d; X X return(*shflag == 0x02); X} X X/* getonechar() - get char from chan */ Xstatic getonechar(channel) Xint channel; X{ X char ac, xc, yc; X X xc = (char)channel; X sys(CHKIN, &ac, &xc, &yc); X sys(GETIN, &ac, &xc, &yc); X return(int)ac; X} X X X/* disk i/o functions */ X X#define SADDR 0x6f X X/* diskerr() - read error channel */ Xchar *diskerr(disk) Xint disk; X{ X int cc; X char ac, xc, yc; X static char msgbuf[41]; X char *mp; X char *second = 0x00b9; X char *status = 0x0090; X X /* tell drive to talk */ X ac = (char)disk; X sys(TALK, &ac, &xc, &yc); X X /* tell it what to talk about */ X ac = (char)SADDR; X *second = SADDR; X sys(TKSA, &ac, &xc, &yc); X X /* read in the response */ X mp = msgbuf; X for(;;) X { X /* get byte from bus in acc */ X sys(ACPTR, &ac, &xc, &yc); X X if(ac == '\r') X { X break; X } X *mp = ac; X mp++; X } X *mp = '\0'; X X /* tell drive to shut up */ X sys(UNTLK, &ac, &xc, &yc); X X return(msgbuf); X} X X X/* timer functions */ X Xunsigned getclock(); X X/* sleep() - sleep for seconds */ Xsleep(usecs) Xunsigned usecs; X{ X setclock((unsigned)0); X X while(getclock() < usecs) X { X } X} X Xstruct clock /* struct matches CIA */ X { X char tenths; X char seconds; X char minutes; X char hours; X }; X X/* setclock() - set timer clock */ Xsetclock(usecs) Xunsigned usecs; X{ X unsigned bsecs; X struct clock *clock1 = 0xdc08; X char *c1mode = 0xdc0f; X X *c1mode &= 0x7f; /* mode is clock */ X X if(usecs > 59) usecs = 59; X X /* convert secs to bcd */ X bsecs = usecs%10 | ((usecs/10)<<4); X X clock1->hours = 0; X clock1->minutes = 0; X clock1->seconds = (char)bsecs; X clock1->tenths = 0; /* free clock */ X} X X/* getclock() - get current clock secs */ Xunsigned getclock() X{ X unsigned usecs; X char junk; X struct clock *clock1 = 0xdc08; X X junk = clock1->seconds; X usecs = (junk & 0x0f) + X 10 * (junk >> 4); X X junk = clock1->tenths; /* free clock */ X X return usecs; X} X X/* end of file */ SHAR_EOF chmod 0664 dos.c || echo "restore of dos.c fails" sed 's/^X//' << 'SHAR_EOF' > menus.c && X/* menus.c - menu routines */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X X/* globals */ Xextern int done; Xextern int echo; Xextern int baud; Xextern int bpchar; Xextern int stopbits; Xextern int parity; Xextern int ddrive; Xextern int asciimode; Xextern int autolf; Xextern int flowcont; X Xchar *parval(); Xchar *dupval(); Xchar *modeval(); X X/* menu() - main menu */ Xmenu() X{ X int mdone = 0; X int kbchar; X int ycoord; X char fname[21]; X X /* draw menu */ X erase(); X while(!mdone) X { X center(1, "Cmaster Main Menu"); X X ycoord = 4; X move(ycoord++, 5); X printf("(Q)uit"); X ycoord++; X X move(ycoord++, 5); X printf("(A)utodial"); X move(ycoord++, 5); X printf("(H)angup"); X move(ycoord++, 5); X printf("(U)pload"); X move(ycoord++, 5); X printf("(D)ownload"); X move(ycoord++, 5); X printf("(N)umber of drive %1d", X ddrive); X ycoord++; X X move(ycoord++, 5); X printf("(M)ode %10s", X modeval(asciimode)); X move(ycoord++, 5); X printf("(L)inefeeds %10s", X lfval(autolf)); X move(ycoord++, 5); X printf("(T)og Duplex %10s", X dupval(echo)); X move(ycoord++, 5); X printf("(F)low Control %10s", X boolval(flowcont)); X ycoord++; X X move(ycoord++, 5); X printf("(B)aud %4d", X baud); X move(ycoord++, 5); X printf("(C)har length %1d", X bpchar); X move(ycoord++, 5); X printf("(P)arity %10s", X parval(parity)); X move(ycoord++, 5); X printf("(S)top bits %1d", X stopbits); X ycoord++; X X move(ycoord, 5); X printf("(R)eturn"); X X /* wait for keypress */ X while(charsinq() == 0) X { X } X kbchar = getkb(); X X /* switch on key */ X switch(kbchar) X { X case 'q': /* quit */ X case 'Q': X done = 1; X mdone = 1; X break; X case 'a': /* autodial */ X case 'A': X erase(); X if(dial()) X { X mdone = 1; X } X erase(); X break; X case 'h': /* hangup */ X case 'H': X modhangup(); X break; X case 'u': /* upload */ X case 'U': X erase(); X center(1, "Cmaster Upload Menu"); X move(5, 5); X printf("Filename:"); X if(getstring(fname, 16)) X { X erase(); X setserial(baud, 8, 1, 0); X setflow(0); X sendfile(fname, ddrive); X setserial(baud, bpchar, X stopbits, parity); X setflow(flowcont); X printf("Press key:"); X while(charsinq() == 0) X { X } X kbchar = getkb(); X mdone = 1; X } X erase(); X break; X case 'd': /* download */ X case 'D': X erase(); X center(1, "Cmaster Download Menu"); X move(5, 5); X printf("Filename:"); X if(getstring(fname, 15)) X { X erase(); X setserial(baud, 8, 1, 0); X setflow(0); X recvfile(fname, ddrive); X setserial(baud, bpchar, X stopbits, parity); X setflow(flowcont); X printf("Press key:"); X while(charsinq() == 0) X { X } X kbchar = getkb(); X mdone = 1; X } X erase(); X break; X case 'n': /* change active drive */ X case 'N': X if(ddrive == 8) X { X ddrive = 9; X } X else X { X ddrive = 8; X } X break; X case 'b': /* cycle baud */ X case 'B': X switch(baud) X { X case 300: X baud = 450; X break; X case 450: X baud = 1200; X break; X case 1200: X baud = 300; X break; X default: X baud = 300; X break; X } X setserial(baud, bpchar, X stopbits, parity); X break; X case 'c': /* bits per char */ X case 'C': X bpchar++; X if(bpchar > 8) X { X bpchar = 7; X } X setserial(baud, bpchar, X stopbits, parity); X break; X case 'p': /* parity */ X case 'P': X if(parity == 0) X { X parity = 1; X } X else X { X parity += 2; X if(parity > 7) X { X parity = 0; X } X } X setserial(baud, bpchar, X stopbits, parity); X break; X case 's': /* stopbits (1 or 2) */ X case 'S': X stopbits++; X if(stopbits > 2) X { X stopbits = 1; X } X setserial(baud, bpchar, X stopbits, parity); X break; X case 'm': /* mode */ X case 'M': X asciimode = !asciimode; X break; X case 'l': /* auto LF */ X case 'L': X autolf = !autolf; X break; X case 'f': /* flow control */ X case 'F': X flowcont = !flowcont; X setflow(flowcont); X break; X case 't': /* toggle local echo */ X case 'T': X echo = !echo; X break; X case 'r': /* return to terminal */ X case 'R': X mdone = 1; X break; X default: X break; X } X } X erase(); X} X X/* parval() - return parity string */ Xstatic char *parval(par) Xint par; X{ X switch(par) X { X case 0: X return("Disabled"); X case 1: X return("Odd"); X case 3: X return("Even"); X case 5: X return("Mark"); X case 7: X return("Space"); X default: X return("Invalid"); X } X} X X/* dupval() - return duplex string */ Xstatic char *dupval(ech) Xint ech; X{ X if(ech) X { X return("Half"); X } X else X { X return("Full"); X } X} X X/* modeval() - return display mode string */ Xstatic char *modeval(mode) Xint mode; X{ X if(mode) X { X return("ASCII"); X } X else X { X return("Graphics"); X } X} X X/* lfval() - return linefeed mode string */ Xstatic char *lfval(mode) Xint mode; X{ X if(mode) X { X return("Auto LF"); X } X else X { X return("No Auto LF"); X } X} X X/* boolval() - return On/Off string */ Xstatic char *boolval(mode) Xint mode; X{ X if(mode) X { X return("On"); X } X else X { X return("Off"); X } X} X X/* end of file */ SHAR_EOF chmod 0664 menus.c || echo "restore of menus.c fails" sed 's/^X//' << 'SHAR_EOF' > screen.c && X/* screen.c - screen routines */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X X#define PLOT 0xfff0 X X/* initscr() - initialize cursor, etc */ Xinitscr() X{ X int i; X char *tmp; X char *sprite0 = 0x07f8; X char *spcol0 = 0xd027; X X /* cursor sprite is defined in X basic input buffer */ X X /* put sprite 0 at $0200 */ X *sprite0 = 8; X X /* set color to white */ X *spcol0 = 1; X X /* first, set sprite to all bgd */ X for(i=0; i<64; i++) X { X tmp = 0x0200 + i; X *tmp = 0; X } X X /* fill in fgd of sprite */ X for(i=7; i<8; i++) X { X tmp = 0x0200 + 3*i; X *tmp = 0xff; X } X} X X/* cursoron() - turn on cursor */ Xcursoron() X{ X char *enab = 0xd015; X X *enab = 0x01; /* turn on sprite 0 */ X} X X/* cursoroff() - turn off cursor */ Xcursoroff() X{ X char *enab = 0xd015; X X *enab = 0x00; /* turn off sprite 0 */ X} X X/* updatecursor() - correct sprite loc */ Xupdatecursor() X{ X char *cury, *curx; X char *ypos, *xpos; X char *highx; X int sy, sx; X X cury = 0x00d6; X curx = 0x00d3; X xpos = 0xd000; X ypos = 0xd001; X highx = 0xd010; X X /* compute cursor screen location */ X sy = (int)*cury; X sx = (int)*curx; X if(sx > 39) /* check for wrap */ X { X sx -= 40; X } X sy = sy << 3; X sx = sx << 3; X sy += 50; X sx += 24; X X *ypos = (char)sy; X *xpos = (char)sx; X if(sx > 255) X { X *highx = 0x01; X } X else X { X *highx = 0x00; X } X} X X/* erase() - clear screen */ Xerase() X{ X putchar((char)147); X} X X/* standout() - reverse video */ Xstandout() X{ X putchar((char)18); X} X X/* standend() - standard video */ Xstandend() X{ X putchar((char)146); X} X X/* center() - center string on line */ Xcenter(y, str) Xint y; Xchar *str; X{ X int x; X X x = 20 - strlen(str)/2; X move(y, x); X printf(str); X} X X/* move() - cursor positioning */ Xmove(y, x) Xint y, x; X{ X char ac, xc, yc; X X /* check for bozo parameters */ X if(y > 24) y = 24; X if(y < 0) y = 0; X if(x > 79) x = 79; X if(x < 0) x = 0; X X xc = (char)y; X yc = (char)x; X X sys(PLOT, &ac, &xc, &yc); X} X X/* setborder() - set border color */ Xsetborder(color) Xint color; X{ X char *border = 0xd020; X X *border = (char)color; X} X X/* setbg() - set background color */ Xsetbg(color) Xint color; X{ X char *bg = 0xd021; X X *bg = (char)color; X} X X/* setfg() - set foreground color */ Xsetfg(color) Xint color; X{ X static char colchars[16] = X { X 144, /* black */ X 5, /* white */ X 28, /* red */ X 159, /* cyan */ X 156, /* purple */ X 32, /* green */ X 31, /* blue */ X 158, /* yellow */ X 129, /* orange */ X 149, /* brown */ X 150, /* lt. red */ X 151, /* grey 1 */ X 152, /* grey 2 */ X 153, /* lt. green */ X 154, /* lt. blue */ X 155 /* grey 3 */ X }; X X if(color < 0) color = 0; X if(color > 15) color = 15; X X putchar(colchars[color]); X} X X/* getstring() - get string with echo */ Xgetstring(s, len) Xchar *s; Xint len; X{ X int done, kbchar, ll; X char *ls; X X done = 0; X ll = 0; X ls = s; X *ls = '\0'; X updatecursor(); X cursoron(); X X while(!done) X { X /* check for <C=> key */ X if(chkstop()) X { X cursoroff(); X return(0); X } X if(charsinq() > 0) X { X kbchar = getkb(); X /* only printable characters */ X /* if(isprint(kbchar)) */ X if((kbchar >= 32 && kbchar <= 95) || X (kbchar >= 193 && kbchar <= 218)) X { X *ls = (char)kbchar; X ls++; X ll++; X *ls = '\0'; X putchar((char)kbchar); X updatecursor(); X if(ll >= len) X { X done = 1; X } X } X else if(kbchar == 13) X { X done = 1; X } X else if(kbchar == 20) X { X /* backspace */ X if(ll > 0) X { X ll--; X ls--; X *ls = '\0'; X putchar((char)20); X updatecursor(); X } X } X } X } X cursoroff(); X return(strlen(s)); X} X X/* end of file */ SHAR_EOF chmod 0664 screen.c || echo "restore of screen.c fails" sed 's/^X//' << 'SHAR_EOF' > xmodem.c && X/* xmodem.c - xmodem protocol */ X/* W Mat Waites - Sept 1988 */ X X#include <stdio.h> X X/* number of retries, timeouts */ X#define RETRY 5 X#define TOUT 2 X#define BTOUT 10 X X/* protocol characters */ X#define SOH 0x01 X#define EOT 0x04 X#define ACK 0x06 X#define NAK 0x15 X#define CAN 0x18 X X#define RECSIZE 128 X Xchar *diskerr(); X Xint rec; Xint tries; Xint timeout; X X/* buffer for data in/out */ Xchar buffer[132]; X X/* sendfile() - send file via xmodem */ Xsendfile(fname, disk) Xchar *fname; Xint disk; X{ X int st; X int ch; X char errbuf[41]; X char locname[21]; X char *status = 0x0090; X FILE dfile; X X rec = 1; X X strcpy(locname, fname); X strcat(locname, ",r"); X X /* attempt to open file for read */ X device(disk); X dfile = fopen(locname); X X /* check for disk error */ X strcpy(errbuf, diskerr(disk)); X st = atoi(errbuf); X if(st >= 20) X { X close(dfile); X showerr(fname, errbuf); X return(0); X } X X printf("%s opened\n", fname); X X /* clear input buffer */ X while(getserial() >= 0) X { X } X X tries = RETRY; X X for(;;) X { X printf("Synching...\n"); X if(chkstop()) X { X close(dfile); X return(0); X } X ch = getchtmo(BTOUT); X if(timeout) X { X printf("Timeout\n"); X tries--; X if(tries > 0) X { X continue; X } X close(dfile); X return(0); X } X if(ch == NAK) X { X break; X } X printf("Strange char [%02x]\n", ch); X } X X printf("Synched\n"); X X /* send the file */ X while(fillbuf(dfile, buffer)) X { X if(chkstop()) X { X close(dfile); X return(0); X } X if(!txrec(buffer)) X { X close(dfile); X return(0); X } X } X X /* tell 'em we're done */ X putserial(EOT); X for(;;) X { X ch = getchtmo(TOUT); X if(timeout) X { X putserial(EOT); X } X else X { X if(ch == ACK) X { X printf("sent EOT\n\n"); X break; X } X } X } X X close(dfile); X printf("%s transferred\n\n", fname); X return(1); X} X X/* recvfile() - recv file via xmodem */ Xrecvfile(fname, disk) Xchar *fname; Xint disk; X{ X int st; X int ch; X int i; X char r1, r2, dt; X int response; X char rchk; X char locname[21]; X char errbuf[41]; X unsigned chksum; X FILE dfile; X X rec = 1; X X strcpy(locname, fname); X strcat(locname, ",w"); X X /* attempt to open file for write */ X device(disk); X dfile = fopen(locname); X X /* check for disk error */ X strcpy(errbuf, diskerr(disk)); X st = atoi(errbuf); X if(st >= 20) X { X close(dfile); X showerr(fname, errbuf); X return(0); X } X X printf("%s opened\n", fname); X X /* clear input queue */ X while(getserial() >= 0) X { X } X X /* transfer file */ X response = NAK; X for(;;) X { X /* get a record */ X printf("Record %3d ", rec); X tries = RETRY; X for(;;) X { X if(chkstop()) X { X close(dfile); X return(0); X } X /* shake hands */ X putserial(response); X /* get 1st char */ X ch = getchtmo(TOUT); X if(timeout) X { X tries--; X if(tries > 0) X { X continue; /* try again */ X } X printf("Can't sync w/sender\n"); X X close(dfile); X return(0); X } X if(ch == SOH) /* beg of data */ X { X break; X } X else if(ch == EOT) /* done */ X { X printf("got EOT\n\n"); X close(dfile); X putserial(ACK); X printf("%s transferred\n\n", X fname); X return(1); X } X else if(ch == CAN) /* cancelled */ X { X close(dfile); X printf("Transfer cancelled!\n"); X return(0); X } X else X { X printf("Strange char [%02x]\n", ch); X gobble(); /* clear any weirdness */ X response = NAK; /* and try again */ X } X } X X response = NAK; X r1 = getchtmo(TOUT); /* record number */ X if(timeout) X { X printf("TMO on recnum\n"); X continue; X } X /* get 1's comp record number */ X r2 = getchtmo(TOUT); X if(timeout) X { X printf("TMO on comp recnum\n"); X continue; X } X X /* get data */ X chksum = 0; X for(i=0; i<RECSIZE; i++) X { X dt = getchtmo(TOUT); X if(timeout) X { X break; X } X buffer[i] = dt; X chksum += dt; X chksum &= 0xff; X } X /* check for data timeout */ X if(timeout) X { X printf("TMO on data\n"); X continue; X } X X /* get checksum */ X rchk = getchtmo(TOUT); X if(timeout) X { X printf("TMO on checksum\n"); X continue; X } X X /* compare rec num and 1's comp */ X if((~r1 & 0xff) != (r2 & 0xff)) X { X printf("Bad recnum's\n"); X continue; X } X X /* compare checksum and local one */ X if(rchk != chksum) X { X printf("Bad checksum\n"); X response = NAK; X continue; X } X X if((r1 ==(rec-1) & 0xff)) /* dupe */ X { X printf("Duplicate record\n"); X response = ACK; X continue; X } X X if(r1 != (rec & 0xff)) X { X printf("Record numbering error\n"); X close(dfile); X return(0); X } X X rec++; X X /* write data to file */ X for(i=0; i<RECSIZE; i++) X { X putc(buffer[i], dfile); X } X X printf("OK\n"); X response = ACK; X } X} X X/* showerr() - display disk error */ Xshowerr(fname, errmsg) Xchar *fname; Xchar *errmsg; X{ X erase(); X move(11, 5); X printf("Error accessing %s", fname); X move(13, 5); X printf("[%s]", errmsg); X move(20, 5); X} X X/* getchtmo() - get char w/timeout */ Xgetchtmo(timlen) Xint timlen; X{ X int serchar; X X timeout = 0; X setclock((unsigned)0); /* start timer */ X X for(;;) X { X X serchar = getserial(); X if(serchar >= 0) X { X return(serchar); X } X X if(getclock() >= timlen) X { X timeout = 1; X return 0; X } X } X} X X/* fillbuf() - get buffer of data */ Xfillbuf(filnum, buf) Xint filnum; Xchar buf[]; X{ X int i; X int echk; X char *status = 0x0090; X X for(i=0; i<RECSIZE; i++) X { X /* get a char from file */ X if((echk=fgetc(filnum)) == EOF) X { X break; X } X buf[i] = echk; X } X X if(i == 0) return 0; X X /* set rest of buffer to CTRL-Z */ X for(; i<RECSIZE; i++) X { X buf[i] = (char)26; X } X return(1); X} X X/* txrec() - send rec, get response */ Xtxrec(buf) Xchar buf[]; X{ X int i; X int ch; X unsigned chksum; X X tries = RETRY; X X for(;;) X { X /* send record */ X X printf("Record %3d ", rec); X putserial(SOH); X putserial(rec); X putserial(~rec); X chksum = 0; X for(i=0; i<RECSIZE; i++) X { X putserial(buf[i]); X chksum += buf[i]; X chksum &= 0xff; X } X putserial(chksum); X X /* get response */ X ch = getchtmo(BTOUT); X if(timeout) X { X tries--; X if(tries > 0) X { X printf("Retrying...\n"); X continue; X } X printf("Timeout\n"); X return(0); X } X X /* analyze response */ X if(ch == CAN) X { X printf("Cancelled\n"); X return(0); X } X else if(ch == ACK) X { X printf("ACKed\n", rec); X break; X } X else X { X if(ch == NAK) X { X printf("NAKed\n", rec); X } X else X { X printf("Strange response\n"); X } X tries--; X if(tries > 0) X { X continue; X } X printf("No more retries!\n"); X return(0); X } X } X rec++; X return(1); X} X X/* gobble() - gobble up stray chars */ Xgobble() X{ X unsigned gotone; X X printf("\ngobbling\n"); X X sleep(2); X X for(;;) X { X gotone = 0; X /* clear input queue */ X while(getserial() >= 0) X { X gotone = 1; X } X if(gotone) X { X sleep(1); X } X else X { X return; X } X } X} X X/* end of file */ SHAR_EOF chmod 0664 xmodem.c || echo "restore of xmodem.c fails" exit 0 -- W Mat Waites gatech!emcard!mat 8-5 ET: (404) 727-7197