Files
Sprinter-SDCC/libc/cbl/cbl_close.c
T
snark13 8458ec65f4 libc/cbl: две точки входа вместо underrun_mode — malloc больше не в резиденте
Линкер тянет .rel целиком, поэтому malloc/free, стоявшие в мёртвой ветке
CBL_UNDERRUN_SILENCE внутри cbl_open, приезжали в резидент КАЖДОМУ
приложению — включая те, что льют тишину сами и кучей не пользуются.

Разведено:
  cbl_open(freq, fmt, pump, fill)          — ничего не аллоцирует;
  cbl_open_silence(freq, fmt, pump, fill)  — аллоцирует буфер тишины;
  _cbl_open_raw(...)                       — общее тело.
Параметр underrun_mode из публичного API убран: режим задаёт выбор функции.

cbl_close больше не зовёт free — иначе malloc возвращался бы тем же путём.
Буфер тишины живёт до выхода из программы и переиспользуется; его размер
запоминается, иначе открытие 16-бит после 8-бит писало бы memset'ом мимо
выделенного куска.  _cbl_open_raw указатель на буфер не трогает вовсе —
иначе cbl_open после cbl_open_silence терял бы уже выделенную память.

В дереве режим SILENCE не использовал никто: все три вызова (cblwav,
cblstream, PoP) передавали CBL_UNDERRUN_APP.

Итог для PoP: _CODE 24329 -> 23716 (−613 Б), свободно в резиденте 129 ->
747 Б.  make size-check чистый (67 программ), звук в MAME проверен —
насос отработал 696 запросов, pop_snd_ok/want = 1/1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 21:53:08 +03:00

28 lines
1.2 KiB
C

/*
* cbl_close — выключить CBL, снять хук насоса и отпустить IM2-таблицу.
* Идемпотентно; вызывается и из atexit.
*
* БУФЕР ТИШИНЫ НЕ ОСВОБОЖДАЕТСЯ. Раньше здесь стоял free(_cbl_silence), и
* он один тянул malloc/free в резидент КАЖДОМУ приложению — включая те, что
* cbl_open_silence() не зовут вовсе. Буфер живёт до выхода из программы и
* переиспользуется при повторном открытии (см. cbl_open_silence.c).
*
* Порт 0x004E не гасится напрямую — вместо этого _cbl_port_sync()
* пересчитывает нужное значение: если gfx_wait_vsync() ещё держит
* ссылку (_cbl_port_refs > 0), останется "немой" режим ради бита
* синхронизации; иначе порт гасится полностью.
*/
#include "_cbl.h"
#include "../irq/_irq.h"
void cbl_close(void)
{
if (!_irq_cbl_hook) return;
IRQ_DISABLE();
_irq_cbl_hook = 0;
IRQ_ENABLE();
_cbl_port_sync();
_irq_table_unref();
}