diff options
Diffstat (limited to 'src/devices/cpu/tlcs870/tlcs870.cpp')
-rw-r--r-- | src/devices/cpu/tlcs870/tlcs870.cpp | 208 |
1 files changed, 121 insertions, 87 deletions
diff --git a/src/devices/cpu/tlcs870/tlcs870.cpp b/src/devices/cpu/tlcs870/tlcs870.cpp index c29db26f769..d29ae07b7b6 100644 --- a/src/devices/cpu/tlcs870/tlcs870.cpp +++ b/src/devices/cpu/tlcs870/tlcs870.cpp @@ -15,7 +15,6 @@ #include "emu.h" #include "tlcs870.h" #include "tlcs870d.h" -#include "debugger.h" //#define VERBOSE 1 #include "logmacro.h" @@ -111,10 +110,10 @@ tlcs870_device::tlcs870_device(const machine_config &mconfig, device_type optype , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0) , m_intram(*this, "intram") , m_dbr(*this, "dbr") - , m_port_in_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}} - , m_port_out_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}} - , m_port_analog_in_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}} - , m_serial_out_cb{{*this}, {*this}} + , m_port_in_cb(*this, 0xff) + , m_port_out_cb(*this) + , m_port_analog_in_cb(*this, 0xff) + , m_serial_out_cb(*this) { } @@ -138,7 +137,7 @@ bool tlcs870_device::stream_arg(std::ostream &stream, uint32_t pc, const char *p } // NOT using templates here because there are subtle differences in the port behavior (the ports are multi-purpose) that still need implementing -READ8_MEMBER(tlcs870_device::port0_r) +uint8_t tlcs870_device::port0_r() { // need to use P0CR (0x000a) to control direction @@ -148,7 +147,7 @@ READ8_MEMBER(tlcs870_device::port0_r) return m_port_out_latch[0]; } -READ8_MEMBER(tlcs870_device::port1_r) +uint8_t tlcs870_device::port1_r() { // need to use P1CR (0x000b) to control direction @@ -158,7 +157,7 @@ READ8_MEMBER(tlcs870_device::port1_r) return m_port_out_latch[1]; } -READ8_MEMBER(tlcs870_device::port2_r) // 3-bit port +uint8_t tlcs870_device::port2_r() // 3-bit port { if (m_read_input_port) return m_port_in_cb[2]() | 0xf8; @@ -166,7 +165,7 @@ READ8_MEMBER(tlcs870_device::port2_r) // 3-bit port return m_port_out_latch[2]; } -READ8_MEMBER(tlcs870_device::port3_r) +uint8_t tlcs870_device::port3_r() { if (m_read_input_port) return m_port_in_cb[3](); @@ -174,7 +173,7 @@ READ8_MEMBER(tlcs870_device::port3_r) return m_port_out_latch[3]; } -READ8_MEMBER(tlcs870_device::port4_r) +uint8_t tlcs870_device::port4_r() { if (m_read_input_port) return m_port_in_cb[4](); @@ -182,7 +181,7 @@ READ8_MEMBER(tlcs870_device::port4_r) return m_port_out_latch[4]; } -READ8_MEMBER(tlcs870_device::port5_r) // 5-bit port +uint8_t tlcs870_device::port5_r() // 5-bit port { if (m_read_input_port) return m_port_in_cb[5]() | 0xe0; @@ -190,7 +189,7 @@ READ8_MEMBER(tlcs870_device::port5_r) // 5-bit port return m_port_out_latch[5]; } -READ8_MEMBER(tlcs870_device::port6_r) // doubles up as analog? +uint8_t tlcs870_device::port6_r() // doubles up as analog? { // need to use P6CR (0x000c) to control direction @@ -200,7 +199,7 @@ READ8_MEMBER(tlcs870_device::port6_r) // doubles up as analog? return m_port_out_latch[6]; } -READ8_MEMBER(tlcs870_device::port7_r) +uint8_t tlcs870_device::port7_r() { // need to use P7CR (0x000d) to control direction @@ -210,70 +209,70 @@ READ8_MEMBER(tlcs870_device::port7_r) return m_port_out_latch[7]; } -WRITE8_MEMBER(tlcs870_device::port0_w) +void tlcs870_device::port0_w(uint8_t data) { m_port_out_latch[0] = data; m_port_out_cb[0](data); } -WRITE8_MEMBER(tlcs870_device::port1_w) +void tlcs870_device::port1_w(uint8_t data) { m_port_out_latch[1] = data; m_port_out_cb[1](data); } -WRITE8_MEMBER(tlcs870_device::port2_w) +void tlcs870_device::port2_w(uint8_t data) { m_port_out_latch[2] = data; m_port_out_cb[2](data); } -WRITE8_MEMBER(tlcs870_device::port3_w) +void tlcs870_device::port3_w(uint8_t data) { m_port_out_latch[3] = data; m_port_out_cb[3](data); } -WRITE8_MEMBER(tlcs870_device::port4_w) +void tlcs870_device::port4_w(uint8_t data) { m_port_out_latch[4] = data; m_port_out_cb[4](data); } -WRITE8_MEMBER(tlcs870_device::port5_w) +void tlcs870_device::port5_w(uint8_t data) { m_port_out_latch[5] = data; m_port_out_cb[5](data); } -WRITE8_MEMBER(tlcs870_device::port6_w) +void tlcs870_device::port6_w(uint8_t data) { m_port_out_latch[6] = data; m_port_out_cb[6](data); } -WRITE8_MEMBER(tlcs870_device::port7_w) +void tlcs870_device::port7_w(uint8_t data) { m_port_out_latch[7] = data; m_port_out_cb[7](data); } -WRITE8_MEMBER(tlcs870_device::p0cr_w) +void tlcs870_device::p0cr_w(uint8_t data) { m_port0_cr = data; } -WRITE8_MEMBER(tlcs870_device::p1cr_w) +void tlcs870_device::p1cr_w(uint8_t data) { m_port1_cr = data; } -WRITE8_MEMBER(tlcs870_device::p6cr_w) +void tlcs870_device::p6cr_w(uint8_t data) { m_port6_cr = data; } -WRITE8_MEMBER(tlcs870_device::p7cr_w) +void tlcs870_device::p7cr_w(uint8_t data) { m_port7_cr = data; } @@ -287,7 +286,7 @@ TIMER_CALLBACK_MEMBER(tlcs870_device::tc1_cb) } -WRITE8_MEMBER(tlcs870_device::tc1cr_w) +void tlcs870_device::tc1cr_w(uint8_t data) { m_TC1CR = data; @@ -302,32 +301,32 @@ WRITE8_MEMBER(tlcs870_device::tc1cr_w) LOG("%d: TC1M-0 (TC1 Mode Select)\n", (m_TC1CR & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::treg1a_l_w) +void tlcs870_device::treg1a_l_w(uint8_t data) { m_TREG1A = (m_TREG1A & 0xff00) | data; } -WRITE8_MEMBER(tlcs870_device::treg1a_h_w) +void tlcs870_device::treg1a_h_w(uint8_t data) { m_TREG1A = (m_TREG1A & 0x00ff) | (data << 8); } -WRITE8_MEMBER(tlcs870_device::treg1b_l_w) +void tlcs870_device::treg1b_l_w(uint8_t data) { m_TREG1B = (m_TREG1B & 0xff00) | data; } -WRITE8_MEMBER(tlcs870_device::treg1b_h_w) +void tlcs870_device::treg1b_h_w(uint8_t data) { m_TREG1B = (m_TREG1B & 0x00ff) | (data << 8); } -READ8_MEMBER(tlcs870_device::treg1b_l_r) +uint8_t tlcs870_device::treg1b_l_r() { return m_TREG1B & 0xff; } -READ8_MEMBER(tlcs870_device::treg1b_h_r) +uint8_t tlcs870_device::treg1b_h_r() { return (m_TREG1B >>8) & 0xff; } @@ -350,7 +349,7 @@ void tlcs870_device::tc2_cancel() m_tcx_timer[1]->adjust(attotime::never); } -WRITE8_MEMBER(tlcs870_device::tc2cr_w) +void tlcs870_device::tc2cr_w(uint8_t data) { if (data & 0x20) { @@ -377,12 +376,12 @@ WRITE8_MEMBER(tlcs870_device::tc2cr_w) LOG("%d: TC2M (TC2 Mode Select)\n", (m_TC2CR & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::treg2_l_w) +void tlcs870_device::treg2_l_w(uint8_t data) { m_TREG2 = (m_TREG2 & 0xff00) | data; } -WRITE8_MEMBER(tlcs870_device::treg2_h_w) +void tlcs870_device::treg2_h_w(uint8_t data) { m_TREG2 = (m_TREG2 & 0x00ff) | (data << 8); } @@ -394,7 +393,7 @@ TIMER_CALLBACK_MEMBER(tlcs870_device::tc3_cb) } -WRITE8_MEMBER(tlcs870_device::tc3cr_w) +void tlcs870_device::tc3cr_w(uint8_t data) { m_TC3CR = data; @@ -409,17 +408,17 @@ WRITE8_MEMBER(tlcs870_device::tc3cr_w) LOG("%d: TC3M (TC3 Mode Select)\n", (m_TC3CR & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::treg3a_w) +void tlcs870_device::treg3a_w(uint8_t data) { m_TREG3A = data; } -READ8_MEMBER(tlcs870_device::treg3a_r) +uint8_t tlcs870_device::treg3a_r() { return m_TREG3A; } -READ8_MEMBER(tlcs870_device::treg3b_r) +uint8_t tlcs870_device::treg3b_r() { return m_TREG3B; } @@ -431,7 +430,7 @@ TIMER_CALLBACK_MEMBER(tlcs870_device::tc4_cb) } -WRITE8_MEMBER(tlcs870_device::tc4cr_w) +void tlcs870_device::tc4cr_w(uint8_t data) { m_TC4CR = data; @@ -446,7 +445,7 @@ WRITE8_MEMBER(tlcs870_device::tc4cr_w) LOG("%d: TC4M-0 (TC4 Mode Select)\n", (m_TC4CR & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::treg4_w) +void tlcs870_device::treg4_w(uint8_t data) { m_TREG4 = data; } @@ -455,7 +454,7 @@ WRITE8_MEMBER(tlcs870_device::treg4_w) // this is used with TLCS870_IRQ_INTTBT (FFF2 INTTBT) (not used by hng64) // the divider output makes use of PORT1 bit 3, which must be properly configured -WRITE8_MEMBER(tlcs870_device::tbtcr_w) +void tlcs870_device::tbtcr_w(uint8_t data) { m_TBTCR = data; @@ -470,7 +469,7 @@ WRITE8_MEMBER(tlcs870_device::tbtcr_w) LOG("%d: TBTCK-0 (Time Base Timer Interrupt Frequency)\n", (m_TBTCR & 0x01) ? 1 : 0); } -READ8_MEMBER(tlcs870_device::tbtcr_r) +uint8_t tlcs870_device::tbtcr_r() { return m_TBTCR; } @@ -480,7 +479,7 @@ READ8_MEMBER(tlcs870_device::tbtcr_r) // TODO: use templates for SIO1/2 ports, as they're the same except for the DBR region they use? // Serial Port 1 -WRITE8_MEMBER(tlcs870_device::sio1cr1_w) +void tlcs870_device::sio1cr1_w(uint8_t data) { m_SIOCR1[0] = data; @@ -545,7 +544,7 @@ WRITE8_MEMBER(tlcs870_device::sio1cr1_w) } -WRITE8_MEMBER(tlcs870_device::sio1cr2_w) +void tlcs870_device::sio1cr2_w(uint8_t data) { m_SIOCR2[0] = data; @@ -564,7 +563,7 @@ WRITE8_MEMBER(tlcs870_device::sio1cr2_w) } -READ8_MEMBER(tlcs870_device::sio1sr_r) +uint8_t tlcs870_device::sio1sr_r() { /* TS-- ---- @@ -616,7 +615,7 @@ TIMER_CALLBACK_MEMBER(tlcs870_device::sio0_transmit_cb) } // Serial Port 2 -WRITE8_MEMBER(tlcs870_device::sio2cr1_w) +void tlcs870_device::sio2cr1_w(uint8_t data) { m_SIOCR1[1] = data; @@ -631,7 +630,7 @@ WRITE8_MEMBER(tlcs870_device::sio2cr1_w) LOG("%d: SCK2-0 (Serial Clock)\n", (m_SIOCR1[1] & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::sio2cr2_w) +void tlcs870_device::sio2cr2_w(uint8_t data) { m_SIOCR2[1] = data; @@ -650,7 +649,7 @@ TIMER_CALLBACK_MEMBER(tlcs870_device::sio1_transmit_cb) { } -READ8_MEMBER(tlcs870_device::sio2sr_r) +uint8_t tlcs870_device::sio2sr_r() { /* TS-- ---- @@ -663,7 +662,7 @@ READ8_MEMBER(tlcs870_device::sio2sr_r) // WDT emulation (Watchdog Timer) -WRITE8_MEMBER(tlcs870_device::wdtcr1_w) +void tlcs870_device::wdtcr1_w(uint8_t data) { m_WDTCR1 = data; @@ -680,7 +679,7 @@ WRITE8_MEMBER(tlcs870_device::wdtcr1_w) // WDTOUT cannot be set to 1 by software } -WRITE8_MEMBER(tlcs870_device::wdtcr2_w) +void tlcs870_device::wdtcr2_w(uint8_t data) { if (data == 0x4e) { @@ -699,7 +698,7 @@ WRITE8_MEMBER(tlcs870_device::wdtcr2_w) // Misc // not used by hng64 -WRITE8_MEMBER(tlcs870_device::syscr1_w) +void tlcs870_device::syscr1_w(uint8_t data) { m_SYSCR1 = data; @@ -714,7 +713,7 @@ WRITE8_MEMBER(tlcs870_device::syscr1_w) LOG("%d: (invalid)\n", (m_SYSCR1 & 0x01) ? 1 : 0); } -WRITE8_MEMBER(tlcs870_device::syscr2_w) +void tlcs870_device::syscr2_w(uint8_t data) { m_SYSCR2 = data; @@ -729,25 +728,25 @@ WRITE8_MEMBER(tlcs870_device::syscr2_w) LOG("%d: (invalid)\n", (m_SYSCR2 & 0x01) ? 1 : 0); } -READ8_MEMBER(tlcs870_device::syscr1_r) +uint8_t tlcs870_device::syscr1_r() { return m_SYSCR1; // low 2 bits are 'undefined' } -READ8_MEMBER(tlcs870_device::syscr2_r) +uint8_t tlcs870_device::syscr2_r() { return m_SYSCR2 | 0x0f; // low bits always read as 1 } // RBS / PSW direct access -WRITE8_MEMBER(tlcs870_device::rbs_w) +void tlcs870_device::rbs_w(uint8_t data) { // upper bits of PSW (status flags) cannot be written, only the register bank m_RBS = data & 0x0f; } -READ8_MEMBER(tlcs870_device::psw_r) +uint8_t tlcs870_device::psw_r() { // outside of checking the results of opcodes that use it directly (DAA / DAS) this is the only way to read / check the 'half' flag return get_PSW(); @@ -755,7 +754,7 @@ READ8_MEMBER(tlcs870_device::psw_r) // ADC emulation -READ8_MEMBER(tlcs870_device::adcdr_r) +uint8_t tlcs870_device::adcdr_r() { return m_ADCDR; } @@ -780,12 +779,12 @@ READ8_MEMBER(tlcs870_device::adcdr_r) */ -READ8_MEMBER(tlcs870_device::adccr_r) +uint8_t tlcs870_device::adccr_r() { return m_ADCCR | 0x80; // return with 'finished' bit set } -WRITE8_MEMBER(tlcs870_device::adccr_w) +void tlcs870_device::adccr_w(uint8_t data) { m_ADCCR = data; @@ -796,12 +795,12 @@ WRITE8_MEMBER(tlcs870_device::adccr_w) } -READ8_MEMBER(tlcs870_device::eintcr_r) +uint8_t tlcs870_device::eintcr_r() { return 0x00; } -WRITE8_MEMBER(tlcs870_device::eintcr_w) +void tlcs870_device::eintcr_w(uint8_t data) { m_EINTCR = data; @@ -822,17 +821,17 @@ WRITE8_MEMBER(tlcs870_device::eintcr_w) */ } -READ8_MEMBER(tlcs870_device::eir_l_r) +uint8_t tlcs870_device::eir_l_r() { return m_EIR & 0xff; } -READ8_MEMBER(tlcs870_device::eir_h_r) +uint8_t tlcs870_device::eir_h_r() { return (m_EIR >> 8) & 0xff; } -WRITE8_MEMBER(tlcs870_device::eir_l_w) +void tlcs870_device::eir_l_w(uint8_t data) { m_EIR = (m_EIR & 0xff00) | data; @@ -847,7 +846,7 @@ WRITE8_MEMBER(tlcs870_device::eir_l_w) LOG("%d: IMF\n", (m_EIR & 0x0001) ? 1 : 0); // can't be Reset interrupt (non-maskable) } -WRITE8_MEMBER(tlcs870_device::eir_h_w) +void tlcs870_device::eir_h_w(uint8_t data) { m_EIR = (m_EIR & 0x00ff) | (data << 8); @@ -869,23 +868,23 @@ WRITE8_MEMBER(tlcs870_device::eir_h_w) by writing 0 to it */ -READ8_MEMBER(tlcs870_device::il_l_r) +uint8_t tlcs870_device::il_l_r() { return m_IL & 0xff; } -READ8_MEMBER(tlcs870_device::il_h_r) +uint8_t tlcs870_device::il_h_r() { return (m_IL >> 8) & 0xff; } -WRITE8_MEMBER(tlcs870_device::il_l_w) +void tlcs870_device::il_l_w(uint8_t data) { // probably not this logic m_IL = (m_IL & 0xff00) | data; } -WRITE8_MEMBER(tlcs870_device::il_h_w) +void tlcs870_device::il_h_w(uint8_t data) { // probably not this logic m_IL = (m_EIR & 0x00ff) | (data << 8); @@ -1235,27 +1234,62 @@ void tlcs870_device::device_start() state_add(STATE_GENPC, "GENPC", m_pc.w.l).formatstr("%04X"); state_add(STATE_GENPCBASE, "CURPC", m_prvpc.w.l).formatstr("%04X").noshow(); - state_add(STATE_GENSP, "GENSP", m_sp.w.l).formatstr("%04X"); + state_add(DEBUGGER_REG_SP, "SP", m_sp.w.l).formatstr("%04X"); state_add(STATE_GENFLAGS, "GENFLAGS", m_F).formatstr("%8s").noshow(); set_icountptr(m_icount); - for (auto &cb : m_port_in_cb) - cb.resolve_safe(0xff); - for (auto &cb : m_port_out_cb) - cb.resolve_safe(); - for (auto &cb : m_port_analog_in_cb) - cb.resolve_safe(0xff); - for (auto &cb : m_serial_out_cb) - cb.resolve_safe(); - - m_serial_transmit_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::sio0_transmit_cb), this)); - m_serial_transmit_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::sio1_transmit_cb), this)); - - m_tcx_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::tc1_cb), this)); - m_tcx_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::tc2_cb), this)); - m_tcx_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::tc3_cb), this)); - m_tcx_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tlcs870_device::tc4_cb), this)); + m_serial_transmit_timer[0] = timer_alloc(FUNC(tlcs870_device::sio0_transmit_cb), this); + m_serial_transmit_timer[1] = timer_alloc(FUNC(tlcs870_device::sio1_transmit_cb), this); + + m_tcx_timer[0] = timer_alloc(FUNC(tlcs870_device::tc1_cb), this); + m_tcx_timer[1] = timer_alloc(FUNC(tlcs870_device::tc2_cb), this); + m_tcx_timer[2] = timer_alloc(FUNC(tlcs870_device::tc3_cb), this); + m_tcx_timer[3] = timer_alloc(FUNC(tlcs870_device::tc4_cb), this); + + save_item(NAME(m_prvpc)); + save_item(NAME(m_pc)); + save_item(NAME(m_sp)); + save_item(NAME(m_port_out_latch)); + save_item(NAME(m_read_input_port)); + save_item(NAME(m_port0_cr)); + save_item(NAME(m_port1_cr)); + save_item(NAME(m_port6_cr)); + save_item(NAME(m_port7_cr)); + save_item(NAME(m_cycles)); + save_item(NAME(m_tmppc)); + save_item(NAME(m_addr)); + save_item(NAME(m_F)); + save_item(NAME(m_RBS)); + save_item(NAME(m_IL)); + save_item(NAME(m_EIR)); + save_item(NAME(m_EINTCR)); + save_item(NAME(m_ADCCR)); + save_item(NAME(m_ADCDR)); + save_item(NAME(m_SYSCR1)); + save_item(NAME(m_SYSCR2)); + save_item(NAME(m_TBTCR)); + save_item(NAME(m_TREG1A)); + save_item(NAME(m_TREG1B)); + save_item(NAME(m_TC1CR)); + save_item(NAME(m_TREG2)); + save_item(NAME(m_TC2CR)); + save_item(NAME(m_TREG3A)); + save_item(NAME(m_TREG3B)); + save_item(NAME(m_TC3CR)); + save_item(NAME(m_TREG4)); + save_item(NAME(m_TC4CR)); + save_item(NAME(m_SIOCR1)); + save_item(NAME(m_SIOCR2)); + save_item(NAME(m_WDTCR1)); + save_item(NAME(m_irqstate)); + save_item(NAME(m_transfer_numbytes)); + save_item(NAME(m_transfer_pos)); + save_item(NAME(m_transfer_shiftreg)); + save_item(NAME(m_transfer_shiftpos)); + save_item(NAME(m_transfer_mode)); + save_item(NAME(m_transmit_bits)); + save_item(NAME(m_receive_bits)); } |