    page    96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§                                                                          §
;§              ディレクトリエントリ  ソート  ユーティリティ                §
;§                                                                          §
;§                                     ＤＳＯＲＴ．ＥＸＥ  Ｖｅｒ１.１１    §
;§                                                                          §
;§                   Copyright (C) by 福地 邦雄 1991. All rights reserved.  §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
    .MODEL  SMALL,C
;
    public  options,usageout,dirlist,dirfind,strcopywild
    extrn   sweep:word,sortexec:word,recursive:word,dirgather:word
    extrn   dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
    extrn   dirtype:word,fattype:word,attribute:word,clustcount:word
    extrn   driveno:word,clustsize:word,fatsize:word,dirsize:word
    extrn   fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
    extrn   drvinf:byte,clustsect:word,subsearch:word
    extrn   sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
    extrn   usagemsg:byte,_msgsize:abs
    extrn   abort:near
    extrn   errorno:word
;
    PUBLIC  setsortfunc,setsortobj,cmpdummy,cmpdirf,cmpfull,cmpname
    PUBLIC  cmpextn,cmpsize,cmpdate,cmptime,strncmp,chrtypes,pathsep
;
REVERSE equ 1
NORMAL  equ 0
TAIL    equ 1
HEAD    equ 0
YES     equ 1
NO      equ 0
TAB     equ 9
CR      equ 0dh
LF      equ 0ah
DEFAULT equ 031h
ARCHIVE equ 020h
SUBDIR  equ 010h
VOLUME  equ 008h
HIDDEN  equ 004h
SYSTEM  equ 002h
RDONLY  equ 001h
;
    .code
;
;------------------------------------------------------------------------------
;
;   options
;       オプション指定の評価とディレクトリのリストを取る
;
;   TYPE    near call
;   IN  AX アーギュメント数
;       SS:BP アーギュメントポインタリストの先頭アドレス
;   OUT 特になし
;   保存レジスタ    ds
;
;------------------------------------------------------------------------------
;
options proc
;
    cld
    push    ax
    mov     ah,2fh                  ; Disk Transfer Address 取得
    int     21h
    lea     bx,[bx+1eh]             ; DTAのファイル名オフセット
    mov     word ptr dta,bx
    mov     word ptr dta+2,es
    pop     bx
    mov     sortfuncs,offset _text:cmpdummy ; ダミーのソート比較関数セット
    mov     word ptr sortfuncs+2,NORMAL
    mov     si,offset sortfuncs+4
    mov     attribute,DEFAULT       ; ソート対象属性のデフォルトセット
;   @do until
@d0001:
        les     di,[bp]
;       @cbegin
;       @case (byte ptr es:[di],=,'-'),S
          cmp   byte ptr es:[di],'-'
          jne   @c0002
            call    setsortfunc
;       @case (byte ptr es:[di],=,'+'),S
          jmp short @c0001
@c0002:
          cmp   byte ptr es:[di],'+'
          jne   @c0003
            call    setsortobj
;       @other
          jmp short @c0001
@c0003:
            mov     word ptr srchname,di    ; ディレクトリ名リストの作成
            mov     word ptr srchname+2,es
            call    dirlist
;       @cend
@c0001:
        add     bp,4                ; 次のアーギュメントへ
        dec     bx
;   @doend (zf,on)
      jnz   @d0001
;   @if (si,=,offset sortfuncs+4)
      cmp   si,offset sortfuncs+4
      jne   @i0001
        mov     word ptr [si],offset cmpfull    ; デフォルトの比較関数セット
        mov     word ptr [si+2],NORMAL
        lea     si,[si+4]
;   @ifend
@i0001:
    not     attribute               ; ソート対象属性を反転させたものを使う
    mov     word ptr [si],0         ; ソート比較関数リストのエンドマーク
    les     di,namebuff             ; ディレクトリ名リストのエンドマーク
    mov     word ptr es:[di],0
;   @if (word ptr es:[0],=,0)
      cmp   word ptr es:[0],0
      jne   @i0002
        jmp     usageout            ; ディレクトリ無しの時、ヘルプ表示
