1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
kvisc/ka/usr/cmd/main.k
julianb0 89ed8fdc0d
vm
2019-08-03 17:41:44 +02:00

343 lines
6.3 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
ps1 = "C:\\> "
main:
.print_prompt:
call print, ps1
; empty argbuf
mov rcx, argbuf.size
mov rdx, argbuf
stosb.rep rdx, zero
; iterator through argbuf
mov rcx, zero
mov q[argv1pos], zero
.input_loop:
pause
pause
pause
; Fill .buf with user input
scan rax
jmp.axz .input_loop
; backspace character?
b.nz rax, 8, .handle_input
; anything to delete?
jmp.cxz .input_loop ; no
; yes, delete it
dec rcx, 1
add rdx, rcx, argbuf
mov b[rdx], zero
; update screen
cmp b[stdin_echoing], 1
prn.z 8
jmp .input_loop
.handle_input:
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
inc rcx, 1
; another one
jmp .input_loop
.extract_argv0:
; did we read anything at all?
; if not, just go back to waiting input
jmp.cxz .print_prompt
; find first whitespace or null-terminator
mov rcx, argbuf.size
mov rdx, argbuf
scasb.rep.nz rdx, ' '
; argv1 exists? if so, save its position
mov rsi, rdx
.next_space:
mov rcx, b[rsi]
jmp.cxz .do_extract
; skip spaces
cmp rcx, ' '
inc.z rsi, 1
jmp.z .next_space
; if we're here, we found a
; non-zero non-space character
mov q[argv1pos], rsi
; fallthrough
.do_extract:
; empty argv0
mov rcx, argbuf.size
mov rax, argv0
stosb.rep rax, zero
; how much do we copy?
sub rcx, rdx, argbuf
jmp.cxz .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
b.z rax, zero, .handle_CLS
.builtin_date = "date"
call strcmp, argv0, .builtin_date
b.z rax, zero, .handle_DATE
.builtin_dir = "dir"
call strcmp, argv0, .builtin_dir
b.z rax, zero, .handle_DIR
.builtin_dump = "dump"
call strcmp, argv0, .builtin_dump
b.z rax, zero, .handle_DUMP
.builtin_echo = "echo"
call strcmp, argv0, .builtin_echo
b.z rax, zero, .handle_ECHO
.builtin_exit = "exit"
call strcmp, argv0, .builtin_exit
b.z rax, zero, .handle_EXIT
.builtin_help = "help"
call strcmp, argv0, .builtin_help
b.z rax, zero, .handle_HELP
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
b.z rax, zero, .handle_HALT
.builtin_print = "print"
call strcmp, argv0, .builtin_print
b.z rax, zero, .handle_PRINT
.builtin_time = "time"
call strcmp, argv0, .builtin_time
b.z rax, zero, .handle_TIME
.builtin_ver = "ver"
call strcmp, argv0, .builtin_ver
b.z rax, zero, .handle_VER
jmp .command_not_found
;
; call builtins
;
.handle_CLS:
prn PRN_CLEAR
jmp .print_prompt
.handle_DATE:
call GetTimeUTC
push b[rax+3]
mov rcx, b[rax+4]
add rcx, rcx, 1
push rcx
push 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 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
jmp .print_prompt
.handle_HALT:
mov rax, Sys.EnterHaltMode
trap 0
jmp .print_prompt
.handle_PRINT:
mov rax, Sys.OpenFile
mov ax0, q[argv1pos]
b.z ax0, zero, .need_params
trap 0
b.l rax, zero, .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
b.l rcx, zero, .couldnt_read
jmp.cxz .empty_file
mov rdx, FILE_LOADP
prns.rep rdx
jmp .print_prompt
.handle_TIME:
call GetTimeUTC
push b[rax]
push b[rax+1]
push b[rax+2]
call printf, .timefmt
inc rsp, 24
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
.handle_VER:
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.exit
call print, .helpmsg.help
call print, .helpmsg.halt
call print, .helpmsg.print
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 and DOS kernel versions\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]
push argv0
call printf, .fnf_errmsg
inc rsp, 16
jmp .print_prompt
.fnf_errmsg = "%s: %s: file not found\n"
.empty_file:
push q[argv1pos]
push argv0
call printf, .ef_errmsg
inc rsp, 16
jmp .print_prompt
.ef_errmsg = "%s: %s: file was empty\n"
.couldnt_read:
push q[argv1pos]
push argv0
call printf, .cno_errmsg
inc rsp, 16
jmp .print_prompt
.cno_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"