/*
MINEM68K.c
Copyright (C) 2009 Bernd Schmidt, 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.
*//*
EMulator of 68K cpu with GENeric c code (not assembly)
This code descends from a simple 68000 emulator that I
(Paul C. Pratt) wrote long ago. That emulator ran on a 680x0,
and used the cpu it ran on to do some of the work. This
descendent fills in those holes with code from the
Un*x Amiga Emulator by Bernd Schmidt, as found being used in vMac.
This emulator is about 10 times smaller than the UAE,
at the cost of being 2 to 3 times slower.
FPU Emulation added 9/12/2009 by Ross Martin
(this code now located in "FPCPEMDV.h")
*/#ifndef AllFiles#include"SYSDEPNS.h"#include"MYOSGLUE.h"#include"ENDIANAC.h"#include"EMCONFIG.h"#include"GLOBGLUE.h"#include"M68KITAB.h"#if WantDisasm#include"DISAM68K.h"#endif#endif#include"MINEM68K.h"/*
ReportAbnormalID unused 0x0123 - 0x01FF
*/#ifndef DisableLazyFlagAll#define DisableLazyFlagAll 0#endif/*
useful for debugging, to tell if an observed bug is
being cause by lazy flag evaluation stuff.
Can also disable parts of it individually:
*/#ifndef ForceFlagsEval#if DisableLazyFlagAll#define ForceFlagsEval 1#else#define ForceFlagsEval 0#endif#endif#ifndef UseLazyZ#if DisableLazyFlagAll || ForceFlagsEval#define UseLazyZ 0#else#define UseLazyZ 1#endif#endif#ifndef UseLazyCC#if DisableLazyFlagAll#define UseLazyCC 0#else#define UseLazyCC 1#endif#endiftypedefunsignedcharflagtype;/* must be 0 or 1, not boolean *//* Memory Address Translation Cache record */structMATCr{ui5rcmpmask;ui5rcmpvalu;ui5rusemask;ui3pusebase;};typedefstructMATCrMATCr;typedefMATCr*MATCp;#ifndef USE_PCLIMIT#define USE_PCLIMIT 1#endif#define AKMemory 0#define AKRegister 1unionArgAddrT{ui5rmem;ui5r*rga;};typedefunionArgAddrTArgAddrT;enum{kLazyFlagsDefault,kLazyFlagsTstB,kLazyFlagsTstW,kLazyFlagsTstL,kLazyFlagsCmpB,kLazyFlagsCmpW,kLazyFlagsCmpL,kLazyFlagsSubB,kLazyFlagsSubW,kLazyFlagsSubL,kLazyFlagsAddB,kLazyFlagsAddW,kLazyFlagsAddL,kLazyFlagsNegB,kLazyFlagsNegW,kLazyFlagsNegL,kLazyFlagsAsrB,kLazyFlagsAsrW,kLazyFlagsAsrL,kLazyFlagsAslB,kLazyFlagsAslW,kLazyFlagsAslL,#if UseLazyZkLazyFlagsZSet,#endifkNumLazyFlagsKinds};typedefvoid(my_reg_call*ArgSetDstP)(ui5rf);#define FasterAlignedL 0/*
If most long memory access is long aligned,
this should be faster. But on the Mac, this
doesn't seem to be the case, so an
unpredictable branch slows it down.
*/#ifndef HaveGlbReg#define HaveGlbReg 0#endifLOCALVARstructregstruct{ui5rregs[16];/* Data and Address registers */ui3ppc_p;ui3ppc_pHi;si5rrMaxCyclesToGo;#if WantCloserCycDecOpR*CurDecOp;#endifDecOpYRCurDecOpY;ui3rLazyFlagKind;ui3rLazyXFlagKind;#if UseLazyZui3rLazyFlagZSavedKind;#endifui5rLazyFlagArgSrc;ui5rLazyFlagArgDst;ui5rLazyXFlagArgSrc;ui5rLazyXFlagArgDst;ArgAddrTArgAddr;ArgSetDstPArgSetDst;ui5bSrcVal;ui3ppc_pLo;ui5rpc;/* Program Counter */MATCrMATCrdB;MATCrMATCwrB;MATCrMATCrdW;MATCrMATCwrW;#if FasterAlignedLMATCrMATCrdL;MATCrMATCwrL;#endifATTepHeadATTel;si5rMoreCyclesToGo;si5rResidualCycles;ui3bfakeword[2];/* Status Register */ui5rintmask;/* bits 10-8 : interrupt priority mask */flagtypet1;/* bit 15: Trace mode 1 */#if Use68020flagtypet0;/* bit 14: Trace mode 0 */#endifflagtypes;/* bit 13: Supervisor or user privilege level */#if Use68020flagtypem;/* bit 12: Master or interrupt mode */#endifflagtypex;/* bit 4: eXte