mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-10-06 15:58:28 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
766 lines
31 KiB
Plaintext
766 lines
31 KiB
Plaintext
;
|
|
; File: PrintGlue.a
|
|
;
|
|
; Contains: This code is the printing glue for 128K ROM printing
|
|
;
|
|
; Copyright: © 1985-1993 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM4> 6/28/93 kc Roll in Ludwig.
|
|
; <LW2> 6/25/93 fau (with mal and chp): If the PDEF is 32 bytes or less, go flush
|
|
; the cache, in case the developer is using the PDEF as a stub and
|
|
; stuffing their own code.
|
|
; <SM3> 11/5/92 SWC Changed PrEqu.a->Printing.a and
|
|
; PrintCallsEqu.a->PrintTrapsEqu.a.
|
|
; <SM1> 6/15/92 CSS Take out forRom and CubeE conditionals because the forRomed code is old
|
|
; and this is CubeE. The net effect of which is to make printing work
|
|
; on SuperMario!!!!!
|
|
; <17> 12/16/91 IH Fix 1018177 in theFuture. Search for symbol "PURGEALIAS". Do
|
|
; not release the print driver alias and make it non-purgable
|
|
; before calling ResolveAlias.
|
|
; <16> 11/27/91 DTY DonÕt save LastSPExtra around _HOpenResFile any more now that
|
|
; _HOpenResFile checks to see if the font caches should be
|
|
; flushed.
|
|
; <15> 10/4/91 gbm #1013134,#1013156: Work around a case where the font caches
|
|
; would get flushed repeatedly during printing
|
|
; <14> 3/6/91 NB Bug: NB-3. Reviewed by csd. An earlier fix to error handling
|
|
; caused the error to not be overwritten if it was already set.
|
|
; However, since PrOpen doesn't reset the error to noErr at
|
|
; startup, any printing error that stays in low-mem after closing
|
|
; the printing manager prevents subsequent printing calls. Now
|
|
; PrOpen (actually PrOpenDrvr) will reset the error to noErr
|
|
; before opening the driver.
|
|
; <13> 3/5/91 PN Fix the warning by putting back the END statement at the end
|
|
; <12> 3/1/91 NB If the resource for the alias is not found, then we would
|
|
; normally return resNotFound. The glue used to return fnfErr
|
|
; whenever it couldn't open the driver and applications have coded
|
|
; for that error. Rather than add an error code, we map
|
|
; resNotFound to fnfErr and save the user some grief. We also put
|
|
; PrError into D0 at exit. This is needed because PrLoadDriver
|
|
; returns the error in D0.
|
|
; <11> 2/21/91 NB Bug: NB-2. Reviewed by dba. Fixed a bug in PrLoadDriver in which
|
|
; it was overwriting the error. This would occasionally cause a
|
|
; cancel request from the user (iUsrAbort) to be replaced with
|
|
; noErr. Now it preserves the error if the error is already set.
|
|
; <10> 8/9/90 CCH Added System 6 print glue back in, conditionalized for ROM only.
|
|
; <8> 8/1/90 gbm fix Darin ÒBoneHeadÓ AdlerÕs ÒoptimizationÓ
|
|
; <7> 7/23/90 dba change this into a linked patch
|
|
; <6> 7/20/90 gbm get rid of the warning
|
|
; <5> 5/18/90 PP Pass address of ÒfromFileÓ correctly to ResolveAlias call.
|
|
; <4> 4/17/90 NB Removed GetResource error messages when the alias is not present.
|
|
; Fixed a bad cleanup condition (called ReleaseResource on a nil
|
|
; handle on an error (no harm, though)).
|
|
; <3> 4/10/90 NB Missed a TST.W D0. Without which, the condition codes for the
|
|
; BNE.S which followed weren't always right. This caused
|
|
; occasionally stack explosions.
|
|
; 4/9/90 Nik Added call to PrLoadDriver. This loads in the driver based on
|
|
; the 'alis' -8192 resource in the system file, rather than on the
|
|
; system printer string. OpenResFile and .Print also make this
|
|
; call, instead of doing it themselves.
|
|
; <1.2> 9/20/89 CCH Rolled in System version from System sources.
|
|
; <1.3> 8/28/89 SES Removed references to nFiles.
|
|
; <1.2> 8/4/89 NMB Restored to 6.0 version of PrGlue. Ginsu is no longer in the 7.0
|
|
; builds of the system (sigh). The glue is now a ptch, rather than
|
|
; part of Rom7xFix.a, at least....
|
|
; <1.1> 5/8/89 NMB Gutted the whole thing and replaced it with a new glue which
|
|
; supports the new printing manager (Ginsu)
|
|
; <1.0> 11/16/88 CCH Added to EASE.
|
|
; 2/22/87 Jay 1). Restore curMap before jumping into the print code. This used
|
|
; to be 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 of the 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.
|
|
; 2/13/87 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.
|
|
; 12/23/86 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.
|
|
; 11/7/86 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.
|
|
; 11/7/86 Jay Fixed bug in PurgePr and NoPurgePr. Check the lower byte of
|
|
; flags to see if the driver is RAM based.
|
|
; 8/1/86 David Added PrGeneral call
|
|
; 9/17/85 Leo Converted to Ira's New Assembler
|
|
; 9/10/85 Leo New trap files, added GoSetVol Changed this file to PrintGlue.a
|
|
; no include files
|
|
; 8/17/85 Leo Integrated PrScreen, went to single Trap and selector.
|
|
; 8/6/85 Leo Added calls to SetVol/GetVol
|
|
; 7/16/85 Leo Fixed bug with stripping return values Removed PrCfgDialog Fixed
|
|
; values in PrGlueTable
|
|
; 7/13/85 Leo from old PrLink
|
|
;
|
|
; 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
|
|
;
|
|
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'Printing.a'
|
|
INCLUDE 'PrPrivate.a'
|
|
INCLUDE 'PrintTrapsEqu.a'
|
|
INCLUDE 'Folders.a'
|
|
INCLUDE 'Aliases.a'
|
|
INCLUDE 'LinkedPatchMacros.a'
|
|
|
|
MACHINE MC68020 ; needed for cache flush <LW2> fau
|
|
|
|
;************************************************************************************************
|
|
;* _MDebugStr takes a string for a parameter and calls DebugStr with it.
|
|
;*
|
|
;* Example: _MDebugStr 'In PrOpen'
|
|
;************************************************************************************************
|
|
|
|
MACRO
|
|
_MDebugStr &dbgStr
|
|
|
|
PEA @dbgAddr
|
|
_DebugStr
|
|
BRA.S @pastDbgAddr
|
|
@dbgAddr DC.B &dbgStr
|
|
ALIGN 2
|
|
@pastDbgAddr
|
|
ENDM
|
|
|
|
PrGlue PatchProc $A8FD,(Plus,SE,II,Portable,IIci)
|
|
;
|
|
; 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
|
|
|
|
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 ; Preset 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 ; <22Feb87> JNP 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?
|
|
Bne.s GetRsrc ; Yes, so get the PDEF
|
|
OpenPrRF
|
|
MOVE.W D2, -(SP) ; save D2 across the call to FetchDriver
|
|
Bsr FetchDriver ; Open our res file
|
|
MOVE.W (SP)+, D2 ; restore D2 as soon as possible
|
|
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
|
|
|
|
; Some programmers are pretty slimy and load a PDEF that is empty. They then <LW2> fau
|
|
; stuff some code into it. However, since HLOCK does not flush the cache anymore, <LW2> fau
|
|
; the code that they stuff into it might not get written back to memory. To solve this, <LW2> fau
|
|
; we check here whether the PDEF resource size is less than, say, 32 bytes. If so, we <LW2> fau
|
|
; assume that they have already loaded the PDEF and modified it, so we flush the cache <LW2> fau
|
|
; for them. <LW2> fau
|
|
|
|
_GetHandleSize ; How big is our PDEF Handle <LW2> fau
|
|
cmp.l #32,D0 ; Is it "small" <LW2> fau
|
|
bhi.s @RealPDEF ; no, don't flush the cache <LW2> fau
|
|
jsr ([jCacheFlush]) ; else, flush the caches. <LW2> fau
|
|
@RealPDEF ; <LW2> fau
|
|
_HLock
|
|
;<22Feb87> JNP Restore curMap before jumping into the print code.
|
|
Move.w a3, -(sp) ; <22Feb87> JNP user's resfile refnum
|
|
_UseResFile ; <22Feb87> JNP 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.w #IOQElSize,sp ; Get an iopb
|
|
Lea PrintName,a0 ; Address of .Print string
|
|
Move.l a0,ioFileName(sp) ; Put in iopb
|
|
Move.w #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.w d1,d1 ; Shift selector left one
|
|
Move.w 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 LoadDriver-LLJump ; Load Driver 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.w #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
|
|
|
|
LoadDriver
|
|
BSR FetchDriver ; error in D0
|
|
|
|
; LLOut is the exit point for this routine. It takes the error in D0 and sets
|
|
; iPrErr with it. We only want that to happen under two circumstances:
|
|
; [1] when the error is uninitialized and
|
|
; [2] when the error is noErr.
|
|
; If the error is already set, we want to leave it alone. This code manages
|
|
; that change. <11>
|
|
|
|
MOVE.W PrintVars+iPrErr, D1 ; get the error in D1 (faster than low-mem access)
|
|
CMPI.W #-1, D1 ; is error uninitialized?
|
|
BEQ LLOut ; Yes, use D0 to set it.
|
|
|
|
TST.W D1 ; Otherwise, is an error pending?
|
|
BZ LLOut ; no, so set the error from D0 in LLOut
|
|
MOVE.W D1, D0 ; otherwise, refresh the D0 error for exit
|
|
BRA LLOut ; LLOut will therefore not reset the error.
|
|
|
|
PrintOpen
|
|
_PrDrvrOpen ; Open the .Print driver
|
|
Move.w PrintVars+iPrErr, d0 ; <22Feb87> JNP Move the error into d0
|
|
BNE.S PrOCerr ;abort if error.
|
|
ST -(SP) ;Mark call "open", by setting a byte true on stack (NB, 3/23/90)
|
|
BRA.S PrOCcom
|
|
PrintClose
|
|
;<13Feb87> JNP removed call to _PrDrvrClose
|
|
; DON'T check for an answer ; just keep slogging through
|
|
SF -(SP) ;Mark Call "close" by setting stack byte false. <NB: 3/23/90>
|
|
PrOCcom
|
|
Bsr FetchDriver ; Open the printer resource file, error in D0
|
|
MOVE.B (SP)+, D1 ; get the flag byte in D1. Always clean up stack!
|
|
|
|
Tst.w D0
|
|
Bne.s PrOCerr ; Error! 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.B D1 ;Open Call?
|
|
BNZ.S @26 ;Yes: Go home
|
|
MOVE.W D0,-(SP) ;No: CloseResFile. Push the refnum param
|
|
_CloseResFile
|
|
@26
|
|
Move.w ResErr,d0
|
|
PrOCerr
|
|
Bra LLOut
|
|
DrvrPrOpen
|
|
CLR.W PrintVars+iPrErr ; force error to noErr at startup for a clean beginning
|
|
_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.w 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.w #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.w 12(a6),d0 ; Set the error code in register
|
|
;
|
|
; LLOut: All the low-level routines return here, with
|
|
; their error code in d0.
|
|
LLOut
|
|
Add.w #IOQElSize,sp ; Strip parameter block
|
|
Move.w 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 ; <13Feb87> JNP
|
|
Bra.s @1 ; <13Feb87> JNP
|
|
@2 Move.w (sp)+, (a1)+ ; <13Feb87> JNP
|
|
@1 Dbf d0, @2 ; <13Feb87> JNP
|
|
NoRetVal
|
|
Move.w PrintVars+iPrErr, d0 ; Leave function result in D0 <12> NB
|
|
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
|
|
;
|
|
|
|
kStartupDisk EQU -1
|
|
|
|
;************************************************************************
|
|
; FindSpecialFolder - find the dirID of a special folder
|
|
; <12jan90 fjs, 3/22/90 used a stack frame: nb>
|
|
;
|
|
; in: d0 = foldertype (ie 'extn')
|
|
; out: d0 = dirID (or 0 if an error occurred) ( this is a lie --sad & ich )
|
|
;************************************************************************
|
|
|
|
FSFStackFrame RECORD 0,decr
|
|
|
|
vRefNum DS.W 1
|
|
dirID DS.L 1
|
|
|
|
kFSFSize EQU *
|
|
ENDR
|
|
|
|
FindSpecialFolder
|
|
WITH FSFStackFrame
|
|
LINK A6, #kFSFSize
|
|
SUBQ.W #2, SP ; space for error
|
|
MOVE.W #kStartupDisk, -(SP) ; this volume
|
|
MOVE.L D0, -(SP) ; folder type (input)
|
|
SF -(SP) ; don't create
|
|
PEA vRefNum(A6) ; ptr to the output vRefNum
|
|
PEA dirID(A6) ; ptr to output dirID
|
|
_FindFolder
|
|
MOVE.W (SP)+, D0 ; fetch error
|
|
BNZ.S @bail ; oh, well. Unlink and out.
|
|
|
|
MOVE.L dirID(A6), D0 ; if no error, copy dirID into output reg.
|
|
|
|
@bail UNLK A6
|
|
RTS
|
|
ENDWITH
|
|
|
|
;************************************************************************
|
|
; FetchDriver: open the system printer's resource file:
|
|
; We do this by resolving the alias written into the system file by
|
|
; the chooser. This alias maps from the system file to the driver.
|
|
; We canonify the system file, and then call ResolveAlias to create
|
|
; a canonified representation of the driver. That representation
|
|
; contains the information needed by HOpenResFile, which we then call.
|
|
; Any error is returned in D0.
|
|
;************************************************************************
|
|
|
|
FetchDriver
|
|
|
|
;************************************************************************
|
|
; CanonSysFile: Canonify the system file
|
|
;
|
|
; sysFileCanon(A6) contains the output CanonSpec if the routine succeeds.
|
|
; If an error occurs, the entire routine is abandoned, with the error in D0.
|
|
;
|
|
; pascal OSErr CanonifyFile(short vRefNum,
|
|
; long dirID,
|
|
; const Str255 *fileName,
|
|
; CanonicalFileSpec *canonicalFile);
|
|
;************************************************************************
|
|
|
|
SpecRec RECORD 0,decr
|
|
|
|
sysFileSpec DS.B FSSpec.size
|
|
driverSpec DS.B FSSpec.size
|
|
aliasHandle DS.L 1
|
|
wasChanged DS.B 1
|
|
if theFuture then ; PURGEALIAS
|
|
aliasState DS.B 1 ; State of the alias
|
|
endif ; PURGEALIAS
|
|
|
|
ALIGN 2
|
|
|
|
kSpecSize EQU * - SpecRec
|
|
ENDR
|
|
|
|
|
|
kAliasID EQU -8192 ; System Printer alias's resID
|
|
|
|
WITH SpecRec
|
|
|
|
LINK A6, #kSpecSize
|
|
|
|
MOVE.L #kSystemFolderType, D0 ; get this folder's dirID
|
|
BSR.S FindSpecialFolder ; if cond code < 0, then we have an error
|
|
BMI @Bail ; if failure, exit routine, error in D0
|
|
|
|
; create a file spec for the system file
|
|
|
|
MOVE.W #kStartupDisk, sysFileSpec + FSSpec.vRefNum(A6) ; VRefNum of startup disk
|
|
MOVE.L D0, sysFileSpec + FSSpec.parID(A6) ; dirID from FetchSpecialFolder
|
|
|
|
MOVEQ #0, D0 ; clear out D0 for BlockMove
|
|
LEA SysResName, A0 ; Copy system file's name
|
|
MOVE.B (A0), D0 ; which is this long
|
|
ADDQ.B #1, D0 ; plus that length byte!
|
|
LEA sysFileSpec + FSSpec.name(A6), A1 ; to the FSSpec
|
|
_BlockMove
|
|
|
|
; ResolveDriver: Resolve the alias using the system file's FSSpec.
|
|
|
|
SUBQ #4, SP ; allocate space for GetResource
|
|
MOVE.L #rAliasType, -(SP) ; get this type
|
|
MOVE.W #kAliasID, -(SP) ; get this ID
|
|
_GetResource ; fetch, boy!
|
|
MOVE.L (SP)+, D0 ; this is the handle
|
|
MOVE.L D0, aliasHandle(A6) ; save it across all these calls
|
|
BNZ.S @ResolveIt ; got one. Off we go...
|
|
|
|
; This is a new problem for the glue. If the resource for the alias is not found, then
|
|
; we would normally return resNotFound. The glue used to return fnfErr whenever it couldn't
|
|
; open the driver and applications have coded for that error. Rather than add an error
|
|
; code, we map resNotFound to fnfErr and save the user some grief.
|
|
|
|
@failedGetRes
|
|
MOVE.W ResErr, D0 ; copy error into output var
|
|
BNZ.S @Bail ; and exit if non-zero
|
|
MOVE.W #fnfErr, D0 ; else, return fnfErr so apps alert the user correctly
|
|
BRA.S @Bail ; and exit.
|
|
|
|
@ResolveIt
|
|
if theFuture then ; PURGEALIAS
|
|
Move.l aliasHandle(A6),A0
|
|
_HGetState
|
|
Move.b D0,aliasState(A6) ; Save the Alias state.
|
|
_HNoPurge ; Make the alias non-purgeable
|
|
endif ; PURGEALIAS
|
|
|
|
SUBQ.W #2, SP ; space for error
|
|
PEA sysFileSpec(A6) ; first parameter
|
|
MOVE.L D0, -(SP) ; the alias handle
|
|
PEA driverSpec(A6) ; ptr to driverSpec
|
|
PEA wasChanged(A6) ; ptr to output boolean (ignored)
|
|
_ResolveAlias
|
|
MOVE.W (SP)+, D0 ; got the error here.
|
|
BNZ.S @Cleanup
|
|
|
|
TST.B wasChanged(A6) ; check if the alias needs updating
|
|
BZ.S @CallHOpenRes ; Nope, keep going
|
|
|
|
MOVE.L aliasHandle(A6), -(SP) ; Now set the resource changed
|
|
_ChangedResource
|
|
TST.W ResErr
|
|
BNZ.S @Cleanup ; exit on error
|
|
|
|
CLR.W -(SP) ; Update the system file
|
|
_UpdateResFile ; (refnum = 0)
|
|
TST.W ResErr
|
|
BNZ.S @Cleanup ; exit on error
|
|
|
|
@CallHOpenRes
|
|
SUBQ.W #2, SP ; space for function result
|
|
MOVE.W driverSpec + FSSpec.vRefNum(A6), -(SP) ; parameter 1: vRefNum
|
|
MOVE.L driverSpec + FSSpec.parID(A6), -(SP) ; parameter 2: parent ID
|
|
PEA driverSpec + FSSpec.name(A6) ; parameter 3: ptr to fileName
|
|
MOVE.B #fsCurPerm, -(SP) ; set permission to "current"
|
|
_HOpenResFile
|
|
|
|
MOVE.W (SP)+, D0 ; grab function result
|
|
|
|
MOVE.W D0, iPrRefNum ; If it worked, then set the refnum
|
|
MOVE.W ResErr, d0 ; set the error in D0
|
|
|
|
@Cleanup
|
|
|
|
if theFuture then ; PURGEALIAS
|
|
Move.l aliasHandle(A6),A0
|
|
Move.b aliasState(A6),D0 ; Restore the alias state.
|
|
_HSetState
|
|
endif
|
|
MOVE.L aliasHandle(A6), -(SP) ; release the alias resource
|
|
_ReleaseResource
|
|
|
|
@Bail UNLK A6 ; error in D0.
|
|
RTS
|
|
ENDWITH
|
|
|
|
; Name of the .Print driver
|
|
|
|
STRING PASCAL
|
|
PrintName DC.B '.Print'
|
|
ALIGN
|
|
|
|
ENDPROC
|
|
|
|
|
|
END
|
|
|
|
|
|
|