/* * p4bio.c — целевая проба bank_read_page()/bank_write_page(). * * Проверяет перенос 4096 байт через одну EMM-страницу без полноразмерного * near-буфера, восстановление W3, контроль границ и отсутствие утечки EMM. * Временный файл создаётся только на тестовой дискете A: и удаляется. */ #include #include #include #include #include #include #include #include #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(); }