mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
stuff
This commit is contained in:
parent
cf7f261eb7
commit
3d002108a4
@ -438,9 +438,6 @@ pref2len = {
|
||||
}
|
||||
|
||||
i_aliases = {
|
||||
"j_1" : "jmp_1",
|
||||
"m_2" : "mov_2",
|
||||
"b_3" : "bch_3",
|
||||
"inc_2" : "add_2",
|
||||
"dec_2" : "sub_2",
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ include "crt/fmt/format.k"
|
||||
include "crt/str/string.k"
|
||||
include "crt/mem/memory.k"
|
||||
include "crt/lib/time.k"
|
||||
include "crt/lib/arith128.k"
|
||||
|
||||
abort:
|
||||
crash
|
||||
|
@ -26,7 +26,7 @@ doprnt:
|
||||
|
||||
; everything below r13 is a regular character; print it
|
||||
.print_regular:
|
||||
b.z r12, r13, .check_modf
|
||||
beq r12, r13, .check_modf
|
||||
|
||||
call .doput, b[r12]
|
||||
|
||||
@ -36,20 +36,20 @@ doprnt:
|
||||
.check_modf:
|
||||
; did we find a '%' ?
|
||||
; if not, then we found fmt's null-terminator; we're done
|
||||
b.nz b[r12], '%', .epilogue
|
||||
bne b[r12], '%', .epilogue
|
||||
|
||||
; we did find a modifier / '%'
|
||||
mov rax, b[r12+1]
|
||||
inc r12, 2
|
||||
|
||||
b.z rax, 's', .modf_s
|
||||
b.z rax, 'c', .modf_c
|
||||
b.z rax, 'p', .modf_p
|
||||
b.z rax, 'x', .modf_x
|
||||
b.z rax, 'd', .modf_d
|
||||
b.z rax, 'o', .modf_o
|
||||
b.z rax, 'b', .modf_b
|
||||
b.z rax, '%', .modf_percent
|
||||
beq rax, 's', .modf_s
|
||||
beq rax, 'c', .modf_c
|
||||
beq rax, 'p', .modf_p
|
||||
beq rax, 'x', .modf_x
|
||||
beq rax, 'd', .modf_d
|
||||
beq rax, 'o', .modf_o
|
||||
beq rax, 'b', .modf_b
|
||||
beq rax, '%', .modf_percent
|
||||
|
||||
; unrecognized
|
||||
jmp .bad_modifier
|
||||
@ -59,11 +59,11 @@ doprnt:
|
||||
mov r13, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
b.z r13, zero, .nullstring
|
||||
bzr r13, .nullstring
|
||||
|
||||
.print_string:
|
||||
mov ax0, b[r13]
|
||||
b.z ax0, zero, .main_loop
|
||||
bzr ax0, .main_loop
|
||||
|
||||
inc r13, 1
|
||||
call .doput
|
||||
@ -109,14 +109,16 @@ doprnt:
|
||||
.print_itoa_buf:
|
||||
mov ax0, b[r13]
|
||||
|
||||
cmp ax0, zero
|
||||
inc.z rsp, 80
|
||||
jmp.z .main_loop
|
||||
|
||||
bzr ax0, .pib_end_loop
|
||||
inc r13, 1
|
||||
|
||||
call .doput
|
||||
jmp .print_itoa_buf
|
||||
|
||||
.pib_end_loop:
|
||||
inc rsp, 80
|
||||
jmp .main_loop
|
||||
|
||||
.modf_percent:
|
||||
call .doput, '%'
|
||||
jmp .main_loop
|
||||
@ -158,15 +160,18 @@ 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
|
||||
cmp r15, zero
|
||||
ret.z
|
||||
bzr r15, .r
|
||||
|
||||
; decrement n and print
|
||||
dec r15, 1
|
||||
call r17
|
||||
|
||||
; did putc fail?
|
||||
mov.axnz r15, zero ; yes, so artificially set n=0
|
||||
jraxz .r
|
||||
|
||||
; yes, so artificially set n=0
|
||||
mov r15, zero
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
|
@ -23,27 +23,29 @@ ltostr:
|
||||
mov rcx, zero
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
b.b ax2, 2, .bad
|
||||
b.a ax2, 36, .bad
|
||||
bltu ax2, 2, .bad
|
||||
bltu 36, ax2, .bad
|
||||
|
||||
; deal with zero
|
||||
b.z ax1, zero, .is_zero
|
||||
bzr ax1, .is_zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
b.z ax3, zero, .conv
|
||||
b.nz ax2, 10, .conv ; base 10
|
||||
bzr ax3, .conv
|
||||
bne ax2, 10, .conv ; base 10
|
||||
|
||||
shr rcx, ax1, 63 ; extract ax1 sign
|
||||
sub.cxnz ax1, zero, ax1 ; NEG if negative
|
||||
jrcxz .conv
|
||||
|
||||
sub ax1, zero, ax1 ; NEG if negative
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
b.z ax1, zero, .fini
|
||||
bzr ax1, .fini
|
||||
|
||||
rem rdx, ax1, ax2 ; ax1 % base
|
||||
|
||||
b.a rdx, 9, .nondec ; rdx > 9 ?
|
||||
blt 9, rdx, .nondec ; rdx > 9 ?
|
||||
|
||||
inc rdx, '0'
|
||||
jmp .next
|
||||
@ -61,13 +63,14 @@ ltostr:
|
||||
|
||||
; add minus flag, null-terminate and reverse
|
||||
.fini:
|
||||
mov.cxnz b[ax0], '-'
|
||||
inc.cxnz ax0, 1
|
||||
jrcxz .cxz
|
||||
mov b[ax0], '-'
|
||||
inc ax0, 1
|
||||
|
||||
.cxz:
|
||||
mov b[ax0], zero
|
||||
|
||||
call strrev2, rax
|
||||
|
||||
ret
|
||||
|
||||
;
|
||||
|
@ -33,10 +33,16 @@ nprintf:
|
||||
; Guaranteed to only affect rcx and ax0
|
||||
;
|
||||
print:
|
||||
mov rcx, STRLEN_MAX
|
||||
b.z b[ax0], zero, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
.l:
|
||||
movzx rax, b[ax0]
|
||||
jraxz .r
|
||||
|
||||
prn rax
|
||||
inc ax0, 1
|
||||
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
@ -44,8 +50,12 @@ print:
|
||||
;
|
||||
nprint:
|
||||
mov rcx, ax1
|
||||
b.z b[ax0], zero, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
prn b[ax0]
|
||||
inc ax0, 1
|
||||
loop .l
|
||||
.r:
|
||||
ret
|
||||
|
||||
|
@ -28,49 +28,49 @@ strtoul:
|
||||
;
|
||||
strtoq:
|
||||
mov rax, zero
|
||||
mov rsi, zero
|
||||
mov rdx, ax0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
b.z ax1, 1, .bad
|
||||
b.a ax1, 36, .bad
|
||||
beq ax1, 1, .bad
|
||||
bltu 36, ax1, .bad
|
||||
|
||||
; empty string?
|
||||
b.z b[rdx], zero, .done
|
||||
bzr b[rdx], .done
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
inc.z rdx, 1
|
||||
jmp.z .skip_spc
|
||||
bne b[rdx], ' ', .no_spc
|
||||
inc rdx, 1
|
||||
jmp .skip_spc
|
||||
|
||||
.no_spc:
|
||||
; skip +
|
||||
cmp b[rdx], '+'
|
||||
inc.z rdx, 1
|
||||
bne b[rdx], '+', .no_plus
|
||||
inc rdx, 1
|
||||
|
||||
; signed?
|
||||
cmp ax2, zero
|
||||
mov.z rsi, zero
|
||||
jmp.z .unsigned
|
||||
.no_plus:
|
||||
; unsigned?
|
||||
bzr ax2, .unsigned
|
||||
|
||||
; parse '-'
|
||||
cmp b[rdx], '-'
|
||||
inc.z rdx, 1
|
||||
mov.z rsi, 1
|
||||
mov.nz rsi, zero
|
||||
bne b[rdx], '-', .unsigned
|
||||
inc rdx, 1
|
||||
mov rsi, 1
|
||||
|
||||
.unsigned:
|
||||
; base 0
|
||||
b.z ax1, 0, .base_0
|
||||
bzr ax1, .base_0
|
||||
|
||||
; base prefix?
|
||||
b.nz b[rdx], '0', .main_loop
|
||||
bne b[rdx], '0', .main_loop
|
||||
|
||||
inc rdx, 1
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
jmp.cxz .done ; "0"
|
||||
b.z rcx, 'x', .parsed_0x
|
||||
b.z rcx, 'b', .parsed_0b
|
||||
jrcxz .done ; "0"
|
||||
beq rcx, 'x', .parsed_0x
|
||||
beq rcx, 'b', .parsed_0b
|
||||
|
||||
; may be octal, but we don't care
|
||||
; we accept "0110101010" (despite base=2) for instance
|
||||
@ -79,7 +79,7 @@ strtoq:
|
||||
.parsed_0x:
|
||||
; are we in base 16?
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
b.nz ax1, 16, .done
|
||||
bne ax1, 16, .done
|
||||
; else
|
||||
inc rdx, 1
|
||||
jmp .main_loop
|
||||
@ -87,7 +87,7 @@ strtoq:
|
||||
.parsed_0b:
|
||||
; are we in base 2?
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
b.nz ax1, 2, .done
|
||||
bne ax1, 2, .done
|
||||
; else
|
||||
inc rdx, 1
|
||||
jmp .main_loop
|
||||
@ -95,47 +95,59 @@ strtoq:
|
||||
.base_0:
|
||||
; guess base
|
||||
|
||||
cmp b[rdx], '0'
|
||||
mov.nz ax1, 10
|
||||
jmp.nz .main_loop
|
||||
beq b[rdx], '0', .b0_not10
|
||||
|
||||
; must be base 10
|
||||
mov ax1, 10
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not10:
|
||||
inc rdx, 1
|
||||
|
||||
cmp b[rdx], 'x'
|
||||
inc.z rdx, 1
|
||||
mov.z ax1, 16
|
||||
jmp.z .main_loop
|
||||
bne b[rdx], 'x', .b0_not16
|
||||
inc rdx, 1
|
||||
mov ax1, 16
|
||||
jmp .main_loop
|
||||
|
||||
cmp b[rdx], 'b'
|
||||
inc.z rdx, 1
|
||||
mov.z ax1, 2
|
||||
jmp.z .main_loop
|
||||
.b0_not16:
|
||||
bne b[rdx], 'b', .b0_not2
|
||||
inc rdx, 1
|
||||
mov ax1, 2
|
||||
jmp .main_loop
|
||||
|
||||
.b0_not2:
|
||||
; take octal by default
|
||||
mov ax1, 8
|
||||
|
||||
.main_loop:
|
||||
movzx rcx, b[rdx]
|
||||
inc rdx, 1
|
||||
|
||||
cmp rcx, '0'
|
||||
jmp.b .done
|
||||
cmp.ae rcx, '9'
|
||||
dec.be rcx, '0'
|
||||
jmp.be .next
|
||||
; between 0 and 9?
|
||||
bltu rcx, '0', .done
|
||||
bltu '9', rcx, .not_digit10
|
||||
|
||||
cmp rcx, 'A'
|
||||
cmp.ae rcx, 'Z'
|
||||
dec.be rcx, 55 ; 'A' - 10
|
||||
jmp.be .next
|
||||
; yes
|
||||
dec rcx, '0'
|
||||
jmp .next
|
||||
|
||||
cmp rcx, 'a'
|
||||
jmp.b .next
|
||||
cmp.ae rcx, 'z'
|
||||
dec.be rcx, 87 ; 'a' - 10
|
||||
jmp.be .next
|
||||
.not_digit10:
|
||||
bltu rcx, 'A', .done
|
||||
bltu 'Z', rcx, .not_digitAZ
|
||||
|
||||
dec rcx, 55 ; 'A' - 10
|
||||
jmp .next
|
||||
|
||||
.not_digitAZ:
|
||||
bltu rcx, 'a', .done
|
||||
bltu 'z', rcx, .done
|
||||
|
||||
dec rcx, 87 ; 'a' - 10
|
||||
jmp .next
|
||||
|
||||
.next:
|
||||
; too large for base?
|
||||
b.ae rcx, ax1, .done
|
||||
blteu ax1, rcx, .done
|
||||
|
||||
mul rax, ax1
|
||||
inc rax, rcx
|
||||
@ -143,11 +155,12 @@ strtoq:
|
||||
|
||||
.done:
|
||||
; negative?
|
||||
cmp rsi, zero
|
||||
ret.z
|
||||
bzr rsi, .r
|
||||
|
||||
; yes
|
||||
sub rax, zero, rax
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
.bad:
|
||||
|
@ -1,59 +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.
|
||||
|
||||
;
|
||||
; int:int add_lq_q(int:int x, int y)
|
||||
;
|
||||
add_lq_q:
|
||||
addf rax, ax0, ax2
|
||||
adcx rdx, ax1, zero
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int add_lq_lq(int:int x, int:int y)
|
||||
;
|
||||
add_lq_lq:
|
||||
addf rax, ax0, ax2
|
||||
adcx rdx, ax1, ax3
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int sub_lq_q(int:int x, int y)
|
||||
;
|
||||
sub_lq_q:
|
||||
subf rax, ax0, ax2
|
||||
sbbx rdx, ax1, zero
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int sub_q_lq(int x, int:int y)
|
||||
;
|
||||
sub_q_lq:
|
||||
subf rax, ax0, ax1
|
||||
sbbx rdx, zero, ax2
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int sub_lq_lq(int:int x, int:int y)
|
||||
;
|
||||
sub_lq_lq:
|
||||
subf rax, ax0, ax2
|
||||
sbbx rdx, ax1, ax3
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int mul_q_q(int x, int y)
|
||||
;
|
||||
mul_q_q:
|
||||
mov rax, ax0
|
||||
mulhi rdx, rax, ax1
|
||||
ret
|
||||
|
||||
;
|
||||
; int:int imul_q_q(int x, int y)
|
||||
;
|
||||
imul_q_q:
|
||||
mov rax, ax0
|
||||
imulhi rdx, rax, ax1
|
||||
ret
|
||||
|
@ -25,15 +25,15 @@ DaysInYear:
|
||||
|
||||
; divisible by 4?
|
||||
rem rcx, ax0, 4
|
||||
jmp.cxnz .end
|
||||
jrcxnz .end
|
||||
|
||||
; divisible by 100?
|
||||
rem rcx, ax0, 100
|
||||
jmp.cxnz .leap
|
||||
jrcxnz .leap
|
||||
|
||||
; divisible by 400?
|
||||
rem rcx, ax0, 400
|
||||
jmp.cxnz .end
|
||||
jrcxnz .end
|
||||
|
||||
.leap:
|
||||
inc rax, 1
|
||||
|
@ -1,16 +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.
|
||||
|
||||
;
|
||||
; void memcpy(void *, const void *, int)
|
||||
;
|
||||
memcpy:
|
||||
mov rcx, ax2
|
||||
ret.cxz
|
||||
|
||||
.l:
|
||||
sub rdx, ax2, rcx
|
||||
mov b[ax0+rdx], b[ax1+rdx]
|
||||
loop .l
|
||||
ret
|
||||
|
@ -1,5 +1,34 @@
|
||||
; 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 "crt/mem/memcpy.k"
|
||||
;
|
||||
; void memcpy(void *, const void *, int)
|
||||
;
|
||||
memcpy:
|
||||
mov rcx, ax2
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
sub rdx, ax2, rcx
|
||||
mov b[ax0+rdx], b[ax1+rdx]
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; void memzero(void *, int)
|
||||
;
|
||||
memzero:
|
||||
mov rcx, ax1
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
mov b[ax0], zero
|
||||
inc ax0, 1
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
|
||||
|
@ -18,9 +18,10 @@ strchr:
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax0, ax1
|
||||
|
||||
cmp b[ax0], zero
|
||||
mov.z rax, zero
|
||||
ret.z
|
||||
bnz b[ax0], .r
|
||||
mov rax, zero
|
||||
ret
|
||||
|
||||
.r:
|
||||
mov rax, ax0
|
||||
ret
|
||||
|
@ -10,19 +10,18 @@
|
||||
; <0 if the first character that does not match has a lower value in str1 than in str2
|
||||
;
|
||||
strcmp:
|
||||
mov rcx, zero
|
||||
mov rsi, zero
|
||||
.l:
|
||||
movzx rax, b[ax0+rcx]
|
||||
movzx rdx, b[ax1+rcx]
|
||||
movzx rax, b[ax0+rsi]
|
||||
movzx rdx, b[ax1+rsi]
|
||||
|
||||
cmp rax, rdx
|
||||
jmp.nz .r
|
||||
bne rax, rdx, .r
|
||||
|
||||
; both zero?
|
||||
add rbx, rax, rdx
|
||||
jmp.bxz .r
|
||||
add rcx, rax, rdx
|
||||
jrcxz .r
|
||||
|
||||
inc rcx, 1
|
||||
inc rsi, 1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
@ -34,14 +33,13 @@ strcmp:
|
||||
;
|
||||
strncmp:
|
||||
mov rcx, ax2
|
||||
jmp.cxz .r
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
movzx rax, b[ax0]
|
||||
movzx rdx, b[ax1]
|
||||
|
||||
cmp rax, rdx
|
||||
jmp.nz .r
|
||||
bne rax, rdx, .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
@ -9,19 +9,22 @@ strcpy:
|
||||
mov rcx, b[ax1]
|
||||
mov b[ax0], rcx
|
||||
|
||||
ret.cxz
|
||||
jrcxz .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
; void strncpy(char *, const char *, int)
|
||||
;
|
||||
strncpy:
|
||||
mov rcx, ax2
|
||||
ret.cxz
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
mov b[ax0], b[ax1]
|
||||
@ -30,6 +33,8 @@ strncpy:
|
||||
inc ax1, 1
|
||||
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
ret
|
||||
|
||||
;
|
||||
@ -37,13 +42,13 @@ strncpy:
|
||||
;
|
||||
strnzcpy:
|
||||
mov rcx, ax2
|
||||
ret.cxz
|
||||
jrcxz .r
|
||||
|
||||
.l:
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
|
||||
jmp.axz .r
|
||||
jraxz .r
|
||||
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
@ -7,9 +7,7 @@
|
||||
; buf and src must NOT overlap
|
||||
;
|
||||
strrev:
|
||||
cmp b[ax1], zero
|
||||
mov.z b[ax0], zero
|
||||
ret.z
|
||||
bzr b[ax1], .z
|
||||
|
||||
; save str's location
|
||||
mov rsi, ax1
|
||||
@ -20,19 +18,24 @@ strrev:
|
||||
scasb.rep.nz ax1, zero
|
||||
dec ax1, 1
|
||||
|
||||
.2:
|
||||
.l:
|
||||
; copy, going backward though str
|
||||
; and forward through buf
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
cmp ax1, rsi
|
||||
mov.z b[ax0+1], zero
|
||||
ret.z
|
||||
beq ax1, rsi, .r
|
||||
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
jmp .2
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
mov b[ax0+1], zero
|
||||
ret
|
||||
|
||||
.z:
|
||||
mov b[ax0], zero
|
||||
ret
|
||||
|
||||
;
|
||||
; void strrev2(char *str)
|
||||
@ -40,8 +43,7 @@ strrev:
|
||||
; Inverses str
|
||||
;
|
||||
strrev2:
|
||||
cmp b[ax0], zero
|
||||
ret.z
|
||||
bzr b[ax0], .r
|
||||
|
||||
mov ax1, ax0
|
||||
|
||||
@ -52,16 +54,16 @@ strrev2:
|
||||
dec ax1, 1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
b.ae ax0, ax1, .3
|
||||
.l:
|
||||
blteu ax1, ax0, .r
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
jmp .2
|
||||
jmp .l
|
||||
|
||||
.3:
|
||||
.r:
|
||||
ret
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ start:
|
||||
mov rsp, DOSKRNL_STACK
|
||||
mov rbp, zero
|
||||
|
||||
;dump
|
||||
; dump
|
||||
|
||||
call main
|
||||
|
||||
|
@ -13,12 +13,12 @@ ScreenOfDeath:
|
||||
call printf, .scr1
|
||||
pop zero
|
||||
|
||||
b.nz r14, zero, .not_con
|
||||
bnz r14, .not_con
|
||||
push .scr2_con
|
||||
jmp .do_print
|
||||
|
||||
.not_con:
|
||||
b.l r14, 4, .not_krn
|
||||
blt r14, 4, .not_krn
|
||||
push .scr2_krn
|
||||
jmp .do_print
|
||||
|
||||
@ -40,10 +40,10 @@ ScreenOfDeath:
|
||||
pause
|
||||
|
||||
scan rax
|
||||
jmp.axz .loop
|
||||
jraxz .loop
|
||||
|
||||
b.z rax, 0x0A, DefaultTrapHandler.handle_Exit
|
||||
b.z rax, 0x1B, DefaultTrapHandler.handle_Shutdown
|
||||
beq rax, 0x0A, DefaultTrapHandler.handle_Exit
|
||||
beq rax, 0x1B, DefaultTrapHandler.handle_Shutdown
|
||||
|
||||
jmp .loop
|
||||
|
||||
|
@ -5,8 +5,8 @@ DefaultExceptionHandler:
|
||||
mov rsp, EXCT0_STACK
|
||||
mov ax1, r12
|
||||
|
||||
b.z r12, zero, DefaultTrapHandler.handle_Shutdown
|
||||
b.a r12, 11, .unknown
|
||||
bzr r12, DefaultTrapHandler.handle_Shutdown
|
||||
bltu 11, r12, .unknown
|
||||
|
||||
mov rsi, .err_ukn
|
||||
lea ax0, b[rsi + r12 * 32]
|
||||
|
@ -40,16 +40,16 @@ DefaultTrapHandler:
|
||||
call RFS.LoadReg, r14, $rax
|
||||
call RFS.LoadArgs, r14
|
||||
|
||||
jmp.axz .handle_Shutdown
|
||||
b.z rax, Sys.Exit, .handle_Exit
|
||||
b.z rax, Sys.ReadFile, .handle_ReadFile
|
||||
b.z rax, Sys.OpenFile, .handle_OpenFile
|
||||
b.z rax, Sys.CloseFile, .handle_CloseFile
|
||||
b.z rax, Sys.CreateFile, .handle_CreateFile
|
||||
b.z rax, Sys.RemoveFile, .handle_RemoveFile
|
||||
b.z rax, Sys.FindNext, .handle_FindNext
|
||||
b.z rax, Sys.FindFirst, .handle_FindFirst
|
||||
b.z rax, Sys.EnterHaltMode, .handle_HaltMode
|
||||
jraxz .handle_Shutdown
|
||||
beq rax, Sys.Exit, .handle_Exit
|
||||
beq rax, Sys.ReadFile, .handle_ReadFile
|
||||
beq rax, Sys.OpenFile, .handle_OpenFile
|
||||
beq rax, Sys.CloseFile, .handle_CloseFile
|
||||
beq rax, Sys.CreateFile, .handle_CreateFile
|
||||
beq rax, Sys.RemoveFile, .handle_RemoveFile
|
||||
beq rax, Sys.FindNext, .handle_FindNext
|
||||
beq rax, Sys.FindFirst, .handle_FindFirst
|
||||
beq rax, Sys.EnterHaltMode, .handle_HaltMode
|
||||
|
||||
call ScreenOfDeath, .badsyscall, r13
|
||||
|
||||
@ -75,8 +75,7 @@ DefaultTrapHandler:
|
||||
call DISK.OpenFile, .cmdcom
|
||||
|
||||
; Crash on failure
|
||||
cmp rax, zero
|
||||
crash.l
|
||||
bltz rax, abort
|
||||
|
||||
; Load at CMDCOM_LOADP
|
||||
mov ax1, CMDCOM_LOADP
|
||||
@ -86,7 +85,7 @@ DefaultTrapHandler:
|
||||
; Assume that COMMAND.COM being
|
||||
; less then 4KB means something
|
||||
; went wrong
|
||||
b.l rax, 0x1000, abort
|
||||
blt rax, 0x1000, abort
|
||||
|
||||
; Close the handle
|
||||
call DISK.CloseFile, rax
|
||||
@ -158,13 +157,13 @@ DefaultTrapHandler:
|
||||
; Misc.
|
||||
;
|
||||
.handle_Shutdown:
|
||||
mov ax0, zero
|
||||
call IDT.DelHandler
|
||||
call IDT.DelHandler, zero
|
||||
|
||||
stop
|
||||
|
||||
.handle_HaltMode:
|
||||
mov rcx, -1
|
||||
hlt.rep
|
||||
stop
|
||||
pause
|
||||
pause
|
||||
hlt
|
||||
jmp .handle_HaltMode
|
||||
|
||||
|
@ -11,8 +11,7 @@ PrintBootMsg:
|
||||
; Initialize TRAP handlers
|
||||
;
|
||||
InitSyscalls:
|
||||
mov ax0, 1
|
||||
call RFS.ActivateFrame
|
||||
call RFS.ActivateFrame, 1
|
||||
|
||||
mov ax1, $rip
|
||||
mov ax2, DefaultTrapHandler
|
||||
@ -25,16 +24,13 @@ InitSyscalls:
|
||||
ret
|
||||
|
||||
InitExcepts:
|
||||
mov ax0, 2
|
||||
call RFS.ActivateFrame
|
||||
call RFS.ActivateFrame, 2
|
||||
|
||||
mov ax1, $rip
|
||||
mov ax2, DefaultExceptionHandler
|
||||
call RFS.StoreReg
|
||||
|
||||
mov ax0, zero
|
||||
mov ax1, 2
|
||||
call IDT.AddHandler
|
||||
call IDT.AddHandler, zero, 2
|
||||
|
||||
SwitchToCMD:
|
||||
mov rax, Sys.Exit
|
||||
|
@ -31,13 +31,13 @@ builtins.dir:
|
||||
trap 0
|
||||
|
||||
.list:
|
||||
jmp.axz .end
|
||||
jraxz .end
|
||||
|
||||
mov r15, rcx # file size
|
||||
mov r15, rcx ; file size
|
||||
inc r14, rcx
|
||||
|
||||
; directory?
|
||||
jmp.dxnz .is_dir
|
||||
bnz rdx, .is_dir
|
||||
|
||||
; found a file
|
||||
inc r12, 1
|
||||
@ -49,8 +49,9 @@ builtins.dir:
|
||||
scasb.rep.nz rsi, '.'
|
||||
|
||||
; print file name
|
||||
sub rcx, rsi, rdi
|
||||
prns.rep rdi
|
||||
sub ax1, rsi, rdi
|
||||
dec ax1, 1
|
||||
call nprint, rdi
|
||||
|
||||
; calculate where to put extension
|
||||
sub rdi, rsi, .buf
|
||||
@ -58,7 +59,7 @@ builtins.dir:
|
||||
|
||||
.ext_pad:
|
||||
; print at least N non-space characters before extension
|
||||
b.ae rdi, N, .print_ext
|
||||
blte N, rdi, .print_ext
|
||||
prn ' '
|
||||
inc rdi, 1
|
||||
jmp .ext_pad
|
||||
@ -68,35 +69,38 @@ builtins.dir:
|
||||
mov rcx, 4
|
||||
prn ' '
|
||||
|
||||
cmp b[rsi], '.'
|
||||
inc.z rsi, 1
|
||||
bne b[rsi], '.', .print_ext.1
|
||||
inc rsi, 1
|
||||
|
||||
.print_ext.1:
|
||||
b.z b[rsi], 0, .print_ext.2
|
||||
bzr b[rsi], .print_ext.2
|
||||
|
||||
; print and decrease rcx, unless it's already 0
|
||||
prn b[rsi]
|
||||
inc rsi, 1
|
||||
dec.cxnz rcx, 1
|
||||
jrcxz .print_ext.1
|
||||
|
||||
dec rcx, 1
|
||||
jmp .print_ext.1
|
||||
|
||||
.print_ext.2:
|
||||
; did we print at least 4 bytes?
|
||||
jmp.cxz .print_bytes ; yes, carry on
|
||||
jrcxz .print_bytes ; yes, carry on
|
||||
|
||||
prn.rep ' '
|
||||
.pe2.l:
|
||||
prn ' '
|
||||
loop .pe2.l
|
||||
|
||||
.print_bytes:
|
||||
; print file size in bytes
|
||||
mov rcx, 3
|
||||
prn.rep ' '
|
||||
prn ' '
|
||||
prn ' '
|
||||
prn ' '
|
||||
|
||||
shr rax, r15, 10
|
||||
and r15, r15, 1023
|
||||
and r15, 1023
|
||||
|
||||
push r15
|
||||
push rax
|
||||
push r15, rax
|
||||
call printf, .bytesstr
|
||||
inc rsp, 16
|
||||
|
||||
@ -129,20 +133,26 @@ builtins.dir:
|
||||
.is_dir:
|
||||
inc r13, 1
|
||||
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .buf
|
||||
prns.rep.nz rdx
|
||||
; use printf instead of print
|
||||
; because it returns # of printed
|
||||
; characters
|
||||
call printf, .buf
|
||||
|
||||
sub rcx, STRLEN_MAX, rcx
|
||||
sub rcx, N, rcx
|
||||
prn.rep ' '
|
||||
blte N, rax, .dir_no_pad
|
||||
sub rcx, N, rax
|
||||
dec rcx, 1
|
||||
|
||||
.dir.l:
|
||||
prn ' '
|
||||
loop .dir.l
|
||||
|
||||
.dir_no_pad:
|
||||
call print, .dir_ext
|
||||
|
||||
jmp .print_bytes
|
||||
|
||||
.buf = [FNAME_MAX]
|
||||
.dir_ext = " <DIR>"
|
||||
.dir_ext = " <DIR> "
|
||||
.endstr0 = " total %dMB + %dKB + %dB\n"
|
||||
.endstr1 = " found %d file(s), %d dir(s)\n"
|
||||
.dirmsg = "Directory of C:\\\n\n"
|
||||
|
@ -22,9 +22,8 @@ main:
|
||||
call print, prompt
|
||||
|
||||
; empty argbuf
|
||||
mov rcx, argbuf.size
|
||||
mov rdx, argbuf
|
||||
stosb.rep rdx, zero
|
||||
call memzero, argbuf, argbuf.size
|
||||
call nprint, argbuf, argbuf.size
|
||||
|
||||
; iterator through argbuf
|
||||
mov rcx, zero
|
||||
@ -38,16 +37,16 @@ main:
|
||||
|
||||
; Fill .buf with user input
|
||||
scan rax
|
||||
jmp.axz .input_loop
|
||||
jraxz .input_loop
|
||||
|
||||
; ESC key pressed?
|
||||
b.z rax, 0x1B, .handle_EXIT
|
||||
beq rax, 0x1B, .handle_EXIT
|
||||
|
||||
; backspace character?
|
||||
b.nz rax, 8, .handle_input
|
||||
bne rax, 8, .handle_input
|
||||
|
||||
; anything to delete?
|
||||
jmp.cxz .input_loop ; no
|
||||
jrcxz .input_loop ; no
|
||||
|
||||
; yes, delete it
|
||||
dec rcx, 1
|
||||
@ -55,19 +54,21 @@ main:
|
||||
mov b[rdx], zero
|
||||
|
||||
; update screen
|
||||
cmp b[stdin_echoing], 1
|
||||
prn.z 8
|
||||
bzr b[stdin_echoing], .input_loop
|
||||
prn 8
|
||||
|
||||
jmp .input_loop
|
||||
|
||||
.handle_input:
|
||||
cmp b[stdin_echoing], 1
|
||||
prn.z rax
|
||||
b.z rax, 10, .extract_argv0
|
||||
bzr b[stdin_echoing], .se.z
|
||||
prn rax
|
||||
|
||||
.se.z:
|
||||
beq rax, 10, .extract_argv0
|
||||
|
||||
; when max line length is reached,
|
||||
; force a newline
|
||||
b.z rcx, argbuf.size, .extract_argv0
|
||||
beq rcx, argbuf.size, .extract_argv0
|
||||
|
||||
; add character to buffer and increase iterator (rcx)
|
||||
add rdx, rcx, argbuf
|
||||
@ -80,7 +81,7 @@ main:
|
||||
.extract_argv0:
|
||||
; did we read anything at all?
|
||||
; if not, just go back to waiting input
|
||||
jmp.cxz .print_prompt
|
||||
jrcxz .print_prompt
|
||||
|
||||
; find first whitespace or null-terminator
|
||||
mov rcx, argbuf.size
|
||||
@ -92,13 +93,14 @@ main:
|
||||
|
||||
.next_space:
|
||||
mov rcx, b[rsi]
|
||||
jmp.cxz .do_extract
|
||||
jrcxz .do_extract
|
||||
|
||||
; skip spaces
|
||||
cmp rcx, ' '
|
||||
inc.z rsi, 1
|
||||
jmp.z .next_space
|
||||
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
|
||||
@ -107,13 +109,11 @@ main:
|
||||
|
||||
.do_extract:
|
||||
; empty argv0
|
||||
mov rcx, argbuf.size
|
||||
mov rax, argv0
|
||||
stosb.rep rax, zero
|
||||
call memzero, argv0, argbuf.size
|
||||
|
||||
; how much do we copy?
|
||||
sub rcx, rdx, argbuf
|
||||
jmp.cxz .detect_builtin
|
||||
jrcxz .detect_builtin
|
||||
dec rcx, 1
|
||||
|
||||
mov rdi, argbuf
|
||||
@ -131,67 +131,67 @@ main:
|
||||
|
||||
.builtin_cls = "cls"
|
||||
call strcmp, argv0, .builtin_cls
|
||||
jmp.axz .handle_CLS
|
||||
jraxz .handle_CLS
|
||||
|
||||
.builtin_crash = "crash"
|
||||
call strcmp, argv0, .builtin_crash
|
||||
jmp.axz .handle_CRASH
|
||||
jraxz .handle_CRASH
|
||||
|
||||
.builtin_date = "date"
|
||||
call strcmp, argv0, .builtin_date
|
||||
jmp.axz .handle_DATE
|
||||
jraxz .handle_DATE
|
||||
|
||||
.builtin_dir = "dir"
|
||||
call strcmp, argv0, .builtin_dir
|
||||
jmp.axz .handle_DIR
|
||||
jraxz .handle_DIR
|
||||
|
||||
.builtin_dump = "dump"
|
||||
call strcmp, argv0, .builtin_dump
|
||||
jmp.axz .handle_DUMP
|
||||
jraxz .handle_DUMP
|
||||
|
||||
.builtin_echo = "echo"
|
||||
call strcmp, argv0, .builtin_echo
|
||||
jmp.axz .handle_ECHO
|
||||
jraxz .handle_ECHO
|
||||
|
||||
.builtin_erase = "erase"
|
||||
call strcmp, argv0, .builtin_erase
|
||||
jmp.axz .handle_ERASE
|
||||
jraxz .handle_ERASE
|
||||
|
||||
.builtin_exit = "exit"
|
||||
call strcmp, argv0, .builtin_exit
|
||||
jmp.axz .handle_EXIT
|
||||
jraxz .handle_EXIT
|
||||
|
||||
.builtin_help = "help"
|
||||
call strcmp, argv0, .builtin_help
|
||||
jmp.axz .handle_HELP
|
||||
jraxz .handle_HELP
|
||||
|
||||
.builtin_halt = "halt"
|
||||
call strcmp, argv0, .builtin_halt
|
||||
jmp.axz .handle_HALT
|
||||
jraxz .handle_HALT
|
||||
|
||||
.builtin_make = "make"
|
||||
call strcmp, argv0, .builtin_make
|
||||
jmp.axz .handle_MAKE
|
||||
jraxz .handle_MAKE
|
||||
|
||||
.builtin_print = "print"
|
||||
call strcmp, argv0, .builtin_print
|
||||
jmp.axz .handle_PRINT
|
||||
jraxz .handle_PRINT
|
||||
|
||||
.builtin_prompt = "prompt"
|
||||
call strcmp, argv0, .builtin_prompt
|
||||
jmp.axz .handle_PROMPT
|
||||
jraxz .handle_PROMPT
|
||||
|
||||
.builtin_remove = "remove"
|
||||
call strcmp, argv0, .builtin_remove
|
||||
jmp.axz .handle_REMOVE
|
||||
jraxz .handle_REMOVE
|
||||
|
||||
.builtin_time = "time"
|
||||
call strcmp, argv0, .builtin_time
|
||||
jmp.axz .handle_TIME
|
||||
jraxz .handle_TIME
|
||||
|
||||
.builtin_vers = "vers"
|
||||
call strcmp, argv0, .builtin_vers
|
||||
jmp.axz .handle_VERS
|
||||
jraxz .handle_VERS
|
||||
|
||||
jmp .command_not_found
|
||||
|
||||
@ -231,11 +231,10 @@ main:
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_ECHO:
|
||||
mov rdx, q[argv1pos]
|
||||
jmp.dxz .echo.end
|
||||
mov rax, q[argv1pos]
|
||||
jraxz .echo.end
|
||||
|
||||
mov rcx, argbuf.size
|
||||
prns.rep.nz rdx
|
||||
call print, rax
|
||||
|
||||
.echo.end:
|
||||
prn 10
|
||||
@ -244,10 +243,10 @@ main:
|
||||
.handle_ERASE:
|
||||
mov rax, Sys.RemoveFile
|
||||
mov ax0, q[argv1pos]
|
||||
b.z ax0, zero, .need_params
|
||||
bzr ax0, .need_params
|
||||
trap 0
|
||||
|
||||
b.l rax, zero, .couldnt_remove
|
||||
bltz rax, .couldnt_remove
|
||||
|
||||
jmp .handle_MAKE ; re-create it back
|
||||
|
||||
@ -264,20 +263,20 @@ main:
|
||||
.handle_MAKE:
|
||||
mov rax, Sys.CreateFile
|
||||
mov ax0, q[argv1pos]
|
||||
b.z ax0, zero, .need_params
|
||||
bzr ax0, .need_params
|
||||
trap 0
|
||||
|
||||
b.l rax, zero, .couldnt_open
|
||||
bltz rax, .couldnt_open
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_PRINT:
|
||||
mov rax, Sys.OpenFile
|
||||
mov ax0, q[argv1pos]
|
||||
b.z ax0, zero, .need_params
|
||||
bzr ax0, .need_params
|
||||
trap 0
|
||||
|
||||
b.l rax, zero, .file_not_found
|
||||
bltz rax, .file_not_found
|
||||
|
||||
mov ax0, rax
|
||||
mov ax1, FILE_LOADP
|
||||
@ -291,18 +290,17 @@ main:
|
||||
mov rax, Sys.CloseFile
|
||||
trap 0
|
||||
|
||||
b.l rcx, zero, .couldnt_read
|
||||
jmp.cxz .empty_file
|
||||
bltz rcx, .couldnt_read
|
||||
jrcxz .empty_file
|
||||
|
||||
mov rdx, FILE_LOADP
|
||||
prns.rep rdx
|
||||
call nprint, FILE_LOADP, rcx
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_PROMPT:
|
||||
mov ax0, prompt
|
||||
mov ax1, q[argv1pos]
|
||||
b.z ax1, zero, .need_params
|
||||
bzr ax1, .need_params
|
||||
call strcpy
|
||||
|
||||
jmp .print_prompt
|
||||
@ -310,10 +308,10 @@ main:
|
||||
.handle_REMOVE:
|
||||
mov rax, Sys.RemoveFile
|
||||
mov ax0, q[argv1pos]
|
||||
b.z ax0, zero, .need_params
|
||||
bzr ax0, .need_params
|
||||
trap 0
|
||||
|
||||
b.l rax, zero, .couldnt_remove
|
||||
bltz rax, .couldnt_remove
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
|
59
vm/in/ALU
59
vm/in/ALU
@ -10,8 +10,6 @@
|
||||
#
|
||||
# $dest = $src1 OR $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
or 2
|
||||
or 3
|
||||
|
||||
@ -20,8 +18,6 @@ or 3
|
||||
#
|
||||
# $dest = $src1 AND $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
and 2
|
||||
and 3
|
||||
|
||||
@ -30,8 +26,6 @@ and 3
|
||||
#
|
||||
# $dest = $src1 XOR $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
xor 2
|
||||
xor 3
|
||||
|
||||
@ -41,8 +35,6 @@ xor 3
|
||||
# $dest = $src1 << $src2 (SHL)
|
||||
# $dest = $src1 >> $src2 (SHR)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
shl 2
|
||||
shl 3
|
||||
shr 2
|
||||
@ -53,86 +45,41 @@ shr 3
|
||||
#
|
||||
# $dest = $src1 >>> $src2 (SAR)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
sar 2
|
||||
sar 3
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Arithmetic instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# CMP Comparison instruction
|
||||
#
|
||||
# SignExtend($1) - $2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
cmp 2
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
#
|
||||
# $dest1 = $src1 + $src2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
add 2
|
||||
add 3
|
||||
addf 3
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
#
|
||||
# $dest = $src1 - $src2
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sub 2
|
||||
sub 3
|
||||
subf 3
|
||||
|
||||
#
|
||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||
#
|
||||
# $dest = $src1 + $src2 + CF (ADC)
|
||||
# $dest = $src1 - $src2 - CF (SBB)
|
||||
#
|
||||
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
adcx 2
|
||||
adcx 3
|
||||
sbbx 2
|
||||
sbbx 3
|
||||
|
||||
#
|
||||
# Arithmetical MUL operation
|
||||
#
|
||||
# $dest = LO($src1 * $src2)
|
||||
#
|
||||
# Preserves ZF and SF
|
||||
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
|
||||
#
|
||||
mul 2
|
||||
mul 3
|
||||
mulf 3
|
||||
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
# $dest1 = HI($dest2 * $src)
|
||||
# $dest2 = LO($dest2 * $src)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
mulhi 3
|
||||
|
||||
# Arithmetical signed MUL operation
|
||||
@ -140,8 +87,6 @@ mulhi 3
|
||||
# $dest1 = HI($dest2 ** $src)
|
||||
# $dest2 = LO($dest2 ** $src)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
imulhi 3
|
||||
|
||||
#
|
||||
@ -159,8 +104,6 @@ div 3
|
||||
#
|
||||
# $dest = $src1 IDIV $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
idiv 2
|
||||
idiv 3
|
||||
|
||||
@ -169,8 +112,6 @@ idiv 3
|
||||
#
|
||||
# $dest = $src1 MOD $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
rem 2
|
||||
rem 3
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
include "SUPER"
|
||||
include "ALU"
|
||||
include "JMP"
|
||||
include "MEM"
|
||||
include "MISC"
|
||||
include "STRING"
|
||||
|
65
vm/in/JMP
Normal file
65
vm/in/JMP
Normal file
@ -0,0 +1,65 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Jump instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Jump (JMP) instruction
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
jmp 1
|
||||
|
||||
jraxz 1
|
||||
jrcxz 1
|
||||
|
||||
jraxnz 1
|
||||
jrcxnz 1
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
#
|
||||
# IF (RCX > 0) THEN
|
||||
# RCX = RCX - 1
|
||||
# RIP = $1
|
||||
# FI
|
||||
#
|
||||
loop 1
|
||||
|
||||
#
|
||||
# Conditional absolute jumps (branches) (BCH)
|
||||
#
|
||||
# IF (COND) THEN
|
||||
# RIP = $3
|
||||
# FI
|
||||
#
|
||||
|
||||
# reg == 0
|
||||
bzr 2
|
||||
|
||||
# reg != 0
|
||||
bnz 2
|
||||
|
||||
# (s)reg < 0
|
||||
bltz 2
|
||||
|
||||
# r1 == r2
|
||||
beq 3
|
||||
|
||||
# r1 != r2
|
||||
bne 3
|
||||
|
||||
# (s)r1 < (s)r2
|
||||
blt 3
|
||||
|
||||
# r1 < r2
|
||||
bltu 3
|
||||
|
||||
# (s)r1 <= (s)r2
|
||||
blte 3
|
||||
|
||||
# r1 <= r2
|
||||
blteu 3
|
||||
|
49
vm/in/MEM
49
vm/in/MEM
@ -1,46 +1,6 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Jump instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Jump (JMP) instruction
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
jmp 1
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
#
|
||||
# IF (RCX > 0) THEN
|
||||
# RCX = RCX - 1
|
||||
# RIP = $1
|
||||
# FI
|
||||
#
|
||||
loop 1
|
||||
|
||||
#
|
||||
# Conditional absolute jumps (branches) (BCH)
|
||||
#
|
||||
# COMPARE(SignExtend($1), $2)
|
||||
#
|
||||
# IF (COND) THEN
|
||||
# RIP = $3
|
||||
# FI
|
||||
#
|
||||
# Sets CF, OF, ZF and SF according to the comparison's results
|
||||
#
|
||||
# This instruction is special in that the COND field specified is not evaluated
|
||||
# before the instruction is executed, but after the comparison it effectuates
|
||||
#
|
||||
# Suffixing B with the REP suffix results in undefined behavior
|
||||
#
|
||||
bch 3
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Stack manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -60,7 +20,7 @@ call 3
|
||||
#
|
||||
# POP(RIP)
|
||||
#
|
||||
ret
|
||||
ret 0
|
||||
|
||||
#
|
||||
# Make new stack frame (ENTER)
|
||||
@ -69,8 +29,9 @@ ret
|
||||
# RBP = RSP
|
||||
# RSP = RSP - $1
|
||||
#
|
||||
enter
|
||||
enter 0
|
||||
enter 1
|
||||
enter 2
|
||||
|
||||
#
|
||||
# Leave stack frame (LEAVE)
|
||||
@ -78,7 +39,7 @@ enter 1
|
||||
# RSP = RBP
|
||||
# POP(RBP)
|
||||
#
|
||||
leave
|
||||
leave 0
|
||||
|
||||
#
|
||||
# PUSH value onto stack
|
||||
@ -114,8 +75,6 @@ pop 3
|
||||
# will result in:
|
||||
# RAX = RBX + RCX * 2 + 4
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
lea 2
|
||||
|
||||
#
|
||||
|
22
vm/in/MISC
22
vm/in/MISC
@ -35,11 +35,6 @@ udf
|
||||
#
|
||||
pause
|
||||
|
||||
#
|
||||
# Throw #OVF when RFX.OF=1 (INTO)
|
||||
#
|
||||
into
|
||||
|
||||
#
|
||||
# Get timestamp in µseconds
|
||||
#
|
||||
@ -79,23 +74,6 @@ dswap 2
|
||||
#
|
||||
prn 1
|
||||
|
||||
#
|
||||
# Print a string to standard output (PRN)
|
||||
#
|
||||
# COMPARE([%1], 0)
|
||||
#
|
||||
# IF (ZF == 0) THEN
|
||||
# PRN([%1])
|
||||
# IF (DF == 0) THEN
|
||||
# %1 = %1 + 1
|
||||
# ELSE
|
||||
# %1 = %1 - 1
|
||||
# FI
|
||||
# FI
|
||||
#
|
||||
#
|
||||
prns 1
|
||||
|
||||
#
|
||||
# Scan a character from standard input (SCAN)
|
||||
#
|
||||
|
15
vm/in/STRING
15
vm/in/STRING
@ -5,21 +5,6 @@
|
||||
# String manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Store value into string (STOSx)
|
||||
#
|
||||
# [%1] = $2
|
||||
# IF (DF == 0) THEN
|
||||
# %str = %str + sizeof(x)
|
||||
# ELSE
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
stosb 2
|
||||
stosw 2
|
||||
stosd 2
|
||||
stosq 2
|
||||
|
||||
#
|
||||
# Scan string for a particular value (SCASx)
|
||||
#
|
||||
|
18
vm/in/SUPER
18
vm/in/SUPER
@ -15,7 +15,7 @@
|
||||
# #ILL if disabled through DV
|
||||
# #1023 otherwise
|
||||
#
|
||||
crash
|
||||
crash 0
|
||||
|
||||
#
|
||||
# Initiate machine shutdown (STOP)
|
||||
@ -27,7 +27,7 @@ crash
|
||||
# #ILL if disabled through DV
|
||||
# #SHT otherwise
|
||||
#
|
||||
stop
|
||||
stop 0
|
||||
|
||||
#
|
||||
# Halt the processor until next E/I (HLT)
|
||||
@ -35,7 +35,7 @@ stop
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
hlt
|
||||
hlt 0
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# E/I handling instructions #
|
||||
@ -56,16 +56,10 @@ trap 1
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
iret
|
||||
iret 0
|
||||
|
||||
#
|
||||
# Clear or set interrupt flag (CLI/STI)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
cli
|
||||
sti
|
||||
cli 0
|
||||
sti 0
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Device control instructions #
|
||||
|
12
vm/in/alu.c
12
vm/in/alu.c
@ -139,18 +139,6 @@ IMPL_START(mulhi, 3)
|
||||
return 2;
|
||||
}
|
||||
|
||||
IMPL_START(mulf, 3)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
ulong tmp;
|
||||
__unsigned_multiply128(p2->val, p3->val, &tmp, r1);
|
||||
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
|
57
vm/in/jmp.c
Normal file
57
vm/in/jmp.c
Normal file
@ -0,0 +1,57 @@
|
||||
// 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 <in/instrs.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(jmp, 1) { R(RIP) = p1->val; return 0; }
|
||||
|
||||
IMPL_START(jraxz, 1) { if (!R(RAX)) R(RIP) = p1->val; return 0; }
|
||||
IMPL_START(jrcxz, 1) { if (!R(RCX)) R(RIP) = p1->val; return 0; }
|
||||
|
||||
IMPL_START(jraxnz, 1) { if (R(RAX)) R(RIP) = p1->val; return 0; }
|
||||
IMPL_START(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; }
|
||||
|
||||
IMPL_START(loop, 1) {
|
||||
if (R(RCX) > 0) {
|
||||
R(RCX)--;
|
||||
R(RIP) = p1->val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(bzr, 2) { SRCP(p1); if (p1->val == 0) R(RIP) = p2->val; return 0; }
|
||||
IMPL_START(bnz, 2) { SRCP(p1); if (p1->val != 0) R(RIP) = p2->val; return 0; }
|
||||
IMPL_START(bltz, 2) { SRCP(p1); if ((long)p1->val < 0) R(RIP) = p2->val; return 0; }
|
||||
|
||||
IMPL_START(beq, 3) { SRCP(p1); if (p1->val == p2->val) R(RIP) = p3->val; return 0; }
|
||||
IMPL_START(bne, 3) { SRCP(p1); if (p1->val != p2->val) R(RIP) = p3->val; return 0; }
|
||||
|
||||
IMPL_START(blt, 3) { SRCP(p1); if ((long)p1->val < (long)p2->val) R(RIP) = p3->val; return 0; }
|
||||
IMPL_START(bltu, 3) { SRCP(p1); if (p1->val < p2->val) R(RIP) = p3->val; return 0; }
|
||||
|
||||
IMPL_START(blte, 3) { SRCP(p1); if ((long)p1->val <= (long)p2->val) R(RIP) = p3->val; return 0; }
|
||||
IMPL_START(blteu, 3) { SRCP(p1); if (p1->val <= p2->val) R(RIP) = p3->val; return 0; }
|
||||
|
||||
IMPL_START(bch, 3)
|
||||
{
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
if (eval_cond(ctx->cond))
|
||||
R(RIP) = p3->val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(cmp, 2)
|
||||
{
|
||||
SRCP(p1);
|
||||
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
return 0;
|
||||
}
|
57
vm/in/mem.c
57
vm/in/mem.c
@ -5,40 +5,6 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(jmp, 1) { R(RIP) = p1->val; return 0; }
|
||||
|
||||
IMPL_START(loop, 1) {
|
||||
if (R(RCX) > 0) {
|
||||
R(RCX)--;
|
||||
R(RIP) = p1->val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(bch, 3)
|
||||
{
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
if (eval_cond(ctx->cond))
|
||||
R(RIP) = p3->val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(cmp, 2)
|
||||
{
|
||||
SRCP(p1);
|
||||
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(lea, 2) { *r1 = p2->addr; return 1; }
|
||||
IMPL_START(mov, 2) { XSRCP(*r1, p2, sx); return 1; }
|
||||
IMPL_START(movzx, 2) { XSRCP(*r1, p2, zx); return 1; }
|
||||
@ -178,6 +144,8 @@ IMPL_START(ret, 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(enter, 0)
|
||||
{
|
||||
R(RSP) -= 8;
|
||||
@ -196,6 +164,27 @@ IMPL_START(enter, 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(enter, 2)
|
||||
{
|
||||
int i, tmp;
|
||||
|
||||
R(RSP) -= 8;
|
||||
tmp = R(RSP);
|
||||
writemem(R(RBP), R(RSP), 8);
|
||||
|
||||
for (i = 0; i < p2->val; i++)
|
||||
{
|
||||
R(RBP) -= 8;
|
||||
R(RSP) -= 8;
|
||||
writemem(R(RBP), R(RSP), 8);
|
||||
}
|
||||
|
||||
R(RBP) = tmp;
|
||||
R(RSP) = tmp - (p1->val * 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(leave, 0)
|
||||
{
|
||||
R(RSP) = R(RBP) + 8;
|
||||
|
@ -66,7 +66,7 @@ void exec_instr(instr_t *in,
|
||||
// For REPs we evaluate the condition AFTER running the instruction,
|
||||
// in a do ... while(cond) fashion
|
||||
//
|
||||
if (ctx->cond && in->func != i_bch_3) // 'B' instruction is special
|
||||
if (ctx->cond)
|
||||
if (!rep && !eval_cond(ctx->cond))
|
||||
return;
|
||||
|
||||
@ -98,11 +98,6 @@ do_rep:
|
||||
|
||||
// Should we really count REP's in instruction count?
|
||||
ctx->ninstrs++;
|
||||
#if 0
|
||||
// Show that we're REP'ing
|
||||
if (ctx->dumpsw)
|
||||
dump_instr(in, p1, p2, p3, lock, rep);
|
||||
#endif
|
||||
|
||||
goto do_rep;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user