Files

92 lines
6.3 KiB
Markdown
Raw Permalink 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.
# zc_sd_driver
Открытый SD/FAT32-драйвер для ZiFi, замена закрытого `WDFCVBI2.COD`.
Реализует ту же CORE-таблицу (`CORE equ #2002` в `zifi.asm`), что и
оригинальный драйвер, но с открытыми исходниками.
## Файлы
- `zc_sd_driver.asm` — резидентная часть: таблица переходов CORE,
сохранение IX в точках входа и распаковщик тела. Длинные рабочие операции
оставляют растровые прерывания включёнными; конфликтующие задачи ZiFi
блокируются снаружи через `init_sd_card`/`sd_exit`.
- `zc_sd_driver_body.asm` — основная логика: SPI/SD-протокол, DMA,
разбор FAT32 (BPB, цепочки кластеров, FAT), поиск по имени с LFN,
создание/удаление файлов и каталогов. Хранится в сжатом виде и
распаковывается в резидентную часть во время выполнения `DOS_SWP`.
- `body_syms.inc` — адреса функций/переменных тела, сгенерированные
из символьной таблицы сборки `zc_sd_driver_body.asm`, подключаются
в `zc_sd_driver.asm` как константы.
## Реализованные функции CORE
`DEV_INI`, `HDD`, `LOAD512`, `SAVE512`, `DOS_SWP`, `MKFILE`, `MKDIR`,
`DELFL`, `RENAME`, `FENTRY`, `LOADNON`, `NXTETY`, `SETDIR`, `SETROOT`,
`SEEK0`. Остальные точки входа таблицы — заглушки (не используются
ZiFi).
## Что реализовано сверх голого CORE ABI
- **MBR/раздел**: автоматически определяет, есть ли на карте
партиция (тип `0x0B`/`0x0C`), или BPB лежит прямо в LBA0; смещение
партиции (`ADDTOP`) прибавляется ко всем последующим LBA.
- **SDSC/SDHC/SDXC**: сама определяет байтовую или блочную адресацию
по биту CCS из CMD8/ACMD41/CMD58, а не считает её заранее известной.
- **Защита от выхода за границу LBA**: перед любым чтением сверяет
номер сектора с реальным размером тома (посчитанным из BPB) —
ошибка в арифметике не уйдёт в CMD17/25 как заведомо неверный адрес.
- **Проверка BPB/FAT32**: сигнатура `55 AA`, `BytesPerSector==512`,
`FATSz16==0`, `RootEntryCount==0`, `SectorsPerCluster` — степень
двойки, прежде чем доверять остальным полям.
- **Зеркалирование FAT**: запись FAT-записи дублируется во все копии
(`NumFATs`), не только в первую.
- **Поиск свободного кластера**: сессионный кэш "куда искать дальше"
плюс чтение/запись `FSInfo`-подсказки (`FSI_Nxt_Free`) — не
пересканирует FAT с кластера 2 при каждой аллокации на разделах с
большим количеством уже занятых кластеров.
- **Длинные имена (LFN)**: генерация уникального короткого имени 8.3
с суффиксом `~N` при коллизии, полноценные LFN-записи для
MKFILE/MKDIR.
- **Дата/время создания**: читает реальные RTC (DS1685-совместимые,
порты `#EFF7`/`#DFF7`/`#BFF7`) и проставляет их в создаваемые
записи каталога вместо фиксированной заглушки.
- **Многокластерные файлы/каталоги**: потоковое чтение и запись
(`stream_open`/`stream_read_sector`/`stream_write_sector`) следует
цепочке FAT и доращивает её по мере необходимости — не ограничено
одним кластером.
## Адресация
Драйвер загружается в физическую страницу `#0F`, отображается в CPU
слот 0 (`#0000-#3FFF`). `CORE` (`#2002`) — фиксированный адрес внутри
этого слота. Резидентная часть собирается с `ORG #2000`; тело
распаковывается в адреса `#0000..body_end` той же страницы —
`body_end` обязан оставаться в пределах `#2002` (граница проверяется
на этапе сборки).
`LOAD512`/`SAVE512` используют прямой DMA между SD-картой и указанной
вызывающим физической страницей/смещением, не затрагивая пейджинг
CPU.
## Сборка
```
cd _sd
sjasmplus.exe zc_sd_driver_body.asm --sym=body_syms_new.txt
# зачем: --sym выгружает адреса ВСЕХ меток тела (включая DATA/CONF --
# служебные метки портов ввода-вывода), а zc_sd_driver.asm уже сам
# объявляет DATA/CONF как константы -- если подключить дамп как есть,
# получим "Duplicate label: DATA"/"Duplicate label: CONF". Поэтому
# перед тем как класть файл в body_syms.inc, эти две строки убираются:
grep -v -E "^(DATA|CONF): EQU" body_syms_new.txt > body_syms.inc
# упаковать zc_sd_driver_body.bin -> zc_sd_driver_body.pb (PackBits;
# любым PackBits-кодировщиком с раунд-трип проверкой -- контрольный
# байт C: C=128 конец, C<128 литерал C+1 байт, C>128 повтор (257-C) раз)
sjasmplus.exe zc_sd_driver.asm
```
Результат (`zc_sd_driver.bin`) копируется в `_spg/` и подключается
через `_spg/spgbld.ini` (`Block = #e000, #0f, zc_sd_driver.bin`).