psx.wiki
Log in
Main page
Hardware
Hardware tests
System software
SDKs
File formats
Games
Tools
History
All pages
page
view source
history
View source for Memory Control
← Memory Control
You do not have permission to edit this page.
Log in
to edit.
--- title: Memory Control type: register summary: Bus timing, region size and RAM configuration registers of the CPU bus. category: Hardware --- ## Summary The memory control registers set the base address, size, bus width and access timing of each device on the CPU bus, and the layout of main RAM. The BIOS initializes them at boot, and software normally leaves them unchanged. Expansion hardware is the exception, since a larger memory window or a 16-bit data bus is selected here.[^mc] The registers are listed below. The [I/O map](/hardware/io-map/) shows them with the rest of the I/O ports, and the [memory map](/hardware/memory-map/) shows the regions they control. Table: Memory control registers | Address | Name | Usual value | Device | | --- | --- | --- | --- | | 1F801000h | DEV0 base address | 1F000000h | DEV0 (PIO) | | 1F801004h | DEV8 base address | 1F802000h | DEV8 (debug) | | 1F801008h | DEV0_DELAY | 0013243Fh | DEV0 (PIO), 512 KB, 8-bit bus | | 1F80100Ch | DEV1_DELAY | 00003022h | DEV1 (debug), 1 byte | | 1F801010h | DEV2_DELAY | 0013243Fh | DEV2 (BIOS ROM), 512 KB, 8-bit bus | | 1F801014h | DEV4_DELAY | 200931E1h | DEV4 (SPU) | | 1F801018h | DEV5_DELAY | 00020843h or 00020943h | DEV5 (CD-ROM) | | 1F80101Ch | DEV8_DELAY | 00070777h | DEV8 (debug), 128 bytes, 8-bit bus | | 1F801020h | COM_DELAY | 00031125h, 0000132Ch or 00001325h | Common delay values | | 1F801060h | DRAM_CTRL | 00000B88h | Main RAM | | FFFE0130h | BCC | | BIU and cache configuration | psx-spx marks the names DEV0_ADDR and DEV8_ADDR as unofficial.[^io] ## 1F801000h - DEV0 Base Address Bits 0 to 23 of the register hold the base address of the DEV0 region, and bits 24 to 31 always read 1Fh. The hardware aligns the base to the region size by masking off the low N bits, where N is the number of address lines set in DEV0_DELAY. With 8 address lines the values 1F000000h and 1F0000FFh therefore select the same base.[^mc0] A PIO DMA transfer is the exception to this masking, because it puts every bit of the register on the bus whatever the region size. The Konami System 573 relies on this when it sets the base to 1F480000h to read its IDE CD-ROM by DMA.[^mc0] ## 1F801004h - DEV8 Base Address The DEV8 base address register has the same layout. However, DEV8 works only at 1F802000h, and any other value appears to disable the region instead of moving it. The DEV1 region has no base address register and is fixed at 1FA00000h.[^mc8] ## Delay/Size Registers The six registers from 1F801008h to 1F80101Ch share one layout. Each sets the read and write delay of its device and the optional bus phases taken from COM_DELAY. It also sets the bus width and the size of the memory window. The bits are shown below:[^mcd] Table: DEVn_DELAY bits | Bits | Content | | --- | --- | | 0 to 3 | Write delay (00h to 0Fh = 1 to 16 cycles) | | 4 to 7 | Read delay (00h to 0Fh = 1 to 16 cycles) | | 8 | Recovery period (1 = use COM0 timing) | | 9 | Hold period (1 = use COM1 timing) | | 10 | Floating period (1 = use COM2 timing) | | 11 | Pre-strobe period (1 = use COM3 timing) | | 12 | Data bus width (0 = 8 bits, 1 = 16 bits) | | 13 | Auto increment (0 = no, 1 = yes) | | 14 to 15 | Unknown (R/W) | | 16 to 20 | Number of address bits (window size = 1 << N bytes) | | 21 to 23 | Unknown (always zero) | | 24 to 27 | DMA timing override | | 28 | Address error flag (write 1 to clear) | | 29 | DMA timing select (0 = normal timing, 1 = use bits 24 to 27) | | 30 | Wide DMA (0 = use bit 12, 1 = full 32 bits) | | 31 | Wait (1 = wait on the external device before ready) | At reset every delay register holds the maximum read and write delay. The first instruction of the BIOS therefore writes 0013243Fh to DEV2_DELAY to speed up its own ROM, and the next writes 00000B88h to DRAM_CTRL. A logic analyzer shows the faster ROM timing taking effect two instructions after the store.[^mcd] Read and write delays are separate values. The default DEV0 write delay is 16 cycles, the slowest setting, so a program that writes to a flash chip on DEV0 should shorten it. With the low 16 bits at zero a single byte access takes 3 CPU cycles, which is the fastest a device can run.[^mcd] ### Bus Phases The /CS signal always goes active at least one cycle before /WR or /RD. The four optional periods add cycles between the events of a read or write as shown below:[^mcd] Table: Bus timing periods | Period | Effect | | --- | --- | | Pre-strobe | Delay between setting the data bus and /CS going active | | Hold | Keeps the data on the bus after /WR goes inactive and before /CS goes inactive | | Floating | Keeps the bus floating after /RD goes inactive and before /CS goes inactive | | Recovery | Delay between two operations | ### Bus Width and Auto Increment The data bus width decides how the CPU splits a 32-bit access. On an 8-bit bus it issues 4 byte accesses and on a 16-bit bus 2 halfword accesses. /CS stays active for the whole sequence while /RD or /WR strobes once per part. When auto increment is set the address increments between the parts. When it is clear, a word read takes 4 bytes from one address into the 4 bytes of the register, which is slightly faster than 4 byte reads.[^mcd] ### DMA Timing Bits 24 to 27 replace the access timing during DMA, but only when bit 29 is set. Wide DMA makes a DMA transfer 32 bits wide by using the low 16 address lines as the high 16 data bits. During a wide DMA read those address lines are therefore inputs.[^mcd] ### Region Size An access past the selected window size raises a bus exception. The largest usable sizes are shown below. A larger setting overlaps the internal I/O ports and crashes the PlayStation.[^mcd] Table: Maximum region sizes | Region | Maximum N | Size | | --- | --- | --- | | DEV0 | 17h | 8 MB | | DEV2 (BIOS ROM) | 16h | 4 MB | | DEV8 | 0Dh | 8 KB | | DEV1 | 15h | 2 MB | The SPU and CD-ROM appear to ignore the size bits. The SPU timing applies both to the 200h-byte SPU region at 1F801C00h and to the 200h-byte region at 1F801E00h. psx-spx gives 220931E1h as the DEV4_DELAY value for reads from SPU RAM.[^mcd] ## 1F801020h - COM_DELAY COM_DELAY holds the cycle counts that a delay register adds to its access time when it selects a bus phase. Bits 16 to 31 always read 0000h.[^mcc] Table: COM_DELAY bits | Bits | Content | | --- | --- | | 0 to 3 | COM0, recovery period cycles | | 4 to 7 | COM1, hold period cycles | | 8 to 11 | COM2, floating release cycles | | 12 to 15 | COM3, strobe active-going edge delay | | 16 to 31 | Unused (reads 0000h) | psx-spx gives the following approximate formula for the first access time (1ST) and the time of each further sequential access (SEQ). A 32-bit access on an 8-bit bus therefore takes 1ST + 3 x SEQ cycles. Code that runs from uncached RAM adds another 0 to 4 cycles.[^mcc] ``` 1ST=0, SEQ=0, MIN=0 IF Use_COM0 THEN 1ST=1ST+COM0-1, SEQ=SEQ+COM0-1 IF Use_COM2 THEN 1ST=1ST+COM2, SEQ=SEQ+COM2 IF Use_COM3 THEN MIN=COM3 IF 1ST<6 THEN 1ST=1ST+1 1ST=1ST+AccessTime+2, SEQ=SEQ+AccessTime+2 IF 1ST<(MIN+6) THEN 1ST=(MIN+6) IF SEQ<(MIN+2) THEN SEQ=(MIN+2) ``` ## 1F801060h - DRAM_CTRL DRAM_CTRL configures the main RAM controller: refresh, wait states, the wiring of the byte strobes and the size of the two RAM banks. Its usual value is 00000B88h.[^mcr] Table: DRAM_CTRL bits | Bits | Content | | --- | --- | | 0 to 2 | Refresh hold-off during DMA (0 = none, 1 to 6 = 4 << (N-1) cycles, 7 = unlimited) | | 3 | /CAS and /WE wiring (0 = common /CAS with per-byte /WE, 1 = per-byte /CAS with common /WE) | | 4 to 5 | Refresh period (256 + 64 x N cycles) | | 6 | Unknown | | 7 | Consecutive access wait state (0 = none, 1 = 1 cycle) | | 8 | /RAS1 bank size bit 1 | | 9 | /RAS0 bank size bit 1 | | 10 | Enable /RAS1 bank (0 = bus fault on access) | | 11 | Bank size bit 0 (both banks) | | 12 to 15 | Unknown | | 16 to 31 | Unused | ### RAM Banks Main RAM is two banks, and the /RAS1 bank is placed directly after the /RAS0 bank. Each bank is 1, 2, 4 or 8 MB, and the size follows from bits 8, 9 and 11 as shown below. The controller picks the bank from the address bit just above the /RAS0 size: A20 for 1 MB, A21 for 2 MB, A22 for 4 MB and A23 for 8 MB. An access to the unmapped rest of the 16 MB raises an exception.[^mcr] ``` /RAS0 size = 1MB << ((DRAM_CTRL.9 << 1) | DRAM_CTRL.11) /RAS1 size = 1MB << ((DRAM_CTRL.8 << 1) | DRAM_CTRL.11) ``` For two banks of equal size bits 8 to 11 give the following layouts:[^mcr] Table: Bank layouts | Bits 8 to 11 | Layout | | --- | --- | | 0000 | 1 MB on /RAS0 | | 0011 | 4 MB on /RAS0 | | 0100 | 1 MB on /RAS0 and 1 MB on /RAS1 | | 0111 | 4 MB on /RAS0 and 4 MB on /RAS1 | | 1000 | 2 MB on /RAS0 | | 1011 | 8 MB on /RAS0 | | 1100 | 2 MB on /RAS0 and 2 MB on /RAS1 | | 1111 | 8 MB on /RAS0 and 8 MB on /RAS1 | ### Refresh and Wait States Bits 0 to 2 set how long a refresh may wait while the controller serves a DMA transfer. The default of 0 makes DMA yield to a refresh at once, while instruction fetches and data accesses appear unaffected.[^mcr] Bit 7 inserts an idle cycle between two consecutive RAM accesses, refreshes included, but not between the words of a DMA or instruction fetch burst. Clearing it makes many games hang during CD-ROM loading on EARLY-PU-8 and LATE-PU-8 boards, although PU-18 and later boards work. Bit 3 exists only in later CPU revisions and has no effect on the DTL-H2700.[^mcr] ### BIOS Values The BIOS writes a value that depends on the board:[^mcr] Table: DRAM_CTRL values written by the BIOS | Board | Value | RAM | Correct value | | --- | --- | --- | --- | | PU-7, EARLY-PU-8 | 0B80h | One 2 MB bank of four 512K x 8 chips, byte masking by /WE | 0880h | | Later retail boards | 0B88h | One 2 MB bank of one 512K x 32 chip, byte masking by /CAS | 0888h | | DTL-H2000, DTL-H2500, DTL-H2700 | 0B88h | One 8 MB bank of four 2M x 8 chips, byte masking by /CAS | 0B88h | On retail boards the BIOS value describes an 8 MB bank, although only 2 MB is fitted. The 2 MB of RAM therefore appears 4 times in the first 8 MB. Puzzle Bobble and Gundam Battle Assault 2 rely on these mirrors, often because a stack was left at 807FFFxxh instead of 801FFFxxh. Wipeout calls the SetMem() BIOS function to set the bank to 2 MB.[^mcr] ## FFFE0130h - BCC BCC is the BIU/cache configuration register of the CW33300 CPU core. Its layout is documented in chapter 14 of the LSI L64360 datasheet, which includes the LR33300 control registers.[^mcb] Table: BCC bits | Bits | Name | Content | | --- | --- | --- | | 0 | LOCK | Cache lock mode (when SR.IsC = 1) | | 1 | INV | Cache invalidation mode (when SR.IsC = 1) | | 2 | TAG | Cache tag test mode (when SR.IsC = 1), used to flush the I-cache | | 3 | RAM | Scratchpad mode (usually 1) | | 4 to 5 | DBLKSZ | Data cache refill size (usually 0, no effect) | | 6 | | Always 0 (R) | | 7 | DS | Data cache enable (usually 1; 0 disables the scratchpad) | | 8 to 9 | IBLKSZ | I-cache refill size (0 = 2 words, 1 = 4 words, 2 and 3 crash) | | 10 | IS0 | Always 0 (R) | | 11 | IS1 | I-cache enable | | 12 | INTP | Interrupt polarity (usually 0) | | 13 | RDPRI | Read priority (usually 1) | | 14 | NOPAD | No wait state (usually 1) | | 15 | BGNT | Bus grant (usually 1) | | 16 | LDSCH | Load scheduling (usually 1) | | 17 | NOSTR | No streaming (usually 0) | | 18 to 31 | | Reserved (R/W) | ### Cache Tag Writes When TAG is set in BCC and IsC is set in the COP0 SR register, a store writes the I-cache tag memory instead of RAM. The stored tag is (data AND 0Fh) OR (offset AND FFFFF000h), so the low 4 data bits become the valid bits of the 4 words in the line and the address part comes from the store offset. A store of 0 at each line base (line x 16) therefore invalidates the line and leaves its code words unchanged.[^mcb] A load in TAG mode returns the valid bits in bits 0 to 3 and a tag match flag in bit 4. Bits 5 to 31 hold leftover code data, so these loads are of use for diagnostics only.[^mcb] ### Cache Flush The BIOS flushes the I-cache with the sequence below. It first clears every tag, then clears every code word, and then restores the normal BCC and SR values.[^mcb] ```c uint32_t sr = COP0_SR; BCC = TAG | IS1; COP0_SR = IsC; for (int i = 0; i < 0x1000; i += 16) // clear one tag per 4-word line *((volatile uint32_t *) i) = 0; COP0_SR = 0; BCC = IS1; COP0_SR = IsC; for (int i = 0; i < 0x1000; i += 4) // clear the code words *((volatile uint32_t *) i) = 0; for (int i = 0; i < 8; i++) *((volatile uint32_t *) 0xa0000000); COP0_SR = 0; BCC = RAM | DS | IBLKSZ_4 | IS1 | RDPRI | NOPAD | BGNT | LDSCH; COP0_SR = sr; ``` TOCA World Touring Cars (SLES-02572) flushes the cache with its own code from uncached RAM instead of calling the BIOS function.[^mcb] ### Scratchpad Mode Clearing bit 3 unmaps the scratchpad and turns it into a data cache. The data cache has no tag memory, however, so CPU loads update its contents but no cache hit ever occurs. Bits 4 and 5 appear to have no effect, and the CPU always reads data from RAM one word at a time.[^mcb] ## References [^mc]: psx-spx. Memory Control. https://psx-spx.consoledev.net/memorycontrol/ [^io]: psx-spx. I/O Map, System Bus Interface. https://psx-spx.consoledev.net/iomap/ [^mc0]: psx-spx. Memory Control, 1F801000h - DEV0 Base Address. https://psx-spx.consoledev.net/memorycontrol/ [^mc8]: psx-spx. Memory Control, 1F801004h - DEV8 Base Address. https://psx-spx.consoledev.net/memorycontrol/ [^mcd]: psx-spx. Memory Control, 1F801008h to 1F80101Ch - Delay/Size. https://psx-spx.consoledev.net/memorycontrol/ [^mcc]: psx-spx. Memory Control, 1F801020h - COM_DELAY. https://psx-spx.consoledev.net/memorycontrol/ [^mcr]: psx-spx. Memory Control, 1F801060h - DRAM_CTRL. https://psx-spx.consoledev.net/memorycontrol/ [^mcb]: psx-spx. Memory Control, FFFE0130h - BCC, BIU/Cache Configuration Register. https://psx-spx.consoledev.net/memorycontrol/