DeadlyKitten36 Posted March 29, 2019 Share Posted March 29, 2019 Hey, Over the last few weeks I've been working on a 2600 emulator as a hobby project and I've had some issues understanding how certain things works. In particular learning assembly and the 6502 is very challenging but I was wondering if anyone would be kind to help me in learning about the 2600 itself. I'm currently trying to figure out how I would emulate the TIA, and my most recent issue relates to the way you use HMOVE/HMP0 registers to achieve smooth scrolling. From what I understand, you use HMP0 as a relative offset to shift the pixels of the sprite to adjust for the 3-1 ratio of CPU - TIA clocks. I found a TIA document online saying that you use the latter 4 bits of HMP0 to determine the offset from -7, + 8. But what I don't understand is why you would need this kind of range when you only need to move the offset 3 pixels at a time. I hope this was coherent, any advice is really appreciated. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted March 29, 2019 Share Posted March 29, 2019 This is only true if you hit the exact cycle you needed when strobing the RESxx register to set the coarse position of the object. If you use a loop to delay until you reach the correct cycle, each loop iteration would take a minimum of 5 cycles, which requires the full 15 color clock range of the fine adjust range. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 30, 2019 Share Posted March 30, 2019 You'll fine lots of useful info at MiniDig, such as the Stella Programmer's Guide, memory maps, an analysis of HMOVE timing, how the audio works, etc. 1 Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted March 30, 2019 Share Posted March 30, 2019 I'm currently trying to figure out how I would emulate the TIA, and my most recent issue relates to the way you use HMOVE/HMP0 registers to achieve smooth scrolling. One piece of advice that I can give is this: don't try to model your emulation after the "official" VCS programmer's guide, but instead try to understand how the chip's interconnected counters work to implement the described behaviour. In particular, Andrew Tower's TIA hardware notes (available i.e. here) are an excellent resource. Just understanding and sticking to them will get you about 95% along the way. 2 Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted March 30, 2019 Share Posted March 30, 2019 Oh, and trying to get the behaviour of reads from non-read location (i.e. TIA write-only registers) might save you a lot of headaches, too --- this is a very common programming error in VCS code, and not emulating it correctly will lead to all sorts of superficially mysterious issues with certain ROMs. Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted March 31, 2019 Author Share Posted March 31, 2019 Thank you everyone I i really appreciate you taking the time to help out. I think I understand how these registers are supposed to work better- Now to try implementing it Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted May 27, 2019 Author Share Posted May 27, 2019 Hey, Sorry to ressurect and old threadI've made a lot of progress on this project and I was hoping someone might be able to lend me some advice about managing the timings of the CPU / TIA a little as it's been difficult to get this right My approach has just been to associate a CPU count with each opcode and then advance the TIA CLK 3x the length of the opcode. The execution looks like Check_Opcode() PerformLogic() AdvanceCLK(3 * LengthOfOpcode) ... I was wondering... Is this naive? Do some ROMs rely on the 2 clocks in a STA before the storage actually completes in a graphics register? It seems like every time I make a change to this timing some other binary starts misbehaving and I wonder if I'm fundamentally going about this incorrectly. Thank you for reading <3 Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted May 27, 2019 Share Posted May 27, 2019 (edited) I was wondering... Is this naive? Do some ROMs rely on the 2 clocks in a STA before the storage actually completes in a graphics register? The 6502 is constructed to perform a read or write on every cycle; there is no cycle without a bus access (as long as RDY is asserted and the CPU is active). If you want 100% accuracy, you have to emulate the bus access pattern cycle-exact. A sensitive test case is Pole Position: the two borders of the road that meet at the horizon are positioned using two subsequent writes during the execution of a single opcode (a BRK according to this post on the Stella list). Failure to emulate this correctly will cause the road to be shifted or distorted. That said, from my experience with 6502.ts, you can get 99% of the way by moving the side effects of the opcode to the last cycle of the instruction (for example, write memory in cycle 3 of a immediate STA). This is the difference between the "instruction exact" setting in Stellerator and the "cycle exact" setting I added last year. In fact. the only real-world example I know of that is broken with the "instruction exact" core *is* Pole Position EDIT: What I forgot: there are various ROMs out there) that accidentally read from the floating bus (by targeting unmapped locations or interpreting bits that are not driven). Those have a tendency depend on the exact sequence of bus accesses of many opcodes, even if the precise timing is usually irrelevant. Edited May 27, 2019 by DirtyHairy Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted May 29, 2019 Author Share Posted May 29, 2019 Thank you for the response DirtyHairy, I appreciate it!I did some reshuffling and I seem to be getting the desired output by moving the effects of each opcode to the last cycle. I'll keep on studying and report back if all goes well ^_^ ~ Quote Link to comment Share on other sites More sharing options...
John Saeger Posted June 7, 2019 Share Posted June 7, 2019 Here is more than you want. I guarantee it!z26-demos.zip 1 Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted June 11, 2019 Author Share Posted June 11, 2019 Here is more than you want. I guarantee it!z26-demos.zip Holy wow that's quite a goldmine haha. Thank you so much <3 Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted July 2, 2019 Author Share Posted July 2, 2019 Hey, I wanted to ask if anyone could help me with understanding WSYNC and other potential timing curveballs I implemented timing as dirtyhairy described, most ROMs I've tested work almost perfectly but I'm running into a lot of cases of being off by one CPU cycle quite a lot. I guess I wanted to ask if anyone knows of any curve balls I should be considering? One thing I tested (and this could be false) is performing a WSYNC puts the beam at 6 CLK even when strobed with longer instructions (sta WSYNC,X) etc I'll keep going over the code and testing with Stella but if anyone had any advice on what I should review Also, for anyone who worked with a lot of 6502, does page crosses play into the timings a lot in time dependent sections of the code? Again, I really appreciate the help. Really enjoying my journey learning about this console ! Quote Link to comment Share on other sites More sharing options...
+Karl G Posted July 3, 2019 Share Posted July 3, 2019 15 hours ago, DeadlyKitten36 said: Also, for anyone who worked with a lot of 6502, does page crosses play into the timings a lot in time dependent sections of the code? This part I can answer. There are a lot of instances where display kernel timing is very tight, and a difference of one cycle can throw things off (e.g. a 48-pixel routine). It is also not uncommon for loops in a display kernel to not use WSYNC at all in order to save those 3 cycles, in which case the cycle-counting in the routine needs to be precise. Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted July 7, 2019 Share Posted July 7, 2019 On 7/3/2019 at 1:15 AM, DeadlyKitten36 said: I implemented timing as dirtyhairy described, most ROMs I've tested work almost perfectly but I'm running into a lot of cases of being off by one CPU cycle quite a lot. I guess I wanted to ask if anyone knows of any curve balls I should be considering? One thing I tested (and this could be false) is performing a WSYNC puts the beam at 6 CLK even when strobed with longer instructions (sta WSYNC,X) etc I would assume that you still have one or two opcodes whose timing is off, and this causes the cycle shift you are observing. You can try to track them down by stepping the affected code in your debugger (provided you have already implemented one ) and comparing the instruction timing to Stella instruction by instruction until you find the faulty opcode. I am not sure whether I understand your question about WSYNC. Strobing WSYNC will pull the RDY line of the CPU low until the next HBLANK phase starts. Pulling RDY low will halt the CPU in the next read cycle. Unless you are close the the 76th cycle, the number of clocks that the strobing instruction requires to execute is irrelevant. The only possible twist concerns instructions with two consecutive write cycles (i.e. RMW instruction); as the CPU stops at the next read cycle, those will still cause the CPU to be suspend until the next HBLANK only (as opposed to skipping a fill line because of writing WSYNC twice). 1 Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted July 8, 2019 Author Share Posted July 8, 2019 (edited) Thank you both for the replies! I have a basic debugger in and I've been stepping through ROMs side by side with stella. I think part of my misunderstanding comes from the beginning of ROMs where intialization happens (CLEAN_START etc).. I think some problems could derive from the mirrored addresses (WSYNC being both 02 and 43 for example). To try and find exactly where I fall out of sync with Stella I added a "frame count" & "cycle count" but I'm having problems with even that. For example, here is the ROM for donkey kong, and I noticed Stella moves to "frame 2", on "scanline 50" the final BPL. Maybe someone here can help me understand this? ? Edited July 8, 2019 by DeadlyKitten36 Quote Link to comment Share on other sites More sharing options...
DirtyHairy Posted July 8, 2019 Share Posted July 8, 2019 (edited) 16 hours ago, DeadlyKitten36 said: To try and find exactly where I fall out of sync with Stella I added a "frame count" & "cycle count" but I'm having problems with even that. For example, here is the ROM for donkey kong, and I noticed Stella moves to "frame 2", on "scanline 50" the final BPL. Maybe someone here can help me understand this? ? I think that you can safely ignore the frame count for now. There is no strict definition of the boundaries of frames for the 2600, especially during the initialization phase of a ROM where no valid TV signal is generated. Stella has a pretty elaborate algorithm for determining the boundaries between frames that is built to address many special cases, and I am not surprised that your counting differs. The cycle count that a section of code requires to execute is an exact number, though, and if you step instruction by instruction, you should be able to track down where your emulation gets it wrong. Edited July 8, 2019 by DirtyHairy Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted July 11, 2019 Author Share Posted July 11, 2019 Hey, Just wanted to drop a message and say thank you again, this information was super helpful- Just trying to find some time to work on this stuff So far I found I wasn't handling 73 cycle WSYNCs correctly, there were some page crosses I forgot to include also. I will write back and let you guys know if I make progress Quote Link to comment Share on other sites More sharing options...
DeadlyKitten36 Posted August 12, 2019 Author Share Posted August 12, 2019 Hey, just wanted to make a final post here thanking everyone for the help again and giving a quick update I'm probably going to come back to this at a later point when I've learned a little more about emulation and programming in general as I've been feel more and more out of my depth working on this. If anyone is interested, I put up what I had so far on GitHub. https://github.com/nd3644/e6502-vcs It got as far running most of the examples from 8bitworkshop and partially runs a few official games but there are timing issues and some things missing in the TIA. Again thank you for the advice, I hope to come back to this at a later point Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.