1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-08-14 09:52:39 +02:00
parent cf7f261eb7
commit 3d002108a4
No known key found for this signature in database
GPG Key ID: 9C7ACF0C053FB8A1
32 changed files with 465 additions and 523 deletions

View File

@ -438,9 +438,6 @@ pref2len = {
}
i_aliases = {
"j_1" : "jmp_1",
"m_2" : "mov_2",
"b_3" : "bch_3",
"inc_2" : "add_2",
"dec_2" : "sub_2",
}

View File

@ -45,7 +45,6 @@ include "crt/fmt/format.k"
include "crt/str/string.k"
include "crt/mem/memory.k"
include "crt/lib/time.k"
include "crt/lib/arith128.k"
abort:
crash

View File

@ -26,7 +26,7 @@ doprnt:
; everything below r13 is a regular character; print it
.print_regular:
b.z r12, r13, .check_modf
beq r12, r13, .check_modf
call .doput, b[r12]
@ -36,20 +36,20 @@ doprnt:
.check_modf:
; did we find a '%' ?
; if not, then we found fmt's null-terminator; we're done
b.nz b[r12], '%', .epilogue
bne b[r12], '%', .epilogue
; we did find a modifier / '%'
mov rax, b[r12+1]
inc r12, 2
b.z rax, 's', .modf_s
b.z rax, 'c', .modf_c
b.z rax, 'p', .modf_p
b.z rax, 'x', .modf_x
b.z rax, 'd', .modf_d
b.z rax, 'o', .modf_o
b.z rax, 'b', .modf_b
b.z rax, '%', .modf_percent
beq rax, 's', .modf_s
beq rax, 'c', .modf_c
beq rax, 'p', .modf_p
beq rax, 'x', .modf_x
beq rax, 'd', .modf_d
beq rax, 'o', .modf_o
beq rax, 'b', .modf_b
beq rax, '%', .modf_percent
; unrecognized
jmp .bad_modifier
@ -59,11 +59,11 @@ doprnt:
mov r13, q[r14]
inc r14, 8
b.z r13, zero, .nullstring
bzr r13, .nullstring
.print_string:
mov ax0, b[r13]
b.z ax0, zero, .main_loop
bzr ax0, .main_loop
inc r13, 1
call .doput
@ -109,14 +109,16 @@ doprnt:
.print_itoa_buf:
mov ax0, b[r13]
cmp ax0, zero
inc.z rsp, 80
jmp.z .main_loop
bzr ax0, .pib_end_loop
inc r13, 1
call .doput
jmp .print_itoa_buf
.pib_end_loop:
inc rsp, 80
jmp .main_loop
.modf_percent:
call .doput, '%'
jmp .main_loop
@ -158,15 +160,18 @@ doprnt:
; we follow the C convention that sprintf()-like functions
; should return the number of characters that would have
; been printed/written if 'n' were big enough
cmp r15, zero
ret.z
bzr r15, .r
; decrement n and print
dec r15, 1
call r17
; did putc fail?
mov.axnz r15, zero ; yes, so artificially set n=0
jraxz .r
; yes, so artificially set n=0
mov r15, zero
.r:
ret

View File

@ -23,27 +23,29 @@ ltostr:
mov rcx, zero
; make sure base is in [2, 32]
b.b ax2, 2, .bad
b.a ax2, 36, .bad
bltu ax2, 2, .bad
bltu 36, ax2, .bad
; deal with zero
b.z ax1, zero, .is_zero
bzr ax1, .is_zero
; deal with base 10 signedness
b.z ax3, zero, .conv
b.nz ax2, 10, .conv ; base 10
bzr ax3, .conv
bne ax2, 10, .conv ; base 10
shr rcx, ax1, 63 ; extract ax1 sign
sub.cxnz ax1, zero, ax1 ; NEG if negative
jrcxz .conv
sub ax1, zero, ax1 ; NEG if negative
; main loop
.conv:
b.z ax1, zero, .fini
bzr ax1, .fini
rem rdx, ax1, ax2 ; ax1 % base
b.a rdx, 9, .nondec ; rdx > 9 ?
blt 9, rdx, .nondec ; rdx > 9 ?
inc rdx, '0'
jmp .next
@ -61,13 +63,14 @@ ltostr:
; add minus flag, null-terminate and reverse
.fini:
mov.cxnz b[ax0], '-'
inc.cxnz ax0, 1
jrcxz .cxz
mov b[ax0], '-'
inc ax0, 1
.cxz:
mov b[ax0], zero
call strrev2, rax
ret
;

View File

@ -33,10 +33,16 @@ nprintf:
; Guaranteed to only affect rcx and ax0
;
print:
mov rcx, STRLEN_MAX
b.z b[ax0], zero, .1
prns.rep.nz ax0
.1:
.l:
movzx rax, b[ax0]
jraxz .r
prn rax
inc ax0, 1
jmp .l
.r:
ret
;
@ -44,8 +50,12 @@ print:
;
nprint:
mov rcx, ax1
b.z b[ax0], zero, .1
prns.rep.nz ax0
.1:
jrcxz .r
.l:
prn b[ax0]
inc ax0, 1
loop .l
.r:
ret

