CODE SEGMENT
    ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE
    ORG 80H
    DtaType STRUC
        DtaDummy DB 21 DUP (?)
        DtaAttr DB ?
        DtaTime DW ?
        DtaDate DW ?
        DtaSize_Low DW ?
        DtaSize_High DW ?
        DtaName DB 13 DUP (?)
    DtaType ENDS
    DTA DtaType <>
    ORG 100H
START: CLD
    MOV AH, 19H
    INT 21H
    ADD AL, 'A'
    MOV PATH[0], AL
    MOV SI, OFFSET DTA
    @@: INC SI
        CMP BYTE PTR [SI], 0DH
    JE @F
        CMP BYTE PTR [SI], ' '
    JBE @B
@@: PUSH SI
    CMP BYTE PTR [SI], 0DH
    JE @NULL
    @@: INC SI
        CMP BYTE PTR [SI], 0DH
    JNE @B
    @@: DEC SI
        CMP BYTE PTR [SI], ' '
    JE @B
    INC SI
    @NULL: MOV BYTE PTR [SI], 0
    POP SI
    MOV DI, OFFSET FILE
    MOV WORD PTR [DI], '.*'
    MOV WORD PTR [DI+2], '*'
    CMP BYTE PTR [SI], 0
    JE SearchStart
    CMP WORD PTR [SI], '?/'
    JNE @F
        MOV AH, 9
        MOV DX, OFFSET DTA_BUFFER
        INT 21H
        MOV AH, 4CH
        INT 21H
    @@: CMP BYTE PTR [SI+1], ':'
        JNE @F
        LODSB
        MOV PATH[0], AL
        INC SI
        CMP BYTE PTR [SI], 0
        JE SearchStart
    @@: MOV CX, 12
        @@: LODSB
            STOSB
            CMP AL, 0
            JE @F
        LOOP @B
        @@: CMP AL, 0
            JE NotKanji
            CMP AL, 0DFH
            JA Kanji
            CMP AL, 21H
            JB Kanji
            CMP AL, 7FH
            JB NotKanji
            CMP AL, 0A0H
            JA NotKanji
            Kanji: DEC DI
            NotKanji: MOV BYTE PTR [DI], 0
    SearchStart:
        MOV DI, OFFSET NUMBER
        MOV CX, 10
        MOV AL, '0' - 1
        @1: INC AL
            PUSH CX
            MOV CL, 10
            MOV AH, '0' - 1
            @2: INC AH
                STOSW
            LOOP @2
            POP CX
        LOOP @1

        MOV AH, 9
        MOV DX, OFFSET MSG1
        INT 21H
        MOV BX, OFFSET FILE
        MOV AH, 2
    @@: MOV DL, [BX]
        OR DL, DL
        JZ @DispEnd
        INT 21H
        INC BX
    JMP SHORT @B
    @DispEnd:
        MOV AH, 9
        MOV DX, OFFSET MSG2
        INT 21H
        CALL SEARCH
        MOV AX, TotalCount
        XOR DX, DX
        CALL Conv_DX_AX
        ADD SI, 5
        MOV DI, OFFSET RESULT[7]
        MOV CX, 5
        REP MOVSB
        MOV AX, TotalSize_Low
        MOV DX, TotalSize_High
        CALL Conv_DX_AX
        MOV DI, OFFSET RESULT[19]
        MOV CX, 5
        REP MOVSW
        MOV AH, 9
        MOV DX, OFFSET RESULT
        INT 21H
        MOV AX, 4C00H
        INT 21H


    SEARCH:                            ; ファイルの検索
            MOV BX, OFFSET PATH        ; FIND = PATH + FILE + 0
            MOV SI, OFFSET FIND
        @@: MOV DL, [BX]
            OR DL, DL
            JZ @F
            MOV [SI], DL
            INC SI
            INC BX
            JMP SHORT @B
        @@: MOV BX, OFFSET FILE
        @@: MOV DL, [BX]
            MOV [SI], DL
            OR DL, DL
            JZ @F
            INC SI
            INC BX
            JMP SHORT @B
        @@: MOV AH, 4EH                ; 最初のファイルを検索
            MOV DX, OFFSET FIND
            MOV CX, 00100111B          ; A + S + H + R
            INT 21H
            JNC @DispPath
            JMP CheckDir
        @DispPath:
            MOV AH, 2                  ; パス名の表示
            MOV BX, (OFFSET PATH) + 2
        @@: MOV DL, [BX]
            OR DL, DL
            JZ @F
            INT 21H
            INC BX
            JMP SHORT @B
        @@: MOV DL, 0DH
            INT 21H
            MOV DL, 0AH
            INT 21H
        DispFile:                      ; ファイル情報の表示
                INC TotalCount         ; ファイルサイズをセット
                MOV AX, DTA.DtaSize_Low
                ADD TotalSize_Low, AX
                MOV DX, DTA.DtaSize_High
                ADC TotalSize_High, DX
                CALL Conv_DX_AX
                MOV DX, DTA.DtaDate    ; 最終更新日をセット
                MOV CL, 9
                SHR DX, CL
                ADD DL, 80
                MOV AX, '91'
                CMP DL, 100
                JB @F                  ;Jump if YEAR < 2000.
                MOV AX, '02'
                SUB DL, 100
            @@: MOV WORD PTR FORMAT[12], AX
                MOV AL, 2FH
            @@: INC AL
                SUB DL, 10
                JNC @B
                ADD DL, 10
                MOV AH, 2FH
            @@: INC AH
                SUB DL, 1
                JNC @B
                MOV WORD PTR FORMAT[14], AX

                MOV BX, DTA.DtaDate
                MOV DX, BX
                MOV CL, 5
                SHR BX, CL
                AND BX, 1111B
                SHL BX, 1
                ADD BX, OFFSET NUMBER
                MOV AX, [BX]
                MOV WORD PTR FORMAT[17], AX
                MOV BX, DX
                AND BX, 11111B
                SHL BX, 1
                ADD BX, OFFSET NUMBER
                MOV AX, [BX]
                MOV WORD PTR FORMAT[20], AX
                MOV BX, DTA.DtaTime    ; 最終更新時刻をセット
                MOV DX, BX
                MOV CL, 11
                SHR BX, CL
                SHL BX, 1
                ADD BX, OFFSET NUMBER
                MOV AX, [BX]
                MOV WORD PTR FORMAT[23], AX
                MOV BX, DX
                MOV CL, 5
                SHR BX, CL
                AND BX, 111111B
                SHL BX, 1
                ADD BX, OFFSET NUMBER
                MOV AX, [BX]
                MOV WORD PTR FORMAT[26], AX
                MOV BX, DX
                AND BX, 11111B
                MOV CL, 2
                SHL BX, CL
                ADD BX, OFFSET NUMBER
                MOV AX, [BX]
                MOV WORD PTR FORMAT[29], AX
                                       ; ファイル属性をセット
                MOV WORD PTR FORMAT[32], ' A'
                MOV WORD PTR FORMAT[34], '  '
                MOV AL, DTA.DtaAttr
                TEST AL, 20H
                JNZ @F
                MOV FORMAT[32], ' '
            @@: TEST AL, 4
                JZ @F
                MOV FORMAT[33], 'S'
            @@: TEST AL, 2
                JZ @F
                MOV FORMAT[34], 'H'
            @@: TEST AL, 1
                JZ @F
                MOV FORMAT[35], 'R'
            @@: MOV AH, 2        ; ファイル名の表示
                MOV DL, ' '
                INT 21H
                INT 21H
                INT 21H
                INT 21H
                MOV CX, 15
                MOV BX, OFFSET DTA.DtaName
            @@: MOV DL, [BX]
                OR DL, DL
                JZ @F
                INT 21H
                INC BX
                LOOP @B
            @@: MOV DL, ' '
            @@: INT 21H
                LOOP @B
                MOV AH, 9              ; ファイル情報を表示
                MOV DX, OFFSET FORMAT
                INT 21H
            @@: MOV AH, 4FH            ; 次のファイルを検索
                INT 21H
                JC CheckDir
            JMP DispFile
        ;----------------------------------------------------------------
        CheckDir:                      ; ディレクトリの検索
            MOV BX, OFFSET PATH        ; BX = OFFSET PATH
            MOV SI, OFFSET FIND        ; SI = OFFSET FIND
        @@: MOV DL, [BX]               ; FIND = PATH + ????????.??? + 0
            OR DL, DL
            JZ @F
            MOV [SI], DL
            INC SI
            INC BX
            JMP SHORT @B
        @@: MOV WORD PTR [SI], '.*'
            MOV WORD PTR [SI+2], '*'
            MOV AH, 4EH                ; 最初のディレクトリを検索
            MOV DX, OFFSET FIND
            MOV CX, 00110111B          ; A + D + S + H + R
        NextDir:
            INT 21H
            JNC @F
    RET
            @@: TEST DTA.DtaAttr, 10H  ; ディレクトリで無ければ次を検索
                JZ NotDir
                CMP BYTE PTR DTA.DtaName[0], '.'
                JE NotDir              ; 子ディレクトリでないならば
                ;'()'                  ; 次のディレクトリを検索
                MOV SI, OFFSET DTA     ; 現在のＤＴＡを退避
                MOV DI, CURRENT_PTR
                MOV CX, 21
                ADD CURRENT_PTR, CX
                REP MOVSB
                MOV BX, OFFSET PATH
                MOV SI, OFFSET DTA.DtaName
            @@: MOV DL, [BX]
                OR DL, DL
                JZ @F
                INC BX
                JMP SHORT @B
            @@: PUSH BX
            @@: MOV DL, [SI]
                OR DL, DL
                JZ @F
                MOV [BX], DL
                INC BX
                INC SI
                JMP SHORT @B
            @@: MOV WORD PTR [BX], '\'
                CALL SEARCH
                POP BX
                MOV BYTE PTR [BX], 0
                ;'()'
                MOV CX, 21
                SUB CURRENT_PTR, CX
                MOV SI, CURRENT_PTR  ; ＤＴＡを復帰
                MOV DI, OFFSET DTA
                REP MOVSB
            NotDir:    ; 次のディレクトリを検索
                MOV AH, 4FH
        JMP SHORT NextDir
