Фикс: чтение файлов нельзя выносить в банк — банковый код сам живёт в W3
Первый запуск после разгрузки встал в halt по мусору в 0xC40E. Причина: pop_level_read_file и pop_kid_data_load маппят страницу данных в W3 на время read() (файл читается по 0xC000), а модули банка исполняются ИЗ ЭТОГО ЖЕ окна — после sprinter_page_w3() следующая инструкция приходит уже из чужой страницы. Обе функции вернулись в резидент; в банке остался код, который ходит через W0 (gfx_w0_map) или окон не трогает вовсе. Правило записано в _pop_level.h и _pop_kid.h: банковый модуль НЕ маппит W3 (через W0 — можно). Поэтому же в резиденте живёт весь libbgi. Куча 6095 Б (было 902 до разгрузки). Проверено в MAME: игра стартует, комната рисуется, Кид управляем. tests-host 6/6.
This commit is contained in:
@@ -48,40 +48,9 @@ void pop_kid_free(void) __banked
|
||||
kid_npages = 0;
|
||||
}
|
||||
|
||||
/* Таблица кадров (241*5 Б) и seqtbl (2310 Б) занимали 3.5 КБ в _CODE окна
|
||||
* W1/W2 — самый дефицитный ресурс. Теперь они лежат в отдельной EMM-
|
||||
* странице, которая маппится в W0 РОВНО на время play_seq (раз за тик).
|
||||
* Страница адресуется как у pop_level: данные с 0x100, ниже — ISR-стаб. */
|
||||
int pop_kid_data_load(const char *path) __banked
|
||||
{
|
||||
uint8_t *pg = (uint8_t *)0xC000; /* страница мапится в W3 на время чтения */
|
||||
uint8_t saved_w3, blk;
|
||||
uint16_t stub;
|
||||
int fd, n;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) return -1;
|
||||
blk = mem_alloc_pages(1);
|
||||
if (!blk) { close(fd); return -1; }
|
||||
kdat_blk = blk;
|
||||
kdat_page = mem_get_page(blk, 0);
|
||||
|
||||
saved_w3 = _io_page_w3;
|
||||
sprinter_page_w3(kdat_page);
|
||||
n = read(fd, pg + KD_DATA_OFF, 16384 - KD_DATA_OFF);
|
||||
if (n >= (int)(KID_BIN_SEQTBL_OFF + KID_SEQTBL_LEN)) {
|
||||
stub = (uint16_t)&_gfx_w0_isr; /* ISR-стаб W0-страницы (как pop_level) */
|
||||
pg[0x38] = 0xC3;
|
||||
pg[0x39] = (uint8_t)(stub & 0xFF);
|
||||
pg[0x3A] = (uint8_t)(stub >> 8);
|
||||
pg[0x66] = 0xED; pg[0x67] = 0x45; /* RETN */
|
||||
}
|
||||
sprinter_page_w3(saved_w3);
|
||||
close(fd);
|
||||
if (n < (int)(KID_BIN_SEQTBL_OFF + KID_SEQTBL_LEN)) { mem_free_block(blk); return -1; }
|
||||
kdat_ok = 1;
|
||||
return 0;
|
||||
}
|
||||
/* ЗАГРУЗКА kid_data.bin (pop_kid_data_load) осталась в РЕЗИДЕНТЕ: она
|
||||
* маппит страницу в W3 на время чтения, а этот модуль сам в W3 — см.
|
||||
* то же правило в _pop_kid.h. */
|
||||
|
||||
void pop_kid_data_free(void) __banked
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user