From WikiPrizm
Revision as of 18:43, 10 February 2015 by Gbl08ma (talk | contribs) (Add paragraph on non-blocking DMA)
Jump to navigationJump to search

This page has not been completed. Parts may be missing or reorganized before completed. Information is provided as-is and may have errors.

The Prizm has a 396×224 LCD, with a central region of 384×216 pixels available for use in your own programs. There are some syscalls to set the color of the screen's border, but the OS only displays content in the more-or-less central 384×216-pixel region, and the syscalls reflect this.


Most (all?) of the needed definitions are in fxcg/display.h.

Most developers prefer to treat the calculator's display as if it were memory-mapped and double-buffered. There is a 162-kilobyte buffer in RAM which we refer to a VRAM, which contains the image to be displayed on the screen. Each pixel is two bytes (16 bits), specifying a color.

To write the contents of VRAM to the display, call Bdisp_PutDisp_DD. There are some syscalls that interface directly with the LCD (bypassing VRAM), such as Bdisp_SetPoint_DD.

VRAM is written in row-major order. The following snippet of code would draw two horizontal black lines at the top and bottom of the display:

#include <fxcg/display.h>

unsigned short *p = VRAM;
int i;

for (i = 0; i < LCD_WIDTH_PX; i++) *p++ = 0;
for (i = 0; i < LCD_WIDTH_PX; i++) *--p = 0;


It is significantly faster to access VRAM (and any memory) in larger chunks. Since the above routine doesn't need to work on individual pixels, it could be optimized by writing 32 bits at a time by changing the type of p to unsigned int * (and changing the limits of iteration accordingly). In nearly all cases, it is desirable to address VRAM in 16-bit chunks (as done above) rather than single bytes. Using longer data types (such as long long) will not offer any further benefit however, as the calculator's processor can only access 32 bits at a time.

As explained above, writing the VRAM to the LCD is typically done using Bdisp_PutDisp_DD. This syscall uses the DMA controller on the SH7305 to perform the operation faster, however, it blocks while the transfer is not complete, which pretty much wastes the benefit of using DMA. To circumvent this restriction, one can use custom code to perform the same action, but allowing for useful calculations to occur while the screen is being drawn. One example of such code can be found on Non-blocking_DMA.


When an add-in is started, the display is in a reduced-color mode. To set it to full 16-bit color depth, use Bdisp_EnableColor.

The exact color format used is 5-6-5 RGB, meaning the red and blue channels are 5 bits each, and the green is 6 bits. The following function will extract the red, green, and blue components from a 16-bit input and return them individually as 6-bit values:

void extractColor(unsigned short x, char *r, char *g, char *b) {
    *b = (x & 0x1F) << 1;
    *g = (x >> 5) & 0x2F;
    *r = ((x >> 11) & 0x1F) << 1;

The header, color.h, contains a color_t definition (just an unsigned short), as well as some color definitions starting with COLOR_. It is preferred you use those constants rather than literals if possible, as well as the color_t type rather than unsigned short.

LCD Hardware

The LCD included in the fx-CG10 and fx-CG20 uses a Renesas 61524 LCD controller with similar functionality as the r61509[1]. As explained before, the LCD itself is 396×224 with an inner 384×216 region (window) primarily used.

Differences Between r61509


Hardware Revisions

The LCD controller hardware has changed with the hardware revision 001V04. The red is no longer too close to pink. The new main board is compatible with the old controller, as can be seen on a calculator that went under repair and had its main board replaced with one of the newer version, while keeping the previous LCD hardware.


  1. r61509 PDF manual, archived