kvisc/ka/usr/cmd-dir.k

165 lines
2.8 KiB
Plaintext

; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
#define N 11
.handle_DIR:
push ebp
mov ebp, esp
push nx0, nx1
push nx2, nx3
nul nx0 ; no. of files found
nul nx1 ; no. of directories found
nul nx2 ; total amount of bytes found
call print, .dirmsg
.dir_first:
mov eax, Sys.FindFirst
mov ax0, .dir_buf
mov ax1, FNAME_MAX
trap 0
jmp .dir_list
.dir_next:
mov eax, Sys.FindNext
mov ax0, .dir_buf
mov ax1, FNAME_MAX
trap 0
.dir_list:
jraxz .dir_end
mov nx3, ecx ; file size
add nx2, ecx
; directory?
bnz edx, .dir_is_dir
; found a file
inc nx0
; separate extension from file name
mov ecx, FNAME_MAX
mov esi, .dir_buf
mov edi, esi
scasb esi, '.'
; print file name
sub ax1, esi, edi
dec ax1
call nprint, edi
; calculate where to put extension
sub edi, esi, .dir_buf
dec edi
.dir_ext_pad:
; print at least N non-space characters before extension
blte N, edi, .dir_print_ext
prn ' '
inc edi
jmp .dir_ext_pad
.dir_print_ext:
prn ' '
; here we print at least 4 characters excluding '.'
mov ecx, 4
bne b[esi], '.', .dir_print_ext.1
inc esi
.dir_print_ext.1:
bzr b[esi], .dir_print_ext.2
; print and decrease ecx, unless it's already 0
prn b[esi]
inc esi
jrcxz .dir_print_ext.1
dec ecx
jmp .dir_print_ext.1
.dir_print_ext.2:
; did we print at least 4 bytes?
jrcxz .dir_print_bytes ; yes, carry on
.dir_pe2.l:
prn ' '
loop .dir_pe2.l
.dir_print_bytes:
; print file size in bytes
prn ' '
prn ' '
prn ' '
shr eax, nx3, 10
and nx3, 1023
push nx3, eax
call printf, .dir_bytesstr
add esp, 16
.dir_prepare_next:
; go find next entry
prn 10
jmp .dir_next
.dir_end:
shr eax, nx2, 10
shr edx, eax, 10
and eax, 1023
and nx2, 1023
push nx2, eax, edx
call printf, .dir_endstr0
add esp, 24
push nx1, nx0
call printf, .dir_endstr1
add esp, 16
pop nx3, nx2
pop nx1, nx0
leave
jmp .print_prompt
; special case: direcory
.dir_is_dir:
inc nx1
; use printf instead of print
; because it returns the # of
; printed characters
call printf, .dir_buf
blte N, eax, .dir_no_pad
sub ecx, N, eax
dec ecx
.dir.l:
prn ' '
loop .dir.l
.dir_no_pad:
call print, .dir_ext
jmp .dir_print_bytes
.dir_buf = [FNAME_MAX]
.dir_ext = " <DIR> "
.dir_endstr0 = " total %dMB + %dKB + %dB\n"
.dir_endstr1 = " found %d file(s), %d dir(s)\n"
.dirmsg = "Directory of C:\\\n\n"
.dir_bytesstr = "%d kilobytes + %d bytes"
; .dir_bytesstr = "%dMB + %dKB + %dB" # too soon
#undef N