Display

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.

Usage #

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 as VRAM, which contains the image to be displayed on the screen. Each pixel is two bytes (16 bits), specifying a color. Because the location in memory of VRAM varies between calculator models, you should call GetVRAMAddress to get a pointer to VRAM. Some older programs use a macro that refers to a fixed address for VRAM; do not do this because your program will not work correctly on both the CG10/CG20 and CG50 calculators.

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 = GetVRAMAddress();
int i;
for (i = 0; i < LCD_WIDTH_PX; i++) *p++ = 0;
p += LCD_WIDTH_PX * (LCD_HEIGHT_PX - 1);
for (i = 0; i < LCD_WIDTH_PX; i++) *--p = 0;

Optimization #

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.

Color #

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 r615091. As explained before, the LCD itself is 396×224 with an inner 384×216 region (window) primarily used.

Differences Between r61509 #

TODO

Hardware Revisions #

So far, Casio has used three different LCD controllers on Prizm calculators:

The 001V04 revision is known to be compatible with the old 3A36-2 controller, as can be seen on a calculator that went under repair and had its 001V03 board replaced with a 001V04 one, while keeping the previous LCD hardware.