[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Apple II Graphics Programming (Assembly)



On 8 Jul., 18:38, Mark Calderbank <nos...@test.com> wrote:
>
> I'm not sure about this. Aren't there screen holes at 78-7F as well
> as F8-FF?

According to the Apple IIe TechNote #10 you are right!
This TN handles the IIe-card for the Mac LC and I quote:

---
Notes:
1. The "Screen-Hole" areas in the above address ranges do
    not trap.
    These are the $xx78-7F and $xxF8-FF address ranges in the
    display areas.
---

This makes sense as
- 240 bytes of each page x 32 pages = 7680 bytes
and
- 40 bytes per hires-line x 192 lines = 7680 bytes!


> Assuming my memory's right, I can come up with three options.
>
> If you have tons of code space, you can do the thoughtless thing
> and just double the loop length:
>
> LDA #0
> LDY #$77
> a STA $2000,Y  (5)
> STA $2080,Y  (5)
> ...
> STA $3F00,Y  (5)
> STA $3F80,Y  (5)

> DEY  (2)
> BPL a  (2/3)

You'd need a branch over a "JMP a" combo at the end as the
unrolled loop would be larger than the branch range...
(64 STA instructions with 3 bytes each = 192 bytes)

About 39600 cycles in total with a JMP and not counting
the register setup at the beginning of the routine - but about
200 bytes of code (400 bytes if you need both hires pages)...


> Or you can do something like what Calibrator said but skip
> over the middle hole along the way:

Sounds interesting!

> LDA #0
> LDY #0
> a STA $2000,Y  (5)
> ...
> STA $3F00,Y  (5)

> INY  (2)
> CPY #$F8  (2)
> BEQ end  (2/3)
> CPY #$78  (2)
> BNE a  (2/3)
> LDY #$80  (2)
> BNE a  (2/3)
> end

The 32 STAs run effectively 240 times x 5 cycles = 38400.
Add to that the stuff beginning with the INY and you'll get:
1 x 7 cycles ($F8 condition)
1 x 15 cycles ($78 condition)
238 x 11 cycles (first BNE successful)
= 2640 cycles
Which results in a total of 41040 cycles.

(I'm probably wrong with the loops but it should be close
enough ;-)

Paul's "standard unrolled version" uses a total of 42239 cycles,
though, as the loop runs 256 times.

With my $F8 check (which still fills about half the holes) it
would need about 40919 cycles...


> Or involve the X register and run the same loop twice with different
> index values but the same exit condition:
>
> LDA #0
> LDY #$77

> b LDX #$77

> a STA $2000,Y
> STA $2100,Y
> ...
> STA $3F00,Y
> DEY  (2)
> DEX  (2)
> BPL a  (2/3)

> CPY #$7F  (2)
> BEQ end  (2/3)
> LDY #$F7  (2)
> BNE b  (always 3)

> end

I hate cycle counting in nested loops - especially when
decrementing! ;-)

The a-loop runs 240 times = 38400+1679 = 40079
Special case #1 (Y=$7F) = +5 cycles (once)
Special case #2 (Y=$FF after DEY) = +11 cycles (once)
= total 40095 cycles (I hope...)

About 2000 cycles faster than Paul's routine (5%) - not very
eye-friendly but perhaps the best trade-off, isn't it?

bye
Marcus