Files
prosolis 5921fab118 Put the transport on the 68000, and find PIO costs 87 clocks a byte
ROADMAP P4b. src/player/xfer.i answers src/player/ring.i's XF_* mailbox with a
real READ(10) to a real MB89352 in place of tools/bench/stream.lua's modelled
transport: 120 records, 4,488,588 B, pixel-exact out of a 256 KB ring, with a
real mid-stream seek in a second pass. The tiling is the SAME 18 wraps and
14.7 KB mean hole that 49.4's host producer and 55.4's modelled transport
produced -- a third transport, same placement, which is the assertion that
ring.i could not tell which side of the seam answered it.

What it costs is the finding. tools/bench/xfer_cost.sh subtracts the same 120
frames run twice and gets 87.28 clocks per delivered byte, against the 68000's
own cycle table for the loop, which says 87.15 -- 0.2% apart, so the cost is the
instruction stream and not MAME's device model, and it is the first number this
rig has produced that survives leaving the emulator. That is 391.8% of a 12 fps
frame; the machine's own V-DISP clock agrees from the other end at 2.57 fps.
Against the ladder, W=5 held is 22.4% of a frame and W=19 is 85.3%, so P4a is
worth 4.6x the worst DMA configuration in this tree and 17.5x the best -- where
before this session it was worth 9 against 19. W itself did not move by a clock.

"UNDERRUNS: 0/120" is vacuous with a synchronous transport, and stream.lua now
prints that argument next to the zero: a frame cannot start before its record
has landed because the decoder IS the transport. The counter that means
something is NO IDLE, 119/120 with a worst overrun of 441 whole ticks. Same
class of error as 49.7.2's free-running ring passing at 48 KB.

58.3: a record is not a sector -- 117 of 120 start part way into one, and
reading whole sectors into the ring corrupts the neighbours rather than wasting
bytes (49.2, no bounds check). scsi.i reads the covering sectors and stores only
the window, which is free in PIO and stops being free the moment P4a succeeds.
tools/analysis/26_sector_align.py prices the three ways out and sector-aligned
records win on both axes: +0.43% wire and zero clocks, against +1.34% and a
bounce copy at +5 clk/B. ROADMAP now carries a four-item re-encode bundle and
P4a should be attempted against a sector-aligned container.

check.sh gains two stages and was ALL GREEN before and after. decode.bin is
unchanged at 1,296 B and the same MD5.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
2026-08-24 23:15:53 -07:00

80 lines
4.2 KiB
Bash
Executable File

#!/bin/bash
# One MB89352 transport run: the 68000 selects a SCSI target and reads the disc
# itself (ROADMAP P4, first half).
#
# tools/bench/scsi_run.sh [container.dlx]
#
# THE APPARATUS, AND ITS TWO SUBSTITUTIONS, BOTH DELIBERATE AND BOTH LABELLED.
#
# 1. THE BOARD. `x68000 -exp1 cz6bs1`, which is what FINDINGS 42.5 says to
# benchmark and never `x68ksupr` -- the Super/XVI internal SCSI is PIO-only in
# MAME (`// TODO: duplicate DMA glue from CZ-6BS1`), so it would measure a
# fallback the real machine does not have.
#
# 2. THE BOOT ROM. MAME refuses to instantiate the card without an 8 KB
# `scsiexrom.bin` (CRC 7be488de), which is not in this tree and is not on this
# machine. This script writes a ZERO-FILLED placeholder into its own rompath,
# so the user's romset is untouched, and MAME prints WRONG CHECKSUMS as it
# should. That is honest HERE and would not be everywhere: the player drives
# the SPC registers directly and never executes a byte of that ROM -- which
# was already the plan in docs/BENCHMARK.md item 4, long before the ROM turned
# out to be missing. DO NOT reuse this rompath for anything that boots from
# the card or calls SCSI IOCS; those DO execute it.
#
# WHAT A GREEN RUN MEANS: the 68000 reached the SPC, selected a target, issued
# READ(10) twice -- at LBA 0 and at a non-zero LBA -- and both came back byte for
# byte identical to the host's copy of the same image. No IOCS, no host in the
# transfer path.
#
# WHAT IT DOES NOT MEAN: anything at all about RATE. MAME's device models are
# functional, not transfer-timing accurate (docs/BENCHMARK.md), and 42.5 reads
# its DMAC configured in wall-clock attotimes rather than per-operand cycles.
# `W` -- clocks stolen per delivered byte, the project's largest open number --
# is untouched by this script.
set -e
cd "$(dirname "$0")/../.."
DLX=${1:-tmp/rc_fr_singe_scsi_span.dlx}
# The container's frame records, laid out as a disc, and the blank card ROM.
# Both are tools/bench/mkvol.sh's, shared with tools/bench/pace_run.sh so the
# SCSI rig and the host-file ring rig cannot be reading different bytes.
bash tools/bench/mkvol.sh "$DLX"
tools/vasm/vasmm68k_mot -Fbin -o tmp/scsigate.bin src/player/scsigate.s > /dev/null
# stdbuf -oL: without it a long MAME run is unobservable until it exits, and a
# run that is merely finishing looks exactly like one that is wedged (34.1).
( cd tmp && SDL_VIDEODRIVER=dummy stdbuf -oL timeout -k 5 300 \
mame x68000 -bios ipl10 -exp1 cz6bs1 \
-rompath "$HOME/mame/roms;./p4roms" -hard dlxdisk.chd \
-ramsize 2M -video soft -window -sound none -nothrottle -plugins \
-autoboot_script ../tools/bench/scsi.lua \
-seconds_to_run 60 > scsi_run.log 2>&1 )
# A run that never reached the report must fail as that, not as a missing line.
grep -aq "^\[SCSI\] done" tmp/scsi_run.log || {
echo "FAIL: the SCSI gate did not finish -- no completion marker."
tail -8 tmp/scsi_run.log; exit 1; }
grep -a "^\[SCSI\]" tmp/scsi_run.log | grep -avE "^\[SCSI\] +[0-9]+:" \
| sed 's/^\[SCSI\] / /'
# THE ASSERTIONS. Printing a result and gating on it are different things, and
# this project has already paid once for a stage that printed.
grep -aq "ANSWERED 60 of 64" tmp/scsi_run.log || {
echo "FAIL: the card's register window is no longer 60 of 64 addresses."
echo " The MB89352 omits TMOD (index 3) and EXBF (index 15) where the"
echo " MB87030 has them, and MAME leaves HOLES rather than shifting the"
echo " later indices down -- which is what puts DREG at \$EA0015. If this"
echo " moved, src/player/scsi.i's whole register map moved with it."
exit 1; }
grep -aq "READ(10) OK: 4096 B from LBA 0" tmp/scsi_run.log || {
echo "FAIL: the 68000 did not read LBA 0 off the SCSI volume byte-exact."
exit 1; }
grep -aq "READ(10) OK: 2048 B from LBA 1000" tmp/scsi_run.log || {
echo "FAIL: the read at a NON-ZERO LBA did not match. A driver that emits a"
echo " malformed LBA field still passes LBA 0, because zero is what a"
echo " malformed field usually is -- so this is the half that matters."
exit 1; }
grep -aq "scsi_read FAILED" tmp/scsi_run.log && {
echo "FAIL: a read reported an error."; exit 1; }
exit 0