diff --git a/toolbox/CMakeLists.txt b/toolbox/CMakeLists.txt index 7148c19..e789a08 100644 --- a/toolbox/CMakeLists.txt +++ b/toolbox/CMakeLists.txt @@ -10,6 +10,7 @@ set(TOOLBOX_SRC mm.cpp os.cpp qd.cpp + sane.cpp ) diff --git a/toolbox/sane.cpp b/toolbox/sane.cpp new file mode 100644 index 0000000..c2bf52f --- /dev/null +++ b/toolbox/sane.cpp @@ -0,0 +1,122 @@ +#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; + } +} \ No newline at end of file diff --git a/toolbox/sane.h b/toolbox/sane.h new file mode 100644 index 0000000..ce7fc79 --- /dev/null +++ b/toolbox/sane.h @@ -0,0 +1,11 @@ +#ifndef __mpw_sane_h__ +#define __mpw_sane_h__ + +#include + +namespace SANE +{ + + uint16_t fp68k(uint16_t trap); +} +#endif diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 0ed57c7..01dbcd3 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -12,6 +12,7 @@ #include "mm.h" #include "os.h" #include "qd.h" +#include "sane.h" // yuck. TST.W d0 @@ -183,6 +184,11 @@ namespace ToolBox { break; + // sane + case 0xa9Eb: + d0 = SANE::fp68k(trap); + break; + default: fprintf(stderr, "Unsupported tool trap: %04x\n", trap); fprintf(stderr, "pc: %08x\n", cpuGetPC());