Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user