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