diff --git a/Makefile.dreamcast.mk b/Makefile.dreamcast.mk index 1559646..751808f 100644 --- a/Makefile.dreamcast.mk +++ b/Makefile.dreamcast.mk @@ -1,6 +1,6 @@ all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp)) -OPT = -O3 +OPT = -Og MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST))))) LIB ?= $(MAKEFILE_PATH)/dreamcast @@ -47,16 +47,13 @@ LIBGCC_OBJ = \ libgcc/_fixsfdi.o \ libgcc/_div_table.o +include classpath.mk + CLASS_FILES = \ - java/io/PrintStream.class.o \ - java/lang/Integer.class.o \ - java/lang/Object.class.o \ - java/lang/String.class.o \ - java/lang/System.class.o \ - java/misc/Memory.class.o \ - p/DreamcastVideo2.class.o \ - sega/dreamcast/holly/Holly.class.o \ - sega/dreamcast/holly/CoreBits.class.o + p/polygon_type_0.class.o \ + p/vertex_polygon_type_0.class.o \ + p/end_of_list.class.o \ + p/DreamcastVideo2.class.o main.elf: LDSCRIPT = $(LIB)/main.lds -main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_FILES) +main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_FILES) $(CLASS_PATH) diff --git a/c/frame.c b/c/frame.c index 9842b67..08e6608 100644 --- a/c/frame.c +++ b/c/frame.c @@ -269,6 +269,18 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str return; } } + if (method_name_constant->utf8.length == 6) { + if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"putSQ", 4)) { + assert(nargs == 2); + assert(return_type == 'V'); + switch (method_name_constant->utf8.bytes[5]) { + //case '2': value = native_java_misc_memory_putSQ2_2(args); break; + case '1': native_java_misc_memory_putSQ1_2(args); break; + default: assert(false); + } + return; + } + } } int java_io_printstream_length = 19; diff --git a/c/main_classpath.h b/c/main_classpath.h new file mode 100644 index 0000000..6518edd --- /dev/null +++ b/c/main_classpath.h @@ -0,0 +1,19 @@ +#include "java/io/PrintStream.class.h" +#include "java/lang/System.class.h" +#include "java/lang/String.class.h" +#include "java/lang/Integer.class.h" +#include "java/lang/Math.class.h" +#include "java/lang/Object.class.h" +#include "java/misc/Memory.class.h" +#include "sega/dreamcast/holly/CoreBits.class.h" +#include "sega/dreamcast/holly/TextureMemoryAllocation.class.h" +#include "sega/dreamcast/holly/Background.class.h" +#include "sega/dreamcast/holly/TABits.class.h" +#include "sega/dreamcast/holly/RegionArray_OPBSize.class.h" +#include "sega/dreamcast/holly/ISPTSP.class.h" +#include "sega/dreamcast/holly/Core.class.h" +#include "sega/dreamcast/holly/Holly.class.h" +#include "sega/dreamcast/holly/RegionArray.class.h" +#include "sega/dreamcast/holly/TAFIFOPolygonConverter.class.h" +#include "sega/dreamcast/holly/TAParameter.class.h" +#include "sega/dreamcast/MemoryMap.class.h" diff --git a/c/main_classpath.inc.c b/c/main_classpath.inc.c new file mode 100644 index 0000000..9379196 --- /dev/null +++ b/c/main_classpath.inc.c @@ -0,0 +1,19 @@ + (const uint8_t *)&_binary_java_io_PrintStream_class_start, + (const uint8_t *)&_binary_java_lang_System_class_start, + (const uint8_t *)&_binary_java_lang_String_class_start, + (const uint8_t *)&_binary_java_lang_Integer_class_start, + (const uint8_t *)&_binary_java_lang_Math_class_start, + (const uint8_t *)&_binary_java_lang_Object_class_start, + (const uint8_t *)&_binary_java_misc_Memory_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_CoreBits_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_TextureMemoryAllocation_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_Background_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_TABits_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_RegionArray_OPBSize_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_ISPTSP_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_Core_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_Holly_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_RegionArray_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_start, + (const uint8_t *)&_binary_sega_dreamcast_holly_TAParameter_class_start, + (const uint8_t *)&_binary_sega_dreamcast_MemoryMap_class_start, diff --git a/c/main_dreamcast.c b/c/main_dreamcast.c index ce4ea88..eb13f47 100644 --- a/c/main_dreamcast.c +++ b/c/main_dreamcast.c @@ -7,30 +7,22 @@ #include "sh7091_scif.h" -#include "java/io/PrintStream.class.h" -#include "java/lang/Integer.class.h" -#include "java/lang/Object.class.h" -#include "java/lang/String.class.h" -#include "java/lang/System.class.h" -#include "java/misc/Memory.class.h" +#include "main_classpath.h" #include "p/DreamcastVideo2.class.h" -#include "sega/dreamcast/holly/Holly.class.h" -#include "sega/dreamcast/holly/CoreBits.class.h" +#include "p/vertex_polygon_type_0.class.h" +#include "p/polygon_type_0.class.h" +#include "p/end_of_list.class.h" void main() { scif_init(0); const uint8_t * class_file_buffers[] = { - (const uint8_t *)&_binary_java_io_PrintStream_class_start, - (const uint8_t *)&_binary_java_lang_Integer_class_start, - (const uint8_t *)&_binary_java_lang_Object_class_start, - (const uint8_t *)&_binary_java_lang_String_class_start, - (const uint8_t *)&_binary_java_lang_System_class_start, - (const uint8_t *)&_binary_java_misc_Memory_class_start, + #include "main_classpath.inc.c" (const uint8_t *)&_binary_p_DreamcastVideo2_class_start, - (const uint8_t *)&_binary_sega_dreamcast_holly_Holly_class_start, - (const uint8_t *)&_binary_sega_dreamcast_holly_CoreBits_class_start, + (const uint8_t *)&_binary_p_vertex_polygon_type_0_class_start, + (const uint8_t *)&_binary_p_polygon_type_0_class_start, + (const uint8_t *)&_binary_p_end_of_list_class_start, }; int class_file_buffers_length = (sizeof (class_file_buffers)) / (sizeof (class_file_buffers[0])); diff --git a/c/native.c b/c/native.c index bf2c14f..847587d 100644 --- a/c/native.c +++ b/c/native.c @@ -63,14 +63,41 @@ uint32_t native_java_misc_memory_getU1_1(uint32_t * args) return value; } -uint32_t native_java_lang_math_sin_1(uint32_t * args) +extern uint32_t store_queue[0x4000000] __asm("store_queue"); + +void native_java_misc_memory_putSQ1_2(uint32_t * args) +{ + #if defined(__dreamcast__) + uint32_t * objectref = (uint32_t *)args[0]; + uint32_t address = (uint32_t)args[1]; + store_queue[0] = objectref[1]; + store_queue[1] = objectref[2]; + store_queue[2] = objectref[3]; + store_queue[3] = objectref[4]; + store_queue[4] = objectref[5]; + store_queue[5] = objectref[6]; + store_queue[6] = objectref[7]; + store_queue[6] = objectref[8]; + + *((uint32_t*)0xff000038) = ((address >> 26) & 0b111) << 2; + + __asm__ volatile ("pref @%0" + : // output + : "r" (&store_queue[0]) // input + : "memory"); + #endif +} + +uint32_t __attribute__ ((noinline)) __attribute__ ((optimize(0))) +native_java_lang_math_sin_1(uint32_t * args) { float arg = ((float *)args)[0]; float value = __builtin_sinf(arg); return *((uint32_t *)&value); } -uint32_t native_java_lang_math_cos_1(uint32_t * args) +uint32_t __attribute__ ((noinline)) __attribute__ ((optimize(0))) +native_java_lang_math_cos_1(uint32_t * args) { float arg = ((float *)args)[0]; float value = __builtin_cosf(arg); diff --git a/c/native.h b/c/native.h index 4d7a579..85b0fb3 100644 --- a/c/native.h +++ b/c/native.h @@ -11,5 +11,6 @@ void native_java_misc_memory_putU1_2(uint32_t * args); uint32_t native_java_misc_memory_getU4_1(uint32_t * args); uint32_t native_java_misc_memory_getU2_1(uint32_t * args); uint32_t native_java_misc_memory_getU1_1(uint32_t * args); +void native_java_misc_memory_putSQ1_2(uint32_t * args); uint32_t native_java_lang_math_sin_1(uint32_t * args); uint32_t native_java_lang_math_cos_1(uint32_t * args); diff --git a/class_headers.sh b/class_headers.sh new file mode 100644 index 0000000..350f848 --- /dev/null +++ b/class_headers.sh @@ -0,0 +1,2 @@ +make java/io/PrintStream.class java/lang/System.class java/lang/String.class java/lang/Integer.class java/lang/Math.class java/lang/Object.class java/misc/Memory.class sega/dreamcast/holly/TAVertexParameter$sprite_type_1.class sega/dreamcast/holly/TAGlobalParameter$end_of_list.class sega/dreamcast/holly/CoreBits.class sega/dreamcast/holly/TAVertexParameter$polygon_type_2.class sega/dreamcast/holly/TAVertexParameter$polygon_type_14.class sega/dreamcast/holly/TextureMemoryAllocation.class sega/dreamcast/holly/TAVertexParameter$polygon_type_9.class sega/dreamcast/holly/TAVertexParameter.class sega/dreamcast/holly/TAVertexParameter$polygon_type_7.class sega/dreamcast/holly/TAGlobalParameter$object_list_set.class sega/dreamcast/holly/Background.class sega/dreamcast/holly/TAVertexParameter$polygon_type_11.class sega/dreamcast/holly/TAGlobalParameter$modifier_volume.class sega/dreamcast/holly/TAVertexParameter$polygon_type_0.class sega/dreamcast/holly/TAVertexParameter$polygon_type_1.class sega/dreamcast/holly/TAVertexParameter$polygon_type_8.class sega/dreamcast/holly/TABits.class sega/dreamcast/holly/RegionArray$OPBSize.class sega/dreamcast/holly/TAGlobalParameter$polygon_type_1.class sega/dreamcast/holly/TAGlobalParameter$polygon_type_2.class sega/dreamcast/holly/TAVertexParameter$polygon_type_10.class sega/dreamcast/holly/TAGlobalParameter$polygon_type_3.class sega/dreamcast/holly/TAGlobalParameter$polygon_type_0.class sega/dreamcast/holly/TAVertexParameter$polygon_type_3.class sega/dreamcast/holly/TAGlobalParameter.class sega/dreamcast/holly/TAVertexParameter$polygon_type_12.class sega/dreamcast/holly/ISPTSP.class sega/dreamcast/holly/TAVertexParameter$polygon_type_5.class sega/dreamcast/holly/Core.class sega/dreamcast/holly/TAGlobalParameter$user_tile_clip.class sega/dreamcast/holly/Holly.class sega/dreamcast/holly/TAVertexParameter$polygon_type_4.class sega/dreamcast/holly/TAVertexParameter$modifier_volume.class sega/dreamcast/holly/RegionArray.class sega/dreamcast/holly/TAGlobalParameter$sprite.class sega/dreamcast/holly/TAVertexParameter$polygon_type_13.class sega/dreamcast/holly/TAVertexParameter$polygon_type_6.class sega/dreamcast/holly/TAVertexParameter$sprite_type_0.class sega/dreamcast/holly/TAGlobalParameter$polygon_type_4.class sega/dreamcast/holly/TAFIFOPolygonConverter.class sega/dreamcast/MemoryMap.class +make -f Makefile.dreamcast.mk java/io/PrintStream.class.h java/lang/System.class.h java/lang/String.class.h java/lang/Integer.class.h java/lang/Math.class.h java/lang/Object.class.h java/misc/Memory.class.h sega/dreamcast/holly/TAVertexParameter$sprite_type_1.class.h sega/dreamcast/holly/TAGlobalParameter$end_of_list.class.h sega/dreamcast/holly/CoreBits.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_2.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_14.class.h sega/dreamcast/holly/TextureMemoryAllocation.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_9.class.h sega/dreamcast/holly/TAVertexParameter.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_7.class.h sega/dreamcast/holly/TAGlobalParameter$object_list_set.class.h sega/dreamcast/holly/Background.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_11.class.h sega/dreamcast/holly/TAGlobalParameter$modifier_volume.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_0.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_1.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_8.class.h sega/dreamcast/holly/TABits.class.h sega/dreamcast/holly/RegionArray$OPBSize.class.h sega/dreamcast/holly/TAGlobalParameter$polygon_type_1.class.h sega/dreamcast/holly/TAGlobalParameter$polygon_type_2.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_10.class.h sega/dreamcast/holly/TAGlobalParameter$polygon_type_3.class.h sega/dreamcast/holly/TAGlobalParameter$polygon_type_0.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_3.class.h sega/dreamcast/holly/TAGlobalParameter.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_12.class.h sega/dreamcast/holly/ISPTSP.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_5.class.h sega/dreamcast/holly/Core.class.h sega/dreamcast/holly/TAGlobalParameter$user_tile_clip.class.h sega/dreamcast/holly/Holly.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_4.class.h sega/dreamcast/holly/TAVertexParameter$modifier_volume.class.h sega/dreamcast/holly/RegionArray.class.h sega/dreamcast/holly/TAGlobalParameter$sprite.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_13.class.h sega/dreamcast/holly/TAVertexParameter$polygon_type_6.class.h sega/dreamcast/holly/TAVertexParameter$sprite_type_0.class.h sega/dreamcast/holly/TAGlobalParameter$polygon_type_4.class.h sega/dreamcast/holly/TAFIFOPolygonConverter.class.h sega/dreamcast/MemoryMap.class.h java/io/PrintStream.class.o java/lang/System.class.o java/lang/String.class.o java/lang/Integer.class.o java/lang/Math.class.o java/lang/Object.class.o java/misc/Memory.class.o sega/dreamcast/holly/TAVertexParameter$sprite_type_1.class.o sega/dreamcast/holly/TAGlobalParameter$end_of_list.class.o sega/dreamcast/holly/CoreBits.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_2.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_14.class.o sega/dreamcast/holly/TextureMemoryAllocation.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_9.class.o sega/dreamcast/holly/TAVertexParameter.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_7.class.o sega/dreamcast/holly/TAGlobalParameter$object_list_set.class.o sega/dreamcast/holly/Background.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_11.class.o sega/dreamcast/holly/TAGlobalParameter$modifier_volume.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_0.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_1.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_8.class.o sega/dreamcast/holly/TABits.class.o sega/dreamcast/holly/RegionArray$OPBSize.class.o sega/dreamcast/holly/TAGlobalParameter$polygon_type_1.class.o sega/dreamcast/holly/TAGlobalParameter$polygon_type_2.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_10.class.o sega/dreamcast/holly/TAGlobalParameter$polygon_type_3.class.o sega/dreamcast/holly/TAGlobalParameter$polygon_type_0.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_3.class.o sega/dreamcast/holly/TAGlobalParameter.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_12.class.o sega/dreamcast/holly/ISPTSP.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_5.class.o sega/dreamcast/holly/Core.class.o sega/dreamcast/holly/TAGlobalParameter$user_tile_clip.class.o sega/dreamcast/holly/Holly.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_4.class.o sega/dreamcast/holly/TAVertexParameter$modifier_volume.class.o sega/dreamcast/holly/RegionArray.class.o sega/dreamcast/holly/TAGlobalParameter$sprite.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_13.class.o sega/dreamcast/holly/TAVertexParameter$polygon_type_6.class.o sega/dreamcast/holly/TAVertexParameter$sprite_type_0.class.o sega/dreamcast/holly/TAGlobalParameter$polygon_type_4.class.o sega/dreamcast/holly/TAFIFOPolygonConverter.class.o sega/dreamcast/MemoryMap.class.o diff --git a/classpath.mk b/classpath.mk new file mode 100644 index 0000000..3c41317 --- /dev/null +++ b/classpath.mk @@ -0,0 +1,20 @@ +CLASS_PATH = \ + java/io/PrintStream.class.o \ + java/lang/System.class.o \ + java/lang/String.class.o \ + java/lang/Integer.class.o \ + java/lang/Math.class.o \ + java/lang/Object.class.o \ + java/misc/Memory.class.o \ + sega/dreamcast/holly/CoreBits.class.o \ + sega/dreamcast/holly/TextureMemoryAllocation.class.o \ + sega/dreamcast/holly/Background.class.o \ + sega/dreamcast/holly/TABits.class.o \ + sega/dreamcast/holly/RegionArray_OPBSize.class.o \ + sega/dreamcast/holly/ISPTSP.class.o \ + sega/dreamcast/holly/Core.class.o \ + sega/dreamcast/holly/Holly.class.o \ + sega/dreamcast/holly/RegionArray.class.o \ + sega/dreamcast/holly/TAFIFOPolygonConverter.class.o \ + sega/dreamcast/holly/TAParameter.class.o \ + sega/dreamcast/MemoryMap.class.o diff --git a/gen_classpath.py b/gen_classpath.py new file mode 100644 index 0000000..151060d --- /dev/null +++ b/gen_classpath.py @@ -0,0 +1,40 @@ +import sys +from itertools import chain + +buf = sys.stdin.read() + +def removesuffix(filename): + if filename.endswith('.java'): + filename = filename.removesuffix('.java') + if filename.endswith('.class'): + filename = filename.removesuffix('.class') + return filename + + +java_files = buf.strip().split('\n') +nosuffix_files = [removesuffix(f) for f in java_files] +class_files = [f + '.class' for f in nosuffix_files] +class_h_files = [f + '.class.h' for f in nosuffix_files] +class_o_files = [f + '.class.o' for f in nosuffix_files] + +with open('class_headers.sh', 'w') as f: + filenames = ' '.join(class_files) + f.write(' '.join(["make", filenames, '\n'])) + filenames = ' '.join(chain(class_h_files, class_o_files)) + f.write(' '.join(["make", "-f", "Makefile.dreamcast.mk", filenames, '\n'])) + +with open('c/main_classpath.inc.c', 'w') as f: + for filename in class_files: + name = filename.replace('/', '_').replace('.', '_') + f.write(f" (const uint8_t *)&_binary_{name}_start,\n") + +with open('c/main_classpath.h', 'w') as f: + for filename in class_h_files: + f.write(f'#include "{filename}"\n') + +with open('classpath.mk', 'w') as f: + f.write("CLASS_PATH = \\\n") + for filename in class_o_files[:-2]: + f.write(f"\t{filename} \\\n") + filename = class_o_files[-1] + f.write(f"\t{filename}\n") diff --git a/generate.sh b/generate.sh index eb0a38f..d6da414 100644 --- a/generate.sh +++ b/generate.sh @@ -5,6 +5,9 @@ python regs/holly.py ../dreamcast/regs/holly.csv > sega/dreamcast/holly/Holly.ja python regs/bits_gen.py ../dreamcast/regs/core_bits.csv holly CoreBits > sega/dreamcast/holly/CoreBits.java python regs/bits_gen.py ../dreamcast/regs/ta_bits.csv holly TABits > sega/dreamcast/holly/TABits.java python regs/bits_gen.py ../dreamcast/regs/isp_tsp.csv holly ISPTSP > sega/dreamcast/holly/ISPTSP.java +python regs/bits_gen.py ../dreamcast/regs/ta_parameter.csv holly TAParameter > sega/dreamcast/holly/TAParameter.java python regs/ta_parameters.py ../dreamcast/regs/vertex_parameter_format.csv holly TAVertexParameter > sega/dreamcast/holly/TAVertexParameter.java python regs/ta_parameters.py ../dreamcast/regs/global_parameter_format.csv holly TAGlobalParameter > sega/dreamcast/holly/TAGlobalParameter.java + +find java/ sega/ -iname '*.java' | python gen_classpath.py diff --git a/java/lang/Math.class.h b/java/lang/Math.class.h new file mode 100644 index 0000000..4ee9649 --- /dev/null +++ b/java/lang/Math.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_java_lang_Math_class_start __asm("_binary_java_lang_Math_class_start"); +extern uint32_t _binary_java_lang_Math_class_end __asm("_binary_java_lang_Math_class_end"); +extern uint32_t _binary_java_lang_Math_class_size __asm("_binary_java_lang_Math_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/java/misc/Memory.class.h b/java/misc/Memory.class.h index 1883bc3..6161dd5 100644 --- a/java/misc/Memory.class.h +++ b/java/misc/Memory.class.h @@ -3,7 +3,7 @@ #include #ifdef __cplusplus -extern "C" { +extern C { #endif extern uint32_t _binary_java_misc_Memory_class_start __asm("_binary_java_misc_Memory_class_start"); diff --git a/java/misc/Memory.java b/java/misc/Memory.java index faad20b..333fbf5 100644 --- a/java/misc/Memory.java +++ b/java/misc/Memory.java @@ -8,4 +8,6 @@ public class Memory { public static native int getU4(int address); public static native int getU2(int address); public static native int getU1(int address); + + public static native void putSQ1(Object object, int address); } diff --git a/p/DreamcastVideo2.class.h b/p/DreamcastVideo2.class.h index 1fcacbe..f638876 100644 --- a/p/DreamcastVideo2.class.h +++ b/p/DreamcastVideo2.class.h @@ -3,7 +3,7 @@ #include #ifdef __cplusplus -extern "C" { +extern C { #endif extern uint32_t _binary_p_DreamcastVideo2_class_start __asm("_binary_p_DreamcastVideo2_class_start"); diff --git a/p/DreamcastVideo2.java b/p/DreamcastVideo2.java index 153572b..a8b444c 100644 --- a/p/DreamcastVideo2.java +++ b/p/DreamcastVideo2.java @@ -1,27 +1,230 @@ package p; -import sega.dreamcast.holly.Holly; +import sega.dreamcast.holly.Background; +import sega.dreamcast.holly.Core; import sega.dreamcast.holly.CoreBits; +import sega.dreamcast.holly.Holly; +import sega.dreamcast.holly.RegionArray; +import sega.dreamcast.holly.TABits; +import sega.dreamcast.holly.TAFIFOPolygonConverter; +import sega.dreamcast.holly.TAParameter; +import sega.dreamcast.holly.TextureMemoryAllocation; +import sega.dreamcast.holly.ISPTSP; import java.misc.Memory; +class end_of_list { + public int parameter_control_word; + public int _res0; + public int _res1; + public int _res2; + public int _res3; + public int _res4; + public int _res5; + public int _res6; + public end_of_list(int parameter_control_word + ) { + this.parameter_control_word = parameter_control_word; + this._res0 = 0; + this._res1 = 0; + this._res2 = 0; + this._res3 = 0; + this._res4 = 0; + this._res5 = 0; + this._res6 = 0; + } +} + +class polygon_type_0 { + public int parameter_control_word; + public int isp_tsp_instruction_word; + public int tsp_instruction_word; + public int texture_control_word; + public int _res0; + public int _res1; + public int data_size_for_sort_dma; + public int next_address_for_sort_dma; + public polygon_type_0(int parameter_control_word, + int isp_tsp_instruction_word, + int tsp_instruction_word, + int texture_control_word, + int data_size_for_sort_dma, + int next_address_for_sort_dma + ) { + this.parameter_control_word = parameter_control_word; + this.isp_tsp_instruction_word = isp_tsp_instruction_word; + this.tsp_instruction_word = tsp_instruction_word; + this.texture_control_word = texture_control_word; + this._res0 = 0; + this._res1 = 0; + this.data_size_for_sort_dma = data_size_for_sort_dma; + this.next_address_for_sort_dma = next_address_for_sort_dma; + } +} + +class vertex_polygon_type_0 { + public int parameter_control_word; + public float x; + public float y; + public float z; + public int _res0; + public int _res1; + public int base_color; + public int _res2; + public vertex_polygon_type_0(int parameter_control_word, + float x, + float y, + float z, + int base_color + ) { + this.parameter_control_word = parameter_control_word; + this.x = x; + this.y = y; + this.z = z; + this._res0 = 0; + this._res1 = 0; + this.base_color = base_color; + this._res2 = 0; + } +} + + class DreamcastVideo2 { + static final int ta_fifo_polygon_converter = 0x10000000; + + public static polygon_type_0 pt0; + public static vertex_polygon_type_0 vt0; + public static end_of_list eol; + + static { + int parameter_control_word = TAParameter.para_control__para_type__polygon_or_modifier_volume + | TAParameter.para_control__list_type__opaque + | TAParameter.obj_control__col_type__packed_color; + + int isp_tsp_instruction_word = ISPTSP.isp_tsp_instruction_word__depth_compare_mode__greater + | ISPTSP.isp_tsp_instruction_word__culling_mode__no_culling; + + int tsp_instruction_word = ISPTSP.tsp_instruction_word__src_alpha_instr__one + | ISPTSP.tsp_instruction_word__dst_alpha_instr__zero + | ISPTSP.tsp_instruction_word__fog_control__no_fog; + + int texture_control_word = 0; + int data_size_for_sort_dma = 0; + int next_address_for_sort_dma = 0; + + pt0 = new polygon_type_0(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + texture_control_word, + data_size_for_sort_dma, + next_address_for_sort_dma); + + vt0 = new vertex_polygon_type_0(0, // parameter_control_word + 0, // x + 0, // y + 0.1f, // z + 0xff00ff00); // color (green) + + eol = new end_of_list(TAParameter.para_control__para_type__end_of_list); + } + + public static int polygon_vertex_parameter_control_word(boolean end_of_strip) + { + return TAParameter.para_control__para_type__vertex_parameter + | (end_of_strip ? TAParameter.para_control__end_of_strip : 0); + } + + + public static void transfer_scene() { + Memory.putSQ1(DreamcastVideo2.pt0, ta_fifo_polygon_converter); + + DreamcastVideo2.vt0.parameter_control_word = polygon_vertex_parameter_control_word(false); + DreamcastVideo2.vt0.x = 10.0f; + DreamcastVideo2.vt0.y = 10.0f; + Memory.putSQ1(DreamcastVideo2.vt0, ta_fifo_polygon_converter); + + DreamcastVideo2.vt0.parameter_control_word = polygon_vertex_parameter_control_word(false); + DreamcastVideo2.vt0.x = 100.0f; + DreamcastVideo2.vt0.y = 10.0f; + Memory.putSQ1(DreamcastVideo2.vt0, ta_fifo_polygon_converter); + + DreamcastVideo2.vt0.parameter_control_word = polygon_vertex_parameter_control_word(true); + DreamcastVideo2.vt0.x = 100.0f; + DreamcastVideo2.vt0.y = 100.0f; + Memory.putSQ1(DreamcastVideo2.vt0, ta_fifo_polygon_converter); + + Memory.putSQ1(DreamcastVideo2.eol, ta_fifo_polygon_converter); + } + public static void main() { - System.out.print("FB_R_SOF1: "); - System.out.println(Memory.getU4(Holly.FB_R_SOF1)); + Core.init(); - System.out.print("FB_R_CTRL: "); - System.out.println(Memory.getU4(Holly.FB_R_CTRL)); + int ta_alloc = + TABits.ta_alloc_ctrl__opb_mode__increasing_addresses + | TABits.ta_alloc_ctrl__pt_opb__no_list + | TABits.ta_alloc_ctrl__tm_opb__no_list + | TABits.ta_alloc_ctrl__t_opb__no_list + | TABits.ta_alloc_ctrl__om_opb__no_list + | TABits.ta_alloc_ctrl__o_opb__8x4byte + ; - int fb_r_ctrl = - CoreBits.fb_r_ctrl__vclk_div__pclk_vclk_1 - | CoreBits.fb_r_ctrl__fb_depth__0888_rgb_32bit - | CoreBits.fb_r_ctrl__fb_enable; - Memory.putU4(Holly.FB_R_CTRL, fb_r_ctrl); + RegionArray.OPBSize[] opb_size = { + new RegionArray.OPBSize(8 * 4, // opaque + 0, // opaque_modifier_volume + 0, // translucent + 0, // translucent_modifier_volume + 0) // punch_through + }; - int red = 0x00ff7700; - int fb = 0xa5000000 + Memory.getU4(Holly.FB_R_SOF1); - for (int i = 0; i < 640 * 480; i++) { - Memory.putU4(fb + (i * 4), red); + int opb_size_total = opb_size[0].total(); + + int framebuffer_width = 640; + int framebuffer_height = 480; + int num_render_passes = opb_size.length; + + Core.fb_init(framebuffer_width, framebuffer_height); + + RegionArray.region_array(framebuffer_width / 32, + framebuffer_height / 32, + opb_size, + num_render_passes, + TextureMemoryAllocation.region_array_start[0], + TextureMemoryAllocation.object_list_start[0]); + RegionArray.region_array(framebuffer_width / 32, + framebuffer_height / 32, + opb_size, + num_render_passes, + TextureMemoryAllocation.region_array_start[1], + TextureMemoryAllocation.object_list_start[1]); + + int background_color = 0xffff00ff; + Background.background(TextureMemoryAllocation.background_start[0], + background_color); + Background.background(TextureMemoryAllocation.background_start[1], + background_color); + + //int ta = -1; + //int core = -2; + int core = 0; + int ta = 0; + while (true) { + TAFIFOPolygonConverter.init(TextureMemoryAllocation.isp_tsp_parameters_start[ta], + TextureMemoryAllocation.isp_tsp_parameters_end[ta], + TextureMemoryAllocation.object_list_start[ta], + TextureMemoryAllocation.object_list_end[ta], + opb_size_total, + ta_alloc, + framebuffer_width / 32, + framebuffer_height / 32); + transfer_scene(); + TAFIFOPolygonConverter.wait_opaque_list(); + Core.start_render(TextureMemoryAllocation.region_array_start[ta], + TextureMemoryAllocation.isp_tsp_parameters_start[ta], + TextureMemoryAllocation.background_start[ta], + TextureMemoryAllocation.framebuffer_start[core], + framebuffer_width); + Core.wait_end_of_render_tsp(); + Memory.putU4(Holly.FB_R_SOF1, TextureMemoryAllocation.framebuffer_start[core]); + core = (core + 1) % 1; } } } diff --git a/p/end_of_list.class.h b/p/end_of_list.class.h new file mode 100644 index 0000000..964e356 --- /dev/null +++ b/p/end_of_list.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_p_end_of_list_class_start __asm("_binary_p_end_of_list_class_start"); +extern uint32_t _binary_p_end_of_list_class_end __asm("_binary_p_end_of_list_class_end"); +extern uint32_t _binary_p_end_of_list_class_size __asm("_binary_p_end_of_list_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/p/polygon_type_0.class.h b/p/polygon_type_0.class.h new file mode 100644 index 0000000..be71425 --- /dev/null +++ b/p/polygon_type_0.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_p_polygon_type_0_class_start __asm("_binary_p_polygon_type_0_class_start"); +extern uint32_t _binary_p_polygon_type_0_class_end __asm("_binary_p_polygon_type_0_class_end"); +extern uint32_t _binary_p_polygon_type_0_class_size __asm("_binary_p_polygon_type_0_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/p/vertex_polygon_type_0.class.h b/p/vertex_polygon_type_0.class.h new file mode 100644 index 0000000..b46232d --- /dev/null +++ b/p/vertex_polygon_type_0.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_p_vertex_polygon_type_0_class_start __asm("_binary_p_vertex_polygon_type_0_class_start"); +extern uint32_t _binary_p_vertex_polygon_type_0_class_end __asm("_binary_p_vertex_polygon_type_0_class_end"); +extern uint32_t _binary_p_vertex_polygon_type_0_class_size __asm("_binary_p_vertex_polygon_type_0_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/regs/bits_java.py b/regs/bits_java.py index 44f2957..b57659e 100644 --- a/regs/bits_java.py +++ b/regs/bits_java.py @@ -8,14 +8,14 @@ def generate_bit(bit): else: name = f"{bit.register_name}__{bit.enum_name}__{bit.bit_name}".lower() - if not bit.value and not bit.mask: + if bit.value is None and bit.mask is None: yield f"public static int {name}(int n) {{" yield f"return (n >> {min(bit.bits)}) & {sign_extend(mask_from_bits(bit.bits), 32)};" yield "}" - elif bit.value: + elif bit.value is not None: assert (bit.value is None) ^ (bit.mask is None), bit yield f"public static final int {name} = {bit.value} << {min(bit.bits)};" - elif bit.mask: + elif bit.mask is not None: assert (bit.value is None) ^ (bit.mask is None), bit yield f"public static int {name}(int n) {{" if type(bit.mask) is str: diff --git a/sega/dreamcast/MemoryMap.class.h b/sega/dreamcast/MemoryMap.class.h new file mode 100644 index 0000000..ae38752 --- /dev/null +++ b/sega/dreamcast/MemoryMap.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_sega_dreamcast_MemoryMap_class_start __asm("_binary_sega_dreamcast_MemoryMap_class_start"); +extern uint32_t _binary_sega_dreamcast_MemoryMap_class_end __asm("_binary_sega_dreamcast_MemoryMap_class_end"); +extern uint32_t _binary_sega_dreamcast_MemoryMap_class_size __asm("_binary_sega_dreamcast_MemoryMap_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/Background.class.h b/sega/dreamcast/holly/Background.class.h new file mode 100644 index 0000000..21e47a9 --- /dev/null +++ b/sega/dreamcast/holly/Background.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_Background_class_start __asm("_binary_sega_dreamcast_holly_Background_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_Background_class_end __asm("_binary_sega_dreamcast_holly_Background_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_Background_class_size __asm("_binary_sega_dreamcast_holly_Background_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/Core.class.h b/sega/dreamcast/holly/Core.class.h new file mode 100644 index 0000000..c54a34e --- /dev/null +++ b/sega/dreamcast/holly/Core.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_Core_class_start __asm("_binary_sega_dreamcast_holly_Core_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_Core_class_end __asm("_binary_sega_dreamcast_holly_Core_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_Core_class_size __asm("_binary_sega_dreamcast_holly_Core_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/Core.java b/sega/dreamcast/holly/Core.java index 85a5266..af5f7d4 100644 --- a/sega/dreamcast/holly/Core.java +++ b/sega/dreamcast/holly/Core.java @@ -9,9 +9,6 @@ public class Core { } public static void init() { - int fb_w_ctrl = CoreBits.fb_w_ctrl__fb_dither - | CoreBits.fb_w_ctrl__fb_packmode__565_rgb_16bit; - int fpu_cull_val = 0x3f800000; // 1.0f int fpu_perp_val = 0; // 0.0f @@ -35,7 +32,6 @@ public class Core { int softreset = CoreBits.softreset__pipeline_soft_reset | CoreBits.softreset__ta_soft_reset; - Memory.putU4(Holly.FB_W_CTRL, fb_w_ctrl); Memory.putU4(Holly.FPU_CULL_VAL, fpu_cull_val); Memory.putU4(Holly.FPU_PERP_VAL, fpu_perp_val); Memory.putU4(Holly.FPU_PARAM_CFG, fpu_param_cfg); @@ -47,6 +43,45 @@ 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_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; + + 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_R_CTRL, fb_r_ctrl); + Memory.putU4(Holly.FB_W_CTRL, fb_w_ctrl); + } + public static void start_render(int region_array_start, int isp_tsp_parameters_start, int background_start, @@ -76,4 +111,23 @@ public class Core { Memory.putU4(Holly.STARTRENDER, 1); } + + public static void wait_end_of_render_tsp() { + int istnrm__end_of_render_tsp = 1 << 2; + while ((Memory.getU4(0xa05f6900) & istnrm__end_of_render_tsp) == 0) { + int isterr = Memory.getU4(0xa05f6908); + if (isterr != 0) { + System.out.print("isterr:"); + System.out.println(isterr); + Memory.putU4(Holly.SOFTRESET, CoreBits.softreset__pipeline_soft_reset); + Memory.putU4(Holly.SOFTRESET, 0); + Memory.putU4(0xa05f6908, isterr); + break; + } + }; + int istnrm = (1 << 2) // istnrm__end_of_render_tsp + | (1 << 1) // istnrm__end_of_render_isp + | (1 << 0); // istnrm__end_of_render_video; + Memory.putU4(0xa05f6900, istnrm); + } } diff --git a/sega/dreamcast/holly/ISPTSP.class.h b/sega/dreamcast/holly/ISPTSP.class.h new file mode 100644 index 0000000..d8e46ec --- /dev/null +++ b/sega/dreamcast/holly/ISPTSP.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_ISPTSP_class_start __asm("_binary_sega_dreamcast_holly_ISPTSP_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_ISPTSP_class_end __asm("_binary_sega_dreamcast_holly_ISPTSP_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_ISPTSP_class_size __asm("_binary_sega_dreamcast_holly_ISPTSP_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/RegionArray.class.h b/sega/dreamcast/holly/RegionArray.class.h new file mode 100644 index 0000000..eef002e --- /dev/null +++ b/sega/dreamcast/holly/RegionArray.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_class_start __asm("_binary_sega_dreamcast_holly_RegionArray_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_class_end __asm("_binary_sega_dreamcast_holly_RegionArray_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_class_size __asm("_binary_sega_dreamcast_holly_RegionArray_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/RegionArray_OPBSize.class.h b/sega/dreamcast/holly/RegionArray_OPBSize.class.h new file mode 100644 index 0000000..de60bb5 --- /dev/null +++ b/sega/dreamcast/holly/RegionArray_OPBSize.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_OPBSize_class_start __asm("_binary_sega_dreamcast_holly_RegionArray_OPBSize_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_OPBSize_class_end __asm("_binary_sega_dreamcast_holly_RegionArray_OPBSize_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_RegionArray_OPBSize_class_size __asm("_binary_sega_dreamcast_holly_RegionArray_OPBSize_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/TABits.class.h b/sega/dreamcast/holly/TABits.class.h new file mode 100644 index 0000000..60c91b1 --- /dev/null +++ b/sega/dreamcast/holly/TABits.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_TABits_class_start __asm("_binary_sega_dreamcast_holly_TABits_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_TABits_class_end __asm("_binary_sega_dreamcast_holly_TABits_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_TABits_class_size __asm("_binary_sega_dreamcast_holly_TABits_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/TAFIFOPolygonConverter.class.h b/sega/dreamcast/holly/TAFIFOPolygonConverter.class.h new file mode 100644 index 0000000..c2f6cb1 --- /dev/null +++ b/sega/dreamcast/holly/TAFIFOPolygonConverter.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_start __asm("_binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_end __asm("_binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_size __asm("_binary_sega_dreamcast_holly_TAFIFOPolygonConverter_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/TAParameter.class.h b/sega/dreamcast/holly/TAParameter.class.h new file mode 100644 index 0000000..9d1cf0d --- /dev/null +++ b/sega/dreamcast/holly/TAParameter.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern C { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_TAParameter_class_start __asm("_binary_sega_dreamcast_holly_TAParameter_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_TAParameter_class_end __asm("_binary_sega_dreamcast_holly_TAParameter_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_TAParameter_class_size __asm("_binary_sega_dreamcast_holly_TAParameter_class_size"); + +#ifdef __cplusplus +} +#endif diff --git a/sega/dreamcast/holly/TextureMemoryAllocation.class.h b/sega/dreamcast/holly/TextureMemoryAllocation.class.h new file mode 100644 index 0000000..282acc5 --- /dev/null +++ b/sega/dreamcast/holly/TextureMemoryAllocation.class.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_sega_dreamcast_holly_TextureMemoryAllocation_class_start __asm("_binary_sega_dreamcast_holly_TextureMemoryAllocation_class_start"); +extern uint32_t _binary_sega_dreamcast_holly_TextureMemoryAllocation_class_end __asm("_binary_sega_dreamcast_holly_TextureMemoryAllocation_class_end"); +extern uint32_t _binary_sega_dreamcast_holly_TextureMemoryAllocation_class_size __asm("_binary_sega_dreamcast_holly_TextureMemoryAllocation_class_size"); + +#ifdef __cplusplus +} +#endif