home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / commercial-software / programming / AZTEC302.ZIP / DOS20.ARC < prev    next >
Text File  |  1998-09-16  |  46KB  |  2,717 lines

  1. access.c
  2. #include <stat.h>
  3. #include <errno.h>
  4.  
  5. access(path, amode)
  6. char *path;
  7. {
  8.     struct {
  9.         char rsvd[21];
  10.         char attr;
  11.         long time;
  12.         long size;
  13.         char name[13];
  14.     } sbuf;
  15.     register char *cp;
  16.  
  17.     _sys(0x1a,&sbuf);
  18.     if (_sys(0x4e,path,~ST_VLABEL) == -1) {
  19.         if (errno == ENOMORE)
  20.             errno = ENOENT;
  21.         return -1;
  22.     }
  23.     if (amode & 02 && sbuf.attr & ST_RDONLY) {
  24.         errno = EACCES;
  25.         return -1;
  26.     }
  27.     if (amode & 01) {    /* execute or search */
  28.         if ((sbuf.attr & ST_DIRECT) == 0) {
  29.             for (cp = sbuf.name ; *cp ;)
  30.                 if (*cp++ == '.')
  31.                     break;
  32.             if (strcmp(cp,"EXE") != 0 && strcmp(cp,"COM") != 0
  33.                     && strcmp(cp,"BAT") != 0) {
  34.                 errno = EACCES;
  35.                 return -1;
  36.             }
  37.         }
  38.     }
  39.     return 0;
  40. }
  41.  
  42. asctime.c
  43. /* Copyright (C) 1984 by Manx Software Systems */
  44. #include <time.h>
  45.  
  46. char *
  47. asctime(tm)
  48. struct tm *tm;
  49. {
  50.     static char days[7][4] = {
  51.         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  52.     };
  53.     static char months[12][4] = {
  54.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  55.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  56.     };
  57.     static char buffer[26];
  58.  
  59.     sprintf(buffer, "%s %s %2d %02d:%02d:%02d %4d\n",
  60.         days[tm->tm_wday], months[tm->tm_mon], tm->tm_mday,
  61.         tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year+1900);
  62.     return buffer;
  63. }
  64. bdos.asm
  65. ;Copyright (C) 1983 by Manx Software Systems
  66. ; :ts=8
  67.     include lmacros.h
  68.     procdef    bdos,<<func,word>,<dxval,word>,<cxval,word>>
  69.     push    es
  70.     mov    ax,func
  71.     test    ah,ah
  72.     jnz    valok
  73.     xchg    ah,al
  74. valok:
  75.     mov    dx,dxval
  76.     mov    cx,cxval
  77.     int    21H
  78.     mov    dx,es
  79.     pop    es
  80.     and    ax,0ffH
  81.     pret
  82.     pend    bdos
  83.     finish
  84.     end
  85. sbegin.asm
  86. ; Copyright (C) 1983 1984 by Manx Software Systems
  87. ; :ts=8
  88.     include lmacros.h
  89. codeseg    segment    para public 'code'
  90.     public    $MEMRY
  91.     public    _mbot_, _sbot_, _mtop_
  92. dataseg    segment    para public 'data'
  93.     extrn    _Uorg_:byte,_Uend_:byte
  94. $MEMRY    dw    offset _Uend_
  95.     public    errno_
  96. errno_    dw    0
  97.     public    _dsval_,_csval_
  98. _dsval_    dw    0
  99. _csval_    dw    0
  100. _mbot_    dw    0
  101. _sbot_    dw    0
  102. _mtop_    dw    0
  103.     public    _PSP_
  104. _PSP_    dw    0
  105.     extrn    _STKSIZ_:word,_HEAPSIZ_:word
  106.     extrn    _STKLOW_:word
  107. dataseg    ends
  108. exitad    dw    0
  109. exitcs    dw    0
  110.  
  111.     assume    cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg
  112. ifdef FARPROC
  113.     extrn Croot_:far
  114. else
  115.     extrn Croot_:near
  116. endif
  117.     public    $begin
  118.     public    _exit_
  119. $begin    proc    far
  120.     mov    bp,dataseg
  121.     test    bp,bp
  122.     jnz    notcom
  123.     mov    bp,ds
  124. notcom:
  125.     mov    exitcs,ds
  126.     mov    bx,[2]    ;get top segment
  127.     sub    bx,bp        ;compute size of Data seg
  128.     cmp    bx,4096        ;check if greater than 64K
  129.     jbe    smallseg
  130.     lea    bx,[bp+4096]    ;end address of segment (paragraphs)
  131.     mov    ax,es
  132.     sub    bx,ax        ;compute length of segment
  133.     mov    ah,4aH        ;SETBLOCK system call
  134.     int    21H
  135.     mov    bx,4096
  136. smallseg:
  137.     mov    es,bp
  138.     mov    es:_PSP_,ds
  139.     mov    cl,4
  140.     shl    bx,cl
  141.     mov    cx,es:_STKLOW_
  142.     test    cx,cx
  143.     jz    setstk         ;stack goes above heap
  144.     mov    bx,es:_STKSIZ_    ;stack goes below heap
  145.     mov    cl,4
  146.     shl    bx,cl
  147.     add    bx, offset _Uend_
  148. setstk:
  149.     cli
  150.     mov    ss,bp
  151.     mov    sp,bx
  152.     sti
  153. ;
  154.     test    bx,bx
  155.     jnz    oksav
  156.     mov    bx,0ffffh
  157. oksav:
  158.     mov    es:_mtop_,bx
  159. ;                now adjust heap size if necessary
  160.     mov    si,es:_STKLOW_   ; can't do it unless heap above stack
  161.     test    si,si
  162.     jz    heapdone
  163.     mov    si,es:_HEAPSIZ_
  164.     mov    cx,bx
  165.     inc    cx
  166.     mov    es:$MEMRY,cx    ; start of heap for later
  167.     mov    cx,4
  168.     shl    si,cl
  169.     add    bx,si
  170.     jnc    heapok
  171.     mov    bx,0ffffh
  172. heapok:
  173.     mov    es:_mtop_,bx    ; and save as _mtop_
  174.     add    bx,15
  175.     mov    cx,4
  176.     shr    bx,cl
  177.     and    bx,01fffh    ; convert to paragraph form
  178.     mov    ax,es
  179.     add    bx,ax        ; calculate paragraph address of last byte
  180.     mov    ax,ds        ; now take the paragrph form and
  181.     sub    bx,ax        ;compute length of segment
  182.     mov    bp,es
  183.     mov    si,ds
  184.     mov    es,si
  185.     mov    ah,4aH        ;SETBLOCK system call
  186.     int    21H
  187.     jnc    heapdone
  188.     mov    ah,4ah
  189.     int    21h        ; get what you can get
  190.     jnc    heapdone
  191.     mov    ax,254
  192.     jmp    badexit
  193. heapdone:
  194.     mov    es,bp
  195.     cld
  196. ;        clear uninitialized data
  197.     mov    di,offset _Uorg_
  198.     mov    cx,offset _Uend_
  199.     sub    cx,di
  200.     inc    cx
  201.     shr    cx,1
  202.     jcxz    noclear
  203.     sub    ax,ax
  204. rep    stosw
  205. noclear:
  206. ;
  207.     mov    es,[2cH]        ;get enviroment segment
  208.     sub    di,di
  209.     mov    cx,7fffH
  210. arglook:
  211.     mov    ah,es:byte ptr [di]
  212.     cmp    ah,'='            ;look for null named env. string
  213.     je    found_args
  214.     test    ah,ah
  215.     jz    no_args
  216. repne    scasb                ;look for null byte
  217.     jz    arglook
  218. no_args:
  219.     mov    cl,[80H]
  220.     sub    ch,ch
  221.     mov    si,81H
  222.     mov    ax,1
  223.     jmp    short mov_args
  224. ;
  225. found_args:
  226.     sub    ax,ax
  227.     stosb            ;zap and skip over '='
  228.     mov    si,di
  229.     mov    di,es
  230.     mov    ds,di
  231. mov_args:
  232.     push    ax            ;first arg # for Croot
  233.     mov    es,bp            ;reload ES with our real dataseg
  234.     mov    di,es:$MEMRY
  235.     push    di            ;argp for Croot
  236.     jcxz    cpy_done
  237. cpy_args:                ;copy argument string to work buffer
  238.     lodsb
  239.     test    al,al
  240.     jz    cpy_done
  241.     stosb
  242.     loop    cpy_args
  243. cpy_done:
  244.     sub    al,al
  245.     stosb            ;null terminate string
  246.     mov    ds,bp        ;set DS, now DS, SS, ES are equal
  247.     inc    di
  248.     and    di,0fffeH    ;adjust to word boundary
  249.     mov    $MEMRY,di    ;save memory allocation info for sbrk()
  250.     mov    _mbot_,di
  251.     mov    ax,_STKLOW_
  252.     test    ax,ax
  253.     jnz    nostk
  254.     mov    ax,sp
  255.     mov    bx,_STKSIZ_
  256.     test    bx,bx
  257.     jnz    gotsiz
  258.     mov    bx,800h
  259. gotsiz:
  260.     mov    cx,4
  261.     shl    bx,cl
  262.     sub    ax,bx
  263.     mov    _sbot_,ax
  264. nostk:
  265.     mov    _dsval_,ds
  266.     mov    _csval_,cs
  267.     call    Croot_        ;Croot(argp, first)
  268.     jmp    short exits
  269. _exit_:
  270.     pop    ax
  271.     pop    ax        ;fetch return code
  272. ifdef FARPROC
  273. exit    label    far
  274. else
  275. exit:
  276. endif
  277. exits:
  278. badexit:
  279.     mov    ah,4cH
  280.     int    21H
  281.     jmp    dword ptr exitad
  282. $begin    endp
  283. codeseg    ends
  284.     end    $begin
  285. chmod.asm
  286. ; :ts=8
  287. ;Copyright (C) 1984 by Manx Software Systems
  288.     include    lmacros.h
  289. dataseg    segment    word public 'data'
  290.     extrn    errno_:word
  291. dataseg    ends
  292.     procdef    chmod, <<filnam,ptr>,<attr,word>>
  293.     pushds
  294.     mov    ax,4301h
  295.     ldptr    dx,filnam,ds
  296.     mov    cx,attr
  297.     int    21h
  298.     popds
  299.     jnc    retok
  300.     mov    ds:errno_,ax
  301.     mov    ax,-1
  302.     pret
  303. retok:
  304.     sub    ax,ax
  305.     pret
  306.     pend    chmod
  307.     finish
  308.     end
  309. croot.c
  310. /* Copyright (C) 1981,1982, 1983 by Manx Software Systems */
  311. #include "errno.h"
  312. #include "fcntl.h"
  313.  
  314. static char **Argv;
  315. static int Argc;
  316.  
  317. noper()
  318. {
  319.     return 0;
  320. }
  321.  
  322. int (*cls_)() = noper;
  323. extern char _ioflg[];
  324.  
  325. Croot(cp, first)
  326. register char *cp;
  327. {
  328.     register char **cpp;
  329.     char *sbrk();
  330. #ifdef REDIR
  331.     register int k;
  332.     register char *fname;
  333. #endif
  334.  
  335.     _ioflg[0] = isatty(0);    /* set flag for i/o routines */
  336.     _ioflg[1] = isatty(1);    /* set flag for i/o routines */
  337.     _ioflg[2] = isatty(2);    /* set flag for i/o routines */
  338.  
  339.     Argv = (char **)sbrk((first+1)*sizeof(char *));
  340.     Argv[0] = "";
  341.     cpp = &Argv[Argc = first];
  342.     for (;;) {
  343.         while (*cp == ' ' || *cp == '\t')
  344.             ++cp;
  345.         if (*cp == 0)
  346.             break;
  347. #ifdef REDIR
  348.         if (*cp == '>') {        /* redirect output */
  349.             k = 1;
  350.             goto redirect;
  351.         } else if (*cp == '<') {    /* redirect input */
  352.             k = 0;
  353. redirect:
  354.             while (*++cp == ' ' || *cp == '\t')
  355.                 ;
  356.             fname = cp;
  357.             while (*++cp)
  358.                 if (*cp == ' ' || *cp == '\t') {
  359.                     *cp++ = 0;
  360.                     break;
  361.                 }
  362.             close(k);
  363.             if (k)
  364.                 k = creat(fname, 0666);
  365.             else
  366.                 k = open(fname, O_RDONLY);
  367.             if (k == -1)
  368.                 redir_err(fname);
  369.         } else 
  370. #endif
  371.         {
  372.             *cpp++ = cp;
  373.             Argc++;
  374.             if (sbrk(sizeof(char *)) == (char *)-1) {
  375.                 write(2, "Too many args.", 14);
  376.                 _exit(200);
  377.             }
  378.             while (*++cp)
  379.                 if (*cp == ' ' || *cp == '\t') {
  380.                     *cp++ = 0;
  381.                     break;
  382.                 }
  383.         }
  384.     }
  385.     *cpp = 0;
  386.     main(Argc,Argv);
  387.     exit(0);
  388. }
  389.  
  390. #ifdef REDIR
  391. static redir_err(name)
  392. char *name;
  393. {
  394.     char buff[200];
  395.  
  396.     strcpy(buff, "Can't open file for redirection: ");
  397.     strcat(buff, name);
  398.     strcat(buff, "\n");
  399.     write(2, buff, strlen(buff));
  400.     exit(10);
  401. }
  402. #endif
  403.  
  404. exit(code)
  405. {
  406.     (*cls_)();
  407.     _exit(code);
  408. }
  409.  
  410. crt0.asm
  411. ; Copyright (C) 1983 1984 by Manx Software Systems
  412. ; :ts=8
  413. PGROUP    group    @CODE,PROG
  414. @CODE    segment    byte public 'CODE'
  415. @CODE    ends
  416. PROG    segment    byte public 'CODE'
  417. PROG    ends
  418.  
  419. DGROUP    group    @DATAB,DATA,@DATAC,@DATAI,@DATAT,@DATAU,@DATAV,@STACK
  420.  
  421. @DATAB    segment    para public 'DATAB'
  422. @DATAB    ends
  423.  
  424. DATA    segment    word public 'DATA'
  425.     db    'Aztec C86 version 3.20x',0
  426.     even
  427.     public    _Dorg
  428. _Dorg    label     byte
  429. DATA    ends
  430.  
  431. @DATAC    segment    word public 'DATAC'
  432. @DATAC    ends
  433. @DATAI    segment    word public 'DATAI'
  434. @DATAI    ends
  435.  
  436. @DATAT    segment    word public 'DATAT'
  437.     public    _Dend
  438. _Dend    label     byte
  439.     public    _Uorg
  440. _Uorg    label     byte
  441. @DATAT    ends
  442.  
  443. @DATAU    segment    word public 'DATAU'
  444. @DATAU    ends
  445.  
  446. @DATAV    segment    word public 'DATAV'
  447.     public    _Uend
  448. _Uend    label     byte
  449. @DATAV    ends
  450.  
  451. @STACK    segment    para stack 'STACK'
  452. First    db    2048 dup (?)
  453. @STACK    ends
  454.     end
  455. csread.asm
  456. ; Copyright (C) 1983, 1984 by Manx Software Systems
  457. ; :ts=8
  458.     include    lmacros.h
  459. dataseg    segment    word public 'data'
  460.     extrn    errno_:word
  461. dataseg ends
  462.     procdef    _csread,<<fd,word>,<addr,fptr>,<len,word>>
  463. ;            _csread(fd, char *addr, len)
  464. ;            read data into code segment
  465.     mov    bx,fd
  466.     push    ds
  467. ifdef FARPROC
  468.     lds    dx,addr
  469. else
  470.     mov    dx,addr
  471. endif
  472.     mov    cx,len
  473. ifndef FARPROC
  474.     mov    ax,cs
  475.     mov    ds,ax
  476. endif
  477.     mov    ah,3fH
  478.     int    21H
  479.     pop    ds
  480.     jnc    ret_ok
  481.     mov    ds:errno_,ax
  482.     mov    ax,-1
  483. ret_ok:
  484.     pret
  485.     pend    _csread
  486.     finish
  487.     end
  488. ctime.c
  489. /* Copyright (C) 1984 by Manx Software Systems */
  490. #include <time.h>
  491.  
  492. char *
  493. ctime(clock)
  494. long *clock;
  495. {
  496.     struct tm *tm;
  497.  
  498.     tm = localtime(clock);
  499.     return asctime(tm);
  500. }
  501. dioctl.asm
  502. ; Copyright (C) 1983 by Manx Software Systems
  503. ; :ts=8
  504.     include    lmacros.h
  505. dataseg    segment word public 'data'
  506.     extrn    errno_:word
  507. dataseg    ends
  508.     procdef    _ioctl, <<fd,word>,<req,byte>,<arg,ptr>,<len,word>>
  509. ;            _ioctl(fd, req, arg[, len])
  510.     mov    bx,fd
  511.     mov    ah,44H
  512.     mov    al,req
  513.     cmp    al,0
  514.     je    getinfo
  515.     cmp    al,1
  516.     je    setinfo
  517.     cmp    al,6
  518.     jge    getstat
  519.     pushds
  520.     ldptr    dx,arg,ds
  521.     mov    cx,len
  522.     int    21H
  523.     popds
  524.     jnc    xret_ok
  525.     mov    ds:errno_,ax
  526.     mov    ax,-1
  527. xret_ok:
  528.     pret
  529. ;
  530. doint    proc    near
  531.     int    21H
  532.     jnc    ret_ok
  533.     mov    ds:errno_,ax
  534.     mov    ax,-1
  535. ret_ok:
  536.     ret
  537. doint    endp
  538. ;
  539. getstat:
  540.     call    doint
  541.     pret
  542. ;
  543. getinfo:
  544.     call    doint
  545.     jc    err
  546.     ldptr    bx,arg,es
  547. ifdef LONGPTR
  548.     mov    es:[bx],dx
  549. else
  550.     mov    ds:[bx],dx
  551. endif
  552.     sub    ax,ax
  553. err:
  554.     pret
  555. ;
  556. setinfo:
  557.     ldptr    bx,arg,es
  558. ifdef LONGPTR
  559.     mov    dl,es:[bx]
  560. else
  561.     mov    dl,ds:[bx]
  562. endif
  563.     sub    dh,dh
  564.     mov    bx,fd
  565.     call    doint
  566.     jc    err
  567.     sub    ax,ax
  568.     pret
  569.     pend    _ioctl
  570.     finish
  571.     end
  572. dos.asm
  573. ; Copyright (C) 1983, 1984 by Manx Software Systems
  574. ; :ts=8
  575.     include    lmacros.h
  576. dataseg    segment    para public 'data'
  577.     extrn    errno_:word
  578. dataseg ends
  579.     assume    ds:dataseg
  580.     procdef    dos,<<func,word>,<bxval,word>,<cxval,word>,<dxval,word>,<dival,word>,<sival,word>>
  581. ;            dos(ax,bx,cx,dx,di,si)
  582.     push    di
  583.     push    si
  584. ifndef LONGPTR
  585.     mov    ax,ds
  586.     mov    es,ax
  587. endif
  588.     mov    ax,func
  589.     test    ah,ah
  590.     jnz    skip
  591.     xchg    ah,al
  592. skip:
  593.     mov    bx,bxval
  594.     mov    cx,cxval
  595.     mov    dx,dxval
  596.     mov    di,dival
  597.     mov    si,sival
  598.     int    21H
  599.     jnc    ret_ok
  600.     mov    errno_,ax
  601.     mov    ax,-1
  602. ret_ok:
  603.     pop    si
  604.     pop    di
  605.     pret
  606.     pend    dos
  607.     finish
  608.     end
  609. dostime.asm
  610. ; Copyright (C) 1984 by Manx Software Systems
  611. ; :ts=8
  612.     include    lmacros.h
  613. codeseg    segment    byte public "code"
  614. days    dw    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333
  615. codeseg    ends
  616.     procdef    dostime, <<arg,ptr>>
  617.     push    es
  618.     push    si
  619. ;
  620.     mov    ah,2aH
  621.     int    21h
  622.     ldptr    bx,arg,es
  623.     sub    cx,1900
  624. ifndef LONGPTR
  625.     mov    ds:word ptr 10[bx],cx    ;year - 1900
  626. else
  627.     mov    es:word ptr 10[bx],cx    ;year - 1900
  628. endif
  629.     sub    ah,ah
  630.     mov    al,dh
  631.     dec    al
  632. ifndef LONGPTR
  633.     mov    ds:word ptr 8[bx],ax    ;month
  634. else
  635.     mov    es:word ptr 8[bx],ax    ;month
  636. endif
  637.     mov    al,dl
  638. ifndef LONGPTR
  639.     mov    ds:word ptr 6[bx],ax    ;day of month
  640. else
  641.     mov    es:word ptr 6[bx],ax    ;day of month
  642. endif
  643. ;
  644.     mov    ah,2cH
  645.     int    21H
  646.     ldptr    bx,arg,es
  647.     sub    ah,ah
  648.     mov    al,ch
  649. ifndef LONGPTR
  650.     mov    ds:word ptr 4[bx],ax    ;hour
  651.     mov    al,cl
  652.     mov    ds:word ptr 2[bx],ax    ;minute
  653.     mov    al,dh
  654.     mov    ds:word ptr [bx],ax    ;seconds
  655.     mov    al,dl
  656.     mov    ds:word ptr 18[bx],ax    ;1/100 seconds
  657. ;
  658.     sub    ax,ax
  659.     mov    si,ds:word ptr 8[bx]
  660.     cmp    si,2
  661.     jb    noleap
  662.     test    ds:byte ptr 10[bx],3
  663.     jnz    noleap
  664.     inc    ax
  665. noleap:
  666.     shl    si,1
  667.     add    ax,cs:days[si]
  668.     add    ax,ds:word ptr 6[bx]
  669.     mov    ds:word ptr 14[bx],ax    ;day of year
  670. ;
  671.     mov    si,ds:word ptr 10[bx]
  672. else
  673.     mov    es:word ptr 4[bx],ax    ;hour
  674.     mov    al,cl
  675.     mov    es:word ptr 2[bx],ax    ;minute
  676.     mov    al,dh
  677.     mov    es:word ptr [bx],ax    ;seconds
  678.     mov    al,dl
  679.     mov    es:word ptr 18[bx],ax    ;1/100 seconds
  680. ;
  681.     sub    ax,ax
  682.     mov    si,es:word ptr 8[bx]
  683.     cmp    si,2
  684.     jb    noleap
  685.     test    es:byte ptr 10[bx],3
  686.     jnz    noleap
  687.     inc    ax
  688. noleap:
  689.     shl    si,1
  690.     add    ax,cs:days[si]
  691.     add    ax,es:word ptr 6[bx]
  692.     mov    es:word ptr 14[bx],ax    ;day of year
  693. ;
  694.     mov    si,es:word ptr 10[bx]
  695. endif
  696.     add    ax,si
  697.     dec    si
  698.     shr    si,1
  699.     shr    si,1
  700.     add    ax,si
  701.     inc    ax
  702.     sub    dx,dx
  703.     mov    cx,7
  704.     div    cx
  705. ifndef LONGPTR
  706.     mov    ds:word ptr 12[bx],dx    ;day of week
  707. ;
  708.     mov    ds:word ptr 16[bx],0    ;say no D.S.T. for now
  709. else
  710.     mov    es:word ptr 12[bx],dx    ;day of week
  711. ;
  712.     mov    es:word ptr 16[bx],0    ;say no D.S.T. for now
  713. endif
  714.     pop    si
  715.     pop    es
  716.     pret
  717.     pend    dostime
  718.     finish
  719.     end
  720. dup.asm
  721. ; Copyright (C) 1984 by Manx Software Systems
  722. ; :ts=8
  723.     include    lmacros.h
  724. dataseg    segment word public 'data'
  725.     extrn    errno_:word
  726. dataseg    ends
  727.     assume    ds:dataseg
  728.     procdef    dup,<<ofd,word>>
  729. ;            dup(ofd) : duplicate file descriptor
  730. ;            if ok, returns new fd. if error, returns -1.
  731.     mov    ah,45h
  732. dupx:
  733.     mov    bx,ofd
  734.     int    21H
  735.     jnc    ret_ok
  736.     mov    errno_,ax
  737.     mov    ax,-1
  738. ret_ok:
  739.     pret
  740.     pend    dup
  741. ;
  742.     procdef    fdup,<<oofd,word>,<nfd,word>>
  743. ;            fdup(ofd, nfd): force dup of ofd into nfd
  744. ;                If nfd is open it will be closed.
  745. ;            if ok, returns nfd; if error, returns -1
  746.     mov    cx,nfd
  747.     mov    ah,46h
  748.     jmp    dupx
  749.     pend    fdup
  750.     finish
  751.     end
  752. exec.asm
  753. ; Copyright (C) 1984 by Manx Software Systems
  754. ; :ts=8
  755.     include    lmacros.h
  756.  
  757. ifdef FARPROC
  758.     extrn    _sigfix_:far
  759. else
  760.     extrn    _sigfix_:near
  761. endif
  762. ;
  763. e_magic    equ    0
  764. e_used    equ    2    ;number of bytes used in final sector of file
  765. e_pages    equ    4    ;size of file in 512-byte pages
  766. e_nreloc equ    6    ;number relocation table items
  767. e_hsize    equ    8    ;size of header in 16-byte paragraphs
  768. e_min    equ    10    ;minimum # of para required above program
  769. e_max    equ    12    ;maximum # of para    "       "      "
  770. e_ss    equ    14    ;offset of stack segment in load module
  771. e_sp    equ    16    ;initial SP value
  772. e_csum    equ    18    ;negative sum of all words in the file
  773. e_ip    equ    20    ;starting IP for program
  774. e_cs    equ    22    ;   "     CS    "
  775. e_freloc equ    24    ;offset of first relocation item
  776. e_ovly    equ    26    ;overlay number
  777.  
  778. ;
  779. ldrsize    equ    1024
  780. header    equ    ldrsize-30
  781. reloc    equ    26
  782. startad    equ    0
  783. ;
  784. dataseg segment word public 'data'
  785.     extrn _PSP_:word
  786. dataseg ends
  787. ;
  788. ;exec(fd,cline,fcb1,fcb2,header)
  789. ;    NOTE: This function never returns, even if the exec
  790. ;    fails.
  791. ;
  792.     procdef exec,<<fd,word>,<cline,ptr>,<fcb1,ptr>,<fcb2,ptr>,<head,ptr>>
  793. ;
  794. ;    copy cmd line and fcb's into PSP
  795. ;
  796. load    proc far        ;so returns are far
  797.     push    ds
  798.     call    _sigfix_        ;restore int 22,23 vectors
  799.     mov    es,ds:_PSP_        ;fetch segment of PSP
  800.     ldptr    si,cline,ds
  801.     mov    di,80h
  802.     mov    cx,64
  803. rep    movsw                ;copy command line
  804.     ldptr    si,fcb1,ds
  805.     mov    di,5ch
  806.     mov    cx,8
  807. rep    movsw                ;copy fcb1
  808.     ldptr    si,fcb2,ds
  809.     mov    cx,8
  810. rep    movsw                ;copy fcb2
  811. ;
  812.     mov    bx,0ffffh        ;ask for all of memory
  813.     mov    ah,4ah
  814.     int    21h
  815.     mov    ah,4ah            ;then ask for what we can get
  816.     int    21h
  817. ;
  818.     mov    dx,fd        ;file handle
  819.     ldptr    si,head,ds    ;exe header from file
  820.     cmp    ds:word ptr [si+e_magic],5a4dh    ;check magic #
  821.     je    exefile
  822.  
  823.     mov    bp,bx            ;compute new SP
  824.     cmp    bp,4096            ;check size of segment
  825.     jbe    smallstk
  826.     mov    bp,4096
  827. smallstk:
  828.     mov    cx,4
  829.     shl    bp,cl            ;new SP
  830. ;
  831.     mov    cx,es
  832.     add    bx,cx        ;end of our segment
  833.     sub    bx,8        ;get 128 bytes for loader and stack
  834.     mov    es,bx
  835.     pop    si        ; get old ds value back
  836.     mov    ss,bx
  837.     mov    sp,128
  838.     push    si        ; push old ds on stack for later use
  839. ;
  840.     mov    cx,cs
  841.     mov    ds,cx
  842.     mov    si,offset com_loader
  843.     sub    di,di
  844.     mov    cx,offset com_ldend
  845.     sub    cx,si
  846. rep    movsb
  847. ;
  848.     mov    bx,dx        ;handle into bx for io calls
  849.     sub    cx,cx
  850.     sub    dx,dx
  851.     mov    ax,4200H
  852.     int    21H        ;rewind file
  853. ;
  854.     mov    dx,100H        ;address to read data into
  855.     lea    cx,[bp-256]    ;byte count to read in
  856.     pop    ds
  857.     mov    ax,ds:_PSP_    ;segment of PSP
  858.     mov    ds,ax
  859.     mov    es,ax
  860.     push    ss
  861.     sub    ax,ax
  862.     push    ax
  863.     mov    ah,3fH
  864.     ret
  865. ;
  866. ;    this block of code is moved to the top of available memory
  867. ;    and jumped to with the registers for a read call setup
  868. ;
  869. com_loader:
  870.     int    21h
  871.     jnc    ok
  872.     mov    ax,4cfeh
  873.     int    21h
  874. ok:
  875.     mov    ah,3eH
  876.     int    21h        ;close the file
  877.     mov    ax,ds
  878.     mov    ss,ax
  879.     mov    sp,bp
  880.     push    ax        ;push new cs
  881.     mov    ax,100h
  882.     push    ax        ;push new ip
  883.     ret
  884. com_ldend:
  885. ;
  886. ;
  887. exefile:
  888.     mov    cx,es
  889.     add    bx,cx        ;end of our segment
  890.     sub    bx,ldrsize/16    ;get mem for loader, header, and stack
  891.     mov    es,bx
  892.     mov    di,header
  893.     mov    cx,13
  894. rep    movsw                ;copy 26 byte file header
  895. ;
  896.     pop    si        ; get old ds value
  897.     mov    ss,bx
  898.     mov    sp,header
  899.     push    si        ; push old ds value on new stack for later use
  900. ;
  901.     mov    cx,cs
  902.     mov    ds,cx
  903.     mov    si,offset exe_loader
  904.     sub    di,di
  905.     mov    cx,offset exe_ldend
  906.     sub    cx,si
  907. rep    movsb
  908. ;
  909.     pop    ds    
  910.     mov    ax,ds:_PSP_    ;segment of PSP
  911.     push    ax        ;ES, DS value for program
  912.     add    ax,10h
  913.     mov    ds,ax        ;place to load program
  914.     mov    bp,ax
  915.     mov    bx,dx        ;get handle into bx for int 21h
  916. ;
  917.     mov    di,header
  918.     mov    dx,ss:e_hsize[di]    ;compute offset of program
  919.     sub    ax,ax
  920.     mov    cl,4
  921. lshift:
  922.     shl    dx,1
  923.     rcl    ax,1
  924.     loop    lshift
  925.     mov    cx,ax
  926.     mov    ax,4200H
  927.     int    21h        ;lseek to load module
  928.     jc    punt
  929. ;
  930.     mov    si,ss:e_pages[di]
  931.     mov    cl,5
  932.     shl    si,cl        ;# paragraphs in file
  933.     sub    si,ss:e_hsize[di]    ;now, # para in program
  934. ;
  935.     push    ss        ;CS for loader
  936.     sub    ax,ax
  937.     push    ax        ;IP for loader
  938.     ret            ;far return to code at top of mem
  939. ;
  940. ;    this code is moved to the top of our segment and jumped to
  941. ;    with the following registers setup:
  942. ;        bx - file handle of program
  943. ;        ds, bp - where to load the program
  944. ;        di - points to the exe header
  945. ;        si - # para to read in
  946. ;        PSP address pushed onto stack
  947. ;
  948. exe_loader:
  949.     mov    ah,3fH
  950.     mov    cx,1024
  951.     sub    dx,dx
  952.     int    21h
  953.     jc    punt
  954.     test    ax,ax
  955.     jz    load_done
  956.     mov    ax,ds
  957.     add    ax,64
  958.     mov    ds,ax
  959.     sub    si,64
  960.     ja    exe_loader
  961. ;
  962. load_done:
  963.     mov    ax,cs
  964.     mov    ds,ax
  965.     cmp    word ptr e_nreloc[di],0
  966.     jz    reloc_done
  967.     mov    dx,e_freloc[di]
  968.     sub    cx,cx
  969.     mov    ax,4200H
  970.     int    21H        ;lseek to relocation info
  971.     jc    punt
  972. relocate:
  973.     lea    dx,reloc[di]
  974.     mov    cx,4
  975.     mov    ah,3fH
  976.     int    21H
  977.     jc    punt
  978.     cmp    ax,4
  979.     jne    punt
  980.     mov    si,reloc[di]
  981.     mov    ax,reloc+2[di]
  982.     add    ax,bp
  983.     mov    es,ax
  984.     add    es:[si],bp
  985.     dec    word ptr e_nreloc[di]
  986.     jnz    relocate
  987. reloc_done:
  988.     mov    ah,3eH
  989.     int    21h        ;close file
  990.     add    e_ss[di],bp    ;relocate stack segment
  991.     add    e_cs[di],bp    ;relocate starting CS
  992.     pop    ax        ;get PSP address before changing stack
  993.     mov    ss,e_ss[di]
  994.     mov    sp,e_sp[di]
  995.     mov    ds,ax
  996.     mov    es,ax
  997.     jmp    cs:dword ptr e_ip[di]
  998. punt:
  999.     mov    ax,4cfeh
  1000.     int    21h
  1001. exe_ldend:
  1002. load    endp
  1003.     pend    exec
  1004.     finish
  1005.     end
  1006. execl.c
  1007. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1008.  
  1009. execl(path, args)
  1010. char *path, *args;
  1011. {
  1012.     return execv(path, &args);
  1013. }
  1014. execlp.c
  1015. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1016.  
  1017. execlp(name, args)
  1018. char *name, *args;
  1019. {
  1020.     return execvp(name, &args);
  1021. }
  1022.  
  1023. execv.c
  1024. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1025.  
  1026. #define EXEMAGIC    0x5a4d
  1027.  
  1028. struct exehead {        /* MS-dos .exe file header */
  1029.     int e_magic;
  1030.     int e_used;            /* number of bytes used in final sector of file */
  1031.     int e_pages;        /* size of file in 512-byte pages */
  1032.     int e_nreloc;        /* number relocation table items */
  1033.     int e_hsize;        /* size of header in 16-byte paragraphs */
  1034.     int e_min;            /* minimum # of para required above program */
  1035.     int e_max;            /* maximum # of para    "       "      " */
  1036.     unsigned e_ss;        /* offset of stack segment in load module */
  1037.     unsigned e_sp;        /* initial SP value */
  1038.     unsigned e_csum;    /* negative sum of all words in the file */
  1039.     unsigned e_ip;        /* starting IP for program */
  1040.     unsigned e_cs;        /*    "     CS    " */
  1041.     int e_freloc;        /* offset of first relocation item */
  1042.     int e_ovly;            /* overlay number */
  1043. };
  1044.  
  1045. execv(path, argv)
  1046. char *path, **argv;
  1047. {
  1048.     register char *cp, *xp;
  1049.     int i, fd;
  1050.     char buffer[130];
  1051.     char fcb1[16], fcb2[16];
  1052.     struct exehead header;
  1053.  
  1054.     if ((fd = open(path,0)) == -1)
  1055.         return -1;
  1056.     if (read(fd, &header, sizeof header) != sizeof header)
  1057.         header.e_magic = 0;
  1058.  
  1059.     cp = buffer+1;
  1060.     i = 1;
  1061.     if (*argv) {
  1062.         ++argv;            /* skip arg0, used for unix (tm) compatibility */
  1063.         while (xp = *argv++) {
  1064.             if (i == 1)
  1065.                 fcbinit(xp, fcb1);
  1066.             else if (i == 2)
  1067.                 fcbinit(xp, fcb2);
  1068.             *cp++ = ' ';
  1069.             while (*xp) {
  1070.                 if (cp >= buffer+128)
  1071.                     goto done;
  1072.                 *cp++ = *xp++;
  1073.             }
  1074.             ++i;
  1075.         }
  1076.     }
  1077. done:
  1078.     buffer[0] = cp - (buffer+1);
  1079.     return exec(fd, buffer, fcb1, fcb2, &header);
  1080. }
  1081.  
  1082. execvp.c
  1083. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1084.  
  1085. execvp(name, argv)
  1086. char *name, **argv;
  1087. {
  1088.     register char *cp, *xp;
  1089.     char *getenv(), path[64];
  1090.  
  1091.     tryexec("", name, argv);
  1092.     if ((cp = getenv("PATH")) != 0) {
  1093.         while (*cp) {
  1094.             xp = path;
  1095.             while (*cp) {
  1096.                 if (*cp == ';') {
  1097.                     ++cp;
  1098.                     break;
  1099.                 }
  1100.                 *xp++ = *cp++;
  1101.             }
  1102.             *xp = 0;
  1103.             if (path[0] != 0)
  1104.                 tryexec(path, name, argv);
  1105.         }
  1106.     }
  1107.     return -1;
  1108. }
  1109.  
  1110. static
  1111. tryexec(dir, name, argv)
  1112. char *dir, *name, **argv;
  1113. {
  1114.     char newname[64];
  1115.     register char *cp;
  1116.     char *strchr(), *strrchr();
  1117.  
  1118.     strcpy(newname, dir);
  1119.     if (((cp = strchr(newname, '/')) || (cp = strchr(newname, '\\')))
  1120.                 && *(cp+1) != 0)
  1121.         strcat(newname, "/");
  1122.     strcat(newname, name);
  1123.     if (strchr(name, '.') == 0) {
  1124.         strcat(newname, ".com");
  1125.         execv(newname, argv);
  1126.         strcpy(strrchr(newname,'.'), ".exe");
  1127.     }
  1128.     execv(newname, argv);
  1129. }
  1130. fcbinit.asm
  1131. ;Copyright (C) 1983 by Manx Software Systems
  1132. ; :ts=8
  1133.     include lmacros.h
  1134.     procdef fcbinit, <<jname,ptr>,<fcb,ptr>>
  1135.     pushds
  1136.     push    di
  1137.     push    si
  1138. ifndef LONGPTR
  1139.     mov    di,ds
  1140.     mov    es,di
  1141. endif
  1142.     ldptr    si,jname
  1143.     ldptr    di,fcb
  1144.     mov    ax,2900H    ; issue parse filename call
  1145.     int    21H
  1146.     and    ax,0ffH
  1147.     cmp    es:byte ptr 1[di],' '
  1148.     jne    nameok
  1149.     mov    ax,-1
  1150. nameok:
  1151.     pop    si
  1152.     pop    di
  1153.     popds
  1154.     pret
  1155.     pend    fcbinit
  1156.     finish
  1157.     end
  1158. fexec.asm
  1159. ; Copyright (C) 1984 by Manx Software Systems
  1160. ; :ts=8
  1161.     include lmacros.h
  1162. dataseg segment para public 'data'
  1163. param    equ    this word
  1164. env    dw    ?
  1165. cline    dw    ?,?
  1166. fcb1    dw    ?,?
  1167. fcb2    dw    ?,?
  1168.     extrn    errno_:word
  1169. dataseg    ends
  1170.     assume    ds:dataseg
  1171. save_ss    dw    0
  1172. save_sp    dw    0
  1173.     procdef    fexec,<<filname,ptr>,<enva,word>,<clinea,ptr>,<fcb1a,ptr>,<fcb2a,ptr>>
  1174. ;            char *fexec(name,env,cline,fcb1,fcb2)
  1175. ;
  1176.     push    si
  1177.     push    di
  1178.     pushf
  1179.     push    [030H]
  1180.     push    [02EH]
  1181.     push    ds
  1182.     push    es
  1183.     mov    cs:save_ss,ss
  1184.     mov    cs:save_sp,sp
  1185. ;
  1186. ;    set up parameter block for exec call
  1187. ;
  1188.     mov    ax,enva
  1189.     mov    env,ax
  1190. ifndef LONGPTR
  1191.     mov    ax,ds
  1192.     mov    es,ax
  1193. endif
  1194.     ldptr    ax,clinea,es
  1195.     mov    cline,ax
  1196.     mov    cline+2,es
  1197.     ldptr    ax,fcb1a,es
  1198.     mov    fcb1,ax
  1199.     mov    fcb1+2,es
  1200.     ldptr    ax,fcb2a,es
  1201.     mov    fcb2,ax
  1202.     mov    fcb2+2,es
  1203. ;
  1204.     mov    ax,ds
  1205.     mov    es,ax
  1206.     mov    bx,offset param
  1207.     ldptr    dx,filname,ds        ;name of file to exec
  1208.     mov    ax,04b00H
  1209.     int    21h
  1210.     mov    ss,cs:save_ss
  1211.     mov    sp,cs:save_sp
  1212.     pop    es
  1213.     pop    ds
  1214.     jnc    noerror
  1215.     mov    errno_,ax
  1216.     mov    ax,-1
  1217.     jmp    short done
  1218. noerror:
  1219.     sub    ax,ax
  1220. done:
  1221.     pop    [02EH]
  1222.     pop    [030H]
  1223.     popf
  1224.     pop    di
  1225.     pop    si
  1226.     pret
  1227.     pend    fexec
  1228.     finish
  1229.     end
  1230. fexecl.c
  1231. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1232.  
  1233. fexecl(path, args)
  1234. char *path, *args;
  1235. {
  1236.     return fexecv(path, &args);
  1237. }
  1238. fexecv.c
  1239. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1240.  
  1241. fexecv(path, argv)
  1242. char *path, **argv;
  1243. {
  1244.     register char *cp, *xp;
  1245.     int i;
  1246.     char buffer[130];
  1247.     char fcb1[16], fcb2[16];
  1248.  
  1249.     cp = buffer+1;
  1250.     i = 1;
  1251.     if (*argv) {
  1252.         ++argv;            /* skip arg0, used for unix (tm) compatibility */
  1253.         while (xp = *argv++) {
  1254.             if (i == 1)
  1255.                 fcbinit(xp, fcb1);
  1256.             else if (i == 2)
  1257.                 fcbinit(xp, fcb2);
  1258.             *cp++ = ' ';
  1259.             while (*xp) {
  1260.                 if (cp >= buffer+128)
  1261.                     goto done;
  1262.                 *cp++ = *xp++;
  1263.             }
  1264.             ++i;
  1265.         }
  1266.     }
  1267. done:
  1268.     buffer[0] = cp - (buffer+1);
  1269.     return fexec(path, 0, buffer, fcb1, fcb2);
  1270. }
  1271.  
  1272. ftime.asm
  1273. ; :ts=8
  1274. ;Copyright (C) 1984 by Manx Software Systems
  1275.     include    lmacros.h
  1276. dataseg    segment    para public 'data'
  1277.     extrn    errno_:word
  1278. dataseg    ends
  1279.     assume    ds:dataseg
  1280.     procdef ftime,<<get,byte>,<fd,word>,<newt1,word>,<newt2,word>>
  1281. ;
  1282. ;long ftime(get/set, fd, [long newtime])
  1283. ;
  1284.     mov    ah,57h
  1285.     mov    al,get
  1286.     mov    bx,fd
  1287.     mov    cx,newt1
  1288.     mov    dx,newt2
  1289.     int    21h
  1290.     jnc    retok
  1291.     mov    errno_,ax
  1292.     mov    ax,-1
  1293.     mov    dx,ax
  1294.     pret
  1295. retok:
  1296.     test    get,1
  1297.     jz    gettime
  1298.     sub    dx,dx
  1299.     mov    cx,dx
  1300. gettime:
  1301.     mov    ax,cx
  1302.     pret
  1303.     pend    ftime
  1304.     finish
  1305.     end
  1306. getcwd.c
  1307. /* Copyright (C) 1984 by Manx Software Systems */
  1308.  
  1309. char *
  1310. getcwd(buf, size)
  1311. char *buf;
  1312. {
  1313.     char *malloc();
  1314.     int allflag = 0;
  1315.  
  1316.     if (buf == 0) {
  1317.         if ((buf = malloc(size)) == 0)
  1318.             return 0;
  1319.         allflag = 1;
  1320.     }
  1321.     if (_sys(0x47,buf,0) == -1) {
  1322.         if (allflag)
  1323.             free(buf);
  1324.         return 0;
  1325.     }
  1326.     return buf;
  1327. }
  1328. getenv.asm
  1329. ; Copyright (C) 1984 by Manx Software Systems
  1330. ; :ts=8
  1331.     include    lmacros.h
  1332. dataseg segment para public 'data'
  1333.     ifndef    LONGPTR
  1334. retbuf    db    256 dup (?)
  1335.     endif
  1336.     extrn    _PSP_:word
  1337. dataseg    ends
  1338.     assume    ds:dataseg
  1339.     procdef    getenv, <<jname,ptr>>
  1340. ;            char *getenv(name)
  1341. ;            char *name;
  1342. ;
  1343.     push    ds
  1344.     push    si
  1345.     push    di
  1346. ifndef LONGPTR
  1347.     mov    bx,ds
  1348.     mov    es,bx
  1349. endif
  1350.     cld
  1351.     ldptr    bx,jname,es
  1352.     mov    ds,ds:_PSP_    ;fetch segment of PSP
  1353.     mov    ds,ds:[2cH]    ;get environment segment
  1354.     sub    si,si
  1355. envloop:
  1356.     lodsb
  1357.     test    al,al
  1358.     jz    nostring
  1359.     sub    di,di
  1360. cmploop:
  1361.     cmp    al,'='
  1362.     jne    notaneq
  1363.     sub    al,al
  1364. notaneq:
  1365.     cmp    al,es:[bx][di]
  1366.     jne    next
  1367.     test    al,al
  1368.     je    foundit
  1369.     inc    di
  1370.     lodsb
  1371.     test    al,al
  1372.     jne    cmploop
  1373.     jmp    envloop
  1374. next:
  1375.     lodsb
  1376.     test    al,al
  1377.     jne    next
  1378.     jmp    envloop
  1379. ;
  1380. foundit:
  1381. ifndef LONGPTR
  1382. ;
  1383. ; copy string to local buffer, so we can return a 16-bit pointer to it.
  1384. ;
  1385.     mov    di,offset retbuf
  1386.     mov    cx,255
  1387. cpyloop:
  1388.     lodsb
  1389.     stosb
  1390.     test    al,al
  1391.     loopnz    cpyloop
  1392.     sub    al,al
  1393.     stosb            ;guarantee null termination
  1394.     mov    ax,offset retbuf
  1395.     test    ax,ax
  1396.     jmp    short done
  1397. ;
  1398. nostring:
  1399.     sub    ax,ax
  1400. done:
  1401. else
  1402.     mov    dx,ds
  1403.     mov    ax,si
  1404.     jmp    short done
  1405.  
  1406. nostring:
  1407.     sub    ax,ax
  1408.     sub    dx,dx
  1409.  
  1410. done:
  1411. endif
  1412.     pop    di
  1413.     pop    si
  1414.     pop    ds
  1415.     pret
  1416.     pend    getenv
  1417.     finish
  1418.     end
  1419. io.asm
  1420. ; Copyright (C) 1983 1984 by Manx Software Systems
  1421. ; :ts=8
  1422.     include lmacros.h
  1423.  
  1424. ifdef    FARPROC
  1425.     extrn    __tty_rd_:far,__tty_wr_:far
  1426. else
  1427.     extrn    __tty_rd_:near,__tty_wr_:near
  1428. endif
  1429.  
  1430. dataseg    segment    para public 'data'
  1431.     extrn    errno_:word
  1432.     public    _ioflg_
  1433. _ioflg_    db    20 dup (0)
  1434.     public    _ttrd_, _ttwr_
  1435.  
  1436. ifdef FARPROC
  1437. _ttrd_    dd    __tty_rd_
  1438. else
  1439. _ttrd_    dw    offset __tty_rd_
  1440. endif
  1441.  
  1442. ifdef    FARPROC
  1443. _ttwr_    dd    __tty_wr_
  1444. else
  1445. _ttwr_    dw    offset __tty_wr_
  1446. endif
  1447. dataseg    ends
  1448.  
  1449.     assume    ds:dataseg
  1450. ;
  1451.     procdef    _read, <<rdfd,word>,<xbuff,ptr>,<xlen,word>>
  1452.     mov    ah,3fH
  1453.     mov    bx,rdfd
  1454.     jmp    short use_dos
  1455.     pend    _read
  1456. ;
  1457.     procdef    _write, <<wrfd,word>,<ybuff,ptr>,<ylen,word>>
  1458.     mov    ah,40H
  1459.     mov    bx,wrfd
  1460.     jmp    short use_dos
  1461.     pend    _write
  1462. ;
  1463.     procdef    read, <<ifd,word>,<ibuffer,ptr>,<ilen,word>>
  1464.             ;read_(fd, buffer, length)
  1465.             ;char *buffer; int length;
  1466.  
  1467.     mov    ah,3fH
  1468.     jmp    short iocommon
  1469.     pend    read
  1470. ;
  1471.     procdef    write, <<fd,word>,<buffer,ptr>,<len,word>>
  1472.             ;write(fd, buffer, length)
  1473.             ;char *buffer; int length;
  1474.     mov    ah,40H
  1475. iocommon:
  1476.     mov    bx,fd
  1477.     cmp    _ioflg_[bx],0
  1478.     jz    use_dos
  1479.     pop    bp
  1480.     cmp    ah,03fH
  1481.     je    readit
  1482.     jmp    _ttwr_
  1483. readit:
  1484.     jmp    _ttrd_
  1485. ;
  1486. use_dos:
  1487.     pushds
  1488.     ldptr    dx,buffer,ds
  1489.     mov    cx,len
  1490.     int    21H
  1491.     popds
  1492.     jnc    io_ok
  1493.     mov    errno_,ax
  1494.     mov    ax,-1
  1495. io_ok:
  1496.     pret
  1497.     pend    write
  1498. ;
  1499.     procdef    close, <<ffd,word>>
  1500.         ;close(fd)
  1501.     mov    ah,3eH
  1502.     mov    bx,ffd
  1503.     int    21H
  1504.     jnc    cls_ok
  1505.     mov    errno_,ax
  1506.     mov    ax,-1
  1507.     pret
  1508. cls_ok:
  1509.     sub    ax,ax
  1510.     pret
  1511.     pend    close
  1512. ;
  1513.     procdef    lseek, <<fffd,word>,<pos1,word>,<pos2,word>,<how,byte>>
  1514.         ;long lseek(fd, pos, how)
  1515.             ;long pos;
  1516.     mov    ah,42H
  1517.     mov    al,how
  1518.     mov    dx,pos1
  1519.     mov    cx,pos2
  1520.     mov    bx,fffd
  1521.     int    21H
  1522.     jnc    lsk_ok
  1523.     mov    errno_,ax
  1524.     mov    ax,-1
  1525.     mov    dx,ax
  1526. lsk_ok:
  1527.     pret
  1528.     pend    lseek
  1529. ;
  1530.     procdef    unlink,<<namea,ptr>>
  1531.             ;unlink(name)
  1532.     pushds
  1533.     mov    ah,41H
  1534.     ldptr    dx,namea,ds
  1535.     int    21H
  1536.     popds
  1537.     jnc    unl_ok
  1538.     mov    errno_,ax
  1539.     mov    ax,-1
  1540.     pret
  1541. unl_ok:
  1542.     sub    ax,ax
  1543.     pret
  1544.     pend    unlink
  1545. ;
  1546.     procdef    rename, <<old,ptr>,<new,ptr>>
  1547.             ;rename(old, new)
  1548.     push    di
  1549.     pushds
  1550.     mov    ah,56H
  1551.     ldptr    dx,old,ds
  1552. ifndef LONGPTR
  1553.     mov    di,ds
  1554.     mov    es,di
  1555. endif
  1556.     ldptr    di,new,es
  1557.     int    21H
  1558.     popds
  1559.     pop    di
  1560.     jnc    rnm_ok
  1561.     mov    errno_,ax
  1562.     mov    ax,-1
  1563.     pret
  1564. rnm_ok:
  1565.     sub    ax,ax
  1566.     pret
  1567.     pend    rename
  1568.     finish
  1569.     end
  1570. ioctl.c
  1571. /* Copyright (C) 1984, 1985 by Manx Software Systems */
  1572. #include "errno.h"
  1573. #include "sgtty.h"
  1574.  
  1575. #define TIME    10        /* number of iterations of raw_rd loop */
  1576. #define MIN        1        /* minimum number of chars returned from read */
  1577.  
  1578. extern char _ioflg[];
  1579. extern int (*_ttrd)();
  1580. extern int (*_ttwr)();
  1581. extern char _Eol;
  1582. extern int _TTrem;
  1583. extern int __tty_rd(), __tty_wr(), _write();
  1584.  
  1585. static struct sgttyb Tty_ctl = { '\b', '\x18', CRMOD|ECHO };
  1586. static int raw_rd(), cr_wr();
  1587. static int ioflags, myflags, ttyfd;
  1588.  
  1589. ioctl(fd, cmd, arg)
  1590. struct sgttyb *arg;
  1591. {
  1592.     int flags;
  1593.  
  1594.     if (_ioflg[fd] == 0) {
  1595.         errno = ENOTTY;
  1596.         return -1;
  1597.     }
  1598.     switch (cmd) {
  1599.     case TIOCGETP:
  1600.         *arg = Tty_ctl;
  1601.         break;
  1602.     case TIOCSETP:
  1603.         if (ttyfd == 0) {
  1604.             if (_ioflg[2])
  1605.                 ttyfd = 2;
  1606.             else if ((ttyfd = _sys(0x3d02,"/dev/con",0)) == -1)
  1607.                 return -1;
  1608.         }
  1609.         if (ioflags == 0) {
  1610.             _ioctl(ttyfd, 0, &ioflags);
  1611.             ioflags &= 0xff;
  1612.         }
  1613.         Tty_ctl = *arg;
  1614.         if ((myflags = Tty_ctl.sg_flags) & RAW)
  1615.             myflags = RAW;
  1616.         _ttwr = _write;
  1617.         _Eol = '\r';
  1618.         if (myflags&CRMOD) {
  1619.             _Eol = '\n';
  1620.             _ttwr = __tty_wr;
  1621.         }
  1622.         if (myflags&(RAW|CBREAK)) {
  1623.             _TTrem = 0;        /* clear out input buffer */
  1624.             _ttrd = raw_rd;
  1625.             ioflags |= 0x20;    /* turn on dos's raw flag */
  1626.             _ioctl(ttyfd, 1, &ioflags);
  1627.         } else {
  1628.             ioflags &= ~0x20;    /* turn off dos's raw flag */
  1629.             _ioctl(ttyfd, 1, &ioflags);
  1630.             _ttrd = __tty_rd;
  1631.         }
  1632.         break;
  1633.     }
  1634.     return 0;
  1635. }
  1636.  
  1637. raw_rd(fd, buff, len)
  1638. register char *buff;
  1639. {
  1640.     int i;
  1641.     register int count;
  1642.  
  1643.     for (count = 0 ; count < len ; ) {
  1644.         for (i = TIME ; i-- ; )
  1645.             if (_ioctl(ttyfd, 6) != 0)
  1646.                 goto have_char;
  1647.         if (count < MIN)
  1648.             continue;
  1649.         break;
  1650. have_char:
  1651.         _read(ttyfd, buff, 1);
  1652.         if (*buff == '\r')
  1653.             *buff = _Eol;
  1654.         if (myflags&ECHO)
  1655.             (*_ttwr)(ttyfd, buff, 1);
  1656.         ++buff;
  1657.         ++count;
  1658.     }
  1659.     return count;
  1660. }
  1661. isatty.asm
  1662. ; Copyright (C) 1983 by Manx Software Systems
  1663. ; :ts=8
  1664.     include lmacros.h
  1665.     procdef    isatty, <<fd,word>>
  1666. ;            isatty(fd)
  1667.     mov    bx,fd
  1668.     mov    ax,4400H
  1669.     int    21H
  1670.     jc    not_tty        ;error, then not a tty
  1671.     test    dl,80h        ;is the channel a device?
  1672.     jz    not_tty        ;no, ...
  1673.     test    dl,3        ;is it console input or output
  1674.     jz    not_tty        ;no, ...
  1675.     mov    ax,1        ;yes, the channel is a tty
  1676.     pret
  1677. not_tty:
  1678.     sub    ax,ax
  1679.     pret
  1680.     pend    isatty
  1681.     finish
  1682.     end
  1683. localtim.c
  1684. /* Copyright (C) 1984 by Manx Software Systems */
  1685. #include <time.h>
  1686.  
  1687. struct tm *
  1688. gmtime(clock)
  1689. long *clock;
  1690. {
  1691.     struct tm *localtime();
  1692.  
  1693.     return localtime(clock);
  1694. }
  1695.  
  1696. struct tm *
  1697. localtime(clock)
  1698. long *clock;
  1699. {
  1700.     union {
  1701.         long l;
  1702.         unsigned u[2];
  1703.     } un;
  1704.     static struct tm tm;
  1705.     static int days[12] = {
  1706.         -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333
  1707.     };
  1708.  
  1709.     un.l = *clock;
  1710.     tm.tm_sec = (un.u[0]&31) * 2;
  1711.     tm.tm_min = (un.u[0]>>5) & 63;
  1712.     tm.tm_hour = (un.u[0]>>11) & 31;
  1713.     tm.tm_mday = un.u[1] & 31;
  1714.     tm.tm_mon = ((un.u[1]>>5) & 15) - 1;
  1715.     tm.tm_year = ((un.u[1]>>9) & 127) + 80;
  1716.     tm.tm_yday = days[tm.tm_mon] + tm.tm_mday +
  1717.                     (tm.tm_mon > 1 && (tm.tm_year&3) == 0);
  1718.     tm.tm_wday = (tm.tm_yday + tm.tm_year + ((tm.tm_year-1)>>2) + 1) % 7;
  1719.     return &tm;
  1720. }
  1721. mkdir.asm
  1722. ; Copyright (C) 1984 by Manx Software Systems
  1723. ; :ts=8
  1724.     include    lmacros.h
  1725. dataseg    segment    para public 'data'
  1726.     extrn    errno_:word
  1727. dataseg    ends
  1728.     assume    ds:dataseg
  1729.     procdef    mkdir,<<namea,ptr>>
  1730. ;            char *mkdir(name)
  1731. ;            char *name;
  1732. ;
  1733.     mov    ah,39h
  1734. dircommon:
  1735.     pushds
  1736.     ldptr    dx,namea,ds
  1737.     int    21h
  1738.     popds
  1739.     jnc    ok
  1740.     mov    errno_,ax
  1741.     mov    ax,-1
  1742. ok:
  1743.     pret
  1744.     pend    mkdir
  1745. ;
  1746.     procdef    rmdir,<<nnamea,ptr>>
  1747.     mov    ah,3aH
  1748.     jmp    dircommon
  1749.     pend    rmdir
  1750. ;
  1751.     procdef    chdir,<<xnamea,ptr>>
  1752.     mov    ah,3bH
  1753.     jmp    dircommon
  1754.     pend    chdir
  1755.     finish
  1756.     end
  1757. open.c
  1758. /* Copyright (C) 1982 1983 1984 by Manx Software Systems */
  1759. #include "errno.h"
  1760. #include "fcntl.h"
  1761.  
  1762. extern int errno;
  1763. extern char _ioflg[];
  1764.  
  1765. creat(name, mode)
  1766. char *name;
  1767. {
  1768.     return open(name, O_WRONLY|O_TRUNC|O_CREAT, mode);
  1769. }
  1770.  
  1771. open(name, flag, mode)
  1772. char *name;
  1773. {
  1774.     register int fd, m;
  1775.  
  1776.     m = 0x3d00 | (flag&3);
  1777.     if ((flag&O_TRUNC) != 0)
  1778.         m = 0x3c00;
  1779.  
  1780.     if ((fd = _sys(m,name,0)) == -1) {
  1781.         if ((flag&O_CREAT) != 0)
  1782.             fd = _sys(0x3c,name,0);
  1783.     } else if ((flag&O_EXCL) != 0) {
  1784.         close(fd);
  1785.         errno = EEXIST;
  1786.         return -1;
  1787.     }
  1788.     if (fd >= 0) {
  1789.         if (flag&O_APPEND)
  1790.             (void)lseek(fd, 0L, 2);
  1791.         _ioflg[fd] = isatty(fd);    /* set flag for i/o routines */
  1792.     }
  1793.     return fd;
  1794. }
  1795. stat.c
  1796. #include <stat.h>
  1797.  
  1798. stat(path, buf)
  1799. char *path; register struct stat *buf;
  1800. {
  1801.     struct {
  1802.         char rsvd[21];
  1803.         char attr;
  1804.         long time;
  1805.         long size;
  1806.         char name[13];
  1807.     } sbuf;
  1808.  
  1809.     _sys(0x1a,&sbuf);
  1810.     if (_sys(0x4e,path,~ST_VLABEL) == -1)
  1811.         return -1;
  1812.     buf->st_attr = sbuf.attr;
  1813.     buf->st_mtime = sbuf.time;
  1814.     buf->st_size = sbuf.size;
  1815.     return 0;
  1816. }
  1817.  
  1818. system.c
  1819. /* Copyright (C) 1984 by Manx Software Systems */
  1820.  
  1821. static int swt_char;
  1822.  
  1823. system(cmd)
  1824. char *cmd;
  1825. {
  1826.     register char *prog;
  1827.     char *getenv();
  1828.     char buffer[130];
  1829.  
  1830. #asm
  1831.     mov    ax,3700h        ;ask dos for current switch character
  1832.     int    21h
  1833.     sub    dh,dh
  1834.     mov    swt_char_,dx
  1835. #endasm
  1836.     if ((prog = getenv("COMSPEC")) == 0)
  1837.         prog = "/command.com";
  1838.     sprintf(buffer+1, "%cC %.123s\r", swt_char, cmd);
  1839.     buffer[0] = strlen(buffer+1) - 1;
  1840.     if (fexec(prog,0,buffer,0,0) == -1)
  1841.         return -1;
  1842.     return wait();
  1843. }
  1844. time.asm
  1845. ; Copyright (C) 1984 by Manx Software Systems
  1846. ; :ts=8
  1847.     include    lmacros.h
  1848.     procdef    time,<<tloc,ptr>> ;time_t time(time_t *tloc)
  1849. ;                if tloc!=0 then time is also stored there
  1850. ;
  1851.     mov    ah,2aH
  1852.     int    21h
  1853.     sub    cx,1980
  1854.     mov    ax,cx
  1855.     mov    cl,9
  1856.     shl    ax,cl
  1857.     and    dh,15
  1858.     and    dl,31
  1859.     mov    cl,3
  1860.     shl    dl,cl
  1861.     shr    dx,cl
  1862.     or    ax,dx
  1863.     push    ax        ;save across system call
  1864. ;
  1865.     mov    ah,2cH
  1866.     int    21H
  1867.     mov    ax,cx
  1868.     and    ah,31
  1869.     and    al,63
  1870.     and    dh,63
  1871.     shr    dh,1        ;divide seconds by two
  1872.     shl    al,1        ;move minutes over 2 bits
  1873.     shl    al,1
  1874.     mov    cl,3        ;now move minutes & hours over 3 bits
  1875.     shl    ax,cl
  1876.     or    al,dh        ;or the seconds/2 into the bottom 5 bits
  1877. ;
  1878.     pop    dx        ;restore the date info as the high word
  1879.     ldptr    bx,tloc,es    ;get tloc
  1880. ifdef LONGPTR
  1881.     mov    cx,es
  1882.     or    cx,bx
  1883. else
  1884.     test    bx,bx
  1885. endif
  1886.     jz    done
  1887. ifdef LONGPTR
  1888.     mov    es:[bx],ax
  1889.     mov    es:2[bx],dx
  1890. else
  1891.     mov    ds:[bx],ax
  1892.     mov    ds:2[bx],dx
  1893. endif
  1894. done:
  1895.     pret
  1896.     pend    time
  1897.     finish
  1898.     end
  1899. ttyio.c
  1900. /* Copyright (C) 1983, 1984 by Manx Software Systems */
  1901. #include "errno.h"
  1902.  
  1903. extern int errno;
  1904.  
  1905. char _Eol = '\n';
  1906. int _TTrem;            /* # of bytes remaining in tty buffer */
  1907.  
  1908. __tty_rd(fd,buff,len)
  1909. char *buff;
  1910. {
  1911.     static char buffer[260], *bp;
  1912.     register int l;
  1913.  
  1914.     if ((l = _TTrem) == 0) {
  1915.         if ((l = _read(fd, buffer, 260)) != 0 && buffer[l-1]=='\n') {
  1916.             --l;
  1917.             buffer[l-1] = _Eol;
  1918.         }
  1919.         bp = buffer;
  1920.         _TTrem = l;
  1921.     }
  1922.     if (l > len)
  1923.         l = len;
  1924.     if (l)
  1925.         movmem(bp, buff, l);
  1926.     bp += l;
  1927.     _TTrem -= l;
  1928.     return l;
  1929. }
  1930.  
  1931. __tty_wr(fd, buff, len)
  1932. char *buff;
  1933. {
  1934.     register int count;
  1935.     register char *cp;
  1936.     static char crbuf = '\r';
  1937.  
  1938.     cp = buff;
  1939.     for (count = len ; count-- ; ) {
  1940.         if (*cp++ == '\n') {
  1941.             _write(fd, buff, cp-buff);
  1942.             _write(fd, &crbuf, 1);
  1943.             buff = cp;
  1944.         }
  1945.     }
  1946.     if (cp != buff)
  1947.         _write(fd, buff, cp-buff);
  1948.     return len;
  1949. }
  1950. utime.c
  1951. /* Copyright (C) 1984 by Manx Software Systems */
  1952.  
  1953. struct utimbuf {
  1954.     long actime;        /* access time (not used on Msdos) */
  1955.     long modtime;        /* modification time */
  1956. };
  1957.  
  1958. utime(path, times)
  1959. char *path; register struct utimbuf *times;
  1960. {
  1961.     long time(), ftime();
  1962.     register int fd, r;
  1963.  
  1964.     if ((fd = open(path, 0)) == -1)
  1965.         return -1;
  1966.     r = ftime(1, fd, times ? times->modtime : time(0));
  1967.     close(fd);
  1968.     return r;
  1969. }
  1970. wait.asm
  1971. ; Copyright (C) 1984 by Manx Software Systems
  1972. ; :ts=8
  1973.     include    lmacros.h
  1974.     procdef    wait
  1975.     mov    ah,4dh
  1976.     int    21h
  1977.     jnc    noerr
  1978.     neg    ax
  1979. noerr:
  1980.     pret
  1981.     pend    wait
  1982.     finish
  1983.     end
  1984. syserr.c
  1985. /* Copyright (C) 1984 by Manx Software Systems */
  1986.  
  1987. char *sys_errlist[] = {
  1988.     /* MsDos error codes */
  1989.     "No error",
  1990.     "Invalid function number",
  1991.     "File not found",
  1992.     "Path not found",
  1993.     "Too many open files",
  1994.     "Access denied",
  1995.     "Bad file handle",
  1996.     "Memory control blocks destroyed",
  1997.     "Insufficient memory",
  1998.     "Invalid memory block address",
  1999.     "Invalid environment",
  2000.     "Invalid format",
  2001.     "Invalid access code",
  2002.     "Invalid data",
  2003.     "",
  2004.     "Invalid drive",
  2005.     "Attempt to remove the current directory",
  2006.     "Not same device",
  2007.     "No more files",
  2008.  
  2009.     /* additional codes for Aztec C */
  2010.     "File exists",
  2011.     "Not a console device",
  2012.     /* math library */
  2013.     "Result too large",
  2014.     "Argument out of domain"
  2015. };
  2016.  
  2017. int sys_nerr =  sizeof (sys_errlist) / sizeof (char *);
  2018. lbegin.asm
  2019. ; Copyright (C) 1983 1984 by Manx Software Systems
  2020. ; :ts=8
  2021.     include lmacros.h
  2022. codeseg    segment    para public 'code'
  2023.     public    $MEMRY
  2024.     public    _mbot_, _sbot_, _mtop_
  2025. dataseg    segment    para public 'data'
  2026. $MEMRY    dw    -1
  2027.     dw    -1
  2028.     public    errno_
  2029. errno_    dw    0
  2030.     public    _dsval_,_csval_
  2031. _dsval_    dw    0
  2032. _csval_    dw    0
  2033. _mbot_    dw    0,0
  2034. _sbot_    dw    0,0
  2035. _mtop_    dw    0,0
  2036.     public    _PSP_
  2037. _PSP_    dw    0
  2038.     extrn    _HEAPSIZ_:word,_STKSIZ_:word
  2039.     extrn    _Uorg_:byte,_Uend_:byte
  2040. dataseg    ends
  2041. exitad    dw    0
  2042. exitcs    dw    0
  2043.  
  2044.     assume    cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg
  2045. ifdef FARPROC
  2046.     extrn Croot_:far
  2047. else
  2048.     extrn Croot_:near
  2049. endif
  2050.     public    $begin
  2051.     public    _exit_
  2052. $begin    proc    far
  2053.     mov    bp,dataseg
  2054.     test    bp,bp
  2055.     jnz    notcom
  2056.     mov    ax,253        ; This CAN'T be a com file
  2057.     jmp    badexit
  2058. notcom:
  2059.     mov    exitcs,ds
  2060.     mov    es,bp
  2061.     mov    es:_PSP_,ds
  2062.     mov    bx,es:_STKSIZ_
  2063.     mov    bp,offset _Uend_ ; stack starts at Uend
  2064.     add    bp,15        ; round up to next paragraph
  2065.     rcr    bp,1
  2066.     mov    cx,3        ; and convert to paragraph form
  2067.     shr    bp,cl
  2068.     and    bp,01fffh
  2069.     mov    dx,es        ; add in datasegment base paragraph
  2070.     add    bp,dx
  2071.     and    bx,1fffh    ; stack can't be bigger than 64K
  2072.     mov    dx,bx
  2073.     mov    cx,4
  2074.     shl    bx,cl
  2075.     cli
  2076.     mov    ss,bp
  2077.     mov    sp,bx
  2078.     sti
  2079. ;
  2080.     add    dx,bp
  2081.     inc    dx
  2082.     mov    es:$MEMRY+2,dx    ; and save as bottom of heap
  2083.     mov    es:$MEMRY,0
  2084.     mov    es:_mbot_+2,dx    ; and save as bottom of heap
  2085.     mov    es:_mbot_,0
  2086. ;                now adjust heap size if necessary
  2087.     mov    bx,es:_HEAPSIZ_
  2088.     add    bx,es:$MEMRY+2    ; add in base paragraph of heap
  2089.     mov    es:_mtop_+2,bx    ; and save as top of heap
  2090.     mov    es:_mtop_,0
  2091.     mov    si,ds
  2092.     sub    bx,si        ; get size of total program in paragraphs
  2093.     mov    bp,es
  2094.     mov    es,si        ; point es at PSP
  2095.     mov    ah,4ah
  2096.     int    21h        ; SETBLOCK to raise or lower allocation
  2097.     jnc    didheap
  2098.     mov    ah,4ah
  2099.     int    21h        ; get what you can get
  2100.     jnc    didheap
  2101.     mov    ax,254
  2102.     jmp    badexit
  2103. didheap:
  2104.     mov    es,bp        ; restore es to point at dataseg
  2105. ;
  2106.     cld
  2107. ;        clear uninitialized data
  2108.     mov    di,offset _Uorg_
  2109.     mov    cx,offset _Uend_
  2110.     sub    cx,di
  2111.     inc    cx
  2112.     shr    cx,1
  2113.     jcxz    noclear
  2114.     sub    ax,ax
  2115. rep    stosw
  2116. noclear:
  2117. ;
  2118.     mov    es,[2cH]        ;get enviroment segment
  2119.     sub    di,di
  2120.     mov    cx,7fffH
  2121. arglook:
  2122.     mov    ah,es:byte ptr [di]
  2123.     cmp    ah,'='            ;look for null named env. string
  2124.     je    found_args
  2125.     test    ah,ah
  2126.     jz    no_args
  2127. repne    scasb                ;look for null byte
  2128.     jz    arglook
  2129. no_args:
  2130.     mov    si,ds
  2131.     mov    es,si
  2132.     mov    si,081h
  2133.     mov    di,080h
  2134.     mov    cl,[80h]
  2135.     sub    ch,ch
  2136.     jcxz    nomov
  2137. rep    movsb
  2138. nomov:
  2139.     sub    al,al
  2140.     stosb
  2141.     mov    ax,1
  2142.     mov    di,080h
  2143.     jmp    short mov_args
  2144. ;
  2145. found_args:
  2146.     sub    ax,ax
  2147.     stosb            ;zap and skip over '='
  2148. mov_args:
  2149.     push    ax        ; first arg # for Croot
  2150.     push    es
  2151.     push    di        ; argp argument for Croot
  2152.     mov    es,bp
  2153.     mov    ds,bp        ;set DS, now DS, SS, ES are equal
  2154.     mov    _dsval_,ds
  2155.     mov    _csval_,cs
  2156.     call    Croot_        ;Croot(argp, first)
  2157.     jmp    short exits
  2158. _exit_:
  2159.     pop    ax
  2160.     pop    ax        ;fetch return code
  2161. ifdef FARPROC
  2162. exit    label    far
  2163. else
  2164. exit:
  2165. endif
  2166. exits:
  2167. badexit:
  2168.     mov    ah,4cH
  2169.     int    21H
  2170.     jmp    dword ptr exitad
  2171. $begin    endp
  2172. codeseg    ends
  2173.     end    $begin
  2174. ssbrk.asm
  2175. ; :ts=8
  2176. ;Copyright (C) 1983 by Manx Software Systems
  2177.     include lmacros.h
  2178. dataseg    segment    word public 'data'
  2179.     extrn    $MEMRY:word
  2180.     extrn    _mbot_:word, _sbot_:word
  2181.     extrn    _mtop_:word
  2182.     extrn    errno_:word
  2183.     extrn    _STKLOW_:word
  2184.     extrn    _PSP_:word
  2185. dataseg    ends
  2186.     assume    ds:dataseg
  2187. ;
  2188. ; sbrk(size): return address of current top & bump by size bytes
  2189. ;
  2190.     procdef    sbrk,<<siz,word>>
  2191.     push    di
  2192.     mov    ax,siz
  2193.     mov    di,$MEMRY
  2194.     add    ax,di
  2195.     push    ax
  2196.     call    brk_
  2197.     pop    cx
  2198.     test    ax,ax
  2199.     jnz    brk_error
  2200.     mov    ax,di        ;return original value of the break
  2201. brk_error:
  2202.     pop    di
  2203.     test    ax,ax        ;set flags for C
  2204.     pret
  2205.     pend    sbrk
  2206. ;
  2207. ; brk(addr):    set current top address to addr
  2208. ;        returns 0 if ok, -1 if error
  2209. ;
  2210.     procdef brk,<<addr,word>>
  2211.     mov    ax,addr
  2212.     inc    ax
  2213.     and    al,-2
  2214.     cmp    ax,_mbot_
  2215.     jb    brk_ov
  2216.     mov    bx,_STKLOW_
  2217.     cmp    bx,0
  2218.     jnz    abovestk
  2219.     cmp    ax,_sbot_
  2220.     jae    brk_ov
  2221.     mov    bx,sp
  2222.     cmp    ax,bx
  2223.     jae    brk_ov
  2224. brk_ok2:
  2225.     mov    $MEMRY,ax    ;new value is good so save it away
  2226.     sub    ax,ax
  2227.     pret
  2228. ;heap is above stack
  2229. abovestk:
  2230.     cmp    ax,_mtop_
  2231.     ja    getstore
  2232.     cmp    ax,$MEMRY
  2233.     ja    brk_ok2
  2234. ;            going to do a SETBLOCK call
  2235. getstore:
  2236.     push    ax
  2237.     mov    bx,ax
  2238.     mov     cx,4
  2239.     shr    bx,cl
  2240.     and    bx,0fffh
  2241.     add    bx,65        ;bump to nearest 1k increment
  2242.     and    bx,0ffc0h    ;and round
  2243.     push    bx
  2244.     push    es
  2245.     mov    cx,es
  2246.     add    bx,cx        ;get actual paragraph address
  2247.     mov    es,_PSP_
  2248.     sub    bx,_PSP_
  2249.     mov    ah,04ah
  2250.     int    21h        ;SETBLOCK
  2251.     pop    es
  2252.     pop    bx
  2253.     pop    ax
  2254.     jc    brk_ov        ; couldn't do it, so punt
  2255.     mov    $MEMRY,ax
  2256.     test    bx,0e000h
  2257.     jnz    brk_ov
  2258.     mov    cx,4
  2259.     shl    bx,cl
  2260.     mov    _mtop_,bx
  2261.     sub    ax,ax
  2262.     pret
  2263. ; invalid request
  2264. brk_ov:
  2265.     mov    errno_,-4
  2266.     mov    ax,-1
  2267.     test    ax,ax
  2268.     pret
  2269.     pend    brk
  2270. ;
  2271. ; rsvstk(size):        set safety margin for stack
  2272. ;            this will make sure that at least size
  2273. ;            bytes of stack below the current level remain.
  2274. ;
  2275.     procdef    rsvstk,<<stksize,word>>
  2276.     mov    ax,sp
  2277.     sub    ax,stksize
  2278.     mov    _sbot_,ax
  2279.     pret
  2280.     pend    rsvstk
  2281.     finish
  2282.     end
  2283. lsbrk.asm
  2284. ; :ts=8
  2285. ;Copyright (C) 1983 by Manx Software Systems
  2286.     include lmacros.h
  2287. dataseg    segment    word public 'data'
  2288.     extrn    $MEMRY:word
  2289.     extrn    _mbot_:word, _sbot_:word
  2290.     extrn    _mtop_:word
  2291.     extrn    errno_:word
  2292.     extrn     _PSP_:word
  2293. dataseg    ends
  2294.     assume    ds:dataseg
  2295. ;
  2296. ; sbrk(size): return address of current top & bump by size bytes
  2297. ;
  2298.     procdef    sbrk,<<siz,word>>
  2299.     push    di
  2300.     push    si
  2301.     mov    ax,$MEMRY    ; convert $MEMRY to 20-bit physical address
  2302.     mov    dx,$MEMRY+2
  2303.     mov    si,ax
  2304.     mov    di,dx
  2305.     mov    cx,4
  2306.     rol    dx,cl
  2307.     mov    bx,dx
  2308.     and    bx,0fff0h
  2309.     and    dx,0fh
  2310.     add    ax,bx
  2311.     adc    dx,0
  2312.     mov    bx,siz        ; load and check sign of size
  2313.     cmp    bx,0
  2314.     jge    notneg
  2315.     sub    ax,bx
  2316.     sbb    dx,0
  2317.     js    brk_error    ; mustn't go negative
  2318.     jmp    canon
  2319. notneg:
  2320.     add    ax,bx
  2321.     adc    dx,0
  2322.     test    dx,0fff0h
  2323.     jnz    brk_error    ; mustn't overflow 20-bits
  2324. canon:
  2325.     ror    dx,cl
  2326.     mov    bx,ax
  2327.     and    ax,0fh
  2328.     shr    bx,cl
  2329.     and    bx,0fffh
  2330.     or    dx,bx
  2331.     push    dx
  2332.     push    ax
  2333.     call    brk_
  2334.     add    sp,4
  2335.     test    ax,ax
  2336.     jnz    brk_error
  2337.     mov    ax,si        ;return original value of the break
  2338.     mov    dx,di
  2339.     pop    si
  2340.     pop    di
  2341.     pret
  2342. brk_error:
  2343.     pop    si
  2344.     pop    di
  2345.     mov    dx,ax
  2346.     pret
  2347.     pend    sbrk
  2348. ;
  2349. ; brk(addr):    set current top address to addr
  2350. ;        returns 0 if ok, -1 if error
  2351. ;
  2352.     procdef brk,<<addr,word>,<aseg,word>>
  2353.     push    di
  2354.     push    si
  2355.     mov    ax,addr
  2356.     inc    ax
  2357.     and    al,-2
  2358.     mov    dx,aseg
  2359.     mov    bx,ax            ; convert to canonical pointer
  2360.     mov    cx,4
  2361.     shr    bx,cl
  2362.     and    bx,0fffh
  2363.     and    ax,0fh
  2364.     add    dx,bx
  2365.     cmp    dx,_mtop_+2
  2366.     ja    getstore
  2367.     jne    brk_ok2
  2368.     cmp    ax,_mtop_
  2369.     jnb    getstore
  2370. brk_ok2:
  2371.     cmp    dx,$MEMRY+2
  2372.     ja    brk_ok3
  2373.     jne    chkunder
  2374.     cmp    ax,$MEMRY
  2375.     jnb    brk_ok3
  2376. chkunder:
  2377.     cmp    dx,_mbot_+2
  2378.     jb    brk_ov
  2379.     jne    getstore
  2380.     cmp    ax,_mbot_
  2381.     jb    brk_ov
  2382. getstore:
  2383. ;            going to do a SETBLOCK call
  2384.     push    ax
  2385.     mov    bx,dx
  2386.     test    ax,ax
  2387.     jz    nobump
  2388.     inc    bx
  2389. nobump:
  2390.     add    bx,63        ;bump to nearest 1k increment
  2391.     and    bx,0ffc0h    ;and round
  2392.     push    es
  2393.     push    bx
  2394.     mov    cx,_PSP_
  2395.     mov    es,cx        ;set segment for SETBLOCK call
  2396.     sub    bx,cx        ;and adjust length appropriately
  2397.     mov    ah,04ah
  2398.     int    21h        ;SETBLOCK
  2399.     pop    bx
  2400.     pop    es
  2401.     pop    ax
  2402.     jc    brk_ov        ; couldn't do it, so punt
  2403.     mov    _mtop_+2,bx
  2404.     mov    _mtop_,0
  2405. brk_ok3:
  2406.     mov    $MEMRY,ax
  2407.     mov    $MEMRY+2,dx
  2408.     sub    ax,ax
  2409.     pop    si
  2410.     pop    di
  2411.     pret
  2412. ; invalid request
  2413. brk_ov:
  2414.     mov    errno_,-4
  2415.     mov    ax,-1
  2416.     test    ax,ax
  2417.     pop    si
  2418.     pop    di
  2419.     pret
  2420.     pend    brk
  2421.     finish
  2422.     end
  2423. clock.asm
  2424.     include lmacros.h
  2425. dataseg segment word public 'data'
  2426. last    dw    0,0
  2427. dataseg ends
  2428.     assume    ds:dataseg
  2429.  
  2430.     procdef clock
  2431.     add    sp,-2
  2432.     mov    ah,2ch
  2433.     int    21h                    ; get time
  2434.     mov    word ptr -2[bp],dx    ;save seconds and hundredths
  2435.     mov    al,ch                ; fetch hours
  2436.     cbw
  2437.     mov    bx,60
  2438.     mul    bx                    ; convert to minutes
  2439.     xchg ax,bx
  2440.     mov    al,cl                ; fetch minutes
  2441.     cbw
  2442.     xchg ax,bx
  2443.     add    ax,bx                ; add to converted hours
  2444.     mov    bx,60
  2445.     mul bx        ; luckily the first two multiplies can be done as shorts
  2446.     xchg ax,bx                ; convert to seconds
  2447.     mov    al,byte ptr -2[bp]    ; fetch seconds
  2448.     cbw
  2449.     xchg ax,bx
  2450.     add    ax,bx
  2451.     adc dx,0                ; add to converted seconds
  2452.     mov    bx,100
  2453.     xchg    ax,dx
  2454.     push    dx
  2455.     mul    bx
  2456.     mov cx,ax
  2457.     pop ax
  2458.     mul bx
  2459.     add dx,cx                ; convert to hunderdths
  2460.     xchg ax,bx
  2461.     mov al,byte ptr -1[bp]    ; fetch hundredths
  2462.     cbw
  2463.     xchg ax,bx
  2464.     add    ax,bx
  2465.     adc    dx,0                ; axdx now contains value in hunredths
  2466.     cmp    dx,word ptr last+2
  2467.     ja    valok
  2468.     jne    clktrn
  2469.     cmp    ax,word ptr last
  2470.     ja    valok
  2471. clktrn:                        ; clock turned over since last call
  2472.     add    ax,0d600h
  2473.     adc dx,083h                ; add in 24 hours
  2474. valok:
  2475.     mov word ptr last+2,dx
  2476.     mov word ptr last,ax
  2477.     mov    bx,dx
  2478.     pret
  2479.     pend clock
  2480.     finish
  2481.     end
  2482.  
  2483. sigfix.asm
  2484. ; Copyright (C) 1985 by Manx Software Systems, Inc.
  2485. ; :ts=8
  2486.     include lmacros.h
  2487.  
  2488. dataseg    segment    word public 'data'
  2489.     public    _brkvec_
  2490. _brkvec_ dw    0,0
  2491. dataseg    ends
  2492.  
  2493.     assume    ds:dataseg
  2494. ;
  2495. ;    This routine is used by exec (used by execl, execv, etc.)
  2496. ;    to reset any signal handlers which have been setup.
  2497. ;
  2498.     procdef    _sigfix
  2499.     cmp    _brkvec_+2,0
  2500.     je    brk_ok
  2501.     push    ds
  2502.     lds    dx,dword ptr _brkvec_
  2503.     mov    ax,2523H    ;restore old cntl-break handler
  2504.     int    21H
  2505.     pop    ds
  2506. brk_ok:
  2507.     pret
  2508.     pend    _sigfix
  2509.  
  2510.     finish
  2511.     end
  2512. sighand.asm
  2513. ; Copyright (C) 1985 by Manx Software Systems, Inc.
  2514. ; :ts=8
  2515.     include lmacros.h
  2516.  
  2517. dataseg    segment    word public 'data'
  2518.     extrn    _PSP_:word
  2519.     extrn    _brkvec_:word
  2520. ifdef FARPROC
  2521.     bss    temp:word,4        ;used for far call to handler
  2522.     global    _sigfuns_:word,6*4
  2523. else
  2524.     global    _sigfuns_:word,6*2
  2525. endif
  2526. dataseg    ends
  2527.  
  2528. ourds    dw    0
  2529.  
  2530.     assume    ds:dataseg
  2531. ;
  2532.     procdef    _sig_setup
  2533.     mov    ourds,ds
  2534.     cmp    _brkvec_+2,0
  2535.     jne    have_brk
  2536.     push    ds
  2537.     mov    ax,3523H    ;get cntl-break (cntl-c) handler
  2538.     int    21H
  2539.     mov    _brkvec_,bx
  2540.     mov    _brkvec_+2,es
  2541.     mov    dx,offset brk_handler
  2542.     mov    ax,cs
  2543.     mov    ds,ax
  2544.     mov    ax,2523H    ;set new cntl-break handler
  2545.     int    21H
  2546.     pop    ds
  2547. have_brk:
  2548.     pret
  2549.     pend    _sig_setup
  2550.  
  2551. brk_handler proc far
  2552.     push    ds
  2553.     mov    ds,ourds
  2554. ifdef FARPROC
  2555.     cmp    _sigfuns_+2,0
  2556.     jne    chk_ignore
  2557.     cmp    _sigfuns_,0
  2558.     jne    chk_ignore
  2559. else
  2560.     cmp    _sigfuns_,0
  2561.     jne    chk_ignore
  2562. endif
  2563.  
  2564.     push    _brkvec_+2
  2565.     push    _brkvec_
  2566.     pop    ds
  2567.     ret
  2568.  
  2569. chk_ignore:
  2570. ifdef FARPROC
  2571.     cmp    _sigfuns_,1
  2572.     jne    not_ignore
  2573.     cmp    _sigfuns_+2,0
  2574.     je    ignore
  2575. not_ignore:
  2576. else
  2577.     cmp    _sigfuns_,1
  2578.     je    ignore
  2579. endif
  2580.     cld
  2581.     push    es
  2582.     push    ax
  2583.     push    bx
  2584.     mov    ax,sp
  2585.     mov    bx,ss
  2586.     mov    es,_PSP_
  2587.     mov    ss,es:[30h]        ;get our last ss:sp from place
  2588.     mov    sp,es:[2eh]        ;where DOS saves it
  2589.     push    ax
  2590.     push    bx
  2591.     push    cx
  2592.     push    dx
  2593.     push    si
  2594.     push    di
  2595.     mov    ax,1        ;signal #1
  2596.     push    ax
  2597. ifdef FARPROC
  2598.     mov    ax,_sigfuns_+2
  2599.     mov    temp+2,ax
  2600.     mov    ax,_sigfuns_
  2601.     mov    temp,ax
  2602.     mov    _sigfuns_,0    ;set SIG_DFL
  2603.     mov    _sigfuns_+2,0
  2604.     sti
  2605.     call    dword ptr temp
  2606. else
  2607.     mov    ax,_sigfuns_
  2608.     mov    _sigfuns_,0    ;set SIG_DFL
  2609.     sti
  2610.     call    ax
  2611. endif
  2612.     pop    ax        ;throw away argument
  2613.     pop    di
  2614.     pop    si
  2615.     pop    dx
  2616.     pop    cx
  2617.     pop    bx
  2618.     pop    ax
  2619.     mov    ss,bx        ;restore to system stack
  2620.     mov    sp,ax
  2621.     pop    bx
  2622.     pop    ax
  2623.     pop    es
  2624.  
  2625. ignore:
  2626.     pop    ds
  2627.     iret
  2628. brk_handler endp
  2629.     finish
  2630.     end
  2631. signal.c
  2632. #include <signal.h>
  2633. #include <errno.h>
  2634.  
  2635. extern void (*_sigfuns[_NUMSIG])();
  2636. static char setup;
  2637.  
  2638. void (*signal(sig, func))()
  2639. register int sig; void (*func)();
  2640. {
  2641.     register void (*retval)();
  2642.  
  2643.     if (!setup) {
  2644.         _sig_setup();
  2645.         setup = 1;
  2646.     }
  2647.     if ((sig -= _FSTSIG) < 0 || sig >= _NUMSIG) {
  2648.         errno = EINVAL;
  2649.         return SIG_ERR;
  2650.     }
  2651.     retval = _sigfuns[sig];
  2652.     _sigfuns[sig] = func;
  2653.     return retval;
  2654. }
  2655. sys.asm
  2656. ;Copyright (C) 1985 by Manx Software Systems
  2657. ; :ts=8
  2658.     include lmacros.h
  2659.  
  2660. dataseg    segment    para public 'data'
  2661.     extrn    errno_:word
  2662. dataseg ends
  2663.     assume    ds:dataseg
  2664.  
  2665.     procdef    _sys,<<func,word>,<arg,ptr>,<arg2,word>>
  2666.     mov    ax,func
  2667.     test    ah,ah
  2668.     jnz    valok
  2669.     xchg    ah,al
  2670. valok:
  2671.     cmp    ah,10
  2672.     jb    simple
  2673. ;
  2674.     push    di
  2675.     pushds
  2676.     push    es
  2677.     cmp    ah,47H        ;check for getcwd call
  2678.     jne    not_cwd
  2679.     mov    dx,arg2        ;load drive # into DX
  2680.     ldptr    si,arg,ds
  2681.     jmp    short issue
  2682. not_cwd:
  2683.     mov    cx,arg2
  2684.     ldptr    dx,arg,ds
  2685. issue:
  2686.     int    21H
  2687.     mov    dx,es
  2688.     pop    es
  2689.     popds
  2690.     jnc    noerror
  2691.     mov    errno_,ax
  2692.     mov    ax,-1
  2693.     mov    dx,ax
  2694. noerror:
  2695.     pop    di
  2696.     pret
  2697. ;
  2698. simple:
  2699.     mov    dx,word ptr arg
  2700.     int    21H
  2701.     and    ax,0ffH
  2702.     pret
  2703.     pend    _sys
  2704.     finish
  2705.     end
  2706. m
  2707. bne macro label
  2708.  local foo
  2709.  je foo
  2710.  jmp label
  2711. foo:
  2712.  endm
  2713. blt macro label
  2714.  local foo
  2715.  jnl foo
  2716.  jmp label
  2717.