diff --git a/_work/target_options.h b/_work/target_options.h index 35072fd..a0b1364 100644 --- a/_work/target_options.h +++ b/_work/target_options.h @@ -4,7 +4,7 @@ // Max VRAM on Mac II(x) is 2MiB // Supported Macintosh models -enum MacModel { +typedef enum MacModel { mdl_Twig43, // Twiggy prototype (ROM 4.3T 07/04/83) mdl_Twiggy, // Twiggy prototype (later) mdl_m128K, // 128K @@ -17,10 +17,10 @@ enum MacModel { mdl_PB100, // PowerBook 100 mdl_II, // II mdl_IIx // IIx -}; +} MacModel_t; // Supported ROM types -enum MacROM { +typedef enum MacROM { rom_Twig43, // ROM 4.3T 07/04/83 rom_Twiggy, // Twiggy prototype (later) rom_64K, // 128K/512K @@ -30,41 +30,41 @@ enum MacROM { rom_IIx, // Mac II FDHD, IIx, IIcx rom_PB100, // PowerBook 100 rom_Classic // Mac Classic -}; +} MacROM_t; -enum M68KType { +typedef enum M68KType { m68000, m68020, m68020FPU -}; +} M68KType_t; // ROM information. Duplicate MacROMs are alternate ROMS also supported struct MacROMInfo { - enum MacROM; + MacROM_t rom; uint32_t cksum; uint32_t size; }; const struct MacROMInfo MacROMInfoTable[] = { - {rom_Twig43, 0x27F4E04B, 2 << 16}, - {rom_Twiggy, 0x2884371D, 2 << 16}, - {rom_64K, 0x28BA61CE, 2 << 16}, // Mac 128K (?) - {rom_64K, 0x28BA4E50, 2 << 16}, // Mac 512K (?) - {rom_128K, 0x4D1EEEE1, 2 << 17}, // v1, 'Lonely Hearts' - {rom_128K, 0x4D1EEAE1, 2 << 17}, // v2, 'Lonely Heifers' - {rom_128K, 0x4D1F8172, 2 << 17}, // v3, 'Loud Harmonicas' - {rom_SE, 0xB2E362A8, 2 << 18}, - {rom_II, 0x97851DB6, 2 << 18}, // v1 - {rom_II, 0x9779D2C4, 2 << 18}, // v2 - {rom_IIx, 0x97221136, 2 << 18}, - {rom_PB100, 0x96645F9C, 2 << 18} + {rom_Twig43, 0x27F4E04B, 1 << 16}, + {rom_Twiggy, 0x2884371D, 1 << 16}, + {rom_64K, 0x28BA61CE, 1 << 16}, // Mac 128K (?) + {rom_64K, 0x28BA4E50, 1 << 16}, // Mac 512K (?) + {rom_128K, 0x4D1EEEE1, 1 << 17}, // v1, 'Lonely Hearts' + {rom_128K, 0x4D1EEAE1, 1 << 17}, // v2, 'Lonely Heifers' + {rom_128K, 0x4D1F8172, 1 << 17}, // v3, 'Loud Harmonicas' + {rom_SE, 0xB2E362A8, 1 << 18}, + {rom_II, 0x97851DB6, 1 << 18}, // v1 + {rom_II, 0x9779D2C4, 1 << 18}, // v2 + {rom_IIx, 0x97221136, 1 << 18}, + {rom_PB100, 0x96645F9C, 1 << 18} }; // Model information // We're using base models for RAM and such; no addons struct MacModelInfo { - enum MacModel; - enum MacROM; - enum M68KType; + MacModel_t MacModel; + MacROM_t MacROM; + M68KType_t M68KType; uint32_t RAMaSize; // RAM in first address space (?) uint32_t RAMbSize; uint32_t RAMvidSize; // External video RAM size @@ -88,14 +88,14 @@ const struct MacModelInfo MacModelInfoTable[] = { .MacModel = mdl_Twig43, .MacROM = rom_Twig43, .M68KType = m68000, - .RAMaSize = 2 >> 16, + .RAMaSize = 2 << 16, .RAMbSize = 0, .RAMvidSize = 0, .hres = 512, .vres = 384, .bpp = 1, .MaxATTListN = 16, - .ClockMult = 1, + .ClockSpeed = 1, .ADB = false, .RTC = false, .PMU = false, @@ -109,13 +109,13 @@ const struct MacModelInfo MacModelInfoTable[] = { .MacROM = rom_Twiggy, .M68KType = m68000, .RAMaSize = 2 >> 16, - .RAMbSize = 0, + <> 16, .RAMbSize = 0, @@ -135,7 +135,7 @@ const struct MacModelInfo MacModelInfoTable[] = { .vres = 384, .bpp = 1, .MaxATTListN = 16, - .ClockMult = 1, + .ClockSpeed = 1, .ADB = false, .RTC = false, .PMU = false, @@ -146,7 +146,7 @@ const struct MacModelInfo MacModelInfoTable[] = { // 512K { .MacModel = mdl_m512K, - .MacROM = rom_64k, + .MacROM = rom_64K, .M68KType = m68000, .RAMaSize = 2 >> 19, .RAMbSize = 0, @@ -155,7 +155,7 @@ const struct MacModelInfo MacModelInfoTable[] = { .vres = 384, .bpp = 1, .MaxATTListN = 16, - .ClockMult = 1, + .ClockSpeed = 1, .ADB = false, .RTC = false, .PMU = false, @@ -166,7 +166,7 @@ const struct MacModelInfo MacModelInfoTable[] = { // 512Ke { .MacModel = mdl_m512Ke, - .MacROM = rom_128k, + .MacROM = rom_128K, .M68KType = m68000, .RAMaSize = 2 >> 19, .RAMbSize = 0, @@ -175,7 +175,7 @@ const struct MacModelInfo MacModelInfoTable[] = { .vres = 384, .bpp = 1, .MaxATTListN = 16, - .ClockMult = 1, + .ClockSpeed = 1, .ADB = false, .RTC = false, .PMU = false, @@ -186,7 +186,7 @@ const struct MacModelInfo MacModelInfoTable[] = { // Plus { .MacModel = mdl_Plus, - .MacROM = rom_128k, + .MacROM = rom_128K, .M68KType = m68000, .RAMaSize = 2 >> 19, // same RAM for SE, SEFDHD, Classic .RAMbSize = 2 >> 19, @@ -195,7 +195,7 @@ const struct MacModelInfo MacModelInfoTable[] = { .vres = 384, .bpp = 1, .MaxATTListN = 16, - .ClockMult = 1, + .ClockSpeed = 1, .ADB = false, .RTC = false, .PMU = false, @@ -215,7 +215,7 @@ const struct MacModelInfo MacModelInfoTable[] = { .vres = 480, .bpp = 8, .MaxATTListN = 20, - .ClockMult = 2, + .ClockSpeed = 2, .ADB = false, .RTC = false, .PMU = false, diff --git a/cfg/EMCONFIG.h b/cfg/EMCONFIG.h index 0a85218..41868be 100644 --- a/cfg/EMCONFIG.h +++ b/cfg/EMCONFIG.h @@ -39,8 +39,6 @@ #define MKC_formac_RShift MKC_Shift #define MKC_UnMappedKey MKC_Control -#define CurEmMd kEmMd_Plus - #define MaxATTListN 32 #define IncludeExtnPbufs 1 // temporary @@ -57,11 +55,13 @@ #define AutoKeyThresh 0x06 #define AutoKeyRate 0x03 -#if (CurEmMd == kEmMd_Plus) -#include "MACPLUS.h" -#elif (CurEmMd == kEmMd_II) +#define CurEmMd kEmMd_II + +//#if (CurEmMd == kEmMd_Plus) +//#include "MACPLUS.h" +//#elif (CurEmMd == kEmMd_II) #include "MACII.h" -#endif +//#endif #define WantDisasm 0 #define ExtraAbnormalReports 0 diff --git a/cfg/MACII.h.bak b/cfg/MACII.h similarity index 94% rename from cfg/MACII.h.bak rename to cfg/MACII.h index 1595685..51e7e68 100644 --- a/cfg/MACII.h.bak +++ b/cfg/MACII.h @@ -7,17 +7,20 @@ you know what you're doing. */ -//#define EmClassicKbrd 0 -//#define EmADB 1 -//#define EmRTC 1 -//#define EmPMU 0 -//#define EmVIA2 1 +#pragma once + +#define EmClassicKbrd 0 +#define EmADB 1 +#define EmRTC 1 +#define EmPMU 0 +#define EmVIA2 1 #define Use68020 1 -#define EmFPU 1 +//#define EmFPU 1 //temporarily disable, because it's broken +#define EmFPU 0 #define EmMMU 0 #define EmASC 1 -#define kMyClockMult 2 +#define ClockMult 2 #define WantCycByPriOp 0 #define WantCloserCyc 0 @@ -36,6 +39,11 @@ #define EmVidCard 1 #define kVidROM_Size 0x000800 +#define RomFileName "MacII.ROM" +#define kRomCheckSum1 0x97851DB +#define kRomCheckSum2 0x9779D2C +#define kROM_Size (1 << 18) + /* the Wire variables are 1/0, not true/false */ enum { diff --git a/meson.build b/meson.build index 6a4f9a0..a3e6e76 100644 --- a/meson.build +++ b/meson.build @@ -78,6 +78,7 @@ HW_SRC = { # 'src/HW/M68K/DISAM68K.c', 'src/HW/M68K/M68KITAB.c', 'src/HW/M68K/MINEM68K.c', +# 'src/HW/M68K/FPCPEMDV.c', ], 'MOUSE': [ 'src/HW/MOUSE/MOUSEMDV.c', @@ -99,9 +100,11 @@ HW_SRC = { 'src/HW/SCSI/SCSIEMDV.c', ], 'SOUND': [ -# 'src/HW/SOUND/ASCEMDEV.c', 'src/HW/SOUND/SNDEMDEV.c', ], + 'SOUND_ASC': [ + 'src/HW/SOUND/ASCEMDEV.c', + ], 'VIA1': [ 'src/HW/VIA/VIAEMDEV.c', ], @@ -113,21 +116,19 @@ HW_SRC = { ], } -MAC_SRC_COMMON = HW_SRC['DISK'] + HW_SRC['M68K'] + HW_SRC['RTC'] + HW_SRC['SOUND'] + HW_SRC['VIA1'] +MAC_SRC_COMMON = HW_SRC['DISK'] + HW_SRC['M68K'] + HW_SRC['RTC'] + HW_SRC['SOUND'] + HW_SRC['VIA1'] + HW_SRC['SCREEN'] + HW_SRC['SCC'] + HW_SRC['SCSI'] + HW_SRC['MOUSE'] # Macintosh definitions MAC_SRC = { 'Plus': MAC_SRC_COMMON + - HW_SRC['SCREEN'] + - HW_SRC['SCC'] + - HW_SRC['SCSI'] + - HW_SRC['MOUSE'] + HW_SRC['KBRD'], 'II': MAC_SRC_COMMON + HW_SRC['VIDCARD'] + - HW_SRC['ADB'], + HW_SRC['ADB'] + + HW_SRC['VIA2'] + + HW_SRC['SOUND_ASC'] } # User interface definitions @@ -165,7 +166,7 @@ EMU_INC = include_directories([ # Just gonna do an SDL2 Mac Plus for now executable( 'microvmac', - sources: MAC_SRC['Plus'] + UI_SRC + EMU_SRC, + sources: MAC_SRC['II'] + UI_SRC + EMU_SRC, dependencies: [lSDL2], include_directories: EMU_INC, ) diff --git a/src/HW/ADB/ADBEMDEV.c b/src/HW/ADB/ADBEMDEV.c index 1025618..aa35536 100644 --- a/src/HW/ADB/ADBEMDEV.c +++ b/src/HW/ADB/ADBEMDEV.c @@ -18,8 +18,6 @@ Apple Desktop Bus EMulated DEVice */ -#if EmADB - #ifndef AllFiles #include "EMCONFIG.h" #include "SYSDEPNS.h" @@ -214,5 +212,3 @@ GLOBALPROC ADB_Update(void) } } } - -#endif diff --git a/src/HW/M68K/FPCPEMDV.c b/src/HW/M68K/FPCPEMDV.c new file mode 100644 index 0000000..1f891c2 --- /dev/null +++ b/src/HW/M68K/FPCPEMDV.c @@ -0,0 +1,1222 @@ +/* + FPCPEMDV.h + + Copyright (C) 2007 Ross Martin, Paul C. Pratt + + You can redistribute this file and/or modify it under the terms + of version 2 of the GNU General Public License as published by + the Free Software Foundation. You should have received a copy + of the license along with this file; see the file COPYING. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + license for more details. +*/ + +/* + Floating Point CoProcessor Emulated Device + Emulates a MC68881 math co-processor + (included by MINEM68K.c) +*/ + +#include "SYSDEPNS.h" +#include "GLOBGLUE.h" + +/* + ReportAbnormalID unused 0x0306 - 0x03FF +*/ + + +LOCALVAR struct fpustruct +{ + myfpr fp[8]; + CPTR FPIAR; /* Floating point instruction address register */ +} fpu_dat; + +LOCALPROC myfp_SetFPIAR(uint32_t v) +{ + fpu_dat.FPIAR = v; +} + +LOCALFUNC uint32_t myfp_GetFPIAR(void) +{ + return fpu_dat.FPIAR; +} + +LOCALFUNC bool DecodeAddrModeRegister(uint32_t sz) +{ + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + uint16_t themode = (Dat >> 3) & 7; + uint16_t thereg = Dat & 7; + + switch (themode) { + case 2 : + case 3 : + case 4 : + case 5 : + case 6 : + return DecodeModeRegister(sz); + break; + case 7 : + switch (thereg) { + case 0 : + case 1 : + case 2 : + case 3 : + case 4 : + return DecodeModeRegister(sz); + break; + default : + return false; + break; + } + break; + default : + return false; + break; + } +} + +LOCALPROC read_long_double(uint32_t addr, myfpr *r) +{ + uint16_t v2; + uint32_t v1; + uint32_t v0; + + v2 = get_word(addr + 0); + /* ignore word at offset 2 */ + v1 = get_long(addr + 4); + v0 = get_long(addr + 8); + + myfp_FromExtendedFormat(r, v2, v1, v0); +} + +LOCALPROC write_long_double(uint32_t addr, myfpr *xx) +{ + uint16_t v2; + uint32_t v1; + uint32_t v0; + + myfp_ToExtendedFormat(xx, &v2, &v1, &v0); + + put_word(addr + 0, v2); + put_word(addr + 2, 0); + put_long(addr + 4, v1); + put_long(addr + 8, v0); +} + +LOCALPROC read_double(uint32_t addr, myfpr *r) +{ + uint32_t v1; + uint32_t v0; + + v1 = get_long(addr + 0); + v0 = get_long(addr + 4); + + myfp_FromDoubleFormat(r, v1, v0); +} + +LOCALPROC write_double(uint32_t addr, myfpr *dd) +{ + uint32_t v1; + uint32_t v0; + + myfp_ToDoubleFormat(dd, &v1, &v0); + + put_long(addr + 0, v1); + put_long(addr + 4, v0); +} + +#if 0 +LOCALPROC read_single(uint32_t addr, myfpr *r) +{ + myfp_FromSingleFormat(r, get_long(addr)); +} + +LOCALPROC write_single(uint32_t addr, myfpr *ff) +{ + put_long(addr, myfp_ToSingleFormat(ff)); +} +#endif + + +LOCALFUNC int CheckFPCondition(uint16_t predicate) +{ + int condition_true = 0; + + uint8_t cc = myfp_GetConditionCodeByte(); + + int c_nan = (cc) & 1; + /* int c_inf = (cc >> 1) & 1; */ + int c_zero = (cc >> 2) & 1; + int c_neg = (cc >> 3) & 1; + + /* + printf( + "FPSR Checked: c_nan=%d, c_zero=%d, c_neg=%d," + " predicate=0x%04x\n", + c_nan, c_zero, c_neg, predicate); + */ + + switch (predicate) { + case 0x11: /* SEQ */ + case 0x01: /* EQ */ + condition_true = c_zero; + break; + case 0x1E: /* SNE */ + case 0x0E: /* NE */ + condition_true = ! c_zero; + break; + case 0x02: /* OGT */ + case 0x12: /* GT */ + condition_true = (! c_neg) && (! c_zero) && (! c_nan); + break; + case 0x0D: /* ULE */ + case 0x1D: /* NGT */ + condition_true = c_neg || c_zero || c_nan; + break; + case 0x03: /* OGE */ + case 0x13: /* GE */ + condition_true = c_zero || ((! c_neg) && (! c_nan)); + break; + case 0x0C: /* ULT */ + case 0x1C: /* NGE */ + condition_true = c_nan || ((! c_zero) && c_neg) ; + break; + case 0x04: /* OLT */ + case 0x14: /* LT */ + condition_true = c_neg && (! c_nan) && (! c_zero); + break; + case 0x0B: /* UGE */ + case 0x1B: /* NLT */ + condition_true = c_nan || c_zero || (! c_neg); + break; + case 0x05: /* OLE */ + case 0x15: /* LE */ + condition_true = ((! c_nan) && c_neg) || c_zero; + break; + case 0x0A: /* UGT */ + case 0x1A: /* NLE */ + condition_true = c_nan || ((! c_neg) && (! c_zero)); + break; + case 0x06: /* OGL */ + case 0x16: /* GL */ + condition_true = (! c_nan) && (! c_zero); + break; + case 0x09: /* UEQ */ + case 0x19: /* NGL */ + condition_true = c_nan || c_zero; + break; + case 0x07: /* OR */ + case 0x17: /* GLE */ + condition_true = ! c_nan; + break; + case 0x08: /* NGLE */ + case 0x18: /* NGLE */ + condition_true = c_nan; + break; + case 0x00: /* SFALSE */ + case 0x10: /* FALSE */ + condition_true = 0; + break; + case 0x0F: /* STRUE */ + case 0x1F: /* TRUE */ + condition_true = 1; + break; + } + + /* printf("condition_true=%d\n", condition_true); */ + + return condition_true; +} + +LOCALIPROC DoCodeFPU_dflt(void) +{ + ReportAbnormalID(0x0301, + "unimplemented Floating Point Instruction"); +#if dbglog_HAVE + { + uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) + | V_regs.CurDecOpY.v[0].ArgDat; + + dbglog_writelnNum("opcode", opcode); + } +#endif + DoCodeFdefault(); +} + +LOCALIPROC DoCodeFPU_Save(void) +{ + uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) + | V_regs.CurDecOpY.v[0].ArgDat; + if ((opcode == 0xF327) || (opcode == 0xF32D)) { +#if 0 + DecodeModeRegister(4); + SetArgValueL(0); /* for now, try null state frame */ +#endif + /* 28 byte 68881 IDLE frame */ + + if (! DecodeAddrModeRegister(28)) { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeAddrModeRegister fails in DoCodeFPU_Save"); +#endif + } else { + put_long(V_regs.ArgAddr.mem, 0x1f180000); + put_long(V_regs.ArgAddr.mem + 4, 0); + put_long(V_regs.ArgAddr.mem + 8, 0); + put_long(V_regs.ArgAddr.mem + 12, 0); + put_long(V_regs.ArgAddr.mem + 16, 0); + put_long(V_regs.ArgAddr.mem + 20, 0); + put_long(V_regs.ArgAddr.mem + 24, 0x70000000); + } + + } else { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln("unimplemented FPU Save"); +#endif + } +} + +LOCALIPROC DoCodeFPU_Restore(void) +{ + uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) + | V_regs.CurDecOpY.v[0].ArgDat; + uint16_t themode = (opcode >> 3) & 7; + uint16_t thereg = opcode & 7; + if ((opcode == 0xF35F) || (opcode == 0xF36D)) { + uint32_t dstvalue; + + if (! DecodeAddrModeRegister(4)) { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeAddrModeRegister fails in DoCodeFPU_Restore"); +#endif + } else { + dstvalue = get_long(V_regs.ArgAddr.mem); + if (dstvalue != 0) { + if (0x1f180000 == dstvalue) { + if (3 == themode) { + m68k_areg(thereg) = V_regs.ArgAddr.mem + 28; + } + } else { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln("unknown restore"); + /* not a null state we saved */ +#endif + } + } + } + } else { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln("unimplemented FPU Restore"); +#endif + } +} + +LOCALIPROC DoCodeFPU_FBccW(void) +{ + /* + Also get here for a NOP instruction (opcode 0xF280), + which is simply a FBF.w with offset 0 + */ + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + + if (CheckFPCondition(Dat & 0x3F)) { + DoCodeBraW(); + } else { + SkipiWord(); + } + + /* printf("pc_p set to 0x%p in FBcc (32bit)\n", V_pc_p); */ +} + +LOCALIPROC DoCodeFPU_FBccL(void) +{ + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + + if (CheckFPCondition(Dat & 0x3F)) { + DoCodeBraL(); + } else { + SkipiLong(); + } +} + +LOCALIPROC DoCodeFPU_DBcc(void) +{ + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + uint16_t thereg = Dat & 7; + uint16_t word2 = (int)nextiword(); + + uint16_t predicate = word2 & 0x3F; + + int condition_true = CheckFPCondition(predicate); + + if (! condition_true) { + uint32_t fdb_count = uint32_t_FromSWord(m68k_dreg(thereg)) - 1; + + m68k_dreg(thereg) = + (m68k_dreg(thereg) & ~ 0xFFFF) | (fdb_count & 0xFFFF); + if ((int32_t)fdb_count == -1) { + SkipiWord(); + } else { + DoCodeBraW(); + } + } else { + SkipiWord(); + } +} + +LOCALIPROC DoCodeFPU_Trapcc(void) +{ + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + uint16_t thereg = Dat & 7; + + uint16_t word2 = (int)nextiword(); + + uint16_t predicate = word2 & 0x3F; + + int condition_true = CheckFPCondition(predicate); + + if (thereg == 2) { + (void) nextiword(); + } else if (thereg == 3) { + (void) nextilong(); + } else if (thereg == 4) { + } else { + ReportAbnormalID(0x0302, "Invalid FTRAPcc (?"); + } + + if (condition_true) { + ReportAbnormalID(0x0303, "FTRAPcc trapping"); + Exception(7); + } +} + +LOCALIPROC DoCodeFPU_Scc(void) +{ + uint16_t word2 = (int)nextiword(); + + if (! DecodeModeRegister(1)) { + DoCodeFPU_dflt(); +#if dbglog_HAVE + dbglog_writeln("bad mode/reg in DoCodeFPU_Scc"); +#endif + } else { + if (CheckFPCondition(word2 & 0x3F)) { + SetArgValueB(0xFFFF); + } else { + SetArgValueB(0x0000); + } + } +} + +LOCALPROC DoCodeF_InvalidPlusWord(void) +{ + BackupPC(); + DoCodeFPU_dflt(); +} + +LOCALFUNC int CountCSIAlist(uint16_t word2) +{ + uint16_t regselect = (word2 >> 10) & 0x7; + int num = 0; + + if (regselect & 1) { + num++; + } + if (regselect & 2) { + num++; + } + if (regselect & 4) { + num++; + } + + return num; +} + +LOCALPROC DoCodeFPU_Move_EA_CSIA(uint16_t word2) +{ + int n; + uint32_t ea_value[3]; + uint16_t regselect = (word2 >> 10) & 0x7; + int num = CountCSIAlist(word2); + + if (regselect == 0) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("Invalid FMOVE instruction"); +#endif + return; + } + + /* FMOVEM.L , */ + + if (! DecodeModeRegister(4 * num)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("bad mode/reg in DoCodeFPU_Move_EA_CSIA"); +#endif + } else { + ea_value[0] = GetArgValueL(); + if (num > 1) { + ea_value[1] = get_long(V_regs.ArgAddr.mem + 4); + } + if (num > 2) { + ea_value[2] = get_long(V_regs.ArgAddr.mem + 8); + } + + n = 0; + if (regselect & (1 << 2)) { + myfp_SetFPCR(ea_value[n++]); + } + if (regselect & (1 << 1)) { + myfp_SetFPSR(ea_value[n++]); + } + if (regselect & (1 << 0)) { + myfp_SetFPIAR(ea_value[n++]); + } + } +} + +LOCALPROC DoCodeFPU_MoveM_CSIA_EA(uint16_t word2) +{ + int n; + uint32_t ea_value[3]; + int num = CountCSIAlist(word2); + + uint16_t regselect = (word2 >> 10) & 0x7; + + /* FMOVEM.L , */ + + if (0 == regselect) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("Invalid FMOVE instruction"); +#endif + } else + if (! DecodeModeRegister(4 * num)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("bad mode/reg in DoCodeFPU_MoveM_CSIA_EA"); +#endif + } else + { + n = 0; + if (regselect & (1 << 2)) { + ea_value[n++] = myfp_GetFPCR(); + } + if (regselect & (1 << 1)) { + ea_value[n++] = myfp_GetFPSR(); + } + if (regselect & (1 << 0)) { + ea_value[n++] = myfp_GetFPIAR(); + } + + SetArgValueL(ea_value[0]); + if (num > 1) { + put_long(V_regs.ArgAddr.mem + 4, ea_value[1]); + } + if (num > 2) { + put_long(V_regs.ArgAddr.mem + 8, ea_value[2]); + } + } +} + +LOCALPROC DoCodeFPU_MoveM_EA_list(uint16_t word2) +{ + int i; + uint32_t myaddr; + uint32_t count; + uint16_t register_list = word2; + + uint16_t fmove_mode = (word2 >> 11) & 0x3; + + /* FMOVEM.X , */ + + if ((fmove_mode == 0) || (fmove_mode == 1)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("Invalid FMOVEM.X instruction"); +#endif + return; + } + + if (fmove_mode == 3) { + /* Dynamic mode */ + register_list = V_regs.regs[(word2 >> 4) & 7]; + } + + count = 0; + for (i = 0; i <= 7; i++) { + int j = 1 << (7 - i); + if (j & register_list) { + ++count; + } + } + + if (! DecodeModeRegister(12 * count)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails DoCodeFPU_MoveM_EA_list"); +#endif + } else { + /* Postincrement mode or Control mode */ + + myaddr = V_regs.ArgAddr.mem; + + for (i = 0; i <= 7; i++) { + int j = 1 << (7 - i); + if (j & register_list) { + read_long_double(myaddr, &fpu_dat.fp[i]); + myaddr += 12; + } + } + } +} + +LOCALPROC DoCodeFPU_MoveM_list_EA(uint16_t word2) +{ + /* FMOVEM.X , */ + + int i; + uint32_t myaddr; + uint32_t count; + uint16_t register_list = word2; + uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; + uint16_t themode = (Dat >> 3) & 7; + + uint16_t fmove_mode = (word2 >> 11) & 0x3; + + if ((fmove_mode == 1) || (fmove_mode == 3)) { + /* Dynamic mode */ + register_list = V_regs.regs[(word2 >> 4) & 7]; + } + + count = 0; + for (i = 7; i >= 0; i--) { + int j = 1 << i; + if (j & register_list) { + ++count; + } + } + + if (! DecodeModeRegister(12 * count)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails DoCodeFPU_MoveM_list_EA"); +#endif + } else { + if (themode == 4) { + /* Predecrement mode */ + + myaddr = V_regs.ArgAddr.mem + 12 * count; + + for (i = 7; i >= 0; i--) { + int j = 1 << i; + if (j & register_list) { + myaddr -= 12; + write_long_double(myaddr, &fpu_dat.fp[i]); + } + } + } else { + /* Control mode */ + + myaddr = V_regs.ArgAddr.mem; + + for (i = 0; i <= 7; i++) { + int j = 1 << (7 - i); + if (j & register_list) { + write_long_double(myaddr, &fpu_dat.fp[i]); + myaddr += 12; + } + } + } + } +} + +LOCALPROC DoCodeFPU_MoveCR(uint16_t word2) +{ + /* FMOVECR */ + uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) + | V_regs.CurDecOpY.v[0].ArgDat; + + if (opcode != 0xF200) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("bad opcode in FMOVECR"); +#endif + } else { + uint16_t RomOffset = word2 & 0x7F; + uint16_t DestReg = (word2 >> 7) & 0x7; + + if (! myfp_getCR(&fpu_dat.fp[DestReg], RomOffset)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("Invalid constant number in FMOVECR"); +#endif + } + } +} + +LOCALPROC SaveResultAndFPSR(myfpr *DestReg, myfpr *result) +{ + *DestReg = *result; + myfp_SetConditionCodeByteFromResult(result); +} + +LOCALPROC DoCodeFPU_GenOp(uint16_t word2, myfpr *source) +{ + myfpr result; + myfpr t0; + myfpr *DestReg = &fpu_dat.fp[(word2 >> 7) & 0x7]; + + switch (word2 & 0x7F) { + + case 0x00: /* FMOVE */ + SaveResultAndFPSR(DestReg, source); + break; + + case 0x01: /* FINT */ + myfp_Int(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x02: /* FSINH */ + myfp_Sinh(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x03: /* FINTRZ */ + myfp_IntRZ(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x04: /* FSQRT */ + myfp_Sqrt(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x06: /* FLOGNP1 */ + myfp_LogNP1(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x08: /* FETOXM1 */ + myfp_EToXM1(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x09: /* FTANH */ + myfp_Tanh(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x0A: /* FATAN */ + myfp_ATan(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x0C: /* FASIN */ + myfp_ASin(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x0D: /* FATANH */ + myfp_ATanh(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x0E: /* FSIN */ + myfp_Sin(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x0F: /* FTAN */ + myfp_Tan(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x10: /* FETOX */ + myfp_EToX(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x11: /* FTWOTOX */ + myfp_TwoToX(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x12: /* FTENTOX */ + myfp_TenToX(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x14: /* FLOGN */ + myfp_LogN(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x15: /* FLOG10 */ + myfp_Log10(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x16: /* FLOG2 */ + myfp_Log2(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x18: /* FABS */ + myfp_Abs(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x19: /* FCOSH */ + myfp_Cosh(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x1A: /* FNEG */ + myfp_Neg(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x1C: /* FACOS */ + myfp_ACos(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x1D: /* FCOS */ + myfp_Cos(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x1E: /* FGETEXP */ + myfp_GetExp(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x1F: /* FGETMAN */ + myfp_GetMan(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x20: /* FDIV */ + myfp_Div(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x21: /* FMOD */ /* 0x2D in some docs, 0x21 in others ? */ + myfp_Mod(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x22: /* FADD */ + myfp_Add(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x23: /* FMUL */ + myfp_Mul(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x24: /* FSGLDIV */ + myfp_Div(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x25: /* FREM */ + myfp_Rem(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x26: /* FSCALE */ + myfp_Scale(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x27: /* FSGLMUL */ + myfp_Mul(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x28: /* FSUB */ + myfp_Sub(&result, DestReg, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + /* FSINCOS */ + myfp_SinCos(&result, &fpu_dat.fp[word2 & 0x7], source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x38: /* FCMP */ + myfp_Sub(&result, DestReg, source); + /* don't save result */ + myfp_SetConditionCodeByteFromResult(&result); + break; + + case 0x3A: /* FTST */ + myfp_SetConditionCodeByteFromResult(source); + break; + + /* + everything after here is not in 68881/68882, + appears first in 68040 + */ + + case 0x40: /* FSMOVE */ + myfp_RoundToSingle(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x41: /* FSSQRT */ + myfp_Sqrt(&t0, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x44: /* FDMOVE */ + myfp_RoundToDouble(&result, source); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x45: /* FDSQRT */ + myfp_Sqrt(&t0, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x58: /* FSABS */ + myfp_Abs(&t0, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x5A: /* FSNEG */ + myfp_Neg(&t0, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x5C: /* FDABS */ + myfp_Abs(&t0, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x5E: /* FDNEG */ + myfp_Neg(&t0, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x60: /* FSDIV */ + myfp_Div(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x62: /* FSADD */ + myfp_Add(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x63: /* FSMUL */ + myfp_Mul(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x64: /* FDDIV */ + myfp_Div(&t0, DestReg, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x66: /* FDADD */ + myfp_Add(&t0, DestReg, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x67: /* FDMUL */ + myfp_Mul(&t0, DestReg, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x68: /* FSSUB */ + myfp_Sub(&t0, DestReg, source); + myfp_RoundToSingle(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + case 0x6C: /* FDSUB */ + myfp_Sub(&t0, DestReg, source); + myfp_RoundToDouble(&result, &t0); + SaveResultAndFPSR(DestReg, &result); + break; + + default: + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("Invalid DoCodeFPU_GenOp"); +#endif + break; + } +} + +LOCALPROC DoCodeFPU_GenOpReg(uint16_t word2) +{ + uint16_t regselect = (word2 >> 10) & 0x7; + + DoCodeFPU_GenOp(word2, &fpu_dat.fp[regselect]); +} + +LOCALPROC DoCodeFPU_GenOpEA(uint16_t word2) +{ + myfpr source; + + switch ((word2 >> 10) & 0x7) { + case 0: /* long-word integer */ + if (! DecodeModeRegister(4)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails GetFPSource L"); +#endif + } else { + myfp_FromLong(&source, GetArgValueL()); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 1: /* Single-Precision real */ + if (! DecodeModeRegister(4)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails GetFPSource S"); +#endif + } else { + myfp_FromSingleFormat(&source, GetArgValueL()); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 2: /* extended precision real */ + if (! DecodeAddrModeRegister(12)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeAddrModeRegister fails GetFPSource X"); +#endif + } else { + read_long_double(V_regs.ArgAddr.mem, &source); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 3: /* packed-decimal real */ + if (! DecodeAddrModeRegister(16)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeAddrModeRegister fails GetFPSource P"); +#endif + } else { + ReportAbnormalID(0x0304, + "Packed Decimal in GetFPSource"); + /* correct? just set to a constant for now */ + /* *r = 9123456789.0; */ + DoCodeFPU_GenOp(word2, &source); + } + break; + case 4: /* Word integer */ + if (! DecodeModeRegister(2)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails GetFPSource W"); +#endif + } else { + myfp_FromLong(&source, GetArgValueW()); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 5: /* Double-precision real */ + if (! DecodeAddrModeRegister(8)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeAddrModeRegister fails GetFPSource D"); +#endif + } else { + read_double(V_regs.ArgAddr.mem, &source); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 6: /* Byte Integer */ + if (! DecodeModeRegister(1)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln( + "DecodeModeRegister fails GetFPSource B"); +#endif + } else { + myfp_FromLong(&source, GetArgValueB()); + DoCodeFPU_GenOp(word2, &source); + } + break; + case 7: /* Not a valid source specifier */ + DoCodeFPU_MoveCR(word2); + break; + default: + /* should not be able to get here */ + break; + } +} + +LOCALPROC DoCodeFPU_Move_FP_EA(uint16_t word2) +{ + /* FMOVE FP?, */ + + uint16_t SourceReg = (word2 >> 7) & 0x7; + myfpr *source = &fpu_dat.fp[SourceReg]; + + switch ((word2 >> 10) & 0x7) { + case 0: /* long-word integer */ + if (! DecodeModeRegister(4)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeModeRegister fails FMOVE L"); +#endif + } else { + SetArgValueL(myfp_ToLong(source)); + } + break; + case 1: /* Single-Precision real */ + if (! DecodeModeRegister(4)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeModeRegister fails FMOVE S"); +#endif + } else { + SetArgValueL(myfp_ToSingleFormat(source)); + } + break; + case 2: /* extended precision real */ + if (! DecodeAddrModeRegister(12)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeAddrModeRegister fails FMOVE X"); +#endif + } else { + write_long_double(V_regs.ArgAddr.mem, source); + } + break; + case 3: /* packed-decimal real */ + if (! DecodeAddrModeRegister(16)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeAddrModeRegister fails FMOVE P"); +#endif + } else { + ReportAbnormalID(0x0305, "Packed Decimal in FMOVE"); + /* ? */ + } + break; + case 4: /* Word integer */ + if (! DecodeModeRegister(2)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeModeRegister fails FMOVE W"); +#endif + } else { + SetArgValueW(myfp_ToLong(source)); + } + break; + case 5: /* Double-precision real */ + if (! DecodeAddrModeRegister(8)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeAddrModeRegister fails FMOVE D"); +#endif + } else { + write_double(V_regs.ArgAddr.mem, source); + } + break; + case 6: /* Byte Integer */ + if (! DecodeModeRegister(1)) { + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writeln("DecodeModeRegister fails FMOVE B"); +#endif + } else { + SetArgValueB(myfp_ToLong(source)); + } + break; + default: + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writelnNum("Bad Source Specifier in FMOVE", + (word2 >> 10) & 0x7); +#endif + break; + } +} + +LOCALIPROC DoCodeFPU_md60(void) +{ + uint16_t word2 = (int)nextiword(); + + switch ((word2 >> 13) & 0x7) { + case 0: + DoCodeFPU_GenOpReg(word2); + break; + case 2: + DoCodeFPU_GenOpEA(word2); + break; + case 3: + DoCodeFPU_Move_FP_EA(word2); + break; + case 4: + DoCodeFPU_Move_EA_CSIA(word2); + break; + case 5: + DoCodeFPU_MoveM_CSIA_EA(word2); + break; + case 6: + DoCodeFPU_MoveM_EA_list(word2); + break; + case 7: + DoCodeFPU_MoveM_list_EA(word2); + break; + default: + DoCodeF_InvalidPlusWord(); +#if dbglog_HAVE + dbglog_writelnNum("Invalid DoCodeFPU_md60", + (word2 >> 13) & 0x7); +#endif + break; + } +} diff --git a/src/HW/M68K/FPCPEMDV.h b/src/HW/M68K/FPCPEMDV.h index 187e102..8b13789 100644 --- a/src/HW/M68K/FPCPEMDV.h +++ b/src/HW/M68K/FPCPEMDV.h @@ -1,1218 +1 @@ -/* - FPCPEMDV.h - Copyright (C) 2007 Ross Martin, Paul C. Pratt - - You can redistribute this file and/or modify it under the terms - of version 2 of the GNU General Public License as published by - the Free Software Foundation. You should have received a copy - of the license along with this file; see the file COPYING. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - license for more details. -*/ - -/* - Floating Point CoProcessor Emulated Device - (included by MINEM68K.c) -*/ - -/* - ReportAbnormalID unused 0x0306 - 0x03FF -*/ - - -LOCALVAR struct fpustruct -{ - myfpr fp[8]; - CPTR FPIAR; /* Floating point instruction address register */ -} fpu_dat; - -LOCALPROC myfp_SetFPIAR(uint32_t v) -{ - fpu_dat.FPIAR = v; -} - -LOCALFUNC uint32_t myfp_GetFPIAR(void) -{ - return fpu_dat.FPIAR; -} - -LOCALFUNC bool DecodeAddrModeRegister(uint32_t sz) -{ - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - uint16_t themode = (Dat >> 3) & 7; - uint16_t thereg = Dat & 7; - - switch (themode) { - case 2 : - case 3 : - case 4 : - case 5 : - case 6 : - return DecodeModeRegister(sz); - break; - case 7 : - switch (thereg) { - case 0 : - case 1 : - case 2 : - case 3 : - case 4 : - return DecodeModeRegister(sz); - break; - default : - return false; - break; - } - break; - default : - return false; - break; - } -} - -LOCALPROC read_long_double(uint32_t addr, myfpr *r) -{ - uint16_t v2; - uint32_t v1; - uint32_t v0; - - v2 = get_word(addr + 0); - /* ignore word at offset 2 */ - v1 = get_long(addr + 4); - v0 = get_long(addr + 8); - - myfp_FromExtendedFormat(r, v2, v1, v0); -} - -LOCALPROC write_long_double(uint32_t addr, myfpr *xx) -{ - uint16_t v2; - uint32_t v1; - uint32_t v0; - - myfp_ToExtendedFormat(xx, &v2, &v1, &v0); - - put_word(addr + 0, v2); - put_word(addr + 2, 0); - put_long(addr + 4, v1); - put_long(addr + 8, v0); -} - -LOCALPROC read_double(uint32_t addr, myfpr *r) -{ - uint32_t v1; - uint32_t v0; - - v1 = get_long(addr + 0); - v0 = get_long(addr + 4); - - myfp_FromDoubleFormat(r, v1, v0); -} - -LOCALPROC write_double(uint32_t addr, myfpr *dd) -{ - uint32_t v1; - uint32_t v0; - - myfp_ToDoubleFormat(dd, &v1, &v0); - - put_long(addr + 0, v1); - put_long(addr + 4, v0); -} - -#if 0 -LOCALPROC read_single(uint32_t addr, myfpr *r) -{ - myfp_FromSingleFormat(r, get_long(addr)); -} - -LOCALPROC write_single(uint32_t addr, myfpr *ff) -{ - put_long(addr, myfp_ToSingleFormat(ff)); -} -#endif - - -LOCALFUNC int CheckFPCondition(uint16_t predicate) -{ - int condition_true = 0; - - uint8_t cc = myfp_GetConditionCodeByte(); - - int c_nan = (cc) & 1; - /* int c_inf = (cc >> 1) & 1; */ - int c_zero = (cc >> 2) & 1; - int c_neg = (cc >> 3) & 1; - - /* - printf( - "FPSR Checked: c_nan=%d, c_zero=%d, c_neg=%d," - " predicate=0x%04x\n", - c_nan, c_zero, c_neg, predicate); - */ - - switch (predicate) { - case 0x11: /* SEQ */ - case 0x01: /* EQ */ - condition_true = c_zero; - break; - case 0x1E: /* SNE */ - case 0x0E: /* NE */ - condition_true = ! c_zero; - break; - case 0x02: /* OGT */ - case 0x12: /* GT */ - condition_true = (! c_neg) && (! c_zero) && (! c_nan); - break; - case 0x0D: /* ULE */ - case 0x1D: /* NGT */ - condition_true = c_neg || c_zero || c_nan; - break; - case 0x03: /* OGE */ - case 0x13: /* GE */ - condition_true = c_zero || ((! c_neg) && (! c_nan)); - break; - case 0x0C: /* ULT */ - case 0x1C: /* NGE */ - condition_true = c_nan || ((! c_zero) && c_neg) ; - break; - case 0x04: /* OLT */ - case 0x14: /* LT */ - condition_true = c_neg && (! c_nan) && (! c_zero); - break; - case 0x0B: /* UGE */ - case 0x1B: /* NLT */ - condition_true = c_nan || c_zero || (! c_neg); - break; - case 0x05: /* OLE */ - case 0x15: /* LE */ - condition_true = ((! c_nan) && c_neg) || c_zero; - break; - case 0x0A: /* UGT */ - case 0x1A: /* NLE */ - condition_true = c_nan || ((! c_neg) && (! c_zero)); - break; - case 0x06: /* OGL */ - case 0x16: /* GL */ - condition_true = (! c_nan) && (! c_zero); - break; - case 0x09: /* UEQ */ - case 0x19: /* NGL */ - condition_true = c_nan || c_zero; - break; - case 0x07: /* OR */ - case 0x17: /* GLE */ - condition_true = ! c_nan; - break; - case 0x08: /* NGLE */ - case 0x18: /* NGLE */ - condition_true = c_nan; - break; - case 0x00: /* SFALSE */ - case 0x10: /* FALSE */ - condition_true = 0; - break; - case 0x0F: /* STRUE */ - case 0x1F: /* TRUE */ - condition_true = 1; - break; - } - - /* printf("condition_true=%d\n", condition_true); */ - - return condition_true; -} - -LOCALIPROC DoCodeFPU_dflt(void) -{ - ReportAbnormalID(0x0301, - "unimplemented Floating Point Instruction"); -#if dbglog_HAVE - { - uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) - | V_regs.CurDecOpY.v[0].ArgDat; - - dbglog_writelnNum("opcode", opcode); - } -#endif - DoCodeFdefault(); -} - -LOCALIPROC DoCodeFPU_Save(void) -{ - uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) - | V_regs.CurDecOpY.v[0].ArgDat; - if ((opcode == 0xF327) || (opcode == 0xF32D)) { -#if 0 - DecodeModeRegister(4); - SetArgValueL(0); /* for now, try null state frame */ -#endif - /* 28 byte 68881 IDLE frame */ - - if (! DecodeAddrModeRegister(28)) { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeAddrModeRegister fails in DoCodeFPU_Save"); -#endif - } else { - put_long(V_regs.ArgAddr.mem, 0x1f180000); - put_long(V_regs.ArgAddr.mem + 4, 0); - put_long(V_regs.ArgAddr.mem + 8, 0); - put_long(V_regs.ArgAddr.mem + 12, 0); - put_long(V_regs.ArgAddr.mem + 16, 0); - put_long(V_regs.ArgAddr.mem + 20, 0); - put_long(V_regs.ArgAddr.mem + 24, 0x70000000); - } - - } else { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln("unimplemented FPU Save"); -#endif - } -} - -LOCALIPROC DoCodeFPU_Restore(void) -{ - uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) - | V_regs.CurDecOpY.v[0].ArgDat; - uint16_t themode = (opcode >> 3) & 7; - uint16_t thereg = opcode & 7; - if ((opcode == 0xF35F) || (opcode == 0xF36D)) { - uint32_t dstvalue; - - if (! DecodeAddrModeRegister(4)) { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeAddrModeRegister fails in DoCodeFPU_Restore"); -#endif - } else { - dstvalue = get_long(V_regs.ArgAddr.mem); - if (dstvalue != 0) { - if (0x1f180000 == dstvalue) { - if (3 == themode) { - m68k_areg(thereg) = V_regs.ArgAddr.mem + 28; - } - } else { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln("unknown restore"); - /* not a null state we saved */ -#endif - } - } - } - } else { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln("unimplemented FPU Restore"); -#endif - } -} - -LOCALIPROC DoCodeFPU_FBccW(void) -{ - /* - Also get here for a NOP instruction (opcode 0xF280), - which is simply a FBF.w with offset 0 - */ - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - - if (CheckFPCondition(Dat & 0x3F)) { - DoCodeBraW(); - } else { - SkipiWord(); - } - - /* printf("pc_p set to 0x%p in FBcc (32bit)\n", V_pc_p); */ -} - -LOCALIPROC DoCodeFPU_FBccL(void) -{ - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - - if (CheckFPCondition(Dat & 0x3F)) { - DoCodeBraL(); - } else { - SkipiLong(); - } -} - -LOCALIPROC DoCodeFPU_DBcc(void) -{ - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - uint16_t thereg = Dat & 7; - uint16_t word2 = (int)nextiword(); - - uint16_t predicate = word2 & 0x3F; - - int condition_true = CheckFPCondition(predicate); - - if (! condition_true) { - uint32_t fdb_count = uint32_t_FromSWord(m68k_dreg(thereg)) - 1; - - m68k_dreg(thereg) = - (m68k_dreg(thereg) & ~ 0xFFFF) | (fdb_count & 0xFFFF); - if ((int32_t)fdb_count == -1) { - SkipiWord(); - } else { - DoCodeBraW(); - } - } else { - SkipiWord(); - } -} - -LOCALIPROC DoCodeFPU_Trapcc(void) -{ - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - uint16_t thereg = Dat & 7; - - uint16_t word2 = (int)nextiword(); - - uint16_t predicate = word2 & 0x3F; - - int condition_true = CheckFPCondition(predicate); - - if (thereg == 2) { - (void) nextiword(); - } else if (thereg == 3) { - (void) nextilong(); - } else if (thereg == 4) { - } else { - ReportAbnormalID(0x0302, "Invalid FTRAPcc (?"); - } - - if (condition_true) { - ReportAbnormalID(0x0303, "FTRAPcc trapping"); - Exception(7); - } -} - -LOCALIPROC DoCodeFPU_Scc(void) -{ - uint16_t word2 = (int)nextiword(); - - if (! DecodeModeRegister(1)) { - DoCodeFPU_dflt(); -#if dbglog_HAVE - dbglog_writeln("bad mode/reg in DoCodeFPU_Scc"); -#endif - } else { - if (CheckFPCondition(word2 & 0x3F)) { - SetArgValueB(0xFFFF); - } else { - SetArgValueB(0x0000); - } - } -} - -LOCALPROC DoCodeF_InvalidPlusWord(void) -{ - BackupPC(); - DoCodeFPU_dflt(); -} - -LOCALFUNC int CountCSIAlist(uint16_t word2) -{ - uint16_t regselect = (word2 >> 10) & 0x7; - int num = 0; - - if (regselect & 1) { - num++; - } - if (regselect & 2) { - num++; - } - if (regselect & 4) { - num++; - } - - return num; -} - -LOCALPROC DoCodeFPU_Move_EA_CSIA(uint16_t word2) -{ - int n; - uint32_t ea_value[3]; - uint16_t regselect = (word2 >> 10) & 0x7; - int num = CountCSIAlist(word2); - - if (regselect == 0) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("Invalid FMOVE instruction"); -#endif - return; - } - - /* FMOVEM.L , */ - - if (! DecodeModeRegister(4 * num)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("bad mode/reg in DoCodeFPU_Move_EA_CSIA"); -#endif - } else { - ea_value[0] = GetArgValueL(); - if (num > 1) { - ea_value[1] = get_long(V_regs.ArgAddr.mem + 4); - } - if (num > 2) { - ea_value[2] = get_long(V_regs.ArgAddr.mem + 8); - } - - n = 0; - if (regselect & (1 << 2)) { - myfp_SetFPCR(ea_value[n++]); - } - if (regselect & (1 << 1)) { - myfp_SetFPSR(ea_value[n++]); - } - if (regselect & (1 << 0)) { - myfp_SetFPIAR(ea_value[n++]); - } - } -} - -LOCALPROC DoCodeFPU_MoveM_CSIA_EA(uint16_t word2) -{ - int n; - uint32_t ea_value[3]; - int num = CountCSIAlist(word2); - - uint16_t regselect = (word2 >> 10) & 0x7; - - /* FMOVEM.L , */ - - if (0 == regselect) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("Invalid FMOVE instruction"); -#endif - } else - if (! DecodeModeRegister(4 * num)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("bad mode/reg in DoCodeFPU_MoveM_CSIA_EA"); -#endif - } else - { - n = 0; - if (regselect & (1 << 2)) { - ea_value[n++] = myfp_GetFPCR(); - } - if (regselect & (1 << 1)) { - ea_value[n++] = myfp_GetFPSR(); - } - if (regselect & (1 << 0)) { - ea_value[n++] = myfp_GetFPIAR(); - } - - SetArgValueL(ea_value[0]); - if (num > 1) { - put_long(V_regs.ArgAddr.mem + 4, ea_value[1]); - } - if (num > 2) { - put_long(V_regs.ArgAddr.mem + 8, ea_value[2]); - } - } -} - -LOCALPROC DoCodeFPU_MoveM_EA_list(uint16_t word2) -{ - int i; - uint32_t myaddr; - uint32_t count; - uint16_t register_list = word2; - - uint16_t fmove_mode = (word2 >> 11) & 0x3; - - /* FMOVEM.X , */ - - if ((fmove_mode == 0) || (fmove_mode == 1)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("Invalid FMOVEM.X instruction"); -#endif - return; - } - - if (fmove_mode == 3) { - /* Dynamic mode */ - register_list = V_regs.regs[(word2 >> 4) & 7]; - } - - count = 0; - for (i = 0; i <= 7; i++) { - int j = 1 << (7 - i); - if (j & register_list) { - ++count; - } - } - - if (! DecodeModeRegister(12 * count)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails DoCodeFPU_MoveM_EA_list"); -#endif - } else { - /* Postincrement mode or Control mode */ - - myaddr = V_regs.ArgAddr.mem; - - for (i = 0; i <= 7; i++) { - int j = 1 << (7 - i); - if (j & register_list) { - read_long_double(myaddr, &fpu_dat.fp[i]); - myaddr += 12; - } - } - } -} - -LOCALPROC DoCodeFPU_MoveM_list_EA(uint16_t word2) -{ - /* FMOVEM.X , */ - - int i; - uint32_t myaddr; - uint32_t count; - uint16_t register_list = word2; - uint16_t Dat = V_regs.CurDecOpY.v[0].ArgDat; - uint16_t themode = (Dat >> 3) & 7; - - uint16_t fmove_mode = (word2 >> 11) & 0x3; - - if ((fmove_mode == 1) || (fmove_mode == 3)) { - /* Dynamic mode */ - register_list = V_regs.regs[(word2 >> 4) & 7]; - } - - count = 0; - for (i = 7; i >= 0; i--) { - int j = 1 << i; - if (j & register_list) { - ++count; - } - } - - if (! DecodeModeRegister(12 * count)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails DoCodeFPU_MoveM_list_EA"); -#endif - } else { - if (themode == 4) { - /* Predecrement mode */ - - myaddr = V_regs.ArgAddr.mem + 12 * count; - - for (i = 7; i >= 0; i--) { - int j = 1 << i; - if (j & register_list) { - myaddr -= 12; - write_long_double(myaddr, &fpu_dat.fp[i]); - } - } - } else { - /* Control mode */ - - myaddr = V_regs.ArgAddr.mem; - - for (i = 0; i <= 7; i++) { - int j = 1 << (7 - i); - if (j & register_list) { - write_long_double(myaddr, &fpu_dat.fp[i]); - myaddr += 12; - } - } - } - } -} - -LOCALPROC DoCodeFPU_MoveCR(uint16_t word2) -{ - /* FMOVECR */ - uint16_t opcode = ((uint16_t)(V_regs.CurDecOpY.v[0].AMd) << 8) - | V_regs.CurDecOpY.v[0].ArgDat; - - if (opcode != 0xF200) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("bad opcode in FMOVECR"); -#endif - } else { - uint16_t RomOffset = word2 & 0x7F; - uint16_t DestReg = (word2 >> 7) & 0x7; - - if (! myfp_getCR(&fpu_dat.fp[DestReg], RomOffset)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("Invalid constant number in FMOVECR"); -#endif - } - } -} - -LOCALPROC SaveResultAndFPSR(myfpr *DestReg, myfpr *result) -{ - *DestReg = *result; - myfp_SetConditionCodeByteFromResult(result); -} - -LOCALPROC DoCodeFPU_GenOp(uint16_t word2, myfpr *source) -{ - myfpr result; - myfpr t0; - myfpr *DestReg = &fpu_dat.fp[(word2 >> 7) & 0x7]; - - switch (word2 & 0x7F) { - - case 0x00: /* FMOVE */ - SaveResultAndFPSR(DestReg, source); - break; - - case 0x01: /* FINT */ - myfp_Int(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x02: /* FSINH */ - myfp_Sinh(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x03: /* FINTRZ */ - myfp_IntRZ(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x04: /* FSQRT */ - myfp_Sqrt(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x06: /* FLOGNP1 */ - myfp_LogNP1(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x08: /* FETOXM1 */ - myfp_EToXM1(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x09: /* FTANH */ - myfp_Tanh(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x0A: /* FATAN */ - myfp_ATan(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x0C: /* FASIN */ - myfp_ASin(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x0D: /* FATANH */ - myfp_ATanh(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x0E: /* FSIN */ - myfp_Sin(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x0F: /* FTAN */ - myfp_Tan(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x10: /* FETOX */ - myfp_EToX(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x11: /* FTWOTOX */ - myfp_TwoToX(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x12: /* FTENTOX */ - myfp_TenToX(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x14: /* FLOGN */ - myfp_LogN(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x15: /* FLOG10 */ - myfp_Log10(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x16: /* FLOG2 */ - myfp_Log2(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x18: /* FABS */ - myfp_Abs(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x19: /* FCOSH */ - myfp_Cosh(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x1A: /* FNEG */ - myfp_Neg(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x1C: /* FACOS */ - myfp_ACos(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x1D: /* FCOS */ - myfp_Cos(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x1E: /* FGETEXP */ - myfp_GetExp(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x1F: /* FGETMAN */ - myfp_GetMan(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x20: /* FDIV */ - myfp_Div(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x21: /* FMOD */ /* 0x2D in some docs, 0x21 in others ? */ - myfp_Mod(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x22: /* FADD */ - myfp_Add(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x23: /* FMUL */ - myfp_Mul(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x24: /* FSGLDIV */ - myfp_Div(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x25: /* FREM */ - myfp_Rem(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x26: /* FSCALE */ - myfp_Scale(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x27: /* FSGLMUL */ - myfp_Mul(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x28: /* FSUB */ - myfp_Sub(&result, DestReg, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - /* FSINCOS */ - myfp_SinCos(&result, &fpu_dat.fp[word2 & 0x7], source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x38: /* FCMP */ - myfp_Sub(&result, DestReg, source); - /* don't save result */ - myfp_SetConditionCodeByteFromResult(&result); - break; - - case 0x3A: /* FTST */ - myfp_SetConditionCodeByteFromResult(source); - break; - - /* - everything after here is not in 68881/68882, - appears first in 68040 - */ - - case 0x40: /* FSMOVE */ - myfp_RoundToSingle(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x41: /* FSSQRT */ - myfp_Sqrt(&t0, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x44: /* FDMOVE */ - myfp_RoundToDouble(&result, source); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x45: /* FDSQRT */ - myfp_Sqrt(&t0, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x58: /* FSABS */ - myfp_Abs(&t0, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x5A: /* FSNEG */ - myfp_Neg(&t0, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x5C: /* FDABS */ - myfp_Abs(&t0, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x5E: /* FDNEG */ - myfp_Neg(&t0, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x60: /* FSDIV */ - myfp_Div(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x62: /* FSADD */ - myfp_Add(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x63: /* FSMUL */ - myfp_Mul(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x64: /* FDDIV */ - myfp_Div(&t0, DestReg, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x66: /* FDADD */ - myfp_Add(&t0, DestReg, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x67: /* FDMUL */ - myfp_Mul(&t0, DestReg, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x68: /* FSSUB */ - myfp_Sub(&t0, DestReg, source); - myfp_RoundToSingle(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - case 0x6C: /* FDSUB */ - myfp_Sub(&t0, DestReg, source); - myfp_RoundToDouble(&result, &t0); - SaveResultAndFPSR(DestReg, &result); - break; - - default: - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("Invalid DoCodeFPU_GenOp"); -#endif - break; - } -} - -LOCALPROC DoCodeFPU_GenOpReg(uint16_t word2) -{ - uint16_t regselect = (word2 >> 10) & 0x7; - - DoCodeFPU_GenOp(word2, &fpu_dat.fp[regselect]); -} - -LOCALPROC DoCodeFPU_GenOpEA(uint16_t word2) -{ - myfpr source; - - switch ((word2 >> 10) & 0x7) { - case 0: /* long-word integer */ - if (! DecodeModeRegister(4)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails GetFPSource L"); -#endif - } else { - myfp_FromLong(&source, GetArgValueL()); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 1: /* Single-Precision real */ - if (! DecodeModeRegister(4)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails GetFPSource S"); -#endif - } else { - myfp_FromSingleFormat(&source, GetArgValueL()); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 2: /* extended precision real */ - if (! DecodeAddrModeRegister(12)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeAddrModeRegister fails GetFPSource X"); -#endif - } else { - read_long_double(V_regs.ArgAddr.mem, &source); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 3: /* packed-decimal real */ - if (! DecodeAddrModeRegister(16)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeAddrModeRegister fails GetFPSource P"); -#endif - } else { - ReportAbnormalID(0x0304, - "Packed Decimal in GetFPSource"); - /* correct? just set to a constant for now */ - /* *r = 9123456789.0; */ - DoCodeFPU_GenOp(word2, &source); - } - break; - case 4: /* Word integer */ - if (! DecodeModeRegister(2)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails GetFPSource W"); -#endif - } else { - myfp_FromLong(&source, GetArgValueW()); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 5: /* Double-precision real */ - if (! DecodeAddrModeRegister(8)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeAddrModeRegister fails GetFPSource D"); -#endif - } else { - read_double(V_regs.ArgAddr.mem, &source); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 6: /* Byte Integer */ - if (! DecodeModeRegister(1)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln( - "DecodeModeRegister fails GetFPSource B"); -#endif - } else { - myfp_FromLong(&source, GetArgValueB()); - DoCodeFPU_GenOp(word2, &source); - } - break; - case 7: /* Not a valid source specifier */ - DoCodeFPU_MoveCR(word2); - break; - default: - /* should not be able to get here */ - break; - } -} - -LOCALPROC DoCodeFPU_Move_FP_EA(uint16_t word2) -{ - /* FMOVE FP?, */ - - uint16_t SourceReg = (word2 >> 7) & 0x7; - myfpr *source = &fpu_dat.fp[SourceReg]; - - switch ((word2 >> 10) & 0x7) { - case 0: /* long-word integer */ - if (! DecodeModeRegister(4)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeModeRegister fails FMOVE L"); -#endif - } else { - SetArgValueL(myfp_ToLong(source)); - } - break; - case 1: /* Single-Precision real */ - if (! DecodeModeRegister(4)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeModeRegister fails FMOVE S"); -#endif - } else { - SetArgValueL(myfp_ToSingleFormat(source)); - } - break; - case 2: /* extended precision real */ - if (! DecodeAddrModeRegister(12)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeAddrModeRegister fails FMOVE X"); -#endif - } else { - write_long_double(V_regs.ArgAddr.mem, source); - } - break; - case 3: /* packed-decimal real */ - if (! DecodeAddrModeRegister(16)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeAddrModeRegister fails FMOVE P"); -#endif - } else { - ReportAbnormalID(0x0305, "Packed Decimal in FMOVE"); - /* ? */ - } - break; - case 4: /* Word integer */ - if (! DecodeModeRegister(2)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeModeRegister fails FMOVE W"); -#endif - } else { - SetArgValueW(myfp_ToLong(source)); - } - break; - case 5: /* Double-precision real */ - if (! DecodeAddrModeRegister(8)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeAddrModeRegister fails FMOVE D"); -#endif - } else { - write_double(V_regs.ArgAddr.mem, source); - } - break; - case 6: /* Byte Integer */ - if (! DecodeModeRegister(1)) { - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writeln("DecodeModeRegister fails FMOVE B"); -#endif - } else { - SetArgValueB(myfp_ToLong(source)); - } - break; - default: - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writelnNum("Bad Source Specifier in FMOVE", - (word2 >> 10) & 0x7); -#endif - break; - } -} - -LOCALIPROC DoCodeFPU_md60(void) -{ - uint16_t word2 = (int)nextiword(); - - switch ((word2 >> 13) & 0x7) { - case 0: - DoCodeFPU_GenOpReg(word2); - break; - case 2: - DoCodeFPU_GenOpEA(word2); - break; - case 3: - DoCodeFPU_Move_FP_EA(word2); - break; - case 4: - DoCodeFPU_Move_EA_CSIA(word2); - break; - case 5: - DoCodeFPU_MoveM_CSIA_EA(word2); - break; - case 6: - DoCodeFPU_MoveM_EA_list(word2); - break; - case 7: - DoCodeFPU_MoveM_list_EA(word2); - break; - default: - DoCodeF_InvalidPlusWord(); -#if dbglog_HAVE - dbglog_writelnNum("Invalid DoCodeFPU_md60", - (word2 >> 13) & 0x7); -#endif - break; - } -} diff --git a/src/HW/M68K/MINEM68K.c b/src/HW/M68K/MINEM68K.c index b4f684c..6e5f6d1 100644 --- a/src/HW/M68K/MINEM68K.c +++ b/src/HW/M68K/MINEM68K.c @@ -262,28 +262,28 @@ LOCALVAR struct regstruct #ifdef r_regs -register struct regstruct *g_regs asm (r_regs); +struct regstruct *g_regs asm (r_regs); #define V_regs (*g_regs) #else #define V_regs regs #endif #ifdef r_pc_p -register uint8_t * g_pc_p asm (r_pc_p); +uint8_t * g_pc_p asm (r_pc_p); #define V_pc_p g_pc_p #else #define V_pc_p V_regs.pc_p #endif #ifdef r_MaxCyclesToGo -register int32_t g_MaxCyclesToGo asm (r_MaxCyclesToGo); +int32_t g_MaxCyclesToGo asm (r_MaxCyclesToGo); #define V_MaxCyclesToGo g_MaxCyclesToGo #else #define V_MaxCyclesToGo V_regs.MaxCyclesToGo #endif #ifdef r_pc_pHi -register uint8_t * g_pc_pHi asm (r_pc_pHi); +uint8_t * g_pc_pHi asm (r_pc_pHi); #define V_pc_pHi g_pc_pHi #else #define V_pc_pHi V_regs.pc_pHi @@ -8202,13 +8202,6 @@ LOCALIPROC DoCodeMMU(void) } #endif -#if EmFPU - -#include "FPMATHEM.h" -#include "FPCPEMDV.h" - -#endif - #if HaveGlbReg LOCALPROC Em_Swap(void) { diff --git a/src/UI/CONTROLM.c b/src/UI/CONTROLM.c index db418ab..f16f6cd 100644 --- a/src/UI/CONTROLM.c +++ b/src/UI/CONTROLM.c @@ -91,7 +91,7 @@ LOCALPROC WarnMsgUnsupportedROM(void) MacErr_t ROM_IsValid(void) { - if(CheckRomCheckSum) { + /*if(CheckRomCheckSum) { uint32_t CheckSum = Calc_Checksum(); if (CheckSum != do_get_mem_long(ROM)) { @@ -107,7 +107,7 @@ MacErr_t ROM_IsValid(void) WarnMsgUnsupportedROM(); return mnvm_miscErr; } - } + }*/ ROM_loaded = true; SpeedStopped = false;