comparison vdp.c @ 1149:6b0da6021544

Don't lock up CPU if performing a read with writes configured when in PBC mode. Allow access to VDP debug commands from Z80 debugger in PBC mode. Handle Mode 4 in VDP debug print functions
author Michael Pavone <pavone@retrodev.com>
date Wed, 04 Jan 2017 20:43:22 -0800
parents 25268334a24c
children 322d28e6f13c
comparison
equal deleted inserted replaced
1148:80ef49539550 1149:6b0da6021544
253 } 253 }
254 } 254 }
255 255
256 void vdp_print_sprite_table(vdp_context * context) 256 void vdp_print_sprite_table(vdp_context * context)
257 { 257 {
258 uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9; 258 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
259 uint16_t current_index = 0; 259 uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9;
260 uint8_t count = 0; 260 uint16_t current_index = 0;
261 do { 261 uint8_t count = 0;
262 uint16_t address = current_index * 8 + sat_address; 262 do {
263 uint16_t cache_address = current_index * 4; 263 uint16_t address = current_index * 8 + sat_address;
264 uint8_t height = ((context->sat_cache[cache_address+2] & 0x3) + 1) * 8; 264 uint16_t cache_address = current_index * 4;
265 uint8_t width = (((context->sat_cache[cache_address+2] >> 2) & 0x3) + 1) * 8; 265 uint8_t height = ((context->sat_cache[cache_address+2] & 0x3) + 1) * 8;
266 int16_t y = ((context->sat_cache[cache_address] & 0x3) << 8 | context->sat_cache[cache_address+1]) & 0x1FF; 266 uint8_t width = (((context->sat_cache[cache_address+2] >> 2) & 0x3) + 1) * 8;
267 int16_t x = ((context->vdpmem[address+ 6] & 0x3) << 8 | context->vdpmem[address + 7]) & 0x1FF; 267 int16_t y = ((context->sat_cache[cache_address] & 0x3) << 8 | context->sat_cache[cache_address+1]) & 0x1FF;
268 uint16_t link = context->sat_cache[cache_address+3] & 0x7F; 268 int16_t x = ((context->vdpmem[address+ 6] & 0x3) << 8 | context->vdpmem[address + 7]) & 0x1FF;
269 uint8_t pal = context->vdpmem[address + 4] >> 5 & 0x3; 269 uint16_t link = context->sat_cache[cache_address+3] & 0x7F;
270 uint8_t pri = context->vdpmem[address + 4] >> 7; 270 uint8_t pal = context->vdpmem[address + 4] >> 5 & 0x3;
271 uint16_t pattern = ((context->vdpmem[address + 4] << 8 | context->vdpmem[address + 5]) & 0x7FF) << 5; 271 uint8_t pri = context->vdpmem[address + 4] >> 7;
272 printf("Sprite %d: X=%d(%d), Y=%d(%d), Width=%u, Height=%u, Link=%u, Pal=%u, Pri=%u, Pat=%X\n", current_index, x, x-128, y, y-128, width, height, link, pal, pri, pattern); 272 uint16_t pattern = ((context->vdpmem[address + 4] << 8 | context->vdpmem[address + 5]) & 0x7FF) << 5;
273 current_index = link; 273 printf("Sprite %d: X=%d(%d), Y=%d(%d), Width=%u, Height=%u, Link=%u, Pal=%u, Pri=%u, Pat=%X\n", current_index, x, x-128, y, y-128, width, height, link, pal, pri, pattern);
274 count++; 274 current_index = link;
275 } while (current_index != 0 && count < 80); 275 count++;
276 } while (current_index != 0 && count < 80);
277 } else {
278 uint16_t sat_address = (context->regs[REG_SAT] & 0x7E) << 7;
279 for (int i = 0; i < 64; i++)
280 {
281 uint8_t y = context->vdpmem[sat_address + (i ^ 1)];
282 if (y >= 0xD0) {
283 break;
284 }
285 uint8_t x = context->vdpmem[sat_address + 0x80 + i*2 + 1];
286 uint16_t tile_address = context->vdpmem[sat_address + 0x80 + i*2] * 32
287 + (context->regs[REG_STILE_BASE] << 11 & 0x2000);
288 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) {
289 tile_address &= ~32;
290 }
291 printf("Sprite %d: X=%d, Y=%d, Pat=%X\n", i, x, y, tile_address);
292 }
293 }
276 } 294 }
277 295
278 #define VRAM_READ 0 //0000 296 #define VRAM_READ 0 //0000
279 #define VRAM_WRITE 1 //0001 297 #define VRAM_WRITE 1 //0001
280 //2 would trigger register write 0010 298 //2 would trigger register write 0010
342 context->regs[REG_MODE_2], context->regs[REG_MODE_2] & BIT_DISP_EN ? "enabled" : "disabled", context->regs[REG_MODE_2] & BIT_VINT_EN ? "enabled" : "disabled", 360 context->regs[REG_MODE_2], context->regs[REG_MODE_2] & BIT_DISP_EN ? "enabled" : "disabled", context->regs[REG_MODE_2] & BIT_VINT_EN ? "enabled" : "disabled",
343 context->regs[REG_MODE_2] & BIT_PAL ? 30 : 28, context->regs[REG_MODE_2] & BIT_MODE_5 ? 5 : 4, 361 context->regs[REG_MODE_2] & BIT_PAL ? 30 : 28, context->regs[REG_MODE_2] & BIT_MODE_5 ? 5 : 4,
344 context->regs[REG_MODE_3], context->regs[REG_MODE_3] & BIT_EINT_EN ? "enabled" : "disabled", context->regs[REG_MODE_3] & BIT_VSCROLL ? "2 cell" : "full", 362 context->regs[REG_MODE_3], context->regs[REG_MODE_3] & BIT_EINT_EN ? "enabled" : "disabled", context->regs[REG_MODE_3] & BIT_VSCROLL ? "2 cell" : "full",
345 hscroll[context->regs[REG_MODE_3] & 0x3], 363 hscroll[context->regs[REG_MODE_3] & 0x3],
346 context->regs[REG_MODE_4], context->regs[REG_MODE_4] & BIT_H40 ? 40 : 32, context->regs[REG_MODE_4] & BIT_HILIGHT ? "enabled" : "disabled"); 364 context->regs[REG_MODE_4], context->regs[REG_MODE_4] & BIT_H40 ? 40 : 32, context->regs[REG_MODE_4] & BIT_HILIGHT ? "enabled" : "disabled");
347 printf("\n**Table Group**\n" 365 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
348 "02: %.2X | Scroll A Name Table: $%.4X\n" 366 printf("\n**Table Group**\n"
349 "03: %.2X | Window Name Table: $%.4X\n" 367 "02: %.2X | Scroll A Name Table: $%.4X\n"
350 "04: %.2X | Scroll B Name Table: $%.4X\n" 368 "03: %.2X | Window Name Table: $%.4X\n"
351 "05: %.2X | Sprite Attribute Table: $%.4X\n" 369 "04: %.2X | Scroll B Name Table: $%.4X\n"
352 "0D: %.2X | HScroll Data Table: $%.4X\n", 370 "05: %.2X | Sprite Attribute Table: $%.4X\n"
353 context->regs[REG_SCROLL_A], (context->regs[REG_SCROLL_A] & 0x38) << 10, 371 "0D: %.2X | HScroll Data Table: $%.4X\n",
354 context->regs[REG_WINDOW], (context->regs[REG_WINDOW] & (context->regs[REG_MODE_4] & BIT_H40 ? 0x3C : 0x3E)) << 10, 372 context->regs[REG_SCROLL_A], (context->regs[REG_SCROLL_A] & 0x38) << 10,
355 context->regs[REG_SCROLL_B], (context->regs[REG_SCROLL_B] & 0x7) << 13, 373 context->regs[REG_WINDOW], (context->regs[REG_WINDOW] & (context->regs[REG_MODE_4] & BIT_H40 ? 0x3C : 0x3E)) << 10,
356 context->regs[REG_SAT], (context->regs[REG_SAT] & (context->regs[REG_MODE_4] & BIT_H40 ? 0x7E : 0x7F)) << 9, 374 context->regs[REG_SCROLL_B], (context->regs[REG_SCROLL_B] & 0x7) << 13,
357 context->regs[REG_HSCROLL], (context->regs[REG_HSCROLL] & 0x3F) << 10); 375 context->regs[REG_SAT], (context->regs[REG_SAT] & (context->regs[REG_MODE_4] & BIT_H40 ? 0x7E : 0x7F)) << 9,
376 context->regs[REG_HSCROLL], (context->regs[REG_HSCROLL] & 0x3F) << 10);
377 } else {
378 printf("\n**Table Group**\n"
379 "02: %.2X | Background Name Table: $%.4X\n"
380 "05: %.2X | Sprite Attribute Table: $%.4X\n"
381 "06: %.2X | Sprite Tile Base: $%.4X\n"
382 "08: %.2X | Background X Scroll: %d\n"
383 "09: %.2X | Background Y Scroll: %d\n",
384 context->regs[REG_SCROLL_A], (context->regs[REG_SCROLL_A] & 0xE) << 10,
385 context->regs[REG_SAT], (context->regs[REG_SAT] & 0x7E) << 7,
386 context->regs[REG_STILE_BASE], (context->regs[REG_STILE_BASE] & 2) << 11,
387 context->regs[REG_X_SCROLL], context->regs[REG_X_SCROLL],
388 context->regs[REG_Y_SCROLL], context->regs[REG_Y_SCROLL]);
389
390 }
358 char * sizes[] = {"32", "64", "invalid", "128"}; 391 char * sizes[] = {"32", "64", "invalid", "128"};
359 printf("\n**Misc Group**\n" 392 printf("\n**Misc Group**\n"
360 "07: %.2X | Backdrop Color: $%X\n" 393 "07: %.2X | Backdrop Color: $%X\n"
361 "0A: %.2X | H-Int Counter: %u\n" 394 "0A: %.2X | H-Int Counter: %u\n"
362 "0F: %.2X | Auto-increment: $%X\n" 395 "0F: %.2X | Auto-increment: $%X\n"
2328 //Should this happen after the prefetch or after the read? 2361 //Should this happen after the prefetch or after the read?
2329 context->address += context->regs[REG_AUTOINC]; 2362 context->address += context->regs[REG_AUTOINC];
2330 return context->prefetch; 2363 return context->prefetch;
2331 } 2364 }
2332 2365
2366 uint8_t vdp_data_port_read_pbc(vdp_context * context)
2367 {
2368 if (context->flags & FLAG_PENDING) {
2369 context->flags &= ~FLAG_PENDING;
2370 //Should these be cleared here?
2371 context->flags &= ~FLAG_READ_FETCHED;
2372 context->flags2 &= ~FLAG2_READ_PENDING;
2373 }
2374 context->flags &= ~FLAG_READ_FETCHED;
2375 //Should this happen after the prefetch or after the read?
2376 context->address += context->regs[REG_AUTOINC];
2377 return context->prefetch;
2378 }
2379
2333 uint16_t vdp_hv_counter_read(vdp_context * context) 2380 uint16_t vdp_hv_counter_read(vdp_context * context)
2334 { 2381 {
2335 if ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_1] & BIT_HVC_LATCH)) { 2382 if ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_1] & BIT_HVC_LATCH)) {
2336 return context->hv_latch; 2383 return context->hv_latch;
2337 } 2384 }