Fix a setcr0 bug which was trashing the condition register; some system
calls are now implemented. A few tests more-or-less pass (but crash on exit).
This commit is contained in:
parent
5111556d14
commit
5d7cdd2c67
|
@ -58,7 +58,7 @@ static bool getcr(uint8_t bit)
|
||||||
static void setcr(uint8_t bit, bool value)
|
static void setcr(uint8_t bit, bool value)
|
||||||
{
|
{
|
||||||
bit = 31 - bit; /* note PowerPC bit numbering */
|
bit = 31 - bit; /* note PowerPC bit numbering */
|
||||||
cpu.cr = cpu.cr & (1<<bit) | (value<<bit);
|
cpu.cr = cpu.cr & ~(1<<bit) | (value<<bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setcr0(bool setcr0, uint32_t value)
|
static void setcr0(bool setcr0, uint32_t value)
|
||||||
|
@ -227,9 +227,9 @@ void dump_state(FILE* stream)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
fprintf(stream, "\n");
|
||||||
fprintf(stream, "pc=0x%08x lr=0x%08x ctr=0x%08x xer=0x%08x cr=0x%08x\n",
|
fprintf(stream, "pc=0x%08x lr=0x%08x ctr=0x%08x xer=0x%08x cr=0x%08x\n",
|
||||||
cpu.cia, cpu.lr, cpu.ctr, cpu.xer, cpu.cr);
|
cpu.cia, cpu.lr, cpu.ctr, cpu.xer, cpu.cr);
|
||||||
fprintf(stream, "insn=0x%08x", read_long(cpu.cia));
|
|
||||||
for (i=0; i<32; i++)
|
for (i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
if ((i % 4) == 0)
|
if ((i % 4) == 0)
|
||||||
|
@ -237,6 +237,10 @@ void dump_state(FILE* stream)
|
||||||
fprintf(stream, "gpr%02d=0x%08x ", i, cpu.gpr[i]);
|
fprintf(stream, "gpr%02d=0x%08x ", i, cpu.gpr[i]);
|
||||||
}
|
}
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
|
|
||||||
|
/* This might fail and cause a reentrant trap if cia is invalid, so
|
||||||
|
* do it last. */
|
||||||
|
fprintf(stream, "insn=0x%08x", read_long(cpu.cia));
|
||||||
}
|
}
|
||||||
|
|
||||||
void single_step(void)
|
void single_step(void)
|
||||||
|
|
|
@ -73,7 +73,11 @@ static uint32_t transform_address(uint32_t address)
|
||||||
|
|
||||||
uint32_t read_long(uint32_t address)
|
uint32_t read_long(uint32_t address)
|
||||||
{
|
{
|
||||||
return READ_LONG(ram, transform_address(address));
|
uint32_t v = READ_LONG(ram, transform_address(address));
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "read 0x%08x: 0x%08x\n", address, v);
|
||||||
|
#endif
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,12 +103,45 @@ void write_word(uint32_t address, uint32_t value)
|
||||||
|
|
||||||
void write_long(uint32_t address, uint32_t value)
|
void write_long(uint32_t address, uint32_t value)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "write 0x%08x: 0x%08x\n", address, value);
|
||||||
|
#endif
|
||||||
WRITE_LONG(ram, transform_address(address), value);
|
WRITE_LONG(ram, transform_address(address), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void system_call(uint8_t trapno)
|
void system_call(uint8_t trapno)
|
||||||
{
|
{
|
||||||
fatal("syscalls unimplemented");
|
cpu.cr &= ~(1<<28); /* reset summary overflow (for success) */
|
||||||
|
switch (cpu.gpr[0])
|
||||||
|
{
|
||||||
|
case 1: /* exit */
|
||||||
|
exit(cpu.gpr[3]);
|
||||||
|
|
||||||
|
case 4: /* write */
|
||||||
|
{
|
||||||
|
int fd = cpu.gpr[3];
|
||||||
|
uint32_t address = cpu.gpr[4];
|
||||||
|
uint32_t len = cpu.gpr[5];
|
||||||
|
void* ptr = ram + transform_address(address);
|
||||||
|
transform_address(address+len); /* bounds check */
|
||||||
|
cpu.gpr[4] = write(fd, ptr, len);
|
||||||
|
if (cpu.gpr[4] == -1)
|
||||||
|
goto error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 126: /* sigprocmask */
|
||||||
|
cpu.gpr[4] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
error:
|
||||||
|
cpu.gpr[3] = errno;
|
||||||
|
cpu.cr |= (1<<28); /* set summary overflow (for failure) */
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fatal("unimplemented system call %d", cpu.gpr[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_program(FILE* fd)
|
static void load_program(FILE* fd)
|
||||||
|
@ -177,7 +214,9 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
//dump_state(stderr);
|
#if 0
|
||||||
|
dump_state(stderr);
|
||||||
|
#endif
|
||||||
single_step();
|
single_step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue