kvisc/ka/usr/cmd/main.k

431 lines
8.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
2019-08-05 14:56:22 +02:00
prompt = [32]
2019-07-10 20:11:35 +02:00
2019-07-10 17:17:45 +02:00
main:
2019-08-05 14:56:22 +02:00
mov rsi, prompt
mov b[rsi+0], 'C'
mov b[rsi+1], ':'
mov b[rsi+2], '\'
mov b[rsi+3], '>'
mov b[rsi+4], ' '
2019-07-10 17:17:45 +02:00
2019-07-10 20:11:35 +02:00
.print_prompt:
2019-08-05 14:56:22 +02:00
call print, prompt
2019-07-10 20:11:35 +02:00
2019-08-14 20:23:05 +02:00
; empty stuff
2019-08-14 09:52:39 +02:00
call memzero, argbuf, argbuf.size
2019-08-14 20:23:05 +02:00
call memzero, argv0, argbuf.size
nul q[argv1pos]
# call nprint, argv0, argbuf.size
2019-07-10 20:11:35 +02:00
; iterator through argbuf
2019-08-14 20:23:05 +02:00
nul rcx
2019-07-10 20:11:35 +02:00
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-08-14 09:52:39 +02:00
jraxz .input_loop
2019-07-10 20:11:35 +02:00
2019-08-06 23:21:37 +02:00
; ESC key pressed?
2019-08-14 09:52:39 +02:00
beq rax, 0x1B, .handle_EXIT
2019-08-06 23:21:37 +02:00
2019-07-10 21:05:26 +02:00
; backspace character?
2019-08-14 09:52:39 +02:00
bne rax, 8, .handle_input
2019-07-10 21:05:26 +02:00
; anything to delete?
2019-08-14 09:52:39 +02:00
jrcxz .input_loop ; no
2019-07-10 21:05:26 +02:00
2019-07-22 14:41:50 +02:00
; yes, delete it
2019-08-03 17:41:44 +02:00
dec rcx, 1
2019-07-10 21:05:26 +02:00
add rdx, rcx, argbuf
2019-08-14 20:23:05 +02:00
nul b[rdx]
2019-07-10 21:05:26 +02:00
; update screen
2019-08-14 09:52:39 +02:00
bzr b[stdin_echoing], .input_loop
prn 8
2019-07-10 21:05:26 +02:00
jmp .input_loop
.handle_input:
2019-08-14 09:52:39 +02:00
bzr b[stdin_echoing], .se.z
prn rax
.se.z:
beq rax, 10, .extract_argv0
2019-07-10 20:11:35 +02:00
; when max line length is reached,
; force a newline
2019-08-14 09:52:39 +02:00
beq rcx, argbuf.size, .extract_argv0
2019-07-10 20:11:35 +02:00
; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf
mov b[rdx], rax
2019-08-03 17:41:44 +02:00
inc 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-08-14 09:52:39 +02:00
jrcxz .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
2019-08-14 20:23:05 +02:00
scasb rdx, ' '
2019-07-10 20:11:35 +02:00
; 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-08-14 09:52:39 +02:00
jrcxz .do_extract
2019-07-10 22:37:59 +02:00
; skip spaces
2019-08-14 09:52:39 +02:00
bne rcx, ' ', .not_a_space
inc rsi, 1
jmp .next_space
2019-07-10 22:37:59 +02:00
2019-08-14 09:52:39 +02:00
.not_a_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:
; how much do we copy?
2019-07-10 21:05:26 +02:00
sub rcx, rdx, argbuf
2019-08-14 09:52:39 +02:00
jrcxz .detect_builtin
2019-08-03 17:41:44 +02:00
dec 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:
2019-08-03 17:41:44 +02:00
mov b[rsi], b[rdi]
2019-07-22 14:41:50 +02:00
2019-08-03 17:41:44 +02:00
inc rdi, 1
inc 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-08-14 09:52:39 +02:00
jraxz .handle_CLS
2019-07-10 21:05:26 +02:00
2019-08-06 22:47:39 +02:00
.builtin_crash = "crash"
call strcmp, argv0, .builtin_crash
2019-08-14 09:52:39 +02:00
jraxz .handle_CRASH
2019-08-06 22:47:39 +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-08-14 09:52:39 +02:00
jraxz .handle_DATE
2019-07-11 18:34:21 +02:00
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-08-14 09:52:39 +02:00
jraxz .handle_DIR
2019-07-10 20:11:35 +02:00
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-08-14 09:52:39 +02:00
jraxz .handle_DUMP
2019-07-17 22:40:13 +02:00
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-08-14 09:52:39 +02:00
jraxz .handle_ECHO
2019-07-10 22:37:59 +02:00
2019-08-05 15:55:46 +02:00
.builtin_erase = "erase"
call strcmp, argv0, .builtin_erase
2019-08-14 09:52:39 +02:00
jraxz .handle_ERASE
2019-08-05 15:55:46 +02:00
2019-07-10 22:37:59 +02:00
.builtin_exit = "exit"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_exit
2019-08-14 09:52:39 +02:00
jraxz .handle_EXIT
2019-07-10 22:37:59 +02:00
.builtin_help = "help"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_help
2019-08-14 09:52:39 +02:00
jraxz .handle_HELP
2019-07-24 16:52:26 +02:00
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
2019-08-14 09:52:39 +02:00
jraxz .handle_HALT
2019-07-10 22:37:59 +02:00
2019-08-05 14:56:22 +02:00
.builtin_make = "make"
call strcmp, argv0, .builtin_make
2019-08-14 09:52:39 +02:00
jraxz .handle_MAKE
2019-08-05 14:56:22 +02:00
2019-07-10 22:37:59 +02:00
.builtin_print = "print"
2019-07-18 22:49:31 +02:00
call strcmp, argv0, .builtin_print
2019-08-14 09:52:39 +02:00
jraxz .handle_PRINT
2019-07-10 22:37:59 +02:00
2019-08-05 14:56:22 +02:00
.builtin_prompt = "prompt"
call strcmp, argv0, .builtin_prompt
2019-08-14 09:52:39 +02:00
jraxz .handle_PROMPT
2019-08-05 14:56:22 +02:00
2019-08-05 15:55:46 +02:00
.builtin_remove = "remove"
call strcmp, argv0, .builtin_remove
2019-08-14 09:52:39 +02:00
jraxz .handle_REMOVE
2019-08-05 15:55:46 +02:00
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-08-14 09:52:39 +02:00
jraxz .handle_TIME
2019-07-11 18:34:21 +02:00
2019-08-05 15:55:46 +02:00
.builtin_vers = "vers"
call strcmp, argv0, .builtin_vers
2019-08-14 09:52:39 +02:00
jraxz .handle_VERS
2019-07-10 22:37:59 +02:00
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:
2019-07-24 16:52:26 +02:00
prn PRN_CLEAR
2019-07-10 22:37:59 +02:00
jmp .print_prompt
2019-08-06 22:47:39 +02:00
.handle_CRASH:
mov rax, 0xDEADBEEF
trap 0
jmp .print_prompt
2019-07-11 18:34:21 +02:00
.handle_DATE:
call GetTimeUTC
mov rcx, b[rax+4]
2019-08-05 16:31:23 +02:00
inc rcx, 1
2019-07-11 18:34:21 +02:00
2019-08-08 18:39:12 +02:00
push b[rax+3], rcx, w[rax+6]
2019-07-18 22:49:31 +02:00
call printf, .datefmt
2019-08-03 17:41:44 +02:00
inc 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:
2019-08-14 09:52:39 +02:00
mov rax, q[argv1pos]
jraxz .echo.end
2019-07-10 22:37:59 +02:00
2019-08-14 09:52:39 +02:00
call print, rax
2019-07-10 22:37:59 +02:00
.echo.end:
prn 10
jmp .print_prompt
2019-08-05 15:55:46 +02:00
.handle_ERASE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
2019-08-14 09:52:39 +02:00
bzr ax0, .need_params
2019-08-05 15:55:46 +02:00
trap 0
2019-08-14 09:52:39 +02:00
bltz rax, .couldnt_remove
2019-08-05 15:55:46 +02:00
jmp .handle_MAKE ; re-create it back
2019-07-10 22:37:59 +02:00
.handle_EXIT:
mov rax, Sys.Shutdown
trap 0
2019-07-24 16:52:26 +02:00
jmp .print_prompt
.handle_HALT:
mov rax, Sys.EnterHaltMode
trap 0
jmp .print_prompt
2019-07-10 22:37:59 +02:00
2019-08-05 14:56:22 +02:00
.handle_MAKE:
mov rax, Sys.CreateFile
mov ax0, q[argv1pos]
2019-08-14 09:52:39 +02:00
bzr ax0, .need_params
2019-08-05 14:56:22 +02:00
trap 0
2019-08-14 09:52:39 +02:00
bltz rax, .couldnt_open
2019-08-05 14:56:22 +02:00
jmp .print_prompt
2019-07-10 22:37:59 +02:00
.handle_PRINT:
2019-07-13 12:38:03 +02:00
mov rax, Sys.OpenFile
mov ax0, q[argv1pos]
2019-08-14 09:52:39 +02:00
bzr ax0, .need_params
2019-07-13 12:38:03 +02:00
trap 0
2019-08-14 09:52:39 +02:00
bltz rax, .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-08-14 09:52:39 +02:00
bltz rcx, .couldnt_read
jrcxz .empty_file
2019-07-13 12:38:03 +02:00
2019-08-14 09:52:39 +02:00
call nprint, FILE_LOADP, rcx
2019-07-13 12:38:03 +02:00
2019-07-10 22:37:59 +02:00
jmp .print_prompt
2019-08-05 14:56:22 +02:00
.handle_PROMPT:
mov ax0, prompt
mov ax1, q[argv1pos]
2019-08-14 09:52:39 +02:00
bzr ax1, .need_params
2019-08-05 14:56:22 +02:00
call strcpy
jmp .print_prompt
2019-08-05 15:55:46 +02:00
.handle_REMOVE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
2019-08-14 09:52:39 +02:00
bzr ax0, .need_params
2019-08-05 15:55:46 +02:00
trap 0
2019-08-14 09:52:39 +02:00
bltz rax, .couldnt_remove
2019-08-05 15:55:46 +02:00
jmp .print_prompt
2019-07-11 18:34:21 +02:00
.handle_TIME:
call GetTimeUTC
2019-08-08 18:39:12 +02:00
push b[rax], b[rax+1], b[rax+2]
2019-07-18 22:49:31 +02:00
call printf, .timefmt
2019-08-03 17:41:44 +02:00
inc rsp, 24
2019-07-11 18:34:21 +02:00
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
2019-08-05 15:55:46 +02:00
.handle_VERS:
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
2019-08-05 15:55:46 +02:00
call print, .helpmsg.erase
2019-07-18 22:49:31 +02:00
call print, .helpmsg.exit
call print, .helpmsg.help
2019-07-24 16:52:26 +02:00
call print, .helpmsg.halt
2019-08-05 14:56:22 +02:00
call print, .helpmsg.make
2019-07-18 22:49:31 +02:00
call print, .helpmsg.print
2019-08-05 14:56:22 +02:00
call print, .helpmsg.prompt
2019-08-05 15:55:46 +02:00
call print, .helpmsg.remove
2019-07-18 22:49:31 +02:00
call print, .helpmsg.time
call print, .helpmsg.ver
2019-07-10 22:37:59 +02:00
jmp .print_prompt
2019-08-05 14:56:22 +02:00
.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"
2019-08-05 16:06:37 +02:00
.helpmsg.erase = " ERASE Clear a file, making it blank\n"
2019-08-05 14:56:22 +02:00
.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"
2019-08-05 16:06:37 +02:00
.helpmsg.remove = " REMOVE Delete a file (permanently)\n"
2019-08-05 14:56:22 +02:00
.helpmsg.time = " TIME Display current time of day\n"
2019-08-05 15:55:46 +02:00
.helpmsg.ver = " VERS Display current COMMAND.COM version\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:
2019-08-08 18:39:12 +02:00
push q[argv1pos], argv0
2019-07-18 22:49:31 +02:00
call printf, .fnf_errmsg
2019-08-03 17:41:44 +02:00
inc rsp, 16
2019-07-13 12:38:03 +02:00
jmp .print_prompt
.fnf_errmsg = "%s: %s: file not found\n"
.empty_file:
2019-08-08 18:39:12 +02:00
push q[argv1pos], argv0
2019-07-18 22:49:31 +02:00
call printf, .ef_errmsg
2019-08-03 17:41:44 +02:00
inc 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
2019-08-05 14:56:22 +02:00
.couldnt_open:
2019-08-08 18:39:12 +02:00
push q[argv1pos], argv0
2019-07-18 22:49:31 +02:00
call printf, .cno_errmsg
2019-08-03 17:41:44 +02:00
inc rsp, 16
2019-07-13 12:38:03 +02:00
jmp .print_prompt
2019-08-05 14:56:22 +02:00
.cno_errmsg = "%s: %s: an error occured while opening file\n"
2019-08-05 15:55:46 +02:00
.couldnt_remove:
2019-08-08 18:39:12 +02:00
push q[argv1pos], argv0
2019-08-05 15:55:46 +02:00
call printf, .cne_errmsg
inc rsp, 16
jmp .print_prompt
.cne_errmsg = "%s: %s: an error occured while removing file\n"
2019-08-05 14:56:22 +02:00
.couldnt_read:
2019-08-08 18:39:12 +02:00
push q[argv1pos], argv0
2019-08-05 14:56:22 +02:00
call printf, .cnr_errmsg
inc rsp, 16
jmp .print_prompt
.cnr_errmsg = "%s: %s: an error occured while reading file\n"
2019-07-13 12:38:03 +02:00
.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"