Mercurial > repos > blastem
changeset 2612:7e04620c9dc1
Get tilemap debug view working for TMS graphics and text modes. Multicolor still TBD
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Feb 2025 23:29:51 -0800 |
parents | 9bd90cd94000 |
children | 1fdf7acc5165 |
files | vdp.c |
diffstat | 1 files changed, 112 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/vdp.c Sat Feb 15 23:06:49 2025 -0800 +++ b/vdp.c Sat Feb 15 23:29:51 2025 -0800 @@ -2587,8 +2587,106 @@ { } +uint32_t tms_map_color(vdp_context *context, uint8_t color) +{ + if (context->type == VDP_GAMEGEAR) { + //Game Gear uses CRAM entries 16-31 for TMS9918A modes + return context->colors[color + 16 + MODE4_OFFSET]; + } else { + color <<= 1; + color = (color & 0xE) | (color << 1 & 0x20); + return context->color_map[color | FBUF_TMS]; + } +} + static void plane_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) { + uint16_t table_address = context->regs[REG_SCROLL_A] << 10 & 0x3C00; + uint16_t color_address = context->regs[REG_COLOR_TABLE] << 6; + uint16_t pattern_address = context->regs[REG_PATTERN_GEN] << 11 & 0x3800; + uint16_t upper_vcounter_mask; + uint16_t upper_vcounter_pmask; + uint16_t pattern_name_mask; + if (context->type > VDP_SMS2) { + //SMS1 and TMS9918A + upper_vcounter_mask = color_address & 0x1800; + upper_vcounter_pmask = pattern_address & 0x1800; + pattern_name_mask = (color_address & 0x07C0) | 0x0038; + } else { + //SMS2 and Game Gear + upper_vcounter_mask = 0x1800; + upper_vcounter_pmask = 0x1800; + pattern_name_mask = 0x07F8; + } + uint32_t cols, pixels; + if (context->regs[REG_MODE_2] & BIT_M1) { + //Text mode + cols = 40; + pixels = 12; + } else { + //Graphics/Multicolor + cols = 32; + pixels = 16; + } + uint32_t fg, bg; + if (context->regs[REG_MODE_2] & BIT_M1) { + //Text mode uses TC and BD colors + fg = tms_map_color(context, context->regs[REG_BG_COLOR] >> 4); + bg = tms_map_color(context, context->regs[REG_BG_COLOR] & 0xF); + } + for (uint32_t row = 0; row < 24; row++) + { + uint32_t *colfb = fb; + for (uint32_t col = 0; col < cols; col++) + { + uint32_t *linefb = colfb; + uint8_t pattern = context->vdpmem[mode4_address_map[table_address] ^ 1]; + uint16_t caddress = color_address; + uint16_t paddress = pattern_address; + if (context->regs[REG_MODE_2] & BIT_M2) { + } else { + if (context->regs[REG_MODE_1] & BIT_M3) { + //Graphics II + caddress &= 0x2000; + paddress &= 0x2000; + caddress |= (row * 8) << 5 & upper_vcounter_mask; + caddress |= pattern << 3 & pattern_name_mask; + paddress |= (row * 8) << 5 & upper_vcounter_pmask; + } else { + caddress |= pattern >> 3; + } + paddress |= pattern << 3 & 0x7F8; + for (uint32_t y = 0; y < 16; y++) + { + uint8_t bits = context->vdpmem[mode4_address_map[paddress] ^ 1]; + if (!(context->regs[REG_MODE_2] & BIT_M1)) { + uint8_t colors = context->vdpmem[mode4_address_map[caddress] ^ 1]; + fg = tms_map_color(context, colors >> 4); + bg = tms_map_color(context, colors & 0xF); + } + + uint32_t *curfb = linefb; + for (uint32_t x = 0; x < pixels; x++) + { + *(curfb++) = (bits & 0x80) ? fg : bg; + if (x & 1) { + bits <<= 1; + } + } + linefb += pitch / sizeof(uint32_t); + if (y & 1) { + if (context->regs[REG_MODE_1] & BIT_M3) { + caddress++; + } + paddress++; + } + } + } + table_address++; + colfb += pixels; + } + fb += 16 * pitch / sizeof(uint32_t); + } } static void sprite_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) @@ -4231,59 +4329,33 @@ tms_sprite_clock(context, 1); return; } + uint8_t fg,bg; + if (context->regs[REG_MODE_2] & BIT_M1) { + //Text mode uses TC and BD colors + fg = context->regs[REG_BG_COLOR] >> 4; + bg = context->regs[REG_BG_COLOR] & 0xF; + } else { + fg = context->tmp_buf_b[0] >> 4; + bg = context->tmp_buf_b[0] & 0xF; + if (!bg) { + bg = context->regs[REG_BG_COLOR] & 0xF; + } + } uint8_t pattern = context->tmp_buf_a[0] & 0x80; context->tmp_buf_a[0] <<= 1; if (!color) { - uint8_t fg,bg; - if (context->regs[REG_MODE_2] & BIT_M1) { - //Text mode uses TC and BD colors - fg = context->regs[REG_BG_COLOR] >> 4; - bg = context->regs[REG_BG_COLOR] & 0xF; - } else { - fg = context->tmp_buf_b[0] >> 4; - bg = context->tmp_buf_b[0] & 0xF; - if (!bg) { - bg = context->regs[REG_BG_COLOR] & 0xF; - } - } color = pattern ? fg : bg; } //TODO: composite debug output - if (context->type == VDP_GAMEGEAR) { - //Game Gear uses CRAM entries 16-31 for TMS9918A modes - context->output[context->hslot * 2 - 8 + BORDER_LEFT] = context->colors[color + 16 + MODE4_OFFSET]; - } else { - color <<= 1; - color = (color & 0xE) | (color << 1 & 0x20); - context->output[context->hslot * 2 - 8 + BORDER_LEFT] = context->color_map[color | FBUF_TMS]; - } + context->output[context->hslot * 2 - 8 + BORDER_LEFT] = tms_map_color(context, color); color = tms_sprite_clock(context, 1); pattern = context->tmp_buf_a[0] & 0x80; context->tmp_buf_a[0] <<= 1; if (!color) { - uint8_t fg,bg; - if (context->regs[REG_MODE_2] & BIT_M1) { - //Text mode uses TC and BD colors - fg = context->regs[REG_BG_COLOR] >> 4; - bg = context->regs[REG_BG_COLOR] & 0xF; - } else { - fg = context->tmp_buf_b[0] >> 4; - bg = context->tmp_buf_b[0] & 0xF; - if (!bg) { - bg = context->regs[REG_BG_COLOR] & 0xF; - } - } color = pattern ? fg : bg; } //TODO: composite debug output - if (context->type == VDP_GAMEGEAR) { - //Game Gear uses CRAM entries 16-31 for TMS9918A modes - context->output[context->hslot * 2 - 7 + BORDER_LEFT] = context->colors[color + 16 + MODE4_OFFSET]; - } else { - color <<= 1; - color = (color & 0xE) | (color << 1 & 0x20); - context->output[context->hslot * 2 - 7 + BORDER_LEFT] = context->color_map[color | FBUF_TMS]; - } + context->output[context->hslot * 2 - 7 + BORDER_LEFT] = tms_map_color(context, color); } #define TMS_OUTPUT(slot) if ((slot) < 4 || (slot) > (256 + BORDER_LEFT - 8) / 2) { tms_border(context); } else { tms_composite(context); }