mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
2737 lines
119 KiB
Plaintext
2737 lines
119 KiB
Plaintext
;
|
||
; File: SizeMem.a
|
||
;
|
||
; Written by: Gary Rensberger
|
||
;
|
||
; Copyright: © 1989-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM49> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
||
; machines.
|
||
; <SM48> 11/19/93 KW copied HMCMerge EDisk calculations and put in OrwellMerge. Only
|
||
; effects the CygnusX1 ROM
|
||
; <SM47> 11/17/93 chp Put back TNT code inadvertantly removed by a previous checkin.
|
||
; <SM46> 11/17/93 KW added some forSTP601 conditionals. Only effects CygnusX1 ROM
|
||
; <SM45> 11/13/93 SAM Roll in <MC10> from mc900ftjesus.
|
||
; <MC10> 11/13/93 SAM In the EDisk calculation from the previous revision, I was not
|
||
; anticipating the result going negative. It does. I now check for
|
||
; it.; <SM44> 11/12/93 SAM Roll in <MC9> from mc900ftjesus.
|
||
; <MC9> 11/12/93 SAM When allocating an EDisk, make sure there is KminHeap (or
|
||
; somesuch) free or don't allocate. The ammount of RAM
|
||
; allocated for the edisk is stored beyond the diagnostic longs at
|
||
; the end of the chunk table. InitMMU uses this size for eMMU
|
||
; machines.
|
||
; <SMG2> 11/9/93 fau Added the TNT Decoder support (HammerHead)
|
||
; <SM42> 11/9/93 KW added some conditional forSTP601. Only used for CygnusX1 ROM
|
||
; <SM41> 11/7/93 SAM Roll in <MC8> from mc900ftjesus.
|
||
; <MC8> 11/7/93 SAM Keep a running total of RAM allocated by the nanokernel in the
|
||
; chunk table.
|
||
; <SM40> 11/6/93 SAM Roll in <MC7> from mc900ftjesus.
|
||
; <MC7> 11/6/93 SAM Disable Sonora video before mucking with the NanoKernel memory
|
||
; allocation.
|
||
; <SM39> 11/1/93 SAM Roll in <MC6> from mc900ftjesus.
|
||
; <MC6> 11/1/93 SAM (RC) HMCMerge now checks PRAM for the diag burn-in sig as well
|
||
; as reading the monitor sense lines for the RBV to determine if a
|
||
; DRAM based frame buffer should be allocated.
|
||
; <SM38> 10/16/93 SAM Roll in <MC5> from mc900ftjesus.
|
||
; <MC5> 10/16/93 SAM Add some slop to the RBV buffer for PDM to account for QD
|
||
; writing past the end of the buffer. (Doesn't this seem like a
|
||
; problem to you? Does to me...)
|
||
; <SM37> 10/15/93 SAM Roll in <MC4> from mc900ftjesus.
|
||
; <MC4> 10/15/93 SAM Ok, I fixed the boot beep code, so the RBV size is now set to a
|
||
; max of 600k (not 768). Removed the 3 extra longs allocated in
|
||
; the chunk table (for debugging).
|
||
; <SM36> 9/29/93 SAM For PDM: from mc900ftjesus.
|
||
; <MC3> 9/25/93 SAM For PDM: Loose Evt1 support.
|
||
; <SM35> 9/13/93 SAM For PDM (HMC): Removed the Edisk hack for the nanokernel.
|
||
; Marked all the DMA buffers noncacheable.
|
||
; <SM34> 9/9/93 pdw Added 'nk' onto front of MakePageWriteThrough.
|
||
; <SM33> 8/23/93 SAM Added a temp hack to increase the amount of RAM allocated for
|
||
; the RAM disk by 1 page (nk bug)
|
||
; <SM32> 8/23/93 SAM Changed the alignment restriction for the EDisk allocation to be
|
||
; 4k.
|
||
; <SM31> 8/23/93 SAM Added some space in the HMC chunk table for a couple of
|
||
; warmstart longs.
|
||
; <SM30> 8/12/93 KW adding two more smurf wombats
|
||
; <SM29> 8/11/93 KW added some branches based on new smurf boxes
|
||
; <SM28> 6/14/93 kc Roll in Ludwig.
|
||
; <LW4> 6/4/93 fau In sizing memory in Cyclone, there was a bug when a Wide Mode
|
||
; SIMM was in bank 5, no SIMM in bank 7, and a Standard Mode SIMM
|
||
; in Bank 0. Bug #1088829.
|
||
; <SM27> 6/3/93 SAM For HMC machines (PDM) if an evt2 or better is found, the floppy
|
||
; and serial DMA buffers are marked noncacheable in order fix a
|
||
; data path snooping during DMA bug.
|
||
; <SM26> 5/9/93 SAM Added a couple lines of crucial code to the PDM physical buffer
|
||
; allocation code. Grin.
|
||
; <SM25> 5/6/93 SAM For PDM. Changed the HMC entry in the sizemem "split" table to
|
||
; point directly at the HMCMerge routine (we don't have to size
|
||
; anything, really). Addded allocation of the DMA and video frame
|
||
; physical buffers to HMCMerge. Added code to make the frame
|
||
; buffer write-through cacheable.
|
||
; <SM24> 4/30/93 SAM Removed non-functional non-universal forRomulator code in
|
||
; SizeBanks (<LW2>). Added one more forSmurf condo.
|
||
; <SM23> 4/19/93 SAM Added forSmurf conditionals around RiscWombat boxflag check
|
||
; (ugh).
|
||
; <SM22> 3/31/93 chp Synchronize SuperMario with changes from <LW2>.
|
||
; <SM21> 3/11/93 SAM Added EDisk allocation to HMC merge code.
|
||
; <LW2> 2/26/93 fau Removed Cyclone EVT3 (MMC) support.
|
||
; <SM20> 2/25/93 RC Fixed Merge code for Smurf. Old code did not do what we thought
|
||
; it did, but now it correctly sizes memory by using the same code
|
||
; and PDM uses.
|
||
; <SM19> 2/20/93 SAM Added emuWarmStartConst to the chunk table build for HMC
|
||
; machines.
|
||
; <SM18> 2/5/93 SAM Added HMC "merge" code that conconcts a fake chunk table and
|
||
; generally does the right thing. (for PDM).
|
||
; <SM17> 12/23/92 RC Added Support for Smurf
|
||
; <SM16> 12/1/92 EH Changed PrattAddr reference to DecoderAddr reference for
|
||
; PrattMerge.
|
||
; <SM15> 12/1/92 EH Added code for Pratt memory controller.
|
||
; <SM14> 11/12/92 rab Added djMEMCSplit to the split table (had added the code but
|
||
; forgot the entry). Also exported SizeSoundBuffer for MMUTable.a.
|
||
; <SM13> 11/10/92 GD Fixed some "forRomulator" issues from latest Horror roll-in.
|
||
; <SM12> 11/3/92 rab Roll in Horror changes. <H16>10/13/92 BG Modified various
|
||
; comments in the djMEMCSplit code to indicate that both WLCD and
|
||
; Primus need to set the OneBufferedBus bit. <H15> 9/28/92 BG
|
||
; Changed the djMEMCMerge code so that if you are trying to create
|
||
; a ReAnimator type ROM, don't turn on memory interleaving. <H14>
|
||
; 8/4/92 SWC Fixed a bug in MSCMerge: we were only allocating
|
||
; enough space for 5 RAM banks (we support 8), so the end of the
|
||
; RAM chunk table was going into write-only RAM.
|
||
; <H13> 7/13/92 SWC Added some code to the end of MergeDone to move the RAM chunk
|
||
; table below a sound buffer in high RAM. This was moved here from
|
||
; MMUTables.a because (1) since the chunk table was moved down
|
||
; after running StartTest, we'd lose the warmstart flag (causes
|
||
; the RAM disk to get trashed on Restart, and (2) diagnostics seem
|
||
; to call SizeMem in several places, so I figured it was better to
|
||
; get everything set up once.
|
||
; <H10> 6/16/92 BG Added back in the interleave initialization for djMEMC.
|
||
; However, a precursor check has been added to only allow that
|
||
; code to be executed if the version number of djMEMC is greater
|
||
; than 0, since version 0 parts will cause Wombat/WLCD to die
|
||
; shortly after enabling interleaving.
|
||
; <H8> 6/12/92 BG Added support for sizing up to 16 banks of memory. This is
|
||
; needed because Wombat can support up to 10 banks. Also - removed
|
||
; the djMEMC configuration register initialization from here and
|
||
; moved it to UniversalPatch.a so that it is not executed multiple
|
||
; times (since SizeMemory gets called multiple times).
|
||
; <H7> 6/9/92 BG Added djMEMC memory controller to split and merge tables, as
|
||
; well as the split and merge code. However, changes to SizeBanks
|
||
; are also required that have not been fully tested on all
|
||
; machines yet, so that did _not_ get rolled in.
|
||
; <H6> 5/20/92 NJV Fixed register-trashing bug in SonoraMerge.
|
||
; <H5> 5/19/92 SWC Modified @MSCSplit and MSCMerge to temporarily support both MSC2
|
||
; and MSC3 while we make the transition.
|
||
; <H4> 5/12/92 HY Roll-in LC II changes. Change the sizing routine for VISA
|
||
; decoders to support 2 or 4MB on PCB.
|
||
; <H3> 5/4/92 JC Change Sonora split so that Bank 0 has 4 Megs of RAM installed.
|
||
; <H2> 4/13/92 JC Remove references to SonoraAddr (is going away) and replaced
|
||
; with references to RBVAddr for Sonora based machines.
|
||
; <SM11> 10/22/92 fau Added support for the YMCA Decoder in standard and wide mode.
|
||
; This involved adding a new YMCASize banks. Added a check to
|
||
; SizeBank to make sure we didn't spin forever if the ram bank end
|
||
; is not a multiple of 2^(n-1) * chunksize. (This will occur when
|
||
; sizing wide memory as standard memory). Also, changed the use
|
||
; of MMC/YMCAExists and MMC/YMCAAddr to use the decoder info.
|
||
; <SM10> 10/18/92 CCH Added support for HMC decoder.
|
||
; <SM9> 9/30/92 fau Incorporated support for the YMCA decoder that is found in
|
||
; Cyclone EVT4. This included the YMCA split routine and the
|
||
; YMCAMerge routine. Left the support for the MMC in there.
|
||
; Eventually, the MMC (used in previous Cyclone EVT's, should go
|
||
; away.)
|
||
; <SM8> 8/19/92 CSS Update from Reality:
|
||
; <23> 8/18/92 DTY Change the name of BootGlobs to StartGlobals to avoid confusion
|
||
; with BootGlobals, which is used by the boot code in Boot[1-3].a.
|
||
; <SM7> 8/17/92 CCH Changed orwell stitch code to use DecoderAddr field instead of
|
||
; OrwellAddr.
|
||
; <SM6> 8/11/92 kc Don't split memory while running the ROM image in RAM on
|
||
; Cyclone. Use A3 instead of A7 in SizeMem to make ReAnimator
|
||
; happy.
|
||
; <SM5> 8/9/92 CCH Don't attempt to stitch memory when running on a RISC processor
|
||
; in a Quadra.
|
||
; <SM4> 7/13/92 CCH Added conditionalized support for Cub Card on Quadras.
|
||
; <SM3> 5/25/92 RB Making Cyclone changes...Pandora/Horror comments follow: <P4>
|
||
; 5/13/92 KW (HV,H4) Roll-in LC II changes. Change the sizing
|
||
; routine for VISA decoders to support 2 or 4MB on PCB. (JC,H3)
|
||
; Change Sonora split so that Bank 0 has 4 Megs of RAM installed.
|
||
; <P2> 3/4/92 RMP Changed MMCMerge to configure Bank B correctly.
|
||
; <H5> 5/19/92 SWC Modified @MSCSplit and MSCMerge to temporarily
|
||
; support both MSC2 and MSC3 while we make the transition.
|
||
; <SM2> 5/16/92 kc Roll in Horror and Terror Changes. Comments follow:
|
||
; <H13> 01/27/92 jmp The original contents of this file have been moved to the
|
||
; SizeMemPatch.a file.
|
||
; <H9> 12/9/91 SAM Added a read to ROM in SizeBank between the RAM write and compare
|
||
; to prevent a floating bus from fooling us into thinking that
|
||
; there are 4 gigabytes of RAM built-in.
|
||
; <H7> 12/5/91 SAM Removing all special cases for built-in RAM for Vail machines
|
||
; cuz the hardware folks decided that their klude was a kludge.
|
||
; <H5> 12/3/91 SAM Changed Sonora split/merge code to use the new SonoraVIA2
|
||
; base address equate.
|
||
; <H4> 11/25/91 SAM First attempt at the Sonora sitch routine for Vail and
|
||
; Carnation.
|
||
; <H3> 10/22/91 SWC Changed MSCAddr references to RBVAddr since MSC is just a
|
||
; variant of the RBV.
|
||
; <H2> 8/5/91 SWC Added a fix to MSCMerge so that it works correctly if all RAM
|
||
; banks are not filled.
|
||
; <T9> 6/21/91 BG Swapped the order of the case table in SizeMemory to match the
|
||
; (new) order of the DecoderKinds table in UniversalEqu.a.
|
||
; <T7> 5/1/91 HJR SWC - Added support for the MSC for DB-Lite.
|
||
; <T4> 11/7/90 BG Made changes for new rev. of Orwell (2) permanent.
|
||
; <22> 12/29/91 RB Added Terror changes.
|
||
; <21> 9/16/91 JSM Cleanup header.
|
||
; <20> 6/12/91 LN removed #include 'HardwareEqu.a'
|
||
; <19> 3/5/91 dba put in an align directive so that we don’t get a warning
|
||
; <18> 3/5/91 PN Fix the warning by putting the END statement at the end
|
||
; <17> 9/24/90 GMR Added special case to JAWS merge code to deal with 2 meg bank A,
|
||
; 0 meg bank B and vice versa when the 2 meg is in a single chunk
|
||
; (as in TIM).
|
||
; <16> 9/19/90 BG Removed 040-related kludges (EclipseNOPs).
|
||
; <15> 8/2/90 CCH Clear D6 error flag after chunk table is written.
|
||
; <14> 7/10/90 CCH Fixed bug in orwell merge, and modified it to create a separate
|
||
; chunk table entry for each chunk listed in universal.a.
|
||
; <13> 5/10/90 GMR Preserved reg d2 inside FMCMerge.
|
||
; <12> 5/3/90 GMR Fixed file contents- ROMLister corrupted the file before
|
||
; check-in.
|
||
; <11> 5/3/90 GMR The chunk table now contains separate, contiguous chunks for
|
||
; each bank of RAM.
|
||
; <10> 4/25/90 GMR Made previous change save register A4, as before.
|
||
; <9> 4/21/90 GMR Moved ConfigureRAM functionality from StartInit.a to this file,
|
||
; to fix problems associated with writing the chunk table before
|
||
; the memory is stitched together. The sizing code now can size up
|
||
; to 8 banks before storing the info in the chunk table. Added
|
||
; Waimea splitting/stitching code to deal with it's 8 banks of
|
||
; RAM.
|
||
; <8> 4/2/90 JJ Correct memory address used to distinguish between Elsies with 1
|
||
; MB vs 2 MB on main logic board.
|
||
; <7> 3/23/90 JJ Added code to handle Elsie VISA 2 setting of size bits.
|
||
; <6> 2/28/90 JJ Added code to initialize memory size bits for machines with VISA
|
||
; decoders.
|
||
; <5> 2/21/90 BG The Orwell configuration code needed a small bit of tweaking.
|
||
; <4> 2/16/90 BG Added code to initialize Orwell bank addresses to the known
|
||
; default power-on state.
|
||
; <3> 1/11/90 CCH Added include of “HardwarePrivateEqu.a”.
|
||
; <2.9> 10/9/89 GMR NEEDED FOR ZONE5: Return bit mask for bad byte lanes, supporting
|
||
; up to 8 banks of 4 byte lanes each. Initialize FMC to put bank B
|
||
; on 64 Meg boundary.
|
||
; <2.8> 6/30/89 GMR Put FF's on bus between byte compare write/read cycles, to
|
||
; eliminate stray capacitance problems when no RAM present on
|
||
; access.
|
||
; <2.7> 6/26/89 GMR Changed to exit with a real stack pointer near low memory, top
|
||
; element on stack contains pointer to memory chunk table at top
|
||
; of last bank.
|
||
; <2.6> 6/11/89 GGD Converted to use RamInfo in rom tables.
|
||
; <2.5> 6/11/89 GMR Changed call to GetHardwareInfo to be a BigBSR6 so it'll reach.
|
||
; <2.4> 5/30/89 GMR Added comment describing error code returned in D6
|
||
; <2.3> 5/26/89 GMR Return error, instead of ignoring bank, if only some SIMMs in a
|
||
; bank are present. This should make Service happy.
|
||
; <2.2> 5/26/89 rwh changed to new improved BootGlobs field names.
|
||
; <2.1> 5/22/89 GMR Corrected prep of d2 before GetHardwareInfo call, optimized a
|
||
; few things, terminated tables with 1 long instead of 2 longs.
|
||
; <2.0> 5/16/89 GMR Rewrote entire file, returning a7 pointing to table of bank
|
||
; entries (start,length,...,$FFFF) on all machines. It's now
|
||
; non-destructive.
|
||
; ---------------Below doesn't apply now---------------
|
||
;==============================================================================================
|
||
; <1.9> 4/28/89 rle check startup code (now in d5) upon entry to determine if stack
|
||
; is valid or memory needs to be tested
|
||
; <1.8> 3/28/89 SES Cleaned up code to run a bit more efficiently. Added an initial
|
||
; browse through memory so that we can run out of Bank B only for
|
||
; HafMac.
|
||
; <1.7> 3/7/89 SES Added code to check for warm start and PwrMgr reset before
|
||
; running Ram test.
|
||
; <1.6> 2/24/89 SES Added code to ensure screen is clean for RBV-based machines.
|
||
; <1.5> 2/23/89 SES Mixed conditional for EXPORT BankASize to reflect what's in the
|
||
; body of routine.
|
||
; <1.4> 2/22/89 SES Added non-destructive code back in. Added check for startup or
|
||
; entry from booted system. Changed stack and table setup to be a
|
||
; bit more flexible. Still need to add a search for where first
|
||
; RAM is.
|
||
; <1.3> 2/16/89 rwh Added support for Fitch Memory Controller rev 1. When FMC2
|
||
; arrives, may need to change these for a contiguous physical
|
||
; memory model. Removed MvMac hack in SizeMem.
|
||
; <1.2> 2/16/89 SES Removed non-destructive code because restored values end up
|
||
; writing via wrap into locations that haven't been checked yet.
|
||
; <1.1> 2/15/89 SES Fixed routine so that it is non-destructive. On exit, stack will
|
||
; be set to the top of tested memory.
|
||
; <1.0> 2/13/89 SES Adding to EASE for the first time.
|
||
;
|
||
;_____________________________________________________________________________________________
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
INCLUDE 'STEqu.a'
|
||
INCLUDE 'MmuEqu.a'
|
||
INCLUDE 'BootEqu.a'
|
||
INCLUDE 'EDiskEqu.a'
|
||
INCLUDE 'DepVideoEqu.a'
|
||
PRINT ON
|
||
STRING ASIS
|
||
|
||
PROC
|
||
|
||
IMPORT GetHardwareInfo, RdXByte,RamInfoPrattFlash
|
||
EXPORT SizeMemory
|
||
EXPORT SizeSoundBuffer ; <SM14>
|
||
MACHINE MC68020
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: SizeMemory
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: a7 - initialized stack pointer (if RAM found), top element points to
|
||
; memory table of size blocks found.
|
||
; d6 - result code, 1 nibble/bank, 1 bit set for each SIMM bad in bank:
|
||
; = 00000000 if RAM sized ok
|
||
; = 00000001 if SIMM 0 in bank A is bad
|
||
; = 0000000F if SIMMs 0,1,2,3 in bank A are bad
|
||
; = 00000020 if SIMM 1 in bank B is bad
|
||
;
|
||
; NOTE!! D6 only holds error information for the first 8 banks! <H8>
|
||
;
|
||
; Uses: a0 - Ptr to table of base addresses
|
||
; a1 - Ptr to product info record
|
||
; d0
|
||
;
|
||
; Destroys: d0-d5,a0-a3,a5
|
||
;
|
||
; This file contains the universal size memory routine, which sizes memory banks
|
||
; for all machines and returns a table of start/size records for each bank found.
|
||
; It assumes data cache is off, and no MMU translation.
|
||
; The table is located at the top of the last bank of RAM found, and the entries
|
||
; have the following format:
|
||
;
|
||
; A7 --> (pointer to chunk table) -----
|
||
; |
|
||
; |
|
||
; ChunkTable: start.L,length.L { bank A } <----
|
||
; start.L,length.L { bank B }
|
||
; ... { bank n }
|
||
; $FFFFFFFF
|
||
;_____________________________________________________________________________________________
|
||
WITH DecoderInfo,DecoderKinds,StartGlobals, RAMBankInfo ; <SM3> rb <SM8> CSS
|
||
|
||
SizeMemory
|
||
move.l a6,d3 ; save return address
|
||
|
||
moveq #0,d2 ; don't know anything about machine
|
||
BigBSR6 GetHardwareInfo,a0
|
||
move.l d3,a2 ; now keep return address in a2
|
||
|
||
moveq #0,d3 ; clear a reg
|
||
move.b d2,d3 ; get memory controller type
|
||
add.w d3,d3 ; adjust for word table index
|
||
move.w @splitTbl(d3.w),d3 ; get offset to splitter routine
|
||
jmp @splitTbl(d3.w) ; SWITCH(controller type)
|
||
|
||
@splitTbl
|
||
|
||
; This table should match the DecoderKinds record in UniversalEqu.a
|
||
|
||
dc.w SizeBanks -@splitTbl ; unknown
|
||
dc.w SizeBanks -@splitTbl ; Mac Pal (no splitting required)
|
||
dc.w SizeBanks -@splitTbl ; BBU (no splitting required)
|
||
dc.w SizeBanks -@splitTbl ; Normandy (no splitting required)
|
||
dc.w @GlueSplit -@splitTbl ; Mac2Glue
|
||
dc.w SizeBanks -@splitTbl ; MDU (no splitting required)
|
||
dc.w @FMCSplit -@splitTbl ; OSS FMC
|
||
dc.w @VisaSplit -@splitTbl ; VISA <T9>
|
||
dc.w @OrwellSplit -@splitTbl ; Orwell <T9>
|
||
dc.w @JAWSSplit -@splitTbl ; JAWS
|
||
dc.w @MSCSplit -@splitTbl ; MSC <7> HJR
|
||
dc.w @SonoraSplit -@splitTbl ; Sonora <H4> SAM
|
||
dc.w @NiagraSplit -@splitTbl ; Niagra <xxx>
|
||
dc.w @YMCASplit -@splitTbl ; Cyclone EVT4 <SM9> fau
|
||
dc.w @djMEMCSplit -@splitTbl ; djMEMc <SM10><SM14>
|
||
dc.w HMCMerge -@splitTbl ; HMC (Go directly to the merge routine) <SM25> <SM10>
|
||
dc.w @PrattSplit -@splitTbl ; Pratt <SM15>
|
||
dc.w HHeadMerge -@splitTbl ; HHead (Go directly to the merge routine) <SM10>
|
||
|
||
Align 4
|
||
;_____________________________________________________________________________________________
|
||
@GlueSplit
|
||
move.l VIA2Addr(a0),a5 ; Yes, get VIA2 base
|
||
ori.b #$C0,VBufA(a5) ; put bank B on 64 meg boundary
|
||
bra SizeBanks ; continue with sizing
|
||
|
||
;_____________________________________________________________________________________________
|
||
@FMCSplit
|
||
movea.l FMCAddr(a0),a5 ; get the FMC base address
|
||
move.w #FMCInit,d2 ; config reg value to put bank B on 64 meg boundary
|
||
moveq.l #16-1,d3 ; loop counter to load 16 bits
|
||
@FMCload move.b d2,FMCConfig(a5) ; load in a bit
|
||
lsr.w #1,d2 ; put next bit into position
|
||
dbra d3,@FMCload ; repeat till all bits loaded
|
||
move.b d2,FMCLatch(a5) ; latch the config data
|
||
bra SizeBanks ; continue with sizing
|
||
|
||
;_____________________________________________________________________________________________
|
||
;
|
||
; Make sure that the 4 banks are split apart onto their default 64MB boundaries.
|
||
; No other changes to the Orwell configuration register are needed because they
|
||
; have been set up in Universal.a and shouldn't require any changes or reconfiguration.
|
||
; See {IntAIncludes}HardwarePrivateEqu.a for a full description of this register.
|
||
;_____________________________________________________________________________________________
|
||
WITH ProductInfo
|
||
|
||
@OrwellSplit
|
||
IF forSTP601 THEN
|
||
bra OrwellMerge ; sized memory in HardwareInit.s <SM46>
|
||
ENDIF
|
||
|
||
IF forSmurf THEN ; <SM24> SAM
|
||
cmp.b #boxRiscQuadra700,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM42>
|
||
cmp.b #boxRiscQuadra900,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM42>
|
||
cmp.b #boxRiscQuadra950,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM29>
|
||
ENDIF
|
||
; Eclipse/040 Memory Controller INIT <4>
|
||
movea.l DecoderAddr(a0),a5 ; get base address of Orwell regs <SM7>
|
||
lea OrBankBCfgAddr(a5),a0 ; get address of config regs.
|
||
move.l #((ORINITBankB)|\ ; get default bank-split values <T6>
|
||
(ORINITBankC<<OrBankFieldSize)|\; <T6>
|
||
(ORINITBankD<<2*OrBankFieldSize)),d3; <T6>
|
||
moveq.l #(3*OrBankFieldSize)-1,d2 ; (18-1) -1 for DBRA, <T3><T4><T6>
|
||
|
||
@OrwellLoad move.l d3,(a0)+ ; send that bit out there
|
||
lsr.l #1,d3 ; get the next bit in position
|
||
dbra d2,@OrwellLoad ; repeat til all bits loaded <T2>
|
||
|
||
move.l d2,OrLoadBanks(a5) ; initialize DRAM bank starting addrs <T2>
|
||
;
|
||
bra SizeBanks ; continue with sizing
|
||
|
||
;_____________________________________________________________________________________________
|
||
@VisaSplit
|
||
move.l RBVAddr(a0),a5 ; Yes, get VISA base <6><SM4> rb, start
|
||
andi.b #%00011111,VsExp(a5) ; clear size bits. Bits now set to 4MB on PCB <H5><Begin>
|
||
; and no memory in SIMMs
|
||
movea.l #$001FFFFE,a0 ; Figure out whether we have 2/4mb on PCB by
|
||
; writing to 2/3 MB boundary.
|
||
move.l #$50616E44,(a0) ; Write a long word. Low then high byte is written out to bus
|
||
cmp.l #$50616E44,(a0) ; If what we wrote is what we get back then we have 4MB on PCB.
|
||
bne.s @got2MB
|
||
ori.b #%11000000,VsExp(a5) ; push RAM on PCB up to 8MB boundary so we can check how much RAM in SIMMs
|
||
|
||
;••••••••••••••••••••••••••••••••
|
||
; At this point we've determined that there is 4MB on PCB. We must now figure out how much
|
||
; RAM is in the SIMM sockets before going on any further. If we have 8Mb in SIMMs then the
|
||
; size bits are set correctly (we then lose 2Mb of on board memory), but if we have less than
|
||
; 8Mb the size bits are incorrect and if left this way the on board memory will not be sized
|
||
; correctly by the routines that follow and the chunk table will be wrong.
|
||
|
||
move.l a5,a7 ; save ptr to VISA base address in a7
|
||
move.l a1,a5 ; get product info ptr
|
||
adda.l ProductInfo.RamInfoPtr(a5),a5
|
||
adda.l #RAMInfoSize+4,a5 ; '+4' taking into account the end of table mark
|
||
move.l #0,a0 ; start of bank A
|
||
move.l #$00800000,a1 ; end of bank A
|
||
move.l #0,d0 ; no previous banks sized
|
||
move.l #$54696e61,d1 ; setup signature
|
||
move.l #0,d5 ; clear bank size nibbles
|
||
BSR6 SizeBank ; how much memory do we have in Bank A?
|
||
cmp.l #$00800000,a0 ; SizeBank returns amount of RAM found in A0
|
||
|
||
blt.s @notMaxMem ; if less than 8mb found then reset size bits and RAM ranges
|
||
|
||
sub.l #RAMInfoSize+4,a5
|
||
bra continue
|
||
@notMaxMem
|
||
ori.b #%10000000,VsExp(a7)
|
||
andi.b #%10011111,VsExp(a7) ; set Bank A to 4mb, since this is the next size if not 8mb
|
||
bra continue
|
||
@got2MB
|
||
ori.b #%11100000,VsExp(a5) ; set size bits to 10mb (i.e. 2mb on PCB and 8mb in SIMMs)
|
||
; we set Bank A to 8Mb so PCB RAM is pushed out of the way
|
||
; so we can then get an accurate reading of Bank A RAM. <SM4> rb, end <H5><End>
|
||
bra SizeBanks ; and continue with sizing
|
||
|
||
ENDWITH
|
||
;_____________________________________________________________________________________________
|
||
@NiagraSplit
|
||
@JAWSSplit
|
||
moveq #0,d0
|
||
movea.l JAWSAddr(a0),a5 ; get ptr to JAWS base
|
||
adda.l #JAWSMemConfigA,a5
|
||
move.b d0,(a5) ; set size reg A
|
||
adda.w #JAWSMemConfigB-JAWSMemConfigA,a5
|
||
move.b d0,(a5) ; set size reg B
|
||
adda.w #JAWSMemConfigC-JAWSMemConfigB,a5
|
||
move.b d0,(a5) ; set size reg C
|
||
bra SizeBanks ; and continue with sizing <22> rb
|
||
|
||
;_____________________________________________________________________________________________
|
||
@MSCSplit
|
||
move.l RBVAddr(a0),a5 ; get MSC base (same as RBV's) <H3> <SM12> begin
|
||
ori.b #(1<<MSCBank8M)|\
|
||
(%111<<MSCSize0),MSCConfig(a5) ; make all banks accessable <H5>
|
||
MOVEA.L A1,A5 ; point to ProductInfo table <H5>
|
||
ADDA.L ProductInfo.RamInfoPtr(A5),A5 ; point to the RAM bank map info <H5>
|
||
BRA.S @MSCRefresh ; <H5>
|
||
@MSCNextBank ; <H5>
|
||
MOVEA.L D2,A0 ; point to the start of this bank <H5>
|
||
MOVEQ #8-1,D0 ; make enough long word accesses to <H17>
|
||
@RASLoop TST.L (A0)+ ; provide 8 RAS cycles of <H17>
|
||
DBRA D0,@RASLoop ; memory initialization <H17>
|
||
@MSCRefresh ADDQ.L #4,A5 ; skip over the bank end <H5>
|
||
MOVE.L (A5)+,D2 ; last RAM bank? <H5>
|
||
BPL.S @MSCNextBank ; -> nope <H5>
|
||
bra SizeBanks ; and continue with sizing <7> HJR <SM12> end
|
||
|
||
;_____________________________________________________________________________________________
|
||
@PrattSplit
|
||
IF forRomulator THEN
|
||
TestInRAM a3 ; are we in RAM?
|
||
bne SizeBanks ; yes, then don't split
|
||
ENDIF
|
||
MOVEA.L A1,A5 ; point to ProductInfo table
|
||
ADDA.L ProductInfo.RamInfoPtr(A5),A5 ; point to the RAM bank map info
|
||
|
||
IF BlackBirdDebug THEN
|
||
PrattFlashSystem ; IF FlashSystem THEN
|
||
bne.s @Continue1 ;
|
||
BigLea RamInfoPrattFlash,a5 ; use phony Flash system RamInfoTables
|
||
@Continue1 ;
|
||
ENDIF ;
|
||
movea.l PrattAddr(a0),a0 ; get ptr to Pratt
|
||
move.b #PrattDefDensity,\ ;
|
||
PrattRAMDensity(a0) ; set default RAM Density
|
||
|
||
move.b #PrattDefConfig,\ ; (don't worry, Pratt will do the right thing if there is Flash)
|
||
PrattRAMConfig(a0) ; set default RAM Configuration
|
||
|
||
;** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING **
|
||
;The following line was added to test Pratt timing for OTPs currently in use for EVT's.
|
||
;For the final product, we need to decide what this value should really be.
|
||
;NOTE: This value does not affect execution speed from Flash.
|
||
move.b #Pratt150nsROM,\
|
||
PrattROMSpeed(a0)
|
||
;** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING **
|
||
|
||
; wait for at least 2mS so that Pratt has time to initialize the RAM banks to meet all
|
||
; vendor specs (the HW spec is really ~500 uS, so we have some margin here)
|
||
move.w #$3000,d2
|
||
@stall dbra d2,@stall
|
||
|
||
BRA.S @PrattRefresh ;
|
||
|
||
@PrattNextBank ;
|
||
MOVEA.L D2,A0 ; point to the start of this bank
|
||
TST.L (A0)+ ; make 8 accesses to each physical RAM bank (for added confidence)
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
TST.L (A0)+
|
||
@PrattRefresh
|
||
ADDQ.L #4,A5 ; skip over the bank end
|
||
MOVE.L (A5)+,D2 ; last RAM bank?
|
||
BPL.S @PrattNextBank ; -> nope
|
||
bra SizeBanks ; and continue with sizing
|
||
|
||
;_____________________________________________________________________________________________
|
||
@SonoraSplit ; <H4>
|
||
MOVE.L RBVAddr(A0),A5 ; Get RBV (Sonora VIA2) <H4> <H2>
|
||
ORI.B #%01111111,SonoraRAMSize(A5) ; Make each bank start at 16mg boundary <H4><H3>
|
||
; and make bank 0 assume 4 megs of RAM <H3>
|
||
BRA SizeBanks ; and continue with sizing <H4>
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
@YMCASplit ;
|
||
IF forRomulator THEN
|
||
TestInRAM a3 ; are we in RAM?
|
||
bne SizeBanks ; yes, then don't split <SM13>
|
||
ENDIF
|
||
|
||
; Set the width options for all 4-pairs of banks to 0 (Standard Mode) This is necessary because <SM11> fau start
|
||
; SizeMem is called multiple times by diagnostics, so the power-up values for the YMCA might be changed
|
||
; by the time the 2nd call is made.
|
||
|
||
Move.l DecoderAddr(A0),A5 ; Get YMCA's Base address
|
||
Lea YMCA_DRAMwidth0(a5),a5 ; Get the base address for the first bank's width register
|
||
Clr.l (A5)+ ; Bank's 0,2
|
||
Clr.l (A5)+ ; Bank's 1,3
|
||
Clr.l (A5)+ ; Bank's 4,6
|
||
Clr.l (A5)+ ; Bank's 5,7 <SM11> fau end
|
||
|
||
; Write to all 8 bank addresses to set their starting addresses 16 MB apart and to set their size to
|
||
; 16 MBytes.
|
||
Move.l DecoderAddr(A0),A5 ; Get YMCA's Base address
|
||
Lea YMCA_DRAMBank0_A20(a5),a5 ; Get the base address for the first bank's A20 register
|
||
|
||
Moveq #0,D0 ; D0 Contains the starting address
|
||
Move.w #8-1,D5 ; No of banks
|
||
|
||
@NextBank
|
||
Move.w #BankBdryRegSize-1,d2 ; Size of boundary address register (bits A26..A20 starting at 0)
|
||
|
||
@loadBdry Ror.l #1,d0 ; Move bit 0 to bit 31
|
||
move.l d0,(a5)+ ; and write it out
|
||
dbra d2,@loadBdry ; continue for all bits
|
||
|
||
Rol.l #BankBdryRegSize,D0 ; Return the address to it's starting position
|
||
Add.l #$10,D0 ; Add (16M >> 20) to the address
|
||
|
||
Move.l #%101,D1 ; D1 contains the size bits = 16MB banks
|
||
Move.w #BankSizeRegSize-1,d2 ; size of memory bank size bits
|
||
|
||
@loadSize Ror.l #1,d1 ; d1 = nibble size = bank size
|
||
move.l d1,(a5)+ ; and write it out
|
||
dbra d2,@loadSize ; continue for all bits
|
||
dbra d5,@NextBank ; go look at the next bank
|
||
|
||
|
||
BRA YMCASizeBanks ; and continue with sizing <SM11>
|
||
; <SM9> fau, end
|
||
|
||
;_____________________________________________________________________________________________ <H7> thru next <H7>
|
||
WITH ProductInfo
|
||
|
||
@djMEMCSplit ; <SM12>begin
|
||
IF forSTP601 THEN
|
||
bra OrwellMerge ; sized memory in HardwareInit.s, so act exactly like STP Orwell machines <SM48>
|
||
ENDIF
|
||
IF forSmurf THEN ; <SM23>
|
||
cmp.b #boxRiscCentris610,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM29>
|
||
cmp.b #boxRiscCentris650,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM29>
|
||
cmp.b #boxRiscQuadra800,ProductKind(a1) ; if we're on a Risc card <SM29>
|
||
beq SizeBanks ; >>SKIP this <SM29>
|
||
cmp.b #boxRiscQuadra610,ProductKind(a1) ; if we're on a Risc card <SM30>
|
||
beq SizeBanks ; >>SKIP this <SM30>
|
||
cmp.b #boxRiscQuadra650,ProductKind(a1) ; if we're on a Risc card <SM30>
|
||
beq SizeBanks ; >>SKIP this <SM30>
|
||
ENDIF ; <SM23> SAM
|
||
; We need to determine whether this machine is a WLCD or not. Get VIA1 information.
|
||
;
|
||
; Useful VIA1 PortA bits to read: PA6, PA4, PA2, PA1 ($56)
|
||
;
|
||
; PA6 = Lego (1), or Frigidaire (0) plastics for Wombat
|
||
; PA4, PA2 = CPU Speed. 0=20MHz, 1=25MHz, 2=33MHz, 3=40MHz
|
||
; PA1 = WLCD or Primus (0), or NOT! [reserved] (1)
|
||
;
|
||
|
||
move.l VIA1Addr(a0),a5 ; get VIA1 address to get machine/cpu_speed info
|
||
moveq #%00101000,d1 ; force VIA1 VDirA to have the correct directions
|
||
move.b d1,VDirA(a5) ; ... so we can read the CPU ID extension info
|
||
|
||
; Preset/Reset the Interleaving Enable register:
|
||
; ----------------------------------------------
|
||
;
|
||
; To be able to call SizeBanks repeatedly, we need to turn OFF any interleaving we may have
|
||
; turned on during previous SizeMemory calls. However, if you are a WLCD, you want to have
|
||
; enabled the OneBufferedBus flag in the InterleaveEnable register. _I_ would have put this
|
||
; bit in a different register (Configuration Register?) but since it's not, we have to make
|
||
; sure it is correctly set.
|
||
;
|
||
; For WLCD and Primus, the OneBufferedBus bit MUST be set.
|
||
; For Wombat(s), the OneBufferedBus bit MUST be CLEARED.
|
||
|
||
moveq #0,d0 ; preset InterleaveEnable to NO interleaving <H8>
|
||
btst.b #1,VBufA(a5) ; PA1: 0 = WLCD, ≠0 = NOT WLCD <H8>
|
||
bne.s @writeIntReg ; IF ( machine_type == WLCD ) || ( machine_type == Primus ) <H16>
|
||
bset #dj_OneBufferedBusBit,d0 ; set OneBufferedBus bit
|
||
@writeIntReg ; ENDIF
|
||
LEA MEMCAddr,A5 ; Get djMEMC base
|
||
move.l d0,MEMCIntleaveEnable(a5) ; disable interleaving, set/clear OneBufferedBus bit
|
||
|
||
; Reset the chip's MemTop
|
||
|
||
MOVEQ #-1,D0
|
||
MOVE.L D0,MEMCmemTop(A5) ; Set MemTop reg to $FF
|
||
|
||
; Reset all bank Cfg Regs so each bank starts on a 64 mb boundary in preparation
|
||
; for sizeBanks. (ie put $110 in Cfg1, $120 in Cfg2, etc.)
|
||
|
||
;_____________________________________________________________________________ <H8> thru next <H8>
|
||
; MEMC DRAM Bank configuration registers look like this: | 11-9 | 8 | 7-0 |
|
||
; Bits 11-9 are unused.
|
||
; Bit 8 is DRAM addressing mode (0 = 64mb bank, 1 = 4mb or 16mb bank)
|
||
; Bits 7-0 are bits 29-22 of the bank's starting physical address.
|
||
; (i.e. smallest bank size = 4mb)
|
||
;
|
||
; Hysterical Note: (BG - 92 June 10)
|
||
; The High-End HW team says that it is entirely unlikely that we'll
|
||
; see 64MBit parts any time in the near future, and it's unlikely that
|
||
; from power/voltage requirements that our boards would be able to
|
||
; support them. So instead of writing the Sizing code to make two passes,
|
||
; one with bit 8 ZERO to check for 64MB banks, then a second pass for
|
||
; non-64MB parts to see whether or not they are there, we simply assume
|
||
; they are NOT there and set bit 8 front and make a single pass.
|
||
;_____________________________________________________________________________
|
||
|
||
MOVE.L #$100,D1 ; Default bank start address (bits 29-22 of addr)
|
||
MOVEQ #dj_MaxBanks-1,D0 ; Loop counter (10 banks) <H8>
|
||
LEA MEMCdRAMCfg0(A5),A5 ; Get starting bank Cfg reg base
|
||
|
||
@Loop MOVE.L D1,(A5)+
|
||
ADD.W #$10,D1 ; Bump the start addr by 64 meg (bits 29-22 of addr)
|
||
DBRA D0,@Loop
|
||
|
||
* BRA.S SizeBanks ; and continue with sizing <H7>
|
||
|
||
; <SM12>end
|
||
|
||
ENDWITH
|
||
;=============================================================================================
|
||
SizeBanks
|
||
movea.l a1,a5 ; pointer to product info table <2.6>
|
||
adda.l ProductInfo.RamInfoPtr(a5),a5 ; point to the ram bank map info <2.6>
|
||
|
||
IF BlackBirdDebug THEN
|
||
btst #(PrattExists//8),(ProductInfo.BasesValid1+3-(PrattExists/8))(a1)
|
||
beq.s @noPratt
|
||
PrattFlashSystem ; IF FlashSystem THEN
|
||
bne.s continue ;
|
||
BigLea RamInfoPrattFlash,a5 ; use phony Flash system RamInfoTables
|
||
@noPratt
|
||
ENDIF ;
|
||
|
||
Continue ; label needed for VISA memory sizing <H5><SM4> rb
|
||
moveq #0,d0 ; clear total RAM size <H8><SM12>
|
||
sub.l a3,a3 ; initialize the "bank 8-15" information <H7><SM12>
|
||
subq.l #1,a3 ; ... to an improbable bank config value <H8><SM12>
|
||
@SizeBanks2 ; label needed for djMEMC sizing 2nd half of table <H8><SM12><SM13>
|
||
movea.l a5,a7 ; keep running copy in a7 <SM12>
|
||
addq.l #4,a7 ; skip over chunk size <SM12>
|
||
moveq #0,d5 ; clear bank size nibbles
|
||
moveq #0,d6 ; clear error bits
|
||
move.l #$54696e61,d1 ; setup signature
|
||
@nextBank
|
||
ror.l #4,d5 ; make room for next bank size nibble
|
||
ror.l #4,d6 ; make room for next bank error nibble
|
||
movea.l (a7)+,a0 ; get start of bank (or terminator) <SM12>
|
||
move.l a0,d2 ; end of table?
|
||
cmpi.l #'SamB',d2 ; at end of 1st table? <H8>
|
||
beq.s @checkErr ; -> yes, check for errs then continue <H8>
|
||
addq.l #1,d2
|
||
beq.s @checkErr ; yes, check for any errors and quit <SM12>
|
||
movea.l (a7)+,a1 ; get end+1 of bank <SM12>
|
||
|
||
BSR6 CheckByteLanes ; any byte lanes valid at start? <2.3>
|
||
moveq #$0F,d3 ; byte lane mask
|
||
and.b d6,d3 ; all byte lanes good here?
|
||
beq.s @size ; yes, try next bank <2.3>
|
||
cmp.b #$0F,d3 ; were all byte lanes bad?
|
||
bne.s @nextBank ; no, leave mask with bad bits
|
||
eor.b d3,d6 ; yes, clear out bit mask
|
||
bra.s @nextBank
|
||
|
||
@size BSR6 SizeBank ; find size of this bank
|
||
bra.s @nextBank ; now size next bank...
|
||
|
||
@checkErr move.l a7,d2 ; Save A7 <H8><SM12>
|
||
sub.l a5,d2 ; (table end + 8) - table start <H8><SM12>
|
||
subq.l #8,d2 ; #entries * 8 <H8><SM12>
|
||
lsr.w #1,d2 ; / 8 * 4 = # of nibbles to roll
|
||
rol.l d2,d5 ; d5 = ....dcba
|
||
rol.l d2,d6 ; d6 = ....dcba
|
||
|
||
tst.l d6 ; any errors?
|
||
bne.s @badBanks ; -> Yes, return now <H8> thru next <H8><SM12>
|
||
|
||
move.l a0,d2 ; get the terminator or extend flag in D2 <SM12>
|
||
cmpi.l #'SamB',d2 ; Extended flag? <SM12>
|
||
bne.s @stitchEm ; -> Nope, we're done <SM12>
|
||
move.l d5,a3 ; We have more to do, save D5 in A3 <SM12>
|
||
|
||
move.l a7,a5 ; Point A5 at the 2nd half of RAMInfo <SM12>
|
||
bra.s @SizeBanks2 ; -> make the second pass <SM12><SM13>
|
||
|
||
@stitchEm move.l a3,d2 ; have we put anything in A3 yet? <SM12>
|
||
addq.l #1,d2 ; if not, it was $FFFFFFFF <SM12>
|
||
beq.w Concat ; IF SomethingInA3 THEN <SM12>
|
||
move.l a3,d6 ; Put the extended nibbles in D6 <SM12>
|
||
exg d6,d5 ; Put low order banks in d5, extended in d6 <SM12>
|
||
bra.w Concat ; Sew baby sew! <SM12>
|
||
|
||
@badBanks jmp (a2) ; yes, return immediately <H8><SM12>
|
||
|
||
|
||
|
||
|
||
;=============================================================================================
|
||
; <SM11> fau start
|
||
YMCASizeBanks
|
||
;
|
||
; The YMCA has a separate SizeBanks routine because it supports standard and wide mode DRAM SIMMs. (See
|
||
; the YMCA ERS). Wide Mode DRAMs have more rows than columns and use less power -- Wombat uses these too.
|
||
; But, we're different and we support the standard mode, where the # of rows and columns are the same. What
|
||
; this means is that in order to size the banks we have to go through the sizing routine twice: once with
|
||
; the memory controller addressing the SIMMS in standard mode, and once in wide mode. (Note: The YMCA ERS
|
||
; has this complicated roadmap to follow in order to size the memory. After reviewing and looking at the
|
||
; DRAMs we support I determined that we can size the memory by making the two passes (standard and wide) and
|
||
; then comparing the nibble sizes for each bank and taking the largest one). One has to be careful because
|
||
; the standard/wide mode is programmed by bank pair: 0/2, 1/3, 4/6, and 5/7. Any bank can be populated, thus
|
||
; have to watch out for nibble sizes of 0. Well, enough of this. FAU 10/21/92
|
||
|
||
movea.l a1,a5 ; pointer to product info table
|
||
movea.l a1,a7 ; save a copy in a7 for the second sizing.
|
||
adda.l ProductInfo.RamInfoPtr(a5),a5 ; point to the ram bank map info
|
||
|
||
IF forRomulator THEN
|
||
|
||
TestInRAM a3 ; Are we in RAM?
|
||
beq.s @YMCAnotInRAM ; No? Then carry on.
|
||
; Yes? Assume Bank A is 4 MB
|
||
movea.l a5,A3 ; keep running copy in A3
|
||
add.l #$0C,A3 ; skip over chunk size and bank A
|
||
move.l #$00400000,d0 ; set RAM size for bank A
|
||
moveq #$01,d5 ; set bank A size nibbles
|
||
moveq #0,d6 ; clear error bits
|
||
move.l #$54696e61,d1 ; setup signature
|
||
|
||
bra.s @YMCAnextBank ; start checking at bank B
|
||
@YMCAnotInRAM
|
||
ENDIF
|
||
|
||
movea.l a5,A3 ; keep running copy in A3
|
||
addq.l #4,A3 ; skip over chunk size
|
||
moveq #0,d0 ; clear total RAM size
|
||
moveq #0,d5 ; clear bank size nibbles
|
||
moveq #0,d6 ; clear error bits
|
||
move.l #$54696e61,d1 ; setup signature
|
||
@YMCAnextBank
|
||
ror.l #4,d5 ; make room for next bank size nibble
|
||
ror.l #4,d6 ; make room for next bank error nibble
|
||
movea.l (A3)+,a0 ; get start of bank (or terminator)
|
||
move.l a0,d2 ; end of table?
|
||
addq.l #1,d2
|
||
beq.s @YMCAcheckErr ; yes, check for any errors
|
||
movea.l (A3)+,a1 ; get end+1 of bank
|
||
|
||
BSR6 CheckByteLanes ; any byte lanes valid at start?
|
||
moveq #$0F,d3 ; byte lane mask
|
||
and.b d6,d3 ; all byte lanes good here?
|
||
beq.s @YMCAsize ; yes, try next bank
|
||
cmp.b #$0F,d3 ; were all byte lanes bad?
|
||
bne.s @YMCAnextBank ; no, leave mask with bad bits
|
||
eor.b d3,d6 ; yes, clear out bit mask
|
||
bra.s @YMCAnextBank
|
||
|
||
@YMCAsize BSR6 SizeBank ; find size of this bank
|
||
bra.s @YMCAnextBank ; now size next bank...
|
||
|
||
@YMCAcheckErr
|
||
suba.l a5,A3 ; (table end + 8) - table start
|
||
subq.l #8,A3 ; #entries * 8
|
||
move.l A3,d2
|
||
lsr.w #1,d2 ; / 8 * 4 = # of nibbles to roll
|
||
rol.l d2,d5 ; d5 = ....dcba
|
||
rol.l d2,d6 ; d6 = ....dcba
|
||
|
||
tst.l d6 ; any errors?
|
||
bne @ExitSizeMem ; if so, don't do the wide banks stuff
|
||
|
||
; Now, resize the memory in wide mode.
|
||
; Save d5 in a7 and do the sizing with the wide mode. Note, d0 has the total size of DRAM, but
|
||
; we're going to recalculate this later, once we figure out which bank needs to be in standard mode and
|
||
; which one is in wide mode
|
||
|
||
; Get back the RamInfoPtr and the Address of our Decoder
|
||
|
||
movea.l a7,a5 ; restore the pointer to the product info table
|
||
adda.l ProductInfo.RamInfoPtr(a5),a5 ; point to the ram bank map info <2.6>
|
||
|
||
movea.l a7,a1 ; restore the pointer to the product info
|
||
adda.l ProductInfo.DecoderInfoPtr(a1),a1 ; point to the decoder info stuff
|
||
movea.l DecoderAddr(a1),a1 ; And get the decoder address
|
||
|
||
; Program the width registers to wide mode now
|
||
|
||
Lea YMCA_DRAMwidth0(a1),a1 ; and get the offset to the width options register
|
||
Move.l #-1,(a1)+ ; Bank's 0,2
|
||
Move.l #-1,(a1)+ ; Bank's 1,3
|
||
Move.l #-1,(a1)+ ; Bank's 4,6
|
||
Move.l #-1,(a1)+ ; Bank's 5,7
|
||
|
||
; Save our nibble sizes for standard mode
|
||
|
||
move.l d5,a7 ; save our standard mode bank sizes
|
||
|
||
IF forRomulator THEN
|
||
|
||
TestInRAM a3 ; Are we in RAM?
|
||
beq.s @2YMCAnotInRAM ; No? Then carry on.
|
||
; Yes? Assume Bank A is 4 MB
|
||
movea.l a5,A3 ; keep running copy in A3
|
||
add.l #$0C,A3 ; skip over chunk size and bank A
|
||
move.l #$00400000,d0 ; set RAM size for bank A
|
||
moveq #$01,d5 ; set bank A size nibbles
|
||
moveq #0,d6 ; clear error bits
|
||
move.l #$54696e61,d1 ; setup signature
|
||
|
||
bra.s @2YMCAnextBank ; start checking at bank B
|
||
@2YMCAnotInRAM
|
||
ENDIF
|
||
movea.l a5,A3 ; keep running copy in A3
|
||
addq.l #4,A3 ; skip over chunk size
|
||
moveq #0,d0 ; clear total RAM size
|
||
moveq #0,d5 ; clear bank size nibbles
|
||
moveq #0,d6 ; clear error bits
|
||
move.l #$54696e61,d1 ; setup signature
|
||
@2YMCAnextBank
|
||
ror.l #4,d5 ; make room for next bank size nibble
|
||
ror.l #4,d6 ; make room for next bank error nibble
|
||
movea.l (A3)+,a0 ; get start of bank (or terminator)
|
||
move.l a0,d2 ; end of table?
|
||
addq.l #1,d2
|
||
beq.s @2YMCAcheckErr ; yes, check for any errors
|
||
movea.l (A3)+,a1 ; get end+1 of bank
|
||
|
||
BSR6 CheckByteLanes ; any byte lanes valid at start?
|
||
moveq #$0F,d3 ; byte lane mask
|
||
and.b d6,d3 ; all byte lanes good here?
|
||
beq.s @2YMCAsize ; yes, try next bank
|
||
cmp.b #$0F,d3 ; were all byte lanes bad?
|
||
bne.s @2YMCAnextBank ; no, leave mask with bad bits
|
||
eor.b d3,d6 ; yes, clear out bit mask
|
||
bra.s @2YMCAnextBank
|
||
|
||
@2YMCAsize BSR6 SizeBank ; find size of this bank
|
||
bra.s @2YMCAnextBank ; now size next bank...
|
||
|
||
@2YMCAcheckErr
|
||
suba.l a5,A3 ; (table end + 8) - table start
|
||
subq.l #8,A3 ; #entries * 8
|
||
move.l A3,d2
|
||
lsr.w #1,d2 ; / 8 * 4 = # of nibbles to roll
|
||
rol.l d2,d5 ; d5 = ....dcba
|
||
rol.l d2,d6 ; d6 = ....dcba
|
||
|
||
tst.l d6 ; any errors?
|
||
bne @ExitSizeMem ; if so, don't do the wide banks stuff
|
||
|
||
; We have finished sizing the memory in wide mode. a7 has the nibble sizes with standard mode,
|
||
; and d5 has the nibble sizes in wide mode.
|
||
|
||
Move.l a7,d4
|
||
|
||
; OK, at this point d4 contains the nibble sizes when sized in standard mode and d5 contains the
|
||
; nibble sizes when sized in wide mode. We now need to determine, for each bank, which nibble contains
|
||
; the largest amount of ram and program the YMCA to the corresponding Std/Wide option. We'll put the
|
||
; combined nibble sizes into d0 and then move it to d5, as that's what the Concat routine expects.
|
||
|
||
Move.l #$50f30420,a3 ; YMCA Width Register
|
||
Lea YMCAWidthOffsets,a0 ; Offset lookup table
|
||
clr.w d1 ; Use d1 as our loop/bank counter
|
||
clr.l d0 ; d0 will contain the combined nibbles
|
||
|
||
@LoopBanks
|
||
move.b d4,d2 ; we need to compare lower nibbles only (d2: std)
|
||
andi.b #$0f,d2 ; so mask out higher nibble
|
||
move.b d5,d3 ; we need to compare nibbles only (d3: wide)
|
||
andi.b #$0f,d3 ; so mask out higher nibble
|
||
cmp.b d3,d2 ; d3<-wide, d2<-standard
|
||
bhs.s @StdMode ; if d2 is ≥ then program in standard mode <LW4>
|
||
or.b d3,d0 ; else, d3 is > so or move nibble into our keeper
|
||
Tst.b d3 ; Was our bank size 0 <LW4>
|
||
beq.s @NextNibble ; Don't set the width register if the size is 0
|
||
Move.w (a0,d1.w*2),a1 ; get offset for this bank
|
||
adda.l a3,a1 ; and add the base of the width registers
|
||
Move.l #-1,(a1) ; and write it out
|
||
bra.s @NextNibble ; go look at next nibble
|
||
@StdMode
|
||
or.b d2,d0 ; Standard width size into the keeper
|
||
; program bank d1 to std mode
|
||
Tst.b d2 ; Was our bank size 0 <LW4>
|
||
beq.s @NextNibble ; Don't set the width register if the size is 0
|
||
Move.w (a0,d1.w*2),a1 ; get offset for this bank
|
||
adda.l a3,a1 ; and add the base
|
||
Clr.l (a1) ; and write it out
|
||
@NextNibble
|
||
lsr.l #4,d4 ; look at next nibble of standard mode
|
||
lsr.l #4,d5 ; look at next nibble of wide mode
|
||
ror.l #4,d0 ; make room for next nibble in our keeper
|
||
addi.w #1,d1 ; increment our loop counter
|
||
cmpi.w #8,d1 ; have we done all 8 banks?
|
||
bne.s @LoopBanks ; go loop through the banks
|
||
|
||
move.l d0,d5 ; put the nibble sizes into d5
|
||
|
||
bra Concat ; no, then stitch banks together (if possible)
|
||
|
||
@ExitSizeMem
|
||
jmp (a2) ; yes, return immediately
|
||
; <SM11> fau end
|
||
;_____________________________________________________________________________________________
|
||
; Routine: SizeBank
|
||
;
|
||
; Inputs: a0 - points to start of physical bank to size
|
||
; a1 - points to end of physical bank to size
|
||
; a2 - SizeMem return address
|
||
; (a5) - page size to check for aliasing (e.g. 1 meg)
|
||
; d0 - total RAM from previous banks sized
|
||
; d1 - signature
|
||
; d5 - x......., where x = nibble sizes of previous bank(s) sized.
|
||
;
|
||
; Outputs: d0 - total RAM including this banks size.
|
||
; d5 - x......n, where n = nibble size of this bank (0..15)
|
||
; a0 - actual size of bank
|
||
;
|
||
; Destroys: a1,d2-d4
|
||
;
|
||
; Given the start and end of a bank of memory, this routine finds the last location
|
||
; within the bank which can be written to (including wrap). Then it trims this back,
|
||
; checking for wrap. On exit, it sets a0 = actual size of unique RAM found in the bank,
|
||
; (0 if no RAM found), and the low nibble of d5 contains n where bank size = 2^(n-1)*chunk size
|
||
; for n > 0, and bank size = 0 for n=0.
|
||
;
|
||
; This routine assumes that the data cache is OFF. The addresses passed in
|
||
; must be on page boundaries, where the page size is in D0.
|
||
;_____________________________________________________________________________________________
|
||
SizeBank
|
||
move.l a0,d4 ; save start of bank
|
||
|
||
subq.l #4,a1 ; point to end-4 of bank
|
||
@check move.l (a1),d2 ; save original
|
||
move.l d1,(a1) ; write signature at top
|
||
|
||
@here tst.l (@here) ; Bus capacitance is a no, no. <H9> SAM
|
||
|
||
cmp.l (a1),d1 ; any RAM there?
|
||
beq.s @foundRAM ; yes, check for wrap
|
||
|
||
suba.l (a5),a1 ; step back to lower block
|
||
cmpa.l a0,a1 ; stepped below start?
|
||
bgt.s @check ; no, continue looking for RAM
|
||
bra.s @exit ; yes, exit
|
||
|
||
@foundRAM
|
||
subq.l #4,a0 ; go 4 bytes back from start
|
||
@loop adda.l (a5),a0 ; add in chunk size
|
||
cmp.l (a0),d1 ; found lowest occurance of signature?
|
||
bne.s @loop ; no, check a little higher up
|
||
|
||
move.l d2,(a0)+ ; restore last four bytes we wiped out
|
||
@length suba.l d4,a0 ; leave a0 with size of bank
|
||
|
||
moveq #0,d3 ; n=0
|
||
move.l a0,d2 ; any ram?
|
||
beq.s @stuff ; no, stuff n=0 into size register
|
||
|
||
move.l (a5),d2 ; start with smallest chunk size (e.g. 1M)
|
||
@next addq #1,d3 ; n=n+1
|
||
cmpa.l d2,a0 ; (2^(n-1))*chunk size = bank size?
|
||
beq.s @stuff ; yes, stuff 'n' into d5
|
||
|
||
; If a0 < d2 then something is wrong! Stuff 0 into d3 and exit. <SM10> fau
|
||
|
||
blt.s @NotAPowerofTwo ; Our loop has gone over a possible match, so better bailout <SM10> fau
|
||
add.l d2,d2 ; calculate next power of two
|
||
bra.s @next
|
||
@NotAPowerofTwo ;<SM10> fau
|
||
moveq #0,d3 ; say no memory.
|
||
@stuff or.b d3,d5 ; 'OR' in 'n' (size of this bank)
|
||
add.l a0,d0 ; add this banks RAM to total size
|
||
@exit RTS6
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: CheckByteLanes
|
||
;
|
||
; Inputs: a0 - location to check
|
||
; d1 - signature
|
||
; d6 - x......0 where x = running bit mask of previous bank(s) SIMM errors
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: d6 - x......e where e = bit mask for this banks errors:
|
||
; e = 0000 if byte lanes 0-3 seem ok
|
||
; e = 0001 if byte lane 0 seems bad
|
||
; e = 1111 if byte lanes 0-3 seem bad
|
||
;
|
||
; Destroys: d2-d4
|
||
;
|
||
; This routine checks which byte lanes are valid at location pointed to by
|
||
; a0. This helps service identify missing SIMMs, etc. It can be called up
|
||
; to 8 times (for 8, 4-byte-wide banks) before overflowing the result register.
|
||
;_____________________________________________________________________________________________
|
||
CheckByteLanes ; <2.3>
|
||
move.l (a0),d3 ; preserve original value
|
||
move.l 4(a0),d4 ; preserve next value <2.8>
|
||
move.l d1,(a0) ; write signature
|
||
|
||
moveq #4-1,d2
|
||
@next move.l #$FFFFFFFF,4(a0) ; take care of stray capacitance on bus <2.8>
|
||
cmp.b (a0,d2.w),d1 ; did this byte match?
|
||
bne.s @bad ; no, shift in error bit
|
||
|
||
not.b d1 ; yes, try compliment to make sure
|
||
not.b (a0,d2.w) ; compliment RAM value
|
||
cmp.b (a0,d2.w),d1 ; did compliment match?
|
||
beq.s @shift ; yes, next byte...
|
||
|
||
@bad bset d2,d6 ; set bad bit mask <2.9>
|
||
|
||
@shift ror.l #8,d1 ; next signature byte
|
||
dbra d2,@next ; do next byte
|
||
move.l d3,(a0) ; restore original at start
|
||
move.l d4,4(a0) ; restore next value <2.8>
|
||
RTS6
|
||
|
||
|
||
|
||
|
||
|
||
;=============================================================================================
|
||
; Routine: Concat
|
||
;
|
||
; Inputs: d0 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; d6 - nibble sizes for up to an additional 8 banks <H7><H8><SM12>
|
||
; a2 - SizeMem return address
|
||
;
|
||
; This routine vectors to the appropriate 'stitch' routine, after getting the decoder type.
|
||
;_____________________________________________________________________________________________
|
||
Concat move.l d0,d3 ; save last size <9>
|
||
moveq #0,d2 ; don't know anything about machine
|
||
movea.l #aStack,sp ; set stack pointer value
|
||
move.l a2,d4 ; save return address
|
||
BigBSR6 GetHardwareInfo,a0 ; get universal info again
|
||
movea.l d4,a2 ; restore return address
|
||
|
||
IF BlackBirdDebug THEN
|
||
btst #(PrattExists//8),(ProductInfo.BasesValid1+3-(PrattExists/8))(a1)
|
||
adda.l ProductInfo.RamInfoPtr(a1),a1 ; point to the ram bank map info
|
||
beq.s @Continue1
|
||
PrattFlashSystem ; IF FlashSystem THEN
|
||
bne.s @Continue1 ;
|
||
BigLea RamInfoPrattFlash,a1 ; use phony Flash system RamInfoTables
|
||
@Continue1 ;
|
||
ELSE ;
|
||
adda.l ProductInfo.RamInfoPtr(a1),a1 ; point to the ram bank map info
|
||
ENDIF
|
||
add.b d2,d2 ; decoder type adjusted for word table access
|
||
ext.w d2
|
||
move.w @mergTbl(d2.w),d1 ; get offset to merger routine
|
||
move.l (a1)+,d2 ; get chunk size in d2 now
|
||
jmp @mergTbl(d1.w) ; call routine (d2=chunk size, a1=1st table entry)
|
||
|
||
@mergTbl
|
||
|
||
; This table should match the DecoderKinds record in UniversalEqu.a <SM9> fau
|
||
|
||
dc.w noMerge -@mergTbl ; unknown
|
||
dc.w noMerge -@mergTbl ; Mac Pal (no merging required)
|
||
dc.w noMerge -@mergTbl ; BBU (no merging required)
|
||
dc.w noMerge -@mergTbl ; Normandy (no merging required)
|
||
dc.w GlueMerge -@mergTbl ; Mac2Glue
|
||
dc.w MDUMerge -@mergTbl ; MDU (no merging possible)
|
||
dc.w FMCMerge -@mergTbl ; OSS FMC
|
||
dc.w VISAMerge -@mergTbl ; VISA <T9>
|
||
dc.w OrwellMerge -@mergTbl ; Orwell <T9>
|
||
dc.w JAWSMerge -@mergTbl ; JAWS
|
||
dc.w MSCMerge -@mergTbl ; MSC <7> HJR
|
||
dc.w SonoraMerge -@mergTbl ; Sonora <H4> SAM
|
||
dc.w NiagraMerge -@mergTbl ; Niagra <xxx>
|
||
dc.w YMCAMerge -@mergTbl ; YMCA <SM9> fau
|
||
dc.w djMEMCMerge -@mergTbl ; djMEMC (djMEMC has a max of 10 banks) <H7><SM12>
|
||
dc.w HMCMerge -@mergTbl ; HMC <SM18> SAM
|
||
dc.w PrattMerge -@mergTbl ; Pratt <SM15>
|
||
dc.w HHeadMerge -@mergTbl ; HHead
|
||
|
||
|
||
Align 4
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: noMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to universal base addresses table
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d1,a1
|
||
;
|
||
; This routine simply writes the chunk table at the top of the bank (pointed to by a1), given
|
||
; the banks size in d0. Used ONLY for single bank systems (like MacPlus, SE, Portable).
|
||
;_____________________________________________________________________________________________
|
||
noMerge ; <9>
|
||
moveq #(3*4)+(1*8),d1 ; size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
|
||
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: HMCMerge (emulated system fake stitch and fake chunk table creation) <SM18> Sam
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
; a1 - Ptr to product info record
|
||
;
|
||
; Destroys: D0-D3/D6,A0-A2
|
||
;
|
||
; This routine creates a fixed size chunk table at the end of logical RAM. The emulator provides
|
||
; us with the size of logical and physical RAM. The logical size accounts for the RAM stolen by
|
||
; the emu for DMA buffers, video, EDisk, etc. The Physical size is useful only for display at the
|
||
; Finder, etc. Oh, yes, by the time we get run (68k code, that is) the native hardware init has
|
||
; already sized and stitched memory together.
|
||
;
|
||
; The fake table looks like this:
|
||
;
|
||
; 1st bank start addr: $00000000
|
||
; Length (log ram size returned from the emu) 0 < X <= 256mb
|
||
; Chunk table terminator $FFFFFFFF
|
||
; Std diagnostic long #1 $00000000
|
||
; Std diagnostic long #2 $00000000
|
||
; Std diagnostic long #3 $00000000
|
||
; Total bytes allocated for an EDisk $xxxxxxxx
|
||
; Total RAM allocated by the nanokernel $xxxxxxxx ; The end of "Physical RAM"
|
||
;
|
||
; Table size: $20 bytes fixed.
|
||
;
|
||
; D7 is used as a flag register for the size of the RAM Disk and whether or not to allocate Video RAM
|
||
; bit 31: high = allocate Video RAM (bit is cleared when testing to turn on video or not)
|
||
;_____________________________________________________________________________________________
|
||
export HMCMerge
|
||
|
||
HMCMerge ; <SM18> Sam
|
||
With NKSystemInfo, ProductInfo, VideoInfo
|
||
|
||
MOVE.L A2,D6 ; Save SizeMem's return address
|
||
|
||
LongBSR6 GetHardwareInfo ; Get universal info again
|
||
MOVE.L DecoderInfo.VIA1Addr(A0),A2 ; Get VIA1's base address for RdXByte
|
||
|
||
; Read PRAM locations (FC through FF) and test for one of several factory settings that
|
||
; tell us to allocate a frame buffer (even if no monitor is connected)
|
||
|
||
MOVEQ.L #0,D7 ; Clear the fb allocation flag
|
||
MOVE.W #burnInLoc,D1 ; 1st burn in byte
|
||
BSR6 RdXByte ; Read the Factory data
|
||
MOVE.B D1,D3 ; Save hi byte
|
||
SWAP D3
|
||
LSL.L #8,D3 ; Shift to high byte
|
||
MOVEQ #0,D1 ; Prep D1 for PRAM data
|
||
MOVE.W #burnInLoc+1,D1 ; 2nd burn in byte
|
||
BSR6 RdXByte ; Read the Factory data
|
||
SWAP D1 ; Save second hi byte
|
||
OR.L D1,D3 ;
|
||
MOVEQ #0,D1 ; Prep D1 for PRAM data
|
||
MOVE.W #burnInLoc+2,D1 ; 3rd burn in byte
|
||
BSR6 RdXByte ; Read the Factory data
|
||
LSL.W #8,D1 ; Shift byte to second low byte
|
||
OR.L D1,D3 ;
|
||
MOVEQ #0,D1 ; Prep D1 for PRAM data
|
||
MOVE.W #burnInLoc+3,D1 ; 4th burn in byte
|
||
BSR6 RdXByte ; Read the Factory data
|
||
OR.L D3,D1 ; OR in the result
|
||
|
||
CMP.L #burninSig,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
CMP.L #burnInSigAlt,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
CMP.L #burnInSig12,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
CMP.L #burnInSig13,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
CMP.L #burnInSig15,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
CMP.L #burnInSig16,D1 ; Is this one of the factory settings?
|
||
BEQ @GetFB ; -> Yes, allocate the frame buffer
|
||
|
||
; No factory enable. Check to see what's connected. If nothing is connected, do not
|
||
; allocate the frame buffer.
|
||
|
||
MOVE.L #SonoraVdCtlBase,A0 ; Offset from VIA1 base to Sonora Control Regs
|
||
ADD.L A2,A0 ; Add in VIA1 base. A0 points to SonoraCtrlRegs
|
||
|
||
MOVE.B #$9F,SonoraVdModeReg(A0) ; Disable video (if it was on) <MC7>
|
||
MOVE.B #tristateSonoraSense,SonoraVdSenseRg(A0) ; Tristate the sense lines.
|
||
BSR6 CheckVidSense
|
||
CMP.B #indexedNoConnect,D3 ; If Sense == No Connect, check Extended Sense
|
||
BNE @GetFB ; Otherwise turn of Video RAM
|
||
|
||
MOVEQ #0,D1 ; prep D1 for Extended sense data
|
||
MOVEQ #0,D3 ; prep D2 for Extended sense data
|
||
|
||
; Sense lines indicate something might be connected. Check the extended sense.
|
||
|
||
; Drive a, Read bc
|
||
|
||
@DriveA MOVE.B #sonoraEnableAMask,SonoraVdSenseRg(A0) ; abc <- 011
|
||
BSR6 CheckVidSense
|
||
ANDI.B #sonoraAMask,D3 ; 0BC
|
||
MOVE.B D3,D1 ; 00 00 BC
|
||
LSL.B #2,D1 ; 00 BC 00
|
||
|
||
; Drive b, Read ac
|
||
|
||
@DriveB MOVE.B #sonoraEnableBMask,SonoraVdSenseRg(A0) ; abc <- 101
|
||
BSR6 CheckVidSense
|
||
ANDI.B #sonoraBMask,D3 ; A0C
|
||
BCLR #sonoraSenseLineA,D3 ; A0C becomes
|
||
BEQ.S @OrIn ; A0C or
|
||
BSET #sonoraSenseLineB,D3 ; A1C
|
||
|
||
@OrIn OR.B D3,D1 ; 00 BC AC
|
||
LSL.B #2,D1 ; BC AC 00
|
||
|
||
; Drive c, Read ab
|
||
|
||
@DriveC MOVE.B #sonoraEnableCMask,SonoraVdSenseRg(A0) ; abc -> 110
|
||
BSR6 CheckVidSense
|
||
ANDI.B #sonoraCMask,D3 ; AB0
|
||
LSR.B #1,D3 ; 0AB
|
||
OR.B D3,D1 ; BC AC AB
|
||
|
||
CMP.B #extendedNoConnect,D1 ; Is anything connected?
|
||
BEQ.S @NoFB ; -> Nope, leave D7 alone. Don't allocate the frame buffer
|
||
|
||
@GetFB BSET.L #31,D7 ; Set the "Allocate a DRAM frame buffer" flag
|
||
@NoFB
|
||
|
||
; Read PRAM to see if the user wants an EDisk. If the size is > MinRamDiskSize then ask the <SM21> SAM
|
||
; nanokernel for some RAM.
|
||
|
||
LongBSR6 GetHardwareInfo ; Get universal info again
|
||
MOVE.L DecoderInfo.VIA1Addr(A0),A2 ; Get VIA1's base address for RdXByte
|
||
|
||
MOVE.W #ramDiskPramAddr,D1 ; Get the EDisk PRAM byte constant
|
||
BSR6 RdXByte ; Read the EDisk size (in % of total RAM) in D1
|
||
MOVE.L D6,A2 ; Restore the return address
|
||
|
||
ADD.L VideoInfoPtr(A1),A1 ; Point A1 to the VideoInfo record for this machine
|
||
MOVE.L VRAMLogAddr32(A1),D6 ; Get the Logical Frame Buffer base address
|
||
|
||
; Get the MMU page size from the nanokernel. Count bits in the result to get a shift factor
|
||
|
||
MOVEQ #0,D3 ; Clear D3
|
||
MOVE.L ([ProcessorInfoPtr],ProcessorInfo.PageSize),D0 ; Get the Page size from the nano-k
|
||
BFFFO D0{15:15},D3 ; Get the shift factor (Find First One)
|
||
NOT.B D3 ; Flip the order (BF instr start at bit 32 -> )
|
||
ADD.B #32,D3 ; Get the bit number (lsb based)
|
||
|
||
MOVEQ #0,D5 ; Clear the EDisk allocation size <MC9>
|
||
MOVE.L (NKSystemInfoPtr),A5 ; Point to the nanokernel SystemInfo record
|
||
ANDI.L #$FF,D1 ; Clear upper bytes of pram byte
|
||
BEQ.S @DMABuffer ; -> No EDisk, check DMA Buffer
|
||
|
||
MOVE.L PhysicalMemorySize(A5),D2 ; Get physical RAM size
|
||
LSR.L #8,D2 ; Scale the size by 256k chunks
|
||
MULU.L D1,D2 ; Mult Chunks by ChunkCount from PRAM = EDisk size
|
||
ADD.L #$7FFF,D2 ; Add an extra 32k to the size
|
||
AND.W #$8000,D2 ; Round down to 32k boundary
|
||
CMPI.L #MinRamDiskSize,D2 ; Is this size too small? (user pulled some SIMMs)
|
||
BLO.S @DMABuffer ; -> Yes, too small. No EDisk
|
||
CMPI.L #MaxRamDiskSize,D2 ; Is it too big? <MC8>
|
||
BHI.S @DMABuffer ; -> Yes, too big. No EDisk
|
||
|
||
MOVE.L LogicalMemorySize(A5),D0 ; Get the logical size (Phys - nk private stuff) <MC8> till next <MC8>
|
||
SUB.L #PDMDMAbufSize,D0 ; Subtract the DAM buffer size from Log RAM size
|
||
TST.L D7 ; Are we going to allocate 614k for a frame buffer?
|
||
BPL.S @CheckMinHeap ; -> Nope,
|
||
SUB.L #604*1024,D0 ; Subtract the frame buffer size if enabled
|
||
@CheckMinHeap
|
||
SUB.L D2,D0 ; Subtract the EDisk size
|
||
CMP.L #MinHeapSize,D0 ; Will we have at least MinHeapSize free after the EDisk?
|
||
BLT.S @DMABuffer ; -> No, do not allocate the EDisk (signed) <MC9>
|
||
|
||
MOVE.L D2,D5 ; Save the number of bytes used by the EDisk in the chunk table. <MC8>
|
||
ADD.L D2,D7 ; Add the size to our running allocation counter
|
||
MOVE.L #bRamDisk,D0 ; Get the EDisk logical base address
|
||
LSR.L D3,D0 ; Turn the address into a page number
|
||
MOVE.L D0,A0 ; Put the logical page number in A0
|
||
|
||
LSR.L D3,D2 ; Turn the size into a page count
|
||
MOVE.L D2,A1 ; Put page count in A1
|
||
|
||
MOVEQ #0,D1 ; Indicate no special alignment necessary
|
||
_nkAllocateMemory ; Get the RAM and map it where we asked
|
||
|
||
; Allocate space for the DMA buffer
|
||
|
||
@DMABuffer MOVE.L #PDMDMAbufSize,D0 ; Get the hard coded DMA buffer size (160k)
|
||
ADD.L D0,D7 ; Add the DMA buffer size to our counter
|
||
LSR.L D3,D0 ; Turn the byte count into a page count
|
||
MOVE.L D0,A1 ; Put page count in A1
|
||
|
||
MOVE.L #PDMDMAlogAddr,D0 ; Get the desired logical address
|
||
LSR.L D3,D0 ; Turn it into a page number
|
||
MOVE.L D0,A0 ; Put the logical page number in A0
|
||
|
||
MOVE.L #(256*1024)-1,D1 ; Align physical address to 256k boundary (AMIC Requirement)
|
||
LSR.L D3,D1 ; Make that a page alignment
|
||
_nkAllocateMemory ; Get the DMA buffer RAM.
|
||
|
||
; Due to a DataPath bug, all byte-assembled buffers need to be marked noncacheable (floppy & serial).
|
||
; Due to an IBM bug, all the rest of the DMA buffers need to be marked noncacheable (marginal parts
|
||
; don't like Global/ARty being asserted).
|
||
|
||
MOVE.L #PDMDMAbufSize,D2 ; Get the number of bytes to mark noncacheable (all of them)
|
||
LSR.L D3,D2 ; Convert that to a page count
|
||
SUBQ #1,D2 ; Make it zero based for DBRA
|
||
|
||
MOVE.L #PDMDMAlogAddr,D0 ; Start of non cacheable range
|
||
LSR.L D3,D0 ; Turn it into a logical page number
|
||
MOVE.L D0,A0 ; Put the page number in A0
|
||
|
||
@NoCacheLup _nkMMUMakePageNonCacheable ; Disable the cache for this page <SM27>
|
||
LEA 1(A0),A0 ; PageNumber++
|
||
DBRA D2,@NoCacheLup ; -> Do this for each page
|
||
|
||
; Allocate RAM for the RAM Based Video (NQD writes *past* the end of the buffer. Get some slop for sloppy...)
|
||
|
||
BCLR.L #31,D7 ; If zero don't allocate the frame buffer
|
||
BEQ.S @Chunky ; -> Do not allocate the frame buffer
|
||
|
||
MOVE.L #604*1024,D2 ; Get 618496 (604k) bytes (max RBV can support w/slop)
|
||
ADD.L D2,D7 ; Add the frame buffer size to our counter
|
||
LSR.L D3,D2 ; Turn the byte count into a page count
|
||
MOVE.L D2,A1 ; Page Count -> A1
|
||
|
||
LSR.L D3,D6 ; Turn the logical video base into page number
|
||
MOVE.L D6,A0 ; Logical Page # -> A0
|
||
MOVEQ #-1,D1 ; Force the allocation to start at phys 0 (HMC Requirement)
|
||
LSR.L D3,D1 ; Make that a page alignment
|
||
_nkAllocateMemory ; Get the RAM and map it where we asked
|
||
|
||
; Make the frame buffer RAM cache mode WriteThrough
|
||
|
||
SUBQ #1,D2 ; Make the RBV page count zero based
|
||
@CacheLupe _nkMakePageWriteThrough
|
||
LEA 1(A0),A0 ; PageNumber++
|
||
DBRA D2,@CacheLupe ; -> Do this for •every• page
|
||
|
||
; Now that RAM has been adjusted by the possible allocation of an EDisk, Video frame buffer
|
||
; and/or DMA buffer, we can construct the RAM chunk table that sits at the top of logical RAM.
|
||
; At this point A5 should be pointing to the nanokernel SystemInfo record.
|
||
|
||
@Chunky MOVE.L UsableMemorySize(A5),D1 ; Get the Useable RAM size from NK
|
||
MOVE.L D1,A5 ; Put the size (our Memtop) in A5
|
||
|
||
; Start from the Top down
|
||
MOVE.L D7,-(A5) ; Put our total allocation at the top of L RAM (Inc edisk). <MC8>
|
||
MOVE.L D5,-(A5) ; Num bytes used by the EDisk <MC8>
|
||
MOVE.L #$68657265,-(A5) ; Old Unused Diag long #3
|
||
MOVE.L #$77617320,-(A5) ; Old Unused Diag long #2
|
||
MOVE.L #$53616D20,-(A5) ; Old Unused Diag long #1
|
||
MOVE.L #-1,-(A5) ; Chunk table terminator
|
||
MOVE.L D1,-(A5) ; Top of usable RAM
|
||
CLR.L -(A5) ; Logical start of RAM
|
||
|
||
MOVE.L A5,A1 ; Put Ptr to chunk table in A1 for MergeDone
|
||
MOVEQ #0,D6 ; Signal no RAM test errors.
|
||
BRA MergeDone ; Set the stack and leave
|
||
|
||
EndWith
|
||
|
||
CheckVidSense
|
||
|
||
MOVE.W #550,D0 ; 550 iterations
|
||
@WaitLupe TST.B vIER(A2) ; Wait ~1.2µs
|
||
DBRA D0,@WaitLupe ; -> Keep looping for ~550µs
|
||
|
||
MOVEQ #0,D3 ; D2 used as senseline scratch.
|
||
MOVE.B SonoraVdSenseRg(A0),D3 ; Read the lines into scratch.
|
||
LSR.B #4,D3 ; Get inputs out of upper nybble.
|
||
|
||
MOVE.W #550,D0 ; 550 iterations
|
||
@WaitLupe2 TST.B vIER(A2) ; Wait ~1.2µs
|
||
DBRA D0,@WaitLupe2 ; -> Keep looping for ~550µs
|
||
RTS6
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: HHEadMerge (emulated system fake stitch and fake chunk table creation) <SM18> Sam
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
; a1 - points to the chunk table
|
||
;
|
||
; Destroys: D0-D3,A0-A2
|
||
;
|
||
; This routine creates a fixed size chunk table at the end of logical RAM. The emulator provides
|
||
; us with the size of logical and physical RAM. The logical size accounts for the RAM stolen by
|
||
; the emu for DMA buffers, video, EDisk, etc. The Physical size is useful only for display at the
|
||
; Finder, etc. Oh, yes, by the time we get run (68k code, that is) the native hardware init has
|
||
; already sized and stitched memory together.
|
||
;
|
||
; The fake table looks like this:
|
||
;
|
||
; 1st bank start addr: $00000000
|
||
; Length (log ram size returned from the emu) 0 < X <= 256mb
|
||
; Chunk table terminator $FFFFFFFF
|
||
; Std diagnostic long #1 $00000000
|
||
; Std diagnostic long #2 $00000000
|
||
; Std diagnostic long #3 $00000000 ; The end of "Physical RAM"
|
||
;
|
||
; Table size: $24 bytes fixed.
|
||
;
|
||
;_____________________________________________________________________________________________
|
||
export HHEADMerge
|
||
|
||
HHEadMerge ; <SM18> Sam
|
||
With NKSystemInfo, ProductInfo, VideoInfo
|
||
|
||
; Read PRAM to see if the user wants an EDisk. If the size is > MinRamDiskSize then ask the <SM21> SAM
|
||
; nanokernel for some RAM.
|
||
|
||
MOVE.L A2,D3 ; Save SizeMem's return address
|
||
|
||
LongBSR6 GetHardwareInfo ; Get universal info again
|
||
MOVE.L DecoderInfo.VIA1Addr(A0),A2 ; Get VIA1's base address for RdXByte
|
||
|
||
LSR.W #8,D2 ; Get the boxflag in the low byte <SM27>
|
||
MOVE.B D2,D7 ; Save it in D7 <SM27>
|
||
|
||
MOVE.W #ramDiskPramAddr,D1 ; Get the EDisk PRAM byte constant
|
||
BSR6 RdXByte ; Read the EDisk size (in % of total RAM) in D1
|
||
MOVE.L D3,A2 ; Restore the return address
|
||
|
||
; Get the MMU page size from the nanokernel. Count bits in the result to get a shift factor
|
||
|
||
MOVEQ #0,D3 ; Clear D3
|
||
MOVE.L ([ProcessorInfoPtr],ProcessorInfo.PageSize),D0 ; Get the Page size from the nano-k
|
||
BFFFO D0{15:15},D3 ; Get the shift factor (Find First One)
|
||
NOT.B D3 ; Flip the order (BF instr start at bit 32 -> )
|
||
ADD.B #32,D3 ; Get the bit number (lsb based)
|
||
|
||
MOVE.L (NKSystemInfoPtr),A5 ; Point to the nanokernel SystemInfo record
|
||
ANDI.L #$FF,D1 ; Clear upper bytes of pram byte
|
||
BEQ.S @Chunky ; -> No EDisk
|
||
|
||
MOVE.L PhysicalMemorySize(A5),D2 ; Get physical RAM size
|
||
LSR.L #8,D2 ; Scale the size by 256k chunks
|
||
MULU.L D1,D2 ; Mult Chunks by ChunkCount from PRAM = EDisk size
|
||
ADD.L #$7FFF,D2 ; Add an extra 32k to the size
|
||
AND.W #$8000,D2 ; Round down to 32k boundary
|
||
CMPI.L #MinRamDiskSize,D2 ; Is this size too small? (user pulled some SIMMs)
|
||
BLO.S @Chunky ; -> Yes, too small. No EDisk
|
||
|
||
MOVE.L #bRamDisk,D0 ; Get the EDisk logical base address
|
||
LSR.L D3,D0 ; Turn the address into a page number
|
||
MOVE.L D0,A0 ; Put the logical page number in A0
|
||
|
||
LSR.L D3,D2 ; Turn the size into a page count
|
||
MOVE.L D2,A1 ; Put page count in A1
|
||
|
||
ADD.W #1,A1 ; (Temp Hack bump up by one to work around nk bug) <SM33>
|
||
;MOVEQ #0,D1 ; Indicate no special alignment necessary
|
||
MOVE.L #16,D1 ; (Temp Hack to get around a nk bug) <SM32>
|
||
_nkAllocateMemory ; Get the RAM and map it where we asked
|
||
|
||
; Now that RAM has been adjusted by the possible allocation of an EDisk, Video frame buffer
|
||
; and/or DMA buffer, we can construct the RAM chunk table that sits at the top of logical RAM.
|
||
; At this point A5 should be pointing to the nanokernel SystemInfo record.
|
||
|
||
@Chunky MOVE.L UsableMemorySize(A5),D1 ; Get the Useable RAM size from NK
|
||
MOVE.L D1,A5 ; Put the size (our Memtop) in A5
|
||
|
||
; Start from the Top down
|
||
LEA -8(A5),A5 ; Leave room for two temp warm start flags <SM31>
|
||
|
||
CLR.L -(A5) ; Old Diag long #3
|
||
CLR.L -(A5) ; Old Diag long #2
|
||
CLR.L -(A5) ; Old Diag long #1
|
||
MOVE.L #-1,-(A5) ; Chunk table terminator
|
||
MOVE.L D1,-(A5) ; Top of usable RAM
|
||
CLR.L -(A5) ; Logical start of RAM
|
||
|
||
MOVE.L A5,A1 ; Put Ptr to chunk table in A1 for MergeDone
|
||
MOVEQ #0,D6 ; Signal no RAM test errors.
|
||
BRA MergeDone ; Set the stack and leave
|
||
|
||
EndWith
|
||
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: GlueMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,d3,a1,a5
|
||
;
|
||
; This routine stitches banks A,B together for the MacII's glue chip decoder. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;_____________________________________________________________________________________________
|
||
GlueMerge ; <9>
|
||
moveq #$0F,d1 ; prepare to mask for size A nibble
|
||
and.b d5,d1 ; get bank A size nibble
|
||
bne.s @sizeBits ; RAM in bank A, leave a1 pointing to bank A start
|
||
addq #8,a1 ; else, advance to bank B's start
|
||
lsr.l #4,d5 ; and move bank B's nibble into lsn
|
||
@sizeBits move.b @VIASizeTable(d1),d0 ; get VIA value
|
||
movea.l VIA2Addr(a0),a5 ; get VIA 2 base
|
||
and.b d0,VBufA(a5) ; stuff in new size bits
|
||
|
||
moveq #(3*4)+(2*8),d1 ; size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
@VIASizeTable
|
||
dc.b $FF ; [0] A size = 0Mb: Start bank B on 64Mb boundary
|
||
dc.b $3F ; [1] A size = 1Mb: Start bank B on 1Mb boundary
|
||
dc.b $FF ; [2] A size = 2Mb: ----
|
||
dc.b $7F ; [3] A size = 4Mb: Start bank B on 4Mb boundary
|
||
dc.b $FF ; [4] A size = 8Mb: ----
|
||
dc.b $BF ; [5] A size =16Mb: Start bank B on 16Mb boundary
|
||
dc.b $FF ; [6] A size =32Mb: ----
|
||
dc.b $FF ; [7] A size =64Mb: Start bank B on 64Mb boundary
|
||
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: MDUMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d3,a1,a5
|
||
;
|
||
; This routine writes the chunk table (containing 1 or 2 entries) at the top of the highest bank,
|
||
; for the Mac IIci's MDU decoder (no stitching possible with this one).
|
||
;_____________________________________________________________________________________________
|
||
MDUMerge ; <9>
|
||
moveq #0,a5 ; no chunk table started yet
|
||
adda.w #16,a1 ; point to end of bank info table
|
||
|
||
@bankLoop tst.b d5 ; any banks left?
|
||
beq MergeDone ; no, exit
|
||
|
||
subq #8,a1 ; point to previous bank
|
||
lsl.l #4,d5 ; yes, shift over next bank
|
||
move.w d5,d1
|
||
lsr.w #8,d1 ; get bank nibble
|
||
andi.b #$0F,d1 ; mask it
|
||
beq.s @bankLoop ; no bank, try next
|
||
|
||
BSR6 expandSize ; convert nibble size (in d1) --> real size (in d0)
|
||
move.l a5,d1 ; already started table?
|
||
bne.s @writeChunk ; yes, then don't write tail
|
||
move.l (a1),a5 ; get base of bank
|
||
adda.l d0,a5 ; point to end of bank
|
||
clr.l -(a5) ; clear test space
|
||
clr.l -(a5) ; clear test space
|
||
move.l #-1,-(a5) ; write FFFFFFFF
|
||
@writeChunk move.l d0,-(a5) ; write size (0nn00000)
|
||
move.l (a1),-(a5) ; write start (0x000000)
|
||
bra.s @bankLoop
|
||
|
||
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: FMCMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d2,a1,a5
|
||
;
|
||
; This routine stitches banks A,B together for the Mac IIfx's FMC decoder. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;_____________________________________________________________________________________________
|
||
FMCMerge ; <9>
|
||
move.w #FMCInit,d1 ; get initial FMC value (assuming no Parity)
|
||
btst.l #RPUExists,d0 ; do we have parity?
|
||
beq.s @cont ; no, we're ok
|
||
move.w #FMCRPUInit,d1
|
||
@cont move.w d1,d0
|
||
|
||
moveq #$0F,d1 ; prepare to mask for size A nibble
|
||
and.b d5,d1 ; get A size nibble
|
||
bne.s @sizeBits ; yes, leave a1 pointing to bank A start
|
||
addq #8,a1 ; else, advance to bank B's start
|
||
lsr.l #4,d5 ; and move bank B's nibble into lsn
|
||
@sizeBits and.b @FMCSizeTable(d1),d0 ; 'or' in FMC size bits
|
||
|
||
movea.l FMCAddr(a0),a5 ; get the FMC base address
|
||
moveq.l #16-1,d1 ; loop counter to load 16 bits <13>
|
||
@FMCload move.b d0,FMCConfig(a5) ; load in a bit
|
||
lsr.w #1,d0 ; put next bit into position
|
||
dbra d1,@FMCload ; repeat till all bits loaded <13>
|
||
st.b FMCLatch(a5) ; latch the config data
|
||
|
||
@writeTable
|
||
moveq #(3*4)+(2*8),d1 ; max size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
@FMCSizeTable
|
||
dc.b $FF ; [0] A size = 0Mb: Start bank B on 64Mb boundary
|
||
dc.b $FF ; [1] A size = 1Mb: ----
|
||
dc.b $FF ; [2] A size = 2Mb: ----
|
||
dc.b $3F ; [3] A size = 4Mb: Start bank B on 4Mb boundary
|
||
dc.b $7F ; [4] A size = 8Mb: Start bank B on 8Mb boundary
|
||
dc.b $BF ; [5] A size =16Mb: Start bank B on 16Mb boundary
|
||
dc.b $FF ; [6] A size =32Mb: ----
|
||
dc.b $FF ; [7] A size =64Mb: Start bank B on 64Mb boundary
|
||
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: OrwellMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks (we only use the lower 4)
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d4,d6,a3,a5
|
||
;
|
||
; This routine stitches banks A,B,C,D together for Eclipse's Orwell decoder. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;_____________________________________________________________________________________________
|
||
WITH ProductInfo
|
||
|
||
OrwellMerge ; <CCH>
|
||
IF forSTP601 THEN ; <SM46>
|
||
WITH NKSystemInfo ; <SM46>
|
||
|
||
; Start <SM48>
|
||
; Read PRAM to see if the user wants an EDisk. If the size is > MinRamDiskSize
|
||
; then ask thenanokernel for some RAM.
|
||
MOVE.L A2,D6 ; Save SizeMem's return address
|
||
|
||
MOVEQ.L #0,D7 ; Memory that might get used for RAM disk
|
||
|
||
LongBSR6 GetHardwareInfo ; Get universal info again
|
||
MOVE.L DecoderInfo.VIA1Addr(A0),A2 ; Get VIA1's base address for RdXByte
|
||
|
||
MOVE.W #ramDiskPramAddr,D1 ; Get the EDisk PRAM byte constant
|
||
BSR6 RdXByte ; Read the EDisk size (in % of total RAM) in D1
|
||
MOVE.L D6,A2 ; Restore the return address>
|
||
|
||
; Get the MMU page size from the nanokernel.Count bits in the result to get a shift factor
|
||
|
||
MOVEQ #0,D3 ; Clear D3
|
||
MOVE.L ([ProcessorInfoPtr],ProcessorInfo.PageSize),D0 ; Get the Page size from the nano-k
|
||
BFFFO D0{15:15},D3 ; Get the shift factor (Find First One)
|
||
NOT.B D3 ; Flip the order (BF instr start at bit 32 -> )
|
||
ADD.B #32,D3 ; Get the bit number (lsb based)
|
||
|
||
MOVEQ #0,D5 ; Clear the EDisk allocation size
|
||
MOVE.L (NKSystemInfoPtr),A5 ; Point to the nanokernel SystemInfo record
|
||
ANDI.L #$FF,D1 ; Clear upper bytes of pram byte
|
||
BEQ.S @AfterRAMDiskCheck ; -> No EDisk
|
||
|
||
MOVE.L PhysicalMemorySize(A5),D2 ; Get physical RAM size
|
||
LSR.L #8,D2 ; Scale the size by 256k chunks
|
||
MULU.L D1,D2 ; Mult Chunks by ChunkCount from PRAM = EDisk size
|
||
ADD.L #$7FFF,D2 ; Add an extra 32k to the size
|
||
AND.W #$8000,D2 ; Round down to 32k boundary
|
||
CMPI.L #MinRamDiskSize,D2 ; Is this size too small? (user pulled some SIMMs)
|
||
BLO.S @AfterRAMDiskCheck ; -> Yes, too small. No EDisk
|
||
CMPI.L #MaxRamDiskSize,D2 ; Is it too big?>
|
||
BHI.S @AfterRAMDiskCheck ; -> Yes, too big. No EDisk
|
||
|
||
MOVE.L LogicalMemorySize(A5),D0 ; Get the logical size (Phys - nk private stuff)
|
||
|
||
@CheckMinHeap
|
||
SUB.L D2,D0 ; Subtract the EDisk size
|
||
CMP.L #MinHeapSize,D0 ; Will we have at least MinHeapSize free after the EDisk?
|
||
BLT.S @AfterRAMDiskCheck ; -> No, do not allocate the EDisk (signed)
|
||
|
||
MOVE.L D2,D5 ; Save the number of bytes used by the EDisk in the chunk table.
|
||
ADD.L D2,D7 ; Add the size to our running allocation counter
|
||
MOVE.L #bRamDisk,D0 ; Get the EDisk logical base address
|
||
LSR.L D3,D0 ; Turn the address into a page number
|
||
MOVE.L D0,A0 ; Put the logical page number in A0
|
||
|
||
LSR.L D3,D2 ; Turn the size into a page count
|
||
MOVE.L D2,A1 ; Put page count in A1
|
||
|
||
MOVEQ #0,D1 ; Indicate no special alignment necessary
|
||
_nkAllocateMemory ; Get the RAM and map it where we asked
|
||
|
||
@AfterRAMDiskCheck
|
||
; End <SM48>
|
||
|
||
MOVE.L (NKSystemInfoPtr),A5 ; Point to the nanokernel SystemInfo record <SM46>
|
||
MOVE.L UsableMemorySize(A5),D1 ; Get the Useable RAM size from NK <SM46>
|
||
MOVE.L D1,A5 ; Put the size (our Memtop) in A5 <SM46>
|
||
|
||
; Start from the Top down <SM46>
|
||
MOVE.L D7,-(A5) ; Put total allocation at the top of L RAM. <SM46>
|
||
MOVE.L #$52555348,-(A5) ; Old Unused Diag long #3 <SM46>
|
||
MOVE.L #$6E757320,-(A5) ; Old Unused Diag long #2 <SM46>
|
||
MOVE.L #$4379676E,-(A5) ; Old Unused Diag long #1 <SM46>
|
||
MOVE.L #-1,-(A5) ; Chunk table terminator <SM46>
|
||
MOVE.L D1,-(A5) ; Top of usable RAM <SM46>
|
||
CLR.L -(A5) ; Logical start of RAM <SM46>
|
||
|
||
MOVE.L A5,A1 ; Put Ptr to chunk table in A1 for MergeDone<SM46>
|
||
MOVEQ #0,D6 ; Signal no RAM test errors. <SM46>
|
||
BRA MergeDone ; Set the stack and leave <SM46>
|
||
ENDWITH ; <SM46>
|
||
ENDIF ; <SM46>
|
||
|
||
IF forSmurf THEN
|
||
bra HMCMerge ; >>SKIP this <SM5> <SM20>
|
||
ENDIF
|
||
|
||
move.w d5,d1 ; get a copy of the size for 4 banks
|
||
swap d5 ; put a copy in msw of d5
|
||
move.w d1,d5 ; and put a copy in the lsw of d5 too
|
||
move.l a1,d6 ; save productinfo ptr for later
|
||
movea.l #0,a3 ; clear memory counter
|
||
move.l #0,d3 ; start with bank 0 (bank A)
|
||
bra.s @bankMapped ; no need to map bank A
|
||
;
|
||
; This code maps the current bank to begin immediately after the previous bank.
|
||
; It loads Orwell's bank configuration registers, but does not latch them in.
|
||
;
|
||
; a3.l - offset to map current bank at
|
||
; d3.l - bank which we are currently mapping
|
||
;
|
||
@mergeLoop ; LOOP
|
||
move.l d3,d1 ; get current bank number
|
||
subq.l #1,d1 ; adjust so Bank 1 has zero offset
|
||
mulu.l #OrBankFieldSize,d1 ; get bit position in register for this bank
|
||
move.l DecoderAddr(a0),a5 ; get base addr of Orwell <SM7>
|
||
lea (OrBankBCfgAddr,a5,d1.w*4),a5 ; get base address of bank field for this bank
|
||
move.l a3,d1 ; get addr to map this bank to
|
||
move.l #22,d4 ; bits to shift to get Orwell config value
|
||
lsr.l d4,d1 ; d1 contains config value for this bank
|
||
move.w #OrBankFieldSize-1,d4 ; size of field to load
|
||
@loadCfgReg move.l d1,(a5)+ ; load a bit
|
||
lsr.l #1,d1 ; get next bit into position
|
||
dbra d4,@loadCfgReg ; continue until entire field is loaded
|
||
;
|
||
; Latch the value we just put into Orwell in.
|
||
;
|
||
movea.l DecoderAddr(a0),a5 ; get base address of Orwell <SM7>
|
||
lea OrLoadBanks(a5),a5 ; get address of latch location
|
||
move.b #$ff,(a5) ; latch bank config values in <14>
|
||
;
|
||
; Increment offset to map next bank to and point to next chunk. Continue loop if not finished.
|
||
;
|
||
@bankMapped
|
||
move.l #$0F,d1 ; mask for size nibble of current bank
|
||
and.b d5,d1 ; get size nibble for current bank
|
||
lsr.l #4,d5 ; shift size of next bank into low nibble <14>
|
||
BSR6 expandSize ; nibble size (in d1) --> real size (in d0)
|
||
adda.l d0,a3 ; calc total amount of memory so far
|
||
@contLoop
|
||
tst.l 8(a1) ; are we at the last bank?
|
||
bmi.s @mergeDone ; >>EXITLOOP if so
|
||
adda.l #8,a1 ; bump chunk pointer to next entry
|
||
addq.l #1,d3 ; bump bank number
|
||
bra.s @mergeLoop ; ENDLOOP
|
||
;
|
||
; Write chunk table at the end of RAM. After merging, RAM looks like one big chunk starting at zero.
|
||
;
|
||
@mergeDone
|
||
move.l a3,d3 ; get a copy of total amount of memory <14>
|
||
move.l d6,a1 ; restore productinfo ptr <14>
|
||
@endMerge moveq #(3*4)+(4*8),d1 ; size of chunk table for this decoder <14>
|
||
|
||
bra writeChunkTable ; and exit <14>
|
||
|
||
ENDWITH
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: SonoraMerge <SAM>
|
||
;
|
||
; Inputs: D0 - bases valid bits
|
||
; D2 - chunk size for this decoder
|
||
; D3 - total size of RAM in system
|
||
; D5 - nibble sizes for up to 8 banks
|
||
; A0 - ptr to table of base addresses
|
||
; A1 - ptr to universal RAMInfo table (first entry)
|
||
; A2 - SizeMem return address
|
||
;
|
||
; Outputs: A5 - points to the chunk table
|
||
;
|
||
; Destroys: D0-D4,D6,A3,A5
|
||
;
|
||
; This routine stitches banks A,B,C,D and E together and sets the SIMM size
|
||
; bits for the two SIMM sockets for the Sonora decoder.
|
||
; It then writes the chunk table at the top of RAM.
|
||
;__________________
|
||
;
|
||
; Weirdness Notes:
|
||
;
|
||
; Supports two SIMMs. Each with at most two banks of RAM.
|
||
;
|
||
; Carnation/Vail machines that have any RAM in bank 0/A (built-in) must have the "Bank0Size" bit
|
||
; in the RAM Config register set to 1.
|
||
;
|
||
; Assumptions:
|
||
; If there is no RAM in the first bank of each SIMM, then the other bank is assumed empty as well.
|
||
; If RAM is found in the second bank of a SIMM it is assumed to be the same size as
|
||
; the first bank.
|
||
;
|
||
;_____________________________________________________________________________________________
|
||
|
||
RAMCfgBank0Size EQU 6 ; Sonora RAMConfig Bank0Size Bit. 1=Onboard RAM for Carnation
|
||
|
||
SonoraMerge MOVE.L D2,A5 ; Save D2 for later <H6><SM12>
|
||
MOVEQ #1,D4 ; SIMM loop counter <H4><SM12>
|
||
MOVEQ #(1<<RAMCfgBank0Size),D6 ; Assume RAM in bank 0.
|
||
|
||
MOVE.L D5,D1 ; Get a copy of the Nibble/Bank count
|
||
AND.B #$0F,D0 ; Get Bank A's nibble count
|
||
BNE.S @noBank0 ; -> No RAM in bank 0/A
|
||
|
||
BCLR.L #RAMCfgBank0Size,D6 ; If no RAM in bank 0 clear the Bank0Size Bit
|
||
@noBank0
|
||
LSR.L #4,D1 ; Look at next bank
|
||
|
||
@SIMMLupe MOVE.B D1,D0 ; Copy two nibbles
|
||
AND.B #$0F,D0 ; Strip the upper nibble
|
||
BEQ.S @noRAMBank1 ; -> branch if no RAM in the first bank of this SIMM
|
||
|
||
MOVE.B D1,D2 ; Copy two nibbles
|
||
AND.B #$F0,D2 ; Strip the lower nibble
|
||
BEQ.S @NoRAMbank2 ; -> No RAM in the second bank of this SIMM
|
||
|
||
ADDQ #1,D0 ; Both banks filled. Assume both same size. Bump the SIMM size
|
||
@noRAMbank2 OR.B D0,D6 ; Put this SIMM size in the Cfg reg
|
||
|
||
@noRAMbank1 ROR.B #3,D6 ; Rotate the Cfg reg to prep for setting SIMM1 size
|
||
LSR.L #4*2,D1 ; Shift the Bank sizes reg two banks right
|
||
DBRA D4,@SIMMLupe ; Do this twice (once for each SIMM)
|
||
ROR.B #2,D6 ; Put the config reg back where it belongs
|
||
|
||
@Done MOVE.L A5,D2 ; restore D2 <H6><SM12>
|
||
MOVE.L RBVAddr(A0),A5 ; Get RBV (Sonora's VIA2) Base Addr <H2><SM12>
|
||
MOVE.B SonoraRAMSize(A5),D0 ; Get the Cfg Reg
|
||
AND.B #$80,D0 ; Mask out all but the HiBit (Slot16MHz)
|
||
OR.B D0,D6 ; Put the Slot16MHz into our SIMM size and Bank0Size byte
|
||
MOVE.B D6,SonoraRAMSize(A5) ; Set the SIMM size & Stich the banks together (magic)
|
||
|
||
MOVEQ #(3*4)+(5*8),D1 ; size of chunk table for this decoder (3 longs + 5 banks)
|
||
BRA writeChunkTable ; write chunk table and exit...
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: YMCAMerge <SM9> fau, start
|
||
;
|
||
; Inputs: D0 - bases valid bits
|
||
; D2 - chunk size for this decoder
|
||
; D3 - total size of RAM in system
|
||
; D5 - nibble sizes for up to 8 banks
|
||
; A0 - ptr to table of base addresses
|
||
; A1 - ptr to universal RAMInfo table (first entry)
|
||
; A2 - SizeMem return address
|
||
;
|
||
; Outputs: A5 - points to the chunk table
|
||
;
|
||
; Destroys: D0-D4,D6,A3,A5
|
||
;
|
||
; This routine stitches banks 0 through 7 and sets the SIMM size
|
||
; bits for the eight banks for the YMCA decoder.
|
||
; It then writes the chunk table at the top of RAM.
|
||
;
|
||
;__________________
|
||
;
|
||
; Weirdness Notes:
|
||
; TBD
|
||
;_____________________________________________________________________________________________
|
||
|
||
YMCAMerge
|
||
Move.w #YMCAMaxSize,d6 ; Max bank size supported by the YMCA in 2^(n-1)* chunksize
|
||
movea.l #0,a3 ; clear memory counter
|
||
Move.l DecoderAddr(A0),A5 ; Get YMCA's Base address <SM11>
|
||
Move.l d5,YMCA_DRAMBank0_A20(a5) ; get the base address for the first bank's A20 register
|
||
|
||
|
||
; d6.w will loop through the supported sizes,from largest to smallest
|
||
; d4.w will have the bank the size is in
|
||
|
||
@NextSize ; LOOP (thru memory sizes)
|
||
Move.l d5,d3 ; Get a running copy of the nibble sizes
|
||
rol.l #4,d3 ; adjust it for the 1st time thru nibble loop
|
||
Moveq #0,d4 ; Counter to loop through 8 nibbles
|
||
Move.l DecoderAddr(A0),A5 ; Get YMCA's Base address <SM11>
|
||
Lea YMCA_DRAMBank0_A20(a5),a5 ; get the base address for the first bank's A20 register
|
||
|
||
@NextNibble ; LOOP (thru banks)
|
||
ror.l #4,d3 ; Get the nibble
|
||
move.w d3,d1 ; we will trash d1
|
||
Andi.w #$000f,d1 ; We only want the lowest nibble
|
||
Cmp.w d6,d1 ; Is this the size we're looking for
|
||
Bne.s @NoSzMatch ; nope
|
||
Swap d4 ; save our counter and use the other word for the shift count & size counter
|
||
Move.w #20,d4 ; # of bits to shift the address to get at the bit we need to program
|
||
Move.l A3,D0 ; get the current amount of memory
|
||
lsr.l d4,D0 ; the boundary reg's consist of A20 thru A26
|
||
Move.w #BankBdryRegSize-1,d4 ; size of boundary address register
|
||
|
||
@loadBdry Ror.l #1,d0 ; Move bit 0 to bit 31
|
||
move.l d0,(a5)+ ; and write it out
|
||
dbra d4,@loadBdry ; continue for all bits
|
||
Move.w #BankSizeRegSize-1,d4 ; size of memory bank
|
||
Move.w d1,d0 ; Get a copy of nibble size in the msw of d1
|
||
Swap d1 ; expand size will trash d1
|
||
Move.w d0,d1 ; both words of d1 contain the nibble size
|
||
BSR6 expandSize ; nibble size (in d1) --> real size (in d0)
|
||
adda.l d0,a3 ; calc total amount of memory so far
|
||
swap d1 ; get d1.w with the nibble size
|
||
|
||
@loadSize Ror.l #1,d1 ; d1 = nibble size = bank size
|
||
move.l d1,(a5)+ ; and write it out
|
||
dbra d4,@loadSize ; continue for all bits
|
||
Swap D4 ; return our bank counter
|
||
bra.s @NextBank ; go look at the next bank
|
||
@NoSzMatch
|
||
Adda.l #40,a5 ; if we didn't match get the base address of the next bank
|
||
@NextBank
|
||
Addq.w #1,d4 ; increment our counter
|
||
Cmpi.w #8,d4 ; Did we loop through the 8 nibbles yet
|
||
bne.s @NextNibble ; ENDLOOP (through banks)
|
||
Dbra d6,@NextSize ; ENDLOOP (through memory sizes)
|
||
|
||
move.l a3,d3 ; get a copy of total amount of memory <14>
|
||
|
||
@Done MOVEQ #(3*4)+(8*8),D1 ; size of chunk table for this decoder (3 longs + 8 banks)
|
||
BRA writeChunkTable ; write chunk table and exit...
|
||
|
||
; <SM9> fau, end
|
||
ALIGN 4
|
||
|
||
; <SM11> fau, start
|
||
YMCAWidthOffsets
|
||
; This table lists the offsets to the YMCA Width base address from the Base Address of the Width Register.
|
||
; It is indexed by bank and provides the offset from YMCA_DRAMwidth0
|
||
|
||
dc.w $0 ; Bank 0's offset
|
||
dc.w $4 ; Bank 1's offset
|
||
dc.w $0 ; Bank 2's offset
|
||
dc.w $4 ; Bank 3's offset
|
||
dc.w $8 ; Bank 4's offset
|
||
dc.w $c ; Bank 5's offset
|
||
dc.w $8 ; Bank 6's offset
|
||
dc.w $c ; Bank 7's offset
|
||
|
||
; <SM11> fau, end
|
||
;_____________________________________________________________________________________________
|
||
; Routine: VISAMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,a5
|
||
;
|
||
; This routine stitches banks A,B together for Elsie's VISA decoder. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;
|
||
; Rewritten 5/12/92 (<H4>) to work with LC and LCII. This routine now assumes that the <SM4> rb, start
|
||
; @VISASplit code has set the size bits correctly for bank B. All we have to do here
|
||
; is set the size bits for bank A only. Couldn't use old routine because on LC II its
|
||
; possible to have the same total RAM configuration but different size bit settings
|
||
; (i.e. 6MB total = 2 MB on PCB + 2-2 MB SIMMs in bank A OR 4 MB on PCB and 2-1 MB SIMMs).
|
||
;_____________________________________________________________________________________________
|
||
VISAMerge ; <9>
|
||
move.b d5,d1 ; <H5><Begin>
|
||
and.w #$000F,d1 ; get Bank A size nibble
|
||
move.b (@VISASizeTable,d1.w),d1 ; use size as index into table for "real" size
|
||
movea.l RBVAddr(a0),a5 ; get size bits
|
||
and.b #%00111111,VsExp(a5) ; zero out bank A size
|
||
or.b d1,VsExp(a5) ; OR in bank A size we just got from table
|
||
|
||
btst #5,VsExp(a5) ; test size bits to see if 2/4mb in bank B
|
||
bne.s @done ; if 4mb then we need to change RAM info tables
|
||
adda.l #RAMInfoSize+4,a1 ; set a1 to 4mb RAM info table
|
||
|
||
@done
|
||
moveq #(3*4)+(2*8),d1 ; size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
@VISASizeTable
|
||
dc.b $00 ; [0] A size = 0MB
|
||
dc.b -1 ; [1] A size = 1MB illegal
|
||
dc.b $40 ; [2] A size = 2MB
|
||
dc.b $80 ; [3] A size = 4MB
|
||
dc.b $C0 ; [4] A size = 8MB <H5><End><SM4> rb, end
|
||
|
||
ALIGN
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: JAWSMerge/NiagraMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,d4,a5
|
||
;
|
||
; This routine stitches banks A-B-C-D,E-F-G-H together for Waimea's JAWS decoder. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;_____________________________________________________________________________________________
|
||
NiagraMerge
|
||
JAWSMerge ; <9>
|
||
moveq #0,d4 ; init card size reg
|
||
|
||
moveq #3,d1 ; get our special-case value (2 Meg, 1 chunk) <4>
|
||
cmp.l d1,d5 ; does bank A have it (with bank B=0)? <4>
|
||
bne.s @checkSpec2 ; no, see if bank B is special (with bank A=0) <4>
|
||
moveq #0,d4 ; B-A = 0-2 meg, use the 0 table entry <4>
|
||
bra.s @getTable ; <4>
|
||
|
||
@checkSpec2 swap d1 ; now check bank B for 2 Meg in lowest chunk <4>
|
||
cmp.l d1,d5 ; with bank A=0 <4>
|
||
bne.s @notSpec ; no, use standard lookup <4>
|
||
moveq #$20,d4 ; yes, use B-A = 4-0 meg table entry <4>
|
||
bra.s @getTable ; <4>
|
||
|
||
@notSpec BSR6 @calcSize ; calc bank B size
|
||
BSR6 @calcSize ; calc bank A size
|
||
|
||
moveq #16-3,d0 ; prepare to shift bank A size code into high 3 bits
|
||
lsl.w d0,d4 ; 00000000 00000bbb aaa00000 00000000
|
||
lsr.l d0,d4 ; 00000000 00000000 00000000 00bbbaaa
|
||
@getTable move.b @JAWSSizeTable(d4.w),d0 ; get JAWS size config value
|
||
|
||
movea.l JAWSAddr(a0),a5 ; get ptr to JAWS base
|
||
adda.l #JAWSMemConfigA,a5
|
||
move.b d0,(a5) ; set size reg A
|
||
|
||
lsr.b #2,d0 ; move in next 2 bits
|
||
adda.w #JAWSMemConfigB-JAWSMemConfigA,a5
|
||
move.b d0,(a5) ; set size reg B
|
||
|
||
lsr.b #2,d0 ; move in last 2 bits
|
||
adda.w #JAWSMemConfigC-JAWSMemConfigB,a5
|
||
move.b d0,(a5) ; set size reg C
|
||
|
||
moveq #(3*4)+(8*8),d1 ; size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
;............................................................................................
|
||
|
||
@calcSize movea.l a6,a5 ; keep return address in a5
|
||
moveq #4-1,d1 ; count 4 banks
|
||
@nextNib swap d1 ; keep count in d1.hw
|
||
move.w #$0F,d1
|
||
rol.l #4,d5 ;
|
||
and.b d5,d1 ; get next size nibble
|
||
BSR6 expandSize ; nibble size (in d1) --> real size (in d0)
|
||
add.l d0,d4 ; add to total for this bank
|
||
swap d1 ; get count back
|
||
dbra d1,@nextNib
|
||
|
||
swap d4 ; 000x00n0
|
||
lsr.w #4,d4 ; 000x000n
|
||
|
||
cmpi.b #8,d4 ; was it 8?
|
||
bne.s @done ; no, then we're done
|
||
subq.b #1,d4 ; yes, make it a 7.
|
||
@done jmp (a5) ; and exit
|
||
|
||
|
||
@JAWSSizeTable
|
||
dc.b %00000 ;[000 000] B:0, A:0
|
||
dc.b %00001 ;[000 001] B:0, A:1
|
||
dc.b %00001 ;[000 010] B:0, A:2
|
||
dc.b %00010 ;[000 011] B:0, A:3
|
||
dc.b %00000 ;[000 100] B:0, A:4
|
||
dc.b %00000 ;[000 101] --------
|
||
dc.b %00000 ;[000 110] B:0, A:6
|
||
dc.b %00000 ;[000 111] B:0, A:8
|
||
|
||
dc.b %11111 ;[001 000] B:1, A:0
|
||
dc.b %10011 ;[001 001] B:1, A:1
|
||
dc.b %00011 ;[001 010] B:1, A:2
|
||
dc.b %01010 ;[001 011] B:1, A:3
|
||
dc.b %01001 ;[001 100] B:1, A:4
|
||
dc.b %00000 ;[001 101] --------
|
||
dc.b %00110 ;[001 110] B:1, A:6
|
||
dc.b %01000 ;[001 111] B:1, A:8
|
||
|
||
dc.b %11111 ;[010 000] B:2, A:0
|
||
dc.b %00111 ;[010 001] B:2, A:1
|
||
dc.b %00011 ;[010 010] B:2, A:2
|
||
dc.b %10010 ;[010 011] B:2, A:3
|
||
dc.b %01001 ;[010 100] B:2, A:4
|
||
dc.b %00000 ;[010 101] --------
|
||
dc.b %00110 ;[010 110] B:2, A:6
|
||
dc.b %01000 ;[010 111] B:2, A:8
|
||
|
||
dc.b %11101 ;[011 000] B:3, A:0
|
||
dc.b %00100 ;[011 001] B:3, A:1
|
||
dc.b %00100 ;[011 010] B:3, A:2
|
||
dc.b %11001 ;[011 011] B:3, A:3
|
||
dc.b %10001 ;[011 100] B:3, A:4
|
||
dc.b %00000 ;[011 101] --------
|
||
dc.b %01110 ;[011 110] B:3, A:6
|
||
dc.b %11000 ;[011 111] B:3, A:8
|
||
|
||
dc.b %10111 ;[100 000] B:4, A:0
|
||
dc.b %01001 ;[100 001] B:4, A:1
|
||
dc.b %00101 ;[100 010] B:4, A:2
|
||
dc.b %01111 ;[100 011] B:4, A:3
|
||
dc.b %11011 ;[100 100] B:4, A:4
|
||
dc.b %00000 ;[100 101] --------
|
||
dc.b %10110 ;[100 110] B:4, A:6
|
||
dc.b %00000 ;[100 111] B:4, A:8
|
||
|
||
dc.b %00000 ;[101 000] --------
|
||
dc.b %00000 ;[101 001] --------
|
||
dc.b %00000 ;[101 010] --------
|
||
dc.b %00000 ;[101 011] --------
|
||
dc.b %00000 ;[101 100] --------
|
||
dc.b %00000 ;[101 101] --------
|
||
dc.b %00000 ;[101 110] --------
|
||
dc.b %00000 ;[101 111] --------
|
||
|
||
dc.b %10111 ;[110 000] B:6, A:0
|
||
dc.b %01011 ;[110 001] B:6, A:1
|
||
dc.b %01011 ;[110 010] B:6, A:2
|
||
dc.b %01100 ;[110 011] B:6, A:3
|
||
dc.b %10100 ;[110 100] B:6, A:4
|
||
dc.b %00000 ;[110 101] --------
|
||
dc.b %11010 ;[110 110] B:6, A:6
|
||
dc.b %00000 ;[110 111] B:6, A:8
|
||
|
||
dc.b %10111 ;[111 000] B:8, A:0
|
||
dc.b %01101 ;[111 001] B:8, A:1
|
||
dc.b %01101 ;[111 010] B:8, A:2
|
||
dc.b %10101 ;[111 011] B:8, A:3
|
||
dc.b %10111 ;[111 100] B:8, A:4
|
||
dc.b %00000 ;[111 101] --------
|
||
dc.b %10111 ;[111 110] B:8, A:6
|
||
dc.b %00000 ;[111 111] B:8, A:8
|
||
|
||
|
||
|
||
; <22> rb, from Terror for DBLite
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: MSCMerge
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,a5
|
||
;
|
||
; This routine stitches banks A-H together for DB-Lite's MSC controller. It then writes
|
||
; the chunk table at the top of RAM. RAM banks 4-7 can either contain 2MB or 8MB of RAM.
|
||
; If bank 4 doesn't have 8MB of RAM, we'll assume the rest don't and clear the MSCBank8M
|
||
; bit in the MSC configuration register.
|
||
;
|
||
; Bank A is always 2MB
|
||
; Bank B is always 2MB
|
||
; Bank C can be 0 or 2
|
||
; Bank D can be 0 or 2
|
||
; Bank E can be 0 or 2 or 8
|
||
; Bank F can be 0 or 2 or 8
|
||
; Bank G can be 0 or 2 or 8
|
||
; Bank H can be 0 or 2 or 8
|
||
;_____________________________________________________________________________________________
|
||
|
||
MSCMerge ; <T7>
|
||
bfffo d5{0:31},d1 ; find the highest bit (bank) set <H5><SM12>
|
||
neg.b d1 ; <H5><SM12>
|
||
add.b #32,d1 ; <H5><SM12>
|
||
asl.b #MSCSize0-2,d1 ; / bank size = highest bank # (upper 3 bits) <H5><SM12>
|
||
ori.b #(1<<MSC25MHz)|(1<<MSCEconoBit)|(1<<MSCFastROM)|(1<<3)|(1<<MSCBank8M),d1 ; <H5><SM12>
|
||
|
||
moveq #$0F,d0 ; find out how much in bank 4 <H5><SM12>
|
||
swap d0 ; <H5><SM12>
|
||
and.l d5,d0 ; <H5><SM12>
|
||
swap d0 ; nibble size in low byte <H5><SM12>
|
||
subq.b #$03,d0 ; check for 8 MB <H5><SM12>
|
||
beq.s @TwoMegBanks ; <H5><SM12>
|
||
bclr #MSCBank8M,d1 ; not 8 MB, clear our Bank8M enable <H5><SM12>
|
||
@TwoMegBanks
|
||
movea.l RBVAddr(a0),a5 ; get ptr to MSC (same as RBV's) <H3>
|
||
and.b d1,MSCConfig(a5) ; set MSC size bits <H2><H5><SM12>
|
||
|
||
@done moveq #(3*4)+(8*8),d1 ; size of chunk table for this decoder <H14><SM12>
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: PrattMerge <SM15>
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,d4,a5
|
||
;
|
||
; This routine stitches banks A-F together for the Pratt controller. It then writes
|
||
; the chunk table at the top of RAM.
|
||
;
|
||
; Onboard RAM:
|
||
; Bank A can be 0,2,4,or 8MB
|
||
; Bank B can be 0,2,4,or 8MB
|
||
; If 2MB banks, then there must be two banks, for a total of 4MB
|
||
; If 4MB banks, then one or two banks allowed, for either 4MB or 8MB
|
||
; If 8MB bank, then one or two banks allowed, for either 8MB or 16MB
|
||
;
|
||
; Expansion RAM:
|
||
; Banks C,D,E,F can have 0,2,4,or 8MB.
|
||
; All expansion banks with RAM in them must be the same size. Banks must be loaded in order.
|
||
;
|
||
;_____________________________________________________________________________________________
|
||
PrattMerge ;
|
||
|
||
; find out which banks have memory
|
||
; input: d5.l -- each non-zero nibble means corresponding bank has memory
|
||
; output: d4.b -- each non-zero bit means corresponding bank has memory, bits 0-5
|
||
;
|
||
movea.l d5,a5 ; save a copy of nibble sizes
|
||
moveq #0,d0 ; initialize count
|
||
move.b #PrattBankBits,d4 ; load initial mask for RAM Configuration Register (in Pratt)
|
||
@bankloop move.b d5,d1 ; get copy of nibble sizes
|
||
andi.b #$0F,d1 ; look at low nibble
|
||
bne.s @next ; nibble non-zero -> memory in bank, so leave bit set
|
||
bclr d0,d4 ; no memory in this bank, so clear bit
|
||
@next lsr.l #4,d5 ; look at next nibble
|
||
addq #1,d0 ; inc nibble count
|
||
cmpi.b #PrattNumbanks-1,d0 ; have we looked at all the banks?
|
||
ble.s @bankloop
|
||
move.l a5,d5 ; restore copy of nibble sizes
|
||
|
||
; figure out the onboard configuration (Banks A and B)
|
||
; output: d1 has the onboard memory bank bit configuration bits configured
|
||
;
|
||
move.b #PrattDensBits,d1 ; load initial mask for RAM Density Register (in Pratt)
|
||
move.l d5,d0 ; get copy of nibble sizes
|
||
andi.l #$0000000F,d0 ; find out how much in bank 0
|
||
bne.s @check2 ; more than 0 MB, go check for 2
|
||
andi.b #Pratt0MBbank,d1 ; there is no RAM on the daughter card
|
||
bra.s @getExpMem
|
||
@check2 cmpi.l #1,d0 ; check for 2 MB (nibble size = 1 for 2MB chunksize)
|
||
bne.s @check4 ; more than 2MB, go check for 4
|
||
andi.b #Pratt2MBbank,d1 ; there are 2MB
|
||
bra.s @getExpMem ;
|
||
@check4 cmpi.l #2,d0 ; check for 4MB (nibble size = 2 for 2MB chunksize)
|
||
bne.s @set8 ; more than 4MB, must be 8
|
||
andi.b #Pratt4MBbank,d1 ; there are 4 MB
|
||
bra.s @getExpMem
|
||
@set8 andi.b #Pratt8MBbank,d1 ; set 8 MB bank size
|
||
|
||
; find out size of expansion memory banks
|
||
; output: d1 has the expansion memory bank size bit configured
|
||
;
|
||
@getExpMem move.l #$00000F00,d0 ; find out how much in bank C (D,E,F must be the same size)
|
||
and.l d5,d0 ; the formula is (2^(n-1) * 2) MB where "n" is the nibble value
|
||
bne.s @check2e
|
||
andi.b #Pratt0MBExBank,d1
|
||
bra.s @writeConfigRegs
|
||
@check2e cmpi.l #$00000100,d0 ; check for 2 MB (nibble size = 1)
|
||
bne.s @check4e
|
||
andi.b #Pratt2MBExBank,d1
|
||
bra.s @writeConfigRegs
|
||
@check4e cmpi.l #$00000200,d0 ; check for 4 MB (nibble size = 2)
|
||
bne.s @set8e
|
||
andi.b #Pratt4MBExBank,d1
|
||
bra.s @writeConfigRegs
|
||
@set8e andi.b #Pratt8MBExBank,d1 ; set config for 8MB banks on the expansion card
|
||
|
||
@writeConfigRegs
|
||
movea.l PrattAddr(a0),a5 ; get ptr to Pratt <SM16>
|
||
IF forRomulator THEN
|
||
TestInRAM a0 ; are we in RAM?
|
||
bne.s @done ; yes, then don't really muck with RAM Config registers
|
||
ENDIF
|
||
move.b d1,PrattRAMDensity(a5) ; set Pratt RAM density register value
|
||
move.b d4,PrattRAMConfig(a5) ; set Pratt RAM config register value
|
||
bset.b #0,PrattRefresh(a5) ; set Pratt Refresh rate to be generated every 33 clocks.
|
||
|
||
@done moveq #(3*4)+(6*8),d1 ; size of chunk table for this decoder
|
||
bra writeChunkTable ; write chunk table and exit...
|
||
|
||
|
||
;_____________________________________________________________________________________________ <H7> thru next <H7>
|
||
; Routine: djMEMCMerge <SM12>begin
|
||
;
|
||
; Inputs: d0 - bases valid bits
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks (Banks 0 thru 7)
|
||
; d6 - nibble sizes for an additional 8 banks (Banks 8 thru 15)
|
||
; a0 - ptr to table of base addresses
|
||
; a1 - ptr to universal RAMInfo table (first entry)
|
||
; a2 - SizeMem return address
|
||
;
|
||
; Outputs: a5 - points to the chunk table
|
||
;
|
||
; Destroys: d0-d1,a5
|
||
;
|
||
; NOTE: If you made it here, then D6 should be zero (no errors encountered during SizeBanks). <H8>
|
||
; If that's true, then if D6 EXITS this code also being zero, then we should be able <H8>
|
||
; to abuse it during this part of the code. <H8>
|
||
;_____________________________________________________________________________________________
|
||
|
||
WITH ProductInfo
|
||
|
||
djMEMCMerge
|
||
IF forSmurf THEN
|
||
bra HMCMerge ; >>SKIP this <SM5> <SM20>
|
||
ENDIF
|
||
|
||
LEA MEMCAddr+MEMCDRAMCfg0,A0 ; Point A0 to the first bank's Cfg reg
|
||
|
||
MOVEQ #0,D0
|
||
SUBA.L A3,A3 ; A3 = 0
|
||
MOVEQ #dj_MaxBanks-1,D1 ; # of banks minus 1 <H8>
|
||
|
||
@Loop MOVE.L A3,D4 ; Get running size in D4
|
||
SWAP D4 ; Poor man's BFEXTU D4{22:8},D4
|
||
LSR.W #6,D4
|
||
|
||
MOVE.L (A0),D0
|
||
MOVE.B D4,D0 ; Move bits 22-29 of addrs into bits 7-0 of cfg reg
|
||
MOVE.L D0,(A0)+
|
||
|
||
MOVEQ #$0F,D4 ; Nibble mask
|
||
CMPI.B #2-1,D1 ; Are we on the first set of 8 banks?
|
||
BHI.S @D5 ; -> Yes, use D5 for the first 8
|
||
|
||
@D6 AND.B D6,D4 ; Get the nibble (banks 8 thru 15)
|
||
ROR.L #4,D6 ; prep for next time
|
||
BRA.S @Comm
|
||
|
||
@D5 AND.B D5,D4 ; Get the nibble (banks 0 thru 7)
|
||
ROR.L #4,D5 ; Roll around for next time
|
||
|
||
@Comm TST.B D4 ; Any RAM in this bank?
|
||
BEQ.S @NextOne ; -> Nope, lupe sum more
|
||
|
||
SUBQ #1,D4 ; Multiplying by powers of 2 (start at 2^1)
|
||
MOVE.L D2,D0 ; chunkSize
|
||
LSL.L D4,D0 ; This bank's size in bytes
|
||
|
||
ADD.L D0,A3 ; Add this bank's size to the running total
|
||
@NextOne DBRA D1,@Loop
|
||
ROL.L #8,D6 ; Fix D6 (contains only 2 banks, but should be in LSB)
|
||
|
||
MOVE.L A3,D0 ; Get total RAM in d0
|
||
SWAP D0 ; Poor man's BFEXTU D4{22:8},D4
|
||
LSR.W #6,D0
|
||
MOVE.L D0,MEMCAddr+MEMCmemTop ; Move bits 22-29 of addrs into bits 7-0 of MemTop reg
|
||
|
||
; -----------------------------------------------------------------------------------------
|
||
;
|
||
; Put in interleave enabling code HERE.
|
||
;
|
||
; It must go here because if you turn it on after the chunk table is built, interleaving
|
||
; "scrambles" the banks and the chunk table would get scrambled as well.
|
||
;
|
||
; At this point, we can thrash A0
|
||
;
|
||
; Bank information is stored in D5 & D6. D5 = banks 0-7, D6 = banks 8&9
|
||
; Organization of D5 and D6 is:
|
||
;
|
||
; +-------------------------------------------------------+
|
||
; | bank | bank | bank | bank | bank | bank | bank | bank |
|
||
; | 7 | 6 | 5 | 4 | 3 | 2 | 1/9 | 0/8 | D5/D6 bank value positions
|
||
; +-------------------------------------------------------+
|
||
; -----------------------------------------------------------------------------------------
|
||
|
||
IF forRomulator THEN ; if you're running a ROM in RAM, you dont EVER <H15><SM10>
|
||
bra @skipInterleave ; want to turn on interleaving. it could make your day <H15><SM10>
|
||
ENDIF ; very unhappy <H15><SM10>
|
||
; Only allow interleave enable on djMEMC versions > 0. <H10> thru next <H10><SM10>
|
||
; Version 0 parts cause the machine to lock up if interleaving is enabled.
|
||
|
||
lea MEMCAddr+MEMCIntleaveEnable,a0; get interleave enable reg. address
|
||
moveq #$0E,d0 ; mask for djMEMC version number, shifted 1 bit to the left
|
||
rol.l #8,d0 ; shift mask to correct location
|
||
and.l (a0),d0 ; check djMEMC version
|
||
beq.s @skipInterleave ; IF djMEMC_Version != 0 THEN <H10><SM10>
|
||
|
||
; make sure banks are the same size first
|
||
|
||
move.l d5,d1 ; get 1st 8 banks info
|
||
move.l d1,d0
|
||
ror.l #4,d0 ; such that d0 = (d1 >> 4), or bank pairs in same bit positions
|
||
eor.l d0,d1 ; XOR them to see if they're the same
|
||
andi.l #$0F0F0F0F,d1 ; AND to get only bottom nibble of each byte
|
||
moveq.l #1,d0 ; starting bit of bank 0&1 in interleave reg.
|
||
move.l (a0),d4 ; get current OneBufferedBit value from interleave reg.
|
||
andi.w #$FFE0,d4 ; force the Interleaved bank bits to be unset
|
||
@chkNextPair
|
||
tst.b d5 ; test this bank PAIR
|
||
beq.s @nextpair ; BRIF both banks empty
|
||
tst.b d1 ; test if both banks EQUAL
|
||
bne.s @nextpair ; IF BankX == BankX+1 THEN
|
||
or.w d0,d4 ; set appropriate bit
|
||
@nextpair ; ENDIF
|
||
ror.l #8,d5 ; point to next bank pair
|
||
ror.l #8,d1 ; point to next XORed bank-pair results
|
||
rol.l #1,d0 ; rotate bit to next interleave bit
|
||
cmpi.b #%10000,d0 ; checking banks 8&9 yet?
|
||
bne.s @chkNextPair ; if still working with banks 0-7
|
||
|
||
; if you're here, then we need to test banks 8&9, found in D6.
|
||
|
||
tst.b d6 ; are both banks empty?
|
||
beq.s @setInterleave ; IF Bank8&9 != EMPTY
|
||
move.b d6,d1 ; get info for bank 8
|
||
move.b d1,d0 ; &9
|
||
andi.b #$0F,d1 ; isolate bank 8
|
||
ror.b #4,d0 ; align them so nibbles for 8&9 are the same
|
||
andi.b #$0F,d0 ; isolate bank 9
|
||
cmp.b d0,d1 ; check if bank 8 is same size as bank 9
|
||
bne.s @setInterleave ; IF Bank8 == Bank9 THEN
|
||
ori.b #%10000,d4 ; set bit for banks 8&9
|
||
@setInterleave ; ENDIF
|
||
move.l d4,(a0) ; and write it out to the interleave config reg.
|
||
|
||
@skipInterleave ; ENDIF <H10><SM12>
|
||
MOVEQ #(3*4)+(10*8),D1 ; size of chunk table for this decoder (3 longs + 10 banks)
|
||
BRA newWriteChunkTable ; write chunk table and exit... (ext nibbles in D6)
|
||
|
||
|
||
ENDWITH
|
||
; ----------------------------------------------------------------------------------------- <H7>
|
||
|
||
align 2 ; <SM12>
|
||
|
||
;_____________________________________________________________________________________________
|
||
; Routine: expandSize
|
||
;
|
||
; Inputs: d1.w - nibble size of this bank
|
||
; d2 - chunk size
|
||
;
|
||
; Outputs: d0 - .nnn...., where n = size in bytes of this bank
|
||
;
|
||
; Destroys: d1
|
||
;
|
||
; This routine converts the nibble size in d1 to a real size (in bytes) in d0, based on a
|
||
; chunk size in d2.
|
||
;_____________________________________________________________________________________________
|
||
expandSize
|
||
moveq #0,d0 ; assume no RAM
|
||
tst.w d1 ; any RAM?
|
||
beq.s @exit ; no, exit
|
||
move.l d2,d0 ; yes, get chunk size
|
||
subq.w #1,d1 ; count it
|
||
lsl.l d1,d0 ; multiply by correct power of 2
|
||
@exit RTS6
|
||
|
||
|
||
|
||
|
||
;=============================================================================================
|
||
;_____________________________________________________________________________________________
|
||
; Routine: writeChunkTable
|
||
;
|
||
; Inputs: a1 - ptr to universal RAMInfo table (first entry)
|
||
; d1 - size of chunk table (including 2 test longs and end of table longword)
|
||
; d2 - chunk size for this decoder
|
||
; d3 - total size of RAM in system
|
||
; d5 - nibble sizes for up to 8 banks
|
||
; d6 - nibble sizes for up to another 8 banks (newWriteChunkTable)
|
||
;
|
||
; Outputs: d0 - .nnn...., where n = size in bytes of this bank
|
||
;
|
||
; Destroys: d1/d5/d6/a7
|
||
;
|
||
; Writes the chunk table at the end of RAM, based on the values passed in. This routine
|
||
; creates a separate entry for each chunk that contains RAM.
|
||
;
|
||
; •• New Mod <H7> •• - If you have more than 8 banks, then you should call newWriteChunkTable
|
||
; with the first 8 banks of nibbles in D5 (as usual) and the second (up to) 8 banks of nibbles
|
||
; in D6. The total size of the chuck table should be in D1 (1 entry for each bank plus the
|
||
; test longs at the end of the table - same as always).
|
||
;_____________________________________________________________________________________________
|
||
|
||
writeChunkTable ; <11> <SM12>
|
||
moveq #0,d6 ; clear the extended nibble count for the old guys <H7><SM12>
|
||
newWriteChunkTable ; new entry point for machines with > 8 banks of memory <H7><SM12>
|
||
movea.l (a1),a5 ; get start of bank
|
||
move.l a5,a0 ; running bank start ptr
|
||
adda.l d3,a5 ; point to end of bank
|
||
suba.l d1,a5 ; allocate space for test space/chunk table
|
||
move.l a5,a7 ; remember start of chunk table
|
||
|
||
@loop moveq #$0F,d1 ; prepare to mask for size nibble
|
||
and.b d5,d1 ; get bank size nibble
|
||
beq.s @next ; skip if no RAM in this bank
|
||
BSR6 expandSize ; convert nibble size (in d1) --> real size (in d0)
|
||
move.l a0,(a7)+ ; write start
|
||
move.l d0,(a7)+ ; write length
|
||
add.l d0,a0 ; calculate next start
|
||
@next lsr.l #4,d5 ; shift in next bank nibble
|
||
bne.s @loop ; continue if more banks
|
||
|
||
move.l d6,d5 ; do we have more banks to do? ( > 8) <H7><SM12>
|
||
beq.s @finishup ; -> Nope, no more <H7><SM12>
|
||
clr.l d6 ; clr the extended nibble sizes (so we only do this once) <H7><SM12>
|
||
bra.s @loop ; do more banks <H7><SM12>
|
||
|
||
@finishup subq.l #1,d5 ; = FFFFFFFF <SM12>
|
||
move.l d5,(a7)+ ; write FFFFFFFF (terminator)
|
||
@fill clr.l (a7)+ ; clear test space
|
||
move.w a7,d0 ; at end of bank
|
||
bne.s @fill ; no, keep clearing
|
||
|
||
;.............................................................................................
|
||
MergeDone
|
||
movea.l (a1),sp ; sp := base of RAM
|
||
adda.l #$8000,sp ; sp := base of RAM + 32K
|
||
move.l a5,-(sp) ; push ptr to chunk table on stack
|
||
|
||
;_____________________________________________________________________________________________ <SM12>begin
|
||
;
|
||
; For machines with a sound buffer in high RAM (i.e., ASC-based machines), we'll move the
|
||
; RAM chunk table below the sound buffer. This will avoid collisions with large MMU tables.
|
||
; We need to do this here because SizeMem gets called more than once (by diagnostics), so
|
||
; that, for example, the warmstart flag will be valid across boots.
|
||
;
|
||
; BEFORE AFTER
|
||
;
|
||
; +-------------------+ <-- top of memory --> +-------------------+
|
||
; | RAM chunks | | |
|
||
; |-------------------| | |
|
||
; | | | |
|
||
; | BootGlobs & +-------------------+ +-------------------+
|
||
; | MMU tables | | | |
|
||
; | will grow dow| Sound Buffer | | Sound Buffer |
|
||
; | | | | | |
|
||
; | V +-------------------+ +-------------------+
|
||
; | | | RAM chunks |
|
||
; +-------------------+ |-------------------|
|
||
; | |
|
||
; | BootGlobs & |
|
||
; | MMU tables |
|
||
; | will grow down |
|
||
; | | |
|
||
; | V |
|
||
; | |
|
||
; +-------------------+
|
||
;_____________________________________________________________________________________________
|
||
|
||
MOVE.L A2,D3 ; save the return address <H13>
|
||
MOVEQ #0,D2 ; get the decoder type <H13>
|
||
BigBSR6 GetHardwareInfo,a0 ; <H13>
|
||
MOVEA.L (SP),A6 ; point to the chunk table <H13>
|
||
LEA @Resume,A2 ; (BSR2) <H13>
|
||
BRA.S SizeSoundBuffer ; get the size of a sound buffer in high RAM (if any) <H13>
|
||
@Resume BEQ.S @Done ; -> no sound buffer <H13>
|
||
SUB.L D0,(SP) ; adjust the address of the new chunk table <H13>
|
||
SUB.L A6,D1 ; calculate the size of the chunk table <H13>
|
||
@MoveChunks MOVE.B -(A1),-(A0) ; move the RAM chunk table to its new home <H13>
|
||
SUBQ.L #1,D1 ; <H13>
|
||
BGT.S @MoveChunks ; <H13>
|
||
@Done MOVEA.L D3,A2 ; restore the return address <H13>
|
||
|
||
moveq #0,d6 ; Z flag set to indicate no error(s) <15>
|
||
jmp (a2)
|
||
|
||
|
||
;_____________________________________________________________________________________________
|
||
;
|
||
; Routine: SizeSoundBuffer
|
||
;
|
||
; Inputs: D2.B- decoder type (from Universal)
|
||
; A2 - return address
|
||
; A6 - physical address of RAM chunk table
|
||
;
|
||
; Outputs: D0 - size of sound buffer (zero if none)
|
||
; A0 - pointer to start of sound buffer
|
||
; A1 - pointer to end of RAM
|
||
; A6 - physical address of RAM chunk table
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: returns the starting address and size of a sound buffer in high RAM.
|
||
;_____________________________________________________________________________________________
|
||
|
||
SizeSoundBuffer ; <H13>
|
||
LEA @bufSizeTbl-4,A1
|
||
MOVEQ #0,D0 ; assume no sound buffer in high RAM
|
||
@FindDecoder
|
||
ADDQ.W #4,A1 ; skip over the previous routine offset
|
||
MOVE.W (A1)+,D0 ; get the next decoder type
|
||
BEQ.S @Done ; -> end of list
|
||
CMP.B D2,D0 ; does the decoder match?
|
||
BNE.S @FindDecoder ; -> no, try the next one
|
||
MOVE.L (A1)+,D0 ; yes, get offset from top of RAM to start of sound buffer
|
||
|
||
MOVEA.L A6,A1 ; point to the start of the chunk table
|
||
BRA.S @FirstChunk ; and start looking
|
||
@FindLastChunk
|
||
ADDQ.W #8,A1 ; skip over the previous chunk start/size
|
||
@FirstChunk TST.L (A1) ; are we at the end of the table?
|
||
BPL.S @FindLastChunk ; -> nope, keep going
|
||
|
||
MOVE.L -(A1),D1 ; calculate the address of the end of the last chunk
|
||
ADD.L -(A1),D1
|
||
MOVEA.L D1,A1 ; and save it
|
||
MOVEA.L D1,A0 ; calculate where the end of the moved chunk table will be
|
||
SUBA.L D0,A0 ; (this is also the start of the sound buffer)
|
||
@Done TST.L D0 ; set the CCR
|
||
JMP (A2)
|
||
|
||
|
||
; IMPORTANT: Because of the way that ConfigureRAM works (in StartInit), the following table sizes must be
|
||
; multiples of 1024.
|
||
@bufSizeTbl DC.W DecoderKinds.MSCDecoder ; MSC
|
||
DC.L (8*1024)
|
||
DC.W DecoderKinds.PrattDecoder ; Pratt (for Blackbird)
|
||
DC.L (32*1024) ; Sound can use a FIFO size up to 32K (includes modem sound buffer)
|
||
|
||
DC.W 0 ; end of list <SM12>end
|
||
|
||
|
||
|
||
END
|