Jump to content
IGNORED

Writing to HSCROL breaks DLIST


Recommended Posts

I'm doing my experiments with PAL artifacting, I have simple program which display bitmap in 320x200 mode, and that's it.

Now I added 'calibration' into the code. It scrolls the image a bit when I press keys 1 to 4. I use HSCROL for that. But I run into interesting problems.

First some more info:

 

The code turns ROM off, all interrupts are pointed at RTI, and disabled. The code just sets up the display, and uses bitmap linked into the XEX, which is generated outside Atari code. The display list is simple, 200 lines, address is set on every line and hscrol is enabled. Dlist is looped using Dlist instruction, not in VBI. As I said, there is no interrupt.

 

This worked fine. Then I added simple loop, which reads keyboard, and if 1 is pressed it writes different value to hscrol register. Thing is the loop is not synchronized in any way. It runs as fast as possible. And time to time, when I pressed the key, the image disappeared. Altirra shows that Antic reads display list from completely wrong location. The CPU running fine, continues the loop.

 

So today I did some testing with Bob!k, we double checked everything. In the end we removed all keyboard reading, and left simple code:

 

loop lda random

sta hscrol

jmp loop

 

This causes the problem every time, and fast, in less than a frame. Antic simply looses the way.

 

Now .. Altirra emulates this quite well. Everything we tested about this worked the same on real hardware. But reading through Altirra's hardware reference I didn't find this problem. There are many hscrol related 'bugs', but everything described just seem to make Antic read false data when reading VRAM .. not Dlist. Or at least that's the way I understood it. In my case it seems Antic reads false data as Dlist, which makes it miss the Dlist jump instruction.

 

So we added sta wsync into our code, just before writing to hscrol. We found, that we can write numbers up to 10 into hscrol. 8 was fine. 9 and 10 showed false data in the image, 11 killed the Dlist looping. In the end we found 4 extra nops after wsync make everything run smooth even with 15, and that's where I left it.

 

It clearly isn't anything new, I just don't know which of the 'bugs' described in the reference it is. For sure I never suspected writing to hscrol at wrong time can kill your Dlist.

 

Have anyone encountered this problem ? Is there some recommendation when exactly write to hscrol ? Does this apply to some other registers ?

Edited by R0ger
Link to comment
Share on other sites

From Altirra Hardware reference:

 

- in Disrupting the DMA clock with HSCROL chapter: This means that in order for a horizontally scrolled normal or wide width line to display correctly, HSCROL should not be rewritten before cycle 111, three cycles before missile DMA fetch. (page 62)

- in Disrupting the DMA clock with mode switching chapter: Horizontally scrolled normal or wide width mode line at fast DMA fetch rate (modes 2-5 or D-F), with HSCROL >= 10. (page 63)

- in Overlapping DMA chapter: Warning The potential for overlap with display list DMA is what makes the abnormal playfield DMA bug a serious one. If it just affected the playfield, then the only problem would be visual glitching. When abnormal playfield DMA overlaps display list DMA, however, it can send the display list execution off into the weeds. This can then cause wild display list interrupts to fire and the program to crash. (page 64)

 

IMHO it's mix of those "bugs".

Edited by MaPa
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Certainly the third thing. Didn't notice it, I only quickly read sections directly containing word hscrol, and somehow I missed it. But that's exactly what's happening. Kudos to Phaeron for implementing so well !

Edited by R0ger
  • Like 2
Link to comment
Share on other sites

Yep, disrupted DMA for sure.

 

Also, the OS writes the DList pointer during VBlank to cater for this situation and in case the DList in use isn't constructed properly. Antic treats DList as a sort of program so just keeps trawling through it until it hits a jump instruction or ticks back at a 1K boundary - without regard for one frame from the previous.

 

I've done programs in the past with slight custom DLists and for reason I couldn't work out they'd go corrupt if I disabled stage 2 VBlank, and this is just simple graphics + text mixing, not any scrolling or other trickery.

 

A good idea is to put a VBlank in your program to do the SDLST copy. Probably a good idea to do your HSCROL store in there as well.

 

For HSCROL stores, as a minimum it's a good idea to do a STA WSYNC immediately before storing HSCROL. That should be enough to prevent the corruption you're getting.

  • Thanks 1
Link to comment
Share on other sites

For HSCROL stores, as a minimum it's a good idea to do a STA WSYNC immediately before storing HSCROL. That should be enough to prevent the corruption you're getting.

 

That puts the write EXACTLY where it must not be ;-) For me wsync and 4 nops solved the problem.

Link to comment
Share on other sites

Certainly the third thing. Didn't notice it, I only quickly read sections directly containing word hscrol, and somehow I missed it. But that's exactly what's happening. Kudos to Phaeron for implementing so well !

Yes, the third describes what can happen when abnormal DMA is happening, but I'm not sure what leads to the abnormal DMA pattern. If just only the simple high value hscrol store after wsync... But then IMHo should be 2 NOPs enough to avoid this problem (WSYNC to 105 cycle, 2x NOP - 109 cycle and STA writes at cycle 113?).

Link to comment
Share on other sites

The abnormal pattern happens when ANTIC leaves bits in the playfield DMA clock because it misses the stop position. If you change HSCROL while the DMA clock is still running, you move the stop position and ANTIC tries to clear the wrong bit in the playfield clock, leaving the bit in the loop. The higher the HSCROL position, the later the playfield DMA goes into horizontal blank and the more time you have to accidentally move the stop too early. This is possible because while ANTIC avoids doing playfield DMA cycles for the part of the playfield that's scrolled into horizontal blank, it still runs the playfield DMA clock for that portion -- that's how the memory scan counter still gets counted for the full 40/48 bytes.

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

Pretty much what I experienced. When writing right after wsync, I could write up to 8. With one extra nop I could write 10. With 2 nops I could write 12 and with 3 nops the dlist didn't break even with 15, but there were still visual glitches. 4 nops seems to glitch-less. That's with 40 characters width.

  • Thanks 1
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...