z80: added crude implementation of WAIT pin

This commit is contained in:
hap 2016-02-07 13:50:05 +01:00
parent 5bc83a2506
commit 4bcc966c7a
11 changed files with 47 additions and 62 deletions

View File

@ -310,14 +310,14 @@ WRITE_LINE_MEMBER( luxor_55_10828_device::fdc_intrq_w )
m_fdc_irq = state; m_fdc_irq = state;
m_pio->port_b_write(state << 7); m_pio->port_b_write(state << 7);
if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, CLEAR_LINE);
} }
WRITE_LINE_MEMBER( luxor_55_10828_device::fdc_drq_w ) WRITE_LINE_MEMBER( luxor_55_10828_device::fdc_drq_w )
{ {
m_fdc_drq = state; m_fdc_drq = state;
if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, CLEAR_LINE);
} }
@ -654,7 +654,7 @@ READ8_MEMBER( luxor_55_10828_device::fdc_r )
{ {
logerror("Z80 WAIT not supported by MAME core\n"); logerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
} }
return m_fdc->gen_r(offset); return m_fdc->gen_r(offset);
@ -671,7 +671,7 @@ WRITE8_MEMBER( luxor_55_10828_device::fdc_w )
{ {
logerror("Z80 WAIT not supported by MAME core\n"); logerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
} }
m_fdc->gen_w(offset, data); m_fdc->gen_w(offset, data);

View File

