summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/wtl3132.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/wtl3132.cpp')
-rw-r--r--src/devices/machine/wtl3132.cpp52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/devices/machine/wtl3132.cpp b/src/devices/machine/wtl3132.cpp
index 7fdfc61a8b3..c5d3aeb02f9 100644
--- a/src/devices/machine/wtl3132.cpp
+++ b/src/devices/machine/wtl3132.cpp
@@ -16,7 +16,6 @@
#include "emu.h"
#include "wtl3132.h"
-#define LOG_GENERAL (1U << 0)
#define LOG_REGS (1U << 1)
#define LOG_IO (1U << 2)
#define LOG_BYPASS (1U << 3)
@@ -42,11 +41,6 @@ wtl3132_device::wtl3132_device(machine_config const &mconfig, char const *tag, d
void wtl3132_device::device_start()
{
- m_fpcn_cb.resolve_safe();
- m_fpex_cb.resolve_safe();
- m_zero_cb.resolve_safe();
- m_port_x_cb.resolve_safe();
-
save_item(NAME(m_fpcn_state));
save_item(NAME(m_fpex_state));
save_item(NAME(m_zero_state));
@@ -323,14 +317,27 @@ void wtl3132_device::stage3(unsigned const index)
m_cr = (m_aa_in[1].v & 0xff000000) && (~m_aa_in[1].v & 0xff000000);
m_a_out = i32_to_f32(m_aa_in[1].v);
+
+ /*
+ * HACK: documentation specifies that the float instruction sets
+ * the condition register when ENCN=1, M1=1 and the operand sign
+ * bits are inconsistent. It does not say what should happen for
+ * other values of ENCN, however setting the condition register to
+ * indicate the result is less than zero like other ALU operations
+ * appears to be required by the SGI GR1 DMA microcode (and some
+ * other assumptions made there).
+ */
+ if (OPF(code, ENCN) == 2)
+ m_cr = f32_lt(m_a_out, i32_to_f32(0));
+
LOG("slot %d stage 3 float 0x%08x == %f\n", index, m_aa_in[1].v, u2f(m_a_out.v));
break;
case MF_FIX:
if ((m_mode & MODE_RTN) && OPF(code, ENCN) == 1)
m_cr = f32_lt(m_aa_in[1], i32_to_f32(-4194304)) || f32_lt(i32_to_f32(4194304), m_aa_in[1]);
- m_a_out.v = (f32_to_i32(m_aa_in[1], (m_mode & MODE_RTN) ?
- softfloat_round_near_even : softfloat_round_min, false) << 8) >> 8;
+ m_a_out.v = util::sext(f32_to_i32(m_aa_in[1], (m_mode & MODE_RTN) ?
+ softfloat_round_near_even : softfloat_round_min, false), 24);
LOG("slot %d stage 3 fix %f == 0x%08x\n", index, u2f(m_aa_in[1].v), m_a_out.v);
break;
case MF_FLUT:
@@ -441,37 +448,38 @@ std::string wtl3132_device::disassemble(u64 const code)
case MF_FSTSR: alu = std::string("fstsr"); break;
case MF_FMODE: alu = util::string_format("fmode 0x%04x", (OPF(code, ABIN) << 10) | (OPF(code, CADD) << 5) | OPF(code, AADD)); break;
- case MF_FABS: alu = util::string_format("fabs %4s, %-12s", reg(OPF(code, AADD)), adst(code)); break;
- case MF_FLOAT: alu = util::string_format("float %4s, %-12s", reg(OPF(code, AADD)), adst(code)); break;
- case MF_FIX: alu = util::string_format("fix %4s, %-12s", reg(OPF(code, AADD)), adst(code)); break;
- case MF_FLUT: alu = util::string_format("flut %4s, %-4s", reg(OPF(code, AADD)), reg(OPF(code, CADD))); break;
+ case MF_FABS: alu = util::string_format("fabs %4s, %s", reg(OPF(code, AADD)), adst(code)); break;
+ case MF_FLOAT: alu = util::string_format("float %4s, %s", reg(OPF(code, AADD)), adst(code)); break;
+ case MF_FIX: alu = util::string_format("fix %4s, %s", reg(OPF(code, AADD)), adst(code)); break;
+ case MF_FLUT: alu = util::string_format("flut %4s, %s", reg(OPF(code, AADD)), reg(OPF(code, CADD))); break;
}
break;
- case F_FSUBR: alu = util::string_format("fsubr %4s, %4s, %-12s", reg(OPF(code, AADD)), abin(code), adst(code)); break;
+ case F_FSUBR: alu = util::string_format("fsubr %4s, %4s, %s", reg(OPF(code, AADD)), abin(code), adst(code)); break;
case F_FSUB:
if (!OPF(code, CWEN) || OPF(code, ADST) != 3 || OPF(code, ENCN))
- alu = util::string_format("fsub %4s, %4s, %-12s", reg(OPF(code, AADD)), abin(code), adst(code));
+ alu = util::string_format("fsub %4s, %4s, %s", reg(OPF(code, AADD)), abin(code), adst(code));
else
alu = std::string("fnop");
break;
case F_FADD:
- if (!OPF(code, CWEN) || OPF(code, ADST) != 3 || OPF(code, ENCN) || OPF(code, ABIN) != 7)
- alu = util::string_format("fadd %4s, %4s, %-12s", reg(OPF(code, AADD)), abin(code), adst(code));
+ // FIXME: unsure if write enable is masked externally?
+ if (OPF(code, ADST) != 3 || OPF(code, ENCN) || OPF(code, ABIN) != 7) // !OPF(code, CWEN) ||
+ alu = util::string_format("fadd %4s, %4s, %s", reg(OPF(code, AADD)), abin(code), adst(code));
else
alu = std::string("fnop");
break;
- case F_FMNA: alu = util::string_format("fmna %4s, %4s, %4s, %-12s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
- case F_FMNS: alu = util::string_format("fmns %4s, %4s, %4s, %-12s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
- case F_FMAC: alu = util::string_format("fmac %4s, %4s, %4s, %-12s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
+ case F_FMNA: alu = util::string_format("fmna %4s, %4s, %4s, %s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
+ case F_FMNS: alu = util::string_format("fmns %4s, %4s, %4s, %s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
+ case F_FMAC: alu = util::string_format("fmac %4s, %4s, %4s, %s", reg(OPF(code, AADD)), mbin(code), abin(code), adst(code)); break;
}
switch (OPF(code, IOCT))
{
- case 1: return util::string_format("%-38s ; floadrc %4s", alu, reg(OPF(code, DADD))); break;
- case 2: return util::string_format("%-38s ; fstore %4s", alu, reg(OPF(code, DADD))); break;
- case 3: return util::string_format("%-38s ; fload %4s", alu, reg(OPF(code, DADD))); break;
+ case 1: return util::string_format("%s; floadrc %4s", alu, reg(OPF(code, DADD))); break;
+ case 2: return util::string_format("%s; fstore %4s", alu, reg(OPF(code, DADD))); break;
+ case 3: return util::string_format("%s; fload %4s", alu, reg(OPF(code, DADD))); break;
default:
return alu;
}