Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Vertical Blank on Apple ][+

646 views
Skip to first unread message

Norman Davie

unread,
Aug 22, 2016, 6:26:44 PM8/22/16
to
Did game companies just count cycles to insure they were not writing to the screen outside the vertical blank interval???

John Brooks

unread,
Aug 22, 2016, 7:47:26 PM8/22/16
to
On Monday, August 22, 2016 at 3:26:44 PM UTC-7, Norman Davie wrote:
> Did game companies just count cycles to insure they were not writing to the screen outside the vertical blank interval???

No VBL sync, so the choices are either to double-buffer or design the graphics engine to minimize time between erase & redraw.

-JB
Twitter: @JBrooksBSI

roger....@gmail.com

unread,
Aug 22, 2016, 8:49:00 PM8/22/16
to
On Monday, August 22, 2016 at 5:26:44 PM UTC-5, Norman Davie wrote:
> Did game companies just count cycles to insure they were not writing to the screen outside the vertical blank interval???

Asides from not knowing when then vertical blank is, I doubt there would have been enough cycles for this type of thing.

For really smooth stuff, page flipping would have been used.

The prototype Apple II mouse card had hardware the could allow finding the vertical blank; see http://www.folklore.org/StoryView.py?project=Macintosh&story=Apple_II_Mouse_Card.txt

mmphosis

unread,
Aug 22, 2016, 10:30:02 PM8/22/16
to
From what I gather the vertical blank can be determined without extra
hardware on the Apple II and Apple II+. The folklore story mentions a tight
loop and another 17 cycle loop.

> To synchronize with the video, Burrell had me fill the Apple II's frame
> buffer so the low bit was on most of the time, but set off at the end of
> the last scan line. I wrote a routine to sit in a tight loop, reading the
> latch. When the low bit changed, we would know the vertical blanking
> interval had just begun.

> The Apple II wasn't fast enough to keep up with its own frame buffer. A
> new byte of video data flew by every microsecond, which was only one
> processor cycle. It took at least 10 processor cycles to iterate through a
> loop, so we ran the risk of never seeing the low bit change. Burrell had a
> way around this, though - if the loop time was relatively prime to the
> display frequency, it eventually had to slip into place. I wrote a 17
> microsecond loop that fit the bill, and we were delighted to see it work
> perfectly.

I wrote routine with a 7 cycle loop that works on at least two emulators. I
don't have real hardware to test this on.

http://hoop-la.ca/apple2/2015/vbl/


Michael J. Mahon

unread,
Aug 22, 2016, 11:06:46 PM8/22/16
to
...and the fastest loop to poll an arbitrary address:

LDA <address>
Bxx <back to LDA>

is 7 cycles.

"Vapor lock" has been around for a long time, but it's difficult to
integrate with general code because of the difficulty of maintaining a
constant cycle count.
--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com

Mark D. Overholser

unread,
Aug 23, 2016, 10:58:13 AM8/23/16
to mmphosis
If you can determine when the Vertical Retrace has just started, you can
update the Screen, just after it, and even if you don't keep up with it,
there won't be any "noticeable jitter" until the Retrace overruns where
you are updating the screen.

If you can keep track of the time elapsed, with Cycle Counting, you
could "pause" your Screen Update, to let the Retrace Pass Over You to
minimize the jitter...


MarkO

roger....@gmail.com

unread,
Aug 23, 2016, 8:55:30 PM8/23/16
to
On Monday, August 22, 2016 at 9:30:02 PM UTC-5, mmphosis wrote:
> From what I gather the vertical blank can be determined without extra
> hardware on the Apple II and Apple II+. The folklore story mentions a tight
> loop and another 17 cycle loop.

You missed a key sentence - it required extra hardware:

"Burrell solved the problem by wiring up the spare flip flop to the low bit of the data bus, using it to latch whatever data the video was displaying so the processor could read it."

IIRC when a mouse card is initialized on II+, it puts up a blank hires screen with a couple of pixels, presumably to figure out when the vertical blank is.

Michael J. Mahon

unread,
Aug 23, 2016, 10:52:53 PM8/23/16
to
Actually, the last-read video byte can be read from any "unconnected" soft
switch address. This is the principle behind Bob Bishop's "vapor lock".

It's possible to sync with the video frame on (at least) any 8-bit Apple II
(I don't know about the IIgs).

John Brooks

unread,
Aug 23, 2016, 11:44:38 PM8/23/16
to
On Tuesday, August 23, 2016 at 7:52:53 PM UTC-7, mjm...@aol.com wrote:
> roger.shimadawrote:
Video sync on the GS is easy due to:
c019: Bit 7 = 1 when not in VBL
C02E-C02F: Vertical scan counter & horizontal scan counter

-JB

Mark Lemmert

unread,
Aug 24, 2016, 1:49:29 AM8/24/16
to
This thread is an interesting topic to me.

I'm working on an Apple IIe tile-based RPG game with complex hi-res screens and animation.

I've never tried working with the vertical blank. My understanding is that drawing during the vertical blank reduces issues with flicker when working with single page animation.

My screens are 17x11 tiles, which are 2 screen bytes X 16 lines. Animation is 4 frames. When a dozen or so tiles on the screen were animated, I had no significant problems with flicker. When half or more tiles on the screen were animated, things got really weird. For example, a screen with mostly animated water tiles.

I could see the animation frames being drawn tile by tile, left to right, top to bottom. The screen draw took a second or so but I could still see the different frame states briefly, verified by slo-mo video. Seeing part of the screen in frame 1 (for example) and part of the screen in frame 2, it seemed to create a distortion that could be described as a flicker.

But, my theory was/is that part of the problem occurring was that the screen draw was simply too slow as evidenced by being able to see parts of the screen in different frame states, and thus drawing in the vehicle blank would possibly make it worse by adding delays, or at best only solve part of the problem. Basically, if it's too slow, it's too slow, was my thinking, and I didn't see how altering the draw timing would help that issue.

I solved the problem by using page flipping for animation, and everything has been working great, but I've always been curious if I diagnosed this correctly and/or if I'm misunderstanding something about the vertical blank and how it may relate to this scenario.

Any thoughts?

I made this change over 6 months ago but if helpful I can probably dig up some video showing the distortion with the single page animation scenario.

Thanks for thoughts anyone has to share.


Mark

zel...@gmail.com

unread,
Aug 24, 2016, 10:15:48 AM8/24/16
to
On Wednesday, August 24, 2016 at 1:49:29 AM UTC-4, Mark Lemmert wrote:
> I've never tried working with the vertical blank. My understanding is that drawing during the vertical blank reduces issues with flicker when working with single page animation.

The original article documenting the technique is (I believe) Bob Bishop's "Have an Apple Split": text version at http://rich12345.tripod.com/aiivideo/softalk.html

The problem is that after detecting the sync position, you have to keep cycle-accurate timing from then on. While it's certainly possible to do that in a game engine, it would be challenging…

Zellyn

Michael J. Mahon

unread,
Aug 24, 2016, 12:57:43 PM8/24/16
to
I agree with your diagnosis.

Drawing during vertical blanking is only effective when the actual drawing
can stay ahead of the raster scan.

If drawing is slower than display refresh, then page flipping is much more
effective, and the flip can be synchronized with vertical blanking for even
better results (if the additional wait is acceptable).

Mark Lemmert

unread,
Aug 24, 2016, 10:59:54 PM8/24/16
to
Great article, thanks!

Mark Lemmert

unread,
Aug 24, 2016, 11:00:25 PM8/24/16
to
Michael,

Thanks for confirming!


Do you know if there are applications where drawing during the veritable blank interval would be more desirable than page flipping?

Thinking more broadly than the Apple II hardware, I’m speculating that using the vertical blank for drawing was mainly used on hardware that didn’t have page flipping available.


Thanks.

Mark




On Wednesday, August 24, 2016 at 11:57:43 AM UTC-5, mjm...@aol.com wrote:
> Mark Lemmert <mark.l...@gmail.com> wrote:

> > But, my theory was/is that part of the problem occurring was that the
> > screen draw was simply too slow as evidenced by being able to see parts
> > of the screen in different frame states, and thus drawing in the vehicle
> > blank would possibly make it worse by adding delays, or at best only
> > solve part of the problem. Basically, if it's too slow, it's too slow,
> > was my thinking, and I didn't see how altering the draw timing would help that issue.



> >
>

Mark D. Overholser

unread,
Aug 25, 2016, 2:32:13 AM8/25/16
to Mark Lemmert
On 8/24/2016 20:00, Mark Lemmert wrote:
> Michael,
>
> Thanks for confirming!
>
>
> Do you know if there are applications where drawing during the
> veritable blank interval would be more desirable than page flipping?
>
> Thinking more broadly than the Apple II hardware, I’m speculating
> that using the vertical blank for drawing was mainly used on hardware
> that didn’t have page flipping available.
>
>
> Thanks.
>
> Mark
>
>
>

My understanding of programming the Atari 2600 is about "Racing the
Beam" and only changing the Graphics when the Scan Line is not Re
Drawing your Graphics..


MarkO

olivier...@itn-group.eu

unread,
Aug 25, 2016, 12:18:17 PM8/25/16
to
Le mardi 23 août 2016 00:26:44 UTC+2, Norman Davie a écrit :
> Did game companies just count cycles to insure they were not writing to the screen outside the vertical blank interval???

One of the trick you can use, from the Apple II+ to the Apple IIgs is to read the $C070.

This byte is the value currently read by the video processor. If you want to be synchonized with the top of the screen (HGR 1), simply write known value at $2000 (begining of the HGR page) and loop over it.

For example :

$2000 : BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD
$2010 : BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD

Waiting Routine :

TOP_SCREEN LDA $C070
CMP $#BD
BNE TOOP_SCREEN

You need several pattern because the LDA / CMP /BNE takes few cycles and you can miss the BD. With sevral ones, you will catch it without any doubt.

Olivier

Michael J. Mahon

unread,
Aug 25, 2016, 9:51:17 PM8/25/16
to
Mark Lemmert <mark.l...@gmail.com> wrote:
> Michael,
>
> Thanks for confirming!
>
>
> Do you know if there are applications where drawing during the veritable
> blank interval would be more desirable than page flipping?
>
> Thinking more broadly than the Apple II hardware, I’m speculating that
> using the vertical blank for drawing was mainly used on hardware that
> didn’t have page flipping available.
>
>
> Thanks.
>
> Mark

Page flipping is definitely the more general approach, but in
RAM-constrained applications, syncing to Vblank and staying ahead of the
refresh is sometimes a necessity.

For any animation that can be completed in a millisecond or two, it's
pretty easy. If the animation requires several milliseconds, it may be
necessary to order the updates top-to-bottom to stay ahead of the refresh.

Lots of games have a large playfield but relatively small moving elements,
so the animation can be done completely during vertical blanking.

Michael J. Mahon

unread,
Aug 25, 2016, 9:51:18 PM8/25/16
to
A perfect example of RAM-constrained programming.

gid...@sasktel.net

unread,
Aug 26, 2016, 12:41:05 AM8/26/16
to
On Thursday, August 25, 2016 at 7:51:17 PM UTC-6, mjm...@aol.com wrote:
> Mark Lemmert <mark.lemmert> wrote:
> > Michael,
> >
> > Thanks for confirming!
> >
> >
> > Do you know if there are applications where drawing during the veritable
> > blank interval would be more desirable than page flipping?
> >
> > Thinking more broadly than the Apple II hardware, I’m speculating that
> > using the vertical blank for drawing was mainly used on hardware that
> > didn’t have page flipping available.
> >
> >
> > Thanks.
> >
> > Mark
>
> Page flipping is definitely the more general approach, but in
> RAM-constrained applications, syncing to Vblank and staying ahead of the
> refresh is sometimes a necessity.
>
> For any animation that can be completed in a millisecond or two, it's
> pretty easy. If the animation requires several milliseconds, it may be
> necessary to order the updates top-to-bottom to stay ahead of the refresh.
>
> Lots of games have a large playfield but relatively small moving elements,
> so the animation can be done completely during vertical blanking.
>
> > On Wednesday, August 24, 2016 at 11:57:43 AM UTC-5, mjm...@aol.com wrote:
> >> Mark Lemmert <mark.lemmert> wrote:
> >
> >>> But, my theory was/is that part of the problem occurring was that the
> >>> screen draw was simply too slow as evidenced by being able to see parts
> >>> of the screen in different frame states, and thus drawing in the vehicle
> >>> blank would possibly make it worse by adding delays, or at best only
> >>> solve part of the problem. Basically, if it's too slow, it's too slow,
> >>> was my thinking, and I didn't see how altering the draw timing would help that issue.
> >
> >
> >
> >>>
> >>
> >> I agree with your diagnosis.
> >>
> >> Drawing during vertical blanking is only effective when the actual drawing
> >> can stay ahead of the raster scan.
> >>
> >> If drawing is slower than display refresh, then page flipping is much more
> >> effective, and the flip can be synchronized with vertical blanking for even
> >> better results (if the additional wait is acceptable).
> >> --
> >> -michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
> >
>
>
>
> --
> -michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com


Has anyone determined what size of area can be drawn within a vertical blank period?

Mark Lemmert

unread,
Aug 26, 2016, 9:47:36 AM8/26/16
to
That makes sense. Thanks!


Mark


On Thursday, August 25, 2016 at 8:51:17 PM UTC-5, mjm...@aol.com wrote:
> Mark Lemmert <mark.l...@gmail.com> wrote:
> > Michael,
> >
> > Thanks for confirming!
> >
> >
> > Do you know if there are applications where drawing during the veritable
> > blank interval would be more desirable than page flipping?
> >

mmphosis

unread,
Aug 26, 2016, 2:52:19 PM8/26/16
to
> Has anyone determined what size of area can be drawn within a vertical
> blank period?

4550 cycles = 65 cycles * 70 lines, from:

http://rich12345.tripod.com/aiivideo/vbl.html

And, 4550 cycles is just the VBL period, you can get more cycles (17030
total) by "racing the beam" as others have mentioned -- and that's at 60
frames per second!

As, for how much screen area can be painted in 4550 cycles?

Coding for speed:

1137.5 bytes = 4550 / 4 cycle STA absolute instruction

That's painting more than the entire GR, GR2, TEXT or TEXT2 screen with the
same byte. Or, you could paint over an eight of the hi-res screen with the
same byte.

I think an interesting thing to do would be to flip the graphics modes while
racing the beam:

https://www.youtube.com/watch?v=KD6ocf_0Bkw


roger....@gmail.com

unread,
Aug 28, 2016, 11:33:36 AM8/28/16
to
On Tuesday, August 23, 2016 at 10:44:38 PM UTC-5, John Brooks wrote:
> Video sync on the GS is easy due to:
> c019: Bit 7 = 1 when not in VBL
> C02E-C02F: Vertical scan counter & horizontal scan counter

I really must remember how wide the experience is in this group....

$C019 as the vertical blank status was added in the //e. (So the mouse card didn't need to muck with the screen on initialization as it did on the ][+.)

The //c works a little differently - it can do something useful: trigger an interrupt on VBL! (I would think that the IIGS can do this too; it's in the mouse firmware on the //c.)

To be clear: the challenge is to detect vertical blank on an original Apple ][, or Apple ][+.

Note that Bob Bishop's pre-//e article includes:

"...there seem to be very few Apple IIs in which the method can't be made to work when the incompatible peripherals are unplugged."

Pity he didn't list the cards.

Additionally, my cryptic "not enough cycles to do this" should have been:

Waiting for vertical blank is generally used for things such as mouse cursors, where a relatively small graphic is redrawn on the same screen. A couple of things to consider are:
* Can the redraw be completed during the vertical blank?
* If vertical blank needs to be poll, can you afford the time to wait for vertical blank?

Page flipping is much easier to implement, though the RAM usage explodes.

Michael Pohoreski

unread,
Aug 28, 2016, 5:58:07 PM8/28/16
to
This is why I love this (news)group ... an old dog can still learn all sorts of new esoteric tricks like this. =P

Norman Davie

unread,
Aug 28, 2016, 7:19:40 PM8/28/16
to
My plan was to do all the drawing on the "hidden" graphics page, then do the page flip when I detect we're in the vertical blank. I don't think there is sufficent cycles to draw anything significant during the VB period.

Dave Kay

unread,
Mar 16, 2023, 6:35:50 AM3/16/23
to
On Monday, August 29, 2016 at 9:19:40 AM UTC+10, Norman Davie wrote:
> My plan was to do all the drawing on the "hidden" graphics page, then do the page flip when I detect we're in the vertical blank. I don't think there is sufficent cycles to draw anything significant during the VB period.
I know this conversation was while back now, but thought I'd jump in. When I was young back in the 80's I had an Apple //c (came with the mouse card or similar). I remember experimenting with the VBI back then and managed to get a mouse pointer the size of the original Mac arrow pointer (copied from studying magazines at the time) to move when I moved the mouse on a hi-res screen.
It was super cool to have this code "running in the background". I couldn't get anything more than a around 2 bytes x 14 pixels (or so). My ASM wasn't the most efficient though, so I'm sure guys here could get a bit more out of it. I do remember using lookup tables to draw to the screen though. Wish we had access to the internet back then. I had to rely on the odd magazine like Softtalk to help me out....

Michael Pohoreski

unread,
Mar 21, 2023, 11:59:11 AM3/21/23
to
On Thursday, March 16, 2023 at 3:35:50 AM UTC-7, Dave Kay wrote:
> I know this conversation was while back now, but thought I'd jump in. When I was young back in the 80's I had an Apple //c (came with the mouse card or similar). I remember experimenting with the VBI back then and managed to get a mouse pointer the size of the original Mac arrow pointer (copied from studying magazines at the time) to move when I moved the mouse on a hi-res screen.

Nice!

> It was super cool to have this code "running in the background".
Yup, one can do all sorts of neat stuff if/when you have a proper Vertical Blanking Interrupt.

> I couldn't get anything more than a around 2 bytes x 14 pixels (or so). My ASM wasn't the most efficient though, so I'm sure guys here could get a bit more out of it. I do remember using lookup tables to draw to the screen though. Wish we had access to the internet back then. I had to rely on the odd magazine like Softtalk to help me out....

Fantavision also has a 10x14 px mouse cursor. I should RE/rip that mouse display graphics code someday ...

Michael.

I am Rob

unread,
Mar 21, 2023, 6:32:20 PM3/21/23
to
I use the 4-byte wide color cursor in dbl-hi-res mode. it's big but it gets the job done.


> For example :
>
> $2000 : BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD
> $2010 : BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD
>
> Waiting Routine :
>
> TOP_SCREEN LDA $C070
> CMP $#BD
> BNE TOOP_SCREEN
>
> You need several pattern because the LDA / CMP /BNE takes few cycles and you can miss the BD. With sevral ones, you will catch it without any doubt.
>

I still have questions regarding the sync bytes and vbl.
Does this work on both hi-res screens?

And on a IIe with the $C019 soft switch, Instead of racing the beam (or staying ahead of the refresh), isn't it better to start drawing when the beam is finished refreshing and is at the bottom of the screen, about to go up, and start drawing to the screen then. Doesn't this do the same thing but offers a little more time to draw to the screen before the screen gets updated on the next time around? This surely would allow the computer instructions to stay ahead of the next refresh cycle.

mmphosis

unread,
Mar 23, 2023, 10:33:13 AM3/23/23
to
> Does this work on both hi-res screens?

For HGR2, change the $2000 addresses to $4000 addresses and BIT $C055 before
the wait routine.

> And on a IIe with the $C019 soft switch, Instead of racing the beam (or
> staying ahead of the refresh), isn't it better to start drawing when the
> beam is finished refreshing and is at the bottom of the screen, about to
> go
> up, and start drawing to the screen then. Doesn't this do the same thing
> but offers a little more time to draw to the screen before the screen gets
> updated on the next time around?

Timing is everything and is fraught with peril.

http://www.deater.net/weave/vmwprod/megademo/cycle_switching.html

https://rich12345.tripod.com/aiivideo/softalk.html

https://web.archive.org/web/20150706084550/http://hoop-la.ca/apple2/2015/winterwarmup/





0 new messages