NAME_MAX := 256 CMD.builtins.dir: push nx0 sub nx0, nx0 # no. of files found mov rcx, STRLEN_MAX mov rdx, .dirmsg prns.rep.nz rdx .dirmsg = "Directory of C:\\\n\n" .first: mov ax0, .buf mov ax1, NAME_MAX call DISK.FindFirst jmp .list .next: mov ax0, .buf mov ax1, NAME_MAX call DISK.FindNext .list: b.z rax, 0, .end ; found something inc nx0 ; separate extension from file name mov rcx, NAME_MAX mov r10, .buf mov r11, r10 scasb.rep.nz r10, '.' ; print file name sub rcx, r10, r11 prns.rep r11 ; calculate where to put extension sub r11, r10, .buf dec r11 .ext_pad: ; print at least 11 non-space characters before extension b.ae r11, 11, .print_ext prn ' ' inc r11 jmp .ext_pad .print_ext: ; here we print at least 4 characters excluding '.' mov rcx, 4 prn ' ' cmp b[r10], '.' inc.z r10 .print_ext.1: b.z b[r10], 0, .print_ext.2 ; print and decrease rcx, unless it's already 0 prn b[r10] inc r10 dec.cxnz rcx jmp .print_ext.1 .print_ext.2: ; did we print at least 4 bytes? j.cxz .print_bytes ; yes, carry on prn.rep ' ' .print_bytes: ; print file size in bytes prn ' ' prn ' ' prn ' ' shr rax, rdx, 10 and rdx, 1023 mov ax0, .bytesstr push rdx push rax call printf add rsp, 16 .bytesstr = "%d kilobytes + %d bytes" .prepare_next: ; go find next entry prn 10 jmp .next .end: mov ax0, .endstr1 push nx0 call printf add rsp, 8 mov rcx, STRLEN_MAX mov rdx, .endstr2 prns.rep.nz rdx pop nx0 ret .buf = [256] .endstr1 = " %d file(s)\n" .endstr2 = " 0 dir(s)\n"