home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d7xx
/
d725
/
snoopdos.lha
/
SnoopDos
/
src
/
snoopglue.s
< prev
next >
Wrap
Text File
|
1992-09-05
|
7KB
|
261 lines
***************************************************************** :ts=8 *****
*
* SNOOPGLUE.S
*
* Assembly support routines for snoopdos.c
*
* This file contains routines to patch/unpatch dos library to point
* to a C routine, and to call the old routines.
*
* Does some special tricks to patch into dos.library, in such a way
* as to work properly under both 1.3 and 2.0.
*
* Also includes a tiny sprintf function.
*
*****************************************************************************
INCLUDE "exec/types.i"
INCLUDE "exec/libraries.i"
INCLUDE "libraries/dosextens.i"
XDEF _installdospatch
XDEF _uninstalldospatch
XDEF _CallLock
XDEF _CallOpen
XDEF _CallLoadSeg
XDEF _CallExecute
XDEF _CallCurrentDir
XDEF _CallDeleteFile
XDEF _sprintf
XREF _DOSBase
XREF _SysBase
XREF _NewOpen
XREF _NewLock
XREF _NewLoadSeg
XREF _NewExecute
XREF _NewCurrentDir
XREF _NewDeleteFile
XREF _LVOOpen
XREF _LVOLock
XREF _LVOLoadSeg
XREF _LVOExecute
XREF _LVOCurrentDir
XREF _LVODeleteFile
XREF _LVORawDoFmt
CALL MACRO
XREF _LVO\1
JSR _LVO\1(A6)
ENDM
SECTION SnoopDos,CODE
*
* Modify DOS library to call our functions for Open() and Lock();
* We can't just use SetFunction() because DOS library is non-standard.
* Instead of using JMP $123456 type instructions, it uses (mostly)
* MOVEQ #funcnum,D0; BRA.L Dispatch. So, we replace this entire
* sequence with a standard JMP instruction, steal the number from
* the MOVEQ instruction and use it when we want to call the real
* DOS library later on.
*
_installdospatch:
MOVEM.L A0-A3/A6,-(A7) * Save regs
MOVE.L 4,A6 * Get ExecBase
MOVE.L _DOSBase,A0 * Get DOSbase
BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library
SetFunc MACRO
MOVEM.W _LVO\1(A0),A1-A3 * Read in current value for func
MOVEM.W A1-A3,\1Save * Save the appropriate data
MOVEM.W CallOur\1,A1-A3 * Read in replacement code
MOVEM.W A1-A3,_LVO\1(A0) * And modify library
ENDM
SetFunc Open
SetFunc Lock
SetFunc LoadSeg
SetFunc Execute
SetFunc CurrentDir
SetFunc DeleteFile
MOVE.L A0,A1 * Finally,
CALL SumLibrary * Recalculate library checksum
MOVEM.L (A7)+,A0-A3/A6 * Save regs
RTS
*
* Reinstall previous DOS patch. If someone has already altered the
* function, we can't actually exit immediately so return a FALSE
* result. While there is a very small window which could cause
* problems (if someone is in the middle of a SetFunction() when
* this is called), but we'll ignore this mostly.
*
_uninstalldospatch:
MOVEM.L A0-A3/A6,-(A7) * Save regs
MOVE.L 4,A6 * Get sysbase
MOVE.L _DOSBase,A0 * Get DOSBase
TestFunc MACRO
MOVE.L CallOur\1+2,D0 * Get old address of function
CMP.L _LVO\1+2(A0),D0 * See if changed
BNE changed * If it has, exit with no action
ENDM
TestFunc Open
TestFunc Lock
TestFunc LoadSeg
TestFunc Execute
TestFunc CurrentDir
TestFunc DeleteFile
BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library
RestFunc MACRO
MOVEM.W \1Save,A1-A3 * Read in prev. value of vec.
MOVEM.W A1-A3,_LVO\1(A0) * Atomically restore it
ENDM
RestFunc Open
RestFunc Lock
RestFunc LoadSeg
RestFunc Execute
RestFunc CurrentDir
RestFunc DeleteFile
MOVE.L A0,A1 * Finally,
CALL SumLibrary * Update library checksum
MOVEQ #1,D0 * Indicate success
BRA.S unexit * And exit
changed:
MOVEQ #0,D0 * Indicate failure to uninstall
unexit:
MOVEM.L (A7)+,A0-A3/A6 * Restore regs
RTS * And exit with return in D0
*
* This code is the code that gets moved directly into the DOS
* library vectors
*
CallOurOpen: JMP NewOpen
CallOurLock: JMP NewLock
CallOurLoadSeg: JMP NewLoadSeg
CallOurExecute: JMP NewExecute
CallOurCurrentDir: JMP NewCurrentDir
CallOurDeleteFile: JMP NewDeleteFile
*
* These are the replacement DOS routines.
*
NewFunc MACRO
MOVEM.L A2-A6/D2-D7,-(A7) * Save all registers (to be safe)
JSR _New\1 * Call C version with params in D1-D3
MOVEM.L (A7)+,A2-A6/D2-D7 * Restore registers
MOVE.L D0,D1 * Copy return value into D1
* * [some routines expect this :-( ]
RTS * Return to caller, exit value in D0
ENDM
NewOpen: NewFunc Open
NewLock: NewFunc Lock
NewLoadSeg: NewFunc LoadSeg
NewExecute: NewFunc Execute
NewCurrentDir: NewFunc CurrentDir
NewDeleteFile: NewFunc DeleteFile
*
* Allow's C to call the old DOS functions. If we're running Kikstart 2.0
* then just call the original function directly. Otherwise, calculate
* where to go from the code stored in the vector.
*
OldDosCall MACRO
LEA.L \1Save,A0 * Get pointer to func save vector
MOVE.W #_LVO\1,D0 * Get library offset vector
BRA.S CallDos * Skip to execute it
ENDM
_CallOpen: OldDosCall Open
_CallLock: OldDosCall Lock
_CallLoadSeg: OldDosCall LoadSeg
_CallExecute: OldDosCall Execute
_CallCurrentDir: OldDosCall CurrentDir
_CallDeleteFile: OldDosCall DeleteFile
NOP * Stop Lattice messing up final branch
CallDos:
MOVEM.L D1-D3/D6/D7/A6,-(A7) * Save registers
MOVE.W (A0),D6 * Get previous instruction
CMP.W #$4ef9,D6 * Is it a JMP instruction?
BNE dos_exec * If not, then call using special code
MOVE.L 2(A0),A0 * Else it's 2.0 or SetFunction()
MOVE.L _DOSBase,A6 * Put DOSBase into A6 as expected
JSR (A0) * Call original function
BRA.S callexit * And exit
dos_exec:
MOVE.W (A0),D6 * Get MOVEQ instruction
EXT.W D6 * Convert data to word
EXT.L D6 * and then longword
EXG.L D0,D6 * Swap with library vector offset
MOVE.W 4(A0),D7 * Get offset to DOS routine from LVO
MOVE.L _DOSBase,A6 * Get DOSBase
ADD.W D6,D7 * Calculate offset value
JSR 4(A6,D7.W) * Call DOS function dispatcher
callexit:
MOVEM.L (A7)+,D1-D3/D6/D7/A6 * Restore registers
RTS * And return to C caller
*****************************************************************************
*
* Taken straight from the Rom Kernel Manuals (V1.3 ed.)
*
* Simple version of the C sprintf() function. Assumes C-style
* stack-based function conventions.
*
* long eyecount;
* eyecount=2;
* sprintf(string, "%s have %ld eyes.", "Fish", eyecount);
*
* would produce "Fish have 2 eyes." in the string buffer. Note that
* integer arguments must be explicitly given as long, otherwise they
* default to 16 bits.
*
*****************************************************************************
stuffChar:
move.b d0,(a3)+ ; Store data in output string
rts
_sprintf:
movem.l a2-a3/a6,-(sp) ; Save registers
move.l 4*4(sp),a3 ; Get the output string pointer
move.l 5*4(sp),a0 ; Get the FormatString pointer
lea.l 6*4(sp),a1 ; Get the pointer to the DataStream
lea.l stuffChar(pc),a2 ; Get pointer to char stuff routine
move.l _SysBase,a6 ; Get ExecBase
jsr _LVORawDoFmt(a6) ; Format string
movem.l (sp)+,a2-a3/a6 ; Restore registers
rts
*****************************************************************************
*
* Globals used by SnoopDos
*
*****************************************************************************
SECTION SnoopData,DATA
OpenSave DS.W 3
LockSave DS.W 3
LoadSegSave DS.W 3
ExecuteSave DS.W 3
CurrentDirSave DS.W 3
DeleteFileSave DS.W 3
END