mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-25 09:30:50 +00:00
580 lines
24 KiB
Plaintext
580 lines
24 KiB
Plaintext
;
|
|
; File: MMU.a
|
|
;
|
|
; Contains: MMU setup and manipulation routines
|
|
;
|
|
; Written by: Bob Herold
|
|
;
|
|
; Copyright: © 1986-1993 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM11> 8/4/93 JDR private sound defines are in SoundPrivate.a
|
|
; <SM10> 12/4/92 SWC Moved SwitchMMU here from StartInit.a.
|
|
; <SM9> 11/13/92 rab Roll in Horror changes. Comments follow:
|
|
; <H4> 7/13/92 NJV Modified Swap030 to not flush the ATC (used pmovefd instead of
|
|
; pmove) when resetting the TTx registers.
|
|
; <SM8> 8/20/92 CCH Removed hack for swapping MMU on Cub Card.
|
|
; <SM7> 8/19/92 CSS Update from Reality:
|
|
; <31> 8/18/92 DTY Change the name of BootGlobs to StartGlobals to avoid confusion
|
|
; with BootGlobals, which is used by the boot code in Boot[1-3].a.
|
|
; <SM6> 7/13/92 CCH Added conditionalized support for Cub Card on Quadra 700.
|
|
; <SM5> 5/17/92 kc Roll in Horror sources. Moved Tables to MMUTables.
|
|
; <H6> 5/24/91 CCH Flushed the ATC entries in SwapMMUMode.
|
|
; <H5> 2/25/91 CCH Fixed a two-instruction window in Swap040 when MMU32Bit is set
|
|
; before the MMU is swapped, and interrupts are still enabled.
|
|
; <H4> 1/24/91 CCH Fix bug where MMUType is not set up correctly in 32-bit mode.
|
|
; <H3> 9/13/90 CCH Shrunk padding size to make room for StartInitPatch.a.
|
|
; <H2> 9/5/90 CCH Added 68040 MMU swap routine in.
|
|
; <5> 5/14/90 CV Adding tables and additional support code to allow video to
|
|
; operate in slot E for Erickson. Split the file in two since it
|
|
; grew with the addition of the slot E support. The remainder of
|
|
; MMU.a is in MMUTables.a.
|
|
; <4> 4/30/90 JJ Changed FindInfo handling of VISA to compute correct video
|
|
; buffer size.
|
|
; <3> 3/12/90 CV Rolling in changes from mainproj. Original comments below.
|
|
; {6} 2/9/90 JJ Added VISA to set of "MMU" types supported by GetMMUType and
|
|
; FindInfo.
|
|
; <2> 2/13/90 CV Rolling in changes from Reality. Original comments below.
|
|
; {5} 2/4/90 GMR Made StartReadPRAM call new routine to read the PRAM byte
|
|
; universally, at least until diagnostics rev their RdXByte
|
|
; routine to work with Egret.
|
|
; <3.8> 9/21/89 SWC Played with padding so entry points line up.
|
|
; <3.6> 7/16/89 CSL Rolling Reality source for Aurora. Original Reality version is
|
|
; 3.6,3.7. Original 3.6,3.7 comments are below:
|
|
; <3.5> 6/29/89 rwh NEEDED FOR AURORA: for Glu chip, fix bug for weird RAM
|
|
; configurations on 030, and fix comments. Changed HMMU/851
|
|
; detection to work w/only Bank B.
|
|
; <3.4> 6/28/89 GGD Moved the TestInRAM macro here, from HardwareEqu, until we
|
|
; figure out what to do about it, since CCH said that nothing uses
|
|
; it anymore, but this code does.
|
|
; <3.3> 6/27/89 rwh NEEDED FOR AURORA: eliminate bogus video entries in F19
|
|
; physicalTable
|
|
; <3.2> 6/27/89 rwh NEEDED FOR AURORA: changes to get FMC rev 2 working. Made
|
|
; onboard video wrap both before AND AFTER the real video buffer.
|
|
; Changed MMUError error codes.
|
|
; <3.1> 6/12/89 rwh added MMUCleanupFor8Mb to copy MMU config info below BufPtr when
|
|
; booting 24 bit OS w/ more than 8 mb RAM.
|
|
; <3.0> 6/12/89 djw Pass prodInfoPtr to GetRBVSize in FindInfo
|
|
; <2.9> 6/11/89 rwh Romulator™ changes: make physical table entry point to ram-based
|
|
; ROM image, peg top logical memory to just below ROM image. Code
|
|
; review doc changes. Changed video slot alias to slot B. Made
|
|
; GetMMUType use vbr to not depend on Bank A being present.
|
|
; <2.8> 6/11/89 GMR Changed call to RdXByte to be a BigBSR6, so it'll reach.
|
|
; <2.7> 6/2/89 rwh removed uneeded equates. Made size field of template a longword,
|
|
; to allow video wrap < 64k. Changed to use new ASC register
|
|
; equates in SwapHmmu. Made physical table have EXACT onboard
|
|
; video buffer size. Added support for upper limits. Changed video
|
|
; wrap to 1st page of buffer, not last page. Removed cache inhibit
|
|
; for RBV video buffer.
|
|
; <2.6> 5/30/89 rwh improved '851 support - use shared global entries. Make mmu
|
|
; enable code more robust.
|
|
; <2.5> 5/30/89 rwh added support for physical table (for VM, Pink/Opus, A/UX etc)
|
|
; <2.4> 5/26/89 rwh Moved ConfigureRam to StartInit. Fixed support for big void in
|
|
; logical space above lowmem (the 'black hole').
|
|
; <2.3> 5/26/89 GGD Changed label names to avoid conflict between GLU and FMC code.
|
|
; Dropped the .S from several branches to fix assembly errors when
|
|
; has both Mac2Via2 and FMC. Branched through a branch so that
|
|
; short branches could reach. Changed HMMU detection to use VIA2
|
|
; instead of VIA1. Corrected branch condition in HMMU detection.
|
|
; <2.2> 5/16/89 rwh added support for big void in logical space above lowmem, so
|
|
; that system and app heaps can start at $38000000 in 32 bit mode.
|
|
; Improved NuMac support.
|
|
; <2.1> 5/14/89 rwh for RBV 32 bit mode map, made space just below video buffer wrap
|
|
; to top of video buffer. Fixes bus error when quickdraw accesses
|
|
; below video buffer.
|
|
; <2.0> 5/14/89 rwh rewrote for universal ROM - now we have one routine that can set
|
|
; up MMU tables for any machine. SwapMMU trap is now set up at
|
|
; runtime to use code specific to the type of MMU.
|
|
; <1.9> 5/10/89 CCH Changed code that swaps the mmu to make sure PMOVE instructions
|
|
; are in the cache when running in RAM.
|
|
; <1.8> 4/27/89 CCH Added code so that the MMU mode can be swapped while running in
|
|
; logical address space, on both the 68851 and the 68030, for
|
|
; NuMac builds only.
|
|
; <1.7> 4/18/89 CCH Added some changes for Rom in Ram to work on the Mac II.
|
|
; <1.6> 3/22/89 CSL Conditional SwapMMu32only for is32BitClean only.
|
|
; <1.5> 3/22/89 CSL Added new routine SwapMMu32only, this is to replace SwapMMUMode
|
|
; when the system is running 32 bit mode only.
|
|
; <1.4> 2/17/89 rwh changes (hacks!) to make MvMac assemble w/o mac2via2
|
|
; <1.3> 2/16/89 rwh added support for Fitch Memory Controller rev 1. When FMC2
|
|
; arrives, remove these changes.
|
|
; <1.2> 1/23/89 CSL Change MMU_Init to support dynamic generation of MMU table.
|
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
;
|
|
; <1.5> 10/6/88 rwh changed 'hasMac2Via2' (from v1.4) to ¬hasRBV. Later we should
|
|
; make these things selected at runtime.
|
|
; <1.4> 10/5/88 CSL added support for RBV and MDU.
|
|
; <•1.3> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|
; <1.2> 9/22/88 CCH changed "xhardwareEqu.a" to "HardwareEqu.a"
|
|
; <1.1> 9/9/88 rwh Rewritten top to bottom for Mac IIx. Now have separate low memory
|
|
; globals for 24 & 32 bit mode. Global points to table that has
|
|
; the CRP and TC value for that mode. This allows us to dynamically
|
|
; switch to new tables. (This version rolled in from Mac IIx sources)
|
|
; <1.0> 2/10/88 BBM Adding file for the first time into EASE…
|
|
;
|
|
; To Do:
|
|
;
|
|
; implement lower limits (bell & whistle...)
|
|
|
|
|
|
PRINT OFF
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'HardwarePrivateEqu.a'
|
|
INCLUDE 'SoundPrivate.a'
|
|
INCLUDE 'MMUEqu.a'
|
|
INCLUDE 'BootEqu.a'
|
|
INCLUDE 'UniversalEqu.a'
|
|
PRINT ON
|
|
|
|
MACHINE MC68030
|
|
MMUStuff PROC
|
|
EXPORT InitMMUGlobals, InitMMUTrap, MMUCleanupFor8Mb, SwitchMMU
|
|
IMPORT BaseOfROM, Critical, PramIO, RamTest
|
|
IMPORT RomLoc
|
|
|
|
WITH StartGlobals ; <SM7>
|
|
WITH MMUConfigInfo
|
|
|
|
|
|
;-----
|
|
; InitMMUTrap - set up trap addres for SwapMMUMode
|
|
;
|
|
; Entry
|
|
; jSwapMMU points to correct SwapMMUMode routine
|
|
;
|
|
; Exit
|
|
; trap address points where jSwapMMU points
|
|
;---
|
|
|
|
InitMMUTrap
|
|
move.l jSwapMMU,a0 ; point to SwapMMUMode routine
|
|
move.w #$A05D,d0 ; get trap #
|
|
_SetTrapAddress ,NEWOS ; fix trap address
|
|
rts
|
|
|
|
|
|
;-----
|
|
; InitMMUGlobals - set up vectors & lowmem for SwapMMUMode
|
|
;
|
|
; Entry
|
|
; BootGlobPtr points to BootGlobs
|
|
; System is in 32 bit mode
|
|
;
|
|
; Exit
|
|
; MMUFlags (byte) cleared to zero (all flags reset)
|
|
; MMUType (byte) has type of MMU
|
|
; MMUMode (byte) has 1, indicating its in 32 bit mode
|
|
; MMU24Info (long) points to 24 bit mode MMU configuration info.
|
|
; MMU32Info (long) points to 32 bit mode MMU configuration info.
|
|
;
|
|
; Trashes
|
|
; d0/a0-a1
|
|
;---
|
|
|
|
InitMMUGlobals
|
|
move.l BootGlobPtr,a1 ; get ptr to boot globals at top of RAM
|
|
clr.b MMUFlags ; clear the flags byte
|
|
move.b #true32b,MMU32bit ; signal in 32 bit mode
|
|
lea sg32Info(a1),a0 ; get addr 32 bit mode info <SM7> CSS
|
|
move.l a0,MMU32Info ; save it in lowmem
|
|
lea sg24Info(a1),a0 ; get addr 24 bit mode info <SM7> CSS
|
|
move.l a0,MMU24Info ; save it in lowmem
|
|
moveq #0,d0 ; clear a reg
|
|
move.b sgTypeMMU(a1),d0 ; get type of MMU <SM7> CSS
|
|
move.b d0,MMUType ; save MMU type in lowmem
|
|
btst.b #MMStartMode,sgMMFlags(a1); check memory manager start mode <SM7> CSS
|
|
beq.s @findSwap ; IF its 32 bit mode only
|
|
lea Swap32Only,a0 ; get ptr to null swap routine
|
|
bra.s @gotSwap ; ...
|
|
@findSwap ; ELSE
|
|
move.w @swaps(d0.w*2),d0 ; get offset to swap routine
|
|
lea @swaps(d0),a0 ; get ptr to swap routine
|
|
@gotSwap ; ENDIF
|
|
move.l a0,jSwapMMU ; init jump vector
|
|
@NoSwap rts
|
|
|
|
@swaps dc.w @NoSwap-@swaps ; No MMU: no swap routine!
|
|
dc.w SwapHMMU-@swaps ; offset to HMMU swap routine
|
|
dc.w @NoSwap-@swaps ; MMB not supported: no swap routine!
|
|
dc.w Swap851-@swaps ; offset to 68851 PMMU swap routine
|
|
dc.w Swap030-@swaps ; offset to 030 PMMU swap routine
|
|
dc.w Swap040-@swaps ; offset to 040 PMMU swap routine <T2>
|
|
dc.w @NoSwap-@swaps ; future expansion
|
|
dc.w @NoSwap-@swaps ; future expansion
|
|
|
|
;----- <3.1>
|
|
; MMUCleanupFor8Mb - copies MMU info (tc, crp, tt0, tt1) to below BufPtr.
|
|
;
|
|
; This is called on systems supporting 24 bit mode that have more than 8mb of RAM
|
|
; installed. The MMU info must be at a place that can be accessed in 24 bit mode,
|
|
; since the Swap MMU code must access it!
|
|
;
|
|
; Entry
|
|
; System is in 32 bit mode
|
|
; MMU24Info (long) points to 24 bit mode MMU configuration info in BootGlobs
|
|
; MMU32Info (long) points to 32 bit mode MMU configuration info in BootGlobs
|
|
; Exit
|
|
; MMU24Info (long) points to 24 bit mode MMU configuration info below BufPtr
|
|
; MMU32Info (long) points to 32 bit mode MMU configuration info below BufPtr
|
|
;
|
|
; Trashes
|
|
; d0/a0-a2
|
|
;---
|
|
|
|
WITH MMUConfigInfo
|
|
|
|
MMUCleanupFor8Mb
|
|
move.l BufPtr,a0 ; get top useable memory
|
|
suba.w #2*MMUInfoSize,a0 ; allocate space for config info
|
|
move.l a0,BufPtr ; update top useable memory
|
|
lea MMU32Info,a1 ; point at ptr to 32 bit mode info
|
|
bsr.s @doCopy ; copy it down
|
|
lea MMU24Info,a1 ; point at ptr to 32 bit mode info
|
|
@doCopy move.l (a1),a2 ; get ptr to info in BootGlobs
|
|
move.l a0,(a1) ; update ptr w/new stuff below BufPtr
|
|
moveq #MMUInfoSize-1,d0 ; loop counter
|
|
@copy move.b (a2)+,(a0)+ ; copy next byte
|
|
dbra d0,@copy ; repeat for all bytes
|
|
rts
|
|
|
|
ENDWITH ; {MMUConfigInfo}
|
|
|
|
;-----
|
|
; Swap32Only - null MMU swap, used when system has 32 bit addressing only
|
|
;
|
|
; Entry:
|
|
; d0.b 0 to set 24-bit mode, non-zero to set 32-bit mode.
|
|
;
|
|
; Exit:
|
|
; MMU32Bit no change
|
|
; d0.l always 1
|
|
;---
|
|
|
|
Swap32Only
|
|
moveq #1,D0 ;always return 32 bit
|
|
rts
|
|
|
|
|
|
;-----
|
|
; Swap851 - switches 68851 PMMU between 24 & 32 bit modes.
|
|
;
|
|
; Entry
|
|
; d0.b 0 to set 24-bit mode, non-zero to set 32-bit mode.
|
|
;
|
|
; Exit
|
|
; MMU32Bit updated with passed value of d0
|
|
; d0.l has previous value of MMU32Bit
|
|
; MMU is switched into the desired mode
|
|
;
|
|
; Trashes:
|
|
; d1/a0/a1
|
|
;---
|
|
|
|
Swap851 move.b d0,d1 ; check what mode we are going to, set up d1
|
|
bne.s @to32 ; IF we want 24 bit mode
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
beq.s @endif ; IF in 32 bit mode now
|
|
move sr,-(sp) ; save current interrupt status
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
move.l MMU24Info,a0 ; get ptr to 24 bit mode info
|
|
bra.s @swap ; go to common swap code
|
|
; ENDIF
|
|
@to32 ; ELSE (we want 32 bit mode)
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
bne.s @endif ; IF in 24 bit mode
|
|
move sr,-(sp) ; save current interrupt status
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
move.l MMU32Info,a0 ; get ptr to 32 bit mode info
|
|
|
|
IF forRomulator THEN ; Assume logical PC <> physical PC <3.7>
|
|
|
|
@swap moveq.l #1,d0 ; unset zero flag <3.7>
|
|
bra.s @doSwap ; go put PMOVE to TC into i-cache <3.7>
|
|
@inCache moveq.l #0,d0 ; set zero flag <3.7>
|
|
pmove theCRP(a0),CRP ; set the root pointer <3.7>
|
|
lea theTC(a0),a1 ; get address of TC <3.7>
|
|
bra.s @doSwap ; go swap modes from i-cache <3.7>
|
|
|
|
; NOTE: the following instructions are put <3.7>
|
|
; . in the i-cache, thus the 4 byte instructions<3.7>
|
|
; . to be executed must start on odd word <3.7>
|
|
; . boundaries so that they are put in on the <3.7>
|
|
ALIGN 4 ; . first pass through <3.7>
|
|
@doSwap bne.s @step ; (2 bytes) if zero flag not set, skip pmove <3.7>
|
|
pmove theCRP(a0),TC ; (4 bytes) disable the 851 <3.7>
|
|
; NOTE: the 851 must be disabled before <3.7>
|
|
; . the TC can be changed. The CRP always <3.7>
|
|
; . has the high bit off, and can be used to <3.7>
|
|
; . disable MMU. Also note that "theCRP" is <3.7>
|
|
; . zero, causing this instruction to be 4 bytes<3.7>
|
|
@step nop ; (2 bytes) force next inst to start on odd word<3.7>
|
|
bne.s @chk ; (2 bytes) if zero flag not set, skip pmove <3.7>
|
|
pmove (a1),TC ; (4 bytes) fire up new TC, flush ATC <3.7>
|
|
@chk beq.s @swapped ; (2 bytes) if zero flag set, we're done <3.7>
|
|
bra.s @inCache
|
|
@swapped ; <3.7>
|
|
|
|
ELSE ; <3.7>
|
|
|
|
@swap pmove theCRP(a0),tc ; disable the MMU so we can load a new TC value <3.8>
|
|
pmove theCRP(a0),crp ; set crp
|
|
@thePmove pmove theTC(a0),tc ; fire up the TC
|
|
|
|
ENDIF
|
|
pflusha ; clean out dirty ATC entries
|
|
move.b d1,MMU32Bit ; update global w/new mode flag
|
|
movec cacr,d1 ; get cache control register
|
|
ori.w #$0008,d1 ; set i-cache 'flush' bit
|
|
movec d1,cacr ; flush instruction caches
|
|
move (sp)+,sr ; restore interrupt mask
|
|
; ENDIF
|
|
@endif ; ENDIF
|
|
rts
|
|
|
|
;-----
|
|
; Swap030 - switches 030 PMMU between 24 & 32 bit modes.
|
|
;
|
|
; Entry
|
|
; d0.b 0 to set 24-bit mode, non-zero to set 32-bit mode.
|
|
;
|
|
; Exit
|
|
; MMU32Bit updated with passed value of d0
|
|
; d0.l has previous value of MMU32Bit
|
|
; MMU is switched into the desired mode
|
|
;
|
|
; Trashes:
|
|
; d1/a0
|
|
;---
|
|
|
|
Swap030 move.b d0,d1 ; check what mode we are going to, set up d1
|
|
bne.s @to32 ; IF we want 24 bit mode
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
beq.s @endif ; IF in 32 bit mode now
|
|
move.l MMU24Info,a0 ; get ptr to 24 bit mode info
|
|
bra.s @swap ; go to common swap code
|
|
; ENDIF
|
|
@to32 ; ELSE (we want 32 bit mode)
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
bne.s @endif ; IF in 24 bit mode
|
|
move.l MMU32Info,a0 ; get ptr to 32 bit mode info
|
|
@swap move sr,-(sp) ; save current interrupt status
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
ploadr #5,theTC(a0) ; ensure that tc load won't cause table walk
|
|
; NOTE: following 2 instr's must not cross
|
|
; . a page boundary, or table walk will occur
|
|
; . with crp & tc in an inconsistent state
|
|
pmovefd theTT0(a0),tt0 ; load the transparent translation regs <H4><SM9>
|
|
pmovefd theTT1(a0),tt1 ; . BEFORE we swap modes! <H4><SM9>
|
|
pmovefd theCRP(a0),crp ; set crp, keep ATC cool for next instrunction
|
|
pmove theTC(a0),tc ; fire up the TC, flush ATC
|
|
move.b d1,MMU32Bit ; update global w/new mode flag
|
|
movec cacr,d1 ; get cache control register
|
|
ori.w #$0808,d1 ; set 'flush' bits
|
|
movec d1,cacr ; flush both caches
|
|
pflusha ; flush the ATC entries <T6>
|
|
move (sp)+,sr ; restore interrupt mask
|
|
; ENDIF
|
|
@endif ; ENDIF
|
|
rts
|
|
|
|
|
|
;-----
|
|
; Swap040 - switches 040 PMMU between 24 & 32 bit modes. <7>
|
|
;
|
|
; Entry
|
|
; d0.b 0 to set 24-bit mode, non-zero to set 32-bit mode.
|
|
;
|
|
; Exit
|
|
; MMU32Bit updated with passed value of d0
|
|
; d0.l has previous value of MMU32Bit
|
|
; MMU is switched into the desired mode
|
|
;
|
|
; Trashes:
|
|
; d1/a0
|
|
;---
|
|
|
|
machine mc68040
|
|
|
|
Swap040 move.b d0,d1 ; check what mode we are going to, set up d1
|
|
bne.s @to32 ; IF we want 24 bit mode
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
beq.s @endif ; IF in 32 bit mode now
|
|
move.l MMU24Info,a0 ; get ptr to 24 bit mode info
|
|
bra.s @swap ; go to common swap code
|
|
; ENDIF
|
|
@to32 ; ELSE (we want 32 bit mode)
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
bne.s @endif ; IF in 24 bit mode
|
|
move.l MMU32Info,a0 ; get ptr to 32 bit mode info
|
|
@swap move sr,-(sp) ; save current interrupt status <T5>
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
move.b d1,MMU32Bit ; update global w/new mode flag
|
|
move.l theTT0(a0),d1 ; get transparent translation reg 0 value
|
|
movec d1,itt0 ; load the instruction TT0 reg
|
|
movec d1,dtt0 ; load the data TT0 reg with the same value
|
|
move.l theTT1(a0),d1 ; get transparent translation reg 1 value
|
|
movec d1,itt1 ; load the instruction TT0 reg
|
|
movec d1,dtt1 ; load the data TT0 reg with the same value
|
|
move.l theTC(a0),d1 ; get the TC value in d1
|
|
move.l theSRP(a0),a0 ; get the SRP value in a0
|
|
movec a0,SRP ; set the SRP with new pointer
|
|
movec d1,TC ; set the TC with the new value
|
|
pflusha ; flush the ATC entries <T6>
|
|
move (sp)+,sr ; restore interrupt mask
|
|
; ENDIF
|
|
@endif ; ENDIF
|
|
rts
|
|
|
|
machine mc68030 ;
|
|
|
|
;-----
|
|
; SwapHMMU - switches HMMU between 24 & 32 bit modes.
|
|
;
|
|
; This routine has a fix for the problem of losing sound interrupts when switching
|
|
; MMU modes. On HMMU Mac II's, a bit on Via2 portB switches the MMU mode.
|
|
; Unfortunately, hitting this bit clears the CB1 interrupt flag, which is
|
|
; the ASC interrupt.
|
|
;
|
|
; Since the interrupt handlers all call SwapMMUMode to switch into 24 bit mode
|
|
; before processing interrutps, an ASC interrupt that occurs after the
|
|
; original interrupt could be lost.
|
|
;
|
|
; This routine reduces the window for losing ASC interrupts to the minimum
|
|
; possible, which is half an instruction. After switching MMU modes,
|
|
; it checks the ASC's interrupt register, and if any interrupts are present
|
|
; (but lost because the CB1 flag was cleared), it OR's the interrupt register back
|
|
; to itself. The ASC then generates a new interrupt.
|
|
;
|
|
; Entry
|
|
; d0.b 0 to set 24-bit mode, non-zero to set 32-bit mode.
|
|
;
|
|
; Exit
|
|
; MMU32Bit updated with passed value of d0
|
|
; d0.l has previous value of MMU32Bit
|
|
; MMU is switched into the desired mode
|
|
;
|
|
; Trashes:
|
|
; d1/a0
|
|
;---
|
|
|
|
SwapHMMU
|
|
move.b d0,d1 ; check what mode desired, save it
|
|
bne.s @1 ; IF we want 24 bit mode
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see what mode we're in now
|
|
beq.s @3 ; IF in 32 bit mode now
|
|
move sr,-(sp) ; save current interrupt status
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
move.l VIA2RBV,a0 ; get ptr to 2nd Via
|
|
bclr #vFC3,vBufB(a0) ; throw us into 24 bit mode
|
|
bra.s @common ; (re-use common code)
|
|
@1 ; ELSE (we want 32 bit mode)
|
|
moveq #0,d0 ; clear return register
|
|
move.b MMU32bit,d0 ; see (and return) what mode we're in now
|
|
bne.s @3 ; IF in 24 bit mode now
|
|
move sr,-(sp) ; save current interrupt status
|
|
ori #HiIntMask,sr ; disable interrupts during switch
|
|
move.l VIA2RBV,a0 ; get ptr to 2nd Via
|
|
bset #vFC3,vBufB(a0) ; throw us into 32 bit mode
|
|
@common move.b d1,MMU32Bit ; update global w/new mode flag
|
|
movec cacr,d1 ; get cache control register
|
|
bset #3,d1 ; set icache flush bit
|
|
movec d1,cacr ; flush da cache, Guido
|
|
move.l ASCBase,a0 ; point to ASC
|
|
adda.w #ascFifoInt,a0 ; point to ASC interrupt register
|
|
move.b (a0),d1 ; get ASC interrupt register
|
|
beq.s @2 ; IF ASC thinks interrupt is pending
|
|
or.b d1,(a0) ; re-generate interrupt to VIA's CB1
|
|
@2 ; ENDIF
|
|
move (sp)+,sr ; restore interrupt mask
|
|
; ENDIF
|
|
@3 ; ENDIF
|
|
rts
|
|
|
|
|
|
;---------------------------------------------------
|
|
; MMU switch code, for Unix & Pink.
|
|
;
|
|
; Turns off the MMU, flushes ATC, then re-enables the MMU with passed info.
|
|
;
|
|
; Entry:
|
|
; a0 - physical address of MMUConfigInfo record (accessed w/MMU turned off)
|
|
; a1 - return address (used after MMU has been turned on w/new configuration)
|
|
;
|
|
; Trashes d0, d1, a2
|
|
;
|
|
; The 040 MMU/Cache accessed differently than 020/030
|
|
;
|
|
; 040 CACR looks like: 040 TC looks like:
|
|
; +--------------------------+ +--------------------------------+
|
|
; | DE | 0...0 | IE | 0...0 | | Enable | PageSize | .... |
|
|
; +--------------------------+ +--------------------------------+
|
|
; 31 15 0 15 14 <Reserved> 0
|
|
;
|
|
; DE Data Cache Enable Enable Enable Address Translations ( = 1 )
|
|
; IE Instruction Cache Enable PageSize Memory page size ( 0 = 4K, 1 = 8K )
|
|
;
|
|
;---------------------------------------------------
|
|
|
|
SwitchMMU
|
|
|
|
@TestCPU sub.l d0,d0 ; D0 = 0
|
|
bset #CACR_DE_040,d0 ; set Data Cache Enable bit on 040s <T22>
|
|
movec d0,CACR ; attempt to enable data cache (temporarily)
|
|
movec CACR,d0 ; check and see if it's still there
|
|
btst #CACR_DE_040,d0 ; see if the bit exists in CACR <T22>
|
|
beq.s @isNot040
|
|
|
|
|
|
MACHINE MC68040 ; IF we're on a 68040 THEN
|
|
|
|
@is040 movec CACR,d0 ; retrieve cache control register
|
|
move.l d0,d1 ; save a copy for later restoration
|
|
sub.l d0,d0 ; clear D0 to disable caches (see diagram above)
|
|
movec d0,CACR ; disable both caches
|
|
movec d0,TC ; disable the ATC
|
|
pflusha ; flush ATC
|
|
movea.l theCRP(a0),a2 ; retrieve the new CRP (= URP on the 040) into D0
|
|
move.l theTC(a0),d0 ; retrieve the new TC into D0
|
|
movec a2,URP ; set up the URP
|
|
movec d0,TC ; ... and the TC
|
|
cpusha bc ; flush both caches (dirty data only pushed out of
|
|
; the data cache. inst. cache CPUSH = CINV)
|
|
movec d1,cacr ; re-enable caches
|
|
bra.s @allDone
|
|
|
|
MACHINE MC68030 ; ELSE we're on a 68030/68020
|
|
|
|
@isNot040 movec cacr,d0 ; get 020/030 cache control reg
|
|
move.w d0,d1 ; save it
|
|
andi #$FEFE,d0 ; clear cache enable bits
|
|
movec d0,cacr ; disable instruction/data caches
|
|
lea TCOff,a2 ; point at a TC=0
|
|
pmove (a2),tc ; turn off the MMU
|
|
pflusha ; flush translation cache
|
|
pmove theCRP(a0),crp ; set up the crp
|
|
pmove theTC(a0),tc ; and the tc
|
|
ori.w #$0808,d1 ; set the flush bits in old cache control reg
|
|
movec d1,cacr ; re-enable & flush caches
|
|
|
|
|
|
@allDone jmp (a1) ; back to the regularly scheduled program
|
|
|
|
TCOff dc.l 0 ; for turning off MMU
|
|
|
|
|
|
ENDWITH ; {MMUConfigInfo}
|
|
ENDWITH ; {BootGlobs}
|
|
|
|
ENDPROC
|
|
END
|
|
|
|
|