# HG changeset patch # User Michael Pavone # Date 1475995760 25200 # Node ID c0a026e974f4b8b989bd8ebd65599d954ec59302 # Parent 6433d4d05934b85c95f6b35c4418bee8177aa771 Basic handling of video/object processor register writes diff -r 6433d4d05934 -r c0a026e974f4 jag_video.c --- 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 #include +#include #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); + } +} diff -r 6433d4d05934 -r c0a026e974f4 jag_video.h --- 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_ diff -r 6433d4d05934 -r c0a026e974f4 jaguar.c --- 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) {