View File

@ -28,49 +28,49 @@ strtoul:
;
strtoq:
mov rax, zero
mov rsi, zero
mov rdx, ax0
; make sure base is in [2, 32]
b.z ax1, 1, .bad
b.a ax1, 36, .bad
beq ax1, 1, .bad
bltu 36, ax1, .bad
; empty string?
b.z b[rdx], zero, .done
bzr b[rdx], .done
.skip_spc:
cmp b[rdx], ' '
inc.z rdx, 1
jmp.z .skip_spc
bne b[rdx], ' ', .no_spc
inc rdx, 1
jmp .skip_spc
.no_spc:
; skip +
cmp b[rdx], '+'
inc.z rdx, 1
bne b[rdx], '+', .no_plus
inc rdx, 1
; signed?
cmp ax2, zero
mov.z rsi, zero
jmp.z .unsigned
.no_plus:
; unsigned?
bzr ax2, .unsigned
; parse '-'
cmp b[rdx], '-'
inc.z rdx, 1
mov.z rsi, 1
mov.nz rsi, zero
bne b[rdx], '-', .unsigned
inc rdx, 1
mov rsi, 1
.unsigned:
; base 0
b.z ax1, 0, .base_0
bzr ax1, .base_0
; base prefix?
b.nz b[rdx], '0', .main_loop
bne b[rdx], '0', .main_loop
inc rdx, 1
movzx rcx, b[rdx]
; "0x"/"0b" prefix
jmp.cxz .done ; "0"
b.z rcx, 'x', .parsed_0x
b.z rcx, 'b', .parsed_0b
jrcxz .done ; "0"
beq rcx, 'x', .parsed_0x
beq rcx, 'b', .parsed_0b
; may be octal, but we don't care
; we accept "0110101010" (despite base=2) for instance
@ -79,7 +79,7 @@ strtoq:
.parsed_0x:
; are we in base 16?
; if not, leave rax = 0 and *rdx = 'x'
b.nz ax1, 16, .done
bne ax1, 16, .done
; else
inc rdx, 1
jmp .main_loop
@ -87,7 +87,7 @@ strtoq:
.parsed_0b:
; are we in base 2?
; if not, leave rax = 0 and *rdx = 'b'
b.nz ax1, 2, .done
bne ax1, 2, .done
; else
inc rdx, 1
jmp .main_loop
@ -95,47 +95,59 @@ strtoq:
.base_0:
; guess base
cmp b[rdx], '0'
mov.nz ax1, 10
jmp.nz .main_loop
beq b[rdx], '0', .b0_not10
; must be base 10
mov ax1, 10
jmp .main_loop
.b0_not10:
inc rdx, 1
cmp b[rdx], 'x'
inc.z rdx, 1
mov.z ax1, 16
jmp.z .main_loop
bne b[rdx], 'x', .b0_not16
inc rdx, 1
mov ax1, 16
jmp .main_loop
cmp b[rdx], 'b'
inc.z rdx, 1
mov.z ax1, 2
jmp.z .main_loop
.b0_not16:
bne b[rdx], 'b', .b0_not2
inc rdx, 1
mov ax1, 2
jmp .main_loop
.b0_not2:
; take octal by default
mov ax1, 8
.main_loop:
movzx rcx, b[rdx]
inc rdx, 1
cmp rcx, '0'
jmp.b .done
cmp.ae rcx, '9'
dec.be rcx, '0'
jmp.be .next
; between 0 and 9?
bltu rcx, '0', .done
bltu '9', rcx, .not_digit10
cmp rcx, 'A'
cmp.ae rcx, 'Z'
dec.be rcx, 55 ; 'A' - 10
jmp.be .next
; yes
dec rcx, '0'
jmp .next
cmp rcx, 'a'
jmp.b .next
cmp.ae rcx, 'z'
dec.be rcx, 87 ; 'a' - 10
jmp.be .next
.not_digit10:
bltu rcx, 'A', .done
bltu 'Z', rcx, .not_digitAZ
dec rcx, 55 ; 'A' - 10
jmp .next
.not_digitAZ:
bltu rcx, 'a', .done
bltu 'z', rcx, .done
dec rcx, 87 ; 'a' - 10
jmp .next
.next:
; too large for base?
b.ae rcx, ax1, .done
blteu ax1, rcx, .done
mul rax, ax1
inc rax, rcx
@ -143,11 +155,12 @@ strtoq:
.done:
; negative?
cmp rsi, zero
ret.z
bzr rsi, .r
; yes
sub rax, zero, rax
.r:
ret
.bad:

View File

