On Wed, 13 Feb 2019 16:27:55 GMT, "Kerr-Mudd,John"
<
nots...@invalid.org> wrote:
> Here's an old program from the 90's? I've recently rewritten for size;
> Original masm code (nice and modular!) Public Domain, if anyone wants
[old code snipped]; com file 872 bytes
and here's the improved 445 byte version:
comments welcome!
(Note followup set to just clax)
; get file info [445] works!
; added commas to size
;; revert to parsing opts for each file
;; re-added 'file not found' msg
; @@@extend to give dir list & allow DC cmds
;cpu 286
cpu 8086
parm_dlm equ '/'
date_dlm equ '-'
time_dlm equ ':'
PSP equ 0x0080
org 0x100
; stdequ
cr equ 0x0D
lf equ 0x0A
eos equ '$'
blank equ 0x20
tab equ 0x09
;DOS fns:
set_dta equ 0x1A
prtstr equ 0x09
exitrc equ 0x4C
fget_first equ 0x4E
fget_next equ 0x4F
%macro dos 1
mov ah,%1
int 0x21
%endm
;------------------------------------------------
Start:
mov dx,DTA
dos set_dta ; set area for info
mov bx,allfiles ; posit no filespec
mov si,asczb ; posit no opts
;; check parms
xor cx,cx
mov di,PSP
mov cl,byte [di]
jcxz just_do_it ; default to just listing all
inc di ; avoid initial space
inc cx ; include cr
add_fn:
mov dx,bx ; pt dx at fn
find_again:
;; mkascz, rtn bx->asczstr,[di]=0
mov al,blank
repz scasb ; skip leading spaces
jcxz just_do_it ; end ofpsp
dec di ; 1st nonblank
inc cx
mov bx,di
repnz scasb ; find end
;; found or EoI
mov byte [di-1],0 ; end word with ascz
cmp byte [bx],parm_dlm ; opts?
jne add_fn
at_dlm: ;; any parms?
mov si,bx ; pt si at opts
inc si ; past /
cmp byte [si],'?' ; was it /?
jne find_again
; je usage
;usage:
mov dx,usaje
msgexit:
dos prtstr
exitwrc:
dos exitrc ; EOprog
just_do_it:
dos fget_first
mov dx,badfn
jc msgexit ; no files match/error
next_file:
push si ; keep si at opts
mov di,OBuff
push di ; dx for print later
push si ; keep si at opts
call print_fn ; must call to allow fallthru
;print_info:
next_opt: ; jmps to prt_etc come back here
mov al,blank ; space between entries
stosb
gn_opt:
pop si
lodsb ; opts
and al,0xFF-0x20 ; ucase
jz end_opts ; space or 0 ends
push si ; all rtns to next_opt
cmp al,'D'
je prt_date
cmp al,'T'
je prt_time
cmp al,'S'
je prt_size
cmp al,'A' ; lookup table costs more
; je prt_attr
jne gn_opt ; nonvalid
prt_attr: ; [18] +2
mov cl,lattrs
mov si,attrltrs
; mov ah,byte [file_attr] ; [4]
mov ax,word [file_attr-1] ; [3]
next_bit:
lodsb
shr ah,1
jc attr_on
mov al,blank
attr_on:
stosb
loop next_bit
jmp next_opt
end_opts: ; all opts dealt with
mov si,endline
movsw ; crlf
movsb ; eos
pop dx ; mov dx,OBuff
dos prtstr ; Print line
pop si ; opts
dos fget_next
jnc next_file
; - tot files, size? no regs left
; prtstr done_all
; jmp exitwrc
ret ; EOprog
prt_date:
mov si,date_parms
mov bl,date_dlm
mov ax,word [file_date]
prt_cent:
push ax ; save raw date/time
;; y2k century special code (max 2099)
mov cl,9
shr ax,cl ; shift
mov dx,'20' ; default to 21st cent
sub al,20d
jnc is21th_cent
mov dx,'19'
add al,100d ; 1980<=ccyy<2000
is21th_cent:
mov word [di],dx
scasw ; inc di past century
no_cent:
call prt_2_dec
jmp prt_rest
prt_time:
mov si,time_parms
mov bl,time_dlm
mov ax,word [file_time]
push ax ; save raw date/time
call prt_nn
; fallthru
prt_rest:
pop ax ; restore base date/time num
call prt_dlm_nn_dlm_nn
jmp next_opt
prt_size:
;putnum8: ;[x28=40] big prt +ve bp:ax 4G max; with commas
mov cl,13 ; 4,000,000,000 chrs max
call nblanks ; [3] ; moves di to end
mov ax,word [file_size] ; low size [3]
mov bp,word [file_size+2] ; high size [4]
xor bx,bx ; -ve count
prt_num8:
mov cl,0x0A ; base 10
adddig8:
dec bx ; next prt posn
push bx
and bl,3 ; F4,F8,FC,[00]
pop bx
jnz nocomma8 ; every 4
mov byte [di+bx],',' ; comma every 4 decs
dec bx
nocomma8:
xor dx,dx
xchg ax,bp ; high part
div cx
xchg ax,bp ; store/high restored low
div cx ; using dx as rmdr from 1st
or dl,'0'
mov byte [di+bx],dl
or ax,ax
jnz adddig8
jmp next_opt
;;; called rtns ------------------------------------
print_fn:
mov si,file_name
mov cl,8 ; fnlth (inc .)
call MovDotZstrThenPad ; fn
mov cl,3 ; extn
; fallthru for extn
MovDotZstrThenPad:
lodsb ; [11]
prt2dot:
stosb ; at least 1 char
lodsb
cmp al,'.' ; until '.'
je endmov
or al,al ; or ascz
loopnz prt2dot ; cx chrs max
endmov: ; fallthru to pad rmdr
nblanks:
mov al,blank
repnz stosb
ret
prt_dlm_nn_dlm_nn:
push ax ; save raw date/time
call prt_dlm_nn
pop ax
; fallthru for 2nd @nn
prt_dlm_nn:
mov byte [di],bl ; prt dlm
inc di
; fallthru for nn
prt_nn:
; mov cx,word [si] & si++ [4]
xchg ax,cx ; store raw d/t
lodsw
xchg ax,cx ; load s&m [3]
shr ax,cl ; shift
and al,ch ; & mask
xor cx,cx ; need ch=0 later?
; fallthru for prt
prt_2_dec: ; <=99 in al [9]
;; reuse prt from size?? [8]
; xor bp,bp
; mov cl,2
; inline prt_num ;
; ret
;; but must add these to prt_size:
; call prt_num ; noret fail!
aam 10 ; split digits
xchg ah,al
or ax,0x3030
stosw ; nn
ret
;data -----------------------------------------
date_parms: ; cent/yr in code
; db 9 ; dys ;15-09 Year
;;(0 = 1980, 119 = 2099 DOS/Windows)
; db 001111111b ; dym 128
db 5 ; dms ;08-05 Month (1–12)
db 000001111b ; dmm 16
db 0 ; dds ;04-00 Day (1–31)
db 000011111b ; ddm 32
time_parms:
db 11 ; ths ;15-11 Hours (0-23)
db 000011111b ; thm 32
db 5 ; tms ;10-05 Minutes (0-59)
db 000111111b ; tmm 64
db 0 ; tss ;04-00 Seconds/2 (0-29)
db 000011111b ; tsm 32
allfiles db '*.*' ; asczb must be next
asczb db 0
OBuff equ $ ; make sure it's long enough to avoid data
badfn db 'File not found: - '
usaje db 'Usage is:'
db '"QFILE filespec [',parm_dlm,'{D|T|S|A}]"',cr,lf ;,lf
db tab,'{D}ate CCYY',date_dlm,'MM',date_dlm,'DD',cr,lf
db tab,'{T}ime HH',time_dlm,'MM',time_dlm,'SS',cr,lf
db tab,'{S}ize in bytes',cr,lf
db tab,'{A}ttr '
;; data & part of help info
attrltrs db 'RHSVDA'
lattrs equ $-attrltrs
endline db cr,lf
db eos
;SECTION DATA
DTA equ $
file_attr equ $+21
file_time equ $+22
file_date equ $+24
file_size equ $+26
file_name equ $+30