Author: Dan Hitchens, Matt Deatherage & Suki Lee
Year: 1988
... describes the routines and internal structures needed to design a printer driver for the Apple IIgs system.
Apple II
Technical Notes
_____________________________________________________________________________
Developer Technical Support
Apple IIgs
#35: Printer Driver Specifications
Revised by: Matt Deatherage September 1990
Written by: Dan Hitchens, Matt Deatherage & Suki Lee May 1988
This Technical Note describes the routines and internal structures needed to
design a printer driver for the Apple IIgs system, and you should use this
Note with the Apple IIgs Toolbox Reference manuals. An overview and
associated parameters for each of the printer driver routines are in the Print
Manager chapter, and you should refer to these for a complete picture.
Changed since March 1990: Added corrections and further descriptions.
_____________________________________________________________________________
Printing Modes
There are two printing modes: immediate and deferred.
o In immediate mode, pages are printed as they are drawn into the
printing grafPort. As the application makes QuickDraw II calls,
the printer driver immediately generates commands, transferring
ink to page when the page is closed. This is the fastest form of
printing, but only produces high-quality images on printers that
can translate QuickDraw II commands to other graphic commands.
For example, the LaserWriter driver translates the QuickDraw II
calls into PostScript(R) calls which can produce high-quality
images.
o In deferred mode (sometimes referred to as spool mode), pages are
captured to memory or disk and printed after all pages have been
defined. Most printer drivers use deferred mode to create high-
quality images. Since most drivers cannot obtain enough memory to
image an entire page at once, they redraw page in several pieces,
or bands. The printer driver creates a grafPort whose boundsRect,
portRect, clipRgn, and visRgn correspond to the band and plays the
picture back, thus causing the saved commands to draw only the
images which fall within the band. Once the pixel image for the
band is created, the printer driver converts the image to printer
codes and sends the codes to the printer through the port driver.
File Structure
The user can install new printer drivers into the system by copying a printer
driver file into a subdirectory called DRIVERS within the SYSTEM subdirectory.
The printer driver file must be of type $BB and have an auxiliary type of
$0001.
Print Driver Calls
A printer driver must support the following calls:
PrDefault $0913 Sets print record to default
PrValidate $0A13 Validates print record
PrStlDialog $0B13 Performs a style dialog
PrJobDialog $0C13 Performs a job dialog
PrPixelMap $0D13 Prints a pixel map
PrOpenDoc $0E13 Opens the document
PrCloseDoc $0F13 Closes the document
PrOpenPage $1013 Opens a page
PrClosePage $1113 Closes a page
PrPicFile $1213 Prints a picture file
--RESERVED-- $1313
PrError $1413 Gets the error value
PrSetError $1513 Sets the error value
GetDeviceName $1713 Gets device's name
PrDriverVer $2313 Gets installed driver version
Printer drivers may support the following calls if they use the new driver
structure outlined below:
PrGetPrinterSpecs $1813 Returns printer type and characteristics
PrGetPgOrientation $3813 Returns page orientation
Print Driver Entry
o For older drivers, entry is at the first byte (no offset). For newer
(Print Manager 3.0 and later) drivers, the first word is $0000, indicating
a new style driver. The next word is a count of how many calls this driver
supports. All drivers must support the minimum call set. Additional calls
must be supported in the sequence listed (for example, if a driver supports
PrGetPgOrientation, it must also support PrGetPrinterSpecs).
o The Print Manager places an index to the correct routine in the X register
(see the example and note the specific ordering of the routines) .
o There are two long return addresses (six bytes) that have been pushed onto
the stack. (You must take these addresses into account to access the
parameters and to return correctly.)
Example
StartOfNewDriver START
dc i2'0' ; new style driver
dc i2'(ListEnd-PrDriverList)/4' ; count
jmp (PrDriverList,x)
PrDriverList dc a4'PrDefault'
dc a4'PrValidate'
dc a4'PrStlDialog'
dc a4'PrJobDialog'
dc a4'PrDriverVer'
dc a4'PrOpenDoc'
dc a4'PrCloseDoc'
dc a4'PrOpenPage'
dc a4'PrClosePage'
dc a4'PrPicFile'
dc a4'InvalidRoutine'
dc a4'PrError'
dc a4'PrSetError'
dc a4'GetDeviceName'
dc a4'PrPixelMap'
dc a4'PrGetPrinterSpecs'
dc a4'PrGetPgOrientation'
ListEnd anop
In previous versions of this Note, the PrPixelMap and PrDriverVer entries were
reversed.
Note that when using the above technique, you're using a 16-bit jump into a
table of 24-bit addresses. If all your entry points are in the same segment,
this is not a problem.
If your routines' entry points are not all in the same segment, you need a
dispatching routine like the following:
StartOfNewDriver START
dc i2 '0' ; new style driver
dc i2 '(ListEnd-PrDriverList)/4' ; count
lda PrDriverList+2,x
sep #$20
pha ; push high byte of
; address
rep #$20
lda PrDriverList,x
dec a ; decrement low 2
; bytes only
pha ; push modified low
; word of address
rtl ; transfer to the
; routine
See Apple IIgs Technical Note #90, 65816 Tips and Pitfalls, for a discussion
of dispatching with RTL.
Print Driver Exit
When one of your routines is ready to exit, it needs to remove the input
parameters from the stack, leaving the result space (if any) and the two RTL
addresses. Set the accumulator and the carry flag to reflect any error you
are returning, then perform an RTL.
Example
If there are N bytes of input parameters to remove, use something like the
following. This code assumes that the error code is in the accumulator.
tay ; keep error code in Y
; temporarily
lda 5,s
sta N+5,s
lda 3,s
sta N+3,s
lda 1,s
sta N+1,s
tsc
clc
adc #N
tcs
tya ; get error code
cmp #1 ; set carry if error
; is not zero
rtl
Figure 1 diagrams the stack just before exiting the print driver:
|
| Previous Contents
|___________________
|
| Results (if any)
|___________________
|
| RTL2 (3 bytes)
|___________________
|
| RTL1 (3 bytes)
|___________________
<-- Stack Pointer
Figure 1-Stack Prior to Exiting the Print Driver
You should do an RTL with the contents of the flags and registers set
appropriately. (See the Return from Call section of the "Using The Apple
Tools" chapter of the Apple IIgs Toolbox Reference.)
Print Record Structure
Since application programs often need to fiddle with parts of the print record
(i.e., the values in the style subrecord), we have defined ways for
applications to interpret the print record, and specifically the style
subrecord.
iDev, the first word of the printer information subrecord, has two defined
values for third-party printer drivers. A value of $8001 indicates a dot-
matrix printer while a value of $8003 indicates a laser printer.
A value of $8001 indicates that fields of the style subrecord should be
interpreted as they are by the ImageWriter driver, as documented in the Apple
IIgs Toolbox Reference. The first seven bits (0-6) of wDev are defined as for
the ImageWriter driver. Bits 7-11 are reserved for Apple's use and must be
set to zero. Bits 12-15 may be used by third-party printer drivers as
necessary; these bits are set to zero in Apple's drivers.
A value of $8003 indicates that fields of the style subrecord should be
interpreted as they are by the LaserWriter driver. The first four bits (0-3)
of wDev are defined as for the LaserWriter driver. Bits 4-11 are reserved for
Apple's use and must be set to zero. Bits 12-15 may be used by third-party
printer drivers as necessary; these bits are set to zero in Apple's drivers.
If an application wishes to take advantages of specific features of a third-
party printer driver, it has to know that it is dealing with that driver.
Since all drivers look pretty much alike, the Print Manager allows you to ask
for the name of the currently selected printer driver. An application may
make the Print Manager call PMGetPrinterName, which is documented in Volume 3
of the Toolbox Reference. The Print Manager returns the name of the currently
selected printer in a Pascal (length byte) string. The name returned is the
name of the file from which the driver was loaded. If you intend to use this
method to identify a driver, you must inform users not to rename the Printer
Driver file on the boot disk.
For alternate driver identification, Developer Technical Support assigns new
iDev values if you feel it is absolutely necessary for your driver. Please
keep in mind, however, that no application knows how to interpret style
records for non-standard iDev values, and that Apple does not publish such
interpretations.
Print Driver Calls
Your printer driver handles the following calls:
PrDefault ($0913)
Description:
Fills the fields of the specified print record with default values for the
printer.
Passed:
PrintRecordHandle LONG Handle to the print record
Returned:
None
Performs the following:
o Validates that PrintRecordHandle is a handle and does nothing if not.
o Determines the default values for the print record either through tables or
calculations. The default values should take into account such things as
paper size and orientation, print mode, printer type, etc.
o Copies the default values to the print record specified by the
PrintRecordHandle parameter.
PrValidate ($0A13)
Description:
Checks the print record to see that it is valid for the currently installed
printer driver.
Passed:
PrintRecordHandle LONG Handle to the print record
Returned:
ChangeFlag WORD Boolean; TRUE if the record is
adjusted
Performs the following:
o Checks to see if the print record is from this particular driver.
o If the print record is not from this driver, it uses the default values for
this driver.
o If the print record is from this driver, it makes any changes that might be
needed (i.e., style, paper size, etc.).
PrStlDialog ($0B13)
Description:
Performs a style dialog with the user.
Passed:
PrintRecordHandle LONG Handle to the print record
Returned:
ConfirmFlag WORD Boolean; TRUE if the dialog is
confirmed
Performs the following:
o Conducts a style dialog with the user to determine the page dimensions and
other information needed for page setup (the initial settings of the dialog
are derived from the print record).
o If the user confirms the dialog, the information from the dialog is saved
in the specified print record, PrValidate is called, and the routine
returns TRUE.
o If the user cancels the dialog, the print record is left unchanged, and the
routine returns FALSE.
Note: The following are items typically found in printer style dialogs:
o Paper Size (US Letter, US Legal, A4 Letter, B5 Letter, International
Fanfold)
o Printing Orientation (Landscape, Portrait)
o Vertical Sizing (Normal, Intermediate, Condensed)
o Special Effects:
Font Effects (Font Substitution, Smoothing)
Reduction or Enlargement
Gaps or No Gaps between pages
Every printer style dialog should have an OK button (default) and a Cancel
button.
Note: When calling other routines in your printer driver (like
PrValidate), be sure to do so through the Tool Dispatcher ($E10000
or $E10004) so any necessary patches have an opportunity to execute.
PrJobDialog ($0C13)
Description:
Performs a job dialog with the user.
Passed:
PrintRecordHandle LONG Handle to the print record
Returned:
ConfirmFlag WORD Boolean; True if the dialog is
confirmed
Performs the following:
o Conducts a job dialog with the user to determine the print quality, range
of pages to print, and other specifications. The initial settings are
derived from the previous PrJobDialog call (or initial default values)
except the page range which is set to ALL, and the number of copies which
is set to ONE.
o If the user confirms the dialog, PrValidate is called, the print record is
updated, and the routine returns TRUE.
o If the user cancels the dialog, the print record is left unchanged, and the
routine returns FALSE.
Note: The following are items typically found in printer job dialogs:
o Print Quality (Best, Faster, Draft, etc.)
o Color option
o Pages (All, Range)
o Copies
o Paper Source (paper cassette, manual feed)
Every printer job dialog should have an OK button (default) and a Cancel
button.
Note: When calling other routines in your printer driver (like
PrValidate), be sure to do so through the Tool Dispatcher ($E10000
or $E10004) so any necessary patches have an opportunity to
execute.
PrPixelMap ($0D13)
Description:
Prints all or part of the specified pixel map.
Passed:
srcLocPtr LONG Pointer to the source LocInfo
which contains the pointer to
the pixel map.
srcRectPtr LONG Pointer to the rectangle which
encloses the pixel map to be
printed.
colorFlag WORD Boolean; FALSE if black and white,
TRUE if color.
Returned:
None
Performs the following:
o Calls DevIsItSafe (port driver call) to verify that the port it functioning
and it is safe to proceed. If it is not functioning, set the internal
error code to $1302 (Port Not On) and return with an error status.
o Saves the current grafPort.
o Turns on the watch cursor to signal the user that it will take some time.
o Clears the internal error code (default, if no errors occur).
You can choose to print the pixel map in any convenient fashion; one
convenient way is to allocate a new print record and call your normal printing
routines. This method is outlined below.
o Gets a new handle for a print record and set it to the defaults by calling
PrDefault.
o If colorFlag is set, change the style subrecord of the print record to
reflect color printing.
o Do any initialization that might be needed by the driver.
o Determine the intersection of the two rectangles (rectangle pointed to by
srcRectPtr and the pixel map's boundary rectangle from srcLocPtr) and if
there is no intersection, then nothing is to be printed.
o Print the pixel image which is within the intersection of the two
rectangles.
o Cause a page eject to occur on the printer.
o Do any clean up that is needed.
o Turn off the watch cursor by calling InitCursor (or restore the previous
cursor using SetCursor).
o Restore the grafPort by calling SetPort.
PrOpenDoc ($0E13)
Description:
This routine initializes the things needed to open a document. In deferred
mode, it establishes a grafPort and makes it the current port for printing.
Passed:
PrintRecordHandle LONG Handle to the print record
PrinterPortPtr LONG Pointer to the grafPort, if
desired, zero to allocate a new
grafPort
Returned:
PrinterPortPtrRet LONG Pointer to the grafPort if the
PrinterPortPtr was zero
Performs the following:
o Calls DevIsItSafe (port driver call) to verify that the port is functioning
and it is safe to proceed.
o Turns on the watch cursor to signal the user that it will take some time.
o Validates the print record passed by calling PrValidate.
o Clears the internal error code (default, if nothing happens).
o Puts up a dialog indicating that printing is occurring (or preparing to
print).
o If the user needs a grafPort, create one and internally note that one was
created (PrCloseDoc needs to know that one was created here).
o Initializes parameters (i.e., page number, document number, etc.).
o If deferred mode, create an initial page list (an array of handles to
pictures) for recording pages. You can pick an arbitrary number to start
with (like 20). This assumes spooling to memory; spooling to disk will
obviously be different.
o Do other initialization that might be needed to start a print job.
Possible errors:
portNotOn $1302 Indicates Port Not On
PrCloseDoc ($0F13)
Description:
Closes the grafPort being used for printing. For immediate mode, this
routine ends the printing job. For deferred mode, this routine ends the
recording of the document to be printed.
Passed:
PrintGrafPortPtr LONG Pointer to the grafPort used for
printing
Returned:
None
Performs the following:
o Checks that the last print driver call did not cause a Port Not On error.
If the error occurred, do nothing and return.
o Call ClosePort to close the printing grafPort.
o If the driver allocated a grafPort in PrOpenDoc, disposes of it.
o If in immediate mode, does what is needed to shut things down.
o Takes down the information dialog box from PrOpenDoc.
Possible errors:
portNotOn $1302 Indicates Port Not On
prBozo $13FF Someone unloaded the driver in
the middle of the print loop
PrOpenPage ($1013)
Description:
Begins a new page only if the page falls within the page range specified in
the job subrecord.
Passed:
PrintGrafPortPtr LONG Pointer to the grafPort used for
printing
PageFramePtr LONG Pointer to the scaling parameter,
zero for none.
Returned:
None
Performs the following:
o Looks at the driver's internal error value, and if an error has occurred,
it returns without doing anything.
o Increments the page number.
o Calls SetPort to make the specified port the current port.
o Initializes the port and zeroes the boundary rectangle so no actual drawing
occurs.
o If immediate mode, then do the following:
If this page is to be printed, install immediate mode procedures by
doing the following:
o Create a procedure table (get the standard procedures from
SetStdProcs).
o Put pointers to your procedures into the table and call the
QuickDraw II routine SetGrafProcs. This causes QuickDraw II calls
to call your routines instead of drawing to the pixel map
associated with the grafPort.
o If deferred mode, then do the following:
o If the current page is out of the page range, then return without
doing anything further.
o If the user passes his own PageFramePtr , then get it.
o Open a picture by calling OpenPicture and adding its handle to the
page list array described in PrOpenDoc.
o Set the ClipRgn and VisRgn to the sizing framing rectangle specified
by PageFramePtr , or if none was specified, to the default of rPage.
Possible errors:
portNotOn $1302 Indicates Port Not On
prBozo $13FF Someone unloaded the driver in
the middle of the print loop
PrClosePage ($1113)
Description:
This signals the end of a page.
Passed:
PrintGrafPortPtr LONG Pointer to the grafPort used for
printing
Returned:
None
Performs the following:
o Looks at the driver's internal error value and if a Port Not On error has
occurred, it returns without doing anything.
o If immediate mode, do the following:
o If the current page is within the range of pages to be printed, then
cause a form feed (unless no gap was specified).
o If deferred mode, do the following:
o If there was no picture generated, then do nothing and just return.
o Restore the grafPort to the port saved in PrOpenPage.
o Do a ClosePicture to close the picture.
Possible errors:
portNotOn $1302 Indicates Port Not On
prBozo $13FF Someone unloaded the driver in
the middle of the print loop
PrPicFile ($1213)
Description:
Prints a picture file generated in deferred mode.
Passed:
PrintRecordHandle LONG Handle to the print record
PrintGrafPortPtr LONG Pointer to the grafPort used for
printing
StatusRecPtr LONG Pointer to the printer status
record
Returned:
None
Performs the following:
o Looks at the driver's internal error value and if a Port Not On error has
occurred, it returns without doing anything.
o If immediate mode, return without doing anything.
o If deferred mode, then do the following:
o If the error code is not zero (errors) then dispose of all the recorded
page images.
o Put up an information dialog indicating that printing is occurring.
o Display a watch cursor (saving the current cursor first if you like).
o If PrintGrafPortPtr is NIL, create one and make a note of it.
o Call OpenPort to make the grafPort the current port.
o If StatusRecPtr is NIL, use an internal one. This is to simplify your
code; if the StatusRecPtr is NIL, you can reasonably choose not to use a
status record at all, but this requires an extra code path.
o Initialize the status record and the number of copies counter.
o If the idle procedure pointer in the print record is NIL, point to an
internal one. Again, as with the StatusRecPtr, you can choose to ignore
idle procedures if no pointer is provided, but this requires an extra
code path.
o Do The Following For Each Copy:
o Calculate the number of bands to print one page and initialize the
page counter.
o Do The Following For Each Page:
o Call the idle procedure routine and initialize the band counter.
o Get the handle to the picture associated with the current page.
o Set the dirty flag in the status record to FALSE.
o If manual paper feed, put up a dialog and wait for a response.
o Do The Following For Each Band:
o Call the idle procedure.
o Calculate the band rectangle and update iCurBand with the
current band number.
o Call the idle procedure again.
o Set the imaging flag in the status record to TRUE.
o Call InitPort to reinitialize the port.
o Adjust fields in the port to cause drawing into the band
buffer.
o Adjust fields in the location information field of the status
record and calculate the sizing rectangle.
o Calculate the boundary rectangle for the band and set the port
rectangle to it.
o Set the ClipRgn and the VisRgn to the sizing rectangle.
o Initialize the band by filling it with white space.
o Call DrawPicture to draw the picture into the band's
rectangle.
o Do whatever is needed to print the pixel image in the band's
rectangle.
o Clear the imaging flag.
o Calculate the next band's position.
o Increment the band's counter and loop back if not done.
o If a vertical gap was specified, cause a form feed.
o Increment the page count to the next page and loop back if not
done.
o Increment the number of copies counter and loop back if not done.
o Free any buffers that you own and close the port.
o Dispose of the information dialog that you put up.
o Dispose of each picture in the picture list by calling KillPicture.
o Dispose of the picture list itself.
o Restore the cursor.
Possible errors:
portNotOn $1302 Indicates Port Not On
prBozo $13FF Someone unloaded the driver in
the middle of the print loop
PrError ($1413)
Description:
Gets the error code from the last Print Manager call.
Passed:
None
Returned:
LastError WORD Result code from last Print
Manager call
Performs the following:
o Gets the driver's internal error value (which was determined by the last
driver call) and sets the return parameter LastError to it.
Possible Errors:
noError $0000
PrAbort $0080 Indicates print job was aborted
$1301 Indicates missing drivers
$1302 Indicates Port Not On
$1303 Indicates No Print Record
$1306 Indicates PAP Connection Not
Made
$1307 Indicates Read/Write PAP Error
$1308 Indicates Printer Connection
Failed
prBozo $13FF Someone unloaded the driver in
the middle of the print loop
PrSetError ($1513)
Description:
Sets the error value.
Passed:
ErrorNumber WORD Error number to be set
Returned:
None
Performs the following:
o Sets the driver's internal error value to the value of the passed
ErrorNumber parameter.
GetDeviceName ($1713)
(also known as PrChanged)
Description:
Used as a communications tool between the printer driver and port driver.
Passed:
None
Returned:
None
Performs the following:
o Calls the port driver routine PrDevPrChanged with the printer name as
input. This is necessary for drivers that work over AppleTalk. The name
passed as the parameter to PrDevPrChanged should be what AppleTalk uses in
an NBPLookup situation; for AppleTalk, such a name should follow Name
Binding Protocol conventions.
This routine will be called by the Print Manager when your driver is first
loaded so a network port driver can find devices of your type.
Applications should not make this call. When this routine will be called
is not guaranteed; you can't use this as a substitute for a startup call.
PrDriverVer ($2313)
Description:
Returns the version number of the currently installed printer driver.
Passed:
Wordspace WORD Space for results
Returned:
versionInfo WORD Printer driver's version number
Performs the following:
o Gets the internal version number of the printer driver and returns it on
the stack at versionInfo.
Note: The internal version number is stored major byte, minor byte
(i.e., $0103 represents version 1.3)
PrGetPrinterSpecs ($1813)
Description:
Returns the type of printer and the printer's characteristics.
Passed:
Wordspace WORD Space for results
Wordspace WORD Space for results
Returned:
PrinterType WORD 0 = undefined
1 = ImageWriter or ImageWriter II
2 = ImageWriter LQ
3 = LaserWriter family
(except IIsc)
4 = Epson
$8001 = generic dot matrix printer
$8003 = generic laser printer
PrCharacteristics WORD Bits 15-2 = reserved, must be zero
Bits 1-0: 00 = cannot determine
01 = black and white
only
10 = color capable
Performs the following:
o Returns characteristics intrinsic for the printer being supported.
The value returned for PrinterType should be the driver's iDev value.
PrGetPgOrientation ($3813)
Description:
Returns the page orientation from a print record.
Passed:
Wordspace WORD Space for result
PrintRecordHandle LONG Handle to the print record
Returned:
PgOrientation WORD Current page orientation:
0 = portrait
1 = landscape
Performs the following:
o Returns the page orientation from the current page setup information in the
print record.
Immediate Mode Procedures
To print in the immediate mode, you need to install procedures which cause
printing when you make QuickDraw II calls (as noted in PrOpenPage). This
section describes the structure and parameters for these routines.
The basic idea is that your driver replaces low-level QuickDraw II routines
with pointers to your own routines. For example, when someone wants QuickDraw
II to draw some text (say with DrawString), QuickDraw II calls your low-level
routine to draw the text. You can then print the text instead.
To install the immediate mode procedures, first create a procedure table for
sixteen entries (16*4 bytes) and fill it with the standard procedures by
calling SetStdProcs. Once you have the standard procedures, install the
addresses of your replacement procedures into it and call SetGrafProcs.
Installing your procedure addresses causes the appropriate QuickDraw II calls
to call your procedures, which, in turn, perform the actual printing.
The routines that need to be written are known as QuickDraw II "bottleneck
procedures." For most dot-matrix printer drivers, the one of most concern
when writing immediate mode procedures is StdText. If your target device has
an alternate page imaging language, you may wish to print entirely in
immediate mode. In this case, you want to intercept most of the bottleneck
procedures. Apple IIgs Technical Note #34, Low-Level QuickDraw II Routines,
contains information on how to install these procedures. The sample code
which follows shows how to replace StdPixels and StdText.
Example:
;*****************************************************************
;** Example of Immediate Mode Printer Procedures. **
;*****************************************************************
Immedprocs Start
SrcRect equ $DC
SrcLocInfo equ $CC
DrawVerb equ $38
TextPtr equ $da
TextLength equ $d8
CharToDraw equ $d6
;------------------------------------------------------------------
;
; StdPixels Procedure (Prints Pixel maps)
;
;------------------------------------------------------------------
Pixel Entry
phb ;save data bank reg on stack
phk ;get program bank reg.
plb ;use as data bank reg.
lda iPrErr ;get errors
beq Continue ;branch if none
brl ExitPixel ;branch if errors
Continue anop
;This gets the source rectangle and stores it at PixelRect
ldx #6
MoveSrc lda SrcRect,x
sta PixelRect,x
dex
dex
bpl MoveSrc
;This gets the source LocInfo and stores it at PixelLoc
ldx #16-2
MoveLI lda SrcLocInfo,x
sta PixelLoc,x
dex
dex
bpl MoveLI
pushlong #PixelLoc ;push pointer to LocInfo
pushlong #PixelRect ;push pointer to rectangle
;++++++++++++++++++++++
; Insert code here to print a pixel map
; INPUT: PixelLoc LONG, Pointer to pixel LocInfo
; PixelRect LONG, Pointer to pixels BoundsRect
; SP->
;++++++++++++++++++++++
Exitpixel lda #0 ;return with no errors
clc
plb ;restore data bank
rtl ;return with long
PixelLoc ds 16 ;pixel LocInfo
PixelRect ds 8 ;pixel rectangle
;------------------------------------------------------------------
;
; StdText Procedure (Prints Standard Text)
;
;------------------------------------------------------------------
StdText Entry
phb ;save data bank reg on stack
phk ;get program bank reg.
plb ;use as data bank reg.
pushlong #PenPos
_GetPen ;current pen pos. -> PenPos
;++++++++++++++++++++++
; Insert Code Here to move the printers head to the corresponding
; PenPos position (if needed).
;++++++++++++++++++++++
pushword #0 ;space for textwidth
;(for call to _TextWidth)
lda DrawVerb ;get DrawVerb
beq DoCar ;if DrawVerb=0 then DoCar
cmp #1
beq Dotext2 ;if DrawVerb=1 then Dotext2
;
;We get here if it's a "C" string (DrawVerb=2)
;
DoCstring anop
sep #$20
longa off
;Search down through string looking for terminator to calc. length
ldy #0
KeepLooking lda [TextPtr],y
beq TheEnd
iny
bra KeepLooking
TheEnd rep #$20
longa on
lda TextPtr+2
pha ;push the pointer to string
lda Textptr
pha
phy ;push the length of sting
bra Common
;
;We get here if it's just one character (DrawVerb=0)
;
DoCar anop
pushword #0
tdc
clc
adc #CharToDraw ;calculate addr. of char.
pha ;push addr. of character
pushword #1 ;push length of one char.
bra Common
;
;We get here if it's a string of text (DrawVerb=1)
;
DoText2 anop
lda TextPtr+2
pha ;push pointer to the string
lda Textptr
pha
lda TextLength
pha ;push the strings length
Common lda 5,s ;Dup the last 3 words of
pha ;the stack (for _TextWidth)
lda 5,s
pha
lda 5,s
pha
;++++++++++++++++++++++
; Insert code here to print the text
;
; INPUT: TextPointer LONG, Pointer to text to print
; TextLength WORD, No. of bytes to print
; SP->
;++++++++++++++++++++++
_TextWidth ;get the texts width (DH)
pushword #0 ;set (DV)=0
_Move ;move current pen location
ExitText lda #0 ;return with no errors
clc
plb ;restore data bank
rtl ;returnith long
PenPos ds 4 ;pen position
end
Further Reference
_____________________________________________________________________________
o Apple IIgs Toolbox Reference, Volumes 1-3
o Apple IIgs Technical Note #36, Port Driver Specifications
o Apple IIgs Technical Note #90, 65816 Tips and Pitfalls
PostScript is a registered trademark of Adobe Systems Incorporated.