Reverse 68k Color QuickDraw

The ROM now round-trips with QuickDraw mostly built from source.
(~30% of the ROM is now built from source.)
This commit is contained in:
Elliot Nunn 2017-10-08 23:26:23 +08:00
parent 6764d35537
commit 9c249dafab
26 changed files with 1240 additions and 3586 deletions

Binary file not shown.

Binary file not shown.

View File

@ -202,7 +202,8 @@ processAppSpec EQU 56
MACRO
_GetFrontProcess
PEA $FFFFFFFF
MOVEQ.L #$FFFFFFFF,D0
MOVE.L D0,-(SP)
MOVE.W #$39,-(SP)
_OSDispatch
ENDM

View File

@ -266,7 +266,7 @@ PMFlag EQU $8000 ; flag to say it's a new pixMap
cPortFlag EQU $C000 ; isPixMap+isCPort
pixVersion EQU $0000 ; isPixMap
qdStackXtra EQU $0640 ; stack space left for interrupts <1.4> BAL
qdStackXtra EQU $0800 ; stack space left for interrupts <1.4> BAL
isPixMap EQU 15 ; for testing high bit of pRowbytes
isCPort EQU 14 ; indicates that "bitmap" belongs to port
@ -376,7 +376,7 @@ CCSTATEREGS EQU CCDEPTH+2 ;[16 BYTES] STATE INFO OF SAVED DATA
CCBYTES EQU CCSTATEREGS+16 ;[WORD] ROWBYTES OF EXPANDED DATA
CCMAXDEPTH EQU CCBYTES+2 ;[WORD] MAXIMUM SCREEN DEPTH
CCSAVEREC EQU CCMAXDEPTH+2 ;SIZE OF CURSOR SAVE AREA
CCSAVEREC EQU CCMAXDEPTH+2+8 ;SIZE OF CURSOR SAVE AREA
; Font Manager low mem
;

View File

@ -265,70 +265,110 @@ selectInitializediskCache equ $0010 ; <24>
MACRO
_sbIsOutline
IMPORT SplineMgr
MOVEQ #sbIsOutline,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbIsOutline,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbRetrieveGlyph
IMPORT SplineMgr
MOVEQ #sbRetrieveGlyph,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbRetrieveGlyph,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbKillSomeCaches
IMPORT SplineMgr
MOVEQ #sbKillSomeCaches,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbKillSomeCaches,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbFillWidthTab
IMPORT SplineMgr
MOVEQ #sbFillWidthTab,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbFillWidthTab,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbResetWorkSpace
IMPORT SplineMgr
MOVEQ #sbResetWorkSpace,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbResetWorkSpace,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbInitMemory
IMPORT SplineMgr
MOVEQ #sbInitMemory,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbInitMemory,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbSetFontState
IMPORT SplineMgr
MOVEQ #sbSetFontState,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbSetFontState,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbSearchForCache
IMPORT SplineMgr
MOVEQ #sbSearchForCache,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbSearchForCache,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_sbPreFlightFontMem
IMPORT SplineMgr
MOVEQ #sbPreFlightFontMem,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbPreFlightFontMem,D0
OPT &OLDOPT
_SplineMgr
ENDM
MACRO
_fsLowestPPEM
IMPORT SplineMgr
MOVEQ #fsLowestPPEM,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #fsLowestPPEM,D0
OPT &OLDOPT
_SplineMgr
ENDM
@ -341,19 +381,31 @@ selectInitializediskCache equ $0010 ; <24>
MACRO
_sbFlushFonts
IMPORT SplineMgr
MOVEQ #sbFlushFonts,D0
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #sbFlushFonts,D0
OPT &OLDOPT
_SplineMgr
ENDM
Macro ; <24>
_InitializePartialFonts ; <24>
moveq #selectInitializePartialFonts,d0 ; <24>
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #selectInitializePartialFonts,d0 ; <24>
OPT &OLDOPT
_SplineMgr ; <24>
EndM ; <24>
Macro ; <24>
_InitializeDiskCache ; <24>
moveq #selectInitializeDiskCache,d0 ; <24>
LCLC &OLDOPT
&OLDOPT SETC &Setting('OPT')
OPT NONE
MOVE #selectInitializeDiskCache,d0 ; <24>
OPT &OLDOPT
_SplineMgr ; <24>
EndM ; <24>

View File

