The C64 OS Programmer's Guide is being written

This guide is being written and released and few chapters at a time. If a chapter seems to be empty, or if you click a chapter in the table of contents but it loads up Chapter 1, that's mostly likely because the chapter you've clicked doesn't exist yet.

Discussion of development topics are on-going about what to put in this guide. The discusssions are happening in the C64 OS Community Support Discord server, available to licensed C64 OS users.

C64 OS PROGRAMMER'S GUIDE

Library Reference: gfx.lib

Overview

gfx.lib is used in conjunction with the service KERNAL module and with image datatype loaders to enable system-level support for splitscreen and fullscreen graphics modes.

Your Application provides a graphics context struct which holds properties that describe the video mode and pointers to where elements of the graphics data can be found. Datatype loaders may optionally be used to load data from a variety of file formats, allocate memory, and populate the graphics context for you. The graphics context is installed by passing it to the setgfx KERNAL routine. The call to setgfx returns immediately if gfx.lib has not already been loaded.

If gfx.lib has been installed, setgfx reads properties from the graphics context and calls routines in the library that set it up. The gfx.lib itself implements the routines for sustaining splitscreen, which can be activated either programmatically or by the user dragging the status bar. And it implements the routines for switching into and out of fullscreen graphics modes. Changes to the video mode are performed synchronously with the raster beam. The changes you want are set in redrawflgs and himemuse and split workspace memory variables. The gfx.lib observes changes in these variables and affects the video mode changes at the appropriate time.

Name gfx.lib
code gf
size 3 pages
Link Yes
Unlink Yes
Emits Memory Warnings No

Related KERNAL modules

Library Routines


Link and Unload

When this library is linked to the KERNAL it also installs itself into the workspace memory variable for the graphics library, gfxlibpg. It also backs up the address of the IRQ Service Routine (ISR). During the main ISR, if gfxlibpg is set, it calls procgfx, this may replace the system's interrupt handler with gfx.lib's own custom ISR. After the custom ISR executes and performs video mode changes it restores the system's default ISR from the backup. This cycle repeats ad infinitum.

;Defined in //os/h/:gfx.h

gfxlibpg = $08ca

It is critically important to use the slunload flag when unloading gfx.lib. This closes the splitscreen, restores the system's default interrupt service handler, unintalls gfx.lib from gfxlibpg, and explicitly switches the video mode back to the standard text-mode UI.

Process Graphics Modes (procgfx_)

Purpose Process graphics and splitscreen modes
Jump offset $06
Communications registers None
Stack requirements 8+
Zero page usage $3f, $40
Registers affected A, X, Y
Input parameters None
Output parameters None

Description: You should never call procgfx manually. This routine is called automatically by the system's interrupt service routine.

procgfx handles entering and exiting fullscreen graphics mode.

If the hmembitm bit of himemuse is unset, splitscreen mode is automatically collapsed and fullscreen mode is automatically reverted to the standard text-mode UI.

;Defined in //os/s/:service.s

himemuse = $03fe

Adjusting splitscreen split position

procgfx handles the technical aspects of the position of the splitscreen's split and updates video memory necessary to draw the screen correctly. You can programmatically set the workspace variable split to any value from screen_rows minus 1 (i.e., 24) to 1. (split should not be set less than 1. Entering fullscreen graphics mode is described next.)

gfx.lib records where the split was positioned last in lastsplt, and if split is ever different from lastsplt, either higher or lower, the necessary adjustments are made to move the split to the new position. If split is set to screen_rows minus 1, the split is closed and the raster interrupt service routines stop alternating until the split is opened again.

The split position can be adjusted by the user by dragging the status bar. Dragging the status bar is implemented by the menu KERNAL module. The only thing dragging the status bar does is set the position of split. It is procgfx of gfx.lib that performs the actual splitscreen adjustments.

;Defined in //os/s/:screen.s

split    = $3f
lastsplt = $40

Enter and exiting fullscreen grahpics mode

Entering and exiting fullscreen graphics mode can be accomplished by setting or clearing, respectively, the renagfx bit of the redrawflgs workspace variable.

procgfx observes these bit changes and performs the transition into and out of fullscreen graphics mode, synchronized with the screen refresh.

;Defined in //os/s/:service.s

redrawflgs = $03ff ;Redraw Active Flags
renagfx    = %00000010 ;Enable Full GFX

Update graphics data or mode

