From 0295de5fe0d05a53a8eb797ec21ccf303e1d4fb1 Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 4 Apr 2023 02:42:08 +0200 Subject: es5510: fix some alu flag problems --- src/devices/cpu/es5510/es5510.cpp | 109 ++++++++++++++++++-------------------- src/mame/snk/miconkit.cpp | 3 ++ 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/src/devices/cpu/es5510/es5510.cpp b/src/devices/cpu/es5510/es5510.cpp index e5b377db12c..914a839c7ef 100644 --- a/src/devices/cpu/es5510/es5510.cpp +++ b/src/devices/cpu/es5510/es5510.cpp @@ -6,7 +6,6 @@ * by Christian Brunschen * * TODO - * ridingf, ringrage and clones: Exception after logo is displayed (MT #06894) * gunlock and clones: Glitch sound after game over once (MT #07861) * DRAM Size isn't verified, differs per machines? * @@ -24,18 +23,6 @@ #include #include -static constexpr int32_t MIN_24 = -(1 << 23); -static constexpr int32_t MAX_24 = (1 << 23) - 1; - -static constexpr int64_t MIN_48 = -(s64(1) << 47); -static constexpr int64_t MAX_48 = (s64(1) << 47) - 1; - -#define SIGN_BIT_24 (0x00800000) -#define GET_SIGN_BIT_24(x) ((x) & SIGN_BIT_24) -#define IS_NEGATIVE(x) (((x) & SIGN_BIT_24) != 0) - -#define CARRY_OUT_24 (0x01000000) - #define VERBOSE 0 #define VERBOSE_EXEC 0 @@ -90,17 +77,17 @@ inline static bool isFlagSet(uint8_t ccr, uint8_t flag) { } inline static int32_t add(int32_t a, int32_t b, uint8_t &flags) { - int32_t aSign = a & SIGN_BIT_24; - int32_t bSign = b & SIGN_BIT_24; + int32_t aSign = a & 0x00800000; + int32_t bSign = b & 0x00800000; int32_t result = a + b; - int32_t resultSign = result & SIGN_BIT_24; + int32_t resultSign = result & 0x00800000; bool overflow = (aSign == bSign) && (aSign != resultSign); - bool carry = result & CARRY_OUT_24; + bool carry = result & 0x01000000; bool negative = resultSign != 0; bool lessThan = (overflow && !negative) || (!overflow && negative); flags = setFlagTo(flags, FLAG_C, carry); flags = setFlagTo(flags, FLAG_N, negative); - flags = setFlagTo(flags, FLAG_Z, result == 0); + flags = setFlagTo(flags, FLAG_Z, (result & 0x00ffffff) == 0); flags = setFlagTo(flags, FLAG_V, overflow); flags = setFlagTo(flags, FLAG_LT, lessThan); return result & 0x00ffffff; @@ -108,8 +95,9 @@ inline static int32_t add(int32_t a, int32_t b, uint8_t &flags) { inline static int32_t saturate(int32_t value, uint8_t &flags, bool negative) { if (isFlagSet(flags, FLAG_V)) { - setFlagTo(flags, FLAG_N, negative); - return negative ? MIN_24 : MAX_24; + flags = setFlagTo(flags, FLAG_N, negative); + flags = clearFlag(flags, FLAG_Z); + return negative ? 0x00800000 : 0x007fffff; } else { return value; } @@ -120,10 +108,11 @@ inline static int32_t negate(int32_t value) { } inline static int32_t asl(int32_t value, int shift, uint8_t &flags) { - int32_t signBefore = value & SIGN_BIT_24; + int32_t signBefore = value & 0x00800000; int32_t result = value << shift; - int32_t signAfter = result & SIGN_BIT_24; + int32_t signAfter = result & 0x00800000; bool overflow = signBefore != signAfter; + flags = setFlagTo(flags, FLAG_Z, (result & 0x00ffffff) == 0); flags = setFlagTo(flags, FLAG_V, overflow); return saturate(result, flags, signBefore != 0); } @@ -392,9 +381,9 @@ uint8_t es5510_device::host_r(address_space &space, offs_t offset) case 0x10: LOG("ES5510: Host Read DADR latch[1]: %02x\n", (dadr_latch >> 8) & 0xff); return (dadr_latch >> 8) & 0xff; case 0x11: LOG("ES5510: Host Read DADR latch[0]: %02x\n", (dadr_latch >> 0) & 0xff); return (dadr_latch >> 0) & 0xff; - case 0x12: LOG("ES5510: Host Reading Host Control\n"); return 0/* host_control */; // Host Control + case 0x12: LOG("ES5510: Host Reading Host Control\n"); return 0; // Host Control - case 0x16: return 0x27/* pc */; // Program Counter, for test purposes only + case 0x16: return 0x27; // Program Counter, for test purposes only } // default: 0. @@ -421,12 +410,12 @@ void es5510_device::host_w(offs_t offset, uint8_t data) break; /* 0x03 to 0x08 INSTR Register */ - case 0x03: instr_latch = ((instr_latch&0x00ffffffffffU) | (int64_t(data)&0xff)<<40); LOG("%s",string_format("ES5510: Host Write INSTR latch[5] = %02x -> %012x\n", data, instr_latch).c_str()); break; - case 0x04: instr_latch = ((instr_latch&0xff00ffffffffU) | (int64_t(data)&0xff)<<32); LOG("%s",string_format("ES5510: Host Write INSTR latch[4] = %02x -> %012x\n", data, instr_latch).c_str()); break; - case 0x05: instr_latch = ((instr_latch&0xffff00ffffffU) | (int64_t(data)&0xff)<<24); LOG("%s",string_format("ES5510: Host Write INSTR latch[3] = %02x -> %012x\n", data, instr_latch).c_str()); break; - case 0x06: instr_latch = ((instr_latch&0xffffff00ffffU) | (int64_t(data)&0xff)<<16); LOG("%s",string_format("ES5510: Host Write INSTR latch[2] = %02x -> %012x\n", data, instr_latch).c_str()); break; - case 0x07: instr_latch = ((instr_latch&0xffffffff00ffU) | (int64_t(data)&0xff)<< 8); LOG("%s",string_format("ES5510: Host Write INSTR latch[1] = %02x -> %012x\n", data, instr_latch).c_str()); break; - case 0x08: instr_latch = ((instr_latch&0xffffffffff00U) | (int64_t(data)&0xff)<< 0); LOG("%s",string_format("ES5510: Host Write INSTR latch[0] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x03: instr_latch = ((instr_latch & 0x00ffffffffffULL) | (int64_t(data)&0xff)<<40); LOG("%s",string_format("ES5510: Host Write INSTR latch[5] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x04: instr_latch = ((instr_latch & 0xff00ffffffffULL) | (int64_t(data)&0xff)<<32); LOG("%s",string_format("ES5510: Host Write INSTR latch[4] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x05: instr_latch = ((instr_latch & 0xffff00ffffffULL) | (int64_t(data)&0xff)<<24); LOG("%s",string_format("ES5510: Host Write INSTR latch[3] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x06: instr_latch = ((instr_latch & 0xffffff00ffffULL) | (int64_t(data)&0xff)<<16); LOG("%s",string_format("ES5510: Host Write INSTR latch[2] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x07: instr_latch = ((instr_latch & 0xffffffff00ffULL) | (int64_t(data)&0xff)<< 8); LOG("%s",string_format("ES5510: Host Write INSTR latch[1] = %02x -> %012x\n", data, instr_latch).c_str()); break; + case 0x08: instr_latch = ((instr_latch & 0xffffffffff00ULL) | (int64_t(data)&0xff)<< 0); LOG("%s",string_format("ES5510: Host Write INSTR latch[0] = %02x -> %012x\n", data, instr_latch).c_str()); break; /* 0x09 to 0x0b DIL Register (r/o) */ @@ -459,7 +448,8 @@ void es5510_device::host_w(offs_t offset, uint8_t data) case 0x11: dadr_latch = (dadr_latch&0xffff00) | ((data&0xff)<< 0); break; /* 0x12 Host Control */ - case 0x12: host_control = (host_control & 0x4) | (data & 0x3); + case 0x12: + host_control = (host_control & 0x4) | (data & 0x3); if (BIT(host_control, 1)) // RAM clear { // TODO: Timing, MEMSIZ and DLENGTH behavior @@ -490,7 +480,7 @@ void es5510_device::host_w(offs_t offset, uint8_t data) break; /* 0x1f Halt enable (w) / Frame Counter (r) */ - case 0x1F: + case 0x1f: LOG("ES5510: Host Write Halt Enable %02x; HALT line is %d\n", data, halt_asserted); if (halt_asserted) { LOG("ES5510: Host Write to Halt Enable while HALT line is asserted: Halting!\n"); @@ -499,7 +489,7 @@ void es5510_device::host_w(offs_t offset, uint8_t data) break; case 0x80: /* Read select - GPR + INSTR */ - LOG("%s",string_format("ES5510: Host Read INSTR+GPR %02x (%s): %012x %06x (%d)\n", data, REGNAME(data & 0xff), instr[data] & 0xffffffffffffU, gpr[data] & 0xffffff, gpr[data]).c_str()); + LOG("%s",string_format("ES5510: Host Read INSTR+GPR %02x (%s): %012x %06x (%d)\n", data, REGNAME(data & 0xff), instr[data] & 0xffffffffffffULL, gpr[data] & 0xffffff, gpr[data]).c_str()); /* Check if an INSTR address is selected */ if (data < 0xa0) { @@ -520,10 +510,10 @@ void es5510_device::host_w(offs_t offset, uint8_t data) case 0xc0: /* Write select - INSTR */ #if VERBOSE DESCRIBE_INSTR(buf, instr_latch, gpr[data], nullptr, nullptr, nullptr, nullptr); - LOG("%s",string_format("ES5510: Host Write INSTR %02x %012x: %s\n", data, instr_latch&0xffffffffffffU, buf).c_str()); + LOG("%s",string_format("ES5510: Host Write INSTR %02x %012x: %s\n", data, instr_latch & 0xffffffffffffULL, buf).c_str()); #endif if (data < 0xa0) { - instr[data] = instr_latch&0xffffffffffffU; + instr[data] = instr_latch & 0xffffffffffffULL; } break; @@ -667,8 +657,7 @@ void es5510_device::device_reset() { device_memory_interface::space_config_vector es5510_device::memory_space_config() const { - return space_config_vector { - }; + return space_config_vector { }; } uint64_t es5510_device::execute_clocks_to_cycles(uint64_t clocks) const noexcept { @@ -881,7 +870,7 @@ void es5510_device::execute_run() { mulacc.result = mulacc.product; } - if (mulacc.result < MIN_48 || mulacc.result > MAX_48) { + if (mulacc.result < -(s64(1) << 47) || mulacc.result >= (s64(1) << 47)) { mac_overflow = true; } else { mac_overflow = false; @@ -899,7 +888,7 @@ void es5510_device::execute_run() { } #endif machl = mulacc.result; - int32_t tmp = mac_overflow ? (machl < 0 ? MIN_24 : MAX_24) : (mulacc.result & 0x0000ffffff000000U) >> 24; + int32_t tmp = mac_overflow ? (machl < 0 ? 0x00800000 : 0x007fffff) : (mulacc.result & 0x0000ffffff000000ULL) >> 24; if (mulacc.dst & SRC_DST_REG) { write_reg(mulacc.cReg, tmp); } @@ -964,7 +953,7 @@ void es5510_device::execute_run() { alu.write_result = !skip; alu.update_ccr = !skippable || (alu.op == OP_CMP); - if (alu.op == 0xF) { + if (alu.op == 0xf) { alu_operation_end(); } else { // --- Read ALU Operands N @@ -1050,8 +1039,8 @@ int32_t es5510_device::read_reg(uint8_t reg) case 239: RETURN16(ser2l, ser2l); case 240: RETURN16(ser3r, ser3r); case 241: RETURN16(ser3l, ser3l); - case 242: /* macl */ RETURN(macl, mac_overflow ? (machl < 0 ? 0x00ffffff : 0x00000000) : (machl >> 0) & 0x00ffffff); - case 243: /* mach */ RETURN(mach, mac_overflow ? (machl < 0 ? MIN_24 : MAX_24) : (machl >> 24) & 0x00ffffff); + case 242: RETURN(macl, mac_overflow ? (machl < 0 ? 0x00000000 : 0x00ffffff) : (machl >> 0) & 0x00ffffff); + case 243: RETURN(mach, mac_overflow ? (machl < 0 ? 0x00800000 : 0x007fffff) : (machl >> 24) & 0x00ffffff); case 244: RETURN(dil, dil); // DIL when reading case 245: RETURN(dlength, dlength); case 246: RETURN(abase, abase); @@ -1061,8 +1050,8 @@ int32_t es5510_device::read_reg(uint8_t reg) case 250: RETURN(ccr, ccr); case 251: RETURN(cmr, cmr); case 252: RETURN(minus_one, 0x00ffffff); - case 253: RETURN(min, MIN_24); - case 254: RETURN(max, MAX_24); + case 253: RETURN(min, 0x00800000); + case 254: RETURN(max, 0x007fffff); case 255: RETURN(zero, 0); default: // unknown SPR @@ -1264,27 +1253,27 @@ int32_t es5510_device::alu_operation(uint8_t op, int32_t a, int32_t b, uint8_t & case 0x5: // AND a &= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); + flags = setFlagTo(flags, FLAG_N, (a & 0x00800000) != 0); + flags = setFlagTo(flags, FLAG_Z, a == 0); return a; case 0x6: // OR a |= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); + flags = setFlagTo(flags, FLAG_N, (a & 0x00800000) != 0); + flags = setFlagTo(flags, FLAG_Z, a == 0); return a; case 0x7: // XOR a ^= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); + flags = setFlagTo(flags, FLAG_N, (a & 0x00800000) != 0); + flags = setFlagTo(flags, FLAG_Z, a == 0); return a; case 0x8: // ABS { - clearFlag(flags, FLAG_N); + flags = clearFlag(flags, FLAG_N); bool isNegative = (a & 0x00800000) != 0; - setFlagTo(flags, FLAG_C, isNegative); + flags = setFlagTo(flags, FLAG_C, isNegative); // Note: the absolute value is calculated by one's complement! return isNegative ? (0x00ffffff ^ a) : a; } @@ -1292,22 +1281,26 @@ int32_t es5510_device::alu_operation(uint8_t op, int32_t a, int32_t b, uint8_t & case 0x9: // MOV return b; - case 0xA: // ASL2 + case 0xa: // ASL2 return asl(b, 2, flags); - case 0xB: // ASL8 + case 0xb: // ASL8 return asl(b, 8, flags); - case 0xC: // LS15 + case 0xc: // LS15 + flags = clearFlag(flags, FLAG_N); + flags = setFlagTo(flags, FLAG_C, (b & 0x00800000) != 0); return (b << 15) & 0x007fffff; - case 0xD: // DIFF + case 0xd: // DIFF return add(0x007fffff, negate(b), flags); - case 0xE: // ASR + case 0xe: // ASR + flags = setFlagTo(flags, FLAG_N, (b & 0x00800000) != 0); + flags = setFlagTo(flags, FLAG_C, (b & 1) != 0); return (b >> 1) | (b & 0x00800000); - case 0xF: // END - handled separately in alu_operation_end() + case 0xf: // END - handled separately in alu_operation_end() default: return 0; } diff --git a/src/mame/snk/miconkit.cpp b/src/mame/snk/miconkit.cpp index 64f2a53fb0d..7fd8ae8a95a 100644 --- a/src/mame/snk/miconkit.cpp +++ b/src/mame/snk/miconkit.cpp @@ -258,6 +258,7 @@ static INPUT_PORTS_START(smiconk) INPUT_PORTS_END + /****************************************************************************** Machine Configs ******************************************************************************/ @@ -299,6 +300,8 @@ void miconkit_state::smiconk(machine_config &config) m_maincpu->set_addrmap(AS_IO, &miconkit_state::smiconk_io_map); } + + /****************************************************************************** ROM Definitions ******************************************************************************/ -- cgit v1.2.3