@ -1,59 +0,0 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int:int add_lq_q(int:int x, int y)
;
add_lq_q:
addf rax, ax0, ax2
adcx rdx, ax1, zero
ret
;
; int:int add_lq_lq(int:int x, int:int y)
;
add_lq_lq:
addf rax, ax0, ax2
adcx rdx, ax1, ax3
ret
;
; int:int sub_lq_q(int:int x, int y)
;
sub_lq_q:
subf rax, ax0, ax2
sbbx rdx, ax1, zero
ret
;
; int:int sub_q_lq(int x, int:int y)
;
sub_q_lq:
subf rax, ax0, ax1
sbbx rdx, zero, ax2
ret
;
; int:int sub_lq_lq(int:int x, int:int y)
;
sub_lq_lq:
subf rax, ax0, ax2
sbbx rdx, ax1, ax3
ret
;
; int:int mul_q_q(int x, int y)
;
mul_q_q:
mov rax, ax0
mulhi rdx, rax, ax1
ret
;
; int:int imul_q_q(int x, int y)
;
imul_q_q:
mov rax, ax0
imulhi rdx, rax, ax1
ret

View File

@ -25,15 +25,15 @@ DaysInYear:
; divisible by 4?
rem rcx, ax0, 4
jmp.cxnz .end
jrcxnz .end
; divisible by 100?
rem rcx, ax0, 100
jmp.cxnz .leap
jrcxnz .leap
; divisible by 400?
rem rcx, ax0, 400
jmp.cxnz .end
jrcxnz .end
.leap:
inc rax, 1

View File

@ -1,16 +0,0 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; void memcpy(void *, const void *, int)
;
memcpy:
mov rcx, ax2
ret.cxz
.l:
sub rdx, ax2, rcx
mov b[ax0+rdx], b[ax1+rdx]
loop .l
ret

View File

@ -1,5 +1,34 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
include "crt/mem/memcpy.k"
;
; void memcpy(void *, const void *, int)
;
memcpy:
mov rcx, ax2
jrcxz .r
.l:
sub rdx, ax2, rcx
mov b[ax0+rdx], b[ax1+rdx]
loop .l
.r:
ret
;
; void memzero(void *, int)
;
memzero:
mov rcx, ax1
jrcxz .r
.l:
mov b[ax0], zero
inc ax0, 1
loop .l
.r:
ret

View File

@ -18,9 +18,10 @@ strchr:
mov rcx, STRLEN_MAX
scasb.rep.nz ax0, ax1
cmp b[ax0], zero
mov.z rax, zero
ret.z
bnz b[ax0], .r
mov rax, zero
ret
.r:
mov rax, ax0
ret

View File

@ -10,19 +10,18 @@
; <0 if the first character that does not match has a lower value in str1 than in str2
;
strcmp:
mov rcx, zero
mov rsi, zero
.l:
movzx rax, b[ax0+rcx]
movzx rdx, b[ax1+rcx]
movzx rax, b[ax0+rsi]
movzx rdx, b[ax1+rsi]
cmp rax, rdx
jmp.nz .r
bne rax, rdx, .r
; both zero?
add rbx, rax, rdx
jmp.bxz .r
add rcx, rax, rdx
jrcxz .r
inc rcx, 1
inc rsi, 1
jmp .l
.r:
@ -34,14 +33,13 @@ strcmp:
;
strncmp:
mov rcx, ax2
jmp.cxz .r
jrcxz .r
.l:
movzx rax, b[ax0]
movzx rdx, b[ax1]
cmp rax, rdx
jmp.nz .r
bne rax, rdx, .r
inc ax0, 1
inc ax1, 1

View File

@ -9,19 +9,22 @@ strcpy:
mov rcx, b[ax1]
mov b[ax0], rcx
ret.cxz
jrcxz .r
inc ax0, 1
inc ax1, 1
jmp .l
.r:
ret
;
; void strncpy(char *, const char *, int)
;
strncpy:
mov rcx, ax2
ret.cxz
jrcxz .r
.l:
mov b[ax0], b[ax1]
@ -30,6 +33,8 @@ strncpy:
inc ax1, 1
loop .l
.r:
ret
;
@ -37,13 +42,13 @@ strncpy:
;
strnzcpy:
mov rcx, ax2
ret.cxz
jrcxz .r
.l:
mov rax, b[ax1]
mov b[ax0], rax
jmp.axz .r
jraxz .r
inc ax0, 1
inc ax1, 1

View File

@ -7,9 +7,7 @@
; buf and src must NOT overlap
;
strrev:
cmp b[ax1], zero
mov.z b[ax0], zero
ret.z
bzr b[ax1], .z
; save str's location
mov rsi, ax1
@ -20,19 +18,24 @@ strrev:
scasb.rep.nz ax1, zero
dec ax1, 1
.2:
.l:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
cmp ax1, rsi
mov.z b[ax0+1], zero
ret.z
beq ax1, rsi, .r
inc ax0, 1
dec ax1, 1
jmp .2
jmp .l
.r:
mov b[ax0+1], zero
ret
.z:
mov b[ax0], zero
ret
;
; void strrev2(char *str)
@ -40,8 +43,7 @@ strrev:
; Inverses str
;
strrev2:
cmp b[ax0], zero
ret.z
bzr b[ax0], .r
mov ax1, ax0
@ -52,16 +54,16 @@ strrev2:
dec ax1, 1
; increase ax0 while decreasing ax1, performing exchanges
.2:
b.ae ax0, ax1, .3
.l:
blteu ax1, ax0, .r
xchg b[ax0], b[ax1]
inc ax0, 1
dec ax1, 1
jmp .2
jmp .l
.3:
.r:
ret

