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