summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2016-10-08 23:49:20 -0700
committerMichael Pavone <pavone@retrodev.com>2016-10-08 23:49:20 -0700
commitd8ac99946d19321cbe191747ac98bd481a6cdea6 (patch)
tree85755945a8cd2e5156adc3953c89f6634bbe3848
parent3bda38c2547f87a25635a886604e8b597bae5491 (diff)
Basic handling of video/object processor register writes
-rw-r--r--jag_video.c90
-rw-r--r--jag_video.h54
-rw-r--r--jaguar.c4
3 files changed, 144 insertions, 4 deletions
diff --git a/jag_video.c b/jag_video.c
index fd484b2..a50a34e 100644
--- a/jag_video.c
+++ b/jag_video.c
@@ -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 @@ jag_video *jag_video_init(void)
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);
+ }
}
diff --git a/jag_video.h b/jag_video.h
index 0555712..4cef19e 100644
--- a/jag_video.h
+++ b/jag_video.h
@@ -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 @@ typedef struct {
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_
diff --git a/jaguar.c b/jaguar.c
index 811db86..76ba875 100644
--- a/jaguar.c
+++ b/jaguar.c
@@ -87,7 +87,7 @@ void rom0_write_16(uint32_t address, jaguar_context *system, uint16_t value)
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 @@ void rom0_write_16(uint32_t address, jaguar_context *system, uint16_t value)
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) {