; From Anthony Williams
; Color file lister, approximately 600 bytes.
; I can't believe I finally got it working!
; If you steal this code, you must buy "Van Halen The Best of: Volume I"
; anthony.williams@bytebbs.com

Print_color macro variable
LOCAL Label1               ; declare local label
  mov ah,9               ; int 10h,func 9
  xor bh,bh               ; page zero
  mov bl,1Bh               ; cyan on dark blue
  mov cx,1               ; print one character
  mov si,offset variable         ; location of our string
Label1:
  lodsb                  ; DS:SI -> AL
  push cx               ; save certain registers
  push bx
  push ax
  mov ah,3               ; get cursor info
  xor bh,bh               ; page zero
  int 10h
  inc dl               ; increase column number
  dec ah               ; set cursor info
  int 10h
  pop ax               ; restore certain registers
  pop bx
  pop cx
  int 10h
  cmp byte ptr [si],'$'            ; for compatibility w/int 21h,9
  jne short Label1            ; go back if not equal
endm

get_cursor macro number            ; justifies everything
push dx                  ; save stuff
push bx
push ax
mov ah,3               ; get cursor info
xor bh,bh               ; page zero
int 10h
mov dl,number               ; screen location to go to
mov ah,2               ; set cursor info
int 10h
pop ax                  ; restore stuff
pop bx
pop dx
endm

Linefeed macro               ; this could be optimized
push dx
push ax
mov ah,2
mov dl,13
int 21h
mov dl,10
int 21h
pop ax
pop dx
endm

CODE_SEG segment public 'CODE'
ASSUME CS:CODE_SEG,DS:CODE_SEG,ES:CODE_SEG   ; make CS=DS=ES
org 100h               ; .COM file

Start:
                mov si,81h         ; check for parameters
                cmp byte ptr [si],13      ; carriage return?
                je No_params
                inc si            ; check some more
                mov di,offset path      ; parse cmdline for filespec
                cld            ; clear direction flag
Parse:
                movsb            ; DS:SI -> ES:DI
                cmp byte ptr [si],13      ; carriage return?
                loopne Parse         ; go back if not
                mov byte ptr [di],0      ; add a null
                jmp short Set_DTA

No_params:
                mov si,offset all
                mov di,offset path
                cld
All_files:
                movsb            ; make filespec = "*.*"
                cmp byte ptr [si],00      ; where's the null?
                loopne All_files

Set_DTA:               ; set Disk Transfer Address
                Linefeed
                mov ah,1Ah         ; int 21h,func 1Ah
                mov dx,offset dta      ; location of our DTA
                int 21h

Find_first:
                mov ah,4Eh         ; int 21h,func 4Eh
                mov cx,0FFFFh         ; find everything!
                mov dx,offset path      ; path
                int 21h

Loading:
                cld            ; clear direction flag again
                mov si,offset dta+1Eh      ; location of ASCIIZ filename
                mov di,offset buffer      ; a buffer is more efficient
                cmp byte ptr [si],00
                je Not_found
Insert:
                movsb            ; move the name into buffer
                cmp byte ptr [si],00      ; stop when reach a zero
                loopne Insert         ; keep going
                mov byte ptr [di],20h      ; here's a space
                inc di
                mov byte ptr [di],'$'      ; this was before I added color
                inc si            ; I -had- used int 21h,func 9
                jmp short Print

Find_next:
                mov ah,4Fh         ; find next file
                mov cx,0FFFFh         ; look for it all!
                mov dx,offset path      ; DX = filespec
                int 21h
                jb Finished
                jmp Loading

Print:
                add Flag,1
                Print_color buffer      ; finally, PRINT!
Output:
                cmp Flag,1
                je Cursor1
                cmp Flag,2
                je Cursor2
                cmp Flag,3         ; This needs an optimization!
                je Cursor3

Go_on:
                xor dl,dl
                mov di,offset buffer
Clear:
                mov byte ptr [di],dl
                cmp byte ptr [di],00
                inc di
                loopne Clear
                jmp Find_next

Not_found:
                mov ah,9         ; errors should always be
                mov dx,offset No_found      ; printed in black and white!
                int 21h            ; color is for stuff that works

Finished:
                Linefeed
                mov ah,4Ch         ; quit everything, close all
                int 21h

Cursor1:
                get_cursor 20         ; go to column 20
                jmp Go_on

Cursor2:
                get_cursor 40         ; column 40
                jmp Go_on

Cursor3:
                get_cursor 60         ; column 60
                mov Flag,0
                Linefeed
                jmp Go_on

Flag db 0               ; data here to save that
all db '*.*',0               ; extra byte (jumping over data)
path db 15 dup(0)
dta db 128h dup(0)
buffer db 30 dup(0)
No_found db 'File(s) not found.$'

CODE_SEG ends               ; end everything, goodbye!
end Start


