pgm2: MCU HLE checkpoint (nw)

This commit is contained in:
MetalliC 2017-12-09 15:09:01 +02:00
parent 0133944497
commit 36fa2147af
2 changed files with 101 additions and 23 deletions

View File

@ -53,7 +53,7 @@
codepath that would not exist in a real environment at the moment) codepath that would not exist in a real environment at the moment)
Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests) Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests)
Debug features (require DIP SW1:8 On): Debug features (require DIP SW1:8 On and SW1:1 Off):
- QC TEST mode: hold P1 A+B during boot - QC TEST mode: hold P1 A+B during boot
- Debug/Cheat mode: hold P1 B+C during boot, when ingame pressing P1 Start skips to next location, where might be more unknown debug features. - Debug/Cheat mode: hold P1 B+C during boot, when ingame pressing P1 Start skips to next location, where might be more unknown debug features.
works for both currently dumped games (orleg2, kov2nl) works for both currently dumped games (orleg2, kov2nl)
@ -126,10 +126,87 @@ INTERRUPT_GEN_MEMBER(pgm2_state::igs_interrupt)
TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2) TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2)
{ {
int scanline = param; m_arm_aic->set_irq(0x46);
}
if(scanline == 0) // "MPU" MCU HLE starts here
m_arm_aic->set_irq(0x46); void pgm2_state::mcu_command(bool is_command)
{
uint8_t cmd = m_mcu_regs[0] & 0xff;
if (is_command && cmd != 0xf6)
logerror("MCU command %08x %08x\n", m_mcu_regs[0], m_mcu_regs[1]);
if (is_command)
{
m_mcu_last_cmd = cmd;
switch (cmd)
{
case 0xf6: // get result
m_mcu_regs[3] = m_mcu_result0;
m_mcu_regs[4] = m_mcu_result1;
m_mcu_timer->adjust(attotime::from_msec(1));
break;
case 0xe0: // command port test
m_mcu_result0 = m_mcu_regs[0];
m_mcu_result1 = m_mcu_regs[1];
m_mcu_timer->adjust(attotime::from_msec(30)); // such quite long delay is needed for debug codes check routine
break;
case 0xe1: // shared ram access (unimplemented)
{
// MCU access to RAM shared at 0x30100000, 2x banks, in the same time CPU and MCU access different banks
// where is offset ?
// uint8_t mode = m_mcu_regs[0] >> 16; // 0 - ???, 1 - read, 2 - write
// uint8_t data = m_mcu_regs[0] >> 24;
m_mcu_result0 = cmd;
m_mcu_result1 = 0;
m_mcu_timer->adjust(attotime::from_msec(1));
}
break;
case 0xc0: // unknown / unimplemented, most of them probably IC Card RW related
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
m_mcu_result0 = cmd;
m_mcu_result1 = 0;
m_mcu_timer->adjust(attotime::from_msec(1));
break;
default:
logerror("MCU unknown command %08x %08x\n", m_mcu_regs[0], m_mcu_regs[1]);
m_mcu_timer->adjust(attotime::from_msec(1));
break;
}
m_mcu_regs[3] = (m_mcu_regs[3] & 0xff00ffff) | 0x00F70000; // set "command accepted" status
}
else // next step
{
if (m_mcu_last_cmd && m_mcu_last_cmd != 0xf6)
{
m_mcu_regs[3] = (m_mcu_regs[3] & 0xff00ffff) | 0x00F20000; // set "command done and return data" status
m_mcu_timer->adjust(attotime::from_msec(1));
}
}
}
READ32_MEMBER(pgm2_state::mcu_r)
{
return m_mcu_regs[(offset >> 15) & 7];
}
WRITE32_MEMBER(pgm2_state::mcu_w)
{
int reg = (offset >> 15) & 7;
COMBINE_DATA(&m_mcu_regs[reg]);
if (reg == 2 && m_mcu_regs[2]) // irq to mcu
mcu_command(true);
if (reg == 5 && m_mcu_regs[5]) // ack to mcu (written at the end of irq handler routine)
mcu_command(false);
} }
static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state ) static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state )
@ -137,13 +214,7 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state )
AM_RANGE(0x02000000, 0x0200ffff) AM_RAM AM_SHARE("sram") // 'battery ram' (in CPU?) AM_RANGE(0x02000000, 0x0200ffff) AM_RAM AM_SHARE("sram") // 'battery ram' (in CPU?)
// could be the card reader, looks a bit like a standard IGS MCU comms protocol going on here AM_RANGE(0x03600000, 0x036bffff) AM_READWRITE(mcu_r, mcu_w)
AM_RANGE(0x03600000, 0x03600003) AM_WRITENOP
AM_RANGE(0x03620000, 0x03620003) AM_WRITENOP
AM_RANGE(0x03640000, 0x03640003) AM_WRITENOP
AM_RANGE(0x03660000, 0x03660003) AM_READ_PORT("UNK1")
AM_RANGE(0x03680000, 0x03680003) AM_READ_PORT("UNK2")
AM_RANGE(0x036a0000, 0x036a0003) AM_WRITENOP
AM_RANGE(0x03900000, 0x03900003) AM_READ_PORT("INPUTS0") AM_RANGE(0x03900000, 0x03900003) AM_READ_PORT("INPUTS0")
AM_RANGE(0x03a00000, 0x03a00003) AM_READ_PORT("INPUTS1") AM_RANGE(0x03a00000, 0x03a00003) AM_READ_PORT("INPUTS1")
@ -170,7 +241,7 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state )
what is the real size? */ what is the real size? */
AM_RANGE(0x300e0000, 0x300e03ff) AM_RAM AM_SHARE("lineram") AM_MIRROR(0x000fc00) AM_RANGE(0x300e0000, 0x300e03ff) AM_RAM AM_SHARE("lineram") AM_MIRROR(0x000fc00)
AM_RANGE(0x30100000, 0x301000ff) AM_RAM // unknown mask 00ff00ff, seems to be banked with 0x30120030 too? AM_RANGE(0x30100000, 0x301000ff) AM_RAM // MCU shared RAM, access at even bytes only (8bit device at 16bit bus?), 2x banks switched via 0x30120032 register (16bit)
AM_RANGE(0x30120000, 0x30120003) AM_RAM AM_SHARE("bgscroll") // scroll AM_RANGE(0x30120000, 0x30120003) AM_RAM AM_SHARE("bgscroll") // scroll
AM_RANGE(0x30120038, 0x3012003b) AM_WRITE(sprite_encryption_w) AM_RANGE(0x30120038, 0x3012003b) AM_WRITE(sprite_encryption_w)
@ -189,19 +260,11 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state )
AM_RANGE(0xfffffd28, 0xfffffd2b) AM_READ(rtc_r) AM_RANGE(0xfffffd28, 0xfffffd2b) AM_READ(rtc_r)
AM_RANGE(0xfffffa08, 0xfffffa0b) AM_WRITE(encryption_do_w) // after uploading encryption? table might actually send it or enable external ROM? AM_RANGE(0xfffffa08, 0xfffffa0b) AM_WRITE(encryption_do_w) // after uploading encryption? table might actually send it or enable external ROM? when read bits0-1 is ROM board status (0 if OK)
AM_RANGE(0xfffffa0c, 0xfffffa0f) AM_READ(unk_startup_r) AM_RANGE(0xfffffa0c, 0xfffffa0f) AM_READ(unk_startup_r)
ADDRESS_MAP_END ADDRESS_MAP_END
static INPUT_PORTS_START( pgm2 ) static INPUT_PORTS_START( pgm2 )
// probably not inputs
PORT_START("UNK1")
PORT_BIT( 0xffffffff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
// probably not inputs
PORT_START("UNK2")
PORT_BIT( 0xffffffff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("INPUTS0") PORT_START("INPUTS0")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
@ -300,12 +363,17 @@ void pgm2_state::machine_start()
save_item(NAME(m_has_decrypted)); save_item(NAME(m_has_decrypted));
save_item(NAME(m_spritekey)); save_item(NAME(m_spritekey));
save_item(NAME(m_realspritekey)); save_item(NAME(m_realspritekey));
save_item(NAME(m_mcu_regs));
save_item(NAME(m_mcu_result0));
save_item(NAME(m_mcu_result1));
save_item(NAME(m_mcu_last_cmd));
} }
void pgm2_state::machine_reset() void pgm2_state::machine_reset()
{ {
m_spritekey = 0; m_spritekey = 0;
m_realspritekey = 0; m_realspritekey = 0;
m_mcu_last_cmd = 0;
} }
static const gfx_layout tiles8x8_layout = static const gfx_layout tiles8x8_layout =
@ -348,7 +416,7 @@ static MACHINE_CONFIG_START( pgm2 )
MCFG_CPU_PROGRAM_MAP(pgm2_map) MCFG_CPU_PROGRAM_MAP(pgm2_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", pgm2_state, igs_interrupt) MCFG_CPU_VBLANK_INT_DRIVER("screen", pgm2_state, igs_interrupt)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", pgm2_state, igs_interrupt2, "screen", 0, 1) MCFG_TIMER_DRIVER_ADD("mcu_timer", pgm2_state, igs_interrupt2)
MCFG_ARM_AIC_ADD("arm_aic") MCFG_ARM_AIC_ADD("arm_aic")
MCFG_IRQ_LINE_CB(WRITELINE(pgm2_state, irq)) MCFG_IRQ_LINE_CB(WRITELINE(pgm2_state, irq))

