Jump to content
IGNORED

Combat scanline count per VSYNC interval?


ehenciak

Recommended Posts

Hi all,

 

This is my first post here...sorry it's so forward. My question is more geared towards those familiar with Atari 2600 emulation and game development. I picked the programming board since most people familiar with the Atari probably know the answer to this. I hope this is the right board ;)!

 

I'm working on an Atari 2600 in an FPGA. I will opensource this one, I promise you that. I have some sick obsession with finishing this thing. Quite frankly, I rarely attack side-projects like this.

 

If you're familiar with current games-in-FPGA projects, my design uses the T65 6502 core found in the Asteroids Deluxe emulation found at www.fpgagames.com. The RIOT and TIA are my designs. RIOT took a couple of hours to implement. Basically, my timing matches the datasheet save the interrupt logic on port B (I don't believe this is necessary, but I'll fix it before I release it). The timer looks dead on accurate. I've got all the "hard" circuitry in TIA complete (the horiz. sync counter, hmotion logic). This took a little more than a couple hours ;). I've tested the heck out of it and it appears to work just fine, but I'll never rule out any bugs...I'm not that arrogant :)!

 

When I first tied it all together, I found a problem similar to the one Eric Crabill had (see www.fpga-games.com). I'm running Tank-Plus (i.e. Sears' 4K version of Combat). Basically, the time in between each VSYNC pulse was around 20ms (translates into 300+ scanlines per screen....yuck) the first time I ran the code. I found two timing problems in the T65 core, fixed them, and now I am down to 16.74ms in between VSYNC pulses. This is almost where we need to be. I am now seeing 263 scanlines per frame. This is one off from what's specified in the Stella guide! Not perfect...

 

Frustrated, I ran Adventure. Adventure seems to be dead on perfect. I am seeing 262 scanlines and a 16.68 ms interval between VSYNC pulses. Wierd. I'll get more games in the simulator as time permits. Hopefully some homebrew author can kick me in the right direction.

 

So, I either still have some sick, silly, timing issue in the CPU (or my TIA) or Combat uses 263 scanlines.

 

My question is, can anyone confirm this? Do any Atari games violate the 262 scanline spec? The end result with a frame rate of 16.74ms is still very close to 60Hz (1.0044 seconds per 60 frames). I am sorry I am too lazy to just fire up an emulator (i'm busy writing one for what it's worth :) )...I'm just hoping someone knows this off the top of their head!

 

Much appreciated!

 

Ed

Link to comment
Share on other sites

Now that's encouraging news. I'll keep testing out stuff with Z26.

 

Adventure seems to run perfectly thus far (262 scanlines all the time during the first 120 ms of simulation).

 

Video Pinball is rather strange....the very first frame was 262 lines...the rest up to about 120 ms were 261.

 

This is a labor of love to say the least....I'm having the time of my life developing this :)!

 

Ed

Link to comment
Share on other sites

I'm targeting an Altera Cyclone. If I produce something, I'll probably use the smallest Cyclone II on the market when they're available in quantity this summer. I want to get it completely working before I start getting people's hopes up. I prefer Xilinx devices, but I need the PLLs in the Cyclone (for a potential feature creep...Xilinx DCMs do not work at speeds < 24MHz).

 

I ran Video Pinball here at work and got 262 myself. In the log file I dumped, I saw a couple of instances where it hit 263 (near the very beginning of execution). I want to check the ROM I was using at home before I start digging thru my TIA / T65 CPU core. I'm dying to get home to compare code execution to what I am seeing in simulation. Running both Combat and Adventure yielded results virtually identical to what I saw in simulation.

 

By the way, for those out there who play with VHDL, please check out the VHDL Simili tool available from www.synphonyeda.com.....it's a downright STEAL! I plan on buying a license for this regardless of the outcome of this Atari endeavour.

 

I'll make a web page about this once I get the 4K games running on my development board. I do not plan on getting any sleep this weekend ;). I WILL OPENSOURCE THIS DESIGN!

 

Ed

Link to comment
Share on other sites

Hi again,

 

PROGRESS!!! Thanks a million for the Z26 tip!

 

