Skip to content
Eliott65wiki
Contents

The machine: the Neo6502kbd

A real 6502, but no memory chip around it: everything the 6502 sees, the RP2040 shows it. What we know about the board, learned from the schematics and then checked on the bench.

On this page

The components

The Neo6502kbd (revision A) is the “built-in keyboard” version of Olimex’s Neo6502. Its main parts, according to the bill of materials and the KiCad schematic published by Olimex:

ComponentRole
W65C02S (TQFP44)the 6502 processor, WDC’s modern CMOS version
RP2040the microcontroller with two ARM Cortex-M0+ cores that does everything else
P25Q16 (2 MB)the RP2040’s flash memory, where the firmware lives
3 × 74LVC245bus buffers: the switches between the 6502 and the RP2040
FE1.1sa 4-port USB hub
CH217Kthe power switch for the USB ports, with current limiting
HDMI socketthe video output, driven directly by the RP2040
Speaker (transducer), UEXT connectorsound, and I2C, SPI and serial extensions

The keyboard in the case is an ordinary USB keyboard, plugged into one of the hub’s ports. The board has no dedicated keyboard controller.

A 6502 with no memory

On most 6502 computers, the processor is surrounded by ROM and RAM. Not here. The 6502 is connected to three 74LVC245s, and these three buffers are connected to the same eight pins of the RP2040 (GPIO 0 to 7). The RP2040 opens one buffer at a time:

  1. the first lets through the low address (A0 to A7);
  2. the second, the high address (A8 to A15);
  3. the third, the data (D0 to D7), in one direction or the other.

The first two work in one direction only (from the 6502 to the RP2040). For the third, the 6502 chooses the direction, through its R/W# pin: the RP2040 must therefore send data only when the 6502 is reading.

The RP2040 also generates the 6502’s clock (PHI2, on GPIO 21) and holds its RESET, IRQ and NMI pins. It therefore has full control of the processor: it can start it, interrupt it, and even freeze it by not answering a cycle.

What is not connected

Four pins of the 6502 (SYNC, RDY, BE, SOB) do not go to the RP2040. The most regrettable is SYNC, which signals an instruction fetch: without it, the RP2040 cannot tell an instruction from data read from memory.

The IRQ, RESET and NMI pins are shared with the SPI of the UEXT connector, through 0 Ω resistors on the Neo6502kbd. All 30 pins of the RP2040 are in use: bus, buffer selection, R/W#, HDMI, sound, clock, UEXT.

The 6502 at 3.3 volts

The board’s 6502 is a W65C02S6TQG-14. The “14” means 14 MHz guaranteed at 5 V. But the board has only one logic rail, at 3.3 V, and at that voltage WDC guarantees only 8 MHz. The datasheet states that the core is static: it has no minimum frequency and tolerates its clock being stopped for as long as you like. Eliott65 makes constant use of this.

Our measurement bench showed that this chip holds at least 10.5 MHz at 3.3 V, beyond the guarantee. That figure applies to our unit; see The bus.

USB: a hub, and a socket that changes everything

The RP2040’s single USB port goes to the FE1.1s hub, which spreads it over the four USB-A sockets. The RP2040 is then the host: it is the one that polls the keyboard and the stick.

The same link also goes to the PGM socket. When a cable is plugged in there, the PC’s voltage holds the hub in reset, and the RP2040 becomes a device of the PC. Practical consequence: with a cable on PGM, no keyboard.

The hub is connected at Full Speed; the keyboard is a Low Speed device. To talk to it through the hub, each exchange must be preceded by a special packet, the PRE. Eliott65’s driver handles it.

The HDMI output

There is no video chip: the four differential pairs of the HDMI socket (three colours and the clock) are connected directly to pins 12 to 19 of the RP2040, through 270 Ω resistors. It is up to the software to produce the signal, bit by bit. See Video.

The socket’s other pins (DDC, CEC, HPD) only go to test pads: the RP2040 cannot read the screen’s EDID, the list of modes it accepts.

The speaker

A small magnetic transducer (QMB-09B-03), driven by GPIO20 through a transistor. It must be fed a square wave; it is loudest around 2.7 kHz. See Sound.

The flash and the probe

The flash is a 2 MB Puya P25Q16. A detail that mattered: the OpenOCD 0.12.0 shipped by distributions does not recognise it; only the development version can program it. The SWD1 connector gives access to the RP2040’s debug port; flashing and almost all our tools go through it. See The bench tools.

The firmware present on the board before Eliott65 was backed up in full (2 MB, with its SHA-256 hash) before any experiment: it can be restored through the probe.

Sources in the repository : docs/journal/00-synthese.md, docs/journal/01-materiel.md, docs/journal/08-video.md, docs/journal/09-usb.md, docs/etude/ETUDE-Eliott65-Neo6502kbd.md.