mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-25 09:30:50 +00:00
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
|