Appendix A

VRAM

Overview

I compiled these tables so that it would be easy to see what banks of VRAM could be used for which purposes. I hope this will be of help to those of you designing your 2D graphic engines or are wanting a more in depth coverage of the Nintendo DS VRAM. I hope they will be as useful to you as they continue to be for me.

Usually, using this appendix is just a two step process. Based on what you want to do, use the usage tables to figure out which VRAM banks are suited to the task. Next, check the layout tables to see if there exist any conflicts between bank memory locations and assignments. If there are no conflicts, you have successfully come up with a VRAM layout for what you want to do. Otherwise, simply go back to the usage charts to see if there are any alternative ways of doing what you want to do. If what you want to do still seems impossible, consider using the 3D hardware.

VRAM Usage

Notes and Precautions

In the tables, you’ll see some numbers. These numbers are called “usage index numbers.” The best usage index number is one: it matches perfectly for that particular task. Greater than one means a wasteful design. Less than one means that you won’t be able to complete the whole task. Individual VRAM banks may have a rating of less than one for any particular task, but when used in conjunction with another bank, those two banks both might be perfectly suited for that task.

For example, if we wanted to store tiles for 128 unique 16 color sprites, the best choice is to use two banks that each have a rating of less than one (.5), F and G. These two banks together sum to one, a perfect match for the task.

There are exceptions to the one is best rule, however. Keep in mind that if you want to double a task, as in you want two 16-bit color bitmaps for instance, you’ll want to sum your usage index number to two. Likewise, if you wanted 10 256 color external backgrounds (for whatever crazy reasons you may have), you’ll want to sum your usage index number to ten. Also note that if assigning leftover banks to auxiliary memory (LCD or Work RAM), a larger number simply gives you more memory, so the one is best rule doesn’t really apply for that table’s purposes.

Each bitmap in the table has a size of 256x256 and is at the specified color depth. If you need a larger bitmap, do the appropriate math to linearly transform the usage index numbers. For instance, a 512x512 16-bit color bitmap will take up 4 times as much memory as a 256x256 sized one. Thus, we multiply our usage numbers by .25 for that particular row, the 16-bit color bitmap row. We then see that it will take VRAM banks A, B, C, and D to meet our purpose. Likewise, if we wanted to do a smaller bitmap, we would multiply by a number larger than 1 for that particular row.

Just because the usage charts say that it is possible, make sure that you check the layout charts to be sure that using your specific combination of the banks is legal.

Main Screen Usage

VRAM BankABCDEFGHI
16-Bit Color Bitmap11110.50.1250.125N/AN/A
256 Color Paletted Bitmap2.662.662.662.661.330.660.66N/AN/A
128 Unique 256 Color Sprites22N/AN/A10.250.25N/AN/A
128 Unique 16 Color Sprites44N/AN/A20.50.5N/AN/A
Background Extended PaletteN/AN/AN/AN/A10.50.5N/AN/A
Object Extended PaletteN/AN/AN/AN/AN/A11N/AN/A

Sub Screen Usage

VRAM BankABCDEFGHI
16-Bit Color BitmapN/AN/A1N/AN/AN/AN/A0.250.125
256 Color Paletted BitmapN/AN/A2.66N/AN/AN/AN/A0.660.25
128 Unique 256 Color SpritesN/AN/AN/A2N/AN/AN/AN/A0.25
128 Unique 16 Color SpritesN/AN/AN/A4N/AN/AN/AN/A0.5
Background Extended PaletteN/AN/AN/AN/AN/AN/AN/A1N/A
Object Extended PaletteN/AN/AN/AN/AN/AN/AN/AN/A1

Auxiliary Memory Usage

VRAM BankABCDEFGHI
LCD (ARM9)111111111
Work RAM (Arm7)N/AN/A11N/AN/AN/AN/AN/A

Texture Usage

VRAM BankABCDEFGHI
Texture Image1111N/AN/AN/AN/AN/A
Texture PaletteN/AN/AN/AN/A10.250.25N/AN/A

VRAM Layout

Notes and Precautions

To use the layout charts, look for the VRAM bank you want to map and select a memory location to map it to. Depending on what you want to do, you’ll want to refer to the numbers listed under the usages. These numbers represent the offset you’ll need to use to access your VRAM bank.

