[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."