Skip to content
Eliott65wiki
Contents

API reference

On this page

File generated by tools/gen_api.py from api/definition.py: do not edit by hand.

How a call works

The 6502 prepares a parameter block in its own memory (never in page zero), writes the address of the block into the gate $FFF8 (low byte) then $FFF9 (high byte, which triggers the call), then waits for the kernel to reset $FFF9 to 0. The results and the error code are then in the block.

Block byteContents
+0service number
+1function number
+2error code (written by the kernel; 0 = success)
+3…parameters (little-endian), and results
        .include "lib/e65.inc"

        lda #<bloc
        ldx #>bloc
        jsr e65_porte          ; or the macro #E65_APPEL bloc
        lda bloc+E65_ERREUR    ; 0 = success

bloc:   .byte E65_SVC_ECRAN, E65_ECRAN_TEXTE, 0
        .word $0400            ; text page
        .byte $1F              ; white on blue

Rules: only $FFF8–$FFFF are reserved (gate and vectors); the call is synchronous; FICHIERS EXECUTER does not return on success.

During the call

The 6502 is not frozen: it loops on $FFF9, and its clock keeps running. Its IRQ and NMI interrupts are therefore still serviced during a long call (file, USB stick). Measured cost of a complete call (SYSTEME PING, program LATENCE.E65): ≈ 5 µs, i.e. 36 cycles at 7.26 MHz, of which around 30 are the 6502’s own instructions. Unmeasured worst case: up to a few milliseconds if the call coincides with USB polling.

Interrupts

No system call in an interrupt handler. Between the write to $FFF8 and the write to $FFF9, an interrupt making its own call would overwrite the low byte of the call in progress. If a handler must nevertheless call the kernel, the main program wraps its calls in PHP / SEI … PLP.

Multitasking and pre-emption

Ctrl+Tab gives the screen and keyboard to the next process, whatever program is in the foreground (the key is not passed on).

Up to 8 processes can run together, each with its own 64 KiB (ADR-0015, ADR-0018: only its non-zero pages occupy memory while it waits). A program can yield (e65_ceder); otherwise the kernel pre-empts it every 10 ms through an NMI (ADR-0016), without asking it anything. During those few microseconds, it borrows the 16 bytes $FFE8–$FFF7 and the NMI vector, then gives them back; on resumption, the 8 bytes below the stack are overwritten, as with any interrupt. A program that drives the NMI itself is not compatible.

Numbering, versions and discovery

  • API version: 1 (E65_VERSION_API). It changes when a number, a parameter or a format changes in an incompatible way; an addition (new function, new service) does not change it.
  • Service number ranges: 0–15 kernel, 16–127 device drivers, 128–255 extensions. Functions are numbered within their service.
  • Discovery: SYSTEME INFO returns the kernel version, the API version and the mask of services present. A service that is present may reply ERR_NON_PRET (device absent).
  • Bytes reserved by the system in the 6502’s memory: 8.

Error codes

CodeNameMeaning
0OKsuccess
1ERR_SERVICEunknown service
2ERR_FONCTIONunknown function
3ERR_PARAMETREinvalid parameter (address out of range, forbidden value…)
4ERR_NON_PRETdevice absent or not ready yet
5ERR_PERIPHERIQUEinput/output error
6ERR_FINno more entries to list
7ERR_ABSENTfile not found
8ERR_FORMATfile or file system not recognised
9ERR_PLEINmedium full
10ERR_OCCUPEno free process or memory, or no other process

Services

0 · SYSTEME

Basic and diagnostic services.

SYSTEME PING — service 0, function 0

Does nothing; always returns OK. Used to check that the kernel is responding.

No parameters.

SYSTEME TRACE — service 0, function 1

Diagnostics: makes 8 bytes visible from the PC (tools/sonde.py).

ByteSizeParameterDirectionDescription
+38octets→8 bytes copied into the kernel state (readable over SWD)

SYSTEME BATTEMENT — service 0, function 2

Sign of life: increments a counter in the kernel state.

No parameters.

SYSTEME INFO — service 0, function 3

Discovery: a program can check the version and the available services before using them.

ByteSizeParameterDirectionDescription
+33version←kernel version: major, minor, patch
+61api←API version (call numbering)
+72services←mask of services present (bit n = service n)
+92reserves←bytes reserved by the system in 6502 memory (8)

SYSTEME TEMPS — service 0, function 4

