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