-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve TIA WSYNC emulation #42
Comments
Old core says 2600. :) |
This is fixed in a6bc247. I actually knew how to fix this bug when I created the issue, but I wanted it documented here anyway. It was actually fixed in the old core in 2006 (!), documented below:
Modified Files: Index: TIA.cxxRCS file: /cvsroot/stella/stella/src/emucore/TIA.cxx,v *** 2212,2217 **** |
2006 --- an anagram of 2600 😏 I am well aware of the issue; however, I fail to see how this fix gets closer to accurately emulating it. Afaik, what happens on WSYNC is that the TIA pulls low RDY which will cause the CPU to halt on the next read cycle. However, this change (as well as the implementation in the old core) checks whether the previous cycle was a read cycle. In addition, it will skip WSYNC alltogether, while the real thing should continue executing just until it hits a read cycle. |
By all means, please feel free to change it to more accurately emulate what's going on. The implementation in the old core 'fixes' the ROM in question, but it's probably only a superficial change. I assume you did this differently in 6502.ts; how did you fix the issue there? |
I didn't fix it at all 😃 In 6502.ts, CPU emulation is currently not sophisticated enough to do anything like this. In particular, all reads required for decoding the instruction happen in the first cycle, and all reads and writes required by the instruction itself happen in the last cycle (this is the reason while Pole Position is glitched in 6502.ts). As the CPU in 6502.ts is dispatched cycle by cycle, properly emulating memory access patterns would require turning every instruction into a state machine. Doing this would make the implementation of this particular edge case trivial, but the required changes are pretty invasive. I am not sure about Stella; the fact that dispatch is driven by the CPU makes emulating memory access patterns much easier. I think one way to correctly implement RDY behavior would be to signal the TIA on each read access. WSYNC could then raise an internal flag, and the necessery advance of the system clock could happen on the next read signal. I might take a stab at implementing this at some point. However, I guess I would first have to design a valid testcase that fails on the current implementation and validate this on real hardware. The most obvious idea is hitting WSYNC with a RMW instruction. A naive implementation like 6502.ts will then skip two lines. Your fix is already better as it will only wait on the first write. Still, there should be a difference of two in the color clock at which the next instruction is executed, and this should be visible when doing a RESx. |
Since this isn't really fixed but only worked around, we should reopen the bug. I also included the original report from sourceforge above, since the Stella sourceforge page will be disappearing eventually. |
Isn't it the same mechanism VIC-II uses to stop 6510 in Commodore 64? Maybe a look into how C64 emulators do it would help. |
Yes, that's a good idea. The main problem now is lack of time; I hope to revisit this soon. |
@sa666666 if you like I can take over this, I think I have a pretty solid idea of how to test and implement proper RDY handling 😏 |
Yes, of course if you have time and are willing, I won't complain 😄 I'm working on the PAL colour-loss now, and how to have it ready in the next day or so. Also I plan to do a new release by the end of the month. So feel free to work on any issue you like before then. |
New release sounds good, I guess we are closing in on 5.0 final 😄 I am currently still trying to get meaningful profiling data out of Stella. After that, I'll be looking at RDY. @KarolS I don't know the details of the C64, but I guess that's true. Afaik every 6502 based system that implements DMA uses this mechanims to make the 6502 temporarily relinquish the bus. |
This testcase probes for proper emulation of the CPU RDY line. You can switch the testcase between PAL and NTSC with the color switc. On Stella, the result looks like this: Observe the "nose" in the middle of the white bar --- this is due to the aforementioned difference in the color clock when stopping the TIA on the first write fof a RMW instruction (INC in this case) instead of stopping at the next read cycle. On real hardware, there is no "nose", just a smooth white rectangle. Other emulators that don't try to account for proper RDY behavior at all show a series of black stripes instead of the "nose" (javatari, MESS). 6502.ts is special: it displays properly, but this is not because of proper RDY emulation, but rather because it doesn't emulate the first spurious write in a RMW instruction at all (that's 6502ts/6502.ts#51) 😏 Next step: fix it. |
The attached test ROM illustrates how it can tell if it was run on an emulator or a real console. Obviously, the emulator should identify as a real console too.
emubug.zip
The text was updated successfully, but these errors were encountered: