VDB: honor the VGA-DAC pixel-mask (RP drives it; BT left it 0xFF); park Mac mirror

RP experiment finding: RP runs on the BT pod emulator (shared MUNGA stack) but
its cockpit VDB heads mis-decode. Root causes captured live (VDB_PALDUMP +
vpxresp log): (1) framebuffer identical to BT (mode 0x111, 640x480); (2) RP
loads pal0 (BT's dynamic color-radar palette) as ALL ZEROS -> radar head black;
(3) RP actively drives the VGA-DAC pixel-mask register that BT leaves at 0xFF,
and pal_draw ignored it -> likely the MFD garble.

Device change: pixel-mask writes now log their VALUE on change
("# VDB pixel-mask[gN] = 0xXX"); pal_draw ANDs the palette index with the
group mask under VDB_APPLYMASK=1 (default off = BT-identical); masks default to
0xFF in vdb_reset so an un-driven group still decodes. Built clean under MINGW64.

Also: Mac Console 4.10 retired from regular use (host .NET console is the daily
driver); tap2_mirror.py PARKED with revive notes for console A/B only. The
SendToRxAdapters registry stays set (serves the .NET host console).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-09 14:53:22 -05:00
co-authored by Claude Fable 5
parent dd2ae57647
commit 68ca9b6f15
3 changed files with 38 additions and 2 deletions
+19 -1
View File
@@ -1326,6 +1326,10 @@ static void write_bmp(const char *path, const unsigned char *rgb, int W, int H)
static void pal_draw(HDC dc, int g, int cw, int ch, bool dump) {
const int W = 640, H = 480;
static unsigned char img[640 * 480 * 3];
/* VDB_APPLYMASK=1: AND the palette index with the group's VGA-DAC
* pixel-mask (default 0xFF = no-op). RP drives this mask actively where
* BT leaves it 0xFF, so honoring it may unscramble RP's MFD heads. */
static const bool apply_mask = getenv("VDB_APPLYMASK") != NULL;
const uint8_t *fb = vga.mem.linear;
Bitu mask = vga.draw.linear_mask ? vga.draw.linear_mask
: (vga.mem.memsize ? vga.mem.memsize - 1 : 0);
@@ -1348,6 +1352,7 @@ static void pal_draw(HDC dc, int g, int cw, int ch, bool dump) {
else { idx = (px >> 8u) & 0xFFu; /* wins 5-9: one mono MFD */
pg = (g <= 6) ? 1 : 2; /* = one color wire of a */
chn = (g <= 6) ? g - 5 : g - 7; } /* head (pentapus split) */
if (apply_mask) idx &= vdb_pal[pg].mask;
const unsigned char *e = &vdb_pal[pg].ram[idx * 3u];
if (chn < 0) {
d[0] = (unsigned char)((e[0] << 2) | (e[0] >> 4)); /* 6-bit DAC -> 8-bit R */
@@ -2533,7 +2538,17 @@ static void vdb_write(Bitu port, Bitu val, Bitu /*iolen*/) {
vdb_data_count++;
break;
case 0: /* pixel-mask */
p.mask = v; vdb_note("pixel-mask set");
/* RP drives this VGA-DAC pixel-mask register actively (BT leaves
* it at 0xFF); log the VALUE on change so we can see how RP gates
* the palette index, and honor it in pal_draw under VDB_APPLYMASK. */
if (v != p.mask) {
p.mask = v;
if (vpx_fp) { vdb_flush_data(); flush_run();
fprintf(vpx_fp, "# VDB pixel-mask[g%d] = 0x%02X\n", g, v);
fflush(vpx_fp); }
} else {
p.mask = v;
}
break;
case 1: /* read-address */
p.raddr = v; p.sub = 0;
@@ -2554,6 +2569,9 @@ static Bitu vdb_read(Bitu port, Bitu /*iolen*/) {
}
static void vdb_reset(void) {
memset(vdb_pal, 0, sizeof vdb_pal);
/* pixel-mask defaults to 0xFF (no gating) so an un-set group decodes
* normally; the game overwrites it if it drives the mask (RP does). */
for (int g = 0; g < 3; g++) vdb_pal[g].mask = 0xFF;
vdb_splitter_on = false; vdb_data_group = -1; vdb_data_count = 0;
}