Trying to get FME-7 IRQs right

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Trying to get FME-7 IRQs right

Post by tepples » Fri Feb 27, 2015 3:02 pm

I made a full-screen text renderer that uses the FME-7 mapper to switch CHR banks. I need FME-7 because it's one of the few mappers supporting more than 8K of SRAM at $6000. The text looks fine in FCEUX and on my PowerPak. But it's a smear of flickering crap in Mednafen, and I'm told it looks similar in Nestopia. I can't debug why because Nestopia has no debugger and I can't seem to understand the manual for Mednafen's. Nor can I tell whether the problem is in the emulators or in my program because I lack an FME-7 devcart. So what should I try next?

I start the first timer period at the start of the NMI handler. Because the FME-7's timer has a fixed reload value of $FFFF, instead of a configurable period value like the MMC3's timer, I have to make later periods a multiple of 256 CPU cycles so that I can write only the high period byte.

Is anyone willing to test this on a modded FME-7 cart? No licensed FME-7 game includes CHR RAM, but if you want, I can make an equivalent demo that uses CHR ROM.


EDIT: In #nesdev, Myask told me that Mednafen's debugger doesn't display properly below 3x scale. My laptop's display can handle only up to 2x.
Attachments
vwfterm.nes
Test ROM
(32.02 KiB) Downloaded 732 times
Intended appearance
Intended appearance
in_fceux.png (4.73 KiB) Viewed 17189 times

lidnariq
Posts: 8780
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Trying to get FME-7 IRQs right

Post by lidnariq » Fri Feb 27, 2015 3:57 pm

The only obvious difference to me between FCEUX's and Nestopia's IRQ implementation is that FCEUX acknowledges the interrupt[1] when code writes any value to the three IRQ registes, but Nestopia's doesn't[2].

[1]:

Code: Select all

	case 0xD: IRQa = V; X6502_IRQEnd(FCEU_IQEXT); break;
	case 0xE: IRQCount &= 0xFF00; IRQCount |= V; X6502_IRQEnd(FCEU_IQEXT); break;
	case 0xF: IRQCount &= 0x00FF; IRQCount |= V << 8; X6502_IRQEnd(FCEU_IQEXT); break;
[2]:

Code: Select all

						case 0xD:

							irq.Update();
							irq.unit.enabled = data & 0x01;

							if (!irq.Connect( data & 0x80 ))
								irq.ClearIRQ();

							break;

						case 0xE:

							irq.Update();
							irq.unit.count = (irq.unit.count & 0xFF00) | data << 0;
							break;

						case 0xF:

							irq.Update();
							irq.unit.count = (irq.unit.count & 0x00FF) | data << 8;
							break;

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Trying to get FME-7 IRQs right

Post by tepples » Fri Feb 27, 2015 5:43 pm

Thanks for finding the relevant source code.

I've been acknowledging IRQ by writing $80 then $81 to reg $0D. Based on my understanding of the wiki, bit 7 is "count" and bit 0 is "generate IRQs", and turning IRQ generation off and back on will acknowledge IRQ. It looks like in Nestopia, you have to stop the counting (write $00 then $81). That'd effectively extend each IRQ period by 6 cycles, making the usable periods 256*n + 6 cycles. I've added a demo that uses this 256*n + 6 technique. The new demo works in Mednafen and Nestopia. Both work on the PowerPak.

Anyone want to help try a few tests for me on Sunsoft silicon?
Attachments
vwfterm-nestopia.nes
256*n+6 technique scrolling
(32.02 KiB) Downloaded 748 times

User avatar
Zepper
Formerly Fx3
Posts: 3190
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Trying to get FME-7 IRQs right

Post by Zepper » Sat Feb 28, 2015 7:47 am

@tepples
Did you use unofficial opcodes? An unofficial opcode $CB was trapped at PC=$E4A9!
Plus, it uses CHR RAM but still writes for CHR ROM swaps. Why?

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Trying to get FME-7 IRQs right

Post by tepples » Sat Feb 28, 2015 7:59 am

Zepper wrote:Did you use unofficial opcodes? An unofficial opcode $CB was trapped at PC=$E4A9!
Yes. AXS #ii is the only unofficial opcode that I regularly use at the moment, and even then only in specific to the NES PPU.
Plus, it uses CHR RAM but still writes for CHR ROM swaps. Why?
It swaps banks of CHR RAM to allow use of more than 256 distinct tiles on the screen.

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Trying to get FME-7 IRQs right

Post by koitsu » Sat Feb 28, 2015 3:32 pm

tepples wrote:
Zepper wrote:Did you use unofficial opcodes? An unofficial opcode $CB was trapped at PC=$E4A9!
Yes. AXS #ii is the only unofficial opcode that I regularly use at the moment, and even then only in specific to the NES PPU.
Why are you doing this? Did you just not witness a reason not to?

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Trying to get FME-7 IRQs right

Post by tepples » Sat Feb 28, 2015 4:26 pm

To save 16 cycles during vblank.

To eliminate unofficial opcodes as a factor in the test, I have added a second build-time option called AVOID_UNOFFICIAL_OPCODES, in addition to the existing build-time option called NESTOPIA_WORKAROUND, and built two more ROMs without unofficial opcodes, one with and one without the Nestopia workarounds. The ROMs built without unofficial opcodes behave (or misbehave) the same way in Mednafen as the corresponding ROMs with unofficial opcodes.
Attachments
official_only.zip
(4.15 KiB) Downloaded 751 times

User avatar
tokumaru
Posts: 11466
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Trying to get FME-7 IRQs right

Post by tokumaru » Sat Feb 28, 2015 5:18 pm

koitsu wrote:Why are you doing this? Did you just not witness a reason not to?
What reason? Emulator inaccuracies?

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Trying to get FME-7 IRQs right

