From 4182178317f64707c493f417a97a96bad0a8546d Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Thu, 2 Jan 2025 17:01:38 -0600 Subject: [PATCH] add video mode initialization --- Makefile.dreamcast.mk | 95 ++++++++++++----------- c/classpath.h | 1 + c/classpath.inc.c | 1 + classpath.mk | 1 + example/DreamcastVideo2.java | 6 +- example/GdromTest.java | 18 +---- generate_classpath.sh | 3 + sega/dreamcast/gdrom/GdromIF.java | 19 +++++ sega/dreamcast/holly/Core.java | 46 ----------- sega/dreamcast/holly/VideoOutput.java | 51 ++++++++++++ sega/dreamcast/holly/VideoOutputMode.java | 40 ++++++++++ 11 files changed, 171 insertions(+), 110 deletions(-) create mode 100644 sega/dreamcast/gdrom/GdromIF.java create mode 100644 sega/dreamcast/holly/VideoOutput.java create mode 100644 sega/dreamcast/holly/VideoOutputMode.java diff --git a/Makefile.dreamcast.mk b/Makefile.dreamcast.mk index 5aa7a85..f4b17fd 100644 --- a/Makefile.dreamcast.mk +++ b/Makefile.dreamcast.mk @@ -81,52 +81,55 @@ jvm.iso: boot.bin main.bin zero.bin /=$(LIB)/COPYRIGH.TXT \ /=$(LIB)/ABSTRACT.TXT \ /=$(LIB)/BIBLIOGR.TXT \ - /=example/GdromDirectoryRecordHandler.class \ - /=example/GdromTest.class \ - /=filesystem/iso9660/ByteParser.class \ - /=filesystem/iso9660/DirectoryRecord.class \ - /=filesystem/iso9660/ExtentReader.class \ - /=filesystem/iso9660/PrimaryVolumeDescriptor.class \ - /=filesystem/iso9660/VolumeParser.class \ - /=java/io/PrintStream.class \ - /=java/lang/DecimalDigits.class \ - /=java/lang/Integer.class \ - /=java/lang/Object.class \ - /=java/lang/String.class \ - /=java/lang/System.class \ - /=java/misc/Memory.class \ - /=jvm/internal/Loader.class \ - /=sega/dreamcast/gdrom/G1IF.class \ - /=sega/dreamcast/gdrom/GdromBits.class \ - /=sega/dreamcast/gdrom/Gdrom.class \ - /=sega/dreamcast/gdrom/GdromExtentReader.class \ - /=sega/dreamcast/gdrom/GdromCommandPacketFormat_cd_read.class \ - /=sega/dreamcast/gdrom/GdromCommandPacketFormat.class \ - /=sega/dreamcast/gdrom/GdromCommandPacketFormat_get_toc.class \ - /=sega/dreamcast/gdrom/GdromCommandPacketInterface.class \ - /=sega/dreamcast/gdrom/GdromProtocol.class \ - /=Main.class \ - /=example/DreamcastVideo2.class \ - /=model/FacePTN.class \ - /=model/ModelObject.class \ - /=model/UntitledModel.class \ - /=model/Vec2.class \ - /=model/Vec3.class \ - /=sega/dreamcast/holly/Background.class \ - /=sega/dreamcast/holly/CoreBits.class \ - /=sega/dreamcast/holly/Core.class \ - /=sega/dreamcast/holly/ISPTSP.class \ - /=sega/dreamcast/holly/RegionArray.class \ - /=sega/dreamcast/holly/RegionArray_OPBSize.class \ - /=sega/dreamcast/holly/TABits.class \ - /=sega/dreamcast/holly/TAFIFOPolygonConverter.class \ - /=sega/dreamcast/holly/TAGlobalParameter.class \ - /=sega/dreamcast/holly/TAGlobalParameter_end_of_list.class \ - /=sega/dreamcast/holly/TAGlobalParameter_polygon_type_0.class \ - /=sega/dreamcast/holly/TAVertexParameter.class \ - /=sega/dreamcast/holly/TAVertexParameter_polygon_type_3.class \ - /=sega/dreamcast/holly/TextureMemoryAllocation.class \ - /=java/lang/Math.class + example/GdromDirectoryRecordHandler.class \ + example/GdromTest.class \ + filesystem/iso9660/ByteParser.class \ + filesystem/iso9660/DirectoryRecord.class \ + filesystem/iso9660/ExtentReader.class \ + filesystem/iso9660/PrimaryVolumeDescriptor.class \ + filesystem/iso9660/VolumeParser.class \ + java/io/PrintStream.class \ + java/lang/DecimalDigits.class \ + java/lang/Integer.class \ + java/lang/Object.class \ + java/lang/String.class \ + java/lang/System.class \ + java/misc/Memory.class \ + jvm/internal/Loader.class \ + sega/dreamcast/gdrom/G1IF.class \ + sega/dreamcast/gdrom/GdromIF.class \ + sega/dreamcast/gdrom/GdromBits.class \ + sega/dreamcast/gdrom/Gdrom.class \ + sega/dreamcast/gdrom/GdromExtentReader.class \ + sega/dreamcast/gdrom/GdromCommandPacketFormat_cd_read.class \ + sega/dreamcast/gdrom/GdromCommandPacketFormat.class \ + sega/dreamcast/gdrom/GdromCommandPacketFormat_get_toc.class \ + sega/dreamcast/gdrom/GdromCommandPacketInterface.class \ + sega/dreamcast/gdrom/GdromProtocol.class \ + Main.class \ + example/DreamcastVideo2.class \ + model/FacePTN.class \ + model/ModelObject.class \ + model/UntitledModel.class \ + model/Vec2.class \ + model/Vec3.class \ + sega/dreamcast/holly/Background.class \ + sega/dreamcast/holly/CoreBits.class \ + sega/dreamcast/holly/Core.class \ + sega/dreamcast/holly/VideoOutput.class \ + sega/dreamcast/holly/VideoOutputMode.class \ + sega/dreamcast/holly/ISPTSP.class \ + sega/dreamcast/holly/RegionArray.class \ + sega/dreamcast/holly/RegionArray_OPBSize.class \ + sega/dreamcast/holly/TABits.class \ + sega/dreamcast/holly/TAFIFOPolygonConverter.class \ + sega/dreamcast/holly/TAGlobalParameter.class \ + sega/dreamcast/holly/TAGlobalParameter_end_of_list.class \ + sega/dreamcast/holly/TAGlobalParameter_polygon_type_0.class \ + sega/dreamcast/holly/TAVertexParameter.class \ + sega/dreamcast/holly/TAVertexParameter_polygon_type_3.class \ + sega/dreamcast/holly/TextureMemoryAllocation.class \ + java/lang/Math.class main.elf: LDSCRIPT = $(LIB)/main.lds main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_PATH) diff --git a/c/classpath.h b/c/classpath.h index 8de1cef..6797e10 100644 --- a/c/classpath.h +++ b/c/classpath.h @@ -13,6 +13,7 @@ #include "java/lang/System.class.h" #include "java/misc/Memory.class.h" #include "sega/dreamcast/gdrom/G1IF.class.h" +#include "sega/dreamcast/gdrom/GdromIF.class.h" #include "sega/dreamcast/gdrom/GdromBits.class.h" #include "sega/dreamcast/gdrom/Gdrom.class.h" #include "sega/dreamcast/gdrom/GdromExtentReader.class.h" diff --git a/c/classpath.inc.c b/c/classpath.inc.c index b51b8b4..0fe905e 100644 --- a/c/classpath.inc.c +++ b/c/classpath.inc.c @@ -13,6 +13,7 @@ (const uint8_t *)&_binary_java_lang_System_class_start, (const uint8_t *)&_binary_java_misc_Memory_class_start, (const uint8_t *)&_binary_sega_dreamcast_gdrom_G1IF_class_start, +(const uint8_t *)&_binary_sega_dreamcast_gdrom_GdromIF_class_start, (const uint8_t *)&_binary_sega_dreamcast_gdrom_GdromBits_class_start, (const uint8_t *)&_binary_sega_dreamcast_gdrom_Gdrom_class_start, (const uint8_t *)&_binary_sega_dreamcast_gdrom_GdromExtentReader_class_start, diff --git a/classpath.mk b/classpath.mk index 3054495..6d9f369 100644 --- a/classpath.mk +++ b/classpath.mk @@ -14,6 +14,7 @@ CLASS_PATH = \ java/lang/System.class.o \ java/misc/Memory.class.o \ sega/dreamcast/gdrom/G1IF.class.o \ + sega/dreamcast/gdrom/GdromIF.class.o \ sega/dreamcast/gdrom/GdromBits.class.o \ sega/dreamcast/gdrom/Gdrom.class.o \ sega/dreamcast/gdrom/GdromExtentReader.class.o \ diff --git a/example/DreamcastVideo2.java b/example/DreamcastVideo2.java index 3ea34a1..93bf121 100644 --- a/example/DreamcastVideo2.java +++ b/example/DreamcastVideo2.java @@ -12,6 +12,8 @@ import sega.dreamcast.holly.TextureMemoryAllocation; import sega.dreamcast.holly.ISPTSP; import sega.dreamcast.holly.TAVertexParameter; import sega.dreamcast.holly.TAGlobalParameter; +import sega.dreamcast.holly.VideoOutput; +import sega.dreamcast.holly.VideoOutputMode; import sega.dreamcast.MemoryMap; import model.UntitledModel; import model.Vec3; @@ -299,7 +301,8 @@ public class DreamcastVideo2 { while ((CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) == 0)); while (!(CoreBits.spg_status__vsync(Memory.getU4(Holly.SPG_STATUS)) == 0)); - Core.fb_r_enable(); + VideoOutput.set_framebuffer_resolution(640, 480); + VideoOutput.set_mode(VideoOutputMode.vga); Memory.putU4(Holly.FB_R_SOF1, TextureMemoryAllocation.framebuffer_start[0]); } @@ -338,7 +341,6 @@ public class DreamcastVideo2 { TextureMemoryAllocation.object_list_start[0]); Core.init(); - Core.fb_init(framebuffer_width, framebuffer_height); boot_splash(ta_alloc, opb_size_total); diff --git a/example/GdromTest.java b/example/GdromTest.java index 840475e..7ca7f42 100644 --- a/example/GdromTest.java +++ b/example/GdromTest.java @@ -2,6 +2,7 @@ package example; import sega.dreamcast.gdrom.GdromExtentReader; import sega.dreamcast.gdrom.GdromProtocol; +import sega.dreamcast.gdrom.GdromIF; import sega.dreamcast.gdrom.G1IF; import java.misc.Memory; import filesystem.iso9660.VolumeParser; @@ -25,19 +26,6 @@ class GdromDirectoryRecordHandler implements DirectoryRecordHandler { this.addresses_ix = 0; } - // transfer_length is in bytes - public static void startG1DMA(int start_address, int transfer_length) { - int gdstar = start_address & ~(0b111 << 29); - - Memory.putU4(G1IF.GDAPRO, 0x8843407F); - Memory.putU4(G1IF.G1GDRC, 0x00001001); - Memory.putU4(G1IF.GDSTAR, gdstar); - Memory.putU4(G1IF.GDLEN, transfer_length); - Memory.putU4(G1IF.GDDIR, 1); - Memory.putU4(G1IF.GDEN, 1); - Memory.putU4(G1IF.GDST, 1); - } - public boolean isClassExt(DirectoryRecord dr) { int length = dr.lengthOfFileIdentifier(); @@ -76,9 +64,8 @@ class GdromDirectoryRecordHandler implements DirectoryRecordHandler { int sectors = length >> 11; // division by 2048 GdromProtocol.cdReadDMA(extent + 150, sectors); - startG1DMA(address, length); + GdromIF.startG1DMA(address, length); - //System.out.println("wait gdst"); while ((Memory.getU4(G1IF.GDST) & 1) != 0); System.out.println("transfer complete"); @@ -101,7 +88,6 @@ class GdromTest { GdromExtentReader reader = new GdromExtentReader(); VolumeParser parser = new VolumeParser(data_track_fad - 150, reader, handler); - System.out.println("::parser parse::"); parser.parse(); Loader.load(buffer_addresses, handler.addresses_ix); diff --git a/generate_classpath.sh b/generate_classpath.sh index b7c2633..5930c87 100644 --- a/generate_classpath.sh +++ b/generate_classpath.sh @@ -86,6 +86,7 @@ declare -a boot_classes=( java/lang/System.class java/misc/Memory.class sega/dreamcast/gdrom/G1IF.class + sega/dreamcast/gdrom/GdromIF.class sega/dreamcast/gdrom/GdromBits.class sega/dreamcast/gdrom/Gdrom.class sega/dreamcast/gdrom/GdromExtentReader.class @@ -129,6 +130,8 @@ declare -a application_classes=( sega/dreamcast/holly/Background.class sega/dreamcast/holly/Core.class sega/dreamcast/holly/CoreBits.class + sega/dreamcast/holly/VideoOutput.class + sega/dreamcast/holly/VideoOutputMode.class sega/dreamcast/holly/ISPTSP.class sega/dreamcast/holly/RegionArray.class sega/dreamcast/holly/RegionArray_OPBSize.class diff --git a/sega/dreamcast/gdrom/GdromIF.java b/sega/dreamcast/gdrom/GdromIF.java new file mode 100644 index 0000000..34a39dd --- /dev/null +++ b/sega/dreamcast/gdrom/GdromIF.java @@ -0,0 +1,19 @@ +package sega.dreamcast.gdrom; + +import sega.dreamcast.gdrom.G1IF; +import java.misc.Memory; + +public class GdromIF { + // transfer_length is in bytes + public static void startG1DMA(int start_address, int transfer_length) { + int gdstar = start_address & ~(0b111 << 29); + + Memory.putU4(G1IF.GDAPRO, 0x8843407F); + Memory.putU4(G1IF.G1GDRC, 0x00001001); + Memory.putU4(G1IF.GDSTAR, gdstar); + Memory.putU4(G1IF.GDLEN, transfer_length); + Memory.putU4(G1IF.GDDIR, 1); + Memory.putU4(G1IF.GDEN, 1); + Memory.putU4(G1IF.GDST, 1); + } +} diff --git a/sega/dreamcast/holly/Core.java b/sega/dreamcast/holly/Core.java index abbd986..8d18b70 100644 --- a/sega/dreamcast/holly/Core.java +++ b/sega/dreamcast/holly/Core.java @@ -43,52 +43,6 @@ public class Core { Memory.putU4(Holly.SOFTRESET, 0); } - public static void fb_init(int x_size, int y_size) { - int y_coeff = CoreBits.y_coeff__coefficient_1(0x80) - | CoreBits.y_coeff__coefficient_0_2(0x40); - - // in 6.10 fixed point; 0x0400 is 1x vertical scale - int scaler_ctl = CoreBits.scaler_ctl__vertical_scale_factor(0x0400); - - int fb_burstctrl = CoreBits.fb_burstctrl__wr_burst(0x09) - | CoreBits.fb_burstctrl__vid_lat(0x3f) - | CoreBits.fb_burstctrl__vid_burst(0x39); - - int fb_x_clip = CoreBits.fb_x_clip__fb_x_clip_max(x_size - 1) - | CoreBits.fb_x_clip__fb_x_clip_min(0); - - int fb_y_clip = CoreBits.fb_y_clip__fb_y_clip_max(y_size - 1) - | CoreBits.fb_y_clip__fb_y_clip_min(0); - - int fb_r_size = CoreBits.fb_r_size__fb_modulus(1) - | CoreBits.fb_r_size__fb_y_size(y_size - 3) - | CoreBits.fb_r_size__fb_x_size((x_size * 16) / 32 - 1); - - int fb_w_ctrl = CoreBits.fb_w_ctrl__fb_dither - | CoreBits.fb_w_ctrl__fb_packmode__565_rgb_16bit; - - Memory.putU4(Holly.Y_COEFF, y_coeff); - Memory.putU4(Holly.SCALER_CTL, scaler_ctl); - Memory.putU4(Holly.FB_BURSTCTRL, fb_burstctrl); - Memory.putU4(Holly.FB_X_CLIP, fb_x_clip); - Memory.putU4(Holly.FB_Y_CLIP, fb_y_clip); - Memory.putU4(Holly.FB_R_SIZE, fb_r_size); - Memory.putU4(Holly.FB_W_CTRL, fb_w_ctrl); - } - - public static void fb_r_disable() { - Memory.putU4(Holly.FB_R_CTRL, 0); - } - - public static void fb_r_enable() { - int fb_r_ctrl = - CoreBits.fb_r_ctrl__vclk_div__pclk_vclk_1 - | CoreBits.fb_r_ctrl__fb_depth__565_rgb_16bit - | CoreBits.fb_r_ctrl__fb_enable; - - Memory.putU4(Holly.FB_R_CTRL, fb_r_ctrl); - } - public static void start_render(int region_array_start, int isp_tsp_parameters_start, int background_start, diff --git a/sega/dreamcast/holly/VideoOutput.java b/sega/dreamcast/holly/VideoOutput.java new file mode 100644 index 0000000..f907734 --- /dev/null +++ b/sega/dreamcast/holly/VideoOutput.java @@ -0,0 +1,51 @@ +package sega.dreamcast.holly; + +import java.misc.Memory; + +public class VideoOutput { + public static void set_framebuffer_resolution(int x_size, int y_size) + { + Memory.putU4(Holly.Y_COEFF, CoreBits.y_coeff__coefficient_1(0x80) + | CoreBits.y_coeff__coefficient_0_2(0x40)); + + // in 6.10 fixed point; 0x0400 is 1x vertical scale + Memory.putU4(Holly.SCALER_CTL, CoreBits.scaler_ctl__vertical_scale_factor(0x0400)); + + Memory.putU4(Holly.FB_BURSTCTRL, CoreBits.fb_burstctrl__wr_burst(0x09) + | CoreBits.fb_burstctrl__vid_lat(0x3f) + | CoreBits.fb_burstctrl__vid_burst(0x39)); + + Memory.putU4(Holly.FB_X_CLIP, CoreBits.fb_x_clip__fb_x_clip_max(x_size - 1) + | CoreBits.fb_x_clip__fb_x_clip_min(0)); + + Memory.putU4(Holly.FB_Y_CLIP, CoreBits.fb_y_clip__fb_y_clip_max(y_size - 1) + | CoreBits.fb_y_clip__fb_y_clip_min(0)); + + Memory.putU4(Holly.FB_R_SIZE, CoreBits.fb_r_size__fb_modulus(1) + | CoreBits.fb_r_size__fb_y_size(y_size - 3) + | CoreBits.fb_r_size__fb_x_size((x_size * 16) / 32 - 1)); + } + + public static void set_mode(VideoOutputMode mode) + { + Memory.putU4(Holly.SPG_LOAD, mode.spg_load); + Memory.putU4(Holly.SPG_HBLANK, mode.spg_hblank); + Memory.putU4(Holly.SPG_VBLANK, mode.spg_vblank); + Memory.putU4(Holly.SPG_WIDTH, mode.spg_width); + Memory.putU4(Holly.SPG_CONTROL, mode.spg_control); + + Memory.putU4(Holly.VO_STARTX, mode.vo_startx); + Memory.putU4(Holly.VO_STARTY, mode.vo_starty); + Memory.putU4(Holly.VO_CONTROL, mode.vo_control); + + Memory.putU4(Holly.SPG_HBLANK_INT, mode.spg_hblank_int); + Memory.putU4(Holly.SPG_VBLANK_INT, mode.spg_vblank_int); + + Memory.putU4(Holly.FB_W_CTRL, CoreBits.fb_w_ctrl__fb_dither + | CoreBits.fb_w_ctrl__fb_packmode__565_rgb_16bit); + + Memory.putU4(Holly.FB_R_CTRL, mode.fb_r_ctrl + | CoreBits.fb_r_ctrl__fb_depth__565_rgb_16bit + | CoreBits.fb_r_ctrl__fb_enable); + } +} diff --git a/sega/dreamcast/holly/VideoOutputMode.java b/sega/dreamcast/holly/VideoOutputMode.java new file mode 100644 index 0000000..7bd8d99 --- /dev/null +++ b/sega/dreamcast/holly/VideoOutputMode.java @@ -0,0 +1,40 @@ +package sega.dreamcast.holly; + +public class VideoOutputMode { + int fb_r_ctrl; + int spg_load; + int spg_hblank; + int spg_vblank; + int spg_width; + int spg_control; + int vo_startx; + int vo_starty; + int vo_control; + int spg_hblank_int; + int spg_vblank_int; + + public static VideoOutputMode vga; + + static { + vga = new VideoOutputMode(); + vga.fb_r_ctrl = CoreBits.fb_r_ctrl__vclk_div__pclk_vclk_1; + vga.spg_load = CoreBits.spg_load__vcount(0x20c) + | CoreBits.spg_load__hcount(0x359); + vga.spg_hblank = CoreBits.spg_hblank__hbend(0x07e) + | CoreBits.spg_hblank__hbstart(0x345); + vga.spg_vblank = CoreBits.spg_vblank__vbend(0x028) + | CoreBits.spg_vblank__vbstart(0x208); + vga.spg_width = CoreBits.spg_width__eqwidth(0x00f) + | CoreBits.spg_width__bpwidth(0x319) + | CoreBits.spg_width__vswidth(0x3) + | CoreBits.spg_width__hswidth(0x3f); + vga.spg_control = CoreBits.spg_control__sync_direction__output; + vga.vo_startx = CoreBits.vo_startx__horizontal_start_position(0x0a8); + vga.vo_starty = CoreBits.vo_starty__vertical_start_position_on_field_2(0x028) + | CoreBits.vo_starty__vertical_start_position_on_field_1(0x028); + vga.vo_control = CoreBits.vo_control__pclk_delay(0x16); + vga.spg_hblank_int = CoreBits.spg_hblank_int__line_comp_val(0x345); + vga.spg_vblank_int = CoreBits.spg_vblank_int__vblank_out_interrupt_line_number(0x015) + | CoreBits.spg_vblank_int__vblank_in_interrupt_line_number(0x208); + } +}