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).
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user