Page 1 of 1
Apu and Interrupts
Posted: Mon Aug 04, 2014 11:04 pm
by Anes
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??
Re: Apu and Interrupts
Posted: Sun Aug 10, 2014 2:41 am
by Anes
no help?? C'mon!!
Re: Apu and Interrupts
Posted: Sun Aug 10, 2014 9:42 am
by Boolean
What's the test ROM name?
Maybe it's more clear if you report the name and that fail number.
Re: Apu and Interrupts
Posted: Sun Aug 10, 2014 9:45 am
by Zepper
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.
Re: Apu and Interrupts
Posted: Sun Aug 10, 2014 1:29 pm
by Anes
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
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.
Boolean: The rom name is Blarrg's apu_reset set.
Re: Apu and Interrupts
Posted: Sun Aug 10, 2014 2:25 pm
by tepples
It means
29829 - checks IRQ
29830 - checks IRQ
Re: Apu and Interrupts
Posted: Mon Aug 11, 2014 1:44 am
by Anes
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:
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;
}
Something wrong there must be in this...
Re: Apu and Interrupts
Posted: Mon Aug 11, 2014 5:07 am
by Zepper
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.