Enhancer — HLE reconstruction and DSP bytecode

DSPHLE selector 0x10 · program image prog03_enhancer · Preview (topology decoded and reconstructed; most panel→cell role mappings are position-decoded).

high-shelf emphasis + all-pass phase + decoded 350 ms slap (DELAY=0x0B proven); roles INFERRED.

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/prog03_enhancer.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 -- ENHANCER
; image rep algo 3  |  slots 3  |  unit 0 (I-RAM load 84)
; family filter  |  confidence medium  |  99 words, 26 class-A multiplies (18 named)
; role: enhancer: phase/emphasis shaping
; 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    088013000B   ?word   0x088013000B   ; 880.1.30.00B  hi12{ESC ?7 res=080}  [external delay-DRAM READ (FORCED, adjudication-round5 sect. 3 -- addr8 bit 6 is the direction field and 0x60 is the WRITE; this REVERSES R1 F1, which bounded the read latency to one repetition when the descriptors need twenty words); this end moves with the user's DELAY (ms) knob, and the delay is READ_CELL - WRITE_CELL; addr8 0x30 also marks the FIRST DRAM access of a body, 37 of 38 distinct images (R3 sect. 6.2). external delay-DRAM access; address = DESCRIPTOR_CELL[k] + G, from the host bank behind pointer ...825 / tag 0x4C (R3, PROVEN BY CONSTRUCTION) -- the k-th class-1 escape word of a body takes the k-th cell of that body's own descriptor block (the IDENTITY map, FORCED in adjudication-round5 sect. 1), so the address is NOT in this word]
  w1    000020B1CD   ld      (p),(p)+11
  w2    000020040E   ld      acc,(p)+0
  w3    0212200000   mac.b   (p)0,(p)+0 ; mem[p]<-acc, acc=0
  w4    002A240000   ?word   0x002A240000   ; 02A.2.40.000  hi12{f31=5 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w5    0000A001D5   ld      (p),c+,(p)+0
        ; C-RAM[0x00] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x00] = damping filter tap 0 (role damping, PROVEN)
  w6    0292A01412   mac     acc,c+,(p)+1 ; store SUPPRESSED (bit7)
        ; C-RAM[0x01] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x01] = damping filter tap 1 (role damping, PROVEN)
  w7    0282ABF1D5   mac     (p),c+,(p)-65
        ; C-RAM[0x02] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x02] = damping filter tap 2 (role damping, PROVEN)
  w8    0282241407   mac.st  acc,(p)+65
  w9    00122C1447   ?word   0x00122C1447   ; 012.2.C1.447  hi12{ST f31=1}  [SPECULATIVE (prospective, not measured): SRC 0x11 = ACCB (2nd accumulator)]
  w10   00002401C8   ?word   0x00002401C8   ; 000.2.40.1C8  hi12{-}  [SPECULATIVE (prospective, not measured): ACT 0x08 = table-port multiply]
  w11   00002C21D5   ld      (p),(p)-62
  w12   010223E1CD   mac     (p),(p)+62
  w13   0212201412   mac     acc,(p)+1 ; mem[p]<-acc, acc=0
  w14   01042C11D5   post    (p),(p)-63
  w15   010223F1CD   mac     (p),(p)+63
  w16   0212ABE412   mac     acc,c+,(p)-66 ; mem[p]<-acc, acc=0
        ; C-RAM[0x03] (coeff, base 0x00 MEASURED)
  w17   0104200000   post.b  (p)0,(p)+0
  w18   0026200000   ?word   0x0026200000   ; 026.2.00.000  hi12{f31=3 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w19   0880130407   dly.r  dsc[k],p+48
  w20   00002FF000   nop
  w21   00122441C0   mac.b   (p),(p)+68 ; mem[p]<-acc, acc=0
  w22   0104A001D5   post    (p),c+,(p)+0
        ; C-RAM[0x04] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x04] = damping filter tap 0 (role damping, PROVEN)
  w23   0292A01412   mac     acc,c+,(p)+1 ; store SUPPRESSED (bit7)
        ; C-RAM[0x05] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x05] = damping filter tap 1 (role damping, PROVEN)
  w24   0282ABB1D5   mac     (p),c+,(p)-69
        ; C-RAM[0x06] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x06] = damping filter tap 2 (role damping, PROVEN)
  w25   0282245000   mac.b   (p)0,(p)+69
  w26   00122BD447   ?word   0x00122BD447   ; 012.2.BD.447  hi12{ST f31=1}  [SPECULATIVE (prospective, not measured): SRC 0x11 = ACCB (2nd accumulator)]
  w27   00002441C8   ?word   0x00002441C8   ; 000.2.44.1C8  hi12{-}  [SPECULATIVE (prospective, not measured): ACT 0x08 = table-port multiply]
  w28   00002BE1D5   ld      (p),(p)-66
  w29   01022421CD   mac     (p),(p)+66
  w30   0212201412   mac     acc,(p)+1 ; mem[p]<-acc, acc=0
  w31   01042BD1D5   post    (p),(p)-67
  w32   01022431CD   mac     (p),(p)+67
  w33   0212ABA412   mac     acc,c+,(p)-70 ; mem[p]<-acc, acc=0
        ; C-RAM[0x07] (coeff, base 0x00 MEASURED)
  w34   0104200000   post.b  (p)0,(p)+0
  w35   0026200000   ?word   0x0026200000   ; 026.2.00.000  hi12{f31=3 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w36   0880130000   dly.r  dsc[k],p+48
  w37   0000A00415   ld      acc,c+,(p)+0
        ; C-RAM[0x08] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x08] = op0x62[0] (role output-level, INFERRED)
  w38   0212AFF1D5   mac     (p),c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x09] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x09] = op0x62[1] (role output-level, INFERRED)
  w39   0202AFB1D5   mac     (p),c+,(p)-5
        ; C-RAM[0x0A] (coeff, base 0x00 MEASURED)
  w40   0202200000   mac.b   (p)0,(p)+0
  w41   09001601D5   dly.w  dsc[k],p+96
  w42   0192A4D000   mac.b   (p)0,c+,(p)+77 ; store SUPPRESSED (bit7)
        ; C-RAM[0x0B] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0B] = op0x64[0] (role coeff, INFERRED)
  w43   00822001C0   mac.b   (p),(p)+0
  w44   0C4032044C   ldreg   r4C,#25          ; immediate -> the register lo12 selects
  w45   0A00000041   ?word   0x0A00000041   ; A00.0.00.041  hi12{ESC f98=2}  [head of a fixed 3-word template (S-5); operands SRC 0x01/ACT 0x01 dark]
  w46   08801202C7   dly.r  dsc[k],p+32
  w47   0102AB54C8   ?word   0x0102AB54C8   ; 102.A.B5.4C8  hi12{f98=1 f31=1} cur+  [gain multiply (same op in phaser all-pass and reverb diffuser)]
        ; C-RAM[0x0C] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0C] = op0x64[1] (role coeff, INFERRED)
  w48   00002F7000   nop
  w49   002820A1CD   ?word   0x002820A1CD   ; 028.2.0A.1CD  hi12{f31=4 ?5 res=020}  [SPECULATIVE (prospective, not measured): ACT 0x0D = delay/state MIXING: mem onto bus (universal; pair w/ 0x0E)]
  w50   00002FF1CE   ld      (p),(p)-1
  w51   0212202407   mac.st  acc,(p)+2 ; mem[p]<-acc, acc=0
  w52   002A24A000   ?word   0x002A24A000   ; 02A.2.4A.000  hi12{f31=5 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w53   0000A001D5   ld      (p),c+,(p)+0
        ; C-RAM[0x0D] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0D] = damping filter tap 0 (role damping, PROVEN)
  w54   0292A01412   mac     acc,c+,(p)+1 ; store SUPPRESSED (bit7)
        ; C-RAM[0x0E] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0E] = damping filter tap 1 (role damping, PROVEN)
  w55   0282AB51D5   mac     (p),c+,(p)-75
        ; C-RAM[0x0F] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x0F] = damping filter tap 2 (role damping, PROVEN)
  w56   028224B407   mac.st  acc,(p)+75
  w57   00122AF447   ?word   0x00122AF447   ; 012.2.AF.447  hi12{ST f31=1}  [SPECULATIVE (prospective, not measured): SRC 0x11 = ACCB (2nd accumulator)]
  w58   00002521C8   ?word   0x00002521C8   ; 000.2.52.1C8  hi12{-}  [SPECULATIVE (prospective, not measured): ACT 0x08 = table-port multiply]
  w59   00002B81D5   ld      (p),(p)-72
  w60   01022481CD   mac     (p),(p)+72
  w61   0212201412   mac     acc,(p)+1 ; mem[p]<-acc, acc=0
  w62   01042B71D5   post    (p),(p)-73
  w63   01022491CD   mac     (p),(p)+73
  w64   0212AB4412   mac     acc,c+,(p)-76 ; mem[p]<-acc, acc=0
        ; C-RAM[0x10] (coeff, base 0x00 MEASURED)
  w65   0104200000   post.b  (p)0,(p)+0
  w66   0026200000   ?word   0x0026200000   ; 026.2.00.000  hi12{f31=3 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w67   00002FF407   ld.st   acc,(p)-1
  w68   001224E1C0   mac.b   (p),(p)+78 ; mem[p]<-acc, acc=0
  w69   0104A001D5   post    (p),c+,(p)+0
        ; C-RAM[0x11] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x11] = damping filter tap 0 (role damping, PROVEN)
  w70   0292A01412   mac     acc,c+,(p)+1 ; store SUPPRESSED (bit7)
        ; C-RAM[0x12] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x12] = damping filter tap 1 (role damping, PROVEN)
  w71   0282AB11D5   mac     (p),c+,(p)-79
        ; C-RAM[0x13] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x13] = damping filter tap 2 (role damping, PROVEN)
  w72   028224F000   mac.b   (p)0,(p)+79
  w73   00122AB447   ?word   0x00122AB447   ; 012.2.AB.447  hi12{ST f31=1}  [SPECULATIVE (prospective, not measured): SRC 0x11 = ACCB (2nd accumulator)]
  w74   00002561C8   ?word   0x00002561C8   ; 000.2.56.1C8  hi12{-}  [SPECULATIVE (prospective, not measured): ACT 0x08 = table-port multiply]
  w75   00002B41D5   ld      (p),(p)-76
  w76   010224C1CD   mac     (p),(p)+76
  w77   0212201412   mac     acc,(p)+1 ; mem[p]<-acc, acc=0
  w78   01042B31D5   post    (p),(p)-77
  w79   010224D1CD   mac     (p),(p)+77
  w80   0212AB0412   mac     acc,c+,(p)-80 ; mem[p]<-acc, acc=0
        ; C-RAM[0x14] (coeff, base 0x00 MEASURED)
  w81   0104200000   post.b  (p)0,(p)+0
  w82   0026200000   ?word   0x0026200000   ; 026.2.00.000  hi12{f31=3 ?5 res=020}  [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
  w83   0000A00415   ld      acc,c+,(p)+0
        ; C-RAM[0x15] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x15] = op0x62[2] (role output-level, INFERRED)
  w84   0212AFF1D5   mac     (p),c+,(p)-1 ; mem[p]<-acc, acc=0
        ; C-RAM[0x16] (coeff, base 0x00 MEASURED)
        ; coeff C-RAM[0x16] = op0x62[3] (role output-level, INFERRED)
  w85   0202AFC1D5   mac     (p),c+,(p)-4
        ; C-RAM[0x17] (coeff, base 0x00 MEASURED)
  w86   0202200000   mac.b   (p)0,(p)+0
  w87   09001601D5   dly.w  dsc[k],p+96
  w88   0192A56000   mac.b   (p)0,c+,(p)+86 ; store SUPPRESSED (bit7)
        ; C-RAM[0x18] (coeff, base 0x00 MEASURED)
  w89   00822001C0   mac.b   (p),(p)+0
  w90   0C4032044C   ldreg   r4C,#25          ; immediate -> the register lo12 selects
  w91   0A00000041   ?word   0x0A00000041   ; A00.0.00.041  hi12{ESC f98=2}  [head of a fixed 3-word template (S-5); operands SRC 0x01/ACT 0x01 dark]
  w92   08801202C7   dly.r  dsc[k],p+32
  w93   0102A9D4C8   ?word   0x0102A9D4C8   ; 102.A.9D.4C8  hi12{f98=1 f31=1} cur+  [gain multiply (same op in phaser all-pass and reverb diffuser)]
        ; C-RAM[0x19] (coeff, base 0x00 MEASURED)
  w94   0000200000   nop
  w95   0000200000   nop
  w96   0000200000   nop
  w97   0880160000   dly.w  dsc[k],p+96
  w98   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 enh_hle = (dsphle == 0x10);
	int    enh_dN = 0; double enh_hi = 0.0, enh_wet = 0.0;
	if (enh_hle)
	{
		enh_dN  = std::clamp(int(double(m_dsp1->cram_read(0x0B) & 0xffffff) * x_cs * sr48 + 0.5), 1, 34999);
		enh_hi  = std::clamp(0.5 + 2.0 * std::fabs(q22x(m_dsp1->cram_read(0x09)) * x_cs), 0.5, 3.0);  // HIGH MIX boost
		enh_wet = 0.25;                                           // modest slap blend (DELAY is the anchor)
		m_enh_lp_l.set_damping(0.64); m_enh_lp_r.set_damping(0.64);
		m_enh_ap_l.set_a(0.6); m_enh_ap_r.set_a(0.6);
	}

Per-sample insert (the reconstructed signal path):

		if (enh_hle)   // ENHANCER: high-shelf emphasis + all-pass phase + decoded ~350 ms slap
		{
			const double xl = double(mix_l) / 32768.0, xr = double(mix_r) / 32768.0;
			const double ehl = xl + (enh_hi - 1.0) * (xl - m_enh_lp_l.process_one(xl));
			const double ehr = xr + (enh_hi - 1.0) * (xr - m_enh_lp_r.process_one(xr));
			const double phl = m_enh_ap_l.process_one(ehl), phr = m_enh_ap_r.process_one(ehr);
			const double dl = m_enh_l.read(double(enh_dN)), dr = m_enh_r.read(double(enh_dN));
			m_enh_l.write(phl); m_enh_r.write(phr);
			mix_l = int32_t(std::clamp(phl + enh_wet * dl, -1.0, 1.0) * 32767.0);
			mix_r = int32_t(std::clamp(phr + enh_wet * dr, -1.0, 1.0) * 32767.0);
		}