Web64 logo Web64 Documentation Web64 C Compiler User Manual

Web64 C Compiler User Manual

Version: 2026-07-27

Copyright (c) 2026 Mika Jussila, Siteledger Solutions Oy

This manual separates the Web64 C compiler and SDK reference from the broader IDE manual. The larger IDE workflow context remains in Web64 IDE User Manual.

Web64 C compiler and virtual headers

The standalone compiler manual lives at Web64 C Compiler User Manual. Use that document when you want the compiler and SDK reference without the rest of the IDE manual.

Web64 IDE includes an experimental browser-native C compiler named Web64 C v0.1. It is intended for small C64 programs, hardware register setup, asset-driven game code, and mixed C/assembly projects inside the Web64 virtual filesystem.

The C compiler is not cc65. It does not use cc65 object files, linker scripts, or a native toolchain. Web64 C lowers supported C modules into Web64 assembler-compatible source, then the existing browser-local assembler produces the PRG, symbols, line maps, diagnostics, and memory ranges.

When the optional Generated Assembly workspace is enabled and opened, the IDE exposes that lowering result as structured, read-only instruction rows with encoded bytes, addresses, and original C source provenance. Display formatting and lookup indexes are created lazily for the active compile revision; enabling the setting alone does not add projection work to live C editing. Source breakpoints use stable lowering provenance where available and are remapped after regenerated addresses move. See Generated Assembly machine view for the complete workflow and machine-breakpoint distinction.

C project model

A C project is made from virtual project records, not host paths. Typical records are:

main.c
include/game.h
assets/generated.h
assets/sprites/player.spr
assets/maps/level1.map

The build graph classifies .c files as C modules, .h files as C headers, assembly files as assembly modules, and asset files as binary or generated records. C modules are ordered before assembly modules so generated C labels and handwritten assembly labels share the final assembler symbol namespace.

For a normal C project, keep the root main.asm empty. Web64 C emits its own startup label that calls the configured C entry function. If you deliberately write your own assembly startup instead, call the C entry yourself, for example jsr _main for a C function named main. Do not leave an unrelated default main.asm program in a C project, because it is assembled after the generated C startup and can make the project appear to start in the wrong code.

C labels are emitted with underscore names. A C function named main becomes _main in assembly. Direct calls to normal C functions emit jsr _name; calls to names that already start with asm_ are treated as direct assembly labels.

C configuration

The default C configuration is:

{
  "enabled": false,
  "dialect": "web64-c-v0.1",
  "entry": "main.c",
  "includePaths": ["include", "assets"],
  "stdout": "screen",
  "stdin": "keyboard",
  "runtimeProfile": "tiny",
  "compilerBackend": "web64-native"
}

Supported stdout and stdin backends are screen, kernal, debug, and none. Use none for freestanding routines that do not need the tiny runtime I/O shims. runtimeProfile currently supports tiny and freestanding.

Supported C subset

Web64 C v0.1 is a freestanding C-like subset with an explicit 6502 data model. Its implemented surface includes:

Undeclared identifiers and undeclared custom functions are errors. Calls to the bundled runtime and names beginning with asm_ retain their legacy implicit-call behavior for existing projects. Unsupported statements, types, signatures, and annotations produce diagnostics instead of being silently accepted.

Constant operands and constant conditions

Typed byte expressions with a compile-time constant use specialized lowering for +, -, &, |, and ^. Commutative operations accept the constant on either side and use a 6502 immediate operand; value - constant uses immediate SBC. constant - value uses an order-preserving sequence and may need one byte temporary, but it avoids the generic stack spill. The constant may be a literal, numeric define, or folded constant expression. This lowering also applies when the dynamic operand is a function result, so it does not use the stack or a zero-page temporary merely to hold the constant. Byte identities such as value + 0, value - 0, value | 0, value ^ 0, and value & 0xff retain evaluation of value but omit the redundant arithmetic instruction.

Constant conditions are folded when the typed expression is side-effect-free. while (true) therefore emits the loop body and back edge without loading and testing 1. Calls, volatile accesses, and other observable expressions are still evaluated; for example, while (rand()) retains the call and conditional branch.

Non-literal 16-bit comparisons now materialize and compare both operand bytes for ==, !=, <, <=, >, and >=. Signed ordering biases both high bytes before comparison, while unsigned ordering compares them directly. Eight-bit integer operands receive the target's normal signed int promotion before mixed-width ordering, including int16_t with uint8_t and int8_t with int16_t. Compound word operands such as target > position + 256 carry through the high byte correctly. Byte-only comparisons retain their immediate and single-byte fast paths.

For example:

while (true) {
    *((uint8_t*)VIC_BORDER) = rand() & 0x0f;
}

lowers to the following core sequence. Generated label suffixes vary by source location.

__web64_c_while_...:
    jsr _rand
    and #0xf
    sta 0xd020
    jmp __web64_c_while_...

The immediate-operand and constant-condition rules are part of typed C lowering and do not require enabling an optional optimizer pass.

Switch statements

Web64 C supports compact integer switch dispatch for state machines, menus, and asset-kind routing. The compiler emits a linear compare/branch sequence and generated labels such as __web64_c_case0_... and __web64_c_switchend_...; it does not pull in the cc64 runtime switch helper or cc65 code movement.

uint8_t mode;
uint8_t color;

void main(void) {
    switch (mode) {
        case 0:
            color = 6;
            break;
        case 1:
            color = 14;
            break;
        default:
            color = 1;
            break;
    }
}

Case labels must resolve to numeric constants or defines. Duplicate case values and duplicate default labels are errors. Fallthrough is preserved when a case omits break.

Pragmas, attributes, and calling conventions

Web64 C uses a registry for pragmas and attributes so source annotations either map to a known Web64 behavior or produce a stable diagnostic.

Supported or recognized forms are:

FormCurrent behavior
#pragma web64 ...Recognized as a Web64-owned control surface and reported with c-pragma-web64-registry until a specific behavior-changing control is implemented.
#pragma warn(...) and #pragma cc64 ...Compatibility no-op warnings.
#pragma optimize(...)Recognized as an optimization-control request; project build settings and optimizer trace remain authoritative.
#pragma bss-name, data-name, rodata-name, code-nameRejected with c-unsupported-pragma; Web64 does not execute native cc65 segment/linker behavior.
_fastcallAccepted as a source-level hint for currently supported declarations/functions.
cdecl / __cdecl__Rejected with c-cdecl-deferred; the native cc65 stack ABI is not implemented.
interrupt / __interrupt__Rejected with c-interrupt-deferred until vector and register preservation policy is implemented.
__attribute__((unused))Diagnostic-only recognized annotation.
__attribute__((noreturn))Diagnostic-only control-flow annotation.

Unknown attributes are errors. This is intentional: Web64 C should not suggest that cc65 or hosted C annotation semantics are active unless the browser-local compiler has executable support for them.

Include resolution

C includes are virtual includes. These forms are accepted:

#include <stdint.h>
#include <c64.h>
#include "include/game.h"
#include "assets/generated.h"

The resolver rejects absolute host paths such as C:/..., /home/..., \\server\..., and file: URLs. Put headers into the Web64 virtual filesystem and include them by project-relative path.

Preprocessing is intentionally bounded. Conditional groups preserve line positions for diagnostics, and bundled headers use include guards so repeated or transitive includes do not duplicate declarations. This is not a complete translation-phase implementation: token pasting, stringification, variadic macros, and general host-compiler preprocessing remain outside the current subset.

assets/generated.h is generated from project asset records at compile time. It exposes deterministic C-safe start/end labels, _size constants, and numeric _kind constants. Asset records keep their browser-local generated-record placement metadata; no native linker script or object segment is introduced.

Bundled virtual headers

Web64 C bundles a small read-only SDK. These headers are resolved from web64://c/include/... before project-local include lookup, except assets/generated.h, which is regenerated from the current project asset records during the build.

HeaderIncludes
stdint.hExact 8/16/32-bit aliases, intptr_t/uintptr_t, intmax_t/uintmax_t, least/fast aliases, and supported integer limits. The 32-bit aliases are primarily storage and constant-expression types; the callable ABI is limited to 8/16-bit values.
stddef.h16-bit size_t, signed 16-bit ptrdiff_t, and NULL.
stdbool.hbool mapped to _Bool, true, false, and __bool_true_false_are_defined. Stores to _Bool normalize to exactly zero or one.
string.hExecutable tiny-runtime implementations of memchr, memcmp, memcpy, overlap-safe memmove, memset, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, and strstr.
stdio.hExecutable puts/putchar plus restricted compiler-lowered printf; unsupported file I/O and fprintf/sprintf names are absent from callable headers.
stdlib.hExecutable abort, 16-bit abs, whitespace/sign-aware decimal atoi, byte-valued rand, and seedable srand; RAND_MAX is 0x00ff.
ctype.hExecutable ASCII isdigit, isalnum, isalpha, isspace, islower, isupper, tolower, and toupper.
libc.hAggregate convenience header that includes stddef.h, stdio.h, stdlib.h, string.h, and ctype.h; it contains no CC64 fixed-address declarations.
c64.hC64 memory map constants, typed register structs, pointer aliases, VIC-II, sprite, SID, CIA, keyboard, joyport, color, screen, and KERNAL constants.
conio.hcc65-familiar console/color macro shim over Web64 screen/stdout helpers.
joystick.hcc65-familiar joystick macro shim over the Web64 joyport helper surface.
6502.hCPU memory-access and simple opcode macro shim through Web64 inline assembly.
cbm.hCBM/KERNAL constant shim; native disk driver and object ABI behavior remain out of scope.
joy.hJoystick helper declaration for joy_read().
sprite.hSprite helper declarations for sprite_enable(), sprite_set_pos(), and sprite_set_color().
web64.hSmall Web64 helper declarations for delays, random byte reads, screen clearing/cursor output, text output, byte plotting, and zero-parameter void calls by address.
web64/assets.hWeb64 Asset Model v1 public typedefs, kind/mode/flag macros, immutable descriptor structs, and mutable runtime instance structs.
assets/generated.hGenerated C declarations for project assets plus deterministic _size, _kind, and implemented typed descriptor constants.

The headers are intentionally compact. Every function declared by the bundled standard-library headers above has either an executable dependency-selected runtime implementation or the documented compiler lowering. Including them does not make the full cc65 or hosted C library available. Runtime-owned parameter slots are emitted once for a whole multi-module build, so repeated guarded includes and calls from multiple translation units do not create duplicate labels. The SDK header tree in the IDE opens these files as read-only web64://c/include/... documents.

Standard headers use extern function declarations because the implementation is outside the header. extern does not assign a fixed address. Calling memcpy, for example, selects web64-runtime/string.asm; including string.h without calling a string function adds no string runtime code. libc.h is retained for source compatibility as an aggregate include, but new code may include the specific standard headers it uses.

Web64 fixed-point math

web64/fixed.h provides the browser-native Web64 fixed-point math surface. The public storage types are ordinary integer-backed C types so they can live in globals, structs, arrays, project files, generated assembly, and debugger metadata without a native object ABI.

TypeStorageMeaning
web64_fix8_8signed 16-bit word8 integer bits and 8 fractional bits, scale 256.
web64_ufix8_8unsigned 16-bit wordUnsigned 8.8 values, scale 256.
web64_fix16_16signed 32-bit long16.16 constants, conversions, floor/to-int/fraction, and wrapping add/sub macros only.
web64_ufix16_16unsigned 32-bit longUnsigned 16.16 storage with the same macro-only v1 policy.
web64_angle8unsigned 8-bit byteOne full turn is 256 units: 0=0, 64=90, 128=180, 192=270 degrees.

Common 8.8 constants and conversions are macros. They do not pull fixed runtime modules by themselves.

NameBehavior
WEB64_FIX8_ONE, WEB64_FIX8_HALF, WEB64_FIX8_MIN, WEB64_FIX8_MAXFixed 8.8 constants.
WEB64_FIX8_FROM_INT(value)Convert an integer value to 8.8. Typed 8-bit inputs lower directly to a zero fraction byte and the source integer byte, without a shift loop or helper call.
WEB64_FIX8_TO_INT(value)Convert 8.8 to integer by taking the high byte.
WEB64_FIX8_FRACTION(value)Return the low fractional byte.
WEB64_FIX8_FROM_RATIO(n, d)Compile-time ratio conversion; constant zero divisors report c-divide-by-zero.
web64_fix8_floor, web64_fix8_ceil, web64_fix8_roundMacro-backed integer-style conversions.
web64_fix8_add_wrap, web64_fix8_sub_wrapWrapping 16-bit fixed add/subtract macros.

For a typed uint8_t or int8_t source, WEB64_FIX8_FROM_INT is recognized as byte placement rather than emitted as a shift sequence. The source byte becomes the integer byte and the fraction byte is cleared; the source is loaded first so assigning through overlapping storage remains correct:

    lda source
    sta destination+1
    lda #0
    sta destination

Implementation-backed 8.8 helpers are dependency-selected. Calling one helper pulls only the runtime module family it needs.

Helper familyPublic namesRuntime module
Multiply and interpolationweb64_fix8_mul, web64_fix8_mul_round, web64_ufix8_mul, web64_fix8_lerpweb64-runtime/fixed-mul.asm
Divisionweb64_fix8_div, web64_ufix8_divweb64-runtime/fixed-div.asm
Saturating/core helpersweb64_fix8_add_sat, web64_fix8_sub_sat, web64_fix8_abs, web64_fix8_min, web64_fix8_max, web64_fix8_clampweb64-runtime/fixed-saturate.asm
Trigonometryweb64_sin8, web64_cos8web64-runtime/fixed-trig.asm
Vector/motionweb64_fixvec2_add, web64_fixvec2_sub, web64_fixvec2_scale, web64_motion2d_integrateweb64-runtime/fixed-vector.asm; scale also selects fixed multiply.

The header also provides short 8.8 aliases for these implementation-backed helpers: f8_mul_round, f8_div, uf8_mul, uf8_div, f8_lerp, f8_abs, f8_min, f8_max, f8_clamp, f8_add_sat, f8_sub_sat, f8_sin, f8_cos, v2f8_add, v2f8_sub, v2f8_scale, and m2d_int. These are preprocessor aliases to the web64_* names, so they keep the same ABI, semantics, and runtime dependency selection. The f8/uf8 prefixes are reserved for the current 8.8 tier; future 16.16 helpers can use distinct 16.16 names.

Signed multiply truncates toward zero from the signed widened product. web64_fix8_mul_round rounds nearest half away from zero. Unsigned multiply selects the middle product bytes, equivalent to (a b) >> 8. Division uses a widened numerator equivalent to a 256 / b; dynamic fixed division by zero returns 0, while constant zero divisors in ratio macros are diagnostics. Overflow wraps for ordinary fixed storage and wrapping helpers; use the saturating helpers when clamp-to-range behavior is wanted. web64_fix8_lerp(a, b, amount) uses amount/256, so amount=255 is close to b but not exactly b.

The standard trig table is a deterministic 256-entry signed 8.8 full-wave sine table. web64_sin8(angle) returns the table value. web64_cos8(angle) uses the same table with a 64-unit phase offset. The exact endpoints include web64_sin8(64) == 0x0100, web64_sin8(192) == 0xff00, web64_cos8(0) == 0x0100, and web64_cos8(128) == 0xff00.

The editor's Insert > Table and Insert > Matrix tools import the same canonical quantizer used to build this compiler table. Signed and unsigned 8.8 output therefore uses identical scale-256 words and nearest/half-away-from-zero rounding. A 256-step generated sine table with amplitude 1, center 0, phase 0, and web64_fix8_8 output is bit-for-bit identical to the compiler's web64_sin8 table. Generated cyclic tables exclude the repeated turn endpoint, matching web64_angle8 values 0..255. These tools perform offline source generation only; they do not add runtime helpers, hidden assets, or program-memory metadata.

Fixed 16.16 support is intentionally smaller in v1. Use the WEB64_FIX16_* constants, integer/ratio conversion macros, floor/to-int/fraction macros, and wrapping add/sub macros for storage and constant-scale data. There are no public 16.16 multiply/divide helper names until executable 6502 helpers and differential tests exist.

Use named helpers for fixed multiply and division. Direct fixed-point operators such as web64_sin8(phase) * radius are rejected by the v1 compiler with c-unsupported-fixed-point-operator; write the operation explicitly:

#include <web64/fixed.h>

web64_fix8_8 x = WEB64_FIX8_FROM_INT(120);
web64_fix8_8 velocity = WEB64_FIX8_FROM_RATIO(3, 2);

void step(void) {
    x = web64_fix8_add_wrap(x, velocity);
    *(uint8_t*)0xd000 = WEB64_FIX8_TO_INT(x);
}
#include <web64/fixed.h>

web64_angle8 phase;
web64_fix8_8 radius = WEB64_FIX8_FROM_INT(24);
web64_fix8_8 offset;

void step(void) {
    phase = phase + 2;
    offset = web64_fix8_mul(web64_sin8(phase), radius);
    *(uint8_t*)0xd000 = 160 + WEB64_FIX8_TO_INT(offset);
}