It will sometimes happen that graphics data is already installed, and while the splitscreen is open or fullscreen graphics mode is enabled new graphics data becomes available. In order to update the appropriate buffers, you must inform gfx.lib that the graphics data has changed. Set the rnewgfx bit of the redrawflgs workspace variable.

procgfx observes these bit changes and performs the low-level updates to the color and screen matrix memory. Bitmap data must be manually installed by your Application to the bitmap memory area.

;Defined in //os/s/:service.s

redrawflgs = $03ff ;Redraw Active Flags
rnewgfx    = %00000001 ;New GFX data

;Defined in //os/s/:io.s

bmapmem    = $e000 ;$ff3f


Configure Graphix (confgfx_)

Purpose Configure the graphics handlers with mode bits and pointers
Jump offset $09
Communications registers A, X, Y
Stack requirements 2
Zero page usage None
Registers affected A, X, Y
Input parameters A → Multicolor Mode VIC-II flags ($D016)
Y → Bitmap Mode VIC-II flags ($D011)
X → Border Color << 4 | Background Color
Output parameters RegPtr ← Color update callback vector address

Description: This routine should never be called directly. This routine is called by the KERNAL routine setgfx.

Load a RegPtr to your graphics context structure and then call setgfx. If the gfx.lib is not installed, this returns immediately and does nothing. If the gfx.lib is installed it proceeds and performs a number of important steps.

First it quits any currently running Utility. Then it copies screen matrix and color memory pointers from the graphics context and writes them into workspace memory. Next, it takes mode settings from the graphics context and uses them to look up VIC-II register bits. Then it calls confgfx in the gfx.lib for you.

The border color and background color are stored in the graphics context in the upper and lower nybbles of one byte, these are passed by setgfx into confgfx. Support for border color was added to gfx.lib in C64 OS v1.08.

The himemuse workspace variable is updated to indicate that high memory is now being used by bitmap graphics data. And a message (mc_hmem) is sent to the Application to inform it that himemuse has changed.

Bitmap and color synchronization

The library routine confgfx returns a vector for a callback for when color memory is updated. The KERNAL routine setgfx returns this vector in a RegPtr. By default, this vector is pointed to raw_rts.

Your Application is responsible for copying or writing bitmap data into the bitmap graphics area, and updating the bitmap graphics data when it changes. The screen matrix memory and color memory are buffered in main memory. The graphics context has pointers to the screen matrix and color memory buffers. Bitmap graphics may be buffered in main memory, if you have the space, or may be held exclusively in the bitmap memory area if main memory is limited. And of course may also be held in an REU if an REU is available.

When bitmap graphics change, you notify the gfx.lib by setting the rnewgfx bit on the redrawflgs. But this doesn't update the screen matrix or color data immediately. They are updated synchronously with the raster interrupt.

When the color memory is updated, at the start of the next frame, the color update vector is jumped through. By changing the vector to point at your own routine, this allows you to synchronize changes to the bitmap data with changes to the color data, which synchronizes both with the raster.

How is this used in practice. The color update vector was originally introduced for Image Viewer to implement animations and matrix images which change the bitmap graphics quickly and in response to user input such as dragging the mouse. The screen matrix and color data are first changed in the buffers, then the rnewgfx bit on the redrawflgs is set. Then, asynchronously from the user interface code, the gfx.lib's raster interrupt updates the screen matrix and color memory from the buffers, jumps through the vector, to a routine implemented by Image Viewer which orders the REU to update the bitmap graphics.

Without this synchronization, if you updated the bitmap data immediately, but the color data doesn't get updated until the start of the next frame, you would see one frame or one partial frame where the bitmap and color data don't align.

If you stop using the color update vector you must restore it to point to raw_rts

;Defined in //os/s/:service.s

raw_rts  = $02b2 

Graphics context

For an overview of the graphics context and its constants see Chapter 4: Using the KERNAL → KERNAL Modules → Service → setgfx.

The base graphics context is used by setgfx and confgfx, and it does not have a pointer to the bitmap data, and neither the KERNAL nor the gfx.lib is responsible for moving the bitmap data.

However, there is an extended graphics context which adds a pointer to a bitmap graphics buffer. The extended graphics context is used only by image datatype loaders and savers, and allows them to manage memory and load and save bitmap graphics from different file formats for you. Your routines may read data from the extended graphics context to help you move and manage the bitmap data once its in memory. But the KERNAL and graphics library don't use or require the extended graphics context.


Previous Section: Library Reference


Next Chapter: Using Toolkit

Table of Contents



This document is subject to revision updates.

Last modified: May 22, 2025