From 8b327ef7093d849a85818b433c833300afad18dd Mon Sep 17 00:00:00 2001 From: Luigi Thirty Date: Wed, 13 Apr 2022 10:25:08 -0500 Subject: 8x300 subcycle improvements (#9539) --- src/devices/cpu/8x300/8x300.cpp | 127 ++++++++++++++++++++++++++++++++-------- src/devices/cpu/8x300/8x300.h | 17 ++++-- 2 files changed, 115 insertions(+), 29 deletions(-) diff --git a/src/devices/cpu/8x300/8x300.cpp b/src/devices/cpu/8x300/8x300.cpp index 6a248517fec..c304999cfe4 100644 --- a/src/devices/cpu/8x300/8x300.cpp +++ b/src/devices/cpu/8x300/8x300.cpp @@ -46,6 +46,11 @@ n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, device_type , m_program_config("program", ENDIANNESS_BIG, 16, 13, -1) , m_io_config("io", ENDIANNESS_BIG, 8, 9, 0) , m_sc_callback(*this) + , m_wc_callback(*this) + , m_lb_callback(*this) + , m_rb_callback(*this) + , m_mclk_callback(*this) + , m_iv_callback(*this) { } @@ -67,15 +72,49 @@ device_memory_interface::space_config_vector n8x300_cpu_device::memory_space_con }; } -void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask) +void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc) { m_IV_latch = (m_IV_latch & ~mask) | (dst & mask); + + if(with_sc) + { + m_sc_callback(1); + m_wc_callback(0); + m_lb_callback(1); + m_iv_callback(m_IVL); + } + + if(with_wc) + { + m_sc_callback(0); + m_wc_callback(1); + m_lb_callback(1); + m_iv_callback(m_IV_latch); + } + WRITEPORT(m_IVL, m_IV_latch); } -void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask) +void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc) { m_IV_latch = (m_IV_latch & ~mask) | (dst & mask); + + if(with_sc) + { + m_sc_callback(1); + m_wc_callback(0); + m_rb_callback(1); + m_iv_callback(m_IVL); + } + + if(with_wc) + { + m_sc_callback(0); + m_wc_callback(1); + m_rb_callback(1); + m_iv_callback(m_IV_latch); + } + WRITEPORT(m_IVR + 0x100, m_IV_latch); } @@ -90,11 +129,11 @@ void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit) case 0x04: m_R4 = val; break; case 0x05: m_R5 = val; break; case 0x06: m_R6 = val; break; - case 0x07: m_IVL = val; m_sc_callback(0, val); break; + case 0x07: m_IVL = val; xmit_lb(val, 0xFF, true, false); break; // OVF is read-only case 0x09: m_R11 = val; break; - case 0x0f: m_IVR = val; m_sc_callback(1, val); break; - default: logerror("8X300: Invalid register %02x written to.\n",reg); break; + case 0x0f: m_IVR = val; xmit_rb(val, 0xFF, true, false); break; + default: logerror("8X300: Tried to write to invalid register %02x.\n",reg); break; } } @@ -102,8 +141,8 @@ void n8x305_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit) { switch (reg) { - case 0x0a: if (xmit) xmit_lb(val, 0xff); else m_R12 = val; break; - case 0x0b: if (xmit) xmit_rb(val, 0xff); else m_R13 = val; break; + case 0x0a: if (xmit) xmit_lb(val, 0xff, true, true); else m_R12 = val; break; + case 0x0b: if (xmit) xmit_rb(val, 0xff, true, true); else m_R13 = val; break; case 0x0c: m_R14 = val; break; case 0x0d: m_R15 = val; break; case 0x0e: m_R16 = val; break; @@ -148,6 +187,11 @@ uint8_t n8x305_cpu_device::get_reg(uint8_t reg) void n8x300_cpu_device::device_resolve_objects() { m_sc_callback.resolve_safe(); + m_wc_callback.resolve_safe(); + m_lb_callback.resolve_safe(); + m_rb_callback.resolve_safe(); + m_mclk_callback.resolve_safe(); + m_iv_callback.resolve_safe(); } void n8x300_cpu_device::device_start() @@ -270,6 +314,10 @@ void n8x300_cpu_device::device_reset() m_AR = 0; m_genPC = 0; m_increment_pc = true; + + m_lb_callback(0); + m_rb_callback(0); + m_mclk_callback(0); } void n8x300_cpu_device::execute_run() @@ -281,12 +329,21 @@ void n8x300_cpu_device::execute_run() uint8_t dst; uint8_t rotlen; // rotate amount or I/O field length uint8_t mask; + bool with_sc; + bool with_wc; /* fetch the opcode */ m_genPC = m_AR; debugger_instruction_hook(m_genPC); opcode = FETCHOP(m_genPC); + /* reset I/O lines for this instruction */ + m_lb_callback(0); + m_rb_callback(0); + m_sc_callback(0); + m_wc_callback(0); + m_mclk_callback(0); + if (m_increment_pc) { m_PC++; @@ -321,9 +378,9 @@ void n8x300_cpu_device::execute_run() src = (get_reg(SRC)) << (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) - xmit_rb(src, mask); + xmit_rb(src, mask, false, true); else - xmit_lb(src, mask); + xmit_lb(src, mask, false, true); } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // MOVE IV,reg @@ -342,9 +399,9 @@ void n8x300_cpu_device::execute_run() dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } } break; @@ -372,9 +429,9 @@ void n8x300_cpu_device::execute_run() mask <<= DST_LSB; SET_OVF; if(DST_IS_RIGHT_BANK) - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // ADD IV,reg @@ -395,9 +452,9 @@ void n8x300_cpu_device::execute_run() dst = (result << (7-DST_LSB)) & 0xff; mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } } break; @@ -423,9 +480,9 @@ void n8x300_cpu_device::execute_run() dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // AND IV,reg @@ -444,9 +501,9 @@ void n8x300_cpu_device::execute_run() dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } } break; @@ -471,9 +528,9 @@ void n8x300_cpu_device::execute_run() dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // XOR IV,reg @@ -492,9 +549,9 @@ void n8x300_cpu_device::execute_run() dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) - xmit_rb(dst, mask); + xmit_rb(dst, mask, false, true); else - xmit_lb(dst, mask); + xmit_lb(dst, mask, false, true); } } break; @@ -552,16 +609,36 @@ void n8x300_cpu_device::execute_run() dst = IMM5; mask <<= (7-SRC_LSB); dst <<= (7-SRC_LSB); + + if(opcode & 0xA00 || opcode & 0xB00) + { + // Imm -> IV Data + with_sc = false; + with_wc = true; + } + else + { + // Imm -> IV Address + with_sc = false; + with_wc = true; + } + if(SRC_IS_RIGHT_BANK) - xmit_rb(dst, mask); + { + xmit_rb(dst, mask, with_sc, with_wc); + } else - xmit_lb(dst, mask); + { + xmit_lb(dst, mask, with_sc, with_wc); + } + } break; case 0x07: // JMP SET_PC(ADDR); break; } + m_mclk_callback(1); CYCLES(1); // all instructions take 1 cycle (250ns) } while (m_icount > 0); } diff --git a/src/devices/cpu/8x300/8x300.h b/src/devices/cpu/8x300/8x300.h index 0c95ddc2002..86db8854478 100644 --- a/src/devices/cpu/8x300/8x300.h +++ b/src/devices/cpu/8x300/8x300.h @@ -46,7 +46,11 @@ public: n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); auto sc_callback() { return m_sc_callback.bind(); } - + auto wc_callback() { return m_wc_callback.bind(); } + auto mclk_callback() { return m_mclk_callback.bind(); } + auto lb_callback() { return m_lb_callback.bind(); } + auto rb_callback() { return m_rb_callback.bind(); } + auto iv_callback() { return m_iv_callback.bind(); } protected: n8x300_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -73,8 +77,8 @@ protected: virtual void set_reg(uint8_t reg, uint8_t val, bool xmit); virtual uint8_t get_reg(uint8_t reg); - void xmit_lb(uint8_t dst, uint8_t mask); - void xmit_rb(uint8_t dst, uint8_t mask); + void xmit_lb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc); + void xmit_rb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc); address_space_config m_program_config; address_space_config m_io_config; @@ -86,7 +90,12 @@ protected: memory_access<13, 1, -1, ENDIANNESS_BIG>::specific m_program; memory_access< 9, 0, 0, ENDIANNESS_BIG>::specific m_io; - devcb_write8 m_sc_callback; // Select Command (address latch) + devcb_write_line m_sc_callback; // address latch + devcb_write_line m_wc_callback; // data latch + devcb_write_line m_lb_callback; + devcb_write_line m_rb_callback; + devcb_write_line m_mclk_callback; + devcb_write8 m_iv_callback; uint16_t m_PC; // Program Counter uint16_t m_AR; // Address Register -- cgit v1.2.3