Memory map

The memory map is currently:

0000Write A[7:0]Read A[7:0]
0001Write A[15:8]Read A[15:8]
0010Write A[23:16]Read A[23:16]
0011Write A[31:24]Read A[31:24]
0100Write LCD Row +0Read IRQ status
0101Write LCD Row +256Clear IRQ status
0110Write D[15:8]Read D[15:8]
0111Write IRQ maskRead IRQ mask
1000Write to SRAMRead from SRAM
1001Write to SDRAMRead from SDRAM
1010Write to SPIRead from SPI
1011Write to voice generatorRead from voice generator
1100Write to MMU + 0Read keys
1101Write to MMU + 256Read rotary encoder
1110Add to addressUnused
1111Write to CLUTUnused

Not all read operations are currently used - the two that aren't are reserved for future expansion (maybe a version number)

The first 8 addresses are for registers, and the last 8 addresses are for operations.

Notes on some of the registers

Here are some notes on the registers (address 4'b0xxx).


These are an internal memory address range - SRAM requires 19 bits, and SDRAM requres 25 bits. The unused bits are ignored.

The row and D[15:8] can influence the address (see later).


D[15:8] is used to provide additional bits for the SDRAM interface (which will only be 16-bit), so to write a value, you initially write to D[15:8], and then write to SDRAM - this combines the bits together. To read a value, you read from SDRAM, and then read D[15:8]


The display is implemented as an 8-bit indexed colour display, so each pixel consumes one byte.

Since there are 320 rows, two addresses are used for the rows - the first takes the data bus input, and sets the row to that value; the second takes the data bus input and adds 256 to it.

At the same time as the row command is issued, D[15:8] is stored at the low 8-bits.

This means that to fill a rectangle, all that needs to happen is that D[15:8] is written to in order to indicate the first column, and then the first row is set. The required number of pixels are written, and then the second row is set. This automatically reverts the address back to the start column.

Notes on the operations

Here are some notes on the operations (address 4'b1xxx).

Add to address

This takes the current data bus value, and sign extend adds it to the current address. So, if you write the value 0x01, then the address is incremented; using 0xff will decrement it.


The colour lookup table (CLUT) uses A[7:0] as the blue component, A[15:8] as green, and A[23:16] as red. The written date is the palette number to select.

Example code

Here is some example code for performing some of the operations.

Writing to an SDRAM address

void writeSD(long addr, short value)
  fpga_write(0x0, (addr >> 0));
  fpga_write(0x1, (addr >> 8));
  fpga_write(0x2, (addr >> 16));
  fpga_write(0x3, (addr >> 24));
  fpga_write(0x6, (value >> 8)); // Set D[15:8]
  fpga_write(0x9, (value >> 0)); // Write to memory

Note that the address is the number of short ints, rather than bytes. Also note that this is the logical address, rather than the physical (unless the MMU has been configured to be a linear set of numbers).

Copying data to SDRAM

void copyToSD(long addr, short* from, short shorts)
  fpga_write(0x0, (addr >> 0));
  fpga_write(0x1, (addr >> 8));
  fpga_write(0x2, (addr >> 16));
  fpga_write(0x3, (addr >> 24));
  while(shorts > 0)
    fpga_write(0x6, (*from >> 8))
    fpga_write(0x0, (*from >> 0));
    fpga_write(0xe, 1); // Increment address

Setting CLUT value

void setCLUT(BYTE red, BYTE green, BYTE blue, BYTE col)
  fpga_write(0x2, red);
  fpga_wirte(0x1, green);
  fpga_write(0x0, blue);
  fpga_write(0xf, col);

Example rectangle fill

Example code to do a rectangle fill would be:

void fillrect(int x0, int y0, int w, int h, int col)
  fpga_write(0x6, x0);            // Write D[15:8] (column)
    int x;

    if(y0 < 256)
      fpga_write(0x4, y0);        // Write to row y0 + 0;
      fpga_write(0x5, y0 & 0xff); // Write to row y0 + 256;
    for(x = w; x > 0; --x)
      fpga_write(0x8, col);       // Write to SRAM
      fpga_write(0xe, 1);         // Increment address
Updated: 2011-06-08 20:39:29 | Comments: 0 | Show comments | Add comment
© Copyright 2010 / / Jason Tribbeck
All trademarks are the property of their respective owners.