Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# Матрица влияния W3/EMM на длинный F_FIRST/F_NEXT.
|
||||
|
||||
PROJ_ROOT := $(abspath $(CURDIR)/../../../..)
|
||||
EXAMPLE := p3map
|
||||
MEMORY := big
|
||||
ALLOCS ?= 3000
|
||||
EXTRA_FLAGS := --safe --max-allocs $(ALLOCS) --bank 1=bank1_enum.c
|
||||
|
||||
include $(PROJ_ROOT)/app.mk
|
||||
|
||||
$(EXE): Makefile bank1_enum.c
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* p3map.c — экранный отчёт матрицы длинного перебора каталога. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <conio.h>
|
||||
#include <sprinter_mem.h>
|
||||
|
||||
uint16_t p3_enum_mode(uint8_t mode, uint8_t page, int *end_errno) __banked;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t block;
|
||||
uint8_t page;
|
||||
uint8_t mode;
|
||||
uint16_t count;
|
||||
int end_errno;
|
||||
|
||||
(void)settextmode(TEXT_MODE_80x32);
|
||||
clrscr_attr(0x17u);
|
||||
gotoxy(0u, 0u);
|
||||
textattr(0x1Fu);
|
||||
cputs("P3 F_NEXT / W3 matrix\r\n\r\n");
|
||||
textattr(0x17u);
|
||||
|
||||
block = mem_alloc_pages(1u);
|
||||
page = block ? mem_get_page(block, 0u) : 0u;
|
||||
printf("EMM: block=%u page=%02X errno=%d\n",
|
||||
(unsigned)block, (unsigned)page, errno);
|
||||
if (!block || !page) goto done;
|
||||
|
||||
for (mode = 0u; mode != 5u; mode++) {
|
||||
errno = 0;
|
||||
if (chdir("\\BIGDIR") != 0) {
|
||||
printf("mode %u: chdir error=%d\n", (unsigned)mode, errno);
|
||||
break;
|
||||
}
|
||||
count = p3_enum_mode(mode, page, &end_errno);
|
||||
printf("mode %u: count=%u end_errno=%d\n",
|
||||
(unsigned)mode, (unsigned)count, end_errno);
|
||||
errno = 0;
|
||||
if (chdir("\\") != 0) {
|
||||
printf("root after mode %u: error=%d\n",
|
||||
(unsigned)mode, errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mem_free_block(block);
|
||||
|
||||
done:
|
||||
textattr(0x1Eu);
|
||||
cputs("\r\nProbe stopped; MAME test will take a snapshot.");
|
||||
for (;;) (void)getkey();
|
||||
}
|
||||
Reference in New Issue
Block a user