dma and mbc1 passing

This commit is contained in:
2025-05-30 11:15:21 -06:00
parent 1455bc5666
commit 26b1f10e16
7 changed files with 76 additions and 23 deletions

2
.vscode/launch.json vendored
View File

@ -9,7 +9,7 @@
"request": "launch", "request": "launch",
"name": "Debug", "name": "Debug",
"program": "${workspaceFolder}/build/gbemu/Debug/gbemu.exe", "program": "${workspaceFolder}/build/gbemu/Debug/gbemu.exe",
"args": [ "${workspaceFolder}/roms/cpu_instrs.gb" ], "args": [ "C:\\Users\\piwalker\\Downloads\\mts-20240926-1737-443f6e1\\mts-20240926-1737-443f6e1\\emulator-only\\mbc1\\rom_512kb.gb" ],
"cwd": "${workspaceFolder}" "cwd": "${workspaceFolder}"
} }
] ]

View File

@ -24,6 +24,7 @@ typedef struct {
u32 rom_size; u32 rom_size;
u8 *rom_data; u8 *rom_data;
rom_header *header; rom_header *header;
bool is_multicart;
//mbc1 data //mbc1 data
bool ram_enabled; bool ram_enabled;

View File

@ -81,6 +81,8 @@ void bus_write(u16 address, u8 value) {
//OAM //OAM
if(!dma_transferring()) if(!dma_transferring())
ppu_oam_write(address, value); ppu_oam_write(address, value);
else
printf("ACCESS DURING DMA!\n");
return; return;
} else if (address < 0xFF00) { } else if (address < 0xFF00) {
//reserved unusable //reserved unusable

View File

@ -250,6 +250,25 @@ bool cart_load(char *cart) {
fprintf(stderr, "WARNING!!! The header checksum does not match! ROM may be corrupt or invalid!\n"); fprintf(stderr, "WARNING!!! The header checksum does not match! ROM may be corrupt or invalid!\n");
} }
if(cart_mbc1() && ctx.header->rom_size >= 5) {
int count = 0;
for(int i = 1; i < 4; i++) {
u32 start_addr = (i << 18);
bool same = true;
for(int j = 0x104; j < 0x134; j++) {
if(ctx.rom_data[start_addr | j] != ctx.rom_data[j]) {
same = false;
break;
}
}
if(same)
count++;
}
if(count >= 2) {
ctx.is_multicart = true;
}
}
if(ctx.battery) { if(ctx.battery) {
cart_battery_load(); cart_battery_load();
} }
@ -294,39 +313,67 @@ void cart_write(u16 address, u8 value){
if((address & 0xE000) == 0x2000) { if((address & 0xE000) == 0x2000) {
//rom bank //rom bank
if(cart_mbc3()) {
value &= 0b1111111;
if(value == 0) { if(value == 0) {
value = 1; value = 1;
} }
if(cart_mbc3()) {
value &= 0b1111111;
ctx.rom_bank_value = value; ctx.rom_bank_value = value;
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value); ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value);
}else { }else {
//printf("Bank Value: %d\n", value);
value &= 0b11111; 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; ctx.rom_bank_value = value;
if(ctx.header->rom_size >= 5) { if(ctx.header->rom_size >= 5) {
ctx.rom_bank_x = ctx.rom_data + (0x4000 * (ctx.rom_bank_value+ctx.rom_bank_value_2)); 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; return;
} }
ctx.rom_bank_x = ctx.rom_data + (0x4000 * ctx.rom_bank_value); 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) { if((address & 0xE000) == 0x4000) {
//ram bank number //ram bank number
if(cart_mbc1() && ctx.banking_mode && ctx.header->rom_size >= 5) { if(cart_mbc1() && ctx.header->rom_size >= 5) {
if(ctx.header->rom_size == 5)
value &= 0b1;
ctx.rom_bank_value_2 = (value & 0b11) << 5; 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)); 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)); ctx.rom_bank_x2 = ctx.rom_data + (0x4000 * (ctx.rom_bank_value_2));
return; return;
} }
ctx.ram_bank_value = value & 0b11; ctx.ram_bank_value = value & 0b11;
if(ctx.ram_banking) { if(ctx.ram_banking) {
if(cart_need_save) { if(cart_need_save()) {
cart_battery_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]; ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value];
} }
}
} }
if((address & 0xE000) == 0x6000) { if((address & 0xE000) == 0x6000) {
@ -349,11 +396,18 @@ void cart_write(u16 address, u8 value){
} }
if (ctx.ram_banking) { if (ctx.ram_banking) {
if(cart_need_save) { if(cart_need_save()) {
cart_battery_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]; ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value];
} }
} else {
ctx.ram_bank = ctx.ram_banks[0];
}
} }
} }

