kvisc/ka/usr/cmd/main.k

292 lines
5.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
ps1 = "C:\\> "
2019-07-10 17:17:45 +02:00
main:
2019-07-10 20:11:35 +02:00
.print_prompt:
mov rcx, STRLEN_MAX
mov rdx, ps1
prns.rep.nz rdx
; empty argbuf
mov rcx, argbuf.size
mov rdx, argbuf
stosb.rep rdx, 0
; iterator through argbuf
xor rcx, rcx
.input_loop:
pause
pause
; Fill .buf with user input
scan rax
b.z rax, 0, .input_loop
2019-07-10 21:05:26 +02:00
; backspace character?
b.nz rax, 8, .handle_input
; anything to delete?
b.z rcx, 0, .input_loop
; delete it
dec rcx
add rdx, rcx, argbuf
mov b[rdx], 0
; 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
inc rcx
; 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
b.z rcx, 0, .print_prompt
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-10 22:37:59 +02:00
mov r11, rdx
b.z b[r11], 0, .no_argv1
inc r11
.next_space:
2019-07-11 18:34:21 +02:00
mov r10, b[r11]
b.z r10, 0, .no_argv1
2019-07-10 22:37:59 +02:00
; skip spaces
2019-07-11 18:34:21 +02:00
cmp r10, ' '
2019-07-10 22:37:59 +02:00
inc.z r11
jmp.z .next_space
mov q[argv1pos], r11
2019-07-10 20:11:35 +02:00
2019-07-10 22:37:59 +02:00
; fallthrough
.no_argv1:
2019-07-10 21:05:26 +02:00
; empty argv0
mov rcx, argbuf.size
mov rax, argv0
stosb.rep rax, 0
2019-07-10 20:11:35 +02:00
; extract argv0
2019-07-10 21:05:26 +02:00
sub rcx, rdx, argbuf
2019-07-10 20:11:35 +02:00
mov rdx, argbuf
mov rax, argv0
movsb.rep rax, rdx
.detect_builtin:
2019-07-10 22:37:59 +02:00
.builtin_cls = "cls"
mov ax0, argv0
mov ax1, .builtin_cls
call strcmp
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"
mov ax0, argv0
mov ax1, .builtin_date
call strcmp
b.z rax, 0, .handle_DATE
2019-07-10 22:37:59 +02:00
.builtin_dir = "dir"
2019-07-10 20:11:35 +02:00
mov ax0, argv0
mov ax1, .builtin_dir
call strcmp
b.z rax, 0, .handle_DIR
2019-07-10 22:37:59 +02:00
.builtin_echo = "echo"
mov ax0, argv0
mov ax1, .builtin_echo
call strcmp
b.z rax, 0, .handle_ECHO
.builtin_exit = "exit"
mov ax0, argv0
mov ax1, .builtin_exit
call strcmp
b.z rax, 0, .handle_EXIT
.builtin_help = "help"
mov ax0, argv0
mov ax1, .builtin_help
call strcmp
b.z rax, 0, .handle_HELP
.builtin_print = "print"
mov ax0, argv0
mov ax1, .builtin_print
call strcmp
b.z rax, 0, .handle_PRINT
2019-07-11 18:34:21 +02:00
.builtin_time = "time"
mov ax0, argv0
mov ax1, .builtin_time
call strcmp
b.z rax, 0, .handle_TIME
2019-07-10 22:37:59 +02:00
.builtin_ver = "ver"
mov ax0, argv0
mov ax1, .builtin_ver
call strcmp
b.z rax, 0, .handle_VER
2019-07-10 20:11:35 +02:00
; fallthrough
.exec_prog:
2019-07-10 21:05:26 +02:00
; fallthrough
.not_found:
mov rcx, STRLEN_MAX
mov rdx, argv0
prns.rep.nz rdx
mov rdx, .errmsg
prns.rep.nz rdx
2019-07-10 20:11:35 +02:00
jmp .print_prompt
2019-07-10 21:05:26 +02:00
.errmsg = " : command not found\n"
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:
time ax0
call GetTimeUTC
push b[rax+3]
mov rcx, b[rax+4]
inc rcx
push rcx
push w[rax+6]
mov ax0, .datefmt
call printf
add rsp, 8*5
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-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:
jmp .print_prompt
2019-07-11 18:34:21 +02:00
.handle_TIME:
time ax0
call GetTimeUTC
push b[rax]
push b[rax+1]
push b[rax+2]
mov ax0, .timefmt
call printf
add rsp, 3*8
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
2019-07-10 22:37:59 +02:00
.handle_VER:
mov rcx, STRLEN_MAX
mov rdx, cmd.versionstr
prns.rep.nz rdx
prn 10
jmp .print_prompt
.handle_HELP:
mov rcx, STRLEN_MAX
mov rdx, .helpmsg
prns.rep.nz rdx
mov rdx, .helpmsg.cls
prns.rep.nz rdx
2019-07-11 18:34:21 +02:00
mov rdx, .helpmsg.date
prns.rep.nz rdx
2019-07-10 22:37:59 +02:00
mov rdx, .helpmsg.dir
prns.rep.nz rdx
mov rdx, .helpmsg.echo
prns.rep.nz rdx
mov rdx, .helpmsg.exit
prns.rep.nz rdx
mov rdx, .helpmsg.help
prns.rep.nz rdx
mov rdx, .helpmsg.print
prns.rep.nz rdx
2019-07-11 18:34:21 +02:00
mov rdx, .helpmsg.time
prns.rep.nz rdx
2019-07-10 22:37:59 +02:00
mov rdx, .helpmsg.ver
prns.rep.nz rdx
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"
.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