; ; 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): ; ; 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ ; machines. ; 11/12/93 SAM Roll in from mc900ftjesus. ; 11/12/93 SAM For EMMU machines get the EDisk size from beyond the chunk table ; (see SizeMem for details). ; 11/10/93 fau Update from SuperMunggio . ; 8/27/93 fau Added a HHead entry to the table of decoders. ; 11/10/93 SAM Roll in from mc900ftjesus. ; 11/10/93 SAM We now enforce the upper limit top the EDisk. Currently its set ; to 255 MB. ; 3/31/93 chp Synchronize SuperMario with changes from . Also modify ; early universal test for has68kEmulator: the constant for this ; test must be modulo 8 and it is the individual’s responsibility ; to look in the correct byte (TestFor is not available yet). ; 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. ; 2/26/93 fau Removed MMC support and changed all names including MMC to YMCA. ; 2/5/93 SAM Added support for emulated MMUs. ; 12/23/92 RC Added Support for Smurf on Wombat ; 12/18/92 RB Updated the MSC MMUTables from Horror, since it was wrong. ; 12/1/92 EH Added tables and code for Pratt Memory controller. ; 11/13/92 rab Roll in Horror changes. Comments follow: ; 10/23/92 BG Changed MinBootGlobs to fix the Quadra 9x0 256MB + RAM Disk ; problem. ; 9/11/92 JC Conditionally add support for an 040 board on Vail. ; 8/10/92 NJV Added Double-Exposure support for Sonora 3.0. ; 7/24/92 NJV Fixed 2 ReAnimator bugs where addresses were being doubly ; corrected. ; 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. ; 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. ; 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. ; 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. ; 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. ; 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). ; 11/10/92 GD Rolled in Niagra (for PowerBook) tables from Horror. Also fixed ; a "forRomulator" build issue. ; 11/3/92 RB Changed the use of LC930 in the 24 bit mode support test to ; Supports24Bit ; 10/30/92 RB On the LC930, do not force 32 bit mode, since it supports 24 bit ; mode. ; 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. ; 10/18/92 CCH Added support for PDM and removed padding at the end. ; 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. ; 08/19/92 CSS BootGlobs was changed to StartGlobals by DTY in Reality and this file ; needs changing, also. ; 08/11/92 jmp Added ReAnimator support for ’030 machines (taken straight from ; Horror). ; 8/9/92 CCH Added ReAnimator™ support for HMMU-based machines, and allow ; Orwell-based machines to have HMMUs. ; 7/13/92 CCH Added conditionalized support for Cub Cards on Quadra 700. ; 5/26/92 CSS Cyclone roll in.; ; 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. ; 4/24/92 KW (JC,H16) Cleaned up Sonora Physical Space Tables. ; 4/16/92 KW (JC, H15) Cleaned up Sonora tables. ; (SWC, H14) Mucked around a bit more with the MSC tables. ; 04/16/92 jmp Replaced some hard-coded values with defined constants. ; 04/08/92 jmp Updated the physMMC table entries to more accurate reflect ; reality (I think). ; 03/22/92 jmp Removed the “isVoid” mappings for Slots A&B for MMC in 24-bit ; mode. ; 2/25/92 RMP Modified the 32-Bit MMC table to map in CIVIC register set and ; VRAM. ; 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. ; 1/23/92 RMP Hand map slot 9 for MMC table in 24 bit mode (is 2nd half of ; 2-Meg ROM). ; 1/22/92 RMP Added MMC support. Added MMC tables. ; 01/13/92 jmp (SWC,H9) Turned off caching for video space for DB-Lite to get ; around a bug with the GSC. ; 1/4/92 RP Changed ROMMaxSize for 2-Meg ROM ; <1> 5/17/92 kc first checked in ; 3/26/92 kc Rolled in from Horror. Comments follow. ;                                   Force 32-bit mode. (see 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. •••• ; 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. ; 4/19/92 JC Cleaned up Sonora Physical Space Tables. ; 4/13/92 JC Cleaned up Sonora tables. ; 4/10/92 SWC Mucked around a bit more with the MSC tables. ; 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. ; 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. ; 1/22/92 JC Change to fix Spike problem on Non Sonora builds. ; 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. ; 1/6/92 SWC Turned off caching for video space for DB-Lite to get around a ; bug with the GSC. ; 12/16/91 HJR Added NiagraTables for Dartanian. ; 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. ;
12/12/91 CCH Reverted back to making Edisk space uncacheable when VM is on. ;
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). ;

