comparison vdp.c @ 2685:da2e06c42d16

Add a compile-time flag to use RGB565 instead of ABGR/ARGB
author Michael Pavone <pavone@retrodev.com>
date Sun, 30 Mar 2025 00:06:53 -0700
parents dbff641a33df
children 05915f01046d
comparison
equal deleted inserted replaced
2684:c649bcc18487 2685:da2e06c42d16
158 158
159 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram, uint8_t type) 159 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram, uint8_t type)
160 { 160 {
161 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE); 161 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE);
162 if (headless) { 162 if (headless) {
163 context->fb = malloc(512 * LINEBUF_SIZE * sizeof(uint32_t)); 163 context->fb = malloc(512 * LINEBUF_SIZE * sizeof(pixel_t));
164 context->output_pitch = LINEBUF_SIZE * sizeof(uint32_t); 164 context->output_pitch = LINEBUF_SIZE * sizeof(pixel_t);
165 } else { 165 } else {
166 context->cur_buffer = FRAMEBUFFER_ODD; 166 context->cur_buffer = FRAMEBUFFER_ODD;
167 context->fb = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch); 167 context->fb = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch);
168 } 168 }
169 context->sprite_draws = MAX_SPRITES_LINE; 169 context->sprite_draws = MAX_SPRITES_LINE;
337 } 337 }
338 if (region_pal) { 338 if (region_pal) {
339 context->flags2 |= FLAG2_REGION_PAL; 339 context->flags2 |= FLAG2_REGION_PAL;
340 } 340 }
341 update_video_params(context); 341 update_video_params(context);
342 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * context->border_top); 342 context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * context->border_top);
343 return context; 343 return context;
344 } 344 }
345 345
346 void vdp_free(vdp_context *context) 346 void vdp_free(vdp_context *context)
347 { 347 {
997 context->vcounter < context->inactive_start + context->border_bot 997 context->vcounter < context->inactive_start + context->border_bot
998 || context->vcounter > 0x200 - context->border_top 998 || context->vcounter > 0x200 - context->border_top
999 )) { 999 )) {
1000 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2; 1000 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2;
1001 if (context->hslot < bg_end_slot) { 1001 if (context->hslot < bg_end_slot) {
1002 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET]; 1002 pixel_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET];
1003 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; 1003 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color;
1004 } 1004 }
1005 } 1005 }
1006 } 1006 }
1007 1007
1818 if (col) { 1818 if (col) {
1819 col -= 2; 1819 col -= 2;
1820 dst = context->compositebuf + BORDER_LEFT + col * 8; 1820 dst = context->compositebuf + BORDER_LEFT + col * 8;
1821 } else { 1821 } else {
1822 dst = context->compositebuf; 1822 dst = context->compositebuf;
1823 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 1823 pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1824 memset(dst, 0, BORDER_LEFT); 1824 memset(dst, 0, BORDER_LEFT);
1825 context->done_composite = dst + BORDER_LEFT; 1825 context->done_composite = dst + BORDER_LEFT;
1826 return; 1826 return;
1827 } 1827 }
1828 memset(dst, 0, 16); 1828 memset(dst, 0, 16);
2057 line -= total_lines - context->border_top; 2057 line -= total_lines - context->border_top;
2058 } else { 2058 } else {
2059 line += context->border_top; 2059 line += context->border_top;
2060 } 2060 }
2061 if (context->enabled_debuggers & (1 << DEBUG_CRAM)) { 2061 if (context->enabled_debuggers & (1 << DEBUG_CRAM)) {
2062 uint32_t *fb = context->debug_fbs[DEBUG_CRAM] + context->debug_fb_pitch[DEBUG_CRAM] * line / sizeof(uint32_t); 2062 pixel_t *fb = context->debug_fbs[DEBUG_CRAM] + context->debug_fb_pitch[DEBUG_CRAM] * line / sizeof(pixel_t);
2063 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 2063 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
2064 for (int i = 0; i < 64; i++) 2064 for (int i = 0; i < 64; i++)
2065 { 2065 {
2066 for (int x = 0; x < 8; x++) 2066 for (int x = 0; x < 8; x++)
2067 { 2067 {
2080 uint16_t address = context->regs[REG_COLOR_TABLE] << 6; 2080 uint16_t address = context->regs[REG_COLOR_TABLE] << 6;
2081 for (int i = 0; i < 32; i++, address++) 2081 for (int i = 0; i < 32; i++, address++)
2082 { 2082 {
2083 uint8_t entry = context->vdpmem[mode4_address_map[address] ^ 1]; 2083 uint8_t entry = context->vdpmem[mode4_address_map[address] ^ 1];
2084 uint8_t fg = entry >> 4, bg = entry & 0xF; 2084 uint8_t fg = entry >> 4, bg = entry & 0xF;
2085 uint32_t fg_full, bg_full; 2085 pixel_t fg_full, bg_full;
2086 if (context->type == VDP_GAMEGEAR) { 2086 if (context->type == VDP_GAMEGEAR) {
2087 //Game Gear uses CRAM entries 16-31 for TMS9918A modes 2087 //Game Gear uses CRAM entries 16-31 for TMS9918A modes
2088 fg_full = context->colors[fg + 16 + MODE4_OFFSET]; 2088 fg_full = context->colors[fg + 16 + MODE4_OFFSET];
2089 bg_full = context->colors[bg + 16 + MODE4_OFFSET]; 2089 bg_full = context->colors[bg + 16 + MODE4_OFFSET];
2090 } else { 2090 } else {
2108 } 2108 }
2109 if ( 2109 if (
2110 context->enabled_debuggers & (1 << DEBUG_COMPOSITE) 2110 context->enabled_debuggers & (1 << DEBUG_COMPOSITE)
2111 && line < (context->inactive_start + context->border_bot + context->border_top) 2111 && line < (context->inactive_start + context->border_bot + context->border_top)
2112 ) { 2112 ) {
2113 uint32_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(uint32_t); 2113 pixel_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(pixel_t);
2114 if (is_mode_5) { 2114 if (is_mode_5) {
2115 uint32_t left, right; 2115 uint32_t left, right;
2116 uint16_t top_line, bottom_line; 2116 uint16_t top_line, bottom_line;
2117 if (context->window_v_latch & WINDOW_DOWN) { 2117 if (context->window_v_latch & WINDOW_DOWN) {
2118 top_line = ((context->window_v_latch & 0x1F) << 3) + context->border_top; 2118 top_line = ((context->window_v_latch & 0x1F) << 3) + context->border_top;
2173 context->pending_hint_start = context->cycles; 2173 context->pending_hint_start = context->cycles;
2174 context->hint_counter = context->regs[REG_HINT]; 2174 context->hint_counter = context->regs[REG_HINT];
2175 } 2175 }
2176 } 2176 }
2177 2177
2178 static void vram_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) 2178 static void vram_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context)
2179 { 2179 {
2180 uint8_t pal = (context->debug_modes[DEBUG_VRAM] % 4) << 4; 2180 uint8_t pal = (context->debug_modes[DEBUG_VRAM] % 4) << 4;
2181 int yshift, ymask, tilesize; 2181 int yshift, ymask, tilesize;
2182 if (context->double_res) { 2182 if (context->double_res) {
2183 yshift = 5; 2183 yshift = 5;
2188 ymask = 0x7; 2188 ymask = 0x7;
2189 tilesize = 32; 2189 tilesize = 32;
2190 } 2190 }
2191 for (int y = 0; y < 512; y++) 2191 for (int y = 0; y < 512; y++)
2192 { 2192 {
2193 uint32_t *line = fb + y * pitch / sizeof(uint32_t); 2193 pixel_t *line = fb + y * pitch / sizeof(pixel_t);
2194 int row = y >> yshift; 2194 int row = y >> yshift;
2195 int yoff = y >> 1 & ymask; 2195 int yoff = y >> 1 & ymask;
2196 for (int col = 0; col < 64; col++) 2196 for (int col = 0; col < 64; col++)
2197 { 2197 {
2198 uint16_t address = (row * 64 + col) * tilesize + yoff * 4; 2198 uint16_t address = (row * 64 + col) * tilesize + yoff * 4;
2208 } 2208 }
2209 } 2209 }
2210 } 2210 }
2211 } 2211 }
2212 2212
2213 static void vram_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) 2213 static void vram_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context)
2214 { 2214 {
2215 for (int y = 0; y < 256; y++) 2215 for (int y = 0; y < 256; y++)
2216 { 2216 {
2217 uint32_t *line = fb + y * pitch / sizeof(uint32_t); 2217 pixel_t *line = fb + y * pitch / sizeof(pixel_t);
2218 int row = y >> 4; 2218 int row = y >> 4;
2219 int yoff = y >> 1 & 7; 2219 int yoff = y >> 1 & 7;
2220 for (int col = 0; col < 64; col++) 2220 for (int col = 0; col < 64; col++)
2221 { 2221 {
2222 uint8_t pal = (col >= 32) << 4; 2222 uint8_t pal = (col >= 32) << 4;
2235 } 2235 }
2236 } 2236 }
2237 } 2237 }
2238 } 2238 }
2239 2239
2240 static void vram_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) 2240 static void vram_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context)
2241 { 2241 {
2242 uint8_t pal = ((context->debug_modes[DEBUG_VRAM] % 14) + 2) << 1; 2242 uint8_t pal = ((context->debug_modes[DEBUG_VRAM] % 14) + 2) << 1;
2243 pal = (pal & 0xE) | (pal << 1 & 0x20); 2243 pal = (pal & 0xE) | (pal << 1 & 0x20);
2244 for (int y = 0; y < 512; y++) 2244 for (int y = 0; y < 512; y++)
2245 { 2245 {
2246 uint32_t *line = fb + y * pitch / sizeof(uint32_t); 2246 pixel_t *line = fb + y * pitch / sizeof(pixel_t);
2247 int row = y >> 4; 2247 int row = y >> 4;
2248 int yoff = y >> 1 & 7; 2248 int yoff = y >> 1 & 7;
2249 for (int col = 0; col < 64; col++) 2249 for (int col = 0; col < 64; col++)
2250 { 2250 {
2251 uint16_t address = (row * 64 + col) * 8 + yoff; 2251 uint16_t address = (row * 64 + col) * 8 + yoff;
2259 } 2259 }
2260 } 2260 }
2261 } 2261 }
2262 } 2262 }
2263 2263
2264 static void plane_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) 2264 static void plane_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context)
2265 { 2265 {
2266 uint16_t hscroll_mask; 2266 uint16_t hscroll_mask;
2267 uint16_t v_mul; 2267 uint16_t v_mul;
2268 uint16_t vscroll_mask = 0x1F | (context->regs[REG_SCROLL] & 0x30) << 1; 2268 uint16_t vscroll_mask = 0x1F | (context->regs[REG_SCROLL] & 0x30) << 1;
2269 switch(context->regs[REG_SCROLL] & 0x3) 2269 switch(context->regs[REG_SCROLL] & 0x3)
2307 hscroll_mask = 0x1F; 2307 hscroll_mask = 0x1F;
2308 } 2308 }
2309 vscroll_mask = 0x1F; 2309 vscroll_mask = 0x1F;
2310 break; 2310 break;
2311 } 2311 }
2312 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 2312 pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
2313 uint16_t num_rows; 2313 uint16_t num_rows;
2314 int num_lines; 2314 int num_lines;
2315 if (context->double_res) { 2315 if (context->double_res) {
2316 num_rows = 64; 2316 num_rows = 64;
2317 num_lines = 16; 2317 num_lines = 16;
2328 //pccv hnnn nnnn nnnn 2328 //pccv hnnn nnnn nnnn
2329 // 2329 //
2330 uint16_t entry = context->vdpmem[address] << 8 | context->vdpmem[address + 1]; 2330 uint16_t entry = context->vdpmem[address] << 8 | context->vdpmem[address + 1];
2331 uint8_t pal = entry >> 9 & 0x30; 2331 uint8_t pal = entry >> 9 & 0x30;
2332 2332
2333 uint32_t *dst = fb + (row * pitch * num_lines / sizeof(uint32_t)) + col * 8; 2333 pixel_t *dst = fb + (row * pitch * num_lines / sizeof(pixel_t)) + col * 8;
2334 if (context->double_res) { 2334 if (context->double_res) {
2335 address = (entry & 0x3FF) * 64; 2335 address = (entry & 0x3FF) * 64;
2336 } else { 2336 } else {
2337 address = (entry & 0x7FF) * 32; 2337 address = (entry & 0x7FF) * 32;
2338 } 2338 }
2347 address += 3; 2347 address += 3;
2348 } 2348 }
2349 for (int y = 0; y < num_lines; y++) 2349 for (int y = 0; y < num_lines; y++)
2350 { 2350 {
2351 uint16_t trow_address = address; 2351 uint16_t trow_address = address;
2352 uint32_t *row_dst = dst; 2352 pixel_t *row_dst = dst;
2353 for (int x = 0; x < 4; x++) 2353 for (int x = 0; x < 4; x++)
2354 { 2354 {
2355 uint8_t byte = context->vdpmem[trow_address]; 2355 uint8_t byte = context->vdpmem[trow_address];
2356 trow_address += x_diff; 2356 trow_address += x_diff;
2357 uint8_t left, right; 2357 uint8_t left, right;
2364 } 2364 }
2365 *(row_dst++) = left ? context->colors[left|pal] : bg_color; 2365 *(row_dst++) = left ? context->colors[left|pal] : bg_color;
2366 *(row_dst++) = right ? context->colors[right|pal] : bg_color; 2366 *(row_dst++) = right ? context->colors[right|pal] : bg_color;
2367 } 2367 }
2368 address += y_diff; 2368 address += y_diff;
2369 dst += pitch / sizeof(uint32_t); 2369 dst += pitch / sizeof(pixel_t);
2370 } 2370 }
2371 } 2371 }
2372 } 2372 }
2373 } 2373 }
2374 2374
2375 static void sprite_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) 2375 static void sprite_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context)
2376 { 2376 {
2377 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 2377 pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
2378 //clear a single alpha channel bit so we can distinguish between actual bg color and sprite 2378 //clear a single alpha channel bit so we can distinguish between actual bg color and sprite
2379 //pixels that just happen to be the same color 2379 //pixels that just happen to be the same color
2380 bg_color &= 0xFEFFFFFF; 2380 bg_color &= 0xFEFFFFFF;
2381 uint32_t *line = fb; 2381 pixel_t *line = fb;
2382 uint32_t border_line = render_map_color(0, 0, 255); 2382 pixel_t border_line = render_map_color(0, 0, 255);
2383 uint32_t sprite_outline = render_map_color(255, 0, 255); 2383 pixel_t sprite_outline = render_map_color(255, 0, 255);
2384 int right_border = 256 + ((context->h40_lines > context->output_lines / 2) ? 640 : 512); 2384 int right_border = 256 + ((context->h40_lines > context->output_lines / 2) ? 640 : 512);
2385 for (int y = 0; y < 1024; y++) 2385 for (int y = 0; y < 1024; y++)
2386 { 2386 {
2387 uint32_t *cur = line; 2387 pixel_t *cur = line;
2388 if (y != 256 && y != 256+context->inactive_start*2) { 2388 if (y != 256 && y != 256+context->inactive_start*2) {
2389 for (int x = 0; x < 255; x++) 2389 for (int x = 0; x < 255; x++)
2390 { 2390 {
2391 *(cur++) = bg_color; 2391 *(cur++) = bg_color;
2392 } 2392 }
2404 for (int x = 0; x < 1024; x++) 2404 for (int x = 0; x < 1024; x++)
2405 { 2405 {
2406 *(cur++) = border_line; 2406 *(cur++) = border_line;
2407 } 2407 }
2408 } 2408 }
2409 line += pitch / sizeof(uint32_t); 2409 line += pitch / sizeof(pixel_t);
2410 } 2410 }
2411 for (int i = 0, index = 0; i < context->max_sprites_frame; i++) 2411 for (int i = 0, index = 0; i < context->max_sprites_frame; i++)
2412 { 2412 {
2413 uint32_t y = (context->sat_cache[index] & 3) << 8 | context->sat_cache[index + 1]; 2413 uint32_t y = (context->sat_cache[index] & 3) << 8 | context->sat_cache[index + 1];
2414 if (!context->double_res) { 2414 if (!context->double_res) {
2429 } 2429 }
2430 uint8_t pal = (tileinfo >> 9) & 0x30; 2430 uint8_t pal = (tileinfo >> 9) & 0x30;
2431 uint16_t hflip = tileinfo & MAP_BIT_H_FLIP; 2431 uint16_t hflip = tileinfo & MAP_BIT_H_FLIP;
2432 uint16_t vflip = tileinfo & MAP_BIT_V_FLIP; 2432 uint16_t vflip = tileinfo & MAP_BIT_V_FLIP;
2433 uint32_t x = (((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF) * 2; 2433 uint32_t x = (((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF) * 2;
2434 uint32_t *line = fb + y * pitch / sizeof(uint32_t) + x; 2434 pixel_t *line = fb + y * pitch / sizeof(pixel_t) + x;
2435 uint32_t *cur = line; 2435 pixel_t *cur = line;
2436 for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++) 2436 for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++)
2437 { 2437 {
2438 *(cur++) = sprite_outline; 2438 *(cur++) = sprite_outline;
2439 } 2439 }
2440 uint8_t advance_source = 1; 2440 uint8_t advance_source = 1;
2451 tile_addr += col_offset * tile_width + 3; 2451 tile_addr += col_offset * tile_width + 3;
2452 col_offset = -col_offset; 2452 col_offset = -col_offset;
2453 } 2453 }
2454 for (; y < y2; y++) 2454 for (; y < y2; y++)
2455 { 2455 {
2456 line += pitch / sizeof(uint32_t); 2456 line += pitch / sizeof(pixel_t);
2457 cur = line; 2457 cur = line;
2458 *(cur++) = sprite_outline; 2458 *(cur++) = sprite_outline;
2459 uint16_t line_addr = tile_addr; 2459 uint16_t line_addr = tile_addr;
2460 for (uint8_t tx = 0; tx <= tile_width; tx++) 2460 for (uint8_t tx = 0; tx <= tile_width; tx++)
2461 { 2461 {
2462 uint16_t cur_addr = line_addr; 2462 uint16_t cur_addr = line_addr;
2463 for (uint8_t cx = 0; cx < 4; cx++) 2463 for (uint8_t cx = 0; cx < 4; cx++)
2464 { 2464 {
2465 uint8_t pair = context->vdpmem[cur_addr]; 2465 uint8_t pair = context->vdpmem[cur_addr];
2466 uint32_t left, right; 2466 pixel_t left, right;
2467 if (hflip) { 2467 if (hflip) {
2468 right = pair >> 4; 2468 right = pair >> 4;
2469 left = pair & 0xF; 2469 left = pair & 0xF;
2470 cur_addr--; 2470 cur_addr--;
2471 } else { 2471 } else {
2504 tile_addr += line_offset; 2504 tile_addr += line_offset;
2505 } 2505 }
2506 advance_source = !advance_source; 2506 advance_source = !advance_source;
2507 } 2507 }
2508 if (y2 != 1024) { 2508 if (y2 != 1024) {
2509 line += pitch / sizeof(uint32_t); 2509 line += pitch / sizeof(pixel_t);
2510 cur = line; 2510 cur = line;
2511 for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++) 2511 for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++)
2512 { 2512 {
2513 *(cur++) = sprite_outline; 2513 *(cur++) = sprite_outline;
2514 } 2514 }
2518 break; 2518 break;
2519 } 2519 }
2520 } 2520 }
2521 } 2521 }
2522 2522
2523 static void plane_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) 2523 static void plane_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context)
2524 { 2524 {
2525 uint32_t bg_color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; 2525 pixel_t bg_color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];
2526 uint32_t address = (context->regs[REG_SCROLL_A] & 0xE) << 10; 2526 uint32_t address = (context->regs[REG_SCROLL_A] & 0xE) << 10;
2527 for (uint32_t row_address = address, end = address + 32*32*2; row_address < end; row_address += 2 * 32) 2527 for (uint32_t row_address = address, end = address + 32*32*2; row_address < end; row_address += 2 * 32)
2528 { 2528 {
2529 uint32_t *col = fb; 2529 pixel_t *col = fb;
2530 for(uint32_t cur = row_address, row_end = row_address + 2 * 32; cur < row_end; cur += 2) 2530 for(uint32_t cur = row_address, row_end = row_address + 2 * 32; cur < row_end; cur += 2)
2531 { 2531 {
2532 uint32_t mapped = mode4_address_map[cur]; 2532 uint32_t mapped = mode4_address_map[cur];
2533 uint16_t entry = context->vdpmem[mapped] << 8 | context->vdpmem[mapped + 1]; 2533 uint16_t entry = context->vdpmem[mapped] << 8 | context->vdpmem[mapped + 1];
2534 uint32_t tile_address = (entry & 0x1FF) << 5; 2534 uint32_t tile_address = (entry & 0x1FF) << 5;
2549 tile_address += 7*4; 2549 tile_address += 7*4;
2550 tile_inc = -4; 2550 tile_inc = -4;
2551 } else { 2551 } else {
2552 tile_inc = 4; 2552 tile_inc = 4;
2553 } 2553 }
2554 uint32_t *line = col; 2554 pixel_t *line = col;
2555 for (int y = 0; y < 16; y++) 2555 for (int y = 0; y < 16; y++)
2556 { 2556 {
2557 uint32_t first = mode4_address_map[tile_address]; 2557 uint32_t first = mode4_address_map[tile_address];
2558 uint32_t last = mode4_address_map[tile_address + 2]; 2558 uint32_t last = mode4_address_map[tile_address + 2];
2559 uint32_t pixels = planar_to_chunky[context->vdpmem[first]] << 1; 2559 uint32_t pixels = planar_to_chunky[context->vdpmem[first]] << 1;
2560 pixels |= planar_to_chunky[context->vdpmem[first+1]]; 2560 pixels |= planar_to_chunky[context->vdpmem[first+1]];
2561 pixels |= planar_to_chunky[context->vdpmem[last]] << 3; 2561 pixels |= planar_to_chunky[context->vdpmem[last]] << 3;
2562 pixels |= planar_to_chunky[context->vdpmem[last+1]] << 2; 2562 pixels |= planar_to_chunky[context->vdpmem[last+1]] << 2;
2563 uint32_t *out = line; 2563 pixel_t *out = line;
2564 for (uint32_t i = i_init; i != i_limit; i += i_inc) 2564 for (uint32_t i = i_init; i != i_limit; i += i_inc)
2565 { 2565 {
2566 uint32_t pixel = context->colors[((pixels >> i & 0xF) | pal) + MODE4_OFFSET]; 2566 pixel_t pixel = context->colors[((pixels >> i & 0xF) | pal) + MODE4_OFFSET];
2567 *(out++) = pixel; 2567 *(out++) = pixel;
2568 *(out++) = pixel; 2568 *(out++) = pixel;
2569 } 2569 }
2570 2570
2571 2571
2572 if (y & 1) { 2572 if (y & 1) {
2573 tile_address += tile_inc; 2573 tile_address += tile_inc;
2574 } 2574 }
2575 line += pitch / sizeof(uint32_t); 2575 line += pitch / sizeof(pixel_t);
2576 } 2576 }
2577 2577
2578 2578
2579 2579
2580 col += 16; 2580 col += 16;
2581 } 2581 }
2582 fb += 16 * pitch / sizeof(uint32_t); 2582 fb += 16 * pitch / sizeof(pixel_t);
2583 } 2583 }
2584 } 2584 }
2585 2585
2586 static void sprite_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) 2586 static void sprite_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context)
2587 { 2587 {
2588 } 2588 }
2589 2589
2590 uint32_t tms_map_color(vdp_context *context, uint8_t color) 2590 pixel_t tms_map_color(vdp_context *context, uint8_t color)
2591 { 2591 {
2592 if (context->type == VDP_GAMEGEAR) { 2592 if (context->type == VDP_GAMEGEAR) {
2593 //Game Gear uses CRAM entries 16-31 for TMS9918A modes 2593 //Game Gear uses CRAM entries 16-31 for TMS9918A modes
2594 return context->colors[color + 16 + MODE4_OFFSET]; 2594 return context->colors[color + 16 + MODE4_OFFSET];
2595 } else { 2595 } else {
2597 color = (color & 0xE) | (color << 1 & 0x20); 2597 color = (color & 0xE) | (color << 1 & 0x20);
2598 return context->color_map[color | FBUF_TMS]; 2598 return context->color_map[color | FBUF_TMS];
2599 } 2599 }
2600 } 2600 }
2601 2601
2602 static void plane_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) 2602 static void plane_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context)
2603 { 2603 {
2604 uint16_t table_address = context->regs[REG_SCROLL_A] << 10 & 0x3C00; 2604 uint16_t table_address = context->regs[REG_SCROLL_A] << 10 & 0x3C00;
2605 uint16_t color_address = context->regs[REG_COLOR_TABLE] << 6; 2605 uint16_t color_address = context->regs[REG_COLOR_TABLE] << 6;
2606 uint16_t pattern_address = context->regs[REG_PATTERN_GEN] << 11 & 0x3800; 2606 uint16_t pattern_address = context->regs[REG_PATTERN_GEN] << 11 & 0x3800;
2607 uint16_t upper_vcounter_mask; 2607 uint16_t upper_vcounter_mask;
2634 fg = tms_map_color(context, context->regs[REG_BG_COLOR] >> 4); 2634 fg = tms_map_color(context, context->regs[REG_BG_COLOR] >> 4);
2635 bg = tms_map_color(context, context->regs[REG_BG_COLOR] & 0xF); 2635 bg = tms_map_color(context, context->regs[REG_BG_COLOR] & 0xF);
2636 } 2636 }
2637 for (uint32_t row = 0; row < 24; row++) 2637 for (uint32_t row = 0; row < 24; row++)
2638 { 2638 {
2639 uint32_t *colfb = fb; 2639 pixel_t *colfb = fb;
2640 for (uint32_t col = 0; col < cols; col++) 2640 for (uint32_t col = 0; col < cols; col++)
2641 { 2641 {
2642 uint32_t *linefb = colfb; 2642 pixel_t *linefb = colfb;
2643 uint8_t pattern = context->vdpmem[mode4_address_map[table_address] ^ 1]; 2643 uint8_t pattern = context->vdpmem[mode4_address_map[table_address] ^ 1];
2644 uint16_t caddress = color_address; 2644 uint16_t caddress = color_address;
2645 uint16_t paddress = pattern_address; 2645 uint16_t paddress = pattern_address;
2646 if (context->regs[REG_MODE_2] & BIT_M2) { 2646 if (context->regs[REG_MODE_2] & BIT_M2) {
2647 } else { 2647 } else {
2663 uint8_t colors = context->vdpmem[mode4_address_map[caddress] ^ 1]; 2663 uint8_t colors = context->vdpmem[mode4_address_map[caddress] ^ 1];
2664 fg = tms_map_color(context, colors >> 4); 2664 fg = tms_map_color(context, colors >> 4);
2665 bg = tms_map_color(context, colors & 0xF); 2665 bg = tms_map_color(context, colors & 0xF);
2666 } 2666 }
2667 2667
2668 uint32_t *curfb = linefb; 2668 pixel_t *curfb = linefb;
2669 for (uint32_t x = 0; x < pixels; x++) 2669 for (uint32_t x = 0; x < pixels; x++)
2670 { 2670 {
2671 *(curfb++) = (bits & 0x80) ? fg : bg; 2671 *(curfb++) = (bits & 0x80) ? fg : bg;
2672 if (x & 1) { 2672 if (x & 1) {
2673 bits <<= 1; 2673 bits <<= 1;
2674 } 2674 }
2675 } 2675 }
2676 linefb += pitch / sizeof(uint32_t); 2676 linefb += pitch / sizeof(pixel_t);
2677 if (y & 1) { 2677 if (y & 1) {
2678 if (context->regs[REG_MODE_1] & BIT_M3) { 2678 if (context->regs[REG_MODE_1] & BIT_M3) {
2679 caddress++; 2679 caddress++;
2680 } 2680 }
2681 paddress++; 2681 paddress++;
2683 } 2683 }
2684 } 2684 }
2685 table_address++; 2685 table_address++;
2686 colfb += pixels; 2686 colfb += pixels;
2687 } 2687 }
2688 fb += 16 * pitch / sizeof(uint32_t); 2688 fb += 16 * pitch / sizeof(pixel_t);
2689 } 2689 }
2690 } 2690 }
2691 2691
2692 static void sprite_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) 2692 static void sprite_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context)
2693 { 2693 {
2694 } 2694 }
2695 2695
2696 static void vdp_update_per_frame_debug(vdp_context *context) 2696 static void vdp_update_per_frame_debug(vdp_context *context)
2697 { 2697 {
2698 if (context->enabled_debuggers & (1 << DEBUG_PLANE)) { 2698 if (context->enabled_debuggers & (1 << DEBUG_PLANE)) {
2699 2699
2700 uint32_t pitch; 2700 uint32_t pitch;
2701 uint32_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_PLANE], &pitch); 2701 pixel_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_PLANE], &pitch);
2702 if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) { 2702 if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) {
2703 if ((context->debug_modes[DEBUG_PLANE] & 3) == 3) { 2703 if ((context->debug_modes[DEBUG_PLANE] & 3) == 3) {
2704 sprite_debug_mode5(fb, pitch, context); 2704 sprite_debug_mode5(fb, pitch, context);
2705 } else { 2705 } else {
2706 plane_debug_mode5(fb, pitch, context); 2706 plane_debug_mode5(fb, pitch, context);
2721 render_framebuffer_updated(context->debug_fb_indices[DEBUG_PLANE], 1024); 2721 render_framebuffer_updated(context->debug_fb_indices[DEBUG_PLANE], 1024);
2722 } 2722 }
2723 2723
2724 if (context->enabled_debuggers & (1 << DEBUG_VRAM)) { 2724 if (context->enabled_debuggers & (1 << DEBUG_VRAM)) {
2725 uint32_t pitch; 2725 uint32_t pitch;
2726 uint32_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_VRAM], &pitch); 2726 pixel_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_VRAM], &pitch);
2727 if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) { 2727 if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) {
2728 vram_debug_mode5(fb, pitch, context); 2728 vram_debug_mode5(fb, pitch, context);
2729 } else if (context->type != VDP_TMS9918A && (context->regs[REG_MODE_1] & BIT_MODE_4)) { 2729 } else if (context->type != VDP_TMS9918A && (context->regs[REG_MODE_1] & BIT_MODE_4)) {
2730 vram_debug_mode4(fb, pitch, context); 2730 vram_debug_mode4(fb, pitch, context);
2731 } else if (context->type != VDP_GENESIS) { 2731 } else if (context->type != VDP_GENESIS) {
2734 render_framebuffer_updated(context->debug_fb_indices[DEBUG_VRAM], 1024); 2734 render_framebuffer_updated(context->debug_fb_indices[DEBUG_VRAM], 1024);
2735 } 2735 }
2736 2736
2737 if (context->enabled_debuggers & (1 << DEBUG_CRAM)) { 2737 if (context->enabled_debuggers & (1 << DEBUG_CRAM)) {
2738 uint32_t starting_line = 512 - 32*4; 2738 uint32_t starting_line = 512 - 32*4;
2739 uint32_t *line = context->debug_fbs[DEBUG_CRAM] 2739 pixel_t *line = context->debug_fbs[DEBUG_CRAM]
2740 + context->debug_fb_pitch[DEBUG_CRAM] * starting_line / sizeof(uint32_t); 2740 + context->debug_fb_pitch[DEBUG_CRAM] * starting_line / sizeof(pixel_t);
2741 pixel_t black = render_map_color(0, 0, 0);
2741 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 2742 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
2742 for (int pal = 0; pal < 4; pal ++) 2743 for (int pal = 0; pal < 4; pal ++)
2743 { 2744 {
2744 uint32_t *cur; 2745 pixel_t *cur;
2745 for (int y = 0; y < 31; y++) 2746 for (int y = 0; y < 31; y++)
2746 { 2747 {
2747 cur = line; 2748 cur = line;
2748 for (int offset = 0; offset < 16; offset++) 2749 for (int offset = 0; offset < 16; offset++)
2749 { 2750 {
2750 for (int x = 0; x < 31; x++) 2751 for (int x = 0; x < 31; x++)
2751 { 2752 {
2752 *(cur++) = context->colors[pal * 16 + offset]; 2753 *(cur++) = context->colors[pal * 16 + offset];
2753 } 2754 }
2754 *(cur++) = 0xFF000000; 2755 *(cur++) = black;
2755 } 2756 }
2756 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); 2757 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t);
2757 } 2758 }
2758 cur = line; 2759 cur = line;
2759 for (int x = 0; x < 512; x++) 2760 for (int x = 0; x < 512; x++)
2760 { 2761 {
2761 *(cur++) = 0xFF000000; 2762 *(cur++) = black;
2762 } 2763 }
2763 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); 2764 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t);
2764 } 2765 }
2765 } else { 2766 } else {
2766 for (int pal = 0; pal < 2; pal ++) 2767 for (int pal = 0; pal < 2; pal ++)
2767 { 2768 {
2768 uint32_t *cur; 2769 pixel_t *cur;
2769 for (int y = 0; y < 31; y++) 2770 for (int y = 0; y < 31; y++)
2770 { 2771 {
2771 cur = line; 2772 cur = line;
2772 for (int offset = MODE4_OFFSET; offset < MODE4_OFFSET + 16; offset++) 2773 for (int offset = MODE4_OFFSET; offset < MODE4_OFFSET + 16; offset++)
2773 { 2774 {
2774 for (int x = 0; x < 31; x++) 2775 for (int x = 0; x < 31; x++)
2775 { 2776 {
2776 *(cur++) = context->colors[pal * 16 + offset]; 2777 *(cur++) = context->colors[pal * 16 + offset];
2777 } 2778 }
2778 *(cur++) = 0xFF000000; 2779 *(cur++) = black;
2779 } 2780 }
2780 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); 2781 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t);
2781 } 2782 }
2782 cur = line; 2783 cur = line;
2783 for (int x = 0; x < 512; x++) 2784 for (int x = 0; x < 512; x++)
2784 { 2785 {
2785 *(cur++) = 0xFF000000; 2786 *(cur++) = black;
2786 } 2787 }
2787 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); 2788 line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t);
2788 } 2789 }
2789 } 2790 }
2790 render_framebuffer_updated(context->debug_fb_indices[DEBUG_CRAM], 512); 2791 render_framebuffer_updated(context->debug_fb_indices[DEBUG_CRAM], 512);
2791 context->debug_fbs[DEBUG_CRAM] = render_get_framebuffer(context->debug_fb_indices[DEBUG_CRAM], &context->debug_fb_pitch[DEBUG_CRAM]); 2792 context->debug_fbs[DEBUG_CRAM] = render_get_framebuffer(context->debug_fb_indices[DEBUG_CRAM], &context->debug_fb_pitch[DEBUG_CRAM]);
2792 } 2793 }
2867 } 2868 }
2868 if (!context->fb) { 2869 if (!context->fb) {
2869 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); 2870 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch);
2870 } 2871 }
2871 output_line += context->top_offset; 2872 output_line += context->top_offset;
2872 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); 2873 context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * output_line);
2873 #ifdef DEBUG_FB_FILL 2874 #ifdef DEBUG_FB_FILL
2874 for (int i = 0; i < LINEBUF_SIZE; i++) 2875 for (int i = 0; i < LINEBUF_SIZE; i++)
2875 { 2876 {
2876 context->output[i] = 0xFFFF00FF; 2877 context->output[i] = 0xFFFF00FF;
2877 } 2878 }
2892 void vdp_reacquire_framebuffer(vdp_context *context) 2893 void vdp_reacquire_framebuffer(vdp_context *context)
2893 { 2894 {
2894 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; 2895 uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top;
2895 if (context->output_lines <= lines_max && context->output_lines > 0) { 2896 if (context->output_lines <= lines_max && context->output_lines > 0) {
2896 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); 2897 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch);
2897 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset)); 2898 context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset));
2898 } else { 2899 } else {
2899 context->output = NULL; 2900 context->output = NULL;
2900 } 2901 }
2901 } 2902 }
2902 2903
2963 2964
2964 #define CHECK_ONLY if (context->cycles >= target_cycles) { return; } 2965 #define CHECK_ONLY if (context->cycles >= target_cycles) { return; }
2965 #define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY 2966 #define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY
2966 #define OUTPUT_PIXEL(slot) if ((slot) >= BG_START_SLOT) {\ 2967 #define OUTPUT_PIXEL(slot) if ((slot) >= BG_START_SLOT) {\
2967 uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\ 2968 uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\
2968 uint32_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ 2969 pixel_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\
2969 if ((*src & 0x3F) | test_layer) {\ 2970 if ((*src & 0x3F) | test_layer) {\
2970 *(dst++) = context->colors[*(src++)];\ 2971 *(dst++) = context->colors[*(src++)];\
2971 } else {\ 2972 } else {\
2972 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\ 2973 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\
2973 }\ 2974 }\
2978 }\ 2979 }\
2979 } 2980 }
2980 2981
2981 #define OUTPUT_PIXEL_H40(slot) if (slot <= (BG_START_SLOT + LINEBUF_SIZE/2)) {\ 2982 #define OUTPUT_PIXEL_H40(slot) if (slot <= (BG_START_SLOT + LINEBUF_SIZE/2)) {\
2982 uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\ 2983 uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\
2983 uint32_t *dst = context->output + (slot - BG_START_SLOT) *2;\ 2984 pixel_t *dst = context->output + (slot - BG_START_SLOT) *2;\
2984 if ((*src & 0x3F) | test_layer) {\ 2985 if ((*src & 0x3F) | test_layer) {\
2985 *(dst++) = context->colors[*(src++)];\ 2986 *(dst++) = context->colors[*(src++)];\
2986 } else {\ 2987 } else {\
2987 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\ 2988 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\
2988 }\ 2989 }\
2997 }\ 2998 }\
2998 } 2999 }
2999 3000
3000 #define OUTPUT_PIXEL_H32(slot) if (slot <= (BG_START_SLOT + (256+HORIZ_BORDER)/2)) {\ 3001 #define OUTPUT_PIXEL_H32(slot) if (slot <= (BG_START_SLOT + (256+HORIZ_BORDER)/2)) {\
3001 uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\ 3002 uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\
3002 uint32_t *dst = context->output + (slot - BG_START_SLOT) *2;\ 3003 pixel_t *dst = context->output + (slot - BG_START_SLOT) *2;\
3003 if ((*src & 0x3F) | test_layer) {\ 3004 if ((*src & 0x3F) | test_layer) {\
3004 *(dst++) = context->colors[*(src++)];\ 3005 *(dst++) = context->colors[*(src++)];\
3005 } else {\ 3006 } else {\
3006 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\ 3007 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\
3007 }\ 3008 }\
3018 3019
3019 //BG_START_SLOT => dst = 0, src = border 3020 //BG_START_SLOT => dst = 0, src = border
3020 //BG_START_SLOT + 13/2=6, dst = 6, src = border + comp + 13 3021 //BG_START_SLOT + 13/2=6, dst = 6, src = border + comp + 13
3021 #define OUTPUT_PIXEL_MODE4(slot) if ((slot) >= BG_START_SLOT) {\ 3022 #define OUTPUT_PIXEL_MODE4(slot) if ((slot) >= BG_START_SLOT) {\
3022 uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\ 3023 uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\
3023 uint32_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ 3024 pixel_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\
3024 if ((slot) - BG_START_SLOT < BORDER_LEFT/2) {\ 3025 if ((slot) - BG_START_SLOT < BORDER_LEFT/2) {\
3025 *(dst++) = context->colors[bgindex];\ 3026 *(dst++) = context->colors[bgindex];\
3026 *(dst++) = context->colors[bgindex];\ 3027 *(dst++) = context->colors[bgindex];\
3027 } else if ((slot) - BG_START_SLOT < (BORDER_LEFT+256)/2){\ 3028 } else if ((slot) - BG_START_SLOT < (BORDER_LEFT+256)/2){\
3028 if ((slot) - BG_START_SLOT == BORDER_LEFT/2) {\ 3029 if ((slot) - BG_START_SLOT == BORDER_LEFT/2) {\
3267 case CALC_SLOT(slot, 5):\ 3268 case CALC_SLOT(slot, 5):\
3268 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 5))\ 3269 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 5))\
3269 render_sprite_cells_mode4(context);\ 3270 render_sprite_cells_mode4(context);\
3270 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 5)) 3271 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 5))
3271 3272
3272 static uint32_t dummy_buffer[LINEBUF_SIZE]; 3273 static pixel_t dummy_buffer[LINEBUF_SIZE];
3273 static void vdp_h40_line(vdp_context * context) 3274 static void vdp_h40_line(vdp_context * context)
3274 { 3275 {
3275 uint16_t address; 3276 uint16_t address;
3276 uint32_t mask; 3277 uint32_t mask;
3277 uint32_t const slot_cycles = MCLKS_SLOT_H40; 3278 uint32_t const slot_cycles = MCLKS_SLOT_H40;
3312 ); 3313 );
3313 scan_sprite_table(context->vcounter, context); 3314 scan_sprite_table(context->vcounter, context);
3314 3315
3315 //Do palette lookup for end of previous line 3316 //Do palette lookup for end of previous line
3316 uint8_t *src = context->compositebuf + (LINE_CHANGE_H40 - BG_START_SLOT) *2; 3317 uint8_t *src = context->compositebuf + (LINE_CHANGE_H40 - BG_START_SLOT) *2;
3317 uint32_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2; 3318 pixel_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2;
3318 if (context->output) { 3319 if (context->output) {
3319 if (test_layer) { 3320 if (test_layer) {
3320 for (int i = 0; i < LINEBUF_SIZE - (LINE_CHANGE_H40 - BG_START_SLOT) * 2; i++) 3321 for (int i = 0; i < LINEBUF_SIZE - (LINE_CHANGE_H40 - BG_START_SLOT) * 2; i++)
3321 { 3322 {
3322 *(dst++) = context->colors[*(src++)]; 3323 *(dst++) = context->colors[*(src++)];
4290 } 4291 }
4291 if (!context->output) { 4292 if (!context->output) {
4292 return; 4293 return;
4293 } 4294 }
4294 } 4295 }
4295 uint32_t color; 4296 pixel_t color;
4296 if (context->type == VDP_GAMEGEAR) { 4297 if (context->type == VDP_GAMEGEAR) {
4297 //Game Gear uses CRAM entries 16-31 for TMS9918A modes 4298 //Game Gear uses CRAM entries 16-31 for TMS9918A modes
4298 color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + 16 + MODE4_OFFSET]; 4299 color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + 16 + MODE4_OFFSET];
4299 } else { 4300 } else {
4300 color = context->regs[REG_BG_COLOR] << 1 & 0x1E; 4301 color = context->regs[REG_BG_COLOR] << 1 & 0x1E;
4799 } else { 4800 } else {
4800 //never active unless either mode 4 or mode 5 is turned on 4801 //never active unless either mode 4 or mode 5 is turned on
4801 active_line = 0x200; 4802 active_line = 0x200;
4802 } 4803 }
4803 } 4804 }
4804 uint32_t *dst; 4805 pixel_t *dst;
4805 uint8_t *debug_dst; 4806 uint8_t *debug_dst;
4806 if (context->output && context->hslot >= BG_START_SLOT && context->hslot <= bg_end_slot) { 4807 if (context->output && context->hslot >= BG_START_SLOT && context->hslot <= bg_end_slot) {
4807 dst = context->output + 2 * (context->hslot - BG_START_SLOT); 4808 dst = context->output + 2 * (context->hslot - BG_START_SLOT);
4808 debug_dst = context->layer_debug_buf + 2 * (context->hslot - BG_START_SLOT); 4809 debug_dst = context->layer_debug_buf + 2 * (context->hslot - BG_START_SLOT);
4809 } else { 4810 } else {
4871 context->flags2 ^= FLAG2_EVEN_FIELD; 4872 context->flags2 ^= FLAG2_EVEN_FIELD;
4872 } 4873 }
4873 4874
4874 if (dst) { 4875 if (dst) {
4875 uint8_t bg_index; 4876 uint8_t bg_index;
4876 uint32_t bg_color; 4877 pixel_t bg_color;
4877 if (mode_5) { 4878 if (mode_5) {
4878 bg_index = context->regs[REG_BG_COLOR] & 0x3F; 4879 bg_index = context->regs[REG_BG_COLOR] & 0x3F;
4879 bg_color = context->colors[bg_index]; 4880 bg_color = context->colors[bg_index];
4880 } else if ((context->regs[REG_MODE_1] & BIT_MODE_4) || context->type != VDP_GENESIS) { 4881 } else if ((context->regs[REG_MODE_1] & BIT_MODE_4) || context->type != VDP_GENESIS) {
4881 bg_index = 0x10 + (context->regs[REG_BG_COLOR] & 0xF); 4882 bg_index = 0x10 + (context->regs[REG_BG_COLOR] & 0xF);