This commit is contained in:
Lior Halphon 2019-07-15 23:02:58 +03:00
parent e1873ad2ec
commit 346e499602
4 changed files with 57 additions and 9 deletions

View File

@ -137,9 +137,8 @@ static void display_vblank(GB_gameboy_t *gb)
if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || gb->stopped) || gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON)) { if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || gb->stopped) || gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON)) {
/* LCD is off, set screen to white or black (if LCD is on in stop mode) */ /* LCD is off, set screen to white or black (if LCD is on in stop mode) */
if (gb->sgb) { if (gb->sgb) {
uint8_t color = (gb->io_registers[GB_IO_LCDC] & 0x80) && gb->stopped && GB_is_cgb(gb) ? 0x3 : 0x0;
for (unsigned i = 0; i < WIDTH * LINES; i++) { for (unsigned i = 0; i < WIDTH * LINES; i++) {
gb->sgb->screen_buffer[i] = color; gb->sgb->screen_buffer[i] = 0x0;
} }
} }
else { else {
@ -387,9 +386,12 @@ static void render_pixel_if_possible(GB_gameboy_t *gb)
} }
if (gb->sgb) { if (gb->sgb) {
if (gb->current_lcd_line < LINES) { if (gb->current_lcd_line < LINES) {
gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = pixel; gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = gb->stopped? 0 : pixel;
} }
} }
else if (gb->model & GB_MODEL_NO_SFC_BIT) {
gb->icd_row[gb->position_in_line] = pixel;
}
else { else {
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[fifo_item->palette * 4 + pixel]; gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[fifo_item->palette * 4 + pixel];
} }
@ -403,9 +405,12 @@ static void render_pixel_if_possible(GB_gameboy_t *gb)
} }
if (gb->sgb) { if (gb->sgb) {
if (gb->current_lcd_line < LINES) { if (gb->current_lcd_line < LINES) {
gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = pixel; gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = gb->stopped? 0 : pixel;
} }
} }
else if (gb->model & GB_MODEL_NO_SFC_BIT) {
gb->icd_row[gb->position_in_line] = pixel;
}
else { else {
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->sprite_palettes_rgb[oam_fifo_item->palette * 4 + pixel]; gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->sprite_palettes_rgb[oam_fifo_item->palette * 4 + pixel];
} }
@ -890,6 +895,11 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
} }
GB_SLEEP(gb, display, 11, LINE_LENGTH - gb->cycles_for_line); GB_SLEEP(gb, display, 11, LINE_LENGTH - gb->cycles_for_line);
gb->mode_for_interrupt = 2; gb->mode_for_interrupt = 2;
/* TODO: Can this timing even be verified? */
if (gb->icd_row_callback) {
gb->icd_row_callback(gb, gb->icd_row);
}
} }
/* Lines 144 - 152 */ /* Lines 144 - 152 */
@ -961,7 +971,11 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
gb->wy_diff = 0; gb->wy_diff = 0;
gb->window_disabled_while_active = false; gb->window_disabled_while_active = false;
gb->current_line = 0; gb->current_line = 0;
gb->current_lcd_line = -1; // TODO: not the correct timing // TODO: not the correct timing
gb->current_lcd_line = -1;
if (gb->icd_vreset_callback) {
gb->icd_vreset_callback(gb);
}
} }
} }

View File

