From 1f55455a6545010d361dbd28543ac2ef6cae8422 Mon Sep 17 00:00:00 2001 From: Samuel Walker Date: Fri, 30 May 2025 00:35:44 -0600 Subject: [PATCH] working on mooneye test suite --- include/timer.h | 2 ++ lib/cpu.c | 6 +++- lib/cpu_fetch.c | 4 ++- lib/cpu_proc.c | 31 +++++++++++--------- lib/interrupts.c | 12 ++++---- lib/io.c | 2 +- lib/timer.c | 74 ++++++++++++++++++++++++++++++++++-------------- 7 files changed, 87 insertions(+), 44 deletions(-) diff --git a/include/timer.h b/include/timer.h index 34640e7..8b3a9b2 100644 --- a/include/timer.h +++ b/include/timer.h @@ -7,6 +7,8 @@ typedef struct { u8 tima; u8 tma; u8 tac; + bool tima_needs_reset; + bool tima_just_reset; } timer_context; typedef struct { diff --git a/lib/cpu.c b/lib/cpu.c index 188a6ad..27d30c6 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -18,7 +18,7 @@ FILE *log; void cpu_init() { ctx.regs.a = 0x01; ctx.regs.f = 0xB0; - ctx.regs.b = 0x00; + ctx.regs.b = 0x19; ctx.regs.c = 0x13; ctx.regs.d = 0x00; ctx.regs.e = 0xD8; @@ -54,6 +54,10 @@ static void execute() { } bool cpu_step() { + + if(ctx.regs.pc == 0x4348) { + printf("made it!\n"); + } if(!ctx.halted) { u16 pc = ctx.regs.pc; diff --git a/lib/cpu_fetch.c b/lib/cpu_fetch.c index c52f146..101bd40 100644 --- a/lib/cpu_fetch.c +++ b/lib/cpu_fetch.c @@ -74,7 +74,9 @@ void fetch_data() { cpu_set_reg(RT_HL, cpu_read_reg(RT_HL)-1); return; case AM_R_A8: - ctx.fetched_data = bus_read(ctx.regs.pc); + u16 addr = bus_read(ctx.regs.pc) | 0xFF00; + emu_cycles(1); + ctx.fetched_data = bus_read(addr); emu_cycles(1); ctx.regs.pc++; return; diff --git a/lib/cpu_proc.c b/lib/cpu_proc.c index 0b435d3..a299c78 100644 --- a/lib/cpu_proc.c +++ b/lib/cpu_proc.c @@ -2,6 +2,7 @@ #include #include #include +#include reg_type decode_reg(u8 reg); @@ -51,7 +52,7 @@ static void proc_daa(cpu_context *ctx) { ctx->regs.a += CPU_FLAG_N ? -u : u; - cpu_set_flags(ctx, ctx->regs.a == 0, -1, 0, fc); + cpu_set_flags(ctx, ctx->regs.a == 0, CPU_FLAG_N, 0, fc); } static void proc_cpl(cpu_context *ctx) { @@ -72,6 +73,7 @@ static void proc_halt(cpu_context *ctx) { } static void proc_stop(cpu_context *ctx) { + timer_get_context()->div = 0; printf("CPU STOP!\n"); } @@ -303,10 +305,6 @@ static void proc_add(cpu_context *ctx) { bool is_16bit = is_16_bit(ctx->cur_inst->reg_1); - if(is_16bit) { - emu_cycles(1); - } - if(ctx->cur_inst->reg_1 == RT_SP) { val = cpu_read_reg(ctx->cur_inst->reg_1) + (char)ctx->fetched_data; } @@ -329,6 +327,12 @@ static void proc_add(cpu_context *ctx) { } cpu_set_reg(ctx->cur_inst->reg_1, val & 0xFFFF); + if(is_16bit) { + emu_cycles(1); + } + if(ctx->cur_inst->reg_1 == RT_SP) { + emu_cycles(1); + } cpu_set_flags(ctx, z, 0, h, c); } @@ -358,10 +362,6 @@ static void proc_inc(cpu_context *ctx) { static void proc_dec(cpu_context *ctx) { u16 val = cpu_read_reg(ctx->cur_inst->reg_1) - 1; - if(is_16_bit(ctx->cur_inst->reg_1)) { - //emu_cycles(1); - } - if (ctx->cur_inst->reg_1 == RT_HL && ctx->dest_is_mem) { val = ctx->fetched_data - 1; val &= 0xFF; @@ -371,6 +371,10 @@ static void proc_dec(cpu_context *ctx) { val = cpu_read_reg(ctx->cur_inst->reg_1); } + if(is_16_bit(ctx->cur_inst->reg_1)) { + emu_cycles(1); + } + if((ctx->cur_opcode & 0x0B) == 0x0B) { return; } @@ -394,21 +398,20 @@ static void proc_pop(cpu_context *ctx) { static void proc_push(cpu_context *ctx) { u16 val = cpu_read_reg(ctx->cur_inst->reg_1); + emu_cycles(1); stack_push((val >> 8) & 0xFF); emu_cycles(1); stack_push((val & 0xFF)); emu_cycles(1); - - emu_cycles(1); } static void proc_ldh(cpu_context *ctx) { if (!ctx->dest_is_mem) { - cpu_set_reg(ctx->cur_inst->reg_1, bus_read(0XFF00 | ctx->fetched_data)); + cpu_set_reg(ctx->cur_inst->reg_1, ctx->fetched_data); } else { bus_write(0xFF00 | ctx->mem_dest, cpu_read_reg(ctx->cur_inst->reg_2)); + emu_cycles(1); } - emu_cycles(1); } static void proc_di(cpu_context *ctx) { @@ -458,12 +461,12 @@ static bool check_condition(cpu_context *ctx) { static void goto_addr(cpu_context *ctx, u16 addr, bool pushpc){ if (check_condition(ctx)) { + emu_cycles(1); if(pushpc) { stack_push16(ctx->regs.pc); emu_cycles(2); } ctx->regs.pc = addr; - emu_cycles(1); } } diff --git a/lib/interrupts.c b/lib/interrupts.c index 6d37940..0c8737b 100644 --- a/lib/interrupts.c +++ b/lib/interrupts.c @@ -7,7 +7,7 @@ void int_handle(cpu_context *ctx, u16 address) { stack_push16(ctx->regs.pc); emu_cycles(2); ctx->regs.pc = address; - emu_cycles(1); + //emu_cycles(1); } bool int_check(cpu_context *ctx, u16 address, interrupt_type t){ @@ -25,14 +25,14 @@ void cpu_request_interrupt(interrupt_type t); void cpu_handle_interrupts(cpu_context *ctx) { if (int_check(ctx, 0x40, IT_VBLANK)) { - + //printf("VBLANK!\n"); } else if(int_check(ctx, 0x48, IT_LCD_STAT)){ - + //printf("LCD!\n"); } else if(int_check(ctx, 0x50, IT_TIMER)){ - + //printf("TIMER!\n"); } else if(int_check(ctx, 0x58, IT_SERIAL)){ - + //printf("Serial!\n"); } else if(int_check(ctx, 0x60, IT_JOYPAD)){ - + //printf("Joy!\n"); } } \ No newline at end of file diff --git a/lib/io.c b/lib/io.c index f6c9beb..eb13764 100644 --- a/lib/io.c +++ b/lib/io.c @@ -37,7 +37,7 @@ u8 io_read(u16 address){ } printf("UNSUPPORTED io_read(%04X)\n", address); - return 0; + return 0xFF; } diff --git a/lib/timer.c b/lib/timer.c index 79d5d70..eb0dd10 100644 --- a/lib/timer.c +++ b/lib/timer.c @@ -5,40 +5,58 @@ static timer_context ctx = {0}; +bool selected_bit() { + switch(ctx.tac & 0b11) { + case 0b00: + return (ctx.div & (1 << 9)); + break; + + case 0b01: + return (ctx.div & (1 << 3)); + break; + + case 0b10: + return (ctx.div & (1 << 5)); + break; + + case 0b11: + return (ctx.div & (1 << 7)); + break; + } +} + +void inc_tima() { + ctx.tima++; + if(ctx.tima == 0x00){ + ctx.tima_needs_reset = true; + } +} + void timer_init() { ctx.div = 0XAC00; } void timer_tick() { u16 prev_div = ctx.div; + bool old = selected_bit(); ctx.div++; - bool timer_update = false; - switch(ctx.tac & 0b11) { - case 0b00: - timer_update = (prev_div & (1 << 9)) && (!(ctx.div & (1 << 9))); - break; + bool new = selected_bit(); - case 0b01: - timer_update = (prev_div & (1 << 3)) && (!(ctx.div & (1 << 3))); - break; - - case 0b10: - timer_update = (prev_div & (1 << 5)) && (!(ctx.div & (1 << 5))); - break; - - case 0b11: - timer_update = (prev_div & (1 << 7)) && (!(ctx.div & (1 << 7))); - break; - } - - if(timer_update && ctx.tac & (1 << 2)) { - ctx.tima++; - if(ctx.tima == 0xFF){ + if((prev_div & (1 << 1)) && (!(ctx.div & (1 << 1)))){ + if(ctx.tima_just_reset) + ctx.tima_just_reset = false; + if(ctx.tima_needs_reset){ ctx.tima = ctx.tma; + ctx.tima_needs_reset = false; + ctx.tima_just_reset = true; cpu_request_interrupt(IT_TIMER); } } + if(ctx.tac & 0b100 && old && !new) { + inc_tima(); + } + audio_sample_tick(); if((prev_div & (1 << 12)) && (!(ctx.div & (1 << 12)))){ @@ -54,22 +72,36 @@ void timer_write(u16 address, u8 value){ switch(address) { case 0xFF04: //DIV + if(selected_bit()) { + inc_tima(); + } ctx.div = 0; break; case 0xFF05: //TIMA + if(ctx.tima_just_reset) + return; + ctx.tima_needs_reset = false; ctx.tima = value; break; case 0xFF06: //TMA + if(ctx.tima_just_reset) + ctx.tima = value; ctx.tma = value; break; case 0xFF07: //TAC + bool current = selected_bit(); + bool old_enable = ctx.tac & 0b100; ctx.tac = value; + bool new = selected_bit(); + if(((current && !new) && (ctx.tac & 0b100)) || (current && old_enable && !(ctx.tac & 0b100))) { + inc_tima(); + } break; } }