http://byuu.cinnamonpirate.com/files/timing_test.zip
I always knew this was possible, but just never bothered to write the code to do it.
It is now possible to get OPHVCT to a known position at any time during execution, there's no more need to reset the SNES to achieve this effect.
This test rom contains a function called seek_frame. When called, it will return IMMEDIATELY at V=0, H=0. And yes, the true H=0, as in HC=0 as well. It can detect half dots as well.
I tested this on hardware, and it checks OPHVCT immediately after calling jsl seek_frame repeatedly. The second it isn't in range, the screen turns red. But it stays blue forever, so it definitely works.
I'd appreciate if anyone wanted to look over my routine for validation, but I'm positive it works fine as is.
It probably won't pass on PAL hardware, though...
There's also a function called seek_cycles, it will seek a set number of clock cycles specified by a.w. It cannot be called with a.w < 640 or > 65535, for obvious reasons. But that's hardly a problem.
This will finally allow us to write tests for the recent NMI / IRQ findings, such as what happens when $421n is read at the same time NMI / IRQ go low. I also plan to write a frontend to the library much like my old op timing test program, but without requiring the reset part anymore, and giving more input / output information.
The only things you'll need to get this working in an emulator are: perfect opcode timings (easy enough), proper $2137 latching behavior (OPHVCT is set 2 clock cycles ahead of when the bus $2137 read cycle begins), and proper scanline / frame lengths (including the missing dot on scanline 240 non-interlace frame 1).
$213f / $4212 are also polled, but the code will auto compensate if those bits aren't set at the exact right time as on hardware, as I don't latch the counters until after that code completes.
Oh, as a side note: no, ZSNES does not pass this test. It shows a blue screen because it retardedly gets stuck in the STAT77 wait loop while I wait for an odd frame.
Gentlemen, behold!
Moderator: ZSNES Mods
-
- ZSNES Shake Shake Prinny
- Posts: 5632
- Joined: Wed Jul 28, 2004 4:15 pm
- Location: PAL50, dood !
Re: Gentlemen, behold!
* grumbles about jedi tricks and voodoo all in a single piece of softwarebyuusan wrote:Oh, as a side note: no, ZSNES does not pass this test. It shows a blue screen because it retardedly gets stuck in the STAT77 wait loop while I wait for an odd frame.
皆黙って俺について来い!!
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
Code: Select all
<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Ok, updated the above archive to a newer version. It's now pretty much the modern version of my opcode timing test, only instead of toying with opcode counts, you just punch in how many half-dots you want it to seek (multiply by two for how many clock cycles to seek) after the start of a new frame, press start, and voila. Results onscreen that don't change every time you press start.
Already I've found out something with it, too.
DRAM refresh is slightly different on 5A22 CPU versions 1 and 2. I don't know about 3 or above as I don't have such a system.
On version 1, DRAM refresh always occurs at HC=528 (dot 132) on every scanline *
On version 2, DRAM refresh alternates every scanline between HC=532 and HC=536. The very first scanline at SNES reset occurs at HC=536 (I determined this by testing the second scanline, and since it obviously inverted...)
* On version 2, the DRAM refresh position does not change on scanline 240 non-interlace field 1 (the scanline that's one dot short), I have not tested this scanline on version 1 yet... but I suspect nothing happens here. I'll post in this thread again after I test it.
Given that, you'll notice that DRAM refresh will make OPHCT 'flicker' between 133 and 134 each time you run the test on a version 2 CPU. Try setting CTR0 in the test ROM to 681 or 682 to see it. On the version 1, it's always consistent: e.g. try with 679 on that.
The flickering is because 524*1364-4 isn't divisible by 8, and the counter seems to go by 8's, just like DMA. They probably share the same CPU locking/timing mechanism.
And of course, we also already know about the long dot differences between 5A22 version 1 and 2... the only other difference I'm aware of is that I hear version 1 can lock up when certain things happen at the same time as a DMA begins, but I know nothing more about that.
Update: Indeed, DRAM refresh still occurs at HC=528, even on scanlines 240+241 non-interlace field 1. Long dots are also always 323 and 327 on the V1 CPU (though this could be because of the V1 PPU2, who knows). There's no constant flickering between 321-323 and 325-327.
Oh, and my positions of course assume the read bus cycle of $2137 starts at 0 instead of 2, and $2137 adds 2 to the current counter position (so you'll actually see an OPHCT latch of 132.5). Makes sense... the DRAM refresh would be on the CPU side and would probably happen between opcode cycles, like everything else.
Optimized the hell out of the testing program, and so I'll probably start making a new NMI test tomorrow to cover all the new findings.
Already I've found out something with it, too.
DRAM refresh is slightly different on 5A22 CPU versions 1 and 2. I don't know about 3 or above as I don't have such a system.
On version 1, DRAM refresh always occurs at HC=528 (dot 132) on every scanline *
On version 2, DRAM refresh alternates every scanline between HC=532 and HC=536. The very first scanline at SNES reset occurs at HC=536 (I determined this by testing the second scanline, and since it obviously inverted...)
* On version 2, the DRAM refresh position does not change on scanline 240 non-interlace field 1 (the scanline that's one dot short), I have not tested this scanline on version 1 yet... but I suspect nothing happens here. I'll post in this thread again after I test it.
Given that, you'll notice that DRAM refresh will make OPHCT 'flicker' between 133 and 134 each time you run the test on a version 2 CPU. Try setting CTR0 in the test ROM to 681 or 682 to see it. On the version 1, it's always consistent: e.g. try with 679 on that.
The flickering is because 524*1364-4 isn't divisible by 8, and the counter seems to go by 8's, just like DMA. They probably share the same CPU locking/timing mechanism.
And of course, we also already know about the long dot differences between 5A22 version 1 and 2... the only other difference I'm aware of is that I hear version 1 can lock up when certain things happen at the same time as a DMA begins, but I know nothing more about that.
Update: Indeed, DRAM refresh still occurs at HC=528, even on scanlines 240+241 non-interlace field 1. Long dots are also always 323 and 327 on the V1 CPU (though this could be because of the V1 PPU2, who knows). There's no constant flickering between 321-323 and 325-327.
Oh, and my positions of course assume the read bus cycle of $2137 starts at 0 instead of 2, and $2137 adds 2 to the current counter position (so you'll actually see an OPHCT latch of 132.5). Makes sense... the DRAM refresh would be on the CPU side and would probably happen between opcode cycles, like everything else.
Optimized the hell out of the testing program, and so I'll probably start making a new NMI test tomorrow to cover all the new findings.