/* * p3store.c — синтетическая проверка предела EMM-store панели. * * DSS не участвует: проба обязана дойти до продуктовой границы 640/641, * которая недостижима через каталог стабильного DSS 1.71 с пределом 512. */ #include #include #include #include #include #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(); }