diff options
Diffstat (limited to 'src/devices/cpu/m6800/m6801.cpp')
-rw-r--r-- | src/devices/cpu/m6800/m6801.cpp | 398 |
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); } |