home *** CD-ROM | disk | FTP | other *** search
- * --------------------------------------------------------------------- *
- * bag.a -- SetFunction ActivateGadget for more reliable performance.
- * Public Domain Freeware source by Justin V. McCormick. 89-09-26
- * --------------------------------------------------------------------- *
- IFD CAPE
- EXEOBJ
- OPTIMON
- SMALLOBJ
- ENDC
-
- include "exec/types.i"
- include "exec/memory.i"
- include "libraries/dos.i"
- include "libraries/dosextens.i"
-
- * --------------------------------------------------------------------- *
- * Equates
- * --------------------------------------------------------------------- *
- BWDELAY EQU 100000 ; The busy-wait delay constant,
- ; can be tuned for your CPU speed.
-
- * --------------------------------------------------------------------- *
- * Macros
- * --------------------------------------------------------------------- *
- SYS MACRO ; Call a Library function, load A6 conditionally
- IFGT NARG-2
- FAIL !!!
- ENDC
- IFEQ NARG-2
- MOVE.L \2,a6
- ENDC
- JSR _LVO\1(a6)
- ENDM
-
- XLVO MACRO ; Declare a LVO offset from amiga.lib
- XREF _LVO\1
- ENDM
-
- * --------------------------------------------------------------------- *
- * Library offsets
- * --------------------------------------------------------------------- *
- IFD NOTEXECOBJ
- XLVO ActivateGadget
- XLVO AllocMem
- XLVO CloseLibrary
- XLVO CopyMem
- XLVO FindTask
- XLVO Forbid
- XLVO FreeMem
- XLVO GetMsg
- XLVO OpenLibrary
- XLVO Output
- XLVO ReplyMsg
- XLVO SetFunction
- XLVO WaitPort
- XLVO Write
- ELSE
- _LVOActivateGadget EQU -$01ce
- _LVOAllocMem EQU -$00c6
- _LVOCloseLibrary EQU -$019e
- _LVOCopyMem EQU -$0270
- _LVOFindTask EQU -$0126
- _LVOForbid EQU -$0084
- _LVOFreeMem EQU -$00d2
- _LVOGetMsg EQU -$0174
- _LVOOpenLibrary EQU -$0198
- _LVOOutput EQU -$003c
- _LVOReplyMsg EQU -$017a
- _LVOSetFunction EQU -$01a4
- _LVOWaitPort EQU -$0180
- _LVOWrite EQU -$0030
- ENDC
-
- SECTION CODE
- * --------------------------------------------------------------------- *
- * EXECUTION STARTS HERE
- * --------------------------------------------------------------------- *
- launch:
- lea _DT(pc),a4
- movea.l 4,a6
- move.l a6,_SysBase-_DT(a4)
- suba.l a1,a1 ;Find our own task pointer
- SYS FindTask ;d0 = FindTask (0L)
- movea.l d0,a2 ;Save it for later
-
- * Check whether launched from CLI or WBench, handle appropriately
- moveq #0,d7 ;Clear out CLI flag/WBench msg pointer
- tst.l pr_CLI(a2) ;Is there a CLI out there?
- bne.s cliargs ;Yep, no message to wait for...
-
- * Must be from WBench, wait for startup message, keep msg as key for removal
- lea pr_MsgPort(a2),a0
- SYS WaitPort ;Wait for startup message
- lea pr_MsgPort(a2),a0
- SYS GetMsg ;Grab Message, pointer in D0
- move.l d0,d7 ;Save message pointer for ReplyMsg later
-
- cliargs:
- lea _DOSName(pc),a1 ;dos.library string pointer
- moveq #0,d0 ;Take any version of DOS
- SYS OpenLibrary ;OpenLibrary("dos.library", 0L)
- move.l d0,_DOSBase-_DT(a4) ;Save DOSBase
-
- lea _INTUIName(pc),a1 ;intuition.library string pointer
- moveq #33,d0 ;Take any version of Intuition after 1.2
- SYS OpenLibrary ;OpenLibrary("intuition.library", 33L)
- move.l d0,_IntuitionBase-_DT(a4) ;Save IntuitionBase
- beq cleanup2 ;Oops, 1.0 or 1.1 user out there still?
-
- * Print credits
- lea _creditmsg(pc),a0
- move.l a0,d2
- move.l #_creditmsgend-_creditmsg,d3
- jsr writemsg
-
- * See if our function is already installed
- movea.l _IntuitionBase-_DT(a4),a0 ;Grab IntuitionBase
- movea.l _LVOActivateGadget+2(a0),a0 ;Grab vector to current ActivateGadget()
- lea MyActivateGadget(pc),a1 ;Grab address of our function
- moveq #OldFunc-MyActivateGadget,d1 ;Length of our function to compare
- 1$ cmpm.b (a0)+,(a1)+ ;Same code?
- dbne d1,1$ ;Yep, compare next byte
-
- * Install or Remove the vector?
- bne.s installbag ;Not our function, install ours
-
- removebag:
- movea.l _IntuitionBase-_DT(a4),a1 ;Grab IBase
- move.w #_LVOActivateGadget,a0 ;The Vector
- movea.l _LVOActivateGadget+2(a1),a2 ;Grab vector to current ActivateGadget()
- move.l OldFunc-MyActivateGadget(a2),d0 ;The original vector to restore
- SYS SetFunction,_SysBase-_DT(a4) ;SetFunction(IntuitionBase, LVOActivateGadget, oldfunc)
- movea.l d0,a1 ;Move old function pointer to A1
- moveq #MyActivateGadgetEnd-MyActivateGadget,d0 ;Size of function
- SYS FreeMem ;FreeMem(oldfunc, sizeof(oldfunc))
-
- lea _removedmsg(pc),a0
- move.l a0,d2 ;d2 = removed message
- move.l #_removedmsgend-_removedmsg,d3 ;d3 = strlen(msg)
- jsr writemsg
- bra.s cleanup
-
- installbag:
- moveq #0,d1
- moveq #MyActivateGadgetEnd-MyActivateGadget,d0
- SYS AllocMem,_SysBase-_DT(a4) ;AllocMem(sizeof(newfunc), 0L)
- tst.l d0
- beq.s cleanup ;Oops, no memory?
-
- * Copy the replacement function to the newly allocated memory
- movea.l d0,a2 ;Copy mem pointer
- lea MyActivateGadget(pc),a0
- movea.l a2,a1
- move.l #MyActivateGadgetEnd-MyActivateGadget,d0
- SYS CopyMem
-
- * Revector the library, save old function address in replacement block
- movea.l _IntuitionBase-_DT(a4),a1
- move.w #_LVOActivateGadget,a0
- move.l a2,d0
- SYS SetFunction ;SetFunction(IntuitionBase, LVOActivateGadget, newfunc)
- move.l d0,OldFunc-MyActivateGadget(a2) ;Save old ActivateGadget vector
-
- lea _installedmsg(pc),a0
- move.l a0,d2 ;d2 = installed message
- move.l #_installedmsgend-_installedmsg,d3 ;d3 = strlen(msg)
- jsr writemsg
-
- * Cleanup and exit parent segment
- cleanup:
- movea.l _IntuitionBase-_DT(a4),a1
- SYS CloseLibrary,_SysBase-_DT(a4) ;CloseLibrary(IntuitionBase)
-
- cleanup2:
- movea.l _DOSBase-_DT(a4),a1
- SYS CloseLibrary ;CloseLibrary(DOSBase)
-
- tst.l d7 ;Were we called from WBench?
- beq.s exit ;from CLI - don't signal WBench
- SYS Forbid ;Prevent WBench from UnloadSeg'ing
- movea.l d7,a1 ;Grab saved message pointer
- SYS ReplyMsg ;Let WBench task know we're done
-
- exit:
- rts
-
- * --------------------------------------------------------------------- *
- writemsg:
- SYS Output,_DOSBase-_DT(a4) ;Get stdout handle
- move.l d0,d1 ;Is there a console to write to?
- beq.s exit ;Nope, blow it off
- jmp _LVOWrite(a6) ;Write(stdout, msg, strlen(msg))
-
- * --------------------------------------------------------------------- *
- * Calls ActivateGadget() up to five times before giving up.
- * Adjust BWDELAY for time delay between attempts.
- * --------------------------------------------------------------------- *
- XDEF MyActivateGadget
- MyActivateGadget:
- movem.l d2-d3/a2-a3,-(sp) ;Save affected regs
-
- movea.l OldFunc(pc),a3 ;Grab original vector
- movem.l a0-a2,-(sp) ;Push parameters onto stack
-
- moveq #4,d2 ;Try 5 times
- 1$ movem.l (sp),a0-a2
- jsr (a3) ;Call ActivateGadget(gad, win, req)
- ; a0 a1 a2
- tst.w d0 ;Success?
- bne.s 3$ ;Yep, done here!
- move.l #BWDELAY,d3 ;Kill some time
- 2$ subq.l #1,d3
- bgt 2$
- dbf d2,1$ ;Try again
-
- 3$ lea 12(sp),sp ;Pop stack parms a0,a1,a2
-
- movem.l (sp)+,d2-d3/a2-a3 ;Restore affected regs
- rts
- OldFunc:
- dc.l 0 ;Pointer to original function
- MyActivateGadgetEnd:
-
- * --------------------------------------------------------------------- *
- * PC Relative data
- * --------------------------------------------------------------------- *
- _DT:
- _SysBase: dc.l 0
- _DOSBase: dc.l 0
- _IntuitionBase: dc.l 0
- _DOSName: DOSNAME
- _INTUIName: dc.b 'intuition.library',$00
-
- _creditmsg: dc.b 'BAG 1.0 by Justin McCormick - '
- dc.b 'BetterActivateGadget '
- _creditmsgend:
- _installedmsg: dc.b 'Installed',$0a
- _installedmsgend:
- _removedmsg: dc.b 'Removed',$0a
- _removedmsgend:
- * ------------------------------------------------------------------------- *
- END
-