Give an accepted action a sound. The same caller changes its picture and triggers this effect; a second version performs the action with the trigger removed. Listen to both.
Working effect
Trigger omitted
Take the effect
The reusable effect
PSG equ $7f
; Pulse on SN76489 tone0, eight serviced frames. Other channels are muted here.
trigger_sound:
push af
ld a,$80
out (PSG),a
ld a,$10
out (PSG),a
ld a,$90
out (PSG),a
ld a,8
ld (SOUND_TICKS),a
pop af
ret
service_sound:
ld a,(SOUND_TICKS)
or a
ret z
dec a
ld (SOUND_TICKS),a
ret nz
ld a,$9f
out (PSG),a
retSN76489-compatible tone 0 at $7F, duration $C005. Trigger preserves AF/B; service changes AF. No stereo-panning interface is provided here.
Include sound.inc once with the caller’s constants and duration byte. Initialise the duration byte to zero before the first service call. Call trigger_sound for an accepted action, then call service_sound exactly once per accepted display update. The eighth service call mutes the effect. Because the supplied caller services in the triggering iteration too, this is a count of service calls, not eight complete elapsed frame intervals. Triggering again restarts the duration; there is no queue.
The complete initialiser also mutes other channels. To reuse just this effect beside music, agree channel ownership and remove unrelated global setup only after providing a replacement. Device latches, power, routing and master volume may affect more than one voice.
Change it and recognise a mistake
Change the tone divisor or attenuation. A stereo effect needs a separate routing contract as well as a tone.
The omitted-trigger control still accepts the action but fails the same audio guard as the working caller. Keyboard clicks or other machine output are not enough: the BASIC checks compare against a separate rejected-command recording.
Deliberately omitted sound trigger
; Original capability caller: owns VDP, one audio channel and declared RAM.
VDP_DATA equ $be
VDP_CTRL equ $bf
TURNS equ $c000
SOUND_TICKS equ $c005
org 0
jp start
defs $66-$,0
retn
defs $100-$,0
start:
di
ld sp,$c3f0
xor a
ld ($c000),a
ld ($c001),a
ld ($c002),a
ld ($c003),a
call init_picture
main:
call wait_frame
ld hl,($c002)
inc hl
ld ($c002),hl
include "../sample.inc"
ld a,($c001)
cpl
and b
jr z,no_action
ld a,($c000)
inc a
ld ($c000),a
nop
nop
nop
no_action:
ld a,b
ld ($c001),a
call draw_picture
call service_sound
jp main
wait_frame:
in a,($bf)
wait_new:
in a,($bf)
and $80
jr z,wait_new
ret
include "../picture.inc"
include "../sound.inc"
defs $7ff0-$,0
db "TMR SEGA"
db 0,0,0,0,0,0,0,$4cThe working implementation above repairs that omission. If an effect instead drones on, check the mute/service path and that its state is initialised. Servicing twice makes a counted effect shorter; servicing only after input can leave it running while the player waits. Those are lifecycle decisions to test when adapting it.
Run the caller
Build the complete caller with make -C sega-game-gear/patterns/assembly/input/read-action. Press button 1 once, keep it held, then release and press again. The piece moves on each new press and returns to its starting position after two; holding does not repeat the action. Load the cartridge produced by the Makefile in the named configuration; retain its reset/header setup.

Where setup, trigger and service belong
; Original capability caller: owns VDP, one audio channel and declared RAM.
VDP_DATA equ $be
VDP_CTRL equ $bf
TURNS equ $c000
SOUND_TICKS equ $c005
org 0
jp start
defs $66-$,0
retn
defs $100-$,0
start:
di
ld sp,$c3f0
xor a
ld ($c000),a
ld ($c001),a
ld ($c002),a
ld ($c003),a
call init_picture
main:
call wait_frame
ld hl,($c002)
inc hl
ld ($c002),hl
include "sample.inc"
ld a,($c001)
cpl
and b
jr z,no_action
ld a,($c000)
inc a
ld ($c000),a
call trigger_sound
no_action:
ld a,b
ld ($c001),a
call draw_picture
call service_sound
jp main
wait_frame:
in a,($bf)
wait_new:
in a,($bf)
and $80
jr z,wait_new
ret
include "picture.inc"
include "sound.inc"
defs $7ff0-$,0
db "TMR SEGA"
db 0,0,0,0,0,0,0,$4cCompare blocking, serviced and queued sound when choosing the next step.
Verification and sources
Target: NTSC stock Game Gear cartridge configuration. 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.
Sega, Game Gear hardware/software reference: controller ports, stereo routing and PSG; TI SN76489A latch/data format.