kvisc/ka/usr/cmd/main.k

431 lines
8.1 KiB
Plaintext

; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
argbuf.size := 256
argbuf = [argbuf.size]
argv0 = [argbuf.size]
argv1pos = 0
stdin_echoing = 1
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, prompt
; empty stuff
call memzero, argbuf, argbuf.size
call memzero, argv0, argbuf.size
nul q[argv1pos]
# call nprint, argv0, argbuf.size
; iterator through argbuf
nul rcx
.input_loop:
pause
pause
pause
; Fill .buf with user input
scan rax
jraxz .input_loop
; ESC key pressed?
beq rax, 0x1B, .handle_EXIT
; backspace character?
bne rax, 8, .handle_input
; anything to delete?
jrcxz .input_loop ; no
; yes, delete it
dec rcx, 1
add rdx, rcx, argbuf
nul b[rdx]
; update screen
bzr b[stdin_echoing], .input_loop
prn 8
jmp .input_loop
.handle_input:
bzr b[stdin_echoing], .se.z
prn rax
.se.z:
beq rax, 10, .extract_argv0
; when max line length is reached,
; force a newline
beq rcx, argbuf.size, .extract_argv0
; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf
mov b[rdx], rax
inc rcx, 1
; another one
jmp .input_loop
.extract_argv0:
; did we read anything at all?
; if not, just go back to waiting input
jrcxz .print_prompt
; find first whitespace or null-terminator
mov rcx, argbuf.size
mov rdx, argbuf
scasb rdx, ' '
; argv1 exists? if so, save its position
mov rsi, rdx
.next_space:
mov rcx, b[rsi]
jrcxz .do_extract
; skip spaces
bne rcx, ' ', .not_a_space
inc rsi, 1
jmp .next_space
.not_a_space:
; if we're here, we found a
; non-zero non-space character
mov q[argv1pos], rsi
; fallthrough
.do_extract:
; how much do we copy?
sub rcx, rdx, argbuf
jrcxz .detect_builtin
dec rcx, 1
mov rdi, argbuf
mov rsi, argv0
.copy_loop:
mov b[rsi], b[rdi]
inc rdi, 1
inc rsi, 1
loop .copy_loop
.detect_builtin:
.builtin_cls = "cls"
call strcmp, argv0, .builtin_cls
jraxz .handle_CLS
.builtin_crash = "crash"
call strcmp, argv0, .builtin_crash
jraxz .handle_CRASH
.builtin_date = "date"
call strcmp, argv0, .builtin_date
jraxz .handle_DATE
.builtin_dir = "dir"
call strcmp, argv0, .builtin_dir
jraxz .handle_DIR
.builtin_dump = "dump"
call strcmp, argv0, .builtin_dump
jraxz .handle_DUMP
.builtin_echo = "echo"
call strcmp, argv0, .builtin_echo
jraxz .handle_ECHO
.builtin_erase = "erase"
call strcmp, argv0, .builtin_erase
jraxz .handle_ERASE
.builtin_exit = "exit"
call strcmp, argv0, .builtin_exit
jraxz .handle_EXIT
.builtin_help = "help"
call strcmp, argv0, .builtin_help
jraxz .handle_HELP
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
jraxz .handle_HALT
.builtin_make = "make"
call strcmp, argv0, .builtin_make
jraxz .handle_MAKE
.builtin_print = "print"
call strcmp, argv0, .builtin_print
jraxz .handle_PRINT
.builtin_prompt = "prompt"
call strcmp, argv0, .builtin_prompt
jraxz .handle_PROMPT
.builtin_remove = "remove"
call strcmp, argv0, .builtin_remove
jraxz .handle_REMOVE
.builtin_time = "time"
call strcmp, argv0, .builtin_time
jraxz .handle_TIME
.builtin_vers = "vers"
call strcmp, argv0, .builtin_vers
jraxz .handle_VERS
jmp .command_not_found
;
; call builtins
;
.handle_CLS:
prn PRN_CLEAR
jmp .print_prompt
.handle_CRASH:
mov rax, 0xDEADBEEF
trap 0
jmp .print_prompt
.handle_DATE:
call GetTimeUTC
mov rcx, b[rax+4]
inc rcx, 1
push b[rax+3], rcx, w[rax+6]
call printf, .datefmt
inc rsp, 40
jmp .print_prompt
.datefmt = "%d/%d/%d\n"
.handle_DIR:
call builtins.dir
jmp .print_prompt
.handle_DUMP:
dump
jmp .print_prompt
.handle_ECHO:
mov rax, q[argv1pos]
jraxz .echo.end
call print, rax
.echo.end:
prn 10
jmp .print_prompt
.handle_ERASE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
bzr ax0, .need_params
trap 0
bltz rax, .couldnt_remove
jmp .handle_MAKE ; re-create it back
.handle_EXIT:
mov rax, Sys.Shutdown
trap 0
jmp .print_prompt
.handle_HALT:
mov rax, Sys.EnterHaltMode
trap 0
jmp .print_prompt
.handle_MAKE:
mov rax, Sys.CreateFile
mov ax0, q[argv1pos]
bzr ax0, .need_params
trap 0
bltz rax, .couldnt_open
jmp .print_prompt
.handle_PRINT:
mov rax, Sys.OpenFile
mov ax0, q[argv1pos]
bzr ax0, .need_params
trap 0
bltz rax, .file_not_found
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
bltz rcx, .couldnt_read
jrcxz .empty_file
call nprint, FILE_LOADP, rcx
jmp .print_prompt
.handle_PROMPT:
mov ax0, prompt
mov ax1, q[argv1pos]
bzr ax1, .need_params
call strcpy
jmp .print_prompt
.handle_REMOVE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
bzr ax0, .need_params
trap 0
bltz rax, .couldnt_remove
jmp .print_prompt
.handle_TIME:
call GetTimeUTC
push b[rax], b[rax+1], b[rax+2]
call printf, .timefmt
inc rsp, 24
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
.handle_VERS:
call print, cmd.versionstr
prn 10
jmp .print_prompt
.handle_HELP:
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.erase
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.remove
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.erase = " ERASE Clear a file, making it blank\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.remove = " REMOVE Delete a file (permanently)\n"
.helpmsg.time = " TIME Display current time of day\n"
.helpmsg.ver = " VERS Display current COMMAND.COM version\n"
.command_not_found:
call print, argv0
call print, .cnf_errmsg
jmp .print_prompt
.cnf_errmsg = ": command not found\n"
.file_not_found:
push q[argv1pos], argv0
call printf, .fnf_errmsg
inc rsp, 16
jmp .print_prompt
.fnf_errmsg = "%s: %s: file not found\n"
.empty_file:
push q[argv1pos], argv0
call printf, .ef_errmsg
inc rsp, 16
jmp .print_prompt
.ef_errmsg = "%s: %s: file was empty\n"
.couldnt_open:
push q[argv1pos], argv0
call printf, .cno_errmsg
inc rsp, 16
jmp .print_prompt
.cno_errmsg = "%s: %s: an error occured while opening file\n"
.couldnt_remove:
push q[argv1pos], argv0
call printf, .cne_errmsg
inc rsp, 16
jmp .print_prompt
.cne_errmsg = "%s: %s: an error occured while removing file\n"
.couldnt_read:
push q[argv1pos], 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
call print, .np_errmsg
jmp .print_prompt
.np_errmsg = ": need more parameters\n"