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;