deltabeard / Peanut-GB

A Game Boy (DMG) emulator single header library written in C99. Performance is prioritised over accuracy.
https://projects.deltabeard.com/peanutgb/
283 stars 40 forks source link

Potential Speed Up [Enhancement] #44

Closed froggestspirit closed 4 years ago

froggestspirit commented 4 years ago

I've been messing with this on a microcontroller, and was getting maybe around 80% speed (going by the crude audio I added). When the program hits a halt, the code has it run a bunch of filler nops until it hits the next interrupt. I've been testing a few things to skip past this, currently I changed the gb->counters to count down, so when it hits a nop, it can take the lowest counter and set the inst_cycles to the next multiple of 4 (4 is the minimum so it doesn't hang on the LCD timer being 0). This gives a small speedup.

froggestspirit commented 4 years ago

Actually, this is a potentially cleaner way to handle it, where the timers don't have to count down: ` if(gb->gb_halt){

static const unsigned int TAC_CYCLES[4] = {1024, 16, 64, 256};

inst_cycles = DIV_CYCLES-gb->counter.div_count;

if(LCD_LINE_CYCLES-gb->counter.lcd_count < inst_cycles) inst_cycles = LCD_LINE_CYCLES-gb->counter.lcd_count;

if(TAC_CYCLES[gb->gb_reg.tac_rate]-gb->counter.tima_count < inst_cycles) inst_cycles = TAC_CYCLES[gb->gb_reg.tac_rate]-gb->counter.tima_count;

if(SERIAL_CYCLES-gb->counter.serial_count < inst_cycles) inst_cycles = SERIAL_CYCLES-gb->counter.serial_count;

inst_cycles += 3;

inst_cycles &= 0xFFFC;

if(inst_cycles <= 0) inst_cycles = 4;

}else{

opcode = __gb_read(gb, gb->cpu_reg.pc++);`
froggestspirit commented 4 years ago

Actually, this is a potentially cleaner way to handle it, where the timers don't have to count down: ` if(gb->gb_halt){

static const unsigned int TAC_CYCLES[4] = {1024, 16, 64, 256};

inst_cycles = DIV_CYCLES-gb->counter.div_count;

if(LCD_LINE_CYCLES-gb->counter.lcd_count < inst_cycles) inst_cycles = LCD_LINE_CYCLES-gb->counter.lcd_count;

if(TAC_CYCLES[gb->gb_reg.tac_rate]-gb->counter.tima_count < inst_cycles) inst_cycles = TAC_CYCLES[gb->gb_reg.tac_rate]-gb->counter.tima_count;

if(SERIAL_CYCLES-gb->counter.serial_count < inst_cycles) inst_cycles = SERIAL_CYCLES-gb->counter.serial_count;

inst_cycles += 3;

inst_cycles &= 0xFFFC;

if(inst_cycles <= 0) inst_cycles = 4;

}else{

opcode = __gb_read(gb, gb->cpu_reg.pc++);`
froggestspirit commented 4 years ago

On further inspection, this can lead to some graphical issues.