mbc2 passing

This commit is contained in:
2025-05-30 12:30:54 -06:00
parent 26b1f10e16
commit 9f0715c825
2 changed files with 135 additions and 93 deletions

View File

@ -13,16 +13,24 @@ bool cart_mbc1() {
return BETWEEN(ctx.header->type, 1, 3);
}
bool cart_mbc2() {
return BETWEEN(ctx.header->type, 5, 6);
}
bool cart_mbc3() {
return BETWEEN(ctx.header->type, 15, 19);
}
bool cart_mbc5() {
return BETWEEN(ctx.header->type, 25, 30)
}
bool cart_mbc() {
return cart_mbc1() || cart_mbc3();
return cart_mbc1() || cart_mbc2() || cart_mbc3() || cart_mbc5();
}
bool cart_battery() {
return ctx.header->type == 3 || BETWEEN(ctx.header->type, 15, 16) || ctx.header->type == 19;
return ctx.header->type == 3 || BETWEEN(ctx.header->type, 15, 16) || ctx.header->type == 19 || ctx.header->type == 6;
}
static const char *ROM_TYPES[] = {
@ -160,6 +168,11 @@ void cart_setup_bamking() {
}
}
if(cart_mbc2()) {
ctx.ram_banks[0] = malloc(0x2000);
memset(ctx.ram_banks[0], 0, 0x2000);
}
ctx.ram_bank = ctx.ram_banks[0];
ctx.rom_bank_x = ctx.rom_data + 0x4000;
ctx.rom_bank_x2 = ctx.rom_data;
@ -286,6 +299,8 @@ u8 cart_read(u16 address){
}
if((address & 0xE000) == 0xA000) {
if(cart_mbc2())
address &= 0xE1FF;
if (!ctx.ram_enabled) {
return 0xFF;
}
@ -294,7 +309,7 @@ u8 cart_read(u16 address){
return 0xFF;
}
return ctx.ram_bank[address - 0xA000];
return cart_mbc2() ? ctx.ram_bank[address - 0xA000] | 0xF0 : ctx.ram_bank[address - 0xA000];
}
return ctx.rom_bank_x[address - 0x4000];
@ -307,95 +322,82 @@ void cart_write(u16 address, u8 value){
return;
}
if(address < 0x2000) {
ctx.ram_enabled = ((value & 0xF) == 0xA);
}
if((address & 0xE000) == 0x2000) {
//rom bank
if(cart_mbc3()) {
value &= 0b1111111;
if(value == 0) {
value = 1;
}
ctx.rom_bank_value = value;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
}else {
//printf("Bank Value: %d\n", value);
value &= 0b11111;
if(value == 0) {
value = 1;
}
if(ctx.is_multicart)
if(cart_mbc2()) {
if(address < 0x4000){
if(address & 0x100) {
value &= 0b1111;
//printf("Bank Value after filter: %d\n", value);
switch(ctx.header->rom_size) {
case 0: value &= 0b1; break;
case 1: value &= 0b11; break;
case 2: value &= 0b111; break;
case 3: value &= 0b1111; break;
default: break;
}
ctx.rom_bank_value = value;
if(ctx.header->rom_size >= 5) {
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
//printf("(REG1 >5) Banked %d\n", ctx.rom_bank_value+ctx.rom_bank_value_2);
return;
}
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
//printf("(REG1 <5) Banked %d\n", ctx.rom_bank_value);
}
}
if((address & 0xE000) == 0x4000) {
//ram bank number
if(cart_mbc1() && ctx.header->rom_size >= 5) {
if(ctx.header->rom_size == 5)
value &= 0b1;
ctx.rom_bank_value_2 = (value & 0b11) << 5;
if(ctx.is_multicart)
ctx.rom_bank_value_2 = (value & 0b11) << 4;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
//printf("(REG2 >5) Banked %d\n", ctx.rom_bank_value+ctx.rom_bank_value_2);
if(ctx.banking_mode)
ctx.rom_bank_x2 = ctx.rom_data + (0x4000 * (ctx.rom_bank_value_2));
return;
}
ctx.ram_bank_value = value & 0b11;
if(ctx.ram_banking) {
if(cart_need_save()) {
cart_battery_save();
}
if((ctx.header->ram_size == 2 && ctx.ram_bank_value == 0) ||
(ctx.header->ram_size == 3 && ctx.ram_bank_value < 4) ||
(ctx.header->ram_size == 5 && ctx.ram_bank_value < 8) ||
(ctx.header->ram_size == 4)) {
ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value];
}
}
}
if((address & 0xE000) == 0x6000) {
//banking mode select
if(cart_mbc1()){
ctx.banking_mode = value & 1;
ctx.ram_banking = ctx.banking_mode;
if(cart_mbc1() && ctx.header->rom_size >= 5) {
if(ctx.banking_mode) {
ctx.rom_bank_value_2 = (value & 0b11) << 5;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
ctx.rom_bank_x2 = ctx.rom_data + (0x4000 * (ctx.rom_bank_value_2));
} else {
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value));
ctx.rom_bank_x2 = ctx.rom_data;
if(value == 0) {
value = 1;
}
switch(ctx.header->rom_size) {
case 0: value &= 0b1; break;
case 1: value &= 0b11; break;
case 2: value &= 0b111; break;
default: break;
}
ctx.rom_bank_value = value;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
} else {
ctx.ram_enabled = ((value & 0xF) == 0xA);
}
}
} else {
if(address < 0x2000) {
ctx.ram_enabled = ((value & 0xF) == 0xA);
}
if((address & 0xE000) == 0x2000) {
//rom bank
if(cart_mbc3()) {
value &= 0b1111111;
if(value == 0) {
value = 1;
}
ctx.rom_bank_value = value;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
}else {
//printf("Bank Value: %d\n", value);
value &= 0b11111;
if(value == 0) {
value = 1;
}
if(ctx.is_multicart)
value &= 0b1111;
//printf("Bank Value after filter: %d\n", value);
switch(ctx.header->rom_size) {
case 0: value &= 0b1; break;
case 1: value &= 0b11; break;
case 2: value &= 0b111; break;
case 3: value &= 0b1111; break;
default: break;
}
ctx.rom_bank_value = value;
if(ctx.header->rom_size >= 5) {
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
//printf("(REG1 >5) Banked %d\n", ctx.rom_bank_value+ctx.rom_bank_value_2);
return;
}
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
//printf("(REG1 <5) Banked %d\n", ctx.rom_bank_value);
}
}
if((address & 0xE000) == 0x4000) {
//ram bank number
if(cart_mbc1() && ctx.header->rom_size >= 5) {
if(ctx.header->rom_size == 5)
value &= 0b1;
ctx.rom_bank_value_2 = (value & 0b11) << 5;
if(ctx.is_multicart)
ctx.rom_bank_value_2 = (value & 0b11) << 4;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
//printf("(REG2 >5) Banked %d\n", ctx.rom_bank_value+ctx.rom_bank_value_2);
if(ctx.banking_mode)
ctx.rom_bank_x2 = ctx.rom_data + (0x4000 * (ctx.rom_bank_value_2));
return;
}
if (ctx.ram_banking) {
ctx.ram_bank_value = value & 0b11;
if(ctx.ram_banking) {
if(cart_need_save()) {
cart_battery_save();
}
@ -405,20 +407,60 @@ void cart_write(u16 address, u8 value){
(ctx.header->ram_size == 4)) {
ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value];
}
} else {
ctx.ram_bank = ctx.ram_banks[0];
}
}
if((address & 0xE000) == 0x6000) {
//banking mode select
if(cart_mbc1()){
ctx.banking_mode = value & 1;
ctx.ram_banking = ctx.banking_mode;
if(cart_mbc1() && ctx.header->rom_size >= 5) {
if(ctx.banking_mode) {
ctx.rom_bank_value_2 = (value & 0b11) << 5;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2));
ctx.rom_bank_x2 = ctx.rom_data + (0x4000 * (ctx.rom_bank_value_2));
} else {
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value));
ctx.rom_bank_x2 = ctx.rom_data;
}
return;
}
if (ctx.ram_banking) {
if(cart_need_save()) {
cart_battery_save();
}
if((ctx.header->ram_size == 2 && ctx.ram_bank_value == 0) ||
(ctx.header->ram_size == 3 && ctx.ram_bank_value < 4) ||
(ctx.header->ram_size == 5 && ctx.ram_bank_value < 8) ||
(ctx.header->ram_size == 4)) {
ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value];
}
} else {
ctx.ram_bank = ctx.ram_banks[0];
}
}
}
}
if((address & 0xE000) == 0xA000) {
if(!ctx.ram_enabled)
if(cart_mbc2())
address &= 0xE1FF;
if(!ctx.ram_enabled){
return;
}
if(!ctx.ram_bank)
return;
ctx.ram_bank[address - 0xA000] = value;
ctx.ram_bank[address - 0xA000] = cart_mbc2() ? value & 0xF : value;
if(ctx.battery) {
ctx.need_save = true;