mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-29 07:29:15 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
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
|
|
|
|
|