11/25/91 CCH Added Sonora support. ;

11/14/91 jmp (CCH) Mark EDisk address space as cacheable in physical space ; table. ;

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 ; orwell32 Setup $C000, $F900C060, $807FC040, Template32Orwell, void32Orwell, physOrwell ; 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 ; MSC32 Setup $80D07750, $600F8507, $807F8507, template32MSC, void32MSC, physMSC ; MSC24040 Setup $C000, 0, 0, template24MSC040, 0, physMSC ; MSC32040 Setup $C000, $600FC060, $807FC060, template32MSC040, void32MSC, physMSC ; Niagra24 Setup $80D86500, 0, 0, template24Niagra, 0, physNiagra ; Niagra32 Setup $80D07750, $600F8507, 0, template32Niagra, void32Niagra, physNiagra ; Sonora24 Setup $80D86500, 0, 0, template24Sonora, 0, physSonora ; Sonora32 Setup $80D07750, $600F8507, $807F8507, template32Sonora, void32Sonora, physSonora ; FstrFrms24 Setup $80F84500, 0, 0, templateFF24, 0, physFF ; CSS FstrFrms32 Setup $80F05750, 0, 0, templateFF32, 0, physFF ; CSS YMCA24 Setup $C000, 0, 0, template24YMCA, 0, physYMCA ; CSS YMCA32 Setup $C000, $F900C060, $807FC040, Template32YMCA, void32YMCA, physYMCA ; CSS SnraForty24 Setup $C000, 0, 0, template24SnraFrty, 0, physSonora ; SnraForty32 Setup $C000, $600FC060, $807FC040, template32SnraFrty, void32Sonora, physSonora ; Pratt24 Setup $C000, 0, 0, template24Pratt, 0, physPratt ; Pratt32 Setup $C000, $A01FC040, $600FC060, template32Pratt, void32Pratt, physPratt ; ;----- ; 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 CSS ; IOMaxSize equ $00040000 ; 256k: max size of memory-mapped I/O space ; <7> EDskMaxSize equ $10000000 ; 256M: size of largest possible RAM disk ; VRAMMaxSize equ $00200000 ; 2M: size of largest possible VRAM 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) MSCVidEnd EQU $70000000 ; end of frame buffer SonoraVidBase EQU $60000000 ; base of built-in frame buffer (not RBV) SonoraVidEnd EQU $70000000 ; end of frame buffer 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) CSS b24DblX equ $00FC0000 ; base of Dbl X 24 bit Slot Space on Sonora 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) CSS bVRAM32 equ $50100000 ; base of VRAM on Cyclone (32 bit mode) CSS 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) bNonSerIO equ $51000000 ; base of non-serialized I/0 area (32 bit) b32VidBase equ $60000000 ; base of built-in frame buffer (not RBV) 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 CSS ;--- FFRomMax equ $400000 ; 4 Mb of ROM space 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 FFbShadow equ $00800000 ; base of shadowed memory FFtShadow equ $00A00000 ; top of shadowed memory FFbRom24 equ $00A00000 ; base of FF ROM (24 bit mode) FFtRom24 equ FFbRom24+FFRomMax ; end of FF ROM (24 bit mode) 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) FFtDblXSlot32 equ FFtEyeOh32+DblXSlotMax ; Top of Double Exposure slot space ;--- ; 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 ; 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 FullTblBit equ 6 ; bit number of full vs early termination field FullTbl equ FullTblMask ; flag for enabling full MMU tables (no early term) 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 tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o and/or video tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; slots Template32RBVb ; RBV in Slot B tp bRom32-bRam, isRAM ; RAM tp bEyeOh32-bRom32, isROM32 ; ROM tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp RBVWrap32b-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots 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 tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp RBVWrap32e-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots 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 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) Template32Jaws tp bRom32-bRam, isRAM ; RAM tp bEyeOh32-bRom32, isROM32 ; ROM tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp LCDWrap32-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots tp LCDBase32-LCDWrap32, isVidWrap ; wrap area tp LCDEnd32-LCDBase32, isVideoRAM ; frame buffer area tp (bTop32Less1-LCDEnd32)+1, isThru+cInhibit ; rest of slots Template32MSC ; 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 bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) 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 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 (b32VidBase-$2000)-(bNonSerEyeOh+IOMaxSize), isVoid ; Invalid tp b32VidBase-(b32VidBase-$2000), isThru+c040InhibitSer ; CPU ID Register tp bRamDisk-b32VidBase, isVoid ; Video (uses TTx regs) tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk+c040CopyBack ; Ram Disk tp (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs) Template32Sonora ; 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, isThru+cInhibit ; Video (uses TT0) tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) Template32Niagra ; 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 ; CSS tp bRealRom32-bRam, isRAM+c040CopyBack ; RAM tp (bRealRom32+ROMMaxSize)-bRealRom32, isROM32+c040CopyBack; ROM tp bVideo32-(bRealRom32+ROMMaxSize), isVoid ; Invalid tp bVRAM32 -bVideo32, isThru+c040InhibitNonSer ; non-ser video I/O. tp (bVRAM32+VRAMMaxSize)-bVRAM32, isThru+c040InhibitNonSer ; non-ser VRAM. tp bRealEyeOh32 -(bVRAM32+VRAMMaxSize), 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) 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). 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> tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM <16> tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitNonSer ; minor slot 9 <16> 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 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 Template24Jaws ; <9> tp bRom24-bRam, isRAM ; RAM tp b24Slot9-bRom24, isROM24 ; ROM <13> tp LCDWrap24-b24Slot9, isVoid ; invalid <13> 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 ; tp bRom24-bRam, isRAM+FullTbl ; RAM tp b24Slot9-bRom24, isROM24+FullTbl ; 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 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 Template24MSC040 ; tp bRom24-bRam, isRAM+c040CopyBack ; RAM tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitSer ; minor slot 9 tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A tp b24SlotC-b24SlotB, b32SlotB+isMap+c040InhibitSer ; minor slot B 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 bTop24Less1-bEyeOh24+1, bRealEyeOh32+isMap+c040InhibitSer ; i/o tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area Template24Niagra ; 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 ; tp bRom24-bRam, isRAM+c040CopyBack ; RAM tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM tp b24SlotA-b24Slot9, b32Slot9+isMap+c040InhibitSer ; minor slot 9 tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A tp b24SlotC-b24SlotB, $60B00000+isMap+c040InhibitNonSer ; Video RAM 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 b24DblX-bEyeOh24, bRealEyeOh32+isMap+c040InhibitSer ; i/o tp (bTop24Less1-b24DblX)+1, $FEE00000+isMap+c040InhibitSer ; Double X slot space tp bTop32Less1-bTop24Less1+1, isWrap24 ; 24-bit wrap area Template24Sonora tp bRom24-bRam, isRAM+FullTbl ; RAM tp b24Slot9-bRom24, isROM24+FullTbl ; ROM 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 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 tp (bTop24Less1-b24DblX)+1, b24SlotE+isMap+cInhibit ; Double X slot space Template24YMCA ; tp bRom24-bRam, isRAM+c040CopyBack ; RAM tp b24Slot9-bRom24, isROM24+c040CopyBack ; ROM tp b24SlotA-b24Slot9, $40900000 + isMap ; Slot 9 is 2nd meg of ROM. tp b24SlotB-b24SlotA, b32SlotA+isMap+c040InhibitSer ; minor slot A tp b24SlotC-b24SlotB, b32SlotB+isMap+c040InhibitSer ; minor slot B 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 ; 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 tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; slots Void32RBVb tp HoleLowMem-bRam, isRAM ; low memory: RAM tp HoleSysHeap - HoleLowMem, isVoid ; black hole tp bRom32 - HoleSysHeap, isRAM ; RAM tp bEyeOh32-bRom32, isROM32 ; ROM tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp RBVWrap32b-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots 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 tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp RBVWrap32e-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots tp RBVBase32e-RBVWrap32e, isVidWrap ; wrap area tp RBVEnd32e-RBVBase32e, isVideo ; frame buffer area tp bTop32Less1-RBVEnd32e+1, isThru+cInhibit ; rest of slots Void32Orwell ; 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) 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 tp bRamDisk-bEyeOh32, isThru+cInhibit ; i/o tp (bRamDisk+EDskMaxSize)-bRamDisk, isEdisk ; Ram Disk tp LCDWrap32-(bRamDisk+EDskMaxSize), isThru+cInhibit ; slots tp LCDBase32-LCDWrap32, isVidWrap ; wrap area tp LCDEnd32-LCDBase32, isVideo ; frame buffer area tp bTop32Less1-LCDEnd32+1, isThru+cInhibit ; rest of slots Void32MSC ; 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 bTop32Less1-(bRamDisk+EDskMaxSize)+1, isVoid ; slots (uses TT1) Void32Sonora ; 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 (bTop32Less1-(bRamDisk+EDskMaxSize))+1, isVoid ; slots (uses TTx regs) Void32Niagra ; 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 ; CSS tp FFbShadow-bRam, isRAM ; RAM tp FFtRom24-FFbShadow, isThru ; ROM tp t24SlotE-FFtRom24, b32SlotE+isMap+cInhibit ; Slot E tp FFtEyeOh24-t24SlotE, isThru+cInhibit ; I/O space tp FFtDblxSlot24-FFtEyeOh24, b24SlotE+isMap+cInhibit ; Slot E (64k), for DblX tp bTop24Less1-FFtDblxSlot24+1, isThru+cInhibit ; rest of I/O space TemplateFF32 tp FFbShadow-bRam, isRAM ; RAM tp FFtShadow-FFbShadow, isThru ; Shadowed area tp FFbRom32-FFtShadow, isRAM ; RAM tp FFtRom32-FFbRom32, FFbRom24+isMap ; ROM tp FFbEyeOh32-FFtRom32, isVoid ; unmapped space tp FFtEyeOh32-FFbEyeOh32, bEyeOh24+isMap+cInhibit ; I/O space tp FFtDblXSlot32-FFtEyeOh32, b24SlotE+isMap+cInhibit ; Slot E (64k), for DblX tp bRAMDisk-FFtDblXSlot32, isThru+cInhibit ; bank switch reg in here tp bRamDisk+EDskMaxSize-bRamDisk, isEdisk ; Ram Disk tp bTop32Less1-(bRamDisk+EDskMaxSize)+1, isThru+cInhibit ; Rest of slot space Void32YMCA ; CSS 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 ; 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 ; 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 ; 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 ;--- physMSC dc.w kUsageRAM, cacheable ; RAM dc.l 0, 0 dc.l 0, 0 dc.l 0, 0 dc.w kUsageROM, cacheable ; ROM 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 kUsageMajorSlot, notCacheable ; slot 9 dc.l $90000000, $10000000 dc.l $90000000, $10000000 dc.l 0, 0 dc.w kUsageMajorSlot, notCacheable ; slot A dc.l $A0000000, $10000000 dc.l $A0000000, $10000000 dc.l 0, 0 dc.w kUsageMajorSlot, notCacheable ; slot B dc.l $B0000000, $10000000 dc.l $B0000000, $10000000 dc.l 0, 0 dc.w kUsageMajorSlot, notCacheable ; slot C in docking station dc.l $C0000000, $10000000 dc.l $C0000000, $10000000 dc.l 0, 0 dc.w kUsageMajorSlot, notCacheable ; slot D in docking station dc.l $D0000000, $10000000 dc.l $D0000000, $10000000 dc.l 0, 0 dc.w kUsageMajorSlot, notCacheable ; slot E (PDS docking connector) dc.l $E0000000, $10000000 dc.l $E0000000, $10000000 dc.l 0, 0 dc.w kUsageMinorSlot, notCacheable ; slot 9 dc.l $F9000000, $01000000 dc.l $F9000000, $01000000 dc.l $00900000, $00100000 dc.w kUsageMinorSlot, notCacheable ; slot A dc.l $FA000000, $01000000 dc.l $FA000000, $01000000 dc.l $00A00000, $00100000 dc.w kUsageMinorSlot, notCacheable ; slot B dc.l $FB000000, $01000000 dc.l $FB000000, $01000000 dc.l $00B00000, $00100000 dc.w kUsageMinorSlot, notCacheable ; slot C in docking station dc.l $FC000000, $01000000 dc.l $FC000000, $01000000 dc.l $00C00000, $00100000 dc.w kUsageMinorSlot, notCacheable ; slot D in docking station 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 ;--- physNiagra dc.w kUsageRAM, cacheable ; dc.l 0, 0 dc.l 0, 0 dc.l 0, 0 dc.w kUsageROM, cacheable ; ROM 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 ;--- 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•• 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 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 ; 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 ; Video Space dc.l $60000000, $01000000 ; dc.l $60000000, $01000000 ; 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 dc.l $FEE00000, $40000 ; with addresses in the range dc.l $50FC0000, $40000 ; $50FC0000-$50100000 dc.l $00FC0000, $40000 ; dc.w kUsageEndTable ;••• Begin CSS Cyclone Roll-in. ;----- ; 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 dc.l $00C00000, $00100000 ; dc.l $40C00000, $00100000 ; dc.l $00C00000, $00100000 ; dc.w kUsageROM, cacheable ; dc.l $00D00000, $00100000 ; dc.l $40D00000, $00100000 ; dc.l $00D00000, $00100000 ; 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 ; ;--- ; Physical table for YMCA Based machines ;--- 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 CSS Cyclone roll-in ;--- ; Physical table for Pratt LCD portables ;--- 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 ; + + --- 2 longs at top of bank are trashed by diagnostics ; + + --- ditto ; + FFFFFFFF + ; + + ; + + ; + ... + ; + + ; + + ; ------------ <--- 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; CSS space for main RAM chunks (addr/size) (last addr -1) eDiskChunks ds.l sgMaxChunks*2; CSS space for eDisk chunks (addr/size) (last addr -1) 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) soundBufferSize ds.l 1 ; size of sound buffer in high RAM (if any) 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) beq.s @NoTables ; -> Yes, bail out now! cmp.b #HMMU,sgTypeMMU(a6) ; CSS check type of MMU bne.s @isPmmu ; IF HMMU @noTables movem.l SaveURegs(a5),UnivRegs ; restore universal registers IF forRomulator THEN ; 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 CSS ^ @dontAdj ; ENDIF | ENDIF ; 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 CSS bsr SaveMMUInfo ; move 32 bit info to BootGlobs CSS btst #MMStartMode,sgMMFlags(a6);check if we're booting 32 bit only 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 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 CSS 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> ;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• CSS ; 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 ;••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• CSS 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 movec d5,vbr ; restore vector base reg <3.8> ENDIF ; 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 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 ; biglea baseOfRom,a5 ; get physical base of ROM MACHINE MC68040 ; corrects for ASM bug w/040 directive move.l a5,d6 ; save it to adjust pointers later ENDIF ; 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 beq @SavePhys ; IF defined physical ROM base THEN move.l ROMPhysAddr(a0),d0 ; use it instead of computed value @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 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 LEA @Resume,A2 ; (BSR2) BRA.L SizeSoundBuffer ; get sound buffer attributes (if any) @Resume MOVE.L A0,soundBufferBase(A5) ; save the base MOVE.L D0,soundBufferSize(A5) ; and size of the sound buffer (if any) move.l #bRamDisk,sgRamDiskBase(a6) ; init logical base of eDisk CSS clr.l sgRamDiskSize(a6) ; assume empty ram disk CSS clr.b sgEDiskStealFlag(a6) ; assume no chunks to steal move.l #-1,eDiskChunks(a5) ; make eDisk chunk table empty too lea sgBottom,a0 ; assume we'll start allocating below BootGlobs CSS move.l a0,sgAllocOff(a6) ; save allocation offset CSS move.b #ramDiskPramAddr,d0 ; get PRAM address of memory manager flags bsr ReadPRAMByte ; read it and weep... andi.l #$ff,d0 ; clear upper bytes of pram byte beq.s @noEdisk ; IF we want an Edisk THEN clr.l d3 ; clear counter 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 bra.s @saveSize ; join the rest of the code (if D1=0 then no EDisk) @countRAM lea sgRamTable+4(a6),a0 ; get pointer to size of the first chunk | 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 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 cmp.l #MaxRamDiskSize,d0 ; check upper size limit bhi.s @noEdisk ; >>EXIT is edisk to too big move.l d0,d1 ; copy the size into D1 move.b #1,sgEDiskStealFlag(a6) ; signal that we want to steal chunks from RAM lea sgRamTable(a6),a0 ; source = chunk table in BootGlobs CSS lea eDiskChunks(a5),a1 ; destination = edisk chunk table bsr stealChunks ; try to steal some ram from main memory @saveSize ; move.l d1,sgRamDiskSize(a6) ; save size of eDisk in boot globals CSS @noEdisk ; ENDIF lea sgRamTable(a6),a0 ; source = chunk table in BootGlobs 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 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 ; rb rb bset #MMStartMode,d0 ; Force 32-bit mode until we make room for a 2 meg rom kc •••• bset #MMMixed,d0 ; Force 32-bit mode until we make room for a 2 meg rom kc •••• bset #MMSysheap,d0 ; Force 32-bit mode until we make room for a 2 meg rom kc •••• bset #MMROZheap,d0 ; Force 32-bit mode until we make room for a 2 meg rom kc •••• bclr #mmHighSysHeap,d0 ; Force 32-bit mode until we make room for a 2 meg rom kc •••• ENDIF ; 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 CSS move.l d1,sgPhys2Log(a6) ; save physical-to-logical offset 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>

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 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 CSS sub.l sgAllocOff(a6),d0 ; total size = top offset - bottom offset CSS WITH PhysicalSpaceBlock move.l soundBufferSize(a5),d1 ; get total RAM taken up by sound buffer add.l d0,d1 ; and boot globals sub.l d1,physical.rangeSize(a0) ; adjust size last useable chunk 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 CSS move.l d0,a4 ; save logical ptr IF forRomulator THEN ; 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 CSS ^ @dontAdj ; ENDIF | ENDIF ; add.l sgAllocOff(a6),d0 ; get logical address top useable memory CSS btst.b #mmHighSysHeap,sgMMFlags(a6); check if 'black hole' before system heap 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 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 ; 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 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> dc.w @Orwell-@casetbl ; .(Orwell) <7> dc.w @Jaws-@casetbl ; .(Jaws) <9> dc.w @MSC-@casetbl ; .(MSC) dc.w @Sonora-@casetbl ; .(Sonora)

