Parametric EQ — HLE reconstruction and DSP bytecode

DSPHLE selector 0x01 · program image prog39_parametric_eq · Intervention-pinned (a panel control was driven and the moving C-RAM cell identified).

5-band RBJ biquad from decoded design params (FREQ=0x03, GAIN=0x01); spectral A/B PASS.

This page pairs the bytecode the effect runs on the NEC µPD6383GF with the high-level reconstruction that makes it audible in MAME. The reconstruction is not the chip’s microcode — it is a textbook DSP block built from the decoded meaning of that microcode, and reading the two together is how the bytecode is understood (and, in time, driven toward a faithful low-level emulation). See also the signal-flow flowchart.

The bytecode below is the source of truth; the HLE reconstruction is not. The HLE is our best current interpretation and may contain mistakes — where the two disagree, the bytecode wins, and a better HLE should be updated here. This page is the permanent archive of the reference HLE: it is kept here even after the code is eventually removed from the MAME sources.

DSP bytecode (reverse-engineered microprogram)

The disassembled image the chip executes for this effect. Source (regenerable): dsp/disasm/prog39_parametric_eq.dsm.

; Reverse-engineered disassembly of the KN5000 effects-DSP microcode
; (NEC uPD6383GF), recovered from the original firmware.  The microcode is the
; work of its original authors; this is a disassembly for preservation and
; interoperability, and no claim of copyright is made over the disassembled program.
; KN5000 effects-DSP program -- PARAMETRIC EQ
; image rep algo 39  |  slots 39  |  unit 0 (I-RAM load 84)
; family eq  |  confidence SOLVED  |  105 words, 60 class-A multiplies (60 named)
; role: parametric EQ: 5 bands x 2 channels, Direct-Form-I bilinear biquad (decoded to the bit); the reference program
; coefficient cursor base 0x00
;
; GENERATED by dsp/tools/gen_dsp_disasm.py -- DO NOT EDIT.
; Put labels/comments in the matching dsp/sym/*.sym; analysis in dsp/algorithms/.

  w0    000020B1CD   ld      (p),(p)+11
  w1    000020040E   ld      acc,(p)+0
  w2    0212200000   mac.b   (p)0,(p)+0 ; mem[p]<-acc, acc=0
  w3    002A200000   ?word   0x002A200000   ; 02A.2.00.000  hi12{f31=5 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w4    0000240407   ld.st   acc,(p)+64
Band0_Section:
  w5    0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x00] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x00] = biquad b1 (role EQ, PROVEN)
        ; P = b1*S0 ; latch A <- S0
  w6    0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x01] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x01] = biquad b0 (role EQ, PROVEN)
        ; S0 <- x ; acc = P ; P = b0*x
  w7    0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x02] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x02] = biquad b2 (role EQ, PROVEN)
        ; acc += P ; P = b2*S1
  w8    0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x03] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x03] = biquad -a1 (role EQ, PROVEN)
        ; acc += P ; P = -a1*S2 ; latch B <- S2
  w9    0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x04] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x04] = biquad -a2 (role EQ, PROVEN)
        ; acc += P ; P = -a2*S3
  w10   01022FF687   mac.st  tb,(p)-1
        ; acc += P ; S3 <- latch B (class-2 store)
  w11   0804816415   post    acc,c
        ; class-8 post-sum step -- OPERATION UNKNOWN
  w12   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x05] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x05] = biquad makeup (role EQ, PROVEN)
        ; S2 <- acc ; P = makeup*acc
  w13   0000203647   ld.st   ta,(p)+3
        ; acc <- P ; S1 <- latch A (class-2 store)
  w14   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x06] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x06] = biquad b1 (role EQ, PROVEN)
  w15   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x07] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x07] = biquad b0 (role EQ, PROVEN)
  w16   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x08] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x08] = biquad b2 (role EQ, PROVEN)
  w17   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x09] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x09] = biquad -a1 (role EQ, PROVEN)
  w18   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x0A] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0A] = biquad -a2 (role EQ, PROVEN)
  w19   01022FF687   mac.st  tb,(p)-1
  w20   0804816415   post    acc,c
  w21   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x0B] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0B] = biquad makeup (role EQ, PROVEN)
  w22   0000203647   ld.st   ta,(p)+3
  w23   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x0C] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0C] = biquad b1 (role EQ, PROVEN)
  w24   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x0D] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0D] = biquad b0 (role EQ, PROVEN)
  w25   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x0E] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0E] = biquad b2 (role EQ, PROVEN)
  w26   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x0F] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0F] = biquad -a1 (role EQ, PROVEN)
  w27   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x10] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x10] = biquad -a2 (role EQ, PROVEN)
  w28   01022FF687   mac.st  tb,(p)-1
  w29   0804816415   post    acc,c
  w30   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x11] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x11] = biquad makeup (role EQ, PROVEN)
  w31   0000203647   ld.st   ta,(p)+3
  w32   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x12] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x12] = biquad b1 (role EQ, PROVEN)
  w33   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x13] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x13] = biquad b0 (role EQ, PROVEN)
  w34   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x14] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x14] = biquad b2 (role EQ, PROVEN)
  w35   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x15] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x15] = biquad -a1 (role EQ, PROVEN)
  w36   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x16] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x16] = biquad -a2 (role EQ, PROVEN)
  w37   01022FF687   mac.st  tb,(p)-1
  w38   0804816415   post    acc,c
  w39   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x17] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x17] = biquad makeup (role EQ, PROVEN)
  w40   0000203647   ld.st   ta,(p)+3
  w41   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x18] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x18] = biquad b1 (role EQ, PROVEN)
  w42   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x19] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x19] = biquad b0 (role EQ, PROVEN)
  w43   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x1A] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1A] = biquad b2 (role EQ, PROVEN)
  w44   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x1B] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1B] = biquad -a1 (role EQ, PROVEN)
  w45   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x1C] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1C] = biquad -a2 (role EQ, PROVEN)
  w46   01022FF687   mac.st  tb,(p)-1
  w47   0804816415   post    acc,c
  w48   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x1D] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1D] = biquad makeup (role EQ, PROVEN)
  w49   00002AD647   ld.st   ta,(p)-83
  w50   0028200000   ?word   0x0028200000   ; 028.2.00.000  hi12{f31=4 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w51   0880130407   dly.r  dsc[k],p+48
  w52   00002F7000   nop
  w53   000020A1CD   ld      (p),(p)+10
  w54   00002FF1CE   ld      (p),(p)-1
  w55   0212202000   mac.b   (p)0,(p)+2 ; mem[p]<-acc, acc=0
  w56   002A200000   ?word   0x002A200000   ; 02A.2.00.000  hi12{f31=5 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w57   0000254407   ld.st   acc,(p)+84
  w58   0801000021   rstcur
  w59   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x00] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x00] = biquad b1 (role EQ, PROVEN)
  w60   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x01] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x01] = biquad b0 (role EQ, PROVEN)
  w61   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x02] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x02] = biquad b2 (role EQ, PROVEN)
  w62   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x03] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x03] = biquad -a1 (role EQ, PROVEN)
  w63   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x04] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x04] = biquad -a2 (role EQ, PROVEN)
  w64   01022FF687   mac.st  tb,(p)-1
  w65   0804816415   post    acc,c
  w66   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x05] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x05] = biquad makeup (role EQ, PROVEN)
  w67   0000203647   ld.st   ta,(p)+3
  w68   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x06] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x06] = biquad b1 (role EQ, PROVEN)
  w69   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x07] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x07] = biquad b0 (role EQ, PROVEN)
  w70   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x08] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x08] = biquad b2 (role EQ, PROVEN)
  w71   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x09] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x09] = biquad -a1 (role EQ, PROVEN)
  w72   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x0A] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0A] = biquad -a2 (role EQ, PROVEN)
  w73   01022FF687   mac.st  tb,(p)-1
  w74   0804816415   post    acc,c
  w75   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x0B] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0B] = biquad makeup (role EQ, PROVEN)
  w76   0000203647   ld.st   ta,(p)+3
  w77   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x0C] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0C] = biquad b1 (role EQ, PROVEN)
  w78   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x0D] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0D] = biquad b0 (role EQ, PROVEN)
  w79   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x0E] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0E] = biquad b2 (role EQ, PROVEN)
  w80   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x0F] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0F] = biquad -a1 (role EQ, PROVEN)
  w81   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x10] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x10] = biquad -a2 (role EQ, PROVEN)
  w82   01022FF687   mac.st  tb,(p)-1
  w83   0804816415   post    acc,c
  w84   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x11] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x11] = biquad makeup (role EQ, PROVEN)
  w85   0000203647   ld.st   ta,(p)+3
  w86   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x12] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x12] = biquad b1 (role EQ, PROVEN)
  w87   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x13] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x13] = biquad b0 (role EQ, PROVEN)
  w88   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x14] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x14] = biquad b2 (role EQ, PROVEN)
  w89   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x15] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x15] = biquad -a1 (role EQ, PROVEN)
  w90   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x16] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x16] = biquad -a2 (role EQ, PROVEN)
  w91   01022FF687   mac.st  tb,(p)-1
  w92   0804816415   post    acc,c
  w93   0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x17] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x17] = biquad makeup (role EQ, PROVEN)
  w94   0000203647   ld.st   ta,(p)+3
  w95   0000A001D3   ld.ta   (p),c+,(p)+0
        ; C-RAM[0x18] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x18] = biquad b1 (role EQ, PROVEN)
  w96   0212A01412   mac     acc,c+,(p)+1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x19] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x19] = biquad b0 (role EQ, PROVEN)
  w97   0202A011D5   mac     (p),c+,(p)+1
        ; C-RAM[0x1A] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1A] = biquad b2 (role EQ, PROVEN)
  w98   0202A011D4   mac.tb  (p),c+,(p)+1
        ; C-RAM[0x1B] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1B] = biquad -a1 (role EQ, PROVEN)
  w99   0202A001D5   mac     (p),c+,(p)+0
        ; C-RAM[0x1C] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1C] = biquad -a2 (role EQ, PROVEN)
  w100  01022FF687   mac.st  tb,(p)-1
  w101  0804816415   post    acc,c
  w102  0212AFF407   mac.st  acc,c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x1D] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x1D] = biquad makeup (role EQ, PROVEN)
  w103  0880130647   dly.r  dsc[k],p+48
  w104  042810E000   ?word   0x042810E000   ; 428.1.0E.000  hi12{END f31=4 ?5 res=020}  [END OF BLOCK, unit 0 -- CALL/RETURN -- and still performs the rest of the word]

HLE reconstruction (MAME, kn5000_tonegen.cpp)

The decode of the bytecode above, rebuilt as audible DSP. Two parts: the parameter refresh (reads the decoded C-RAM coefficient cells once per update) and the per-sample insert (the signal processing). Default OFF, behind the DSPHLE research port. Source: src/mame/matsushita/kn5000_tonegen.cpp.

Parameter refresh (decode the C-RAM coefficients):

	const bool eq_hle = (dsphle == 1);
	if (eq_hle)
	{
		// The raw C-RAM cells are NOT direct-form biquad coefficients: eq_spectral_ab.py
		// proved no permutation of {cell0..5} -> {b0,b1,b2,a1,a2} yields a valid peaking
		// response (that needs the undecoded x/y-history realization, walled N2). But the
		// DESIGN PARAMETERS are recoverable from the cells, and building textbook RBJ
		// peaking biquads from them is the validated HLE route (dsp/hle/). Per band:
		//   * FREQUENCY  (SOLID, MEASURED, N1'): cell 0x03 == 2*cos w0  ->  w0 = acos(c3/2).
		//     Cross-checked: cell 0x00 == -c3/2 == -cos w0 in every capture, and band 1's
		//     0x03 gives 966 Hz (== N1' band-1 centre).  Universal across bands.
		//   * GAIN       (MEASURED per band): A^2 == 1 + G[band]*(c1-0.5).  Cell base+1 is
		//     EXACTLY 0.5 (0x200000) at 0 dB -- for every band, and under a frequency-only edit
		//     -- and deviates only under a gain edit; so (c1-0.5) is the pure, frequency-
		//     INDEPENDENT gain signal (unlike (c1-c2), which an FC edit would misread as
		//     +31 dB).  Each band's slope G was fit by driving THAT band's gain +12 dB on the
		//     panel and reading its cell (dsp/tools/eq_band_gain_calibrate.py): the slope is
		//     NOT uniform -- it roughly HALVES per band (the gain cell moves ~2x further per dB
		//     as the band centre rises), so a single constant is wrong for bands 1-4.
		//   * Q          (ASSUMED): 2.0.  Q sets bandwidth only; the peak height that the
		//     spectral A/B checks == the designed dB regardless of Q.
		// Coefficients are RBJ (Audio EQ Cookbook), normalised by a0.  Default OFF; validated
		// offline (eq_rbj_reconstruct_ab.py) and by in-emulator spectral A/B at bands 0 and 2
		// (+~11 dB at the band centre, flat elsewhere).  See N1-EQ-COEFFICIENT-MEMORY note.
		constexpr double GAIN_G[5] = { 465.8, 225.8, 114.2, 58.3, 30.5 };  // per-band A^2 slope
		constexpr double QVAL   = 2.0;      // assumed band Q (documented)
		auto q22 = [](uint32_t v) -> double {
			int32_t s = (v & 0x800000) ? int32_t(v) - 0x1000000 : int32_t(v);
			return double(s) / 4194304.0; };
		for (int band = 0; band < 5; band++)
		{
			const uint8_t base = uint8_t(band * 6);
			const u32 r1 = m_dsp1->cram_read(base + 1);
			const u32 r3 = m_dsp1->cram_read(base + 3);
			double c1 = q22(r1);   // gain cell
			double c3 = q22(r3);   // frequency cell
			// m_cram is read at one of two scales that differ by exactly 2x (N1':
			// "operand = C-RAM cell >> 1"). The capture dumps recorded the CELL scale
			// (0x03 = 2*cos w0, gain baseline 0.5); at runtime, when the EQ insert reads
			// m_cram without the LLE having executed (the normal HLE case, DSPCFG off),
			// m_cram holds the firmware-uploaded OPERAND scale -- exactly half (0x03 =
			// cos w0, baseline 0.25). Detect via the frequency cell: all five fixed band
			// centres (673..3219 Hz) have cos w0 in 0.89..0.995, so |c3|<=1 is operand
			// scale (double both cells back to the cell scale the formula is calibrated on);
			// |c3|>1 is already cell scale. MEASURED: runtime c3=0.9954, c1=0.2532 (+12 dB)
			// == exactly half the dump's 1.9908 / 0.50654.
			const double norm = (std::fabs(c3) <= 1.0) ? 2.0 : 1.0;
			c1 *= norm; c3 *= norm;
			const double cosw0 = std::clamp(c3 * 0.5, -0.9995, 0.9995);
			const double asq   = 1.0 + GAIN_G[band] * (c1 - 0.5); // A^2; >1 boost, <1 cut
			if (KN5000_EQHLE_DEBUG)
			{
				static u32 dbgcall = 0; static int dbgn = 0; static bool dbgthis = false;
				if (band == 0) { dbgthis = ((dbgcall++ % 400) == 0 && dbgn < 40); if (dbgthis) dbgn++; }
				if (dbgthis)
					fprintf(stderr, "### EQHLE t=%.2f b%d r1=%06X r3=%06X c1=%.4f c3=%.4f asq=%.3f\n",
							machine().time().as_double(), band, r1, r3, c1, c3, asq);
			}
			// A band is ACTIVE only if its cells are a plausible peaking design: c3 is a
			// real 2*cos w0 (|c3|<=2) and asq is a sane gain (about -17..+34 dB). Zeroed or
			// not-yet-uploaded C-RAM (c1=c3=0 -> asq=-226) or garbage -> unity passthrough,
			// so a missing/idle EQ can never turn into the broadband cut that a raw A=0.1
			// cascade would produce.
			if (std::fabs(c3) > 2.001 || asq < 0.02 || asq > 50.0 ||
			    std::fabs(asq - 1.0) < 1e-4)   // out-of-range / 0 dB / unused -> passthrough
			{
				m_eq_l[band].set_coeffs(1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
				m_eq_r[band].set_coeffs(1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
				continue;
			}
			const double A     = std::sqrt(std::max(asq, 0.01));
			const double w0    = std::acos(cosw0);
			const double alpha = std::sin(w0) / (2.0 * QVAL);
			const double b0 = 1.0 + alpha * A;
			const double b1 = -2.0 * cosw0;
			const double b2 = 1.0 - alpha * A;
			const double a0 = 1.0 + alpha / A;
			const double a1 = -2.0 * cosw0;
			const double a2 = 1.0 - alpha / A;
			m_eq_l[band].set_coeffs(b0 / a0, b1 / a0, b2 / a0, a1 / a0, a2 / a0, 1.0);
			m_eq_r[band].set_coeffs(b0 / a0, b1 / a0, b2 / a0, a1 / a0, a2 / a0, 1.0);
		}
	}

Per-sample insert (the reconstructed signal path):

		if (eq_hle)
		{
			double yl = double(mix_l) / 32768.0;
			double yr = double(mix_r) / 32768.0;
			for (int band = 0; band < 5; band++)
			{
				yl = m_eq_l[band].process_one(yl);
				yr = m_eq_r[band].process_one(yr);
			}
			mix_l = int32_t(yl * 32768.0);
			mix_r = int32_t(yr * 32768.0);
		}