/** * Check if is time to do a new request * @return */ long long MPU6050::timeCheck() { long long cur = getMilliTime(false); int interval = cur - timeLastCatch; if (interval >= timeAvg) { return cur; }/* else if (timeCountCatch < timeCountTarget) { printf("Count\n"); return cur; }*/ return 0; }
void run(struct Computer *computer) { struct CPU *cpu = &computer->cpu; struct RAM *ram = &computer->ram; struct GPU *gpu = &computer->gpu; struct DMA *dma = &computer->dma; struct Screen *screen = computer->screen; // TODO boot computer initTime(); // init CPU cpu->IP = CODE_ADDR; cpu->SP = ram->size - 1; CPU_run(cpu); // how many emulated cycles can we do until the next refresh uint32 cpuCycles = cpu->clockRate / gpu->refreshRate; uint32 tickCounter = 0; double refreshTimeMs = 1000.0 / (double) gpu->refreshRate; double sleepTimeMs = 0.0; double tickStartMs = 0.0; double tickEndMs = 0.0; double tickDiffMs = 0.0; printf("CPU clock rate: %ld Hz\n", cpu->clockRate); printf("Video refresh rate: %ld Hz\n", gpu->refreshRate); printf("CPU cycles per frame: %ld\n", cpuCycles); printf("Refresh time: %f ms\n", refreshTimeMs); while (CPU_isRunning(cpu)) { tickCounter = cpuCycles; tickStartMs = getMilliTime(); while (CPU_isRunning(cpu) && tickCounter > 0) { CPU_tick(cpu); DMA_tick(dma); tickCounter--; } // update the screen if (screen != NULL) { draw(gpu, screen); CPU_interrupt(cpu, VBLANK_INTERRUPT); } // we need to pump events or the window freezes SDL_PumpEvents(); SDL_RenderClear(screen->renderer); SDL_RenderCopy(screen->renderer, screen->texture, NULL, NULL); SDL_RenderPresent(screen->renderer); tickEndMs = getMilliTime(); tickDiffMs = tickEndMs - tickStartMs; sleepTimeMs = refreshTimeMs - tickDiffMs; // printf("> %f %f\n", tickDiffMs, sleepTimeMs); if (sleepTimeMs >= 1.0) { SDL_Delay((Uint32) sleepTimeMs); } } }
/** * Reset average time measurement for interval of request data from MPU unit */ void MPU6050::timeReset() { timeAvg = 0; timeCountCatch = 0; timeLastCatch = getMilliTime(false); }