@ -1071,12 +1071,42 @@ NXTDST MOVE.L (A4)+,D1 ;GET NEXT DST DEVICE
MOVE.L srcDevice,A1 ;handle to source gDevice
move.l (a1),a1 ;pointer to source gDevice
move.l gdRect(a1),d0 ;get rect top.left
move.l theGDevice,a1 ;handle to destination gDevice
move.l (a1),a1 ;pointer to destination gDevice
cmp.l gdRect(a1),d0 ;dest and src gDevice have same top-left?
beq.s nxtdst ;devices overlap, skip drawing
move.l theGDevice,a0 ;handle to destination gDevice
move.l (a0),a0 ;pointer to destination gDevice
CMP $24(A0), D0
BGT.S @L5
BLT.S @L2
SWAP D0
CMP gdRect+0(A0), D0
BGT.S @L6
BLT.S @L3
MOVE.L gdRect+4(A1), D0
CMP gdRect+6(A0), D0
BLT.S @L7
BGT.S @L4
BRA.S nxtdst
@L2 SWAP D0
CMP gdRect+0(A0), D0
BGT.S @cont
@L3 MOVE.L gdRect+4(A1), D0
CMP gdRect+6(A0), D0
BLT.S @cont
@L4 SWAP D0
CMP gdRect+4(A0), D0
BLT.S @cont
BRA.S nxtdst
@L5 SWAP D0
CMP gdRect+0(A0), D0
BLT.S @cont
@L6 MOVE.L gdRect+4(A1), D0
CMP gdRect+6(A0), D0
BGT.S @cont
@L7 SWAP D0
CMP gdRect+4(A0), D0
BGT.S @cont
BRA.S nxtdst
@cont
;
; End of <KON 2/19/90>
@ -1711,11 +1741,91 @@ DSTRECT EQU MASKRECT-4 ;long, addr of Rect
MODE EQU DSTRECT-2 ;WORD
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
VARSIZE EQU 0
VARSIZE EQU -4
share LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS FOR DEVLOOP
CLR.L -4(A6)
MOVE.L MASKBITS(A6), D0
BEQ @skip
MOVEA.L D0, A0
CMPI #$1, $20(A0)
BNE @skip
MOVEA.L $16(A6), A0
MOVEA.L $E(A6), A1
MOVE $4(A0), D0
SUB (A0), D0
SUB $4(A1), D0
ADD (A1), D0
BGT.B @L0
MOVE $6(A0), D0
SUB $2(A0), D0
SUB $6(A1), D0
ADD $2(A0), D0
BLE @skip
@L0 SUBQ #$4, SP
DC.W $AA18 ;_GetCTable
MOVE.L (SP)+, D3
BEQ @skip
SUBQ #$2, SP
PEA.L -4(A6)
MOVE #$2, -(SP)
PEA.L MASKRECT(A6)
MOVE.L D3, -(SP)
CLR.L -(SP)
PEA 4
MOVE.L #$160000,D0 ;_QDExtensions -> _NewGWorld
DC.W $AB1D
MOVE (SP)+, D4
BNE.B @L1
TST.L -4(A6)
BNE.B @L2
@L1 SUBQ #$2, SP
PEA.L -4(A6)
MOVE #$2, -(SP)
PEA.L MASKRECT(A6)
MOVE.L D3, -(SP)
CLR.L -(SP)
CLR.L -(SP)
MOVE.L #$160000,D0 ;_QDExtensions -> _NewGWorld
DC.W $AB1D
MOVE (SP)+, D4
@L2 MOVE.L D3, -(SP)
DC.W $AA24 ;_DisposCTable
TST D4
BNE.B @skip
MOVE.L -4(A6), D0
BEQ.B @skip
MOVEA.L D0, A3
SUBQ #$8, SP
PEA.L $4(SP)
PEA.L $4(SP)
MOVE.L #$80005,D0 ;_QDExtensions -> _GetGWorld
DC.W $AB1D
MOVE.L -4(A6), -(SP)
CLR.L -(SP)
MOVE.L #$80006,D0 ;_QDExtensions -> _SetGWorld
DC.W $AB1D
MOVE.L MASKBITS(A6), -(SP)
PEA.L $2(A3)
MOVE.L MASKRECT(A6), -(SP)
PEA.L $10(A3)
CLR -(SP)
CLR.L -(SP)
DC.W $A8EC ;_CopyBits
SUBQ #$2, SP
MOVE.L $2(A3), -(SP)
MOVE.L #$40001,D0 ;_QDExtensions -> _LockPixels
DC.W $AB1D
ADDQ #$2, SP
MOVEA.L $2(A3), A0
_HLock
MOVE.L (A0), MASKBITS(A6)
MOVE.L #$80005,D0 ;_QDExtensions -> _GetGWorld
DC.W $AB1D
@skip
; SET UP REGISTERS FOR CALLING CMDEVLOOP
MOVE.L DSTBITS(A6),A1 ;GET DST BIT/PIXMAP
@ -1763,7 +1873,15 @@ SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS
NOTPORT MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) <BAL 28May89>
JSR CMDevLoop ;AND DRAW THE IMAGE
MOVE.L -4(A6),D0
BEQ.S @skipQDCall
MOVE.L D0,-(SP)
MOVE.L #$40004,D0 ;_QDExtensions -> _DisposeGWorld
DC.W $AB1D
@skipQDCall
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
UNLINK PARAMSIZE,'KopyMask'
@ -2296,9 +2414,9 @@ cutOutDevices
move.l pmTable(a0),a0 ;get handle to source color table
move.l (a0),a0 ;deref it
cmp.l ctSeed(a0),d1 ;do the color tables seeds match ?
beq.s @next
beq @next
movem.l d1/a1,-(sp) ;save our scratch registers
movem.l d1/a1-a3,-(sp) ;save our scratch registers
clr.b -(sp) ;make space for boolean result
pea tempRect1(a6) ;pointer to the SrcRect in global coordinates
@ -2307,7 +2425,34 @@ cutOutDevices
pea tempRect2(a6) ;pointer to the result
_SectRect ;get the intersection
tst.b (sp)+ ;if they didn't intersect at all, then skip to
beq.s @skip ;..the next device
beq @skip ;..the next device
move.l (a1),a0
move.l GDPMap(a0),a0
move.l (a0),a0
move.l pmTable(a0),a0
move.l (a0),a0
move.l (DeviceList),a2
@again move.l (a2),a2
move.l GDPMap(a2),a3
move.l (a3),a3
move.l pmTable(a3),a3
move.l (a3),a3
move.l (a3),d0
cmp.l (a0),d0
bne @done
sub.l #8,sp
clr.b -(sp)
pea.l tempRect1(a6)
pea.l $22(a2)
pea.l $a(sp)
_SectRect
tst.b (sp)+
add.l #8,sp
bne @skip
@done move.l GDNextGD(a2),d0
move.l d0,a2
bne.s @again
lea tempRect2(a6),a0 ;point to our temp rect
pea topleft(a0) ;convert the temp rect back to local coordinates
@ -2323,7 +2468,7 @@ cutOutDevices
move.l d6,-(sp)
_DiffRgn
@skip movem.l (sp)+,d1/a1 ;restore our scratch registers
@skip movem.l (sp)+,d1/a1-a3 ;restore our scratch registers
@next move.l (a1),a0 ;deref the current device list handle
move.l GDNextGD(a0),d0 ;get the next device handle into D0

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@ PrNonPortable EQU 1
WholeErrors EQU 1
AddrModeFlag EQU 0
Quicker EQU 1
has32BitQD EQU 1
ROMPaletteMgr EQU 1 ;set to zero for System Disk, 1 for ROM build <C864>
@ -155,6 +156,7 @@ BlockHead PROC EXPORT
endif
INCLUDE 'BITBLT.a'
INCLUDE 'cCrsrCore.a'
INCLUDE 'QDExtensions2.a'
INCLUDE 'QDUtil.a'
INCLUDE 'Colorasm.a'
INCLUDE 'Patterns.a'

View File