For example, say we decided to use VRAM banks A and B to display a 16-bit color bitmap. We would look for VRAM banks A and B under the VRAM Banks column on the “Main Screen Background” table. After finding them, we notice that we can assign them to memory locations 0x0600:0000, 0x0602:0000, 0x0604:0000, and 0x0606:0000. We then choose to map VRAM bank A to 0x0600:0000 and VRAM bank B to 0x0602:0000. To access our 16-bit color bitmaps we use the offset of 0 for the first and 8 for the second. In the case of backgrounds, libnds provides the BG_BMP_BASE macro for use to use when setting up our backgrounds. In this case, some code we might use to set up BG2 and BG3 might look like the following.

  BG2_CR =
      BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);  // on the bottom
  BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY(0);  // on the top

Slots are not readable or writable by the ARM9 or the ARM7. No usage is necessarily implied on these tables, only layout in comparison to the sizes of relevant data.

Each bitmap in the table has a size of 256x256 and is at the specified color depth.

Main Screen Background

Memory Location16-Bit Color Bitmap256 Color Paletted BitmapVRAM Banks
0x0600:000000A,B,C,D,E,F,G
0x0600:400000F,G
0x0600:800000F,G
0x0600:C00003F,G
0x0601:000003F,G
0x0601:400003F,G
0x0601:800006F,G
0x0601:C00006F,G
0x0602:000086A,B,C,D,F,G
0x0602:400089F,G
0x0602:800089F,G
0x0602:C00089F,G
0x0603:0000812F,G
0x0603:4000812F,G
0x0603:8000812F,G
0x0603:C000815F,G
0x0604:00001615A,B,C,D
0x0604:40001615
0x0604:80001618
0x0604:C0001618
0x0605:00001618
0x0605:40001621
0x0605:80001621
0x0605:C0001621
0x0606:00002424A,B,C,D
0x0606:40002424
0x0606:80002424
0x0606:C0002428
0x0607:00002428
0x0607:40002428
0x0607:800024N/A
0x0607:C00024N/A

Main Screen Object

Memory Location128 Unique 256 Color Sprites128 Unique 16 Color SpritesVRAM Banks
0x0640:000000A,B,E,F,G
0x0640:400000F,G
0x0640:800002F,G
0x0640:C00002F,G
0x0641:000044F,G
0x0641:400044F,G
0x0641:800046F,G
0x0641:C00046F,G
0x0642:000088A,B,F,G
0x0642:400088F,G
0x0642:8000810F,G
0x0642:C000810F,G
0x0643:00001212F,G
0x0643:40001212F,G
0x0643:80001214F,G
0x0643:C0001214F,G

Main Screen Background Extended Palette

Background extended palette slots are 32KB each, despite which VRAM bank is assigned to them.

SlotVRAM Banks
0E,F,G
1E,F,G
2E,F,G
3E,F,G

Main Screen Object Extended Palette

Object extended palette slots are 8KB each, despite which VRAM bank is assigned to them.

SlotVRAM Banks
0F,G

Sub Screen Background

Memory Location16-Bit Color Bitmap256 Color Paletted BitmapVRAM Banks
0x0620:000000C,H
0x0620:400000
0x0620:800000I
0x0620:C00003
0x0621:000003
0x0621:400003
0x0621:80000N/A
0x0621:C0000N/A

Sub Screen Object

Memory Location128 Unique 256 Color Sprites128 Unique 16 Color SpritesVRAM Banks
0x0660:000000D,I
0x0660:400000
0x0660:800002
0x0660:C00002
0x0661:000044
0x0661:400044
0x0661:800046
0x0661:C00046

Sub Screen Background Extended Palette

Background extended palette slots are 32KB each, despite which VRAM bank is assigned to them.

SlotVRAM Banks
0H
1H
2H
3H

Sub Screen Object Extended Palette

Object extended palette slots are 8KB each, despite which VRAM bank is assigned to them.

SlotVRAM Banks
0I

Texture Palette

Texture palette slots are 64KB each.

SlotVRAM Banks
0E,F,G
1E,F,G
2E,F,G
3E
4F,G
5F,G

Texture Image

Texture image slots are 128KB each.

SlotVRAM Banks
0A,B,C,D
1A,B,C,D
2A,B,C,D
3A,B,C,D

ARM9 Access (LCD)

Memory LocationVRAM Banks
0x0680:0000A
0x0682:0000B
0x0684:0000C
0x0686:0000D
0x0688:0000E
0x0689:0000F
0x0689:4000G
0x0689:8000H
0x068A:0000I

ARM7 Access (Work RAM)

Memory LocationVRAM Banks
0x0600:0000C,D
0x0602:0000C,D