/* * p1_screen.c — визуальная проверка экранной EMM-страницы и WINREST. */ #include #include #include #include #include #include #include "p1_platform.h" #define P1_SCREEN_W 80u #define P1_SCREEN_H 32u #define P1_ROW_BYTES 160u #define P1_MARKER_OFF 0x2000u static uint8_t row_buf[P1_ROW_BYTES]; static uint8_t marker_buf[2u * 20u * 2u]; static void row_clear(uint8_t attr) { uint8_t x; for (x = 0; x < P1_SCREEN_W; x++) { row_buf[(uint16_t)x * 2u] = ' '; row_buf[(uint16_t)x * 2u + 1u] = attr; } } static void row_text(uint8_t x, const char *text, uint8_t attr) { while (*text && x < P1_SCREEN_W) { row_buf[(uint16_t)x * 2u] = (uint8_t)*text++; row_buf[(uint16_t)x * 2u + 1u] = attr; x++; } } static void marker_build(void) { static const char top[] = "PARTIAL WINREST OK "; static const char bot[] = "offset = 0x2000 "; uint8_t x; for (x = 0; x < 20; x++) { marker_buf[(uint16_t)x * 2u] = (uint8_t)top[x]; marker_buf[(uint16_t)x * 2u + 1u] = COLOR(COLOR_WHITE, COLOR_RED); marker_buf[40u + (uint16_t)x * 2u] = (uint8_t)bot[x]; marker_buf[40u + (uint16_t)x * 2u + 1u] = COLOR(COLOR_YELLOW, COLOR_RED); } } int p1_test_screen(void) { uint8_t block; uint8_t page; uint8_t y; p1_heading("WINREST: preparing EMM screen"); errno = 0; block = mem_alloc_pages(1); if (block == 0) { printf("mem_alloc_pages failed: errno=%d\n", errno); return -1; } page = mem_get_page(block, 0); if (page == 0) { printf("mem_get_page failed: errno=%d\n", errno); mem_free_block(block); return -1; } for (y = 0; y < P1_SCREEN_H; y++) { /* Только яркие foreground 9..15 на синем: граница не должна * исчезать из-за комбинации blue-on-blue вроде прежнего 0x11. */ uint8_t attr = COLOR((uint8_t)(COLOR_LIGHTBLUE + (y % 7u)), COLOR_BLUE); row_clear(attr); row_buf[0] = (y == 0 || y == 31) ? '+' : '|'; row_buf[158] = (y == 0 || y == 31) ? '+' : '|'; if (y == 0 || y == 31) { uint8_t x; for (x = 1; x < 79; x++) row_buf[(uint16_t)x * 2u] = '-'; } if (y == 2) row_text(4, "FULL 80x32 WINREST FROM EMM PAGE", COLOR(COLOR_WHITE, COLOR_BLUE)); if (y == 4) row_text(4, "Rows have different foreground colours.", COLOR(COLOR_YELLOW, COLOR_BLUE)); if (y == 6) row_text(4, "Expected: complete border, no shifted cells.", COLOR(COLOR_YELLOW, COLOR_BLUE)); if (y == 28) row_text(4, "Press a key for partial-offset test.", COLOR(COLOR_WHITE, COLOR_BLUE)); bank_write(page, (uint16_t)y * P1_ROW_BYTES, row_buf, P1_ROW_BYTES); } marker_build(); bank_write(page, P1_MARKER_OFF, marker_buf, sizeof(marker_buf)); p1_winrest(0, 0, P1_SCREEN_H, P1_SCREEN_W, page, 0); (void)getkey(); /* Две строки по 20 ячеек поверх середины полного экрана. */ p1_winrest(14, 30, 2, 20, page, P1_MARKER_OFF); (void)getkey(); mem_free_block(block); p1_heading("WINREST test finished"); cputs("Visual checks:\r\n"); cputs(" 1. Full 80x32 frame had no shifts or holes.\r\n"); cputs(" 2. Red/yellow 20x2 marker appeared at row 14, col 30.\r\n"); cputs(" 3. Marker text started at offset 0x2000.\r\n"); cputs("\r\nReturn PASS only records that both calls completed.\r\n"); return 0; }