The fixed-point optimizer has a gated specialization pass. Constant helper calls can fold to direct word materialization, and typed dynamic identity or safe power-of-two unsigned cases can lower to word copies or shifts. The runtime helper is removed only when every call to that helper is proven folded or lowered; mixed folded and fallback call sets keep the verified runtime module.

The public examples repository contains source-backed projects for this section: c-fixed-subpixel-scroll, c-fixed-sine-lerp, and c-fixed-motion. These are portable .web64proj records and are compiled by the fixed-point regression harness.

c64.h hardware definitions

c64.h is the main C64 hardware header. It provides numeric constants for pointer-style register access and typed volatile pointer aliases for common chip register blocks.

Common memory and I/O constants include:

C64_RAM_BASE
C64_BASIC_START
C64_SCREEN_RAM
C64_COLOR_RAM
C64_CHAR_ROM
C64_IO_BASE
C64_KERNAL_ROM

Typed aliases include:

c64_reg8_t
c64_cpu_port_registers
c64_screen_ram
c64_color_ram
c64_vicii_registers
c64_sid_registers
C64_CPU_PORT
C64_SCREEN
C64_COLOR
VICII
VIC
SID

VIC-II, sprite, and color constants include:

VIC_BASE
VIC_BORDER
VIC_BACKGROUND
VIC_RASTER
VIC_CONTROL1
VIC_CONTROL2
VIC_MEMORY_SETUP
VIC_SPRITE_ENABLE
VIC_SPRITE_X_MSB
VIC_SPRITE0_X
VIC_SPRITE0_Y
VIC_SPRITE0_COLOR
VIC_SPRITE_POINTER_BASE
VIC_BORDER_COLOR
VIC_BACKGROUND_COLOR
VIC_SPRITE_POINTERS
BORDER_COLOR
BACKGROUND_COLOR
SPRITE_ENABLE
SPRITE_MULTICOLOR
VIC_COLOR_BLACK
VIC_COLOR_WHITE
VIC_COLOR_BLUE
VIC_COLOR_LIGHT_GRAY

SID constants include:

SID_BASE
SID_VOICE1_FREQ_LO
SID_VOICE1_FREQ_HI
SID_VOICE1_PULSE_LO
SID_VOICE1_PULSE_HI
SID_VOICE1_CONTROL
SID_VOICE1_ATTACK_DECAY
SID_VOICE1_SUSTAIN_RELEASE
SID_VOLUME_FILTER_MODE
SID_WAVE_TRIANGLE
SID_WAVE_SAW
SID_WAVE_PULSE
SID_WAVE_NOISE
SID_GATE

CIA, keyboard, and joyport constants include:

CIA1_PRA
CIA1_PRB
CIA1_DDRA
CIA1_DDRB
CIA2_PRA
CIA2_PRB
KEYBOARD_COLUMN_PORT
KEYBOARD_ROW_PORT
KEYBOARD_COLUMN_DDR
KEYBOARD_ROW_DDR
JOYPORT_1
JOYPORT_2
JOY_UP
JOY_DOWN
JOY_LEFT
JOY_RIGHT
JOY_FIRE
JOY_RELEASED_MASK
JOY2_UP()
JOY2_DOWN()
JOY2_LEFT()
JOY2_RIGHT()
JOY2_FIRE()

Common KERNAL entry constants include:

KERNAL_CHROUT
KERNAL_CHRIN
KERNAL_GETIN
KERNAL_SCNKEY
KERNAL_PLOT
KERNAL_LOAD
KERNAL_SAVE

Joystick bits are active-low on the C64. A pressed fire button clears the JOY_FIRE bit in the sampled port value, so test for release with joy & JOY_FIRE and for press with !(joy & JOY_FIRE). The JOY2_*() macros express the same active-low tests for joystick port 2.

Web64 helper headers

The helper headers are compiler-recognized v0.1 intrinsics. They are intended for compact C64 projects and lower to direct register/KERNAL/SID reads and writes.

#include <stdint.h>
#include <joy.h>
#include <sprite.h>
#include <web64.h>

uint8_t joy;
uint8_t rnd;

void main(void) {
    clrscr();
    gotoxy(0, 0);
    cprintf("READY");

    sprite_enable(1);
    sprite_set_pos(0, 300, 100);
    sprite_set_color(0, VIC_COLOR_LIGHT_GRAY);

    joy = joy_read();
    rnd = random8();
    if (!(joy & JOY_FIRE)) {
        plot_pixel(0x0400, 42);
    }

    delay_frames(2);
    delay_ms(40);
}

plot_pixel(address, value) is byte-oriented in v0.1: pass the target bitmap, screen, color, or other memory address explicitly. delay_ms() is frame-based and approximate.

VoidCall(addr) calls a zero-parameter void function at a literal, generated, or runtime 16-bit address:

#include <web64.h>
#include <assets/generated.h>

void main(void) {
    VoidCall(title_play_address);
}

A constant address lowers to one absolute JSR. The address must refer to an initialized routine whose calling convention takes no parameters.

VoidCall is a function-like macro, so every .c translation unit that uses it must include <web64.h> itself; an include in another .c file is not project-global. A missing include produces c-implicit-function-declaration on the call line and blocks the build instead of emitting an unresolved _VoidCall. Repeating the exact macro definition produces a non-blocking c-macro-redefinition-identical warning for backwards compatibility. A different replacement definition produces the blocking c-macro-redefinition error. Warnings remain visible but do not prevent Start; only error diagnostics make a build unrunnable.

C runtime header examples

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

uint8_t lives = 3;
bool running = true;

void main(void) {
    lives--;
}

stdio.h declares puts and putchar for the tiny runtime, plus restricted compiler-lowered printf for string-literal formats with %d values. Calls are routed through the configured stdout backend. File I/O declarations and fprintf/sprintf are intentionally absent until they have executable implementations. Select stdout: none for code that should not pull in output support.

Screen and color RAM example

#include <stdint.h>
#include <c64.h>

void main(void) {
    *(volatile uint8_t *)VIC_BORDER = VIC_COLOR_BLUE;
    *(volatile uint8_t *)VIC_BACKGROUND = VIC_COLOR_BLACK;
    *(volatile uint8_t *)C64_SCREEN_RAM = 1;
    *(volatile uint8_t *)C64_COLOR_RAM = VIC_COLOR_WHITE;
}

The typed register aliases from c64.h can express chip register writes more clearly:

#include <c64.h>

void main(void) {
    VIC->border_color = VIC_COLOR_BLUE;
    VIC->background_color0 = VIC_COLOR_BLACK;
}

Joystick and sprite helper example

#include <stdint.h>
#include <joy.h>
#include <sprite.h>

uint8_t joy;

void main(void) {
    sprite_enable(1);
    sprite_set_pos(0, 80, 100);
    sprite_set_color(0, VIC_COLOR_LIGHT_GRAY);

    joy = joy_read();
    if (!(joy & JOY_FIRE)) {
        BACKGROUND_COLOR = VIC_COLOR_RED;
    }
}

SID register example

#include <stdint.h>
#include <c64.h>

void main(void) {
    *(volatile uint8_t *)SID_VOICE1_FREQ_LO = 0x11;
    *(volatile uint8_t *)SID_VOICE1_FREQ_HI = 0x25;
    *(volatile uint8_t *)SID_VOICE1_ATTACK_DECAY = 0x09;
    *(volatile uint8_t *)SID_VOICE1_SUSTAIN_RELEASE = 0xf0;
    *(volatile uint8_t *)SID_VOLUME_FILTER_MODE = 0x0f;
    *(volatile uint8_t *)SID_VOICE1_CONTROL = 0x21;
}

0x21 is SID_WAVE_SAW | SID_GATE. Use the named constants when writing project code; keep immediate values in examples when you need to stay inside the current v0.1 expression subset.

Web64 asset access from C

assets/generated.h is produced from the virtual project asset records at compile time. It is the supported C-facing contract for browser-local assets: C code can refer to deterministic labels, sizes, asset-kind constants, typed data aliases, read-only flags, and the implemented Asset Model v1 descriptor declarations/constants without hard-coding assembler names by hand.

The generated header makes asset labels visible to the C compiler and final assembler namespace. When generated C actually references an asset data label, a C-only build embeds that payload once on demand. A hybrid build reuses an existing assembly label or .incbin instead of emitting a duplicate. Descriptor- and size-only references do not embed payload bytes. Browser-local asset files remain the canonical project records; generated .inc and .sid outputs remain derived assets where the IDE pipeline creates them. SID Tracker generates one .sid binary and one .inc, not a duplicate .bin.

Slice 17 adds the public web64/assets.h Asset Model v1 header and generated typed descriptor declarations/constants for source-backed charsets/chars, sprite banks, blocksets, maps, and SID files. This currently documents and exposes the byte-exact descriptor shape; runtime helper modules, overlay-pair descriptor completion, malformed asset diagnostics, descriptor backing bytes for every planned case, and browser/emulator conformance closure remain planned until their executable evidence exists.

Supported C asset records are project-local records whose kind is one of asset, binary, blob, sprite, spritebank, spriteanimation, charset, char, tile, block, blockset, tilemap, map, sid, or source. Typical file extensions are .bin, .raw, .dat, .spr, .chr, .ch8, .blk, .blocks, .map, .w64map, and .sid. A .w64sid record is editable composition source, not a runtime C asset. Its generated .sid is selected for assets/generated.h; an older generated .bin remains a fallback only when the project has no generated .sid. Unsupported kinds produce a c-unsupported-asset-kind diagnostic instead of becoming silent zero addresses.

The built-in kind constants are provided by web64/assets.h and re-used by assets/generated.h:

#define WEB64_ASSET_MODEL_VERSION 0x0001
#define WEB64_GENERATED_ASSETS_VERSION 0x0001
#define WEB64_ASSET_ADDRESS_NONE 0x0000
#define WEB64_ASSET_REF_NONE 0x0000
#define WEB64_SPRITE_BLOCK_NONE 0xff
#define WEB64_ASSET_KIND_BINARY 1
#define WEB64_ASSET_KIND_CHAR 2
#define WEB64_ASSET_KIND_CHARSET 3
#define WEB64_ASSET_KIND_SPRITE_MONO 4
#define WEB64_ASSET_KIND_SPRITE_MC 5
#define WEB64_ASSET_KIND_SPRITE_OVERLAY 6
#define WEB64_ASSET_KIND_BLOCK 7
#define WEB64_ASSET_KIND_BLOCKSET 8
#define WEB64_ASSET_KIND_MAP 9
#define WEB64_ASSET_KIND_SID 10
#define WEB64_ASSET_KIND_SOURCE 11

Asset paths are converted into C-safe symbols from the file basename with the extension removed. Non-identifier characters become _, and names that do not start with a C identifier character are prefixed. For example, assets/sprites/player.spr becomes player, while assets/sprites/player ship.spr becomes player_ship. Duplicate basenames that normalize to the same C symbol produce c-duplicate-asset-symbol.

The physical data labels match the names generated by the IDE asset editors: <symbol>_chars for charsets, <symbol>_sprites for sprite banks, <symbol>_blocks for block sets, <symbol>_map for maps, and <symbol>_sid for SID files. Historical base names remain C aliases, so existing source using player continues to address player_sprites. The metadata contract retains the historical start/end names while also exposing the physical data/dataEnd labels to build tools.

For a sprite asset named player.spr, the generated header includes:

#define WEB64_ASSET_KIND_SPRITE_MC 5
extern const unsigned char player_sprites[];
#define player player_sprites
extern const unsigned char player_sprites_end[];
#define player_end player_sprites_end
#define player_size 128
#define player_sprites_size player_size
#define player_kind 5
#define player_data player_sprites
#define player_bytes player_sprites
#define player_readonly 1

Use the editor data label or _data/_bytes aliases when a routine needs an asset pointer. Use _size in initializers, conditions, copy loops, and bounds checks. Use _kind when one C source handles multiple generated assets.

#include <stdint.h>
#include <assets/generated.h>

uint16_t player_size_bytes = player_size;
const unsigned char *player_ptr = player_data;

void main(void) {
    if (player_kind == WEB64_ASSET_KIND_SPRITE_MC) {
        asm_load_player_sprite();
    }
}

A binary/blob asset follows the same rules:

#include <stdint.h>
#include <assets/generated.h>

const unsigned char *blob_ptr = example_blob_data;
uint16_t blob_size = example_blob_size;

void main(void) {
    if (example_blob_size) {
        asm_use_blob();
    }
}

Generated asset symbols are read-only in C. Assigning a pointer variable from an asset is supported; assigning to the asset symbol itself is not.

#include <assets/generated.h>

const unsigned char *ok = example_blob_data;

void main(void) {
    ok = example_blob_bytes;  /* supported */
    example_blob = 1;         /* diagnostic: c-readonly-asset-write */
}

For implemented Slice 17 descriptor families, assets/generated.h also includes <web64/assets.h>, declares a typed <symbol>_asset descriptor, creates a <symbol>_descriptor alias, and emits constants derived from the source asset metadata. Descriptor member reads such as title_asset.load_address lower directly to constants and do not allocate a descriptor block or embed the payload by themselves. Referencing the descriptor's data member, a generated data label, or a _data/_bytes alias selects that payload for on-demand embedding when no project assembly label already supplies it.

#include <stdint.h>
#include <assets/generated.h>

uint16_t font_chars = font_char_count;
uint8_t font_multicolor = (font_mode == 2);

uint16_t player_frames = player_frame_count;
uint8_t player_payload = player_payload_bytes_per_frame;  /* 63 visible bytes */
uint8_t player_record = player_bytes_per_frame;           /* 64 stored bytes */

uint8_t terrain_cell_bytes = terrain_bytes_per_block;
uint16_t level_cells = level1_cell_count;
uint8_t level_index_width = level1_index_width;

void main(void) {
    if (player_frames && level_cells) {
        asm_prepare_assets();
    }
}

The generated descriptor declarations have these public shapes where implemented:

extern const Web64CharsetAsset font_asset;
#define font_descriptor font_asset
#define font_char_count 256
#define font_bytes_per_char 8
#define font_mode 2

extern const Web64SpriteAsset player_asset;
#define player_descriptor player_asset
#define player_frame_count 2
#define player_bytes_per_frame 64
#define player_payload_bytes_per_frame 63

extern const Web64BlockSetAsset terrain_asset;
#define terrain_descriptor terrain_asset
#define terrain_bytes_per_block 6

extern const Web64MapAsset level1_asset;
#define level1_descriptor level1_asset
#define level1_cell_count 240
#define level1_index_width 2

extern const Web64SidAsset title_asset;
extern const unsigned char title_sid[];
#define title_descriptor title_asset
#define title_file_size 2980
#define title_c64_data_offset 124
#define title_c64_data_size 2856
#define title_c64_data (title_sid + 124)
#define title_payload (title_sid + 124)
#define title_payload_size 2856
#define title_load_address 4096
#define title_init_address 4096
#define title_play_address 4160
#define title_song_count 1

web64/assets.h defines descriptor and instance structs such as Web64CharAsset, Web64CharsetAsset, Web64SpriteAsset, Web64SpriteOverlayAsset, Web64BlockAsset, Web64BlockSetAsset, Web64MapAsset, Web64SidAsset, Web64Sprite, Web64SpriteOverlay, and Web64MapView. Web64SidAsset describes the complete PSID file and its C64 payload offset/size, load/init/play addresses, song selection, speed flags, and SID flags. Descriptor references use explicit 16-bit Web64AssetAddress payload-label addresses and Web64AssetRef descriptor-label addresses rather than public generated-label pointer initializers. Zero is reserved as WEB64_ASSET_ADDRESS_NONE/WEB64_ASSET_REF_NONE. Public kind, mode, cell-type, flag, and boolean fields use uint8_t typedefs and macros; C bit-fields and public enum ABI are deferred.

In a hybrid project, assembly may explicitly import the complete SID file under the generated <symbol>_sid label:

title_sid:
    .incbin "assets/music/title.sid"

The explicit import is optional for C-only projects because a C reference to title_payload selects title_sid for on-demand embedding. If the hybrid assembly already defines title_sid, the compiler reuses it.

#include <string.h>
#include <assets/generated.h>

void load_title_music(void) {
    memcpy((void*)title_asset.load_address,
           title_payload,
           title_asset.c64_data_size);
}

title_asset.file_size and title_sid describe the complete PSID file, including its 124-byte header. Copying that pair directly to load_address is incorrect. The generated title_payload pointer skips c64_data_offset, and c64_data_size copies only bytes intended for C64 memory.

After the SID payload has been loaded and initialized, its generated zero-parameter play address can be called directly from C:

(*(void (*)(void))title_play_address)();

Constant targets lower to one absolute JSR; runtime uint16_t targets use a self-modifying call-site operand. An undeclared target such as title_play_address without #include <assets/generated.h> produces c-undeclared-identifier during C lowering instead of becoming a late undefined assembly symbol. Indirect calls with parameters remain diagnosed because an unknown target cannot use Web64's callee-owned ordinary parameter slots.

The same rule applies to copy arguments. A fabricated name such as enemy_sprites_any_symbol_blahblah produces c-undeclared-identifier on the C source line. A rejected call emits no partial argument pushes, so an invalid copy cannot silently corrupt the 6502 hardware stack.

