From 63858f2f8ea4431d7335564b1f0fcf9d9b29b2e7 Mon Sep 17 00:00:00 2001 From: hap Date: Thu, 13 May 2021 18:29:01 +0200 Subject: hd6301y: preliminary support for port 6 handshaking --- src/devices/cpu/m6800/m6800.h | 2 +- src/devices/cpu/m6800/m6801.cpp | 96 +++++++++++++++++++++++++++++++++++++++-- src/devices/cpu/m6800/m6801.h | 32 ++++++++++++-- 3 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/devices/cpu/m6800/m6800.h b/src/devices/cpu/m6800/m6800.h index 8b8980d1c5c..10e40ab3a3f 100644 --- a/src/devices/cpu/m6800/m6800.h +++ b/src/devices/cpu/m6800/m6800.h @@ -79,7 +79,7 @@ protected: uint8_t m_wai_state; /* WAI opcode state ,(or sleep opcode state) */ uint8_t m_nmi_state; /* NMI line state */ uint8_t m_nmi_pending; /* NMI pending */ - uint8_t m_irq_state[3]; /* IRQ line state [IRQ1,TIN,SC1] */ + uint8_t m_irq_state[4]; /* IRQ line state [IRQ1,TIN,SC1,IS] */ /* Memory spaces */ memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cprogram, m_copcodes; diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index 47b9649800d..3edcebed0c1 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -78,6 +78,7 @@ enum }; /* take interrupt */ +#define TAKE_ISI enter_interrupt("take ISI\n",0xfff8) #define TAKE_ICI enter_interrupt("take ICI\n",0xfff6) #define TAKE_OCI enter_interrupt("take OCI\n",0xfff4) #define TAKE_TOI enter_interrupt("take TOI\n",0xfff2) @@ -291,7 +292,7 @@ void hd6301y_cpu_device::hd6301y_io(address_map &map) map(0x0015, 0x0015).w(FUNC(hd6301y_cpu_device::p5_data_w)); //map(0x001e, 0x001e).rw(FUNC(hd6301y_cpu_device::sci_trcsr2_r), FUNC(hd6301y_cpu_device::sci_trcsr2_w)); map(0x0020, 0x0020).rw(FUNC(hd6301y_cpu_device::ff_r), FUNC(hd6301y_cpu_device::p5_ddr_w)); - //map(0x0021, 0x0021).rw(FUNC(hd6301y_cpu_device::p6_csr_r), FUNC(hd6301y_cpu_device::p6_csr_w)); + map(0x0021, 0x0021).rw(FUNC(hd6301y_cpu_device::p6_csr_r), FUNC(hd6301y_cpu_device::p6_csr_w)); } @@ -415,7 +416,6 @@ void m6801_cpu_device::m6800_check_irq2() ((m_trcsr & (M6801_TRCSR_RIE|M6801_TRCSR_ORFE)) == (M6801_TRCSR_RIE|M6801_TRCSR_ORFE)) || ((m_trcsr & (M6801_TRCSR_TIE|M6801_TRCSR_TDRE)) == (M6801_TRCSR_TIE|M6801_TRCSR_TDRE))) { - LOG("SCI interrupt\n"); TAKE_SCI; } } @@ -444,11 +444,21 @@ void hd6301x_cpu_device::m6800_check_irq2() ((m_trcsr & (M6801_TRCSR_RIE|M6801_TRCSR_ORFE)) == (M6801_TRCSR_RIE|M6801_TRCSR_ORFE)) || ((m_trcsr & (M6801_TRCSR_TIE|M6801_TRCSR_TDRE)) == (M6801_TRCSR_TIE|M6801_TRCSR_TDRE))) { - LOG("SCI interrupt\n"); TAKE_SCI; } } +void hd6301y_cpu_device::m6800_check_irq2() +{ + if (m_pending_isi) + { + TAKE_ISI; + standard_irq_callback(HD6301Y_IS_LINE); + } + else + hd6301x_cpu_device::m6800_check_irq2(); +} + void m6801_cpu_device::modified_tcsr() { m_irq2 = (m_tcsr&(m_tcsr<<3))&(TCSR_ICF|TCSR_OCF|TCSR_TOF); @@ -985,6 +995,24 @@ void m6801_cpu_device::execute_set_input(int irqline, int state) } } +void hd6301y_cpu_device::execute_set_input(int irqline, int state) +{ + switch (irqline) + { + case HD6301Y_IS_LINE: + // interrupt at falling edge + if (!state && m_irq_state[HD6301Y_IS_LINE] && m_p6_csr & 0x40) + m_pending_isi = true; + m_irq_state[HD6301Y_IS_LINE] = state; + break; + + default: + m6801_cpu_device::execute_set_input(irqline, state); + break; + } +} + + void m6801_cpu_device::device_resolve_objects() { @@ -1075,6 +1103,17 @@ void hd6301x_cpu_device::device_start() save_item(NAME(m_t2cnt_written)); } +void hd6301y_cpu_device::device_start() +{ + hd6301x_cpu_device::device_start(); + + m_irq_state[HD6301Y_IS_LINE] = 0; + + save_item(NAME(m_p6_csr)); + save_item(NAME(m_pending_isi)); + save_item(NAME(m_pending_isi_clear)); +} + void m6801_cpu_device::device_reset() { m6800_cpu_device::device_reset(); @@ -1133,6 +1172,15 @@ void hd6301x_cpu_device::device_reset() m_t2cnt_written = false; } +void hd6301y_cpu_device::device_reset() +{ + hd6301x_cpu_device::device_reset(); + + m_p6_csr = 0; + m_pending_isi = false; + m_pending_isi_clear = false; +} + void m6801_cpu_device::write_port2() { @@ -1396,11 +1444,16 @@ void hd6301y_cpu_device::p5_ddr_w(uint8_t data) } uint8_t hd6301x_cpu_device::p5_data_r() +{ + return m_in_portx_func[0](); +} + +uint8_t hd6301y_cpu_device::p5_data_r() { if(m_portx_ddr[0] == 0xff) return m_portx_data[0]; else - return (m_in_portx_func[0]() & (m_portx_ddr[0] ^ 0xff)) | (m_portx_data[0] & m_portx_ddr[0]); + return ((m_in_portx_func[0]() | ((m_irq_state[HD6301Y_IS_LINE]) ? 0x10 : 0)) & (m_portx_ddr[0] ^ 0xff)) | (m_portx_data[0] & m_portx_ddr[0]); } void hd6301y_cpu_device::p5_data_w(uint8_t data) @@ -1438,6 +1491,41 @@ void hd6301x_cpu_device::p6_data_w(uint8_t data) m_out_portx_func[1](0, (m_portx_data[1] & m_portx_ddr[1]) | (m_portx_ddr[1] ^ 0xff), m_portx_ddr[1]); } +uint8_t hd6301y_cpu_device::p6_data_r() +{ + clear_pending_isi(); + return hd6301x_cpu_device::p6_data_r(); +} + +void hd6301y_cpu_device::p6_data_w(uint8_t data) +{ + clear_pending_isi(); + hd6301x_cpu_device::p6_data_w(data); +} + +void hd6301y_cpu_device::clear_pending_isi() +{ + // IS flag is cleared when reading/writing P6 after reading P6 CSR + if (m_pending_isi_clear) + { + m_pending_isi_clear = false; + m_pending_isi = false; + } +} + +uint8_t hd6301y_cpu_device::p6_csr_r() +{ + m_pending_isi_clear = m_pending_isi; + return (m_p6_csr & 0x7f) | (m_pending_isi ? 0x80 : 0) | 7; +} + +void hd6301y_cpu_device::p6_csr_w(uint8_t data) +{ + LOGPORT("Port 6 Control/Status Register: %02x\n", data); + + m_p6_csr = data & 0x78; +} + uint8_t hd6301x_cpu_device::p7_data_r() { return 0xe0 | m_portx_data[2]; diff --git a/src/devices/cpu/m6800/m6801.h b/src/devices/cpu/m6800/m6801.h index 57eb487e853..5ebd7b038df 100644 --- a/src/devices/cpu/m6800/m6801.h +++ b/src/devices/cpu/m6800/m6801.h @@ -26,6 +26,11 @@ enum HD6301_IRQ_LINE = M6800_IRQ_LINE }; +enum +{ + HD6301Y_IS_LINE = M6801_SC1_LINE+1 +}; + enum { M6801_MODE_0 = 0, @@ -71,6 +76,7 @@ protected: // device_execute_interface overrides virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); } + virtual uint32_t execute_input_lines() const noexcept override { return 4; } virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface overrides @@ -269,10 +275,10 @@ protected: virtual void write_port2() override; void p2_ddr_2bit_w(uint8_t data); - uint8_t p5_data_r(); + virtual uint8_t p5_data_r(); void p6_ddr_w(uint8_t data); - uint8_t p6_data_r(); - void p6_data_w(uint8_t data); + virtual uint8_t p6_data_r(); + virtual void p6_data_w(uint8_t data); uint8_t p7_data_r(); void p7_data_w(uint8_t data); @@ -357,8 +363,28 @@ public: protected: hd6301y_cpu_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; + + // device_execute_interface overrides + virtual uint32_t execute_input_lines() const noexcept override { return 5; } + virtual void execute_set_input(int inputnum, int state) override; + void p5_ddr_w(uint8_t data); + virtual uint8_t p5_data_r() override; void p5_data_w(uint8_t data); + virtual uint8_t p6_data_r() override; + virtual void p6_data_w(uint8_t data) override; + uint8_t p6_csr_r(); + void p6_csr_w(uint8_t data); + + virtual void m6800_check_irq2() override; + void clear_pending_isi(); + + uint8_t m_p6_csr; + bool m_pending_isi; + bool m_pending_isi_clear; }; -- cgit v1.2.3