dma and mbc1 passing
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -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}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
74
lib/cart.c
74
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");
|
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,38 +313,66 @@ void cart_write(u16 address, u8 value){
|
|||||||
|
|
||||||
if((address & 0xE000) == 0x2000) {
|
if((address & 0xE000) == 0x2000) {
|
||||||
//rom bank
|
//rom bank
|
||||||
if(value == 0) {
|
|
||||||
value = 1;
|
|
||||||
}
|
|
||||||
if(cart_mbc3()) {
|
if(cart_mbc3()) {
|
||||||
value &= 0b1111111;
|
value &= 0b1111111;
|
||||||
|
if(value == 0) {
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
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));
|
||||||
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;
|
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();
|
||||||
}
|
}
|
||||||
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 (ctx.ram_banking) {
|
||||||
if(cart_need_save) {
|
if(cart_need_save()) {
|
||||||
cart_battery_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){
|
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.ram_banking = state->ram_banking;
|
||||||
ctx.banking_mode = state->banking_mode;
|
ctx.banking_mode = state->banking_mode;
|
||||||
ctx.rom_bank_value = state->rom_bank_value;
|
ctx.rom_bank_value = state->rom_bank_value;
|
||||||
|
14
lib/cpu.c
14
lib/cpu.c
@ -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
|
||||||
@ -54,10 +54,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;
|
||||||
@ -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();
|
||||||
|
@ -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++;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user