156 lines
10 KiB
Markdown
156 lines
10 KiB
Markdown
# BLOCK MAP: FUN_180529fe0 (полная разметка по raw asm, 22v)
|
||
|
||
Источник: `handoff/nls_dasm/f529fe0_full.dis` (soothe_mem.bin, база 0x180000000,
|
||
диапазон 529c60–52ba00; старый f529fe0.dis был ОБРЕЗАН на 52a813).
|
||
Регистры: r13 = индекс полосы, r12 = state-ptr ctx+0x440518, esi/r8d = nbin,
|
||
rbx = nbands ([rsp+0x30]), rdi = ctx. Флаг 0x5408b8 выбирает float/double
|
||
вариант thunk-операций (семантика пар идентична).
|
||
|
||
## Исправление адресации (главное)
|
||
«Скалярные» буферы NOTES 21b — МАССИВЫ пер-полосных векторов (шаг 16 байт):
|
||
- bands[i] = [ctx+0x540678+i·16] — кривые полос
|
||
- acc[i] = [ctx+0x5407c8+i·16] — ПЕР-ПОЛОСНЫЙ аккумулятор combine
|
||
- track[i] = [ctx+0x540768+i·16] — трек основного цикла
|
||
|
||
## Thunk-таблица (ILT-стаб 180001xxx -> jmp [table + idx*8], idx @1826159a0)
|
||
Резолв при live idx=4; семантика из тел + NOTES 21b:
|
||
| стаб float | стаб double | impl | op |
|
||
|---|---|---|---|
|
||
| 0x180001f10 | 0x180001c70 | dc40 / **8d60** | dst = B − A (sub) |
|
||
| 0x180001fa0 | 0x180001940 | ee20→487a0 / **3c40** | fma att/rel половин |
|
||
| 0x180001d60 | —(встречен в 1b80-паре?) | — / **5a20** | dst += B (add) |
|
||
| 0x180001970 | — | **3f40** | sub (float) |
|
||
| 0x1800019a0 | — | **4200** | mul scalar? (делегирует 181a63fe0) |
|
||
| 0x180001a00 | — | **4720** | mul |
|
||
| 0x180001a60 | — | **5160** | sub DOUBLE |
|
||
| 0x180001850 | — | **25e0** | add DOUBLE |
|
||
| 0x180002000 | 0x180001c40 | ? | axpy-класс (band ⊕ track) |
|
||
| 0x180002060 | 0x180002120 | 10860/11940 | transform со скаляром xmm3 |
|
||
| 0x180002270 | 0x1800022a0 | 14c40/15060 | transform со скаляром xmm0/xmm1 |
|
||
| 0x180002030 | 0x180001d30 | ? | transform float/double |
|
||
| in-place кернелы | | 140950/140980/1409b0/1409e0/140a40/140ad0/140b00/140b60 | bigkernel-семейство (exp2/mask) |
|
||
|
||
## Карта блоков
|
||
|
||
### Пролог
|
||
- `52a03a–52a396`: PRNG-пролог. LCG state @ctx+0x2404e0, шаги +0x3cdca,
|
||
+0x140236, +0x10d56, +0xdf6b6, +0xa8c5e, +0x72916; LUT ptr @ctx+0x5408b0;
|
||
константы 262b704/262b5c8(int)/262b700(int)/24c3c58. Результат: индексы
|
||
iVar7/iVar8 ([rsp+0x130]/счётчики) и стартовая позиция цикла.
|
||
Live-поведение залочено раньше (fVar30=1).
|
||
- `52a397`: r14 = &bands[0].
|
||
|
||
### Pre-combine #1 (52a397–52a421)
|
||
- `52dbc0(f6f8_data, bands[0], nbin)` — copy bands[0] → f6f8.
|
||
- цикл i=1..nbands−1 по массиву @0x540688 (= &bands[1]!): transform(f6f8, bands[i])
|
||
через 20f0(float)/1850(double=25e0 ADD). ⇒ **f6f8 = Σ_{i≥1} bands[i]** (или min/max
|
||
— точный op 20f0 не залочен, кандидат ADD по double-паре!).
|
||
|
||
### Нормировка + mix-вес (52a421–52a458)
|
||
- `52d920(f6f8, xmm11/[rsp+0x148](int), nbin)` — f6f8 /= K.
|
||
- `xmm7 = powf([ctx+0x2c], xmm13)` — mix^p.
|
||
|
||
### Pre-combine #2 (52a45e–52a4f6) по всем полосам
|
||
- band[i] *= (xmm11 − xmm7) [thunk 2030/1d30]
|
||
- f6f8 ⊕= ... с весом xmm7 [thunk 1fd0/2150]
|
||
⇒ взвешенное смешение кривых полос ДО основного цикла.
|
||
|
||
### Основной цикл по полосам (52a4fb..52b3c7, тело с 52a580)
|
||
На каждую полосу i (r13):
|
||
1. `scale` (52a583–52a5c4): s = xmm11·[0x540870]; если флаг 0x5408b8:
|
||
s ← exp(PRNG)-ветка; затем ·[0x54088c]. Читается track_i (@0x540768[i]) в [rsp+0x40].
|
||
2. `transform(bands[i], s)` (52a5cc–52a607): bands[i] *= s [2030/1d30].
|
||
3. флаг-оп (52a608–52a645): transform(bands[i], bands[i]) через 140980/1409b0
|
||
(bigkernel, вероятно exp2-кернел) — только при флаге.
|
||
4. `52d650(state@0x440518, f6f8, bands[i], nbin)` (52a646–52a658) — БИДИР-IIR #1:
|
||
band → f6f8 (double, коэф down@0x440528/up@0x4c0528, acc@0x540528, reset внутри).
|
||
5. Инлайн БИДИР-IIR #2 (52a65d–52a85a, только при флаге; иначе прыжок на 6):
|
||
вход f6f8 → выход bands[i] (тот же state 0x440518, reset отдельно).
|
||
6. `transform(f6f8 ⊕ bands[i])` (52a85b–52a896) [1970/1a60 = 3f40 SUB float /
|
||
5160 SUB double]: f6f8 −= bands[i]? (аргументы rcx=f6f8, rdx=band).
|
||
7. **БИДИР-IIR #3** (52a897–52aa6e, инлайн): state base 0x3404f8
|
||
(down@0x2404f8, up@0x2c04f8, acc@0x3404f8), длина из поля ctx+0x2404e8,
|
||
IN-PLACE по bands[i]. Reset каждый вызов.
|
||
8. `op(bands[i], скаляр xmm9=0?)` (52aa6e–52aaaf) [2060/2120].
|
||
9. Ветка флага==0 (52aabc–52ab90):
|
||
- op(vec@0x540698, f6f8, scalar=(конст1 − [0x54087c])) [1a00/1be0 = mul]
|
||
- op(f6f8, scalar=[0x54087c]·xmm10) [2270/22a0]
|
||
- bigkernel `140b60/140950(bands[i], f6f8, bands[i], nbin)`
|
||
10. **COMBINE (52ab90–52abd7)**: acc_i = [0x5407c8+i·16];
|
||
`op(rcx=acc_i, rdx=bands[i], r8=f6f8, r9=nbin)` [1f10→dc40 float-SUB /
|
||
1c70→8d60 double-SUB]: **f6f8 = bands[i] − acc_i** ✓ NOTES 21b.
|
||
11. Половины f6f8 + fma (52abd7–52ad04):
|
||
- rbp = f6f8 + nbin (верхняя половина); op(f6f8_low?, ...) [2060/2120, scalar 0]
|
||
- op(rcx=f6f8_upper, rdx=vec@0x5406c8, r8=acc_i) [1fa0/1940 = **3c40 fma**]
|
||
- op(rcx=f6f8_lower, rdx=vec@0x5406e8, r8=acc_i) [1fa0/1940]
|
||
⇒ fma с коэф-массивами 0x5406c8 (upper/att) и 0x5406e8 (lower/rel) ✓.
|
||
12. `acc_i += bands[i]` (52acf4–52ad03) [1b80→6840 / 1d60→**5a20** add] ✓.
|
||
13. Ветка флага!=0 (52ad04–52ae57): повтор п.9 с теми же адресами
|
||
(0x540698, f6f8-blend, bigkernel 1409e0/140ad0).
|
||
14. `op(bands[i], скаляры 0x1824c4680 / xmm13)` (52ae58–52ae56 хвост).
|
||
15. `bands[i] ⊕= track_i [rsp+0x40]` (52ae74–52ae8a) [2000/1c40].
|
||
16. `op(vec@0x5406a8, bands[i])` (52ae8f–52aecа) [2000/1c40].
|
||
17. флаг → bigkernel in-place 140980/1409b0 (52aecb–52af08).
|
||
18. **БИДИР-IIR #4 ×2** (52af09–52b2af и повтор 52b0de–52b2af):
|
||
state base 0x440510 (down@0x340510, up@0x3c0510, acc@0x440510),
|
||
длина ctx+0x340500, in-place bands[i]. ДВА прохода подряд (каждый с reset).
|
||
19. Финальные scale/op полосы (52b2af–52b3af):
|
||
- скаляр `[ctx+0x1c+i·4] · xmm14` → transform [2030/1d30]
|
||
- bigkernel in-place 1409e0/140ad0 (при флаге) ИЛИ
|
||
op(scalar=xmm12/xmm8) [2270/22a0] + `140a40/140b00(band,band,scalar)`
|
||
20. Инкремент i (52b3af–52b3c7), выход при i ≥ nbands.
|
||
|
||
### Эпилог (52b3cd–52b935)
|
||
- GUI-snapshot блок (флаг 0x2404bc): копии векторов @0x540728 ← bands[i]
|
||
(совпадает с consumers_out.txt:144-183).
|
||
- Остаток до 52b935: восстановить при транскрипции (вероятно dry/wet + mirror).
|
||
|
||
## Состояния бидир-IIR (4 базы, лейаут {down,+0x80000 up,+0x80010/+0x100010 acc})
|
||
| # | база | downCoef | upCoef | acc | длина |
|
||
|---|------|----------|--------|-----|-------|
|
||
| 1–2 (52d650+инлайн) | 0x440518 | +0x10 | +0x80010 | +0x100010 | nbin |
|
||
| 3 | 0x2c04f8-группа | 0x2404f8 | 0x2c04f8 | 0x3404f8 | поле ctx+0x2404e8 |
|
||
| 4 ×2 | 0x340510/0x3c0510 | 0x340510 | 0x3c0510 | 0x440510 | поле ctx+0x340500 |
|
||
|
||
## Открытые вопросы к транскрипции
|
||
1. Точный op thunk 20f0/1850 в pre-combine #1 (ADD — кандидат).
|
||
2. Аргументный порядок 2000/1c40 (axpy) и 2060/2120.
|
||
3. Семантика bigkernel-семейства 1409xx/140axx/140bxx (какой где: exp2(-x),
|
||
exp2(-x)·blend, mirror?).
|
||
4. Что пишется в track_i @0x540768[i] (writer вне метода — искать отдельной охотой;
|
||
кандидат FUN_18052e9b0).
|
||
5. Эпилог 52b4eb–52b935.
|
||
|
||
## ДОПОЛНЕНИЕ 22v: декод генератора коэффициентов
|
||
|
||
### FUN_180530b60 (апдейт параметров, size=462)
|
||
- fVar2 = powf([ctx+0x540878], K1); fVar3 = powf([ctx+0x54087c], K2)
|
||
(оба live = 0.5 — параметры attack/release-класса);
|
||
- лог-интерполяция констант → [ctx+0x540894] и [ctx+0x540898] (тау-скаляры);
|
||
- вызовы генератора на все три состояния:
|
||
- 180533340(ctx+0x2404e8, tau=0x540894-ветка, C=DAT_1824c459c, sr, ...)
|
||
- 180533340(ctx+0x340500, tau=[0x540894], ...)
|
||
- 180533340(ctx+0x440518, tau=[0x540898], ..., mult=DAT_1824c4564)
|
||
|
||
### FUN_180533340(state, tau, C, sr, p, mult) — ГЕНЕРАТОР КОЭФ. БИДИР-IIR
|
||
```
|
||
sr' = sr · DAT_1824c3d8c
|
||
acc = 0; downCoef[0] = 1.0 (int-пара {0, 0x3ff00000} @+0x10)
|
||
n = state[0]; fc_norm = (C/sr')·n
|
||
for i in 1..n-1:
|
||
g = (i <= fc_norm) ? fc_norm/i : powf(fc_norm/i, p) # частотный варп!
|
||
c = 1/(g·tau/mult + 1)
|
||
up[i] = exp(c·g·tau/state[2] · DAT_1824c46b8)
|
||
down[i] = 1 − up[i]
|
||
```
|
||
ЛЕЙАУТ СОСТОЯНИЯ СОШЁССЯ: downCoef[] @base+0x10, upCoef[] @base+0x80010
|
||
(pdVar6[0x10000] = +0x80000 байт), acc — скаляр в хвосте. Это ЧАСТОТНО-
|
||
ЗАВИСИМОЕ сглаживание маски: сила растёт к низким бинам (1/i) с питч-законом
|
||
выше кросса. Вот где «размазывание» нотча в реале — НЕ плоский IIR, который
|
||
мы отвергли офлайн (22u), а пер-биновый варп!
|
||
|
||
### Статус сбора (решение: без коммитов до первой валидации)
|
||
Незакоммичено: f529fe0_full.dis, BLOCKMAP_529fe0.md, thunk-резолвер,
|
||
правки NOTES_LEVEL (22v будет добавлена при транскрипции). Следующий шаг —
|
||
транскрипция process_frame_faithful по этой карте.
|