Memory

From xboxdevwiki
Revision as of 23:54, 24 May 2021 by X86corez (talk | contribs) (I/O port map: Remove overlapping ide0, minor corrections.)
Jump to: navigation, search

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
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]

Ports Purpose
0000-001f dma1
0020-003f pic1
0040-0043 timer0
0050-0053 timer1
0060-006f keyboard
0070-007f rtc
0080-008f dma page reg
00a0-00bf pic2
00c0-00df dma2
00f0-00ff fpu
01f0-01f7 ide0
03c0-03df vesafb
03f6-03f6 ide0
0cf8-0cff PCI conf1
1000-100f nVidia Corporation nForce PCI System Management
1080-10ff nVidia Corporation nForce MC'97 Modem (Intel 537)
1400-14ff nVidia Corporation nForce MC'97 Modem (Intel 537)
c000-c00f nVidia Corporation nForce PCI System Management (amd756-smbus)
c200-c21f nVidia Corporation nForce PCI System Management
d000-d0ff nVidia Corporation nForce AC'97 Audio
d200-d27f nVidia Corporation nForce AC'97 Audio
e000-e007 nVidia Corporation nForce Ethernet Controller
ff60-ff6f nVidia Corporation nForce IDE

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;
}