working on mooneye test suite
This commit is contained in:
@ -7,6 +7,8 @@ typedef struct {
|
||||
u8 tima;
|
||||
u8 tma;
|
||||
u8 tac;
|
||||
bool tima_needs_reset;
|
||||
bool tima_just_reset;
|
||||
} timer_context;
|
||||
|
||||
typedef struct {
|
||||
|
@ -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;
|
||||
@ -55,6 +55,10 @@ static void execute() {
|
||||
|
||||
bool cpu_step() {
|
||||
|
||||
if(ctx.regs.pc == 0x4348) {
|
||||
printf("made it!\n");
|
||||
}
|
||||
|
||||
if(!ctx.halted) {
|
||||
u16 pc = ctx.regs.pc;
|
||||
fetch_instruction();
|
||||
|
@ -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;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <emu.h>
|
||||
#include <bus.h>
|
||||
#include <stack.h>
|
||||
#include <timer.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
2
lib/io.c
2
lib/io.c
@ -37,7 +37,7 @@ u8 io_read(u16 address){
|
||||
}
|
||||
|
||||
printf("UNSUPPORTED io_read(%04X)\n", address);
|
||||
return 0;
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
|
74
lib/timer.c
74
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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user