Mercurial > repos > blastem
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 } |