comparison vdp.c @ 984:bd4d698d995b

FIFO should show as empty during a DMA fill after the initial write is done. BlastEm now gets a perfect score in VDP FIFO Testing
author Michael Pavone <pavone@retrodev.com>
date Sun, 24 Apr 2016 14:30:15 -0700
parents 14d2f3b0e45d
children f9ee6f746cb4
comparison
equal deleted inserted replaced
983:14d2f3b0e45d 984:bd4d698d995b
485 485
486 #define CRAM_BITS 0xEEE 486 #define CRAM_BITS 0xEEE
487 #define VSRAM_BITS 0x7FF 487 #define VSRAM_BITS 0x7FF
488 #define VSRAM_DIRTY_BITS 0xF800 488 #define VSRAM_DIRTY_BITS 0xF800
489 489
490 void vdp_advance_dma(vdp_context * context)
491 {
492 context->regs[REG_DMASRC_L] += 1;
493 if (!context->regs[REG_DMASRC_L]) {
494 context->regs[REG_DMASRC_M] += 1;
495 }
496 context->address += context->regs[REG_AUTOINC];
497 uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1;
498 context->regs[REG_DMALEN_H] = dma_len >> 8;
499 context->regs[REG_DMALEN_L] = dma_len;
500 if (!dma_len) {
501 context->flags &= ~FLAG_DMA_RUN;
502 context->cd &= 0xF;
503 }
504 }
505
490 void external_slot(vdp_context * context) 506 void external_slot(vdp_context * context)
491 { 507 {
508 if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80 && context->fifo_read < 0) {
509 context->fifo_read = (context->fifo_write-1) & (FIFO_SIZE-1);
510 fifo_entry * cur = context->fifo + context->fifo_read;
511 cur->cycle = context->cycles;
512 cur->address = context->address;
513 cur->partial = 2;
514 vdp_advance_dma(context);
515 }
492 fifo_entry * start = context->fifo + context->fifo_read; 516 fifo_entry * start = context->fifo + context->fifo_read;
493 if (context->fifo_read >= 0 && start->cycle <= context->cycles) { 517 if (context->fifo_read >= 0 && start->cycle <= context->cycles) {
494 switch (start->cd & 0xF) 518 switch (start->cd & 0xF)
495 { 519 {
496 case VRAM_WRITE: 520 case VRAM_WRITE:
528 } else if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0xC0) { 552 } else if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0xC0) {
529 if (context->flags & FLAG_READ_FETCHED) { 553 if (context->flags & FLAG_READ_FETCHED) {
530 context->vdpmem[context->address ^ 1] = context->prefetch; 554 context->vdpmem[context->address ^ 1] = context->prefetch;
531 555
532 //Update DMA state 556 //Update DMA state
533 context->regs[REG_DMASRC_L] += 1; 557 vdp_advance_dma(context);
534 if (!context->regs[REG_DMASRC_L]) {
535 context->regs[REG_DMASRC_M] += 1;
536 }
537 context->address += context->regs[REG_AUTOINC];
538 uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1;
539 context->regs[REG_DMALEN_H] = dma_len >> 8;
540 context->regs[REG_DMALEN_L] = dma_len;
541 if (!dma_len) {
542 context->flags &= ~FLAG_DMA_RUN;
543 context->cd &= 0xF;
544 }
545 558
546 context->flags &= ~FLAG_READ_FETCHED; 559 context->flags &= ~FLAG_READ_FETCHED;
547 } else { 560 } else {
548 context->prefetch = context->vdpmem[(context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L] ^ 1]; 561 context->prefetch = context->vdpmem[(context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L] ^ 1];
549 562
596 609
597 void run_dma_src(vdp_context * context, int32_t slot) 610 void run_dma_src(vdp_context * context, int32_t slot)
598 { 611 {
599 //TODO: Figure out what happens if CD bit 4 is not set in DMA copy mode 612 //TODO: Figure out what happens if CD bit 4 is not set in DMA copy mode
600 //TODO: Figure out what happens when CD:0-3 is not set to a write mode in DMA operations 613 //TODO: Figure out what happens when CD:0-3 is not set to a write mode in DMA operations
601 //TODO: Figure out what happens if DMA gets disabled part way through a DMA fill or DMA copy
602 if (context->fifo_write == context->fifo_read) { 614 if (context->fifo_write == context->fifo_read) {
603 return; 615 return;
604 } 616 }
605 fifo_entry * cur = NULL; 617 fifo_entry * cur = NULL;
606 switch(context->regs[REG_DMASRC_H] & 0xC0) 618 if (!(context->regs[REG_DMASRC_H] & 0x80))
607 { 619 {
608 //68K -> VDP 620 //68K -> VDP
609 case 0:
610 case 0x40:
611 if (slot == -1 || !is_refresh(context, slot-1)) { 621 if (slot == -1 || !is_refresh(context, slot-1)) {
612 cur = context->fifo + context->fifo_write; 622 cur = context->fifo + context->fifo_write;
613 cur->cycle = context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)*FIFO_LATENCY; 623 cur->cycle = context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
614 cur->address = context->address; 624 cur->address = context->address;
615 cur->value = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); 625 cur->value = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
617 cur->partial = 0; 627 cur->partial = 0;
618 if (context->fifo_read < 0) { 628 if (context->fifo_read < 0) {
619 context->fifo_read = context->fifo_write; 629 context->fifo_read = context->fifo_write;
620 } 630 }
621 context->fifo_write = (context->fifo_write + 1) & (FIFO_SIZE-1); 631 context->fifo_write = (context->fifo_write + 1) & (FIFO_SIZE-1);
622 } 632 vdp_advance_dma(context);
623 break;
624 //Fill
625 case 0x80:
626 if (context->fifo_read < 0) {
627 context->fifo_read = (context->fifo_write-1) & (FIFO_SIZE-1);
628 cur = context->fifo + context->fifo_read;
629 cur->cycle = context->cycles;
630 cur->address = context->address;
631 cur->partial = 2;
632 }
633 break;
634 }
635
636 if (cur) {
637 context->regs[REG_DMASRC_L] += 1;
638 if (!context->regs[REG_DMASRC_L]) {
639 context->regs[REG_DMASRC_M] += 1;
640 }
641 context->address += context->regs[REG_AUTOINC];
642 uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1;
643 context->regs[REG_DMALEN_H] = dma_len >> 8;
644 context->regs[REG_DMALEN_L] = dma_len;
645 if (!dma_len) {
646 //printf("DMA end at cycle %d, frame: %d, vcounter: %d, hslot: %d\n", context->cycles, context->frame, context->vcounter, context->hslot);
647 context->flags &= ~FLAG_DMA_RUN;
648 context->cd &= 0xF;
649 } 633 }
650 } 634 }
651 } 635 }
652 636
653 #define WINDOW_RIGHT 0x80 637 #define WINDOW_RIGHT 0x80