The generated SID .inc can be imported by the assembly side of the same hybrid project. All macros from assets/generated.h are compile-time C metadata and are not re-emitted as assembler definitions; the generated .inc remains the assembly-side definition source. This prevents duplicate symbols when a loaded project contains an older generated .inc, while C expressions still fold the current asset-manifest values. Saving the W64SID asset regenerates both derived files; legacy tracker-generated includes are recognized by their generated-file marker, while genuine manual include overrides remain preserved.

The C-facing <symbol>_size is the complete PSID file size, while the W64SID assembly include retains its established <symbol>_size payload-size meaning. Use the unambiguous <symbol>_file_size and <symbol>_c64_data_size names when code needs to distinguish the complete PSID from its C64 payload.

The kind constants are descriptor categories, not broad payload buckets: char, charset, mono sprite, multicolor sprite, sprite overlay, block, block set, map, SID, source, and binary. Web64MapCellType reserves WEB64_MAP_CELL_CHAR and defines current block maps as WEB64_MAP_CELL_BLOCK. Sprite descriptor mode describes payload encoding; mutable Web64Sprite.flags controls the VIC-II instance bit, and helpers must reject applying an instance mode that does not match the asset payload. Sprite multicolor descriptor fields are defaults/compatibility metadata for the global $d025/$d026 registers, not per-instance storage. Source-backed v1 block payloads are row-major char-index bytes only; color/attribute layers stay absent until an explicit binary layout or separate addresses are implemented.

Use memcpy to copy a referenced payload to its runtime C64 address. Graphics labels use the same names shown by their IDE-generated assembly includes:

#include <string.h>
#include <assets/generated.h>

void main(void) {
    memcpy((void*)0x2800, bumps_chars, bumps_size);
    memcpy((void*)0x3000, c_joy_sprites, c_joy_size);
    memcpy((void*)0x3100, bank_2_sprites, bank_2_size);
    memcpy((void*)0x3400, enemy_sprites, enemy_size);
    memcpy((void*)title_load_address,
           title_payload,
           title_asset.c64_data_size);
}

For explicit fixed placement, compression, loaders, or cycle-sensitive copies, assembly remains available and may define the same physical data label. The generated C projection detects that definition and does not append another copy of the asset.

Generated asset labels participate in the C build graph. The IDE build output view marks assets/generated.h as a read-only generated header and records asset-label dependencies from the header to the backing project asset. Descriptor-only access must not select asset helper runtime modules. Duplicate C-safe symbols, unsupported placement/address policies, stale generated metadata, and unsupported asset kinds are reported as diagnostics when detected.

Inline assembly example

#include <c64.h>

void wait_raster(void) {
    asm("wait:\n    lda $d012\n    cmp #$80\n    bne wait");
}

void irq_guard(void) {
    asm volatile(R"(
    sei
    lda #$00
    sta $d020
    cli
)");
}

Inline assembly is emitted directly into the generated assembly module. Supported forms include asm("..."), asm volatile("..."), __asm__("..."), adjacent C string fragments, and simple R"(...)" raw string literals. GCC-style operand constraints and named operand substitution are not part of the v0.1 subset; use constants, labels, or normal C statements around the assembly block. Keep labels unique if the inline block can be emitted more than once.

Mixed C and assembly

Use C for simple game logic and register setup, and assembly for code that needs exact addressing modes, cycle control, or fuller language support.

void main(void) {
    asm_init_irq();
}

A call to asm_init_irq() emits jsr asm_init_irq, so a project assembly file can define:

asm_init_irq:
    sei
    rts

Use this boundary for raster IRQs, music players, fast sprite movement, decompression, asset copies, and other routines that are better expressed directly in 6502 assembly.

Declaring and passing parameters to assembly routines

Web64 C v0.1 treats calls whose names start with asm_ as direct assembly calls. The C call:

asm_copy_sprite();

emits:

    jsr asm_copy_sprite

Declare the routine in a project header so the C source has a stable name, then define the same unmangled label in an .asm file:

/* game.h */
void asm_copy_sprite(void);
; routines.asm
asm_copy_sprite:
    ; assembly body
    rts

Ordinary asm_ calls do not currently marshal C formal parameters. Do not rely on asm_copy_sprite(slot, color) to place values in registers or on the stack. Pass parameters explicitly through shared globals or through an inline assembly block that sets up registers before a jsr.

For shared globals, declare the parameter storage in C and write it before the call. C globals are visible to assembly with underscore-mangled labels:

#include <stdint.h>
#include "game.h"

uint8_t sprite_slot;
uint8_t sprite_color;

void main(void) {
    sprite_slot = 0;
    sprite_color = 1;
    asm_set_sprite_color();
}
/* game.h */
void asm_set_sprite_color(void);
; routines.asm
VIC_SPRITE0_COLOR = $d027

asm_set_sprite_color:
    ldx _sprite_slot
    lda _sprite_color
    sta VIC_SPRITE0_COLOR,x
    rts

For byte-sized values, this shared-global pattern is the most explicit and debugger-friendly option. For 16-bit values, store low and high bytes in separate globals, or use a uint16_t global only with assembly that intentionally reads both bytes from the emitted label layout. Keep the ownership clear: C writes the parameter fields, the assembly routine reads or updates them, and both sides agree which labels are scratch state versus persistent game state.

When a routine must receive CPU registers directly, use inline assembly for the setup and call:

void main(void) {
    asm("    lda #$06\n"
        "    ldx #$00\n"
        "    jsr asm_set_sprite_color_reg");
}
asm_set_sprite_color_reg:
    sta $d027,x
    rts

Use the register setup form only when the C source and assembly routine are tightly coupled. For reusable routines, prefer named globals because the parameter contract remains visible in the project symbols and debugger.

Web64 C v1 expression and ABI contract

The implemented scalar expression frontend tokenizes and parses supported expressions before lowering. Supported scalar expressions include integer and character literals, identifiers, grouped expressions, casts, declared function calls, zero-parameter calls through casted function pointers, unary +, unary -, bitwise ~, logical !, binary +, -, *, /, %, <<, >>, comparisons, bitwise &, ^, |, logical && and ||, assignment expressions in supported statement contexts, constant-index array access, typed pointer dereference, and struct/union member access backed by Web64 aggregate metadata. The conditional ?: operator is not implemented.

The Web64 C v1 integer model uses 8-bit _Bool, uint8_t, int8_t, char, and unsigned char; 16-bit uint16_t, int16_t, int, unsigned int, size_t, ptrdiff_t, and pointers; and 32-bit long aliases for supported storage and constant-expression use. Plain char is signed. INT_MIN is 0x8000, INT_MAX is 0x7fff, and RAND_MAX is 0x00ff. Byte operands promote to Web64 int for ordinary arithmetic unless an explicit cast or assignment context narrows the final value. Function parameters and return values wider than 16 bits are rejected because no 32-bit call ABI exists yet.

Function calls are clobber boundaries. Ordinary C-to-C calls evaluate arguments left-to-right into byte-exact stack-backed temporaries, then pop them in reverse into the callee's statically allocated parameter slots immediately before the call. Each argument uses the declared parameter width: for example, a (uint16_t, uint8_t, uint16_t, uint8_t) call stages exactly six bytes. Byte arguments converted to word parameters are zero-extended or sign-extended according to the declared source type. Nested calls retain their own arguments and declared return width during this staging. _fastcall accepts zero arguments, one word or pointer argument in A/X, or two byte arguments in A then X; unsupported signatures diagnose. Return values use A for byte results and A/X for word or pointer results. Byte-returning compatibility helpers such as rand, putchar, and puts clear X so older callers that consumed A/X continue to work. printf supports string-literal formats with %d arguments; each value is parsed, typed, fully evaluated, and printed in format order. Unsupported specifiers and mismatched argument counts emit diagnostics.

Casted function-pointer calls support return_type (*)(void). Constant targets lower to a direct absolute JSR; runtime 16-bit targets patch a call-site operand immediately before JSR $ffff. Undeclared targets produce c-undeclared-identifier, and indirect calls with parameters produce c-unsupported-indirect-call-arguments.

Ordinary locals and parameters use static storage, so generated functions and tiny-runtime helpers are non-reentrant and are not interrupt-safe unless a helper explicitly documents otherwise. Direct and mutual recursion within a translation unit are diagnosed. Web64 reserves zero-page $02-$09 for compiler/runtime scratch and $fb-$fe for indirect argument and pointer scratch; __web64_zeropage(address) declarations that overlap those ranges are rejected and the memory-layout report exposes the ownership.

Across translation units, external functions and objects retain underscore-prefixed public labels. static definitions receive deterministic module-private labels. Multiple external definitions and conflicting assembler-visible macro definitions are errors. A configured entry must have external linkage; static main is rejected. A helper-only C build with no external entry remains a warning for compatibility with mixed projects that provide their own assembly startup.

Inline assembly is supported through string forms such as asm("..."), asm volatile("..."), and __asm__("..."). Inline assembly labels share the generated assembler symbol namespace; local labels beginning with @ are scoped by the compiler, duplicate labels diagnose, and collisions with generated C/runtime labels diagnose. Inline assembly is a clobber boundary; preserve values explicitly when crossing it.

Supported #pragma warn, #pragma cc64, and #pragma optimize forms are compatibility no-ops that produce stable warnings. Segment/linker-effect pragmas such as bss-name, data-name, rodata-name, and code-name are unsupported diagnostics because Web64 does not run a native linker script.

Optimizer safety contract

Optimizer pass gates default to off and each enabled pass reports its decision in the optimizer trace. Transformations preserve hardware-register and C volatile accesses. Duplicate load/store/compare removal and register-temporary stack rewrites require local value, flag, and control-flow safety; opaque inline assembly is a fence.

Assembly-only strength reduction and boolean-branch folding are deliberately not performed without typed proof of width, signedness, and live flags. Dead-code analysis tracks references from instructions including jsr and from assembler directives, and it preserves distinct adjacent labels. Fixed-point specialization remains a typed, gated pass: a runtime helper is removed only when every use has been proven replaceable. Cost reports expose compiler/runtime dependencies, estimated bytes/cycles, hardware accesses, and the complete reserved zero-page ownership.

Compiler compatibility appendix

CategoryStatusNotes
Parser-backed scalar arithmetic and bitwise expressionsImplementedCovered by the compiler regression suite and deterministic expression fuzzer.
*, /, %ImplementedLower through dependency-selected arithmetic helper runtime modules. Divide by constant zero and INT_MIN / -1 diagnose.
Casts and integer promotionsImplemented for the shipped scalar subsetExplicit casts preserve width/signedness; unsupported cast shapes diagnose.
Conditional preprocessing and include guardsImplemented for the bounded subsetLine-preserving conditional groups, object/function macros, #undef, and active #error are supported; token pasting, stringification, and variadic macros are not.
Declarations and linkageImplemented for the shipped scalar/aggregate subsetPrototypes, locals, parameters, extern, internal-linkage static, enums, and guarded multi-translation-unit headers are supported; duplicate external definitions diagnose.
Nested calls and _fastcall runtime callsImplementedCall results are spilled across later calls according to the Web64 C ABI contract.
printf %d materializationImplementedString-literal formats with matching %d arguments are supported.
Aggregates, member access, and pointer aliasesImplemented for fixed-layout Web64 recordsStructs use declaration-order byte offsets without implicit padding; unions overlay at offset zero. Runtime aggregate indexes remain diagnosed.
Bundled standard-library declarationsImplementedEvery callable declaration in string.h, stdio.h, stdlib.h, and ctype.h has executable runtime code or documented compiler lowering.
Typed pointersImplemented for byte/word pointees16-bit pointers load and store one or two little-endian bytes according to pointee width. Wider pointees and general pointer arithmetic remain limited.
Inline assemblyImplemented with Web64 scoping rulesGCC/ca65 operand constraints and native optimizer behavior are not implemented.
Runtime dependency selectionImplementedRuntime modules are selected from source evidence, not linked monolithically.
Recursion and reentrancyUnsupported with explicit diagnosticsStatic parameter/local slots make ordinary generated code non-reentrant; same-translation-unit call cycles diagnose.
Native cc65 objects, libraries, linker configs, and host pathsNot applicableWeb64 is browser-local and lowers to Web64 assembler-compatible source.
32-bit call ABI, interrupt functions, native cdecl, full hosted libc, floating point, bit-fields, flexible arrays, and broad C preprocessor behaviorDeferred or unsupportedThese remain explicit diagnostics or out of current scope.

Verified public examples

The governed web64-examples repository is the public example suite for Web64 C v1. c-compiler-conformance/c-compiler-conformance.web64proj prints PASS/FAIL for arithmetic, shifts, bitwise expressions, casts, nested calls, _fastcall runtime calls, and printf argument handling. tutorials/README.md links runnable projects for SDK headers, generated assets/generated.h, C64 register aliases, joystick helpers, sprite helpers, mixed C/ASM symbol behavior, runtime dependency boundaries, and unsupported-syntax diagnostics.

Web64 SDK header index

HeaderSummaryDeclarations
6502.hInline assembly and direct-memory convenience macros for 6502-centric C code.6 symbols
assets/generated.hProject-generated asset declarations exported into C builds from the current asset manifest.0 symbols
c64.hTyped C64 hardware register blocks, memory map constants, colors, and device pointer macros.217 symbols
cbm.hCBM and KERNAL compatibility constants and light Web64 shims.7 symbols
conio.hcc65-style screen and text helpers mapped onto the Web64 SDK surface.31 symbols
ctype.hASCII-oriented character classification and case-conversion declarations backed by the Web64 runtime.8 symbols
joy.hMinimal joystick helper for reading the active C64 port state.1 symbols
joystick.hcc65-familiar joystick constants and helpers without native driver loading.5 symbols
libc.hAggregate convenience header over the dependency-linked Web64 standard library surface.2 symbols
peekpoke.hPEEK/POKE helper macros for byte and word memory access.4 symbols
sprite.hSmall sprite helper API for position, color, and enable writes.3 symbols
stdbool.hBoolean language aliases and constants.4 symbols
stddef.hCore pointer-sized typedefs and NULL.3 symbols
stdint.hFixed-width integer typedefs and limit macros.29 symbols
stdio.hTiny stdio surface: putchar, puts, and compiler-lowered literal printf.4 symbols
stdlib.hTiny stdlib surface: abs, atoi, rand, srand, and abort.6 symbols
string.hByte and C-string manipulation declarations backed by the Web64 runtime.18 symbols
web64.hGeneral Web64 SDK helpers for timing, text, randomness, simple drawing, and zero-parameter void calls by address.8 symbols
web64/assets.hPublic Web64 Asset Model v1 descriptor types and constants for generated asset metadata.44 symbols
web64/fixed.h8.8 fixed-point, secondary 16.16 macros, angle8 trig helpers, and vector/motion declarations.69 symbols

Web64 SDK reference

6502.h

Inline assembly and direct-memory convenience macros for 6502-centric C code.

Included headers: <stdint.h>.

Macros:

NameValueDescription
PEEK(address)((volatile uint8_t)(address))Macro constant exported by the header.
POKE(address, value)((volatile uint8_t)(address) = (uint8_t)(value))Macro constant exported by the header.
PEEKW(address)((volatile uint16_t)(address))Macro constant exported by the header.
POKEW(address, value)((volatile uint16_t)(address) = (uint16_t)(value))Macro constant exported by the header.
CLI__asm__("cli")Macro constant exported by the header.
SEI__asm__("sei")Macro constant exported by the header.

Header listing:

#ifndef WEB64_6502_H
#define WEB64_6502_H
#include <stdint.h>
#define PEEK(address) (*(volatile uint8_t*)(address))
#define POKE(address, value) (*(volatile uint8_t*)(address) = (uint8_t)(value))
#define PEEKW(address) (*(volatile uint16_t*)(address))
#define POKEW(address, value) (*(volatile uint16_t*)(address) = (uint16_t)(value))
#define CLI() __asm__("cli")
#define SEI() __asm__("sei")
#endif

assets/generated.h

Project-generated asset declarations exported into C builds from the current asset manifest.

Included headers: <web64/assets.h>.

Header listing:

#ifndef WEB64_ASSETS_GENERATED_H
#define WEB64_ASSETS_GENERATED_H
#include <web64/assets.h>
#endif

c64.h

Typed C64 hardware register blocks, memory map constants, colors, and device pointer macros.

Typedefs:

NameDeclarationDescription
c64_reg8_ttypedef unsigned char c64_reg8_t;C64-specific alias type used by the hardware headers.

Structs:

