mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
5b0f0cc134
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.
1131 lines
32 KiB
Plaintext
1131 lines
32 KiB
Plaintext
;
|
|
; File: PatchMacros.a
|
|
;
|
|
; Contains: macros for patching
|
|
;
|
|
; Written by: Ed KeyCaps
|
|
;
|
|
; Copyright: © 1989-1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <15> 4/10/92 SAH Fixed the leaFar macro for non 68000 machines by having it do
|
|
; the same thing for all machines.
|
|
; <14> 10/28/91 SAM/KSM Clean up header.
|
|
; <12> 1/30/91 gbm sab, #38: Change the Ôalready including this fileÕ variable to
|
|
; all uppercase (for security reasons)
|
|
; <11> 1/25/91 stb JDR: remove betaStage and finalStage
|
|
; <10> 11/9/90 dba <JSM> add macros for protected come-from patches
|
|
; <9> 7/11/90 gbm stop using temp as a weapon
|
|
; <8> 5/2/90 BBM change default freespace for 6.0 compatibility.
|
|
; <6> 4/11/90 dba change so MakeSysFree is no longer used under 7.0
|
|
; <5> 2/26/90 EMT Added LeaTrap.
|
|
; <4> 1/31/90 csd Added the required $ to the hex constant. (What do you expect
|
|
; for 5:11 am?)
|
|
; <3> 1/31/90 csd In MakeSysFree, mask off the low bit of the amount of space
|
|
; requested so that the MacPlus wonÕt address error in SetAppBase.
|
|
; <2> 12/20/89 dba use betaStage and finalStage instead of Beta and Final
|
|
; <3.1> 11/27/89 dvb Fixed DcBind, and added DcROM
|
|
; <3.0> 8/29/89 EMT Added ACTR in FixRomAddresses to allow for more looping. Removed
|
|
; references to SPLINE_FONT per Sampo and Charlton.
|
|
; <2.9> 8/29/89 dba added OSTrapReturnAddressDepth equate
|
|
; <2.8> 8/15/89 dba NEEDED FOR 6.0.4: added leaFar, jmpFar, jsrFar, setTrapA0,
|
|
; getTrapA0, setTrap, setTrapFar, getTrap, getTrapFar,
|
|
; stuffOldTrap, and stuffOldTrapFar macros and made InstToolTp,
|
|
; InstOSTp, PatchOSJump, and PatchToolJump macros use them;
|
|
; changed leaROM so that destination can be non-address register
|
|
; <2.7> 8/7/89 EMT Per PKE, force SEEK_ALLOWED to be false on all final builds FOR
|
|
; 6.0.4.
|
|
; <2.6> 8/3/89 EMT Roll in some of the more urgent code review changes FOR 6.0.4:
|
|
; Added USE_MAKESYSFREE conditional in the same vein as
|
|
; SEEK_ALLOWED Fixed PtchInstall to correctly fail with SysError.
|
|
; Removed meaningless comments.
|
|
; <2.5> 8/2/89 CEL When building a beta system the seek function can not be used
|
|
; due to a conditional. The conditional warns a user - which is
|
|
; good. But a ROM may not be final which makes it impossible to
|
|
; build a system that works on those machines. The SEEK_ALLOWED
|
|
; variable was added that allows one to use the seek option if
|
|
; this flag is set. So the naive persons will be warned and the
|
|
; daring still can make systems that work on moving targets!!!
|
|
; <2.4> 6/28/89 EMT Only use MakeSysFree stuff for spline fonts. Otherwise, use 1.0
|
|
; version with 32-bit clean fixes (1.9, 2.2)
|
|
; <2.3> 6/12/89 EMT Cleaned up source code including 2.2 fixes.
|
|
; <2.2> 6/12/89 BAL Fixed bugs in 1.9 which caused the system heap to be huge and
|
|
; init31 to fail.
|
|
; <2.1> 6/10/89 CEL Took out old Macro labelsÉ
|
|
; <2.0> 6/2/89 CEL ifdefed the old labels out of patchmacs
|
|
; <1.9> 6/1/89 EMT StripAddress before executing 'ptch's.
|
|
; <1.8> 5/31/89 EMT Added DcBind macro for Dave and Earsh.
|
|
; <1.7> 5/24/89 EMT Fixed "robust" Bind macros. Thanks Carl.
|
|
; <1.6> 5/23/89 CCH Backed out BIND macros that refused to be robust. This version
|
|
; same as 1.4.
|
|
; <1.5> 5/23/89 EMT Rewrote Bind macros to be more robust.
|
|
; <1.4> 5/12/89 EMT Shortened names for Bind macros. Old ones still work. Removed
|
|
; MaxSymbols, MaxReferences, and SysDifferent.
|
|
; <¥1.3> 5/3/89 CEL Added seek capability in addition to hard offset binding, and
|
|
; merged macros from each PTCH file into here, so there is only
|
|
; one source for all the macros.
|
|
; <1.2> 4/12/89 EMT 'HardwareEqu.a' doesn't work due to scope, removed ROMStart
|
|
; reference.
|
|
; <1.1> 4/12/89 EMT Included 'HardwareEqu.a' for ROMStart equate.
|
|
; <1.0> 4/7/89 EMT New today.
|
|
;
|
|
|
|
IF &TYPE('__INCLUDINGPATCHMACROS__') = 'UNDEFINED' THEN
|
|
__INCLUDINGPATCHMACROS__ SET 1
|
|
|
|
IF &TYPE('__INCLUDINGFSEQU__') = 'UNDEFINED' THEN
|
|
INCLUDE 'FSEqu.a'
|
|
ENDIF
|
|
|
|
; conditionals for this file
|
|
|
|
IF (&TYPE('SEEK_ALLOWED') = 'UNDEFINED') OR (StageInt = finalStage) THEN
|
|
SEEK_ALLOWED: EQU (StageInt < betaStage)
|
|
ENDIF
|
|
|
|
IF (&TYPE('USE_MAKESYSFREE') = 'UNDEFINED') THEN
|
|
USE_MAKESYSFREE: EQU 0
|
|
ENDIF
|
|
|
|
; ROM versions
|
|
|
|
MacPlus EQU $0075
|
|
MacSE EQU $0276
|
|
MacII EQU $0178
|
|
Esprit EQU $037A
|
|
Aurora EQU $067C
|
|
|
|
; useful equates for patching
|
|
|
|
OSTrapReturnAddressDepth equ $1C
|
|
|
|
;
|
|
; MACRO leaFar &label,®ister
|
|
;
|
|
; This does an LEA that can reach farther than 32K.
|
|
;
|
|
; <SAH> Removed check for Machine other than 68000 as the macro generated
|
|
; a normal pc relative with 16 bit offset lea for these machines. All
|
|
; machines now use the 68000 version which does a real leaFar.
|
|
|
|
MACRO
|
|
leaFar &label,®ister
|
|
@local: lea (&label-@local).L,®ister
|
|
lea @local(pc,®ister..L),®ister
|
|
ENDM
|
|
|
|
;
|
|
; MACRO jmpFar &label,®ister
|
|
;
|
|
; This does an JMP that can reach farther than 32K.
|
|
;
|
|
|
|
MACRO
|
|
jmpFar &label,&scratch
|
|
IF &SETTING('MACHINE') = 'MC68000' THEN
|
|
@local: lea (&label-@local).L,&scratch
|
|
jmp @local(pc,&scratch..L)
|
|
ELSE
|
|
bra.L &label
|
|
ENDIF
|
|
ENDM
|
|
|
|
;
|
|
; MACRO jsrFar &label,®ister
|
|
;
|
|
; This does an JSR that can reach farther than 32K.
|
|
;
|
|
|
|
MACRO
|
|
jsrFar &label,&scratch
|
|
IF &SETTING('MACHINE') = 'MC68000' THEN
|
|
@local: lea (&label-@local).L,&scratch
|
|
jsr @local(pc,&scratch..L)
|
|
ELSE
|
|
bsr.L &label
|
|
ENDIF
|
|
ENDM
|
|
|
|
;
|
|
; MACRO BackToTrap &JumpLabel
|
|
;
|
|
; Insert an absolute JMP instruction, initially to the ROM reset vector, to be
|
|
; patched at installation time to the previous address from the trap table.
|
|
; the &JumpLabel provided refers to the 4-byte address to be backpatched.
|
|
;
|
|
MACRO
|
|
BackToTrap &JumpLabel
|
|
EXPORT &JumpLabel
|
|
JMP (0).L
|
|
&JumpLabel EQU *-4
|
|
ENDM
|
|
|
|
;
|
|
; MACRO JsrTrap &JumpLabel
|
|
;
|
|
; Insert an absolute JSR instruction, initially to the ROM reset vector, to be
|
|
; patched at installation time to the previous address from the trap table.
|
|
; the &JumpLabel provided refers to the 4-byte address to be backpatched.
|
|
;
|
|
MACRO
|
|
JsrTrap &JumpLabel
|
|
EXPORT &JumpLabel
|
|
JSR (0).L
|
|
&JumpLabel EQU *-4
|
|
ENDM
|
|
|
|
;
|
|
; MACRO LeaTrap &JumpLabel
|
|
;
|
|
; Insert an absolute LEA instruction, initially to the ROM reset vector, to be
|
|
; patched at installation time to the previous address from the trap table.
|
|
; the &JumpLabel provided refers to the 4-byte address to be backpatched.
|
|
;
|
|
MACRO
|
|
LeaTrap &JumpLabel, &Reg
|
|
EXPORT &JumpLabel
|
|
LEA (0).L, &Reg
|
|
&JumpLabel EQU *-4
|
|
ENDM
|
|
|
|
;
|
|
; MACRO setTrapA0 &trapNumber
|
|
;
|
|
; Install the patch pointed to by A0 as trap &trapNumber.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
;
|
|
|
|
MACRO
|
|
setTrapA0 &trapNumber
|
|
LCLA &realTrapNumber
|
|
&realTrapNumber: SETA &EVAL(&trapNumber)
|
|
IF (&realTrapNumber AND $800) = 0 THEN ; it is an OS trap
|
|
&realTrapNumber: SETA &realTrapNumber AND $FF
|
|
IF &realTrapNumber < 128 THEN
|
|
moveq #&realTrapNumber,d0 ; move trap number (sometimes sign extended)
|
|
ELSE
|
|
moveq #&realTrapNumber-$100,d0 ; move trap number (sometimes sign extended)
|
|
ENDIF
|
|
_SetTrapAddress newOS
|
|
ELSE
|
|
&realTrapNumber: SETA &realTrapNumber AND $3FF
|
|
IF &realTrapNumber < 128 THEN
|
|
moveq #&realTrapNumber,d0 ; move trap number
|
|
ELSE
|
|
move.w #&realTrapNumber,d0 ; move trap number
|
|
ENDIF
|
|
_SetTrapAddress newTool
|
|
ENDIF
|
|
ENDM
|
|
|
|
;
|
|
; MACRO getTrapA0 &trapNumber
|
|
;
|
|
; Get the current address of trap &trapNumber into A0.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
;
|
|
|
|
MACRO
|
|
getTrapA0 &trapNumber
|
|
LCLA &realTrapNumber
|
|
&realTrapNumber: SETA &EVAL(&trapNumber)
|
|
IF (&realTrapNumber AND $800) = 0 THEN ; it is an OS trap
|
|
&realTrapNumber: SETA &realTrapNumber AND $FF
|
|
IF &realTrapNumber < 128 THEN
|
|
moveq #&realTrapNumber,d0 ; move trap number (sometimes sign extended)
|
|
ELSE
|
|
moveq #&realTrapNumber-$100,d0 ; move trap number (sometimes sign extended)
|
|
ENDIF
|
|
_GetTrapAddress newOS
|
|
ELSE
|
|
&realTrapNumber: SETA &realTrapNumber AND $3FF
|
|
IF &realTrapNumber < 128 THEN
|
|
moveq #&realTrapNumber,d0 ; move trap number
|
|
ELSE
|
|
move.w #&realTrapNumber,d0 ; move trap number
|
|
ENDIF
|
|
_GetTrapAddress newTool
|
|
ENDIF
|
|
ENDM
|
|
|
|
;
|
|
; MACRO setTrap &patchLabel,&trapNumber
|
|
;
|
|
; Install the patch at &patchLabel as trap &trapNumber.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
; As a special case, bypass IMPORTing absolute addresses written in hex with a leading '$'.
|
|
;
|
|
|
|
MACRO
|
|
setTrap &patchLabel,&trapNumber
|
|
IF &patchLabel[1] <> '$' THEN
|
|
IMPORT &patchLabel
|
|
ENDIF
|
|
lea &patchLabel,a0
|
|
setTrapA0 &trapNumber
|
|
ENDM
|
|
|
|
;
|
|
; MACRO setTrapFar &patchLabel,&trapNumber
|
|
;
|
|
; Install the patch at &patchLabel (which can be far away) as trap &trapNumber.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
; As a special case, bypass IMPORTing absolute addresses written in hex with a leading '$'.
|
|
;
|
|
|
|
MACRO
|
|
setTrapFar &patchLabel,&trapNumber
|
|
IF &patchLabel[1] <> '$' THEN
|
|
IMPORT &patchLabel
|
|
ENDIF
|
|
leaFar &patchLabel,a0
|
|
setTrapA0 &trapNumber
|
|
ENDM
|
|
|
|
;
|
|
; MACRO stuffOldTrap &jumpLabel,&trapNumber
|
|
;
|
|
; Stuff the current address of trap &trapNumber at &jumpLabel,
|
|
; usually the effective address of a JMP instruction terminating a patch.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
;
|
|
|
|
MACRO
|
|
stuffOldTrap &jumpLabel,&trapNumber
|
|
getTrapA0 &trapNumber
|
|
IMPORT &jumpLabel
|
|
lea &jumpLabel,a1
|
|
move.l a0,(a1)
|
|
ENDM
|
|
|
|
;
|
|
; MACRO stuffOldTrapFar &jumpLabel,&trapNumber
|
|
;
|
|
; Stuff the current address of trap &trapNumber at &jumpLabel (which can be far away),
|
|
; usually the effective address of a JMP instruction terminating a patch.
|
|
; This handles OS traps and Toolbox traps by checking the toolbox bit.
|
|
;
|
|
|
|
MACRO
|
|
stuffOldTrapFar &jumpLabel,&trapNumber
|
|
getTrapA0 &trapNumber
|
|
IMPORT &jumpLabel
|
|
leaFar &jumpLabel,a1
|
|
move.l a0,(a1)
|
|
ENDM
|
|
|
|
;
|
|
; MACRO InstOSTp &PatchLabel, &TrapNumber
|
|
;
|
|
; Install the patch at &PatchLabel as OS trap &TrapNumber. As a special case,
|
|
; bypass the IMPORTing of absolute addresses (presumably written in hex with a
|
|
; leading $) passed as &PatchLabel.
|
|
;
|
|
|
|
MACRO
|
|
InstOSTp &PatchLabel,&TrapNumber
|
|
setTrap &patchLabel,(&trapNumber AND $FF)
|
|
ENDM
|
|
|
|
;
|
|
; MACRO InstToolTp &PatchLabel, &TrapNumber
|
|
;
|
|
; Install the patch at &PatchLabel as Toolbox trap &TrapNumber. As a special case,
|
|
; bypass the IMPORTing of absolute addresses (presumably written in hex with a
|
|
; leading $) passed as &PatchLabel.
|
|
;
|
|
|
|
MACRO
|
|
InstToolTp &PatchLabel,&TrapNumber
|
|
setTrap &patchLabel,($800 OR (&trapNumber AND $3FF))
|
|
ENDM
|
|
|
|
;
|
|
; This is a macro that sets up the arguments for a vanilla Toolbox trap patch
|
|
; rom76Fix had a setfractenable with a number and not a routine
|
|
; The normal InstToolTp does not work
|
|
;
|
|
MACRO
|
|
InstToolTpNum
|
|
LCLC &trapid
|
|
&trapid SETC &Syslst[1]
|
|
IF (&trapid[1] <> '$') THEN
|
|
IMPORT &Syslst[1]
|
|
ENDIF
|
|
LEA &Syslst[1],A0
|
|
MOVE.w #&Syslst[2],D0
|
|
DC.W ($A647)
|
|
ENDM
|
|
|
|
;
|
|
; MACRO PatchOSJump &JumpLabel,&TrapNumber
|
|
;
|
|
; Stuff the current trap address of OS trap &TrapNumber into the longword at
|
|
; &JumpLabel, presumably a JMP instruction terminating a patch.
|
|
;
|
|
|
|
MACRO
|
|
PatchOSJump &JumpLabel,&TrapNumber
|
|
stuffOldTrap &jumpLabel,(&trapNumber AND $FF)
|
|
ENDM
|
|
|
|
;
|
|
; MACRO PatchToolJump &JumpLabel,&TrapNumber
|
|
;
|
|
; Stuff the current trap address of Tool trap &TrapNumber into the longword at
|
|
; &JumpLabel, presumably a JMP instruction terminating a patch.
|
|
;
|
|
|
|
MACRO
|
|
PatchToolJump &JumpLabel,&TrapNumber
|
|
stuffOldTrap &jumpLabel,($800 OR (&trapNumber AND $3FF))
|
|
ENDM
|
|
|
|
;_________________________________________________________________________________
|
|
; DcRom, JmpRom, JsrRom, PeaRom, LeaRom, CmpRA
|
|
;
|
|
; These macros are used to build a run-time symbol table for patching multiple
|
|
; ROMs.
|
|
;_________________________________________________________________________________
|
|
|
|
; A/UX Patching macros - JmpROM, JsrROM, CmpRA. <PB302>
|
|
; The ROM addresses in the instructions produced by these macros are offset by
|
|
; the actual ROM address (determined from ROMBase) at patch install time.
|
|
; Each location to be offset gets a label of the form RXXXnnn, with nnn
|
|
; being 000, 001, 002, 003, ...
|
|
; &RomFixIndex is a count of the number of locations to be fixed (and the next
|
|
; value of nnn to be used).
|
|
; The RXXXnnn labels are used to build a table of fixup locations; see FixupTbl at
|
|
; the end of this file.
|
|
;
|
|
gbla &RomFixIndex
|
|
&RomFixIndex seta 0
|
|
|
|
;
|
|
; MACRO DcRom &RomOffset <dvb>
|
|
;
|
|
; Define a longword which is a ROM address.
|
|
|
|
MACRO
|
|
DcRom &RomOffset
|
|
gbla &RomFixIndex
|
|
entry RXXX&I2S(&ROMFIXINDEX,-3)
|
|
DC.L (&RomOffset)
|
|
RXXX&I2S(&ROMFIXINDEX,-3) equ *-4
|
|
&RomFixIndex seta &RomFixIndex+1
|
|
ENDM
|
|
|
|
;
|
|
; MACRO JmpRom &RomOffset <PB302>
|
|
;
|
|
; Jump into the ROM.
|
|
|
|
MACRO
|
|
JmpRom &RomOffset
|
|
;jmp ([ROMBase],&RomOffset)
|
|
gbla &RomFixIndex
|
|
entry RXXX&I2S(&ROMFIXINDEX,-3)
|
|
jmp (&RomOffset).L ; <PB330>
|
|
RXXX&I2S(&ROMFIXINDEX,-3) equ *-4
|
|
&RomFixIndex seta &RomFixIndex+1
|
|
ENDM
|
|
|
|
;
|
|
; MACRO JsrRom &RomOffset <PB302>
|
|
;
|
|
; JSR Into the ROM
|
|
;
|
|
MACRO
|
|
JsrRom &RomOffset
|
|
gbla &RomFixIndex
|
|
entry RXXX&I2S(&ROMFIXINDEX,-3)
|
|
jsr (&RomOffset).L ; <PB330>
|
|
RXXX&I2S(&ROMFIXINDEX,-3) equ *-4
|
|
&RomFixIndex seta &RomFixIndex+1
|
|
ENDM
|
|
|
|
;
|
|
; MACRO CmpRA &RomOffset, &Effective_Address <PB302>
|
|
;
|
|
MACRO
|
|
CmpRA &RomOffset, &EffAddr
|
|
gbla &RomFixIndex
|
|
entry RXXX&I2S(&ROMFIXINDEX,-3)
|
|
RXXX&I2S(&ROMFIXINDEX,-3) equ *+2
|
|
cmp.l #&RomOffset, &EffAddr
|
|
&RomFixIndex seta &RomFixIndex+1
|
|
ENDM
|
|
|
|
;
|
|
; MACRO PeaRom &RomOffset <PB319>
|
|
;
|
|
; Pea ROM address
|
|
;
|
|
MACRO
|
|
PeaRom &RomOffset
|
|
gbla &RomFixIndex
|
|
entry RXXX&I2S(&ROMFIXINDEX,-3)
|
|
pea &RomOffset
|
|
RXXX&I2S(&ROMFIXINDEX,-3) equ *-4
|
|
&RomFixIndex seta &RomFixIndex+1
|
|
ENDM
|
|
|
|
;
|
|
; MACRO leaROM &ROMOffset,®ister
|
|
;
|
|
; LEA into the ROM
|
|
;
|
|
|
|
MACRO
|
|
leaRom &ROMOffset,®ister
|
|
GBLA &ROMFixIndex
|
|
ENTRY RXXX&I2S(&ROMFixIndex,-3)
|
|
IF &SUBSTR(&TYPE(®ister),1,5) = 'REG A' THEN
|
|
lea &ROMOffset,®ister
|
|
ELSE
|
|
move.l #&ROMOffset,®ister
|
|
ENDIF
|
|
RXXX&I2S(&ROMFixIndex,-3): equ *-4
|
|
&ROMFixIndex: seta &ROMFixIndex+1
|
|
ENDM
|
|
|
|
;_________________________________________________________________________________
|
|
; RomVersions, Bind, JmpBind, JsrBind, PeaBind, LeaBind, CmpBind, DcBind, FixRomAddresses
|
|
;
|
|
; These macros are used to build a run-time symbol table for patching multiple
|
|
; ROMs.
|
|
;_________________________________________________________________________________
|
|
|
|
;
|
|
; MACRO RomVersions &RomVersion1, RomVersion2, É
|
|
;
|
|
; Identify the ROM version numbers a paticular patch file calls.
|
|
; Allocates the symbol lists.
|
|
;
|
|
MACRO
|
|
RomVersions
|
|
GBLA &NumSymbols
|
|
&NumSymbols SETA 0
|
|
GBLA &NumReferences
|
|
&NumReferences SETA 0
|
|
GBLA &NumVersions
|
|
&NumVersions SETA &NBR(&SYSLIST)
|
|
GBLC &RomVersion[&NumVersions]
|
|
LCLA &i
|
|
&i SETA 1
|
|
|
|
WHILE &i <= &NumVersions DO
|
|
&RomVersion[&i] SETC &SYSLIST[&i]
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
ENDM
|
|
|
|
;
|
|
; MACRO &Symbol Bind (&RomVersion1, &RomOffset1), (&RomVersion2, SEEK, &TrapNum, &Pattern1, &Pattern2, É), É
|
|
;
|
|
; Binds offsets to symbols based upon their RomVersion. &RomOffset is an offset from ROMBase,
|
|
; however, if it has memory manager bits set, an absolute must be used. These are not first class
|
|
; symbols; they only have meaning when used in these macros.
|
|
;
|
|
MACRO
|
|
&Symbol Bind
|
|
GBLA &NumSymbols
|
|
&NumSymbols SETA &NumSymbols + 1
|
|
Bind_&Symbol EQU &NumSymbols
|
|
LCLA &i, &j
|
|
&i SETA 1
|
|
|
|
WHILE &i <= &NBR(&SYSLIST) DO
|
|
IF &SYSLIST[&i,2] = 'SEEK' THEN ;test for SEEK
|
|
|
|
IF SEEK_ALLOWED THEN
|
|
RomSymTab_&SYSLIST[&i,1]_&NumSymbols EQU 0
|
|
Trap_&SYSLIST[&i,1]_&NumSymbols EQU &SYSLIST[&i,3]
|
|
NumPats_&SYSLIST[&i,1]_&NumSymbols EQU &NBR(&SYSLIST[&i]) - 3
|
|
&j SETA 1
|
|
WHILE &j <= (&NBR(&SYSLIST[&i]) - 3) DO
|
|
PatTab_&SYSLIST[&i,1]_&NumSymbols._&j EQU &SYSLIST[&i,&j+3]
|
|
&j SETA &j + 1
|
|
ENDWHILE
|
|
ELSE
|
|
! Seek not permitted on beta and final software!
|
|
ENDIF ;SEEK_ALLOWED
|
|
ELSE ;Not a SEEK
|
|
RomSymTab_&SYSLIST[&i,1]_&NumSymbols EQU &SYSLIST[&i,2]
|
|
ENDIF
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
ENDM
|
|
|
|
;
|
|
; MACRO JmpBind &Symbol
|
|
;
|
|
; JMP through a Bind symbol.
|
|
;
|
|
MACRO
|
|
JmpBind &Symbol
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences EQU *+2
|
|
JMP (Bind_&Symbol).L
|
|
ENDM
|
|
|
|
;
|
|
; MACRO JsrBind &Symbol
|
|
;
|
|
; JSR through a Bind symbol.
|
|
;
|
|
MACRO
|
|
JsrBind &Symbol
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences EQU *+2
|
|
JSR (Bind_&Symbol).L
|
|
ENDM
|
|
|
|
;
|
|
; MACRO PeaBind &Symbol
|
|
;
|
|
; PEA a Bind symbol.
|
|
;
|
|
MACRO
|
|
PeaBind &Symbol
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences EQU *+2
|
|
PEA (Bind_&Symbol).L
|
|
ENDM
|
|
|
|
;
|
|
; MACRO LeaBind &Symbol, &Reg
|
|
;
|
|
; LEA a Bind symbol into a register.
|
|
;
|
|
MACRO
|
|
LeaBind &Symbol, &Reg
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences EQU *+2
|
|
LEA (Bind_&Symbol).L, &Reg
|
|
ENDM
|
|
|
|
;
|
|
; MACRO CmpBind &Symbol, &EA
|
|
;
|
|
; CMP a Bind symbol to an effective address.
|
|
;
|
|
MACRO
|
|
CmpBind &Symbol, &EA
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences EQU *+2
|
|
CMP.L #Bind_&Symbol, &EA
|
|
ENDM
|
|
|
|
;
|
|
; MACRO DcBind &Symbol
|
|
;
|
|
; Make a constant based upon a Bind symbol
|
|
;
|
|
MACRO
|
|
DcBind &Symbol
|
|
GBLA &NumReferences
|
|
&NumReferences SETA &NumReferences + 1
|
|
ENTRY RomRefTab_&NumReferences
|
|
RomRefTab_&NumReferences
|
|
DC.L Bind_&Symbol
|
|
ENDM
|
|
|
|
;
|
|
; MACRO FixRomAddresses
|
|
;
|
|
; Fixes the references in the patch file. Should be first thing executed by
|
|
; the patch and should live in the cut-back portion of the code. Also includes
|
|
; the assembler instructions to build the tables.
|
|
;
|
|
; This macro destroys A0-A4/D0-D3.
|
|
;
|
|
; The format of the tables are as follows:
|
|
; # of Symbols (word)
|
|
; # of Rom Versions (word)
|
|
; Rom Version Table
|
|
; Rom ID (word)
|
|
; Offset to Symbol Table (word)
|
|
; 1 per Rom Version
|
|
; Symbol Table
|
|
; Offset from ROMBase (long), 0 if a SEEK (to be replaced at runtime)
|
|
; Seek Table
|
|
; Reference ID (long)
|
|
; Trap # (word)
|
|
; # of longs to search (word)
|
|
; search pattern (n longs)
|
|
; 0.L at the end of each seek table
|
|
; Reference Table
|
|
; Offset to reference (long)
|
|
; 0.L
|
|
;
|
|
; After retreiving the correct address, it may be altered as follows to ensure it
|
|
; works correctly under A/UX.
|
|
; Addressing High Byte in Instruction Action
|
|
; 24 bit NZ Do not alter the address in the instruction.
|
|
; Used with CMPRA to a ROM Resource.
|
|
; 32 bit NZ Mask out 12 high bits from the address
|
|
; in the instruction, leaving a ROM offset
|
|
; Then add in ROMBase.
|
|
; either Zero Normal Case. Add ROMBase to the address
|
|
; in the instruction.
|
|
;
|
|
MACRO
|
|
FixRomAddresses
|
|
ACTR 10000 ; Allow for lots 'o looping <3.0>
|
|
; First, find the correct symbol and seek tables for the machine.
|
|
LEA RomTableStart, A2 ; Beginning of tables in A2
|
|
MOVE.L A2, A1 ; Copy to A1
|
|
MOVE.W (A1)+, D0 ; Number of symbols in D0
|
|
ASL.W #2, D0 ; * 4 for number of bytes
|
|
MOVE.W (A1)+, D1 ; Number of versions in D1
|
|
MOVE.L ROMBase, A0 ; ROMBase in A0
|
|
MOVE.W 8(A0), D2 ; Rom version number in D2
|
|
BRA.S @VersDBRA
|
|
|
|
@NextVersion
|
|
CMP.W (A1)+, D2 ; Is this it?
|
|
BEQ.S @FoundVersion ; Yes!
|
|
ADDQ.L #2, A1 ; Nope, go to next one.
|
|
@VersDBRA DBRA D1, @NextVersion
|
|
|
|
; Damn! Didn't find it.
|
|
CLR.L ResumeProc ; disable the resume button.
|
|
MOVEQ.L #dsBadPatch, D0
|
|
_SysError
|
|
|
|
@FoundVersion
|
|
MOVE.L A0, D3 ; ROMBase in D3
|
|
MOVE.W (A1)+, D1 ; Get the symbol table offset
|
|
LEA (A2, D1.W), A1 ; Symbol table starts at A1
|
|
|
|
IF SEEK_ALLOWED THEN
|
|
LEA (A1, D0.W), A2 ; Seek table starts at A2
|
|
|
|
@NextSeek
|
|
; Use seek table to patch symbol table.
|
|
MOVE.L (A2)+, D2 ; Symbol ID in D2
|
|
ASL.L #2, D2 ; * 4 for number of bytes
|
|
BEQ.S @DoneSeek ; If 0, we're done.
|
|
MOVE.W (A2)+, D0 ; Get trap number
|
|
CMP.W #$A800, D0 ; OS or TB trap?
|
|
BLO.S @OSTrap ; < $A800 is OS - use GetTrapWordAddress when available
|
|
_GetTrapAddress newTool
|
|
BRA.S @GotTrap
|
|
@OSTrap _GetTrapAddress newOS
|
|
@GotTrap
|
|
CMP.L A0, D3 ; Make sure we're looking at ROM.
|
|
BLO.S @InROM ; If ROMBase < the address, we're cool.
|
|
_Debugger
|
|
|
|
@InROM
|
|
MOVE.W (A2)+, D4 ; Get # of longs in D4
|
|
BEQ.S @GotMatch ; If 0, we got it already!
|
|
|
|
@NextMatch
|
|
MOVE.L (A2), D0 ; Get first pattern
|
|
@FirstMatch
|
|
; Try to match the first 4 byte pattern. Assume that the pattern is word aligned,
|
|
; since SEEK is used for matching instruction sequences.
|
|
ADDQ.L #2, A0 ; Next word, please.
|
|
CMP.L (A0), D0 ; Does first pattern match?
|
|
BNE.S @FirstMatch ; Nope, look for next one.
|
|
|
|
MOVE.W D4, D0 ; Get # of longs
|
|
SUBQ.W #1, D0 ; Subtract 1 because we've found first pattern
|
|
LEA 4(A0), A3 ; A3 is ROM without first long
|
|
LEA 4(A2), A4 ; A4 is search pattern without first long
|
|
BRA.S @LongDBRA
|
|
|
|
@NextLong
|
|
CMP.L (A3)+, (A4)+ ; Same?
|
|
BNE.S @NextMatch ; No, gotta start fresh.
|
|
@LongDBRA DBRA D0, @NextLong ; Seen enough?
|
|
|
|
@GotMatch
|
|
SUB.L D3, A0 ; Turn A0 into a ROMBase offset
|
|
MOVE.L A0, -4(A1, D2.L) ; Put it in the symbol table
|
|
ASL.W #2, D4 ; Convert # of longs to bytes
|
|
LEA (A2, D4.W), A2 ; Go to next entry in seek table
|
|
BRA.S @NextSeek
|
|
|
|
@DoneSeek
|
|
ENDIF ;SEEK_ALLOWED
|
|
|
|
MOVEQ.L #-1, D0
|
|
_StripAddress ; D0 is negative with 32 bit memory manager.
|
|
LEA RefTableStart, A0 ; Reference table in A0
|
|
|
|
@NextReference
|
|
MOVE.L (A0)+, D2 ; Offset in D2
|
|
BEQ RomTableEnd ; All done.
|
|
LEA RomTableStart(PC, D2.L), A2 ; Address of code to patch in A2
|
|
MOVE.L (A2), D1 ; Symbol ID in D1
|
|
ASL.L #2, D1 ; * 4 for number of bytes
|
|
MOVE.L -4(A1, D1.L), D1 ; Offset from ROMBase in D1
|
|
CMP.L #$00FFFFFF, D1 ; High bits set?
|
|
BLS.S @AddIt ; No, normal case
|
|
TST.L D0 ; 32 bit mode?
|
|
BPL.S @CopyReference ; No, don't touch!
|
|
AND.L #$000FFFFF, D1 ; Yes, clear high 12 bits.
|
|
@AddIt
|
|
ADD.L D3, D1 ; Add in ROMBase
|
|
@CopyReference
|
|
MOVE.L D1, (A2) ; Put it in the code.
|
|
BRA.S @NextReference
|
|
|
|
; Build the table.
|
|
ALIGN 4
|
|
RomTableStart
|
|
GBLA &NumSymbols
|
|
NumSymbols DC.W &NumSymbols
|
|
GBLA &NumVersions
|
|
NumVersions DC.W &NumVersions
|
|
GBLC &RomVersion[*]
|
|
LCLA &i, &j, &k
|
|
VersTableStart
|
|
&i SETA 1
|
|
WHILE &i <= &NumVersions DO
|
|
DC.W &RomVersion[&i]
|
|
DC.W SymTableStart_&i - RomTableStart
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
|
|
&i SETA 1
|
|
WHILE &i <= &NumVersions DO
|
|
SymTableStart_&i
|
|
&j SETA 1
|
|
WHILE &j <= &NumSymbols DO
|
|
DC.L RomSymTab_&RomVersion[&i]_&j
|
|
&j SETA &j + 1
|
|
ENDWHILE
|
|
|
|
IF SEEK_ALLOWED THEN
|
|
SeekTableStart_&i
|
|
&j SETA 1
|
|
WHILE &j <= &NumSymbols DO
|
|
PatchMacros$temp SET RomSymTab_&RomVersion[&i]_&j ; Stupid assembler!
|
|
IF PatchMacros$temp = 0 THEN
|
|
DC.L &j
|
|
DC.W Trap_&RomVersion[&i]_&j
|
|
DC.W NumPats_&RomVersion[&i]_&j
|
|
&k SETA 1
|
|
PatchMacros$temp SET NumPats_&RomVersion[&i]_&j ; Stupid assembler!
|
|
WHILE &k <= PatchMacros$temp DO
|
|
DC.L PatTab_&RomVersion[&i]_&j._&k
|
|
&k SETA &k + 1
|
|
ENDWHILE
|
|
ENDIF
|
|
&j SETA &j + 1
|
|
ENDWHILE
|
|
DC.L 0
|
|
ENDIF ;SEEK_ALLOWED
|
|
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
|
|
RefTableStart
|
|
GBLA &NumReferences
|
|
&i SETA 1
|
|
WHILE &i <= &NumReferences DO
|
|
DC.L RomRefTab_&i - RomTableStart
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
|
|
DC.L 0
|
|
RomTableEnd
|
|
ENDM
|
|
|
|
;_________________________________________________________________________________
|
|
; EntryTable, PtchInst
|
|
;
|
|
; These macros are used in conjunction with 'ptch' resources.
|
|
;_________________________________________________________________________________
|
|
|
|
;
|
|
; MACRO EntryTable &entryPt, &trapID
|
|
;
|
|
; Placed at the end of a 'ptch' file, this macro specifies a patch to be
|
|
; applied by the macro which reads and executed the 'ptch'.
|
|
;
|
|
Macro
|
|
EntryTable &entryPt, &trapID
|
|
If (&entryPt <> '0') Then
|
|
Import &entryPt
|
|
Import Start
|
|
DC.L &entryPt-Start
|
|
DC.W &trapID
|
|
Else
|
|
DC.L 0
|
|
EndIf
|
|
EndM
|
|
|
|
;
|
|
; MACRO PtchInst &selector
|
|
;
|
|
; Placed at the appropriate point, this macro calls the ptchInstall routine,
|
|
; which loads and executes the given 'ptch' resource.
|
|
;
|
|
Macro ; PMAB308 24Nov87 RWW
|
|
PtchInst &selector
|
|
MoveQ #&Eval(&selector),D0
|
|
Import ptchInstall
|
|
Bsr ptchInstall
|
|
EndM
|
|
|
|
;
|
|
; MACRO UsesPtchInst
|
|
;
|
|
; Placed in the cutback section of a patch, this macro includes the code
|
|
; required by the PtchInst macro.
|
|
;
|
|
Macro
|
|
UsesPtchInst
|
|
|
|
IF USE_MAKESYSFREE THEN
|
|
ptchInstall Proc Export
|
|
|
|
MinSysExtra EQU 16*1024 ; Add in Extra space for system <2.3-4april89-CEL>
|
|
|
|
SubQ #4,SP ; room for result <2.3-4april89-CEL>
|
|
Move.L #'ptch',-(SP) ; signature of loadable patch resource <2.3-4april89-CEL>
|
|
Move.W D0,-(SP) ; pass along given ID <2.3-4april89-CEL>
|
|
SF -(SP) ; just get a handle before sizing... <2.3-4april89-CEL>
|
|
_SetResLoad ; <2.3-4april89-CEL>
|
|
_GetResource ; get the resource handle <2.3-4april89-CEL>
|
|
MOVE.L (SP)+,D4 ; save the resource handle <2.3-4april89-CEL>
|
|
BEQ.S @xit ; we didn't get it, so just go on <2.3-4april89-CEL>
|
|
CLR.L -(SP) ; slot for resource size <2.3-4april89-CEL>
|
|
MOVE.L D4,-(SP) ; saved handle <2.3-4april89-CEL>
|
|
_SizeRsrc ; (SP) := patch res size <2.3-4april89-CEL>
|
|
MOVE.L (SP)+,D3 ; prime input to heap sizer <2.3-4april89-CEL>
|
|
ADD.L #MinSysExtra,D3 ; handy value <2.3-4april89-CEL>
|
|
BSR MakeSysFree ; get D3 contiguous bytes in sys heap <2.3-4april89-CEL>
|
|
ST -(SP) ; just get a handle before sizing... <2.3-4april89-CEL>
|
|
_SetResLoad ; <2.3-4april89-CEL>
|
|
MOVE.L D4,-(SP) ; saved handle <2.3-4april89-CEL>
|
|
_LoadResource ; get it in this time <2.3-4april89-CEL>
|
|
|
|
MOVE.L D4,-(SP) ; saved handle <2.3-4april89-CEL>
|
|
Move.L D4,-(SP) ; make a copy of the handle <2.3>
|
|
_DetachResource
|
|
; Uh, should we lock it down too, in case somebody goofs up?
|
|
|
|
Move.L (SP),A0 ; fetch handle (and keep copy on stack)
|
|
Move.L (A0),D0 ; point at head of resource <1.9>
|
|
_StripAddress ; strip it <1.9>
|
|
Move.L D0,-(SP) ; save it on the stack <2.3>
|
|
Move.L D0,A0 ; put it into A0 <1.9>
|
|
Jsr (A0) ; go execute init code
|
|
|
|
; on return, A0 should hold cutback address
|
|
Move.L A0,D1 ; save cutback address
|
|
Move.L A0,A1 ; and make an index copy
|
|
|
|
Move.L (SP)+,D2 ; get previously stripped pointer <2.3>
|
|
|
|
@3 Move.L (A1)+,D0 ; get address
|
|
Beq.S @1 ; if it's zero, we be done
|
|
|
|
Add.L D2,D0 ; add base to get real address
|
|
Move.L D0,A0 ; move to A0 for SetTrapAddress
|
|
Move.W (A1)+,D0 ; get trap number
|
|
|
|
Cmp.W #$A800,D0 ; OS or TB trap?
|
|
Bcs.S @2 ; < $A800 is OS
|
|
|
|
_SetTrapAddress newTool
|
|
Bra.S @3
|
|
|
|
@2 _SetTrapAddress newOS
|
|
Bra.S @3
|
|
|
|
@1 Move.L D1,D0 ; cutback address
|
|
Sub.L D2,D0 ; cutback - resource start = new size
|
|
Move.L (SP)+,A0 ; fetch handle, for the last time
|
|
_SetHandleSize
|
|
|
|
Bra.S @done ; <PMAB335>
|
|
|
|
@xit clr.l ResumeProc ; disable the resume button. <PMAB442>
|
|
MoveQ.L #dsBadPatch, D0 ; <PMAB335>
|
|
_SysError ; <PMAB335>
|
|
|
|
@done Rts ; <PMAB335>
|
|
|
|
*********************************************************************** ;<2.3-4april89-CEL>
|
|
* PROCEDURE MakeSysFree
|
|
* Guarantee a contiguous block of free space in the sys heap.
|
|
* To avoid purging everything, we use a loop based on _CompactMem.
|
|
* Growing the zone depends on whether there is a distinct appl zone,
|
|
* as is the case with Plus and SE and in which case we use the
|
|
* traditional _SetApplBase, or whether sys and appl are coincident,
|
|
* as is the case with II and in which case we just allocate a handle
|
|
* and immediately release it. In the worst case, the loop should be
|
|
* executed twice. At this early stage, we donÕt init the appl zone,
|
|
* just set its base. The initializations of InitApplZone are for later.
|
|
* Input:
|
|
* d3 = requested space
|
|
* Trashes:
|
|
* d0-d2/a0-a1
|
|
*********************************************************************** ;<2.3-4april89-CEL>
|
|
MakeSysFree ; new routine
|
|
move.l d3,d0 ; amount needed
|
|
_CompactMem SYS ; look for it in sys zone
|
|
sub.l d3,d0 ; gotten - needed
|
|
bge.s @loopEnd ; gotten ³ needed --> done
|
|
|
|
andi.w #$FFFE, d0 ; make sure itÕs even for MacPlus ;<3><4> csd
|
|
|
|
movea.l SysZone,a0 ; start of sys zone
|
|
cmpa.l ApplZone,a0 ; are they coincident?
|
|
beq.s @loopEnd ; same go to the end
|
|
|
|
movea.l SysZone,a0 ; start of sys zone
|
|
movea.l bkLim(a0),a0 ; end of sys zone
|
|
suba.l d0,a0 ; end of sys zone + (needed-gotten)
|
|
adda.w #128,a0 ; with slop
|
|
_SetApplBase ; free up more sys space
|
|
_InitApplZone ; init the Toolbox world, too
|
|
bra.s MakeSysFree ; be sure we have enough
|
|
@loopEnd
|
|
rts ; end of MakeSysFree
|
|
|
|
EndProc
|
|
|
|
ELSE ; USE_MAKESYSFREE
|
|
|
|
; ***************************************************************************
|
|
; ptchInstall - subroutine
|
|
; <PMAB308/RWW112187>
|
|
; Loads 'ptch' resource, initializes it, and installs its traps.
|
|
; 'ptch' resource is assumed to have SysHeap and Locked bits set!
|
|
;
|
|
; Entry: D0.W = rsrc ID of 'ptch' resource to load
|
|
;
|
|
; Uses: D0-D2, A0-A1
|
|
;
|
|
; ***************************************************************************
|
|
|
|
ptchInstall Proc Export
|
|
|
|
SubQ #4,SP ; room for result
|
|
Move.L #'ptch',-(SP) ; signature of loadable patch resource
|
|
Move.W D0,-(SP) ; pass along given ID
|
|
_GetResource ; just in case we want to ROM it later on
|
|
Tst.L (SP) ; handle returned?
|
|
Bnz.S @4 ; Yep, okay to continue
|
|
AddQ #4,SP ; Yank garbage off the stack
|
|
Bra.S @xit ; and depart
|
|
@4
|
|
Move.L (SP),-(SP) ; make a copy of the handle
|
|
_DetachResource
|
|
; Uh, should we lock it down too, in case somebody goofs up?
|
|
|
|
Move.L (SP),A0 ; fetch handle (and keep copy on stack)
|
|
Move.L (A0),D0 ; point at head of resource <1.9>
|
|
_StripAddress ; strip it <1.9>
|
|
Move.L D0,-(SP) ; save it on the stack <2.3>
|
|
Move.L D0,A0 ; put it into A0 <1.9>
|
|
Jsr (A0) ; go execute init code
|
|
|
|
; on return, A0 should hold cutback address
|
|
Move.L A0,D1 ; save cutback address
|
|
Move.L A0,A1 ; and make an index copy
|
|
|
|
Move.L (SP)+,D2 ; get previously stripped pointer <2.3>
|
|
|
|
@3 Move.L (A1)+,D0 ; get offset
|
|
Beq.S @1 ; if it's zero, we be done
|
|
|
|
Add.L D2,D0 ; add base to get real address
|
|
Move.L D0,A0 ; move to A0 for SetTrapAddress
|
|
Move.W (A1)+,D0 ; get trap number
|
|
|
|
Cmp.W #$A800,D0 ; OS or TB trap?
|
|
Bcs.S @2 ; < $A800 is OS
|
|
|
|
_SetTrapAddress NewTool
|
|
Bra.S @3
|
|
|
|
@2 _SetTrapAddress NewOS
|
|
Bra.S @3
|
|
|
|
@1 Move.L D1,D0 ; cutback address
|
|
Sub.L D2,D0 ; cutback - resource start = new size
|
|
Move.L (SP)+,A0 ; fetch handle, for the last time
|
|
_SetHandleSize
|
|
Bra.S @done
|
|
|
|
@xit clr.l ResumeProc ; disable the resume button.
|
|
MoveQ.L #dsBadPatch, D0
|
|
_SysError
|
|
|
|
@done Rts
|
|
|
|
EndProc
|
|
|
|
ENDIF ; USE_MAKESYSFREE
|
|
|
|
EndM
|
|
|
|
;
|
|
; MACRO protectedJmp &label,&toWhere
|
|
;
|
|
; This puts the special protection header on for the patch protector.
|
|
; See PatchProtector.a for details.
|
|
;
|
|
|
|
macro
|
|
protectedJmp &label,&toWhere
|
|
bra.s @skip
|
|
@jmp:
|
|
jmp (&toWhere).L
|
|
@skip:
|
|
&label: equ @jmp
|
|
endm
|
|
|
|
;
|
|
; MACRO protectedJmpBind &label,&toWhere
|
|
;
|
|
; This puts the special protection header on for the patch protector.
|
|
; See PatchProtector.a for details.
|
|
;
|
|
|
|
macro
|
|
protectedJmpBind &label,&toWhere
|
|
bra.s @skip
|
|
@jmp:
|
|
jmpBind &toWhere
|
|
@skip:
|
|
&label: equ @jmp
|
|
endm
|
|
|
|
;
|
|
; MACRO protectedJmpROM &label,&toWhere
|
|
;
|
|
; This puts the special protection header on for the patch protector.
|
|
; See PatchProtector.a for details.
|
|
;
|
|
|
|
macro
|
|
protectedJmpROM &label,&toWhere
|
|
bra.s @skip
|
|
@jmp:
|
|
jmpROM &toWhere
|
|
@skip:
|
|
&label: equ @jmp
|
|
endm
|
|
|
|
ENDIF ; ...already included |