Site Tools


documentation:hardware:opera:memory_configurations
no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


documentation:hardware:opera:memory_configurations [2023/12/03 17:42] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== Details ======
 +
 +According to [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/pgsfldr/spg/01spg003.html#XREF36250|3DO development documents]]:
 +
 +<blockquote>
 +
 +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.
 +
 +</blockquote>
 +
 +Memory address 0x0330_0004, a MADAM register (MSYSBits), is used to indicate the 3DO's memory configuration. From the Portfolio OS source we find [[http://github.com/trapexit/portfolio_os/blob/master/src/dipir/dipirutils.c#L58|FindMemSize()]] and [[https://github.com/trapexit/portfolio_os/blob/bee7b0c8e4287083c73cb5497b658880c9e7af8e/src/kernel/mem.c#L337|FindRamSize()]].
 +
 +<code c 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;
 +}
 +</code>
 +
 +<code c 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;
 +}
 +</code>
 +
 +====== 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