Skip to content
Eliott65wiki
Contents

Eliott65 for complete beginners

Never touched a microcontroller? It doesn’t matter. In ten minutes, with one photo and a few diagrams, here is what Eliott65 is and why it is a little unusual.

On this page

1. The machine: an 8-bit computer of today

The Neo6502kbd is a small computer sold by Olimex, with its keyboard built into the case. At its heart is a real 6502, the processor of the Apple II, Commodore 64, Oric and BBC Micro: a new chip, made today by WDC under the name W65C02S.

Here is the board, out of its case, on our bench:

Olimex Neo6502kbd Rev.A board powered on, seen from above, with a USB stick, an HDMI cable and three probe wires on the SWD1 header; numbers mark the parts described in the caption
  1. W65C02S (U6) — the real 6502 processor. It runs the programs but has no memory of its own.
  2. 3 × 74LVC245 (U7 to U9) — three switches: they take turns carrying the low address, the high address and the data over the same 8 wires.
  3. RP2040 (U3) — the dual-core ARM microcontroller. It plays the 6502’s memory and runs all of Eliott65: kernel, video, USB, files.
  4. P25Q16 flash (U1) — 2 MB where the Eliott65 firmware sleeps while the board is off.
  5. FE1.1s USB hub (U5) — spreads the RP2040’s single USB port over the four sockets.
  6. USB-A sockets — keyboard, USB stick, mouse. The case keyboard is an ordinary USB keyboard.
  7. HDMI output — the picture, produced bit by bit by the RP2040, with no video chip.
  8. USB-C: power and PGM — power, and the PGM socket for talking to the PC (it then holds the hub in reset).
  9. SWD1 header — the debug port: three wires to a probe that reads and writes the RP2040’s memory while it runs.
  10. Speaker (SPK1) — a magnetic transducer: Eliott65 plays notes and melodies on it (SON service).
  11. UEXT header — I2C, SPI and serial expansions (not used by Eliott65).

Photo of our bench: the board powered on, USB stick plugged in, debug probe on SWD1.

What is surprising when you look closely: there is no memory chip next to the 6502. No ROM, no RAM. The 6502 is connected only to three small switching chips (marker 2), and behind them, to an RP2040 (marker 3), the microcontroller of the Raspberry Pi Pico.

2. The board’s trick: an RP2040 that plays the memory

A processor spends its time saying “give me the byte at this address” or “store this byte at this address”. On a conventional computer, a memory chip answers. Here, it is the RP2040: it listens to every request from the 6502 and answers itself, several million times per second. The 64 KiB that the 6502 believes it has are in fact a piece of the RP2040’s memory.

Who does what on the Neo6502kbdThe 6502 is only wired to three 74LVC245 switches, themselves wired to the RP2040. Inside the RP2040: the bus served by PIO and DMA, the 6502's 64 KiB memory, core 0 running the kernel and core 1 producing the picture. Around it: the flash, the USB hub and the HDMI screen.W65C02Sthe processorno memory of its ownbus3 × 74LVC245switches8 shared wiresRP20402 ARM cores, 264 KiB of memoryPIO + DMA: the busserves every 6502 cycle6502 memory: 64 KiBa slice of the RP2040's RAMCore 0: the kernelsystem calls, files, USBCore 1: videoencodes the picture line by line2 MB flashthe firmwareUSB hubkeyboard, key,mouseScreenHDMI
Who does what. The 6502 talks only to the RP2040; the RP2040 does everything else: the memory, the picture, USB, the files. The Eliott65 firmware runs entirely in the RP2040.

3. The idea behind Eliott65: leave all the memory to the 6502

On a 1980s microcomputer, the system takes up a good part of the memory: BASIC ROM, screen area, system variables. What is left for your programs is often much less than the 64 KiB the 6502 can address.

Since the RP2040 is right there, alongside, with its two cores and 264 KiB of memory, Eliott65 puts the whole system there: the kernel, the drivers, file management. In the 6502’s memory, it keeps only 8 bytes.

Memory as the 6502 sees it under Eliott65Out of 65,536 bytes, 65,528 are free for programs, from $0000 to $FFF7. Only 8 bytes are taken: the call gate at $FFF8–$FFF9 and the vectors at $FFFA–$FFFF.65,528 bytes for your programs$0000$FFF78 bytes: call gate ($FFF8–9) + vectors ($FFFA–F)$FFF8–$FFFFThe kernel, drivers, screen and files live elsewhere: inside the RP2040.(The 8 bytes are enlarged to be visible: to scale they would be 0.1 pixel wide.)
Memory as the 6502 sees it: 65,528 bytes out of 65,536 are yours.

