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-07-11 18:34:21 +02:00
parent 42202788da
commit cec0afb0ee
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
37 changed files with 369 additions and 348 deletions

View File

@ -296,7 +296,10 @@ def parse_preproc(line):
sys.exit(1)
i = int(s, base=0)
i = i + (8 - i % 8)
if (i % 8) != 0:
i = i + (8 - i % 8)
written = b_data.write(bytearray(i))
assert(written == i)
@ -334,9 +337,10 @@ def parse_preproc(line):
pdata += 1
# align
for i in range(8 - len(s) % 8):
written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False))
pdata += 1
if (len(s) % 8) != 0:
for i in range(8 - len(s) % 8):
written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False))
pdata += 1
pdefs[label + "_len"] = str(real_len)
@ -756,7 +760,9 @@ special_syms = {
def gentext():
text_start = start_addr
data_start = text_start + ptext
data_start += (8 - data_start % 8)
if (data_start % 8) != 0:
data_start += (8 - data_start % 8)
instrs.seek(0)
@ -844,7 +850,9 @@ def sort_by_list(dict_, list_):
def gensym():
text_start = start_addr
data_start = text_start + ptext
data_start += (8 - data_start % 8)
if (data_start % 8) != 0:
data_start += (8 - data_start % 8)
for label in plabels_text:
plabels_text[label] += text_start
@ -864,10 +872,11 @@ def genout():
b_data.seek(0)
b_out.write(b_text.read())
data_align = (8 - ptext % 8)
if (ptext % 8) != 0:
data_align = (8 - ptext % 8)
for i in range(data_align):
b_out.write(int(0).to_bytes(1, byteorder='little', signed=False))
for i in range(data_align):
b_out.write(int(0).to_bytes(1, byteorder='little', signed=False))
b_out.write(b_data.read())

View File

@ -1,33 +1,22 @@
inv
flg
rip eip ip
rpc epc pc
px0
px1
fc1
fc2
sa0 k0
sa1 k1
sa2 k2
sa3 k3
cr0 c0
cr1 c1
cr2 c2
cr3 c3
cr4 c4
trp tp
rax eax ax rx0 r0
rbx ebx bx rx1 r1
rcx ecx cx rx2 r2
rdx edx dx rx3 r3
rsi esi si rx4 r4
rdi edi di rx5 r5
rbp ebp bp rx6 r6
rsp esp sp rx7 r7
rx8 r8
rx9 r9
rax ax r0
rbx bx r1
rcx cx r2
rdx dx r3
rsi si r4
rdi di r5
rbp bp r6
rsp sp r7
rfx fs r8
rip ip r9
r10
r11
r12
@ -35,36 +24,20 @@ r13
r14
r15
ax0 a0
ax1 a1
ax2 a2
ax3 a3
ax4 a4
ax5 a5
ax6 a6
ax7 a7
ax8 a8
ax9 a9
a10
a11
a12
a13
a14
a15
ax0 a0 r16
ax1 a1 r17
ax2 a2 r18
ax3 a3 r19
ax4 a4 r20
ax5 a5 r21
ax6 a6 r22
ax7 a7 r23
nx0 n0
nx1 n1
nx2 n2
nx3 n3
nx4 n4
nx5 n5
nx6 n6
nx7 n7
nx8 n8
nx9 n9
n10
n11
n12
n13
n14
n15
nx0 n0 r24
nx1 n1 r25
nx2 n2 r26
nx3 n3 r27
nx4 n4 r28
nx5 n5 r29
nx6 n6 r30
nx7 n7 r31

View File

@ -9,4 +9,5 @@ include "crt/limits.k"
include "crt/err/errno.k"
include "crt/fmt/format.k"
include "crt/str/string.k"
include "crt/lib/time.k"

View File

@ -20,7 +20,7 @@ utoa:
;
ltostr:
mov rax, ax0
xor rx8, rx8
xor r11, r11
; make sure base is in [2, 32]
b.b ax2, 2, .bad
@ -35,9 +35,9 @@ ltostr:
cmp.nz ax2, 10 ; base 10
j.nz .conv
sgn rx8, ax1 ; extract ax1 sign
sgn r11, ax1 ; extract ax1 sign
cmp rx8, -1 ; negative?
cmp r11, -1 ; negative?
neg.z ax1, ax1
; main loop
@ -63,7 +63,7 @@ ltostr:
; add minus flag, null-terminate and reverse
.fini:
cmp rx8, -1
cmp r11, -1
mov.z b[ax0], '-'
inc.z ax0

View File

@ -113,32 +113,32 @@ strtoq:
mov ax1, 8
.main_loop:
movzx rx8, b[rdx]
movzx r12, b[rdx]
inc rdx
cmp rx8, '0'
cmp r12, '0'
jmp.b .done
cmp.ae rx8, '9'
sub.be rx8, '0'
cmp.ae r12, '9'
sub.be r12, '0'
jmp.be .next
cmp rx8, 'A'
cmp.ae rx8, 'Z'
sub.be rx8, 55 ; 'A' - 10
cmp r12, 'A'
cmp.ae r12, 'Z'
sub.be r12, 55 ; 'A' - 10
jmp.be .next
cmp rx8, 'a'
cmp r12, 'a'
jmp.b .next
cmp.ae rx8, 'z'
sub.be rx8, 87 ; 'a' - 10
cmp.ae r12, 'z'
sub.be r12, 87 ; 'a' - 10
jmp.be .next
.next:
; too large for base?
b.ae rx8, ax1, .done
b.ae r12, ax1, .done
mul rax, ax1
add rax, rx8
add rax, r12
jmp .main_loop
.done:

83
ka/crt/lib/time.k Normal file
View File

@ -0,0 +1,83 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; struct TIME
; {
; byte sec; +0 (0-59)
; byte min; +1 (0-59)
; byte hour; +2 (0-23)
; byte mday; +3 (0-31)
; byte month; +4 (0-11)
; byte; +5 (pad)
; word year; +6 (0-65536)
; word yday; +8 (0-365)
; word; +10 (pad)
; dword; +12 (pad)
; } 16 bytes
;
;
; int DaysInYear(int year)
;
DaysInYear:
mov rax, 365
; divisible by 4?
rem rcx, ax0, 4
b.nz rcx, 0, .end
; divisible by 100?
rem rcx, ax0, 100
b.nz rcx, 0, .leap
; divisible by 400?
rem rcx, ax0, 400
b.nz rcx, 0, .end
.leap:
inc rax
.end:
ret
;
; TIME *GetTimeUTC(void)
;
GetTimeUTC:
ytime r11, r12, r13
mov rdx, .buf
; seconds
rem rcx, r11, 60
mov b[rdx], rcx
; minutes
div rcx, r11, 60
rem rcx, 60
mov b[rdx+1], rcx
; hours
div rcx, r11, 3600
rem rcx, 24
mov b[rdx+2], rcx
; month days
div rcx, r11, 3600*24
mov b[rdx+3], rcx
; month
mov b[rdx+4], r12
; years
mov w[rdx+6], r13
;
; ydays (TODO)
;
mov rax, .buf
ret
.buf = [24]

View File

@ -12,7 +12,7 @@ strrev:
ret.z
; save str's location
mov rx8, ax1
mov r10, ax1
; go to str's end, just before
; the null terminator
@ -26,7 +26,7 @@ strrev:
mov rax, b[ax1]
mov b[ax0], rax
cmp ax1, rx8
cmp ax1, r10
mov.z b[ax0+1], 0
ret.z

View File

@ -63,7 +63,7 @@ trap0_handler:
call RFS.StoreReg
; No flags set
mov ax1, $flg
mov ax1, $rfx
xor ax2, ax2
call RFS.StoreReg

View File

@ -83,11 +83,11 @@ main:
inc r11
.next_space:
mov rx8, b[r11]
b.z rx8, 0, .no_argv1
mov r10, b[r11]
b.z r10, 0, .no_argv1
; skip spaces
cmp rx8, ' '
cmp r10, ' '
inc.z r11
jmp.z .next_space
@ -115,6 +115,12 @@ main:
call strcmp
b.z rax, 0, .handle_CLS
.builtin_date = "date"
mov ax0, argv0
mov ax1, .builtin_date
call strcmp
b.z rax, 0, .handle_DATE
.builtin_dir = "dir"
mov ax0, argv0
mov ax1, .builtin_dir
@ -145,6 +151,12 @@ main:
call strcmp
b.z rax, 0, .handle_PRINT
.builtin_time = "time"
mov ax0, argv0
mov ax1, .builtin_time
call strcmp
b.z rax, 0, .handle_TIME
.builtin_ver = "ver"
mov ax0, argv0
mov ax1, .builtin_ver
@ -176,6 +188,25 @@ main:
prn 0xC15000AF
jmp .print_prompt
.handle_DATE:
time ax0
call GetTimeUTC
push b[rax+3]
mov rcx, b[rax+4]
inc rcx
push rcx
push w[rax+6]
mov ax0, .datefmt
call printf
add rsp, 8*5
jmp .print_prompt
.datefmt = "%d/%d/%d\n"
.handle_DIR:
call builtins.dir
jmp .print_prompt
@ -198,6 +229,21 @@ main:
.handle_PRINT:
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, 3*8
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
.handle_VER:
mov rcx, STRLEN_MAX
mov rdx, cmd.versionstr
@ -213,6 +259,8 @@ main:
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.echo
@ -223,6 +271,8 @@ main:
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
@ -230,10 +280,12 @@ main:
.helpmsg = "The following commands are built-in:\n"
.helpmsg.cls = " CLS Clear screen\n"
.helpmsg.date = " DATE Display current date\n"
.helpmsg.dir = " DIR Print contents of current directory\n"
.helpmsg.echo = " ECHO Write arguments to standard output\n"
.helpmsg.exit = " EXIT Initiate machine shutdown\n"
.helpmsg.help = " HELP Show these messages\n"
.helpmsg.print = " PRINT Show contents of text file\n"
.helpmsg.ver = " VER Show current COMMAND.COM and DOS kernel versions\n"
.helpmsg.help = " HELP Display these messages\n"
.helpmsg.print = " PRINT Display contents of text file\n"
.helpmsg.time = " TIME Display current time of day\n"
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"

View File

@ -6,7 +6,7 @@
verbose ?= yes
OBJDIR = ob
FLAGS=-O2 -Wall -fno-builtin-log -I.
FLAGS=-O2 -Wall -fno-builtin-log -I. -Werror=implicit-function-declaration
dv_src = $(shell ls dv/*.c)
in_src = $(shell ls in/*.c)

View File

@ -188,7 +188,7 @@ long cpudev_storereg(ctx_t *ctx, dev_t *dev)
if ((ushort)ax1 >= NREGS)
_except(ctx, E_UDF, "cpudev: register index out of range: #%u", ax1);
rfs[ax0][ax1] = ax2;
rfs[ax0][ax1] = R(AX2);
return 0;
}

View File

@ -97,7 +97,10 @@ long diskdev_open(ctx_t *ctx, dev_t *dev)
tmp = open(buf, O_RDWR);
if (tmp < 0)
{
perror("diskdev: open");
return -1;
}
disk->table[fd] = tmp;
rax = fd;
@ -126,7 +129,7 @@ long diskdev_read(ctx_t *ctx, dev_t *dev)
{
GETDISK();
if (ax0 >= MAXOPEN || disk->table[ax0] <= 0 || ax2 >= MAXRW)
if (ax0 >= MAXOPEN || disk->table[ax0] <= 0 || R(AX2) >= MAXRW)
return -1;
int ret;
@ -135,7 +138,7 @@ long diskdev_read(ctx_t *ctx, dev_t *dev)
if (buf == NULL)
return -1;
ret = read(disk->table[ax0], buf, ax2);
ret = read(disk->table[ax0], buf, R(AX2));
if (ret < 0)
{

View File

@ -13,17 +13,6 @@
#
break
#
# Step-by-step execution (STEP)
#
# IF $1 == 0 THEN
# (disable step-by-step execution)
# ELSE
# (enable step-by-step execution)
# FI
#
step ri
#
# Enable/disable instruction dumping (DUMP)
#

View File

@ -36,6 +36,13 @@ xpause
#
time r
#
# $1 = seconds since start of month
# $2 = current month
# $3 = current year
#
ytime r r r
#
# Get timestamp in µseconds
#

View File

@ -86,12 +86,3 @@ rotl rm r r
#
ldarg r r
#
# Get code/data offset (GCO/GCD)
#
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco r
gcd r

View File

@ -43,7 +43,7 @@ leave
# RSP = RSP - 8
# *RSP = $1
#
push ri
push rim
#
# POP value from stack

View File

@ -88,28 +88,28 @@ IMPL_END;
IMPL_START_2(adc)
{
ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&CF);
v1 = src1 + src2 + !!(rfx&CF);
}
IMPL_OUT;
IMPL_START_2(ado)
{
ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&OF);
v1 = src1 + src2 + !!(rfx&OF);
}
IMPL_OUT;
IMPL_START_2(sbb)
{
ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&CF);
v1 = src1 - src2 - !!(rfx&CF);
}
IMPL_OUT;
IMPL_START_2(sbo)
{
ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&OF);
v1 = src1 - src2 - !!(rfx&OF);
}
IMPL_OUT;
@ -159,13 +159,13 @@ IMPL_START_2(mulf)
multiply(src1, src2, &v2, &v1);
if (v2 > 0) {
flg |= CF;
flg |= OF;
rfx |= CF;
rfx |= OF;
}
else {
flg &= ~CF;
flg &= ~OF;
rfx &= ~CF;
rfx &= ~OF;
}
}
IMPL_OUT;

View File

@ -16,12 +16,6 @@ IMPL_START_0(break)
}
IMPL_END;
IMPL_START_1(step)
{
ctx->step = !!v1;
}
IMPL_END;
IMPL_START_1(dump)
{
(void)v1;

View File

@ -8,14 +8,14 @@
IMPL_START_0(cli)
{
CHK_SUPERV();
cr0 &= ~IF;
R(CR0) &= ~IF;
}
IMPL_END;
IMPL_START_0(sti)
{
CHK_SUPERV();
cr0 |= IF;
R(CR0) |= IF;
}
IMPL_END;
@ -23,13 +23,13 @@ IMPL_END;
IMPL_START_0(cld)
{
flg &= ~DF;
R(RFX) &= ~DF;
}
IMPL_END;
IMPL_START_0(std)
{
flg |= DF;
R(RFX) |= DF;
}
IMPL_END;
@ -37,19 +37,19 @@ IMPL_END;
IMPL_START_0(cmc)
{
flg = (flg&CF ? flg&~CF : flg|CF);
R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF);
}
IMPL_END;
IMPL_START_0(clc)
{
flg &= ~CF;
R(RFX) &= ~CF;
}
IMPL_END;
IMPL_START_0(stc)
{
flg |= CF;
R(RFX) |= CF;
}
IMPL_END;

View File

@ -4,13 +4,13 @@
#define PARITY(v) __builtin_parity(v)
#define SET_ZF(v) \
flg = ((v) == 0 ? (flg|ZF) : (flg&~ZF))
R(RFX) = ((v) == 0 ? (R(RFX)|ZF) : (R(RFX)&~ZF))
#define SET_SF(v) \
flg = ((long)(v) < 0 ? (flg|SF) : (flg&~SF))
R(RFX) = ((long)(v) < 0 ? (R(RFX)|SF) : (R(RFX)&~SF))
#define SET_PF(v) \
flg = (PARITY(v) == 1 ? (flg|PF) : (flg&~PF))
R(RFX) = (PARITY(v) == 1 ? (R(RFX)|PF) : (R(RFX)&~PF))
#define SET_ZSF(v) \
SET_ZF(v); \
@ -25,12 +25,12 @@
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
long _s1 = (long)v1, _s2 = (long)v2; \
\
if (_u1 < _u2) flg |= CF; \
else flg &= ~CF; \
if (_u1 < _u2) R(RFX) |= CF; \
else R(RFX) &= ~CF; \
\
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
flg |= OF; \
else flg &= ~OF; \
R(RFX) |= OF; \
else R(RFX) &= ~OF; \
SET_ZSF(_u1 - _u2);

View File

@ -26,11 +26,11 @@ IMPL_START_0(prns)
COMPARE(ch, 0);
if ((flg & ZF) == 0)
if ((rfx & ZF) == 0)
{
console_putc(ctx, ch);
if (flg & DF)
if (rfx & DF)
R(p1->reg)--;
else
R(p1->reg)++;

View File

@ -94,7 +94,7 @@ IMPL_START_2(name) \
#define CHK_SUPERV() \
do { \
if ((cr0 & UF) > 0) { \
if ((R(CR0) & UF) > 0) { \
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
} \
} while (0)

View File

@ -7,21 +7,21 @@
IMPL_START_1(j)
{
rip = v1;
R(RIP) = v1;
}
IMPL_END;
IMPL_START_1(jmp)
{
rip = v1;
R(RIP) = v1;
}
IMPL_END;
IMPL_START_1(loop)
{
if (rcx > 0) {
rcx--;
rip = v1;
if (R(RCX) > 0) {
R(RCX)--;
R(RIP) = v1;
}
}
IMPL_END;
@ -33,7 +33,7 @@ IMPL_START_3(b)
COMPARE(v1, v2);
if (eval_cond(ctx, ctx->cond))
rip = v3;
R(RIP) = v3;
}
IMPL_END;

View File

@ -13,7 +13,7 @@ IMPL_OUT;
IMPL_START_2(test)
{
flg &= ~(CF|OF);
rfx &= ~(CF|OF);
SET_ZSF(v1 & v2);
}
IMPL_END;

View File

@ -44,6 +44,20 @@ IMPL_START_1(time)
}
IMPL_OUT;
IMPL_START_3(ytime)
{
time_t t = time(NULL);
struct tm *tm = localtime(&t);
v1 = tm->tm_sec + tm->tm_min * 60
+ tm->tm_hour * 60 * 60
+ tm->tm_mday * 60 * 60 * 24;
v2 = tm->tm_mon;
v3 = tm->tm_year + 1900;
}
IMPL_OUT_3;
IMPL_START_1(utime)
{
struct timeval time;
@ -56,27 +70,27 @@ IMPL_OUT;
IMPL_START_0(cls)
{
rax = rbx = rcx = rdx = rdi = rsi = 0;
for (int i = RX8; i <= N15; i++) R(i) = 0;
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
for (int i = R10; i <= NX7; i++) R(i) = 0;
}
IMPL_END;
IMPL_START_0(clr)
{
rax = rbx = rcx = rdx = rdi = rsi = 0;
for (int i = RX8; i <= R15; i++) R(i) = 0;
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 <= A15; i++) R(i) = 0;
for (int i = AX0; i <= AX7; i++) R(i) = 0;
}
IMPL_END;
IMPL_START_0(cln)
{
for (int i = NX0; i <= N15; i++) R(i) = 0;
for (int i = NX0; i <= NX7; i++) R(i) = 0;
}
IMPL_END;

View File

@ -60,12 +60,12 @@ IMPL_OUT_2;
IMPL_START_2(cmpxchg)
{
if (rax == v1) {
flg |= ZF;
rfx |= ZF;
v1 = v2;
}
else {
flg &= ~ZF;
rfx &= ~ZF;
rax = v1;
}
}
@ -105,17 +105,3 @@ IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_1(gco)
{
v1 = cr1;
}
IMPL_OUT;
IMPL_START_1(gcd)
{
v1 = cr2;
}
IMPL_OUT;
//----------------------------------------------------------------------------//

View File

@ -9,46 +9,46 @@
IMPL_START_1(push)
{
rsp -= 8;
writemem(ctx, v1, rsp, 8);
R(RSP) -= 8;
writemem(ctx, v1, R(RSP), 8);
}
IMPL_END;
IMPL_START_1(pop)
{
v1 = readmem(ctx, rsp, 8);
rsp += 8;
v1 = readmem(ctx, R(RSP), 8);
R(RSP) += 8;
}
IMPL_OUT;
IMPL_START_1(call)
{
rsp -= 8;
writemem(ctx, rip, rsp, 8);
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
rip = v1;
R(RIP) = v1;
}
IMPL_END;
IMPL_START_0(ret)
{
rip = readmem(ctx, rsp, 8);
rsp += 8;
R(RIP) = readmem(ctx, R(RSP), 8);
R(RSP) += 8;
}
IMPL_END;
IMPL_START_0(enter)
{
writemem(ctx, rbp, rsp - 8, 8);
rbp = rsp - 8;
rsp -= (p1->val + 1) * 8;
writemem(ctx, R(RBP), R(RSP) - 8, 8);
R(RBP) = R(RSP) - 8;
R(RSP) -= (p1->val + 1) * 8;
}
IMPL_END;
IMPL_START_0(leave)
{
rsp = rbp + 8;
rbp = readmem(ctx, rbp, 8);
R(RSP) = R(RBP) + 8;
R(RBP) = readmem(ctx, R(RBP), 8);
}
IMPL_END;

View File

@ -6,7 +6,7 @@
//----------------------------------------------------------------------------//
#define STR_MOVE(reg, len) \
if ((flg & DF) == 0) \
if ((rfx & DF) == 0) \
R(reg) += len; \
else \
R(reg) -= len;
@ -52,7 +52,7 @@ static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
R(p1->reg) = readmem(ctx, R(p2->reg), len);
flg = (R(p1->reg) == 0 ? flg|ZF : flg&~ZF);
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
STR_MOVE(p2->reg, len);
}
@ -91,10 +91,10 @@ static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
COMPARE(x, v2);
if (x == 0) {
flg |= ZF;
R(RFX) |= ZF;
}
else if (!(flg&ZF)) {
else if (!(R(RFX)&ZF)) {
STR_MOVE(p1->reg, len);
}
}
@ -170,7 +170,7 @@ static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
COMPARE(x1, x2);
if (!x1 && !x2)
flg &= ~ZF;
R(RFX) &= ~ZF;
STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len);
@ -207,7 +207,7 @@ static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
ulong x = readmem(ctx, R(p2->reg), len);
writemem(ctx, x, R(p1->reg), len);
flg = (x == 0 ? flg|ZF : flg&~ZF);
R(RFX) = (x == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len);

View File

@ -14,7 +14,7 @@ IMPL_END;
IMPL_START_0(into)
{
if (flg & OF)
if (R(RFX) & OF)
_except(ctx, E_OVF, "INTO instruction with FLG.OF=1");
}
IMPL_END;
@ -25,7 +25,7 @@ IMPL_START_0(iret)
{
trace("\nReturning from exception #%ld\n\n", R(R11));
rip = R(R13);
R(RIP) = R(R13);
rfs_current_idx = R(R12);
ctx->rf = rfs[R(R12)];
}

View File

@ -58,6 +58,9 @@ struct ctx_t
// Instruction currently executing
instr_t *cur_in;
// Starting address of instruction currently executing
ulong cur_pc;
// Memory and memory size
ushort *mp;
ulong mz;
@ -65,14 +68,12 @@ struct ctx_t
// Read next instruction
ushort (*get)(ctx_t *ctx);
// Step by step
int step;
// Devices list head
dev_t *dh;
// Instructions executed so far
ulong ninstrs;
// Instructions executed
ulong ninstrs; // totally
ulong ni_thisfr; // this frame
// Last COND field
uint cond;

View File

@ -43,11 +43,11 @@ static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
return;
}
if (ctx->r[reg].flags & (RES | CTL))
if (ctx->r[reg].flags & RES)
//_except(ctx, E_ACC, "Reserved REG: %u", reg);
if (ctx->r[reg].flags & SYS)
if (cr0 & UF)
if (R(CR0) & UF)
_except(ctx, E_SYS, "User access to SYS REG: %u", reg);
}
@ -160,7 +160,7 @@ void decode(ctx_t *ctx)
ushort w1, w2;
uchar f1 = 0, f2 = 0, f3 = 0;
rpc = rip;
rpc = R(RIP);
//
// Process the first word of the instruction

View File

@ -91,7 +91,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
R(R10) = code;
R(R11) = effcode;
R(R12) = orig_frame;
R(R13) = rip;
R(R13) = R(RIP);
idt_handling[effcode]++;

View File

@ -15,25 +15,25 @@ bool eval_cond(ctx_t *ctx, uint cond)
{
case CD_NONE: ok = 1; break;
case CD_C: ok = flg&CF; break;
case CD_O: ok = flg&OF; break;
case CD_Z: ok = flg&ZF; break;
case CD_S: ok = flg&SF; break;
case CD_P: ok = flg&PF; break;
case CD_C: ok = rfx&CF; break;
case CD_O: ok = rfx&OF; break;
case CD_Z: ok = rfx&ZF; break;
case CD_S: ok = rfx&SF; break;
case CD_P: ok = rfx&PF; break;
case CD_A: ok = !(flg&CF || flg&ZF); break;
case CD_AE: ok = !(flg&CF); break;
case CD_A: ok = !(rfx&CF || rfx&ZF); break;
case CD_AE: ok = !(rfx&CF); break;
case CD_B: ok = flg&CF; break;
case CD_BE: ok = flg&CF || flg&ZF; break;
case CD_B: ok = rfx&CF; break;
case CD_BE: ok = rfx&CF || rfx&ZF; break;
case CD_G: ok = !(flg&ZF) && (!(flg&SF) == !(flg&OF)); break;
case CD_GE: ok = !(flg&SF) == !(flg&OF); break;
case CD_G: ok = !(rfx&ZF) && (!(rfx&SF) == !(rfx&OF)); break;
case CD_GE: ok = !(rfx&SF) == !(rfx&OF); break;
case CD_L: ok = !(flg&SF) != !(flg&OF); break;
case CD_LE: ok = flg&ZF || (!(flg&SF) != !(flg&OF)); break;
case CD_L: ok = !(rfx&SF) != !(rfx&OF); break;
case CD_LE: ok = rfx&ZF || (!(rfx&SF) != !(rfx&OF)); break;
case CD_CXZ: ok = !rcx; break;
case CD_CXZ: ok = !R(RCX); break;
default:
_except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
@ -80,7 +80,7 @@ do_rep:
#define OUTPUT(p, r) { \
if (p->type == A_REG) \
R(p->reg) = r1; \
R(p->reg) = r; \
else if (p1->type == A_IMM64) \
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
else { \
@ -102,10 +102,10 @@ do_rep:
if (!eval_cond(ctx, ctx->cond))
return;
if (rcx > 0)
rcx--;
if (R(RCX) > 0)
R(RCX)--;
if (rcx == 0)
if (R(RCX) == 0)
return;
// Should we really count REP's in instruction count?

View File

@ -13,19 +13,17 @@ static ushort *fwprog;
ushort bget(ctx_t *ctx)
{
ulong addr = rip + cr1;
ulong addr = R(RIP) + R(CR1);
if (addr2real(addr) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: "
"rip=0x%lX cr1=0x%lX",
rip, cr1);
R(RIP), R(RIP));
}
ushort c = ctx->mp[addr2real(addr)];
//log("bget 0x%lX: 0x%lX\n", addr, c);
rip += 2;
R(RIP) += 2;
return c;
}
@ -67,9 +65,6 @@ void main_loop(void)
decode(&main_ctx);
console_update(&main_ctx);
if (main_ctx.step)
getchar();
}
die(0);

View File

@ -129,7 +129,7 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
}
#define GETREAL() \
ulong real = addr2real(addr + cr2)
ulong real = addr2real(addr + R(CR2))
//----------------------------------------------------------------------------//

View File

@ -5,97 +5,50 @@
reg_t arch_r[] =
{
{ "inv", RES }, { "flg", GPR }, { "rip", GPR }, { "rpc", GPR },
{ "px0", RES }, { "px1", RES }, { "fc1", RES }, { "fc2", RES },
{ "sa0", SYS }, { "sa1", SYS }, { "sa2", SYS }, { "sa3", SYS },
{ "cr0", SYS }, { "cr1", SYS }, { "cr2", SYS }, { "cr3", SYS },
{ "inv", RES }, { "fc1", RES }, { "cr0", SYS }, { "cr1", SYS },
{ "cr2", SYS }, { "cr3", SYS }, { "cr4", SYS }, { "trp", GPR },
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
{ "rsi", GPR }, { "rdi", GPR }, { "rbp", GPR }, { "rsp", GPR },
{ "rx8", GPR }, { "rx9", GPR }, { "r10", GPR }, { "r11", GPR },
{ "rfx", GPR }, { "rip", GPR }, { "r10", GPR }, { "r11", GPR },
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
{ "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR },
{ "ax4", GPR }, { "ax5", GPR }, { "ax6", GPR }, { "ax7", GPR },
{ "ax8", GPR }, { "ax9", GPR }, { "a10", GPR }, { "a11", GPR },
{ "a12", GPR }, { "a13", GPR }, { "a14", GPR }, { "a15", GPR },
{ "nx0", GPR }, { "nx1", GPR }, { "nx2", GPR }, { "nx3", GPR },
{ "nx4", GPR }, { "nx5", GPR }, { "nx6", GPR }, { "nx7", GPR },
{ "nx8", GPR }, { "nx9", GPR }, { "n10", GPR }, { "n11", GPR },
{ "n12", GPR }, { "n13", GPR }, { "n14", GPR }, { "n15", GPR },
// { "dr0", SYS }, { "dr1", SYS }, { "dr2", SYS }, { "dr3", SYS },
// { "sa4", SYS }, { "sa5", SYS }, { "sa6", SYS }, { "sa7", SYS },
// { "dr4", SYS }, { "dr5", SYS }, { "dr6", SYS }, { "dr7", SYS },
// { "cr4", CTL }, { "cr5", CTL }, { "cr6", CTL }, { "cr7", CTL },
/*
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
{ "r20", GPR }, { "r21", GPR }, { "r22", GPR }, { "r23", GPR },
{ "r24", GPR }, { "r25", GPR }, { "r26", GPR }, { "r27", GPR },
{ "r28", GPR }, { "r29", GPR }, { "r30", GPR }, { "r31", GPR },
{ "a16", GPR }, { "a17", GPR }, { "a18", GPR }, { "a19", GPR },
{ "a20", GPR }, { "a21", GPR }, { "a22", GPR }, { "a23", GPR },
{ "a24", GPR }, { "a25", GPR }, { "a26", GPR }, { "a27", GPR },
{ "a28", GPR }, { "a29", GPR }, { "a30", GPR }, { "a31", GPR },
{ "n16", GPR }, { "n17", GPR }, { "n18", GPR }, { "n19", GPR },
{ "n20", GPR }, { "n21", GPR }, { "n22", GPR }, { "n23", GPR },
{ "n24", GPR }, { "n25", GPR }, { "n26", GPR }, { "n27", GPR },
{ "n28", GPR }, { "n29", GPR }, { "n30", GPR }, { "n31", GPR },
*/
};
static_assert(NREGS <= 256, "");
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
#define DUMPREGS(down, up) \
for (i = down; i <= up; i++) { \
if (i % 4 == 0) \
trace("\n"); \
r = &ctx->r[i]; \
trace("%s=0x%-16lX ", r->name, R(i)); \
} \
void dumpregs(ctx_t *ctx)
{
int i;
reg_t *r;
trace("Current RFRAME index: #%lu", rfs_current_idx);
trace("Current RFRAME index: #%lu\n", rfs_current_idx);
trace("\n\nEnviron:");
trace("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
trace("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
DUMPREGS(RAX, R15);
trace("\n\nControl:");
trace("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu", fc0, fc1, fc2);
trace("\n\nArgument:");
trace("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
trace("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
trace("\n\nVolatile:");
trace("\nrax=0x%-16lX rcx=0x%-16lX rdx=0x%-16lX", R(RAX), R(RCX), R(RDX));
trace("\nr10=0x%-16lX r11=0x%-16lX r12=0x%-16lX", R(R10), R(R11), R(R12));
trace("\nr13=0x%-16lX r14=0x%-16lX r15=0x%-16lX", R(R13), R(R14), R(R15));
trace("\n\nPersistent:");
trace("\nrbx=0x%-16lX rdi=0x%-16lX rsi=0x%-16lX", R(RBX), R(RDI), R(RSI));
trace("\nnx0=0x%-16lX nx1=0x%-16lX nx2=0x%-16lX", R(NX0), R(NX1), R(NX2));
trace("\nnx3=0x%-16lX nx4=0x%-16lX nx5=0x%-16lX", R(NX3), R(NX4), R(NX5));
trace("\n");
DUMPREGS(AX0, A15);
trace("\n");
DUMPREGS(NX0, N15);
trace("\n");
DUMPREGS(SA0, SA3);
DUMPREGS(CR0, CR3);
trace("\n\nrip=0x%-16lX rpc=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX",
rip, rpc, rsp, rbp);
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu flg=0x%-16lX\n",
fc0, fc1, fc2, flg);
/*
trace("\nCF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
!!(flg&CF), !!(flg&OF),
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(cr0&IF), !!(cr0&UF));
*/
assert(inv == 0);
assert(R(INV) == 0);
}

View File

@ -4,24 +4,22 @@
// Register types
enum
{
GPR = 1 << 0, // General
CTL = 1 << 1, // Control
SEG = 1 << 2, // Segment
RES = 1 << 8, // Reserved for insternal use
SYS = 1 << 9, // Reserved for supervisor mode
GPR = 0, // Non-reserved
RES = 1 << 0, // Reserved for insternal use
SYS = 1 << 1, // Reserved for supervisor mode
};
// FLG register
enum
{
CF = 1 << 0, // Carry flag
OF = 1 << 1, // Overflow flag
ZF = 1 << 0, // Zero flag
SF = 1 << 1, // Sign flag
ZF = 1 << 2, // Zero flag
SF = 1 << 3, // Sign flag
CF = 1 << 4, // Carry flag
OF = 1 << 5, // Overflow flag
PF = 1 << 4, // Parity flag
DF = 1 << 5, // Direction flag
PF = 1 << 8, // Parity flag
DF = 1 << 9, // Direction flag
};
// CR0 register
@ -39,53 +37,25 @@ struct reg_t
enum
{
INV, FLG, RIP, RPC, PX0, PX1, FC1, FC2,
SA0, SA1, SA2, SA3, // SA4, SA5, SA6, SA7,
CR0, CR1, CR2, CR3, // CR4, CR5, CR6, CR7,
INV, FC1, CR0, CR1, CR2, CR3, CR4, TRP,
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
RX8, RX9, R10, R11, R12, R13, R14, R15,
RFX, RIP, R10, R11, R12, R13, R14, R15,
AX0, AX1, AX2, AX3, AX4, AX5, AX6, AX7,
AX8, AX9, A10, A11, A12, A13, A14, A15,
NX0, NX1, NX2, NX3, NX4, NX5, NX6, NX7,
NX8, NX9, N10, N11, N12, N13, N14, N15,
// DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR7,
// R16, R17, R18, R19, R20, R21, R22, R23,
// R24, R25, R26, R27, R28, R29, R30, R31,
// A16, A17, A18, A19, A20, A21, A22, A23,
// A24, A25, A26, A27, A28, A29, A30, A31,
// N16, N17, N18, N19, N20, N21, N22, N23,
// N24, N25, N26, N27, N28, N29, N30, N31,
NREGS
};
#define fc0 ctx->ninstrs
#define fc2 ctx->ni_thisfr
#define rpc ctx->cur_pc
#define inv R(INV)
#define rip R(RIP)
#define rpc R(RPC)
#define flg R(FLG)
#define fc1 R(FC1)
#define fc2 R(FC2)
#define cr0 R(CR0)
#define cr1 R(CR1)
#define cr2 R(CR2)
#define rfx R(RFX)
#define rax R(RAX)
#define rbx R(RBX)
#define rcx R(RCX)
#define rdx R(RDX)
#define rsi R(RSI)
#define rdi R(RDI)
#define rbp R(RBP)
#define rsp R(RSP)
#define ax0 R(AX0)
#define ax1 R(AX1)
#define ax2 R(AX2)
#define ax3 R(AX3)