changeset 19:04fc17376999

Sort of working tile rendering and tile test ROM
author Michael Pavone <pavone@retrodev.com>
date Mon, 28 Mar 2016 23:43:31 -0700
parents cc885122e9e3
children a9364f5ee81a
files src/main.c src/vdp.c src/vdp.h tiletest.s16
diffstat 4 files changed, 152 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/main.c	Sun Mar 27 22:14:26 2016 -0700
+++ b/src/main.c	Mon Mar 28 23:43:31 2016 -0700
@@ -63,7 +63,7 @@
 {
 	console *system = context->system;
 	vdp_run(&system->video, context->cycles);
-	system->video.hscroll = value;
+	vdp_write_hscroll(&system->video, value);
 }
 
 uint16_t horizontal_port_read(cpu *context, uint8_t port)
@@ -111,8 +111,6 @@
 	}
 }
 
-
-
 int main(int argc, char **argv)
 {
 	if (argc < 2) {
--- a/src/vdp.c	Sun Mar 27 22:14:26 2016 -0700
+++ b/src/vdp.c	Mon Mar 28 23:43:31 2016 -0700
@@ -1,5 +1,6 @@
 #include <stdint.h>
 #include <string.h>
+#include <stdio.h>
 #include "vdp.h"
 #include "system.h"
 
@@ -25,7 +26,55 @@
 				context->vcounter = 0;
 			}
 		}
