mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-11-18 14:06:47 +00:00
2028 lines
69 KiB
Plaintext
2028 lines
69 KiB
Plaintext
;
|
||
; File: CCrsrCore.a
|
||
;
|
||
; Contains: system cursor/mouse routines. Contains the mouse interrupt receivers
|
||
; and cursor drawing and hiding routines.
|
||
;
|
||
; Written by: Bud Tribble 2-Oct-81
|
||
;
|
||
; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM6> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
||
; so they can conditionalized out of the build.
|
||
; <SM5> 2/4/93 CSS Update from Horror:
|
||
; <H3> 7/13/92 djw <GED> Overpatched DrawCursor, EraseCursor and SetCrsrData,
|
||
; vectorizing them to allow access later.
|
||
; <SM4> 6/11/92 stb <sm 6/9/92>stb Add comments from QDciPatchROM.a to ShowCursor,
|
||
; SetCCursor
|
||
; <SM3> 5/16/92 kc Add forRom conditionals around last change.
|
||
; <SM2> 5/16/92 kc Roll in Horror. Comments follow:
|
||
; <H2> 2/12/92 SWC Patched out most of CrsrVBLTask since the new cursor
|
||
; acceleration code does things differently.
|
||
; <7> 7/10/91 dba end of the forPost70 conditional; we are past 7.0 for good
|
||
; <6> 5/31/91 KON Register A2 gets trashed when setting a color cursor and there
|
||
; is more than one GDevice.
|
||
; <5> 9/17/90 BG Removed <4>. 040s are now behaving more reliably.
|
||
; <4> 6/25/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <3> 6/25/90 KON Obscure-show-hide leaves crsr hidden only, Obscure-hide-show
|
||
; leaves crsr obscured only.
|
||
; <2> 1/3/90 BAL Updated to latest local source version.
|
||
; <•1.7> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.6> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
|
||
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
|
||
; fixed up necessary files…
|
||
; <•1.5> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
||
; 4/7/89 BAL Moved crsrVBLTask to head of file and scrnAddress to end of file
|
||
; for VM.
|
||
; 9/7/88 BAL Altered showCursor to clear crsrObscure if showing cursor.
|
||
; 6/28/88 BAL Use special 1 to 24 bit pixel expansion routine.
|
||
; 6/21/88 BAL Finally fixed SetCCursor; Needed to Lock input handle across
|
||
; routine.
|
||
; 3/25/88 BAL Altered Show/Hide Cursor to use 32 bit clean addresses.
|
||
; 3/23/88 BAL Fixed bug in CrsrRect.right for pixel depth > 1.
|
||
; <C944> 11/7/87 BAL Rolled in patches to SetCCursor to preserve A2.
|
||
; 5/27/87 EHB Added fix to SetCCursor for trashed A2
|
||
; <C856> 5/26/87 CSL Fixed absolute cursor positioning problem.
|
||
; 10/13/86 EHB Rolled in new version of CrsrVBLTask
|
||
; 10/13/86 EHB Added AllocCrsr; called by AllocCursor.
|
||
; 10/6/86 EHB Added SetCCursor; redid other routines to support color.
|
||
; 10/2/86 EHB Redid inner loop of ShowCursor for color support
|
||
; 7/14/86 EHB Don't draw cursor if CRSRPTR not set up.
|
||
; <C63> 7/2/86 EHB CLEAR D0 BEFORE CALLING EXTBL ROUTINES. Multiply offset amount
|
||
; by depth for left pinning Check 8 longs of cursor
|
||
; <C63> 7/2/86 EHB Include colorequ in great equate purge
|
||
; <C60> 6/30/86 EHB New ShowCursor/HideCursor for depth support Fixed branch bug in
|
||
; ShieldCursor
|
||
; <C28> 5/30/86 CSL Added changes for Aladdin, and Aladdin Front desk bus support.
|
||
; <C1> 5/6/86 RDC Added fixes in ShowCursor routine
|
||
; <C1> 4/15/86 RDC Added changes for new 68020 Reno project (NuMac) - Added include
|
||
; for newequ.text to get at low mem equates for screen vars -
|
||
; Added changes in Cursor routines to use low mem for screen
|
||
; values
|
||
; 2/19/86 BBM Made some modifications to work under MPW
|
||
;_______________________________________________________________________
|
||
;
|
||
; Before Lonely Hearts
|
||
;_______________________________________________________________________
|
||
; 11/5/85 JTC for ELR (on telephone) Fix loop termination condition in
|
||
; HideCursor that killed MacPaint, e.g.
|
||
; 7/25/85 RDC Added include for HWequ file
|
||
; 7/23/85 RDC Moved mouse interrupt routines to IntHnd.Text
|
||
; 4/23/85 JTC Change to PIN hotSpot between 0 and 16, not 15. <23Apr85>
|
||
; 4/5/85 JTC Fix discontinuity in PinGuts; mask hotSpot with $000F000F in
|
||
; SetCursor; add ScreenAddress and ScreenSize to SysDef traplist;
|
||
; fix 'changed' test in SetCursor. Punted on desired call to get
|
||
; Cursor ID ... see Change note for details.
|
||
; 8/20/83 LAK Just uses CrsrThresh for scaling params.
|
||
; 8/18/83 LAK Changed name of CrsrTask to CrsrVBLTask (but why?).
|
||
; 7/20/83 SC Cleaned up after code review
|
||
; 4/28/83 AJH moved PinRect into crsrCore
|
||
; 1/28/83 AJH made SetCursor display it if its different
|
||
; 1/23/83 LAK Adapted for new equate files.
|
||
; 1/13/83 SC Decouple and scaled Cursor stuff
|
||
; 11/7/82 AJH Made ObscureCursor unbusy cursor if already obscured
|
||
; 10/16/82 LAK Modified for new LisaGraf cursor interface
|
||
; 9/5/82 LAK IntHnd now handles ext/sts interrupt resetting
|
||
; 8/26/82 LAK updated for 512-dots
|
||
; 8/5/82 LAK modified for INTHND change (no need to modify A0-1 for SCC port
|
||
; A) or read status reg.
|
||
; 5/4/82 LAK Updated MV1INT, MH1INT for SCC hardware
|
||
; 4/9/82 AJH Changed SHOWCURSOR to clip ala Rick Meyer's Lisa routines
|
||
; 10/31/81 AJH Hardwired the CRSR task into the VBL manager
|
||
; 10/19/81 bmw fixed a bug andy found in getscreen
|
||
; 7/3/81 AJH Installed "ObscureCursror" entry point and support
|
||
;
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
MACHINE MC68020 ;<C60/30JUN86>
|
||
|
||
cursorShadow EQU 0
|
||
|
||
CRSRCORE PROC EXPORT
|
||
EXPORT CrsrVBLTask
|
||
|
||
EXPORT InitCrTable
|
||
EXPORT PinRect
|
||
|
||
IMPORT ScrnAddress
|
||
IMPORT ScrnSize
|
||
IMPORT ScrnBitMap
|
||
IMPORT PATCONVERT ; expand routine for color cursors/patterns
|
||
IMPORT AllocCrsr ; proc at end of file
|
||
IMPORT SETCRSRDATA ; PROC AT END OF FILE
|
||
IMPORT SHFTTBL ; TO CONVERT DEPTH TO SHIFT
|
||
IMPORT RGetHSize
|
||
|
||
IMPORT BLITCURSOR,UNBLITCURSOR ; Cursor Pixelling <dvb 19sep88>
|
||
EXPORT DRAWCURSOR,ERASECURSOR ; Cursor Displaying <dvb 19sep88>
|
||
EXPORT CursorSect
|
||
EXPORT GETMAINCRSR ;JUST USED INTERNALLY
|
||
;
|
||
; offset table for jump table initialization
|
||
;
|
||
InitCrTable
|
||
DC.W HideCursor-InitCrTable
|
||
DC.W ShowCursor-InitCrTable
|
||
DC.W ShieldCursor-InitCrTable
|
||
DC.W ScrnAddress-InitCrTable
|
||
DC.W ScrnSize-InitCrTable
|
||
DC.W InitCursor-InitCrTable
|
||
DC.W SetCursor-InitCrTable
|
||
DC.W ObscureCursor-InitCrTable
|
||
DC.W AllocCrsr-InitCrTable
|
||
DC.W SetCCursor-InitCrTable
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; CrsrVBLTask - executed once each vertical retrace
|
||
;
|
||
|
||
; ugly equs - stay here for now!
|
||
adbCount EQU 0 ; word: number of valid error deltas
|
||
MaxCnt EQU adbCount+2 ; word: limit on number of error deltas
|
||
Err7 EQU MaxCnt+2 ; word: time-7 error magnitude
|
||
Err6 EQU Err7+2 ; word: time-6 error magnitude
|
||
Err5 EQU Err6+2 ; word: time-5 error magnitude
|
||
Err4 EQU Err5+2 ; word: time-4 error magnitude
|
||
Err3 EQU Err4+2 ; word: time-3 error magnitude
|
||
Err2 EQU Err3+2 ; word: time-2 error magnitude
|
||
Err1 EQU Err2+2 ; word: time-1 error magnitude
|
||
Error EQU Err1+2 ; word: accumulated error
|
||
GSize EQU Error+2
|
||
|
||
CrsrVBLTask ;COME HERE ON VERTICAL RETRACE
|
||
|
||
If Not forRom Then ; <H2>
|
||
TST.B CrsrNew ; Mouse changed?
|
||
BEQ TrackDone ; No … return
|
||
TST.B CrsrBusy ; Cursor locked?
|
||
BNE TrackDone ; Yes … return
|
||
|
||
TST.B CrsrCouple ; Cursor coupled to mouse?
|
||
BEQ NoComp ; No … skip computation <DSV>
|
||
|
||
MOVE.W MTemp+H,D0 ; Find ∆Mx
|
||
SUB.W RawMouse+H,D0
|
||
|
||
MOVE.W MTemp+V,D1 ; Find ∆My
|
||
SUB.W RawMouse+V,D1
|
||
|
||
MOVE.W D0,D2 ; x := |∆Mx|
|
||
BGE.S AbslXl
|
||
NEG.W D2
|
||
AbslXl
|
||
|
||
MOVE.W D1,D3 ; y := |∆My|
|
||
BGE.S AbslYl
|
||
NEG.W D3
|
||
AbslYl
|
||
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals <c856/26May87>
|
||
CMP.W D2,D3 ; D3 := magnitude(x,y)
|
||
BLS.S MagDone
|
||
EXG D2,D3
|
||
MagDone ASR.W #1,D3
|
||
ADD.W D2,D3
|
||
|
||
BNE.S DoComp ; Zero magnitude … don’t compute <c856/26May87>
|
||
MOVE.W #1,adbCount(A0) ; No hits <c856/26May87>
|
||
CLR.W Error(A0) ; No errors <c856/26May87>
|
||
BRA DoPin ; Update the cursor <c856/26May87>
|
||
DoComp
|
||
;
|
||
MOVEM.L D4-D5,-(A7) ; Save off registers
|
||
MOVE.W adbCount(A0),D4 ; D4 is the number of samples
|
||
CMP.W MaxCnt(A0),D4 ; Is Count less than MaxCnt
|
||
BGE.S CountOK
|
||
ADD.W #1,adbCount(A0) ; Yes … we will have one more error
|
||
CountOK
|
||
|
||
MOVE.W D3,D5 ; Magnitude at current time
|
||
|
||
MOVE.W D4,D2 ; Get Count
|
||
SUB.W #1,D2 ; Index into JTab
|
||
ASL.W #1,D2 ; REQUIRES BRA.S’s IN JUMP TABLES
|
||
JMP JTab(PC,D2.W) ; Jump to the right code per Count
|
||
|
||
JTab BRA.S E1 ; Count = 1
|
||
BRA.S E2 ; Count = 2
|
||
BRA.S E3 ; Count = 3
|
||
BRA.S E4 ; Count = 4
|
||
BRA.S E5 ; Count = 5
|
||
BRA.S E6 ; Count = 6
|
||
BRA.S E7 ; Count = 7
|
||
|
||
E8 ADD.W Err7(A0),D5 ; Accumulate time-7 magnitude
|
||
|
||
E7 ADD.W Err6(A0),D5 ; Accumulate time-6 magnitude
|
||
MOVE.W Err6(A0),Err7(A0) ; Shift out time-6 magnitude
|
||
|
||
E6 ADD.W Err5(A0),D5 ; Accumulate time-5 magnitude
|
||
MOVE.W Err5(A0),Err6(A0) ; Shift out time-5 magnitude
|
||
|
||
E5 ADD.W Err4(A0),D5 ; Accumulate time-4 magnitude
|
||
MOVE.W Err4(A0),Err5(A0) ; Shift out time-4 magnitude
|
||
|
||
E4 ADD.W Err3(A0),D5 ; Accumulate time-3 magnitude
|
||
MOVE.W Err3(A0),Err4(A0) ; Shift out time-3 magnitude
|
||
|
||
E3 ADD.W Err2(A0),D5 ; Accumulate time-2 magnitude
|
||
MOVE.W Err2(A0),Err3(A0) ; Shift out time-2 magnitude
|
||
|
||
E2 ADD.W Err1(A0),D5 ; Accumulate time-1 magnitude
|
||
MOVE.W Err1(A0),Err2(A0) ; Shift out time-1 magnitude
|
||
|
||
E1 MOVE.W D3,Err1(A0) ; Shift out current magnitude
|
||
|
||
MOVE.W D4,D2 ; Round up the divide
|
||
ASR.W #1,D2 ; by half the denominator
|
||
ADD.W D2,D5
|
||
EXT.L D5 ; Set up for the divide
|
||
DIVU D4,D5 ; Find the average magnitude
|
||
|
||
MOVE.W D3,D4 ; Get the original magnitude
|
||
SUB.W D5,D3 ; Find distance to average magnitude
|
||
ADD.W Error(A0),D3 ; Add on the accumulated error
|
||
CMP.W #-1,D3 ; Define -1 div 2 = 0
|
||
BNE.S DivOK
|
||
CLR.W D3
|
||
DivOK ASR.W #1,D3 ; Get half of it
|
||
MOVE.W D3,Error(A0) ; Update it
|
||
ADD.W D5,D3 ; Desired mag is average+Error
|
||
|
||
CMP.W #255,D5 ; mag := MAX(mag,255)
|
||
BLS.S MaxDone
|
||
MOVE.B #255,D5
|
||
MaxDone
|
||
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get at globals
|
||
add #GSize,a0 ; <10/24/86 SMH> point to table
|
||
|
||
CLR.W D2 ; i := 0
|
||
|
||
Search ADD.B #1,D2 ; repeat
|
||
CMP.B (A0)+,D5 ; i := i+1
|
||
BHI.S Search ; until mag ≤ Table[i]
|
||
|
||
MULS D2,D3 ; D4 := i*(Mag(∆M)+Error)
|
||
|
||
MULS D3,D0 ; ∆Cx := (∆Mx*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
DIVS D4,D0 ; <<<<<< D3 >>>>>>>
|
||
BMI.S @1 ; branch if minus
|
||
ANDI.W #$007F,D0 ; control max displacement (fix mouse jump)
|
||
BRA.S @3
|
||
@1
|
||
ORI.W #$FF80,D0 ; control max displacement (fix mouse jump)
|
||
@3
|
||
MULS D3,D1 ; ∆Cy := (∆My*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
DIVS D4,D1 ; <<<<<< D3 >>>>>>>
|
||
BMI.S @5 ; branch if minus
|
||
ANDI.W #$007F,D1 ; control max displacement (fix mouse jump)
|
||
BRA.S @7
|
||
@5
|
||
ORI.W #$FF80,D1 ; control max displacement (fix mouse jump)
|
||
@7
|
||
MOVEM.L (A7)+,D4-D5 ; Restore registers
|
||
ADD.W D0,RawMouse+H ; Update raw mouse location
|
||
ADD.W D1,RawMouse+V
|
||
;
|
||
DoPin ; <c456/26May87>
|
||
LEA CrsrPin,A0 ; Bounding rect for cursor
|
||
MOVE.L RawMouse,D0 ; Pin mouse inside rect
|
||
|
||
Endif ; Not forRom <H2>
|
||
|
||
BSR.S ScrnPin ; return to SHOWIT if screen changes
|
||
|
||
MOVE.L D0,RawMOUSE ; update cursor loc with clipped pt
|
||
MOVE.L D0,MTEMP ; Update real mouse location with ""
|
||
|
||
AND.L MOUSEMASK,D0 ; do jerky masking to drop low order bits
|
||
MOVE.L MOUSEOffset,D1 ; Get the offset
|
||
BEQ.S skipPin ; and skip 2nd pin if not
|
||
ADD.L D1,D0 ; do jerky offset
|
||
BSR.S ScrnPin ; return to SHOWIT if screen changes
|
||
|
||
skipPin MOVE.L D0,MOUSE
|
||
|
||
NotCup BSR ERASECURSOR ; HIDE THE CURSOR <dvb 19sep88>
|
||
SHOWIT CLR.B CRSRNEW ; RESET THE CURSOR CHANGED FLAG
|
||
CLR.B CRSROBSCURE ; it's no longer obscured
|
||
BSR DRAWCURSOR ; AND SHOW CURSOR IN NEW POSITION <dvb 19sep88>
|
||
|
||
CRSRDONE ;AND RETURN
|
||
RTS
|
||
|
||
TrackDone
|
||
move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals
|
||
MOVE.W #1,adbCount(A0) ; No hits
|
||
CLR.W Error(A0) ; No errors
|
||
RTS ; Goodbye
|
||
|
||
NoComp move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals
|
||
MOVE.W #1,adbCount(A0) ; No hits
|
||
CLR.W Error(A0) ; No errors
|
||
BRA.S NotCup ; Update the cursor
|
||
|
||
|
||
; --------end of ugly jcrsrcoreTask
|
||
|
||
|
||
|
||
ScrnPin CMP LEFT(A0),D0 ;less than left?
|
||
BGE.S LEFTOK ;if not, no problem
|
||
BSR.S FindScreen ;=>look for new screen
|
||
MOVE LEFT(A0),D0 ;pin to the left
|
||
|
||
LEFTOK CMP RIGHT(A0),D0 ;greater than right?
|
||
BLT.S RIGHTOK ;if not, no problem WAS BLE!! <05Apr85>
|
||
BSR.S FindScreen ;=>look for new screen
|
||
MOVE RIGHT(A0),D0 ;pin to the right
|
||
SUBQ #1,D0 ;really want one less
|
||
|
||
RIGHTOK SWAP D0 ;consider y
|
||
CMP TOP(A0),D0 ;less than top?
|
||
BGE.S TOPOK ;if not, no problem
|
||
SWAP D0
|
||
BSR.S FindScreen ;=>look for new screen
|
||
SWAP D0
|
||
MOVE TOP(A0),D0 ;pin to the top
|
||
|
||
TOPOK CMP BOTTOM(A0),D0 ;greater than bottom?
|
||
BLT.S BOTOK ;if not, no problem WAS BLE!! <05Apr85>
|
||
SWAP D0
|
||
BSR.S FindScreen ;=>look for new screen
|
||
SWAP D0
|
||
MOVE BOTTOM(A0),D0 ;pin to the bottom
|
||
SUBQ #1,D0 ;really want one less
|
||
|
||
BOTOK SWAP D0
|
||
RTS ;and return
|
||
|
||
; Check to see if cursor has moved to another screen.
|
||
; If not, returns with D0 unchanged.
|
||
; If so, hides the cursor, updates cursor globals and does messy return.
|
||
;
|
||
; Clobbers D1-D3/A0-A3 which are preserved by interrupt handler
|
||
|
||
FindScreen MOVE D0,D3 ;pt.h in D3
|
||
MOVE.L D0,D1 ;pt.v in D1
|
||
SWAP D1 ;pt.v in D1
|
||
MOVE.L DeviceList,D2 ;get the first GDevice
|
||
BMI.S NoDev ;=>just in case no GDevice
|
||
DoDev MOVE.L D2,A3 ;get device handle
|
||
MOVE.L (A3),A3 ;get device pointer
|
||
TST GDFlags(A3) ;is screen active?
|
||
BPL.S NxtDev ;=>no, try next device
|
||
LEA GDRect(A3),A1 ;point to rect
|
||
CMP (A1)+,D1 ;above top?
|
||
BLT.S NxtDev ;=>yes, check next device
|
||
CMP (A1)+,D3 ;to left of screen?
|
||
BLT.S NxtDev ;=>yes, check next device
|
||
CMP (A1)+,D1 ;to bottom of screen?
|
||
BGE.S NxtDev ;=>yes, check next device
|
||
CMP (A1)+,D3 ;to right of screen?
|
||
BLT.S GotDev ;=>no, cursor is on this screen
|
||
NxtDev MOVE.L GDNextGD(A3),D2 ;get next device in chain
|
||
BNE.S DoDev ;=>there is one, check it
|
||
NoDev RTS ;else return and pin to current screen
|
||
|
||
; cursor has changed devices, update depth and rowbytes for current device
|
||
|
||
GotDev MOVE.L CRSRPTR,A0 ;get handle to cursor data
|
||
MOVE.L (A0),A0 ;get pointer to cursor data
|
||
MOVE.L CrsrDevice,A1 ;get handle to current device
|
||
MOVE.L (A1),A1 ;point to current device
|
||
MOVE CCDEPTH(A0),GDCCDEPTH(A1) ;copy depth
|
||
MOVE CCBYTES(A0),GDCCBYTES(A1) ;copy expanded rowbytes
|
||
|
||
; now get the data, depth and rowbytes for the new device
|
||
|
||
BSR ERASECURSOR ;else erase the cursor
|
||
@0 SWAP D3 ;get pt.h in high word
|
||
MOVE D1,D3 ;get pt.v in low word
|
||
SWAP D3 ;now get them in the right order
|
||
MOVE.L D3,MTEMP ;update real mouse location with ""
|
||
MOVE.L D3,RawMOUSE ;update cursor loc with clipped pt
|
||
MOVE.L D3,MOUSE ;update mouse position
|
||
MOVE.L D2,CrsrDevice ;set the current cursor device
|
||
MOVE.L A3,A1 ;get pointer to grafDevice
|
||
JSR SetCrsrData ;and set up low-memory stuff for cursor
|
||
|
||
MOVE GDREFNUM(A3),D0 ;get the refNum
|
||
NOT D0 ;refNum -> unitnum
|
||
ASL #2,D0 ;get offset in unitTable
|
||
MOVE.L UTableBase,A0 ;get the base of the unit table
|
||
MOVE.L (A0,D0),A3 ;A3 = handle to the DCE
|
||
MOVE.L (A3),A0 ;get pointer to the DCE
|
||
MOVEQ #0,D0 ;clear out D0
|
||
MOVE.B dCtlSlot(A0),D0 ;get the slot number
|
||
_ATTACHVBL ;attach vbl to this slot
|
||
|
||
ADDQ #8,SP ;strip 2 RTS's from stack
|
||
BRA SHOWIT ;=>and go display cursor on new screen
|
||
|
||
|
||
; This routine is used by the pinrect routine below and is also called directly
|
||
; by CrsrVBLTask above to save time
|
||
; A0 should be pinning rect and D0 is the point to be pinned
|
||
; Fixed to avoid discontinuity on right and bottom. <05Apr85>
|
||
|
||
PinGuts
|
||
CMP LEFT(A0),D0 ;less than left?
|
||
BGE.S @1 ;if not, no problem
|
||
MOVE LEFT(A0),D0 ;pin to the left
|
||
|
||
@1 CMP RIGHT(A0),D0 ;greater than right?
|
||
BLT.S @2 ;if not, no problem WAS BLE!! <05Apr85>
|
||
MOVE RIGHT(A0),D0 ;pin to the right
|
||
SUBQ #1,D0 ;really want one less
|
||
|
||
@2 SWAP D0 ;consider y
|
||
CMP TOP(A0),D0 ;less than top?
|
||
BGE.S @3 ;if not, no problem
|
||
MOVE TOP(A0),D0 ;pin to the top
|
||
|
||
@3 CMP BOTTOM(A0),D0 ;greater than bottom?
|
||
BLT.S @4 ;if not, no problem WAS BLE!! <05Apr85>
|
||
MOVE BOTTOM(A0),D0 ;pin to the bottom
|
||
SUBQ #1,D0 ;really want one less
|
||
|
||
@4 SWAP D0
|
||
|
||
RTS
|
||
;
|
||
; Utility FUNCTION PinRect(theRect: Rect; thePt: Point): Point;
|
||
;
|
||
; given a rectangle and a point, pin the point inside the rectangle
|
||
;
|
||
PinRect
|
||
MOVE.L 4(SP),D0 ;get the point
|
||
MOVE.L 8(SP),A0 ;get the rect ptr
|
||
|
||
BSR.S PinGuts ; go pin it
|
||
|
||
MOVE.L (SP)+,A0 ;get return address
|
||
ADDQ #8,SP ;strip parameters
|
||
MOVE.L D0,(SP) ;return pinned pt as result
|
||
JMP (A0) ;return to caller
|
||
|
||
|
||
;_______________________________________________________________________ ;<dvb 19Sep88>
|
||
; ;<dvb 19Sep88>
|
||
; PROCEDURE CursorSect -- called by shieldcursor, showcursor ;<dvb 19Sep88>
|
||
; ;<dvb 19Sep88>
|
||
; Does a sectrect of CrsrRect and ShieldRect, all global-coörd like. ;<dvb 19Sep88>
|
||
; CLEAR the z-flag if they DO intersect: BNE YesTheyIntersect.
|
||
; This code is was moved out of ShieldCursor. ;<dvb 19Sep88>
|
||
;
|
||
; Since CrsrRect is in local screen coörds, and ShieldRect is in globals,
|
||
; the CrsrDevice's GDRect is used as an offset.
|
||
;_______________________________________________________________________ ;<dvb 19Sep88>
|
||
CursorSect MOVEM.L A0/A1/D0,-(SP) ;save the approprate regs <dvb 19Sep88>
|
||
|
||
TST ShieldDepth ;Any shielding?
|
||
BEQ.s @NoSect
|
||
|
||
LEA CrsrRect,A0 ;point to crsr rect ;<dvb 19Sep88>
|
||
MOVE.L CrsrDevice,A1 ;GET CURSOR DEVICE ;<dvb 19Sep88>
|
||
MOVE.L (A1),A1 ;POINT TO CURSOR DEVICE ;<dvb 19Sep88>
|
||
ADD #GDRECT,A1 ;POINT TO DEVICE'S RECT ;<dvb 19Sep88>
|
||
|
||
MOVE ShieldRect+Bottom,D0 ;GET SHIELD BOTTOM ;<dvb 19Sep88>
|
||
SUB TOP(A1),D0 ;CONVERT TO SCREEN LOCAL;<dvb 19Sep88>
|
||
CMP (A0)+,D0 ;IS SHIELDBOTTOM < SAVETOP ? ;<dvb 19Sep88>
|
||
BLT.S @NOSECT ;YES, NO INTERSECTION ;<dvb 19Sep88>
|
||
|
||
MOVE ShieldRect+Right,D0 ;GET SHIELD RIGHT <dvb 19Sep88>
|
||
SUB LEFT(A1),D0 ;CONVERT TO SCREEN LOCAL <dvb 19Sep88>
|
||
CMP (A0)+,D0 ;IS SHIELDRIGHT <= SAVELEFT ? <dvb 19Sep88>
|
||
BLE.S @NOSECT ;YES, NO INTERSECTION <dvb 19Sep88>
|
||
|
||
MOVE ShieldRect+Top,D0 ;GET SHIELD TOP <dvb 19Sep88>
|
||
SUB TOP(A1),D0 ;CONVERT TO SCREEN LOCAL <dvb 19Sep88>
|
||
CMP (A0)+,D0 ;IS SHIELDTOP >= SAVEBOTTOM ? <dvb 19Sep88>
|
||
BGE.S @NOSECT ;YES, NO INTERSECTION <dvb 19Sep88>
|
||
|
||
MOVE ShieldRect+Left,D0 ;GET SHIELD LEFT <dvb 19Sep88>
|
||
SUB LEFT(A1),D0 ;CONVERT TO SCREEN LOCAL <dvb 19Sep88>
|
||
CMP (A0),D0 ;IS SHIELDLEFT >= SAVERIGHT ? <dvb 19Sep88>
|
||
BGE.S @NOSECT ;YES, NO INTERSECTION <dvb 19Sep88>
|
||
|
||
@SECT MOVEQ #1,D0 ;Clear the Z-flag <dvb 19Sep88>
|
||
BRA.S @out ;<dvb 19Sep88>
|
||
|
||
@NOSECT CLR D0 ;Set the Z-flag <dvb 19Sep88>
|
||
@out MOVEM.L (SP)+,A0/A1/D0 ;Restore regs <dvb 19Sep88>
|
||
RTS ;bye.
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE ObscureCursor -- called via the jump table
|
||
;
|
||
; Removes the cursor from the screen without hiding it, so the next
|
||
; time the mouse moves, it will show up again.
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
ObscureCursor
|
||
MOVE.B #1,CrsrBusy ;"Occupado" <dvb 19sep88>
|
||
MOVE.B #1,CrsrObscure ;Mark it as obscure <dvb 19sep88>
|
||
BRA.S EraseCursor ;and erase it
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; HIDECURSOR - is called from CrsrVBLTask, and via jump table.
|
||
;
|
||
; Subtracts 1 from crsrstate and hides the cursor if visible.
|
||
;
|
||
;
|
||
HideCursor
|
||
MOVE.B #1,CrsrBusy ;MARK CHANGE IN PROGRESS
|
||
SUB #1,CRSRSTATE ;CURSOR HIDDEN ONE DEEPER
|
||
|
||
;Fall into EraseCursor
|
||
|
||
;________________________________________________________________________
|
||
; <SM5> CSS Horror vectorized this vector. We are supporting this to be
|
||
; compatible with Horror.
|
||
; EraseCursor calls a vectorized version of the routine via lomem.
|
||
; EraseCursor is vectorized to gain access to low level cursor blit routines.
|
||
; (NOTE: Vector is initialized in StartInit.a to routine named VEraseCursor.)
|
||
|
||
; EraseCursor is much like HideCursor, but doesn't decrement the CrsrState <dvb 19sep88>
|
||
|
||
EraseCursor
|
||
move.l EraseCrsrVector,-(sp) ;<SM5> CSS
|
||
rts ;jump to the vectored routine <SM5> CSS
|
||
DoneHid CLR.B CRSRBUSY ;CHANGE COMPLETE
|
||
RTS
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE InitCursor;
|
||
;
|
||
; Definitely redisplay the cursor, independent of previous calls to
|
||
; HideCursor, ShieldCursor and ObscureCursor. It falls into showCursor.
|
||
;
|
||
InitCursor
|
||
MOVE.B #1,CrsrBusy ;mark it busy
|
||
CLR.B CrsrObscure ;we wont be obscure no more
|
||
CLR CrsrState ;reset state to 0
|
||
CLR ShieldDepth
|
||
;
|
||
; fall into ShowCursor
|
||
;
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; SHOWCURSOR - Called from CrsrVBLTask and via Jump Table.
|
||
;
|
||
; Adds 1 to CRSRSTATE and paints cursor if zero and cursor is
|
||
; not already visible.
|
||
;
|
||
; this reflects the fix from QDciPatchROM.a where obscure/show/hide left <sm 6/9/92>stb
|
||
; the cursor hidden only, and obscure/hide/show left the cursor obscured only. <sm 6/9/92>stb
|
||
|
||
ShowCursor
|
||
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
|
||
|
||
TST ShieldDepth ;Any shielding?
|
||
BEQ.s @2
|
||
|
||
@1 SUBQ #1,ShieldDepth ;If so, this ShowCursor unshields,
|
||
BRA.s DrawCursor ;but doesn't up the cursor level.
|
||
|
||
@2 ADDQ #1,CRSRSTATE ;CURSOR HIDDEN ONE LESS DEEP
|
||
bmi.s DoneSho
|
||
beq.s DrawCursor ;<KON 25JUN90>
|
||
clr.b CrsrObscure ;unobscure cursor if level went past zero <KON 25JUN90>
|
||
|
||
;fall into DrawCursor
|
||
|
||
;________________________________________________________________________
|
||
; <SM5> CSS Horror vectorized this vector. We are supporting this to be
|
||
; compatible with Horror.
|
||
; DrawCursor calls a vectorized version of the routine via lomem.
|
||
; DrawCursor is vectorized to gain access to low level cursor blit routines.
|
||
; (NOTE: Vector is initialized in StartInit.a to routine named VDrawCursor.)
|
||
|
||
; DrawCursor is much like ShowCursor, but doesn't increment the CrsrState <dvb 19sep88>
|
||
|
||
DrawCursor
|
||
move.l DrawCrsrVector,-(sp) ; <SM5> CSS
|
||
rts ;jump to the vectored routine <SM5> CSS
|
||
|
||
DoneSho CLR.B CRSRBUSY ;CHANGE COMPLETE
|
||
RTS
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; CURSHIELD - Called via Jump Table
|
||
;
|
||
; PROCEDURE ShieldCursor(left,top,right,bottom: INTEGER);
|
||
;
|
||
; Subtracts 1 from CRSRSTATE, hides cursor only if it intersects SHIELDRECT.
|
||
; left,top,right bottom is the shieldRect in global coordinates
|
||
;
|
||
; ALL REGISTERS RESTORED.
|
||
;
|
||
|
||
ShieldVars RECORD {return},DECREMENT ;<dvb 19Sep99>
|
||
ShieldLeft DS.W 1 ;<dvb 19Sep99>
|
||
ShieldTop DS.W 1 ;<dvb 19Sep99>
|
||
ShieldRight DS.W 1 ;<dvb 19Sep99>
|
||
ShieldBot DS.W 1 ;<dvb 19Sep99>
|
||
return DS.L 1 ;<dvb 19Sep99>
|
||
ENDR
|
||
|
||
WITH ShieldVars
|
||
ShieldCursor
|
||
TST ShieldDepth ;Any shielding already? ;<dvb 19Sep88>
|
||
BEQ.s @2 ;No=>don't unionrect
|
||
|
||
MOVEM.L D0/A0,-(SP) ;Save some regs (and +8 our vars below*)
|
||
LEA ShieldRect+right,A0 ;A0->ShieldRect.right
|
||
|
||
MOVE.L ShieldBot+8(SP),D0 ;D0 = New shield bot,right (*)
|
||
CMP (A0),D0 ;Compare to ShieldRect.right
|
||
BLE.s @u1 ;Is the new right bigger?
|
||
MOVE D0,(A0)
|
||
|
||
@u1 SWAP D0 ;D0 = New shield bottom
|
||
CMP -(A0),D0 ;Compare to ShieldRect.bottom
|
||
BLE.s @u2 ;Is the new bottom bigger?
|
||
MOVE D0,(A0) ;If so, replace with it.
|
||
|
||
@u2 MOVE.L ShieldTop+8(SP),D0 ;D0 = New shield top,left (*)
|
||
CMP -(A0),D0 ;Compare to ShieldRect.left
|
||
BGE.s @u3 ;Is the new left smaller?
|
||
MOVE D0,(A0)
|
||
|
||
@u3 SWAP D0 ;D0 = New shield top
|
||
CMP -(A0),D0 ;Compare to ShieldRect.top
|
||
BGE.s @u4 ;Is the new top smaller?
|
||
MOVE D0,(A0)
|
||
|
||
@u4 MOVEM.L (SP)+,D0/A0
|
||
BRA.s @3
|
||
|
||
@2 MOVE.L ShieldBot(SP),ShieldRect+botRight ;save shieldrect ;<dvb 19Sep88>
|
||
MOVE.L ShieldTop(SP),ShieldRect+topLeft ;<dvb 19Sep88>
|
||
@3 ADDQ #1,ShieldDepth ;Shielding officially on
|
||
MOVE.B #1,CrsrBusy
|
||
BSR CursorSect ;<dvb 19Sep88>
|
||
BEQ.s @1 ;<dvb 19Sep88>
|
||
|
||
BSR EraseCursor ;IT DOES INTERSECT, REMOVE IT
|
||
|
||
@1 CLR.B CrsrBusy
|
||
MOVE.L (SP)+,(SP) ;STRIP 8 bytes of PARAMETERS, MOVING
|
||
MOVE.L (SP)+,(SP) ;RETURN ADDR UP ON STACK
|
||
RTS
|
||
|
||
ENDWITH
|
||
|
||
IMPORT CopyHandle,PatConvert
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE SetCCursor(cCrsr: CCrsrHandle);
|
||
;
|
||
; This procedure copies the data in the specified color cursor into the
|
||
; system's cursor save area. If the depth > 2, it expands it.
|
||
|
||
; this routine was taken from QDciPatchROM.a because A2 was getting trashed <sm 6/9/92>stb
|
||
; when setting CCursor on multiple device systems <sm 6/9/92>stb
|
||
|
||
SetCCursor MOVEM.L D3-D4/A2-A4,-(SP) ;save work registers
|
||
move.l 24(sp),a2 ;get ccrsrHandle <BAL 21Jun88>
|
||
move.l a2,a0 ;make a copy
|
||
_HGetState
|
||
move d0,-(sp) ;save state for later
|
||
move.l a2,a0 ;make a copy
|
||
_HLock
|
||
MOVE.L (a2),A2 ;GET POINTER TO NEW CURSOR
|
||
|
||
MOVE.L ([CRSRPTR]),A3 ;point to current cursor (LOCKED)
|
||
MOVE.L crsrID(A2),D0 ;and get ID of new cursor
|
||
CMP #CCrsrPat,ccType(A3) ;is current cursor a color cursor?
|
||
BNE.S NotCC ;=>no, it has definitely changed
|
||
CMP.L ccID(A3),D0 ;same as current one?
|
||
BEQ SCCDONE ;=>yes, just return
|
||
|
||
NotCC MOVE.B #1,CRSRBUSY ;flag the cursor as busy
|
||
MOVE.L D0,ccID(A3) ;set new ID
|
||
LEA crsr1Data(A2),A0 ;point to old-cursor data
|
||
LEA THECRSR,A1 ;put it here
|
||
MOVEQ #16,D0 ;data+mask+hotspot = 17 longs
|
||
@0 MOVE.L (A0)+,(A1)+ ;copy data
|
||
DBRA D0,@0 ;until done
|
||
|
||
LEA crsr1Data(A2),A0 ;point to old-cursor data
|
||
LEA CCLASTCRSR(A3),A1 ;save here to indicate cursor changed
|
||
MOVEQ #7,D0 ;move 8 longs
|
||
@1 MOVE.L (A0)+,(A1)+ ;copy data
|
||
DBRA D0,@1 ;=>loop until done
|
||
|
||
MOVE crsrType(A2),ccType(A3) ;copy the type
|
||
|
||
; NOTE: ALL THE DST HANDLES ARE LOCKED, BUT THEY HAVE BEEN SET TO THE PROPER SIZE
|
||
|
||
MOVE.L crsrMap(A2),-(SP) ;push src pixMap handle
|
||
MOVE.L ccMap(A3),-(SP) ;push dst pixMap handle
|
||
_CopyPixMap ;copy the pixMap
|
||
|
||
MOVE.L crsrData(A2),-(SP) ;push src data handle
|
||
MOVE.L ccData(A3),-(SP) ;push dst data handle
|
||
_CopyHandle ;copy the cursor data
|
||
|
||
; FOR EACH ACTIVE SCREEN DEVICE, EXPAND CURSOR, IF NECESSARY
|
||
|
||
MOVE.L DEVICELIST,D4 ;D4 = CURRENT DEVICE
|
||
MOVE.L D4,A4 ;GET HANDLE TO CURRENT DEVICE
|
||
NXTSCR MOVE.L (A4),A4 ;A4 = POINTER TO CURRENT DEVICE
|
||
TST.W GDFLAGS(A4) ;IS THE DEVICE ACTIVE?
|
||
BPL CHKNXT ;=>NO, CHECK NEXT DEVICE
|
||
;ACTIVE DEVICES ARE LOCKED DOWN
|
||
MOVE.L GDPMAP(A4),A0 ;GET HANDLE TO DEVICE'S PIXMAP
|
||
MOVE.L (A0),A0 ;POINT TO DEVICE'S PIXMAP
|
||
MOVE PIXELSIZE(A0),D3 ;GET DEVICE'S PIXELSIZE
|
||
|
||
; IF THE PATTERN IS PRE-EXPANDED TO THE RIGHT DEPTH, JUST COPY THAT DATA
|
||
|
||
CLR GDCCDEPTH(A4) ;flag to expand one-bit data
|
||
MOVE CRSRXVALID(A2),D0 ;is there pre-expanded data?
|
||
BEQ.S GOEXP ;=>no, do expansion
|
||
CMP D3,D0 ;is the expanded data the right depth?
|
||
BNE.S GOEXP ;=>no, expand from the source
|
||
MOVE D0,GDCCDEPTH(A4) ;else copy the expanded depth
|
||
MOVE.L crsrXData(A2),-(SP) ;push the src xdata handle
|
||
MOVE.L CCXDATA(A3),-(SP) ;push the dst xdata handle
|
||
_CopyHandle ;and copy it
|
||
BRA.S CHKNXT ;=>data already expanded, just exit
|
||
|
||
GOEXP CMP #CCRSRPAT,CCTYPE(A3) ;IS IT A COLOR CURSOR?
|
||
BNE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0
|
||
CMP #2,D3 ;IS DEPTH GREATER THAN 2?
|
||
BLE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0
|
||
|
||
MOVE D3,GDCCDEPTH(A4) ;RECORD THE EXPANDED DEPTH
|
||
MOVE.L GDCCXDATA(A4),CCXDATA(A3) ;GET DEVICE'S EXPANDED DATA FOR PATCONVERT
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE GRAFDEVICE (USED BY PATCONVERT)
|
||
MOVE.L D4,THEGDEVICE ;SET IT TO CURRENT DEVICE
|
||
MOVE.L CRSRPTR,-(SP) ;PUSH HANDLE TO CURSOR (LOCKED)
|
||
_PATCONVERT ;AND EXPAND TO CURRENT DEPTH
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE GRAFDEVICE
|
||
|
||
; EXPAND THE MASK TO THE CURRENT DEPTH
|
||
|
||
MOVE D3,D0 ;GET DEPTH
|
||
MOVEQ #0,D1 ;DEFAULT SHIFT = 0
|
||
NXTSHFT1 LSR #1,D0 ;CHECK NEXT DEPTH BIT
|
||
BCS.S GOTSHFT1 ;=>GOT SHIFT
|
||
ADDQ #1,D1 ;ELSE ADD ONE TO SHIFT
|
||
BRA.S NXTSHFT1 ;LOOP UNTIL WE HIT A ONE
|
||
|
||
GOTSHFT1 LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK
|
||
MOVE.L ([GDCCXMASK,A4]),A1 ;POINT TO EXPANDED MASK (LOCKED)
|
||
|
||
move.l a2,d4 ;save pointer to new cursor <25APR91 KON>
|
||
MOVE.L A1,A2 ;GET START OF DST BUFFER <27May87 EHB>
|
||
MOVE #32,D0 ;GET #BYTES OF SOURCE <27May87 EHB>
|
||
LSL D1,D0 ;MULTIPLY BY DEPTH <27May87 EHB>
|
||
ADD D0,A2 ;POINT TO END OF BUFFER <27May87 EHB>
|
||
|
||
move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE
|
||
add.l 0(A3,D1*4),A3 ;USE DEPTH TO SELECT ROUTINE
|
||
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
|
||
JSR (A3) ;EXPAND 32*DEPTH BYTES
|
||
MOVE.L ([CRSRPTR]),A3 ;GET BACK POINTER TO CURSOR (LOCKED)
|
||
move.l d4,a2 ;restore pointer to new cursor <25APR91 KON>
|
||
|
||
DONEONE MOVE GDCCDEPTH(A4),D0 ;GET EXPANDED DEPTH
|
||
ADD D0,D0 ;DOUBLE IT
|
||
MOVE D0,GDCCBYTES(A4) ;AND SAVE AS CURSOR'S ROWBYTES
|
||
|
||
CHKNXT MOVE.L GDNEXTGD(A4),D4 ;IS THERE A NEXT DEVICE?
|
||
MOVE.L D4,A4 ;GET HANDLE TO NEXT DEVICE
|
||
BNE NXTSCR ;=>THERE IS ONE, PREPARE ITS CURSOR
|
||
|
||
BSR.S GETMAINCRSR ;RESTORE EXPAND DATA FOR MAIN CURSOR
|
||
BSR ERASECURSOR ;HIDE THE OLD CURSOR
|
||
BSR DRAWCURSOR ;DISPLAY THE NEW CURSOR
|
||
SCCDONE CLR.B CRSRBUSY ;CURSOR NOT BUSY ANYMORE
|
||
move (sp)+,d0 ;get ccrsrhandle state
|
||
move.l 24(sp),a0 ;get ccrsrHandle
|
||
_HSetState
|
||
MOVEM.L (SP)+,D3-D4/A2-A4 ;restore work registers
|
||
MOVE.L (SP)+,(SP) ;strip parameter
|
||
RTS ;and return
|
||
|
||
;_______________________________________________________________________
|
||
|
||
GETMAINCRSR MOVE.L CRSRDEVICE,A0 ;GET HANDLE TO CURSOR DEVICE
|
||
MOVE.L (A0),A0 ;GET POINTER TO CURSOR DEVICE
|
||
MOVE.L CRSRPTR,A1 ;GET HANDLE TO CURSOR SAVE AREA
|
||
MOVE.L (A1),A1 ;GET POINTER TO CURSOR SAVE
|
||
MOVE.L GDCCXDATA(A0),CCXDATA(A1) ;GET CURRENT EXPANDED DATA
|
||
MOVE.L GDCCXMASK(A0),CCXMASK(A1) ;GET CURRENT EXPANDED MASK
|
||
MOVE GDCCDEPTH(A0),CCDEPTH(A1) ;GET EXPANDED DEPTH
|
||
MOVE GDCCBYTES(A0),CCBYTES(A1) ;GET EXPANDED ROWBYTES
|
||
RTS ;AND RETURN
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE SetCursor(hotSpot: Point; height: INTEGER; data: Ptr; mask:Ptr);
|
||
;
|
||
; This procedure sets THECRSR pointer in the system global area.
|
||
; A reasonable hotSpot is ENFORCED! Also fix bug to note changed when only hotspot does. <05Apr85>
|
||
;
|
||
; WARNING: to save code, this routine really doesn't use the above interface.
|
||
; It ignores the height and mask parameters. It assumes that the mask immediately
|
||
; follows the data (as it does when called from LisaGraf)
|
||
;
|
||
SetCursor MOVE.L ([CRSRPTR]),A0 ;point to crsr data structure (LOCKED)
|
||
move.b #1,crsrBusy ;don't allow vbl drawing until we're done <09Aug88>
|
||
MOVE #oldCrsrPat,ccType(A0) ;say that it's an old cursor
|
||
|
||
MOVE.L 8(SP),A0 ;get address of data mask
|
||
LEA THECRSR,A1 ;point to system cursor buffer
|
||
MOVEQ #15,D2 ;have 16 longs to move
|
||
MOVEQ #0,D1 ;flag that its not different
|
||
|
||
SetCurLoop MOVE.L (A0)+,D0 ;get next longWord of new cursor
|
||
CMP.L (A1),D0 ;is it the same as what's there
|
||
BEQ.S @1 ;if so, skip
|
||
ADDQ #1,D1 ;flag that its different
|
||
@1 MOVE.L D0,(A1)+ ;move it into the cursor buffer
|
||
DBRA D2,SetCurLoop ;move all 64 bytes
|
||
|
||
MOVE.L 14(SP),D0 ;get the alleged hotspot <23Apr85>
|
||
|
||
; Clean up the two coordinates to lie between 0 and 16. <23Apr85>
|
||
|
||
MOVEQ #16,D2 ; VERY handy temp, from loop above <23Apr85>
|
||
CMP.W D2,D0 ; <23Apr85>
|
||
BLS.S @31 ; D0 LowerorSame as 16 is ok <23Apr85>
|
||
MOVE.W D2,D0 ;pin it at 16 <23Apr85>
|
||
|
||
@31 SWAP D0 ;align the high-order coord <23Apr85>
|
||
CMP.W D2,D0 ; <23Apr85>
|
||
BLS.S @33 ; D0 LowerorSame as 16 is ok <23Apr85>
|
||
MOVE.W D2,D0 ; <23Apr85>
|
||
|
||
@33 SWAP D0 ;realign coords <23Apr85>
|
||
CMP.L TheCrsr+HotSpot,D0 ;is it new? <05Apr85>
|
||
BEQ.S @3 ; <05Apr85>
|
||
ADDQ #1,D1 ;flag it's different <05Apr85>
|
||
MOVE.L D0,TheCrsr+HotSpot ;move in the hotSpot <05Apr85>
|
||
@3
|
||
|
||
; DID THE CURSOR CHANGE?
|
||
|
||
clr.b crsrBusy ;re-allow vbl drawing <09Aug88>
|
||
TST D1 ;did it change?
|
||
BEQ.S @6 ;skip if it didn't
|
||
|
||
; IF SO, FORCE THE CURSOR TO BE REDISPLAYED BY HIDING AND THEN SHOWING IT
|
||
|
||
BSR EraseCursor ;hide it
|
||
BSR DrawCursor ;then show it again to redraw it
|
||
|
||
@6 MOVE.L (SP)+,A0 ;get return address
|
||
ADD #14,SP ;strip parameters
|
||
JMP (A0) ;return to caller
|
||
|
||
|
||
|
||
SetCrsrData PROC EXPORT
|
||
;------------------------------------------------
|
||
; UTILITY SetCrsrData
|
||
;
|
||
; This routine is called to initialize low-memory locations
|
||
; to the necessary values for the grafDevice pointer in A1.
|
||
;
|
||
IMPORT SetCrsrDelay ;<SM5> CSS
|
||
bsr.l SetCrsrDelay ;<SM5> CSS
|
||
MOVE.L CRSRPTR,A0 ;get handle to cursor data
|
||
MOVE.L (A0),A0 ;get pointer to cursor data
|
||
|
||
; initialize the grafDevice's cursor variables
|
||
|
||
MOVE.L GDCCXDATA(A1),CCXDATA(A0) ;copy handle to expanded data
|
||
MOVE.L GDCCXMASK(A1),CCXMASK(A0) ;copy handle to expanded mask
|
||
MOVE GDCCDEPTH(A1),CCDEPTH(A0) ;copy depth
|
||
MOVE GDCCBYTES(A1),CCBYTES(A0) ;copy expanded rowbytes
|
||
|
||
; set the pinning rectangle to the current screen
|
||
|
||
LEA GDRect(A1),A0 ;get rect for current device
|
||
MOVE.L (A0)+,crsrPin ;and set pinning rectangle
|
||
MOVE.L (A0),crsrPin+4 ;from device's rectangle
|
||
|
||
; set the depth, rowbytes, height, and width of the current screen
|
||
|
||
MOVE.L GDPMap(A1),A0 ;get pixMap of current device
|
||
MOVE.L (A0),A0 ;point at pixmap
|
||
MOVE PixelSize(A0),chunkyDepth ;set depth of cursor's screen
|
||
MOVE.L (A0)+,crsrBase ;update base address for cursor
|
||
MOVE (A0)+,D0 ;get rowbytes
|
||
AND #nuRBMask,D0 ;clear flag bits
|
||
MOVE D0,crsrRow ;set cursor rowbytes
|
||
MOVE bottom(A0),D0 ;get bottom of cursor's screen
|
||
SUB top(A0),D0 ;calc height of cursor's screen
|
||
MOVE D0,ColLines ;save height of cursor's screen
|
||
MOVE right(A0),D0 ;get right of cursor's screen
|
||
SUB left(A0),D0 ;calc width of cursor's screen
|
||
MOVE D0,RowBits ;save width of cursor's screen
|
||
RTS
|
||
|
||
|
||
ALLOCCRSR PROC EXPORT
|
||
IMPORT PatConvert,GETMAINCRSR,SetCrsrData
|
||
IMPORT RNEWHANDLE,ERASECURSOR,DRAWCURSOR
|
||
;--------------------------------------------------
|
||
;
|
||
; PROCEDURE AllocCrsr;
|
||
;
|
||
; Allocates all global cursor data structures. A maximum depth of 8 is assumed.
|
||
;
|
||
; CRSRPTR IS USED AS A HANDLE TO AN EXTENDED PATTERN WHICH CONTAINS THESE FIELDS:
|
||
;
|
||
; CCTYPE EQU 0 ;[WORD] CURSOR TYPE
|
||
; CCMAP EQU CCTYPE+2 ;[LONG] HANDLE TO CURSOR'S PIXMAP
|
||
; CCDATA EQU CCMAP+4 ;[LONG] HANDLE TO CURSOR'S COLOR DATA
|
||
; CCXDATA EQU CCDATA+4 ;[LONG] HANDLE TO EXPANDED DATA
|
||
; CCXMASK EQU CCXDATA+4 ;[LONG] HANDLE TO EXPANDED MASK
|
||
; CCSAVE EQU CCXMASK+4 ;[LONG] HANDLE TO SAVE BITS UNDER CURSOR
|
||
; CCLASTCRSR EQU CCSAVE+4 ;[32 BYTES] DATA FOR LAST B/W CURSOR DRAWN
|
||
; CCID EQU CCLASTCRSR ;[LONG] ID FOR LAST COLOR CURSOR DRAWN
|
||
; CCTABLE EQU CCID+4 ;[LONG] TABLE ID FOR LAST COLOR CURSOR
|
||
; CCDEPTH EQU CCLASTCRSR+32 ;[WORD] DEPTH FOR LAST CURSOR DRAWN
|
||
; CCSTATEREGS EQU CCDEPTH+2 ;[20 BYTES] STATE INFO OF SAVED DATA
|
||
; CCBYTES EQU CCSTATEREGS+16 ;[WORD] ROWBYTES OF EXPANDED DATA
|
||
; CCMAXDEPTH EQU CCBYTES+2 ;[WORD] MAXIMUM CURSOR DEPTH
|
||
|
||
|
||
MOVEM.L D0-D6/A0-A4/A6,-(SP) ;PRESERVE ALL REGS
|
||
MOVE.L THEZONE,-(SP) ;SAVE THE CURRENT HEAP ZONE
|
||
MOVE.L SYSZONE,THEZONE ;SET CURRENT ZONE TO SYS ZONE
|
||
|
||
; ALLOCATE MAIN CURSOR STRUCTURE AND DATA AREAS IF NECESSARY
|
||
|
||
BSR ERASECURSOR ;HIDE THE CURSOR
|
||
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
|
||
|
||
MOVE.L CRSRPTR,D0 ;GET CRSRPTR (REALLY HANDLE)
|
||
CMP.L MINUSONE,D0 ;IS IT ALLOCATED?
|
||
BNE.S MAINOK ;=>ALREADY ALLOCATED, CONTINUE
|
||
|
||
; RESERVE MEMORY FOR AND ALLOCATE CURSOR STRUCTURE.
|
||
; THE CURSOR SAVE RECORD CONTAINS A PIXMAP, A DATA HANDLE, AND A SAVE HANDLE.
|
||
|
||
clr.b CrsrObscure ;we wont be obscure no more
|
||
clr CrsrState ;reset state to 0
|
||
clr ShieldDepth ;no more shielding
|
||
|
||
MOVEQ #CCSAVEREC,D1 ;GET SIZE OF CURSOR SAVE RECORD
|
||
BSR GETLOWHANDLE ;ALLOCATE RECORD DOWN LOW AND LOCK
|
||
MOVE.L A0,CRSRPTR ;SAVE HANDLE TO CURSOR
|
||
MOVE.L (A0),A4 ;KEEP POINTER IN A4
|
||
|
||
MOVEQ #PMREC,D0 ;WE'RE GOING TO LOCK THIS
|
||
_RESRVMEM ;SO RESERVE SPACE DOWN LOW
|
||
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
|
||
_NEWPIXMAP ;ALLOCATE A PIXMAP
|
||
MOVE.L (SP)+,A0 ;GET HANDLE TO PIXMAP
|
||
MOVE.L A0,CCMAP(A4) ;SAVE PIXMAP IN CURSOR RECORD
|
||
_HLOCK ;LOCK IT DOWN
|
||
|
||
MOVEQ #2,D0 ;DEFAULT SIZE OF DATA HANDLE
|
||
JSR RNEWHANDLE ;ALLOCATE IT
|
||
MOVE.L A0,CCDATA(A4) ;AND SAVE FOR CURSOR DATA
|
||
|
||
; RESERVE AND ALLOCATE MEMORY IN WHICH TO SAVE THE BITS BEHIND THE CURSOR.
|
||
; MAGIC AMOUNT OF MEMORY RESERVED IS FOR 32 BIT DEEP, LONG ALIGNED CURSOR.
|
||
|
||
if cursorShadow then
|
||
MOVE.L #$400*4,D1 ;GET REQUIRED SIZE 32*32*4
|
||
else
|
||
MOVE.L #$400,D1 ;GET REQUIRED SIZE 16*16*4
|
||
endif
|
||
BSR GETLOWHANDLE ;GET LOW,LOCKED HANDLE
|
||
MOVE.L A0,CCSAVE(A4) ;SAVE INTO RECORD
|
||
|
||
; INITIALIZE THE CURSOR TO THE ARROW CURSOR.
|
||
|
||
MOVE #OLDCRSRPAT,CCTYPE(A4) ;SAY THAT IT'S AN OLD CURSOR
|
||
CLR CCDEPTH(A4) ;CLEAR DEPTH TO SAY NOT EXPANDED
|
||
|
||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO GRAFGLOBALS
|
||
LEA ARROW(A0),A0 ;POINT TO ARROW CURSOR
|
||
LEA THECRSR,A1 ;PUT IT HERE
|
||
MOVEQ #16,D0 ;DATA+MASK+HOTSPOT = 17 LONGS
|
||
@2 MOVE.L (A0)+,(A1)+ ;COPY DATA
|
||
DBRA D0,@2 ;UNTIL DONE
|
||
|
||
|
||
; FOR EACH ACTIVE SCREEN DEVICE, ALLOCATE EXPANDED CURSOR MEMORY IF NECESSARY
|
||
; ALL DEVICES ARE GUARANTEED TO BE LOCKED.
|
||
|
||
MAINOK MOVE.L CRSRPTR,A4 ;GET HANDLE TO CURSOR STUFF
|
||
MOVE.L (A4),A4 ;GET POINTER (LOCKED)
|
||
MOVE.L DEVICELIST,D4 ;D4 = CURRENT DEVICE
|
||
MOVE.L D4,A6 ;GET HANDLE TO CURRENT DEVICE
|
||
NXTDEVICE MOVE.L (A6),A6 ;A6 = POINTER TO CURRENT DEVICE
|
||
TST.W GDFLAGS(A6) ;IS THE DEVICE ACTIVE?
|
||
BPL CHKNEXT ;=>NO, CHECK NEXT DEVICE
|
||
|
||
TST GDCCDEPTH(A6) ;HAS MEMORY BEEN ALLOCATED?
|
||
BNE.S DOEXPAND ;=>YES, EXPAND CURSOR IF NECESSARY
|
||
|
||
MOVE.L GDCCXDATA(A6),A0 ;GET HANDLE TO EXPANDED DATA
|
||
_DISPOSHANDLE ;DISPOSE THE CURRENT HANDLE
|
||
MOVE.L #$400,D1 ;GET SIZE OF EXPANDED HANDLE @@@@ used to be $100
|
||
BSR GETLOWHANDLE ;GET A LOW, LOCKED HANDLE
|
||
MOVE.L A0,GDCCXDATA(A6) ;AND SAVE IT
|
||
|
||
MOVE.L GDCCXMASK(A6),A0 ;GET HANDLE TO EXPANDED DATA
|
||
_DISPOSHANDLE ;DISPOSE THE CURRENT HANDLE
|
||
BSR GETLOWHANDLE ;GET A LOW, LOCKED HANDLE
|
||
MOVE.L A0,GDCCXMASK(A6) ;AND SAVE IT
|
||
|
||
DOEXPAND
|
||
; MAKE SURE ALL THE HANDLES ARE THE RIGHT SIZE FOR THE CURRENT DEPTH.
|
||
; IF COLOR CURSOR AND DEPTH IS > 2 BITS PER PIXEL, THEN EXPAND TO CURRENT DEPTH.
|
||
; BLACK AND WHITE (AND 2 BIT) CURSORS ARE EXPANDED BY SHOWCURSOR.
|
||
|
||
MOVE.L GDPMAP(A6),A0 ;GET HANDLE TO DEVICE'S PIXMAP
|
||
MOVE.L (A0),A0 ;POINT TO DEVICE'S PIXMAP
|
||
MOVE PIXELSIZE(A0),D3 ;GET DEVICE'S PIXELSIZE
|
||
CMP GDCCDEPTH(A6),D3 ;HAS DEPTH CHANGED?
|
||
BEQ.S CHKNEXT ;=>NO, THIS DEVICE IS OK
|
||
|
||
; CONVERT DEPTH TO SHIFT AMOUNT IN D6
|
||
|
||
MOVE D3,D0 ;GET DEPTH
|
||
MOVEQ #0,D6 ;DEFAULT SHIFT = 0
|
||
NXTSHFT LSR #1,D0 ;CHECK NEXT DEPTH BIT
|
||
BCS.S GOTSHFT ;=>GOT SHIFT
|
||
ADDQ #1,D6 ;ELSE ADD ONE TO SHIFT
|
||
BRA.S NXTSHFT ;LOOP UNTIL WE HIT A ONE
|
||
|
||
GOTSHFT CMP #CCRSRPAT,CCTYPE(A4) ;IS IT A COLOR CURSOR?
|
||
BNE.S CHKNEXT ;=>NO
|
||
CMP #2,D3 ;IS DEPTH GREATER THAN 2?
|
||
BLE.S CHKNEXT ;=>NO
|
||
|
||
MOVE.L GDCCXDATA(A6),CCXDATA(A4) ;GET EXPAND HANDLE FOR PATCONVERT
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE GRAFDEVICE
|
||
MOVE.L D4,THEGDEVICE ;SET IT TO CURRENT DEVICE
|
||
MOVE.L CRSRPTR,-(SP) ;PUSH HANDLE TO CURSOR
|
||
_PATCONVERT ;AND EXPAND TO CURRENT DEPTH
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE GRAFDEVICE
|
||
|
||
; EXPAND THE MASK TO THE CURRENT DEPTH
|
||
|
||
LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK
|
||
MOVE.L ([GDCCXMASK,A6]),A1 ;POINT TO EXPANDED MASK (LOCKED)
|
||
MOVE.L A1,A2 ;GET START OF DST BUFFER
|
||
MOVE #32,D0 ;GET #BYTES OF SOURCE
|
||
LSL D6,D0 ;MULTIPLY BY DEPTH
|
||
ADD D0,A2 ;POINT TO END OF BUFFER
|
||
|
||
move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE
|
||
add.l 0(A3,D6*4),A3 ;USE DEPTH TO SELECT ROUTINE
|
||
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
|
||
JSR (A3) ;EXPAND 32*DEPTH BYTES
|
||
|
||
MOVE D3,GDCCDEPTH(A6) ;SAVE DEPTH OF EXPANDED CURSOR
|
||
ADD D3,D3 ;GET 2*DEPTH
|
||
MOVE D3,GDCCBYTES(A6) ;SAVE ROWBYTES FOR EXPANDED CURSOR
|
||
|
||
CHKNEXT MOVE.L GDNEXTGD(A6),D4 ;IS THERE A NEXT DEVICE?
|
||
MOVE.L D4,A6 ;GET HANDLE TO NEXT DEVICE
|
||
BNE NXTDEVICE ;=>THERE IS ONE, PREPARE ITS CURSOR
|
||
|
||
BSR GETMAINCRSR ;SET UP FIELDS FOR MAIN CURSOR
|
||
MOVE.L CRSRDEVICE,A1 ;GET HANDLE TO CURSOR DEVICE
|
||
MOVE.L (A1),A1 ;GET POINTER TO CURSOR DEVICE
|
||
JSR SetCrsrData ;AND SET UP LOW-MEM FOR THIS DEVICE
|
||
|
||
MOVE.L (SP)+,THEZONE ;RESTORE THE ZONE
|
||
CLR.B CRSRBUSY ;CHANGE COMPLETE
|
||
BSR DRAWCURSOR
|
||
MOVEM.L (SP)+,D0-D6/A0-A4/A6 ;RESTORE ALL REGS
|
||
RTS
|
||
|
||
|
||
GETLOWHANDLE
|
||
;--------------------------------------------------
|
||
; UTILITY GETLOWHANDLE
|
||
;
|
||
; THIS ROUTINE RESERVES MEMORY FOR A HANDLE, ALLOCATES THE HANDLE
|
||
; AND THEN LOCKS IT DOWN. THE DESIRED SIZE IS IN D1. THE RETURNED HANDLE IS IN A0
|
||
; ONLY D0 IS TRASHED
|
||
|
||
MOVE.L D1,D0 ;GET THE DESIRED SIZE
|
||
_RESRVMEM ;RESERVE SPACE FOR THE HANDLE DOWN LOW
|
||
BNE.S MEMFULL ;=>ON ERROR, JUST BOMB
|
||
MOVE.L D1,D0 ;GET THE DESIRED SIZE
|
||
_NEWHANDLE ,CLEAR ;ALLOCATE THE HANDLE
|
||
_HLOCK ;LOCK IT
|
||
RTS ;AND RETURN
|
||
|
||
MEMFULL MOVEQ #25,D0 ;MEM FULL ERROR
|
||
_SYSERROR ;FLAG IT
|
||
DC.W $A9FF ;JUST IN CASE WE RETURN
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; BLITCURSOR <dvb 19sep88>
|
||
;
|
||
; The only thing that will stop this routine from blitting the cursor
|
||
; to the screen is ShieldRect. Since the new CrsrRect isn't known
|
||
; until pretty far through the process, it's checked here, not
|
||
; DrawCursor. CrsrState and CrsrObscure are _not_ checked here.
|
||
; It seems likely that patching this routine will have use on accelerator
|
||
; cards etc.
|
||
|
||
BLITCURSOR PROC EXPORT
|
||
IMPORT CursorSect, SHFTTBL
|
||
|
||
TST.L CRSRPTR ;CURSOR ALLOCATED?
|
||
BMI NoBlit ;=>NO, JUST RETURN
|
||
MOVEM.L D0-D7/A0-A6,-(SP) ;SAVE REGISTERS
|
||
LEA THECRSR+DATA,A2 ;POINT TO THE CURSOR
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; CONVERT CHUNKY DEPTH TO SHIFT AMOUNT IN D7
|
||
;
|
||
LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
||
MOVE CHUNKYDEPTH,D1 ;GET DEPTH
|
||
MOVEQ #0,D7 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D1),D7 ;GET SHIFT AMOUNT IN D7
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; CHECK THE CURSOR TO SEE IF IT HAS CHANGED
|
||
; OLD CURSORS: CHECK CURSOR DATA AND DEPTH
|
||
; NEW CURSORS: CHECK DEPTH
|
||
;
|
||
GOTSHFT MOVE.L ([CRSRPTR]),A4 ;GET POINTER TO CURSOR DATA (LOCKED)
|
||
CMP #CCRSRPAT,CCTYPE(A4) ;IS IT A COLOR CURSOR?
|
||
BNE.S OLDCUR ;=>NO, JUST AN OLD ONE
|
||
CMP CCDEPTH(A4),D1 ;HAS DEPTH CHANGED?
|
||
BEQ NOEXPAND ;=>NO, DON'T EXPAND
|
||
CMP #2,D1 ;IS DEPTH 2 or 1?
|
||
BGT EXPMASK ;=>NO, JUST EXPAND MASK
|
||
BRA.S CPYDATA ;=>ELSE JUST COPY DATA
|
||
|
||
OLDCUR LEA CCLASTCRSR(A4),A0 ;POINT TO SAVED DATA
|
||
MOVE.L A2,A1 ;GET POINTER TO CURSOR
|
||
MOVEQ #7,D0 ;CHECK 8 LONGS
|
||
@0 CMP.L (A0)+,(A1)+ ;ARE THEY THE SAME?
|
||
BNE.S GOEXPAND ;=>NO, EXPAND IT
|
||
DBRA D0,@0 ;=>LOOP UNTIL DONE
|
||
|
||
CMP CCDEPTH(A4),D1 ;HAS DEPTH CHANGED?
|
||
BEQ NOEXPAND ;=>NO, DON'T EXPAND
|
||
|
||
GOEXPAND
|
||
;-----------------------------------------------
|
||
;
|
||
; INVALIDATE EXPANDED DATA FOR EACH DEVICE BY CLEARING DEPTH
|
||
; THIS MUST BE DONE SO THAT ALL EXPANDED CURSOR IMAGES ARE RENDERED INVALID AFTER
|
||
; AN OLD CURSOR HAS BEEN SET. IF THE CURSOR IS NEW, SETCCURSOR ALREADY DID THIS.
|
||
|
||
MOVE.L DEVICELIST,A0 ;GET FIRST HANDLE IN DEVICE LIST
|
||
NXTGD MOVE.L (A0),A0 ;POINT TO FIRST DEVICE
|
||
TST GDFLAGS(A0) ;IS IT ACTIVE?
|
||
BPL.S NOTACT ;=>NO, SKIP TO NEXT
|
||
CLR GDCCDEPTH(A0) ;ELSE INVALIDATE EXPANDED DATA
|
||
NOTACT MOVE.L GDNEXTGD(A0),D0 ;GET NEXT GRAFDEVICE
|
||
MOVE.L D0,A0 ;GET INTO A0
|
||
BNE.S NXTGD ;=>REPEAT FOR ALL DEVICES
|
||
|
||
; COPY THE CURSOR DATA TO IDENTIFY THIS CURSOR
|
||
|
||
CPYDATA LEA CCLASTCRSR(A4),A0 ;POINT TO SAVED DATA
|
||
MOVE.L A2,A1 ;GET CURSOR
|
||
MOVEQ #7,D0 ;MOVE 8 LONGS
|
||
@0 MOVE.L (A1)+,(A0)+ ;MOVE A LONG
|
||
DBRA D0,@0 ;=>LOOP UNTIL DONE
|
||
|
||
; UPDATE THE ROWBYTES AND DEPTH FOR THE EXPANDED DATA
|
||
|
||
; MOVE D1,(A0)+ ;COPY THE DEPTH TOO <this is the top half of ccID! <BAL 01Apr89>
|
||
MOVE D1,CCDEPTH(A4) ;SET DEPTH TO SAY IT'S EXPANDED
|
||
ADD D1,D1 ;DOUBLE FOR CURSOR'S ROWBYTES
|
||
MOVE D1,CCBYTES(A4) ;AND UPDATE ROWBYTES
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; EXPAND THE CURSOR TO THE CURRENT DEPTH
|
||
;
|
||
MOVE.L A2,A0 ;SRC = CURSOR
|
||
MOVE.L ([CCXDATA,A4]),A1 ;POINT TO EXPANDED DATA (LOCKED)
|
||
MOVE.L A1,A2 ;GET START OF DST BUFFER
|
||
MOVE #32,D5 ;GET #BYTES OF SOURCE
|
||
LSL D7,D5 ;MULTIPLY BY DEPTH
|
||
ADD D5,A2 ;POINT TO END OF BUFFER
|
||
|
||
move d7,d0
|
||
cmp #4,d0 ;16/32 bits per pixel? <BAL 28Jun88>
|
||
blt.s @1 ;no, don't hack depth conversion
|
||
addq #2,d0 ;get address of spiffy 1 to 15/24 bit expand
|
||
|
||
@1 move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE
|
||
add.l 0(A3,D0*4),A3 ;USE DEPTH TO SELECT ROUTINE
|
||
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
|
||
JSR (A3) ;EXPAND 32*DEPTH BYTES
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; EXPAND THE MASK TO THE CURRENT DEPTH
|
||
;
|
||
EXPMASK LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK
|
||
MOVE.L ([CCXMASK,A4]),A1 ;POINT TO EXPANDED MASK (LOCKED)
|
||
MOVE.L A1,A2 ;GET START OF DST BUFFER
|
||
MOVE #32,D5 ;GET #BYTES OF SOURCE <BAL 14Jun88>
|
||
LSL D7,D5 ;MULTIPLY BY DEPTH <BAL 14Jun88>
|
||
ADD D5,A2 ;POINT TO END OF BUFFER
|
||
|
||
move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE
|
||
add.l 0(A3,D7*4),A3 ;USE DEPTH TO SELECT ROUTINE
|
||
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
|
||
JSR (A3) ;EXPAND 32*DEPTH BYTES
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; PREPARE TO BLT THE CURSOR ON THE SCREEN IN ANY DEPTH
|
||
; (SUBTITLE: WALTZ OF THE REGISTERS)
|
||
;
|
||
NOEXPAND
|
||
MOVE.L ([CCXDATA,A4]),d0 ;A2 = EXPANDED DATA FOR BLT (LOCKED)
|
||
_rTranslate24To32 ;strip off high byte
|
||
move.l d0,a2
|
||
MOVE.L ([CCXMASK,A4]),d0 ;A3 = EXPANDED MASK FOR BLT (LOCKED)
|
||
_rTranslate24To32 ;strip off high byte
|
||
move.l d0,a3
|
||
MOVEQ #16,D5 ;D5 = 16
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; CLIP THE CURSOR VERTICALLY AND GET THE TOP AND BOTTOM INTO D2 AND D3.
|
||
; IF THE TOP IS CLIPPED, UPDATE THE DATA BASE ADDRESSES IN A2 AND A3.
|
||
;
|
||
MOVE MOUSE+V,D2 ;MOUSE POSITION Y
|
||
SUB CRSRPIN+TOP,D2 ;CONVERT TO SCREEN LOCAL COORDS
|
||
SUB THECRSR+HOTSPOT+V,D2 ; - HOTSPOT = TOP EDGE
|
||
MOVE D2,D3 ;GET CURSOR BOTTOM
|
||
ADD D5,D3 ; = TOP + 16
|
||
CMP D5,D3 ;AT TOP?
|
||
BGE.S CHKBOT ;=>NOT AT TOP
|
||
NEG D2 ;GET NUMBER OF CLIPPED ROWS
|
||
CMP D5,D2 ;ARE ALL 16 CLIPPED?
|
||
BEQ SkipBlit ;=>IF SO, NOTHING TO SHOW
|
||
MULU CCBYTES(A4),D2 ; * ROWBYTES FOR OFFSET
|
||
ADD.L D2,A2 ;ADD VERTICAL OFFSET INTO CURSOR
|
||
ADD.L D2,A3 ;ADD VERTICAL OFFSET INTO MASK
|
||
MOVEQ #0,D2 ;AND PIN CURSOR TO TOP
|
||
|
||
CHKBOT MOVE COLLINES,D4 ;GET BOTTOM OF SCREEN
|
||
CMP D4,D3 ;PAST BOTTOM?
|
||
BLE.S CHKLFT ;=>NO, VERTICAL OK
|
||
MOVE D4,D3 ;ELSE PIN TO BOTTOM EDGE
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; CLIP THE CURSOR HORIZONTALLY AND GET THE LEFT AND RIGHT INTO D0 AND D1
|
||
; IF THE LEFT OF THE CURSOR IS CLIPPED, ADJUST THE OFFET IN D6.
|
||
|
||
CHKLFT MOVEQ #0,D6 ;INIT SRC/DST OFFSET TO 0
|
||
MOVE MOUSE+H,D0 ;MOUSE POSITION X
|
||
SUB CRSRPIN+LEFT,D0 ;CONVERT TO SCREEN LOCAL COORDS
|
||
SUB THECRSR+HOTSPOT+H,D0 ; - HOTSPOT = CURSOR LEFT
|
||
MOVE D0,D1 ;GET CURSOR RIGHT
|
||
ADD D5,D1 ; = LEFT + 16
|
||
CMP D5,D1 ;AT LEFT EDGE?
|
||
BGE.S CHKRT ;=>NOT AT LEFT EDGE
|
||
SUB D0,D6 ;OFFSET = AMOUNT CLIPPED
|
||
MOVEQ #0,D0 ;AND PIN TO LEFT EDGE
|
||
|
||
CHKRT MOVE ROWBITS,D4 ;GET RIGHT EDGE OF SCREEN
|
||
CMP D4,D1 ;PAST RIGHT EDGE?
|
||
BLE.S RTOK ;=>NO, HORIZONTAL OK
|
||
MOVE D4,D1 ;ELSE PIN TO RIGHT EDGE
|
||
RTOK
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; USE TOP AND LEFT TO CALCULATE THE LONG ALIGNED SCREEN BASE ADDRESS
|
||
|
||
MOVE.L CRSRBASE,A5 ;A5 = POINTER TO BASE OF SCREEN
|
||
MOVE CRSRROW,A0 ;A0 = SCREEN ROWBYTES
|
||
MOVE A0,D4 ;COPY FOR MULU
|
||
MULU D2,D4 ;TOP * ROWBYTES
|
||
ADD.L D4,A5 ;ADD VERT OFFSET INTO SCREEN
|
||
ext.l d0 ;make it a long <BAL 17Jan89>
|
||
LSL.l D7,D0 ;CONVERT LEFT PIXELS TO BITS
|
||
MOVE.l D0,D4 ;GET LEFT EDGE
|
||
AND.l #~$1F,D4 ;LONGWORD ALIGNED
|
||
MOVE.l D4,D5 ;MAKE A COPY
|
||
ASR.l #3,D5 ;CONVERT BITS TO BYTES
|
||
ADD.l D5,A5 ;GET BASE OFFSET IN SCREEN
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SAVE THE CRSRRECT FOR CURSHIELD
|
||
|
||
LEA CrsrRect,A1 ;SET UP CRSRRECT
|
||
MOVE D2,(A1)+ ;TOP
|
||
MOVE.l D4,D5 ;GET LONG ALIGNED LEFT IN BITS
|
||
LSR.l D7,D5 ;CONVERT TO PIXELS
|
||
MOVE D5,(A1)+ ;LONG ALIGNED LEFT
|
||
MOVE D3,(A1)+ ;BOTTOM
|
||
MOVE D5,(A1) ;RIGHT = LEFT + longcount/pixs in long
|
||
|
||
if cursorShadow then
|
||
add.w #16,-2(a1) ;grow height for shadow
|
||
add.w #16,(a1) ;grow width for shadow
|
||
endif
|
||
|
||
SAMELONG
|
||
;-----------------------------------------------
|
||
;
|
||
; ADJUST DST/SRC OFFSET IN D6
|
||
; GET NUMBER OF ROWS TO DO IN D3
|
||
; GET LONGCNT IN D5 AND USE TO ADJUST DSTBUMP IN A0
|
||
|
||
AND #$1F,D0 ;GET LEFT EDGE MOD 32
|
||
LSL D7,D6 ;CONVERT OFFSET TO BITS
|
||
SUB D0,D6 ; = NEG OFFSET FROM SOURCE
|
||
|
||
ext.l d1 ;make it a long <BAL 17Jan89>
|
||
LSL.l D7,D1 ;CONVERT RIGHT EDGE TO BITS
|
||
MOVE.l D1,D5 ;MAKE COPY
|
||
SUB.l D4,D5 ;GET WIDTH OF CURSOR
|
||
ble SkipBlit ;crsr fits in 0 or fewer longs so don't draw
|
||
subq #1,d5 ;force multiples of 32 to round down
|
||
|
||
LSR.l #5,D5 ;GET LONGS-1
|
||
|
||
SUB D2,D3 ;D3 = # ROWS TO DO
|
||
SUBQ #1,D3 ;MAKE IT 0 BASED
|
||
|
||
MOVE.l D5,D2 ;GET LONGS
|
||
ADDQ.l #1,D2 ;MAKE ONE BASED
|
||
LSL.l #2,D2 ;CONVERT TO BYTES
|
||
SUB.l D2,A0 ;ADJUST DST BUMP
|
||
|
||
lsl.l #3,d2 ;get long aligned bit width
|
||
lsr.l d7,d2 ;get effective cursr pixel width
|
||
add d2,(a1) ;adjust crsrRect.right = left+width
|
||
|
||
BSR CursorSect ;Now then, do we intersect shield?
|
||
BNE SkipBlit ;If so, ththat's all.
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; CONVERT LEFT EDGE AND RIGHT EDGE TO LEFTMASK AND RIGHTMASK IN D4 AND D2
|
||
|
||
MOVEQ #-1,D4 ;FILL LONG WITH ONES
|
||
LSR.L D0,D4 ;AND SHIFT IN 0'S FOR LEFTMASK
|
||
|
||
MOVEQ #-1,D2 ;FILL LONG WITH ONES
|
||
AND #$1F,D1 ;GET RIGHT MOD 32
|
||
beq.s @1 ;does right have a real mask? no, flush it
|
||
LSR.L D1,D2 ;AND SHIFT 0'S IN FROM RIGHT
|
||
NOT.L D2 ;GET RIGHTMASK
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT
|
||
; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE.
|
||
|
||
@1 LEA CCBYTES(A4),A6 ;POINT TO END OF SAVE STATE AREA
|
||
MOVE (A6),A1 ;A1 = ROWBYTES FOR EXPANDED CURSOR
|
||
MOVE.L ([CCSAVE,A4]),d0 ;A4 = POINTER TO SAVE AREA (LOCKED)
|
||
_rTranslate24To32 ;strip off high byte
|
||
move.l d0,a4
|
||
MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
movem.l a0-a2,-(sp) ;save off registers
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2)
|
||
movem.l (sp)+,a0-a2 ;restore registers
|
||
move.b d0,-(sp) ;save previous state for later
|
||
|
||
MOVE.L D5,A6 ;SAVE LONGCNT
|
||
EXT.L D6 ;BFEXTU LIKES LONG OFFSETS
|
||
MOVE.L D6,-(SP) ;SAVE OFFSET ON STACK
|
||
MOVE.L D4,-(SP) ;SAVE LEFTMASK ON STACK
|
||
|
||
;use alternate loop if on Direct Device <BAL 12 Mar89>
|
||
|
||
cmp #4,d7 ;are we 16 or 32 bits/pixel (direct device) ?
|
||
bge Direct ;no, don't hack
|
||
|
||
if cursorShadow then
|
||
cmp #3,d7
|
||
beq Shadow8
|
||
endif
|
||
|
||
TST D5 ;CHECK FOR JUST ONE LONG
|
||
BRA.S START ;AND JUMP INTO MIDDLE
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!)
|
||
;
|
||
; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT
|
||
; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK
|
||
; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH
|
||
; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S),
|
||
; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING
|
||
; EFFECTS WILL MANIFEST THEMSELVES.
|
||
;
|
||
; REGISTER USE: D0: SCRATCH A0: DSTBUMP
|
||
; D1: SCRATCH A1: SRCBUMP
|
||
; D2: RIGHTMASK A2: SRCPTR
|
||
; D3: ROWCNT A3: MASKPTR
|
||
; D4: LEFTMASK A4: SAVEPTR
|
||
; D5: LONGCNT A5: DSTPTR
|
||
; D6: OFFSET A6: COPY LONGCNT
|
||
; D7: SCRATCH (A7): LEFTMASK
|
||
; 4(A7): COPY OFFSET
|
||
|
||
END AND.L D2,D4 ;AND RIGHTMASK INTO LEFTMASK
|
||
MAIN BFEXTU (A2){D6:0},D0 ;EXTRACT A LONG OF SRC
|
||
BFEXTU (A3){D6:0},D1 ;EXTRACT A LONG OF MASK
|
||
ADD.L #32,D6 ;BUMP TO NEXT LONG
|
||
AND.L D4,D0 ;AND SRC WITH LEFTMASK
|
||
AND.L D4,D1 ;AND MASK WITH LEFTMASK
|
||
MOVE.L D0,D7 ;COPY SRC
|
||
|
||
AND.L D1,D7 ;GET MASK AND SRC (PIXELS TO REPLACE)
|
||
NOT.L D1 ;GET NOTMASK
|
||
MOVE.L (A5),d4 ;get a long of screen
|
||
move.l d4,(A4)+ ;SAVE A LONG OF SCREEN
|
||
|
||
AND.L D1,D0 ;GET NOTMASK AND SRC (PIXELS TO INVERT)
|
||
AND.L d4,D1 ;PUNCH HOLE FOR PIXELS TO REPLACE (used to be A5)
|
||
OR.L D7,D1 ;REPLACE PIXELS WITHIN MASK
|
||
EOR.L D0,D1 ;INVERT PIXELS OUTSIDE OF MASK
|
||
MOVE.L D1,(A5)+ ;AND PUT TO DST
|
||
MOVEQ #-1,D4 ;FLUSH LEFTMASK
|
||
SUB #1,D5 ;DECREMENT LONGCNT
|
||
START BGT.S MAIN ;=>MORE THAN ONE TO DO
|
||
BEQ.S END ;=>DO LAST LONG
|
||
MOVE.L 4(SP),D6 ;RESTORE OFFSET
|
||
MOVE.L (SP),D4 ;RESTORE LEFTMASK
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT (TEST D5)
|
||
DBRA D3,START ;=>DO NEXT ROW
|
||
|
||
bra DoneBlit
|
||
|
||
|
||
Direct
|
||
bgt.s Direct32
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!)
|
||
;
|
||
; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT
|
||
; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK
|
||
; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH
|
||
; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S),
|
||
; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING
|
||
; EFFECTS WILL MANIFEST THEMSELVES.
|
||
;
|
||
; REGISTER USE: D0: SCRATCH A0: DSTBUMP
|
||
; D1: SCRATCH A1: SRCBUMP
|
||
; D2: RIGHTMASK A2: SRCPTR
|
||
; D3: ROWCNT A3: MASKPTR
|
||
; D4: LEFTMASK A4: SAVEPTR
|
||
; D5: LONGCNT A5: DSTPTR
|
||
; D6: OFFSET A6: COPY LONGCNT
|
||
; D7: SCRATCH (A7): LEFTMASK
|
||
; 4(A7): COPY OFFSET
|
||
Direct16
|
||
swap d4
|
||
|
||
addq #1,d5 ;make one based
|
||
add d5,d5 ;convert longcnt to word cnt
|
||
move d5,d0 ;save pixel cnt
|
||
subq #2,d5 ;make zero based - 1
|
||
move d5,a6 ;save a copy for later scans
|
||
|
||
moveq #-1,d7
|
||
lsr.w #1,d7 ;make into low15bits mask
|
||
|
||
add d0,d0 ;make into byte cnt
|
||
sub d0,a1 ;make srcRow into srcBump
|
||
|
||
asr #3,d6 ;make offset into bytes
|
||
add d6,a2 ;adjust src ptr
|
||
add d6,a3 ;adjust mask ptr
|
||
|
||
@first tst d4 ;is left pixel masked?
|
||
bne.s @MAIN ;no, go to it
|
||
move.w (a5)+,(a4)+ ;save first pixel
|
||
addq #2,a2 ;bump past first src pixel
|
||
addq #2,a3 ;bump past first mask pixel
|
||
bra.s @next
|
||
|
||
@MAIN move.w (A2)+,D0 ;EXTRACT A LONG OF SRC
|
||
MOVE.w (A5),d1 ;get a long of screen
|
||
move.w d1,(A4)+ ;SAVE A LONG OF SCREEN
|
||
tst.w (A3)+ ;EXTRACT A LONG OF MASK
|
||
bne.s @inside
|
||
not.w d0 ;flip src so that black is all 1's
|
||
and.w d7,d0 ;mask off high bit
|
||
beq.s @skipit ;no use in xoring with zero
|
||
eor.w d1,d0 ;xor dst with src
|
||
@inside
|
||
move.w d0,(a5)
|
||
@skipit addq #2,a5
|
||
@next dbra D5,@MAIN ;DECREMENT LONGCNT
|
||
|
||
tst d2 ;is right pixel masked?
|
||
bne.s @last ;no, go to it
|
||
move.w (a5)+,(a4)+ ;save first pixel
|
||
addq #2,a2 ;bump past first src pixel
|
||
addq #2,a3 ;bump past first mask pixel
|
||
bra.s @nxtScn
|
||
|
||
@last move.w (A2)+,D0 ;EXTRACT A LONG OF SRC
|
||
MOVE.w (A5),d1 ;get a long of screen
|
||
move.w d1,(A4)+ ;SAVE A LONG OF SCREEN
|
||
tst.w (A3)+ ;EXTRACT A LONG OF MASK
|
||
bne.s @in
|
||
not.w d0 ;flip src so that black is all 1's
|
||
and.w d7,d0 ;mask off high bit
|
||
beq.s @skip ;no use in xoring with zero
|
||
eor.w d1,d0 ;xor dst with src
|
||
@in
|
||
move.w d0,(a5)
|
||
@skip addq #2,a5
|
||
@nxtScn ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@First ;=>DO NEXT ROW
|
||
bra DoneBlit
|
||
|
||
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!)
|
||
;
|
||
; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT
|
||
; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK
|
||
; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH
|
||
; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S),
|
||
; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING
|
||
; EFFECTS WILL MANIFEST THEMSELVES.
|
||
;
|
||
; REGISTER USE: D0: SCRATCH A0: DSTBUMP
|
||
; D1: SCRATCH A1: SRCBUMP
|
||
; D2: RIGHTMASK A2: SRCPTR
|
||
; D3: ROWCNT A3: MASKPTR
|
||
; D4: LEFTMASK A4: SAVEPTR
|
||
; D5: LONGCNT A5: DSTPTR
|
||
; D6: OFFSET A6: COPY LONGCNT
|
||
; D7: SCRATCH (A7): LEFTMASK
|
||
; 4(A7): COPY OFFSET
|
||
|
||
if cursorShadow then
|
||
|
||
Direct32
|
||
move d5,d0 ;get a copy of long cnt
|
||
addq #1,d0 ;make one based
|
||
lsl #2,d0 ;make into byte cnt
|
||
sub d0,a1 ;make srcRow into srcBump
|
||
|
||
asr #3,d6 ;make offset into bytes
|
||
add d6,a2 ;adjust src ptr
|
||
add d6,a3 ;adjust mask ptr
|
||
|
||
|
||
voff equ 4
|
||
hoff equ 4
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT
|
||
; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE.
|
||
|
||
movem.l d3/d5/a6/a5/a0,-(sp)
|
||
MOVE.L ([CRSRPTR]),D0 ;GET POINTER TO CURSOR DATA (LOCKED)
|
||
_rTranslate24To32
|
||
MOVE.L D0,A6
|
||
LEA CCBYTES(A6),A6 ;POINT TO END OF SAVE STATE AREA
|
||
move.w mouse,d0 ;get vert pos
|
||
lsr.w #6,d0
|
||
; add.w #voff,d3
|
||
add.w d0,d3
|
||
move.w mouse+2,d0 ;get horiz pos
|
||
lsr.w #6,d0
|
||
; add.w #hoff,d5
|
||
add.w d0,d5
|
||
lsl.w #2,d0
|
||
; sub.w #hoff*4,a0
|
||
sub.w d0,a0
|
||
MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT
|
||
MOVE.L D5,A6 ;SAVE LONGCNT
|
||
|
||
@MAIN2 MOVE.L (A5)+,d1 ;get a long of screen
|
||
move.l d1,(a4)+ ;save a long of screen
|
||
dbra D5,@MAIN2 ;DECREMENT LONGCNT
|
||
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN2 ;=>DO NEXT ROW
|
||
movem.l (sp)+,a5/d3/d5/a6/a0
|
||
|
||
|
||
movem.l d3/a2-a5,-(sp)
|
||
|
||
; moveq #voff,d0
|
||
move.w mouse,d0 ;get vert pos
|
||
lsr.w #6,d0
|
||
bra.s @1
|
||
|
||
@0 ADD.w CRSRROW,A5 ;offset SCREEN POINTER vertically
|
||
@1 dbra d0,@0
|
||
|
||
move.w mouse+2,d0 ;get horiz pos
|
||
lsr.w #6,d0
|
||
lsl.w #2,d0
|
||
; add.w #hoff*4,a5
|
||
add.w d0,a5
|
||
|
||
@MAIN1 MOVE.L (A5),d1 ;get a long of screen
|
||
move.l (A2)+,d0 ;combine A LONG OF src
|
||
not.l d0 ;interested in nothing , dammit!!@!
|
||
and.l $31a,d0 ; shit line
|
||
or.l (A3)+,d0 ;EXTRACT A LONG OF MASK
|
||
beq.s @skipit1
|
||
;d0 = 0
|
||
moveq #0,d0 ;assume result is black
|
||
moveq #$3f,d4 ;amount to remove from screen
|
||
swap d4 ;d4 = $3f0000
|
||
sub.l d4,d1 ;darken the red channel
|
||
bcs.s @pinred
|
||
move.l d1,d0 ;take the red channel
|
||
@pinred
|
||
lsr.l #8,d4
|
||
sub.w d4,d1 ;darken the grn channel
|
||
bcs.s @pingrn
|
||
move.w d1,d0 ;take the grn channel
|
||
@pingrn
|
||
lsr.w #8,d4
|
||
sub.b d4,d1 ;darken the blu channel
|
||
bcs.s @pinblu
|
||
move.b d1,d0 ;take the blu channel
|
||
@pinblu
|
||
|
||
move.l d0,(a5)
|
||
@skipit1
|
||
addq #4,a5
|
||
dbra D5,@MAIN1 ;DECREMENT LONGCNT
|
||
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN1 ;=>DO NEXT ROW
|
||
|
||
movem.l (sp)+,d3/a2-a5
|
||
|
||
|
||
|
||
@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC
|
||
MOVE.L (A5),d1 ;get a long of screen
|
||
tst.l (A3)+ ;EXTRACT A LONG OF MASK
|
||
bne.s @inside
|
||
not.l d0 ;flip src so that black is all 1's
|
||
beq.s @skipit ;no use in xoring with zero
|
||
eor.l d1,d0 ;xor dst with src
|
||
@inside
|
||
move.l d0,(a5)
|
||
@skipit addq #4,a5
|
||
dbra D5,@MAIN ;DECREMENT LONGCNT
|
||
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN ;=>DO NEXT ROW
|
||
bra DoneBlit
|
||
|
||
|
||
; REGISTER USE: D0: SCRATCH A0: DSTBUMP
|
||
; D1: SCRATCH A1: SRCBUMP
|
||
; D2: RIGHTMASK A2: SRCPTR
|
||
; D3: ROWCNT A3: MASKPTR
|
||
; D4: LEFTMASK A4: SAVEPTR
|
||
; D5: LONGCNT A5: DSTPTR
|
||
; D6: OFFSET A6: COPY LONGCNT
|
||
; D7: SCRATCH (A7): LEFTMASK
|
||
; 4(A7): COPY OFFSET
|
||
Shadow8
|
||
move d5,d0 ;get a copy of long cnt
|
||
addq #1,d0 ;make one based
|
||
lsl #2,d0 ;make into byte cnt
|
||
sub d0,a1 ;make srcRow into srcBump
|
||
|
||
asr #3,d6 ;make offset into bytes
|
||
add d6,a2 ;adjust src ptr
|
||
add d6,a3 ;adjust mask ptr
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT
|
||
; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE.
|
||
|
||
movem.l d3/d5/a6/a5/a0,-(sp)
|
||
MOVE.L ([CRSRPTR]),D0 ;GET POINTER TO CURSOR DATA (LOCKED)
|
||
_rTranslate24To32
|
||
MOVE.L D0,A6
|
||
LEA CCBYTES(A6),A6 ;POINT TO END OF SAVE STATE AREA
|
||
move.w mouse,d0 ;get vert pos
|
||
lsr.w #6,d0 ;d0=voff
|
||
; add.w #voff,d3
|
||
add.w d0,d3
|
||
move.w mouse+2,d0 ;get horiz pos
|
||
lsr.w #6,d0 ;d0=hoff
|
||
; add.w #hoff,d5
|
||
addq #3,d0
|
||
lsr.w #2,d0 ;d0=shadow width longs
|
||
add.w d0,d5
|
||
|
||
lsl.w #2,d0
|
||
; sub.w #hoff*4,a0
|
||
sub.w d0,a0
|
||
MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT
|
||
MOVE.L D5,A6 ;SAVE LONGCNT
|
||
|
||
;-------------------------------------------
|
||
; Save bits under cursor/shadow
|
||
;-------------------------------------------
|
||
@MAIN2 MOVE.L (A5)+,d1 ;get a long of screen
|
||
move.l d1,(a4)+ ;save a long of screen
|
||
dbra D5,@MAIN2 ;DECREMENT LONGCNT
|
||
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN2 ;=>DO NEXT ROW
|
||
movem.l (sp)+,a5/d3/d5/a6/a0
|
||
|
||
|
||
;-------------------------------------------
|
||
; Draw Shadow
|
||
;-------------------------------------------
|
||
movem.l d3/a2-a5,-(sp)
|
||
|
||
; moveq #voff-1,d0
|
||
move.w mouse,d0 ;get vert pos
|
||
lsr.w #6,d0
|
||
bra.s @1
|
||
|
||
@0 ADD.w CRSRROW,A5 ;offset SCREEN POINTER vertically
|
||
@1 dbra d0,@0
|
||
|
||
move.w mouse+2,d0 ;get horiz pos
|
||
lsr.w #6,d0
|
||
add.w d0,a5
|
||
; add.w #hoff,a5
|
||
|
||
@MAIN1 MOVE.l (A5),d1 ;get a long of screen
|
||
move.l (A2)+,d0 ;combine A LONG OF src
|
||
or.l (A3)+,d0 ;EXTRACT A LONG OF MASK
|
||
beq.s @skipit1
|
||
;d0 = 0
|
||
moveq #0,d0 ;assume result is black
|
||
moveq #$3f,d4 ;amount to remove from screen
|
||
swap d4 ;d4 = $3f0000
|
||
sub.l d4,d1 ;darken the red channel
|
||
bcs.s @pinred
|
||
move.l d1,d0 ;take the red channel
|
||
@pinred
|
||
lsr.l #8,d4
|
||
sub.w d4,d1 ;darken the grn channel
|
||
bcs.s @pingrn
|
||
move.w d1,d0 ;take the grn channel
|
||
@pingrn
|
||
lsr.w #8,d4
|
||
sub.b d4,d1 ;darken the blu channel
|
||
bcs.s @pinblu
|
||
move.b d1,d0 ;take the blu channel
|
||
@pinblu
|
||
|
||
; move.l d0,(a5)
|
||
@skipit1
|
||
addq #4,a5
|
||
dbra D5,@MAIN1 ;DECREMENT LONGCNT
|
||
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN1 ;=>DO NEXT ROW
|
||
|
||
movem.l (sp)+,d3/a2-a5
|
||
|
||
;-------------------------------------------
|
||
; Draw cursor atop shadow
|
||
;-------------------------------------------
|
||
|
||
@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC
|
||
tst.l (A3)+ ;EXTRACT A LONG OF MASK
|
||
bne.s @inside
|
||
tst.l d0 ;flip src so that black is all 1's
|
||
beq.s @skipit ;no use in xoring with zero
|
||
MOVE.L (A5),d1 ;get a long of screen
|
||
eor.l d1,d0 ;xor dst with src
|
||
@inside
|
||
move.l d0,(a5)
|
||
@skipit addq #4,a5
|
||
dbra D5,@MAIN ;DECREMENT LONGCNT
|
||
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN ;=>DO NEXT ROW
|
||
|
||
else
|
||
|
||
Direct32
|
||
moveq #-1,d4
|
||
lsr.l #8,d4 ;get low3bytes in d4
|
||
move d5,d0 ;get a copy of long cnt
|
||
addq #1,d0 ;make one based
|
||
lsl #2,d0 ;make into byte cnt
|
||
sub d0,a1 ;make srcRow into srcBump
|
||
|
||
asr #3,d6 ;make offset into bytes
|
||
add d6,a2 ;adjust src ptr
|
||
add d6,a3 ;adjust mask ptr
|
||
|
||
@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC
|
||
MOVE.L (A5),d1 ;get a long of screen
|
||
move.l d1,(A4)+ ;SAVE A LONG OF SCREEN
|
||
tst.l (A3)+ ;EXTRACT A LONG OF MASK
|
||
bne.s @inside
|
||
not.l d0 ;flip src so that black is all 1's
|
||
and.l d4,d0 ;mask off high byte
|
||
beq.s @skipit ;no use in xoring with zero
|
||
eor.l d1,d0 ;xor dst with src
|
||
@inside
|
||
move.l d0,(a5)
|
||
@skipit addq #4,a5
|
||
dbra D5,@MAIN ;DECREMENT LONGCNT
|
||
|
||
ADD.L A1,A3 ;BUMP CURSOR DATA
|
||
ADD.L A1,A2 ;BUMP CURSOR MASK
|
||
ADD.L A0,A5 ;BUMP SCREEN POINTER
|
||
MOVE.L A6,D5 ;RESTORE LONGCNT
|
||
DBRA D3,@MAIN ;=>DO NEXT ROW
|
||
|
||
endif
|
||
|
||
|
||
DoneBlit
|
||
ADDQ #8,SP ;STRIP LEFTMASK AND OFFSET
|
||
MOVE.B #1,CrsrVis ;CURSOR VISIBLE
|
||
|
||
moveq #0,d0
|
||
move.b (sp)+,d0 ;get previous MMU state in d0
|
||
_rSwapMMUMode ;restore MMU mode from d0.b
|
||
SkipBlit
|
||
MOVEM.L (SP)+,D0-D7/A0-A6 ;THE WALTZ IS OVER...(TANGO VERY MUCH)
|
||
NoBlit
|
||
RTS
|
||
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; UNBLITCURSOR <dvb 19sep88>
|
||
;
|
||
; This routine unconditionally removes cursor according to the data in
|
||
; CCSTATEREGS.
|
||
; Such things as crsrstate, crsrvis, and other nonsense have already been
|
||
; checked. Vectoring this routine may prove useful for later cursor
|
||
; enhancements.
|
||
|
||
UNBLITCURSOR PROC EXPORT
|
||
TST.L CRSRPTR ;CURSOR ALLOCATED?
|
||
BMI.S DONEHIDE ;=>NO, JUST RETURN
|
||
MOVEM.L D1-D4/A0-A2,-(SP) ;SAVE REGS USED
|
||
|
||
MOVE.L ([CRSRPTR]),A0 ;GET POINTER TO CURSOR SAVE DATA (LOCKED)
|
||
MOVE.L CCSAVE(A0),A1 ;GET HANDLE TO SAVED BITS
|
||
MOVE.L (A1),d0 ;POINT TO SAVED BITS
|
||
_rTranslate24To32 ;mask off high byte
|
||
move.l d0,a1
|
||
LEA CCSTATEREGS(A0),A0 ;POINT TO SAVE STATE AREA
|
||
MOVEM.L (A0)+,D2/D3/D4/A2 ;GET /ROWCNT/LONGCNT/DSTBUMP/DSTLEFT
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit mode
|
||
movem.l d2/a1/a2,-(sp) ;save off registers
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2)
|
||
movem.l (sp)+,d2/a1/a2 ;restore registers
|
||
|
||
MOVE.L D3,A0 ;SAVE LONGCNT
|
||
@1 MOVE.L (A1)+,(A2)+ ;RESTORE A LONG OF SOURCE
|
||
DBRA D3,@1 ;=>DO ENTIRE ROW
|
||
MOVE.L A0,D3 ;RESTORE LONGCNT
|
||
ADD D4,A2 ;BUMP DST
|
||
DBRA D2,@1 ;=>DO FOR ALL LINES
|
||
|
||
_rSwapMMUMode ;restore original mode from d0.b
|
||
|
||
CLR.B CRSRVIS ;MARK IT AS INVISIBLE
|
||
MOVEM.L (SP)+,D1-D4/A0-A2 ;RESTORE REGS USED
|
||
DONEHIDE RTS
|
||
|
||
|
||
;
|
||
;_______________________________________________________________________
|
||
;
|
||
; FUNCTION ScrnAddress:Ptr;
|
||
;
|
||
; return a pointer to the start of the bit-map display
|
||
;
|
||
ScrnAddress PROC EXPORT
|
||
MOVE.L ScrnBase,4(SP) ;get screenBase set up by OS
|
||
RTS ;that was easy!
|
||
|
||
;
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE ScrnSize(VAR hDots,vDots: INTEGER);
|
||
;
|
||
; return the size of the screen in pixels
|
||
;
|
||
ScrnSize PROC EXPORT
|
||
MOVE.L (SP)+,D0 ;get the return address
|
||
MOVE.L MainDevice,A0 ;get handle to main screen device
|
||
MOVE.L (A0),A0 ;point to main screen device
|
||
MOVE.L (SP)+,A1 ;get pointer to vDots
|
||
MOVE GDRect+bottom(A0),D1 ;get bottom
|
||
SUB GDRect+top(A0),D1 ;calc height
|
||
MOVE D1,(A1) ;return the number of vertical pixels
|
||
MOVE.L (SP)+,A1 ;get pointer to hdots
|
||
MOVE GDRect+right(A0),D1 ;get right
|
||
SUB GDRect+left(A0),D1 ;calc width
|
||
MOVE D1,(A1) ;return the number of horizontal pixels
|
||
MOVE.L D0,A0 ;get return address
|
||
JMP (A0) ;and return
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE ScrnBitMap(VAR x: BitMap);
|
||
;
|
||
; return the screen bitmap
|
||
;
|
||
ScrnBitMap PROC EXPORT
|
||
MOVE.L (SP)+,D0 ;get the return address
|
||
MOVE.L MainDevice,A0 ;get handle to main screen device
|
||
MOVE.L (A0),A0 ;point to main screen device
|
||
MOVE.L GDPMap(A0),A0 ;get handle to screen's pixMap
|
||
MOVE.L (A0),A0 ;point to screen's pixMap
|
||
MOVE.L (SP)+,A1 ;get pointer to BitMap
|
||
MOVE.L (A0)+,(A1)+ ;copy base addr
|
||
MOVE (A0)+,D1 ;get rowbytes
|
||
AND #nuRBMask,D1 ;mask flag bits
|
||
MOVE D1,(A1)+ ;copy rowbytes
|
||
MOVE.L (A0)+,(A1)+ ;copy bounds.topleft
|
||
MOVE.L (A0)+,(A1)+ ;copy bounds.botright
|
||
MOVE.L D0,A0 ;get return address
|
||
JMP (A0) ;and return
|
||
|
||
|