Difference between revisions of "Memory"

From xboxdevwiki
Jump to: navigation, search
(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 (and the motherboard has empty spots where these could have been) but no games took advantage of it. The debug Xbox and the Chihiro both contained 128MB 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 [[BIOS]] and [[MCPX ROM]] are also mapped to memory at the top 16MB and the top 512bytes respectively. On Debug Xboxs and Chihiro, only the BIOS is mapped.
+
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 - 0x04000000
+
|0x00000000 - 0x03FFFFFF
|0x00000000 - 0x08000000
+
|0x00000000 - 0x07FFFFFF
 
|-
 
|-
|BIOS
+
|Shadow RAM
|0xFF000000 - 0xFFFFFFFF
+
|0xF0000000 - 0xF3FFFFFF
|0xFF000000 - 0xFFFFFFFF
+
|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 MAIN_MEMORY 128 * 1024 * 1024
+
#define MEMORY_SIZE 128 * 1024 * 1024
 
int mcpx_active = 0;
 
int mcpx_active = 0;
 
#else
 
#else
#define MAIN_MEMORY 64 * 1024 * 1024
+
#define MEMORY_SIZE 64 * 1024 * 1024
 
int mcpx_active = 1;
 
int mcpx_active = 1;
 
#endif
 
#endif
  
#define BIOS_SIZE 256 * 1024
+
#define FLASH_SIZE 256 * 1024
#define BIOS_MEMORY_SIZE 16 * 1024 * 1024
+
#define FLASH_MAP_SIZE 16 * 1024 * 1024
#define BIOS_MEMORY (0xFFFFFFFF - BIOS_MEMORY_SIZE + 1)
+
#define FLASH_MAP_ADDRESS (0xFFFFFFFF - FLASH_MAP_SIZE + 1)
 +
 
 
#define MCPX_SIZE  0x200
 
#define MCPX_SIZE  0x200
#define MCPX_MEMORY (0xFFFFFFFF - MCPX_SIZE + 1)
+
#define MCPX_MAP_ADDRESS (0xFFFFFFFF - MCPX_MAP_SIZE + 1)
  
uint8_t memory[MAIN_MEMORY] = {0};
+
uint8_t memory[MEMORY_SIZE] = {0};
uint8_t bios[BIOS_SIZE] = {0};
+
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 < MAIN_MEMORY) {
+
     if (location < MEMORY_SIZE) {
 
         return memory[location];
 
         return memory[location];
 
     }
 
     }
  
     if (mcpx_active && location >= MCPX_MEMORY) {
+
     if (mcpx_active && location >= MCPX_MAP_ADDRESS) {
         return mcpx[location - MCPX_MEMORY];
+
         return mcpx[location - MCPX_MAP_ADDRESS];
 
     }
 
     }
  
     if (location >= BIOS_MEMORY) {
+
     if (location >= FLASH_MAP_ADDRESS) {
         return bios[(location - BIOS_MEMORY) % BIOS_SIZE];
+
         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 get_memory(location + 1) << 8 | get_memory(location);
+
     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;
}