Metropoli BBS
VIEWER: gmodfile.asm MODE: TEXT (CP437)
                assume          ds:MyData

F_File          = 0
F_Directory     = 1
F_Drive         = 2

DTA_dosuse      = 0
DTA_dosattr     = 15h
DTA_dostime     = 16h
DTA_dosdate     = 18h
DTA_lsize       = 1Ah
DTA_hsize       = 1Ch
DTA_dosname     = 1Eh
DTA_totallength = 1Fh

struc   FStruc
Filename        db      13 dup (?)
TypeOfFile      db      ?
KInFile         dw      ?
ends    FStruc

struc   Psp ; Structure representing DOS's Program Segment Prefix(Psp)
    Int20h              dw  ?   ; Int 20h
    EndOfAllocation dw  ?   ; Segment, end of allocation block
    Reserved1           db  ?   ; Reserved by DOS
    MsDosDispatcher db  5h  dup (?) ; Long call to MS-DOS function
                                        ; dispatcher
    OldTermination      dd  ?   ; Previous contents of termination handler
                                ; interrupt vector(Int 22h)
    OldCtrlCHandler dd  ?   ; Previous contents of CTRL-C interrupt
                                ; vector(Int 23h)
    OldCriticalError    dd  ?   ; Previous contents of critical-error
                                ; interrupt vector(Int 24h)
    Reserved2           db  16h dup (?) ; Reserved by DOS
    EnvironmentBlock    dw  ?           ; Segment address of environment block
    Reserved3           db  2Eh dup (?) ; Reserved by DOS
    Fcb1                db  10h dup (?) ; Default File Control Block(FCB) #1
    Fcb2                db  14h dup (?) ; Default File Control Block(FCB) #2
    CommanDTAil         db  ? ; Command tail and default DTA
ends    ; Psp

; The following record type represents the file attributes field in a
; DOS directory entry.

record  FileAttribType  UnUsed:2, Archive:1, Directory:1, Volume:1, System:1, Hidden:1, ReadOnly:1

struc   DTA ; Structure representing the DOS Data Transfer Area(DTA)
Reserved        db  15h dup (?)     ; Used by Find Next function
FileAttribute   FileAttribType  <>  ; Attribute of file that was found
    ;         BIT       Meaning
    ; 7 6 5 4 3 2 1 0
    ;               1   Read only
    ;             1     Hidden
    ;           1       System
    ;         1         Volume label
    ;       1           Subdirectory
    ;     1             Archive
    ;   1               Unused
    ; 1                 Unused
Filetime        dw  ?               ; Time of file modification
Filedate        dw  ?               ; Date of file modification
Filesize        dd  ?               ; File size in bytes
Filename        db  13  dup (?)     ; File name(ASCIIZ string)
ends    ; DTA

proc    DisplayAll
        mov     ax,MyData
        mov     ds,ax
        mov     cx,[TopFile]
        mov     bx,1
	mov	dx,23
        call    DisplayFiles
        ret
endp    DisplayAll

SegS            dd      0
Line1           dw      0
ThisFile        dw      0
proc            DisplayOneFile
                push    ds si es di
                mov     [Word cs:SegS+2],es
                mov     [Word cs:SegS],di
                mov     [Word cs:Line1],bx
                mov     [Word cs:ThisFile],cx
                mov     ax,MyData
                mov     ds,ax
                mov     ax,[cs:Screen]
                mov     es,ax
                mov     ax,160
                mul     bx
                mov     di,ax
                add     di,56*2
;                inc     di
;                inc     di
                push    cx
                mov     cx,22
@@WriteBackLoop:mov     ax,[es:di]
                and     ah,00001111b
                stosw
                loop    @@WriteBackLoop
                pop     cx

                lds     si,[cs:SegS]
                mov     ax,size FStruc
                mul     cx
                add     si,ax
                cmp     [Byte si+FStruc.TypeOfFile],F_Directory
                jz      @@JustWriteTheDirectory
                mov     ax,seg MKLine
                mov     es,ax
                mov     di,offset MKLine
                mov     cx,8
                push    ds si
@@CopyNameLoop: lodsb
                cmp     al,0
                jz      @@FoundPeriod
                cmp     al,'.'
                jz      @@FoundPeriod
                stosb
                loop    @@CopyNameLoop
                inc     si
@@FoundPeriod:  mov     al,0
                stosb
                mov     cx,3
                mov     di,offset Ext
                cmp     [Byte si],0
                jz      @@ZeroAtExt
