The Apple II hi-res screen sits on 8KB of memory, so it should be possible to erase it quickly. The Applesoft HGR command is slow enough that the "Venetian blind" erasure is clearly visible. Clearing the screen to a color with CALL 62454 feels even slower. Why is this?
- 9,040
- 1
- 30
- 84
1 Answers
If you look at the screen clear code in the Applesoft BASIC ROM, you'll find this:
f3f6 lda $e6 ;put base address of current hi-res page
sta $1b ; into $1a/1b (will be $2000 or $4000)
ldy #$00
sty $1a
f3fe lda $1c ;get color value
sta ($1a),y ;store it in frame buffer
jsr $f47e ;update color value
iny ;advance, looping...
bne $f3fe
inc $1b
lda $1b
and #$1f
bne $f3fe ;...until we get to $4000/$6000
rts
f47e asl ;lose the hi bit, now $00/$fe for black/white,
cmp #$c0 ; or $54/$aa for green/purple/orange/blue
bpl $f489 ;branch if black or white
lda $1c
eor #$7f ;invert color bits for odd/even
sta $1c
f489 rts
This is a ROM routine, so size is at a premium, and self-modifying code is not allowed. It's optimized for space, not speed.
The most significant impact of this optimization choice is the code at $f47e, which tests the color value and potentially updates it for every byte. This code is necessary because of the rather strange hi-res graphics layout, which (among other oddities) represents an odd number of pixels with each byte. So while a solid black line is 00 00 00 00 ..., a solid green line is 2a 55 2a 55 .... The high bit doesn't change, hence the exclusive-OR with $7f. (The code at $f47e is shared with other routines, e.g. the line-drawing code, that must update the color when moving across the screen.)
The total time required to erase the screen to black is 271,121 cycles. Clearing to green would require 328,465 cycles.
The fastest possible screen clear would write a byte to 7680 addresses -- it's not 8192 because we don't need to overwrite the "screen holes". On a 6502, that requires 4 cycles per byte, or about 30720 cycles. The code to do that would fill about half of available RAM on an Apple II though.
A 192-byte unrolled loop can do it in about 39480 cycles. That's ~5x the code, for ~8x the speed.
While these approaches are faster, they still have the "Venetian blind" look. While that's something of an Apple II hallmark, not everyone wants that, and it may not be possible to simply show page 2 while you're erasing page 1. In a mere 127 bytes, for ~41,300 cycles you can erase the screen from right to left, using a clever function written by John Brooks.
- 9,040
- 1
- 30
- 84
HGRalways clears to black? Or is this routine more general than that, allowing for arbitrary colors when filling? It seems to me you could clear screen to black very quickly in a very small routine, even taking into account memory holes. – paxdiablo Mar 21 '22 at 03:18