====== Details ====== According to [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/pgsfldr/spg/01spg003.html#XREF36250|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 [[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()]]. /* * 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; } /* * 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.