View File

@ -38,13 +38,16 @@ public:
m_sprites_colour(*this, "sprites_colour"), m_sprites_colour(*this, "sprites_colour"),
m_sp_palette(*this, "sp_palette"), m_sp_palette(*this, "sp_palette"),
m_bg_palette(*this, "bg_palette"), m_bg_palette(*this, "bg_palette"),
m_tx_palette(*this, "tx_palette") m_tx_palette(*this, "tx_palette"),
m_mcu_timer(*this, "mcu_timer")
{ } { }
DECLARE_READ32_MEMBER(unk_startup_r); DECLARE_READ32_MEMBER(unk_startup_r);
DECLARE_READ32_MEMBER(rtc_r); DECLARE_READ32_MEMBER(rtc_r);
DECLARE_READ32_MEMBER(mcu_r);
DECLARE_WRITE32_MEMBER(fg_videoram_w); DECLARE_WRITE32_MEMBER(fg_videoram_w);
DECLARE_WRITE32_MEMBER(bg_videoram_w); DECLARE_WRITE32_MEMBER(bg_videoram_w);
DECLARE_WRITE32_MEMBER(mcu_w);
DECLARE_READ32_MEMBER(orleg2_speedup_r); DECLARE_READ32_MEMBER(orleg2_speedup_r);
DECLARE_READ32_MEMBER(kov2nl_speedup_r); DECLARE_READ32_MEMBER(kov2nl_speedup_r);
@ -104,6 +107,12 @@ private:
uint32_t m_realspritekey; uint32_t m_realspritekey;
int m_sprite_predecrypted; int m_sprite_predecrypted;
uint32_t m_mcu_regs[8];
uint32_t m_mcu_result0;
uint32_t m_mcu_result1;
uint8_t m_mcu_last_cmd;
void mcu_command(bool is_command);
// devices // devices
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
@ -122,6 +131,7 @@ private:
required_device<palette_device> m_sp_palette; required_device<palette_device> m_sp_palette;
required_device<palette_device> m_bg_palette; required_device<palette_device> m_bg_palette;
required_device<palette_device> m_tx_palette; required_device<palette_device> m_tx_palette;
required_device<timer_device> m_mcu_timer;
}; };
#endif #endif