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:
David Given 2018-06-16 08:35:36 +02:00
parent 5111556d14
commit 5d7cdd2c67
2 changed files with 48 additions and 5 deletions

View file

@ -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)

View file

@ -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();
} }