diff --git a/Makefile b/Makefile index b62095a..0a25b7b 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,6 @@ KODIR=fs -AOUT=$(KODIR)/dos.com -ASYM=$(KODIR)/dos.sym KVVM=$(KODIR)/kvisc.exe all: kas @@ -15,18 +13,22 @@ kpc: vm/Makefile kas: kpc as/regs.lst as/k-as.py @cp vm/in/instrs.lst as -DOSK = $(shell find ka -name '*.k') +dos: kas dosclean + @cd ka && make --no-print-directory -s -$(AOUT): $(DOSK) kas - @as/k-as.py ka/dos.k 0x100000 $(AOUT) $(ASYM) +#@as/k-as.py ka/dos.k 0x100000 $(AOUT) $(ASYM) -.PHONY: clean -clean: +.PHONY: clean dosclean + +dosclean: + @rm -f $(KODIR)/*.com $(KODIR)/*.sym + +clean: dosclean @cd vm && make clean --no-print-directory -s verbose=no - @rm -f $(AOUT) $(ASYM) $(KVVM) as/instrs.lst + @rm -f $(KVVM) as/instrs.lst -test: $(AOUT) - @$(KVVM) $(AOUT) $(ASYM) +test: dos + @$(KVVM) $(KODIR)/doskrnl.com $(KODIR)/doskrnl.sym @rm -f $(AOUT) $(ASYM) wc: clean diff --git a/as/k-as.py b/as/k-as.py index 737ae17..017c89a 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -11,6 +11,8 @@ from array import array from tempfile import TemporaryFile from collections import OrderedDict +#print("k-as command line: '{}'".format(sys.argv)) + WANT_DISASM = False if len(sys.argv) != 5: @@ -32,7 +34,7 @@ b_sym = open(sys.argv[4], "w") start_addr = int(sys.argv[2], base=0) -os.chdir(os.path.dirname(sys.argv[1])) +# os.chdir(os.path.dirname(sys.argv[1])) def leave(): source.close() diff --git a/ka/Makefile b/ka/Makefile new file mode 100644 index 0000000..362cfca --- /dev/null +++ b/ka/Makefile @@ -0,0 +1,15 @@ +# The OS/K Team licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +all: dos + +KODIR=../fs + +KSRC = $(shell ls *.k) +KCOM = $(patsubst %.k,$(KODIR)/%.com,$(KSRC)) + +$(KODIR)/%.com: %.k + @../as/k-as.py $< 0x100000 $@ $(patsubst %.k,$(KODIR)/%.sym,$<) + +dos: $(KCOM) + diff --git a/ka/inc/screen.k b/ka/command.k similarity index 53% rename from ka/inc/screen.k rename to ka/command.k index a35d291..66d55db 100644 --- a/ka/inc/screen.k +++ b/ka/command.k @@ -1,6 +1,13 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. -SCR_TEXTMODE_WIDTH := 80 -SCR_TEXTMODE_HEIGHT := 25 +start: + call CMD.builtins.dir + stop + + +include "crt/crt.k" + +include "usr/cmd/dir.k" +include "sys/drv/diskdev.k" diff --git a/ka/crt/crt.k b/ka/crt/crt.k index 19ba511..9c58f1b 100644 --- a/ka/crt/crt.k +++ b/ka/crt/crt.k @@ -4,6 +4,7 @@ ; ; Include CRT librairies ; +include "crt/limits.k" include "crt/err/errno.k" include "crt/fmt/format.k" include "crt/str/string.k" diff --git a/ka/crt/fmt/printf.k b/ka/crt/fmt/printf.k index ce924a9..7465da8 100644 --- a/ka/crt/fmt/printf.k +++ b/ka/crt/fmt/printf.k @@ -19,6 +19,15 @@ printf: lea ax3, b[rsp+8] jmp doprnt +; +; int nprintf(const char *fmt, int n, ...) +; +nprintf: + mov ax2, ax0 + mov ax0, putc + lea ax3, b[rsp+8] + jmp doprnt + ; ; Print a string ; diff --git a/ka/inc/limits.k b/ka/crt/limits.k similarity index 100% rename from ka/inc/limits.k rename to ka/crt/limits.k diff --git a/ka/dos.k b/ka/doskrnl.k similarity index 91% rename from ka/dos.k rename to ka/doskrnl.k index 0d9f860..8dacbec 100644 --- a/ka/dos.k +++ b/ka/doskrnl.k @@ -10,7 +10,7 @@ start: call main - call dir_test + call CMD.builtins.dir hlt @@ -25,9 +25,6 @@ start: prn rax jmp .1 - - -include "inc/limits.k" include "crt/crt.k" ; @@ -41,3 +38,4 @@ include "sys/drv/diskdev.k" include "sys/tests.k" include "sys/main.k" +include "usr/cmd/dir.k" diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k new file mode 100644 index 0000000..922452b --- /dev/null +++ b/ka/usr/cmd/dir.k @@ -0,0 +1,121 @@ +NAME_MAX := 256 + +CMD.builtins.dir: + push nx0 + + sub nx0, nx0 # no. of files found + + mov ax0, .dirmsg + call print + +.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: + test rax, rax + j.z .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: + prn b[r11] + inc r11 + + cmp r11, r10 + j.b .print_file_name + + ; calculate where to put extension + lea r11, b[r10 - 1] + sub r11, .buf + +.ext_pad: + ; print at least 11 non-space characters before extension + cmp r11, 11 + j.ae .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: + cmp b[r10], 0 + j.z .print_ext.2 + + ; print and decrease rcx, unless it's already 0 + prn b[r10] + inc r10 + test rcx, rcx + dec.nz rcx + + jmp .print_ext.1 + +.print_ext.2: + ; did we print at least 4 bytes? + test rcx, rcx + j.z .print_bytes ; yes, carry on + + prn.rep ' ' + jmp .print_ext.2 + +.print_bytes: + ; print file size in bytes + prn ' ' + prn ' ' + prn ' ' + + mov rax, rdx + shr rax, 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 ax0, .endstr2 + call print + + pop nx0 + ret + +.buf = [256] +.endstr1 = " %d file(s)\n" +.endstr2 = " 0 dir(s)\n" diff --git a/vm/dv/DISKDEV b/vm/dv/DISKDEV index 0a96248..3cdd1d0 100644 --- a/vm/dv/DISKDEV +++ b/vm/dv/DISKDEV @@ -10,11 +10,13 @@ Disk device function slots: 16 p i - - firstfile - write name of first file on disk in #ax1-sized buffer #ax0 - - rax = number of bytes written (0 = no files found) 17 p i - - findnext - write name of next file on disk in #ax1-sized buffer #ax0 + + For both slot #16 and slot #17: - rax = number of bytes written (0 = no files found) + - rdx = number of bytes in file 18-25 - - - - (reserved) (reserved) diff --git a/vm/dv/diskdev.c b/vm/dv/diskdev.c index 73a2b91..b4b46cc 100644 --- a/vm/dv/diskdev.c +++ b/vm/dv/diskdev.c @@ -2,6 +2,7 @@ // See the LICENSE file in the project root for more information. #include +#include #include #define MAXOPEN 4096 @@ -26,6 +27,8 @@ struct disk_t long diskdev_findnext(ctx_t *ctx, dev_t *dev) { + struct stat st; + char name[NAME_MAX+4]; dirent_t *ent; GETDISK(); @@ -47,6 +50,17 @@ long diskdev_findnext(ctx_t *ctx, dev_t *dev) rax = copystr(ctx, ax0, ax1, ent->d_name); + snprintf(name, NAME_MAX+4, "fs/%s", ent->d_name); + + if (stat(name, &st) < 0) + { + perror("diskdev: couldn't stat file in directory: "); + rdx = -1; + } + + else + rdx = st.st_size; + return 0; } diff --git a/vm/la/kvisc.lang b/vm/la/kvisc.lang index 7794e74..a83cdb5 100644 --- a/vm/la/kvisc.lang +++ b/vm/la/kvisc.lang @@ -74,10 +74,6 @@ \b([1-9][0-9]*|0)([Uu]([Ll]|LL|ll)?|([Ll]|LL|ll)[Uu]?)?\b - - \b([0-9]+[Ee][-]?[0-9]+|([0-9]*\.[0-9]+|[0-9]+\.)([Ee][-]?[0-9]+)?)[fFlL]? - - \b0[xX][0-9a-fA-F]+([Uu]([Ll]|LL|ll)?|([Ll]|LL|ll)[Uu]?)?\b