comparison vdp.c @ 2557:75dd7536c467

Apparently window v/h size is latched once per line. Fixes glitch in Landstalker
author Michael Pavone <pavone@retrodev.com>
date Thu, 16 Jan 2025 22:42:09 -0800
parents 61645edbe30f
children e534423bd20d
comparison
equal deleted inserted replaced
2556:6f1eebc0a90b 2557:75dd7536c467
1287 context->vscroll_latch[vsram_off] = context->vsram[column - 2 + vsram_off]; 1287 context->vscroll_latch[vsram_off] = context->vsram[column - 2 + vsram_off];
1288 } 1288 }
1289 } 1289 }
1290 if (!vsram_off) { 1290 if (!vsram_off) {
1291 uint16_t left_col, right_col; 1291 uint16_t left_col, right_col;
1292 if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { 1292 if (context->window_h_latch & WINDOW_RIGHT) {
1293 left_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2 + 2; 1293 left_col = (context->window_h_latch & 0x1F) * 2 + 2;
1294 right_col = 42; 1294 right_col = 42;
1295 } else { 1295 } else {
1296 left_col = 0; 1296 left_col = 0;
1297 right_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2; 1297 right_col = (context->window_h_latch & 0x1F) * 2;
1298 if (right_col) { 1298 if (right_col) {
1299 right_col += 2; 1299 right_col += 2;
1300 } 1300 }
1301 } 1301 }
1302 uint16_t top_line, bottom_line; 1302 uint16_t top_line, bottom_line;
1303 if (context->regs[REG_WINDOW_V] & WINDOW_DOWN) { 1303 if (context->window_v_latch & WINDOW_DOWN) {
1304 top_line = (context->regs[REG_WINDOW_V] & 0x1F) << window_line_shift; 1304 top_line = (context->window_v_latch & 0x1F) << window_line_shift;
1305 bottom_line = context->double_res ? 481 : 241; 1305 bottom_line = context->double_res ? 481 : 241;
1306 } else { 1306 } else {
1307 top_line = 0; 1307 top_line = 0;
1308 bottom_line = (context->regs[REG_WINDOW_V] & 0x1F) << window_line_shift; 1308 bottom_line = (context->window_v_latch & 0x1F) << window_line_shift;
1309 } 1309 }
1310 if ((column >= left_col && column < right_col) || (line >= top_line && line < bottom_line)) { 1310 if ((column >= left_col && column < right_col) || (line >= top_line && line < bottom_line)) {
1311 uint16_t address = context->regs[REG_WINDOW] << 10; 1311 uint16_t address = context->regs[REG_WINDOW] << 10;
1312 uint16_t line_offset, offset, mask; 1312 uint16_t line_offset, offset, mask;
1313 if (context->regs[REG_MODE_4] & BIT_H40) { 1313 if (context->regs[REG_MODE_4] & BIT_H40) {
2098 ) { 2098 ) {
2099 uint32_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(uint32_t); 2099 uint32_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(uint32_t);
2100 if (is_mode_5) { 2100 if (is_mode_5) {
2101 uint32_t left, right; 2101 uint32_t left, right;
2102 uint16_t top_line, bottom_line; 2102 uint16_t top_line, bottom_line;
2103 if (context->regs[REG_WINDOW_V] & WINDOW_DOWN) { 2103 if (context->window_v_latch & WINDOW_DOWN) {
2104 top_line = ((context->regs[REG_WINDOW_V] & 0x1F) << 3) + context->border_top; 2104 top_line = ((context->window_v_latch & 0x1F) << 3) + context->border_top;
2105 bottom_line = context->inactive_start + context->border_top; 2105 bottom_line = context->inactive_start + context->border_top;
2106 } else { 2106 } else {
2107 top_line = context->border_top; 2107 top_line = context->border_top;
2108 bottom_line = ((context->regs[REG_WINDOW_V] & 0x1F) << 3) + context->border_top; 2108 bottom_line = ((context->window_v_latch & 0x1F) << 3) + context->border_top;
2109 } 2109 }
2110 if (line >= top_line && line < bottom_line) { 2110 if (line >= top_line && line < bottom_line) {
2111 left = 0; 2111 left = 0;
2112 right = 320 + BORDER_LEFT + BORDER_RIGHT; 2112 right = 320 + BORDER_LEFT + BORDER_RIGHT;
2113 } else if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { 2113 } else if (context->window_h_latch & WINDOW_RIGHT) {
2114 left = (context->regs[REG_WINDOW_H] & 0x1F) * 16 + BORDER_LEFT; 2114 left = (context->window_h_latch & 0x1F) * 16 + BORDER_LEFT;
2115 right = 320 + BORDER_LEFT + BORDER_RIGHT; 2115 right = 320 + BORDER_LEFT + BORDER_RIGHT;
2116 } else { 2116 } else {
2117 left = 0; 2117 left = 0;
2118 right = (context->regs[REG_WINDOW_H] & 0x1F) * 16 + BORDER_LEFT; 2118 right = (context->window_h_latch & 0x1F) * 16 + BORDER_LEFT;
2119 } 2119 }
2120 for (uint32_t i = left; i < right; i++) 2120 for (uint32_t i = left; i < right; i++)
2121 { 2121 {
2122 uint8_t src = context->layer_debug_buf[i] & DBG_SRC_MASK; 2122 uint8_t src = context->layer_debug_buf[i] & DBG_SRC_MASK;
2123 if (src == DBG_SRC_A) { 2123 if (src == DBG_SRC_A) {
2132 } 2132 }
2133 } 2133 }
2134 } 2134 }
2135 2135
2136 context->vcounter++; 2136 context->vcounter++;
2137 if (is_mode_5) {
2138 context->window_h_latch = context->regs[REG_WINDOW_H];
2139 context->window_v_latch = context->regs[REG_WINDOW_V];
2140 }
2137 if (context->vcounter == jump_start) { 2141 if (context->vcounter == jump_start) {
2138 context->vcounter = jump_end; 2142 context->vcounter = jump_end;
2139 } else { 2143 } else {
2140 context->vcounter &= 0x1FF; 2144 context->vcounter &= 0x1FF;
2141 } 2145 }
5369 context->flags2 &= ~FLAG2_HINT_PENDING; 5373 context->flags2 &= ~FLAG2_HINT_PENDING;
5370 } 5374 }
5371 } 5375 }
5372 } 5376 }
5373 5377
5374 #define VDP_STATE_VERSION 3 5378 #define VDP_STATE_VERSION 4
5375 void vdp_serialize(vdp_context *context, serialize_buffer *buf) 5379 void vdp_serialize(vdp_context *context, serialize_buffer *buf)
5376 { 5380 {
5377 save_int8(buf, VDP_STATE_VERSION); 5381 save_int8(buf, VDP_STATE_VERSION);
5378 save_int8(buf, VRAM_SIZE / 1024);//VRAM size in KB, needed for future proofing 5382 save_int8(buf, VRAM_SIZE / 1024);//VRAM size in KB, needed for future proofing
5379 save_buffer8(buf, context->vdpmem, VRAM_SIZE); 5383 save_buffer8(buf, context->vdpmem, VRAM_SIZE);
5452 save_int32(buf, context->pending_vint_start); 5456 save_int32(buf, context->pending_vint_start);
5453 save_int32(buf, context->pending_hint_start); 5457 save_int32(buf, context->pending_hint_start);
5454 save_int32(buf, context->address_latch); 5458 save_int32(buf, context->address_latch);
5455 //was cd_latch, for compatibility with older builds that expect it 5459 //was cd_latch, for compatibility with older builds that expect it
5456 save_int8(buf, context->cd); 5460 save_int8(buf, context->cd);
5461 save_int8(buf, context->window_h_latch);
5462 save_int8(buf, context->window_v_latch);
5457 } 5463 }
5458 5464
5459 void vdp_deserialize(deserialize_buffer *buf, void *vcontext) 5465 void vdp_deserialize(deserialize_buffer *buf, void *vcontext)
5460 { 5466 {
5461 vdp_context *context = vcontext; 5467 vdp_context *context = vcontext;
5586 load_buffer8(buf, context->linebuf, LINEBUF_SIZE); 5592 load_buffer8(buf, context->linebuf, LINEBUF_SIZE);
5587 5593
5588 context->cycles = load_int32(buf); 5594 context->cycles = load_int32(buf);
5589 context->pending_vint_start = load_int32(buf); 5595 context->pending_vint_start = load_int32(buf);
5590 context->pending_hint_start = load_int32(buf); 5596 context->pending_hint_start = load_int32(buf);
5597 context->window_h_latch = context->regs[REG_WINDOW_H];
5598 context->window_v_latch = context->regs[REG_WINDOW_V];
5591 if (version > 2) { 5599 if (version > 2) {
5592 context->address_latch = load_int32(buf); 5600 context->address_latch = load_int32(buf);
5593 //was cd_latch, no longer used 5601 //was cd_latch, no longer used
5594 load_int8(buf); 5602 load_int8(buf);
5603 if (version > 3) {
5604 context->window_h_latch = load_int8(buf);
5605 context->window_v_latch = load_int8(buf);
5606 }
5595 } else { 5607 } else {
5596 context->address_latch = context->address; 5608 context->address_latch = context->address;
5597 } 5609 }
5598 update_video_params(context); 5610 update_video_params(context);
5599 } 5611 }