void S9xMainLoop_SA1_APU (void) { for (;;) { UPDATE_APU_COUNTER(); if (CPUPack.CPU.Flags) { if (CPUPack.CPU.Flags & NMI_FLAG) { if (--CPUPack.CPU.NMICycleCount == 0) { CPUPack.CPU.Flags &= ~NMI_FLAG; if (CPUPack.CPU.WaitingForInterrupt) { CPUPack.CPU.WaitingForInterrupt = FALSE; CPUPack.CPU.PC++; } S9xOpcode_NMI (); } } if (CPUPack.CPU.Flags & IRQ_PENDING_FLAG) { if (CPUPack.CPU.IRQCycleCount == 0) { if (CPUPack.CPU.WaitingForInterrupt) { CPUPack.CPU.WaitingForInterrupt = FALSE; CPUPack.CPU.PC++; } if (IRQ_ACTIVE) { if (!CheckFlag (IRQ)) S9xOpcode_IRQ (); } else CPUPack.CPU.Flags &= ~IRQ_PENDING_FLAG; } else CPUPack.CPU.IRQCycleCount--; } if (CPUPack.CPU.Flags & SCAN_KEYS_FLAG) break; } #ifdef CPU_SHUTDOWN CPUPack.CPU.PCAtOpcodeStart = CPUPack.CPU.PC; #endif CPUPack.CPU.Cycles += CPUPack.CPU.MemSpeed; extern int os9x_SA1_exec; for(int i=0;i<os9x_SA1_exec;i++) (*CPUPack.ICPU.S9xOpcodes[*CPUPack.CPU.PC++].S9xOpcode) (); //S9xUpdateAPUTimer (); if (SA1Pack_SA1.Executing) S9xSA1MainLoop (); DO_HBLANK_CHECK (); } }
void S9xMainLoop_NoSA1_NoAPU (void) { for (;;) { if (CPUPack.CPU.Flags) { if (CPUPack.CPU.Flags & NMI_FLAG) { if (--CPUPack.CPU.NMICycleCount == 0) { CPUPack.CPU.Flags &= ~NMI_FLAG; if (CPUPack.CPU.WaitingForInterrupt) { CPUPack.CPU.WaitingForInterrupt = FALSE; CPUPack.CPU.PC++; } S9xOpcode_NMI (); } } if (CPUPack.CPU.Flags & IRQ_PENDING_FLAG) { if (CPUPack.CPU.IRQCycleCount == 0) { if (CPUPack.CPU.WaitingForInterrupt) { CPUPack.CPU.WaitingForInterrupt = FALSE; CPUPack.CPU.PC++; } if (IRQ_ACTIVE) { if (!CheckFlag (IRQ)) S9xOpcode_IRQ (); } else CPUPack.CPU.Flags &= ~IRQ_PENDING_FLAG; } else CPUPack.CPU.IRQCycleCount--; } if (CPUPack.CPU.Flags & SCAN_KEYS_FLAG) break; } #ifdef CPU_SHUTDOWN CPUPack.CPU.PCAtOpcodeStart = CPUPack.CPU.PC; #endif CPUPack.CPU.Cycles += CPUPack.CPU.MemSpeed; (*CPUPack.ICPU.S9xOpcodes[*CPUPack.CPU.PC++].S9xOpcode) (); DO_HBLANK_CHECK (); } return; }
void S9xMainLoop (void) { for (;;) { #ifdef DEBUG_MAXCOUNT CPU.GlobalLoopCount++; if(Settings.MaxCount && CPU.GlobalLoopCount == Settings.MaxCount) { fprintf(stderr, "Max loop count reached: %ld \n", Settings.MaxCount); S9xExit(); } #endif APU_EXECUTE (); if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (--CPU.NMICycleCount == 0) { CPU.Flags &= ~NMI_FLAG; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } S9xOpcode_NMI (); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == CPU.PC - CPU.PCBase) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } #endif CHECK_SOUND (); if (CPU.Flags & IRQ_PENDING_FLAG) { if (CPU.IRQCycleCount == 0) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CheckFlag (IRQ)) S9xOpcode_IRQ (); } else CPU.Flags &= ~IRQ_PENDING_FLAG; } else { if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ)) CPU.IRQCycleCount=1; } } #ifdef DEBUGGER if (CPU.Flags & DEBUG_MODE_FLAG) break; #endif if (CPU.Flags & SCAN_KEYS_FLAG) break; #ifdef DEBUGGER if (CPU.Flags & TRACE_FLAG) S9xTrace (); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif } #ifdef CPU_SHUTDOWN CPU.PCAtOpcodeStart = CPU.PC; #endif CPU.Cycles += CPU.MemSpeed; (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (); S9xUpdateAPUTimer(); if (SA1.Executing) S9xSA1MainLoop (); DO_HBLANK_CHECK(); } Registers.PC = CPU.PC - CPU.PCBase; S9xPackStatus (); APURegisters.PC = IAPU.PC - IAPU.RAM; S9xAPUPackStatus (); if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed (); CPU.Flags &= ~SCAN_KEYS_FLAG; } #ifdef DETECT_NASTY_FX_INTERLEAVE if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) { CPU.TriedInterleavedMode2 = TRUE; CPU.BRKTriggered = FALSE; S9xDeinterleaveMode2 (); } #endif }
void S9xMainLoop (void) { for (;;) { APU_EXECUTE(); if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.Flags &= ~NMI_FLAG; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } S9xOpcode_NMI(); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == Registers.PCw) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } #endif CHECK_SOUND(); if (CPU.Flags & IRQ_PENDING_FLAG) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CheckFlag(IRQ)) S9xOpcode_IRQ(); } else CPU.Flags &= ~IRQ_PENDING_FLAG; } if (CPU.Flags & SCAN_KEYS_FLAG) break; #ifdef DEBUGGER if (CPU.Flags & DEBUG_MODE_FLAG) break; if (CPU.Flags & TRACE_FLAG) S9xTrace(); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif } #ifdef CPU_SHUTDOWN CPU.PBPCAtOpcodeStart = Registers.PBPC; #endif register uint8 Op; register struct SOpcodes *Opcodes; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.Cycles += CPU.MemSpeed; Opcodes = ICPU.S9xOpcodes; } else { Op = S9xGetByte(Registers.PBPC); OpenBus = Op; Opcodes = S9xOpcodesSlow; } if ((Registers.PCw&MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; CPU.PCBase = GetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase!=CPU.PCBase || (Registers.PCw&~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } Registers.PCw++; (*Opcodes[Op].S9xOpcode)(); S9xUpdateAPUTimer(); if (SA1.Executing) S9xSA1MainLoop(); if (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); } S9xPackStatus(); APURegisters.PC = IAPU.PC - IAPU.RAM; S9xAPUPackStatus(); if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed(); CPU.Flags &= ~SCAN_KEYS_FLAG; } }
void S9xMainLoop_SA1_APU(void) { for (;;) { asm_APU_EXECUTE(1); if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (--CPU.NMICycleCount == 0) { CPU.Flags &= ~NMI_FLAG; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; ++CPU.PC; } S9xOpcode_NMI(); } } if (CPU.Flags & IRQ_PENDING_FLAG) { if (CPU.IRQCycleCount == 0) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CheckFlag(IRQ)) S9xOpcode_IRQ(); } else CPU.Flags &= ~IRQ_PENDING_FLAG; } else CPU.IRQCycleCount--; } if (CPU.Flags & SCAN_KEYS_FLAG) break; } #ifdef CPU_SHUTDOWN CPU.PCAtOpcodeStart = CPU.PC; #endif #ifdef VAR_CYCLES CPU.Cycles += CPU.MemSpeed; #else CPU.Cycles += ICPU.Speed [*CPU.PC]; #endif (*ICPU.S9xOpcodes[*CPU.PC++].S9xOpcode)(); //S9xUpdateAPUTimer (); if (SA1.Executing) S9xSA1MainLoop(); DO_HBLANK_CHECK(); } }
void S9xMainLoop(void) { int i; for (;;) { for (i=0;i<32;i++) render_snescast(); if (CPU.NMILine) { if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.NMILine = FALSE; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } S9xOpcode_NMI(); } } if (CPU.IRQTransition || CPU.IRQExternal) { if (CPU.IRQPending) CPU.IRQPending--; else { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } CPU.IRQTransition = FALSE; CPU.IRQPending = Timings.IRQPendCount; if (!CheckFlag(IRQ)) S9xOpcode_IRQ(); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == Registers.PCw) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } if (CPU.Flags & DEBUG_MODE_FLAG) break; if (CPU.Flags & TRACE_FLAG) S9xTrace(); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif if (CPU.Flags & SCAN_KEYS_FLAG) break; register uint8 Op; register struct SOpcodes *Opcodes; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.PrevCycles = CPU.Cycles; CPU.Cycles += CPU.MemSpeed; S9xCheckInterrupts(); Opcodes = ICPU.S9xOpcodes; } else { Op = S9xGetByte(Registers.PBPC); OpenBus = Op; Opcodes = S9xOpcodesSlow; } if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } Registers.PCw++; (*Opcodes[Op].S9xOpcode)(); if (Settings.SA1) S9xSA1MainLoop(); } S9xPackStatus(); if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed(); CPU.Flags &= ~SCAN_KEYS_FLAG; } }
void S9xMainLoop (void) { #define CHECK_FOR_IRQ_CHANGE() \ if (Timings.IRQFlagChanging) \ { \ if (Timings.IRQFlagChanging & IRQ_TRIGGER_NMI) \ { \ CPU.NMIPending = TRUE; \ Timings.NMITriggerPos = CPU.Cycles + 6; \ } \ if (Timings.IRQFlagChanging & IRQ_CLEAR_FLAG) \ ClearIRQ(); \ else if (Timings.IRQFlagChanging & IRQ_SET_FLAG) \ SetIRQ(); \ Timings.IRQFlagChanging = IRQ_NONE; \ } if (CPU.Flags & SCAN_KEYS_FLAG) { CPU.Flags &= ~SCAN_KEYS_FLAG; S9xMovieUpdate(); } for (;;) { if (CPU.NMIPending) { #ifdef DEBUGGER if (Settings.TraceHCEvent) S9xTraceFormattedMessage ("Comparing %d to %d\n", Timings.NMITriggerPos, CPU.Cycles); #endif if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.NMIPending = FALSE; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; CPU.Cycles += TWO_CYCLES + ONE_DOT_CYCLE / 2; while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); } CHECK_FOR_IRQ_CHANGE(); S9xOpcode_NMI(); } } if (CPU.Cycles >= Timings.NextIRQTimer) { #ifdef DEBUGGER S9xTraceMessage ("Timer triggered\n"); #endif S9xUpdateIRQPositions(false); CPU.IRQLine = TRUE; } if (CPU.IRQLine || CPU.IRQExternal) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; CPU.Cycles += TWO_CYCLES + ONE_DOT_CYCLE / 2; while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); } if (!CheckFlag(IRQ)) { /* The flag pushed onto the stack is the new value */ CHECK_FOR_IRQ_CHANGE(); S9xOpcode_IRQ(); } } /* Change IRQ flag for instructions that set it only on last cycle */ CHECK_FOR_IRQ_CHANGE(); #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == Registers.PCw) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } if (CPU.Flags & DEBUG_MODE_FLAG) break; if (CPU.Flags & TRACE_FLAG) S9xTrace(); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif { S9xSyncSpeed(); } break; } uint8 Op; struct SOpcodes *Opcodes; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.Cycles += CPU.MemSpeed; Opcodes = ICPU.S9xOpcodes; } else { Op = S9xGetByte(Registers.PBPC); OpenBus = Op; Opcodes = S9xOpcodesSlow; } if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } Registers.PCw++; (*Opcodes[Op].S9xOpcode)(); if (Settings.SA1) S9xSA1MainLoop(); } S9xPackStatus(); }
void S9xMainLoop (void) { for (;;) { if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.Flags &= ~NMI_FLAG; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } S9xOpcode_NMI(); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == Registers.PCw) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } #endif if (CPU.Flags & IRQ_FLAG) { if (CPU.IRQPending) // FIXME: In case of IRQ during WRAM refresh CPU.IRQPending--; else { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CheckFlag(IRQ)) // in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared. S9xOpcode_IRQ(); } else CPU.Flags &= ~IRQ_FLAG; } } if (CPU.Flags & SCAN_KEYS_FLAG) break; #ifdef DEBUGGER if (CPU.Flags & DEBUG_MODE_FLAG) break; if (CPU.Flags & TRACE_FLAG) S9xTrace(); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif } #ifdef CPU_SHUTDOWN CPU.PBPCAtOpcodeStart = Registers.PBPC; #endif register uint8 Op; register struct SOpcodes *Opcodes; CPU.PrevCycles = CPU.Cycles; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.Cycles += CPU.MemSpeed; Opcodes = ICPU.S9xOpcodes; } else { Op = S9xGetByte(Registers.PBPC); OpenBus = Op; Opcodes = S9xOpcodesSlow; } if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } Registers.PCw++; (*Opcodes[Op].S9xOpcode)(); if (SA1.Executing) S9xSA1MainLoop(); #if (S9X_ACCURACY_LEVEL <= 2) while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); #endif } S9xPackStatus(); if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed(); CPU.Flags &= ~SCAN_KEYS_FLAG; } }
void S9xMainLoop (void) { static int loop_times=0; int loops2=0; //printf("Enter S9xMainLoop %d %x\n", loop_times, Registers.PCw); for (;;) { loops2++; //printf("S9xMainLoop %d for loop %d flags=%d\n", loop_times, loops2, CPU.Flags); if (CPU.NMILine) { //printf("case 1\n"); if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.NMILine = FALSE; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } S9xOpcode_NMI(); } } if (CPU.IRQTransition || CPU.IRQExternal) { //printf("case 2\n"); if (CPU.IRQPending) CPU.IRQPending--; else { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } CPU.IRQTransition = FALSE; CPU.IRQPending = Timings.IRQPendCount; if (!CheckFlag(IRQ)) S9xOpcode_IRQ(); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == Registers.PCw) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } if (CPU.Flags & DEBUG_MODE_FLAG) break; if (CPU.Flags & TRACE_FLAG) S9xTrace(); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif if (CPU.Flags & SCAN_KEYS_FLAG) break; register uint8 Op; register Opcode *Opcodes; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.PrevCycles = CPU.Cycles; CPU.Cycles += CPU.MemSpeed; S9xCheckInterrupts(); Opcodes = ICPU.S9xOpcodes; //printf("case 3 %x %x %d %d\n", Registers.PCw, Op, CPU.PrevCycles, CPU.Cycles); } else { //printf("case 4\n"); Op = S9xGetByte(Registers.PBPC); OpenBus = Op; Opcodes = S9xOpcodesSlow; } if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; //printf("case 5\n"); CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } //printf("case 3.1 %d\n", CPU.Cycles); Registers.PCw++; Opcodes[Op](); //printf("case 3.2 %d\n", CPU.Cycles); if (Settings.SA1){ //printf("case 6\n"); S9xSA1MainLoop(); } } S9xPackStatus(); if (CPU.Flags & SCAN_KEYS_FLAG) { //printf("case 7\n"); #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed(); CPU.Flags &= ~SCAN_KEYS_FLAG; } //printf("Exit S9xMainLoop %d loops2=%d\n", loop_times++, loops2); }
void S9xMainLoop (void) { struct SCPUState *cpu = &CPU; struct SICPU *icpu = &ICPU; struct SIAPU *iapu = &IAPU; struct SAPU *apu = &APU; struct SRegisters *reg = &Registers; struct SAPURegisters *areg = &APURegisters; for (;;) { APU_EXECUTE (); if (cpu->Flags) { if (cpu->Flags & NMI_FLAG) { if (--cpu->NMICycleCount == 0) { cpu->Flags &= ~NMI_FLAG; if (cpu->WaitingForInterrupt) { cpu->WaitingForInterrupt = FALSE; ++cpu->PC; } S9xOpcode_NMI (); } } #ifdef DEBUGGER if ((cpu->Flags & BREAK_FLAG) && !(cpu->Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == cpu->PC - cpu->PCBase) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else cpu->Flags |= DEBUG_MODE_FLAG; } } } #endif CHECK_SOUND (); if (cpu->Flags & IRQ_PENDING_FLAG) { if (cpu->IRQCycleCount == 0) { if (cpu->WaitingForInterrupt) { cpu->WaitingForInterrupt = FALSE; cpu->PC++; } if (cpu->IRQActive) // if (cpu->IRQActive && !Settings.DisableIRQ) { if (!CHECKFLAG (IRQ)) S9xOpcode_IRQ (); } else cpu->Flags &= ~IRQ_PENDING_FLAG; } else cpu->IRQCycleCount--; } #ifdef DEBUGGER if (cpu->Flags & DEBUG_MODE_FLAG) break; #endif if (cpu->Flags & SCAN_KEYS_FLAG) break; #ifdef DEBUGGER if (cpu->Flags & TRACE_FLAG) S9xTrace (); if (cpu->Flags & SINGLE_STEP_FLAG) { cpu->Flags &= ~SINGLE_STEP_FLAG; cpu->Flags |= DEBUG_MODE_FLAG; } #endif } //if (CPU.Flags) #ifdef CPU_SHUTDOWN cpu->PCAtOpcodeStart = cpu->PC; #endif #ifdef VAR_CYCLES cpu->Cycles += cpu->MemSpeed; #else cpu->Cycles += icpu->Speed [*cpu->PC]; #endif (*icpu->S9xOpcodes [*cpu->PC++].S9xOpcode) (reg, icpu, cpu); #ifndef _ZAURUS if (SA1.Executing) S9xSA1MainLoop (); #endif DO_HBLANK_CHECK(); } // for(;;) Registers.PC = cpu->PC - cpu->PCBase; S9xPackStatus (); areg->PC = iapu->PC - iapu->RAM; S9xAPUPackStatus_OP (); if (cpu->Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(cpu->Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed (); cpu->Flags &= ~SCAN_KEYS_FLAG; } #ifndef _ZAURUS if (cpu->BRKTriggered && Settings.SuperFX && !cpu->TriedInterleavedMode2) { cpu->TriedInterleavedMode2 = TRUE; cpu->BRKTriggered = FALSE; S9xDeinterleaveMode2 (); } #endif }
void S9xMainLoop (void) { for (;;) { APU_EXECUTE (); if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (--CPU.NMICycleCount == 0) { CPU.Flags &= ~NMI_FLAG; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } S9xOpcode_NMI (); } } if (CPU.Flags & IRQ_PENDING_FLAG) { if (CPU.IRQCycleCount == 0) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CheckFlag (IRQ)) S9xOpcode_IRQ (); } else CPU.Flags &= ~IRQ_PENDING_FLAG; } else CPU.IRQCycleCount--; } if (CPU.Flags & SCAN_KEYS_FLAG) break; } #ifdef CPU_SHUTDOWN CPU.PCAtOpcodeStart = CPU.PC; #endif CPU.Cycles += CPU.MemSpeed; (*ICPU.S9xOpcodes[*CPU.PC++].S9xOpcode) (); S9xUpdateAPUTimer (); if (SA1.Executing) S9xSA1MainLoop (); DO_HBLANK_CHECK (); } Registers.PC = CPU.PC - CPU.PCBase; S9xPackStatus (); (APURegistersUncached->PC) = (IAPUuncached->PC) - (IAPUuncached->RAM); S9xAPUPackStatus (); if (CPU.Flags & SCAN_KEYS_FLAG) { S9xSyncSpeed (); CPU.Flags &= ~SCAN_KEYS_FLAG; } if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) { CPU.TriedInterleavedMode2 = TRUE; CPU.BRKTriggered = FALSE; S9xDeinterleaveMode2 (); } }
void S9xMainLoop (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) { #else void S9xMainLoop (void) { struct SICPU * icpu = &ICPU; struct SCPUState * cpu = &CPU; struct SRegisters * reg = &Registers; #endif for (;;) { APU_EXECUTE (); if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (--CPU.NMICycleCount == 0) { CPU.Flags &= ~NMI_FLAG; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; ++CPU.PC; } S9xOpcode_NMI (); } } #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { for (int Break = 0; Break != 6; Break++) { if (S9xBreakpoint[Break].Enabled && S9xBreakpoint[Break].Bank == Registers.PB && S9xBreakpoint[Break].Address == CPU.PC - CPU.PCBase) { if (S9xBreakpoint[Break].Enabled == 2) S9xBreakpoint[Break].Enabled = TRUE; else CPU.Flags |= DEBUG_MODE_FLAG; } } } #endif CHECK_SOUND (); if (CPU.Flags & IRQ_PENDING_FLAG) { if (CPU.IRQCycleCount == 0) { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; CPU.PC++; } if (CPU.IRQActive && !Settings.DisableIRQ) { if (!CHECKFLAG (IRQ)) S9xOpcode_IRQ (); } else CPU.Flags &= ~IRQ_PENDING_FLAG; } else CPU.IRQCycleCount--; } #ifdef DEBUGGER if (CPU.Flags & DEBUG_MODE_FLAG) break; #endif if (CPU.Flags & SCAN_KEYS_FLAG) break; #ifdef DEBUGGER if (CPU.Flags & TRACE_FLAG) S9xTrace (); if (CPU.Flags & SINGLE_STEP_FLAG) { CPU.Flags &= ~SINGLE_STEP_FLAG; CPU.Flags |= DEBUG_MODE_FLAG; } #endif } //if (CPU.Flags) #ifdef CPU_SHUTDOWN CPU.PCAtOpcodeStart = CPU.PC; #endif #ifdef VAR_CYCLES CPU.Cycles += CPU.MemSpeed; #else CPU.Cycles += ICPU.Speed [*CPU.PC]; #endif (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (&Registers, &ICPU, &CPU); if (SA1.Executing) S9xSA1MainLoop (); DO_HBLANK_CHECK(); } // for(;;) Registers.PC = CPU.PC - CPU.PCBase; S9xPackStatus (); APURegisters.PC = IAPU.PC - IAPU.RAM; S9xAPUPackStatus (); if (CPU.Flags & SCAN_KEYS_FLAG) { #ifdef DEBUGGER if (!(CPU.Flags & FRAME_ADVANCE_FLAG)) #endif S9xSyncSpeed (); CPU.Flags &= ~SCAN_KEYS_FLAG; } if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) { CPU.TriedInterleavedMode2 = TRUE; CPU.BRKTriggered = FALSE; S9xDeinterleaveMode2 (); } } void S9xSetIRQ (uint32 source) { CPU.IRQActive |= source; CPU.Flags |= IRQ_PENDING_FLAG; CPU.IRQCycleCount = 3; if (CPU.WaitingForInterrupt) { // Force IRQ to trigger immediately after WAI - // Final Fantasy Mystic Quest crashes without this. CPU.IRQCycleCount = 0; CPU.WaitingForInterrupt = FALSE; CPU.PC++; } }
void S9xMainLoop (void) { do { register uint8 Op; register struct SOpcodes *Opcodes; /* Speedhack - skip idle loop if exists. */ if (idle_loop_elimination_enable && (Registers.PBPC == idle_loop_target_pc) && (CPU.Cycles < CPU.NextEvent)) CPU.Cycles = CPU.NextEvent; if (CPU.Flags) { if (CPU.Flags & NMI_FLAG) { if (Timings.NMITriggerPos <= CPU.Cycles) { CPU.Flags &= ~NMI_FLAG; Timings.NMITriggerPos = 0xffff; if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } S9xOpcode_NMI(); } } if (CPU.Flags & IRQ_FLAG) { if (CPU.IRQPending) CPU.IRQPending--; /* FIXME: In case of IRQ during WRAM refresh */ else { if (CPU.WaitingForInterrupt) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; } if (CPU.IRQActive) { /* in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared. */ if (!CheckFlag(IRQ)) S9xOpcode_IRQ(); } else CPU.Flags &= ~IRQ_FLAG; } } if (CPU.Flags & SCAN_KEYS_FLAG) break; } Opcodes = S9xOpcodesSlow; CPU.PrevCycles = CPU.Cycles; if (CPU.PCBase) { Op = CPU.PCBase[Registers.PCw]; CPU.Cycles += CPU.MemSpeed; Opcodes = ICPU.S9xOpcodes; } else { Op = S9xGetByte(Registers.PBPC); OpenBus = Op; } if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE) { uint8 *oldPCBase = CPU.PCBase; CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4))); if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK)) Opcodes = S9xOpcodesSlow; } Registers.PCw++; (*Opcodes[Op].S9xOpcode)(); if (Settings.SA1) S9xSA1MainLoop(); #if (S9X_ACCURACY_LEVEL <= 2) while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); #endif }while(1); S9xPackStatus(); if (CPU.Flags & SCAN_KEYS_FLAG) { CPU.Flags &= ~SCAN_KEYS_FLAG; } }