<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Tue, 24 Sep 2002 20:10:52 +0100
From   : Richard_Talbot-Watkins@...
Subject: Re: rupture technique

james watson wrote:

> I thought this was the case (only starts of &3000,&4000,&5800,&6000).
> Can you explain what the rupture technique is please?

"Vertical rupture" is the name someone coined for the technique whereby one
TV frame contains more than 1 CRTC cycle, allowing us to "split" the screen
into separate blocks, each of which can thus have its start address set
independently of the others, which means we can of course hardware scroll
parts of the screen separately to the others.

My smooth scrolling demo relies on it!  Recall how we have a scrolling
section and a stationary bit - that's using exactly this technique to
achieve that.

Because the top part of the screen is scrolling, we need to make this use
the bottom range of screen addresses (i.e. &5800..&7FFF), as we need to
benefit from the hardware screen wrap-around at &8000.  Note that at the
beginning of the demo, we prod the addressable latch at &FE40 to specify
a 10k screen.  The bottom half of the screen is stationary, so we use the
rupture technique and set up the bottom half's start address to be &3000.
So effectively, the two halves of the screen are mapped the other way
round, but the truth is that we could split the screen any number of times
in a frame, and set each block's address to be whatever we wanted - linear
address space?  PAH!

Suppose we want to set up a simple screen rupture - MODE 2, top 16 lines
hardware scrolled, bottom 16 lines stationary.  We need to be able to set
the top half screen address to any value between &5800...&7FF8, and lock
the bottom half to &3000.

Here's how my solution worked....

* First note that we have 39 character rows in a PAL screen.
* Next note that in normal MODE2, we have VSync set to occur at line 34
  (value in R7)
* This means that from the point of VSync we have 5 character rows left
  of the CRTC cycle - remember this!  It is important later on....

I then implemented rupture as follows:

* Wait for VSync interrupt!
* As we know, this happens towards the end of the CRTC cycle.  TV flyback
  will have started, and the TV is ready to start the new physical frame
  shortly.  So the beginning of the next CRTC cycle represents the top of
  the new frame.

* Immediately set up R12/R13 with the hardware scroll start address for
  the "top" screen.  This is cached by the CRTC and will be used when it
  starts its new cycle.

* Now we must wait until the new CRTC cycle has started.  We already know
  this to take 5 character rows (remember?!).

        5 character rows
        =  40 (5*8) scanlines
        =  2560 (40*64) 1MHz clock ticks

  So we wait for AT LEAST 2560 clock ticks... to cater for differing
  tolerances in clock speeds and CRTCs, we wait for a while longer than
  this, as we only care that we are rastering somewhere within the new
  CRTC cycle.  As I've mentioned in the past, the timing required is not
  actually all that delicate.

* We are now into a new CRTC cycle.  The CRTC has taken its internal
  address pointer from R12/R13 and is currently refreshing the screen from
  somewhere between &5800 and &8000 (whatever we specified - we are
  choosing this address for our scrolling after all!)

Next we do a few cunning things:

* We set R4 to 15, specifying a total CRTC cycle length of 16 rows.
* We set R7 to anything greater than 15.  This ensures that VSync will
  NEVER be generated during this cycle.  This is what we want, as we
  know from the PAL standard that we must have 39 rows in a refresh,
  and generating VSync every 16 rows will clearly cause the TV to
  barf!  Let's set R7 to 255 just to make a point :)
* We set R6 to 16: this ensures that we see all the rows of this CRTC
  cycle; this is what we want - they are all valid after all.  Of
  course we could equally set R6 to anything higher than 16; it won't
  display any more because there are only 16 rows in the whole CRTC
  cycle!

Note that setting R4,R6 and R7 *during* the cycle they are controlling
works OK, as the CRTC doesn't pre-cache them (as it does with R12/R13),
they are simply read each time round its internal loop as it needs them.

Now here's the more cunning bit:

* We set R12/R13 to look at &3000.  As we know, the CRTC has already
  cached its internal address pointer from R12/R13 this update and
  changing them mid-update won't affect its screen address pointer.
  However, as we know, this update is only going to last 16 rows, at
  which point its cycle will start all over again, and its screen
  address pointer will be re-cached, this time using the NEW values
  in R12/R13, i.e. &3000!

* Now we need to wait for the new CRTC cycle to begin - this will of
  course be in 16 character rows time from the last cycle:

        16 character rows
        = 128 (16*8) scanlines
        = 8192 (128*64) 1MHz clock ticks

  At this point, the TV will be starting to rasterise the physical bottom
  half of the screen, and the CRTC will be sending screen data from
  addresses &3000 onwards to the TV.

The trick now is to restore normal conditions again.  We have 23 more rows
left in the PAL refresh to make up.  So:

*  We set R4 to 22 to give us 23 rows.
*  We set R6 to 16 to ensure that we only plot 16 rows.
*  We set R7 such that VSync is generated at the *same point relative to
   the end of the CRTC cycle as a normal MODE 2 refresh*.  As we
   remembered earlier (you remember?), we had 5 rows left following a
   VSync.  So, if we set R7 to (23-5)=18, we get the VSync in the same
   place.

And that's pretty much it!  The VSync generated then takes us back to the
beginning of this loop, upon which we do the same thing all over again.

Of course, my smooth scrolling demo also messes about with R5 in order to
get the pixel-by-pixel movement but that's just extra code bolted onto this
framework.

In a real game, the waits in the above loop would be handled by a VIA timer
interrupt, rather than an idle delay loop as I did in my demo (which was
purely to keep it simple).

Hope that helps make it all a little clearer.  You may be able to see what
the code is doing now!

Cheers,
Rich

--
Rich Talbot-Watkins
SCEE Cambridge
Richard_Talbot-Watkins@...     



**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
postmaster@...     

This footnote also confirms that this email message has been checked
for all known viruses.

**********************************************************************
 SCEE 2002
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>