These 8 bytes are:

  • 2 “gate” bytes (at $FFF8 and $FFF9): this is how programs ask the system for a service;
  • 6 vector bytes (from $FFFA to $FFFF): the 6502 requires them; they tell it where to start and where to go when an interrupt occurs.

4. Asking for a service: the call gate

When a program wants to display text, read a file or find out the time, it makes a system call. With Eliott65, it works like a counter window: you fill in a form, slide it through the slot, and wait for the answer.

A system call, step by stepThe program puts its parameters in a block of its own memory, writes the block address at $FFF8–$FFF9 and waits by reading $FFF9 again. The kernel, on core 0, reads the block, does the work, writes the results and sets $FFF9 back to zero. The program resumes. About 5 microseconds for a simple call.6502 programKernel (RP2040 core 0)① prepares a parameter block② writes the block address at $FFF8–$FFF9③ waits, reading $FFF9 againLDA $FFF9 / BNEreads the block, does the work,writes the results into the block④ sets $FFF9 back to 0⑤ resumes with its results≈ 5 µs for a simple call, about 36 6502 cycles
The program writes the address of its “form” into the gate, then waits. The kernel, which runs on one core of the RP2040, does the work and hands control back. The whole thing takes about 5 millionths of a second.

The form (the parameter block) is stored wherever the program wants, in its own memory. Nothing is reserved in advance for it. That is what makes it possible to keep only 8 bytes.

5. What you see on the screen

At start-up, Eliott65 runs a small test program that checks the memory and displays the state of the system, then it looks for a shell on the USB stick: a command line where you type the name of a program to launch it.

Eliott65 start-up screen in coloured text on a blue background: rainbow ELIOTT65 title, checksum $7F80, memory errors $0000, 16-colour palette
The start-up screen: the memory test passes (0 errors), the 16 colours of text mode are displayed. The 6502 writes these characters directly into its memory; the RP2040 reads them there to build the picture.

Eliott65 can also do graphics: scrolling tile backgrounds and sprites (those little characters that move over the background).

Graphics screen: a scrolling chequerboard of coloured tiles, with eight coloured diamonds bouncing over it
GRAPHE.E65: a tile background scrolling diagonally and 8 diamond-shaped sprites bouncing around. The program only changes a few bytes in its memory; the RP2040 draws.

6. Several programs at once

Eliott65 can run up to 8 programs at the same time. Only one has the screen and the keyboard (you switch with Ctrl+Tab); the others carry on in the background.

But the 6502 has only one 64 KiB memory. The trick: when switching from one program to another, the RP2040 puts away the useful pages of the first in its own reserve and puts back those of the second in their place. Since most programs use only a small part of their 64 KiB, it fits.

Several programs in the same memoryThe 6502 always sees a single 64 KiB window, cut into 16 pages of 4 KiB. At each program switch, the active program's non-zero pages go out to a pool of 31 frames of 4 KiB, and the next program's pages come in. A page that is entirely zero takes no frame.The 6502's window64 KiB = 16 pages of 4 KiB010000000000000Fout: its non-zero pagesin: those of the next oneRP2040 pool31 frames of 4 KiBAAABBBBCCCtableactive program (A)program B, waitingprogram C, waitingfree frameA page left at zero takes no frame: a typical program only fills 3 of them.
The 6502 always sees the same memory. When switching programs, only the pages that contain something make the round trip to the RP2040’s reserve.

And what if a program never hands back control? The kernel interrupts it anyway, thanks to a hardware interrupt of the 6502 (the NMI): this is pre-emptive multitasking.

7. Switching off without losing anything: hibernation

Since all of the 6502’s memory is in the RP2040, the system can save it to a file on the stick, along with the state of the screen and keyboard. Later, you “launch” this file like a program, and the machine resumes exactly where it left off, down to the byte.

8. In short

QuestionShort answer
What is it?A firmware, a kernel and a small operating system for the Neo6502kbd.
What is different?The system lives in the RP2040; the 6502 keeps 65,528 bytes out of 65,536.
Does it really work?Yes: everything described here has been measured and validated on the board.
What does it replace?The board’s original firmware. The two are not compatible: programs must be written for Eliott65.
What next?See Where the project stands.

To go further, each idea on this page has its own article: the bus, system calls, video, multitasking, hibernation. And the technical terms are explained in the glossary.

Sources in the repository : README.md, docs/journal/00-synthese.md, docs/etude/ETUDE-Eliott65-Neo6502kbd.md.