mirror of
https://github.com/holub/mame
synced 2025-07-03 00:56:03 +03:00
move 68705 timer logic out of arkanoid driver and into 68705 core
(note, probably needs to use clock derived from 68705 clock)
This commit is contained in:
parent
1f044c7fd1
commit
70b23e6f93
@ -1107,6 +1107,86 @@ WRITE8_MEMBER(m68705_new_device::pc_w)
|
||||
COMBINE_DATA(&m_portC_in);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tdr_r)
|
||||
{
|
||||
//logerror("internal_68705 TDR read, returning %02X\n", m_tdr);
|
||||
return m_tdr;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tdr_w)
|
||||
{
|
||||
//logerror("internal_68705 TDR written with %02X, was %02X\n", data, m_tdr);
|
||||
m_tdr = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tcr_r)
|
||||
{
|
||||
//logerror("internal_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
|
||||
return (m_tcr & 0xF7);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tcr_w)
|
||||
{
|
||||
/*
|
||||
logerror("internal_68705 TCR written with %02X\n", data);
|
||||
if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
|
||||
if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
|
||||
if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
|
||||
if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
|
||||
if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
|
||||
logerror(" Prescaler: %d\n", (1<<(data&0x7)));
|
||||
*/
|
||||
// if timer was enabled but now isn't, shut it off.
|
||||
// below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
|
||||
// Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
|
||||
if ((m_tcr^data)&0x20)// check if TIN state changed
|
||||
{
|
||||
/* logerror("timer enable state changed!\n"); */
|
||||
if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
|
||||
else m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
// prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
|
||||
if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
|
||||
{
|
||||
/* logerror("timer reset due to PSC or prescaler change!\n"); */
|
||||
m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
m_tcr = data;
|
||||
// if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
|
||||
}
|
||||
|
||||
void m68705_new_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_68705_PRESCALER_EXPIRED:
|
||||
timer_68705_increment(ptr, param);
|
||||
break;
|
||||
default:
|
||||
assert_always(false, "Unknown id in m68705_new_device::device_timer");
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(m68705_new_device::timer_68705_increment)
|
||||
{
|
||||
m_tdr++;
|
||||
if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(m_tcr&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
The 68(7)05 peripheral memory map:
|
||||
@ -1170,6 +1250,10 @@ DEVICE_ADDRESS_MAP_START( internal_map, 8, m68705_new_device )
|
||||
AM_RANGE(0x005, 0x005) AM_WRITE(internal_ddrB_w)
|
||||
AM_RANGE(0x006, 0x006) AM_WRITE(internal_ddrC_w)
|
||||
|
||||
AM_RANGE(0x008, 0x008) AM_READWRITE(internal_68705_tdr_r, internal_68705_tdr_w)
|
||||
AM_RANGE(0x009, 0x009) AM_READWRITE(internal_68705_tcr_r, internal_68705_tcr_w)
|
||||
|
||||
|
||||
AM_RANGE(0x010, 0x07f) AM_RAM
|
||||
AM_RANGE(0x080, 0x7ff) AM_ROM
|
||||
ADDRESS_MAP_END
|
||||
@ -1201,6 +1285,14 @@ void m68705_new_device::device_start()
|
||||
m_portA_in = 0xff;
|
||||
m_portB_in = 0xff;
|
||||
m_portC_in = 0xff;
|
||||
|
||||
// allocate the MCU timer, even if we have no MCU, and set it to fire NEVER.
|
||||
m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68705_new_device::timer_68705_increment),this));
|
||||
m_68705_timer->adjust(attotime::never);
|
||||
|
||||
save_item(NAME(m_tdr));
|
||||
save_item(NAME(m_tcr));
|
||||
|
||||
}
|
||||
|
||||
void m68705_new_device::device_reset()
|
||||
@ -1211,6 +1303,13 @@ void m68705_new_device::device_reset()
|
||||
m_ddrA = 0;
|
||||
m_ddrB = 0;
|
||||
m_ddrC = 0;
|
||||
|
||||
m_tdr = 0xFF;
|
||||
m_tcr = 0x7F;
|
||||
|
||||
//set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<7)));
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -406,6 +406,11 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(pc_w);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
TIMER_68705_PRESCALER_EXPIRED,
|
||||
};
|
||||
|
||||
DECLARE_ADDRESS_MAP(internal_map, 8);
|
||||
|
||||
DECLARE_READ8_MEMBER(internal_portA_r);
|
||||
@ -420,6 +425,11 @@ protected:
|
||||
DECLARE_WRITE8_MEMBER(internal_ddrB_w);
|
||||
DECLARE_WRITE8_MEMBER(internal_ddrC_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(internal_68705_tdr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tdr_w);
|
||||
DECLARE_READ8_MEMBER(internal_68705_tcr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tcr_w);
|
||||
|
||||
void update_portA_state();
|
||||
void update_portB_state();
|
||||
void update_portC_state();
|
||||
@ -436,6 +446,9 @@ protected:
|
||||
u8 m_ddrB;
|
||||
u8 m_ddrC;
|
||||
|
||||
u8 m_tdr;
|
||||
u8 m_tcr;
|
||||
|
||||
/* Callbacks */
|
||||
devcb_write8 m_portA_cb_w;
|
||||
devcb_write8 m_portB_cb_w;
|
||||
@ -445,6 +458,12 @@ protected:
|
||||
devcb_read8 m_portB_cb_r;
|
||||
devcb_read8 m_portC_cb_r;
|
||||
|
||||
/* Timers */
|
||||
emu_timer *m_68705_timer;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_68705_increment);
|
||||
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
@ -896,19 +896,6 @@ static ADDRESS_MAP_START( brixian_map, AS_PROGRAM, 8, arkanoid_state )
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( mcu_map, AS_PROGRAM, 8, arkanoid_state )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x7ff)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x0000, 0x0000) AM_READWRITE(arkanoid_68705_port_a_r, arkanoid_68705_port_a_w)
|
||||
AM_RANGE(0x0001, 0x0001) AM_READ_PORT("MUX")
|
||||
AM_RANGE(0x0002, 0x0002) AM_READWRITE(arkanoid_68705_port_c_r, arkanoid_68705_port_c_w)
|
||||
AM_RANGE(0x0004, 0x0004) AM_WRITE(arkanoid_68705_ddr_a_w)
|
||||
AM_RANGE(0x0006, 0x0006) AM_WRITE(arkanoid_68705_ddr_c_w)
|
||||
AM_RANGE(0x0008, 0x0008) AM_READWRITE(arkanoid_68705_tdr_r, arkanoid_68705_tdr_w)
|
||||
AM_RANGE(0x0009, 0x0009) AM_READWRITE(arkanoid_68705_tcr_r, arkanoid_68705_tcr_w)
|
||||
AM_RANGE(0x0010, 0x007f) AM_RAM
|
||||
AM_RANGE(0x0080, 0x07ff) AM_ROM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/* MCU Hookup based on 'Arkanoid_TAITO_(Japan 1986) PCB.rar' from Taro and others at http://zx-pk.ru forums
|
||||
NOTE and TODO: these comments have not been significantly updated since the real taito arkanoid schematics were found. beware of mistakes!
|
||||
@ -1271,9 +1258,6 @@ GFXDECODE_END
|
||||
|
||||
void arkanoid_state::machine_start()
|
||||
{
|
||||
// allocate the MCU timer, even if we have no MCU, and set it to fire NEVER.
|
||||
m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(arkanoid_state::timer_68705_increment),this));
|
||||
m_68705_timer->adjust(attotime::never);
|
||||
|
||||
save_item(NAME(m_gfxbank));
|
||||
save_item(NAME(m_palettebank));
|
||||
@ -1290,12 +1274,9 @@ void arkanoid_state::machine_start()
|
||||
|
||||
save_item(NAME(m_portA_in));
|
||||
save_item(NAME(m_portA_out));
|
||||
save_item(NAME(m_ddrA));
|
||||
save_item(NAME(m_portC_internal));
|
||||
save_item(NAME(m_portC_out));
|
||||
save_item(NAME(m_ddrC));
|
||||
save_item(NAME(m_tdr));
|
||||
save_item(NAME(m_tcr));
|
||||
save_item(NAME(m_old_portC_out));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void arkanoid_state::machine_reset()
|
||||
@ -1313,17 +1294,12 @@ void arkanoid_state::machine_reset()
|
||||
// the following 3 are all part of the 74ls74 at ic26 and are cleared on reset
|
||||
m_Z80HasWritten = 0;
|
||||
m_MCUHasWritten = 0;
|
||||
if (m_mcu.found()) m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
if (m_mcu.found()) m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<7)));
|
||||
|
||||
m_portA_in = 0;
|
||||
m_portA_out = 0;
|
||||
m_ddrA = 0;
|
||||
m_portC_internal = 0;
|
||||
m_portC_out = 0;
|
||||
m_ddrC = 0;
|
||||
m_tdr = 0xFF;
|
||||
m_tcr = 0x7F;
|
||||
m_old_portC_out = 0;
|
||||
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1346,8 +1322,13 @@ static MACHINE_CONFIG_START( arkanoid, arkanoid_state )
|
||||
|
||||
MCFG_WATCHDOG_ADD("watchdog")
|
||||
|
||||
MCFG_CPU_ADD("mcu", M68705, XTAL_12MHz/4) /* verified on pcb */
|
||||
MCFG_CPU_PROGRAM_MAP(mcu_map)
|
||||
MCFG_CPU_ADD("mcu", M68705_NEW, 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_QUANTUM_TIME(attotime::from_hz(6000)) // 100 CPU slices per second to synchronize between the MCU and the main CPU
|
||||
|
||||
|
@ -15,10 +15,7 @@ enum {
|
||||
class arkanoid_state : public driver_device
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
TIMER_68705_PRESCALER_EXPIRED,
|
||||
};
|
||||
|
||||
|
||||
arkanoid_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
@ -56,13 +53,13 @@ public:
|
||||
/* mcu internal related */
|
||||
uint8_t m_portA_in;
|
||||
uint8_t m_portA_out;
|
||||
uint8_t m_ddrA;
|
||||
uint8_t m_portC_internal;
|
||||
uint8_t m_portC_out;
|
||||
uint8_t m_ddrC;
|
||||
uint8_t m_tdr;
|
||||
uint8_t m_tcr;
|
||||
emu_timer *m_68705_timer;
|
||||
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;
|
||||
@ -76,16 +73,8 @@ public:
|
||||
|
||||
DECLARE_READ8_MEMBER(arkanoid_Z80_mcu_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_Z80_mcu_w);
|
||||
DECLARE_READ8_MEMBER(arkanoid_68705_port_a_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_port_a_w);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_ddr_a_w);
|
||||
DECLARE_READ8_MEMBER(arkanoid_68705_port_c_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_port_c_w);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_ddr_c_w);
|
||||
DECLARE_READ8_MEMBER(arkanoid_68705_tdr_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_tdr_w);
|
||||
DECLARE_READ8_MEMBER(arkanoid_68705_tcr_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_68705_tcr_w);
|
||||
|
||||
|
||||
DECLARE_READ8_MEMBER(arkanoid_bootleg_f000_r);
|
||||
DECLARE_READ8_MEMBER(arkanoid_bootleg_f002_r);
|
||||
DECLARE_WRITE8_MEMBER(arkanoid_bootleg_d018_w);
|
||||
@ -118,10 +107,7 @@ public:
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_arkanoid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_hexa(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_CALLBACK_MEMBER(timer_68705_increment);
|
||||
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void arkanoid_bootleg_init( );
|
||||
|
||||
protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
};
|
||||
|
@ -32,98 +32,17 @@ WRITE8_MEMBER(arkanoid_state::arkanoid_Z80_mcu_w)
|
||||
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
|
||||
}
|
||||
|
||||
READ8_MEMBER(arkanoid_state::arkanoid_68705_port_a_r)
|
||||
READ8_MEMBER(arkanoid_state::mcu_porta_r)
|
||||
{
|
||||
return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
|
||||
return m_portA_in;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_port_a_w)
|
||||
WRITE8_MEMBER(arkanoid_state::mcu_porta_w)
|
||||
{
|
||||
m_portA_out = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_ddr_a_w)
|
||||
{
|
||||
m_ddrA = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(arkanoid_state::arkanoid_68705_tdr_r)
|
||||
{
|
||||
//logerror("arkanoid_68705 TDR read, returning %02X\n", m_tdr);
|
||||
return m_tdr;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_tdr_w)
|
||||
{
|
||||
//logerror("arkanoid_68705 TDR written with %02X, was %02X\n", data, m_tdr);
|
||||
m_tdr = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(arkanoid_state::arkanoid_68705_tcr_r)
|
||||
{
|
||||
//logerror("arkanoid_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
|
||||
return (m_tcr & 0xF7);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_tcr_w)
|
||||
{
|
||||
/*
|
||||
logerror("arkanoid_68705 TCR written with %02X\n", data);
|
||||
if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
|
||||
if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
|
||||
if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
|
||||
if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
|
||||
if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
|
||||
logerror(" Prescaler: %d\n", (1<<(data&0x7)));
|
||||
*/
|
||||
// if timer was enabled but now isn't, shut it off.
|
||||
// below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
|
||||
// Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
|
||||
if ((m_tcr^data)&0x20)// check if TIN state changed
|
||||
{
|
||||
/* logerror("timer enable state changed!\n"); */
|
||||
if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
|
||||
else m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
// prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
|
||||
if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
|
||||
{
|
||||
/* logerror("timer reset due to PSC or prescaler change!\n"); */
|
||||
m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
m_tcr = data;
|
||||
// if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
m_mcu->set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
m_mcu->set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
|
||||
}
|
||||
|
||||
void arkanoid_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_68705_PRESCALER_EXPIRED:
|
||||
timer_68705_increment(ptr, param);
|
||||
break;
|
||||
default:
|
||||
assert_always(false, "Unknown id in arkanoid_state::device_timer");
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(arkanoid_state::timer_68705_increment)
|
||||
{
|
||||
m_tdr++;
|
||||
if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
m_mcu->set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
m_mcu->set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(m_tcr&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
|
||||
READ8_MEMBER(arkanoid_state::arkanoid_68705_port_c_r)
|
||||
READ8_MEMBER(arkanoid_state::mcu_portc_r)
|
||||
{
|
||||
int portC_in = 0;
|
||||
|
||||
@ -138,73 +57,45 @@ READ8_MEMBER(arkanoid_state::arkanoid_68705_port_c_r)
|
||||
/* 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 (m_portC_internal & m_ddrC) | (portC_in & ~m_ddrC);
|
||||
return portC_in;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_port_c_w)
|
||||
READ8_MEMBER(arkanoid_state::mcu_portb_r)
|
||||
{
|
||||
m_portC_internal = data|0xF0;
|
||||
uint8_t changed_m_portC_out = (m_portC_out^(m_portC_internal|(~m_ddrC)));
|
||||
m_portC_out = (m_portC_internal|(~m_ddrC));
|
||||
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 ((changed_m_portC_out&0x04) && (m_portC_out&0x04))
|
||||
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 (~m_portC_out&0x04)
|
||||
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 (~m_portC_out&0x08)
|
||||
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;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(arkanoid_state::arkanoid_68705_ddr_c_w)
|
||||
{
|
||||
if ((data|0xF0)^m_ddrC) // if ddr changed, recalculate the port c output
|
||||
{
|
||||
uint8_t changed_m_portC_out = (m_portC_out^(m_portC_internal|(~(data|0xF0))));
|
||||
m_portC_out = (m_portC_internal|(~(data|0xF0)));
|
||||
|
||||
/* 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 ((changed_m_portC_out&0x04) && (m_portC_out&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 (~m_portC_out&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 (~m_portC_out&0x08)
|
||||
{
|
||||
/* a write from the 68705 to the Z80; remember its value */
|
||||
m_MCUHasWritten = 1;
|
||||
m_fromMCU = m_portA_out;
|
||||
}
|
||||
}
|
||||
m_ddrC = data|0xF0;
|
||||
}
|
||||
|
||||
CUSTOM_INPUT_MEMBER(arkanoid_state::arkanoid_semaphore_input_r)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user