mirror of
https://github.com/holub/mame
synced 2025-06-07 13:23:50 +03:00
-cpu/powerpc: Don't overwrite RA in lmw instruction. (#11512)
* For 4xx series and 601, skip over the register update. * For any other flavor, raise an illegal instruction exception. -konami/stingnet: Added ATA CS1 to address map, and removed comment about crash which has been fixed.
This commit is contained in:
parent
59e8aef15e
commit
bced77dec9
@ -2256,12 +2256,27 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler,
|
||||
case 0x2e: /* LMW */
|
||||
UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op)
|
||||
UML_MOV(block, mem(&m_core->tempaddr), R32Z(G_RA(op))); // mov [tempaddr],ra
|
||||
for (int regnum = G_RD(op); regnum < 32; regnum++)
|
||||
|
||||
if (G_RD(op) <= G_RA(op) && !(m_cap & PPCCAP_4XX) && m_flavor != PPC_MODEL_601)
|
||||
{
|
||||
UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op)));
|
||||
// add i0,[tempaddr],simm + 4*(regnum-rd)
|
||||
UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align
|
||||
UML_MOV(block, R32(regnum), I0); // mov regnum,i0
|
||||
// RA being in the range is an invalid form
|
||||
// 403 and 405 manual allows writes where regnum != RA || regnum == 31, regnum == RA is skipped
|
||||
// 601 user manual lists no special rules for R31 being valid but regnum == RA is skipped
|
||||
// 603 and above just says it's an invalid form
|
||||
// tropchnc (403GA) is known to use this behavior
|
||||
UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int regnum = G_RD(op); regnum < 32; regnum++)
|
||||
{
|
||||
UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op)));
|
||||
// add i0,[tempaddr],simm + 4*(regnum-rd)
|
||||
UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align
|
||||
|
||||
if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31))
|
||||
UML_MOV(block, R32(regnum), I0); // mov regnum,i0
|
||||
}
|
||||
}
|
||||
generate_update_cycles(block, compiler, desc->pc + 4, true); // <update cycles>
|
||||
return true;
|
||||
|
@ -289,8 +289,21 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
|
||||
|
||||
case 0x2e: // LMW
|
||||
GPR_USED_OR_ZERO(desc, G_RA(op));
|
||||
for (regnum = G_RD(op); regnum < 32; regnum++)
|
||||
GPR_MODIFIED(desc, regnum);
|
||||
|
||||
if (G_RD(op) <= G_RA(op) && !(m_ppc.m_cap & PPCCAP_4XX) && !is_601_class())
|
||||
{
|
||||
// Undefined invalid form that has different behavior between CPUs
|
||||
// See ppcdrc.cpp for a more detailed explanation
|
||||
desc.flags |= OPFLAG_INVALID_OPCODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (regnum = G_RD(op); regnum < 32; regnum++)
|
||||
{
|
||||
if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31))
|
||||
GPR_MODIFIED(desc, regnum);
|
||||
}
|
||||
}
|
||||
desc.flags |= OPFLAG_READS_MEMORY;
|
||||
desc.cycles = 32 - G_RD(op);
|
||||
return true;
|
||||
|
@ -15,11 +15,6 @@
|
||||
GC965 Magic Timer Poker
|
||||
GC966 Joker Time
|
||||
GC967 Egyptian Slot
|
||||
|
||||
TODO: With VBL IRQs working, the deferred function to load the first stage boot from the CD-ROM is jumped to
|
||||
at 0xFFFA9578 but it immediately hits an alignment fault trying to store a 32-bit word to a 16-bit aligned
|
||||
address. (Does the 403 maybe not have that exception? The PPC architecture docs indicate it's not a requirement
|
||||
for all implementations. Or is this an early security failure?).
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -94,6 +89,7 @@ void stingnet_state::main_map(address_map &map)
|
||||
map(0x71000000, 0x71000007).noprw(); // TODO: what is going on here?
|
||||
map(0x71000010, 0x71000013).ram();
|
||||
map(0x72000000, 0x7200000f).rw(m_ata, FUNC(ata_interface_device::cs0_r), FUNC(ata_interface_device::cs0_w));
|
||||
map(0x72000010, 0x7200001f).rw(m_ata, FUNC(ata_interface_device::cs1_r), FUNC(ata_interface_device::cs1_w));
|
||||
map(0x73000000, 0x730000ff).rw(m_gcu, FUNC(k057714_device::read), FUNC(k057714_device::write));
|
||||
map(0x7ff00000, 0x7ff7ffff).mirror(0x00080000).rom().region("program", 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user