sys7.1-doc-wip/OS/TrapDispatcher/Dispatch.a
2019-07-27 22:37:48 +08:00

771 lines
32 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: Dispatch.a
;
; Written by: Andy Hertzfeld July 15, 1982
;
; Copyright: © 1982-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM15> 10/25/93 SAM Roll in <MC4> from mc900ftjesus.
; <MC4> 10/25/93 SAM Changed equate name mmCacheUnk1 to mmFigEnable.
; <SM14> 10/15/93 rab Roll ProtectGetTrap and ProtectSetTrap from PatchProtector.a
; into G/SetTrapAddress.
; <SM13> 10/12/93 SAM Roll in <MC2> from mc900ftjesus.
; <MC2> 10/12/93 SAM Redid the figment check to look at universal flags to determine
; if we should switch in the figment aware dispatch table. Side
; effect of this check is the update of MMFlags from PRAM.
; <SM12> 5/26/93 BT Switch polarity of figment switch.
; <SM11> 5/20/93 BT Urgh, forgot something
; <SM10> 5/20/93 BT Update build to only include Figment under conditional compile
; flag "hasNewHeapMgr".
; <SM9> 5/19/93 BT Change PRAM address to end of Spectre's Server Name address.
; Using slot 6 didn't work because it was reset after every second
; boot.
; <SM8> 5/18/93 BT Add some code to check PRAM to see if Figment is supposed to be
; loaded and change which trap table is used, accordingly. The
; alternate trap table is right after the original OS trap table
; in DispTable.a
; <SM7> 5/6/93 SAM On machines with a 68k emulator running, the cacheFlush vector
; is pointed at an RTS (cuz there's no need to be flushin!)
; <SM6> 11/30/92 GD Added support for A-Trap tracing and logging in forRomulator
; builds (with the correct nub).
; <SM5> 11/2/92 kc Remove DispatchTable DeCompression.
; <SM4> 7/1/92 RB Added the TrapAddressBits procedure to Get and Set TrapAddress.
; This function takes a full word trap address and it clears/sets
; the relevant OS/Toolbox bits. The Installer needs this in order
; for it to work on SuperMario.
; <SM3> 5/21/92 RB Changing the name of SetTrapAddress and GetTrapAddress to
; SetTrapAddressTrap and GetTrapAddressTrap because someone forgot
; to finish the damn job.
; <SM2> 5/11/92 PN Remove 68000 conditionals for SuperMario ROM
; <8> 2/12/92 JSM Moving to TrapDispatcher directory, keeping all revisions.
; <7> 8/29/91 JSM Cleanup header.
; <6> 6/12/91 LN Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
; <5> 10/10/90 HJR Save and restore d1 register in the Cache flush routine since it
; needs to be preserved routines that call this code directly.
; <4> 6/25/90 BG Corrected a comment. No code changes.
; <3> 1/15/90 BG Added vCacheFlush68040 to provide 040 cache flushing. Modified
; InitDispatcher to install the 040 cache flushing routine into
; jCacheFlush when appropriate.
; <2> 1/11/90 CCH Added include of HardwarePrivateEqu.a.
; <1.5> 7/17/89 GGD Changed aligns to use alignment equate instead of hard coded 16.
; <1.4> 6/15/89 GGD Incorporated code review optimization to cache flushing routine.
; <1.3> 4/1/89 GGD Removed reference to DispOff, and referenced as an offset from
; ROMBase instead, to eliminate link errors on some machines.
; <1.2> 11/17/88 GGD Completely re-written and optimized. Old change history left
; around for historical purposes.
; <•1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.0> 2/10/88 BBM Adding file for the first time into EASE…
; <C914> 10/29/87 rwh Port to Modern Victorian (onMvMac)
; <C668> 1/22/87 bbm added a vector to flush the cache in SetTrapAddress. Added anew
; the same to GetTrapAddress and the routine to do it (called
; vCacheFlush). Even though the routine is in this module, you
; should go through the vector so that UNIX (which runs in user
; mode) can still patch this call.
; <C476> 12/2/86 JTC Unroll various cases in order to optimize for speed, not space.
; Some random notes: 1) We were careful to use CMPI.W rather than
; BTST to decode the A-line words, because the immediate
; operations were faster on the 68000; nowadays (on the 020 that
; is), the Bxxx instructions are a single cycle faster in the
; worst case, but in the interest of simplicity we leave well
; enough alone. 2) Although we were careful to use the constant
; numTrapMask to strip the leading bits $A800, we later use BCLRs
; to get rid of the $0600 bits in the OS trap words--just a little
; nit. Change SetTrapAddress to flush the cache, based on David
; Goldsmiths suggestion that many apps (and formerly MacApp)
; would indiscreetly blast some code into the system heap
; (possibly an absolute jump elsewhere) and _SetTrapAddress. To
; accommodate non-020 systems we leave the cache-clearing code in
; even though we move the entry point down past it in the case of
; 68000s; if a system is to run with the 020, a simple patch will
; be needed to fix the entry points to the cache-buster routines.
; <C456> 11/22/86 bbm moved the code to flush the cache into blockmove, loadseg,
; unloadseg, and read. this might improve performance.
; <C99> 8/5/86 BBM added support for expanded toolbox table on NuMac. (this file
; now includes hwEqu.a)
; <C54> 6/25/86 WRL & BBM Flush cache in trap dispatch for 68020 to fix self
; modifying code.
; 2/19/86 BBM Made some modifications to work under MPW
; 5/5/85 JTC _L... made modifier-bits variants of the original _Set... and
; _Get...
; 3/6/85 JTC Long-word dispatch table entries. Separate OSTable and
; ToolTable. New _LGetTrapAddress and _LSetTrapAddress.
; 1/31/85 LAK Added ATrap68010 for new machine support.
; 1/23/85 LAK Adapted for new equate files.
; 8/8/83 LAK Saved space in SetTrapAddr as per 17-July code review.
; 5/12/83 JTC Tweaked for speedup.
; 2/22/83 LAK Changed OS dispatch to save fewer regs since OS routines now
; observe Pascal regsave conventions; (async bit is bit 10).
; 10/24/82 AJH Added bit 10 auto-pop for toolBox dispatches Added
; GetTrapAddress, SetTrapAddress
;
;_______________________________________________________________________
;
; Written by Andy Hertzfeld July 15, 1982
; Re-Written and optimized by Gary G. Davidian November 7, 1988
;
; Copyright Apple Computer, Inc. 1982-1988
; All Rights Reserved
;
; Ancient Modification History: (for historical purposes only, does not correspond to this code)
;
; 24-Oct-82 AJH Added bit 10 auto-pop for toolBox dispatches
; Added GetTrapAddress, SetTrapAddress
; 22-Feb-83 LAK Changed OS dispatch to save fewer regs since OS routines
; now observe Pascal regsave conventions;
; (async bit is bit 10).
; 12-May-83 JTC Tweaked for speedup.
; 08-Aug-83 LAK Saved space in SetTrapAddr as per 17-July code review.
;_______________________________________________________________________
;
; 23 Jan 85 LAK Adapted for new equate files.
; 31 Jan 85 LAK Added ATrap68010 for new machine support.
; 06 Mar 85 JTC Long-word dispatch table entries. Separate OSTable and ToolTable.
; New _LGetTrapAddress and _LSetTrapAddress.
; 05 May 85 JTC _L... made modifier-bits variants of the original _Set... and _Get...
;_______________________________________________________________________
eject
Title 'Dispatch - Line A trap dispatcher'
;_______________________________________________________________________
;
; EMT1010 -- MacIntosh Operating System Dispatcher
;
; The following code receives all Line 1010 emulator traps and transfers control
; to the appropriate system code to interpret the trap. Two 32-bit/entry RAM-based
; dispatch tables are used to derive the addresses to dispatch to. Since this table
; is patchable, a system or application program can patch in and intercept any system
; call to fix bugs, etc.
;
; An A-line trap has the form: 1010 tabc nnnn nnnn
;
; t=1 ==> Toolbox; t=0 ==> OS. They differ mainly in register saving conventions.
;
; ToolBox:
; These calls follow Pascal parameter-passing conventions, receiving and returning
; values on the stack, and saving all but D0-D2/A0-A1.
; All registers are preserved up to the time the target routine is reached; the
; stack is as though a JSR had been executed.
; a=1 ==> an extra return address was on the stack when the trap was executed
; (e.g. a dumb compiler required a JSR to the A-line trap). This superfluous
; address will be removed by the dispatcher.
; bcnnnnnnnn = trap number
;
; OS:
; All parameters are passed in registers. Routine must follow Pascal
; conventions about D3-D7/A2-A7. D0/A0-A1 are passed through to the
; routine unchanged. D1.W is the actual A-line instruction.
; c=1 ==> D1-D2/A1 are preserved by the dispatcher (so values can be returned
; in D0/A0).
; c=0 ==> D1-D2/A0-A1 are preserved by the dispatcher (so D0 can be returned).
; a,b = don't care, but are used by the traps to indicate, say, SYS/APPL,
; SYNC/ASYNC, DIACRITICALS/NOT, . . .
; nnnnnnnn = trap number
;
; Dispatch addresses are maintained in two tables of long words, ToolTable with 512 entries,
; and OSTable with 256 entries. (They used to be rolled into one table of 512 word entries.)
; For backward compatibility, the GetTrapAddress and SetTrapAddress routines use the original
; trap numbering scheme, that is traps $00-$4F, $54, and $57 are OS traps, and the rest are
; Tool traps.
;
; The expanded routines GetTrapAddress and SetTrapAddress routines use
; bits #10 to specify Tool=1/OS=0 and #9 to specify New=1/Old=0 numbering. Bit #10 is ignored
; when bit #9 is 0.
;
; A few things to remember. Although toolbox routines use pascal register
; saving conventions, the trap dispatcher must preserve all registers when
; dispatching a toolbox trap, since there are some routines which are
; documented as saving all registers (_Debugger, _LoadSeg, _FP68K, …).
;
; Even though the OS trap dispatcher saves A0-A2/D1-D2 for the user, it
; may not modify A0 or A1 before calling the OS routine, since routines
; like _BlockMove expect paramaters in A0/A1/D0. Additionally, register
; D1 must contain a copy of the A-Trap word, since that is how routines
; read the additional trap bits (eg. _NewPtr ,SYS,CLEAR).
;
; Although the register save order, and format of the stack frame for an
; OS trap is undocumented, Microsoft does a SetTrapAddress on _GetHandleSize
; and and their new routine calls the ROM GetHandleSize, and then restores
; the registers that the trap dispatcher saved, and does a TST.L on D0.
; Because of this, register save order must be maintained for compatibility,
; since we may never get back to restore them.
;
; For machines with CPUs earlier than the 68020, we include 3 versions of the
; trap dispatcher in ROM, 68000, 68010, and 68020/030. At startup time we determine
; which CPU we are running on, and install the correct dispatcher. We also modify
; the dispatch addresses for GetTrapAddress, SetTrapAddress, and BlockMove to use
; cache flushing versions when the CPU is a 68020 or later.
; On systems with 68020/030 cpus, we only provode the 020/030 versions.
;_______________________________________________________________________
print off
LOAD 'StandardEqu.d'
include 'HardwarePrivateEqu.a'
include 'UniversalEqu.a'
print on
print nomdir
machine mc68020 ; assembles 68020 instructions, even for a 68000
; Conditionals used only within this code and unlikely to change.
FasterTool equ 1 ; favor toolbox traps at the expense of OS (68000 only)
Opt68010 equ 0 ; share code with 68000, and don't use separate optimized 68010 code
LotusKludge equ 1 ; add extra code to be compatible with a Lotus kludge
Dispatcher proc export
export EMT1010 ; default line A-Trap dispatcher
export GetTrapAddressTrap ; <SM3> rb
export SetTrapAddressTrap ; <SM3> rb
export CacheFlush
export vCacheFlush
export InitDispatcher
export BadTrap
import SysErr1
import BlockMove68020
If hasNewHeapMgr Then
import PramIO ; <SM8 BT>
endif
Title 'Dispatch - ATrap68020'
;_______________________________________________________________________
;
; 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 / 68040 A-line trap dispatcher <4>
;
; 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
;_______________________________________________________________________
align alignment ; align on cache line boundary <1.5>
ATrap68020 ; 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 alignment ; 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 alignment ; 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 alignment ; 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
Rts020Disp rts ; 2 1 0 return
EMT1010 equ ATrap68020
Title 'Dispatch - Find Table Entry'
;_______________________________________________________________________
;
; 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 #numTrapMask,d0 ; clear all but trap bits
lea (ToolTable,d0.w*4),a1 ; index into the Toolbox table
bra CacheFlush ; flush inst cache and return (destroys only reg D1) <SM14>
@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,d0.w*4),a1 ; index into the OS table
bra.s CacheFlush ; flush inst cache and return (destroys only reg D1)
Title 'Dispatch - Get / Set Trap Address'
IMPORT TrapAddressBits ; <SM4> rb
;_______________________________________________________________________
;
; Routine: GetTrapAddress
;
; Function: Return trap address from dispatch table.
;
; Input: D0 - trap number in low 9 bits
;
; Output: A0 - trap address
;
;_______________________________________________________________________
kBranchOverJMPLOpcode equ $6006 ; <SM14>
kJMPLOpcode equ $4EF9 ; <SM14>
kComeFromHeader equ (kBranchOverJMPLOpcode << 16) + kJMPLOpcode ; <SM14>
GetTrapAddressTrap ; <SM3> rb
bsr TrapAddressBits ; makes sure trap word is correct <SM14>begin
move ccr,-(sp) ; save condition register
bsr.s OldGetTrapAddress ; call the old GetTrapAddress
move (sp)+,ccr ; get condition codes back
bcs.s @done ; come-from patches bypass our trickery
@next
cmp.l #kComeFromHeader,(a0) ; does this have the come-from header?
bne.s @done ; no we are done
move.l 4(a0),a0 ; go on to the next
bra.s @next
@done
moveq #0,d0 ; must zero the result code again
rts
OldGetTrapAddress ; ; <SM14>end
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
;
;_______________________________________________________________________
SetTrapAddressTrap ; <SM3> rb
move.l (a0),d2 ; get header of trap, and check for bus errors <5><SM14>begin
bsr TrapAddressBits ; makes sure trap word is correct <SM4> rb
bcs.s OldSetTrapAddress ; come-from patches bypass our trickery
cmp.l #kComeFromHeader,d2 ; headers can only be used on come-from patches <5>
beq.s @illegalHeader ; saw a header, so I must system error <5>
movem.l d0-d1/a0,-(sp) ; save trap address, number, and bits
bsr OldGetTrapAddress ; call the old GetTrapAddress
move.l #0,a1 ; no come-froms found yet
@next
cmp.l #kComeFromHeader,(a0)+ ; does this have the come-from header?
bne.s @done ; no we are done
move.l a0,a1 ; remember this address
move.l (a0),a0 ; go on to the next
bra.s @next
@done
movem.l (sp)+,d0-d1/a0 ; restore trap address, number, and bits
cmp.l #0,a1 ; any come-froms found?
beq.s OldSetTrapAddress ; no, go do the real SetTrapAddress
move.l a0,(a1) ; set the trap address
move.l jCacheFlush,-(sp) ; get the cache flush vector <9>
rts ; call it, and then return to the trap dispatcher <9>
@illegalHeader
move.w #dsBadPatchHeader,d0 ; get error code <5>
_SysError ; report it to the unsuspecting user <5>
OldSetTrapAddress
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
move.l jCacheFlush,-(sp) ; get the cache flush vector <9>
rts ; call it, and then return to the trap dispatcher <9><SM14>end
;_______________________________________________________________________
;
; 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. In the 040 case, NO registers are destroyed. <3>
;
;_______________________________________________________________________
CacheFlush
move.l jCacheFlush,-(sp) ; push the vector
rts ; jump through the vector
vCacheFlush
move.l d1,-(SP) ; save this f*&%$ng register <5>
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
move.l (SP)+,d1 ; restore register <5>
rts ; all done
vCacheFlush68040 ; 68040 cache flushing for self-modifying programs <3>
; NOTE - since the 040 I-Cache never gets "dirty", it only needs to be invalidated. <3>
; BUT - if someone writes self-modifying code, it will end up in the D-Cache (!), <3>
; the D-Cache must be flushed since the I-Cache does not snoop the D-Cache <3>
; (and verse visea).[MC68040 User's Manual, 1st Ed., pg 7-7] <3>
;
MACHINE MC68040 ; perform 040 cache flushing <3>
cpusha bc ; invalidate the i-cache, flush d-cache <3>
rts ; return to caller - no registers destroyed <3>
MACHINE MC68020 ; reset to previous MACHINE directive <3>
Title 'Dispatch - InitDispatcher'
;_______________________________________________________________________
; InitDispatcher: Load Tool and OS trap tables, separate blocks of 512 and 256
; 32-bit addresses.
;
; Encoded table contains 512 Tooltraps, then as many OS traps as used. Format of entries is:
; $80 ==> skip entry
; $FF ==> next 4 bytes are absolute ROM address
; 1xxx xxxx ==> xxxx xxx0 is a positive offset from last trap address
; 0yyy ... y ==> yyyy yyyy yyyy yyy0 is a SIGNED offset from last trap address
; 0000 ... 0 ==> end of table
; Table begins at offset DispTableOff from base of ROM.
;
; Destroys D0-D3/A0-A4
; Called by StartInit
;_______________________________________________________________________
if LotusKludge then
; The following code is to accommodate Lotus, which, on Mac+ and later machines,
; looks INTO THE ROM INSTRUCTION STREAM to derive the address of the a-trap handler,
; presumably to bypass any debugger that may be installed. This code is NOT executed
; by this ROM, it is only here for compatibility. I assume they search for the final
; "move.l a0,line1010" instruction, and look for the LEA's relative to it, so this code
; must come before the real dispatcher installation code so that we don't confuse them.
; See the MacPlus ROMs locs $4005AE…$4005BB.
lea EMT1010,A0 ; default dispatcher (cpuflag=0)
beq.s @kludge ; br if 680000
lea ATrap68020,a0 ; otherwise use the 68020 dispatcher
@kludge move.l a0,Line1010 ; install the Line-A exception handler
endif
InitDispatcher ; initialize / install the trap dispatcher
If &Type('NewBuildSystem') = 'Undefined' Then
NewBuildSystem Equ 0
Endif
If NewBuildSystem Then ; This is a temporary hack <SM5>.start
; initialize the trap dispatch tables
with ROMHeader
lea BadTrap,a4 ; a4 := trap handler for undefined A-Traps
move.l ROMBase,a3 ; a3 := address of ROM base
movea.l a3,a2 ; a2 := address of ROM base
add.l DispTableOff(a3),a2 ; a2 += dispatch table offset
; initialize ToolBox table
lea ToolTable,a1 ; a1 := ToolBox dispatch table ptr
move.w #numTbTrap-1,d0 ; d0 := loop counter for toolbox trap table
ToolLoop move.l (a2)+,d1 ; get the next entry from the ROM dispatch table
beq.s @BadTrap ; if zero then unused trap
@GoodTrap add.l a3,d1 ; add ROM base to offset
bra.s @Install ; install trap handler
@BadTrap move.l a4,d1 ; install bad trap handler
@Install move.l d1,(a1)+ ; install it into the ToolBox dispatch table
@NextEntry dbra d0,ToolLoop ; loop till end of table
; initialize OS table
if hasNewHeapMgr Then ; <MC2> SAM
With ProductInfo
BTST #hasNewMemMgr,UnivROMFlags ; Does this ROM support Figment?
BEQ.S @noFigment ; -> No. Don't bother w/PRAM
MOVEM.L A0-A3/D1/D3,-(SP) ; save regs
MOVEA.L UnivInfoPtr,a1 ; Get product info pointer
MOVEA.L A1,A0 ; Make a copy into A1
ADDA.L ProductInfo.DecoderInfoPtr(A1),A0 ; Get ptr to hardware bases
MOVE.L ProductInfo.ExtValid(A1),D1 ; Get external features (0-31)
MOVE.L #MMPRAMloc,D3 ; Read MMFlags from PRAM
LEA MMFlags,A3 ; A3 points to MMFlags lomem
BSR.L PramIO ; Get the current MMFlags
MOVEM.L (SP)+,A0-A3/D1/D3 ; restore regs
BTST #mmFigEnable,MMFlags ; Is Figment enabled for this boot?
BEQ.S @noFigment ; -> Nope. Use old MemMgr
ADD.L #numOSTrap*4,A2 ; Yes, skip to second table
EndWith
endif
@noFigment lea OSTable,a1 ; a1 := OS dispatch table ptr
move.w #numOsTrap-1,d0 ; d0 := loop counter for toolbox trap table
OSLoop move.l (a2)+,d1 ; get the next entry from the ROM dispatch table
beq.s @BadTrap ; if zero then unused trap
@GoodTrap add.l a3,d1 ; add ROM base to offset
bra.s @Install ; install trap handler
@BadTrap move.l a4,d1 ; install bad trap handler
@Install move.l d1,(a1)+ ; install it into the OS dispatch table
@NextEntry dbra d0,OSLoop ; loop till end of table
Else ;Not NewBuildSystem ; This is a temporary hack <SM5>.end
; setup registers
lea BadTrap,a4 ; a4 := trap handler for undefined A-Traps
movea.l ROMBase,a3 ; a3 := absolute address of base of ROM
movea.l a3,a2 ; a2 := trap handler address (start at ROMBase)
lea ToolTable,a1 ; a1 := RAM based dispatch table ptr (ToolBox first)
movea.l a3,a0 ; a0 := ROM based encoded dispatch table ptr
adda.l ROMHeader.DispTableOff(a0),a0 ; add offset stored in ROM by PostLinker <1.3>
moveq.l #$7F,d2 ; d2 := constant $7F for masking
move.w #numTbTrap-1,d0 ; d0 := loop counter for toolbox trap table
; initialize the RAM based dispatch tables
@TablesLoop move.b (a0)+,d1 ; get next byte from encoded ROM table
bmi.s @notSignedWord ; signed word offsets have high bit cleared
lsl.w #8,d1 ; position high byte, make room for low byte
move.b (a0)+,d1 ; insert the low byte
@DoubleOffset
add.w d1,d1 ; double it to form 16 bit even signed offset
beq.s @TablesDone ; an offset of zero terminates the loop
adda.w d1,a2 ; add offset to previous trap handler address
@WriteEntry move.l a2,(a1)+ ; install it into the RAM based dispatch table
@nextEntry dbra d0,@TablesLoop ; loop through the Toolbox table, and then OsTable
; end of ToolBox table, switch to OsTable, and continue until end of ROM table found
lea OSTable,a1 ; a1 := RAM based dispatch table ptr (OSTalbe last)
bra.s @TablesLoop ; loop through OSTable (loop count = $FFFF from DBRA)
@notSignedWord
and.w d2,d1 ; clear high bits, check for $80
beq.s @unused ; $80 indicated unused trap number
cmp.w d2,d1 ; check for $FF (which is now $7F)
bne.s @DoubleOffset ; if $81…$FE, low 7 bits are positive offset
; $FF indicates that a 4 byte absolute (from ROMBase) offset follows
movea.l (a0)+,a2 ; get the offset
adda.l a3,a2 ; add in ROMBase
bra.s @WriteEntry ; write out the table entry
; $80 indicates that the trap number for this entry is undefined
@unused move.l a4,(a1)+ ; install bad trap handler (dont change prev handler addr)
bra.s @nextEntry ; go on the next table entry
@TablesDone
EndIf ; Not NewBuildSystem
; now install the trap dispatcher
lea EMT1010,a0 ; point to the dispatcher
TestFor has68kEmulator ; Are we emulating a 68020? <SM7> SAM
beq.s @noEmu ; -> Nope. <SM7>
lea Rts020Disp,A1 ; Point A1 to an rts (hopefully near some cache resident code) <SM7>
bra.s @StuffFlush ; -> Install it <SM7>
@noEmu cmpi.b #cpu68040,CpuFlag ; check if we need to install 040 Cache Flush routine <3>
bne.s @notAn040 ; NO ... perform 020/030 cache-flush <3>
lea vCacheFlush68040,a1 ; YES ... get addr. of 040 cache flush routine <3>
@StuffFlush move.l a1,jCacheFlush ; ... and install it <3>
@notAn040 ; <3>
move.l a0,Line1010 ; install the Line-A exception handler
IF forRomulator THEN ; register the Line-A handler with the nub <SM6>
movec vbr,a0 ; |
movea.l ResetPC(a0),a0 ; v
cmpi.l #'nver',2(a0) ; does nub have a version number?
bne.s @skipLog ; no, then don't do this…
cmpi.w #$0120,6(a0) ; else check the version number
blo.s @skipLog ; if version too low, then bail…
adda.l $0A(a0),a0 ; get nub logging routine address from vect table
tst.l (a0) ; be paranoid
beq.s @skipLog ; bail if vector is null
jsr (a0) ; call nub supplied routine (finally) ^
@skipLog ; |
ENDIF ; forRomulator <SM6>
rts ; A-Trap dispatcher is now initialized
;_______________________________________________________________________
; BadTrap: receiver for unimplemented core routines.
; Destroys D0
; Called by default routine for unimplemented routines.
;_______________________________________________________________________
BadTrap
movem.l d0-d7/a0-a7,SEVars ; save regs in debugger space
moveq.l #dsCoreErr,d0 ; get DS alert ID for bad traps
jmp SysErr1 ; invoke the DS manager
; <SM4> rb, start from PatchProtector.a
TrapAddressBits proc export
; TrapAddressBits
;
; In:
; d0.w trap number
; d1.w [GS]etTrapAddress trap word
;
; Out:
; d1.w (modified) [GS]etTrapAddress trap word
; ccr CC if it is not a come-from, CS if it is a come-from
; bits in trap numbers and Set/GetTrapAddress opcodes
TrapNumber record 0
toolboxBit equ 11
endr
TrapAddressOpcode record 0
newBit equ 9
toolboxBit equ 10
endr
btst #TrapAddressOpcode.newBit,d1 ; is this N[GS]etTrapAddress?
bnz.s @notFullWord ; yes, dont handle it
btst #TrapAddressOpcode.toolboxBit,d1 ; is this normal [GS]etTrapAddress?
bz.s @notFullWord ; yes, dont handle it
@fullWord
; adjust the trap bits
bset #TrapAddressOpcode.newBit,d1 ; is this NGetTrapAddress?
btst #TrapNumber.toolboxBit,d0 ; is the trap a Toolbox trap?
bnz.s @toolbox ; yes, leave the bit set
bclr #TrapAddressOpcode.toolboxBit,d1 ; clear bit for OS
@toolbox
cmp.w #$C000,d0 ; is this a come-from trap word?
blo.s @notComeFrom ; no, it is not
cmp.w #$D000,d0 ; is it a come-from trap word?
bhs.s @notComeFrom ; no, it is not
@comeFrom
; oooh... carry is set for us, we can return
rts
@notFullWord
@notComeFrom
and #$FE,ccr ; clear the carry bit
rts
endproc
; <SM4> rb, end
end