HALT fix, QoL tweaks
This commit is contained in:
+51
-11
@@ -979,7 +979,7 @@ static void cpuDIVU(VB *emu, VB_INSTRUCTION *inst) {
|
||||
static void cpuHALT(VB *emu, VB_INSTRUCTION *inst) {
|
||||
emu->cpu.state = CPU_HALTED;
|
||||
inst->size = 0;
|
||||
/* TODO: Find out how many clocks this takes */
|
||||
/* emu->cpu.clocks = ? */
|
||||
}
|
||||
|
||||
/* Input Byte */
|
||||
@@ -1491,8 +1491,8 @@ static int cpuExecute(VB *emu) {
|
||||
/* Post-instruction tasks */
|
||||
if (emu->cpu.causeCode == 0 && !emu->cpu.busWait) {
|
||||
|
||||
/* Advance to next instruction if not processing a bit string */
|
||||
if (!emu->cpu.substring)
|
||||
/* Advance to next instruction */
|
||||
if (emu->cpu.state != CPU_HALTED && !emu->cpu.substring)
|
||||
emu->cpu.pc += inst->size;
|
||||
|
||||
/* Check for interrupts */
|
||||
@@ -1505,11 +1505,10 @@ static int cpuExecute(VB *emu) {
|
||||
emu->cpu.substring = 0;
|
||||
}
|
||||
|
||||
/* Switch to fetch mode if not halting and execution has completed */
|
||||
/* Switch to fetch mode */
|
||||
else if (emu->cpu.state != CPU_HALTED &&
|
||||
!emu->cpu.busWait && !emu->cpu.substring) {
|
||||
emu->cpu.state = CPU_FETCH;
|
||||
emu->cpu.fetch = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1518,6 +1517,7 @@ static int cpuExecute(VB *emu) {
|
||||
/* Enter an exception state */
|
||||
static int cpuException(VB *emu) {
|
||||
uint16_t causeCode = emu->cpu.causeCode;
|
||||
int irq = causeCode < 0xFF00;
|
||||
|
||||
/* Fatal exception */
|
||||
if (emu->cpu.psw.np) {
|
||||
@@ -1587,7 +1587,7 @@ static int cpuException(VB *emu) {
|
||||
else {
|
||||
emu->cpu.ecr.eicc = causeCode;
|
||||
emu->cpu.eipsw = vbGetSystemRegister(emu, VB_PSW);
|
||||
emu->cpu.eipc = emu->cpu.pc;
|
||||
emu->cpu.eipc = emu->cpu.pc + (irq ? 2 : 0);
|
||||
emu->cpu.eipcFrom = emu->cpu.pcFrom;
|
||||
emu->cpu.eipcTo = emu->cpu.pcTo;
|
||||
emu->cpu.psw.ep = 1;
|
||||
@@ -1596,7 +1596,7 @@ static int cpuException(VB *emu) {
|
||||
}
|
||||
|
||||
/* Interrupt */
|
||||
if (causeCode < 0xFF00)
|
||||
if (irq)
|
||||
emu->cpu.psw.i += emu->cpu.psw.i == 15 ? 0 : 1;
|
||||
|
||||
/* Update state */
|
||||
@@ -1690,10 +1690,11 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
|
||||
|
||||
/* Processing by operations state */
|
||||
switch (emu->cpu.state) {
|
||||
case CPU_FETCH : if (cpuFetch (emu)) return 1; break;
|
||||
case CPU_EXECUTE : if (cpuExecute (emu)) return 1; break;
|
||||
case CPU_EXCEPTION: if (cpuException(emu)) return 1; break;
|
||||
case CPU_HALTED : if (cpuCheckIRQs(emu)) return 0; break;
|
||||
case CPU_EXCEPTION: if ( cpuException(emu)) return 1; break;
|
||||
case CPU_EXECUTE : if ( cpuExecute (emu)) return 1; break;
|
||||
case CPU_FATAL : return 0; break;
|
||||
case CPU_FETCH : if ( cpuFetch (emu)) return 1; break;
|
||||
case CPU_HALTED : if (!cpuCheckIRQs(emu)) return 0; break;
|
||||
}
|
||||
|
||||
} while (clocks > 0);
|
||||
@@ -1702,6 +1703,45 @@ static int cpuEmulate(VB *emu, uint32_t clocks) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Simulate a hardware reset */
|
||||
static void cpuReset(VB *emu) {
|
||||
int x; /* Iterator */
|
||||
|
||||
/* Registers */
|
||||
vbSetProgramCounter(emu, 0xFFFFFFF0);
|
||||
vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
|
||||
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
||||
|
||||
/* Cache */
|
||||
vbSetSystemRegister(emu, VB_CHCW, 0x00000000);
|
||||
|
||||
/* Other state */
|
||||
emu->cpu.busWait = 0;
|
||||
emu->cpu.state = CPU_FETCH;
|
||||
emu->cpu.substring = 0;
|
||||
for (x = 0; x < 5; x++)
|
||||
emu->cpu.irq[x] = 0;
|
||||
|
||||
/* Other registers (the hardware does not do this) */
|
||||
for (x = 0; x < 32; x++)
|
||||
emu->cpu.program[x] = 0x00000000;
|
||||
emu->cpu.adtre = 0x00000000;
|
||||
emu->cpu.eipc = 0x00000000;
|
||||
emu->cpu.eipsw = 0x00000000;
|
||||
emu->cpu.fepc = 0x00000000;
|
||||
emu->cpu.fepsw = 0x00000000;
|
||||
emu->cpu.sr29 = 0x00000000;
|
||||
emu->cpu.sr31 = 0x00000000;
|
||||
|
||||
/* History tracking */
|
||||
emu->cpu.eipcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.eipcTo = 0xFFFFFFF0;
|
||||
emu->cpu.fepcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.fepcTo = 0xFFFFFFF0;
|
||||
emu->cpu.pcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.pcTo = 0xFFFFFFF0;
|
||||
}
|
||||
|
||||
/* Determine the number of clocks before a break condititon could occur */
|
||||
static uint32_t cpuUntil(VB *emu, uint32_t clocks) {
|
||||
|
||||
|
||||
@@ -197,36 +197,8 @@ int32_t vbRead(VB *emu, uint32_t address, int type, int debug) {
|
||||
void vbReset(VB *emu) {
|
||||
uint32_t x; /* Iterator */
|
||||
|
||||
/* CPU registers */
|
||||
vbSetProgramCounter(emu, 0xFFFFFFF0);
|
||||
vbSetSystemRegister(emu, VB_ECR, 0x0000FFF0);
|
||||
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
||||
|
||||
/* Extra CPU registers (the hardware does not do this) */
|
||||
for (x = 0; x < 32; x++)
|
||||
emu->cpu.program[x] = 0x00000000;
|
||||
emu->cpu.adtre = 0x00000000;
|
||||
emu->cpu.eipc = 0x00000000;
|
||||
emu->cpu.eipsw = 0x00000000;
|
||||
emu->cpu.fepc = 0x00000000;
|
||||
emu->cpu.fepsw = 0x00000000;
|
||||
emu->cpu.sr29 = 0x00000000;
|
||||
emu->cpu.sr31 = 0x00000000;
|
||||
|
||||
/* History tracking */
|
||||
emu->cpu.eipcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.eipcTo = 0xFFFFFFF0;
|
||||
emu->cpu.fepcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.fepcTo = 0xFFFFFFF0;
|
||||
emu->cpu.pcFrom = 0xFFFFFFF0;
|
||||
emu->cpu.pcTo = 0xFFFFFFF0;
|
||||
|
||||
/* Other CPU state */
|
||||
emu->cpu.busWait = 0;
|
||||
emu->cpu.state = CPU_FETCH;
|
||||
emu->cpu.substring = 0;
|
||||
for (x = 0; x < 5; x++)
|
||||
emu->cpu.irq[x] = 0;
|
||||
/* Subsystem components */
|
||||
cpuReset(emu);
|
||||
|
||||
/* WRAM (the hardware does not do this) */
|
||||
for (x = 0; x < 0x10000; x++)
|
||||
|
||||
Reference in New Issue
Block a user