diff --git a/.gitignore b/.gitignore index e95ece7..b6710e8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ stdout.txt stderr.txt stdin.txt *.sym +*.tmp diff --git a/as/k-as.py b/as/k-as.py index 1f96d28..7b3b2ac 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -536,8 +536,8 @@ def parse_instr(line): # # Determine memory format # - if word[0] == '[': - assert(word[-1] == ']') + if word[0] in '[(': + assert(word[-1] in '])') word = word[1:-1] # preprocessor, again @@ -589,7 +589,6 @@ def parse_instr(line): assert(len(wtok[0].split('*')) == 2) assert(is_number(wtok[1].strip())) - print(wtok) reg2, imm1 = wtok[0].split('*', 1) imm2 = wtok[1] diff --git a/fs/dir/file b/fs/dir/file new file mode 100644 index 0000000..e69de29 diff --git a/ka/sys/intr/trap0.k b/ka/sys/intr/trap0.k index 52c04d7..4ff210d 100644 --- a/ka/sys/intr/trap0.k +++ b/ka/sys/intr/trap0.k @@ -17,11 +17,16 @@ trap0_handler: b.z rax, Sys.FindNext, .handle_FindNext b.z rax, Sys.FindFirst, .handle_FindFirst b.z rax, Sys.OpenFile, .handle_OpenFile + b.z rax, Sys.CreateFile, .handle_CreateFile b.z rax, Sys.CloseFile, .handle_CloseFile b.z rax, Sys.ReadFile, .handle_ReadFile b.z rax, Sys.EnterHaltMode, .handle_HaltMode mov rax, 1 << 63 +.fini.savecx: + mov ax2, rcx + call RFS.StoreReg, r14, $rcx + .fini: jmp TrapHandlers.epilog @@ -86,18 +91,23 @@ trap0_handler: .handle_FindFirst: inc ax0, r12 call DISK.FindFirst - jmp .fini + jmp .fini.savecx .handle_FindNext: inc ax0, r12 call DISK.FindNext - jmp .fini + jmp .fini.savecx .handle_OpenFile: inc ax0, r12 call DISK.OpenFile jmp .fini +.handle_CreateFile: + inc ax0, r12 + call DISK.CreateFile + jmp .fini + .handle_CloseFile: call DISK.CloseFile jmp .fini diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index da251c7..9d2e624 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -1,17 +1,19 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. +N := 11 + builtins.dir: push rbp mov rbp, rsp push r12 + push r13 + mov r12, zero # no. of files found call print, .dirmsg -.dirmsg = "Directory of C:\\\n\n" - .first: mov rax, Sys.FindFirst mov ax0, .buf @@ -27,11 +29,16 @@ builtins.dir: trap 0 .list: + mov r13, rcx # file size + jmp.axz .end ; found something inc r12, 1 + ; directory? + jmp.dxnz .is_dir + ; separate extension from file name mov rcx, FNAME_MAX mov rsi, .buf @@ -47,8 +54,8 @@ builtins.dir: dec rdi, 1 .ext_pad: - ; print at least 11 non-space characters before extension - b.ae rdi, 11, .print_ext + ; print at least N non-space characters before extension + b.ae rdi, N, .print_ext prn ' ' inc rdi, 1 jmp .ext_pad @@ -82,16 +89,14 @@ builtins.dir: mov rcx, 3 prn.rep ' ' - shr rax, rdx, 10 - and rdx, rdx, 1023 + shr rax, r13, 10 + and r13, r13, 1023 - push rdx + push r13 push rax call printf, .bytesstr inc rsp, 16 -.bytesstr = "%d kilobytes + %d bytes" - .prepare_next: ; go find next entry prn 10 @@ -104,12 +109,32 @@ builtins.dir: call print, .endstr2 + pop r13 pop r12 leave ret + ; special case: direcory +.is_dir: + mov rcx, STRLEN_MAX + mov rdx, .buf + prns.rep.nz rdx + + sub rcx, STRLEN_MAX, rcx + b.ae rcx, N, .is_dir.print_ext + sub rcx, N, rcx + prn.rep ' ' + +.is_dir.print_ext: + call print, .dir_ext + + jmp .print_bytes + .buf = [FNAME_MAX] +.dir_ext = " " .endstr1 = " %d file(s)\n" .endstr2 = " 0 dir(s)\n" +.dirmsg = "Directory of C:\\\n\n" +.bytesstr = "%d kilobytes + %d bytes" diff --git a/ka/usr/cmd/main.k b/ka/usr/cmd/main.k index 878fc52..d7f1a2d 100644 --- a/ka/usr/cmd/main.k +++ b/ka/usr/cmd/main.k @@ -8,12 +8,18 @@ argv1pos = 0 stdin_echoing = 1 -ps1 = "C:\\> " +prompt = [32] main: + mov rsi, prompt + mov b[rsi+0], 'C' + mov b[rsi+1], ':' + mov b[rsi+2], '\' + mov b[rsi+3], '>' + mov b[rsi+4], ' ' .print_prompt: - call print, ps1 + call print, prompt ; empty argbuf mov rcx, argbuf.size @@ -152,10 +158,18 @@ main: call strcmp, argv0, .builtin_halt jmp.axz .handle_HALT +.builtin_make = "make" + call strcmp, argv0, .builtin_make + jmp.axz .handle_MAKE + .builtin_print = "print" call strcmp, argv0, .builtin_print jmp.axz .handle_PRINT +.builtin_prompt = "prompt" + call strcmp, argv0, .builtin_prompt + jmp.axz .handle_PROMPT + .builtin_time = "time" call strcmp, argv0, .builtin_time jmp.axz .handle_TIME @@ -218,6 +232,16 @@ main: trap 0 jmp .print_prompt +.handle_MAKE: + mov rax, Sys.CreateFile + mov ax0, q[argv1pos] + b.z ax0, zero, .need_params + trap 0 + + b.l rax, zero, .couldnt_open + + jmp .print_prompt + .handle_PRINT: mov rax, Sys.OpenFile mov ax0, q[argv1pos] @@ -246,6 +270,14 @@ main: jmp .print_prompt +.handle_PROMPT: + mov ax0, prompt + mov ax1, q[argv1pos] + b.z ax1, zero, .need_params + call strcpy + + jmp .print_prompt + .handle_TIME: call GetTimeUTC @@ -275,24 +307,28 @@ main: call print, .helpmsg.exit call print, .helpmsg.help call print, .helpmsg.halt + call print, .helpmsg.make call print, .helpmsg.print + call print, .helpmsg.prompt call print, .helpmsg.time call print, .helpmsg.ver jmp .print_prompt -.helpmsg = "The following commands are built-in:\n" -.helpmsg.cls = " CLS Clear screen\n" -.helpmsg.date = " DATE Display current date\n" -.helpmsg.dir = " DIR Print contents of current directory\n" -.helpmsg.dump = " DUMP Toggles debug instruction dumping\n" -.helpmsg.echo = " ECHO Write arguments to standard output\n" -.helpmsg.exit = " EXIT Initiate machine shutdown\n" -.helpmsg.help = " HELP Display these messages\n" -.helpmsg.halt = " HALT Put processor in halt mode\n" -.helpmsg.print = " PRINT Display contents of text file\n" -.helpmsg.time = " TIME Display current time of day\n" -.helpmsg.ver = " VER Display current COMMAND.COM version\n" +.helpmsg = "The following commands are built-in:\n" +.helpmsg.cls = " CLS Clear screen\n" +.helpmsg.date = " DATE Display current date\n" +.helpmsg.dir = " DIR Print contents of current directory\n" +.helpmsg.dump = " DUMP Toggles debug instruction dumping\n" +.helpmsg.echo = " ECHO Write arguments to standard output\n" +.helpmsg.exit = " EXIT Initiate machine shutdown\n" +.helpmsg.help = " HELP Display these messages\n" +.helpmsg.halt = " HALT Put processor in halt mode\n" +.helpmsg.make = " MAKE Create an empty file\n" +.helpmsg.print = " PRINT Display contents of text file\n" +.helpmsg.prompt = " PROMPT Change the command line prompt\n" +.helpmsg.time = " TIME Display current time of day\n" +.helpmsg.ver = " VER Display current COMMAND.COM version\n" .command_not_found: call print, argv0 @@ -321,7 +357,7 @@ main: .ef_errmsg = "%s: %s: file was empty\n" -.couldnt_read: +.couldnt_open: push q[argv1pos] push argv0 call printf, .cno_errmsg @@ -329,7 +365,17 @@ main: jmp .print_prompt -.cno_errmsg = "%s: %s: an error occured while reading file\n" +.cno_errmsg = "%s: %s: an error occured while opening file\n" + +.couldnt_read: + push q[argv1pos] + push argv0 + call printf, .cnr_errmsg + inc rsp, 16 + + jmp .print_prompt + +.cnr_errmsg = "%s: %s: an error occured while reading file\n" .need_params: call print, argv0 diff --git a/vm/dv/DISKDEV b/vm/dv/DISKDEV index 5cb415b..b8b93db 100644 --- a/vm/dv/DISKDEV +++ b/vm/dv/DISKDEV @@ -16,7 +16,8 @@ Disk device function slots: For both slot #16 and slot #17: - rax = number of bytes written (0 = no files found) - - rdx = number of bytes in file + - rcx = number of bytes in file + - rdx = 0 if file, 1 if directory 18-21 - - - - (reserved) (reserved) diff --git a/vm/dv/diskdev.c b/vm/dv/diskdev.c index 69068f8..d75bbcc 100644 --- a/vm/dv/diskdev.c +++ b/vm/dv/diskdev.c @@ -55,14 +55,18 @@ long diskdev_findnext(dev_t *dev) snprintf(name, NAME_MAX+4, "fs/%s", ent->d_name); - if (stat(name, &st) < 0) + if (lstat(name, &st) < 0) { perror("diskdev: couldn't stat file in directory: "); + R(RCX) = -1; R(RDX) = -1; } else - R(RDX) = st.st_size; + { + R(RCX) = st.st_size; + R(RDX) = !S_ISREG(st.st_mode); + } return 0; } @@ -94,7 +98,7 @@ long diskdev_open(dev_t *dev) if (fd == MAXOPEN) return -1; - tmp = open(buf, O_RDWR); + tmp = open(buf, O_RDWR|O_NOFOLLOW); if (tmp < 0) { @@ -108,6 +112,27 @@ long diskdev_open(dev_t *dev) return 0; } +long diskdev_create(dev_t *dev) +{ + int tmp; + char buf[NAME_MAX+4] = { 'f', 's', '/', 0 }; + + readstr(R(AX0), NAME_MAX, buf+3); + + tmp = creat(buf, 0); + + if (tmp < 0) + { + perror("diskdev: create"); + return -1; + } + + close(tmp); + R(RAX) = 0; + + return 0; +} + long diskdev_close(dev_t *dev) { GETDISK(); @@ -175,6 +200,7 @@ long diskdev_poweron(dev_t *dev) dev->fslots[25] = diskdev_open; dev->fslots[26] = diskdev_close; + dev->fslots[27] = diskdev_create; dev->fslots[32] = diskdev_read;