1 /*
2   Hatari - m68000.c
3 
4   This file is distributed under the GNU General Public License, version 2
5   or at your option any later version. Read the file gpl.txt for details.
6 
7   These routines originally (in WinSTon) handled exceptions as well as some
8   few OpCode's such as Line-F and Line-A. In Hatari it has mainly become a
9   wrapper between the WinSTon sources and the UAE CPU code.
10 */
11 
12 /* 2007/03/xx	[NP]	Possibility to add several wait states for the same instruction in		*/
13 /*			M68000_WaitState (e.g. clr.b $fa1b.w in Decade Demo Menu).			*/
14 /* 2007/04/14	[NP]	Add support for instruction pairing in M68000_AddCycles, using OpcodeFamily and	*/
15 /*			LastOpcodeFamily (No Cooper Loader, Oh Crickey ... Hidden Screen).		*/
16 /* 2007/04/24	[NP]	Add pairing for BCLR/Bcc.							*/
17 /* 2007/09/29	[NP]	Use the new int.c and INT_CONVERT_TO_INTERNAL.					*/
18 /* 2007/11/26	[NP]	We set BusErrorPC in m68k_run_1 instead of M68000_BusError, else the BusErrorPC	*/
19 /*			will not point to the opcode that generated the bus error.			*/
20 /*			In M68000_BusError, if we have 'move.l $0,$24', we need to generate a bus error	*/
21 /*			for the read, not for the write that should occur after (TransBeauce 2 Demo).	*/
22 /* 2008/01/07	[NP]	Function 'M68000_InitPairing' and 'PairingArray' as a lookup table for fast	*/
23 /*			determination of valid pairing combinations (replace lots of 'if' tests in	*/
24 /*			m68000.h).									*/
25 /* 2008/01/25	[NP]	Add pairing for LSR/MOVE (and all other bit shifting instr) (Anomaly Demo Intro)*/
26 /* 2008/02/02	[NP]	Add pairing for CMP/Bcc (Level 16 Fullscreen (1988)).				*/
27 /* 2008/02/08	[NP]	Add pairing for LSL/LEA (and all other bit shifting instr) (TVI 2 - The Year	*/
28 /*			After Demo).									*/
29 /* 2008/02/11	[NP]	Add pairing for MULS/MOVEA (Delirious Demo IV Loader).				*/
30 /* 2008/01/25	[NP]	Add pairing for LSR/MOVEA (and all other bit shifting instr) (Decade Demo Reset)*/
31 /* 2008/02/16	[NP]	Add pairing for MULS/DIVS (fixes e605 demo part 3).				*/
32 /* 2008/03/08	[NP]	In M68000_Exception, we need to know if the exception was triggered by an MFP	*/
33 /*			interrupt or by a video interrupt. In the case MFP vector base was changed in	*/
34 /*			fffa17 to an other value than the default $40, testing exceptionNr is not enough*/
35 /*			to correctly process the exception. For example, if vector base is set to $10	*/
36 /*			then MFP Timer A will call vector stored at address $74, which would be wrongly	*/
37 /*			interpreted as a level 5 int (which doesn't exist on Atari and will cause an	*/
38 /*			assert to fail in intlevel()). We use InterruptSource to correctly recognize the*/
39 /*			MFP interrupts (fix 'Toki' end part fullscreen which sets vector base to $10).	*/
40 /* 2008/04/14	[NP]	Add pairing for BTST/Bcc (eg btst #7,d0 + bne.s label  (with branch taken)).	*/
41 /* 2008/04/15	[NP]	As tested on a real STF :							*/
42 /*				- MUL/DIV can pair (but DIV/MUL can't)					*/
43 /*					(eg mulu d0,d0 + divs d1,d1 with d0=0 and d1=1)			*/
44 /*				- MUL/MOVE can pair, but not DIV/MOVE					*/
45 /*				- EXG/MOVE can pair (eg exg d3,d4 + move.l 0(a3,d1.w),a4)		*/
46 /*				- MOVE/DBcc can't pair							*/
47 /* 2008/04/16	[NP]	Functions 'M68000_InitPairing_BitShift' to ease code maintenance.		*/
48 /*			Tested on STF : add pairing between bit shift instr and ADD/SUB/OR/AND/EOR/NOT	*/
49 /*			CLR/NEG (certainly some more possible, haven't tested everything)		*/
50 /*			(fixes lsr.w #4,d4 + add.b $f0(a4,d4),d7 used in Zoolook part of ULM New Year).	*/
51 /* 2008/07/08	[NP]	Add pairing between bit shift instr and ADDX/SUBX/ABCD/SBCD (fixes lsl.l #1,d0	*/
52 /*			+ abcd d1,d1 used in Dragonnels - Rainbow Wall).				*/
53 /* 2008/10/05	[NP]	Pass the 'ExceptionSource' parameter to Exception() in uae-cpu/newcpu.c		*/
54 /* 2010/05/07	[NP]	Add pairing for ADD/MOVE ; such pairing should only be possible when combined	*/
55 /*			with d8(an,ix) address mode (eg: add.l (a5,d1.w),d0 + move.b 7(a5,d1.w),d5)	*/
56 /*			(fixes Sommarhack 2010 Invitation by DHS).					*/
57 /* 2010/11/07	[NP]	Add pairing between bit shift instr and JMP (fixes lsl.w #2,d0 + jmp 2(pc,d0)	*/
58 /*			used in Fullparts by Hemoroids).						*/
59 /* 2011/12/11	[NP]	Add pairing between MUL and JSR (fixes muls #52,d2 + jsr 0(a1,d2.w) used in	*/
60 /*			Lemmings Compilation 40's Intro).						*/
61 /* 2014/05/07	[NP]	In M68000_WaitEClock, use CyclesGlobalClockCounter instead of the VBL video	*/
62 /*			counter (else for a given position in a VBL we would always get the same value	*/
63 /*			for the E clock).								*/
64 /* 2015/02/01	[NP]	When using the new WinUAE's cpu, don't handle MFP/DSP interrupts by calling	*/
65 /*			directly Exception(), we must set bit 6 in pendingInterrupts and use the IACK	*/
66 /*			sequence to get the exception's vector number.					*/
67 /* 2015/02/05	[NP]	For the new WinUAE's cpu, don't use ExceptionSource anymore when calling	*/
68 /*			Exception().									*/
69 /* 2015/02/11	[NP]	Replace BusErrorPC by regs.instruction_pc, to get similar code to WinUAE's cpu  */
70 /* 2015/10/08	[NP]	Add M68000_AddCycles_CE() to handle cycles when running with WinUAE's cpu in	*/
71 /*			'cycle exact' mode. In that case, instruction pairing don't have to be handled	*/
72 /*			with some tables/heuristics anymore.						*/
73 
74 
75 const char M68000_fileid[] = "Hatari m68000.c : " __DATE__ " " __TIME__;
76 
77 #include "main.h"
78 #include "configuration.h"
79 #include "gemdos.h"
80 #include "hatari-glue.h"
81 #include "cycInt.h"
82 #include "m68000.h"
83 #include "memorySnapShot.h"
84 #include "mfp.h"
85 #include "options.h"
86 #include "savestate.h"
87 #include "stMemory.h"
88 #include "tos.h"
89 #include "falcon/crossbar.h"
90 #include "cart.h"
91 
92 #if ENABLE_DSP_EMU
93 #include "dsp.h"
94 #endif
95 
96 #if ENABLE_WINUAE_CPU
97 #include "mmu_common.h"
98 #endif
99 
100 /* information about current CPU instruction */
101 cpu_instruction_t CpuInstruction;
102 
103 Uint32 BusErrorAddress;		/* Stores the offending address for bus-/address errors */
104 bool bBusErrorReadWrite;	/* 0 for write error, 1 for read error */
105 int nCpuFreqShift;		/* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */
106 int WaitStateCycles = 0;	/* Used to emulate the wait state cycles of certain IO registers */
107 int BusMode = BUS_MODE_CPU;	/* Used to tell which part is owning the bus (cpu, blitter, ...) */
108 bool CPU_IACK = false;		/* Set to true during an exception when getting the interrupt's vector number */
109 static bool M68000_DebuggerFlag;/* Is debugger enabled or not ? */
110 
111 int LastOpcodeFamily = i_NOP;	/* see the enum in readcpu.h i_XXX */
112 int LastInstrCycles = 0;	/* number of cycles for previous instr. (not rounded to 4) */
113 int Pairing = 0;		/* set to 1 if the latest 2 intr paired */
114 char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
115 
116 
117 /* to convert the enum from OpcodeFamily to a readable value for pairing's debug */
118 const char *OpcodeName[] = { "ILLG",
119 	"OR","AND","EOR","ORSR","ANDSR","EORSR",
120 	"SUB","SUBA","SUBX","SBCD",
121 	"ADD","ADDA","ADDX","ABCD",
122 	"NEG","NEGX","NBCD","CLR","NOT","TST",
123 	"BTST","BCHG","BCLR","BSET",
124 	"CMP","CMPM","CMPA",
125 	"MVPRM","MVPMR","MOVE","MOVEA","MVSR2","MV2SR",
126 	"SWAP","EXG","EXT","MVMEL","MVMLE",
127 	"TRAP","MVR2USP","MVUSP2R","RESET","NOP","STOP","RTE","RTD",
128 	"LINK","UNLK",
129 	"RTS","TRAPV","RTR",
130 	"JSR","JMP","BSR","Bcc",
131 	"LEA","PEA","DBcc","Scc",
132 	"DIVU","DIVS","MULU","MULS",
133 	"ASR","ASL","LSR","LSL","ROL","ROR","ROXL","ROXR",
134 	"ASRW","ASLW","LSRW","LSLW","ROLW","RORW","ROXLW","ROXRW",
135 	"CHK","CHK2",
136 	"MOVEC2","MOVE2C","CAS","CAS2","DIVL","MULL",
137 	"BFTST","BFEXTU","BFCHG","BFEXTS","BFCLR","BFFFO","BFSET","BFINS",
138 	"PACK","UNPK","TAS","BKPT","CALLM","RTM","TRAPcc","MOVES",
139 	"FPP","FDBcc","FScc","FTRAPcc","FBcc","FSAVE","FRESTORE",
140 	"CINVL","CINVP","CINVA","CPUSHL","CPUSHP","CPUSHA","MOVE16",
141 	"MMUOP"
142 };
143 
144 
145 /*-----------------------------------------------------------------------*/
146 /**
147  * Add pairing between all the bit shifting instructions and a given Opcode
148  */
149 
M68000_InitPairing_BitShift(int OpCode)150 static void M68000_InitPairing_BitShift ( int OpCode )
151 {
152 	PairingArray[  i_ASR ][ OpCode ] = 1;
153 	PairingArray[  i_ASL ][ OpCode ] = 1;
154 	PairingArray[  i_LSR ][ OpCode ] = 1;
155 	PairingArray[  i_LSL ][ OpCode ] = 1;
156 	PairingArray[  i_ROL ][ OpCode ] = 1;
157 	PairingArray[  i_ROR ][ OpCode ] = 1;
158 	PairingArray[ i_ROXR ][ OpCode ] = 1;
159 	PairingArray[ i_ROXL ][ OpCode ] = 1;
160 }
161 
162 
163 /**
164  * Init the pairing matrix
165  * Two instructions can pair if PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1
166  */
M68000_InitPairing(void)167 static void M68000_InitPairing(void)
168 {
169 	/* First, clear the matrix (pairing is false) */
170 	memset(PairingArray , 0 , MAX_OPCODE_FAMILY * MAX_OPCODE_FAMILY);
171 
172 	/* Set all valid pairing combinations to 1 */
173 	PairingArray[  i_EXG ][ i_DBcc ] = 1;
174 	PairingArray[  i_EXG ][ i_MOVE ] = 1;
175 	PairingArray[  i_EXG ][ i_MOVEA] = 1;
176 
177 	PairingArray[ i_CMPA ][  i_Bcc ] = 1;
178 	PairingArray[  i_CMP ][  i_Bcc ] = 1;
179 
180 	M68000_InitPairing_BitShift ( i_DBcc );
181 	M68000_InitPairing_BitShift ( i_MOVE );
182 	M68000_InitPairing_BitShift ( i_MOVEA );
183 	M68000_InitPairing_BitShift ( i_LEA );
184 	M68000_InitPairing_BitShift ( i_JMP );
185 
186 	PairingArray[ i_MULU ][ i_MOVEA] = 1;
187 	PairingArray[ i_MULS ][ i_MOVEA] = 1;
188 	PairingArray[ i_MULU ][ i_MOVE ] = 1;
189 	PairingArray[ i_MULS ][ i_MOVE ] = 1;
190 
191 	PairingArray[ i_MULU ][ i_DIVU ] = 1;
192 	PairingArray[ i_MULU ][ i_DIVS ] = 1;
193 	PairingArray[ i_MULS ][ i_DIVU ] = 1;
194 	PairingArray[ i_MULS ][ i_DIVS ] = 1;
195 
196 	PairingArray[ i_MULU ][ i_JSR ] = 1;
197 	PairingArray[ i_MULS ][ i_JSR ] = 1;
198 
199 	PairingArray[ i_BTST ][  i_Bcc ] = 1;
200 
201 	M68000_InitPairing_BitShift ( i_ADD );
202 	M68000_InitPairing_BitShift ( i_SUB );
203 	M68000_InitPairing_BitShift ( i_OR );
204 	M68000_InitPairing_BitShift ( i_AND );
205 	M68000_InitPairing_BitShift ( i_EOR );
206 	M68000_InitPairing_BitShift ( i_NOT );
207 	M68000_InitPairing_BitShift ( i_CLR );
208 	M68000_InitPairing_BitShift ( i_NEG );
209 	M68000_InitPairing_BitShift ( i_ADDX );
210 	M68000_InitPairing_BitShift ( i_SUBX );
211 	M68000_InitPairing_BitShift ( i_ABCD );
212 	M68000_InitPairing_BitShift ( i_SBCD );
213 
214 	PairingArray[ i_ADD ][ i_MOVE ] = 1;		/* when using xx(an,dn) addr mode */
215 	PairingArray[ i_SUB ][ i_MOVE ] = 1;
216 
217 	PairingArray[ i_ABCD ][ i_DBcc ] = 1;
218 	PairingArray[ i_SBCD ][ i_DBcc ] = 1;
219 }
220 
221 
222 /**
223  * One-time CPU initialization.
224  */
M68000_Init(void)225 void M68000_Init(void)
226 {
227 	/* Init UAE CPU core */
228 	Init680x0();
229 
230 	/* Init the pairing matrix */
231 	M68000_InitPairing();
232 }
233 
234 
235 /*-----------------------------------------------------------------------*/
236 /**
237  * Reset CPU 68000 variables
238  */
M68000_Reset(bool bCold)239 void M68000_Reset(bool bCold)
240 {
241 //fprintf ( stderr,"M68000_Reset in cold=%d" , bCold );
242 #if ENABLE_WINUAE_CPU
243 	UAE_Set_Quit_Reset ( bCold );
244 	set_special(SPCFLAG_MODE_CHANGE);		/* exit m68k_run_xxx() loop and check for cpu changes / reset / quit */
245 
246 #else /* UAE CPU core */
247 	if (bCold)
248 	{
249 		/* Clear registers */
250 		memset(&regs, 0, sizeof(regs));
251 	}
252 	/* Now reset the UAE CPU core */
253 	m68k_reset();
254 	Cart_PatchCpuTables();
255 #endif
256 
257 	BusMode = BUS_MODE_CPU;
258 	CPU_IACK = false;
259 //fprintf ( stderr,"M68000_Reset out cold=%d\n" , bCold );
260 }
261 
262 
263 /*-----------------------------------------------------------------------*/
264 /**
265  * Enable/disable breakpoints in the debugger
266  */
M68000_SetDebugger(bool debug)267 void M68000_SetDebugger(bool debug)
268 {
269 	M68000_DebuggerFlag = debug;
270 
271 	if ( debug )
272 		M68000_SetSpecial(SPCFLAG_DEBUGGER);
273 	else
274 		M68000_UnsetSpecial(SPCFLAG_DEBUGGER);
275 }
276 
277 
278 /*-----------------------------------------------------------------------*/
279 /**
280  * Restore debugger state (breakpoints)
281  * This is called from CPU core after a reset, because CPU core clears regs.spcflags
282  */
M68000_RestoreDebugger(void)283 void M68000_RestoreDebugger(void)
284 {
285 	if ( M68000_DebuggerFlag )
286 		M68000_SetSpecial(SPCFLAG_DEBUGGER);
287 	else
288 		M68000_UnsetSpecial(SPCFLAG_DEBUGGER);
289 }
290 
291 
292 
293 /*-----------------------------------------------------------------------*/
294 /**
295  * Start 680x0 emulation
296  */
M68000_Start(void)297 void M68000_Start(void)
298 {
299 //fprintf (stderr, "M68000_Start\n" );
300 
301 	/* Load initial memory snapshot */
302 	if (bLoadMemorySave)
303 	{
304 		MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, false);
305 	}
306 	else if (bLoadAutoSave)
307 	{
308 		MemorySnapShot_Restore(ConfigureParams.Memory.szAutoSaveFileName, false);
309 	}
310 
311 #if ENABLE_WINUAE_CPU
312 	UAE_Set_Quit_Reset ( false );
313 	m68k_go(true);
314 #else
315 	m68k_go(true);
316 #endif
317 }
318 
319 
320 /*-----------------------------------------------------------------------*/
321 /**
322  * Check whether CPU settings have been changed.
323  * Possible values for WinUAE :
324  *	cpu_model : 68000 , 68010, 68020, 68030, 68040, 68060
325  *	cpu_level : not used anymore
326  *	cpu_compatible : 0/false (no prefetch for 68000/20/30)  1/true (prefetch opcode for 68000/20/30)
327  *	cpu_cycle_exact : 0/false   1/true (most accurate, implies cpu_compatible)
328  *	cpu_memory_cycle_exact : 0/false   1/true (less accurate than cpu_cycle_exact)
329  *	cpu_data_cache : 0/false (don't emulate caches)   1/true (emulate instr/data caches for 68020/30/40/60)
330  *	address_space_24 : 1 (68000/10 and 68030 LC for Falcon), 0 (68020/30/40/60)
331  *	fpu_model : 0, 68881 (external), 68882 (external), 68040 (cpu) , 68060 (cpu)
332  *	fpu_strict : true/false (more accurate rounding)
333  *	fpu_mode :  0  faster but less accurate, use host's cpu/fpu with 64 bit precision)
334  *		    1  most accurate but slower, use softfloat library)
335  *		   -1  similar to 0 but with extended 80 bit precision, only for x86 CPU)
336  *		       (TODO [NP] not in Hatari for now, require fpp_native_msvc_80bit.cpp / fpux64_80.asm / fpux86_80.asm)
337  *	mmu_model : 0, 68030, 68040, 68060
338  *
339  *	m68k_speed : -1=don't adjust cycle  >=0 use m68k_speed_throttle to precisely adjust cycles
340  *	m68k_speed_throttle : if not 0, used to set cycles_mult. In Hatari, set it to 0
341  *	cpu_frequency : in CE mode, fine control of cpu freq, set it to freq/2. Not used in Hatari, set it to 0.
342  *	cpu_clock_multiplier : used to speed up/slow down clock by multiple of 2 in CE mode. In Hatari
343  *			we use nCpuFreqShift, so this should always be set to 2<<8 = 512 to get the same
344  *			cpucycleunit as in non CE mode.
345  *	cachesize : size of cache in MB when using JIT. Not used in Hatari at the moment, set it to 0
346  */
M68000_CheckCpuSettings(void)347 void M68000_CheckCpuSettings(void)
348 {
349 //fprintf ( stderr,"M68000_CheckCpuSettings in\n" );
350 	changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel;
351 
352 #if ENABLE_WINUAE_CPU
353 	/* WinUAE core uses cpu_model instead of cpu_level, so we've got to
354 	 * convert these values here: */
355 	switch (changed_prefs.cpu_level) {
356 		case 0 : changed_prefs.cpu_model = 68000; break;
357 		case 1 : changed_prefs.cpu_model = 68010; break;
358 		case 2 : changed_prefs.cpu_model = 68020; break;
359 		case 3 : changed_prefs.cpu_model = 68030; break;
360 		case 4 : changed_prefs.cpu_model = 68040; break;
361 		case 5 : changed_prefs.cpu_model = 68060; break;
362 		default: fprintf (stderr, "M68000_CheckCpuSettings() : Error, cpu_level unknown\n");
363 	}
364 	currprefs.cpu_level = changed_prefs.cpu_level;			/* TODO remove, not used anymore */
365 
366 	/* Only 68040/60 can have 'internal' FPU */
367 	if ( ( ConfigureParams.System.n_FPUType == FPU_CPU ) && ( changed_prefs.cpu_model < 68040 ) )
368 		ConfigureParams.System.n_FPUType = FPU_NONE;
369 
370 	/* 68000/10 can't have an FPU */
371 	if ( ( ConfigureParams.System.n_FPUType != FPU_NONE ) && ( changed_prefs.cpu_model < 68020 ) )
372 	{
373 		Log_Printf(LOG_WARN, "FPU is not supported in 68000/010 configurations, disabling FPU\n");
374 		ConfigureParams.System.n_FPUType = FPU_NONE;
375 	}
376 
377 	changed_prefs.int_no_unimplemented = true;
378 	changed_prefs.fpu_no_unimplemented = true;
379 	changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
380 	changed_prefs.cpu_cycle_exact = ConfigureParams.System.bCycleExactCpu;
381 	changed_prefs.cpu_memory_cycle_exact = ConfigureParams.System.bCycleExactCpu;
382 	changed_prefs.address_space_24 = ConfigureParams.System.bAddressSpace24;
383 	changed_prefs.fpu_model = ConfigureParams.System.n_FPUType;
384 	changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU;
385 	changed_prefs.fpu_mode = ( ConfigureParams.System.bSoftFloatFPU ? 1 : 0 );
386 
387 	/* Update the MMU model by taking the same value as CPU model */
388 	/* MMU is only supported for CPU >=68030, this is later checked in custom.c fixup_cpu() */
389 	if ( !ConfigureParams.System.bMMU )
390 		changed_prefs.mmu_model = 0;				/* MMU disabled */
391 	else
392 		changed_prefs.mmu_model = changed_prefs.cpu_model;	/* MMU enabled */
393 
394 	/* Set cpu speed to default values (only used in WinUAE, not in Hatari) */
395 	changed_prefs.m68k_speed = 0;
396 	changed_prefs.cpu_clock_multiplier = 2 << 8;
397 
398 	/* We don't use JIT */
399 	changed_prefs.cachesize = 0;
400 
401 	/* Always emulate instr/data caches for cpu >= 68020 */
402 	/* Cache emulation requires cpu_compatible or cpu_cycle_exact mode */
403 	if ( ( changed_prefs.cpu_model < 68020 ) ||
404 	     ( ( changed_prefs.cpu_compatible == false ) && ( changed_prefs.cpu_cycle_exact == false ) ) )
405 		changed_prefs.cpu_data_cache = false;
406 	else
407 		changed_prefs.cpu_data_cache = true;
408 
409 	/* Update SPCFLAG_MODE_CHANGE flag if needed */
410 	check_prefs_changed_cpu();
411 
412 #else
413 	if (ConfigureParams.System.nCpuLevel > 4)
414 		ConfigureParams.System.nCpuLevel = 4;
415 
416 	changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
417 	changed_prefs.cpu_cycle_exact = 0;				/* With old UAE CPU, cycle_exact is always false */
418 
419 	if (table68k)
420 		check_prefs_changed_cpu();
421 #endif
422 //fprintf ( stderr, "M68000_CheckCpuSettings out\n" );
423 }
424 
425 
426 /*-----------------------------------------------------------------------*/
427 /**
428  * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
429  */
M68000_MemorySnapShot_Capture(bool bSave)430 void M68000_MemorySnapShot_Capture(bool bSave)
431 {
432 #if ENABLE_WINUAE_CPU
433 	int len;
434 	uae_u8 chunk[ 1000 ];
435 
436 	MemorySnapShot_Store(&pendingInterrupts, sizeof(pendingInterrupts));	/* for intlev() */
437 
438 	if (bSave)
439 	{
440 		//m68k_dumpstate_file(stderr, NULL);
441 		save_cpu (&len,chunk);
442 		//printf ( "save cpu done\n"  );
443 		save_cpu_extra (&len,chunk);
444 		//printf ( "save cpux done\n" );
445 		save_fpu (&len,chunk);
446 		//printf ( "save fpu done\n"  );
447 		save_mmu (&len,chunk);
448 		//printf ( "save mmu done\n"  );
449 		//m68k_dumpstate_file(stderr, NULL);
450 	}
451 	else
452 	{
453 		//m68k_dumpstate_file(stderr, NULL);
454 		restore_cpu (chunk);
455 		//printf ( "restore cpu done\n" );
456 		restore_cpu_extra (chunk);
457 		//printf ( "restore cpux done\n" );
458 		restore_fpu (chunk);
459 		//printf ( "restore fpu done\n"  );
460 		restore_mmu (chunk);
461 		//printf ( "restore mmu done\n"  );
462 		//m68k_dumpstate_file(stderr, NULL);
463 	}
464 
465 #else /* UAE CPU core */
466 	Uint32 savepc;
467 
468 	/* For the UAE CPU core: */
469 	MemorySnapShot_Store(&pendingInterrupts, sizeof(pendingInterrupts));	/* for intlev() */
470 
471 	MemorySnapShot_Store(&currprefs.address_space_24,
472 	                     sizeof(currprefs.address_space_24));
473 	MemorySnapShot_Store(&regs.regs[0], sizeof(regs.regs));       /* D0-D7 A0-A6 */
474 
475 	if (bSave)
476 	{
477 		savepc = M68000_GetPC();
478 		MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
479 	}
480 	else
481 	{
482 		MemorySnapShot_Store(&savepc, sizeof(savepc));            /* PC */
483 		regs.pc = savepc;
484 		regs.prefetch_pc = regs.pc + 128;
485 	}
486 
487 	MemorySnapShot_Store(&regs.prefetch, sizeof(regs.prefetch));  /* prefetch */
488 
489 	if (bSave)
490 	{
491 		MakeSR();
492 		if (regs.s)
493 		{
494 			MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));    /* USP */
495 			MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* ISP */
496 		}
497 		else
498 		{
499 			MemorySnapShot_Store(&regs.regs[15], sizeof(regs.regs[15]));  /* USP */
500 			MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));    /* ISP */
501 		}
502 		MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));          /* SR/CCR */
503 	}
504 	else
505 	{
506 		MemorySnapShot_Store(&regs.usp, sizeof(regs.usp));
507 		MemorySnapShot_Store(&regs.isp, sizeof(regs.isp));
508 		MemorySnapShot_Store(&regs.sr, sizeof(regs.sr));
509 	}
510 	MemorySnapShot_Store(&regs.opcode, sizeof(regs.opcode));
511 	MemorySnapShot_Store(&regs.instruction_pc, sizeof(regs.instruction_pc));
512 	MemorySnapShot_Store(&regs.stopped, sizeof(regs.stopped));
513 	MemorySnapShot_Store(&regs.dfc, sizeof(regs.dfc));            /* DFC */
514 	MemorySnapShot_Store(&regs.sfc, sizeof(regs.sfc));            /* SFC */
515 	MemorySnapShot_Store(&regs.vbr, sizeof(regs.vbr));            /* VBR */
516 	MemorySnapShot_Store(&regs.caar, sizeof(regs.caar));          /* CAAR */
517 	MemorySnapShot_Store(&regs.cacr, sizeof(regs.cacr));          /* CACR */
518 	MemorySnapShot_Store(&regs.msp, sizeof(regs.msp));            /* MSP */
519 
520 	if (!bSave)
521 	{
522 		Cart_PatchCpuTables();
523 
524 		M68000_SetPC(regs.pc);
525 		/* MakeFromSR() must not swap stack pointer */
526 		regs.s = (regs.sr >> 13) & 1;
527 		MakeFromSR();
528 		/* set stack pointer */
529 		if (regs.s)
530 			m68k_areg(regs, 7) = regs.isp;
531 		else
532 			m68k_areg(regs, 7) = regs.usp;
533 	}
534 
535 	if (bSave)
536 		save_fpu();
537 	else
538 		restore_fpu();
539 #endif
540 }
541 
542 
543 /*-----------------------------------------------------------------------*/
544 /**
545  * Check whether bus error reporting should be reported or not.
546  * We do not want to print messages when TOS is testing for available HW
547  * or when a program just checks for the floating point co-processor.
548  */
M68000_IsVerboseBusError(uint32_t pc,uint32_t addr)549 bool M68000_IsVerboseBusError(uint32_t pc, uint32_t addr)
550 {
551 	const uint32_t nTosProbeAddrs[] =
552 	{
553 		0xf00039, 0xff8900, 0xff8a00, 0xff8c83,
554 		0xff8e0d, 0xff8e09, 0xfffa40
555 	};
556 	const uint32_t nEmuTosProbeAddrs[] =
557 	{
558 		0xf0001d, 0xf0005d, 0xf0009d, 0xf000dd, 0xff8006, 0xff8282,
559 		0xff8400, 0xff8701, 0xff8901, 0xff8943, 0xff8961, 0xff8c80,
560 		0xff8a3c, 0xff9201, 0xfffa81, 0xfffe00
561 	};
562 	int idx;
563 
564 	if (ConfigureParams.Log.nTextLogLevel == LOG_DEBUG)
565 		return true;
566 
567 	if (ConfigureParams.System.bAddressSpace24
568 	    || (addr & 0xff000000) == 0xff000000)
569 	{
570 		addr &= 0xffffff;
571 	}
572 
573 	/* Program just probing for FPU? A lot of C startup code is always
574 	 * doing this, so reporting bus errors here would be annoying */
575 	if (addr == 0xfffa42)
576 		return false;
577 
578 	/* Always report other bus errors from normal programs */
579 	if (pc < TosAddress || pc > TosAddress + TosSize)
580 		return true;
581 
582 	for (idx = 0; idx < ARRAY_SIZE(nTosProbeAddrs); idx++)
583 	{
584 		if (nTosProbeAddrs[idx] == addr)
585 			return false;
586 	}
587 
588 	if (bIsEmuTOS)
589 	{
590 		for (idx = 0; idx < ARRAY_SIZE(nEmuTosProbeAddrs); idx++)
591 		{
592 			if (nEmuTosProbeAddrs[idx] == addr)
593 				return false;
594 		}
595 	}
596 
597 	return true;
598 }
599 
600 /**
601  * BUSERROR - Access outside valid memory range.
602  * Use bRead = 0 for write errors and bRead = 1 for read errors!
603  */
M68000_BusError(Uint32 addr,int ReadWrite,int Size,int AccessType)604 void M68000_BusError ( Uint32 addr , int ReadWrite , int Size , int AccessType )
605 {
606 	LOG_TRACE(TRACE_CPU_EXCEPTION, "Bus error %s at address $%x PC=$%x.\n",
607 	          ReadWrite ? "reading" : "writing", addr, M68000_InstrPC);
608 
609 #ifndef ENABLE_WINUAE_CPU
610 	if ((regs.spcflags & SPCFLAG_BUSERROR) == 0)		/* [NP] Check that the opcode has not already generated a read bus error */
611 	{
612 		BusErrorAddress = addr;				/* Store for exception frame */
613 		bBusErrorReadWrite = ReadWrite;
614 		M68000_SetSpecial(SPCFLAG_BUSERROR);		/* The exception will be done in newcpu.c */
615 	}
616 #else
617 	/* With WinUAE's cpu, on a bus error instruction will be correctly aborted before completing, */
618 	/* so we don't need to check if the opcode already generated a bus error or not */
619 	exception2 ( addr , ReadWrite , Size , AccessType );
620 #endif
621 }
622 
623 
624 /*-----------------------------------------------------------------------*/
625 /**
626  * Exception handler
627  */
M68000_Exception(Uint32 ExceptionNr,int ExceptionSource)628 void M68000_Exception(Uint32 ExceptionNr , int ExceptionSource)
629 {
630 #ifndef WINUAE_FOR_HATARI
631 	if ((ExceptionSource == M68000_EXC_SRC_AUTOVEC)
632 		&& (ExceptionNr>24 && ExceptionNr<32))		/* 68k autovector interrupt? */
633 	{
634 		/* Handle autovector interrupts the UAE's way
635 		 * (see intlev() and do_specialties() in UAE CPU core) */
636 		/* In our case, this part is only called for HBL and VBL interrupts */
637 		int intnr = ExceptionNr - 24;
638 		pendingInterrupts |= (1 << intnr);
639 		M68000_SetSpecial(SPCFLAG_INT);
640 	}
641 
642 	else							/* MFP or direct CPU exceptions */
643 	{
644 		Uint16 SR;
645 
646 		/* Was the CPU stopped, i.e. by a STOP instruction? */
647 		if (regs.spcflags & SPCFLAG_STOP)
648 		{
649 			regs.stopped = 0;
650 			M68000_UnsetSpecial(SPCFLAG_STOP);    /* All is go,go,go! */
651 		}
652 
653 		/* 68k exceptions are handled by Exception() of the UAE CPU core */
654 		Exception(ExceptionNr, m68k_getpc(), ExceptionSource);
655 
656 		/* Set Status Register so interrupt can ONLY be stopped by another interrupt
657 		 * of higher priority */
658 		if ( (ExceptionSource == M68000_EXC_SRC_INT_MFP)
659 		  || (ExceptionSource == M68000_EXC_SRC_INT_DSP) )
660 		{
661 			SR = M68000_GetSR();
662 			SR = (SR&SR_CLEAR_IPL)|0x0600;		/* MFP or DSP, level 6 */
663 			M68000_SetSR(SR);
664 		}
665 	}
666 
667 #else
668 	if ( ExceptionNr > 24 && ExceptionNr < 32 )		/* Level 1-7 interrupts */
669 	{
670 		/* In our case, this part is called for HBL, VBL and MFP/DSP interrupts */
671 		/* For WinUAE CPU, we must call M68000_Update_intlev after changing pendingInterrupts */
672 		/* (in order to call doint() and to update regs.ipl with regs.ipl_pin, else */
673 		/* the exception might be delayed by one instruction in do_specialties()) */
674 		pendingInterrupts |= (1 << ( ExceptionNr - 24 ));
675 		M68000_Update_intlev();
676 	}
677 
678 	else							/* direct CPU exceptions */
679 	{
680 		Exception(ExceptionNr);
681 	}
682 #endif
683 }
684 
685 
686 
687 
688 /*-----------------------------------------------------------------------*/
689 /**
690  * Update the list of pending interrupts.
691  * Level 2 (HBL) and 4 (VBL) are only cleared when the interrupt is processed,
692  * but level 6 is shared between MFP and DSP and can be cleared by MFP or DSP
693  * before being processed.
694  * So, we need to check which IRQ are set/cleared at the same time
695  * and update level 6 accordingly : level 6 = MFP_IRQ OR DSP_IRQ
696  *
697  * [NP] NOTE : temporary case for interrupts with WinUAE CPU in cycle exact mode
698  * In CE mode, interrupt state should be updated on each subcycle of every opcode
699  * then ipl_fetch() is called in each opcode.
700  * For now, Hatari with WinUAE CPU in CE mode only evaluates the interrupt state
701  * after the end of each opcode. So we need to call ipl_fetch() ourselves at the moment.
702  */
M68000_Update_intlev(void)703 void	M68000_Update_intlev ( void )
704 {
705 #ifdef WINUAE_FOR_HATARI
706 	Uint8	Level6_IRQ;
707 
708 #if ENABLE_DSP_EMU
709 	Level6_IRQ = MFP_GetIRQ_CPU() | DSP_GetHREQ();
710 #else
711 	Level6_IRQ = MFP_GetIRQ_CPU();
712 #endif
713 	if ( Level6_IRQ == 1 )
714 		pendingInterrupts |= (1 << 6);
715 	else
716 		pendingInterrupts &= ~(1 << 6);
717 
718 	if ( pendingInterrupts )
719 		doint();
720 	else
721 		M68000_UnsetSpecial ( SPCFLAG_INT | SPCFLAG_DOINT );
722 
723 	/* Temporary case for WinUAE CPU in CE mode */
724 	/* doint() will update regs.ipl_pin, so copy it into regs.ipl */
725 	if ( ConfigureParams.System.bCycleExactCpu )
726 		regs.ipl = regs.ipl_pin;			/* See ipl_fetch() in cpu/cpu_prefetch.h */
727 #endif
728 }
729 
730 
731 
732 
733 /*-----------------------------------------------------------------------*/
734 /**
735  * There are some wait states when accessing certain hardware registers on the ST.
736  * This function simulates these wait states and add the corresponding cycles.
737  *
738  * [NP] with some instructions like CLR, we have a read then a write at the
739  * same location, so we may have 2 wait states (read and write) to add
740  * (WaitStateCycles should be reset to 0 after all the cycles were added
741  * in run_xx() in newcpu.c).
742  *
743  * - When CPU runs in cycle exact mode, wait states are added immediately.
744  * - For other less precise modes, all the wait states are cumulated and added
745  *   after the instruction was processed.
746  */
M68000_WaitState(int WaitCycles)747 void M68000_WaitState(int WaitCycles)
748 {
749 #ifndef WINUAE_FOR_HATARI
750 	WaitStateCycles += WaitCycles;				/* Cumulate all the wait states for this instruction */
751 
752 #else
753 	if ( ConfigureParams.System.bCycleExactCpu )
754 		currcycle += ( WaitCycles * CYCLE_UNIT / 2 );	/* Add wait states immediately to the CE cycles counter */
755 	else
756 	{
757 		WaitStateCycles += WaitCycles;			/* Cumulate all the wait states for this instruction */
758 	}
759 #endif
760 }
761 
762 
763 
764 /*-----------------------------------------------------------------------*/
765 /**
766  * Some components (HBL/VBL interrupts, access to the ACIA) require an
767  * extra delay to be synchronized with the E Clock.
768  * E Clock's frequency is 1/10th of the CPU, ie 0.8 MHz in an STF/STE
769  * This delay is a multiple of 2 and will follow the pattern [ 0 8 6 4 2 ]
770  */
M68000_WaitEClock(void)771 int	M68000_WaitEClock ( void )
772 {
773 	int	CyclesToNextE;
774 
775 	/* We must wait for the next multiple of 10 cycles to be synchronised with E Clock */
776 	CyclesToNextE = 10 - CyclesGlobalClockCounter % 10;
777 	if ( CyclesToNextE == 10 )		/* we're already synchronised with E Clock */
778 		CyclesToNextE = 0;
779 	return CyclesToNextE;
780 }
781 
782 
783 
784 
785 /*-----------------------------------------------------------------------*/
786 /**
787  * Some hardware registers can only be accessed on a 4 cycles boundary
788  * (shifter color regs and shifter res reg).
789  * An extra delay should be added when needed if current cycle
790  * count is not multiple of 4.
791  */
M68000_SyncCpuBus(bool read)792 static void	M68000_SyncCpuBus ( bool read )
793 {
794 	Uint64	Cycles;
795 	int	CyclesToNextBus;
796 
797 	if ( read )
798 		Cycles = Cycles_GetClockCounterOnReadAccess();
799 	else
800 		Cycles = Cycles_GetClockCounterOnWriteAccess();
801 
802 	CyclesToNextBus = Cycles & 3;
803 //fprintf ( stderr , "sync bus %lld %d\n" , Cycles, CyclesToNextBus );
804 	if ( CyclesToNextBus != 0 )
805 	{
806 //fprintf ( stderr , "sync bus wait %lld %d\n" ,Cycles, 4-CyclesToNextBus );
807 		M68000_WaitState ( 4 - CyclesToNextBus );
808 	}
809 }
810 
811 
M68000_SyncCpuBus_OnReadAccess(void)812 void	M68000_SyncCpuBus_OnReadAccess ( void )
813 {
814 	M68000_SyncCpuBus ( true );
815 }
816 
817 
M68000_SyncCpuBus_OnWriteAccess(void)818 void	M68000_SyncCpuBus_OnWriteAccess ( void )
819 {
820 	M68000_SyncCpuBus ( false );
821 }
822 
823 
824 
825 
826 /*-----------------------------------------------------------------------*/
827 /**
828  * In case we modified the memory by accessing it directly (and bypassing
829  * the CPU's cache mechanism), we need to flush the instruction and data
830  * caches to force an update of the caches on the next accesses.
831  *
832  * [NP] NOTE : for now, flush_instr_caches and flush_dcache flush
833  * the whole caches, not just 'addr'
834  */
M68000_Flush_All_Caches(uaecptr addr,int size)835 void	M68000_Flush_All_Caches ( uaecptr addr , int size )
836 {
837 //fprintf ( stderr , "M68000_Flush_All_Caches\n" );
838 #ifdef WINUAE_FOR_HATARI
839 	flush_cpu_caches(true);
840 	invalidate_cpu_data_caches();
841 #endif
842 }
843 
844 
M68000_Flush_Instr_Cache(uaecptr addr,int size)845 void	M68000_Flush_Instr_Cache ( uaecptr addr , int size )
846 {
847 //fprintf ( stderr , "M68000_Flush_Instr_Cache\n" );
848 #ifdef WINUAE_FOR_HATARI
849 	/* Instruction cache for cpu >= 68020 */
850 	flush_cpu_caches(true);
851 #endif
852 }
853 
854 
M68000_Flush_Data_Cache(uaecptr addr,int size)855 void	M68000_Flush_Data_Cache ( uaecptr addr , int size )
856 {
857 //fprintf ( stderr , "M68000_Flush_Data_Cache\n" );
858 #ifdef WINUAE_FOR_HATARI
859 	/* Data cache for cpu >= 68030 */
860 	invalidate_cpu_data_caches();
861 #endif
862 }
863 
864 
865 
866 /*-----------------------------------------------------------------------*/
867 /**
868  * When running in 68000 CE mode, allow to change the "do_cycles" functions
869  * in the cpu emulation depending on the blitter state.
870  *  - if the blitter is not busy, we keep the 'normal' 68000 CE "do_cycles" functions
871  *  - if the blitter is busy, we use a slightly slower "do_cycles" to accurately
872  *    count bus accesses made by the blitter and the CPU
873  *
874  * This limits the overhead of emulating cycle exact blitter bus accesses when blitter is OFF.
875  */
M68000_SetBlitter_CE(bool state)876 void	M68000_SetBlitter_CE ( bool state )
877 {
878 #ifdef WINUAE_FOR_HATARI
879 //fprintf ( stderr , "M68000_SetBlitter_CE state=%s\n" , state ? "on" : "off" );
880 	if ( state )
881 	{
882 		set_x_funcs_hatari_blitter ( 1 );		/* on */
883 	}
884 	else
885 	{
886 		set_x_funcs_hatari_blitter ( 0 );		/* off */
887 	}
888 #endif
889 }
890 
891 
892 /*-----------------------------------------------------------------------*/
893 /**
894  * On real STF/STE hardware, DMA accesses are restricted to 4 MB (video addresses,
895  * FDC, STE DMA sound) in the range 0 - $3fffff (22 bits of address)
896  * When STF/STE are expanded beyond 4 MB, some special '_FRB' cookies variables
897  * need to be set in TOS to allocate an intermediate buffer in lower 4 MB
898  * that will be used to transfer data in RAM between 4 MB and 16 MB.
899  * This buffer is needed because real HW can't access RAM beyond 4 MB.
900  *
901  * In Hatari, we allow DMA addresses to use 24 bits when RAM size is set
902  * to 8 or 16 MB. This way any program / TOS version can make use of extra
903  * RAM beyond 4 MB without requiring an intermediate buffer.
904  *
905  * But it should be noted that programs using 24 bits of DMA addresses would
906  * not work on real HW ; this is just to make RAM expansion more transparent
907  * under emulation.
908  *
909  * We return a mask for bits 16-23 :
910  *  - 0x3f for compatibility with real HW and limit of 4 MB
911  *  - 0xff to allow DMA addresses beyond 4 MB (or for Falcon / TT)
912  */
DMA_MaskAddressHigh(void)913 int	DMA_MaskAddressHigh ( void )
914 {
915 	if (Config_IsMachineTT() || Config_IsMachineFalcon())
916 		return 0xff;					/* Falcon / TT can access 24 bits with DMA */
917 
918 	else if (ConfigureParams.Memory.STRamSize_KB > 4*1024)	/* ST/STE with more than 4 MB */
919 		return 0xff;					/* Allow 'fake' 24 bits for DMA */
920 
921 	else							/* ST/STE with <= 4 MB */
922 		return 0x3f;					/* Limit DMA range to 22 bits (same as real HW) */
923 }
924 
925 
926 
927 
928 /*-----------------------------------------------------------------------*/
929 /**
930  * This function should be called when the cpu freq is changed, to update
931  * other components that depend on it.
932  *
933  * For now, only Falcon mode requires some updates for the crossbar
934  */
M68000_ChangeCpuFreq(void)935 void	M68000_ChangeCpuFreq ( void )
936 {
937 	if ( Config_IsMachineFalcon() )
938 	{
939 		Crossbar_Recalculate_Clocks_Cycles();
940 	}
941 }
942 
943 
944 
945 
946 /*-----------------------------------------------------------------------*/
947 /**
948  * Some CPU registers can't be read or modified directly, some additional
949  * actions are required.
950  */
M68000_GetSR(void)951 Uint16	M68000_GetSR ( void )
952 {
953 	MakeSR();
954 	return regs.sr;
955 }
956 
M68000_SetSR(Uint16 v)957 void	M68000_SetSR ( Uint16 v )
958 {
959 	regs.sr = v;
960 	MakeFromSR();
961 }
962 
M68000_SetPC(uaecptr v)963 void	M68000_SetPC ( uaecptr v )
964 {
965 	m68k_setpc ( v );
966 #ifdef WINUAE_FOR_HATARI
967 	fill_prefetch();
968 #else
969 	refill_prefetch (m68k_getpc(), 0);
970 #endif
971 }
972 
973 
974