Jump to content

Photo

Changing playfield width in a DLI - timing


13 replies to this topic

#1 simonl OFFLINE  

simonl

    Chopper Commander

  • 160 posts
  • Location:UK

Posted Fri Jul 1, 2011 12:08 PM

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

#2 Rybags ONLINE  

Rybags

    Quadrunner

  • 12,888 posts
  • Location:Australia

Posted Fri Jul 1, 2011 12:19 PM

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.

#3 simonl OFFLINE  

simonl

    Chopper Commander

  • Topic Starter
  • 160 posts
  • Location:UK

Posted Fri Jul 1, 2011 1:09 PM

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

#4 Rybags ONLINE  

Rybags

    Quadrunner

  • 12,888 posts
  • Location:Australia

Posted Fri Jul 1, 2011 1:28 PM

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, Fri Jul 1, 2011 1:31 PM.


#5 MaPa ONLINE  

MaPa

    Dragonstomper

  • 786 posts
  • Location:Czech Republic

Posted Sat Jul 2, 2011 5:17 AM

I think you can change playfield width only outside the playfield or in Hblank as I had once a problem setting different playfield width in middle of scanline and on real HW the screen was messed up.

#6 ANTIQ OFFLINE  

ANTIQ

    Chopper Commander

  • 132 posts

Posted Sat Jul 2, 2011 6:24 AM

I was wondering if it could make ANTIC overrun.

#7 Rybags ONLINE  

Rybags

    Quadrunner

  • 12,888 posts
  • Location:Australia

Posted Sat Jul 2, 2011 6:42 AM

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.

#8 ANTIQ OFFLINE  

ANTIQ

    Chopper Commander

  • 132 posts

Posted Sat Jul 2, 2011 7:45 AM

Changing the playfield width could cause the current position to never equal the stop position.

I'm only speculating!

#9 Rybags ONLINE  

Rybags

    Quadrunner

  • 12,888 posts
  • Location:Australia

Posted Sat Jul 2, 2011 8:24 AM

Yes, that seems to be the VIC and Shifter logic.

Antic seems to just display only if both the range and mode meet requirements, there doesn't seem to be a flip border trick to make characters go beyond where they're supposed to.

#10 phaeron OFFLINE  

phaeron

    Stargunner

  • 1,223 posts
  • Location:USA

Posted Sat Jul 2, 2011 3:50 PM

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.

#11 snicklin OFFLINE  

snicklin

    Stargunner

  • 1,289 posts
  • Location:Australia

Posted Sun Jul 3, 2011 5:24 AM

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.

#12 Creature XL OFFLINE  

Creature XL

    Dragonstomper

  • 775 posts
  • Location:Hannover.De

Posted Sun Jul 3, 2011 6:37 AM

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, Sun Jul 3, 2011 6:40 AM.


#13 Stephen OFFLINE  

Stephen

    River Patroller

  • 4,786 posts
  • A8 Gear Head
  • Location:Akron, Ohio

Posted Sun Jul 3, 2011 12:25 PM

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?

#14 Rybags ONLINE  

Rybags

    Quadrunner

  • 12,888 posts
  • Location:Australia

Posted Sun Jul 3, 2011 12:36 PM

If your doing it offscreen immediately before new rows of characters there shouldn't be a problem.

If you do changes part way down a row, you can get unexpected results. Least of which is the alignment will skip out.




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users