arkanoid: convert 68705 interface to device, re-use same device for puzznic, eliminate puzznic protection hacks

This commit is contained in:
Vas Crabb 2017-01-13 15:59:44 +11:00
parent c8fc908f98
commit 48c6dfbc55
10 changed files with 367 additions and 322 deletions

View File

@ -279,9 +279,7 @@ template <std::size_t N> WRITE8_MEMBER(m68705_new_device::port_ddr_w)
template <std::size_t N> void m68705_new_device::port_cb_w()
{
u8 const data(m_port_open_drain[N]
? m_port_latch[N] | ~m_port_ddr[N]
: (m_port_latch[N] & m_port_ddr[N]) | (m_port_input[N] & ~m_port_ddr[N]));
u8 const data(m_port_open_drain[N] ? m_port_latch[N] | ~m_port_ddr[N] : m_port_latch[N]);
u8 const mask(m_port_open_drain[N] ? (~m_port_latch[N] & m_port_ddr[N]) : m_port_ddr[N]);
m_port_cb_w[N](space(AS_PROGRAM), 0, data, mask);
}

View File

@ -82,20 +82,20 @@ public:
// static configuration helpers
// TODO: REMOVE THESE
template<class _Object> static devcb_base &set_readpa_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_in_a_handler.set_callback(object); }
template<class _Object> static devcb_base &set_readpb_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_in_b_handler.set_callback(object); }
template<class _Object> static devcb_base &set_readca1_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_in_ca1_handler.set_callback(object); }
template<class _Object> static devcb_base &set_readca2_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_in_ca2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_readcb1_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_in_cb1_handler.set_callback(object); }
template<class Obj> static devcb_base &set_readpa_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_in_a_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_readpb_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_in_b_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_readca1_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_in_ca1_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_readca2_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_in_ca2_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_readcb1_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_in_cb1_handler.set_callback(std::forward<Obj>(object)); }
// TODO: CONVERT THESE TO WRITE LINE
template<class _Object> static devcb_base &set_writepa_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_out_a_handler.set_callback(object); }
template<class _Object> static devcb_base &set_writepb_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_out_b_handler.set_callback(object); }
template<class Obj> static devcb_base &set_writepa_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_out_a_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_writepb_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_out_b_handler.set_callback(std::forward<Obj>(object)); }
template<class _Object> static devcb_base &set_ca2_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_ca2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_cb2_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_cb2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_irqa_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_irqa_handler.set_callback(object); }
template<class _Object> static devcb_base &set_irqb_handler(device_t &device, _Object object) { return downcast<pia6821_device &>(device).m_irqb_handler.set_callback(object); }
template<class Obj> static devcb_base &set_ca2_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_ca2_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_cb2_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_cb2_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_irqa_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_irqa_handler.set_callback(std::forward<Obj>(object)); }
template<class Obj> static devcb_base &set_irqb_handler(device_t &device, Obj &&object) { return downcast<pia6821_device &>(device).m_irqb_handler.set_callback(std::forward<Obj>(object)); }
DECLARE_READ8_MEMBER( read ) { return reg_r(offset); }
DECLARE_WRITE8_MEMBER( write ) { reg_w(offset, data); }

View File