View File

@ -13,12 +13,12 @@ ScreenOfDeath:
call printf, .scr1
pop zero
b.nz r14, zero, .not_con
bnz r14, .not_con
push .scr2_con
jmp .do_print
.not_con:
b.l r14, 4, .not_krn
blt r14, 4, .not_krn
push .scr2_krn
jmp .do_print
@ -40,10 +40,10 @@ ScreenOfDeath:
pause
scan rax
jmp.axz .loop
jraxz .loop
b.z rax, 0x0A, DefaultTrapHandler.handle_Exit
b.z rax, 0x1B, DefaultTrapHandler.handle_Shutdown
beq rax, 0x0A, DefaultTrapHandler.handle_Exit
beq rax, 0x1B, DefaultTrapHandler.handle_Shutdown
jmp .loop

View File

@ -5,8 +5,8 @@ DefaultExceptionHandler:
mov rsp, EXCT0_STACK
mov ax1, r12
b.z r12, zero, DefaultTrapHandler.handle_Shutdown
b.a r12, 11, .unknown
bzr r12, DefaultTrapHandler.handle_Shutdown
bltu 11, r12, .unknown
mov rsi, .err_ukn
lea ax0, b[rsi + r12 * 32]

View File

@ -40,16 +40,16 @@ DefaultTrapHandler:
call RFS.LoadReg, r14, $rax
call RFS.LoadArgs, r14
jmp.axz .handle_Shutdown
b.z rax, Sys.Exit, .handle_Exit
b.z rax, Sys.ReadFile, .handle_ReadFile
b.z rax, Sys.OpenFile, .handle_OpenFile
b.z rax, Sys.CloseFile, .handle_CloseFile
b.z rax, Sys.CreateFile, .handle_CreateFile
b.z rax, Sys.RemoveFile, .handle_RemoveFile
b.z rax, Sys.FindNext, .handle_FindNext
b.z rax, Sys.FindFirst, .handle_FindFirst
b.z rax, Sys.EnterHaltMode, .handle_HaltMode
jraxz .handle_Shutdown
beq rax, Sys.Exit, .handle_Exit
beq rax, Sys.ReadFile, .handle_ReadFile
beq rax, Sys.OpenFile, .handle_OpenFile
beq rax, Sys.CloseFile, .handle_CloseFile
beq rax, Sys.CreateFile, .handle_CreateFile
beq rax, Sys.RemoveFile, .handle_RemoveFile
beq rax, Sys.FindNext, .handle_FindNext
beq rax, Sys.FindFirst, .handle_FindFirst
beq rax, Sys.EnterHaltMode, .handle_HaltMode
call ScreenOfDeath, .badsyscall, r13
@ -75,8 +75,7 @@ DefaultTrapHandler:
call DISK.OpenFile, .cmdcom
; Crash on failure
cmp rax, zero
crash.l
bltz rax, abort
; Load at CMDCOM_LOADP
mov ax1, CMDCOM_LOADP
@ -86,7 +85,7 @@ DefaultTrapHandler:
; Assume that COMMAND.COM being
; less then 4KB means something
; went wrong
b.l rax, 0x1000, abort
blt rax, 0x1000, abort
; Close the handle
call DISK.CloseFile, rax
@ -158,13 +157,13 @@ DefaultTrapHandler:
; Misc.
;
.handle_Shutdown:
mov ax0, zero
call IDT.DelHandler
call IDT.DelHandler, zero
stop
.handle_HaltMode:
mov rcx, -1
hlt.rep
stop
pause
pause
hlt
jmp .handle_HaltMode

View File

@ -11,8 +11,7 @@ PrintBootMsg:
; Initialize TRAP handlers
;
InitSyscalls:
mov ax0, 1
call RFS.ActivateFrame
call RFS.ActivateFrame, 1
mov ax1, $rip
mov ax2, DefaultTrapHandler
@ -25,16 +24,13 @@ InitSyscalls:
ret
InitExcepts:
mov ax0, 2
call RFS.ActivateFrame
call RFS.ActivateFrame, 2
mov ax1, $rip
mov ax2, DefaultExceptionHandler
call RFS.StoreReg
mov ax0, zero
mov ax1, 2
call IDT.AddHandler
call IDT.AddHandler, zero, 2
SwitchToCMD:
mov rax, Sys.Exit

View File

