mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
vm
This commit is contained in:
parent
06345cfa78
commit
e1299836de
20
as/regs.lst
20
as/regs.lst
@ -1,4 +1,4 @@
|
||||
rzx zero
|
||||
rzx zr zero
|
||||
cr0 c0
|
||||
cr1 c1
|
||||
cr2 c2
|
||||
@ -20,15 +20,15 @@ ax3 a3 r9
|
||||
ax4 a4 r10
|
||||
ax5 a5 r11
|
||||
|
||||
r12
|
||||
r13
|
||||
r14
|
||||
r15
|
||||
r16
|
||||
r17
|
||||
r18
|
||||
r19
|
||||
r20
|
||||
nx0 n0 r12
|
||||
nx1 n1 r13
|
||||
nx2 n2 r14
|
||||
nx3 n3 r15
|
||||
nx4 n4 r16
|
||||
nx5 n5 r17
|
||||
nx6 n6 r18
|
||||
nx7 n7 r19
|
||||
nx8 n8 r20
|
||||
grp gp
|
||||
trp tp
|
||||
srp sp
|
||||
|
@ -169,7 +169,7 @@ doprnt:
|
||||
cmp r15, zero
|
||||
ret.z
|
||||
|
||||
; if n>0, decrement n and print
|
||||
; decrement n and print
|
||||
dec r15, 1
|
||||
call r17
|
||||
|
||||
|
@ -41,7 +41,7 @@ print:
|
||||
;
|
||||
; Print exactly ax1 characters
|
||||
;
|
||||
print_n:
|
||||
nprint:
|
||||
mov rcx, ax1
|
||||
b.z b[ax0], zero, .1
|
||||
prns.rep.nz ax0
|
||||
|
@ -59,7 +59,7 @@ builtins.dir:
|
||||
prn ' '
|
||||
|
||||
cmp b[rsi], '.'
|
||||
add.z rsi, rsi, 1
|
||||
inc.z rsi, 1
|
||||
|
||||
.print_ext.1:
|
||||
b.z b[rsi], 0, .print_ext.2
|
||||
|
@ -183,7 +183,6 @@ main:
|
||||
push w[rax+6]
|
||||
|
||||
call printf, .datefmt
|
||||
|
||||
inc rsp, 40
|
||||
|
||||
jmp .print_prompt
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long clockdev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
long clockdev_poweron(dev_t *dev)
|
||||
{
|
||||
dev->state = DEVGOOD;
|
||||
|
||||
|
@ -17,35 +17,35 @@ size_t rfs_current_idx = 0;
|
||||
|
||||
#define CHK_INDEX(idx) \
|
||||
if ((size_t)idx > MAX_RFRAME_IDX) \
|
||||
_except(ctx, E_UDF, "cpudev: invalid rframe index: #%u", idx);
|
||||
_except(E_UDF, "cpudev: invalid rframe index: #%u", idx);
|
||||
|
||||
#define CHK_FRAME(idx) \
|
||||
CHK_INDEX(idx); \
|
||||
if (rfs[idx] == NULL) \
|
||||
_except(ctx, E_UDF, \
|
||||
_except(E_UDF, \
|
||||
"cpudev: operation on inactive reframe #%u", idx);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long cpudev_getmaxidx(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_getmaxidx(dev_t *dev)
|
||||
{
|
||||
R(RAX) = MAX_RFRAME_IDX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_getrfusage(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_getrfusage(dev_t *dev)
|
||||
{
|
||||
R(RAX) = rfs_used;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_getcuridx(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_getcuridx(dev_t *dev)
|
||||
{
|
||||
R(RAX) = rfs_current_idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_leastavail(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_leastavail(dev_t *dev)
|
||||
{
|
||||
size_t it;
|
||||
|
||||
@ -64,7 +64,7 @@ long cpudev_leastavail(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long cpudev_isactive(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_isactive(dev_t *dev)
|
||||
{
|
||||
CHK_INDEX(R(AX0));
|
||||
|
||||
@ -73,12 +73,12 @@ long cpudev_isactive(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_activate(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_activate(dev_t *dev)
|
||||
{
|
||||
CHK_INDEX(R(AX0));
|
||||
|
||||
if (rfs[R(AX0)] != NULL)
|
||||
_except(ctx, E_UDF,
|
||||
_except(E_UDF,
|
||||
"cpudev: activating already activated rframe: #%u", R(AX0));
|
||||
|
||||
rfs[R(AX0)] = calloc(NREGS, sizeof(ulong));
|
||||
@ -91,12 +91,12 @@ long cpudev_activate(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_deactivate(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_deactivate(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
|
||||
if (R(AX0) == 0)
|
||||
_except(ctx, E_UDF, "cpudev: deactivating rframe #0");
|
||||
_except(E_UDF, "cpudev: deactivating rframe #0");
|
||||
|
||||
free(rfs[R(AX0)]);
|
||||
rfs[R(AX0)] = NULL;
|
||||
@ -109,7 +109,7 @@ long cpudev_deactivate(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long cpudev_copyframe(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_copyframe(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
CHK_FRAME(R(AX1));
|
||||
@ -122,16 +122,16 @@ long cpudev_copyframe(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_moveframe(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_moveframe(dev_t *dev)
|
||||
{
|
||||
CHK_INDEX(R(AX0));
|
||||
CHK_FRAME(R(AX1));
|
||||
|
||||
if (R(AX1) == 0)
|
||||
_except(ctx, E_UDF, "cpudev: trying to move frame #0");
|
||||
_except(E_UDF, "cpudev: trying to move frame #0");
|
||||
|
||||
if (rfs[R(AX0)] != NULL)
|
||||
_except(ctx, E_UDF, "cpudev: trying to move frame #%u "
|
||||
_except(E_UDF, "cpudev: trying to move frame #%u "
|
||||
"active frame #%u", R(AX1), R(AX0));
|
||||
|
||||
rfs[R(AX0)] = rfs[R(AX1)];
|
||||
@ -140,7 +140,7 @@ long cpudev_moveframe(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_switchframe(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_switchframe(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
|
||||
@ -152,7 +152,7 @@ long cpudev_switchframe(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long cpudev_loadargs(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_loadargs(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
|
||||
@ -166,12 +166,12 @@ long cpudev_loadargs(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
|
||||
}
|
||||
long cpudev_loadreg(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_loadreg(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
|
||||
if ((ushort)R(AX1) >= NREGS || R(AX1) == RZX)
|
||||
_except(ctx, E_UDF,
|
||||
_except(E_UDF,
|
||||
"cpudev: register invalid or index out of range: #%u", R(AX1));
|
||||
|
||||
R(RAX) = rfs[R(AX0)][R(AX1)];
|
||||
@ -179,12 +179,12 @@ long cpudev_loadreg(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_storereg(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_storereg(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX0));
|
||||
|
||||
if ((ushort)R(AX1) >= NREGS)
|
||||
_except(ctx, E_UDF, "cpudev: register index out of range: #%u", R(AX1));
|
||||
_except(E_UDF, "cpudev: register index out of range: #%u", R(AX1));
|
||||
|
||||
rfs[R(AX0)][R(AX1)] = R(AX2);
|
||||
|
||||
@ -195,20 +195,20 @@ long cpudev_storereg(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
#define CHK_IDT_INDEX(idx) \
|
||||
if ((ulong)idx >= IDT_SLOTS) \
|
||||
_except(ctx, E_UDF, "cpudev: invalid IDT slot index: #%u", idx);
|
||||
_except(E_UDF, "cpudev: invalid IDT slot index: #%u", idx);
|
||||
|
||||
/* except.h */
|
||||
ulong idt[IDT_SLOTS] = { 0 };
|
||||
bool idt_masked[IDT_SLOTS] = { 0 }; // deliberately masked by software
|
||||
bool idt_handling[IDT_SLOTS] = { 0 }; // a handler is already running
|
||||
|
||||
long cpudev_idtadd(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_idtadd(dev_t *dev)
|
||||
{
|
||||
CHK_FRAME(R(AX1));
|
||||
CHK_IDT_INDEX(R(AX0));
|
||||
|
||||
if (idt[R(AX0)] != 0)
|
||||
_except(ctx, E_UDF, "cpudev: IDT slot index already in use: #%u", R(AX0));
|
||||
_except(E_UDF, "cpudev: IDT slot index already in use: #%u", R(AX0));
|
||||
|
||||
assert(idt_handling[R(AX0)] == 0);
|
||||
|
||||
@ -217,12 +217,12 @@ long cpudev_idtadd(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_idtdel(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_idtdel(dev_t *dev)
|
||||
{
|
||||
CHK_IDT_INDEX(R(AX0));
|
||||
|
||||
if (idt[R(AX0)] == 0)
|
||||
_except(ctx, E_UDF, "cpudev: IDT slot index not in use: #%u", R(AX0));
|
||||
_except(E_UDF, "cpudev: IDT slot index not in use: #%u", R(AX0));
|
||||
|
||||
idt[R(AX0)] = 0;
|
||||
idt_handling[R(AX0)] = 0;
|
||||
@ -230,7 +230,7 @@ long cpudev_idtdel(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_idtquery(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_idtquery(dev_t *dev)
|
||||
{
|
||||
if (R(AX0) >= IDT_SLOTS || idt[R(AX0)] == 0)
|
||||
R(RAX) = R(RDX) = 0;
|
||||
@ -243,12 +243,12 @@ long cpudev_idtquery(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_idtdone(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_idtdone(dev_t *dev)
|
||||
{
|
||||
CHK_IDT_INDEX(R(AX0));
|
||||
|
||||
if (idt_handling[R(AX0)] == 0)
|
||||
_except(ctx, E_UDF, "cpudev: idtdone, not handling E/I #%u", R(AX0));
|
||||
_except(E_UDF, "cpudev: idtdone, not handling E/I #%u", R(AX0));
|
||||
|
||||
idt_handling[R(AX0)]--;
|
||||
|
||||
@ -257,7 +257,7 @@ long cpudev_idtdone(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long cpudev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_poweron(dev_t *dev)
|
||||
{
|
||||
rfs = calloc(MAX_RFRAME_IDX + 2, sizeof(reg_t *));
|
||||
|
||||
@ -292,7 +292,7 @@ long cpudev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cpudev_poweroff(ctx_t *ctx, dev_t *dev)
|
||||
long cpudev_poweroff(dev_t *dev)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
@ -28,7 +28,7 @@ struct disk_t
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long diskdev_findnext(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_findnext(dev_t *dev)
|
||||
{
|
||||
struct stat st;
|
||||
char name[NAME_MAX+4];
|
||||
@ -51,7 +51,7 @@ long diskdev_findnext(ctx_t *ctx, dev_t *dev)
|
||||
break;
|
||||
}
|
||||
|
||||
R(RAX) = writestr(ctx, R(AX0), R(AX1), ent->d_name);
|
||||
R(RAX) = writestr(R(AX0), R(AX1), ent->d_name);
|
||||
|
||||
snprintf(name, NAME_MAX+4, "fs/%s", ent->d_name);
|
||||
|
||||
@ -67,25 +67,25 @@ long diskdev_findnext(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long diskdev_findfirst(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_findfirst(dev_t *dev)
|
||||
{
|
||||
GETDISK();
|
||||
|
||||
rewinddir(disk->dir);
|
||||
|
||||
return diskdev_findnext(ctx, dev);
|
||||
return diskdev_findnext(dev);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long diskdev_open(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_open(dev_t *dev)
|
||||
{
|
||||
GETDISK();
|
||||
|
||||
int fd, tmp;
|
||||
char buf[NAME_MAX+4] = { 'f', 's', '/', 0 };
|
||||
|
||||
readstr(ctx, R(AX0), NAME_MAX, buf+3);
|
||||
readstr(R(AX0), NAME_MAX, buf+3);
|
||||
|
||||
for (fd = 0; fd < MAXOPEN; fd++)
|
||||
if (disk->table[fd] == 0)
|
||||
@ -108,7 +108,7 @@ long diskdev_open(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long diskdev_close(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_close(dev_t *dev)
|
||||
{
|
||||
GETDISK();
|
||||
|
||||
@ -125,7 +125,7 @@ long diskdev_close(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long diskdev_read(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_read(dev_t *dev)
|
||||
{
|
||||
GETDISK();
|
||||
|
||||
@ -150,13 +150,13 @@ long diskdev_read(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
// Xxx dedicated function & faster copy
|
||||
for (; ret; ret--, R(AX1)++, buf++)
|
||||
writemem(ctx, *buf, R(AX1), 1);
|
||||
writemem(*buf, R(AX1), 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long diskdev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_poweron(dev_t *dev)
|
||||
{
|
||||
disk_t *disk = calloc(1, sizeof(disk_t));
|
||||
|
||||
@ -183,7 +183,7 @@ long diskdev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long diskdev_poweroff(ctx_t *ctx, dev_t *dev)
|
||||
long diskdev_poweroff(dev_t *dev)
|
||||
{
|
||||
GETDISK();
|
||||
int fd;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
long keybdev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
long keybdev_poweron(dev_t *dev)
|
||||
{
|
||||
dev->state = DEVGOOD;
|
||||
|
||||
|
@ -3,21 +3,21 @@
|
||||
|
||||
#include <pc/device.h>
|
||||
|
||||
long memdev_getmemoff(ctx_t *ctx, dev_t *dev)
|
||||
long memdev_getmemoff(dev_t *dev)
|
||||
{
|
||||
R(RAX) = MEMOFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long memdev_getmemsize(ctx_t *ctx, dev_t *dev)
|
||||
long memdev_getmemsize(dev_t *dev)
|
||||
{
|
||||
R(RAX) = ctx->mz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long memdev_poweron(ctx_t *ctx, dev_t *dev)
|
||||
long memdev_poweron(dev_t *dev)
|
||||
{
|
||||
dev->fslots[0] = memdev_getmemoff;
|
||||
dev->fslots[1] = memdev_getmemsize;
|
||||
|
@ -64,7 +64,7 @@ IMPL_START(div)
|
||||
SRCP(p3);
|
||||
|
||||
if (!p3->val)
|
||||
_except(ctx, E_DIV, "DIV by 0");
|
||||
_except(E_DIV, "DIV by 0");
|
||||
*r1 = p2->val / p3->val;
|
||||
|
||||
return 1;
|
||||
@ -76,7 +76,7 @@ IMPL_START(idiv)
|
||||
SRCP(p3);
|
||||
|
||||
if (!p3->val)
|
||||
_except(ctx, E_DIV, "IDIV by 0");
|
||||
_except(E_DIV, "IDIV by 0");
|
||||
|
||||
*r1 = (ulong)((long)p2->val/(long)p3->val);
|
||||
|
||||
|
@ -54,7 +54,7 @@ def parse_2(fp):
|
||||
.format(deprecated, tok[0], n, tok[0]))
|
||||
hd.write("#else\n")
|
||||
hd.write("#define I_{} {}\n".format(tok[0].upper(), count))
|
||||
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
|
||||
hd.write("extern bool i_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
|
||||
.format(tok[0]))
|
||||
hd.write("#endif\n\n")
|
||||
|
||||
|
@ -6,22 +6,22 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define IMPL_START(name) \
|
||||
uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
|
||||
uint i_##name(acc_t *p1, acc_t *p2, acc_t *p3, \
|
||||
ulong *r1, ulong *r2, ulong *r3) \
|
||||
|
||||
#define XSRCP(v, p, x) \
|
||||
if (ACC_FMT_IS_MEM(p->type)) \
|
||||
v = readmem##x(ctx, p->addr, p->mlen); \
|
||||
v = readmem##x(p->addr, p->mlen); \
|
||||
else v = p->val; \
|
||||
|
||||
#define SRCP(p) \
|
||||
if (__builtin_expect(ACC_FMT_IS_MEM(p->type), 0)) \
|
||||
p->val = readmemsx(ctx, p->addr, p->mlen); \
|
||||
p->val = readmemsx(p->addr, p->mlen); \
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define INTO() \
|
||||
if (R(RFX) & OF) _except(ctx, E_OVF, "Overflow");
|
||||
if (R(RFX) & OF) _except(E_OVF, "Overflow");
|
||||
|
||||
#define PARITY(v) __builtin_parity(v)
|
||||
|
||||
@ -69,7 +69,7 @@ uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
|
||||
#define CHK_SUPERV() \
|
||||
do { \
|
||||
if ((R(CR0) & UF) > 0) { \
|
||||
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
|
||||
_except(E_SYS, "Supervisor-only INSTR"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
18
vm/in/mem.c
18
vm/in/mem.c
@ -22,7 +22,7 @@ IMPL_START(b)
|
||||
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
if (eval_cond(ctx, ctx->cond))
|
||||
if (eval_cond(ctx->cond))
|
||||
R(RIP) = p3->val;
|
||||
|
||||
return 0;
|
||||
@ -69,14 +69,14 @@ IMPL_START(push)
|
||||
XSRCP(p1->val, p1, zx);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, p1->val, R(RSP), 8);
|
||||
writemem(p1->val, R(RSP), 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(pop)
|
||||
{
|
||||
*r1 = readmemzx(ctx, R(RSP), 8);
|
||||
*r1 = readmemzx(R(RSP), 8);
|
||||
R(RSP) += 8;
|
||||
|
||||
return 1;
|
||||
@ -87,7 +87,7 @@ IMPL_START(call)
|
||||
SRCP(p1);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
writemem(R(RIP), R(RSP), 8);
|
||||
R(RIP) = p1->val;
|
||||
|
||||
return 0;
|
||||
@ -99,7 +99,7 @@ IMPL_START(xcall2)
|
||||
SRCP(p2);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
writemem(R(RIP), R(RSP), 8);
|
||||
|
||||
R(RIP) = p1->val;
|
||||
R(AX0) = p2->val;
|
||||
@ -114,7 +114,7 @@ IMPL_START(xcall3)
|
||||
SRCP(p3);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
writemem(R(RIP), R(RSP), 8);
|
||||
|
||||
R(RIP) = p1->val;
|
||||
R(AX0) = p2->val;
|
||||
@ -125,7 +125,7 @@ IMPL_START(xcall3)
|
||||
|
||||
IMPL_START(ret)
|
||||
{
|
||||
R(RIP) = readmemzx(ctx, R(RSP), 8);
|
||||
R(RIP) = readmemzx(R(RSP), 8);
|
||||
R(RSP) += 8;
|
||||
|
||||
return 0;
|
||||
@ -133,7 +133,7 @@ IMPL_START(ret)
|
||||
|
||||
IMPL_START(enter)
|
||||
{
|
||||
writemem(ctx, R(RBP), R(RSP) - 8, 8);
|
||||
writemem(R(RBP), R(RSP) - 8, 8);
|
||||
R(RBP) = R(RSP) - 8;
|
||||
R(RSP) -= (p1->val + 1) * 8;
|
||||
|
||||
@ -143,7 +143,7 @@ IMPL_START(enter)
|
||||
IMPL_START(leave)
|
||||
{
|
||||
R(RSP) = R(RBP) + 8;
|
||||
R(RBP) = readmemzx(ctx, R(RBP), 8);
|
||||
R(RBP) = readmemzx(R(RBP), 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
18
vm/in/misc.c
18
vm/in/misc.c
@ -18,9 +18,9 @@ IMPL_START(break)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
trace("\nExecuting BREAK INSTR\n");
|
||||
dumpregs(ctx);
|
||||
dumpregs();
|
||||
|
||||
do_hlt(ctx);
|
||||
do_hlt();
|
||||
|
||||
trace("Resuming execution\n");
|
||||
#endif
|
||||
@ -34,7 +34,7 @@ IMPL_START(dump)
|
||||
trace("0x%lX:\t...\n", ctx->cur_pc);
|
||||
|
||||
else if (!ctx->dumpsw)
|
||||
dump_instr(ctx, ctx->cur_in, p1, p2, p3, 0, 0);
|
||||
dump_instr(ctx->cur_in, p1, p2, p3, 0, 0);
|
||||
|
||||
ctx->dumpsw = !ctx->dumpsw;
|
||||
#endif
|
||||
@ -133,10 +133,10 @@ IMPL_START(prn)
|
||||
|
||||
// Magic value? :)
|
||||
if (__builtin_expect(v == PRN_CLEAR_MAGIC, 0))
|
||||
console_clear(ctx);
|
||||
console_clear();
|
||||
|
||||
else if (v > 0)
|
||||
console_putc(ctx, (char)v);
|
||||
console_putc((char)v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -144,15 +144,15 @@ IMPL_START(prn)
|
||||
IMPL_START(prns)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "PRNS given a non-REG operand");
|
||||
_except(E_ILL, "PRNS given a non-REG operand");
|
||||
|
||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||
uchar ch = readmemzx(R(p1->reg), 1);
|
||||
|
||||
COMPARE_SUB(ch, 0);
|
||||
|
||||
if ((R(RFX) & ZF) == 0)
|
||||
{
|
||||
console_putc(ctx, ch);
|
||||
console_putc(ch);
|
||||
|
||||
if (R(RFX) & DF)
|
||||
R(p1->reg)--;
|
||||
@ -165,7 +165,7 @@ IMPL_START(prns)
|
||||
|
||||
IMPL_START(scan)
|
||||
{
|
||||
*r1 = console_scankeybuf(ctx);
|
||||
*r1 = console_scankeybuf();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -11,28 +11,28 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
static void stos_impl(acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "STOSX given a non-REG operand");
|
||||
_except(E_ILL, "STOSX given a non-REG operand");
|
||||
|
||||
writemem(ctx, p2->val, R(p1->reg), len);
|
||||
writemem(p2->val, R(p1->reg), len);
|
||||
STR_MOVE(p1->reg, len);
|
||||
}
|
||||
|
||||
IMPL_START(stosb) { stos_impl(ctx, p1, p2, 1); return 0; }
|
||||
IMPL_START(stosw) { stos_impl(ctx, p1, p2, 2); return 0; }
|
||||
IMPL_START(stosd) { stos_impl(ctx, p1, p2, 4); return 0; }
|
||||
IMPL_START(stosq) { stos_impl(ctx, p1, p2, 8); return 0; }
|
||||
IMPL_START(stosb) { stos_impl(p1, p2, 1); return 0; }
|
||||
IMPL_START(stosw) { stos_impl(p1, p2, 2); return 0; }
|
||||
IMPL_START(stosd) { stos_impl(p1, p2, 4); return 0; }
|
||||
IMPL_START(stosq) { stos_impl(p1, p2, 8); return 0; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
static void scas_impl(acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "SCASX given a non-REG operand");
|
||||
_except(E_ILL, "SCASX given a non-REG operand");
|
||||
|
||||
ulong x = readmemsx(ctx, R(p1->reg), len);
|
||||
ulong x = readmemsx(R(p1->reg), len);
|
||||
COMPARE_SUB(x, p2->val);
|
||||
|
||||
if (x == 0) {
|
||||
@ -44,10 +44,10 @@ static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
}
|
||||
}
|
||||
|
||||
IMPL_START(scasb) { scas_impl(ctx, p1, p2, 1); return 0; }
|
||||
IMPL_START(scasw) { scas_impl(ctx, p1, p2, 2); return 0; }
|
||||
IMPL_START(scasd) { scas_impl(ctx, p1, p2, 4); return 0; }
|
||||
IMPL_START(scasq) { scas_impl(ctx, p1, p2, 8); return 0; }
|
||||
IMPL_START(scasb) { scas_impl(p1, p2, 1); return 0; }
|
||||
IMPL_START(scasw) { scas_impl(p1, p2, 2); return 0; }
|
||||
IMPL_START(scasd) { scas_impl(p1, p2, 4); return 0; }
|
||||
IMPL_START(scasq) { scas_impl(p1, p2, 8); return 0; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void do_hlt(ctx_t *ctx)
|
||||
void do_hlt()
|
||||
{
|
||||
SDL_Event evt;
|
||||
|
||||
@ -21,7 +21,7 @@ void do_hlt(ctx_t *ctx)
|
||||
|
||||
if (evt.type == SDL_KEYDOWN)
|
||||
{
|
||||
console_handle_input(ctx, evt.key.keysym.sym);
|
||||
console_handle_input(evt.key.keysym.sym);
|
||||
if (evt.key.keysym.sym == SDLK_RETURN)
|
||||
break;
|
||||
}
|
||||
@ -31,16 +31,16 @@ void do_hlt(ctx_t *ctx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(hlt) { CHK_SUPERV(); do_hlt(ctx); return 0; }
|
||||
IMPL_START(stop) { CHK_SUPERV(); _except(ctx, E_SHT, "STOP INSTR"); }
|
||||
IMPL_START(crash) { CHK_SUPERV(); _except(ctx, 1023, "CRASH instruction"); }
|
||||
IMPL_START(hlt) { CHK_SUPERV(); do_hlt(); return 0; }
|
||||
IMPL_START(stop) { CHK_SUPERV(); _except(E_SHT, "STOP INSTR"); }
|
||||
IMPL_START(crash) { CHK_SUPERV(); _except(1023, "CRASH instruction"); }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(trap)
|
||||
{
|
||||
if (p1->val > 255) _except(ctx, E_ILL, "TRAP number greater than 255");
|
||||
_except(ctx, p1->val + 256, "TRAP instruction");
|
||||
if (p1->val > 255) _except(E_ILL, "TRAP number greater than 255");
|
||||
_except(p1->val + 256, "TRAP instruction");
|
||||
}
|
||||
|
||||
|
||||
@ -64,9 +64,9 @@ IMPL_START(sti) { CHK_SUPERV(); R(CR0) |= IF; return 0; }
|
||||
//
|
||||
// code common to devctl and iocall
|
||||
//
|
||||
dev_t *devctl_common(ctx_t *ctx, ulong idx)
|
||||
dev_t *devctl_common(ulong idx)
|
||||
{
|
||||
dev_t *dev = devget(ctx, idx);
|
||||
dev_t *dev = devget(idx);
|
||||
|
||||
if (!dev) R(RAX) = -2;
|
||||
else if (dev->state == DEVPWOF) R(RAX) = -3;
|
||||
@ -80,16 +80,16 @@ IMPL_START(devctl)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
|
||||
dev_t *dev = devctl_common(ctx, p1->val);
|
||||
dev_t *dev = devctl_common(p1->val);
|
||||
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
switch (p2->val) {
|
||||
case 0: writestr(ctx, R(AX0), DEVLEN, dev->type); break;
|
||||
case 1: writestr(ctx, R(AX0), DEVLEN, dev->name); break;
|
||||
case 2: writestr(ctx, R(AX0), DEVLEN, dev->modl); break;
|
||||
case 3: writestr(ctx, R(AX0), DEVLEN, dev->vend); break;
|
||||
case 0: writestr(R(AX0), DEVLEN, dev->type); break;
|
||||
case 1: writestr(R(AX0), DEVLEN, dev->name); break;
|
||||
case 2: writestr(R(AX0), DEVLEN, dev->modl); break;
|
||||
case 3: writestr(R(AX0), DEVLEN, dev->vend); break;
|
||||
case 4: R(RAX) = dev->major; R(RDX) = dev->minor; break;
|
||||
case 5: R(RAX) = dev->feats; R(RDX) = dev->revis; break;
|
||||
default: R(RAX) = -6; break;
|
||||
@ -103,13 +103,13 @@ IMPL_START(iocall)
|
||||
CHK_SUPERV();
|
||||
|
||||
long rc;
|
||||
dev_t *dev = devctl_common(ctx, p1->val);
|
||||
dev_t *dev = devctl_common(p1->val);
|
||||
|
||||
if (dev == NULL) return 0;
|
||||
else if (p2->val >= DEVSLOTS || dev->fslots[p2->val] == NULL) R(RAX) = -6;
|
||||
|
||||
else {
|
||||
rc = dev->fslots[p2->val](ctx, dev);
|
||||
rc = dev->fslots[p2->val](dev);
|
||||
if (rc < 0) { R(RAX) = rc; R(RDX) = 0; }
|
||||
}
|
||||
|
||||
|
14
vm/pc/arch.h
14
vm/pc/arch.h
@ -79,20 +79,23 @@ struct ctx_t
|
||||
bool dumpsw;
|
||||
};
|
||||
|
||||
#define ctx (&main_ctx)
|
||||
extern ctx_t main_ctx;
|
||||
|
||||
#define R(X) ctx->rf[X]
|
||||
|
||||
void die(int code) __attribute__((__noreturn__));
|
||||
|
||||
void dumpregs(ctx_t *);
|
||||
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
|
||||
void dumpmem(ctx_t *, ulong, ulong);
|
||||
void dumpregs(void);
|
||||
void dumpinstr(ulong, uint, ushort, acc_t *, acc_t *);
|
||||
void dumpmem(ulong, ulong);
|
||||
|
||||
void decode(ctx_t *ctx);
|
||||
void decode(void);
|
||||
|
||||
void enable_stdin_echoing(void);
|
||||
void disable_stdin_echoing(void);
|
||||
|
||||
extern void do_hlt(ctx_t *ctx);
|
||||
extern void do_hlt(void);
|
||||
|
||||
#include <pc/mem.h>
|
||||
#include <pc/sym.h>
|
||||
@ -101,7 +104,6 @@ extern void do_hlt(ctx_t *ctx);
|
||||
#include <pc/except.h>
|
||||
#include <ob/arch_i.h>
|
||||
|
||||
extern ctx_t main_ctx;
|
||||
extern reg_t arch_r[NREGS];
|
||||
extern instr_t arch_i[NINSTRS];
|
||||
|
||||
|
@ -36,7 +36,7 @@ int csn_y = 0;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_init(ctx_t *ctx)
|
||||
void console_init(void)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
|
||||
{
|
||||
@ -79,7 +79,7 @@ void console_init(ctx_t *ctx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_exit(ctx_t *ctx)
|
||||
void console_exit(void)
|
||||
{
|
||||
size_t y;
|
||||
|
||||
@ -104,7 +104,7 @@ void console_exit(ctx_t *ctx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_render(ctx_t *ctx)
|
||||
void console_render(void)
|
||||
{
|
||||
size_t y;
|
||||
|
||||
@ -120,7 +120,7 @@ void console_render(ctx_t *ctx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_update(ctx_t *ctx)
|
||||
void console_update(void)
|
||||
{
|
||||
SDL_Event evt;
|
||||
|
||||
@ -133,7 +133,7 @@ void console_update(ctx_t *ctx)
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
console_handle_input(ctx, evt.key.keysym.sym);
|
||||
console_handle_input(evt.key.keysym.sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -141,19 +141,19 @@ void console_update(ctx_t *ctx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_clear(ctx_t *ctx)
|
||||
void console_clear(void)
|
||||
{
|
||||
csn_y = CONSOLE_HEIGHT - 1;
|
||||
|
||||
for (int i = 0; i < CONSOLE_HEIGHT; i++)
|
||||
console_putc(ctx, '\n');
|
||||
console_putc('\n');
|
||||
|
||||
csn_x = csn_y = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_putat(ctx_t *ctx, char ch, int x, int y)
|
||||
void console_putat(char ch, int x, int y)
|
||||
{
|
||||
SDL_Surface *surf;
|
||||
|
||||
@ -213,12 +213,12 @@ void console_putat(ctx_t *ctx, char ch, int x, int y)
|
||||
|
||||
SDL_FreeSurface(surf);
|
||||
|
||||
console_render(ctx);
|
||||
console_render();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void console_putc(ctx_t *ctx, char ch)
|
||||
void console_putc(char ch)
|
||||
{
|
||||
size_t y;
|
||||
|
||||
@ -237,11 +237,11 @@ void console_putc(ctx_t *ctx, char ch)
|
||||
return;
|
||||
|
||||
csn_x--;
|
||||
console_putat(ctx, ' ', csn_x, csn_y);
|
||||
console_putat(' ', csn_x, csn_y);
|
||||
break;
|
||||
|
||||
default:
|
||||
console_putat(ctx, ch, csn_x, csn_y);
|
||||
console_putat(ch, csn_x, csn_y);
|
||||
csn_x++;
|
||||
break;
|
||||
}
|
||||
@ -289,7 +289,7 @@ void console_putc(ctx_t *ctx, char ch)
|
||||
scr_rects[y]->y -= _SURF_H; // surf->h
|
||||
}
|
||||
|
||||
console_render(ctx);
|
||||
console_render();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,15 +7,15 @@
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
#include <pc/keybd.h>
|
||||
|
||||
void console_init(ctx_t *ctx);
|
||||
void console_exit(ctx_t *ctx);
|
||||
void console_init(void);
|
||||
void console_exit(void);
|
||||
|
||||
void console_render(ctx_t *ctx);
|
||||
void console_putat(ctx_t *ctx, char ch, int x, int y);
|
||||
void console_putc(ctx_t *ctx, char ch);
|
||||
void console_update(ctx_t *ctx);
|
||||
void console_render(void);
|
||||
void console_putat(char ch, int x, int y);
|
||||
void console_putc(char ch);
|
||||
void console_update(void);
|
||||
|
||||
void console_clear(ctx_t *ctx);
|
||||
void console_clear(void);
|
||||
|
||||
void console_handle_input(ctx_t *, SDL_Keycode);
|
||||
void console_handle_input(SDL_Keycode);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// Instruction fetch
|
||||
//
|
||||
|
||||
static uchar fetchb(ctx_t *ctx)
|
||||
static uchar fetchb(void)
|
||||
{
|
||||
uchar v = *(ctx->mp + R(RIP) + R(CR1) - MEMOFF);
|
||||
R(RIP) += 1;
|
||||
@ -19,7 +19,7 @@ static uchar fetchb(ctx_t *ctx)
|
||||
return v;
|
||||
}
|
||||
|
||||
static ushort fetchw(ctx_t *ctx)
|
||||
static ushort fetchw(void)
|
||||
{
|
||||
ushort v = *(ushort *)(ctx->mp + R(RIP) + R(CR1) - MEMOFF);
|
||||
R(RIP) += 2;
|
||||
@ -27,7 +27,7 @@ static ushort fetchw(ctx_t *ctx)
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint fetchd(ctx_t *ctx)
|
||||
static uint fetchd(void)
|
||||
{
|
||||
uint v = *(uint *)(ctx->mp + R(RIP) + R(CR1) - MEMOFF);
|
||||
R(RIP) += 4;
|
||||
@ -35,7 +35,7 @@ static uint fetchd(ctx_t *ctx)
|
||||
return v;
|
||||
}
|
||||
|
||||
static ulong fetchq(ctx_t *ctx)
|
||||
static ulong fetchq(void)
|
||||
{
|
||||
ulong v = *(ulong *)(ctx->mp + R(RIP) + R(CR1) - MEMOFF);
|
||||
R(RIP) += 8;
|
||||
@ -46,38 +46,38 @@ static ulong fetchq(ctx_t *ctx)
|
||||
//
|
||||
// Verify that access to a certain register is legal
|
||||
//
|
||||
static void checkreg(ctx_t *ctx, uint reg)
|
||||
static void checkreg(uint reg)
|
||||
{
|
||||
if (reg >= NREGS)
|
||||
_except(ctx, E_ILL, "Inexistent register: %u", reg);
|
||||
_except(E_ILL, "Inexistent register: %u", reg);
|
||||
|
||||
if (ctx->r[reg].flags & RES)
|
||||
_except(ctx, E_ACC, "Reserved REG: %u", reg);
|
||||
_except(E_ACC, "Reserved REG: %u", reg);
|
||||
|
||||
if (ctx->r[reg].flags & SYS)
|
||||
if (R(CR0) & UF)
|
||||
_except(ctx, E_SYS, "User access to SYS REG: %u", reg);
|
||||
_except(E_SYS, "User access to SYS REG: %u", reg);
|
||||
}
|
||||
|
||||
//
|
||||
// Verify that given access length is that of a byte/word/dword/qword
|
||||
//
|
||||
static void checklength(ctx_t *ctx, instr_t *in, uint len)
|
||||
static void checklength(instr_t *in, uint len)
|
||||
{
|
||||
static const int lentab[9] = { 0, 1, 1, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
if (len > 8 || lentab[len] == 0)
|
||||
_except(ctx, E_ILL, "%s: Invalid memory access length: %u",
|
||||
_except(E_ILL, "%s: Invalid memory access length: %u",
|
||||
in->name, len);
|
||||
}
|
||||
|
||||
//
|
||||
// Extracts one operand
|
||||
//
|
||||
static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
static void extract_param(instr_t *in, acc_t *p)
|
||||
{
|
||||
// Get next operand ModRM-like byte
|
||||
uchar fmt = fetchb(ctx);
|
||||
uchar fmt = fetchb();
|
||||
|
||||
uchar hi = (fmt & 0b11100000) >> 5;
|
||||
uchar lo = fmt & 0b00011111;
|
||||
@ -89,7 +89,7 @@ static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
{
|
||||
p->reg = lo;
|
||||
p->type = A_REG;
|
||||
checkreg(ctx, p->reg);
|
||||
checkreg(p->reg);
|
||||
|
||||
p->val = R(p->reg);
|
||||
|
||||
@ -105,26 +105,26 @@ static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
{
|
||||
case 1:
|
||||
p->type = A_IMM8;
|
||||
p->val = fetchb(ctx);
|
||||
p->val = fetchb();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
p->type = A_IMM16;
|
||||
p->val = fetchw(ctx);
|
||||
p->val = fetchw();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p->type = A_IMM32;
|
||||
p->val = fetchd(ctx);
|
||||
p->val = fetchd();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
p->type = A_IMM64;
|
||||
p->val = fetchq(ctx);
|
||||
p->val = fetchq();
|
||||
break;
|
||||
|
||||
default:
|
||||
_except(ctx, E_ILL, "%s: Invalid immediate length: %hhu",
|
||||
_except(E_ILL, "%s: Invalid immediate length: %hhu",
|
||||
in->name, lo);
|
||||
}
|
||||
|
||||
@ -135,53 +135,53 @@ static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
// Memory operands
|
||||
//
|
||||
|
||||
checklength(ctx, in, lo);
|
||||
checklength(in, lo);
|
||||
p->mlen = lo;
|
||||
|
||||
switch (hi)
|
||||
{
|
||||
case 1:
|
||||
p->type = AM_RR;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = p->imm1 = p->imm2 = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
p->type = AM_RR;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->reg2 = fetchb(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = fetchb();
|
||||
p->imm1 = 1;
|
||||
p->imm2 = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
p->type = AM_RRI;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->reg2 = fetchb(ctx);
|
||||
p->imm2 = (short)fetchw(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = fetchb();
|
||||
p->imm2 = (short)fetchw();
|
||||
p->imm1 = 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p->type = AM_RRI;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->reg2 = fetchb(ctx);
|
||||
p->imm2 = (int)fetchd(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = fetchb();
|
||||
p->imm2 = (int)fetchd();
|
||||
p->imm1 = 1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
p->type = AM_RRII;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->reg2 = fetchb(ctx);
|
||||
p->imm1 = fetchb(ctx);
|
||||
p->imm2 = (short)fetchd(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->reg2 = fetchb();
|
||||
p->imm1 = fetchb();
|
||||
p->imm2 = (short)fetchd();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
p->type = AM_RRI;
|
||||
p->reg1 = fetchb(ctx);
|
||||
p->imm2 = fetchq(ctx);
|
||||
p->reg1 = fetchb();
|
||||
p->imm2 = fetchq();
|
||||
p->reg2 = RZX;
|
||||
p->imm1 = 1;
|
||||
break;
|
||||
@ -193,7 +193,7 @@ static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
//
|
||||
// Instruction fetch & decode
|
||||
//
|
||||
void decode(ctx_t *ctx)
|
||||
void decode(void)
|
||||
{
|
||||
instr_t *in;
|
||||
ushort b1, b2, rep = 0, lock;
|
||||
@ -204,16 +204,16 @@ void decode(ctx_t *ctx)
|
||||
// Address range check
|
||||
// (assumes max. instruction length is 32 bytes)
|
||||
if (R(RIP) + R(CR1) - MEMOFF >= ctx->mz - 32)
|
||||
_except(ctx, E_ACC, "Executing out of memory");
|
||||
_except(E_ACC, "Executing out of memory");
|
||||
|
||||
// Instruction bytes
|
||||
b1 = fetchb(ctx);
|
||||
b1 = fetchb();
|
||||
|
||||
// Suffixes?
|
||||
if (b1 & (1 << 7))
|
||||
{
|
||||
b1 &= ~(1 << 7);
|
||||
b2 = fetchb(ctx);
|
||||
b2 = fetchb();
|
||||
}
|
||||
|
||||
else
|
||||
@ -221,7 +221,7 @@ void decode(ctx_t *ctx)
|
||||
|
||||
// Renge check
|
||||
if (b1 >= NINSTRS)
|
||||
_except(ctx, E_ILL, "No such INSTR: 0x%hhX", b1);
|
||||
_except(E_ILL, "No such INSTR: 0x%hhX", b1);
|
||||
|
||||
// Find instruction
|
||||
in = &ctx->i[b1];
|
||||
@ -235,30 +235,30 @@ void decode(ctx_t *ctx)
|
||||
// Operand 1?
|
||||
if (in->nprms == 0)
|
||||
{
|
||||
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
|
||||
exec_instr(in, NULL, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in, &p1);
|
||||
extract_param(in, &p1);
|
||||
|
||||
// Operand 2?
|
||||
if (in->nprms == 1)
|
||||
{
|
||||
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
|
||||
exec_instr(in, &p1, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in, &p2);
|
||||
extract_param(in, &p2);
|
||||
|
||||
// Operand 1?
|
||||
if (in->nprms == 2)
|
||||
{
|
||||
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
|
||||
exec_instr(in, &p1, &p2, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in, &p3);
|
||||
extract_param(in, &p3);
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep);
|
||||
exec_instr(in, &p1, &p2, &p3, lock, rep);
|
||||
}
|
||||
|
||||
|
@ -67,22 +67,20 @@ struct instr_t
|
||||
{
|
||||
char *name;
|
||||
uint nprms;
|
||||
uint (*func)(ctx_t *, acc_t *, acc_t *, acc_t *,
|
||||
ulong *, ulong *, ulong *);
|
||||
uint (*func)(acc_t *, acc_t *, acc_t *,
|
||||
ulong *, ulong *, ulong *);
|
||||
};
|
||||
|
||||
bool eval_cond(ctx_t *ctx, uint cond);
|
||||
bool eval_cond(uint cond);
|
||||
|
||||
void exec_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
void exec_instr(instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
bool lock,
|
||||
bool rep);
|
||||
|
||||
void dump_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
void dump_instr(instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
|
@ -23,25 +23,25 @@ static dev_t *arch_d[] =
|
||||
};
|
||||
|
||||
|
||||
int devinitall(ctx_t *ctx)
|
||||
int devinitall(void)
|
||||
{
|
||||
size_t it;
|
||||
|
||||
for (it = 0; arch_d[it] != NULL; it++) {
|
||||
// trace("Adding device %s\n", arch_d[it]->name);
|
||||
if (devinit(ctx, arch_d[it]) < 0)
|
||||
if (devinit(arch_d[it]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devfiniall(ctx_t *ctx)
|
||||
int devfiniall(void)
|
||||
{
|
||||
int failed = 0;
|
||||
|
||||
while (ctx->dh)
|
||||
if (devfini(ctx, ctx->dh) < 0)
|
||||
if (devfini(ctx->dh) < 0)
|
||||
failed = -1;
|
||||
|
||||
return failed;
|
||||
@ -63,7 +63,7 @@ void devfree(dev_t *dev)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
dev_t *devget(ctx_t *ctx, int idx)
|
||||
dev_t *devget(int idx)
|
||||
{
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
@ -76,7 +76,7 @@ dev_t *devget(ctx_t *ctx, int idx)
|
||||
return dev;
|
||||
}
|
||||
|
||||
void devattach(ctx_t *ctx, dev_t *dev)
|
||||
void devattach(dev_t *dev)
|
||||
{
|
||||
dev_t *it;
|
||||
|
||||
@ -91,13 +91,13 @@ void devattach(ctx_t *ctx, dev_t *dev)
|
||||
else ctx->dh = dev;
|
||||
}
|
||||
|
||||
int devinit(ctx_t *ctx, dev_t *dev)
|
||||
int devinit(dev_t *dev)
|
||||
{
|
||||
if (!dev || dev->state != DEVPWOF)
|
||||
return -1;
|
||||
|
||||
if (dev->fpwon)
|
||||
dev->fpwon(ctx, dev);
|
||||
dev->fpwon(dev);
|
||||
|
||||
else dev->state = DEVGOOD;
|
||||
|
||||
@ -106,7 +106,7 @@ int devinit(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
dev->id = random();
|
||||
|
||||
devattach(ctx, dev);
|
||||
devattach(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -115,7 +115,7 @@ int devinit(ctx_t *ctx, dev_t *dev)
|
||||
|
||||
// NEVER detach while some assembly code
|
||||
// may still be running on the vm!
|
||||
void devdetach(ctx_t *ctx, dev_t *dev)
|
||||
void devdetach(dev_t *dev)
|
||||
{
|
||||
dev_t *it;
|
||||
|
||||
@ -136,25 +136,25 @@ void devdetach(ctx_t *ctx, dev_t *dev)
|
||||
}
|
||||
}
|
||||
|
||||
int devfini(ctx_t *ctx, dev_t *dev)
|
||||
int devfini(dev_t *dev)
|
||||
{
|
||||
if (dev->state == DEVPWOF || dev->state == DEVFERR) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dev->fpwoff)
|
||||
dev->fpwoff(ctx, dev);
|
||||
dev->fpwoff(dev);
|
||||
|
||||
else dev->state = DEVPWOF;
|
||||
|
||||
if (dev->state != DEVPWOF)
|
||||
goto err;
|
||||
|
||||
devdetach(ctx, dev);
|
||||
devdetach(dev);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
devdetach(ctx, dev);
|
||||
devdetach(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#define DEVLEN 32
|
||||
#define DEVSLOTS 4096
|
||||
|
||||
typedef long (*devfn_t)(ctx_t *, dev_t *);
|
||||
typedef long (*devfn_t)(dev_t *);
|
||||
|
||||
enum
|
||||
{
|
||||
@ -46,14 +46,14 @@ struct dev_t
|
||||
dev_t *devalloc(void);
|
||||
void devfree(dev_t *);
|
||||
|
||||
dev_t *devget(ctx_t *, int);
|
||||
dev_t *devget(int);
|
||||
|
||||
void devattach(ctx_t *, dev_t *);
|
||||
void devdetach(ctx_t *, dev_t *);
|
||||
void devattach(dev_t *);
|
||||
void devdetach( dev_t *);
|
||||
|
||||
int devinit(ctx_t *, dev_t *);
|
||||
int devfini(ctx_t *, dev_t *);
|
||||
int devinit(dev_t *);
|
||||
int devfini(dev_t *);
|
||||
|
||||
int devinitall(ctx_t *);
|
||||
int devfiniall(ctx_t *);
|
||||
int devinitall(void);
|
||||
int devfiniall(void);
|
||||
|
||||
|
@ -11,12 +11,12 @@ void die(int code)
|
||||
if (main_ctx.mp)
|
||||
free(main_ctx.mp);
|
||||
|
||||
console_exit(&main_ctx);
|
||||
console_exit();
|
||||
|
||||
//
|
||||
// Shut down devices
|
||||
//
|
||||
if (devfiniall(&main_ctx) < 0)
|
||||
if (devfiniall() < 0)
|
||||
{
|
||||
logerr("Couldn't deinitialize devices\n");
|
||||
exit(-100 - code);
|
||||
|
13
vm/pc/dump.c
13
vm/pc/dump.c
@ -14,10 +14,9 @@ static const char *cond_suffixes[] =
|
||||
"?"
|
||||
};
|
||||
|
||||
static void dump_acc(ctx_t *ctx, acc_t *p);
|
||||
static void dump_acc(acc_t *p);
|
||||
|
||||
void dump_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
void dump_instr(instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
@ -55,22 +54,22 @@ void dump_instr(ctx_t *ctx,
|
||||
trace("\t");
|
||||
|
||||
if (p1)
|
||||
dump_acc(ctx, p1);
|
||||
dump_acc(p1);
|
||||
|
||||
if (p2) {
|
||||
trace(", ");
|
||||
dump_acc(ctx, p2);
|
||||
dump_acc(p2);
|
||||
}
|
||||
|
||||
if (p3) {
|
||||
trace(", ");
|
||||
dump_acc(ctx, p3);
|
||||
dump_acc(p3);
|
||||
}
|
||||
|
||||
trace("\n");
|
||||
}
|
||||
|
||||
static void dump_acc(ctx_t *ctx, acc_t *p)
|
||||
static void dump_acc(acc_t *p)
|
||||
{
|
||||
uint mfmt;
|
||||
sym_t *sym;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
int dying = 0;
|
||||
|
||||
void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
void _except(int _code, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
ulong handler;
|
||||
@ -63,7 +63,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
||||
|
||||
// Double fault then?
|
||||
if (code < 512)
|
||||
_except(ctx, E_DBF, "Double Fault; previously handling: #%u", code);
|
||||
_except(E_DBF, "Double Fault; previously handling: #%u", code);
|
||||
|
||||
// Todo: queue INTs
|
||||
else
|
||||
@ -112,7 +112,7 @@ actually_die:
|
||||
|
||||
dying = 1;
|
||||
|
||||
dumpregs(ctx);
|
||||
dumpregs();
|
||||
logerr("\n");
|
||||
|
||||
die(code);
|
||||
|
@ -30,4 +30,4 @@ extern int dying;
|
||||
extern jmp_buf exc_jmp_buf;
|
||||
|
||||
void main_loop(void) __attribute__((__noreturn__));
|
||||
void _except(ctx_t *, int, char *, ...) __attribute__((__noreturn__));
|
||||
void _except(int, char *, ...) __attribute__((__noreturn__));
|
||||
|
21
vm/pc/exec.c
21
vm/pc/exec.c
@ -5,7 +5,7 @@
|
||||
|
||||
#define rfx R(RFX)
|
||||
|
||||
bool eval_cond(ctx_t *ctx, uint cond)
|
||||
bool eval_cond(uint cond)
|
||||
{
|
||||
bool neg = cond & (1 << 4);
|
||||
bool ok;
|
||||
@ -32,7 +32,7 @@ bool eval_cond(ctx_t *ctx, uint cond)
|
||||
case CD_DXZ: ok = !R(RDX); break;
|
||||
|
||||
default:
|
||||
_except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
|
||||
_except(E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
|
||||
}
|
||||
|
||||
return neg ? !ok : !!ok;
|
||||
@ -42,15 +42,14 @@ bool eval_cond(ctx_t *ctx, uint cond)
|
||||
if (p->type == A_REG) \
|
||||
R(p->reg) = r; \
|
||||
else if (ACC_IS_MEM(p)) \
|
||||
writemem(ctx, r, p->addr, p->mlen); \
|
||||
else _except(ctx, E_ACC, "Trying to output to an IMM"); \
|
||||
writemem(r, p->addr, p->mlen); \
|
||||
else _except(E_ACC, "Trying to output to an IMM"); \
|
||||
}
|
||||
|
||||
//
|
||||
// Executes an instruction
|
||||
//
|
||||
void exec_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
void exec_instr(instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
acc_t *p3,
|
||||
@ -68,14 +67,14 @@ void exec_instr(ctx_t *ctx,
|
||||
// in a do ... while(cond) fashion
|
||||
//
|
||||
if (ctx->cond && in->func != i_b) // 'B' instruction is special
|
||||
if (!rep && !eval_cond(ctx, ctx->cond))
|
||||
if (!rep && !eval_cond(ctx->cond))
|
||||
return;
|
||||
|
||||
if (ctx->dumpsw)
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep);
|
||||
dump_instr(in, p1, p2, p3, lock, rep);
|
||||
|
||||
do_rep:
|
||||
out = in->func(ctx, p1, p2, p3, &r1, &r2, &r3);
|
||||
out = in->func(p1, p2, p3, &r1, &r2, &r3);
|
||||
|
||||
if (out)
|
||||
{
|
||||
@ -88,7 +87,7 @@ do_rep:
|
||||
if (rep)
|
||||
{
|
||||
// RCX remains untouched when condition fails
|
||||
if (!eval_cond(ctx, ctx->cond))
|
||||
if (!eval_cond(ctx->cond))
|
||||
return;
|
||||
|
||||
if (R(RCX) > 0)
|
||||
@ -102,7 +101,7 @@ do_rep:
|
||||
#if 0
|
||||
// Show that we're REP'ing
|
||||
if (ctx->dumpsw)
|
||||
dump_instr(ctx, in, p1, p2, p3, lock, rep);
|
||||
dump_instr(in, p1, p2, p3, lock, rep);
|
||||
#endif
|
||||
|
||||
goto do_rep;
|
||||
|
@ -11,7 +11,7 @@ keycode_t keybuf[KEYBUFSIZE] = { 0 };
|
||||
keycode_t *keybuf_last = &keybuf[0];
|
||||
keycode_t *keybuf_ptr = &keybuf[0];
|
||||
|
||||
void console_addkey(ctx_t *ctx, keycode_t key)
|
||||
void console_addkey(keycode_t key)
|
||||
{
|
||||
*keybuf_ptr++ = key;
|
||||
|
||||
@ -19,7 +19,7 @@ void console_addkey(ctx_t *ctx, keycode_t key)
|
||||
keybuf_ptr = &keybuf[0];
|
||||
}
|
||||
|
||||
keycode_t console_getkey(ctx_t *ctx)
|
||||
keycode_t console_getkey(void)
|
||||
{
|
||||
keycode_t rc = *keybuf_last++;
|
||||
|
||||
@ -29,10 +29,10 @@ keycode_t console_getkey(ctx_t *ctx)
|
||||
return rc;
|
||||
}
|
||||
|
||||
keycode_t console_scankeybuf(ctx_t *ctx)
|
||||
keycode_t console_scankeybuf(void)
|
||||
{
|
||||
if (keybuf_last != keybuf_ptr)
|
||||
return console_getkey(ctx);
|
||||
return console_getkey();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -51,7 +51,7 @@ _QKEY(SDLK_##key, c, cshift, cmode, calt, cgui)
|
||||
else if ((mod & KMOD_GUI)) code = cgui; \
|
||||
break;
|
||||
|
||||
void console_handle_input(ctx_t *ctx, SDL_Keycode key)
|
||||
void console_handle_input(SDL_Keycode key)
|
||||
{
|
||||
keycode_t code = 0;
|
||||
|
||||
@ -60,7 +60,7 @@ void console_handle_input(ctx_t *ctx, SDL_Keycode key)
|
||||
if (mod & KMOD_CTRL)
|
||||
{
|
||||
if (key == SDLK_c)
|
||||
_except(ctx, E_BRK, "Ctrl+C received");
|
||||
_except(E_BRK, "Ctrl+C received");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -191,6 +191,6 @@ void console_handle_input(ctx_t *ctx, SDL_Keycode key)
|
||||
}
|
||||
|
||||
if (code != 0)
|
||||
console_addkey(ctx, code);
|
||||
console_addkey(code);
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ extern keycode_t keybuf[KEYBUFSIZE];
|
||||
extern keycode_t *keybuf_last;
|
||||
extern keycode_t *keybuf_ptr;
|
||||
|
||||
keycode_t console_getkey(ctx_t *);
|
||||
keycode_t console_scankeybuf(ctx_t *);
|
||||
keycode_t console_getkey(void);
|
||||
keycode_t console_scankeybuf(void);
|
||||
|
||||
void console_addkey(ctx_t *, keycode_t);
|
||||
void console_handle_input(ctx_t *ctx, SDL_Keycode key);
|
||||
void console_addkey(keycode_t);
|
||||
void console_handle_input(SDL_Keycode key);
|
||||
|
||||
|
10
vm/pc/main.c
10
vm/pc/main.c
@ -15,7 +15,7 @@ ctx_t main_ctx;
|
||||
|
||||
void sigcommon(void)
|
||||
{
|
||||
_except(&main_ctx, E_BRK, "SIGNAL'ed");
|
||||
_except(E_BRK, "SIGNAL'ed");
|
||||
}
|
||||
|
||||
void sigint(int _)
|
||||
@ -43,9 +43,9 @@ void main_loop(void)
|
||||
//
|
||||
while (!dying) {
|
||||
// Execute one instruction
|
||||
decode(&main_ctx);
|
||||
decode();
|
||||
|
||||
console_update(&main_ctx);
|
||||
console_update();
|
||||
}
|
||||
|
||||
die(0);
|
||||
@ -136,7 +136,7 @@ int main(int argc, char **argv)
|
||||
// Devices initialization
|
||||
//
|
||||
main_ctx.dh = 0;
|
||||
if (devinitall(&main_ctx) < 0) {
|
||||
if (devinitall() < 0) {
|
||||
logerr("Couldn't initialize devices\n");
|
||||
free(main_ctx.rf);
|
||||
free(fwprog);
|
||||
@ -144,7 +144,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// To be moved to some screen device
|
||||
console_init(&main_ctx);
|
||||
console_init();
|
||||
|
||||
main_loop();
|
||||
}
|
||||
|
60
vm/pc/mem.c
60
vm/pc/mem.c
@ -5,12 +5,12 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
ulong readstr(ctx_t *ctx, ulong addr, ulong maxn, char *buf)
|
||||
ulong readstr(ulong addr, ulong maxn, char *buf)
|
||||
{
|
||||
ulong orig_maxn = maxn;
|
||||
|
||||
for (; maxn > 0; buf++, addr++, maxn--) {
|
||||
*buf = readmemzx(ctx, addr, 1) & 0xFF;
|
||||
*buf = readmemzx(addr, 1) & 0xFF;
|
||||
|
||||
if (*buf == 0)
|
||||
break;
|
||||
@ -21,15 +21,15 @@ ulong readstr(ctx_t *ctx, ulong addr, ulong maxn, char *buf)
|
||||
return orig_maxn - maxn;
|
||||
}
|
||||
|
||||
ulong writestr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
||||
ulong writestr(ulong addr, ulong maxn, char *str)
|
||||
{
|
||||
ulong orig_maxn = maxn;
|
||||
|
||||
for (; *str && maxn > 0; str++, addr++, maxn--) {
|
||||
writemem(ctx, *str, addr, 1);
|
||||
writemem(*str, addr, 1);
|
||||
}
|
||||
|
||||
writemem(ctx, 0, addr, 1);
|
||||
writemem(0, addr, 1);
|
||||
|
||||
return orig_maxn - maxn;
|
||||
}
|
||||
@ -38,33 +38,33 @@ ulong writestr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
||||
|
||||
#define CHK_ALIGN(type) \
|
||||
if (addr % alignof(type) > 0) { \
|
||||
_except(ctx, E_ALI, \
|
||||
_except(E_ALI, \
|
||||
"Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \
|
||||
addr, real, alignof(type)); \
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static ulong readmem8(ctx_t *ctx, ulong real, ulong addr)
|
||||
static ulong readmem8(ulong real, ulong addr)
|
||||
{
|
||||
return (ulong)ctx->mp[real];
|
||||
}
|
||||
|
||||
static ulong readmem16(ctx_t *ctx, ulong real, ulong addr)
|
||||
static ulong readmem16(ulong real, ulong addr)
|
||||
{
|
||||
CHK_ALIGN(ushort);
|
||||
|
||||
return (ulong)*(ushort *)(ctx->mp + real);
|
||||
}
|
||||
|
||||
static ulong readmem32(ctx_t *ctx, ulong real, ulong addr)
|
||||
static ulong readmem32(ulong real, ulong addr)
|
||||
{
|
||||
CHK_ALIGN(uint);
|
||||
|
||||
return (ulong)*(uint *)(ctx->mp + real);
|
||||
}
|
||||
|
||||
static ulong readmem64(ctx_t *ctx, ulong real, ulong addr)
|
||||
static ulong readmem64(ulong real, ulong addr)
|
||||
{
|
||||
CHK_ALIGN(ulong);
|
||||
|
||||
@ -73,24 +73,24 @@ static ulong readmem64(ctx_t *ctx, ulong real, ulong addr)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void writemem8(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
static void writemem8(ulong val, ulong real, ulong addr)
|
||||
{
|
||||
ctx->mp[real] = val & 0xFF;
|
||||
}
|
||||
|
||||
static void writemem16(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
static void writemem16(ulong val, ulong real, ulong addr)
|
||||
{
|
||||
*(ushort*)(ctx->mp + real) = val & 0xFFFF;
|
||||
}
|
||||
|
||||
static void writemem32(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
static void writemem32(ulong val, ulong real, ulong addr)
|
||||
{
|
||||
CHK_ALIGN(uint);
|
||||
|
||||
*(uint*)(ctx->mp + real) = val & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
static void writemem64(ulong val, ulong real, ulong addr)
|
||||
{
|
||||
CHK_ALIGN(ulong);
|
||||
|
||||
@ -101,7 +101,7 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
|
||||
#define CHK_RANGE() \
|
||||
if (addr < MEMOFF || real >= MEMSIZE) { \
|
||||
_except(ctx, E_ACC, \
|
||||
_except(E_ACC, \
|
||||
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
|
||||
}
|
||||
|
||||
@ -110,22 +110,22 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
ulong readmemzx(ctx_t *ctx, ulong addr, uint len)
|
||||
ulong readmemzx(ulong addr, uint len)
|
||||
{
|
||||
GETREAL();
|
||||
CHK_RANGE();
|
||||
|
||||
switch (len) {
|
||||
case 1: return readmem8(ctx, real, addr); break;
|
||||
case 2: return readmem16(ctx, real, addr); break;
|
||||
case 4: return readmem32(ctx, real, addr); break;
|
||||
case 8: return readmem64(ctx, real, addr); break;
|
||||
case 1: return readmem8(real, addr); break;
|
||||
case 2: return readmem16(real, addr); break;
|
||||
case 4: return readmem32(real, addr); break;
|
||||
case 8: return readmem64(real, addr); break;
|
||||
|
||||
default: logerr("readmemzx() bad length %d!\n", len); abort();
|
||||
}
|
||||
}
|
||||
|
||||
ulong readmemsx(ctx_t *ctx, ulong addr, uint len)
|
||||
ulong readmemsx(ulong addr, uint len)
|
||||
{
|
||||
GETREAL();
|
||||
CHK_RANGE();
|
||||
@ -134,22 +134,22 @@ ulong readmemsx(ctx_t *ctx, ulong addr, uint len)
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
val = readmem8(ctx, real, addr);
|
||||
val = readmem8(real, addr);
|
||||
val = (ulong)(long)(char)val;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
val = readmem16(ctx, real, addr);
|
||||
val = readmem16(real, addr);
|
||||
val = (ulong)(long)(short)val;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
val = readmem32(ctx, real, addr);
|
||||
val = readmem32(real, addr);
|
||||
val = (ulong)(long)(int)val;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
return readmem64(ctx, real, addr);
|
||||
return readmem64(real, addr);
|
||||
|
||||
default: logerr("readmemsx() bad length %d!\n", len); abort();
|
||||
}
|
||||
@ -157,7 +157,7 @@ ulong readmemsx(ctx_t *ctx, ulong addr, uint len)
|
||||
return val;
|
||||
}
|
||||
|
||||
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||
void writemem(ulong val, ulong addr, uint len)
|
||||
{
|
||||
GETREAL();
|
||||
CHK_RANGE();
|
||||
@ -165,10 +165,10 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||
// log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len);
|
||||
|
||||
switch (len) {
|
||||
case 1: writemem8(ctx, val, real, addr); break;
|
||||
case 2: writemem16(ctx, val, real, addr); break;
|
||||
case 4: writemem32(ctx, val, real, addr); break;
|
||||
case 8: writemem64(ctx, val, real, addr); break;
|
||||
case 1: writemem8(val, real, addr); break;
|
||||
case 2: writemem16(val, real, addr); break;
|
||||
case 4: writemem32(val, real, addr); break;
|
||||
case 8: writemem64(val, real, addr); break;
|
||||
default: logerr("writemem() bad length %d!\n", len); abort();
|
||||
}
|
||||
}
|
||||
|
16
vm/pc/mem.h
16
vm/pc/mem.h
@ -18,16 +18,10 @@ static inline char getmempref(ushort len)
|
||||
// Address of boot firmware stack
|
||||
#define FWSTACK (MEMOFF * 2) // 2MB
|
||||
|
||||
ulong readstr(ctx_t *ctx, ulong addr, ulong maxn, char *buf);
|
||||
ulong writestr(ctx_t *ctx, ulong addr, ulong maxn, char *str);
|
||||
ulong readstr(ulong addr, ulong maxn, char *buf);
|
||||
ulong writestr(ulong addr, ulong maxn, char *str);
|
||||
|
||||
ulong readmemzx(ctx_t *c, ulong addr, uint len);
|
||||
ulong readmemsx(ctx_t *c, ulong addr, uint len);
|
||||
void writemem(ctx_t *, ulong val, ulong addr, uint len);
|
||||
|
||||
|
||||
#define SIGN_EXTEND(val, mask) \
|
||||
(val & ((mask + 1) >> 1) \
|
||||
? (val | ~mask) \
|
||||
: val)
|
||||
ulong readmemzx(ulong addr, uint len);
|
||||
ulong readmemsx(ulong addr, uint len);
|
||||
void writemem(ulong val, ulong addr, uint len);
|
||||
|
||||
|
@ -21,7 +21,7 @@ static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
|
||||
|
||||
#define TRACE logerr
|
||||
|
||||
void dumpregs(ctx_t *ctx)
|
||||
void dumpregs()
|
||||
{
|
||||
TRACE("Current RFRAME index: #%lu", rfs_current_idx);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user