void PI_DMA_WRITE (usf_state_t * state) { uint32_t i; PI_STATUS_REG |= PI_STATUS_DMA_BUSY; if ( PI_DRAM_ADDR_REG + PI_WR_LEN_REG + 1 > state->RdramSize) { PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(state); return; } if ( PI_CART_ADDR_REG >= 0x08000000 && PI_CART_ADDR_REG <= 0x08010000) { return; } if ( PI_CART_ADDR_REG >= 0x10000000 && PI_CART_ADDR_REG <= 0x1FBFFFFF) { PI_CART_ADDR_REG -= 0x10000000; for (i = 0; i < PI_WR_LEN_REG + 1; i ++) { *(state->N64MEM+((PI_DRAM_ADDR_REG + i) ^ 3)) = *PageROM(state, (PI_CART_ADDR_REG + i) ^ 3); } PI_CART_ADDR_REG += 0x10000000; PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(state); CheckTimer(state); return; } PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(state); }
void PI_DMA_READ (void) { // PI_STATUS_REG |= PI_STATUS_DMA_BUSY; if ( PI_DRAM_ADDR_REG + PI_RD_LEN_REG + 1 > RdramSize) { #ifndef EXTERNAL_RELEASE DisplayError("PI_DMA_READ not in Memory"); #endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } if ( PI_CART_ADDR_REG >= 0x08000000 && PI_CART_ADDR_REG <= 0x08010000) { if (SaveUsing == Auto) { SaveUsing = Sram; } if (SaveUsing == Sram) { DmaToSram( N64MEM+PI_DRAM_ADDR_REG, PI_CART_ADDR_REG - 0x08000000, PI_RD_LEN_REG + 1 ); PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } if (SaveUsing == FlashRam) { DmaToFlashram( N64MEM+PI_DRAM_ADDR_REG, PI_CART_ADDR_REG - 0x08000000, PI_WR_LEN_REG + 1 ); PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } } if (SaveUsing == FlashRam) { #ifndef EXTERNAL_RELEASE DisplayError("**** FLashRam DMA Read address %X *****",PI_CART_ADDR_REG); #endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } #ifndef EXTERNAL_RELEASE DisplayError("PI_DMA_READ where are you dmaing to ?"); #endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; }
void RunRsp (usf_state_t * state) { #ifdef DEBUG_INFO fprintf(state->debug_log, "RSP Task:"); #endif if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0) { if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 ) { uint32_t Task = *( uint32_t *)(state->DMEM + 0xFC0); switch (Task) { case 1: { MI_INTR_REG |= 0x20; SP_STATUS_REG |= (0x0203 ); if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) MI_INTR_REG |= 1; #ifdef DEBUG_INFO fprintf(state->debug_log, " DList - interrupts %d\n", MI_INTR_REG); #endif CheckInterrupts(state); DPC_STATUS_REG &= ~0x0002; return; } break; case 2: { #ifdef DEBUG_INFO fprintf(state->debug_log, " AList"); #endif break; } break; default: break; } real_run_rsp(state, 100); SP_STATUS_REG |= (0x0203 ); if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) { #ifdef DEBUG_INFO fprintf(state->debug_log, " - interrupt"); #endif MI_INTR_REG |= 1; CheckInterrupts(state); } } } #ifdef DEBUG_INFO fprintf(state->debug_log, "\n"); #endif }
EXPORT void CALL ProcessDList(void) { OGL.frame_dl++; if (config.autoFrameSkip) { OGL_UpdateFrameTime(); if (OGL.consecutiveSkips < 1) { unsigned t = 0; for(int i = 0; i < OGL_FRAMETIME_NUM; i++) t += OGL.frameTime[i]; t *= config.targetFPS; if (config.romPAL) t = (t * 5) / 6; if (t > (OGL_FRAMETIME_NUM * 1000)) { OGL.consecutiveSkips++; OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } } } else if (frameSkipper.willSkipNext()) { OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } OGL.consecutiveSkips = 0; RSP_ProcessDList(); OGL.mustRenderDlist = true; }
void CPU::ExecuteOneInstruction() { switch (current_state_) { case State::Running: previous_pc_ = registers_.pc; ExecuteInstruction(FetchByte()); break; case State::Halted: // NOP instructions are executed until Halted state ends NotifyMachineCycleLapse(); break; case State::HaltBug: // PC increment is skipped once when fetching the next opcode (no extra cycles are lapsed) current_state_ = State::Running; previous_pc_ = registers_.pc; ExecuteInstruction(mmu_->ReadByte(registers_.pc)); break; case State::Stopped: //TODO check for joypad input, since that is the only thing that can finish Stopped state return; } CheckInterrupts(); }
void SI_DMA_READ (usf_state_t * state) { if ((int32_t)SI_DRAM_ADDR_REG > (int32_t)state->RdramSize) { return; } PifRamRead(state); SI_DRAM_ADDR_REG &= 0xFFFFFFF8; if ((int32_t)SI_DRAM_ADDR_REG < 0) { int32_t count, RdramPos; RdramPos = (int32_t)SI_DRAM_ADDR_REG; for (count = 0; count < 0x40; count++, RdramPos++) { if (RdramPos < 0) { continue; } state->N64MEM[RdramPos ^3] = state->PIF_Ram[count]; } } else { int32_t count, RdramPos; RdramPos = (uint32_t)SI_DRAM_ADDR_REG; for (count = 0; count < 0x40; count++, RdramPos++) { if (RdramPos < 0) { continue; } state->N64MEM[RdramPos ^3] = state->PIF_Ram[count]; } } MI_INTR_REG |= MI_INTR_SI; SI_STATUS_REG |= SI_STATUS_INTERRUPT; CheckInterrupts(state); }
void PI_DMA_READ (usf_state_t * state) { PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(state); return; }
EXPORT void CALL ProcessDList(void) { OGL.frame_dl++; if (frameSkipper.willSkipNext()) { OGL.frameSkipped++; RSP.busy = FALSE; RSP.DList++; /* avoid hang on frameskip */ *REG.MI_INTR |= MI_INTR_DP; CheckInterrupts(); *REG.MI_INTR |= MI_INTR_SP; CheckInterrupts(); return; } OGL.consecutiveSkips = 0; RSP_ProcessDList(); OGL.mustRenderDlist = true; }
void TimerDone (usf_state_t * state) { switch (state->Timers->CurrentTimerType) { case CompareTimer: if(state->enablecompare) FAKE_CAUSE_REGISTER |= CAUSE_IP7; CheckInterrupts(state); ChangeCompareTimer(state); break; case ViTimer: RefreshScreen(state); MI_INTR_REG |= MI_INTR_VI; CheckInterrupts(state); *state->WaitMode=0; break; case AiTimer: ChangeTimer(state,AiTimer,0); AI_STATUS_REG=0; state->AudioIntrReg|=4; //CheckInterrupts(state); break; } CheckTimer(state); }
void DoSomething ( usf_state_t * state ) { if (state->CPU_Action->CloseCPU) { //StopEmulation(); state->cpu_running = 0; //printf("Stopping?\n"); } if (state->CPU_Action->CheckInterrupts) { state->CPU_Action->CheckInterrupts = 0; CheckInterrupts(state); } if (state->CPU_Action->DoInterrupt) { state->CPU_Action->DoInterrupt = 0; DoIntrException(state, 0); } state->CPU_Action->DoSomething = 0; if (state->CPU_Action->DoInterrupt) { state->CPU_Action->DoSomething = 1; } }
void SP_DMA_READ (usf_state_t * state) { SP_DRAM_ADDR_REG &= 0x1FFFFFFF; if (SP_DRAM_ADDR_REG > state->RdramSize) { SP_DMA_BUSY_REG = 0; SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; return; } if (SP_RD_LEN_REG + 1 + (SP_MEM_ADDR_REG & 0xFFF) > 0x1000) { return; } memcpy( state->DMEM + (SP_MEM_ADDR_REG & 0x1FFF), state->N64MEM + SP_DRAM_ADDR_REG, SP_RD_LEN_REG + 1 ); SP_DMA_BUSY_REG = 0; SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; MI_INTR_REG &= ~MI_INTR_SP; CheckInterrupts(state); CheckTimer(state); }
void SI_DMA_WRITE (void) { BYTE * PifRamPos = &PIF_Ram[0]; if ((int)SI_DRAM_ADDR_REG > (int)RdramSize) { #ifndef EXTERNAL_RELEASE DisplayError("SI DMA\nSI_DRAM_ADDR_REG not in RDRam space"); #endif return; } SI_DRAM_ADDR_REG &= 0xFFFFFFF8; if ((int)SI_DRAM_ADDR_REG < 0) { int count, RdramPos; RdramPos = (int)SI_DRAM_ADDR_REG; for (count = 0; count < 0x40; count++, RdramPos++) { if (RdramPos < 0) { PIF_Ram[count] = 0; continue; } PIF_Ram[count] = N64MEM[RdramPos ^3]; } } else { _asm { mov ecx, dword ptr [RegSI] mov ecx, dword ptr [ecx] add ecx, N64MEM mov edi, PifRamPos mov edx, 0 memcpyloop: mov eax, dword ptr [ecx + edx] bswap eax mov dword ptr [edi + edx],eax mov eax, dword ptr [ecx + edx + 4] bswap eax mov dword ptr [edi + edx + 4],eax mov eax, dword ptr [ecx + edx + 8] bswap eax mov dword ptr [edi + edx + 8],eax mov eax, dword ptr [ecx + edx + 12] bswap eax mov dword ptr [edi + edx + 12],eax add edx, 16 cmp edx, 64 jb memcpyloop } } #if (!defined(EXTERNAL_RELEASE)) if (LogOptions.LogPRDMAMemLoads) { int count; char HexData[100], AsciiData[100], Addon[20]; LogMessage(""); LogMessage("\tData DMAed to the Pif Ram:"); LogMessage("\t--------------------------"); for (count = 0; count < 16; count ++ ) { if ((count % 4) == 0) { sprintf(HexData,"\0"); sprintf(AsciiData,"\0"); } sprintf(Addon,"%02X %02X %02X %02X", PIF_Ram[(count << 2) + 0], PIF_Ram[(count << 2) + 1], PIF_Ram[(count << 2) + 2], PIF_Ram[(count << 2) + 3] ); strcat(HexData,Addon); if (((count + 1) % 4) != 0) { sprintf(Addon,"-"); strcat(HexData,Addon); } sprintf(Addon,"%c%c%c%c", PIF_Ram[(count << 2) + 0], PIF_Ram[(count << 2) + 1], PIF_Ram[(count << 2) + 2], PIF_Ram[(count << 2) + 3] ); strcat(AsciiData,Addon); if (((count + 1) % 4) == 0) { LogMessage("\t%s %s",HexData, AsciiData); } } LogMessage(""); } #endif PifRamWrite(); if (DelaySI) { ChangeTimer(SiTimer,0x900); } else { MI_INTR_REG |= MI_INTR_SI; SI_STATUS_REG |= SI_STATUS_INTERRUPT; CheckInterrupts(); } }
void PI_DMA_WRITE (void) { DWORD i; PI_STATUS_REG |= PI_STATUS_DMA_BUSY; if ( PI_DRAM_ADDR_REG + PI_WR_LEN_REG + 1 > RdramSize) { #ifndef EXTERNAL_RELEASE DisplayError("PI_DMA_WRITE not in Memory"); #endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } if ( PI_CART_ADDR_REG >= 0x08000000 && PI_CART_ADDR_REG <= 0x08010000) { if (SaveUsing == Auto) { SaveUsing = Sram; } if (SaveUsing == Sram) { DmaFromSram( N64MEM+PI_DRAM_ADDR_REG, PI_CART_ADDR_REG - 0x08000000, PI_WR_LEN_REG + 1 ); PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); return; } if (SaveUsing == FlashRam) { DmaFromFlashram( N64MEM+PI_DRAM_ADDR_REG, PI_CART_ADDR_REG - 0x08000000, PI_WR_LEN_REG + 1 ); PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); } return; } if ( PI_CART_ADDR_REG >= 0x10000000 && PI_CART_ADDR_REG <= 0x1FBFFFFF) { #ifdef ROM_IN_MAPSPACE if (WrittenToRom) { DWORD OldProtect; VirtualProtect(ROM,RomFileSize,PAGE_READONLY, &OldProtect); } #endif PI_CART_ADDR_REG -= 0x10000000; if (PI_CART_ADDR_REG + PI_WR_LEN_REG + 1 < RomFileSize) { for (i = 0; i < PI_WR_LEN_REG + 1; i ++) { *(N64MEM+((PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM+((PI_CART_ADDR_REG + i) ^ 3)); } } else { DWORD Len; Len = RomFileSize - PI_CART_ADDR_REG; for (i = 0; i < Len; i ++) { *(N64MEM+((PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM+((PI_CART_ADDR_REG + i) ^ 3)); } for (i = Len; i < PI_WR_LEN_REG + 1 - Len; i ++) { *(N64MEM+((PI_DRAM_ADDR_REG + i) ^ 3)) = 0; } } PI_CART_ADDR_REG += 0x10000000; if (!DMAUsed) { DMAUsed = TRUE; FirstDMA(); } PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); //ChangeTimer(PiTimer,(int)(PI_WR_LEN_REG * 8.9) + 50); //ChangeTimer(PiTimer,(int)(PI_WR_LEN_REG * 8.9)); CheckTimer(); return; } #ifndef EXTERNAL_RELEASE if (ShowUnhandledMemory) { DisplayError("PI_DMA_WRITE not in ROM"); } #endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); }
void HleCheckInterrupts(void* user_defined) { CheckInterrupts((usf_state_t*)user_defined); }
void __cdecl RspCheckInterrupts(void) { CheckInterrupts(); }
void PifRamWrite (void) { int Channel, CurPos; Channel = 0; if( PIF_Ram[0x3F] > 0x1) { switch (PIF_Ram[0x3F]) { case 0x08: PIF_Ram[0x3F] = 0; MI_INTR_REG |= MI_INTR_SI; SI_STATUS_REG |= SI_STATUS_INTERRUPT; CheckInterrupts(); break; case 0x10: memset(PifRom,0,0x7C0); break; case 0x30: PIF_Ram[0x3F] = 0x80; break; case 0xC0: memset(PIF_Ram,0,0x40); break; default: if (ShowPifRamErrors) { DisplayError("Unkown PifRam control: %d",PIF_Ram[0x3F]); } } return; } for (CurPos = 0; CurPos < 0x40; CurPos++){ switch(PIF_Ram[CurPos]) { case 0x00: Channel += 1; if (Channel > 6) { CurPos = 0x40; } break; case 0xFE: CurPos = 0x40; break; case 0xFF: break; case 0xB4: case 0x56: case 0xB8: break; /* ??? */ default: if ((PIF_Ram[CurPos] & 0xC0) == 0) { if (Channel < 4) { if (Controllers[Channel].Present && Controllers[Channel].RawData) { if (ControllerCommand) { ControllerCommand(Channel,&PIF_Ram[CurPos]); } } else { ProcessControllerCommand(Channel,&PIF_Ram[CurPos]); } } else if (Channel == 4) { EepromCommand(&PIF_Ram[CurPos]); } else { #ifndef EXTERNAL_RELEASE DisplayError("Command on channel 5?"); #endif } CurPos += PIF_Ram[CurPos] + (PIF_Ram[CurPos + 1] & 0x3F) + 1; Channel += 1; } else { if (ShowPifRamErrors) { DisplayError("Unknown Command in PifRamWrite(%X)",PIF_Ram[CurPos]); } CurPos = 0x40; } break; } } PIF_Ram[0x3F] = 0; if (ControllerCommand) { ControllerCommand(-1,NULL); } }