mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
stuff
This commit is contained in:
parent
f9ecf442a1
commit
b8d29210fb
@ -30,8 +30,7 @@ doprnt:
|
||||
|
||||
.print_regular:
|
||||
; everything below rdi is a regular character; print it
|
||||
cmp rbx, rdi
|
||||
j.z .check_modf
|
||||
b.e rbx, rdi, .check_modf
|
||||
|
||||
mov ax0, b[rbx]
|
||||
call .doput
|
||||
@ -41,29 +40,22 @@ doprnt:
|
||||
|
||||
.check_modf:
|
||||
; did we find a '%' ?
|
||||
cmp b[rbx], '%'
|
||||
j.nz .epilogue ; no, we found fmt's null-terminator; we're done
|
||||
; if not, then we found fmt's null-terminator; we're done
|
||||
b.nz b[rbx], '%', .epilogue
|
||||
|
||||
; we did find a modifier / '%'
|
||||
mov rax, b[rbx+1]
|
||||
add rbx, 2
|
||||
|
||||
cmp rax, 's'
|
||||
j.z .modf_s
|
||||
cmp rax, 'c'
|
||||
j.z .modf_c
|
||||
cmp rax, 'p'
|
||||
j.z .modf_p
|
||||
cmp rax, 'x'
|
||||
j.z .modf_x
|
||||
cmp rax, 'd'
|
||||
j.z .modf_d
|
||||
cmp rax, 'o'
|
||||
j.z .modf_o
|
||||
cmp rax, 'b'
|
||||
j.z .modf_b
|
||||
cmp rax, '%'
|
||||
j.z .modf_percent
|
||||
b.e rax, 's', .modf_s
|
||||
b.e rax, 'c', .modf_c
|
||||
b.e rax, 'p', .modf_p
|
||||
b.e rax, 'x', .modf_x
|
||||
b.e rax, 'd', .modf_d
|
||||
b.e rax, 'o', .modf_o
|
||||
b.e rax, 'b', .modf_b
|
||||
b.e rax, '%', .modf_percent
|
||||
|
||||
; unrecognized
|
||||
jmp .bad_modifier
|
||||
|
||||
|
@ -23,14 +23,11 @@ ltostr:
|
||||
xor rx8, rx8
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
cmp ax2, 2
|
||||
j.b .bad
|
||||
cmp ax2, 36
|
||||
j.a .bad
|
||||
b.b ax2, 2, .bad
|
||||
b.a ax2, 36, .bad
|
||||
|
||||
; deal with zero
|
||||
test ax1, ax1
|
||||
j.z .zero
|
||||
b.e ax1, 0, .zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
@ -45,14 +42,12 @@ ltostr:
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
test ax1, ax1
|
||||
j.z .fini
|
||||
b.e ax1, 0, .fini
|
||||
|
||||
mov r10, ax1
|
||||
rem r10, ax2 ; ax1 % base
|
||||
|
||||
cmp r10, 9 ; r10 > 9 ?
|
||||
j.a .nondec
|
||||
b.a r10, 9, .nondec ; r10 > 9 ?
|
||||
|
||||
add r10, '0'
|
||||
jmp .next
|
||||
|
@ -33,15 +33,9 @@ nprintf:
|
||||
;
|
||||
print:
|
||||
mov rcx, STRLEN_MAX
|
||||
|
||||
b.z b[ax0], 0, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
cmp b[ax0], 0
|
||||
ret.z
|
||||
|
||||
prn b[ax0]
|
||||
inc ax0
|
||||
loop .1
|
||||
|
||||
ret
|
||||
|
||||
;
|
||||
@ -49,11 +43,8 @@ print:
|
||||
;
|
||||
print_n:
|
||||
mov rcx, ax1
|
||||
|
||||
b.z b[ax0], 0, .1
|
||||
prns.rep.nz ax0
|
||||
.1:
|
||||
prn b[ax0]
|
||||
inc ax0
|
||||
loop .1
|
||||
|
||||
ret
|
||||
|
||||
|
@ -31,14 +31,11 @@ strtoq:
|
||||
mov rdx, ax0
|
||||
|
||||
; make sure base is in [2, 32]
|
||||
cmp ax1, 1
|
||||
j.z .bad
|
||||
cmp ax1, 36
|
||||
j.a .bad
|
||||
b.z ax1, 1, .bad
|
||||
b.a ax1, 36, .bad
|
||||
|
||||
; empty string?
|
||||
cmp b[rdx], 0
|
||||
jmp.z .done
|
||||
b.z b[rdx], 0, .done
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
@ -62,36 +59,27 @@ strtoq:
|
||||
|
||||
.unsigned:
|
||||
; base 0
|
||||
test ax1, ax1
|
||||
jmp.z .base_0
|
||||
b.z ax1, 0, .base_0
|
||||
|
||||
; base prefix?
|
||||
cmp b[rdx], '0'
|
||||
jmp.nz .main_loop
|
||||
b.nz b[rdx], '0', .main_loop
|
||||
|
||||
inc rdx
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; string is "0"
|
||||
cmp b[rdx], 0
|
||||
jmp.z .done
|
||||
|
||||
; "0x" prefix
|
||||
cmp b[rdx], 'x'
|
||||
jmp.z .parsed_0x
|
||||
|
||||
; "0b" prefix
|
||||
cmp b[rdx], 'b'
|
||||
jmp.z .parsed_0b
|
||||
; "0x"/"0b" prefix
|
||||
b.z rcx, 0, .done ; "0"
|
||||
b.z rcx, 'x', .parsed_0x
|
||||
b.z rcx, 'b', .parsed_0b
|
||||
|
||||
; may be octal, but we don't care
|
||||
; we accept "0110101010" (binary) for instance
|
||||
; we accept "0110101010" (despite base=2) for instance
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0x:
|
||||
; are we in base 16?
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
cmp ax1, 16
|
||||
jmp.nz .done
|
||||
b.nz ax1, 16, .done
|
||||
; else
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
@ -99,8 +87,7 @@ strtoq:
|
||||
.parsed_0b:
|
||||
; are we in base 2?
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
cmp ax1, 2
|
||||
jmp.nz .done
|
||||
b.nz ax1, 2, .done
|
||||
; else
|
||||
inc rdx
|
||||
jmp .main_loop
|
||||
@ -126,7 +113,7 @@ strtoq:
|
||||
mov ax1, 8
|
||||
|
||||
.main_loop:
|
||||
mov rx8, b[rdx]
|
||||
movzx rx8, b[rdx]
|
||||
inc rdx
|
||||
|
||||
cmp rx8, '0'
|
||||
@ -148,8 +135,7 @@ strtoq:
|
||||
|
||||
.next:
|
||||
; too large for base?
|
||||
cmp rx8, ax1
|
||||
jmp.ae .done
|
||||
b.ae rx8, ax1, .done
|
||||
|
||||
mul rax, ax1
|
||||
add rax, rx8
|
||||
|
@ -53,8 +53,7 @@ strrev2:
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
cmp ax0, ax1
|
||||
j.ae .3
|
||||
b.ae ax0, ax1, .3
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
|
@ -9,7 +9,6 @@ start:
|
||||
xor rbp, rbp
|
||||
|
||||
call main
|
||||
|
||||
call CMD.builtins.dir
|
||||
|
||||
hlt
|
||||
@ -19,8 +18,7 @@ start:
|
||||
scan rax
|
||||
xpause
|
||||
|
||||
test rax, rax
|
||||
j.z .1
|
||||
b.z rax, 0, .1
|
||||
|
||||
prn rax
|
||||
jmp .1
|
||||
|
@ -2,8 +2,9 @@
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
PrintBootMsg:
|
||||
mov ax0, .bootmsg
|
||||
call print
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .bootmsg
|
||||
prns.rep.nz rdx
|
||||
ret
|
||||
|
||||
.bootmsg = "Starting DOS...\n\n"
|
||||
|
@ -5,8 +5,9 @@ CMD.builtins.dir:
|
||||
|
||||
sub nx0, nx0 # no. of files found
|
||||
|
||||
mov ax0, .dirmsg
|
||||
call print
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .dirmsg
|
||||
prns.rep.nz rdx
|
||||
|
||||
.dirmsg = "Directory of C:\\\n\n"
|
||||
|
||||
@ -22,8 +23,7 @@ CMD.builtins.dir:
|
||||
call DISK.FindNext
|
||||
|
||||
.list:
|
||||
test rax, rax
|
||||
j.z .end
|
||||
b.z rax, 0, .end
|
||||
|
||||
; found something
|
||||
inc nx0
|
||||
@ -34,12 +34,9 @@ CMD.builtins.dir:
|
||||
mov r11, r10
|
||||
scasb.rep.nz r10, '.'
|
||||
|
||||
.print_file_name:
|
||||
prn b[r11]
|
||||
inc r11
|
||||
|
||||
cmp r11, r10
|
||||
j.b .print_file_name
|
||||
; print file name
|
||||
ksub rcx, r10, r11
|
||||
prns.rep r11
|
||||
|
||||
; calculate where to put extension
|
||||
ksub r11, r10, .buf
|
||||
@ -47,8 +44,7 @@ CMD.builtins.dir:
|
||||
|
||||
.ext_pad:
|
||||
; print at least 11 non-space characters before extension
|
||||
cmp r11, 11
|
||||
j.ae .print_ext
|
||||
b.ae r11, 11, .print_ext
|
||||
prn ' '
|
||||
inc r11
|
||||
jmp .ext_pad
|
||||
@ -62,21 +58,18 @@ CMD.builtins.dir:
|
||||
inc.z r10
|
||||
|
||||
.print_ext.1:
|
||||
cmp b[r10], 0
|
||||
j.z .print_ext.2
|
||||
b.z b[r10], 0, .print_ext.2
|
||||
|
||||
; print and decrease rcx, unless it's already 0
|
||||
prn b[r10]
|
||||
inc r10
|
||||
test rcx, rcx
|
||||
dec.nz rcx
|
||||
dec.cxnz rcx
|
||||
|
||||
jmp .print_ext.1
|
||||
|
||||
.print_ext.2:
|
||||
; did we print at least 4 bytes?
|
||||
test rcx, rcx
|
||||
j.z .print_bytes ; yes, carry on
|
||||
j.cxz .print_bytes ; yes, carry on
|
||||
|
||||
prn.rep ' '
|
||||
|
||||
@ -109,8 +102,9 @@ CMD.builtins.dir:
|
||||
call printf
|
||||
add rsp, 8
|
||||
|
||||
mov ax0, .endstr2
|
||||
call print
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .endstr2
|
||||
prns.rep.nz rdx
|
||||
|
||||
pop nx0
|
||||
ret
|
||||
|
17
vm/in/INOUT
17
vm/in/INOUT
@ -10,6 +10,23 @@
|
||||
#
|
||||
prn rim
|
||||
|
||||
#
|
||||
# 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 r
|
||||
|
||||
#
|
||||
# Scan a character from standard input (SCAN)
|
||||
#
|
||||
|
@ -13,5 +13,5 @@ include "FLAGS"
|
||||
include "INOUT"
|
||||
include "DEBUG"
|
||||
include "STRING"
|
||||
include "KINSTRS"
|
||||
include "TERNARY"
|
||||
|
||||
|
28
vm/in/JUMPS
28
vm/in/JUMPS
@ -24,20 +24,20 @@ jmp ri
|
||||
loop ri
|
||||
|
||||
#
|
||||
# Relative jump (BCH) instruction ("branch")
|
||||
# Conditional absolute jumps (B)
|
||||
#
|
||||
# RIP = RIP + $1
|
||||
# COMPARE($1, $2)
|
||||
#
|
||||
b ri
|
||||
bch ri
|
||||
|
||||
#
|
||||
# RCX-dependent relative jump (BOOP) instruction
|
||||
#
|
||||
# IF (RCX > 0) THEN
|
||||
# RCX = RCX - 1
|
||||
# RIP = RIP + $1
|
||||
# FI
|
||||
#
|
||||
boop ri
|
||||
# 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
|
||||
#
|
||||
b rim rim ri
|
||||
|
||||
|
@ -13,6 +13,24 @@ IMPL_START_1(prn)
|
||||
}
|
||||
IMPL_END
|
||||
|
||||
IMPL_START_0(prns)
|
||||
{
|
||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||
|
||||
COMPARE(ch, 0);
|
||||
|
||||
if ((flg & ZF) == 0)
|
||||
{
|
||||
console_putc(ctx, ch);
|
||||
|
||||
if (flg & DF)
|
||||
R(p1->reg)--;
|
||||
else
|
||||
R(p1->reg)++;
|
||||
}
|
||||
}
|
||||
IMPL_END
|
||||
|
||||
IMPL_START_1(scan)
|
||||
{
|
||||
v1 = console_scankeybuf(ctx);
|
||||
|
@ -3,9 +3,7 @@
|
||||
|
||||
#include <in/instrs.h>
|
||||
|
||||
//
|
||||
// Jump instructions
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(j)
|
||||
{
|
||||
@ -28,24 +26,16 @@ IMPL_START_1(loop)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(b)
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_3(b)
|
||||
{
|
||||
rip += v1;
|
||||
COMPARE(v1, v2);
|
||||
|
||||
if (eval_cond(ctx, ctx->cond))
|
||||
rip = v3;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(bch)
|
||||
{
|
||||
rip += v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(boop)
|
||||
{
|
||||
if (rcx > 0) {
|
||||
rcx--;
|
||||
rip += v1;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define K_IMPL_ALU(name, expr) \
|
||||
IMPL_START_3(k##name) \
|
||||
{ \
|
||||
v1 = expr; \
|
||||
v1 = (expr); \
|
||||
} \
|
||||
IMPL_OUT_ZSF
|
||||
|
@ -70,6 +70,9 @@ struct ctx_t
|
||||
|
||||
// Instructions executed so far
|
||||
ulong ninstrs;
|
||||
|
||||
// Last COND field
|
||||
uint cond;
|
||||
};
|
||||
|
||||
#define R(X) ctx->rf[X]
|
||||
|
@ -7,7 +7,8 @@
|
||||
// Read the "DECD" file before reading this code
|
||||
//
|
||||
|
||||
static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt, int which)
|
||||
static void check_param_type(ctx_t *ctx, instr_t *in,
|
||||
uint prm, uchar fmt, int which)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
@ -153,7 +154,6 @@ void decode(ctx_t *ctx)
|
||||
acc_t p3 = { 0 };
|
||||
|
||||
bool rep = 0;
|
||||
uint cond = 0;
|
||||
bool lock, nomore;
|
||||
|
||||
ushort w1, w2;
|
||||
@ -172,9 +172,9 @@ void decode(ctx_t *ctx)
|
||||
nomore = !!(w1 & SUFF_NOMORE);
|
||||
|
||||
if (w1 & SUFF_COND)
|
||||
{
|
||||
cond = ctx->get(ctx);
|
||||
}
|
||||
ctx->cond = ctx->get(ctx);
|
||||
else
|
||||
ctx->cond = 0;
|
||||
|
||||
w1 &= ~(SUFF_LOCK|SUFF_NOMORE|SUFF_COND);
|
||||
|
||||
@ -217,7 +217,7 @@ void decode(ctx_t *ctx)
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep, cond);
|
||||
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ void decode(ctx_t *ctx)
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep, cond);
|
||||
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -257,13 +257,13 @@ void decode(ctx_t *ctx)
|
||||
f1, f2, f3, in->full);
|
||||
}
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep, cond);
|
||||
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
check_param_type(ctx, in, in->prm3, f3, 3);
|
||||
extract_param(ctx, &p3, f3);
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep, cond);
|
||||
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep);
|
||||
}
|
||||
|
||||
|
@ -81,14 +81,15 @@ struct instr_t
|
||||
ulong *, ulong *, ulong *);
|
||||
};
|
||||
|
||||
bool eval_cond(ctx_t *ctx, uint cond);
|
||||
|
||||
void exec_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
bool lock,
|
||||
bool rep,
|
||||
uint cond);
|
||||
bool rep);
|
||||
|
||||
void extract_param(ctx_t *ctx,
|
||||
acc_t *p,
|
||||
@ -100,6 +101,5 @@ void dump_instr(ctx_t *ctx,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
bool lock,
|
||||
bool rep,
|
||||
uint cond);
|
||||
bool rep);
|
||||
|
||||
|
11
vm/pc/dump.c
11
vm/pc/dump.c
@ -13,10 +13,6 @@ char *cond_suffixes[] =
|
||||
"?"
|
||||
};
|
||||
|
||||
#ifndef _ATT_STYLE
|
||||
#define _ATT_STYLE 0
|
||||
#endif
|
||||
|
||||
void dump_acc(ctx_t *ctx, acc_t *p);
|
||||
|
||||
void dump_instr(ctx_t *ctx,
|
||||
@ -25,12 +21,9 @@ void dump_instr(ctx_t *ctx,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
bool lock,
|
||||
bool rep,
|
||||
uint cond)
|
||||
bool rep)
|
||||
{
|
||||
/*
|
||||
trace("%03lu 0x%lX:\t", ctx->ninstrs, pc);
|
||||
*/
|
||||
uint cond = ctx->cond;
|
||||
|
||||
trace("0x%lX:\t", rpc);
|
||||
|
||||
|
21
vm/pc/exec.c
21
vm/pc/exec.c
@ -2,6 +2,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/arch.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
bool eval_cond(ctx_t *ctx, uint cond)
|
||||
{
|
||||
@ -50,8 +51,7 @@ void exec_instr(ctx_t *ctx,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
bool lock,
|
||||
bool rep,
|
||||
uint cond)
|
||||
bool rep)
|
||||
{
|
||||
bool out;
|
||||
ulong r1 = 0, r2 = 0, r3 = 0;
|
||||
@ -67,17 +67,12 @@ void exec_instr(ctx_t *ctx,
|
||||
// For REPs we evaluate the condition AFTER running the instruction,
|
||||
// in a do ... while(cond) fashion
|
||||
//
|
||||
if (!rep && !eval_cond(ctx, cond))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
// Say something about ignored instruction?
|
||||
//trace("0x%lX:\n", rpc);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (ctx->cond && in->func != i_b) // 'B' instruction is special
|
||||
if (!rep && !eval_cond(ctx, ctx->cond))
|
||||
return;
|
||||
|
||||
#ifndef NDEBUG
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep, cond);
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep);
|
||||
#endif
|
||||
|
||||
do_rep:
|
||||
@ -132,7 +127,7 @@ do_rep:
|
||||
if (rep)
|
||||
{
|
||||
// RCX remains untouched when condition fails
|
||||
if (!eval_cond(ctx, cond))
|
||||
if (!eval_cond(ctx, ctx->cond))
|
||||
return;
|
||||
|
||||
if (rcx > 0)
|
||||
@ -145,7 +140,7 @@ do_rep:
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Show that we're REP'ing
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep, cond);
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep);
|
||||
#endif
|
||||
|
||||
goto do_rep;
|
||||
|
Loading…
Reference in New Issue
Block a user