comparison lc8951.c @ 2419:0871f555eff6

Fix some CD-ROM emulation issues and make timing better match my MCD2. Seems to fix or at least improve video playback in Iron Helix and Power Rangers
author Michael Pavone <pavone@retrodev.com>
date Thu, 18 Jan 2024 23:03:58 -0800
parents f8b5142c06aa
children
comparison
equal deleted inserted replaced
2418:cc07f544c620 2419:0871f555eff6
54 #define BIT_DTEN 0x02 54 #define BIT_DTEN 0x02
55 #define BIT_STEN 0x01 55 #define BIT_STEN 0x01
56 56
57 //CTRL0 57 //CTRL0
58 #define BIT_DECEN 0x80 58 #define BIT_DECEN 0x80
59 #define BIT_EDCRQ 0x40
59 #define BIT_WRRQ 0x04 60 #define BIT_WRRQ 0x04
60 #define BIT_ORQ 0x02 61 #define BIT_ORQ 0x02
61 #define BIT_PRQ 0x01 62 #define BIT_PRQ 0x01
62 63
63 //CTRL1 64 //CTRL1
238 context->regs[STAT3] &= ~BIT_VALST; 239 context->regs[STAT3] &= ~BIT_VALST;
239 if (context->ctrl0 & BIT_WRRQ) { 240 if (context->ctrl0 & BIT_WRRQ) {
240 uint16_t block_start = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer)-1); 241 uint16_t block_start = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer)-1);
241 for (int reg = HEAD0; reg < PTL; reg++) 242 for (int reg = HEAD0; reg < PTL; reg++)
242 { 243 {
244 printf("Setting header reg %X to %X: %X\n", reg, block_start, context->buffer[block_start]);
243 context->regs[reg] =context->buffer[block_start++]; 245 context->regs[reg] =context->buffer[block_start++];
244 block_start &= (sizeof(context->buffer)-1); 246 block_start &= (sizeof(context->buffer)-1);
245 } 247 }
246 } 248 }
247 printf("Decode done %X:%X:%X mode %X\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2], context->regs[HEAD3]); 249 printf("Decode done %X:%X:%X mode %X @ %u\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2], context->regs[HEAD3], context->cycle);
248 // This check is a hack until I properly implement error detection 250 // This check is a hack until I properly implement error detection
249 if (context->regs[HEAD0] < 0x74 && (context->regs[HEAD0] & 0xF) < 0xA 251 if (context->regs[HEAD0] < 0x74 && (context->regs[HEAD0] & 0xF) < 0xA
250 && context->regs[HEAD1] < 0x60 && (context->regs[HEAD1] & 0xF) < 0xA 252 && context->regs[HEAD1] < 0x60 && (context->regs[HEAD1] & 0xF) < 0xA
251 && context->regs[HEAD2] < 0x75 && (context->regs[HEAD2] & 0xF) < 0xA 253 && context->regs[HEAD2] < 0x75 && (context->regs[HEAD2] & 0xF) < 0xA
252 && context->regs[HEAD3] < 3 && !(context->regs[STAT0] & (BIT_NOSYNC|BIT_ILSYNC)) 254 && context->regs[HEAD3] < 3 && !(context->regs[STAT0] & (BIT_NOSYNC|BIT_ILSYNC))
256 context->regs[STAT0] |= BIT_CRCOK; 258 context->regs[STAT0] |= BIT_CRCOK;
257 } 259 }
258 context->regs[STAT1] = 0; 260 context->regs[STAT1] = 0;
259 context->regs[STAT2] = 0x10; 261 context->regs[STAT2] = 0x10;
260 } else { 262 } else {
261 if (context->ctrl0 & (BIT_WRRQ|BIT_ORQ|BIT_PRQ)) { 263 if (context->ctrl0 & (BIT_EDCRQ|BIT_ORQ|BIT_PRQ)) {
262 context->regs[STAT0] |= BIT_UCEBLK; 264 context->regs[STAT0] |= BIT_UCEBLK;
263 } 265 }
264 context->regs[STAT1] = 0xFF; 266 context->regs[STAT1] = 0xFF;
265 context->regs[STAT2] = 0xF2; 267 context->regs[STAT2] = 0xF2;
266 } 268 }
339 if (context->sector_counter < 4) { 341 if (context->sector_counter < 4) {
340 //TODO: Handle SHDREN = 1 342 //TODO: Handle SHDREN = 1
341 if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) { 343 if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) {
342 //monitor only mode 344 //monitor only mode
343 context->regs[HEAD0 + context->sector_counter] = byte; 345 context->regs[HEAD0 + context->sector_counter] = byte;
344 } 346 if (context->sector_counter == 3) {
347 printf("Monitoring sector %02d:%02d:%02d\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2]);
348 }
349 } else {
350 if (context->sector_counter == 3) {
351 printf("Writing sector %02d:%02d:%02d @ %u\n",
352 context->buffer[(current_write_addr - 3) & (sizeof(context->buffer)-1)],
353 context->buffer[(current_write_addr - 2) & (sizeof(context->buffer)-1)],
354 context->buffer[(current_write_addr - 1) & (sizeof(context->buffer)-1)],
355 context->cycle);
356 }
357 }
358
345 } 359 }
346 360
347 if (sync_detected || sync_inserted) { 361 if (sync_detected || sync_inserted) {
348 //we've recevied the sync pattern for the next block 362 //we've recevied the sync pattern for the next block
349 context->regs[STAT0] &= ~(BIT_ILSYNC | BIT_NOSYNC | BIT_LBLK | BIT_SBLK); 363 context->regs[STAT0] &= ~(BIT_ILSYNC | BIT_NOSYNC | BIT_LBLK | BIT_SBLK);
367 if (context->ctrl0 & BIT_WRRQ) { 381 if (context->ctrl0 & BIT_WRRQ) {
368 uint16_t block_start = current_write_addr + 1 - 2352; 382 uint16_t block_start = current_write_addr + 1 - 2352;
369 context->regs[PTL] = block_start; 383 context->regs[PTL] = block_start;
370 context->regs[PTH] = block_start >> 8; 384 context->regs[PTH] = block_start >> 8;
371 } 385 }
372 printf("Decoding block starting at %X (WRRQ: %d, sector_offset: %X)\n", context->regs[PTL] | (context->regs[PTH] << 8), !!(context->ctrl0 & BIT_WRRQ), sector_offset); 386 printf("Decoding block starting at %X (WRRQ: %d, sector_offset: %X), current write address: %X @ %u\n", context->regs[PTL] | (context->regs[PTH] << 8), !!(context->ctrl0 & BIT_WRRQ), sector_offset, current_write_addr, context->cycle);
373 //Based on measurements of a Wondermega M1 (LC8951) with SYDEN, SYIEN and DECEN only 387 //Based on mcd-verificator results on an MCD2 with LC89515
374 context->decode_end = context->cycle + 22030 * context->clock_step; 388 //value seems to be between ~132500 and ~133500
389 context->decode_end = context->cycle + 133000 * context->clock_step;
375 } 390 }
376 } else { 391 } else {
377 context->sector_counter++; 392 context->sector_counter++;
378 context->sector_counter &= 0xFFF; 393 context->sector_counter &= 0xFFF;
379 if (sync_ignored) { 394 if (sync_ignored) {