diff options
Diffstat (limited to 'src/devices/machine/z8536.h')
-rw-r--r-- | src/devices/machine/z8536.h | 209 |
1 files changed, 172 insertions, 37 deletions
diff --git a/src/devices/machine/z8536.h b/src/devices/machine/z8536.h index 3a21628e53f..ccecde18849 100644 --- a/src/devices/machine/z8536.h +++ b/src/devices/machine/z8536.h @@ -2,10 +2,32 @@ // copyright-holders:Curt Coder /********************************************************************** - Zilog Z8536 Counter/Timer and Parallel I/O emulation + Zilog Z8036/Z8536 Counter/Timer and Parallel I/O Unit ********************************************************************** _____ _____ + AD4 1 |* \_/ | 40 AD3 + AD5 2 | | 39 AD2 + AD6 3 | | 38 AD1 + AD7 4 | | 37 AD0 + _DS 5 | | 36 _CS0 + R/_W 6 | | 35 CS1 + GND 7 | | 34 _AS + PB0 8 | | 33 PA0 + PB1 9 | | 32 PA1 + PB2 10 | Z8036 | 31 PA2 + PB3 11 | | 30 PA3 + PB4 12 | | 29 PA4 + PB5 13 | | 28 PA5 + PB6 14 | | 27 PA6 + PB7 15 | | 26 PA7 + PCLK 16 | | 25 _INTACK + IEI 17 | | 24 _INT + IEO 18 | | 23 +5 V + PC0 19 | | 22 PC3 + PC1 20 |_____________| 21 PC2 + + _____ _____ D4 1 |* \_/ | 40 D3 D5 2 | | 39 D2 D6 3 | | 38 D1 @@ -69,27 +91,19 @@ // TYPE DEFINITIONS //************************************************************************** -// ======================> z8536_device +// ======================> cio_base_device -class z8536_device : public device_t, - public device_z80daisy_interface +class cio_base_device : public device_t { public: - // construction/destruction - z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> static devcb_base &set_irq_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_irq.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pa_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pa.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pa_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pa.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pb_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pb_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pc_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pc.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_pc_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pc.set_callback(std::forward<Object>(cb)); } - - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); - - int intack_r(); + template <class Object> static devcb_base &set_irq_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_irq.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pa_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pa.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pa_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pa.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pb_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pb.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pb_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pb.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pc_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pc.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_pc_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pc.set_callback(std::forward<Object>(cb)); } DECLARE_WRITE_LINE_MEMBER( pa0_w ) { external_port_w(PORT_A, 0, state); } DECLARE_WRITE_LINE_MEMBER( pa1_w ) { external_port_w(PORT_A, 1, state); } @@ -114,18 +128,19 @@ public: DECLARE_WRITE_LINE_MEMBER( pc2_w ) { external_port_w(PORT_C, 2, state); } DECLARE_WRITE_LINE_MEMBER( pc3_w ) { external_port_w(PORT_C, 3, state); } + int intack_r(); + protected: + // construction/destruction + cio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - // device_z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; + bool is_reset() const { return (m_register[MASTER_INTERRUPT_CONTROL] & MICR_RESET) != 0; } -private: enum { TIMER_1 = 0, @@ -133,15 +148,6 @@ private: TIMER_3 }; - // states - enum - { - STATE_RESET = -1, - STATE_0, - STATE_1 - }; - - // ports enum { @@ -155,7 +161,7 @@ private: // registers enum { - MASTER_INTERRUPT_CONTROL = 0, + MASTER_INTERRUPT_CONTROL = 0x00, MASTER_CONFIGURATION_CONTROL, PORT_A_INTERRUPT_VECTOR, PORT_B_INTERRUPT_VECTOR, @@ -171,7 +177,7 @@ private: PORT_A_DATA, PORT_B_DATA, PORT_C_DATA, - COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE, + COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE = 0x10, COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE, COUNTER_TIMER_2_CURRENT_COUNT_MS_BYTE, COUNTER_TIMER_2_CURRENT_COUNT_LS_BYTE, @@ -187,7 +193,7 @@ private: COUNTER_TIMER_2_MODE_SPECIFICATION, COUNTER_TIMER_3_MODE_SPECIFICATION, CURRENT_VECTOR, - PORT_A_MODE_SPECIFICATION, + PORT_A_MODE_SPECIFICATION = 0x20, PORT_A_HANDSHAKE_SPECIFICATION, PORT_A_DATA_PATH_POLARITY, PORT_A_DATA_DIRECTION, @@ -206,6 +212,96 @@ private: }; + // master interrupt control register + enum + { + MICR_RESET = 0x01, // reset + MICR_RJA = 0x02, // right justified address + MICR_CT_VIS = 0x04, // counter/timer vector includes status + MICR_PB_VIS = 0x08, // port B vector includes status + MICR_PA_VIS = 0x10, // port A vector includes status + MICR_NV = 0x20, // no vector + MICR_DLC = 0x40, // disable lower chain + MICR_MIE = 0x80 // master interrupt enable + }; + + + // master configuration control register + enum + { + MCCR_LC_MASK = 0x03, // counter/timer link controls + MCCR_PAE = 0x04, // port A enable + MCCR_PLC = 0x08, // port link control + MCCR_PCE_CT3E = 0x10, // port C and counter/timer 3 enable + MCCR_CT2E = 0x20, // counter/timer 2 enable + MCCR_CT1E = 0x40, // counter/timer 1 enable + MCCR_PBE = 0x80 // port B enable + }; + + + // port mode specification registers + enum + { + PMS_LPM = 0x01, // latch on pattern match + PMS_DTE = 0x01, // deskew timer enable + PMS_PMS_MASK = 0x06, // pattern mode specification + PMS_IMO = 0x08, // interrupt on match only + PMS_SB = 0x10, // single buffer + PMS_ITB = 0x20, // interrupt on two bytes + PMS_PTS_MASK = 0xc0 // port type select + }; + + + // port handshake specification registers + enum + { + PHS_DTS_MASK = 0x07, // deskew time specification + PHS_RWS_MASK = 0x38, // request/wait specification + PHS_HTS_MASK = 0xc0 // handshake type specification + }; + + + // port command and status registers + enum + { + PCS_IOE = 0x01, // interrupt on error + PCS_PMF = 0x02, // pattern match flag (read only) + PCS_IRF = 0x04, // input register full (read only) + PCS_ORE = 0x08, // output register empty (read only) + PCS_ERR = 0x10, // interrupt error (read only) + PCS_IP = 0x20, // interrupt pending + PCS_IE = 0x40, // interrupt enable + PCS_IUS = 0x80 // interrupt under service + }; + + + // counter/timer mode specification registers + enum + { + CTMS_DCS_MASK = 0x03, // output duty cycle + CTMS_REB = 0x04, // retrigger enable bit + CTMS_EDE = 0x08, // external gate enable + CTMS_ETE = 0x10, // external trigger enable + CTMS_ECE = 0x20, // external count enable + CTMS_EOE = 0x40, // external output enable + CTMS_CSC = 0x80 // continuous/single cycle + }; + + + // counter/timer command and status registers + enum + { + CTCS_CIP = 0x01, // count in progress (read only) + CTCS_TCB = 0x02, // trigger command bit (write only - read returns 0) + CTCS_GCB = 0x04, // gate command bit + CTCS_RCC = 0x08, // read counter control (read/set only - cleared by reading CCR LSB) + CTCS_ERR = 0x10, // interrupt error (read only) + CTCS_IP = 0x20, // interrupt pending + CTCS_IE = 0x40, // interrupt enable + CTCS_IUS = 0x80 // interrupt under service + }; + + // interrupt control enum { @@ -313,6 +409,7 @@ private: void match_pattern(int port); void external_port_w(int port, int bit, int state); +private: devcb_write_line m_write_irq; devcb_read8 m_read_pa; @@ -328,9 +425,7 @@ private: int m_irq; // register state - int m_state; uint8_t m_register[48]; - uint8_t m_pointer; // input/output port state uint8_t m_input[3]; @@ -343,8 +438,48 @@ private: uint16_t m_counter[3]; }; +// ======================> z8036_device + +class z8036_device : public cio_base_device +{ +public: + // construction/destruction + z8036_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); +}; + +// ======================> z8536_device + +class z8536_device : public cio_base_device, public device_z80daisy_interface +{ +public: + // construction/destruction + z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_z80daisy_interface overrides + virtual int z80daisy_irq_state() override; + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + +private: + // control state machine + bool m_state0; + uint8_t m_pointer; +}; + // device type definition +DECLARE_DEVICE_TYPE(Z8036, z8036_device) DECLARE_DEVICE_TYPE(Z8536, z8536_device) #endif // MAME_MACHINE_Z8536_H |