From ea2ea1e293fede48c29041300bd4f466c208c79a Mon Sep 17 00:00:00 2001 From: Max Regan Date: Mon, 2 Jul 2018 00:12:07 -0700 Subject: [PATCH] gbdb,cpu,video: reduce number of calls to cycle functions Instead of calling cpu_cycle() and video_cycle() once per emulated cycle, call cpu_cycle() once per emulated instruction. This should not have any obvious effects on the emulation (as currently written), because all of the memory reads and writes are done in the first "cycle" of the instruction. This patch results in a substantial performance gain (>100%, if I recall correctly). --- src/apps/gbdb.c | 6 ++++-- src/gbemu/cpu.c | 17 +++++++---------- src/gbemu/cpu.h | 2 +- src/gbemu/video.c | 9 ++++----- src/gbemu/video.h | 2 +- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/apps/gbdb.c b/src/apps/gbdb.c index 256fe90..f1bd0b1 100644 --- a/src/apps/gbdb.c +++ b/src/apps/gbdb.c @@ -164,8 +164,10 @@ static void init(void) static void cycle() { - lr35902_cycle(&cpu); - gb_video_cycle(&video); + int cycles; + + cycles = lr35902_cycle(&cpu); + gb_video_cycle(&video, cycles); } static void show_prompt() diff --git a/src/gbemu/cpu.c b/src/gbemu/cpu.c index 5098ec1..65731c8 100644 --- a/src/gbemu/cpu.c +++ b/src/gbemu/cpu.c @@ -315,23 +315,17 @@ static const unsigned int cb_extra_cycles[256] = { 0 }; (cpu)->zf = (tmp) == 0; \ } while (0) -void lr35902_cycle(struct lr35902_state *cpu) +int lr35902_cycle(struct lr35902_state *cpu) { uint8_t inst; uint8_t val; uint16_t val_16; uint8_t *reg = NULL; - - cpu->metrics.cycles++; - - if (cpu->stall_cycles > 0) { - cpu->stall_cycles--; - return; - } + int cycles; cpu->metrics.retired_instrs++; inst = cpu->mem_read(cpu, cpu->pc++); - cpu->stall_cycles = op_extra_cycles[inst]; + cycles = op_extra_cycles[inst]; switch (inst) { case 0x00: /* NOP */ @@ -995,7 +989,7 @@ void lr35902_cycle(struct lr35902_state *cpu) case 0xca: case 0xcb: inst = cpu->mem_read(cpu, cpu->pc++); - cpu->stall_cycles = cb_extra_cycles[inst]; + cycles = cb_extra_cycles[inst]; switch (inst) { case 0x00: case 0x01: @@ -1475,4 +1469,7 @@ void lr35902_cycle(struct lr35902_state *cpu) RST(cpu, 0x38); break; } + + cpu->metrics.cycles += cycles + 1; + return cycles + 1; } diff --git a/src/gbemu/cpu.h b/src/gbemu/cpu.h index e4ab46d..55f73b0 100644 --- a/src/gbemu/cpu.h +++ b/src/gbemu/cpu.h @@ -135,6 +135,6 @@ void lr35902_set_reg_8(struct lr35902_state *cpu, lr35902_regs_8 reg, uint8_t val); -void lr35902_cycle(struct lr35902_state *cpu); +int lr35902_cycle(struct lr35902_state *cpu); #endif diff --git a/src/gbemu/video.c b/src/gbemu/video.c index d5e00f4..f9d141f 100644 --- a/src/gbemu/video.c +++ b/src/gbemu/video.c @@ -12,12 +12,11 @@ void gb_video_init(struct gb_video *video) memset(video, 0, sizeof(*video)); } -void gb_video_cycle(struct gb_video *video) +void gb_video_cycle(struct gb_video *video, int cycles) { - if (video->line_counter < CYCLES_PER_LINE - 1) { - video->line_counter++; - } else { - video->line_counter = 0; + video->line_counter += cycles; + if (video->line_counter >= CYCLES_PER_LINE) { + video->line_counter -= CYCLES_PER_LINE; video->curline += 1; if (video->curline > LCD_Y_MAX) { video->curline = 0; diff --git a/src/gbemu/video.h b/src/gbemu/video.h index 4d78803..4facce5 100644 --- a/src/gbemu/video.h +++ b/src/gbemu/video.h @@ -93,7 +93,7 @@ struct gb_video { }; void gb_video_init(struct gb_video *video); -void gb_video_cycle(struct gb_video *video); +void gb_video_cycle(struct gb_video *video, int cycles); uint8_t gb_video_mem_read(struct gb_video *video, uint16_t addr); void gb_video_mem_write(struct gb_video *video, uint16_t addr, uint8_t val);