@ -31,13 +31,13 @@ builtins.dir:
trap 0
.list:
jmp.axz .end
jraxz .end
mov r15, rcx # file size
mov r15, rcx ; file size
inc r14, rcx
; directory?
jmp.dxnz .is_dir
bnz rdx, .is_dir
; found a file
inc r12, 1
@ -49,8 +49,9 @@ builtins.dir:
scasb.rep.nz rsi, '.'
; print file name
sub rcx, rsi, rdi
prns.rep rdi
sub ax1, rsi, rdi
dec ax1, 1
call nprint, rdi
; calculate where to put extension
sub rdi, rsi, .buf
@ -58,7 +59,7 @@ builtins.dir:
.ext_pad:
; print at least N non-space characters before extension
b.ae rdi, N, .print_ext
blte N, rdi, .print_ext
prn ' '
inc rdi, 1
jmp .ext_pad
@ -68,35 +69,38 @@ builtins.dir:
mov rcx, 4
prn ' '
cmp b[rsi], '.'
inc.z rsi, 1
bne b[rsi], '.', .print_ext.1
inc rsi, 1
.print_ext.1:
b.z b[rsi], 0, .print_ext.2
bzr b[rsi], .print_ext.2
; print and decrease rcx, unless it's already 0
prn b[rsi]
inc rsi, 1
dec.cxnz rcx, 1
jrcxz .print_ext.1
dec rcx, 1
jmp .print_ext.1
.print_ext.2:
; did we print at least 4 bytes?
jmp.cxz .print_bytes ; yes, carry on
jrcxz .print_bytes ; yes, carry on
prn.rep ' '
.pe2.l:
prn ' '
loop .pe2.l
.print_bytes:
; print file size in bytes
mov rcx, 3
prn.rep ' '
prn ' '
prn ' '
prn ' '
shr rax, r15, 10
and r15, r15, 1023
and r15, 1023
push r15
push rax
push r15, rax
call printf, .bytesstr
inc rsp, 16
@ -129,14 +133,20 @@ builtins.dir:
.is_dir:
inc r13, 1
mov rcx, STRLEN_MAX
mov rdx, .buf
prns.rep.nz rdx
; use printf instead of print
; because it returns # of printed
; characters
call printf, .buf
sub rcx, STRLEN_MAX, rcx
sub rcx, N, rcx
prn.rep ' '
blte N, rax, .dir_no_pad
sub rcx, N, rax
dec rcx, 1
.dir.l:
prn ' '
loop .dir.l
.dir_no_pad:
call print, .dir_ext
jmp .print_bytes

View File