;----------------------------------------------------------------------------
Conv_DX_AX PROC
    MOV SI, OFFSET FORMAT
    PUSH SI
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 0CA00H
    SBB DX, 3B9AH
JNC @B
    ADD AX, 0CA00H
    ADC DX, 3B9AH
    MOV [SI], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 0E100H
    SBB DX, 5F5H
JNC @B
    ADD AX, 0E100H
    ADC DX, 5F5H
    MOV [SI+1], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 9680H
    SBB DX, 98H
JNC @B
    ADD AX, 9680H
    ADC DX, 98H
    MOV [SI+2], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 4240H
    SBB DL, 0FH
JNC @B
    ADD AX, 4240H
    ADC DL, 0FH
    MOV [SI+3], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 86A0H
    SBB DL, 1H
JNC @B
    ADD AX, 86A0H
    ADC DL, 1H
    MOV [SI+4], CL
    MOV CL, '0' - 1
    CMP DL, 0
    JE @F
    ADD CL, 6
    ADD AX, 5536
@@: INC CL
    SUB AX, 10000
JNC @B
    ADD AX, 10000
    MOV [SI+5], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 1000
JNC @B
    ADD AX, 1000
    MOV [SI+6], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AX, 100
JNC @B
    ADD AX, 100
    MOV [SI+7], CL
    MOV CL, '0' - 1
