Support for an alternative MBC1 wiring, should solve most N-in-1 carts (Issue #3)
This commit is contained in:
parent
c6bafe3fc3
commit
bd7f8f2555
@ -854,9 +854,14 @@ static bool mbc(GB_gameboy_t *gb, char *arguments)
|
|||||||
GB_log(gb, "Current mapped RAM bank: %x\n", gb->mbc_ram_bank);
|
GB_log(gb, "Current mapped RAM bank: %x\n", gb->mbc_ram_bank);
|
||||||
GB_log(gb, "RAM is curently %s\n", gb->mbc_ram_enable? "enabled" : "disabled");
|
GB_log(gb, "RAM is curently %s\n", gb->mbc_ram_enable? "enabled" : "disabled");
|
||||||
}
|
}
|
||||||
if (cartridge->mbc_type == GB_MBC1) {
|
if (cartridge->mbc_type == GB_MBC1 && gb->mbc1_wiring == GB_STANDARD_MBC1_WIRING) {
|
||||||
GB_log(gb, "MBC1 banking mode is %s\n", gb->mbc1.mode == 1 ? "RAM" : "ROM");
|
GB_log(gb, "MBC1 banking mode is %s\n", gb->mbc1.mode == 1 ? "RAM" : "ROM");
|
||||||
}
|
}
|
||||||
|
if (cartridge->mbc_type == GB_MBC1 && gb->mbc1_wiring == GB_MBC1M_WIRING) {
|
||||||
|
GB_log(gb, "MBC1 uses MBC1M wiring. \n");
|
||||||
|
GB_log(gb, "Current mapped ROM0 bank: %x\n", gb->mbc_rom0_bank);
|
||||||
|
GB_log(gb, "MBC1 multicart banking mode is %s\n", gb->mbc1.mode == 1 ? "enabled" : "disabled");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -165,12 +165,7 @@ int GB_load_rom(GB_gameboy_t *gb, const char *path)
|
|||||||
memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
|
memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
|
||||||
fread(gb->rom, gb->rom_size, 1, f);
|
fread(gb->rom, gb->rom_size, 1, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
gb->cartridge_type = &GB_cart_defs[gb->rom[0x147]];
|
GB_configure_cart(gb);
|
||||||
if (gb->cartridge_type->has_ram) {
|
|
||||||
static const int ram_sizes[256] = {0, 0x800, 0x2000, 0x8000, 0x20000, 0x10000};
|
|
||||||
gb->mbc_ram_size = ram_sizes[gb->rom[0x149]];
|
|
||||||
gb->mbc_ram = malloc(gb->mbc_ram_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -312,6 +312,10 @@ typedef struct GB_gameboy_s {
|
|||||||
uint8_t *rom;
|
uint8_t *rom;
|
||||||
uint32_t rom_size;
|
uint32_t rom_size;
|
||||||
const GB_cartridge_t *cartridge_type;
|
const GB_cartridge_t *cartridge_type;
|
||||||
|
enum {
|
||||||
|
GB_STANDARD_MBC1_WIRING,
|
||||||
|
GB_MBC1M_WIRING,
|
||||||
|
} mbc1_wiring;
|
||||||
|
|
||||||
/* Various RAMs */
|
/* Various RAMs */
|
||||||
uint8_t *ram;
|
uint8_t *ram;
|
||||||
|
51
Core/mbc.c
51
Core/mbc.c
@ -1,4 +1,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "gb.h"
|
#include "gb.h"
|
||||||
|
|
||||||
const GB_cartridge_t GB_cart_defs[256] = {
|
const GB_cartridge_t GB_cart_defs[256] = {
|
||||||
@ -50,14 +52,32 @@ void GB_update_mbc_mappings(GB_gameboy_t *gb)
|
|||||||
switch (gb->cartridge_type->mbc_type) {
|
switch (gb->cartridge_type->mbc_type) {
|
||||||
case GB_NO_MBC: case GB_MBC4: return;
|
case GB_NO_MBC: case GB_MBC4: return;
|
||||||
case GB_MBC1:
|
case GB_MBC1:
|
||||||
/* Standard MBC1 wiring: */
|
/* Todo: some obscure behaviors of MBC1 are not supported. See http://forums.nesdev.com/viewtopic.php?f=20&t=14099 */
|
||||||
if (gb->mbc1.mode == 0) {
|
if (gb->mbc1.mode == 0) {
|
||||||
gb->mbc_rom_bank = gb->mbc1.bank_low | (gb->mbc1.bank_high << 5);
|
switch (gb->mbc1_wiring) {
|
||||||
gb->mbc_ram_bank = 0;
|
case GB_STANDARD_MBC1_WIRING:
|
||||||
|
gb->mbc_rom_bank = gb->mbc1.bank_low | (gb->mbc1.bank_high << 5);
|
||||||
|
gb->mbc_ram_bank = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GB_MBC1M_WIRING:
|
||||||
|
gb->mbc_rom_bank = (gb->mbc1.bank_low & 0xF) | (gb->mbc1.bank_high << 4);
|
||||||
|
gb->mbc_ram_bank = 0;
|
||||||
|
gb->mbc_rom0_bank = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gb->mbc_rom_bank = gb->mbc1.bank_low;
|
switch (gb->mbc1_wiring) {
|
||||||
gb->mbc_ram_bank = gb->mbc1.bank_high;
|
case GB_STANDARD_MBC1_WIRING:
|
||||||
|
gb->mbc_rom_bank = gb->mbc1.bank_low;
|
||||||
|
gb->mbc_ram_bank = gb->mbc1.bank_high;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GB_MBC1M_WIRING:
|
||||||
|
gb->mbc_rom_bank = (gb->mbc1.bank_low & 0xF) | (gb->mbc1.bank_high << 4);
|
||||||
|
gb->mbc_rom0_bank = gb->mbc1.bank_high << 4;
|
||||||
|
gb->mbc_ram_bank = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GB_MBC2:
|
case GB_MBC2:
|
||||||
@ -75,4 +95,25 @@ void GB_update_mbc_mappings(GB_gameboy_t *gb)
|
|||||||
if (gb->mbc_rom_bank == 0 && gb->cartridge_type->mbc_type != GB_MBC5) {
|
if (gb->mbc_rom_bank == 0 && gb->cartridge_type->mbc_type != GB_MBC5) {
|
||||||
gb->mbc_rom_bank = 1;
|
gb->mbc_rom_bank = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_configure_cart(GB_gameboy_t *gb)
|
||||||
|
{
|
||||||
|
gb->cartridge_type = &GB_cart_defs[gb->rom[0x147]];
|
||||||
|
|
||||||
|
if (gb->cartridge_type->has_ram) {
|
||||||
|
static const int ram_sizes[256] = {0, 0x800, 0x2000, 0x8000, 0x20000, 0x10000};
|
||||||
|
gb->mbc_ram_size = ram_sizes[gb->rom[0x149]];
|
||||||
|
gb->mbc_ram = malloc(gb->mbc_ram_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MBC1 has at least 3 types of wiring (We currently support two (Standard and 4bit-MBC1M) of these).
|
||||||
|
See http://forums.nesdev.com/viewtopic.php?f=20&t=14099 */
|
||||||
|
|
||||||
|
/* Attempt to "guess" wiring */
|
||||||
|
if (gb->cartridge_type->mbc_type == GB_MBC1) {
|
||||||
|
if (gb->rom_size >= 0x44000 && memcmp(gb->rom + 0x104, gb->rom + 0x40104, 0x30) == 0) {
|
||||||
|
gb->mbc1_wiring = GB_MBC1M_WIRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,5 +4,5 @@
|
|||||||
|
|
||||||
extern const GB_cartridge_t GB_cart_defs[256];
|
extern const GB_cartridge_t GB_cart_defs[256];
|
||||||
void GB_update_mbc_mappings(GB_gameboy_t *gb);
|
void GB_update_mbc_mappings(GB_gameboy_t *gb);
|
||||||
|
void GB_configure_cart(GB_gameboy_t *gb);
|
||||||
#endif /* MBC_h */
|
#endif /* MBC_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user