; ; 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É ; 10/29/87 rwh Port to Modern Victorian (onMvMac) ; 10/22/87 MSH This file needs nHardwareEqu.a included. ; 9/30/87 MSH Port to HcMac (Laguna) ; 5/26/87 CSL Fixed absolute cursor positioning problem. ; 7/15/86 EHB Save smaller CRSRRECT in ShowCursor (less flicker) ; 7/14/86 EHB Don't draw cursor if CRSRPTR not set up. ; 7/2/86 EHB Include colorequ in great equate purge ; 7/2/86 EHB CLEAR D0 BEFORE CALLING EXTBL ROUTINES. Multiply offset amount ; by depth for left pinning Check 8 longs of cursor ; 6/30/86 EHB New ShowCursor/HideCursor for depth support Fixed branch bug in ; ShieldCursor ; 5/30/86 CSL Added changes for Aladdin, and Aladdin Front desk bus support. ; 5/6/86 RDC Added fixes in ShowCursor routine ; 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 ; 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 ; RDC Added fixes in ShowCursor routine ; CSL Added changes for Aladdin, and Aladdin Front desk bus support. ; EHB New ShowCursor/HideCursor for depth support ; Fixed branch bug in ShieldCursor ; EHB Include colorequ in great equate purge ; 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. ; EHB Save smaller CRSRRECT in ShowCursor (less flicker) ; CSL Fixed absolute cursor positioning problem. ; MSH Port to HcMac (Laguna) ; MSH This file needs nHardwareEqu.a included. ; rwh Port to Modern Victorian (onMvMac) ;_______________________________________________________________________ BLANKS ON STRING ASIS IF CPU ³ 020 THEN ;<1.2> MACHINE MC68020 ; ENDIF LOAD 'StandardEqu.d' INCLUDE 'HardwareEqu.a' INCLUDE 'colorequ.a' ; CRSRCORE PROC EXPORT EXPORT CrsrVBLTask EXPORT ScrnAddress EXPORT ScrnSize EXPORT ScrnBitMap EXPORT InitCrTable EXPORT PinRect WITH PmgrRec ; ; ; 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 ; <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 <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 ; ; ;_______________________________________________________________________ ; ; 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 ; <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 ; <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 <= ? BLE.S @4 MOVE.W ColLines,D4 ; last row on screen 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 <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 ; 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 ; ;_______________________________________________________________________ ; ; 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 SUB.W #16,D0 ; compute max X-coord CMP.W (A0),D0 ; do saved bits wrap around ? BLE.S SECT ;YES, BETTER HIDE CURSOR 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 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 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 MOVE.L (SP)+,A0 ;get pointer to hDots ScrnCmn MOVE RowBits,(A0) ;return the number of horizontal pixels 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 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 ; 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 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 MOVE.W #1,adbCount(A0) ; No hits CLR.W Error(A0) ; No errors BRA DoPin ; Update the cursor 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 >>>>>>> ; 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 ; 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