home *** CD-ROM | disk | FTP | other *** search
-
- incpath include:
- maclib sm.mac
- macfile macro.i
- macfile snoopy.i
- macfile extern/main
- macfile macros/patch
-
- section main,code
-
- ***********************************************************************************
- ;-------------- this is the patch-function that replaces any original LIBRARY code.
- ;-------------- Note that we have a little recursion-protector here that will
- ;-------------- prevents recursions that occur inside the original vector
- ;-------------- just aslong as the PatchCode() is active
- ;--------------
-
- ;-------------- NOTE: the device patch follows below & is a LOT more complicated
-
-
- xdef Patch_START
- Patch_START dc.b PATCH_IDSTRING ; sphead_Ident
- dc.l 0 ; sphead_Owner
- dc.l 0 ; sphead_OriginalFunction
-
- xdef PatchInfoStruct
- PatchInfoStruct dc.l 0 ; sphead_Info
- push a0
- lea (recursionWord,pc),a0
- tst.w (a0)
- bne.b OriginalCode
- move.w #-1,(a0)
- pop a0
- addq.l #1,(ActiveCalls)
- push a6
- bsr.b SetupReplyMsg1
- push a6
- movea.l (4,sp),a6
- xdef OriginalVector0
- OriginalVector0 jsr $ffff0000
- pop a6
- bsr SendReplyMsg1
- lea (recursionWord,pc),a6
- clr.w (a6)
- pop a6
- subq.l #1,(ActiveCalls)
- rts
-
- OriginalCode pop a0 ; from initial push at line #ß
- xdef OriginalVector1
- OriginalVector1 jsr $ffff000
- rts
-
- ;-------------- HEY DUDES: I know this is a bit messy, but I couldn't think of
- ;-------------- anything better for my purpose. Of course, Snoopy will probably
- ;-------------- miss out one or two calls in "stress situations", but
- ;-------------- "better safe than sorry".....
- recursionWord dc.w 0 ; if bit15 is 0, then no call is currently active
-
- ***********************************************************************************
- ;-------------- sets up the replymsg given by the patch function
- ;--------------
- ;-------------- => d0-d7/a0-a5: Registers before function call
- ;-------------- <= a6: PatchCallMessage structure
- ;-------------- allocate data structure
- SetupReplyMsg1 pushm d0-d7/a0-a5
- movea.l (execBase).w,a6
- move.l (thistask),d0
- cmp.l (ThisTask,a6),d0
- beq .SKIPTHIS
- move.l #smsg_SIZEOF,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALL AllocMem,<(execBase).w>
- move.l d0,a6
- popm d0-d7/a0-a5
-
- ;-------------- fail if NULL; else save all registers
- cmpa.l #0,a6
- beq .FAIL
- SAVEREGS smsg_RegsBeforeCall
- .FAIL rts
- .SKIPTHIS suba.l a6,a6
- popm d0-d7/a0-a5
- rts
-
- ***********************************************************************************
- ;-------------- sends the reply message back
- ;--------------
- ;-------------- => d0-d7/a0-a5: Registers after function call
- ;--------------
- ;-------------- fail if NULL; else save all registers
- SendReplyMsg1 cmpa.l #0,a6
- beq .FAIL
- SAVEREGS smsg_RegsAfterCall
- pushm d0-d7/a0-a5
-
- movea.l (execBase).w,a0
- move.l (ThisTask,a0),(smsg_Task,a6)
- move.l (PatchInfoStruct,pc),(smsg_Info,a6)
- movea.l a6,a5 ; a5 = Data structure
- movea.l a0,a6
-
- ;-------------- setup other message stuff
- move.b #NT_MESSAGE,(LN_TYPE,a5)
- move.w #smsg_SIZEOF,(MN_LENGTH,a5)
- move.w #MSGTYPEF_LIBRARY,(smsg_Type,a5) ; **DO NOT REMOVE**
- move.l #0,(MN_REPLYPORT,a5)
- move.l (myport),a0 ; port
- move.l a5,a1 ; message
- CALL PutMsg
-
- ;-------------- new: handle timeout
- push a6
- movea.l (PatchInfoStruct,pc),a1
- move.l (spatch_Timeout,a1),d1
- beq.b .NOTIMEOUT
- cmpi.l #-1,d1
- beq.b .BREAKOUT
- BRBS.B #31,d1,.NOTIMEOUT ; skip negative timeout values
- CALL Delay,<(dosBase)>
- bra.b .NOTIMEOUT
- .BREAKOUT move.l #SIGBREAKF_CTRL_C,d0
- CALL Wait,<(execBase).w>
- .NOTIMEOUT pop a6
-
- popm d0-d7/a0-a5
- .FAIL rts
-
- xdef Patch_SIZEOF
- Patch_SIZEOF dc.l *-Patch_START
-
- ;-------------- Now the two patches for BeginIO()/AbortIO(); Both patches
- ;-------------- are very small and "minimalistic" (I had a much more complicated
- ;-------------- one in the beginning but it didn't work -> this one does ;-)
-
- xdef BeginIO_Patch
- BeginIO_Patch: dc.b PATCH_IDSTRING ; sphead_Ident
- dc.l 0 ; sphead_Owner
- dc.l 0 ; sphead_OriginalFunction
- dc.l 0 ; sphead_Info (size of memory)
- dc.l 0 ; sphead_DevicePtr
-
- ;-------------- "here we go again with a funky intro": BeginIO gets the
- ;-------------- IOBlock in a1 and a pointer to the device in a6.
- addq.l #1,(ActiveCalls)
- push d4
- move.l (4,sp),d4
- pushm d0-d3/d5-d7/a0-a6
- lea (BeginIO_Patch,pc),a5
- move.w #MSGTYPEF_DEVICE|MSGTYPEF_BEGINIO,d5
- jsr PerformDevicePatch
- popm d0-d3/d5-d7/a0-a6
- pop d4
- subq.l #1,(ActiveCalls)
- xdef BeginIO_Jump
- BeginIO_Jump: jsr $ffff0000 ; proceed with IO call
- rts
- xdef BeginIO_SIZEOF
- BeginIO_SIZEOF dc.l *-BeginIO_Patch
-
- xdef AbortIO_Patch
- AbortIO_Patch: dc.b PATCH_IDSTRING ; sphead_Ident
- dc.l 0 ; sphead_Owner
- dc.l 0 ; sphead_OriginalFunction
- dc.l 0 ; sphead_Info (size of memory)
- dc.l 0 ; sphead_DevicePtr
- addq.l #1,(ActiveCalls)
- push d4
- move.l (4,sp),d4
- pushm d0-d3/d5-d7/a0-a6
- lea (AbortIO_Patch,pc),a5
- move.w #MSGTYPEF_DEVICE,d5
- jsr PerformDevicePatch
- popm d0-d3/d5-d7/a0-a6
- pop d4
- subq.l #1,(ActiveCalls)
- xdef AbortIO_Jump
- AbortIO_Jump: jsr $ffff0000 ; proceed with IO call
- rts
- xdef AbortIO_SIZEOF
- AbortIO_SIZEOF dc.l *-AbortIO_Patch
-
-
- **************************************************************************
- ;-------------- Really perform a device patch (because BeginIO()/AbortIO()
- ;-------------- really are *VERY* similar)
- ;--------------
- ;-------------- => a5: APTR begin_of_patch
- ;-------------- d5: WORD flags
- ;--------------
- ;-------------- Note: This function DOES NOT save any registers, the patches
- ;-------------- above have to take care of this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;--------------
- ENTRY PerformDevicePatch
- move.l a1,d6 ; d6 = pointer to IO block
- move.l #sdmsg_SIZEOF,d7
- add.l (sphead_Info,a5),d7 ; d0 = size of allocated memory
- move.l d7,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALL AllocMem,<(execBase).w>
- tst.l d0
- beq.b PerformDevicePatch_done
- movea.l d0,a4
- move.l d4,(sdmsg_PC,a4)
-
- ;-------------- copy IO block
- move.l (sphead_Info,a5),d0
- subq.w #1,d0
- lea (sdmsg_SIZEOF,a4),a1 ; target
- movea.l d6,a0 ; source
- .COPYMEMORY move.b (a0)+,(a1)+
- dbra d0,.COPYMEMORY
-
- ;-------------- setup other message stuff
- move.b #NT_MESSAGE,(LN_TYPE,a4)
- move.w d7,(MN_LENGTH,a4)
- move.l (sphead_DevicePtr,a5),(sdmsg_DeviceBase,a4)
- move.l (ThisTask,a6),(sdmsg_Task,a4)
- move.w d5,(sdmsg_Type,a4) ; **DO NOT REMOVE**
- move.l #0,(MN_REPLYPORT,a4)
-
- ;-------------- send message and immediately continue processing
- move.l (myport),a0 ; port
- move.l a4,a1 ; message
- CALL PutMsg
- DONE PerformDevicePatch
-
- section memory,bss
-
- ;-------------- *** DO NOT REMOVE THIS ***, its here just to make sure
- ;-------------- SLINK doesn't place the BSS section as the second section
- ;-------------- (DETACHSTARTUPARGS macro (see main.asm) relys on a certain
- ;-------------- section layout which could be scratched somehow)
- ds.w 1
-
- **************************************************************************
- ;--------------
-