@ -112,6 +112,11 @@ void GB_init(GB_gameboy_t *gb, GB_model_t model)
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
gb->clock_multiplier = 1.0; gb->clock_multiplier = 1.0;
if (model & GB_MODEL_NO_SFC_BIT) {
/* Disable time syncing. Timing should be done by the SFC emulator. */
gb->turbo = true;
}
GB_reset(gb); GB_reset(gb);
} }
@ -576,6 +581,7 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* Unverified */ case GB_MODEL_SGB_PAL: /* Unverified */
case GB_MODEL_SGB_NO_SFC:
for (unsigned i = 0; i < gb->ram_size; i++) { for (unsigned i = 0; i < gb->ram_size; i++) {
gb->ram[i] = GB_random(); gb->ram[i] = GB_random();
if (i & 0x100) { if (i & 0x100) {
@ -588,6 +594,7 @@ static void reset_ram(GB_gameboy_t *gb)
break; break;
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
for (unsigned i = 0; i < gb->ram_size; i++) { for (unsigned i = 0; i < gb->ram_size; i++) {
gb->ram[i] = 0x55; gb->ram[i] = 0x55;
gb->ram[i] ^= GB_random() & GB_random() & GB_random(); gb->ram[i] ^= GB_random() & GB_random() & GB_random();
@ -620,7 +627,9 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* Unverified */ case GB_MODEL_SGB_PAL: /* Unverified */
case GB_MODEL_SGB_NO_SFC:
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
for (unsigned i = 0; i < sizeof(gb->hram); i++) { for (unsigned i = 0; i < sizeof(gb->hram); i++) {
if (i & 1) { if (i & 1) {
gb->hram[i] = GB_random() | GB_random() | GB_random(); gb->hram[i] = GB_random() | GB_random() | GB_random();
@ -643,7 +652,9 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified */ case GB_MODEL_SGB_NTSC: /* Unverified */
case GB_MODEL_SGB_PAL: /* Unverified */ case GB_MODEL_SGB_PAL: /* Unverified */
case GB_MODEL_SGB_NO_SFC: /* Unverified */
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
for (unsigned i = 0; i < 8; i++) { for (unsigned i = 0; i < 8; i++) {
if (i & 2) { if (i & 2) {
gb->oam[i] = GB_random() & GB_random() & GB_random(); gb->oam[i] = GB_random() & GB_random() & GB_random();
@ -669,7 +680,9 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* Unverified */ case GB_MODEL_SGB_PAL: /* Unverified */
case GB_MODEL_SGB2: { case GB_MODEL_SGB_NO_SFC: /* Unverified */
case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC: {
uint8_t temp; uint8_t temp;
for (unsigned i = 0; i < GB_IO_WAV_END - GB_IO_WAV_START; i++) { for (unsigned i = 0; i < GB_IO_WAV_END - GB_IO_WAV_START; i++) {
if (i & 1) { if (i & 1) {
@ -911,3 +924,13 @@ void GB_set_joyp_write_callback(GB_gameboy_t *gb, GB_joyp_write_callback_t callb
{ {
gb->joyp_write_callback = callback; gb->joyp_write_callback = callback;
} }
void GB_set_icd_row_callback(GB_gameboy_t *gb, GB_icd_row_callback_t callback)
{
gb->icd_row_callback = callback;
}
void GB_set_icd_vreset_callback(GB_gameboy_t *gb, GB_icd_vreset_callback_t callback)
{
gb->icd_vreset_callback = callback;
}

View File

@ -23,7 +23,6 @@
#define GB_STRUCT_VERSION 13 #define GB_STRUCT_VERSION 13
#ifdef GB_INTERNAL
#define GB_MODEL_FAMILY_MASK 0xF00 #define GB_MODEL_FAMILY_MASK 0xF00
#define GB_MODEL_DMG_FAMILY 0x000 #define GB_MODEL_DMG_FAMILY 0x000
#define GB_MODEL_MGB_FAMILY 0x100 #define GB_MODEL_MGB_FAMILY 0x100
@ -31,6 +30,7 @@
#define GB_MODEL_PAL_BIT 0x1000 #define GB_MODEL_PAL_BIT 0x1000
#define GB_MODEL_NO_SFC_BIT 0x2000 #define GB_MODEL_NO_SFC_BIT 0x2000
#ifdef GB_INTERNAL
#if __clang__ #if __clang__
#define UNROLL _Pragma("unroll") #define UNROLL _Pragma("unroll")
#elif __GNUC__ #elif __GNUC__
@ -243,6 +243,8 @@ typedef void (*GB_serial_transfer_bit_start_callback_t)(GB_gameboy_t *gb, bool b
typedef bool (*GB_serial_transfer_bit_end_callback_t)(GB_gameboy_t *gb); typedef bool (*GB_serial_transfer_bit_end_callback_t)(GB_gameboy_t *gb);
typedef void (*GB_update_input_hint_callback_t)(GB_gameboy_t *gb); typedef void (*GB_update_input_hint_callback_t)(GB_gameboy_t *gb);
typedef void (*GB_joyp_write_callback_t)(GB_gameboy_t *gb, uint8_t value); typedef void (*GB_joyp_write_callback_t)(GB_gameboy_t *gb, uint8_t value);
typedef void (*GB_icd_row_callback_t)(GB_gameboy_t *gb, uint8_t *row);
typedef void (*GB_icd_vreset_callback_t)(GB_gameboy_t *gb);
typedef struct { typedef struct {
bool state; bool state;
@ -420,6 +422,7 @@ struct GB_gameboy_internal_s {
uint16_t serial_length; uint16_t serial_length;
uint8_t double_speed_alignment; uint8_t double_speed_alignment;
uint8_t serial_count; uint8_t serial_count;
uint8_t icd_row[160];
); );
/* APU */ /* APU */
@ -535,6 +538,8 @@ struct GB_gameboy_internal_s {
GB_serial_transfer_bit_end_callback_t serial_transfer_bit_end_callback; GB_serial_transfer_bit_end_callback_t serial_transfer_bit_end_callback;
GB_update_input_hint_callback_t update_input_hint_callback; GB_update_input_hint_callback_t update_input_hint_callback;
GB_joyp_write_callback_t joyp_write_callback; GB_joyp_write_callback_t joyp_write_callback;
GB_icd_row_callback_t icd_row_callback;
GB_icd_vreset_callback_t icd_vreset_callback;
/* IR */ /* IR */
long cycles_since_ir_change; // In 8MHz units long cycles_since_ir_change; // In 8MHz units
@ -696,6 +701,8 @@ void GB_disconnect_serial(GB_gameboy_t *gb);
/* For integration with SFC/SNES emulators */ /* For integration with SFC/SNES emulators */
void GB_set_joyp_write_callback(GB_gameboy_t *gb, GB_joyp_write_callback_t callback); void GB_set_joyp_write_callback(GB_gameboy_t *gb, GB_joyp_write_callback_t callback);
void GB_set_icd_row_callback(GB_gameboy_t *gb, GB_icd_row_callback_t callback);
void GB_set_icd_vreset_callback(GB_gameboy_t *gb, GB_icd_vreset_callback_t callback);
#ifdef GB_INTERNAL #ifdef GB_INTERNAL
uint32_t GB_get_clock_rate(GB_gameboy_t *gb); uint32_t GB_get_clock_rate(GB_gameboy_t *gb);

View File

@ -273,7 +273,9 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_NTSC:
case GB_MODEL_SGB_PAL: case GB_MODEL_SGB_PAL:
case GB_MODEL_SGB_NO_SFC:
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
; ;
} }
} }
@ -584,7 +586,9 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_NTSC:
case GB_MODEL_SGB_PAL: case GB_MODEL_SGB_PAL:
case GB_MODEL_SGB_NO_SFC:
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:
case GB_MODEL_AGB: case GB_MODEL_AGB:
break; break;