Applesoft Hi-Res Routines
by Neil Parker
=========================

The following zero-page locations are used by the hi-res routines:
X0L	EQU	$E0	;Low-order byte of X coordinate
X0H	EQU	$E1	;Hi-order byte of X coordinate
Y0	EQU	$E2	;Y coordinate
HCOLOR	EQU	$E4	;Color masking word from table at $F6F6:
			;black1= $0
			;green = $2A = %00101010
			;purple= $55 = %01010101
			;white1= $7F = %01111111
			;black2= $80 = %10000000
			;orange= $AA = %10101010
			;blue  = $D5 = %11010101
			;white2= $FF = %11111111
HPAG	EQU	$E6	;Page where plotting will be done:
			;page 1 = $20, page 2 = $40
SCALE	EQU	$E7	;Scale for DRAW and XDRAW
COLLSN	EQU	$EA	;Collision count for DRAW and XDRAW
SHAPEL	EQU	$1A	;Shape definition pointer
SHAPEH	EQU	$1B
*
HCOLOR1 EQU	$1C	;HCOLOR, shifted to account for even/odd columns
HBASL	EQU	$26	;Pointer to first byte of current line
HBASH	EQU	$27
HNDX	EQU	$E5	;INT(X coordinate / 7)
HMASK	EQU	$30	;Bit position mask cooresponding to X coord MOD 7
			;taken from table at MSKTBL ($F5B2)

Also used are $1D, $D0-D5, $E3, $E8-E9.

The routines:

HGR	EQU	$F3E2
Inputs: none
Outputs: zero-page pointers initialized for page 1

This is the entry point for the BASIC HGR command.  It clears and displays
page 1, and initializes it for drawing.

HGR2	EQU	$F3D8
Inputs: none
Outputs: zero-page pointers initialized for page 2

This is the entry point for the BASIC HGR2 command.  It clears and displays
page 2, and initializes it for drawing.

SETHCOL EQU     $F6F0
Inputs: X = color number (0-7)
Outputs: HCOLOR ($E4) = color mask

Convert a standard Applesoft hi-res color number into the corresponding
color mask.  This subroutine is the same as
        LDA     $F6F6,X
        STA     HCOLOR
but you can save a couple of bytes by calling SETHCOL instead of using the
above instructions.

HCLR	EQU	$F3F2
Inputs: HPAG ($E2) = page to be cleared
Outputs: none

Clear the current hi-res page to black.  The page need not be displayed.

BKGNDO	EQU	$F3F4
Inputs: A = color mask of desired color
Outputs: none

Clear the current hi-res page to the desired color.  The page need not be
displayed.

BKGND	EQU	$F3F6
Inputs: HCOLOR1 ($1C) = color mask of desired color
Outputs: none

A later entry point to the previous routine.

HPOSN	EQU	$F411
Inputs: A = Y coordinate
        X = low byte of X coordinate
        Y = hi byte of X coordinate
        HCOLOR ($E4) = color mask
	HPAG ($E6) = page to plot on
Outputs: HBASL, HBASH ($26,27) = base address of line
         HNDX ($E5) = offset to byte containing pixel
         HMASK ($30) = mask byte for pixel
         HCOLOR1 ($1C) = shifted color mask
         X0L ($E0) = low byte of X-coordinate
         X0H ($E1) = hi byte of X-coordinate
         Y0 ($E2) = Y-coordinate

Compute the memory address and mask of a pixel.

HFIND	EQU	$F5CB
Inputs: HBASL, HBASH ($26,27) = base address of line
        HNDX ($E5) = offset to byte containing pixel
        HMASK ($30) = mask byte for pixel
Outputs: X0L ($E0) = low byte of X-coordinate
         X0H ($E1) = hi byte of X-coordinate
         Y0 ($E2) = Y-coordinate

This routine is the inverse of HPOSN.  Given the memory address and mask
for a pixel, compute its coordinates.

HPLOT	EQU	$F457
Inputs: A = Y-coordinate
	X = low byte X-coordinate
	Y = hi byte X-coordinate
	HCOLOR ($E4) = color mask
	HPAG ($E6) = page to plot on
Outputs: same as HPOSN

Plot a point at the given coordinates, in the given color.

