mirror of
https://github.com/elliotnunn/boot3.git
synced 2024-12-31 23:29:50 +00:00
5b0f0cc134
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
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
|
|
|
|
|