comparison segacd.c @ 2062:07ed42bd7b4c segacd

Some progress on CDC and CDD emulation. Now passes first 3 "CDC INIT" tests in mcd-verificator
author Michael Pavone <pavone@retrodev.com>
date Fri, 28 Jan 2022 00:50:17 -0800
parents 7c1760b5b3e5
children 02a9846668d1
comparison
equal deleted inserted replaced
2061:7c1760b5b3e5 2062:07ed42bd7b4c
290 cd->timer_pending = 1; 290 cd->timer_pending = 1;
291 } 291 }
292 } 292 }
293 } 293 }
294 294
295 static void cdd_run(segacd_context *cd, uint32_t cycle)
296 {
297 cdd_mcu_run(&cd->cdd, cycle, cd->gate_array + GA_CDD_CTRL, &cd->cdc);
298 lc8951_run(&cd->cdc, cycle);
299 }
300
295 static uint32_t next_timer_int(segacd_context *cd) 301 static uint32_t next_timer_int(segacd_context *cd)
296 { 302 {
297 if (cd->timer_pending) { 303 if (cd->timer_pending) {
298 return cd->stopwatch_cycle; 304 return cd->stopwatch_cycle;
299 } 305 }
309 static void calculate_target_cycle(m68k_context * context) 315 static void calculate_target_cycle(m68k_context * context)
310 { 316 {
311 segacd_context *cd = context->system; 317 segacd_context *cd = context->system;
312 context->int_cycle = CYCLE_NEVER; 318 context->int_cycle = CYCLE_NEVER;
313 uint8_t mask = context->status & 0x7; 319 uint8_t mask = context->status & 0x7;
314 if (mask < 4) { 320 if (mask < 5) {
315 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) { 321 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) {
316 uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle; 322 uint32_t cdc_cycle = lc8951_next_interrupt(&cd->cdc);
317 if (cdd_cycle < context->int_cycle) { 323 if (cdc_cycle < context->int_cycle) {
318 context->int_cycle = cdd_cycle; 324 context->int_cycle = cdc_cycle;
319 context->int_num = 4; 325 context->int_num = 5;
320 } 326 }
321 } 327 }
322 if (mask < 3) { 328 if (mask < 4) {
323 uint32_t next_timer; 329 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) {
324 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) { 330 uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle;
325 uint32_t next_timer_cycle = next_timer_int(cd); 331 if (cdd_cycle < context->int_cycle) {
326 if (next_timer_cycle < context->int_cycle) { 332 context->int_cycle = cdd_cycle;
327 context->int_cycle = next_timer_cycle; 333 context->int_num = 4;
328 context->int_num = 3;
329 } 334 }
330 } 335 }
331 if (mask < 2) { 336 if (mask < 3) {
332 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { 337 uint32_t next_timer;
333 context->int_cycle = cd->int2_cycle; 338 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) {
334 context->int_num = 2; 339 uint32_t next_timer_cycle = next_timer_int(cd);
340 if (next_timer_cycle < context->int_cycle) {
341 context->int_cycle = next_timer_cycle;
342 context->int_num = 3;
343 }
344 }
345 if (mask < 2) {
346 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) {
347 context->int_cycle = cd->int2_cycle;
348 context->int_num = 2;
349 }
335 } 350 }
336 } 351 }
337 } 352 }
338 } 353 }
339 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 354 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
368 case GA_MEM_MODE: 383 case GA_MEM_MODE:
369 return cd->gate_array[reg] & 0xFF1F; 384 return cd->gate_array[reg] & 0xFF1F;
370 case GA_CDC_CTRL: 385 case GA_CDC_CTRL:
371 return cd->gate_array[reg] | cd->cdc.ar; 386 return cd->gate_array[reg] | cd->cdc.ar;
372 case GA_CDC_REG_DATA: 387 case GA_CDC_REG_DATA:
388 cdd_run(cd, m68k->current_cycle);
373 return lc8951_reg_read(&cd->cdc); 389 return lc8951_reg_read(&cd->cdc);
374 case GA_STOP_WATCH: 390 case GA_STOP_WATCH:
375 case GA_TIMER: 391 case GA_TIMER:
376 timers_run(cd, m68k->current_cycle); 392 timers_run(cd, m68k->current_cycle);
377 return cd->gate_array[reg]; 393 return cd->gate_array[reg];
378 case GA_CDD_STATUS0: 394 case GA_CDD_STATUS0:
379 case GA_CDD_STATUS1: 395 case GA_CDD_STATUS1:
380 case GA_CDD_STATUS2: 396 case GA_CDD_STATUS2:
381 case GA_CDD_STATUS3: 397 case GA_CDD_STATUS3:
382 case GA_CDD_STATUS4: 398 case GA_CDD_STATUS4:
383 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); 399 cdd_run(cd, m68k->current_cycle);
384 return cd->gate_array[reg]; 400 return cd->gate_array[reg];
385 break; 401 break;
386 case GA_FONT_DATA0: 402 case GA_FONT_DATA0:
387 case GA_FONT_DATA1: 403 case GA_FONT_DATA1:
388 case GA_FONT_DATA2: 404 case GA_FONT_DATA2:
480 cd->gate_array[reg] &= 0xFFC2; 496 cd->gate_array[reg] &= 0xFFC2;
481 cd->gate_array[reg] |= value & (BIT_RET|BIT_MEM_MODE|MASK_PRIORITY); 497 cd->gate_array[reg] |= value & (BIT_RET|BIT_MEM_MODE|MASK_PRIORITY);
482 break; 498 break;
483 } 499 }
484 case GA_CDC_CTRL: 500 case GA_CDC_CTRL:
501 cdd_run(cd, m68k->current_cycle);
485 lc8951_ar_write(&cd->cdc, value); 502 lc8951_ar_write(&cd->cdc, value);
486 cd->gate_array[reg] &= 0xC000; 503 cd->gate_array[reg] &= 0xC000;
487 cd->gate_array[reg] = value & 0x0700; 504 cd->gate_array[reg] = value & 0x0700;
488 break; 505 break;
489 case GA_CDC_REG_DATA: 506 case GA_CDC_REG_DATA:
507 cdd_run(cd, m68k->current_cycle);
490 lc8951_reg_write(&cd->cdc, value); 508 lc8951_reg_write(&cd->cdc, value);
509 calculate_target_cycle(m68k);
491 break; 510 break;
492 case GA_STOP_WATCH: 511 case GA_STOP_WATCH:
493 //docs say you should only write zero to reset 512 //docs say you should only write zero to reset
494 //mcd-verificator comments suggest any value will reset 513 //mcd-verificator comments suggest any value will reset
495 timers_run(cd, m68k->current_cycle); 514 timers_run(cd, m68k->current_cycle);
518 case GA_INT_MASK: 537 case GA_INT_MASK:
519 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1); 538 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1);
520 calculate_target_cycle(m68k); 539 calculate_target_cycle(m68k);
521 break; 540 break;
522 case GA_CDD_CTRL: { 541 case GA_CDD_CTRL: {
523 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); 542 cdd_run(cd, m68k->current_cycle);
524 uint16_t changed = cd->gate_array[reg] ^ value; 543 uint16_t changed = cd->gate_array[reg] ^ value;
525 cd->gate_array[reg] &= ~BIT_HOCK; 544 cd->gate_array[reg] &= ~BIT_HOCK;
526 cd->gate_array[reg] |= value & BIT_HOCK; 545 cd->gate_array[reg] |= value & BIT_HOCK;
527 if (changed & BIT_HOCK) { 546 if (changed & BIT_HOCK) {
528 if (value & BIT_HOCK) { 547 if (value & BIT_HOCK) {
536 } 555 }
537 case GA_CDD_CMD0: 556 case GA_CDD_CMD0:
538 case GA_CDD_CMD1: 557 case GA_CDD_CMD1:
539 case GA_CDD_CMD2: 558 case GA_CDD_CMD2:
540 case GA_CDD_CMD3: 559 case GA_CDD_CMD3:
541 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); 560 cdd_run(cd, m68k->current_cycle);
542 cd->gate_array[reg] = value & 0x0F0F; 561 cd->gate_array[reg] = value & 0x0F0F;
543 break; 562 break;
544 case GA_CDD_CMD4: 563 case GA_CDD_CMD4:
545 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); 564 cdd_run(cd, m68k->current_cycle);
546 cd->gate_array[reg] = value & 0x0F0F; 565 cd->gate_array[reg] = value & 0x0F0F;
547 cdd_mcu_start_cmd_recv(&cd->cdd, cd->gate_array + GA_CDD_CTRL); 566 cdd_mcu_start_cmd_recv(&cd->cdd, cd->gate_array + GA_CDD_CTRL);
548 break; 567 break;
549 case GA_FONT_COLOR: 568 case GA_FONT_COLOR:
550 cd->gate_array[reg] = value & 0xFF; 569 cd->gate_array[reg] = value & 0xFF;
584 } 603 }
585 return vcontext; 604 return vcontext;
586 case GA_CDD_CMD4: 605 case GA_CDD_CMD4:
587 if (!address) { 606 if (!address) {
588 //byte write to $FF804A should not trigger transfer 607 //byte write to $FF804A should not trigger transfer
589 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); 608 cdd_run(cd, m68k->current_cycle);
590 cd->gate_array[reg] &= 0x0F; 609 cd->gate_array[reg] &= 0x0F;
591 cd->gate_array[reg] |= (value << 8 & 0x0F00); 610 cd->gate_array[reg] |= (value << 8 & 0x0F00);
592 return vcontext; 611 return vcontext;
593 } 612 }
594 //intentional fallthrough for $FF804B 613 //intentional fallthrough for $FF804B
609 } 628 }
610 629
611 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) 630 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle)
612 { 631 {
613 timers_run(cd, cycle); 632 timers_run(cd, cycle);
614 cdd_mcu_run(&cd->cdd, cycle, cd->gate_array + GA_CDD_CTRL); 633 cdd_run(cd, cycle);
615 } 634 }
616 635
617 static m68k_context *sync_components(m68k_context * context, uint32_t address) 636 static m68k_context *sync_components(m68k_context * context, uint32_t address)
618 { 637 {
619 segacd_context *cd = context->system; 638 segacd_context *cd = context->system;