sys7.1-doc-wip/Libs/InterfaceSrcs/PrGlue.a
2019-07-27 22:37:48 +08:00

590 lines
26 KiB
Plaintext

;
; File: PrGlue.a
;
; Contains: Printing Glue
;
; Copyright: © 1990, 1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <4> 2/20/92 DTY _PrGlue is now in Traps.a.
; <3> 7/17/91 JL File Header was screwed up.
; <2> 9/18/90 gbm Get rid of stupid end statement at the end of the file, and fix
; the file that includes us, PrintCalls.a
;
; To Do:
;
;
; PrGlue.a
;
; This file requires that a symbol inROM be defined
; outside of it.
;
; File created
; 7/13/85 Leo from old PrLink
;
; Modified
; 7/16/85 Leo Fixed bug with stripping return values
; Removed PrCfgDialog
; Fixed values in PrGlueTable
; 8/06/85 Leo Added calls to SetVol/GetVol
; 8/17/85 Leo Integrated PrScreen, went to single
; Trap and selector.
; 9/10/85 Leo New trap files, added GoSetVol
; Changed this file to PrGlue.a
; no include files
; 17Sep85 Leo Converted to Ira's New Assembler
; 17Mar86 Bayles Fixed Function call bugs (PrError).
; A little more efficient.
; 8/1/86 David Added PrGeneral call
; 21Aug86 Bayles Fixed Bug in PrSetError. Error now placed in d0
; rather than in $944. LLOut then sets $944 from d0.
; 24Sep86 Bayles Increased PDEFID capability by swapping FuncByte
; and PDEFid fields of the selector dispatch longword.
; 15Oct86 Jay Fixed bug in PurgePr and NoPurgePr. Check the lower byte of
; flags to see if the driver is RAM based.
; 06Nov86 Jay Fixed bugs in PrDrvrDCE and PrDrvrVers. Put the result
; on the stack at (sp) instead of at 12(a6). Then, jump to GlueOut
; instead of LLOut. Changed Bra.s at PrOCerr to Bra.
; 18Dec86 Jay If the GetResource call to get a PDEF fails, don't give up.
; The printer resfile may not be in the resource search path. Save and restore
; the user resource map around the GetResource (for PDEF) call.
; Get the printer resfile refnum from the
; low memory print var ($944+$E) or open the printer resource file to get it.
; After opening the printer resource file, save the refnum in low memory.
; The code to get the printer resfile refnum is now in a procedure called OpenRF.
; Check the print error after _PrDrvrOpen call in PrintOpen.
; 13Feb87 Jay 1). Fixed a BAD bug with stack corruption on error exit if the printer resource
; file does not exist in the system folder.
; - In OpenRF, return _OpenRFPerm error in d0
; - Removed ResErr check after OpenRF call under OpenPrRF. The error is already in d0.
; - Under OpenPrRF, if we have an error from OpenRF, put that error in low memory and
; branch to GlueAbort. It used to bne to LLOut.
; - Cleaned up GlueOut to eliminate call to _BlockMove.
; 2). Don't close the driver during PrClose. Close the resource file only.
; This is to eliminate the overhead of going thru .Print everytime.
; NOTE: The old PrLink used to leave the driver open. It must have been changed when
; PrLink was changed to PrGlue (I think!).
; - Removed call to _PrDrvrClose from PrintClose.
; 20Feb87 Jay 1). Restore user's res file ref num before jumping into the print code. This was
; done after comming back from the print code. The reason for this fix is that by
; leaving curMap pointing to us we might kick the application out ofthe resource
; search path. What if we need a resource out of the application file while we are
; inside the print code?
; 2). Also, under PrintOpen, Move PrintVars+iPrErr to d0 instead of testing it.
; This is because if PrDrvrOpen failed then it puts the error is in low memory but D0
; (which is also the error) gets written over on the way out from PrDrvrOpen.
; PrintOpen tests low memory and if it is an error, goes to LLOut which puts D0 in
; low memory! D0 at this point is bad and the application does not get the correct
; error code.
; 3). Save curMap in a3 before getting the PDEF resource the first time.
; 10Jun87 Jay If the PrGlue trap is installed then go ahead and use it, otherwise
; fall thru and use the linked code. If an application uses Printing
; Manager thru calls and links with this glue then it is guaranteed to work
; on all machines (including the 512k) running any system file.
;
;
; This code is the printing glue for 128K ROM printing
; calls. In this ROM, there is a single trap for printing,
; which is this code. This code takes the selctor, which
; is the last parameter to every printing call, and
; dispatches to the correct routine.
;
; There are two types of printing routines: those related
; to the high-level (PrOpenPage, etc.) interface, and
; those related to the low-level (driver calls) interface.
; The low-level interface calls are also referred to as
; 'non-link' routines throughout the comments, for reasons
; which totally escape me.
;
; The high-level interfaces are handled as one block,
; collectively referred to as PrGlue. These routines
; simply fetch the appropriate PDEF resource from the
; current printer resource file, and jsr to a certain
; offset into the resource. Which PDEF to use and
; how far into the PDEF to Jsr to are recorded in
; PrGlueTable, along with useful information like
; the number of bytes of parameters and return value
; there are for each entry. This information is used
; to allow PrGlue to build a stack frame for the routine
; and call the PDEF, after which it copies the return
; information back up on the stack and returns.
;
; The non-link routines are mostly calls on the
; .Print driver. They get themselves a iopb and
; make the call, or twiddle some aspect of the
; driver. The routines that fool with the DCE
; of the driver or the handle to the driver itself
; get the DCE by making a Status call on the
; driver, and pulling the DCEPtr out of the CSParam
; area of the iopb.
;
; PrOpen and PrClose are high-level routines that
; do not dispatch to a PDEF. They are responsible
; for opening/closing the current printer resource file.
; They also Open/Close the .Print driver.
;
; These routines are called with a final parameter,
; in addition to the ones listed in Inside Mac.
; As the last parameter, they take a longword
; full of information. The format of this long
; is like so:
;
; 31 23 15 7 0
; +--------+--------+--------+--------+
; |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
; +--------+--------+--------+--------+
; Bits 31-27: Selector for the various routines in the glue
; Bits 26-24: Number of bytes of function result for this routine
; (must be either 0, 2, or 4)
; Bits 23-16: ID of PDEF to call for high level routines
; Bits 15-08: The number of bytes of parameters
; to this routine
; Bit 07: 1 if the PDEF should be unlocked after
; the call (high level routines)
; Bits 06-00: The offset into the PDEF to Jsr to
; (high level routines)
; 31 23 15 7 0
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | | | | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | | | | |
; | Result Bytes | | Unlock Flag |
;Routine Selector PDEF ID Parameter Bytes PDEF Offset
;
;
; Routine Selector value
; ------- -------- -----
; (high-level routines)
; PrOpenDoc 0
; PrCloseDoc 1
; PrOpenPage 2
; PrClosePage 3
; PrintDefault 4
; PrStlDialog 5
; PrJobDialog 6
; PrStlInit 7
; PrJobInit 8
; PrDlgMain 9
; PrValidate 10
; PrJobMerge 11
; PrPicFile 12
; PrHack 13
; PrGeneral 14
; (low-level and 'non-link' routines)
; PrDrvrOpen 16
; PrDrvrClose 17
; PrDrvrDCE 18
; PrDrvrVers 19
; PrCtlCall 20
; PrPurge 21
; PrNoPurge 22
; PrError 23
; PrSetError 24
; PrOpen 25
; PrClose 26
;
BLANKS ON
STRING ASIS
PrintCalls PROC EXPORT
;
; A few constants regarding selector values:
PrDocLimit EQU 3 ; Highest selector for doc loop routine
PDEFLimit EQU 15 ; Highest selector for high-level (PDEF-calling)
; routines
;
; PrGlue Entry points are below. The idea of this entry setup is to allow PrGlue
; to determine what entry point was used in very little code space. The Bsr.s
; pushes the return address on the stack, which PrGlue then uses to derive which
; entry point was used. The key is that the entry points here are arranged in
; the same order as the table PrGlueTable, below.
;
; Constants: Offsets into the PrGlue information
Selectr EQU 8+0 ; Selector for routine invoked (Most significant 5 bits)
FuncByt EQU 8+0 ; Bytes of function result (Least significant 3 bits)
PDEFId EQU 8+1 ; ID of the PDEF to call (8 bits)
ParmByt EQU 8+2 ; Bytes of parameters (8 bits)
CodeOfs EQU 8+3 ; Offset into the PDEF of the code for this function (7 bits)
;
; Parameters to the Glue:
longAt EQU 8 ; Offset from a6 of longWord o'info
;
; PrGlue itself
; If the PrGlue trap is installed, use it, otherwise use the linked code.
Move.l a3,-(sp) ; Save a3
Move.l #$A89F, d0 ; Trap number for _UnImplTrap
_GetTrapAddress ;
Move.l a0, a3 ; Save it in a3
Move.l #$A8FD, d0 ; Trap number for _PrGlue
_GetTrapAddress ;
Cmp.l a0, a3 ; Are the two addresses same?
Beq.s UseGlue ; Yes, the PrGlue trap is not installed. Use the linked code.
Move.l (sp)+, a3 ; No, the trap is installed, restore a3 and use the trap.
; Copy the parameters, control long word and return value of the routine down onto the stack again
Link a6,#0 ; Stack frame, Only to execute the trap
Lea 8(a6),a0 ; Address of the control long word on the stack
Moveq #7,d0 ; Get bytes of param + bytes of return value + bytes in the
and.b FuncByt(a6),d0 ; Control long word (4) in d0.
Add.b ParmByt(a6),d0 ; Together, these are the number of bytes to copy.
Add.b #4, d0 ; The Control long word.
Sub.w d0,sp ; We know the thing isn't actually more than a word wide
Move.l sp,a1 ; Beginning of destination
_BlockMove ; Make a copy. Note: Leaves d0 = 0
_PrGlue ; Use the trap.
; We have executed the Printing Manager routine, restore the stack and return.
; Get the number of bytes of parameter to this entry in d1
Moveq #0,d1
Move.b ParmByt(a6),d1 ; Get from the table, source of all knowledge...
; Copy the function value, if any, back up to the caller's stack frame
Moveq #7,d0 ; We're going for # bytes function value in d0
and.b FuncByt(a6),d0 ; Got 'em
Beq.s NoRetVal1
Move.l sp,a0 ; The function left its result on top of stack
Lea 12(a6,d1),a1 ; The place we want to go is after the original params.
Lsr.w #1, d0 ; Convert to word
Bra.s @1 ; Copy the function result where the app expects it
@2 Move.w (sp)+, (a1)+ ;
@1 Dbf d0, @2 ;
NoRetVal1
Unlk a6 ; get rid of the stack frame used while executing the trap
Move.l (sp)+,a0 ; Return address
Adda.l d1,sp ; Strip params
Addq #4,sp ; Strip glue parameter
Jmp (a0) ; ...and we're out
UseGlue
Move.l (sp)+, a3 ; Restore a3 and fall thru to execute the linked code.
; Start of the linked PrGlue
Link a6,#0 ; Stack frame, no local variables
Movem.l a3-a4,-(sp) ; Save the regs we will use to hold info across
; the call to the actual print routine
; Get selector in d1
Moveq #0,d1
Move.b Selectr(a6),d1 ; Get the byte containing it
Lsr.b #3,d1 ; Move selector over
Beq.s OpenDocOnly ; PrOpenDoc has a bunch of special case code, so don't
; get the ID the way we do it normally
; If it's a low-level call, dispatch to that stuff
Tst.b Selectr(a6) ; Test the selector: high-level or low-level?
Bmi LowLevel ; Send the low-level calls off to thier corner
; Get Id of PDEF that this call will be dispatched to in d2
Moveq #0,d2 ; Put mask for PDEFId in d2
Move.b PDEFId(a6),d2 ; Get PDEF Id from Glue Parameter.
Bne.s GetPDEF ; If that's nonzero, it's the id. If it's zero,
; the id should be gotten from printing globals
Moveq #3,d2 ; Mask for PrintLoop type from Globals. This
; is also the PDEF Id to use
And.b PrintVars+bDocLoop,d2 ; Get that info into d2
Bra.s GetPDEF ; ...and go to it
OpenDocOnly
; For OpenDoc, we get the print loop type, which is the PDEF Id, from
; the print record passed by the caller as a parameter.
Move.l 20(a6),a0 ; Get handle to print record
Move.l (a0),a0 ; Deref Handle
Moveq #3,d2 ; Mask for doc loop type
And.b PrJob+bJDocLoop(a0),d2 ; Mask off them bits
Andi.b #$FC,PrintVars+bDocLoop ; Clear out those two bits in PrintVars
Or.b d2,PrintVars+bDocLoop ; and put the new bits in
;
; Get that PDEF
GetPDEF
Move.w CurMap, a3 ; <20Feb87> save user's resfile refnum in a3
Clr.l -(sp) ; Room for the GetResource result
Move.l #'PDEF',-(sp) ; Type
Move d2,-(sp) ; id
_GetResource
Move.l (sp)+,d0
Tst.l d0 ; Test the result of GetResource
Bne.s GotPDEF ; we have the PDEF
; CurMap may be set to point to the user's res file. We need to set it to point to our resfile.
; Check the low memory global iPrRefNum. If it is $FFFF (i.e is not used and is initialised)
; then open the printer resource file to get our refnum. Otherwise use the refnum stored in the
; low memory global to call _UseResFile. Check the result of this call, if it failed then open
; the printer resource file to get our ref num.
Cmpi.w #$FFFF, iPrRefNum ; is our refnum in low memory?
Beq.s OpenPrRF ; no, open the printer resource file
Move.w iPrRefNum, -(sp) ; Try _UseResFile on this refnum
_UseResFile
Tst.w ResErr ; Did it work?
Beq.s GetRsrc ; yes, go get the PDEF from this resource file
OpenPrRF
Bsr OpenRF ; Open our res file
Tst.w d0 ; success?
Beq.s Continue ; <13Feb87> JNP yes, continue
Move.w d0, PrintVars+iPrErr ; <13Feb87> JNP no, set error and get out.
Bra GlueAbort ; <13Feb87> JNP
Continue ; <13Feb87> JNP
Move.w iPrRefNum, -(sp)
_UseResFile ; our resfile is opened, now let's use it.
GetRsrc
Clr.l -(sp) ; Room for the GetResource result
Move.l #'PDEF',-(sp) ; Type
Move d2,-(sp) ; id
_GetResource ; get that PDEF
Move.l (sp)+,d0
Tst.l d0 ; Test the result of GetResource
Bne.s GotPDEF
; Can't get the resource... set PrError, and jump down to the return point
Move.w a3, -(sp) ; User's res file refnum
_UseResFile ; Restore user's Resource map. Refnum is on the stack.
Move.w #resNotFound,PrintVars+iPrErr
Bra GlueAbort
;
GotPDEF
Move.l d0,a4 ; Transfer the handle to an a-reg
Move.l a4,a0 ; Lock that baby down
_HLock
;<20Feb87> Restore curMap before jumping into the print code.
Move.w a3, -(sp) ; <20Feb87> user's resfile refnum
_UseResFile ; <20Feb87> Restore user's Resource map.
; Copy the parameters and return value of the routine down onto the stack again
Lea 12(a6),a0 ; Start of old parameters
Moveq #7,d0 ; Get bytes of param + bytes of return value in d0
and.b FuncByt(a6),d0 ; Together, these are the number of bytes to copy
Add.b ParmByt(a6),d0
Sub.w d0,sp ; We know the thing isn't actually more than a word wide
Move.l sp,a1 ; Beginning of destination
_BlockMove ; Note: Leaves d0 = 0
; Call the routine. The offset into the PDEF to jump to is given by the glue parameter
Move.b CodeOfs(a6),d0 ; Get offset (note high part of d0 is still 0)
Andi.b #$7F,d0 ; Mask off the unlock bit that is stored there
Move.l (a4),a0 ; Deref PDEF handle
Jsr 0(a0,d0) ; Call the routine
; Unlock the PDEF if the unlock bit from PrGlueTable is set
Move.b CodeOfs(a6),d0 ; The unlock bit is the high-order bit of this byte, so...
Bpl.s NoUnlock
Move.l a4,a0
_HUnlock ; make it float again
NoUnlock
Bra GlueOut
;
; All the low-level routines are implemented here
LowLevel
; Allocate and set up for .Print call a iopb on
; the stack
Sub #IOQElSize,sp ; Get an iopb
Lea PrintName,a0 ; Address of .Print string
Move.l a0,ioFileName(sp) ; Put in iopb
Move #iPrDrvrRef,ioRefNum(sp) ; Put refNum in iopb
Clr.b ioPermssn(sp) ; Always a good idea
Move.l sp,a0 ; Put pointer in a0
; The selector is in d1. We're gonna do a jump table on
; it. After the jump table, everybody should branch
; back to LLOut.
Moveq #0,d0 ; Since LLOut uses d0 as a return code,
; let's make sure it's something reasonable
Bclr #4,d1 ; We don't want the high bit
Add d1,d1 ; Shift selector left one
Move LLJump(d1),d1 ; Get jump table entry
Jmp LLJump(d1) ; Go to correct entry
LLJump
DC.W DrvrPrOpen-LLJump ; PrDrvrOpen 16
DC.W DrvrPrClose-LLJump ; PrDrvrClose 17
DC.W DrvrDCE-LLJump ; PrDrvrDCE 18
DC.W DrvrVers-LLJump ; PrDrvrVers 19
DC.W CtlCall-LLJump ; PrCtlCall 20
DC.W PurgePr-LLJump ; PrPurge 21
DC.W NoPurgePr-LLJump ; PrNoPurge 22
DC.W GetError-LLJump ; PrError 23
DC.W SetError-LLJump ; PrSetError 24
DC.W PrintOpen-LLJump ; PrOpen 25
DC.W PrintClose-LLJump ; PrClose 26
DC.W LLBadParam-LLJump ; not implemented 27
DC.W LLBadParam-LLJump ; not implemented 28
DC.W LLBadParam-LLJump ; not implemented 29
DC.W LLBadParam-LLJump ; not implemented 30
DC.W LLBadParam-LLJump ; not implemented 31
LLBadParam
Move #paramErr,PrintVars+iPrErr ; Yes, say params in error
GlueAbort
Moveq #0,d1 ; Get the number of bytes of parameter to this entry in d1
Move.b ParmByt(a6),d1 ; Get from the glue parameter, source of all knowledge...
Bra PrExit
PrintOpen
_PrDrvrOpen ; Open the .Print driver
Move.w PrintVars+iPrErr, d0 ; <20Feb87> Move the error into d0
BNE.S PrOCerr ;abort if error.
MOVEQ #0, D1 ;Mark Call Open
BRA.S PrOCcom
PrintClose
; 13Feb87 JNP Removed call to _PrDrvrClose.
MOVEQ #1, D1 ;Mark Call close
PrOCcom
Bsr OpenRF ; Open the printer resource file
Tst.w d0 ; success?
Bne.s PrOCerr ; no, get out
; Test result of OpenResFile
Move.w iPrRefNum, d0 ; get the refnum in d0
Tst.w ResErr
Bne.s @26
;Now return for opens, or close the resfile with the id
;found above if closing.
TST.W D1 ;Open Call?
BEQ.S @26 ;Yes: Go home
MOVE.W D0,-(SP) ;No: CloseResFile. Push the refnum param
_CloseResFile
@26
Move ResErr,d0
PrOCerr
Bra LLOut
DrvrPrOpen
_Open ; Do the open
Bra.s LLOut ; and out
DrvrPrClose
_Close ; Do the close
Bra.s LLOut ; and out
DrvrDCE ;
Bsr.s GetDCEHandle ; Get DCE handle in a0
add.w #IOQELSize-4, sp ; Leave room for the DCEHandle
Move.l a0, (sp) ; Move the handle to the stack,
; Glueout will pick up the value and adjust the stack
Bra.s GlueOut ; get out
DrvrVers ;
Bsr.s GetDCEHandle ; Get DCE handle in a0
Move.l (a0),a0 ; Deref it
Moveq #0, d0
Move.b DCtlQueue+1(a0),d0 ; Get the version byte
add.w #IOQELSize-2, sp ; Leave room for one word
Move.w d0, (sp) ; Move the version# to the stack,
; Glueout will pick up the value and adjust the stack
Bra.s GlueOut ; Get out
CtlCall
Move.l 12(a6),csParam+8(a0) ; lParam3
Move.l 16(a6),CSParam+4(A0) ; lParam2
Move.l 20(a6),CSParam(A0) ; lParam1
Move 24(a6),CSCode(A0) ; iWhichCtl
_Control
Bra.s LLOut ; and out
PurgePr
Bsr.s GetDCEHandle ; Get DCE handle in a0
Move.l (a0),a0 ; Deref DCE handle
Btst #dRAMBased,dCtlFlags+1(a0) ; Is this a RAM-based driver?
Beq.s LLOut ; No? Well then it's not gonna purge
Move.l DCtlDriver(a0),a0 ; Get driver handle
_HPurge ; make purgeable
Bra.s LLOut
NoPurgePr
Bsr.s GetDCEHandle ; Get DCE handle in a0
Move.l (a0),a0 ; Deref DCE handle
Btst #dRAMBased,dCtlFlags+1(a0) ; Is this a RAM-based driver?
Beq.s LLOut ; No? Well then it's won't purge anyway
Move.l DCtlDriver(a0),a0 ; Get driver handle
_HNoPurge ; make non purgeable
Bra.s LLOut
GetDCEHandle
Move #1,csCode(a0) ; The old get-the-DCE status call
_Status
Move.l csParam(a0),a0 ; Get DCE Handle
Rts
GetError
add.w #IOQElSize-2,sp ; Strip parameter block except for one word
Move.w PrintVars+iPrErr,(sp) ; Get error code
Bra.s GlueOut
SetError
Move 12(a6),d0 ; Set the error code
;
; LLOut: All the low-level routines return here, with
; their error code in d0.
LLOut
Add #IOQElSize,sp ; Strip parameter block
Move d0,PrintVars+iPrErr ; Set return code
GlueOut
;
; Get the number of bytes of parameter to this entry in d1
Moveq #0,d1
Move.b ParmByt(a6),d1 ; Get from the table, source of all knowledge...
; Copy the function value, if any, back up to the caller's stack frame
Moveq #7,d0 ; We're going for # bytes function value in d0
and.b FuncByt(a6),d0 ; Got 'em
Beq.s NoRetVal
Move.l sp,a0 ; The function left its result on top of stack
Lea 12(a6,d1),a1 ; The place we want to go is after the original params
Lsr.w #1, d0 ;
Bra.s @1 ;
@2 Move.w (sp)+, (a1)+ ;
@1 Dbf d0, @2 ;
NoRetVal
PrExit
;
; Unwind our stack frame and strip the params (# bytes params still in d1)
Movem.l (sp)+,a3-a4
Unlk a6
Move.l (sp)+,a0 ; Return address
Adda.l d1,sp ; Strip params
Addq #4,sp ; Strip glue parameter
Jmp (a0) ; ...and we're out
;
; Subroutines for PrGlue
;
; GetDefDrive returns the default volume refNum in d0.
; GoSetVol sets the current default volume to the vRefNum
; in d0.
;
GetDefDrive ;get the default drive into D0
MOVEQ #0,D0
GoSetVol ;set the default drive to D0.
SUB #ioVQElSize,SP ;make room for _SetVol parm block
MOVE.L SP,A0
MOVE D0,ioVDrvNum(A0) ;pass the drive number
CLR.L ioVNPtr(A0) ;nil name pointer
_SetVol
_GetVol
MOVE ioVDrvNum(A0),D0 ;get back the drive number
ADD #ioVQElSize,SP ;pop off the frame
RTS ;return without error check
;
;Open printer resource file. Get the printer name from the system resource file (resid $E000)
;First get the name of the current printer's resource file from Sys.Rsrc.
;Returns GetString error in d0 and printer resfile refnum in the low memory global iPrRefNum
;
OpenRF
Subq #4,sp ; Make room for rsrc handle
Move.W #$E000,-(sp) ; ID for RsrcFile name
_GetString
Move.L (sp)+,d0 ; Get the RsrcFile name handle
Bne.S @13 ; Go around if we got something
Move.w #resNotFound,d0 ; I think it's an error
Bra.s GetOut ; Get out
@13
Move.L d0, a1 ; Save the resource handle
; Save the current default volume, and set it to the system volume Leo 8/85
Bsr.s GetDefDrive ; Get volume in d0
Swap d1 ; Swap d1 halves
Move.w d0,d1 ; Save in d1
;Open the printer resource file.
Subq #2,sp ; Make room for rsrc refnum
Move.l a1,a0 ; Lock down the name
_HLock
Move.L (a1),-(sp) ; Deref string handle into stack
_OpenResFile ; open the res file
; Leave refNum on stack
Move.w (sp)+, iPrRefNum ; save the refnum in low memory.
Move.l a1,a0 ; More handle happiness
_HUnlock ; UnLock the name handle
; Reset default volume
Move.w d1,d0 ; Put saved vRefNum in d0
Swap d1 ; Restore d1
Bsr.s GoSetVol ; Put default volume back
Move.w ResErr, d0 ; Return _OpenResFile error
GetOut
Rts
;
; Data for PrGlue
;
; Name of the .Print driver
STRING PASCAL
PrintName
DC.B '.Print '
ALIGN 2
;