mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
exec
This commit is contained in:
parent
b38eab6d76
commit
f1b3bf129b
23
as/k-as.py
23
as/k-as.py
@ -394,7 +394,7 @@ pref2len = {
|
||||
|
||||
i_aliases = {
|
||||
"inc_2" : "add_2",
|
||||
"dec_2" : "sub_2",
|
||||
#"dec_2" : "sub_2",
|
||||
}
|
||||
|
||||
def parse_instr(line):
|
||||
@ -564,13 +564,20 @@ def parse_instr(line):
|
||||
instr_args += "%%imm8 {} {} {}".format(fmts["m_rr"]|mlen, '$'+reg1, '$'+reg2)
|
||||
size += 3
|
||||
|
||||
# [reg+reg+imm]
|
||||
else:
|
||||
instr_args += "%%imm8 {} {} {} %%signed %%imm16 {}"\
|
||||
.format(fmts["m_rriw"]|mlen, '$'+reg1, '$'+reg2, imm2)
|
||||
size += 5
|
||||
# [reg+imm16]
|
||||
elif reg2 == 'zero':
|
||||
instr_args += "%%imm8 {} {} %%signed %%imm16 {}"\
|
||||
.format(fmts["m_rriw"]|mlen, '$'+reg1, imm2)
|
||||
size += 4
|
||||
|
||||
# [reg+reg*imm+imm]
|
||||
# [reg+reg+imm32]
|
||||
else:
|
||||
instr_args += "%%imm8 {} {} {} %%signed %%imm32 {}"\
|
||||
.format(fmts["m_rrid"]|mlen, '$'+reg1, '$'+reg2, imm2)
|
||||
size += 7
|
||||
|
||||
|
||||
# [reg+reg*imm8+imm32]
|
||||
else:
|
||||
instr_args += "%%imm8 {} {} {} %%imm8 {} %%signed %%imm32 {}"\
|
||||
.format(fmts["m_rrii"]|mlen, '$'+reg1, '$'+reg2, imm1, imm2)
|
||||
@ -581,7 +588,7 @@ def parse_instr(line):
|
||||
instr_args += "%%imm8 {} {}".format(fmts["m_r"]|mlen, '$'+word)
|
||||
size += 2
|
||||
|
||||
# [imm], converted to [zero+imm]
|
||||
# [imm32], converted to [zero+imm32]
|
||||
else:
|
||||
instr_args += "%%imm8 {} $zero $zero %%signed %%imm32 {}".format(fmts["m_rrid"]|mlen, word)
|
||||
size += 7
|
||||
|
3
ka/ABI
3
ka/ABI
@ -11,13 +11,14 @@ There is a 128-bytes red zone below 'rsp'.
|
||||
|
||||
A function's assembly code looks like this:
|
||||
label:
|
||||
enter N
|
||||
enter N*8
|
||||
...
|
||||
...
|
||||
...
|
||||
leave
|
||||
ret
|
||||
'N' is the number of local variables used by the function.
|
||||
'N' may be omitted if it is zero.
|
||||
|
||||
The above code is equivalent to (and can be substitued by) the following:
|
||||
label:
|
||||
|
2
ka/FIXME
Normal file
2
ka/FIXME
Normal file
@ -0,0 +1,2 @@
|
||||
Known issues:
|
||||
- alignment issue... compile with _WANT_ALIGN, see &argv1pos not aligned by 8
|
386
ka/command.k
386
ka/command.k
@ -1,18 +1,24 @@
|
||||
; 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:
|
||||
cmdstart:
|
||||
jmp start
|
||||
|
||||
include "crt/crt.k"
|
||||
|
||||
FILE_LOADP := 0x121000 ; 4KB above stack
|
||||
CMDCOM_CODE := 0x100000 ; 1MB
|
||||
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 versions as well
|
||||
FILE_LOADP := 0x108000 ; + 32KB
|
||||
|
||||
start:
|
||||
mov rsp, 0x120000
|
||||
mov rsp, CMDCOM_STACK
|
||||
mov rbp, zero
|
||||
|
||||
cls
|
||||
call main
|
||||
|
||||
mov rax, Sys.EnterHaltMode
|
||||
@ -20,8 +26,374 @@ start:
|
||||
|
||||
crash
|
||||
|
||||
include "usr/cmd/main.k"
|
||||
include "usr/cmd/dir.k"
|
||||
|
||||
cmd.versionstr = "COMMAND.COM, version 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 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
|
||||
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
|
||||
|
||||
; 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
|
||||
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
|
||||
|
||||
mov rdi, argbuf
|
||||
mov rsi, argv0
|
||||
|
||||
.copy_loop:
|
||||
mov b[rsi], b[rdi]
|
||||
|
||||
inc rdi
|
||||
inc rsi
|
||||
|
||||
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 .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 rcx, b[rax+4]
|
||||
inc rcx
|
||||
|
||||
push b[rax+3], rcx, w[rax+6]
|
||||
call printf, .datefmt
|
||||
inc rsp, 40
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.datefmt = "%d/%d/%d\n"
|
||||
|
||||
.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_EXIT:
|
||||
mov rax, Sys.Shutdown
|
||||
trap 0
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_HALT:
|
||||
mov rax, 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[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"
|
||||
|
||||
.exec_not_found:
|
||||
push argv0
|
||||
call printf, .enf_errmsg
|
||||
inc rsp, 8
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.enf_errmsg = "%s: file 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"
|
||||
|
||||
|
@ -48,6 +48,11 @@ include "crt/fmt/ltostr.k"
|
||||
include "crt/fmt/strtol.k"
|
||||
include "crt/fmt/doprnt.k"
|
||||
include "crt/fmt/printf.k"
|
||||
|
||||
exit:
|
||||
mov rax, Sys.Exit
|
||||
trap 0
|
||||
|
||||
abort:
|
||||
crash
|
||||
|
||||
|
@ -65,7 +65,7 @@ doprnt:
|
||||
movzx ax0, b[r13]
|
||||
bzr ax0, .main_loop
|
||||
|
||||
inc r13, 1
|
||||
inc r13
|
||||
call .doput
|
||||
|
||||
jmp .print_string
|
||||
@ -99,7 +99,7 @@ doprnt:
|
||||
|
||||
.print_number:
|
||||
; allocate itoa conversion buffer
|
||||
dec rsp, 80
|
||||
sub rsp, 80
|
||||
mov r13, rsp
|
||||
|
||||
; assume modifier already set up ax2
|
||||
@ -110,7 +110,7 @@ doprnt:
|
||||
movzx ax0, b[r13]
|
||||
|
||||
bzr ax0, .pib_end_loop
|
||||
inc r13, 1
|
||||
inc r13
|
||||
|
||||
call .doput
|
||||
jmp .print_itoa_buf
|
||||
@ -155,7 +155,7 @@ doprnt:
|
||||
;
|
||||
.doput:
|
||||
; update print count
|
||||
inc r16, 1
|
||||
inc r16
|
||||
|
||||
; if n==0, don't print
|
||||
; we follow the C convention that sprintf()-like functions
|
||||
@ -164,7 +164,7 @@ doprnt:
|
||||
bzr r15, .r
|
||||
|
||||
; decrement n and print
|
||||
dec r15, 1
|
||||
dec r15
|
||||
call r17
|
||||
|
||||
; did putc fail?
|
||||
|
@ -56,7 +56,7 @@ ltostr:
|
||||
.next:
|
||||
mov b[ax0], rdx
|
||||
|
||||
inc ax0, 1
|
||||
inc ax0
|
||||
|
||||
div ax1, ax2
|
||||
jmp .conv
|
||||
@ -65,7 +65,7 @@ ltostr:
|
||||
.fini:
|
||||
jrcxz .cxz
|
||||
mov b[ax0], '-'
|
||||
inc ax0, 1
|
||||
inc ax0
|
||||
|
||||
.cxz:
|
||||
nul b[ax0]
|
||||
|
@ -38,7 +38,7 @@ print:
|
||||
jraxz .r
|
||||
|
||||
prn rax
|
||||
inc ax0, 1
|
||||
inc ax0
|
||||
|
||||
jmp .l
|
||||
|
||||
@ -54,7 +54,7 @@ nprint:
|
||||
|
||||
.l:
|
||||
prn b[ax0]
|
||||
inc ax0, 1
|
||||
inc ax0
|
||||
loop .l
|
||||
.r:
|
||||
ret
|
||||
|
@ -39,13 +39,13 @@ strtoq:
|
||||
|
||||
.skip_spc:
|
||||
bne b[rdx], ' ', .no_spc
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
jmp .skip_spc
|
||||
|
||||
.no_spc:
|
||||
; skip +
|
||||
bne b[rdx], '+', .no_plus
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
|
||||
.no_plus:
|
||||
; unsigned?
|
||||
@ -53,7 +53,7 @@ strtoq:
|
||||
|
||||
; parse '-'
|
||||
bne b[rdx], '-', .unsigned
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
mov rsi, 1
|
||||
|
||||
.unsigned:
|
||||
@ -63,7 +63,7 @@ strtoq:
|
||||
; base prefix?
|
||||
bne b[rdx], '0', .main_loop
|
||||
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
@ -88,7 +88,7 @@ strtoq:
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
bne ax1, 2, .done
|
||||
; else
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
|
||||
.base_0:
|
||||
@ -101,16 +101,16 @@ strtoq:
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not10:
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
|
||||
bne b[rdx], 'x', .b0_not16
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
mov ax1, 16
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not16:
|
||||
bne b[rdx], 'b', .b0_not2
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
mov ax1, 2
|
||||
jmp .main_loop
|
||||
|
||||
@ -120,28 +120,28 @@ strtoq:
|
||||
|
||||
.main_loop:
|
||||
movzx rcx, b[rdx]
|
||||
inc rdx, 1
|
||||
inc rdx
|
||||
|
||||
; between 0 and 9?
|
||||
bltu rcx, '0', .done
|
||||
bltu '9', rcx, .not_digit10
|
||||
|
||||
; yes
|
||||
dec rcx, '0'
|
||||
sub rcx, '0'
|
||||
jmp .next
|
||||
|
||||
.not_digit10:
|
||||
bltu rcx, 'A', .done
|
||||
bltu 'Z', rcx, .not_digitAZ
|
||||
|
||||
dec rcx, 55 ; 'A' - 10
|
||||
sub rcx, 55 ; 'A' - 10
|
||||
jmp .next
|
||||
|
||||
.not_digitAZ:
|
||||
bltu rcx, 'a', .done
|
||||
bltu 'z', rcx, .done
|
||||
|
||||
dec rcx, 87 ; 'a' - 10
|
||||
sub rcx, 87 ; 'a' - 10
|
||||
jmp .next
|
||||
|
||||
.next:
|
||||
|
@ -25,7 +25,7 @@ memzero:
|
||||
|
||||
.l:
|
||||
nul b[ax0]
|
||||
inc ax0, 1
|
||||
inc ax0
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
|
34
ka/crt/str.k
34
ka/crt/str.k
@ -32,8 +32,8 @@ strcpy:
|
||||
|
||||
jrcxz .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
jmp .l
|
||||
|
||||
@ -50,8 +50,8 @@ strncpy:
|
||||
.l:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
loop .l
|
||||
|
||||
@ -71,8 +71,8 @@ strnzcpy:
|
||||
|
||||
jraxz .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
||||
loop .l
|
||||
|
||||
@ -102,11 +102,11 @@ strcmp:
|
||||
add rcx, rax, rdx
|
||||
jrcxz .r
|
||||
|
||||
inc rsi, 1
|
||||
inc rsi
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
dec rax, rdx
|
||||
sub rax, rdx
|
||||
ret
|
||||
|
||||
;
|
||||
@ -122,12 +122,12 @@ strncmp:
|
||||
|
||||
bne rax, rdx, .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
dec rax, rdx
|
||||
sub rax, rdx
|
||||
ret
|
||||
|
||||
;
|
||||
@ -170,7 +170,7 @@ strrev:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb ax1, zero
|
||||
dec ax1, 1
|
||||
dec ax1
|
||||
|
||||
.l:
|
||||
; copy, going backward though str
|
||||
@ -179,8 +179,8 @@ strrev:
|
||||
|
||||
beq ax1, rsi, .r
|
||||
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
inc ax0
|
||||
dec ax1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
@ -205,7 +205,7 @@ strrev2:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb ax1, zero
|
||||
dec ax1, 1
|
||||
dec ax1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.l:
|
||||
@ -213,8 +213,8 @@ strrev2:
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
inc ax0
|
||||
dec ax1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
|
14
ka/crt/sys.k
14
ka/crt/sys.k
@ -15,6 +15,20 @@ Sys.Shutdown := 0x00
|
||||
;
|
||||
Sys.Exit := 0x01
|
||||
|
||||
;
|
||||
; EXEC syscall
|
||||
;
|
||||
; IN
|
||||
; ax0 = new RIP to load
|
||||
; ax1 = frame ID to switch to
|
||||
;
|
||||
; New frame ID must be higher than current
|
||||
; frame ID, and cannot be below 5
|
||||
;
|
||||
; New CR1 is set so that new RIP corresponds to 1MB
|
||||
;
|
||||
Sys.ExecuteInFrame := 0x02
|
||||
|
||||
; FIND syscalls
|
||||
;
|
||||
; Find file on disk
|
||||
|
16
ka/doskrnl.k
16
ka/doskrnl.k
@ -10,13 +10,17 @@ include "crt/crt.k"
|
||||
;
|
||||
; Special addresses
|
||||
;
|
||||
DOSKRNL_CODE := 0x100000 ; 1MB (code)
|
||||
DOSKRNL_STACK := 0x110000 ; + 64KB
|
||||
TRAP0_STACK := 0x112000 ; + 8KB
|
||||
INTR0_STACK := 0x114000 ; + 8KB
|
||||
EXCT0_STACK := 0x118000 ; + 8KB
|
||||
DOSKRNL_CODE := 0x100000 ; 1MB
|
||||
DOSKRNL_STACK := 0x104000 ; + 16KB
|
||||
TRAP0_STACK := 0x104800 ; + 18KB
|
||||
INTR0_STACK := 0x105000 ; + 20KB
|
||||
EXCT0_STACK := 0x105800 ; + 22KB
|
||||
|
||||
CMDCOM_LOADP := 0x120000 ; 1MB + 128KB
|
||||
; The kernel guarantees that COMMAND.COM
|
||||
; will always be loaded on a 16KB boundary
|
||||
; This is guaranteed to be the case in all
|
||||
; future versions as well
|
||||
CMDCOM_LOADP := 0x108000 ; + 32KB
|
||||
CMDCOM_MAXSZ := 0x80000 ; 512KB
|
||||
|
||||
;
|
||||
|
18
ka/hello.k
Normal file
18
ka/hello.k
Normal file
@ -0,0 +1,18 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
start:
|
||||
jmp main
|
||||
|
||||
include "crt/crt.k"
|
||||
|
||||
main:
|
||||
mov rsp, 0x104000
|
||||
nul rbp
|
||||
|
||||
call print, .hellow
|
||||
|
||||
jmp exit
|
||||
|
||||
.hellow = "Hello World!\n"
|
||||
|
@ -48,8 +48,7 @@ RFS.LoadArgs:
|
||||
ret
|
||||
|
||||
RFS.LoadReg:
|
||||
.slot := 33
|
||||
iocall CPUDEV, .slot
|
||||
iocall CPUDEV, 33
|
||||
ret
|
||||
|
||||
RFS.StoreReg:
|
||||
|
@ -18,7 +18,8 @@ ScreenOfDeath:
|
||||
jmp .do_print
|
||||
|
||||
.not_con:
|
||||
blt r14, 4, .not_krn
|
||||
; rframes #2-#3-#4 belong to kernel
|
||||
blt 4, r14, .not_krn
|
||||
push .scr2_krn
|
||||
jmp .do_print
|
||||
|
||||
|
@ -20,7 +20,7 @@ DefaultExceptionHandler:
|
||||
.err_udf = "Undefined behaviour exception\0\0"
|
||||
.err_ill = "Illformed instruction exception"
|
||||
.err_acc = "Invalid memory access exception"
|
||||
.err_sys = "Supervisor-only exception used\0"
|
||||
.err_sys = "Supervisor-only instruct. used\0"
|
||||
.err_dbf = "Double fault exception~~~~~~~~\0"
|
||||
.err_imp = "Feat. not implemented exception"
|
||||
.err_ali = "Misalignmed address exception\0\0"
|
||||
|
@ -40,8 +40,11 @@ DefaultTrapHandler:
|
||||
call RFS.LoadReg, r14, $rax
|
||||
call RFS.LoadArgs, r14
|
||||
|
||||
; will be optimized with a table
|
||||
; when we have a "finished" consistent API
|
||||
jraxz .handle_Shutdown
|
||||
beq rax, Sys.Exit, .handle_Exit
|
||||
beq rax, Sys.ExecuteInFrame, .handle_EIF
|
||||
beq rax, Sys.ReadFile, .handle_ReadFile
|
||||
beq rax, Sys.OpenFile, .handle_OpenFile
|
||||
beq rax, Sys.CloseFile, .handle_CloseFile
|
||||
@ -51,8 +54,12 @@ DefaultTrapHandler:
|
||||
beq rax, Sys.FindFirst, .handle_FindFirst
|
||||
beq rax, Sys.EnterHaltMode, .handle_HaltMode
|
||||
|
||||
.sod:
|
||||
call ScreenOfDeath, .badsyscall, r13
|
||||
|
||||
.wrong:
|
||||
call ScreenOfDeath, .badparams, r13
|
||||
|
||||
.fini.savecx:
|
||||
mov ax2, rcx
|
||||
call RFS.StoreReg, r14, $rcx
|
||||
@ -61,6 +68,7 @@ DefaultTrapHandler:
|
||||
jmp TrapHandlers.epilog
|
||||
|
||||
.badsyscall = "Invalid syscall number in RAX"
|
||||
.badparams = "Invalid syscall parameters"
|
||||
|
||||
;------------------------------------------------;
|
||||
; Syscall implementations ;
|
||||
@ -70,48 +78,91 @@ DefaultTrapHandler:
|
||||
; Pass control to COMMAND.COM in frame 0
|
||||
;
|
||||
.handle_Exit:
|
||||
; deactivate current rframe
|
||||
bzr r14, .hE_nz ; unless it's 0...
|
||||
call RFS.DeactivateFrame, r14
|
||||
|
||||
; Open COMMAND.COM
|
||||
.hE_nz:
|
||||
; open COMMAND.COM
|
||||
call DISK.OpenFile, .cmdcom
|
||||
|
||||
; Crash on failure
|
||||
; crash on failure
|
||||
bltz rax, abort
|
||||
|
||||
; Load at CMDCOM_LOADP
|
||||
; load at CMDCOM_LOADP
|
||||
mov ax1, CMDCOM_LOADP
|
||||
mov ax2, CMDCOM_MAXSZ
|
||||
call DISK.ReadFile, rax
|
||||
|
||||
; Assume that COMMAND.COM being
|
||||
; assume that COMMAND.COM being
|
||||
; less then 4KB means something
|
||||
; went wrong
|
||||
blt rax, 0x1000, abort
|
||||
|
||||
; Close the handle
|
||||
; close the handle
|
||||
call DISK.CloseFile, rax
|
||||
|
||||
; Code address
|
||||
; code address
|
||||
mov ax2, 0x100000
|
||||
call RFS.StoreReg, zero, $rip
|
||||
|
||||
; Usermode
|
||||
; usermode
|
||||
mov ax2, 3
|
||||
call RFS.StoreReg, zero, $cr0
|
||||
|
||||
mov rcx, CMDCOM_LOADP
|
||||
dec rcx, 0x100000
|
||||
sub rcx, 0x100000
|
||||
|
||||
; Code offset
|
||||
; code offset
|
||||
mov ax2, rcx
|
||||
call RFS.StoreReg, zero, $cr1
|
||||
|
||||
; Return frame
|
||||
; return frame
|
||||
nul r14
|
||||
|
||||
jmp .fini
|
||||
|
||||
.cmdcom = "command.com"
|
||||
|
||||
.handle_EIF:
|
||||
blt ax1, 5, .wrong
|
||||
|
||||
; RIP can't be <1MB
|
||||
mov rcx, 0x100000
|
||||
blt ax0, rcx, .wrong
|
||||
|
||||
; add old CR1
|
||||
add ax0, r12
|
||||
|
||||
; real RIP can't be <1MB+32KB either
|
||||
; (kernel + cmdcom personal space)
|
||||
add rdx, rcx, 0x8000
|
||||
blt ax0, rcx, .wrong
|
||||
|
||||
; save rframe and compute new CR1
|
||||
mov rbx, ax1
|
||||
sub rdi, ax0, rcx
|
||||
|
||||
; activate rframe
|
||||
call RFS.ActivateFrame, rbx
|
||||
|
||||
; save new CR1
|
||||
mov ax2, rdi
|
||||
call RFS.StoreReg, rbx, $cr1
|
||||
|
||||
; interruptible user mode
|
||||
mov ax2, 3
|
||||
call RFS.StoreReg, rbx, $cr0
|
||||
|
||||
; set RIP = 1MB
|
||||
mov ax2, rcx
|
||||
call RFS.StoreReg, rbx, $rip
|
||||
|
||||
; change return frame
|
||||
mov r14, rbx
|
||||
|
||||
jmp .fini
|
||||
|
||||
;
|
||||
; Disk API
|
||||
;
|
||||
@ -154,7 +205,6 @@ DefaultTrapHandler:
|
||||
;
|
||||
.handle_Shutdown:
|
||||
call IDT.DelHandler, zero
|
||||
|
||||
stop
|
||||
|
||||
.handle_HaltMode:
|
||||
|
@ -3,16 +3,16 @@
|
||||
|
||||
N := 11
|
||||
|
||||
builtins.dir:
|
||||
.handle_DIR:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
push r12, r13
|
||||
push r14, r15
|
||||
|
||||
nul r12 # no. of files found
|
||||
nul r13 # no. of directories found
|
||||
nul r14 # total amount of bytes found
|
||||
nul r12 ; no. of files found
|
||||
nul r13 ; no. of directories found
|
||||
nul r14 ; total amount of bytes found
|
||||
|
||||
call print, .dirmsg
|
||||
|
||||
@ -40,7 +40,7 @@ builtins.dir:
|
||||
bnz rdx, .is_dir
|
||||
|
||||
; found a file
|
||||
inc r12, 1
|
||||
inc r12
|
||||
|
||||
; separate extension from file name
|
||||
mov rcx, FNAME_MAX
|
||||
@ -50,37 +50,37 @@ builtins.dir:
|
||||
|
||||
; print file name
|
||||
sub ax1, rsi, rdi
|
||||
dec ax1, 1
|
||||
dec ax1
|
||||
call nprint, rdi
|
||||
|
||||
; calculate where to put extension
|
||||
sub rdi, rsi, .buf
|
||||
dec rdi, 1
|
||||
dec rdi
|
||||
|
||||
.ext_pad:
|
||||
; print at least N non-space characters before extension
|
||||
blte N, rdi, .print_ext
|
||||
prn ' '
|
||||
inc rdi, 1
|
||||
inc rdi
|
||||
jmp .ext_pad
|
||||
|
||||
.print_ext:
|
||||
prn ' '
|
||||
; here we print at least 4 characters excluding '.'
|
||||
mov rcx, 4
|
||||
prn ' '
|
||||
|
||||
bne b[rsi], '.', .print_ext.1
|
||||
inc rsi, 1
|
||||
inc rsi
|
||||
|
||||
.print_ext.1:
|
||||
bzr b[rsi], .print_ext.2
|
||||
|
||||
; print and decrease rcx, unless it's already 0
|
||||
prn b[rsi]
|
||||
inc rsi, 1
|
||||
inc rsi
|
||||
jrcxz .print_ext.1
|
||||
|
||||
dec rcx, 1
|
||||
dec rcx
|
||||
jmp .print_ext.1
|
||||
|
||||
.print_ext.2:
|
||||
@ -127,11 +127,11 @@ builtins.dir:
|
||||
pop r13, r12
|
||||
|
||||
leave
|
||||
ret
|
||||
jmp .print_prompt
|
||||
|
||||
; special case: direcory
|
||||
.is_dir:
|
||||
inc r13, 1
|
||||
inc r13
|
||||
|
||||
; use printf instead of print
|
||||
; because it returns # of printed
|
||||
@ -140,7 +140,7 @@ builtins.dir:
|
||||
|
||||
blte N, rax, .dir_no_pad
|
||||
sub rcx, N, rax
|
||||
dec rcx, 1
|
||||
dec rcx
|
||||
|
||||
.dir.l:
|
||||
prn ' '
|
56
ka/usr/cmd-exec.k
Normal file
56
ka/usr/cmd-exec.k
Normal file
@ -0,0 +1,56 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
.try_exec:
|
||||
; try without appending ".com"
|
||||
mov rax, Sys.OpenFile
|
||||
mov ax0, argv0
|
||||
trap 0
|
||||
|
||||
; we good?
|
||||
blte zero, rax, .do_exec
|
||||
|
||||
; nope, append ".com" and try again
|
||||
sub rcx, argbuf.size, 5
|
||||
scasb ax0, zero ; find null-term
|
||||
mov b[ax0+0], '.' ; ".com"
|
||||
mov b[ax0+1], 'c'
|
||||
mov b[ax0+2], 'o'
|
||||
mov b[ax0+3], 'm'
|
||||
nul b[ax0+4]
|
||||
|
||||
; try again
|
||||
mov rax, Sys.OpenFile
|
||||
mov ax0, argv0
|
||||
trap 0
|
||||
|
||||
; still no good?
|
||||
bltz rax, .exec_not_found
|
||||
|
||||
.do_exec:
|
||||
; load file into memory
|
||||
mov ax0, rax
|
||||
mov ax1, FILE_LOADP
|
||||
mov ax2, FILE_MAXSZ
|
||||
mov rax, Sys.ReadFile
|
||||
trap 0
|
||||
|
||||
; save load address
|
||||
mov rcx, rax
|
||||
|
||||
; close file
|
||||
mov rax, Sys.CloseFile
|
||||
trap 0
|
||||
|
||||
; read anything?
|
||||
bltz rcx, .couldnt_read
|
||||
jrcxz .empty_file
|
||||
|
||||
; all good, let's go
|
||||
mov rax, Sys.ExecuteInFrame
|
||||
mov ax0, FILE_LOADP
|
||||
mov ax1, 5
|
||||
trap 0
|
||||
|
||||
; unreachable
|
||||
jmp abort
|
60
ka/usr/cmd-fsmisc.k
Normal file
60
ka/usr/cmd-fsmisc.k
Normal file
@ -0,0 +1,60 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
.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_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_REMOVE:
|
||||
mov rax, Sys.RemoveFile
|
||||
mov ax0, q[argv1pos]
|
||||
bzr ax0, .need_params
|
||||
trap 0
|
||||
|
||||
bltz rax, .couldnt_remove
|
||||
|
||||
jmp .print_prompt
|
||||
|
@ -1,430 +0,0 @@
|
||||
; 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"
|
||||
|
@ -23,7 +23,7 @@ size_t rfs_current_idx = 0;
|
||||
CHK_INDEX(idx); \
|
||||
if (rfs[idx] == NULL) \
|
||||
_except(E_UDF, \
|
||||
"cpudev: operation on inactive reframe #%u", idx);
|
||||
"cpudev: operation on inactive rframe #%u", idx);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -57,7 +57,7 @@ long diskdev_findnext(dev_t *dev)
|
||||
|
||||
if (lstat(name, &st) < 0)
|
||||
{
|
||||
perror("diskdev: couldn't stat file in directory: ");
|
||||
//perror("diskdev: couldn't stat file in directory: ");
|
||||
R(RCX) = -1;
|
||||
R(RDX) = -1;
|
||||
}
|
||||
@ -102,7 +102,7 @@ long diskdev_open(dev_t *dev)
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
perror("diskdev: open");
|
||||
//perror("diskdev: open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ negv 1
|
||||
negv 2
|
||||
|
||||
# Addition
|
||||
inc 1
|
||||
add 2
|
||||
add 3
|
||||
|
||||
@ -52,6 +53,7 @@ addv 2
|
||||
addv 3
|
||||
|
||||
# Substraction
|
||||
dec 1
|
||||
sub 2
|
||||
sub 3
|
||||
|
||||
|
@ -68,6 +68,7 @@ IMPL_START(negv, 2) {
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(inc, 1) { SRCP(p1); *r1 = p1->val + 1; return 1; }
|
||||
IMPL_START(add, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
|
||||
IMPL_START(add, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; }
|
||||
|
||||
@ -97,6 +98,7 @@ IMPL_START(addv, 3) {
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(dec, 1) { SRCP(p1); *r1 = p1->val - 1; return 1; }
|
||||
IMPL_START(sub, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
|
||||
IMPL_START(sub, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; }
|
||||
|
||||
|
@ -11,7 +11,7 @@ Values for ModRMs:
|
||||
(for memory accesses, xxxxx = access size)
|
||||
001xxxxx [reg]
|
||||
010xxxxx [reg+reg]
|
||||
011xxxxx [reg+reg+imm16]
|
||||
011xxxxx [reg+imm16]
|
||||
100xxxxx [reg+reg+imm32]
|
||||
101xxxxx [reg+reg*imm8+imm32]
|
||||
110xxxxx [reg+imm64]
|
||||
|
@ -157,8 +157,8 @@ static void extract_param(instr_t *in, acc_t *p)
|
||||
case 3:
|
||||
p->type = AM_RRI;
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = fetchb();
|
||||
p->imm2 = (short)fetchw();
|
||||
p->reg2 = RZX;
|
||||
p->imm1 = 1;
|
||||
break;
|
||||
|
||||
|
11
vm/pc/mem.c
11
vm/pc/mem.c
@ -36,13 +36,20 @@ ulong writestr(ulong addr, ulong maxn, char *str)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifdef _WANT_ALIGN
|
||||
|
||||
#define CHK_ALIGN(type) \
|
||||
if (addr % alignof(type) > 0) { \
|
||||
_except(E_ALI, \
|
||||
"Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \
|
||||
addr, real, alignof(type)); \
|
||||
"Non-aligned memory access: 0x%012lX (0x%012lX) by %lu vs %lu", \
|
||||
addr, real, alignof(type) - (addr % alignof(type)), \
|
||||
alignof(type)); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define CHK_ALIGN(type)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static ulong readmem8(ulong real, ulong addr)
|
||||
|
Loading…
Reference in New Issue
Block a user