pushman: better understanding of how CPU reads MCU data/status

bballs: simplify protection MCU simulation using pushman hookup as a guide

(nw) bballs appears to use a simpler single-word arrangement for
messages from CPU to MCU, perhaps so it can use a 28-pin MCU (pushman
MCU receives the command byte on port D, which the 28-pin parts lack)
This commit is contained in:
Vas Crabb 2017-01-17 03:52:08 +11:00
parent 408a8fceb4
commit a3e60b3f3d
3 changed files with 66 additions and 74 deletions

View File

@ -87,15 +87,15 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( pushman_map, AS_PROGRAM, 16, pushman_state )
AM_IMPORT_FROM(main_map)
AM_RANGE(0x060000, 0x060001) AM_READWRITE(mcu_data_r, mcu_data_w)
AM_RANGE(0x060002, 0x600003) AM_WRITE(mcu_cmd_w)
AM_RANGE(0x060006, 0x060007) AM_READ(mcu_ack_r)
AM_RANGE(0x060000, 0x060007) AM_READ(mcu_comm_r)
AM_RANGE(0x060000, 0x060003) AM_WRITE(mcu_comm_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( bballs_map, AS_PROGRAM, 16, bballs_state )
ADDRESS_MAP_GLOBAL_MASK(0xfffff)
AM_RANGE(0x00000, 0x3ffff) AM_ROM
AM_RANGE(0x60000, 0x60007) AM_READWRITE(bballs_68705_r, bballs_68705_w)
AM_RANGE(0x60000, 0x60007) AM_READ(bballs_68705_r)
AM_RANGE(0x60000, 0x60003) AM_WRITE(bballs_68705_w)
// are these mirror addresses or does this PCB have a different addressing?
AM_RANGE(0xe0800, 0xe17ff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0xe4000, 0xe4001) AM_READ_PORT("P1_P2") AM_WRITE(tigeroad_videoctrl_w)
@ -685,6 +685,7 @@ MACHINE_CONFIG_END
void pushman_state::machine_start()
{
save_item(NAME(m_host_semaphore));
save_item(NAME(m_mcu_semaphore));
save_item(NAME(m_host_latch));
save_item(NAME(m_mcu_latch));
@ -705,17 +706,14 @@ MACHINE_CONFIG_END
MACHINE_RESET_MEMBER(bballs_state, bballs)
{
m_new_latch = 0;
m_latch = 0x400;
std::fill(std::begin(m_shared_ram), std::end(m_shared_ram), 0);
m_mcu_semaphore = false;
m_mcu_latch = 0x0400;
}
void bballs_state::machine_start()
{
save_item(NAME(m_shared_ram));
save_item(NAME(m_latch));
save_item(NAME(m_new_latch));
save_item(NAME(m_mcu_semaphore));
save_item(NAME(m_mcu_latch));
}
static MACHINE_CONFIG_DERIVED_CLASS(bballs, f1dream_comad, bballs_state)

View File

@ -72,6 +72,7 @@ public:
pushman_state(const machine_config &mconfig, device_type type, const char *tag)
: tigeroad_state(mconfig, type, tag)
, m_mcu(*this, "mcu")
, m_host_semaphore(false)
, m_mcu_semaphore(false)
, m_host_latch(0xffff)
, m_mcu_latch(0xffff)
@ -81,10 +82,8 @@ public:
m_has_coinlock = false;
}
DECLARE_READ16_MEMBER(mcu_data_r);
DECLARE_READ16_MEMBER(mcu_ack_r);
DECLARE_WRITE16_MEMBER(mcu_data_w);
DECLARE_WRITE16_MEMBER(mcu_cmd_w);
DECLARE_READ16_MEMBER(mcu_comm_r);
DECLARE_WRITE16_MEMBER(mcu_comm_w);
DECLARE_WRITE8_MEMBER(mcu_pa_w);
DECLARE_WRITE8_MEMBER(mcu_pb_w);
@ -95,7 +94,7 @@ protected:
required_device<m68705u_device> m_mcu;
bool m_mcu_semaphore;
bool m_host_semaphore, m_mcu_semaphore;
u16 m_host_latch, m_mcu_latch;
u16 m_mcu_output;
u8 m_mcu_latch_ctl;
@ -107,9 +106,8 @@ class bballs_state : public tigeroad_state
public:
bballs_state(const machine_config &mconfig, device_type type, const char *tag)
: tigeroad_state(mconfig, type, tag)
, m_shared_ram{ 0, 0, 0, 0, 0, 0, 0, 0 }
, m_latch(0xffff)
, m_new_latch(0)
, m_mcu_semaphore(false)
, m_mcu_latch(0xffff)
{
m_has_coinlock = false;
}
@ -118,12 +116,10 @@ public:
DECLARE_WRITE16_MEMBER(bballs_68705_w);
DECLARE_MACHINE_RESET(bballs);
DECLARE_DRIVER_INIT(bballs);
protected:
virtual void machine_start() override;
u8 m_shared_ram[8];
u16 m_latch;
u16 m_new_latch;
bool m_mcu_semaphore;
u16 m_mcu_latch;
};