NameDescriptionField summary
c64_cpu_port_registersMemory-mapped register layout exported by <c64.h>.volatile c64_reg8_t data_direction, volatile c64_reg8_t data
c64_screen_ramTyped memory block overlay for a C64 RAM region.volatile c64_reg8_t cells[1000]
c64_color_ramTyped memory block overlay for a C64 RAM region.volatile c64_reg8_t cells[1000]
c64_vicii_registersVIC-II registers.47 fields: volatile c64_reg8_t sprite0_x, volatile c64_reg8_t sprite0_y, volatile c64_reg8_t sprite1_x, volatile c64_reg8_t sprite1_y, ...
c64_sid_voice_registersSID registers.7 fields: volatile c64_reg8_t freq_lo, volatile c64_reg8_t freq_hi, volatile c64_reg8_t pulse_lo, volatile c64_reg8_t pulse_hi, ...
c64_sid_registersMemory-mapped register layout exported by <c64.h>.29 fields: volatile c64_reg8_t voice1_freq_lo, volatile c64_reg8_t voice1_freq_hi, volatile c64_reg8_t voice1_pulse_lo, volatile c64_reg8_t voice1_pulse_hi, ...
c64_cia_registersCIA, keyboard, and joyport registers.16 fields: volatile c64_reg8_t pra, volatile c64_reg8_t prb, volatile c64_reg8_t ddra, volatile c64_reg8_t ddrb, ...

Macros:

NameValueDescription
C64_RAM_BASE0x0000Common C64 memory map.
C64_BASIC_START0x0801C64 memory-map or device-register constant.
C64_SCREEN_RAM0x0400C64 memory-map or device-register constant.
C64_COLOR_RAM0xd800C64 memory-map or device-register constant.
C64_CHAR_ROM0xd000C64 memory-map or device-register constant.
C64_IO_BASE0xd000C64 memory-map or device-register constant.
C64_KERNAL_ROM0xe000C64 memory-map or device-register constant.
C64_CPU_PORT((volatile c64_cpu_port_registers*)0x0000)C64 memory-map or device-register constant.
C64_SCREEN((volatile c64_screen_ram*)C64_SCREEN_RAM)C64 memory-map or device-register constant.
C64_COLOR((volatile c64_color_ram*)C64_COLOR_RAM)C64 memory-map or device-register constant.
VIC_BASE0xd000C64 memory-map or device-register constant.
VIC_SPRITE0_X0xd000C64 memory-map or device-register constant.
VIC_SPRITE0_Y0xd001C64 memory-map or device-register constant.
VIC_SPRITE1_X0xd002C64 memory-map or device-register constant.
VIC_SPRITE1_Y0xd003C64 memory-map or device-register constant.
VIC_SPRITE2_X0xd004C64 memory-map or device-register constant.
VIC_SPRITE2_Y0xd005C64 memory-map or device-register constant.
VIC_SPRITE3_X0xd006C64 memory-map or device-register constant.
VIC_SPRITE3_Y0xd007C64 memory-map or device-register constant.
VIC_SPRITE4_X0xd008C64 memory-map or device-register constant.
VIC_SPRITE4_Y0xd009C64 memory-map or device-register constant.
VIC_SPRITE5_X0xd00aC64 memory-map or device-register constant.
VIC_SPRITE5_Y0xd00bC64 memory-map or device-register constant.
VIC_SPRITE6_X0xd00cC64 memory-map or device-register constant.
VIC_SPRITE6_Y0xd00dC64 memory-map or device-register constant.
VIC_SPRITE7_X0xd00eC64 memory-map or device-register constant.
VIC_SPRITE7_Y0xd00fC64 memory-map or device-register constant.
VIC_SPRITE_X_MSB0xd010C64 memory-map or device-register constant.
VIC_CONTROL10xd011C64 memory-map or device-register constant.
VIC_RASTER0xd012C64 memory-map or device-register constant.
VIC_LIGHTPEN_X0xd013C64 memory-map or device-register constant.
VIC_LIGHTPEN_Y0xd014C64 memory-map or device-register constant.
VIC_SPRITE_ENABLE0xd015C64 memory-map or device-register constant.
VIC_CONTROL20xd016C64 memory-map or device-register constant.
VIC_SPRITE_Y_EXPAND0xd017C64 memory-map or device-register constant.
VIC_MEMORY_SETUP0xd018C64 memory-map or device-register constant.
VIC_INTERRUPT_STATUS0xd019C64 memory-map or device-register constant.
VIC_INTERRUPT_ENABLE0xd01aC64 memory-map or device-register constant.
VIC_SPRITE_PRIORITY0xd01bC64 memory-map or device-register constant.
VIC_SPRITE_MULTICOLOR0xd01cC64 memory-map or device-register constant.
VIC_SPRITE_X_EXPAND0xd01dC64 memory-map or device-register constant.
VIC_SPRITE_COLLISION0xd01eC64 memory-map or device-register constant.
VIC_DATA_COLLISION0xd01fC64 memory-map or device-register constant.
VIC_BORDER0xd020C64 memory-map or device-register constant.
VIC_BACKGROUND0xd021C64 memory-map or device-register constant.
VIC_BACKGROUND00xd021C64 memory-map or device-register constant.
VIC_BACKGROUND10xd022C64 memory-map or device-register constant.
VIC_BACKGROUND20xd023C64 memory-map or device-register constant.
VIC_BACKGROUND30xd024C64 memory-map or device-register constant.
VIC_SPRITE_MULTICOLOR00xd025C64 memory-map or device-register constant.
VIC_SPRITE_MULTICOLOR10xd026C64 memory-map or device-register constant.
VIC_SPRITE0_COLOR0xd027C64 memory-map or device-register constant.
VIC_SPRITE1_COLOR0xd028C64 memory-map or device-register constant.
VIC_SPRITE2_COLOR0xd029C64 memory-map or device-register constant.
VIC_SPRITE3_COLOR0xd02aC64 memory-map or device-register constant.
VIC_SPRITE4_COLOR0xd02bC64 memory-map or device-register constant.
VIC_SPRITE5_COLOR0xd02cC64 memory-map or device-register constant.
VIC_SPRITE6_COLOR0xd02dC64 memory-map or device-register constant.
VIC_SPRITE7_COLOR0xd02eC64 memory-map or device-register constant.
VIC_COLOR_BLACK0x00C64 memory-map or device-register constant.
VIC_COLOR_WHITE0x01C64 memory-map or device-register constant.
VIC_COLOR_RED0x02C64 memory-map or device-register constant.
VIC_COLOR_CYAN0x03C64 memory-map or device-register constant.
VIC_COLOR_PURPLE0x04C64 memory-map or device-register constant.
VIC_COLOR_GREEN0x05C64 memory-map or device-register constant.
VIC_COLOR_BLUE0x06C64 memory-map or device-register constant.
VIC_COLOR_YELLOW0x07C64 memory-map or device-register constant.
VIC_COLOR_ORANGE0x08C64 memory-map or device-register constant.
VIC_COLOR_BROWN0x09C64 memory-map or device-register constant.
VIC_COLOR_LIGHT_RED0x0aC64 memory-map or device-register constant.
VIC_COLOR_DARK_GRAY0x0bC64 memory-map or device-register constant.
VIC_COLOR_GRAY0x0cC64 memory-map or device-register constant.
VIC_COLOR_LIGHT_GREEN0x0dC64 memory-map or device-register constant.
VIC_COLOR_LIGHT_BLUE0x0eC64 memory-map or device-register constant.
VIC_COLOR_LIGHT_GRAY0x0fC64 memory-map or device-register constant.
COLOR_BLACKVIC_COLOR_BLACKColor alias constant for VIC palette values.
COLOR_WHITEVIC_COLOR_WHITEColor alias constant for VIC palette values.
COLOR_REDVIC_COLOR_REDColor alias constant for VIC palette values.
COLOR_CYANVIC_COLOR_CYANColor alias constant for VIC palette values.
COLOR_PURPLEVIC_COLOR_PURPLEColor alias constant for VIC palette values.
COLOR_GREENVIC_COLOR_GREENColor alias constant for VIC palette values.
COLOR_BLUEVIC_COLOR_BLUEColor alias constant for VIC palette values.
COLOR_YELLOWVIC_COLOR_YELLOWColor alias constant for VIC palette values.
COLOR_ORANGEVIC_COLOR_ORANGEColor alias constant for VIC palette values.
COLOR_BROWNVIC_COLOR_BROWNColor alias constant for VIC palette values.
COLOR_LIGHTREDVIC_COLOR_LIGHT_REDColor alias constant for VIC palette values.
COLOR_GRAY1VIC_COLOR_DARK_GRAYColor alias constant for VIC palette values.
COLOR_GRAY2VIC_COLOR_GRAYColor alias constant for VIC palette values.
COLOR_LIGHTGREENVIC_COLOR_LIGHT_GREENColor alias constant for VIC palette values.
COLOR_LIGHTBLUEVIC_COLOR_LIGHT_BLUEColor alias constant for VIC palette values.
COLOR_GRAY3VIC_COLOR_LIGHT_GRAYColor alias constant for VIC palette values.
VIC_SPRITE_POINTER_BASE0x07f8C64 memory-map or device-register constant.
VICII((volatile c64_vicii_registers*)VIC_BASE)Typed pointer or expression macro.
VICVICIIMacro constant exported by the header.
SID_BASE0xd400C64 memory-map or device-register constant.
SID_VOICE1_FREQ_LO0xd400C64 memory-map or device-register constant.
SID_VOICE1_FREQ_HI0xd401C64 memory-map or device-register constant.
SID_VOICE1_PULSE_LO0xd402C64 memory-map or device-register constant.
SID_VOICE1_PULSE_HI0xd403C64 memory-map or device-register constant.
SID_VOICE1_CONTROL0xd404C64 memory-map or device-register constant.
SID_VOICE1_ATTACK_DECAY0xd405C64 memory-map or device-register constant.
SID_VOICE1_SUSTAIN_RELEASE0xd406C64 memory-map or device-register constant.
SID_VOICE2_FREQ_LO0xd407C64 memory-map or device-register constant.
SID_VOICE2_FREQ_HI0xd408C64 memory-map or device-register constant.
SID_VOICE2_PULSE_LO0xd409C64 memory-map or device-register constant.
SID_VOICE2_PULSE_HI0xd40aC64 memory-map or device-register constant.
SID_VOICE2_CONTROL0xd40bC64 memory-map or device-register constant.
SID_VOICE2_ATTACK_DECAY0xd40cC64 memory-map or device-register constant.
SID_VOICE2_SUSTAIN_RELEASE0xd40dC64 memory-map or device-register constant.
SID_VOICE3_FREQ_LO0xd40eC64 memory-map or device-register constant.
SID_VOICE3_FREQ_HI0xd40fC64 memory-map or device-register constant.
SID_VOICE3_PULSE_LO0xd410C64 memory-map or device-register constant.
SID_VOICE3_PULSE_HI0xd411C64 memory-map or device-register constant.
SID_VOICE3_CONTROL0xd412C64 memory-map or device-register constant.
SID_VOICE3_ATTACK_DECAY0xd413C64 memory-map or device-register constant.
SID_VOICE3_SUSTAIN_RELEASE0xd414C64 memory-map or device-register constant.
SID_FILTER_CUTOFF_LO0xd415C64 memory-map or device-register constant.
SID_FILTER_CUTOFF_HI0xd416C64 memory-map or device-register constant.
SID_FILTER_RESONANCE0xd417C64 memory-map or device-register constant.
SID_VOLUME_FILTER_MODE0xd418C64 memory-map or device-register constant.
SID_POT_X0xd419C64 memory-map or device-register constant.
SID_POT_Y0xd41aC64 memory-map or device-register constant.
SID_OSC3_RANDOM0xd41bC64 memory-map or device-register constant.
SID_ENV30xd41cC64 memory-map or device-register constant.
SID_WAVE_TRIANGLE0x10C64 memory-map or device-register constant.
SID_WAVE_SAW0x20C64 memory-map or device-register constant.
SID_WAVE_PULSE0x40C64 memory-map or device-register constant.
SID_WAVE_NOISE0x80C64 memory-map or device-register constant.
SID_GATE0x01C64 memory-map or device-register constant.
SID_SYNC0x02C64 memory-map or device-register constant.
SID_RING_MOD0x04C64 memory-map or device-register constant.
SID_TEST0x08C64 memory-map or device-register constant.
SID((volatile c64_sid_registers*)SID_BASE)Typed pointer or expression macro.
CIA1_BASE0xdc00CIA, keyboard, and joyport registers.
CIA1_PRA0xdc00C64 memory-map or device-register constant.
CIA1_PRB0xdc01C64 memory-map or device-register constant.
CIA1_DDRA0xdc02C64 memory-map or device-register constant.
CIA1_DDRB0xdc03C64 memory-map or device-register constant.
CIA1_TIMER_A_LO0xdc04C64 memory-map or device-register constant.
CIA1_TIMER_A_HI0xdc05C64 memory-map or device-register constant.
CIA1_TIMER_B_LO0xdc06C64 memory-map or device-register constant.
CIA1_TIMER_B_HI0xdc07C64 memory-map or device-register constant.
CIA1_TOD_10THS0xdc08C64 memory-map or device-register constant.
CIA1_TOD_SECONDS0xdc09C64 memory-map or device-register constant.
CIA1_TOD_MINUTES0xdc0aC64 memory-map or device-register constant.
CIA1_TOD_HOURS0xdc0bC64 memory-map or device-register constant.
CIA1_SERIAL_DATA0xdc0cC64 memory-map or device-register constant.
CIA1_INTERRUPT_CONTROL0xdc0dC64 memory-map or device-register constant.
CIA1_CONTROL_A0xdc0eC64 memory-map or device-register constant.
CIA1_CONTROL_B0xdc0fC64 memory-map or device-register constant.
CIA2_BASE0xdd00C64 memory-map or device-register constant.
CIA2_PRA0xdd00C64 memory-map or device-register constant.
CIA2_PRB0xdd01C64 memory-map or device-register constant.
CIA2_DDRA0xdd02C64 memory-map or device-register constant.
CIA2_DDRB0xdd03C64 memory-map or device-register constant.
CIA2_TIMER_A_LO0xdd04C64 memory-map or device-register constant.
CIA2_TIMER_A_HI0xdd05C64 memory-map or device-register constant.
CIA2_TIMER_B_LO0xdd06C64 memory-map or device-register constant.
CIA2_TIMER_B_HI0xdd07C64 memory-map or device-register constant.
CIA2_TOD_10THS0xdd08C64 memory-map or device-register constant.
CIA2_TOD_SECONDS0xdd09C64 memory-map or device-register constant.
CIA2_TOD_MINUTES0xdd0aC64 memory-map or device-register constant.
CIA2_TOD_HOURS0xdd0bC64 memory-map or device-register constant.
CIA2_SERIAL_DATA0xdd0cC64 memory-map or device-register constant.
CIA2_INTERRUPT_CONTROL0xdd0dC64 memory-map or device-register constant.
CIA2_CONTROL_A0xdd0eC64 memory-map or device-register constant.
CIA2_CONTROL_B0xdd0fC64 memory-map or device-register constant.
CIA1((volatile c64_cia_registers*)CIA1_BASE)Typed pointer or expression macro.
CIA2((volatile c64_cia_registers*)CIA2_BASE)Typed pointer or expression macro.
KEYBOARD_COLUMN_PORT0xdc00Macro constant exported by the header.
KEYBOARD_ROW_PORT0xdc01Macro constant exported by the header.
KEYBOARD_COLUMN_DDR0xdc02Macro constant exported by the header.
KEYBOARD_ROW_DDR0xdc03Macro constant exported by the header.
KEYBOARD_ACTIVE_MASK0xffMacro constant exported by the header.
JOYPORT_10xdc01Macro constant exported by the header.
JOYPORT_20xdc00Macro constant exported by the header.
JOY_UP0x01Macro constant exported by the header.
JOY_DOWN0x02Macro constant exported by the header.
JOY_LEFT0x04Macro constant exported by the header.
JOY_RIGHT0x08Macro constant exported by the header.
JOY_FIRE0x10Macro constant exported by the header.
JOY_ACTIVE_LOW0x00Macro constant exported by the header.
JOY_RELEASED_MASK0x1fMacro constant exported by the header.
JOY2_UP(!(CIA1->pra & JOY_UP))Macro constant exported by the header.
JOY2_DOWN(!(CIA1->pra & JOY_DOWN))Macro constant exported by the header.
JOY2_LEFT(!(CIA1->pra & JOY_LEFT))Macro constant exported by the header.
JOY2_RIGHT(!(CIA1->pra & JOY_RIGHT))Macro constant exported by the header.
JOY2_FIRE(!(CIA1->pra & JOY_FIRE))Macro constant exported by the header.
JOY_UP_P(v)(!((v) & JOY_UP))Macro constant exported by the header.
JOY_DOWN_P(v)(!((v) & JOY_DOWN))Macro constant exported by the header.
JOY_LEFT_P(v)(!((v) & JOY_LEFT))Macro constant exported by the header.
JOY_RIGHT_P(v)(!((v) & JOY_RIGHT))Macro constant exported by the header.
JOY_FIRE_P(v)(!((v) & JOY_FIRE))Macro constant exported by the header.
VIC_BORDER_COLORVIC_BORDERConvenience aliases.
VIC_BACKGROUND_COLORVIC_BACKGROUNDC64 memory-map or device-register constant.
VIC_SPRITE_POINTERSVIC_SPRITE_POINTER_BASEC64 memory-map or device-register constant.
BORDER_COLORVIC->border_colorMacro constant exported by the header.
BACKGROUND_COLORVIC->background_color0Macro constant exported by the header.
SPRITE_ENABLEVIC->sprite_enableMacro constant exported by the header.
SPRITE_MULTICOLORVIC->sprite_multicolorMacro constant exported by the header.
KERNAL_CHROUT0xffd2Common KERNAL entry points.
KERNAL_CHRIN0xffcfMacro constant exported by the header.
KERNAL_GETIN0xffe4Macro constant exported by the header.
KERNAL_SCNKEY0xff9fMacro constant exported by the header.
KERNAL_PLOT0xfff0Macro constant exported by the header.
KERNAL_SETLFS0xffbaMacro constant exported by the header.
KERNAL_SETNAM0xffbdMacro constant exported by the header.
KERNAL_LOAD0xffd5Macro constant exported by the header.
KERNAL_SAVE0xffd8Macro constant exported by the header.

