summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6800/m6801.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6800/m6801.cpp')
-rw-r--r--src/devices/cpu/m6800/m6801.cpp96
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];