mac-rom/OS/Mouse.a

380 lines
10 KiB
Plaintext
Raw Normal View History

;
; File: Mouse.a
;
; Contains: routines related to the mouse
;
; Written by: Steve Horowitz & Francis Stanbach
;
; Copyright: <09> 1990 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <7> 1/13/91 dba (KIP) add fix for old key repeat bugs in the Macintosh Plus ROM;
; specifically, be sure that KeyThresh and KeyRepThresh do not
; have 0s in them
; <6> 7/10/90 dba Oops! Frank forgot to export MTable and he didn<64>t test it (my
; fault, I was with him at the time).
; <5> 7/10/90 fjs more cleanup related to Darin
; <4> 5/19/90 fjs more cleanup related to Darin
; <3> 5/16/90 dba work on it more (tag-team programming)
; <2> 5/16/90 fjs add more comments for Captain Van Eye Patch
; <1> 5/16/90 fjs Annette sure was cute
; 5/15/90 fjs That's right I'm writing this code
;
; To Do:
;
load 'StandardEqu.d'
include 'LinkedPatchMacros.a'
MGlobals record 0 ; mouse mapping globals data structure
Count ds.w 1 ; word: number of valid error deltas
MaxCnt ds.w 1 ; word: limit on number of error deltas
Err7 ds.w 1 ; word: time-7 error magnitude
Err6 ds.w 1 ; word: time-6 error magnitude
Err5 ds.w 1 ; word: time-5 error magnitude
Err4 ds.w 1 ; word: time-4 error magnitude
Err3 ds.w 1 ; word: time-3 error magnitude
Err2 ds.w 1 ; word: time-2 error magnitude
Err1 ds.w 1 ; word: time-1 error magnitude
Error ds.w 1 ; word: accumulated error
GSize equ * ; size of regular globals
Table ds.b 8 ; mickey bytes table
TotalSize equ * ; size
endr
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; initialize the mouse mapping table
PlusMouseInit InstallProc (Plus)
import MickeyBytesHelper
import MTable
; since the Plus boot code sometimes leaves KeyThresh and KeyRepThresh 0, check for that case.
tst.w KeyRepThresh
bne.s KeyRepThreshOK
move.w #$48*2,KeyRepThresh ; stuff same value used by modern boot code
KeyRepThreshOK
tst.w KeyThresh
bne.s KeyThreshOK
move.w #$1FFF<<2,KeyThresh ; stuff same value used by modern boot code
KeyThreshOK
lea MTable,a2 ; load pointer to table in a2
jmp MickeyBytesHelper
endproc
ADBMouseInit InstallProc (SE,II,Portable,IIci)
import MickeyBytesHelper
move.l MickeyBytes,a2 ; get ptr to globals
add #MGlobals.Table,a2 ; point past globals to table
jmp MickeyBytesHelper
endproc
MickeyBytesHelper proc
; get the value in PRAM
moveq #$78,d0 ; mask off the appropriate bits
and.b SPVolCtl,d0 ; of value from PRAM
lsr.b #3,d0 ; gets resource # to load
; attempt to get the resource from system file
subq #4,sp ; room for ResHandle
move.l #'mcky',-(sp) ; Mickey Mouse Tracking bytes
move.w d0,-(sp) ; gives us our ID
_GetResource
move.l (sp)+,d0 ; get handle into d0
beq.s noBytes ; we didn't get one, use default
move.l d0,a0 ; get handle in a0
move.l (a0),a0 ; source = mickey bytes
bra.s gotMickey ; install the bytes (should this be 'rts' ?)
noBytes
lea default, a0 ; use the default bytes
; make it default to 2 if there is no resource
and.b #87,SPVolCtl ; mask off old setting
ori.b #(2<<3),SPVolCtl ; and OR it in PRAM
gotMickey
move.l (a0)+,(a2)+ ; move the bytes in
move.l (a0),(a2)
rts
default dc.b 4, 10, 15, 255, 255, 255, 255, 255
ENDPROC
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Mouse Mapping code for Mac Plus
ROMs Plus
MakePatch MapCode,jCrsrTask
MouseMapping PROC
EXPORT MapCode
EXPORT MTable
; This signature is so that the Mouse control panel can recognize this lovely CrsrTask.
; It is probably completely unnecessary; at the very least we could do something shorter.
STRING ASIS
Signature dc.b 'Horowitz' ; isn<73>t that special
Globals
; define these as constants instead of storage so that you can give them
; initial values without explicitly initializing them. Is this cheezy or
; genius ? <15may90 fjs>
mCount dc.w 1 ; word: number of valid error deltas
mMaxCnt dc.w 1 ; word: limit on number of error deltas
mErr7 dc.w 0 ; word: time-7 error magnitude
mErr6 dc.w 0 ; word: time-6 error magnitude
mErr5 dc.w 0 ; word: time-5 error magnitude
mErr4 dc.w 0 ; word: time-4 error magnitude
mErr3 dc.w 0 ; word: time-3 error magnitude
mErr2 dc.w 0 ; word: time-2 error magnitude
mErr1 dc.w 0 ; word: time-1 error magnitude
mError dc.w 0 ; word: accumulated error
mTable dc.b 0,0,0,0,0,0,0,0 ; mickey bytes table (some day put default values here?)
with MGlobals
MapCode
tst.b CrsrNew ; Mouse changed?
beq Done ; No <20> return
tst.b CrsrBusy ; Cursor locked?
bne Done ; 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 AbsX
neg.w d2
AbsX
move.w d1,d3 ; y := |<7C>My|
bge.s AbsY
neg.w d3
AbsY
cmp.w d2,d3 ; d3 := magnitude(x,y)
bls.s magdone
exg d2,d3
MagDone
ASR.w #1,d3
add.w d2,d3
; *** BEGIN NEW ***
lea Globals,a0 ; Get my globals
bne.s DoComp ; <03/07/87 EMT>
move.w #1,Count(a0) ; No hits <03/07/87 EMT>
clr.w Error(a0) ; No errors <03/07/87 EMT>
BRA DoPin ; Redraw the cursor <03/07/87 EMT>
DoComp ; <03/07/87 EMT>
moveM.l d4-d5,-(A7) ; Save off registers
move.w Count(a0),d4 ; d4 is the number of samples
cmp.w MaxCnt(a0),d4 ; Is Count less than MaxCnt
bge.s CountOK
add.w #1,Count(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
; *** bra.s E8 ; Count = 8 ***
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
lea MTable,a0 ; address 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
; *** END NEW ***
add.w d0,RawMouse+H ; Update raw mouse location
add.w d1,RawMouse+V
DoPin ; <03/07/87 EMT>
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
; *** BEGIN NEW ***
rts ; Goodbye
Done
lea Globals,a0 ; Get my globals
move.w #1,Count(a0) ; No hits
clr.w Error(a0) ; No errors
rts ; Goodbye
NoComp
lea Globals,a0 ; Get my globals
move.w #1,Count(a0) ; No hits
clr.w Error(a0) ; No errors
bra.s Repaint ; Update the cursor
; *** END NEW ***
; PinGuts limits the point in d0 to the bounding rectangle pointed to by a0.
; use the ROM instead, since it even works better, but only when you are really sure!
; (Darin)
PinGuts
cmp.w Left(a0),d0 ; Check left side
bge.s LeftOK
move.w Left(a0),d0
LeftOK
cmp.w Right(a0),d0 ; Check right side
ble.s RightOK
move.w Right(a0),d0
sub.w #1,d0
RightOK
swap d0 ; Deal with vertical coord
cmp.w Top(a0),d0 ; Check top
bge.s TopOK
move.w Top(a0),d0
TopOK
cmp.w Bottom(a0),d0 ; Check bottom
ble.s BotOK
move.w Bottom(a0),d0
sub.w #1,d0
BotOK
swap d0
rts
endwith
endproc
end