supermario/base/SuperMarioProj.1994-02-09/OS/MMU/MMUTables.a
2019-06-29 23:17:50 +08:00

4390 lines
181 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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: MMUTables.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):
;
; <SM23> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
; machines.
; <SM22> 11/12/93 SAM Roll in <MC3> from mc900ftjesus.
; <MC3> 11/12/93 SAM For EMMU machines get the EDisk size from beyond the chunk table
; (see SizeMem for details).
; <SM21> 11/10/93 fau Update from SuperMunggio <SMG2>.
; <SMG2> 8/27/93 fau Added a HHead entry to the table of decoders.
; <SM20> 11/10/93 SAM Roll in <MC2> from mc900ftjesus.
; <MC2> 11/10/93 SAM We now enforce the upper limit top the EDisk. Currently its set
; to 255 MB.
; <SM19> 3/31/93 chp Synchronize SuperMario with changes from <LW2>. Also modify
; early universal test for has68kEmulator: the constant for this
; test must be modulo 8 and it is the individuals responsibility
; to look in the correct byte (TestFor is not available yet).
; <SM18> 3/11/93 SAM Added a flag to bootGlobs that tell this code whether or not to
; steal chunks of RAM for the EDisk. Added code to check that
; flag (sgEDiskStealFlag) instead of sgEDiskSize.
; <LW2> 2/26/93 fau Removed MMC support and changed all names including MMC to YMCA.
; <SM17> 2/5/93 SAM Added support for emulated MMUs.
; <SM16> 12/23/92 RC Added Support for Smurf on Wombat
; <SM15> 12/18/92 RB Updated the MSC MMUTables from Horror, since it was wrong.
; <SM14> 12/1/92 EH Added tables and code for Pratt Memory controller.
; <SM13> 11/13/92 rab Roll in Horror changes. Comments follow:
; <H32> 10/23/92 BG Changed MinBootGlobs to fix the Quadra 9x0 256MB + RAM Disk
; problem.
; <H31> 9/11/92 JC Conditionally add support for an 040 board on Vail.
; <H30> 8/10/92 NJV Added Double-Exposure support for Sonora 3.0.
; <H29> 7/24/92 NJV Fixed 2 ReAnimator bugs where addresses were being doubly
; corrected.
; <H28> 7/15/92 SWC Put the sound buffer size into the 24- and 32-bit size fields in
; its entry in the physical space table since VM was getting
; confused.
; <H27> 7/13/92 SWC Moved the code to move the RAM chunk table below a sound buffer
; (SkipSoundBuffer) to SizeMemPatch.a since when it was here, the
; warmstart flag would get trashed and so would the RAM disk.
; <H25> 7/6/92 SWC Fixed a couple of bugs in SkipSoundBuffer. If a sound buffer is
; present, we'll separate it out from other RAM in the physical
; space table so VM won't use it for paging.
; <H23> 6/23/92 SWC Modified MSC tables to use full page tables. Modified Dart's MMU
; tables to use the same setup (needed to tweak things a bit). Use
; TT0 for DBLite and Dartanian LCD video (we both use the same
; hardware), and TT1 for DBLite's slot space. Added a new routine,
; SkipSoundBuffer, to move the RAM chunk table down if there is a
; sound buffer in high RAM. Use a common equate, b32VidBase, to
; specify the base of a non-RBV video frame buffer (MSC and Sonora
; versions went away) since that part of the address space is
; supposed to be reserved for just that purpose.
; <H22> 6/3/92 HY Change ROM space for LC/Slice to 4mb. DblX slot space now 64k
; and the rest of I/O space is now mapped straight thru.
; Removed all mappings in MMU templates/physical templates for
; on-board video. Remove routine GetVisaSize (we don't support
; on-board video, so not needed). Add MMU entry for RAM disk.
; <H20> 5/28/92 BG Added Wombat memory information. As far as MMUs and memory
; mapping, it should look exactly the same as Orwell (Q700/9x0).
; <SM12> 11/10/92 GD Rolled in Niagra (for PowerBook) tables from Horror. Also fixed
; a "forRomulator" build issue.
; <SM11> 11/3/92 RB Changed the use of LC930 in the 24 bit mode support test to
; Supports24Bit
; <SM10> 10/30/92 RB On the LC930, do not force 32 bit mode, since it supports 24 bit
; mode.
; <SM9> 10/22/92 HY Change MMU tables for LC II/930 to support PDS flash. Also
; remove onboard video support, add EDisk entry, and reduce
; DblX range from 256k to 64k. Increase ROM size from 2 to 4Mb.
; <SM8> 10/18/92 CCH Added support for PDM and removed padding at the end.
; <SM7> 9/30/92 fau Added support for the new Cyclone EVT4 decoder, YMCA. It uses
; the same tables as the MMC, but it is a new entry in the
; DecoderKinds record.
; <SM6> 08/19/92 CSS BootGlobs was changed to StartGlobals by DTY in Reality and this file
; needs changing, also.
; <SM5> 08/11/92 jmp Added ReAnimator support for 030 machines (taken straight from
; Horror).
; <SM4> 8/9/92 CCH Added ReAnimator™ support for HMMU-based machines, and allow
; Orwell-based machines to have HMMUs.
; <SM3> 7/13/92 CCH Added conditionalized support for Cub Cards on Quadra 700.
; <SM1> 5/26/92 CSS Cyclone roll in.;
; <P13> 5/13/92 KW (HV,H18) Roll-in LC II changes. Add MMU templates for LC II,
; modify InitMMU routine so that the exception vector table
; contains logical instead of physical addresses, modify @VISA
; routine to load up A0 and A1 with MMU templates, and modified
; routine doPhysROM to build the ROM entries according to the way
; the physical templates are defined if the ROM physical size is
; not 256mb.
; (HJR,H17) Modified Niagra MMU Templates so that part of ROM is
; mapped to the end of Slot E space. This is in order to fake the
; Slot Manager into using part of the Main rom as the config ROM.
; It is necessary that if the location of VSCDeclData moves that
; the corresponding MMU Tables be updated. Updated physNiagra
; space table.
; <P12> 4/24/92 KW (JC,H16) Cleaned up Sonora Physical Space Tables.
; <P11> 4/16/92 KW (JC, H15) Cleaned up Sonora tables.
; (SWC, H14) Mucked around a bit more with the MSC tables.
; <P10> 04/16/92 jmp Replaced some hard-coded values with defined constants.
; <P9> 04/08/92 jmp Updated the physMMC table entries to more accurate reflect
; reality (I think).
; <P8> 03/22/92 jmp Removed the “isVoid” mappings for Slots A&B for MMC in 24-bit
; mode.
; <P7> 2/25/92 RMP Modified the 32-Bit MMC table to map in CIVIC register set and
; VRAM.
; <P6> 02/07/92 jmp (SWC,H13) Added entries to the MSC tables for slots C and D,
; which are available when DBLite is plugged into its docking
; station.
; (JC,H12) Add support for optionally using full page tables on
; 030 machines, modify Sonora Tables, and add support for
; alternate physical ROM address as defined in Universal Tables.
; (JC,H11) Change to fix Spike problem on Non Sonora builds.
; (JC,H10) Add support for Double Exposure for Vail as it was done
; on Foster Farms, and added support for the alternate ROM
; physical address defined in Universal Tables.
; <P5> 1/23/92 RMP Hand map slot 9 for MMC table in 24 bit mode (is 2nd half of
; 2-Meg ROM).
; <P4> 1/22/92 RMP Added MMC support. Added MMC tables.
; <P3> 01/13/92 jmp (SWC,H9) Turned off caching for video space for DB-Lite to get
; around a bug with the GSC.
; <P2> 1/4/92 RP Changed ROMMaxSize for 2-Meg ROM
; <1> 5/17/92 kc first checked in
; <SM0> 3/26/92 kc Rolled in from Horror. Comments follow.
;                                   Force 32-bit mode. (see <SM7> in MemoryMgr.a)                   
; •••• This should be backed out as soon as we carve out space for
; the 2 Meg rom from the slot address space. ••••
; <H17> 4/24/92 HJR Modified Niagra MMU Templates so that part of ROM is mapped to
; the end of Slot E space. This is in order to fake the Slot
; Manager into using part of the Main rom as the config ROM. It
; is necessary that if the location of VSCDeclData moves that the
; corresponding MMU Tables be updated. Updated physNiagra space
; table.
; <H16> 4/19/92 JC Cleaned up Sonora Physical Space Tables.
; <H15> 4/13/92 JC Cleaned up Sonora tables.
; <H14> 4/10/92 SWC Mucked around a bit more with the MSC tables.
; <H13> 1/31/92 SWC Added entries to the MSC tables for slots C and D, which are
; available when DBLite is plugged into its docking station.
; <H12> 1/24/92 JC Add support for optionally using full page tables on 030
; machines, modify Sonora Tables, and add support for alternate
; physical ROM address as defined in Universal Tables.
; <H11> 1/22/92 JC Change to fix Spike problem on Non Sonora builds.
; <H10> 1/20/92 JC Add support for Double Exposure for Vail as it was done on
; Foster Farms, and added support for the alternate ROM physical
; address defined in Universal Tables.
; <H9> 1/6/92 SWC Turned off caching for video space for DB-Lite to get around a
; bug with the GSC.
; <H8> 12/16/91 HJR Added NiagraTables for Dartanian.
; <H7> 12/13/91 SWC Removed video wrap space from MSC tables since the CPU ID
; register is directly below the LCD frame buffer so we won't have
; any QuickDraw gotchas.
; <H6> 12/12/91 CCH Reverted back to making Edisk space uncacheable when VM is on.
; <H5> 12/3/91 SWC Added MSCVidWrap to specify the video wrap and display size for
; DB-Lite since its LCD display supports grayscale (and hence more
; VRAM).
; <H4> 11/25/91 CCH Added Sonora support.
; <H3> 11/14/91 jmp (CCH) Mark EDisk address space as cacheable in physical space
; table.
; <H2> 10/15/91 SWC Changed BSR to PRamIO to a BSR.L since PRamIO moved from
; ClockPatch.a to Clock.a.
; ———————————————————————————————————————————————————————————————————————————————————————
; Pre-HORROR ROM comments begin here.
; ———————————————————————————————————————————————————————————————————————————————————————
; <25> 7/8/91 CCH Bumped padding size.
; <24> 6/26/91 CCH Moved RAM disk to slot 7 space.
; <23> 6/25/91 CCH Fixed a bug in HandleTrailing and WriteTableNode for levels that
; contain no valid descriptors. Increased Max Ram disk size to 256
; meg. Added Ram disk support to all machines and changed Ram disk
; address space to slot 6 space.
; <22> 6/21/91 BG Swapped the order of the case table in FindInfo to match the
; (new) order of the DecoderKinds table in UniversalEqu.a.
; <21> 6/13/91 CCH Moved bRamDisk equate to EDiskEqu.a, and changed RAM disk
; address location.
; <20> 6/11/91 CCH Created a nonserialized image of i/o space just above existing
; space on Orwell-based machines and made slot 9 minor slot space
; non-serialized.
; <19> 5/31/91 djw Added jump table entries and MMU tables to support DBLite/MSC.
; <18> 5/23/91 CCH Fixed a bug in WriteTableNode that wrote out page descriptors in
; the intermediate table when it encountered an entire level of
; invalid descriptors. Also modified the Jaws template to take
; advantage of early termination descriptors.
; <17> 5/9/91 HJR Set VRAMrealSize to LCDMaxSize in the Jaws case in FindInfo and
; removed the Slot $E entry in physical space table since make
; physical set that area to be onboard video.
; <16> 5/9/91 CCH Removed slot $B mapping from 24-bit Jaws template.
; <15> 4/21/91 CCH Turned on copyback mode at boot on 68040's. Modified Jaws
; template to add ramdisk support for Tim. Also fixed a bug in
; HandlerTrailing which screwed up when all pages in a subtable
; were invalid.
; <14> 4/5/91 CCH Added slot 9 minor slot space for Orwell machines as
; kUsageOnboardVideo in physical space table.
; <13> 3/29/91 CCH Removed slot 9 entry from Orwell physical space tables.
; <12> 3/19/91 CCH Turned off full-tables for non-68040 machines.
; <11> 3/19/91 CCH Added modifications to have the MMU create a seperate ram disk
; area to allow bootable RAM disks under VM and on machines with
; non-contiguous memory architectures. Also turned on full page
; tables on 030 machines.
; <10> 3/5/91 BG Fixed a typo in Template24RBVe. Slot B was mapped to Slot 9.
; <9> 2/18/91 HJR Fix commenting error.
; <8> 2/18/91 HJR Corrected physical space table for physLCD. VM now works on
; Tim.
; <7> 2/4/91 CCH Added physical space table for Orwell based machines.
; <6> 1/14/91 CCH Exported Trans.
; <5> 12/20/90 CCH Changed stack initialization to used fixed value.
; <4> 10/25/90 CCH Added support for ReAnimator when forRomulator equate is set.
; <3> 10/2/90 CCH Added padding at the end of the file.
; <2> 9/9/90 CCH Moved this file into second half-meg of ROM, and rolled in
; Eclipse and Tim support.
; ———————————————————————————————————————————————————————————————————————————————————————
; Pre-Terror ROM comments begin here.
; ———————————————————————————————————————————————————————————————————————————————————————
; <3> 6/12/90 JJ Add support for Apple II emulation video modes. Rolled in
; changes from main project. Original comments follow.
; {14} 6/7/90 CCH Ensured that only 24 bits are compared in the 24-bit logical
; video base address when determining which slot to use for video.
; <2> 5/14/90 CV Fixed mistake in last rev.
; <1> 5/14/90 CV This file was originally part of MMU.a. It contains the MMU
; tables. The files were split because the addition of code to
; support video in slot E made the file grow beyond the space
; allocated in MMU.a.
; To Do:
;
; implement lower limits (bell & whistle...)
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'MMUEqu.a'
INCLUDE 'BootEqu.a'
INCLUDE 'UniversalEqu.a'
INCLUDE 'EdiskEqu.a'
PRINT ON
MACHINE MC68030
MMUStuff PROC
EXPORT InitMMU
EXPORT Trans
IMPORT BaseOfROM, Critical, PramIO, RamTest
IMPORT RomLoc
IMPORT SizeSoundBuffer
WITH StartGlobals
WITH MMUConfigInfo
;-----
; The following table give MMU setup information for the different memory controllers
; and their associate memory models (contiguous, split, weird with RBV onboard video).
; Some extra entries have been provide for future overpatches.
;
; The Splitxxmb32 entries are for split memory model machines (such as the MDU without
; onboard video). The xx is the size of the smallest RAM chunk. We can set up early
; termination entries to match the smallest RAM chunk size, and thereby make the table
; smaller when we have larger RAM chunks.
;
; Include in each table entry is the TC (translation control register), the two
; translation register values to use, an offset to a template describing how to map
; the logical address space, an offset to a special template (see next paragraph) and
; an offset to a 'physical table' template.
;
; The special template can be used to create a huge void in the logical space above low
; memory and start the system heap right below the ROM. This is useful for stress-testing
; 32 bit addressing. The special template is used when the appropriate parameter RAM bit
; is set.
;---
MACRO
&label Setup &tc,&tt0,&tt1,&template,&special,&physical
&label dc.l &tc
dc.l &tt0
dc.l &tt1
dc.w &template-&label
dc.w &special-&label
dc.w &physical-&label
ENDM
MMUSetupInfo RECORD 0,INCR
newtc ds.l 1 ; translation control register
newtt0 ds.l 1 ; transparent translation reg 0
newtt1 ds.l 1 ; transparent translation reg 1
templOff ds.w 1 ; offset to template
specialOff ds.w 1 ; offset to special template
physicalOff ds.w 1 ; offset to template for physical space
size equ * ; size of each table entry
ENDR
WITH MMUSetupInfo
; transp. transp offset to offset to offset to
; TC xlat 0 xlat 1 template special template physical template
; -------- --------- --------- ----------- ---------------- ----------------
contig24 Setup $80F84500, 0, 0, template24, 0, physNormal
contig32 Setup $80F05750, 0, 0, template32, void32, physNormal
split24 Setup $80F84500, 0, 0, template24, 0, physNormal
split1mb32 Setup $80F05750, 0, 0, template32, void32, physNormal
split2mb32 Setup $80F05660, 0, 0, template32, void32, physNormal
split4mb32 Setup $80F05570, 0, 0, template32, void32, physNormal
split8mb32 Setup $80F05480, 0, 0, template32, void32, physNormal
split16mb32 Setup $80F08900, 0, 0, template32, void32, physNormal
split32mb32 Setup $80F07A00, 0, 0, template32, void32, physNormal
split64mb32 Setup $80F06B00, 0, 0, template32, void32, physNormal
Rbv24b Setup $80F84500, 0, 0, template24RBVb, 0, physRBVb ; <11>
Rbv32b Setup $80F05750, 0, 0, Template32RBVb, void32RBVb, physRBVb ; <11>
Rbv24e Setup $80F84500, 0, 0, template24RBVe, 0, physRBVe ; <11>
Rbv32e Setup $80F05750, 0, 0, Template32RBVe, void32RBVe, physRBVe ; <11>
orwell24 Setup $C000, 0, 0, template24Orwell, 0, physOrwell ; <T7>
orwell32 Setup $C000, $F900C060, $807FC040, Template32Orwell, void32Orwell, physOrwell ; <T20>
Jaws24 Setup $80F84500, 0, 0, template24Jaws, 0, physLCD ; <9>
Jaws32 Setup $80F05750, 0, 0, template32Jaws, void32Jaws, physLCD ; <9>
MSC24 Setup $80D86500, 0, 0, template24MSC, 0, physMSC ; <H23>
MSC32 Setup $80D07750, $600F8507, $807F8507, template32MSC, void32MSC, physMSC ; <H23>
MSC24040 Setup $C000, 0, 0, template24MSC040, 0, physMSC ; <H23>
MSC32040 Setup $C000, $600FC060, $807FC060, template32MSC040, void32MSC, physMSC ; <H23>
Niagra24 Setup $80D86500, 0, 0, template24Niagra, 0, physNiagra ; <H23>
Niagra32 Setup $80D07750, $600F8507, 0, template32Niagra, void32Niagra, physNiagra ; <H23>
Sonora24 Setup $80D86500, 0, 0, template24Sonora, 0, physSonora ; <H12>
Sonora32 Setup $80D07750, $600F8507, $807F8507, template32Sonora, void32Sonora, physSonora ; <H12>
FstrFrms24 Setup $80F84500, 0, 0, templateFF24, 0, physFF ; <SM1> CSS <H18>
FstrFrms32 Setup $80F05750, 0, 0, templateFF32, 0, physFF ; <SM1> CSS <H18>
YMCA24 Setup $C000, 0, 0, template24YMCA, 0, physYMCA ; <SM1> CSS <P4><LW2>
YMCA32 Setup $C000, $F900C060, $807FC040, Template32YMCA, void32YMCA, physYMCA ; <SM1> CSS <P4><LW2>
SnraForty24 Setup $C000, 0, 0, template24SnraFrty, 0, physSonora ; <H31><SM13>
SnraForty32 Setup $C000, $600FC060, $807FC040, template32SnraFrty, void32Sonora, physSonora ; <H31><SM13>
Pratt24 Setup $C000, 0, 0, template24Pratt, 0, physPratt ; <SM14>
Pratt32 Setup $C000, $A01FC040, $600FC060, template32Pratt, void32Pratt, physPratt ; <SM14>
;-----
; The template tables describe the logical to physical address mapping.
;
; Eech entry has a size of a chunk of the logical space, a suggested physical address for
; the chunk, a type and a cache inhibit flag. The size and physical address fields are
; long sized. The suggested physical address often is mostly used for the 24 bit mode case.
;
; The type and cache inhibit flags are imbedded in the low order 4 bits of the suggested
; physical address word, as follows:
;
; bits 3,2,1,0 - template type, describes how to map these addresses as follows:
;
; 0000 - map the logical address straight thru
; 0001 - a RAM entry. Map to pages of RAM allocated from the chunks found by Starttest.
; 0010 - a ROM entry for 32 bit mode. Use either the hardware defined physical
; address of the ROM, or the base of the ROM image if it is running in RAM.
; 0011 - a ROM entry for 24 bit mode. Use either a 24 bit compatible version of the
; hardware address of the ROM, or the base of the ROM image running in RAM.
; 0100 - hack for a quickdraw bug: map to the end of the onboard video buffer
; This is used to map addresses immediately below the buffer to someplace
; that won;t cause bus errors, cuz quickdraw sometimes acceses there.
; 0101 - a video entry. Map to onboard video buffer (at physical zero for RBV)
; 0110 - use the specific address specified in the template.
; 0111 - map the address as invalid - this space will be a void in the middle of
; real RAM
; 1000 - 24-bit mode wrap area. This is used on processors that don't have an
; initial-shift feature (i.e. 68040).
;
; bit 5 - cache inhibit flag (1 means inhibit the cache, i.e. uncacheable)
;
; bit 4 - 68040 cache mode. This is the second bit in the cache mode for a 68040. Bit 5
; is the first bit and still indicates if the cache is inhibited. If the cache
; is on, this bit means 1=CopyBack, 0=Writethrough. If the cache is inhibited, this
; bit means 1=Non Serialized, 0=Serialized.
;
; bit 6 - 0 = use early termination of MMU Tables for this block.
; 1 = map full pages for this block
;
;---
;-----
; Equates defining the logical address space
;---
k8Size equ $00002000 ; 8K
k32Size equ $00008000 ; 32K
k128Size equ k32Size*4 ; 128K
k512Size equ k128Size*4 ; 512K
DeclRomSize equ $A0000 ; Fake DeclData Rom size
DeclRomSz equ k128Size ; Fake DeclDate Rom size for super mario
ROMMaxSize equ $00200000 ; 2M: size of largest possible ROM <SM1> CSS ; <T7>
IOMaxSize equ $00040000 ; 256k: max size of memory-mapped I/O space ; <7>
EDskMaxSize equ $10000000 ; 256M: size of largest possible RAM disk ; <T23>
VRAMMaxSize equ $00200000 ; 2M: size of largest possible VRAM <SM1> CSS
VidWrapSize equ k32Size ; size of area before frame buffer to map to
; start of frame buffer. Fixes a Quickdraw bug.
; NOTE: must be multiple of page size
RBVMaxSize equ $F8000 ; maximum frame buffer size for RBV.
LCDMaxSize equ k32Size ; maximum frame buffer size for Waimea LCD. <9>
; NOTE: must be multiple of page size
_AssumeEq $100000, VidWrapSize+RBVMaxSize ; total video area must be 1 mb, or
; template below must change
RBVBase32b equ $FBB08000 ; 32 bit mode base of logical RBV frame buffer in slot B <11>
RBVWrap32b equ RBVBase32b-VidWrapSize ; 32 bit mode address of wrap area
RBVEnd32b equ RBVBase32b + RBVMaxSize ; 32 bit mode end frame buffer address
_AssumeEq 0, RBVWrap32b<<12 ; RBV Wrap must be on 1MB boundary, or
; template below must change
_AssumeEq 0, RBVEnd32b<<12 ; end of frame buffer must be on 1MB boundary, or
; template below must change
RBVBase32e equ $FEE08000 ; 32 bit mode base of logical RBV frame buffer in slot E <11>
RBVWrap32e equ RBVBase32e-VidWrapSize ; 32 bit mode address of wrap area
RBVEnd32e equ RBVBase32e + RBVMaxSize ; 32 bit mode end frame buffer address
_AssumeEq 0, RBVWrap32e<<12 ; RBV Wrap must be on 1MB boundary, or
; template below must change
_AssumeEq 0, RBVEnd32e<<12 ; end of frame buffer must be on 1MB boundary, or
; template below must change
LCDBase32 equ $FEE08000 ; 32 bit mode base of logical video frame buffer <9>
LCDWrap32 equ LCDBase32-VidWrapSize ; 32 bit mode address of wrap area <9>
LCDEnd32 equ LCDBase32 + LCDMaxSize ; 32 bit mode end frame buffer address <9>
_AssumeEq 0, LCDWrap32<<12 ; LCD Wrap must be on 1MB boundary, or
; template below must change
RBVBase24b equ (RBVBase32b<<8)>>8 ; 24 bit mode base of logical RBV frame buffer in slot B <11>
RBVWrap24b equ RBVBase24b-VidWrapSize ; 24 bit mode address of wrap area
RBVEnd24b equ RBVBase24b + RBVMaxSize ; 24 bit mode end frame buffer address
RBVBase24e equ (RBVBase32e<<8)>>8 ; 24 bit mode base of logical RBV frame buffer in slot E <11>
RBVWrap24e equ RBVBase24e-VidWrapSize ; 24 bit mode address of wrap area
RBVEnd24e equ RBVBase24e + RBVMaxSize ; 24 bit mode end frame buffer address
LCDBase24 equ (LCDBase32<<8)>>8 ; 24 bit mode base of logical video frame buffer
LCDWrap24 equ LCDBase24-VidWrapSize ; 24 bit mode address of wrap area
LCDEnd24 equ LCDBase24 + LCDMaxSize ; 24 bit mode end frame buffer address
MSCVidBase EQU $60000000 ; base of built-in frame buffer (not RBV) <t19>
MSCVidEnd EQU $70000000 ; end of frame buffer <t19>
SonoraVidBase EQU $60000000 ; base of built-in frame buffer (not RBV) <H12>
SonoraVidEnd EQU $70000000 ; end of frame buffer <H12><H15>
bRam equ $0 ; base of RAM area
bRom24 equ $00800000 ; base of ROM area (24 bit mode)
bEyeOh24 equ $00F00000 ; base of I/O area (24 bit mode)
b24Slot9 equ $00900000 ; base of minor slot 9 (24 bit mode)
b24SlotA equ $00A00000 ; base of minor slot A (24 bit mode)
b24SlotB equ $00B00000 ; base of minor slot B (24 bit mode)
b24SlotC equ $00C00000 ; base of minor slot C (24 bit mode)
b24SlotD equ $00D00000 ; base of minor slot D (24 bit mode)
b24SlotE equ $00E00000 ; base of minor slot E (24 bit mode)
t24SlotE equ $00F00000 ; top of minor slot E (24 bit mode) <SM1> CSS <H18>
b24DblX equ $00FC0000 ; base of Dbl X 24 bit Slot Space on Sonora <H10>
bTop24Less1 equ $00FFFFFF ; top of address space, less 1 (24 bit mode)
bRom32 equ $40000000 ; base of ROM area (32 bit mode)
bRealRom32 equ $40800000 ; exact base of ROM area (32 bit mode) <7>
bEyeOh32 equ $50000000 ; base of I/O area (32 bit mode)
bVideo32 equ $50036000 ; base of video I/O area (32 bit mode) <SM1> CSS <P7>
bVRAM32 equ $50100000 ; base of VRAM on Cyclone (32 bit mode) <SM1> CSS <P7>
bRealEyeOh32 equ $50F00000 ; exact base of I/O area (32 bit mode) <7>
bNonSerEyeOh equ $50F40000 ; base of non-serialized I/O area (32 bit) <T20>
bNonSerIO equ $51000000 ; base of non-serialized I/0 area (32 bit)
b32VidBase equ $60000000 ; base of built-in frame buffer (not RBV) <SM12>
b32Slot9 equ $F9000000 ; base of minor slot 9 (32 bit mode)
b32SlotA equ $FA000000 ; base of minor slot A (32 bit mode)
b32SlotB equ $FB000000 ; base of minor slot B (32 bit mode)
b32SlotC equ $FC000000 ; base of minor slot C (32 bit mode)
b32SlotD equ $FD000000 ; base of minor slot D (32 bit mode)
b32SlotE equ $FE000000 ; base of minor slot E (32 bit mode)
b32SlotF equ $FF000000 ; base of minor slot F (32 bit mode) DO NOT USE!!!
bTop32Less1 equ $FFFFFFFF ; top of address space, minus 1 (32 bit mode)
;---
; Equates for Foster Farms templates <SM1> CSS
;---
FFRomMax equ $400000 ; 4 Mb of ROM space <H18><Begin><SM9>
FFIOMax equ $C0000 ; Max I/O space
FFVideoMax equ $10000 ; 64k max for video buffer
FFbPhysVideo equ $9F0000 ; physical base for on-board video
DblXSlotMax equ $10000 ; maximum size of double X slot space <SM9>
FFbShadow equ $00800000 ; base of shadowed memory <SM13>
FFtShadow equ $00A00000 ; top of shadowed memory <SM13>
FFbRom24 equ $00A00000 ; base of FF ROM (24 bit mode) <SM9>
FFtRom24 equ FFbRom24+FFRomMax ; end of FF ROM (24 bit mode) <SM9>
FFbRom32 equ $40A00000 ; base of FF ROM area (32 bit mode)
FFtRom32 equ FFbRom32+FFRomMax
FFbEyeOh24 equ $00F00000 ; Beginning of I/O space (24 bit mode)
FFtEyeOh24 equ FFbEyeOh24+FFIOMax ; End of I/O space (24 bit mode)
FFbEyeOh32 equ $50F00000 ; Beginning of I/O space (32 bit mode)
FFtEyeOh32 equ FFbEyeOh32+FFIOMax ; End of I/O space (32 bit mode)
FFtDblxSlot24 equ FFtEyeOh24+DblXSlotMax ; Top of Double Exposure slot space (24 bit) <SM9>
FFtDblXSlot32 equ FFtEyeOh32+DblXSlotMax ; Top of Double Exposure slot space <H18><End>
;---
; Equates for building and accessing the template
;---
typeMask equ $0000000F ; mask to get type bits <7>
cBitMask equ $00000020 ; mask to get cache inhibit bit <7>
c040ModeMask equ $00000030 ; mask to get cache mode bits for 68040 <7>
physMask equ $FFFF0000 ; mask to get suggested physical address <7>
FullTblMask equ $00000040 ; mask to get full vs early termination field <H12>
; Values for the 68040 Cache Mode field <16>
c040CacheField equ 4 ; lsb of 68040 cache mode bits <16>
c040WriteThru equ (0 << c040CacheField) ; cacheable, writethrough <16>
c040CopyBack equ (1 << c040CacheField) ; cacheable, copyback <16>
c040InhibitSer equ (2 << c040CacheField) ; cache inhibited, serialized writes <16>
c040InhibitNonSer equ (3 << c040CacheField) ; cache inhibited, non-serialized writes<16>
cBitNum equ 5 ; bit number of cache inhibit flag <7>
cInhibit equ cBitMask ; flag for inhibiting cache
isThru equ 0 ; type = 0000: logical address = physical address
isRam equ 1 ; type = 0001: allocate physical addr from RAM chunks
isRom32 equ 2 ; type = 0010: use physical address of ROM
isRom24 equ 3 ; type = 0011: use 24 bit mode physical address of ROM
isVidWrap equ 4 ; type = 0100: wrap to start of video buffer
isVideo equ 5 ; type = 0101: allocate physical addr from video buffer
isMap equ 6 ; type = 0110: use suggested physical addr from template
isVoid equ 7 ; type = 0111: map as invalid
isWrap24 equ 8 ; type = 1000: start of 24-bit mode wrap <7>
isVideoRAM equ 9 ; type = 1001: dedicated onboard video RAM <9>
isEdisk equ 10 ; type = 1010: ram disk <T11>
FullTblBit equ 6 ; bit number of full vs early termination field <H12>
FullTbl equ FullTblMask ; flag for enabling full MMU tables (no early term) <H12>
Template RECORD 0,INCR ; Template Entry:
span ds.l 1 ; span of the entry
physNflag ds.l 1 ; suggested physical address, & flags <7>
tEntrySize equ * ; size of a template entry
ENDR
MACRO
&label tp &span,&physNflag
&label dc.l &span
dc.l &physNflag ; <7>
ENDM
Template32
tp bRom32-bRam, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o and/or video <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; slots <T23>
Template32RBVb ; RBV in Slot B
tp bRom32-bRam, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp RBVWrap32b-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp RBVBase32b-RBVWrap32b, isVidWrap ; wrap area <11>
tp RBVEnd32b-RBVBase32b, isVideo ; frame buffer area <11>
tp (bTop32Less1-RBVEnd32b)+1, isThru+cInhibit ; rest of slots <11>
Template32RBVe ; RBV in Slot E <11>
tp bRom32-bRam, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp RBVWrap32e-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp RBVBase32e-RBVWrap32e, isVidWrap ; wrap area
tp RBVEnd32e-RBVBase32e, isVideo ; frame buffer area
tp (bTop32Less1-RBVEnd32e)+1, isThru+cInhibit ; rest of slots
Template32Orwell ; <7>
tp bRealRom32-bRam, isRAM+c040CopyBack ; RAM <T20>
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack; ROM <T11><T15>
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <T23>
tp bNonSerEyeOh-bRealEyeOh32, isThru+c040InhibitSer ; ser i/o <T20>
tp (bNonSerEyeOh+IOMaxSize)-bNonSerEyeOh, isThru+c040InhibitNonSer ; non-ser i/o <T20>
tp bRamDisk-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk <T23>
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs) <T23>
Template32Jaws
tp bRom32-bRam, isRAM ; RAM <T20>
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp LCDWrap32-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp LCDBase32-LCDWrap32, isVidWrap ; wrap area
tp LCDEnd32-LCDBase32, isVideoRAM ; frame buffer area
tp (bTop32Less1-LCDEnd32)+1, isThru+cInhibit ; rest of slots
Template32MSC ; <t19>
tp bRealRom32-bRam, isRAM+FullTbl ; RAM <H23><SM13>
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+FullTbl ; ROM <H23><SM13>
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <H23><SM13>
tp b32VidBase-bRealEyeOh32, isThru+cInhibit ; i/o <H23><SM13>
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0) <H23><SM13>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23><SM13>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) <H23><SM13>
Template32MSC040
tp bRealRom32-bRam, isRAM+c040CopyBack ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack ; ROM
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid
tp b32VidBase-bRealEyeOh32, isThru+c040InhibitSer ; i/o
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0)
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1)
Template32SnraFrty ;
tp bRealRom32-bRam, isRAM+c040CopyBack ; RAM <SM13>
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack ; ROM <SM13>
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <SM13>
tp bNonSerEyeOh-bRealEyeOh32, isThru+c040InhibitSer ; ser i/o <SM13>
tp (bNonSerEyeOh+IOMaxSize)-bNonSerEyeOh, isThru+c040InhibitNonSer; non-ser i/o <SM13>
tp (b32VidBase-$2000)-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid <SM13>
tp b32VidBase-(b32VidBase-$2000), isThru+c040InhibitSer ; CPU ID Register <SM13>
tp bRamDisk-b32VidBase, isVoid ; Video (uses TTx regs) <SM13>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk <SM13>
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs) <SM13>
Template32Sonora ; <H10><H12>
tp bRealRom32-bRam, isRAM+FullTbl ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+FullTbl ; ROM <H15>
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <H15>
tp b32VidBase-bRealEyeOh32, isThru+cInhibit ; I/O <H23><SM13>
tp bRamDisk-b32VidBase, isThru+cInhibit ; Video (uses TT0) <H23><SM13>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <H15><SM13>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) <SM13>
Template32Niagra ; <SM12>
tp bRealRom32-bRam, isRAM+FullTbl ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+FullTbl ; ROM
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid
tp b32VidBase-bRealEyeOh32, isThru+cInhibit ; i/o
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0)
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk
tp b32SlotE-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots thru E
tp (b32SlotF-DeclRomSize)-b32SlotE, isThru+cInhibit ; slot E up to config ROM
tp b32SlotF-(b32SlotF-DeclRomSize), bRealRom32+isMap+cInhibit ; slot E Config ROM
tp bTop32Less1-b32SlotF+1, isThru+cInhibit ; slots
Template32YMCA ; <SM1> CSS <P4><LW2>
tp bRealRom32-bRam, isRAM+c040CopyBack ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack; ROM
tp bVideo32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <P7>
tp bVRAM32 -bVideo32, isThru+c040InhibitNonSer ; non-ser video I/O. <P7>
tp (bVRAM32+VRAMMaxSize)-bVRAM32, isThru+c040InhibitNonSer ; non-ser VRAM. <P7>
tp bRealEyeOh32 -(bVRAM32+VRAMMaxSize), isVoid ; Invalid <P7>
tp bNonSerEyeOh-bRealEyeOh32, isThru+c040InhibitSer ; ser i/o
tp (bNonSerEyeOh+IOMaxSize)-bNonSerEyeOh, isThru+c040InhibitNonSer ; non-ser i/o
tp bRamDisk-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs)
Template32Pratt
tp bRom32-bRam, isRAM+c040CopyBack ; RAM
; IMPORTANT! The following two lines contain the expression 2*ROMMaxSize so that we can overlay
; the emulation monitor for the HP 040 emulator into a valid address range. For the final product,
; we don't need the factor of 2 (i.e. just use ROMMaxSize instead). <ged>
tp (bRom32+2*ROMMaxSize)-bRom32, isROM32+c040CopyBack ; ROM
tp bEyeOh32-(bRom32+2*ROMMaxSize), isVoid ; Invalid
tp bNonSerIO-bEyeOh32, isThru+c040InhibitSer ; ser i/o
tp b32VidBase-bNonSerIO, isThru+c040InhibitNonSer ; non-ser i/o
tp bRamDisk-b32VidBase, isVoid ; Invalid
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk
tp b32SlotA-(bRamDisk+EDskMaxSize), isVoid ; Invalid
tp b32SlotC-b32SlotA, isThru+c040InhibitSer ; Minor slot spaces A and B
tp b32SlotE-b32SlotC, isVoid ; Invalid
tp (b32SlotF-DeclRomSz)-b32SlotE, isThru+c040InhibitSer ; map beginning of slot E thru
tp b32SlotF-(b32SlotF-DeclRomSz), ($402e0000-DeclRomSz)+isMap+c040InhibitSer; slot E Config ROM
tp bTop32Less1-b32SlotF+1, isVoid ; slot f not used
Template24
tp bRom24-bRam, isRAM ; RAM
tp b24Slot9-bRom24, isROM24 ; ROM
tp b24SlotA-b24Slot9, b32Slot9+isMap+cInhibit ; minor slot 9 <7>
tp b24SlotB-b24SlotA, b32SlotA+isMap+cInhibit ; minor slot A <7>
tp b24SlotC-b24SlotB, b32SlotB+isMap+cInhibit ; minor slot B <7>
tp b24SlotD-b24SlotC, b32SlotC+isMap+cInhibit ; minor slot C <7>
tp b24SlotE-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D <7>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+cInhibit ; minor slot E <7>
tp (bTop24Less1-bEyeOh24)+1, bEyeOh32+isMap+cInhibit ; i/o <7>
Template24RBVb ; RBV in Slot B <11>
tp bRom24-bRam, isRAM ; RAM
tp b24Slot9-bRom24, isROM24 ; ROM
tp b24SlotA-b24Slot9, b32Slot9+isMap+cInhibit ; minor slot 9 <7>
tp RBVWrap24b-b24SlotA, b32SlotA+isMap+cInhibit ; minor slot A <7><11>
tp RBVBase24b-RBVWrap24b, isVidWrap ; wrap area <11>
tp RBVEnd24b-RBVBase24b, isVideo ; frame buffer area <11>
tp b24SlotD-RBVEnd24b, b32SlotC+isMap+cInhibit ; minor slot C <7><11>
tp b24SlotE-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D <7>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+cInhibit ; minor slot E <7>
tp bTop24Less1-bEyeOh24+1, bEyeOh32+isMap+cInhibit ; i/o <7>
Template24RBVe ; <11>
tp bRom24-bRam, isRAM ; RAM
tp b24Slot9-bRom24, isROM24 ; ROM
tp b24SlotA-b24Slot9, b32Slot9+isMap+cInhibit ; minor slot 9
tp b24SlotB-b24SlotA, b32SlotA+isMap+cInhibit ; minor slot A
tp b24SlotC-b24SlotB, b32SlotB+isMap+cInhibit ; minor slot B
tp b24SlotD-b24SlotC, b32SlotC+isMap+cInhibit ; minor slot C
tp RBVWrap24e-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D
tp RBVBase24e-RBVWrap24e, isVidWrap ; wrap area
tp RBVEnd24e-RBVBase24e, isVideo ; frame buffer area
tp bEyeOh24-RBVEnd24e, isVoid ; invalid
tp bTop24Less1-bEyeOh24+1, bEyeOh32+isMap+cInhibit ; i/o
Template24Orwell ; <7>
tp bRom24-bRam, isRAM+c040CopyBack ; RAM <16><T15>
tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM <16><T15>
tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitNonSer ; minor slot 9 <16><T20>
tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A <16>
tp b24SlotC-b24SlotB, b32SlotB+isMap+c040InhibitSer ; minor slot B <16>
tp b24SlotD-b24SlotC, b32SlotC+isMap+c040InhibitSer ; minor slot C <16>
tp b24SlotE-b24SlotD, b32SlotD+isMap+c040InhibitSer ; minor slot D <16>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+c040InhibitSer ; minor slot E <16>
tp IOMaxSize,bRealEyeOh32+isMap+c040InhibitSer ; serialized i/o <T20>
tp IOMaxSize,bNonSerEyeOh+isMap+c040InhibitNonSer ; nonserialized i/o <T20>
tp bTop24Less1-(bEyeOh24+(2*IOMaxSize))+1, isVoid ; void <T20>
tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area <T20>
Template24Jaws ; <9>
tp bRom24-bRam, isRAM ; RAM
tp b24Slot9-bRom24, isROM24 ; ROM <13>
tp LCDWrap24-b24Slot9, isVoid ; invalid <13><T16>
tp LCDBase24-LCDWrap24, isVidWrap ; wrap area
tp LCDEnd24-LCDBase24, isVideoRAM ; frame buffer area
tp bEyeOh24-LCDEnd24, isVoid ; invalid
tp bTop24Less1-bEyeOh24+1, bEyeOh32+isMap+cInhibit ; i/o
Template24MSC ; <t19>
tp bRom24-bRam, isRAM+FullTbl ; RAM <H23><SM13>
tp b24Slot9-bRom24, isROM24+FullTbl ; ROM <H23><SM13>
tp b24SlotA-b24Slot9, b32Slot9+isMap+cInhibit ; minor slot 9 <H14>
tp b24SlotB-b24SlotA, b32SlotA+isMap+cInhibit ; minor slot A <H14>
tp b24SlotC-b24SlotB, b32SlotB+isMap+cInhibit ; minor slot B <H14>
tp b24SlotD-b24SlotC, b32SlotC+isMap+cInhibit ; minor slot C <H13>
tp b24SlotE-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D <H13>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+cInhibit ; minor slot E
tp bTop24Less1-bEyeOh24+1, bRealEyeOh32+isMap+cInhibit ; i/o <H23><SM13>
Template24MSC040 ; <H35>
tp bRom24-bRam, isRAM+c040CopyBack ; RAM <H35>
tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM <H36>
tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitSer ; minor slot 9 <H36>
tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A <H35>
tp b24SlotC-b24SlotB, b32SlotB+isMap+c040InhibitSer ; minor slot B <H35>
tp b24SlotD-b24SlotC, b32SlotC+isMap+c040InhibitSer ; minor slot C <H35>
tp b24SlotE-b24SlotD, b32SlotD+isMap+c040InhibitSer ; minor slot D <H35>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+c040InhibitSer ; minor slot E <H35>
tp bTop24Less1-bEyeOh24+1, bRealEyeOh32+isMap+c040InhibitSer ; i/o <H35>
tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area <H35 End>
Template24Niagra ; <SM12>
tp bRom24-bRam, isRAM+FullTbl ; RAM
tp b24Slot9-bRom24, isROM24+FullTbl ; ROM
tp b24SlotC-b24Slot9, isVoid ; invalid
tp b24SlotD-b24SlotC, b32SlotC+isMap+cInhibit ; minor slot C
tp b24SlotE-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D
tp bEyeOh24-b24SlotE, b32SlotE+isMap+cInhibit ; minor slot E
tp bTop24Less1-bEyeOh24+1, bRealEyeOh32+isMap+cInhibit ; i/o
Template24SnraFrty ; <SM13>
tp bRom24-bRam, isRAM+c040CopyBack ; RAM <SM13>
tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM <SM13>
tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitSer ; minor slot 9 <SM13>
tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A <SM13>
tp b24SlotC-b24SlotB, $60B00000+isMap+c040InhibitNonSer ; Video RAM <SM13>
tp b24SlotD-b24SlotC, b32SlotC+isMap+c040InhibitSer ; minor slot C <SM13>
tp b24SlotE-b24SlotD, b32SlotD+isMap+c040InhibitSer ; minor slot D <SM13>
tp bEyeOh24-b24SlotE, b32SlotE+isMap+c040InhibitSer ; minor slot E <SM13>
tp b24DblX-bEyeOh24, bRealEyeOh32+isMap+c040InhibitSer ; i/o <SM13>
tp (bTop24Less1-b24DblX)+1, $FEE00000+isMap+c040InhibitSer ; Double X slot space <SM13>
tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area <SM13>
Template24Sonora
tp bRom24-bRam, isRAM+FullTbl ; RAM <H12>
tp b24Slot9-bRom24, isROM24+FullTbl ; ROM <H15><H16>
tp b24SlotA-b24Slot9, b32Slot9+isMap+cInhibit ; minor slot 9
tp b24SlotB-b24SlotA, b32SlotA+isMap+cInhibit ; minor slot A
tp b24SlotC-b24SlotB, $60B00000+isMap+cInhibit ; Video RAM <H12><H15>
tp b24SlotD-b24SlotC, b32SlotC+isMap+cInhibit ; minor slot C
tp b24SlotE-b24SlotD, b32SlotD+isMap+cInhibit ; minor slot D
tp bEyeOh24-b24SlotE, b32SlotE+isMap+cInhibit ; minor slot E
tp b24DblX-bEyeOh24, bRealEyeOh32+isMap+cInhibit ; i/o <H10>
tp (bTop24Less1-b24DblX)+1, b24SlotE+isMap+cInhibit ; Double X slot space<H10>
Template24YMCA ;<SM1> <P4><LW2>
tp bRom24-bRam, isRAM+c040CopyBack ; RAM
tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM
tp b24SlotA-b24Slot9, $40900000 + isMap ; Slot 9 is 2nd meg of ROM. <P5>
tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A <P8>
tp b24SlotC-b24SlotB, b32SlotB+isMap+c040InhibitSer ; minor slot B <P8>
tp b24SlotD-b24SlotC, b32SlotC+isMap+c040InhibitSer ; minor slot C
tp b24SlotE-b24SlotD, b32SlotD+isMap+c040InhibitSer ; minor slot D
tp bEyeOh24-b24SlotE, b32SlotE+isMap+c040InhibitSer ; minor slot E
tp IOMaxSize,bRealEyeOh32+isMap+c040InhibitSer ; serialized i/o
tp IOMaxSize,bNonSerEyeOh+isMap+c040InhibitNonSer ; nonserialized i/o
tp bTop24Less1-(bEyeOh24+(2*IOMaxSize))+1, isVoid ; void
tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area
Template24Pratt ; <SM14>
tp bRom24-bRam, isRAM+c040CopyBack ; RAM
tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM
tp b24SlotA-b24Slot9, isVoid ; invalid
tp b24SlotC-b24SlotA, b32SlotC+isMap+c040InhibitSer ; minor slots A-B
tp b24SlotE-b24SlotC, isVoid ; minor slots C-D
tp bEyeOh24-b24SlotE, b32SlotE+isMap+c040InhibitSer ; minor slot E
tp bTop24Less1-bEyeOh24+1, bRealEyeOh32+isMap+c040InhibitSer ; i/o
Void32
tp HoleLowMem-bRam, isRAM ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRom32 - HoleSysHeap, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; slots <T23>
Void32RBVb
tp HoleLowMem-bRam, isRAM ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRom32 - HoleSysHeap, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp RBVWrap32b-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp RBVBase32b-RBVWrap32b, isVidWrap ; wrap area
tp RBVEnd32b-RBVBase32b, isVideo ; frame buffer area
tp (bTop32Less1-RBVEnd32b)+1, isThru+cInhibit ; rest of slots
Void32RBVe
tp HoleLowMem-bRam, isRAM ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRom32 - HoleSysHeap, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp RBVWrap32e-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp RBVBase32e-RBVWrap32e, isVidWrap ; wrap area
tp RBVEnd32e-RBVBase32e, isVideo ; frame buffer area
tp bTop32Less1-RBVEnd32e+1, isThru+cInhibit ; rest of slots
Void32Orwell ; <T23>
tp HoleLowMem-bRam, isRAM+c040CopyBack ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRealRom32-HoleSysHeap, isRAM+c040CopyBack ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack; ROM
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid <T23>
tp bNonSerEyeOh-bRealEyeOh32, isThru+c040InhibitSer ; ser i/o <T23>
tp (bNonSerEyeOh+IOMaxSize)-bNonSerEyeOh, isThru+c040InhibitNonSer ; non-ser i/o <T23>
tp bRamDisk-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk <T23>
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs) <T23>
Void32Jaws ; <9>
tp HoleLowMem-bRam, isRAM ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRom32 - HoleSysHeap, isRAM ; RAM
tp bEyeOh32-bRom32, isROM32 ; ROM <T23>
tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o <T23>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23>
tp LCDWrap32-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots <T23>
tp LCDBase32-LCDWrap32, isVidWrap ; wrap area
tp LCDEnd32-LCDBase32, isVideo ; frame buffer area
tp bTop32Less1-LCDEnd32+1, isThru+cInhibit ; rest of slots
Void32MSC ; <t19>
tp HoleLowMem-bRam, isRAM+FullTbl ; low memory: RAM <H23><SM13>
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRealRom32 - HoleSysHeap, isRAM+FullTbl ; RAM <H23><SM13>
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32 ; ROM <H23><SM13>
tp b32VidBase-(bRealRom32+ROMMaxSize), isThru+cInhibit ; i/o <H23><SM13>
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0) <H23><SM13>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <T23><SM13>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) <H23><SM13>
Void32Sonora ; <H10><H12>
tp HoleLowMem-bRam, isRAM+FullTbl ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRealRom32-HoleSysHeap, isRAM+FullTbl ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32 ; ROM
tp b32VidBase-(bRealRom32+ROMMaxSize), isThru+cInhibit ; I/O <H23><SM13>
tp bRamDisk-b32VidBase, isVoid ; Video (uses TT0) <H23><SM13>
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk <H15>
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs)
Void32Niagra ; <SM12>
tp HoleLowMem-bRam, isRAM+FullTbl ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRealRom32 - HoleSysHeap, isRAM+FullTbl ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32 ; ROM
tp b32VidBase-(bRealRom32+ROMMaxSize), isThru+cInhibit ; i/o
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0)
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk
tp b32SlotE-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots thru E
tp (b32SlotF-DeclRomSize)-b32SlotE, isThru+cInhibit ; slot E up to config ROM
tp b32SlotF-(b32SlotF-DeclRomSize), bRealRom32+isMap+cInhibit; slot E Config ROM
tp bTop32Less1-b32SlotF+1, isThru+cInhibit ; slots
TemplateFF24 ; <SM1> CSS
tp FFbShadow-bRam, isRAM ; RAM <H18><SM13>
tp FFtRom24-FFbShadow, isThru ; ROM <H22><SM13>
tp t24SlotE-FFtRom24, b32SlotE+isMap+cInhibit ; Slot E <SM13>
tp FFtEyeOh24-t24SlotE, isThru+cInhibit ; I/O space <SM13>
tp FFtDblxSlot24-FFtEyeOh24, b24SlotE+isMap+cInhibit ; Slot E (64k), for DblX <H22><SM13>
tp bTop24Less1-FFtDblxSlot24+1, isThru+cInhibit ; rest of I/O space <H22><SM13>
TemplateFF32
tp FFbShadow-bRam, isRAM ; RAM <SM13>
tp FFtShadow-FFbShadow, isThru ; Shadowed area <SM13>
tp FFbRom32-FFtShadow, isRAM ; RAM <SM13>
tp FFtRom32-FFbRom32, FFbRom24+isMap ; ROM <H22><SM13>
tp FFbEyeOh32-FFtRom32, isVoid ; unmapped space <SM13>
tp FFtEyeOh32-FFbEyeOh32, bEyeOh24+isMap+cInhibit ; I/O space <SM13>
tp FFtDblXSlot32-FFtEyeOh32, b24SlotE+isMap+cInhibit ; Slot E (64k), for DblX <SM13>
tp bRAMDisk-FFtDblXSlot32, isThru+cInhibit ; bank switch reg in here <H22><SM13>
tp bRamDisk+EDskMaxSize-bRamDisk, isEdisk ; Ram Disk <H22><SM13>
tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; Rest of slot space <H22><SM13>
Void32YMCA ; <SM1> CSS <P4><LW2>
tp HoleLowMem-bRam, isRAM+c040CopyBack ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRealRom32-HoleSysHeap, isRAM+c040CopyBack ; RAM
tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack; ROM
tp bRealEyeOh32-(bRealRom32+ROMMaxSize), isVoid ; Invalid
tp bNonSerEyeOh-bRealEyeOh32, isThru+c040InhibitSer ; ser i/o
tp (bNonSerEyeOh+IOMaxSize)-bNonSerEyeOh, isThru+c040InhibitNonSer ; non-ser i/o
tp bRamDisk-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk
tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs)
Void32Pratt ; <SM14>
tp HoleLowMem-bRam, isRAM+c040CopyBack ; low memory: RAM
tp HoleSysHeap - HoleLowMem, isVoid ; black hole
tp bRom32 - HoleSysHeap, isRAM+c040CopyBack ; RAM
tp (bRom32+ROMMaxSize)-bRom32, isROM32 ; ROM
tp b32VidBase-(bRom32+ROMMaxSize), isThru+c040InhibitSer ; i/o
tp bRamDisk-b32VidBase, isVoid ; video (uses TT0)
tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk
tp b32SlotE-(bRamDisk+EDskMaxSize), isThru+c040InhibitSer ; slots thru E
tp (b32SlotF-DeclRomSize)-b32SlotE, isThru+c040InhibitSer ; slot E up to config ROM
tp b32SlotF-(b32SlotF-DeclRomSize), bRom32+c040InhibitSer ; slot E Config ROM
tp bTop32Less1-b32SlotF+1, isThru+c040InhibitSer ; slots
;-----
; The physical template tables describe the significant sections of the pysical address space.
; These templates are used ONLY to generate the 'physical table', which is passed to VM and
; other foreign operating systems such as Pink/Opus and A/UX. The 'physical table' is not used
; for the vanilla Mac OS.
;
; Each physical template entry describes a chunk of the physical address space. Most of the
; template entries are just copied to the actual physical table. However, RAM intries are
; dynamically generated.
;---
IF (&TYPE('kUsageRAM') = 'UNDEFINED') THEN
; values for PhysicalSpaceUsage
kUsageRAM EQU 1
kUsageROM EQU 2
kUsageIO EQU 3
kUsageMinorSlot EQU 4
kUsageMajorSlot EQU 5
kUsageLowMemory equ 6
kUsageBootGlobals equ 7
kUsageOnboardVideo equ 8
kUsageOnboardVideoWrap equ 9
kUsageEDisk equ 10
kUsageEndTable equ $FFFF
kUsageOther EQU 0
; values for PhysicalSpaceAtributes bits
kCacheableBit EQU 0 ; MMU cacheable
kCacheableMask EQU 1 ; MMU cacheable
cacheable EQU kCacheableMask
notCacheable EQU 0
; structure to describe a range of addresses
AddressRange RECORD 0
address DS.L 1 ; start of range
rangeSize DS.L 1 ; size of range
size EQU *
ENDR
; structure to describe a single block of PhysicalSpace
PhysicalSpaceBlock RECORD 0
usage DS.W 1 ; what kind of block this is
attributes DS.W 1 ; MMU (and other) attributes
physical DS.B AddressRange ; physical address range
logical DS.B AddressRange ; suggested 32-bit address range
logical24 DS.B AddressRange ; suggested 24-bit address range
; more can be added here in later versions
size EQU *
ENDR
; structure to describe an entire PhysicalSpace
PhysicalSpace RECORD 0
numEntries DS.W 1 ; number of entries in table
entrySize DS.W 1 ; size of each entry in table
firstEntry DS.B PhysicalSpaceBlock ; first in variable-sized table
ENDR
ENDIF
physNormal dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40000000, $10000000
dc.l $40000000, $10000000
dc.l $00800000, $00100000 ; <SM13>
dc.w kUsageIO, notCacheable
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageMajorSlot, notCacheable
dc.l $60000000, $10000000
dc.l $60000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $90000000, $10000000
dc.l $90000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FB000000, $01000000
dc.l $FB000000, $01000000
dc.l $00B00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageEndTable
;---
; Max size of buffer for physical table = size of above fized stuff, plus entries for
; max # of RAM chunks, plus video and video wrapping space, plus bootglobals space <3.2>
; plus a few more just to be safe. <3.2>
;---
physBufSize equ *-physNormal + (sgMaxChunks+6) * PhysicalSpaceBlock.size ; <SM6> CSS ;<3.2>
;---
; Physical table for RBV in Slot B <9>
;---
physRBVb dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40000000, $10000000
dc.l $40000000, $10000000
dc.l $00800000, $00100000
dc.w kUsageIO, notCacheable
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageMajorSlot, notCacheable
dc.l $90000000, $10000000
dc.l $90000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageEndTable
;---
; Physical table for RBV in Slot E <11>
;---
physRBVe dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40000000, $10000000
dc.l $40000000, $10000000
dc.l $00800000, $00100000
dc.w kUsageIO, notCacheable
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageMajorSlot, notCacheable
dc.l $90000000, $10000000
dc.l $90000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FB000000, $01000000
dc.l $FB000000, $01000000
dc.l $00B00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageEndTable
;---
; Physical table for 68030 LCD portables <9> <17> HJR
;---
physLCD dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40000000, $10000000
dc.l $40000000, $10000000
dc.l $00800000, $00100000
dc.w kUsageIO, notCacheable
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageEndTable
;---
; Physical table for MSC-based portables <t19>
;---
physMSC dc.w kUsageRAM, cacheable ; RAM
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable ; ROM <H23><SM13>
dc.l $40800000, ROMMaxSize
dc.l $40800000, ROMMaxSize
dc.l $00800000, ROMMaxSize
dc.w kUsageIO, notCacheable ; I/O
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageOnboardVideo, notCacheable ; LCD video <SM13>
dc.l $60000000, $10000000
dc.l $60000000, $10000000
dc.l $00000000, $00000000
dc.w kUsageMajorSlot, notCacheable ; slot 9 <H14>
dc.l $90000000, $10000000
dc.l $90000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable ; slot A <H14>
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable ; slot B <H14>
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable ; slot C in docking station <H13>
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable ; slot D in docking station <H13>
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable ; slot E (PDS docking connector) <H13>
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable ; slot 9 <H14>
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot A <H14>
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot B <H14>
dc.l $FB000000, $01000000
dc.l $FB000000, $01000000
dc.l $00B00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot C in docking station <H13>
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot D in docking station <H13>
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot E (PDS docking connector)
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageEndTable
;---
; Physical table for Niagra LCD portables <H17>
;---
physNiagra dc.w kUsageRAM, cacheable ; <SM12>
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable ; ROM <H23>
dc.l $40800000, ROMMaxSize
dc.l $40800000, ROMMaxSize
dc.l $00800000, ROMMaxSize
dc.w kUsageIO, notCacheable ; I/O
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l $00F00000, $00100000
dc.w kUsageOnboardVideo, notCacheable ; LCD video
dc.l $60000000, $10000000
dc.l $60000000, $10000000
dc.l $00000000, $00000000
dc.w kUsageMinorSlot, notCacheable ; slot C
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot D
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot E up to declaration ROM
dc.l $FE000000, $01000000-DeclRomSize
dc.l $FE000000, $01000000-DeclRomSize
dc.l $00E00000, $00100000
dc.w kUsageMinorSlot, notCacheable ; slot E declaration ROM (VSCDeclData)
dc.l $40800000, DeclRomSize
dc.l $FF000000-DeclRomSize, DeclRomSize
dc.l $00000000, $00000000
dc.w kUsageEndTable
;---
; Physical table for Orwell Based machines <T7>
;---
physOrwell dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40800000, ROMMaxSize
dc.l $40800000, ROMMaxSize
dc.l $00800000, ROMMaxSize
dc.w kUsageIO, notCacheable
dc.l $50F00000, IOMaxSize
dc.l $50F00000, IOMaxSize
dc.l $00F00000, IOMaxSize
dc.w kUsageIO, notCacheable ; ••temp•• <T20>
dc.l $50F40000, IOMaxSize ; should be nonserialized
dc.l $50F40000, IOMaxSize
dc.l $00F40000, IOMaxSize
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageOnboardVideo, notCacheable
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FB000000, $01000000
dc.l $FB000000, $01000000
dc.l $00B00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageEndTable
physSonora dc.w kUsageRAM, cacheable ; Special Cased for Double X Slot E <H10>
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40800000, ROMMaxSize
dc.l $40800000, ROMMaxSize
dc.l $00800000, ROMMaxSize
; dc.w kUsageROM, cacheable ; ROM
; dc.l $40000000, $10000000
; dc.l $40000000, $10000000
; dc.l $00800000, $00100000
dc.w kUsageIO, notCacheable ;<H16>
dc.l $50000000, $10000000 ; Don't map all of I/O Space
dc.l $50000000, $00FC0000 ; because of Double Exposure Card
dc.l $00F00000, $000C0000
dc.w kUsageOnboardVideo, notCacheable ;<H16> Video Space <H30>
dc.l $60000000, $01000000 ;<SM13>
dc.l $60000000, $01000000 ;<SM13>
dc.l $00B00000, $00100000
dc.w kUsageMajorSlot, notCacheable
dc.l $90000000, $10000000
dc.l $90000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $F9000000, $01000000
dc.l $F9000000, $01000000
dc.l $00900000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageOther, notCacheable ; Double X accesses slot E <FF4>
dc.l $FEE00000, $40000 ; with addresses in the range <FF4><H30><SM13>
dc.l $50FC0000, $40000 ; $50FC0000-$50100000 <FF4>
dc.l $00FC0000, $40000 ; <FF4>
dc.w kUsageEndTable
;••• Begin <SM1> CSS Cyclone Roll-in.
;----- <H18><Begin>
; Physical table for Foster Farms
;---
physFF dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $00A00000, $00100000
dc.l $40A00000, $00100000
dc.l $00A00000, $00100000
dc.w kUsageROM, cacheable
dc.l $00B00000, $00100000
dc.l $40B00000, $00100000
dc.l $00B00000, $00100000
dc.w kUsageROM, cacheable ; define 2 Mb addtional ROM <SM9>
dc.l $00C00000, $00100000 ; <SM9>
dc.l $40C00000, $00100000 ; <SM9>
dc.l $00C00000, $00100000 ; <SM9>
dc.w kUsageROM, cacheable ; <SM9>
dc.l $00D00000, $00100000 ; <SM9>
dc.l $40D00000, $00100000 ; <SM9>
dc.l $00D00000, $00100000 ; <SM9>
dc.w kUsageIO, notCacheable
dc.l $00F00000, FFIOMax
dc.l $50F00000, FFIOMax
dc.l $00F00000, FFIOMax
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageOther, notCacheable ; Double X accesses slot E
dc.l $00E00000, DblXSlotMax ; with addresses in the range
dc.l $50FC0000, DblXSlotMax ; $50FC0000-$50CFFFFF
dc.l $00FC0000, DblXSlotMax ;
dc.w kUsageEndTable ; <H18><End>
;---
; Physical table for YMCA Based machines <P4><LW2>
;---
physYMCA dc.w kUsageRAM, cacheable
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable
dc.l $40800000, ROMMaxSize
dc.l $40800000, ROMMaxSize
dc.l $00800000, ROMMaxSize
dc.w kUsageOnboardVideo, notCacheable
dc.l $50100000, VRAMMaxSize
dc.l $50100000, VRAMMaxSize
dc.l 0, 0
dc.w kUsageIO, notCacheable
dc.l $50036000, $00002000
dc.l $50036000, $00002000
dc.l 0, 0
dc.w kUsageIO, notCacheable
dc.l $50F00000, IOMaxSize
dc.l $50F00000, IOMaxSize
dc.l $00F00000, IOMaxSize
dc.w kUsageMajorSlot, notCacheable
dc.l $A0000000, $10000000
dc.l $A0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $B0000000, $10000000
dc.l $B0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $C0000000, $10000000
dc.l $C0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $D0000000, $10000000
dc.l $D0000000, $10000000
dc.l 0, 0
dc.w kUsageMajorSlot, notCacheable
dc.l $E0000000, $10000000
dc.l $E0000000, $10000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable
dc.l $FA000000, $01000000
dc.l $FA000000, $01000000
dc.l $00A00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FB000000, $01000000
dc.l $FB000000, $01000000
dc.l $00B00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FC000000, $01000000
dc.l $FC000000, $01000000
dc.l $00C00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FD000000, $01000000
dc.l $FD000000, $01000000
dc.l $00D00000, $00100000
dc.w kUsageMinorSlot, notCacheable
dc.l $FE000000, $01000000
dc.l $FE000000, $01000000
dc.l $00E00000, $00100000
dc.w kUsageEndTable
;••• End <SM1> CSS Cyclone roll-in
;---
; Physical table for Pratt LCD portables <SM14>
;---
physPratt dc.w kUsageRAM, cacheable ;
dc.l 0, 0
dc.l 0, 0
dc.l 0, 0
dc.w kUsageROM, cacheable ; ROM
dc.l $40000000, ROMMaxSize
dc.l $40000000, ROMMaxSize
dc.l 0,0
dc.w kUsageIO, notCacheable ; I/O
dc.l $50000000, $10000000
dc.l $50000000, $10000000
dc.l 0,0
dc.w kUsageOnboardVideo, notCacheable ; LCD video
dc.l $60000000, $10000000
dc.l $60000000, $10000000
dc.l 0,0
dc.w kUsageMajorSlot, notCacheable ; PDS, major slots A-B
dc.l $A0000000, $20000000
dc.l $A0000000, $20000000
dc.l 0, 0
dc.w kUsageMinorSlot, notCacheable ; PDS, minor slots A-B
dc.l $FA000000, $02000000
dc.l $FA000000, $02000000
dc.l 0,0
dc.w kUsageMinorSlot, notCacheable ; slot E up to declaration ROM
dc.l $FE000000, $01000000-DeclRomSz
dc.l $FE000000, $01000000-DeclRomSz
dc.l 0,0
dc.w kUsageMinorSlot, notCacheable ; slot E up to declaration ROM
dc.l $402e0000-DeclRomSz, DeclRomSz
dc.l $FF000000-DeclRomSz, DeclRomSz
dc.l 0,0
dc.w kUsageEndTable
;-----
; MMUError - unrecoverable error discovered while setting up MMU.
;---
MMUError move.w #102,d6 ; minor error code = MMU setup error <3.2>
move.l #$0F,d7 ; major error code = NuMac error <3.2>
bigjmp Critical,a0 ; ugly tone, service call needed...
;-----
; InitMMU - sets up the MMU depending on what memory controller we are running and
; what chunks of RAM were found by StartTest.
;
; Entry
; 'Universal ROM' registers
; a0 - Pointer to table of base addresses
; a1 - Pointer to ProductInfo record for this machine
; d0 - Flags indicating which base addresses are valid
; d1 - Flags indicating which external features are valid
; d2 - Bits 15..8, BoxFlag info (possibly unknown)
; d2 - Bits 7..0, Address Decoder Kind (zero if unknown)
; d7 - bits 31-16: logic board type
; d7 - bits 15-0: cpu type (0 = 68000, 1 = 68010, 2 = 68020, 3 = 68030, 4 = 68040, etc.) <2>
;
; a6 - points to table of RAM chunks, tucked under the top of memory as follows:
;
; ------------ <--- top of highest RAM bank
; + <diags> + --- 2 longs at top of bank are trashed by diagnostics
; + <diags> + --- ditto
; + FFFFFFFF +
; + <size> +
; + <addr> +
; + ... +
; + <size> +
; + <addr> +
; ------------ <--- a6
;
; Ench RAM chunk is specified by its physical addess and size. The table of
; RAM chunks is terminiated by a single longword of $FFFFFFFF. The code
; depends on the table being sorted by chunk start address, with the lowest
; addressed chunk pointed to by a6.
;
;
; Exit
; Universal registers d0-d2/d7,a0-a1 preserved
; a4 - points to BootGlobs in logical space
; sp - in the middle of the useable logical space
;
; Trashes
; d3-d5/a2-a7 (a4,sp as documented above)
;
; Conventions Used:
; Routines called by InitMMU assume they can trash d0-d1/a0, and must preserve
; all other registers they use. Exceptions to this rule should be cleary documented.
;---
Initframe RECORD {InitLink},DECR
InitRet ds.l 1 ; return address
InitLink ds.l 1 ; prev value link register
prodInfoPtr ds.l 1 ; saved a1 - Pointer to ProductInfo record for this machine
basesPtr ds.l 1 ; saved a0 - Pointer to table of base addresses
cpuType ds.w 1 ; saved d7 - bits 15-0: cpu type (0 = 68000, 1 = 68010, etc)
boxInfo ds.w 1 ; - bits 31-16: logic board type
decoder ds.b 1 ; saved d2 - Bits 7..0, Address Decoder Kind (zero if unknown)
boxType ds.b 1 ; - Bits 15..8, BoxFlag info (possibly unknown)
upperD2 ds.w 1 ; - upper word of d2
extFeatures ds.l 1 ; saved d1 - Flags indicating which external features are valid
basesValid ds.l 1 ; saved d0 - Flags indicating which base addresses are valid
SaveURegs equ BasesValid ; save universal registers here
globChunks ds.l sgMaxChunks*2;<SM6> CSS space for main RAM chunks (addr/size) (last addr -1)
eDiskChunks ds.l sgMaxChunks*2;<SM6> CSS space for eDisk chunks (addr/size) (last addr -1) <T11>
lastPhysRam ds.l 1 ; offset in physical table to last RAM chunk entry
smallest ds.l 1 ; size of smallest chunk, in megabytes
VRAMPhysBase ds.l 1 ; base of video buffer, if any <9>
VRAMrealSize ds.l 1 ; unrounded size of video buffer <9>
VRAMSize ds.l 1 ; size of video buffer, rounded up to MMU page size multiple <9>
logVRAMBase24 ds.l 1 ; 24-bit logical base address of video <9>
logVRAMBase32 ds.l 1 ; 32-bit logical base address of video <9>
logRomBase ds.l 1 ; logical, 24 bit alias-able addr of ROM
physRomBase ds.l 1 ; physical ROM addr as the hardware sees it
soundBufferBase ds.l 1 ; base of sound buffer in high RAM (if any) <H25><SM13>
soundBufferSize ds.l 1 ; size of sound buffer in high RAM (if any) <H25><SM13>
InitSize equ * ; size of frame
ENDR
WITH InitFrame
UnivRegs REG d0-d2/d7/a0-a1 ; registers to preserve for universality
InitMMU link a5,#InitSize ; set up stack frame
bsr SetupGlobals ; set up stack frame, boot globals
bsr FindInfo ; get ptr to MMU setup info
; returns a0 = 32 bit info ptr, a1 = 24 bit ptr
cmpi.b #EMMU1,sgTypeMMU(A6) ; Do we have an Emulated MMU? (ie don't make tables) <SM17>
beq.s @NoTables ; -> Yes, bail out now! <SM17>
cmp.b #HMMU,sgTypeMMU(a6) ; <SM6> CSS check type of MMU
bne.s @isPmmu ; IF HMMU
@noTables
movem.l SaveURegs(a5),UnivRegs ; restore universal registers
IF forRomulator THEN ; <T11>
TestInRAM A2 ; check if running ROM image in RAM |
beq.s @dontAdj ; IF in RAM v
biglea BaseOfROM,a4 ; get address base of ROM
suba.l a6,a4 ; calc offset from BootGlobs
move.l a4,sgAllocOff(a6) ; save allocation offset <SM6> CSS ^
@dontAdj ; ENDIF |
ENDIF ; <T11>
move.l a6,a4 ; return ptr to BootGlobs
unlk a5 ; remove stack frame
rts ; EXITROUTINE
@isPmmu ; ENDIF
move.l a1,a4 ; save ptr to 24 bit mode MMU setup info
move.l a0,a2 ; save ptr to 32 bit mode MMU setup info
bsr MakePhysicalTable ; create physical space table (for VM et. al.)
move.l a2,a0 ; recall ptr to 32 bit mode info
bsr MakeTable ; make 32 bit translation table
lea sg32Info(a6),a1 ; point at 32 bit mode info in BootGlobs <SM6> CSS
bsr SaveMMUInfo ; move 32 bit info to BootGlobs <SM6> CSS
btst #MMStartMode,sgMMFlags(a6);check if we're booting 32 bit only <SM6> CSS
bne.s @modesOK ; IF not booting 32 only
move.l a4,a0 ; recall addr 24 bit mode MMU setup Info
move.l a4,a2 ; recall addr 24 bit mode MMU setup Info
bsr MakeTable ; make a translation table
@modesOK ; ENDIF
lea sg24Info(a6),a1 ; point at 24 bit mode info in BootGlobs <SM6> CSS
bsr SaveMMUInfo ; move 24 (or 32) bit info to BootGlobs
@done ; ENDIF
bsr CleanupGlobals ; tidy up, leaving registers as follows:
; a2 - InitMMU's logical return address
; a3 - points to tc in MMUConfigInfo
; a4 - logical ptr to BootGlobs
; d3 - ROM physical-2-logical conversion constant
; sp - midway thru useable logical RAM
; d0-d2/d7/a0-a1 restored (DON'T TOUCH!)
;-----
; The following code actually enables the MMU. Since enabling the MMU may change the
; address of the code that actually does it (if it is running in RAM under Romulator™),
; we take precautions to ensure that both the 'pmove tc' and the 'jmp to the new logical
; address' are both in the 020/030 instruction cache. We can then jump to our new
; logical pc without fetching anything from the old pc, which is invalid once the pmove
; is executed. The same principle applies to the 040 'MOVEC URP', 'MOVEC TC' code. <2>
;
; We preload the instruction cache by executing the code snippet twice, passing in the Z
; condition code flag to determine whether to run the pmove or not. Since the pmove is
; 4 bytes, if we ensure that it is on a non-longword boundary, it will always be prefetched
; and cached by the 020 on the first pass thru the code.
;
; It is important the the transparent translation registers be set up before the MMU <7>
; is enabled, since we get the values for the TT regs using a3, which may become <7>
; invalid once the MMU is enabled. This will also work with Romulator™, since <7>
; we are already executing out of phyiscal space, which will not be affected by <7>
; transparent translation. <7>
;
; This routine assumes that the MMU is NOT enabled when called on a system with a <3.8>
; 68851 PMMU. <3.8>
;---
VTEntries equ 64 ; entries in exception vector table <SM1> CSS <H18>
IF forRomulator THEN ; <3.8>
biglea baseOfRom,a5 ; get physical base of ROM <3.8>
move.l a5,d6 ; save it to adjust pointers later <3.8>
ENDIF ; <3.8>
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <2><3>
beq.s @enable040MMU ; YES ... go enable 040 MMU <2>
pflusha ; flush address translation cache <16>
;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• <SM1> CSS <H18><Begin>
; For LC since all addresses are mapped straight thru, (i.e. no address translation takes place)
; 00AxXXXX is a valid address in 32 or 24 bit modes but on Foster Farms trying to access the ROM
; at 00AxXXXX will generate a bus error in 32 bit mode once the MMU is turned on. Therefore we
; must adjust all ptrs that have already been set up to pt at 40AxXXXX. Note: this address is
; also valid in 24 bit mode since the upper 8 bits of the address are ignored in this mode.
; Remember, D3 contains the ROM physical-2-logical conversion constant.
;•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
add.l d3,a0 ; adjust ptr to base addrs
add.l d3,a1 ; adjust ptr to productInfo rec
movec vbr,a5 ; get address of vectors
move.w #VTEntries-1,d5 ; get number of entries to adjust
@adj add.l d3,(a5)+ ; convert a vector
dbra d5,@adj ; do all of them
;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• <SM1> CSS <H18><End>
movec cacr,d5 ; NO ... get cache control reg
ori.w #$0808,d5 ; set flush bits (also set ccr.z = 0, for no pmove)
movec d5,cacr ; flush instruction, data caches
pmove theTT0-theTC(a3),tt0 ; load the transparent translation regs <7>
pmove theTT1-theTC(a3),tt1 ; BEFORE we fire up the MMU <7>
lea theCRP-theTC(a3),a6 ; get address of CRP <3.8>
lea @return1,a5 ; get 1st return addr
bra.s @inIcache ; load tc enable code into i-cache <3.8>
@return1 lea @mmuEnabled,a5 ; get 2nd return addr <3.8>
add.l d3,a5 ; add in phys-to-log conversion constant <3.8>
moveq #0,d5 ; set ccr.z = 1, so pmove gets executed
IF NOT forRomulator THEN ; Do not set the VBR to 0 if this is a ReAnimator build <H29>
movec d5,vbr ; restore vector base reg <3.8>
ENDIF ; <H29>
bra.s @inIcache ; go enable the mmu, return from InitMMU <3.8>
nop ; appease the assembler gods
ALIGN 4 ; <3.8>
@inIcache bne.s @step ; (2 bytes) IF second time thru
pmove (a6),crp ; (4 bytes) set up 32 bit mode crp <3.8>
@step nop ; (2 bytes) aligns next pmove to odd-word <3.8>
bne.s @goBack ; (2 bytes) IF second time thru <3.8>
pmove (a3),tc ; (4 bytes) enable the MMU
@goBack jmp (a5) ; (2 bytes) ENDIF - return
@mmuEnabled
IF 0 THEN
IF forRomulator THEN ; <3.8>
TestInRam a5 ; running in RAM? <3.8>
beq.s @noAdj ; if not, don't adjust pointers <3.8>
move.l ROMBase,d5 ; get correct base of ROM <3.8>
sub.l d6,d5 ; make d5 a phys-to-log offset <3.8>
add.l d5,a0 ; adjust ptr to base addrs <3.8>
add.l d5,a1 ; adjust ptr to productInfo rec <3.8>
@noAdj ; <3.8>
ENDIF ; <3.8>
ENDIF
jmp (a2) ; get InitMMU return addr <3.8>
;-----
; Enable the MMU on a 68040.
;
; Flush both caches. Use a CPUSHA instead of a CINVA, since CINVA does not flush <2>
; dirty entries to memory. N.B. - the CPUSHA IC generated by the <BC> operand does <2>
; NOT flush out the inst. cache, but instead performs the same action as a CINVA IC. <2>
; This is because in the 040, there won't BE any "dirty" entries in the inst. cache. <2>
;
; Since the Mac OS does not distinguish between instruction and data space, we must <7>
; duplicate the values placed in the instruction and data transparent translation <7>
; registers. <7>
;-----
MACHINE MC68040 ; The use of 040 instructions requires this <2>
@enable040MMU ; <2>
IF forRomulator THEN ; <T4>
biglea baseOfRom,a5 ; get physical base of ROM <T4>
MACHINE MC68040 ; corrects for ASM bug w/040 directive <SM12>
move.l a5,d6 ; save it to adjust pointers later <T4>
ENDIF ; <T4>
pflusha ; flush address translation cache <16>
move.l theTT0-theTC(a3),d5 ; get transparent translation reg 0 value <7>
movec d5,itt0 ; load the instruction TT0 reg <7>
movec d5,dtt0 ; load the data TT0 reg with the same value <7>
move.l theTT1-theTC(a3),d5 ; get transparent translation reg 1 value <7>
movec d5,itt1 ; load the instruction TT0 reg <7>
movec d5,dtt1 ; load the data TT0 reg with the same value <7>
moveq #0,d5 ; set ccr.z=1, to put enable code in cache <7>
lea @return0,a5 ; get 1st return addr <2>
bra.s @cachedEnableCode ; load TC enable code into i-cache <2>
@return0 lea @mmuEnabled,a5 ; get 2nd return addr <2>
add.l d3,a5 ; add in phys-to-log conversion constant <2>
if NOT forRomulator THEN ; <16>
movec d5,vbr ; restore vector base reg to zero <16>
endif ; <16>
move.l theSRP-theTC(a3),a6 ; retrieve 040 SRP value <7>
move.l (a3),d5 ; retrieve 040 TC value in lsw (ccr.z=0) <2>
bra.s @cachedEnableCode ; go enable the MMU, return from InitMMU <2>
ALIGN 16 ; force onto Cache Line boundary <2>
@cachedEnableCode
beq.s @aJMP ; (2 bytes) IF second time thru, fall thru <2>
movec a6,SRP ; (2 bytes) set up 32 bit mode SRP <7>
movec d5,TC ; (2 bytes) enable the MMU <2>
@aJMP jmp (a5) ; (2 bytes) ENDIF - return <2>
; ----------------------------------------------------------------------------------- <2>
MACHINE MC68030 ; return to prior MACHINE directive <2>
; ----------------------------------------------------------------------------------- <2>
;-----
; SetupGlobals - sets up the InitMMU stack frame and the BootGlobals record that is passed
; back to StartInit.
;
; Entry:
;
; a0 - Pointer to table of base addresses
; a1 - Pointer to ProductInfo record for this machine
; d0 - Flags indicating which base addresses are valid
; d1 - Flags indicating which external features are valid
; d2 - Bits 15..8, BoxFlag info (possibly unknown)
; d2 - Bits 7..0, Address Decoder Kind (zero if unknown)
; d7 - bits 31-16: logic board type
; d7 - bits 15-0: cpu type (0 = 68000, 1 = 68010, etc)
;
; a6 - points to RAM chunk table
;
; Exit
; InitMMU Stack frame set up
; BootGlobals set up
;---
WITH DecoderInfo
SetupGlobals
movem.l UnivRegs,SaveURegs(a5) ; save universal regs
move.l ROMAddr(a0),d0 ; get base address of ROM
move.l d0,logRomBase(a5) ; save it our globals
tst.l ROMPhysAddr(a0) ; Check if there is a defined physical ROM base <H12>
beq @SavePhys ; IF defined physical ROM base THEN <H12>
move.l ROMPhysAddr(a0),d0 ; use it instead of computed value <H12>
@SavePhys move.l d0,physRomBase(a5) ; save it in our globals
bsr GetMMUType ; figure out what kind of MMU we have
move.b d0,sgTypeMMU(a6) ; save MMU type in BootGlobs <SM6> CSS
clr.l VRAMSize(a5) ; assume no onboard video <9>
clr.l VRAMrealSize(a5) ; assume no onboard video <9>
clr.l VRAMPhysBase(a5) ; assume no VRAM <9>
MOVE.B decoder(A5),D2 ; get the decoder type <H27><SM13>
LEA @Resume,A2 ; (BSR2) <H27><SM13>
BRA.L SizeSoundBuffer ; get sound buffer attributes (if any) <H27><SM13>
@Resume MOVE.L A0,soundBufferBase(A5) ; save the base <H27><SM13>
MOVE.L D0,soundBufferSize(A5) ; and size of the sound buffer (if any) <H27><SM13>
move.l #bRamDisk,sgRamDiskBase(a6) ; init logical base of eDisk <T11><SM6> CSS
clr.l sgRamDiskSize(a6) ; assume empty ram disk <T11><SM6> CSS
clr.b sgEDiskStealFlag(a6) ; assume no chunks to steal <SAM>
move.l #-1,eDiskChunks(a5) ; make eDisk chunk table empty too
lea sgBottom,a0 ; assume we'll start allocating below BootGlobs <SM6> CSS
move.l a0,sgAllocOff(a6) ; save allocation offset <SM6> CSS
move.b #ramDiskPramAddr,d0 ; get PRAM address of memory manager flags <T11>
bsr ReadPRAMByte ; read it and weep... <T11>
andi.l #$ff,d0 ; clear upper bytes of pram byte <T11>
beq.s @noEdisk ; IF we want an Edisk THEN <T11>
clr.l d3 ; clear counter <T23>
cmpi.b #EMMU1,sgTypeMMU(A6) ; DO we have an EMMU? (have we already stolen RAM for the EDisk?)
bne.s @countRAM ; -> Nope, parse the tables
move.l sgTestSpace+24(a6),d1 ; Get the amount of bytes allocated by SizeMem for the EDisk <MC3>
bra.s @saveSize ; join the rest of the code (if D1=0 then no EDisk) <MC3>
@countRAM lea sgRamTable+4(a6),a0 ; get pointer to size of the first chunk | <SM6> CSS
@countLoop ; LOOP (to count RAM chunk sizes) v
add.l (a0)+,d3 ; bump RAM counter
tst.l (a0)+ ; is this the last chunk?
bpl.s @countLoop ; UNTIL (we reach the last chunk)
@gotSize lsr.l #8,d3 ; get chunk size
mulu.l d3,d0 ; calc size of edisk
add.l #$7fff,d0 ; bump edisk past next 32k boundary <T24>
and.w #$8000,d0 ; round down to the boundary ^
cmp.l #MinRamDiskSize,d0 ; check ram disk size |
blo.s @noEdisk ; >>EXIT if edisk is too small <T23>
cmp.l #MaxRamDiskSize,d0 ; check upper size limit <MC2>
bhi.s @noEdisk ; >>EXIT is edisk to too big <MC2>
move.l d0,d1 ; copy the size into D1 <SAM>
move.b #1,sgEDiskStealFlag(a6) ; signal that we want to steal chunks from RAM <SAM>
lea sgRamTable(a6),a0 ; source = chunk table in BootGlobs <T11> <SM6> CSS
lea eDiskChunks(a5),a1 ; destination = edisk chunk table <T11>
bsr stealChunks ; try to steal some ram from main memory <T11>
@saveSize ;
move.l d1,sgRamDiskSize(a6) ; save size of eDisk in boot globals <T11> <SM6> CSS
@noEdisk ; ENDIF <T11>
lea sgRamTable(a6),a0 ; source = chunk table in BootGlobs <SM6> CSS
lea globChunks(a5),a1 ; destination = our globals
bsr CopyChunks ; copy RAM chunks to our globals
move.l d0,smallest(a5) ; remember smallest chunk size
move.l d1,sgTotalRAM(a6) ; remember total RAM size in BootGlobs <SM6> CSS
; a0 = top highest bank, d1 = total RAM
sub.l a0,d1 ; normal phys-to-log offset = total - top
move.b #MMPRAMloc**$FF,d0 ; get PRAM address of memory manager flags
bsr ReadPRAMByte ; read it and weep... <5>
IF NOT Supports24Bit THEN ; <SM10> rb <SM11> rb
bset #MMStartMode,d0 ; Force 32-bit mode until we make room for a 2 meg rom <SM3> kc ••••
bset #MMMixed,d0 ; Force 32-bit mode until we make room for a 2 meg rom <SM3> kc ••••
bset #MMSysheap,d0 ; Force 32-bit mode until we make room for a 2 meg rom <SM3> kc ••••
bset #MMROZheap,d0 ; Force 32-bit mode until we make room for a 2 meg rom <SM3> kc ••••
bclr #mmHighSysHeap,d0 ; Force 32-bit mode until we make room for a 2 meg rom <SM3> kc ••••
ENDIF ; <SM10> rb
btst #MMStartMode,d0 ; check for 32 bit only
bne.s @not24 ; IF not 32 bit only
bclr #mmHighSysHeap,d0 ; weird system heap is a bad idea
bra.s @modeOk ; ...
@not24 btst #mmHighSysHeap,d0 ; ELSEIF 'black hole' before system heap
beq.s @modeOk ; .
add.l #HoleSysHeap-HoleLowMem,d1 ; phys-to-log offset = (total-top) +
; .(new base system heap - ram for lowmem)
@modeOk ; ENDIF
move.b d0,sgMMFlags(a6) ; save memory mgr flags in BootGlobs <SM6> CSS
move.l d1,sgPhys2Log(a6) ; save physical-to-logical offset <SM6> CSS
rts
ENDWITH ; {DecoderInfo}
;_____________________________________________________________________________________________
; Routine ReadPRAMByte
;
; Inputs: D0 - byte # to read from PRAM
; A5 - local frame pointer for InitMMU
;
; Outputs: D0 - byte read
;
; Destroys: ??
;_____________________________________________________________________________________________
ReadPRAMByte
movem.l d1-d6/a0-a3,-(sp) ; save regs that may be trashed
movea.l basesPtr(a5),a0 ; get ptr to hardware bases <4.0>
movea.l prodInfoPtr(a5),a1 ; get ptr to product info
move.l extFeatures(a5),d1 ; get external features <5>
moveq #1,d3 ; read 1 byte
swap d3 ; high byte contains count
move.w d0,d3 ; low word contains byte # to read
subq #2,sp ; allocate buffer space
movea.l sp,a3
bsr.l PramIO ; read it and weep... <5><H2>
moveq #0,d0
move.b (sp)+,d0 ; get byte out of buffer
movem.l (sp)+,d1-d6/a0-a3 ; restore regs
rts
;_____________________________________________________________________________________________
; CleanupGlobals
;
; Fixes up the RAM entries in the physical space table to account for total space
; occupied by boot globals and mmu tables. Restores the 'universal' registers that were
; passed in to InitMMU. Converts the ptr to BootGlobals into a logical address. Stuffs
; a few last tidbits of useful information into BootGlobs. Figures out logical return
; address for InitMMU.
;
; Entry
; a5 - points to InitMMU stack frame
; a6 - physical address of BootGlobs
;
; Exit:
; universal registers d0-d2/d7/a0-a1 restored
; d3 - ROM physical-2-logical conversion constant
; a2 - InitMMU's logical return address
; a3 - points to tc value in the 32 bit mode MMUConfigInfo record in BootGlobs
; a4 - logical address of BootGlobals
; sp - halfway through logical useable RAM space, clipped at 8 mb unless 'black hole'
;---
CleanupGlobals
move.l a6,a0 ; get ptr to BootGlobs
add.l sgPhysicalTableOff(a6),a0 ; get ptr to start of physical table <SM6> CSS
add.l lastPhysRam(a5),a0 ; get ptr to entry for last RAM chunk
move.l sgTopOff(a6),d0 ; get offset to top of boot globals area <SM6> CSS
sub.l sgAllocOff(a6),d0 ; total size = top offset - bottom offset <SM6> CSS
WITH PhysicalSpaceBlock
move.l soundBufferSize(a5),d1 ; get total RAM taken up by sound buffer <H25><SM13>
add.l d0,d1 ; and boot globals <H25><SM13>
sub.l d1,physical.rangeSize(a0) ; adjust size last useable chunk <H25><SM13>
move.l physical.address(a0),d1 ; get address last useable chunk
add.l physical.rangeSize(a0),d1 ; address bootglobs chunk = addr last + size
adda.w #PhysicalSpaceBlock.size,a0 ; point at entry for boot globals
move.l d1,physical.address(a0) ; set address boot globals chunk
move.l d0,physical.rangeSize(a0) ; set size boot globals chunk
move.w #kUsageBootGlobals,usage(a0); set usage field of boot globals chunk
ENDWITH
move.l (sp),d5 ; remember return address
move.l a6,d0 ; get physical ptr to BootGlobs
add.l sgPhys2Log(a6),d0 ; convert to logical ptr <SM6> CSS
move.l d0,a4 ; save logical ptr
IF forRomulator THEN ; <T11>
TestInRAM A2 ; check if running ROM image in RAM |
beq.s @dontAdj ; IF in RAM v
biglea BaseOfROM,a0 ; get address base of ROM
suba.l d0,a0 ; calc offset from BootGlobs
move.l a0,sgAllocOff(a6) ; save allocation offset <SM6> CSS ^
@dontAdj ; ENDIF |
ENDIF ; <T11>
add.l sgAllocOff(a6),d0 ; get logical address top useable memory <SM6> CSS
btst.b #mmHighSysHeap,sgMMFlags(a6); check if 'black hole' before system heap <SM6> CSS
beq.s @noHole ; IF 'black hole'
move.l d0,sp ; temporarily set new logical stack ptr there
sub.l #HoleSysHeap-HoleLowMem,d0 ; adjust amount of useable logical memory
lsr.l #1,d0 ; divide amt useable logical memory by 2
suba.l d0,sp ; stack = middle of useable logical memory
bra.s @donestak ; .
@noHole ; ELSE
cmp.l #$200000,d0 ; do we have at least two meg of RAM? <5>
bge.s @plentyORam ; IF we have less than two meg THEN <5>
lsr.l #2,d0 ; divide amt useable logical memory by 4 <5>
mulu.l #3,d0 ; multiply by 3 to get 3/4 of useable memory<5>
bra.s @stakOk ; go set stack <5>
@plentyORam ; ELSE <5>
move.l #defStackAddr,d0 ; use default stack size <5>
@stakOk ; ENDIF
move.l d0,sp ; set new stack
@doneStak ; ENDIF
biglea BaseOfROM,a1 ; get physical base address of ROM
move.l logRomBase(a5),d3 ; get future logical base addr ROM
sub.l a1,d3 ; get ROM phys-2-log conversion constant
move.l InitRet(a5),a2 ; get InitMMU's return address
add.l d3,a2 ; convert return addr to logical addr
lea sg32Info+theTC(a6),a3 ; point at 32 bit mode tc <SM6> CSS
movem.l SaveURegs(a5),UnivRegs ; restore 'universal' registers
movea.l d5,a5 ; get return address
jmp (a5) ; return to caller
;-----
; SaveMMUInfo - save tc, tt0, tt1, create and save crp
;
; Entry: d0 has 1st longword of crp
; a0 points to translation table
; a1 points to MMUConfigInfo record where info should be saved
; a2 points to layout info
;-----
SaveMMUInfo move.l newtc(a2),theTC(a1) ; move tc
move.l newtt0(a2),theTT0(a1) ; move tt0
move.l newtt1(a2),theTT1(a1) ; move tt1
move.l d0,theCRP(a1) ; save 1st half of crp
move.l a0,theCRP+4(a1) ; save 2nd half crp on 030, full srp on 040
cmp.w #cpu68040,d7 ; running on a 68040? <7>
bne.s @exit ; IF on 68040 <7>
andi.l #$fffffe00,theSRP(a1) ; bits 0-8 of SRP must be zero <7>
@exit ; ENDIF <7>
rts
;-----
; GetMMUType - figure out what kind of MMU we have
;
; Entry
; a5 - points to InitMMU globals
; d7 - bits 31-16: logic board type
; d7 - bits 15-0: cpu type (0 = 68000, 1 = 68010, 2 = 68020, 3 = 68030, 4 = 68040, etc.) <2>
;
; Exit
; d0.b - type of MMU
;
; Destroys d1-d2/a0-a1
;---
MMUTypes ; CPU type -> MMU type mapping
dc.b NoMMU ; 68000 - no MMU
dc.b NoMMU ; 68010 - no MMU
dc.b HMMU ; 68020 - HMMU or 68851
dc.b PMMU030 ; 68030 - '030 MMU
dc.b PMMU040 ; 68040 - '040 MMU <2>
MaxCPU equ *-MMUTypes-1 ; highest CPU flag supported
GetMMUType cmp.w #MaxCPU,d7 ; check if CPU type is in range
bhi MMUError ; if outta range, we're hosed
moveq #0,d0 ; clear a reg
move.b MMUTypes(d7),d0 ; get MMU type, based on CPU type
move.l prodInfoPtr(A5),A0 ; Get ptr to productInfo table
btst #ProductInfo.has68kEmulator//8,ProductInfo.ExtValid1+3(A0)
beq.s @done ; -> No emu. MMU type is correct.
moveq #EMMU1,D0 ; Set the MMU type to EmuMMU cause we're emulation an 020.
@done rts
;-----
; CopyChunks - copies a RAM chunk table, skipping zero sized chunks, remembering
; the smallest one, and accumulating the total size of all the chunks.
;
; Entry
; a0 - points to source table of chunks
; a1 - points to destination table of chunks
;
; Exit
; d0.l - size of smallest RAM chunk
; d1.l - total size of all chunks
; a0.l - ptr to end of last chunk
;---
CopyRegs REG d2-d5
CopyChunks movem.l CopyRegs,-(sp) ; save work regs
moveq #0,d1 ; init total RAM size to zero
moveq #-1,d0 ; init smallest size to huge
moveq #-1,d5 ; end of table marker
bra.s @startloop ; start in the middle...
@copyLoop ; LOOP thru RAM chunks in BootGlobs
cmp.l d0,d3 ; check chunk size
bhs.s @smallOK ; If it is the smallest so far
move.l d3,d0 ; save the new smallest size
@smallOK ; ENDIF
add.l d3,d1 ; add bank size to total
move.l d2,d4 ; get ptr to start of bank
add.l d3,d4 ; ptr to end = start + size
@startloop move.l (a0)+,d2 ; get next addr from source
move.l (a0)+,d3 ; get next size from source
move.l d2,(a1)+ ; save addr in destination
move.l d3,(a1)+ ; move size to destination
bne.s @sizeOK ; IF size is zero
subq #8,a1 ; back up 1 entry in destination
@sizeOK ; ENDIF
cmp.l d5,d2 ; check for end of list marker
bne.s @copyLoop ; REPEAT till end of list
move.l d4,a0 ; return ptr to end of bank
movem.l (sp)+,CopyRegs ; restore regs
rts
;-----
; StealChunks - Steals chunks from the end of a chunk table and moves them to <T11>
; another table. Also copies the original Boot Globs from the end
; of the original last chunk to the "new" last chunk of main memory.
;
; Entry
; a0 - points to source table of chunks
; a1 - points to destination table of chunks
; d0 - amount of RAM to steal
;
; Exit
; d1.l - total size of memory stolen, else zero upon failure
; a6.l - new boot globs pointer if RAM was stolen
;
; Destroys
; a1-a3
;-----
MinBootGlobs equ $00080000 ; 512k: boot globs min size <SM13>
StealRegs REG d2-d5/a4
StealChunks
movem.l StealRegs,-(sp) ; save work regs
move.l a0,a2 ; get addr of source chunks
move.l a1,a3 ; get addr of dest chunks
move.l d0,d2 ; get number of bytes to steal
clr.l d3 ; clear RAM size count
@findEndLoop ; LOOP (to find end of source chunks)
cmp.l #-1,(a2)+ ; did we reach the end?
beq.s @foundEnd ; >>EXIT when we get there
add.l (a2)+,d3 ; add size of this chunk into total
bra.s @findEndLoop ; END
@foundEnd ;
sub.l #MinHeapSize,d3 ; subtract minimum amount of RAM for System
ble @notEnufRAM ; >>EXIT if not enuf RAM
cmp.l d3,d2 ; check against requested amount
bhi @notEnufRAM ; >>EXIT if not enuf RAM
add.l #MinBootGlobs,d2 ; so we eat past boot globs
suba.l #4,a2 ; point just past last chunk entry
cmp.l #MinBootGlobs,-4(a2); is this a boot globs chunk?
beq.s @getChunksLoop ; IF boot globs chunk is not already seperate THEN
move.l -4(a2),d4 ; get size of previous last chunk
sub.l #MinBootGlobs,d4 ; calc new size of previous last chunk
move.l d4,-4(a2) ; save new size in previous last chunk
add.l -8(a2),d4 ; calc new end of previous last chunk
move.l d4,(a2) ; save start of boot globs chunk in new entry
move.l #MinBootGlobs,4(a2) ; save size of new chunk in a new entry at end
move.l #-1,8(a2) ; put end of chunk marker after boot globs chunk
adda.l #8,a2 ; point past new boot globs chunk
; ENDIF
move.l a2,a4 ; save ptr to end of boot globs chunk in src table
@getChunksLoop ; LOOP (to get start of Edisk chunks)
sub.l -(a2),d2 ; subtract this chunk from request
suba.l #4,a2 ; point to beginning of this chunk
bgt.s @getChunksLoop ; END
move.l a2,a0 ; make a copy of source table address
bsr copyChunks ; copy the chunk table starting with the chunk in a0
add.l d2,d1 ; calc amount of memory stolen
neg.l d2 ; get number of bytes in last main RAM chunk we don't need
move.l d2,4(a2) ; save new size of last chunk of main RAM in src table
sub.l d2,4(a3) ; save size of first chunk of edisk in dest table
add.l d2,(a3) ; adjust start of first chunk of edisk in dest table
; fix up boot globs chunks
move.l -8(a4),8(a2) ; copy start of boot globs chunk down in src table
move.l -4(a4),12(a2) ; copy size of boot globs chunk down in src table
move.l #-1,16(a2) ; put an end marker in src table after last chunk
@findEndLoop1 ; LOOP (to find end of dest chunks)
cmp.l #-1,(a3)+ ; did we reach the end?
beq.s @foundEnd1 ; >>EXIT when we get there
add.l #4,a3 ; bump up ptr to next addr
bra.s @findEndLoop1 ; END
@foundEnd1 move.l #-1,-12(a3) ; kill off extra boot globs chunk
sub.l #MinBootGlobs,d1 ; adjust amount of memory stolen
@exit movem.l (sp)+,StealRegs ; restore regs
rts
@notEnufRAM
clr.l d1 ; clear total size to indicate failure
bra.s @exit
;-----
; FindInfo - massage RAM chunks based on what type of hardware we are on, and return
; pointers to the layout tables to use in setting up the MMU.
;
; On a machine with RBV onboard video, the video buffer space is removed from the Bank A
; chunk, and the chunks are rearranged so that Bank B, if present, appears first in the
; table. This makes logical low memory show up in Bank B's faster RAM once the MMU tables
; are set up.
;
; On machines with a simple split memory architecture, the size of the smallest chunk is
; used to pick which layout table to use. This allows smaller tables with larger RAM sizes.
;
; Entry:
; a5 - points to InitMMU global stack frame
; a6 - points to BootGlobs
;
; Exit:
; InitMMU stack frame updated with massaged list of RAM chunks.
; a0 - points to 32 bit mode layout info
; a1 - points to 24 bit mode layout info
;---
WITH DecoderInfo
FindRegs REG d2-d6/a2 ; <3.0>
FindInfo movem.l FindRegs,-(sp) ; save work registers
movem.l globChunks(a5),d2-d5; d2-d3, d4-d5 = first two RAM chunks addr/size
move.l basesPtr(a5),a1 ; get ptr to table of base addresses
move.l basesValid(a5),d6 ; get mask of valid base addresses
moveq #0,d0 ; clear a reg
move.b decoder(a5),d0 ; get controller type
move.w @casetbl(d0.w*2),d0 ; get offset to controller routine
jmp @casetbl(d0.w) ; SWITCH(controller type)
@casetbl dc.w @bad-@casetbl ; .(unknown)
dc.w @bad-@casetbl ; .(Mac Pal)
dc.w @bad-@casetbl ; .(BBU)
dc.w @bad-@casetbl ; .(Normandy)
dc.w @Glu-@casetbl ; .(Mac2Glue)
dc.w @MDU-@casetbl ; .(MDU)
dc.w @FMC-@casetbl ; .(OSS FMC)
dc.w @VISA-@casetbl ; .(VISA has MMU similar to HMMU) <12><T22>
dc.w @Orwell-@casetbl ; .(Orwell) <7><T22>
dc.w @Jaws-@casetbl ; .(Jaws) <9>
dc.w @MSC-@casetbl ; .(MSC) <T19>
dc.w @Sonora-@casetbl ; .(Sonora) <H4>
dc.w @Niagra-@casetbl ; .(Niagra) <H8>
dc.w @YMCA-@casetbl ; .(YMCA) <SM7> fau <LW2>
dc.w @djMEMC-@casetbl ; .(djMEMC) <H20><SM13>
dc.w @Emulated-@casetbl ; .(HMC) <SM8>
dc.w @Pratt-@casetbl ; .(Pratt) <SM14>
dc.w @Emulated-@casetbl ; .(HHead)
Align 4
@bad ; CASE non-MMU based controller:
bra MMUError ; we're hosed...
@exp ; CASE some new controller:
moveq #2,d0 ; filler for a future overpatch
moveq #2,d0 ; filler for a future overpatch
bra @endSwitch
;---
; Mac II glue chip: check for weird cases, normally return pointer to Contiguous setup.
; Normal case is no bank B here, since we merged it with bank A
; and set the size bits. If we still have bank B, either there
; was no bank A, or Bank B is bigger than bank A. Either can be
; handled if a 68851 is present by using the Split setup.
;---
@Glu ; CASE Mac 2 glue chip:
lea Contig32,a0 ; assume contig 32 bit mode layout info
lea Contig24,a1 ; assume contig 24 bit mode layout info
tst.l d2 ; check if first chunk start w/Bank A <3.5>
bne.s @tryPMMU ; if not, its a weird case (has to be bank B) <3.5>
addq.l #1,d4 ; check if second chunk (bank B) exists <3.5>
beq @endSwitch ; if only one chunk of RAM, we're all set <3.5>
@tryPMMU cmp.b #HMMU,sgTypeMMU(a6) ; see if we have an MMU up to the task <3.5> <SM6> CSS
bne @split ; if its a PMMU, we can live with split memory <3.5>
bra MMUError ; otherwise we're hosed (no mem at addr zero!)
;---
; Emulated: RISC Macs have MMU functionality, but don't need to be setup here. <SM8> cch
;---
@Emulated ; CASE RISC Mac:
bra @endSwitch ; that's all folks
;---
; Sonora: Weird Case necessary to be able to handle Vail and Double Exposure. <H10>
;---
@Sonora ; CASE Sonora chip: <H4>
move.l d0,a0 ; save d0 <H31 Begin><SM13>
movec cacr,d0 ; <SM13>
move.l d0,a1 ; save cacr <SM13>
sub.l d0,d0 ; D0 = 0 <SM13>
bset #CACR_DE_040,d0 ; set Data Cache Enable bit on 040s <SM13>
movec d0,CACR ; attempt to enable data cache (temporarily) <SM13>
movec CACR,d0 ; check and see if it's still there <SM13>
btst #CACR_DE_040,d0 ; see if the bit exists in CACR <SM13>
beq.s @Sonora030 ; IF we're on a 68040 THEN <SM13>
MACHINE MC68040 ; need this for the MOVEC D0,TC below <SM13>
cinva bc ; make sure caches are invalidated <SM13>
MACHINE MC68030 ; return to prior MACHINE directive <2> <SM13>
move.l a1,d0 ; restore cacr <SM13>
movec d0,cacr ;
move.l a0,d0 ; restore d0 <SM13>
lea SnraForty32,a0 ; use Sonora's 040 32 bit mode layout info <SM13>
lea SnraForty24,a1 ; use Sonora's 040 24 bit mode layout info <SM13>
bra @endSwitch ; that's all folks <SM13>
@Sonora030 move.l a1,d0 ; restore cacr <SM13>
movec d0,cacr ; <SM13>
move.l a0,d0 ; restore d0 <H31 End><SM13>
lea Sonora32,a0 ; use Sonora's 32 bit mode layout info
lea Sonora24,a1 ; use Sonora's 24 bit mode layout info
bra @endSwitch ; that's all folks
;---
; Orwell: no weird cases. This wonderful decoder has already been set up to merge <7>
; RAM to be contiguous.
;---
@djMEMC ; CASE djMEMC chip: <H20><SM13>
@Orwell ; CASE Orwell chip: <7>
lea Orwell32,a0 ; use Orwell's 32 bit mode layout info
lea Orwell24,a1 ; use Orwell's 24 bit mode layout info
bra @endSwitch ; that's all folks
;---
; Jaws: Memory is always contiguous on Jaws, and onboard video will always be on.
;---
@Jaws ; CASE Jaws chip: <9>
movea.l prodInfoPtr(a5),a0 ; get productInfo record in a0
move.l a0,a1 ; get a copy in a1
adda.l ProductInfo.VideoInfoPtr(a0),a1 ; point to the VideoInfo record
move.l VideoInfo.VRAMPhysAddr(a1),VRAMPhysBase(a5) ; initialize base of video RAM
move.l VideoInfo.VRAMLogAddr32(a1),logVRAMBase32(a5) ; 24-bit logical VRAM addr
move.l VideoInfo.VRAMLogAddr24(a1),logVRAMBase24(a5) ; 32-bit logical VRAM addr
move.l #LCDMaxSize,VRAMrealSize(a5) ; set the size of video for phys space tbl <17> HJR
lea Jaws32,a0 ; use Jaws' 32 bit mode layout info
lea Jaws24,a1 ; use Jaws' 24 bit mode layout info
bra @endSwitch ; that's all folks
;---
; MSC: Memory is always contiguous on MSC, and onboard video will always be on.
;---
@MSC ; CASE MSC chip: <t19>
movea.l prodInfoPtr(a5),a0 ; get productInfo record in a0
move.l a0,a1 ; get a copy in a1
adda.l ProductInfo.VideoInfoPtr(a0),a1 ; point to the VideoInfo record
move.l VideoInfo.VRAMPhysAddr(a1),VRAMPhysBase(a5) ; initialize base of video RAM
move.l VideoInfo.VRAMLogAddr32(a1),logVRAMBase32(a5) ; 24-bit logical VRAM addr
move.l VideoInfo.VRAMLogAddr24(a1),logVRAMBase24(a5) ; 32-bit logical VRAM addr
lea MSC32,a0 ; use MSC's 32 bit mode layout info
lea MSC24,a1 ; use MSC's 24 bit mode layout info
bra @endSwitch ; that's all folks
;---
; Niagra: Memory is always contiguous on Niagra, and onboard video will always be on. <H8>
; through next <H8>
;---
@Niagra ;
movea.l prodInfoPtr(a5),a0 ; get productInfo record in a0
move.l a0,a1 ; get a copy in a1
adda.l ProductInfo.VideoInfoPtr(a0),a1 ; point to the VideoInfo record
move.l VideoInfo.VRAMPhysAddr(a1),VRAMPhysBase(a5) ; initialize base of video RAM
move.l VideoInfo.VRAMLogAddr32(a1),logVRAMBase32(a5) ; 24-bit logical VRAM addr
move.l VideoInfo.VRAMLogAddr24(a1),logVRAMBase24(a5) ; 32-bit logical VRAM addr
lea Niagra32,a0 ; use Niagra' 32 bit mode layout info
lea Niagra24,a1 ; use Niagra' 24 bit mode layout info
bra @endSwitch ; that's all folks <H8>
;---
; Pratt: Memory is always contiguous on Pratt, and onboard video will always be on. <SM14>
;
;---
@Pratt ;
movea.l prodInfoPtr(a5),a0 ; get productInfo record in a0
move.l a0,a1 ; get a copy in a1
adda.l ProductInfo.VideoInfoPtr(a0),a1 ; point to the VideoInfo record
move.l VideoInfo.VRAMPhysAddr(a1),VRAMPhysBase(a5) ; initialize base of video RAM
move.l VideoInfo.VRAMLogAddr32(a1),logVRAMBase32(a5) ; 24-bit logical VRAM addr
move.l VideoInfo.VRAMLogAddr24(a1),logVRAMBase24(a5) ; 32-bit logical VRAM addr
lea Pratt32,a0 ; use Niagra' 32 bit mode layout info
lea Pratt24,a1 ; use Niagra' 24 bit mode layout info
bra @endSwitch ; that's all folks
;---
; FMC - only weird case is bank B only. For other cases, we previously merged
; everything into one bank starting at physical zero. We can survive bank B
; only with the split model.
;---
@FMC ; CASE FMC chip: <3.6>
lea Contig32,a0 ; assume contig 32 bit mode layout info
lea Contig24,a1 ; assume contig 24 bit mode layout info
tst.l d2 ; check if RAM starts at physical zero
bne @split ; if not, we can live with split memory mode <3.8>
bra @endSwitch ; ...
;••• Begin <SM7> fau
;---
; YMCA: no weird cases.
;---
@YMCA ; CASE YMCA chip:
lea YMCA32,a0 ; use YMCA's 32 bit mode layout info <LW2>
lea YMCA24,a1 ; use YMCA's 24 bit mode layout info <LW2>
bra @endSwitch ; that's all folks
;••• End <SM7> fau end
;---
; MDU - if RBV present w/monitor attached, deallocate video buffer from useable RAM
; and make Bank B, if present, be low memory.
;---
@MDU ; CASE MDU chip:
btst #RBVExists,d6 ; check if RBV exists
beq @split ; IF RBV exists <3.8>
movea.l prodInfoPtr(a5),a0 ; get productInfo record in a0 <9>
move.l a0,a1 ; get a copy in a1 <9>
adda.l ProductInfo.VideoInfoPtr(a0),a1 ; point to the VideoInfo record <9>
move.l VideoInfo.VRAMPhysAddr(a1),VRAMPhysBase(a5) ; initialize base of video RAM <9>
move.l VideoInfo.VRAMLogAddr32(a1),logVRAMBase32(a5) ; 24-bit log. VRAM addr <9>
move.l VideoInfo.VRAMLogAddr24(a1),logVRAMBase24(a5) ; 32-bit log. VRAM addr <9>
cmpi.l #RBVBase32b,logVRAMBase32(a5) ; check which slot video is in <11>
adda.l ProductInfo.DecoderInfoPtr(a0),a0 ; point a0 to decoder info <11>
bne.s @slotE ; IF RBV is in Slot B THEN <11>
lea RBV32b,a3 ; point to RBV Slot B table <11>
bra.s @gotSlot ; ELSE <11>
@slotE lea RBV32e,a3 ; point to RBV Slot E table <11>
@gotSlot ; ENDIF <11>
bfextu newtc(a3){8,4},d0 ; get # addr bits for pageSize <11>
moveq #0,d6 ; clear a reg
bset d0,d6 ; get our pagesize
move.l sgTotalRAM(a6),d0 ; get total amt memory (for GetRBVSize) <SM6> CSS
moveq #0,d1 ; signal no rounding, we want the REAL size
move.l RBVAddr(a0),a0 ; get addr of RBV hardware <11>
movea.l prodInfoPtr(a5),a2 ; pass addr of productInfo record in a2 <3.0>
bsr GetRBVSize ; get actual video buffer size
move.l d0,VRAMrealSize(a5) ; save it for later <9>
move.l sgTotalRAM(a6),d0 ; get total amt memory (for GetRBVSize) <SM6> CSS
move.l d6,d1 ; rounding factor = MMU page size
bigjsr GetRBVSize,a4 ; get monitor size, rounded up to pagesize
move.l d0,VRAMSize(a5) ; save it for later <9>
beq @split ; if no monitor, its easy!
tst.l d2 ; check if any memory in Bank A
bne @split ; if no Bank A, its easy!
sub.l d0,d3 ; subtract monitor size from bank A
move.l d3,globChunks+4(a5) ; update RAM chunk table
add.l d0,d2 ; add monitor size to bank A start addr
move.l d2,globChunks(a5) ; update RAM chunk table
sub.l d0,sgPhys2Log(a6) ; adjust physical-to-logical conversion offset <SM6> CSS
move.l a3,a0 ; point to RBV table <11>
lea globChunks+8(a5),a1 ; get pointer to second chunk <T23>
tst.l sgEDiskStealFlag(a6); check for ram disk <SM6> CSS | <SAM>
beq.s @noRamDisk ; IF there is a ram disk THEN v
add.l #8,a1 ; point at third chunk
@noRamDisk ; ENDIF
tst.l (a1) ; check for bank B ^
bmi.s @noBankB ; IF Bank B exists |
IF forRomulator THEN ; •••Note: Romulator won't work with an Edisk <T23>
TestInRam A2 ; are we running in ram? <3.8>
beq.s @inROM ; if not, skip this <3.8>
BigLea BaseOfRom,a2 ; get current base of ROM <3.8>
lsl.l #1,d1 ; add an extra page to bootglobs <3.8>
add.l ROMHeader.RomSize(a2),d1 ; increase size of bootglobs by ROM size <3.8>
@inROM ;
ENDIF ; <3.8>
tst.l sgEDiskStealFlag(a6); check for ram disk <SM6> CSS <SAM>
bne.s @ramDiskExists ; IF there is no ram disk THEN
sub.l d1,d5 ; decrement Bank B size by pagesize
@ramDiskExists ; ENDIF <T23>
lea globChunks(a5),a1 ; point at beginning of chunk table
move.l d4,(a1)+ ; put Bank B (addr) first in Ram chunk table
move.l d5,(a1)+ ; put Bank B (size) first in Ram chunk table
move.l d2,(a1)+ ; put Bank A (addr) second in Ram chunk table
move.l d3,(a1)+ ; put Bank A (size) second in Ram chunk table
tst.l sgEDiskStealFlag(a6); check for ram disk <T23> <SM6> CSS <SAM>
bne.s @noBankB ; IF there is no ram disk THEN <T23>
add.l d5,d4 ; get addr of last <pagesize> chunk
move.l d4,(a1)+ ; put addr last little chunk in table
move.l d1,(a1)+ ; put size last little chunk in table
moveq #-1,d4 ; get end of table marker
move.l d4,(a1)+ ; put end marker in table
move.l d4,(a1)+ ; put end marker in table
; ENDIF <T23>
@noBankB ; ENDIF
move.l #RBVBase24b,d2 ; get the 24-bit video base address <14>
move.l logVRAMBase24(a5),d3 ; get the 24-bit video base addr for this machine <14>
andi.l #$ffffff,d2 ; ensure these are 24-bit addrs... <14>
andi.l #$ffffff,d3 ; same here <14>
cmp.l d3,d2 ; check which slot video is in <14>
bne.s @inSlotE ; IF RBV is in Slot B THEN <11>
lea RBV24b,a1 ; point to RBV Slot B table <11>
bra.s @done ; ELSE <11>
@inSlotE lea RBV24e,a1 ; point to RBV Slot E table <11>
@done ; ENDIF <11>
bra.s @endSwitch ; ...
;--- <12>
; VISA chip: Generally, the VISA code is similar to the HMMU (that is, there isn't any
; hardware, and it doesn't do anything). This code also whacks the ChunkTable
; to adjust for usage of RAM by the video system. There's no possibility of
; the split RAM case (big block in bank B), since there's no PMMU at all.
;
; For Slice there is no on-board video so no need to allocate a video buffer. <H22><SM13>
; All we need to do is allocate a 4k sound buffer. <H22> <SM13>
;---
@VISA ; CASE VISA chip:
sub.l #$00001000,sgAllocOff(A6) ; allocate 4k sound buffer <H22><SM13>
lea FstrFrms24,a1 ; point to 24 bit MMU info table <H18>
lea FstrFrms32,a0 ; point to 32 bit MMU info table <H18>
bra @endSwitch ; <H22><SM13>
@split ; ELSE (no RBV, just split memory)
move.l smallest(a5),d0 ; get size smallest chunk
bfffo d0{0,0},d0 ; get 32-log2(size)
subq.w #5,d0 ; normalize to 64 meg
muls.w #-MMUSetupInfo.Size,d0; compute offset from 64 meg entry
lea (split64mb32,d0.w),a0; return addr 32 bit mode layout
lea Split24,a1 ; return split 24 bit mode layout info
;fallThru bra.s @endSwitch ; ...
@endSwitch ; ENDSWITCH
movem.l (sp)+,FindRegs ; restore work registers
rts
;-----
; MakePhysicalTable
;
; Create the 'physical table' describing the significant portions of the physical
; address space. Use the physical template to create the table.
;
; The table is actually created into a buffer on the stack, then copied to space
; allocated below BootGlobals.
;
; Entry
; a0 - points to 32 bit mode layout info
; a5 - points to InitMMU stack frame
; a6 - points to BootGlobs
;
; Exit
; physical table created (in BootGlobs)
;---
MakPhysRegs REG a1-a2
MakePhysicalTable
movem.l MakPhysRegs,-(sp) ; save work registers
suba.w #physBufSize,sp ; allocate buffer on stack
move.l sp,a2 ; save ptr to buffer start
move.l a2,a1 ; init buffer fill ptr
add.w physicalOff(a0),a0 ; scan ptr = addr physical template
@loop ; LOOP for each entry
move.w PhysicalSpaceBlock.usage(a0),d0;get template entry type
cmp.w #kUsageEndTable,d0 ; check it
beq.s @exitLoop ; >>EXITLOOP if end-of-table
cmp.w #kUsageRAM,d0 ; check it again
bne.s @notRam ; IF its a RAM entry
bsr doPhysRam ; generate RAM entries
adda.w #PhysicalSpaceBlock.size,a0 ; point at next template entry
bra.s @loop ; .
@notRam cmp.w #kUsageROM,d0 ; ELSEIF its a ROM entry
bne.s @notRom ; .
bsr doPhysRom ; generate ROM entry
adda.w #PhysicalSpaceBlock.size,a0 ; point at next template entry
bra.s @loop ; .
@notRom ; ELSE
moveq #PhysicalSpaceBlock.size-1,d0; prepare to copy entry to buffer
@copy move.b (a0)+,(a1)+ ; LOOP - copy next byte
dbra d0,@copy ; REPEAT
; ENDIF
bra.s @loop ; REPEAT
@exitLoop
suba.l a2,a1 ; size = end - start
move.l a1,d1 ; save size of entries
addq.l #PhysicalSpace.firstEntry-PhysicalSpace,a1 ; add in extra fields
move.l a6,a0 ; get ptr to BootGlobs
move.l sgAllocOff(a6),d0 ; get current allocation offset <SM6> CSS
sub.l a1,d0 ; allocate space for physical table
move.l d0,sgPhysicalTableOff(a6) ; save offset to physical table <SM6> CSS
move.l d0,sgAllocOff(a6) ; update allocation offset <SM6> CSS
add.l d0,a0 ; get ptr to allocated table
move.l d1,d0 ; get total size of entries
divu #PhysicalSpaceBlock.size,d0 ; # entries = (total size)/(entry size)
move.w d0,(a0)+ ; write # entries
move.w #PhysicalSpaceBlock.size,(a0)+ ; write entry size
bra.s @endCopy ; adjust for dbra
@copyLoop move.b (a2)+,(a0)+ ; LOOP - copy byte from buffer to final table
@endCopy dbra d1,@copyLoop ; REPEAT for all bytes of entries in buffer
adda.w #physBufSize,sp ; de-allocate buffer from stack
movem.l (sp)+,MakPhysRegs ; restore registers
rts
;-----
; doPhysRam - local subroutine of MakePhysicalTable to generate RAM entries in the
; physical table.
;
; First, if onboard video uses some RAM, entries are generated for both the video
; and the wrap of the logical space before and afet the video buffer (to accomodate <3.2>
; the Quickdraw bug of accessing a few bytes before and after the video buffer). <3.2>
;
; Then, a RAM entry is generated for each RAM chunk from our 'massaged' RAM chunk
; table. The first RAM entry is marked as low memory, so VM knows where low
; memory really is. We also duplicate the last entry, because we need to
; divide the last chunk into useable Ram and boot globals space. Later we will
; go back and adjust the addesses and sizes to reflect the actual size of the
; boot globals/mmu tables area.
;
; Entry
; a0 - points to physical template entry
; a1 - buffer fill ptr where physical table is being generated
; a2 - points to start of buffer
; a5 - points to InitMMU stack frame
; a6 - points to boot globs
;
; Exit
; a1 - updated buffer fill ptr (after RAM entries are added)
; a0-a2 preserved
;---
doPhysRegs REG d2-d4/a3-a4
doPhysRam movem.l doPhysRegs,-(sp) ; save registers
move.l VRAMrealSize(a5),d0 ; get exact onboard video size <9>
beq.s @doneVideo ; IF any onboard video
move.l VRAMPhysBase(a5),d4 ; get physical base <T11>
moveq #kUsageOnboardVideo,d1 ; entry type = onboard video <3.2, to end 3.2>
move.l logVRAMBase32(a5),d2 ; logical 32 addr <9>
move.l logVRAMBase24(a5),d3 ; logical 24 addr <T11>
bsr @writeOne ; create entry for real video buffer
add.l d0,d2 ; log 32 addr = end of video buffer
add.l d0,d3 ; log 24 addr = end of video buffer <T11>
move.l #VidWrapSize,d0 ; size = size of wrap area <9>
moveq #kUsageOnboardVideoWrap,d1 ; entry type = onboard video WRAP
bsr.w @writeOne ; create entry for wrap area after video buffer <SM13>
move.l logVRAMBase32(a5),d2 ; wrap area before video buffer <9>
sub.l d0,d2 ; calculate start of wrap area <9>
move.l logVRAMBase24(a5),d3 ; logical 24 addr <T11>
sub.l d0,d3 ; calculate start of wrap area <T11>
bsr.w @writeOne ; for wrap area before video buffer <T11><SM13>
@doneVideo ; ENDIF
tst.l sgEDiskStealFlag(a6) ; check for ram disk <SM6> CSS <T11> <SAM>
beq.s @doneEDisk ; IF any ram disk THEN |
move.l #kUsageEDisk,d1 ; entry type = ram disk v
move.l sgRamDiskBase(a6),d2 ; logical 32 base = from globals <SM6> CSS
clr.l d3 ; no access in 24-bit mode
lea eDiskChunks(a5),a3 ; point at ram disk chunk table
@eDiskLoop ; LOOP (to write entries for eDisk chunks)
move.l (a3)+,d4 ; get chunk addr
move.l (a3)+,d0 ; get chunk size
cmp.l #-1,d4 ; check for end of chunks
beq.s @doneEDisk ; >>EXITIF done all ram disk chunks
bsr @writeOne ; write a physical table entry
add.l d0,d2 ; bump up logical pointer ^
bra.s @eDiskLoop ; REPEAT |
@doneEDisk ; ENDIF <T11>
moveq #kUsageLowMemory,d0 ; start w/type = low memory
lea globChunks(a5),a3 ; point at massaged RAM chunk table
@ramLoop ; LOOP through RAM chunk table
movem.l (a3)+,d1-d2 ; get chunk addr/size
cmp.l #-1,d1 ; check for end of chunks
beq.s @doneRam ; >>EXITIF done all RAM chunks
move.l a1,a4 ; remember pointer to last RAM entry
move.w d0,(a1)+ ; type = current type
move.w #cacheable,(a1)+ ; attributes = cacheable
move.l d1,(a1)+ ; physical addr = RAM chunk addr
move.l d2,(a1)+ ; physical size = RAM chunk size
clr.l (a1)+ ; logical 32 addr = (don't care)
clr.l (a1)+ ; logical 32 size = (don't care)
clr.l (a1)+ ; logical 24 addr = (don't care)
clr.l (a1)+ ; logical 24 size = (don't care)
moveq #kUsageRam,d0 ; next type = normal RAM
bra.s @ramLoop ; REPEAT
@doneRam
move.l a4,d0 ; get ptr to last RAM chunk entry
sub.l a2,d0 ; buffer offset = ptr - start of buffer
addq.l #PhysicalSpace.firstEntry-PhysicalSpace,d0 ; account for extra fields
move.l d0,lastPhysRam(a5) ; save offset to last RAM chunk entry
moveq #PhysicalSpaceBlock.size-1,d0;prepare to copy last RAM chunk entry
@copy move.b (a4)+,(a1)+ ; LOOP - copy next byte
dbra d0,@copy ; REPEAT
move.l soundBufferSize(a5),d0 ; is there a sound buffer on this machine? <H25><SM13>
beq.s @NoSoundBuffer ; -> nope, all done <H25><SM13>
clr.w (a1)+ ; entry type = other <H25><SM13>
move.w #notCacheable,(a1)+ ; attributes = notCacheable <H25><SM13>
move.l soundBufferBase(a5),(a1)+ ; physical addr = base of sound buffer <H25><SM13>
move.l d0,(a1)+ ; physical size = size of sound buffer <H25><SM13>
clr.l (a1)+ ; logical 32 addr = (don't care) <H25><SM13>
move.l d0,(a1)+ ; logical 32 size = size of sound buffer <H28><SM13>
clr.l (a1)+ ; logical 24 addr = (don't care) <H25><SM13>
move.l d0,(a1)+ ; logical 24 size = size of sound buffer <H28><SM13>
@NoSoundBuffer ; <H25><SM13>
movem.l (sp)+,doPhysRegs ; restore regs
rts
;------
; mini-routine to write a non-cached physical space entry
; d0 - size
; d1 - entry type
; d2 - logical 32 addr
; d3 - logical 24 addr
; d4 - physical addr
; a1 - pointer to next free entry
;------
@writeOne move.w d1,(a1)+ ; write out entry type
move.w #notCacheable,(a1)+ ; attributes = notCacheable <T11>
move.l d4,(a1)+ ; physical addr = video base addr <T11>
move.l d0,(a1)+ ; physical size
move.l d2,(a1)+ ; logical 32 addr
move.l d0,(a1)+ ; logical 32 size
move.l d3,(a1) ; logical 24 addr
andi.l #$00FFFFFF,(a1)+ ; strip high byte of 24 bit addr
move.l d0,(a1)+ ; logical 24 size
rts
;-----
; doPhysRom - local subroutine of MakePhysicalTable to generate the Rom entry in the
; physical table.
;
; The physical address in the entry is the physical address of the ROM image, which might
; be in RAM if we are using Romulator™. The size is obtained from the Rom header.
;
; Entry
; a0 - points to physical template entry
; a1 - buffer fill ptr where physical table is being generated
; a2 - points to start of buffer
; a5 - points to InitMMU stack frame
;
; Exit
; a1 - updated buffer fill ptr (after RAM entries are added)
; a0-a2 preserved
;---
doPhysRom exg a3,d1 ; save register
move.w PhysicalSpaceBlock.usage(a0),(a1)+ ; <SM1> CSS get usage type <H18>
move.w PhysicalSpaceBlock.attributes(a0),(a1)+ ; <SM1> CSS get the attributes <H18>
move.l PhysicalSpaceBlock.physical.rangeSize(a0),d0 ; <SM1> CSS <H18>
cmpi.l #$10000000,d0 ; <SM1> CSS is the size 256MB ? <H18>
bne.s @doNew ; <SM1> CSS if 256MB then generate ROM entry the old way otherwise get<H18>
; ; <SM1> CSS actual values from the physical space template
biglea BaseOfRom,a3 ; get physical addr Rom image
move.l a3,(a1)+ ; physical addr = image addr
move.l RomHeader.RomSize(a3),d0 ; get Rom image size from header
move.l d0,(a1)+ ; physical size = image size
exg a3,d1 ; restore reg
move.l logRomBase(a5),d1 ; get logical addr ROM
move.l d1,(a1)+ ; logical 32 addr
move.l d0,(a1)+ ; logical 32 size...
and.l #$FFFFFF,d1 ; get 24 bit mode address of ROM
move.l d1,(a1)+ ; logical 24 addr...
move.l d0,(a1)+ ; logical 24 size...
bra.s @done ; <SM1> CSS <H18>
@doNew move.l PhysicalSpaceBlock.physical.address(a0),(a1)+ ; <SM1> CSS get the physical address of the rom bank <H18>
move.l d0,(a1)+ ; <SM1> CSS physical size of rom image from template <H18>
move.l PhysicalSpaceBlock.logical.address(a0),(a1)+ ; <SM1> CSS get the logical 32 bit Rom bank address <H18>
move.l PhysicalSpaceBlock.logical.rangesize(a0),(a1)+ ; <SM1> CSS get the logical 32 bit Rom bank size <H18>
move.l PhysicalSpaceBlock.logical24.address(a0),(a1)+ ; <SM1> CSS get the logical 24 bit Rom bank address <H18>
move.l PhysicalSpaceBlock.logical24.rangesize(a0),(a1)+ ; <SM1> CSS get the logical 32 bit Rom bank size <H18>
@done exg a3,d1 ; <SM1> CSS restore reg <H18>
rts
;-----
;
; MakeTable - creates an MMU table.
;
; First an intermediate table is generated, given the installed RAM and the desired
; logical map. Then the final MMU table entries are generated from the intermediate table.
;
; The intermediate table entries are formatted as follows:
;
; 31 8 7 6 5 43 2 10
; +--------------------------------+-+-+-+--+-+--+
; | page address or table limit |0|c|0|xx|0|yy|
; +--------------------------------+-+-+-+--+-+--+
; c - cache inhibit bit (one if cache should be inhibited, zero if not)
; xx - level in table. Level one corresponds to TIA, four to TID
; yy - descriptor type
;
; Each intermediate entry corresponds to some piece of the logical address space. For
; instance, if the tc specifies 16 TIA entries, there would be 16 level 1 entries.
;
; The intermediate entry is generated to allow easy creation of the final MMU table.
; Entries for the same level are laid out consecutively until it is determined that
; a deeper level is needed, or until the entire address space for that level has been
; covered.
;
; If a deeper level is needed, entries are laid out for that deeper level, followed
; by an entry for the parent level with a descriptor type of 'table'. The sequence
; of levels for a tc w/16 TIA entries, xx TIB entries, yy TIC entries might look like:
;
; 1111223333...322..2111111111111
; | | - level 1 'table' entry, possible w/limit for the preceeding run
; | of level 2's
; |
; | - level 2 'table' entry, possibly w/limit
;
; In the above example, the level 2's even had a nested level 3 table!
;
; Entry: a0 points to table layout info
; a5 points to InitMMU stack frame
;
; Exit: a0 points to created table
; d0 has 1st longword of CRP
;-----
tableSize EQU $30000 ; get 192k of space for intermediate table <7>
MakeFrame RECORD {prevLink},DECR
Return ds.l 1 ; return addr
prevLink ds.l 1 ; previous value of link register
mmuSetupPtr ds.l 1 ; ptr to mmu setup information
templatePtr ds.l 1 ; pointer to template
logicalAddr ds.l 1 ; current logical address
genPtr ds.l 1 ; ptr into "intermediate form" table
ramChunks ds.l sgMaxChunks*2 ; space for copy of RAM chunks (addr/size) (last addr -1) <SM6> CSS
eDskChunks ds.l sgMaxChunks*2 ; space for copy of edisk chunks (addr/size) (last addr -1) <T11> <SM6> CSS
vidAddr ds.l 1 ; video chunk addr (get bumped up as allocated)
vidSize ds.l 1 ; video chunk size (gets bumped down as allocated)
doWrap24 ds.w 1 ; true if we need to wrap tables for 24-bit mode <7>
intermedTbl ds.l 1 ; start of intermediate table <7>
makeLocSize equ * ; size of locals
ENDR
NoLimit equ $7FFF0000 ; what to stuff in limit field when there is no limit
WITH MakeFrame
MakeTable
MakeRegs REG d2/a1
link a4,#makeLocSize-tableSize ; set up stack frame <7>
movem.l MakeRegs,-(sp) ; save registers
move.l a0,mmuSetupPtr(a4) ; save ptr to MMU setup info
move.w templOff(a0),d0 ; get offset to normal template
btst.b #mmHighSysHeap,sgMMFlags(a6) ; check if creating map w/huge void <SM6> CSS
beq.s @haveTempl ; IF we are
move.w specialOff(a0),d0 ; get offset to special template
@haveTempl add.w d0,a0 ; ENDIF - add in template offset
move.l a0,templatePtr(a4) ; save ptr to template
lea globChunks(a5),a0 ; source = ram chunk table from InitMMU globals
lea ramChunks(a4),a1 ; destination = our local copy
bsr.s CopyChunks ; get a local copy of chunk table
lea eDiskChunks(a5),a0 ; source = ram disk chunk table from globals <T11>
lea eDskChunks(a4),a1 ; destination = our local copy <T11>
bsr.s CopyChunks ; get a local copy of chunk table <T11>
move.l VRAMPhysBase(a5),vidAddr(a4) ; get local copy of base of video RAM <9>
move.l VRAMSize(a5),vidSize(a4) ; get local copy of size of video buffer <9>
bsr.s IntermediateTable ; make the intermediate table
bsr FinalTable ; make the final MMU tables
movem.l (sp)+,MakeRegs ; restore registers
unlk a4 ; deallocate stack frame
rts
;-----
; IntermediateTable - wrapper routine for creating the intermediate form table.
;
; The table is created using two mutually recursive routines, DoLevel and DoNode.
; DoLevel is responsible for creating all nodes at a given level. It calls DoNode
; to create each node.
;
; DoNode attempts to create a node at the current level. If it determines that a node
; can be created at the current level (a contiguous physical space is possible for the
; current logical address mapping and the span of the current level), it quickly does so
; and returns. Otherwise, a lower level table is neccessary, and it calls DoLevel to
; create the lower level entries in the intermediate table.
;
; This routine simply sets up for generating nodes at the top level, and calls DoLevel.
; Before returning, it appends a dummy level zero node to the end of the intermediate
; table, to make generating the final MMU tables easier.
;
; Entry:
; a4 - points to MakeTable stack frame
;
;---
IntermediateTable
move.l d2,-(sp) ; save work reg
lea intermedTbl(a4),a0 ; get ptr to where intermediate table will go
move.l a0,genPtr(a4) ; save ptr to intermediate table
clr.l logicalAddr(a4) ; start at logical address zero
clr.w doWrap24(a4) ; assume generating for 32-bit mode <7>
moveq #1,d0 ; start at level one
bsr.s DoLevel ; create level 1 (and higher!) intermediate table
moveq #0,d2 ; signal writing table node for level zero
bsr WriteTableNode ; write the final table node
move.l (sp)+,d2 ; restore work reg
rts
;-----
; DoLevel - create intermediate table entries for a given level of the MMU tree.
;
; Entry:
; d0.w - the level
;---
DoLevelRegs REG d2-d4
DoLevel movem.l DoLevelRegs,-(sp) ; save regs
move.w d0,d2 ; save level of interest
bsr SpanAndCount ; d0 = span, d1 = count of entries at this level
move.l d0,d3 ; save span
move.l d1,d4 ; save count
bra.s @endLoop ; adjust loop count for dbra
@loop ; LOOP count times
bsr.s DoNode ; create next node
@endLoop dbra d4,@loop ; REPEAT
movem.l (sp)+,DoLevelRegs ; restore regs
rts
;-----
; DoNode - create a node in the intermediate table, given the current table level and
; logical address.
;
; Entry:
; d2.w - level
; d3 - span of this level (passed in for convenience, could be recomputed here)
; a4 - points to MakeTable stack frame
;---
DoNode bsr.s PageAddr ; a0 = page address, d0 = type, d1 = cache inhibit flag
move.b @casetbl(d0),d0 ; get offset to routine to handle type
jmp @casetbl(d0.w) ; SWITCH(type)
@casetbl dc.b @valid-@casetbl ; .
dc.b @invalid-@casetbl ; .
dc.b @noFit-@casetbl ; .
dc.b @endCase-@casetbl ; .
ALIGN 2 ; .
@valid ; CASE(type = valid)
bsr WritePageNode ; write page node(level, page addr, cache flag)
bra.s @endCase ; ...
@invalid ; CASE(type = invalid)
bsr WriteInvalidNode ; write invalid node(level)
bra.s @endCase ; ...
@noFit ; CASE(type = didn't fit)
bsr CanGoDeeper ; see if we can go to next level
beq.s @noDeeper ; IF we can
move.w d2,d0 ; recall level
addq.w #1,d0 ; bump to next level
bsr.s DoLevel ; make entries at next level
bsr WriteTableNode ; write a table node (level)
bra.s @endCase ; ...
@noDeeper ; ELSE
bsr WriteInvalidNode ; write invalid node (level)
; ENDIF
;fallthru bra.s @endCase ; ...
@endCase ; ENDSWITCH
rts
;-----
; PageAddr - given logical address and level span, return information about the physical
; page where it will map to
;
; Entry:
; a4 - points to MakeTable stack frame
; a5 - points to InitMMU stack frame <3.2>
; d2.w - level
; d3 - span of this level (passed in for convenience, could be recomputed here)
;
; Exit
; d0.w - type (0 = valid page, 1 = invalid page, 2 = didn't fit)
; d1.w - cache inhibit flag in bit 6
; a0 - page address
;---
WITH Template
PageRegs REG d3-d5
PageAddr movem.l PageRegs,-(sp) ; save regs
move.l templatePtr(a4),a0 ; get ptr to template table
moveq #0,d5 ; template logical address = zero
move.l logicalAddr(a4),d0 ; get our current logical addr
@loop ; LOOP
move.l span(a0),d1 ; get chunk size
move.l d0,d4 ; recall our current logical address
sub.l d5,d4 ; get offset from start of template chunk
cmp.l d4,d1 ; check if we're in this chunk's range
bhi.s @exitLoop ; >>EXITLOOP if logical addr falls in this chunk
add.l d1,d5 ; bump template chunk address by size this chunk
addq.l #tEntrySize,a0 ; point at next template entry
bra.s @loop ; REPEAT
@exitLoop ; at this point: a0 -> template entry,
; d1 = template chunk size, d2 -> bottom of chunk,
; d3 = level span, d4 = our offset from bottom of chunk
move.l d3,d0 ; save level span
add.l d4,d3 ; get offset + span
cmp.l d3,d1 ; check against size of chunk
bhs.s @fits ; IF logical span doesn't fit in template chunk
moveq #2,d0 ; returned type = "doesn't fit"
bra @done ; EXITROUTINE
@fits ; ENDIF
move.l physNflag(a0),d3 ; get phys addr/flags word <7>
move.l d3,d5 ; copy for getting type bits <7>
and.l #typeMask,d5 ; mask all except type bits <7>
move.b @casetbl(d5),d5 ; get offset to routine to handle type
jmp @casetbl(d5.w) ; SWITCH(type)
@casetbl dc.b @thru-@casetbl ; .
dc.b @ram-@casetbl ; .
dc.b @rom32-@casetbl ; .
dc.b @rom24-@casetbl ; .
dc.b @vidWrap-@casetbl ; .
dc.b @video-@casetbl ; .
dc.b @mapped-@casetbl ; .
dc.b @Void-@casetbl ; .
dc.b @wrap24-@casetbl ; . <7>
dc.b @vram-@casetbl ; . <9>
dc.b @eDisk-@casetbl ; . <T11>
ALIGN 2 ; .
@thru ; CASE(pass thru)
move.l logicalAddr(a4),a0 ; page address = current logical address
bra.s @valid ; returned type = "valid page"
@ram ; CASE(ram)
bsr.w GrabRam ; allocate from RAM chunks, return type, page addr
bra.s @endSwitch ; ...
@wrap24 ; CASE(24-bit wrap area) <7>
move.w #1,doWrap24(a4) ; fall through, and mark "invalid" <7>
@Void ; CASE(void in the middle of RAM)
moveq #1,d0 ; mark page as "invalid"
bra.s @endSwitch ; ...
@rom32 ; CASE(rom, 32 bit mode)
move.l physRomBase(a5),d0 ; assume running in ROM (use real h/w address)<H12>
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <H12>
beq.s @nomask ; IF NOT on a 68040 THEN <H12>
btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block<H12>
bne.s @nomask ; IF Full Tables NOT wanted then <H12>
and.l #$ff000000,d0 ; mask to just use high byte of phys addr <H12>
@nomask move.l d0,a0 ; ENDIF <H12>
bra.s @romCommon ; (continue w/common code) <H12>
@rom24 ; CASE(rom, 24 bit mode) <H12>
move.l physRomBase(a5),a0 ; assume running in ROM (use phys addr) <H12>
@romCommon
IF forRomulator THEN ; <3.7>
biglea BaseOfROM,a0 ; point to start of ROM image in RAM
ENDIF ; <3.7>
@gotROM ; ENDIF
add.l d4,a0 ; returned page addr = start of ROM + offset from
; .start of template chunk
bra.s @valid ; returned type = "valid page"
@vidWrap ; CASE(wrap to start of video)
move.l VRAMPhysBase(a5),a0 ; get physical base of video buffer <9>
bra.s @valid ; ...
@video ; CASE(video)
bsr GrabVideo ; allocate from vRAM chunks, return type, page addr
bra.s @endSwitch ; ...
@vram ; CASE(vram) <9>
move.l VRAMPhysBase(a5),a0 ; get physical base of video RAM <9>
; adda.l d4,a0 ; returned page addr = start + offset <T11>
bra.s @valid ; ... <9>
@eDisk ; CASE(ram disk) <T11>
bsr GrabEdisk ; allocate from eDisk chunks, return type, page addr
bra.s @endSwitch ; ... <T11>
@mapped ; CASE(mapped)
move.l d3,d0 ; get phys addr/flags word
and.l #physMask,d0 ; mask all except suggested physical addr <7>
move.l d0,a0 ; returned page addr = suggested phys addr <7>
add.l d4,a0 ; .plus offset from start of template chunk
@valid moveq #0,d0 ; returned type = "valid page"
;fallThru bra.s @endSwitch ; ...
@endSwitch ; ENDSWITCH
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <7>
beq.s @on040 ; IF NOT on a 68040 THEN <7>
btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block<H12>
beq.s @term ; IF Full Tables wanted then <H12>
and.l #cBitMask,d3 ; get cache inhibit bit <H12>
bra.s @fullTables ; check table level <H12>
; ELSE
@term and.l #cBitMask,d3 ; get cache inhibit bit <7><H12>
bra.s @setCache ; ELSE <7><H12>
@on040 and.l #c040ModeMask,d3 ; get cache mode bits <7>
@fullTables bsr.w CanGoDeeper ; check if we are at the lowest Level <7><H12>
beq.s @setCache ; >>EXITROUTINE if NOT on lowest level <7><H12>
cmp.w #0,d0 ; check if we would have returned valid <7>
bne.s @setCache ; >>EXITROUTINE if NOT returning valid <7>
moveq #2,d0 ; can't have a page descriptor yet, return "doesn't fit" <7>
@setCache ; ENDIF <7>
lsl.l #6-cBitNum,d3 ; move it into position <7>
move.w d3,d1 ; return it
@done movem.l (sp)+,PageRegs ; restore regs
rts
ENDWITH ; {Template}
;-----
; GrabRAM - allocate some space from the chunks of RAM.
;
; The procedure scans the chunks, looking for one that has a non-zero size.
; It then determines whether the allocation amount fits in that chunk. No attempt
; is made to look at other chunks (if it doesn't fit in the first non-zero sized one)
; in order to preserve the ordering present in the chunk table.
;
; Entry:
; a4 - ptr to MakeTable stack frame
; d0 - amount to allocate
; d2.w - level
; d3 - phys addr/flags
;
; Exit:
; a0 - ptr to the RAM chunk
; d0 - type, as follows:
; zero: valid (allocation was successful)
; one: invalid (no RAM available)
; two: didn't fit (requested size didn't fit in first available chunk)
;
; if successful, RAM chunk's size reduced by allocation amount.
;
; Trashes
; d1
;---
GrabRAM lea ramChunks(a4),a0 ; point at table of RAM chunks
move.l d0,d1 ; save allocation amt
moveq #1,d0 ; assume returning "invalid" (no RAM available)
@loop cmp.l #-1,(a0)+ ; LOOP while more chunks
beq.s @done ; >>EXITROUTINE if no more chunks
tst.l (a0)+ ; check size of chunk
beq.s @loop ; REPEAT while nothing in this chunk
moveq #2,d0 ; assume returning "didn't fit"
cmp.l -4(a0),d1 ; check size versus desired size
bhi.s @done ; IF chunk is big enough
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <H12>
beq.s @fulltbl ; IF on a 68040 THEN <H12>
btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block <H12>
beq.s @term ; IF Full Tables wanted then <H12>
@fulltbl bsr.w CanGoDeeper ; check if on lowest level <7><H12>
bne.s @valid ; >>EXITROUTINE if we're not on lowest level <7>
; ENDIF <7>
@term move.l -8(a0),d0 ; page addr = start addr chunk <H12>
add.l d1,-8(a0) ; increment start addr by allocation amt
sub.l d1,-4(a0) ; decrement chunk size by allocation amt
move.l d0,a0 ; return page addr
@valid moveq #0,d0 ; returned type = "valid"
@done ; ENDIF
rts
;-----
; GrabVideo - allocate some space from the RAM allocated to video
;
; Entry:
; a4 - ptr to MakeTable stack frame
; a5 - points to InitMMU stack frame <3.2>
; d0 - amount to allocate
; d2.w - level
; d3 - phys addr/flags
;
; Exit:
; If requested size didn't fit in video RAM chunk
; d0 - two (didn't fit)
; a0 - undefined
; If all video RAM already allocated
; d0 - zero (valid page)
; a0 - base of video RAM (makes end of buffer wrap to start) <3.2>
; If requested size successfully allocated from video RAM chunk
; d0 - zero (valid page)
; a0 - allocated RAM chunk addr
; video RAM chunk's size reduced by allocation amount.
;
; Trashes
; d1
;---
GrabVideo move.l d0,d1 ; save allocation amt
move.l VRAMPhysBase(a5),a0 ; assume no vRAM left, wrap to physical buffer base <9>
tst.l vidSize(a4) ; check remaining video RAM
beq.s @valid ; EXITROUTINE w/valid if none left <3.2>
moveq #2,d0 ; assume returning "didn't fit" (not enuf video RAM left)
cmp.l vidSize(a4),d1 ; check if there is enough
bhi.s @done ; EXITROUTINE if not enough left
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <H12>
beq.s @fulltbl ; IF on a 68040 THEN <H12>
btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block <H12>
beq.s @term ; IF Full Tables wanted then <H12>
@fulltbl bsr.s CanGoDeeper ; check if we'er on the lowest level <7><H12>
bne.s @valid ; >>EXITROUTINE if we're not on lowest level <7>
; ENDIF <7>
@term move.l vidAddr(a4),a0 ; return ptr to video RAM chunk <H12>
add.l d1,vidAddr(a4) ; bump video addr by allocation amt
sub.l d1,vidSize(a4) ; decrease remaining size by allocation amt
@valid moveq #0,d0 ; return "valid" <3.2>
@done rts
;-----
; GrabEdisk - allocate some space from the RAM allocated to the RAM disk
;
; The procedure scans the chunks, looking for one that has a non-zero size.
; It then determines whether the allocation amount fits in that chunk. No attempt
; is made to look at other chunks (if it doesn't fit in the first non-zero sized one)
; in order to preserve the ordering present in the chunk table.
;
; Entry:
; a4 - ptr to MakeTable stack frame
; d0 - amount to allocate
; d2.w - level
; d3 - phys addr/flags
;
; Exit:
; a0 - ptr to the RAM disk chunk
; d0 - type, as follows:
; zero: valid (allocation was successful)
; one: invalid (no RAM available)
; two: didn't fit (requested size didn't fit in first available chunk)
;
; if successful, RAM disk chunk size reduced by allocation amount.
;
; Trashes
; d1
;---
GrabEdisk
lea eDskChunks(a4),a0 ; point at table of eDisk chunks
move.l d0,d1 ; save allocation amt
moveq #1,d0 ; assume returning "invalid" (no RAM available)
@loop cmp.l #-1,(a0)+ ; LOOP while more chunks
beq.s @done ; >>EXITROUTINE if no more chunks
tst.l (a0)+ ; check size of chunk
beq.s @loop ; REPEAT while nothing in this chunk
moveq #2,d0 ; assume returning "didn't fit"
cmp.l -4(a0),d1 ; check size versus desired size
bhi.s @done ; IF chunk is big enough
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <H12>
beq.s @fulltbl ; IF on a 68040 THEN <H12>
btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block <H12>
beq.s @term ; IF Full Tables wanted then <H12>
@fulltbl bsr.s CanGoDeeper ; check if we'er on the lowest level <7><H12>
bne.s @valid ; >>EXITROUTINE if we're not on lowest level <7><H12>
; ENDIF <7>
@term move.l -8(a0),d0 ; page addr = start addr chunk
add.l d1,-8(a0) ; increment start addr by allocation amt
sub.l d1,-4(a0) ; decrement chunk size by allocation amt
move.l d0,a0 ; return page addr
@valid moveq #0,d0 ; returned type = "valid"
@done ; ENDIF
rts
;-----
; CanGoDeeper - check if we can generate tables at at next level
;
; Entry:
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit
; Z flag - ne if we can, eq if we can't
;
; Trashes
; none
;---
DeeperRegs REG d0/a0 ; <H12>
CanGoDeeper
movem.l DeeperRegs,-(sp) ;save working registers <H12>
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <7>
bne.s @not040 ; IF on a 68040 THEN <7>
cmp.w #3,d2 ; third level is the deepest we can go <7>
bra.s @done ; ELSE <7>
@not040 cmp.w #4,d2 ; fourth level is the deepest we can go <7>
@1 beq.s @done ; >>EXITROUTINE w/failure if at deepest level <7>
clr.l d0 ; so not to mess up bfextu down below <7>
move.w d2,d0 ; get level
addq.w #1,d0 ; get next level
lsl.w #2,d0 ; multiply by four (= TIx field size)
add.w #12,d0 ; get offset to TIx field
move.l mmuSetupPtr(a4),a0 ; get ptr to MMU setup info
bfextu newtc(a0){d0,4},d0 ; get TIx field for next level (eq if no TIx bits)
@done ; ENDIF <7>
movem.l (sp)+,DeeperRegs ; restore regs <H12>
rts
;-----
; WritePageNode - write a page node to the intermediate table.
;
; Entry:
; d1.w - cache inhibit flag
; d2.w - current level
; d3.l - logical address span of the node
; a0 - page address
; a4 - points to MakeTable stack frame
;
; Trashes:
; d0/a0
;---
WritePageNode
moveq #0,d0 ; clear a reg
move.w d2,d0 ; get the level
lsl.w #3,d0 ; shift level into place
or.w d1,d0 ; factor in the cache inhibit flag
add.l a0,d0 ; lay in the page address
addq.w #descrPage,d0 ; set type = 'page'
AdvAndWrite add.l d3,logicalAddr(a4) ; logical address += span of this entry
WriteNode move.l genPtr(a4),a0 ; get ptr to next intermediate table entry
move.l d0,-(a0) ; put entry into intermediate table <7>
move.l a0,genPtr(a4) ; save ptr to next entry
rts
;-----
; WriteInvalidNode - write an invalid page node to the intermediate table.
;
; Entry:
; d2.w - current level
; d3.l - logical address span of the node
; a4 - points to MakeTable stack frame
;
; Trashes:
; d0/a0
;---
WriteInvalidNode
moveq #0,d0 ; clear a reg
move.w d2,d0 ; get the level
lsl.w #3,d0 ; shift level into place
; NOTE: invalid type = 0, so its already there
bra.s AdvAndWrite ; advance logical address, write node to
; .intermediate table & EXIT
;-----
; WriteTableNode - write a table node to the intermediate table.
;
; Entry:
; d2.w - level
; a4 - points to MakeTable stack frame
;
; Trashes:
; d0/a0
;---
WriteTableNode
cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 <7>
bne.s @not040 ; IF on a 68040 THEN <7>
movea.l #NoLimit,a0 ; we don't have limit fields <7>
bra.s @1 ; ELSE <7>
@not040 bsr.s Limit ; get limit field
; ENDIF <7>
@1 moveq #0,d0 ; clear a reg
move.w d2,d0 ; get the level
lsl.w #3,d0 ; shift level into place
tst.w a0 ; check if low word of a0 is nonzero <T23>
bne.s @doWrite ; IF it is clear THEN <T23>
addq.w #descrTbl4,d0 ; set type to '4 byte table descriptor'
add.l a0,d0 ; factor in the limit field
or.w #LongStat,d0 ; put in rest of status field
@doWrite bra.s WriteNode ; write node to intermediate table & EXIT
; ENDIF
;-----
; Limit - given current level, looks backwards in intermediate table to see if
; a limit can be used on the next deeper level.
;
; If limit is possible, entries are shifted in the table to get rid of any entries
; made obsolete by the limit.
;
; Entry:
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit:
; a0 - limit field
;---
Limit move.l d3,-(sp) ; save work reg
bsr.s CountLeading ; get # leading invalid entries at next level
move.w d0,d3 ; save it
bsr.s CountTrailing ; get # trailing invalid entries at next level
move.w d0,d1 ; save it
or.w d3,d0 ; check for both zero
bne.s @yesLimit ; IF no leading OR trailing invalids
movea.l #NoLimit,a0 ; no limit!
bra.s @haveLimit ; .
@yesLimit cmp.w d1,d3 ; ELSEIF more trailing than leading
bhi.s @doLeading ; .
move.w d1,d0 ; recall # trailing invalids
bsr.s HandleTrailing ; handle upper limit case
bra.s @haveLimit ; .
@doLeading ; ELSE
move.w d3,d0 ; recall # leading invalids
bsr.s HandleLeading ; handle lower limit case
@haveLimit ; ENDIF
move.l (sp)+,d3 ; restore work reg
rts
;-----
; CountLeading - count the number of leading invalid entries for the next lower level.
;
; Entry:
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit:
; d0.w - # leading invalid entries
;---
CountLeading
moveq #0,d0 ; deal w/leading invalid entries later...
rts
;-----
; HandleLeading - purge the leading invalid entries at the next level from
; the intermediate table, and return an appropriate limit field.
;
; Entry:
; d0.w - # leading invalids
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit:
; a0 - limit field
;---
HandleLeading
move.l #NoLimit,a0 ; deal w/leading invalid entries later...
rts
;-----
; CountTrailing - count the number of trailing invalid entries for the next lower level.
;
; Entry:
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit:
; d0.w - # trailing invalid entries
;---
CountTrailing
moveq #0,d0 ; # trailing invalids = 0
move.l genPtr(a4),a0 ; get ptr to next intermediate table entry
@loop ; LOOP backwards thru intermediate table
move.l (a0)+,d1 ; get entry <7>
bfextu d1{30,2},d1 ; get descriptor type
bne.s @exitLoop ; >>EXITLOOP if not invalid
addq.w #1,d0 ; bump # trailing invalids
cmpa.l intermedTbl(a4),a0 ; check if we're at start of table
bne.s @loop ; REPEAT till start of table
@exitLoop rts
;-----
; HandleTrailing - purge the trailing invalid entries at the next level from
; the intermediate table, and return an appropriate limit field.
; Entry:
; d0.w - # trailing invalids
; d2.w - current level
; a4 - points to MakeTable stack frame
;
; Exit:
; a0 - limit field
;---
HandleTrailing
move.l d2,-(sp) ; save work reg
exg d2,d0 ; get current level, save # trailers
addq.w #1,d0 ; look at level we're getting limit for
bsr.s SpanAndCount ; get max # entries for that level
cmp.w d2,d1 ; check max entries against trailing invalids <T15>
blt.s @invalidLevel ; IF less invalids than max entries THEN |
sub.w d2,d1 ; limit = max # - # trailing v
subq.w #1,d1 ; limits are zero-based!
swap d1 ; get limit field in hi word
clr.w d1 ; zap low word
move.l d1,a0 ; return it
moveq #0,d0 ; clear a reg
move.w d2,d0 ; get # trailing invalids
bra.s @bumpPtr ; go bump intermediate table ptr
@invalidLevel ; ELSE
move.l d1,d0 ; use max number of entries <T15>
move.l #1,a0 ; return a bad limit <T23>
@bumpPtr ; ENDIF <T15>
lsl.l #2,d0 ; get size of their intermediate table entries
add.l d0,genPtr(a4) ; purge entries from intermediate table <7>
move.l (sp)+,d2 ; restore reg
rts
;-----
; SpanAndCount - get the address span of a given table level, and # entries at that level
;
; Entry
; d0.w - level
; a4 - ptr to MakeTable stack frame
;
; Exit
; d0.l - address span
; d1.w - count
;---
SpanAndCount
SpanRegs REG d2-d3
movem.l SpanRegs,-(sp) ; save regs
move.l mmuSetupPtr(a4),a0 ; get ptr to MMU setup info
cmp.w #cpu68040,d7 ; check if we are an 040 <7>
bne.s @not040 ; IF on a 68040 THEN <7>
clr.l d2 ; clear reg for span bits <7>
clr.l d3 ; clear reg for entry bits <7>
subq.w #1,d0 ; convert level into table index <7>
move.b (TIX040,d0.w*2),d2 ; get # of bits in this level's span <7>
move.b (TIX040+1,d0.w*2),d3; get # of bits in entry count for this level <7>
move.l #14,d0 ; bit # in TC to test for page size on 68040 <7>
btst d0,newtc(a0) ; check what size pages we're using <7>
beq.s @8kPages ; IF we're using 4k pages <7>
subq #1,d2 ; span goes down by half <7>
addq #1,d3 ; and number of entries doubles <7>
@8kPages ; ENDIF <7>
bra.s @done ; ELSE <7>
@not040 moveq #32,d2 ; start w/all address bits
bfextu newtc(a0){12,4},d1 ; get # initial shift bits
sub.l d1,d2 ; reduce total bits by initial shift
moveq #16,d1 ; get bit offset to 1st TIx field
subq.w #1,d0 ; adjust level for dbra
@loopTIx ; LOOP
bfextu newtc(a0){d1,4},d3 ; get # bits this level
sub.l d3,d2 ; reduce total by # bits this level
addq.w #4,d1 ; bump offset to next TIx field
dbra d0,@loopTIx ; REPEAT for all levels
; ENDIF <7>
@done moveq #0,d0 ; clear return reg
bset d2,d0 ; set address span for this level
moveq #0,d1 ; clear return reg
bset d3,d1 ; set # entries this level
movem.l (sp)+,SpanRegs ; restore regs
rts
TIX040 ; 68040 built-in table index field sizes (8k pages) <7>
LevelOne dc.b 25,7 ; 32M span, 128 entries <7>
LevelTwo dc.b 18,7 ; 256k span, 128 entries <7>
LevelThree dc.b 13,5 ; 8k span, 32 entries <7>
;-----
; FinalTable - generate the final MMU table from the intermediate table
;
; Entry:
; a4 - point to MakeTable stack frame
; intermediate table has been created
;
; Exit
; a0 - points to newly created MMU table
; d0 - has 1st word of crp (limit, descriptor type)
;---
FinalTable lea intermedTbl(a4),a0 ; get ptr to intermediate table
move.l a0,genPtr(a4) ; initialize scanning ptr
moveq #1,d0 ; start generating at level 1
bsr.s Generate ; generate the table
tst.w doWrap24(a4) ; wrap the tables for 24-bit mode? <7>
beq.s @noWrap ; IF we need to wrap tables THEN <7>
bsr Wrap24BitTable ; wrap tables for 24-bit mode <7>
@noWrap ; ENDIF <7>
move.l ([genPtr,a4],-4),d1 ; get next intermediate table entry <7>
add.w d0,d1 ; make type '8 byte' if sub-table is 8 byte
and.w #descrTypeMask,d1 ; crp doesn't have extra status field bits
cmp.b #PMMU851,sgTypeMMU(a6) ; check MMU type <SM6> CSS
bne.s @done ; IF we are on a 68851
bset #9,d1 ; set 'shared global' bit
@done ; ENDIF
move.l d1,d0 ; return crp
rts
;-----
; Generate - given a level, generate a (sub) table for that level
;
; Entry
; d0.w - level
;
; Exit
; d0.w - size (0 = short, 1 = long) of entries at this level
; a0 - ptr to generated table
;---
GenRegs REG d2-d4/a1-a2
Generate movem.l GenRegs,-(sp) ; save work regs
move.l d0,d4 ; save level
bsr.s CountAndSize ; get #, size table entries needed
move.w d0,d3 ; save count
move.w d1,d2 ; save size
bsr.s AllocTbl ; allocate space for the (sub) table
move.l a0,a1 ; set up fill ptr for table
move.l a0,a2 ; remember table address
bra.s @repeat ; adjust for dbra
@loop ; LOOP
move.l ([genPtr,a4],-4),d0 ; get next intermediate table entry <7>
bfextu d0{27,2},d1 ; get level of this entry
cmp.w d1,d4 ; check against level we're generating for
bhs.s @notTbl ; IF entry's level deeper than ours
move.w d4,d0 ; recall level we are working on
addq.w #1,d0 ; bump to deeper level
bsr.s Generate ; generate sub-table at next deeper level
bsr MakeTableEntry ; make a 4/8 byte table descriptor at fill ptr <16>
bra.s @next ; ...
@notTbl bne.s @weird ; ELSEIF entry's level = ours
bsr MakePageEntry ; make a 4/8 byte page/invalid entry at fill ptr
;fallThru bra.s @next ; ...
@next ; ENDIF
@repeat dbra d3,@loop ; REPEAT for all entries at this level
move.l a2,a0 ; return ptr to generated table
move.w d2,d0 ; return size of entries in generated table
movem.l (sp)+,GenRegs ; restore work regs
rts
@weird ; entry's level less deep than ours - SHOULD NEVER HAPPEN!
dc.w $A9FF ; trap to debugger, call Sculley
;-----
; CountAndSize - return number and size of entries for subtree at given level
;
; Number of entries is obtained by scanning forward in the intermediate table,
; counting entries at this level until a higher (lower in number) level entry
; is found. Size is assumed 4 byte, but is 8 byte if any of the intermediate
; table entries encountered at this level are 8 byte.
;
; Entry
; d0 - level
; a4 points to MakeTable stack frame
;
; Exit
; d0.w - number of entries
; d1.w - zero if 4 byte descriptors, one if eight byte descriptors
;---
CountRegs REG d2-d4
CountAndSize
movem.l CountRegs,-(sp) ; save work registers
move.w d0,d2 ; save level of interest
move.l genPtr(a4),a0 ; get ptr to itermediate table entry
moveq #0,d1 ; assume 4 byte descriptors
moveq #0,d0 ; count = zero
@loop ; LOOP
move.l -(a0),d3 ; get next intermediate table entry <7>
bfextu d3{27,2},d4 ; get level of this entry
cmp.w d4,d2 ; compare level to ours
bhi.s @done ; >>EXITIF level less deep than ours
bne.s @loop ; COUNTINUELOOP if not same level as ours
addq.w #1,d0 ; bump count
bfextu d3{30,2},d4 ; get type from entry
cmp.w #descrTbl4,d4 ; check it
bne.s @loop ; CONTINUELOOP if type ≠ "4 byte table"
swap d3 ; get limit field
cmp.w #NoLimit>>16,d3 ; check the limit
beq.s @loop ; CONTINUELOOP if no limit
moveq #1,d1 ; signal we'll need 8 byte descriptors
bra.s @loop ; REPEAT
@done movem.l (sp)+,CountRegs ; restore work regs
rts
;-----
; AllocTbl - allocate quadlong aligned space for MMU table from BootGlobs
;
; Entry
; d0.w - # entries in table
; d1.w - size of entries (0 = short, 1 = long)
; d4.w - level
; a6 - points to BootGlobs
;
; Exit
; a0 - ptr to allocated space
;
;-----
AllocTbl and.l #$FFFF,d0 ; clear hi word of # entries
addq.w #2,d1 ; convert size into scale factor
ext.l d1 ; clear hi word of size
lsl.l d1,d0 ; table size = scaled # entries
move.l a6,d1 ; get ptr to BootGlobs
add.l sgAllocOff(a6),d1 ; calculate current allocation ptr <SM6> CSS
sub.l d0,d1 ; allocate our table
cmpi.w #cpu68040,d7 ; check the type of processor <16>
bne.s @notAn040 ; IF on a 68040 THEN <16>
lea AlignmentMasks,a0 ; get address of table alignment masks <16>
and.w (a0,d4.w*2),d1 ; align the table <16>
bra.s @aligned ; ELSE <16>
@notAn040 and.b #$F0,d1 ; ensure quad-long alignment for 020/030's <16>
@aligned ; ENDIF <16>
move.l d1,a0 ; return ptr to allocated space
sub.l a6,d1 ; figure out new allocation offset
move.l d1,sgAllocOff(a6) ; update allocation offset <SM6> CSS
rts
; Masks for aligning 68040 tables on the correct boundaries <16>
AlignmentMasks
Level0 dc.w 0
Level1 dc.w $fe00 ; align to 512 bytes (SRP ptr)
Level2 dc.w $fe00 ; align to 512 bytes (ptrs IN 1st level) <T11>
Level3 dc.w $ff00 ; align to 256 bytes (ptrs IN 2nd level) <T11>
;-----
; MakeTableEntry - make a 4 or eight byte table descriptor at passed fill ptr
;
; Entry
; d0 - size (0 = short, 1 = long) of entries in sub-table
; d2 - size (0 = short, 1 = long) of table descriptor to be made
; a0 - ptr to sub-table
; a1 - fill ptr
; a4 - points to MakeTable stack frame (genPtr points to next intermediate entry)
;
; Exit
; a1 - fillptr updated to next place to put a descriptor
; genPtr(a4) - points to next intermediate table entry
;---
MakeTableEntry
subq.l #4,genPtr(a4) ; bump scan ptr <7>
move.l ([genPtr,a4]),d1 ; get next intermediate table entry <7>
add.w d0,d1 ; make type '8 byte' if sub-table is 8 byte
bfextu d1{30,2},d0 ; get descriptor type
tst.w d2 ; check descriptor size
bne.s @eightByte ; IF its a 4 byte descriptor
add.l a0,d0 ; merge sub-table address w/type
bset #3,d0 ; set used bit, so processor won't have to
move.l d0,(a1)+ ; lay down descriptor, update fill ptr
bra.s @done ; ...
@eightByte ; ELSE (its an eight byte descriptor)
bfclr d1{24,6} ; clear rest of status field
bset #3,d1 ; set used bit, so processor won't have to
move.l d1,(a1)+ ; lay down limit & status, update fill ptr
move.l a0,(a1)+ ; lay down table address, update fill ptr
@done ; ENDIF
rts
;-----
; MakePageEntry - make a (4 or eight byte) page or table descriptor at passed fill ptr
;
; Entry
; d2 - size (0 = short, 1 = long) of descriptor to be made
; a1 - fill ptr
; a4 - points to MakeTable stack frame (genPtr points to next intermediate entry)
;
; Exit
; a1 - fillptr updated to next place to put a descriptor
; genPtr(a4) - points to next intermediate table entry
;---
MakePageEntry
subq.l #4,genPtr(a4) ; bump scan ptr <7>
move.l ([genPtr,a4]),d0 ; get next intermediate table entry <7>
bfextu d0{25,7},d1 ; get descriptor type, cache inhibit bit
and.w #$FF00,d0 ; clear out all except page address
bfset d1{27,2} ; set modified, used bits so processor won't have to
tst.w d2 ; check descriptor size
bne.s @eightByte ; IF its a 4 byte descriptor
add.l d0,d1 ; merge page address w/status field
move.l d1,(a1)+ ; lay down descriptor, update fill ptr
bra.s @done ; ...
@eightByte ; ELSE (its an eight byte descriptor)
bfset d1{1,21} ; set limit to $7FFF, set up high bits of status
move.l d1,(a1)+ ; lay down limit & status, update fill ptr
move.l d0,(a1)+ ; lay down page address, update fill ptr
@done ; ENDIF
rts
ENDWITH ; {MakeFrame}
ENDWITH ; {InitFrame}
ENDWITH ; {MMUSetupInfo}
;-----
; Wrap24BitTable - Wrap the entries in the first and second level tables. This causes <7>
; the first byte in an address to be essentially ignored in 24-bit mode.
; Note: This routine assumes 4-byte descriptors.
;
; Entry
; a0 - points to newly created MMU table
; a4 - point to MakeTable stack frame
;
; Exit
; a0 - ptr to generated table
;---
WrapRegs REG d2/a1-a2
Wrap24BitTable
movem.l WrapRegs,-(sp) ; save work registers
move.l a0,a2 ; save ptr to mmu table
move.w #2,d0 ; for level two,
bsr.s SpanAndCount ; find entrys' address span and count
mulu.l d1,d0 ; calc span of entire 2nd-level table
move.l #24,d2 ; bits in 16 meg chunk
lsr.l d2,d0 ; calc how many 16 meg chunks in level
and.l #$ffff,d1 ; clear high word of count
divu.w d0,d1 ; calc # of entries to duplicate
move.l (a2),d2 ; get table descriptor for first 2nd-level table
andi.l #$fffffff0,d2 ; get rid of attribute bits
move.l d2,a1 ; get it in an address register
subq.l #2,d0 ; (# of copies to make)-1
movea.l a1,a0 ; get copy of pointer to table
lsl.l #2,d1 ; convert # of entries to bytes
@chunkLoop
adda.l d1,a0 ; point to copy destination
clr.l d2 ; clear counter
@copyLoop
move.l (a1,d2),(a0,d2) ; copy an entry
addq.l #4,d2 ; point to next entry
cmp.l d2,d1 ; done?
bne.s @copyLoop ; nope, keep looping
dbra d0,@chunkLoop ; do next chunk, if any
moveq.l #1,d0 ; for level one --
bsr.s SpanAndCount ; get address span and entry count
movea.l a2,a1 ; get a copy of the mmu table pointer
adda.l #4,a1 ; bump to point at second entry in table
subq.w #2,d1 ; (# of entries to copy) - 1
@wrapLoop
move.l (a2),(a1)+ ; copy an entry
dbra d1,@wrapLoop ; loop through first level table
movea.l a2,a0 ; restore a0
movem.l (sp)+,WrapRegs ; restore work regs
rts ;
;_____________________________________________________________________________________________
; GetRBVSize - return size of RBV video buffer, optionally rounded up.
;
; Entry
; d0.l - total memory available
; d1.l - MMU page size to round buffer size up to. Zero if no rounding.
; a0 - RBV base address
; a2 - ProductInfo record ptr (for finding slot zero PRAM alias addr) <8.1>
;
; Exit
; d0 - the size
;
; all registers except parameters are preserved
;_____________________________________________________________________________________________
GetRBVSize
IF hasRBV THEN
bra.s DoRBVSize ; branch around tables, assembler barfs on fwd refs
Trans ; Translations from monitor ID bits
dc.w 0 ; 000 = reserved (no monitor)
dc.w P15Table-Trans ; x01 = 15" portrait
dc.w IIGSTable-Trans ; 010 = IIgs
dc.w 0 ; 011 = reserved (no monitor)
dc.w 0 ; 100 = reserved (no monitor)
dc.w P15Table-Trans ; x01 = 15" portrait
dc.w MacIITable-Trans ; 110 = Mac 2
dc.w 0 ; 111 = no monitor
; these sizes are ordered to match the option bit ordering in DeclDataRBV.a
SETable DC.L $0002AC00 ; SE (9" monitor), 8 bits/pixel, 171 Kbyte buffer <8.9>
DC.L $00005580 ; SE (9" monitor, 342x512), 1 bit/pixel, 21.375 Kbyte buffer <8.9>
DC.L $00015600 ; SE (9" monitor), 4 bits/pixel, 85.5 Kbyte buffer <8.9>
DC.L $0000A600 ; SE (9" monitor), 2 bits/pixel, 42.75 Kbyte buffer <8.9>
IIGSTable DC.L $00030000 ; IIGS (12" monitor,384x512), 8 bits/pixel, 192 Kbyte buffer <8.9>
DC.L $00006000 ; IIGS (12" monitor,384x512), 1 bit/pixel, 24 Kbyte buffer <8.9>
DC.L $00018000 ; IIGS (12" monitor,384x512), 4 bits/pixel, 96 Kbyte buffer <8.9>
DC.L $0000C000 ; IIGS (12" monitor,384x512), 2 bits/pixel, 48 Kbyte buffer <8.9>
MacIITable DC.L $0004B000 ; Mac II (12" monitor,640x480), 8 bits/pixel, 300 Kbyte buffer
DC.L $00009600 ; Mac II (12" monitor,640x480), 1 bit/pixel, 37.5 Kbyte buffer
DC.L $00025800 ; Mac II (12" monitor,640x480), 4 bits/pixel, 150 Kbyte buffer
DC.L $00012C00 ; Mac II (12" monitor,640x480), 2 bits/pixel, 75 Kbyte buffer
P15Table
DC.L $00043F80 ; Portrait (15" monitor,640x870), 4 bits/pixel, 272 Kbyte buffer
DC.L $00010FE0 ; Portrait (15" monitor,640x870), 1 bit/pixel, 68 Kbyte buffer
DC.L $00021FC0 ; Portrait (15" monitor,640x870), 2 bits/pixel, 136 Kbyte buffer
GetRBVRegs REG d1-d4/a0
DoRBVSize movem.l GetRBVRegs,-(sp) ; save regs
move.l d1,-(SP) ; save the rounding factor
moveq #(1<<RvMonID3)+(1<<RvMonID2)+(1<<RvMonID1),d4 ; get monitor parameters
and.b RvMonP(a0),d4 ; keep only the interesting bits
lsr.b #RvMonID1,d4 ; make it zero based
; determine the cpu RAM and speed configuration
moveq #0,d3 ; d3 used to calc sRsrc id for video modes
cmp.l #$180000,d0 ; was there more than 1MB of RAM?
bge.s @0 ; if ≥, then more than 1MB
bset #3,d3 ; set 1MB flag bit on
@0
;+++ should do a CPU speed determination here (look at speed ID bits) and set bit 4 of D3
;+++ RBVPrimaryInit does this test based on TimeDBRA. Since this code doesn't do it,
;+++ we don't test this bit below as part of the pRAM verification
movea.l a2,a0 ; a0 = ptr to productinfo record <8.1>
adda.l ProductInfo.VideoInfoPtr(a2),a0 ; point to the VideoInfo record <8.1>
moveq.l #0,d2 ; <8.1>
move.b VideoInfo.SlotPramAddr(a0),d2 ; set d2 = pram addr for slot zero <8.1>
move.w d2,d0 ; <8.1>
addq.w #4,d0 ; get the last configuration flags from slot 0 pRAM <8.1>
bsr ReadPRAMByte ; read it and weep... <5>
eor.b d3,d0 ; exclusive or to see if anything changed
btst #3,d0 ; did the RAM size change?
bne.s @configChanged ; if set, then it did
;+++ btst #4,d0 ; did the CPU speed change?
;+++ bne.s @configChanged ; if set, then the configuration changed
; test if the monitor type has changed
move.w d2,d0 ; d2 = addr of slot zero pram <8.1>
addq.w #3,d0 ; get the last video sRsrc spID from pRAM <8.1>
bsr ReadPRAMByte ; read this pRAM
bclr #7,d0 ; mask off the spID hi bit
move.w d0,d3 ; remember this value in d3
and.l #7,D0 ; lo-3 bits = monitor ID
moveq #0,d1 ; clear this register out as a long in case there's no monitor
move.w (Trans,d4*2),d1 ; 0 = none, 1-4 = SE, IIGS, MacII, P15
beq.s @gotSize ; if no monitor, then don't allocate any memory for video
cmp.b d0,d4 ; is the monitor the same?
beq.s @noChange ; yup, so the saved slot pRAM value is OK
@configChanged ; if we got here, then the CPU configuration has changed
; PRESERVE D1 ACROSS THIS SECTION!
btst #3,d3 ; was the 1MB bit turned on?
beq.s @10 ; if not, then skip
bclr #4,d3 ; if 1MB, then ignore CPU speed
@10
or.b d4,d3 ; OR the monitor ID in d4 with the config data in d3 to get
; sRsrc id (with hi-bit off)
; when 1MB/25MHz machines default to 1,2,4 instead of 1,2,4,8, then and extra test will be needed hee
;
; at this point, we have the valid video sRsrc spID (sans bit 7) in d3. We use this value to look
; up the buffer size in the Trans table declared above
;
@noChange
lea Trans,a0 ; point to table
moveq #0,d1 ; clear, in case there's no monitor <6.4>
move.w (Trans,d4*2),d1 ; 0 = none, 1-4 = SE, IIGS, MacII, P15 <6.4>
beq.s @gotSize ; if no monitor, then no memory for video <6.4>
adda.l d1,a0 ; offset to monitor's table <6.4>
lsr #3,d3 ; get the option bits at the bottom of d3
move.l (a0,d3*4),d1 ; get the frame buffer size in d1
move.l (SP),d0 ; get the rounding factor in d0
beq.s @gotSize ; IF rounding needed
move.l d1,d2 ; save our size
tdivu.l d0,d3:d2 ; get remainder of size/round factor
tst.l d3 ; check remainder
beq.s @gotSize ; IF any remainder
sub.l d3,d0 ; get round factor - remainder
add.l d0,d1 ; add to size to get next higher
; ENDIF
; ENDIF
@gotSize ; ENDIF
move.l d1,d0 ; return size
move.l (SP)+,d1 ; restore d1
movem.l (sp)+,GetRBVRegs ; restore regs
ELSE
moveq #0,d0 ; no RBV, no size
ENDIF
RTS
;_____________________________________________________________________________________________
;
; GetVISASize - calculate size of VISA video buffer
;
; This routine finds the amount of RAM occupied by the video frame buffer to be used by the
; VISA decoder, and adjusts the chunk table sizes accordingly. This code is similar to
; that in the Universal primaryInit (in RBVPrimaryInit.a). It needs to verify the
; connected display, and do some pRAM stuff to make this calculation work correctly.
;
; Preserves all registers
;
; Inputs : A2 = pointer to productInfo record
; A3 = VISA base address
; A6 = pointer to RAM chunk table
;
; Outputs : none
;
;_____________________________________________________________________________________________
WITH StartGlobals
GetVISASize
; I'm a bad dog to include these equates here, but they live in different files in Reality/split sources and
; the Reality version can't be included.
sRsrc_VidElsA2Em EQU $A8 ; special Apple II emulation mode (1,4)
sRsrc_VidElsGSa EQU $A2 ; Rubik (1,4)
MOVEM.L A0/A2/A3/D0/D2/D4,-(SP)
MOVE.B VsMonP(A3),D4 ; get the current monitor information
LSR.B #3,D4 ; shift the monitor ID into the low bits
AND.B #7,D4 ; clear out other bits
CMP.B #7,D4 ; if sense lines read 111 then no connect
BEQ.S @Done ; no changes needed if no connect
CMP.B #2,D4 ; if =2, then Rubik display
BNE.S @isJersey ; if =6, then Jersey display
LEA RubikTbl,A1 ; point to the Rubik memory table
BRA.S @GetPRAM ;
@isJersey LEA JerseyTbl,A1 ; point to the Jersey memory table
@GetPRAM
ADD.L ProductInfo.VideoInfoPtr(A2),A2 ; point to the VideoInfo record
MOVEQ #0,D2 ; clear out this register
MOVE.B VideoInfo.SlotPramAddr(A2),D2 ; get the start of pRAM for built-in video
ADDQ #4,D2 ; point to the config byte (see PrimaryInit)
MOVE.W D2,D0 ; copy it to this register
BSR ReadPRAMByte ; get the config byte from pRAM in D0, the RAM-less way
CMP.B D4,D0 ; was it the same configuration?
BNE.S @ReConfig ; no, so recalculate the default
; the display configuration is the same, so use the spID in slot pRAM byte 3 to determine allocation
MOVE.W D2,D0 ; point to pRAM byte again, clearing bits 8-15 of D0
SUBQ #1,D0 ; point to byte 3
BSR ReadPRAMByte ; get the config byte from pRAM in D0, the RAM-less way
CMP.W #sRsrc_VidElsA2Em,D0 ; is it the Apple II emulation mode?
BNE.S @0 ; if not, continue
MOVE.B #sRsrc_VidElsGSa,D0 ; memory allocation for the Apple II mode is same as Rubik (1,4)
@0
LSR.B #3,D0 ; shift lo to make index
AND.B #3,D0 ; just the low two bits
BRA.S @GetSize ;
; the display configuration is different, so determine the new default
@ReConfig
MOVEQ #0,D0 ; zero index register
CMP.B #2,D4 ; if =2, then Rubik display, so default is RAM sensitive
BNE.S @GetSize ; if Jersey, then no RAM size variant
CMP.L #$100000,sgTotalRAM(A6) ; is there more than a megabyte of RAM? <SM6> CSS
BGT.S @GetSize ; if so, then select variant 0
ADDQ #1,D0 ; select variant 1 for Elsie with 1MB on Rubik
@GetSize
MOVE.L (A1,D0.W*4),D0 ; get size for this config. A1=Monitor table, D0=index in tbl
; adjust the sgAllocOff field down by the frame buffer size
MOVE.L sgTotalRAM(A6),D2 ; get total ram <SM6> CSS
SUB.L D0,D2 ; subtract frame buffer size to get base of frame buffer
SUB.L A6,D2 ; make frame buffer base relative to pointer to boot globals
MOVE.L D2,sgAllocOff(A6) ; <SM6> CSS
@Done
MOVEM.L (SP)+,A0/A2/A3/D0/D2/D4 ; restore work registers
RTS
RubikTbl DC.L $0001B400,$00007000,$0003B400,$00027000 ; sizes for Rubik (1,4),(1),(1,4,2Pg),(1,2Pg)
JerseyTbl DC.L $0000B000,$00000000,$0002B000 ; sizes for Jersey (1), <extra>, (1,2Pg) <12>
ENDWITH ; {MMUConfigInfo}
ENDWITH ; {BootGlobs}
ENDPROC
END