Annotation of hatari/src/m68000.c, revision 1.1.1.11

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.