@@CopyExtLoop:  lodsb
                cmp     al,0
                jz      @@ZeroAtExt
                stosb
                loop    @@CopyExtLoop
@@ZeroAtExt:    mov     al,0
                stosb
                mov     dx,[cs:Line1]
                mov     bx,56
                mov     cx,seg MKLine
                mov     si,offset MKLine
                mov     ax,8
                mov     di,200Ah
                call    WriteChars
                mov     dx,[cs:Line1]
                mov     bx,65
                mov     cx,seg Ext
                mov     si,offset Ext
                mov     ax,3
                mov     di,200Ah
                call    WriteChars
                pop     si ds
                mov     bx,[Word si+FStruc.KInFile]
                mov     ax,bx
                mov     dx,3
                mov     cx,seg kline2
                mov     di,offset kline2+1
                call    ConvertKToStr
                mov     bx,74
                mov     dx,[cs:Line1]
                mov     cx,seg kline2
                mov     si,offset kline2
                call    Write
                jmp     @@AlmostDone
@@JustWriteTheDirectory:
                mov     dx,[cs:Line1]
                mov     bx,56
                mov     cx,ds
                mov     ax,8
                mov     di,2004h
                call    WriteChars
                mov     bx,65
                mov     dx,[cs:Line1]
                mov     cx,seg ExtBlank
                mov     si,offset ExtBlank
                call    Write
                mov     bx,74
                mov     dx,[cs:Line1]
                mov     cx,seg ExtBlank
                mov     si,offset ExtBlank
                call    Write
@@AlmostDone:   mov     ax,MyData
                mov     ds,ax
                mov     ax,[ThisFile]
                cmp     ax,[CurFile]
                jnz     @@End

                mov     ax,[Screen]
                mov     es,ax
                mov     ax,160
                mul     [cs:Line1]
                mov     di,ax
;                add     di,2
                add     di,56*2
                mov     cx,22
@@WriteLoop:    mov     ax,[es:di]
                or      ah,01010000b
                stosw
                loop    @@WriteLoop
@@End:          pop     di es si ds
                ret
endp            DisplayOneFile

; cx - Start
; bx - Startline
; dx - NumLines
proc            DisplayFiles
                push    ds si es di
                les     di,[FileSeg]
                add     dx,bx
@@DisplayFileLoop:
                cmp     cx,[NumFiles]
                jge     @@ClearRest
                push    bx cx dx
                call    DisplayOneFile
                pop     dx cx bx
@@DoIt:         inc     cx
                inc     bx
                cmp     bx,dx
                jnz     @@DisplayFileLoop
                jmp     @@Done
@@ClearRest:    push    bx cx dx
                mov     ax,[cs:Screen]
                mov     es,ax
                mov     ax,160
                mul     bx
                mov     di,ax
                add     di,56*2
;                inc     di
;                inc     di
                mov     cx,22
@@WriteBackLoop:mov     [Word es:di],0
                add     di,2
                loop    @@WriteBackLoop
                pop     dx cx bx
                jmp     @@DoIt
@@Done:         pop     di es si ds
                ret
endp            DisplayFiles

; ax - Type Of File
proc            CopyFilename
                push    ds si es di
                mov     dx,seg NewDTA
                mov     ds,dx
                mov     si,offset NewDTA
                mov     [Byte es:di+FStruc.TypeOfFile],al
                add     si,(offset (DTA).Filename)
                mov     cx,13
                rep     movsb
                pop     di es si ds
                ret
endp            CopyFilename

proc            CleanFileSegment
                les     di,[FileSeg]
                xor     dx,dx
                mov     ax,size FStruc
                mov     bx,[MaxFiles]
                mul     bx
                mov     cx,ax
                shr     cx,1
                xor     ax,ax
                rep     stosw
                xor     di,di
                ret
endp            CleanFileSegment

proc            GetDrives
                push    es di
                mov     ax,seg DriveList
                mov     es,ax
                mov     di,offset DriveList
                mov     bx,1
@@LoopDrives:   mov     [Byte es:di],0
                mov     ax,4409h
                int     21h
                jb      @@BottomLoop
                mov     [Byte es:di],1
@@BottomLoop:   inc     di
                inc     bx
                cmp     bx,26
                jnz     @@LoopDrives
                pop     di es
                ret
endp            GetDrives

proc            GetDirs
                push    ds si
                mov     ax,seg WildDir
                mov     ds,ax
                mov     dx,offset WildDir
@@DirSearch:    mov     ah,4Eh
                mov     cx,3Fh
                int     21h
                jb      @@End
