diff --git a/Makefile b/Makefile index 0a113f7..b62095a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,11 @@ # The OS/K Team licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -KODIR=ka/obj +KODIR=fs + +AOUT=$(KODIR)/dos.com +ASYM=$(KODIR)/dos.sym +KVVM=$(KODIR)/kvisc.exe all: kas @@ -13,17 +17,17 @@ kas: kpc as/regs.lst as/k-as.py DOSK = $(shell find ka -name '*.k') -$(KODIR)/a.out: $(DOSK) kas - @as/k-as.py ka/dos.k 0x100000 $(KODIR)/a.out $(KODIR)/a.sym +$(AOUT): $(DOSK) kas + @as/k-as.py ka/dos.k 0x100000 $(AOUT) $(ASYM) .PHONY: clean clean: @cd vm && make clean --no-print-directory -s verbose=no - @rm -f $(KODIR)/a.out $(KODIR)/a.sym $(KODIR)/k.exe as/instrs.lst + @rm -f $(AOUT) $(ASYM) $(KVVM) as/instrs.lst -test: $(KODIR)/a.out - @vm/k.exe $(KODIR)/a.out $(KODIR)/a.sym - @rm -f $(KODIR)/a.out $(KODIR)/a.sym +test: $(AOUT) + @$(KVVM) $(AOUT) $(ASYM) + @rm -f $(AOUT) $(ASYM) wc: clean @cat $(shell find -type f -name '*' ! -path './.git/*' | egrep '(ka|vm)/*') | wc -l diff --git a/fn/console_font.ttf b/fs/console_font.ttf similarity index 100% rename from fn/console_font.ttf rename to fs/console_font.ttf diff --git a/fs/dos.com b/fs/dos.com new file mode 100644 index 0000000..f5e5f7e Binary files /dev/null and b/fs/dos.com differ diff --git a/ka/crt/err/errno.k b/ka/crt/err/errno.k index 49d68cd..ee3a284 100644 --- a/ka/crt/err/errno.k +++ b/ka/crt/err/errno.k @@ -1,8 +1,7 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. -EOK := 0 EINVAL := 1 - errno = 0 +EOK := 0 diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index cfce069..ec77c0f 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -11,6 +11,7 @@ itoa: ; ; void utoa(char *buf, int num, int base) ; +utoa: sub ax3, ax3 jmp ltostr diff --git a/ka/dos.k b/ka/dos.k index 7c93b51..0d9f860 100644 --- a/ka/dos.k +++ b/ka/dos.k @@ -10,9 +10,9 @@ start: call main - call strtol_test + call dir_test - stop + hlt ; Wait for and print input indefinitely .1: @@ -33,8 +33,11 @@ include "crt/crt.k" ; ; Disk Operating System ; + include "sys/drv/cpudev.k" include "sys/drv/memdev.k" +include "sys/drv/diskdev.k" + include "sys/tests.k" include "sys/main.k" diff --git a/ka/sys/drv/diskdev.k b/ka/sys/drv/diskdev.k new file mode 100644 index 0000000..f806354 --- /dev/null +++ b/ka/sys/drv/diskdev.k @@ -0,0 +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. + +DISKDEV := 4 + +DISK.FindFirst: + iocall DISKDEV, 16 + ret + +DISK.FindNext: + iocall DISKDEV, 17 + ret + diff --git a/ka/sys/fileapi.k b/ka/sys/fileapi.k new file mode 100644 index 0000000..e69de29 diff --git a/ka/sys/tests.k b/ka/sys/tests.k index dd5b4f4..5a58fd1 100644 --- a/ka/sys/tests.k +++ b/ka/sys/tests.k @@ -1,6 +1,40 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. +dir_test: + mov ax0, .buf + mov ax1, 128 + call DISK.FindFirst + jmp .list + +.next: + mov ax0, .buf + mov ax1, 128 + call DISK.FindNext + +.list: + test rax, rax + j.z .nothing + + mov ax0, .fnd + call print + + mov ax0, .buf + call print + + prn 10 + + jmp .next + +.nothing: + mov ax0, .err + call print + ret + +.buf = [128] +.fnd = "File found: " +.err = "No more files found" + strtol_test: mov ax0, .s1 mov ax1, 10 diff --git a/vm/Makefile b/vm/Makefile index 062a929..e3af193 100644 --- a/vm/Makefile +++ b/vm/Makefile @@ -26,7 +26,9 @@ CL2='\033[1;36m' CL3='\033[0m' NC='\033[1;37m' -all: k.exe +KEXE=../fs/kvisc.exe + +all: $(KEXE) -include $(dep) @@ -51,7 +53,7 @@ clean: @rm -f $(OBJDIR)/*/*.o in/arch_i.h in/instrs.lst @rm -f $(OBJDIR)/*/*.d -k.exe: in/instrs.lst $(obj) - @gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o k.exe +$(KEXE): in/instrs.lst $(obj) + @gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE) @echo ${CL2}[$@] ${CL}made successfully.${CL3} diff --git a/vm/dv/DEVICES b/vm/dv/DEVICES index 0a26156..d88741c 100644 --- a/vm/dv/DEVICES +++ b/vm/dv/DEVICES @@ -9,4 +9,5 @@ to the same device: 1 memory device 2 clock device 3 keyboard device - 4 screen device + 4 disk device + 5 screen device diff --git a/vm/dv/DISKDEV b/vm/dv/DISKDEV new file mode 100644 index 0000000..0a96248 --- /dev/null +++ b/vm/dv/DISKDEV @@ -0,0 +1,26 @@ +# The OS/K Team licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +Disk device function slots: + + slot ax0 ax1 ax2 thr name desc + 0 - - - - ispresent rax = is disk present? + 1 - - - - isready rax = is disk ready? + 2-15 - - - - (reserved) (reserved) + + 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 + - rax = number of bytes written (0 = no files found) + + 18-25 - - - - (reserved) (reserved) + + 26 p i - - open + - open file whose name is stored in #ax1-sized buffer #ax0 + - rax = -1 if couldn't open file, rax = file handle otherwise + + 27 i - - - close closes file with handle #ax0 + diff --git a/vm/dv/diskdev.c b/vm/dv/diskdev.c new file mode 100644 index 0000000..73a2b91 --- /dev/null +++ b/vm/dv/diskdev.c @@ -0,0 +1,119 @@ +// The OS/K Team licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include +#include + +#define MAXOPEN 4096 + +typedef struct disk_t disk_t; +typedef struct dirent dirent_t; + +struct disk_t +{ + // disk directory + DIR *dir; + + // open files + int *table[MAXOPEN]; + uint opened; +}; + +#define GETDISK() \ + disk_t *disk = (disk_t *)dev->data + +//----------------------------------------------------------------------------// + +long diskdev_findnext(ctx_t *ctx, dev_t *dev) +{ + dirent_t *ent; + GETDISK(); + + for (;;) + { + ent = readdir(disk->dir); + + if (ent == NULL) + { + rax = 0; + return 0; + } + + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + continue; + + break; + } + + rax = copystr(ctx, ax0, ax1, ent->d_name); + + return 0; +} + +long diskdev_findfirst(ctx_t *ctx, dev_t *dev) +{ + GETDISK(); + + rewinddir(disk->dir); + + return diskdev_findnext(ctx, dev); +} + +//----------------------------------------------------------------------------// + +long diskdev_poweron(ctx_t *ctx, dev_t *dev) +{ + disk_t *disk = calloc(1, sizeof(disk_t)); + + disk->dir = opendir("fs"); + + if (disk->dir == NULL) + { + logerr("diskdev: couldn't open fs directory\n"); + return -1; + } + + dev->data = (void *)disk; + + dev->fslots[16] = diskdev_findfirst; + dev->fslots[17] = diskdev_findnext; + + dev->state = DEVGOOD; + + return 0; +} + +long diskdev_poweroff(ctx_t *ctx, dev_t *dev) +{ + GETDISK(); + + if (disk && disk->dir) + closedir(disk->dir); + + if (disk) + free(disk); + + dev->data = NULL; + dev->state = DEVPWOF; + + return 0; +} + +//----------------------------------------------------------------------------// + +dev_t diskdev = +{ + .type = "disk", + .name = "disk", + .modl = "", + .vend = "The OS/K Team", + + .major = KARCH_MAJOR, + .minor = KARCH_MINOR, + .revis = KARCH_REVIS, + + .fpwon = diskdev_poweron, + .fpwoff = diskdev_poweroff, +}; + + diff --git a/vm/in/super.c b/vm/in/super.c index b2e1bdf..d5b28a2 100644 --- a/vm/in/super.c +++ b/vm/in/super.c @@ -24,6 +24,9 @@ IMPL_START_0(hlt) { if (evt.type == SDL_QUIT) die(0); + + if (evt.type == SDL_KEYDOWN) + console_handle_input(ctx, evt.key.keysym.sym); } } } @@ -54,15 +57,6 @@ dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2) return NULL; } -void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str) -{ - for (; *str && maxn > 0; str++, addr++, maxn--) { - writemem(ctx, *str, addr, 1); - } - - writemem(ctx, 0, addr, 1); -} - IMPL_START_2(devctl) { CHK_SUPERV(); diff --git a/vm/pc/console.c b/vm/pc/console.c index c68a2ee..c610f58 100644 --- a/vm/pc/console.c +++ b/vm/pc/console.c @@ -50,7 +50,7 @@ void console_init(ctx_t *ctx) TTF_Init(); scr_font = TTF_OpenFont - ("fn/console_font.ttf", CONSOLE_FONT_SIZE); + ("fs/console_font.ttf", CONSOLE_FONT_SIZE); if (scr_font == NULL) { diff --git a/vm/pc/device.c b/vm/pc/device.c index 6feb993..82fc4df 100644 --- a/vm/pc/device.c +++ b/vm/pc/device.c @@ -9,14 +9,15 @@ // Add new builtin devices here // -extern dev_t cpudev, memdev, clockdev, keybdev, screendev; +extern dev_t cpudev, memdev, clockdev, keybdev, diskdev; static dev_t *arch_d[] = { - &cpudev, - &memdev, - &clockdev, - &keybdev, + &cpudev, // 0 + &memdev, // 1 + &clockdev, // 2 + &keybdev, // 3 + &diskdev, // 4 NULL, }; diff --git a/vm/pc/mem.c b/vm/pc/mem.c index 3ecf3c6..9c78749 100644 --- a/vm/pc/mem.c +++ b/vm/pc/mem.c @@ -5,6 +5,21 @@ //----------------------------------------------------------------------------// +ulong copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str) +{ + ulong orig_maxn = maxn; + + for (; *str && maxn > 0; str++, addr++, maxn--) { + writemem(ctx, *str, addr, 1); + } + + writemem(ctx, 0, addr, 1); + + return orig_maxn - maxn; +} + +//----------------------------------------------------------------------------// + #define CHK_ALIGN(type) \ if (addr % alignof(type) > 0) { \ _except(ctx, E_ALI, \ diff --git a/vm/pc/mem.h b/vm/pc/mem.h index ebaa28d..8aa56f2 100644 --- a/vm/pc/mem.h +++ b/vm/pc/mem.h @@ -16,6 +16,8 @@ static inline char getmempref(ushort len) // Address of boot firmware stack #define FWSTACK (MEMOFF * 2) // 2MB +ulong copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str); + ulong readmem(ctx_t *c, ulong addr, uint len); void writemem(ctx_t *, ulong val, ulong addr, uint len);