diff --git a/src/devices/bus/hp9845_io/98034.cpp b/src/devices/bus/hp9845_io/98034.cpp index 0744a1bf0a1..ae2928e0f6b 100644 --- a/src/devices/bus/hp9845_io/98034.cpp +++ b/src/devices/bus/hp9845_io/98034.cpp @@ -132,6 +132,9 @@ READ16_MEMBER(hp98034_io_card::reg_r) m_force_flg = true; update_flg(); + // PPU yields to let NP see FLG=0 immediately + // (horrible race conditions lurking...) + space.device().execute().yield(); LOG(("read R%u=%04x\n" , offset + 4 , res)); return res; @@ -152,6 +155,9 @@ WRITE16_MEMBER(hp98034_io_card::reg_w) m_force_flg = true; update_flg(); + // PPU yields to let NP see FLG=0 immediately + // (horrible race conditions lurking...) + space.device().execute().yield(); LOG(("write R%u=%04x\n" , offset + 4 , data)); } diff --git a/src/devices/bus/ieee488/hp9895.cpp b/src/devices/bus/ieee488/hp9895.cpp index 2dfdb670e02..80aa16bc55c 100644 --- a/src/devices/bus/ieee488/hp9895.cpp +++ b/src/devices/bus/ieee488/hp9895.cpp @@ -10,6 +10,10 @@ #include "hp9895.h" +// Debugging +#define VERBOSE 1 +#define LOG(x) do { if (VERBOSE) logerror x; } while (0) + // device type definition const device_type HP9895 = &device_creator; @@ -32,38 +36,124 @@ void hp9895_device::device_start() void hp9895_device::device_reset() { + m_cpu_irq = false; } void hp9895_device::ieee488_eoi(int state) { + m_phi->eoi_w(state); } void hp9895_device::ieee488_dav(int state) { + m_phi->dav_w(state); } void hp9895_device::ieee488_nrfd(int state) { + m_phi->nrfd_w(state); } void hp9895_device::ieee488_ndac(int state) { + m_phi->ndac_w(state); } void hp9895_device::ieee488_ifc(int state) { + m_phi->ifc_w(state); } void hp9895_device::ieee488_srq(int state) { + m_phi->srq_w(state); } void hp9895_device::ieee488_atn(int state) { + m_phi->atn_w(state); } void hp9895_device::ieee488_ren(int state) { + m_phi->ren_w(state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_eoi_w) +{ + m_bus->eoi_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_dav_w) +{ + m_bus->dav_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_nrfd_w) +{ + m_bus->nrfd_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_ndac_w) +{ + m_bus->ndac_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_ifc_w) +{ + m_bus->ifc_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_srq_w) +{ + m_bus->srq_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_atn_w) +{ + m_bus->atn_w(this , state); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_ren_w) +{ + m_bus->ren_w(this , state); +} + +READ8_MEMBER(hp9895_device::phi_dio_r) +{ + return m_bus->dio_r(); +} + +WRITE8_MEMBER(hp9895_device::phi_dio_w) +{ + m_bus->dio_w(this , data); +} + +WRITE_LINE_MEMBER(hp9895_device::phi_int_w) +{ + m_cpu->set_input_line(INPUT_LINE_NMI , state); +} + +READ8_MEMBER(hp9895_device::phi_reg_r) +{ + uint16_t reg = m_phi->reg16_r(space , offset , mem_mask); + + // Reading D1=1 from a register sets the Z80 IRQ line + if (BIT(reg , 14) && !m_cpu_irq) { + m_cpu_irq = true; + m_cpu->set_input_line(INPUT_LINE_IRQ0 , ASSERT_LINE); + } + + return (uint8_t)reg; +} + +WRITE16_MEMBER(hp9895_device::z80_m1_w) +{ + // Every M1 cycle of Z80 clears the IRQ line + if (m_cpu_irq) { + m_cpu_irq = false; + m_cpu->set_input_line(INPUT_LINE_IRQ0 , CLEAR_LINE); + } } ROM_START(hp9895) @@ -81,15 +171,26 @@ static ADDRESS_MAP_START(z80_io_map , AS_IO , 8 , hp9895_device) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) // TODO: TEMP! - AM_RANGE(0x10 , 0x17) AM_DEVREADWRITE("phi" , phi_device , reg8_r , reg8_w) + AM_RANGE(0x10 , 0x17) AM_DEVWRITE("phi" , phi_device , reg8_w) AM_READ(phi_reg_r) ADDRESS_MAP_END static MACHINE_CONFIG_FRAGMENT(hp9895) MCFG_CPU_ADD("cpu" , Z80 , 4000000) MCFG_CPU_PROGRAM_MAP(z80_program_map) MCFG_CPU_IO_MAP(z80_io_map) + MCFG_Z80_SET_REFRESH_CALLBACK(WRITE16(hp9895_device , z80_m1_w)) MCFG_DEVICE_ADD("phi" , PHI , 0) + MCFG_PHI_EOI_WRITE_CB(WRITELINE(hp9895_device , phi_eoi_w)) + MCFG_PHI_DAV_WRITE_CB(WRITELINE(hp9895_device , phi_dav_w)) + MCFG_PHI_NRFD_WRITE_CB(WRITELINE(hp9895_device , phi_nrfd_w)) + MCFG_PHI_NDAC_WRITE_CB(WRITELINE(hp9895_device , phi_ndac_w)) + MCFG_PHI_IFC_WRITE_CB(WRITELINE(hp9895_device , phi_ifc_w)) + MCFG_PHI_SRQ_WRITE_CB(WRITELINE(hp9895_device , phi_srq_w)) + MCFG_PHI_ATN_WRITE_CB(WRITELINE(hp9895_device , phi_atn_w)) + MCFG_PHI_REN_WRITE_CB(WRITELINE(hp9895_device , phi_ren_w)) + MCFG_PHI_DIO_READWRITE_CB(READ8(hp9895_device , phi_dio_r) , WRITE8(hp9895_device , phi_dio_w)) + MCFG_PHI_INT_WRITE_CB(WRITELINE(hp9895_device , phi_int_w)) MACHINE_CONFIG_END const tiny_rom_entry *hp9895_device::device_rom_region() const diff --git a/src/devices/bus/ieee488/hp9895.h b/src/devices/bus/ieee488/hp9895.h index 9f451535e61..d7591d684be 100644 --- a/src/devices/bus/ieee488/hp9895.h +++ b/src/devices/bus/ieee488/hp9895.h @@ -42,9 +42,32 @@ public: virtual void ieee488_atn(int state) override; virtual void ieee488_ren(int state) override; + // PHI write CBs + DECLARE_WRITE_LINE_MEMBER(phi_eoi_w); + DECLARE_WRITE_LINE_MEMBER(phi_dav_w); + DECLARE_WRITE_LINE_MEMBER(phi_nrfd_w); + DECLARE_WRITE_LINE_MEMBER(phi_ndac_w); + DECLARE_WRITE_LINE_MEMBER(phi_ifc_w); + DECLARE_WRITE_LINE_MEMBER(phi_srq_w); + DECLARE_WRITE_LINE_MEMBER(phi_atn_w); + DECLARE_WRITE_LINE_MEMBER(phi_ren_w); + + // PHI DIO r/w CBs + DECLARE_READ8_MEMBER(phi_dio_r); + DECLARE_WRITE8_MEMBER(phi_dio_w); + + // PHI IRQ/Z80 NMI + DECLARE_WRITE_LINE_MEMBER(phi_int_w); + + // PHI register read & Z80 IRQ + DECLARE_READ8_MEMBER(phi_reg_r); + DECLARE_WRITE16_MEMBER(z80_m1_w); + private: required_device m_cpu; required_device m_phi; + + bool m_cpu_irq; }; // device type definition diff --git a/src/devices/machine/phi.cpp b/src/devices/machine/phi.cpp index e24f579ba9c..2ac82a44326 100644 --- a/src/devices/machine/phi.cpp +++ b/src/devices/machine/phi.cpp @@ -244,6 +244,15 @@ void phi_device::set_ext_signal(phi_488_signal_t signal , int state) state = !state; if (m_ext_signals[ signal ] != state) { m_ext_signals[ signal ] = state; + LOG(("EXT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" , + m_ext_signals[ PHI_488_EOI ] , + m_ext_signals[ PHI_488_DAV ] , + m_ext_signals[ PHI_488_NRFD ] , + m_ext_signals[ PHI_488_NDAC ] , + m_ext_signals[ PHI_488_IFC ] , + m_ext_signals[ PHI_488_SRQ ] , + m_ext_signals[ PHI_488_ATN ] , + m_ext_signals[ PHI_488_REN ])); update_fsm(); } } @@ -309,7 +318,7 @@ READ16_MEMBER(phi_device::reg16_r) ((res & REG_D0D1_MASK) >> (REG_D0D1_SHIFT - REG_STATUS_D0D1_BIT)); } - LOG(("R %u=%04x\n" , offset , res)); + //LOG(("R %u=%04x\n" , offset , res)); return res; } @@ -405,7 +414,7 @@ void phi_device::int_reg_w(offs_t offset , uint16_t data) data = (data & REG_D08D15_MASK) | ((m_reg_status << (REG_D0D1_SHIFT - REG_STATUS_D0D1_BIT)) & REG_D0D1_MASK); } - LOG(("W %u=%04x\n" , offset , data)); + //LOG(("W %u=%04x\n" , offset , data)); switch (offset) { case REG_W_INT_COND: @@ -525,7 +534,7 @@ void phi_device::set_signal(phi_488_signal_t signal , bool state) { if (state != m_signals[ signal ]) { m_signals[ signal ] = state; - LOG(("EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" , + LOG(("INT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" , m_signals[ PHI_488_EOI ] , m_signals[ PHI_488_DAV ] , m_signals[ PHI_488_NRFD ] , @@ -1026,6 +1035,7 @@ void phi_device::update_fsm(void) phi_device::nba_origin_t phi_device::nba_msg(uint8_t& new_byte , bool& new_eoi) const { + // TODO: consider CIC if (!m_fifo_out.empty()) { uint16_t word = m_fifo_out.peek(); if ((word & REG_D0D1_MASK) == REG_OFIFO_IFCMD_MASK) { diff --git a/src/devices/machine/phi.h b/src/devices/machine/phi.h index 60ecb3ea311..84955d290af 100644 --- a/src/devices/machine/phi.h +++ b/src/devices/machine/phi.h @@ -17,28 +17,28 @@ phi_device::set_dio_write_cb(*device , DEVCB_##_write); // Set write callbacks to access uniline signals on IEEE-488 -#define MCFG_PHI_EOI_WRITE_CB(_read , _write) \ +#define MCFG_PHI_EOI_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_EOI , DEVCB_##_write); -#define MCFG_PHI_DAV_WRITE_CB(_read , _write) \ +#define MCFG_PHI_DAV_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_DAV , DEVCB_##_write); -#define MCFG_PHI_NRFD_WRITE_CB(_read , _write) \ +#define MCFG_PHI_NRFD_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_NRFD , DEVCB_##_write); -#define MCFG_PHI_NDAC_WRITE_CB(_read , _write) \ +#define MCFG_PHI_NDAC_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_NDAC , DEVCB_##_write); -#define MCFG_PHI_IFC_WRITE_CB(_read , _write) \ +#define MCFG_PHI_IFC_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_IFC , DEVCB_##_write); -#define MCFG_PHI_SRQ_WRITE_CB(_read , _write) \ +#define MCFG_PHI_SRQ_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_SRQ , DEVCB_##_write); -#define MCFG_PHI_ATN_WRITE_CB(_read , _write) \ +#define MCFG_PHI_ATN_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_ATN , DEVCB_##_write); -#define MCFG_PHI_REN_WRITE_CB(_read , _write) \ +#define MCFG_PHI_REN_WRITE_CB(_write) \ phi_device::set_488_signal_write_cb(*device , phi_device::PHI_488_REN , DEVCB_##_write); // Set write callback for INT signal