@ -10,6 +10,7 @@
* - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2 * - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2
* was set before this instruction (implemented, but not enabled: we need * was set before this instruction (implemented, but not enabled: we need
* document Z80 types first, see below) * document Z80 types first, see below)
* - WAIT only stalls between instructions now, it should stall immediately.
* - Ideally, the tiny differences between Z80 types should be supported, * - Ideally, the tiny differences between Z80 types should be supported,
* currently known differences: * currently known differences:
* - LD A,I/R P/V flag reset glitch is fixed on CMOS Z80 * - LD A,I/R P/V flag reset glitch is fixed on CMOS Z80
@ -113,10 +114,6 @@
#define VERBOSE 0 #define VERBOSE 0
/* Debug purpose: set to 1 to test /WAIT pin behaviour.
*/
#define STALLS_ON_WAIT_ASSERT 0
/* On an NMOS Z80, if LD A,I or LD A,R is interrupted, P/V flag gets reset, /* On an NMOS Z80, if LD A,I or LD A,R is interrupted, P/V flag gets reset,
even if IFF2 was set before this instruction. This issue was fixed on even if IFF2 was set before this instruction. This issue was fixed on
the CMOS Z80, so until knowing (most) Z80 types on hardware, it's disabled */ the CMOS Z80, so until knowing (most) Z80 types on hardware, it's disabled */
@ -3478,10 +3475,16 @@ void nsc800_device::device_reset()
} }
/**************************************************************************** /****************************************************************************
* Execute 'cycles' T-states. Return number of T-states really executed * Execute 'cycles' T-states.
****************************************************************************/ ****************************************************************************/
void z80_device::execute_run() void z80_device::execute_run()
{ {
if (m_wait_state)
{
// stalled
m_icount = 0;
return;
}
/* check for NMIs on the way in; they can only be set externally */ /* check for NMIs on the way in; they can only be set externally */
/* via timers, and can't be dynamically enabled, so it is safe */ /* via timers, and can't be dynamically enabled, so it is safe */
@ -3523,29 +3526,23 @@ void z80_device::execute_run()
PRVPC = PCD; PRVPC = PCD;
debugger_instruction_hook(this, PCD); debugger_instruction_hook(this, PCD);
m_r++; m_r++;
#if STALLS_ON_WAIT_ASSERT
static int test_cycles;
if(m_wait_state == ASSERT_LINE)
{
m_icount --;
test_cycles ++;
}
else
{
if(test_cycles != 0)
printf("stalls for %d z80 cycles\n",test_cycles);
test_cycles = 0;
EXEC(op,rop());
}
#else
EXEC(op,rop()); EXEC(op,rop());
#endif
if (m_wait_state)
m_icount = 0;
} while (m_icount > 0); } while (m_icount > 0);
} }
void nsc800_device::execute_run() void nsc800_device::execute_run()
{ {
if (m_wait_state)
{
// stalled
m_icount = 0;
return;
}
/* check for NMIs on the way in; they can only be set externally */ /* check for NMIs on the way in; they can only be set externally */
/* via timers, and can't be dynamically enabled, so it is safe */ /* via timers, and can't be dynamically enabled, so it is safe */
/* to just check here */ /* to just check here */
@ -3579,6 +3576,10 @@ void nsc800_device::execute_run()
debugger_instruction_hook(this, PCD); debugger_instruction_hook(this, PCD);
m_r++; m_r++;
EXEC(op,rop()); EXEC(op,rop());
if (m_wait_state)
m_icount = 0;
} while (m_icount > 0); } while (m_icount > 0);
} }
@ -3609,6 +3610,9 @@ void z80_device::execute_set_input(int inputnum, int state)
case Z80_INPUT_LINE_WAIT: case Z80_INPUT_LINE_WAIT:
m_wait_state = state; m_wait_state = state;
break; break;
default:
break;
} }
} }
@ -3616,17 +3620,6 @@ void nsc800_device::execute_set_input(int inputnum, int state)
{ {
switch (inputnum) switch (inputnum)
{ {
case Z80_INPUT_LINE_BUSRQ:
m_busrq_state = state;
break;
case INPUT_LINE_NMI:
/* mark an NMI pending on the rising edge */
if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE)
m_nmi_pending = TRUE;
m_nmi_state = state;
break;
case NSC800_RSTA: case NSC800_RSTA:
m_nsc800_irq_state[NSC800_RSTA] = state; m_nsc800_irq_state[NSC800_RSTA] = state;
break; break;
@ -3639,17 +3632,8 @@ void nsc800_device::execute_set_input(int inputnum, int state)
m_nsc800_irq_state[NSC800_RSTC] = state; m_nsc800_irq_state[NSC800_RSTC] = state;
break; break;
case INPUT_LINE_IRQ0: default:
/* update the IRQ state via the daisy chain */ z80_device::execute_set_input(inputnum, state);
m_irq_state = state;
if (m_daisy.present())
m_irq_state = m_daisy.update_irq_state();
/* the main execute loop will take the interrupt */
break;
case Z80_INPUT_LINE_WAIT:
m_wait_state = state;
break; break;
} }
} }

View File

@ -19,6 +19,7 @@ enum
NSC800_RSTB, NSC800_RSTB,
NSC800_RSTC, NSC800_RSTC,
Z80_INPUT_LINE_WAIT, Z80_INPUT_LINE_WAIT,
Z80_INPUT_LINE_BOGUSWAIT, /* WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT */
Z80_INPUT_LINE_BUSRQ Z80_INPUT_LINE_BUSRQ
}; };

View File

@ -1067,7 +1067,7 @@ static MACHINE_CONFIG_START( adam, adam_state )
MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD(SN76489A_TAG, SN76489A, XTAL_7_15909MHz/2) MCFG_SOUND_ADD(SN76489A_TAG, SN76489A, XTAL_7_15909MHz/2)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MCFG_SN76496_READY_HANDLER(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) MCFG_SN76496_READY_HANDLER(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_BOGUSWAIT))
// devices // devices
MCFG_ADAMNET_BUS_ADD() MCFG_ADAMNET_BUS_ADD()

View File

