sys7.1-doc-wip/Misc/ShowINIT.a
2019-07-27 22:37:48 +08:00

466 lines
22 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: ShowINIT.a
;
; Contains: xxx put contents here xxx
;
; Written by: xxx put writers here xxx
;
; Copyright: © 1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <1> 1/4/93 ejb first checked in
;
;
; File: ShowINIT.a
; Last Modified: Monday, December 21, 1992 1:17:00 PM
;
; # after any modification, please execute the following giberish to update the dates in this file
; find ∞ "{active}"; replace \(([∂"∂'])®0Version of )®1≈\ "®1`date -d -s`®0" "{active}"
; find • "{active}"; replace /(Last∂ Modified: )®0≈/ "®0`date`" "{active}"
;————————————————————————————————————————————————————————————————————————————————————————————————
;
; INIT notification routine
; by Paul Mercer, Darin Adler, Paul Snively, Frédéric Miserey, Alex Rosenberg,
; and François Grieu, from an idea by Steve Capps
;
; The whole thing is for drawing an extension's icon during the boot process;
; this code has had a complicated life cycle: there are dozens of different
; versions around in the wilderness.
;
; François Grieu, latest offender of this code, is on AppleLink FRA0003
; the internet address is: FRA0003@AppleLink.Apple.COM
;
; This particular variation :
; - knows how to wrap around the screen, for thoose with many inits; this only
; works with cooperating ShowINITs
; - draw from ICN#/icl4/icl8 combos, now the standard for icons; the best
; source is choosen according to main screen pixel depth and available resources
; - does NOT support the old cicn resources
; - displays a nice empty square if no valid ICN# is present (new feature)
; - has been rewritten for extreme compactness: shrinked from 964 to 500 bytes,
; while lot of error prevention and checking was added.
; - is heavily commented, hopefuly compensating much of the obfuscation introduced.
;
; as supplied, the programming interface is :
;
; extern pascal void ShowINIT(short iconID, short moveX);
;
; PROCEDURE ShowINIT(iconID: INTEGER, moveX: INTEGER); EXTERNAL
;
; iconID: resource ID of an ICN#, and (optionaly) of an icl4 and/or icl8
; moveX: horizontal displacement for next icon; legitimate values are
; -1 or 40 standard 40 pixels displacement
; 0 no displacement (for animation purproses)
;
; a typical INIT with a small animation looks like :
;
; ShowINIT(128,0); /* draw first icon, don't move */
; doMyOwnjob(); /* do some usefull stuff */
; ShowINIT(129,-1); /* draw second icon, advance for next */
;
;
; (FRG: My first idea was to remove the moveX parameter entirely, since I never use it;
; later I realised it meant others could not just use my code as a drop-in replacement,
; and precluded animations; thus, I introduced an assembly option to control what moveX
; does, and if it exists; see below under moveX_option)
;
;————————————————————————————————————————————————————————————————————————————————————————————————
; Revision history
;
; 6/7/87 PM - Created First version.
; 6/15/87 PM - Changed to standard (Pascal) calling conventions.
; 6/20/87 PM - Fixed color & Finder bug on Mac II.
; 6/22/87 DBA - Improved handling of QuickDraw.
; 6/29/87 DBA - Used scratch8 to avoid conflict with “Easy Access”.
; 6/30/87 DBA - Changed to a 4-byte scheme with “checksum”.
; 6/30/87 PFS - Separated into ShowINIT and InnerShowINIT.
; 7/1/87 DBA - Fixed stack bug and switched to CurApName.
; 7/2/87 PM - Added check for old signature in ApplScratch for backword compatibility
; (TMON Startup).
; 7/3/87 PM - Removed _SysBeep in ErrorExit since it causes a crash.
; - Also changed ICN# plotter to srcOr mode for Blinker.
; 7/13/87 PM - Fixed A3 trashing bug in InnerShowINIT - exit code left word on stack
; (reported by D. Dunham).
; 7/21/87 PM - Due to popular demand, InitGraf is no longer being called.
; This avoids the gamma correction problem with Startupscreens getting
; “washed out” by ShowINIT, though someone else is still bound to call
; InitGraf sooner or later (i.e. InitWindows).
; 7/29/87 PM - Put InitGraf back in; this is required (reported by C. Derossi at Apple
; Tech Support).
; - Took out GetPort/SetPort.
; 10/6/87 PM - Set CurrentA5 properly. Rearranged myVars.
; 12/28/87 PM - Major revision to accomodate future INIT31 based ShowINIT.
; 7/14/88 PM - Major revision to get rid of above 'accomodations'.
; - Added color icon 'cicn' support and fixed beep crash.
; - Removed support for old signature.
; 11/25/89 PM - Added Y dimension support, icl4/8 support to get rid of 'obsolete' cicns.
; 3/27/90 AMR - 'cicn's were not being drawn in their native size
; 11/30/91 FRG - Started from source found on Lord of the Files, dev. CD Vol VII.
; - Removed cicn support - these are obsolete and may cause palette problems
; - Introduced a right margin (causes wraparound sooner on a few sreens).
; - Simplified A5 world allocation; all variables now A5-based
; - Initialized more fields in the PixMap.
; - Added a check that ICN#/icl4/icl8 resources are at least the expected size;
; blockmoved these into variables and disposed the Resource immediately;
; default drawing if no ICN# can be loaded; many other sanity cheks.
; - Rather than disposing the Color Map of the PixMap returned by _NewPixMap and
; later manufacturing an empty Color Map before disposing the PixMap, we now
; save the original Color Map, and restore it before disposing the PixMap.
; 12/3/91 FRG - Introduced moveX_option for backward link-level compatibility.
; - Spread subroutines to use short branchs where possible.
; - Firmly decided to stop shrinking the code - maybe it's too late.
; 12/4/91 FRG - Did extensive tests on many configurations and monitor stiings, including
; - Plus and SE under 6.0.7 and 3.2
; - II under System 6.0.7 and 3.2
; - IIcx under System 7
; - IIci under 6.0.7 and 7.0.1
; - IIfx under 7.0 and two Apple 13" monitors
; - IIfx under 6.0.7 and 32 bits color (RasterOps card & monitor)
; not a single crash; the INIT adapts well to the environment and draws using
; the right resource and colors; however, there are quite a few visual
; glitches with old INITs, when drawing past the first line. Many keep drawing
; on the bottom line; some will allow only two or three lines.
; All in all, the method implemented seems to be the official one, and
; reasonably compatible with what's around.
; - AppleLink relase.
; 12/21/92 - Call LoadResource after GetResource <rb>
; 3/26/93 chp - Change QuickEqu.a to QuickDraw.a for new AIncludes.
;
;————————————————————————————————————————————————————————————————————————————————————————————————
;
INCLUDE 'Traps.a'
INCLUDE 'SysEqu.a'
INCLUDE 'QuickDraw.a'
;
;————————————————————————————————————————————————————————————————————————————————————————————————
;
; Assembly-time option for moveX parameter treatment. Allowable values for moveX_option are :
; 0 ; original : negative value -> 40, other taken as is
; 1 ; enforce standard : zero -> no move, others -> 40 pixels right
; 2 ; no moveX parameter - function name changed to ShowINIT_EZ
;
; if necessay, moveX_option can be set up from the command line, for example:
; ASM -d moveX_option=2 ShowINIT.a
;
; with moveX_option=2, the programming interface becomes :
;
; extern pascal void ShowINIT_EZ(short iconID);
;
; PROCEDURE ShowINIT_EZ(iconID: INTEGER); EXTERNAL
;
;
IF &TYPE('moveX_option') = 'UNDEFINED' THEN
moveX_option SET 0 ; default to old behaviour
ENDIF
;
;
PROC
IF moveX_option <> 2 THEN ; option 2 supresses the moveX parameter and change name
EXPORT (ShowINIT):CODE ; keep standard name
ELSE
EXPORT (ShowINIT_EZ):CODE ; name when no moveX parameter
ENDIF
;
; other constants
iconSize EQU 32 ; X & Y size of icons (don't even think to change this…)
iconSpacer EQU 8 ; X & Y spacing, and top/left/bottom/right sreen margin
checksumConst EQU $1021 ; constant used for computing checksum
minColorDepth EQU 4 ; minimum bits/pixel for drawing color icons
iconRowBytes EQU 32/8 ; 32/8 bits
hasCQDBit EQU 6 ; this bit in ROM85 is cleared if Color QuickDraw is available
;
; remanent low mem variables; CurApName+32-8 is a GREAT place to store 8 bytes (it was Darin's idea)
myVCheck EQU CurApName+32-8 ; a simple checksum of myV to determine first-timeness
myV EQU myVCheck+2 ; current vertical position
myH EQU myV+2 ; current horizontal position
myHCheck EQU myH+2 ; a simple checksum of myH to determine first-timeness
;
; our register list: D7 and A6 are still for rent !!
savedRegList REG D3-D6/A2-A5 ; registers used - adjust savedRegCnt accordingly
savedRegCnt EQU 8 ; count of saved registers
; our variables and buffers; allocated on the stack, making an A5 world
; insert new fields only as advertised; do not reorder
stackFrame RECORD {A5Link},DECR ; build a stack frame record
paramBegin EQU * ; start parameters after this point
iconID DS.W 1 ; resource ID of the ICN#/icl4/icl8 combo
IF moveX_option <> 2 THEN ; option 2 supresses the moveX parameter
moveX DS.W 1 ; horizontal move parameter
ENDIF
; insert additionnal parameters here
paramSize EQU paramBegin-* ; size of all the passed parameters
DS.L 1 ; place holder for return address
DS.L savedRegCnt ; place holder for saved registers
A5Link DS.L 1 ; QuickDraw will stuff a pointer to his variables here
; possible location for additionnal variables
thePort DS.L 1 ; QuickDraw globals
DS.B grafSize-4 ; other QuickDraw globals (except thePort)
; prefered location for additionnal variables
myPort DS.B portRec ; a private port
myBitMap DS.B bitmapRec ; private bitMap record for our ICN# offscreen
; possible location for additionnal variables
buf_iclx DS.B 1024 ; room for an icl8 (also hold the icl4)
; possible location for additionnal variables
buf_mask DS.B 128 ; ICN# mask
buf_icon DS.B 128 ; ICN# icon
dstRect DS.B 8 ; the rectangle we draw to - must be last
varsSize EQU *
ENDR
WITH stackFrame ; cover our local stack frame
;
;————————————————————————————————————————————————————————————————————————————————————————————————
;
;
; the entry point : this is to be kept on the first instruction of the module, for compatibility
; only one of the two label is realy exported, depending on moveX_option
ShowINIT:
ShowINIT_EZ:
;
; first we build an A5 world on the stack. This why we save the registers before the LINK An,#
MOVEM.L savedRegList,-(A7) ; save registers, including A5
LINK A5,#varsSize ; allocate our variables & A5 world
MOVE.L A7,A2 ; points to dstRect - used later
;
; initialise QuickDraw gear
; we open a new port to get fresh information, and isolate the screen port from our messing
PEA thePort(A5)
_InitGraf ; fixes color bug as per DA@ICOM
LEA myPort(A5),A4 ; will later move into myBitMap
MOVE.L A4,-(A7) ; _ClosePort parameter (done in cleanup)
MOVE.L A4,-(A7) ; _OpenPort parameter
_OpenPort
;
; setup myBitMap to refer to the ICN# mask (not yet loaded)
MOVE.L #(iconSize<<16)+iconSize,D6 ; D6 constant from now on
MOVE.L D6,-(A4) ;bounds.botRight
CLR.L -(A4) ;bounds.topLeft ; 0-0-32-32 standard icon bounds
MOVE.W #iconRowBytes,-(A4) ;rowBytes
LEA buf_mask(A5),A0 ; pointer to Mask
MOVE.L A0,-(A4) ;baseAddr ; A4 is ptr to myBitMap from now on
;
; (11/30/91 FRG) build drawing coordinates and update the remanent variables
; First we calculate the rightmost position allowable.
; There is, purprosely, a small deviation from the original : we have a 7 pixels right margin.
; Also note that the moveX parameter is always ignored for wraparound calculation, as in the original,
; else it would ruin animation on the rightmost position
MOVEQ #iconSize+iconSpacer,D2 ; (horizontal spacing) added in valid_coord
MOVE.W myPort+portBounds+right(A5),D1 ; horizontal screen size
SUB.W D2,D1 ; maximum in valid_coord (right margin)
IF moveX_option = 0 THEN ; original
MOVE.W moveX(A5),D2 ; prescribed horizontal spacing
BPL.S more ; must be non-negative
MOVEQ #iconSize+iconSpacer,D2 ; default horizontal spacing
ELSEIF moveX_option = 1 THEN ; enforce regular icon spacing
TST.W moveX(A5) ; flag for horizontal spacing
BNE.S more ; non-zero means default
MOVEQ #0,D2 ; zero means no move
ENDIF
more MOVEQ #0,D3 ; nothing yet to be substracted in valid_coord
MOVEQ #iconSpacer,D4 ; default (for valid_coord)
MOVE.L myH,D0 ; get myH & myHCheck
SWAP D0 ; myHCheck <-> myH (reversed for historical reasons)
BSR.S valid_coord ; build left coordinate
SWAP D0 ; myH <-> myHCheck (reversed for historical reasons)
MOVE.L D0,myH ; save updated myH & myHCheck
MOVEQ #-(iconSize+iconSpacer),D4
ADD.W myPort+portBounds+bottom(A5),D4 ; vertical default
MOVEQ #0,D2 ; nothing to be added
MOVE.W D4,D1 ; maximum (same as default)
MOVE.L myVCheck,D0 ; get myVCheck/myV
BSR.S valid_coord ; build top coordinate
MOVE.L D0,myVCheck ; store myVCheck/myV
;
; result (topLeft of our location on the screen) is in D5. A2 points to dstRect
MOVE.L D5,(A2)+ ;topLeft ; save the resulting X/Y coordinate
ADD.L D6,D5 ; compute the botRight (no overflow can occur)
MOVE.L D5,(A2)+ ;botRight ; make an icon-sized rect
;
; load the ICN#
MOVEQ #256/128,D3 ; size for DATA+MASK
MOVE.L #'ICN#',D4 ; note that here A2 points to buf_icon
BSR.S load_rsrc ; load the icon and mask
BEQ.S got_mask ; ICN# loaded ok
;
; (11/30/91 FRG) no resource loaded; draw a simple light gray rect with black border
PEA ltGray+thePort(A5)
_BackPat ; set background pattern to light gray
PEA dstRect(A5) ; _FrameRect parameter
MOVE.L (A7),-(A7) ; _EraseRect parameter
_EraseRect ; make the inside
_FrameRect ; and the border
BRA.W cleanup
;
; (11/30/91 FRG) coordinate validator; called two times to process the H then V coordinates; trashes A0
; reg *** on entry *** *** on exit ***
; D0 lo:coordinate hi:alleged checksum lo: result coordinate hi:updated checksum
; D1 maximum value unchanged
; D2 post-offset (added for horizontal shift) unchanged
; D3 pre-offset (substracted for vertical offset) set to iconSize+iconSpacer if maximum exceeded
; D4 default when invalid checksum or out of bound unchanged
; D5 lo:ignored hi:previous result lo: previous result hi:result coordinate
valid_coord BSR.S adj_chksum ; adjust high word of D0
CMP.L A0,D0 ; a copy of D0 was kept in A0
BEQ.S useD0a ; D0's checksum was OK
MOVE.W D4,D0 ; revert to default
useD0a SUB.W D3,D0 ; on vertical pass : move up if previous overflow
CMP.W #iconSpacer,D0 ; check against minimum
BLO.S useDefault ; too left/high, use default & no line change
CMP.W D1,D0
BLS.S useD0b ; check for overflow
MOVEQ #iconSize+iconSpacer,D3 ; (vertical spacing) remember the overflow
useDefault MOVE.W D4,D0
useD0b MOVE.W D0,D5 ; store left / top
SWAP D5 ; build the top point
ADD.W D2,D0 ; add after
adj_chksum MOVE.L D0,A0 ; fix D0's high byte
ROL.W #1,D0
EOR.W #checksumConst,D0
SWAP D0
MOVE.W A0,D0
RTS
;
; (11/30/91 FRG) load an ICN#/icl4/icl8 resource
; on entry : A2 = destination; unchanged
; D4 = resource type; unchanged
; D3 = expected length/128 (either or 2,4,8). Is returned multiplied by 128
; on exit D0 = 0 if OK, and -1 if error; flags are set accordingly
load_rsrc ASL.W #7,D3 ; D3 *= 128
SUBQ.L #4,A7 ; _GetResource result
MOVE.L D4,-(A7) ; type
MOVE.W iconID(A5),-(A7) ; id
_GetResource
MOVE.L (A7)+,D0
BEQ.S baderr ; nil handle
MOVE.L D0,A0
MOVE.L A0,-(SP)
_LoadResource ; load resource
MOVE.L (A0),D2
BEQ.S baderr ; purged handle
MOVE.L A0,-(A7) ; parameter for _ReleaseResource
_GetHandleSize
CMP.L D3,D0
BLO.S miderr ; not the expected size
MOVE.L D3,D0 ; len for _BlockMove
MOVE.L D2,A0 ; src for _BlockMove
MOVE.L A2,A1 ; dst for _BlockMove
_BlockMove
_ReleaseResource
MOVEQ #0,D0 ; mark OK
RTS
miderr _ReleaseResource
baderr MOVEQ #-1,D0 ; mark err
RTS
;
; try to draw in color; if anything fails, revert to ShowINIT1Bit
got_mask BTST.B #hasCQDBit,ROM85 ; does CQD exists ?
BNE.S ShowINIT1Bit ; no, we'll do it one bit
MOVE.L MainDevice,D5 ; get handle to main device
BSR.S safe_deref_D5
MOVE.L gdPMap(A3),D5 ; get its pixmap handle
BSR.S safe_deref_D5
MOVE.L #'icl8',D4 ; icl8 as first choice
CMPI.W #minColorDepth,pmPixelSize(A3) ; test main screen depth
BLT.S ShowINIT1Bit ; not deep enough for us to draw in color
BEQ.S is_4bits ; screen is 4 bits deep, first use icl4
SUBQ.B #4,D4 ; icl8->icl4
is_4bits LEA buf_iclx(A5),A2 ; storage pointer for load_rsrc
MOVEQ #1,D5 ; try to load the appropriate iclx, else try the other
two_times_max MOVEQ #$0C,D3 ; note : high word of D3 is 0 from now on
EOR.W D3,D4 ; alternates icl4 and icl8
AND.W D4,D3 ; 4 or 8; after load_rsrc will become 512 or 1024
BSR.S load_rsrc ; load eiter the icl4 or icl8 (D3 multiplied by 128)
DBEQ D5,two_times_max
BEQ.S ShowINITxBit ; found a resource, go draw in color
;
; draw the B&W ICN#
ShowINIT1Bit MOVEQ #srcBic,D0 ; mode for Mask
BSR.S doCopyBits
MOVEQ #-128,D0
ADD.L D0,baseAddr(A4) ; now move myBitMap to the ICON
MOVEQ #srcOr,D0 ; mode for the ICON
BSR.S doCopyBits
BRA.S cleanup ; all done
;
; (12/02/91 FRG) checks for handle just loaded in D5; if invalid, revert to ShowINIT1Bit
; returns the handle in A0, the dereferenced handle in A3 and D0; destroys A1
safe_deref_D5 MOVE.L (A7)+,A1 ; pop return address, keep flags
BEQ.S ShowINIT1Bit ; error - nil handle (in D5)
MOVE.L D5,A0
MOVE.L (A0),D0
BEQ.S ShowINIT1Bit ; error - purged handle
MOVE.L D0,A3
JMP (A1)
;
; (11/30/91 FRG) a subroutine to CopyBits myBitMap to the dstRect in said (D0) mode
doCopyBits MOVE.L A4,-(A7) ; source bitmap (is myBitMap)
PEA myPort+portBits(A5) ; dst bitmap
PEA myBitMap+bounds(A5) ; srcRect
PEA dstRect(A5) ; dstRect
MOVE.W D0,-(A7) ; mode
CLR.L -(A7) ; no clip region
_CopyBits ; draw it
RTS
; draw on icl4 or icl8; we need to manufacture an offsceen pixmap
ShowINITxBit SUBQ.L #4,A7
_NewPixMap ; make a new PixMap
MOVE.L (A7)+,D5 ; D5 keeps the PixMap till we dispose it
BSR.S safe_deref_D5
_HLock ; lock the new PixMap
; while we point here, prepare the bitMaps/pixMaps for the _CopyMask
MOVE.L A3,-(A7) ; srcBits (is the new PixMap)
MOVE.L A4,-(A7) ; maskBits (is myBitMap)
PEA myPort+portBits(A5) ; dst bitmap
; now fill in the PixMap fields, in ascending order (so we save code, and won't forget anything)
MOVE.L A2,(A3)+ ;pmBaseAddr ; address where the icl4/icl8 was _BlockMoved
MOVE.B #$80,(A3)+ ;pmNewFlag ; mark as new style PixMap
LSR.W #7-2,D3 ; depth in bit (8 or 4) multiplyed by 4
MOVE.B D3,(A3)+ ;pmRowBytes+1 ; set Row Width in bytes (either 32 or 16)
; while we point here, prepare the Rect parameters for the _CopyMask
MOVE.L A3,-(A7) ; srcRect is pmBounds
MOVE.L A3,-(A7) ; maskRect is same
PEA dstRect(A5) ; dstRect
CLR.L (A3)+ ;pmBounds.topLeft ; set the pmBounds
MOVE.L D6,(A3)+ ;pmBounds+botRight ; D6 = (iconSize<<16) + iconSize
CLR.L (A3)+ ;pmVersion/pmPackType ; standard
CLR.L (A3)+ ;pmPackSize ; standard
ADDQ.L #pmPixelType-pmHRes,A3 ; let pmHRes & pmVRes unchanged
LSR.W #2,D3 ; depth in bit (8 or 4)
MOVE.L D3,(A3)+ ;pmPixelType/pmPixelSize (pmPixelType zeroed=>chunky)
MOVE.W #1,(A3)+ ;pmCmpCount ; components in pixel, 1 for chunky
MOVE.W D3,(A3)+ ;pmCmpSize ; same as pmPixelSize
CLR.L (A3)+ ;pmPlaneBytes ; 0 for chunky
SUBQ.L #4,A7 ; get the clut appropriate for our depth
MOVE.L #'clut',-(A7)
MOVE.W D3,-(A7) ; resource id = either (8 or 4)
_RGetResource ; hopefully can't fail on a color machine
MOVE.L (A3),D4 ;pmTable ; keep the original color map around
MOVE.L (A7)+,(A3)+ ;pmTable ; stuff the ROM clut
CLR.L (A3) ;pmReserved ; must be set to 0 for future compatibility
; now do the much awaited drawing
_CopyMask ; do the drawing
; cleanly dispose the PixMap
MOVE.L D4,-(A3) ;pmTable ; restore the original color map
MOVE.L D5,-(A7) ; original new PixMap Handle
_DisposPixMap
; about all done
cleanup _ClosePort ; parameter for this one pushed long ago
; *** (DBA) I think that QuickDraw leaves handles around. Too bad we can't get rid of them…
UNLK A5 ; de-allocate our variables - does NOT restore A5
MOVEM.L (A7)+,savedRegList ; restore standard registers, including A5
MOVE.L (A7)+,A0 ; pop return address
ADDA #paramSize,A7 ; discard parameters (optimized into ADDQ.W)
JMP (A0) ; all done
;————————————————————————————————————————————————————————————————————————————————————————————————
; ShowINITCredits
STRING ASIS
DC.W 'ShowINIT by Paul Mercer'
DC.W 'Copyright 1987-1991'
DC.W 'Version of 12/21/92'
;————————————————————————————————————————————————————————————————————————————————————————————————
ENDPROC
END