@ -221,8 +221,8 @@ SlotParms EQU IOPBlk-spBlock.SPBlockSize ; parameter block for slot manag
VidParms EQU SlotParms-12 ; [12] size of mode params
StartList EQU VidParms-4 ; [long] pointer to start of resource
VARSIZE EQU StartList ; size of local vars for CheckDevices
UTILVARS EQU VidParms ; size of local vars for utility routines
VARSIZE EQU StartList-4 ; size of local vars for CheckDevices
UTILVARS EQU VidParms-$30 ; size of local vars for utility routines
; ¥¥¥ Start of Code ¥¥¥
;
@ -317,557 +317,42 @@ SetDevGamma
; ----------------------------------------------------------------------------------------------------------
NewFunc
Link A6,#-$B4
Move.l A2,-(SP)
Move.l (A0),A2
Lea.l -$94(A6),A1
Move.l #-2,(A1)
Lea.l -$B4(A6),A0
Move.l A0,$C(A1)
Lea.l -$40(A6),A0
Move (A2),$18(A0)
Move #$14,$1A(A0)
Move.l A1,$1C(A0)
dc.w $A205 ; _PBStatusImmed
Move.l (SP)+,A2
Unlk A6
Rts
CheckDevices ; <19>: Moved label from within if-endif to embed utility
; routines. It would be nice to be able to the the LINK
; stuff AFTER the GotScrn entrypoint.
LINK A6,#VARSIZE ; allocate local stack frame
MOVEM.L A0-A6/D0-D7,-(SP) ; so we donÕt screw up the boot process
;+++ MOVEM.L D6-D7/A2-A4,-(SP) ; save work registers
MOVEM.L A0-A4/D0-D7,-(SP) ; so we donÕt screw up the boot process
;+++; check to see if the device list needs to be initialized
;+++
;+++ MOVE.L DeviceList,A0 ; get handle to device list
;+++ MOVE.L (A0),A0 ; point to head of device list
;+++ MOVE GDFlags(A0),D0 ; get the flags word
;+++ BTST #allInit,D0 ; test initialize flag?
;+++ BNE GoHome ; => devices already initialized
; ¥¥¥ 1st INIT ¥¥¥
;
; Try to load in the resource. If none, then just do a SetEntries on the boot device (see
; the comments on the NoScrn code below).
;
GetScrn
CLR.L -(SP) ; make room for function result
MOVE.L #'scrn',-(SP) ; push desired resource type
CLR -(SP) ; resource ID = 0
_GetResource ; get the resource
MOVE.L (SP)+,D0 ; get the resource handle
Beq.s NoScrn ; if nil, do the no 'scrn' code
; ¥¥¥ 2nd INIT ¥¥¥
;
; Test the scrnInval low-mem to make sure the screen resource is valid. (Note: scrnInval
; will generally be cleared by the video cardÕs primaryInit IF the information in
; pRAM doesnÕt match the current set up). This is ALSO a case where we need to
; make a SetEntries call so the screen colors donÕt change on the the first SetEntries
; and/or SetGamma call.
;
ChkScrn
Tst.b scrnInval ; If the 'scrn' resource is not invalid,
Bne.s GotScrn ; then just go on.
Move.l D0,A4 ; Save the 'scrn' resource handle.
Move.l #gestaltDisplayMgrAttr,D0 ; We need to know if the Display Manager is around.
_Gestalt ; Ask, and ye shall receive.
Bne.s @NoDM ; Oops, got an error.
Move.l A0,D0 ; Get the result into D0.
Btst #gestaltDisplayMgrPresent,D0 ; If the Display Manager is around, then
Bne.s NoScrn ; donÕt dispose of the 'scrn' resource so
@NoDM ; so that the Display Manager can deal with it.
Clr.w -(Sp) ; Make room for resFile refNum.
Move.l A4,-(Sp) ; Push 'scrn' resource handle for resFile.
_HomeResFile ; Get refNum.
Move.l A4,-(Sp) ; Push 'scrn' resource handle for remove.
_RmveResource ; Try to remove it.
Tst.w ResErr ; If everything is okay, then
Beq.s @DisposeIt ; just go on.
Tst.w (Sp)+ ; Clean up the stack.
Move.l A4,D0 ; Get 'scrn' resource handle back into D0.
Bra.s GotScrn ; And weÕre screwed.
@DisposeIt Movea.l A4,A0 ; Get 'scrn' resource handle into A0.
_DisposHandle ; Dispose it.
_UpdateResFile ; Update the 'scrn's resFile lest we die later.
; If a 'scrn' resource is NOT around weÕll get here. The only thing we want to do at this
; point is to call SetDevEntries on the boot device so that the screen will not change colors
; after a SetEntries/SetGamma call is made later.
;
NoScrn
Move.l DeviceList,A0 ; A0 contains gDevice.
Move.l #-1,A1 ; Use gDeviceÕs PixMap for colorTable.
Bsr.s SetDevEntries ;
Bra NoGammaFix
; ¥¥¥ 3rd INIT ¥¥¥
;
; Lock down the 'scrn' handle, and point at the data (in A4).
;
GotScrn
MOVE.L DeviceList,A0 ; get handle to device list
MOVE.L (A0),A0 ; point to head of device list
BSET #allInit,GDFlags(A0) ; say list has been initialized
MOVE.L D0,-(SP) ; save 'scrn' resource for ReleaseResource
MOVE.L D0,A0 ; get the resource
_HLock ; lock it down
MOVE.L (A0),A4 ; A4 = resource pointer
; Validate the 'scrn' resource. There must be a descriptor for every screen device.
; I assume that there are no duplicate entries and that screens don't overlap.
; In addition the devices in the 'scrn' resource must be in slot order.
;
MOVE.L A4,StartList(A6) ; save pointer to start of list
MOVE (A4)+,D7 ; get the number of screens in resource
WITH spBlock,vpBlock
LEA SlotParms(A6),A0 ; get pointer to parameter block
MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0)
; set category ID, type
MOVE.W #drSwApple,spDrvrSw(A0) ; set software, hardware ID
MOVE.B #$01,spTBMask(A0) ; ignore spDrvrHw
MOVE.B #0,spSlot(A0) ; start with desired slot (0 to check built-in devices)
MOVE.B #0,spID(A0) ; start with first (zeroth) ID
CLR.B spExtDev(A0) ;
NxtDev _sNextTypesRsrc ; get next video device
BEQ.S GotDev ; => there is one
; There are no more screens; are there any more entries in the 'scrn' resource?
;
TST D7 ; there should have been one per device
BEQ GoodRsrc ; => there was, go initialize them
BRA BadScrn ;
; Scan through 'scrn' resource entry for this device.
;
GotDev MOVE (A4)+,D0 ; get type
CMP spDrvrHw(A0),D0 ; does it match?
BNE BadScrn ; => nope, bad screen resource
MOVE (A4)+,D0 ; get slot
CMP.B spSlot(A0),D0 ; does it match?
BNE.S BadScrn ; => nope, bad screen resource
; Get the DCE entry for the device and check dCtlDevBase.
; If no match, look for other devices in the same slot.
;
SlotOK MOVE spRefNum(A0),D0 ; get the refNum
NOT D0 ; refNum to unitnum
ASL #2,D0 ; offset in unitTable
MOVE.L UTableBase,A1 ; get the base of the unit table
MOVE.L (A1,D0),A3 ; A3 = handle to the DCE
MOVE.L (A3),A1 ; get pointer to the DCE
MOVE.L dCtlDevBase(A1),D0 ; get dCtlDevBase
CMP.L (A4)+,D0 ; do they match?
BNE.S BadScrn ; => nope, bad screen resource
; Test to make sure that the requested mode (screen depth) is valid in this video
; sRsrc list.
;
MOVE.B spID(A0),D1 ; save the spID (so that itÕs correct for the sNextTypesRsrc)
MOVE.W (A4)+,D0 ; get the mode
MOVE.B D0,spID(A0) ; insert into spBlock
_sFindStruct ; find the sRsrc list entry for this mode
BNE.S BadScrn ; if not, then the scrn resource is no good
MOVE.B D1,spID(A0) ; restore the spID
; To be completely compulsive about it, make sure there's a gDevice.
;
MOVE.L DeviceList,A3 ; A3 = first gDevice in list
MOVE spRefNum(A0),D1 ; get refnum (unaffected by sFindStruct)
@NxtGD MOVE.L (A3),A1 ; get pointer to device
CMP gdRefNum(A1),D1 ; does refnum match?
BEQ.S RectCheck ; => yes, this device matches!
MOVE.L gdNextGD(A1),D0 ; get handle of next device
MOVE.L D0,A3 ; get in A3
BNE.S @NxtGD ; => check all gDevices
BRA.S BadScrn ; => no such gDevice, bad 'scrn'
; Compare the size of the remembered screenRect to the size of this gDevice's
; gdRect. At this point, the gdRects are still topleft={0,0} from InitGDevice
; so we can just check 'scrn' rect against botRight.
;
RectCheck
ADD #8,A4 ; skip to global rect in 'scrn'
MOVE.W bottom(A4),D0 ; get bottom
SUB.W top(A4),D0 ; = height
CMP.W gdRect+bottom(A1),D0 ; is it equal?
BNE.S BadScrn ; nope, we're out
MOVE.W right(A4),D0 ; get right
SUB.W left(A4),D0 ; = width
CMP.W gdRect+right(A1),D0 ; is it equal?
BNE.S BadScrn ; nope, we're out
; This device matches! Go check the next one.
;
SkipData ADD #8,A4 ; skip to control field
MOVE (A4)+,D0 ; get number of control calls
BRA.S SkipCtl ; skip control call
SkipNxt MOVE.L (A4)+,D1 ; get control code, size of params
ADD D1,A4 ; add size of params to skip block
SkipCtl DBRA D0,SkipNxt ; => skip next control
SUBQ #1,D7 ; decrement device count
BMI.S BadScrn ; => oops, bad screen resource
LEA SlotParms(A6),A0 ; get pointer to parameter block <14>
BRA.s NxtDev ; => check next device <19>: .s
; If the 'scrn' resource is bad, then let's walk down the device list and offset
; the invalid screens' gdRects so that they don't all pile up at (0,0). Let's keep
; it simple--just put them all edge-to-edge, with the top edge at 0 (unchanged) and
; to the right of the previous guys'. Offset the gdPMap's rect also.
;
BadScrn
MOVE.L DeviceList,A0 ; get the head of the list (the boot screen)
MOVE.L (A0),A0 ; hndl->ptr
MOVE.W gdRect+right(A0),D1 ; get the boot screen's right edge (if the scrn
; is invalid, then this is the real right edge)
@Loop MOVE.L gdNextGD(A0),D0 ; get handle to next screen
BEQ ScrnDone ; when NIL we're out of here <19>: Done -> ScrnDone
MOVE.L D0,A0 ; get this device
MOVE.L (A0),A0 ; handle to ptr
ADD.W D1,gdRect+left(A0) ; offset the left edge (normally zero)
ADD.W D1,gdRect+right(A0) ; offset the right edge
MOVE.L gdPMap(A0),A1 ; get the gdPMap handle
MOVE.L (A1),A1 ; get the gdPMap pointer
ADD.W D1,pmBounds+left(A1) ; offset the left edge (normally zero)
ADD.W D1,pmBounds+right(A1) ; offset the right edge
MOVE.W gdRect+right(A0),D1 ; get the new right edge for the next device
BRA.S @Loop ; for each screen
GoodRsrc _HideCursor ; cursor must be hidden here
MOVE.B #true,CrsrBusy ; MARK CHANGE IN PROGRESS
; Configure each entry in the scrn resource
;
MOVE.L StartList(A6),A4 ; save pointer to start of list
MOVE (A4)+,D7 ; get the number of screens in resource
SUBQ #1,D7 ; make it 0 based
; It would be nice if this routine could use sRsrcInfo or sNextsRsrc here, but we
; don't keep the video sRsrc spID in the scrn resource, just the hw ID!!! To
; make up for this, we must do a search by type.
;
DoNxt LEA SlotParms(A6),A0 ; get pointer to parameter block
MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0)
; set category ID, type
MOVE.W #drSwApple,spDrvrSw(A0) ;
; set software, (invalid) hardware ID
MOVE (A4)+,spDrvrHw(A0) ; set driver hardware ID
MOVE.B #$00,spTBMask(A0) ; all fields valid
MOVE (A4)+,D0 ; get slot
MOVE.B D0,spSlot(A0) ; does it match?
MOVE.B #0,spID(A0) ; start with first ID
CLR.B spExtDev(A0) ;
_sNextTypesRsrc ; get next video device
;+++ BNE BadScrn ; => this should never be taken (so letÕs comment it out) <12>
; We found a device that matches the given description! Find its gDevice and configure it.
;
MOVE spRefNum(A0),D1 ; D1 = refnum
MOVE.L DeviceList,A3 ; A3 = first gDevice in list
@NxtGD MOVE.L (A3),A0 ; get pointer to device
CMP gdRefNum(A0),D1 ; does refnum match?
BEQ.S @GotGD ; => yes, got the gDevice
MOVE.L gdNextGD(A0),D0 ; get handle of next device
MOVE.L D0,A3 ; get in A3
BNE.S @NxtGD ; => check all gDevices
;+++ BRA BadScrn ; => this should never be taken (so letÕs comment it out) <12>
@GotGD MOVE.L (A4)+,D0 ; discard dCtlDevBase
; Set up the GDFlags word before calling InitGDevice.
;
MOVE.L (A3),A1 ; point at the grafDevice
MOVE gdFlags(A1),D0 ; get the flags word
AND 2(A4),D0 ; turn off the bits that are used
OR 4(A4),D0 ; turn on new bits
BSET #ramInit,D0 ; say we've initialized it
BSET #screenDevice,D0 ; and flag it as a screen device
MOVE D0,GDFlags(A1) ; set the flags word
; If main device, set up low-memory handles. (Wait: If the ramInit and screenDevice
; flags are NOT setup, then why would the mainScreen flag be setup? -- jmp)
;
MOVE gdFlags(A1),D0 ; get the flags word
BTST #mainScreen,D0 ; is it the main scrn?
BEQ.S @InitGD ; => no, go init device
MOVE.L A3,MainDevice ; set up as main screen device
MOVE.L A3,TheGDevice ; set up as default destination device
MOVE.L A3,SrcDevice ; set up as default source device
; AllocCursor called by InitCursor to init cursor
MOVE.L (A3),A0 ; point to gDevice
MOVE.L gdPMap(A0),A0 ; get pixMap handle
MOVE.L (A0),A0 ; point to pixMap
MOVE.L baseAddr(A0),D0 ; get base address
MOVE.L D0,scrnBase ; and set up screen base
LEA SlotParms(A6),A0 ; point at slot manager block again (it's still positioned from above)
MOVE (A4),D0 ; get the requested mode
MOVE.B #oneBitMode,spId(A0) ; pass the default mode (assumed to be 1-bit mode)
_sFindStruct ; point to this mode information
MOVE.B #mVidParams,spID(A0) ; now get the device pixmap
_sGetBlock ; on the current heap (system normally here)
MOVE.L spResult(A0),A1 ; get the result pointer
MOVE.w vpRowBytes(A1),screenRow ; get the screen row bytes (WORD)
; Set up the low-mem for screen resolution too. TheyÕre only WORD/WORD rather then FIXED/FIXED.
;
MOVE.W vpHRes(A1),ScrHRes ; Take the high word of vpHRes
MOVE.W vpVRes(A1),ScrVRes ; Take the high word of vpVRes
MOVE.L spResult(A0),A0 ; Do what it says in IM V (p 446) instead of
_DisposPtr ; of using _sDispose. <12>
@InitGD MOVE D1,-(SP) ; push refnum
MOVE (A4)+,-(SP) ; push mode
CLR -(SP) ; which should be long
MOVE.L A3,-(SP) ; push gDevice
_InitGDevice ; configure the gDevice
ADDQ #4,A4 ; mask and flags already used
; If there is a gamma table resource id, get the gamma correction table and call the driver.
; We need to do this before setting the color table (via SetEntries) to make sure it takes
; effect right away.
;
MOVE 2(A4),D0 ; get the gamma table resource id
CMP #-1,D0 ; is it -1?
BEQ.S ChkTbl ; => yes, no table
; If the gamma table resource id = -2, then request linear gamma from the driver.
;
CMP #-2,D0 ; is it -2?
BNE.S @GetFromSys ; nope, so load the system resource
;+++ LEA VidParms(A6),A1 ; point to parameter block
;+++ CLR.L csGTable(A1) ; pass NIL to tell new drivers to set linear
;+++ BSR.S GammaControl ; call a common routine to set gamma
; <19>: Use SetDevGamma instead of GammaControl
;
Move.l A3,A0 ; Put gDevice in A0 for SetDevGamma call.
Move.l #0,A1 ; (nil) gammaTable Ptr in A1 (to set linear).
Bsr.s SetDevGamma
;
BRA.S ChkTbl
; Load the gamma resource from the system and set it.
;
@GetFromSys CLR.L -(SP) ; make room for function result
MOVE.L #'gama',-(SP) ; push gamma table rsrc type
MOVE D0,-(SP) ; else push resource id
_GetResource ; try to read in gamma table
MOVE.L (SP)+,D0 ; get the result
BEQ.S ChkTbl ; => couldn't find it, use default
MOVE.L D0,-(SP) ; save a copy for later
MOVE.L D0,A0 ; setup for HLock
_HLock ;
;+++ LEA VidParms(A6),A1 ; point to params for SetGamma
;+++ MOVE.L (A0),csGTable(A1) ; gamma table pointer is only param
;+++ BSR.S GammaControl ; call a common routine
; <19>: Use SetDevGamma instead of GammaControl. For <23>, the setup for the
; SetDevGamma call was backwards.
;
Move.l (A0),A1 ; Put pointer to gammaTable in A1, and
Move.l A3,A0 ; put pointer to GDevice in A0.
Bsr.s SetDevGamma
;
MOVE.L (SP),A0 ; get the resource handle back
_HUnlock ; free it
_ReleaseResource ; and release it (fixing the stack)
; <19>: Commented out GammaControl as it is replaced by the SetDevGamma utility
; above. Also, the branch around the GammaControl routine is commented
; out.
;
;+++ BRA.S ChkTbl ; continue on
;
; Here's an imbedded utility. I know I burn 2 bytes always BSRing around it, but I
; would burn two with a word branch if the utility were outside. This routine sets
; up the iopb and csParam block for a SetGamma control call. It expects the csGTable
; field to be set up, the csParam block pointer in A1, and the gdevice pointer in A3.
;
;GammaControl
;
; LEA IOPBlk(A6),A0 ; point to parameter block
; MOVE.L A1,csParam(A0) ; move addr of parms into block
; MOVE.W #cscSetGamma,csCode(A0) ; cscSetGamma <12>
;+++ CLR.L ioCompletion(A0) ; no completion routine <16>: not necessary
;+++ CLR.W ioVRefNum(A0) ; no volRefNum <16>: not necessary
; MOVE.L (A3),A1 ; point to gdevice
; MOVE GDRefNum(A1),ioRefNum(A0) ; set device's refnum
; _Control ,IMMED ; SetGamma(GammaTable)
; ; if error here (likely if -2 were passed to
; ; and old driver) then just use default table
; RTS ; and back
;
;
; Previously, if there was a color table resource id, this part loaded that table. Now,
; it checks the state of the gdDevType bit. If it is monochrome (=0), then this routine
; substitutes pixelSize+32 for the resID. If it is color (=1) and in 2- or 4-bit mode, then
; pixelSize+64 is substituted to yield a modified color table that includes the highlight
; color.
;
; If we EVER have a gamma ID <> -1 (not default), then be sure to set the color table
; to flush this gamma into the CLUT hardware.
;
; The pointer to the gDevice is still in A1.
;
;
ChkTbl
MOVE.L (A3),A1 ; point to the gDevice again
MOVE.L gdPMap(A1),A0 ; get pixmap
MOVE.L (A0),A0 ; get pixmap ptr
MOVE.W pmPixelSize(A0),D0 ; get depth
CMP #clutType,gdType(A1) ; is it a direct/fixed (SKH) device? <SM9>
BNE SetGRect ; if so, then do nothing <19>:s <SM4> CSS
BTST #gdDevType,gdFlags+1(A1) ; is it color or monochrome mode?
BNE.S @ClrMode ; if set, then this is color
CMP.W #2,D0 ; 1 or 2 bit/pixel?
BLE.S @RegClr ; don't do anything funky
@MonoMode
ADD #32,D0 ; add 32 to pixelsize in all modes for linear gray
BRA.S @GetClut ;
@ClrMode
MOVE.W D0,D1 ; copy the depth
AND #9,D1 ; is it 1- or 8-bit mode?
BNE.S @RegClr ; if so, then do regular behavior
@Is2or4
ADD #64,D0 ; for 2- or 4-bit, add 64 to pixel depth (gives color+highlight)
;!!! BRA.S @GetClut ;
@RegClr
;!!! MOVE (A4),D1 ; get the color table resource id
;!!! CMP #-1,D1 ; is it -1?
;!!! BNE.S @GetClut ; if not, then set the CLUT
;!!! CMP #-1,2(A4) ; if CLUTid=-1, and gammaID<>-1, then set CLUT to flush
;!!! BEQ.S SetGRect ; if both are default, then continue
@GetClut CLR.L -(SP) ; make room for function result
MOVE D0,-(SP) ; push resource id
_GetCTable ; get a color table
MOVE.L (SP)+,D0 ; get the result
BEQ.S SetGRect ; => couldn't find it, use default
MOVE.L D0,A0 ; save source handle in A0
MOVE.L (A3),A1 ; point at the gDevice
MOVE.L gdPMap(A1),A1 ; get handle to its pixMap
MOVE.L (A1),A1 ; point at the pixMap
MOVE.L pmTable(A1),A1 ; get handle to existing color table
MOVE.L A1,-(SP) ; push the color table for later
MOVE.L A0,-(SP) ; push new table handle for dispose
_GetHandleSize ; get the source size
MOVE.L D0,D1 ; save size in D1
EXG A0,A1 ; get dest handle in A0
_SetHandleSize ; set the dest handle size
EXG A0,A1 ; swap dest back to A1, src to A0
MOVE.L (A0),A0 ; get source ptr
MOVE.L (A1),A1 ; get dst ptr
MOVE.L D1,D0 ; get size to move
_BlockMove ; copy it
_DisposCTable ; and dispose new handle
; Now call the driver to set this color table (handle on stack)
; <19>: Use SetDevEntries call instead of in-line code.
;
Move.l A3,A0 ; A0 contains gDevice.
Move.l (Sp),A1 ; A1 contain colorTable Handle
Bsr.s SetDevEntries ;
; MOVE.L (SP),A0 ; get handle to color table
; _HLock ; lock down the color table
; LEA VidParms(A6),A1 ; point to params for SetEntries
; MOVE.L (A0),A0 ; get ctabPtr
; CLR.W csStart(A1) ; start at zero, use sequence mode
; MOVE.W ctSize(A0),csCount(A1) ; for the length of the table
; LEA ctTable(A0),A0 ; get pointer to colorspecs
; MOVE.L A0,csTable(A1) ; color table pointer is first param
; LEA IOPBlk(A6),A0 ; point to parameter block
; MOVE.L A1,csParam(A0) ; move addr of parms into block
; MOVE.W #cscSetEntries,csCode(A0) ; cscSetEntries <12>
;+++ CLR.L ioCompletion(A0) ; no completion routine <14>: not necessary
;+++ CLR.W ioVRefNum(A0) ; no volRefNum <14>: not necessary
; MOVE.L (A3),A1 ; point to gdevice
; MOVE gdRefNum(A1),ioRefNum(A0) ; set device's refnum
; _Control ,IMMED ; do a SetEntries on color table
;
; MOVE.L (SP),A0 ; get handle to color table
; _HUnLock ; unlock the color table
; Finally, generate an inverse table for the table (handle on stack)
;
MOVE.L (A3),A1 ; point at the gDevice
MOVE.L gdITable(A1),-(SP) ; push inverse table handle
MOVEQ #4,D0 ; make 4-4-4 inverse tables
MOVE D0,gdResPref(A1) ; save in GDevice
MOVE D0,-(SP) ; and push res
_MakeITable ; and generate inverse table (color/inverse table handles still on stack)
; Use the specified rectangle to determine the device's global coordinates
;
SetGRect
ADDA #4,A4 ; skip the CLUT and gamma resID's
MOVE.L (A3),A0 ; point to the grafDevice
MOVE.L gdPmap(A0),A1 ; get handle to pixMap
MOVE.L (A1),A1 ; get pointer to pixMap
ADDQ #bounds,A1 ; point to pixMap.bounds
LEA gdRect(A0),A0 ; point to its rectangle
MOVE.L (A4)+,D0 ; get topLeft for mouse offset
MOVE.L D0,(A1)+ ; copy topLeft to pixMap.bounds
MOVE.L D0,(A0)+ ; copy topLeft to GDRect
MOVE.L (A4),(A1) ; copy botRight to pixMap.bounds
MOVE.L (A4)+,(A0)+ ; copy botRight to GDRect
; Parse and execute the additional control commands
;
MOVE (A4)+,D6 ; get number of control calls
BRA.S ChkNxtCtl ; => jump into end of dbra loop
DoCtl LEA IOPBlk(A6),A0 ; point to parameter block
LEA 4(A4),A1 ; point to call parameters
MOVE.L A1,csParam(A0) ; move addr of parms into block
MOVE.W (A4)+,csCode(A0) ; set control code
;+++ CLR.L ioCompletion(A0) ; no completion routine <14>: not necessary
;+++ CLR.W ioVRefNum(A0) ; no volRefNum <14>: not necessary
MOVE.L (A3),A1 ; point to gdevice
MOVE gdRefNum(A1),ioRefNum(A0) ; set device's refnum
_Control ,IMMED ; and issue the control call
MOVE (A4)+,D0 ; get size of param block
ADD D0,A4 ; skip param block
ChkNxtCtl DBRA D6,DoCtl ; loop for all control calls
ChkNxt DBRA D7,DoNxt ; loop for all screens in resource
MOVE.L MainDevice,a0
move.l a0,CrsrDevice ; cursor is now on main device, no longer on boot device
import GetDCtlEntry
subq #4,sp ; room for resulting DCE handle
move.l (a0),a0
move.w gdRefnum(a0),-(sp) ; get the refNum
jsr GetDCtlEntry
move.l (sp)+,a0 ; get handle to DCE
move.l (a0),a0 ; get pointer to DCE
move.l #0,d0 ; clear out D0
move.b dCtlSlot(a0),d0 ; get the slot number
_AttachVBL ; attach VBL to this slot
CLR.B CrsrBusy ; end of change
_AllocCursor ; make sure all cursor structs are updated
_ShowCursor ; now redisplay cursor
ScrnDone _ReleaseResource ; all done with the resource <19>: Done -> ScrnDone
; ¥¥¥ 4th INIT ¥¥¥
;
; As explained above in the SixPack update notes, the NoGammaFix is for $067C-class
@ -879,14 +364,7 @@ ScrnDone _ReleaseResource ; all done with the resource <19>: Done -> ScrnDone
;
NoGammaFix
Move.l ROMBase,A0 ; Point to ROMBase with A0.
If Not ForROM Then
Cmp.w #$067C,8(A0) ; If weÕre not running on a $67C
Bne GoHome ; ROM, then just go on.
Else
Cmp.w #$077D,8(A0) ; If weÕre not running on a $77D
Bne GoHome ; ROM, then just go on.
Endif
WITH spBlock,vpBlock
; Get the default gamma table from ROM (so we donÕt have to get it every time
; we find a card that needs it -- if we donÕt find any cards that need
@ -925,6 +403,15 @@ NoGammaFix
Move.l (A0),A0 ; DCE Ptr.
Move.b dCtlSlot(A0),D0 ; Save slot number.
Cmp.b #15,D0
Bcs.b @dont
Move.l A3,A0
Bsr.w NewFunc
Bne.s @reallyDont
Bra.s @skipGD
@dont
Lea SlotParms(A6),A0 ; Fill out SpBlock:
Move.b D0,spSlot(A0) ; spSlot = slot number
Clr.w spID(A0) ; spID = 0
@ -947,6 +434,8 @@ NoGammaFix
; We found a non-TFB card that contains no gamma table directory. So, we need to
; employ our fix, which is to make a SetGamma and then a SetEntries call.
@reallyDont
Move.l A2,A0 ; Lock down the gammaTable Handle.
_Hlock
@ -969,11 +458,6 @@ NoGammaFix
Move.l A2,A0 ; Dispose of the storage used for the
_DisposHandle ; gammaTable Handle.
GoHome
;+++ MOVEM.L (SP)+,D6-D7/A2-A4 ; restore work registers
MOVEM.L (SP)+,A0-A6/D0-D7 ; so we donÕt screw up the boot process
UNLK A6
; ¥¥¥ 5th INIT ¥¥¥
;
;----------------------------------------------------------------
@ -1139,7 +623,7 @@ DoDrvrPatches
;
; Save all registers to prevent problems with the ROM INIT running code.
;
MOVEM.L A0-A6/D0-D7,-(SP) ; so we donÕt screw up the boot process
MOVEM.L A5-A6,-(SP) ; so we donÕt screw up the boot process
;
; Point to UnitTable in A2.
@ -1195,7 +679,12 @@ NxtSlotLoop
MOVE.L (A2,D0*4),A1 ; get DCE handle
MOVE.L (A1),A1 ; get DCE pointer
MOVE.L A1,A4 ; save this for driver patching code below
MOVE.L (A1),A4
MOVE dCtlFlags(A1),D0
BTST.L #6,D0
BEQ.S @dont
MOVE.L (A4),A4
@dont
;
; Point to spBlock.
@ -1235,13 +724,7 @@ NxtSlotLoop
; Take the DCE pointer in A4 (from above), and test to see if we want to patch this driver.
;
@IntPtch
If Not ForROM Then
BTST #dRAMBased,dCtlFlags+1(A4) ; test if this is a driver in ROM (Erickson overpatch) <7.0>
BEQ NxtSlot ; if so, then continue to next slot <7.0>
Endif
MOVE.L dCtlDriver(A4),A1 ; get handle to driver
MOVE.L (A1),A1 ; get pointer to driver
MOVE.L A4,A1 ; get pointer to driver
MOVE.L drvrName+2(A1),D0 ; get a unique long from the name
CMP.L #'DrWV',D0 ; is it the 2-Page card?
@ -1342,201 +825,10 @@ Out LEA spBlockSize(SP),SP ; clean up the stack <SM6>
;
; Lets restore more registers than have ever been restored before. (Hey, you can never be too careful.)
;
MOVEM.L (SP)+,A0-A6/D0-D7 ; so we donÕt screw up the boot process
MOVEM.L (SP)+,A5-A6
MOVEM.L (SP)+,A0-A4/D0-D7 ; so we donÕt screw up the boot process
; ¥¥¥ 6th INIT ¥¥¥
;
if asINIT then
;
; Early in the boot process an _InitGraf was performed (for the Welcome to Mac box).
; It's not correct if the main screen moved away from the boot screen, so let's call
; InitGraf on these early globals to correct the problem. This will fix a problem
; with the LMgr "init" which didn't do an InitGraf while setting up the environment
; for an alert dialog.
;
; Note that for the new boot process this is no longer necessary.
;
PEA -4(A5)
_InitGraf
endif
; ¥¥¥ 7th INIT ¥¥¥
;
If Not ForROM Then
;---------------------------------------------------------------------
; Local variables, definitions, etc....
;---------------------------------------------------------------------
drHwDAFB Equ $001C ; Built-in Video Hardware ID for Macintosh Quadras 700/900/950.
DrvrVer950 Equ $0001 ; Version number of the Macintosh Quadra 950Õs video driver.
badEntry Equ $38 ; Location of bad table entry in the Macintosh Quadra 950 driver.
; Straight from the Macintosh Quadra 950 ROMÕs source codeÉ
;
DAFBVidPrivates RECORD 0
saveBaseAddr DS.L 1 ; the screen base address (NOT ST corrected!)
saveScreenBase DS.L 1 ; ST corrected version of saveBaseAddr.
saveSQElPtr DS.L 1 ; the SQ element pointer (for _SIntRemove)
saveGammaPtr DS.L 1 ; the pointer to the Gamma correction table
saveGamDispPtr DS.L 1 ; the pointer to the Gamma block
saveVDACBase DS.L 1 ; the base addr of the VDAC
saveDAFBBase DS.L 1 ; the base addr of the DAFB
saveVidPtr DS.L 1 ; pointer to a big block of DAFB video parameters
GFlags DS.W 1 ; flags word
has16bppACDC Ds.b 1 ; true if AC842A is around
pageModeSet Ds.b 1 ; true if the pRam PageMode enable bit is set
saveMode DS.W 1 ; the current mode setting (in lo-byte)
saveMonID DS.W 1 ; monitor type ID (in lo-byte)
saveSlotId DS.W 1 ; spID of video sRsrc (hi-order byte only!)
DAFBVidPrivSize EQU *
ENDR
; Flags within GFlags wordÉ
;
GrayFlag EQU 15 ; luminance mapped if GFlags(GrayFlag) = 1
IntDisFlag EQU 14 ; interrupts disabled if GFlags(IntFlag) =1
IsMono EQU 13 ; true if monochrome only display (Portrait/Kong)
UseSeq EQU 12 ; true if sequence mode SetEntries
UseTrans Equ 12 ; True if weÕre supposed to translate 5-bit into 8 (DAFB 16bpp).
Is16 EQU 11 ; true if 16Mhz (Slow) CPU
IsSlow Equ 11 ; True if Slow CPU (for DAFB, 25Mhz is slow).
IsDirect EQU 10 ; true if direct video mode, else chunkyIndexed
PsuedoIndex EQU 9 ; true if SetEntries request was mapped to indexed from sequential
; (due to screen depth hardware requirements)
Has16bppSRsrc Equ 9 ; True if FifthVidMode is 16bpp instead of 32bpp (DAFB).
SyncOnGreen Equ 8 ; True if weÕre supposed to put sync on green (DAFB).
bra.s PatchQuadra950Driver ; skip over the title
String Pascal
DAFBVideoTitle Dc.b '.Display_Video_Apple_DAFB'
Align 2
;---------------------------------------------------------------------
; Main
;---------------------------------------------------------------------
PatchQuadra950Driver
String AsIs
With SpBlock,DAFBVidPrivates
Quadra950SaveRegs Reg D4-D6 ; Define work registers.
If AsInit Then
Cmp.w #$3FFF,ROM85 ; If Color QuickDraw is not around,
Bne @ExitNow ; then just leave.
EndIf
Tst.l DeviceList ; If the device list is empty,
Beq @ExitNow ; then just leave.
Move.l DeviceList,A0 ; Get the DeviceList Handle.
Move.l (A0),A0 ; Make it a pointer.
Move.w gdRefNum(A0),D0 ; If thereÕs no driver, then
Beq @ExitNow ; we canÕt do anything here.
Movem.l Quadra950SaveRegs,-(Sp) ; Save work registers.
Suba.w #spBlockSize,Sp ; Allocate SpBlock
; The shipping version of the Macintosh Quadra 950Õs ROM (1.7F2) has a bug in the built-in video
; driver which prevents the DirectSetEntries call from working correctly when the attached display
; is put into 32 bit-per-pixel mode. To fix this problem, we just patch the bad table in place
; since it resides in the System heap.
;
Move.l Sp,A0 ; Get spBlock ptr into A0.
Clr.b spId(A0) ; Begin at id 0.
Clr.b spSlot(A0) ; We only care about Slot $0.
Clr.b spExtDev(A0) ; No external device.
Clr.b spTBMask(A0) ; No mask in search.
Move.w #catDisplay,spCategory(A0) ; Look for: Display,
Move.w #typVideo,spCType(A0) ; Video,
Move.w #drSwApple,spDrvrSW(A0) ; Apple,
Move.w #drHwDAFB,spDrvrHW(A0) ; DAFB.
Clr.l spParamData(A0) ; Look only for enabled sRsrcs.
Bset #foneslot,spParamData+3(A0) ; Limit search to this slot only.
_GetTypeSRsrc ; If built-in video is not enabled, then
Bne.s @AllDone ; just quit.
; We found the DAFB-based (Macintosh Quadra 700/900/950) built-in video in Slot $0.
;
Moveq #0,D5 ; Prepare D5.
Move.w spRefNum(A0),D5 ; Get the refNum.
Beq.s @AllDone ; If nil, then just leave (no driver).
Not.w D5 ; Convert the refNum intoÉ
Lsl.w #2,D5 ; Éa UTable index.
Add.l UTableBase,D5 ; Get a ptr to the AuxDCEHandle.
Move.l D5,A0 ; Get it into A0.
Move.l (A0),A0 ; Get the AuxDCEHandle.
Move.l (A0),A0 ; Get the AuxDCEPtr.
Move.l A0,D5 ; Save it for later.
move.w dCtlFlags(a0),d0 ; <27> Get driver flags
Move.l dCtlDriver(A0),A0 ; Get driver.
btst #dRAMBased,d0 ; <27> Check to see if dCtlDriver is a handle or a pointer
bz.s @gotDriverPointer ; <27> A ROM based driver means itÕs a pointer
Move.l (A0),A0 ; Get ptr to driver.
@gotDriverPointer
Move.l A0,D6 ; Save it for later.
Moveq #0,D0 ; Prepare D0.
Lea drvrName(A0),A0 ; Point to the driver name.
Move.l A0,D4 ; Save it for later.
Move.b (A0)+,D0 ; Get its length.
Swap D0 ; Save it.
Lea DAFBVideoTitle,A1 ; Point to the driver name we want.
Move.b (A1)+,D0 ; Get its length.
_CmpString ; Compare the names.
Tst.w D0 ; If they are not equal, then we donÕt know about
Bne.s @AllDone ; this DAFB driver, so just leave.
Moveq #0,D0 ; Re-prepare D0.
Move.l D4,A0 ; Re-point to the driver name.
Move.b (A0),D0 ; Get its length.
Addq #2,D0 ; Adjust offset to version field.
Bclr #0,D0 ; Adjust offset for word alignment.
Move.w (A0,D0),D4 ; Get the driverÕs version number.
Cmp.w #DrvrVer950,D4 ; If this isnÕt the Quadra 950Õs driver version,
Bne.s @AllDone ; then just leave.
Adda.w D0,A0 ; Point to version part of driver name.
Move.l A0,D4 ; Save it for later.
; We found the Macintosh Quadra 950Õs version of the DAFB driver.
;
Move.l D5,A0 ; Re-point to the AuxDCEPtr.
Move.l dCtlStorage(A0),A0 ; Get the Handle to DAFB private storage.
Move.l (A0),A0 ; Make it a pointer.
Btst #Has16bppSRsrc,GFlags(A0) ; If a 16bpp-capable sRsrc is not in use,
Beq.s @AllDone ; then just leave.
Move.l D6,A0 ; Re-point to the DAFB driver.
Move.b #$FF,badEntry(A0) ; Fix the bad table entry.
Move.l D4,A0 ; Re-point to the DAFB driver version number.
Move.w #DrvrVer950+1,(A0) ; Update it.
@AllDone
Add.w #spBlockSize,Sp ; Deallocate SpBlock.
Movem.l (Sp)+,Quadra950SaveRegs ; Restore work registers.
@ExitNow ; Outta here, dudes.
Rts
Endwith
Else
Rts
Endif
UNLK A6
RTS
END

View File

@ -637,7 +637,7 @@ Seed
MOVE.L D5,D4 ; copy total # of color (and cleared hi word)
SUBQ #2,D4 ; this is the number of colors remaining
BLE.S QVille ; if zero or negative, all done
BLT.S QVille ; if zero or negative, all done
MOVEQ #1,D5 ; start at color #1 (zero based)
@TheRestOfUs ; a temporary label for the rest of us
BSR.S QUtil ; queue it

View File

@ -21,6 +21,7 @@ QDPatchesDir = {ColorQDDir}Patches:
CQDObjs = "{ObjDir}CheckDevicesINIT.a.o" ¶
"{ObjDir}CQD.a.o" ¶
"{LibDir}MoreCQD.lib" ¶
"{ObjDir}DeviceLoop.a.o"
@ -28,8 +29,8 @@ CQDObjs = "{ObjDir}CheckDevicesINIT.a.o"
Rez {StdROpts} -o "{Targ}" "{ColorQDDir}CQD.r" -i "{QDPatchesDir}"
# "{LibDir}CQD.lib" Ä {CQDObjs}
# Lib {StdLibOpts} -o "{Targ}" {CQDObjs}
"{LibDir}CQD.lib" Ä {CQDObjs}
Lib {StdLibOpts} -o "{Targ}" {CQDObjs}
"{ObjDir}CheckDevicesINIT.a.o" Ä "{ColorQDDir}CheckDevicesINIT.a"

View File

@ -105,8 +105,38 @@ LocalSize EQU *
link A6, #LocalSize
movem.l D3-D7/A2-A4, callerRegs(A6) ; save the callers registers
btst #6, ROM85 ; Color QuickDraw available?
bnz @classicQD ; if not, handle old case
machine MC68030
move.l ([$2b6],$1fc),a0
machine MC68020
tst.b $b5(a0)
beq.s @noShield
move.l drawingRgn(a6),d0
beq.s @noConversion
move.l d0,a0
move.l (a0),a0
move.l $2(a0),localRect+0(a6)
move.l $6(a0),localRect+4(a6)
pea localRect+0(a6)
_LocalToGlobal
pea localRect+4(a6)
_LocalToGlobal
bra.s @proceedWithShield
@noConversion
move.l #$80008000,localRect+0(a6)
move.l #$7fff7fff,localRect+4(a6)
@proceedWithShield
pea localRect+0(a6)
clr.l -(sp)
_ShieldCursor
@noShield
move.l TheGDevice, D0 ; Get the handle to the current GDevice
move.l MainDevice, D1 ; Get the handle to the main device
@ -149,11 +179,11 @@ LocalSize EQU *
beq @noMore ; if so, no more devices
move.l (A4), A3 ; point at the GDevice record
bsr TestAndIntersect ; is device good for drawing?
bz.s @nextDevice ; if not, keep searching
bz @nextDevice ; if not, keep searching
move.l flags(A6), D0 ; get the callerÕs options
btst #allDevicesBit, D0 ; are we ignoring regions?
bnz.s @visRgnSetup ; if so, donÕt change the visRgn
bnz @visRgnSetup ; if so, donÕt change the visRgn
move.l D4, -(SP) ; rectangle region handle
pea localRect(A6) ; this device (local coords)
@ -175,10 +205,12 @@ LocalSize EQU *
move.l ctSeed(A0), D7 ; stash deviceÕs ctab seed
move.l flags(A6), D0 ; get callerÕs flags
btst #singleDevicesBit, D0 ; should we group devices?
bnz.s @groupingDone ; if not, donÕt call AddSimilar
bnz @groupingDone ; if not, donÕt call AddSimilar
bsr AddSimilarDevices ; find all the like devices
@groupingDone
movem.l D3-D7/A2-A4/A6, -(SP) ; save OUR registers
bsr NewFunc1
move D2,-(SP)
swap D6
move.l D6, -(SP) ; pass depth and flags
move.l A4, -(SP) ; and the GDHandle
@ -187,6 +219,8 @@ LocalSize EQU *
movem.l callerRegs(A6), D3-D7/A2-A4 ; restore callerÕs registers
move.l A6Link(A6), A6 ; and restore callerÕs A6
jsr (A0) ; call the drawing procedure
move (SP)+,D2
bsr NewFunc2
movem.l (SP)+, D3-D7/A2-A4/A6 ; get OUR register set back
move.l (A4), A3 ; fix GDevicePtr
@nextDevice
@ -194,13 +228,6 @@ LocalSize EQU *
addq #1, D3 ; increment device number
bra.s @deviceIntersect ; try this one
@classicQD
move.l A6, -(SP) ; save our stack frame ptr
move.w #1, -(SP) ; pass depth (always 1)
move.w #fakeDeviceFlags, -(SP) ; and gdflags (something reasonable)
clr.l -(SP) ; NIL for GDHandle
bra.s @simpleDeviceCommon
@oneDevice
move.l A6, -(SP) ; save our stack frame ptr
move.l gdPMap(A0), A1 ; PixMapHandle
@ -230,6 +257,17 @@ LocalSize EQU *
_DisposRgn
move.l savedVis(A6), visRgn(A2) ; put original visRgn back
@exit
machine MC68030
move.l ([$2b6],$1fc),a0
machine MC68020
tst.b $b5(a0)
beq.s @noShow
_ShowCursor
@noShow
movem.l callerRegs(A6), D3-D7/A2-A4 ; restore regs
unlk A6
move.l (SP)+, A0 ; clean stack and return
@ -252,27 +290,30 @@ AddSimilarDevices
movem.l A3-A4/D3/D6, -(SP) ; save original state
andi.w #importantFlagsMask, D6 ; keep only pertinent flags
move.l A3, A1
move.l gdNextGD(A3), A4 ; start with next device
addq #1, D3 ; which is next in number, too
@addLoop
move.l A4, D0 ; is there a GDHandle?
bz.s @noMore ; if NIL, then weÕre done
bz @noMore ; if NIL, then weÕre done
move.l (A4), A3 ; handle->ptr
bsr.s TestAndIntersect ; see if device is okay by itself
bz.s @nextDevice ; if not, try next one
move.l A1, -(SP)
bsr TestAndIntersect ; see if device is okay by itself
move.l (SP)+, A1
bz @nextDevice ; if not, try next one
move.w gdFlags(A3), D0 ; get device attributes
andi.w #importantFlagsMask, D0 ; strip unimportant ones
cmp.w D0, D6 ; is this device similar to test device?
bne.s @nextDevice ; if not, donÕt use it
bne @nextDevice ; if not, donÕt use it
move.l gdPMap(A3), A0 ; get deviceÕs PixMapHandle
move.l (A0), A0 ; get deviceÕs PixMapPtr
move.l D6, D0 ; get depth and flags
swap D0 ; get depth into low word
cmp.w pmPixelSize(A0), D0 ; save depth as test device?
bne.s @nextDevice ; if not, donÕt use it
bne @nextDevice ; if not, donÕt use it
move.l flags(A6), D0 ; get the option flags
btst #dontMatchSeedsBit, D0 ; should we check ctSeeds?
@ -280,12 +321,49 @@ AddSimilarDevices
move.l pmTable(A0), A0 ; handle to color table
move.l (A0), A0
cmp.l ctSeed(A0), D7 ; are the seeds the same?
bne.s @nextDevice ; if not, donÕt use this one
bne @nextDevice ; if not, donÕt use this one
@seedsChecked
move.l A3, A0
move.l $22(A1), D0
cmp $24(A0), D0
bgt.s @L4
blt.s @L1
swap D0
cmp $22(A0), D0
bgt.s @L5
blt.s @L2
move.l $26(A1), D0
cmp $28(A0), D0
blt.s @L6
bgt.s @L3
bra.s @nextDevice
@L1 swap D0
cmp $22(A0), D0
bgt.s @doneWhateverThatWas
@L2 move.l $26(A1), D0
cmp $28(A0), D0
blt.s @doneWhateverThatWas
@L3 swap D0
cmp $26(A0), D0
blt.s @doneWhateverThatWas
bra.s @nextDevice
@L4 swap D0
cmp $22(A0), D0
blt.s @doneWhateverThatWas
@L5 move.l $26(A1), D0
cmp $28(A0), D0
bgt.s @doneWhateverThatWas
@L6 swap D0
cmp $26(A0), D0
bgt.s @doneWhateverThatWas
bra.s @nextDevice
@doneWhateverThatWas
move.l flags(A6), D0 ; what are the current options?
btst #allDevicesBit, D0 ; are we ignoring drawingRgn?
bnz.s @visRgnSetup ; if so, no regions to setup
move.l A1, -(SP)
move.l D4, -(SP) ; rectangle region handle
pea localRect(A6) ; this device (local coords)
@ -299,6 +377,7 @@ AddSimilarDevices
move.l (SP), -(SP) ; get ORed together
_XorRgn ; XOr is a fast way to Union when guaranteed no overlap
move.l (A4), A3 ; fix GDevicePtr
move.l (SP)+, A1
@visRgnSetup
bset.l D3, D5 ; mark this device done
@ -347,4 +426,73 @@ TestAndIntersect
@exit
rts
NewFunc1
moveq #0, D2
move.l (DeviceList), D0
beq.s @return
moveq #0, D1
@L0 movea.l D0, A0
movea.l (A0), A0
cmp D3, D1
beq.s @L8
tst $14(A0)
bpl.s @L8
movea.l (A4), A1
move.l $22(A1), D0
cmp $24(A0), D0
bgt.s @L4
blt.s @L1
swap D0
cmp $22(A0), D0
bgt.s @L5
blt.s @L2
move.l $26(A1), D0
cmp $28(A0), D0
blt.s @L6
bgt.s @L3
bra.s @L7
@L1 swap D0
cmp $22(A0), D0
bgt.s @L8
@L2 move.l $26(A1), D0
cmp $28(A0), D0
blt.s @L8
@L3 swap D0
cmp $26(A0), D0
blt.s @L8
bra.s @L7
@L4 swap D0
cmp $22(A0), D0
blt.s @L8
@L5 move.l $26(A1), D0
cmp $28(A0), D0
bgt.s @L8
@L6 swap D0
cmp $26(A0), D0
bgt.s @L8
@L7 bclr.s #7, $14(A0)
bset.l D1, D2
@L8 addq #1, D1
move.l $1E(A0), D0
bne.s @L0
@return Rts
NewFunc2
tst D2
beq.s @return
move.l (DeviceList), D0
beq.s @return
@L10 move.l D0, A0
move.l (A0), A0
lsr #1, D2
bcc.s @L11
bset.s #7, $14(A0)
tst D2
beq.s @return
@L11 move.l $1E(A0), D0
bne.s @L10
@return Rts
END

View File

@ -2861,6 +2861,7 @@ renderIt
@singleByteFont
endif
; 72624
MOVE.L WidthTabHandle, -(SP) ;2) Push the Width Table Handle onto the stack
PEA fontID(A6) ;1) Push the Glyph Rec Ptr
TST.B FASTFLAG(A6) ;if slow no need for 32-bit stuff
@ -2868,7 +2869,6 @@ renderIt
TST.B needs32bit(A6) ;running 32 bit clean
BEQ.S @skip32 ;NOPE, so skip it
move.b MMUsave(a6),d0 ;get previous MMU state in d0
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
_sbRetrieveGlyph ;Call the routine via SplineDispatch
moveq #true32b,d0 ;switch to 32 bit addressing
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)

View File

@ -1005,7 +1005,7 @@ selectGetGray equ 25
MACRO
_ZapLinks
DoPaletteDispatch selectZapLinks,0
DoPaletteDispatch selectZapLinks,4
ENDM
MACRO
@ -2921,6 +2921,7 @@ _EmptyHandle OPWORD $A000+43
_InitApplZone OPWORD $A000+44
_SetApplLimit OPWORD $A000+45
_BlockMove OPWORD $A000+46
_BlockMoveData OPWORD $A000+46+$200
; Here are the event manager routines