minivmac4ios/Mini vMac/mnvm_core/MINEM68K.c

1 line
97 KiB
C
Raw Normal View History

2016-05-01 17:05:36 +00:00
/* 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. */ /* MINimum EMulator of 68K cpu 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" typedef unsigned char flagtype; /* Memory Address Translation Cache record */ struct MATCr { ui5r cmpmask; ui5r cmpvalu; ui5r usemask; ui3p usebase; }; typedef struct MATCr MATCr; typedef MATCr *MATCp; /* This variable was introduced because a program could do a Bcc from within chip memory to a location within expansion memory. With a pointer variable the program counter would point to the wrong location. With this variable unset the program counter is always correct, but programs will run slower (about 4%). Usually, you'll want to have this defined. vMac REQUIRES this. It allows for fun things like Restart. */ #ifndef USE_POINTER #define USE_POINTER 1 #endif #define AKMemory 0 #define AKRegister 1 #define AKConstant 2 union ArgAddrT { ui5r mem; ui5r *rga; }; typedef union ArgAddrT ArgAddrT; LOCALVAR struct regstruct { ui5r regs[16]; /* Data and Address registers */ ui5r pc; /* Program Counter */ CPTR usp; /* User Stack Pointer */ CPTR isp; /* Interrupt Stack Pointer */ #if Use68020 CPTR msp; /* Master Stack Pointer */ #endif /* Status Register */ ui5r intmask; /* bits 10-8 : interrupt priority mask */ flagtype t1; /* bit 15: Trace mode 1 */ #if Use68020 flagtype t0; /* bit 14: Trace mode 0 */ #endif flagtype s; /* bit 13: Supervisor or user privilege level */ #if Use68020 flagtype m; /* bit 12: Master or interrupt mode */ #endif flagtype x; /* bit 4: eXtend */ flagtype n; /* bit 3: Negative */ flagtype z; /* bit 2: Zero */ flagtype v; /* bit 1: oVerflow */ flagtype c; /* bit 0: Carry */ flagtype TracePending; flagtype ExternalInterruptPending; #if 0 flagtype ResetPending; #endif ui3b *fIPL; #if Use68020 ui5b sfc; /* Source Function Code register */ ui5b dfc; /* Destination Function Code register */ ui5b vbr; /* Vector Base Register */ ui5b cacr; /* Cache Control Register */ /* bit 0 : Enable Cache bit 1 : Freeze Cache bit 2 : Clear Entry In Cache (write only) bit 3 : Clear Cache (write only) */ ui5b caar; /* Cache Address Register */ #endif MATCr MATCrdB; MATCr MATCwrB; MATCr MATCrdW; MATCr MATCwrW; MATCr MATCex; ATTep HeadATTel; DecOpR CurDecOp; #if USE_POINTER ui3p pc_p; ui3p pc_oldp; #endif ui5b opsize; ui5b ArgKind; ArgAddrT ArgAddr; ui5b SrcVal; ui5b opcode; si5r MaxCyclesToGo; si5r MoreCyclesToGo; si5r ResidualCycles; ui3b fakeword[2]; #define disp_table_sz (256 * 256) #if SmallGlobals DecOpR *disp_table; #else DecOpR disp_table[disp_table_sz]; #endif } regs; #define ui5r_MSBisSet(x) (((si5r)(x)) < 0) #define ZFLG regs.z #define NFLG regs.n #define CFLG regs.c #define VFLG regs.v #define XFLG regs.x LOCALFUNC ui4b m68k_getCR(void) { return (XFLG << 4) | (NFLG << 3) | (ZFLG << 2) | (VFLG << 1) | CFLG; } LOCALFUNC MayInline void m68k_setCR(ui4b newcr) { XFL