;   @ifend
@i0002:
    ret
;
options endp
;
;------------------------------------------------------------------------------
;
;   usageout
;       ヘルプメッセージを表示して終了
;
;   TYPE    near call
;   IN  なし
;   OUT なし
;   保存レジスタ    なし
;
;------------------------------------------------------------------------------
;
usageout    proc
;
    mov     errorno,1
    mov     dx,offset usagemsg
    mov     cx,_msgsize
    jmp     abort
;
usageout    endp
;
;------------------------------------------------------------------------------
;
;   setsortfunc
;       ソート機能指定オプションの評価と、比較関数リストの作成
;
;   TYPE    near call
;   IN      AL アーギュメント文字
;           DS:SI 比較関数リストアドレス
;   OUT     SI += 4 
;   保存レジスタ    bx,cx,dx,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
setsortfunc proc
;
    inc     di
;   @do repeat
@d0002:
        mov     al,es:[di]
        inc     di
;       @if (al,=,0)
          or    al,al
          jne   @i0003
;           @doexit
              jmp   @d0003
;       @ifend
@i0003:
;       @if (al,>=,'a'),S           ; 昇順
          cmp   al,'a'
          jb    @i0004
            mov     word ptr [si+2],NORMAL
            sub     al,'a'-'A'
;       @else                       ; 降順
          jmp short @i0005
@i0004:
            mov     word ptr [si+2],REVERSE
;       @ifend
@i0005:
;       @cbegin
;       @case (al,=,'D'),S          ; 最終更新日付
          cmp   al,'D'
          jne   @c0005
            mov     ax,offset _text:cmpdate
;       @case (al,=,'E'),S          ; 拡張子 3バイト
          jmp short @c0004
@c0005:
          cmp   al,'E'
          jne   @c0006
            mov     ax,offset _text:cmpextn
;       @case (al,=,'F'),S          ; フルネーム 11バイト
          jmp short @c0004
@c0006:
          cmp   al,'F'
          jne   @c0007
            mov     ax,offset _text:cmpfull
;       @case (al,=,'N'),S          ; ファイル名 8バイト
          jmp short @c0004
@c0007:
          cmp   al,'N'
          jne   @c0008
            mov     ax,offset _text:cmpname
;       @case (al,=,'S'),S          ; ファイルサイズ
          jmp short @c0004
@c0008:
          cmp   al,'S'
          jne   @c0009
            mov     ax,offset _text:cmpsize
;       @case (al,=,'T'),S          ; 最終更新時刻
          jmp short @c0004
@c0009:
          cmp   al,'T'
          jne   @c0010
            mov     ax,offset _text:cmptime
;       @other
          jmp short @c0004
@c0010:
            jmp     usageout
;       @cend
@c0004:
        mov     [si],ax
        lea     si,[si+4]
;   @doend
      jmp   @d0002
@d0003:
    ret
;
setsortfunc endp
;
;------------------------------------------------------------------------------
;
;   setsortobj
;       ソート対象選択オプション評価
;
;   TYPE    near call
;   IN  AL アーギュメント文字
;   OUT なし
;   保存レジスタ    AX以外
;
;------------------------------------------------------------------------------
;
setsortobj  proc
;
    inc     di
;   @do repeat
@d0004:
        mov     al,es:[di]
        inc     di
;       @if (al,=,0)
          or    al,al
          jne   @i0006
;           @doexit
              jmp   @d0005
;       @ifend
@i0006:
;       @if (al,>=,'a'),S           ; 先頭に
          cmp   al,'a'
          jb    @i0007
            mov     dirgather,HEAD
            sub     al,'a'-'A'
;       @else                       ; 末尾に
          jmp short @i0008
@i0007:
            mov     dirgather,TAIL
;       @ifend
@i0008:
;       @cbegin
;       @case (al,=,'G'),S          ; ディレクトリの扱い
          cmp   al,'G'
          jne   @c0012
            mov     sortfuncs,offset _text:cmpdirf
            mov     ax,dirgather
            mov     sortfuncs+2,ax