@ -22,9 +22,8 @@ main:
call print, prompt
; empty argbuf
mov rcx, argbuf.size
mov rdx, argbuf
stosb.rep rdx, zero
call memzero, argbuf, argbuf.size
call nprint, argbuf, argbuf.size
; iterator through argbuf
mov rcx, zero
@ -38,16 +37,16 @@ main:
; Fill .buf with user input
scan rax
jmp.axz .input_loop
jraxz .input_loop
; ESC key pressed?
b.z rax, 0x1B, .handle_EXIT
beq rax, 0x1B, .handle_EXIT
; backspace character?
b.nz rax, 8, .handle_input
bne rax, 8, .handle_input
; anything to delete?
jmp.cxz .input_loop ; no
jrcxz .input_loop ; no
; yes, delete it
dec rcx, 1
@ -55,19 +54,21 @@ main:
mov b[rdx], zero
; update screen
cmp b[stdin_echoing], 1
prn.z 8
bzr b[stdin_echoing], .input_loop
prn 8
jmp .input_loop
.handle_input:
cmp b[stdin_echoing], 1
prn.z rax
b.z rax, 10, .extract_argv0
bzr b[stdin_echoing], .se.z
prn rax
.se.z:
beq rax, 10, .extract_argv0
; when max line length is reached,
; force a newline
b.z rcx, argbuf.size, .extract_argv0
beq rcx, argbuf.size, .extract_argv0
; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf
@ -80,7 +81,7 @@ main:
.extract_argv0:
; did we read anything at all?
; if not, just go back to waiting input
jmp.cxz .print_prompt
jrcxz .print_prompt
; find first whitespace or null-terminator
mov rcx, argbuf.size
@ -92,13 +93,14 @@ main:
.next_space:
mov rcx, b[rsi]
jmp.cxz .do_extract
jrcxz .do_extract
; skip spaces
cmp rcx, ' '
inc.z rsi, 1
jmp.z .next_space
bne rcx, ' ', .not_a_space
inc rsi, 1
jmp .next_space
.not_a_space:
; if we're here, we found a
; non-zero non-space character
mov q[argv1pos], rsi
@ -107,13 +109,11 @@ main:
.do_extract:
; empty argv0
mov rcx, argbuf.size
mov rax, argv0
stosb.rep rax, zero
call memzero, argv0, argbuf.size
; how much do we copy?
sub rcx, rdx, argbuf
jmp.cxz .detect_builtin
jrcxz .detect_builtin
dec rcx, 1
mov rdi, argbuf
@ -131,67 +131,67 @@ main:
.builtin_cls = "cls"
call strcmp, argv0, .builtin_cls
jmp.axz .handle_CLS
jraxz .handle_CLS
.builtin_crash = "crash"
call strcmp, argv0, .builtin_crash
jmp.axz .handle_CRASH
jraxz .handle_CRASH
.builtin_date = "date"
call strcmp, argv0, .builtin_date
jmp.axz .handle_DATE
jraxz .handle_DATE
.builtin_dir = "dir"
call strcmp, argv0, .builtin_dir
jmp.axz .handle_DIR
jraxz .handle_DIR
.builtin_dump = "dump"
call strcmp, argv0, .builtin_dump
jmp.axz .handle_DUMP
jraxz .handle_DUMP
.builtin_echo = "echo"
call strcmp, argv0, .builtin_echo
jmp.axz .handle_ECHO
jraxz .handle_ECHO
.builtin_erase = "erase"
call strcmp, argv0, .builtin_erase
jmp.axz .handle_ERASE
jraxz .handle_ERASE
.builtin_exit = "exit"
call strcmp, argv0, .builtin_exit
jmp.axz .handle_EXIT
jraxz .handle_EXIT
.builtin_help = "help"
call strcmp, argv0, .builtin_help
jmp.axz .handle_HELP
jraxz .handle_HELP
.builtin_halt = "halt"
call strcmp, argv0, .builtin_halt
jmp.axz .handle_HALT
jraxz .handle_HALT
.builtin_make = "make"
call strcmp, argv0, .builtin_make
jmp.axz .handle_MAKE
jraxz .handle_MAKE
.builtin_print = "print"
call strcmp, argv0, .builtin_print
jmp.axz .handle_PRINT
jraxz .handle_PRINT
.builtin_prompt = "prompt"
call strcmp, argv0, .builtin_prompt
jmp.axz .handle_PROMPT
jraxz .handle_PROMPT
.builtin_remove = "remove"
call strcmp, argv0, .builtin_remove
jmp.axz .handle_REMOVE
jraxz .handle_REMOVE
.builtin_time = "time"
call strcmp, argv0, .builtin_time
jmp.axz .handle_TIME
jraxz .handle_TIME
.builtin_vers = "vers"
call strcmp, argv0, .builtin_vers
jmp.axz .handle_VERS
jraxz .handle_VERS
jmp .command_not_found
@ -231,11 +231,10 @@ main:
jmp .print_prompt
.handle_ECHO:
mov rdx, q[argv1pos]
jmp.dxz .echo.end
mov rax, q[argv1pos]
jraxz .echo.end
mov rcx, argbuf.size
prns.rep.nz rdx
call print, rax
.echo.end:
prn 10
@ -244,10 +243,10 @@ main:
.handle_ERASE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
b.z ax0, zero, .need_params
bzr ax0, .need_params
trap 0
b.l rax, zero, .couldnt_remove
bltz rax, .couldnt_remove
jmp .handle_MAKE ; re-create it back
@ -264,20 +263,20 @@ main:
.handle_MAKE:
mov rax, Sys.CreateFile
mov ax0, q[argv1pos]
b.z ax0, zero, .need_params
bzr ax0, .need_params
trap 0
b.l rax, zero, .couldnt_open
bltz rax, .couldnt_open
jmp .print_prompt
.handle_PRINT:
mov rax, Sys.OpenFile
mov ax0, q[argv1pos]
b.z ax0, zero, .need_params
bzr ax0, .need_params
trap 0
b.l rax, zero, .file_not_found
bltz rax, .file_not_found
mov ax0, rax
mov ax1, FILE_LOADP
@ -291,18 +290,17 @@ main:
mov rax, Sys.CloseFile
trap 0
b.l rcx, zero, .couldnt_read
jmp.cxz .empty_file
bltz rcx, .couldnt_read
jrcxz .empty_file
mov rdx, FILE_LOADP
prns.rep rdx
call nprint, FILE_LOADP, rcx
jmp .print_prompt
.handle_PROMPT:
mov ax0, prompt
mov ax1, q[argv1pos]
b.z ax1, zero, .need_params
bzr ax1, .need_params
call strcpy
jmp .print_prompt
@ -310,10 +308,10 @@ main:
.handle_REMOVE:
mov rax, Sys.RemoveFile
mov ax0, q[argv1pos]
b.z ax0, zero, .need_params
bzr ax0, .need_params
trap 0
b.l rax, zero, .couldnt_remove
bltz rax, .couldnt_remove
jmp .print_prompt

View File

@ -10,8 +10,6 @@
#
# $dest = $src1 OR $src2
#
# Preserves all flags
#
or 2
or 3
@ -20,8 +18,6 @@ or 3
#
# $dest = $src1 AND $src2
#
# Preserves all flags
#
and 2
and 3
@ -30,8 +26,6 @@ and 3
#
# $dest = $src1 XOR $src2
#
# Preserves all flags
#
xor 2
xor 3
@ -41,8 +35,6 @@ xor 3
# $dest = $src1 << $src2 (SHL)
# $dest = $src1 >> $src2 (SHR)
#
# Preserves all flags
#
shl 2
shl 3
shr 2
@ -53,86 +45,41 @@ shr 3
#
# $dest = $src1 >>> $src2 (SAR)
#
# Preserves all flags
#
sar 2
sar 3
#---------------------------------------------------------------------------#
# Arithmetic instructions #
#---------------------------------------------------------------------------#
#
# CMP Comparison instruction
#
# SignExtend($1) - $2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
cmp 2
#
# Arithmetical ADD operation
#
# $dest1 = $src1 + $src2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
add 2
add 3
addf 3
#
# Arithmetical SUB operation
#
# $dest = $src1 - $src2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
sub 2
sub 3
subf 3
#
# Arithmetical ADD/SUB operation, with carry/overflow
#
# $dest = $src1 + $src2 + CF (ADC)
# $dest = $src1 - $src2 - CF (SBB)
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
adcx 2
adcx 3
sbbx 2
sbbx 3
#
# Arithmetical MUL operation
#
# $dest = LO($src1 * $src2)
#
# Preserves ZF and SF
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
#
mul 2
mul 3
mulf 3
# Arithmetical unsigned MUL operation
#
# $dest1 = HI($dest2 * $src)
# $dest2 = LO($dest2 * $src)
#
# Preserves all flags
#
mulhi 3
# Arithmetical signed MUL operation
@ -140,8 +87,6 @@ mulhi 3
# $dest1 = HI($dest2 ** $src)
# $dest2 = LO($dest2 ** $src)
#
# Preserves all flags
#
imulhi 3
#
@ -159,8 +104,6 @@ div 3
#
# $dest = $src1 IDIV $src2
#
# Preserves all flags
#
idiv 2
idiv 3
@ -169,8 +112,6 @@ idiv 3
#
# $dest = $src1 MOD $src2
#
# Preserves all flags
#
rem 2
rem 3

