start putting some 68705 functionality in the CPU core rather than copy+pasted in all the drivers.

as this is a lengthy task I've created a derived CPU type with the new functionality to aid in the process without disrupting existing drivers that haven't yet been updated.

started with tiger heli / slap fight.
This commit is contained in:
David Haywood 2016-12-22 19:42:40 +00:00
parent 9c2ca81b06
commit 50eb47f54e
5 changed files with 370 additions and 202 deletions

View File

@ -415,6 +415,14 @@ m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *
{
}
m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source),
m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map)
{
}
void m6805_base_device::device_start()
{
m_program = &space(AS_PROGRAM);
@ -448,6 +456,7 @@ void m6805_base_device::device_start()
}
void m6805_base_device::device_reset()
{
m_ea.w.l = 0;
@ -954,6 +963,159 @@ void m68705_device::execute_set_input(int inputnum, int state)
}
}
/* ddr - direction registers */
WRITE8_MEMBER(m68705_new_device::mc68705_ddrA_w)
{
m_ddrA = data;
}
WRITE8_MEMBER(m68705_new_device::mc68705_ddrB_w)
{
m_ddrB = data;
}
WRITE8_MEMBER(m68705_new_device::mc68705_ddrC_w)
{
m_ddrC = data;
}
/* read ports */
READ8_MEMBER(m68705_new_device::mc68705_portA_r)
{
m_portA_in = m_portA_cb_r(0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled
uint8_t res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
return res;
}
READ8_MEMBER(m68705_new_device::mc68705_portB_r)
{
m_portB_in = m_portB_cb_r(0, ~m_ddrB);
uint8_t res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
return res;
}
READ8_MEMBER(m68705_new_device::mc68705_portC_r)
{
m_portC_in = m_portC_cb_r(0, ~m_ddrC);
uint8_t res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
return res;
}
/* write ports */
WRITE8_MEMBER(m68705_new_device::mc68705_portA_w)
{
m_portA_cb_w(0, data, m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pushed
m_portA_out = data;
}
WRITE8_MEMBER(m68705_new_device::mc68705_portB_w)
{
m_portB_cb_w(0, data, m_ddrB);
m_portB_out = data;
}
WRITE8_MEMBER(m68705_new_device::mc68705_portC_w)
{
m_portC_cb_w(0, data, m_ddrC);
m_portC_out = data;
}
/*
The 68(7)05 peripheral memory map:
Common for Px, Rx, Ux parts:
0x00: Port A data (RW)
0x01: Port B data (RW)
0x02: Port C data (RW) [top 4 bits do nothing (read as 1s) on Px parts, work as expected on Rx, Ux parts]
0x03: [Port D data (RW), only on Rx, Ux parts]
0x04: Port A DDR (Write only, reads as 0xFF)
0x05: Port B DDR (Write only, reads as 0xFF)
0x06: Port C DDR (Write only, reads as 0xFF) [top 4 bits do nothing on Px parts, work as expected on Rx, Ux parts]
0x07: Unused (reads as 0xFF?)
0x08: Timer Data Register (RW; acts as ram when timer isn't counting, otherwise decrements once per prescaler expiry)
0x09: Timer Control Register (RW; on certain mask part and when MOR bit 6 is not set, all bits are RW except bit 3 which
always reads as zero. when MOR bit 6 is set and on all mask parts except one listed in errata in the 6805 daatsheet,
the top two bits are RW, bottom 6 always read as 1 and writes do nothing; on the errata chip, bit 3 is writable and
clears the prescaler, reads as zero)
0x0A: [Miscellaneous Register, only on Rx, Sx, Ux parts]
0x0B: [Eprom parts: Programming Control Register (write only?, low 3 bits; reads as 0xFF?); Unused (reads as 0xFF?) on
Mask parts]
0x0C: Unused (reads as 0xFF?)
0x0D: Unused (reads as 0xFF?)
0x0E: [A/D control register, only on Rx, Ux, Sx parts]
0x0F: [A/D result register, only on Rx, Ux, Sx parts]
0x10-0x7f: internal ram; SP can only point to 0x60-0x7F. Rx parts have an unused hole from 0x10-0x3F (reads as 0xFF?)
0x80-0xFF: Page 0 user rom
The remainder of the memory map differs here between parts, see appropriate datasheet for each part.
The four vectors are always stored in big endian form as the last 8 bytes of the address space.
Sx specific differences:
0x02: Port C data (RW) [top 6 bits do nothing (read as 1s) on Sx parts]
0x06: Port C DDR (Write only, reads as 0xFF) [top 6 bits do nothing on Sx parts]
0x0B: Timer 2 Data Register MSB
0x0C: Timer 2 Data Register LSB
0x0D: Timer 2 Control Register
0x10: SPI Data Register
0x11: SPI Control Register
0x12-0x3F: Unused (reads as 0xFF?)
MOR ADDRESS: Mask Option Register; does not exist on R2 and several other but not all mask parts, located at 0x784 on Px parts
Rx Parts: 40 pins; address space is 0x000-0xfff with an unused hole at 0x10-0x3f and and 0x100-0x7BF; has A/D converter, Ports A-D;
eprom parts have MOR at 0xF38; mask parts have selftest rom at similar area; selftest roms differ between the U2 and U3 versions
Px Parts: 28 pins; address space is 0x000-0x7ff; eprom parts have MOR at 0x784 and bootstrap rom at 0x785-0x7f7; mask parts have a
selftest rom at similar area; port c is just 4 bits.
Sx Parts: 40 pins; address space is 0x000-0xfff with an unused hole at 0x12-0x3f and and 0x100-0x9BF; has A/D converter; has SPI
serial; port C is just two bits; has an extra 16-bit timer compared to Ux/Rx; selftest rom at 0xF00-0xFF7
Ux Parts: 40 pins; address space is 0x000-0xfff; has A/D converter, Ports A-D; eprom parts have MOR at 0xF38; mask parts have
selftest rom at similar area; selftest roms differ between the U2 and U3 versions
*/
ADDRESS_MAP_START( m68705_internal_map, AS_PROGRAM, 8, m68705_new_device )
AM_RANGE(0x000, 0x000) AM_READWRITE(mc68705_portA_r, mc68705_portA_w)
AM_RANGE(0x001, 0x001) AM_READWRITE(mc68705_portB_r, mc68705_portB_w)
AM_RANGE(0x002, 0x002) AM_READWRITE(mc68705_portC_r, mc68705_portC_w)
AM_RANGE(0x004, 0x004) AM_WRITE(mc68705_ddrA_w)
AM_RANGE(0x005, 0x005) AM_WRITE(mc68705_ddrB_w)
AM_RANGE(0x006, 0x006) AM_WRITE(mc68705_ddrC_w)
AM_RANGE(0x010, 0x07f) AM_RAM
AM_RANGE(0x080, 0x7ff) AM_ROM
ADDRESS_MAP_END
void m68705_new_device::device_start()
{
m68705_device::device_start();
save_item(NAME(m_portA_in));
save_item(NAME(m_portB_in));
save_item(NAME(m_portC_in));
save_item(NAME(m_portA_out));
save_item(NAME(m_portB_out));
save_item(NAME(m_portC_out));
save_item(NAME(m_ddrA));
save_item(NAME(m_ddrB));
save_item(NAME(m_ddrC));
m_portA_cb_w.resolve_safe();
m_portB_cb_w.resolve_safe();
m_portC_cb_w.resolve_safe();
m_portA_cb_r.resolve_safe(0xff);
m_portB_cb_r.resolve_safe(0xff);
m_portC_cb_r.resolve_safe(0xff);
}
/****************************************************************************
* HD63705 section
@ -1000,4 +1162,5 @@ void hd63705_device::execute_set_input(int inputnum, int state)
const device_type M6805 = &device_creator<m6805_device>;
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
const device_type M68705 = &device_creator<m68705_device>;
const device_type M68705_NEW = &device_creator<m68705_new_device>;
const device_type HD63705 = &device_creator<hd63705_device>;

View File

@ -17,6 +17,7 @@ class m6805_device;
extern const device_type M6805;
extern const device_type M68HC05EG;
extern const device_type M68705;
extern const device_type M68705_NEW;
extern const device_type HD63705;
// ======================> m6805_base_device
@ -27,6 +28,7 @@ class m6805_base_device : public cpu_device
public:
// construction/destruction
m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source);
m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source);
protected:
// device-level overrides
@ -328,6 +330,10 @@ public:
m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__) { }
m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source)
: m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) { }
protected:
// device-level overrides
virtual void device_reset() override;
@ -337,6 +343,106 @@ protected:
virtual void interrupt() override;
};
// ======================> m68705_new_device
ADDRESS_MAP_EXTERN(m68705_internal_map, 8);
#define MCFG_M68705_PORTA_W_CB(_devcb) \
m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTB_W_CB(_devcb) \
m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTC_W_CB(_devcb) \
m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTA_R_CB(_devcb) \
m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTB_R_CB(_devcb) \
m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTC_R_CB(_devcb) \
m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb);
class m68705_new_device : public m68705_device
{
public:
// construction/destruction
m68705_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: m68705_device(mconfig, tag, owner, clock, M68705, "M68705 (NEW)", 11, ADDRESS_MAP_NAME( m68705_internal_map ), "m68705_new", __FILE__),
m_portA_in(0),
m_portB_in(0),
m_portC_in(0),
m_portA_out(0),
m_portB_out(0),
m_portC_out(0),
m_ddrA(0),
m_ddrB(0),
m_ddrC(0),
m_portA_cb_w(*this),
m_portB_cb_w(*this),
m_portC_cb_w(*this),
m_portA_cb_r(*this),
m_portB_cb_r(*this),
m_portC_cb_r(*this)
{ }
// static configuration helpers
template<class _Object> static devcb_base &set_portA_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portA_cb_w.set_callback(object); }
template<class _Object> static devcb_base &set_portB_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portB_cb_w.set_callback(object); }
template<class _Object> static devcb_base &set_portC_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portC_cb_w.set_callback(object); }
template<class _Object> static devcb_base &set_portA_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portA_cb_r.set_callback(object); }
template<class _Object> static devcb_base &set_portB_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portB_cb_r.set_callback(object); }
template<class _Object> static devcb_base &set_portC_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portC_cb_r.set_callback(object); }
DECLARE_READ8_MEMBER(mc68705_portA_r);
DECLARE_READ8_MEMBER(mc68705_portB_r);
DECLARE_READ8_MEMBER(mc68705_portC_r);
DECLARE_WRITE8_MEMBER(mc68705_portA_w);
DECLARE_WRITE8_MEMBER(mc68705_portB_w);
DECLARE_WRITE8_MEMBER(mc68705_portC_w);
DECLARE_WRITE8_MEMBER(mc68705_ddrA_w);
DECLARE_WRITE8_MEMBER(mc68705_ddrB_w);
DECLARE_WRITE8_MEMBER(mc68705_ddrC_w);
protected:
uint8_t m_portA_in;
uint8_t m_portB_in;
uint8_t m_portC_in;
uint8_t m_portA_out;
uint8_t m_portB_out;
uint8_t m_portC_out;
uint8_t m_ddrA;
uint8_t m_ddrB;
uint8_t m_ddrC;
/* Callbacks */
devcb_write8 m_portA_cb_w;
devcb_write8 m_portB_cb_w;
devcb_write8 m_portC_cb_w;
devcb_read8 m_portA_cb_r;
devcb_read8 m_portB_cb_r;
devcb_read8 m_portC_cb_r;
// device-level overrides
virtual void device_start() override;
// virtual void execute_set_input(int inputnum, int state) override;
// virtual void interrupt() override;
};
// ======================> hd63705_device
class hd63705_device : public m6805_base_device

View File

@ -481,39 +481,6 @@ ADDRESS_MAP_END
/***************************************************************************
MCU Memory Maps
NOTE: handlers and simulation are in the src/mame/machine folder
***************************************************************************/
static ADDRESS_MAP_START( tigerh_m68705_map, AS_PROGRAM, 8, slapfght_state )
ADDRESS_MAP_GLOBAL_MASK(0x7ff)
AM_RANGE(0x0000, 0x0000) AM_READWRITE(tigerh_68705_portA_r, tigerh_68705_portA_w)
AM_RANGE(0x0001, 0x0001) AM_READWRITE(tigerh_68705_portB_r, tigerh_68705_portB_w)
AM_RANGE(0x0002, 0x0002) AM_READWRITE(tigerh_68705_portC_r, tigerh_68705_portC_w)
AM_RANGE(0x0004, 0x0004) AM_WRITE(tigerh_68705_ddrA_w)
AM_RANGE(0x0005, 0x0005) AM_WRITE(tigerh_68705_ddrB_w)
AM_RANGE(0x0006, 0x0006) AM_WRITE(tigerh_68705_ddrC_w)
AM_RANGE(0x0010, 0x007f) AM_RAM
AM_RANGE(0x0080, 0x07ff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START( slapfight_m68705_map, AS_PROGRAM, 8, slapfght_state )
ADDRESS_MAP_GLOBAL_MASK(0x7ff)
AM_RANGE(0x0000, 0x0000) AM_READWRITE(slapfight_68705_portA_r, slapfight_68705_portA_w)
AM_RANGE(0x0001, 0x0001) AM_READWRITE(slapfight_68705_portB_r, slapfight_68705_portB_w)
AM_RANGE(0x0002, 0x0002) AM_READWRITE(slapfight_68705_portC_r, slapfight_68705_portC_w)
AM_RANGE(0x0004, 0x0004) AM_WRITE(slapfight_68705_ddrA_w)
AM_RANGE(0x0005, 0x0005) AM_WRITE(slapfight_68705_ddrB_w)
AM_RANGE(0x0006, 0x0006) AM_WRITE(slapfight_68705_ddrC_w)
AM_RANGE(0x0010, 0x007f) AM_RAM
AM_RANGE(0x0080, 0x07ff) AM_ROM
ADDRESS_MAP_END
/***************************************************************************
@ -770,15 +737,9 @@ void slapfght_state::machine_start()
m_main_sent = false;
m_from_main = 0;
m_from_mcu = 0;
m_portA_in = 0;
m_portA_out = 0;
m_ddrA = 0;
m_portB_in = 0;
m_portB_out = 0;
m_ddrB = 0;
m_portC_in = 0;
m_portC_out = 0;
m_ddrC = 0;
m_from_mcu_latch = 0;
m_to_mcu_latch = 0;
m_old_portB = 0;
m_getstar_status = 0;
m_getstar_sequence_index = 0;
@ -801,15 +762,10 @@ void slapfght_state::machine_start()
save_item(NAME(m_main_sent));
save_item(NAME(m_from_main));
save_item(NAME(m_from_mcu));
save_item(NAME(m_portA_in));
save_item(NAME(m_portA_out));
save_item(NAME(m_ddrA));
save_item(NAME(m_portB_in));
save_item(NAME(m_portB_out));
save_item(NAME(m_ddrB));
save_item(NAME(m_portC_in));
save_item(NAME(m_portC_out));
save_item(NAME(m_ddrC));
save_item(NAME(m_from_mcu_latch));
save_item(NAME(m_to_mcu_latch));
save_item(NAME(m_old_portB));
save_item(NAME(m_getstar_status));
save_item(NAME(m_getstar_sequence_index));
@ -1030,8 +986,13 @@ static MACHINE_CONFIG_START( tigerh, slapfght_state )
MCFG_CPU_PROGRAM_MAP(tigerh_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(slapfght_state, sound_nmi, 360) // music speed, verified with pcb recording
MCFG_CPU_ADD("mcu", M68705, XTAL_36MHz/12) // 3MHz
MCFG_CPU_PROGRAM_MAP(tigerh_m68705_map)
MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_36MHz/12) // 3MHz
MCFG_M68705_PORTA_R_CB(READ8(slapfght_state, tigerh_mcu_porta_r))
MCFG_M68705_PORTA_W_CB(WRITE8(slapfght_state, tigerh_mcu_porta_w))
MCFG_M68705_PORTB_W_CB(WRITE8(slapfght_state, tigerh_mcu_portb_w))
MCFG_M68705_PORTC_R_CB(READ8(slapfght_state, tigerh_mcu_portc_r))
MCFG_QUANTUM_PERFECT_CPU("maincpu")
@ -1095,8 +1056,11 @@ static MACHINE_CONFIG_START( slapfigh, slapfght_state )
MCFG_CPU_PROGRAM_MAP(tigerh_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(slapfght_state, sound_nmi, 180)
MCFG_CPU_ADD("mcu", M68705, XTAL_36MHz/12) // 3MHz
MCFG_CPU_PROGRAM_MAP(slapfight_m68705_map)
MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_36MHz/12) // 3MHz
MCFG_M68705_PORTA_R_CB(READ8(slapfght_state, tigerh_mcu_porta_r))
MCFG_M68705_PORTA_W_CB(WRITE8(slapfght_state, tigerh_mcu_porta_w))
MCFG_M68705_PORTB_W_CB(WRITE8(slapfght_state, slapfght_mcu_portb_w))
MCFG_M68705_PORTC_R_CB(READ8(slapfght_state, slapfght_mcu_portc_r))
MCFG_QUANTUM_PERFECT_CPU("maincpu")

View File

@ -65,15 +65,10 @@ public:
bool m_main_sent;
uint8_t m_from_main;
uint8_t m_from_mcu;
uint8_t m_portA_in;
uint8_t m_portA_out;
uint8_t m_ddrA;
uint8_t m_portB_in;
uint8_t m_portB_out;
uint8_t m_ddrB;
uint8_t m_portC_in;
uint8_t m_portC_out;
uint8_t m_ddrC;
uint8_t m_from_mcu_latch;
uint8_t m_to_mcu_latch;
uint8_t m_old_portB;
int m_getstar_status;
int m_getstar_sequence_index;
@ -102,25 +97,16 @@ public:
DECLARE_WRITE8_MEMBER(tigerh_mcu_w);
DECLARE_READ8_MEMBER(tigerh_mcu_r);
DECLARE_READ8_MEMBER(tigerh_mcu_status_r);
DECLARE_READ8_MEMBER(tigerh_68705_portA_r);
DECLARE_WRITE8_MEMBER(tigerh_68705_portA_w);
DECLARE_WRITE8_MEMBER(tigerh_68705_ddrA_w);
DECLARE_READ8_MEMBER(tigerh_68705_portB_r);
DECLARE_WRITE8_MEMBER(tigerh_68705_portB_w);
DECLARE_WRITE8_MEMBER(tigerh_68705_ddrB_w);
DECLARE_READ8_MEMBER(tigerh_68705_portC_r);
DECLARE_WRITE8_MEMBER(tigerh_68705_portC_w);
DECLARE_WRITE8_MEMBER(tigerh_68705_ddrC_w);
DECLARE_READ8_MEMBER(slapfight_68705_portA_r);
DECLARE_WRITE8_MEMBER(slapfight_68705_portA_w);
DECLARE_WRITE8_MEMBER(slapfight_68705_ddrA_w);
DECLARE_READ8_MEMBER(slapfight_68705_portB_r);
DECLARE_WRITE8_MEMBER(slapfight_68705_portB_w);
DECLARE_WRITE8_MEMBER(slapfight_68705_ddrB_w);
DECLARE_READ8_MEMBER(slapfight_68705_portC_r);
DECLARE_WRITE8_MEMBER(slapfight_68705_portC_w);
DECLARE_WRITE8_MEMBER(slapfight_68705_ddrC_w);
DECLARE_READ8_MEMBER(tigerh_mcu_porta_r);
DECLARE_WRITE8_MEMBER(tigerh_mcu_porta_w);
DECLARE_WRITE8_MEMBER(tigerh_mcu_portb_w);
DECLARE_WRITE8_MEMBER(slapfght_mcu_portb_w);
DECLARE_READ8_MEMBER(tigerh_mcu_portc_r);
DECLARE_READ8_MEMBER(slapfght_mcu_portc_r);
DECLARE_READ8_MEMBER(getstar_mcusim_r);
DECLARE_WRITE8_MEMBER(getstar_mcusim_w);

View File

@ -48,159 +48,108 @@ READ8_MEMBER(slapfght_state::tigerh_mcu_status_r)
}
/**************************************************************************/
/***************************************************************************
READ8_MEMBER(slapfght_state::tigerh_68705_portA_r)
MCU port handlers (general)
***************************************************************************/
READ8_MEMBER(slapfght_state::tigerh_mcu_porta_r)
{
return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
return m_to_mcu_latch;
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_portA_w)
WRITE8_MEMBER(slapfght_state::tigerh_mcu_porta_w)
{
m_portA_out = data;
m_from_mcu_latch = data;
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_ddrA_w)
{
m_ddrA = data;
}
READ8_MEMBER(slapfght_state::tigerh_68705_portB_r)
{
return (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_portB_w)
{
if ((m_ddrB & 0x02) && (~data & 0x02) && (m_portB_out & 0x02))
{
if (m_main_sent)
m_mcu->set_input_line(0, CLEAR_LINE);
m_portA_in = m_from_main;
m_main_sent = false;
}
if ((m_ddrB & 0x04) && (data & 0x04) && (~m_portB_out & 0x04))
{
m_from_mcu = m_portA_out;
m_mcu_sent = true;
}
m_portB_out = data;
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_ddrB_w)
{
m_ddrB = data;
}
READ8_MEMBER(slapfght_state::tigerh_68705_portC_r)
{
m_portC_in = 0;
if (!m_main_sent)
m_portC_in |= 0x01;
if (m_mcu_sent)
m_portC_in |= 0x02;
return (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_portC_w)
{
m_portC_out = data;
}
WRITE8_MEMBER(slapfght_state::tigerh_68705_ddrC_w)
{
m_ddrC = data;
}
/***************************************************************************
Slap Fight MCU
MCU port handlers (Tiger Heli)
***************************************************************************/
READ8_MEMBER(slapfght_state::slapfight_68705_portA_r)
WRITE8_MEMBER(slapfght_state::tigerh_mcu_portb_w)
{
return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_portA_w)
{
m_portA_out = data;
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_ddrA_w)
{
m_ddrA = data;
}
READ8_MEMBER(slapfght_state::slapfight_68705_portB_r)
{
return (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_portB_w)
{
if ((m_ddrB & 0x02) && (~data & 0x02) && (m_portB_out & 0x02))
if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
{
if (m_main_sent)
m_mcu->set_input_line(0, CLEAR_LINE);
m_portA_in = m_from_main;
m_to_mcu_latch = m_from_main;
m_main_sent = false;
}
if ((m_ddrB & 0x04) && (data & 0x04) && (~m_portB_out & 0x04))
if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
{
m_from_mcu = m_portA_out;
m_from_mcu = m_from_mcu_latch;
m_mcu_sent = true;
}
if ((m_ddrB & 0x08) && (~data & 0x08) && (m_portB_out & 0x08))
{
m_scrollx_lo = m_portA_out;
}
if ((m_ddrB & 0x10) && (~data & 0x10) && (m_portB_out & 0x10))
{
m_scrollx_hi = m_portA_out;
}
m_portB_out = data;
m_old_portB = data;
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_ddrB_w)
READ8_MEMBER(slapfght_state::tigerh_mcu_portc_r)
{
m_ddrB = data;
uint8_t ret = 0;
if (!m_main_sent)
ret |= 0x01;
if (m_mcu_sent)
ret |= 0x02;
return ret;
}
READ8_MEMBER(slapfght_state::slapfight_68705_portC_r)
{
m_portC_in = 0;
/***************************************************************************
MCU port handlers (Slap Fight)
***************************************************************************/
WRITE8_MEMBER(slapfght_state::slapfght_mcu_portb_w)
{
if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
{
if (m_main_sent)
m_portC_in |= 0x01;
if (!m_mcu_sent)
m_portC_in |= 0x02;
m_mcu->set_input_line(0, CLEAR_LINE);
return (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
m_to_mcu_latch = m_from_main;
m_main_sent = false;
}
if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
{
m_from_mcu = m_from_mcu_latch;
m_mcu_sent = true;
}
if ((mem_mask & 0x08) && (~data & 0x08) && (m_old_portB & 0x08))
{
m_scrollx_lo = m_from_mcu_latch;
}
if ((mem_mask & 0x10) && (~data & 0x10) && (m_old_portB & 0x10))
{
m_scrollx_hi = m_from_mcu_latch;
}
m_old_portB = data;
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_portC_w)
READ8_MEMBER(slapfght_state::slapfght_mcu_portc_r)
{
m_portC_out = data;
uint8_t ret = 0;
if (!m_main_sent)
ret |= 0x01;
if (m_mcu_sent)
ret |= 0x02;
ret ^= 0x3; // inverted logic compared to tigerh
return ret;
}
WRITE8_MEMBER(slapfght_state::slapfight_68705_ddrC_w)
{
m_ddrC = data;
}
/***************************************************************************
Get Star MCU simulation :(