mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
es5510: fix some alu flag problems
This commit is contained in:
parent
f49f2aafa1
commit
0295de5fe0
@ -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 <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
******************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user