;       @case (al,=,'T'),S          ; 再帰呼び出し
          jmp short @c0011
@c0012:
          cmp   al,'T'
          jne   @c0013
            mov     recursive,YES
;       @case (al,=,'N'),S          ; ソート無し
          jmp short @c0011
@c0013:
          cmp   al,'N'
          jne   @c0014
            mov     sortexec,NO
;       @case (al,=,'F'),S          ; 掃き寄せ無し
          jmp short @c0011
@c0014:
          cmp   al,'F'
          jne   @c0015
            mov     sweep,NO
;       @case (al,=,'A'),S          ; アーカイブ属性
          jmp short @c0011
@c0015:
          cmp   al,'A'
          jne   @c0016
            xor     attribute,ARCHIVE
;       @case (al,=,'D'),S          ; ディレクトリ
          jmp short @c0011
@c0016:
          cmp   al,'D'
          jne   @c0017
            xor     attribute,SUBDIR
;       @case (al,=,'V'),S          ; ボリュームラベル
          jmp short @c0011
@c0017:
          cmp   al,'V'
          jne   @c0018
            xor     attribute,VOLUME
;       @case (al,=,'S'),S          ; システムファイル
          jmp short @c0011
@c0018:
          cmp   al,'S'
          jne   @c0019
            xor     attribute,SYSTEM
;       @case (al,=,'H'),S          ; 隠しファイル
          jmp short @c0011
@c0019:
          cmp   al,'H'
          jne   @c0020
            xor     attribute,HIDDEN
;       @case (al,=,'R'),S          ; 読み出しのみ可能
          jmp short @c0011
@c0020:
          cmp   al,'R'
          jne   @c0021
            xor     attribute,RDONLY
;       @other
          jmp short @c0011
@c0021:
            jmp     usageout
;       @cend
@c0011:
;   @doend
      jmp   @d0004
@d0005:
    ret
;
setsortobj  endp
;
;------------------------------------------------------------------------------
;
;   cmpdummy
;       ダミー比較ルーチン 必ず ＝ で終了
;
;   TYPE    near call
;   IN  なし
;   OUT AX=0 ZERO FLAG=1
;   保存レジスタ    AX以外
;
;------------------------------------------------------------------------------
;
cmpdummy    proc
;
    xor     ax,ax
    ret
;
cmpdummy    endp
;
;------------------------------------------------------------------------------
;
;   cmpdirf
;       ディレクトリ属性比較
;
;   TYPE    near call
;   IN      DS:SI エントリ１アドレス
;           ES:DI エントリ２アドレス
;   OUT     AX ﾃﾞｨﾚｸﾄﾘ:通常= -1  通常:ﾃﾞｨﾚｸﾄﾘ= 1  その他 0
;   保存レジスタ    AX以外
;
;------------------------------------------------------------------------------
;
cmpdirf proc
;
    mov     al,[si+0bh]             ; 属性バイトの取り出し
    mov     ah,[di+0bh]
    and     ax,01010h
    cmp     al,ah
    ja      dirfhead                ; Dir:File
    jb      dirftail                ; File:Dir
    xor     ax,ax                   ; 同じ属性
    ret
dirfhead:
    mov     ax,-1
    ret
dirftail:
    mov     ax,1
    ret
;
cmpdirf endp
;
;------------------------------------------------------------------------------
;
;   cmpfull
;       フルネーム比較
;
;   TYPE    near call
;   IN      DS:SI エントリ１アドレス
;           ES:DI エントリ２アドレス
;   OUT     AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpfull proc
;
    mov     cx,11
    call    strncmp
    ret
;
cmpfull endp
;
;------------------------------------------------------------------------------
;
;   cmpname
;       ファイル名比較
;
;   TYPE    near call
;   IN      DS:SI エントリ１アドレス
;           ES:DI エントリ２アドレス
;   OUT     AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpname proc
;
    mov     cx,8
    call    strncmp
    ret
