mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
taitosj: Made security MCU hookup a device
This commit is contained in:
parent
9ef9bee33b
commit
a716e67787
@ -3632,6 +3632,8 @@ files {
|
||||
MAME_DIR .. "src/mame/includes/buggychl.h",
|
||||
MAME_DIR .. "src/mame/machine/taito68705interface.cpp",
|
||||
MAME_DIR .. "src/mame/machine/taito68705interface.h",
|
||||
MAME_DIR .. "src/mame/machine/taitosjsec.cpp",
|
||||
MAME_DIR .. "src/mame/machine/taitosjsec.h",
|
||||
MAME_DIR .. "src/mame/video/buggychl.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/capr1.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/caprcyc.cpp",
|
||||
|
@ -256,8 +256,7 @@ ADDRESS_MAP_END
|
||||
|
||||
/* only difference is taitosj_fake_ replaced with taitosj_mcu_ */
|
||||
static ADDRESS_MAP_START( taitosj_main_mcu_map, AS_PROGRAM, 8, taitosj_state )
|
||||
AM_RANGE(0x8800, 0x8800) AM_MIRROR(0x07fe) AM_READWRITE(taitosj_mcu_data_r, taitosj_mcu_data_w)
|
||||
AM_RANGE(0x8801, 0x8801) AM_MIRROR(0x07fe) AM_READ(taitosj_mcu_status_r)
|
||||
AM_RANGE(0x8800, 0x8801) AM_MIRROR(0x07fe) AM_DEVREADWRITE("bmcu", taito_sj_security_mcu_device, data_r, data_w)
|
||||
AM_IMPORT_FROM( taitosj_main_nomcu_map )
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -289,8 +288,7 @@ static ADDRESS_MAP_START( kikstart_main_map, AS_PROGRAM, 8, taitosj_state )
|
||||
AM_RANGE(0x0000, 0x5fff) AM_ROM
|
||||
AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank1")
|
||||
AM_RANGE(0x8000, 0x87ff) AM_RAM
|
||||
AM_RANGE(0x8800, 0x8800) AM_READWRITE(taitosj_mcu_data_r, taitosj_mcu_data_w)
|
||||
AM_RANGE(0x8801, 0x8801) AM_READ(taitosj_mcu_status_r)
|
||||
AM_RANGE(0x8800, 0x8801) AM_DEVREADWRITE("bmcu", taito_sj_security_mcu_device, data_r, data_w)
|
||||
AM_RANGE(0x8802, 0x8802) AM_NOP
|
||||
AM_RANGE(0x8a00, 0x8a5f) AM_WRITEONLY AM_SHARE("colscrolly")
|
||||
AM_RANGE(0x9000, 0xbfff) AM_WRITE(taitosj_characterram_w) AM_SHARE("characterram")
|
||||
@ -1815,10 +1813,11 @@ static MACHINE_CONFIG_DERIVED( mcu, nomcu )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(taitosj_main_mcu_map)
|
||||
|
||||
MCFG_CPU_ADD("mcu", M68705P3, XTAL_3MHz) /* xtal is 3MHz, divided by 4 internally */
|
||||
MCFG_M68705_PORTA_W_CB(WRITE8(taitosj_state, taitosj_68705_portA_w))
|
||||
MCFG_M68705_PORTB_W_CB(WRITE8(taitosj_state, taitosj_68705_portB_w))
|
||||
MCFG_M68705_PORTC_R_CB(READ8(taitosj_state, taitosj_68705_portC_r))
|
||||
MCFG_CPU_ADD("bmcu", TAITO_SJ_SECURITY_MCU, XTAL_3MHz) /* xtal is 3MHz, divided by 4 internally */
|
||||
MCFG_TAITO_SJ_SECURITY_MCU_68READ_CB(READ8(taitosj_state, mcu_mem_r))
|
||||
MCFG_TAITO_SJ_SECURITY_MCU_68WRITE_CB(WRITE8(taitosj_state, mcu_mem_w))
|
||||
MCFG_TAITO_SJ_SECURITY_MCU_68INTRQ_CB(WRITELINE(taitosj_state, mcu_intrq_w))
|
||||
MCFG_TAITO_SJ_SECURITY_MCU_BUSRQ_CB(WRITELINE(taitosj_state, mcu_busrq_w))
|
||||
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
|
||||
MACHINE_CONFIG_END
|
||||
@ -2274,7 +2273,7 @@ ROM_START( frontlin )
|
||||
ROM_LOAD( "fl70.u70", 0x0000, 0x1000, CRC(15f4ed8c) SHA1(ec096234e4e594100180eb99c8c57eb97b9f57e2) )
|
||||
ROM_LOAD( "fl71.u71", 0x1000, 0x1000, CRC(c3eb38e7) SHA1(427e5deb6a6e22d8c34923209a818f79d50e59d4) )
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "aa1.13", 0x0000, 0x0800, CRC(7e78bdd3) SHA1(9eeb0e969fd013b9db074a15b0463216453e9364) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime */
|
||||
@ -2441,7 +2440,7 @@ ROM_START( elevator ) // 5 board set, using 2732s on both mainboard and square r
|
||||
ROM_REGION( 0x0800, "pal", 0 ) // on GAME BOARD
|
||||
ROM_LOAD( "ww15.pal16l8.ic24.jed.bin", 0x0000, 0x0117, CRC(c3ec20d6) SHA1(4bcdd92ca6b75ba825a7f90b1f35d8dcaeaf8a96) ) // what format is this? jed2bin?
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "ba3__11.mc68705p3.ic4", 0x0000, 0x0800, CRC(9ce75afc) SHA1(4c8f5d926ae2bec8fcb70692125b9e1c863166c6) ) // IC4 on the older Z80+security daughterboard; The MCU itself has a strange custom from-factory silkscreen, rather than "MC68705P3S" it is labeled "15-00011-001 // DA68237"
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime, on Square ROM board */
|
||||
@ -2529,7 +2528,7 @@ ROM_START( elevator4 ) // later 4 board set, with rom data on 2764s, split betwe
|
||||
ROM_REGION( 0x0800, "pal", 0 ) // on GAME BOARD
|
||||
ROM_LOAD( "ww15.pal16l8.ic24.jed.bin", 0x0000, 0x0117, CRC(c3ec20d6) SHA1(4bcdd92ca6b75ba825a7f90b1f35d8dcaeaf8a96) ) // what format is this? jed2bin?
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "ba3__11.mc68705p3.ic24", 0x0000, 0x0800, CRC(9ce75afc) SHA1(4c8f5d926ae2bec8fcb70692125b9e1c863166c6) ) // IC24 on the later CPU BOARD; The MCU itself has a strange custom from-factory silkscreen, rather than "MC68705P3S" it is labeled "15-00011-001 // DA68237"
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime, on L-shaped rom board */
|
||||
@ -2559,7 +2558,7 @@ ROM_START( tinstar )
|
||||
ROM_LOAD( "ts.71", 0x1000, 0x1000, CRC(03c91332) SHA1(3903e876ae02e9aea7ee6854bb4c6407dd7108d6) )
|
||||
ROM_LOAD( "ts.72", 0x2000, 0x1000, CRC(beeed8f3) SHA1(2a18edecabbfd10b3238338cb5554edc8c18d93c) )
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "a10-12", 0x0000, 0x0800, CRC(889eefc9) SHA1(1a31aa21c02215410eea27ed52fad67f007ee810) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime */
|
||||
@ -2603,7 +2602,7 @@ ROM_START( tinstar2 )
|
||||
ROM_LOAD( "a10-29.bin", 0x0000, 0x2000, CRC(771f1a6a) SHA1(c5d1841840ff35e2c20a285b1b7f35150356f50f) )
|
||||
ROM_LOAD( "a10-10.bin", 0x2000, 0x1000, CRC(beeed8f3) SHA1(2a18edecabbfd10b3238338cb5554edc8c18d93c) )
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "a10-12", 0x0000, 0x0800, CRC(889eefc9) SHA1(1a31aa21c02215410eea27ed52fad67f007ee810) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime */
|
||||
@ -2684,7 +2683,7 @@ ROM_START( sfposeid )
|
||||
ROM_LOAD( "a14-10.70", 0x0000, 0x1000, CRC(f1365f35) SHA1(34b3ea03eb9fbf5454858fa6e07ec49a7b3be8b4) )
|
||||
ROM_LOAD( "a14-11.71", 0x1000, 0x1000, CRC(74a12fe2) SHA1(8678ea68bd283b7a63915717cdbbedef0b699198) )
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "a14-12", 0x0000, 0x0800, CRC(091beed8) SHA1(263806aef01bbc258f5cfa92de8a9e355491fb3a) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime */
|
||||
@ -2740,7 +2739,7 @@ ROM_START( kikstart )
|
||||
ROM_LOAD( "a20-11", 0x1000, 0x1000, CRC(8db12dd9) SHA1(3b291d478b3f3f1bf93d95a78506d99a71f36d05) )
|
||||
ROM_LOAD( "a20-12", 0x2000, 0x1000, CRC(e7eeb933) SHA1(26f3904f6d4dc814318221f1c9cd5dcc671fe05a) )
|
||||
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
|
||||
ROM_LOAD( "a20-13.ic91", 0x0000, 0x0800, CRC(3fb6c4fb) SHA1(04b9458f21a793444cd587055e2e3ccfa3f835a2) )
|
||||
|
||||
ROM_REGION( 0x8000, "gfx1", 0 ) /* graphic ROMs used at runtime */
|
||||
|
@ -1,7 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nicola Salmoria
|
||||
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/taitosjsec.h"
|
||||
|
||||
#include "machine/gen_latch.h"
|
||||
|
||||
@ -33,7 +33,7 @@ public:
|
||||
m_kikstart_scrollram(*this, "kikstart_scroll"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_mcu(*this, "mcu"),
|
||||
m_mcu(*this, "bmcu"),
|
||||
m_dac(*this, "dac"),
|
||||
m_dacvol(*this, "dacvol"),
|
||||
m_ay1(*this, "ay1"),
|
||||
@ -63,12 +63,6 @@ public:
|
||||
required_shared_ptr<uint8_t> m_video_priority;
|
||||
required_shared_ptr<uint8_t> m_collision_reg;
|
||||
optional_shared_ptr<uint8_t> m_kikstart_scrollram;
|
||||
uint8_t m_fromz80;
|
||||
uint8_t m_toz80;
|
||||
uint8_t m_zaccept;
|
||||
uint8_t m_zready;
|
||||
uint8_t m_busreq;
|
||||
uint8_t m_portA_out;
|
||||
uint8_t m_spacecr_prot_value;
|
||||
uint8_t m_protection_value;
|
||||
uint32_t m_address;
|
||||
@ -91,12 +85,10 @@ public:
|
||||
DECLARE_READ8_MEMBER(taitosj_fake_data_r);
|
||||
DECLARE_WRITE8_MEMBER(taitosj_fake_data_w);
|
||||
DECLARE_READ8_MEMBER(taitosj_fake_status_r);
|
||||
DECLARE_READ8_MEMBER(taitosj_mcu_data_r);
|
||||
DECLARE_WRITE8_MEMBER(taitosj_mcu_data_w);
|
||||
DECLARE_READ8_MEMBER(taitosj_mcu_status_r);
|
||||
DECLARE_WRITE8_MEMBER(taitosj_68705_portA_w);
|
||||
DECLARE_WRITE8_MEMBER(taitosj_68705_portB_w);
|
||||
DECLARE_READ8_MEMBER(taitosj_68705_portC_r);
|
||||
DECLARE_READ8_MEMBER(mcu_mem_r);
|
||||
DECLARE_WRITE8_MEMBER(mcu_mem_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(mcu_intrq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(mcu_busrq_w);
|
||||
DECLARE_READ8_MEMBER(spacecr_prot_r);
|
||||
DECLARE_WRITE8_MEMBER(alpine_protection_w);
|
||||
DECLARE_WRITE8_MEMBER(alpinea_bankswitch_w);
|
||||
@ -120,9 +112,6 @@ public:
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_taitosj(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_kikstart(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_CALLBACK_MEMBER(taitosj_mcu_real_data_w);
|
||||
TIMER_CALLBACK_MEMBER(taitosj_mcu_data_real_r);
|
||||
TIMER_CALLBACK_MEMBER(taitosj_mcu_status_real_w);
|
||||
void init_common();
|
||||
void reset_common();
|
||||
void set_pens();
|
||||
@ -144,7 +133,7 @@ public:
|
||||
int video_update_common(bitmap_ind16 &bitmap, const rectangle &cliprect, copy_layer_func_t copy_layer_func);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
optional_device<m68705p_device> m_mcu;
|
||||
optional_device<taito_sj_security_mcu_device> m_mcu;
|
||||
required_device<dac_8bit_r2r_device> m_dac;
|
||||
required_device<discrete_device> m_dacvol;
|
||||
required_device<ay8910_device> m_ay1;
|
||||
|
@ -23,14 +23,6 @@ void taitosj_state::machine_start()
|
||||
membank("bank1")->configure_entry(0, memregion("maincpu")->base() + 0x6000);
|
||||
membank("bank1")->configure_entry(1, memregion("maincpu")->base() + 0x10000);
|
||||
|
||||
save_item(NAME(m_fromz80));
|
||||
save_item(NAME(m_toz80));
|
||||
save_item(NAME(m_zaccept));
|
||||
save_item(NAME(m_zready));
|
||||
save_item(NAME(m_busreq));
|
||||
|
||||
save_item(NAME(m_portA_out));
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_spacecr_prot_value));
|
||||
save_item(NAME(m_protection_value));
|
||||
}
|
||||
@ -42,12 +34,8 @@ void taitosj_state::machine_reset()
|
||||
/* never write to the bank selector register) */
|
||||
taitosj_bankswitch_w(space, 0, 0);
|
||||
|
||||
|
||||
m_zaccept = 1;
|
||||
m_zready = 0;
|
||||
m_busreq = 0;
|
||||
if (m_mcu)
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
m_mcu->reset_w(PULSE_LINE);
|
||||
|
||||
m_spacecr_prot_value = 0;
|
||||
}
|
||||
@ -107,153 +95,28 @@ READ8_MEMBER(taitosj_state::taitosj_fake_status_r)
|
||||
}
|
||||
|
||||
|
||||
/* timer callback : */
|
||||
READ8_MEMBER(taitosj_state::taitosj_mcu_data_r)
|
||||
READ8_MEMBER(taitosj_state::mcu_mem_r)
|
||||
{
|
||||
LOG(("%04x: protection read %02x\n",space.device().safe_pc(),m_toz80));
|
||||
m_zaccept = 1;
|
||||
return m_toz80;
|
||||
return m_maincpu->space(AS_PROGRAM).read_byte(offset);
|
||||
}
|
||||
|
||||
/* timer callback : */
|
||||
TIMER_CALLBACK_MEMBER(taitosj_state::taitosj_mcu_real_data_w)
|
||||
WRITE8_MEMBER(taitosj_state::mcu_mem_w)
|
||||
{
|
||||
m_zready = 1;
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
|
||||
m_fromz80 = param;
|
||||
m_maincpu->space(AS_PROGRAM).write_byte(offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taitosj_state::taitosj_mcu_data_w)
|
||||
WRITE_LINE_MEMBER(taitosj_state::mcu_intrq_w)
|
||||
{
|
||||
LOG(("%04x: protection write %02x\n",space.device().safe_pc(),data));
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(taitosj_state::taitosj_mcu_real_data_w),this), data);
|
||||
/* temporarily boost the interleave to sync things up */
|
||||
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10));
|
||||
// FIXME: there's a logic network here that makes this edge sensitive or something and mixes it with other interrupt sources
|
||||
if (CLEAR_LINE != state)
|
||||
LOG(("68705 68INTRQ **NOT SUPPORTED**!\n"));
|
||||
}
|
||||
|
||||
READ8_MEMBER(taitosj_state::taitosj_mcu_status_r)
|
||||
WRITE_LINE_MEMBER(taitosj_state::mcu_busrq_w)
|
||||
{
|
||||
/* temporarily boost the interleave to sync things up */
|
||||
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10));
|
||||
|
||||
/* bit 0 = the 68705 has read data from the Z80 */
|
||||
/* bit 1 = the 68705 has written data for the Z80 */
|
||||
return ~((m_zready << 0) | (m_zaccept << 1));
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taitosj_state::taitosj_68705_portA_w)
|
||||
{
|
||||
LOG(("%04x: 68705 port A write %02x\n",space.device().safe_pc(),data));
|
||||
m_portA_out = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Port B connections:
|
||||
*
|
||||
* all bits are logical 1 when read (+5V pullup)
|
||||
*
|
||||
* 0 W !68INTRQ
|
||||
* 1 W !68LRD (enables latch which holds command from the Z80)
|
||||
* 2 W !68LWR (loads the latch which holds data for the Z80, and sets a
|
||||
* status bit so the Z80 knows there's data waiting)
|
||||
* 3 W to Z80 !BUSRQ (aka !WAIT) pin
|
||||
* 4 W !68WRITE (triggers write to main Z80 memory area and increases low
|
||||
* 8 bits of the latched address)
|
||||
* 5 W !68READ (triggers read from main Z80 memory area and increases low
|
||||
* 8 bits of the latched address)
|
||||
* 6 W !LAL (loads the latch which holds the low 8 bits of the address of
|
||||
* the main Z80 memory location to access)
|
||||
* 7 W !UAL (loads the latch which holds the high 8 bits of the address of
|
||||
* the main Z80 memory location to access)
|
||||
*/
|
||||
|
||||
/* timer callback : 68705 is going to read data from the Z80 */
|
||||
TIMER_CALLBACK_MEMBER(taitosj_state::taitosj_mcu_data_real_r)
|
||||
{
|
||||
m_zready = 0;
|
||||
}
|
||||
|
||||
/* timer callback : 68705 is writing data for the Z80 */
|
||||
TIMER_CALLBACK_MEMBER(taitosj_state::taitosj_mcu_status_real_w)
|
||||
{
|
||||
m_toz80 = param;
|
||||
m_zaccept = 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taitosj_state::taitosj_68705_portB_w)
|
||||
{
|
||||
LOG(("%04x: 68705 port B write %02x\n", space.device().safe_pc(), data));
|
||||
|
||||
if (~data & 0x01)
|
||||
{
|
||||
LOG(("%04x: 68705 68INTRQ **NOT SUPPORTED**!\n", space.device().safe_pc()));
|
||||
}
|
||||
if (~data & 0x02)
|
||||
{
|
||||
/* 68705 is going to read data from the Z80 */
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(taitosj_state::taitosj_mcu_data_real_r), this));
|
||||
m_mcu->pa_w(space, 0, m_fromz80);
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
LOG(("%04x: 68705 <- Z80 %02x\n", space.device().safe_pc(), m_fromz80));
|
||||
}
|
||||
if (~data & 0x08)
|
||||
m_busreq = 1;
|
||||
else
|
||||
m_busreq = 0;
|
||||
if (~data & 0x04)
|
||||
{
|
||||
LOG(("%04x: 68705 -> Z80 %02x\n", space.device().safe_pc(), m_portA_out));
|
||||
|
||||
/* 68705 is writing data for the Z80 */
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(taitosj_state::taitosj_mcu_status_real_w),this), m_portA_out);
|
||||
}
|
||||
if (~data & 0x10)
|
||||
{
|
||||
address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
|
||||
LOG(("%04x: 68705 write %02x to address %04x\n",space.device().safe_pc(), m_portA_out, m_address));
|
||||
|
||||
cpu0space.write_byte(m_address, m_portA_out);
|
||||
|
||||
/* increase low 8 bits of latched address for burst writes */
|
||||
m_address = (m_address & 0xff00) | ((m_address + 1) & 0xff);
|
||||
}
|
||||
if (~data & 0x20)
|
||||
{
|
||||
u8 const value = m_maincpu->space(AS_PROGRAM).read_byte(m_address);
|
||||
m_mcu->pa_w(space, 0, value);
|
||||
LOG(("%04x: 68705 read %02x from address %04x\n", space.device().safe_pc(), value, m_address));
|
||||
}
|
||||
if (~data & 0x40)
|
||||
{
|
||||
LOG(("%04x: 68705 address low %02x\n", space.device().safe_pc(), m_portA_out));
|
||||
m_address = (m_address & 0xff00) | m_portA_out;
|
||||
}
|
||||
if (~data & 0x80)
|
||||
{
|
||||
LOG(("%04x: 68705 address high %02x\n", space.device().safe_pc(), m_portA_out));
|
||||
m_address = (m_address & 0x00ff) | (m_portA_out << 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Port C connections:
|
||||
*
|
||||
* 0 R ZREADY (1 when the Z80 has written a command in the latch)
|
||||
* 1 R ZACCEPT (1 when the Z80 has read data from the latch)
|
||||
* 2 R from Z80 !BUSAK pin
|
||||
* 3 R 68INTAK (goes 0 when the interrupt request done with 68INTRQ
|
||||
* passes through)
|
||||
*/
|
||||
|
||||
READ8_MEMBER(taitosj_state::taitosj_68705_portC_r)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = (m_zready << 0) | (m_zaccept << 1) | ((m_busreq^1) << 2);
|
||||
LOG(("%04x: 68705 port C read %02x\n",space.device().safe_pc(),res));
|
||||
return res;
|
||||
// this actually goes to the Z80 BUSRQ (aka WAIT) pin, and the MCU waits for the bus to become available
|
||||
// we're pretending this happens immediately to make life easier
|
||||
m_mcu->busak_w(state);
|
||||
}
|
||||
|
||||
|
||||
|
224
src/mame/machine/taitosjsec.cpp
Normal file
224
src/mame/machine/taitosjsec.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
#include "emu.h"
|
||||
#include "taitosjsec.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(TAITO_SJ_SECURITY_MCU, taito_sj_security_mcu_device, "taitosjsecmcu", "Taito SJ Security MCU Interface")
|
||||
|
||||
|
||||
taito_sj_security_mcu_device::taito_sj_security_mcu_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock)
|
||||
: device_t(mconfig,TAITO_SJ_SECURITY_MCU, tag, owner, clock)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_68read_cb(*this)
|
||||
, m_68write_cb(*this)
|
||||
, m_68intrq_cb(*this)
|
||||
, m_busrq_cb(*this)
|
||||
, m_addr(0U)
|
||||
, m_mcu_data(0U)
|
||||
, m_host_data(0U)
|
||||
, m_read_data(0U)
|
||||
, m_zaccept(false)
|
||||
, m_zready(false)
|
||||
, m_pb_val(0U)
|
||||
, m_busak(false)
|
||||
, m_reset(false)
|
||||
{
|
||||
}
|
||||
|
||||
READ8_MEMBER(taito_sj_security_mcu_device::data_r)
|
||||
{
|
||||
if (BIT(offset, 0))
|
||||
{
|
||||
// ZLSTATUS
|
||||
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10));
|
||||
return
|
||||
(u8(space.unmap()) & 0xfc) |
|
||||
u8(m_zaccept ? 0x00 : 0x02) |
|
||||
u8(m_zready ? 0x00 : 0x01);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ZLREAD
|
||||
if (!machine().side_effect_disabled())
|
||||
m_zaccept = true;
|
||||
return m_mcu_data;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taito_sj_security_mcu_device::data_w)
|
||||
{
|
||||
if (BIT(offset, 0))
|
||||
{
|
||||
// ZINTRQ
|
||||
// FIXME: this can be jumpered to /INT on the MCU
|
||||
}
|
||||
else
|
||||
{
|
||||
// ZLWRITE
|
||||
device_scheduler &sched(machine().scheduler());
|
||||
sched.synchronize(timer_expired_delegate(FUNC(taito_sj_security_mcu_device::do_host_write), this), data);
|
||||
sched.boost_interleave(attotime::zero, attotime::from_usec(10));
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(taito_sj_security_mcu_device::busak_w)
|
||||
{
|
||||
m_busak = (ASSERT_LINE == state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(taito_sj_security_mcu_device::reset_w)
|
||||
{
|
||||
m_reset = (ASSERT_LINE == state);
|
||||
if (CLEAR_LINE != state)
|
||||
{
|
||||
m_zaccept = true;
|
||||
m_zready = false;
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
}
|
||||
m_mcu->set_input_line(INPUT_LINE_RESET, state);
|
||||
}
|
||||
|
||||
void taito_sj_security_mcu_device::device_start()
|
||||
{
|
||||
m_68read_cb.resolve_safe(0xff);
|
||||
m_68write_cb.resolve_safe();
|
||||
m_68intrq_cb.resolve_safe();
|
||||
m_busrq_cb.resolve_safe();
|
||||
|
||||
save_item(NAME(m_addr));
|
||||
save_item(NAME(m_mcu_data));
|
||||
save_item(NAME(m_host_data));
|
||||
save_item(NAME(m_read_data));
|
||||
save_item(NAME(m_zaccept));
|
||||
save_item(NAME(m_zready));
|
||||
save_item(NAME(m_pb_val));
|
||||
save_item(NAME(m_busak));
|
||||
save_item(NAME(m_reset));
|
||||
|
||||
m_addr = 0xffffU;
|
||||
m_mcu_data = 0xffU;
|
||||
m_host_data = 0xffU;
|
||||
m_read_data = 0xffU;
|
||||
m_pb_val = 0xffU;
|
||||
m_busak = false;
|
||||
m_reset = false;
|
||||
}
|
||||
|
||||
void taito_sj_security_mcu_device::device_reset()
|
||||
{
|
||||
m_zaccept = true;
|
||||
m_zready = false;
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_MEMBER(taito_sj_security_mcu_device::device_add_mconfig)
|
||||
MCFG_CPU_ADD("mcu", M68705P5, DERIVED_CLOCK(1, 1))
|
||||
MCFG_M68705_PORTA_R_CB(READ8(taito_sj_security_mcu_device, mcu_pa_r))
|
||||
MCFG_M68705_PORTC_R_CB(READ8(taito_sj_security_mcu_device, mcu_pc_r))
|
||||
MCFG_M68705_PORTA_W_CB(WRITE8(taito_sj_security_mcu_device, mcu_pa_w))
|
||||
MCFG_M68705_PORTB_W_CB(WRITE8(taito_sj_security_mcu_device, mcu_pb_w))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
READ8_MEMBER(taito_sj_security_mcu_device::mcu_pa_r)
|
||||
{
|
||||
return get_bus_val();
|
||||
}
|
||||
|
||||
READ8_MEMBER(taito_sj_security_mcu_device::mcu_pc_r)
|
||||
{
|
||||
// FIXME 68INTAK is on PC3 but we're ignoring it
|
||||
return
|
||||
(m_zready ? 0x01U : 0x00U) |
|
||||
(m_zaccept ? 0x02U : 0x00U) |
|
||||
(m_busak ? 0x00U : 0x04U);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taito_sj_security_mcu_device::mcu_pa_w)
|
||||
{
|
||||
m_pa_val = data;
|
||||
if (BIT(~m_pb_val, 6))
|
||||
m_addr = (m_addr & 0xff00U) | u16(get_bus_val());
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(taito_sj_security_mcu_device::mcu_pb_w)
|
||||
{
|
||||
bool inc_addr(false);
|
||||
u8 const diff(m_pb_val ^ data);
|
||||
|
||||
// 68INTRQ
|
||||
if (BIT(diff, 0))
|
||||
m_68intrq_cb(BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE);
|
||||
|
||||
// 68LRD
|
||||
u8 const bus_val(get_bus_val());
|
||||
if (BIT(diff & data, 1))
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(taito_sj_security_mcu_device::do_mcu_read), this));
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
// 68LWR
|
||||
if (BIT(diff & data, 2))
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(taito_sj_security_mcu_device::do_mcu_write), this), bus_val);
|
||||
|
||||
// BUSRQ
|
||||
if (BIT(diff, 3))
|
||||
m_busrq_cb(BIT(data, 3) ? CLEAR_LINE : ASSERT_LINE);
|
||||
|
||||
// 68WRITE
|
||||
if (BIT(diff, 4))
|
||||
{
|
||||
if (BIT(~data, 4))
|
||||
m_68write_cb(space, m_addr, bus_val);
|
||||
else if (BIT(data, 5))
|
||||
inc_addr = true;
|
||||
}
|
||||
|
||||
// 68READ
|
||||
if (BIT(diff, 5))
|
||||
{
|
||||
if (BIT(~data, 5))
|
||||
m_read_data = m_68read_cb(space, m_addr);
|
||||
else if (BIT(data, 4))
|
||||
inc_addr = true;
|
||||
}
|
||||
|
||||
// LAL
|
||||
if (BIT(~data, 6))
|
||||
m_addr = (m_addr & 0xff00U) | u16(bus_val);
|
||||
else if (inc_addr)
|
||||
m_addr = (m_addr & 0xff00U) | ((m_addr + 1) & 0x00ffU);
|
||||
|
||||
// UAL
|
||||
if (BIT(~data, 7))
|
||||
m_addr = (m_addr & 0x00ffU) | (u16(bus_val) << 8);
|
||||
|
||||
m_pb_val = data;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(taito_sj_security_mcu_device::do_mcu_read)
|
||||
{
|
||||
m_zready = false;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(taito_sj_security_mcu_device::do_mcu_write)
|
||||
{
|
||||
m_mcu_data = u8(param);
|
||||
if (!m_reset)
|
||||
m_zaccept = false;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(taito_sj_security_mcu_device::do_host_write)
|
||||
{
|
||||
m_host_data = u8(param);
|
||||
if (!m_reset)
|
||||
{
|
||||
m_zready = true;
|
||||
// FIXME: this can be jumpered off if ZINTRQ is being used
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
|
||||
}
|
||||
}
|
100
src/mame/machine/taitosjsec.h
Normal file
100
src/mame/machine/taitosjsec.h
Normal file
@ -0,0 +1,100 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
#ifndef MAME_MACHINE_TAITSJSEC_H
|
||||
#define MAME_MACHINE_TAITSJSEC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/m6805/m68705.h"
|
||||
|
||||
// TODO: there should be a device representing the whole security board with both the Z80 and 68705
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(TAITO_SJ_SECURITY_MCU, taito_sj_security_mcu_device)
|
||||
|
||||
|
||||
#define MCFG_TAITO_SJ_SECURITY_MCU_68READ_CB(cb) \
|
||||
devcb = &taito_sj_security_mcu_device::set_68read_cb(*device, DEVCB_##cb);
|
||||
#define MCFG_TAITO_SJ_SECURITY_MCU_68WRITE_CB(cb) \
|
||||
devcb = &taito_sj_security_mcu_device::set_68write_cb(*device, DEVCB_##cb);
|
||||
#define MCFG_TAITO_SJ_SECURITY_MCU_68INTRQ_CB(cb) \
|
||||
devcb = &taito_sj_security_mcu_device::set_68intrq_cb(*device, DEVCB_##cb);
|
||||
#define MCFG_TAITO_SJ_SECURITY_MCU_BUSRQ_CB(cb) \
|
||||
devcb = &taito_sj_security_mcu_device::set_busrq_cb(*device, DEVCB_##cb);
|
||||
|
||||
class taito_sj_security_mcu_device : public device_t
|
||||
{
|
||||
public:
|
||||
template <typename Obj> static devcb_base &set_68read_cb(device_t &device, Obj &&cb)
|
||||
{ return downcast<taito_sj_security_mcu_device &>(device).m_68read_cb.set_callback(std::forward<Obj>(cb)); }
|
||||
template <typename Obj> static devcb_base &set_68write_cb(device_t &device, Obj &&cb)
|
||||
{ return downcast<taito_sj_security_mcu_device &>(device).m_68write_cb.set_callback(std::forward<Obj>(cb)); }
|
||||
template <typename Obj> static devcb_base &set_68intrq_cb(device_t &device, Obj &&cb)
|
||||
{ return downcast<taito_sj_security_mcu_device &>(device).m_68intrq_cb.set_callback(std::forward<Obj>(cb)); }
|
||||
template <typename Obj> static devcb_base &set_busrq_cb(device_t &device, Obj &&cb)
|
||||
{ return downcast<taito_sj_security_mcu_device &>(device).m_busrq_cb.set_callback(std::forward<Obj>(cb)); }
|
||||
|
||||
taito_sj_security_mcu_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock);
|
||||
|
||||
// uses two consecutive addresses
|
||||
DECLARE_READ8_MEMBER(data_r);
|
||||
DECLARE_WRITE8_MEMBER(data_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(busak_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(reset_w);
|
||||
|
||||
protected:
|
||||
void device_start() override;
|
||||
void device_reset() override;
|
||||
void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
DECLARE_READ8_MEMBER(mcu_pa_r);
|
||||
DECLARE_READ8_MEMBER(mcu_pc_r);
|
||||
DECLARE_WRITE8_MEMBER(mcu_pa_w);
|
||||
DECLARE_WRITE8_MEMBER(mcu_pb_w);
|
||||
|
||||
private:
|
||||
u8 const get_bus_val() const
|
||||
{ return (BIT(~m_pb_val, 1) ? m_host_data : 0xffU) & m_pa_val & ((m_busak && BIT(~m_pb_val, 5)) ? m_read_data : 0xffU); }
|
||||
|
||||
TIMER_CALLBACK_MEMBER(do_mcu_read);
|
||||
TIMER_CALLBACK_MEMBER(do_mcu_write);
|
||||
TIMER_CALLBACK_MEMBER(do_host_write);
|
||||
|
||||
required_device<m68705p_device> m_mcu;
|
||||
|
||||
devcb_read8 m_68read_cb;
|
||||
devcb_write8 m_68write_cb;
|
||||
devcb_write_line m_68intrq_cb;
|
||||
devcb_write_line m_busrq_cb;
|
||||
|
||||
// IC6/IC10 latch/count the low byte, IC14 buffers low byte, IC3 latches high byte
|
||||
u16 m_addr;
|
||||
|
||||
// latched by IC9
|
||||
u8 m_mcu_data;
|
||||
|
||||
// latched by IC13
|
||||
u8 m_host_data;
|
||||
|
||||
// buffered by IC16
|
||||
u8 m_read_data;
|
||||
|
||||
// IC7 pin 6, indicates CPU has accepted data from MCU
|
||||
bool m_zaccept;
|
||||
|
||||
// IC7 pin 9, indicates CPU has sent data to MCU
|
||||
bool m_zready;
|
||||
|
||||
// previous MCU port outputs for detecting edges
|
||||
u8 m_pa_val, m_pb_val;
|
||||
|
||||
// input state
|
||||
bool m_busak, m_reset;
|
||||
};
|
||||
|
||||
#endif // MAME_MACHINE_TATISJSEC_H
|
Loading…
Reference in New Issue
Block a user