home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
294.lha
/
Bag_v1.0
/
bag.asm
< prev
next >
Wrap
Assembly Source File
|
1989-10-08
|
7KB
|
243 lines
* --------------------------------------------------------------------- *
* 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