Header listing:

#ifndef WEB64_C64_H
#define WEB64_C64_H

/* Common C64 memory map. */
#define C64_RAM_BASE 0x0000
#define C64_BASIC_START 0x0801
#define C64_SCREEN_RAM 0x0400
#define C64_COLOR_RAM 0xd800
#define C64_CHAR_ROM 0xd000
#define C64_IO_BASE 0xd000
#define C64_KERNAL_ROM 0xe000

typedef unsigned char c64_reg8_t;

typedef struct c64_cpu_port_registers {
    volatile c64_reg8_t data_direction;
    volatile c64_reg8_t data;
} c64_cpu_port_registers;

typedef struct c64_screen_ram {
    volatile c64_reg8_t cells[1000];
} c64_screen_ram;

typedef struct c64_color_ram {
    volatile c64_reg8_t cells[1000];
} c64_color_ram;

#define C64_CPU_PORT ((volatile c64_cpu_port_registers*)0x0000)
#define C64_SCREEN ((volatile c64_screen_ram*)C64_SCREEN_RAM)
#define C64_COLOR ((volatile c64_color_ram*)C64_COLOR_RAM)

/* VIC-II registers. */
typedef struct c64_vicii_registers {
    volatile c64_reg8_t sprite0_x;
    volatile c64_reg8_t sprite0_y;
    volatile c64_reg8_t sprite1_x;
    volatile c64_reg8_t sprite1_y;
    volatile c64_reg8_t sprite2_x;
    volatile c64_reg8_t sprite2_y;
    volatile c64_reg8_t sprite3_x;
    volatile c64_reg8_t sprite3_y;
    volatile c64_reg8_t sprite4_x;
    volatile c64_reg8_t sprite4_y;
    volatile c64_reg8_t sprite5_x;
    volatile c64_reg8_t sprite5_y;
    volatile c64_reg8_t sprite6_x;
    volatile c64_reg8_t sprite6_y;
    volatile c64_reg8_t sprite7_x;
    volatile c64_reg8_t sprite7_y;
    volatile c64_reg8_t sprite_x_msb;
    volatile c64_reg8_t control1;
    volatile c64_reg8_t raster;
    volatile c64_reg8_t lightpen_x;
    volatile c64_reg8_t lightpen_y;
    volatile c64_reg8_t sprite_enable;
    volatile c64_reg8_t control2;
    volatile c64_reg8_t sprite_y_expand;
    volatile c64_reg8_t memory_setup;
    volatile c64_reg8_t interrupt_status;
    volatile c64_reg8_t interrupt_enable;
    volatile c64_reg8_t sprite_priority;
    volatile c64_reg8_t sprite_multicolor;
    volatile c64_reg8_t sprite_x_expand;
    volatile c64_reg8_t sprite_collision;
    volatile c64_reg8_t data_collision;
    volatile c64_reg8_t border_color;
    volatile c64_reg8_t background_color0;
    volatile c64_reg8_t background_color1;
    volatile c64_reg8_t background_color2;
    volatile c64_reg8_t background_color3;
    volatile c64_reg8_t sprite_multicolor0;
    volatile c64_reg8_t sprite_multicolor1;
    volatile c64_reg8_t sprite0_color;
    volatile c64_reg8_t sprite1_color;
    volatile c64_reg8_t sprite2_color;
    volatile c64_reg8_t sprite3_color;
    volatile c64_reg8_t sprite4_color;
    volatile c64_reg8_t sprite5_color;
    volatile c64_reg8_t sprite6_color;
    volatile c64_reg8_t sprite7_color;
} c64_vicii_registers;

#define VIC_BASE 0xd000
#define VIC_SPRITE0_X 0xd000
#define VIC_SPRITE0_Y 0xd001
#define VIC_SPRITE1_X 0xd002
#define VIC_SPRITE1_Y 0xd003
#define VIC_SPRITE2_X 0xd004
#define VIC_SPRITE2_Y 0xd005
#define VIC_SPRITE3_X 0xd006
#define VIC_SPRITE3_Y 0xd007
#define VIC_SPRITE4_X 0xd008
#define VIC_SPRITE4_Y 0xd009
#define VIC_SPRITE5_X 0xd00a
#define VIC_SPRITE5_Y 0xd00b
#define VIC_SPRITE6_X 0xd00c
#define VIC_SPRITE6_Y 0xd00d
#define VIC_SPRITE7_X 0xd00e
#define VIC_SPRITE7_Y 0xd00f
#define VIC_SPRITE_X_MSB 0xd010
#define VIC_CONTROL1 0xd011
#define VIC_RASTER 0xd012
#define VIC_LIGHTPEN_X 0xd013
#define VIC_LIGHTPEN_Y 0xd014
#define VIC_SPRITE_ENABLE 0xd015
#define VIC_CONTROL2 0xd016
#define VIC_SPRITE_Y_EXPAND 0xd017
#define VIC_MEMORY_SETUP 0xd018
#define VIC_INTERRUPT_STATUS 0xd019
#define VIC_INTERRUPT_ENABLE 0xd01a
#define VIC_SPRITE_PRIORITY 0xd01b
#define VIC_SPRITE_MULTICOLOR 0xd01c
#define VIC_SPRITE_X_EXPAND 0xd01d
#define VIC_SPRITE_COLLISION 0xd01e
#define VIC_DATA_COLLISION 0xd01f
#define VIC_BORDER 0xd020
#define VIC_BACKGROUND 0xd021
#define VIC_BACKGROUND0 0xd021
#define VIC_BACKGROUND1 0xd022
#define VIC_BACKGROUND2 0xd023
#define VIC_BACKGROUND3 0xd024
#define VIC_SPRITE_MULTICOLOR0 0xd025
#define VIC_SPRITE_MULTICOLOR1 0xd026
#define VIC_SPRITE0_COLOR 0xd027
#define VIC_SPRITE1_COLOR 0xd028
#define VIC_SPRITE2_COLOR 0xd029
#define VIC_SPRITE3_COLOR 0xd02a
#define VIC_SPRITE4_COLOR 0xd02b
#define VIC_SPRITE5_COLOR 0xd02c
#define VIC_SPRITE6_COLOR 0xd02d
#define VIC_SPRITE7_COLOR 0xd02e
#define VIC_COLOR_BLACK 0x00
#define VIC_COLOR_WHITE 0x01
#define VIC_COLOR_RED 0x02
#define VIC_COLOR_CYAN 0x03
#define VIC_COLOR_PURPLE 0x04
#define VIC_COLOR_GREEN 0x05
#define VIC_COLOR_BLUE 0x06
#define VIC_COLOR_YELLOW 0x07
#define VIC_COLOR_ORANGE 0x08
#define VIC_COLOR_BROWN 0x09
#define VIC_COLOR_LIGHT_RED 0x0a
#define VIC_COLOR_DARK_GRAY 0x0b
#define VIC_COLOR_GRAY 0x0c
#define VIC_COLOR_LIGHT_GREEN 0x0d
#define VIC_COLOR_LIGHT_BLUE 0x0e
#define VIC_COLOR_LIGHT_GRAY 0x0f
#define COLOR_BLACK VIC_COLOR_BLACK
#define COLOR_WHITE VIC_COLOR_WHITE
#define COLOR_RED VIC_COLOR_RED
#define COLOR_CYAN VIC_COLOR_CYAN
#define COLOR_PURPLE VIC_COLOR_PURPLE
#define COLOR_GREEN VIC_COLOR_GREEN
#define COLOR_BLUE VIC_COLOR_BLUE
#define COLOR_YELLOW VIC_COLOR_YELLOW
#define COLOR_ORANGE VIC_COLOR_ORANGE
#define COLOR_BROWN VIC_COLOR_BROWN
#define COLOR_LIGHTRED VIC_COLOR_LIGHT_RED
#define COLOR_GRAY1 VIC_COLOR_DARK_GRAY
#define COLOR_GRAY2 VIC_COLOR_GRAY
#define COLOR_LIGHTGREEN VIC_COLOR_LIGHT_GREEN
#define COLOR_LIGHTBLUE VIC_COLOR_LIGHT_BLUE
#define COLOR_GRAY3 VIC_COLOR_LIGHT_GRAY
#define VIC_SPRITE_POINTER_BASE 0x07f8
#define VICII ((volatile c64_vicii_registers*)VIC_BASE)
#define VIC VICII

/* SID registers. */
typedef struct c64_sid_voice_registers {
    volatile c64_reg8_t freq_lo;
    volatile c64_reg8_t freq_hi;
    volatile c64_reg8_t pulse_lo;
    volatile c64_reg8_t pulse_hi;
    volatile c64_reg8_t control;
    volatile c64_reg8_t attack_decay;
    volatile c64_reg8_t sustain_release;
} c64_sid_voice_registers;

typedef struct c64_sid_registers {
    volatile c64_reg8_t voice1_freq_lo;
    volatile c64_reg8_t voice1_freq_hi;
    volatile c64_reg8_t voice1_pulse_lo;
    volatile c64_reg8_t voice1_pulse_hi;
    volatile c64_reg8_t voice1_control;
    volatile c64_reg8_t voice1_attack_decay;
    volatile c64_reg8_t voice1_sustain_release;
    volatile c64_reg8_t voice2_freq_lo;
    volatile c64_reg8_t voice2_freq_hi;
    volatile c64_reg8_t voice2_pulse_lo;
    volatile c64_reg8_t voice2_pulse_hi;
    volatile c64_reg8_t voice2_control;
    volatile c64_reg8_t voice2_attack_decay;
    volatile c64_reg8_t voice2_sustain_release;
    volatile c64_reg8_t voice3_freq_lo;
    volatile c64_reg8_t voice3_freq_hi;
    volatile c64_reg8_t voice3_pulse_lo;
    volatile c64_reg8_t voice3_pulse_hi;
    volatile c64_reg8_t voice3_control;
    volatile c64_reg8_t voice3_attack_decay;
    volatile c64_reg8_t voice3_sustain_release;
    volatile c64_reg8_t filter_cutoff_lo;
    volatile c64_reg8_t filter_cutoff_hi;
    volatile c64_reg8_t filter_resonance;
    volatile c64_reg8_t volume_filter_mode;
    volatile c64_reg8_t pot_x;
    volatile c64_reg8_t pot_y;
    volatile c64_reg8_t osc3_random;
    volatile c64_reg8_t env3;
} c64_sid_registers;

#define SID_BASE 0xd400
#define SID_VOICE1_FREQ_LO 0xd400
#define SID_VOICE1_FREQ_HI 0xd401
#define SID_VOICE1_PULSE_LO 0xd402
#define SID_VOICE1_PULSE_HI 0xd403
#define SID_VOICE1_CONTROL 0xd404
#define SID_VOICE1_ATTACK_DECAY 0xd405
#define SID_VOICE1_SUSTAIN_RELEASE 0xd406
#define SID_VOICE2_FREQ_LO 0xd407
#define SID_VOICE2_FREQ_HI 0xd408
#define SID_VOICE2_PULSE_LO 0xd409
#define SID_VOICE2_PULSE_HI 0xd40a
#define SID_VOICE2_CONTROL 0xd40b
#define SID_VOICE2_ATTACK_DECAY 0xd40c
#define SID_VOICE2_SUSTAIN_RELEASE 0xd40d
#define SID_VOICE3_FREQ_LO 0xd40e
#define SID_VOICE3_FREQ_HI 0xd40f
#define SID_VOICE3_PULSE_LO 0xd410
#define SID_VOICE3_PULSE_HI 0xd411
#define SID_VOICE3_CONTROL 0xd412
#define SID_VOICE3_ATTACK_DECAY 0xd413
#define SID_VOICE3_SUSTAIN_RELEASE 0xd414
#define SID_FILTER_CUTOFF_LO 0xd415
#define SID_FILTER_CUTOFF_HI 0xd416
#define SID_FILTER_RESONANCE 0xd417
#define SID_VOLUME_FILTER_MODE 0xd418
#define SID_POT_X 0xd419
#define SID_POT_Y 0xd41a
#define SID_OSC3_RANDOM 0xd41b
#define SID_ENV3 0xd41c
#define SID_WAVE_TRIANGLE 0x10
#define SID_WAVE_SAW 0x20
#define SID_WAVE_PULSE 0x40
#define SID_WAVE_NOISE 0x80
#define SID_GATE 0x01
#define SID_SYNC 0x02
#define SID_RING_MOD 0x04
#define SID_TEST 0x08

/* CIA, keyboard, and joyport registers. */
typedef struct c64_cia_registers {
    volatile c64_reg8_t pra;
    volatile c64_reg8_t prb;
    volatile c64_reg8_t ddra;
    volatile c64_reg8_t ddrb;
    volatile c64_reg8_t timer_a_lo;
    volatile c64_reg8_t timer_a_hi;
    volatile c64_reg8_t timer_b_lo;
    volatile c64_reg8_t timer_b_hi;
    volatile c64_reg8_t tod_10ths;
    volatile c64_reg8_t tod_seconds;
    volatile c64_reg8_t tod_minutes;
    volatile c64_reg8_t tod_hours;
    volatile c64_reg8_t serial_data;
    volatile c64_reg8_t interrupt_control;
    volatile c64_reg8_t control_a;
    volatile c64_reg8_t control_b;
} c64_cia_registers;

#define SID ((volatile c64_sid_registers*)SID_BASE)

/* CIA, keyboard, and joyport registers. */
#define CIA1_BASE 0xdc00
#define CIA1_PRA 0xdc00
#define CIA1_PRB 0xdc01
#define CIA1_DDRA 0xdc02
#define CIA1_DDRB 0xdc03
#define CIA1_TIMER_A_LO 0xdc04
#define CIA1_TIMER_A_HI 0xdc05
#define CIA1_TIMER_B_LO 0xdc06
#define CIA1_TIMER_B_HI 0xdc07
#define CIA1_TOD_10THS 0xdc08
#define CIA1_TOD_SECONDS 0xdc09
#define CIA1_TOD_MINUTES 0xdc0a
#define CIA1_TOD_HOURS 0xdc0b
#define CIA1_SERIAL_DATA 0xdc0c
#define CIA1_INTERRUPT_CONTROL 0xdc0d
#define CIA1_CONTROL_A 0xdc0e
#define CIA1_CONTROL_B 0xdc0f
#define CIA2_BASE 0xdd00
#define CIA2_PRA 0xdd00
#define CIA2_PRB 0xdd01
#define CIA2_DDRA 0xdd02
#define CIA2_DDRB 0xdd03
#define CIA2_TIMER_A_LO 0xdd04
#define CIA2_TIMER_A_HI 0xdd05
#define CIA2_TIMER_B_LO 0xdd06
#define CIA2_TIMER_B_HI 0xdd07
#define CIA2_TOD_10THS 0xdd08
#define CIA2_TOD_SECONDS 0xdd09
#define CIA2_TOD_MINUTES 0xdd0a
#define CIA2_TOD_HOURS 0xdd0b
#define CIA2_SERIAL_DATA 0xdd0c
#define CIA2_INTERRUPT_CONTROL 0xdd0d
#define CIA2_CONTROL_A 0xdd0e
#define CIA2_CONTROL_B 0xdd0f
#define CIA1 ((volatile c64_cia_registers*)CIA1_BASE)
#define CIA2 ((volatile c64_cia_registers*)CIA2_BASE)
#define KEYBOARD_COLUMN_PORT 0xdc00
#define KEYBOARD_ROW_PORT 0xdc01
#define KEYBOARD_COLUMN_DDR 0xdc02
#define KEYBOARD_ROW_DDR 0xdc03
#define KEYBOARD_ACTIVE_MASK 0xff
#define JOYPORT_1 0xdc01
#define JOYPORT_2 0xdc00
#define JOY_UP 0x01
#define JOY_DOWN 0x02
#define JOY_LEFT 0x04
#define JOY_RIGHT 0x08
#define JOY_FIRE 0x10
#define JOY_ACTIVE_LOW 0x00
#define JOY_RELEASED_MASK 0x1f
#define JOY2_UP() (!(CIA1->pra & JOY_UP))
#define JOY2_DOWN() (!(CIA1->pra & JOY_DOWN))
#define JOY2_LEFT() (!(CIA1->pra & JOY_LEFT))
#define JOY2_RIGHT() (!(CIA1->pra & JOY_RIGHT))
#define JOY2_FIRE() (!(CIA1->pra & JOY_FIRE))
#define JOY_UP_P(v) (!((v) & JOY_UP))
#define JOY_DOWN_P(v) (!((v) & JOY_DOWN))
#define JOY_LEFT_P(v) (!((v) & JOY_LEFT))
#define JOY_RIGHT_P(v) (!((v) & JOY_RIGHT))
#define JOY_FIRE_P(v) (!((v) & JOY_FIRE))

