[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Introduction to to Graphics in C on the Apple II
Bill Buckels wrote:
On Jan 7, 9:25 pm, "John B. Matthews" <nos...@nospam.invalid> wrote:
And both optimize by using a base address lookup table. I wanted to
compare your approach with an example of using static linking in cc65; I
had the link, but forgot the example!
The lookup table trick avoided many calculations for me over the last
30 years. I highly recommend precalculating everything that one can.
This is probably just common-sense to most of us but I appreciate that
you have recognized how this technique can be applied to saving
precious instructions on these tiny processors:)
And tables are an excellent example of the time-space tradeoff
in action. If space is more important than speed, calculation is
good.
Both give a single-load binary and yours is fast and cross-OS. I would
say the results are exemplary. Thanks!
When one is using tiny processors (not only old C compilers) optimal
techniques seem to become honed razor-sharp as we also know. A good
example is the ballistic speed that cc65 works when compared to Aztec
C which was pretty damned good by the end of its life cycle.
I just wanted to post the alternative to that lookup table that you
refer to (see below)so I remember to make a note of this somewhere...
too many instructions... that's the thing for us to remember... this
is actually part of the code that I used in 1980-something to create
the table for the hi-res display:
/* provides base offset for hires scanlines */
/* does not bother to check whether we are in range */
/* gets the address as quickly as possible */
/* stays away from processor intensive mul and div */
gethibase(currentline,currentbase)
int currentline;
int *currentbase;
{
FILE *fp;
int ybase=0,z,a;
if(currentline >63)
{
if (currentline < 128)
{
ybase+=0x28;
currentline-=64;
}
else
{
ybase+=0x50;
currentline-=128;
}
}
z=(currentline>>3);
a = (z<<7)|ybase;
*currentbase = (currentline - (z<<3))<<10 | a;
/*
fp = fopen("hb.txt","a");
fprintf(fp,"%d,", *currentbase);
if (currentline%8 == 0) fprintf(fp,"\n");
fclose(fp);
*/
}
I suspect the "base calculation" is both smaller and faster in
assembly language:
* Hi-res base address calculation. This comes from
* the HPOSN routine at $f411.
*
* Put the line in A. The result is placed in $26-27,
* offset from address 0. X and Y are not disturbed.
*
* You must OR $20 or $40 into $27 to select the hi-res
* page.
bascalc pha
and #$c0
sta hbasl
lsr
lsr
ora hbasl
sta hbasl
pla
sta hbash
asl
asl
asl
rol hbash
asl
rol hbash
asl
ror hbasl
lda hbash
and #$1f
sta hbash
rts
(From Andy McFadden's fast graphics routines, taken in turn from
the Applesoft HPOSN routine.)
Bit fiddling of this kind has always been the "poster child" for
high-level language inefficiency, though it is seldom needed in
practice. In Apple II graphics, it finds its way into the inner
loop (unless two pages of memory are used for a table)!
-michael
NadaNet and AppleCrate II: parallel computing for Apple II computers!
Home page: http://home.comcast.net/~mjmahon
"The wastebasket is our most important design
tool--and it's seriously underused."