@ -784,10 +784,11 @@ DIP locations verified for:
***************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "includes/arkanoid.h"
#include "sound/ay8910.h"
#include "cpu/z80/z80.h"
#include "machine/watchdog.h"
#include "sound/ay8910.h"
/***************************************************************************/
@ -801,7 +802,7 @@ static ADDRESS_MAP_START( arkanoid_map, AS_PROGRAM, 8, arkanoid_state )
AM_RANGE(0xd008, 0xd008) AM_WRITE(arkanoid_d008_w) /* gfx bank, flip screen, 68705 reset, etc. */
AM_RANGE(0xd00c, 0xd00c) AM_READ_PORT("SYSTEM") /* 2 bits from the 68705 */
AM_RANGE(0xd010, 0xd010) AM_READ_PORT("BUTTONS") AM_DEVWRITE("watchdog", watchdog_timer_device, reset_w)
AM_RANGE(0xd018, 0xd018) AM_READWRITE(arkanoid_Z80_mcu_r, arkanoid_Z80_mcu_w) /* input from the 68705 */
AM_RANGE(0xd018, 0xd018) AM_DEVREADWRITE("mcu", arkanoid_mcu_device_base, data_r, data_w) /* input from the 68705 */
AM_RANGE(0xe000, 0xe7ff) AM_RAM_WRITE(arkanoid_videoram_w) AM_SHARE("videoram")
AM_RANGE(0xe800, 0xe83f) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0xe840, 0xefff) AM_RAM
@ -967,7 +968,7 @@ static INPUT_PORTS_START( arkanoid )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, arkanoid_state,arkanoid_semaphore_input_r, nullptr) /* Z80 and MCU Semaphores */
PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("mcu", arkanoid_mcu_device_base, semaphore_r, nullptr) /* Z80 and MCU Semaphores */
PORT_START("BUTTONS")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
@ -1257,7 +1258,6 @@ GFXDECODE_END
void arkanoid_state::machine_start()
{
save_item(NAME(m_gfxbank));
save_item(NAME(m_palettebank));
@ -1265,17 +1265,6 @@ void arkanoid_state::machine_start()
save_item(NAME(m_bootleg_id));
save_item(NAME(m_bootleg_cmd));
save_item(NAME(m_Z80HasWritten));
save_item(NAME(m_fromZ80));
save_item(NAME(m_MCUHasWritten));
save_item(NAME(m_fromMCU));
save_item(NAME(m_portA_in));
save_item(NAME(m_portA_out));
save_item(NAME(m_old_portC_out));
}
void arkanoid_state::machine_reset()
@ -1286,19 +1275,6 @@ void arkanoid_state::machine_reset()
m_paddle_select = 0;
m_bootleg_cmd = 0;
// latched data bytes
m_fromZ80 = 0;
m_fromMCU = 0;
// the following 3 are all part of the 74ls74 at ic26 and are cleared on reset
m_Z80HasWritten = 0;
m_MCUHasWritten = 0;
m_portA_in = 0;
m_portA_out = 0;
m_old_portC_out = 0;
if (m_mcu.found()) m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
/*
@ -1321,13 +1297,8 @@ static MACHINE_CONFIG_START( arkanoid, arkanoid_state )
MCFG_WATCHDOG_ADD("watchdog")
MCFG_CPU_ADD("mcu", M68705P5, XTAL_12MHz/4) /* verified on pcb */
MCFG_M68705_PORTA_R_CB(READ8(arkanoid_state, mcu_porta_r))
MCFG_M68705_PORTA_W_CB(WRITE8(arkanoid_state, mcu_porta_w))
MCFG_M68705_PORTB_R_CB(READ8(arkanoid_state, mcu_portb_r))
MCFG_M68705_PORTC_R_CB(READ8(arkanoid_state, mcu_portc_r))
MCFG_M68705_PORTC_W_CB(WRITE8(arkanoid_state, mcu_portc_w))
MCFG_DEVICE_ADD("mcu", ARKANOID_68705P5, XTAL_12MHz/4) /* verified on pcb */
MCFG_ARKANOID_MCU_PORTB_R_CB(IOPORT("MUX"))
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) // 100 CPU slices per second to synchronize between the MCU and the main CPU
@ -1483,7 +1454,7 @@ ROM_START( arkanoid ) // v1.0 World
ROM_LOAD( "a75-01-1.ic17", 0x0000, 0x8000, CRC(5bcda3b0) SHA1(52cadd38b5f8e8856f007a9c602d6b508f30be65) )
ROM_LOAD( "a75-11.ic16", 0x8000, 0x8000, CRC(eafd7191) SHA1(d2f8843b716718b1de209e97a874e8ce600f3f87) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75__06.ic14", 0x0000, 0x0800, CRC(0be83647) SHA1(625fd1e6061123df612f115ef14a06cd6009f5d1) ) // verified authentic v1.x MCU from Taito/Romstar Board
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1508,7 +1479,7 @@ ROM_START( arkanoidu ) // V2.0 US/Romstar
ROM_LOAD( "a75-19.ic17", 0x0000, 0x8000, CRC(d3ad37d7) SHA1(a172a1ef5bb83ee2d8ed2842ef8968af19ad411e) )
ROM_LOAD( "a75-18.ic16", 0x8000, 0x8000, CRC(cdc08301) SHA1(05f54353cc8333af14fa985a2764960e20e8161a) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75-20.ic14", 0x0000, 0x0800, BAD_DUMP CRC(de518e47) SHA1(b8eddd1c566505fb69e3d1207c7a9720dfb9f503) ) /* Hand crafted based on the bootleg a75-06 chip, need the real data here */
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1528,7 +1499,7 @@ ROM_START( arkanoiduo ) // V1.0 USA/Romstar
ROM_LOAD( "a75__01-1.ic17", 0x0000, 0x8000, CRC(5bcda3b0) SHA1(52cadd38b5f8e8856f007a9c602d6b508f30be65) )
ROM_LOAD( "a75__10.ic16", 0x8000, 0x8000, CRC(a1769e15) SHA1(fbb45731246a098b29eb08de5d63074b496aaaba) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75__06.ic14", 0x0000, 0x0800, CRC(0be83647) SHA1(625fd1e6061123df612f115ef14a06cd6009f5d1) ) // verified authentic v1.x MCU from Taito/Romstar Board
ROM_REGION( 0x18000, "gfx1", 0 ) /* Silkscreen: "IC62 27128/256", "IC63 27128/256", "IC64 27128/256" */
@ -1550,7 +1521,7 @@ ROM_START( arkanoidj ) // V2.1 Japan
ROM_LOAD( "a75_24.ic17", 0x0000, 0x8000, CRC(3f2b27e9) SHA1(656035f5292d6921448e74d3e1abab57b46e7d9e) )
ROM_LOAD( "a75_25.ic16", 0x8000, 0x8000, CRC(c13b2038) SHA1(0b8197b48e57ffe9ccad0ebbc24891d1da7c9880) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75-26.ic14", 0x0000, 0x0800, BAD_DUMP CRC(962960d4) SHA1(64b065a54b1658364db569ac06b717eb7bdd186e) ) /* Hand crafted based on the bootleg a75-06 chip, need the real data here */
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1569,7 +1540,7 @@ ROM_START( arkanoidja ) // V2.0 Japan w/level select
ROM_LOAD( "a75-21.ic17", 0x0000, 0x8000, CRC(bf0455fc) SHA1(250522b84b9f491c3f4efc391bf6aa6124361369) )
ROM_LOAD( "a75-22.ic16", 0x8000, 0x8000, CRC(3a2688d3) SHA1(9633a661352def3d85f95ca830f6d761b0b5450e) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
// the handcrafted value at 0x351 (0x9ddb) seems incorrect compared to other sets? (but it appears the value is never used, and the data it would usually point to does not exist in the program rom?)
ROM_LOAD( "a75-23.ic14", 0x0000, 0x0800, BAD_DUMP CRC(0a4abef6) SHA1(fdce0b7a2eab7fd4f1f4fc3b93120b1ebc16078e) ) /* Hand crafted based on the bootleg a75-06 chip, need the real data here */
@ -1589,7 +1560,7 @@ ROM_START( arkanoidjb ) // V1.1 Japan
ROM_LOAD( "a75-01-1.ic17", 0x0000, 0x8000, CRC(5bcda3b0) SHA1(52cadd38b5f8e8856f007a9c602d6b508f30be65) )
ROM_LOAD( "a75-02.ic16", 0x8000, 0x8000, CRC(bbc33ceb) SHA1(e9b6fef98d0d20e77c7a1c25eff8e9a8c668a258) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75__06.ic14", 0x0000, 0x0800, CRC(0be83647) SHA1(625fd1e6061123df612f115ef14a06cd6009f5d1) ) // verified authentic v1.x MCU from Taito/Romstar Board
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1609,7 +1580,7 @@ ROM_START( arkatour ) // Tournament version
ROM_LOAD( "a75-27.ic17", 0x0000, 0x8000, CRC(e3b8faf5) SHA1(4c09478fa41881fa89ee6afb676aeb780f17ac2e) )
ROM_LOAD( "a75-28.ic16", 0x8000, 0x8000, CRC(326aca4d) SHA1(5a194b7a0361236d471b24905dc6434372f81252) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75-32.ic14", 0x0000, 0x0800, BAD_DUMP CRC(d3249559) SHA1(b1542764450016614e9e03cedd6a2f1e59961789) ) /* Hand crafted based on the bootleg a75-06 chip, need the real data here */
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1630,7 +1601,7 @@ ROM_START( arkanoidjbl ) // bootleg with MCU copied from real Taito code, but no
ROM_LOAD( "e1.6d", 0x0000, 0x8000, CRC(dd4f2b72) SHA1(399a8636030a702dafc1da926f115df6f045bef1) ) /* Hacked up Notice warning text */
ROM_LOAD( "e2.6f", 0x8000, 0x8000, CRC(bbc33ceb) SHA1(e9b6fef98d0d20e77c7a1c25eff8e9a8c668a258) ) /* == A75-02.IC16 */
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "68705p3.6i", 0x0000, 0x0800, CRC(389a8cfb) SHA1(9530c051b61b5bdec7018c6fdc1ea91288a406bd) ) // This set had an unprotected mcu with a bootlegged copy of the real Taito a75__06.ic14 code, unlike the other bootlegs. It has the bootstrap code missing and the security bit cleared, the area after the rom filled with 0x00, and the verify mode disable jump removed. Otherwise it matches a75__06.ic14
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1650,7 +1621,7 @@ ROM_START( arkanoidjbl2 ) // Bootleg with ??? MCU, probably the a75-06__bootleg_
ROM_LOAD( "1.ic81", 0x0000, 0x8000, CRC(9ff93dc2) SHA1(eee0975b799a8e6717f646dd40716dc454476106) )
ROM_LOAD( "2.ic82", 0x8000, 0x8000, CRC(bbc33ceb) SHA1(e9b6fef98d0d20e77c7a1c25eff8e9a8c668a258) ) /* == A75-02.IC16 */
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75-06__bootleg_68705.ic14", 0x0000, 0x0800, BAD_DUMP CRC(515d77b6) SHA1(a302937683d11f663abd56a2fd7c174374e4d7fb) ) /* Uses the bootleg MCU? Not sure what mcu is supposed to go with this set... */
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1670,7 +1641,7 @@ ROM_START( ark1ball ) /* This set requires a MCU. No MCU rom was supplied so we
ROM_LOAD( "2palline.7f", 0x8000, 0x8000, CRC(ed6b62ab) SHA1(4d4991b422756bd304fc5ef236aac1422fe1f999) )
/* Use the current A75-06.IC14 MCU code so the game is playable */
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a75-06__bootleg_68705.ic14", 0x0000, 0x0800, BAD_DUMP CRC(515d77b6) SHA1(a302937683d11f663abd56a2fd7c174374e4d7fb) ) /* Uses the bootleg MCU? Not sure what mcu is supposed to go with this set... */
ROM_REGION( 0x18000, "gfx1", 0 )
@ -1981,7 +1952,7 @@ ROM_START( brixian )
ROM_LOAD( "b1.bin", 0x00000, 0x8000, CRC(3d167d09) SHA1(1d5bd098b655b8d2f956cfcb718213915bee3e41) )
ROM_LOAD( "e7.bin", 0x08000, 0x2000, CRC(9e3707ab) SHA1(a04fb4824239f8ed1ef1de2f3c0f9d749320b2ba) )
ROM_REGION( 0x0800, "mcu", 0 )
ROM_REGION( 0x0800, "mcu:mcu", 0 )
ROM_LOAD( "68705p5", 0x0000, 0x0800, NO_DUMP ) // this just provides the 0x200 bytes of code we load in the protdata region by coping it to 0xc600 on startup
ROM_REGION( 0x200, "protdata", 0 )

View File

@ -33,8 +33,6 @@ TODO:
- plgirls doesn't work without a kludge because of an interrupt issue. This
happens because the program enables interrupts before setting IM2, so the
interrupt vector is interpreted as IM0, which is obviously bogus.
- The puzznic protection is worked around, but I'm not happy with it
(the 68705-returned values are wrong, I'm sure of that).
- A bunch of control registers are simply ignored
- The source of irqs 0 and 1 is unknown, while 2 is vblank (0 is
usually ignored by the program, 1 leads to reading the
@ -57,6 +55,7 @@ puzznici note
#include "emu.h"
#include "includes/taito_l.h"
#include "includes/taitoipt.h"
#include "machine/taito68705interface.h"
#include "audio/taitosnd.h"
@ -91,8 +90,6 @@ struct
{ &taitol_state::taitol_chardef1f_m, 0x7000 }, // 1f
};
u8 const puzznic_mcu_reply[] = { 0x50, 0x1f, 0xb6, 0xba, 0x06, 0x03, 0x47, 0x05, 0x00 };
} // anonymous namespace
@ -157,16 +154,6 @@ void taitol_1cpu_state::state_register()
save_item(NAME(m_extport));
}
void puzznic_state::state_register()
{
taitol_1cpu_state::state_register();
save_item(NAME(m_mcu_pos));
save_item(NAME(m_mcu_reply_len));
save_item(NAME(m_last_data_adr));
save_item(NAME(m_last_data));
}
void horshoes_state::state_register()
{
taitol_1cpu_state::state_register();
@ -246,15 +233,6 @@ void taitol_1cpu_state::taito_machine_reset()
m_extport = 0;
}
void puzznic_state::taito_machine_reset()
{
taitol_1cpu_state::taito_machine_reset();
m_mcu_reply = puzznic_mcu_reply;
m_mcu_pos = m_mcu_reply_len = 0;
m_last_data_adr = m_last_data = 0;
}
void horshoes_state::taito_machine_reset()
{
taitol_1cpu_state::taito_machine_reset();
@ -504,34 +482,11 @@ READ8_MEMBER(taitol_1cpu_state::extport_select_and_ym2203_r)
return m_ymsnd->read(space, offset & 1);
}
WRITE8_MEMBER(puzznic_state::mcu_data_w)
{
m_last_data = data;
m_last_data_adr = space.device().safe_pc();
// logerror("mcu write %02x (%04x)\n", data, space.device().safe_pc());
switch (data)
{
case 0x43:
m_mcu_pos = 0;
m_mcu_reply_len = ARRAY_LENGTH(puzznic_mcu_reply);
break;
}
}
WRITE8_MEMBER(taitol_state::mcu_control_w)
{
// logerror("mcu control %02x (%04x)\n", data, space.device().safe_pc());
}
READ8_MEMBER(puzznic_state::mcu_data_r)
{
// logerror("mcu read (%04x) [%02x, %04x]\n", space.device().safe_pc(), last_data, last_data_adr);
if (m_mcu_pos == m_mcu_reply_len)
return 0;
return m_mcu_reply[m_mcu_pos++];
}
READ8_MEMBER(taitol_state::mcu_control_r)
{
// logerror("mcu control read (%04x)\n", space.device().safe_pc());
@ -810,12 +765,11 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( puzznic_map, AS_PROGRAM, 8, puzznic_state )
static ADDRESS_MAP_START( puzznic_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0xa800, 0xa800) AM_READNOP // Watchdog
AM_RANGE(0xb000, 0xb7ff) AM_RAM // Wrong, used to overcome protection
AM_RANGE(0xb800, 0xb800) AM_READWRITE(mcu_data_r, mcu_data_w)
AM_RANGE(0xb800, 0xb800) AM_DEVREADWRITE("mcu", arkanoid_68705p3_device, data_r, data_w)
AM_RANGE(0xb801, 0xb801) AM_READWRITE(mcu_control_r, mcu_control_w)
AM_RANGE(0xbc00, 0xbc00) AM_WRITENOP // Control register, function unknown
ADDRESS_MAP_END
@ -1931,12 +1885,14 @@ static MACHINE_CONFIG_START( plotting, taitol_1cpu_state )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED_CLASS( puzznic, plotting, puzznic_state )
static MACHINE_CONFIG_DERIVED( puzznic, plotting )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(puzznic_map)
MCFG_DEVICE_ADD("mcu", ARKANOID_68705P3, XTAL_13_33056MHz / 4) /* clock is complete guess */
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, puzznic)
MACHINE_CONFIG_END
@ -2344,7 +2300,7 @@ ROM_START( puzznic )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "c20-09.ic11", 0x00000, 0x20000, CRC(156d6de1) SHA1(c247936b62ef354851c9bace76a7a0aa14194d5f) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "mc68705p3.ic4", 0x0000, 0x0800, CRC(085f68b4) SHA1(2dbc7e2c015220dc59ee1f1208540744e5b9b7cc) )
ROM_REGION( 0x20000, "gfx1", 0 )
@ -2359,7 +2315,7 @@ ROM_START( puzznicj )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "c20-04.ic11", 0x00000, 0x20000, CRC(a4150b6c) SHA1(27719b8993735532cd59f4ed5693ff3143ee2336) )
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_REGION( 0x0800, "mcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "mc68705p3.ic4", 0x0000, 0x0800, CRC(085f68b4) SHA1(2dbc7e2c015220dc59ee1f1208540744e5b9b7cc) )
ROM_REGION( 0x40000, "gfx1", 0 )

View File

@ -1,7 +1,7 @@
#include "cpu/m6805/m68705.h"
// license:BSD-3-Clause
// copyright-holders:Brad Oliver,Stephane Humbert
#include "machine/taito68705interface.h"
/* This it the best way to allow game specific kludges until the system is fully understood */
enum {
ARKUNK = 0, /* unknown bootlegs for inclusion of possible new sets */
@ -20,14 +20,17 @@ public:
arkanoid_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_videoram(*this,"videoram"),
m_spriteram(*this,"spriteram"),
m_protram(*this,"protram"),
m_maincpu(*this, "maincpu"),
m_mcu(*this, "mcu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { }
: driver_device(mconfig, type, tag)
, m_videoram(*this, "videoram")
, m_spriteram(*this, "spriteram")
, m_protram(*this, "protram")
, m_muxports(*this, "P%u", 1)
, m_maincpu(*this, "maincpu")
, m_mcuintf(*this, "mcu")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
{
}
/* memory pointers */
required_shared_ptr<uint8_t> m_videoram;
@ -46,36 +49,17 @@ public:
int m_bootleg_id;
uint8_t m_bootleg_cmd;
/* mcu interface related */
bool m_Z80HasWritten; // z80 has written to latch flag
uint8_t m_fromZ80; // byte latch for z80->68705 comms
bool m_MCUHasWritten; // 68705 has written to latch flag
uint8_t m_fromMCU; // byte latch for 68705->z80 comms
/* mcu internal related */
uint8_t m_portA_in;
uint8_t m_portA_out;
uint8_t m_old_portC_out;
DECLARE_READ8_MEMBER( mcu_porta_r );
DECLARE_READ8_MEMBER( mcu_portb_r );
DECLARE_READ8_MEMBER( mcu_portc_r );
DECLARE_WRITE8_MEMBER( mcu_porta_w );
DECLARE_WRITE8_MEMBER( mcu_portc_w );
/* hexaa */
uint8_t m_hexaa_from_main;
uint8_t m_hexaa_from_sub;
/* devices */
required_ioport_array<2> m_muxports;
required_device<cpu_device> m_maincpu;
optional_device<m68705p_device> m_mcu;
optional_device<arkanoid_mcu_device_base> m_mcuintf;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
DECLARE_READ8_MEMBER(arkanoid_Z80_mcu_r);
DECLARE_WRITE8_MEMBER(arkanoid_Z80_mcu_w);
DECLARE_READ8_MEMBER(arkanoid_bootleg_f000_r);
DECLARE_READ8_MEMBER(arkanoid_bootleg_f002_r);
@ -90,7 +74,6 @@ public:
DECLARE_WRITE8_MEMBER(hexaa_f000_w);
DECLARE_WRITE8_MEMBER(hexaa_sub_80_w);
DECLARE_READ8_MEMBER(hexaa_sub_90_r);
DECLARE_CUSTOM_INPUT_MEMBER(arkanoid_semaphore_input_r);
DECLARE_CUSTOM_INPUT_MEMBER(arkanoid_input_mux);
DECLARE_DRIVER_INIT(block2);
DECLARE_DRIVER_INIT(arkblock);

View File

@ -248,34 +248,6 @@ protected:
};
class puzznic_state : public taitol_1cpu_state
{
public:
puzznic_state(const machine_config &mconfig, device_type type, const char *tag)
: taitol_1cpu_state(mconfig, type, tag)
, m_mcu_reply(nullptr)
, m_mcu_pos(0)
, m_mcu_reply_len(0)
, m_last_data_adr(0)
, m_last_data(0)
{
}
DECLARE_READ8_MEMBER(mcu_data_r);
DECLARE_WRITE8_MEMBER(mcu_data_w);
protected:
virtual void state_register() override;
virtual void taito_machine_reset() override;
u8 const * m_mcu_reply;
int m_mcu_pos;
int m_mcu_reply_len;
int m_last_data_adr;
int m_last_data;
};
class horshoes_state : public taitol_1cpu_state
{
public:

View File

@ -17,105 +17,9 @@
#define ARKANOID_BOOTLEG_VERBOSE 1
READ8_MEMBER(arkanoid_state::arkanoid_Z80_mcu_r)
{
/* return the last value the 68705 wrote, and mark that we've read it */
m_MCUHasWritten = 0;
return m_fromMCU;
}
WRITE8_MEMBER(arkanoid_state::arkanoid_Z80_mcu_w)
{
m_Z80HasWritten = 1;
m_fromZ80 = data;
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
}
READ8_MEMBER(arkanoid_state::mcu_porta_r)
{
return m_portA_in;
}
WRITE8_MEMBER(arkanoid_state::mcu_porta_w)
{
m_portA_out = data;
}
READ8_MEMBER(arkanoid_state::mcu_portc_r)
{
int portC_in = 0;
/* bit 0 is latch 1 on ic26, is high if m_Z80HasWritten(latch 1) is set */
if (m_Z80HasWritten)
portC_in |= 0x01;
/* bit 1 is the negative output of latch 2 on ic26, is high if m_68705write is clear */
if (!m_MCUHasWritten)
portC_in |= 0x02;
/* bit 2 is an output, to clear latch 1, return whatever state it was set to in m_portC_out */
/* bit 3 is an output, to set latch 2, return whatever state it was set to in m_portC_out */
return portC_in;
}
READ8_MEMBER(arkanoid_state::mcu_portb_r)
{
return ioport("MUX")->read();
}
WRITE8_MEMBER(arkanoid_state::mcu_portc_w)
{
/* bits 0 and 1 are inputs, should never be set as outputs here. if they are, ignore them. */
/* bit 2 is an output, to clear latch 1(m_Z80HasWritten) on rising edge, and enable the z80->68705 communication latch on level low */
// if 0x04 rising edge, clear m_Z80HasWritten/latch 1 (and clear the irq line)
if ((~m_old_portC_out&0x04) && (data&0x04))
{
m_Z80HasWritten = 0;
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
// if 0x04 low, enable the m_portA_in latch, otherwise set the latch value to 0xFF
if (~data&0x04)
m_portA_in = m_fromZ80;
else
m_portA_in = 0xFF;
/* bit 3 is an output, to set latch 2(m_MCUHasWritten) and latch the port_a value into the 68705->z80 latch, on falling edge or low level */
// if 0x08 low, set m_MCUHasWritten/latch 2
if (~data&0x08)
{
/* a write from the 68705 to the Z80; remember its value */
m_MCUHasWritten = 1;
m_fromMCU = m_portA_out;
}
m_old_portC_out = data;
}
CUSTOM_INPUT_MEMBER(arkanoid_state::arkanoid_semaphore_input_r)
{
int res = 0;
/* bit 0x40 is latch 1 on ic26, is high if m_Z80HasWritten(latch 1) is clear */
if (!m_Z80HasWritten)
res |= 0x01;
/* bit 0x80 is the negative output of latch 2 on ic26, is high if m_MCUHasWritten is clear */
if (!m_MCUHasWritten)
res |= 0x02;
return res;
}
CUSTOM_INPUT_MEMBER(arkanoid_state::arkanoid_input_mux)
{
const char *tag1 = (const char *)param;
const char *tag2 = tag1 + strlen(tag1) + 1; // the f***? is this right? are we intentionally pointer-mathing off the end of one array to hit another?
return ioport((m_paddle_select == 0) ? tag1 : tag2)->read();
return m_muxports[(0 == m_paddle_select) ? 0 : 1]->read();
}
/*

View File

@ -3,53 +3,86 @@
#include "emu.h"
#include "machine/taito68705interface.h"
#include "cpu/m6805/m68705.h"
#include "cpu/z80/z80.h"
/*
Most Taito 68705s share a similar (often identical) hookup.
This file encapsulates that.
used by:
buggychl.cpp - buggychl
bking.cpp - bking3
40love.cpp - 40love
bublbobl.cpp - tokio
flstory.cpp - flstory
nycaptor.cpp - nycaptor
lsasquad.cpp - lsasquad
- daikaiju
lkage.cpp - lkage
used by:
buggychl.cpp - buggychl
bking.cpp - bking3
40love.cpp - 40love
bublbobl.cpp - tokio
flstory.cpp - flstory
nycaptor.cpp - nycaptor
lsasquad.cpp - lsasquad
- daikaiju
lkage.cpp - lkage
and the following with slight changes:
slapfght.cpp - tigerh (inverted status bits read on portC)
- slapfght (extended outputs for scrolling)
bigevglf.cpp - writes to mcu aren't latched(?)f
and the following with slight changes:
slapfght.cpp - tigerh (inverted status bits read on portC)
- slapfght (extended outputs for scrolling)
bigevglf.cpp - writes to mcu aren't latched(?)f
not hooked up here, but possible (needs investigating)
pitnrun.cpp - have more functionality on portB, currently using 'instant timers' for latches
taitosj.cpp - ^^
changela.cpp - ^^
arkanoid.cpp - uses 68705 timers (they need to be moved to the 68705 core) and also some portB differences?
xain.cpp - not a Taito game (licensed to Taito?) but MCU hookup looks almost the same
renegade.cpp - ^^
matmania.cpp - ^^
not hooked up here, but possible (needs investigating)
pitnrun.cpp - have more functionality on portB, currently using 'instant timers' for latches
taitosj.cpp - ^^
changela.cpp - ^^
xain.cpp - not a Taito game (licensed to Taito?) but MCU hookup looks almost the same
renegade.cpp - ^^
matmania.cpp - ^^
68705 sets in Taito drivers that are NOT suitable for hookup here?
bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup
mexico86.cpp - knightb, mexico86 - bootleg 68705s
retofinv.cpp - the current MCU dump is a bootleg at least
sqix.cpp - hotsmash - kaneko hookup, different from Taito ones.
68705 sets in Taito drivers that are NOT suitable for hookup here?
bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup
mexico86.cpp - knightb, mexico86 - bootleg 68705s
retofinv.cpp - the current MCU dump is a bootleg at least
sqix.cpp - hotsmash - kaneko hookup, different from Taito ones.
there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps.
there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps.
*/
namespace {
MACHINE_CONFIG_FRAGMENT( taito68705 )
MCFG_CPU_ADD("mcu", M68705P5, DERIVED_CLOCK(1, 1))
MCFG_M68705_PORTA_R_CB(READ8(taito68705_mcu_device, mcu_porta_r))
MCFG_M68705_PORTA_W_CB(WRITE8(taito68705_mcu_device, mcu_porta_w))
MCFG_M68705_PORTB_W_CB(WRITE8(taito68705_mcu_device, mcu_portb_w))
MCFG_M68705_PORTC_R_CB(READ8(taito68705_mcu_device, mcu_portc_r))
MACHINE_CONFIG_END
MACHINE_CONFIG_FRAGMENT( arkanoid_68705p3 )
MCFG_CPU_ADD("mcu", M68705P3, DERIVED_CLOCK(1, 1))
MCFG_M68705_PORTA_R_CB(READ8(arkanoid_mcu_device_base, mcu_pa_r))
MCFG_M68705_PORTB_R_CB(READ8(arkanoid_mcu_device_base, mcu_pb_r))
MCFG_M68705_PORTC_R_CB(READ8(arkanoid_mcu_device_base, mcu_pc_r))
MCFG_M68705_PORTA_W_CB(WRITE8(arkanoid_mcu_device_base, mcu_pa_w))
MCFG_M68705_PORTC_W_CB(WRITE8(arkanoid_mcu_device_base, mcu_pc_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_FRAGMENT( arkanoid_68705p5 )
MCFG_CPU_ADD("mcu", M68705P5, DERIVED_CLOCK(1, 1))
MCFG_M68705_PORTA_R_CB(READ8(arkanoid_mcu_device_base, mcu_pa_r))
MCFG_M68705_PORTB_R_CB(READ8(arkanoid_mcu_device_base, mcu_pb_r))
MCFG_M68705_PORTC_R_CB(READ8(arkanoid_mcu_device_base, mcu_pc_r))
MCFG_M68705_PORTA_W_CB(WRITE8(arkanoid_mcu_device_base, mcu_pa_w))
MCFG_M68705_PORTC_W_CB(WRITE8(arkanoid_mcu_device_base, mcu_pc_w))
MACHINE_CONFIG_END
} // anonymous namespace
const device_type TAITO68705_MCU = &device_creator<taito68705_mcu_device>;
const device_type TAITO68705_MCU_SLAP = &device_creator<taito68705_mcu_slap_device>;
const device_type TAITO68705_MCU_TIGER = &device_creator<taito68705_mcu_tiger_device>;
const device_type TAITO68705_MCU_BEG = &device_creator<taito68705_mcu_beg_device>;
const device_type ARKANOID_68705P3 = &device_creator<arkanoid_68705p3_device>;
const device_type ARKANOID_68705P5 = &device_creator<arkanoid_68705p5_device>;
taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TAITO68705_MCU, "Taito M68705 MCU Interface", tag, owner, clock, "taito68705", __FILE__),
@ -80,14 +113,6 @@ taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, devi
static MACHINE_CONFIG_FRAGMENT( taito68705 )
MCFG_CPU_ADD("mcu", M68705P5, DERIVED_CLOCK(1,1))
MCFG_M68705_PORTA_R_CB(READ8(taito68705_mcu_device, mcu_porta_r))
MCFG_M68705_PORTA_W_CB(WRITE8(taito68705_mcu_device, mcu_porta_w))
MCFG_M68705_PORTB_W_CB(WRITE8(taito68705_mcu_device, mcu_portb_w))
MCFG_M68705_PORTC_R_CB(READ8(taito68705_mcu_device, mcu_portc_r))
MACHINE_CONFIG_END
machine_config_constructor taito68705_mcu_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( taito68705 );
@ -325,22 +350,22 @@ taito68705_mcu_beg_device::taito68705_mcu_beg_device(const machine_config &mconf
WRITE8_MEMBER(taito68705_mcu_beg_device::mcu_portb_w)
{
// transitions are reversed
if ((mem_mask & 0x02) && (data & 0x02) && (~m_old_portB & 0x02) ) /* positive going transition of the clock */
{
if ((mem_mask & 0x02) && (data & 0x02) && (~m_old_portB & 0x02) ) /* positive going transition of the clock */
{
//if (m_main_sent)
m_mcu->set_input_line(0, CLEAR_LINE);
//m_to_mcu_latch = m_from_main; // this is weird, no latching?!
m_main_sent = false;
}
if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04) ) /* positive going transition of the clock */
{
}
if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04) ) /* positive going transition of the clock */
{
m_from_mcu = m_from_mcu_latch;
m_mcu_sent = true;
// logerror("sent %02x\n", m_from_mcu);
}
}
m_old_portB = data;
m_old_portB = data;
}
WRITE8_MEMBER(taito68705_mcu_beg_device::mcu_w)
@ -354,3 +379,159 @@ WRITE8_MEMBER(taito68705_mcu_beg_device::mcu_w)
}
// Arkanoid/Puzznic (completely different)
READ8_MEMBER(arkanoid_mcu_device_base::data_r)
{
// clear MCU semaphore flag and return data
u8 const result(m_mcu_latch);
m_mcu_flag = false;
m_semaphore_cb(CLEAR_LINE);
return result;
}
WRITE8_MEMBER(arkanoid_mcu_device_base::data_w)
{
// set host semaphore flag and latch data
m_host_flag = true;
m_host_latch = data;
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
}
CUSTOM_INPUT_MEMBER(arkanoid_mcu_device_base::semaphore_r)
{
// bit 0 is host semaphore flag, bit 1 is MCU semaphore flag (both active low)
return (m_host_flag ? 0x00 : 0x01) | (m_mcu_flag ? 0x00 : 0x02) | 0xfc;
}
WRITE_LINE_MEMBER(arkanoid_mcu_device_base::reset_w)
{
m_mcu->set_input_line(INPUT_LINE_RESET, state);
// TODO: determine whether host CPU controlled reset also clears the semaphore flags
}
READ8_MEMBER(arkanoid_mcu_device_base::mcu_pa_r)
{
// PC2 controls whether host host latch drives the port
return BIT(m_pc_output, 2) ? 0xff : m_host_latch;
}
READ8_MEMBER(arkanoid_mcu_device_base::mcu_pb_r)
{
return m_portb_r_cb(space, offset, mem_mask);
}
READ8_MEMBER(arkanoid_mcu_device_base::mcu_pc_r)
{
// PC0 is the host semaphore flag (active high)
// PC1 is the MCU semaphoe flag (active low)
return (m_host_flag ? 0x01 : 0x00) | (m_mcu_flag ? 0x00 : 0x02) | 0xfc;
}
WRITE8_MEMBER(arkanoid_mcu_device_base::mcu_pa_w)
{
m_pa_output = data;
}
WRITE8_MEMBER(arkanoid_mcu_device_base::mcu_pc_w)
{
// rising edge on PC2 clears the host semaphore flag
if (BIT(data, 2) && !BIT(m_pc_output, 2))
{
m_host_flag = false;
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
// PC3 sets the MCU semaphore when low
if (!BIT(data, 3))
{
m_mcu_flag = true;
// data is latched on falling edge
if (BIT(m_pc_output, 3))
m_mcu_latch = m_pa_output & (BIT(m_pc_output, 2) ? 0xff : m_host_latch);
}
m_pc_output = data;
if (!BIT(data, 3))
m_semaphore_cb(ASSERT_LINE);
}
arkanoid_mcu_device_base::arkanoid_mcu_device_base(
machine_config const &mconfig,
device_type type,
char const *name,
char const *tag,
device_t *owner,
uint32_t clock,
char const *shortname,
char const *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
, m_mcu(*this, "mcu")
, m_semaphore_cb(*this)
, m_portb_r_cb(*this)
, m_host_flag(false)
, m_mcu_flag(false)
, m_host_latch(0xff)
, m_mcu_latch(0xff)
, m_pa_output(0xff)
, m_pc_output(0xff)
{
}
void arkanoid_mcu_device_base::device_start()
{
m_semaphore_cb.resolve_safe();
m_portb_r_cb.resolve_safe(0xff);
save_item(NAME(m_host_flag));
save_item(NAME(m_mcu_flag));
save_item(NAME(m_host_latch));
save_item(NAME(m_mcu_latch));
save_item(NAME(m_pa_output));
save_item(NAME(m_pc_output));
m_host_latch = 0xff;
m_mcu_latch = 0xff;
m_pa_output = 0xff;
m_pc_output = 0xff;
}
void arkanoid_mcu_device_base::device_reset()
{
m_host_flag = false;
m_mcu_flag = false;
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
m_semaphore_cb(CLEAR_LINE);
}
arkanoid_68705p3_device::arkanoid_68705p3_device(
machine_config const &mconfig,
char const *tag,
device_t *owner,
uint32_t clock)
: arkanoid_mcu_device_base(mconfig, ARKANOID_68705P3, "Arkanoid MC68705P3 Interface", tag, owner, clock, "arkanoid_68705p3", __FILE__)
{
}
machine_config_constructor arkanoid_68705p3_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME(arkanoid_68705p3);
}
arkanoid_68705p5_device::arkanoid_68705p5_device(
machine_config const &mconfig,
char const *tag,
device_t *owner,
uint32_t clock)
: arkanoid_mcu_device_base(mconfig, ARKANOID_68705P5, "Arkanoid MC68705P5 Interface", tag, owner, clock, "arkanoid_68705p5", __FILE__)
{
}
machine_config_constructor arkanoid_68705p5_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME(arkanoid_68705p5);
}

View File

@ -1,6 +1,17 @@
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood
#include "cpu/m6805/m68705.h"
extern const device_type TAITO68705_MCU;
extern const device_type TAITO68705_MCU_SLAP;
extern const device_type TAITO68705_MCU_TIGER;
extern const device_type TAITO68705_MCU_BEG;
extern const device_type ARKANOID_68705P3;
extern const device_type ARKANOID_68705P5;
class taito68705_mcu_device : public device_t
{
public:
@ -15,7 +26,7 @@ public:
virtual DECLARE_READ8_MEMBER( mcu_portc_r );
DECLARE_WRITE8_MEMBER( mcu_porta_w );
virtual DECLARE_WRITE8_MEMBER( mcu_portb_w );
DECLARE_READ8_MEMBER( mcu_status_r );
DECLARE_CUSTOM_INPUT_MEMBER( mcu_sent_r );
DECLARE_CUSTOM_INPUT_MEMBER( main_sent_r );
@ -43,7 +54,6 @@ protected:
required_device<cpu_device> m_mcu;
};
extern const device_type TAITO68705_MCU;
#define MCFG_TAITO_M68705_EXTENSION_CB(_devcb) \
taito68705_mcu_slap_device::set_extension_cb(*device, DEVCB_##_devcb);
@ -53,7 +63,7 @@ class taito68705_mcu_slap_device : public taito68705_mcu_device
public:
taito68705_mcu_slap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual DECLARE_WRITE8_MEMBER( mcu_portb_w ) override;
template<class _Object> static devcb_base &set_extension_cb(device_t &device, _Object object) { return downcast<taito68705_mcu_slap_device &>(device).m_extension_cb_w.set_callback(object); }
devcb_write8 m_extension_cb_w;
@ -62,7 +72,6 @@ protected:
virtual void device_start() override;
};
extern const device_type TAITO68705_MCU_SLAP;
class taito68705_mcu_tiger_device : public taito68705_mcu_device
{
@ -71,7 +80,6 @@ public:
virtual DECLARE_READ8_MEMBER( mcu_portc_r ) override;
};
extern const device_type TAITO68705_MCU_TIGER;
class taito68705_mcu_beg_device : public taito68705_mcu_device
{
@ -81,4 +89,76 @@ public:
virtual DECLARE_WRITE8_MEMBER(mcu_portb_w) override;
};
extern const device_type TAITO68705_MCU_BEG;
#define MCFG_ARKANOID_MCU_SEMAPHORE_CB(cb) \
arkanoid_mcu_device_base::set_semaphore_cb(*device, DEVCB_##cb);
#define MCFG_ARKANOID_MCU_PORTB_R_CB(cb) \
arkanoid_mcu_device_base::set_portb_r_cb(*device, DEVCB_##cb);
class arkanoid_mcu_device_base : public device_t
{
public:
template <typename Obj> static devcb_base &set_semaphore_cb(device_t &device, Obj &&object)
{ return downcast<arkanoid_mcu_device_base &>(device).m_semaphore_cb.set_callback(std::forward<Obj>(object)); }
template <typename Obj> static devcb_base &set_portb_r_cb(device_t &device, Obj &&object)
{ return downcast<arkanoid_mcu_device_base &>(device).m_portb_r_cb.set_callback(std::forward<Obj>(object)); }
// host interface
DECLARE_READ8_MEMBER(data_r);
DECLARE_WRITE8_MEMBER(data_w);
DECLARE_CUSTOM_INPUT_MEMBER(semaphore_r);
DECLARE_WRITE_LINE_MEMBER(reset_w);
// MCU callbacks
DECLARE_READ8_MEMBER(mcu_pa_r);
DECLARE_READ8_MEMBER(mcu_pb_r);
DECLARE_READ8_MEMBER(mcu_pc_r);
DECLARE_WRITE8_MEMBER(mcu_pa_w);
DECLARE_WRITE8_MEMBER(mcu_pc_w);
protected:
arkanoid_mcu_device_base(
machine_config const &mconfig,
device_type type,
char const *name,
char const *tag,
device_t *owner,
uint32_t clock,
char const *shortname,
char const *source);
virtual void device_start() override;
virtual void device_reset() override;
required_device<m68705p_device> m_mcu;
devcb_write_line m_semaphore_cb;
devcb_read8 m_portb_r_cb;
bool m_host_flag;
bool m_mcu_flag;
u8 m_host_latch;
u8 m_mcu_latch;
u8 m_pa_output;
u8 m_pc_output;
};
class arkanoid_68705p3_device : public arkanoid_mcu_device_base
{
public:
arkanoid_68705p3_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
protected:
virtual machine_config_constructor device_mconfig_additions() const override;
};
class arkanoid_68705p5_device : public arkanoid_mcu_device_base
{
public:
arkanoid_68705p5_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
protected:
virtual machine_config_constructor device_mconfig_additions() const override;
};

View File

@ -59,8 +59,8 @@ WRITE8_MEMBER(arkanoid_state::arkanoid_d008_w)
leaving the tilt screen (as the MCU is now out of sync with main CPU
which resets itself). This bit is the likely candidate as it is flipped
early in bootup just prior to accessing the MCU for the first time. */
if (m_mcu.found()) // Bootlegs don't have the MCU but still set this bit
m_mcu->set_input_line(INPUT_LINE_RESET, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
if (m_mcuintf.found()) // Bootlegs don't have the MCU but still set this bit
m_mcuintf->reset_w(BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE);
}