/* * p2palette — минимальная проба многоцветной текстовой темы P2.2. * * Использует публичные системные text_pal_get/set_color(). Для каждого * применяемого атрибута обычный и FLASH-планы задаются попарно одинаково. * Исходные записи сохраняются и восстанавливаются перед выходом. */ #include #include #define SAMPLE_COUNT 6u #define ATTR_UI COLOR(COLOR_BLACK, COLOR_CYAN) typedef struct { uint8_t attr; uint8_t paper_r; uint8_t paper_g; uint8_t paper_b; uint8_t ink_r; uint8_t ink_g; uint8_t ink_b; const char *name; } ThemeSample; static const ThemeSample samples[SAMPLE_COUNT] = { { COLOR(COLOR_WHITE, COLOR_BLUE), 0x00, 0x00, 0xA8, 0xFF, 0xFF, 0xFF, "WHITE / BLUE" }, { COLOR(COLOR_YELLOW, COLOR_GREEN), 0x00, 0xA8, 0x00, 0xFF, 0xFF, 0x00, "YELLOW / GREEN" }, { COLOR(COLOR_WHITE, COLOR_RED), 0xA8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, "WHITE / RED" }, { COLOR(COLOR_WHITE, COLOR_MAGENTA), 0xA8, 0x00, 0xA8, 0xFF, 0xFF, 0xFF, "WHITE / MAGENTA" }, { COLOR(COLOR_BLACK, COLOR_LIGHTGRAY),0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, "BLACK / LIGHTGRAY" }, { ATTR_UI, 0x00, 0xA8, 0xA8, 0x00, 0x00, 0x00, "BLACK / CYAN" } }; /* [sample][plane][RGB]. Static: буферы BIOS остаются в W2, не на стеке. */ static uint8_t saved[SAMPLE_COUNT][4u][3u]; static uint8_t readback[SAMPLE_COUNT][4u][3u]; static void save_palette(void) { uint8_t i; uint8_t p; for (i = 0u; i < SAMPLE_COUNT; i++) { for (p = 0u; p < 4u; p++) { text_pal_get_color(p, samples[i].attr, &saved[i][p][0], &saved[i][p][1], &saved[i][p][2]); } } } static void set_sample(uint8_t i) { const ThemeSample *s = &samples[i]; text_pal_set_color(TEXT_PAL_PAPER, s->attr, s->paper_r, s->paper_g, s->paper_b); text_pal_set_color(TEXT_PAL_BLINK_PAPER, s->attr, s->paper_r, s->paper_g, s->paper_b); text_pal_set_color(TEXT_PAL_INK, s->attr, s->ink_r, s->ink_g, s->ink_b); text_pal_set_color(TEXT_PAL_BLINK_INK, s->attr, s->ink_r, s->ink_g, s->ink_b); } static uint8_t verify_palette(void) { uint8_t i; uint8_t p; uint8_t failed = 0u; for (i = 0u; i < SAMPLE_COUNT; i++) { for (p = 0u; p < 4u; p++) { const ThemeSample *s = &samples[i]; uint8_t want_r = (p == TEXT_PAL_PAPER || p == TEXT_PAL_BLINK_PAPER) ? s->paper_r : s->ink_r; uint8_t want_g = (p == TEXT_PAL_PAPER || p == TEXT_PAL_BLINK_PAPER) ? s->paper_g : s->ink_g; uint8_t want_b = (p == TEXT_PAL_PAPER || p == TEXT_PAL_BLINK_PAPER) ? s->paper_b : s->ink_b; text_pal_get_color(p, s->attr, &readback[i][p][0], &readback[i][p][1], &readback[i][p][2]); if (readback[i][p][0] != want_r || readback[i][p][1] != want_g || readback[i][p][2] != want_b) failed++; } } return failed; } static void restore_palette(void) { uint8_t i; uint8_t p; for (i = 0u; i < SAMPLE_COUNT; i++) { for (p = 0u; p < 4u; p++) { text_pal_set_color(p, samples[i].attr, saved[i][p][0], saved[i][p][1], saved[i][p][2]); } } } static void fill_row(uint8_t y, uint8_t attr, const char *name) { uint8_t x; for (x = 0u; x < 80u; x++) wrchar(x, y, ' ', attr); for (x = 0u; name[x] && x < 30u; x++) { wrchar((uint8_t)(4u + x), y, name[x], attr); } for (x = 42u; x < 76u; x++) { wrchar(x, y, (x & 1u) ? '#' : '@', attr); } } static void draw_screen(uint8_t failed) { uint8_t i; clrscr_attr(ATTR_UI); textattr(ATTR_UI); gotoxy(1u, 0u); cputs("P2.2 SYSTEM TEXT PALETTE PROBE - BIOS CALLS ARE ALLOWED"); gotoxy(1u, 2u); cprintf("Readback of 6 attrs x 4 planes: %s (%u mismatches)", failed ? "FAIL" : "PASS", (unsigned)failed); gotoxy(1u, 3u); cputs("Each PAPER pair and INK pair is identical; scene must not flash."); for (i = 0u; i < SAMPLE_COUNT; i++) { fill_row((uint8_t)(6u + i * 3u), samples[i].attr, samples[i].name); fill_row((uint8_t)(7u + i * 3u), samples[i].attr, "same attribute, second row"); } gotoxy(1u, 26u); cputs("If any coloured band disappears, compare MAME phase with readback."); gotoxy(1u, 28u); cputs("Press a key to restore every saved palette entry and exit."); } int main(void) { uint8_t previous_mode = gettextmode(); uint8_t i; uint8_t failed; if (settextmode(TEXT_MODE_80x32) != 0) return 1; save_palette(); for (i = 0u; i < SAMPLE_COUNT; i++) set_sample(i); failed = verify_palette(); draw_screen(failed); (void)getkey(); restore_palette(); textattr(COLOR(COLOR_WHITE, COLOR_BLACK)); clrscr(); if (previous_mode == TEXT_MODE_40x32 || previous_mode == TEXT_MODE_80x32) { (void)settextmode(previous_mode); } return failed ? 2 : 0; }