-		//TODO: do rendering stuff here
+		context->status &= ~(VDP_STATUS_VRAM|VDP_STATUS_SRAM);
+		//Render to linebuffer
+		if (context->vcounter > 15 && context->vcounter < 240 && context->hcounter < 406) {
+			if (context->hcounter < 246) {
+				context->status |= VDP_STATUS_VRAM;
+				if (!context->hcounter) {
+					//flip linebuffers
+					if (context->drawbuffer == context->linebuffers) {
+						context->drawbuffer = context->linebuffers + 328;
+						context->readbuffer = context->linebuffers;
+					} else {
+						context->drawbuffer = context->linebuffers;
+						context->readbuffer = context->linebuffers + 328;
+					}
+					context->draw_dest = 0;
+				}
+				if (context->draw_counter) {
+					context->draw_counter--;
+					uint16_t pixels = context->vram[context->draw_source++];
+					for (int i = 0; i < 4; i++)
+					{
+						uint8_t pixel = ((pixels >> ((3-i) * 4)) & 0xF) | context->palpriority;
+						context->drawbuffer[context->draw_dest++] = pixel;
+					}
+				} else {
+					//00VV VVVV VVHH HHHH
+					uint16_t vpos = (context->vscroll & 0x7FF) + context->vcounter - 16;
+					uint16_t vmask = (context->vscroll >> 2) & 0x3E00;
+					uint16_t vcoarse = (vpos << 3) & 0x3FC0;
+					uint16_t vfine = vpos & 7;
+					uint16_t hcoarse = ((context->hscroll >> 3) + context->hcounter/6) & 0x3F;
+					uint16_t tableaddress = hcoarse | (vcoarse & ~vmask) | ((context->vscroll << 3) & vmask);
+					//printf("VCounter: %X, VScroll: %X, HCounter: %X, Table: %X\n", context->vcounter, context->vscroll, context->hcounter, tableaddress);
+					uint16_t entry = context->vram[tableaddress];
+					context->draw_source = (entry & 0x3FF) * 16;
+					if (entry & 0x1000) {
+						context->draw_source += 14 - vfine * 2;
+					} else {
+						context->draw_source += vfine * 2;
+					}
+					context->palpriority = entry >> 9 & 0x70;
+					context->draw_counter = 2;
+					//TODO: handle horizontal flip
+				}
+				//TODO: Scan sprite table
+			} else {
+				//TODO: Render sprites
+			}
+		}
 		//Draw to framebuffer
 		if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) {
 			if (!context->hcounter && context->vcounter == 9) {
@@ -96,3 +145,13 @@
 	context->fifo = value;
 	context->status |= VDP_STATUS_FIFO;
 }
+
+void vdp_write_hscroll(vdp *context, uint16_t value)
+{
+	context->hscroll = value & 0x1FF;
+	if (value & 0x8000) {
+		context->status |= VDP_STATUS_ENABLED;
+	} else {
+		context->status &= ~VDP_STATUS_ENABLED;
+	}
+}
--- a/src/vdp.h	Sun Mar 27 22:14:26 2016 -0700
+++ b/src/vdp.h	Mon Mar 28 23:43:31 2016 -0700
@@ -19,12 +19,17 @@
 	uint16_t vscroll;
 	uint16_t hscroll;
 	
+	uint16_t draw_source;
+	uint16_t draw_dest;
+	
 	uint16_t vram[32*512];
-	uint8_t  linebuffers[320*2];
+	uint8_t  linebuffers[328*2];
 	uint16_t sram[64*2];
 	uint16_t cram[64];
 	
 	uint8_t  fifo_dest;
+	uint8_t  draw_counter;
+	uint8_t  palpriority;
 } vdp;
 
 enum {
@@ -43,5 +48,6 @@
 void vdp_run(vdp *context, uint32_t target);
 void vdp_write_address(vdp *context, uint16_t value);
 void vdp_write_data(vdp *context, uint16_t value);
+void vdp_write_hscroll(vdp *context, uint16_t value);
 
 #endif //VDP_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tiletest.s16	Mon Mar 28 23:43:31 2016 -0700
@@ -0,0 +1,84 @@
+
+	;write palette entries to CRAM
+	ldim 0, r0
+	ldimh $FF, r0
+	outi 14, r0
+	ldim colors, r0
+	ldim $80, r1
+	ldimh $0, r1
+	ldim 0, r2
+cloop:
+	ld16 r0, r2, r3
+	outi 15, r3
+	addi 2, r2
+	cmp r1, r2
+	bne cloop
+	
+	;write tile to VRAM
+	ldim 0, r2
+	outi 14, r2
+	ldim tile, r0
+	ldim 32, r1
+tloop:
+	ld16 r0, r2, r3
+	outi 15, r3
+	addi 2, r2
+	cmp r1, r2
+	bne tloop
+	
+	;write name table entries to VRAM
+	ldim 0, r2
+	ldimh $60, r2
+	outi 14, r2
+	;current entry
+	ldim 0, r0
+	;increment
+	ldimh $8, r2
+	;counter
+	ldim $00, r1
+	ldimh $7, r1
+nloop:
+	outi 15, r0
+	add r2, r0, r0
+	addi -1, r1
+	bne nloop
+	
+	;write vscroll register
+	ldim $0, r0
+	ldimh $E6, r0
+	outi $C, r0
+	;write hscroll register to enable display
+	ldimh $80, r0
+	outi $D, r0
+forever:
+	bra forever
+tile:
+	dc.l $000FFFFF
+	dc.l $E111EEEE
+	dc.l $DD222DDD
+	dc.l $CCC333CC
+	dc.l $BBBB444B
+	dc.l $AAAAA555
+	dc.l $99996669
+	dc.l $88877788
+colors:
+	dc.w $0000, $0001, $0002, $0003
+	dc.w $0004, $0005, $0006, $0007
+	dc.w $0008, $0009, $000A, $000B
+	dc.w $000C, $000D, $000E, $000F
+	
+	dc.w $0000, $0010, $0020, $0030
+	dc.w $0040, $0050, $0060, $0070
+	dc.w $0080, $0090, $00A0, $00B0
+	dc.w $00C0, $00D0, $00E0, $00F0
+	
+	dc.w $0000, $0100, $0200, $0300
+	dc.w $0400, $0500, $0600, $0700
+	dc.w $0800, $0900, $0A00, $0B00
+	dc.w $0C00, $0D00, $0E00, $0F00
+	
+	dc.w $0000, $0111, $0222, $0333
+	dc.w $0444, $0555, $0666, $0777
+	dc.w $0888, $0999, $0AAA, $0BBB
+	dc.w $0CCC, $0DDD, $0EEE, $0FFF
+