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.cpp398
1 files changed, 345 insertions, 53 deletions
diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp
index de9cae8e9fd..a5e3226d770 100644
--- a/src/devices/cpu/m6800/m6801.cpp
+++ b/src/devices/cpu/m6800/m6801.cpp
@@ -78,10 +78,12 @@ 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)
#define TAKE_SCI enter_interrupt("take SCI\n",0xfff0)
+#define TAKE_CMI enter_interrupt("take CMI\n",0xffec)
/* mnemonics for the Timer Control and Status Register bits */
#define TCSR_OLVL 0x01
@@ -276,9 +278,9 @@ void hd6301x_cpu_device::hd6301x_io(address_map &map)
map(0x0018, 0x0018).rw(FUNC(hd6301x_cpu_device::p7_data_r), FUNC(hd6301x_cpu_device::p7_data_w)); // TODO: external except in single-chip mode
map(0x0019, 0x0019).rw(FUNC(hd6301x_cpu_device::ocr2h_r), FUNC(hd6301x_cpu_device::ocr2h_w));
map(0x001a, 0x001a).rw(FUNC(hd6301x_cpu_device::ocr2l_r), FUNC(hd6301x_cpu_device::ocr2l_w));
- //map(0x001b, 0x001b).rw(FUNC(hd6301x_cpu_device::tcsr3_r), FUNC(hd6301x_cpu_device::tcsr3_w));
- //map(0x001c, 0x001c).rw(FUNC(hd6301x_cpu_device::ff_r), FUNC(hd6301x_cpu_device::tconr_w));
- //map(0x001d, 0x001d).rw(FUNC(hd6301x_cpu_device::t2cnt_r), FUNC(hd6301x_cpu_device::t2cnt_w));
+ map(0x001b, 0x001b).rw(FUNC(hd6301x_cpu_device::tcsr3_r), FUNC(hd6301x_cpu_device::tcsr3_w));
+ map(0x001c, 0x001c).rw(FUNC(hd6301x_cpu_device::ff_r), FUNC(hd6301x_cpu_device::tconr_w));
+ map(0x001d, 0x001d).rw(FUNC(hd6301x_cpu_device::t2cnt_r), FUNC(hd6301x_cpu_device::t2cnt_w));
//map(0x001f, 0x001f).rw(FUNC(hd6301x_cpu_device::tstreg_r), FUNC(hd6301x_cpu_device::tstreg_w));
}
@@ -290,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));
}
@@ -318,6 +320,7 @@ m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, device_type ty
, m_out_port_func(*this)
, m_out_sc2_func(*this)
, m_out_sertx_func(*this)
+ , m_sclk_divider(8)
{
}
@@ -356,6 +359,7 @@ hd6301x_cpu_device::hd6301x_cpu_device(const machine_config &mconfig, device_typ
, m_in_portx_func(*this)
, m_out_portx_func(*this)
{
+ m_sclk_divider = 16;
}
hd6301x0_cpu_device::hd6301x0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -412,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;
}
}
@@ -433,15 +436,29 @@ void hd6301x_cpu_device::m6800_check_irq2()
{
TAKE_TOI;
}
+ else if ((m_tcsr3 & 0xc0) == 0xc0)
+ {
+ TAKE_CMI;
+ }
else if (((m_trcsr & (M6801_TRCSR_RIE|M6801_TRCSR_RDRF)) == (M6801_TRCSR_RIE|M6801_TRCSR_RDRF)) ||
((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_p6csr & 0xc0) == 0xc0)
+ {
+ TAKE_ISI;
+ standard_irq_callback(M6801_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);
@@ -505,7 +522,7 @@ void m6801_cpu_device::check_timer_event()
{
TOH++; // next IRQ point
#if 0
- CLEANUP_COUNTERS();
+ cleanup_counters();
#endif
m_tcsr |= TCSR_TOF;
m_pending_tcsr |= TCSR_TOF;
@@ -565,14 +582,14 @@ void hd6301x_cpu_device::check_timer_event()
{
TOH++; // next IRQ point
#if 0
- CLEANUP_COUNTERS();
+ cleanup_counters();
#endif
m_tcsr |= TCSR_TOF;
m_pending_tcsr |= TCSR_TOF;
modified_tcsr();
}
- if (m_irq2 & (TCSR_OCF | TCSR_TOF))
+ if ((m_irq2 & (TCSR_OCF | TCSR_TOF)) || (m_tcsr3 & 0xc0) == 0xc0)
{
if (m_wai_state & M6800_SLP)
m_wai_state &= ~M6800_SLP;
@@ -591,7 +608,41 @@ void m6801_cpu_device::increment_counter(int amount)
check_timer_event();
}
-void m6801_cpu_device::EAT_CYCLES()
+void hd6301x_cpu_device::increment_counter(int amount)
+{
+ m6800_cpu_device::increment_counter(amount);
+ if (m_t2cnt_written)
+ m_t2cnt_written = false;
+ else if (BIT(m_tcsr3, 4))
+ {
+ switch (m_tcsr3 & 0x03)
+ {
+ case 0x00:
+ // Timer 2 input = E clock
+ increment_t2cnt(amount);
+ break;
+
+ case 0x01:
+ // Timer 2 input = E clock/8
+ increment_t2cnt((amount + (CTD & 0x0007)) >> 3);
+ break;
+
+ case 0x02:
+ // Timer 2 input = E clock/128
+ increment_t2cnt((amount + (CTD & 0x007f)) >> 7);
+ break;
+
+ case 0x03:
+ // Timer 2 input = external Tclk
+ break;
+ }
+ }
+ CTD += amount;
+ if (CTD >= m_timer_next || (m_tcsr3 & 0xc0) == 0xc0)
+ check_timer_event();
+}
+
+void m6801_cpu_device::eat_cycles()
{
int cycles_to_eat = std::min(int(m_timer_next - CTD), m_icount);
if (cycles_to_eat > 0)
@@ -599,7 +650,7 @@ void m6801_cpu_device::EAT_CYCLES()
}
/* cleanup high-word of counters */
-void m6801_cpu_device::CLEANUP_COUNTERS()
+void m6801_cpu_device::cleanup_counters()
{
OCH -= CTH;
TOH -= CTH;
@@ -609,10 +660,10 @@ void m6801_cpu_device::CLEANUP_COUNTERS()
check_timer_event();
}
-void hd6301x_cpu_device::CLEANUP_COUNTERS()
+void hd6301x_cpu_device::cleanup_counters()
{
OC2H -= CTH;
- m6801_cpu_device::CLEANUP_COUNTERS();
+ m6801_cpu_device::cleanup_counters();
}
void m6801_cpu_device::set_rmcr(uint8_t data)
@@ -648,6 +699,44 @@ void m6801_cpu_device::set_rmcr(uint8_t data)
}
}
+void hd6301x_cpu_device::set_rmcr(uint8_t data)
+{
+ if (m_rmcr == data) return;
+
+ m_rmcr = data;
+
+ switch ((m_rmcr & 0x1c) >> 2)
+ {
+ case 0: // TODO: clock sync
+ case 3:
+ case 7: // external clock
+ LOGSER("SCI: Using external serial clock: true\n");
+ m_use_ext_serclock = true;
+ m_sci_timer->enable(false);
+ break;
+
+ case 1:
+ case 2:
+ case 4: // TODO: clock sync
+ case 5:
+ case 6:
+ if (BIT(m_rmcr, 5))
+ {
+ LOGSER("SCI: Using Timer 2 clock\n");
+ m_sci_timer->enable(false);
+ }
+ else
+ {
+ int divisor = M6801_RMCR_SS[m_rmcr & M6801_RMCR_SS_MASK];
+ attotime period = cycles_to_attotime(divisor);
+ LOGSER("SCI: Setting serial rate, Divisor: %d Hz: %d\n", divisor, period.as_hz());
+ m_sci_timer->adjust(period, 0, period);
+ }
+ m_use_ext_serclock = false;
+ break;
+ }
+}
+
int m6801_cpu_device::m6800_rx()
{
return (m_in_port_func[1]() & M6801_PORT2_IO3) >> 3;
@@ -709,7 +798,7 @@ void m6801_cpu_device::serial_transmit()
// send stop bit '1'
m_tx = 1;
- CHECK_IRQ_LINES();
+ check_irq_lines();
m_txbits = M6801_SERIAL_START;
@@ -797,7 +886,7 @@ void m6801_cpu_device::serial_receive()
LOGRX("SCI Receive Overrun Error\n");
- CHECK_IRQ_LINES();
+ check_irq_lines();
}
else
{
@@ -811,7 +900,7 @@ void m6801_cpu_device::serial_receive()
// set RDRF flag
m_trcsr |= M6801_TRCSR_RDRF;
- CHECK_IRQ_LINES();
+ check_irq_lines();
}
}
}
@@ -829,7 +918,7 @@ void m6801_cpu_device::serial_receive()
LOGRX("SCI Receive Framing Error\n");
- CHECK_IRQ_LINES();
+ check_irq_lines();
}
m_rxbits = M6801_SERIAL_START;
@@ -890,7 +979,7 @@ void m6801_cpu_device::execute_set_input(int irqline, int state)
{
m_irq_state[M6801_TIN_LINE] = state;
//edge = (state == CLEAR_LINE ) ? 2 : 0;
- if( ((m_tcsr&TCSR_IEDG) ^ (state==CLEAR_LINE ? TCSR_IEDG : 0))==0 )
+ if (((m_tcsr&TCSR_IEDG) ^ (state==CLEAR_LINE ? TCSR_IEDG : 0)) == 0)
return;
/* active edge in */
m_tcsr |= TCSR_ICF;
@@ -906,6 +995,28 @@ 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 M6801_IS_LINE:
+ // interrupt at falling edge
+ if (!state && m_irq_state[M6801_IS_LINE])
+ {
+ m_p6csr |= 0x80; // IS flag
+ m_pending_isf_clear = false;
+ }
+
+ m_irq_state[M6801_IS_LINE] = state;
+ break;
+
+ default:
+ m6801_cpu_device::execute_set_input(irqline, state);
+ break;
+ }
+}
+
+
void m6801_cpu_device::device_resolve_objects()
{
@@ -932,6 +1043,7 @@ void m6801_cpu_device::device_start()
m_sci_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m6801_cpu_device::sci_tick),this));
+ m_irq_state[M6801_IS_LINE] = 0;
m_port_ddr[3] = 0;
m_port_data[3] = 0;
m_input_capture = 0;
@@ -951,7 +1063,7 @@ void m6801_cpu_device::device_start()
save_item(NAME(m_counter.d));
save_item(NAME(m_output_compare.d));
save_item(NAME(m_input_capture));
- save_item(NAME(m_p3csr_is3_flag_read));
+ save_item(NAME(m_pending_isf_clear));
save_item(NAME(m_port3_latched));
save_item(NAME(m_port2_written));
@@ -972,11 +1084,8 @@ void m6801_cpu_device::device_start()
save_item(NAME(m_use_ext_serclock));
save_item(NAME(m_latch09));
-
save_item(NAME(m_timer_over.d));
-
save_item(NAME(m_timer_next));
-
save_item(NAME(m_sc1_state));
}
@@ -991,6 +1100,19 @@ void hd6301x_cpu_device::device_start()
save_item(NAME(m_tcsr2));
save_item(NAME(m_pending_tcsr2));
save_item(NAME(m_output_compare2.d));
+
+ save_item(NAME(m_t2cnt));
+ save_item(NAME(m_tconr));
+ save_item(NAME(m_tcsr3));
+ save_item(NAME(m_tout3));
+ save_item(NAME(m_t2cnt_written));
+}
+
+void hd6301y_cpu_device::device_start()
+{
+ hd6301x_cpu_device::device_start();
+
+ save_item(NAME(m_p6csr));
}
void m6801_cpu_device::device_reset()
@@ -1005,7 +1127,7 @@ void m6801_cpu_device::device_reset()
m_port_ddr[2] = 0x00;
m_port_data[0] = 0;
m_p3csr = 0x00;
- m_p3csr_is3_flag_read = 0;
+ m_pending_isf_clear = false;
m_port2_written = false;
m_port3_latched = 0;
/* TODO: on reset port 2 should be read to determine the operating mode (bits 0-2) */
@@ -1043,6 +1165,21 @@ void hd6301x_cpu_device::device_reset()
m_tcsr2 = 0x00;
m_pending_tcsr2 = 0x00;
OC2D = 0xffff;
+
+ m_t2cnt = 0x00;
+ m_tconr = 0xff;
+ m_tcsr3 = 0x00;
+ m_tout3 = false;
+ m_t2cnt_written = false;
+
+ m_p3csr = 0; // does not have this reg
+}
+
+void hd6301y_cpu_device::device_reset()
+{
+ hd6301x_cpu_device::device_reset();
+
+ m_p6csr = 7;
}
@@ -1086,12 +1223,17 @@ void hd6301x_cpu_device::write_port2()
data = (data & 0xef) | (m_tx << 4);
ddr |= 0x10;
}
+ if ((m_tcsr3 & 0x0c) != 0)
+ {
+ data = (data & 0xbf) | (m_tout3 << 6);
+ ddr |= 0x40;
+ }
m_out_port_func[1](0, data, ddr);
}
/*
- if change_pc() direccted these areas ,Call hd63701_trap_pc().
+ if change_pc() directed these areas, call hd63701_trap_pc().
'mode' is selected by the sense of p2.0,p2.1,and p2.3 at reset timing.
mode 0,1,2,4,6 : $0000-$001f
mode 5 : $0000-$001f,$0200-$efff
@@ -1119,7 +1261,7 @@ void m6801_cpu_device::p1_ddr_w(uint8_t data)
uint8_t m6801_cpu_device::p1_data_r()
{
- if(m_port_ddr[0] == 0xff)
+ if (m_port_ddr[0] == 0xff)
return m_port_data[0];
else
return (m_in_port_func[0]() & (m_port_ddr[0] ^ 0xff)) | (m_port_data[0] & m_port_ddr[0]);
@@ -1159,7 +1301,7 @@ void hd6301x_cpu_device::p2_ddr_2bit_w(uint8_t data)
uint8_t m6801_cpu_device::p2_data_r()
{
- if(m_port_ddr[1] == 0xff)
+ if (m_port_ddr[1] == 0xff)
return m_port_data[1];
else
return (m_in_port_func[1]() & (m_port_ddr[1] ^ 0xff)) | (m_port_data[1] & m_port_ddr[1]);
@@ -1191,11 +1333,11 @@ uint8_t m6801_cpu_device::p3_data_r()
if (!machine().side_effects_disabled())
{
- if (m_p3csr_is3_flag_read)
+ if (m_pending_isf_clear)
{
LOGPORT("Cleared IS3\n");
m_p3csr &= ~M6801_P3CSR_IS3_FLAG;
- m_p3csr_is3_flag_read = 0;
+ m_pending_isf_clear = false;
}
if (!(m_p3csr & M6801_P3CSR_OSS))
@@ -1207,8 +1349,7 @@ uint8_t m6801_cpu_device::p3_data_r()
if ((m_p3csr & M6801_P3CSR_LE) || (m_port_ddr[2] == 0xff))
data = m_port_data[2];
else
- data = (m_in_port_func[2]() & (m_port_ddr[2] ^ 0xff))
- | (m_port_data[2] & m_port_ddr[2]);
+ data = (m_in_port_func[2]() & (m_port_ddr[2] ^ 0xff)) | (m_port_data[2] & m_port_ddr[2]);
if (!machine().side_effects_disabled())
{
@@ -1226,11 +1367,11 @@ void m6801_cpu_device::p3_data_w(uint8_t data)
{
LOGPORT("Port 3 Data Register: %02x\n", data);
- if (m_p3csr_is3_flag_read)
+ if (m_pending_isf_clear)
{
LOGPORT("Cleared IS3\n");
m_p3csr &= ~M6801_P3CSR_IS3_FLAG;
- m_p3csr_is3_flag_read = 0;
+ m_pending_isf_clear = false;
}
if (m_p3csr & M6801_P3CSR_OSS)
@@ -1247,11 +1388,29 @@ void m6801_cpu_device::p3_data_w(uint8_t data)
}
}
+uint8_t hd6301x_cpu_device::p3_data_r()
+{
+ // no handshaking protocol
+ if (m_port_ddr[2] == 0xff)
+ return m_port_data[2];
+ else
+ return (m_in_port_func[2]() & (m_port_ddr[2] ^ 0xff)) | (m_port_data[2] & m_port_ddr[2]);
+}
+
+void hd6301x_cpu_device::p3_data_w(uint8_t data)
+{
+ // no handshaking protocol
+ LOGPORT("Port 3 Data Register: %02x\n", data);
+
+ m_port_data[2] = data;
+ m_out_port_func[2](0, (m_port_data[2] & m_port_ddr[2]) | (m_port_ddr[2] ^ 0xff), m_port_ddr[2]);
+}
+
uint8_t m6801_cpu_device::p3_csr_r()
{
if ((m_p3csr & M6801_P3CSR_IS3_FLAG) && !machine().side_effects_disabled())
{
- m_p3csr_is3_flag_read = 1;
+ m_pending_isf_clear = true;
}
return m_p3csr;
@@ -1277,7 +1436,7 @@ void m6801_cpu_device::p4_ddr_w(uint8_t data)
uint8_t m6801_cpu_device::p4_data_r()
{
- if(m_port_ddr[3] == 0xff)
+ if (m_port_ddr[3] == 0xff)
return m_port_data[3];
else
return (m_in_port_func[3]() & (m_port_ddr[3] ^ 0xff)) | (m_port_data[3] & m_port_ddr[3]);
@@ -1304,10 +1463,16 @@ void hd6301y_cpu_device::p5_ddr_w(uint8_t data)
uint8_t hd6301x_cpu_device::p5_data_r()
{
- if(m_portx_ddr[0] == 0xff)
+ // read-only
+ 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[M6801_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)
@@ -1331,7 +1496,7 @@ void hd6301x_cpu_device::p6_ddr_w(uint8_t data)
uint8_t hd6301x_cpu_device::p6_data_r()
{
- if(m_portx_ddr[1] == 0xff)
+ if (m_portx_ddr[1] == 0xff)
return m_portx_data[1];
else
return (m_in_portx_func[1]() & (m_portx_ddr[1] ^ 0xff)) | (m_portx_data[1] & m_portx_ddr[1]);
@@ -1345,6 +1510,48 @@ 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()
+{
+ if (!machine().side_effects_disabled())
+ clear_pending_isf();
+
+ return hd6301x_cpu_device::p6_data_r();
+}
+
+void hd6301y_cpu_device::p6_data_w(uint8_t data)
+{
+ clear_pending_isf();
+
+ hd6301x_cpu_device::p6_data_w(data);
+}
+
+void hd6301y_cpu_device::clear_pending_isf()
+{
+ // IS flag is cleared when reading/writing P6 after reading P6 CSR
+ if (m_pending_isf_clear)
+ {
+ m_p6csr &= 0x7f;
+ m_pending_isf_clear = false;
+ }
+}
+
+uint8_t hd6301y_cpu_device::p6_csr_r()
+{
+ if (!machine().side_effects_disabled())
+ m_pending_isf_clear = true;
+
+ return m_p6csr | 7;
+}
+
+void hd6301y_cpu_device::p6_csr_w(uint8_t data)
+{
+ LOGPORT("Port 6 Control/Status Register: %02x\n", data);
+
+ m_p6csr = (m_p6csr & 0x80) | (data & 0x7f);
+ if (!(m_cc & 0x10) && data & 0x40)
+ m6800_check_irq2();
+}
+
uint8_t hd6301x_cpu_device::p7_data_r()
{
return 0xe0 | m_portx_data[2];
@@ -1376,13 +1583,13 @@ void m6801_cpu_device::tcsr_w(uint8_t data)
m_tcsr = data | (m_tcsr & 0xe0);
m_pending_tcsr &= m_tcsr;
modified_tcsr();
- if( !(m_cc & 0x10) )
+ if (!(m_cc & 0x10))
m6800_check_irq2();
}
uint8_t m6801_cpu_device::ch_r()
{
- if(!(m_pending_tcsr&TCSR_TOF) && !machine().side_effects_disabled())
+ if (!(m_pending_tcsr & TCSR_TOF) && !machine().side_effects_disabled())
{
m_tcsr &= ~TCSR_TOF;
modified_tcsr();
@@ -1428,13 +1635,13 @@ void m6801_cpu_device::ocrh_w(uint8_t data)
{
LOGTIMER("Output Compare High Register: %02x\n", data);
- if(!(m_pending_tcsr&TCSR_OCF))
+ if (!(m_pending_tcsr & TCSR_OCF))
{
m_tcsr &= ~TCSR_OCF;
modified_tcsr();
}
- if( m_output_compare.b.h != data)
+ if (m_output_compare.b.h != data)
{
m_output_compare.b.h = data;
modified_counters();
@@ -1445,13 +1652,13 @@ void m6801_cpu_device::ocrl_w(uint8_t data)
{
LOGTIMER("Output Compare Low Register: %02x\n", data);
- if(!(m_pending_tcsr&TCSR_OCF))
+ if (!(m_pending_tcsr & TCSR_OCF))
{
m_tcsr &= ~TCSR_OCF;
modified_tcsr();
}
- if( m_output_compare.b.l != data)
+ if (m_output_compare.b.l != data)
{
m_output_compare.b.l = data;
modified_counters();
@@ -1460,7 +1667,7 @@ void m6801_cpu_device::ocrl_w(uint8_t data)
uint8_t m6801_cpu_device::icrh_r()
{
- if(!(m_pending_tcsr&TCSR_ICF) && !machine().side_effects_disabled())
+ if (!(m_pending_tcsr & TCSR_ICF) && !machine().side_effects_disabled())
{
m_tcsr &= ~TCSR_ICF;
modified_tcsr();
@@ -1491,7 +1698,7 @@ void hd6301x_cpu_device::tcsr2_w(uint8_t data)
m_tcsr2 = data | (m_tcsr2 & TCSR2_OCF2);
m_pending_tcsr2 &= m_tcsr2;
modified_tcsr();
- if( !(m_cc & 0x10) )
+ if (!(m_cc & 0x10))
m6800_check_irq2();
}
@@ -1509,13 +1716,13 @@ void hd6301x_cpu_device::ocr2h_w(uint8_t data)
{
LOGTIMER("Output Compare High Register 2: %02x\n", data);
- if(!(m_pending_tcsr2&TCSR2_OCF2))
+ if (!(m_pending_tcsr2 & TCSR2_OCF2))
{
m_tcsr2 &= ~TCSR2_OCF2;
modified_tcsr();
}
- if( m_output_compare2.b.h != data)
+ if (m_output_compare2.b.h != data)
{
m_output_compare2.b.h = data;
modified_counters();
@@ -1526,13 +1733,13 @@ void hd6301x_cpu_device::ocr2l_w(uint8_t data)
{
LOGTIMER("Output Compare Low Register 2: %02x\n", data);
- if(!(m_pending_tcsr2&TCSR2_OCF2))
+ if (!(m_pending_tcsr2 & TCSR2_OCF2))
{
m_tcsr2 &= ~TCSR2_OCF2;
modified_tcsr();
}
- if( m_output_compare2.b.l != data)
+ if (m_output_compare2.b.l != data)
{
m_output_compare2.b.l = data;
modified_counters();
@@ -1540,6 +1747,93 @@ void hd6301x_cpu_device::ocr2l_w(uint8_t data)
}
+void hd6301x_cpu_device::increment_t2cnt(int amount)
+{
+ if (amount > uint8_t(m_tconr - m_t2cnt))
+ {
+ if (m_t2cnt > m_tconr)
+ {
+ amount -= 256 - m_t2cnt;
+ m_t2cnt = 0;
+ }
+ m_t2cnt = (m_t2cnt + amount) % (m_tconr + 1);
+
+ if (BIT(m_tcsr3, 3))
+ {
+ if (m_tout3 != BIT(m_tcsr3, 2))
+ {
+ m_tout3 = BIT(m_tcsr3, 2);
+ m_port2_written = true;
+ write_port2();
+ }
+ }
+ else if (BIT(m_tcsr3, 2))
+ {
+ m_tout3 = !m_tout3;
+ m_port2_written = true;
+ write_port2();
+ }
+
+ if (BIT(m_rmcr, 5) && !m_use_ext_serclock)
+ {
+ if (m_ext_serclock + amount >= 32)
+ {
+ m_ext_serclock = (m_ext_serclock + amount) % 32;
+ serial_transmit();
+ serial_receive();
+ }
+ else
+ m_ext_serclock += amount;
+ }
+
+ m_tcsr3 |= 0x80;
+ m_timer_next = 0; // HACK
+ }
+ else
+ m_t2cnt += amount;
+}
+
+uint8_t hd6301x_cpu_device::t2cnt_r()
+{
+ return m_t2cnt;
+}
+
+void hd6301x_cpu_device::t2cnt_w(uint8_t data)
+{
+ m_t2cnt = data;
+ m_t2cnt_written = true;
+}
+
+void hd6301x_cpu_device::tconr_w(uint8_t data)
+{
+ m_tconr = data;
+}
+
+uint8_t hd6301x_cpu_device::tcsr3_r()
+{
+ return m_tcsr3;
+}
+
+void hd6301x_cpu_device::tcsr3_w(uint8_t data)
+{
+ uint8_t tout3_last_enable = (m_tcsr3 & 0x0c) != 0;
+
+ // Bit 5 does not exist and Bit 7 can only be written with 0
+ m_tcsr3 = data & (0x5f | (m_tcsr3 & 0x80));
+
+ if (m_tout3 && !BIT(data, 4))
+ {
+ m_tout3 = false;
+ write_port2();
+ }
+ else if (tout3_last_enable ? (data & 0x0c) == 0 : (data & 0x0c) != 0)
+ {
+ m_port2_written = true;
+ write_port2();
+ }
+}
+
+
uint8_t m6801_cpu_device::sci_rmcr_r()
{
return m_rmcr;
@@ -1643,8 +1937,6 @@ void m6801_cpu_device::rcr_w(uint8_t data)
uint8_t m6801_cpu_device::ff_r()
{
- if (!machine().side_effects_disabled())
- logerror("PC %04x: warning - read from write-only internal register\n", pc());
return 0xff;
}
@@ -1655,7 +1947,7 @@ void m6801_cpu_device::m6801_clock_serial()
{
m_ext_serclock++;
- if (m_ext_serclock >= 8)
+ if (m_ext_serclock >= m_sclk_divider)
{
m_ext_serclock = 0;
serial_transmit();
@@ -1684,7 +1976,7 @@ std::unique_ptr<util::disasm_interface> hd6301_cpu_device::create_disassembler()
return std::make_unique<m680x_disassembler>(6301);
}
-void hd6301_cpu_device::TAKE_TRAP()
+void hd6301_cpu_device::take_trap()
{
enter_interrupt("take TRAP\n",0xffee);
}