Building a Human68k driver for USB keyboards via PS/2
Keeping an X68000 usable often depends on ordinary peripherals as much as on the board itself. The original keyboard and its controller belong to a specific generation of Sharp hardware, while a modern generic USB keyboard speaks a different protocol. For Australian collectors, replacement parts are usually easier to obtain than original Japanese-market spares: swap meets, second-hand shops and Australian online sellers routinely offer USB keyboards and inexpensive adapters. Sydney and Melbourne have particularly broad access to mainstream computer retailers such as Jaycar, although no adapter listing should be trusted without checking its protocol.
A USB-to-PS/2 lead is easy to misunderstand. A passive lead merely gives a keyboard’s built-in PS/2 circuitry access to an adapter’s clock and data wiring; most current USB-only keyboards have no such circuitry, so the lead may do nothing. An active converter reads USB reports and generates PS/2 clocked data, but still needs a real PS/2 host controller on the X68000 side. The small round connector is not that controller, and the X68000’s proprietary keyboard socket is not automatically a PC-compatible port.
The useful project is therefore a Human68k driver for a generic USB keyboard through a PS/2 adapter, paired with an interface whose electrical and register documentation is known. The software must translate scan codes and modifier state into something applications can use while leaving the original BIOS path intact if the new hardware is absent. The X68000 community reference pages are a good place to locate model-specific information and people who have already examined particular boards.
| Connection path | Required hardware | Driver-level work | Main limitation |
|---|---|---|---|
| Original X68000 keyboard | Original keyboard and cable | Existing BIOS handling | Requires original hardware |
| Passive USB-to-PS/2 lead | Keyboard with native PS/2 emulation | Scan-code conversion | Most USB-only keyboards will not work |
| Active USB-to-PS/2 converter | A genuine PS/2 controller on the X68000 side | Scan codes, acknowledgements and layout mapping | Adapter support varies |
| USB host-controller expansion | Compatible USB host hardware and software | USB descriptors, reports and HID mapping | A larger hardware and software project |
Establish the hardware path
Begin with the hardware boundary. An expansion board can make the project practical if it provides a genuine PS/2 host controller and documents how its registers are mapped into the X68000 address space. A cable, socket or protocol converter is not a substitute for that controller. If the PS/2 interface is provided by a different add-on, check its voltage, clock ownership and interrupt connection before writing any code.
Also separate the two adapter families. Passive USB-to-PS/2 leads work only with keyboards whose firmware already exposes a PS/2 interface. Active converters contain a USB host and a PS/2 device, but their translation tables may omit media keys, Fn combinations or unusual modifiers. Treat a promising advertisement as a starting point for testing, not proof that every key will arrive.
Power deserves the same attention. Do not assume an X68000 or expansion-board port can supply enough current for a converter, separately powered hub or illuminated keyboard. Use a documented, regulated supply where one is required; in Australia, an external mains unit should be suitable for 230 V at 50 Hz and carry the appropriate Australian compliance markings. Imported controller boards can also attract GST and courier or Australia Post handling charges, so include those in a hobby budget rather than comparing only the advertised sale price.
Identify the controller and key codes
On the X68000, hardware access is through memory-mapped registers. Do not copy an x86 controller routine that reads ports 0x60 and 0x64: on a PC those are I/O ports, while an X68000 interface may place equivalent registers at completely different addresses. The controller data register, status register and command register must be identified from the schematic or board documentation, along with any address decoder that translates CPU space. Human68k BIOS behaviour can also vary by model, so record the machine and BIOS revision with every register observation.
The PS/2 exchange itself is more consistent. The host supplies the clock and reads a frame containing a start bit, eight data bits, odd parity and a stop bit; common clock rates fall around 10–16 kHz. A keyboard normally acknowledges a transmitted byte with 0xFA. A read loop must check the output-full status, consume the data register, and leave the controller ready for the next byte. Timeouts are important because a disconnected adapter can otherwise leave a program waiting forever.
Raw codes are not application keys. PS/2 devices commonly transmit scan set 2, while a conventional controller may translate that into set 1 codes for the host. The set 1 make code for A, for example, is 0x1B, while extended keys can carry an 0xE0 prefix and releases can use 0xF0. Those values are unrelated to X68000 or Human68k key conventions until a deliberate translation exists. Build a map from PS/2 make and break codes to X68000-facing values, then handle Shift, Control, Alt, Caps Lock and the Japanese kana state as explicit fields. Most PC keyboards sold for Australian use have a US-style layout, but labels and modifier order still vary by model.
Write the driver in layers
Separate the protocol work from the operating-system interface. The low layer should initialise the controller, read bytes, acknowledge frames and maintain decoder state. The upper layer should convert decoded events into stable X68000 key codes, apply the chosen layout and deliver events to an application or replacement console input routine. Register access belongs in the platform-specific part of the driver, with symbolic definitions for the board’s actual memory addresses.
The following fragment illustrates the access pattern rather than providing drop-in source. The macros must resolve to the real controller addresses, and a production timeout should use the platform timer as well as a bounded spin count.
/* Board-specific memory-mapped register addresses. */
static int ps2_read_byte(unsigned char *value)
{
unsigned long guard = KBD_READ_LIMIT;
while (guard-- != 0) {
if ((*(volatile unsigned char *)KBD_STATUS
& KBD_OUTPUT_FULL) == 0)
continue;
*value = *(volatile unsigned char *)KBD_DATA;
return 1;
}
return 0;
}
Initialisation should be boring and reversible. Drain stale bytes, identify the keyboard if the controller supports that command, establish defaults, then enable scanning. Polling can follow a simple contract: return zero when no event is ready, otherwise fill one event and return one. Use Human68k’s documented waiting facility between polls rather than consuming the processor in a tight loop. If several events arrive between calls, place them in a small ring buffer and define an overflow policy instead of silently losing keystrokes.
Treat memory-mapped controller registers as volatile and keep reads and writes in the required order; a compiler is free to reorder ordinary memory accesses. Protect a read-modify-write of a shared command register with the system’s critical-section mechanism. Avoid calling a trap #15 console routine from inside a hardware interrupt, since it may not be reentrant. It is also worth keeping the normal BIOS keyboard path available as a fallback, so a failed probe can return the user to a usable screen rather than an unresponsive machine.
Add interrupt handling carefully
Interrupts improve responsiveness, but they add ownership problems. A conventional controller uses status and command registers such as read/write command byte, disable and enable keyboard interface, and interface test. These are controller operations, not Human68k system calls. An interrupt-driven driver must clear the source correctly, handle an unexpected 0xFA acknowledgement, and avoid overwriting a command byte belonging to another subsystem. A controller reset may be useful during initialisation, yet it should be followed by the device’s self-test and scan-enable sequence rather than assumed to succeed.
On the 68000 side, the handler must preserve the interrupted register set and stack before using its own working registers, and it must return with the correct exception frame. The exact vector and interrupt mask depend on the X68000 hardware and how the Human68k BIOS owns that source. Install a vector only after establishing which component currently services the keyboard interrupt; two readers of the same register can corrupt each other even when each appears correct. Where the BIOS provides no supported sharing mechanism, document the conflict clearly and keep the polling driver as a recovery path.
Plan for imperfect devices. An adapter can forward normal typing while dropping media keys, Num Lock, Pause or a modifier chord, and its repeat behaviour may differ from the original keyboard. Parity errors, overruns and a stuck clock need bounded recovery: discard the bad byte, resynchronise at a frame boundary, and return to a known state after a limited number of retries. Sustained recovery attempts are worse than one clean error report, because they can make the rest of the machine appear to hang.
Test the result and publish the work
Testing must cover more than typing an English sentence. Record every physical key, including shifted symbols, function keys, arrows, Backspace, Enter, Tab, the numeric keypad and the modifier combinations needed by Human68k applications. Test a cold boot with the new driver, then a reboot with it already resident. Compare the resulting events with the original keyboard where possible, and deliberately test key release, rapid typing, held modifiers and an unplugged adapter. A printed key-map listing is invaluable when a software build maps a physical key to the wrong character.
Publish the implementation with enough detail to reproduce it: controller address map, IRQ arrangement, adapter make and USB identifiers, supported scan codes, known omissions, build instructions and photographs of the wiring. Keep a revision history, because a later BIOS release or controller change can invalidate an otherwise sound driver. Readers looking for further background can consult Zack Michaels’s site, while direct discussion remains more useful than an undocumented binary.
The final test is a clean handoff to another owner. Load the tested executable from a documented startup script, include a source archive, and explain how to restore the original keyboard or fall back to BIOS input. Share the key map, wiring diagram and known limitations with the wider hobby community, including participants in an Australian X68000 group or a Canberra preservation meetup. Release the working driver and its documentation so another collector can reproduce the result without repeating every expensive or time-consuming hardware mistake.
Nereid-X Expansion Board
A personally-produced LAN+USB+Memory expansion board for Sharp X68000 series computers. Multiple production runs were offered, including a final batch and a later revival reproduction run.
Power Supply Repair
X68 power supply repair and modification services were offered by the site owner, with documentation shared through diary entries spanning 2001–2006.
Server & Networking
Notes on FreeBSD administration, ISP changes, server migration, and networking topics. The site itself ran on FreeBSD with the hns diary system and Namazu search integration.
Get in touch
X68K.NET connects Sharp X68000 enthusiasts through community links and shared projects. Reach out with questions about the Nereid project or X68 resources.