summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/clipper
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/clipper')
-rw-r--r--src/devices/cpu/clipper/clipper.cpp213
-rw-r--r--src/devices/cpu/clipper/clipper.h49
-rw-r--r--src/devices/cpu/clipper/clipperd.cpp24
-rw-r--r--src/devices/cpu/clipper/clipperd.h6
4 files changed, 135 insertions, 157 deletions
diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp
index 67eebf611cf..32c1d0dee82 100644
--- a/src/devices/cpu/clipper/clipper.cpp
+++ b/src/devices/cpu/clipper/clipper.cpp
@@ -14,11 +14,9 @@
*/
#include "emu.h"
-#include "debugger.h"
#include "clipper.h"
#include "clipperd.h"
-#define LOG_GENERAL (1U << 0)
#define LOG_EXCEPTION (1U << 1)
#define LOG_SYSCALLS (1U << 2)
@@ -68,6 +66,7 @@ clipper_c300_device::clipper_c300_device(const machine_config &mconfig, const ch
clipper_c400_device::clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C4R4)
+ , m_db_pc(0)
, m_cammu(*this, "^cammu")
{
}
@@ -81,34 +80,15 @@ clipper_device::clipper_device(const machine_config &mconfig, device_type type,
, m_psw(endianness == ENDIANNESS_BIG ? PSW_BIG : 0)
, m_ssw(cpuid)
, m_r(m_rs)
+ , m_ru{0}
+ , m_rs{0}
+ , m_f{0}
+ , m_fp_pc(0)
+ , m_fp_dst(0)
+ , m_info{0}
{
}
-// rotate helpers to replace MSVC intrinsics
-inline u32 rotl32(u32 x, u8 shift)
-{
- shift &= 31;
- return (x << shift) | (x >> ((32 - shift) & 31));
-}
-
-inline u32 rotr32(u32 x, u8 shift)
-{
- shift &= 31;
- return (x >> shift) | (x << ((32 - shift) & 31));
-}
-
-inline u64 rotl64(u64 x, u8 shift)
-{
- shift &= 63;
- return (x << shift) | (x >> ((64 - shift) & 63));
-}
-
-inline u64 rotr64(u64 x, u8 shift)
-{
- shift &= 63;
- return (x >> shift) | (x << ((64 - shift) & 63));
-}
-
void clipper_device::device_start()
{
// configure the cammu address spaces
@@ -203,7 +183,7 @@ void clipper_device::execute_run()
if (m_nmi)
{
// acknowledge non-maskable interrupt
- standard_irq_callback(INPUT_LINE_NMI);
+ standard_irq_callback(INPUT_LINE_NMI, m_pc);
LOGMASKED(LOG_EXCEPTION, "non-maskable interrupt\n");
m_pc = intrap(EXCEPTION_INTERRUPT_BASE, m_pc);
@@ -216,7 +196,7 @@ void clipper_device::execute_run()
if ((m_ivec & IVEC_LEVEL) <= SSW(IL))
{
// acknowledge interrupt
- standard_irq_callback(INPUT_LINE_IRQ0);
+ standard_irq_callback(INPUT_LINE_IRQ0, m_pc);
m_pc = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_pc);
@@ -226,24 +206,25 @@ void clipper_device::execute_run()
while (m_icount > 0)
{
- debugger_instruction_hook(m_pc);
-
if (m_wait)
{
+ debugger_wait_hook();
m_icount = 0;
continue;
}
+ debugger_instruction_hook(m_pc);
+
// fetch and decode an instruction
if (decode_instruction())
{
- float_exception_flags = 0;
+ softfloat_exceptionFlags = 0;
// execute instruction
execute_instruction();
// check floating point exceptions
- if (float_exception_flags)
+ if (softfloat_exceptionFlags)
fp_exception();
}
@@ -328,12 +309,12 @@ device_memory_interface::space_config_vector clipper_device::memory_space_config
};
}
-bool clipper_device::memory_translate(int spacenum, int intention, offs_t &address)
+bool clipper_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{
- return ((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_FETCH ? get_icammu() : get_dcammu()).memory_translate(m_ssw, spacenum, intention, address);
+ return (intention == TR_FETCH ? get_icammu() : get_dcammu()).memory_translate(m_ssw, spacenum, intention, address, target_space);
}
-WRITE16_MEMBER(clipper_device::set_exception)
+void clipper_device::set_exception(u16 data)
{
LOGMASKED(LOG_EXCEPTION, "external exception 0x%04x triggered\n", data);
@@ -550,22 +531,22 @@ void clipper_device::execute_instruction()
case 0x20:
// adds: add single floating
- set_fp(R2, float32_add(get_fp32(R2), get_fp32(R1)), F_IVUX);
+ set_fp(R2, f32_add(get_fp32(R2), get_fp32(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x21:
// subs: subtract single floating
- set_fp(R2, float32_sub(get_fp32(R2), get_fp32(R1)), F_IVUX);
+ set_fp(R2, f32_sub(get_fp32(R2), get_fp32(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x22:
// addd: add double floating
- set_fp(R2, float64_add(get_fp64(R2), get_fp64(R1)), F_IVUX);
+ set_fp(R2, f64_add(get_fp64(R2), get_fp64(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x23:
// subd: subtract double floating
- set_fp(R2, float64_sub(get_fp64(R2), get_fp64(R1)), F_IVUX);
+ set_fp(R2, f64_sub(get_fp64(R2), get_fp64(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x24:
@@ -574,11 +555,11 @@ void clipper_device::execute_instruction()
break;
case 0x25:
// cmps: compare single floating
- FLAGS(0, 0, float32_eq(get_fp32(R2), get_fp32(R1)), float32_lt(get_fp32(R2), get_fp32(R1)));
+ FLAGS(0, 0, f32_eq(get_fp32(R2), get_fp32(R1)), f32_lt(get_fp32(R2), get_fp32(R1)));
// flag unordered
- if (float_exception_flags & float_flag_invalid)
+ if (softfloat_exceptionFlags & softfloat_flag_invalid)
m_psw |= PSW_Z | PSW_N;
- float_exception_flags &= F_NONE;
+ softfloat_exceptionFlags &= F_NONE;
break;
case 0x26:
// movd: move double floating
@@ -586,47 +567,47 @@ void clipper_device::execute_instruction()
break;
case 0x27:
// cmpd: compare double floating
- FLAGS(0, 0, float64_eq(get_fp64(R2), get_fp64(R1)), float64_lt(get_fp64(R2), get_fp64(R1)));
+ FLAGS(0, 0, f64_eq(get_fp64(R2), get_fp64(R1)), f64_lt(get_fp64(R2), get_fp64(R1)));
// flag unordered
- if (float_exception_flags & float_flag_invalid)
+ if (softfloat_exceptionFlags & softfloat_flag_invalid)
m_psw |= PSW_Z | PSW_N;
- float_exception_flags &= F_NONE;
+ softfloat_exceptionFlags &= F_NONE;
break;
case 0x28:
// muls: multiply single floating
- set_fp(R2, float32_mul(get_fp32(R2), get_fp32(R1)), F_IVUX);
+ set_fp(R2, f32_mul(get_fp32(R2), get_fp32(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x29:
// divs: divide single floating
- set_fp(R2, float32_div(get_fp32(R2), get_fp32(R1)), F_IVDUX);
+ set_fp(R2, f32_div(get_fp32(R2), get_fp32(R1)), F_IVDUX);
// TRAPS: F_IVDUX
break;
case 0x2a:
// muld: multiply double floating
- set_fp(R2, float64_mul(get_fp64(R2), get_fp64(R1)), F_IVUX);
+ set_fp(R2, f64_mul(get_fp64(R2), get_fp64(R1)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x2b:
// divd: divide double floating
- set_fp(R2, float64_div(get_fp64(R2), get_fp64(R1)), F_IVDUX);
+ set_fp(R2, f64_div(get_fp64(R2), get_fp64(R1)), F_IVDUX);
// TRAPS: F_IVDUX
break;
case 0x2c:
// movsw: move single floating to word
- m_r[R2] = get_fp32(R1);
+ m_r[R2] = get_fp32(R1).v;
break;
case 0x2d:
// movws: move word to single floating
- set_fp(R2, m_r[R1], F_NONE);
+ set_fp(R2, float32_t{ m_r[R1] }, F_NONE);
break;
case 0x2e:
// movdl: move double floating to longword
- set_64(R2, get_fp64(R1));
+ set_64(R2, get_fp64(R1).v);
break;
case 0x2f:
// movld: move longword to double floating
- set_fp(R2, get_64(R1), F_NONE);
+ set_fp(R2, float64_t{ get_64(R1) }, F_NONE);
break;
case 0x30:
// shaw: shift arithmetic word
@@ -687,18 +668,18 @@ void clipper_device::execute_instruction()
case 0x34:
// rotw: rotate word
if (!BIT31(m_r[R1]))
- m_r[R2] = rotl32(m_r[R2], m_r[R1]);
+ m_r[R2] = rotl_32(m_r[R2], m_r[R1]);
else
- m_r[R2] = rotr32(m_r[R2], -m_r[R1]);
+ m_r[R2] = rotr_32(m_r[R2], -m_r[R1]);
// FLAGS: 00ZN
FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
break;
case 0x35:
// rotl: rotate longword
if (!BIT31(m_r[R1]))
- set_64(R2, rotl64(get_64(R2), m_r[R1]));
+ set_64(R2, rotl_64(get_64(R2), m_r[R1]));
else
- set_64(R2, rotr64(get_64(R2), -m_r[R1]));
+ set_64(R2, rotr_64(get_64(R2), -m_r[R1]));
// FLAGS: 00ZN
FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
break;
@@ -766,9 +747,9 @@ void clipper_device::execute_instruction()
case 0x3c:
// roti: rotate immediate
if (!BIT31(m_info.imm))
- m_r[R2] = rotl32(m_r[R2], m_info.imm);
+ m_r[R2] = rotl_32(m_r[R2], m_info.imm);
else
- m_r[R2] = rotr32(m_r[R2], -m_info.imm);
+ m_r[R2] = rotr_32(m_r[R2], -m_info.imm);
FLAGS(0, 0, m_r[R2] == 0, BIT31(m_r[R2]));
// FLAGS: 00ZN
// TRAPS: I
@@ -776,9 +757,9 @@ void clipper_device::execute_instruction()
case 0x3d:
// rotli: rotate longword immediate
if (!BIT31(m_info.imm))
- set_64(R2, rotl64(get_64(R2), m_info.imm));
+ set_64(R2, rotl_64(get_64(R2), m_info.imm));
else
- set_64(R2, rotr64(get_64(R2), -m_info.imm));
+ set_64(R2, rotr_64(get_64(R2), -m_info.imm));
FLAGS(0, 0, get_64(R2) == 0, BIT63(get_64(R2)));
// FLAGS: 00ZN
// TRAPS: I
@@ -842,13 +823,13 @@ void clipper_device::execute_instruction()
case 0x64:
case 0x65:
// loads: load single floating
- get_dcammu().load<float32>(m_ssw, m_info.address, [this](float32 v) { set_fp(R2, v, F_NONE); });
+ get_dcammu().load<u32>(m_ssw, m_info.address, [this](u32 v) { set_fp(R2, float32_t{ v }, F_NONE); });
// TRAPS: C,U,A,P,R,I
break;
case 0x66:
case 0x67:
// loadd: load double floating
- get_dcammu().load<float64>(m_ssw, m_info.address, [this](float64 v) { set_fp(R2, float64(v), F_NONE); });
+ get_dcammu().load<u64>(m_ssw, m_info.address, [this](u64 v) { set_fp(R2, float64_t{ v }, F_NONE); });
// TRAPS: C,U,A,P,R,I
break;
case 0x68:
@@ -893,13 +874,13 @@ void clipper_device::execute_instruction()
case 0x74:
case 0x75:
// stors: store single floating
- get_dcammu().store<float32>(m_ssw, m_info.address, get_fp32(R2));
+ get_dcammu().store<u32>(m_ssw, m_info.address, get_fp32(R2).v);
// TRAPS: A,P,W,I
break;
case 0x76:
case 0x77:
// stord: store double floating
- get_dcammu().store<float64>(m_ssw, m_info.address, get_fp64(R2));
+ get_dcammu().store<u64>(m_ssw, m_info.address, get_fp64(R2).v);
// TRAPS: A,P,W,I
break;
case 0x78:
@@ -1262,7 +1243,7 @@ void clipper_device::execute_instruction()
m_r[0]--;
m_r[1]++;
- m_r[2] = rotr32(m_r[2], 8);
+ m_r[2] = rotr_32(m_r[2], 8);
}
// TRAPS: P,W
break;
@@ -1317,7 +1298,7 @@ void clipper_device::execute_instruction()
// store fi at sp - 8 * (8 - i)
for (int i = m_info.subopcode & 0x7; i < 8 && !m_exception; i++)
- get_dcammu().store<float64>(m_ssw, m_r[15] - 8 * (8 - i), get_fp64(i));
+ get_dcammu().store<u64>(m_ssw, m_r[15] - 8 * (8 - i), get_fp64(i).v);
// decrement sp after push to allow restart on exceptions
if (!m_exception)
@@ -1330,7 +1311,7 @@ void clipper_device::execute_instruction()
// load fi from sp + 8 * (i - N)
for (int i = m_info.subopcode & 0x7; i < 8 && !m_exception; i++)
- get_dcammu().load<float64>(m_ssw, m_r[15] + 8 * (i - (m_info.subopcode & 0x7)), [this, i](float64 v) { set_fp(i, v, F_NONE); });
+ get_dcammu().load<u64>(m_ssw, m_r[15] + 8 * (i - (m_info.subopcode & 0x7)), [this, i](u64 v) { set_fp(i, float64_t{ v }, F_NONE); });
// increment sp after pop to allow restart on exceptions
if (!m_exception)
@@ -1341,86 +1322,86 @@ void clipper_device::execute_instruction()
// cnvsw: convert single floating to word
m_fp_pc = m_info.pc;
- m_r[m_info.macro & 0xf] = float32_to_int32(get_fp32((m_info.macro >> 4) & 0xf));
+ m_r[m_info.macro & 0xf] = f32_to_i32(get_fp32((m_info.macro >> 4) & 0xf), softfloat_roundingMode, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x31:
// cnvrsw: convert rounding single floating to word (non-IEEE +0.5/-0.5 rounding)
m_fp_pc = m_info.pc;
- if (float32_lt(get_fp32((m_info.macro >> 4) & 0xf), 0))
- m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_sub(get_fp32((m_info.macro >> 4) & 0xf),
- float32_div(int32_to_float32(1), int32_to_float32(2))));
+ if (f32_lt(get_fp32((m_info.macro >> 4) & 0xf), float32_t{ 0 }))
+ m_r[m_info.macro & 0xf] = f32_to_i32(f32_sub(get_fp32((m_info.macro >> 4) & 0xf),
+ f32_div(i32_to_f32(1), i32_to_f32(2))), softfloat_round_minMag, true);
else
- m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_add(get_fp32((m_info.macro >> 4) & 0xf),
- float32_div(int32_to_float32(1), int32_to_float32(2))));
+ m_r[m_info.macro & 0xf] = f32_to_i32(f32_add(get_fp32((m_info.macro >> 4) & 0xf),
+ f32_div(i32_to_f32(1), i32_to_f32(2))), softfloat_round_minMag, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x32:
// cnvtsw: convert truncating single floating to word
m_fp_pc = m_info.pc;
- m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(get_fp32((m_info.macro >> 4) & 0xf));
+ m_r[m_info.macro & 0xf] = f32_to_i32(get_fp32((m_info.macro >> 4) & 0xf), softfloat_round_minMag, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x33:
// cnvws: convert word to single floating
- set_fp(m_info.macro & 0xf, int32_to_float32(m_r[(m_info.macro >> 4) & 0xf]), F_X);
+ set_fp(m_info.macro & 0xf, i32_to_f32(m_r[(m_info.macro >> 4) & 0xf]), F_X);
// TRAPS: F_X
break;
case 0x34:
// cnvdw: convert double floating to word
m_fp_pc = m_info.pc;
- m_r[m_info.macro & 0xf] = float64_to_int32(get_fp64((m_info.macro >> 4) & 0xf));
+ m_r[m_info.macro & 0xf] = f64_to_i32(get_fp64((m_info.macro >> 4) & 0xf), softfloat_roundingMode, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x35:
// cnvrdw: convert rounding double floating to word (non-IEEE +0.5/-0.5 rounding)
m_fp_pc = m_info.pc;
- if (float64_lt(get_fp64((m_info.macro >> 4) & 0xf), 0))
- m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_sub(get_fp64((m_info.macro >> 4) & 0xf),
- float64_div(int32_to_float64(1), int32_to_float64(2))));
+ if (f64_lt(get_fp64((m_info.macro >> 4) & 0xf), float64_t{ 0 }))
+ m_r[m_info.macro & 0xf] = f64_to_i32(f64_sub(get_fp64((m_info.macro >> 4) & 0xf),
+ f64_div(i32_to_f64(1), i32_to_f64(2))), softfloat_round_minMag, true);
else
- m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_add(get_fp64((m_info.macro >> 4) & 0xf),
- float64_div(int32_to_float64(1), int32_to_float64(2))));
+ m_r[m_info.macro & 0xf] = f64_to_i32(f64_add(get_fp64((m_info.macro >> 4) & 0xf),
+ f64_div(i32_to_f64(1), i32_to_f64(2))), softfloat_round_minMag, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x36:
// cnvtdw: convert truncating double floating to word
m_fp_pc = m_info.pc;
- m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(get_fp64((m_info.macro >> 4) & 0xf));
+ m_r[m_info.macro & 0xf] = f64_to_i32(get_fp64((m_info.macro >> 4) & 0xf), softfloat_round_minMag, true);
// TRAPS: F_IX
- float_exception_flags &= F_IX;
+ softfloat_exceptionFlags &= F_IX;
break;
case 0x37:
// cnvwd: convert word to double floating
- set_fp(m_info.macro & 0xf, int32_to_float64(m_r[(m_info.macro >> 4) & 0xf]), F_NONE);
+ set_fp(m_info.macro & 0xf, i32_to_f64(m_r[(m_info.macro >> 4) & 0xf]), F_NONE);
break;
case 0x38:
// cnvsd: convert single to double floating
- set_fp(m_info.macro & 0xf, float32_to_float64(get_fp32((m_info.macro >> 4) & 0xf)), F_I);
+ set_fp(m_info.macro & 0xf, f32_to_f64(get_fp32((m_info.macro >> 4) & 0xf)), F_I);
// TRAPS: F_I
break;
case 0x39:
// cnvds: convert double to single floating
- set_fp(m_info.macro & 0xf, float64_to_float32(get_fp64((m_info.macro >> 4) & 0xf)), F_IVUX);
+ set_fp(m_info.macro & 0xf, f64_to_f32(get_fp64((m_info.macro >> 4) & 0xf)), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x3a:
// negs: negate single floating
- set_fp(m_info.macro & 0xf, float32_mul(get_fp32((m_info.macro >> 4) & 0xf), int32_to_float32(-1)), F_NONE);
+ set_fp(m_info.macro & 0xf, f32_mul(get_fp32((m_info.macro >> 4) & 0xf), i32_to_f32(-1)), F_NONE);
break;
case 0x3b:
// negd: negate double floating
- set_fp(m_info.macro & 0xf, float64_mul(get_fp64((m_info.macro >> 4) & 0xf), int32_to_float64(-1)), F_NONE);
+ set_fp(m_info.macro & 0xf, f64_mul(get_fp64((m_info.macro >> 4) & 0xf), i32_to_f64(-1)), F_NONE);
break;
case 0x3c:
/*
@@ -1433,18 +1414,18 @@ void clipper_device::execute_instruction()
* correct exception flags are set.
*/
// scalbs: scale by, single floating
- set_fp(m_info.macro & 0xf, float32_mul(get_fp32(m_info.macro & 0xf),
+ set_fp(m_info.macro & 0xf, f32_mul(get_fp32(m_info.macro & 0xf),
((s32(m_r[(m_info.macro >> 4) & 0xf]) > -127 && s32(m_r[(m_info.macro >> 4) & 0xf]) < 128)
- ? float32((s32(m_r[(m_info.macro >> 4) & 0xf]) + 127) << 23)
- : float32(~u32(0)))), F_IVUX);
+ ? float32_t{ u32(s32(m_r[(m_info.macro >> 4) & 0xf]) + 127) << 23 }
+ : float32_t{ ~u32(0) })), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x3d:
// scalbd: scale by, double floating
- set_fp(m_info.macro & 0xf, float64_mul(get_fp64(m_info.macro & 0xf),
+ set_fp(m_info.macro & 0xf, f64_mul(get_fp64(m_info.macro & 0xf),
(s32(m_r[(m_info.macro >> 4) & 0xf]) > -1023 && s32(m_r[(m_info.macro >> 4) & 0xf]) < 1024)
- ? float64(u64(s32(m_r[(m_info.macro >> 4) & 0xf]) + 1023) << 52)
- : float64(~u64(0))), F_IVUX);
+ ? float64_t{ u64(s32(m_r[(m_info.macro >> 4) & 0xf]) + 1023) << 52 }
+ : float64_t{ ~u64(0) }), F_IVUX);
// TRAPS: F_IVUX
break;
case 0x3e:
@@ -1804,10 +1785,10 @@ void clipper_device::set_psw(const u32 psw)
// set the softfloat rounding mode based on the psw rounding mode
switch (PSW(FR))
{
- case FR_0: float_rounding_mode = float_round_nearest_even; break;
- case FR_1: float_rounding_mode = float_round_up; break;
- case FR_2: float_rounding_mode = float_round_down; break;
- case FR_3: float_rounding_mode = float_round_to_zero; break;
+ case FR_0: softfloat_roundingMode = softfloat_round_near_even; break;
+ case FR_1: softfloat_roundingMode = softfloat_round_max; break;
+ case FR_2: softfloat_roundingMode = softfloat_round_min; break;
+ case FR_3: softfloat_roundingMode = softfloat_round_minMag; break;
}
}
@@ -1830,31 +1811,31 @@ void clipper_device::fp_exception()
* doesn't explicitly specify, this is a guess. Simply put, exceptions
* are considered in sequence with an increasing order of priority.
*/
- if (float_exception_flags & float_flag_inexact)
+ if (softfloat_exceptionFlags & softfloat_flag_inexact)
{
m_psw |= PSW_FX;
if (PSW(EFX))
exception = EXCEPTION_FLOATING_INEXACT;
}
- if (float_exception_flags & float_flag_underflow)
+ if (softfloat_exceptionFlags & softfloat_flag_underflow)
{
m_psw |= PSW_FU;
if (PSW(EFU))
exception = EXCEPTION_FLOATING_UNDERFLOW;
}
- if (float_exception_flags & float_flag_overflow)
+ if (softfloat_exceptionFlags & softfloat_flag_overflow)
{
m_psw |= PSW_FV;
if (PSW(EFV))
exception = EXCEPTION_FLOATING_OVERFLOW;
}
- if (float_exception_flags & float_flag_divbyzero)
+ if (softfloat_exceptionFlags & softfloat_flag_infinite)
{
m_psw |= PSW_FD;
if (PSW(EFD))
exception = EXCEPTION_FLOATING_DIVIDE_BY_ZERO;
}
- if (float_exception_flags & float_flag_invalid)
+ if (softfloat_exceptionFlags & softfloat_flag_invalid)
{
m_psw |= PSW_FI;
if (PSW(EFI))
@@ -1922,8 +1903,8 @@ void clipper_c400_device::execute_instruction()
case 0x47:
// loadd2: load double floating double
// TODO: 128-bit load
- get_dcammu().load<float64>(m_ssw, m_info.address + 0, [this](float64 v) { set_fp(R2 + 0, v, F_NONE); });
- get_dcammu().load<float64>(m_ssw, m_info.address + 8, [this](float64 v) { set_fp(R2 + 1, v, F_NONE); });
+ get_dcammu().load<u64>(m_ssw, m_info.address + 0, [this](u64 v) { set_fp(R2 + 0, float64_t{ v }, F_NONE); });
+ get_dcammu().load<u64>(m_ssw, m_info.address + 8, [this](u64 v) { set_fp(R2 + 1, float64_t{ v }, F_NONE); });
// TRAPS: C,U,A,P,R,I
break;
@@ -1962,16 +1943,16 @@ void clipper_c400_device::execute_instruction()
case 0xb0:
// abss: absolute value single floating?
- if (float32_lt(get_fp32(R1), 0))
- set_fp(R2, float32_mul(get_fp32(R1), int32_to_float32(-1)), F_IVUX);
+ if (f32_lt(get_fp32(R1), float32_t{ 0 }))
+ set_fp(R2, f32_mul(get_fp32(R1), i32_to_f32(-1)), F_IVUX);
else
set_fp(R2, get_fp32(R1), F_IVUX);
break;
case 0xb2:
// absd: absolute value double floating?
- if (float64_lt(get_fp64(R1), 0))
- set_fp(R2, float64_mul(get_fp64(R1), int32_to_float64(-1)), F_IVUX);
+ if (f64_lt(get_fp64(R1), float64_t{ 0 }))
+ set_fp(R2, f64_mul(get_fp64(R1), i32_to_f64(-1)), F_IVUX);
else
set_fp(R2, get_fp64(R1), F_IVUX);
break;
diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h
index d480100d509..19f51650b3b 100644
--- a/src/devices/cpu/clipper/clipper.h
+++ b/src/devices/cpu/clipper/clipper.h
@@ -6,9 +6,7 @@
#pragma once
-#include <limits.h>
-#include "softfloat/milieu.h"
-#include "softfloat/softfloat.h"
+#include "softfloat3/source/include/softfloat.h"
#include "cpu/clipper/common.h"
#include "machine/cammu.h"
@@ -20,8 +18,8 @@
class clipper_device : public cpu_device
{
public:
- DECLARE_WRITE8_MEMBER(set_ivec) { m_ivec = data; }
- DECLARE_WRITE16_MEMBER(set_exception);
+ void set_ivec(u8 data) { m_ivec = data; }
+ void set_exception(u16 data);
// branch conditions (first description for comparison, second for move/logical)
enum branch_conditions : u8
@@ -142,30 +140,29 @@ public:
enum fp_exception_mask : u8
{
F_NONE = (0),
- F_I = (float_flag_invalid),
- F_X = (float_flag_inexact),
- F_IX = (float_flag_invalid | float_flag_inexact),
- F_IVUX = (float_flag_invalid | float_flag_overflow | float_flag_underflow | float_flag_inexact),
- F_IVDUX = (float_flag_invalid | float_flag_overflow | float_flag_divbyzero | float_flag_underflow | float_flag_inexact)
+ F_I = (softfloat_flag_invalid),
+ F_X = (softfloat_flag_inexact),
+ F_IX = (softfloat_flag_invalid | softfloat_flag_inexact),
+ F_IVUX = (softfloat_flag_invalid | softfloat_flag_overflow | softfloat_flag_underflow | softfloat_flag_inexact),
+ F_IVDUX = (softfloat_flag_invalid | softfloat_flag_overflow | softfloat_flag_infinite | softfloat_flag_underflow | softfloat_flag_inexact)
};
protected:
clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid);
// device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
// device_execute_interface overrides
- virtual u32 execute_min_cycles() const override { return 1; }
- virtual u32 execute_max_cycles() const override { return 1; } // FIXME: don't know, especially macro instructions
- virtual u32 execute_input_lines() const override { return 2; } // number of input/interrupt lines (irq/nmi)
+ virtual u32 execute_min_cycles() const noexcept override { return 1; }
+ virtual u32 execute_max_cycles() const noexcept override { return 1; } // FIXME: don't know, especially macro instructions
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
- virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
+ virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
@@ -207,19 +204,19 @@ protected:
}
// floating point helpers
- float32 get_fp32(const u8 reg) const { return m_f[reg & 0xf]; }
- float64 get_fp64(const u8 reg) const { return m_f[reg & 0xf]; }
- template <typename T> void set_fp(const u8 reg, const T data, const fp_exception_mask exception_mask)
+ float32_t get_fp32(u8 const reg) const { return float32_t{ u32(m_f[reg & 0xf]) }; }
+ float64_t get_fp64(u8 const reg) const { return float64_t{ m_f[reg & 0xf] }; }
+ template <typename T> void set_fp(u8 const reg, T const data, fp_exception_mask const exception_mask)
{
// suppress unexpected exceptions
- float_exception_flags &= exception_mask;
+ softfloat_exceptionFlags &= exception_mask;
// save floating exception state
m_fp_pc = m_pc;
m_fp_dst = m_f[reg & 0xf];
// assign data
- if (float_exception_flags & float_flag_overflow && PSW(EFV))
+ if (softfloat_exceptionFlags & softfloat_flag_overflow && PSW(EFV))
{
/*
* If the EFV flag is set, the computed result is delivered to the
@@ -241,9 +238,9 @@ protected:
* Standard wrapped exponent.
*/
// FIXME: implement non-IEEE behaviour described above
- m_f[reg & 0xf] = data;
+ m_f[reg & 0xf] = data.v;
}
- else if (float_exception_flags & float_flag_underflow && PSW(EFU))
+ else if (softfloat_exceptionFlags & softfloat_flag_underflow && PSW(EFU))
{
/*
* If EFU is set, the floating underflow exception is signalled
@@ -260,10 +257,10 @@ protected:
* is 0..-275; for double-precision the range is 0..-1125.
*/
// FIXME: implement non-IEEE behaviour described above
- m_f[reg & 0xf] = data;
+ m_f[reg & 0xf] = data.v;
}
else
- m_f[reg & 0xf] = data;
+ m_f[reg & 0xf] = data.v;
// set floating dirty flag
m_ssw |= SSW_FRD;
@@ -359,7 +356,7 @@ public:
protected:
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
virtual u32 intrap(const u16 vector, const u32 old_pc) override;
diff --git a/src/devices/cpu/clipper/clipperd.cpp b/src/devices/cpu/clipper/clipperd.cpp
index 5af39805227..17969d4da26 100644
--- a/src/devices/cpu/clipper/clipperd.cpp
+++ b/src/devices/cpu/clipper/clipperd.cpp
@@ -150,22 +150,22 @@ offs_t clipper_disassembler::disassemble(std::ostream &stream, offs_t pc, const
case 0x46: util::stream_format(stream, "loadd2 (r%d),f%d", R1, R2); bytes = 2; break;
case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
#endif
- case 0x48: util::stream_format(stream, "b%-4s (r%d)", cc[R2], R1); bytes = 2; break;
- case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
+ case 0x48: util::stream_format(stream, "b%-4s (r%d)", cc[R2], R1); bytes = 2; if (R2 != 0) flags |= STEP_COND; break;
+ case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; if (ADDR_R2 != 0) flags |= STEP_COND; break;
#if C400_INSTRUCTIONS
// delayed branches
- case 0x4a: util::stream_format(stream, "cdb r%d,(r%d)", R2, R1); bytes = 2; break;
- case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
- case 0x4c: util::stream_format(stream, "cdbeq r%d,(r%d)", R2, R1); bytes = 2; break;
- case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
- case 0x4e: util::stream_format(stream, "cdbne r%d,(r%d)", R2, R1); bytes = 2; break;
- case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
- case 0x50: util::stream_format(stream, "db%-4s (r%d)", cc[R2], R1); bytes = 2; break;
- case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
+ case 0x4a: util::stream_format(stream, "cdb r%d,(r%d)", R2, R1); bytes = 2; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x4c: util::stream_format(stream, "cdbeq r%d,(r%d)", R2, R1); bytes = 2; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x4e: util::stream_format(stream, "cdbne r%d,(r%d)", R2, R1); bytes = 2; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_COND | step_over_extra(2); break;
+ case 0x50: util::stream_format(stream, "db%-4s (r%d)", cc[R2], R1); bytes = 2; if (R2 != 0) flags |= STEP_COND | step_over_extra(2); break;
+ case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; if (ADDR_R2 != 0) flags |= STEP_COND | step_over_extra(2); break;
#else
// these instructions are in the C300 documentation, but appear to be replaced in the C400
- case 0x4c: util::stream_format(stream, "bf%s (r%d)", R2 == 0 ? "any" : "bad", R1); bytes = 2; break;
- case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break;
+ case 0x4c: util::stream_format(stream, "bf%s (r%d)", R2 == 0 ? "any" : "bad", R1); bytes = 2; flags |= STEP_COND; break;
+ case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_COND; break;
#endif
case 0x60: util::stream_format(stream, "loadw (r%d),r%d", R1, R2); bytes = 2; break;
diff --git a/src/devices/cpu/clipper/clipperd.h b/src/devices/cpu/clipper/clipperd.h
index cac65afdf93..5db8a4ed2f4 100644
--- a/src/devices/cpu/clipper/clipperd.h
+++ b/src/devices/cpu/clipper/clipperd.h
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay
-#ifndef MAME_CPU_CLIPPER_CLIPPERDASM_H
-#define MAME_CPU_CLIPPER_CLIPPERDASM_H
+#ifndef MAME_CPU_CLIPPER_CLIPPERD_H
+#define MAME_CPU_CLIPPER_CLIPPERD_H
#pragma once
@@ -20,4 +20,4 @@ private:
std::string address (offs_t pc, const data_buffer &opcodes);
};
-#endif
+#endif // MAME_CPU_CLIPPER_CLIPPERD_H