dc.w @Niagra-@casetbl ; .(Niagra) dc.w @YMCA-@casetbl ; .(YMCA) fau dc.w @djMEMC-@casetbl ; .(djMEMC) dc.w @Emulated-@casetbl ; .(HMC) dc.w @Pratt-@casetbl ; .(Pratt) 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> 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. cch ;--- @Emulated ; CASE RISC Mac: bra @endSwitch ; that's all folks ;--- ; Sonora: Weird Case necessary to be able to handle Vail and Double Exposure. ;--- @Sonora ; CASE Sonora chip:

move.l d0,a0 ; save d0 movec cacr,d0 ; move.l d0,a1 ; save cacr sub.l d0,d0 ; D0 = 0 bset #CACR_DE_040,d0 ; set Data Cache Enable bit on 040s movec d0,CACR ; attempt to enable data cache (temporarily) movec CACR,d0 ; check and see if it's still there btst #CACR_DE_040,d0 ; see if the bit exists in CACR beq.s @Sonora030 ; IF we're on a 68040 THEN MACHINE MC68040 ; need this for the MOVEC D0,TC below cinva bc ; make sure caches are invalidated MACHINE MC68030 ; return to prior MACHINE directive <2> move.l a1,d0 ; restore cacr movec d0,cacr ; move.l a0,d0 ; restore d0 lea SnraForty32,a0 ; use Sonora's 040 32 bit mode layout info lea SnraForty24,a1 ; use Sonora's 040 24 bit mode layout info bra @endSwitch ; that's all folks @Sonora030 move.l a1,d0 ; restore cacr movec d0,cacr ; move.l a0,d0 ; restore d0 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: @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: 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. ; through next ;--- @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 ;--- ; Pratt: Memory is always contiguous on Pratt, and onboard video will always be on. ; ;--- @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 fau ;--- ; YMCA: no weird cases. ;--- @YMCA ; CASE YMCA chip: lea YMCA32,a0 ; use YMCA's 32 bit mode layout info lea YMCA24,a1 ; use YMCA's 24 bit mode layout info bra @endSwitch ; that's all folks ;••• End 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) 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) 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 CSS move.l a3,a0 ; point to RBV table <11> lea globChunks+8(a5),a1 ; get pointer to second chunk tst.l sgEDiskStealFlag(a6); check for ram disk CSS | 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 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 CSS bne.s @ramDiskExists ; IF there is no ram disk THEN sub.l d1,d5 ; decrement Bank B size by pagesize @ramDiskExists ; ENDIF 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 CSS bne.s @noBankB ; IF there is no ram disk THEN add.l d5,d4 ; get addr of last 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 @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. ; All we need to do is allocate a 4k sound buffer. ;--- @VISA ; CASE VISA chip: sub.l #$00001000,sgAllocOff(A6) ; allocate 4k sound buffer lea FstrFrms24,a1 ; point to 24 bit MMU info table lea FstrFrms32,a0 ; point to 32 bit MMU info table bra @endSwitch ; @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 CSS sub.l a1,d0 ; allocate space for physical table move.l d0,sgPhysicalTableOff(a6) ; save offset to physical table CSS move.l d0,sgAllocOff(a6) ; update allocation offset 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 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 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 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 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 sub.l d0,d3 ; calculate start of wrap area bsr.w @writeOne ; for wrap area before video buffer @doneVideo ; ENDIF tst.l sgEDiskStealFlag(a6) ; check for ram disk CSS 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 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 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? beq.s @NoSoundBuffer ; -> nope, all done clr.w (a1)+ ; entry type = other move.w #notCacheable,(a1)+ ; attributes = notCacheable move.l soundBufferBase(a5),(a1)+ ; physical addr = base of sound buffer move.l d0,(a1)+ ; physical size = size of sound buffer clr.l (a1)+ ; logical 32 addr = (don't care) move.l d0,(a1)+ ; logical 32 size = size of sound buffer clr.l (a1)+ ; logical 24 addr = (don't care) move.l d0,(a1)+ ; logical 24 size = size of sound buffer @NoSoundBuffer ; 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 move.l d4,(a1)+ ; physical addr = video base addr 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)+ ; CSS get usage type move.w PhysicalSpaceBlock.attributes(a0),(a1)+ ; CSS get the attributes move.l PhysicalSpaceBlock.physical.rangeSize(a0),d0 ; CSS cmpi.l #$10000000,d0 ; CSS is the size 256MB ? bne.s @doNew ; CSS if 256MB then generate ROM entry the old way otherwise get ; ; 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 ; CSS @doNew move.l PhysicalSpaceBlock.physical.address(a0),(a1)+ ; CSS get the physical address of the rom bank move.l d0,(a1)+ ; CSS physical size of rom image from template move.l PhysicalSpaceBlock.logical.address(a0),(a1)+ ; CSS get the logical 32 bit Rom bank address move.l PhysicalSpaceBlock.logical.rangesize(a0),(a1)+ ; CSS get the logical 32 bit Rom bank size move.l PhysicalSpaceBlock.logical24.address(a0),(a1)+ ; CSS get the logical 24 bit Rom bank address move.l PhysicalSpaceBlock.logical24.rangesize(a0),(a1)+ ; CSS get the logical 32 bit Rom bank size @done exg a3,d1 ; CSS restore reg 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) CSS eDskChunks ds.l sgMaxChunks*2 ; space for copy of edisk chunks (addr/size) (last addr -1) 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 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 lea eDskChunks(a4),a1 ; destination = our local copy bsr.s CopyChunks ; get a local copy of chunk table 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 ; . 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) cmp.w #cpu68040,d7 ; Check whether or not we're on an 040 beq.s @nomask ; IF NOT on a 68040 THEN btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block bne.s @nomask ; IF Full Tables NOT wanted then and.l #$ff000000,d0 ; mask to just use high byte of phys addr @nomask move.l d0,a0 ; ENDIF bra.s @romCommon ; (continue w/common code) @rom24 ; CASE(rom, 24 bit mode) move.l physRomBase(a5),a0 ; assume running in ROM (use phys addr) @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 bra.s @valid ; ... <9> @eDisk ; CASE(ram disk) bsr GrabEdisk ; allocate from eDisk chunks, return type, page addr bra.s @endSwitch ; ... @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 beq.s @term ; IF Full Tables wanted then and.l #cBitMask,d3 ; get cache inhibit bit bra.s @fullTables ; check table level ; ELSE @term and.l #cBitMask,d3 ; get cache inhibit bit <7> bra.s @setCache ; ELSE <7> @on040 and.l #c040ModeMask,d3 ; get cache mode bits <7> @fullTables bsr.w CanGoDeeper ; check if we are at the lowest Level <7> beq.s @setCache ; >>EXITROUTINE if NOT on lowest level <7> 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 beq.s @fulltbl ; IF on a 68040 THEN btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block beq.s @term ; IF Full Tables wanted then @fulltbl bsr.w CanGoDeeper ; check if on lowest level <7> 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 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 beq.s @fulltbl ; IF on a 68040 THEN btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block beq.s @term ; IF Full Tables wanted then @fulltbl bsr.s CanGoDeeper ; check if we'er on the lowest level <7> 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 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 beq.s @fulltbl ; IF on a 68040 THEN btst.l #FullTblBit,d3 ; Check if we want full MMU tables for this block beq.s @term ; IF Full Tables wanted then @fulltbl bsr.s CanGoDeeper ; check if we'er on the lowest level <7> 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 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 ; CanGoDeeper movem.l DeeperRegs,-(sp) ;save working registers 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 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 bne.s @doWrite ; IF it is clear THEN 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 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 move.l #1,a0 ; return a bad limit @bumpPtr ; ENDIF 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 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 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 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) Level3 dc.w $ff00 ; align to 256 bytes (ptrs IN 2nd level) ;----- ; 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< 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? 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 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) ; 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), , (1,2Pg) <12> ENDWITH ; {MMUConfigInfo} ENDWITH ; {BootGlobs} ENDPROC END