Files
Sprinter-SDCC/libc/mem/bank_read_page.c
T
snark13 ba3aca07bf Архивы ресурсов PBA1: звук одним файлом, музыка потоком; ALLOCS 6000
ЗАМЕР, из которого всё выросло (MAME, 2026-08-25): `open` стоит 51,4 мс,
а чтение 16 КБ из уже открытого файла — 32,6 мс.  То есть 61 % времени
загрузки уходит на ОТКРЫТИЕ, а не на данные, и чистая скорость чтения —
491 КБ/с, а не 260.  На диске игры 343 файла; одна только стартовая пачка
(kid+shadow+bg+sound+guard, ~142 файла) — это 7,3 секунды чистого open.

* toolchain/pop_pack_arc.py + pop_arc.c/h (банк 8) — формат PBA1:
  заголовок 512 Б, магия, count, записи по 4 байта (offset в СЕКТОРАХ —
  архив бывает больше 64 КБ; size в байтах — ресурс всегда <= 16 КБ,
  он обязан лезть в EMM-страницу).  Таблицу держит вызывающий на своём
  стеке: в W2 её класть нельзя, а стека в точке загрузки израсходовано
  75 байт из 1279 (замер там же).
* libc: bank_read_page — чтение из УЖЕ ОТКРЫТОГО файла в EMM-страницу.
  bank_load_file переписана через неё, поэтому дублирования работы с W3
  не осталось и резидент почти не вырос.
* Набор эффектов: 10 файлов -> SND\snd.arc, один open вместо десяти.
* Музыка: трек лежит ОДНИМ файлом и читается порциями по странице —
  нарезка на куски больше не нужна.  Этот же путь понадобится финалу
  `won` (1,2 МБ), который в память целиком не влезает.
* Менеджер звука приведён к оригиналу: играющая музыка участвует в
  таблицах приоритета наравне с эффектами (seg000:1672 + data.h:433).
  Почти вся музыка НЕперебиваема, поэтому поверх неё эффект не стартует —
  ровно как в SDLPoP; раньше эффект её перебивал.
* ALLOCS 3000 -> 6000 (решение пользователя): сборка +20 с, резидент
  -161 байт.  Куча 87 -> 248 Б.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 17:13:25 +03:00

36 lines
1.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* bank_read_page — прочитать из УЖЕ ОТКРЫТОГО файла прямо в EMM-страницу.
*
* Зачем отдельно от bank_load_file: та открывает и закрывает файл на каждый
* вызов, а `open` на Sprinter стоит дорого — замер в MAME (PoP, 2026-08-25):
* open 51,4 мс против 32,6 мс на чтение 16 КБ, то есть 61 % времени уходит
* на открытие. Кто читает из одного файла несколько кусков (архив ресурсов,
* поток музыки), обязан держать fd открытым — тогда эта цена платится раз.
*
* ESTEX принимает файловый буфер только в W1..W3; используем W3, сохраняя и
* восстанавливая раскладку. Функция резидентна, поэтому её безопасно
* вызывать из банкового кода huge: пока W3 занят целевой страницей, никакой
* памяти вызывающего мы не читаем. Позицию в файле вызывающий ставит сам
* (lseek) — здесь только перенос.
*
* Возврат: фактически прочитанный размер либо -1 + errno.
*/
#include <unistd.h>
#include <errno.h>
#include <sprinter.h>
#include <sprinter_mem.h>
int bank_read_page(int fd, uint8_t phys_page, uint16_t off, uint16_t size)
{
uint8_t saved;
int n;
if (off > 0x3FFFu || size > (uint16_t)(0x4000u - off)) {
errno = EINVAL; return -1;
}
saved = _io_page_w3;
sprinter_page_w3(phys_page);
n = read(fd, (void *)(0xC000u + off), size);
sprinter_page_w3(saved);
return n;
}