Im confused with apu and interrupts.
There are a couple of Blarrg's test that don't pass in my emu so im looking for help.
Please tell me if what i think is right:
1 - There are two flags: irq_inhibit flag and frame_interrupt flag
2 - When 0x40 is written to $4017 inihibit_flag is set to "1" and flrame_interrupt is cleared to "0". Otherwise inihibit_flag is cleared, but frame_interrupt flag is unchanged.
3 - On step 4 more or less of the 0x80 = 0 mode IF inihibit_flag is "0" frame_interrupt is set to "1" and IRQ line is asserted (irq_collector = 0)
4 - When $4015 is read it returns the state of frame_interrupt. IF SET -> data_to_return |= 0x40. AFTERWARDS it clears the frame_interrupt flag. AND AFTERWARDS all that IRQ is acknowledged (irq_collector = 1).
5 - On Power Up, according to the wiki $00 is written to $4017 so interrupt_inhibit is clear allowing IRQs.
What is wrong??
Apu and Interrupts
Moderator: Moderators
Apu and Interrupts
ANes
Re: Apu and Interrupts
What's the test ROM name?
Maybe it's more clear if you report the name and that fail number.
Maybe it's more clear if you report the name and that fail number.
Re: Apu and Interrupts
Well, it's not that easy and... so boolean. I remember of having a lot of trouble and hours of tracing my APU code in order to get the things working right. I had to add a cycle counter in order to clock the quarter/half frames correctly, thanks to the help of Q below.
7456 cycles after init, triggers quarter frame
14912 cycles after init, triggers quarter+half frames
22370 cycles after init, triggers quarter frame
mode 0 - 29828 cycles after init, triggers quarter+half frames, checks IRQ
29829 and 30 - checks IRQ
37280 cycles after init, triggers quarter+half frames
There's more on the wiki regarding $4017 register.
7456 cycles after init, triggers quarter frame
14912 cycles after init, triggers quarter+half frames
22370 cycles after init, triggers quarter frame
mode 0 - 29828 cycles after init, triggers quarter+half frames, checks IRQ
29829 and 30 - checks IRQ
37280 cycles after init, triggers quarter+half frames
There's more on the wiki regarding $4017 register.
Re: Apu and Interrupts
What do you mean with "29829 and 30" Zepper? I understand the other ones, but not that. Also i have read the wiki, but sometimes gets not to much understandable for me.Zepper wrote:7456 cycles after init, triggers quarter frame
14912 cycles after init, triggers quarter+half frames
22370 cycles after init, triggers quarter frame
mode 0 - 29828 cycles after init, triggers quarter+half frames, checks IRQ
29829 and 30 - checks IRQ
37280 cycles after init, triggers quarter+half frames
Boolean: The rom name is Blarrg's apu_reset set.
ANes
Re: Apu and Interrupts
It means
29829 - checks IRQ
29830 - checks IRQ
29829 - checks IRQ
29830 - checks IRQ
Re: Apu and Interrupts
Good info Zepper and Tepples. I could pass test "4017 timming".
I cannot pass $4017 re-written. I don't know what's wrong here, it seems a lame test to pass. Anyway this Blarrg's test ask me to reset 2 times and then the error "should me wrtten with last value written".
My ResetApu() routhine is very simple: it writes $0 to $4015 and the previous value in $4017 wich was stored in a variable.
My WriteApu() and $4017 write looks like this:
Something wrong there must be in this...
I cannot pass $4017 re-written. I don't know what's wrong here, it seems a lame test to pass. Anyway this Blarrg's test ask me to reset 2 times and then the error "should me wrtten with last value written".
My ResetApu() routhine is very simple: it writes $0 to $4015 and the previous value in $4017 wich was stored in a variable.
My WriteApu() and $4017 write looks like this:
Code: Select all
case 0x4017:
Apu.reg4017 = data; //this stores the previos value
Apu.seq_divider = 0; // reset sequencer divider as Blarrg's doc says
Apu.sequence = 0; // reset Frame Sequence again as Blarrg's says
if (Apu.reg4017 & 0x40)
{
Apu.irq_disable = 1; //irq inhibit flag set
}
else
{
Apu.irq_disable= 0; //irq inhibit flag clean
}
Apu.frame_interrupt = 0; //IM NOT SURE THIS OK
Apu.mode = Apu.reg4017 & 0x80; //Sets the mode
if (Apu.mode) If mode = 0x80 Clocks inmediatly quarter and half frames
{
ClockEnvelope(&Apu.Square.Env);
ClockEnvelope(&Apu.Square2.Env);
ClockEnvelope(&Apu.Noise.Env);
ClockLinearCounter();
ClockLenCounter(&Apu.Square.Len);
ClockLenCounter(&Apu.Square2.Len);
ClockLenCounter(&Apu.Triangle.Len);
ClockLenCounter(&Apu.Noise.Len);
ClockSweep(&Apu.Square.Sweep, &Apu.Square.PTimer, 0);
ClockSweep(&Apu.Square2.Sweep, &Apu.Square2.PTimer, 1);
}
break;
}
ANes
Re: Apu and Interrupts
Use a log file! Your first line of $4017 must be: fprintf(fp, "$4017 value: %02X (old_value: %02X)\n", value_written, old_value).
Log it and check what's up. Be sure the value is the same after the reset.
Log it and check what's up. Be sure the value is the same after the reset.