diff options
Diffstat (limited to 'src/devices/cpu/m6800/m6801.cpp')
-rw-r--r-- | src/devices/cpu/m6800/m6801.cpp | 96 |
1 files changed, 92 insertions, 4 deletions
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() { @@ -1397,10 +1445,15 @@ 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]; |