Clock: duration measurements by the 6502. NON_PRET error if the platform provides no clock.

ByteSizeParameterDirectionDescription
+34microsecondes←time since start-up (hardware timer, µs)
+74cycles←6502 cycles since start-up (sampled every 1 ms)

SYSTEME HIBERNER — service 0, function 5

Writes the complete state of the machine (512-byte header: screen, keyboard; then the 64 KiB of 6502 memory) to a file. Use the e65_hiberner routine from libe65, which also saves the Y, P and S registers (not visible on the bus). Resumption: FICHIERS EXECUTER on the .HIB file (for example by typing its name in the shell); the routine then returns to its caller with A = $FF.

ByteSizeParameterDirectionDescription
+32nom→address of the hibernation file name (8.3, for example ETAT.HIB)
+52reprise→address where the 6502 will restart on resumption

SYSTEME LANCER — service 0, function 6

Loads a program (or resumes a .HIB hibernation file) into a free memory space (a full 64 KiB, separate from the caller’s) without running it straight away: it will start, through its RESET vector, the first time the caller yields. The caller keeps the screen and keyboard. ERR_OCCUPE if all 8 processes are taken or if the page pool is not sufficient (ADR-0018).

ByteSizeParameterDirectionDescription
+32nom→address of the name of a .E65 program
+51espace←number of the memory space allocated to the new process

SYSTEME CEDER — service 0, function 7

Hands over to the next process, without waiting for pre-emption (≈ 10 ms). Use the e65_ceder routine from libe65, which saves Y, P and S; it returns with A = $FF when the process gets control back, with A = $00 straight away if there is no other process. The process’s memory is intact (nothing is copied: the 6502 simply changes memory space).

ByteSizeParameterDirectionDescription
+32reprise→address where this process will restart when it gets control back

SYSTEME PROCESSUS — service 0, function 8

Multitasking state.

ByteSizeParameterDirectionDescription
+31actif←space of the calling process
+41premier_plan←space that has the screen and keyboard
+51occupes←mask of occupied spaces (bit n = space n)
+61espaces←number of memory spaces in the machine
+74commutations←number of switches since start-up

SYSTEME PREMIER_PLAN — service 0, function 9

Gives the screen and keyboard to a process: the screen immediately shows its text page, and keystrokes go into its queue. The other processes keep running and writing to their own page, without displaying anything.

ByteSizeParameterDirectionDescription
+31espace→space that receives the screen and keyboard

SYSTEME TERMINER — service 0, function 10

Terminates the calling process and frees its space; does not return. If it had the foreground, the foreground passes to the next process. ERR_OCCUPE if it is the only process. The libe65 routine e65_quitter chains TERMINER then, if it is the last one, the execution of SHELL.E65.

No parameters.

SYSTEME DORMIR — service 0, function 13

Like CEDER, but the process is no longer chosen until it wakes up: a key for it (it is in the foreground) or the end of the delay. A key wakes it immediately, without waiting for the end of the time slice (ADR-0019). Returns straight away (A = $00) if no other process is awake or if a key is already waiting for it. Use the e65_dormir routine (A, X = delay).

ByteSizeParameterDirectionDescription
+32reprise→address where this process will restart when it wakes up
+52delai→delay in ms before waking up (0: only a key)

SYSTEME NOM — service 0, function 11

Name of the program running in a space (that of the file launched, executed or resumed). ERR_PARAMETRE if the space is free.

ByteSizeParameterDirectionDescription
+31espace→space of a process
+42adresse→where to write the name (13 bytes: 8.3 name terminated by 0)

SYSTEME TUER — service 0, function 12

Terminates another process and frees its space; if it had the foreground, the foreground returns to the caller. To terminate oneself: TERMINER.

ByteSizeParameterDirectionDescription
+31espace→space of another process

1 · ECRAN

640 × 480 screen (logical 320 × 240). The text and attribute pages stay in the 6502’s memory and are read directly by the video driver on every frame (“zero copy”): writing to them is all it takes.

ECRAN MIRE — service 1, function 0

Displays the diagnostic test pattern (colour bars and ramps).

No parameters.

ECRAN TEXTE — service 1, function 1

40 × 30 text screen, a single text and background colour. PARAMETRE error if the page goes beyond $FFF7.

ByteSizeParameterDirectionDescription
+32page→address of the text page (40 × 30 = 1,200 bytes, ASCII)
+51couleurs→background « 4

ECRAN TEXTE_COULEUR — service 1, function 2

