diff --git a/Core/display.c b/Core/display.c index e25a6c2..38dca24 100644 --- a/Core/display.c +++ b/Core/display.c @@ -912,12 +912,15 @@ static void render_line(GB_gameboy_t *gb) unsigned priority:6; // Object priority – 0 in DMG, OAM index in CGB unsigned palette:3; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG) bool bg_priority:1; // BG priority bit - } object_buffer[160 + 16]; // allocate extra to avoid per pixel checks - memset(object_buffer, 0, sizeof(object_buffer)); - + } _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks + static const uint8_t empty_object_buffer[sizeof(_object_buffer)]; + const typeof(_object_buffer[0]) *object_buffer; + if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) { + object_buffer = &_object_buffer[0]; object_t *objects = (object_t *) &gb->oam; - + memset(_object_buffer, 0, sizeof(_object_buffer)); + while (gb->n_visible_objs) { unsigned object_index = gb->visible_objs[gb->n_visible_objs - 1]; unsigned priority = gb->object_priority == GB_OBJECT_PRIORITY_X? 0 : object_index; @@ -932,7 +935,7 @@ static void render_line(GB_gameboy_t *gb) data1 = flip(data1); } - typeof(object_buffer[0]) *p = object_buffer + object->x; + typeof(_object_buffer[0]) *p = _object_buffer + object->x; if (object->x >= 168) { continue; } @@ -956,6 +959,9 @@ static void render_line(GB_gameboy_t *gb) } } } + else { + object_buffer = (const void *)empty_object_buffer; + } uint32_t *restrict p = gb->screen; @@ -1069,11 +1075,14 @@ static void render_line_sgb(GB_gameboy_t *gb) unsigned pixel:2; // Color, 0-3 unsigned palette:1; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG) bool bg_priority:1; // BG priority bit - } object_buffer[160 + 16]; // allocate extra to avoid per pixel checks - memset(object_buffer, 0, sizeof(object_buffer)); + } _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks + static const uint8_t empty_object_buffer[sizeof(_object_buffer)]; + const typeof(_object_buffer[0]) *object_buffer; if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) { + object_buffer = &_object_buffer[0]; object_t *objects = (object_t *) &gb->oam; + memset(_object_buffer, 0, sizeof(_object_buffer)); while (gb->n_visible_objs) { const object_t *object = &objects[gb->visible_objs[gb->n_visible_objs - 1]]; @@ -1087,7 +1096,7 @@ static void render_line_sgb(GB_gameboy_t *gb) data1 = flip(data1); } - typeof(object_buffer[0]) *p = object_buffer + object->x; + typeof(_object_buffer[0]) *p = _object_buffer + object->x; if (object->x >= 168) { continue; } @@ -1104,6 +1113,9 @@ static void render_line_sgb(GB_gameboy_t *gb) } } } + else { + object_buffer = (const void *)empty_object_buffer; + } uint8_t *restrict p = gb->sgb->screen_buffer; diff --git a/Core/memory.c b/Core/memory.c index cd76d57..2493238 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -1648,7 +1648,7 @@ void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) void GB_dma_run(GB_gameboy_t *gb) { - while (gb->dma_cycles >= 4 && gb->dma_steps_left) { + while (unlikely(gb->dma_cycles >= 4 && gb->dma_steps_left)) { /* Todo: measure this value */ gb->dma_cycles -= 4; gb->dma_steps_left--; @@ -1671,7 +1671,7 @@ void GB_dma_run(GB_gameboy_t *gb) void GB_hdma_run(GB_gameboy_t *gb) { - if (!gb->hdma_on) return; + if (likely(!gb->hdma_on)) return; while (gb->hdma_cycles >= 0x4) { gb->hdma_cycles -= 0x4; diff --git a/Core/timing.c b/Core/timing.c index 3cf62bc..d405918 100644 --- a/Core/timing.c +++ b/Core/timing.c @@ -113,7 +113,7 @@ void GB_timing_sync(GB_gameboy_t *gb) static void ir_run(GB_gameboy_t *gb, uint32_t cycles) { - if (gb->model == GB_MODEL_AGB) return; + if ((gb->model == GB_MODEL_AGB || !gb->cgb_mode) && gb->cartridge_type->mbc_type != GB_HUC1 && gb->cartridge_type->mbc_type != GB_HUC3) return; if (gb->infrared_input || gb->cart_ir || (gb->io_registers[GB_IO_RP] & 1)) { gb->ir_sensor += cycles; if (gb->ir_sensor > IR_MAX) { @@ -203,10 +203,10 @@ static void timers_run(GB_gameboy_t *gb, uint8_t cycles) static void advance_serial(GB_gameboy_t *gb, uint8_t cycles) { - if (gb->printer.command_state || gb->printer.bits_received) { + if (unlikely(gb->printer_callback && (gb->printer.command_state || gb->printer.bits_received))) { gb->printer.idle_time += cycles; } - if (gb->serial_length == 0) { + if (likely(gb->serial_length == 0)) { gb->serial_cycles += cycles; return; } @@ -270,7 +270,7 @@ void GB_set_rtc_multiplier(GB_gameboy_t *gb, double multiplier) static void rtc_run(GB_gameboy_t *gb, uint8_t cycles) { - if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return; + if (likely(gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc)) return; gb->rtc_cycles += cycles; time_t current_time = 0; uint32_t rtc_second_length = unlikely(gb->rtc_second_length)? gb->rtc_second_length : GB_get_unmultiplied_clock_rate(gb) * 2; @@ -368,7 +368,7 @@ static void rtc_run(GB_gameboy_t *gb, uint8_t cycles) void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) { - if (gb->speed_switch_countdown) { + if (unlikely(gb->speed_switch_countdown)) { if (gb->speed_switch_countdown == cycles) { gb->cgb_double_speed ^= true; gb->speed_switch_countdown = 0; @@ -389,11 +389,11 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) gb->dma_cycles += cycles; timers_run(gb, cycles); - if (!gb->stopped) { + if (unlikely(!gb->stopped)) { advance_serial(gb, cycles); // TODO: Verify what happens in STOP mode } - if (gb->speed_switch_halt_countdown) { + if (unlikely(gb->speed_switch_halt_countdown)) { gb->speed_switch_halt_countdown -= cycles; if (gb->speed_switch_halt_countdown <= 0) { gb->speed_switch_halt_countdown = 0; @@ -412,14 +412,14 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) gb->speed_switch_freeze = 0; } - if (!gb->cgb_double_speed) { + if (unlikely(!gb->cgb_double_speed)) { cycles <<= 1; } gb->absolute_debugger_ticks += cycles; // Not affected by speed boost - if (gb->io_registers[GB_IO_LCDC] & 0x80) { + if (likely(gb->io_registers[GB_IO_LCDC] & 0x80)) { gb->double_speed_alignment += cycles; } gb->hdma_cycles += cycles; @@ -430,7 +430,7 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) gb->rumble_on_cycles += gb->rumble_strength & 3; gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3; - if (!gb->stopped) { // TODO: Verify what happens in STOP mode + if (unlikely(!gb->stopped)) { // TODO: Verify what happens in STOP mode GB_dma_run(gb); GB_hdma_run(gb); }