View File

@ -3,6 +3,7 @@
include "SUPER"
include "ALU"
include "JMP"
include "MEM"
include "MISC"
include "STRING"

65
vm/in/JMP Normal file
View File

@ -0,0 +1,65 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
#---------------------------------------------------------------------------#
# Jump instructions #
#---------------------------------------------------------------------------#
#
# Jump (JMP) instruction
#
# RIP = $1
#
jmp 1
jraxz 1
jrcxz 1
jraxnz 1
jrcxnz 1
#
# RCX-dependent jump (LOOP) instruction
#
# IF (RCX > 0) THEN
# RCX = RCX - 1
# RIP = $1
# FI
#
loop 1
#
# Conditional absolute jumps (branches) (BCH)
#
# IF (COND) THEN
# RIP = $3
# FI
#
# reg == 0
bzr 2
# reg != 0
bnz 2
# (s)reg < 0
bltz 2
# r1 == r2
beq 3
# r1 != r2
bne 3
# (s)r1 < (s)r2
blt 3
# r1 < r2
bltu 3
# (s)r1 <= (s)r2
blte 3
# r1 <= r2
blteu 3

View File

@ -1,46 +1,6 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
#---------------------------------------------------------------------------#
# Jump instructions #
#---------------------------------------------------------------------------#
#
# Jump (JMP) instruction
#
# RIP = $1
#
jmp 1
#
# RCX-dependent jump (LOOP) instruction
#
# IF (RCX > 0) THEN
# RCX = RCX - 1
# RIP = $1
# FI
#
loop 1
#
# Conditional absolute jumps (branches) (BCH)
#
# COMPARE(SignExtend($1), $2)
#
# IF (COND) THEN
# RIP = $3
# FI
#
# Sets CF, OF, ZF and SF according to the comparison's results
#
# This instruction is special in that the COND field specified is not evaluated
# before the instruction is executed, but after the comparison it effectuates
#
# Suffixing B with the REP suffix results in undefined behavior
#
bch 3
#---------------------------------------------------------------------------#
# Stack manipulation instructions #
#---------------------------------------------------------------------------#
@ -60,7 +20,7 @@ call 3
#
# POP(RIP)
#
ret
ret 0
#
# Make new stack frame (ENTER)
@ -69,8 +29,9 @@ ret
# RBP = RSP
# RSP = RSP - $1
#
enter
enter 0
enter 1
enter 2
#
# Leave stack frame (LEAVE)
@ -78,7 +39,7 @@ enter 1
# RSP = RBP
# POP(RBP)
#
leave
leave 0
#
# PUSH value onto stack
@ -114,8 +75,6 @@ pop 3
# will result in:
# RAX = RBX + RCX * 2 + 4
#
# Preserves all flags
#
lea 2
#

View File

@ -35,11 +35,6 @@ udf
#
pause
#
# Throw #OVF when RFX.OF=1 (INTO)
#
into
#
# Get timestamp in µseconds
#
@ -79,23 +74,6 @@ dswap 2
#
prn 1
#
# Print a string to standard output (PRN)
#
# COMPARE([%1], 0)
#
# IF (ZF == 0) THEN
# PRN([%1])
# IF (DF == 0) THEN
# %1 = %1 + 1
# ELSE
# %1 = %1 - 1
# FI
# FI
#
#
prns 1
#
# Scan a character from standard input (SCAN)
#

View File

@ -5,21 +5,6 @@
# String manipulation instructions #
#---------------------------------------------------------------------------#
#
# Store value into string (STOSx)
#
# [%1] = $2
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
#
stosb 2
stosw 2
stosd 2
stosq 2
#
# Scan string for a particular value (SCASx)
#

View File

@ -15,7 +15,7 @@
# #ILL if disabled through DV
# #1023 otherwise
#
crash
crash 0
#
# Initiate machine shutdown (STOP)
@ -27,7 +27,7 @@ crash
# #ILL if disabled through DV
# #SHT otherwise
#
stop
stop 0
#
# Halt the processor until next E/I (HLT)
@ -35,7 +35,7 @@ stop
# Throws:
# #SYS if not in supervisor mode
#
hlt
hlt 0
#---------------------------------------------------------------------------#
# E/I handling instructions #
@ -56,16 +56,10 @@ trap 1
# Throws:
# #SYS if not in supervisor mode
#
iret
iret 0
#
# Clear or set interrupt flag (CLI/STI)
#
# Throws:
# #SYS if not in supervisor mode
#
cli
sti
cli 0
sti 0
#---------------------------------------------------------------------------#
# Device control instructions #

