8e389c03f8
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
91 lines
2.7 KiB
C
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;
|
|
}
|