Files
prosolis f925a1dd9a Put sound on the wire, and find three LSBs are worth 25 dB
ROADMAP P6, everything in the item except the bus half session 20 closed.
tools/encoder/adpcm.py is an MSM6258 codec, tools/encoder/extract_audio.py
takes the same seconds of the same stream the frames come from,
tools/bench/verify_adpcm.py is the gate, tools/analysis/32_audio_wire.py the
container arithmetic.

There is no reference encoder -- ffmpeg has a decoder for this format and none
the other way -- so what is gated is the decoder the encoder runs INSIDE its
own nibble search, sample-exact against ffmpeg's over 4,268 nibbles. An
encoder that agrees with its own wrong decoder is what that catches. The Singe
window: 156,250 samples -> 78,125 B at 21.97 dB, which is 7,812.5 B/s to the
byte. Normalising the disc's -13.4 dBFS level moves the SNR 21.97 -> 21.97, so
the level is not a lever.

And the two published delta formulas are not the same codec. They differ by at
most 3 in 12-bit units; encode for one and decode on the other and the SNR
goes 21.97 -> -2.88 dB, the noise louder than the signal, because ADPCM is
recursive the way the video codec is temporally recursive. Which one the chip
runs is now P6a and it is a precondition on shipping any audio.

And audio is the first thing the packed branch's simplification has cost
anything for. A record has no index BY DESIGN, so audio cannot be per-record
without making records variable; it rides a fixed cadence (F, A), the obvious
F=1 wastes 57.3% of every audio sector, and the pick is F=11 A=14 -- 0.09%
padding, 14,336 B held, wire 582.0 -> 589.6 KB/s. The codec container, which
kept its index, pays zero.

The MAME experiment did not work and 65.5 says so: :okim6258 is there at
$E92001/$E92003, read out of the machine's own program map, and feeding it
from Lua recorded silence across control 0..3 x port C 0..15. The register
semantics were not guessed at further.

FINDINGS 65. check.sh ALL GREEN before and after, with a new stage.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
2026-08-25 09:11:03 -07:00

37 lines
1.5 KiB
Lua

-- Feed the x68000's OWN okim6258 a known nibble stream and let MAME record what
-- comes out, so that "which delta formula does the chip use" is a MEASUREMENT
-- and not a reading of source code that is not on this machine (64.4).
--
-- The feed is deliberately SLOW -- a byte every host frame, where real time
-- wants ~138 -- because the question is not the rate. A starved chip holds its
-- last sample, so the wave is a STAIRCASE of the reconstructed values, which is
-- exactly the sequence the two candidate formulas disagree about.
M = manager.machine
local sp = M.devices[":maincpu"].spaces["program"]
local CTRL, DATA = 0xE92001, 0xE92003
local CMD = tonumber(os.getenv("AD_CMD") or "1")
-- 12 loud nibbles to climb the step index, then every nibble in turn: the pairs
-- where the two formulas differ are all at step indices above the floor.
local nibs = {}
for i = 1, 12 do nibs[#nibs+1] = 7 end
for i = 0, 15 do nibs[#nibs+1] = i end
for i = 0, 15 do nibs[#nibs+1] = i end
local bytes = {}
for i = 1, #nibs, 2 do bytes[#bytes+1] = nibs[i] * 16 + nibs[i+1] end
local n, started = 0, false
SUB = emu.add_machine_frame_notifier(function()
n = n + 1
if n == 30 then
sp:write_u8(CTRL, CMD)
started = true
print(string.format("[AD] ctrl $%02X written to $%06X", CMD, CTRL))
elseif started and n > 30 and (n - 30) <= #bytes then
sp:write_u8(DATA, bytes[n - 30])
elseif started and (n - 30) == #bytes + 20 then
print("[AD] fed " .. #bytes .. " bytes = " .. #nibs .. " nibbles")
print("[AD] done")
M:exit()
end
end)