kvisc/ka/usr/cmd/main.k

388 lines
7.2 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
; 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-08-03 17:41:44 +02:00
dec 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-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-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-08-03 17:41:44 +02:00
inc.z 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-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-03 21:11:12 +02:00
jmp.axz .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-08-03 21:11:12 +02:00
jmp.axz .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-03 21:11:12 +02:00
jmp.axz .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-03 21:11:12 +02:00
jmp.axz .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-03 21:11:12 +02:00
jmp.axz .handle_ECHO
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-03 21:11:12 +02:00
jmp.axz .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-03 21:11:12 +02:00
jmp.axz .handle_HELP
2019-07-24 16:52:26 +02:00
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
2019-08-03 21:11:12 +02:00
jmp.axz .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
jmp.axz .handle_MAKE
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-03 21:11:12 +02:00
jmp.axz .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
jmp.axz .handle_PROMPT
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-03 21:11:12 +02:00
jmp.axz .handle_TIME
2019-07-11 18:34:21 +02:00
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-08-03 21:11:12 +02:00
jmp.axz .handle_VER
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-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-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:
mov rdx, q[argv1pos]
2019-08-03 21:11:12 +02:00
jmp.dxz .echo.end
2019-07-10 22:37:59 +02:00
mov rcx, argbuf.size
prns.rep.nz rdx
.echo.end:
prn 10
jmp .print_prompt
.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]
b.z ax0, zero, .need_params
trap 0
b.l rax, zero, .couldnt_open
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-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-08-05 14:56:22 +02:00
.handle_PROMPT:
mov ax0, prompt
mov ax1, q[argv1pos]
b.z ax1, zero, .need_params
call strcpy
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
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-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
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-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"
.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"
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-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:
push q[argv1pos]
push 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-07-13 12:38:03 +02:00
push q[argv1pos]
push 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"
.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"
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"