Mercurial > repos > blastem
diff vdp.c @ 470:541c1ae8abf3
Properly delay 68K on VDP reads. Dummy VDP test port implementation. Initial stab at handling undefined bits of VSRAM and CRAM.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 13 Sep 2013 19:22:46 -0700 |
parents | 140af5509ce7 |
children | f065769836e8 |
line wrap: on
line diff
--- a/vdp.c Wed Sep 11 19:26:35 2013 -0700 +++ b/vdp.c Fri Sep 13 19:22:46 2013 -0700 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "vdp.h" @@ -391,15 +391,21 @@ void external_slot(vdp_context * context) { fifo_entry * start = (context->fifo_end - FIFO_SIZE); + if (context->flags2 & FLAG2_READ_PENDING) { + context->flags2 &= ~FLAG2_READ_PENDING; + context->flags |= FLAG_UNUSED_SLOT; + return; + } if (context->fifo_cur != start && start->cycle <= context->cycles) { switch (start->cd & 0xF) { case VRAM_WRITE: if (start->partial) { - //printf("VRAM Write: %X to %X\n", start->value, context->address ^ 1); + printf("VRAM Write: %X to %X at %d (line %d, slot %d)\n", start->value, start->address ^ 1, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16); + context->last_fifo_val = start->value; context->vdpmem[start->address ^ 1] = start->value; } else { - //printf("VRAM Write High: %X to %X\n", start->value >> 8, context->address); + printf("VRAM Write High: %X to %X at %d (line %d, slot %d)\n", start->value >> 8, start->address, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16); context->vdpmem[start->address] = start->value >> 8; start->partial = 1; //skip auto-increment and removal of entry from fifo @@ -409,12 +415,14 @@ case CRAM_WRITE: { //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1)); write_cram(context, start->address, start->value); + context->last_fifo_val = start->value; break; } case VSRAM_WRITE: if (((start->address/2) & 63) < VSRAM_SIZE) { //printf("VSRAM Write: %X to %X\n", start->value, context->address); context->vsram[(start->address/2) & 63] = start->value; + context->last_fifo_val = start->value; } break; @@ -1428,7 +1436,7 @@ int vdp_control_port_write(vdp_context * context, uint16_t value) { - //printf("control port write: %X at %d\n", value, context->cycles); + printf("control port write: %X at %d\n", value, context->cycles); if (context->flags & FLAG_DMA_RUN) { return -1; } @@ -1482,7 +1490,7 @@ int vdp_data_port_write(vdp_context * context, uint16_t value) { - //printf("data port write: %X at %d\n", value, context->cycles); + printf("data port write: %X at %d\n", value, context->cycles); if (context->flags & FLAG_DMA_RUN && (context->regs[REG_DMASRC_H] & 0xC0) != 0x80) { return -1; } @@ -1514,6 +1522,11 @@ return 0; } +void vdp_test_port_write(vdp_context * context, uint16_t value) +{ + //TODO: implement test register +} + uint16_t vdp_control_port_read(vdp_context * context) { context->flags &= ~FLAG_PENDING; @@ -1549,6 +1562,9 @@ return value; } +#define CRAM_BITS 0xEEE +#define VSRAM_BITS 0x3FF + uint16_t vdp_data_port_read(vdp_context * context) { context->flags &= ~FLAG_PENDING; @@ -1557,6 +1573,7 @@ } //Not sure if the FIFO should be drained before processing a read or not, but it would make sense context->flags &= ~FLAG_UNUSED_SLOT; + context->flags2 |= FLAG2_READ_PENDING; while (!(context->flags & FLAG_UNUSED_SLOT)) { vdp_run_context(context, context->cycles + ((context->latched_mode & BIT_H40) ? 16 : 20)); } @@ -1566,17 +1583,20 @@ case VRAM_READ: value = context->vdpmem[context->address] << 8; context->flags &= ~FLAG_UNUSED_SLOT; + context->flags2 |= FLAG2_READ_PENDING; while (!(context->flags & FLAG_UNUSED_SLOT)) { vdp_run_context(context, context->cycles + ((context->latched_mode & BIT_H40) ? 16 : 20)); } value |= context->vdpmem[context->address ^ 1]; break; case CRAM_READ: - value = context->cram[(context->address/2) & (CRAM_SIZE-1)]; + value = context->cram[(context->address/2) & (CRAM_SIZE-1)] & CRAM_BITS; + value |= context->last_fifo_val & ~CRAM_BITS; break; case VSRAM_READ: if (((context->address / 2) & 63) < VSRAM_SIZE) { - value = context->vsram[context->address & 63]; + value = context->vsram[context->address & 63] & VSRAM_BITS; + value |= context->last_fifo_val & ~VSRAM_BITS; } break; } @@ -1693,6 +1713,12 @@ return (line << 8) | linecyc; } +uint16_t vdp_test_port_read(vdp_context * context) +{ + //TODO: Find out what actually gets returned here + return 0xFFFF; +} + void vdp_adjust_cycles(vdp_context * context, uint32_t deduction) { context->cycles -= deduction;