Put the SPC on the 68000, and find P4 was blocked on a file nobody needed
ROADMAP P4, first half. Every byte the player has ever consumed was placed in emulated RAM by a host: decode.lua preloaded a container, stream.lua answered a mailbox at a modelled rate. src/player/scsi.i selects a SCSI target on a real MB89352 and issues READ(10) itself -- 4,096 B from LBA 0 and 2,048 B from LBA 1000, both byte-for-byte against the host's copy of the same volume, with no IOCS and no host in the transfer path. The non-zero LBA is the half that matters: a driver that emits a malformed LBA field still passes block 0, because zero is what a malformed field usually is. P4 was recorded as blocked in this tree and was not. Session 21's handoff said MAME's x68000 has no MB89352 path; -exp1 cz6bs1 instantiates one next to the HD63450, and FINDINGS 32.4 had read that card's DMA glue in session 9. The session-21 note is a regression in the record, not a discovery. What is genuinely absent is the 8 KB scsiexrom.bin MAME requires to INSTANTIATE the card and the player never executes -- driving the SPC registers directly has been the plan since BENCHMARK item 4 in session 2 -- so scsi_run.sh supplies a zero-filled placeholder on its own rompath, leaves the user's romset alone, and lets MAME print WRONG CHECKSUMS as it should. B3 is untouched: it wants that ROM's bytes disassembled and a blank one has none. The register map is measured, not inferred, and it corrects MAME's own documentation. The probe walks $EA0000..$EA003F one address at a time with a bus-error handler that records the fault and steps the index, because a sequential dump reports the first hole as the answer -- the earlier version took a bus error at $EA0006 and knew nothing about the other 57. 60 of 64 answer; the two holes are exactly the TMOD and EXBF the MB89352 omits and the MB87030 has. MAME leaves HOLES and does not shift the later indices down, which its own device summary claims it does, and that is what keeps DREG at $EA0015. The data register is DMA-only here and a PIO write vanishes. x68k_scsiext.cpp glues $EA0015 and nothing else, and with exown() asserted and DRQ low the byte is discarded: no error bit, no status change, no interrupt. Quieting all four DMAC channels does not change it. Measured rather than reasoned about -- write $5A, read back $00 with the FIFO still empty -- because ten command bytes vanishing without trace looks exactly like a target refusing a command, which is how it first presented. So every transfer runs the SPC in DMA mode and the CPU moves the bytes through the DMAC's own door. That costs the argument something, and it is easy to overclaim here: with exown asserted at idle MAME cannot distinguish a CPU-driven byte at $EA0015 from a DMAC-driven one. This shows the DATA PATH and cannot by itself show that the HD63450 is driving it, which is precisely what ROADMAP calls P4's first job. Whether a real CZ-6BS1 also refuses PIO there is not settled; it is a property of MAME's model and it wants a board. W did not move by one clock, and could not have. MAME's device models are functional rather than transfer-timing accurate and 42.5 reads its DMAC configured in wall-clock attotimes, so this is BENCHMARK Tier 1 -- does the read path work -- and never Tier 2. W is still the largest open number here. Five bugs, four of them silent, recorded in 57.5 because the pattern is the finding: a chain of rol.l #8 that loaded a transfer counter of ZERO from a count of 10; a byte handed to a FIFO mistaken for a byte on the bus; a fixed phase sequence where the bus decides the order; the discarded PIO write; and an initiator that must drop ACK and only then release the bus. The last appeared only once there were TWO reads -- one passed byte-exact and every conclusion from it was sound, and the second could not select. A player issues one command per record, so that failure would have been universal in the ring and invisible in a one-read demonstration. No decoder code changed; decode.bin is still 1,296 B at the same MD5. check.sh gains a SCSI stage that builds the volume out of the same stream_disk.bin the ring rig reads, gates the register window at 60 of 64 and both reads byte-exact, and skips when chdman is absent. ALL GREEN before and after. Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/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. prep_stream.py already
|
||||
# writes exactly this file for the ring rig, so the SCSI volume and the host-file
|
||||
# pipe carry byte-identical bytes and a difference between the two rigs cannot be
|
||||
# a difference in what they are reading.
|
||||
[ -f tmp/stream_disk.bin ] || python3 tools/bench/prep_stream.py "$DLX" > /dev/null
|
||||
if [ ! -f tmp/dlxdisk.chd ] || [ tmp/stream_disk.bin -nt tmp/dlxdisk.chd ]; then
|
||||
python3 - <<'PY'
|
||||
d = open("tmp/stream_disk.bin", "rb").read()
|
||||
n = (len(d) + 511) // 512
|
||||
open("tmp/dlxdisk.img", "wb").write(d + b"\0" * (n * 512 - len(d)))
|
||||
print(f" disc image: {len(d)} B of records -> {n} sectors")
|
||||
PY
|
||||
rm -f tmp/dlxdisk.chd
|
||||
chdman createhd -i tmp/dlxdisk.img -o tmp/dlxdisk.chd -ss 512 > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
mkdir -p tmp/p4roms/x68k_cz6bs1
|
||||
[ -f tmp/p4roms/x68k_cz6bs1/scsiexrom.bin ] || \
|
||||
head -c 8192 /dev/zero > tmp/p4roms/x68k_cz6bs1/scsiexrom.bin
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user