gbs: function to load from memory buffer

This commit is contained in:
John Regan 2021-04-20 08:38:53 -04:00
parent a2d3b8c174
commit 0e8d8effdf
2 changed files with 33 additions and 12 deletions

View File

@ -369,24 +369,25 @@ void GB_gbs_switch_track(GB_gameboy_t *gb, uint8_t track)
} }
} }
int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info) int GB_load_gbs_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size, GB_gbs_info_t *info)
{ {
FILE *f = fopen(path, "rb"); if(size < sizeof(gb->gbs_header)) {
if (!f) { GB_log(gb, "Not a valid GBS file.\n");
GB_log(gb, "Could not open GBS: %s.\n", strerror(errno)); return -1;
return errno;
} }
fread(&gb->gbs_header, sizeof(gb->gbs_header), 1, f);
memcpy(&gb->gbs_header,buffer,sizeof(gb->gbs_header));
if (gb->gbs_header.magic != BE32('GBS\x01') || if (gb->gbs_header.magic != BE32('GBS\x01') ||
((LE16(gb->gbs_header.load_address) < GBS_ENTRY + GBS_ENTRY_SIZE || ((LE16(gb->gbs_header.load_address) < GBS_ENTRY + GBS_ENTRY_SIZE ||
LE16(gb->gbs_header.load_address) >= 0x8000) && LE16(gb->gbs_header.load_address) >= 0x8000) &&
LE16(gb->gbs_header.load_address) != 0)) { LE16(gb->gbs_header.load_address) != 0)) {
GB_log(gb, "Not a valid GBS file.\n"); GB_log(gb, "Not a valid GBS file.\n");
fclose(f);
return -1; return -1;
} }
fseek(f, 0, SEEK_END);
size_t data_size = ftell(f) - sizeof(gb->gbs_header); size_t data_size = size - sizeof(gb->gbs_header);
gb->rom_size = (data_size + LE16(gb->gbs_header.load_address) + 0x3FFF) & ~0x3FFF; /* Round to bank */ gb->rom_size = (data_size + LE16(gb->gbs_header.load_address) + 0x3FFF) & ~0x3FFF; /* Round to bank */
/* And then round to a power of two */ /* And then round to a power of two */
while (gb->rom_size & (gb->rom_size - 1)) { while (gb->rom_size & (gb->rom_size - 1)) {
@ -398,14 +399,14 @@ int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
if (gb->rom_size == 0) { if (gb->rom_size == 0) {
gb->rom_size = 0x8000; gb->rom_size = 0x8000;
} }
fseek(f, sizeof(gb->gbs_header), SEEK_SET);
if (gb->rom) { if (gb->rom) {
free(gb->rom); free(gb->rom);
} }
gb->rom = malloc(gb->rom_size); gb->rom = malloc(gb->rom_size);
memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */ memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
fread(gb->rom + LE16(gb->gbs_header.load_address), 1, data_size, f); memcpy(gb->rom + LE16(gb->gbs_header.load_address), buffer + sizeof(gb->gbs_header), data_size);
fclose(f);
gb->cartridge_type = &GB_cart_defs[0x11]; gb->cartridge_type = &GB_cart_defs[0x11];
if (gb->mbc_ram) { if (gb->mbc_ram) {
@ -453,6 +454,25 @@ int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
return 0; return 0;
} }
int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
{
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open GBS: %s.\n", strerror(errno));
return errno;
}
fseek(f, 0, SEEK_END);
size_t file_size = ftell(f);
fseek(f, 0, SEEK_SET);
uint8_t *file_data = malloc(file_size);
fread(file_data,1,file_size,f);
fclose(f);
int r = GB_load_gbs_from_buffer(gb,file_data,file_size,info);
free(file_data);
return r;
}
int GB_load_isx(GB_gameboy_t *gb, const char *path) int GB_load_isx(GB_gameboy_t *gb, const char *path)
{ {
FILE *f = fopen(path, "rb"); FILE *f = fopen(path, "rb");

View File

@ -819,6 +819,7 @@ void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer,
int GB_load_rom(GB_gameboy_t *gb, const char *path); int GB_load_rom(GB_gameboy_t *gb, const char *path);
void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size); void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size);
int GB_load_isx(GB_gameboy_t *gb, const char *path); int GB_load_isx(GB_gameboy_t *gb, const char *path);
int GB_load_gbs_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size, GB_gbs_info_t *info);
int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info); int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info);
void GB_gbs_switch_track(GB_gameboy_t *gb, uint8_t track); void GB_gbs_switch_track(GB_gameboy_t *gb, uint8_t track);