mpw/toolbox/sane.cpp
2013-02-20 23:28:13 -05:00

122 lines
2.1 KiB
C++

#include "qd.h"
#include "toolbox.h"
#include <cpu/defs.h>
#include <cpu/CpuModule.h>
#include <cpu/fmem.h>
#include <stdlib.h>
#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;
}
}