Annotation of os2sdk/startup/dos/stdargv.asm, revision 1.1.1.1

1.1       root        1:        page    ,132
                      2:        TITLE   stdargv - standard & wildcard _setargv routine
                      3: ;***
                      4: ;stdargv.asm - standard & wildcard _setargv routine
                      5: ;
                      6: ;      Copyright (c) 1985-1987, Microsoft Corporation.  All rights reserved.
                      7: ;
                      8: ;Purpose:
                      9: ;      processes program command line, with or without wildcard expansion
                     10: ;
                     11: ;*******************************************************************************
                     12: 
                     13: 
                     14: ifdef  WILDCARD
                     15:        name    _setargv        ; wildcard _setargv routine
                     16: else
                     17:        name    stdargv         ; standard _setargv routine
                     18: endif
                     19: 
                     20: ifdef  WILDCARD
                     21: ?DF    =       1               ; tell cmacros.inc we want to define our own segments
                     22: endif
                     23: 
                     24: include        version.inc
                     25:        .xlist
                     26: include        cmacros.inc
                     27: include        msdos.inc
                     28:        .list
                     29: 
                     30: ifdef  WILDCARD                ; **********************************************
                     31: 
                     32: createSeg _TEXT, code, word,   public, CODE,   <>
                     33: createSeg _DATA, data, word,   public, DATA,   DGROUP
                     34: 
                     35: createSeg HDR, nhdr,   byte,   public, MSG,    DGROUP
                     36: createSeg MSG, nmsg,   byte,   public, MSG,    DGROUP
                     37: createSeg PAD, npad,   byte,   common, MSG,    DGROUP
                     38: createSeg EPAD,        nepad,  byte,   common, MSG,    DGROUP
                     39: 
                     40: defGrp DGROUP                  ; define DGROUP
                     41: 
                     42: dataOFFSET equ offset DGROUP:
                     43: 
                     44: ; Message used by ___setargv (wildcard version of __setargv)
                     45: 
                     46: sBegin nmsg
                     47: assumes        ds,data
                     48:        dw      8
                     49:        db      'R6008',13,10,'- not enough space for arguments',13,10,0
                     50: sEnd
                     51: 
                     52: sBegin npad
                     53: assumes        ds,data
                     54:        dw      -1
                     55: ; no padding for now;
                     56: ; MAX padding would be
                     57: ;      db      25 dup(0)
                     58: sEnd
                     59: 
                     60: 
                     61: externP        _cwild                  ; Wildcard Expander
                     62: externNP _amsg_exit            ; error handler (unable to allocate)
                     63: 
                     64: endif                          ; WILDCARD      ; **********************************************
                     65: 
                     66: 
                     67: sBegin data
                     68: assumes        ds,data
                     69: 
                     70: ifdef  _QC                     ; [1]
                     71: extrn  __QCrtcsip:DWORD        ; [1]
                     72: endif  ;_QC                    ; [1]
                     73: 
                     74: C_CR   equ     0DH             ; ASCII carriage return
                     75: 
                     76: C_BLANK        equ     ' '             ; ASCII space character
                     77: C_TAB  equ     09h             ; ASCII horizontal tab character
                     78: 
                     79: C_QUOTE        equ     '"'             ; ASCII (double) Quote Charater
                     80: C_BACKSLASH equ        '\'             ; ASCII backward slash character
                     81: 
                     82: externDP __argv                        ; argument string array address
                     83: externW        __argc                  ; count of argument strings
                     84: externW        _psp                    ; address of Program Segment Prefix
                     85: externB        _osmajor                ; address of DOS version (major part)
                     86: externD        _pgmptr                 ; far ptr to name of program
                     87: 
                     88: staticCP retadr,0              ; return address
                     89: 
                     90: 
                     91: ifdef  WILDCARD                ; **********************************************
                     92: 
                     93: dta_flag db    0               ; Has DMA been set yet?
                     94: 
                     95: file_reserv db 21 dup (0)
                     96: file_attrib db 0
                     97: file_time dw   0
                     98: file_date dw   0
                     99: file_sizel dw  0
                    100: file_sizeh dw  0
                    101: file_name db   13 dup (0)
                    102: 
                    103: endif                          ; WILDCARD      ; **********************************************
                    104: 
                    105: sEnd
                    106: 
                    107: ; ****************************************
                    108: 
                    109: jmps   MACRO   target
                    110:        jmp     short target
                    111:        ENDM
                    112: 
                    113: lje    MACRO   target
                    114:        LOCAL   temp
                    115:        jne     temp
                    116:        jmp     target
                    117: temp:
                    118:        ENDM
                    119: 
                    120: ifdef  IBMC20
                    121: 
                    122: DELIM  MACRO   target
                    123:        cmp     al,C_CR         ;; Test for end-of-line character
                    124:        je      target
                    125:        ENDM
                    126: 
                    127: LDELIM MACRO   target
                    128:        cmp     al,C_CR         ;; Test for end-of-line character
                    129:        lje     target
                    130:        ENDM
                    131: 
                    132: else ; IBMC20
                    133: 
                    134: DELIM  MACRO   target
                    135:        cmp     al,C_CR         ;; Test for end-of-line character
                    136:        je      target
                    137:        or      al,al           ;; Either Carriage Return or Null
                    138:        je      target
                    139:        ENDM
                    140: 
                    141: LDELIM MACRO   target
                    142:        cmp     al,C_CR         ;; Test for end-of-line character
                    143:        lje     target
                    144:        or      al,al           ;; Either Carriage Return or Null
                    145:        lje     target
                    146:        ENDM
                    147: 
                    148: endif ; IBMC20
                    149: 
                    150: ; ****************************************
                    151: 
                    152: sBegin code
                    153: 
                    154: assumes        ds,data
                    155: assumes        ss,data
                    156: assumes        cs,code
                    157: 
                    158: page
                    159: ;***
                    160: ;_setargv, __setargv - set up "argc" and "argv" for C programs
                    161: ;
                    162: ;Purpose:
                    163: ;      Gets the command line from the PSP and moves the information
                    164: ;      to its place on the stack.
                    165: ;
                    166: ;      SIDE EFFECTS:
                    167: ;              Allocates space on the stack for the argument strings
                    168: ;              and a list of pointers to them.
                    169: ;      ASSUMPTIONS:
                    170: ;              Under DOS 2, there is no argv[0] string, so "C" is used.
                    171: ;              Under DOS 3 and later, the argv[0] string is found in the
                    172: ;              environment segment, after the double null that terminates
                    173: ;              that segment and after a word of value 1.  The rest of the
                    174: ;              command line is found in the Program Segment Prefix at
                    175: ;              offset 81H, and is terminated by a 0DH.  This command "tail"
                    176: ;              cannot be greater than 126 bytes in length.
                    177: ;
                    178: ;              Quote marks and backslashes are treated specially.  A quoted
                    179: ;              string is passed as a single argument, not including the
                    180: ;              opening and closing quote characters.  A quote may be imbedded
                    181: ;              in a string by placing an odd number of backslashes (`\')
                    182: ;              before it.  Each pair of backslashes which precedes a quote
                    183: ;              results in a single backslash in the resultant string.
                    184: ;              An even number of backslashes followed by a quote results in
                    185: ;              half that many backslashes, and the quote begins or ends the
                    186: ;              quoted part of the string as is appropriate.  Backslashes not
                    187: ;              followed by a quote are treated normally.
                    188: ;
                    189: ;              [""] ==> []
                    190: ;              [\"] ==> ["]
                    191: ;              [" \" "] == [ " ]
                    192: ;              [" \\"] == [ \]
                    193: ;              [" \\ "] == [ \\ ]
                    194: ;              [" \\\" "] == [ \" ]
                    195: ;              etc.
                    196: ;              ["one two three"] ==> [one two three]
                    197: ;              [one" two "three] ==> [one two three]
                    198: ;              [o"ne two t"hree] ==> [one two three]
                    199: ;              ["one \"two\" three"] ==> [one "two" three]
                    200: ;              ["x\\\"x"] ==> [x\"x]
                    201: ;
                    202: ;Entry:
                    203: ;
                    204: ;Exit:
                    205: ;      "argv" points to a null-terminated list of pointers to ASCIZ
                    206: ;      strings, each of which is an argument from the command line.
                    207: ;      "argc" is the number of arguments.  The strings are copied from
                    208: ;      the Program Segment Prefix into space allocated on the stack.
                    209: ;      The list of pointers is also located on the stack.
                    210: ;
                    211: ;Uses:
                    212: ;      All registers except DS, SS, and BP are modified
                    213: ;      Note especially that SI and DI are NOT preserved!
                    214: ;
                    215: ;Exceptions:
                    216: ;
                    217: ;*******************************************************************************
                    218: 
                    219: ifdef  WILDCARD                ; **********************************************
                    220: 
                    221: labelP <PUBLIC,__setargv>
                    222: 
                    223: else                           ; **********************************************
                    224: 
                    225: labelP <PUBLIC,_setargv>
                    226: 
                    227: endif                          ; WILDCARD      ; **********************************************
                    228: 
                    229:        pop     word ptr [retadr] ; get return address (offset)
                    230: if     sizeC
                    231:        pop     word ptr [retadr+2] ; get return address (segment)
                    232: endif
                    233:        mov     dx,2
                    234:        cmp     byte ptr [_osmajor],dl ; 2 bytes if DOS version = 2.X
                    235:        je      dos_two
                    236: 
                    237:        mov     es,_psp
                    238:        mov     es,es:[DOS_envp] ; get environment segment
                    239:        mov     word ptr [_pgmptr+2],es ; set global variable "_pgmptr"
                    240:        xor     ax,ax
                    241:        cwd                     ; DX=0
                    242:        mov     cx,8000H
                    243:        xor     di,di           ; scan from beginning of environment
                    244: find_env_end:
                    245:        repne   scasb
                    246:        scasb
                    247:        jne     find_env_end
                    248: ;
                    249:        inc     di              ; skip count word (always 0x0001)
                    250:        inc     di
                    251:        mov     word ptr [_pgmptr],di ; set global variable "_pgmptr"
                    252:        mov     cx,-1
                    253:        repne   scasb
                    254:        not     cx
                    255:        mov     dx,cx           ; DX=number of bytes in argv[0]
                    256: dos_two:
                    257:        mov     di,1            ; always start with one argument
                    258:        mov     si,81H
                    259:        mov     ds,_psp
                    260:        assumes ds,nothing
                    261: ;*
                    262: ;*     Count the command tail arguments
                    263: ;*
                    264: ;
                    265: ;      DI will count the number of arguments
                    266: ;      DX will count the number of bytes needed for the arguments
                    267: ;              (not including the null terminators)
                    268: ;
                    269: arg100:
                    270: arg110:
                    271:        lodsb
                    272:        cmp     al,C_BLANK
                    273:        je      arg110
                    274:        cmp     al,C_TAB
                    275:        je      arg110
                    276: 
                    277:        DELIM   arg400
                    278: 
                    279:        inc     di              ; Another argument
                    280: ;
                    281: ; Parse an argument
                    282: ;
                    283: arg200:
                    284:        dec     si              ; back up to reload character
                    285: arg210:
                    286:        lodsb
                    287: 
                    288:        cmp     al,C_BLANK
                    289:        je      arg100
                    290:        cmp     al,C_TAB
                    291:        je      arg100          ; white space terminates argument
                    292: 
                    293:        DELIM   arg400
                    294: 
                    295:        cmp     al,C_QUOTE
                    296:        je      arg310
                    297: 
                    298:        cmp     al,C_BACKSLASH
                    299:        je      arg220
                    300: 
                    301:        inc     dx
                    302:        jmps    arg210
                    303: ;
                    304: ; Count backslashes
                    305: ;
                    306: arg220:
                    307:        xor     cx,cx
                    308: arg221:
                    309:        inc     cx              ; CX counts the backslashes
                    310:        lodsb
                    311:        cmp     al,C_BACKSLASH
                    312:        je      arg221
                    313: ;
                    314:        cmp     al,C_QUOTE
                    315:        je      arg230
                    316: 
                    317:        add     dx,cx           ; not followed by `"' -- treat `\'s normally
                    318:        jmp     arg200
                    319: ;
                    320: arg230:
                    321:        mov     ax,cx
                    322:        shr     cx,1
                    323:        adc     dx,cx           ; add 1 for every pair of backslashes
                    324:        test    al,1            ; plus 1 for the " if odd number of \
                    325:        jnz     arg210          ; " was escaped with a \
                    326:        jmps    arg310          ; " opens a quoted substring
                    327: ;
                    328: ; Enter a quoted string
                    329: ;
                    330: arg300:
                    331:        dec     si              ; back up to reload character
                    332: arg310:
                    333:        lodsb
                    334: 
                    335:        DELIM   arg400
                    336: 
                    337:        cmp     al,C_QUOTE
                    338:        je      arg210          ; end of quoted portion of string
                    339: 
                    340:        cmp     al,C_BACKSLASH
                    341:        je      arg320
                    342: 
                    343:        inc     dx
                    344:        jmp     arg310
                    345: ;
                    346: ; Count backslashes
                    347: ;
                    348: arg320:
                    349:        xor     cx,cx
                    350: arg321:
                    351:        inc     cx              ; CX counts the backslashes
                    352:        lodsb
                    353:        cmp     al,C_BACKSLASH
                    354:        je      arg321
                    355: ;
                    356:        cmp     al,C_QUOTE
                    357:        je      arg330
                    358: 
                    359:        add     dx,cx           ; not followed by `"' -- treat `\'s normally
                    360:        jmp     arg300
                    361: ;
                    362: arg330:
                    363:        mov     ax,cx
                    364:        shr     cx,1
                    365:        adc     dx,cx           ; add 1 for every pair of backslashes
                    366:        test    al,1            ; plus 1 for the " if odd number of \
                    367:        jnz     arg310          ; " was escaped with a \
                    368:        jmps    arg210          ; " closes a quoted substring
                    369: ;
                    370: ; Command line is fully parsed - compute number of bytes needed
                    371: ;
                    372: arg400:
                    373: ;
                    374: ;      Number of bytes needed =
                    375: ;              Number of bytes used to make strings +
                    376: ;              Number of bytes used to terminate strings +
                    377: ;              sizeof(DATAPTR) * ( number of arguments + 1 )
                    378: ;
                    379:        push    ss
                    380:        pop     ds              ; Restore DS = DGROUP
                    381:        assumes ds,data
                    382: 
                    383:        mov     __argc,di       ; Store number of arguments
                    384: 
                    385:        add     dx,di           ; add in terminator bytes
                    386: ifdef  WILDCARD
                    387:        add     dx,di           ; add in Wildcard flag bytes
                    388: endif
                    389:        inc     di              ; add one for NULL pointer
                    390:        shl     di,1
                    391: if     sizeD
                    392:        shl     di,1
                    393: endif
                    394:        add     dx,di           ; add space for pointers to space for chars
                    395: 
                    396:        and     dl,not 1        ; Round up to an even number of bytes
                    397: ;
                    398: ;      Allocate space on the stack
                    399: ;
                    400: ;      DX is the total number of bytes needed for strings and pointers
                    401: ;      DI is the number of bytes needed for the pointers
                    402: ;
                    403:        sub     sp,dx
                    404:        mov     ax,sp
                    405: 
                    406:        mov     word ptr (__argv),ax
                    407: if     sizeD
                    408:        mov     word ptr (__argv+2),ds
                    409: endif
                    410: ;
                    411: ;      Copy argument strings and addresses onto heap/stack
                    412: ;              Address table is on the top, strings below that
                    413: ;
                    414:        mov     bx,ax
                    415:        add     di,bx
                    416: 
                    417:        push    ss              ; ES=SS
                    418:        pop     es              ; ES:DI is where the string copies will go
                    419:        assumes es,data
                    420: ;
                    421: ;      DS:SI   points to the argv[0]
                    422: ;
                    423: ;      ES:BX   points to where argv[0],argv[1],argv[2],... go
                    424: ;      ES:DI   points to where *argv[0],*argv[1],*argv[2],... go
                    425: ; For wildcard version only:
                    426: ;      ES:DX   points to the wildcard flag character (prepended to argument)
                    427: ;              during the creation of each argument
                    428: ;
                    429:        mov     ss:[bx],di      ; argv[i] - offset part
                    430: if     sizeD
                    431:        mov     ss:[bx+2],ss    ; argv[i] - segment part
                    432:        add     bx,4
                    433: else
                    434:        inc     bx
                    435:        inc     bx
                    436: endif
                    437: 
                    438:        lds     si,[_pgmptr]    ; copy argv[0], either fake or from env seg
                    439:        assumes ds,nothing
                    440: 
                    441: ifdef  WILDCARD
                    442:        movsb
                    443:        dec     si              ; copy first character as quote flag
                    444: endif
                    445: 
                    446: copy_argv0:
                    447:        lodsb
                    448:        stosb
                    449:        or      al,al
                    450:        jnz     copy_argv0
                    451: ;
                    452: ;      DS:SI   points to the raw command tail string
                    453: ;
                    454:        mov     si,81H          ; address of strings
                    455:        mov     ds,ss:[_psp]    ; DS:SI is where the source strings are
                    456:        assumes ds,nothing
                    457: 
                    458:        jmps    arg510
                    459: ;
                    460: ;      Skip blanks
                    461: ;
                    462: arg500:
                    463:        xor     ax,ax
                    464:        stosb
                    465: arg510:
                    466:        lodsb
                    467:        cmp     al,C_BLANK
                    468:        je      arg510
                    469:        cmp     al,C_TAB
                    470:        je      arg510
                    471: 
                    472:        LDELIM  arg810
                    473: 
                    474:        mov     ss:[bx],di
                    475: if     sizeD
                    476:        mov     ss:[bx+2],ss
                    477:        add     bx,4
                    478: else
                    479:        inc     bx
                    480:        inc     bx
                    481: endif
                    482: 
                    483: ifdef  WILDCARD
                    484:        mov     dx,di
                    485:        stosb                   ; initialize wildcard flag
                    486: endif
                    487: ;
                    488: ;
                    489: ; Parse an argument
                    490: ;
                    491: arg600:
                    492:        dec     si              ; back up to reload character
                    493: arg610:
                    494:        lodsb
                    495: 
                    496:        cmp     al,C_BLANK
                    497:        je      arg500
                    498:        cmp     al,C_TAB
                    499:        je      arg500          ; white space terminates argument
                    500: 
                    501:        DELIM   arg800
                    502: 
                    503:        cmp     al,C_QUOTE
                    504:        je      arg710x
                    505: 
                    506:        cmp     al,C_BACKSLASH
                    507:        je      arg620
                    508: 
                    509:        stosb
                    510:        jmps    arg610
                    511: ;
                    512: ; Count backslashes
                    513: ;
                    514: arg620:
                    515:        xor     cx,cx
                    516: arg621:
                    517:        inc     cx              ; CX counts the backslashes
                    518:        lodsb
                    519:        cmp     al,C_BACKSLASH
                    520:        je      arg621
                    521: ;
                    522:        cmp     al,C_QUOTE
                    523:        je      arg630
                    524: 
                    525:        mov     al,C_BACKSLASH
                    526:        rep     stosb           ; not followed by `"' -- treat `\'s normally
                    527:        jmp     arg600
                    528: ;
                    529: arg630:
                    530:        mov     al,C_BACKSLASH
                    531:        shr     cx,1
                    532:        rep     stosb
                    533:        jnc     arg710x         ; " opens a quoted substring
                    534:        mov     al,C_QUOTE
                    535:        stosb
                    536:        jmp     arg610          ; " was escaped with a \
                    537: ;
                    538: ; Enter a quoted string
                    539: ;
                    540: ifdef  WILDCARD
                    541: arg710x:
                    542:        inc     si              ; undoes the "DEC SI" between arg700 and arg710
                    543: endif
                    544: 
                    545: arg700x:
                    546: 
                    547: ifdef  WILDCARD
                    548:        xchg    dx,di           ; set the wildcard flag character to `"'
                    549:        mov     al,C_QUOTE
                    550:        stosb
                    551:        dec     di
                    552:        xchg    dx,di
                    553: endif
                    554: 
                    555: arg700:
                    556:        dec     si              ; back up to reload character
                    557: 
                    558: ifndef WILDCARD
                    559: arg710x:
                    560: endif
                    561: 
                    562: arg710:
                    563:        lodsb
                    564: 
                    565:        DELIM   arg800
                    566: 
                    567:        cmp     al,C_QUOTE
                    568:        je      arg610          ; end of quoted portion of string
                    569: 
                    570:        cmp     al,C_BACKSLASH
                    571:        je      arg720
                    572: 
                    573:        stosb
                    574:        jmp     arg710
                    575: ;
                    576: ; Count backslashes
                    577: ;
                    578: arg720:
                    579:        xor     cx,cx
                    580: arg721:
                    581:        inc     cx              ; CX counts the backslashes
                    582:        lodsb
                    583:        cmp     al,C_BACKSLASH
                    584:        je      arg721
                    585: ;
                    586:        cmp     al,C_QUOTE
                    587:        je      arg730
                    588: 
                    589:        mov     al,C_BACKSLASH
                    590:        rep     stosb           ; not followed by `"' -- treat `\'s normally
                    591:        jmp     arg700x
                    592: ;
                    593: arg730:
                    594:        mov     al,C_BACKSLASH
                    595:        shr     cx,1
                    596:        rep     stosb           ; store 1 for every pair of backslashes
                    597:        jnc     arg610          ; " closes a quoted substring
                    598:        mov     al,C_QUOTE      ; " was escaped with a \
                    599:        stosb
                    600:        jmps    arg710x
                    601: ;
                    602: ; Terminate last argument string, terminate list of argument pointers
                    603: ;
                    604: arg800:
                    605:        xor     ax,ax
                    606:        stosb                   ; null-terminate final argument
                    607: arg810:
                    608:        push    ss
                    609:        pop     ds
                    610:        assumes ds,data
                    611: 
                    612:        mov     word ptr [bx],0 ; add null pointer to __argv[]
                    613: if     sizeD
                    614:        mov     word ptr [bx+2],0
                    615: endif
                    616: 
                    617: ifndef WILDCARD
                    618:        jmp     [retadr]        ; THE END
                    619: else
                    620:        call    _cwild
                    621:        test    ax,ax
                    622:        jz      no_arg_err
                    623: 
                    624: ifdef  _QC                                     ; [1]
                    625:        mov     ds,cs:[$F_PSP]                  ;[2] get PSP
                    626:        mov     ax,ds:[PSP_DGROUP_SEG]          ;[2] get DGROUP
                    627:        mov     ds, ax                          ;[2] ds = DGROUP
                    628: 
                    629:        mov     ax, word ptr [retadr]           ; [1] Offset...
                    630:        mov     word ptr [__QCrtcsip], ax       ; [1] ...save
                    631: if sizeC
                    632:        mov     ax, word ptr [retadr+2]         ; [1] Segment...
                    633:        mov     word ptr [__QCrtcsip+2], ax     ; [1] ...save
                    634: else                                           ; [1]
                    635:        mov     word ptr [__QCrtcsip+2], cs     ; [1] (Near call)
                    636: endif                                          ; [1]
                    637: endif  ;_QC                                    ; [1] (_QC)
                    638: 
                    639:        mov     ax,8
                    640:        jmp     _amsg_exit      ;
                    641: 
                    642: no_arg_err:
                    643:        jmp     [retadr]
                    644: 
                    645: page
                    646: ;***
                    647: ;_find(dir) - find first matching file name against pattern "dir"
                    648: ;
                    649: ;Purpose:
                    650: ;      _find(dir) - Find first matching file name against pattern "dir"
                    651: ;      If dir == NULL, then get next match for current pattern.
                    652: ;
                    653: ;Entry:
                    654: ;      dir     = DATA PTR of pattern to match
                    655: ;
                    656: ;Exit:
                    657: ;      AX      = the address of a static area containing the file name if a
                    658: ;                match was found.  Returns NULL if no match was found.
                    659: ;
                    660: ;Uses:
                    661: ;      CX,DX, [dta_flag].
                    662: ;
                    663: ;Exceptions:
                    664: ;
                    665: ;*******************************************************************************
                    666: 
                    667: cProc  _find,<PUBLIC>
                    668:        parmdp  dir
                    669: cBegin
                    670:        test    [dta_flag],-1
                    671:        jnz     not_very_first
                    672: 
                    673:        mov     [dta_flag],-1
                    674: ;
                    675: ;      Set DTA, where the match structure is returned
                    676: ;
                    677:        mov     dx,dataOFFSET file_reserv
                    678:        callos  setdma
                    679: ;
                    680: not_very_first:
                    681:        mov     ah,DOS_findnext ; assume not first
                    682: 
                    683: if     sizeD
                    684:        push    ds
                    685:        lds     dx,dir
                    686:        mov     cx,ds
                    687:        jcxz    find_next
                    688: else
                    689:        mov     dx,dir
                    690:        test    dx,dx
                    691:        jz      find_next
                    692: endif
                    693:        mov     cx,A_D          ; match directories as well as files
                    694:        mov     ah,DOS_findfirst
                    695: find_next:
                    696:        callos
                    697: if     sizeD
                    698:        pop     ds
                    699: endif
                    700:        mov     ax,dataOFFSET file_name
                    701: if     sizeD
                    702:        mov     dx,ds
                    703: endif
                    704:        jnc     retname
                    705: 
                    706:        xor     ax,ax           ; return 0 for no more matches
                    707: if     sizeD
                    708:        cwd
                    709: endif
                    710: 
                    711: retname:
                    712: 
                    713: cEnd
                    714: 
                    715: endif                          ;       WILDCARD        ; ***********************************************
                    716: 
                    717: sEnd   code
                    718: 
                    719:        end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.