Skip to content

Read keyboard controls on Acorn Electron

Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.

Build acorn-electron/patterns/assembly/input/mos-controls, type the generated build/loader.bas in the recorded BASIC, then RUN. Move with Q/A/O/P; Space restarts. Holding a direction keeps moving; holding Space must allow movement after the first restart.

Acorn Electron native caller after accepted input.
Captured from the running caller in the configuration below.

Take the reader

Copy the input routine with its two tables and private key_index byte. Define OSBYTE=$FFF4 and provide one byte called controls. The caller shows read_controls followed by detect_edges; previous, pressed and released each need their own byte. Initialise previous before the first read.

The reusable reader

input.inc
; MOS OSBYTE 129: negative INKEY scans. No key-buffer consumption.
; Returns controls bits U/D/L/R/action=1/2/4/8/16; changes A/X/Y/flags.
read_controls:
    lda #0
    sta controls
    ldx #0
key_next:
    stx key_index
    lda #129
    ldy #$ff
    lda key_numbers,x
    tax
    lda #129
    jsr OSBYTE
    txa
    ldx key_index
    cmp #0
    beq key_up
    lda controls
    ora key_masks,x
    sta controls
key_up:
    inx
    cpx #5
    bne key_next
    rts
key_numbers: !byte $ef,$be,$c9,$c8,$9d ; Q/A/O/P/Space (-17/-66/-55/-56/-99)
key_masks: !byte 1,2,4,8,16
key_index: !byte 0

read_controls scans Q/A/O/P/Space through MOS OSBYTE 129. It returns controls bits 1/2/4/8/16 for up/down/left/right/action, without consuming the character buffer. A/X/Y/flags change; key_index is private scratch.

Call from main with MOS IRQ services active. The routine samples five keys without draining the character buffer. Its private scratch makes it non-reentrant; an interrupt must not call it halfway through another scan.

Change it and recognise a mistake

Change the key-number/mask tables together. Read once, then derive pressed/released before replacing previous.

If a held Space keeps restarting the player, the action path is testing controls instead of pressed, or clearing previous during reset. The working caller is checked while Space stays held and a direction is pressed: movement must still occur. Keep held directions and restart edges separate.

The complete caller

Working setup and integration

demo.asm
; Acorn Electron OS/BASIC. Typed loader, then CALL &3000.
; Q/A/O/P move, Space restarts. MOS owns IRQ and SOUND queue; reset to leave.
*=$3000
OSWRCH=$ffee
OSWORD=$fff1
start:
    cli
    jsr reset_game
main_loop:
    jsr wait_frame
    jsr read_controls
    jsr detect_edges
    jsr update_player
    jsr draw_screen
    inc updates
frame_done:
    jmp main_loop
updates: !byte 0
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/state.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/rules.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/collision.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/input.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/draw.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/collect-and-respond/sound.inc"
!source "../../../../../bbc-micro/patterns/assembly/framework/game-loop/frame.inc"

For more responsive controls, compare polling, buffering and press edges in input choices.

Verification and sources

Target: Electron MOS/BASIC, MODE 6. These callers were executed with released Emu198x 0.44.1; assembly uses Asm198x 0.0.71. The sample folder contains reproduction instructions and retained observations. The independent checker binds source, native captures and actual output; its rejection tests exercise wrong state, missing files and false audio claims.

This qualifies the named emulator/firmware path. Pitch accuracy, original hardware and other peripherals require their own observations. The muted MOS run is an explicit diagnostic RAM patch to RTS at trigger_sound, restored after the check.

Acorn, BBC Microcomputer Advanced User Guide / Electron technical documentation: OSBYTE &81 negative INKEY and OSWORD &07 SOUND block; MOS IRQ ownership.