Volkov: добавить Sprinter Commander

Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
2026-09-10 10:45:30 +03:00
parent 05bcd8197e
commit 8e389c03f8
870 changed files with 21310 additions and 25 deletions
+4 -3
View File
@@ -1,9 +1,10 @@
/*
* fcntl.h — open / creat for Sprinter ESTEX.
*
* POSIX-style flag bits. The low two bits select access mode (matches
* POSIX numbering — RDONLY=0, WRONLY=1, RDWR=2 — and is translated to
* the ESTEX OPEN $11 convention inside open()).
* Флаги унаследованы от исторического Sprinter C API: младшие биты задают
* RDONLY=2, WRONLY=1, RDWR=3 (это НЕ POSIX-нумерация). open() переводит их
* в соглашение ESTEX OPEN $11; нулевой access mode принимается как RDONLY
* для совместимости с кодом, ожидающим POSIX O_RDONLY=0.
*
* The other flags map onto ESTEX calls like this:
* O_CREAT + O_EXCL → $0B (CREATE_NEW, fails if exists)
+5 -4
View File
@@ -117,11 +117,12 @@ void bank_write(uint8_t phys_page, uint16_t off, const void *src, uint16_t n)
int bank_load_file(uint8_t phys_page, uint16_t off, const char *path,
uint16_t max_size);
/* То же, но из УЖЕ ОТКРЫТОГО файла и с текущей позиции (её ставит вызывающий
* через lseek). Нужна тем, кто читает из одного файла много кусков: `open`
* стоит дороже самого чтения (замер: 51,4 мс против 32,6 мс на 16 КБ), и
* держать fd открытым — единственный способ эту цену не платить. */
/* Обмен с УЖЕ ОТКРЫТЫМ файлом и его текущей позицией (её ставит вызывающий
* через lseek). `open` стоит дороже самого чтения (замер: 51,4 мс против
* 32,6 мс на 16 КБ), а явное владение fd позволяет построить потоковый
* copy-job с собственной политикой create/temp/rename. */
int bank_read_page(int fd, uint8_t phys_page, uint16_t off, uint16_t size);
int bank_write_page(int fd, uint8_t phys_page, uint16_t off, uint16_t size);
int bank_save_file(uint8_t phys_page, uint16_t off, const char *path,
uint16_t size);
+14 -7
View File
@@ -27,16 +27,23 @@ static int _estex_open_raw(const char *path, int posix_mode) __naked
(void)path; (void)posix_mode;
__asm
push ix
;; HL = путь, DE = posix_mode. Перевести в нумерацию ESTEX.
;; HL = путь, DE = flags. Низкие биты libc: W=1, R=2, RW=3;
;; ESTEX: RW=0, R=1, W=2. flags=0 оставляем совместимым с R.
ld a, e
and a, #0x03
ld c, #1
or a, a
jr Z, _oopen_real
ld c, #2
dec a
jr Z, _oopen_real
ld c, #0
or a, a
jr Z, _oopen_read
cp a, #1
jr Z, _oopen_write
cp a, #2
jr Z, _oopen_read
jr _oopen_real ; 3 = read/write
_oopen_read:
ld c, #1
jr _oopen_real
_oopen_write:
ld c, #2
_oopen_real:
ld a, c
ld c, #0x11 ; ESTEX OPEN
+32
View File
@@ -0,0 +1,32 @@
/*
* bank_write_page — записать диапазон EMM-страницы в УЖЕ ОТКРЫТЫЙ файл.
*
* Это симметричная операция к bank_read_page(): вызывающий владеет fd,
* позицией файла и политикой create/temp/rename, а функция только временно
* отображает физическую страницу в W3 и передаёт её диапазон ESTEX WRITE.
* W3 восстанавливается до возврата на всех путях.
*
* ABI: обычный SDCC __sdcccall(1). Возврат — записанный размер либо
* -1 с errno; допустимый диапазон страницы проверяется до переключения W3.
*/
#include <unistd.h>
#include <errno.h>
#include <sprinter.h>
#include <sprinter_mem.h>
int bank_write_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 = write(fd, (const void *)(0xC000u + off), size);
sprinter_page_w3(saved);
return n;
}