@ -516,7 +516,7 @@ static MACHINE_CONFIG_START( ep64, ep64_state )
MCFG_EP64_EXPANSION_BUS_SLOT_DAVE(DAVE_TAG) MCFG_EP64_EXPANSION_BUS_SLOT_DAVE(DAVE_TAG)
MCFG_EP64_EXPANSION_BUS_SLOT_IRQ_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0)) MCFG_EP64_EXPANSION_BUS_SLOT_IRQ_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
MCFG_EP64_EXPANSION_BUS_SLOT_NMI_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_NMI)) MCFG_EP64_EXPANSION_BUS_SLOT_NMI_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_NMI))
MCFG_EP64_EXPANSION_BUS_SLOT_WAIT_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) MCFG_EP64_EXPANSION_BUS_SLOT_WAIT_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_BOGUSWAIT))
MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, "printer") MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, "printer")
MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(ep64_state, write_centronics_busy)) MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(ep64_state, write_centronics_busy))

View File

@ -168,7 +168,7 @@ static MACHINE_CONFIG_START( horizon, horizon_state )
// S-100 // S-100
MCFG_S100_BUS_ADD() MCFG_S100_BUS_ADD()
MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_BOGUSWAIT))
//MCFG_S100_SLOT_ADD("s100_1", horizon_s100_cards, NULL, NULL) // CPU //MCFG_S100_SLOT_ADD("s100_1", horizon_s100_cards, NULL, NULL) // CPU
MCFG_S100_SLOT_ADD("s100_2", horizon_s100_cards, nullptr) // RAM MCFG_S100_SLOT_ADD("s100_2", horizon_s100_cards, nullptr) // RAM
MCFG_S100_SLOT_ADD("s100_3", horizon_s100_cards, "mdsad") // MDS MCFG_S100_SLOT_ADD("s100_3", horizon_s100_cards, "mdsad") // MDS

View File

@ -716,7 +716,7 @@ static MACHINE_CONFIG_START( mpz80, mpz80_state )
MCFG_S100_BUS_ADD() MCFG_S100_BUS_ADD()
MCFG_S100_IRQ_CALLBACK(WRITELINE(mpz80_state, s100_pint_w)) MCFG_S100_IRQ_CALLBACK(WRITELINE(mpz80_state, s100_pint_w))
MCFG_S100_NMI_CALLBACK(WRITELINE(mpz80_state, s100_nmi_w)) MCFG_S100_NMI_CALLBACK(WRITELINE(mpz80_state, s100_nmi_w))
MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_BOGUSWAIT))
MCFG_S100_SLOT_ADD("s100_1", mpz80_s100_cards, "mm65k16s") MCFG_S100_SLOT_ADD("s100_1", mpz80_s100_cards, "mm65k16s")
MCFG_S100_SLOT_ADD("s100_2", mpz80_s100_cards, "wunderbus") MCFG_S100_SLOT_ADD("s100_2", mpz80_s100_cards, "wunderbus")
MCFG_S100_SLOT_ADD("s100_3", mpz80_s100_cards, "dj2db") MCFG_S100_SLOT_ADD("s100_3", mpz80_s100_cards, "dj2db")

View File

@ -492,7 +492,7 @@ static MACHINE_CONFIG_START( mrgame, mrgame_state )
MCFG_DAC_ADD("dacr") MCFG_DAC_ADD("dacr")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50)
MCFG_SOUND_ADD("tms", TMS5220, 672000) // uses a RC combination. 672k copied from jedi.h MCFG_SOUND_ADD("tms", TMS5220, 672000) // uses a RC combination. 672k copied from jedi.h
MCFG_TMS52XX_READYQ_HANDLER(INPUTLINE("audiocpu2", Z80_INPUT_LINE_WAIT)) MCFG_TMS52XX_READYQ_HANDLER(INPUTLINE("audiocpu2", Z80_INPUT_LINE_BOGUSWAIT))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)

View File

