kvisc/ka/usr/cmd/main.k

332 lines
6.1 KiB
Plaintext
Raw Normal View History

2019-07-10 17:17:45 +02:00
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
2019-07-10 20:11:35 +02:00
argbuf.size := 256
argbuf = [argbuf.size]
argv0 = [argbuf.size]
argv1pos = 0
stdin_echoing = 1
ps1 = "C:\\> "
2019-07-10 17:17:45 +02:00
main:
2019-07-10 20:11:35 +02:00
.print_prompt:
2019-07-18 22:49:31 +02:00
call print, ps1
2019-07-10 20:11:35 +02:00
; empty argbuf
mov rcx, argbuf.size
mov rdx, argbuf
2019-07-22 14:41:50 +02:00
stosb.rep rdx, zero
2019-07-10 20:11:35 +02:00
; iterator through argbuf
2019-07-17 22:25:50 +02:00
mov rcx, zero
2019-07-10 20:11:35 +02:00
2019-07-17 22:25:50 +02:00
mov q[argv1pos], zero
2019-07-13 12:38:03 +02:00
2019-07-10 20:11:35 +02:00
.input_loop:
pause
pause
2019-07-15 20:46:00 +02:00
pause
2019-07-10 20:11:35 +02:00
; Fill .buf with user input
scan rax
2019-07-22 14:41:50 +02:00
jmp.axz .input_loop
2019-07-10 20:11:35 +02:00
2019-07-10 21:05:26 +02:00
; backspace character?
b.nz rax, 8, .handle_input
; anything to delete?
2019-07-22 14:41:50 +02:00
jmp.cxz .input_loop ; no
2019-07-10 21:05:26 +02:00
2019-07-22 14:41:50 +02:00
; yes, delete it
2019-07-18 22:49:31 +02:00
sub rcx, rcx, 1
2019-07-10 21:05:26 +02:00
add rdx, rcx, argbuf
2019-07-17 22:25:50 +02:00
mov b[rdx], zero
2019-07-10 21:05:26 +02:00
; update screen
cmp b[stdin_echoing], 1
prn.z 8
jmp .input_loop
.handle_input:
2019-07-10 20:11:35 +02:00
cmp b[stdin_echoing], 1
prn.z rax
b.z rax, 10, .extract_argv0
; when max line length is reached,
; force a newline
b.z rcx, argbuf.size, .extract_argv0
; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf
mov b[rdx], rax
2019-07-18 22:49:31 +02:00
add rcx, rcx, 1
2019-07-10 20:11:35 +02:00
; another one
jmp .input_loop
.extract_argv0:
2019-07-10 21:05:26 +02:00
; did we read anything at all?
; if not, just go back to waiting input
2019-07-22 14:41:50 +02:00
jmp.cxz .print_prompt
2019-07-10 21:05:26 +02:00
2019-07-10 20:11:35 +02:00
; find first whitespace or null-terminator
mov rcx, argbuf.size
mov rdx, argbuf
scasb.rep.nz rdx, ' '
; argv1 exists? if so, save its position
2019-07-22 13:18:13 +02:00
mov rsi, rdx
2019-07-10 22:37:59 +02:00
.next_space:
2019-07-22 13:18:13 +02:00
mov rcx, b[rsi]
2019-07-22 14:41:50 +02:00
jmp.cxz .do_extract
2019-07-10 22:37:59 +02:00
; skip spaces
2019-07-22 14:41:50 +02:00
cmp rcx, ' '
2019-07-22 13:18:13 +02:00
add.z rsi, rsi, 1
2019-07-10 22:37:59 +02:00
jmp.z .next_space
2019-07-22 14:41:50 +02:00
; if we're here, we found a
; non-zero non-space character
2019-07-22 13:18:13 +02:00
mov q[argv1pos], rsi
2019-07-10 20:11:35 +02:00
2019-07-10 22:37:59 +02:00
; fallthrough
2019-07-22 14:41:50 +02:00
.do_extract:
2019-07-10 21:05:26 +02:00
; empty argv0
mov rcx, argbuf.size
mov rax, argv0
2019-07-22 14:41:50 +02:00
stosb.rep rax, zero
2019-07-10 21:05:26 +02:00
2019-07-22 14:41:50 +02:00
; how much do we copy?
2019-07-10 21:05:26 +02:00
sub rcx, rdx, argbuf
2019-07-18 22:49:31 +02:00
jmp.cxz .detect_builtin
2019-07-22 14:41:50 +02:00
sub rcx, rcx, 1
2019-07-18 22:49:31 +02:00
2019-07-22 14:41:50 +02:00
mov rdi, argbuf
mov rsi, argv0
2019-07-18 22:49:31 +02:00
2019-07-22 14:41:50 +02:00
.copy_loop:
mov rax, b[rdi]
mov b[rsi], rax
add rdi, rdi, 1
add rsi, rsi, 1
2019-07-18 22:49:31 +02:00
2019-07-22 14:41:50 +02:00
loop .copy_loop
2019-07-10 20:11:35 +02:00
.detect_builtin:
2019-07-10 22:37:59 +02:00
.builtin_cls = "cls"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_cls
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_CLS
2019-07-10 21:05:26 +02:00
2019-07-11 18:34:21 +02:00
.builtin_date = "date"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_date
2019-07-11 18:34:21 +02:00
b.z rax, 0, .handle_DATE
2019-07-10 22:37:59 +02:00
.builtin_dir = "dir"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_dir
2019-07-10 20:11:35 +02:00
b.z rax, 0, .handle_DIR
2019-07-17 22:40:13 +02:00
.builtin_dump = "dump"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_dump
2019-07-17 22:40:13 +02:00
b.z rax, 0, .handle_DUMP
2019-07-10 22:37:59 +02:00
.builtin_echo = "echo"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_echo
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_ECHO
.builtin_exit = "exit"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_exit
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_EXIT
.builtin_help = "help"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_help
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_HELP
.builtin_print = "print"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_print
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_PRINT
2019-07-11 18:34:21 +02:00
.builtin_time = "time"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_time
2019-07-11 18:34:21 +02:00
b.z rax, 0, .handle_TIME
2019-07-10 22:37:59 +02:00
.builtin_ver = "ver"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_ver
2019-07-10 22:37:59 +02:00
b.z rax, 0, .handle_VER
2019-07-13 12:38:03 +02:00
jmp .command_not_found
2019-07-10 21:05:26 +02:00
2019-07-10 20:11:35 +02:00
;
; call builtins
;
2019-07-10 22:37:59 +02:00
.handle_CLS:
prn 0xC15000AF
jmp .print_prompt
2019-07-11 18:34:21 +02:00
.handle_DATE:
call GetTimeUTC
push b[rax+3]
mov rcx, b[rax+4]
2019-07-18 22:49:31 +02:00
add rcx, rcx, 1
2019-07-11 18:34:21 +02:00
push rcx
push w[rax+6]
2019-07-18 22:49:31 +02:00
call printf, .datefmt
2019-07-11 18:34:21 +02:00
2019-07-18 22:49:31 +02:00
add rsp, rsp, 40
2019-07-11 18:34:21 +02:00
jmp .print_prompt
.datefmt = "%d/%d/%d\n"
2019-07-10 20:11:35 +02:00
.handle_DIR:
call builtins.dir
jmp .print_prompt
2019-07-10 17:17:45 +02:00
2019-07-17 22:40:13 +02:00
.handle_DUMP:
dump
jmp .print_prompt
2019-07-10 22:37:59 +02:00
.handle_ECHO:
mov rdx, q[argv1pos]
b.z rdx, 0, .echo.end
mov rcx, argbuf.size
prns.rep.nz rdx
.echo.end:
prn 10
jmp .print_prompt
.handle_EXIT:
mov rax, Sys.Shutdown
trap 0
.handle_PRINT:
2019-07-13 12:38:03 +02:00
mov rax, Sys.OpenFile
mov ax0, q[argv1pos]
2019-07-17 22:25:50 +02:00
b.z ax0, zero, .need_params
2019-07-13 12:38:03 +02:00
trap 0
2019-07-17 22:25:50 +02:00
b.l rax, zero, .file_not_found
2019-07-13 12:38:03 +02:00
mov ax0, rax
mov ax1, FILE_LOADP
mov ax2, FILE_MAXSZ
mov rax, Sys.ReadFile
trap 0
mov rcx, rax
mov rax, Sys.CloseFile
trap 0
2019-07-22 14:41:50 +02:00
b.l rcx, zero, .couldnt_read
jmp.cxz .empty_file
2019-07-13 12:38:03 +02:00
mov rdx, FILE_LOADP
prns.rep rdx
2019-07-10 22:37:59 +02:00
jmp .print_prompt
2019-07-11 18:34:21 +02:00
.handle_TIME:
call GetTimeUTC
push b[rax]
push b[rax+1]
push b[rax+2]
2019-07-18 22:49:31 +02:00
call printf, .timefmt
add rsp, rsp, 24
2019-07-11 18:34:21 +02:00
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
2019-07-10 22:37:59 +02:00
.handle_VER:
2019-07-18 22:49:31 +02:00
call print, cmd.versionstr
2019-07-10 22:37:59 +02:00
prn 10
jmp .print_prompt
.handle_HELP:
2019-07-18 22:49:31 +02:00
call print, .helpmsg
call print, .helpmsg.cls
call print, .helpmsg.date
call print, .helpmsg.dir
call print, .helpmsg.dump
call print, .helpmsg.echo
call print, .helpmsg.exit
call print, .helpmsg.help
call print, .helpmsg.print
call print, .helpmsg.time
call print, .helpmsg.ver
2019-07-10 22:37:59 +02:00
jmp .print_prompt
.helpmsg = "The following commands are built-in:\n"
.helpmsg.cls = " CLS Clear screen\n"
2019-07-11 18:34:21 +02:00
.helpmsg.date = " DATE Display current date\n"
2019-07-10 22:37:59 +02:00
.helpmsg.dir = " DIR Print contents of current directory\n"
2019-07-17 22:40:13 +02:00
.helpmsg.dump = " DUMP Toggles debug instruction dumping\n"
2019-07-10 22:37:59 +02:00
.helpmsg.echo = " ECHO Write arguments to standard output\n"
.helpmsg.exit = " EXIT Initiate machine shutdown\n"
2019-07-11 18:34:21 +02:00
.helpmsg.help = " HELP Display these messages\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 and DOS kernel versions\n"
2019-07-10 22:37:59 +02:00
2019-07-13 12:38:03 +02:00
.command_not_found:
2019-07-18 22:49:31 +02:00
call print, argv0
call print, .cnf_errmsg
2019-07-13 12:38:03 +02:00
jmp .print_prompt
.cnf_errmsg = ": command not found\n"
.file_not_found:
push q[argv1pos]
push argv0
2019-07-18 22:49:31 +02:00
call printf, .fnf_errmsg
2019-07-17 22:25:50 +02:00
add rsp, rsp, 16
2019-07-13 12:38:03 +02:00
jmp .print_prompt
.fnf_errmsg = "%s: %s: file not found\n"
.empty_file:
push q[argv1pos]
push argv0
2019-07-18 22:49:31 +02:00
call printf, .ef_errmsg
2019-07-17 22:25:50 +02:00
add rsp, rsp, 16
2019-07-13 12:38:03 +02:00
jmp .print_prompt
2019-07-22 14:41:50 +02:00
.ef_errmsg = "%s: %s: file was empty\n"
2019-07-13 12:38:03 +02:00
.couldnt_read:
push q[argv1pos]
push argv0
2019-07-18 22:49:31 +02:00
call printf, .cno_errmsg
2019-07-17 22:25:50 +02:00
add rsp, rsp, 16
2019-07-13 12:38:03 +02:00
jmp .print_prompt
.cno_errmsg = "%s: %s: an error occured while reading file\n"
.need_params:
2019-07-18 22:49:31 +02:00
call print, argv0
call print, .np_errmsg
2019-07-13 12:38:03 +02:00
jmp .print_prompt
.np_errmsg = ": need more parameters\n"