changeset 1088:c0a026e974f4

Basic handling of video/object processor register writes
author Michael Pavone <pavone@retrodev.com>
date Sat, 08 Oct 2016 23:49:20 -0700
parents 6433d4d05934
children 87597a048d38
files jag_video.c jag_video.h jaguar.c
diffstat 3 files changed, 144 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/jag_video.c	Fri Oct 07 18:27:38 2016 -0700
+++ b/jag_video.c	Sat Oct 08 23:49:20 2016 -0700
@@ -1,7 +1,23 @@
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include "jag_video.h"
 
+enum {
+	VMODE_CRY,
+	VMODE_RGB24,
+	VMODE_DIRECT16,
+	VMODE_RGB16,
+	VMODE_VARIABLE
+};
+
+char *vmode_names[] = {
+	"CRY",
+	"RGB16",
+	"DIRECT16",
+	"VARIABLE"
+};
+
 jag_video *jag_video_init(void)
 {
 	return calloc(1, sizeof(jag_video));
@@ -10,4 +26,78 @@
 void jag_video_run(jag_video *context, uint32_t target_cycle)
 {
 	context->cycles = target_cycle;
+	
 }
+
+static uint8_t is_reg_writeable(uint32_t address)
+{
+	return address < VID_HLPEN || address >= VID_OBJLIST1;
+}
+
+void jag_video_reg_write(jag_video *context, uint32_t address, uint16_t value)
+{
+	uint32_t reg = (address >> 1 & 0x7F) - 2;
+	if (reg < JAG_VIDEO_REGS && is_reg_writeable(reg)) {
+		context->regs[reg] = value;
+		if (reg == VID_VMODE) {
+			context->pclock_div = (value >> 9 & 7) + 1;
+			context->pclock_counter = 0;
+			if (value & 0x10) {
+				context->mode = VMODE_VARIABLE;
+			} else {
+				context->mode = value >> 1 & 3;
+			}
+			printf("Mode %s, pixel clock divider: %d, time base generation: %s\n", vmode_names[context->mode], context->pclock_div, value & 1 ? "enabled" : "disabled");
+		}
+		switch (reg)
+		{
+		case VID_OBJLIST1:
+			printf("Object List Pointer 1: %X\n", value);
+			break;
+		case VID_OBJLIST2:
+			printf("Object List Pointer 2: %X\n", value);
+			break;
+		case VID_HPERIOD:
+			printf("Horizontal period: %d\n", value & 0x3FF);
+			break;
+		case VID_HBLANK_BEGIN:
+			printf("horizontal blanking begin: %d\n", value & 0x7FF);
+			break;
+		case VID_HBLANK_END:
+			printf("horizontal blanking end: %d\n", value & 0x7FF);
+			break;
+		case VID_HSYNC:
+			printf("horizontal sync start: %d\n", value & 0x7FF);
+			break;
+		case VID_HDISP_BEGIN1:
+			printf("horizontal display begin 1: %d\n", value & 0x7FF);
+			break;
+		case VID_HDISP_BEGIN2:
+			printf("horizontal display begin 2: %d\n", value & 0x7FF);
+			break;
+		case VID_HDISP_END:
+			printf("horizontal display end: %d\n", value & 0x7FF);
+			break;
+		case VID_VPERIOD:
+			printf("Vertical period: %d\n", value & 0x7FF);
+			break;
+		case VID_VBLANK_BEGIN:
+			printf("vertical blanking begin: %d\n", value & 0x7FF);
+			break;
+		case VID_VBLANK_END:
+			printf("vertical blanking end: %d\n", value & 0x7FF);
+			break;
+		case VID_VSYNC:
+			printf("vertical sync start: %d\n", value & 0x7FF);
+			break;
+		case VID_VDISP_BEGIN:
+			printf("vertical display begin: %d\n", value & 0x7FF);
+			break;
+		case VID_VDISP_END:
+			printf("vertical display end: %d\n", value & 0x7FF);
+			break;
+		}
+	} else {
+		fprintf(stderr, "Write to invalid video/object processor register %X:%X\n", address, value);
+	}
+}
--- a/jag_video.h	Fri Oct 07 18:27:38 2016 -0700
+++ b/jag_video.h	Sat Oct 08 23:49:20 2016 -0700
@@ -1,7 +1,52 @@
 #ifndef JAG_VIDEO_H_
 #define JAG_VIDEO_H_
 
-#define JAG_VIDEO_REGS 0x2E
+enum {
+	VID_HCOUNT,
+	VID_VCOUNT,
+	VID_HLPEN,
+	VID_VLPEN,
+	VID_REG_C,
+	VID_REG_E,
+	VID_OBJ0,
+	VID_OBJ1,
+	VID_OBJ2,
+	VID_OBJ3,
+	VID_REG_18,
+	VID_REG_1A,
+	VID_REG_1C,
+	VID_REG_1E,
+	VID_OBJLIST1,
+	VID_OBJLIST2,
+	VID_REG_24,
+	VID_OBJFLAG,
+	VID_VMODE,
+	VID_BORDER_RG,
+	VID_BORDER_B,
+	VID_HPERIOD,
+	VID_HBLANK_BEGIN,
+	VID_HBLANK_END,
+	VID_HSYNC,
+	VID_HVSYNC,
+	VID_HDISP_BEGIN1,
+	VID_HDISP_BEGIN2,
+	VID_HDISP_END,
+	VID_VPERIOD,
+	VID_VBLANK_BEGIN,
+	VID_VBLANK_END,
+	VID_VSYNC,
+	VID_VDISP_BEGIN,
+	VID_VDISP_END,
+	VID_VEQUAL_BEGIN,
+	VID_VEQUAL_END,
+	VID_VINT,
+	VID_PIT0,
+	VID_PIT1,
+	VID_HEQUAL_END,
+	VID_REG_56,
+	VID_BGCOLOR,
+	JAG_VIDEO_REGS
+};
 #define LINEBUFFER_WORDS 720
 
 typedef struct {
@@ -13,10 +58,15 @@
 	uint16_t     *write_line_buffer;
 	uint16_t     *read_line_buffer;
 	
-	uint32_t cycles;
+	uint32_t     cycles;
+	uint8_t      pclock_div;
+	uint8_t      pclock_counter;
+	uint8_t      mode;
 } jag_video;
 
+
 jag_video *jag_video_init(void);
 void jag_video_run(jag_video *context, uint32_t target_cycle);
+void jag_video_reg_write(jag_video *context, uint32_t address, uint16_t value);
 
 #endif //JAG_VIDEO_H_
--- a/jaguar.c	Fri Oct 07 18:27:38 2016 -0700
+++ b/jaguar.c	Sat Oct 08 23:49:20 2016 -0700
@@ -87,7 +87,7 @@
 						mem_pointers[rom + 1] = system->cart + ((0x200000 & (system->cart_size-1)) >> 1);
 						mem_pointers[rom + 2] = system->cart + ((0x400000 & (system->cart_size-1)) >> 1);
 						system->memcon_written = 1;
-						printf("MEMCON1 write - ROMHI: %d", value & 1);
+						printf("MEMCON1 write - ROMHI: %d\n", value & 1);
 						//TODO: invalidate code cache
 					}
 					system->memcon1 = value;
@@ -96,7 +96,7 @@
 					system->memcon2 = value;
 					break;
 				default:
-					fprintf(stderr, "Unhandled write to video mode/memory control registers - %X:%X\n", address, value);
+					jag_video_reg_write(system->video, address, value);
 					break;
 				}
 			} else if (address < 0x100800) {