I think I now got the T65 from Opencores cycle-for-cycle accurate. There was yet another cycle count error in one of the instructions. This will allow me to complete TIA rather rapidly at this point. After I get the 4K games working, I will probably go back and make the core a little smaller in terms of logic elements and much more easier to read. Only 2 functional bugs and 2 timing bugs is friggin great for a hardly used core (assuming they're all squashed)!!!! Hell, most cores you buy off of vendors have significant problems that are much easier to fix!

 

Again, what I'm now seeing in simulation matches the log file of Z26 PERFECTLY for Combat. Major thanks for the pointer!

 

Ed

Link to comment
Share on other sites

I think I now got the T65 from Opencores cycle-for-cycle accurate.

Good, but did you do the "illegal" opcodes too? Many modern homebrews (including mine!) use them (mainly LAX, DCP and various NOPs).

 

    Again, what I'm now seeing in simulation matches the log file of Z26 PERFECTLY for Combat.  Major thanks for the pointer!

Yes, z26 and its logfile are great for developing and debugging. Thanks to John and Eckhard and all who contributed to z26's development. :thumbsup:

Link to comment
Share on other sites

Hi again,

 

First, the T65 core doesn't support illegal opcodes outright....however, judging by the way the CPU is implemented, they either A. Work "somewhat" or B. Don't work at all, but will be fixable. I pretty much got the gist of the implementation. I am going to focus strictly on some simple, early Atari 4K games at first to confirm the CPU is doing what it should.

 

Overall, once I get TIA done, I may just write my own core since I'll know TIA isn't the issue by then. Although, if the CPU works, why waste time on that with Maria needing implemented. I will test out both Thrust and the others :)! It's half the reason I'm making this :) :). The other half is pure curiosity.

 

Ed

 

PS Again, I will Opensource this design.

Link to comment
Share on other sites

Another quick question....I posted this in the hardware forum, but that doesn't seem to be the best place...

 

 

On the TIA schematics, it appears that if a WSYNC "internal" pulse occurs when the horizontal timing LFSR has just wrapped (i.e. SHB is subsequently set), then WSYNC would not be permitted to pulse since it would be tied to '0' via the n-channel pulldown whose gate is tied to SHB. As a result, the RDY latch would not be set (I should say cleared since the output is inverted) resulting in the CPU not being stopped. Simple enough, eh?

 

Well, according to Z26, this is not the case. If Z26 sees a WSYNC

occur on CPU cycle 75 (low phase of the CPU clock is when WSYNC internal would pulse), Z26 immediately jumps to the next scanline. My TIA stays on the current scanline. This causes a mismatch in my simulation since I'm using Z26 as a baseline. For those interested, this occurs on frame 1, scanline 3, CPU cycle 74 of NTSC Video Pinball.

 

Fortunately, I ran my simulation out far enough to get to the eigth frame. I checked several instruction executions and I appear to be back in sync with Z26 at this point. Going back to frame 2, I saw the same thing.

 

Finally, I looked at the Z26 source code. They make some mention of simply skipping a line if WSYNC occurs at this point, but they didn't seem to sure about that based on a comment near that particular code.

 

I'm just wondering if anyone has any comments on this. I think ignoring the WSYNC in this case (i.e. don't stop the CPU) as opposed to skipping a scanline seems to be the right way to go from a purist standpoint. You wouldn't want to stop the CPU anyway since you'd be on the 1st clock of the scanline anyway! However, I can see how this is

quite possibly a dog chasing his tail since this only happens during game initialization....I don't see why someone would issue a WSYNC so close to the end of a scanline anyway. Since you virtually have to account for each cycle while drawing, why waste a whole line's worth of cycles by WSYNC'ing so close to the end. You'd waste a couple of cycles performing the write and also waste the entire 76 cycles of the line that draws nothing!

 

Another note : After looking at the schematics even more, it really does seem that if the CPU writes to WSYNC and the actual CPU write (i.e. when r_wn is asserted by the processor) occurs on the same cycle SHB is set, then a WSYNC will not take place. TIA basically drives the signal that sets the latch to stop the CPU on the low half of the CPU clock. If this signal arrives on cycle earlier, RDY would be asserted for a very short time. If it is one cycle later, then the CPU would halt for the entire scanline minus one CPU cycle (i.e. 75 clock cycles)

 

Sorry about the babble....does anyone have any thoughts on this? I have a feeling that this probably only occurs during game initialization...

Link to comment
Share on other sites

I am not 100% sure if I understand you correctly, but if a WSYNC would end at e.g. cycle 1, it will halt the CPU for the whole remaining scanline.
If it didn't, it seems like that would royally screw up sprite-positioning routines executed during VBLANK (when cycles aren't counted precisely) because this:
sta WSYNC

