Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# Синтетическая проверка границы одной EMM-страницы панели: 640/641.
|
||||
|
||||
PROJ_ROOT := $(abspath $(CURDIR)/../../../..)
|
||||
EXAMPLE := p3store
|
||||
MEMORY := big
|
||||
ALLOCS ?= 3000
|
||||
EXTRA_FLAGS := --safe --max-allocs $(ALLOCS) -I ../../include
|
||||
EXTRA_SRCS := ../../src/sc_store.c
|
||||
|
||||
include $(PROJ_ROOT)/app.mk
|
||||
|
||||
$(EXE): Makefile ../../src/sc_store.c ../../include/sc_entry.h \
|
||||
../../include/sc_panel.h ../../include/sc_store.h
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* p3store.c — синтетическая проверка предела EMM-store панели.
|
||||
*
|
||||
* DSS не участвует: проба обязана дойти до продуктовой границы 640/641,
|
||||
* которая недостижима через каталог стабильного DSS 1.71 с пределом 512.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <sprinter_mem.h>
|
||||
#include "sc_panel.h"
|
||||
#include "sc_store.h"
|
||||
|
||||
#define STORE_BYTES ((uint16_t)(SC_DIR_CAPACITY * sizeof(ScDirEntry)))
|
||||
|
||||
static ScPanel panel;
|
||||
static ScDirEntry entry;
|
||||
static ScDirEntry check;
|
||||
|
||||
static uint32_t expected_size(uint16_t index)
|
||||
{
|
||||
return (uint32_t)index * 257ul + 3ul;
|
||||
}
|
||||
|
||||
static uint8_t verify_entry(uint16_t index)
|
||||
{
|
||||
if (sc_store_get(&panel, index, &check) != 0) return 0u;
|
||||
return check.name[0] == 'R' && check.name[1] == (char)(index & 0x7Fu) &&
|
||||
check.size == expected_size(index) && check.date == index &&
|
||||
check.time == (uint16_t)(index ^ 0x55AAu) &&
|
||||
check.reserved == 0xA5u;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint16_t total_before;
|
||||
uint16_t free_before;
|
||||
uint16_t total_after;
|
||||
uint16_t free_after;
|
||||
uint16_t written = 0u;
|
||||
uint16_t i;
|
||||
uint8_t block;
|
||||
uint8_t page;
|
||||
uint8_t first_ok;
|
||||
uint8_t middle_ok;
|
||||
uint8_t last_ok;
|
||||
uint8_t put_641_blocked;
|
||||
uint8_t get_641_blocked;
|
||||
uint8_t tail_ok;
|
||||
uint8_t emm_restored;
|
||||
|
||||
(void)settextmode(TEXT_MODE_80x32);
|
||||
clrscr_attr(0x17u);
|
||||
gotoxy(0u, 0u);
|
||||
textattr(0x1Fu);
|
||||
cputs("P3 EMM store 640/641 diagnostic\r\n\r\n");
|
||||
textattr(0x17u);
|
||||
|
||||
printf("entry=%u capacity=%u bytes=%u reserve=%u\n",
|
||||
(unsigned)sizeof(ScDirEntry), (unsigned)SC_DIR_CAPACITY,
|
||||
(unsigned)STORE_BYTES, (unsigned)(0x4000u - STORE_BYTES));
|
||||
|
||||
mem_info(&total_before, &free_before);
|
||||
block = mem_alloc_pages(1u);
|
||||
page = block ? mem_get_page(block, 0u) : 0u;
|
||||
printf("EMM: block=%u page=%02X free_before=%u\n",
|
||||
(unsigned)block, (unsigned)page, (unsigned)free_before);
|
||||
if (!block || !page) goto failed_alloc;
|
||||
|
||||
memset(&panel, 0, sizeof(panel));
|
||||
panel.phys_page = page;
|
||||
bank_store_byte(page, STORE_BYTES, 0x5Au);
|
||||
bank_store_byte(page, 0x3FFFu, 0xC3u);
|
||||
|
||||
for (i = 0u; i < SC_DIR_CAPACITY; i++) {
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.name[0] = 'R';
|
||||
entry.name[1] = (char)(i & 0x7Fu);
|
||||
entry.size = expected_size(i);
|
||||
entry.date = i;
|
||||
entry.time = (uint16_t)(i ^ 0x55AAu);
|
||||
entry.reserved = 0xA5u;
|
||||
if (sc_store_put(&panel, i, &entry) != 0) break;
|
||||
written++;
|
||||
}
|
||||
panel.count = written;
|
||||
|
||||
first_ok = verify_entry(0u);
|
||||
middle_ok = verify_entry(319u);
|
||||
last_ok = verify_entry(639u);
|
||||
put_641_blocked = (sc_store_put(&panel, 640u, &entry) != 0);
|
||||
get_641_blocked = (sc_store_get(&panel, 640u, &check) != 0);
|
||||
tail_ok = bank_load_byte(page, STORE_BYTES) == 0x5Au &&
|
||||
bank_load_byte(page, 0x3FFFu) == 0xC3u;
|
||||
|
||||
printf("write: count=%u first=%u middle=%u last=%u\n",
|
||||
(unsigned)written, (unsigned)first_ok,
|
||||
(unsigned)middle_ok, (unsigned)last_ok);
|
||||
printf("guard: put640=%u get640=%u tail=%u\n",
|
||||
(unsigned)put_641_blocked, (unsigned)get_641_blocked,
|
||||
(unsigned)tail_ok);
|
||||
|
||||
mem_free_block(block);
|
||||
mem_info(&total_after, &free_after);
|
||||
emm_restored = total_before == total_after && free_before == free_after;
|
||||
printf("cleanup: free_after=%u restored=%u\n",
|
||||
(unsigned)free_after, (unsigned)emm_restored);
|
||||
|
||||
textattr((written == 640u && first_ok && middle_ok && last_ok &&
|
||||
put_641_blocked && get_641_blocked && tail_ok && emm_restored) ?
|
||||
0x1Eu : 0x4Fu);
|
||||
cputs((written == 640u && first_ok && middle_ok && last_ok &&
|
||||
put_641_blocked && get_641_blocked && tail_ok && emm_restored) ?
|
||||
"\r\nPASS: store boundary is intact." :
|
||||
"\r\nFAIL: store boundary violation.");
|
||||
goto stopped;
|
||||
|
||||
failed_alloc:
|
||||
textattr(0x4Fu);
|
||||
cputs("\r\nFAIL: cannot allocate EMM page.");
|
||||
|
||||
stopped:
|
||||
textattr(0x1Eu);
|
||||
cputs("\r\nProbe stopped; MAME test will take a snapshot.");
|
||||
for (;;) (void)getkey();
|
||||
}
|
||||
Reference in New Issue
Block a user