nesdev.com
https://forums.nesdev.com/

Trying to get FME-7 IRQs right
https://forums.nesdev.com/viewtopic.php?f=2&t=12436
Page 1 of 2

Author:  tepples [ Fri Feb 27, 2015 3:02 pm ]
Post subject:  Trying to get FME-7 IRQs right

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:
File comment: Test ROM
vwfterm.nes [32.02 KiB]
Downloaded 123 times
File comment: Intended appearance
in_fceux.png
in_fceux.png [ 4.73 KiB | Viewed 4028 times ]

Author:  lidnariq [ Fri Feb 27, 2015 3:57 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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:
   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:
                  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;

Author:  tepples [ Fri Feb 27, 2015 5:43 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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:
File comment: 256*n+6 technique scrolling
vwfterm-nestopia.nes [32.02 KiB]
Downloaded 127 times

Author:  Zepper [ Sat Feb 28, 2015 7:47 am ]
Post subject:  Re: Trying to get FME-7 IRQs right

@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?

Author:  tepples [ Sat Feb 28, 2015 7:59 am ]
Post subject:  Re: Trying to get FME-7 IRQs right

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.

Quote:
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.

Author:  koitsu [ Sat Feb 28, 2015 3:32 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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?

Author:  tepples [ Sat Feb 28, 2015 4:26 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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 138 times

Author:  tokumaru [ Sat Feb 28, 2015 5:18 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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

What reason? Emulator inaccuracies?

Author:  koitsu [ Sat Feb 28, 2015 5:34 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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.

Author:  tokumaru [ Sat Feb 28, 2015 6:13 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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.

Author:  rainwarrior [ Sat Feb 28, 2015 6:57 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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.

Author:  tepples [ Sat Feb 28, 2015 7:11 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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 230 times
powerpakresult.jpg
powerpakresult.jpg [ 90.17 KiB | Viewed 3895 times ]

Author:  l_oliveira [ Sat Feb 28, 2015 7:42 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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

Author:  Myask [ Sat Feb 28, 2015 8:56 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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
MednafenTooSmall.png [ 35.67 KiB | Viewed 3854 times ]

Author:  tepples [ Sat Feb 28, 2015 9:41 pm ]
Post subject:  Re: Trying to get FME-7 IRQs right

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.

Page 1 of 2 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/