summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp/unsp_fxxx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/unsp/unsp_fxxx.cpp')
-rw-r--r--src/devices/cpu/unsp/unsp_fxxx.cpp70
1 files changed, 50 insertions, 20 deletions
diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp
index 66d195e7850..7bd76da1270 100644
--- a/src/devices/cpu/unsp/unsp_fxxx.cpp
+++ b/src/devices/cpu/unsp/unsp_fxxx.cpp
@@ -60,15 +60,11 @@ inline void unsp_device::execute_fxxx_000_group(uint16_t op)
// MUL us ( signed * unsigned )
// MUL 1 1 1 1* r r r 0* 0 0 0 0 1 r r r (** = sign bits, fixed here)
- const uint16_t opa = (op >> 9) & 7;
- const uint16_t opb = op & 7;
+ const uint16_t rd = (op >> 9) & 7;
+ const uint16_t rs = op & 7;
m_core->m_icount -= 12;
- uint32_t lres = m_core->m_r[opa] * m_core->m_r[opb];
- if (m_core->m_r[opb] & 0x8000)
- {
- lres -= m_core->m_r[opa] << 16;
- }
- m_core->m_r[REG_R4] = lres >> 16;
+ int32_t lres = (int32_t)(uint32_t)m_core->m_r[rd] * (int32_t)(int16_t)m_core->m_r[rs];
+ m_core->m_r[REG_R4] = (uint16_t)(lres >> 16);
m_core->m_r[REG_R3] = (uint16_t)lres;
return;
@@ -290,15 +286,13 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op)
return;
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
- logerror("unimplemented: fir_mov on\n");
m_core->m_icount -= 1;
- //unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
+ m_core->m_fir_move = 1;
return;
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
- logerror("unimplemented: fir_mov off\n");
m_core->m_icount -= 1;
- //unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
+ m_core->m_fir_move = 0;
return;
case 0xf161: case 0xf361: case 0xf561: case 0xf761: case 0xf961: case 0xfb61: case 0xfd61: case 0xff61:
@@ -392,13 +386,11 @@ void unsp_device::execute_fxxx_101_group(uint16_t op)
return;
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
- logerror("fir_mov on (shouldn't exist on 1.0, is this 1.2 or does it act as a NOP?)\n");
- //unimplemented_opcode(op); // jak_care triggers this, which again strongly suggests that everything we have is 1.2 or above even if most new features are unused
+ m_core->m_fir_move = 1;
return;
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
- logerror("fir_mov off (shouldn't exist on 1.0, is this 1.2 or does it act as a NOP?)\n");
- //unimplemented_opcode(op); // jak_care triggers this, see above
+ m_core->m_fir_move = 0;
return;
case 0xf160: case 0xf360: case 0xf560: case 0xf760: case 0xf960: case 0xfb60: case 0xfd60: case 0xff60:
@@ -458,8 +450,45 @@ inline void unsp_device::execute_fxxx_110_group(uint16_t op)
// MULS 1 1 1 1* r r r 1* 1 0*s s s r r r (1* = sign bit, 1* = sign bit 0* = upper size bit)
// MULS ss with upper size bit not set
- //unimplemented_opcode(op);
- //return;
+ const uint16_t size = ((op >> 3) & 7) ? ((op >> 3) & 7) : 16;
+ const uint16_t rd = (op >> 9) & 7;
+ const uint16_t rs = op & 7;
+ execute_muls(rd, rs, size);
+}
+
+inline void unsp_device::execute_muls(const uint16_t rd, const uint16_t rs, const uint16_t size)
+{
+ const uint32_t rdv = m_core->m_r[rd];
+ const uint32_t rsv = m_core->m_r[rs];
+ int64_t lres = 0;
+ uint16_t values[16];
+ for (uint16_t i = 0; i < size; i++)
+ {
+ values[i] = read16(rdv + i);
+ const uint16_t rhs = read16(rsv + i);
+ uint32_t tres = values[i] * rhs;
+ if (values[i] & 0x8000)
+ {
+ tres -= rhs << 16;
+ }
+ if (rhs & 0x8000)
+ {
+ tres -= values[i] << 16;
+ }
+ lres += (int64_t)(int32_t)tres;
+ }
+ m_core->m_sb = 0;
+ if (m_core->m_fir_move)
+ {
+ for (uint16_t i = size - 1; i > 0; i--)
+ {
+ write16(rdv + i, values[i - 1]);
+ }
+ }
+ m_core->m_r[rd] += size;
+ m_core->m_r[rs] += size;
+ m_core->m_r[REG_R4] = (uint16_t)(lres >> 16);
+ m_core->m_r[REG_R3] = (uint16_t)lres;
}
inline void unsp_device::execute_fxxx_111_group(uint16_t op)
@@ -472,8 +501,9 @@ inline void unsp_device::execute_fxxx_111_group(uint16_t op)
// MULS 1 1 1 1* r r r 1* 1 1*s s s r r r (1* = sign bit, 1* = sign bit 1* = upper size bit)
// MULS ss with upper size bit set.
- //unimplemented_opcode(op);
- //return;
+ const uint16_t rd = (op >> 9) & 7;
+ const uint16_t rs = op & 7;
+ execute_muls(rd, rs, ((op >> 3) & 7) + 8);
}
void unsp_device::execute_fxxx_group(uint16_t op)