mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-29 07:29:15 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
192 lines
6.9 KiB
Plaintext
192 lines
6.9 KiB
Plaintext
;
|
|
; File: PatchProtector.a
|
|
;
|
|
; Contains: a patch to SetTrapAddress and GetTrapAddress that ÒprotectsÓ come-from patches
|
|
;
|
|
; Written by: Darin Adler
|
|
;
|
|
; Copyright: © 1990-1991 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <11> 8/28/91 JSM Cleanup header.
|
|
; <10> 4/5/91 gbm dba: Exit via jCacheFlush when setting the trap address. This
|
|
; makes it possible to use copy-back mode on '040's
|
|
; <9> 4/3/91 dba kill the fun
|
|
; <8> 3/25/91 dba VL: get rid of that stupid StripAddress
|
|
; <7> 3/4/91 dba gbm: do a StripAddress for all the 24-bit slobs out there
|
|
; <6> 12/18/90 gbm (dba) Use the noPatchProtector conditional to prevent two patch
|
|
; protectors from getting upset at each other.
|
|
; <5> 12/5/90 dba <gbm> disallow come-from patch headers except from people who
|
|
; use the $CXXX form of SetTrapAddress; also check the address
|
|
; passed to SetTrapAddress for validity, by reading the first long
|
|
; word and looking for the come-from header
|
|
; <4> 8/2/90 dba get rid of the MemTop and odd checks
|
|
; <3> 5/30/90 dba add validation for the old address in GetTrapAddress
|
|
; <2> 5/1/90 dba do nothing to this file, just touch it so that people will get
|
|
; the LinkedPatchLib rebuilt
|
|
; <1> 3/21/90 dba fixed some more bugs and checked in for general use
|
|
; 2/1/90 dba fixed the bug that Ed found
|
|
; 1/30/90 dba revamped, added [GS]etTrapWordAddress
|
|
; 1/25/90 dba added a header
|
|
;
|
|
; To Do:
|
|
; take into account the number of toolbox traps on each machine in [GS]etTrapWordAddress
|
|
;
|
|
; This is a patch to Get/SetTrapAddress that respects come-from patches with a special format.
|
|
;
|
|
; bra.s *+6
|
|
; jmp OldTrapAddress
|
|
;
|
|
; Get and SetTrapAddress will notice patches that begin with this sequence and treat them as
|
|
; Òcome-fromÓ patches. Instead of changing the address of the trap in the trap table, instead
|
|
; they will change the ÒoldÓ address in the last come-from patch in the chain.
|
|
;
|
|
; This patch needs to be installed before any come-from patches are installed. This can be done
|
|
; by linking it first in the first 'lpch' to be loaded.
|
|
;
|
|
; This patch also implements a new variant of [GS]etTrapAddress called [GS]etTrapWordAddress.
|
|
; It takes a whole trap word, and does the right thing, removing the need for N[GS]etTrapAddress.
|
|
;
|
|
|
|
print push,off
|
|
load 'StandardEqu.d'
|
|
include 'LinkedPatchMacros.a'
|
|
print pop
|
|
|
|
; opcodes
|
|
|
|
kBranchOverJMPLOpcode equ $6006
|
|
kJMPLOpcode equ $4EF9
|
|
|
|
kComeFromHeader equ (kBranchOverJMPLOpcode << 16) + kJMPLOpcode
|
|
|
|
; bits in trap numbers and Set/GetTrapAddress opcodes
|
|
|
|
TrapNumber record 0
|
|
toolboxBit equ 11
|
|
endr
|
|
|
|
TrapAddressOpcode record 0
|
|
newBit equ 9
|
|
toolboxBit equ 10
|
|
endr
|
|
|
|
; The following patch has to use $A046 as the trap number instead of _GetTrapAddress.
|
|
; This is because it is installed before these patches modify the behavior of [GS]etTrapAddress
|
|
; to work properly for full trap words. The trap number is thus used as an Òold-styleÓ trap number.
|
|
; $A046 is GetTrapAddress, but $A146 (the value of _GetTrapAddress) is interpreted as $A946.
|
|
|
|
ProtectGetTrap patchproc $A046,(Plus,SE,II,Portable,IIci,noPatchProtector)
|
|
import TrapAddressBits
|
|
export OldGetTrapAddress
|
|
|
|
jsr TrapAddressBits ; set bits in the trap word
|
|
move sr,-(sp) ; would do a MOVE CCR, but it is not available on 68000
|
|
bsr.s OldGetTrapAddress ; call the old GetTrapAddress
|
|
move (sp)+,ccr ; get condition codes back
|
|
bcs.s @done ; come-from patches bypass our trickery
|
|
@next
|
|
cmp.l #kComeFromHeader,(a0) ; does this have the come-from header?
|
|
bne.s @done ; no we are done
|
|
move.l 4(a0),a0 ; go on to the next
|
|
bra.s @next
|
|
@done
|
|
moveq #0,d0 ; must zero the result code again
|
|
rts
|
|
|
|
OldGetTrapAddress
|
|
jmpOld
|
|
|
|
endproc
|
|
|
|
; Since SetTrapAddress looks at the first long word of the previous value of the trapÕs address,
|
|
; it can be dangerous to call SetTrapAddress on some random value. Later, a correct SetTrapAddress
|
|
; might encounter a bus error or address error or some other problem. To avoid this, SetTrapAddress
|
|
; looks at the first long word of the new trap address *before* setting the address in the trap table
|
|
; or come-from chain. This ensures that the bus error will happen right away.
|
|
|
|
ProtectSetTrap patchproc _SetTrapAddress,(Plus,SE,II,Portable,IIci,noPatchProtector)
|
|
import TrapAddressBits
|
|
import OldGetTrapAddress
|
|
|
|
move.l (a0),d2 ; get header of trap, and check for bus errors <5>
|
|
|
|
jsr TrapAddressBits ; set bits in the trap word
|
|
bcs.s OldSetTrapAddress ; come-from patches bypass our trickery
|
|
|
|
cmp.l #kComeFromHeader,d2 ; headers can only be used on come-from patches <5>
|
|
beq.s @illegalHeader ; saw a header, so I must system error <5>
|
|
|
|
movem.l d0-d1/a0,-(sp) ; save trap address, number, and bits
|
|
jsr OldGetTrapAddress ; call the old GetTrapAddress
|
|
move.l #0,a1 ; no come-froms found yet
|
|
@next
|
|
cmp.l #kComeFromHeader,(a0)+ ; does this have the come-from header?
|
|
bne.s @done ; no we are done
|
|
move.l a0,a1 ; remember this address
|
|
move.l (a0),a0 ; go on to the next
|
|
bra.s @next
|
|
@done
|
|
movem.l (sp)+,d0-d1/a0 ; restore trap address, number, and bits
|
|
|
|
cmp.l #0,a1 ; any come-froms found?
|
|
beq.s OldSetTrapAddress ; no, go do the real SetTrapAddress
|
|
move.l a0,(a1) ; set the trap address
|
|
move.l jCacheFlush,-(sp) ; get the cache flush vector <9>
|
|
rts ; call it, and then return to the trap dispatcher <9>
|
|
|
|
@illegalHeader
|
|
move.w #dsBadPatchHeader,d0 ; get error code <5>
|
|
_SysError ; report it to the unsuspecting user <5>
|
|
|
|
OldSetTrapAddress
|
|
jsrOld ; call so we can flush the cache when we return <9>
|
|
move.l jCacheFlush,-(sp) ; get the cache flush vector <9>
|
|
rts ; call it, and then return to the trap dispatcher <9>
|
|
|
|
endproc
|
|
|
|
TrapAddressBits proc
|
|
|
|
; TrapAddressBits
|
|
;
|
|
; In:
|
|
; d0.w trap number
|
|
; d1.w [GS]etTrapAddress trap word
|
|
;
|
|
; Out:
|
|
; d1.w (modified) [GS]etTrapAddress trap word
|
|
; ccr CC if it is not a come-from, CS if it is a come-from
|
|
|
|
btst #TrapAddressOpcode.newBit,d1 ; is this N[GS]etTrapAddress?
|
|
bnz.s @notFullWord ; yes, donÕt handle it
|
|
btst #TrapAddressOpcode.toolboxBit,d1 ; is this normal [GS]etTrapAddress?
|
|
bz.s @notFullWord ; yes, donÕt handle it
|
|
|
|
@fullWord
|
|
; adjust the trap bits
|
|
|
|
bset #TrapAddressOpcode.newBit,d1 ; is this NGetTrapAddress?
|
|
btst #TrapNumber.toolboxBit,d0 ; is the trap a Toolbox trap?
|
|
bnz.s @toolbox ; yes, leave the bit set
|
|
bclr #TrapAddressOpcode.toolboxBit,d1 ; clear bit for OS
|
|
@toolbox
|
|
|
|
cmp.w #$C000,d0 ; is this a come-from trap word?
|
|
blo.s @notComeFrom ; no, it is not
|
|
cmp.w #$D000,d0 ; is it a come-from trap word?
|
|
bhs.s @notComeFrom ; no, it is not
|
|
@comeFrom
|
|
; oooh... carry is set for us, we can return
|
|
rts
|
|
|
|
@notFullWord
|
|
@notComeFrom
|
|
and #$FE,ccr ; clear the carry bit
|
|
rts
|
|
|
|
endproc
|
|
|
|
end
|