View File

@ -139,18 +139,6 @@ IMPL_START(mulhi, 3)
return 2;
}
IMPL_START(mulf, 3)
{
SRCP(p2);
SRCP(p3);
ulong tmp;
__unsigned_multiply128(p2->val, p3->val, &tmp, r1);
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
return 1;
}
//----------------------------------------------------------------------------//
static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)

57
vm/in/jmp.c Normal file
View File

@ -0,0 +1,57 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <in/instrs.h>
//----------------------------------------------------------------------------//
IMPL_START(jmp, 1) { R(RIP) = p1->val; return 0; }
IMPL_START(jraxz, 1) { if (!R(RAX)) R(RIP) = p1->val; return 0; }
IMPL_START(jrcxz, 1) { if (!R(RCX)) R(RIP) = p1->val; return 0; }
IMPL_START(jraxnz, 1) { if (R(RAX)) R(RIP) = p1->val; return 0; }
IMPL_START(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; }
IMPL_START(loop, 1) {
if (R(RCX) > 0) {
R(RCX)--;
R(RIP) = p1->val;
}
return 0;
}
IMPL_START(bzr, 2) { SRCP(p1); if (p1->val == 0) R(RIP) = p2->val; return 0; }
IMPL_START(bnz, 2) { SRCP(p1); if (p1->val != 0) R(RIP) = p2->val; return 0; }
IMPL_START(bltz, 2) { SRCP(p1); if ((long)p1->val < 0) R(RIP) = p2->val; return 0; }
IMPL_START(beq, 3) { SRCP(p1); if (p1->val == p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(bne, 3) { SRCP(p1); if (p1->val != p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(blt, 3) { SRCP(p1); if ((long)p1->val < (long)p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(bltu, 3) { SRCP(p1); if (p1->val < p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(blte, 3) { SRCP(p1); if ((long)p1->val <= (long)p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(blteu, 3) { SRCP(p1); if (p1->val <= p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(bch, 3)
{
SRCP(p1);
SRCP(p2);
COMPARE_SUB(p1->val, p2->val);
if (eval_cond(ctx->cond))
R(RIP) = p3->val;
return 0;
}
IMPL_START(cmp, 2)
{
SRCP(p1);
COMPARE_SUB(p1->val, p2->val);
return 0;
}

View File

@ -5,40 +5,6 @@
//----------------------------------------------------------------------------//
IMPL_START(jmp, 1) { R(RIP) = p1->val; return 0; }
IMPL_START(loop, 1) {
if (R(RCX) > 0) {
R(RCX)--;
R(RIP) = p1->val;
}
return 0;
}
IMPL_START(bch, 3)
{
SRCP(p1);
SRCP(p2);
COMPARE_SUB(p1->val, p2->val);
if (eval_cond(ctx->cond))
R(RIP) = p3->val;
return 0;
}
IMPL_START(cmp, 2)
{
SRCP(p1);
COMPARE_SUB(p1->val, p2->val);
return 0;
}
//----------------------------------------------------------------------------//
IMPL_START(lea, 2) { *r1 = p2->addr; return 1; }
IMPL_START(mov, 2) { XSRCP(*r1, p2, sx); return 1; }
IMPL_START(movzx, 2) { XSRCP(*r1, p2, zx); return 1; }
@ -178,6 +144,8 @@ IMPL_START(ret, 0)
return 0;
}
//----------------------------------------------------------------------------//
IMPL_START(enter, 0)
{
R(RSP) -= 8;
@ -196,6 +164,27 @@ IMPL_START(enter, 1)
return 0;
}
IMPL_START(enter, 2)
{
int i, tmp;
R(RSP) -= 8;
tmp = R(RSP);
writemem(R(RBP), R(RSP), 8);
for (i = 0; i < p2->val; i++)
{
R(RBP) -= 8;
R(RSP) -= 8;
writemem(R(RBP), R(RSP), 8);
}
R(RBP) = tmp;
R(RSP) = tmp - (p1->val * 8);
return 0;
}
IMPL_START(leave, 0)
{
R(RSP) = R(RBP) + 8;

View File

@ -66,7 +66,7 @@ void exec_instr(instr_t *in,
// For REPs we evaluate the condition AFTER running the instruction,
// in a do ... while(cond) fashion
//
if (ctx->cond && in->func != i_bch_3) // 'B' instruction is special
if (ctx->cond)
if (!rep && !eval_cond(ctx->cond))
return;
@ -98,11 +98,6 @@ do_rep:
// Should we really count REP's in instruction count?
ctx->ninstrs++;
#if 0
// Show that we're REP'ing
if (ctx->dumpsw)
dump_instr(in, p1, p2, p3, lock, rep);
#endif
goto do_rep;
}