Files
Sprinter-SDCC/applications/Volkov/tests/p4_bank_io_probe/p4bio.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

137 lines
4.1 KiB
C

/*
* p4bio.c — целевая проба bank_read_page()/bank_write_page().
*
* Проверяет перенос 4096 байт через одну EMM-страницу без полноразмерного
* near-буфера, восстановление W3, контроль границ и отсутствие утечки EMM.
* Временный файл создаётся только на тестовой дискете A: и удаляется.
*/
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <conio.h>
#include <sprinter.h>
#include <sprinter_mem.h>
#define TEST_PATH "A:\\P4BIO.TMP"
#define TEST_SIZE 4096u
#define READ_OFFSET 4096u
static uint8_t chunk[256];
static uint8_t pattern(uint16_t pos)
{
return (uint8_t)((uint8_t)(pos * 37u) + (uint8_t)(pos >> 8) + 0x5Au);
}
static void prepare_page(uint8_t page)
{
uint16_t base;
uint16_t i;
for (base = 0u; base < TEST_SIZE; base += (uint16_t)sizeof(chunk)) {
for (i = 0u; i < (uint16_t)sizeof(chunk); i++) {
chunk[i] = pattern((uint16_t)(base + i));
}
bank_write(page, base, chunk, (uint16_t)sizeof(chunk));
}
}
static uint8_t verify_page(uint8_t page)
{
uint16_t i;
for (i = 0u; i < TEST_SIZE; i++) {
if (bank_load_byte(page, (uint16_t)(READ_OFFSET + i)) != pattern(i)) {
return 0u;
}
}
return 1u;
}
int main(void)
{
uint16_t total_before;
uint16_t free_before;
uint16_t total_after;
uint16_t free_after;
uint8_t block = 0u;
uint8_t page = 0u;
uint8_t w3_before;
uint8_t write_w3_ok = 0u;
uint8_t read_w3_ok = 0u;
uint8_t data_ok = 0u;
uint8_t range_ok = 0u;
uint8_t cleanup_ok;
int fd = -1;
int written = -1;
int loaded = -1;
(void)settextmode(TEXT_MODE_80x32);
clrscr_attr(0x17u);
gotoxy(0u, 0u);
textattr(0x1Fu);
cputs("P4 bank page file I/O diagnostic\r\n\r\n");
textattr(0x17u);
(void)unlink(TEST_PATH);
mem_info(&total_before, &free_before);
block = mem_alloc_pages(1u);
page = block ? mem_get_page(block, 0u) : 0u;
if (!block || !page) goto cleanup;
prepare_page(page);
fd = open(TEST_PATH, O_WRONLY | O_CREAT | O_EXCL);
if (fd < 0) goto cleanup;
w3_before = _io_page_w3;
written = bank_write_page(fd, page, 0u, TEST_SIZE);
write_w3_ok = (_io_page_w3 == w3_before);
if (close(fd) != 0) goto cleanup;
fd = -1;
if (written != TEST_SIZE) goto cleanup;
fd = open(TEST_PATH, O_RDONLY);
if (fd < 0) goto cleanup;
w3_before = _io_page_w3;
loaded = bank_read_page(fd, page, READ_OFFSET, TEST_SIZE);
read_w3_ok = (_io_page_w3 == w3_before);
if (close(fd) != 0) goto cleanup;
fd = -1;
if (loaded != TEST_SIZE) goto cleanup;
data_ok = verify_page(page);
errno = 0;
w3_before = _io_page_w3;
range_ok = bank_write_page(-1, page, 0x3FFFu, 2u) == -1 &&
errno == EINVAL && _io_page_w3 == w3_before;
cleanup:
if (fd >= 0) (void)close(fd);
(void)unlink(TEST_PATH);
if (block != 0u) mem_free_block(block);
mem_info(&total_after, &free_after);
cleanup_ok = total_before == total_after && free_before == free_after;
printf("page=%02X write=%d read=%d data=%u\n",
(unsigned)page, written, loaded, (unsigned)data_ok);
printf("W3: write=%u read=%u range=%u errno=%d\n",
(unsigned)write_w3_ok, (unsigned)read_w3_ok,
(unsigned)range_ok, errno);
printf("EMM: before=%u after=%u restored=%u\n",
(unsigned)free_before, (unsigned)free_after,
(unsigned)cleanup_ok);
textattr((written == TEST_SIZE && loaded == TEST_SIZE && data_ok &&
write_w3_ok && read_w3_ok && range_ok && cleanup_ok) ?
0x1Eu : 0x4Fu);
cputs((written == TEST_SIZE && loaded == TEST_SIZE && data_ok &&
write_w3_ok && read_w3_ok && range_ok && cleanup_ok) ?
"\r\nPASS: bank page file I/O is intact." :
"\r\nFAIL: bank page file I/O violation.");
textattr(0x1Eu);
cputs("\r\nProbe stopped; MAME test will take a snapshot.");
for (;;) (void)getkey();
}