;
cmpname endp
;
;------------------------------------------------------------------------------
;
;   cmpextn
;       拡張子比較
;
;   TYPE    near call
;   IN      DS:SI エントリ１アドレス
;           ES:DI エントリ２アドレス
;   OUT     AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpextn proc    uses bx si di
;
    lea     si,[si+8]               ; 拡張子位置
    lea     di,[di+8]
    mov     cx,3
    call    strncmp
    ret
;
cmpextn endp
;
;------------------------------------------------------------------------------
;
;   cmpsize
;       ファイルサイズ比較
;
;   TYPE    near call
;   IN  DS:SI エントリ１アドレス
;       ES:DI エントリ２アドレス
;   OUT AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpsize proc
;
    mov     ax,[si+1ch]             ; エントリ１のファイルサイズ４バイト
    mov     cx,[si+1eh]
    cmp     cx,[di+1eh]             ; エントリ２と比較
    ja      sizeabove
    jb      sizebelow
    cmp     ax,[di+1ch]
    ja      sizeabove
    jb      sizebelow
    xor     ax,ax
    ret
sizeabove:
    mov     ax,1
    ret
sizebelow:
    mov     ax,-1
    ret
;
cmpsize endp
;
;------------------------------------------------------------------------------
;
;   cmpdate
;       最終更新日付比較
;
;   TYPE    near call
;   IN  DS:SI エントリ１アドレス
;       ES:DI エントリ２アドレス
;   OUT AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmpdate proc
;
    mov     ax,[si+18h]
    cmp     ax,[di+18h]
    ja      dateabove
    jb      datebelow
    xor     ax,ax
    ret
dateabove:
    mov     ax,1
    ret
datebelow:
    mov     ax,-1
    ret
;
cmpdate endp
;
;------------------------------------------------------------------------------
;
;   cmptime
;       最終更新時刻比較
;
;   TYPE    near call
;   IN  DS:SI エントリ１アドレス
;       ES:DI エントリ２アドレス
;   OUT AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
cmptime proc
;
    mov     ax,[si+16h]
    cmp     ax,[di+16h]
    ja      timeabove
    jb      timebelow
    xor     ax,ax
    ret
timeabove:
    mov     ax,1
    ret
timebelow:
    mov     ax,-1
    ret
;
cmptime endp
;
;------------------------------------------------------------------------------
;
;   strncmp
;       文字列比較 漢字対応 漢字はANKより大きい
;
;   TYPE    near call
;   IN  CX 比較サイズ
;       DS:SI エントリ１アドレス
;       ES:DI エントリ２アドレス
;   OUT AX ｴﾝﾄﾘ1<ｴﾝﾄﾘ2= -1  ｴﾝﾄﾘ1=ｴﾝﾄﾘ2= 0  ｴﾝﾄﾘ1>ｴﾝﾄﾘ2= 1
;   保存レジスタ    bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
strncmp proc    uses bx si di
;
    cld
;   @do until
@d0006:
        dec     cx
        mov     ax,[si]             ; エントリ１ １文字取得
        inc     si
        call    chrtypes
;       @if (zf,off)
          jz    @i0009
            dec     cx
            inc     si
;       @ifend
@i0009:
;
        mov     bx,ax
        mov     ax,[di]             ; エントリ２ １文字取得
        inc     di
        call    chrtypes
;       @if (zf,off)
          jz    @i0010
            inc     di
;       @ifend
@i0010:
        cmp     bx,ax               ; 比較
        ja      strabove
        jb      strbelow
        or      cx,cx
;   @doend (zf,on),or,(sf,on)
      jz    @d0007
      js    @d0007
      jmp   @d0006
@d0007:
;
    xor     ax,ax
streturn:
    ret
;
strabove:
    mov     ax,1
    jmp     streturn
strbelow:
    mov     ax,-1
    jmp     streturn
