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" the five semi-stable instructions (SHX abs,y, SHY abs,x, SHA abs,y, SHA (zp),y, TAS abs,y) 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, shxing1, comprehensively searches SHX 03nn,y, x=FB 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, shxing2, comprehensively searches SHX nn80,y, y=80 and makes sure that the subset of writes that happen to system RAM happen to the right place. Source included, CC-0 or public domain, Pass is just the word "OK"; otherwise it'll say the first test that failed.
The third 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 sufficiently controllable. 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 shxing1 is not implemented correctly. Checking on hardware shows a number in the range of D9 to E9, or roughly one out of every 300 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" the five semi-stable instructions (SHX abs,y, SHY abs,x, SHA abs,y, SHA (zp),y, TAS abs,y) 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, shxing1, comprehensively searches SHX 03nn,y, x=FB 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, shxing2, comprehensively searches SHX nn80,y, y=80 and makes sure that the subset of writes that happen to system RAM happen to the right place. Source included, CC-0 or public domain, Pass is just the word "OK"; otherwise it'll say the first test that failed.
The third 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 sufficiently controllable. 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 shxing1 is not implemented correctly. Checking on hardware shows a number in the range of D9 to E9, or roughly one out of every 300 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 1 — Views 333