Post by koitsu » Sat Feb 28, 2015 5:34 pm

Reason is in the quoted material, and that isn't "emulator inaccuracy".

Bottom line: if you want to be as compatible as possible (I am not referring to just emulators -- what makes you think NES-on-a-chip implements said opcodes, or any other non-Nintendo-sanctioned device?) then don't use undocumented opcodes. (And I will not tolerate splitting hairs over the use of the word "undocumented" vs. "unofficial" -- you know what I mean).

Same general advice applies to some PPU features as well (e.g. emphasis bits).

I classify use of undocument opcodes the equivalent of "hipster focus". Stop trying to show off/screw around and just write shit that you know is going to work universally. Come on -- deep down inside you know what you're doing is silly.

User avatar
tokumaru
Posts: 11466
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Trying to get FME-7 IRQs right

Post by tokumaru » Sat Feb 28, 2015 6:13 pm

koitsu wrote:I classify use of undocument opcodes the equivalent of "hipster focus". Stop trying to show off/screw around and just write shit that you know is going to work universally. Come on -- deep down inside you know what you're doing is silly.
I would say that using these opcodes is justifiable if they allow you to do something concrete that wouldn't be possible without them. On the NES that would be almost never in an actual game, but a realtime 3D demo for example could get a decent frame rate boost by making any part of the rendering pipeline faster.

On the Atari 2600, where you only have a measly 76 cycles per scanline and a primitive video system with memory for less then 1 scanline, unofficial opcodes could mean more colorful/detailed players and backgrounds. In that case, I consider unofficial opcodes more than welcome, otherwise I agree that it just looks like people are showing off.

My point is that I find it OK to risk sacrificing compatibility if the alternative is sacrificing an interesting feature. At the same time, I think that if you're copying an NES, your product should be able to do what an NES does if you want to call it accurate. If you want to skip implementing such obscure details, like many people do when few games rely on such details, that's fine, each project has its scope and limitations, but there's no denying that this is an inaccuracy.

User avatar
rainwarrior
Posts: 7672
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Trying to get FME-7 IRQs right

Post by rainwarrior » Sat Feb 28, 2015 6:57 pm

Reasons to use illegal opcodes:

1. It's "fun".
2. It breaks on low quality emulators, encouraging them to improve.
3. It saves cycles.

Reasons to avoid illegal opcodes:

4. It breaks on low quality emulators, discouraging people from using your software.


If you don't care much who uses your software, reason 4 could be irrelevant, leaving you with no reason not to use them. I think reason 3 is usually irrelevant as well; the cycle savings aren't normally meaningful, though they could be in the right situation. I suspect Tepples is motivated by 1, finding it fun to try out an obscure feature, and by 2, and if you don't have a financial stake in your software it's not as much a problem if you don't care about 4. You have to care about the popularity of your software for 4 to be important.

For a test like this which is explicitly about improving emulation knowledge (the whole point is finding incompatibilities and learning from them), it doesn't seem to me that reason 4 is relevant at all.
Last edited by rainwarrior on Sat Feb 28, 2015 7:12 pm, edited 1 time in total.

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Trying to get FME-7 IRQs right

Post by tepples » Sat Feb 28, 2015 7:11 pm

Here's another test specifically for the acknowledgment behaviors I'm seeing. No unofficial opcodes.

The demo tries to acknowledge the interrupt in one of six ways:
  • Writing value of $00, $01, $80, or $81 to register $0D
  • Writing value of $FF to register $0E or $0F
These are the results I get:
  • FCEUX: all Acked
  • Mednafen: 0D=00 and 0D=01 Acked; others No ack
  • PowerPak: 0D=00 and 0D=80 Acked; others No ack
EDIT: I mentioned it on #nesdev.
  • tpw_rules tried it on Everdrive and got the same result as PowerPak
Attachments
fme7acktest-r1.zip
(19.94 KiB) Downloaded 1170 times
powerpakresult.jpg

User avatar
l_oliveira
Posts: 404
Joined: Wed Jul 13, 2011 6:51 am
Location: Brasilia, Brazil

Re: Trying to get FME-7 IRQs right

Post by l_oliveira » Sat Feb 28, 2015 7:42 pm

tepples wrote:Here's another test specifically for the acknowledgment behaviors I'm seeing. No unofficial opcodes.

The demo tries to acknowledge the interrupt in one of six ways:
  • Writing value of $00, $01, $80, or $81 to register $0D
  • Writing value of $FF to register $0E or $0F
These are the results I get:
  • FCEUX: all Acked
  • Mednafen: 0D=00 and 0D=01 Acked; others No ack
  • PowerPak: 0D=00 and 0D=80 Acked; others No ack
EDIT: I mentioned it on #nesdev.
  • tpw_rules tried it on Everdrive and got the same result as PowerPak
Image

User avatar
Myask
Posts: 965
Joined: Sat Jul 12, 2014 3:04 pm

Re: Trying to get FME-7 IRQs right

Post by Myask » Sat Feb 28, 2015 8:56 pm

clarification for posterity: Mednafen's debugging console is 640x480, (at least in NES mode, haven't tried others). x2 scaling for NES on default settings (top/bottom 8 scanlines hidden) is 512x448.

Thus, (2.5, 2) scaling minimum with all scanlines displayed.
Attachments
MednafenTooSmall.png

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Trying to get FME-7 IRQs right

Post by tepples » Sat Feb 28, 2015 9:41 pm

Thanks for the confirmation, l_oliveira.

In #nesdev, Quietust confirmed that he'll be implementing the newly confirmed behavior in coming Nintendulator beta versions. Now we just need to hit up the bug trackers for FCEUX and other major emulators.

Post Reply