Jump to content
IGNORED

Changing playfield width in a DLI - timing


Recommended Posts

Is it possible to change playfield width from normal to wide with SDMCTL in a DLI? If so, do you need to do it a scanline or two in advance? I'm guessing it's a timing problem, as all I'm getting is the normal playfield with a phantom character in the border - derp :twisted:

 

Cheers,

 

Simon

Link to comment
Share on other sites

No, SDMCTL is just the shadow and gets plugged into DMACTL during VBlank.

 

You can change the Antic register DMACTL on the fly, of course it'll get written back at VBI so you need to do so every frame it's wanted.

 

You can change DMACTL whenever you want but the results won't necessarily be what you wanted.

e.g. you could change from Standard to Wide mode part way through a line but the character codes for the extra bytes mightn't have been fetched.

In that case, Antic reuses whatever data was last there.

 

You can get some interesting effects.

 

Another idea I had some time back but never tried properly was "Super HScrolling".

 

Imagine a sine-wave effect you wanted to wave across the screen, with a width of 10 characters or so. To do so without moving data or changing LMS isn't possible.

 

But if you dynamically change HSCROL as well as the DMA width you can in effect move graphics over a 12 character region.

 

Of course the problem mentioned before can arise - e.g. you have Narrow Mode when the character codes are fetched, you only have 32 positions filled.

So when you switch to Std or Wide, there might be unwanted data in the last 8 or 16 columns.

 

The trick in this case would be to keep those as blanks to avoid the situation.

 

The Interlace 480i technique also uses DMACTL tricks. If the "Scanline 240 bug" is enabled, you can hit DMACTL during the vertical area that's normally always black, to generate extra HSync pulses.

 

The other use of the Scanline 240 bug is that it lets you show PMGs anywhere. But you have to load the GRAF registers yourself each scanline outside the normal 240 because Antic doesn't do it then.

Link to comment
Share on other sites

No, SDMCTL is just the shadow and gets plugged into DMACTL during VBlank.

 

Oops, that's what I meant, I think I need to go back to mnemonic school!

 

You can change the Antic register DMACTL on the fly, of course it'll get written back at VBI so you need to do so every frame it's wanted.

 

You can change DMACTL whenever you want but the results won't necessarily be what you wanted.

e.g. you could change from Standard to Wide mode part way through a line but the character codes for the extra bytes mightn't have been fetched.

In that case, Antic reuses whatever data was last there.

 

You can get some interesting effects.

 

Still can't get mine to go, I'm wondering if the next few lines after the DLI being blanks (i.e. no load) is messing it up. Either that or it's one of those ones that sort of works on an emulator but would crash immediately on the real h/w. Never mind, I'll keep tinkering.

 

Another idea I had some time back but never tried properly was "Super HScrolling".

 

Sounds good, get to it! ;)

 

Cheers,

 

Simon

Link to comment
Share on other sites

The thing to consider too is that you usually don't want to turn off DList Instruction fetch.

 

The other thing is badlines, you have much less flexibility there.

 

And there is a good chance emulation might produce different results - of course Altirra is usually spot on or not far off.

 

As for the change width, the DMA Timing charts, e.g. in Altirra HW Guide can be of help there.

 

You see, the character fetches occur before the actual graphics start being displayed, so you've got to pre-empt in some cases. If you've got HScrolling enabled then you can fudge it too, use a big HSCROL value and you gain a few cycles.

 

On the other hand, changing mid-line should be immediate, e.g. change Wide to Narrow just after Narrow would have finished and it should go blank.

Edited by Rybags
Link to comment
Share on other sites

Overrun? How do you mean?

 

I'd say the logic in Antic WRT this stuff is somewhat different to VIC or ST's Shifter, with VIC you can do border change tricks to allow extra graphics.

 

With Antic, the change you make is somewhat immediate and Antic seems to internally disable some processes at specific times regardless of if they're in use or not, e.g. character/bitmap DMA, PMG fetches.

Link to comment
Share on other sites

ANTIQ is correct -- changing the playfield width in the middle of a scanline can cause ANTIC to miss the playfield stop and keep going to the end of the wide playfield. However, to do this you need to change the playfield width before ANTIC has hit the stop to a point that's already been passed. This is impossible on the first scanline of a mode 2-5 line since the CPU is blocked by the wall of playfield DMA.

 

I list the detailed behavior for DMACTL with changes in my hardware doc, but the short version is that the important points are about 3-5 cycles prior to when playfield DMA stops and starts for each width. Playfield DMA starts or stops whenever ANTIC crosses those boundaries and the width setting in DMACTL matches. Therefore, if you have a wide playfield and try to change the playfield width to normal after it has already started, there will be no effect on the start but the playfield will stop at the normal width point on the right side. If this is done on the first scanline, this will also affect the memory scan counter, advancing it by a width that isn't ordinarily possible like 44 bytes. If you switch the setting such that the start is missed, playfield DMA is skipped, and if you switch it such that the end is missed, it keeps going until wide end. (And if you screw around with horizontal scrolling, it can keep going beyond that!)

 

