Using resload_Protect#?
Theory
There are various situations thinkable in which it maybe very useful the get
informed when the program which should installed makes accesses to some specific
memory locations. With the resload_Protect#? functions it is possible
to protect certain memory locations from reading and/or writing by the
processor. Protecting means that every access to such a protected area if
performed will create an Access Fault exception which will result in an
appropriate requester by WHDLoad. If you declare a memory area as protected
using a resload_Protect#? function
WHDLoad will modify the affected page descriptors in the MMU translation tree.
Now on every access to the protected page the CPU will create an Access Fault
exception. The exception handler inside WHDLoad will verify the reason for the
exception. If the reason was an access to a protected page but the access does
not match the protected area the access will be emulated, and normal program
execution continues. Otherwise WHDLoad will quit with an appropriate requester.
If the access was an access to the instruction stream (i.e. the cpu attempts to
load code) it will always be emulated, or with other words the resload_Protect#? functions only affects
reading and writing of data. The fact that every access to a protected page
(pagesize is currently $1000) even if the protected area has only a length of 1
byte will create an access fault results in a strong slow down of the execution
speed of the program. Especially if parts of the code are located on the same
page. If the program depends on his execution speed, differences in the
execution are possible. So it maybe possible that some programs will not work
with the protected feature.
Example: checksums over code
If you install a game using WHDLoad you have to patch the original loader
routines in the game in a way that they will use WHDLoad to load the game data.
Some games are performing checksums over certain code areas to detect if the
original code has been modified. This detection routines maybe sometimes hard to
find. But using the resload_Protect#?
functions in WHDLoad nothing is easier than this. All you have to do is to
protect the bytes you changed in the games code from reading. Now every routine
which tries to make a checksum and read your patched code will cause an access
fault. And you will know where the routine is located.
Limitations
You must not protect the memory page where the SSP points to. If you do so, and
an Exception occurs, it will result in a Double Bus Fault because the CPU will
be unable to write the exception stackframe. After a Double Bus Fault only a
reset can be performed to continue execution.
- 68020 + 68851
- this hardware is currently not supported
- 68030
- 3-Byte transfers are not supported and will create a real Access Fault,
such transfers will occure if an longword on an odd address at a page boundary
will be accessed (e.g. "tst.l ($fff)" where the page at $1000 is protected),
because this is invalid on a 68000 you will probably never see something like
this
- locked transfers caused by tas, cas or cas2 are not supported and will
create a real Access Fault, not a problem because locked transfers are anyway
not supported by Amigas hardware
- 68040
- this hardware is currently not supported
- 68060
- misaligned data stream accesses are not supported and will create a real
Access Fault, a misaligned access is an access which spans two pages (and at
least one of both is protected), for example "tst.l ($ffe)" affects the page
$0..$fff and the page $1000..$1fff, this limitation is a real problem and will
make the resload_Protect feature sometimes nearly unuseable, perhaps I will
later try to support this but its difficult
- misaligned instruction stream accesses are not supported and will create a
real Access Fault if both affected pages are protected, most times such a
constellation should be avoidable
- locked transfers caused by tas or cas are not supported and will create a
real Access Fault, not a problem because locked transfers are anyway not
supported by Amigas hardware
- instructions which lie on a protected page (and therefore will be emulated)
and access the supervisor portion of the status register will be executed wrong,
these instructions will always see the trace bit as 1 and the interrupt priority
mask as 7, any modification of the supervisor portion will be without effect
(i.e. the supervisor portion will remain unchanged)
- movem instruction may access a protected area without creating a Access
Fault exception, this is possible because only the first access will be verified
for matching the protected area
- move16 and double precision operations (FPU) are unsupported and will create
a real Access Fault
- a "move (mem),(mem)" with overlapping source and destination address which
generates an Access Fault because Misalignment will be executed wrong, for
example "move.l ($ffc),($ffe)" where page $1000..$1fff is protected and memory
before execution contains ($ffc)=$11112222,($1000)=$33334444, after execution
$1000 contains $11114444 and not $22224444