kuniokun: Replace MCU simulation with actual dump [ShouTime, brizzo]

This commit is contained in:
AJR 2017-06-20 22:28:29 -04:00
parent 8bf9290a1e
commit fa3f8ec042
2 changed files with 19 additions and 301 deletions

View File

@ -19,7 +19,6 @@ IRQ is used to handle coin inputs
Known issues:
- coin counter isn't working properly (interrupt related?)
- kuniokun MCU internal ROM needs to be dumped
Memory Map (Preliminary):
@ -176,25 +175,6 @@ WRITE8_MEMBER(renegade_state::sound_w)
m_audiocpu->set_input_line(M6809_IRQ_LINE, HOLD_LINE);
}
/**************************************************************************/
/* MCU Simulation
**
** Renegade and Nekketsu Kouha Kunio Kun MCU behaviors are identical,
** except for the initial MCU status byte, and command encryption table
** (and enemy health??)
*/
static const uint8_t kuniokun_xor_table[0x2a] =
{
0x48, 0x8a, 0x48, 0xa5, 0x01, 0x48, 0xa9, 0x00,
0x85, 0x01, 0xa2, 0x10, 0x26, 0x10, 0x26, 0x11,
0x26, 0x01, 0xa5, 0x01, 0xc5, 0x00, 0x90, 0x04,
0xe5, 0x00, 0x85, 0x01, 0x26, 0x10, 0x26, 0x11,
0xca, 0xd0, 0xed, 0x68, 0x85, 0x01, 0x68, 0xaa,
0x68, 0x60
};
void renegade_state::machine_start()
{
m_rombank->configure_entries(0, 2, memregion("maincpu")->base(), 0x4000);
@ -204,276 +184,22 @@ void renegade_state::machine_start()
save_item(NAME(m_adpcm_playing));
}
DRIVER_INIT_MEMBER(renegade_state, renegade)
{
m_mcu_sim = false;
}
DRIVER_INIT_MEMBER(renegade_state, kuniokun)
{
m_mcu_sim = true;
m_mcu_checksum = 0x85;
m_mcu_encrypt_table = kuniokun_xor_table;
m_mcu_encrypt_table_len = 0x2a;
subdevice("mcu:mcu")->execute().suspend(SUSPEND_REASON_DISABLE, 1);
save_item(NAME(m_mcu_buffer));
save_item(NAME(m_mcu_input_size));
save_item(NAME(m_mcu_output_byte));
save_item(NAME(m_mcu_key));
}
DRIVER_INIT_MEMBER(renegade_state, kuniokunb)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
/* Remove the MCU handlers */
space.unmap_readwrite(0x3804, 0x3804);
space.unmap_read(0x3805, 0x3805);
}
/***************************************************************************
MCU simulation
MCU interface
***************************************************************************/
READ8_MEMBER(renegade_state::mcu_reset_r)
{
if (m_mcu_sim == true)
{
m_mcu_key = -1;
m_mcu_input_size = 0;
m_mcu_output_byte = 0;
}
else
{
m_mcu->reset_w(PULSE_LINE);
}
m_mcu->reset_w(PULSE_LINE);
return 0;
}
WRITE8_MEMBER(renegade_state::mcu_w)
{
if (m_mcu_sim == true)
{
m_mcu_output_byte = 0;
if (m_mcu_key < 0)
{
m_mcu_key = 0;
m_mcu_input_size = 1;
m_mcu_buffer[0] = data;
}
else
{
data ^= m_mcu_encrypt_table[m_mcu_key++];
if (m_mcu_key == m_mcu_encrypt_table_len)
m_mcu_key = 0;
if (m_mcu_input_size < MCU_BUFFER_MAX)
m_mcu_buffer[m_mcu_input_size++] = data;
}
}
else
{
m_mcu->data_w(space, offset, data, mem_mask);
}
}
void renegade_state::mcu_process_command()
{
m_mcu_input_size = 0;
m_mcu_output_byte = 0;
switch (m_mcu_buffer[0])
{
/* 0x0d: stop MCU when ROM check fails */
case 0x10:
m_mcu_buffer[0] = m_mcu_checksum;
break;
case 0x26: /* sound code -> sound command */
{
int sound_code = m_mcu_buffer[1];
static const uint8_t sound_command_table[256] =
{
0xa0, 0xa1, 0xa2, 0x80, 0x81, 0x82, 0x83, 0x84,
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
0x8d, 0x8e, 0x8f, 0x97, 0x96, 0x9b, 0x9a, 0x95,
0x9e, 0x98, 0x90, 0x93, 0x9d, 0x9c, 0xa3, 0x91,
0x9f, 0x99, 0xa6, 0xae, 0x94, 0xa5, 0xa4, 0xa7,
0x92, 0xab, 0xac, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
0x50, 0x50, 0x90, 0x30, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xa0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x90,
0x30, 0x30, 0x30, 0xb0, 0xb0, 0xb0, 0xb0, 0xf0,
0xf0, 0xf0, 0xf0, 0xd0, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x10, 0x10, 0x50, 0x30, 0xb0, 0xb0, 0xf0,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x10, 0x10, 0x30, 0x30, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x8f, 0x8f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
0xef, 0xef, 0xcf, 0x8f, 0x8f, 0x0f, 0x0f, 0x0f
};
m_mcu_buffer[0] = 1;
m_mcu_buffer[1] = sound_command_table[sound_code];
}
break;
case 0x33: /* joy bits -> joy dir */
{
int joy_bits = m_mcu_buffer[2];
static const uint8_t joy_table[0x10] =
{
0, 3, 7, 0, 1, 2, 8, 0, 5, 4, 6, 0, 0, 0, 0, 0
};
m_mcu_buffer[0] = 1;
m_mcu_buffer[1] = joy_table[joy_bits & 0xf];
}
break;
case 0x44: /* 0x44, 0xff, DSW2, stage# -> difficulty */
{
int difficulty = m_mcu_buffer[2] & 0x3;
int stage = m_mcu_buffer[3];
static const uint8_t difficulty_table[4] = { 5, 3, 1, 2 };
int result = difficulty_table[difficulty];
if (stage == 0)
result--;
result += stage / 4;
if (result > 0x21)
result += 0xc0;
m_mcu_buffer[0] = 1;
m_mcu_buffer[1] = result;
}
break;
case 0x55: /* 0x55, 0x00, 0x00, 0x00, DSW2 -> timer */
{
int difficulty = m_mcu_buffer[4] & 0x3;
static const uint16_t table[4] =
{
0x4001, 0x5001, 0x1502, 0x0002
};
m_mcu_buffer[0] = 3;
m_mcu_buffer[2] = table[difficulty] >> 8;
m_mcu_buffer[3] = table[difficulty] & 0xff;
}
break;
case 0x41: /* 0x41, 0x00, 0x00, stage# -> ? */
{
// int stage = m_mcu_buffer[3];
m_mcu_buffer[0] = 2;
m_mcu_buffer[1] = 0x20;
m_mcu_buffer[2] = 0x78;
}
break;
case 0x40: /* 0x40, 0x00, difficulty, enemy_type -> enemy health */
{
int difficulty = m_mcu_buffer[2];
int enemy_type = m_mcu_buffer[3];
int health;
if (enemy_type <= 4)
{
health = 0x18 + difficulty * 2;
if (health > 0x40)
health = 0x40; /* max 0x40 */
}
else
{
health = 0x06 + difficulty * 2;
if (health > 0x20)
health = 0x20; /* max 0x20 */
}
logerror("e_type:0x%02x diff:0x%02x -> 0x%02x\n", enemy_type, difficulty, health);
m_mcu_buffer[0] = 1;
m_mcu_buffer[1] = health;
}
break;
case 0x42: /* 0x42, 0x00, stage#, character# -> enemy_type */
{
int stage = m_mcu_buffer[2] & 0x3;
int indx = m_mcu_buffer[3];
int enemy_type=0;
static const int table[] =
{
0x01, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, /* for stage#: 0 */
0x02, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, /* for stage#: 1 */
0x03, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, /* for stage#: 2 */
0x04, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, /* for stage#: 3 */
0x3d, 0x23, 0x26, 0x0a, 0xb6, 0x11, 0xa4, 0x0f, /* strange data (maybe out of table) */
};
int offset = stage * 8 + indx;
if (stage >= 2)
offset--;
enemy_type = table[offset];
m_mcu_buffer[0] = 1;
m_mcu_buffer[1] = enemy_type;
}
break;
default:
logerror("unknown MCU command: %02x\n", m_mcu_buffer[0]);
break;
}
}
READ8_MEMBER(renegade_state::mcu_r)
{
if (m_mcu_sim == true)
{
int result = 1;
if (m_mcu_input_size)
mcu_process_command();
if (m_mcu_output_byte < MCU_BUFFER_MAX)
result = m_mcu_buffer[m_mcu_output_byte++];
return result;
}
else
{
return m_mcu->data_r(space, offset, mem_mask);
}
}
CUSTOM_INPUT_MEMBER(renegade_state::mcu_status_r)
{
if (m_mcu_sim == true)
{
return 0x01;
}
else if (m_mcu)
if (m_mcu.found())
{
return
((CLEAR_LINE == m_mcu->host_semaphore_r()) ? 0x01 : 0x00) |
@ -510,7 +236,7 @@ WRITE8_MEMBER(renegade_state::coincounter_w)
/********************************************************************************************/
static ADDRESS_MAP_START( renegade_map, AS_PROGRAM, 8, renegade_state )
static ADDRESS_MAP_START( renegade_nomcu_map, AS_PROGRAM, 8, renegade_state )
AM_RANGE(0x0000, 0x17ff) AM_RAM
AM_RANGE(0x1800, 0x1fff) AM_RAM_WRITE(fg_videoram_w) AM_SHARE("fg_videoram")
AM_RANGE(0x2000, 0x27ff) AM_RAM AM_SHARE("spriteram")
@ -521,14 +247,19 @@ static ADDRESS_MAP_START( renegade_map, AS_PROGRAM, 8, renegade_state )
AM_RANGE(0x3801, 0x3801) AM_READ_PORT("IN1") AM_WRITE(scroll_msb_w) /* Player#2 controls, coin triggers */
AM_RANGE(0x3802, 0x3802) AM_READ_PORT("DSW2") AM_WRITE(sound_w) /* DIP2 various IO ports */
AM_RANGE(0x3803, 0x3803) AM_READ_PORT("DSW1") AM_WRITE(flipscreen_w) /* DIP1 */
AM_RANGE(0x3804, 0x3804) AM_READWRITE(mcu_r, mcu_w)
AM_RANGE(0x3805, 0x3805) AM_READWRITE(mcu_reset_r, bankswitch_w)
AM_RANGE(0x3805, 0x3805) AM_READNOP AM_WRITE(bankswitch_w)
AM_RANGE(0x3806, 0x3806) AM_WRITENOP // ?? watchdog
AM_RANGE(0x3807, 0x3807) AM_WRITE(coincounter_w)
AM_RANGE(0x4000, 0x7fff) AM_ROMBANK("rombank")
AM_RANGE(0x8000, 0xffff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START( renegade_map, AS_PROGRAM, 8, renegade_state )
AM_RANGE(0x3804, 0x3804) AM_DEVREADWRITE("mcu", taito68705_mcu_device, data_r, data_w)
AM_RANGE(0x3805, 0x3805) AM_READ(mcu_reset_r)
AM_IMPORT_FROM(renegade_nomcu_map)
ADDRESS_MAP_END
static ADDRESS_MAP_START( renegade_sound_map, AS_PROGRAM, 8, renegade_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM
AM_RANGE(0x1000, 0x1000) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
@ -780,6 +511,9 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( kuniokunb, renegade )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(renegade_nomcu_map)
MCFG_DEVICE_REMOVE("mcu")
MACHINE_CONFIG_END
@ -834,8 +568,8 @@ ROM_START( kuniokun )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "n0-5.bin", 0x8000, 0x8000, CRC(3587de3b) SHA1(f82e758254b21eb0c5a02469c72adb86d9577065) )
ROM_REGION( 0x0800, "mcu:mcu", 0 )
ROM_LOAD( "mcu", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x0800, "mcu:mcu", 0 ) // MC68705P3
ROM_LOAD( "nz-0.bin", 0x0000, 0x0800, CRC(650bb5f0) SHA1(56a9679e3265de244ce2191a81b709992f012111) )
ROM_REGION( 0x08000, "chars", 0 )
ROM_LOAD( "ta18-25.bin", 0x0000, 0x8000, CRC(9bd2bea3) SHA1(fa79c9d4c71c1dbbf0e14cb8d6870f1f94b9af88) )
@ -909,6 +643,6 @@ ROM_END
GAME( 1986, renegade, 0, renegade, renegade, renegade_state, renegade, ROT0, "Technos Japan (Taito America license)", "Renegade (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, kuniokun, renegade, renegade, renegade, renegade_state, kuniokun, ROT0, "Technos Japan", "Nekketsu Kouha Kunio-kun (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, kuniokunb, renegade, kuniokunb, renegade, renegade_state, kuniokunb, ROT0, "bootleg", "Nekketsu Kouha Kunio-kun (Japan bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, renegade, 0, renegade, renegade, renegade_state, 0, ROT0, "Technos Japan (Taito America license)", "Renegade (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, kuniokun, renegade, renegade, renegade, renegade_state, 0, ROT0, "Technos Japan", "Nekketsu Kouha Kunio-kun (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, kuniokunb, renegade, kuniokunb, renegade, renegade_state, 0, ROT0, "bootleg", "Nekketsu Kouha Kunio-kun (Japan bootleg)", MACHINE_SUPPORTS_SAVE )

View File

@ -6,8 +6,6 @@
#include "machine/gen_latch.h"
#include "sound/msm5205.h"
#define MCU_BUFFER_MAX 6
class renegade_state : public driver_device
{
public:
@ -46,25 +44,14 @@ public:
uint32_t m_adpcm_end;
bool m_adpcm_playing;
bool m_mcu_sim;
uint8_t m_mcu_buffer[MCU_BUFFER_MAX];
uint8_t m_mcu_input_size;
uint8_t m_mcu_output_byte;
int8_t m_mcu_key;
int m_mcu_checksum;
const uint8_t *m_mcu_encrypt_table;
int m_mcu_encrypt_table_len;
int32_t m_scrollx;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
DECLARE_WRITE8_MEMBER(sound_w);
DECLARE_READ8_MEMBER(mcu_reset_r);
DECLARE_WRITE8_MEMBER(mcu_w);
DECLARE_READ8_MEMBER(mcu_r);
DECLARE_WRITE8_MEMBER(bankswitch_w);
DECLARE_WRITE8_MEMBER(coincounter_w);
void mcu_process_command();
DECLARE_WRITE8_MEMBER(fg_videoram_w);
DECLARE_WRITE8_MEMBER(bg_videoram_w);
DECLARE_WRITE8_MEMBER(flipscreen_w);
@ -81,9 +68,6 @@ public:
TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
DECLARE_DRIVER_INIT(kuniokun);
DECLARE_DRIVER_INIT(kuniokunb);
DECLARE_DRIVER_INIT(renegade);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;