For a DLI, I'd recommend writing to DMACTL as early in horizontal blank as possible, i.e. STA WSYNC / STX DMACTL. The window for this can be really tight. The worst case is wide or normal scrolled character graphics on the next scanline, with P/M graphics enabled and a LMS instruction. In that case there are only 7 cycles in horizontal blank until it's too late.

 

There are several programs that rely on this behavior, by the way: Aztec Climber, Pacem in Terris, and Turmoil have unusual timing for DMACTL writes. Aztec Climber in particular relies on a nonstandard line pitch. This is what the tail end of the display list looks like:

 

 0DE4: mode 7
       lms 33A8
 0DE7: blank 4
 0DE8: mode 6
 0DE9: waitvbl 0DA6

 

However, if you check Altirra's display list history (.dlhistory), you see this:

 

Ycoord DLIP PFAD H V DMACTL MODE
--------------------------------
 196: 0de4 33a8 3 0   3f   47
 212: 0de7 33be 3 0   32   30
 216: 0de8 33be 3 0   32   06
 224: 0de9 33d2 3 0   32   41

 

The mode 7 line is wide width (DMACTL=$3F), so it should advance the scan counter by 24 bytes to $33C0. Instead, however, it advanced only 22 bytes to $33BE. This is caused by a late write to DMACTL after DMA has already started:

 

   2193:187:  9 | A=76 X=40 Y=FF S=FC P=33 | 0E1C: 20 50 11         JSR $1150
 - NMI interrupt (DLI)
     2193:187: 39 | A=76 X=40 Y=FF S=F7 P=37 | C018: 2C 0F D4         BIT NMIST
     2193:187: 55 | A=76 X=40 Y=FF S=F7 P=B5 | C01B: 10 03            BPL $C020
     2193:187: 61 | A=76 X=40 Y=FF S=F7 P=B5 | C01D: 6C 00 02         JMP (VDSLST)
     2193:187: 71 | A=76 X=40 Y=FF S=F7 P=B5 | 1B7C: 48               PHA
     2193:187: 77 | A=76 X=40 Y=FF S=F6 P=B5 | 1B7D: 8A               TXA
     2193:187: 81 | A=40 X=40 Y=FF S=F6 P=35 | 1B7E: 48               PHA
     2193:187: 87 | A=40 X=40 Y=FF S=F5 P=35 | 1B7F: AD 0B D4         LDA VCOUNT
     2193:187: 95 | A=5D X=40 Y=FF S=F5 P=35 | 1B82: C9 40            CMP #$40
     2193:187: 99 | A=5D X=40 Y=FF S=F5 P=35 | 1B84: 10 34            BPL $1BBA
     2193:187:105 | A=5D X=40 Y=FF S=F5 P=35 | 1BBA: A2 D0            LDX #$D0
     2193:187:107 | A=5D X=D0 Y=FF S=F5 P=B5 | 1BBC: A9 32            LDA #$32
     2193:187:109 | A=32 X=D0 Y=FF S=F5 P=35 | 1BBE: 8E 0A D4         STX WSYNC
     2193:187:113 | A=32 X=D0 Y=FF S=F5 P=35 | 1BC1: 8E 1A D0         STX COLBK
     2193:188:110 | A=32 X=D0 Y=FF S=F5 P=35 | 1BC4: E8               INX
     2193:188:112 | A=32 X=D1 Y=FF S=F5 P=B5 | 1BC5: E0 D8            CPX #$D8
     2193:189:  1 | A=32 X=D1 Y=FF S=F5 P=B4 | 1BC7: D0 F5            BNE $1BBE
   + Last 5 insns repeated 7 times
     2193:196:  8 | A=32 X=D8 Y=FF S=F5 P=37 | 1BC9: 8D 00 D4         STA DMACTL
     2193:196: 15 | A=32 X=D8 Y=FF S=F5 P=37 | 1BCC: A9 32            LDA #$32

 

The result is wide start with a normal stop.

Link to comment
Share on other sites

This is an interesting article as I am looking to do the same (but haven't done it yet).

 

I want a narrow main screen and then a standard width section for putting statistics/scores on. It shouldn't be difficult it seems.

 

I take this quote to ask a general question for this thread.

First, in your case no problem. Just store a value in DMACTL. Nothing special.

Further, why would we want to mess ANTIC timings to open the border? The border can be opened with POKE 35,559.

Maybe my coding is too straight out of the book. But why does anyone want to change the width mid-line?

 

Or is it the good old :"Because I can?" :)

 

What I did was changing DMA mid-line to gain a bit of cycles, at least i thought so. I had a part of my display in the left quarter of the 48-byte mode then blank and the another part in the last quarter. And I think with the switching of of the DMA I gained something, however, that was before I found the Altirra-HW-Doc with all those timing diagrams. Maybe I should recalculate if it really was worth it :)

Edited by Creature XL
Link to comment
Share on other sites

This is an interesting article as I am looking to do the same (but haven't done it yet).

 

I want a narrow main screen and then a standard width section for putting statistics/scores on. It shouldn't be difficult it seems.

I never knew there was an issue with this. I have some code doing width changes among other things in a multi-DLI screen. I have from normal to narrow and back to normal width again, with no screen issues. I am not doing it mid-line though. I have it several instructions below my STA WSYNC too - did I just get lucky?

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