Files
Sprinter-SDCC/applications/Volkov/tests/p3_enum_matrix/bank1_enum.c
T
snark13 8e389c03f8 Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
2026-09-10 10:45:30 +03:00

91 lines
2.7 KiB
C

/*
* bank1_enum.c — отделяет влияние адреса ffblk от переключений W3.
*
* Весь перебор исполняется при подключённом BANK1, а диагностический DTA
* занимает последние 256 байт W1. Это историческая матрица, доказавшая,
* что ни адрес DTA, ни чтение/запись W3 не снимают предел DSS. mode=0 не
* трогает W3, mode=1 читает байт EMM, mode=2 пишет 24 байта EMM.
*/
#include <stdint.h>
#include <errno.h>
#include <dir.h>
#include <sprinter_mem.h>
#define FIND_ATTRS (FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_DIREC | FA_ARCH)
__at (0x7F00) static ffblk_t find_buf;
/* Копии wrapper находятся в том же W1, что и цикл. Так проверяется не
* только адрес ffblk, но и адрес самой инструкции RST/возврата из DSS. */
static int p3_ffirst_local(const char *pattern, ffblk_t *buf,
uint8_t attrib) __naked
{
(void)pattern; (void)buf; (void)attrib;
__asm
ld iy, #2
add iy, sp
ld a, 0 (iy)
push ix
ld bc, #0x0119
rst #0x10
pop ix
pop hl
inc sp
jr c, p3_ffirst_fail$
ld de, #0
jp (hl)
p3_ffirst_fail$:
call __errno_set
ld de, #-1
jp (hl)
__endasm;
}
static int p3_fnext_local(ffblk_t *buf) __naked
{
(void)buf;
__asm
push ix
ex de, hl
ld c, #0x1A
rst #0x10
pop ix
jr c, p3_fnext_fail$
ld de, #0
ret
p3_fnext_fail$:
call __errno_set
ld de, #-1
ret
__endasm;
}
uint16_t p3_enum_mode(uint8_t mode, uint8_t page, int *end_errno) __banked
{
uint16_t count = 0u;
uint8_t payload[24];
uint16_t offset;
errno = 0;
if ((mode >= 3u ?
p3_ffirst_local("*.*", &find_buf, FIND_ATTRS) :
ffirst("*.*", &find_buf, FIND_ATTRS)) == 0) {
for (;;) {
count++;
if (mode == 1u) {
payload[0] = bank_load_byte(page, 0u);
} else if (mode == 2u || mode == 4u) {
offset = (uint16_t)(((count - 1u) % 640u) * 24u);
bank_write(page, offset, payload, 24u);
}
errno = 0;
if ((mode >= 3u ? p3_fnext_local(&find_buf) :
fnext(&find_buf)) != 0) break;
if (count == 2000u) break;
}
}
*end_errno = errno;
return count;
}