[comp.sys.apple2] Vertical blank

tm@polari.UUCP (Toshi Morita) (06/06/90)

Paul Sender writes:

(various stuff deleted)

>I also understand that some folks reading this newsgroup have some way of
>storing particular values in the unused locations scattered about the text
>and hires pages, and then watch some unused location in the motherboard's
>I/O page for those particular values.  It seems that these values will get
>latched someplace where a program can see them during the retrace intervals.
>All of this is undocumented by Apple, of course, but I seem to recall quite
.a bit of discussion about this around two years ago.  Can someone elaborate
>on this technique, and is it still used?
>--
>Paul Sander        (408) 734-9822  | Wisdom

If I recall correctly, any value fetched by the video circuitry is accessible
by reading the $C05X softswitches. Values in screen holes appear at $C05X
during horizontal retrace.

For example, to determine when the video has started vertical blanking
interval, assuming screen is in graphics mode:

1) Select a value that is not used in the video display. This can either be
predetermined (preferred) or memory can be scanned (inefficient). Some programs
never use values with the high bits clear or set; if so, this is ideal since
the converse can be used for the next step.

2) Store the value at the first byte in the last screen hole.
   (pg 1 = $3ff8, pg 2 = $5ff8)

3) Watch a softswitch (ex. $C050) for the value to appear.

4) Execute vertical blanking interval code.


On an Apple //e, //c, or //gs this code is obsolete - it's much easier to poll
the high bit of $C019 to determine the vertical blank interval status.


tm@polari.UUCP

GRAY@ADMIN.HumberC.ON.CA (Kelly Gray) (06/07/90)

> If I recall correctly, any value fetched by the video circuitry is
> accessible by reading the $C05X softswitches. Values in screen holes appear
> at $C05X during horizontal retrace.

There is a bit more to the trick than that. First of all, the tightest loop you
can write to test for the value is going to be at least seven clock cycles long,
and the video circuitry fetches a different byte on EVERY clock cycle, so at
least seven consecutive identical bytes will be needed in the pattern you are
testing for.
 The pattern byte must appear in only one area in the screen RAM area, but
exactly were doesn't really matter at all. It can be in an unused screen hole,
or in the display itself, as long as it is unique.
 Once you have found the pattern byte, this does NOT mean that the display is in
the middle of the vertical blanking interval. It means that the video display is
currently updating the area of the screen corresponding to the memory location
where the pattern is.
For example, if your pattern string was located in the eight bytes starting the
hi-res graphics page 1, addresses $8192-$8199, the checking loop would find the
pattern when the video circuitry was updating the display somewhere in the first
fifty six pixels of the top line on the screen.
 If the pattern is in one of the hi-res screen holes, then the video circuitry
will have just entered the vertical blanking period when the pattern is found.

Why this trick works is actually fairly simple. During each clock cycle, the
6502 has control of the data bus for the first half, and the video circutry has
control during the second half. If the 6502 ever tries to read from a memory
location where there is no memory (or anything else) present to respond, the
byte that will be read is a "ghost" copy of the byte that the video cuicutry
last read.

The code that I've seen to do this timing is the following loop:

      LDA #PATTERN     ;get a copy of the byte used in the pattern
LOOP  CMP $C058        ;Read from non-existant RAM (The annunciator
                       ; outputs don't drive the data bus)
      BNE LOOP         ;if not found, wait
                       ;if found, fall through to your screen code



There are some real neat tricks that can be done with this sort of technique.
For example, I saw a demo that had text on the TOP four lines of the display,
and graphics on the rest (In spite of the fact that Apple says it can't be
done!) The trick was to hide a pattern of bytes in one of the hi-res screen
holes, and wait for the pattern to be found. When the pattern was found, switch
to text mode, wait a PRECISE number of clock cycles until the Apple had just
finished displaying the last line of the text, and then trip the soft switches
back to graphics mode.
 In fact, if you are willing to let your program do nothing but sit in a VERY
precise timing loop, it is possible to eventually get it in synchronization with
the video display to the point where you can control the switching of the
graphics modes to within eight pixels of any point of the display.


  <o_o>
        Kelly Gray (GRAY@ADMIN.HUMBERC.ON.CA)