From 57449ec55e03c7a8a532a9bcec4e6abd20be3259 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 14 Sep 2026 12:28:13 +0300 Subject: [PATCH] Keep raster display stable during I/O --- _sd/README.md | 4 +- _sd/zc_sd_driver.asm | 41 ++--- _spg/ZIFI/zifi.spg | Bin 44544 -> 44544 bytes includes.asm | 12 +- zifi.asm | 378 ++++++++++++++++++++++++++++++------------- 5 files changed, 291 insertions(+), 144 deletions(-) diff --git a/_sd/README.md b/_sd/README.md index 592ed24..80e507b 100644 --- a/_sd/README.md +++ b/_sd/README.md @@ -7,7 +7,9 @@ ## Файлы - `zc_sd_driver.asm` — резидентная часть: таблица переходов CORE, - di/ei-обёртки над каждой точкой входа, распаковщик тела. + сохранение IX в точках входа и распаковщик тела. Длинные рабочие операции + оставляют растровые прерывания включёнными; конфликтующие задачи ZiFi + блокируются снаружи через `init_sd_card`/`sd_exit`. - `zc_sd_driver_body.asm` — основная логика: SPI/SD-протокол, DMA, разбор FAT32 (BPB, цепочки кластеров, FAT), поиск по имени с LFN, создание/удаление файлов и каталогов. Хранится в сжатом виде и diff --git a/_sd/zc_sd_driver.asm b/_sd/zc_sd_driver.asm index 8926de6..bc0108a 100644 --- a/_sd/zc_sd_driver.asm +++ b/_sd/zc_sd_driver.asm @@ -216,59 +216,46 @@ wrap_save512 push ix call core_save512 pop ix ret -wrap_mkfile di - push ix +; Runtime filesystem calls are already bracketed by zifi.asm's +; init_sd_card/sd_exit. That disables every IRQ job which can repage CPU +; slots or touch DMA, while leaving the raster interrupts themselves alive. +; Keeping DI across FAT scans and card busy waits skipped the text-mode raster +; lines and produced full-height bands / flashes of the backing splash. +wrap_mkfile push ix call core_mkfile pop ix - ei ret -wrap_mkdir di - push ix +wrap_mkdir push ix call core_mkdir pop ix - ei ret -wrap_fentry di - push ix +wrap_fentry push ix call drv_fentry pop ix - ei ret -wrap_loadnon di - push ix +wrap_loadnon push ix call drv_loadnon pop ix - ei ret -wrap_setdir di - push ix +wrap_setdir push ix call core_setdir pop ix - ei ret -wrap_setroot di - push ix +wrap_setroot push ix call core_setroot pop ix - ei ret -wrap_seek0 di - push ix +wrap_seek0 push ix call stream_open pop ix - ei ret -wrap_delfl di - push ix +wrap_delfl push ix call core_delfl pop ix - ei ret -wrap_renam di - push ix +wrap_renam push ix call core_renam pop ix - ei ret ; DOS_SWP now does real work (depacking the body -- see drv_dos_swp ; below), unlike every other entry here it previously had NO di/ei diff --git a/_spg/ZIFI/zifi.spg b/_spg/ZIFI/zifi.spg index a543b7d8dc6d9886445cd45bd178007322458881..5b05450e6e22a5cc6a61cd3af5311d86eaa11a4e 100644 GIT binary patch delta 11519 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 delta 11623 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