home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol183 / apymboot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-09-10  |  5.3 KB  |  264 lines

  1. /* YAMBOOT.C by Steve Passe (Cnode SYSOP), 1981
  2.     
  3.    Modifications for Australian
  4.    conditions by Bill Bolton (Software Tools SYSOP), 1982
  5.  
  6. This program uses the "Christensen" MODEM7/YAM protocol for file
  7. transfers.  To receive a  type '<esc>', you will be prompted for
  8. the file name. (<esc> is the ASCII escape character: ^[).
  9.  
  10. Add whatever code necessary to the initialize_port() function (setup your
  11. port for 8 bits, 1 stop bit, baud rate of 300 if necessary, etc.).
  12. Using a serial modem you will have to make changes of port addresses and
  13. masks in the #ifdef modem area. There is a define CLKMHZ which should
  14. be set to the clock rate for your CPU.
  15.  
  16. This program uses large chunks of the YAM package for file transfers, 
  17. (thanks Chuck).
  18.  
  19. */
  20.  
  21. #include "apcio.h"        /* Must have modem defines setup */
  22.  
  23. #define SOH 0x01
  24. #define EOT 0x04
  25. #define ACK 0x06
  26. #define NAK 0x15
  27. #define CAN 0x18
  28. #define RETRYMAX 10
  29. #define TIMEOUT (-1)
  30. #define PATHLEN 20
  31. #define WCEOT (-2)
  32. #define CLKMHZ 2        /* CPU speed in Mhz */
  33.  
  34.  
  35.  
  36. #define DIR_IO 0x06        /* You have to have CP/M 2.2 */
  37. #define INPUT 0xff
  38. #define FLAG char
  39.  
  40. int Baud;
  41. FLAG Rfile;
  42. char Rname[PATHLEN];
  43. unsigned T1pause, Timeout;
  44. char File_buf[BUFSIZ];
  45. char Checksum, Lastrx;
  46. int Wcj, Firstch;
  47.  
  48. main()
  49. {
  50.     char received, to_send, in_modem(), getch(), escflag;
  51.     Rfile = FALSE;
  52.     T1pause = 311*CLKMHZ;
  53.     escflag = NULL;
  54.     Baud = 300;
  55.     initialize_port();
  56.     printf("\n\tYAMBOOT in the style of MBOOT.\n\n");
  57.     while (TRUE) {
  58.         if (received = in_modem()) putch(received);
  59.         else if (to_send = getch())
  60.             (to_send == ESC) ? download():out_modem(to_send);
  61.     }
  62. }
  63. char
  64. in_modem()
  65. {
  66.     if (peek(MSTAT) & MIMASK) return peek(MDATA);
  67.     else return FALSE;
  68. }
  69. out_modem(out_char)
  70. char out_char;
  71. {
  72.     while (!(peek(MSTAT) & MOMASK))    ;
  73.     poke(MDATA, out_char);
  74. }
  75. char
  76. getch()
  77. {
  78.     return bdos(DIR_IO, INPUT);
  79. }
  80.  
  81. /*
  82.  
  83.     Most of the following functions taken from YAM package by
  84. Chuck Forsberg, BDS C UG disk Utilities 3, some modifications made for
  85. compatibility with cnode code.
  86.  
  87. */
  88.  
  89. download(filename)
  90. char *filename;
  91. {
  92.     printf("\n\n\tReceive: ");
  93.     scanf("%s", Rname);
  94.     printf("ready to receive '%s'\n", Rname);
  95.     if(wcrx(Rname)==ERROR) {
  96.         abort('r');
  97.     }
  98.     return OK;
  99. }
  100.  
  101. /* Adapted from CMODEM13.C, by Jack M. Wierda and Roderick W. Hart */
  102. wcrx(name)
  103. char *name;
  104. {
  105.     int sectnum, sectcurr, sectcomp;
  106.     char *cp, rxbuf[128], sendchar;
  107.     if(openrx(name)==ERROR)
  108.         return ERROR;
  109.     sectnum=0;
  110.     sendchar=NAK;
  111.     for(;;) {
  112.         out_modem(sendchar);
  113.         sectcurr=wcgetsec(rxbuf, (sectnum & 0x7f) ? 50 : 130);
  114.         if(sectcurr==(sectnum+1 & 0xff)) {
  115.             sectnum++;
  116.             for(cp=rxbuf,Wcj=128; --Wcj>=0; )
  117.                 if(putc(*cp++, File_buf)==ERROR) {
  118.                     printf("\nDisk Full\n");
  119.                     return ERROR;
  120.                 }
  121.             sendchar=ACK;
  122.         }
  123.         else if(sectcurr==sectnum) {
  124.             printf("\nReceived dup Sector %d",sectcurr);
  125.             sendchar=ACK;
  126.         }
  127.         else if(sectcurr==WCEOT) {
  128.             out_modem(ACK);
  129.             closerx(FALSE);
  130.             return OK;
  131.         }
  132.         else {
  133.             printf(" Sync Error\n");
  134.             return ERROR;
  135.         }
  136.     }
  137. }
  138. wcgetsec(rxbuf, time)
  139. char *rxbuf;
  140. int time;
  141. {
  142.     int sectcurr,errors;
  143.     char *cp;
  144.  
  145.     for(Lastrx=errors=0; errors<RETRYMAX; errors++) {
  146.         do {
  147.             Firstch=readbyt(time);
  148.         }
  149.         while(Firstch != SOH && Firstch != TIMEOUT && Firstch != EOT
  150.               && Firstch != CAN);    /* wait for one of these */
  151.         if(Firstch==SOH) {
  152.             sectcurr=readbyt(1);
  153.             if((sectcurr+readbyt(1))==255) {
  154.                 Checksum=0;
  155.                 for(cp=rxbuf,Wcj=128; --Wcj>=0; ) {
  156.                     isprint(*cp = readbyt(1)) ? putchar(*cp) : putchar('.');
  157.                     Checksum += (*cp++);
  158.                 }
  159.                 if(((Checksum-readbyt(1))& 0xff)==0)
  160.                     return sectcurr;
  161.                 else
  162.                     printf("Checksum Error #%d", errors);
  163.             }
  164.             else
  165.                 printf("Sector number garbled #%d", errors);
  166.         }
  167.         else if(Firstch==EOT)
  168.             return WCEOT;
  169.         else if(Firstch==CAN) {
  170.             if(Lastrx==CAN) {
  171.                 printf("\nSender CANcelled");
  172.                 return ERROR;
  173.             } else {
  174.                 Lastrx=CAN;
  175.                 continue;
  176.             }
  177.         }
  178.         else if(Firstch==TIMEOUT)
  179.             printf("\nSOH Timeout #%d", errors);
  180.         Lastrx=0;
  181.         while(readbyt(1)!=TIMEOUT)
  182.             ;
  183.         out_modem(NAK);
  184.         time=40;
  185.     }
  186.     out_modem(CAN);out_modem(CAN);out_modem(CAN);
  187.     return ERROR;
  188. }
  189. openrx(name)
  190. char *name;
  191. {
  192.     printf("\nSaving it as '%s'", name);
  193.     if(fopen(name, File_buf) != ERROR) {
  194.         fclose(File_buf);
  195.         printf("\nI already have one, try another name");
  196.         return ERROR;
  197.     }
  198.     if(fcreat(name, File_buf)==ERROR){
  199.         printf("\nCan't create '%s'", name);
  200.         return ERROR;
  201.     }
  202.     Rfile= TRUE;
  203.     return OK;
  204. }
  205. readbyt(decisecs)
  206. int decisecs;
  207. {
  208.     if (peek(MSTAT) & MIMASK)
  209.         return peek(MDATA);
  210.     while (--decisecs >= 0) {
  211.         if (peek(MSTAT) & MIMASK)
  212.             return peek(MDATA);
  213.         if (bdos(DIR_IO, INPUT))
  214.             return TIMEOUT;
  215.         if (peek(MSTAT) & MIMASK)
  216.             return peek(MDATA);
  217.         for (Timeout = T1pause; --Timeout; )
  218.             if (peek(MSTAT) & MIMASK)
  219.                 return peek(MDATA);
  220.     }
  221.     return TIMEOUT;
  222. }
  223. abort(flag)
  224. char flag;
  225. {
  226.     flag == 't' ? closetx() : closerx();
  227.     out_modem(CAN);out_modem(CAN);out_modem(CAN);
  228.     return ERROR;
  229. }
  230. closetx()
  231. {
  232. }
  233. closerx()
  234. {
  235.     if(Rfile) {
  236.         fflush(File_buf);
  237.         fclose(File_buf);
  238.         printf("\n\n%s closed", Rname);
  239.         Rfile=FALSE;
  240.     }
  241. }
  242. purgeline()
  243. {
  244.     while (peek(MSTAT) & MIMASK)
  245.         peek(MDATA);
  246. }
  247.  
  248. /* end of code from yam */
  249.  
  250. initialize_port()
  251. {
  252.     /* put your modem port intialisation code here, you may NOT need
  253.        it if you are CERTAIN that the port will be initialised
  254.        correctly before entering BOOTMODM */
  255. }
  256.  
  257. isprint(c)
  258. char c;
  259. {
  260.   return (c >= ' ' && c <= '~') || (c == 0x0d) || (c == 0x0a) || (c==0x09);
  261. }
  262.  
  263. /* END OF YAMBOOT */
  264.