Sunday, October 18, 2026

Commodore Programmer's Keyboard References

C128 scancodes



Composite C64 and C128 keyboard references

Composite plus/4 and C16 keyboard references

Vic-20 keyboard references

The programs are

  • 64keymaps.prg
  • 128keymaps.prg
  • +4keymaps.prg
  • 16keymaps.prg
  • 20keymaps.prg
These and more are available at the following:

Link: https://github.com/davervw/c-keymaps

C64 keyboard remapper, these keymap displays, and related utilities

Friday, October 9, 2026

Commodore BASIC .TXT listing out and in


This image shows a quick-reference for how to LIST out to a file, and have BASIC type in a listing from a file.  This is not original work except for fixing the port to plus/4 and similar.

Links:

(plus/4,16,116 version is a careful and thoughtful port of the sx64.net version, meaning AI Gemini tried really hard, but kept getting confused by C64 knowledge.  AI got the 2035 and 810 addresses right, but I had to research the values to poke.  Informing AI of the correction, it kept trying to supplement the answer getting it more wrong, so I put an end to that!)

Sunday, August 23, 2026

Extending C128 BASIC using REM statement parameters

 



So on the C64 you could have commands like SYS 49152,X,Y,"TEXT" where your machine/assembly code could specifically parse the commas and numbers.  The result was a way to interface between BASIC and Assembly to use the best of both worlds.   BASIC is easy to edit, debug, and change.  6502 is fast and can do some low level operations including accessing all 64K RAM, and all the ROMs.

BUT!!!   On the C128, the SYS command was extended to allow ease of passing registers.  This is fine if you want to transfer data in 0..255 chunks.  But coordinates on the screen are 320x200, so that goes past a byte, and addresses are 0..65535, they definitely go past a byte.  And strings are another animal.

On the C128 the statement SYS 4864,1,2,3 will call the routine with .A, .X, .Y registers populated with 1, 2, and 3 respectively.  That's fine and dandy, but if you want to do something more, you have to do it another way.

Here comes the new syntax:

SYS 4864 : REM 300, 65535, "Hello C128"