View File

@ -124,35 +124,38 @@ WRITE16_MEMBER(tigeroad_state::f1dream_control_w)
}
READ16_MEMBER(pushman_state::mcu_data_r)
READ16_MEMBER(pushman_state::mcu_comm_r)
{
return m_mcu_latch;
}
READ16_MEMBER(pushman_state::mcu_ack_r)
{
if (m_mcu_semaphore)
switch (offset & 0x03)
{
m_mcu_semaphore = false;
return 0x0000;
case 0: // read and acknowledge MCU reply
if (!space.debugger_access())
m_mcu_semaphore = false;
return m_mcu_latch;
case 2: // expects bit 0 to be high when MCU has accepted command (other bits ignored)
return m_host_semaphore ? 0x0000 : 0x0001;
case 3: // expects bit 0 to be low when MCU has sent response (other bits ignored)
return m_mcu_semaphore ? 0x0000 : 0x0001;
}
else
logerror("unknown MCU read offset %X & %04X\n", offset, mem_mask);
return 0x0000;
}
WRITE16_MEMBER(pushman_state::mcu_comm_w)
{
switch (offset & 0x01)
{
return 0x00ff;
case 0:
COMBINE_DATA(&m_host_latch);
break;
case 1:
m_mcu->pd_w(space, 0, data & 0x00ff);
m_host_semaphore = true;
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
break;
}
}
WRITE16_MEMBER(pushman_state::mcu_data_w)
{
COMBINE_DATA(&m_host_latch);
}
WRITE16_MEMBER(pushman_state::mcu_cmd_w)
{
m_mcu->pd_w(space, 0, data & 0x00ff);
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
}
WRITE8_MEMBER(pushman_state::mcu_pa_w)
{
m_mcu_output = (m_mcu_output & 0xff00) | (u16(data) & 0x00ff);
@ -172,6 +175,7 @@ WRITE8_MEMBER(pushman_state::mcu_pc_w)
}
else
{
m_host_semaphore = false;
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
m_mcu->pa_w(space, 0, (m_host_latch >> 8) & 0x00ff);
m_mcu->pb_w(space, 0, (m_host_latch >> 0) & 0x00ff);
@ -190,41 +194,35 @@ WRITE8_MEMBER(pushman_state::mcu_pc_w)
/* ElSemi - Bouncing balls protection. */
READ16_MEMBER(bballs_state::bballs_68705_r)
{
if (offset == 0)
return m_latch;
if (offset == 3 && m_new_latch)
switch (offset)
{
m_new_latch = 0;
return 0;
case 0: // read and acknowledge MCU reply
if (!space.debugger_access())
m_mcu_semaphore = false;
return m_mcu_latch;
case 2: // pretend MCU accepts command instantly
return 0x0001;
case 3: // expects bit 0 to be low when MCU has sent response (other bits ignored)
return m_mcu_semaphore ? 0x0000 : 0x0001;
}
if (offset == 3 && !m_new_latch)
return 0xff;
return (m_shared_ram[2 * offset + 1] << 8) + m_shared_ram[2 * offset];
logerror("unknown 68705 read offset %X & %04X\n", offset, mem_mask);
return 0x0000;
}
WRITE16_MEMBER(bballs_state::bballs_68705_w)
{
if (ACCESSING_BITS_8_15)
m_shared_ram[2 * offset] = data >> 8;
if (ACCESSING_BITS_0_7)
m_shared_ram[2 * offset + 1] = data & 0xff;
if (offset == 0)
m_mcu_latch = 0;
if ((data >> 8) <= 0x0f)
{
m_latch = 0;
if (m_shared_ram[0] <= 0xf)
{
m_latch = m_shared_ram[0] << 2;
if (m_shared_ram[1])
m_latch |= 2;
m_new_latch = 1;
}
else if (m_shared_ram[0])
{
if (m_shared_ram[1])
m_latch |= 2;
m_new_latch = 1;
}
m_mcu_latch = (data >> 6) & 0x03fc;
if (data & 0x00ff)
m_mcu_latch |= 2;
m_mcu_semaphore = true;
}
else if (data >> 8)
{
if (data & 0x00ff)
m_mcu_latch |= 2;
m_mcu_semaphore = true;
}
}