sta HMOVE

couldn't be guaranteed to occur at the proper cycle every time.

Link to comment
Share on other sites

Sorry to be unclear. Here's the relevant information from NTSC Video Pinball executing. I am at work right now, so I need to be brief. Please be aware that this is a special case of a WSYNC being issued virtually at the end of a scanline. The actual write to TIA would occur on what Z26 calls the 75th cycle of the scanline.

 

( 1 3 74 ) f069: 84 02 sty WSYNC

( 1 5 0 ) f06b: 84 00 sty VSYNC

 

As we know, Z26 labels clock cycles from 0 to 75 (76 cycles total)

 

So, STY begins execution on CPU clock 74. This is a three cycle instruction (i.e. OPcode fetch + 2 cycles to execute...opcode fetch would have taken place on cycle 73).

 

On clock cycle 75, the CPU will drive its r_wn signal low thus indicating a write to the TIA WSYNC register.

 

On the low half of the CPU clock 75, the signal which sets the RDY latch, thus driving RDY low, is asserted.

 

However, internally, TIA's LFSR, which tracks scanline position if you will, has just been reset. The latch which stores set horizontal blank (shb signal on the schematic) is currently set high thus not permitting the WSYNC latch to set. This would actually make sense in that one is at the start of the new scanline. The only difference is that Z26 would be starting the new scanline at CPU cycle 1.

 

If the write to TIA would take place on cycle 75, then the entire next scanline would be wasted.

 

Again, by write, I mean that the CPU is writing a location. I do not mean that "an opcode has started that involves a write".

 

I hope this is a little clearer :)!

 

Thanks!

 

Ed

Link to comment
Share on other sites

So, STY begins execution on CPU clock 74.  This is a three cycle instruction (i.e. OPcode fetch + 2 cycles to execute...opcode fetch would have taken place on cycle 73).

I suppose that's the point of misunderstanding. 74 doesn't mean the first cycle of execution, but the start of the whole instruction (incl. opcode fetch!).

Link to comment
Share on other sites

This would explain a lot! I'll check this as soon as I get home. I believe I am starting my cycle counter at the wrong time. I assumed that the cycle time indicated the contents of the instruction register. The first microcycle of any instruction is the opcode fetch. The opcode itself is not latched into the instruction register until the next cycle.

 

Since Combat never does this "WSYNC too close to the next scanline", I would have never seen this while checking out Combat.

 

This is not due to a bug in my TIA either, it is due to a bug with me and my silly verification environment :)!

 

Assuming that you're familiar with the TIA schematics, would you agree that if a write of WSYNC that results in the CPU's write cycle being coincident with the cycle that TIA has set hblank set were to occur, the result would not cause the scanline to be "wasted"? In other words, if the CPU writes to TIA on what Z26 calls cycle 75, TIA would ignore this WSYNC since the CPU would already be at the start of the next line.

 

Danke Schoen again Thomas!!!!

 

Ed

Link to comment
Share on other sites

Assuming that you're familiar with the TIA schematics....

I am only a programmer. You can find the real hardware experts at the [stella] mailing list.

 

In other words, if the CPU writes to TIA on what Z26 calls cycle 75, TIA would ignore this WSYNC since the CPU would already be at the start of the next line.

No, writing @75 would result in finishing the instruction @01, therefore you would loose one scanline. The latest WSYNC write, which won't let you loose the next scanline, starts @73.

 

Danke Schoen again Thomas!!!!

Gern geschehen, Ed! :)

Link to comment
Share on other sites

The source of my problem was the way I was registering data in my virtual TIA. I was doing it one cycle too early. This explains my confusion. When I do a write up on this, I'll draw timing diagrams to show my error. Everything is OK now.

 

I found my bug when adding the ball logic. Pitfall uses the ball for the ladders. My ladders were 3 pixels to the left of the center of the hole in the ground. I was pretty much resetting the TIA ball counter at the wrong time.

 

Due to my arrogance, I wasted a day tracking this problem down....however, everything is back on track. If I would have used my head, 1 CPU cycle = 3 color clocks....that would have clued me in a lot earlier and I would have made more progress. I thought it was something with the CPU core at first...I also had a problem with my horizontal motion counters (simple enough to fix...please work for Cosmic Ark :) ).

 

I'm adding the player0/1 logic tonight. If this works, screenshots will look significantly more interesting and forthcomming :)!

 

Thanks again!

 

Ed

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...