mbc2 passing
This commit is contained in:
226
lib/cart.c
226
lib/cart.c
@ -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;
|
||||
|
Reference in New Issue
Block a user