HPLOT1	EQU	$F45A
Inputs: HCOLOR1 ($1C) = shifted color mask
        HMASK ($30) = mask byte for pixel
        HBASL, HBASH ($26,27) = base address of line
        Y = offset into line of byte containing pixel
Outputs: none

This is the most primitive plotting routine.  It plots a pixel at the given
location, using the following code:
	LDA	HCOLOR1
	EOR	(HBASL),Y
	AND	HMASK
	EOR	(HBASL),Y
	STA	(HBASL),Y
	RTS

HLIN	EQU	$F53A
Inputs: A = ending point X-coordinate low byte
	X = ending point X-coordinate hi byte
	Y = ending point Y-coordinate
	X0L ($E0) = starting point X-coordinate low byte
	X0H ($E1) = starting point X-coordinate hi byte
	Y0 ($E2) = starting point Y-coordinate
	HPAG ($E6) = page to plot on
	HBASL, HBASH ($26,27) = base address of line of starting point
	HMASK ($30) = mask byte for starting pixel
	HNDX ($E5) = offset into line of byte containing starting pixel
	HCOLOR1 ($1C) = shifted color mask
Outputs: X0L...HCOLOR1 set up according to last point plotted

Draw a line between two points.  The usual calling sequence is to first
call HPOSN or HPLOT to fix the starting point, and then call HLIN to draw
the line.  This automatically sets up the information in X0L...HCOLOR1, so
the programmer does not usually need to supply this information.  A series
of lines can be drawn like this:
     call HPOSN to fix the starting point
     call HLIN to draw to the second point
     call HLIN to draw to the third point
     call HLIN to draw to the fourth point
     etc...

