-
Notifications
You must be signed in to change notification settings - Fork 3
/
LDIR41.ASM
1355 lines (1126 loc) · 28.9 KB
/
LDIR41.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
page 74,132
title --- ldir - list directory -
; LDIR (c) Copyright Vernon D. Buerg 1985-1989
; ALL RIGHTS RESERVED.
dtantry struc ; DTA entry returned by DOS
dtarsvd db 21 dup (0) ; reserved
dtaattr db 0 ; attribute
dtatime dw 0 ; update time
dtadate dw 0 ; update date
dtasize dw 0,0 ; size bytes (lo,hi)
dtaname db 12 dup (' ') ; name and ext
db 0,13,10,255 ; stopper and print
dtantry ends
argntry struc ; Search arguments
argdriv db 0,':' ; drive
argpath db '\' ; path delimiter
argname db 64 dup (0),255 ; path,file,ext
argntry ends
tblntry struc ; Table Entries
tblattr db 0 ; attribute
tblpath db 21 dup (0) ; path name(s)
tblname db 8 dup (' ') ; file name
tbldot db ' ' ; delimiter
tblext db 3 dup (' ') ; extension
tblsize db ' 0000000 ' ; File size
tbldate db '80-01/01 ' ; Date
tbltime db ' 0:00 ' ; Time
tblfatr db 3 dup (' ') ; File attributes
tblctl db 13,10,255 ; print control chars
tblntry ends
filntry struc ; List of files in table
filsub db 0 ; -index to subdirectory name
filattr db 0 ; -file attributes
filtime dw 0 ; -time stamp
fildate dw 0 ; -date stamp
filsize dw 0,0 ; -file size
filname db 12 dup ('?') ; -asciiz file name
filstop db ? ; -asciiz stopper
filntry ends
bios segment at 40h ; dos data area
org 84h ;
ega_row label byte ; rows on screen
bios ends
save macro reglist
irp reg, <reglist>
push reg ; save register
endm
endm
return macro reglist
irp reg, <reglist>
pop reg ; restore register
endm
ret ; return to caller
endm
cseg segment public para 'CODE'
assume cs:cseg, ds:cseg, es:nothing
org 100h
ldir proc far
mov sp,offset local_stack_end ; Use local stack
mov word ptr stackx,sp ; Save stack ptr for exiting
jmp start
page
;
; Data Areas, Constants, Etc.
dta_len equ size dtantry ; DTA length
arg_len equ size argntry ; Argument length
tbl_len equ size tblntry ; Disk record entry
fil_len equ size filntry ; File description entry
tblpara equ tbl_len/16 ; paragraphs in each table entry
depth equ 3 ; Maximum sub-DIR nest level
tab equ 9 ; A tabbie
lf equ 10 ; Line feed
cr equ 13 ; Carriage return
stopper equ 255 ; Ends print strings
curdsk equ 19h ;Get current disk
setdta equ 1ah ;Set data transfer area
dskspc equ 36h ;Get disk free space
chdir equ 3bh ;Change directory
write equ 40h ;Write to a file handle
getpath equ 47h ;Get current directory
stackx dw 0 ; Entry stack pointer
dirmask db 0 ; Directory flags mask
errlvl db 0 ; DOS return code
_attr db 7 ; Clear attribute
_page db 0 ; Video page
_rows db 0 ; Rows on screen
flags db byname ; Command switches
byattr equ 1 ; -attributes included
byhide equ 2 ; -want hidden files
byclear equ 4 ; -clear screen
bydate equ 8 ; -sort by date/time
byext equ 10h ; -sort by extension
byname equ 40h ; -sort by name
bysize equ 80h ; -sort by size
flags2 db 0 ; More switches
bymod equ 01h ; -modified files only
bywait equ 02h ; -wait when screen full
bybrief equ 4 ; -four up
bypath equ 20h ; -all paths
date record yr:7,mo:4,dy:5 ; Packed date
time record hour:5,min:6,sec:5 ; Packed time
anyname db '\????????.???',0,stopper ;Global filename.ext
subdir db '-Dir'
count dw 0 ; Number of files
numdir dw 0 ; Number of table entries
maxdir dw 0 ; Maximum table entries
nxtdir dw 0 ; Offset to next entry
segdir dw 0 ; Segment addr of of gotten table
numbyte dw 0,0 ;Total bytes used
linecnt db 0 ;Line counter for /W
ddptr dw 0
page
;
; Headings and titles
titlea db 'List DIRectory Volume: '
volname db 11 dup (' '),11 dup (' ')
month db 'mm/'
day db 'dd/'
year db 'yy '
hours db 'hh:'
mins db 'mm:'
secs db 'ss',cr,lf,stopper
more db '... more',stopper
backsp db 8 dup (8),stopper ; backspace over 'more'
titleb db tab,tab,tab,tab,' ' ;Command parameters
titles db 64 dup (0),stopper ;Current directory
titlec db cr,lf,'Filename Ext Bytes -Last Change- '
titled db 'Filename Ext Bytes -Last Change-'
newline db lf,cr,stopper
nrmsg db cr,cr,2 dup (' ') ;Ending message
nrbytes db ' 0 bytes in'
nrfiles db ' 0 File(s); '
nrsize db ' 0 bytes free.',stopper
extfcb db 255,0,0,0,0,0 ; Extended FCB to get label
db 8 ; Attribute
drivenr db 0,11 dup('?') ; Drive number
db 2 dup(0) ; Current block number
db 3 dup(0) ; Logical record size
db 20 dup(0) ; File size
temp db 0 ; Sort exchange area
origdr db 'x:' ; Original drive
origdir db '\',63 dup (0) ; and path
origptr dw origdir ; End of orig path name
rootdir db 'x:\',0 ; To get vol label
olddate db 8 dup (0) ;
drptr dw offset parmdr ;
model tblntry <> ; Model print line
page
;
; Set default drive and path
start:
mov ah,8 ; Get monitor stuff
int 10h ;
mov _page,0 ; -video page
mov _attr,ah ; -current attribute
push es ; set dos data area
mov ax,bios ; segment address
mov es,ax ;
mov al,byte ptr es:ega_row ; dos rows on screen
mov ah,24 ; default max rows
or al,al ; is row value ok?
jz start1 ; no, use default
mov ah,al ; yes,
start1: sub ah,2 ; compensate for heading
mov byte ptr _rows,ah ; set max rows on screen
pop es ;
call switchs ; Get program options
mov ah,13 ; Reset diskettes
int 21h ;
mov ah,curdsk ; Get current disk
int 21h ;
add al,'A' ;
mov origdr,al ; Save original drive letter
mov rootdir,al ; for reading vol label
mov parmdr,al ;
mov dx,offset dta ; Set Data Transfer Area
mov ah,setdta ;
int 21h ;
call getparm ; Get desired dr:path in 'parmdir'
call getvol ; Get vol name, current dir in 'origdir'
call setarg ; Set search argument
call alloc ; Allocate table for directory
call clock ; Date/time to heading
call getdir ; Read the directory
test flags,255 ; Any sort options?
jz nosort ; no, display fifo dir
call sort ; Sort directory table
nosort:
call print ; Display the entries
mov ax,count ; Number of files
sub dx,dx ;
mov si,offset nrfiles ;
call format ;
mov dx,numbyte ; Total bytes used
mov ax,numbyte+2 ;
mov si,offset nrbytes ;
call format ;
mov dx,offset nrmsg ; Display summary stats
exit: mov sp,cs:stackx ; Insure exiting stack
call prints ; Display final message
done: mov sp,cs:stackx ; Insure exiting stack
mov al,errlvl ; Return to system
mov ah,4ch ; via EXIT with error level
int 21h ;
ldir endp
page
;
; Set options from command line
switchs proc near
mov si,82h ; Command tail
mov dh,flags ; Default switches
mov dl,flags2
sub cx,cx
or cl,byte ptr -2[si] ; test parm length
jz switch_exit ; none, return as-is
sw1: lodsb ; Scan for switch
cmp al,'/'
loopne sw1
or cx,cx ; found one?
jz switch_exit
mov byte ptr -1[si],cr ; Stop string here
jmp short sw2a
switch_exit:
mov flags,dh ; Store new switches
mov flags2,dl
mov al,dirmask ; Current directory attribute mask
test flags,byhide ; include hidden files
jz swx1
or al,2
swx1: test flags,byattr ; include display of attributes?
jz swx2
or al,7
swx2: test flags2,bypath ; include sub-directories?
jz swx3
or al,16
swx3: mov byte ptr dirmask,al ; Update dir search criteria
ret
sw2: lodsb
cmp al,'/' ; Another switch?
loopne sw2
jcxz switch_exit
sw2a: lodsb ; yes, get letter following
dec cx
jle sw3 ; missing switch
sw3: cmp al,'?' ; Help?
jne sw4
mov dx,offset help
jmp exit
sw4: and al,0dfh ; Make option uppercase
cmp al,'A' ; Attributes?
jne sw5
or dh,byattr
sw5: cmp al,'B' ; Brief?
jne sw6
or dl,bybrief
sw6: cmp al,'C' ; Clear?
jne sw7
or dh,byclear
call cls
sw7: cmp al,'D' ; Date?
jne sw8
or dh,bydate
sw8: cmp al,'X' ; Ext?
jne sw9
or dh,byext
sw9: cmp al,'P' ; Paths?
jne sw10
or dl,bypath
sw10: cmp al,'S' ; Size?
jne sw11
or dh,bysize
sw11: cmp al,'H' ; Hidden?
jne sw12
or dh,byhide
sw12: cmp al,'M' ; Modified only
jne sw12b
or dl,bymod
sw12b: cmp al,'W' ; Wait when screen fills?
jne sw12c
or dl,bywait
sw12c: cmp al,'F' ; Sort by filename?
jne sw12d
or dh,byname
sw12d: cmp al,'N' ; No sorting?
jne sw13
and dh,0ffh-byname-byext-bysize-bydate
sw13: jmp sw2 ; Try for another option
switchs endp
page
;
; Copy command parameters
getparm proc near
mov si,82h ; Command tail
mov di,offset parmdir ; goes after d:\
sub cx,cx ;
or cl,byte ptr -2[si] ; any parmeters?
jz parm9 ; no, use defaults
parm0: cmp byte ptr 1[si],':' ; Drive specified?
jne parm1 ; no
mov di,offset parmdr ; yes, replace drive letter
parm1: lodsb ; Skip leading blanks
cmp al,' ' ;
jne parm3 ;
loope parm1 ;
jcxz parm9 ;
parm2: lodsb ; Copy d:\path\fname.ext
parm3: cmp al,cr ; end of string?
je parm9 ;
cmp al,' ' ; end of operand?
jbe parm9 ;
cmp al,',' ;
je parm9 ;
stosb ;
loop parm2 ;
parm9: and parmdr,0dfh ; Upper case drive parm
mov drptr,di ; Save ptr to parm end
mov al,0 ; Insure asciiz
stosb ;
mov al,parmdr ;
mov origdr,al ;
mov rootdir,al ;
ret ;
getparm endp
page
;
; Get volume label and disk free space
getvol proc near
mov dl,parmdr ; Get drive letter
sub dl,64 ; and make it a number
mov drivenr,dl ;
mov si,offset origdir+1 ; Save current path name
mov ah,getpath ;
int 21h ;
mov al,0 ; Get end of path name
mov di,offset origdir ;
mov cx,67 ;
repne scasb ;
sub di,2 ;
mov origptr,di ;
cmp origdir+1,0 ; Already in root?
je getvl3 ; yes, no chdir needed
inc origptr ;
mov dx,offset rootdir ; no, point to root directory
mov ah,chdir ;
int 21h ;
jc getvl9 ;
getvl3: mov dx,offset extfcb ; Search for volume entry
mov ah,11h ;
int 21h ;
or al,al ; Any found?
jnz getvl4 ; no, tough
mov cx,11 ; yes, copy it to heading
mov si,offset dta+8 ;
mov di,offset volname ;
repz movsb ;
getvl4: cmp origdir+1,0 ; Need to restore curdir?
je getvl9 ;
mov dx,offset origdr ; Back to current dir
mov ah,chdir ;
int 21h ;
getvl9: ; Get disk free space
mov dl,parmdr ; Current drive letter
sub dl,64 ; as a number
mov ah,dskspc ; Get free space
int 21h ;
cmp ax,0ffffh ; Valid?
je getvl10 ; no, skip it
mul cx ; Bytes per cluster
mul bx ; Total free
mov si,offset nrsize ; Point to msg
call format ;
getvl10:
ret ;
getvol endp ;
page
;
; Set search criteria
setarg proc near
set1: mov bp,offset dta ; First DTA
mov bx,offset search ; Search arument entries
mov ax,word ptr parmdr ; Set search drive
lea di,[bx].argdriv ;
stosw ;
; parameter is possibly a filespec
set2: cmp byte ptr parmdir,'\' ; path requested?
je set8 ; yes, more than a filespec
mov cx,origptr ; no, set search path
mov si,offset origdr+2 ; from original path
sub cx,si ;
jcxz set2a ; In a subdir?
rep movsb ;
mov al,'\' ; Add filespec delimiter
stosb ;
set2a: mov si,offset parmdir ; Copy filespec
mov cx,drptr ; to search criteria
sub cx,si ;
jcxz set5 ; None, append global filespec
rep movsb ;
jmp set7 ; Done
; parameter is possibly a path\filespec
set8: mov dx,offset parmdr ; Requested d:\path\filespec
mov ah,chdir ;
int 21h ; Is parm a valid path name?
jc set4 ; no, have d:\path\filespec
set8a: mov dx,offset origdr ; Restore path
mov ah,chdir ;
int 21h ;
mov si,offset parmdir ; Set search d:\path
mov cx,drptr ; from command parameter
sub cx,si ;
jcxz set5 ;
rep movsb ;
jmp set5 ; Append global filespec
set4: mov si,offset parmdir ; Set search d:\path
mov cx,drptr ; from command parameter
sub cx,si ;
set4a: jcxz set5 ;
rep movsb ;
jmp set7 ; Done
; append global filespec to search criteria
set5: mov si,offset anyname ; Add global search arg
cmp byte ptr -1[di],'\' ; Already have delimiter?
jne set6 ;
dec di ; yes, overlay it
set6: mov cx,15 ; Length of global filespec
push di ; Save current end pointer
rep movsb ;
pop di ; Restore work reg
jmp set9 ;
set7: mov al,0 ; Append ASCIIZ stopper
stosb ;
set9: lea si,[bx].argdriv ; Copy d:\path\filespec
mov cx,di ;
sub cx,si ;
mov di,offset titles ; to titles
rep movsb ;
mov byte ptr [di],stopper ; Add print stopper
set10: ret ; Back to caller
setarg endp
page
;
; Obtain directory table
alloc proc near
push bx ; save registers
mov bx,pgmsize ; size of program module
mov ah,4ah ; modify memory
int 21h ;
mov bx,-1 ; ask for all remaining memory
alloc1:
mov ah,48h ; allocate memory
int 21h ;
jc alloc1 ; get what there is
mov segdir,ax ; segment addr of table
mov nxtdir,0 ; offset to first entry
shr bx,1 ; change number of paragraphs
shr bx,1 ; to 64-byte entries
mov maxdir,bx ; maximum table count
pop bx ; restore registers
ret ;
alloc endp
page
;
; Build table of directory entries
getdir proc near
push bp ; Ptr to DTA
push bx ; Ptr to search are
; Set DTA for current nesting level
mov dx,bp ; Data transfer area
mov ah,setdta ; Set local DTA
int 21h
; Set search criteria for this level
mov dx,bx ; Search criteria
sub cx,cx ; Directory options
mov cl,dirmask
mov ah,4eh ; Find first matching entry
int 21h
; Examine directory entry just returned
get1: or al,al
jnz gotdir ; Not found, quit looking.
cmp byte ptr [bp].dtaattr,10h
jne get3 ; Is it a sub-dir?
cmp byte ptr [bp].dtaname,'.'
je get4 ; May be <DIR> entry
call addfile ; Add directory entry to table
; Build parms for sub-dir search
lea dx,[bp].dtaname ; Save ptr to found name
lea si,[bx].argdriv ; Point to current arg
add bp,dta_len ; Next DTA
add bx,arg_len ; Next search arg
; Copy previous arg as next search arg
mov cx,64 ; Maximum length
lea di,[bx].argdriv ; Point to new search arg
get6: lodsb ;
cmp al,'?' ; Used global name?
je get9 ; yes, single nest
cmp al,0 ; End of dir name?
je get5 ; yes, append wild cards
stosb ;
loop get6 ; Continue copying
; Add sub-dir name to search arg
get9: mov si,dx ; Saved ptr to found name
get8: lodsb ;
cmp al,0 ; End of DIR name?
je get5 ; yes, append wild cards
stosb ; no, add to arg
loop get8 ; Continue copying fname
get5: mov si,offset anyname ; Append wild cards
rep movsb ;
call getdir ; Search the sub-dir
sub bx,arg_len ; restore arg
sub bp,dta_len ; and DTA
; Restore DTA to find next matching entry
mov dx,bp ; Data transfer area
mov ah,setdta ; Set DTA
int 21h ;
jmp short get4 ;
get3: call addfile ; Add the entry
get4: mov cx,12 ; Clear found name
mov al,' ' ;
lea di,[bp].dtaname ; Point to file name area
rep stosb ;
mov ah,4fh ; Search for next file
mov dx,bp ;
int 21h ;
jmp get1 ; Loop for next one
gotdir: pop bx ; Restore arg
pop bp ; and DTA
ret ; Return to caller
getdir endp ;
page
;
; Add a directory entry to table
addfile proc near
save <cx,bp,di,si> ; Save registers
mov cx,tbl_len ; Initialize table entry
mov si,offset model ;
mov di,offset pline ;
rep movsb ;
mov al,[bp].dtaattr ; Copy file attributes
mov pline.tblattr,al ;
test flags2,bymod ; Just modified files?
jz addfile1 ; no, add all
test al,10h ; yes, pass subdirs
jnz addfile1 ;
test al,20h ; is it modified tho?
jnz addfile1 ; yes, add the entry
jmp addfile11 ; no, exit
addfile1:
call getdate ; Format date
call gettime ; time
call getsize ; bytes
lea si,[bp].dtaname ; Copy file name
lea di,pline.tblname ;
mov cx,12 ;
addfile2:
lodsb ;
cmp al,0 ;
je addfile5 ;
cmp al,'.' ; separate extension
je addfile3 ;
stosb ;
loop addfile2 ;
addfile3:
jcxz addfile5 ;
lea di,pline.tblname+8 ;
addfile4:
stosb ;
lodsb ;
cmp al,0 ;
je addfile5 ;
loop addfile4 ;
addfile5:
lea di,pline.tblpath ; Copy path name
lea si,[bx].argname ;
mov cx,size tblpath ;
addfile6:
cmp byte ptr 1[si],'?' ; Wildcard part?
je addfile7 ; yes, have name
lodsb ;
stosb ;
loop addfile6 ;
addfile7:
lea si,pline.tblname ;
test pline.tblattr,10h ; Subdirectory?
jnz addfile8 ; yes, copy path name
jcxz addfile10 ; no, pad with blanks
mov al,' ' ;
rep stosb ;
jmp addfile10 ;
addfile8:
cmp cl,12 ; Max subdir name length
jbe addfile9 ; to be copied
mov cl,12 ;
addfile9:
rep movsb ;
addfile10:
mov cx,numdir ; Number of table entries
cmp cx,maxdir ; is table full?
jae addfile11 ; yes, skip it
push es ; no, add to table
mov ax,word ptr segdir ; Segment addr of table
add ax,nxtdir ; plus next entry offset
sub di,di ;
mov si,offset pline ; copy table stuff
mov cx,tbl_len ;
mov es,ax ; Set target segment
rep movsb ;
pop es ;
inc numdir ; Incr entry count
add nxtdir,tblpara ; Bump offset for next table entry
addfile11:
return <si,di,bp,cx> ; restore registers
addfile endp
page
;
; Print file information
print proc near
cmp numdir,1 ; Just one file?
ja printt ; no, two up heading
mov word ptr titled,0a0dh ;
mov titled+2,stopper ;
printt:
mov dx,offset titlea ; Top titles
call prints ;
mov dx,offset titleb ; Subdir name
call prints ;
mov dx,offset titlec ; Headings
call prints ;
mov ax,cs ; Set extra seg
mov es,ax ; locally
sub ax,ax ; Offset to first table entry
mov nxtdir,ax ; as current entry
mov ax,numdir ; Compute offset
inc ax ; to second half
shr ax,1 ;
mov cl,2 ; Times 64 (4 paras each)
shl ax,cl ;
mov cx,numdir ; Number of entries
or cx,cx ; Even number of entries?
jz print7 ; yes, all set
inc cx ; no, just one
shr cx,1 ; Set half of count
print_next:
call print0 ; Left side
push [nxtdir] ;
add nxtdir,ax ;
call print0 ; Right side
pop [nxtdir] ;
add nxtdir,tblpara ; Point to next entry
test flags2,bywait ; Wait for screen full?
jz printw1 ; no, continue
inc linecnt ; yes, bump line count
mov dl,_rows ; rows available on screen
dec dl ; leave room for headings
cmp linecnt,dl ; Full now?
jb printw1 ; no, continue
call waitkey ; yes, get a key
printw1:
loop print_next ; continue for all entries
print7:
ret ; done, return
print endp ;
print0 proc near
save <ax,cx,di> ; Save registers
push ds ; copy table entry to print line
mov cx,tbl_len ; length of table entry
sub si,si ; offset to next entry
mov di,offset pline ; offset to print line
mov ax,word ptr segdir ; Segment addr for table
add ax,nxtdir ; plus paras offset
mov ds,ax ; as source segment
rep movsb ; for copy
pop ds ;
inc count ; Number of files
mov ax,count ;
cmp ax,numdir ; Done em all?
jbe print1 ; no, display this one
dec count ; yes,
jmp print9 ; done, return
print1:
mov cl,byte ptr pline.tblattr
lea di,byte ptr pline.tblfatr
test cl,32 ; Archived?
jnz print2 ;
mov al,'A' ;
stosb ;
print2: test cl,4 ; System?
jz print3 ;
mov al,'S' ;
stosb ;
print3: test cl,2 ; Hidden?
jz print4 ;
mov al,'H' ;
stosb ;
print4: test cl,1 ; Read only?
jz print5 ;
mov al,'R' ;
stosb ;
print5: test cl,10h ; Sub directory?
jz print5a ; no
lea di,pline.tblfatr-1 ; yes, special display
mov si,offset subdir ;
mov cx,4 ;
rep movsb ; for copying
print5a:
test flags2,bypath ; Doing all paths?
jz print6 ;
cmp pline.tblpath+1,'?' ; Nested entry?
je print6 ; no, as-is
mov pline.tblfatr-1,'-' ; yes, flag it in display
print6: lea si,pline.tbldate ; Reformat date
mov di,offset olddate ; for copying
mov cx,8 ;
rep movsb ;
lea di,pline.tbldate ; Format date
mov ax,word ptr olddate+3 ;
stosw ;
mov al,"/" ;
stosb ;
mov ax,word ptr olddate+6 ;
stosw ;
mov al,"/" ;
stosb ;
mov ax,word ptr olddate ;
stosw ;
cmp pline.tblext,' ' ; Any extension?
jne print8 ; yes, leave the dot
mov pline.tblext-1,' ' ; no, rid it
print8: lea dx,pline.tblname ;
mov byte ptr pline.tblctl,' '
mov byte ptr pline.tblctl+1,stopper
mov nrmsg+1,lf ;
test count,1 ; Right side?
jnz print8a ;
mov nrmsg+1,cr ;
mov word ptr pline.tblctl,0a0dh
print8a:
call prints ; Display an entry
print9:
return <di,cx,ax> ; Restore registers
print0 endp
page
;
; Pause at end of screen for any key
waitkey proc near
save <ax,bx,cx,dx> ; save work regs
mov linecnt,0 ; reset counter
mov ah,2 ; Set cursor position
mov dl,0 ; col 72
mov dh,_rows ; last row
add dh,2 ; adjust for heading
sub bx,bx
int 10h
mov dx,offset more ; ask for more
call prints ;
mov ah,0 ; wait for a key
int 16h ;
mov dx,offset backsp ; backspace over 'more...'
call prints ;
test flags,byclear ; Clear screen each time?
jz waitkeyc ; no
call cls ; Clear screen
waitkeyc:
mov dx,offset titlea ; Top titles
call prints ;
mov dx,offset titleb ; Subdir name
call prints ;
mov dx,offset titlec ; Headings
call prints ;
waitkeyx:
return <dx,cx,bx,ax> ; restore registers
waitkey endp
page
;
; Format the date
getdate proc near ;Format the date
mov ax,word ptr [bp].dtadate
mov di,offset pline.tbldate
or ax,ax ;Is it zero?
jz gotdate
push ax ;Save date
and ax,mask yr ;Get year part
mov cl,yr ;Bits to shift
call cnvrt
or al,'8' ;Adjust for base year
stosw
mov al,'-'
stosb
pop ax ;Get the date back
push ax ;Save it
and ax,mask mo ;Get month part
mov cl,mo ;Bits to shift
call cnvrt2
stosw
mov al,'/'
stosb
pop ax ;Get the date back
and ax,mask dy ;Get day part
mov cl,dy ;Bits to shift
call cnvrt
stosw
gotdate:ret
getdate endp
page
;
; Format the time
gettime proc near ; Format the date
mov ax,word ptr [bp].dtatime;
lea di,pline.tbltime ;
or ax,ax ; It is zero?
jz gottime ;
push ax ; Save date
and ax,mask hour ; Get hour part
mov cl,hour ; Bits to shift
shr ax,cl ;
call cnvrt1 ;
stosw ;
mov al,':' ;
stosb ;
gt3: pop ax ; Get the time back
and ax,mask min ; Get min part
mov cl,min ; Bits to shift
call cnvrt ;
stosw ;
gottime:
ret ;
gettime endp
cnvrt2 proc near ; Convert to ASCII
call cnvrt ;
cmp al,'0' ; Suppress leading zero
jne cnvrtd ;
mov al,' ' ;
ret ;
cnvrt: shr ax,cl ;
cnvrt1: aam ; Make AL into BCD
or ax,'00' ; and to ASCII