home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
commod
/
qmouse27.lha
/
qmouse.s
< prev
Wrap
Text File
|
1993-04-18
|
39KB
|
2,008 lines
;QMouse.s
;Written by Dan Babcock
;This source was assembled with Macro68 release 3.
Macro68 equ 1
DevPac3 equ 2
ASM equ Macro68
IFEQ ASM-Macro68
exeobj
objfile 'c:QMouse'
MC68000
multipass
ENDC
IFEQ ASM-DevPac3
include 'exec/types.i'
include 'exec/exec.i'
include 'dos/dos_lib.i'
include 'dos/dos.i'
include 'dos/dostags.i'
include 'dos/dosextens.i'
include 'intuition/intuition.i'
include 'intuition/intuitionbase.i'
include 'intuition/intuition_lib.i'
include 'graphics/graphics_lib.i'
include 'graphics/layers_lib.i'
include 'graphics/copper.i'
include 'graphics/gfxbase.i'
include 'hardware/custom.i'
include 'hardware/dmabits.i'
include 'hardware/intbits.i'
include 'exec/exec_lib.i'
include 'devices/timer.i'
include 'devices/input.i'
include 'devices/inputevent.i'
include 'devices/trackdisk.i'
ENDC
;Some V39 equates
IFND _LVOSetWindowPointerA
_LVOSetWindowPointerA equ -$330
ENDC
IFND WA_BusyPointer
WA_BusyPointer equ $80000098
ENDC
IFND WA_Pointer
WA_Pointer equ $80000097
ENDC
;End V39 equates
IFND SYS
SYS macro
jsr _LVO\1(a6)
endm
ENDC
IFND _custom
_custom equ $dff000
ENDC
IFND _LVOSystemTagList
_LVOSystemTagList equ -$25E
ENDC
IFND push
push macro
move.l \1,-(sp)
endm
ENDC
IFND pop
pop macro
move.l (sp)+,\1
endm
ENDC
;Set INFO_LEVEL to 1 for full debugging output.
INFO_LEVEL equ 0
;Put a message to the serial port. Used like so:
;
;PUTDEBUG <'Init: called'>
;
;Parameters can be printed out by pushing them on the stack and
;adding the appropriate C printf-style % formatting commands.
PUTDEBUG macro ;<msg>
ifne INFO_LEVEL
movem.l d0-d1/a0-a1,-(sp)
lea .msg\@(pc),a0 ;Point to static format string
lea 16(sp),a1 ;Point to args
bsr KPutFmt
movem.l (sp)+,d0-d1/a0-a1
bra .end\@
.msg\@:
dc.b \1,$a,0
even
.end\@:
endc
endm
MAXQUEUE equ 32
SCREENLISTSIZE equ 32 ;maximum number of screens to keep track of
POINTERLISTSIZE equ 32
HANDLERPRI equ 60 ;priority of input.device handler
TaskPriority equ 21
ShellPriority equ 0
MaxCopperSize equ 500
SysBackground equ $e ;offset into gb_copinit copper list
WindowStart equ $0 ;offset into LOF copper list
DefColor equ $fff ;white
WaitLine equ $16
move.l 4,a6
cmp.w #37,LIB_VERSION(a6)
bhs GoodVersion
;Print an error message - the user doesn't have 2.0
lea DosName(pc),a1
SYS OldOpenLibrary
tst.l d0
beq ErrEnd
move.l d0,a6
SYS Output
move.l d0,d1
moveq #EndSorry-Sorry,d3
lea Sorry(pc),a0
move.l a0,d2
SYS Write
move.l a6,a1
move.l 4,a6
SYS CloseLibrary
ErrEnd: moveq #RETURN_FAIL,d0
rts
dc.b '$VER: QMouse 2.70 (19.4.93)',$a,0
Sorry: dc.b 'Sorry, this program requires Kickstart 2.0!',$a,0
EndSorry:
BadArgs: dc.b 'Bad arguments.',$a,0
even
GoodVersion:
;Allocate global data structure
move.l #Data_Sizeof,d0
move.l #MEMF_CLEAR,d1
SYS AllocMem
tst.l d0
beq ErrEnd
move.l d0,a5
lea GlobalPtr(pc),a0
move.l a5,(a0)
;Allocate chip RAM data.
move.l #CData_Sizeof,d0
move.l #MEMF_CLEAR+MEMF_CHIP,d1
SYS AllocMem
move.l d0,ChipData(a5)
beq CleanUp
;Initialize static data
move.b #HANDLERPRI,InputInterrupt+LN_PRI(a5)
move.l a5,InputInterrupt+IS_DATA(a5)
moveq #1,d0
move.l d0,ClickCount(a5) ;***BUG: WAS A1 (trashing memory)
;THANKS to Chris Schneider for finding
;it!!!!!!!!!!!!!!!!
;Open libraries
lea LibTable(pc),a2
move.l a2,a3
moveq #NumLibs-1,d2
.OLibLoop:
move.w (a2)+,a1
add.l a3,a1
SYS OldOpenLibrary
move.w (a2)+,a0
add.l a5,a0
move.l d0,(a0)
beq CleanUp
dbra d2,.OLibLoop
;Parse command line
lea Template(pc),a0
move.l a0,d1
lea Options(a5),a0
move.l a0,d2
moveq #0,d3 ;no custom rdarg structure
move.l DosBase(a5),a6
SYS ReadArgs
move.l d0,ArgPtr(a5)
bne .ArgsOK
lea BadArgs(pc),a0
move.l a0,d1
SYS VPrintf
bra CleanUp
.ArgsOK:
move.l 4,a6
;Process QUIT option, if selected.
tst.l QuitOption(a5)
beq .SkipQuit
lea ProcName(pc),a1
SYS FindTask
tst.l d0
beq CleanUp
move.l d0,a1
move.l TC_Userdata(a1),a0
move.l QuitSig(a0),d0
SYS Signal ;tell task to quit
bsr CleanUp
bra .Exit
.SkipQuit:
;If already installed, kill the existing process.
lea ProcName(pc),a1
SYS FindTask
tst.l d0
beq .NotInstalled
move.l d0,a1
move.l TC_Userdata(a1),a0
move.l QuitSig(a0),d0
SYS Signal ;tell task to quit
moveq #26,d2
.Kill: subq.l #1,d2
beq .Exit
move.l DosBase(a5),a6
moveq #2,d1
SYS Delay
lea ProcName(pc),a1
move.l 4,a6
SYS FindTask
tst.l d0
bne .Kill
.NotInstalled:
;Get stack for command.
move.l DosBase(a5),a6
SYS Cli
move.l d0,a0
move.l cli_DefaultStack(a0),d0
lsl.l #2,d0
lea CmdStackSize(pc),a0
move.l d0,(a0)
move.l 4,a6
;Copy resident part of code into allocated memory
lea StartAllocCode(pc),a0 ;source
lea ResidentCode(a5),a1 ;destination
move.l #ResidentCodeSize,d0 ;size
SYS CopyMem
SYS CacheClearU ;for 020/030/040
;Start a process
move.l DosBase(a5),a6
lea ResidentCode(a5),a0
lea EntryPoint(pc),a1
move.l a0,(a1)
lea ProcName-StartAllocCode+ResidentCode(a5),a0
lea ProcNamePtr(pc),a1
move.l a0,(a1)
lea NewProcTags(pc),a0
move.l a0,d1
SYS CreateNewProc
;Exit back to CLI
.Exit: moveq #0,d0
rts
***************************************************************************
* The following code is copied into allocated memory. *
***************************************************************************
StartAllocCode:
move.l 4,a6
move.l GlobalPtr(pc),a5
lea IntRoutine(pc),a0
move.l a0,InputInterrupt+IS_CODE(a5)
;Perform relocations.
lea PatchAlert(pc),a1
movem.l 8(a1),d0-d2
add.l a1,d0
add.l a1,d1
add.l a1,d2
movem.l d0-d2,8(a1)
;Initialize damping constant.
move.l AccelOption(a5),d0
beq .NoDamp
move.l d0,a0
move.l (a0),d0
subq.l #1,d0
move.l ThreshOption(a5),d1
beq .DefThresh
move.l d1,a0
move.l (a0),d1
.DefThresh:
addq.l #1,d1
muls.w d0,d1
move.w d1,DampingConstant(a5)
.NoDamp:
;Allocate signals
moveq #NumSigs-1,d2
lea Sigs(a5),a2
.SigLoop: moveq #-1,d0
SYS AllocSignal
tst.l d0
bmi CleanUp
moveq #0,d1
bset d0,d1
move.l d1,(a2)+
dbra d2,.SigLoop
;Initialize semaphore(s)
lea Semaphores(a5),a2
moveq #NumSemaphores-1,d2
.InitSema:
move.l a2,a0
SYS InitSemaphore
lea SS_SIZE(a2),a2
dbra d2,.InitSema
move.l ThisTask(a6),a0
move.l a0,Task(a5)
move.l a5,TC_Userdata(a0)
;Install no-flicker option if selected.
tst.l FlickerOption(a5)
beq .NoFlicker
move.l GraphBase(a5),a0
move.l gb_copinit(a0),a0
move.l a0,OriginalCopInit(a5)
move.l ChipData(a5),a1
lea Copper(a1),a1
move.l a1,a2
move.w #MaxCopperSize/4-1,d0
.CLoop: move.l (a0)+,d1
cmp.l #$008A0000,d1
beq .CopEnd
move.l d1,(a1)+
dbra d0,.CLoop
clr.l FlickerOption(a5)
bra .NoFlicker
.CopEnd: move.l #$01800000,(a1)+
move.l a1,WaitLineAddress(a5)
move.l #$1607FFFE,(a1)+
move.w #$0180,(a1)+
move.l #$008A0000,2(a1)
move.l a1,RealBackground(a5)
move.l a2,cop1lc+_custom
move.l GraphBase(a5),a0
move.l a2,gb_copinit(a0)
cmp.w #color,SysBackground-2(a2)
bne .DefColor
move.w SysBackground(a2),(a1)
bra .NoFlicker
.DefColor:
move.w #DefColor,(a1)
.NoFlicker:
;Patch MANY system routines.
lea PatchTable(pc),a2
move.l a2,a3
.Patch: move.w (a2)+,d0 ;get base
beq .EndPatch
move.l (a5,d0.w),a1 ;library base to patch
move.w (a2)+,d0 ;get minimum library version
cmp.w LIB_VERSION(a1),d0
bls .VersionOK
addq.l #6,a2
bra .Patch
.VersionOK:
move.w (a2)+,d0 ;get offset to new routine
lea (a3,d0.w),a0
move.l a0,d0 ;new routine address
move.w (a2)+,a0 ;_LVO offset
SYS SetFunction
move.w (a2)+,d1
move.l d0,(a5,d1.w)
bra .Patch
.EndPatch:
;Create an IORequest structure
SYS CreateMsgPort
move.l d0,InputMsgPort(a5)
beq CleanUp
move.l d0,a0
moveq #IOSTD_SIZE,d0
SYS CreateIORequest
move.l d0,InputIORequest(a5)
beq CleanUp
;Perform NoClick, if desired.
move.l NoClickOption(a5),d2
beq .Click
move.l d2,a0
move.l (a0),d2
.Click: moveq #0,d3
moveq #3,d4
.ClickLoop:
lea TrackName(pc),a0 ;device name
move.l d3,d0 ;unit number
move.l InputIORequest(a5),a1 ;IO request
moveq #0,d1 ;flags
SYS OpenDevice
tst.l d0
bne .ECLoop
move.l InputIORequest(a5),a1 ;IO request
move.l IO_UNIT(a1),a0
btst d3,d2
beq .SkipNoClick
bset #TDPB_NOCLICK,TDU_PUBFLAGS(a0)
.SkipNoClick:
tst.l VerifyOption(a5)
beq .NoVerify
bset #1,TDU_PUBFLAGS(a0)
.NoVerify:
tst.l NoVerifyOption(a5)
beq .SkipVerify
bclr #1,TDU_PUBFLAGS(a0)
.SkipVerify:
SYS CloseDevice
.ECLoop: addq.l #1,d3
dbra d4,.ClickLoop
;Handle 'STAR' option.
tst.l StarOption(a5)
beq .NoStar
move.l DosBase(a5),a0
move.l dl_Root(a0),a0
bset #0,rn_Flags(a0)
.NoStar:
;Open the input.device
lea InputName(pc),a0 ;device name
moveq #0,d0 ;unit number
move.l InputIORequest(a5),a1 ;IO request
moveq #0,d1 ;flags
SYS OpenDevice
tst.l d0
bne CleanUp
;Install virtical blank routine if needed.
tst.l SunMouseOption(a5)
beq .SkipVBL
moveq #INTB_VERTB,d0
lea VBlankServer(a5),a1
move.l a5,IS_DATA(a1)
lea VBlankRoutine(pc),a0
move.l a0,IS_CODE(a1)
move.b #NT_INTERRUPT,LN_TYPE(a1)
SYS AddIntServer
bset #STB_IntInstalled,Status(a5)
.SkipVBL:
;Install input handler
move.l InputIORequest(a5),a1
move.w #IND_ADDHANDLER,IO_COMMAND(a1)
lea InputInterrupt(a5),a0
move.l a0,IO_DATA(a1)
SYS DoIO
tst.l d0
bne CleanUp
st HandlerInstalled(a5)
;Wait for signal(s)
Wait:
tst.l TaskQueue(a5)
bne .DoTasks
lea Sigs(a5),a0
move.l (a0)+,d0
moveq #NumSigs-2,d1
.. add.l (a0)+,d0
dbra d1,..
move.l 4,a6
SYS Wait
move.l d0,d7
move.l d7,d1
and.l QuitSig(a5),d1
bne SafeCleanUp
move.l d7,d1
and.l FuncSig(a5),d1
beq Wait
.DoTasks: move.l IntBase(a5),a6
lea TaskQueue(a5),a4
.TaskLoop:
move.l (a4),d0
beq Wait
clr.l (a4)+
move.l d0,a0
bsr GetSemaphore
jsr (a0)
bsr FreeSemaphore
bra .TaskLoop
AmigaM:
move.l ib_FirstScreen(a6),d0
beq .End
move.l d0,a0
jmp _LVOScreenToBack(a6)
.End: rts
AmigaN: jmp _LVOWBenchToFront(a6)
CTF: bsr GetWindow
tst.l d0
beq .NoCTF
move.l CTFOption(a5),a2
move.l (a2),d1
cmp.l #1,d1
bhi .MoreThanOne
bra DoWindowToFront
.MoreThanOne:
cmp.l ClickWindow(a5),d0
beq .SameWindow
move.l d0,ClickWindow(a5)
moveq #1,d0
move.l d0,ClickCount(a5)
.Time: move.l ib_Seconds(a6),ClickTime+TV_SECS(a5)
move.l ib_Micros(a6),ClickTime+TV_MICRO(a5)
.NoCTF: rts
.SameWindow:
;Check to see whether MaxClickDelay has been exceeded. If not, increment
;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
;Window under pointer in D0.
push d0
move.l ClickTime+TV_SECS(a5),d0
move.l ClickTime+TV_MICRO(a5),d1
move.l ib_Seconds(a6),d2
move.l ib_Micros(a6),d3
SYS DoubleClick
tst.l d0
beq .TimeExceeded
addq.l #1,ClickCount(a5)
move.l CTFOption(a5),a0
move.l (a0),d0
cmp.l ClickCount(a5),d0
bhi .NeedMoreClicks
clr.l ClickCount(a5)
pop d0
bra DoWindowToFront
.TimeExceeded:
moveq #1,d0
move.l d0,ClickCount(a5)
.NeedMoreClicks:
pop d0
bra .Time
CTB: bsr GetWindow
tst.l d0
beq .FlipScreen
move.l d0,a1
move.l wd_Flags(a1),d2
and.l #WFLG_BACKDROP,d2
bne .FlipScreen
;Is this the only window on this screen, except for backdrop windows?
move.l wd_WScreen(a1),a1
move.l sc_FirstWindow(a1),a1
.BackLoop:
cmp.l a1,d0
beq .EBackLoop
move.l wd_Flags(a1),d2
and.l #WFLG_BACKDROP,d2
beq .FlipWindow
.EBackLoop:
move.l (a1),a1
move.l a1,d2
bne .BackLoop
.FlipScreen:
tst.l d1
beq .End
move.l d1,a0
jmp _LVOScreenToBack(a6)
.FlipWindow:
move.l d0,a0
jmp _LVOWindowToBack(a6)
.End: rts
PopCLI:
;Execute the desired command
move.l a6,-(sp)
move.l DosBase(a5),a6
move.l CmdOption(a5),d1
beq .End
lea .Tags(pc),a0
move.l a0,d2 ;tags
SYS SystemTagList
tst.l NoWBenchToFrontOption(a5)
bne .SkipWBenchToFront
move.l IntBase(a5),a6
SYS WBenchToFront
.SkipWBenchToFront:
.End: move.l (sp)+,a6
rts
.Tags: dc.l SYS_UserShell,0
dc.l NP_Priority,ShellPriority
dc.l NP_StackSize
CmdStackSize:
dc.l 0
dc.l 0 ;end of tag list
SafeCleanUp:
;Make sure the SetFunction'ed vectors are still intact.
lea PatchTable(pc),a0
move.l a0,a2
.Safe: move.w (a0)+,d0
beq CleanUp
move.l (a5,d0.w),a1 ;library base
addq.l #2,a0 ;skip version #
move.w (a0)+,d0
lea (a2,d0.w),a3 ;address of new routine
move.w (a0)+,d0 ;_LVO offset
move.w (a0)+,d1 ;Old vector
tst.l (a5,d1.w)
beq .Safe
cmp.l 2(a1,d0.w),a3
beq .Safe
;A routine has been patched by another program. Alert the user.
move.l IntBase(a5),a6
sub.l a0,a0
lea PatchAlert(pc),a1
sub.l a2,a2
SYS EasyRequestArgs
bra Wait
PatchAlert:
dc.l es_SIZEOF
dc.l 0
dc.l .TitleText-PatchAlert
dc.l .AlertText-PatchAlert
dc.l .OkayText-PatchAlert
.TitleText:
dc.b 'QMouse message',0
.AlertText:
dc.b 'Can''t quit or modify parameters. Another program '
dc.b $a,'has patched the same OS routines!',0
.OkayText:
dc.b 'OK',0
even
CleanUp:
;Enter with global ptr in A5
move.l 4,a6
;Remove interrupt routine, if installed.
btst #STB_IntInstalled,Status(a5)
beq .SkipIntRemove
moveq #INTB_VERTB,d0
lea VBlankServer(a5),a1
SYS RemIntServer
.SkipIntRemove:
;Remove input handler, if installed.
tst.b HandlerInstalled(a5)
beq .SkipHand
move.l InputIORequest(a5),a1
move.w #IND_REMHANDLER,IO_COMMAND(a1)
lea InputInterrupt(a5),a0
move.l a0,IO_DATA(a1)
SYS DoIO
.SkipHand:
tst.l OldCloseScreen(a5)
beq .SkipRestore
bsr RestoreMouse
move.l a5,a1 ;global
move.l a5,a0 ;dummy ("input event")
bsr RestoreScreen
;Restore original vectors.
lea PatchTable(pc),a2
.RestoreVecs:
move.w (a2),d0
beq .SkipRestore
addq.l #6,a2 ;skip new routine info
move.l (a5,d0.w),a1 ;get library base
move.w (a2)+,a0 ;get _LVO
move.w (a2)+,d0
move.l (a5,d0.w),d0 ;old routine
beq .RestoreVecs
SYS SetFunction
bra .RestoreVecs
.SkipRestore:
;Delay for 1/10 second to ensure that no-one is using the patch code.
move.l DosBase(a5),d0
beq .SkipFreeArg
move.l d0,a6
moveq #5,d1
SYS Delay
;Free argument structure
move.l ArgPtr(a5),d1
beq .SkipFreeArg
SYS FreeArgs
.SkipFreeArg:
move.l 4,a6
;Free signals
lea Sigs(a5),a2
moveq #NumSigs-1,d2
.SigLoop: move.l (a2)+,d1
beq .NextSig
moveq #-1,d0
.BitLoop: addq.l #1,d0
btst d0,d1
beq .BitLoop
SYS FreeSignal
.NextSig: dbra d2,.SigLoop
;Remove flicker option, if selected.
tst.l FlickerOption(a5)
beq .SkipFlicker
move.l OriginalCopInit(a5),a0
move.l GraphBase(a5),a2
move.l gb_copinit(a2),a1
.CLoop: move.l (a1)+,(a0)+
cmp.l #$008A0000,(a0)
bne .CLoop
move.l OriginalCopInit(a5),gb_copinit(a2)
move.l OriginalCopInit(a5),cop1lc+_custom
.SkipFlicker:
;Close libraries
lea LibTable+2(pc),a2
moveq #NumLibs-1,d2
.CLibLoop:
move.w (a2),a0
add.l a5,a0
tst.l (a0)
beq .SkipClose
move.l (a0),a1
SYS CloseLibrary
.SkipClose:
addq.l #4,a2
dbra d2,.CLibLoop
;Close input.device
move.l InputIORequest(a5),d0
beq .SkipCloseDev
move.l d0,a1
tst.b IO_ERROR(a1) ;was there an error?
bne .SkipCloseDev ;yes, don't close
SYS CloseDevice
.SkipCloseDev:
;Delete IORequest structure
move.l InputIORequest(a5),a0
SYS DeleteIORequest
move.l InputMsgPort(a5),a0
SYS DeleteMsgPort
;Free chip data.
move.l ChipData(a5),d0
beq .SkipChipData
move.l d0,a1
move.l #CData_Sizeof,d0
SYS FreeMem
.SkipChipData:
;Deallocate global structure. Note that this code is (sometimes) executed
;within the memory that we are freeing, so we are careful to terminate with
;a JMP.
move.l a5,a1
move.l #Data_Sizeof,d0
jmp _LVOFreeMem(a6)
;Semaphore routines
GetSemaphore:
rts
movem.l a0/a6,-(sp)
move.l GlobalPtr(pc),a0
lea MySemaphore(a0),a0
move.l 4,a6
SYS ObtainSemaphore
movem.l (sp)+,a0/a6
rts
FreeSemaphore:
rts
movem.l a0/a6,-(sp)
move.l GlobalPtr(pc),a0
lea MySemaphore(a0),a0
move.l 4,a6
SYS ReleaseSemaphore
movem.l (sp)+,a0/a6
rts
Forbid: move.l a6,-(sp)
move.l 4,a6
SYS Forbid
move.l (sp)+,a6
rts
Permit: move.l a6,-(sp)
move.l 4,a6
SYS Permit
move.l (sp)+,a6
rts
LibTable: dc.w DosName-LibTable
dc.w DosBase
dc.w IntName-LibTable
dc.w IntBase
dc.w LayersName-LibTable
dc.w LayersBase
dc.w GraphName-LibTable
dc.w GraphBase
dc.w UtilityName-LibTable
dc.w UtilityBase
EndLibTable:
NumLibs equ (EndLibTable-LibTable)/4
;****************** SetFunction'ed routines ***************
patch macro
dc.w \1
dc.w \3 ;minimum library version
dc.w New\2-PatchTable
dc.w _LVO\2
dc.w Old\2
endm
PatchTable:
patch IntBase,SetWindowPointerA,39
patch IntBase,OpenWindowTagList,39
patch IntBase,CloseScreen,37
patch IntBase,CloseWorkBench,37
patch IntBase,CloseWindow,37
patch IntBase,OpenScreen,37
patch IntBase,ScreenToFront,37
patch IntBase,ScreenToBack,37
patch IntBase,OpenScreenTagList,37
patch IntBase,WBenchToFront,37
patch IntBase,WBenchToBack,37
patch IntBase,SetPointer,37
patch IntBase,ClearPointer,37
patch IntBase,DisplayBeep,37
patch GraphBase,LoadView,37
dc.w 0
NewDisplayBeep:
move.l GlobalPtr(pc),a1
tst.l BeepOption(a1)
bne .SkipBeep
move.l OldDisplayBeep(a1),-(sp)
.SkipBeep:
rts
NewOpenWindowTagList:
;Enter with NewWindow in A0, taglist in A1
move.l a1,-(sp)
pea .HandlePointer(pc)
subq.l #8,sp
move.l a0,(sp)
move.l GlobalPtr(pc),a0
move.l OldOpenWindowTagList(a0),4(sp)
move.l (sp)+,a0
.End: rts
.RestoreD0:
move.l (sp)+,d0
rts
.HandlePointer:
move.l (sp)+,a1
tst.l d0
beq .End
move.l d0,a0
move.l d0,-(sp)
pea .RestoreD0(pc)
; bra NewSetWindowPointerA
NewSetWindowPointerA:
;Enter with:
;A0 - Window
;A1 - taglist
SaveRegs setrl d4-d5/a0-a6
bsr GetSemaphore
movem.l SaveRegs,-(sp)
move.l GlobalPtr(pc),a5
lea PointerList(a5),a2
;Find if window is already in table and find empty spot.
moveq #POINTERLISTSIZE-1,d4
sub.l a3,a3
.WinSearch:
move.l pt_Window(a2),d5
bne .SkipSave
move.l a2,a3
.SkipSave:
cmp.l d5,a0
beq .Found
lea pt_Sizeof(a2),a2
dbra d4,.WinSearch
move.l a3,a2
move.l a2,d4
beq .CallOld ;no room in table, so forget it
.Found:
;Store the taglist information
move.l a0,a3 ;window
move.l a1,a4 ;taglist
move.l a0,pt_Window(a2)
st TagVersion(a2)
move.l UtilityBase(a5),a6
;Check for WA_BusyPointer.
move.l #WA_BusyPointer,d0
move.l a4,a0
SYS FindTagItem
tst.l d0
beq .NotBusy
move.l d0,a0
IFNE INFO_LEVEL
move.l 4(a0),-(sp)
move.l (a0),-(sp)
PUTDEBUG <'WA_BusyPointer=%lx,%lx '>
addq.l #8,sp
ENDC
move.l (a0),(a2)
move.l 4(a0),4(a2)
beq .NotBusy
clr.l 8(a2)
bra .CallOld
.NotBusy:
;Check for WA_Pointer.
move.l #WA_Pointer,d0
move.l a4,a0
SYS FindTagItem
tst.l d0
beq .Nothing
move.l d0,a0
IFNE INFO_LEVEL
move.l 4(a0),-(sp)
move.l (a0),-(sp)
PUTDEBUG <'WA_Pointer=%lx,%lx '>
addq.l #8,sp
ENDC
move.l (a0),(a2)
move.l 4(a0),4(a2)
clr.l 8(a2)
bra .CallOld
.Nothing:
;Don't understand the taglist.
PUTDEBUG <'Don''t grok SetWindowPointerA taglist!'>
clr.l pt_Window(a2)
.CallOld: cmp.l MBlankWindow(a5),a3
beq .End
;Call old SetWindowPointerA
movem.l (sp)+,SaveRegs
subq.l #8,sp
move.l a0,(sp)
move.l GlobalPtr(pc),a0
move.l OldSetWindowPointerA(a0),4(sp)
move.l (sp)+,a0
bra FreeSemaphore
.End: movem.l (sp)+,SaveRegs
bra FreeSemaphore
NewSetPointer:
bsr GetSemaphore
movem.l d4-d5/a2-a3/a5,-(sp)
move.l GlobalPtr(pc),a5
cmp.l ChipData(a5),a1 ;special check to ward off sneaky code like
beq .End1 ;reqtools
lea PointerList(a5),a2
;Find if window is already in table and find empty spot.
moveq #POINTERLISTSIZE-1,d4
sub.l a3,a3
.WinSearch:
move.l pt_Window(a2),d5
bne .SkipSave
move.l a2,a3
.SkipSave:
cmp.l d5,a0
beq .Found
lea pt_Sizeof(a2),a2
dbra d4,.WinSearch
move.l a3,a2
move.l a2,d4
beq .End ;no room in table, so forget it
.Found: movem.l d0-d3/a0-a1,(a2)
clr.b TagVersion(a2)
.End: cmp.l MBlankWindow(a5),a0
beq .End1
movem.l (sp)+,d4-d5/a2-a3/a5
subq.l #8,sp
move.l a0,(sp)
move.l GlobalPtr(pc),a0
move.l OldSetPointer(a0),4(sp)
move.l (sp)+,a0
bra FreeSemaphore
.End1: movem.l (sp)+,d4-d5/a2-a3/a5
bra FreeSemaphore
NewClearPointer:
bsr GetSemaphore
move.l GlobalPtr(pc),a1
lea PointerList(a1),a1
moveq #POINTERLISTSIZE-1,d0
.ClearLoop:
cmp.l pt_Window(a1),a0
beq .Found
lea pt_Sizeof(a1),a1
dbra d0,.ClearLoop
bra .End
.Found: clr.l pt_Window(a1)
.End: move.l GlobalPtr(pc),a1
cmp.l MBlankWindow(a1),a0
beq .End1
move.l OldClearPointer(a1),-(sp)
.End1: bra FreeSemaphore
NewLoadView:
pea .NewLoad(pc)
move.l GlobalPtr(pc),a0
move.l OldLoadView(a0),-(sp)
rts
.NewLoad:
move.l GlobalPtr(pc),a0
tst.l FlickerOption(a0)
beq .End
move.l RealBackground(a0),a1
move.l GraphBase(a0),a0
move.l gb_copinit(a0),a0
move.w SysBackground(a0),(a1)
.End: rts
NewCloseWorkBench:
bsr GetSemaphore
SYS OpenWorkBench ;get workbench screen ptr in d0
tst.l d0
beq FreeSemaphore
move.l d0,a0
move.l GlobalPtr(pc),a1
move.l OldCloseWorkBench(a1),d1
bset #STB_InCloseWB,Status(a1)
bra CloseScreenCode
NewCloseScreen:
bsr GetSemaphore
move.l GlobalPtr(pc),a1
move.l OldCloseScreen(a1),d1
CloseScreenCode:
;Code shared by NewCloseScreen and NewCloseWorkBench
;Enter with Screen in A0, Global in A1, old vector in D1
;Check for match in ScreenPtr
cmp.l ScreenPtr(a1),a0
bne .NotSP
clr.l ScreenPtr(a1)
.NotSP:
lea ScreenList(a1),a1
moveq #SCREENLISTSIZE-1,d0
.Loop: cmp.l (a1),a0
beq .Match
addq.l #8,a1
dbra d0,.Loop
.End: move.l GlobalPtr(pc),a1
pea .ExtraClose(pc)
move.l d1,-(sp)
rts
.Match: clr.l (a1)
bra .End
.ExtraClose:
move.l GlobalPtr(pc),a0
move.l ib_FirstScreen(a6),CurrentTopScreen(a0)
move.l ib_ActiveScreen(a6),CurrentActiveScreen(a0)
bclr #STB_InCloseWB,Status(a0)
bsr FreeSemaphore
bra RestoreWindow
NewCloseWindow:
move.l GlobalPtr(pc),a1
btst #STB_InCloseWB,Status(a1)
bne .InWB
bsr GetSemaphore
pea .ExtraClose(pc)
bra .Cont
.InWB: pea .ExtraClose1(pc)
.Cont: bsr Forbid
push a0
SYS ClearPointer
pop a0
move.l GlobalPtr(pc),a1
cmp.l MBlankWindow(a1),a0
bne .SkipClear
clr.l MBlankWindow(a1)
.SkipClear:
lea ScreenList+4(a1),a1
moveq #SCREENLISTSIZE-1,d0
.Loop: cmp.l (a1),a0
beq .Match
addq.l #8,a1
dbra d0,.Loop
.End: move.l GlobalPtr(pc),a1
bsr Permit
move.l OldCloseWindow(a1),-(sp)
rts
.Match: clr.l -4(a1)
bra .End
.ExtraClose:
bsr FreeSemaphore
.ExtraClose1:
move.l GlobalPtr(pc),a0
bsr Forbid
move.l ib_ActiveWindow(a6),CurrentActiveWindow(a0)
move.l ib_ActiveScreen(a6),CurrentActiveScreen(a0)
bra Permit
MyRemember:
bsr GetSemaphore
movem.l a0/a2/a4-a5,-(sp)
move.l GlobalPtr(pc),a5
move.l IntBase(a5),a4
bsr Forbid
move.l ib_ActiveScreen(a4),a0
move.l ib_ActiveWindow(a4),a2
bsr Permit
bsr RememberWindow
move.l (a5,d0.w),d0
movem.l (sp)+,a0/a2/a4-a5
move.l d0,-(sp)
bra FreeSemaphore
NewOpenScreen:
move.w #OldOpenScreen,d0
bra MyRemember
NewOpenScreenTagList:
move.w #OldOpenScreenTagList,d0
bra MyRemember
NewWBenchToFront:
move.w #OldWBenchToFront,d0
_MR: bsr MyRemember
bra RestoreWindow
NewWBenchToBack:
move.w #OldWBenchToBack,d0
bra _MR
NewScreenToFront:
move.w #OldScreenToFront,d0
bra _MR
NewScreenToBack:
move.w #OldScreenToBack,d0
bra _MR
;****************** End of SetFunction'ed routines ***************
RememberWindow:
;No OS calls
;Enter with Screen in A0, Window in A2
movem.l d0-d1/a0-a2/a5,-(sp)
move.l GlobalPtr(pc),a5
;Sanity checks
move.l a0,d0
beq .End
move.l a2,d0
beq .End
lea ScreenList(a5),a1
moveq #SCREENLISTSIZE-1,d0
.ScLoop: cmp.l (a1),a0
beq .Match
addq.l #8,a1
dbra d0,.ScLoop
;Screen not found. Add to screen list.
lea ScreenList(a5),a1
moveq #SCREENLISTSIZE-1,d0
.AddLoop: tst.l (a1)
beq .Match
addq.l #8,a1
dbra d0,.AddLoop
bra .End ;table is full
.Match:
move.l a0,(a1)+ ;screen
move.l a2,(a1) ;currently activated window
.End: movem.l (sp)+,d0-d1/a0-a2/a5
rts
RestoreWindow:
movem.l a1-a2,-(sp)
move.l GlobalPtr(pc),a1
lea TaskRestoreWindow(pc),a2
bsr DoFunc
movem.l (sp)+,a1-a2
rts
TaskRestoreWindow:
;This routine restores (re-activates) the previously activated window for
;this screen.
movem.l d0-d2/a0-a2/a6,-(sp)
move.l GlobalPtr(pc),a0
lea ScreenList(a0),a2
move.l IntBase(a0),a6
move.l ib_FirstScreen(a6),d2
beq .End ;sanity check
move.l d2,CurrentTopScreen(a0)
tst.l PubChangeOption(a0)
beq .NoPubChange
;If the screen is public, make it the default public screen.
SYS LockPubScreenList
.PubLoop: tst.l d0
beq .EndPubChange
move.l d0,a0
cmp.l psn_Screen(a0),d2
beq .FoundScreen
move.l LN_SUCC(a0),d0
bra .PubLoop
.FoundScreen:
move.l LN_NAME(a0),a0
SYS SetDefaultPubScreen
.EndPubChange:
SYS UnlockPubScreenList
.NoPubChange:
move.l d2,a0
moveq #SCREENLISTSIZE-1,d0
.Loop: cmp.l (a2),a0
beq .Match
addq.l #8,a2
dbra d0,.Loop
move.l sc_FirstWindow(a0),a0 ;default window
move.l a0,d0
beq .End ;sanity check
bra .SkipMatch
.Match:
move.l 4(a2),a0
.SkipMatch:
SYS ActivateWindow
move.l GlobalPtr(pc),a0
move.l ib_ActiveScreen(a6),CurrentActiveScreen(a0)
.End: movem.l (sp)+,d0-d2/a0-a2/a6
rts
;Get window associated with current mouse position.
;Returns Window in D0 and screen in D1.
GetWindow:
movem.l d4/a0-a1/a4-a6,-(sp)
move.l GlobalPtr(pc),a5
move.l LayersBase(a5),a6
move.l IntBase(a5),a4
move.l ib_FirstScreen(a4),d4
.ScLoop: tst.l d4
beq .ErrEnd
move.l d4,a0
move.l sc_NextScreen(a0),d4
move.w sc_MouseX(a0),d0
bmi .ScLoop
move.w sc_MouseY(a0),d1
bmi .ScLoop
push a0
lea sc_LayerInfo(a0),a0
SYS WhichLayer
pop d1
tst.l d0
beq .End
move.l d0,a0
move.l lr_Window(a0),d0
.End: movem.l (sp)+,d4/a0-a1/a4-a6
rts
.ErrEnd: moveq #0,d0
moveq #0,d1
bra .End
ActivateWindow:
;Activate the window under the mouse pointer.
;Enter with IntuitionBase in A6
movem.l d0-d1/a0-a1,-(sp)
bsr GetWindow
tst.l d0
beq .End
move.l d0,a0
cmp.l ib_ActiveWindow(a6),a0
beq .End
tst.l wd_FirstRequest(a0)
bne .End
SYS ActivateWindow
.End: movem.l (sp)+,d0-d1/a0-a1
rts
DoWindowToFront:
;Perform a WindowToFront on the window in D0.
;Enter with IntuitionBase in A6.
tst.l d0
beq .End1
movem.l d0-d1/a0-a1/a6,-(sp)
move.l d0,a0
move.l wd_WLayer(a0),a1
move.l a1,d0
beq .End
move.l lr_ClipRect(a1),a1
move.l a1,d0
beq .End
tst.l (a1)
beq .End
move.l wd_Flags(a0),d0
and.l #WFLG_BACKDROP,d0
bne .End
SYS WindowToFront
.End: movem.l (sp)+,d0-d1/a0-a1/a6
.End1: rts
BlankMouse:
movem.l d0-d3/a0-a1/a5-a6,-(sp)
move.l GlobalPtr(pc),a5
move.l IntBase(a5),a6
move.l ib_ActiveWindow(a6),d0
beq .End
cmp.l MBlankWindow(a5),d0
beq .End
bsr RestoreMouse
move.l d0,MBlankWindow(a5)
move.l d0,a0
move.l ChipData(a5),a1
; lea ZeroMouse(a1),a1 ;not needed
moveq #1,d0 ;height
moveq #16,d1 ;width
moveq #0,d2 ;xoffset
moveq #0,d3 ;yoffset
pea .End(pc)
move.l OldSetPointer(a5),-(sp)
rts
.End: movem.l (sp)+,d0-d3/a0-a1/a5-a6
rts
RestoreMouse:
movem.l d0-d1/a0-a2/a5-a6,-(sp)
move.l GlobalPtr(pc),a5
move.l IntBase(a5),a6
move.l MBlankWindow(a5),d0
beq .End
;Look for window in pointer table. If present, do a SetPointer or SetWindowPointerA
;to restore the custom pointer. Otherwise call ClearPointer.
move.l d0,a0
clr.l MBlankWindow(a5)
lea PointerList(a5),a1
moveq #POINTERLISTSIZE-1,d0
.WinLoop: cmp.l pt_Window(a1),a0
beq .Found
lea pt_Sizeof(a1),a1
dbra d0,.WinLoop
pea .End(pc)
move.l OldClearPointer(a5),-(sp)
rts
.End: movem.l (sp)+,d0-d1/a0-a2/a5-a6
rts
.Found: move.l a1,a2
tst.b TagVersion(a2)
beq .NoTag
;Call SetWindowPointerA to restore the custom pointer.
move.l pt_Window(a2),a0
pea .End(pc)
move.l OldSetWindowPointerA(a5),-(sp)
rts
.NoTag: movem.l (a2),d0-d3/a0-a1
pea .End(pc)
move.l OldSetPointer(a5),-(sp)
rts
;***************************************************************************
;Start of input handler code
;***************************************************************************
BlankScreen:
;Enter with global in A1.
move.w #DMAF_COPPER+DMAF_RASTER,dmacon+_custom
clr.w color+_custom
bset #STB_SBlanked,Status(a1)
rts
RestoreScreen:
;Enter with global in A1 AND input event in A0.
move.l ie_TimeStamp(a0),ScreenTime(a1)
bclr #STB_SBlanked,Status(a1)
beq .End
move.w #DMAF_SETCLR+DMAF_COPPER+DMAF_RASTER,dmacon+_custom
.End: rts
DoFunc:
;Enter with pointer to routine in A2
;Enter with global ptr in A1.
movem.l d0-d1/a0-a1/a6,-(sp)
lea TaskQueue(a1),a0
moveq #MAXQUEUE-1,d0
.. tst.l (a0)+
dbeq d0,..
bne .End
move.l a2,-4(a0)
move.l FuncSig(a1),d0
move.l Task(a1),a1
move.l 4,a6
SYS Signal
.End: movem.l (sp)+,d0-d1/a0-a1/a6
rts
;**************************** Input handler *********************************
IntRoutine:
movem.l d2/a2/a6,-(sp)
move.l a0,-(sp)
bsr Forbid
move.l IntBase(a1),a6
;Handle NoFlicker option
tst.l FlickerOption(a1)
beq .SkipFlick
move.l GraphBase(a1),a0
move.l gb_LOFlist(a0),a2
move.l WaitLineAddress(a1),a0
cmp.b #WaitLine-1,WindowStart(a2)
blo .DisableNF
move.b #WaitLine,(a0)
bra .SkipDisableNF
.DisableNF:
clr.b (a0)
.SkipDisableNF:
move.l GraphBase(a1),a0
move.l gb_copinit(a0),a0
cmp.w #color,SysBackground-2(a0)
bne .DefColor
move.w SysBackground(a0),d0
move.l RealBackground(a1),a0
move.w d0,(a0)
bra .SkipColor
.DefColor:
move.l RealBackground(a1),a0
move.w #DefColor,(a0)
.SkipColor:
move.l (sp),a0
.SkipFlick:
;Check for change in active screen.
move.l CurrentActiveScreen(a1),d0
cmp.l ib_ActiveScreen(a6),d0
beq .SameActiveScreen
push a0
move.l CurrentActiveScreen(a1),a0
move.l CurrentActiveWindow(a1),a2
bsr RememberWindow
pop a0
.SameActiveScreen:
;Check for change in top screen.
move.l CurrentTopScreen(a1),d0
beq .CSZ
cmp.l ib_FirstScreen(a6),d0
beq .SkipRW
push a0
move.l CurrentActiveScreen(a1),a0
move.l CurrentActiveWindow(a1),a2
bsr RememberWindow
pop a0
lea TaskRestoreWindow(pc),a2
bsr DoFunc
.CSZ: move.l ib_FirstScreen(a6),CurrentTopScreen(a1)
.SkipRW: move.l ib_ActiveWindow(a6),CurrentActiveWindow(a1)
move.l ib_ActiveScreen(a6),CurrentActiveScreen(a1)
;Re-blank mouse if a new window has been activated.
move.l MBlankWindow(a1),d0
beq .Loop
cmp.l ib_ActiveWindow(a6),d0
beq .EndMBW
lea BlankMouse(pc),a2
bsr DoFunc
.EndMBW:
.Loop: cmp.b #IECLASS_TIMER,ie_Class(a0)
beq .Timer
cmp.b #IECLASS_RAWKEY,ie_Class(a0)
bne .NotKey
tst.b ie_Code+1(a0)
bmi .Next ;ignore up key codes
bsr RestoreScreen
;Handle immediate blank feature
tst.l ImmBlankOption(a1)
beq .SkipImmBlank
;Check for lamiga+ramiga
cmp.b #IEQUALIFIER_LCOMMAND+IEQUALIFIER_RCOMMAND,ie_Qualifier+1(a0)
bne .SkipImmBlank
bsr BlankScreen
.SkipImmBlank:
;Perform SunKey
tst.l SunKeyOption(a1)
beq .SkipSKey
lea ActivateWindow(pc),a2
bsr DoFunc
.SkipSKey:
;Do Northgate keyboard mapping.
tst.l NorthGateOption(a1)
beq .SkipNorthgate
lea NorthgateTable(pc),a2
move.w ie_Code(a0),d0
bclr #7,d0
.NorthgateLoop:
move.b (a2),d1
beq .EndNorthgate
addq.l #3,a2
cmp.b d0,d1
bne .NorthgateLoop
and.w #$80,ie_Code(a0)
move.b -2(a2),d0
or.b d0,ie_Code+1(a0)
move.b -1(a2),d0
bmi .EndNorthgate
bset d0,ie_Qualifier+1(a0)
.EndNorthgate:
.SkipNorthgate:
btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
bne .DoLAmiga
;Blank mouse pointer
tst.l MBlankOption(a1)
beq .NoMBlank
lea BlankMouse(pc),a2
bsr DoFunc
.NoMBlank:
bra .Next
.DoLAmiga:
cmp.w #$37,ie_Code(a0) ;'m'?
bne .NotM
;We found an Amiga-M. Defuse and perform action.
clr.b ie_Class(a0)
lea AmigaM(pc),a2
bsr DoFunc
bra .End
.NotM: cmp.w #$36,ie_Code(a0) ;'n'?
bne .NotN
;We found an Amiga-N. Defuse and perform action.
clr.b ie_Class(a0)
lea AmigaN(pc),a2
bsr DoFunc
bra .End
.NotN: tst.l CmdOption(a1)
beq .Next
cmp.w #$45,ie_Code(a0) ;ESC?
bne .Next
clr.b ie_Class(a0)
lea PopCLI(pc),a2
bsr DoFunc
bra .End
.NotKey: bsr RestoreScreen
.Timer: move.w ib_MouseX(a6),d0
move.w ib_MouseY(a6),d1
cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
beq .DoMouse
cmp.w CurrentX(a1),d0
bne .DoMouse
cmp.w CurrentY(a1),d1
beq .Next
.DoMouse:
move.w d0,CurrentX(a1)
move.w d1,CurrentY(a1)
tst.l MBlankOption(a1)
beq .NoRestore
move.l ie_TimeStamp(a0),MouseTime(a1)
lea RestoreMouse(pc),a2
bsr DoFunc
.NoRestore:
;Perform SunMouse
tst.l SunMouseOption(a1)
beq .SkipSunMouse
move.w ie_Qualifier(a0),d0
and.w #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
bne .SkipSunMouse
cmp.w #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
beq .SkipSunMouse
move.l SunMouseDelayOption(a1),a2
move.l a2,d0
beq .SkipLoad
move.l (a2),d0
.SkipLoad:
addq.l #1,d0
move.l d0,SunMouseDelay(a1)
.SkipSunMouse:
;Perform click-to-back.
cmp.w #IECODE_RBUTTON,ie_Code(a0)
bne .NoCTB
move.w ie_Qualifier(a0),d0
btst #IEQUALIFIERB_LEFTBUTTON,d0
beq .DoSunRMB
tst.l CTBOption(a1)
beq .NoCTB
lea CTB(pc),a2
bsr DoFunc
clr.b ie_Class(a0)
bra .Next
.DoSunRMB:
;Perform SunRMB
tst.l SunRMBOption(a1)
beq .SkipSunRMB
lea ActivateWindow(pc),a2
bsr DoFunc
.SkipSunRMB:
.NoCTB:
;Perform click-to-front.
tst.l CTFOption(a1)
beq .NoCTF
cmp.w #IECODE_LBUTTON,ie_Code(a0)
bne .NoCTF
btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
bne .NoCTF ;to avoid interferring with Snap
lea CTF(pc),a2
bsr DoFunc
.NoCTF:
;Perform acceleration.
tst.l AccelOption(a1)
beq .Next
move.l ThreshOption(a1),d0
beq .T1
move.l d0,a2
move.l (a2),d0
.T1: move.w ie_X(a0),d1
bpl .PosX
neg.w d1
.PosX: cmp.w d0,d1
bls .SkipX ;below threshold
move.l AccelOption(a1),a2
move.l (a2),d1
muls.w ie_X(a0),d1
tst.w ie_X(a0)
bpl .SubDampX
add.w DampingConstant(a1),d1
bra .DampX
.SubDampX:
sub.w DampingConstant(a1),d1
.DampX: move.w d1,ie_X(a0)
.SkipX: move.w ie_Y(a0),d1
bpl .PosY
neg.w d1
.PosY: cmp.w d0,d1
bls .EndAccel
move.l AccelOption(a1),a2
move.l (a2),d1
muls.w ie_Y(a0),d1
tst.w ie_Y(a0)
bpl .SubDampY
add.w DampingConstant(a1),d1
bra .DampY
.SubDampY:
sub.w DampingConstant(a1),d1
.DampY: move.w d1,ie_Y(a0)
.EndAccel:
.Next: move.l a0,d1
move.l (a0),d0
move.l d0,a0
bne .Loop
;Check for time-outs (mouse and screen blanking)
move.l d1,a0
tst.l MBlankOption(a1)
beq .NoMTime
tst.l MBlankWindow(a1)
bne .NoMTime
move.l MBlankOption(a1),a0
move.l (a0),d0 ;get value in seconds
move.l d1,a0
move.l ie_TimeStamp(a0),d1
tst.l MouseTime(a1)
beq .InitMBlank
sub.l MouseTime(a1),d1
cmp.l d0,d1 ;TimePassed ? UserSetting
blo .NoMTime
lea BlankMouse(pc),a2
bsr DoFunc
.NoMTime:
tst.l SBlankOption(a1)
beq .End
btst #STB_SBlanked,Status(a1)
bne .End
push a0
move.l SBlankOption(a1),a0
move.l (a0),d0 ;get value in seconds
pop a0
move.l ie_TimeStamp(a0),d1
tst.l ScreenTime(a1)
beq .InitSBlank
sub.l ScreenTime(a1),d1
cmp.l d0,d1 ;TimePassed ? UserSetting
blo .End
bsr BlankScreen
.End: move.l (sp)+,d0
bsr Permit
.EndEnd: movem.l (sp)+,d2/a2/a6
rts
.InitMBlank:
move.l ie_TimeStamp(a0),MouseTime(a1)
bra .NoMTime
.InitSBlank:
move.l ie_TimeStamp(a0),ScreenTime(a1)
bra .End
;Enter with global pointer in A1.
;d0, d1, a0, a1, a5, and a6 are scratch.
;Must always end with a "moveq #0,d0" to set the Z flag.
VBlankRoutine:
tst.l SunMouseDelay(a1)
beq .End
subq.l #1,SunMouseDelay(a1)
bne .End
move.l a2,-(sp)
lea ActivateWindow(pc),a2
bsr DoFunc
move.l (sp)+,a2
.End: moveq #0,d0
rts
GlobalPtr:
dc.l 0
NorthgateTable:
;Assign PageUp/PageDown/Home/End to shift-cursor sequences
dc.b $6b,$4f,IEQUALIFIERB_LSHIFT
dc.b $6c,$4e,IEQUALIFIERB_LSHIFT
dc.b $6d,$4c,IEQUALIFIERB_LSHIFT
dc.b $6e,$4d,IEQUALIFIERB_LSHIFT
;Change a couple keypad key assignments to be more Amiga-like.
dc.b $5c,$5b,0 ;'/' key -> ')' key
dc.b $5d,$5c,0 ;'*' key -> '/' key
dc.b $4a,$5d,0 ;'-' key -> '*' key
dc.b 0
ProcName: dc.b 'QMouse process',0
InputName:
dc.b 'input.device',0
TrackName:
dc.b 'trackdisk.device',0
even
;*************************** Debugging stuff *************************
IFNE INFO_LEVEL
KPutFmt: movem.l a2/a6,-(sp)
move.l 4,a6
lea KPutChar(pc),a2
SYS RawDoFmt
movem.l (sp)+,a2/a6
rts
KPutChar:
;Serial
comment |
move.l a6,-(sp)
move.l 4,a6
SYS RawPutChar
move.l (sp)+,a6
rts
|
;Printer
comment |
move.b #$ff,$bfe301
.Print: btst #0,$bfd000
bne .Print
move.b d0,$bfe101
rts
|
;Memory
movem.l a0-a1,-(sp)
lea MemPtr(pc),a1
move.l (a1),a0
move.b d0,(a0)+
move.l a0,(a1)
movem.l (sp)+,a0-a1
rts
MemPtr: dc.l $300000
ENDC
EndAllocCode: ;end of code copied into allocated memory
;***********************************************************************
NewProcTags:
dc.l NP_Entry
EntryPoint:
dc.l 0
dc.l NP_Name
ProcNamePtr:
dc.l 0
dc.l NP_Cli,-1
dc.l NP_Priority,TaskPriority
dc.l 0 ;end of tags
Template: dc.b 'M=MBLANK/K/N,'
dc.b 'S=SBLANK/K/N,'
dc.b 'N=NOFLICKER/S,'
dc.b 'CMD/K,'
dc.b 'A=ACCELERATION/K/N,'
dc.b 'T=THRESHOLD/K/N,'
dc.b 'CTB=CLICKTOBACK/S,'
dc.b 'CTF=CLICKTOFRONT/K/N,'
dc.b 'SUNMOUSE/S,'
dc.b 'SUNKEY/S,'
dc.b 'SunRMB/S,'
dc.b 'NORTHGATE/S,'
dc.b 'NOBEEP/S,'
dc.b 'NOCLICK/K/N,'
dc.b 'VERIFY/S,'
dc.b 'NOVERIFY/S,'
dc.b 'STAR/S,'
dc.b 'NoWBenchToFront/S,'
dc.b 'PUBCHANGE/S,'
dc.b 'SunMouseDelay/K/N,'
dc.b 'ImmBlank/S,'
dc.b 'QUIT/S',0
IntName: dc.b 'intuition.library',0
GraphName:
dc.b 'graphics.library',0
DosName: dc.b 'dos.library',0
LayersName:
dc.b 'layers.library',0
UtilityName:
dc.b 'utility.library',0
;The ordering here is special: data registers first, then address
;registers, so that MOVEM may be used to save/restore the data.
STRUCTURE pt,0
LONG pt_Height
LONG pt_Width
LONG pt_XOffset
LONG pt_YOffset
LONG pt_Window
LONG pt_Pointer
BYTE TagVersion ;special boolean indicator
BYTE pt_pad
LABEL pt_Sizeof
ResidentCodeSize equ EndAllocCode-StartAllocCode
STRUCTURE Data,0
WORD Nothing ;to make zero special
LABEL Sigs
LONG QuitSig
LONG FuncSig
LABEL EndSigs
LABEL Semaphores
STRUCT MySemaphore,SS_SIZE
LABEL EndSemaphores
LONG Task
LONG InputMsgPort
LONG InputIORequest
STRUCT InputInterrupt,IS_SIZE
LONG IntBase
LONG GraphBase
LONG LayersBase
LONG UtilityBase
STRUCT ScreenList,SCREENLISTSIZE*8
STRUCT PointerList,POINTERLISTSIZE*pt_Sizeof
STRUCT TaskQueue,MAXQUEUE*4+4
LONG OldCloseScreen
LONG OldCloseWorkBench
LONG OldCloseWindow
LONG OldScreenToFront
LONG OldScreenToBack
LONG OldOpenScreen
LONG OldOpenScreenTagList
LONG OldWBenchToFront
LONG OldWBenchToBack
LONG OldLoadView
LONG OldSetPointer
LONG OldSetWindowPointerA
LONG OldClearPointer
LONG OldDisplayBeep
LONG OldOpenWindowTagList
LONG DosBase
LONG ArgPtr
STRUCT ResidentCode,ResidentCodeSize
LONG MouseTime ;timeout for mouse blanking
LONG ScreenTime ;for screen blanking
LONG MBlankWindow
WORD DampingConstant
LONG ClickWindow
STRUCT ClickTime,TV_SIZE
LONG ClickCount
LONG Path
LONG ChipData
LONG RealBackground
LONG OriginalCopInit
LONG ScreenPtr
WORD CurrentX
WORD CurrentY
LONG WaitLineAddress
LONG CurrentTopScreen
LONG CurrentActiveScreen
LONG CurrentActiveWindow
LONG SunMouseDelay
STRUCT VBlankServer,IS_SIZE
LABEL Options
LONG MBlankOption
LONG SBlankOption
LONG FlickerOption
LONG CmdOption
LONG AccelOption
LONG ThreshOption
LONG CTBOption
LONG CTFOption
LONG SunMouseOption
LONG SunKeyOption
LONG SunRMBOption
LONG NorthGateOption
LONG BeepOption
LONG NoClickOption
LONG VerifyOption
LONG NoVerifyOption
LONG StarOption
LONG NoWBenchToFrontOption
LONG PubChangeOption
LONG SunMouseDelayOption
LONG ImmBlankOption
LONG QuitOption
BYTE HandlerInstalled
BYTE Status ;various status bits (defined below)
LABEL Data_Sizeof
;Bit definitions for Status
BITDEF ST,SBlanked,0
BITDEF ST,IntInstalled,1
BITDEF ST,InCloseWB,2
NumSigs equ (EndSigs-Sigs)/4
NumSemaphores equ (EndSemaphores-Semaphores)/SS_SIZE
STRUCTURE CData,0
STRUCT ZeroMouse,12
STRUCT Copper,MaxCopperSize+4*4
LABEL CData_Sizeof
end