mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 20:49:19 +00:00
843 lines
31 KiB
Plaintext
843 lines
31 KiB
Plaintext
;
|
|
; File: DispatchPatch.a
|
|
;
|
|
; Contents: a patch to get a new trap dispatcher on the machines that need it
|
|
; The dispatcher is a faster one for the II ROMs, and one that is
|
|
; both faster, and supports a secondary trap table on the Plus and SE ROMs.
|
|
;
|
|
; Since this gets in the way of debugging, it is loaded as part of the
|
|
; pre-patch boot process, before MacsBug is loaded. This code, along with
|
|
; BootCode.a, makes up the 'boot' 3 resource.
|
|
;
|
|
; Copyright: © 1982-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 7/20/93 SAM Added a macro to correctly set the assembler directive according
|
|
; to the build conditional "CPU".
|
|
; <6> 3/27/92 JSM Update header comments, this code now lives in 'boot' 3.
|
|
; <5> 2/12/92 JSM Moving to TrapDispatcher directory, keeping all revisions.
|
|
; <4> 8/14/90 dba get auto-pop and extended cases working on a Plus or SE w/68020
|
|
; <3> 7/11/90 gbm blast some asm warnings
|
|
; <2> 6/15/90 EMT Fixed a few typos.
|
|
; <1> 6/11/90 EMT New today.
|
|
;
|
|
|
|
load 'StandardEqu.d'
|
|
|
|
MACRO
|
|
SETMACHINE
|
|
IF CPU = 020 THEN
|
|
MACHINE MC68020
|
|
ELSEIF CPU = 030 THEN
|
|
MACHINE MC68030
|
|
ELSEIF CPU = 040 THEN
|
|
MACHINE MC68040
|
|
ELSE
|
|
AERROR 'Unknown CPU type'
|
|
ENDIF
|
|
ENDM
|
|
|
|
SETMACHINE
|
|
|
|
MacPlus equ $0075
|
|
MacSE equ $0276
|
|
MacII equ $0178
|
|
numTbTrap equ 512 ; old number of toolbox traps
|
|
XnumTbTrap equ 1024 ; total # of toolbox traps in the extended trap dispatcher
|
|
XnumTrapMask equ XNumTbTrap-1 ; mask for number of extended toolbox traps
|
|
XTbEntries equ XNumTbTrap-numTbTrap ; # of toolbox traps in extended portion of trap table
|
|
XTbSize equ XTbEntries*4 ; size of the extended trap table (in bytes)
|
|
ToolTable equ $0E00 ; start of toolbox trap table
|
|
PlusToolDiff equ $0C00-ToolTable ; difference between the MacPlus and the current toolbox trap table
|
|
|
|
MACRO
|
|
InitPlusFix
|
|
GBLA &NumTTRefs
|
|
&NumTTRefs SETA 0
|
|
ENDM
|
|
InitPlusFix
|
|
|
|
MACRO
|
|
PlusToolTrapRef &Offset
|
|
GBLA &NumTTRefs
|
|
&NumTTRefs SETA &NumTTRefs + 1
|
|
ENTRY PlusToolTrapRefTab_&NumTTRefs
|
|
PlusToolTrapRefTab_&NumTTRefs EQU *+&Offset
|
|
ENDM
|
|
|
|
MACRO
|
|
FixUpMacPlus
|
|
LEA StartFixMacPlus,A0
|
|
@NextFix
|
|
MOVE.W (A0)+, D0 ; Offset in D0
|
|
BEQ.S EndFixMacPlus ; If 0, we're done.
|
|
LEA StartFixMacPlus(PC, D0.W), A1 ; Get address of code to patch.
|
|
ADD.W #PlusToolDiff, (A1) ; Add the magic difference.
|
|
BRA.S @NextFix ; And move on.
|
|
|
|
; Build the table.
|
|
GBLA &NumTTRefs
|
|
LCLA &i
|
|
StartFixMacPlus
|
|
&i SETA 1
|
|
WHILE &i <= &NumTTRefs DO
|
|
DC.W PlusToolTrapRefTab_&i - StartFixMacPlus
|
|
&i SETA &i + 1
|
|
ENDWHILE
|
|
DC.W 0
|
|
EndFixMacPlus
|
|
ENDM
|
|
|
|
; -----------------------------------------------------------------------------------------
|
|
;
|
|
; A-Trap Dispatcher Patch for the Mac Plus and SE <4.3>
|
|
; ===============================================
|
|
;
|
|
; This code "borrowed" from Gary Davidian's rewrite of the A-Trap Dispatcher
|
|
; (Nov. '88). For the complete history of this code, see file "OS:Dispatch.a".
|
|
;
|
|
; The basic upgrade is to install Gary's optimized A-Trap Dispatch code and
|
|
; to extend the size of the Toolbox Trap dispatch table. On the Plus and the
|
|
; SE, the Toolbox trap table consists of 512 entries. On the II and beyond,
|
|
; it consists of 1024 entries (see HardwareEqu.a for details).
|
|
;
|
|
; NOTE - this code completely replaces all previous A-Trap dispatch code.
|
|
; Because it is possible to have accelerators that could possibly be another
|
|
; processor besides the 68000 (a 68010, 68020 or 68030), we provide three (3)
|
|
; dispatchers (a 68000, 68010, and one for 68020/68030).
|
|
;
|
|
; BG 5-July-89
|
|
; -----------------------------------------------------------------------------------------
|
|
|
|
MacPlusAndSEATrapDispatch PROC
|
|
|
|
; ****************************************************
|
|
; * *
|
|
; * Varous ENTRYs required by the installation code *
|
|
; * *
|
|
; ****************************************************
|
|
|
|
ENTRY MacPlusAndSEATrap68000
|
|
ENTRY MacPlusAndSEATrap68010
|
|
ENTRY EndMacPlusAndSEATrap68000
|
|
ENTRY MacPlusAndSEATrap68020
|
|
ENTRY EndMacPlusAndSEATrap68020
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: MacPlusAndSEATrap68000
|
|
;
|
|
; Function: Dispatch A-line emulator traps to Mac system.
|
|
;
|
|
; Input: (SP) - status register
|
|
; 2(SP) - address of trapped instruction
|
|
; 6(SP) - stack frame format word (for 68010s)
|
|
;
|
|
; Output: none
|
|
;
|
|
; Called by: Jump through vector at $28 when trap occurs.
|
|
;
|
|
; 68000 A-line trap dispatcher
|
|
;
|
|
; Timing information Clocks ROM Reads RAM Reads RAM Writes
|
|
;
|
|
; ToolBox, autopop 196 23 14 8
|
|
; ToolBox, normal 206 24 14 10
|
|
;
|
|
if OSTable-($100*4) <> 0 then
|
|
; OpSys, A0 not saved 306 36 21 16
|
|
else
|
|
; OpSys, A0 not saved 302 35 21 16
|
|
endif
|
|
; OpSys, normal 328 37 23 18
|
|
;_______________________________________________________________________
|
|
MacPlusAndSEATrap68000 ; 34 0 4 3 overhead for A-Trap exception
|
|
move.w d3,-(sp) ; 8 1 0 1 save d3, stack has d3.lo/x/pc
|
|
move.l a2,-(sp) ; 12 1 0 2 save a2, stack has a2/d3.lo/x/pc
|
|
movea.l 4+4(sp),a2 ; 16 2 2 0 get return address
|
|
move.w (a2)+,d3 ; 8 1 1 0 get trap word, inc pc
|
|
cmpi.w #$A800,d3 ; 8 2 0 0 see if os or tool trap
|
|
blo.s OSTrap68000 ; 8 1 0 0 os-traps are lower
|
|
|
|
ToolTrap68000
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 2
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 4
|
|
; +++
|
|
; We subtract *numTbTrap* as well as $A800 to determine whether it is either (1) in the
|
|
; extended toolbox or (2) an autoPop operation. This allows the "standard A-Trap (in the
|
|
; normal range of Plus/SE traps) to still run at the fastest possible speed. We'll take
|
|
; care of sorting out autoPop and/or extended entries out of the main flow of traffic.
|
|
|
|
subi.w #(($A800+numTbTrap)\; 8 2 0 0 subtract tool trap start
|
|
*4)**$FFFF,d3 ; and see if auto-pop set
|
|
; OR if in extended toolbox table
|
|
bhs.s @Extended ; 8 1 0 0 handle auto pop separately
|
|
; ---
|
|
; This is the "standard" A-Trap handling.
|
|
move.l a2,4+4(sp) ; 16 2 0 2 save updated return pc
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
move.w 4(sp),d3 ; 12 2 1 0 restore d3
|
|
; +++
|
|
; We re-add in *numTbTrap* because we subtracted it above.
|
|
PlusToolTrapRef 2
|
|
move.l ToolTable\ ; 28 3 2 2 get trap table entry
|
|
+(numTbTrap*4)(a2)\ ; biased by -extended- bit
|
|
,4(sp) ; setup routine address
|
|
; ---
|
|
movea.l (sp)+,a2 ; 12 1 2 0 restore a2
|
|
rts ; 16 2 2 0 jump to the routine
|
|
|
|
; +++
|
|
; Here, we need to do two things:
|
|
;
|
|
; 1. See whether or not trap is an auto-pop one.
|
|
; -- if it is NOT, then it has to be an extended one.
|
|
; -- if it IS, continue checking (at #2)
|
|
; 2. If you made it here, we need to check if we're dealing with an extended autoPop.
|
|
; Check if the Extended bit is on.
|
|
; -- if it IS, perform the extended autoPop dance.
|
|
; -- if not, handle the "normal" auto-pop trap dispatch.
|
|
|
|
@Extended ; 2 1 0 0 overhead needed to branch here
|
|
addi.w #(numTbTrap*4),d3 ; 8 2 0 0 restore original shifted offset value
|
|
bclr #12,d3 ; 10 1 0 0 clear (and test)(shifted) auto-pop bit
|
|
beq.s @JustExtended ; 8 1 0 0 if not an auto-pop
|
|
bclr #11,d3 ; 10 1 0 0 clear (and test)(shifted) extended bit
|
|
beq.s @AutoPop ; 8 1 0 0 not extended - perform std. auto-pop
|
|
|
|
; Handle extended auto-pop) toolbox trap addressing here:
|
|
; -- D3.w now contains the offset into the extended trap table.
|
|
|
|
@XAutoPop ; 2 1 0 0 overhead needed to branch here
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
adda.l XToolTable,a2 ; 22 2 5 0 add in base address of extended table
|
|
move.l (a2),4+4(sp) ; 16 ? 3 1 get trap table entry
|
|
movea.l (sp)+,a2 ; 12 1 2 0 restore a2
|
|
move.w (sp),d3 ; 8 1 1 0 restore d3
|
|
addq.w #4,sp ; 8 1 0 0 pop hole from stack
|
|
rts ; 16 2 2 0 jump to the routine
|
|
|
|
; Handle extended (non-auto-pop) toolbox trap addressing here:
|
|
; -- D3.w now contains the offset into the extended trap table.
|
|
|
|
@JustExtended ; 2 1 0 0 overhead needed to branch here
|
|
bclr #11,d3 ; 10 1 0 0 clear extended bit (since we know its set)
|
|
move.l a2,4+4(sp) ; 16 2 0 2 save updated return pc
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
move.w 4(sp),d3 ; 12 2 1 0 restore d3
|
|
adda.l XToolTable,a2 ; 22 2 5 0 add in base address of extended table
|
|
move.l (a2),4(sp) ; 16 ? 3 1 get trap table entry
|
|
movea.l (sp)+,a2 ; 12 1 2 0 restore a2
|
|
rts ; 16 2 2 0 jump to the routine
|
|
@AutoPop
|
|
; ---
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
PlusToolTrapRef 2
|
|
move.l ToolTable(a2)\ ; 28 3 2 2 get trap table entry
|
|
,4+4(sp) ; setup routine address
|
|
movea.l (sp)+,a2 ; 12 1 2 0 restore a2
|
|
move.w (sp),d3 ; 8 1 1 0 restore d3
|
|
addq.w #4,sp ; 8 1 0 0 pop hole from stack
|
|
rts ; 16 2 2 0 jump to the routine
|
|
|
|
MacPlusAndSEATrap68010
|
|
move.w d3,(sp) ; save d3, stack has d3.lo/pc/x
|
|
move.l a2,-(sp) ; save a2, stack has a2/d3.lo/x/pc
|
|
movea.l 4+2(sp),a2 ; get return address
|
|
move.w (a2)+,d3 ; 8 1 1 0 get trap word, inc pc
|
|
cmpi.w #$A800,d3 ; 8 2 0 0 see if os or tool trap
|
|
bhs.s ToolTrap68000 ; 8 1 0 0 Tool traps are higher or equal
|
|
|
|
OSTrap68000 ; 2 1 0 0 overhead needed to branch here
|
|
move.l a2,4+4(sp) ; 16 2 0 2 save updated return pc
|
|
move.l d2,-(sp) ; 12 1 0 2 save d2, stack has d2/a2/xx/pc
|
|
move.l d1,-(sp) ; 12 1 0 2 save d1, stack has d1/d2/a2/xx/pc
|
|
move.l a1,-(sp) ; 12 1 0 2 save a1, stack has a1/d1/d2/a2/xx/pc
|
|
move.w d3,d1 ; 4 1 0 0 pass trap word to OStraps in D1
|
|
andi.w #$0100,d3 ; 8 2 0 0 test the don't save A0 bit
|
|
bne.s @A0NotSaved ; 8 1 0 0 handle it separately
|
|
|
|
move.l a0,-(sp) ; 12 1 0 2 save a0, stack has a0/a1/d1/d2/a2/xx/pc
|
|
move.b d1,d3 ; 4 1 0 0 zero extend the trap table index
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 2
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 4
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
move.w 5*4(sp),d3 ; 12 2 1 0 restore d3.low
|
|
movea.l OSTable(a2),a2 ; 16 2 2 0 get trap table entry
|
|
jsr (a2) ; 16 2 0 2 call the routine
|
|
movea.l (sp)+,a0 ; 12 1 2 0 restore a0
|
|
movea.l (sp)+,a1 ; 12 1 2 0 restore a1
|
|
movem.l (sp)+,d1/d2/a2 ; 36 2 7 0 restore d1/d2/a2
|
|
tst.w d0 ; 4 1 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 8 1 0 0 pop hole from stack
|
|
rts ; 16 2 2 0 return
|
|
|
|
@A0NotSaved ; 2 1 0 0 overhead needed to branch here
|
|
move.b d1,d3 ; 4 1 0 0 zero extend the trap table index
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 2
|
|
add.w d3,d3 ; 4 1 0 0 trap number * 4
|
|
movea.w d3,a2 ; 4 1 0 0 setup index to table entry
|
|
move.w 4*4(sp),d3 ; 12 2 1 0 restore d3.low
|
|
if OSTable-($100*4) <> 0 then
|
|
movea.l OSTable\ ; 16 2 2 0 get trap table entry
|
|
-($100*4)(a2),a2 ; biased by the dont save A0 bit
|
|
else
|
|
movea.l OSTable\ ; 12 1 2 0 get trap table entry
|
|
-($100*4)(a2),a2 ; biased by the dont save A0 bit
|
|
endif
|
|
jsr (a2) ; 16 2 0 2 call the routine
|
|
movea.l (sp)+,a1 ; 12 1 2 0 restore a1
|
|
movem.l (sp)+,d1/d2/a2 ; 36 2 7 0 restore d1/d2/a2
|
|
tst.w d0 ; 4 1 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 8 1 0 0 pop hole from stack
|
|
rts ; 16 2 2 0 return
|
|
|
|
EndMacPlusAndSEATrap68000
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: MacPlusAndSEATrap68020
|
|
;
|
|
; Function: Dispatch A-line emulator traps to Mac system.
|
|
;
|
|
; Input: (SP) - status register
|
|
; 2(SP) - address of trapped instruction
|
|
; 6(SP) - stack frame format word
|
|
;
|
|
; Output: none
|
|
;
|
|
; Called by: Jump through vector at $28 when trap occurs.
|
|
;
|
|
; 68020 / 68030 A-line trap dispatcher
|
|
;
|
|
; Approx Mem information ROM Reads RAM Reads RAM Writes
|
|
;
|
|
; ToolBox, autopop 13 8 7
|
|
; ToolBox, normal 12 8 8
|
|
;
|
|
; OpSys, A0 not saved 20 10 10
|
|
; OpSys, normal 20 11 11
|
|
;_______________________________________________________________________
|
|
|
|
machine mc68020
|
|
align 16 ; align on cache line boundary
|
|
MacPlusAndSEATrap68020 ; 2 1 4 overhead for A-Trap exception
|
|
move.l a2,-(sp) ; 1 0 1 save a2, stack has a2/x/pc/x
|
|
move.l d2,-(sp) ; 0 0 1 save d2, stack has d2/a2/x/pc/x
|
|
movea.l 4+4+2(sp),a2 ; 1 2 0 get return address
|
|
move.w (a2)+,d2 ; 1 1 0 get trap word, inc pc
|
|
cmpi.w #$A800,d2 ; 1 0 0 see if os or tool trap
|
|
blo.s @OSTrap ; 0 0 0 os-traps are lower
|
|
|
|
@ToolTrap
|
|
; +++
|
|
subi.w #($A800+numTbTrap)\ ; 1 0 0 subtract tool trap start
|
|
,d2 ; and see if auto-pop set
|
|
bhs.s @Extended ; 1 0 0 handle auto pop separately
|
|
|
|
; This is the "standard" toolbox trap handling path.
|
|
|
|
PlusToolTrapRef 4
|
|
move.l (ToolTable\ ; 2 1 1 get trap table entry
|
|
+(numTbTrap*4)\ ; biased by extended bit
|
|
,d2.w*4),4+4(sp) ; setup routine address
|
|
; ---
|
|
move.l a2,4+4+4(sp) ; 1 0 1 save updated return pc
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
rts ; 1 1 0 jump to the routine
|
|
|
|
; +++
|
|
; Here, we need to do two things:
|
|
;
|
|
; 1. See whether or not trap is an extended one.
|
|
; -- if it is NOT, then it has to be a standard autoPop.
|
|
; -- if it IS, continue checking (at #2)
|
|
; 2. If you made it here, we need to check if we're dealing with autoPop.
|
|
; -- if it IS, perform the extended autoPop dance.
|
|
; -- if not, handle the "normal" extended trap dispatch.
|
|
|
|
@Extended ; 1 0 0 overhead needed to branch here
|
|
cmp.w #autoPop-numTbTrap\ ; check and see if this is auto-pop
|
|
,d2
|
|
blo.s @JustExtended ; it is just extended (not auto-pop)
|
|
sub.w #autoPop,d2 ; get rid of the auto-pop bit
|
|
bcs.s @AutoPop ; not extended - perform std. auto-pop
|
|
|
|
; The stack will have a2/d2/trap_addr/hole.l.
|
|
; We get rid of the hole with an RTD, and top of stack will have original
|
|
; user's return address.
|
|
|
|
@XAutoPop ; 1 0 0 overhead needed to branch here
|
|
move.l ([XToolTable],\ ; get base address of extended table
|
|
d2.w*4),4+4(sp) ; setup routine address
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
rtd #4 ; 1 1 0 jump to the routine (and remove hole)
|
|
|
|
; Handle extended (non-auto-pop) toolbox trap addressing here:
|
|
; The stack will be rewritten to look like a2/d2/trap_addr/inc'ed_pc.
|
|
|
|
align 16 ; align on cache line boundary
|
|
@JustExtended ; 1 0 0 overhead needed to branch here
|
|
move.l ([XToolTable],\ ; get base address of extended table
|
|
d2.w*4),4+4(sp) ; setup routine address
|
|
move.l a2,4+4+4(sp) ; 1 0 1 save updated return pc
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
rts ; 1 1 0 jump to the routine
|
|
|
|
align 16 ; align on cache line boundary
|
|
@AutoPop ; 1 0 0 overhead needed to branch here
|
|
PlusToolTrapRef 4
|
|
move.l (ToolTable\ ; 2 1 1 get trap table entry
|
|
+(numTbTrap*4)\ ; biased by extended bit
|
|
,d2.w*4),4+4(sp) ; setup routine address
|
|
move.l (sp)+,d2 ; 1 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 0 1 0 restore a2
|
|
rtd #4 ; 1 1 0 jump to the routine
|
|
|
|
align 16 ; align on cache line boundary
|
|
@OSTrap ; 1 0 0 overhead needed to branch here
|
|
move.l d1,-(sp) ; 1 0 1 save d1, stack has d1/d2/a2/xx/pc
|
|
move.l a1,-(sp) ; 0 0 1 save a1, stack has a1/d1/d2/a2/xx/pc
|
|
move.w d2,d1 ; 1 0 0 pass trap word to OStraps in D1
|
|
move.l a2,5*4(sp) ; 1 0 1 save updated return pc
|
|
andi.w #$0100,d2 ; 1 0 0 test the don't save A0 bit
|
|
bne.s @A0NotSaved ; 0 0 0 handle it separately
|
|
|
|
move.b d1,d2 ; 1 0 0 zero extend the trap table index
|
|
move.l a0,-(sp) ; 0 0 1 save a0, stack has a0/a1/d1/d2/a2/xx/pc
|
|
jsr ([OSTable,d2.w*4]) ; 3 1 1 call the routine
|
|
movea.l (sp)+,a0 ; 1 1 0 restore a0
|
|
movea.l (sp)+,a1 ; 0 1 0 restore a1
|
|
move.l (sp)+,d1 ; 1 1 0 restore d1
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
tst.w d0 ; 0 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 1 0 0 pop hole from stack
|
|
rts ; 1 1 0 return
|
|
|
|
align 16 ; align on cache line boundary
|
|
@A0NotSaved ; 1 0 0 overhead needed to branch here
|
|
move.b d1,d2 ; 1 0 0 get the trap table index
|
|
jsr ([OSTable-($100*4),d2.w*4]) ; 2 1 1 call the routine
|
|
movea.l (sp)+,a1 ; 1 1 0 restore a1
|
|
move.l (sp)+,d1 ; 0 1 0 restore d1
|
|
move.l (sp)+,d2 ; 1 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 0 1 0 restore a2
|
|
tst.w d0 ; 1 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 0 0 0 pop hole from stack
|
|
rts ; 2 1 0 return
|
|
|
|
EndMacPlusAndSEATrap68020
|
|
ENDPROC
|
|
|
|
TrapCommon PROC ENTRY
|
|
|
|
ENTRY GetTrapAddress
|
|
ENTRY SetTrapAddress
|
|
ENTRY vCacheFlush68020
|
|
ENTRY vCacheFlush
|
|
ENTRY EndTrapCommon
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: FindTableEntry
|
|
;
|
|
; Function: Return address of trap entry in the dispatch table.
|
|
; (flushes Inst cache on 020).
|
|
;
|
|
; Input: D0 - trap number in low bits
|
|
; D1 - Get/Set TrapAddress trap word (for NewTool/NewOS bit testing)
|
|
;
|
|
; Output: A1 - address of trap table entry for specified trap number
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
FindTableEntry
|
|
_AssumeEq OldDisp,ToolDisp-1 ; OldDisp is next to, and lower than ToolDisp
|
|
lsl.w #16-ToolDisp,d1 ; ccr.c <- ToolDisp, ccr.n <- OldDisp
|
|
bpl.s @oldTrap ; if OldDisp = 0, it's an old style trap
|
|
bcc.s @osTrap ; if ToolDisp = 0, it's a new style OS trap
|
|
|
|
; Otherwise, it's a new style ToolBox trap
|
|
@toolTrap andi.w #XnumTrapMask,d0 ; clear all but trap bits
|
|
move.w d0,d1 ; save a copy for "extended" testing
|
|
subi.w #numTbTrap,d1 ; < 0 if NOT an extended table entry
|
|
PlusToolTrapRef 2
|
|
lea ToolTable,a1 ; point to base of the Toolbox table
|
|
bmi.s @done ; if ccr.n, trap is in orig. part of the trap table
|
|
movea.l XToolTable,a1 ; place extended toolbox address in A1
|
|
move.w d1,d0 ; move (trap# - numTbTrap) [extended TB trap offset] to D1
|
|
|
|
@done add.w d0,d0 ; trap number * 2
|
|
add.w d0,d0 ; trap number * 4
|
|
adda.w d0,a1 ; index into the dispatch table
|
|
bra.s CacheFlush ; flush inst cache and return (destroys only reg D1)
|
|
|
|
@oldTrap andi.w #$01FF,d0 ; clear irrelevant bits
|
|
moveq.l #-$0057,d1 ; setup to check for ToolBox range
|
|
add.w d0,d1 ; d1 := TrapNum - $0057
|
|
bgt.s @toolTrap ; $0058 … $01FF are tool box traps
|
|
beq.s @osTrap ; $0057 is an OS trap
|
|
addq.w #$0057-$004F,d1 ; d1 := TrapNum - $004F
|
|
ble.s @osTrap ; $0000 … $004F are OS traps
|
|
subq.w #$0054-$004F,d1 ; d1 := TrapNum - $0054
|
|
bne.s @toolTrap ; $0054 is an OS trap, $50…$53,$55,$56 are tool box
|
|
@osTrap andi.w #$00FF,d0 ; only 8 bits for OS trap numbers
|
|
lea OSTable,a1 ; point to base of the OS table
|
|
bra.s @done ; index into the table and return
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetTrapAddress
|
|
;
|
|
; Function: Return trap address from dispatch table.
|
|
;
|
|
; Input: D0 - trap number in low 9 bits
|
|
;
|
|
; Output: A0 - trap address
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
GetTrapAddress
|
|
bsr.s FindTableEntry ; locate the dispatch table entry
|
|
movea.l (a1),a0 ; get the routine address from the table
|
|
moveq.l #noErr,d0 ; return with success
|
|
rts ; all done
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: SetTrapAddress
|
|
;
|
|
; Function: Load new trap vector into dispatch table.
|
|
; On 020 machines, flush the cache as well.
|
|
;
|
|
; Input: D0 - trap number in low 9 bits
|
|
; A0 - trap address
|
|
;
|
|
; Output: none
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
SetTrapAddress
|
|
bsr.s FindTableEntry ; locate the dispatch table entry
|
|
move.l a0,(a1) ; install the new routine address into the table
|
|
moveq.l #noErr,d0 ; return with success
|
|
rts ; all done
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Macros: CacheFlush, vCacheFlush
|
|
;
|
|
; Function: Flush the 68020 Cache. For programs that do self modifying code, etc.
|
|
;
|
|
; Arguments; none
|
|
;
|
|
; Invoked by: BlockMove, GetTrapAddress, LoadSeg, Read, SetTrapAddress, UnloadSeg
|
|
;
|
|
; Note that this routine only trashes one register, namely D1. D1 was chosen to speed up
|
|
; blockmove. In blockmove we can trash D1, since D1 is not used in blockmove, and since D1
|
|
; is preserved by the trap dispatcher.
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
CacheFlush
|
|
move.l jCacheFlush,-(sp) ; push the vector
|
|
rts ; jump through the vector
|
|
|
|
vCacheFlush68020 ; change at runtime if cache found
|
|
movec.l cacr,d1 ; get current cache state of 68020
|
|
addq.w #1<<3,d1 ; flush the instruction cache <1.4>
|
|
movec.l d1,cacr ; write back to the control register
|
|
|
|
vCacheFlush ; if no cache, nothing to flush
|
|
rts ; all done
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; End of code for optimized, extended A-Trap Dispatcher.
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
EndTrapCommon
|
|
ENDPROC
|
|
|
|
; -----------------------------------------------------------------------------------------
|
|
;
|
|
; A-Trap Dispatcher Patch for the Mac II
|
|
; ======================================
|
|
;
|
|
; This code "borrowed" from Gary Davidian's rewrite of the A-Trap Dispatcher
|
|
; (Nov. '88). For the complete history of this code, see file ":OS:Dispatch.a".
|
|
;
|
|
; The basic upgrade is to install Gary's optimized A-Trap Dispatch code.
|
|
; NOTE - this code completely replaces all previous A-Trap dispatch code.
|
|
;
|
|
; <BG> 7-July-1989
|
|
; -----------------------------------------------------------------------------------------
|
|
|
|
PROC
|
|
ENTRY MacIIATrap68020
|
|
ENTRY EndMacIIATrap68020
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: ATrap68020
|
|
;
|
|
; Function: Dispatch A-line emulator traps to Mac system.
|
|
;
|
|
; Input: (SP) - status register
|
|
; 2(SP) - address of trapped instruction
|
|
; 6(SP) - stack frame format word
|
|
;
|
|
; Output: none
|
|
;
|
|
; Called by: Jump through vector at $28 when trap occurs.
|
|
;
|
|
; 68020 / 68030 A-line trap dispatcher
|
|
;
|
|
; Approx Mem information ROM Reads RAM Reads RAM Writes
|
|
;
|
|
; ToolBox, autopop 13 8 7
|
|
; ToolBox, normal 12 8 8
|
|
;
|
|
; OpSys, A0 not saved 20 10 10
|
|
; OpSys, normal 20 11 11
|
|
;_______________________________________________________________________
|
|
|
|
MyAlignment set 16 ; alignment set to 16 for 68030
|
|
align MyAlignment ; align on cache line boundary <1.5>
|
|
MacIIATrap68020 ; 2 1 4 overhead for A-Trap exception
|
|
move.l a2,-(sp) ; 1 0 1 save a2, stack has a2/x/pc/x
|
|
move.l d2,-(sp) ; 0 0 1 save d2, stack has d2/a2/x/pc/x
|
|
movea.l 4+4+2(sp),a2 ; 1 2 0 get return address
|
|
move.w (a2)+,d2 ; 1 1 0 get trap word, inc pc
|
|
cmpi.w #$A800,d2 ; 1 0 0 see if os or tool trap
|
|
blo.s @OSTrap ; 0 0 0 os-traps are lower
|
|
|
|
@ToolTrap
|
|
subi.w #($A800+autoPop)\ ; 1 0 0 subtract tool trap start
|
|
,d2 ; and see if auto-pop set
|
|
bhs.s @AutoPop ; 1 0 0 handle auto pop separatly
|
|
|
|
move.l (ToolTable\ ; 2 1 1 get trap table entry
|
|
+(autoPop*4)\ ; biased by autopop bit
|
|
,d2.w*4),4+4(sp) ; setup routine address
|
|
move.l a2,4+4+4(sp) ; 1 0 1 save updated return pc
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
rts ; 1 1 0 jump to the routine
|
|
|
|
align MyAlignment ; align on cache line boundary <1.5>
|
|
@AutoPop ; 1 0 0 overhead needed to branch here
|
|
move.l (ToolTable,d2.w*4)\ ; 2 1 1 get trap table entry
|
|
,4+4(sp) ; setup routine address
|
|
move.l (sp)+,d2 ; 1 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 0 1 0 restore a2
|
|
rtd #4 ; 1 1 0 jump to the routine
|
|
eject
|
|
align MyAlignment ; align on cache line boundary <1.5>
|
|
@OSTrap ; 1 0 0 overhead needed to branch here
|
|
move.l d1,-(sp) ; 1 0 1 save d1, stack has d1/d2/a2/xx/pc
|
|
move.l a1,-(sp) ; 0 0 1 save a1, stack has a1/d1/d2/a2/xx/pc
|
|
move.w d2,d1 ; 1 0 0 pass trap word to OStraps in D1
|
|
move.l a2,5*4(sp) ; 1 0 1 save updated return pc
|
|
andi.w #$0100,d2 ; 1 0 0 test the don't save A0 bit
|
|
bne.s @A0NotSaved ; 0 0 0 handle it separatly
|
|
|
|
move.b d1,d2 ; 1 0 0 zero extend the trap table index
|
|
move.l a0,-(sp) ; 0 0 1 save a0, stack has a0/a1/d1/d2/a2/xx/pc
|
|
jsr ([OSTable,d2.w*4]) ; 3 1 1 call the routine
|
|
movea.l (sp)+,a0 ; 1 1 0 restore a0
|
|
movea.l (sp)+,a1 ; 0 1 0 restore a1
|
|
move.l (sp)+,d1 ; 1 1 0 restore d1
|
|
move.l (sp)+,d2 ; 0 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 1 1 0 restore a2
|
|
tst.w d0 ; 0 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 1 0 0 pop hole from stack
|
|
rts ; 1 1 0 return
|
|
|
|
align MyAlignment ; align on cache line boundary <1.5>
|
|
@A0NotSaved ; 1 0 0 overhead needed to branch here
|
|
move.b d1,d2 ; 1 0 0 get the trap table index
|
|
jsr ([OSTable-($100*4),d2.w*4]) ; 2 1 1 call the routine
|
|
movea.l (sp)+,a1 ; 1 1 0 restore a1
|
|
move.l (sp)+,d1 ; 0 1 0 restore d1
|
|
move.l (sp)+,d2 ; 1 1 0 restore d2
|
|
movea.l (sp)+,a2 ; 0 1 0 restore a2
|
|
tst.w d0 ; 1 0 0 set conditions based on d0.w
|
|
addq.w #4,sp ; 0 0 0 pop hole from stack
|
|
rts ; 2 1 0 return
|
|
|
|
EndMacIIATrap68020
|
|
ENDPROC
|
|
|
|
SETMACHINE ; set it back to the native type <SM7>
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; Beginning of installation code
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
InstallDispatch PROC EXPORT
|
|
move.l ROMBase,a0 ; point to ROM
|
|
move.w 8(a0),d0 ; get ROM version
|
|
cmp.w #MacPlus,d0 ; is it a Mac Plus?
|
|
beq.s InstallPlus ; go to it.
|
|
cmp.w #MacSE,d0 ; is it a Mac SE?
|
|
beq.s InstallSE ; go to it.
|
|
cmp.w #MacII,d0 ; is it a Mac II?
|
|
beq InstallMacII ; go to it.
|
|
rts ; nothing to do.
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; Beginning of installation code for optimized, extended A-Trap Dispatcher. <4.1>
|
|
;
|
|
; This creates the extended part of the Toolbox A-Trap dispatch table used
|
|
; by all new dispatcher code. It also installs new UnImplemented,
|
|
; GetTrapAddress, and SetTrapAddress traps. Finally, it decides which of
|
|
; the A-Trap dispatch tables to use based on *CpuFlag*.
|
|
;
|
|
; <BG> 5-July-1989
|
|
; csd 16-Oct-89 Moved this install code above all other patches. <5.5>
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
InstallPlus
|
|
FixUpMacPlus
|
|
|
|
InstallSE
|
|
; setup registers
|
|
move.l #XTbSize,d0 ; size of toolbox trap table extension
|
|
_NewPtr sys ; request the extension to be in the system heap
|
|
bne Error ; ... no, so don't perform any further installation
|
|
|
|
move.l a0,XToolTable ; Save location of extended toolbox trap table
|
|
move.l a0,a1 ; use a1 for it
|
|
|
|
; Initialize extended Toolbox trap table with _Unimplemented.
|
|
|
|
move.w #$A89F,d0 ; offset into toolbox trap table for _Unimplemented
|
|
_GetTrapAddress
|
|
move.w #XTbEntries-1,d1 ; number of extended Toolbox trap entries
|
|
|
|
@XTableInit
|
|
move.l a0,(a1)+ ; point all extended entries at BadTrap
|
|
dbra d1,@XTableInit
|
|
|
|
; Now make the decision as to which A-Trap table to use, based on *CpuFlag*
|
|
moveq.l #0,d2 ; d2 = offset to Line1010 vector. Assume no offset
|
|
cmpi.b #1,CpuFlag ; let's see what kind of dispatcher we need
|
|
blo.s @Install68000
|
|
beq.s @Install68010
|
|
|
|
move.l #EndMacPlusAndSEATrap68020-MacPlusAndSEATrap68020,d1
|
|
lea MacPlusAndSEATrap68020,a1
|
|
bsr.s MoveToSysAlign ; copy the code on down.
|
|
move.l #vCacheFlush68020-TrapCommon,d1
|
|
bra.s @InstallCommon ; a1 = Line1010 vector, d1 = offset to CacheFlush
|
|
|
|
@Install68010
|
|
move.l #MacPlusAndSEATrap68010-MacPlusAndSEATrap68000,d2
|
|
; d2 = offset to Line1010 vector.
|
|
|
|
@Install68000
|
|
move.l #EndMacPlusAndSEATrap68000-MacPlusAndSEATrap68000,d1
|
|
lea MacPlusAndSEATrap68000,a1
|
|
bsr.s MoveToSys ; copy the code on down.
|
|
move.l #vCacheFlush-TrapCommon,d1
|
|
add.l d2,a1 ; add the offset to the Line1010 vector.
|
|
|
|
@InstallCommon
|
|
move.l a1,Line1010 ; install the Line-A exception handler
|
|
move.l d1,d2 ; save the CacheFlush offset in d2
|
|
|
|
move.l #EndTrapCommon-TrapCommon,d1
|
|
lea TrapCommon,a1
|
|
bsr.s MoveToSys ; copy the code on down.
|
|
|
|
; The common code is now in the system heap and pointed to by a1. The offset to the correct
|
|
; CacheFlush routine is in d2. We need to install the CacheFlush vector.
|
|
lea (a1,d2.l),a0 ; add the offset to CacheFlush.
|
|
move.l a0,jCacheFlush ; initialize cache-flushing vector
|
|
|
|
; Now update the _GetTrapAddress and _SetTrapAddress traps to point to the new code.
|
|
lea GetTrapAddress-TrapCommon(a1),a0
|
|
moveq.l #$46,d0 ; _GetTrapAddress
|
|
_SetTrapAddress
|
|
lea SetTrapAddress-TrapCommon(a1),a0
|
|
moveq.l #$47,d0 ; _SetTrapAddress
|
|
_SetTrapAddress
|
|
|
|
rts
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; End of installation code for optimized, extended A-Trap Dispatcher.
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; Beginning of installation code for optimized, extended A-Trap Dispatcher.
|
|
;
|
|
; This installs the new dispatcher code.
|
|
;
|
|
; <BG> 7-July-1989
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
InstallMacII
|
|
move.l #EndMacIIATrap68020-MacIIATrap68020,d1
|
|
lea MacIIATrap68020,a1
|
|
bsr.s MoveToSysAlign
|
|
move.l a1,Line1010 ; install the Line-A exception handler
|
|
rts
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
; Creates a block in the system heap, copies the block of memory starting at a1 for d1 bytes into
|
|
; it. Returns the place it copied to in a1.
|
|
MoveToSys
|
|
move.l d1,d0 ; How much space we'll need.
|
|
_NewPtr sys ; request the system heap
|
|
bne.s Error ; no memory, panic.
|
|
|
|
exg a1,a0 ; put source and destinaton for blockmove in right place.
|
|
move.l d1,d0 ; number of bytes
|
|
_BlockMove
|
|
rts
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
; Creates a block in the system heap, copies the block of memory starting at a1 for d1 bytes into
|
|
; it, and aligns it to a 16 byte boundary. Returns the place it copied to in a1.
|
|
MoveToSysAlign
|
|
moveq #14,d0 ; Add 14 bytes of slop to the pointer.
|
|
add.l d1,d0 ; How much space we'll need.
|
|
_NewPtr sys ; request the system heap
|
|
bne.s Error ; no memory, panic.
|
|
|
|
moveq.l #15,d0 ; align to a 16 byte boundary
|
|
add.l a0,d0 ; by adding 15
|
|
and.b #$F0,d0 ; and clearing out the low nibble
|
|
|
|
move.l a1,a0 ; source for blockmove
|
|
move.l d0,a1 ; destination for blockmove (aligned 16)
|
|
move.l d1,d0 ; number of bytes
|
|
_BlockMove
|
|
rts
|
|
|
|
Error
|
|
moveq #dsMemFullErr,d0
|
|
_SysError
|
|
rts
|
|
|
|
ENDPROC
|
|
|
|
; ------------------------------------------------------------------------------------
|
|
;
|
|
; End of installation code for optimized, extended A-Trap Dispatcher.
|
|
;
|
|
; ------------------------------------------------------------------------------------
|
|
END
|