From 319cb98eab3591c402977f8ef76291af7e3bf629 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Sun, 5 Jan 2020 18:13:31 +0000 Subject: sunplus_gcm394 (jak_car2 / jak_gtg / unsp20 etc.) current notes / refactoring etc. (nw) (#6134) * refactor extended register use (nw) * continued refactor (nw) * some refactor (nw) * simplify some logic (nw) * (nw) * (nw) * (nw) * finish pushing extended opcodes through common codepaths (nw) * note improvements (nw) * bg pen notes (nw) * some renames etc. (nw) * some renames, notes on other register use etc. (nw) --- src/devices/cpu/unsp/unsp.cpp | 37 +- src/devices/cpu/unsp/unsp.h | 5 +- src/devices/cpu/unsp/unsp_extended.cpp | 1236 +++----------------------- src/devices/cpu/unsp/unsp_other.cpp | 52 +- src/devices/machine/sunplus_gcm394.cpp | 206 ++++- src/devices/machine/sunplus_gcm394.h | 34 +- src/devices/machine/sunplus_gcm394_video.cpp | 15 +- src/mame/drivers/sunplus_gcm394.cpp | 24 +- 8 files changed, 380 insertions(+), 1229 deletions(-) diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp index 87a95bd900f..a3e783dd6c9 100644 --- a/src/devices/cpu/unsp/unsp.cpp +++ b/src/devices/cpu/unsp/unsp.cpp @@ -60,24 +60,28 @@ unsp_device::unsp_device(const machine_config &mconfig, device_type type, const , m_enable_drc(false) { m_iso = 10; + m_numregs = 8; } unsp_device::unsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : unsp_device(mconfig, UNSP, tag, owner, clock, address_map_constructor()) { m_iso = 10; + m_numregs = 8; } unsp_11_device::unsp_11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : unsp_device(mconfig, UNSP_11, tag, owner, clock, address_map_constructor()) { m_iso = 11; + m_numregs = 8; } unsp_11_device::unsp_11_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal) : unsp_device(mconfig, type, tag, owner, clock, internal) { m_iso = 11; + m_numregs = 8; } @@ -85,24 +89,28 @@ unsp_12_device::unsp_12_device(const machine_config &mconfig, const char *tag, d : unsp_11_device(mconfig, UNSP_12, tag, owner, clock, address_map_constructor()) { m_iso = 12; + m_numregs = 8; } unsp_12_device::unsp_12_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal) : unsp_11_device(mconfig, type, tag, owner, clock, internal) { m_iso = 12; + m_numregs = 8; } unsp_20_device::unsp_20_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : unsp_12_device(mconfig, UNSP_20, tag, owner, clock, address_map_constructor()) { m_iso = 20; + m_numregs = 16; } unsp_20_device::unsp_20_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal) : unsp_12_device(mconfig, type, tag, owner, clock, internal) { m_iso = 20; + m_numregs = 16; } unsp_device::~unsp_device() @@ -182,9 +190,12 @@ void unsp_device::unimplemented_opcode(uint16_t op, uint16_t ximm, uint16_t ximm void unsp_device::device_start() { + m_core = (internal_unsp_state *)m_cache.alloc_near(sizeof(internal_unsp_state)); memset(m_core, 0, sizeof(internal_unsp_state)); + m_core->m_r.resize(m_numregs); + #if ENABLE_UNSP_DRC m_enable_drc = allow_drc() && (m_iso < 12); #else @@ -275,21 +286,20 @@ void unsp_20_device::device_start() int baseindex = UNSP_SB + 1; #endif - state_add(baseindex + UNSP20_R8, "R8", m_secondary_r[UNSP20_R8]).formatstr("%04X"); - state_add(baseindex + UNSP20_R9, "R9", m_secondary_r[UNSP20_R9]).formatstr("%04X"); - state_add(baseindex + UNSP20_R10, "R10", m_secondary_r[UNSP20_R10]).formatstr("%04X"); - state_add(baseindex + UNSP20_R11, "R11", m_secondary_r[UNSP20_R11]).formatstr("%04X"); - state_add(baseindex + UNSP20_R12, "R12", m_secondary_r[UNSP20_R12]).formatstr("%04X"); - state_add(baseindex + UNSP20_R13, "R13", m_secondary_r[UNSP20_R13]).formatstr("%04X"); - state_add(baseindex + UNSP20_R14, "R14", m_secondary_r[UNSP20_R14]).formatstr("%04X"); - state_add(baseindex + UNSP20_R15, "R15", m_secondary_r[UNSP20_R15]).formatstr("%04X"); - - save_item(NAME(m_secondary_r)); + state_add(baseindex + UNSP20_R8, "R8", m_core->m_r[UNSP20_R8+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R9, "R9", m_core->m_r[UNSP20_R9+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R10, "R10", m_core->m_r[UNSP20_R10+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R11, "R11", m_core->m_r[UNSP20_R11+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R12, "R12", m_core->m_r[UNSP20_R12+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R13, "R13", m_core->m_r[UNSP20_R13+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R14, "R14", m_core->m_r[UNSP20_R14+8]).formatstr("%04X"); + state_add(baseindex + UNSP20_R15, "R15", m_core->m_r[UNSP20_R15+8]).formatstr("%04X"); } void unsp_device::device_reset() { - memset(m_core->m_r, 0, sizeof(uint32_t) * 8); + for (int i = 0; i < m_numregs; i++) + m_core->m_r[i] = 0; m_core->m_r[REG_PC] = read16(0xfff7); m_core->m_enable_irq = 0; @@ -301,11 +311,6 @@ void unsp_device::device_reset() void unsp_20_device::device_reset() { unsp_12_device::device_reset(); - - for (int i = 0; i < 8; i++) - { - m_secondary_r[i] = 0; - } } void unsp_device::device_stop() diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h index 507d731ffff..691859c6e5f 100644 --- a/src/devices/cpu/unsp/unsp.h +++ b/src/devices/cpu/unsp/unsp.h @@ -164,7 +164,7 @@ protected: struct internal_unsp_state { - uint32_t m_r[8]; // why are these 32-bit? they're 16-bit regs? (changing to uint16_t causes crashes tho, so something is depending on this) + std::vector m_r; // why are these 32-bit? they're 16-bit regs? (changing to uint16_t causes crashes tho, so something is depending on this) uint32_t m_enable_irq; uint32_t m_enable_fiq; uint32_t m_irq; @@ -232,6 +232,7 @@ protected: void update_nz(uint32_t value); void update_nzsc(uint32_t value, uint16_t r0, uint16_t r1); + bool do_basic_alu_ops(const uint16_t& op0, uint32_t& lres, uint16_t& r0, uint16_t& r1, uint32_t& r2, bool update_flags); private: // compilation boundaries -- how far back/forward does the analysis extend? @@ -320,6 +321,8 @@ private: #if UNSP_LOG_REGS FILE *m_log_file; #endif +protected: + int m_numregs; }; diff --git a/src/devices/cpu/unsp/unsp_extended.cpp b/src/devices/cpu/unsp/unsp_extended.cpp index 114424c098c..df5711e8b7b 100644 --- a/src/devices/cpu/unsp/unsp_extended.cpp +++ b/src/devices/cpu/unsp/unsp_extended.cpp @@ -9,6 +9,10 @@ #include "unspdasm.h" +// TODO: the call conventions and general use of 'do_basic_alu_ops' from unsp_other.cpp could be cleaned up +// at the moment things like the 'Store' opcode make things more complex than they need to be, and require +// the passing of a store address each time, they make the regular use of the code a little awkward too tho. + void unsp_device::execute_extended_group(uint16_t op) { // shouldn't get here anyway @@ -26,181 +30,27 @@ void unsp_20_device::execute_extended_group(uint16_t op) { case 0x00: case 0x10: { - // Ext Register Ra = Ra op Rb + // Ext Register + // Ra = Ra op Rb + // A = B op C uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - switch (aluop) - { - case 0x00: // add - { - // A += B - //logerror( "(Extended group 0) %s += %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - m_core->m_icount -= 1; // TODO - - uint16_t r0 = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; - uint16_t r1 = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; - - uint32_t lres = r0 + r1; - - update_nzsc(lres, r0, r1); - - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } - - //unimplemented_opcode(op, ximm); - return; - break; - } - - case 0x01: // adc - // A += B, Carry - logerror( "(Extended group 0) %s += %s, carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x02: // sub - // A -= B - logerror( "(Extended group 0) %s -= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x03: // sbc - // A -= B, Carry - logerror( "(Extended group 0) %s -= %s, carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - { - // CMP A,B - //logerror( "(Extended group 0) cmp %s, %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - m_core->m_icount -= 1; // TODO - - uint16_t r0 = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; - uint16_t r1 = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; - - uint32_t lres = r0 + (uint16_t)(~r1) + uint32_t(1); - update_nzsc(lres, r0 , ~r1); + uint16_t b = m_core->m_r[ra]; + uint16_t c = m_core->m_r[rb]; + uint32_t lres; + uint32_t storeaddr = b; // dest address for STORE - //unimplemented_opcode(op, ximm); - return; - break; - } - - case 0x06: // neg - // A = -B - logerror( "(Extended group 0) %s = -%s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x08: // xor - // A ^= B - logerror( "(Extended group 0) %s ^= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x09: // load - { - // A = B - //logerror("(Extended group 0) %s = %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - m_core->m_icount -= 1; // TODO - - uint32_t lres = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; - update_nz(lres); - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, (ra != 7)); - return; - break; - } - case 0x0a: // or + if (write) { - // A |= B - //logerror("(Extended group 0) %s |= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - uint16_t a = (ra & 0x8) ? m_secondary_r[ra & 0x7] : m_core->m_r[ra & 0x7]; - uint16_t b = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; - - uint32_t lres = a | b; - - update_nz(lres); - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } - - //unimplemented_opcode(op, ximm); - return; - break; - } - case 0x0b: // and - // A &= B - logerror( "(Extended group 0) %s &= %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 0) test %s, %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0d: // store - // B = A - logerror( "(Extended group 0) %s = %s\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 0) \n"); - unimplemented_opcode(op, ximm); - return; - break; + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; } - - unimplemented_opcode(op, ximm); return; } case 0x02: @@ -210,8 +60,6 @@ void unsp_20_device::execute_extended_group(uint16_t op) // Ext Push/Pop if (ximm & 0x8000) { - // just skip for now, as nothing really even uses the extended registers yet - uint8_t rb = (ximm & 0x000f) >> 0; uint8_t size = (ximm & 0x7000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; @@ -225,10 +73,7 @@ void unsp_20_device::execute_extended_group(uint16_t op) while (size--) { - if (rb & 0x8) - push(m_secondary_r[rx--], &m_secondary_r[rb & 0x7]); - else - push(m_secondary_r[rx--], &m_core->m_r[rb & 0x7]); + push(m_core->m_r[(rx--) + 8], &m_core->m_r[rb]); } } else @@ -257,9 +102,9 @@ void unsp_20_device::execute_extended_group(uint16_t op) while (size--) { if (rb & 0x8) - m_secondary_r[realrx++] = pop(&m_secondary_r[rb & 0x07]); + m_core->m_r[(realrx++) + 8] = pop(&m_core->m_r[(rb & 0x07) + 8]); else - m_secondary_r[realrx++] = pop(&m_core->m_r[rb & 0x07]); + m_core->m_r[(realrx++) + 8] = pop(&m_core->m_r[rb & 0x07]); } } else @@ -278,148 +123,33 @@ void unsp_20_device::execute_extended_group(uint16_t op) uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); - // Ra=Rb op IMM16 + // Ra = Rb op IMM16 + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - switch (aluop) - { - case 0x00: // add - // A = B + C - logerror( "(Extended group 1) %s = %s + %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x01: // adc - // A = B + C, Carry - logerror( "(Extended group 1) %s = %s + %04x, carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x02: // sub - // A = B - C - logerror( "(Extended group 1) %s = %s - %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x03: // sbc - // A = B - C, Carry - logerror( "(Extended group 1) %s = %s - %04x, carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x04: // cmp - // CMP B,C - logerror( "(Extended group 1) cmp %s, %04x\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x06: // neg - // A = -C - logerror( "(Extended group 1) %s = -%04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x08: // xor - // A = B ^ C - logerror( "(Extended group 1) %s = %s ^ %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + uint16_t b = m_core->m_r[rb]; + uint32_t lres; + uint32_t storeaddr = 0;// m_core->m_r[ra]; // dest address for STORE (invalid anyway?) - case 0x09: // load + if (aluop == 0xd) { - // A = C - //logerror("(Extended group 1) %s = %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , imm16_2); - m_core->m_icount -= 1; // TODO - - uint32_t lres = imm16_2; - update_nz(lres); - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } - - return; - break; - } - case 0x0a: // or - // A = B | C - logerror( "(Extended group 1) %s = %s | %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); + // store is invalid? unimplemented_opcode(op, ximm, imm16_2); - return; - break; + } - case 0x0b: // and - { - // A = B & C - //logerror("(Extended group 1) %s = %s & %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - // , imm16_2); - - uint16_t b = (rb & 0x8) ? m_secondary_r[rb & 0x7] : m_core->m_r[rb & 0x7]; - uint32_t lres = b & imm16_2; - update_nz(lres); - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } + bool write = do_basic_alu_ops(aluop, lres, b, imm16_2, storeaddr, (ra != 7)); - return; - break; - } - case 0x0c: // test - // TEST B,C - logerror( "(Extended group 1) test %s, %04x\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0d: // store, C = B, invalid for this mode (would store to immediate) - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 1) \n"); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + if (write) + { + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; } - unimplemented_opcode(op, ximm, imm16_2); return; } @@ -429,925 +159,165 @@ void unsp_20_device::execute_extended_group(uint16_t op) uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); - // Ra=Rb op [A16] + // Ra = Rb op [A16] + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - switch (aluop) - { - case 0x00: // add - // A = B + C - logerror( "(Extended group 2) %s = %s + [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x01: // adc - // A = B + C, Carry - logerror( "(Extended group 2) %s = %s + [%04x], carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x02: // sub - // A = B - C - logerror( "(Extended group 2) %s = %s - [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x03: // sbc - // A = B - C, Carry - logerror( "(Extended group 2) %s = %s - [%04x], carry\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x04: // cmp - // CMP B,C - logerror( "(Extended group 2) cmp %s, [%04x]\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + uint16_t b = m_core->m_r[rb]; + uint16_t c = read16(imm16_2); + uint32_t storeaddr = imm16_2; // dest address for STORE + uint32_t lres; - case 0x06: // neg - // A = -C - logerror( "(Extended group 2) %s = -[%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x08: // xor - // A = B ^ C - logerror( "(Extended group 2) %s = %s ^ [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, (ra != 7)); - case 0x09: // load + if (write) { - // A = C - //logerror("(Extended group 2) %s = [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - // , imm16_2); - //unimplemented_opcode(op, ximm, imm16_2); - - m_core->m_icount -= 1; // TODO - - //uin32_t lreg = UNSP_LREG_I(imm16_2); - - uint32_t lres = read16(imm16_2); - update_nz(lres); - if (ra & 0x8) - { - m_secondary_r[ra & 0x7] = (uint16_t)lres; - } - else - { - m_core->m_r[ra & 0x7] = (uint16_t)lres; - } - - return; - break; - } - - case 0x0a: // or - // A = B | C - logerror( "(Extended group 2) %s = %s | [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0b: // and - // A = B & C - logerror( "(Extended group 2) %s = %s & [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0c: // test - // TEST B,C - logerror( "(Extended group 2) test %s, [%04x]\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , imm16_2); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0d: // store - // C = B - logerror( "(Extended group 2) [%04x] = %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 2) \n"); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; } - unimplemented_opcode(op, ximm, imm16_2); return; } case 0x07: case 0x17: { + // this decoding / hookup might be incorrect, only seen Store used, and that the decode seems strange for that + uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); //[A16] = Ra op Rb + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - switch (aluop) - { - case 0x00: // add - // A = B + C - logerror( "(Extended group 3) [%04x] = %s + %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x01: // adc - // A = B + C, Carry - logerror( "(Extended group 3) [%04x] = %s + %s, carry\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x02: // sub - // A = B - C - logerror( "(Extended group 3) [%04x] = %s - %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x03: // sbc - // A = B - C, Carry - logerror( "(Extended group 3) [%04x] = %s - %s, carry\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x04: // cmp (is this even a valid form? [A16] not even used) - // CMP B,C - logerror( "(Extended group 3) cmp %s, %s\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x06: // neg - // A = -C - logerror( "(Extended group 3) [%04x] = -%s\n", imm16_2 - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x08: // xor - // A = B ^ C - logerror( "(Extended group 3) [%04x] = %s ^ %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x09: // load - // A = C - logerror( "(Extended group 3) [%04x] = %s\n", imm16_2 - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0a: // or - // A = B | C - logerror( "(Extended group 3) [%04x] = %s | %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - - case 0x0b: // and - // A = B & C - logerror( "(Extended group 3) [%04x] = %s & %s\n", imm16_2 - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + uint16_t a = imm16_2; + uint16_t b = m_core->m_r[ra]; + uint16_t c = m_core->m_r[rb]; + uint32_t lres; + uint32_t r2 = a; - case 0x0c: // test (is this even a valid form? [A16] not even used) - // TEST B,C - logerror( "(Extended group 3) test %s, %s\n", (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7]); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; + bool write = do_basic_alu_ops(aluop, lres, b, c, r2, true); - case 0x0d: // store (is this even a valid form? [A16] not even used if C = B form below is used, code needs to write to A) + if (write) { - // C = B - //logerror( "(Extended group 3) [%04x] = %s\n", imm16_2 - // , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - m_core->m_icount -= 1; // TODO - - if (ra != rb) - { - logerror("(Extended group 3) store ra != rb"); - unimplemented_opcode(op, ximm, imm16_2); - } - - if (rb & 0x8) - { - write16(imm16_2, m_secondary_r[rb & 0x07]); - } - else - { - write16(imm16_2, m_core->m_r[rb & 0x07]); - } - - return; - break; + // a = [A16] + write16(imm16_2, lres); } - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 3) \n"); - unimplemented_opcode(op, ximm, imm16_2); - return; - break; - } - - unimplemented_opcode(op, ximm, imm16_2); return; } case 0x08: case 0x09: { - // Ext Indirect Rx=Rx op [Ry@] - uint8_t aluop = (ximm & 0xf000) >> 12; - uint8_t ry = (ximm & 0x0007) >> 0; - uint8_t form = (ximm & 0x0018) >> 3; - uint8_t rx = (ximm & 0x0e00) >> 9; - - switch (aluop) - { - case 0x00: // add - // A += B - logerror( "(Extended group 4) %s += ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x01: // adc - // A += B, Carry - logerror( "(Extended group 4) %s += ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror( ", carry"); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x02: // sub - // A -= B - logerror( "(Extended group 4) %s -= ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x03: // sbc - // A -= B, Carry - logerror( "(Extended group 4) %s -= ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror( ", carry"); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - // CMP A,B - logerror( "(Extended group 4) cmp %s, ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x06: // neg - // A = -B - logerror( "(Extended group 4) %s = -", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x08: // xor - // A ^= B - logerror( "(Extended group 4) %s ^= ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; + // Ext Indirect + // Rx = Rx op [Ry@] + // A = B op C - case 0x09: // load - // A = B - logerror( "(Extended group 4) %s = ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0a: // or - // A |= B - logerror( "(Extended group 4) %s |= ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0b: // and - // A &= B - logerror( "(Extended group 4) %s &= ", extregs[rx]); - logerror( forms[form], extregs[ry]); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 4) test %s, ", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0d: // store - // B = A - logerror( "(Extended group 4) "); - logerror( forms[form], extregs[ry]); - logerror( " = %s", extregs[rx]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 4) \n"); - unimplemented_opcode(op, ximm); - return; - break; - } + //uint8_t aluop = (ximm & 0xf000) >> 12; + //uint8_t ry = (ximm & 0x0007) >> 0; + //uint8_t form = (ximm & 0x0018) >> 3; + //uint8_t rx = (ximm & 0x0e00) >> 9; + logerror("(Extended group 4 'Rx=Rx op [Ry@]' form) unimplemented "); unimplemented_opcode(op, ximm); return; } case 0x0a: case 0x0b: { // Ext DS_Indirect Rx=Rx op ds:[Ry@] - uint8_t aluop = (ximm & 0xf000) >> 12; - uint8_t ry = (ximm & 0x0007) >> 0; - uint8_t form = (ximm & 0x0018) >> 3; - uint8_t rx = (ximm & 0x0e00) >> 9; - - switch (aluop) - { - case 0x00: // add - // A += B - logerror( "(Extended group 5) %s += ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x01: // adc - // A += B, Carry - logerror( "(Extended group 5) %s += ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror( ", carry"); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x02: // sub - // A -= B - logerror( "(Extended group 5) %s -= ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x03: // sbc - // A -= B, Carry - logerror( "(Extended group 5) %s -= ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror( ", carry"); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - // CMP A,B - logerror( "(Extended group 5) cmp %s, ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x06: // neg - // A = -B - logerror( "(Extended group 5) %s = -ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x08: // xor - // A ^= B - logerror( "(Extended group 5) %s ^= ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - case 0x09: // load - // A = B - logerror( "(Extended group 5) %s = ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0a: // or - // A |= B - logerror( "(Extended group 5) %s |= ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0b: // and - // A &= B - logerror( "(Extended group 5) %s &= ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 5) test %s, ds:", extregs[rx]); - logerror( forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0d: // store - // B = A - logerror( "(Extended group 5) ds:"); - logerror( forms[form], extregs[ry]); - logerror( " = %s", extregs[rx]); - logerror("\n"); - unimplemented_opcode(op, ximm); - return; - break; + //uint8_t aluop = (ximm & 0xf000) >> 12; + //uint8_t ry = (ximm & 0x0007) >> 0; + //uint8_t form = (ximm & 0x0018) >> 3; + //uint8_t rx = (ximm & 0x0e00) >> 9; - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 5) \n"); - unimplemented_opcode(op, ximm); - return; - break; - } + logerror("(Extended group 5 'Rx=Rx op ds:[Ry@]' form) unimplemented "); unimplemented_opcode(op, ximm); return; } case 0x18: case 0x19: case 0x1a: case 0x1b: { - // Ext IM6 Rx=Rx op IM6 + // Ext IM6 + // Rx = Rx op IM6 + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; uint8_t imm6 = (ximm & 0x003f) >> 0; - switch (aluop) - { - case 0x00: // add - // A += B - logerror("(Extended group 6) %s += %02x\n", extregs[rx], imm6); - unimplemented_opcode(op, ximm); - return; - break; + uint16_t b = m_core->m_r[rx + 8]; + uint16_t c = imm6; - case 0x01: // adc - // A += B, Carry - logerror("(Extended group 6) %s += %02x, carry\n", extregs[rx], imm6); - unimplemented_opcode(op, ximm); - return; - break; + uint32_t storeaddr = 0; // dest address for STORE + uint32_t lres; - case 0x02: // sub + if (aluop == 0xd) { - // A -= B - //logerror("(Extended group 6) %s -= %02x\n", extregs[rx], imm6); - m_core->m_icount -= 1; // TODO - - uint32_t lres = m_secondary_r[rx] + (uint16_t)(~imm6) + uint32_t(1); - update_nzsc(lres, m_secondary_r[rx], ~imm6); - m_secondary_r[rx] = (uint16_t)lres; - - return; - break; - } - case 0x03: // sbc - // A -= B, Carry - logerror("(Extended group 6) %s -= %02x, carry\n", extregs[rx], imm6); + // store is invalid? unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - { - // CMP A,B - //logerror("(Extended group 6) cmp %s, %02x\n", extregs[rx], imm6); - - m_core->m_icount -= 1; // TODO - - uint32_t lres = m_secondary_r[rx] + (uint16_t)(~imm6) + uint32_t(1); - update_nzsc(lres, m_secondary_r[rx] , ~imm6); - - //unimplemented_opcode(op, ximm); - return; - break; } - case 0x06: // neg - // A = -B - logerror( "(Extended group 6) %s = -%02x\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - case 0x08: // xor - // A ^= B - logerror( "(Extended group 6) %s ^= %02x\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, true); - case 0x09: // load + if (write) { - // A = B - //logerror( "(Extended group 6) %s = %02x\n", extregs[rx], imm6 ); - - m_core->m_icount -= 1; // TODO - - uint32_t lres = imm6; - update_nz(lres); - m_secondary_r[rx] = (uint16_t)lres; - - return; - break; - } - - case 0x0a: // or - // A |= B - logerror( "(Extended group 6) %s |= %02x\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0b: // and - // A &= B - logerror( "(Extended group 6) %s &= %02x\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 6) test %s, %02x\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0d: // store, B = A (invalid for this type) - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 6) \n"); - unimplemented_opcode(op, ximm); - return; - break; + // A = Rx + m_core->m_r[rx + 8] = (uint16_t)lres; } - unimplemented_opcode(op, ximm); return; } case 0x0c: case 0x0d: case 0x0e: case 0x0f: { - // Ext Base+Disp6 Rx=Rx op [BP+IM6] + // Ext Base+Disp6 + // Rx = Rx op [BP+IM6] + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; uint8_t imm6 = (ximm & 0x003f) >> 0; - switch (aluop) - { - case 0x00: // add - { - // A += B - // logerror( "(Extended group 7) %s += [BP+%02x]\n", extregs[rx], imm6 ); - m_core->m_icount -= 1; // TODO - - uint16_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); - uint16_t r0 = m_secondary_r[rx]; - uint16_t r1 = read16(addr); + uint32_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); - uint32_t lres = r0 + r1; + uint16_t b = m_core->m_r[rx + 8]; + uint16_t c = read16(addr); - update_nzsc(lres, r0, r1); + uint32_t storeaddr = addr; // dest address for STORE + uint32_t lres; - m_secondary_r[rx] = lres; + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, true); - //unimplemented_opcode(op, ximm); - return; - break; - } - case 0x01: // adc + if (write) { - // A += B, Carry - //logerror( "(Extended group 7) %s += [BP+%02x], carry\n", extregs[rx], imm6 ); - m_core->m_icount -= 1; // TODO - - uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0; - uint16_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); - uint16_t r0 = m_secondary_r[rx]; - uint16_t r1 = read16(addr); - - uint32_t lres = r0 + r1 + c; - - update_nzsc(lres, r0, r1); - - m_secondary_r[rx] = lres; - - //unimplemented_opcode(op, ximm); - return; - break; - } - - case 0x02: // sub - // A -= B - logerror( "(Extended group 7) %s -= [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x03: // sbc - // A -= B, Carry - logerror( "(Extended group 7) %s -= [BP+%02x], carry\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - // CMP A,B - logerror( "(Extended group 7) cmp %s, [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x06: // neg - // A = -B - logerror( "(Extended group 7) %s = -[BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x08: // xor - // A ^= B - logerror( "(Extended group 7) %s ^= [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x09: // load - // A = B - logerror( "(Extended group 7) %s = [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0a: // or - // A |= B - logerror( "(Extended group 7) %s |= [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0b: // and - // A &= B - logerror( "(Extended group 7) %s &= [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 7) test %s, [BP+%02x]\n", extregs[rx], imm6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0d: // store - // B = A - logerror( "(Extended group 7) [BP+%02x] = %s\n", imm6, extregs[rx] ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 7) \n"); - unimplemented_opcode(op, ximm); - return; - break; + // A = Rx + m_core->m_r[rx + 8] = (uint16_t)lres; } - unimplemented_opcode(op, ximm); return; } case 0x1c: case 0x1d: case 0x1e: case 0x1f: { - // Ext A6 Rx=Rx op [A6] - uint8_t aluop = (ximm & 0xf000) >> 12; - uint8_t rx = (ximm & 0x0e00) >> 9; - uint8_t a6 = (ximm & 0x003f) >> 0; - - switch (aluop) - { - case 0x00: // add - // A += B - logerror( "(Extended group 8) %s += [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x01: // adc - // A += B, Carry - logerror( "(Extended group 8) %s += [%02x], carry\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x02: // sub - // A -= B - logerror( "(Extended group 8) %s -= [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x03: // sbc - // A -= B, Carry - logerror( "(Extended group 8) %s -= [%02x], carry\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x04: // cmp - // CMP A,B - logerror( "(Extended group 8) cmp %s, [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x06: // neg - // A = -B - logerror( "(Extended group 8) %s = -[%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x08: // xor - // A ^= B - logerror( "(Extended group 8) %s ^= [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x09: // load - // A = B - logerror( "(Extended group 8) %s = [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0a: // or - // A |= B - logerror( "(Extended group 8) %s |= [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0b: // and - // A &= B - logerror( "(Extended group 8) %s &= [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x0c: // test - // TEST A,B - logerror( "(Extended group 8) test %s, [%02x]\n", extregs[rx], a6 ); - unimplemented_opcode(op, ximm); - return; - break; + // Ext A6 + // Rx = Rx op [A6] + // A = B op C - case 0x0d: // store - // B = A - logerror( "(Extended group 8) [%02x] = %s\n", a6, extregs[rx] ); - unimplemented_opcode(op, ximm); - return; - break; - - case 0x05: // invalid - case 0x07: // invalid - case 0x0e: // invalid - case 0x0f: // invalid - logerror( "(Extended group 8) \n"); - unimplemented_opcode(op, ximm); - return; - break; - } + //uint8_t aluop = (ximm & 0xf000) >> 12; + //uint8_t rx = (ximm & 0x0e00) >> 9; + //uint8_t a6 = (ximm & 0x003f) >> 0; + logerror("(Extended group 8 'Rx=Rx op [A6]' form) unimplemented "); unimplemented_opcode(op, ximm); return; diff --git a/src/devices/cpu/unsp/unsp_other.cpp b/src/devices/cpu/unsp/unsp_other.cpp index 9e9fb984cb4..2300f2a5bc0 100644 --- a/src/devices/cpu/unsp/unsp_other.cpp +++ b/src/devices/cpu/unsp/unsp_other.cpp @@ -204,6 +204,7 @@ void unsp_device::execute_remaining(const uint16_t op) r0 = m_core->m_r[opb]; r2 = read16(UNSP_LPC); add_lpc(1); + // additional special case 'if (op1 == 0x04 && opn == 0x03)' write logic below break; default: // Shifted ops @@ -266,12 +267,26 @@ void unsp_device::execute_remaining(const uint16_t op) break; } + bool write = do_basic_alu_ops(op0, lres, r0, r1, r2, (opa != 7) ? true : false); + + if (write) + { + if (op1 == 0x04 && opn == 0x03) // store [imm16], r + write16(r2, lres); + else + m_core->m_r[opa] = (uint16_t)lres; + } +} + + +bool unsp_device::do_basic_alu_ops(const uint16_t &op0, uint32_t &lres, uint16_t &r0, uint16_t &r1, uint32_t &r2, bool update_flags) +{ switch (op0) { case 0x00: // Add { lres = r0 + r1; - if (opa != 7) + if (update_flags) update_nzsc(lres, r0, r1); break; } @@ -279,69 +294,66 @@ void unsp_device::execute_remaining(const uint16_t op) { uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0; lres = r0 + r1 + c; - if (opa != 7) + if (update_flags) update_nzsc(lres, r0, r1); break; } case 0x02: // Subtract lres = r0 + (uint16_t)(~r1) + uint32_t(1); - if (opa != 7) + if (update_flags) update_nzsc(lres, r0, ~r1); break; case 0x03: // Subtract w/ carry { uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0; lres = r0 + (uint16_t)(~r1) + c; - if (opa != 7) + if (update_flags) update_nzsc(lres, r0, ~r1); break; } case 0x04: // Compare lres = r0 + (uint16_t)(~r1) + uint32_t(1); - if (opa != 7) + if (update_flags) update_nzsc(lres, r0, ~r1); - return; + return false; case 0x06: // Negate lres = -r1; - if (opa != 7) + if (update_flags) update_nz(lres); break; case 0x08: // XOR lres = r0 ^ r1; - if (opa != 7) + if (update_flags) update_nz(lres); break; case 0x09: // Load lres = r1; - if (opa != 7) + if (update_flags) update_nz(lres); break; case 0x0a: // OR lres = r0 | r1; - if (opa != 7) + if (update_flags) update_nz(lres); break; case 0x0b: // AND lres = r0 & r1; - if (opa != 7) + if (update_flags) update_nz(lres); break; case 0x0c: // Test lres = r0 & r1; - if (opa != 7) + if (update_flags) update_nz(lres); - return; + return false; case 0x0d: // Store write16(r2, r0); - return; + return false; default: - unimplemented_opcode(op); - return; + fatalerror("UNSP: illegal ALU optype %02x at %04x\n", op0, UNSP_LPC); + return false; } - if (op1 == 0x04 && opn == 0x03) // store [imm16], r - write16(r2, lres); - else - m_core->m_r[opa] = (uint16_t)lres; + return true; } diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index ed0522de90d..34fa38066f8 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -729,25 +729,12 @@ READ16_MEMBER(sunplus_gcm394_base_device::internalrom_lower32_r) } } -READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r) -{ - return machine().rand(); -} - -//[:maincpu] ':maincpu' (001490):sunplus_gcm394_base_device::unk_r @ 0x785f -READ16_MEMBER(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r) -{ - return 0x0000; -} - - - // GPR27P512A = C2 76 // HY27UF081G2A = AD F1 80 1D // H27U518S2C = AD 76 -READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) +READ16_MEMBER(generalplus_gpac800_device::nand_7854_r) { // TODO: use actual NAND / Smart Media devices once this is better understood. // The games have extensive checks on startup to determine the flash types, but then it appears that @@ -762,11 +749,11 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) // real TSM code starts at 4c000 - //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context()); + //logerror("%s:sunplus_gcm394_base_device::nand_7854_r\n", machine().describe_context()); if (m_nandcommand == 0x90) // read ident { - logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr); + logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr); uint8_t data = 0x00; @@ -802,9 +789,9 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) } else if (m_nandcommand == 0x00) { - //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr); + //logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr); - uint32_t nandaddress = (m_flash_addr_high << 16) | m_flash_addr_low; + uint32_t nandaddress = (m_nand_addr_high << 16) | m_nand_addr_low; uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr); m_curblockaddr++; @@ -813,13 +800,13 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) } else if (m_nandcommand == 0x70) // read status { - logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr); + logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr); return 0xffff; } else { - logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr); + logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr); return 0xffff; } @@ -834,25 +821,159 @@ WRITE16_MEMBER(generalplus_gpac800_device::nand_command_w) m_nandcommand = data; } -WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_low_w) +WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_low_w) { - //logerror("%s:sunplus_gcm394_base_device::flash_addr_low_w %04x\n", machine().describe_context(), data); - m_flash_addr_low = data; + //logerror("%s:sunplus_gcm394_base_device::nand_addr_low_w %04x\n", machine().describe_context(), data); + m_nand_addr_low = data; m_curblockaddr = 0; } -WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) +WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_high_w) { - //logerror("%s:sunplus_gcm394_base_device::flash_addr_high_w %04x\n", machine().describe_context(), data); - m_flash_addr_high = data; + //logerror("%s:sunplus_gcm394_base_device::nand_addr_high_w %04x\n", machine().describe_context(), data); + m_nand_addr_high = data; - uint32_t address = (m_flash_addr_high << 16) | m_flash_addr_low; + uint32_t address = (m_nand_addr_high << 16) | m_nand_addr_low; logerror("%s: flash address is now %08x\n", machine().describe_context(), address); m_curblockaddr = 0; } +WRITE16_MEMBER(generalplus_gpac800_device::nand_dma_ctrl_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_dma_ctrl_w(?) %04x\n", machine().describe_context(), data); + m_nand_dma_ctrl = data; +} + +READ16_MEMBER(generalplus_gpac800_device::nand_7850_r) +{ + // 0x8000 = ready + return m_nand_7850 | 0x8000; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_7850_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_7850_w %04x\n", machine().describe_context(), data); + m_nand_7850 = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_7856_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_7856_w %04x\n", machine().describe_context(), data); + m_nand_7856 = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_7857_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_7857_w %04x\n", machine().describe_context(), data); + m_nand_7857 = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_785b_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_785b_w %04x\n", machine().describe_context(), data); + m_nand_785b = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_785c_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_785c_w %04x\n", machine().describe_context(), data); + m_nand_785c = data; +} + +WRITE16_MEMBER(generalplus_gpac800_device::nand_785d_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_785d_w %04x\n", machine().describe_context(), data); + m_nand_785d = data; +} + +// [:maincpu] ':maincpu' (00146D) jak_tsm +READ16_MEMBER(generalplus_gpac800_device::nand_785e_r) +{ + return 0x0000; +} + +//[:maincpu] ':maincpu' (001490) jak_tsm +READ16_MEMBER(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r) +{ + return 0x0000; +} + +/* +UNMAPPED reads writes + +jak_tsm uses these (all iniitalized near start) +unclear if these are specific to the GPAC800 type, or present in the older types + +[:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000) +[:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000) +[:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002) +[:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9) +[:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57) +[:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400) +[:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002) +[:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011) +[:maincpu] ':maincpu' (00045B):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x0000) +[:maincpu] ':maincpu' (00045D):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x0000) +[:maincpu] ':maincpu' (00045F):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x0000) +[:maincpu] ':maincpu' (000461):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x0000) + +jak_car2 uses these + +[:maincpu] ':maincpu' (004056):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002) +[:maincpu] ':maincpu' (004059):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9) +[:maincpu] ':maincpu' (00405C):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57) +[:maincpu] ':maincpu' (00405F):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400) +[:maincpu] ':maincpu' (004062):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002) +[:maincpu] ':maincpu' (004065):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011) +[:maincpu] ':maincpu' (004069):sunplus_gcm394_base_device::unk_r @ 0x7880 +[:maincpu] ':maincpu' (00406F):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x1249) +[:maincpu] ':maincpu' (004071):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x1249) +[:maincpu] ':maincpu' (004073):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x1249) +[:maincpu] ':maincpu' (004075):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x1249) +[:maincpu] ':maincpu' (004088):sunplus_gcm394_base_device::unk_w @ 0x7841 (data 0x000f) +[:maincpu] ':maincpu' (00408F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000) +[:maincpu] ':maincpu' (004092):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0002) + +[:maincpu] ':maincpu' (03000A):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x36db) +[:maincpu] ':maincpu' (03000C):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x36db) +[:maincpu] ':maincpu' (03000E):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x36db) +[:maincpu] ':maincpu' (030010):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x36db) +[:maincpu] ':maincpu' (030013):sunplus_gcm394_base_device::unk_w @ 0x787f (data 0x0010) +[:maincpu] ':maincpu' (03001D):sunplus_gcm394_base_device::unk_w @ 0x7804 (data 0x1c7f) +[:maincpu] ':maincpu' (030023):sunplus_gcm394_base_device::unk_w @ 0x7805 (data 0xcdf0) +[:maincpu] ':maincpu' (03E645):sunplus_gcm394_base_device::unk_w @ 0x7861 (data 0x1f66) +[:maincpu] ':maincpu' (03E64C):sunplus_gcm394_base_device::unk_w @ 0x786b (data 0x0000) +[:maincpu] ':maincpu' (03E64F):sunplus_gcm394_base_device::unk_w @ 0x7869 (data 0x0000) +[:maincpu] ':maincpu' (03E652):sunplus_gcm394_base_device::unk_w @ 0x786a (data 0x0000) +[:maincpu] ':maincpu' (03E65B):sunplus_gcm394_base_device::unk_w @ 0x7966 (data 0x0001) +[:maincpu] ':maincpu' (03CBD0):sunplus_gcm394_base_device::unk_w @ 0x7871 (data 0x0000) + +-- this one seems like a common alt type of DMA, used in both hw types as it polls 707c status before doing it +[:maincpu] ':maincpu' (03B4C7):sunplus_gcm394_base_device::unk_w @ 0x707c (data 0x0001) +-- also video / alt dma? +[:maincpu] ':maincpu' (068C15):sunplus_gcm394_base_device::unk_r @ 0x707e + +beambox sets things up with different values (ultimately stalls on some check, maybe seeprom?) + +[:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000) +[:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000) +[:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002) +[:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9) +[:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0f58) +[:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400) +[:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002) +[:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x4011) +[:maincpu] ':maincpu' (00045C):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x2492) -- note pair of 4, but different values to above games +[:maincpu] ':maincpu' (00045E):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x2492) +[:maincpu] ':maincpu' (000460):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x2492) +[:maincpu] ':maincpu' (000462):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x2492) + +vbaby code is very differet, attempts to load NAND block manually, not with DMA + +*/ + // all tilemap registers etc. appear to be in the same place as the above system, including the 'extra' ones not on the earlier models // so it's likely this is built on top of that just with NAND support @@ -861,13 +982,20 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) sunplus_gcm394_base_device::base_internal_map(map); // 785x = NAND device - map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // NAND Control Reg + map(0x007850, 0x007850).rw(FUNC(generalplus_gpac800_device::nand_7850_r), FUNC(generalplus_gpac800_device::nand_7850_w)); // NAND Control Reg map(0x007851, 0x007851).w(FUNC(generalplus_gpac800_device::nand_command_w)); // NAND Command Reg - map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::flash_addr_low_w)); // NAND Low Address Reg - map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::flash_addr_high_w)); // NAND High Address Reg - map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // NAND Data Reg -// map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control - + map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::nand_addr_low_w)); // NAND Low Address Reg + map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::nand_addr_high_w)); // NAND High Address Reg + map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::nand_7854_r)); // NAND Data Reg + map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control + map(0x007856, 0x007856).w(FUNC(generalplus_gpac800_device::nand_7856_w)); // usually 0x0021? + map(0x007857, 0x007857).w(FUNC(generalplus_gpac800_device::nand_7857_w)); + + // most of these are likely ECC stuff for testing the ROM? + map(0x00785b, 0x00785b).w(FUNC(generalplus_gpac800_device::nand_785b_w)); + map(0x00785c, 0x00785c).w(FUNC(generalplus_gpac800_device::nand_785c_w)); + map(0x00785d, 0x00785d).w(FUNC(generalplus_gpac800_device::nand_785d_w)); + map(0x00785e, 0x00785e).r(FUNC(generalplus_gpac800_device::nand_785e_r)); // also ECC status related? map(0x00785f, 0x00785f).r(FUNC(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)); // ECC Low Byte Error Flag 1 (maybe) // 128kwords internal ROM @@ -881,6 +1009,7 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) map(0x200000, 0x3fffff).rw(FUNC(generalplus_gpac800_device::cs_bank_space_r), FUNC(generalplus_gpac800_device::cs_bank_space_w)); } + void sunplus_gcm394_base_device::device_start() { unsp_20_device::device_start(); @@ -987,8 +1116,15 @@ void generalplus_gpac800_device::device_reset() { sunplus_gcm394_base_device::device_reset(); - m_flash_addr_low = 0x0000; - m_flash_addr_high = 0x0000; + m_nand_addr_low = 0x0000; + m_nand_addr_high = 0x0000; + m_nand_dma_ctrl = 0x0000; + m_nand_7850 = 0x0000; + m_nand_785d = 0x0000; + m_nand_785c = 0x0000; + m_nand_785b = 0x0000; + m_nand_7856 = 0x0000; + m_nand_7857 = 0x0000; } IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb) diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index b211089187b..ef0ee3be9b5 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -325,7 +325,6 @@ public: generalplus_gpac800_device(mconfig, tag, owner, clock) { m_screen.set_tag(std::forward(screen_tag)); - m_testval = 0; m_csbase = 0x30000; } @@ -338,22 +337,33 @@ protected: virtual void device_reset() override; private: - DECLARE_READ16_MEMBER(unkarea_7850_r); - DECLARE_READ16_MEMBER(unkarea_7854_r); - + DECLARE_READ16_MEMBER(nand_7850_r); + DECLARE_READ16_MEMBER(nand_7854_r); + DECLARE_WRITE16_MEMBER(nand_dma_ctrl_w); + DECLARE_WRITE16_MEMBER(nand_7850_w); DECLARE_WRITE16_MEMBER(nand_command_w); - - DECLARE_WRITE16_MEMBER(flash_addr_low_w); - DECLARE_WRITE16_MEMBER(flash_addr_high_w); - + DECLARE_WRITE16_MEMBER(nand_addr_low_w); + DECLARE_WRITE16_MEMBER(nand_addr_high_w); DECLARE_READ16_MEMBER(nand_ecc_low_byte_error_flag_1_r); - - int m_testval; + DECLARE_WRITE16_MEMBER(nand_7856_w); + DECLARE_WRITE16_MEMBER(nand_7857_w); + DECLARE_WRITE16_MEMBER(nand_785b_w); + DECLARE_WRITE16_MEMBER(nand_785c_w); + DECLARE_WRITE16_MEMBER(nand_785d_w); + DECLARE_READ16_MEMBER(nand_785e_r); uint16_t m_nandcommand; - uint16_t m_flash_addr_low; - uint16_t m_flash_addr_high; + uint16_t m_nand_addr_low; + uint16_t m_nand_addr_high; + + uint16_t m_nand_dma_ctrl; + uint16_t m_nand_7850; + uint16_t m_nand_785d; + uint16_t m_nand_785c; + uint16_t m_nand_785b; + uint16_t m_nand_7856; + uint16_t m_nand_7857; int m_curblockaddr; }; diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index 5fc11dffd26..277fa8f69ba 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -705,10 +705,23 @@ void gcm394_base_video_device::draw_sprites(const rectangle &cliprect, uint32_t uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - memset(&m_screenbuf[m_screen->width() * cliprect.min_y], 0, 4 * m_screen->width() * ((cliprect.max_y - cliprect.min_y) + 1)); + // For jak_car2 and jak_gtg the palette entry for 'magenta' in the test mode is intentionally set to a transparent black pen + // (it is stored in the palette table in ROM that way, and copied directly) so the only way for the magenta entries on the screen + // to be correctly displayed is if there is a magenta BG pen to fall through to (or for another palette write to change the palette + // that is copied, but this does not appear to be the case). How the bg pen is set is unknown, it is not a regular palette entry. + // The 'bitmap test mode' in jak_car2 requires this to be black instead, + //const uint16_t bgcol = 0x7c1f; // magenta + const uint16_t bgcol = 0x0000; // black for (uint32_t scanline = (uint32_t)cliprect.min_y; scanline <= (uint32_t)cliprect.max_y; scanline++) { + uint32_t* bufferline = &m_screenbuf[scanline * m_screen->width()]; + + for (int x = 0; x < m_screen->width(); x++) + { + bufferline[x] = m_rgb555_to_rgb888[bgcol]; + } + for (int i = 0; i < 4; i++) { if (1) diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index d71101052f1..54e748bc5b0 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -400,10 +400,13 @@ WRITE16_MEMBER(gcm394_game_state::porta_w) logerror("%s: Port A:WRITE %04x\n", machine().describe_context(), data); } +// some sources indicate these later SoC types run at 96Mhz, others indicate 48Mhz. +// unSP 2.0 CPUs have a lower average CPI too (2 instead of 6 on unSP 1.0 or 5 on unSP 1.1 / 1.2 / unSP 2.0) so using regular unSP timings might result in things being too slow +// as with the older SunPlus chips this appears to be an fully internally generated frequency, external XTALs again are typically 6MHz or simply not present. void gcm394_game_state::base(machine_config &config) { - GCM394(config, m_maincpu, XTAL(27'000'000), m_screen); + GCM394(config, m_maincpu, 96000000/2, m_screen); m_maincpu->porta_in().set(FUNC(gcm394_game_state::porta_r)); m_maincpu->portb_in().set(FUNC(gcm394_game_state::portb_r)); m_maincpu->porta_out().set(FUNC(gcm394_game_state::porta_w)); @@ -459,10 +462,9 @@ WRITE16_MEMBER(wrlshunt_game_state::hunt_porta_w) } - void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config) { - GPAC800(config, m_maincpu, XTAL(27'000'000), m_screen); + GPAC800(config, m_maincpu, 96000000/2, m_screen); m_maincpu->porta_in().set(FUNC(generalplus_gpac800_game_state::porta_r)); m_maincpu->portb_in().set(FUNC(generalplus_gpac800_game_state::portb_r)); m_maincpu->porta_out().set(FUNC(generalplus_gpac800_game_state::porta_w)); @@ -811,7 +813,7 @@ INPUT_PORTS_END ROM_START(smartfp) //ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different) - //ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) + //ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) ROM_REGION(0x800000, "maincpu", ROMREGION_ERASE00) ROM_LOAD16_WORD_SWAP("smartfitpark.bin", 0x000000, 0x800000, CRC(ada84507) SHA1(a3a80bf71fae62ebcbf939166a51d29c24504428)) @@ -819,7 +821,7 @@ ROM_END ROM_START(wrlshunt) //ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different) - //ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) + //ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) ROM_REGION(0x8000000, "maincpu", ROMREGION_ERASE00) ROM_LOAD16_WORD_SWAP("wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796)) @@ -928,7 +930,7 @@ https://web.archive.org/web/20180106005235/http://www.lcis.com.tw/paper_store/pa ROM_START( wlsair60 ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "wlsair60.nand", 0x0000, 0x8400000, CRC(eec23b97) SHA1(1bb88290cf54579a5bb51c08a02d793cd4d79f7a) ) @@ -936,7 +938,7 @@ ROM_END ROM_START( jak_gtg ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "goldentee.bin", 0x0000, 0x4200000, CRC(87d5e815) SHA1(5dc46cd753b791449cc41d5eff4928c0dcaf35c0) ) @@ -944,7 +946,7 @@ ROM_END ROM_START( jak_car2 ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "cars2.bin", 0x0000, 0x4200000, CRC(4d610e09) SHA1(bc59f5f7f676a8f2a78dfda7fb62c804bbf850b6) ) @@ -952,7 +954,7 @@ ROM_END ROM_START( jak_tsm ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "toystorymania.bin", 0x0000, 0x4200000, CRC(183b20a5) SHA1(eb4fa5ee9dfac58f5244d00d4e833b1e461cc52c) ) @@ -960,7 +962,7 @@ ROM_END ROM_START( vbaby ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "vbaby.bin", 0x0000, 0x8400000, CRC(d904441b) SHA1(3742bc4e1e403f061ce2813ecfafc6f30a44d287) ) @@ -968,7 +970,7 @@ ROM_END ROM_START( beambox ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "beambox.bin", 0x0000, 0x4200000, CRC(a486f04e) SHA1(73c7d99d8922eba58d94e955e254b9c3baa4443e) ) -- cgit v1.2.3