|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - m68000.c
1.1 root 3:
1.1.1.6 root 4: This file is distributed under the GNU Public License, version 2 or at
5: 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
1.1.1.5 root 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.
1.1 root 10: */
1.1.1.12 root 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)*/
1.1.1.13 root 31: /* 2008/02/16 [NP] Add pairing for MULS/DIVS (fixes e605 demo part 3). */
1.1.1.12 root 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 */
1.1.1.13 root 38: /* assert to fail in intlevel()). We use InterruptSource to correctly recognize the*/
1.1.1.12 root 39: /* MFP interrupts (fix 'Toki' end part fullscreen which sets vector base to $10). */
1.1.1.13 root 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 */
1.1.1.16 root 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). */
1.1.1.17! root 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). */
1.1.1.12 root 59:
60:
1.1.1.14 root 61: const char M68000_fileid[] = "Hatari m68000.c : " __DATE__ " " __TIME__;
1.1 root 62:
63: #include "main.h"
1.1.1.12 root 64: #include "configuration.h"
1.1 root 65: #include "gemdos.h"
1.1.1.6 root 66: #include "hatari-glue.h"
1.1.1.16 root 67: #include "cycInt.h"
1.1 root 68: #include "m68000.h"
69: #include "memorySnapShot.h"
70: #include "mfp.h"
1.1.1.12 root 71: #include "options.h"
72: #include "savestate.h"
1.1 root 73: #include "stMemory.h"
74: #include "tos.h"
75:
76:
1.1.1.12 root 77: Uint32 BusErrorAddress; /* Stores the offending address for bus-/address errors */
78: Uint32 BusErrorPC; /* Value of the PC when bus error occurs */
1.1.1.13 root 79: bool bBusErrorReadWrite; /* 0 for write error, 1 for read error */
1.1.1.12 root 80: int nCpuFreqShift; /* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */
81: int nWaitStateCycles; /* Used to emulate the wait state cycles of certain IO registers */
1.1.1.14 root 82: int BusMode = BUS_MODE_CPU; /* Used to tell which part is owning the bus (cpu, blitter, ...) */
1.1.1.12 root 83:
1.1.1.16 root 84: int LastOpcodeFamily = i_NOP; /* see the enum in readcpu.h i_XXX */
85: int LastInstrCycles = 0; /* number of cycles for previous instr. (not rounded to 4) */
86: int Pairing = 0; /* set to 1 if the latest 2 intr paired */
1.1.1.12 root 87: char PairingArray[ MAX_OPCODE_FAMILY ][ MAX_OPCODE_FAMILY ];
88:
89:
90: /* to convert the enum from OpcodeFamily to a readable value for pairing's debug */
91: const char *OpcodeName[] = { "ILLG",
92: "OR","AND","EOR","ORSR","ANDSR","EORSR",
93: "SUB","SUBA","SUBX","SBCD",
94: "ADD","ADDA","ADDX","ABCD",
95: "NEG","NEGX","NBCD","CLR","NOT","TST",
96: "BTST","BCHG","BCLR","BSET",
97: "CMP","CMPM","CMPA",
98: "MVPRM","MVPMR","MOVE","MOVEA","MVSR2","MV2SR",
99: "SWAP","EXG","EXT","MVMEL","MVMLE",
100: "TRAP","MVR2USP","MVUSP2R","RESET","NOP","STOP","RTE","RTD",
101: "LINK","UNLK",
102: "RTS","TRAPV","RTR",
103: "JSR","JMP","BSR","Bcc",
104: "LEA","PEA","DBcc","Scc",
105: "DIVU","DIVS","MULU","MULS",
106: "ASR","ASL","LSR","LSL","ROL","ROR","ROXL","ROXR",
107: "ASRW","ASLW","LSRW","LSLW","ROLW","RORW","ROXLW","ROXRW",
108: "CHK","CHK2",
109: "MOVEC2","MOVE2C","CAS","CAS2","DIVL","MULL",
110: "BFTST","BFEXTU","BFCHG","BFEXTS","BFCLR","BFFFO","BFSET","BFINS",
111: "PACK","UNPK","TAS","BKPT","CALLM","RTM","TRAPcc","MOVES",
112: "FPP","FDBcc","FScc","FTRAPcc","FBcc","FSAVE","FRESTORE",
113: "CINVL","CINVP","CINVA","CPUSHL","CPUSHP","CPUSHA","MOVE16",
114: "MMUOP"
115: };
1.1.1.8 root 116:
1.1.1.12 root 117:
118: /*-----------------------------------------------------------------------*/
119: /**
1.1.1.13 root 120: * Add pairing between all the bit shifting instructions and a given Opcode
121: */
122:
123: static void M68000_InitPairing_BitShift ( int OpCode )
124: {
125: PairingArray[ i_ASR ][ OpCode ] = 1;
126: PairingArray[ i_ASL ][ OpCode ] = 1;
127: PairingArray[ i_LSR ][ OpCode ] = 1;
128: PairingArray[ i_LSL ][ OpCode ] = 1;
129: PairingArray[ i_ROL ][ OpCode ] = 1;
130: PairingArray[ i_ROR ][ OpCode ] = 1;
131: PairingArray[ i_ROXR ][ OpCode ] = 1;
132: PairingArray[ i_ROXL ][ OpCode ] = 1;
133: }
134:
135:
136: /**
1.1.1.12 root 137: * Init the pairing matrix
138: * Two instructions can pair if PairingArray[ LastOpcodeFamily ][ OpcodeFamily ] == 1
139: */
1.1.1.16 root 140: static void M68000_InitPairing(void)
1.1.1.12 root 141: {
142: /* First, clear the matrix (pairing is false) */
143: memset(PairingArray , 0 , MAX_OPCODE_FAMILY * MAX_OPCODE_FAMILY);
144:
145: /* Set all valid pairing combinations to 1 */
146: PairingArray[ i_EXG ][ i_DBcc ] = 1;
1.1.1.13 root 147: PairingArray[ i_EXG ][ i_MOVE ] = 1;
148: PairingArray[ i_EXG ][ i_MOVEA] = 1;
149:
1.1.1.12 root 150: PairingArray[ i_CMPA ][ i_Bcc ] = 1;
151: PairingArray[ i_CMP ][ i_Bcc ] = 1;
1.1.1.13 root 152:
153: M68000_InitPairing_BitShift ( i_DBcc );
154: M68000_InitPairing_BitShift ( i_MOVE );
155: M68000_InitPairing_BitShift ( i_MOVEA );
156: M68000_InitPairing_BitShift ( i_LEA );
1.1.1.17! root 157: M68000_InitPairing_BitShift ( i_JMP );
1.1.1.13 root 158:
1.1.1.12 root 159: PairingArray[ i_MULU ][ i_MOVEA] = 1;
160: PairingArray[ i_MULS ][ i_MOVEA] = 1;
161: PairingArray[ i_MULU ][ i_MOVE ] = 1;
162: PairingArray[ i_MULS ][ i_MOVE ] = 1;
1.1.1.13 root 163:
164: PairingArray[ i_MULU ][ i_DIVU ] = 1;
165: PairingArray[ i_MULU ][ i_DIVS ] = 1;
166: PairingArray[ i_MULS ][ i_DIVU ] = 1;
167: PairingArray[ i_MULS ][ i_DIVS ] = 1;
168:
169: PairingArray[ i_BTST ][ i_Bcc ] = 1;
170:
171: M68000_InitPairing_BitShift ( i_ADD );
172: M68000_InitPairing_BitShift ( i_SUB );
173: M68000_InitPairing_BitShift ( i_OR );
174: M68000_InitPairing_BitShift ( i_AND );
175: M68000_InitPairing_BitShift ( i_EOR );
176: M68000_InitPairing_BitShift ( i_NOT );
177: M68000_InitPairing_BitShift ( i_CLR );
178: M68000_InitPairing_BitShift ( i_NEG );
179: M68000_InitPairing_BitShift ( i_ADDX );
180: M68000_InitPairing_BitShift ( i_SUBX );
181: M68000_InitPairing_BitShift ( i_ABCD );
182: M68000_InitPairing_BitShift ( i_SBCD );
1.1.1.16 root 183:
184: PairingArray[ i_ADD ][ i_MOVE ] = 1; /* when using xx(an,dn) addr mode */
185: PairingArray[ i_SUB ][ i_MOVE ] = 1;
186: }
187:
188:
189: /**
190: * One-time CPU initialization.
191: */
192: void M68000_Init(void)
193: {
194: /* Init UAE CPU core */
195: Init680x0();
196:
197: /* Init the pairing matrix */
198: M68000_InitPairing();
1.1.1.12 root 199: }
1.1 root 200:
201:
1.1.1.3 root 202: /*-----------------------------------------------------------------------*/
1.1.1.12 root 203: /**
204: * Reset CPU 68000 variables
205: */
1.1.1.13 root 206: void M68000_Reset(bool bCold)
1.1 root 207: {
1.1.1.12 root 208: /* Clear registers */
209: if (bCold)
210: {
1.1.1.16 root 211: memset(®s, 0, sizeof(regs));
1.1.1.12 root 212: }
213:
214: /* Now directly reset the UAE CPU core: */
1.1.1.17! root 215: /* Laurent : for now, using parameter 0, but some other parameters can be used here (see newcpu.c) */
! 216: #if ENABLE_WINUAE_CPU
! 217: m68k_reset(0);
! 218: #else
1.1.1.12 root 219: m68k_reset();
1.1.1.17! root 220: #endif
1.1.1.14 root 221: BusMode = BUS_MODE_CPU;
1.1.1.12 root 222: }
223:
224:
225: /*-----------------------------------------------------------------------*/
226: /**
1.1.1.16 root 227: * Start 680x0 emulation
1.1.1.12 root 228: */
229: void M68000_Start(void)
230: {
231: /* Load initial memory snapshot */
232: if (bLoadMemorySave)
233: {
1.1.1.15 root 234: MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, false);
1.1.1.12 root 235: }
236: else if (bLoadAutoSave)
237: {
1.1.1.15 root 238: MemorySnapShot_Restore(ConfigureParams.Memory.szAutoSaveFileName, false);
1.1.1.12 root 239: }
1.1.1.7 root 240:
1.1.1.15 root 241: m68k_go(true);
1.1 root 242: }
243:
1.1.1.3 root 244:
245: /*-----------------------------------------------------------------------*/
1.1.1.12 root 246: /**
1.1.1.17! root 247: * Check whether CPU settings have been changed.
1.1.1.12 root 248: */
1.1.1.17! root 249: void M68000_CheckCpuSettings(void)
1.1.1.12 root 250: {
1.1.1.17! root 251: if (ConfigureParams.System.nCpuFreq < 12)
! 252: {
! 253: ConfigureParams.System.nCpuFreq = 8;
! 254: nCpuFreqShift = 0;
! 255: }
! 256: else if (ConfigureParams.System.nCpuFreq > 26)
! 257: {
! 258: ConfigureParams.System.nCpuFreq = 32;
! 259: nCpuFreqShift = 2;
! 260: }
! 261: else
! 262: {
! 263: ConfigureParams.System.nCpuFreq = 16;
! 264: nCpuFreqShift = 1;
! 265: }
1.1.1.12 root 266: changed_prefs.cpu_level = ConfigureParams.System.nCpuLevel;
267: changed_prefs.cpu_compatible = ConfigureParams.System.bCompatibleCpu;
1.1.1.17! root 268:
! 269: #if ENABLE_WINUAE_CPU
! 270: switch (changed_prefs.cpu_level) {
! 271: case 0 : changed_prefs.cpu_model = 68000; break;
! 272: case 1 : changed_prefs.cpu_model = 68010; break;
! 273: case 2 : changed_prefs.cpu_model = 68020; break;
! 274: case 3 : changed_prefs.cpu_model = 68030; break;
! 275: case 4 : changed_prefs.cpu_model = 68040; break;
! 276: case 5 : changed_prefs.cpu_model = 68060; break;
! 277: default: fprintf (stderr, "Init680x0() : Error, cpu_level unknown\n");
! 278: }
! 279:
! 280: changed_prefs.address_space_24 = ConfigureParams.System.bAddressSpace24;
! 281: changed_prefs.cpu_cycle_exact = ConfigureParams.System.bCycleExactCpu;
! 282: changed_prefs.fpu_model = ConfigureParams.System.n_FPUType;
! 283: changed_prefs.fpu_strict = ConfigureParams.System.bCompatibleFPU;
! 284: changed_prefs.mmu_model = ConfigureParams.System.bMMU;
1.1.1.12 root 285: #endif
286: if (table68k)
287: check_prefs_changed_cpu();
288: }
289:
290:
291: /*-----------------------------------------------------------------------*/
292: /**
293: * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
294: */
1.1.1.13 root 295: void M68000_MemorySnapShot_Capture(bool bSave)
1.1 root 296: {
1.1.1.12 root 297: Uint32 savepc;
1.1.1.17! root 298: #if ENABLE_WINUAE_CPU
! 299: int len;
! 300: uae_u8 *chunk = 0;
! 301: #endif
1.1 root 302:
1.1.1.12 root 303: /* For the UAE CPU core: */
304: MemorySnapShot_Store(&currprefs.address_space_24,
305: sizeof(currprefs.address_space_24));
306: MemorySnapShot_Store(®s.regs[0], sizeof(regs.regs)); /* D0-D7 A0-A6 */
307:
308: if (bSave)
309: {
310: savepc = M68000_GetPC();
311: MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */
312: }
313: else
314: {
315: MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */
316: regs.pc = savepc;
317: #ifdef UAE_NEWCPU_H
318: regs.prefetch_pc = regs.pc + 128;
319: #endif
320: }
1.1.1.8 root 321:
1.1.1.12 root 322: #ifdef UAE_NEWCPU_H
323: MemorySnapShot_Store(®s.prefetch, sizeof(regs.prefetch)); /* prefetch */
324: #else
325: uae_u32 prefetch_dummy;
326: MemorySnapShot_Store(&prefetch_dummy, sizeof(prefetch_dummy));
327: #endif
328:
329: if (bSave)
330: {
331: MakeSR();
332: if (regs.s)
333: {
334: MemorySnapShot_Store(®s.usp, sizeof(regs.usp)); /* USP */
335: MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* ISP */
336: }
337: else
338: {
339: MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* USP */
340: MemorySnapShot_Store(®s.isp, sizeof(regs.isp)); /* ISP */
341: }
342: MemorySnapShot_Store(®s.sr, sizeof(regs.sr)); /* SR/CCR */
343: }
344: else
345: {
346: MemorySnapShot_Store(®s.usp, sizeof(regs.usp));
347: MemorySnapShot_Store(®s.isp, sizeof(regs.isp));
348: MemorySnapShot_Store(®s.sr, sizeof(regs.sr));
349: }
350: MemorySnapShot_Store(®s.stopped, sizeof(regs.stopped));
351: MemorySnapShot_Store(®s.dfc, sizeof(regs.dfc)); /* DFC */
352: MemorySnapShot_Store(®s.sfc, sizeof(regs.sfc)); /* SFC */
353: MemorySnapShot_Store(®s.vbr, sizeof(regs.vbr)); /* VBR */
1.1.1.17! root 354: #if ENABLE_WINUAE_CPU
! 355: MemorySnapShot_Store(®s.caar, sizeof(regs.caar)); /* CAAR */
! 356: MemorySnapShot_Store(®s.cacr, sizeof(regs.cacr)); /* CACR */
! 357: #else
1.1.1.12 root 358: MemorySnapShot_Store(&caar, sizeof(caar)); /* CAAR */
359: MemorySnapShot_Store(&cacr, sizeof(cacr)); /* CACR */
1.1.1.17! root 360: #endif
1.1.1.12 root 361: MemorySnapShot_Store(®s.msp, sizeof(regs.msp)); /* MSP */
362:
363: if (!bSave)
364: {
365: M68000_SetPC(regs.pc);
366: /* MakeFromSR() must not swap stack pointer */
367: regs.s = (regs.sr >> 13) & 1;
368: MakeFromSR();
369: /* set stack pointer */
370: if (regs.s)
371: m68k_areg(regs, 7) = regs.isp;
372: else
373: m68k_areg(regs, 7) = regs.usp;
374: }
375:
1.1.1.17! root 376: #if ENABLE_WINUAE_CPU
! 377: if (bSave)
! 378: save_fpu(&len,0);
! 379: else
! 380: restore_fpu(chunk);
! 381: #else
1.1.1.12 root 382: if (bSave)
383: save_fpu();
384: else
385: restore_fpu();
1.1.1.17! root 386: #endif
1.1 root 387: }
388:
389:
1.1.1.3 root 390: /*-----------------------------------------------------------------------*/
1.1.1.12 root 391: /**
392: * BUSERROR - Access outside valid memory range.
1.1.1.17! root 393: * Use bRead = 0 for write errors and bRead = 1 for read errors!
1.1.1.12 root 394: */
1.1.1.17! root 395: void M68000_BusError(Uint32 addr, bool bRead)
1.1 root 396: {
1.1.1.12 root 397: /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */
398: // BusErrorPC = M68000_GetPC(); /* [NP] We set BusErrorPC in m68k_run_1 */
1.1.1.7 root 399:
1.1.1.15 root 400: /* Do not print message when TOS is testing for available HW or
401: * when a program just checks for the floating point co-processor. */
402: if ((BusErrorPC < TosAddress || BusErrorPC > TosAddress + TosSize)
403: && addr != 0xfffa42)
1.1.1.12 root 404: {
1.1.1.15 root 405: /* Print bus error message */
1.1.1.17! root 406: fprintf(stderr, "M68000 Bus Error %s at address $%x.\n",
! 407: bRead ? "reading" : "writing", addr);
1.1.1.12 root 408: }
409:
410: if ((regs.spcflags & SPCFLAG_BUSERROR) == 0) /* [NP] Check that the opcode has not already generated a read bus error */
411: {
412: BusErrorAddress = addr; /* Store for exception frame */
1.1.1.17! root 413: bBusErrorReadWrite = bRead;
1.1.1.12 root 414: M68000_SetSpecial(SPCFLAG_BUSERROR); /* The exception will be done in newcpu.c */
415: }
1.1 root 416: }
417:
1.1.1.3 root 418:
419: /*-----------------------------------------------------------------------*/
1.1.1.12 root 420: /**
421: * Exception handler
422: */
1.1.1.13 root 423: void M68000_Exception(Uint32 ExceptionVector , int ExceptionSource)
1.1.1.12 root 424: {
425: int exceptionNr = ExceptionVector/4;
426:
1.1.1.16 root 427: if ((ExceptionSource == M68000_EXC_SRC_AUTOVEC)
428: && (exceptionNr>24 && exceptionNr<32)) /* 68k autovector interrupt? */
1.1.1.12 root 429: {
430: /* Handle autovector interrupts the UAE's way
431: * (see intlev() and do_specialties() in UAE CPU core) */
432: /* In our case, this part is only called for HBL and VBL interrupts */
433: int intnr = exceptionNr - 24;
434: pendingInterrupts |= (1 << intnr);
435: M68000_SetSpecial(SPCFLAG_INT);
436: }
1.1.1.13 root 437:
438: else /* MFP or direct CPU exceptions */
1.1.1.12 root 439: {
440: Uint16 SR;
441:
442: /* Was the CPU stopped, i.e. by a STOP instruction? */
443: if (regs.spcflags & SPCFLAG_STOP)
444: {
445: regs.stopped = 0;
446: M68000_UnsetSpecial(SPCFLAG_STOP); /* All is go,go,go! */
447: }
448:
449: /* 68k exceptions are handled by Exception() of the UAE CPU core */
1.1.1.17! root 450: #if ENABLE_WINUAE_CPU
! 451: Exception(exceptionNr, m68k_getpc(), ExceptionSource);
! 452: #else
1.1.1.12 root 453: #ifdef UAE_NEWCPU_H
1.1.1.13 root 454: Exception(exceptionNr, m68k_getpc(), ExceptionSource);
1.1.1.12 root 455: #else
456: Exception(exceptionNr, ®s, m68k_getpc(®s));
457: #endif
1.1.1.17! root 458: #endif
1.1.1.12 root 459: SR = M68000_GetSR();
460:
461: /* Set Status Register so interrupt can ONLY be stopped by another interrupt
462: * of higher priority! */
1.1.1.16 root 463: if (ExceptionSource == M68000_EXC_SRC_INT_MFP)
1.1.1.12 root 464: {
465: Uint32 MFPBaseVector = (unsigned int)(MFP_VR&0xf0)<<2;
466: if ( (ExceptionVector>=MFPBaseVector) && (ExceptionVector<=(MFPBaseVector+0x3c)) )
467: SR = (SR&SR_CLEAR_IPL)|0x0600; /* MFP, level 6 */
468: }
1.1.1.16 root 469: else if (ExceptionSource == M68000_EXC_SRC_INT_DSP)
470: {
471: SR = (SR&SR_CLEAR_IPL)|0x0600; /* DSP, level 6 */
472: }
1.1.1.12 root 473:
474: M68000_SetSR(SR);
475: }
1.1 root 476: }
477:
1.1.1.8 root 478:
479: /*-----------------------------------------------------------------------*/
1.1.1.12 root 480: /**
481: * There seem to be wait states when a program accesses certain hardware
482: * registers on the ST. Use this function to simulate these wait states.
483: * [NP] with some instructions like CLR, we have a read then a write at the
484: * same location, so we may have 2 wait states (read and write) to add
485: * (nWaitStateCycles should be reset to 0 after the cycles were added).
486: */
1.1.1.11 root 487: void M68000_WaitState(int nCycles)
1.1.1.8 root 488: {
1.1.1.12 root 489: M68000_SetSpecial(SPCFLAG_EXTRA_CYCLES);
1.1.1.11 root 490:
1.1.1.12 root 491: nWaitStateCycles += nCycles; /* add all the wait states for this instruction */
1.1.1.8 root 492: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.