Jump to content
IGNORED

P/M DMA and VCOUNT timing


phaeron

Recommended Posts

I've been trying to tune the cycle timing in my Atari emulator to be exact compared to a real Atari, and have come up with some results that don't quite match what I've seen discussed in this forum... so I figured I'd ask to see if anyone could spot where I may have gone wrong.

 

Here are my WIP charts:

http://www.virtualdub.org/other/antic-timings.pdf

 

I made these with the help of a little 6502 test program that uses the RANDOM register to count cycles. One thing that I'm unsure about is the timing of player/missile DMA. I have an elaborate text chart by Bennet that shows missile DMA starting 11 cycles prior to character name DMA on wide mode 2 scan line, with three idle cycles after LMS address fetch. My profiling results on a real Atari seem to indicate that P/M and display list DMA occurs one cycle later, however, so that if missile DMA starts on cycle 0, character name DMA starts at cycle 10. Most everything else appears to agree, including WSYNC and refresh timing. The charts are numbered so that the CPU restarts execution after STA WSYNC at cycle 105, with one cycle of the next instruction already having been executed before the CPU was halted.

 

The other thing I need verification on is exactly when VCOUNT steps. It seems to happen on cycle 112, but I haven't found that documented anywhere.

 

Can any ANTIC experts comment?

Link to comment
Share on other sites

Nice charts (accuracy check pending of course).

 

Missile DMA always occurs on cycle 113. Then you have DList Instruction if needed on cycle 0.

IIRC, if PMG DMA isn't enabled, it fetches the operands if needed on the following 2 cycles.

 

Otherwise it uses the 4 cycles (1-4) for Player DMA. Remember of course that many documentation is wrong re PMGs - the DMA occurs each line regardless of if they're in 1 or 2 line mode (otherwise, VDELAY just plain wouldn't work).

 

If PMG DMA is active, then cycles 5,6 are DList operand if needed.

 

 

How are you utilizing RANDOM to determine cycle counts? Are you loading it then comparing to some pre-calculated table?

 

VCOUNT - not sure here, but cycle 112 sounds feasible. It would be easy enough to test... just have a program issue WSYNC, then try different delays to skew a subsequent LDA VCOUNT instruction. Best to do it with DMACTL=00 so nothing gets in the way.

Link to comment
Share on other sites

I should add - GTIA behaviour, re PMG DMA.

 

GTIA actually "thinks" that Missile DMA is happening the first time a HALT comes from Antic after a HBlank command is issued on AN0-AN2.

 

As such, if Antic doesn't have PMG DMA enabled, it can mistakenly think the DList instruction is the missiles (and think subsequent bus data is the Players).

 

Of course, if no HALT occurs during HBlank, GTIA doesn't bother trying to reload the GRAF registers.

Link to comment
Share on other sites

I can't take credit for the chart designs, as they're inspired by Bennet's text charts.

 

I don't see the display list address timing you're describing -- AFAICT, any LMS/jump address is always fetched five cycles after the instruction byte, whether or not P/M graphics is enabled. I've attached a screenshot of my test application running on an NTSC 800XL. The three lines are mode 2 row 2 with P/M off, mode 7 row 0 with P/M off, and mode 7 row 0 with P/M on. The first five cycles are prior to LDA RANDOM right after STA WSYNC, followed by missile DMA, display list DMA, player DMA, and address DMA. Notice that the display list DMA doesn't appear to move.

 

To count cycles, I set AUDCTL bit 7 to 1, and then repeat the test until the LDA RANDOM right after STA WSYNC returns $00. Because the noise generator is running in 9-bit mode, and the POKEY noise generators are XOR-based LFSRs, if the 8 bits sampled by RANDOM are 0 then the ninth bit must be a 1. This establishes a predictable pattern from which my test code can count cycles based on subsequent RANDOM values. It's a bit annoying since it can take over a minute for the noise LFSR to hit just the right phase, but it's far more reliable than the method I was using before, which was to time sprite collisions.

 

Missile DMA always occurs on cycle 113. Then you have DList Instruction if needed on cycle 0.

IIRC, if PMG DMA isn't enabled, it fetches the operands if needed on the following 2 cycles.

 

Crap, just "fixed" that. Maybe I'll have to unfix it.

post-16457-1242190500_thumb.png

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...