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 / HM2.CZ / HM2.C
Text File  |  2000-06-30  |  11KB  |  465 lines

  1. /***************************** Module 2 ************************************/
  2.  
  3. #define  C80
  4. #include "hmodem80.h"
  5.  
  6. cntbits(byte)
  7. char byte;
  8. {
  9.    static int i,count;
  10.  
  11.    for (count=i=0; i<8; i++) {
  12.       count += (byte & 1);
  13.       byte >>= 1;
  14.    }
  15.    return count;
  16. }
  17.  
  18. reset(drive)
  19. unsigned drive;
  20. {
  21.    drive = toupper(drive);
  22.    if (isalpha(drive) && drive <= 'F') {
  23.       Currdrive = drive;
  24.       bdos(RESET,NULL);
  25.       bdos(SELDSK,(Currdrive-'A')&0xff);
  26.    }
  27. }
  28.  
  29. addatadrive(filename)
  30. char filename[];        /* must have room for at least 15 chars */
  31. {
  32.    addrive(filename,Datadrive);
  33. }
  34.  
  35. addrive(filename,drive)
  36. char *filename;
  37. int drive;
  38. {
  39.    if (!isin(filename,":")) {
  40.       strcpy(Buf,filename);
  41.       filename[0] = (char)drive;
  42.       sprintf(filename+1,":%s",Buf);
  43.    }
  44. }
  45.  
  46. sendout(prot)
  47. int prot;
  48. {
  49.    static int kbdata, count, result;
  50.  
  51.    result = NERROR;
  52.    if (!prot)
  53.       kbdata = protocol(TRUE);
  54.    else
  55.       kbdata = prot;
  56.    if (Inhost) {
  57.       if (count=getpathname("(s) for Download"))
  58.          mstrout("\nBegin your Download procedure...",TRUE);
  59.    }
  60.    else 
  61.       count = getpathname("(s) for Transmit");
  62.    if (count) {
  63.       switch(kbdata) {
  64.       case 'K':
  65.          Blklen = KSIZE;
  66.          Xmodem = TRUE;
  67.          Zmodem = FALSE;
  68.          result = wcsend(1,Pathlist);
  69.          break;
  70.       case 'X':
  71.          Blklen = 128;
  72.          Xmodem = TRUE;
  73.          Zmodem = FALSE;
  74.          result = wcsend(1,Pathlist);
  75.          break;
  76.       case 'Y':
  77.          Zmodem = Xmodem = FALSE;
  78.          result = wcsend(count,Pathlist);
  79.          break;
  80.       case 'Z':
  81.          Zmodem = TRUE;
  82.          Xmodem = FALSE;
  83.          result = wcsend(count,Pathlist);
  84.          break;
  85.       case 'A':
  86.          result = asciisend(Pathlist[0]);
  87.          break;
  88.       default:
  89.          result = !OK;
  90.          break;
  91.       }
  92.    }
  93.    freepath(count);
  94.    printf("\nTransfer %s\n",result==OK?"Successful":"Aborted");
  95.    flush();
  96.    return result;
  97. }
  98.  
  99. bringin(prot)
  100. int prot;
  101. {
  102.    static int kbdata, count, result;
  103.  
  104.    count = 0;
  105.    result = NERROR;
  106.    if (!prot)
  107.       kbdata = protocol(FALSE);
  108.    else
  109.       kbdata = prot;
  110.    switch(kbdata) {
  111.    case 'X':
  112.       if (Inhost) {
  113.          if (count=getpathname(" to Upload"))
  114.             mstrout("\nBegin your Upload procedure...",TRUE);
  115.       }
  116.       else 
  117.          count = getpathname(" to Receive");
  118.       if (!count)
  119.          break;
  120.       Zmodem = FALSE;
  121.       Nozmodem = Xmodem = TRUE;
  122.       result = wcreceive(Pathlist[0]);      /* just one file */
  123.       break;
  124.    case 'Y':
  125.       Zmodem = Xmodem = FALSE;
  126.       Nozmodem = TRUE;
  127.       if (Inhost)
  128.          mstrout("\nBegin your Upload procedure...",TRUE);
  129.       result = wcreceive(NULL);
  130.       break;
  131.    case 'Z':
  132.       Zmodem = TRUE;
  133.       Nozmodem = Xmodem = FALSE;
  134.       if (Inhost)
  135.          mstrout("\nBegin your Upload procedure...",TRUE);
  136.       result = wcreceive(NULL);
  137.       break;
  138.    default:
  139.       break;
  140.    }
  141.    freepath(count);  /* should be just 1 */
  142.    printf("\nTransfer %s\n",result==OK?"Successful":"Aborted");
  143.    flush();
  144.    return result;
  145. }
  146.  
  147. /*
  148. /* exec: function to chain to another C-generated com file, with
  149. /*     text argument passing.
  150. /* Calling sequence:
  151. /*     exec(prog, args);
  152. /*     char *prog, *args;
  153. /* where
  154. /*     prog is the name of the program being executed next
  155. /*     args is a pointer to a string of arguments separated by
  156. /*       blanks or tabs.  Embedded blanks within the arguments are
  157. /*       not allowed, unless the called program does not use the
  158. /*       default FCB parameters (and most don't) and can parse the
  159. /*       command line parameter list itself (like C80 programs can).
  160. */
  161. exec() {
  162. #ifdef   C80
  163. #asm
  164.     JMP @exec
  165. ;
  166. ;    CP/M memory pointers
  167. ;
  168. @BASE       EQU 0000H    ;either 0 or 4200h for CP/M systems
  169. @FCB       EQU @BASE+5CH    ;default file control block
  170. @TBUFF    EQU @BASE+80H    ;sector buffer
  171. @BDOS       EQU @BASE+5    ;bdos entry point
  172. @TPA       EQU @BASE+100H    ;transient program area
  173. @ERRV       EQU 255     ;error value returned by bdos calls
  174. ;
  175. ;    CP/M BDOS CALL MNEMONICS
  176. ;
  177. @OPENC    EQU 15        ;open a file
  178. @READS    EQU 20        ;read a sector (sequential)
  179. @SDMA       EQU 26        ;set dma
  180. ;
  181. ;    Argument pointers
  182. ;
  183. @ARGS:    DS 0
  184. @ARG1:    DS 2
  185. @ARG2:    DS 2
  186. @ARG3:    DS 2
  187. @ARG4:    DS 2
  188. @ARG5:    DS 2
  189. @ARG6:    DS 2
  190. ;
  191. @exec:
  192.     LXI   H,4
  193.     DAD   SP
  194.     MOV   E,M
  195.     INX   H
  196.     MOV   D,M        ;DE points to program name now
  197.     LXI   H,-60
  198.     DAD   SP           ; compute &newfcb for use here
  199.     PUSH  H           ; save for much later (will pop into bc)
  200.     PUSH  H           ;make a few copies for local use below
  201.     PUSH  H
  202.     CALL  x?fcb##    ;set up com file for exec-ing
  203.     POP   H           ;get new fcb addr
  204.     LXI   B,9        ;set extension to com
  205.     DAD   B
  206.     MVI   M,'C'
  207.     INX   H
  208.     MVI   M,'O'
  209.     INX   H
  210.     MVI   M,'M'
  211.     POP   D              ;get new fcb addr again
  212.     MVI   C,@OPENC       ;open the file for reading
  213.     CALL  @BDOS
  214.     CPI   @ERRV
  215.     JNZ   @NOERR
  216.     POP   H              ;if can't (like it doesn't exist), return -1
  217.     LXI   H,-1
  218.     DB    0C9H        ; return instruction
  219.  
  220. @NOERR:  
  221.    LXI   H,4           ;get args pointer
  222.     DAD   SP
  223.     CALL  h@##          ;HL = *HL
  224.     CALL  @SPARG       ;separate them into individual strings
  225.     LHLD  @ARG1
  226.     MOV   A,H
  227.     ORA   L
  228.     JNZ   @EXCL0
  229.     LXI   D,@ARG1       ;no arguments -- create a blank FCB
  230.     PUSH  D              ;call x?fcb with null string
  231.     LXI   H,@FCB
  232.     CALL  x?fcb
  233.     POP   H
  234.     JMP   @EXCL6
  235.  
  236. @EXCL0: 
  237.    XCHG
  238.     LXI   H,@FCB
  239.     CALL  x?fcb          ;stick first param into default FCB slot
  240.     LHLD  @ARG2          ;and stick second param string
  241.     MOV   A,H
  242.     ORA   L
  243.     JNZ   @EXCL6
  244.     LXI   H,@ARG2
  245.  
  246. @EXCL6: 
  247.    XCHG                 ;into second default fcb slot
  248.     LXI   H,@FCB+16
  249.     CALL  x?fcb
  250.     LXI   D,@TBUFF+1     ;now construct command line:
  251.     LXI   H,4
  252.     DAD   SP           ;HL points to arg string pointer
  253.     CALL  h@        ;HL points to arg string
  254.     MVI   B,0        ;char count for com. line buf.
  255.     MOV   A,H        ;are there any arguments?
  256.     ORA   L
  257.     JZ    @EXCL9
  258.     ORA   M           ; (Bug fix 7/83 WB)
  259.     JNZ   @EXCL5
  260. @EXCL9: 
  261.    STAX  D        ;no--zero TBUFF and TBUFF+1
  262.     JMP   @EXCL2
  263. @EXCL5:  
  264.    MVI   A,' '    ;yes--start buffer off with a ' '
  265.     STAX  D
  266.     INX   D
  267.     INR   B
  268. @EXCL1: 
  269.    MOV   A,M           ;now copy argument string to command line
  270.     CALL  NAM@U##       ;make sure they're upper case
  271.     STAX  D
  272.     INX   D
  273.     INX   H
  274.     INR   B
  275.     ORA   A
  276.     JNZ   @EXCL1
  277.     DCR   B
  278.  
  279. @EXCL2: 
  280.    LXI   H,@TBUFF       ;set length of command line
  281.     MOV   M,B           ;at location tbuff
  282.  
  283.     LXI   D,@CODE0       ;copy loader down to end of tbuff
  284.     LXI   H,@TPA-42
  285.     MVI   B,42          ;length of loader
  286. @EXCL4:  LDAX D
  287.     MOV   M,A
  288.     INX   D
  289.     INX   H
  290.     DCR   B
  291.     JNZ   @EXCL4
  292.  
  293.     POP   B               ;get back working fcb pointer
  294.     LHLD  @BASE+6
  295.     SPHL
  296.     LXI   H,@BASE
  297.     PUSH  H               ;set base of ram as return addr
  298.     JMP   @TPA-42        ;(go to `CODE0:')
  299. ;
  300. ; THIS LOADER CODE IS NOW: 42 BYTES LONG.
  301. ;
  302. @CODE0:
  303.    LXI   D,@TPA    ;destination address of new program
  304. @CODE1: 
  305.    PUSH  D            ;push dma addr
  306.     PUSH  B            ;push fcb pointer
  307.     MVI   C,@SDMA        ;set dma address for new sector
  308.     CALL  @BDOS
  309.     POP   D            ;get pointer to working fcb in de
  310.     PUSH  D            ;and re-push it
  311.     MVI   C,@READS        ;read a sector
  312.     CALL  @BDOS
  313.     POP   B            ;restore fcb pointer into bc
  314.     POP   D            ;and dma address into de
  315.     ORA   A            ;end of file?
  316.     JZ    @TPA-8        ;if not, get next sector (goto `CODE2:')
  317.     MVI   C,@SDMA        ;reset dma pointer
  318.     LXI   D,@TBUFF
  319.     CALL  @BDOS
  320.     JMP   @TPA        ;and go invoke the program
  321.  
  322. @CODE2: 
  323.    LXI   H,80H        ; bump dma address
  324.     DAD   D
  325.     XCHG
  326.     JMP   @TPA-39        ;and go loop (at CODE1)
  327. ;
  328. ; this routine takes the string pointed to by HL,
  329. ; seperates it into non-white strings,
  330. ; and places them contiguously in array ARGST.
  331. ; also places pointers to these individual strings in ARGS
  332. ;
  333. @SPARG: 
  334.    XCHG              ;DE = original string
  335.     LXI   B,@ARGST    ;BC = new string (w/ each substr 0-terminated)
  336.     LXI   H,@ARGS    ;HL = pointer to ARGS space
  337. @SEP0:
  338.     DCX   D
  339. @SEP1:
  340.     INX   D        ;scan over white space
  341.     LDAX  D
  342.     CPI   ' '
  343.     JZ    @SEP1
  344.     CPI   9
  345.     JZ    @SEP1
  346.     CPI   0        ; char = 0?
  347.     JZ    @SPRET    ; yes -- return
  348.     MOV   M,C     ; no -- store local pointer at proper args
  349.     INX   H
  350.     MOV   M,B     ;argsn = BC
  351.     INX   H
  352. @TOWSP:
  353.    STAX  B        ;store non-white
  354.     INX   B
  355.     INX   D        ;now scan to next white space
  356.     LDAX  D
  357.     CPI   0
  358.     JZ    @SEP2
  359.     CPI   ' '
  360.     JZ    @SEP2
  361.     CPI   9
  362.     JNZ   @TOWSP
  363. @SEP2:
  364.     XRA   A
  365.     STAX  B        ;store 0 to terminate this string
  366.     INX   B
  367.     JMP   @SEP0    ; and loop
  368. @SPRET:
  369.    MOV   M,A     ;set last argn to 0 and return
  370.     INX   H
  371.     MOV   M,A
  372.     DB    0C9H  ; return instruction
  373. @ARGST: DS 100
  374. #endasm
  375. #endif
  376. }
  377.  
  378. /* command: expand wild cards in the command line.  (7/25/83)
  379.  * usage: command(&argc, &argv) modifies argc and argv as necessary
  380.  * uses sbrk to create the new arg list
  381.  * NOTE: requires makfcb() and bdos() from file stdlib.c.  When used
  382.  *    with a linker and stdlib.rel, remove the #include stdlib.c.
  383.  *
  384.  * Written by Dr. Jim Gillogly; Modified for CP/M by Walt Bilofsky.
  385.  * Modified by HM to just get ambiguous fn for zmodem, ymodem.
  386.  */
  387.  
  388. int COMnf,*COMfn,COMc,*COMv;
  389. char *COMarg,*COMs;
  390. static expand();
  391.  
  392. command(argcp,argvp)
  393. int *argcp,*argvp;
  394. {
  395.     int f_alloc[MAXFILES];
  396.  
  397.     COMfn = f_alloc;
  398.     COMc = *argcp;
  399.     COMv = *argvp;
  400.     COMnf = 0;
  401.     for (COMarg = *COMv; COMc--; COMarg = *++COMv) {
  402. #ifdef   DEBUG
  403.    printf("\nDoing %s",COMarg);
  404. #endif
  405.        for (COMs = COMarg; *COMs; COMs++)
  406.             if (*COMs == '?' || *COMs == '*') {    
  407.             expand();
  408.                 goto contn;  /* expand each name at most once */
  409.             }
  410.         COMfn[COMnf] = alloc(FNSIZE);
  411.       strcpy(COMfn[COMnf++],COMarg);     /* no expansion */
  412.       contn:;
  413.     }
  414.     *argcp = COMnf;
  415.     COMfn[COMnf++] = -1;
  416.     COMv = *argvp = alloc(2 * COMnf);
  417.     while (COMnf--) 
  418.       COMv[COMnf] = COMfn[COMnf];
  419. }
  420.  
  421. static expand()
  422. {
  423.     char fcb[36];
  424.     static char *p,*q;
  425.     static int i,flg;
  426.  
  427. #ifdef   DEBUG
  428.    printf("\nExpanding %s",COMarg);
  429. #endif
  430.     makfcb(COMarg,fcb);
  431.     if (fcb[0] == -1) 
  432.       fcb[0] = '?';     /* Check for all users */
  433.     for (i = flg = 1; i <= 11; ++i) {    /* Expand *'s */
  434.         if (i == 9) 
  435.          flg = 1;
  436.         if (fcb[i] == '*') 
  437.          flg = 0;
  438.         if (flg == 0) 
  439.          fcb[i] = '?'; 
  440.    }
  441.     flg = 17;
  442.     bdos(26,0x80);                /* Make sure DMA address OK */
  443.     while ((i = bdos(flg,fcb)) != -1) {
  444.         COMfn[COMnf++] = q = alloc(FNSIZE);
  445.         if (COMnf >= MAXFILES-1) {
  446.             for (p = "Too many file names.\n"; putchar(*p++); );
  447.             exit(0); }
  448.         p = 0x81 + i * 32;        /* Where to find dir. record */
  449.         if (COMarg[1] == ':' && COMarg[0] != '?') {
  450.             *q++ = COMarg[0]; 
  451.          *q++ = ':';
  452.       }
  453.         for (i = 12; --i; ) {
  454.             if (i == 3) 
  455.             *q++ = '.';
  456.             if ((*q = *p++ & 0177) != ' ') 
  457.             ++q; 
  458.       }
  459.         *q = 0;
  460.         flg = 18;
  461.     }
  462. }
  463.  
  464. /************************** END OF MODULE 2 *********************************/
  465.