BESS format updates

This commit is contained in:
Lior Halphon 2021-04-06 01:02:49 +03:00
parent 7a558492b6
commit 1c31812ffd

View File

@ -52,23 +52,20 @@ typedef struct __attribute__((packed)) {
uint8_t execution_mode; // 0 = running; 1 = halted; 2 = stopped uint8_t execution_mode; // 0 = running; 1 = halted; 2 = stopped
uint8_t io_registers[0x80]; uint8_t io_registers[0x80];
uint8_t hram[0x7f];
BESS_buffer_t ram; BESS_buffer_t ram;
BESS_buffer_t vram; BESS_buffer_t vram;
BESS_buffer_t mbc_ram; BESS_buffer_t mbc_ram;
BESS_buffer_t oam;
BESS_buffer_t hram;
BESS_buffer_t background_palettes;
BESS_buffer_t sprite_palettes;
} BESS_CORE_t; } BESS_CORE_t;
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
BESS_block_t header; BESS_block_t header;
uint8_t oam[256]; uint8_t extra_oam[96];
} BESS_OAM_t; } BESS_XOAM_t;
typedef struct __attribute__((packed)) {
BESS_block_t header;
uint8_t background_palettes[0x40];
uint8_t sprite_palettes[0x40];
} BESS_PALS_t;
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
BESS_block_t header; BESS_block_t header;
@ -233,8 +230,7 @@ size_t GB_get_save_state_size(GB_gameboy_t *gb)
+ sizeof(BESS_CORE_t) + sizeof(BESS_CORE_t)
+ sizeof(BESS_block_t) // NAME + sizeof(BESS_block_t) // NAME
+ sizeof(BESS_NAME) - 1 + sizeof(BESS_NAME) - 1
+ sizeof(BESS_OAM_t) + sizeof(BESS_XOAM_t)
+ (GB_is_cgb(gb)? sizeof(BESS_PALS_t) : 0)
+ (gb->sgb? sizeof(BESS_SGB_t) : 0) + (gb->sgb? sizeof(BESS_SGB_t) : 0)
+ bess_size_for_cartridge(gb->cartridge_type) // MBC & RTC block + bess_size_for_cartridge(gb->cartridge_type) // MBC & RTC block
+ sizeof(BESS_block_t) // END block + sizeof(BESS_block_t) // END block
@ -456,10 +452,12 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
if (!DUMP_SECTION(gb, file, core_state)) goto error; if (!DUMP_SECTION(gb, file, core_state)) goto error;
if (!DUMP_SECTION(gb, file, dma )) goto error; if (!DUMP_SECTION(gb, file, dma )) goto error;
if (!DUMP_SECTION(gb, file, mbc )) goto error; if (!DUMP_SECTION(gb, file, mbc )) goto error;
uint32_t hram_offset = file->tell(file) + 4;
if (!DUMP_SECTION(gb, file, hram )) goto error; if (!DUMP_SECTION(gb, file, hram )) goto error;
if (!DUMP_SECTION(gb, file, timing )) goto error; if (!DUMP_SECTION(gb, file, timing )) goto error;
if (!DUMP_SECTION(gb, file, apu )) goto error; if (!DUMP_SECTION(gb, file, apu )) goto error;
if (!DUMP_SECTION(gb, file, rtc )) goto error; if (!DUMP_SECTION(gb, file, rtc )) goto error;
uint32_t video_offset = file->tell(file) + 4;
if (!DUMP_SECTION(gb, file, video )) goto error; if (!DUMP_SECTION(gb, file, video )) goto error;
uint32_t sgb_offset = 0; uint32_t sgb_offset = 0;
@ -470,7 +468,7 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
if (!dump_section(file, gb->sgb, sizeof(*gb->sgb))) goto error; if (!dump_section(file, gb->sgb, sizeof(*gb->sgb))) goto error;
} }
BESS_CORE_t bess_core; BESS_CORE_t bess_core = {0,};
bess_core.mbc_ram.offset = LE32(file->tell(file)); bess_core.mbc_ram.offset = LE32(file->tell(file));
bess_core.mbc_ram.size = LE32(gb->mbc_ram_size); bess_core.mbc_ram.size = LE32(gb->mbc_ram_size);
@ -555,21 +553,30 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
bess_core.io_registers[GB_IO_DIV] = gb->div_counter >> 8; bess_core.io_registers[GB_IO_DIV] = gb->div_counter >> 8;
bess_core.io_registers[GB_IO_BANK] = gb->boot_rom_finished; bess_core.io_registers[GB_IO_BANK] = gb->boot_rom_finished;
bess_core.io_registers[GB_IO_KEY1] |= gb->cgb_double_speed? 0x80 : 0; bess_core.io_registers[GB_IO_KEY1] |= gb->cgb_double_speed? 0x80 : 0;
memcpy(bess_core.hram, gb->hram, sizeof(gb->hram)); bess_core.hram.size = LE32(sizeof(gb->hram));
bess_core.hram.offset = LE32(hram_offset + offsetof(GB_gameboy_t, hram) - GB_SECTION_OFFSET(hram));
bess_core.oam.size = LE32(sizeof(gb->oam));
bess_core.oam.offset = LE32(video_offset + offsetof(GB_gameboy_t, oam) - GB_SECTION_OFFSET(video));
if (GB_is_cgb(gb)) {
bess_core.background_palettes.size = LE32(sizeof(gb->background_palettes_data));
bess_core.background_palettes.offset = LE32(video_offset + offsetof(GB_gameboy_t, background_palettes_data) - GB_SECTION_OFFSET(video));
bess_core.sprite_palettes.size = LE32(sizeof(gb->sprite_palettes_data));
bess_core.sprite_palettes.offset = LE32(video_offset + offsetof(GB_gameboy_t, sprite_palettes_data) - GB_SECTION_OFFSET(video));
}
if (file->write(file, &bess_core, sizeof(bess_core)) != sizeof(bess_core)) { if (file->write(file, &bess_core, sizeof(bess_core)) != sizeof(bess_core)) {
goto error; goto error;
} }
/* BESS OAM */ /* BESS XOAM */
BESS_OAM_t bess_oam; BESS_XOAM_t bess_xoam = {0,};
bess_oam.header = (BESS_block_t){BE32('OAM '), LE32(sizeof(bess_oam) - sizeof(bess_oam.header))}; bess_xoam.header = (BESS_block_t){BE32('XOAM'), LE32(sizeof(bess_xoam) - sizeof(bess_xoam.header))};
memcpy(bess_oam.oam, gb->oam, sizeof(gb->oam)); if (GB_is_cgb(gb)) {
memcpy(bess_oam.oam + sizeof(gb->oam), gb->extra_oam, sizeof(gb->extra_oam)); memcpy(bess_xoam.extra_oam, gb->extra_oam, sizeof(bess_xoam.extra_oam));
}
if (file->write(file, &bess_oam, sizeof(bess_oam)) != sizeof(bess_oam)) { if (file->write(file, &bess_xoam, sizeof(bess_xoam)) != sizeof(bess_xoam)) {
goto error; goto error;
} }
@ -593,19 +600,6 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
} }
} }
if (GB_is_cgb(gb)) {
/* BESS PALS */
BESS_PALS_t bess_pals;
bess_pals.header = (BESS_block_t){BE32('PALS'), LE32(sizeof(bess_pals) - sizeof(bess_oam.header))};
memcpy(bess_pals.background_palettes, gb->background_palettes_data, sizeof(bess_pals.background_palettes));
memcpy(bess_pals.sprite_palettes, gb->sprite_palettes_data, sizeof(bess_pals.sprite_palettes));
if (file->write(file, &bess_pals, sizeof(bess_pals)) != sizeof(bess_pals)) {
goto error;
}
}
bool needs_sgb_padding = false; bool needs_sgb_padding = false;
if (gb->sgb) { if (gb->sgb) {
/* BESS SGB */ /* BESS SGB */
@ -808,8 +802,6 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
save.halted = core.execution_mode == 1; save.halted = core.execution_mode == 1;
save.stopped = core.execution_mode == 2; save.stopped = core.execution_mode == 2;
memcpy(save.hram, core.hram, sizeof(save.hram));
// CPU related // CPU related
// Determines DMG mode // Determines DMG mode
@ -884,19 +876,10 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
file->read(file, emulator_name, LE32(block.size)); file->read(file, emulator_name, LE32(block.size));
} }
break; break;
case BE32('OAM '): case BE32('XOAM'):
if (!found_core) goto parse_error; if (!found_core) goto parse_error;
if (LE32(block.size) != 256 && LE32(block.size) != 160) goto parse_error; if (LE32(block.size) != 96) goto parse_error;
file->read(file, save.oam, sizeof(save.oam)); file->read(file, save.extra_oam, sizeof(save.extra_oam));
if (LE32(block.size) == 256) {
file->read(file, save.extra_oam, sizeof(save.extra_oam));
}
break;
case BE32('PALS'):
if (!found_core) goto parse_error;
if (LE32(block.size) != sizeof(BESS_PALS_t) - sizeof(block)) goto parse_error;
file->read(file, save.background_palettes_data, sizeof(save.background_palettes_data));
file->read(file, save.sprite_palettes_data, sizeof(save.sprite_palettes_data));
break; break;
case BE32('MBC '): case BE32('MBC '):
if (!found_core) goto parse_error; if (!found_core) goto parse_error;
@ -950,6 +933,10 @@ done:
read_bess_buffer(&core.ram, file, gb->ram, gb->ram_size); read_bess_buffer(&core.ram, file, gb->ram, gb->ram_size);
read_bess_buffer(&core.vram, file, gb->vram, gb->vram_size); read_bess_buffer(&core.vram, file, gb->vram, gb->vram_size);
read_bess_buffer(&core.mbc_ram, file, gb->mbc_ram, gb->mbc_ram_size); read_bess_buffer(&core.mbc_ram, file, gb->mbc_ram, gb->mbc_ram_size);
read_bess_buffer(&core.oam, file, gb->oam, sizeof(gb->oam));
read_bess_buffer(&core.hram, file, gb->hram, sizeof(gb->hram));
read_bess_buffer(&core.background_palettes, file, gb->background_palettes_data, sizeof(gb->background_palettes_data));
read_bess_buffer(&core.sprite_palettes, file, gb->sprite_palettes_data, sizeof(gb->sprite_palettes_data));
if (gb->sgb) { if (gb->sgb) {
memset(gb->sgb, 0, sizeof(*gb->sgb)); memset(gb->sgb, 0, sizeof(*gb->sgb));
GB_sgb_load_default_data(gb); GB_sgb_load_default_data(gb);