From 26b1f10e1675c25b8de57bfe73b3d9c430d7fb29 Mon Sep 17 00:00:00 2001 From: Samuel Walker Date: Fri, 30 May 2025 11:15:21 -0600 Subject: [PATCH] dma and mbc1 passing --- .vscode/launch.json | 2 +- include/cart.h | 1 + lib/bus.c | 2 ++ lib/cart.c | 74 +++++++++++++++++++++++++++++++++++++++------ lib/cpu.c | 14 +++------ lib/dma.c | 4 +-- lib/ppu.c | 2 +- 7 files changed, 76 insertions(+), 23 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9bf4f7e..2cb39d5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "request": "launch", "name": "Debug", "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}" } ] diff --git a/include/cart.h b/include/cart.h index 245c30f..5818b55 100644 --- a/include/cart.h +++ b/include/cart.h @@ -24,6 +24,7 @@ typedef struct { u32 rom_size; u8 *rom_data; rom_header *header; + bool is_multicart; //mbc1 data bool ram_enabled; diff --git a/lib/bus.c b/lib/bus.c index 2043b8d..e7c136a 100644 --- a/lib/bus.c +++ b/lib/bus.c @@ -81,6 +81,8 @@ void bus_write(u16 address, u8 value) { //OAM if(!dma_transferring()) ppu_oam_write(address, value); + else + printf("ACCESS DURING DMA!\n"); return; } else if (address < 0xFF00) { //reserved unusable diff --git a/lib/cart.c b/lib/cart.c index 12c46d2..41e973f 100644 --- a/lib/cart.c +++ b/lib/cart.c @@ -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"); } + 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) { cart_battery_load(); } @@ -294,38 +313,66 @@ void cart_write(u16 address, u8 value){ if((address & 0xE000) == 0x2000) { //rom bank - if(value == 0) { - value = 1; - } 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.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; + 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_x2 = ctx.rom_data + (0x4000 * (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) { + if(cart_need_save()) { cart_battery_save(); } - ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value]; + 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]; + } + } } @@ -349,10 +396,17 @@ void cart_write(u16 address, u8 value){ } if (ctx.ram_banking) { - if(cart_need_save) { + if(cart_need_save()) { cart_battery_save(); } - ctx.ram_bank = ctx.ram_banks[ctx.ram_bank_value]; + 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]; } } } @@ -411,7 +465,7 @@ u8 cart_get_rom_bank() { } void cart_load_state(const cart_state* state){ - ctx.ram_enabled = state->ram_enabled; + ctx.ram_enabled = state->ram_enabled; ctx.ram_banking = state->ram_banking; ctx.banking_mode = state->banking_mode; ctx.rom_bank_value = state->rom_bank_value; diff --git a/lib/cpu.c b/lib/cpu.c index 27d30c6..ffc24f6 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -8,7 +8,7 @@ #include cpu_context ctx = {0}; -#define CPU_DEBUG 0 +#define CPU_DEBUG 1 #define FILE_LOG 0 #if FILE_LOG == 1 @@ -54,10 +54,6 @@ static void execute() { } bool cpu_step() { - - if(ctx.regs.pc == 0x4348) { - printf("made it!\n"); - } if(!ctx.halted) { u16 pc = ctx.regs.pc; @@ -81,15 +77,15 @@ bool cpu_step() { char inst[16]; inst_to_str(&ctx, 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("%-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); if(ctx.cur_inst == NULL){ printf("Unknown Instruction! %02X\n", ctx.cur_opcode); exit(-7); } - dbg_update(); - dbg_print(); + //dbg_update(); + //dbg_print(); #endif execute(); diff --git a/lib/dma.c b/lib/dma.c index 5906434..b8da838 100644 --- a/lib/dma.c +++ b/lib/dma.c @@ -7,7 +7,7 @@ static dma_context ctx; void dma_start(u8 start) { ctx.active = true; ctx.byte = 0; - ctx.start_delay = 2; + ctx.start_delay = 0; ctx.value = start; } @@ -21,7 +21,7 @@ void dma_tick() { 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++; diff --git a/lib/ppu.c b/lib/ppu.c index c2c72fe..b1f2d76 100644 --- a/lib/ppu.c +++ b/lib/ppu.c @@ -70,7 +70,7 @@ void ppu_oam_write(u16 address, u8 value) { } u8 ppu_oam_read(u16 address){ - if (address > 0xFE00) { + if (address >= 0xFE00) { address -= 0xFE00; }