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
|
||||
|
||||
kas: kpc as/regs.lst as/k-as.py
|
||||
@cp vm/in/instrs.lst as
|
||||
@cp vm/ob/instrs.lst as
|
||||
|
||||
dos: kas dosclean
|
||||
@cd ka && make --no-print-directory -s
|
||||
@ -24,7 +24,7 @@ dosclean:
|
||||
@rm -f $(KODIR)/*.com $(KODIR)/*.sym
|
||||
|
||||
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
|
||||
@cd vm && make clean --no-print-directory -s verbose=no
|
||||
|
@ -13,7 +13,6 @@ start:
|
||||
mov rbp, zero
|
||||
|
||||
cls
|
||||
cld
|
||||
call main
|
||||
|
||||
mov rax, Sys.EnterHaltMode
|
||||
|
@ -10,4 +10,5 @@ include "crt/err/errno.k"
|
||||
include "crt/fmt/format.k"
|
||||
include "crt/str/string.k"
|
||||
include "crt/lib/time.k"
|
||||
include "crt/lib/arith128.k"
|
||||
|
||||
|
@ -34,7 +34,7 @@ doprnt:
|
||||
mov ax0, b[rbx]
|
||||
call .doput
|
||||
|
||||
inc rbx
|
||||
add rbx, rbx, 1
|
||||
jmp .print_regular
|
||||
|
||||
.check_modf:
|
||||
@ -71,7 +71,7 @@ doprnt:
|
||||
cmp ax0, zero
|
||||
jmp.z .main_loop
|
||||
|
||||
inc rdi
|
||||
add rdi, rdi, 1
|
||||
call .doput
|
||||
jmp .print_string
|
||||
|
||||
@ -82,10 +82,8 @@ doprnt:
|
||||
jmp .main_loop
|
||||
|
||||
.modf_p:
|
||||
mov ax0, '0'
|
||||
call .doput
|
||||
mov ax0, 'x'
|
||||
call .doput
|
||||
call .doput, '0'
|
||||
call .doput, 'x'
|
||||
; Fallthrough
|
||||
|
||||
.modf_x:
|
||||
@ -122,44 +120,29 @@ doprnt:
|
||||
add.z rsp, rsp, 80
|
||||
jmp.z .main_loop
|
||||
|
||||
inc rdi
|
||||
add rdi, rdi, 1
|
||||
call .doput
|
||||
jmp .print_itoa_buf
|
||||
|
||||
.modf_percent:
|
||||
mov ax0, '%'
|
||||
call .doput
|
||||
call .doput, '%'
|
||||
jmp .main_loop
|
||||
|
||||
.bad_modifier:
|
||||
; print "%?" to clearly indicate that something is wrong
|
||||
mov ax0, '%'
|
||||
call .doput
|
||||
|
||||
mov ax0, '?'
|
||||
call .doput
|
||||
call .doput, '%'
|
||||
call .doput, '?'
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
.nullstring:
|
||||
; %s was passed a NULL
|
||||
mov ax0, '('
|
||||
call .doput
|
||||
|
||||
mov ax0, 'n'
|
||||
call .doput
|
||||
|
||||
mov ax0, 'u'
|
||||
call .doput
|
||||
|
||||
mov ax0, 'l'
|
||||
call .doput
|
||||
|
||||
mov ax0, 'l'
|
||||
call .doput
|
||||
|
||||
mov ax0, ')'
|
||||
call .doput
|
||||
call .doput, '('
|
||||
call .doput, 'n'
|
||||
call .doput, 'u'
|
||||
call .doput, 'l'
|
||||
call .doput, 'l'
|
||||
call .doput, ')'
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
@ -178,7 +161,7 @@ doprnt:
|
||||
;
|
||||
.doput:
|
||||
; update print count
|
||||
inc nx1
|
||||
add nx1, nx1, 1
|
||||
|
||||
; if n==0, don't print
|
||||
; we follow the C convention that sprintf()-like functions
|
||||
@ -188,7 +171,7 @@ doprnt:
|
||||
ret.z
|
||||
|
||||
; if n>0, decrement n and print
|
||||
dec nx0
|
||||
sub nx0, nx0, 1
|
||||
call nx3
|
||||
|
||||
; did putc fail?
|
||||
|
@ -34,10 +34,9 @@ ltostr:
|
||||
b.z ax3, zero, .conv
|
||||
b.nz ax2, 10, .conv ; base 10
|
||||
|
||||
sgn r11, ax1 ; extract ax1 sign
|
||||
|
||||
cmp r11, -1 ; negative?
|
||||
neg.z ax1, ax1
|
||||
shr r11, ax1, 63 ; extract ax1 sign
|
||||
cmp r11, zero ; negative?
|
||||
sub.nz ax1, zero, ax1 ; yes
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
@ -55,7 +54,7 @@ ltostr:
|
||||
|
||||
.next:
|
||||
mov b[ax0], r10
|
||||
inc ax0
|
||||
add ax0, ax0, 1
|
||||
|
||||
div ax1, ax1, ax2
|
||||
jmp .conv
|
||||
@ -64,12 +63,11 @@ ltostr:
|
||||
.fini:
|
||||
cmp r11, -1
|
||||
mov.z b[ax0], '-'
|
||||
inc.z ax0
|
||||
add.z ax0, ax0, 1
|
||||
|
||||
mov b[ax0], zero
|
||||
|
||||
mov ax0, rax
|
||||
call strrev2
|
||||
call strrev2, rax
|
||||
|
||||
ret
|
||||
|
||||
|
@ -39,12 +39,12 @@ strtoq:
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
inc.z rdx
|
||||
add.z rdx, rdx, 1
|
||||
jmp.z .skip_spc
|
||||
|
||||
; skip +
|
||||
cmp b[rdx], '+'
|
||||
inc.z rdx
|
||||
add.z rdx, rdx, 1
|
||||
|
||||
; signed?
|
||||
cmp ax2, zero
|
||||
@ -53,7 +53,7 @@ strtoq:
|
||||
|
||||
; parse '-'
|
||||
cmp b[rdx], '-'
|
||||
inc.z rdx
|
||||
add.z rdx, rdx, 1
|
||||
mov.z r10, 1
|
||||
mov.nz r10, zero
|
||||
|
||||
@ -64,7 +64,7 @@ strtoq:
|
||||
; base prefix?
|
||||
b.nz b[rdx], '0', .main_loop
|
||||
|
||||
inc rdx
|
||||
add rdx, rdx, 1
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
@ -81,7 +81,7 @@ strtoq:
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
b.nz ax1, 16, .done
|
||||
; else
|
||||
inc rdx
|
||||
add rdx, rdx, 1
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0b:
|
||||
@ -89,7 +89,7 @@ strtoq:
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
b.nz ax1, 2, .done
|
||||
; else
|
||||
inc rdx
|
||||
add rdx, rdx, 1
|
||||
jmp .main_loop
|
||||
|
||||
.base_0:
|
||||
@ -98,15 +98,15 @@ strtoq:
|
||||
cmp b[rdx], '0'
|
||||
mov.nz ax1, 10
|
||||
jmp.nz .main_loop
|
||||
inc rdx
|
||||
add rdx, rdx, 1
|
||||
|
||||
cmp b[rdx], 'x'
|
||||
inc.z rdx
|
||||
add.z rdx, rdx, 1
|
||||
mov.z ax1, 16
|
||||
jmp.z .main_loop
|
||||
|
||||
cmp b[rdx], 'b'
|
||||
inc.z rdx
|
||||
add.z rdx, rdx, 1
|
||||
mov.z ax1, 2
|
||||
jmp.z .main_loop
|
||||
|
||||
@ -114,7 +114,7 @@ strtoq:
|
||||
|
||||
.main_loop:
|
||||
movzx r12, b[rdx]
|
||||
inc rdx
|
||||
add rdx, rdx, 1
|
||||
|
||||
cmp r12, '0'
|
||||
jmp.b .done
|
||||
@ -147,7 +147,7 @@ strtoq:
|
||||
ret.z
|
||||
|
||||
; yes
|
||||
neg rax, rax
|
||||
sub rax, zero, rax
|
||||
ret
|
||||
|
||||
.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
|
||||
|
||||
.leap:
|
||||
inc rax
|
||||
add rax, rax, 1
|
||||
|
||||
.end:
|
||||
ret
|
||||
|
@ -11,12 +11,27 @@
|
||||
;
|
||||
strcmp:
|
||||
mov rcx, STRLEN_MAX
|
||||
cmpzsb.rep.z ax0, ax1
|
||||
|
||||
mov rax, b[ax0-1]
|
||||
mov rcx, b[ax1-1]
|
||||
sub rax, rax, rcx
|
||||
.1:
|
||||
jmp.cxz .2
|
||||
|
||||
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
|
||||
|
||||
;
|
||||
@ -24,14 +39,22 @@ strcmp:
|
||||
;
|
||||
strncmp:
|
||||
mov rcx, ax2
|
||||
mov.cxz rax, zero
|
||||
ret.cxz
|
||||
|
||||
cmpzsb.rep.z ax0, ax1
|
||||
.1:
|
||||
jmp.cxz .2
|
||||
|
||||
mov rax, b[ax0-1]
|
||||
mov rcx, b[ax1-1]
|
||||
sub rax, rax, rcx
|
||||
mov rax, b[ax0]
|
||||
mov rdx, b[ax1]
|
||||
|
||||
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
|
||||
|
||||
|
@ -5,8 +5,17 @@
|
||||
; void strcpy(char *, const char *)
|
||||
;
|
||||
strcpy:
|
||||
mov rcx, STRLEN_MAX
|
||||
movsb.rep.nz ax0, ax1
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
|
||||
b.z rax, zero, .1
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
|
||||
jmp strcpy
|
||||
|
||||
.1:
|
||||
ret
|
||||
|
||||
;
|
||||
@ -14,24 +23,42 @@ strcpy:
|
||||
;
|
||||
strncpy:
|
||||
mov rcx, ax2
|
||||
|
||||
.1:
|
||||
ret.cxz
|
||||
|
||||
movsb.rep.nz ax0, ax1
|
||||
ret
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
sub rcx, rcx, 1
|
||||
|
||||
jmp .1
|
||||
|
||||
;
|
||||
; void strnzcpy(char *, const char *, int)
|
||||
;
|
||||
strnzcpy:
|
||||
mov rcx, ax2
|
||||
ret.cxz
|
||||
|
||||
dec rcx
|
||||
jmp.cxz .1
|
||||
|
||||
movsb.rep.nz ax0, ax1
|
||||
|
||||
.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
|
||||
|
||||
.3:
|
||||
ret
|
||||
|
||||
|
@ -15,6 +15,10 @@ strnlen:
|
||||
; int strlen(char *)
|
||||
;
|
||||
strlen:
|
||||
mov ax1, STRLEN_MAX
|
||||
jmp strnlen
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, rcx
|
||||
scasb.rep.nz ax0, zero
|
||||
|
||||
sub rax, rdx, rcx
|
||||
ret
|
||||
|
||||
|
@ -18,7 +18,7 @@ strrev:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, zero
|
||||
dec ax1
|
||||
sub ax1, ax1, 1
|
||||
|
||||
.2:
|
||||
; copy, going backward though str
|
||||
@ -30,8 +30,8 @@ strrev:
|
||||
mov.z b[ax0+1], zero
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
dec ax1
|
||||
add ax0, ax0, 1
|
||||
sub ax1, ax1, 1
|
||||
jmp .2
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ strrev2:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, zero
|
||||
dec ax1
|
||||
sub ax1, ax1, 1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
@ -60,8 +60,8 @@ strrev2:
|
||||
xchg rax, b[ax0]
|
||||
mov b[ax1], rax
|
||||
|
||||
inc ax0
|
||||
dec ax1
|
||||
add ax0, ax0, 1
|
||||
sub ax1, ax1, 1
|
||||
jmp .2
|
||||
|
||||
.3:
|
||||
|
@ -28,17 +28,13 @@ TrapHandlers.epilog:
|
||||
|
||||
; TRAP return values: RAX-RDX
|
||||
|
||||
mov ax0, r12
|
||||
mov ax1, $rax
|
||||
mov ax2, rax
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, r12, $rax
|
||||
|
||||
mov ax1, $rdx
|
||||
mov ax2, rdx
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, r12, $rdx
|
||||
|
||||
mov ax0, r11
|
||||
call IDT.DoneHandling
|
||||
call IDT.DoneHandling, r11
|
||||
|
||||
iret
|
||||
|
||||
|
@ -37,18 +37,16 @@ trap0_handler:
|
||||
.handle_Exit:
|
||||
|
||||
; Open COMMAND.COM
|
||||
mov ax0, .cmdcom
|
||||
call DISK.OpenFile
|
||||
call DISK.OpenFile, .cmdcom
|
||||
|
||||
; Crash on failure
|
||||
cmp rax, zero
|
||||
crash.l
|
||||
|
||||
; Load at CMDCOM_LOADP
|
||||
mov ax0, rax
|
||||
mov ax1, CMDCOM_LOADP
|
||||
mov ax2, CMDCOM_MAXSZ
|
||||
call DISK.ReadFile
|
||||
call DISK.ReadFile, rax
|
||||
|
||||
; Assume that COMMAND.COM being
|
||||
; less then 4KB means something
|
||||
@ -57,32 +55,26 @@ trap0_handler:
|
||||
crash.b
|
||||
|
||||
; Close the handle
|
||||
mov ax0, rax
|
||||
call DISK.CloseFile
|
||||
call DISK.CloseFile, rax
|
||||
|
||||
; Code address
|
||||
mov ax0, zero
|
||||
mov ax1, $rip
|
||||
mov ax2, 0x100000
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, zero, $rip
|
||||
|
||||
; Usermode
|
||||
mov ax1, $cr0
|
||||
mov ax2, 3
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, zero, $cr0
|
||||
|
||||
mov rcx, CMDCOM_LOADP
|
||||
sub rcx, rcx, 0x100000
|
||||
|
||||
; Code offset
|
||||
mov ax1, $cr1
|
||||
mov ax2, rcx
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, zero, $cr1
|
||||
|
||||
; Data offset
|
||||
mov ax1, $cr2
|
||||
mov ax2, rcx
|
||||
call RFS.StoreReg
|
||||
call RFS.StoreReg, zero, $cr2
|
||||
|
||||
; Return frame
|
||||
mov q[rbp-16], zero
|
||||
@ -128,7 +120,9 @@ trap0_handler:
|
||||
.handle_HaltMode:
|
||||
hlt
|
||||
.HLT.loop:
|
||||
xpause
|
||||
pause
|
||||
pause
|
||||
pause
|
||||
|
||||
scan rax
|
||||
b.z rax, zero, .HLT.loop
|
||||
|
@ -1,6 +1,61 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; 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:
|
||||
.bufsize := 256
|
||||
|
||||
|
@ -32,7 +32,7 @@ builtins.dir:
|
||||
b.z rax, 0, .end
|
||||
|
||||
; found something
|
||||
inc nx0
|
||||
add nx0, nx0, 1
|
||||
|
||||
; separate extension from file name
|
||||
mov rcx, NAME_MAX
|
||||
@ -46,13 +46,13 @@ builtins.dir:
|
||||
|
||||
; calculate where to put extension
|
||||
sub r11, r10, .buf
|
||||
dec r11
|
||||
sub r11, r11, 1
|
||||
|
||||
.ext_pad:
|
||||
; print at least 11 non-space characters before extension
|
||||
b.ae r11, 11, .print_ext
|
||||
prn ' '
|
||||
inc r11
|
||||
add r11, r11, 1
|
||||
jmp .ext_pad
|
||||
|
||||
.print_ext:
|
||||
@ -61,15 +61,16 @@ builtins.dir:
|
||||
prn ' '
|
||||
|
||||
cmp b[r10], '.'
|
||||
inc.z r10
|
||||
add.z r10, r10, 1
|
||||
|
||||
.print_ext.1:
|
||||
b.z b[r10], 0, .print_ext.2
|
||||
|
||||
; print and decrease rcx, unless it's already 0
|
||||
prn b[r10]
|
||||
inc r10
|
||||
dec.cxnz rcx
|
||||
mov r12, b[r10]
|
||||
prn r12
|
||||
add r10, r10, 1
|
||||
sub.cxnz rcx, rcx, 1
|
||||
|
||||
jmp .print_ext.1
|
||||
|
||||
@ -88,10 +89,9 @@ builtins.dir:
|
||||
shr rax, rdx, 10
|
||||
and rdx, rdx, 1023
|
||||
|
||||
mov ax0, .bytesstr
|
||||
push rdx
|
||||
push rax
|
||||
call printf
|
||||
call printf, .bytesstr
|
||||
add rsp, rsp, 16
|
||||
|
||||
.bytesstr = "%d kilobytes + %d bytes"
|
||||
@ -102,14 +102,11 @@ builtins.dir:
|
||||
jmp .next
|
||||
|
||||
.end:
|
||||
mov ax0, .endstr1
|
||||
push nx0
|
||||
call printf
|
||||
call printf, .endstr1
|
||||
add rsp, rsp, 8
|
||||
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .endstr2
|
||||
prns.rep.nz rdx
|
||||
call print, .endstr2
|
||||
|
||||
pop nx0
|
||||
ret
|
||||
|
@ -13,9 +13,7 @@ ps1 = "C:\\> "
|
||||
main:
|
||||
|
||||
.print_prompt:
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, ps1
|
||||
prns.rep.nz rdx
|
||||
call print, ps1
|
||||
|
||||
; empty argbuf
|
||||
mov rcx, argbuf.size
|
||||
@ -43,7 +41,7 @@ main:
|
||||
b.z rcx, zero, .input_loop
|
||||
|
||||
; delete it
|
||||
dec rcx
|
||||
sub rcx, rcx, 1
|
||||
add rdx, rcx, argbuf
|
||||
mov b[rdx], zero
|
||||
|
||||
@ -65,7 +63,7 @@ main:
|
||||
; add character to buffer and increase iterator (rcx)
|
||||
add rdx, rcx, argbuf
|
||||
mov b[rdx], rax
|
||||
inc rcx
|
||||
add rcx, rcx, 1
|
||||
|
||||
; another one
|
||||
jmp .input_loop
|
||||
@ -83,7 +81,7 @@ main:
|
||||
; argv1 exists? if so, save its position
|
||||
mov r11, rdx
|
||||
b.z b[r11], zero, .no_argv1
|
||||
inc r11
|
||||
add r11, r11, 1
|
||||
|
||||
.next_space:
|
||||
mov r10, b[r11]
|
||||
@ -91,7 +89,7 @@ main:
|
||||
|
||||
; skip spaces
|
||||
cmp r10, ' '
|
||||
inc.z r11
|
||||
add.z r11, r11, 1
|
||||
jmp.z .next_space
|
||||
|
||||
mov q[argv1pos], r11
|
||||
@ -108,68 +106,59 @@ main:
|
||||
sub rcx, rdx, argbuf
|
||||
mov rdx, argbuf
|
||||
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:
|
||||
|
||||
.builtin_cls = "cls"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_cls
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_cls
|
||||
b.z rax, 0, .handle_CLS
|
||||
|
||||
.builtin_date = "date"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_date
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_date
|
||||
b.z rax, 0, .handle_DATE
|
||||
|
||||
.builtin_dir = "dir"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_dir
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_dir
|
||||
b.z rax, 0, .handle_DIR
|
||||
|
||||
.builtin_dump = "dump"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_dump
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_dump
|
||||
b.z rax, 0, .handle_DUMP
|
||||
|
||||
.builtin_echo = "echo"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_echo
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_echo
|
||||
b.z rax, 0, .handle_ECHO
|
||||
|
||||
.builtin_exit = "exit"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_exit
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_exit
|
||||
b.z rax, 0, .handle_EXIT
|
||||
|
||||
.builtin_help = "help"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_help
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_help
|
||||
b.z rax, 0, .handle_HELP
|
||||
|
||||
.builtin_print = "print"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_print
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_print
|
||||
b.z rax, 0, .handle_PRINT
|
||||
|
||||
.builtin_time = "time"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_time
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_time
|
||||
b.z rax, 0, .handle_TIME
|
||||
|
||||
.builtin_ver = "ver"
|
||||
mov ax0, argv0
|
||||
mov ax1, .builtin_ver
|
||||
call strcmp
|
||||
call strcmp, argv0, .builtin_ver
|
||||
b.z rax, 0, .handle_VER
|
||||
|
||||
jmp .command_not_found
|
||||
@ -182,19 +171,17 @@ main:
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_DATE:
|
||||
time ax0
|
||||
call GetTimeUTC
|
||||
|
||||
push b[rax+3]
|
||||
mov rcx, b[rax+4]
|
||||
inc rcx
|
||||
add rcx, rcx, 1
|
||||
push rcx
|
||||
push w[rax+6]
|
||||
|
||||
mov ax0, .datefmt
|
||||
call printf
|
||||
call printf, .datefmt
|
||||
|
||||
add rsp, rsp, 5*8
|
||||
add rsp, rsp, 40
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -252,53 +239,36 @@ main:
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_TIME:
|
||||
time ax0
|
||||
call GetTimeUTC
|
||||
|
||||
push b[rax]
|
||||
push b[rax+1]
|
||||
push b[rax+2]
|
||||
mov ax0, .timefmt
|
||||
call printf
|
||||
add rsp, rsp, 3*8
|
||||
call printf, .timefmt
|
||||
add rsp, rsp, 24
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.timefmt = "%d:%d:%d\n"
|
||||
|
||||
.handle_VER:
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, cmd.versionstr
|
||||
prns.rep.nz rdx
|
||||
call print, cmd.versionstr
|
||||
prn 10
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.handle_HELP:
|
||||
mov rcx, STRLEN_MAX
|
||||
|
||||
mov rdx, .helpmsg
|
||||
prns.rep.nz rdx
|
||||
mov rdx, .helpmsg.cls
|
||||
prns.rep.nz rdx
|
||||
mov rdx, .helpmsg.date
|
||||
prns.rep.nz rdx
|
||||
mov rdx, .helpmsg.dir
|
||||
prns.rep.nz rdx
|
||||
mov rdx, .helpmsg.dump
|
||||
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
|
||||
call print, .helpmsg
|
||||
call print, .helpmsg.cls
|
||||
call print, .helpmsg.date
|
||||
call print, .helpmsg.dir
|
||||
call print, .helpmsg.dump
|
||||
call print, .helpmsg.echo
|
||||
call print, .helpmsg.exit
|
||||
call print, .helpmsg.help
|
||||
call print, .helpmsg.print
|
||||
call print, .helpmsg.time
|
||||
call print, .helpmsg.ver
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -315,22 +285,17 @@ main:
|
||||
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"
|
||||
|
||||
.command_not_found:
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, argv0
|
||||
prns.rep.nz rdx
|
||||
|
||||
mov rdx, .cnf_errmsg
|
||||
prns.rep.nz rdx
|
||||
call print, argv0
|
||||
call print, .cnf_errmsg
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
.cnf_errmsg = ": command not found\n"
|
||||
|
||||
.file_not_found:
|
||||
mov ax0, .fnf_errmsg
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
call printf, .fnf_errmsg
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
@ -338,10 +303,9 @@ main:
|
||||
.fnf_errmsg = "%s: %s: file not found\n"
|
||||
|
||||
.empty_file:
|
||||
mov ax0, .ef_errmsg
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
call printf, .ef_errmsg
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
@ -349,10 +313,9 @@ main:
|
||||
.ef_errmsg = "%s: %s: file is empty\n"
|
||||
|
||||
.couldnt_read:
|
||||
mov ax0, .cno_errmsg
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf
|
||||
call printf, .cno_errmsg
|
||||
add rsp, rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
@ -360,12 +323,8 @@ main:
|
||||
.cno_errmsg = "%s: %s: an error occured while reading file\n"
|
||||
|
||||
.need_params:
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, argv0
|
||||
prns.rep.nz rdx
|
||||
|
||||
mov rdx, .np_errmsg
|
||||
prns.rep.nz rdx
|
||||
call print, argv0
|
||||
call print, .np_errmsg
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
|
@ -46,14 +46,14 @@ $(OBJDIR)/%.d: %.c
|
||||
# echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
|
||||
# fi
|
||||
|
||||
in/instrs.lst: in/INSTRS in/arch_i.py
|
||||
ob/instrs.lst: in/arch_i.py
|
||||
@cd in && python3 arch_i.py
|
||||
|
||||
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
|
||||
|
||||
$(KEXE): in/instrs.lst $(obj)
|
||||
$(KEXE): ob/instrs.lst $(obj)
|
||||
@gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE)
|
||||
@echo ${CL2}[$@] ${CL}made successfully.${CL3}
|
||||
|
||||
|
106
vm/in/ALU
106
vm/in/ALU
@ -5,15 +5,6 @@
|
||||
# Logical instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Bitwise NOT operation
|
||||
#
|
||||
# $1 = NOT($2)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
not r r
|
||||
|
||||
#
|
||||
# Bitwise OR operation
|
||||
#
|
||||
@ -22,10 +13,6 @@ not r r
|
||||
# Preserves all flags
|
||||
#
|
||||
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
|
||||
@ -35,10 +22,6 @@ nor r r ri
|
||||
# Preserves all flags
|
||||
#
|
||||
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
|
||||
@ -48,10 +31,6 @@ nand r r ri
|
||||
# Preserves all flags
|
||||
#
|
||||
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)
|
||||
@ -91,50 +70,6 @@ sar r r ri
|
||||
cmp r 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
|
||||
#
|
||||
@ -146,7 +81,6 @@ dec r
|
||||
#
|
||||
add r r ri
|
||||
addf r r ri
|
||||
addo r r ri
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
@ -159,26 +93,22 @@ addo r r ri
|
||||
#
|
||||
sub r r ri
|
||||
subf r r ri
|
||||
subo r r ri
|
||||
|
||||
#
|
||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||
#
|
||||
# $dest = $src1 + $src2 + CF (ADC)
|
||||
# $dest = $src1 + $src2 + OF (ADO)
|
||||
# $dest = $src1 - $src2 - CF (SBB)
|
||||
# $dest = $src1 - $src2 - OF (SBO)
|
||||
#
|
||||
# Preserves ZF and SF
|
||||
# Flags CF and OF are undefined for now
|
||||
# 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 r r ri
|
||||
adox r r ri
|
||||
sbbx r r ri
|
||||
sbox r r ri
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MUL operation
|
||||
# Arithmetical MUL operation
|
||||
#
|
||||
# $dest = LO($src1 * $src2)
|
||||
#
|
||||
@ -187,31 +117,47 @@ sbox r r ri
|
||||
#
|
||||
mul r r ri
|
||||
mulf r r ri
|
||||
mulo r r ri
|
||||
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
# $dest1 = HI($dest2 * $src)
|
||||
# $dest2 = LO($dest2 * $src)
|
||||
#
|
||||
# Sets CF and OF if HI($2 * $3) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
# Preserves all flags
|
||||
#
|
||||
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
|
||||
#
|
||||
# $dest1 = $1 DIV $2
|
||||
# $dest = $src1 DIV $src2
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
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
|
||||
#
|
||||
|
84
vm/in/MISC
84
vm/in/MISC
@ -24,36 +24,21 @@ dump
|
||||
# Misc. instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#
|
||||
# Do nothing (NOOP)
|
||||
#
|
||||
# (nothing)
|
||||
#
|
||||
# Throws:
|
||||
# (nothing)
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
nop
|
||||
|
||||
#
|
||||
# Pause the CPU for a very short amount of time (PAUSE)
|
||||
# Used in spin-like loops
|
||||
# Used in spin-type loops
|
||||
#
|
||||
pause
|
||||
|
||||
#
|
||||
# Pause the CPU for a relatively long time (XPAUSE)
|
||||
# Throw #OVF when RFX.OF=1 (INTO)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
xpause
|
||||
into
|
||||
|
||||
#
|
||||
# Get timestamp in seconds
|
||||
# Get timestamp in µseconds
|
||||
#
|
||||
time r
|
||||
utime r r
|
||||
|
||||
#
|
||||
# $1 = seconds since start of month
|
||||
@ -62,68 +47,11 @@ time 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
|
||||
#
|
||||
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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -144,7 +72,7 @@ dswap r r
|
||||
#
|
||||
# Send a character to standard output (PRN)
|
||||
#
|
||||
prn rim
|
||||
prn ri
|
||||
|
||||
#
|
||||
# Print a string to standard output (PRN)
|
||||
|
@ -52,6 +52,8 @@ b rm ri ri
|
||||
# JMP(RIP)
|
||||
#
|
||||
call ri
|
||||
call i ri
|
||||
call i ri ri
|
||||
|
||||
#
|
||||
# Return to caller (RET)
|
||||
@ -103,9 +105,9 @@ pop r
|
||||
# $1 = ADDR($2)
|
||||
#
|
||||
# For instance:
|
||||
# LEA RAX, [RBX + RCX + 4]
|
||||
# LEA RAX, [RBX + RCX * 2 + 4]
|
||||
# will result in:
|
||||
# RAX = RBX + RCX + 4
|
||||
# RAX = RBX + RCX * 2 + 4
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
|
74
vm/in/STRING
74
vm/in/STRING
@ -20,24 +20,6 @@ stosw r ri
|
||||
stosl 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)
|
||||
#
|
||||
@ -65,61 +47,5 @@ scasw r ri
|
||||
scasl 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
|
||||
|
||||
#
|
||||
# Clear or set interrupt flag (CLI/STI)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
cli
|
||||
sti
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Device control instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -70,7 +79,7 @@ iret
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
devctl ri ri
|
||||
devctl r r
|
||||
|
||||
#
|
||||
# Call a device-defined function slot of device (IOCALL)
|
||||
|
89
vm/in/alu.c
89
vm/in/alu.c
@ -4,26 +4,16 @@
|
||||
#include <in/instrs.h>
|
||||
|
||||
#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(and) { 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(shr) { v1 = v2 >> 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(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT;
|
||||
IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
|
||||
IMPL_START_3(addf) { COMPARE_ADD(v2, v3); v1 = v2 + v3; } 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(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
||||
IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT;
|
||||
IMPL_START_3(subf){ COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(R(RFX)&CF); } IMPL_OUT;
|
||||
IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } IMPL_OUT;
|
||||
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(R(RFX)&CF); } IMPL_OUT;
|
||||
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(R(RFX)&OF); } IMPL_OUT;
|
||||
IMPL_START_3(adcx) { v3 += !!(R(RFX)&CF); COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
|
||||
IMPL_START_3(sbbx) { v3 += !!(R(RFX)&CF); COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
||||
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
|
||||
IMPL_START_3(div) {
|
||||
if (!v3)
|
||||
_except(ctx, E_DIV, "DIV by 0");
|
||||
v1 = v2 / v3;
|
||||
} IMPL_OUT;
|
||||
IMPL_START_3(idiv) {
|
||||
if (!v3)
|
||||
_except(ctx, E_DIV, "IDIV by 0");
|
||||
v1 = (ulong)((long)v2/(long)v3);
|
||||
} IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
||||
//
|
||||
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
{
|
||||
ulong u1 = (u & 0xffffffff);
|
||||
ulong v1 = (v & 0xffffffff);
|
||||
ulong t = (u1 * v1);
|
||||
ulong w3 = (t & 0xffffffff);
|
||||
ulong k = (t >> 32);
|
||||
|
||||
u >>= 32;
|
||||
t = (u * v1) + k;
|
||||
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;
|
||||
__uint128_t r = (__uint128_t)u * (__uint128_t)v;
|
||||
|
||||
*hi = r >> 64;
|
||||
*lo = r;
|
||||
}
|
||||
|
||||
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
||||
IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
||||
IMPL_START_3(mulhi) { __unsigned_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
||||
|
||||
IMPL_START_3(mulf) {
|
||||
ulong tmp;
|
||||
multiply(v2, v3, &tmp, &v1);
|
||||
__unsigned_multiply128(v2, v3, &tmp, &v1);
|
||||
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||
} IMPL_OUT;
|
||||
|
||||
IMPL_START_3(mulo) {
|
||||
ulong tmp;
|
||||
multiply(v2, v3, &tmp, &v1);
|
||||
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||
INTO();
|
||||
} IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
{
|
||||
__int128_t r = (__int128_t)(long)u * (__int128_t)(long)v;
|
||||
|
||||
*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
|
||||
|
||||
fi = open("INSTRS")
|
||||
hd = open("arch_i.h", "w")
|
||||
ls = open("instrs.lst", "w")
|
||||
hd = open("../ob/arch_i.h", "w")
|
||||
ls = open("../ob/instrs.lst", "w")
|
||||
|
||||
count = 0
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/arch.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
@ -108,18 +107,29 @@ IMPL_START_2(name) \
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define COMPARE(v1, v2) \
|
||||
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
|
||||
long _s1 = (long)v1, _s2 = (long)v2; \
|
||||
#define COMPARE_ADD(v1, v2) \
|
||||
ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 + _u2); \
|
||||
\
|
||||
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; \
|
||||
else R(RFX) &= ~CF; \
|
||||
\
|
||||
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|
||||
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
|
||||
if (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \
|
||||
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(cpuid) { rax = rdx = 0; } IMPL_END;
|
||||
|
||||
IMPL_START_0(into) { INTO(); } 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)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
@ -77,24 +72,6 @@ IMPL_START_0(cls) {
|
||||
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
||||
} 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)
|
||||
@ -151,7 +128,7 @@ IMPL_START_0(prns)
|
||||
{
|
||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||
|
||||
COMPARE(ch, 0);
|
||||
COMPARE_SUB(ch, 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_START_3(b) {
|
||||
COMPARE(v1, v2);
|
||||
COMPARE_SUB(v1, v2);
|
||||
|
||||
if (eval_cond(ctx, ctx->cond))
|
||||
R(RIP) = v3;
|
||||
@ -51,11 +51,32 @@ IMPL_START_1(pop) {
|
||||
R(RSP) += 8;
|
||||
} IMPL_OUT;
|
||||
|
||||
/*
|
||||
IMPL_START_1(call) {
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
R(RIP) = v1;
|
||||
} 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) {
|
||||
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)
|
||||
{
|
||||
DECV(v2, p2);
|
||||
|
||||
ulong x = readmem(ctx, R(p1->reg), len);
|
||||
COMPARE(x, v2);
|
||||
COMPARE_SUB(x, v2);
|
||||
|
||||
if (x == 0) {
|
||||
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)
|
||||
{
|
||||
ulong x = readmem(ctx, R(p2->reg), len);
|
||||
|
@ -42,7 +42,6 @@ IMPL_START_1(trap) {
|
||||
_except(ctx, v1 + 256, "TRAP instruction");
|
||||
} IMPL_END;
|
||||
|
||||
IMPL_START_0(into) { INTO(); } IMPL_END;
|
||||
|
||||
IMPL_START_0(iret) {
|
||||
if (ctx->dumpsw)
|
||||
@ -55,6 +54,9 @@ IMPL_START_0(iret) {
|
||||
}
|
||||
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/decode.h>
|
||||
#include <pc/except.h>
|
||||
#include <in/arch_i.h>
|
||||
#include <ob/arch_i.h>
|
||||
|
||||
extern ctx_t main_ctx;
|
||||
extern reg_t arch_r[NREGS];
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/arch.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
#define rfx R(RFX)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user