@@: INC CL
    SUB AL, 10
JNC @B
    ADD AL, 10
    MOV [SI+8], CL
    ADD AL, '0'
    MOV [SI+9], AL
    MOV CL, 9
@@:    CMP BYTE PTR [SI], '0'
    JNE @F
    MOV BYTE PTR [SI], ' '
    INC SI
LOOP @B
@@: POP SI
RET
Conv_DX_AX ENDP

;----------------------------------------------------------------------------
    EVEN
    CURRENT_PTR DW OFFSET DUMMY_BUFFER
    MSG1 DB 'ファイル $'
    MSG2 DB ' 検索中', 0DH, 0AH, '$'
    FORMAT DB '                -  -     :  :       ', 0DH, 0AH, '$'
    RESULT DB '全部で       個               バイトのファイルがあります。$'
    DTA_BUFFER  DB 'Option: [Drive:][Filename.Type]', 0DH, 0AH, '$'
    TotalCount DW 0
    TotalSize_LOW DW 0
    TotalSize_HIGH DW 0
    PATH DB ' :\', 0
         DB 256 DUP (?)
    FIND DB 260 DUP (?)
    NUMBER DB 200 DUP (?)
    FILE DB 13 DUP (?)
DUMMY_BUFFER:
    ; This is stack area for DTA.
CODE ENDS
    END START
