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.cpp788
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);
}