If the information in X0L, X0H, Y0 (the "external coordinates") does not
match the information in HBASL...HCOLOR1 (the "internal coordinates"), then
an offset occurs in the plotting:  draw an imaginary line from the
"external coordinates" to the ending point, and then move this imaginary
line parallel to itself so that the "external coordinate" point is on top
of the "internal coordinate" point.  Plot the resulting line.  (This
feature is used by the next call, which simply sets the "external
coordinates" to (0,0) and falls into HLIN.)

HLINRL	EQU	$F530
Inputs: A = ending point X-coordinate low byte
	X = ending point X-coordinate hi byte
	Y = ending point Y-coordinate
	HPAG ($E6) = page to be plotted on
	HBASL, HBASH...HCOLOR1 = same as for HLIN
Outputs: X0L...HCOLOR1 set up according to last point plotted

Plot a line relative to the previous point plotted.  The ending point
should be specified as if the previous point plotted were the origin of a
new temporary coordinate system.  This call may be of limited usefulness,
since the ending point coordinates are unsigned, and it therefore only
appears possible to go down and to the right.

DRAW	EQU	$F601
Inputs: A = rotation value (0-$3F)
	X = pointer to shape definition, low byte
	Y = pointer to shape definition, hi byte
	SCALE ($E7) = scale factor (1 = smallest, 0 interpreted as 256)
	HPAG ($E6) = page to be plotted on
	HBASL...HCOLOR1 = same as for HLIN
Outputs: HBASL...HCOLOR1 set up according to last point plotted
         COLLSN ($EA) = number of pixels that changed while drawing

Draw an Applesoft shape.  As with HLIN, this call usually follows a call to
HPOSN or HPLOT to fix the starting point, so it will not usually be
necessary for the programmer to set up HBASL...HCOLOR1 manually.  The
X and Y registers should not point to a full Applesoft shape table, but
rather to one of the shapes within the table.  After calling DRAW, you can
find out where you've been left by calling HFIND.

DRAW1	EQU	$F605
Inputs: A = rotation value (0-$3F)
	SHAPEL, SHAPEH ($1A,1B) = pointer to shape definition
	SCALE ($E7) = scale factor (1 = smallest, 0 interpreted as 256)
	HPAG ($E6) = page to be plotted on
	HBASL...HCOLOR1 = same as for HLIN
Outputs: same as DRAW

This is an alternate entry point to DRAW.  It can be used when there is
only a single shape to be drawn, as the SHAPEL, SHAPEH pointer need only be
initialized once.  This saves the step of loading the pointer into X and Y
prior to a call to DRAW.

XDRAW	EQU	$F65D
Inputs: Same as for DRAW (except that the color is ignored)
Outputs: Same as DRAW

Xdraw an Applesoft shape.  This call works exactly the same as DRAW, except
that it draws the shape by XORing onto the screen rather than drawing it in
the current color.

XDRAW1	EQU 	$F661
Inputs: Same as DRAW1 (except that the color is ignored)
Outputs: Same as DRAW1

This is an alternate entry point to XDRAW.  It has the same relationship to
XDRAW that DRAW1 has to DRAW.

LEFT	EQU	$F467
Inputs: HMASK ($30) = Mask byte for current pixel
	HNDX ($E5) = Offset into line of byte containing current pixel
	HCOLOR1 ($1C) = shifted color mask
Outputs: See below

Given a pixel (in "internal coordinates"), this routine calculates HMASK,
HNDX, and HCOLOR1 for the pixel immediately to the left.  If this would
move the pixel off the left edge of the display, it wraps around to the
right edge.  The output data replaces the input data.

RIGHT	EQU	$F48A
Inputs: same as for LEFT
Outputs: see below

This routine functions just like LEFT, but it moves to the right instead of
to the left.  Wrap-around occurs at the right edge of the display.

UP	EQU	$F4D5
Inputs: HBASL, HBASH ($26,27) = address of current line
Outputs: see below

Given the address of a line of the display, this routine calculates the
address of the line immediately above it.  Wrap-around occurs at the top of
the display.  The output data replaces the input data.

DOWN	EQU 	$F504
Inputs: HBASL, HBASH ($26,27) = address of current line
	HPAG ($E6) = current hi-res page
Outputs: see below

Given the address of a line of the display, calculate the address of the
line immediately below it.  Wrap-around occurs at the bottom of the
display.  The output data replaces the input data.

LEFTRT	EQU	$F465
Inputs: same as for LEFT/RIGHT
        N flag--see below
Outputs: same as LEFT/RIGHT

If the processor N (negative) flag is set, move LEFT, otherwise move RIGHT.

UPDWN	EQU	$F4D3
Inputs: same as for UP/DOWN
	N flag--see below
Outputs: same as UP/DOWN

If the processor N (negative) flag is set, move DOWN, otherwise move UP.

LRUD	EQU	$F4D1
Inputs: same as for LEFT/RIGHT and UP/DOWN
	N and C flags--see below
Outputs: same as LEFT/RIGHT and UP/DOWN

Move LEFT, RIGHT, UP, or DOWN according to the processor N (negative) and C
(carry) flags:

     N C  Move
     - -  ----
     0 0  UP
     0 1  RIGHT
     1 0  DOWN
     1 1  LEFT

Note that LEFT, RIGHT, UP, DOWN, LFTRT, UPDWN, and LRUD only move--they do
not plot.

The entry points corresponding to the Applesoft tokens are different from
the above, as the token handlers must generally parse parameters from the
program text.  This makes them somewhat less useful than the above
routines, but for the curious, here they are:

HGR2	$F3D8
HGR	$F3E2
HCOLOR= $F6E9
HPLOT	$F6FE
DRAW	$F769
XDRAW	$F76F
ROT=	$F721
SCALE=	$F727
SHLOAD	$F775 (not present on all Apples)

Sources:

C. K. Mesztenyi, "Notes on Hi-Res Graphics Routines in Applesoft,"
_Apple_Orchard_, Spring 1981.  This describes many of the Applesoft hi-res
routines in considerable detail.  Several routines are given different
names from the above.

Apple Computer, Inc. (from contact John Crossley), "Applesoft Internal
Entry Points," _The_Apple_Orchard_, March/April 1980.  A large listing of
internal Applesoft routines, including some of the graphics routines.
Has a few errors.

The Programmer's Aid No. 1 Reference Manual (I think that's what it's
called--I have only a few photocopied pages) contains Steve Wozniak's
original commented source code for the hi-res routines in the Programmer's
Aid No. 1 ROM.  It appears that this source code was used almost verbatim
by the authors of Applesoft.  I have used the labels and routine names from
this listing.  (If you have the DOS 3.3 System Master, then you have a copy
of the Programmer's Aid No. 1 ROM...it lives in the language card along
with Integer BASIC, from $D000 to $D7FF.)

Obligatory Disclaimer:  Although I have expended some effort in collecting
and verifying the above information, I cannot guarantee its accuracy or
freedom from typos.

	  - Neil Parker