|
|
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.8 ! root 11: char M68000_rcsid[] = "Hatari $Id: m68000.c,v 1.28 2004/06/11 10:04:46 thothy Exp $";
1.1 root 12:
13: #include "main.h"
14: #include "bios.h"
15: #include "debug.h"
16: #include "gemdos.h"
1.1.1.6 root 17: #include "hatari-glue.h"
1.1 root 18: #include "int.h"
19: #include "m68000.h"
20: #include "memorySnapShot.h"
21: #include "mfp.h"
22: #include "stMemory.h"
23: #include "tos.h"
24: #include "vdi.h"
25: #include "xbios.h"
26:
27:
28: void *PendingInterruptFunction;
29: short int PendingInterruptCount;
1.1.1.8 ! root 30:
1.1.1.7 root 31: Uint32 BusAddressLocation; /* Stores the offending address for bus-/address errors */
32: Uint32 BusErrorPC; /* Value of the PC when bus error occurs */
1.1.1.8 ! root 33: BOOL bBusErrorReadWrite; /* 0 for write error, 1 for read error */
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.8 ! root 148: void M68000_BusError(unsigned long 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.7 root 159: BusAddressLocation = 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: ADDRESSERROR - Access incorrect memory boundary, eg byte offset for a word access
168: */
169: void M68000_AddressError(unsigned long addr)
170: {
1.1.1.3 root 171: fprintf(stderr, "M68000_AddressError at address $%lx\n", (long)addr);
1.1.1.8 ! root 172: BusAddressLocation = addr; /* Store for exception frame */
! 173: M68000_Exception(EXCEPTION_ADDRERROR); /* Cause trap */
1.1 root 174: }
175:
1.1.1.3 root 176:
177: /*-----------------------------------------------------------------------*/
1.1 root 178: /*
179: Exception handler
180: */
1.1.1.8 ! root 181: void M68000_Exception(Uint32 ExceptionVector)
1.1 root 182: {
1.1.1.6 root 183: int exceptionNr = ExceptionVector/4;
1.1.1.2 root 184:
1.1.1.6 root 185: if(exceptionNr>24 && exceptionNr<32) /* 68k autovector interrupt? */
186: {
187: /* Handle autovector interrupts the UAE's way
188: * (see intlev() and do_specialties() in UAE CPU core) */
1.1.1.8 ! root 189: int intnr = exceptionNr - 24;
! 190: pendingInterrupts |= (1 << intnr);
1.1.1.6 root 191: set_special(SPCFLAG_INT);
192: }
193: else
194: {
195: /* Was the CPU stopped, i.e. by a STOP instruction? */
1.1.1.8 ! root 196: if(regs.spcflags & SPCFLAG_STOP)
! 197: {
! 198: regs.stopped = 0;
! 199: unset_special(SPCFLAG_STOP); /* All is go,go,go! */
! 200: }
1.1.1.6 root 201:
202: /* 68k exceptions are handled by Exception() of the UAE CPU core */
203: Exception(exceptionNr, m68k_getpc());
204:
205: MakeSR();
206: /* Set Status Register so interrupt can ONLY be stopped by another interrupt
207: * of higher priority! */
208: #if 0 /* VBL and HBL are handled in the UAE CPU core (see above). */
209: if (ExceptionVector==EXCEPTION_VBLANK)
210: SR = (SR&SR_CLEAR_IPL)|0x0400; /* VBL, level 4 */
211: else if (ExceptionVector==EXCEPTION_HBLANK)
212: SR = (SR&SR_CLEAR_IPL)|0x0200; /* HBL, level 2 */
213: else
214: #endif
215: {
216: unsigned long MFPBaseVector = (unsigned int)(MFP_VR&0xf0)<<2;
217: if ( (ExceptionVector>=MFPBaseVector) && (ExceptionVector<=(MFPBaseVector+0x34)) )
218: SR = (SR&SR_CLEAR_IPL)|0x0600; /* MFP, level 6 */
219: }
220: MakeFromSR();
221: }
1.1 root 222: }
223:
1.1.1.8 ! root 224:
! 225: /*-----------------------------------------------------------------------*/
! 226: /*
! 227: There seem to be wait states when a program accesses certain hardware
! 228: registers on the ST. Use this function to simulate these wait states.
! 229: */
! 230: void M68000_WaitState(void)
! 231: {
! 232: set_special(SPCFLAG_EXTRA_CYCLES);
! 233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.