Type the shared BASIC loader and RUN it. A digit changes as the game updates. Hold Space to slow it with excessive CPU work, then release it to recover.
Reuse a service contract
This is the same executable as the BBC Micro example. It calls MOS instead of reaching directly into the BBC’s VIA or the Electron’s ULA. Shared services make that reuse possible; the common CPU alone would not.
Call wait_frame once before input/update/draw. The wrapper leaves A=19 and does not preserve X/Y/flags. Keep the MOS IRQ service and interrupts enabled. The wait accepts the next display sync; it supplies no missed-frame count and does not replay updates.
; BBC Model B MOS service. Keep the MOS IRQ path and interrupts enabled.
; OSBYTE &13 waits for the next display sync. A becomes &13; X/Y/flags change.
; ROM entry point, not a replacement IRQ handler. Reuses the system's clock.
OSBYTE = $fff4
wait_frame:
lda #19
jmp OSBYTEStart the complete example
run the following command:
make -C acorn-electron/patterns/assembly/framework/game-loop. That builds the shared sources in bbc-micro/patterns/assembly/framework/game-loop; type its build/loader.bas on the Electron and RUN it.
The loader selects MODE 6 and reserves memory above HIMEM=&3000. It installs our own executable at &3000 using DATA statements. This is a typed program route, not a snapshot of an already-running machine. Reset to leave.
; BBC Model B, MOS 1.20/BASIC II. Enter generated loader.bas, RUN.
; Space holds slow CPU work. MOS services own IRQ/video/keyboard. Reset to leave.
*=$3000
OSWRCH=$ffee
start:
cli
lda #0
sta updates
sta updates+1
sta slow
main_loop:
jsr wait_frame
jsr read_input
jsr update_game
jsr draw_screen
jsr expensive_work
frame_done:
jmp main_loop
read_input:
lda #129
ldx #$9d ; INKEY(-99): Space
ldy #$ff
jsr OSBYTE
stx slow ; $ff held, 0 released
rts
update_game:
inc updates
bne update_done
inc updates+1
update_done:
rts
draw_screen:
lda #31 ; VDU 31: fixed text position, then a changing digit
jsr OSWRCH
lda #10
jsr OSWRCH
lda #8
jsr OSWRCH
lda updates
lsr
lsr
lsr
and #7
clc
adc #48
jmp OSWRCH
expensive_work:
lda slow
beq work_done
ldy #64
work_outer:
ldx #0
work_inner:
dex
bne work_inner
dey
bne work_outer
work_done:
rts
updates: !word 0
slow: !byte 0
!source "frame.inc"What happens when work runs late
The MOS interface is shared, but the amount of work that fits is not assumed to match the BBC. The same deliberate workload produced fewer updates on the tested Electron. That is a result for this caller and configuration, not a ranking of the machines or an isolated CPU benchmark.
The source comparison waits for installation to finish, with a bounded timeout. It does not assume both machines’ BASIC loaders complete after the same short delay. A new graphics mode, peripheral or direct hardware routine needs its own evidence.
Check this combination
Code status: assembled and emulator-executed. Acorn Electron, pinned OS/BASIC. The recorded checks identify sources, firmware and observer. In three 30-frame windows the caller made 30 normal, 5 deliberately slowed and 30 recovered updates. An unpaced negative control is rejected by the same rate guard. This is configuration-specific emulator evidence, not an original-hardware or whole-emulator claim.