kvisc/ka/command.k

400 lines
7.8 KiB
Plaintext
Raw Normal View History

2019-06-20 18:13:06 +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-08-21 16:57:32 +02:00
cmdstart:
2019-07-10 17:17:45 +02:00
jmp start
2019-08-21 18:47:03 +02:00
#include "crt/crt.k"
2019-07-10 17:17:45 +02:00
2019-09-03 09:06:58 +02:00
#define CMDCOM_CODE 0x100000 // 1MB
#define CMDCOM_STACK 0x104000 // + 16KB
2019-08-21 16:57:32 +02:00
; COMMAND.COM guarantees that programs
; are always loaded on a 16KB boundary
; This is guaranteed to be the case
2019-09-07 16:45:03 +02:00
; in all future veesions as well
2019-09-03 09:06:58 +02:00
#define FILE_LOADP 0x108000 // + 32KB
2019-07-13 12:38:03 +02:00
2019-07-01 13:16:17 +02:00
start:
2019-09-07 16:45:03 +02:00
mov esp, CMDCOM_STACK
mov ebp, zero
2019-07-17 22:40:13 +02:00
2019-07-10 17:17:45 +02:00
call main
2019-07-01 13:16:17 +02:00
2019-09-07 16:45:03 +02:00
mov eax, Sys.EnterHaltMode
2019-07-10 17:17:45 +02:00
trap 0
2019-07-01 13:16:17 +02:00
2019-07-10 17:17:45 +02:00
crash
2019-07-01 13:16:17 +02:00
2019-09-07 16:45:03 +02:00
cmd.veesionstr = "COMMAND.COM, veesion 0.1 (KVISC)\nCopyright (C) 2019, The OS/K Team\nMIT license (permissive), see LICENCE file in source tree"
2019-07-10 22:37:59 +02:00
2019-08-21 16:57:32 +02:00
argbuf.size := 256
argbuf = [argbuf.size]
argv0 = [argbuf.size]
argv1pos = 0
stdin_echoing = 1
prompt = [32]
main:
2019-09-07 16:45:03 +02:00
mov esi, prompt
mov b[esi+0], 'C'
mov b[esi+1], ':'
mov b[esi+2], '\'
mov b[esi+3], '>'
mov b[esi+4], ' '
2019-08-21 16:57:32 +02:00
.print_prompt:
call print, prompt
; empty stuff
call memzero, argbuf, argbuf.size
call memzero, argv0, argbuf.size
nul q[argv1pos]
2019-08-21 18:47:03 +02:00
; call nprint, argv0, argbuf.size
2019-08-21 16:57:32 +02:00
; iterator through argbuf
2019-09-07 16:45:03 +02:00
nul ecx
2019-08-21 16:57:32 +02:00
.input_loop:
pause
pause
pause
; Fill .buf with user input
2019-09-07 16:45:03 +02:00
scan eax
2019-09-08 19:04:07 +02:00
jeaxz .input_loop
2019-08-21 16:57:32 +02:00
; ESC key pressed?
2019-09-07 16:45:03 +02:00
beq eax, 0x1B, .handle_EXIT
2019-08-21 16:57:32 +02:00
; backspace character?
2019-09-07 16:45:03 +02:00
bne eax, 8, .handle_input
2019-08-21 16:57:32 +02:00
; anything to delete?
2019-09-08 19:04:07 +02:00
jecxz .input_loop ; no
2019-08-21 16:57:32 +02:00
; yes, delete it
2019-09-07 16:45:03 +02:00
dec ecx
add edx, ecx, argbuf
nul b[edx]
2019-08-21 16:57:32 +02:00
; update screen
bzr b[stdin_echoing], .input_loop
prn 8
jmp .input_loop
.handle_input:
bzr b[stdin_echoing], .se.z
2019-09-07 16:45:03 +02:00
prn eax
2019-08-21 16:57:32 +02:00
.se.z:
2019-09-07 16:45:03 +02:00
beq eax, 10, .extract_argv0
2019-08-21 16:57:32 +02:00
; when max line length is reached,
; force a newline
2019-09-07 16:45:03 +02:00
beq ecx, argbuf.size, .extract_argv0
2019-08-21 16:57:32 +02:00
2019-09-07 16:45:03 +02:00
; add character to buffer and increase iterator (ecx)
add edx, ecx, argbuf
mov b[edx], eax
inc ecx
2019-08-21 16:57:32 +02:00
; another one
jmp .input_loop
.extract_argv0:
; did we read anything at all?
; if not, just go back to waiting input
2019-09-08 19:04:07 +02:00
jecxz .print_prompt
2019-08-21 16:57:32 +02:00
; find first whitespace or null-terminator
2019-09-07 16:45:03 +02:00
mov ecx, argbuf.size
mov edx, argbuf
scasb edx, ' '
2019-08-21 16:57:32 +02:00
; argv1 exists? if so, save its position
2019-09-07 16:45:03 +02:00
mov esi, edx
2019-08-21 16:57:32 +02:00
.next_space:
2019-09-07 16:45:03 +02:00
mov ecx, b[esi]
2019-09-08 19:04:07 +02:00
jecxz .do_extract
2019-08-21 16:57:32 +02:00
; skip spaces
2019-09-07 16:45:03 +02:00
bne ecx, ' ', .not_a_space
inc esi
2019-08-21 16:57:32 +02:00
jmp .next_space
.not_a_space:
; if we're here, we found a
; non-zero non-space character
2019-09-07 16:45:03 +02:00
mov q[argv1pos], esi
2019-08-21 16:57:32 +02:00
; fallthrough
.do_extract:
; how much do we copy?
2019-09-07 16:45:03 +02:00
sub ecx, edx, argbuf
2019-09-08 19:04:07 +02:00
jecxz .detect_builtin
2019-09-07 16:45:03 +02:00
dec ecx
2019-08-21 16:57:32 +02:00
2019-09-07 16:45:03 +02:00
mov edi, argbuf
mov esi, argv0
2019-08-21 16:57:32 +02:00
.copy_loop:
2019-09-07 16:45:03 +02:00
mov b[esi], b[edi]
2019-08-21 16:57:32 +02:00
2019-09-07 16:45:03 +02:00
inc edi
inc esi
2019-08-21 16:57:32 +02:00
loop .copy_loop
.detect_builtin:
.builtin_cls = "cls"
call strcmp, argv0, .builtin_cls
2019-09-08 19:04:07 +02:00
jeaxz .handle_CLS
2019-08-21 16:57:32 +02:00
.builtin_crash = "crash"
call strcmp, argv0, .builtin_crash
2019-09-08 19:04:07 +02:00
jeaxz .handle_CRASH
2019-08-21 16:57:32 +02:00
.builtin_date = "date"
call strcmp, argv0, .builtin_date
2019-09-08 19:04:07 +02:00
jeaxz .handle_DATE
2019-08-21 16:57:32 +02:00
.builtin_dir = "dir"
call strcmp, argv0, .builtin_dir
2019-09-08 19:04:07 +02:00
jeaxz .handle_DIR
2019-08-21 16:57:32 +02:00
.builtin_dump = "dump"
call strcmp, argv0, .builtin_dump
2019-09-08 19:04:07 +02:00
jeaxz .handle_DUMP
2019-08-21 16:57:32 +02:00
.builtin_echo = "echo"
call strcmp, argv0, .builtin_echo
2019-09-08 19:04:07 +02:00
jeaxz .handle_ECHO
2019-08-21 16:57:32 +02:00
.builtin_erase = "erase"
call strcmp, argv0, .builtin_erase
2019-09-08 19:04:07 +02:00
jeaxz .handle_ERASE
2019-08-21 16:57:32 +02:00
.builtin_exit = "exit"
call strcmp, argv0, .builtin_exit
2019-09-08 19:04:07 +02:00
jeaxz .handle_EXIT
2019-08-21 16:57:32 +02:00
.builtin_help = "help"
call strcmp, argv0, .builtin_help
2019-09-08 19:04:07 +02:00
jeaxz .handle_HELP
2019-08-21 16:57:32 +02:00
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
2019-09-08 19:04:07 +02:00
jeaxz .handle_HALT
2019-08-21 16:57:32 +02:00
.builtin_make = "make"
call strcmp, argv0, .builtin_make
2019-09-08 19:04:07 +02:00
jeaxz .handle_MAKE
2019-08-21 16:57:32 +02:00
.builtin_print = "print"
call strcmp, argv0, .builtin_print
2019-09-08 19:04:07 +02:00
jeaxz .handle_PRINT
2019-08-21 16:57:32 +02:00
.builtin_prompt = "prompt"
call strcmp, argv0, .builtin_prompt
2019-09-08 19:04:07 +02:00
jeaxz .handle_PROMPT
2019-08-21 16:57:32 +02:00
.builtin_remove = "remove"
call strcmp, argv0, .builtin_remove
2019-09-08 19:04:07 +02:00
jeaxz .handle_REMOVE
2019-08-21 16:57:32 +02:00
.builtin_time = "time"
call strcmp, argv0, .builtin_time
2019-09-08 19:04:07 +02:00
jeaxz .handle_TIME
2019-08-21 16:57:32 +02:00
.builtin_vers = "vers"
call strcmp, argv0, .builtin_vers
2019-09-08 19:04:07 +02:00
jeaxz .handle_VERS
2019-08-21 16:57:32 +02:00
jmp .try_exec
;
; call builtins
;
2019-08-21 18:47:03 +02:00
#include "usr/cmd-dir.k"
#include "usr/cmd-exec.k"
#include "usr/cmd-fsmisc.k"
2019-08-21 16:57:32 +02:00
.handle_CLS:
prn PRN_CLEAR
jmp .print_prompt
.handle_CRASH:
jmp abort
.handle_DATE:
call GetTimeUTC
2019-09-07 16:45:03 +02:00
mov ecx, b[eax+4]
inc ecx
2019-08-21 16:57:32 +02:00
2019-09-07 16:45:03 +02:00
push b[eax+3], ecx, w[eax+6]
2019-08-21 16:57:32 +02:00
call printf, .datefmt
2019-09-07 16:45:03 +02:00
add esp, 40
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.datefmt = "%d/%d/%d\n"
.handle_DUMP:
dump
jmp .print_prompt
.handle_ECHO:
2019-09-07 16:45:03 +02:00
mov eax, q[argv1pos]
2019-09-08 19:04:07 +02:00
jeaxz .echo.end
2019-08-21 16:57:32 +02:00
2019-09-07 16:45:03 +02:00
call print, eax
2019-08-21 16:57:32 +02:00
.echo.end:
prn 10
jmp .print_prompt
.handle_EXIT:
2019-09-07 16:45:03 +02:00
mov eax, Sys.Shutdown
2019-08-21 16:57:32 +02:00
trap 0
jmp .print_prompt
.handle_HALT:
2019-09-07 16:45:03 +02:00
mov eax, Sys.EnterHaltMode
2019-08-21 16:57:32 +02:00
trap 0
jmp .print_prompt
.handle_PROMPT:
mov ax0, prompt
mov ax1, q[argv1pos]
bzr ax1, .need_params
call strcpy
jmp .print_prompt
.handle_TIME:
call GetTimeUTC
2019-09-07 16:45:03 +02:00
push b[eax], b[eax+1], b[eax+2]
2019-08-21 16:57:32 +02:00
call printf, .timefmt
2019-09-07 16:45:03 +02:00
add esp, 24
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
.handle_VERS:
2019-09-07 16:45:03 +02:00
call print, cmd.veesionstr
2019-08-21 16:57:32 +02:00
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"
2019-09-07 16:45:03 +02:00
.helpmsg.ver = " VERS Display current COMMAND.COM veesion\n"
2019-08-21 16:57:32 +02:00
.exec_not_found:
push argv0
call printf, .enf_errmsg
2019-09-07 16:45:03 +02:00
add esp, 8
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.enf_errmsg = "%s: file not found\n"
.file_not_found:
push q[argv1pos], argv0
call printf, .fnf_errmsg
2019-09-07 16:45:03 +02:00
add esp, 16
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.fnf_errmsg = "%s: %s: file not found\n"
.empty_file:
push q[argv1pos], argv0
call printf, .ef_errmsg
2019-09-07 16:45:03 +02:00
add esp, 16
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.ef_errmsg = "%s: %s: file was empty\n"
.couldnt_open:
push q[argv1pos], argv0
call printf, .cno_errmsg
2019-09-07 16:45:03 +02:00
add esp, 16
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.cno_errmsg = "%s: %s: an error occured while opening file\n"
.couldnt_remove:
push q[argv1pos], argv0
call printf, .cne_errmsg
2019-09-07 16:45:03 +02:00
add esp, 16
2019-08-21 16:57:32 +02:00
jmp .print_prompt
.cne_errmsg = "%s: %s: an error occured while removing file\n"
.couldnt_read:
push q[argv1pos], argv0
call printf, .cnr_errmsg
2019-09-07 16:45:03 +02:00
add esp, 16
2019-08-21 16:57:32 +02:00
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"