ICD APIs
This commit is contained in:
parent
e1873ad2ec
commit
346e499602
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
Core/gb.c
27
Core/gb.c
@ -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();
|
||||||
@ -641,9 +650,11 @@ static void reset_ram(GB_gameboy_t *gb)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user