Site Tools


documentation:hardware:opera:memory_configurations

Details

According to 3DO development documents:

A minimum 3DO system includes 2 MB of DRAM and 1 MB of VRAM for a total of 3 MB of RAM. Optional memory configurations can, for this version of the hardware, go up to a maximum of 16 MB of RAM: 1 MB of VRAM and 15 MB of DRAM, or 2 MB of VRAM and 14 MB of DRAM.

Memory address 0x0330_0004, a MADAM register (MSYSBits), is used to indicate the 3DO's memory configuration. From the Portfolio OS source we find FindMemSize() and FindRamSize().

dipirutils.c
/*
 * Compute size of DRAM based on contents of the Madam System Control Register.
 *
 *             |  x8 == 0   |  x8 == 0  |  x8 == 1
 *  MSYS       | MSYS DRAM  | MSYS DRAM | MSYS
 *  2:0  VRAM  | 6:5  SET0  | 4:3 SET1  | 6:3  DRAM
 *  ---  ----  | ---- ----  | ---- ---- | ---- ----
 *             |  00  0 MB  |  00 0 MB  |
 *  001  1 MB  |  01  1 MB  |  01 1 MB  | 0101 2 MB
 *  010  2 MB  |  10  4 MB  |  10 4 MB  | 1010 8 MB
 *
 * Combinations not shown in the above tables are not supported and
 * this routine is not guaranteed to return anything sensible (even
 * though it usually will do something vaguely rational).
 */
void
FindMemSize(uint32 *pDramSize, uint32 *pVramSize)
{
    uint32 bits = *MSYSBits;
    uint32 dram_size;
    uint32 vram_size;
 
    /*
     * This may look complex, but it only takes about eight ARM
     * instructions to evaluate. Basicly, take each DRAM set size
     * field, and double it to get the left-shift count. Then
     * shift "a quarter megabyte" left by the count, casting off
     * anything less than a megabyte; this is easiest to do if you
     * shift "1" left by the count, then right by two. We turn it
     * into megabytes later.
     */
    dram_size =
        (((1<<((bits>> (DRAMSIZE_SET0SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2) +
         ((1<<((bits>> (DRAMSIZE_SET1SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2));
 
    vram_size = ((bits & VRAMSIZE_MASK)>> VRAMSIZE_SHIFT);
 
    /* Convert to megabytes */
    *pDramSize = dram_size * 1024*1024;
    *pVramSize = vram_size * 1024*1024;
}
mem.c
/*
 * FindRamSize(): compute "vram_size" and "dram_size" based on the
 * contents of the Madam System Control Register.
 *
 *             |  x8 == 0   |  x8 == 0  |  x8 == 1
 *  MSYS       | MSYS DRAM  | MSYS DRAM | MSYS
 *  2:0  VRAM  | 6:5  SET0  | 4:3 SET1  | 6:3  DRAM
 *  ---  ----  | ---- ----  | ---- ---- | ---- ----
 *             |  00  0 MB  |  00 0 MB  |
 *  001  1 MB  |  01  1 MB  |  01 1 MB  | 0101 2 MB
 *  010  2 MB  |  10  4 MB  |  10 4 MB  | 1010 8 MB
 *                          |  11 16MB  |
 *
 * Combinations not shown in the above tables are not supported and
 * this routine is not guaranteed to return anything sensible (even
 * though it usually will do something vaguely rational).
 *
 * Note: only 16 MB address space is available for system memory, so
 * the actual amount of DRAM available is reduced so that the sum of
 * the DRAM and VRAM is no larger than 16 MB.
 */
 
void
FindRamSize (void)
{
  uint32    bits = *MSYSBits;
 
  /*
   * This may look complex, but it only takes about eight ARM
   * instructions to evaluate. Basicly, take each DRAM set size
   * field, and double it to get the left-shift count. Then
   * shift "a quarter megabyte" left by the count, casting off
   * anything less than a megabyte; this is easiest to do if you
   * shift "1" left by the count, then right by two. We turn it
   * into megabytes later.
   */
  dram_size =
    (((1<<((bits>> (DRAMSIZE_SET0SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2) +
     ((1<<((bits>> (DRAMSIZE_SET1SHIFT-1))&(DRAMSIZE_SETMASK<<1)))>>2));
 
  /*
   * Only two VRAM sizes are defined. I'd guess that this gets
   * more complex if we start seeing more VRAM sizes.
   */
  vram_size = ((bits & VRAMSIZE_MASK)>> VRAMSIZE_SHIFT);
 
  /*
   * Opera only provides 16 Megabytes of physical address space
   * to contain both the VRAM and DRAM, and the VRAM is above
   * the DRAM. If the calculations above give more than 16M of
   * total memory, trim DRAM back so the total is exactly 16M.
   */
  if ((dram_size + vram_size)> 16)
    dram_size = 16 - vram_size;
 
  /*
   * The rest of the system wants to deal with byte counts, not
   * numbers of megabytes, so be nice to it.
   */
  dram_size <<= 20;
  vram_size <<= 20;
 
  /*
   * As mentioned above, VRAM starts where DRAM ends; note the
   * actual VRAM starting address for future consumption.
   */
  vram_start = (uint8 *) dram_size;
 
  if (vram_size> ONEMEG)
    two_vram_banks = TRUE;
  else
    two_vram_banks = FALSE;
}

TODO

  • Given there is 48MB of address space between 0x0000_0000 and the ROM at 0x0300_0000 it might be possible to hack the ROM to allow for 16MB + 16MB of DRAM and 16MB of VRAM.
  • FreeDO/4DO was hard coded to support the retail model's memory configuration. In the least it should be possible to enhance Opera to support the official permutations.
documentation/hardware/opera/memory_configurations.txt · Last modified: 2023/12/03 17:42 by trapexit