8e389c03f8
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
172 lines
5.7 KiB
C
172 lines
5.7 KiB
C
/*
|
|
* p2palette — минимальная проба многоцветной текстовой темы P2.2.
|
|
*
|
|
* Использует публичные системные text_pal_get/set_color(). Для каждого
|
|
* применяемого атрибута обычный и FLASH-планы задаются попарно одинаково.
|
|
* Исходные записи сохраняются и восстанавливаются перед выходом.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <conio.h>
|
|
|
|
#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;
|
|
}
|