/* Convenience aliases. */
#define VIC_BORDER_COLOR VIC_BORDER
#define VIC_BACKGROUND_COLOR VIC_BACKGROUND
#define VIC_SPRITE_POINTERS VIC_SPRITE_POINTER_BASE
#define BORDER_COLOR VIC->border_color
#define BACKGROUND_COLOR VIC->background_color0
#define SPRITE_ENABLE VIC->sprite_enable
#define SPRITE_MULTICOLOR VIC->sprite_multicolor

/* Common KERNAL entry points. */
#define KERNAL_CHROUT 0xffd2
#define KERNAL_CHRIN 0xffcf
#define KERNAL_GETIN 0xffe4
#define KERNAL_SCNKEY 0xff9f
#define KERNAL_PLOT 0xfff0
#define KERNAL_SETLFS 0xffba
#define KERNAL_SETNAM 0xffbd
#define KERNAL_LOAD 0xffd5
#define KERNAL_SAVE 0xffd8

#endif

cbm.h

CBM and KERNAL compatibility constants and light Web64 shims.

Included headers: <stdint.h>, <c64.h>.

Macros:

NameValueDescription
CHRINKERNAL_CHRINMacro constant exported by the header.
CHROUTKERNAL_CHROUTMacro constant exported by the header.
GETINKERNAL_GETINMacro constant exported by the header.
LOADKERNAL_LOADMacro constant exported by the header.
SAVEKERNAL_SAVEMacro constant exported by the header.
SETLFSKERNAL_SETLFSMacro constant exported by the header.
SETNAMKERNAL_SETNAMMacro constant exported by the header.

Header listing:

#ifndef WEB64_CBM_H
#define WEB64_CBM_H
#include <stdint.h>
#include <c64.h>
#define CHRIN KERNAL_CHRIN
#define CHROUT KERNAL_CHROUT
#define GETIN KERNAL_GETIN
#define LOAD KERNAL_LOAD
#define SAVE KERNAL_SAVE
#define SETLFS KERNAL_SETLFS
#define SETNAM KERNAL_SETNAM
#endif

conio.h

cc65-style screen and text helpers mapped onto the Web64 SDK surface.

Included headers: <stdint.h>, <c64.h>, <web64.h>.

Functions:

NamePrototypeDescriptionTypical use
cputc_fastcall int cputc(int ch)Function declared by <conio.h>. (fastcall)cputc(...)
cputs_fastcall int cputs(char *text)Function declared by <conio.h>. (fastcall)cputs(...)
textcolor_fastcall int textcolor(int color)Function declared by <conio.h>. (fastcall)textcolor(...)
bordercolor_fastcall int bordercolor(int color)Function declared by <conio.h>. (fastcall)bordercolor(...)
bgcolor_fastcall int bgcolor(int color)Function declared by <conio.h>. (fastcall)bgcolor(...)
wherex_fastcall int wherex(void)Function declared by <conio.h>. (fastcall)wherex(...)
wherey_fastcall int wherey(void)Function declared by <conio.h>. (fastcall)wherey(...)
cputhex8_fastcall int cputhex8(int value)Function declared by <conio.h>. (fastcall)cputhex8(...)

Macros:

NameValueDescription
COLOR_BLACKVIC_COLOR_BLACKColor alias constant for VIC palette values.
COLOR_WHITEVIC_COLOR_WHITEColor alias constant for VIC palette values.
COLOR_REDVIC_COLOR_REDColor alias constant for VIC palette values.
COLOR_CYANVIC_COLOR_CYANColor alias constant for VIC palette values.
COLOR_PURPLEVIC_COLOR_PURPLEColor alias constant for VIC palette values.
COLOR_GREENVIC_COLOR_GREENColor alias constant for VIC palette values.
COLOR_BLUEVIC_COLOR_BLUEColor alias constant for VIC palette values.
COLOR_YELLOWVIC_COLOR_YELLOWColor alias constant for VIC palette values.
COLOR_ORANGEVIC_COLOR_ORANGEColor alias constant for VIC palette values.
COLOR_BROWNVIC_COLOR_BROWNColor alias constant for VIC palette values.
COLOR_LIGHTREDVIC_COLOR_LIGHT_REDColor alias constant for VIC palette values.
COLOR_GRAY1VIC_COLOR_DARK_GRAYColor alias constant for VIC palette values.
COLOR_GRAY2VIC_COLOR_GRAYColor alias constant for VIC palette values.
COLOR_LIGHTGREENVIC_COLOR_LIGHT_GREENColor alias constant for VIC palette values.
COLOR_LIGHTBLUEVIC_COLOR_LIGHT_BLUEColor alias constant for VIC palette values.
COLOR_GRAY3VIC_COLOR_LIGHT_GRAYColor alias constant for VIC palette values.
CH_ENTER13Macro constant exported by the header.
CH_ESC27Macro constant exported by the header.
CH_DEL20Macro constant exported by the header.
CH_CURS_LEFT157Macro constant exported by the header.
CH_CURS_RIGHT29Macro constant exported by the header.
CH_CURS_UP145Macro constant exported by the header.
CH_CURS_DOWN17Macro constant exported by the header.

Header listing:

#ifndef WEB64_CONIO_H
#define WEB64_CONIO_H
#include <stdint.h>
#include <c64.h>
#include <web64.h>
#define COLOR_BLACK VIC_COLOR_BLACK
#define COLOR_WHITE VIC_COLOR_WHITE
#define COLOR_RED VIC_COLOR_RED
#define COLOR_CYAN VIC_COLOR_CYAN
#define COLOR_PURPLE VIC_COLOR_PURPLE
#define COLOR_GREEN VIC_COLOR_GREEN
#define COLOR_BLUE VIC_COLOR_BLUE
#define COLOR_YELLOW VIC_COLOR_YELLOW
#define COLOR_ORANGE VIC_COLOR_ORANGE
#define COLOR_BROWN VIC_COLOR_BROWN
#define COLOR_LIGHTRED VIC_COLOR_LIGHT_RED
#define COLOR_GRAY1 VIC_COLOR_DARK_GRAY
#define COLOR_GRAY2 VIC_COLOR_GRAY
#define COLOR_LIGHTGREEN VIC_COLOR_LIGHT_GREEN
#define COLOR_LIGHTBLUE VIC_COLOR_LIGHT_BLUE
#define COLOR_GRAY3 VIC_COLOR_LIGHT_GRAY
extern _fastcall int cputc(int ch);
extern _fastcall int cputs(char *text);
extern _fastcall int textcolor(int color);
extern _fastcall int bordercolor(int color);
extern _fastcall int bgcolor(int color);
extern _fastcall int wherex(void);
extern _fastcall int wherey(void);
extern _fastcall int cputhex8(int value);
#define CH_ENTER 13
#define CH_ESC 27
#define CH_DEL 20
#define CH_CURS_LEFT 157
#define CH_CURS_RIGHT 29
#define CH_CURS_UP 145
#define CH_CURS_DOWN 17
#endif

ctype.h

ASCII-oriented character classification and case-conversion declarations backed by the Web64 runtime.

Functions:

NamePrototypeDescriptionTypical use
isdigit_fastcall int isdigit(int c)Returns nonzero when the byte is an ASCII decimal digit. (fastcall)if (isdigit(ch)) { ... }
isalnum_fastcall int isalnum(int c)Returns nonzero when the byte is an ASCII letter or digit. (fastcall)if (isalnum(ch)) { ... }
isalpha_fastcall int isalpha(int c)Returns nonzero when the byte is an ASCII letter. (fastcall)if (isalpha(ch)) { ... }
isspace_fastcall int isspace(int c)Returns nonzero when the byte is an ASCII whitespace character. (fastcall)if (isspace(ch)) { ... }
islower_fastcall int islower(int c)Returns nonzero when the byte is a lowercase ASCII letter. (fastcall)if (islower(ch)) { ... }
isupper_fastcall int isupper(int c)Returns nonzero when the byte is an uppercase ASCII letter. (fastcall)if (isupper(ch)) { ... }
tolower_fastcall int tolower(int c)Converts an uppercase ASCII letter to lowercase when applicable. (fastcall)ch = tolower(ch);
toupper_fastcall int toupper(int c)Converts a lowercase ASCII letter to uppercase when applicable. (fastcall)ch = toupper(ch);

Header listing:

#ifndef WEB64_CTYPE_H
#define WEB64_CTYPE_H
/* Web64 tiny ctype parameter: c is the byte character/classification value in A for _fastcall calls. */
extern _fastcall int isdigit(int c);
extern _fastcall int isalnum(int c);
extern _fastcall int isalpha(int c);
extern _fastcall int isspace(int c);
extern _fastcall int islower(int c);
extern _fastcall int isupper(int c);
extern _fastcall int tolower(int c);
extern _fastcall int toupper(int c);
#endif

joy.h

Minimal joystick helper for reading the active C64 port state.

Included headers: <stdint.h>, <c64.h>.

Functions:

NamePrototypeDescriptionTypical use
joy_readuint8_t joy_read(void)Reads the current joystick bitfield from the configured port helper.uint8_t state = joy_read();

Header listing:

#ifndef WEB64_JOY_H
#define WEB64_JOY_H
#include <stdint.h>
#include <c64.h>
uint8_t joy_read(void);
#endif

joystick.h

cc65-familiar joystick constants and helpers without native driver loading.

Included headers: <stdint.h>, <c64.h>.

Functions:

NamePrototypeDescriptionTypical use
joy_read_fastcall uint8_t joy_read(uint8_t port)Reads the current joystick bitfield from the configured port helper. (fastcall)uint8_t state = joy_read();
web64_joy_read_fastcall uint8_t web64_joy_read(uint8_t port)Web64 SDK runtime helper. (fastcall)web64_joy_read(...)

Macros:

NameValueDescription
JOY_11Macro constant exported by the header.
JOY_22Macro constant exported by the header.
JOY_BTN_1JOY_FIREMacro constant exported by the header.

Header listing:

#ifndef WEB64_JOYSTICK_H
#define WEB64_JOYSTICK_H
#include <stdint.h>
#include <c64.h>
#define JOY_1 1
#define JOY_2 2
#define JOY_BTN_1 JOY_FIRE
extern _fastcall uint8_t joy_read(uint8_t port);
extern _fastcall uint8_t web64_joy_read(uint8_t port);
#endif

libc.h

Aggregate convenience header over the dependency-linked Web64 standard library surface.

Included headers: <stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <ctype.h>.

Macros:

NameValueDescription
INT_MAX0x7fffWeb64 aggregate convenience header. Implementations are linked only when called.
INT_MIN0x8000Macro constant exported by the header.

Header listing:

#ifndef WEB64_LIBC_H
#define WEB64_LIBC_H
/* Web64 aggregate convenience header. Implementations are linked only when called. */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define INT_MAX 0x7fff
#define INT_MIN 0x8000
#endif

peekpoke.h

PEEK/POKE helper macros for byte and word memory access.

Included headers: <stdint.h>.

Macros:

NameValueDescription
PEEK(address)((volatile uint8_t)(address))Macro constant exported by the header.
POKE(address, value)((volatile uint8_t)(address) = (uint8_t)(value))Macro constant exported by the header.
PEEKW(address)((volatile uint16_t)(address))Macro constant exported by the header.
POKEW(address, value)((volatile uint16_t)(address) = (uint16_t)(value))Macro constant exported by the header.

Header listing:

#ifndef WEB64_PEEKPOKE_H
#define WEB64_PEEKPOKE_H
#include <stdint.h>
#define PEEK(address) (*(volatile uint8_t*)(address))
#define POKE(address, value) (*(volatile uint8_t*)(address) = (uint8_t)(value))
#define PEEKW(address) (*(volatile uint16_t*)(address))
#define POKEW(address, value) (*(volatile uint16_t*)(address) = (uint16_t)(value))
#endif

sprite.h

Small sprite helper API for position, color, and enable writes.

Included headers: <stdint.h>, <c64.h>.

Functions:

NamePrototypeDescriptionTypical use
sprite_set_posvoid sprite_set_pos(uint8_t sprite_id, uint16_t x, uint8_t y)Writes a hardware sprite position, including X MSB handling.sprite_set_pos(0, x, y);
sprite_enablevoid sprite_enable(uint8_t mask)Sets the VIC sprite enable mask through the helper runtime.sprite_enable(0x03);
sprite_set_colorvoid sprite_set_color(uint8_t sprite_id, uint8_t color)Writes a sprite color register for the selected hardware sprite.sprite_set_color(0, COLOR_BLUE);

Header listing:

#ifndef WEB64_SPRITE_H
#define WEB64_SPRITE_H
#include <stdint.h>
#include <c64.h>
void sprite_set_pos(uint8_t sprite_id, uint16_t x, uint8_t y);
void sprite_enable(uint8_t mask);
void sprite_set_color(uint8_t sprite_id, uint8_t color);
#endif

stdbool.h

Boolean language aliases and constants.

Macros:

NameValueDescription
bool_BoolMacro constant exported by the header.
true1Boolean literal alias.
false0Boolean literal alias.
__bool_true_false_are_defined1Confirms that boolean macros are available.

Header listing:

#ifndef WEB64_STDBOOL_H
#define WEB64_STDBOOL_H
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif

stddef.h

Core pointer-sized typedefs and NULL.

Typedefs:

NameDeclarationDescription
size_ttypedef unsigned int size_t;Unsigned byte-count type for object sizes and lengths.
ptrdiff_ttypedef signed int ptrdiff_t;Signed pointer-difference type.

Macros:

NameValueDescription
NULL0Null pointer constant.

Header listing:

#ifndef WEB64_STDDEF_H
#define WEB64_STDDEF_H
typedef unsigned int size_t;
typedef signed int ptrdiff_t;
#define NULL 0
#endif

stdint.h

Fixed-width integer typedefs and limit macros.

Typedefs:

NameDeclarationDescription
uint8_ttypedef unsigned char uint8_t;Unsigned 8-bit integer type.
uint16_ttypedef unsigned int uint16_t;Unsigned 16-bit integer type.
uint32_ttypedef unsigned long uint32_t;Unsigned 32-bit integer type.
int8_ttypedef signed char int8_t;Signed 8-bit integer type.
int16_ttypedef signed int int16_t;Signed 16-bit integer type.
int32_ttypedef signed long int32_t;Signed 32-bit integer type.
intptr_ttypedef int16_t intptr_t;Alias for int16_t.
uintptr_ttypedef uint16_t uintptr_t;Alias for uint16_t.
intmax_ttypedef int32_t intmax_t;Alias for int32_t.
uintmax_ttypedef uint32_t uintmax_t;Alias for uint32_t.
int_least8_ttypedef int8_t int_least8_t;Alias for int8_t.
uint_least8_ttypedef uint8_t uint_least8_t;Alias for uint8_t.
int_least16_ttypedef int16_t int_least16_t;Alias for int16_t.
uint_least16_ttypedef uint16_t uint_least16_t;Alias for uint16_t.
int_least32_ttypedef int32_t int_least32_t;Alias for int32_t.
uint_least32_ttypedef uint32_t uint_least32_t;Alias for uint32_t.
int_fast8_ttypedef int8_t int_fast8_t;Alias for int8_t.
uint_fast8_ttypedef uint8_t uint_fast8_t;Alias for uint8_t.
int_fast16_ttypedef int16_t int_fast16_t;Alias for int16_t.
uint_fast16_ttypedef uint16_t uint_fast16_t;Alias for uint16_t.
int_fast32_ttypedef int32_t int_fast32_t;Alias for int32_t.
uint_fast32_ttypedef uint32_t uint_fast32_t;Alias for uint32_t.

Macros:

NameValueDescription
INT8_MIN0x80Macro constant exported by the header.
INT8_MAX0x7fMacro constant exported by the header.
UINT8_MAX0xffMacro constant exported by the header.
INT16_MIN0x8000Macro constant exported by the header.
INT16_MAX0x7fffMacro constant exported by the header.
UINT16_MAX0xffffMacro constant exported by the header.
UINT32_MAX0xffffffffULMacro constant exported by the header.

Header listing:

#ifndef WEB64_STDINT_H
#define WEB64_STDINT_H
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed int int16_t;
typedef signed long int32_t;
typedef int16_t intptr_t;
typedef uint16_t uintptr_t;
typedef int32_t intmax_t;
typedef uint32_t uintmax_t;
typedef int8_t int_least8_t;
typedef uint8_t uint_least8_t;
typedef int16_t int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t int_least32_t;
typedef uint32_t uint_least32_t;
typedef int8_t int_fast8_t;
typedef uint8_t uint_fast8_t;
typedef int16_t int_fast16_t;
typedef uint16_t uint_fast16_t;
typedef int32_t int_fast32_t;
typedef uint32_t uint_fast32_t;
#define INT8_MIN 0x80
#define INT8_MAX 0x7f
#define UINT8_MAX 0xff
#define INT16_MIN 0x8000
#define INT16_MAX 0x7fff
#define UINT16_MAX 0xffff
#define UINT32_MAX 0xffffffffUL
#endif

