This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/tools/re-capture/trigger_watch.sh
Sylpheed RE agent 28a4b1ead1 re: ISL opcodes decoded; the branch base is PER PHASE and isl.py was wrong
All 25 opcodes now have meanings. Ops 2/4/6/8 are integer compound assignment
(+= -= *= /=) and 3/5/7/9 the float versions; 10 and 11 are integer and float
compare writing three condition bits; 13-18 are je/jne/jl/jle/jg/jge; 21-24 are
push.i/push.f/pop.i/pop.f over deques at phase+44 and phase+64.

The shared-handler question is answered: the dispatcher leaves the opcode in r4
and the shared thunks never overwrite it, so those helpers take an extra opcode
argument and index a secondary table (0x82271448, 0x8227152C).

CORRECTION to my own tool and note: the branch/jump base is [phase+232], which
the phase initialiser sets to 0x24 + the phase's entry from the mission-level
stream -- 0xE4 / 0x14AA8 / 0x24B4C for Stage 02's three phases, not the file's
0x24. Measured on phase 1: base 0xE4 puts 525 of 525 branch targets on an
instruction boundary; base 0x24 manages 188. isl.py had been using 0x24 for
every phase, so its jump targets were wrong throughout. Fixed via
isl.phase_bases().

That also settles two things mission-script-ssb.md left open: offsets ARE
code-base-relative, and 0x1883's operand IS a code pointer -- the earlier worry
that some 'land on IEEE floats' was an artefact of adding the wrong base.
2026-08-25 18:52:09 +00:00

52 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Find what WRITES the trigger-queue count, by watching the word rather than
# hunting the instruction statically.
#
# The static hunt failed (isl-builtins.md): the only writes to `+20` in the
# container's code are block initialisations, yet the count demonstrably moves
# 0 -> 1 -> 2 during a mission. A watchpoint names the writer directly.
#
# The address translation is the fiddly part, so it is explicit:
# guest VA -> file offset via gmem.va_to_off
# file offset -> HOST address via the /dev/shm/xenia_memory_* mapping in
# /proc/<pid>/maps: host = map_start - map_off + off
# gdb debugs the HOST process, so a guest VA cannot be watched directly.
set -u
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
export PYTHONPATH=/sylph-home/.local/lib/python3.12/site-packages
export XENIA_BIN=/sylph-home/re/bin/gdb-wrap/xenia_canary
SD="$(cd "$(dirname "$0")" && pwd)"; export SD
CMD=/tmp/gdb-cmd; OUT=/tmp/gdb-out.log
WATCH_S="${1:-240}"
sleepfor(){ python3 -c "import time,sys; time.sleep(float(sys.argv[1]))" "$1"; }
"$SD/launch_mission.sh" fly || { echo "BOOT FAILED"; exit 1; }
CFG=/tmp/nav-tw.json
for t in 1 2 3; do
python3 "$SD/pad.py" set "rt=1" >/dev/null 2>&1; sleepfor 3
python3 "$SD/pad.py" clear >/dev/null 2>&1
if python3 "$SD/entities2.py" self 0x130 "$CFG" >/dev/null 2>&1; then
SYLPH_HUNT=1 SYLPH_KEEPOUT=1400 nohup python3 "$SD/pilot.py" "$CFG" 900 \
</dev/null >/tmp/tw-pilot.log 2>&1 & echo "--- pilot flying"; break
fi
done
HOSTADDR=$(python3 "$SD/host_addr.py" 2>/tmp/tw-addr.err)
echo "--- translation: $(cat /tmp/tw-addr.err)"
echo "--- host addr: $HOSTADDR"
case "$HOSTADDR" in 0x*) ;; *) echo "could not translate"; exit 2;; esac
pid=$(pgrep -x gdb | head -1); before=$(wc -c < "$OUT")
kill -INT "$pid"; sleepfor 3
{ echo 'echo === WATCH SET ===\n'
echo "watch *(unsigned int*)$HOSTADDR"
echo "continue"; } >> "$CMD"
echo "--- watching ${WATCH_S}s"
sleepfor "$WATCH_S"
kill -INT "$pid"; sleepfor 3
{ echo 'echo === WHO WROTE IT ===\n'; echo 'bt 8'; echo 'x/3i $pc'
echo 'echo === END ===\n'; echo 'delete'; echo 'continue'; } >> "$CMD"
sleepfor 10
tail -c +$((before + 1)) "$OUT" | grep -vE '^\s*$' | tail -60
echo "TRIGGER WATCH DONE"