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