static INLINE u8 memread(u32 addr) { static int n; //handle dpcm cycle stealing if(nes->cpu.pcmcycles) { n = nes->cpu.pcmcycles - 1; nes->cpu.pcmcycles = 0; if(addr == 0x4016 || addr == 0x4017) { if(n--) memread(addr); while(n--) cpu_tick(); } else { while(n--) memread(addr); } apu_dpcm_fetch(); } //increment cycle counter, check irq lines cpu_tick(); //read data from address return(cpu_read(addr)); }
static INLINE void memwrite(u32 addr,u8 data) { //handle dpcm cycle stealing if(nes->cpu.pcmcycles) nes->cpu.pcmcycles--; //increment cycle counter, check irq lines cpu_tick(); //write data to its address cpu_write(addr,data); }
static void track_free(void* p, size_t size) { track_init(); assert(!track.internal); track.internal = true; track.stack = pool_track_push(track.stack, POOL_TRACK_FREE); track.stack = pool_track_push(track.stack, p); track.stack = pool_track_push(track.stack, (void*)size); track.stack = pool_track_push(track.stack, (void*)cpu_tick()); track.internal = false; }
static void track_alloc(void* p, size_t size) { track_init(); if(track.internal) return; track.internal = true; track.stack = pool_track_push(track.stack, POOL_TRACK_ALLOC); track.stack = pool_track_push(track.stack, p); track.stack = pool_track_push(track.stack, (void*)size); track.stack = pool_track_push(track.stack, (void*)cpu_tick()); track.internal = false; }
/** * Executes a single step * * @param emu Reference to the emulator structure */ void emulator_tick(emulator_t* emu) { cpu_tick(&emu->cpu); /* When graphics are emulated, we execute a screen refresh after 34ms has * passed (30 frames per second) */ uint32_t frame_time = 20; if (emu->graphics) { uint64_t now = emulator_get_time(); if ((now - emu->last_refresh) > frame_time) { fb_tick(&emu->fb); emu->last_refresh = now; } } }
static void track_pull(pool_item_t* p, size_t length, size_t size) { track_init(); assert(!track.internal); track.internal = true; uint64_t tsc = cpu_tick(); track.stack = pool_track_push(track.stack, POOL_TRACK_PULL_LIST); track.stack = pool_track_push(track.stack, (void*)length); track.stack = pool_track_push(track.stack, (void*)size); track.stack = pool_track_push(track.stack, (void*)tsc); while(p != NULL) { track.stack = pool_track_push(track.stack, POOL_TRACK_PULL); track.stack = pool_track_push(track.stack, p); track.stack = pool_track_push(track.stack, (void*)size); track.stack = pool_track_push(track.stack, (void*)tsc); p = p->next; } track.internal = false; }
int gb_tick(gb_t *gb) { update_joypad(gb); if (!cpu_tick(gb)) return 0; if (!lcd_tick(gb)) return 0; if (++gb->ticks == TICKS_MAX) { ERR("Game Over"); return 0; } // DMA if (gb->mem[IO_DMA] != 0xFF) { // XXX instant DMA? memcpy(&gb->mem[0xFE00], &gb->mem[gb->mem[IO_DMA] << 8], 0xA0); gb->mem[IO_DMA] = 0xFF; } if (++gb->ticks_divider == TICKS_DIVIDER) { gb->mem[IO_DIV]++; gb->ticks_divider = 0; } if (gb->mem[IO_TAC] & (1 << 2)) { // timer ON unsigned int total_ticks; switch(gb->mem[IO_TAC] & 3) { case 0: total_ticks = 244; break; case 1: total_ticks = 4; break; case 2: total_ticks = 15; break; case 3: total_ticks = 61; break; } if (++gb->ticks_timer >= total_ticks) { gb->ticks_timer = 0; if (gb->mem[IO_TIMA]++ == 0xFF) { //overflow gb->mem[IO_TIMA] = gb->mem[IO_TMA]; cpu_interrupt(gb, 2); } } } return 1; }