A list of the 3DO's memory mappings. Much of this was sourced from the 3DOessence spreadsheet. ===== General ===== ^Base Address^End Address^Size^Hardware^Description| |0x0000_0000|0x001F_FFFF|2MiB|DRAM| | |0x0020_0000|0x002F_FFFF|1MiB|VRAM| | |0x0300_0000|0x030F_FFFF|1MiB|ROM| | |0x0314_0000|0x0315_FFFF|128KiB|NVRAM| | |0x0316_0000|0x0317_FFFF|128KiB|NVRAM mirror| | |0x0320_0000|0x032F_FFFF?|1MiB|SPORT| | |0x0330_0000|0x0330_07FF|2KiB|MADAM| | |0x0340_0000|0x0340_03FF|1KiB|CLIO| | | | | | | | | | | | | | ===== SPORT ===== ^ ^ ^ ^ ^ | | | | | | | | | | | | | ===== MADAM ===== ^Address^Description^ | |0x0330_0000|read: MADAM version/feature data \\ write: debug output| | |0x0330_0004|read: memory configuration \\ * 0x0100_0000: Red MADAM \\ * 0x0102_0000: Green MADAM w/ matrix hardware \\ * 0x0102_0001: Green MADAM w/ no matrix hardware| | |0x0330_0008|DMA channel enablement \\ * 0x0000_8000: Player Bus \\ * 0x0010_0000: Sprite control| | |0x0330_000C|Unsure. "testbin" sets it to 0x00178906.| | |0x0330_0020| \\ Contains a bitmask of reasons for an abort signal MADAM sent to the CPU. \\ * 0x0000_0001: ROMF "Rom Failure" \\ * 0x0000_0002: ROMW "Rom Write" \\ * 0x0000_0004: CLIOT "CLIO timeout" \\ * 0x0000_0008: HARDU "User access to hardware" \\ * 0x0000_0010: SYSRAMU "User access to sysram" \\ * 0x0000_0020: FENCEV "Fence (memory protection) violation" \\ * 0x0000_0040: VPR "Virtual Page error" \\ * 0x0000_0080: R26E "Out of 26bit address range" \\ * 0x0000_0100: SPSC "SPORT while SC" \\ * 0x0000_0200: BITE "Byte access to hardware" \\ * 0x0000_0400: BADDEC \\ * 0x0000_0800: ARPS "ARM to Regis / PIP while SIP" \\ * 0x0000_1000: BWAAC "Byte address, word access"| | |0x0330_0024|DMA privilage violations \\ * 0x0000_0001: DMA access to SYSRAM \\ * 0x0000_0002: SPORT access to SYSRAM (VDL DMA channel) \\ * 0x0000_0004: REGIS access to SYSRAM \\ * 0x0000_0008: DMA access over VRAMSIZE \\ * 0x0000_0010: SPORT access over VRAMSIZE (VDL DMA channel) \\ * 0x0000_0020: REGIS acess over VRAMSIZE \\ * 0x0000_0040: REGIS math failure| | |0x0330_0028| \\ Spryte rendering engine status register. Details found in {{:documentation:patents:pat5572235_-_method_and_apparatus_for_processing_image_data.pdf|US patent 5,572,235}}. See Table 1.8. \\ * 0x0000_0010: SPRON "spryte engine enabled" \\ * 0x0000_0020: SPRPAU "spryte engine paused"| | |0x0330_002C| \\ Write a value and when read it will return the number of the most significantly set bit. \\ \\ example: Write 0x8400_0000 and a read will return 31. Write 0x0000_0000 and the return will be 0xFFFF_FFFF; \\ | | |0x0330_0040|The currently rendered horizontal pixel offset.| | |0x0330_0100|SPRSTRT: Spryte rendering engine's start register. From {{:documentation:patents:pat5572235_-_method_and_apparatus_for_processing_image_data.pdf|US patent 5,572,235}}: The Spryte rendering process is started from the CPU by writing a meaningless value to the 'SPRSTRT' address in the memory address manipulator chip (MAMC). This sets the 'Spryte-ON' flipflop. Writing to SPRSTART while the 'Spryte-ON' flipflop is already on will have no effect at all. BUT DON'T DO IT. The race condition of Spryte just now ending and you just now writing is not preventable.| | |0x0330_0104|SPRSTOP: Spryte rendering engine's stop register. From {{:documentation:patents:pat5572235_-_method_and_apparatus_for_processing_image_data.pdf|US patent 5,572,235}}: The Spryte process is stopped cold when the CPU writes to 'SPRSTOP'. All intermediate states of the engines have been RESET. The data pointers are now WRONG. Spryte processing is dead. Except, of course, for the SPRPAUS flipflop.| | |0x0330_0108|SPRCNTU: Spryte rendering engine's continue register. From {{:documentation:patents:pat5572235_-_method_and_apparatus_for_processing_image_data.pdf|US patent 5,572,235}}: The CPU can reset the PAUSE flipflop by writing to 'SPRCNTU'. If the Spryte engine was on but paused it will not continue. If not, it won't. This is also when the CPU might avail itself of the SPRPAUS function.| | |0x0330_010C|SPRPAUS: Spryte rendering engine's pause register. From {{:documentation:patents:pat5572235_-_method_and_apparatus_for_processing_image_data.pdf|US patent 5,572,235}}: The CPU can request that the Spryte rendering engine stop operating at the end of the current Spryte but not reset itself by writing to 'SPRPAUS'. This will set a 'SPRPAUS' flipflop that will cause the Cpryte rendering engine to set its 'PAUSE' flipflop at the end of the current Spryte. When the PAUSE flipflop is set by this mechanism (not by other means), the SPRPAUS flipflop will be cleared. The SPRPAUS event is only a one shot thing. Obviously this can only be done if the CPU already has access to the system bus. SPRPAUS can be set by the CPU even if the Spryte engine is off. When an interrupt is present, the PAUSE flipflop is held in a 'set' condition. This will allow the Spryte rendering engine to pause cleanly and allow the CPU to notice the interrupt.| | |0x0330_0110|CCBCTL0: struct Bitmap→bm_CEControl \\ General spryte rendering engine control word| | |0x0330_0130|REGCTL0: struct Bitmap→bm_REGCTL0 \\ Controls the modulo for reading source frame buffer data into the primary and/or secondary imput port of the spryte engine and for writing spryte image result data from the spryte engine into a destination frame buffer in VRAM. The modulo effectively indicates the number of pixels per scan line as represented in the respective frame buffer in VRAM.| | |0x0330_0134|REGCTL1: struct Bitmap→bm_REGCTL1 \\ X and Y clip values, effecively indicating the number of pixels in the X and Y dimensions which make up the frame buffer. Bits 26:16 indicate the last writable row (counting from row 0) in the Y dimension and the bits 10:0 indicate the last writable column (counting from col 0) in the X dimension. All other bits must be zero. As an example, a value of 0x00EF_013F indicates that the frame buffer data is represented in 320×240 format.| | |0x0330_0138|REGCTL2: struct Bitmap→bm_REGCTL2 \\ Read base address. Indicates the address in VRAM of the upper left corner pixel of the source frame buffer data.| | |0x0330_013C|REGCTL3: struct Bitmap→bm_REGCTL3 \\ Write base address. Indicates the addres in VRAM of the upper left corner pixel of the destination frame buffer.| | |0x0330_0230|Fence control 0L| | |0x0330_0234|Fence control 0R| | |0x0330_0238|Fence control 1L| | |0x0330_023C|Fence control 1R| | |0x0330_0270|Fence control 2L| | |0x0330_0274|Fence control 2R| | |0x0330_0278|Fence control 3L| | |0x0330_027C|Fence control 3R| | |0x0330_0400|CPU RAM to DSP DMA Group 0x0: current address \\ See US patent {{:documentation:patents:wo09410641a1_-_audio_-_video_computer_architecture.pdf|WO09410641A1}} page 46 line 25 for details.| | |0x0330_0404|CPU RAM to DSP DMA Group 0x0: current length| | |0x0330_0408|CPU RAM to DSP DMA Group 0x0: next address| | |0x0330_040C|CPU RAM to DSP DMA Group 0x0: next length| | |…| | | |0x0330_04C0|CPU RAM to DSP DMA Group 0xC: current address| | |0x0330_04C4|CPU RAM to DSP DMA Group 0xC: current length| | |0x0330_04C8|CPU RAM to DSP DMA Group 0xC: next address| | |0x0330_04CC|CPU RAM to DSP DMA Group 0xC: next length| | |0x0330_04D0|FMV DMA group 1?| | |0x0330_04D4|FMV DMA group 1?| | |0x0330_04E0|FMV DMA group 1?| | |0x0330_04E4|FMV DMA group 1?| | |0x0330_0540|XBUS DMA: source / destination address| | |0x0330_0544|XBUS DMA: length| | |0x0330_0550|FMV DMA group 2?| | |0x0330_0554|FMV DMA group 2?| | |0x0330_0560|FMV DMA group 2?| | |0x0330_0564|FMV DMA group 2?| | |0x0330_0570|Player Bus DMA: destination address \\ See US patent {{:documentation:patents:wo09410641a1_-_audio_-_video_computer_architecture.pdf|WO09410641A1}} page 61 line 25 for details.| | |0x0330_0574|Player Bus DMA: length \\ Lower half word of 0xFFFC (-4) indicates end.| | |0x0330_0578|Player Bus DMA: source address| | | | | | | | | | | | | | | | | | ===== CLIO ===== ^Address^Description| |0x0340_0000|CLIO version in high byte. Feature flags in the rest.| |0x0340_0004|unknown| |0x0340_0008|FreeDO code implies it's the line which should trigger VINT0. However, 3DOessence.xml claims it is only triggered on even fields. When doing that some games run at half speed. \\ \\ FZ10 function 0x03024674 writes to this register and then sets the interrupt mask (via 0x0340_0048). Function 0x03022454 writes 0x11 via 0x03024674.| |0x0340_000C|FreeDO code implies it's the line which should trigger VINT1. However, 3DOessence.xml claims it is only triggered on odd fields. When doing that some games run at half speed. \\ \\ Games seem to write 0x0000_0005 and 0xFFFF_FFFF to it each field render.| |0x0340_0010|??? FZ10 function 0x0300_0FB4 writes 0x2000 to this register if 0x0340_0000 == 0x0400_0000.| |0x0340_0014|unknown| |0x0340_0018|unknown| |0x0340_001C|unknown| |0x0340_0020|??? FZ10 function 0x0300_0248 writes 0xF400_0000 twice in a row if 0x0340_0000 == 0x0400_0000.| |0x0340_0024|??? FZ10 function 0x0300_0248 writes 0x6001_1F1F then 0xE001_1F1F if 0x0340_0000 == 0x0400_0000 else it writes 0xC005_0F0F.| |0x0340_0028|Reason the console reset? \\ * writing a 0x0000_0000 resets bits \\ * bits 0, 1, 6 checked by BIOS \\ * FZ10 BIOS function 0x0302706C writes 0x30| |0x0340_002C|??? Games write 0x0000_000B to it each field render as does a number of FZ10 ROM functions (0x0300_3BC4, 0x0302_18D0, 0x0302_45C0). MAME suggests it is a watchdog.| |0x0340_0030|??? HCNT: according to MAME| |0x0340_0034|VCNT: currently displayed raster line + bit 11 representing even (0) or odd (1) field.| |0x0340_0038|??? Games write 0xC693_B70F to it each field render. MAME suggests it is a seed for a PRNG.| |0x0340_003C|??? MAME suggests it is a PRNG. FZ10 ROM function 0x0300_56C8 reads the value and ORs it with a read from the PRNG at 0x0340_17F0 << 0x10.| |0x0340_0040|Triggers ARM's FIQ (Fast Interrupt reQuest) exception. \\ Reading yields pending interrupts mask. Writing a mask will *set* the corresponding bits to enable software triggered hardware interrupts. Higher numbered interrupts have higher priorities (implemented in software by the handler.) \\ \\ bit 0x00: VINT0 \\ bit 0x01: VINT1 \\ bit 0x02: EXINT (XBUS devices) \\ bit 0x03: Timer 0xF \\ bit 0x04: Timer 0xD \\ bit 0x05: Timer 0xB \\ bit 0x06: Timer 0x9 \\ bit 0x07: Timer 0x7 \\ bit 0x08: Timer 0x5 \\ bit 0x09: Timer 0x3 \\ bit 0x0A: Timer 0x1 \\ bit 0x0B: Audio Timer \\ bit 0x0C: Audio DMA - DSP to RAM0 \\ bit 0x0D: Audio DMA - DSP to RAM1 \\ bit 0x0E: Audio DMA - DSP to RAM2 \\ bit 0x0F: Audio DMA - DSP to RAM3 \\ bit 0x10: Audio DMA - RAM0 to DSP \\ bit 0x11: Audio DMA - RAM1 to DSP \\ bit 0x12: Audio DMA - RAM2 to DSP \\ bit 0x13: Audio DMA - RAM3 to DSP \\ bit 0x14: Audio DMA - RAM4 to DSP \\ bit 0x15: Audio DMA - RAM5 to DSP \\ bit 0x16: Audio DMA - RAM6 to DSP \\ bit 0x17: Audio DMA - RAM7 to DSP \\ bit 0x18: Audio DMA - RAM8 to DSP \\ bit 0x19: Audio DMA - RAM9 to DSP \\ bit 0x1A: Audio DMA - RAMA to DSP \\ bit 0x1B: Audio DMA - RAMB to DSP \\ bit 0x1C: Audio DMA - RAMC to DSP \\ bit 0x1D: XBUS DMA transfer complete \\ bit 0x1E: ??? Watchdog? \\ bit 0x1F: Indicates more interrupt flags are in 0x0340_0060| |0x0340_0044|Reading yields pending interrupts mask from 0x0340_0040. \\ Writing will *clear* the corresponding bits.| |0x0340_0048|Reading yields the interrupt enable mask for 0x0340_0040. \\ Writing will *set* the corresponding mask bits.| |0x0340_004C|Reading yields the interrupt enable mask for 0x0340_0040. \\ Writing will *clear* the corresponding mask bits.| |0x0340_0050|???| |0x0340_0054|???| |0x0340_0058|Reading yields DMA controller interrupt failure reasons? \\ bits 0…14: channels which had an underflow? \\ bit 15: ??? \\ bits 16…19: channels which had an overflow? \\ bit 20: access violation which details are described by 0x0330_0024 (MADAM) \\ bit 21: indicates bits 22…27 contain some address?| |0x0340_005C|???| |0x0340_0060|Continuation of 0x0340_0040 \\ \\ bit 0x00: ? \\ bit 0x01: ? \\ bit 0x02: FMV module (Woody). Uses 0x031C_0000 - 0x031C_FFFF. \\ bit 0x03: ? \\ bit 0x04: FMV Video from RAM \\ bit 0x05: FMV Video to RAM \\ bit 0x06: FMV Audio from RAM \\ bit 0x07: FMV Audio to RAM \\ bit 0x08: DMA controller interrupt \\ bit 0x09: \\ bit 0x0A: \\ bit 0x0B: \\ bit 0x0C: \\ bit 0x0D: \\ bit 0x0E: \\ bit 0x0F: \\ bit 0x10: \\ bit 0x11: \\ bit 0x12: \\ bit 0x13: \\ bit 0x14: \\ bit 0x15: \\ bit 0x16: \\ bit 0x17: \\ bit 0x18: \\ bit 0x19: \\ bit 0x1A: \\ bit 0x1B: \\ bit 0x1C: \\ bit 0x1D: \\ bit 0x1E: \\ bit 0x1F:| |0x0340_0064|Like 0x0340_0044| |0x0340_0068|Like 0x0340_0048| |0x0340_006C|Like 0x0340_004C| | | | |0x0340_0410| \\ first DIPIR \\ \\ 0x8000 - active \\ 0x4000 - happened before reset \\ 0x00xx - device number of the DIPIR \\ | |0x0340_0414|second DIPIR| | | | |0x0340_17F0|PRNG which returns 16bit value on read.|