;
strncmp endp
;
;------------------------------------------------------------------------------
;
;   chrtypes
;       漢字判定
;
;   TYPE    near call
;   IN  AX 文字コード AL=第一バイト
;   OUT AX 判定後コード ANK:AH=0
;       ZERO FLAG AHのTEST結果
;   保存レジスタ    AX以外
;
;------------------------------------------------------------------------------
;
chrtypes    proc
;
    cmp     al,081h
    jb      chrank
    cmp     al,0a0h
    jb      chrsjis
    cmp     al,0e0h
    jb      chrank
    cmp     al,0fch
    jbe     chrsjis
chrank:
    xor     ah,ah
    ret
chrsjis:
    xchg    ah,al
    test    ah,ah
    ret
;
chrtypes    endp
;
;------------------------------------------------------------------------------
;
;   dirlist
;       全てのディレクトリ名を検索して、そのパス名をバッファに格納する
;       ワイルドカード対応  FUNCTION    4EH,4FH
;
;   TYPE    near call
;   IN  検索情報構造体
;   OUT ディレクションフラグ アップ方向
;   保存レジスタ    bp,ds
;
;------------------------------------------------------------------------------
;
dirlist    proc uses bx si
        local copysiz,fnamsiz,saveds
;
    mov     saveds,ds               ;DS セーブ
    les     di,srchname             ;パス名の長さと、最終位置を獲得
    mov     cx,0ffffh
    cld
    xor     al,al
  repne scasb
    not     cx
    dec     cx
    mov     fnamsiz,cx
    mov     di,word ptr srchname
    call    pathsep                 ; パス名中の最後の'\'位置を獲得
    mov     copysiz,cx              ; バッファへの共通コピーサイズをセット
    mov     di,word ptr srchname
    mov     dx,es:[di]
;   @cbegin
;   @case (zf,on)                   ; セパレータなし
      jnz   @c0023
;       @if (dx,=,'.'),or,(dx,=,'..')   ; カレント/親？
          cmp   dx,'.'
          je    @i0011
          cmp   dx,'..'
          jne   @i0012
@i0011:
            jmp parentdir