40 × 30 text screen with a text and background colour per character.

ByteSizeParameterDirectionDescription
+32page→address of the text page (1,200 bytes)
+52attributs→address of the attribute page (1,200 bytes, background « 4

ECRAN GRAPHIQUE — service 1, function 3

Displays the graphics (GRAPHIQUE service, ADR-0025): 320 × 240, two layers and 128 sprites. Takes the graphics in the same way as the GRAPHIQUE service (OCCUPE if they belong to another process, NON_PRET if the machine has none). Returning to text: TEXTE or TEXTE_COULEUR (the graphics stay with the process).

No parameters.

ECRAN HERCULES — service 1, function 4

Hercules mode (E10-S8): 720 × 350 at 1 bit per pixel, monochrome, centred on the screen (720 × 480). The image is read directly from the program’s memory, without copying: the program draws with plain writes. Line y is at image + 90 × y; bit 7 of each byte = leftmost pixel; bit set = ink.

ByteSizeParameterDirectionDescription
+32image→address of the image: 350 lines of 90 bytes (31,500 bytes, at most $84EC)
+51encre→0 white, 1 amber, 2 green

ECRAN HERCULES_TEXTE — service 1, function 5

80 × 25 text of the Hercules mode, in 9 × 14 pixel cells, read without copying from the program’s memory (like TEXTE). Attribute of a character: bit 0 inverse, bit 1 underline, bit 2 blink. Characters $00 to $7F (bit 7 ignored; $00 to $1F: blank). 9 × 14 font drawn for Eliott65.

ByteSizeParameterDirectionDescription
+32page→address of the characters: 25 rows of 80 (2,000 bytes)
+52attributs→address of the attributes (2,000 bytes), or 0: none
+71encre→0 white, 1 amber, 2 green

2 · CLAVIER

USB keyboard (in-house host driver). Codes: ASCII, 13 Enter, 8 backspace, 9 tab, 27 Esc, $7F Delete, $81 up, $82 down, $83 left, $84 right, Ctrl-A to Ctrl-Z = 1 to 26.

CLAVIER ZONE — service 2, function 0

Declares a keyboard queue in the 6502’s memory: [0] head (written by the kernel), [1] tail (written by the 6502), [2..17] 16 characters. The 6502 then reads its keyboard without any call: a key is waiting when tail ≠ head; after reading, tail = (tail + 1) & 15. The queue is emptied by the call.

ByteSizeParameterDirectionDescription
+32zone→address of an 18-byte queue in 6502 memory (0: internal queue)

CLAVIER LIRE — service 2, function 1

Classic read, for programs that have not declared a zone.

ByteSizeParameterDirectionDescription
+31caractere←next character from the internal queue, 0 if none

CLAVIER DISPOSITION — service 2, function 2

Selects the keyboard layout.

ByteSizeParameterDirectionDescription
+31disposition→0: US (QWERTY, default), 1: FR (AZERTY)

3 · STOCKAGE

USB stick seen as a sequence of 512-byte blocks. Blocks are read and written directly at the chosen address in the 6502’s memory.

STOCKAGE INFO — service 3, function 0

Capacity of the stick. NON_PRET error as long as it is not ready.

ByteSizeParameterDirectionDescription
+34blocs←number of blocks
+72taille←size of a block (512)

STOCKAGE LIRE — service 3, function 1

Reads a block.

ByteSizeParameterDirectionDescription
+34bloc→block number
+72adresse→destination (512 bytes) in 6502 memory

STOCKAGE ECRIRE — service 3, function 2

Writes a block. Caution: raw write, without a file system.

ByteSizeParameterDirectionDescription
+34bloc→block number
+72adresse→source (512 bytes) in 6502 memory

4 · FICHIERS

File system of the stick or floppy disk: FAT12, FAT16 or FAT32 (read and write; type detected automatically). Names are ASCII strings terminated by 0; paths with “/”, case-insensitive, 8.3 short name or long name (64 characters at most).

FICHIERS LISTER — service 4, function 0

One entry of the root directory, as a short name. FIN error after the last one.

ByteSizeParameterDirectionDescription
+32index→position of the entry in the root (starting from 0)
+52adresse→where to write 18 bytes: short name (13, terminated by 0), attributes (1), size (4)

FICHIERS LIRE — service 4, function 1

Loads a file (or its beginning) directly into 6502 memory.

ByteSizeParameterDirectionDescription
+32nom→address of the file name
+52destination→load address in 6502 memory
+72maximum↔maximum number of bytes; on return: number of bytes read

FICHIERS EXECUTER — service 4, function 2

Loads and runs a .E65 program. On success, the call does not return: the 6502 is suspended, the program is loaded in its place, then the 6502 restarts on it (the screen goes back to the test pattern, the keyboard queue is discarded). On error (FORMAT, ABSENT…), the calling program continues.

ByteSizeParameterDirectionDescription
+32nom→address of the name of a .E65 program

FICHIERS LISTER_LONG — service 4, function 3

One entry of the root directory, with its long name.

ByteSizeParameterDirectionDescription
+32index→position of the entry in the root
+52adresse→where to write 70 bytes: attributes (1), size (4), long name (65, terminated by 0)

FICHIERS ECRIRE — service 4, function 4

Creates the file, or replaces its contents if it exists (short or long name). Careful write order: data, FAT table, directory entry, then release of the old contents. Errors: PARAMETRE (name not 8.3 for a creation, or a directory), PLEIN, ABSENT (parent directory).

ByteSizeParameterDirectionDescription
+32nom→address of the name (path; final name 8.3 for a creation)
+52source→address of the data in 6502 memory
+72longueur→number of bytes (0: empty file)

FICHIERS SUPPRIMER — service 4, function 5

Deletes the file and its long-name entries, and frees its clusters.

ByteSizeParameterDirectionDescription
+32nom→address of the file name (not a directory)

5 · GRAPHIQUE

320 × 240 graphics (ADR-0025): 32 KiB of video memory, 256-colour palette (RGB 4:4:4, 0x0RGB), two layers (tiles or bitmap, 1 to 8 bits per pixel) and 128 sprites. Only one process holds them at a time: its first call takes them if they are free (default palette, layers off, sprites hidden, video memory at 0), otherwise OCCUPE. They are released when that process terminates, is killed or executes another program; hibernation does not save them. Maps, bitmaps and sprite images can also be in the program’s memory, read on every frame without copying (PLAN sources, bit 6 of a sprite’s attributes, TABLE_LUTINS): writing to them is all it takes. Formats: see ADR-0025.

GRAPHIQUE ECRIRE — service 5, function 0

Copy from 6502 memory to video memory.

ByteSizeParameterDirectionDescription
+32video→address in video memory ($0000 to $7FFF)
+52source→address in 6502 memory
+72longueur→number of bytes

GRAPHIQUE LIRE — service 5, function 1

Copy from video memory to 6502 memory.

ByteSizeParameterDirectionDescription
+32video→address in video memory
+52destination→address in 6502 memory (ending at $FFF7 at most)
+72longueur→number of bytes

GRAPHIQUE CHARGER — service 5, function 2

Loads a file from the stick directly into video memory, without going through the 6502’s memory.

ByteSizeParameterDirectionDescription
+32nom→address of the file name
+52video→address in video memory
+72decalage→starting position in the file
+92maximum↔maximum number of bytes; on return: number of bytes read

GRAPHIQUE PALETTE — service 5, function 3

Changes palette colours. Colour 0 is the background colour.

ByteSizeParameterDirectionDescription
+31premiere→first colour changed (0 to 255)
+41nombre→number of colours (0 = 256)
+52source→address of the colours: 2 bytes each, 0x0RGB, little-endian

GRAPHIQUE PLAN — service 5, function 4

Configures a layer. Map entry: bits 0–9 tile, bit 10 horizontal flip, bit 11 vertical flip, bits 12–15 palette bank.

ByteSizeParameterDirectionDescription
+31plan→0 (back) or 1 (front)
+41mode→0 off, 1 tiles, 2 bitmap
+51bpp→bits per pixel: 1, 2, 4 or 8
+61tuiles16→0: 8 × 8 tiles; 1: 16 × 16
+71log2_largeur→map 2^n tiles wide (5, 6 or 7)
+81log2_hauteur→map 2^n tiles high (5, 6 or 7)
+91banque→bitmap mode below 8 bpp: colour = bank × 16 + value
+101sources→bit 0: map in 6502 memory; bit 1: tiles or bitmap in 6502 memory
+112carte→address of the map (16-bit entries)
+132donnees→address of the tiles, or of the bitmap
+152defil_x→horizontal scroll
+172defil_y→vertical scroll

GRAPHIQUE DEFILER — service 5, function 5

Changes only the scroll of a layer.

ByteSizeParameterDirectionDescription
+31plan→0 or 1
+42x→horizontal scroll
+62y→vertical scroll

GRAPHIQUE LUTIN — service 5, function 6

Configures a sprite. Bit 7 of the shape and of the attributes is reserved (PARAMETRE).

ByteSizeParameterDirectionDescription
+31numero→sprite 0 to 127 (the lowest is drawn in front)
+42x→X position (signed)
+62y→Y position (signed)
+82adresse→address of the image
+101forme→bits 0–1 width (8 « n), 2–3 height, bit 4: 8 bpp (otherwise 4), bit 5 H flip, bit 6 V flip
+111attributs→bits 0–3 bank, 4–5 depth (0 hidden, 1 behind the layers, 2 between them, 3 in front), bit 6: image in 6502 memory

GRAPHIQUE TABLE_LUTINS — service 5, function 7

“Shadow” table: re-read at the start of each frame, it replaces the sprites. In 6502 memory, the program moves its sprites with simple writes, without calling the kernel.

ByteSizeParameterDirectionDescription
+31ou→0 none, 1 6502 memory, 2 video memory
+42adresse→address of the table: 128 sprites of 8 bytes (X, Y, address, shape, attributes)

GRAPHIQUE TRAME — service 5, function 8

To synchronise with the display: wait for the number to change, then modify the image (less tearing).

ByteSizeParameterDirectionDescription
+34image←number of the frame displayed (video counter)

GRAPHIQUE REMPLIR — service 5, function 9

Fills an area of video memory.

ByteSizeParameterDirectionDescription
+32video→address in video memory
+52longueur→number of bytes
+71valeur→fill byte

GRAPHIQUE LIGNES — service 5, function 10

Table read on every line (effects in the manner of the SNES’s HDMA, without copying): the line’s scroll replaces the layer’s (waves, parallax); the line’s bank replaces the bank of a bitmap layer, or is added (modulo 16) to that of each cell of a tile layer. A 16-colour image can thus show up to 256 colours (16 per line). No effect at 8 bits per pixel. The program modifies the table whenever it likes.

ByteSizeParameterDirectionDescription
+31plan→0 or 1
+41table→0: scroll (240 × 4 bytes: X, Y); 1: bank (240 bytes)
+51ou→0 none, 1 6502 memory, 2 video memory
+62adresse→address of the table

GRAPHIQUE MEMOIRE — service 5, function 11

Extends video memory to 64 KiB by borrowing 8 free frames from the process pool (zeroed; addresses $8000 to $FFFF), or reduces it back to 32 KiB by returning them. OCCUPE if there are not 8 free frames. While they are borrowed, they are unavailable to waiting processes (LANCER or a switch may be refused). They are also returned when the graphics are released. At 32 KiB, an address from $8000 to $FFFF wraps round to $0000 to $7FFF.

ByteSizeParameterDirectionDescription
+31kio↔32 or 64; on return: the size of video memory in KiB

6 · SON

The board’s speaker (magnetic transducer on GPIO20, square wave by PWM; loudest around 2.7 kHz, its resonance). Nothing blocks: the note or melody plays while the program carries on. Only one at a time: a new call replaces the previous one, whatever the process. The sound stops when its process ends, is killed or executes another program. NON_PRET on a platform without a speaker. Frequencies: 0 (silence) or 20 to 20,000 Hz.

SON NOTE — service 6, function 0

Plays a note and returns immediately.

ByteSizeParameterDirectionDescription
+32frequence→in Hz; 0: silence
+52duree→in milliseconds; 0: until the next call
+71volume→1 to 255 (duty cycle volume / 512); 0: silence

SON ETAT — service 6, function 1

To wait for a sound to end, or to follow a melody.

ByteSizeParameterDirectionDescription
+32reste←milliseconds remaining; $FFFF: endless; 0: silence
+52note←melody: address of the current note; 0 otherwise

SON MELODIE — service 6, function 2

Plays a sequence of notes in the background. The notes are read one by one in the program’s memory, without copying: it can change the sequence while it plays (generated music, tempo). A note with an invalid frequency stops the melody.

ByteSizeParameterDirectionDescription
+32adresse→first note: 4 bytes each, frequency (2, 0: rest) then duration in ms (2); duration 0: end
+51volume→1 to 255; 0: silence
+61boucle→0: once; 1: starts again from the beginning after the end

Updated on October 15, 2026.