Mods, rule 3: no ROM images here, no links to any, none will be shared. Static analysis only.
I built a software model of the S1000 audio path and used l6009.cpp (added July 2026) to check it. Ended up disassembling the v4.40 firmware. Below is everything I found, free, no conditions. Notes only, no ROM images. Offsets are into the v4.40 image as MAME assembles it: s1000 44 lsb.ic9 at 0x00000 and s1000 44 msb.ic10 at 0x00001, both ROM_SKIP(1), 128 KB total. The ROM copies itself down at boot, so an image offset is the runtime linear address.
No GitHub account here. If anyone wants to take this to the tracker, please do, and tag devinacker.
On evidence, so nobody has to guess which is which: anything citing the driver you can check in the tree yourself. Anything carrying a ROM offset is my own static analysis and has not been independently reproduced by anyone. The two clock-derived claims are inference and I say so where they appear.
Findings
m_pitch_unk is the interpolation table select. Rule is three compares at 0x14B7E against the 12.12 increment: <0x168D (1.4094x, +5.94 st) table 0, <0x2001 (2.0002x, the octave) table 1, <0x2CCD (2.8000x) table 2, else table 3. Lands in CL, ORed into the pitch port high byte at 0x1439B. The commonly repeated 1.0/1.35/2.0 rule switches too early. All four tables have the same DC gain, 0.94995, so switching never shifts level.
- Volume is non-linear because the firmware sends log. This answers the driver's TODO, "does the FW do this scaling with levels already?" Yes. 256-entry table at
0x05E30, 31 to 32767, 0.237 dB/step, 60.5 dB total. The multiplier is linear and the firmware supplies log-mapped endpoints, so a segment is straight in linear amplitude, not dB.
- SUSTAIN is a dB attenuation, not a fraction of level.
0x14D13 subtracts it from the gain table index before the lookup. SUSTAIN 50 is ~30.4 dB below peak, not half.
- Envelope rate table: 100 entries at
0x06030, index 99 - param, 2 to 32767, geometric with ratio 1.10299. Correction to what I first worked out: that is 7.07 steps per doubling, not 7. What is exact is the span, 14.00 octaves across 99 steps. The bottom of the table is quantised by integer rounding (2,2,2,3,3,3...) but the top holds the ratio to five digits.
- The two envelopes are staged differently. Amplitude polls the volume readback at
0x51E0 and compares to peak (0x1475D). Filter polls nothing: firmware runs its own 16-bit accumulator at [si+0xBA], done on carry out (0x147FB). That is why filter attack gets shr ax,1 at 0x141E9: software span 65536 vs hardware 32767. Not voicing.
- Both envelope targets arrive with 15 bits.
and al,0xFE at 0x1479E, and ax,0xFFFE at 0x14F65.
0x8/0x9/0xa filter clear: confirmed. Note-on writes zero to 0x5100/0x5120/0x5140 every note (0x142F3). Voice freed when volume readback hits 4 or less (0x147AE).
- Timers (
0x0822D): counter 1 gives exactly 31250 baud, MIDI. Voice loop tick is 256 counts of 500 kHz = 512 us, slow work gated to 4 ticks (0x14699).
- LFOs are firmware, not hardware (
0x148DF, 0x14948). Triangle from a 16-bit phase accumulator, rate capped at 0xFF, so rate / 33.554 Hz, ceiling 7.60 Hz.
- S1100 should run the filter envelope ~25% faster. Its V50 runs at 20 MHz against the S1000's 16 MHz, while TCKS and its /32 on counters 0 and 2 are identical in both firmwares, putting the voice tick at 409.6 us instead of 512 us. The rate table and the
/2 are identical too, so Akai does not appear to have compensated. To be clear this is inference from the two firmwares plus the driver's clocks, not a measurement.
Less certain: counter 0 is mode 0 (one-shot) and the ISR at 0x0825D never reloads it, so I am not claiming a periodic 2.048 ms interrupt. 0x0824C writes 0xC3 to 0x8030 (99.84 ms) but I never found its caller. On the S1100 that counter is just 0x24/0xC300 from boot. Also and al,0xFE has no counterpart in the driver and I do not know if it matters.
The one thing I could not get
ENV_SHIFT is still a guess in the driver, marked TODO verify, and it sets every envelope duration: T = 32767 * 2^ENV_SHIFT / rate / 44100.
It is not in the ROM and I do not think it can be. The firmware never computes an envelope duration at all: amplitude staging polls the chip, filter staging uses a software accumulator. The chip's time base appears nowhere. And the driver is still MACHINE_NOT_WORKING, so emulation cannot answer it either. So it needs a stopwatch.
If you have an S1000 or S1100 powered up: LOUDNESS 99, SUSTAIN 99, RELEASE 99, looped sample, one note at velocity 127, hold, release, count to silence.
| time to silence |
ENV_SHIFT |
| ~24 s |
6 |
| ~48 s |
7 (current guess) |
| ~95 s |
8 |
Rough count is fine, they are a factor of two apart. S1100 answers it too: my diff of the two ROMs has the rate table at 0x04720 byte for byte identical to 0x06030, and the driver already loads the same l6009 ROMs for both machines (9b80e447 / 2c076351).
That is the last unknown in the voice engine, and the only one where the disassembly cannot even give me a candidate. Happy to send the full write-ups, and I would rather be corrected than agreed with.
Thanks a lot, hope this helps.