Apu and Interrupts

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Apu and Interrupts

Post 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??
ANes
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Apu and Interrupts

Post by Anes »

no help?? C'mon!!
ANes
Boolean
Posts: 87
Joined: Thu Jan 02, 2014 7:58 am

Re: Apu and Interrupts

Post by Boolean »

What's the test ROM name?
Maybe it's more clear if you report the name and that fail number.
User avatar
Zepper
Formerly Fx3
Posts: 3264
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Apu and Interrupts

Post 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.
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Apu and Interrupts

Post 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.
ANes
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Apu and Interrupts

Post by tepples »

It means
29829 - checks IRQ
29830 - checks IRQ
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Apu and Interrupts

Post 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...
ANes
User avatar
Zepper
Formerly Fx3
Posts: 3264
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Apu and Interrupts

Post 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.
Post Reply