home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / HEATH / HMSRC20.LBR / HM0.CZ / HM0.C
Text File  |  2000-06-30  |  14KB  |  450 lines

  1. /*************************************************************************/
  2. /*                                                                       */
  3. /*                      H M O D E M   II                                 */  
  4. /*                For H/Z89 and H8/H19 Z80 Systems                       */
  5. /*                  Developed by Harold D. Maney                         */
  6. /*                    510 Barrack Hill Road                              */
  7. /*                    Ridgefield, CT 06877                               */
  8. /*                                                                       */
  9. /*                    GEnie address HMANEY                               */
  10. /*                                                                       */
  11. /*************************************************************************/
  12. /*                                                                       */
  13. /*  3 December 1984     Written by Harold D. Maney                       */
  14. /*  1 November 1987     Improved for Linda's 2400 bps modem              */
  15. /*  20 November 1987    Greatly improved for Linda                       */
  16. /*  29 November 1987    Added YMODEM, ZMODEM support                     */
  17. /*  12 May 1988         Released HModem II Ver 2.05.05 as shareware      */
  18. /*  15 May 1988         Released source code for HModem II               */
  19. /*                                                                       */
  20. /*************************************************************************/
  21. /*                                                                       */
  22. /*  This source code may be distributed freely without restriction       */
  23. /*  for the express purpose of promoting the use of the ZMODEM           */
  24. /*  file transfer protocol.  Programmers are requested to include        */
  25. /*  credit (in the source code) to the developers for any code           */
  26. /*  incorporated from this program.                                      */
  27. /*                                                                       */
  28. /*************************************************************************/
  29. /*                                                                       */
  30. /*  This program was inspired by lmodem.c written by David D. Clark      */
  31. /*  in the November 83 issue of Byte.  Although it bears no resemblance  */
  32. /*  to David's program, I can credit him with sparking my interest in    */
  33. /*  modem programs written in C.                                         */
  34. /*                                                                       */
  35. /*  Hmodem is somewhat machine specific.  It has been set up to run on   */
  36. /*  H89 computers with the 8250 ACE.  It is tailored to use the H19/89   */
  37. /*  function keys for commands.  The Heath system tick counter is used   */
  38. /*  for timing.                                                          */
  39. /*                                                                       */
  40. /*  Compile and assemble with Software Toolworks C/80 ver 3.0 or later.  */
  41. /*  The optional Mathpak is required to support long integers.           */
  42. /*                                                                       */
  43. /*  The following files comprise HModem II:                              */
  44. /*                                                                       */
  45. /*    hmodem80.h        the header file                                  */
  46. /*    hm0.c             the main program                                 */
  47. /*    hm1.c-hm6.c       everything but x/y/zmodem                        */
  48. /*    hm7.c             Chuck Forsberg's sz.c modified for cp/m          */
  49. /*    hm8.c             Chuck Forsberg's rz.c modified for cp/m          */
  50. /*    hzm.c             Chuck Forsberg's zm.c modified for cp/m          */
  51. /*    zmodem.h          zmodem header file                               */
  52. /*    hconfig0.c        configuration overlay                            */
  53. /*    hconfig1.c        configuration overlay                            */
  54. /*    hconfig.h         configuration overlay header                     */
  55. /*    hm.sub            sample submit file for compiling and linking     */
  56. /*                                                                       */
  57. /*    Hints for using C80:                                               */
  58. /*                                                                       */
  59. /*      1.  You must use C80 with M80/L80.                               */
  60. /*      2.  If you need to speed the program up or make it smaller,      */
  61. /*          convert all structures to simple variables.                  */
  62. /*      3.  Always use static storage rather than automatic.             */
  63. /*                                                                       */
  64. /*************************************************************************/
  65.  
  66. #define  MAIN
  67. #define  C80
  68.  
  69. #include "hmodem80.h"
  70.  
  71. main(argc,argv)
  72. int argc;
  73. char *argv[];
  74. {
  75.    static unsigned nextfunction, addr;
  76.    static int i, count;
  77.    static int kbdata, mdmdata;
  78.    static char keypad[] = "pqrstuvwxynM";
  79.    static char keybuf[2];
  80.    static unsigned commandflag = 0;
  81.    static int dolabel, result;
  82.  
  83.    Cmode = 0;
  84.    if (!parmatch(argc,argv,"HCONFIG")) 
  85.       title();
  86.    printf("\033G\033x7"); /* no graphics mode and select alternate keypad */
  87.    getconfig();
  88.    initvector();                 /* set up interrupt vector */
  89.    initializemodem();
  90.    cls();
  91.    tlabel();
  92.    Invokdrive = bdos(GETCUR,NULL) + 'A';
  93.    Currdrive = Datadrive;
  94.    reset(Currdrive);
  95.    printf("READY\n");
  96.    showcurs();
  97.  
  98.    /************** the main loop ************************/
  99.  
  100.    while (TRUE) {
  101.       if (kbdata = getch())  {         /* get any char at kbd */
  102.          if (nextfunction = getfunct(kbdata)) {
  103.             dolabel = TRUE;
  104.             flush();
  105.             nextfunction |= commandflag;
  106.             switch (nextfunction) {
  107.  
  108.             case RECEIVE:
  109.                keep(Lastlog);
  110.                bringin(NULL);
  111.                startcapture();
  112.                break;
  113.  
  114.             case CAPTURE:
  115.                capturetog(Logfile);
  116.                break;
  117.  
  118.             case DIR:
  119.                killlabel();
  120.                keep(Lastlog);
  121.                directory();
  122.                startcapture();
  123.                break;
  124.  
  125.             case PRTSCRN:
  126.                screenprint();
  127.                break;
  128.  
  129.             case SEND:
  130.                keep(Lastlog);
  131.                sendout(NULL);
  132.                startcapture();
  133.                break;
  134.  
  135.             case HANGUP:
  136.             case CHANGUP:
  137.                hangup();
  138.                dolabel = FALSE;
  139.                break;
  140.  
  141.             case COMMAND:
  142.             case CCOMMAND:
  143.                commandflag ^= LEVELFLAG;
  144.                break;
  145.  
  146.             case DIAL:
  147.                keep(Lastlog);
  148.                dial();
  149.                purgeline();
  150.                startcapture();
  151.                break;
  152.  
  153.             case HOST:
  154.                keep(Lastlog);
  155.                QuitFlag = FALSE;
  156.                Inhost = TRUE;
  157.                while (!QuitFlag)
  158.                   dohost();
  159.                Inhost = FALSE;
  160.                flush();
  161.                cls();
  162.                startcapture();
  163.                break;
  164.  
  165.             case CONFIG:
  166.                killlabel();
  167.                cls();
  168.                configure();
  169.                perror("HCONFIG.COM not found");
  170.                break;
  171.  
  172.             case TOGPRT:
  173.                toggleprt();
  174.                break;
  175.  
  176.             case DISK:
  177.                diskstuff();
  178.                break;
  179.  
  180.             case HELP:
  181.             case CHELP:
  182.                help();               
  183.                break;
  184.  
  185.             case QUIT:
  186.             case CQUIT:
  187.                doexit(QUIT);
  188.                break;
  189.  
  190.             default:
  191.                dolabel = FALSE;
  192.                keybuf[0] = nextfunction;
  193.                keybuf[1] = '\0';
  194.                if ((i=index(keypad,keybuf)) != -1) {
  195.                   mstrout(KbMacro[i],TRUE);
  196.                }
  197.                break;
  198.             }                            /* end of switch*/
  199.             if (dolabel)
  200.                commandflag ? comlabel() : tlabel();
  201.          }                             /*end of if nextfunction*/
  202.          else {
  203.             mcharout(kbdata);
  204. lfloop:
  205.             tobuffer(kbdata);
  206.             if (!FDx) {
  207.                putchar(kbdata);
  208.                toprinter(kbdata);
  209.                if (kbdata == CR) {
  210.                   kbdata = LF;
  211.                   goto lfloop;
  212.                }
  213.             }
  214.          }
  215.       }                    /*  end of if char at kbd  */
  216.  
  217.       if (minprdy()) {
  218.          mdmdata = mcharinp();
  219.          putchar(mdmdata);
  220.          tobuffer(mdmdata);
  221.          toprinter(mdmdata);
  222.       }
  223.       prtservice();     /* service printer at the end of each loop */
  224.    }    /* end of while */
  225. }  /* end of main */
  226.  
  227. tobuffer(c)
  228. int c;
  229. {
  230.    if (BFlag) {
  231.       MainBuffer[TxtPtr++] = (char)c;
  232.       if (TxtPtr > Buftop) {
  233.          keep(Lastlog);
  234.          startcapture();
  235.       }
  236.    }
  237. }
  238.  
  239. toprinter(c)
  240. int c;
  241. {
  242.    if (PFlag) {
  243.       *Prthead++ = (char)c;
  244.       adjustprthead();
  245.    }
  246. }
  247.  
  248. keep(filename)
  249. char *filename;
  250. {
  251.    static int fl;
  252.  
  253.    if (!BFlag)
  254.       return;
  255.    if (!TxtPtr)
  256.       goto cleanup;
  257.    mcharout(CTRLS);
  258.    while (TxtPtr % 128)
  259.       MainBuffer[TxtPtr++] = 0;
  260.    addatadrive(filename);
  261.    if (!(fl = fopen(filename,"ub")) && !(fl = fopen(filename,"wb")))
  262.       openerror(fl,filename);
  263.    else {
  264.       seek(fl,0,2);       
  265.       write(fl,MainBuffer,TxtPtr);
  266.       fclose(fl);
  267.    }
  268.    mcharout(CTRLQ);
  269.    TxtPtr = 0;
  270. cleanup:
  271.    free(MainBuffer);
  272. }
  273.  
  274. toggleprt()
  275. {
  276.    PFlag = !PFlag;
  277.    if (PFlag) {
  278.       if (getprtbuf() != OK)
  279.          PFlag = FALSE;
  280.    }
  281.    else {
  282.       free(Prtbuf);
  283.    }
  284. }
  285.  
  286. getprtbuf()
  287. {
  288.    keep(Lastlog);                    /* need to steal some of the buffer */
  289.    Prtbuf = alloc(Pbufsiz);
  290.    if (allocerror(Prtbuf))
  291.       return NERROR;
  292.    Prthead = Prttail = Prtbottom = Prtbuf;
  293.    Prttop = Prtbuf + Pbufsiz - 1;
  294.    startcapture();
  295. #ifdef DEBUG
  296.    printf("\nPrtbuf = %x\n",Prtbuf);
  297. #endif
  298.    return OK;
  299. }
  300.  
  301. startcapture()     /* allocate capture buffer */
  302. {
  303.    char *grabmem();
  304.  
  305.    if (!BFlag)
  306.       return;
  307.    MainBuffer = grabmem(&Bufsize);
  308.    Buftop = Bufsize - 1;
  309.    TxtPtr = 0;
  310. #ifdef DEBUG
  311.    printf("\ncapture Bufsize = %u\n",Bufsize);
  312. #endif
  313. }
  314.  
  315. char *
  316. grabmem(sizep)         /* grab all available memory */
  317. unsigned *sizep;       /* place to store how much we got */
  318. {
  319.    static char *p;
  320.    static unsigned size;
  321.  
  322.    size = BUFSTART;
  323.    while ((p=alloc(size)) == -1) {
  324.       size -= 1024;
  325.       if (size < 2048) {
  326.          size = 0;
  327.          break;
  328.       }
  329.    }
  330. #ifdef DEBUG
  331.    printf("\ngrabmem = %x %d\n",p,size);
  332. #endif
  333.    *sizep = size;
  334.    return p;
  335. }
  336.  
  337. protocol(for_send)
  338. int for_send;        /* select block size in transmit only */
  339. {
  340.    static int c;
  341.    static char *buffer;
  342.    
  343.    buffer = Pathname;
  344.    sprintf(buffer,"\n%sXmodem, %sYmodem, or Zmodem? (%sX,%sY,Z) <X>  ",
  345.       for_send ? "ASCII, " : "",
  346.       for_send ? "Xmodem-1k, " : "",
  347.       for_send ? "A," : "",
  348.       for_send ? "K," : "" );
  349.    if (Inhost) {
  350.       mstrout(buffer,TRUE);
  351.       purgeline();
  352.       c = toupper(mgetchar(20));
  353.       if (c == CR)
  354.          c = 'X';
  355.       mcharout(c);
  356.       return c;
  357.    }
  358.    else {
  359.       printf(buffer);
  360.       flush();
  361.       c = toupper(getchar());
  362.       if (c == '\n')
  363.          c = 'X';
  364.    }
  365.    return c;
  366. }
  367.  
  368. getpathname(string)
  369. char *string;
  370. {
  371.    static int c;
  372.    static char *buffer;
  373.  
  374.    buffer = Pathname;
  375.    sprintf(buffer,"\nPlease enter file name%s:  ",string);
  376.    if (Inhost) {
  377.       mstrout(buffer,TRUE);
  378.       if (!(c=mgetline(Pathname,PATHLEN,TRUE)))
  379.          return 0;
  380.    }
  381.    else {
  382.       printf(buffer);
  383.       if (!(c=getline(Pathname,PATHLEN)))
  384.          return 0;
  385.    }
  386.    return linetolist();
  387. }
  388.  
  389. linetolist()   /* expand and put Pathnames in Pathlist, return count */
  390. {
  391.    static char *p;
  392.    static int count, i;
  393.    static char **tempalloc;
  394.  
  395.    tempalloc = Pathlist = alloc(510);
  396.    if (allocerror(tempalloc))
  397.       return 0;
  398. #ifdef   DEBUG
  399.       printf("Pathlist = %x\n",Pathlist);
  400. #endif
  401.    count = 0;
  402.    Pathlist[count++] = Pathname;
  403.    for (p=Pathname; *p; p++) {         /* break up into substrings */
  404.       if (*p == ' ') {
  405.          *p = '\0';
  406.          while (*++p == ' ');         /* dump extra spaces */
  407.          Pathlist[count++] = p;
  408.       }
  409.    }
  410. #ifdef   DEBUG
  411.    printf("\nbefore command\n");
  412.    for (i=0; i < count; i++)
  413.       printf("%d %s\n",i,Pathlist[i]);
  414. #endif
  415.    command(&count,&Pathlist);
  416. #ifdef   DEBUG
  417.    printf("\nafter command\n");
  418.    for (i=0; i < count; i++)
  419.       printf("%d %s\n",i,Pathlist[i]);
  420. #endif
  421.    free(tempalloc);
  422.    return count;   
  423. }
  424.  
  425. freepath(n)
  426. int n;
  427. {
  428.    if (n) {
  429.       while (n)
  430.          free(Pathlist[--n]);
  431.       free(Pathlist);
  432.    }
  433. }
  434.  
  435. configure()
  436. {
  437.    doexit(CONFIG);
  438. }
  439.  
  440. parmatch(argc,argv,string)
  441. int argc;
  442. char *argv[], *string;
  443. {
  444.    if (argc < 1)
  445.       return FALSE;
  446.    return (!strcmp(string,argv[1]));
  447. }
  448.  
  449. /***************************END OF MODULE 0*********************************/
  450.