#include "qd.h" #include "toolbox.h" #include #include #include #include #include "stackframe.h" using ToolBox::Log; namespace SANE { double to_double(uint64_t x) { return *((double *)&x); } uint64_t to_int64(double d) { return *((uint64_t *)&d); } uint16_t fl2x() { // long to extended (80-bit fp) uint16_t op; uint32_t dest; uint32_t src; StackFrame<10>(src, dest, op); //80-bit isn't popular anymore, so convert to double (64-bit) Log(" FL2X(%08x, %08x, %084x)\n", src, dest, op); int32_t i = memoryReadLong(src); double d = (double)i; int64_t i64 = to_int64(d); memoryWriteLongLong(i64, dest); memoryWriteWord(0, dest + 8); return 0; } uint16_t fdivx() { // div extended (80-bit fp) uint16_t op; uint32_t dest; uint32_t src; StackFrame<10>(src, dest, op); //80-bit isn't popular anymore, so convert to double (64-bit) Log(" FDIVX(%08x, %08x, %084x)\n", src, dest, op); uint64_t si = memoryReadLongLong(src); uint64_t di = memoryReadLongLong(dest); double sd = to_double(si); double dd = to_double(di); // dest = dest / src dd = dd / sd; di = to_int64(dd); memoryWriteLongLong(di, dest); memoryWriteWord(0, dest + 8); return 0; } uint16_t fx2dec() { // extended (80-bit fp) to decimal // convert a to d based on decform f uint16_t op; uint32_t f_adr; uint32_t a_adr; uint32_t d_adr; StackFrame<14>(f_adr, a_adr, d_adr, op); uint64_t si = memoryReadLongLong(a_adr); double sd = to_double(si); // ugh, really don't want to write this code right now. memoryWriteWord(0, d_adr); memoryWriteWord(0, d_adr + 2); memoryWriteWord(0, d_adr + 4); return 0; } uint16_t fp68k(uint16_t trap) { uint16_t op; uint32_t sp = cpuGetAReg(7); op = memoryReadWord(sp); Log("%04x FP68K(%04x)\n", op); if (op == 0x0006) return fdivx(); if (op == 0x000b) return fx2dec(); if (op == 0x280e) return fl2x(); fprintf(stderr, "fp68k -- op %04x is not yet supported\n", op); exit(1); return 0; } }