sys7.1-doc-wip/QuickDraw/Classic/CrsrCore.a
2019-07-27 22:37:48 +08:00

1132 lines
38 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

;
; File: CrsrCore.a
;
; Contains: xxx put contents here (or delete the whole line) xxx
;
; Written by: Bud Tribble 2-Oct-81
;
; Copyright: © 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.
; <•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…
; <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 “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
;•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…
; 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 ≥ 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 ¬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 ¬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 … 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 … dont 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.Ss 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 >>>>>>>
;
MULS D3,D1 ; ∆Cy := (∆My*i*(Mag(∆M)+Error))/Mag(∆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