For a variety of silly reasons, I found myself wanting an instruction that took exactly 15 pixels to write to a mapper register. While there are two official opcodes that do this (STA abs,x and STA abs,y), I needed to write two different values.
According to No More Secrets, it's possible to "disarm" these five semi-stable instructions by careful choice of address and register contents. So I tried to use SHX/SXA but then I discovered that basically every emulator implements these wrong.
The first test ROM, shxshy1, comprehensively searches SHX 03nn,y and makes sure that all 65536 writes happen to the right place. (No page crossing = where you want it. Page crossing = somewhere else, in this case zero page). As of today, only Nestopia and MAME handle this correctly, although puNES passes for the wrong reason. Source included, CC-0 or public domain. Pass is just the word "OK"; otherwise it'll say the first test that failed.
The second test ROM plays DMC during playback, because if the instruction is interrupted by RDY, then the value written is not corrupted. This is only here to confirm what Groepaz wrote; it's hard to make a situation where this behavior would be desirable. Source included, CC-0 or public domain. Pass is a non-zero number on the right; Fail is zero; Fatal error gets a screen showing that the behavior tested in shxshy1 is not implemented correctly. Checking on hardware shows a number in the range of D9 to E9, or roughly one out of every 18 SHX are interrupted in this test.
Note that these tests only test SHX=$9E. For SHY=$9C it's the same but X and Y are swapped. The remaining problematic instructions are variations on SAX - SHA=$93 and SHA=$9F are like SHX except it's A&X; TAS=$9B is identical to SHA=$9F except it also stores A&X into S.
Note that correct behavior is:
According to No More Secrets, it's possible to "disarm" these five semi-stable instructions by careful choice of address and register contents. So I tried to use SHX/SXA but then I discovered that basically every emulator implements these wrong.
The first test ROM, shxshy1, comprehensively searches SHX 03nn,y and makes sure that all 65536 writes happen to the right place. (No page crossing = where you want it. Page crossing = somewhere else, in this case zero page). As of today, only Nestopia and MAME handle this correctly, although puNES passes for the wrong reason. Source included, CC-0 or public domain. Pass is just the word "OK"; otherwise it'll say the first test that failed.
The second test ROM plays DMC during playback, because if the instruction is interrupted by RDY, then the value written is not corrupted. This is only here to confirm what Groepaz wrote; it's hard to make a situation where this behavior would be desirable. Source included, CC-0 or public domain. Pass is a non-zero number on the right; Fail is zero; Fatal error gets a screen showing that the behavior tested in shxshy1 is not implemented correctly. Checking on hardware shows a number in the range of D9 to E9, or roughly one out of every 18 SHX are interrupted in this test.
Note that these tests only test SHX=$9E. For SHY=$9C it's the same but X and Y are swapped. The remaining problematic instructions are variations on SAX - SHA=$93 and SHA=$9F are like SHX except it's A&X; TAS=$9B is identical to SHA=$9F except it also stores A&X into S.
Note that correct behavior is:
- When there is no page crossing, use the calculated address
- When there is a page crossing, AND the calculated address (which has a carry out because of the page crossing: H+1) with the register that is being stored
Statistics: Posted by lidnariq — Tue Dec 10, 2024 6:15 am — Replies 0 — Views 21