changeset 1637:95880d947257

Fix for VRAM byte write order broke VDP FIFO testing ROM results. This change cleans up VRAM writes and fixes the regression while preserving the correct VRAM byte write order
author Michael Pavone <pavone@retrodev.com>
date Sun, 11 Nov 2018 22:39:29 -0800
parents d2775a242dc6
children f27142c48567
files vdp.c
diffstat 1 files changed, 23 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/vdp.c	Sun Nov 11 11:33:38 2018 -0800
+++ b/vdp.c	Sun Nov 11 22:39:29 2018 -0800
@@ -878,14 +878,17 @@
 	context->vdpmem[address] = value;
 }
 
+#define DMA_FILL 0x80
+#define DMA_COPY 0xC0
+#define DMA_TYPE_MASK 0xC0
 static void external_slot(vdp_context * context)
 {
-	if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80 && context->fifo_read < 0) {
+	if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_FILL && context->fifo_read < 0) {
 		context->fifo_read = (context->fifo_write-1) & (FIFO_SIZE-1);
 		fifo_entry * cur = context->fifo + context->fifo_read;
 		cur->cycle = context->cycles;
 		cur->address = context->address;
-		cur->partial = 2;
+		cur->partial = 1;
 		vdp_advance_dma(context);
 	}
 	fifo_entry * start = context->fifo + context->fifo_read;
@@ -896,23 +899,16 @@
 			if ((context->regs[REG_MODE_2] & (BIT_128K_VRAM|BIT_MODE_5)) == (BIT_128K_VRAM|BIT_MODE_5)) {
 				vdp_check_update_sat(context, start->address, start->value);
 				write_vram_word(context, start->address, start->value);
-			} else if (start->partial == 3) {
-				vdp_check_update_sat_byte(context, start->address ^ 1, start->value);
-				write_vram_byte(context, start->address ^ 1, start->value);
-			} else if (start->partial) {
-				//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);
-				uint8_t byte = start->value >> 8;
-				if (start->partial > 1) {
-					vdp_check_update_sat_byte(context, start->address, byte);
+			} else {
+				uint8_t byte = start->partial == 1 ? start->value >> 8 : start->value;
+				vdp_check_update_sat_byte(context, start->address ^ 1, byte);
+				write_vram_byte(context, start->address ^ 1, byte);
+				if (!start->partial) {
+					start->address = start->address ^ 1;
+					start->partial = 1;
+					//skip auto-increment and removal of entry from fifo
+					return;
 				}
-				write_vram_byte(context, start->address, byte);
-			} else {
-				//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);
-				vdp_check_update_sat(context, start->address, start->value);
-				write_vram_byte(context, start->address ^ 1, start->value);
-				start->partial = 1;
-				//skip auto-increment and removal of entry from fifo
-				return;
 			}
 			break;
 		case CRAM_WRITE: {
@@ -927,7 +923,7 @@
 				}
 				write_cram(context, start->address, val);
 			} else {
-				write_cram(context, start->address, start->partial == 2 ? context->fifo[context->fifo_write].value : start->value);
+				write_cram(context, start->address, start->partial ? context->fifo[context->fifo_write].value : start->value);
 			}
 			break;
 		}
@@ -943,7 +939,7 @@
 						context->vsram[(start->address/2) & 63] |= start->value;
 					}
 				} else {
-					context->vsram[(start->address/2) & 63] = start->partial == 2 ? context->fifo[context->fifo_write].value : start->value;
+					context->vsram[(start->address/2) & 63] = start->partial ? context->fifo[context->fifo_write].value : start->value;
 				}
 			}
 
@@ -951,12 +947,12 @@
 		}
 		context->fifo_read = (context->fifo_read+1) & (FIFO_SIZE-1);
 		if (context->fifo_read == context->fifo_write) {
-			if ((context->cd & 0x20) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) {
+			if ((context->cd & 0x20) && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_FILL) {
 				context->flags |= FLAG_DMA_RUN;
 			}
 			context->fifo_read = -1;
 		}
-	} else if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & 0xC0) == 0xC0) {
+	} else if ((context->flags & FLAG_DMA_RUN) && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_COPY) {
 		if (context->flags & FLAG_READ_FETCHED) {
 			write_vram_byte(context, context->address ^ 1, context->prefetch);
 			
@@ -3105,7 +3101,7 @@
 		}
 		uint32_t min_dma_complete = dmalen * (context->regs[REG_MODE_4] & BIT_H40 ? 16 : 20);
 		if (
-			(context->regs[REG_DMASRC_H] & 0xC0) == 0xC0 
+			(context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_COPY 
 			|| (((context->cd & 0xF) == VRAM_WRITE) && !(context->regs[REG_MODE_2] & BIT_128K_VRAM))) {
 			//DMA copies take twice as long to complete since they require a read and a write
 			//DMA Fills and transfers to VRAM also take twice as long as it requires 2 writes for a single word
@@ -3181,7 +3177,7 @@
 		//printf("New Address: %X, New CD: %X\n", context->address, context->cd);
 		if (context->cd & 0x20) {
 			//
-			if((context->regs[REG_DMASRC_H] & 0xC0) != 0x80) {
+			if((context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) != DMA_FILL) {
 				//DMA copy or 68K -> VDP, transfer starts immediately
 				//printf("DMA start (length: %X) at cycle %d, frame: %d, vcounter: %d, hslot: %d\n", (context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L], context->cycles, context->frame, context->vcounter, context->hslot);
 				if (!(context->regs[REG_DMASRC_H] & 0x80)) {
@@ -3262,7 +3258,7 @@
 int vdp_data_port_write(vdp_context * context, uint16_t value)
 {
 	//printf("data port write: %X at %d\n", value, context->cycles);
-	if (context->flags & FLAG_DMA_RUN && (context->regs[REG_DMASRC_H] & 0xC0) != 0x80) {
+	if (context->flags & FLAG_DMA_RUN && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) != DMA_FILL) {
 		return -1;
 	}
 	if (context->flags & FLAG_PENDING) {
@@ -3274,7 +3270,7 @@
 	/*if (context->fifo_cur == context->fifo_end) {
 		printf("FIFO full, waiting for space before next write at cycle %X\n", context->cycles);
 	}*/
-	if (context->cd & 0x20 && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) {
+	if (context->cd & 0x20 && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_FILL) {
 		context->flags &= ~FLAG_DMA_RUN;
 	}
 	while (context->fifo_write == context->fifo_read) {
@@ -3310,7 +3306,7 @@
 	/*if (context->fifo_cur == context->fifo_end) {
 		printf("FIFO full, waiting for space before next write at cycle %X\n", context->cycles);
 	}*/
-	if (context->cd & 0x20 && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) {
+	if (context->cd & 0x20 && (context->regs[REG_DMASRC_H] & DMA_TYPE_MASK) == DMA_FILL) {
 		context->flags &= ~FLAG_DMA_RUN;
 	}
 	while (context->fifo_write == context->fifo_read) {