@ -425,12 +425,12 @@ READ8_MEMBER(nightgal_state::royalqn_nsc_blit_r)
TIMER_CALLBACK_MEMBER(nightgal_state::z80_wait_ack_cb) TIMER_CALLBACK_MEMBER(nightgal_state::z80_wait_ack_cb)
{ {
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, CLEAR_LINE);
} }
void nightgal_state::z80_wait_assert_cb() void nightgal_state::z80_wait_assert_cb()
{ {
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
// Note: cycles_to_attotime requires z80 context to work, calling for example m_subcpu as context gives a x4 cycle boost in z80 terms (reads execute_cycles_to_clocks() from NCS?) even if they runs at same speed basically. // Note: cycles_to_attotime requires z80 context to work, calling for example m_subcpu as context gives a x4 cycle boost in z80 terms (reads execute_cycles_to_clocks() from NCS?) even if they runs at same speed basically.
// TODO: needs a getter that tells a given CPU how many cycles requires an executing opcode for the r/w operation, which stacks with wait state penalty for accessing this specific area. // TODO: needs a getter that tells a given CPU how many cycles requires an executing opcode for the r/w operation, which stacks with wait state penalty for accessing this specific area.

View File

@ -193,7 +193,7 @@ READ8_MEMBER( super6_state::fdc_r )
// don't crash please... but it's true, WAIT does nothing in our Z80 // don't crash please... but it's true, WAIT does nothing in our Z80
//fatalerror("Z80 WAIT not supported by MAME core\n"); //fatalerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
return !m_fdc->intrq_r() << 7; return !m_fdc->intrq_r() << 7;
} }
@ -409,14 +409,14 @@ SLOT_INTERFACE_END
WRITE_LINE_MEMBER( super6_state::fdc_intrq_w ) WRITE_LINE_MEMBER( super6_state::fdc_intrq_w )
{ {
if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, CLEAR_LINE);
m_ctc->trg3(!state); m_ctc->trg3(!state);
} }
WRITE_LINE_MEMBER( super6_state::fdc_drq_w ) WRITE_LINE_MEMBER( super6_state::fdc_drq_w )
{ {
if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); if (state) m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, CLEAR_LINE);
m_dma->rdy_w(state); m_dma->rdy_w(state);
} }

View File

@ -189,7 +189,7 @@ READ8_MEMBER( xor100_state::fdc_wait_r )
if (!m_fdc_irq && !m_fdc_drq) if (!m_fdc_irq && !m_fdc_drq)
{ {
fatalerror("Z80 WAIT not supported by MAME core\n"); fatalerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
} }
} }
@ -442,7 +442,7 @@ void xor100_state::fdc_intrq_w(bool state)
if (state) if (state)
{ {
fatalerror("Z80 WAIT not supported by MAME core\n"); fatalerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
} }
} }
@ -453,7 +453,7 @@ void xor100_state::fdc_drq_w(bool state)
if (state) if (state)
{ {
fatalerror("Z80 WAIT not supported by MAME core\n"); fatalerror("Z80 WAIT not supported by MAME core\n");
m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); m_maincpu->set_input_line(Z80_INPUT_LINE_BOGUSWAIT, ASSERT_LINE);
} }
} }
@ -568,7 +568,7 @@ static MACHINE_CONFIG_START( xor100, xor100_state )
// S-100 // S-100
MCFG_S100_BUS_ADD() MCFG_S100_BUS_ADD()
MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT)) MCFG_S100_RDY_CALLBACK(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_BOGUSWAIT))
MCFG_S100_SLOT_ADD("s100_1", xor100_s100_cards, nullptr) MCFG_S100_SLOT_ADD("s100_1", xor100_s100_cards, nullptr)
MCFG_S100_SLOT_ADD("s100_2", xor100_s100_cards, nullptr) MCFG_S100_SLOT_ADD("s100_2", xor100_s100_cards, nullptr)
MCFG_S100_SLOT_ADD("s100_3", xor100_s100_cards, nullptr) MCFG_S100_SLOT_ADD("s100_3", xor100_s100_cards, nullptr)