mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
vm
This commit is contained in:
parent
1b5b90fa37
commit
2a610f2d7a
16
as/k-as.py
16
as/k-as.py
@ -129,6 +129,7 @@ inc_depth_max = 16
|
||||
# Quickly goes through source file and resolves "include" directives ONLY
|
||||
def do_includes(fi):
|
||||
global inc_depth
|
||||
global pcurfile
|
||||
|
||||
for _, line in enumerate(fi):
|
||||
line = line.rstrip()
|
||||
@ -146,10 +147,11 @@ def do_includes(fi):
|
||||
print("Invalid format for include directive: {}".format(line))
|
||||
leave(1)
|
||||
|
||||
inc = tok[1][1:-1]
|
||||
old_curf = pcurfile
|
||||
pcurfile = tok[1][1:-1]
|
||||
|
||||
try:
|
||||
new_fi = open(inc, "r")
|
||||
new_fi = open(pcurfile, "r")
|
||||
|
||||
except:
|
||||
print("Couldn't open file: {}".format(line))
|
||||
@ -160,8 +162,11 @@ def do_includes(fi):
|
||||
print("Maximal include depth reached: {}".format(line))
|
||||
leave(1)
|
||||
|
||||
source.write("$file: {}:\n".format(inc.replace(' ', '')))
|
||||
source.write("$file: {}:\n".format(pcurfile.replace(' ', '')))
|
||||
do_includes(new_fi)
|
||||
pcurfile = old_curf
|
||||
source.write("$file: {}:\n".format(pcurfile.replace(' ', '')))
|
||||
|
||||
|
||||
else:
|
||||
source.write("{}\n".format(line))
|
||||
@ -177,6 +182,7 @@ def parse():
|
||||
global plastlabel
|
||||
|
||||
source.seek(0)
|
||||
pcurfile = sys.argv[1]
|
||||
|
||||
for ln_no, line in enumerate(source):
|
||||
line = line.rstrip()
|
||||
@ -563,8 +569,8 @@ def parse_instr(line):
|
||||
# Offsets
|
||||
#
|
||||
if '+' in word:
|
||||
reg1 = "inv"
|
||||
reg2 = "inv"
|
||||
reg1 = "rzx"
|
||||
reg2 = "rzx"
|
||||
imm1 = '1'
|
||||
imm2 = '0'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
inv
|
||||
rzx zero
|
||||
fc1
|
||||
cr0 c0
|
||||
cr1 c1
|
||||
|
@ -10,7 +10,7 @@ FILE_LOADP := 0x141000 ; 4KB above stack
|
||||
|
||||
start:
|
||||
mov rsp, 0x140000
|
||||
xor rbp, rbp
|
||||
mov rbp, zero
|
||||
|
||||
cls
|
||||
cld
|
||||
|
@ -11,17 +11,15 @@ doprnt:
|
||||
mov q[rbp-8], rbx
|
||||
mov q[rbp-16], nx0
|
||||
mov q[rbp-24], nx1
|
||||
mov q[rbp-32], nx2
|
||||
mov q[rbp-40], rdi
|
||||
mov q[rbp-48], rsi
|
||||
mov q[rbp-56], nx3
|
||||
mov q[rbp-32], rdi
|
||||
mov q[rbp-40], rsi
|
||||
mov q[rbp-48], nx3
|
||||
|
||||
mov rbx, ax2 ; fmt
|
||||
mov nx3, ax0 ; putc
|
||||
mov nx0, ax1 ; n
|
||||
xor nx1, nx1 ; return value
|
||||
xor nx2, nx2 ; index in va_list
|
||||
mov rsi, ax3 ; ap
|
||||
mov rsi, ax3 ; va_list
|
||||
mov nx1, zero ; return value
|
||||
|
||||
.main_loop:
|
||||
; find '%' or null-terminator
|
||||
@ -46,7 +44,7 @@ doprnt:
|
||||
|
||||
; we did find a modifier / '%'
|
||||
mov rax, b[rbx+1]
|
||||
add rbx, 2
|
||||
add rbx, rbx, 2
|
||||
|
||||
b.z rax, 's', .modf_s
|
||||
b.z rax, 'c', .modf_c
|
||||
@ -62,24 +60,24 @@ doprnt:
|
||||
|
||||
.modf_s:
|
||||
; get string address
|
||||
mov rdi, q[rsi+nx2*8]
|
||||
inc nx2
|
||||
mov rdi, q[rsi]
|
||||
add rsi, rsi, 8
|
||||
|
||||
test rdi, rdi
|
||||
j.z .nullstring
|
||||
cmp rdi, zero
|
||||
jmp.z .nullstring
|
||||
|
||||
.print_string:
|
||||
mov ax0, b[rdi]
|
||||
test ax0, ax0
|
||||
j.z .main_loop
|
||||
cmp ax0, zero
|
||||
jmp.z .main_loop
|
||||
|
||||
inc rdi
|
||||
call .doput
|
||||
jmp .print_string
|
||||
|
||||
.modf_c:
|
||||
mov ax0, q[rsi+nx2*8]
|
||||
inc nx2
|
||||
mov ax0, q[rsi]
|
||||
add rsi, rsi, 8
|
||||
call .doput
|
||||
jmp .main_loop
|
||||
|
||||
@ -108,21 +106,21 @@ doprnt:
|
||||
|
||||
.print_number:
|
||||
; allocate itoa conversion buffer
|
||||
sub rsp, 80
|
||||
sub rsp, rsp, 80
|
||||
mov rdi, rsp
|
||||
|
||||
; assume modifier already set up ax2
|
||||
mov ax0, rsp
|
||||
mov ax1, q[rsi+nx2*8]
|
||||
mov ax1, q[rsi]
|
||||
call itoa
|
||||
inc nx2
|
||||
add rsi, rsi, 8
|
||||
|
||||
.print_itoa_buf:
|
||||
mov ax0, b[rdi]
|
||||
|
||||
test ax0, ax0
|
||||
add.z rsp, 80
|
||||
j.z .main_loop
|
||||
cmp ax0, zero
|
||||
add.z rsp, rsp, 80
|
||||
jmp.z .main_loop
|
||||
|
||||
inc rdi
|
||||
call .doput
|
||||
@ -170,10 +168,9 @@ doprnt:
|
||||
mov rbx, q[rbp-8]
|
||||
mov nx0, q[rbp-16]
|
||||
mov nx1, q[rbp-24]
|
||||
mov nx2, q[rbp-32]
|
||||
mov rdi, q[rbp-40]
|
||||
mov rsi, q[rbp-48]
|
||||
mov nx3, q[rbp-56]
|
||||
mov rdi, q[rbp-32]
|
||||
mov rsi, q[rbp-40]
|
||||
mov nx3, q[rbp-48]
|
||||
leave
|
||||
ret
|
||||
;
|
||||
@ -187,7 +184,7 @@ doprnt:
|
||||
; we follow the C convention that sprintf()-like functions
|
||||
; should return the number of characters that would have
|
||||
; been printed/written if 'n' were big enough
|
||||
test nx0, nx0
|
||||
cmp nx0, zero
|
||||
ret.z
|
||||
|
||||
; if n>0, decrement n and print
|
||||
@ -195,8 +192,8 @@ doprnt:
|
||||
call nx3
|
||||
|
||||
; did putc fail?
|
||||
test rax, rax
|
||||
xor.nz nx0, nx0 ; yes, so artificially set n=0
|
||||
cmp rax, zero
|
||||
mov.nz nx0, zero ; yes, so artificially set n=0
|
||||
|
||||
ret
|
||||
|
||||
|
@ -12,7 +12,7 @@ itoa:
|
||||
; void utoa(char *buf, int num, int base)
|
||||
;
|
||||
utoa:
|
||||
xor ax3, ax3
|
||||
mov ax3, zero
|
||||
jmp ltostr
|
||||
|
||||
;
|
||||
@ -20,20 +20,19 @@ utoa:
|
||||
;
|
||||
ltostr:
|
||||
mov rax, ax0
|
||||
xor r11, r11
|
||||
mov r11, zero
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
b.b ax2, 2, .bad
|
||||
b.a ax2, 36, .bad
|
||||
|
||||
; deal with zero
|
||||
b.z ax1, 0, .zero
|
||||
b.z ax1, zero, .is_zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
test ax3, ax3
|
||||
cmp.nz ax2, 10 ; base 10
|
||||
j.nz .conv
|
||||
b.z ax3, zero, .conv
|
||||
b.nz ax2, 10, .conv ; base 10
|
||||
|
||||
sgn r11, ax1 ; extract ax1 sign
|
||||
|
||||
@ -42,17 +41,17 @@ ltostr:
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
b.z ax1, 0, .fini
|
||||
b.z ax1, zero, .fini
|
||||
|
||||
rem r10, ax1, ax2 ; ax1 % base
|
||||
|
||||
b.a r10, 9, .nondec ; r10 > 9 ?
|
||||
|
||||
add r10, '0'
|
||||
add r10, r10, '0'
|
||||
jmp .next
|
||||
|
||||
.nondec:
|
||||
add r10, 55 ; 'A' - 10
|
||||
add r10, r10, 55 ; 'A' - 10
|
||||
|
||||
.next:
|
||||
mov b[ax0], r10
|
||||
@ -67,7 +66,7 @@ ltostr:
|
||||
mov.z b[ax0], '-'
|
||||
inc.z ax0
|
||||
|
||||
mov b[ax0], 0
|
||||
mov b[ax0], zero
|
||||
|
||||
mov ax0, rax
|
||||
call strrev2
|
||||
@ -82,7 +81,7 @@ ltostr:
|
||||
mov b[ax0], 0
|
||||
ret
|
||||
|
||||
.zero:
|
||||
.is_zero:
|
||||
mov b[ax0], 48 ; '0'
|
||||
mov b[ax0+1], 0
|
||||
ret
|
||||
|
@ -6,7 +6,7 @@
|
||||
;
|
||||
putc:
|
||||
prn ax0
|
||||
xor rax, rax
|
||||
mov rax, zero
|
||||
ret
|
||||
|
||||
;
|
||||
@ -16,7 +16,7 @@ printf:
|
||||
mov ax2, ax0
|
||||
mov ax0, putc
|
||||
mov ax1, STRLEN_MAX
|
||||
lea ax3, b[rsp+8]
|
||||
add ax3, rsp, 8
|
||||
jmp doprnt
|
||||
|
||||
;
|
||||
@ -25,7 +25,7 @@ printf:
|
||||
nprintf:
|
||||
mov ax2, ax0
|
||||
mov ax0, putc
|
||||
lea ax3, b[rsp+8]
|
||||
add ax3, rsp, 8
|
||||
jmp doprnt
|
||||
|
||||
;
|
||||
@ -33,7 +33,7 @@ nprintf:
|
||||
;
|
||||
print:
|
||||
mov rcx, STRLEN_MAX
|
||||
b.z b[ax0], 0, .1
|
||||
b.z b[ax0], zero, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
ret
|
||||
@ -43,7 +43,7 @@ print:
|
||||
;
|
||||
print_n:
|
||||
mov rcx, ax1
|
||||
b.z b[ax0], 0, .1
|
||||
b.z b[ax0], zero, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
ret
|
||||
|
@ -18,7 +18,7 @@ strtol:
|
||||
; rdx = pointer to first invalid byte
|
||||
;
|
||||
strtoul:
|
||||
xor ax2, ax2
|
||||
mov ax2, zero
|
||||
jmp strtoq
|
||||
|
||||
;
|
||||
@ -27,7 +27,7 @@ strtoul:
|
||||
; guesses base when 'base'=0
|
||||
;
|
||||
strtoq:
|
||||
xor rax, rax
|
||||
mov rax, zero
|
||||
mov rdx, ax0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
@ -35,7 +35,7 @@ strtoq:
|
||||
b.a ax1, 36, .bad
|
||||
|
||||
; empty string?
|
||||
b.z b[rdx], 0, .done
|
||||
b.z b[rdx], zero, .done
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
@ -47,15 +47,15 @@ strtoq:
|
||||
inc.z rdx
|
||||
|
||||
; signed?
|
||||
test ax2, ax2
|
||||
xor.z r10, r10
|
||||
cmp ax2, zero
|
||||
mov.z r10, zero
|
||||
jmp.z .unsigned
|
||||
|
||||
; parse '-'
|
||||
cmp b[rdx], '-'
|
||||
inc.z rdx
|
||||
mov.z r10, 1
|
||||
sub.nz r10, r10
|
||||
mov.nz r10, zero
|
||||
|
||||
.unsigned:
|
||||
; base 0
|
||||
@ -68,7 +68,7 @@ strtoq:
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
b.z rcx, 0, .done ; "0"
|
||||
b.z rcx, zero, .done ; "0"
|
||||
b.z rcx, 'x', .parsed_0x
|
||||
b.z rcx, 'b', .parsed_0b
|
||||
|
||||
@ -119,18 +119,18 @@ strtoq:
|
||||
cmp r12, '0'
|
||||
jmp.b .done
|
||||
cmp.ae r12, '9'
|
||||
sub.be r12, '0'
|
||||
sub.be r12, r12, '0'
|
||||
jmp.be .next
|
||||
|
||||
cmp r12, 'A'
|
||||
cmp.ae r12, 'Z'
|
||||
sub.be r12, 55 ; 'A' - 10
|
||||
sub.be r12, r12, 55 ; 'A' - 10
|
||||
jmp.be .next
|
||||
|
||||
cmp r12, 'a'
|
||||
jmp.b .next
|
||||
cmp.ae r12, 'z'
|
||||
sub.be r12, 87 ; 'a' - 10
|
||||
sub.be r12, r12, 87 ; 'a' - 10
|
||||
jmp.be .next
|
||||
|
||||
.next:
|
||||
@ -138,12 +138,12 @@ strtoq:
|
||||
b.ae r12, ax1, .done
|
||||
|
||||
mul rax, rax, ax1
|
||||
add rax, r12
|
||||
add rax, rax, r12
|
||||
jmp .main_loop
|
||||
|
||||
.done:
|
||||
; negative?
|
||||
test r10, r10
|
||||
cmp r10, zero
|
||||
ret.z
|
||||
|
||||
; yes
|
||||
|
@ -25,15 +25,15 @@ DaysInYear:
|
||||
|
||||
; divisible by 4?
|
||||
rem rcx, ax0, 4
|
||||
b.nz rcx, 0, .end
|
||||
b.nz rcx, zero, .end
|
||||
|
||||
; divisible by 100?
|
||||
rem rcx, ax0, 100
|
||||
b.nz rcx, 0, .leap
|
||||
b.nz rcx, zero, .leap
|
||||
|
||||
; divisible by 400?
|
||||
rem rcx, ax0, 400
|
||||
b.nz rcx, 0, .end
|
||||
b.nz rcx, zero, .end
|
||||
|
||||
.leap:
|
||||
inc rax
|
||||
|
@ -18,8 +18,8 @@ strchr:
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax0, ax1
|
||||
|
||||
cmp b[ax0], 0
|
||||
xor.z rax, rax
|
||||
cmp b[ax0], zero
|
||||
mov.z rax, zero
|
||||
ret.z
|
||||
|
||||
mov rax, ax0
|
||||
|
@ -18,13 +18,14 @@ strcmp:
|
||||
;
|
||||
strncmp:
|
||||
mov rcx, ax2
|
||||
mov.cxz rax, 0
|
||||
mov.cxz rax, zero
|
||||
ret.cxz
|
||||
|
||||
cmpzsb.rep.z ax0, ax1
|
||||
|
||||
mov rax, b[ax0-1]
|
||||
sub rax, b[ax1-1]
|
||||
mov rcx, b[ax1-1]
|
||||
sub rax, rax, rcx
|
||||
|
||||
ret
|
||||
|
||||
|
@ -27,11 +27,11 @@ strnzcpy:
|
||||
ret.cxz
|
||||
|
||||
dec rcx
|
||||
j.cxz .1
|
||||
jmp.cxz .1
|
||||
|
||||
movsb.rep.nz ax0, ax1
|
||||
|
||||
.1:
|
||||
mov b[ax0], 0
|
||||
mov b[ax0], zero
|
||||
ret
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
;
|
||||
strnlen:
|
||||
mov rcx, ax1
|
||||
scasb.rep.nz ax0, 0
|
||||
scasb.rep.nz ax0, zero
|
||||
|
||||
sub rax, ax1, rcx
|
||||
ret
|
||||
|
@ -7,8 +7,8 @@
|
||||
; buf and src must NOT overlap
|
||||
;
|
||||
strrev:
|
||||
cmp b[ax1], 0
|
||||
mov.z b[ax0], 0
|
||||
cmp b[ax1], zero
|
||||
mov.z b[ax0], zero
|
||||
ret.z
|
||||
|
||||
; save str's location
|
||||
@ -17,7 +17,7 @@ strrev:
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, 0
|
||||
scasb.rep.nz ax1, zero
|
||||
dec ax1
|
||||
|
||||
.2:
|
||||
@ -27,7 +27,7 @@ strrev:
|
||||
mov b[ax0], rax
|
||||
|
||||
cmp ax1, r10
|
||||
mov.z b[ax0+1], 0
|
||||
mov.z b[ax0+1], zero
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
@ -41,7 +41,7 @@ strrev:
|
||||
; Inverses str
|
||||
;
|
||||
strrev2:
|
||||
cmp b[ax0], 0
|
||||
cmp b[ax0], zero
|
||||
ret.z
|
||||
|
||||
mov ax1, ax0
|
||||
@ -49,7 +49,7 @@ strrev2:
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, 0
|
||||
scasb.rep.nz ax1, zero
|
||||
dec ax1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
|
@ -24,7 +24,7 @@ CMDCOM_MAXSZ := 0x80000 ; 512KB
|
||||
;
|
||||
start:
|
||||
mov rsp, DOSKRNL_STACK
|
||||
xor rbp, rbp
|
||||
mov rbp, zero
|
||||
|
||||
call main
|
||||
|
||||
|
@ -2,10 +2,11 @@
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
TrapHandlers.prolog:
|
||||
mov rbp, rsp
|
||||
sub rsp, rsp, 24
|
||||
mov q[rbp-8], r11
|
||||
mov q[rbp-16], r12
|
||||
mov q[rbp-24], r13
|
||||
sub rsp, rbp, 24
|
||||
|
||||
mov rdx, cr2
|
||||
|
||||
@ -16,7 +17,7 @@ TrapHandlers.prolog:
|
||||
|
||||
mov nx0, cr2
|
||||
mov cr2, rdx
|
||||
xor rdx, rdx
|
||||
mov rdx, zero
|
||||
|
||||
jmp rcx
|
||||
|
||||
|
@ -5,7 +5,7 @@ trap0_handler:
|
||||
|
||||
.init:
|
||||
mov rcx, .text
|
||||
mov rbp, TRAP0_STACK
|
||||
mov rsp, TRAP0_STACK
|
||||
jmp TrapHandlers.prolog
|
||||
|
||||
.text:
|
||||
@ -41,7 +41,7 @@ trap0_handler:
|
||||
call DISK.OpenFile
|
||||
|
||||
; Crash on failure
|
||||
cmp rax, 0
|
||||
cmp rax, zero
|
||||
crash.l
|
||||
|
||||
; Load at CMDCOM_LOADP
|
||||
@ -61,23 +61,18 @@ trap0_handler:
|
||||
call DISK.CloseFile
|
||||
|
||||
; Code address
|
||||
xor ax0, ax0
|
||||
mov ax0, zero
|
||||
mov ax1, $rip
|
||||
mov ax2, 0x100000
|
||||
call RFS.StoreReg
|
||||
|
||||
; No flags set
|
||||
mov ax1, $rfx
|
||||
xor ax2, ax2
|
||||
call RFS.StoreReg
|
||||
|
||||
; Usermode
|
||||
mov ax1, $cr0
|
||||
mov ax2, 3
|
||||
call RFS.StoreReg
|
||||
|
||||
mov rcx, CMDCOM_LOADP
|
||||
sub rcx, 0x100000
|
||||
sub rcx, rcx, 0x100000
|
||||
|
||||
; Code offset
|
||||
mov ax1, $cr1
|
||||
@ -90,7 +85,7 @@ trap0_handler:
|
||||
call RFS.StoreReg
|
||||
|
||||
; Return frame
|
||||
mov q[rbp-16], 0
|
||||
mov q[rbp-16], zero
|
||||
|
||||
jmp .fini
|
||||
|
||||
@ -100,17 +95,17 @@ trap0_handler:
|
||||
; Disk API
|
||||
;
|
||||
.handle_FindFirst:
|
||||
add ax0, nx0
|
||||
add ax0, ax0, nx0
|
||||
call DISK.FindFirst
|
||||
jmp .fini
|
||||
|
||||
.handle_FindNext:
|
||||
add ax0, nx0
|
||||
add ax0, ax0, nx0
|
||||
call DISK.FindNext
|
||||
jmp .fini
|
||||
|
||||
.handle_OpenFile:
|
||||
add ax0, nx0
|
||||
add ax0, ax0, nx0
|
||||
call DISK.OpenFile
|
||||
jmp .fini
|
||||
|
||||
@ -119,7 +114,7 @@ trap0_handler:
|
||||
jmp .fini
|
||||
|
||||
.handle_ReadFile:
|
||||
add ax1, nx0
|
||||
add ax1, ax0, nx0
|
||||
call DISK.ReadFile
|
||||
jmp .fini
|
||||
|
||||
@ -127,6 +122,7 @@ trap0_handler:
|
||||
; Misc.
|
||||
;
|
||||
.handle_Shutdown:
|
||||
mov nx0, zero
|
||||
stop
|
||||
|
||||
.handle_HaltMode:
|
||||
@ -135,7 +131,7 @@ trap0_handler:
|
||||
xpause
|
||||
|
||||
scan rax
|
||||
b.z rax, 0, .HLT.loop
|
||||
b.z rax, zero, .HLT.loop
|
||||
|
||||
prn rax
|
||||
jmp .HLT.loop
|
||||
|
@ -23,7 +23,7 @@ InitSyscalls:
|
||||
call RFS.StoreReg
|
||||
|
||||
mov ax1, ax0
|
||||
add ax0, 255 # TRAP no. (ax0 - 1)
|
||||
add ax0, ax0, 255 # TRAP no. (ax0 - 1)
|
||||
call IDT.AddHandler
|
||||
|
||||
ret
|
||||
|
@ -6,7 +6,7 @@ NAME_MAX := 256
|
||||
builtins.dir:
|
||||
push nx0
|
||||
|
||||
xor nx0, nx0 # no. of files found
|
||||
mov nx0, zero # no. of files found
|
||||
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .dirmsg
|
||||
@ -75,7 +75,7 @@ builtins.dir:
|
||||
|
||||
.print_ext.2:
|
||||
; did we print at least 4 bytes?
|
||||
j.cxz .print_bytes ; yes, carry on
|
||||
jmp.cxz .print_bytes ; yes, carry on
|
||||
|
||||
prn.rep ' '
|
||||
|
||||
@ -86,13 +86,13 @@ builtins.dir:
|
||||
prn ' '
|
||||
|
||||
shr rax, rdx, 10
|
||||
and rdx, 1023
|
||||
and rdx, rdx, 1023
|
||||
|
||||
mov ax0, .bytesstr
|
||||
push rdx
|
||||
push rax
|
||||
call printf
|
||||
add rsp, 16
|
||||
add rsp, rsp, 16
|
||||
|
||||
.bytesstr = "%d kilobytes + %d bytes"
|
||||
|
||||
@ -105,7 +105,7 @@ builtins.dir:
|
||||
mov ax0, .endstr1
|
||||
push nx0
|
||||
call printf
|
||||
add rsp, 8
|
||||
add rsp, rsp, 8
|
||||
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .endstr2
|
||||
|
@ -23,9 +23,9 @@ main:
|
||||
stosb.rep rdx, 0
|
||||
|
||||
; iterator through argbuf
|
||||
xor rcx, rcx
|
||||
mov rcx, zero
|
||||
|
||||
mov q[argv1pos], 0
|
||||
mov q[argv1pos], zero
|
||||
|
||||
.input_loop:
|
||||
pause
|
||||
@ -34,18 +34,18 @@ main:
|
||||
|
||||
; Fill .buf with user input
|
||||
scan rax
|
||||
b.z rax, 0, .input_loop
|
||||
b.z rax, zero, .input_loop
|
||||
|
||||
; backspace character?
|
||||
b.nz rax, 8, .handle_input
|
||||
|
||||
; anything to delete?
|
||||
b.z rcx, 0, .input_loop
|
||||
b.z rcx, zero, .input_loop
|
||||
|
||||
; delete it
|
||||
dec rcx
|
||||
add rdx, rcx, argbuf
|
||||
mov b[rdx], 0
|
||||
mov b[rdx], zero
|
||||
|
||||
; update screen
|
||||
cmp b[stdin_echoing], 1
|
||||
@ -73,7 +73,7 @@ main:
|
||||
.extract_argv0:
|
||||
; did we read anything at all?
|
||||
; if not, just go back to waiting input
|
||||
b.z rcx, 0, .print_prompt
|
||||
b.z rcx, zero, .print_prompt
|
||||
|
||||
; find first whitespace or null-terminator
|
||||
mov rcx, argbuf.size
|
||||
@ -82,12 +82,12 @@ main:
|
||||
|
||||
; argv1 exists? if so, save its position
|
||||
mov r11, rdx
|
||||
b.z b[r11], 0, .no_argv1
|
||||
b.z b[r11], zero, .no_argv1
|
||||
inc r11
|
||||
|
||||
.next_space:
|
||||
mov r10, b[r11]
|
||||
b.z r10, 0, .no_argv1
|
||||
b.z r10, zero, .no_argv1
|
||||
|
||||
; skip spaces
|
||||
cmp r10, ' '
|
||||
@ -188,7 +188,7 @@ main:
|
||||
mov ax0, .datefmt
|
||||
call printf
|
||||
|
||||
add rsp, 5*8
|
||||
add rsp, rsp, 5*8
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -216,10 +216,10 @@ main:
|
||||
.handle_PRINT:
|
||||
mov rax, Sys.OpenFile
|
||||
mov ax0, q[argv1pos]
|
||||
b.z ax0, 0, .need_params
|
||||
b.z ax0, zero, .need_params
|
||||
trap 0
|
||||
|
||||
b.l rax, 0, .file_not_found
|
||||
b.l rax, zero, .file_not_found
|
||||
|
||||
mov ax0, rax
|
||||
mov ax1, FILE_LOADP
|
||||
@ -233,8 +233,8 @@ main:
|
||||
mov rax, Sys.CloseFile
|
||||
trap 0
|
||||
|
||||
b.l rax, 0, .couldnt_read
|
||||
b.z rax, 0, .empty_file
|
||||
b.l rax, zero, .couldnt_read
|
||||
b.z rax, zero, .empty_file
|
||||
|
||||
mov rdx, FILE_LOADP
|
||||
prns.rep rdx
|
||||
@ -250,7 +250,7 @@ main:
|
||||
push b[rax+2]
|
||||
mov ax0, .timefmt
|
||||
call printf
|
||||
add rsp, 3*8
|
||||
add rsp, rsp, 3*8
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -318,7 +318,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
add rsp, 16
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -329,7 +329,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
add rsp, 16
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -340,7 +340,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
add rsp, 16
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
|
@ -173,8 +173,9 @@ long cpudev_loadreg(ctx_t *ctx, dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(ax0);
|
||||
|
||||
if ((ushort)ax1 >= NREGS)
|
||||
_except(ctx, E_UDF, "cpudev: register index out of range: #%u", ax1);
|
||||
if ((ushort)ax1 >= NREGS || ax1 == RZX)
|
||||
_except(ctx, E_UDF,
|
||||
"cpudev: register invalid or index out of range: #%u", ax1);
|
||||
|
||||
R(ax1) = rfs[ax0][ax1];
|
||||
|
||||
|
42
vm/in/ALU
42
vm/in/ALU
@ -5,16 +5,6 @@
|
||||
# Logical instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# TEST Comparison instruction
|
||||
#
|
||||
# $1 AND $2
|
||||
#
|
||||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
test r ri
|
||||
|
||||
#
|
||||
# Bitwise NOT operation
|
||||
#
|
||||
@ -31,15 +21,10 @@ not r r
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
or r ri
|
||||
or r r ri
|
||||
or m ri
|
||||
or m r ri
|
||||
|
||||
# $dest = $src1 OR NOT($src2)
|
||||
orn r ri
|
||||
orn r r ri
|
||||
|
||||
# $dest = NOT($src1 OR $src2)
|
||||
nor r r ri
|
||||
|
||||
@ -50,14 +35,9 @@ nor r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
and r rim
|
||||
and r r rim
|
||||
and m ri
|
||||
and m r ri
|
||||
|
||||
and r r ri
|
||||
# $dest = $src1 AND NOT($src2)
|
||||
andn r r ri
|
||||
|
||||
# $dest = NOT($src1 AND $src2)
|
||||
nand r r ri
|
||||
|
||||
@ -68,14 +48,9 @@ nand r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
xor r rim
|
||||
xor r r rim
|
||||
xor m ri
|
||||
xor m r ri
|
||||
|
||||
xor r r ri
|
||||
# $dest = $src1 XOR NOT($src2)
|
||||
xorn r r ri
|
||||
|
||||
# $dest = NOT($src1 XOR $src2)
|
||||
xnor r r ri
|
||||
|
||||
@ -150,7 +125,7 @@ neg r r
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
inc rm
|
||||
inc r
|
||||
|
||||
#
|
||||
# Arithmetical DEC operation
|
||||
@ -159,7 +134,7 @@ inc rm
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
dec rm
|
||||
dec r
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
@ -170,10 +145,7 @@ dec rm
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
add r rim
|
||||
add r r ri
|
||||
add m ri
|
||||
|
||||
addf r r ri
|
||||
addo r r ri
|
||||
|
||||
@ -198,15 +170,9 @@ xadd m r
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sub r rim
|
||||
sub r r ri
|
||||
sub r i r
|
||||
sub m ri
|
||||
|
||||
subf r r ri
|
||||
subf r i r
|
||||
subo r r ri
|
||||
subo r i r
|
||||
|
||||
#
|
||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||
|
25
vm/in/MOV
25
vm/in/MOV
@ -10,7 +10,6 @@
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
j ri
|
||||
jmp ri
|
||||
|
||||
#
|
||||
@ -145,27 +144,3 @@ movzx r m
|
||||
#
|
||||
xchg r rm
|
||||
|
||||
#
|
||||
# Compare-and-exchange (CMPXCHG) instruction
|
||||
#
|
||||
# IF ($1 == RAX) THEN
|
||||
# $1 = $2
|
||||
# ZF = 1
|
||||
# ELSE
|
||||
# RAX = $1
|
||||
# ZF = 0
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
#
|
||||
cmpxchg rm r
|
||||
|
||||
#
|
||||
# 3-operand rotation (ROTd)
|
||||
#
|
||||
# $3 -> $2 -> $1 -> $3 (ROTL)
|
||||
# $1 -> $2 -> $3 -> $1 (ROTR)
|
||||
#
|
||||
rotr rm r r
|
||||
rotl rm r r
|
||||
|
||||
|
20
vm/in/alu.c
20
vm/in/alu.c
@ -9,11 +9,9 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT;
|
||||
IMPL_START_2(test) { rfx &= ~(CF|OF); SET_ZSF(v1 & v2); } IMPL_END;
|
||||
|
||||
IMPL_START_2(or) { ALU_GET_SRCS(); v1 = src1 | src2; } IMPL_OUT;
|
||||
IMPL_START_2(and) { ALU_GET_SRCS(); v1 = src1 & src2; } IMPL_OUT;
|
||||
IMPL_START_2(xor) { ALU_GET_SRCS(); v1 = src1 ^ src2; } IMPL_OUT;
|
||||
IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT;
|
||||
IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT;
|
||||
IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
@ -40,7 +38,7 @@ IMPL_START_1(dec) { v1--; } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_2(add) { ALU_GET_SRCS(); v1 = src1 + src2; } IMPL_OUT;
|
||||
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
|
||||
IMPL_START_2(xadd) { ulong tmp = v1; v1 += v2; v2 = tmp; } IMPL_OUT_2;
|
||||
IMPL_START_3(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT;
|
||||
IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
|
||||
@ -48,16 +46,16 @@ IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_2(cmp) { COMPARE(v1, v2); } IMPL_END;
|
||||
IMPL_START_2(sub) { ALU_GET_SRCS(); v1 = src1 - src2; } IMPL_OUT;
|
||||
IMPL_START_3(sub) { v1 = v2 - v3; } IMPL_OUT;
|
||||
IMPL_START_3(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
||||
IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(rfx&CF); } IMPL_OUT;
|
||||
IMPL_START_3(adox) { v1 = v2 + v3 + !!(rfx&OF); } IMPL_OUT;
|
||||
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(rfx&CF); } IMPL_OUT;
|
||||
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(rfx&OF); } IMPL_OUT;
|
||||
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(R(RFX)&CF); } IMPL_OUT;
|
||||
IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } IMPL_OUT;
|
||||
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(R(RFX)&CF); } IMPL_OUT;
|
||||
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(R(RFX)&OF); } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -35,9 +35,10 @@ uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
|
||||
IMPL_START_0(name) \
|
||||
DECV(v1, p1);
|
||||
|
||||
#define IMPL_START_1_NOIN(name) \
|
||||
#define IMPL_START_X_NOIN(name) \
|
||||
IMPL_START_0(name) \
|
||||
ulong v1;
|
||||
ulong v1, v2, v3; \
|
||||
(void)v1; (void)v2; (void)v3;
|
||||
|
||||
#define IMPL_START_2(name) \
|
||||
IMPL_START_1(name) \
|
||||
@ -82,6 +83,9 @@ IMPL_START_2(name) \
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define INTO() \
|
||||
if (R(RFX) & OF) _except(ctx, E_OVF, "Overflow");
|
||||
|
||||
#define PARITY(v) __builtin_parity(v)
|
||||
|
||||
#define SET_ZF(v) \
|
||||
@ -119,21 +123,6 @@ IMPL_START_2(name) \
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define INTO() \
|
||||
if (R(RFX) & OF) _except(ctx, E_OVF, "Overflow");
|
||||
|
||||
#define ALU_GET_SRCS() \
|
||||
ulong src1, src2; \
|
||||
if (p3) { \
|
||||
src1 = v2; \
|
||||
GETV(src2, p3); \
|
||||
} else { \
|
||||
src1 = v1; \
|
||||
src2 = v2; \
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define CHK_SUPERV() \
|
||||
do { \
|
||||
if ((R(CR0) & UF) > 0) { \
|
||||
|
19
vm/in/misc.c
19
vm/in/misc.c
@ -19,12 +19,14 @@ IMPL_START_0(xpause) { CHK_SUPERV(); usleep(25000); } IMPL_END;
|
||||
|
||||
IMPL_START_0(break)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
trace("\nExecuting BREAK INSTR\n");
|
||||
dumpregs(ctx);
|
||||
|
||||
do_hlt(ctx);
|
||||
|
||||
trace("Resuming execution\n");
|
||||
#endif
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
@ -47,9 +49,9 @@ IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(time) { v1 = time(NULL); } IMPL_OUT;
|
||||
IMPL_START_X_NOIN(time) { v1 = time(NULL); } IMPL_OUT;
|
||||
|
||||
IMPL_START_3(ytime)
|
||||
IMPL_START_X_NOIN(ytime)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm = localtime(&t);
|
||||
@ -129,8 +131,10 @@ IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(prn)
|
||||
IMPL_START_0(prn)
|
||||
{
|
||||
DECVZX(v1, p1);
|
||||
|
||||
// Magic value? :)
|
||||
if (__builtin_expect(v1 == 0xC15000AF, 0))
|
||||
console_clear(ctx);
|
||||
@ -140,7 +144,8 @@ IMPL_START_1(prn)
|
||||
if (p1->mlen > 1) {
|
||||
trace("prn warning: large access size\n");
|
||||
}
|
||||
console_putc(ctx, (char)v1);
|
||||
if (v1 > 0)
|
||||
console_putc(ctx, (char)v1);
|
||||
}
|
||||
}
|
||||
IMPL_END
|
||||
@ -151,11 +156,11 @@ IMPL_START_0(prns)
|
||||
|
||||
COMPARE(ch, 0);
|
||||
|
||||
if ((rfx & ZF) == 0)
|
||||
if ((R(RFX) & ZF) == 0)
|
||||
{
|
||||
console_putc(ctx, ch);
|
||||
|
||||
if (rfx & DF)
|
||||
if (R(RFX) & DF)
|
||||
R(p1->reg)--;
|
||||
else
|
||||
R(p1->reg)++;
|
||||
@ -163,7 +168,7 @@ IMPL_START_0(prns)
|
||||
}
|
||||
IMPL_END
|
||||
|
||||
IMPL_START_1(scan)
|
||||
IMPL_START_X_NOIN(scan)
|
||||
{
|
||||
v1 = console_scankeybuf(ctx);
|
||||
}
|
||||
|
16
vm/in/mov.c
16
vm/in/mov.c
@ -5,7 +5,6 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(j) { R(RIP) = v1; } IMPL_END;
|
||||
IMPL_START_1(jmp) { R(RIP) = v1; } IMPL_END;
|
||||
IMPL_START_1(loop) {
|
||||
if (R(RCX) > 0) {
|
||||
@ -25,23 +24,16 @@ IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1_NOIN(lea) { v1 = p2->addr; } IMPL_OUT;
|
||||
IMPL_START_X_NOIN(lea) { v1 = p2->addr; } IMPL_OUT;
|
||||
IMPL_START_2_ONLY(mov) { v1 = v2; } IMPL_OUT;
|
||||
|
||||
IMPL_START_2_ONLY(movsxb) { v1 = (ulong)(long)(char)(v2 & 0xFF); }IMPL_OUT;
|
||||
IMPL_START_2_ONLY(movsxw) { v1 = (ulong)(long)(short)(v2 & 0xFFFF); }IMPL_OUT;
|
||||
IMPL_START_2_ONLY(movsxl) { v1 = (ulong)(long)(int)(v2 & 0xFFFFFFFF); }IMPL_OUT;
|
||||
|
||||
IMPL_START_1_NOIN(movzx) { DECVZX(v2, p2); v1 = v2; } IMPL_OUT;
|
||||
IMPL_START_X_NOIN(movzx) { DECVZX(v2, p2); v1 = v2; } IMPL_OUT;
|
||||
|
||||
IMPL_START_2(xchg) { ulong t = v1; v1 = v2; v2 = t; } IMPL_OUT_2;
|
||||
IMPL_START_3(rotl) { ulong tmp = v1; v1 = v2; v2 = v3; v3 = tmp; } IMPL_OUT_3;
|
||||
IMPL_START_3(rotr) { ulong tmp = v3; v3 = v2; v2 = v1; v1 = tmp; } IMPL_OUT_3;
|
||||
|
||||
IMPL_START_2(cmpxchg) {
|
||||
if (R(RAX) == v1) { R(RFX) |= ZF; v1 = v2; }
|
||||
else { R(RFX) &= ~ZF; R(RAX) = v1; }
|
||||
} IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
@ -69,10 +61,10 @@ IMPL_START_0(ret) {
|
||||
R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8;
|
||||
} IMPL_END;
|
||||
|
||||
IMPL_START_0(enter) {
|
||||
IMPL_START_1(enter) {
|
||||
writemem(ctx, R(RBP), R(RSP) - 8, 8);
|
||||
R(RBP) = R(RSP) - 8;
|
||||
R(RSP) -= (p1->val + 1) * 8;
|
||||
R(RSP) -= (v1 + 1) * 8;
|
||||
} IMPL_END;
|
||||
|
||||
IMPL_START_0(leave) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define STR_MOVE(reg, len) \
|
||||
if (!(rfx & DF)) R(reg) += len; \
|
||||
if (!(R(RFX) & DF)) R(reg) += len; \
|
||||
else R(reg) -= len;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
@ -45,7 +45,8 @@ IMPL_START_1(trap) {
|
||||
IMPL_START_0(into) { INTO(); } IMPL_END;
|
||||
|
||||
IMPL_START_0(iret) {
|
||||
trace("\nReturning from exception #%ld\n\n", R(R11));
|
||||
if (ctx->dumpsw)
|
||||
trace("\nReturning from exception #%ld\n\n", R(R11));
|
||||
|
||||
// should do more checks
|
||||
R(RIP) = R(R13);
|
||||
@ -63,21 +64,11 @@ dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
||||
{
|
||||
dev_t *dev = devget(ctx, v1);
|
||||
|
||||
if (!dev)
|
||||
rax = -2;
|
||||
|
||||
else if (dev->state == DEVPWOF)
|
||||
rax = -3;
|
||||
|
||||
else if (dev->state == DEVFERR)
|
||||
rax = -4;
|
||||
|
||||
else if (dev->state == DEVPLUG)
|
||||
rax = -5;
|
||||
|
||||
else
|
||||
return dev;
|
||||
|
||||
if (!dev) rax = -2;
|
||||
else if (dev->state == DEVPWOF) rax = -3;
|
||||
else if (dev->state == DEVFERR) rax = -4;
|
||||
else if (dev->state == DEVPLUG) rax = -5;
|
||||
else return dev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -91,35 +82,13 @@ IMPL_START_2(devctl)
|
||||
return 0;
|
||||
|
||||
switch (v2) {
|
||||
case 0:
|
||||
writestr(ctx, ax0, DEVLEN, dev->type);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
writestr(ctx, ax0, DEVLEN, dev->name);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
writestr(ctx, ax0, DEVLEN, dev->modl);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
writestr(ctx, ax0, DEVLEN, dev->vend);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rax = dev->major;
|
||||
rdx = dev->minor;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
rax = dev->feats;
|
||||
rdx = dev->revis;
|
||||
break;
|
||||
|
||||
default:
|
||||
rax = -6;
|
||||
break;
|
||||
case 0: writestr(ctx, ax0, DEVLEN, dev->type); break;
|
||||
case 1: writestr(ctx, ax0, DEVLEN, dev->name); break;
|
||||
case 2: writestr(ctx, ax0, DEVLEN, dev->modl); break;
|
||||
case 3: writestr(ctx, ax0, DEVLEN, dev->vend); break;
|
||||
case 4: rax = dev->major; rdx = dev->minor; break;
|
||||
case 5: rax = dev->feats; rdx = dev->revis; break;
|
||||
default: rax = -6; break;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
@ -131,18 +100,12 @@ IMPL_START_2(iocall)
|
||||
long rc;
|
||||
dev_t *dev = devctl_common(ctx, v1, v2);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
if (v2 >= DEVSLOTS)
|
||||
rax = -6;
|
||||
|
||||
else if (dev->fslots[v2] == NULL)
|
||||
rax = -6;
|
||||
if (dev == NULL) return 0;
|
||||
else if (v2 >= DEVSLOTS || dev->fslots[v2] == NULL) rax = -6;
|
||||
|
||||
else {
|
||||
rc = dev->fslots[v2](ctx, dev);
|
||||
if (rc < 0) rax = rc;
|
||||
if (rc < 0) { rax = rc; rdx = 0; }
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
@ -55,8 +55,8 @@
|
||||
match-empty-string-at-end = "TRUE">
|
||||
|
||||
<!-- KVISC -->
|
||||
<keyword>(inv|flg|[re]pc)</keyword>
|
||||
<keyword>[re][abcdfg]x</keyword>
|
||||
<keyword>(inv|flg|zero|[re]pc)</keyword>
|
||||
<keyword>[re][abcdfgz]x</keyword>
|
||||
<keyword>[re][sd]i</keyword>
|
||||
<keyword>[re][sbi]p</keyword>
|
||||
<keyword>[a-z]x?[0-9]+[bwdlq]?</keyword>
|
||||
|
@ -30,21 +30,13 @@ static void check_param_type(ctx_t *ctx, instr_t *in,
|
||||
//
|
||||
// Verify that access to a certain register is legal
|
||||
//
|
||||
static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
|
||||
static void checkreg(ctx_t *ctx, uint reg)
|
||||
{
|
||||
if (reg >= NREGS)
|
||||
_except(ctx, E_ILL, "Inexistent register: %u", reg);
|
||||
|
||||
if (reg == INV)
|
||||
{
|
||||
if (!inv_is_ok)
|
||||
_except(ctx, E_ILL, "INV dereference");
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->r[reg].flags & RES)
|
||||
//_except(ctx, E_ACC, "Reserved REG: %u", reg);
|
||||
_except(ctx, E_ACC, "Reserved REG: %u", reg);
|
||||
|
||||
if (ctx->r[reg].flags & SYS)
|
||||
if (R(CR0) & UF)
|
||||
@ -64,7 +56,7 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
||||
if (fmt == A_REG)
|
||||
{
|
||||
p->reg = ctx->get(ctx);
|
||||
checkreg(ctx, p->reg, 0);
|
||||
checkreg(ctx, p->reg);
|
||||
|
||||
p->val = R(p->reg);
|
||||
|
||||
@ -83,9 +75,7 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
||||
|
||||
assert(ACC_FMT_IS_MEM(fmt));
|
||||
|
||||
//
|
||||
// Handle a memory access
|
||||
//
|
||||
|
||||
mlen = fmt & AM_MLEN_MASK;
|
||||
mfmt = fmt & AM_MFMT_MASK;
|
||||
@ -114,8 +104,8 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
||||
p->reg1 = temp >> 8;
|
||||
p->reg2 = temp & 0xFF;
|
||||
|
||||
checkreg(ctx, p->reg1, 1);
|
||||
checkreg(ctx, p->reg2, 1);
|
||||
checkreg(ctx, p->reg1);
|
||||
checkreg(ctx, p->reg2);
|
||||
|
||||
if (mfmt == AM_RRI)
|
||||
{
|
||||
@ -149,26 +139,14 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
||||
void decode(ctx_t *ctx)
|
||||
{
|
||||
instr_t *in;
|
||||
|
||||
acc_t p1 = { 0 };
|
||||
acc_t p2 = { 0 };
|
||||
acc_t p3 = { 0 };
|
||||
|
||||
bool rep = 0;
|
||||
bool lock, nomore;
|
||||
|
||||
ushort w1, w2;
|
||||
uchar f1 = 0, f2 = 0, f3 = 0;
|
||||
ushort w1, w2, rep = 0, lock, nomore;
|
||||
acc_t p1 = { 0 }, p2 = { 0 }, p3 = { 0 };
|
||||
|
||||
rpc = R(RIP);
|
||||
|
||||
//
|
||||
// Process the first word of the instruction
|
||||
//
|
||||
w1 = ctx->get(ctx);
|
||||
|
||||
// Extract first word flags
|
||||
|
||||
lock = !!(w1 & SUFF_LOCK);
|
||||
nomore = !!(w1 & SUFF_NOMORE);
|
||||
|
||||
@ -179,22 +157,16 @@ void decode(ctx_t *ctx)
|
||||
|
||||
w1 &= ~(SUFF_LOCK|SUFF_NOMORE|SUFF_COND);
|
||||
|
||||
// Find instruction
|
||||
|
||||
if (w1 >= NINSTRS)
|
||||
{
|
||||
_except(ctx, E_ILL, "No such INSTR: 0x%hX", w1);
|
||||
}
|
||||
|
||||
// Find instruction
|
||||
in = &ctx->i[w1];
|
||||
ctx->cur_in = in;
|
||||
|
||||
// Second word?
|
||||
if (!nomore)
|
||||
{
|
||||
//
|
||||
// Process second word
|
||||
//
|
||||
|
||||
w2 = ctx->get(ctx);
|
||||
|
||||
// REP and COND
|
||||
@ -206,18 +178,13 @@ void decode(ctx_t *ctx)
|
||||
f1 = w2 & Fx_MASK;
|
||||
}
|
||||
|
||||
//
|
||||
// Deal with operand 1
|
||||
//
|
||||
|
||||
// Operand 1?
|
||||
if (in->prm1 == NOPRM)
|
||||
{
|
||||
if (f1 || f2 || f3)
|
||||
{
|
||||
_except(ctx, E_ILL,
|
||||
"FTn (%u,%u,%u) filled for 0-param INSTR '%s'",
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
|
||||
return;
|
||||
@ -226,18 +193,13 @@ void decode(ctx_t *ctx)
|
||||
check_param_type(ctx, in, in->prm1, f1, 1);
|
||||
extract_param(ctx, &p1, f1);
|
||||
|
||||
//
|
||||
// Deal with operand 2
|
||||
//
|
||||
|
||||
// Operand 2?
|
||||
if (in->prm2 == NOPRM)
|
||||
{
|
||||
if (f2 || f3)
|
||||
{
|
||||
_except(ctx, E_ILL,
|
||||
"FT3/FT2 (%u,%u,%u) filled for 1-param INSTR '%s'",
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
|
||||
return;
|
||||
@ -246,18 +208,13 @@ void decode(ctx_t *ctx)
|
||||
check_param_type(ctx, in, in->prm2, f2, 2);
|
||||
extract_param(ctx, &p2, f2);
|
||||
|
||||
//
|
||||
// Deal with operand 3
|
||||
//
|
||||
|
||||
// Operand 1?
|
||||
if (in->prm3 == NOPRM)
|
||||
{
|
||||
if (f3)
|
||||
{
|
||||
_except(ctx, E_ILL,
|
||||
"FT3 (%u,%u,%u) filled for 2-param INSTR '%s'",
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
|
||||
return;
|
||||
|
@ -8,8 +8,6 @@ void die(int code)
|
||||
{
|
||||
dying = 1;
|
||||
|
||||
enable_stdin_echoing();
|
||||
|
||||
if (main_ctx.mp)
|
||||
free(main_ctx.mp);
|
||||
|
||||
|
@ -14,14 +14,6 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
|
||||
ulong orig_frame;
|
||||
|
||||
trace("\nException %u - ", code);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vlog(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
trace("\n\n");
|
||||
|
||||
//
|
||||
// Interrupted earlier?
|
||||
//
|
||||
@ -29,7 +21,6 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
if (dying)
|
||||
{
|
||||
logerr("Exception thrown while dying=1\n");
|
||||
enable_stdin_echoing();
|
||||
exit(-12);
|
||||
}
|
||||
|
||||
@ -82,6 +73,17 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
// Is this a valid frame?
|
||||
if (rfs[handler] != NULL)
|
||||
{
|
||||
if (ctx->dumpsw)
|
||||
{
|
||||
trace("\nException %u - ", code);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vlog(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
trace("\n\n");
|
||||
}
|
||||
|
||||
orig_frame = rfs_current_idx;
|
||||
|
||||
ctx->rf = rfs[handler];
|
||||
@ -101,11 +103,18 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
}
|
||||
|
||||
actually_die:
|
||||
logerr("\nException %u - ", code);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vlog(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
logerr("\n\n");
|
||||
|
||||
dying = 1;
|
||||
|
||||
dumpregs(ctx);
|
||||
trace("\n");
|
||||
logerr("\n");
|
||||
|
||||
die(code);
|
||||
}
|
||||
|
25
vm/pc/exec.c
25
vm/pc/exec.c
@ -4,6 +4,8 @@
|
||||
#include <pc/arch.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
#define rfx R(RFX)
|
||||
|
||||
bool eval_cond(ctx_t *ctx, uint cond)
|
||||
{
|
||||
bool neg = cond & (1 << 4);
|
||||
@ -42,6 +44,16 @@ bool eval_cond(ctx_t *ctx, uint cond)
|
||||
return neg ? !ok : !!ok;
|
||||
}
|
||||
|
||||
#define OUTPUT(p, r) { \
|
||||
if (p->type == A_REG) \
|
||||
R(p->reg) = r; \
|
||||
else if (p1->type == A_IMM64) \
|
||||
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
|
||||
else { \
|
||||
assert(ACC_IS_MEM(p)); \
|
||||
writemem(ctx, r, p->addr, p->mlen); \
|
||||
} }
|
||||
|
||||
//
|
||||
// Executes an instruction
|
||||
//
|
||||
@ -75,25 +87,16 @@ void exec_instr(ctx_t *ctx,
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep);
|
||||
|
||||
do_rep:
|
||||
assert(R(RZX) == 0);
|
||||
|
||||
out = in->func(ctx, p1, p2, p3, &r1, &r2, &r3);
|
||||
|
||||
#define OUTPUT(p, r) { \
|
||||
if (p->type == A_REG) \
|
||||
R(p->reg) = r; \
|
||||
else if (p1->type == A_IMM64) \
|
||||
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
|
||||
else { \
|
||||
assert(ACC_IS_MEM(p)); \
|
||||
writemem(ctx, r, p->addr, p->mlen); \
|
||||
} }
|
||||
|
||||
|
||||
if (out)
|
||||
{
|
||||
OUTPUT(p1, r1);
|
||||
if (out >= 2) OUTPUT(p2, r2);
|
||||
if (out >= 3) OUTPUT(p3, r3);
|
||||
R(RZX) = 0;
|
||||
}
|
||||
|
||||
if (rep)
|
||||
|
@ -25,6 +25,6 @@ void logerr(const char *fmt, ...)
|
||||
|
||||
void vlog(const char *fmt, va_list ap)
|
||||
{
|
||||
vfprintf(stdout, fmt, ap);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ jmp_buf exc_jmp_buf;
|
||||
//
|
||||
void main_loop(void)
|
||||
{
|
||||
trace("\n\n\n");
|
||||
if (main_ctx.dumpsw)
|
||||
trace("\n\n\n");
|
||||
|
||||
setjmp(exc_jmp_buf);
|
||||
|
||||
@ -77,7 +78,7 @@ int main(int argc, char **argv)
|
||||
main_ctx.r = arch_r;
|
||||
main_ctx.i = arch_i;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if 0 && defined(NDEBUG)
|
||||
main_ctx.dumpsw = 1;
|
||||
#endif
|
||||
|
||||
@ -166,7 +167,6 @@ int main(int argc, char **argv)
|
||||
// To be moved to some screen device
|
||||
console_init(&main_ctx);
|
||||
|
||||
disable_stdin_echoing();
|
||||
main_loop();
|
||||
}
|
||||
|
||||
|
44
vm/pc/regs.c
44
vm/pc/regs.c
@ -5,7 +5,7 @@
|
||||
|
||||
reg_t arch_r[] =
|
||||
{
|
||||
{ "inv", RES }, { "fc1", RES }, { "cr0", SYS }, { "cr1", SYS },
|
||||
{ "zero", GPR }, { "fc1", RES }, { "cr0", SYS }, { "cr1", SYS },
|
||||
{ "cr2", SYS }, { "cr3", SYS }, { "cr4", SYS }, { "trp", GPR },
|
||||
|
||||
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
|
||||
@ -21,34 +21,36 @@ reg_t arch_r[] =
|
||||
|
||||
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
|
||||
|
||||
#define TRACE logerr
|
||||
|
||||
void dumpregs(ctx_t *ctx)
|
||||
{
|
||||
trace("Current RFRAME index: #%lu", rfs_current_idx);
|
||||
TRACE("Current RFRAME index: #%lu", rfs_current_idx);
|
||||
|
||||
trace("\n\nEnviron:");
|
||||
trace("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
|
||||
trace("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
|
||||
TRACE("\n\nEnviron:");
|
||||
TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
|
||||
TRACE("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
|
||||
|
||||
trace("\n\nControl:");
|
||||
trace("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
|
||||
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu", fc0, fc1, fc2);
|
||||
TRACE("\n\nControl:");
|
||||
TRACE("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
|
||||
TRACE("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu", fc0, fc1, fc2);
|
||||
|
||||
trace("\n\nArgument:");
|
||||
trace("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
|
||||
trace("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
|
||||
TRACE("\n\nArgument:");
|
||||
TRACE("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
|
||||
TRACE("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
|
||||
|
||||
trace("\n\nVolatile:");
|
||||
trace("\nrax=0x%-16lX rcx=0x%-16lX rdx=0x%-16lX", R(RAX), R(RCX), R(RDX));
|
||||
trace("\nr10=0x%-16lX r11=0x%-16lX r12=0x%-16lX", R(R10), R(R11), R(R12));
|
||||
trace("\nr13=0x%-16lX r14=0x%-16lX r15=0x%-16lX", R(R13), R(R14), R(R15));
|
||||
TRACE("\n\nVolatile:");
|
||||
TRACE("\nrax=0x%-16lX rcx=0x%-16lX rdx=0x%-16lX", R(RAX), R(RCX), R(RDX));
|
||||
TRACE("\nr10=0x%-16lX r11=0x%-16lX r12=0x%-16lX", R(R10), R(R11), R(R12));
|
||||
TRACE("\nr13=0x%-16lX r14=0x%-16lX r15=0x%-16lX", R(R13), R(R14), R(R15));
|
||||
|
||||
trace("\n\nPersistent:");
|
||||
trace("\nrbx=0x%-16lX rdi=0x%-16lX rsi=0x%-16lX", R(RBX), R(RDI), R(RSI));
|
||||
trace("\nnx0=0x%-16lX nx1=0x%-16lX nx2=0x%-16lX", R(NX0), R(NX1), R(NX2));
|
||||
trace("\nnx3=0x%-16lX nx4=0x%-16lX nx5=0x%-16lX", R(NX3), R(NX4), R(NX5));
|
||||
TRACE("\n\nPersistent:");
|
||||
TRACE("\nrbx=0x%-16lX rdi=0x%-16lX rsi=0x%-16lX", R(RBX), R(RDI), R(RSI));
|
||||
TRACE("\nnx0=0x%-16lX nx1=0x%-16lX nx2=0x%-16lX", R(NX0), R(NX1), R(NX2));
|
||||
TRACE("\nnx3=0x%-16lX nx4=0x%-16lX nx5=0x%-16lX", R(NX3), R(NX4), R(NX5));
|
||||
|
||||
trace("\n");
|
||||
TRACE("\n");
|
||||
|
||||
assert(R(INV) == 0);
|
||||
assert(R(RZX) == 0);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct reg_t
|
||||
|
||||
enum
|
||||
{
|
||||
INV, FC1, CR0, CR1, CR2, CR3, CR4, TRP,
|
||||
RZX, FC1, CR0, CR1, CR2, CR3, CR4, TRP,
|
||||
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
|
||||
RFX, RIP, R10, R11, R12, R13, R14, R15,
|
||||
AX0, AX1, AX2, AX3, AX4, AX5, AX6, AX7,
|
||||
@ -51,7 +51,6 @@ enum
|
||||
#define rpc ctx->cur_pc
|
||||
|
||||
#define fc1 R(FC1)
|
||||
#define rfx R(RFX)
|
||||
|
||||
#define rax R(RAX)
|
||||
#define rdx R(RDX)
|
||||
|
23
vm/pc/tmio.c
23
vm/pc/tmio.c
@ -1,23 +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.
|
||||
|
||||
#include <termio.h>
|
||||
|
||||
void enable_stdin_echoing(void)
|
||||
{
|
||||
struct termios t;
|
||||
tcgetattr(0, &t);
|
||||
t.c_lflag |= ECHO;
|
||||
tcsetattr(0, TCSANOW, &t);
|
||||
}
|
||||
|
||||
void disable_stdin_echoing(void)
|
||||
{
|
||||
return;
|
||||
|
||||
struct termios t;
|
||||
tcgetattr(0, &t);
|
||||
t.c_lflag &= ~ECHO;
|
||||
tcsetattr(0, TCSANOW, &t);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user