@@Internal:     mov     al,[Byte offset NewDTA+(offset (DTA).FileAttribute)]
                test    al,10h          ; Is the file a directory
                jz      @@SkipIt        ; Nope
                mov     ax,F_Directory
                call    CopyFilename
                inc     [Word NumFiles]
                mov     ax,[NumFiles]
                cmp     [MaxFiles],ax
                jz      @@End
                add     di,size FStruc
@@SkipIt:       mov     ah,4Fh
                int     21h
                jnb     @@Internal
@@End:          pop     si ds
                ret
endp            GetDirs

proc            GetInfoOnMOD
                push    ds si es di
                mov     ax,seg NewDTA
                mov     ds,ax
                mov     si,offset NewDTA
                mov     ax,F_File
                call    CopyFilename

                mov     ax,[Word offset NewDTA+(offset (DTA).Filesize)+1]
                shr     ax,2
                mov     [Word es:di+(offset(FStruc).KInFile)],ax
                pop     di es si ds
                ret
endp            GetInfoOnMOD

proc            GetModules
                push    ds si
                mov     ax,[MaxFiles]
                cmp     [NumFiles],ax
                jz      @@End
                mov     ax,seg WildMod
                mov     ds,ax
                mov     dx,offset WildMod
@@DirSearch:    mov     ah,4Eh
                mov     cx,3h
                int     21h
                jb      @@End
@@Internal:     call    GetInfoOnMOD
                inc     [Word NumFiles]
                mov     ax,[NumFiles]
                cmp     [MaxFiles],ax
                jz      @@End
                add     di,size FStruc
                mov     ah,4Fh
                int     21h
                jnb     @@Internal
@@End:          pop     si ds
                ret
endp            GetModules

proc            ReadFiles
                push    es di
                mov     ax,MyData
                mov     ds,ax
                mov     [Word NumFiles],0
                mov     [Word CurFile],0
                mov     [Word TopFile],0
                mov     ah,1Ah
                mov     dx,offset NewDTA
                int     21h
                push    ds
                mov     ax,seg CurPath
                mov     ds,ax
                mov     si,offset CurPath
                mov     ah,47h
                mov     dl,0
                int     21h
                pop     ds
                mov     ah,19h
                int     21h
                add     al,'A'
                mov     [DriveLetter],al

                call    CleanFileSegment
                call    GetDrives
                call    GetDirs
                call    GetModules
                mov     ax,[MaxFiles]
                cmp     [NumFiles],ax
                jnz     @@End
;        call    TooManyFiles
@@End:          call    SortFiles
                pop     di es
                ret
endp            ReadFiles

proc            SortFiles
                push    ds si es di bp
                les     di,[FileSeg]
                mov     si,di
                add     di,size FStruc
                mov     cx,[NumFiles]
                or      cx,cx
                jz      @@End
                mov     cx,0
                mov     dx,size FStruc
                mov     bx,0
@@TopLoop:      push    cx bp
                mov     bp,0
                ; ──── Compare
                mov     al,[es:bp+si+FStruc.TypeOfFile]
                cmp     al,[es:bp+di+FStruc.TypeOfFile]
                jnz     @@NewRecord

                mov     cx,8
@@ByteByByte:   mov     al,[es:bp+si]
                mov     ah,[es:bp+di]
                inc     bp
                cmp     al,ah
                jnz     @@DoneCompare
                cmp     al,0
                jnz     @@CheckOther
                clc
                jmp     @@DoneCompare
@@CheckOther:   cmp     ah,0
                jnz     @@ByteByByte
                stc
@@DoneCompare:  jb      @@NewRecord

@@SwapThem:     mov     bx,1
                mov     bp,0
                mov     cx,dx
@@SwapLoop:     mov     al,[es:bp+si]
                mov     ah,[es:bp+di]
                mov     [es:bp+di],al
                mov     [es:bp+si],ah
                inc     bp
                loop    @@SwapLoop

@@NewRecord:    pop     bp cx
                inc     cx
                mov     ax,[NumFiles]
                dec     ax
                cmp     cx,ax
                jz      @@FixThem
                add     si,dx
                add     di,dx
                jmp     @@TopLoop
@@FixThem:      cmp     bx,0
                jz      @@End
                les     di,[FileSeg]
                mov     si,di
                add     di,dx
                mov     bx,0
                mov     cx,0
                jmp     @@TopLoop
@@End:          pop     bp di es si ds
                ret
endp    SortFiles


[ RETURN TO DIRECTORY ]