Write the results of an ALU operation before writing to register/memory (#13486)

Sega Rally has an instruction that calculates d += p and loads a value into d at the same time; it is the loaded value that should be used, not the result of the ALU operation

Also only test the d register when performing an ALU operation
This commit is contained in:
Matthew Daniels 2025-03-20 21:17:38 +00:00 committed by GitHub
parent bdfd419e21
commit 5363907b72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 19 deletions

View File

@ -256,18 +256,6 @@ void mb86233_device::pcs_pop()
m_pcs[i] = m_pcs[i+1]; m_pcs[i] = m_pcs[i+1];
} }
void mb86233_device::testdz()
{
if(m_d)
m_st &= ~F_ZRD;
else
m_st |= F_ZRD;
if(m_d & 0x80000000)
m_st |= F_SGD;
else
m_st &= ~F_SGD;
}
void mb86233_device::stset_set_sz_int(u32 val) void mb86233_device::stset_set_sz_int(u32 val)
{ {
m_alu_stset = val ? (val & 0x80000000 ? F_SGD : 0) : F_ZRD; m_alu_stset = val ? (val & 0x80000000 ? F_SGD : 0) : F_ZRD;
@ -324,7 +312,7 @@ void mb86233_device::alu_pre(u32 alu)
} }
case 0x06: { case 0x06: {
// fmad // fadd
m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD; m_alu_stmask = F_ZRD|F_SGD|F_CPD|F_OVD|F_DVZD;
m_alu_r1 = f2u(u2f(m_d) + u2f(m_a)); m_alu_r1 = f2u(u2f(m_d) + u2f(m_a));
stset_set_sz_fp(m_alu_r1); stset_set_sz_fp(m_alu_r1);
@ -676,9 +664,9 @@ void mb86233_device::write_reg(u32 r, u32 v)
case 0x14: m_b = set_exp(m_b, v); break; case 0x14: m_b = set_exp(m_b, v); break;
case 0x15: m_b = set_mant(m_b, v); break; case 0x15: m_b = set_mant(m_b, v); break;
/* c */ /* c */
case 0x19: m_d = v; testdz(); break; case 0x19: m_d = v; break;
case 0x1a: m_d = set_exp(m_d, v); testdz(); break; case 0x1a: m_d = set_exp(m_d, v); break;
case 0x1b: m_d = set_mant(m_d, v); testdz(); break; case 0x1b: m_d = set_mant(m_d, v); break;
case 0x1c: m_p = v; break; case 0x1c: m_p = v; break;
case 0x1d: m_p = set_exp(m_p, v); break; case 0x1d: m_p = set_exp(m_p, v); break;
case 0x1e: m_p = set_mant(m_p, v); break; case 0x1e: m_p = set_mant(m_p, v); break;
@ -812,6 +800,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_io_1(r2, v); write_mem_io_1(r2, v);
break; break;
} }
@ -822,6 +811,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_io_1(r2, v); write_mem_io_1(r2, v);
break; break;
} }
@ -832,6 +822,7 @@ void mb86233_device::execute_run()
u32 v = m_io.read_dword(ea); u32 v = m_io.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_internal_1(r2, v, false); write_mem_internal_1(r2, v, false);
break; break;
} }
@ -842,6 +833,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_internal_1(r2, v, true); write_mem_internal_1(r2, v, true);
break; break;
} }
@ -852,6 +844,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_internal_1(r2, v, false); write_mem_internal_1(r2, v, false);
break; break;
} }
@ -862,6 +855,7 @@ void mb86233_device::execute_run()
u32 v = m_program.read_dword(ea); u32 v = m_program.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_mem_internal_1(r2, v, false); write_mem_internal_1(r2, v, false);
break; break;
} }
@ -872,6 +866,7 @@ void mb86233_device::execute_run()
// mov reg, mem // mov reg, mem
u32 v = read_reg(r2); u32 v = read_reg(r2);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
alu_post(alu);
write_mem_internal_1(r1, v, false); write_mem_internal_1(r1, v, false);
break; break;
} }
@ -880,6 +875,7 @@ void mb86233_device::execute_run()
// mov reg, mem (e) // mov reg, mem (e)
u32 v = read_reg(r2); u32 v = read_reg(r2);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
alu_post(alu);
write_mem_io_1(r1, v); write_mem_io_1(r1, v);
break; break;
} }
@ -890,6 +886,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_1(r1); ea_post_1(r1);
alu_post(alu);
write_reg(r2, v); write_reg(r2, v);
break; break;
} }
@ -900,6 +897,7 @@ void mb86233_device::execute_run()
u32 v = m_data.read_dword(ea); u32 v = m_data.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_1(r1); ea_post_1(r1);
alu_post(alu);
write_reg(r2, v); write_reg(r2, v);
break; break;
} }
@ -910,6 +908,7 @@ void mb86233_device::execute_run()
u32 v = m_io.read_dword(ea); u32 v = m_io.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_1(r1); ea_post_1(r1);
alu_post(alu);
write_reg(r2, v); write_reg(r2, v);
break; break;
} }
@ -920,6 +919,7 @@ void mb86233_device::execute_run()
u32 v = m_program.read_dword(ea); u32 v = m_program.read_dword(ea);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
ea_post_0(r1); ea_post_0(r1);
alu_post(alu);
write_reg(r2, v); write_reg(r2, v);
break; break;
} }
@ -928,11 +928,13 @@ void mb86233_device::execute_run()
// mov reg, reg // mov reg, reg
u32 v = read_reg(r1); u32 v = read_reg(r1);
if(m_stall) goto do_stall; if(m_stall) goto do_stall;
alu_post(alu);
write_reg(r2, v); write_reg(r2, v);
break; break;
} }
default: default:
alu_post(alu);
logerror("unhandled ld/mov subop 7/%x (%x)\n", r2 >> 6, m_ppc); logerror("unhandled ld/mov subop 7/%x (%x)\n", r2 >> 6, m_ppc);
break; break;
} }
@ -940,11 +942,11 @@ void mb86233_device::execute_run()
} }
default: default:
alu_post(alu);
logerror("unhandled ld/mov subop %x (%x)\n", op, m_ppc); logerror("unhandled ld/mov subop %x (%x)\n", op, m_ppc);
break; break;
} }
alu_post(alu);
break; break;
} }
@ -983,7 +985,6 @@ void mb86233_device::execute_run()
break; break;
case 3: case 3:
m_d = util::sext(opcode, 24); m_d = util::sext(opcode, 24);
testdz();
break; break;
} }
break; break;

View File

@ -109,7 +109,6 @@ private:
static u32 get_exp(u32 val); static u32 get_exp(u32 val);
static u32 get_mant(u32 val); static u32 get_mant(u32 val);
void testdz();
void alu_update_st(); void alu_update_st();
void alu_pre(u32 alu); void alu_pre(u32 alu);
void alu_post(u32 alu); void alu_post(u32 alu);