mac-rom/QuickDraw/Classic/CrsrCore.a

1132 lines
38 KiB
Plaintext
Raw Normal View History

;
; File: CrsrCore.a
;
; Contains: xxx put contents here (or delete the whole line) xxx
;
; Written by: Bud Tribble 2-Oct-81
;
; Copyright: <09> 1981-1990 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <3> 6/25/90 KON Also add previous patch to CQD version, even though it doesn't
; get built from here.
; <2> 6/25/90 KON Update show cursor so obscure-hide-show leaves cursor obscured,
; and obscure-show-hide leaves cursor hidden.
; <1.8> 11/1/89 MSH Rolling HcMac fiction changes in. Pmgr equates now in record
; format and IdleUpdate
; <1.7> 8/22/89 SES Removed include nEqu.d.
; <1.6> 6/10/89 SWC Changed all Mac Plus/SE screen dimension references to use lomem
; variables instead.
; <1.5> 3/31/89 MSH If SetCursor is setting the watch cursor (RAM or ROM version)
; then
; <1.4> 3/10/89 MSH Added onhcmac to scrnsize.
; <1.3> 3/1/89 MSH Fixed up hcmac to use rowbits and collines for screen size
; <1.2> 2/20/89 rwh changed to feature based conditionals.
; <1.1> 11/10/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <<3C>1.2> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.1> 9/8/88 MSH When drawing new cursor, reset the idle/sleep timeout.
; <1.0> 2/10/88 BBM Adding file for the first time into EASE<53>
; <C914> 10/29/87 rwh Port to Modern Victorian (onMvMac)
; <C918> 10/22/87 MSH This file needs nHardwareEqu.a included.
; <C893> 9/30/87 MSH Port to HcMac (Laguna)
; <C856> 5/26/87 CSL Fixed absolute cursor positioning problem.
; <C75> 7/15/86 EHB Save smaller CRSRRECT in ShowCursor (less flicker)
; 7/14/86 EHB Don't draw cursor if CRSRPTR not set up.
; <C63> 7/2/86 EHB Include colorequ in great equate purge
; <C63> 7/2/86 EHB CLEAR D0 BEFORE CALLING EXTBL ROUTINES. Multiply offset amount
; by depth for left pinning Check 8 longs of cursor
; <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
; 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
;
; To Do:
;
;EASE$$$ READ ONLY COPY of file <20>crsrcore.a<>
; 1.8 MSH 11/01/1989 Rolling HcMac fiction changes in. Pmgr equates now in record format and IdleUpdate
; trap replaces equivalent idle update code.
; 1.7 SES 08/22/1989 Removed include nEqu.d.
; 1.6 SWC 06/10/1989 Changed all Mac Plus/SE screen dimension references to use lomem variables instead.
; 1.5 MSH 03/31/1989 If SetCursor is setting the watch cursor (RAM or ROM version) then
; set a flag. HcMac only.
; 1.4 MSH 03/10/1989 Added onhcmac to scrnsize.
; 1.3 MSH 03/01/1989 Fixed up hcmac to use rowbits and collines for screen size
; calculations.
; 1.2 rwh 02/20/1989 changed to feature based conditionals.
; 1.1 CCH 11/10/1988 Fixed Header.
; 1.0 CCH 11/ 9/1988 Adding to EASE.
; OLD REVISIONS BELOW
;<3B>1.2 CCH 9/23/1988 Got rid of inc.sum.d and empty nFiles
; 1.1 MSH 9/8/1988 When drawing new cursor, reset the idle/sleep timeout.
; 1.0 BBM 2/10/88 Adding file for the first time into EASE<53>
; END EASE MODIFICATION HISTORY
; FILE: CRSRCORE.TEXT
;_______________________________________________________________________
;
; CRSRCORE - System cursor/mouse routines. Contains the
; mouse interrupt receivers and cursor drawing
; and hiding routines.
;
; Written by: Bud Tribble 2-Oct-81
;
; MODIFICATION HISTORY:
;
; 19-oct-81 bmw fixed a bug andy found in getscreen
; 31-Oct-81 AJH Hardwired the CRSR task into the VBL manager
; 09-Apr-82 AJH Changed SHOWCURSOR to clip ala Rick Meyer's Lisa routines
; 04-May-82 LAK Updated MV1INT, MH1INT for SCC hardware
; 05-Aug-82 LAK modified for INTHND change (no need to modify A0-1 for
; SCC port A) or read status reg.
; 03-Jul-81 AJH Installed "ObscureCursror" entry point and support
; 26-Aug-82 LAK updated for 512-dots
; 05-Sep-82 LAK IntHnd now handles ext/sts interrupt resetting
; 16-Oct-82 LAK Modified for new LisaGraf cursor interface
; 07-Nov-82 AJH Made ObscureCursor unbusy cursor if already obscured
; 13-Jan-83 SC Decouple and scaled Cursor stuff
; 28-Jan-83 AJH made SetCursor display it if its different
; 28-Apr-83 AJH moved PinRect into crsrCore
; 20-Jul-83 SC Cleaned up after code review
; 18-Aug-83 LAK Changed name of CrsrTask to CrsrVBLTask (but why?).
; 20-Aug-83 LAK Just uses CrsrThresh for scaling params.
;-----------------------------------------------------------------------
; 23 Jan 83 LAK Adapted for new equate files.
; 05 Apr 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.
; 23 Apr 85 JTC Change to PIN hotSpot between 0 and 16, not 15. <23Apr85>
; 23 Apr 85 LAK/BDA/AJH Added ScrnBitMap proc. Changed all <23Apr85>
; Screen names to Scrn for consistency and to avoid
; ScreenBits conflict.
; <23Jul85> RDC Moved mouse interrupt routines to IntHnd.Text
; <25Jul85> RDC Added include for HWequ file
; <05Nov85> JTC for ELR (on telephone) Fix loop termination condition in HideCursor that killed
; MacPaint, e.g.
;_______________________________________________________________________
;
; Post Lonely Hearts
;_______________________________________________________________________
;
; <19feb86> BBM Made some modifications to work under MPW
; <C1/15Apr86> 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
; <C1/6May86> RDC Added fixes in ShowCursor routine
; <C28/30May86>CSL Added changes for Aladdin, and Aladdin Front desk bus support.
; <C60/30JUN86>EHB New ShowCursor/HideCursor for depth support
; Fixed branch bug in ShieldCursor
; <C63/2Jul86> EHB Include colorequ in great equate purge
; <C63/2Jul86> EHB CLEAR D0 BEFORE CALLING EXTBL ROUTINES.
; Multiply offset amount by depth for left pinning
; Check 8 longs of cursor
; 14Jul86 EHB Don't draw cursor if CRSRPTR not set up.
; <C75/15Jul86>EHB Save smaller CRSRRECT in ShowCursor (less flicker)
; <C856/26May87> CSL Fixed absolute cursor positioning problem.
; <C893/30Sep87> MSH Port to HcMac (Laguna)
; <C918/22oct87> MSH This file needs nHardwareEqu.a included.
; <C914/29Oct87> rwh Port to Modern Victorian (onMvMac)
;_______________________________________________________________________
BLANKS ON
STRING ASIS
IF CPU <20> 020 THEN ;<C914><1.2>
MACHINE MC68020 ;<C60/30JUN86>
ENDIF
LOAD 'StandardEqu.d'
INCLUDE 'HardwareEqu.a'
INCLUDE 'colorequ.a' ;<C63/2Jul86>
CRSRCORE PROC EXPORT
EXPORT CrsrVBLTask
EXPORT ScrnAddress
EXPORT ScrnSize
EXPORT ScrnBitMap
EXPORT InitCrTable
EXPORT PinRect
WITH PmgrRec ;<v1.8>
;
; 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
;_______________________________________________________________________
;
; 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. This falls through into HideCursor
;
;_______________________________________________________________________
ObscureCursor
MOVE.B #1,CRSRBUSY ;flag the cursor as busy
IF hasCQD THEN ; <C914><1.2>
TST.L CRSRPTR ;CURSOR ALLOCATED?
BMI.S DONEHIDE ;=>NO, JUST RETURN
ENDIF
BSET #0,CRSROBSCURE ;mark it as obscured
BNE.S DoneHide ;if already obscured, skip hide
;Fall into hidecursor
;_______________________________________________________________________
;
; HIDECURSOR - is called from CrsrVBLTask, CURSHIELD, and via jump table.
;
; Subtracts 1 from crsrstate and hides the cursor if visible.
;
;
IF <09>hasCQD THEN ; <1.2>
HideCursor
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
TST.B CRSRVIS ;IS CURSOR VISIBLE?
BEQ.S NOHIDE ;NO, DON'T TRY TO REMOVE IT
MOVEM.L D0-D1/A0-A1,-(SP) ;SAVE REGS USED
LEA CrsrRect,A1 ; point to rect for fun
MOVE (A1),D1 ;GET BOTTOM OF SAVED BITS
CLR.L (A1)+ ;RESET topleft to 0
SUB (A1),D1 ;CALC HEIGHT COUNT
CLR.L (A1)
NEG D1 ; D1 contained top-bottom so invert
BEQ.S DRKXLPLYTKC ; INVISIBLE CURSOR? DON'T BLIT ANYTHING <05Nov85> ELR
MOVE.L CRSRADDR,A1 ;POINT TO WHERE WE LAST SAVED FROM
LEA CRSRSAVE,A0 ;POINT TO THE SAVED DATA
MOVE.W ScreenRow,D0 ;GET ROWBYTES <C1/15Apr86><1.6>
ERASLP MOVE.L (A0)+,(A1) ;RESTORE BITS UNDER CURSOR
ADD D0,A1 ;BUMP DSTPTR TO NEXT ROW
SUBQ #1,D1 ;DEC LOOP COUNT
BGT.S ERASLP ;ERASE ALL ROWS -- was BNE.S <05Nov85 JTC4ELR>
DRKXLPLYTKC
CLR.B CRSRVIS ;MARK IT AS INVISIBLE
MOVEM.L (SP)+,D0-D1/A0-A1 ;RESTORE REGS USED
NOHIDE SUB #1,CRSRSTATE ;CURSOR HIDDEN ONE DEEPER
DoneHide
CLR.B CRSRBUSY ;CHANGE COMPLETE
RTS
ELSE ; <1.2>
HideCursor
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
TST.L CRSRPTR ;CURSOR ALLOCATED?
BMI.S DONEHIDE ;=>NO, JUST RETURN
TST.B CRSRVIS ;IS CURSOR VISIBLE?
BEQ.S NOHIDE ;NO, DON'T TRY TO REMOVE IT
MOVEM.L D0-D2/A0-A2,-(SP) ;SAVE REGS USED
LEA CrsrRect,A1 ; point to rect for fun
MOVE (A1),D1 ;GET BOTTOM OF SAVED BITS
CLR.L (A1)+ ;RESET topleft to 0
SUB (A1),D1 ;CALC HEIGHT COUNT
CLR.L (A1)
NEG D1 ; D1 contained top-bottom so invert
BEQ.S DRKXLPLYTKC ; INVISIBLE CURSOR? DON'T BLIT ANYTHING <05Nov85> ELR
MOVE.L CRSRPTR,A0 ;GET POINTER TO CURSOR SAVE DATA
LEA STATEREGS(A0),A0 ;POINT TO SAVE STATE AREA
MOVEM.L (A0)+,D0/D1/D2/A1/A2 ;GET /ROWCNT/LONGCNT/DSTBUMP/SAVE/DSTLEFT
@0 MOVE.L D1,A0 ;SAVE LONGCNT
@1 MOVE.L (A1)+,(A2)+ ;RESTORE A LONG OF SOURCE
DBRA D1,@1 ;=>DO ENTIRE ROW
MOVE.L A0,D1 ;RESTORE LONGCNT
ADD D2,A2 ;BUMP DST
DBRA D0,@0 ;=>DO FOR ALL LINES
DRKXLPLYTKC
CLR.B CRSRVIS ;MARK IT AS INVISIBLE
MOVEM.L (SP)+,D0-D2/A0-A2 ;RESTORE REGS USED
NOHIDE SUB #1,CRSRSTATE ;CURSOR HIDDEN ONE DEEPER
DONEHIDE CLR.B CRSRBUSY ;CHANGE COMPLETE
RTS
ENDIF ;<C60/30JUN86>
;
;_______________________________________________________________________
;
; PROCEDURE InitCursor;
;
; Definately redisplay the cursor, independent of previous calls to
; HideCursor, ShieldCursor and ObscureCursor. It falls into showCursor.
;
InitCursor
MOVE.B #1,CrsrBusy ;mark it busy
IF hasCQD THEN ; <C914><1.2>
TST.L CRSRPTR ;CURSOR ALLOCATED?
BMI.S DONEHIDE ;=>NO, JUST RETURN
ENDIF
CLR.B CrsrObscure ;we wont be obscure no more
CLR CrsrState ;reset state to 0
;
; 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.
;
;
IF <20>hasCQD THEN ; <C60/30jun86><C893><1.2>
SHOWCURSOR
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
ADDQ #1,CRSRSTATE ;CURSOR HIDDEN ONE LESS DEEP
BLT.S DoneHide ;QUIT IF STILL HIDDEN
beq.s @JustDrawIt
clr.b CrsrObscure ;unobscure if level goes +
@JustDrawIt
CLR CRSRSTATE ;DON'T LET CRSRSTATE GET > 0
TST.B CRSRVIS ;IS CURSOR ALREADY VISIBLE?
BNE.S DoneHide ;YES, DON'T TRY TO REDRAW
;
; the following code is adapted from Rick Meyer's SmallTalk cursor routines
;
MOVEM.L D0-D5/A0-A3,-(SP) ; save registers
MOVEQ #16,D5 ; constant used below; good until @4
LEA CrsrSave,A0 ; saved data address
LEA TheCrsr+Data,A2 ; cursor data bitmap address
LEA TheCrsr+Mask,A3 ; cursor mask bitmap address
; Compute and bounds check the X-coordinate of the data under the cursor.
MOVE.W Mouse+H,D0 ; cursor X-coordinate
SUB.W TheCrsr+HotSpot+H,D0 ; - cursor hotspot X-coordinate
MOVEQ #$F,D2 ; upper left X-coordinate
AND.W D0,D2 ; bit offset within word
NEG.W D2 ; negated and converted to
ADD.W D5,D2 ; left shift count
; work around crummy assembler -- what we want is "MOVE.L #$0000FFFF,D3"
; but the assembler screws it up
MOVEQ #0 ,D3 ; all ones into D3
SUBQ.W #1,D3 ; get 0000FFFF into D3
LSL.L D2,D3 ; shifted into position
AND.W #$FFF0,D0 ; upper left X-coord rounded down
BGE.S @1 ; branch if >= 0
MOVEQ #0,D0 ; minimum upper left X-coord of 0
SWAP D3 ; adjust 32-bit mask
SUB D3,D3 ; LSL #16,D3
ADD.W D5,D2 ; adjust left shift count
@1 MOVE.W RowBits,D1 ; calculate upper left x-coordinate <1.6>
SUB.W #32,D1
CMP.W D1,D0 ; is it less than 32 pixels from the right edge?<1.6>
BLE.S @2
MOVE.W D1,D0 ; yes, pin it 32 pixels from the right <1.6>
SUB D3,D3 ; LSR #16,D3
SWAP D3 ; adjust 32-bit mask
ADD.W D5,D2 ; adjust left shift count
; Compute and bounds check the Y-coordinate of the data under the cursor.
@2 MOVE.W D5,D4 ; rows of saved data
MOVE.W Mouse+V,D1 ; cursor Y-coordinate
SUB.W TheCrsr+HotSpot+V,D1 ; - cursor hotspot Y-coordinate
BGE.S @3 ; branch if upper left Y >= 0
ADD.W D1,D4 ; decrease rows of saved data
ADD.W D1,D1 ; double for byte count
SUB.W D1,A2 ; increase cursor data address
SUB.W D1,A3 ; increase cursor mask address
MOVEQ #0,D1 ; minimum upper left Y of 0
@3 MOVE.W ColLines,D5
SUB.W #16,D5
CMP.W D5,D1 ; upper left Y <= ? <C1/15Apr86><v1.3>
BLE.S @4
MOVE.W ColLines,D4 ; last row on screen <C1/15Apr86>
SUB.W D1,D4 ; adjust rows of saved data
@4 LEA CrsrRect,A1 ; set up crsrrect
MOVE D1,(A1)+ ; top
MOVE D0,(A1)+ ; left
MOVE D1,(A1) ; bottom
ADD D4,(A1)+ ; = top + D4(# rows)
MOVE D0,(A1) ; right = left + 32
ADD #32,(A1)
; Display the cursor on the screen.
; D5 IS 16 UNTIL NOW and used above
MOVE.L ScrnBase,A1 ; screen memory address
LSR.W #3,D0 ; convert X-coord to bytes
ADD.W D0,A1 ; and add to screen address
MOVE.W ScreenROW,D5 ; bytes per row on screen <C1/15Apr86><1.6>
MULU D5,D1 ; * Y-coord
ADD.L D1,A1 ; added to screen address
MOVE.L A1,CrsrAddr ; saved data screen address
BRA.S @6 ; test for rows=0
@5 MOVE.W (A2)+,D0 ; cursor data
ROL.L D2,D0 ; shift to proper bit position
AND.L D3,D0 ; eliminate unwanted bits
MOVE.W (A3)+,D1 ; cursor mask
ROL.L D2,D1 ; shift to proper bit position
AND.L D3,D1 ; eliminate unwanted bits
NOT.L D1 ; invert cursor mask
MOVE.L (A1),(A0)+ ; from screen to saved data
AND.L D1,(A1) ; screen and (not mask)
EOR.L D0,(A1) ; xor cursor data
ADD.W D5,A1 ; screen address of next row
@6 DBF D4,@5 ; loop 'SavedRows' times
MOVE.B #1,CrsrVis ; cursor visible
MOVEM.L (SP)+,D0-D5/A0-A3 ; restore registers <C1/15Apr86>
;
DONESHOW CLR.B CRSRBUSY ;CHANGE COMPLETE
RTS
ELSE ; <1.2>
IMPORT EXTBL ; bit expansion routines from QD
SHOWCURSOR
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
TST.L CRSRPTR ;CURSOR ALLOCATED?
BMI.S DONEHIDE ;=>NO, JUST RETURN
ADDQ #1,CRSRSTATE ;CURSOR HIDDEN ONE LESS DEEP
BLT.S DoneHide ;QUIT IF STILL HIDDEN
beq.s @JustDrawIt
clr.b CrsrObscure ;unobscure if level goes +
@JustDrawIt
CLR CRSRSTATE ;DON'T LET CRSRSTATE GET > 0
TST.B CRSRVIS ;IS CURSOR ALREADY VISIBLE?
BNE.S DoneHide ;YES, DON'T TRY TO REDRAW
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
; IF CURSOR HAS CHANGED, EXPAND IT FOR CURRENT DEPTH
;
MOVE.L CRSRPTR,A0 ;GET POINTER TO DATA SAVE AREA
MOVE CHUNKYDEPTH,D0 ;GET DEPTH
MOVE D0,D1 ;SAVE DEPTH
MOVEQ #0,D7 ;DEFAULT SHIFT = 0
NXTSHFT LSR #1,D0 ;CHECK NEXT DEPTH BIT
BCS.S GOTSHFT ;=>GOT SHIFT
ADDQ #1,D7 ;ELSE ADD ONE TO SHIFT
BRA.S NXTSHFT ;LOOP UNTIL WE HIT A ONE
;-----------------------------------------------
;
; CHECK THE CURSOR TO SEE IF IT HAS CHANGED
;
GOTSHFT MOVE.L A0,A4 ;COPY CURSOR SAVE
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 (A0),D1 ;HAS DEPTH CHANGED?
BEQ.S NOEXPAND ;=>NO, DON'T EXPAND
;-----------------------------------------------
;
; COPY THE CURSOR TO SAY WE'VE EXPANDED IT
;
GOEXPAND MOVE.L A4,A0 ;GET CURSOR SAVE
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
MOVE D1,(A0)+ ;COPY THE DEPTH TOO
;-----------------------------------------------
;
; EXPAND THE CURSOR AND THE MASK TO THE CURRENT DEPTH
;
MOVE.L A2,A0 ;SRC = CURSOR
MOVE.L A4,A1 ;GET DATA POINTER
ADD EXCOFST(A4),A1 ;DST = EXPANDED CURSOR DATA
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
LEA EXTBL,A3 ;POINT TO ROUTINE TABLE
ADD 0(A3,D7*2),A3 ;USE DEPTH TO SELECT ROUTINE
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
JSR (A3) ;EXPAND 32*DEPTH BYTES
LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK
MOVE.L A4,A1 ;GET DATA POINTER
ADD EXMOFST(A4),A1 ;DST = EXPANDED CURSOR MASK
MOVE.L A1,A2 ;GET START OF DST BUFFER
ADD D5,A2 ;POINT TO END OF BUFFER
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 A4,A2 ;A4 = POINTER TO DATA SAVE AREA
ADD EXCOFST(A4),A2 ;A2 = POINTER TO EXPANDED CURSOR
MOVE.L A4,A3 ;GET COPY
ADD EXMOFST(A4),A3 ;A3 = POINTER TO EXPANDED MASK
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 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
MULU CRSRBYTES(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 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 SCRNBASE,A5 ;A5 = POINTER TO BASE OF SCREEN
MOVE SCREENROW,A0 ;A0 = SCREEN ROWBYTES
MOVE.L A0,D4 ;COPY FOR MULU
MULU D2,D4 ;TOP * ROWBYTES
ADD.L D4,A5 ;ADD VERT OFFSET INTO SCREEN
LSL D7,D0 ;CONVERT LEFT PIXELS TO BITS
MOVE D0,D4 ;GET LEFT EDGE
AND #$FFE0,D4 ;LONGWORD ALIGNED
MOVE D4,D5 ;MAKE A COPY
LSR #3,D5 ;CONVERT BITS TO BYTES
ADD D5,A5 ;GET BASE OFFSET IN SCREEN
;-----------------------------------------------
;
; SAVE THE CRSRRECT FOR CURSHIELD
LEA CrsrRect,A1 ;SET UP CRSRRECT
MOVE D2,(A1)+ ;TOP
MOVE D4,D5 ;GET LONG ALIGNED LEFT IN BITS
LSR D7,D5 ;CONVERT TO PIXELS
MOVE D5,(A1)+ ;LONG ALIGNED LEFT
MOVE D3,(A1)+ ;BOTTOM
MOVE D5,(A1) ;RIGHT = LEFT + 32 OR 64
ADD #32,(A1) ;ASSUME RIGHT,LEFT IN SAME LONG
EOR D1,D5 ;TURN OFF COMMON BITS
AND #$FFE0,D5 ;IGNORE LOW 32
BEQ.S SAMELONG ;=>NOT IN SAME LONG
ADD #32,(A1) ;ELSE BUMP RIGHT
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
LSL D7,D1 ;CONVERT RIGHT EDGE TO BITS
MOVE D1,D5 ;MAKE COPY
SUB D4,D5 ;GET WIDTH OF CURSOR
LSR #5,D5 ;GET LONGS-1
SUB D2,D3 ;D3 = # ROWS TO DO
SUBQ #1,D3 ;MAKE IT 0 BASED
MOVE D5,D2 ;GET LONGS
ADDQ #1,D2 ;MAKE ONE BASED
LSL #2,D2 ;CONVERT TO BYTES
SUB D2,A0 ;ADJUST DST BUMP
;-----------------------------------------------
;
; 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 ;GET LEFTMASK
AND #$1F,D1 ;GET RIGHT MOD 32
MOVEQ #-1,D2 ;FILL LONG WITH ONES
LSR.L D1,D2 ;AND SHIFT 0'S IN FROM RIGHT
NOT.L D2 ;GET RIGHTMASK
;-----------------------------------------------
;
; SAVE DSTLEFT/SAVE/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT
; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE.
LEA CRSRBYTES(A4),A6 ;POINT TO END OF SAVE STATE AREA
MOVE (A6),A1 ;A1 = ROWBYTES FOR EXPANDED CURSOR
ADD SAVEOFST(A4),A4 ;PLACE TO SAVE SCREEN DATA
MOVEM.L A5/A4/A0/D5/D3,-(A6) ;SAVE DSTLEFT/SAVE/DSTBUMP/LONGCNT/ROWCNT
MOVE.L D5,A6 ;SAVE LONGCNT
EXT.L D6 ;BFEXTU LIKES LONG OFFSETS
MOVE.L D6,D7 ;SAVE OFFSET
MOVE.L D4,-(SP) ;SAVE LEFTMASK ON STACK
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!!)
;
; REGISTER USE: D0: SCRATCH A0: DSTBUMP
; D1: SCRATCH A1: SRCBUMP
; D2: RIGHTMASK A2: MASKPTR
; D3: ROWCNT A3: SRCPTR
; D4: LEFTMASK A4: SAVEPTR
; D5: LONGCNT A5: DSTPTR
; D6: OFFSET A6: COPY LONGCNT
; D7: COPY OFFSET (A7): LEFTMASK
END AND.L D2,D4 ;AND RIGHTMASK INTO LEFTMASK
MAIN BFEXTU (A2){D6:0},D0 ;EXTRACT A LONG OF MASK
BFEXTU (A3){D6:0},D1 ;EXTRACT A LONG OF SRC
ADD.L #32,D6 ;BUMP TO NEXT LONG
AND.L D4,D0 ;AND MASK WITH LEFTMASK
AND.L D4,D1 ;AND SRC WITH LEFTMASK
NOT.L D1 ;GET NOTSRC FOR PUNCHING DST
MOVE.L (A5),(A4)+ ;SAVE A LONG OF SCREEN
AND.L D1,(A5) ;PUNCH HOLE IN DST
EOR.L D0,(A5)+ ;AND DRAW CURSOR
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 D7,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
MOVE.L (SP)+,D4 ;POP LEFTMASK
MOVE.B #1,CrsrVis ;CURSOR VISIBLE
MOVEM.L (SP)+,D0-D7/A0-A6 ;THE WALTZ IS OVER...(TANGO VERY MUCH)
;
DONESHOW CLR.B CRSRBUSY ;CHANGE COMPLETE
RTS
ENDIF ;<C60/30jun86>
;_______________________________________________________________________
;
; 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.
;
PARAMSIZE EQU 8
ShieldTop EQU 16
ShieldLeft EQU 18
ShieldBottom EQU 12
ShieldRight EQU 14
;
ShieldCursor
; LINK A6,#0 ;NO LOCAL VARS
MOVEM.L D0/A0,-(SP) ;SAVE REGISTERS
LEA CrsrRect,A0 ; point to crsr rect
MOVE ShieldBottom(SP),D0 ;GET SHIELD BOTTOM
CMP (A0)+,D0 ;IS SHIELDBOTTOM < SAVETOP ?
BLT.S NOSECT ;YES, NO INTERSECTION
MOVE.W RowBits,D0 ; get bits per row <C1/15Apr86>
SUB.W #16,D0 ; compute max X-coord <C1/15Apr86>
CMP.W (A0),D0 ; do saved bits wrap around ? <C1/15Apr86>
BLE.S SECT ;YES, BETTER HIDE CURSOR <C60/30JUN86>
MOVE ShieldRight(SP),D0 ;GET SHIELD RIGHT
CMP (A0)+,D0 ;IS SHIELDRIGHT <= SAVELEFT ?
BLE.S NOSECT ;YES, NO INTERSECTION
MOVE ShieldTop(SP),D0 ;GET SHIELD TOP
CMP (A0)+,D0 ;IS SHIELDTOP >= SAVEBOTTOM ?
BGE.S NOSECT ;YES, NO INTERSECTION
MOVE ShieldLeft(SP),D0 ;GET SHIELD LEFT
CMP (A0),D0 ;IS SHIELDLEFT >= SAVERIGHT ?
BGE.S NOSECT ;YES, NO INTERSECTION
SECT BSR HIDECURSOR ;IT DOES INTERSECT, REMOVE IT
BRA.S DONE ;CONTINUE
NOSECT SUB #1,CRSRSTATE ;MARK AS HIDDEN ONE DEEPER
DONE MOVEM.L (SP)+,D0/A0 ;RESTORE REGISTERS
; UNLK A6
MOVE.L (SP)+,(SP) ;STRIP 8 bytes of PARAMETERS, MOVING
MOVE.L (SP)+,(SP) ;RETURN ADDR UP ON STACK
RTS
;_______________________________________________________________________
;
; 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 8(SP),A0 ;get address of data mask
IF onHcMac THEN
MOVE.L PmgrBase,A1 ;check for the watch cursor <v1.5>
SF watchCrsr(A1)
MOVE.L A0,D0
_StripAddress
CMP.L RAMwatchPtr(A1),D0 ;set flag if so
BEQ.S @5
CMP.L ROMwatchPtr(A1),D0 ;set flag if so
BNE.S @10
@5 ST watchCrsr(A1)
@10
ENDIF
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 ; <23Apr85>
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 ; <23Apr85>
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
; if the cursor changed, force it to be displayed by hiding then showing it
TST D1 ;did it change?
BEQ.S @2 ;skip if it didn't
BSR HideCursor ;hide it
BSR ShowCursor ;then show it again to redraw it
IF onHcMac THEN
_IdleUpdate ;new cursor is activity <v1.8>
ENDIF
@2
MOVE.L (SP)+,A0 ;get return address
ADD #14,SP ;strip parameters
JMP (A0) ;return to caller
;
;_______________________________________________________________________
;
; FUNCTION ScrnAddress:Ptr;
;
; return a pointer to the start of the bit-map display
;
ScrnAddress
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
MOVE.L (SP)+,A1 ;get the return address
MOVE.L (SP)+,A0 ;get pointer to vDots
MOVE ColLines,(A0) ;return the number of vertical pixels <C1/15Apr86>
MOVE.L (SP)+,A0 ;get pointer to hDots
ScrnCmn MOVE RowBits,(A0) ;return the number of horizontal pixels <C1/15Apr86>
JMP (A1) ;return to caller
;_______________________________________________________________________
;
; PROCEDURE ScrnBitMap(VAR x: BitMap);
;
; return the screen bitmap
;
ScrnBitMap
MOVE.L (SP)+,A1 ;get the return address <23Apr85>
MOVE.L (SP)+,A0 ;get pointer to vDots <23Apr85>
MOVE.L ScrnBase,(A0)+ ; <23Apr85>
MOVE.W ScreenRow,(A0)+ ; <23Apr85>
CLR.L (A0)+ ; <23Apr85>
MOVE ColLines,(A0)+ ;number of vertical pixels <C1/15Apr86>
BRA.S ScrnCmn ;share common ending <23Apr85>
; mouse int routines deleted (moved to IntHnd) <23Jul85>
;_______________________________________________________________________
;
; by Dan Venolia
; modified by Steve Horowitz
;
; 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
TST.B CrsrNew ; Mouse changed?
BEQ TrackDone ; No <20> return
TST.B CrsrBusy ; Cursor locked?
BNE TrackDone ; Yes <20> return
;
TST.B CrsrCouple ; Cursor coupled to mouse?
BEQ NoComp ; No <20> skip computation <DSV>
;
MOVE.W MTemp+H,D0 ; Find <20>Mx
SUB.W RawMouse+H,D0
;
MOVE.W MTemp+V,D1 ; Find <20>My
SUB.W RawMouse+V,D1
;
MOVE.W D0,D2 ; x := |<7C>Mx|
BGE.S AbslXl
NEG.W D2
AbslXl
;
MOVE.W D1,D3 ; y := |<7C>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 <20> don<6F>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 <20> 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 <20> Table[i]
;
MULS D2,D3 ; D4 := i*(Mag(<28>M)+Error)
;
MULS D3,D0 ; <20>Cx := (<28>Mx*i*(Mag(<28>M)+Error))/Mag(<28>M)
DIVS D4,D0 ; <<<<<< D3 >>>>>>>
;
MULS D3,D1 ; <20>Cy := (<28>My*i*(Mag(<28>M)+Error))/Mag(<28>M)
DIVS D4,D1 ; <<<<<< D3 >>>>>>>
;
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
BSR.S PinGuts
;
MOVE.L D0,RawMouse ; Update cursor locations
MOVE.L D0,MTemp
;
AND.L MouseMask,D0 ; Do jerky masking to drop low bits
MOVE.L MouseOffset,D1 ; Get the offset
BEQ.S SkipPin ; Skip 2nd pin if not
ADD.L D1,D0 ; Do jerky offset
BSR.S PinGuts ; Pin mouse inside rect again
SkipPin MOVE.L D0,Mouse ; Actual mouse location
;
Repaint TST.B CrsrObscure ; Unpaint the cursor
BNE.S Unpainted
_HideCursor ; Hide the cursor
Unpainted
;
CLR.B CrsrNew ; Cursor is fresh
CLR.B CrsrObscure ; Cursor is not obscured
_ShowCursor ; Repaint the cursor
;
RTS ; Goodbye
;
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 Repaint ; Update the cursor
; --------end of ugly jcrsrcoreTask
; 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 BLT!! <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
END