Difference between revisions of "Memory"
From xboxdevwiki
(Fixed bug in pseudocode) |
(Add shadow RAM to memory map) |
||
(21 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
− | The Xbox has 64MB Memory. This could be expanded to 128MB of memory ( | + | The Xbox has 64MB Memory. This could be expanded to 128MB of memory on boards of revision 1.0-1.4 (Boards of revision 1.0-1.4 have empty spots for the extra memory, but they were later removed on 1.6 boards) but no games took advantage of it. The debug Xbox and the Chihiro both contained 128MB Memory. |
− | The memory was shared between the CPU and GPU. On the retail Xbox, the [[ | + | The memory was shared between the CPU and GPU. On the retail Xbox, the [[Flash ROM]] and [[MCPX ROM]] are also mapped to memory at the top 16 MiB and the top 512 Bytes respectively. However on Debug Xboxes and Chihiro, only the Flash is mapped as they don't contain an MCPX ROM. |
− | {| | + | = Memory map = |
+ | {| class="wikitable" style="text-align: center;" | ||
! Memory Type | ! Memory Type | ||
! Retail Xbox Range | ! Retail Xbox Range | ||
Line 9: | Line 10: | ||
|- | |- | ||
|Main Memory | |Main Memory | ||
− | |0x00000000 - | + | |0x00000000 - 0x03FFFFFF |
− | |0x00000000 - | + | |0x00000000 - 0x07FFFFFF |
|- | |- | ||
− | | | + | |Shadow RAM |
− | | | + | |0xF0000000 - 0xF3FFFFFF |
− | | | + | |0xF0000000 - 0xF7FFFFFF |
|- | |- | ||
− | |MCPX | + | |[[GPU|GPU (NV2A) Registers]] |
+ | |colspan="2"|0xFD000000 - 0xFDFFFFFF | ||
+ | |- | ||
+ | |[[APU|APU Registers]] | ||
+ | |colspan="2"|0xFE800000 - 0xFE87FFFF | ||
+ | |- | ||
+ | |[[ACI|ACI (AC97) Registers]] | ||
+ | |colspan="2"|0xFEC00000 - 0xFEC00FFF | ||
+ | |- | ||
+ | |USB 0 Registers | ||
+ | |colspan="2"|0xFED00000 - 0xFED00FFF | ||
+ | |- | ||
+ | |USB 1 Registers | ||
+ | |colspan="2"|0xFED08000 - 0xFED08FFF | ||
+ | |- | ||
+ | |NIC (NVNet) Registers | ||
+ | |colspan="2"|0xFEF00000 - 0xFEF003FF | ||
+ | |- | ||
+ | |[[Flash ROM]] | ||
+ | |colspan="2"|0xFF000000 - 0xFFFFFFFF | ||
+ | |- | ||
+ | |[[MCPX ROM]] | ||
|0xFFFFFE00 - 0xFFFFFFFF | |0xFFFFFE00 - 0xFFFFFFFF | ||
|N/A | |N/A | ||
|} | |} | ||
+ | = I/O port map = | ||
+ | {{FIXME|reason=Taken from the KVMBOX memorymap.txt, not confirmed}} | ||
+ | |||
+ | {| class="wikitable" style="text-align: center;" | ||
+ | ! Device | ||
+ | ! Retail Xbox Range | ||
+ | ! Debug/Chihiro Range | ||
+ | |- | ||
+ | |DMA Channels 0-3 | ||
+ | |colspan="2"|0x0000 - 0x000F | ||
+ | |- | ||
+ | |Master PIC | ||
+ | |colspan="2"|0x0020 - 0x0021 | ||
+ | |- | ||
+ | |[[Super I/O|Super I/O Configuration]] | ||
+ | |N/A | ||
+ | |0x002E - 0x002F | ||
+ | |- | ||
+ | |[[Porting an Operating System to the Xbox HOWTO #Timer Frequency|PIT]] | ||
+ | |colspan="2"|0x0040 - 0x0043 | ||
+ | |- | ||
+ | |[[17 Mistakes Microsoft Made in the Xbox Security System #The Xbox Hardware|A20 Gate]] / [[MCPX #Pin L21: PC Speaker|Speaker]] | ||
+ | |colspan="2"|0x0060 - 0x006F | ||
+ | |- | ||
+ | |CMOS / RTC | ||
+ | |colspan="2"|0x0070 - 0x0073 | ||
+ | |- | ||
+ | |DMA Page Address | ||
+ | |colspan="2"|0x0080 - 0x008F | ||
+ | |- | ||
+ | |Slave PIC | ||
+ | |colspan="2"|0x00A0 - 0x00A1 | ||
+ | |- | ||
+ | |DMA Channels 4-7 | ||
+ | |colspan="2"|0x00C0 - 0x00DF | ||
+ | |- | ||
+ | |FPU Error Control | ||
+ | |colspan="2"|0x00F0 - 0x00F1 | ||
+ | |- | ||
+ | |IDE | ||
+ | |colspan="2"|0x01F0 - 0x01F7 | ||
+ | |- | ||
+ | |vesafb {{FIXME|reason=Does XGPU expose I/O ports?}} | ||
+ | |colspan="2"|0x03C0 - 0x03DF | ||
+ | |- | ||
+ | |IDE {{FIXME|reason=Really? This is rather one of FDC ports}} | ||
+ | |colspan="2"|0x03F6 - 0x03F6 | ||
+ | |- | ||
+ | |[[Super I/O|Super I/O Serial]] | ||
+ | |N/A | ||
+ | |0x03F8 - 0x03FF | ||
+ | |- | ||
+ | |[[PCI|PCI Configuration]] | ||
+ | |colspan="2"|0x0CF8 - 0x0CFF | ||
+ | |- | ||
+ | |[[SMBus|SMBus (I2C)]] | ||
+ | |colspan="2"|0x1000 - 0x100F | ||
+ | |- | ||
+ | |rowspan="2"|Modem (MC97) | ||
+ | |colspan="2"|0x1080 - 0x10FF | ||
+ | |- | ||
+ | |colspan="2"|0x1400 - 0x14FF | ||
+ | |- | ||
+ | |[[PCI #00.01:0 - ISA Bridge|LPC PM]] | ||
+ | |colspan="2"|0x8000 - 0x80FF | ||
+ | |- | ||
+ | |rowspan="2"|[[SMBus|SMBus (I2C)]] | ||
+ | |colspan="2"|0xC000 - 0xC00F | ||
+ | |- | ||
+ | |colspan="2"|0xC200 - 0xC21F | ||
+ | |- | ||
+ | |rowspan="2"|[[ACI|ACI (AC97)]] | ||
+ | |colspan="2"|0xD000 - 0xD0FF | ||
+ | |- | ||
+ | |colspan="2"|0xD200 - 0xD27F | ||
+ | |- | ||
+ | |NIC (NVNet) | ||
+ | |colspan="2"|0xE000 - 0xE007 | ||
+ | |- | ||
+ | |IDE | ||
+ | |colspan="2"|0xFF60 - 0xFF6F | ||
+ | |} | ||
+ | |||
+ | = Emulation = | ||
Code for emulating the memory might consist of: | Code for emulating the memory might consist of: | ||
<pre> | <pre> | ||
#ifdef DEBUG || CHIHIRO | #ifdef DEBUG || CHIHIRO | ||
− | #define | + | #define MEMORY_SIZE 128 * 1024 * 1024 |
int mcpx_active = 0; | int mcpx_active = 0; | ||
#else | #else | ||
− | #define | + | #define MEMORY_SIZE 64 * 1024 * 1024 |
int mcpx_active = 1; | int mcpx_active = 1; | ||
#endif | #endif | ||
− | #define | + | #define FLASH_SIZE 256 * 1024 |
− | #define | + | #define FLASH_MAP_SIZE 16 * 1024 * 1024 |
− | #define | + | #define FLASH_MAP_ADDRESS (0xFFFFFFFF - FLASH_MAP_SIZE + 1) |
+ | |||
#define MCPX_SIZE 0x200 | #define MCPX_SIZE 0x200 | ||
− | #define | + | #define MCPX_MAP_ADDRESS (0xFFFFFFFF - MCPX_MAP_SIZE + 1) |
− | uint8_t memory[ | + | uint8_t memory[MEMORY_SIZE] = {0}; |
− | uint8_t | + | uint8_t flash[FLASH_SIZE] = {0}; |
uint8_t mcpx[MCPX_SIZE] = {0}; | uint8_t mcpx[MCPX_SIZE] = {0}; | ||
uint8_t get_memory_byte(uint32_t location) { | uint8_t get_memory_byte(uint32_t location) { | ||
− | if (location < | + | if (location < MEMORY_SIZE) { |
return memory[location]; | return memory[location]; | ||
} | } | ||
− | if (mcpx_active && location >= | + | if (mcpx_active && location >= MCPX_MAP_ADDRESS) { |
− | return mcpx[location - | + | return mcpx[location - MCPX_MAP_ADDRESS]; |
} | } | ||
− | if (location >= | + | if (location >= FLASH_MAP_ADDRESS) { |
− | return | + | return flash[(location - FLASH_MAP_ADDRESS) % FLASH_SIZE]; |
} | } | ||
Line 60: | Line 167: | ||
uint16_t get_memory_word(uint32_t location) { | uint16_t get_memory_word(uint32_t location) { | ||
− | return | + | return get_memory_byte(location + 1) << 8 | get_memory_byte(location); |
} | } | ||
Latest revision as of 23:59, 20 February 2024
The Xbox has 64MB Memory. This could be expanded to 128MB of memory on boards of revision 1.0-1.4 (Boards of revision 1.0-1.4 have empty spots for the extra memory, but they were later removed on 1.6 boards) but no games took advantage of it. The debug Xbox and the Chihiro both contained 128MB Memory.
The memory was shared between the CPU and GPU. On the retail Xbox, the Flash ROM and MCPX ROM are also mapped to memory at the top 16 MiB and the top 512 Bytes respectively. However on Debug Xboxes and Chihiro, only the Flash is mapped as they don't contain an MCPX ROM.
Memory map
Memory Type | Retail Xbox Range | Debug/Chihiro Range |
---|---|---|
Main Memory | 0x00000000 - 0x03FFFFFF | 0x00000000 - 0x07FFFFFF |
Shadow RAM | 0xF0000000 - 0xF3FFFFFF | 0xF0000000 - 0xF7FFFFFF |
GPU (NV2A) Registers | 0xFD000000 - 0xFDFFFFFF | |
APU Registers | 0xFE800000 - 0xFE87FFFF | |
ACI (AC97) Registers | 0xFEC00000 - 0xFEC00FFF | |
USB 0 Registers | 0xFED00000 - 0xFED00FFF | |
USB 1 Registers | 0xFED08000 - 0xFED08FFF | |
NIC (NVNet) Registers | 0xFEF00000 - 0xFEF003FF | |
Flash ROM | 0xFF000000 - 0xFFFFFFFF | |
MCPX ROM | 0xFFFFFE00 - 0xFFFFFFFF | N/A |
I/O port map
[FIXME]
Device | Retail Xbox Range | Debug/Chihiro Range |
---|---|---|
DMA Channels 0-3 | 0x0000 - 0x000F | |
Master PIC | 0x0020 - 0x0021 | |
Super I/O Configuration | N/A | 0x002E - 0x002F |
PIT | 0x0040 - 0x0043 | |
A20 Gate / Speaker | 0x0060 - 0x006F | |
CMOS / RTC | 0x0070 - 0x0073 | |
DMA Page Address | 0x0080 - 0x008F | |
Slave PIC | 0x00A0 - 0x00A1 | |
DMA Channels 4-7 | 0x00C0 - 0x00DF | |
FPU Error Control | 0x00F0 - 0x00F1 | |
IDE | 0x01F0 - 0x01F7 | |
vesafb [FIXME] | 0x03C0 - 0x03DF | |
IDE [FIXME] | 0x03F6 - 0x03F6 | |
Super I/O Serial | N/A | 0x03F8 - 0x03FF |
PCI Configuration | 0x0CF8 - 0x0CFF | |
SMBus (I2C) | 0x1000 - 0x100F | |
Modem (MC97) | 0x1080 - 0x10FF | |
0x1400 - 0x14FF | ||
LPC PM | 0x8000 - 0x80FF | |
SMBus (I2C) | 0xC000 - 0xC00F | |
0xC200 - 0xC21F | ||
ACI (AC97) | 0xD000 - 0xD0FF | |
0xD200 - 0xD27F | ||
NIC (NVNet) | 0xE000 - 0xE007 | |
IDE | 0xFF60 - 0xFF6F |
Emulation
Code for emulating the memory might consist of:
#ifdef DEBUG || CHIHIRO #define MEMORY_SIZE 128 * 1024 * 1024 int mcpx_active = 0; #else #define MEMORY_SIZE 64 * 1024 * 1024 int mcpx_active = 1; #endif #define FLASH_SIZE 256 * 1024 #define FLASH_MAP_SIZE 16 * 1024 * 1024 #define FLASH_MAP_ADDRESS (0xFFFFFFFF - FLASH_MAP_SIZE + 1) #define MCPX_SIZE 0x200 #define MCPX_MAP_ADDRESS (0xFFFFFFFF - MCPX_MAP_SIZE + 1) uint8_t memory[MEMORY_SIZE] = {0}; uint8_t flash[FLASH_SIZE] = {0}; uint8_t mcpx[MCPX_SIZE] = {0}; uint8_t get_memory_byte(uint32_t location) { if (location < MEMORY_SIZE) { return memory[location]; } if (mcpx_active && location >= MCPX_MAP_ADDRESS) { return mcpx[location - MCPX_MAP_ADDRESS]; } if (location >= FLASH_MAP_ADDRESS) { return flash[(location - FLASH_MAP_ADDRESS) % FLASH_SIZE]; } printf("Memory in unspecified range: %08X\n", location); return 0; } uint16_t get_memory_word(uint32_t location) { return get_memory_byte(location + 1) << 8 | get_memory_byte(location); } uint32_t get_memory_dword(uint32_t location) { return get_memory_word(location + 2) << 16 | get_memory_word(location); } void deactivate_mcpx() { mcpx_active = 0; }