/* YAMBOOT.C by Steve Passe (Cnode SYSOP), 1981 Modifications for Australian conditions by Bill Bolton (Software Tools SYSOP), 1982 This program uses the "Christensen" MODEM7/YAM protocol for file transfers. To receive a type '', you will be prompted for the file name. ( is the ASCII escape character: ^[). Add whatever code necessary to the initialize_port() function (setup your port for 8 bits, 1 stop bit, baud rate of 300 if necessary, etc.). Using a serial modem you will have to make changes of port addresses and masks in the #ifdef modem area. There is a define CLKMHZ which should be set to the clock rate for your CPU. This program uses large chunks of the YAM package for file transfers, (thanks Chuck). */ #include "apcio.h" /* Must have modem defines setup */ #define SOH 0x01 #define EOT 0x04 #define ACK 0x06 #define NAK 0x15 #define CAN 0x18 #define RETRYMAX 10 #define TIMEOUT (-1) #define PATHLEN 20 #define WCEOT (-2) #define CLKMHZ 2 /* CPU speed in Mhz */ #define DIR_IO 0x06 /* You have to have CP/M 2.2 */ #define INPUT 0xff #define FLAG char int Baud; FLAG Rfile; char Rname[PATHLEN]; unsigned T1pause, Timeout; char File_buf[BUFSIZ]; char Checksum, Lastrx; int Wcj, Firstch; main() { char received, to_send, in_modem(), getch(), escflag; Rfile = FALSE; T1pause = 311*CLKMHZ; escflag = NULL; Baud = 300; initialize_port(); printf("\n\tYAMBOOT in the style of MBOOT.\n\n"); while (TRUE) { if (received = in_modem()) putch(received); else if (to_send = getch()) (to_send == ESC) ? download():out_modem(to_send); } } char in_modem() { if (peek(MSTAT) & MIMASK) return peek(MDATA); else return FALSE; } out_modem(out_char) char out_char; { while (!(peek(MSTAT) & MOMASK)) ; poke(MDATA, out_char); } char getch() { return bdos(DIR_IO, INPUT); } /* Most of the following functions taken from YAM package by Chuck Forsberg, BDS C UG disk Utilities 3, some modifications made for compatibility with cnode code. */ download(filename) char *filename; { printf("\n\n\tReceive: "); scanf("%s", Rname); printf("ready to receive '%s'\n", Rname); if(wcrx(Rname)==ERROR) { abort('r'); } return OK; } /* Adapted from CMODEM13.C, by Jack M. Wierda and Roderick W. Hart */ wcrx(name) char *name; { int sectnum, sectcurr, sectcomp; char *cp, rxbuf[128], sendchar; if(openrx(name)==ERROR) return ERROR; sectnum=0; sendchar=NAK; for(;;) { out_modem(sendchar); sectcurr=wcgetsec(rxbuf, (sectnum & 0x7f) ? 50 : 130); if(sectcurr==(sectnum+1 & 0xff)) { sectnum++; for(cp=rxbuf,Wcj=128; --Wcj>=0; ) if(putc(*cp++, File_buf)==ERROR) { printf("\nDisk Full\n"); return ERROR; } sendchar=ACK; } else if(sectcurr==sectnum) { printf("\nReceived dup Sector %d",sectcurr); sendchar=ACK; } else if(sectcurr==WCEOT) { out_modem(ACK); closerx(FALSE); return OK; } else { printf(" Sync Error\n"); return ERROR; } } } wcgetsec(rxbuf, time) char *rxbuf; int time; { int sectcurr,errors; char *cp; for(Lastrx=errors=0; errors=0; ) { isprint(*cp = readbyt(1)) ? putchar(*cp) : putchar('.'); Checksum += (*cp++); } if(((Checksum-readbyt(1))& 0xff)==0) return sectcurr; else printf("Checksum Error #%d", errors); } else printf("Sector number garbled #%d", errors); } else if(Firstch==EOT) return WCEOT; else if(Firstch==CAN) { if(Lastrx==CAN) { printf("\nSender CANcelled"); return ERROR; } else { Lastrx=CAN; continue; } } else if(Firstch==TIMEOUT) printf("\nSOH Timeout #%d", errors); Lastrx=0; while(readbyt(1)!=TIMEOUT) ; out_modem(NAK); time=40; } out_modem(CAN);out_modem(CAN);out_modem(CAN); return ERROR; } openrx(name) char *name; { printf("\nSaving it as '%s'", name); if(fopen(name, File_buf) != ERROR) { fclose(File_buf); printf("\nI already have one, try another name"); return ERROR; } if(fcreat(name, File_buf)==ERROR){ printf("\nCan't create '%s'", name); return ERROR; } Rfile= TRUE; return OK; } readbyt(decisecs) int decisecs; { if (peek(MSTAT) & MIMASK) return peek(MDATA); while (--decisecs >= 0) { if (peek(MSTAT) & MIMASK) return peek(MDATA); if (bdos(DIR_IO, INPUT)) return TIMEOUT; if (peek(MSTAT) & MIMASK) return peek(MDATA); for (Timeout = T1pause; --Timeout; ) if (peek(MSTAT) & MIMASK) return peek(MDATA); } return TIMEOUT; } abort(flag) char flag; { flag == 't' ? closetx() : closerx(); out_modem(CAN);out_modem(CAN);out_modem(CAN); return ERROR; } closetx() { } closerx() { if(Rfile) { fflush(File_buf); fclose(File_buf); printf("\n\n%s closed", Rname); Rfile=FALSE; } } purgeline() { while (peek(MSTAT) & MIMASK) peek(MDATA); } /* end of code from yam */ initialize_port() { /* put your modem port intialisation code here, you may NOT need it if you are CERTAIN that the port will be initialised correctly before entering BOOTMODM */ } isprint(c) char c; { return (c >= ' ' && c <= '~') || (c == 0x0d) || (c == 0x0a) || (c==0x09); } /* END OF YAMBOOT */ .