Mercurial > repos > blastem
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) { |