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

1.1     ! root        1: /*
        !             2:   Hatari
        !             3: 
        !             4:   M68000 - CPU. This handles exception handling as well as a few OpCode's such as Line-F and Line-A.
        !             5:   We also have a function to save off the last 'x' instruction ran which is very handy for debugging
        !             6:   as we can see what code was run before a crash etc...
        !             7:   (Other CPU functions can be found in 'decode.asm/.inc')
        !             8: */
        !             9: 
        !            10: #include "main.h"
        !            11: #include "bios.h"
        !            12: #include "cart.h"
        !            13: #include "debug.h"
        !            14: #include "decode.h"
        !            15: #include "disass.h"
        !            16: #include "fdc.h"
        !            17: #include "gemdos.h"
        !            18: #include "ikbd.h"
        !            19: #include "int.h"
        !            20: #include "m68000.h"
        !            21: #include "memAlloc.h"
        !            22: #include "memorySnapShot.h"
        !            23: #include "mfp.h"
        !            24: #include "misc.h"
        !            25: #include "psg.h"
        !            26: #include "screen.h"
        !            27: #include "stMemory.h"
        !            28: #include "tos.h"
        !            29: #include "vdi.h"
        !            30: #include "view.h"
        !            31: #include "xbios.h"
        !            32: 
        !            33: 
        !            34: /* Taken from Decode.asm - Thothy */
        !            35: /* These should be replaced with UAE's CPU core equivalents one day */
        !            36: unsigned short SR_Before;
        !            37: unsigned long ExceptionVector;
        !            38: short int PendingInterruptFlag;
        !            39: void *PendingInterruptFunction;
        !            40: short int PendingInterruptCount;
        !            41: int SoundCycles;
        !            42: BOOL bInSuperMode;
        !            43: unsigned long EmuCCode;
        !            44: unsigned long BusAddressLocation;
        !            45: 
        !            46: 
        !            47: /* Use these if want to bring up any bus/address error, else uses 68000 vector handler */
        !            48: #ifndef FINAL_VERSION
        !            49: //  #define TRAP_BUSERROR_HISTORY                 // Output history on true Bus Error(bombs display)
        !            50: //  #define TRAP_ADDRESSERROR_HISTORY             // Or Address Error
        !            51: //  #define TRAP_ILLEGALINSTRUCTIONERROR_HISTORY  // Or Illegal Instruction
        !            52: #endif
        !            53: 
        !            54: BOOL bDoTraceException;          /* Do TRACE? */
        !            55: 
        !            56: 
        !            57: //-----------------------------------------------------------------------
        !            58: /*
        !            59:   Reset CPU 68000 variables
        !            60: */
        !            61: void M68000_Reset(BOOL bCold)
        !            62: {
        !            63:   int i;
        !            64: 
        !            65:   // Clear registers, set PC, SR and stack pointers
        !            66:   if (bCold) {
        !            67:     for(i=0; i<(16+1); i++)
        !            68:       Regs[i] = 0;
        !            69:   }
        !            70:   PC = TOSAddress;                            /* Start of TOS image, 0xfc0000 or 0xe00000 */
        !            71:   SR = 0x2700;                                /* Starting status register */
        !            72:   bDoTraceException = FALSE;                  /* No TRACE exceptions */
        !            73:   bInSuperMode = TRUE;                        /* We begin in supervisor mode */
        !            74:   Regs[REG_A7] = Regs[REG_A8] = 0x0000f000;   /* Stack default */
        !            75:   Reg_SuperSP = (unsigned long)&Regs[REG_A7]; /* So use this register as our stack */
        !            76:   Reg_UserSP = (unsigned long)&Regs[REG_A8];
        !            77:   PendingInterruptFlag = 0;        // Clear pending flag
        !            78: 
        !            79:   // Read Supervisor Stack/PC for warm reset
        !            80:   if (!bCold) {
        !            81:     Regs[REG_A8] = STMemory_ReadLong(0x00000000);
        !            82:     PC = STMemory_ReadLong(0x00000004);
        !            83:   }
        !            84: 
        !            85:   // Hold display for extended VDI resolutions(under init our VDI)
        !            86:   bHoldScreenDisplay = TRUE;
        !            87: }
        !            88: 
        !            89: //-----------------------------------------------------------------------
        !            90: /*
        !            91:   Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
        !            92: */
        !            93: void M68000_MemorySnapShot_Capture(BOOL bSave)
        !            94: {
        !            95:   // Save/Restore details
        !            96:   MemorySnapShot_Store(&bDoTraceException,sizeof(bDoTraceException));
        !            97: }
        !            98: 
        !            99: //-----------------------------------------------------------------------
        !           100: /*
        !           101:   Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
        !           102:   This is for 'decode.asm' variables - as cannot use 'decode.c' as will overwrite assembler .obj file!
        !           103: */
        !           104: void M68000_Decode_MemorySnapShot_Capture(BOOL bSave)
        !           105: {
        !           106:   int ID;
        !           107: 
        !           108:   // Save/Restore details
        !           109:   MemorySnapShot_Store(Regs,sizeof(Regs));
        !           110:   MemorySnapShot_Store(&STRamEnd,sizeof(STRamEnd));
        !           111:   MemorySnapShot_Store(&STRamEnd_BusErr,sizeof(STRamEnd_BusErr));
        !           112:   MemorySnapShot_Store(&PendingInterruptCount,sizeof(PendingInterruptCount));
        !           113:   MemorySnapShot_Store(&PendingInterruptFlag,sizeof(PendingInterruptFlag));
        !           114:   if (bSave) {
        !           115:     // Convert function to ID
        !           116:     ID = Int_HandlerFunctionToID(PendingInterruptFunction);
        !           117:     MemorySnapShot_Store(&ID,sizeof(int));
        !           118:   }
        !           119:   else {
        !           120:     // Convert ID to function
        !           121:     MemorySnapShot_Store(&ID,sizeof(int));
        !           122:     PendingInterruptFunction = Int_IDToHandlerFunction(ID);
        !           123:   }
        !           124:   MemorySnapShot_Store(&PC,sizeof(PC));
        !           125:   MemorySnapShot_Store(&SR,sizeof(SR));
        !           126:   MemorySnapShot_Store(&SR_Before,sizeof(SR_Before));
        !           127:   MemorySnapShot_Store(&bInSuperMode,sizeof(bInSuperMode));
        !           128:   MemorySnapShot_Store(&Reg_SuperSP,sizeof(Reg_SuperSP));
        !           129:   MemorySnapShot_Store(&Reg_UserSP,sizeof(Reg_UserSP));
        !           130:   MemorySnapShot_Store(&EmuCCode,sizeof(EmuCCode));
        !           131:   MemorySnapShot_Store(&ExceptionVector,sizeof(ExceptionVector));  
        !           132: }
        !           133: 
        !           134: //-----------------------------------------------------------------------
        !           135: /*
        !           136:   ILLEGAL - Unknown 68000 OpCode
        !           137: */
        !           138: void M68000_IllegalInstruction(void)
        !           139: {
        !           140: fprintf(stderr, "M68000_IllegalInstruction\n");
        !           141:   ADD_CYCLES(34,4,3);
        !           142:   ExceptionVector = EXCEPTION_ILLEGALINS;  /* Illegal vector */
        !           143:   M68000_Exception();        /* Cause trap */
        !           144: //  RET;
        !           145: }
        !           146: 
        !           147: //-----------------------------------------------------------------------
        !           148: /*
        !           149:   BUSERROR - Access outside valid memory range
        !           150: */
        !           151: void M68000_BusError(unsigned long addr)
        !           152: {
        !           153:  /* Reset PC's stack to normal(as may have done many calls) so return to
        !           154:     correct level after exception.
        !           155:     Enter here with 'ebp' as address we tried to access */
        !           156: fprintf(stderr, "M68000_BusError at address $%lx\n", (long)addr);
        !           157:  BusAddressLocation=addr;    /* Store for exception frame */
        !           158:  ExceptionVector = EXCEPTION_BUSERROR;  /* Handler */
        !           159:  M68000_Exception();      /* Cause trap */
        !           160: /*
        !           161:  asm("  mov  [BusAddressLocation],ebp\n"      // Store for exception frame
        !           162:      "  mov  esp,[StackSave]\n"        // Restore stack
        !           163:      "  mov  [ExceptionVector],EXCEPTION_BUSERROR\n");  // Handler
        !           164:  SAVE_ASSEM_REGS();            // Save assembly registers
        !           165:  asm("   call  M68000_Exception\n");        // Cause trap
        !           166:  RESTORE_ASSEM_REGS();            // Restore assembly registers
        !           167:  RET;                // Start decoding
        !           168: */
        !           169: }
        !           170: 
        !           171: //-----------------------------------------------------------------------
        !           172: /*
        !           173:   ADDRESSERROR - Access incorrect memory boundary, eg byte offset for a word access
        !           174: */
        !           175: void M68000_AddressError(unsigned long addr)
        !           176: {
        !           177: fprintf(stderr, "M68000_AddressError at address $%lx\n", (long)addr);
        !           178:  BusAddressLocation=addr;    /* Store for exception frame */
        !           179:  ExceptionVector=EXCEPTION_ADDRERROR;  /* Handler */
        !           180:  M68000_Exception();      /* Cause trap */
        !           181: /*
        !           182:  // Reset PC's stack to normal(as may have done many calls) so return to correct level after exception
        !           183:  __asm {
        !           184:   // Enter here with 'ebp' as address we tried to access
        !           185:   mov    [BusAddressLocation],ebp    // Store for exception frame
        !           186:   mov    esp,[StackSave]        // Restore stack
        !           187:   mov    [ExceptionVector],EXCEPTION_ADDRERROR  // Handler
        !           188:   SAVE_ASSEM_REGS            // Save assembly registers
        !           189:   call  M68000_Exception        // Cause trap
        !           190:   RESTORE_ASSEM_REGS          // Restore assembly registers
        !           191:   }
        !           192:   RET                // Start decoding
        !           193: */  
        !           194: }
        !           195: 
        !           196: //-----------------------------------------------------------------------
        !           197: /*
        !           198:   See if in user/super mode and if need to swap SP
        !           199: */
        !           200: void M68000_CheckUserSuperToggle(void)
        !           201: {
        !           202:   unsigned long *TempReg;
        !           203:   unsigned long TempSP;
        !           204: 
        !           205:   // Have we swapped mode?
        !           206:   if ( (SR_Before&SR_SUPERMODE)!=(SR&SR_SUPERMODE) ) {
        !           207:     // Yes, swap to ST's REG_A8!
        !           208:     TempSP = Regs[REG_A7];
        !           209:     Regs[REG_A7] = Regs[REG_A8];
        !           210:     Regs[REG_A8] = TempSP;
        !           211: 
        !           212:     // And keep track of which of our registers is the supermode stack pointer
        !           213:     TempReg = (unsigned long *)Reg_SuperSP;
        !           214:     Reg_SuperSP = Reg_UserSP;
        !           215:     Reg_UserSP = (unsigned long)TempReg;
        !           216: 
        !           217:     // Swap super flag
        !           218:     bInSuperMode^=TRUE;
        !           219:   }
        !           220: 
        !           221:   // Set/Clear trace mode
        !           222:   if (SR&SR_TRACEMODE) {
        !           223:     // Have we set the TRACE bit for the FIRST time? Don't let exception occur until NEXT instruction
        !           224:     // NOTE Sometimes the TRACE bit can be set many times, so only skip exception on FIRST one
        !           225:     if ((PendingInterruptFlag&PENDING_INTERRUPT_FLAG_TRACE)==0) {
        !           226:       PendingInterruptFlag |= PENDING_INTERRUPT_FLAG_TRACE;
        !           227:       bDoTraceException = FALSE;
        !           228:     }
        !           229:   }
        !           230:   else
        !           231:     PendingInterruptFlag &= CLEAR_PENDING_INTERRUPT_FLAG_TRACE;
        !           232: }
        !           233: 
        !           234: //-----------------------------------------------------------------------
        !           235: /*
        !           236:   Called when TRACE bit is set. This causes 'exception' after each instruction, BUT
        !           237:   it does not execute after the FIRST 'move SR,xxxx' to set the bit
        !           238: */
        !           239: void M68000_TraceModeTriggered(void)
        !           240: {
        !           241: /* FIXME */
        !           242: /*
        !           243:   __asm {
        !           244:     cmp    [bDoTraceException],FALSE    // First time around? Skip exception
        !           245:     je    dont_need_expection
        !           246: 
        !           247:     mov    [ExceptionVector],EXCEPTION_TRACE  // Handler
        !           248:     SAVE_ASSEM_REGS            // Save assembly registers
        !           249:     call  M68000_Exception        // Cause trap
        !           250:     RESTORE_ASSEM_REGS          // Restore assembly registers
        !           251: 
        !           252: dont_need_expection:;
        !           253:     mov    [bDoTraceException],TRUE    // Do TRACE exception next time around
        !           254:     ret
        !           255:   }
        !           256: */
        !           257: }
        !           258: 
        !           259: //-----------------------------------------------------------------------
        !           260: /*
        !           261:   Exception handler
        !           262: */
        !           263: void M68000_Exception(void)
        !           264: {
        !           265:   unsigned long Vector,MFPBaseVector;
        !           266:   BOOL bRet=FALSE;
        !           267: 
        !           268:   /* At the moment, this functions ist just a wrapper to Exception() of the UAE CPU - Thothy */
        !           269:   Exception(ExceptionVector/4, m68k_getpc());
        !           270:   return;
        !           271: 
        !           272: #if 0
        !           273:   // Was the CPU stopped, ie by a STOP instruction?
        !           274: /* FIXME: */
        !           275: /*
        !           276:   if (CPUStopped) {
        !           277:     PC += 4;    // Skip after the STOP instruction as CPU is now to resume!
        !           278:     CPUStopped = FALSE;  // All is go,go,go!
        !           279:   }
        !           280: */
        !           281:   /* Find exception vector, keep 32-bit address as top byte is used by TOS */
        !           282:   /* exception vectors as an ID! */
        !           283:   Vector = STMemory_ReadLong(ExceptionVector);
        !           284: 
        !           285:   /* Check for intercept - The game 'Operation Wolf' re-directs traps, */
        !           286:   /* so double check is a TOS trap and not software! (ie Vector is >0xE00000) */
        !           287:   if ((Vector&0xffffff)>=0xE00000) {
        !           288:     if (ExceptionVector==EXCEPTION_TRAP13)
        !           289:       bRet = Bios();
        !           290:     else if (ExceptionVector==EXCEPTION_TRAP14)
        !           291:       bRet = XBios();
        !           292:     else if (ExceptionVector==EXCEPTION_TRAP1)
        !           293:       bRet = GemDOS();
        !           294:     else if (ExceptionVector==EXCEPTION_TRAP2) {
        !           295:       bRet = VDI();
        !           296:       if (!bRet) {
        !           297:         // Set 'PC' as address of 'VDI_OPCODE' illegal instruction
        !           298:         // This will call VDI_OpCode after completion of Trap call!
        !           299:         // Use to modify return structure from VDI
        !           300:         if (bUseVDIRes) {
        !           301:           VDI_OldPC = PC;
        !           302:           PC = CART_VDI_OPCODE_ADDR;
        !           303:         }
        !           304:       }
        !           305:     }
        !           306: 
        !           307:   // Do handly bit of debugging to trap bus/address errors, before goes to TOS handler
        !           308: #ifdef TRAP_BUSERROR_HISTORY
        !           309:     if (ExceptionVector==EXCEPTION_BUSERROR) {
        !           310:       MessageBox(NULL,"TRAP BUS ERROR",PROG_NAME,MB_OK | MB_ICONSTOP);
        !           311:       Debug_File("TRAP BUS ERROR\n");
        !           312:       M68000_OutputHistory();
        !           313:       exit(0);
        !           314:     }
        !           315: #endif
        !           316: #ifdef TRAP_ADDRESSERROR_HISTORY
        !           317:     if (ExceptionVector==EXCEPTION_ADDRERROR) {
        !           318:       MessageBox(NULL,"TRAP ADDRESS ERROR",PROG_NAME,MB_OK | MB_ICONSTOP);
        !           319:       Debug_File("TRAP ADDRESS ERROR\n");
        !           320:       M68000_OutputHistory();
        !           321:       exit(0);
        !           322:     }
        !           323: #endif
        !           324: #ifdef TRAP_ILLEGALINSTRUCTIONERROR_HISTORY
        !           325:     if (ExceptionVector==EXCEPTION_ILLEGALINS) {
        !           326:       MessageBox(NULL,"TRAP ILLEGAL INSTRUCTION ERROR",PROG_NAME,MB_OK | MB_ICONSTOP);
        !           327:       Debug_File("TRAP ILLEGAL INSTRUCTION ERROR\n");
        !           328:       M68000_OutputHistory();
        !           329:       exit(0);
        !           330:     }
        !           331: #endif
        !           332:   }
        !           333: 
        !           334:   // Did we re-direct call? No, so let's call it!
        !           335:   if (!bRet) {
        !           336:     // Save PC and SR to supervisor stack
        !           337: /* FIXME */
        !           338: /*
        !           339:     __asm {
        !           340:       push  ebp
        !           341: 
        !           342:       mov    edx,[Reg_SuperSP]
        !           343: 
        !           344:       sub    DWORD PTR [edx],SIZE_LONG
        !           345:       mov    ebp,[edx]        // Stack pointer
        !           346:       and    ebp,0xffffff        // as 24-bit address in PC memory(note _C)
        !           347:       mov    ecx,[PC]        // Save PC
        !           348:       SWAP_ENDIAN_LONG_ECX
        !           349:       mov    DWORD PTR STRam[ebp],ecx
        !           350: 
        !           351:       sub    DWORD PTR [edx],SIZE_WORD
        !           352:       mov    ebp,[edx]        // Stack pointer
        !           353:       and    ebp,0xffffff        // as 24-bit address in PC memory(note _C)
        !           354:       mov    cx,WORD PTR [SR]
        !           355:       and    ecx,SR_MASK        // Remove condition codes
        !           356:       mov    eax,[EmuCCode]
        !           357:       shr    eax,4          // Emulation codes in correct bits
        !           358:       and    eax,SR_CCODE_MASK
        !           359:       or    eax,ecx          // Or in current condition codes
        !           360:       SWAP_ENDIAN_WORD_AX
        !           361:       mov    WORD PTR STRam[ebp],ax
        !           362: 
        !           363:       pop    ebp
        !           364:     }
        !           365: */
        !           366:     // Exception frame, total 14 bytes (6 already put on stack, ie PC and SR)
        !           367:     //       15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
        !           368:     // SSP->|                                |RW|IN|Func.cod|         Higher
        !           369:     // address
        !           370:     //      |High word access address                       |
        !           371:     //      |Low word access address                        |
        !           372:     //      |Instruction register                           |
        !           373:     //      |Status register                                |
        !           374:     //      |High word program counter                      |
        !           375:     //      |Low word program counter                       |         Lower address
        !           376:     // 
        !           377:     // RW: Write=0, Read=1
        !           378:     // IN: Instruction=0, Not=1
        !           379:     if ( (ExceptionVector==EXCEPTION_BUSERROR) || (ExceptionVector==EXCEPTION_ADDRERROR) ) {
        !           380: /* FIXME */
        !           381: /*
        !           382:       __asm {
        !           383:         push  ebp
        !           384: 
        !           385:         mov    ebp,[InsPC]      // Get PC of instruction last ran
        !           386:         mov    cx,WORD PTR [ebp]    // 'Opcode' in 68000 endian
        !           387:         mov    edx,[Reg_SuperSP]
        !           388:         sub    DWORD PTR [edx],SIZE_WORD
        !           389:         mov    ebp,[edx]      // Stack pointer
        !           390:         and    ebp,0xffffff      // as 24-bit address in PC memory(note _C)
        !           391:         mov    WORD PTR STRam[ebp],cx    // Store 'Instruction Register'
        !           392: 
        !           393:         sub    DWORD PTR [edx],SIZE_LONG
        !           394:         mov    ebp,[edx]      // Stack pointer
        !           395:         and    ebp,0xffffff      // as 24-bit address in PC memory(note _C)
        !           396:         mov    ecx,[BusAddressLocation]  // Address which caused fault
        !           397:         SWAP_ENDIAN_LONG_ECX
        !           398:         mov    DWORD PTR STRam[ebp],ecx
        !           399: 
        !           400:         sub    DWORD PTR [edx],SIZE_WORD
        !           401:         mov    ebp,[edx]      // Stack pointer
        !           402:         and    ebp,0xffffff      // as 24-bit address in PC memory(note _C)
        !           403:         xor    ecx,ecx
        !           404:         mov    WORD PTR STRam[ebp],cx    // '0' for now
        !           405: 
        !           406:         pop    ebp
        !           407:       }
        !           408: */
        !           409:     }
        !           410: 
        !           411:     SR_Before = SR;
        !           412:     SR &= SR_CLEAR_TRACEMODE;            // Clear trace mode (bit 15)
        !           413:     SR |= SR_SUPERMODE;                // Set super mode (bit 13)
        !           414:     M68000_CheckUserSuperToggle();          // Check if swapped mode
        !           415: 
        !           416:     // Do call to vector
        !           417: //    char szString[256];
        !           418: //    sprintf(szString,"0x%X (0x%X)",Vector,ExceptionVector);
        !           419: //    debug << szString << endl;
        !           420:     PC = Vector;
        !           421:     // Set Status Register so interrupt can ONLY be stopped by another interrupt of higher priority!
        !           422:     if (ExceptionVector==EXCEPTION_VBLANK)
        !           423:       SR = (SR&SR_CLEAR_IPL)|0x0400;        // VBL, level 4
        !           424:     else if (ExceptionVector==EXCEPTION_HBLANK)
        !           425:       SR = (SR&SR_CLEAR_IPL)|0x0200;        // HBL, level 2    
        !           426:     else {
        !           427:       MFPBaseVector = (unsigned int)(MFP_VR&0xf0)<<2;
        !           428:       if ( (ExceptionVector>=MFPBaseVector) && (ExceptionVector<=(MFPBaseVector+0x34)) )
        !           429:         SR = (SR&SR_CLEAR_IPL)|0x0600;      // MFP, level 6
        !           430:     }
        !           431:   }
        !           432: #endif
        !           433: }
        !           434: 
        !           435: //-----------------------------------------------------------------------
        !           436: /*
        !           437:   Handle Line-A OpCode exception(Top 4-bit in opcode are 0xA)
        !           438: */
        !           439: /*
        !           440: void M68000_Line_A_OpCode_Execute(void)
        !           441: {
        !           442:   PC -= SIZE_WORD;    // PC needs to be at address of Line-A instruction
        !           443:   ExceptionVector = EXCEPTION_LINE_A;
        !           444:   M68000_Exception();
        !           445: }
        !           446: 
        !           447: void M68000_Line_A_OpCode(void)
        !           448: {
        !           449: //FIXME   SAVE_ASSEM_REGS();        // Save assembly registers
        !           450:   M68000_Line_A_OpCode_Execute();
        !           451: //  RESTORE_ASSEM_REGS();        // Restore assembly registers
        !           452: //  RET;
        !           453: }
        !           454: */
        !           455: 
        !           456: //-----------------------------------------------------------------------
        !           457: /*
        !           458:   During init do 0xA000, followed by 0xA0FF - we use this to get pointer to Line-A structure details(to fix for extended VDI res)
        !           459: */
        !           460: void M68000_Line_A_Trap(void)
        !           461: {
        !           462: /* FIXME */
        !           463: /*
        !           464: 
        !           465:   PUSH_ALL
        !           466:   __asm {
        !           467:     mov    edx,DWORD PTR Regs[REG_D0*4]
        !           468:     mov    [LineABase],edx
        !           469:     mov    edx,DWORD PTR Regs[REG_A1*4]
        !           470:     mov    [FontBase],edx
        !           471:     call  VDI_LineA                // Modify Line-A structure
        !           472:   }
        !           473:   POP_ALL
        !           474:   RET
        !           475: */
        !           476: }
        !           477: 
        !           478: //-----------------------------------------------------------------------
        !           479: /*
        !           480:   Handle Line-F OpCode exception(Top 4-bit in opcode are 0xF)
        !           481: */
        !           482: /*
        !           483: void M68000_Line_F_OpCode_Execute(void)
        !           484: {
        !           485:   PC -= SIZE_WORD;    // PC needs to be at address of Line-F instruction
        !           486:   ExceptionVector = EXCEPTION_LINE_F;
        !           487:   M68000_Exception();
        !           488: }
        !           489: 
        !           490: void M68000_Line_F_OpCode(void)
        !           491: {
        !           492: //FIXME   SAVE_ASSEM_REGS();    // Save assembly registers
        !           493:   M68000_Line_F_OpCode_Execute();
        !           494: //  RESTORE_ASSEM_REGS();      // Restore assembly registers
        !           495: //  RET;
        !           496: }
        !           497: */
        !           498: 
        !           499: //-----------------------------------------------------------------------
        !           500: /*
        !           501:   Use 'InsPC' to find how many cycles last instruction took to execute
        !           502: */
        !           503: int M68000_FindLastInstructionCycles(void)
        !           504: {
        !           505:   unsigned short int OpCode;
        !           506: 
        !           507: //FIXME   OpCode = *(unsigned short int *)InsPC;      // Read 'opcode'
        !           508: //FIXME   return( DecodeTable[(OpCode*SIZEOF_DECODE)+(DECODE_CYCLES/sizeof(long))] );
        !           509:   return 4; /* Ouargs ... this is an uggly hack */
        !           510: }
        !           511: 
        !           512: //-----------------------------------------------------------------------
        !           513: /*
        !           514:   Output CPU instruction history(last 'x' instructions) for debugging
        !           515: */
        !           516: void M68000_OutputHistory(void)
        !           517: {
        !           518: #ifndef FINAL_VERSION
        !           519:   unsigned long StartPC;
        !           520:   int i;
        !           521: 
        !           522:   /* First, Return back into a Window */
        !           523:   Screen_ReturnFromFullScreen();
        !           524:   View_ToggleWindowsMouse(MOUSE_WINDOWS);
        !           525: 
        !           526:   Debug_File("HISTORY\n");
        !           527: 
        !           528:   for(i=0; i<(INSTRUCTION_HISTORY_SIZE-1); i++) {
        !           529:     StartPC = DisPC = InstructionHistory[(InstructionHistoryIndex+i+1)&INSTRUCTION_HISTORY_MASK];
        !           530:     Disass_DiassembleLine();            // Disassemble instruction
        !           531: 
        !           532:     Debug_File("%8.8X\t%s\n",StartPC,szOpString);
        !           533:   }
        !           534: #endif
        !           535: }

unix.superglobalmegacorp.com

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