stdio.h

Tiny stdio surface: putchar, puts, and compiler-lowered literal printf.

Functions:

NamePrototypeDescriptionTypical use
putchar_fastcall int putchar(int c)Writes one character to the current text output. (fastcall)putchar('A');
puts_fastcall int puts(const char *str)Writes a zero-terminated string and a trailing newline. (fastcall)puts("READY");
printfint printf(const char *format, ...)Formats a literal format string through the compiler-lowered Web64 printf subset.printf("SCORE %d", score);

Macros:

NameValueDescription
EOF0xffffEnd-of-file or error return value constant.

Header listing:

#ifndef WEB64_STDIO_H
#define WEB64_STDIO_H
#define EOF 0xffff
/* Web64 tiny stdio surface: putchar/puts are runtime calls; printf is compiler-lowered for literal formats with %d values. */
extern _fastcall int putchar(int c);
extern _fastcall int puts(const char *str);
extern int printf(const char *format, ...);
#endif

stdlib.h

Tiny stdlib surface: abs, atoi, rand, srand, and abort.

Functions:

NamePrototypeDescriptionTypical use
absint abs(int j)Returns the absolute value of a signed integer.int magnitude = abs(value);
atoiint atoi(const char *s)Parses a decimal C string into an integer.int number = atoi(text);
rand_fastcall int rand(void)Returns a small pseudo-random integer up to RAND_MAX. (fastcall)uint8_t value = rand() & 0x0f;
srand_fastcall void srand(unsigned int seed)Seeds the runtime random generator. (fastcall)srand(0x1234);
abortvoid abort(void)Stops execution immediately through the runtime abort path.if (fatal) abort();

Macros:

NameValueDescription
RAND_MAX0x00ffLargest value returned by the active random helper.

Header listing:

#ifndef WEB64_STDLIB_H
#define WEB64_STDLIB_H
#define RAND_MAX 0x00ff
/* Web64 tiny stdlib parameters: j=value, s=C string pointer, seed=byte random seed. */
extern int abs(int j);
extern int atoi(const char *s);
extern _fastcall int rand(void);
extern _fastcall void srand(unsigned int seed);
void abort(void);
#endif

string.h

Byte and C-string manipulation declarations backed by the Web64 runtime.

Included headers: <stddef.h>.

Functions:

NamePrototypeDescriptionTypical use
memchrvoid memchr(const void s, int c, size_t n)Scans the first n bytes for a byte value and returns its address when found.char *hit = memchr(buffer, 0, count);
memcmpint memcmp(const void s1, const void s2, size_t n)Compares two byte ranges and returns less than, equal to, or greater than zero.if (memcmp(a, b, size) == 0) { ... }
memcpyvoid memcpy(void s1, const void *s2, size_t n)Copies n bytes from source to destination without overlap handling.memcpy(dest, src, size);
memmovevoid memmove(void s1, const void *s2, size_t n)Copies n bytes while allowing overlapping ranges.memmove(dest, src, size);
memsetvoid memset(void s, int c, size_t n)Fills n bytes with a constant byte value.memset(screen, 32, 1000);
strcatchar strcat(char s1, const char *s2)Appends one C string to another destination buffer.strcat(buffer, suffix);
strchrchar strchr(const char s, int c)Finds the first matching character in a C string.char *p = strchr(text, ':');
strcmpint strcmp(const char s1, const char s2)Lexicographically compares two C strings.if (strcmp(a, b) == 0) { ... }
strcpychar strcpy(char s1, const char *s2)Copies a source C string including the trailing zero byte.strcpy(dest, src);
strcspnsize_t strcspn(const char s1, const char s2)Counts bytes until any reject character appears.size_t prefix = strcspn(text, ",;");
strlensize_t strlen(const char *s)Returns the byte length of a zero-terminated C string.size_t len = strlen(text);
strncatchar strncat(char s1, const char *s2, size_t n)Appends at most n bytes from a C string.strncat(buffer, suffix, limit);
strncmpint strncmp(const char s1, const char s2, size_t n)Compares at most n bytes of two C strings.if (strncmp(text, "SYS", 3) == 0) { ... }
strncpychar strncpy(char s1, const char *s2, size_t n)Copies at most n bytes from a C string.strncpy(dest, src, limit);
strpbrkchar strpbrk(const char s1, const char *s2)Finds the first character that belongs to a search set.char *p = strpbrk(text, ":=");
strrchrchar strrchr(const char s, int c)Finds the last matching character in a C string.char *ext = strrchr(path, '.');
strspnsize_t strspn(const char s1, const char s2)Counts bytes from the start while all bytes belong to an allowed set.size_t prefix = strspn(text, "0123456789");
strstrchar strstr(const char s1, const char *s2)Finds one C string within another.char *hit = strstr(text, "SID");

Header listing:

#ifndef WEB64_STRING_H
#define WEB64_STRING_H
#include <stddef.h>
/* Web64 tiny string runtime parameters: s/s1=destination pointer, s2=source/search pointer, c=byte value, n=count. */
extern void *memchr(const void *s, int c, size_t n);
extern int memcmp(const void *s1, const void *s2, size_t n);
extern void *memcpy(void *s1, const void *s2, size_t n);
extern void *memmove(void *s1, const void *s2, size_t n);
extern void *memset(void *s, int c, size_t n);
extern char *strcat(char *s1, const char *s2);
extern char *strchr(const char *s, int c);
extern int strcmp(const char *s1, const char *s2);
extern char *strcpy(char *s1, const char *s2);
extern size_t strcspn(const char *s1, const char *s2);
extern size_t strlen(const char *s);
extern char *strncat(char *s1, const char *s2, size_t n);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern char *strncpy(char *s1, const char *s2, size_t n);
extern char *strpbrk(const char *s1, const char *s2);
extern char *strrchr(const char *s, int c);
extern size_t strspn(const char *s1, const char *s2);
extern char *strstr(const char *s1, const char *s2);
#endif

web64.h

General Web64 SDK helpers for timing, text, randomness, simple drawing, and zero-parameter void calls by address.

Included headers: <stdint.h>, <c64.h>.

Functions:

NamePrototypeDescriptionTypical use
delay_framesvoid delay_frames(uint8_t frames)Waits for a number of video frames.delay_frames(5);
delay_msvoid delay_ms(uint16_t milliseconds)Waits approximately the requested number of milliseconds.delay_ms(250);
random8uint8_t random8(void)Returns an 8-bit random value from the Web64 helper runtime.uint8_t value = random8();
clrscrvoid clrscr(void)Clears the active text screen.clrscr();
gotoxyvoid gotoxy(uint8_t x, uint8_t y)Moves the text cursor to an X,Y character position.gotoxy(10, 12);
cprintfvoid cprintf(const char *text)Prints a C string through the current Web64 text output path.cprintf("HELLO");
plot_pixelvoid plot_pixel(uint16_t address, uint8_t value)Writes a byte value to a caller-chosen bitmap or memory address.plot_pixel(address, value);

Macros:

NameValueDescription
VoidCall(addr)((void ()(void))(addr))()Macro constant exported by the header.

Header listing:

#ifndef WEB64_CORE_H
#define WEB64_CORE_H
#include <stdint.h>
#include <c64.h>
#define VoidCall(addr) (*(void (*)(void))(addr))()
void delay_frames(uint8_t frames);
void delay_ms(uint16_t milliseconds);
uint8_t random8(void);
void clrscr(void);
void gotoxy(uint8_t x, uint8_t y);
void cprintf(const char *text);
void plot_pixel(uint16_t address, uint8_t value);
#endif

web64/assets.h

Public Web64 Asset Model v1 descriptor types and constants for generated asset metadata.

Included headers: <stdint.h>.

Typedefs:

NameDeclarationDescription
Web64AssetKindtypedef uint8_t Web64AssetKind;Web64 SDK public alias type.
Web64SpriteModetypedef uint8_t Web64SpriteMode;Web64 SDK public alias type.
Web64MapCellTypetypedef uint8_t Web64MapCellType;Web64 SDK public alias type.
Web64AssetFlagstypedef uint8_t Web64AssetFlags;Web64 SDK public alias type.
Web64Booltypedef uint8_t Web64Bool;Web64 SDK public alias type.
Web64AssetAddresstypedef uint16_t Web64AssetAddress;Web64 SDK public alias type.
Web64AssetReftypedef uint16_t Web64AssetRef;Web64 SDK public alias type.

Structs:

NameDescriptionField summary
Web64CharAssetDescriptor struct used by generated asset metadata or runtime helpers.12 fields: Web64AssetAddress data, uint8_t width_pixels, uint8_t height_pixels, uint8_t bytes_per_char, ...
Web64SpriteAssetDescriptor struct used by generated asset metadata or runtime helpers.21 fields: Web64AssetAddress data, uint16_t byte_size, uint16_t frame_count, uint8_t bytes_per_frame, ...
Web64BlockAssetDescriptor struct used by generated asset metadata or runtime helpers.16 fields: Web64AssetAddress data, uint16_t byte_size, uint8_t width_chars, uint8_t height_chars, ...
Web64MapAssetDescriptor struct used by generated asset metadata or runtime helpers.22 fields: Web64AssetAddress cells, Web64AssetAddress colors, Web64AssetAddress attributes, Web64AssetRef source, ...
Web64SpriteRuntime-facing Web64 helper struct.16 fields: Web64AssetRef asset, uint16_t x, uint8_t y, uint8_t frame, ...
Web64MapViewRuntime-facing Web64 helper struct.8 fields: Web64AssetRef asset, uint16_t map_x, uint16_t map_y, uint8_t screen_x, ...

Macros:

NameValueDescription
WEB64_ASSET_MODEL_VERSION0x0001Macro constant exported by the header.
WEB64_GENERATED_ASSETS_VERSION0x0001Macro constant exported by the header.
WEB64_ASSET_ADDRESS_NONE0x0000Macro constant exported by the header.
WEB64_ASSET_REF_NONE0x0000Macro constant exported by the header.
WEB64_SPRITE_BLOCK_NONE0xffMacro constant exported by the header.
WEB64_ASSET_KIND_BINARY1Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_CHAR2Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_CHARSET3Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_SPRITE_MONO4Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_SPRITE_MC5Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_SPRITE_OVERLAY6Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_BLOCK7Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_BLOCKSET8Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_MAP9Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_SID10Web64 asset kind discriminator constant.
WEB64_ASSET_KIND_SOURCE11Web64 asset kind discriminator constant.
WEB64_SPRITE_MODE_MONO1Sprite asset storage mode constant.
WEB64_SPRITE_MODE_MULTICOLOR2Sprite asset storage mode constant.
WEB64_MAP_CELL_CHAR1Map cell-type discriminator constant.
WEB64_MAP_CELL_BLOCK2Map cell-type discriminator constant.
WEB64_SPRITE_FLAG_ENABLED1Web64 sprite runtime flag bit.
WEB64_SPRITE_FLAG_MULTICOLOR2Web64 sprite runtime flag bit.
WEB64_SPRITE_FLAG_EXPAND_X4Web64 sprite runtime flag bit.
WEB64_SPRITE_FLAG_EXPAND_Y8Web64 sprite runtime flag bit.
WEB64_SPRITE_FLAG_BEHIND_BACKGROUND16Web64 sprite runtime flag bit.
WEB64_CHAR_FLAG_MULTICOLOR1Web64 character asset flag bit.
WEB64_BLOCK_FLAG_HAS_COLORS1Web64 block asset flag bit.
WEB64_BLOCK_FLAG_HAS_ATTRIBUTES2Web64 block asset flag bit.
WEB64_MAP_FLAG_BLOCK_CELLS1Web64 map asset flag bit.
WEB64_MAP_FLAG_HAS_COLORS2Web64 map asset flag bit.
WEB64_MAP_FLAG_HAS_ATTRIBUTES4Web64 map asset flag bit.

Header listing:

#ifndef WEB64_ASSETS_H
#define WEB64_ASSETS_H
#include <stdint.h>
#define WEB64_ASSET_MODEL_VERSION 0x0001
#define WEB64_GENERATED_ASSETS_VERSION 0x0001
#define WEB64_ASSET_ADDRESS_NONE 0x0000
#define WEB64_ASSET_REF_NONE 0x0000
#define WEB64_SPRITE_BLOCK_NONE 0xff
#define WEB64_ASSET_KIND_BINARY 1
#define WEB64_ASSET_KIND_CHAR 2
#define WEB64_ASSET_KIND_CHARSET 3
#define WEB64_ASSET_KIND_SPRITE_MONO 4
#define WEB64_ASSET_KIND_SPRITE_MC 5
#define WEB64_ASSET_KIND_SPRITE_OVERLAY 6
#define WEB64_ASSET_KIND_BLOCK 7
#define WEB64_ASSET_KIND_BLOCKSET 8
#define WEB64_ASSET_KIND_MAP 9
#define WEB64_ASSET_KIND_SID 10
#define WEB64_ASSET_KIND_SOURCE 11
#define WEB64_SPRITE_MODE_MONO 1
#define WEB64_SPRITE_MODE_MULTICOLOR 2
#define WEB64_MAP_CELL_CHAR 1
#define WEB64_MAP_CELL_BLOCK 2
#define WEB64_SPRITE_FLAG_ENABLED 1
#define WEB64_SPRITE_FLAG_MULTICOLOR 2
#define WEB64_SPRITE_FLAG_EXPAND_X 4
#define WEB64_SPRITE_FLAG_EXPAND_Y 8
#define WEB64_SPRITE_FLAG_BEHIND_BACKGROUND 16
#define WEB64_CHAR_FLAG_MULTICOLOR 1
#define WEB64_BLOCK_FLAG_HAS_COLORS 1
#define WEB64_BLOCK_FLAG_HAS_ATTRIBUTES 2
#define WEB64_MAP_FLAG_BLOCK_CELLS 1
#define WEB64_MAP_FLAG_HAS_COLORS 2
#define WEB64_MAP_FLAG_HAS_ATTRIBUTES 4
typedef uint8_t Web64AssetKind;
typedef uint8_t Web64SpriteMode;
typedef uint8_t Web64MapCellType;
typedef uint8_t Web64AssetFlags;
typedef uint8_t Web64Bool;
typedef uint16_t Web64AssetAddress;
typedef uint16_t Web64AssetRef;
typedef struct { Web64AssetAddress data; uint8_t width_pixels; uint8_t height_pixels; uint8_t bytes_per_char; uint8_t mode; uint8_t default_color; } Web64CharAsset;
typedef struct { Web64AssetAddress data; uint16_t byte_size; uint16_t char_count; uint8_t bytes_per_char; uint8_t mode; } Web64CharsetAsset;
typedef struct { Web64AssetAddress data; uint16_t byte_size; uint16_t frame_count; uint8_t bytes_per_frame; uint8_t payload_bytes_per_frame; uint8_t width_pixels; uint8_t height_pixels; uint8_t mode; uint8_t default_color; uint8_t multicolor_1; uint8_t multicolor_2; uint8_t data_block; } Web64SpriteAsset;
typedef struct { Web64AssetRef base; Web64AssetRef overlay; uint16_t frame_count; uint8_t base_color; uint8_t overlay_color; uint8_t multicolor_1; uint8_t multicolor_2; uint8_t flags; } Web64SpriteOverlayAsset;
typedef struct { Web64AssetAddress data; uint16_t byte_size; uint8_t width_chars; uint8_t height_chars; uint8_t char_index_width; uint8_t flags; } Web64BlockAsset;
typedef struct { Web64AssetAddress data; Web64AssetRef charset; uint16_t byte_size; uint16_t block_count; uint8_t width_chars; uint8_t height_chars; uint16_t bytes_per_block; uint8_t index_width; uint8_t flags; } Web64BlockSetAsset;
typedef struct { Web64AssetAddress cells; Web64AssetAddress colors; Web64AssetAddress attributes; Web64AssetRef source; uint16_t width; uint16_t height; uint16_t cell_count; uint8_t cell_type; uint8_t index_width; uint8_t flags; } Web64MapAsset;
typedef struct { Web64AssetAddress data; uint16_t file_size; uint16_t c64_data_offset; uint16_t c64_data_size; uint16_t load_address; uint16_t init_address; uint16_t play_address; uint16_t song_count; uint16_t start_song; uint32_t speed_flags; uint16_t flags; } Web64SidAsset;
typedef struct { Web64AssetRef asset; uint16_t x; uint8_t y; uint8_t frame; uint8_t hardware_sprite; uint8_t data_block; uint8_t color; uint8_t flags; } Web64Sprite;
typedef struct { Web64AssetRef asset; uint16_t x; uint8_t y; uint8_t frame; uint8_t base_hardware_sprite; uint8_t overlay_hardware_sprite; uint8_t flags; } Web64SpriteOverlay;
typedef struct { Web64AssetRef asset; uint16_t map_x; uint16_t map_y; uint8_t screen_x; uint8_t screen_y; uint8_t viewport_width; uint8_t viewport_height; uint8_t flags; } Web64MapView;
#endif

web64/fixed.h

8.8 fixed-point, secondary 16.16 macros, angle8 trig helpers, and vector/motion declarations.

