void OS_loop() { int error; topOffProcesses(); // Run the current process until the next interrupt or trap call. char* string = PCB_toString(current_pcb, &error); printf("Now Running: %s\n", string); free(string); Interrupt interrupt = CPU_run(); execute_ISR(interrupt); }
int main() { CPU_t* cpu; FILE* in = fopen("out.txt","r"); CPU_ctor(cpu); if(!cmd_download(cpu, in)) { printf("Empty commands file!!\n"); CPU_dtor(cpu); return 0; } CPU_run(cpu); CPU_dump(cpu); CPU_dtor(cpu); printf("LOL\n"); // LOL :) return 0; }
/**************** Sample generation ****************/ int SPC_play( THIS, long count, int32_t* out ) { int i; assert( count % 2 == 0 ); /* output is always in pairs of samples */ long start_time = -(count >> 1) * CLOCKS_PER_SAMPLE - EXTRA_CLOCKS; /* DSP output is made on-the-fly when DSP registers are read or written */ this->sample_buf = out; this->next_dsp = start_time + CLOCKS_PER_SAMPLE; /* Localize timer next_tick times and run them to the present to prevent a running but ignored timer's next_tick from getting too far behind and overflowing. */ for ( i = 0; i < TIMER_COUNT; i++ ) { struct Timer* t = &this->timer [i]; if ( t->enabled ) { t->next_tick += start_time + EXTRA_CLOCKS; Timer_run( t, start_time ); } } /* Run from start_time to 0, pre-advancing by extra cycles from last run */ this->extra_cycles = CPU_run( this, start_time + this->extra_cycles ) + EXTRA_CLOCKS; if ( this->extra_cycles < 0 ) { /*dprintf( "Unhandled instruction $%02X, pc = $%04X\n", (int) CPU_read( r.pc ), (unsigned) r.pc ); */ return -1; } /* Catch DSP up to present */ ENTER_TIMER(cpu); SPC_run_dsp( this, -EXTRA_CLOCKS ); EXIT_TIMER(cpu); assert( this->next_dsp == CLOCKS_PER_SAMPLE - EXTRA_CLOCKS ); assert( this->sample_buf - out == count ); 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); } } }