diff options
Diffstat (limited to 'src/devices/cpu/m6800/m6801.cpp')
-rw-r--r-- | src/devices/cpu/m6800/m6801.cpp | 788 |
1 files changed, 389 insertions, 399 deletions
diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index e92fbfe343c..df8cb5de6bf 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -11,6 +11,7 @@ #define LOG_RXTICK (1U << 4) #define LOG_PORT (1U << 5) #define LOG_SER (1U << 6) +#define LOG_TIMER (1U << 7) //#define VERBOSE (LOG_SER) //#define LOG_OUTPUT_STREAM std::cout @@ -23,6 +24,7 @@ #define LOGRXTICK(...) LOGMASKED(LOG_RXTICK, __VA_ARGS__) #define LOGPORT(...) LOGMASKED(LOG_PORT, __VA_ARGS__) #define LOGSER(...) LOGMASKED(LOG_SER, __VA_ARGS__) +#define LOGTIMER(...) LOGMASKED(LOG_TIMER, __VA_ARGS__) #define CT m_counter.w.l @@ -48,44 +50,6 @@ SET_TIMER_EVENT; \ } -// I/O registers - -enum -{ - IO_P1DDR = 0, - IO_P2DDR, - IO_P1DATA, - IO_P2DATA, - IO_P3DDR, - IO_P4DDR, - IO_P3DATA, - IO_P4DATA, - IO_TCSR, - IO_CH, - IO_CL, - IO_OCRH, - IO_OCRL, - IO_ICRH, - IO_ICRL, - IO_P3CSR, - IO_RMCR, - IO_TRCSR, - IO_RDR, - IO_TDR, - IO_RCR, - IO_CAAH, - IO_CAAL, - IO_TCR1, - IO_TCR2, - IO_TSR, - IO_OCR2H, - IO_OCR2L, - IO_OCR3H, - IO_OCR3L, - IO_ICR2H, - IO_ICR2L -}; - // serial I/O #define M6801_RMCR_SS_MASK 0x03 // Speed Select @@ -257,10 +221,34 @@ const m6800_cpu_device::op_func m6801_cpu_device::hd63701_insn[0x100] = { }; +void m6801_cpu_device::m6801_io(address_map &map) +{ + map(0x0000, 0x0000).rw(FUNC(m6801_cpu_device::ff_r), FUNC(m6801_cpu_device::p1_ddr_w)); + map(0x0001, 0x0001).rw(FUNC(m6801_cpu_device::ff_r), FUNC(m6801_cpu_device::p2_ddr_w)); + map(0x0002, 0x0002).rw(FUNC(m6801_cpu_device::p1_data_r), FUNC(m6801_cpu_device::p1_data_w)); + map(0x0003, 0x0003).rw(FUNC(m6801_cpu_device::p2_data_r), FUNC(m6801_cpu_device::p2_data_w)); + map(0x0004, 0x0004).rw(FUNC(m6801_cpu_device::ff_r), FUNC(m6801_cpu_device::p3_ddr_w)); // TODO: external in 6801 modes 0–3 & 6 + map(0x0005, 0x0005).rw(FUNC(m6801_cpu_device::ff_r), FUNC(m6801_cpu_device::p4_ddr_w)); // TODO: external in 6801 modes 0–3 + map(0x0006, 0x0006).rw(FUNC(m6801_cpu_device::p3_data_r), FUNC(m6801_cpu_device::p3_data_w)); + map(0x0007, 0x0007).rw(FUNC(m6801_cpu_device::p4_data_r), FUNC(m6801_cpu_device::p4_data_w)); + map(0x0008, 0x0008).rw(FUNC(m6801_cpu_device::tcsr_r), FUNC(m6801_cpu_device::tcsr_w)); + map(0x0009, 0x0009).rw(FUNC(m6801_cpu_device::ch_r), FUNC(m6801_cpu_device::ch_w)); + map(0x000a, 0x000a).rw(FUNC(m6801_cpu_device::cl_r), FUNC(m6801_cpu_device::cl_w)); + map(0x000b, 0x000b).rw(FUNC(m6801_cpu_device::ocrh_r), FUNC(m6801_cpu_device::ocrh_w)); + map(0x000c, 0x000c).rw(FUNC(m6801_cpu_device::ocrl_r), FUNC(m6801_cpu_device::ocrl_w)); + map(0x000d, 0x000d).r(FUNC(m6801_cpu_device::icrh_r)); + map(0x000e, 0x000e).r(FUNC(m6801_cpu_device::icrl_r)); + map(0x000f, 0x000f).rw(FUNC(m6801_cpu_device::p3_csr_r), FUNC(m6801_cpu_device::p3_csr_w)); // TODO: external in 6801 modes 0–3, 5 & 6 + map(0x0010, 0x0010).rw(FUNC(m6801_cpu_device::sci_rmcr_r), FUNC(m6801_cpu_device::sci_rmcr_w)); + map(0x0011, 0x0011).rw(FUNC(m6801_cpu_device::sci_trcsr_r), FUNC(m6801_cpu_device::sci_trcsr_w)); + map(0x0012, 0x0012).r(FUNC(m6801_cpu_device::sci_rdr_r)); + map(0x0013, 0x0013).w(FUNC(m6801_cpu_device::sci_tdr_w)); + map(0x0014, 0x0014).rw(FUNC(m6801_cpu_device::rcr_r), FUNC(m6801_cpu_device::rcr_w)); +} + void m6801_cpu_device::m6803_mem(address_map &map) { - map(0x0000, 0x001f).rw(FUNC(m6801_cpu_device::m6801_io_r), FUNC(m6801_cpu_device::m6801_io_w)); - map(0x0020, 0x007f).noprw(); /* unused */ + m6801_io(map); map(0x0080, 0x00ff).ram(); /* 6803 internal RAM */ } @@ -268,8 +256,12 @@ void m6801_cpu_device::m6803_mem(address_map &map) DEFINE_DEVICE_TYPE(M6801, m6801_cpu_device, "m6801", "Motorola MC6801") DEFINE_DEVICE_TYPE(M6803, m6803_cpu_device, "m6803", "Motorola MC6803") DEFINE_DEVICE_TYPE(M6803E, m6803e_cpu_device, "m6803e", "Motorola MC6803E") -DEFINE_DEVICE_TYPE(HD6301, hd6301_cpu_device, "hd6301", "Hitachi HD6301") -DEFINE_DEVICE_TYPE(HD63701, hd63701_cpu_device, "hd63701", "Hitachi HD63701") +DEFINE_DEVICE_TYPE(HD6301V1, hd6301v1_cpu_device, "hd6301v1", "Hitachi HD6301V1") +DEFINE_DEVICE_TYPE(HD6301X0, hd6301x0_cpu_device, "hd6301x0", "Hitachi HD6301X0") +DEFINE_DEVICE_TYPE(HD6301Y0, hd6301y0_cpu_device, "hd6301y0", "Hitachi HD6301Y0") +DEFINE_DEVICE_TYPE(HD63701V0, hd63701v0_cpu_device, "hd63701v0", "Hitachi HD63701V0") +DEFINE_DEVICE_TYPE(HD63701X0, hd63701x0_cpu_device, "hd63701x0", "Hitachi HD63701X0") +DEFINE_DEVICE_TYPE(HD63701Y0, hd63701y0_cpu_device, "hd63701y0", "Hitachi HD63701Y0") DEFINE_DEVICE_TYPE(HD6303R, hd6303r_cpu_device, "hd6303r", "Hitachi HD6303R") DEFINE_DEVICE_TYPE(HD6303X, hd6303x_cpu_device, "hd6303x", "Hitachi HD6303X") DEFINE_DEVICE_TYPE(HD6303Y, hd6303y_cpu_device, "hd6303y", "Hitachi HD6303Y") @@ -298,18 +290,18 @@ m6803e_cpu_device::m6803e_cpu_device(const machine_config &mconfig, const char * { } -hd6301_cpu_device::hd6301_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6301_cpu_device(mconfig, HD6301, tag, owner, clock) +hd6301_cpu_device::hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : m6801_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701) { } -hd6301_cpu_device::hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : m6801_cpu_device(mconfig, type, tag, owner, clock, hd63701_insn, cycles_63701) +hd6301v1_cpu_device::hd6301v1_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301_cpu_device(mconfig, HD6301V1, tag, owner, clock) { } -hd63701_cpu_device::hd63701_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : m6801_cpu_device(mconfig, HD63701, tag, owner, clock, hd63701_insn, cycles_63701) +hd63701v0_cpu_device::hd63701v0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301_cpu_device(mconfig, HD63701V0, tag, owner, clock) { } @@ -318,13 +310,38 @@ hd6303r_cpu_device::hd6303r_cpu_device(const machine_config &mconfig, const char { } +hd6301x_cpu_device::hd6301x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : hd6301_cpu_device(mconfig, type, tag, owner, clock) +{ +} + +hd6301x0_cpu_device::hd6301x0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301x_cpu_device(mconfig, HD6301X0, tag, owner, clock) +{ +} + +hd63701x0_cpu_device::hd63701x0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301x_cpu_device(mconfig, HD63701X0, tag, owner, clock) +{ +} + hd6303x_cpu_device::hd6303x_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6301_cpu_device(mconfig, HD6303X, tag, owner, clock) + : hd6301x_cpu_device(mconfig, HD6303X, tag, owner, clock) +{ +} + +hd6301y0_cpu_device::hd6301y0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301x_cpu_device(mconfig, HD6301Y0, tag, owner, clock) +{ +} + +hd63701y0_cpu_device::hd63701y0_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hd6301x_cpu_device(mconfig, HD63701Y0, tag, owner, clock) { } hd6303y_cpu_device::hd6303y_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : hd6301_cpu_device(mconfig, HD6303Y, tag, owner, clock) + : hd6301x_cpu_device(mconfig, HD6303Y, tag, owner, clock) { } @@ -428,13 +445,13 @@ void m6801_cpu_device::set_rmcr(uint8_t data) switch ((m_rmcr & M6801_RMCR_CC_MASK) >> 2) { case 0: - LOGSER("6801: Using external serial clock: false\n"); + LOGSER("SCI: Using external serial clock: false\n"); m_sci_timer->enable(false); m_use_ext_serclock = false; break; case 3: // external clock - LOGSER("6801: Using external serial clock: true\n"); + LOGSER("SCI: Using external serial clock: true\n"); m_use_ext_serclock = true; m_sci_timer->enable(false); break; @@ -444,7 +461,7 @@ void m6801_cpu_device::set_rmcr(uint8_t data) { int divisor = M6801_RMCR_SS[m_rmcr & M6801_RMCR_SS_MASK]; attotime period = cycles_to_attotime(divisor); - LOGSER("6801: Setting serial rate, Divisor: %d Hz: %d\n", divisor, period.as_hz()); + 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; } @@ -459,7 +476,7 @@ int m6801_cpu_device::m6800_rx() void m6801_cpu_device::serial_transmit() { - LOGTXTICK("6801 Tx Tick presenting: %d\n", m_tx); + LOGTXTICK("SCI Tx Tick presenting: %d\n", m_tx); if (m_trcsr & M6801_TRCSR_TE) { @@ -505,7 +522,7 @@ void m6801_cpu_device::serial_transmit() m_txbits++; - LOGTX("6801 Transmit START Data %02x\n", m_tsr); + LOGTX("SCI Transmit START Data %02x\n", m_tsr); } break; @@ -517,7 +534,7 @@ void m6801_cpu_device::serial_transmit() m_txbits = M6801_SERIAL_START; - LOGTX("6801 Transmit STOP\n"); + LOGTX("SCI Transmit STOP\n"); break; default: @@ -527,7 +544,7 @@ void m6801_cpu_device::serial_transmit() // shift transmit register m_tsr >>= 1; - LOGTX("6801 Tx Present Bit %u: %u\n", m_txbits, m_tx); + LOGTX("SCI Tx Present Bit %u: %u\n", m_txbits, m_tx); m_txbits++; break; @@ -546,7 +563,7 @@ void m6801_cpu_device::serial_transmit() void m6801_cpu_device::serial_receive() { - LOGRXTICK("6801 Rx Tick TRCSR %02x bits %u check %02x\n", m_trcsr, m_rxbits, m_trcsr & M6801_TRCSR_RE); + LOGRXTICK("SCI Rx Tick TRCSR %02x bits %u check %02x\n", m_trcsr, m_rxbits, m_trcsr & M6801_TRCSR_RE); if (m_trcsr & M6801_TRCSR_RE) { @@ -557,11 +574,11 @@ void m6801_cpu_device::serial_receive() { m_rxbits++; - LOGRX("6801 Received WAKE UP bit %u\n", m_rxbits); + LOGRX("SCI Received WAKE UP bit %u\n", m_rxbits); if (m_rxbits == 10) { - LOGRX("6801 Receiver Wake Up\n"); + LOGRX("SCI Receiver Wake Up\n"); m_trcsr &= ~M6801_TRCSR_WU; m_rxbits = M6801_SERIAL_START; @@ -569,7 +586,7 @@ void m6801_cpu_device::serial_receive() } else { - LOGRX("6801 Receiver Wake Up interrupted\n"); + LOGRX("SCI Receiver Wake Up interrupted\n"); m_rxbits = M6801_SERIAL_START; } @@ -585,21 +602,21 @@ void m6801_cpu_device::serial_receive() // start bit found m_rxbits++; - LOGRX("6801 Received START bit\n"); + LOGRX("SCI Received START bit\n"); } break; case M6801_SERIAL_STOP: if (m6800_rx() == 1) { - LOGRX("6801 Received STOP bit\n"); + LOGRX("SCI Received STOP bit\n"); if (m_trcsr & M6801_TRCSR_RDRF) { // overrun error m_trcsr |= M6801_TRCSR_ORFE; - LOGRX("6801 Receive Overrun Error\n"); + LOGRX("SCI Receive Overrun Error\n"); CHECK_IRQ_LINES(); } @@ -610,7 +627,7 @@ void m6801_cpu_device::serial_receive() // transfer data into receive register m_rdr = m_rsr; - LOGRX("6801 Receive Data Register: %02x\n", m_rdr); + LOGRX("SCI Receive Data Register: %02x\n", m_rdr); // set RDRF flag m_trcsr |= M6801_TRCSR_RDRF; @@ -631,7 +648,7 @@ void m6801_cpu_device::serial_receive() m_trcsr |= M6801_TRCSR_ORFE; m_trcsr &= ~M6801_TRCSR_RDRF; - LOGRX("6801 Receive Framing Error\n"); + LOGRX("SCI Receive Framing Error\n"); CHECK_IRQ_LINES(); } @@ -646,7 +663,7 @@ void m6801_cpu_device::serial_receive() // receive bit into register m_rsr |= (m6800_rx() << 7); - LOGRX("6801 RX sampled DATA bit %u: %u\n", m_rxbits, BIT(m_rsr, 7)); + LOGRX("SCI RX sampled DATA bit %u: %u\n", m_rxbits, BIT(m_rsr, 7)); m_rxbits++; break; @@ -854,421 +871,399 @@ void m6801_cpu_device::set_os3(int state) m_out_sc2_func(state); } -READ8_MEMBER( m6801_cpu_device::m6801_io_r ) + +void m6801_cpu_device::p1_ddr_w(uint8_t data) { - uint8_t data = 0; + LOGPORT("Port 1 Data Direction Register: %02x\n", data); - switch (offset) + if (m_port_ddr[0] != data) { - case IO_P1DDR: - data = m_port_ddr[0]; - break; - - case IO_P2DDR: - data = m_port_ddr[1]; - break; - - case IO_P1DATA: - if(m_port_ddr[0] == 0xff) - data = m_port_data[0]; - else - data = (m_in_port_func[0]() & (m_port_ddr[0] ^ 0xff)) - | (m_port_data[0] & m_port_ddr[0]); - break; - - case IO_P2DATA: - if(m_port_ddr[1] == 0xff) - data = m_port_data[1]; - else - data = (m_in_port_func[1]() & (m_port_ddr[1] ^ 0xff)) - | (m_port_data[1] & m_port_ddr[1]); - break; + m_port_ddr[0] = data; + m_out_port_func[0]((m_port_data[0] & m_port_ddr[0]) | (m_port_ddr[0] ^ 0xff)); + } +} - case IO_P3DDR: - data = 0xff; - break; +uint8_t m6801_cpu_device::p1_data_r() +{ + 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]); +} - case IO_P4DDR: - data = m_port_ddr[3]; - break; +void m6801_cpu_device::p1_data_w(uint8_t data) +{ + LOGPORT("Port 1 Data Register: %02x\n", data); - case IO_P3DATA: - if (!machine().side_effects_disabled()) - { - if (m_p3csr_is3_flag_read) - { - LOGPORT("Cleared IS3\n"); - m_p3csr &= ~M6801_P3CSR_IS3_FLAG; - m_p3csr_is3_flag_read = 0; - } + m_port_data[0] = data; + m_out_port_func[0]((m_port_data[0] & m_port_ddr[0]) | (m_port_ddr[0] ^ 0xff)); +} - if (!(m_p3csr & M6801_P3CSR_OSS)) - { - set_os3(ASSERT_LINE); - } - } +void m6801_cpu_device::p2_ddr_w(uint8_t data) +{ + LOGPORT("Port 2 Data Direction Register: %02x\n", data); - 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]); + if (m_port_ddr[1] != data) + { + m_port_ddr[1] = data; + write_port2(); + } +} - if (!machine().side_effects_disabled()) - { - m_port3_latched = 0; +uint8_t m6801_cpu_device::p2_data_r() +{ + 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]); +} - if (!(m_p3csr & M6801_P3CSR_OSS)) - { - set_os3(CLEAR_LINE); - } - } - break; +void m6801_cpu_device::p2_data_w(uint8_t data) +{ + LOGPORT("Port 2 Data Register: %02x\n", data); - case IO_P4DATA: - if(m_port_ddr[3] == 0xff) - data = m_port_data[3]; - else - data = (m_in_port_func[3]() & (m_port_ddr[3] ^ 0xff)) - | (m_port_data[3] & m_port_ddr[3]); - break; + m_port_data[1] = data; + m_port2_written = 1; + write_port2(); +} - case IO_TCSR: - m_pending_tcsr = 0; - data = m_tcsr; - break; +void m6801_cpu_device::p3_ddr_w(uint8_t data) +{ + LOGPORT("Port 3 Data Direction Register: %02x\n", data); - case IO_CH: - if(!(m_pending_tcsr&TCSR_TOF) && !machine().side_effects_disabled()) - { - m_tcsr &= ~TCSR_TOF; - MODIFIED_tcsr; - } - data = m_counter.b.h; - break; + if (m_port_ddr[2] != data) + { + m_port_ddr[2] = data; + m_out_port_func[2]((m_port_data[2] & m_port_ddr[2]) | (m_port_ddr[2] ^ 0xff)); + } +} - case IO_CL: - data = m_counter.b.l; - // HACK there should be a break here, but Coleco Adam won't boot with it present, proper fix required to the free-running counter +uint8_t m6801_cpu_device::p3_data_r() +{ + uint8_t data; - case IO_OCRH: - if(!(m_pending_tcsr&TCSR_OCF) && !machine().side_effects_disabled()) + if (!machine().side_effects_disabled()) + { + if (m_p3csr_is3_flag_read) { - m_tcsr &= ~TCSR_OCF; - MODIFIED_tcsr; + LOGPORT("Cleared IS3\n"); + m_p3csr &= ~M6801_P3CSR_IS3_FLAG; + m_p3csr_is3_flag_read = 0; } - data = m_output_compare.b.h; - break; - case IO_OCRL: - if(!(m_pending_tcsr&TCSR_OCF) && !machine().side_effects_disabled()) + if (!(m_p3csr & M6801_P3CSR_OSS)) { - m_tcsr &= ~TCSR_OCF; - MODIFIED_tcsr; + set_os3(ASSERT_LINE); } - data = m_output_compare.b.l; - break; + } - case IO_ICRH: - if(!(m_pending_tcsr&TCSR_ICF) && !machine().side_effects_disabled()) - { - m_tcsr &= ~TCSR_ICF; - MODIFIED_tcsr; - } - data = (m_input_capture >> 0) & 0xff; - break; + 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]); - case IO_ICRL: - data = (m_input_capture >> 8) & 0xff; - break; + if (!machine().side_effects_disabled()) + { + m_port3_latched = 0; - case IO_P3CSR: - if ((m_p3csr & M6801_P3CSR_IS3_FLAG) && !machine().side_effects_disabled()) + if (!(m_p3csr & M6801_P3CSR_OSS)) { - m_p3csr_is3_flag_read = 1; + set_os3(CLEAR_LINE); } + } + return data; +} - data = m_p3csr; - break; - - case IO_RMCR: - data = m_rmcr; - break; +void m6801_cpu_device::p3_data_w(uint8_t data) +{ + LOGPORT("Port 3 Data Register: %02x\n", data); - case IO_TRCSR: - if (!machine().side_effects_disabled()) - { - if (m_trcsr & M6801_TRCSR_TDRE) - { - m_trcsr_read_tdre = 1; - } + if (m_p3csr_is3_flag_read) + { + LOGPORT("Cleared IS3\n"); + m_p3csr &= ~M6801_P3CSR_IS3_FLAG; + m_p3csr_is3_flag_read = 0; + } - if (m_trcsr & M6801_TRCSR_ORFE) - { - m_trcsr_read_orfe = 1; - } + if (m_p3csr & M6801_P3CSR_OSS) + { + set_os3(ASSERT_LINE); + } - if (m_trcsr & M6801_TRCSR_RDRF) - { - m_trcsr_read_rdrf = 1; - } - } + m_port_data[2] = data; + m_out_port_func[2]((m_port_data[2] & m_port_ddr[2]) | (m_port_ddr[2] ^ 0xff)); - data = m_trcsr; - break; + if (m_p3csr & M6801_P3CSR_OSS) + { + set_os3(CLEAR_LINE); + } +} - case IO_RDR: - if (!machine().side_effects_disabled()) - { - if (m_trcsr_read_orfe) - { - LOG("Cleared ORFE\n"); - m_trcsr_read_orfe = 0; - m_trcsr &= ~M6801_TRCSR_ORFE; - } +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; + } - if (m_trcsr_read_rdrf) - { - LOG("Cleared RDRF\n"); - m_trcsr_read_rdrf = 0; - m_trcsr &= ~M6801_TRCSR_RDRF; - } - } + return m_p3csr; +} - data = m_rdr; - break; +void m6801_cpu_device::p3_csr_w(uint8_t data) +{ + LOGPORT("Port 3 Control and Status Register: %02x\n", data); - case IO_TDR: - data = m_tdr; - break; + m_p3csr = data; +} - case IO_RCR: - data = m_ram_ctrl; - break; +void m6801_cpu_device::p4_ddr_w(uint8_t data) +{ + LOGPORT("Port 4 Data Direction Register: %02x\n", data); - case IO_CAAH: - case IO_CAAL: - case IO_TCR1: - case IO_TCR2: - case IO_TSR: - case IO_OCR2H: - case IO_OCR2L: - case IO_OCR3H: - case IO_OCR3L: - case IO_ICR2H: - case IO_ICR2L: - default: - logerror("PC %04x: warning - read from reserved internal register %02x\n", pc(),offset); + if (m_port_ddr[3] != data) + { + m_port_ddr[3] = data; + m_out_port_func[3]((m_port_data[3] & m_port_ddr[3]) | (m_port_ddr[3] ^ 0xff)); } - - return data; } -WRITE8_MEMBER( m6801_cpu_device::m6801_io_w ) +uint8_t m6801_cpu_device::p4_data_r() { - switch (offset) - { - case IO_P1DDR: - LOGPORT("Port 1 Data Direction Register: %02x\n", data); - - if (m_port_ddr[0] != data) - { - m_port_ddr[0] = data; - m_out_port_func[0]((m_port_data[0] & m_port_ddr[0]) | (m_port_ddr[0] ^ 0xff)); - } - break; + 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]); +} - case IO_P2DDR: - LOGPORT("Port 2 Data Direction Register: %02x\n", data); +void m6801_cpu_device::p4_data_w(uint8_t data) +{ + LOGPORT("Port 4 Data Register: %02x\n", data); - if (m_port_ddr[1] != data) - { - m_port_ddr[1] = data; - write_port2(); - } - break; + m_port_data[3] = data; + m_out_port_func[3]((m_port_data[3] & m_port_ddr[3]) | (m_port_ddr[3] ^ 0xff)); +} - case IO_P1DATA: - LOGPORT("Port 1 Data Register: %02x\n", data); +uint8_t m6801_cpu_device::tcsr_r() +{ + if (!machine().side_effects_disabled()) + m_pending_tcsr = 0; + return m_tcsr; +} - m_port_data[0] = data; - m_out_port_func[0]((m_port_data[0] & m_port_ddr[0]) | (m_port_ddr[0] ^ 0xff)); - break; +void m6801_cpu_device::tcsr_w(uint8_t data) +{ + LOGTIMER("Timer Control and Status Register: %02x\n", data); - case IO_P2DATA: - LOGPORT("Port 2 Data Register: %02x\n", data); + m_tcsr = data; + m_pending_tcsr &= m_tcsr; + MODIFIED_tcsr; + if( !(m_cc & 0x10) ) + m6800_check_irq2(); +} - m_port_data[1] = data; - m_port2_written = 1; - write_port2(); - break; +uint8_t m6801_cpu_device::ch_r() +{ + if(!(m_pending_tcsr&TCSR_TOF) && !machine().side_effects_disabled()) + { + m_tcsr &= ~TCSR_TOF; + MODIFIED_tcsr; + } + return m_counter.b.h; +} - case IO_P3DDR: - LOGPORT("Port 3 Data Direction Register: %02x\n", data); +uint8_t m6801_cpu_device::cl_r() +{ + uint8_t data = m_counter.b.l; - if (m_port_ddr[2] != data) - { - m_port_ddr[2] = data; - m_out_port_func[2]((m_port_data[2] & m_port_ddr[2]) | (m_port_ddr[2] ^ 0xff)); - } - break; + // HACK there should be a break here, but Coleco Adam won't boot with it present, proper fix required to the free-running counter + (void)data; + return ocrh_r(); +} - case IO_P4DDR: - LOGPORT("Port 4 Data Direction Register: %02x\n", data); +void m6801_cpu_device::ch_w(uint8_t data) +{ + LOGTIMER("Counter High Register: %02x\n", data); - if (m_port_ddr[3] != data) - { - m_port_ddr[3] = data; - m_out_port_func[3]((m_port_data[3] & m_port_ddr[3]) | (m_port_ddr[3] ^ 0xff)); - } - break; + m_latch09 = data & 0xff; /* 6301 only */ + CT = 0xfff8; + TOH = CTH; + MODIFIED_counters; +} - case IO_P3DATA: - LOGPORT("Port 3 Data Register: %02x\n", data); +void m6801_cpu_device::cl_w(uint8_t data) +{ + LOGTIMER("Counter Low Register: %02x\n", data); - if (m_p3csr_is3_flag_read) - { - LOGPORT("Cleared IS3\n"); - m_p3csr &= ~M6801_P3CSR_IS3_FLAG; - m_p3csr_is3_flag_read = 0; - } + CT = (m_latch09 << 8) | (data & 0xff); + TOH = CTH; + MODIFIED_counters; +} - if (m_p3csr & M6801_P3CSR_OSS) - { - set_os3(ASSERT_LINE); - } +uint8_t m6801_cpu_device::ocrh_r() +{ + if(!(m_pending_tcsr&TCSR_OCF) && !machine().side_effects_disabled()) + { + m_tcsr &= ~TCSR_OCF; + MODIFIED_tcsr; + } + return m_output_compare.b.h; +} - m_port_data[2] = data; - m_out_port_func[2]((m_port_data[2] & m_port_ddr[2]) | (m_port_ddr[2] ^ 0xff)); +uint8_t m6801_cpu_device::ocrl_r() +{ + if(!(m_pending_tcsr&TCSR_OCF) && !machine().side_effects_disabled()) + { + m_tcsr &= ~TCSR_OCF; + MODIFIED_tcsr; + } + return m_output_compare.b.l; +} - if (m_p3csr & M6801_P3CSR_OSS) - { - set_os3(CLEAR_LINE); - } - break; +void m6801_cpu_device::ocrh_w(uint8_t data) +{ + LOGTIMER("Output Compare High Register: %02x\n", data); - case IO_P4DATA: - LOGPORT("Port 4 Data Register: %02x\n", data); + if( m_output_compare.b.h != data) + { + m_output_compare.b.h = data; + MODIFIED_counters; + } +} - m_port_data[3] = data; - m_out_port_func[3]((m_port_data[3] & m_port_ddr[3]) | (m_port_ddr[3] ^ 0xff)); - break; +void m6801_cpu_device::ocrl_w(uint8_t data) +{ + LOGTIMER("Output Compare Low Register: %02x\n", data); - case IO_TCSR: - LOG("Timer Control and Status Register: %02x\n", data); + if( m_output_compare.b.l != data) + { + m_output_compare.b.l = data; + MODIFIED_counters; + } +} - m_tcsr = data; - m_pending_tcsr &= m_tcsr; +uint8_t m6801_cpu_device::icrh_r() +{ + if(!(m_pending_tcsr&TCSR_ICF) && !machine().side_effects_disabled()) + { + m_tcsr &= ~TCSR_ICF; MODIFIED_tcsr; - if( !(m_cc & 0x10) ) - m6800_check_irq2(); - break; + } + return (m_input_capture >> 0) & 0xff; +} - case IO_CH: - LOG("Counter High Register: %02x\n", data); +uint8_t m6801_cpu_device::icrl_r() +{ + return (m_input_capture >> 8) & 0xff; +} - m_latch09 = data & 0xff; /* 6301 only */ - CT = 0xfff8; - TOH = CTH; - MODIFIED_counters; - break; - case IO_CL: /* 6301 only */ - LOG("Counter Low Register: %02x\n", data); +uint8_t m6801_cpu_device::sci_rmcr_r() +{ + return m_rmcr; +} - CT = (m_latch09 << 8) | (data & 0xff); - TOH = CTH; - MODIFIED_counters; - break; +void m6801_cpu_device::sci_rmcr_w(uint8_t data) +{ + LOGSER("SCI Rate and Mode Control Register: %02x\n", data); - case IO_OCRH: - LOG("Output Compare High Register: %02x\n", data); + set_rmcr(data); +} - if( m_output_compare.b.h != data) +uint8_t m6801_cpu_device::sci_trcsr_r() +{ + if (!machine().side_effects_disabled()) + { + if (m_trcsr & M6801_TRCSR_TDRE) { - m_output_compare.b.h = data; - MODIFIED_counters; + m_trcsr_read_tdre = 1; } - break; - case IO_OCRL: - LOG("Output Compare Low Register: %02x\n", data); - - if( m_output_compare.b.l != data) + if (m_trcsr & M6801_TRCSR_ORFE) { - m_output_compare.b.l = data; - MODIFIED_counters; + m_trcsr_read_orfe = 1; } - break; - case IO_ICRH: - case IO_ICRL: - case IO_RDR: - LOG("PC %04x: warning - write %02x to read only internal register %02x\n",pc(),data,offset); - break; + if (m_trcsr & M6801_TRCSR_RDRF) + { + m_trcsr_read_rdrf = 1; + } + } - case IO_P3CSR: - LOGPORT("Port 3 Control and Status Register: %02x\n", data); + return m_trcsr; +} - m_p3csr = data; - break; +void m6801_cpu_device::sci_trcsr_w(uint8_t data) +{ + LOGSER("SCI Transmit/Receive Control and Status Register: %02x\n", data); - case IO_RMCR: - LOGSER("Rate and Mode Control Register: %02x\n", data); + if ((data & M6801_TRCSR_TE) && !(m_trcsr & M6801_TRCSR_TE)) + { + m_txstate = M6801_TX_STATE_INIT; + m_txbits = 0; + m_tx = 1; + } - set_rmcr(data); - break; + if ((data & M6801_TRCSR_RE) && !(m_trcsr & M6801_TRCSR_RE)) + { + m_rxbits = 0; + } - case IO_TRCSR: - LOGSER("Transmit/Receive Control and Status Register: %02x\n", data); + m_trcsr = (m_trcsr & 0xe0) | (data & 0x1f); +} - if ((data & M6801_TRCSR_TE) && !(m_trcsr & M6801_TRCSR_TE)) +uint8_t m6801_cpu_device::sci_rdr_r() +{ + if (!machine().side_effects_disabled()) + { + if (m_trcsr_read_orfe) { - m_txstate = M6801_TX_STATE_INIT; - m_txbits = 0; - m_tx = 1; + LOGSER("Cleared ORFE\n"); + m_trcsr_read_orfe = 0; + m_trcsr &= ~M6801_TRCSR_ORFE; } - if ((data & M6801_TRCSR_RE) && !(m_trcsr & M6801_TRCSR_RE)) + if (m_trcsr_read_rdrf) { - m_rxbits = 0; + LOGSER("Cleared RDRF\n"); + m_trcsr_read_rdrf = 0; + m_trcsr &= ~M6801_TRCSR_RDRF; } + } - m_trcsr = (m_trcsr & 0xe0) | (data & 0x1f); - break; + return m_rdr; +} - case IO_TDR: - LOGSER("6801 Transmit Data Register: $%02x/%d\n", data, data); +void m6801_cpu_device::sci_tdr_w(uint8_t data) +{ + LOGSER("SCI Transmit Data Register: $%02x/%d\n", data, data); - if (m_trcsr_read_tdre) - { - m_trcsr_read_tdre = 0; - m_trcsr &= ~M6801_TRCSR_TDRE; - } - m_tdr = data; - break; + if (m_trcsr_read_tdre) + { + m_trcsr_read_tdre = 0; + m_trcsr &= ~M6801_TRCSR_TDRE; + } + m_tdr = data; +} - case IO_RCR: - LOG("RAM Control Register: %02x\n", data); - m_ram_ctrl = data; - break; +uint8_t m6801_cpu_device::rcr_r() +{ + return m_ram_ctrl; +} - case IO_CAAH: - case IO_CAAL: - case IO_TCR1: - case IO_TCR2: - case IO_TSR: - case IO_OCR2H: - case IO_OCR2L: - case IO_OCR3H: - case IO_OCR3L: - case IO_ICR2H: - case IO_ICR2L: - default: - logerror("PC %04x: warning - write %02x to reserved internal register %02x\n", pc(),data,offset); - break; - } +void m6801_cpu_device::rcr_w(uint8_t data) +{ + LOG("RAM Control Register: %02x\n", data); + + m_ram_ctrl = 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; } @@ -1307,12 +1302,7 @@ std::unique_ptr<util::disasm_interface> hd6301_cpu_device::create_disassembler() return std::make_unique<m680x_disassembler>(6301); } -std::unique_ptr<util::disasm_interface> hd63701_cpu_device::create_disassembler() -{ - return std::make_unique<m680x_disassembler>(63701); -} - -void hd63701_cpu_device::TAKE_TRAP() +void hd6301_cpu_device::TAKE_TRAP() { enter_interrupt("take TRAP\n",0xffee); } |