void StartEmulationFromSave ( usf_state_t * state, void * savestate ) { uint32_t count = 0; //printf("Starting generic Cpu\n"); //CloseCpu(); memset(state->N64MEM, 0, state->RdramSize); memset(state->DMEM, 0, 0x1000); memset(state->IMEM, 0, 0x1000); memset(state->TLB_Map, 0, 0x100000 * sizeof(uintptr_t) + 0x10000); memset(state->CPU_Action,0,sizeof(*state->CPU_Action)); state->WrittenToRom = 0; InitilizeTLB(state); SetupRegisters(state, state->Registers); BuildInterpreter(state); state->Timers->CurrentTimerType = -1; state->Timers->Timer = 0; for (count = 0; count < MaxTimers; count ++) { state->Timers->Active[count] = 0; } ChangeTimer(state,ViTimer,5000); ChangeCompareTimer(state); state->ViFieldNumber = 0; state->CPURunning = 1; *state->WaitMode = 0; init_rsp(state); Machine_LoadStateFromRAM(state, savestate); state->SampleRate = 48681812 / (AI_DACRATE_REG + 1); if(state->enableFIFOfull) { const float VSyncTiming = 789000.0f; double BytesPerSecond = 48681812.0 / (AI_DACRATE_REG + 1) * 4; double CountsPerSecond = (double)(((double)VSyncTiming) * (double)60.0); double CountsPerByte = (double)CountsPerSecond / (double)BytesPerSecond; uint32_t IntScheduled = (uint32_t)((double)AI_LEN_REG * CountsPerByte); ChangeTimer(state,AiTimer,IntScheduled); AI_STATUS_REG|=0x40000000; } state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG; CPUHLE_Scan(state); }
uint32_t Machine_LoadStateFromRAM(usf_state_t * state, void * savestatespace) { uint8_t LoadHeader[0x40]; uint32_t Value, count, SaveRDRAMSize, offset=0; ReadFromMem( savestatespace,&Value,sizeof(Value),&offset); if (Value != 0x23D8A6C8) { return 0; } ReadFromMem( savestatespace,&SaveRDRAMSize,sizeof(SaveRDRAMSize),&offset); ReadFromMem( savestatespace,&LoadHeader,0x40,&offset); state->Timers->CurrentTimerType = -1; state->Timers->Timer = 0; for (count = 0; count < MaxTimers; count ++) { state->Timers->Active[count] = 0; } //fix rdram size if (SaveRDRAMSize != state->RdramSize) { // dothis :) } state->RdramSize = SaveRDRAMSize; ReadFromMem( savestatespace,&Value,sizeof(Value),&offset); ChangeTimer(state,ViTimer,Value); ReadFromMem( savestatespace,&state->PROGRAM_COUNTER,sizeof(state->PROGRAM_COUNTER),&offset); ReadFromMem( savestatespace,state->GPR,sizeof(int64_t)*32,&offset); ReadFromMem( savestatespace,state->FPR,sizeof(int64_t)*32,&offset); ReadFromMem( savestatespace,state->CP0,sizeof(uint32_t)*32,&offset); ReadFromMem( savestatespace,state->FPCR,sizeof(uint32_t)*32,&offset); ReadFromMem( savestatespace,&state->HI,sizeof(int64_t),&offset); ReadFromMem( savestatespace,&state->LO,sizeof(int64_t),&offset); ReadFromMem( savestatespace,state->RegRDRAM,sizeof(uint32_t)*10,&offset); ReadFromMem( savestatespace,state->RegSP,sizeof(uint32_t)*10,&offset); ReadFromMem( savestatespace,state->RegDPC,sizeof(uint32_t)*10,&offset); ReadFromMem( savestatespace,state->RegMI,sizeof(uint32_t)*4,&offset); ReadFromMem( savestatespace,state->RegVI,sizeof(uint32_t)*14,&offset); ReadFromMem( savestatespace,state->RegAI,sizeof(uint32_t)*6,&offset); ReadFromMem( savestatespace,state->RegPI,sizeof(uint32_t)*13,&offset); ReadFromMem( savestatespace,state->RegRI,sizeof(uint32_t)*8,&offset); ReadFromMem( savestatespace,state->RegSI,sizeof(uint32_t)*4,&offset); ReadFromMem( savestatespace,state->tlb,sizeof(TLB)*32,&offset); ReadFromMem( savestatespace,(uint8_t*)state->PIF_Ram,0x40,&offset); ReadFromMem( savestatespace,state->RDRAM,SaveRDRAMSize,&offset); ReadFromMem( savestatespace,state->DMEM,0x1000,&offset); ReadFromMem( savestatespace,state->IMEM,0x1000,&offset); state->CP0[32] = 0; SetupTLB(state); ChangeCompareTimer(state); AI_STATUS_REG = 0; AiDacrateChanged(state, AI_DACRATE_REG); // StartAiInterrupt(state); SetFpuLocations(state); // important if FR=1 return 1; }
void do_dma(usf_state_t * state, const struct ai_dma * dma) { AddBuffer(state, state->RDRAM + (dma->address & (state->RdramSize - 1) & ~3), dma->length); if(!(AI_STATUS_REG&AI_STATUS_FULL)) { if (state->enableFIFOfull) { ChangeTimer(state,AiTimer,dma->duration + state->Timers->Timer); } else { state->AudioIntrReg|=4; } } }
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 RefreshScreen (usf_state_t * state){ if (state->OLD_VI_V_SYNC_REG != VI_V_SYNC_REG) { state->OLD_VI_V_SYNC_REG = VI_V_SYNC_REG; if (VI_V_SYNC_REG == 0) { state->VI_INTR_TIME = 500000; } else { state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500; if ((VI_V_SYNC_REG & 1) != 0) { state->VI_INTR_TIME -= 38; } } } ChangeTimer(state,ViTimer,state->Timers->Timer + state->Timers->NextTimer[ViTimer] + state->VI_INTR_TIME); if ((VI_STATUS_REG & 0x10) != 0) { if (state->ViFieldNumber == 0) { state->ViFieldNumber = 1; } else { state->ViFieldNumber = 0; } } else { state->ViFieldNumber = 0; } }
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 AiQueueInt(usf_state_t *state) { ChangeTimer(state,AiTimer,state->enableFIFOfull ? get_dma_duration(state) + state->Timers->Timer : 0); }
void ChangeCompareTimer(usf_state_t * state) { uint32_t NextCompare = COMPARE_REGISTER - COUNT_REGISTER; if ((NextCompare & 0x80000000) != 0) { NextCompare = 0x7FFFFFFF; } if (NextCompare == 0) { NextCompare = 0x1; } ChangeTimer(state,CompareTimer,NextCompare); }