;       @ifend
@i0012:
;   @case (fnamsiz,=,1),and,(dl,=,'\'),S ; ルート指定か？
      jmp   @c0022
@c0023:
      cmp   fnamsiz,1
      jne   @c0024
      cmp   dl,'\'
      jne   @c0024
        mov     ah,19h              ; カレントドライブ取得
        int     21h
        add     al,'A'              ; ドライブ名作成
        mov     ah,':'
        jmp     rootpath
;   @case (cx,=,2),S                ; カレント/親 指定か？
      jmp short @c0022
@c0024:
      cmp   cx,2
      jne   @c0025
;       @if (dh,=,':')
          cmp   dh,':'
          jne   @i0013
;           @if (fnamsiz,=,2)
              cmp   fnamsiz,2
              jne   @i0014
                sub     namebuffsiz,4   ; ディレクトリ名バッファサイズチェック
;               @if (cf,on)
                  jnc   @i0015
                    add     namebuffsiz,4
                    jmp     srchout
;               @ifend
@i0015:
                cld
                les     di,namebuff
                mov     ax,dx           ; ドライブ名
                stosw
                mov     ax,'.'          ; カレントディレクトリ指定
                stosw
                mov     word ptr namebuff,di    ; 新オフセット設定
                jmp     srchout
;           @ifend
@i0014:
;           @if (fnamsiz,<=,4)
              cmp   fnamsiz,4
              ja    @i0016
                mov ax,es:[di+2]
;               @if (ax,=,'.'),or,(ax,=,'..')
                  cmp   ax,'.'
                  je    @i0017
                  cmp   ax,'..'
                  jne   @i0018
@i0017:
                    jmp parentdir
;               @ifend
@i0018:
;           @ifend
@i0016:
;       @ifend
@i0013:
;   @case (fnamsiz,=,3),and,(word ptr es:[di+1],=,'\:'),S ; ルート指定か？
      jmp short @c0022
@c0025:
      cmp   fnamsiz,3
      jne   @c0026
      cmp   word ptr es:[di+1],'\:'
      jne   @c0026
        mov     ax,dx
rootpath:
        sub     namebuffsiz,3       ; バッファ残りサイズ確認
;       @if (cf,on)
          jnc   @i0019
            add     namebuffsiz,3
            jmp     srchout
;       @ifend
@i0019:
        cld
        les     di,namebuff         ; ドライブ名のみセット
        stosw
        xor     al,al
        stosb
        mov     word ptr namebuff,di
        jmp     srchout
;   @cend
@c0022:
@c0026:
;
    mov     ah,4eh                  ;最初のファイル名検索ファンクション
    mov     cx,037h                 ;ボリュームラベル以外すべて
    lds     dx,srchname
    int     21h
;   @do while,(cf,off)
@d0008:
      jc    @d0009
        mov     ds,saveds           ; DS 復元
        les     di,dta
;       @if (byte ptr es:[di-9],on,10h) ;ディレクトリかどうかのチェック
          test  byte ptr es:[di-9],10h
          jz    @i0020
            mov     dx,es:[di]      ; 再帰処理のさいに '.' '..' を外す
;           @if (subsearch,=,YES)
              cmp   subsearch,YES
              jne   @i0021
;               @if (dx,=,'.'),or,(dx,=,'..')
                  cmp   dx,'.'
                  je    @i0022
                  cmp   dx,'..'
                  jne   @i0023
@i0022:
                    jmp     skipperiod
;               @ifend
@i0023:
;           @ifend
@i0021:
            mov     cx,13           ;DTA上のファイル名から、長さを獲得
            xor     al,al
            cld
          repne scasb
            sub     cx,13
            neg     cx
            mov     fnamsiz,cx      ;ファイル名長さをセーブ
            add     cx,copysiz      ;残りバッファサイズのチェックと更新
            sub     namebuffsiz,cx
;           @if (cf,on)
              jnc   @i0024
                add     namebuffsiz,cx  ;不足
                jmp     short   srchout
;           @ifend
@i0024:
            les     di,namebuff     ;共通パス名のコピー
            lds     si,srchname
            mov     cx,copysiz
          rep   movsb
            mov     ds,saveds       ;ファイル名のコピー
            lds     si,dta
            mov     cx,fnamsiz
            rep     movsb
            mov     ds,saveds
            mov     word ptr namebuff,di    ;新オフセットの設定
;       @ifend
@i0020:
skipperiod:
        mov     ah,4fh              ;次のファイル名検索ファンクション
        lds     dx,srchname
        mov     cx,037h
        int     21h                 ;見つかればパス名セーブ
;   @doend
      jmp   @d0008
@d0009:
    mov ds,saveds
srchout:
    ret
;
parentdir:
    cld                             ; パス名長さを調べる
    les     di,srchname
    xor     ax,ax
    mov     cx,-1
  repne scasb
    not     cx
    sub     namebuffsiz,cx
;   @if (cf,on)
      jnc   @i0025
        add     namebuffsiz,cx      ;不足
        jmp     short   srchout
;   @ifend
@i0025:
    les     di,namebuff             ;ファイル名のコピー
    lds     si,srchname
  rep movsb
    mov     ds,saveds               ; DS 復元
    mov     word ptr namebuff,di    ;新オフセットの設定
    jmp     short   srchout
;
dirlist    endp
;
;------------------------------------------------------------------------------
;
;   pathsep
;       パス名を調べて一番最後の':'か'\'までのバイト数を通知する
;
;   TYPE    near call
;   IN  CX      パス名長さ
;       ES:DI   パス名の先頭アドレス
;   OUT CX & ZERO FLAG 最後の':'or'\'までのバイト数 及び 0か？
;       DIR FLAG アップ方向
;   保存レジスタ    bx,si,bp,ds,es
;
;------------------------------------------------------------------------------
;
pathsep     proc
;
;   @if (cx,/=,0)                   ; 0 でない時
      or    cx,cx
      je    @i0026
        push    cx                  ; 長さをセーブ
        xor     dx,dx               ; 位置を初期化
;       @do until
@d0010:
            mov     al,es:[di]      ; 文字獲得
            inc     di
;           @cbegin
;           @case (al,=,':'),or,(al,=,'\'),S ; セパレータならば位置を記憶
              cmp   al,':'
              je    @c0028
              cmp   al,'\'
              jne   @c0029
@c0028:
                mov     dx,cx
;           @case (al,<,81h),or,(al,>,0fch),S ; α/Ｎ なにもしない
              jmp short @c0027
@c0029:
              cmp   al,81h
              jb    @c0030
              cmp   al,0fch
              jbe   @c0031
@c0030:
;           @case (al,>=,0a0h),and,(al,<=,0dfh),S ; カナ なにもしない
              jmp short @c0027
@c0031:
              cmp   al,0a0h
              jb    @c0032
              cmp   al,0dfh
              ja    @c0032
;           @other                  ; 漢字 第二バイト分を進める
              jmp short @c0027
@c0032:
                inc     di
                dec     cx          ; 残り0なら終了
                jz      analysend
;           @cend
@c0027:
            dec     cx              ; 残り0なら終了
;       @doend (zf,on)
          jnz   @d0010
analysend:
        pop     cx                  ; パス名長を復元
;       @if (dx,/=,0),S             ; セパレータが有った時
          or    dx,dx
          je    @i0027
            dec     dx              ; DX にはパス名最後からのオフセット
            sub     cx,dx           ; 先頭からのオフセットに直す
;       @else
          jmp short @i0028
@i0027:
            xor     cx,cx           ; セパレータが無い時は0
;       @ifend
@i0028:
;   @ifend
@i0026:
    ret
;
pathsep     endp
;
;------------------------------------------------------------------------------
;
;   dirfind
;       パス名をもとにディレクトリかを調べ、ディレクトリの開始クラスタ
;       と、存在するドライブ番号を通知する
;
;   TYPE    near call
;   IN  ES:DI パス名の先頭アドレス
;   OUT AX ディレクトリの開始クラスタ番号
;       DL ドライブ番号
;       CARRY FLAG ディレクトリ属性 0:DIR 1:OTHERまたはルートでﾌｧｲﾙ無し
;   保存レジスタ    bp,ds
;
;------------------------------------------------------------------------------
;
dirfind     proc
;
    call    strcopywild             ; 検索用パス名の作成
;
    mov     ah,2fh                  ; DTA 取得
    int     21h
;
    mov     ah,4eh                  ; ファイル検索
    mov     cx,3fh
    int     21h
;   @if (cf,off)                    ; 見つかった
      jc    @i0029
        mov     ax,es:[bx+0fh]      ; ディレクトリの開始クラスタ取得
        xor     dx,dx
        mov     dl,es:[bx]          ; ディレクトリのドライブ番号取得
;   @ifend
@i0029:
    ret
;
dirfind     endp
;
;------------------------------------------------------------------------------
;
;   strcopywild
;       指定されたパス名をPATHBUFFにコピーし、ワイルドカードを付加する
;
;   TYPE    near call
;   IN  ES:DI パス名の先頭アドレス
;   OUT PATHBUFF
;       ES:DI PATHBUFFのアドレス
;   保存レジスタ    bp,ds
;
;------------------------------------------------------------------------------
;
strcopywild proc
;
    cld                             ; パス名長さを調べる
    mov     cx,-1
    xor     ax,ax
    mov     si,di
  repne     scasb
    not     cx
    dec     cx
    mov     ax,ds                   ; パス名をPATHBUFFにコピー
    mov     dx,es
    mov     ds,dx
    mov     es,ax
    mov     di,offset pathbuff
    mov     dx,di
    rep     movsb
    mov     ds,ax                   ; ワイルドカード指定を付加
    mov     cx,5
    mov     si,offset wildcard
    rep     movsb
;
    mov     di,offset pathbuff
    ret
;
strcopywild endp
;
    end
