working on mooneye test suite
This commit is contained in:
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