|
|
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.10! root 11: char M68000_rcsid[] = "Hatari $Id: m68000.c,v 1.33 2005/07/15 19:30:32 thothy Exp $";
1.1 root 12:
13: #include "main.h"
14: #include "bios.h"
15: #include "gemdos.h"
1.1.1.6 root 16: #include "hatari-glue.h"
1.1 root 17: #include "int.h"
18: #include "m68000.h"
19: #include "memorySnapShot.h"
20: #include "mfp.h"
21: #include "stMemory.h"
22: #include "tos.h"
23: #include "vdi.h"
24: #include "xbios.h"
25:
26:
27: void *PendingInterruptFunction;
28: short int PendingInterruptCount;
1.1.1.8 root 29:
1.1.1.9 root 30: Uint32 BusErrorAddress; /* Stores the offending address for bus-/address errors */
1.1.1.7 root 31: Uint32 BusErrorPC; /* Value of the PC when bus error occurs */
1.1.1.8 root 32: BOOL bBusErrorReadWrite; /* 0 for write error, 1 for read error */
1.1.1.9 root 33: int nCpuFreqShift; /* Used to emulate higher CPU frequencies: 0=8MHz, 1=16MHz, 2=32Mhz */
1.1 root 34:
35:
1.1.1.3 root 36: /*-----------------------------------------------------------------------*/
1.1 root 37: /*
38: Reset CPU 68000 variables
39: */
40: void M68000_Reset(BOOL bCold)
41: {
42: int i;
43:
1.1.1.7 root 44: /* Clear registers */
1.1.1.5 root 45: if (bCold)
46: {
1.1 root 47: for(i=0; i<(16+1); i++)
48: Regs[i] = 0;
49: }
1.1.1.7 root 50:
1.1.1.4 root 51: /* Now directly reset the UAE CPU core: */
52: m68k_reset();
1.1 root 53: }
54:
1.1.1.3 root 55:
56: /*-----------------------------------------------------------------------*/
1.1 root 57: /*
1.1.1.8 root 58: Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type)
1.1 root 59: */
60: void M68000_MemorySnapShot_Capture(BOOL bSave)
61: {
62: int ID;
1.1.1.8 root 63: Uint32 savepc;
1.1 root 64:
1.1.1.3 root 65: /* Save/Restore details */
1.1 root 66: MemorySnapShot_Store(Regs,sizeof(Regs));
67: MemorySnapShot_Store(&STRamEnd,sizeof(STRamEnd));
68: MemorySnapShot_Store(&PendingInterruptCount,sizeof(PendingInterruptCount));
1.1.1.5 root 69: if (bSave)
70: {
1.1.1.3 root 71: /* Convert function to ID */
1.1 root 72: ID = Int_HandlerFunctionToID(PendingInterruptFunction);
73: MemorySnapShot_Store(&ID,sizeof(int));
74: }
1.1.1.5 root 75: else
76: {
1.1.1.3 root 77: /* Convert ID to function */
1.1 root 78: MemorySnapShot_Store(&ID,sizeof(int));
79: PendingInterruptFunction = Int_IDToHandlerFunction(ID);
80: }
1.1.1.8 root 81:
82: /* For the UAE CPU core: */
83: MemorySnapShot_Store(&cpu_level, sizeof(cpu_level)); /* MODEL */
84: MemorySnapShot_Store(&address_space_24, sizeof(address_space_24));
85: MemorySnapShot_Store(®s.regs[0], sizeof(regs.regs)); /* D0-D7 A0-A6 */
86: if (bSave)
87: {
88: savepc = m68k_getpc();
89: MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */
90: }
91: else
92: {
93: MemorySnapShot_Store(&savepc, sizeof(savepc)); /* PC */
94: regs.pc = savepc;
95: regs.prefetch_pc = regs.pc + 128;
96: }
97: MemorySnapShot_Store(®s.prefetch, sizeof(regs.prefetch)); /* prefetch */
98: if (bSave)
99: {
100: MakeSR ();
101: if (regs.s)
102: {
103: MemorySnapShot_Store(®s.usp, sizeof(regs.usp)); /* USP */
104: MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* ISP */
105: }
106: else
107: {
108: MemorySnapShot_Store(®s.regs[15], sizeof(regs.regs[15])); /* USP */
109: MemorySnapShot_Store(®s.isp, sizeof(regs.isp)); /* ISP */
110: }
111: MemorySnapShot_Store(®s.sr, sizeof(regs.sr)); /* SR/CCR */
112: }
113: else
114: {
115: MemorySnapShot_Store(®s.usp, sizeof(regs.usp));
116: MemorySnapShot_Store(®s.isp, sizeof(regs.isp));
117: MemorySnapShot_Store(®s.sr, sizeof(regs.sr));
118: }
119: MemorySnapShot_Store(®s.stopped, sizeof(regs.stopped));
120: MemorySnapShot_Store(®s.dfc, sizeof(regs.dfc)); /* DFC */
121: MemorySnapShot_Store(®s.sfc, sizeof(regs.sfc)); /* SFC */
122: MemorySnapShot_Store(®s.vbr, sizeof(regs.vbr)); /* VBR */
123: MemorySnapShot_Store(®_caar, sizeof(reg_caar)); /* CAAR */
124: MemorySnapShot_Store(®_cacr, sizeof(reg_cacr)); /* CACR */
125: MemorySnapShot_Store(®s.msp, sizeof(regs.msp)); /* MSP */
126:
127: if (!bSave)
128: {
129: m68k_setpc (regs.pc);
130: /* MakeFromSR() must not swap stack pointer */
131: regs.s = (regs.sr >> 13) & 1;
132: MakeFromSR();
133: /* set stack pointer */
134: if (regs.s)
135: m68k_areg(regs, 7) = regs.isp;
136: else
137: m68k_areg(regs, 7) = regs.usp;
138: }
139:
1.1 root 140: }
141:
142:
1.1.1.3 root 143: /*-----------------------------------------------------------------------*/
1.1 root 144: /*
1.1.1.8 root 145: BUSERROR - Access outside valid memory range.
146: Use bReadWrite = 0 for write errors and bReadWrite = 1 for read errors!
1.1 root 147: */
1.1.1.10! root 148: void M68000_BusError(Uint32 addr, BOOL bReadWrite)
1.1 root 149: {
1.1.1.7 root 150: /* FIXME: In prefetch mode, m68k_getpc() seems already to point to the next instruction */
151: BusErrorPC = m68k_getpc();
152:
153: if(BusErrorPC < TosAddress || BusErrorPC > TosAddress + TosSize)
1.1.1.5 root 154: {
1.1.1.7 root 155: /* Print bus errors (except for TOS' hardware tests) */
1.1.1.5 root 156: fprintf(stderr, "M68000_BusError at address $%lx\n", (long)addr);
157: }
158:
1.1.1.9 root 159: BusErrorAddress = addr; /* Store for exception frame */
1.1.1.8 root 160: bBusErrorReadWrite = bReadWrite;
1.1.1.7 root 161: set_special(SPCFLAG_BUSERROR); /* The exception will be done in newcpu.c */
1.1 root 162: }
163:
1.1.1.3 root 164:
165: /*-----------------------------------------------------------------------*/
1.1 root 166: /*
167: Exception handler
168: */
1.1.1.8 root 169: void M68000_Exception(Uint32 ExceptionVector)
1.1 root 170: {
1.1.1.6 root 171: int exceptionNr = ExceptionVector/4;
1.1.1.2 root 172:
1.1.1.6 root 173: if(exceptionNr>24 && exceptionNr<32) /* 68k autovector interrupt? */
174: {
175: /* Handle autovector interrupts the UAE's way
176: * (see intlev() and do_specialties() in UAE CPU core) */
1.1.1.8 root 177: int intnr = exceptionNr - 24;
178: pendingInterrupts |= (1 << intnr);
1.1.1.6 root 179: set_special(SPCFLAG_INT);
180: }
181: else
182: {
183: /* Was the CPU stopped, i.e. by a STOP instruction? */
1.1.1.8 root 184: if(regs.spcflags & SPCFLAG_STOP)
185: {
186: regs.stopped = 0;
187: unset_special(SPCFLAG_STOP); /* All is go,go,go! */
188: }
1.1.1.6 root 189:
190: /* 68k exceptions are handled by Exception() of the UAE CPU core */
191: Exception(exceptionNr, m68k_getpc());
192:
193: MakeSR();
194: /* Set Status Register so interrupt can ONLY be stopped by another interrupt
195: * of higher priority! */
196: #if 0 /* VBL and HBL are handled in the UAE CPU core (see above). */
197: if (ExceptionVector==EXCEPTION_VBLANK)
198: SR = (SR&SR_CLEAR_IPL)|0x0400; /* VBL, level 4 */
199: else if (ExceptionVector==EXCEPTION_HBLANK)
200: SR = (SR&SR_CLEAR_IPL)|0x0200; /* HBL, level 2 */
201: else
202: #endif
203: {
1.1.1.10! root 204: Uint32 MFPBaseVector = (unsigned int)(MFP_VR&0xf0)<<2;
1.1.1.6 root 205: if ( (ExceptionVector>=MFPBaseVector) && (ExceptionVector<=(MFPBaseVector+0x34)) )
206: SR = (SR&SR_CLEAR_IPL)|0x0600; /* MFP, level 6 */
207: }
208: MakeFromSR();
209: }
1.1 root 210: }
211:
1.1.1.8 root 212:
213: /*-----------------------------------------------------------------------*/
214: /*
215: There seem to be wait states when a program accesses certain hardware
216: registers on the ST. Use this function to simulate these wait states.
217: */
218: void M68000_WaitState(void)
219: {
220: set_special(SPCFLAG_EXTRA_CYCLES);
221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.