View File

@ -8,7 +8,7 @@
#include <memory.h> #include <memory.h>
cpu_context ctx = {0}; cpu_context ctx = {0};
#define CPU_DEBUG 0 #define CPU_DEBUG 1
#define FILE_LOG 0 #define FILE_LOG 0
#if FILE_LOG == 1 #if FILE_LOG == 1
@ -55,10 +55,6 @@ static void execute() {
bool cpu_step() { bool cpu_step() {
if(ctx.regs.pc == 0x4348) {
printf("made it!\n");
}
if(!ctx.halted) { if(!ctx.halted) {
u16 pc = ctx.regs.pc; u16 pc = ctx.regs.pc;
fetch_instruction(); fetch_instruction();
@ -81,15 +77,15 @@ bool cpu_step() {
char inst[16]; char inst[16];
inst_to_str(&ctx, inst); inst_to_str(&ctx, inst);
//printf("%-12s\n", inst);
printf("%08lX - %04X: %-12s (%02X %02X %02X) A: %02X F: %s BC: %02X%02X DE: %02X%02X HL: %02X%02X SP: %04X PC: %04X\n", emu_get_context()->ticks, pc, inst, ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, flags, ctx.regs.b, ctx.regs.c, ctx.regs.d, ctx.regs.e, ctx.regs.h, ctx.regs.l, ctx.regs.sp, ctx.regs.pc); //printf("%08lX - %04X: %-12s (%02X %02X %02X) A: %02X F: %s BC: %02X%02X DE: %02X%02X HL: %02X%02X SP: %04X PC: %04X\n", emu_get_context()->ticks, pc, inst, ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, flags, ctx.regs.b, ctx.regs.c, ctx.regs.d, ctx.regs.e, ctx.regs.h, ctx.regs.l, ctx.regs.sp, ctx.regs.pc);
if(ctx.cur_inst == NULL){ if(ctx.cur_inst == NULL){
printf("Unknown Instruction! %02X\n", ctx.cur_opcode); printf("Unknown Instruction! %02X\n", ctx.cur_opcode);
exit(-7); exit(-7);
} }
dbg_update(); //dbg_update();
dbg_print(); //dbg_print();
#endif #endif
execute(); execute();

View File

@ -7,7 +7,7 @@ static dma_context ctx;
void dma_start(u8 start) { void dma_start(u8 start) {
ctx.active = true; ctx.active = true;
ctx.byte = 0; ctx.byte = 0;
ctx.start_delay = 2; ctx.start_delay = 0;
ctx.value = start; ctx.value = start;
} }
@ -21,7 +21,7 @@ void dma_tick() {
return; return;
} }
ppu_oam_write(ctx.byte, bus_read(((ctx.value << 8)) + ctx.byte)); ppu_oam_write(ctx.byte, bus_read((ctx.value << 8) | ctx.byte));
ctx.byte++; ctx.byte++;

View File

@ -70,7 +70,7 @@ void ppu_oam_write(u16 address, u8 value) {
} }
u8 ppu_oam_read(u16 address){ u8 ppu_oam_read(u16 address){
if (address > 0xFE00) { if (address >= 0xFE00) {
address -= 0xFE00; address -= 0xFE00;
} }