By using the token getter, you can check for colon, REM token, then proceed to parse values and variables as before on C64.  (With the exception that I couldn't get expressions like 2+3 to work, maybe something to do with REM.  But we can work around that.)

Check out the github repository for program listings including commented assembly for more details, and to grab a copy of the D64 containing the PRG.

Saturday, August 15, 2026

Touch points and buttons on M5Core 2" displays, Tab 5" display, and Sunton 7" display for keyboard emulation


I have targeted the following M5 Stack models with my C64/C128/Vic-20/Apple 1 emulator:

(Even though I have targeted other boards, I had only implemented touch on the CoreS3)

The primary reason for targeting these boards was the common 2" 320x240 display perfect for most C64 emulation, and the availability of a wristband that works with Core2 and CoreS3 (it works with the Fire if and only if you never need to charge the battery - not aware of a universe where that works out long term).

[aside... Originally I had supported the M5 Core Basic, but without PSRAM, it was difficult to support the different computer models that currently load into that memory.  So M5 Core BASIC was dropped after its initial development.]

The Basic and Fire have three UI hardware buttons.   The Core2 has three virtual touchscreen buttons (touchscreen expands farther down from the LCD screen to allow for capacitive touch button points, and the M5 library abstracts them similar to physical buttons, so your code doesn't even have to know the difference).  The CoreS3 has no UI buttons, but I've manually implemented virtual touch screen buttons at the bottom of the screen.   From left to right the buttons are known to M5 as A, B, and C.

So button support for Basic, Fire, and Core2 was straightforward.

  • press Button A: Cursor UP
  • press Button B: RETURN
  • press Button C: Cursor Down
With hold functionality as well.
  • hold Button A: toggle computer model (C64, C128, Vic-20, Apple 1, repeats)
  • hold Button B: LOAD"*",8 / RUN for Commodore, snapshot system for Apple 1
  • hold Button C: STOP
Thus, one can demonstrate the emulator loading a menu of programs, scrolling though the listing, and choosing one.  And toggle between the emulators.   The Apple 1 snapshot system allows choosing a snapshot and loading or saving it.

I support other hardware targets, and I have BLE pairing functionality.  So I am thinking of expanding support of the virtual buttons, including more virtual buttons, and providing 8-position joystick inputs (and button) too.  But for now, here is the documentation for the existing buttons.

And then just like that, the CoreS3, Tab5, and Sunton 7" now have more touch points implemented for their capacitive touch screens to allow for more virtual keys.




Monday, June 29, 2026

BLE HID coprocessor for microcontrollers

 

Teensy in green, ESP32-C3 in blue

I have a Teensy 4.1 operating as a Commodore 64 (and Vic-20, and 128, and Apple 1) emulator.  It already supports USB Host (via 5 pin header on top) and web page helper (via USB CDC).

The Teensy doesn't have wireless capability, but I wanted to add BLE keyboard support.  So enter the ESP32-C3 as a coprocessor.  It is running a custom firmware using the NimBLE library to enumerate BLE HID devices in pairing mode, and connects as soon as it finds one. If everything works successfully, it sends HID reports as ASCII over the UART channel (received at Teensy RX pin 0).  

While the Teensy is busy driving the LCD with a bunch of connections, the ESP32-C3 is only wired at 5V input, ground, and a TX pin.  The ESP firmware is built without USB CDC support so that the Serial line defaults to GPIO.  

Shown is a USB only ESP32-C3 board with the advantage of being slightly cheaper.  When I purchased it years ago when ESP32-C3 was relatively new, it was about US$2 on AliExpress.  Looking today, there's even more choices available in all sorts of price ranges and sizes.

So the Teensy is doing what it is good at, and the ESP32-C3 is filling in a wireless connection gap.  The red jumper is provided to be able to pull power.  Though the power connection does have its advantage that the ESP32-C3 has a USB-C port, while the Teensy has a USB-Micro connector.

Look Ma -- no wires!

Mouse, Trackpad, and Gamepad/Joystick are supported as well.  Gamepads and Joysticks will require HID maps which are loaded but not interpreted yet, nor passed on the interface (work to be done).  Joystick support is not implemented yet in my emulators, but stay tuned!

Update (2026-07-03): coprocessor firmware updated to support my custom BLE CBM keyboard sources, and optionally convert standard HID reports to Commodore key scan codes.  By focusing on Commodore scan codes, the integration with the emulators is now simpler, and seamlessly supports more of my keyboards -- while also as being an option, the coprocessor can be used by those that expect standard HID bytes. (Note: no conversion from Commodore to keyboard HID, only the other way around.)

Added Tab5 Keyboard support for my portable emulators for Commodore

 

Tab5 Keyboard is a convenience add-on

I added native keyboard support to my emulators already running on M5Stack's Tab5.

There were already 64/Vic-20/128 original keyboards, CardKB, web page adapter, Palm Portable Keyboard, and custom BLE support.  

Now there is also attached keyboard accessory support.  The Tab5 is a 5" ESP32-P4 handheld tablet with high resolution 1280x720 LCD.  The keyboard plugs into the bottom of the tablet, extending the size, and the capabilities.

The implementation scans all 70 keys for presses and translates to a list of C128 key scan codes into ASCII comma separated and newline terminated form, which the emulators already know how to translate into Commodore model specific keyboard scan codes.  As these are pressed scan codes, the press is persisted in the emulated system until the physical key is released.  These are symbolic mappings, not positional mappings because that is my preference.  Want different?  This is open source!

All visibly labeled keys are supported mostly as is.  Keys not Commodore specific are mapped to a Commodore PETSCII character already mapped to the proper ASCII character for the minimal environment (left arrow, underscore, caret, curly braces, pipe, backslash, backquote, tilde).  In addition, shift [Aa] supports letters, and numbers and punctuation to do the normal shifted characters.  Both [sym] and shift [Aa] do the symbols.   Additional keys worthy of documentation are:

  • _=             RIGHT SHIFT
  • tab            COMMODORE C=
  • sym tab        TAB
  • esc            STOP
  • shift esc      LOAD RUN
  • sym esc        ESC
  • ctrl sym del   STOP RESTORE
  • shift del      INSERT
  • \              £
  • sym shift \    SHIFT £
  • shift -        LEFT ARROW
  • sym shift -    SHIFT -
  • shift +        =
  • sym shift +    SHIFT =
  • sym shift *    SHIFT *
  • sym up         HOME
  • sym shift up   CLEAR
  • sym 1          F1
  • ...
  • sym 8          F8

As a reminder the emulators included are:

  • Commodore 64
  • Commodore 128
  • Commodore Vic-20
  • Environment similar to an Apple 1 (minimalistic 6502/6850/ROM/RAM plus terminal)

Links:

https://github.com/davervw/c-simple-emu6502-cbm/tree/unified-pio

Sunday, June 7, 2026

Extended Screen for C128




Finally, Commodore 128 can provide the 80 column screen that multiple monitor folks need - extended screen.  Spread those columns across two separate monitors for a wider view.

Instructions

  1. Download disk image, and use as is with modern tools, or image to floppy.
  2. Click the 80 column keyboard button into position to make it the default.
  3. Attach two monitors to your C128.  Composite on the left, digital RGB on the right.
  4. Start up (or reset) C128 with disk attached.  Boot sector will load and run 80DUAL by default.
  5. Enjoy screen extended 80 columns!

It works by reinitializing the VDC 8563/8568 registers to display 40 columns offset by 40 columns, and each line thereafter also offset by 40 columns.  Since the KERNAL hasn't been told any differently, it will continue to treat the VDC as an 80 column display, but the VDC settings are now to display only the right hand 40 columns.  An IRQ routine is installed to copy 5 lines from VDC RAM to VIC-II screen RAM (hardwired to address 1024 currently) and color RAM.  The effect is that as text is typed or displayed on the 80-column virtual and physical display, the hidden left-hand side of the screen will also be displayed on the composite monitor.

This is a proof of concept, and has limitations.  

  • The machine language routines use $1300-$15ff for code and data
  • The code uses self-modification techniques so can't be moved to ROM as is
  • Character set changes are not handled
  • Changing to composite screen is not handled, will continue to be overwritten from VDC RAM
  • No graphics support
  • Slow, less than 12 frames per second operation
  • Not compatible with SNAKE
  • Will interfere with programs that write text to VDC screen using own (not ROM) routines.  It has a fixed list of ROM addresses to avoid interrupting, and doesn't include RAM.
Why?
  • It was a challenge I set myself
  • Because it's ridiculous and outrageous, has little practical purpose.  I like the bizarre possibilities.
  • Related to my rgb64