mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
more RISC-ifications
This commit is contained in:
parent
5b315ad46a
commit
40653a8047
4
Makefile
4
Makefile
@ -11,7 +11,7 @@ kpc: vm/Makefile
|
|||||||
@cd vm && make --no-print-directory -s verbose=yes
|
@cd vm && make --no-print-directory -s verbose=yes
|
||||||
|
|
||||||
kas: kpc as/regs.lst as/k-as.py
|
kas: kpc as/regs.lst as/k-as.py
|
||||||
@cp vm/in/instrs.lst as
|
@cp vm/ob/instrs.lst as
|
||||||
|
|
||||||
dos: kas dosclean
|
dos: kas dosclean
|
||||||
@cd ka && make --no-print-directory -s
|
@cd ka && make --no-print-directory -s
|
||||||
@ -24,7 +24,7 @@ dosclean:
|
|||||||
@rm -f $(KODIR)/*.com $(KODIR)/*.sym
|
@rm -f $(KODIR)/*.com $(KODIR)/*.sym
|
||||||
|
|
||||||
inclean:
|
inclean:
|
||||||
@rm -f vm/in/arch_i.h vm/in/instrs.lst vm/ob/in/*.o
|
@rm -f vm/ob/arch_i.h vm/ob/instrs.lst vm/ob/in/*.o
|
||||||
|
|
||||||
clean: dosclean
|
clean: dosclean
|
||||||
@cd vm && make clean --no-print-directory -s verbose=no
|
@cd vm && make clean --no-print-directory -s verbose=no
|
||||||
|
@ -13,7 +13,6 @@ start:
|
|||||||
mov rbp, zero
|
mov rbp, zero
|
||||||
|
|
||||||
cls
|
cls
|
||||||
cld
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
mov rax, Sys.EnterHaltMode
|
mov rax, Sys.EnterHaltMode
|
||||||
|
@ -10,4 +10,5 @@ include "crt/err/errno.k"
|
|||||||
include "crt/fmt/format.k"
|
include "crt/fmt/format.k"
|
||||||
include "crt/str/string.k"
|
include "crt/str/string.k"
|
||||||
include "crt/lib/time.k"
|
include "crt/lib/time.k"
|
||||||
|
include "crt/lib/arith128.k"
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ doprnt:
|
|||||||
mov ax0, b[rbx]
|
mov ax0, b[rbx]
|
||||||
call .doput
|
call .doput
|
||||||
|
|
||||||
inc rbx
|
add rbx, rbx, 1
|
||||||
jmp .print_regular
|
jmp .print_regular
|
||||||
|
|
||||||
.check_modf:
|
.check_modf:
|
||||||
@ -71,7 +71,7 @@ doprnt:
|
|||||||
cmp ax0, zero
|
cmp ax0, zero
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
inc rdi
|
add rdi, rdi, 1
|
||||||
call .doput
|
call .doput
|
||||||
jmp .print_string
|
jmp .print_string
|
||||||
|
|
||||||
@ -82,10 +82,8 @@ doprnt:
|
|||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.modf_p:
|
.modf_p:
|
||||||
mov ax0, '0'
|
call .doput, '0'
|
||||||
call .doput
|
call .doput, 'x'
|
||||||
mov ax0, 'x'
|
|
||||||
call .doput
|
|
||||||
; Fallthrough
|
; Fallthrough
|
||||||
|
|
||||||
.modf_x:
|
.modf_x:
|
||||||
@ -122,44 +120,29 @@ doprnt:
|
|||||||
add.z rsp, rsp, 80
|
add.z rsp, rsp, 80
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
inc rdi
|
add rdi, rdi, 1
|
||||||
call .doput
|
call .doput
|
||||||
jmp .print_itoa_buf
|
jmp .print_itoa_buf
|
||||||
|
|
||||||
.modf_percent:
|
.modf_percent:
|
||||||
mov ax0, '%'
|
call .doput, '%'
|
||||||
call .doput
|
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.bad_modifier:
|
.bad_modifier:
|
||||||
; print "%?" to clearly indicate that something is wrong
|
; print "%?" to clearly indicate that something is wrong
|
||||||
mov ax0, '%'
|
call .doput, '%'
|
||||||
call .doput
|
call .doput, '?'
|
||||||
|
|
||||||
mov ax0, '?'
|
|
||||||
call .doput
|
|
||||||
|
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.nullstring:
|
.nullstring:
|
||||||
; %s was passed a NULL
|
; %s was passed a NULL
|
||||||
mov ax0, '('
|
call .doput, '('
|
||||||
call .doput
|
call .doput, 'n'
|
||||||
|
call .doput, 'u'
|
||||||
mov ax0, 'n'
|
call .doput, 'l'
|
||||||
call .doput
|
call .doput, 'l'
|
||||||
|
call .doput, ')'
|
||||||
mov ax0, 'u'
|
|
||||||
call .doput
|
|
||||||
|
|
||||||
mov ax0, 'l'
|
|
||||||
call .doput
|
|
||||||
|
|
||||||
mov ax0, 'l'
|
|
||||||
call .doput
|
|
||||||
|
|
||||||
mov ax0, ')'
|
|
||||||
call .doput
|
|
||||||
|
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
@ -178,7 +161,7 @@ doprnt:
|
|||||||
;
|
;
|
||||||
.doput:
|
.doput:
|
||||||
; update print count
|
; update print count
|
||||||
inc nx1
|
add nx1, nx1, 1
|
||||||
|
|
||||||
; if n==0, don't print
|
; if n==0, don't print
|
||||||
; we follow the C convention that sprintf()-like functions
|
; we follow the C convention that sprintf()-like functions
|
||||||
@ -188,7 +171,7 @@ doprnt:
|
|||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
; if n>0, decrement n and print
|
; if n>0, decrement n and print
|
||||||
dec nx0
|
sub nx0, nx0, 1
|
||||||
call nx3
|
call nx3
|
||||||
|
|
||||||
; did putc fail?
|
; did putc fail?
|
||||||
|
@ -34,10 +34,9 @@ ltostr:
|
|||||||
b.z ax3, zero, .conv
|
b.z ax3, zero, .conv
|
||||||
b.nz ax2, 10, .conv ; base 10
|
b.nz ax2, 10, .conv ; base 10
|
||||||
|
|
||||||
sgn r11, ax1 ; extract ax1 sign
|
shr r11, ax1, 63 ; extract ax1 sign
|
||||||
|
cmp r11, zero ; negative?
|
||||||
cmp r11, -1 ; negative?
|
sub.nz ax1, zero, ax1 ; yes
|
||||||
neg.z ax1, ax1
|
|
||||||
|
|
||||||
; main loop
|
; main loop
|
||||||
.conv:
|
.conv:
|
||||||
@ -55,7 +54,7 @@ ltostr:
|
|||||||
|
|
||||||
.next:
|
.next:
|
||||||
mov b[ax0], r10
|
mov b[ax0], r10
|
||||||
inc ax0
|
add ax0, ax0, 1
|
||||||
|
|
||||||
div ax1, ax1, ax2
|
div ax1, ax1, ax2
|
||||||
jmp .conv
|
jmp .conv
|
||||||
@ -64,12 +63,11 @@ ltostr:
|
|||||||
.fini:
|
.fini:
|
||||||
cmp r11, -1
|
cmp r11, -1
|
||||||
mov.z b[ax0], '-'
|
mov.z b[ax0], '-'
|
||||||
inc.z ax0
|
add.z ax0, ax0, 1
|
||||||
|
|
||||||
mov b[ax0], zero
|
mov b[ax0], zero
|
||||||
|
|
||||||
mov ax0, rax
|
call strrev2, rax
|
||||||
call strrev2
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ strtoq:
|
|||||||
|
|
||||||
.skip_spc:
|
.skip_spc:
|
||||||
cmp b[rdx], ' '
|
cmp b[rdx], ' '
|
||||||
inc.z rdx
|
add.z rdx, rdx, 1
|
||||||
jmp.z .skip_spc
|
jmp.z .skip_spc
|
||||||
|
|
||||||
; skip +
|
; skip +
|
||||||
cmp b[rdx], '+'
|
cmp b[rdx], '+'
|
||||||
inc.z rdx
|
add.z rdx, rdx, 1
|
||||||
|
|
||||||
; signed?
|
; signed?
|
||||||
cmp ax2, zero
|
cmp ax2, zero
|
||||||
@ -53,7 +53,7 @@ strtoq:
|
|||||||
|
|
||||||
; parse '-'
|
; parse '-'
|
||||||
cmp b[rdx], '-'
|
cmp b[rdx], '-'
|
||||||
inc.z rdx
|
add.z rdx, rdx, 1
|
||||||
mov.z r10, 1
|
mov.z r10, 1
|
||||||
mov.nz r10, zero
|
mov.nz r10, zero
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ strtoq:
|
|||||||
; base prefix?
|
; base prefix?
|
||||||
b.nz b[rdx], '0', .main_loop
|
b.nz b[rdx], '0', .main_loop
|
||||||
|
|
||||||
inc rdx
|
add rdx, rdx, 1
|
||||||
movzx rcx, b[rdx]
|
movzx rcx, b[rdx]
|
||||||
|
|
||||||
; "0x"/"0b" prefix
|
; "0x"/"0b" prefix
|
||||||
@ -81,7 +81,7 @@ strtoq:
|
|||||||
; if not, leave rax = 0 and *rdx = 'x'
|
; if not, leave rax = 0 and *rdx = 'x'
|
||||||
b.nz ax1, 16, .done
|
b.nz ax1, 16, .done
|
||||||
; else
|
; else
|
||||||
inc rdx
|
add rdx, rdx, 1
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.parsed_0b:
|
.parsed_0b:
|
||||||
@ -89,7 +89,7 @@ strtoq:
|
|||||||
; if not, leave rax = 0 and *rdx = 'b'
|
; if not, leave rax = 0 and *rdx = 'b'
|
||||||
b.nz ax1, 2, .done
|
b.nz ax1, 2, .done
|
||||||
; else
|
; else
|
||||||
inc rdx
|
add rdx, rdx, 1
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
.base_0:
|
.base_0:
|
||||||
@ -98,15 +98,15 @@ strtoq:
|
|||||||
cmp b[rdx], '0'
|
cmp b[rdx], '0'
|
||||||
mov.nz ax1, 10
|
mov.nz ax1, 10
|
||||||
jmp.nz .main_loop
|
jmp.nz .main_loop
|
||||||
inc rdx
|
add rdx, rdx, 1
|
||||||
|
|
||||||
cmp b[rdx], 'x'
|
cmp b[rdx], 'x'
|
||||||
inc.z rdx
|
add.z rdx, rdx, 1
|
||||||
mov.z ax1, 16
|
mov.z ax1, 16
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
cmp b[rdx], 'b'
|
cmp b[rdx], 'b'
|
||||||
inc.z rdx
|
add.z rdx, rdx, 1
|
||||||
mov.z ax1, 2
|
mov.z ax1, 2
|
||||||
jmp.z .main_loop
|
jmp.z .main_loop
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ strtoq:
|
|||||||
|
|
||||||
.main_loop:
|
.main_loop:
|
||||||
movzx r12, b[rdx]
|
movzx r12, b[rdx]
|
||||||
inc rdx
|
add rdx, rdx, 1
|
||||||
|
|
||||||
cmp r12, '0'
|
cmp r12, '0'
|
||||||
jmp.b .done
|
jmp.b .done
|
||||||
@ -147,7 +147,7 @@ strtoq:
|
|||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
; yes
|
; yes
|
||||||
neg rax, rax
|
sub rax, zero, rax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.bad:
|
.bad:
|
||||||
|
59
ka/crt/lib/arith128.k
Normal file
59
ka/crt/lib/arith128.k
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
; 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_lq_q(int x, int y)
|
||||||
|
;
|
||||||
|
mul_q_q:
|
||||||
|
mov rax, ax0
|
||||||
|
mulhi rdx, rax, ax1
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; int:int imul_lq_q(int x, int y)
|
||||||
|
;
|
||||||
|
imul_q_q:
|
||||||
|
mov rax, ax0
|
||||||
|
imulhi rdx, rax, ax1
|
||||||
|
ret
|
||||||
|
|
@ -36,7 +36,7 @@ DaysInYear:
|
|||||||
b.nz rcx, zero, .end
|
b.nz rcx, zero, .end
|
||||||
|
|
||||||
.leap:
|
.leap:
|
||||||
inc rax
|
add rax, rax, 1
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
ret
|
ret
|
||||||
|
@ -11,12 +11,27 @@
|
|||||||
;
|
;
|
||||||
strcmp:
|
strcmp:
|
||||||
mov rcx, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
cmpzsb.rep.z ax0, ax1
|
|
||||||
|
|
||||||
mov rax, b[ax0-1]
|
.1:
|
||||||
mov rcx, b[ax1-1]
|
jmp.cxz .2
|
||||||
sub rax, rax, rcx
|
|
||||||
|
|
||||||
|
movzx rax, b[ax0]
|
||||||
|
movzx rdx, b[ax1]
|
||||||
|
|
||||||
|
cmp rax, rdx
|
||||||
|
jmp.nz .2
|
||||||
|
|
||||||
|
; both zero?
|
||||||
|
add r11, rax, rdx
|
||||||
|
b.z r11, zero, .2
|
||||||
|
|
||||||
|
add ax0, ax0, 1
|
||||||
|
add ax1, ax1, 1
|
||||||
|
sub rcx, rcx, 1
|
||||||
|
jmp .1
|
||||||
|
|
||||||
|
.2:
|
||||||
|
sub rax, rax, rdx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -24,14 +39,22 @@ strcmp:
|
|||||||
;
|
;
|
||||||
strncmp:
|
strncmp:
|
||||||
mov rcx, ax2
|
mov rcx, ax2
|
||||||
mov.cxz rax, zero
|
|
||||||
ret.cxz
|
|
||||||
|
|
||||||
cmpzsb.rep.z ax0, ax1
|
.1:
|
||||||
|
jmp.cxz .2
|
||||||
|
|
||||||
mov rax, b[ax0-1]
|
mov rax, b[ax0]
|
||||||
mov rcx, b[ax1-1]
|
mov rdx, b[ax1]
|
||||||
sub rax, rax, rcx
|
|
||||||
|
|
||||||
|
cmp rax, rdx
|
||||||
|
jmp.nz .2
|
||||||
|
|
||||||
|
add ax0, ax0, 1
|
||||||
|
add ax1, ax1, 1
|
||||||
|
sub rcx, rcx, 1
|
||||||
|
jmp .1
|
||||||
|
|
||||||
|
.2:
|
||||||
|
sub rax, rax, rdx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -5,8 +5,17 @@
|
|||||||
; void strcpy(char *, const char *)
|
; void strcpy(char *, const char *)
|
||||||
;
|
;
|
||||||
strcpy:
|
strcpy:
|
||||||
mov rcx, STRLEN_MAX
|
mov rax, b[ax1]
|
||||||
movsb.rep.nz ax0, ax1
|
mov b[ax0], rax
|
||||||
|
|
||||||
|
b.z rax, zero, .1
|
||||||
|
|
||||||
|
add ax0, ax0, 1
|
||||||
|
add ax1, ax1, 1
|
||||||
|
|
||||||
|
jmp strcpy
|
||||||
|
|
||||||
|
.1:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -14,24 +23,42 @@ strcpy:
|
|||||||
;
|
;
|
||||||
strncpy:
|
strncpy:
|
||||||
mov rcx, ax2
|
mov rcx, ax2
|
||||||
|
|
||||||
|
.1:
|
||||||
ret.cxz
|
ret.cxz
|
||||||
|
|
||||||
movsb.rep.nz ax0, ax1
|
mov rax, b[ax1]
|
||||||
ret
|
mov b[ax0], rax
|
||||||
|
|
||||||
|
add ax0, ax0, 1
|
||||||
|
add ax1, ax1, 1
|
||||||
|
sub rcx, rcx, 1
|
||||||
|
|
||||||
|
jmp .1
|
||||||
|
|
||||||
;
|
;
|
||||||
; void strnzcpy(char *, const char *, int)
|
; void strnzcpy(char *, const char *, int)
|
||||||
;
|
;
|
||||||
strnzcpy:
|
strnzcpy:
|
||||||
mov rcx, ax2
|
mov rcx, ax2
|
||||||
ret.cxz
|
|
||||||
|
|
||||||
dec rcx
|
|
||||||
jmp.cxz .1
|
|
||||||
|
|
||||||
movsb.rep.nz ax0, ax1
|
|
||||||
|
|
||||||
.1:
|
.1:
|
||||||
|
jmp.cxz .2
|
||||||
|
|
||||||
|
mov rax, b[ax1]
|
||||||
|
mov b[ax0], rax
|
||||||
|
|
||||||
|
b.z rax, zero, .3
|
||||||
|
|
||||||
|
add ax0, ax0, 1
|
||||||
|
add ax1, ax1, 1
|
||||||
|
sub rcx, rcx, 1
|
||||||
|
|
||||||
|
jmp .1
|
||||||
|
|
||||||
|
.2:
|
||||||
mov b[ax0], zero
|
mov b[ax0], zero
|
||||||
|
|
||||||
|
.3:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ strnlen:
|
|||||||
; int strlen(char *)
|
; int strlen(char *)
|
||||||
;
|
;
|
||||||
strlen:
|
strlen:
|
||||||
mov ax1, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
jmp strnlen
|
mov rdx, rcx
|
||||||
|
scasb.rep.nz ax0, zero
|
||||||
|
|
||||||
|
sub rax, rdx, rcx
|
||||||
|
ret
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ strrev:
|
|||||||
; the null terminator
|
; the null terminator
|
||||||
mov rcx, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
scasb.rep.nz ax1, zero
|
scasb.rep.nz ax1, zero
|
||||||
dec ax1
|
sub ax1, ax1, 1
|
||||||
|
|
||||||
.2:
|
.2:
|
||||||
; copy, going backward though str
|
; copy, going backward though str
|
||||||
@ -30,8 +30,8 @@ strrev:
|
|||||||
mov.z b[ax0+1], zero
|
mov.z b[ax0+1], zero
|
||||||
ret.z
|
ret.z
|
||||||
|
|
||||||
inc ax0
|
add ax0, ax0, 1
|
||||||
dec ax1
|
sub ax1, ax1, 1
|
||||||
jmp .2
|
jmp .2
|
||||||
|
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ strrev2:
|
|||||||
; the null terminator
|
; the null terminator
|
||||||
mov rcx, STRLEN_MAX
|
mov rcx, STRLEN_MAX
|
||||||
scasb.rep.nz ax1, zero
|
scasb.rep.nz ax1, zero
|
||||||
dec ax1
|
sub ax1, ax1, 1
|
||||||
|
|
||||||
; increase ax0 while decreasing ax1, performing exchanges
|
; increase ax0 while decreasing ax1, performing exchanges
|
||||||
.2:
|
.2:
|
||||||
@ -60,8 +60,8 @@ strrev2:
|
|||||||
xchg rax, b[ax0]
|
xchg rax, b[ax0]
|
||||||
mov b[ax1], rax
|
mov b[ax1], rax
|
||||||
|
|
||||||
inc ax0
|
add ax0, ax0, 1
|
||||||
dec ax1
|
sub ax1, ax1, 1
|
||||||
jmp .2
|
jmp .2
|
||||||
|
|
||||||
.3:
|
.3:
|
||||||
|
@ -28,17 +28,13 @@ TrapHandlers.epilog:
|
|||||||
|
|
||||||
; TRAP return values: RAX-RDX
|
; TRAP return values: RAX-RDX
|
||||||
|
|
||||||
mov ax0, r12
|
|
||||||
mov ax1, $rax
|
|
||||||
mov ax2, rax
|
mov ax2, rax
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, r12, $rax
|
||||||
|
|
||||||
mov ax1, $rdx
|
|
||||||
mov ax2, rdx
|
mov ax2, rdx
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, r12, $rdx
|
||||||
|
|
||||||
mov ax0, r11
|
call IDT.DoneHandling, r11
|
||||||
call IDT.DoneHandling
|
|
||||||
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
@ -37,18 +37,16 @@ trap0_handler:
|
|||||||
.handle_Exit:
|
.handle_Exit:
|
||||||
|
|
||||||
; Open COMMAND.COM
|
; Open COMMAND.COM
|
||||||
mov ax0, .cmdcom
|
call DISK.OpenFile, .cmdcom
|
||||||
call DISK.OpenFile
|
|
||||||
|
|
||||||
; Crash on failure
|
; Crash on failure
|
||||||
cmp rax, zero
|
cmp rax, zero
|
||||||
crash.l
|
crash.l
|
||||||
|
|
||||||
; Load at CMDCOM_LOADP
|
; Load at CMDCOM_LOADP
|
||||||
mov ax0, rax
|
|
||||||
mov ax1, CMDCOM_LOADP
|
mov ax1, CMDCOM_LOADP
|
||||||
mov ax2, CMDCOM_MAXSZ
|
mov ax2, CMDCOM_MAXSZ
|
||||||
call DISK.ReadFile
|
call DISK.ReadFile, rax
|
||||||
|
|
||||||
; Assume that COMMAND.COM being
|
; Assume that COMMAND.COM being
|
||||||
; less then 4KB means something
|
; less then 4KB means something
|
||||||
@ -57,32 +55,26 @@ trap0_handler:
|
|||||||
crash.b
|
crash.b
|
||||||
|
|
||||||
; Close the handle
|
; Close the handle
|
||||||
mov ax0, rax
|
call DISK.CloseFile, rax
|
||||||
call DISK.CloseFile
|
|
||||||
|
|
||||||
; Code address
|
; Code address
|
||||||
mov ax0, zero
|
|
||||||
mov ax1, $rip
|
|
||||||
mov ax2, 0x100000
|
mov ax2, 0x100000
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, zero, $rip
|
||||||
|
|
||||||
; Usermode
|
; Usermode
|
||||||
mov ax1, $cr0
|
|
||||||
mov ax2, 3
|
mov ax2, 3
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, zero, $cr0
|
||||||
|
|
||||||
mov rcx, CMDCOM_LOADP
|
mov rcx, CMDCOM_LOADP
|
||||||
sub rcx, rcx, 0x100000
|
sub rcx, rcx, 0x100000
|
||||||
|
|
||||||
; Code offset
|
; Code offset
|
||||||
mov ax1, $cr1
|
|
||||||
mov ax2, rcx
|
mov ax2, rcx
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, zero, $cr1
|
||||||
|
|
||||||
; Data offset
|
; Data offset
|
||||||
mov ax1, $cr2
|
|
||||||
mov ax2, rcx
|
mov ax2, rcx
|
||||||
call RFS.StoreReg
|
call RFS.StoreReg, zero, $cr2
|
||||||
|
|
||||||
; Return frame
|
; Return frame
|
||||||
mov q[rbp-16], zero
|
mov q[rbp-16], zero
|
||||||
@ -128,7 +120,9 @@ trap0_handler:
|
|||||||
.handle_HaltMode:
|
.handle_HaltMode:
|
||||||
hlt
|
hlt
|
||||||
.HLT.loop:
|
.HLT.loop:
|
||||||
xpause
|
pause
|
||||||
|
pause
|
||||||
|
pause
|
||||||
|
|
||||||
scan rax
|
scan rax
|
||||||
b.z rax, zero, .HLT.loop
|
b.z rax, zero, .HLT.loop
|
||||||
|
@ -1,6 +1,61 @@
|
|||||||
; The OS/K Team licenses this file to you under the MIT license.
|
; The OS/K Team licenses this file to you under the MIT license.
|
||||||
; See the LICENSE file in the project root for more information.
|
; See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
arith128_test:
|
||||||
|
call .test_add
|
||||||
|
call .test_sub
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.print_lq:
|
||||||
|
push rax
|
||||||
|
push rdx
|
||||||
|
mov ax0, .fmt
|
||||||
|
call printf
|
||||||
|
add rsp, rsp, 16
|
||||||
|
prn 10
|
||||||
|
ret
|
||||||
|
.fmt = "0x%x:%x"
|
||||||
|
|
||||||
|
.test_add:
|
||||||
|
|
||||||
|
mov ax0, 0x99AABBCCDDEEFF00
|
||||||
|
mov ax1, 0x1122334455667788
|
||||||
|
mov ax2, 0xFF
|
||||||
|
call add_lq_q
|
||||||
|
call .print_lq
|
||||||
|
|
||||||
|
mov ax0, 0xFFFFFFFFFFFFFFFF
|
||||||
|
mov ax1, zero
|
||||||
|
mov ax2, 5
|
||||||
|
call add_lq_q
|
||||||
|
call .print_lq
|
||||||
|
|
||||||
|
mov ax0, 0x5500660077008800
|
||||||
|
mov ax1, 0x1100220033004400
|
||||||
|
mov ax2, 0x00AA00BB00CC00DD
|
||||||
|
mov ax3, 0x009900CE00DF00AB
|
||||||
|
call add_lq_lq
|
||||||
|
call .print_lq
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.test_sub:
|
||||||
|
|
||||||
|
mov ax0, 0x99AABBCCDDEEFFFF
|
||||||
|
mov ax1, 0x1122334455667788
|
||||||
|
mov ax2, 0xFF
|
||||||
|
call sub_lq_q
|
||||||
|
call .print_lq
|
||||||
|
|
||||||
|
mov ax0, zero
|
||||||
|
mov ax1, zero
|
||||||
|
mov ax2, 2
|
||||||
|
call sub_lq_q
|
||||||
|
call .print_lq
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
file_test:
|
file_test:
|
||||||
.bufsize := 256
|
.bufsize := 256
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ builtins.dir:
|
|||||||
b.z rax, 0, .end
|
b.z rax, 0, .end
|
||||||
|
|
||||||
; found something
|
; found something
|
||||||
inc nx0
|
add nx0, nx0, 1
|
||||||
|
|
||||||
; separate extension from file name
|
; separate extension from file name
|
||||||
mov rcx, NAME_MAX
|
mov rcx, NAME_MAX
|
||||||
@ -46,13 +46,13 @@ builtins.dir:
|
|||||||
|
|
||||||
; calculate where to put extension
|
; calculate where to put extension
|
||||||
sub r11, r10, .buf
|
sub r11, r10, .buf
|
||||||
dec r11
|
sub r11, r11, 1
|
||||||
|
|
||||||
.ext_pad:
|
.ext_pad:
|
||||||
; print at least 11 non-space characters before extension
|
; print at least 11 non-space characters before extension
|
||||||
b.ae r11, 11, .print_ext
|
b.ae r11, 11, .print_ext
|
||||||
prn ' '
|
prn ' '
|
||||||
inc r11
|
add r11, r11, 1
|
||||||
jmp .ext_pad
|
jmp .ext_pad
|
||||||
|
|
||||||
.print_ext:
|
.print_ext:
|
||||||
@ -61,15 +61,16 @@ builtins.dir:
|
|||||||
prn ' '
|
prn ' '
|
||||||
|
|
||||||
cmp b[r10], '.'
|
cmp b[r10], '.'
|
||||||
inc.z r10
|
add.z r10, r10, 1
|
||||||
|
|
||||||
.print_ext.1:
|
.print_ext.1:
|
||||||
b.z b[r10], 0, .print_ext.2
|
b.z b[r10], 0, .print_ext.2
|
||||||
|
|
||||||
; print and decrease rcx, unless it's already 0
|
; print and decrease rcx, unless it's already 0
|
||||||
prn b[r10]
|
mov r12, b[r10]
|
||||||
inc r10
|
prn r12
|
||||||
dec.cxnz rcx
|
add r10, r10, 1
|
||||||
|
sub.cxnz rcx, rcx, 1
|
||||||
|
|
||||||
jmp .print_ext.1
|
jmp .print_ext.1
|
||||||
|
|
||||||
@ -88,10 +89,9 @@ builtins.dir:
|
|||||||
shr rax, rdx, 10
|
shr rax, rdx, 10
|
||||||
and rdx, rdx, 1023
|
and rdx, rdx, 1023
|
||||||
|
|
||||||
mov ax0, .bytesstr
|
|
||||||
push rdx
|
push rdx
|
||||||
push rax
|
push rax
|
||||||
call printf
|
call printf, .bytesstr
|
||||||
add rsp, rsp, 16
|
add rsp, rsp, 16
|
||||||
|
|
||||||
.bytesstr = "%d kilobytes + %d bytes"
|
.bytesstr = "%d kilobytes + %d bytes"
|
||||||
@ -102,14 +102,11 @@ builtins.dir:
|
|||||||
jmp .next
|
jmp .next
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
mov ax0, .endstr1
|
|
||||||
push nx0
|
push nx0
|
||||||
call printf
|
call printf, .endstr1
|
||||||
add rsp, rsp, 8
|
add rsp, rsp, 8
|
||||||
|
|
||||||
mov rcx, STRLEN_MAX
|
call print, .endstr2
|
||||||
mov rdx, .endstr2
|
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
pop nx0
|
pop nx0
|
||||||
ret
|
ret
|
||||||
|
@ -13,9 +13,7 @@ ps1 = "C:\\> "
|
|||||||
main:
|
main:
|
||||||
|
|
||||||
.print_prompt:
|
.print_prompt:
|
||||||
mov rcx, STRLEN_MAX
|
call print, ps1
|
||||||
mov rdx, ps1
|
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
; empty argbuf
|
; empty argbuf
|
||||||
mov rcx, argbuf.size
|
mov rcx, argbuf.size
|
||||||
@ -43,7 +41,7 @@ main:
|
|||||||
b.z rcx, zero, .input_loop
|
b.z rcx, zero, .input_loop
|
||||||
|
|
||||||
; delete it
|
; delete it
|
||||||
dec rcx
|
sub rcx, rcx, 1
|
||||||
add rdx, rcx, argbuf
|
add rdx, rcx, argbuf
|
||||||
mov b[rdx], zero
|
mov b[rdx], zero
|
||||||
|
|
||||||
@ -65,7 +63,7 @@ main:
|
|||||||
; add character to buffer and increase iterator (rcx)
|
; add character to buffer and increase iterator (rcx)
|
||||||
add rdx, rcx, argbuf
|
add rdx, rcx, argbuf
|
||||||
mov b[rdx], rax
|
mov b[rdx], rax
|
||||||
inc rcx
|
add rcx, rcx, 1
|
||||||
|
|
||||||
; another one
|
; another one
|
||||||
jmp .input_loop
|
jmp .input_loop
|
||||||
@ -83,7 +81,7 @@ main:
|
|||||||
; argv1 exists? if so, save its position
|
; argv1 exists? if so, save its position
|
||||||
mov r11, rdx
|
mov r11, rdx
|
||||||
b.z b[r11], zero, .no_argv1
|
b.z b[r11], zero, .no_argv1
|
||||||
inc r11
|
add r11, r11, 1
|
||||||
|
|
||||||
.next_space:
|
.next_space:
|
||||||
mov r10, b[r11]
|
mov r10, b[r11]
|
||||||
@ -91,7 +89,7 @@ main:
|
|||||||
|
|
||||||
; skip spaces
|
; skip spaces
|
||||||
cmp r10, ' '
|
cmp r10, ' '
|
||||||
inc.z r11
|
add.z r11, r11, 1
|
||||||
jmp.z .next_space
|
jmp.z .next_space
|
||||||
|
|
||||||
mov q[argv1pos], r11
|
mov q[argv1pos], r11
|
||||||
@ -108,68 +106,59 @@ main:
|
|||||||
sub rcx, rdx, argbuf
|
sub rcx, rdx, argbuf
|
||||||
mov rdx, argbuf
|
mov rdx, argbuf
|
||||||
mov rax, argv0
|
mov rax, argv0
|
||||||
movsb.rep rax, rdx
|
|
||||||
|
.mmove:
|
||||||
|
jmp.cxz .detect_builtin
|
||||||
|
|
||||||
|
mov r11, b[rdx]
|
||||||
|
mov b[rax], r11
|
||||||
|
|
||||||
|
add rdx, rdx, 1
|
||||||
|
add rax, rax, 1
|
||||||
|
sub rcx, rcx, 1
|
||||||
|
|
||||||
|
jmp .mmove
|
||||||
|
|
||||||
.detect_builtin:
|
.detect_builtin:
|
||||||
|
|
||||||
.builtin_cls = "cls"
|
.builtin_cls = "cls"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_cls
|
||||||
mov ax1, .builtin_cls
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_CLS
|
b.z rax, 0, .handle_CLS
|
||||||
|
|
||||||
.builtin_date = "date"
|
.builtin_date = "date"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_date
|
||||||
mov ax1, .builtin_date
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_DATE
|
b.z rax, 0, .handle_DATE
|
||||||
|
|
||||||
.builtin_dir = "dir"
|
.builtin_dir = "dir"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_dir
|
||||||
mov ax1, .builtin_dir
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_DIR
|
b.z rax, 0, .handle_DIR
|
||||||
|
|
||||||
.builtin_dump = "dump"
|
.builtin_dump = "dump"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_dump
|
||||||
mov ax1, .builtin_dump
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_DUMP
|
b.z rax, 0, .handle_DUMP
|
||||||
|
|
||||||
.builtin_echo = "echo"
|
.builtin_echo = "echo"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_echo
|
||||||
mov ax1, .builtin_echo
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_ECHO
|
b.z rax, 0, .handle_ECHO
|
||||||
|
|
||||||
.builtin_exit = "exit"
|
.builtin_exit = "exit"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_exit
|
||||||
mov ax1, .builtin_exit
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_EXIT
|
b.z rax, 0, .handle_EXIT
|
||||||
|
|
||||||
.builtin_help = "help"
|
.builtin_help = "help"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_help
|
||||||
mov ax1, .builtin_help
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_HELP
|
b.z rax, 0, .handle_HELP
|
||||||
|
|
||||||
.builtin_print = "print"
|
.builtin_print = "print"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_print
|
||||||
mov ax1, .builtin_print
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_PRINT
|
b.z rax, 0, .handle_PRINT
|
||||||
|
|
||||||
.builtin_time = "time"
|
.builtin_time = "time"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_time
|
||||||
mov ax1, .builtin_time
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_TIME
|
b.z rax, 0, .handle_TIME
|
||||||
|
|
||||||
.builtin_ver = "ver"
|
.builtin_ver = "ver"
|
||||||
mov ax0, argv0
|
call strcmp, argv0, .builtin_ver
|
||||||
mov ax1, .builtin_ver
|
|
||||||
call strcmp
|
|
||||||
b.z rax, 0, .handle_VER
|
b.z rax, 0, .handle_VER
|
||||||
|
|
||||||
jmp .command_not_found
|
jmp .command_not_found
|
||||||
@ -182,19 +171,17 @@ main:
|
|||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
.handle_DATE:
|
.handle_DATE:
|
||||||
time ax0
|
|
||||||
call GetTimeUTC
|
call GetTimeUTC
|
||||||
|
|
||||||
push b[rax+3]
|
push b[rax+3]
|
||||||
mov rcx, b[rax+4]
|
mov rcx, b[rax+4]
|
||||||
inc rcx
|
add rcx, rcx, 1
|
||||||
push rcx
|
push rcx
|
||||||
push w[rax+6]
|
push w[rax+6]
|
||||||
|
|
||||||
mov ax0, .datefmt
|
call printf, .datefmt
|
||||||
call printf
|
|
||||||
|
|
||||||
add rsp, rsp, 5*8
|
add rsp, rsp, 40
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
@ -252,53 +239,36 @@ main:
|
|||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
.handle_TIME:
|
.handle_TIME:
|
||||||
time ax0
|
|
||||||
call GetTimeUTC
|
call GetTimeUTC
|
||||||
|
|
||||||
push b[rax]
|
push b[rax]
|
||||||
push b[rax+1]
|
push b[rax+1]
|
||||||
push b[rax+2]
|
push b[rax+2]
|
||||||
mov ax0, .timefmt
|
call printf, .timefmt
|
||||||
call printf
|
add rsp, rsp, 24
|
||||||
add rsp, rsp, 3*8
|
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
.timefmt = "%d:%d:%d\n"
|
.timefmt = "%d:%d:%d\n"
|
||||||
|
|
||||||
.handle_VER:
|
.handle_VER:
|
||||||
mov rcx, STRLEN_MAX
|
call print, cmd.versionstr
|
||||||
mov rdx, cmd.versionstr
|
|
||||||
prns.rep.nz rdx
|
|
||||||
prn 10
|
prn 10
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
.handle_HELP:
|
.handle_HELP:
|
||||||
mov rcx, STRLEN_MAX
|
call print, .helpmsg
|
||||||
|
call print, .helpmsg.cls
|
||||||
mov rdx, .helpmsg
|
call print, .helpmsg.date
|
||||||
prns.rep.nz rdx
|
call print, .helpmsg.dir
|
||||||
mov rdx, .helpmsg.cls
|
call print, .helpmsg.dump
|
||||||
prns.rep.nz rdx
|
call print, .helpmsg.echo
|
||||||
mov rdx, .helpmsg.date
|
call print, .helpmsg.exit
|
||||||
prns.rep.nz rdx
|
call print, .helpmsg.help
|
||||||
mov rdx, .helpmsg.dir
|
call print, .helpmsg.print
|
||||||
prns.rep.nz rdx
|
call print, .helpmsg.time
|
||||||
mov rdx, .helpmsg.dump
|
call print, .helpmsg.ver
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.echo
|
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.exit
|
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.help
|
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.print
|
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.time
|
|
||||||
prns.rep.nz rdx
|
|
||||||
mov rdx, .helpmsg.ver
|
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
@ -315,22 +285,17 @@ main:
|
|||||||
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"
|
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"
|
||||||
|
|
||||||
.command_not_found:
|
.command_not_found:
|
||||||
mov rcx, STRLEN_MAX
|
call print, argv0
|
||||||
mov rdx, argv0
|
call print, .cnf_errmsg
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
mov rdx, .cnf_errmsg
|
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
.cnf_errmsg = ": command not found\n"
|
.cnf_errmsg = ": command not found\n"
|
||||||
|
|
||||||
.file_not_found:
|
.file_not_found:
|
||||||
mov ax0, .fnf_errmsg
|
|
||||||
push q[argv1pos]
|
push q[argv1pos]
|
||||||
push argv0
|
push argv0
|
||||||
call printf
|
call printf, .fnf_errmsg
|
||||||
add rsp, rsp, 16
|
add rsp, rsp, 16
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
@ -338,10 +303,9 @@ main:
|
|||||||
.fnf_errmsg = "%s: %s: file not found\n"
|
.fnf_errmsg = "%s: %s: file not found\n"
|
||||||
|
|
||||||
.empty_file:
|
.empty_file:
|
||||||
mov ax0, .ef_errmsg
|
|
||||||
push q[argv1pos]
|
push q[argv1pos]
|
||||||
push argv0
|
push argv0
|
||||||
call printf
|
call printf, .ef_errmsg
|
||||||
add rsp, rsp, 16
|
add rsp, rsp, 16
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
@ -349,10 +313,9 @@ main:
|
|||||||
.ef_errmsg = "%s: %s: file is empty\n"
|
.ef_errmsg = "%s: %s: file is empty\n"
|
||||||
|
|
||||||
.couldnt_read:
|
.couldnt_read:
|
||||||
mov ax0, .cno_errmsg
|
|
||||||
push q[argv1pos]
|
push q[argv1pos]
|
||||||
push argv0
|
push argv0
|
||||||
call printf
|
call printf, .cno_errmsg
|
||||||
add rsp, rsp, 16
|
add rsp, rsp, 16
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
@ -360,12 +323,8 @@ main:
|
|||||||
.cno_errmsg = "%s: %s: an error occured while reading file\n"
|
.cno_errmsg = "%s: %s: an error occured while reading file\n"
|
||||||
|
|
||||||
.need_params:
|
.need_params:
|
||||||
mov rcx, STRLEN_MAX
|
call print, argv0
|
||||||
mov rdx, argv0
|
call print, .np_errmsg
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
mov rdx, .np_errmsg
|
|
||||||
prns.rep.nz rdx
|
|
||||||
|
|
||||||
jmp .print_prompt
|
jmp .print_prompt
|
||||||
|
|
||||||
|
@ -46,14 +46,14 @@ $(OBJDIR)/%.d: %.c
|
|||||||
# echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
|
# echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
|
||||||
# fi
|
# fi
|
||||||
|
|
||||||
in/instrs.lst: in/INSTRS in/arch_i.py
|
ob/instrs.lst: in/arch_i.py
|
||||||
@cd in && python3 arch_i.py
|
@cd in && python3 arch_i.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f $(OBJDIR)/*/*.o in/arch_i.h in/instrs.lst
|
@rm -f $(OBJDIR)/*/*.o ob/arch_i.h ob/instrs.lst
|
||||||
@rm -f $(OBJDIR)/*/*.d
|
@rm -f $(OBJDIR)/*/*.d
|
||||||
|
|
||||||
$(KEXE): in/instrs.lst $(obj)
|
$(KEXE): ob/instrs.lst $(obj)
|
||||||
@gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE)
|
@gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE)
|
||||||
@echo ${CL2}[$@] ${CL}made successfully.${CL3}
|
@echo ${CL2}[$@] ${CL}made successfully.${CL3}
|
||||||
|
|
||||||
|
106
vm/in/ALU
106
vm/in/ALU
@ -5,15 +5,6 @@
|
|||||||
# Logical instructions #
|
# Logical instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
#
|
|
||||||
# Bitwise NOT operation
|
|
||||||
#
|
|
||||||
# $1 = NOT($2)
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
not r r
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bitwise OR operation
|
# Bitwise OR operation
|
||||||
#
|
#
|
||||||
@ -22,10 +13,6 @@ not r r
|
|||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
or r r ri
|
or r r ri
|
||||||
# $dest = $src1 OR NOT($src2)
|
|
||||||
orn r r ri
|
|
||||||
# $dest = NOT($src1 OR $src2)
|
|
||||||
nor r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bitwise AND operation
|
# Bitwise AND operation
|
||||||
@ -35,10 +22,6 @@ nor r r ri
|
|||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
and r r ri
|
and r r ri
|
||||||
# $dest = $src1 AND NOT($src2)
|
|
||||||
andn r r ri
|
|
||||||
# $dest = NOT($src1 AND $src2)
|
|
||||||
nand r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bitwise XOR operation
|
# Bitwise XOR operation
|
||||||
@ -48,10 +31,6 @@ nand r r ri
|
|||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
xor r r ri
|
xor r r ri
|
||||||
# $dest = $src1 XOR NOT($src2)
|
|
||||||
xorn r r ri
|
|
||||||
# $dest = NOT($src1 XOR $src2)
|
|
||||||
xnor r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Logical left/right shift (SHL/SHR)
|
# Logical left/right shift (SHL/SHR)
|
||||||
@ -91,50 +70,6 @@ sar r r ri
|
|||||||
cmp r ri
|
cmp r ri
|
||||||
cmp m ri
|
cmp m ri
|
||||||
|
|
||||||
#
|
|
||||||
# Arithmetical SGN operation
|
|
||||||
#
|
|
||||||
# IF ($1 == 0) THEN
|
|
||||||
# $2 = 0
|
|
||||||
# ELIF ($1 GT 0) THEN
|
|
||||||
# $2 = 1
|
|
||||||
# ELSE
|
|
||||||
# $2 = LONG_MIN
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Treats $1 and $2 as signed values
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
sgn r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Arithmetical NEG operation
|
|
||||||
#
|
|
||||||
# $1 = NOT($2) + 1
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
neg r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Arithmetical INC operation
|
|
||||||
#
|
|
||||||
# $1 = $1 + 1
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
inc r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Arithmetical DEC operation
|
|
||||||
#
|
|
||||||
# $1 = $1 - 1
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
dec r
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical ADD operation
|
# Arithmetical ADD operation
|
||||||
#
|
#
|
||||||
@ -146,7 +81,6 @@ dec r
|
|||||||
#
|
#
|
||||||
add r r ri
|
add r r ri
|
||||||
addf r r ri
|
addf r r ri
|
||||||
addo r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical SUB operation
|
# Arithmetical SUB operation
|
||||||
@ -159,26 +93,22 @@ addo r r ri
|
|||||||
#
|
#
|
||||||
sub r r ri
|
sub r r ri
|
||||||
subf r r ri
|
subf r r ri
|
||||||
subo r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||||
#
|
#
|
||||||
# $dest = $src1 + $src2 + CF (ADC)
|
# $dest = $src1 + $src2 + CF (ADC)
|
||||||
# $dest = $src1 + $src2 + OF (ADO)
|
|
||||||
# $dest = $src1 - $src2 - CF (SBB)
|
# $dest = $src1 - $src2 - CF (SBB)
|
||||||
# $dest = $src1 - $src2 - OF (SBO)
|
|
||||||
#
|
#
|
||||||
# Preserves ZF and SF
|
# Sets CF if unsigned integer overflow occur, clears it otherwise
|
||||||
# Flags CF and OF are undefined for now
|
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||||
|
# Sets ZF and SF according to the result
|
||||||
#
|
#
|
||||||
adcx r r ri
|
adcx r r ri
|
||||||
adox r r ri
|
|
||||||
sbbx r r ri
|
sbbx r r ri
|
||||||
sbox r r ri
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical unsigned MUL operation
|
# Arithmetical MUL operation
|
||||||
#
|
#
|
||||||
# $dest = LO($src1 * $src2)
|
# $dest = LO($src1 * $src2)
|
||||||
#
|
#
|
||||||
@ -187,31 +117,47 @@ sbox r r ri
|
|||||||
#
|
#
|
||||||
mul r r ri
|
mul r r ri
|
||||||
mulf r r ri
|
mulf r r ri
|
||||||
mulo r r ri
|
|
||||||
|
|
||||||
# Arithmetical unsigned MUL operation
|
# Arithmetical unsigned MUL operation
|
||||||
#
|
#
|
||||||
# $dest1 = HI($dest2 * $src)
|
# $dest1 = HI($dest2 * $src)
|
||||||
# $dest2 = LO($dest2 * $src)
|
# $dest2 = LO($dest2 * $src)
|
||||||
#
|
#
|
||||||
# Sets CF and OF if HI($2 * $3) > 0, clears them otherwise
|
# Preserves all flags
|
||||||
# Preserves ZF and SF
|
|
||||||
#
|
#
|
||||||
mulhi r r ri
|
mulhi r r ri
|
||||||
|
|
||||||
|
# Arithmetical signed MUL operation
|
||||||
|
#
|
||||||
|
# $dest1 = HI($dest2 ** $src)
|
||||||
|
# $dest2 = LO($dest2 ** $src)
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
imulhi r r ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical unsigned DIV operation
|
# Arithmetical unsigned DIV operation
|
||||||
#
|
#
|
||||||
# $dest1 = $1 DIV $2
|
# $dest = $src1 DIV $src2
|
||||||
#
|
#
|
||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
div r r ri
|
div r r ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical unsigned modulo operation (REM)
|
# Arithmetical signed DIV operation
|
||||||
#
|
#
|
||||||
# $1 = $1 MOD $2
|
# $dest = $src1 IDIV $src2
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
idiv r r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Arithmetical modulo operation (REM)
|
||||||
|
#
|
||||||
|
# $dest = $src1 MOD $src2
|
||||||
#
|
#
|
||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
|
84
vm/in/MISC
84
vm/in/MISC
@ -24,36 +24,21 @@ dump
|
|||||||
# Misc. instructions #
|
# Misc. instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
#
|
|
||||||
# Do nothing (NOOP)
|
|
||||||
#
|
|
||||||
# (nothing)
|
|
||||||
#
|
|
||||||
# Throws:
|
|
||||||
# (nothing)
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
nop
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Pause the CPU for a very short amount of time (PAUSE)
|
# Pause the CPU for a very short amount of time (PAUSE)
|
||||||
# Used in spin-like loops
|
# Used in spin-type loops
|
||||||
#
|
#
|
||||||
pause
|
pause
|
||||||
|
|
||||||
#
|
#
|
||||||
# Pause the CPU for a relatively long time (XPAUSE)
|
# Throw #OVF when RFX.OF=1 (INTO)
|
||||||
#
|
#
|
||||||
# Throws:
|
into
|
||||||
# #SYS if not in supervisor mode
|
|
||||||
#
|
|
||||||
xpause
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get timestamp in seconds
|
# Get timestamp in µseconds
|
||||||
#
|
#
|
||||||
time r
|
utime r r
|
||||||
|
|
||||||
#
|
#
|
||||||
# $1 = seconds since start of month
|
# $1 = seconds since start of month
|
||||||
@ -62,68 +47,11 @@ time r
|
|||||||
#
|
#
|
||||||
ytime r r r
|
ytime r r r
|
||||||
|
|
||||||
#
|
|
||||||
# Get timestamp in µseconds
|
|
||||||
#
|
|
||||||
utime r
|
|
||||||
|
|
||||||
#
|
|
||||||
# CPU Identification Number
|
|
||||||
#
|
|
||||||
# Does nothing (for now)
|
|
||||||
#
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Clean-up misc. instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clear all GPR registers except RBP/RSP
|
# Clear all GPR registers except RBP/RSP
|
||||||
#
|
#
|
||||||
cls
|
cls
|
||||||
|
|
||||||
#
|
|
||||||
# Clear base registers except RBP/RSP (CLR)
|
|
||||||
#
|
|
||||||
clr
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear argument registers (CLA)
|
|
||||||
#
|
|
||||||
cla
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear nonvolatile registers (CLN)
|
|
||||||
#
|
|
||||||
cln
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Flag manipulation instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear or set interrupt flag (CLI/STI)
|
|
||||||
#
|
|
||||||
# Throws:
|
|
||||||
# #SYS if not in supervisor mode
|
|
||||||
#
|
|
||||||
cli
|
|
||||||
sti
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear or set direction flag (CLD/STD)
|
|
||||||
#
|
|
||||||
cld
|
|
||||||
std
|
|
||||||
|
|
||||||
#
|
|
||||||
# Complement, clear or set carry flag (CMC/CLC/STC)
|
|
||||||
#
|
|
||||||
cmc
|
|
||||||
clc
|
|
||||||
stc
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Byte-wise / bit-wise manipulation instructions #
|
# Byte-wise / bit-wise manipulation instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -144,7 +72,7 @@ dswap r r
|
|||||||
#
|
#
|
||||||
# Send a character to standard output (PRN)
|
# Send a character to standard output (PRN)
|
||||||
#
|
#
|
||||||
prn rim
|
prn ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Print a string to standard output (PRN)
|
# Print a string to standard output (PRN)
|
||||||
|
@ -52,6 +52,8 @@ b rm ri ri
|
|||||||
# JMP(RIP)
|
# JMP(RIP)
|
||||||
#
|
#
|
||||||
call ri
|
call ri
|
||||||
|
call i ri
|
||||||
|
call i ri ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Return to caller (RET)
|
# Return to caller (RET)
|
||||||
@ -103,9 +105,9 @@ pop r
|
|||||||
# $1 = ADDR($2)
|
# $1 = ADDR($2)
|
||||||
#
|
#
|
||||||
# For instance:
|
# For instance:
|
||||||
# LEA RAX, [RBX + RCX + 4]
|
# LEA RAX, [RBX + RCX * 2 + 4]
|
||||||
# will result in:
|
# will result in:
|
||||||
# RAX = RBX + RCX + 4
|
# RAX = RBX + RCX * 2 + 4
|
||||||
#
|
#
|
||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
|
74
vm/in/STRING
74
vm/in/STRING
@ -20,24 +20,6 @@ stosw r ri
|
|||||||
stosl r ri
|
stosl r ri
|
||||||
stosq r ri
|
stosq r ri
|
||||||
|
|
||||||
#
|
|
||||||
# Load value from string (LODSx)
|
|
||||||
#
|
|
||||||
# $1 = [%2]
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %str = %str + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %str = %str - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Preserves CF, OF and SF
|
|
||||||
# Sets ZF according to the loaded value
|
|
||||||
#
|
|
||||||
lodsb r r
|
|
||||||
lodsw r r
|
|
||||||
lodsl r r
|
|
||||||
lodsq r r
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Scan string for a particular value (SCASx)
|
# Scan string for a particular value (SCASx)
|
||||||
#
|
#
|
||||||
@ -65,61 +47,5 @@ scasw r ri
|
|||||||
scasl r ri
|
scasl r ri
|
||||||
scasq r ri
|
scasq r ri
|
||||||
|
|
||||||
#
|
|
||||||
# Compare bytes in strings (CMPSx)
|
|
||||||
#
|
|
||||||
# CMP([%1], [%2])
|
|
||||||
#
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + sizeof(x)
|
|
||||||
# %2 = %2 + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - sizeof(x)
|
|
||||||
# %2 = %2 - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Sets CF, OF, ZF and SF according to the result of the comparison
|
|
||||||
#
|
|
||||||
# Moves past the compared values in any case!
|
|
||||||
#
|
|
||||||
cmpsb r r
|
|
||||||
cmpsw r r
|
|
||||||
cmpsl r r
|
|
||||||
cmpsq r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Safe compare bytes in strings (CMPZSx)
|
|
||||||
#
|
|
||||||
# Behaves precisely like CMPSx, except in the following case:
|
|
||||||
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
|
|
||||||
#
|
|
||||||
# This prevents 'CMPZSx.REP.Z' from ignoring null-terminators when both strings
|
|
||||||
# have the exact same content; this allows for short strcmp's
|
|
||||||
#
|
|
||||||
cmpzsb r r
|
|
||||||
cmpzsw r r
|
|
||||||
cmpzsl r r
|
|
||||||
cmpzsq r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Move value from string to string (MOVSx)
|
|
||||||
#
|
|
||||||
# [%1] = [%2]
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + sizeof(x)
|
|
||||||
# %2 = %2 + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - sizeof(x)
|
|
||||||
# %2 = %2 - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Preserves CF, OF and SF
|
|
||||||
# Sets ZF according to the moved value
|
|
||||||
#
|
|
||||||
movsb r r
|
|
||||||
movsw r r
|
|
||||||
movsl r r
|
|
||||||
movsq r r
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
11
vm/in/SUPER
11
vm/in/SUPER
@ -58,6 +58,15 @@ trap ri
|
|||||||
#
|
#
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear or set interrupt flag (CLI/STI)
|
||||||
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
|
cli
|
||||||
|
sti
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Device control instructions #
|
# Device control instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -70,7 +79,7 @@ iret
|
|||||||
# Throws:
|
# Throws:
|
||||||
# #SYS if not in supervisor mode
|
# #SYS if not in supervisor mode
|
||||||
#
|
#
|
||||||
devctl ri ri
|
devctl r r
|
||||||
|
|
||||||
#
|
#
|
||||||
# Call a device-defined function slot of device (IOCALL)
|
# Call a device-defined function slot of device (IOCALL)
|
||||||
|
87
vm/in/alu.c
87
vm/in/alu.c
@ -4,26 +4,16 @@
|
|||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
|
|
||||||
#define _NEED_ARCH_I
|
#define _NEED_ARCH_I
|
||||||
#include <in/arch_i.h>
|
#include <ob/arch_i.h>
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT;
|
|
||||||
IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT;
|
IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT;
|
||||||
IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT;
|
IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT;
|
||||||
IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT;
|
IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_3(orn) { v1 = v2 | ~v3; } IMPL_OUT;
|
|
||||||
IMPL_START_3(nor) { v1 = ~(v2 | v3); } IMPL_OUT;
|
|
||||||
IMPL_START_3(andn) { v1 = v2 & ~v3; } IMPL_OUT;
|
|
||||||
IMPL_START_3(nand) { v1 = ~(v2 & v3); } IMPL_OUT;
|
|
||||||
IMPL_START_3(xorn) { v1 = v2 ^ ~v3; } IMPL_OUT;
|
|
||||||
IMPL_START_3(xnor) { v1 = ~(v2 ^ v3); } IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT;
|
IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT;
|
||||||
IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT;
|
IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT;
|
||||||
IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT;
|
IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT;
|
||||||
@ -31,81 +21,64 @@ IMPL_START_3(sar) { v1 = (ulong)((long)v2 >> (long)v3); } IMPL_OUT;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2(sgn) { v1 = (!v2 ? 0: ((long)v2 < 0 ? (ulong)-1L : 1)); } IMPL_OUT;
|
|
||||||
IMPL_START_2(neg) { v1 = ~v2 + 1; } IMPL_OUT;
|
|
||||||
IMPL_START_1(inc) { v1++; } IMPL_OUT;
|
|
||||||
IMPL_START_1(dec) { v1--; } IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
|
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
|
||||||
IMPL_START_3(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT;
|
IMPL_START_3(addf) { COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
|
||||||
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(cmp) { COMPARE_SUB(v1, v2); } IMPL_END;
|
||||||
IMPL_START_3(sub) { v1 = v2 - v3; } 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(subf){ COMPARE_SUB(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 + !!(R(RFX)&CF); } IMPL_OUT;
|
IMPL_START_3(adcx) { v3 += !!(R(RFX)&CF); COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
|
||||||
IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } IMPL_OUT;
|
IMPL_START_3(sbbx) { v3 += !!(R(RFX)&CF); COMPARE_SUB(v2, v3); v1 = v2 - v3; } 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;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
||||||
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
|
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
|
||||||
IMPL_START_3(div) {
|
IMPL_START_3(div) {
|
||||||
if (!v3)
|
if (!v3)
|
||||||
_except(ctx, E_DIV, "DIV by 0");
|
_except(ctx, E_DIV, "DIV by 0");
|
||||||
v1 = v2 / v3;
|
v1 = v2 / v3;
|
||||||
} IMPL_OUT;
|
} IMPL_OUT;
|
||||||
|
IMPL_START_3(idiv) {
|
||||||
|
if (!v3)
|
||||||
|
_except(ctx, E_DIV, "IDIV by 0");
|
||||||
|
v1 = (ulong)((long)v2/(long)v3);
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
//
|
static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||||
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
|
||||||
//
|
|
||||||
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
|
||||||
{
|
{
|
||||||
ulong u1 = (u & 0xffffffff);
|
__uint128_t r = (__uint128_t)u * (__uint128_t)v;
|
||||||
ulong v1 = (v & 0xffffffff);
|
|
||||||
ulong t = (u1 * v1);
|
|
||||||
ulong w3 = (t & 0xffffffff);
|
|
||||||
ulong k = (t >> 32);
|
|
||||||
|
|
||||||
u >>= 32;
|
*hi = r >> 64;
|
||||||
t = (u * v1) + k;
|
*lo = r;
|
||||||
k = (t & 0xffffffff);
|
|
||||||
ulong w1 = (t >> 32);
|
|
||||||
|
|
||||||
v >>= 32;
|
|
||||||
t = (u1 * v) + k;
|
|
||||||
k = (t >> 32);
|
|
||||||
|
|
||||||
if (hi) *hi = (u * v) + w1 + k;
|
|
||||||
if (lo) *lo = (t << 32) + w3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
IMPL_START_3(mulhi) { __unsigned_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
||||||
IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
|
||||||
|
|
||||||
IMPL_START_3(mulf) {
|
IMPL_START_3(mulf) {
|
||||||
ulong tmp;
|
ulong tmp;
|
||||||
multiply(v2, v3, &tmp, &v1);
|
__unsigned_multiply128(v2, v3, &tmp, &v1);
|
||||||
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||||
} IMPL_OUT;
|
} IMPL_OUT;
|
||||||
|
|
||||||
IMPL_START_3(mulo) {
|
//----------------------------------------------------------------------------//
|
||||||
ulong tmp;
|
|
||||||
multiply(v2, v3, &tmp, &v1);
|
static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||||
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
{
|
||||||
INTO();
|
__int128_t r = (__int128_t)(long)u * (__int128_t)(long)v;
|
||||||
} IMPL_OUT;
|
|
||||||
|
*hi = r >> 64;
|
||||||
|
*lo = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPL_START_3(imulhi) { __signed_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
@ -131,8 +131,8 @@ def parse_2(fp):
|
|||||||
count = count + 1
|
count = count + 1
|
||||||
|
|
||||||
fi = open("INSTRS")
|
fi = open("INSTRS")
|
||||||
hd = open("arch_i.h", "w")
|
hd = open("../ob/arch_i.h", "w")
|
||||||
ls = open("instrs.lst", "w")
|
ls = open("../ob/instrs.lst", "w")
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
#include <pc/arch.h>
|
#include <pc/arch.h>
|
||||||
#include <in/arch_i.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -108,18 +107,29 @@ IMPL_START_2(name) \
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#define COMPARE(v1, v2) \
|
#define COMPARE_ADD(v1, v2) \
|
||||||
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
|
ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 + _u2); \
|
||||||
long _s1 = (long)v1, _s2 = (long)v2; \
|
\
|
||||||
|
if (_u1 + _u2 < _u2) R(RFX) |= CF; \
|
||||||
|
else R(RFX) &= ~CF; \
|
||||||
|
\
|
||||||
|
if (((_u1 ^ _u3) & (_u2 ^ _u3)) >> 63) \
|
||||||
|
R(RFX) |= OF; \
|
||||||
|
else R(RFX) &= ~OF; \
|
||||||
|
\
|
||||||
|
SET_ZSF(_u3);
|
||||||
|
|
||||||
|
#define COMPARE_SUB(v1, v2) \
|
||||||
|
ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 - _u2); \
|
||||||
\
|
\
|
||||||
if (_u1 < _u2) R(RFX) |= CF; \
|
if (_u1 < _u2) R(RFX) |= CF; \
|
||||||
else R(RFX) &= ~CF; \
|
else R(RFX) &= ~CF; \
|
||||||
\
|
\
|
||||||
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|
if (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \
|
||||||
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
|
|
||||||
R(RFX) |= OF; \
|
R(RFX) |= OF; \
|
||||||
else R(RFX) &= ~OF; \
|
else R(RFX) &= ~OF; \
|
||||||
SET_ZSF(_u1 - _u2);
|
\
|
||||||
|
SET_ZSF(_u3);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
27
vm/in/misc.c
27
vm/in/misc.c
@ -9,11 +9,8 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(nop) {} IMPL_END;
|
IMPL_START_0(into) { INTO(); } IMPL_END;
|
||||||
IMPL_START_0(cpuid) { rax = rdx = 0; } IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(pause) { usleep(5000); } IMPL_END;
|
IMPL_START_0(pause) { usleep(5000); } IMPL_END;
|
||||||
IMPL_START_0(xpause) { CHK_SUPERV(); usleep(25000); } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -46,8 +43,6 @@ IMPL_END;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_X_NOIN(time) { v1 = time(NULL); } IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_X_NOIN(ytime)
|
IMPL_START_X_NOIN(ytime)
|
||||||
{
|
{
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
@ -77,24 +72,6 @@ IMPL_START_0(cls) {
|
|||||||
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
||||||
} IMPL_END;
|
} IMPL_END;
|
||||||
|
|
||||||
IMPL_START_0(clr) {
|
|
||||||
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
|
||||||
for (int i = R10; i <= R15; i++) R(i) = 0;
|
|
||||||
} IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cla) { for (int i = AX0; i <= AX7; i++) R(i) = 0; } IMPL_END;
|
|
||||||
IMPL_START_0(cln) { for (int i = NX0; i <= NX7; i++) R(i) = 0; } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END;
|
|
||||||
IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END;
|
|
||||||
IMPL_START_0(cld) { R(RFX) &= ~DF; } IMPL_END;
|
|
||||||
IMPL_START_0(clc) { R(RFX) &= ~CF; } IMPL_END;
|
|
||||||
IMPL_START_0(std) { R(RFX) |= DF; } IMPL_END;
|
|
||||||
IMPL_START_0(stc) { R(RFX) |= CF; } IMPL_END;
|
|
||||||
IMPL_START_0(cmc) { R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF); } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2(bswap)
|
IMPL_START_2(bswap)
|
||||||
@ -151,7 +128,7 @@ IMPL_START_0(prns)
|
|||||||
{
|
{
|
||||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||||
|
|
||||||
COMPARE(ch, 0);
|
COMPARE_SUB(ch, 0);
|
||||||
|
|
||||||
if ((R(RFX) & ZF) == 0)
|
if ((R(RFX) & ZF) == 0)
|
||||||
{
|
{
|
||||||
|
23
vm/in/mov.c
23
vm/in/mov.c
@ -15,7 +15,7 @@ IMPL_START_1(loop) {
|
|||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
IMPL_START_3(b) {
|
IMPL_START_3(b) {
|
||||||
COMPARE(v1, v2);
|
COMPARE_SUB(v1, v2);
|
||||||
|
|
||||||
if (eval_cond(ctx, ctx->cond))
|
if (eval_cond(ctx, ctx->cond))
|
||||||
R(RIP) = v3;
|
R(RIP) = v3;
|
||||||
@ -51,11 +51,32 @@ IMPL_START_1(pop) {
|
|||||||
R(RSP) += 8;
|
R(RSP) += 8;
|
||||||
} IMPL_OUT;
|
} IMPL_OUT;
|
||||||
|
|
||||||
|
/*
|
||||||
IMPL_START_1(call) {
|
IMPL_START_1(call) {
|
||||||
R(RSP) -= 8;
|
R(RSP) -= 8;
|
||||||
writemem(ctx, R(RIP), R(RSP), 8);
|
writemem(ctx, R(RIP), R(RSP), 8);
|
||||||
R(RIP) = v1;
|
R(RIP) = v1;
|
||||||
} IMPL_END;
|
} IMPL_END;
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPL_START_1(call) {
|
||||||
|
R(RSP) -= 8;
|
||||||
|
writemem(ctx, R(RIP), R(RSP), 8);
|
||||||
|
R(RIP) = v1;
|
||||||
|
|
||||||
|
if (p2)
|
||||||
|
{
|
||||||
|
DECV(v2, p2);
|
||||||
|
ax0 = v2;
|
||||||
|
|
||||||
|
if (p3)
|
||||||
|
{
|
||||||
|
DECV(v3, p3);
|
||||||
|
ax1 = v3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
IMPL_START_0(ret) {
|
IMPL_START_0(ret) {
|
||||||
R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8;
|
R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8;
|
||||||
|
@ -25,26 +25,12 @@ IMPL_START_0(stosq) { stos_impl(ctx, p1, p2, 8); } IMPL_END;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|
||||||
{
|
|
||||||
R(p1->reg) = readmem(ctx, R(p2->reg), len);
|
|
||||||
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
|
|
||||||
STR_MOVE(p2->reg, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPL_START_0(lodsb) { lods_impl(ctx, p1, p2, 1); } IMPL_END;
|
|
||||||
IMPL_START_0(lodsw) { lods_impl(ctx, p1, p2, 2); } IMPL_END;
|
|
||||||
IMPL_START_0(lodsl) { lods_impl(ctx, p1, p2, 4); } IMPL_END;
|
|
||||||
IMPL_START_0(lodsq) { lods_impl(ctx, p1, p2, 8); } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||||
{
|
{
|
||||||
DECV(v2, p2);
|
DECV(v2, p2);
|
||||||
|
|
||||||
ulong x = readmem(ctx, R(p1->reg), len);
|
ulong x = readmem(ctx, R(p1->reg), len);
|
||||||
COMPARE(x, v2);
|
COMPARE_SUB(x, v2);
|
||||||
|
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
R(RFX) |= ZF;
|
R(RFX) |= ZF;
|
||||||
@ -62,45 +48,6 @@ IMPL_START_0(scasq) { scas_impl(ctx, p1, p2, 8); } IMPL_END;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|
||||||
{
|
|
||||||
ulong x1 = readmem(ctx, R(p1->reg), len);
|
|
||||||
ulong x2 = readmem(ctx, R(p2->reg), len);
|
|
||||||
|
|
||||||
COMPARE(x1, x2);
|
|
||||||
|
|
||||||
STR_MOVE(p1->reg, len);
|
|
||||||
STR_MOVE(p2->reg, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPL_START_0(cmpsb) { cmps_impl(ctx, p1, p2, 1); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpsw) { cmps_impl(ctx, p1, p2, 2); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpsl) { cmps_impl(ctx, p1, p2, 4); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpsq) { cmps_impl(ctx, p1, p2, 8); } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|
||||||
{
|
|
||||||
ulong x1 = readmem(ctx, R(p1->reg), len);
|
|
||||||
ulong x2 = readmem(ctx, R(p2->reg), len);
|
|
||||||
|
|
||||||
COMPARE(x1, x2);
|
|
||||||
|
|
||||||
if (!x1 && !x2)
|
|
||||||
R(RFX) &= ~ZF;
|
|
||||||
|
|
||||||
STR_MOVE(p1->reg, len);
|
|
||||||
STR_MOVE(p2->reg, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPL_START_0(cmpzsb) { cmpzs_impl(ctx, p1, p2, 1); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpzsw) { cmpzs_impl(ctx, p1, p2, 2); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpzsl) { cmpzs_impl(ctx, p1, p2, 4); } IMPL_END;
|
|
||||||
IMPL_START_0(cmpzsq) { cmpzs_impl(ctx, p1, p2, 8); } IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||||
{
|
{
|
||||||
ulong x = readmem(ctx, R(p2->reg), len);
|
ulong x = readmem(ctx, R(p2->reg), len);
|
||||||
|
@ -42,7 +42,6 @@ IMPL_START_1(trap) {
|
|||||||
_except(ctx, v1 + 256, "TRAP instruction");
|
_except(ctx, v1 + 256, "TRAP instruction");
|
||||||
} IMPL_END;
|
} IMPL_END;
|
||||||
|
|
||||||
IMPL_START_0(into) { INTO(); } IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(iret) {
|
IMPL_START_0(iret) {
|
||||||
if (ctx->dumpsw)
|
if (ctx->dumpsw)
|
||||||
@ -55,6 +54,9 @@ IMPL_START_0(iret) {
|
|||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END;
|
||||||
|
IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -102,7 +102,7 @@ extern void do_hlt(ctx_t *ctx);
|
|||||||
#include <pc/regs.h>
|
#include <pc/regs.h>
|
||||||
#include <pc/decode.h>
|
#include <pc/decode.h>
|
||||||
#include <pc/except.h>
|
#include <pc/except.h>
|
||||||
#include <in/arch_i.h>
|
#include <ob/arch_i.h>
|
||||||
|
|
||||||
extern ctx_t main_ctx;
|
extern ctx_t main_ctx;
|
||||||
extern reg_t arch_r[NREGS];
|
extern reg_t arch_r[NREGS];
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
#include <pc/arch.h>
|
#include <pc/arch.h>
|
||||||
#include <in/arch_i.h>
|
|
||||||
|
|
||||||
#define rfx R(RFX)
|
#define rfx R(RFX)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user