Included headers: <stdint.h>.

Functions:

NamePrototypeDescriptionTypical use
web64_fix8_mulweb64_fix8_8 web64_fix8_mul(web64_fix8_8 a, web64_fix8_8 b)Multiplies signed 8.8 fixed-point values and truncates toward zero.speed = web64_fix8_mul(speed, factor);
web64_fix8_mul_roundweb64_fix8_8 web64_fix8_mul_round(web64_fix8_8 a, web64_fix8_8 b)Multiplies signed 8.8 values and rounds to nearest, half away from zero.speed = web64_fix8_mul_round(speed, factor);
web64_fix8_divweb64_fix8_8 web64_fix8_div(web64_fix8_8 a, web64_fix8_8 b)Divides signed 8.8 fixed-point values through the runtime helper ABI.ratio = web64_fix8_div(a, b);
web64_sin8web64_fix8_8 web64_sin8(web64_angle8 angle)Returns sine as signed 8.8 fixed-point for an angle8 turn fraction.web64_fix8_8 dy = web64_sin8(angle);
web64_cos8web64_fix8_8 web64_cos8(web64_angle8 angle)Returns cosine as signed 8.8 fixed-point for an angle8 turn fraction.web64_fix8_8 dx = web64_cos8(angle);
web64_ufix8_mulweb64_ufix8_8 web64_ufix8_mul(web64_ufix8_8 a, web64_ufix8_8 b)Multiplies unsigned 8.8 fixed-point values.value = web64_ufix8_mul(a, b);
web64_ufix8_divweb64_ufix8_8 web64_ufix8_div(web64_ufix8_8 a, web64_ufix8_8 b)Divides unsigned 8.8 fixed-point values.value = web64_ufix8_div(a, b);
web64_fix8_lerpweb64_fix8_8 web64_fix8_lerp(web64_fix8_8 a, web64_fix8_8 b, uint8_t amount)Interpolates between two signed 8.8 values using an 8-bit amount.value = web64_fix8_lerp(a, b, amount);
web64_fix8_absweb64_fix8_8 web64_fix8_abs(web64_fix8_8 value)Returns the absolute value of a signed 8.8 fixed-point value.speed = web64_fix8_abs(speed);
web64_fix8_minweb64_fix8_8 web64_fix8_min(web64_fix8_8 a, web64_fix8_8 b)Returns the smaller of two signed 8.8 values.limit = web64_fix8_min(a, b);
web64_fix8_maxweb64_fix8_8 web64_fix8_max(web64_fix8_8 a, web64_fix8_8 b)Returns the larger of two signed 8.8 values.limit = web64_fix8_max(a, b);
web64_fix8_clampweb64_fix8_8 web64_fix8_clamp(web64_fix8_8 value, web64_fix8_8 min_value, web64_fix8_8 max_value)Clamps a signed 8.8 value between two limits.speed = web64_fix8_clamp(speed, min, max);
web64_fix8_add_satweb64_fix8_8 web64_fix8_add_sat(web64_fix8_8 a, web64_fix8_8 b)Adds signed 8.8 values and saturates at the public min/max bounds.speed = web64_fix8_add_sat(speed, delta);
web64_fix8_sub_satweb64_fix8_8 web64_fix8_sub_sat(web64_fix8_8 a, web64_fix8_8 b)Subtracts signed 8.8 values and saturates at the public min/max bounds.speed = web64_fix8_sub_sat(speed, delta);
web64_fixvec2_addvoid web64_fixvec2_add(Web64FixVec2 out, const Web64FixVec2 a, const Web64FixVec2 *b)Adds two 8.8 vector values into an output vector.web64_fixvec2_add(&out, &a, &b);
web64_fixvec2_subvoid web64_fixvec2_sub(Web64FixVec2 out, const Web64FixVec2 a, const Web64FixVec2 *b)Subtracts one 8.8 vector from another into an output vector.web64_fixvec2_sub(&out, &a, &b);
web64_fixvec2_scalevoid web64_fixvec2_scale(Web64FixVec2 out, const Web64FixVec2 value, web64_fix8_8 scale)Scales a 2D 8.8 vector by an 8.8 scalar.web64_fixvec2_scale(&out, &velocity, scale);
web64_motion2d_integratevoid web64_motion2d_integrate(Web64Motion2D *motion)Updates position and velocity using the 8.8 motion helper contract.web64_motion2d_integrate(&motion);

Typedefs:

NameDeclarationDescription
web64_fix8_8typedef int16_t web64_fix8_8;Web64 fixed-point ABI contract v1. 8.8 layout: high byte is integer part, low byte is fraction; signed range -128.0..+127.99609375. 16.16 layout: high word is integer part, low word is fraction; this secondary tier exposes no-runtime constants, conversions, floor/to-int, and wrapping add/sub macros. 16.16 multiply/divide helpers are intentionally absent until executable 6502 implementations and tests exist. Default add/sub helpers wrap; saturation, rounding, and checked/debug behavior use explicit public names. web64_fix8_mul truncates toward zero; web64_fix8_mul_round rounds nearest with half ties away from zero. web64_fix8_div reports compile-time zero divisors and returns 0 for dynamic zero in v1. web64_fix8_lerp uses amount/256; amount 255 approaches b but is not endpoint-exact. web64_angle8 maps 0..255 to one full turn; sin/cos return signed 8.8 from a 256-entry full-wave table. Trig endpoints are exact: sin(64)=0x0100 and sin(192)=0xff00; cosine is sine(angle+64). Negative conversions, floor, ceil, and shift-derived lowering must be emitted from this contract, not host-language shifts. WEB64_FIX8_FROM_INT keeps standard shift semantics; typed 8-bit inputs lower directly to fraction=0/integer=value byte placement. Runtime helper modules are dependency-selected by referenced helper family. Vector helpers accept overlapping out/a/b pointers; invalid pointers are caller error.
web64_ufix8_8typedef uint16_t web64_ufix8_8;Unsigned 8.8 fixed-point storage type.
web64_fix16_16typedef int32_t web64_fix16_16;Signed 16.16 fixed-point storage type.
web64_ufix16_16typedef uint32_t web64_ufix16_16;Unsigned 16.16 fixed-point storage type.
web64_angle8typedef uint8_t web64_angle8;8-bit full-turn angle type where 256 steps equal one rotation.

Structs:

NameDescriptionField summary
Web64FixVec2Two-axis signed 8.8 vector used by the fixed-point helpers.6 fields: web64_fix8_8 x, web64_fix8_8 y, } Web64FixVec2, typedef struct { Web64FixVec2 position, ...

Macros:

NameValueDescription
WEB64_FIX8_ONE0x0100Fixed-point constant or conversion macro.
WEB64_FIX8_HALF0x0080Fixed-point constant or conversion macro.
WEB64_FIX8_MIN0x8000Fixed-point constant or conversion macro.
WEB64_FIX8_MAX0x7fffFixed-point constant or conversion macro.
WEB64_FIX8_FROM_INT(value)((value) << 8)Fixed-point constant or conversion macro.
WEB64_FIX8_TO_INT(value)((value) >> 8)Fixed-point constant or conversion macro.
WEB64_FIX8_FRACTION(value)((value) & 0x00ff)Fixed-point constant or conversion macro.
WEB64_FIX8_FROM_RATIO(numerator, denominator)(((numerator) << 8) / (denominator))Fixed-point constant or conversion macro.
web64_fix8_from_int(value)WEB64_FIX8_FROM_INT(value)Macro constant exported by the header.
web64_fix8_to_int(value)WEB64_FIX8_TO_INT(value)Macro constant exported by the header.
web64_fix8_floor(value)((value) & 0xff00)Typed pointer or expression macro.
web64_fix8_round(value)(((value) + 0x0080) & 0xff00)Typed pointer or expression macro.
web64_fix8_ceil(value)(((value) + 0x00ff) & 0xff00)Typed pointer or expression macro.
web64_fix8_add_wrap(a, b)((web64_fix8_8)((a) + (b)))Typed pointer or expression macro.
web64_fix8_sub_wrap(a, b)((web64_fix8_8)((a) - (b)))Typed pointer or expression macro.
WEB64_FIX16_ONE0x00010000Fixed-point constant or conversion macro.
WEB64_FIX16_HALF0x00008000Fixed-point constant or conversion macro.
WEB64_FIX16_MIN0x80000000Fixed-point constant or conversion macro.
WEB64_FIX16_MAX0x7fffffffFixed-point constant or conversion macro.
WEB64_FIX16_FROM_INT(value)((web64_fix16_16)(value) << 16)Fixed-point constant or conversion macro.
WEB64_FIX16_TO_INT(value)((value) >> 16)Fixed-point constant or conversion macro.
WEB64_FIX16_FRACTION(value)((value) & 0x0000ffff)Fixed-point constant or conversion macro.
WEB64_FIX16_FROM_RATIO(numerator, denominator)(((web64_fix16_16)(numerator) << 16) / (denominator))Fixed-point constant or conversion macro.
web64_fix16_from_int(value)WEB64_FIX16_FROM_INT(value)Macro constant exported by the header.
web64_fix16_to_int(value)WEB64_FIX16_TO_INT(value)Macro constant exported by the header.
web64_fix16_floor(value)((value) & 0xffff0000)Typed pointer or expression macro.
web64_fix16_add_wrap(a, b)((web64_fix16_16)((a) + (b)))Typed pointer or expression macro.
web64_fix16_sub_wrap(a, b)((web64_fix16_16)((a) - (b)))Typed pointer or expression macro.
f8_mul_roundweb64_fix8_mul_roundShort 8.8 helper aliases.
f8_divweb64_fix8_divShort fixed-point helper alias macro.
uf8_mulweb64_ufix8_mulShort fixed-point helper alias macro.
uf8_divweb64_ufix8_divShort fixed-point helper alias macro.
f8_lerpweb64_fix8_lerpShort fixed-point helper alias macro.
f8_absweb64_fix8_absShort fixed-point helper alias macro.
f8_minweb64_fix8_minShort fixed-point helper alias macro.
f8_maxweb64_fix8_maxShort fixed-point helper alias macro.
f8_clampweb64_fix8_clampShort fixed-point helper alias macro.
f8_add_satweb64_fix8_add_satShort fixed-point helper alias macro.
f8_sub_satweb64_fix8_sub_satShort fixed-point helper alias macro.
f8_sinweb64_sin8Short fixed-point helper alias macro.
f8_cosweb64_cos8Short fixed-point helper alias macro.
v2f8_addweb64_fixvec2_addShort fixed-point helper alias macro.
v2f8_subweb64_fixvec2_subShort fixed-point helper alias macro.
v2f8_scaleweb64_fixvec2_scaleShort fixed-point helper alias macro.
m2d_intweb64_motion2d_integrateShort fixed-point helper alias macro.

Header listing:

#ifndef WEB64_FIXED_H
#define WEB64_FIXED_H
#include <stdint.h>

/* Web64 fixed-point ABI contract v1.
   8.8 layout: high byte is integer part, low byte is fraction; signed range -128.0..+127.99609375.
   16.16 layout: high word is integer part, low word is fraction; this secondary tier exposes no-runtime constants, conversions, floor/to-int, and wrapping add/sub macros.
   16.16 multiply/divide helpers are intentionally absent until executable 6502 implementations and tests exist.
   Default add/sub helpers wrap; saturation, rounding, and checked/debug behavior use explicit public names.
   web64_fix8_mul truncates toward zero; web64_fix8_mul_round rounds nearest with half ties away from zero.
   web64_fix8_div reports compile-time zero divisors and returns 0 for dynamic zero in v1.
   web64_fix8_lerp uses amount/256; amount 255 approaches b but is not endpoint-exact.
   web64_angle8 maps 0..255 to one full turn; sin/cos return signed 8.8 from a 256-entry full-wave table.
   Trig endpoints are exact: sin(64)=0x0100 and sin(192)=0xff00; cosine is sine(angle+64).
   Negative conversions, floor, ceil, and shift-derived lowering must be emitted from this contract, not host-language shifts.
   WEB64_FIX8_FROM_INT keeps standard shift semantics; typed 8-bit inputs lower directly to fraction=0/integer=value byte placement.
   Runtime helper modules are dependency-selected by referenced helper family.
   Vector helpers accept overlapping out/a/b pointers; invalid pointers are caller error.
 */
typedef int16_t web64_fix8_8;
typedef uint16_t web64_ufix8_8;
typedef int32_t web64_fix16_16;
typedef uint32_t web64_ufix16_16;
typedef uint8_t web64_angle8;
typedef struct { web64_fix8_8 x; web64_fix8_8 y; } Web64FixVec2;
typedef struct { Web64FixVec2 position; Web64FixVec2 velocity; Web64FixVec2 acceleration; } Web64Motion2D;

#define WEB64_FIX8_ONE 0x0100
#define WEB64_FIX8_HALF 0x0080
#define WEB64_FIX8_MIN 0x8000
#define WEB64_FIX8_MAX 0x7fff
#define WEB64_FIX8_FROM_INT(value) ((value) << 8)
#define WEB64_FIX8_TO_INT(value) ((value) >> 8)
#define WEB64_FIX8_FRACTION(value) ((value) & 0x00ff)
#define WEB64_FIX8_FROM_RATIO(numerator, denominator) (((numerator) << 8) / (denominator))
#define web64_fix8_from_int(value) WEB64_FIX8_FROM_INT(value)
#define web64_fix8_to_int(value) WEB64_FIX8_TO_INT(value)
#define web64_fix8_floor(value) ((value) & 0xff00)
#define web64_fix8_round(value) (((value) + 0x0080) & 0xff00)
#define web64_fix8_ceil(value) (((value) + 0x00ff) & 0xff00)
#define web64_fix8_add_wrap(a, b) ((web64_fix8_8)((a) + (b)))
#define web64_fix8_sub_wrap(a, b) ((web64_fix8_8)((a) - (b)))

#define WEB64_FIX16_ONE 0x00010000
#define WEB64_FIX16_HALF 0x00008000
#define WEB64_FIX16_MIN 0x80000000
#define WEB64_FIX16_MAX 0x7fffffff
#define WEB64_FIX16_FROM_INT(value) ((web64_fix16_16)(value) << 16)
#define WEB64_FIX16_TO_INT(value) ((value) >> 16)
#define WEB64_FIX16_FRACTION(value) ((value) & 0x0000ffff)
#define WEB64_FIX16_FROM_RATIO(numerator, denominator) (((web64_fix16_16)(numerator) << 16) / (denominator))
#define web64_fix16_from_int(value) WEB64_FIX16_FROM_INT(value)
#define web64_fix16_to_int(value) WEB64_FIX16_TO_INT(value)
#define web64_fix16_floor(value) ((value) & 0xffff0000)
#define web64_fix16_add_wrap(a, b) ((web64_fix16_16)((a) + (b)))
#define web64_fix16_sub_wrap(a, b) ((web64_fix16_16)((a) - (b)))

web64_fix8_8 web64_fix8_mul(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_fix8_mul_round(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_fix8_div(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_sin8(web64_angle8 angle);
web64_fix8_8 web64_cos8(web64_angle8 angle);
web64_ufix8_8 web64_ufix8_mul(web64_ufix8_8 a, web64_ufix8_8 b);
web64_ufix8_8 web64_ufix8_div(web64_ufix8_8 a, web64_ufix8_8 b);
web64_fix8_8 web64_fix8_lerp(web64_fix8_8 a, web64_fix8_8 b, uint8_t amount);
web64_fix8_8 web64_fix8_abs(web64_fix8_8 value);
web64_fix8_8 web64_fix8_min(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_fix8_max(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_fix8_clamp(web64_fix8_8 value, web64_fix8_8 min_value, web64_fix8_8 max_value);
web64_fix8_8 web64_fix8_add_sat(web64_fix8_8 a, web64_fix8_8 b);
web64_fix8_8 web64_fix8_sub_sat(web64_fix8_8 a, web64_fix8_8 b);
void web64_fixvec2_add(Web64FixVec2 *out, const Web64FixVec2 *a, const Web64FixVec2 *b);
void web64_fixvec2_sub(Web64FixVec2 *out, const Web64FixVec2 *a, const Web64FixVec2 *b);
void web64_fixvec2_scale(Web64FixVec2 *out, const Web64FixVec2 *value, web64_fix8_8 scale);
void web64_motion2d_integrate(Web64Motion2D *motion);

/* Short 8.8 helper aliases. */
#define f8_mul_round web64_fix8_mul_round
#define f8_div web64_fix8_div
#define uf8_mul web64_ufix8_mul
#define uf8_div web64_ufix8_div
#define f8_lerp web64_fix8_lerp
#define f8_abs web64_fix8_abs
#define f8_min web64_fix8_min
#define f8_max web64_fix8_max
#define f8_clamp web64_fix8_clamp
#define f8_add_sat web64_fix8_add_sat
#define f8_sub_sat web64_fix8_sub_sat
#define f8_sin web64_sin8
#define f8_cos web64_cos8
#define v2f8_add web64_fixvec2_add
#define v2f8_sub web64_fixvec2_sub
#define v2f8_scale web64_fixvec2_scale
#define m2d_int web64_motion2d_integrate
#endif