diff --git a/common.mk b/common.mk index 2ca3900..4f2de30 100644 --- a/common.mk +++ b/common.mk @@ -55,7 +55,8 @@ MAIN_OBJ = \ holly/background.o \ holly/region_array.o \ holly/ta_parameter.o \ - storequeue.o \ + holly/ta_fifo_polygon_converter.o \ + holly/core.o \ scene.o all: main.cdi @@ -139,6 +140,12 @@ audio.pcm: %.data.o: %.data $(BUILD_BINARY_O) +clean: + find -P \ + -regextype posix-egrep \ + -regex '.*\.(iso|o|bin|elf|cue|gch)$$' \ + -exec rm {} \; + .SUFFIXES: .INTERMEDIATE: .SECONDARY: diff --git a/holly/core.cpp b/holly/core.cpp new file mode 100644 index 0000000..7715260 --- /dev/null +++ b/holly/core.cpp @@ -0,0 +1,84 @@ +#include "float_uint32.h" +#include "core_bits.h" +#include "../holly.h" +#include "../memorymap.h" + +#include "texture_memory_alloc.h" + +#include "core.h" +#include "background.h" +#include "region_array.h" + +void core_init() +{ + holly.ISP_FEED_CFG = isp_feed_cfg::cache_size_for_translucency(0x200); + + holly.FPU_SHAD_SCALE = fpu_shad_scale::scale_factor_for_shadows(1); + holly.FPU_CULL_VAL = _i(1.f); + holly.FPU_PERP_VAL = _i(0.f); + holly.SPAN_SORT_CFG = span_sort_cfg::span_sort_enable + | span_sort_cfg::offset_sort_enable; + + holly.FOG_COL_RAM = fog_col_ram::red(127) + | fog_col_ram::green(127) + | fog_col_ram::blue(127); + + holly.FOG_COL_VERT = fog_col_vert::red(127) + | fog_col_vert::green(127) + | fog_col_vert::blue(127); + + holly.FOG_CLAMP_MIN = fog_clamp_min::alpha(0) + | fog_clamp_min::red(0) + | fog_clamp_min::green(0) + | fog_clamp_min::blue(0); + + holly.FOG_CLAMP_MAX = fog_clamp_max::alpha(255) + | fog_clamp_max::red(255) + | fog_clamp_max::green(255) + | fog_clamp_max::blue(255); + + holly.HALF_OFFSET = half_offset::tsp_texel_sampling_position::center + | half_offset::tsp_pixel_sampling_position::center + | half_offset::fpu_pixel_sampling_position::center; + + holly.FPU_PARAM_CFG = fpu_param_cfg::region_header_type::type_2 + | fpu_param_cfg::tsp_parameter_burst_threshold(31) + | fpu_param_cfg::isp_parameter_burst_threshold(31) + | fpu_param_cfg::pointer_burst_size(7) // must be less than opb size + | fpu_param_cfg::pointer_first_burst_size(7); // half of pointer burst size(?) +} + +void core_init_texture_memory() +{ + volatile texture_memory_alloc * mem = reinterpret_cast(texture_memory); + + background_parameter(mem->background); + region_array(mem->region_array, + (offsetof (struct texture_memory_alloc, object_list)), + 640 / 32, // width + 480 / 32 // height + ); +} + +void core_start_render(int fb) +{ + holly.REGION_BASE = (offsetof (struct texture_memory_alloc, region_array)); + holly.PARAM_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); + + holly.ISP_BACKGND_T = isp_backgnd_t::tag_address((offsetof (struct texture_memory_alloc, background)) / 4) + | isp_backgnd_t::tag_offset(0) + | isp_backgnd_t::skip(1); + holly.ISP_BACKGND_D = _i(1.f/100000); + + holly.FB_W_CTRL = 1 << 3 | fb_w_ctrl::fb_packmode::_565_rgb_16bit; + holly.FB_W_LINESTRIDE = (640 * 2) / 8; + + int w_fb = (!(!fb)) * 0x00096000; + int r_fb = (!fb) * 0x00096000; + holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; + holly.FB_W_SOF2 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; + holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; + holly.FB_R_SOF2 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; + + holly.STARTRENDER = 1; +} diff --git a/holly/core.h b/holly/core.h new file mode 100644 index 0000000..540c78d --- /dev/null +++ b/holly/core.h @@ -0,0 +1,5 @@ +#pragma once + +void core_init(); +void core_init_texture_memory(); +void core_start_render(int fb); diff --git a/holly/core_bits.h b/holly/core_bits.h index f114bd5..5761bde 100644 --- a/holly/core_bits.h +++ b/holly/core_bits.h @@ -148,18 +148,18 @@ namespace fpu_param_cfg { namespace half_offset { namespace tsp_texel_sampling_position { - constexpr uint32_t top_left(uint32_t reg) { return (reg >> 2) & 0x1; } - constexpr uint32_t center(uint32_t reg) { return (reg >> 2) & 0x1; } + constexpr uint32_t top_left = 1 << 2; + constexpr uint32_t center = 1 << 2; } namespace tsp_pixel_sampling_position { - constexpr uint32_t top_left(uint32_t reg) { return (reg >> 1) & 0x1; } - constexpr uint32_t center(uint32_t reg) { return (reg >> 1) & 0x1; } + constexpr uint32_t top_left = 1 << 1; + constexpr uint32_t center = 1 << 1; } namespace fpu_pixel_sampling_position { - constexpr uint32_t top_left(uint32_t reg) { return (reg >> 0) & 0x1; } - constexpr uint32_t center(uint32_t reg) { return (reg >> 0) & 0x1; } + constexpr uint32_t top_left = 1 << 0; + constexpr uint32_t center = 1 << 0; } } diff --git a/holly/ta_bits.h b/holly/ta_bits.h index 04b2917..40d84d0 100644 --- a/holly/ta_bits.h +++ b/holly/ta_bits.h @@ -33,8 +33,8 @@ namespace ta_glob_tile_clip { namespace ta_alloc_ctrl { namespace opb_mode { - constexpr uint32_t decreasing_addresses = 0 << 20; - constexpr uint32_t increasing_addresses = 1 << 20; + constexpr uint32_t increasing_addresses = 0 << 20; + constexpr uint32_t decreasing_addresses = 1 << 20; } namespace pt_opb { diff --git a/holly/ta_fifo_polygon_converter.cpp b/holly/ta_fifo_polygon_converter.cpp new file mode 100644 index 0000000..68f0d41 --- /dev/null +++ b/holly/ta_fifo_polygon_converter.cpp @@ -0,0 +1,87 @@ +#include + +#include "core_bits.h" +#include "ta_bits.h" +#include "../holly.h" +#include "../systembus.h" +#include "../systembus_bits.h" +#include "../sh7091.h" +#include "../sh7091_bits.h" + +#include "texture_memory_alloc.h" + +#include "ta_fifo_polygon_converter.h" + +void ta_polygon_converter_init() +{ + holly.SOFTRESET = softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + holly.TA_GLOB_TILE_CLIP = ta_glob_tile_clip::tile_y_num((480 / 32) - 1) + | ta_glob_tile_clip::tile_x_num((640 / 32) - 1); + + holly.TA_ALLOC_CTRL = ta_alloc_ctrl::opb_mode::increasing_addresses + | ta_alloc_ctrl::pt_opb::no_list + | ta_alloc_ctrl::tm_opb::no_list + | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::om_opb::no_list + | ta_alloc_ctrl::o_opb::_16x4byte; + + holly.TA_ISP_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); + holly.TA_ISP_LIMIT = (offsetof (struct texture_memory_alloc, object_list)); // the end of isp_tsp_parameters + holly.TA_OL_BASE = (offsetof (struct texture_memory_alloc, object_list)); + holly.TA_OL_LIMIT = (offsetof (struct texture_memory_alloc, _res0)); // the end of the object_list + holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)); + //holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)) + // + (640 / 32) * (320 / 32) * 16 * 4; + + holly.TA_LIST_INIT = ta_list_init::list_init; + + volatile uint32_t _dummy_read = holly.TA_LIST_INIT; + (void)_dummy_read; +} + +extern void serial_string(const char * s); + +void ta_polygon_converter_transfer(volatile uint32_t * buf, uint32_t size) +{ + /* wait for previous transfer to complete (if any) */ + //while ((system.C2DST & C2DST__STATUS) != 0); /* 1 == transfer is in progress */ + /* CHCR2__TE can be reset even if there is no in-progress transfer. Despite + DCDBSysArc990907E's claim, it does not appear to be useful to check TE. */ + //while ((sh7091.DMAC.CHCR2 & CHCR2__TE) == 0); /* 1 == all transfers are completed */ + + /* start a new CH2-DMA transfer from "system memory" to "TA FIFO polygon converter" */ + // this dummy read is required on real hardware. + volatile uint32_t _dummy = sh7091.DMAC.CHCR2; + (void)_dummy; + sh7091.DMAC.CHCR2 = 0; /* disable DMA channel */ + sh7091.DMAC.SAR2 = reinterpret_cast(&buf[0]); /* start address, must be aligned to a CHCHR__TS-sized (32-byte) boundary */ + sh7091.DMAC.DMATCR2 = DMATCR2__TRANSFER_COUNT(size / 32); /* transfer count, in CHCHR__TS-sized (32-byte) units */ + sh7091.DMAC.CHCR2 = CHCR2__DM__DESTINATION_ADDRESS_FIXED + | CHCR2__SM__SOURCE_ADDRESS_INCREMENTED + | CHCR2__RS(0b0010) /* external request, single address mode; + external address space → external device */ + | CHCR2__TM__BURST_MODE /* transmit mode */ + | CHCR2__TS__32_BYTE /* transfer size */ + | CHCR2__DE; /* DMAC (channel) enable */ + + sh7091.DMAC.DMAOR = DMAOR__DDT /* on-demand data transfer mode */ + | DMAOR__PR__CH2_CH0_CH1_CH3 /* priority mode; CH2 > CH0 > CH1 > CH3 */ + | DMAOR__DME; /* DMAC master enable */ + system.C2DSTAT = C2DSTAT__ADDRESS(0x10000000); /* CH2-DMA destination address */ + system.C2DLEN = CD2LEN__LENGTH(size) ; /* CH2-DMA length (must be a multiple of 32) */ + system.C2DST = 1; /* CH2-DMA start (an 'external' request from SH7091's perspective) */ + + // wait for CH2-DMA completion + while ((system.ISTNRM & ISTNRM__END_OF_DMA_CH2_DMA) == 0); + // reset CH2-DMA interrupt status + system.ISTNRM = ISTNRM__END_OF_DMA_CH2_DMA; +} + +void ta_wait_opaque_list() +{ + while ((system.ISTNRM & ISTNRM__END_OF_TRANSFERRING_OPAQUE_LIST) == 0); + + system.ISTNRM = ISTNRM__END_OF_TRANSFERRING_OPAQUE_LIST; +} diff --git a/holly/ta_fifo_polygon_converter.h b/holly/ta_fifo_polygon_converter.h new file mode 100644 index 0000000..f3e9f02 --- /dev/null +++ b/holly/ta_fifo_polygon_converter.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +void ta_polygon_converter_init(); +void ta_polygon_converter_transfer(volatile uint32_t * buf, uint32_t size); +void ta_wait_opaque_list(); diff --git a/holly/texture_memory_alloc.h b/holly/texture_memory_alloc.h new file mode 100644 index 0000000..c831b9b --- /dev/null +++ b/holly/texture_memory_alloc.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct texture_memory_alloc { + uint32_t isp_tsp_parameters[0x00100000 / 4]; // TA_ISP_BASE / PARAM_BASE (the actual objects) + uint32_t object_list[0x00100000 / 4]; // TA_OL_BASE (contains object pointer blocks) + uint32_t _res0[ 0x20 / 4]; // (the TA may clobber 4 bytes starting at TA_OL_LIMIT) + uint32_t region_array[0x00002000 / 4]; // REGION_BASE + uint32_t background[0x00000020 / 4]; // ISP_BACKGND_T + uint32_t framebuffer[2][0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 +}; diff --git a/main.cpp b/main.cpp index 2924ea5..e257e38 100644 --- a/main.cpp +++ b/main.cpp @@ -1,16 +1,18 @@ #include +#include "memorymap.h" + +#include "sh7091.h" +#include "sh7091_bits.h" +#include "holly.h" +#include "holly/core.h" +#include "holly/core_bits.h" +#include "holly/ta_fifo_polygon_converter.h" +#include "systembus.h" + #include "cache.h" #include "load.h" #include "vga.h" - -#include "sh7091.h" -#include "sh7091_bits.h" -#include "memorymap.h" -#include "systembus.h" -#include "holly.h" -#include "holly/core_bits.h" - #include "rgb.h" #include "scene.h" @@ -43,12 +45,15 @@ inline void serial_char(const char c) void serial_string(const char * s) { - return; while (*s != '\0') { serial_char(*s++); } } +/* must be aligned to 32-bytes for DMA transfer */ +// the aligned(32) attribute does not actually align to 32 bytes. +volatile uint32_t __attribute__((aligned(32))) scene[(32 * 5) / 4]; + extern "C" void main() { @@ -76,7 +81,6 @@ void main() } } - holly.SOFTRESET = softreset::pipeline_soft_reset | softreset::ta_soft_reset; holly.SOFTRESET = 0; @@ -86,22 +90,29 @@ void main() v_sync_out(); v_sync_in(); - scene_holly_init(); - scene_init_texture_memory(); + + core_init(); + core_init_texture_memory(); int frame = 0; + // the address of `scene` must be a multiple of 32 bytes + // this is mandatory for ch2-dma to the ta fifo polygon converter + if ((reinterpret_cast(scene) & 31) != 0) { + serial_string("unaligned\n"); + while(1); + } - while (1) { - scene_ta_init(); - scene_geometry_transfer(); - scene_wait_opaque_list(); - scene_start_render(frame); - frame = !frame; - - // I do not understand why, but flycast does not show the first-rendered - // framebuffer. - + while (true) { v_sync_out(); v_sync_in(); + + ta_polygon_converter_init(); + uint32_t ta_parameter_count = scene_transform(&scene[0]); + uint32_t ta_parameter_size = ta_parameter_count * 32; /* 32 bytes per parameter */ + ta_polygon_converter_transfer(&scene[0], ta_parameter_size); + ta_wait_opaque_list(); + core_start_render(frame); + + frame = !frame; } } diff --git a/regs/core_bits.csv b/regs/core_bits.csv index d70f83b..d2a82c0 100644 --- a/regs/core_bits.csv +++ b/regs/core_bits.csv @@ -83,12 +83,12 @@ "FPU_PARAM_CFG",,"7-4","pointer_burst_size",,"0xf",,,,,, "FPU_PARAM_CFG",,"3-0","pointer_first_burst_size",,"0xf",,,,,, ,,,,,,,,,,, -"HALF_OFFSET","tsp_texel_sampling_position",2,"top_left",,,,,,,, -"HALF_OFFSET","tsp_texel_sampling_position",2,"center",,,,,,,, -"HALF_OFFSET","tsp_pixel_sampling_position",1,"top_left",,,,,,,, -"HALF_OFFSET","tsp_pixel_sampling_position",1,"center",,,,,,,, -"HALF_OFFSET","fpu_pixel_sampling_position",0,"top_left",,,,,,,, -"HALF_OFFSET","fpu_pixel_sampling_position",0,"center",,,,,,,, +"HALF_OFFSET","tsp_texel_sampling_position",2,"top_left",1,,,,,,, +"HALF_OFFSET","tsp_texel_sampling_position",2,"center",1,,,,,,, +"HALF_OFFSET","tsp_pixel_sampling_position",1,"top_left",1,,,,,,, +"HALF_OFFSET","tsp_pixel_sampling_position",1,"center",1,,,,,,, +"HALF_OFFSET","fpu_pixel_sampling_position",0,"top_left",1,,,,,,, +"HALF_OFFSET","fpu_pixel_sampling_position",0,"center",1,,,,,,, ,,,,,,,,,,, "FPU_PERP_VAL",,"30-0","perpendicular_triangle_compare",,"float_0_8_23",,,,,, ,,,,,,,,,,, diff --git a/regs/core_bits.ods b/regs/core_bits.ods index 21a62de..f60fffd 100644 Binary files a/regs/core_bits.ods and b/regs/core_bits.ods differ diff --git a/regs/ta_bits.csv b/regs/ta_bits.csv index 6b9bf4d..6019e5a 100644 --- a/regs/ta_bits.csv +++ b/regs/ta_bits.csv @@ -14,8 +14,8 @@ "TA_GLOB_TILE_CLIP",,"19-16","tile_y_num",,"0xf", "TA_GLOB_TILE_CLIP",,"5-0","tile_x_num",,"0x1f", ,,,,,, -"TA_ALLOC_CTRL","opb_mode",20,"decreasing_addresses",0,, -"TA_ALLOC_CTRL","opb_mode",20,"increasing_addresses",1,, +"TA_ALLOC_CTRL","opb_mode",20,"increasing_addresses",0,, +"TA_ALLOC_CTRL","opb_mode",20,"decreasing_addresses",1,, "TA_ALLOC_CTRL","pt_opb","17-16","no_list",0,, "TA_ALLOC_CTRL","pt_opb","17-16","_8x4byte",1,, "TA_ALLOC_CTRL","pt_opb","17-16","_16x4byte",2,, diff --git a/regs/ta_bits.ods b/regs/ta_bits.ods index 6c5dcf4..a979772 100644 Binary files a/regs/ta_bits.ods and b/regs/ta_bits.ods differ diff --git a/scene.cpp b/scene.cpp index 7123887..636ed8a 100644 --- a/scene.cpp +++ b/scene.cpp @@ -1,31 +1,11 @@ #include -#include "holly/region_array.h" -#include "holly/background.h" #include "holly/ta_parameter.h" -#include "holly/core_bits.h" -#include "holly.h" -#include "ta.h" -#include "sh7091.h" - -#include "memorymap.h" -#include "storequeue.h" -#include "systembus.h" -#include "holly/float_uint32.h" - -struct texture_memory_alloc { - uint32_t isp_tsp_parameters[0x00100000 / 4]; // TA_ISP_BASE / PARAM_BASE (the actual objects) - uint32_t object_list[0x00100000 / 4]; // TA_OL_BASE (contains object pointer blocks) - uint32_t _res0[ 0x20 / 4]; // (the TA may clobber 4 bytes starting at TA_OL_LIMIT) - uint32_t region_array[0x00002000 / 4]; // REGION_BASE - uint32_t background[0x00000020 / 4]; // ISP_BACKGND_T - uint32_t framebuffer[2][0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 -}; /* - 0,-.5 - | - --- + 0,-.5 + | + --- -0.5,0.5 | 0.5,0.5 */ @@ -35,108 +15,16 @@ float scene_triangle[3][3] = { { -0.5f, 0.5f, 1/10.f}, }; -void scene_holly_init() -{ - holly.ISP_FEED_CFG = ISP_FEED_CFG__TRANSLUCENCY_CACHE_SIZE(0x200); - - holly.FPU_SHAD_SCALE = FPU_SHAD_SCALE__SCALE_FACTOR(1); - holly.FPU_CULL_VAL = _i(1.f); - holly.FPU_PERP_VAL = _i(0.f); - holly.SPAN_SORT_CFG = SPAN_SORT_CFG__SPAN_SORT_ENABLE - | SPAN_SORT_CFG__OFFSET_SORT_ENABLE; - - holly.FOG_COL_RAM = FOG_COL_RAM__RED(127) - | FOG_COL_RAM__GREEN(127) - | FOG_COL_RAM__BLUE(127); - - holly.FOG_COL_VERT = FOG_COL_VERT__RED(127) - | FOG_COL_VERT__GREEN(127) - | FOG_COL_VERT__BLUE(127); - - holly.FOG_CLAMP_MIN = FOG_CLAMP_MIN__ALPHA(0) - | FOG_CLAMP_MIN__RED(0) - | FOG_CLAMP_MIN__GREEN(0) - | FOG_CLAMP_MIN__BLUE(0); - - holly.FOG_CLAMP_MAX = FOG_CLAMP_MAX__ALPHA(255) - | FOG_CLAMP_MAX__RED(255) - | FOG_CLAMP_MAX__GREEN(255) - | FOG_CLAMP_MAX__BLUE(255); - - holly.HALF_OFFSET = HALF_OFFSET__TSP_TEXEL_SAMPLE_POSITION_CENTER - | HALF_OFFSET__TSP_PIXEL_SAMPLE_POSITION_CENTER - | HALF_OFFSET__FPU_PIXEL_SAMPLE_POSITION_CENTER; - - holly.FPU_PARAM_CFG = FPU_PARAM_CFG__REGION_HEADER_TYPE__2 - | FPU_PARAM_CFG__TSP_PARAMETER_BURST_TRIGGER(31) - | FPU_PARAM_CFG__ISP_PARAMETER_BURST_TRIGGER(31) - | FPU_PARAM_CFG__POINTER_BURST_SIZE(7) // must be less than OPB size - | FPU_PARAM_CFG__POINTER_FIRST_BURST_SIZE(7); // half of pointer burst size(?) -} - -void scene_ta_init() -{ - holly.SOFTRESET = SOFTRESET__TA_SOFT_RESET; - holly.SOFTRESET = 0; - - holly.TA_GLOB_TILE_CLIP = TA_GLOB_TILE_CLIP__TILE_Y_NUM((480 / 32) - 1) - | TA_GLOB_TILE_CLIP__TILE_X_NUM((640 / 32) - 1); - - holly.TA_ALLOC_CTRL = TA_ALLOC_CTRL__OPB_MODE_INCREASING - | TA_ALLOC_CTRL__PT_OPB__NONE - | TA_ALLOC_CTRL__TM_OPB__NONE - | TA_ALLOC_CTRL__T_OPB__NONE - | TA_ALLOC_CTRL__OM_OPB__NONE - | TA_ALLOC_CTRL__O_OPB__16; - - holly.TA_ISP_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); - holly.TA_ISP_LIMIT = (offsetof (struct texture_memory_alloc, object_list)); // the end of isp_tsp_parameters - holly.TA_OL_BASE = (offsetof (struct texture_memory_alloc, object_list)); - holly.TA_OL_LIMIT = (offsetof (struct texture_memory_alloc, _res0)); // the end of the object_list - holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)); - //holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)) - // + (640 / 32) * (320 / 32) * 16 * 4; - - holly.TA_LIST_INIT = TA_LIST_INIT__LIST_INIT; - - volatile uint32_t _dummy_read = holly.TA_LIST_INIT; - (void)_dummy_read; -} - -void scene_wait_opaque_list() -{ - while ((system.ISTNRM & SB_ISTNRM__TAEOINT) == 0); - - system.ISTNRM = SB_ISTNRM__TAEOINT; -} - static float theta = 0; -constexpr float degree = 0.01745329f; +constexpr float one_degree = 0.01745329f; -void scene_geometry_transfer() +uint32_t scene_transform(volatile uint32_t * scene) { - /* - triangle(store_queue); - sq_transfer_32byte(ta_fifo_polygon_converter); + uint32_t ix = 0; - for (int i = 0; i < 3; i++) { - bool end_of_strip = i == 2; + triangle(&scene[(32 * ix) / 4]); + ix++; - vertex(store_queue, - scene_triangle[i][0], // x - scene_triangle[i][1], // y - scene_triangle[i][2], // z - 0xffff00ff, // base_color - end_of_strip); - - sq_transfer_32byte(ta_fifo_polygon_converter); - } - - end_of_list(store_queue); - sq_transfer_32byte(ta_fifo_polygon_converter); - */ - uint32_t __attribute__((aligned(32))) scene[(32 * 5) / 4]; - triangle(&scene[(32 * 0) / 4]); for (int i = 0; i < 3; i++) { bool end_of_strip = i == 2; @@ -150,69 +38,19 @@ void scene_geometry_transfer() x += 320.f; y += 240.f; - vertex(&scene[(32 * (i + 1)) / 4], + vertex(&scene[(32 * ix) / 4], x, // x y, // y scene_triangle[i][2], // z 0xffff00ff, // base_color end_of_strip); + ix++; } - end_of_list(&scene[(32 * 4) / 4]); - theta += degree; - volatile uint32_t _dummy = sh7091.DMAC.CHCR2; - (void)_dummy; - sh7091.DMAC.CHCR2 = 0; - sh7091.DMAC.SAR2 = reinterpret_cast(&scene[0]); - sh7091.DMAC.DMATCR2 = (32 * 5) / 32; - // SM(1) {source address increment} - // | RS(2) {external request, single address mode} - // | TM {burst mode} - // | TS(2) {32-byte block} - // | DE {enable channel} - sh7091.DMAC.CHCR2 = 0x12c1; - sh7091.DMAC.DMAOR = 0x8201; - system.C2DSTAT = 0x10000000; - system.C2DLEN = 32 * 5; - system.C2DST = 1; + end_of_list(&scene[(32 * ix) / 4]); + ix++; - while ((system.ISTNRM & (1 << 19)) == 0); - system.ISTNRM = (1 << 19); -} - -void scene_init_texture_memory() -{ - volatile texture_memory_alloc * mem = reinterpret_cast(texture_memory); - - background_parameter(mem->background); - region_array(mem->region_array, - (offsetof (struct texture_memory_alloc, object_list)), - 640 / 32, // width - 480 / 32 // height - ); -} - -void scene_start_render(int fb) -{ - holly.REGION_BASE = (offsetof (struct texture_memory_alloc, region_array)); - holly.PARAM_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); - - holly.ISP_BACKGND_T = ISP_BACKGND_T__TAG_ADDRESS((offsetof (struct texture_memory_alloc, background)) / 4) - | ISP_BACKGND_T__TAG_OFFSET(0) - | ISP_BACKGND_T__SKIP(1); - holly.ISP_BACKGND_D = _i(1.f/100000); - - //holly.SOFTRESET = softreset::pipeline_soft_reset; - - holly.FB_W_CTRL = 1 << 3 | FB_W_CTRL__FB_PACKMODE__565_RGB; - holly.FB_W_LINESTRIDE = (640 * 2) / 8; - - int w_fb = (!(!fb)) * 0x00096000; - int r_fb = (!fb) * 0x00096000; - holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + w_fb; - holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)) + r_fb; - - //holly.SOFTRESET = 0; - - holly.STARTRENDER = 1; + theta += one_degree; + + return ix; } diff --git a/scene.h b/scene.h index 0326f6b..1817f99 100644 --- a/scene.h +++ b/scene.h @@ -1,8 +1,5 @@ #pragma once -void scene_holly_init(); -void scene_ta_init(); -void scene_init_texture_memory(); -void scene_geometry_transfer(); -void scene_wait_opaque_list(); -void scene_start_render(int fb); +#include + +uint32_t scene_transform(volatile uint32_t * scene); diff --git a/sh7091_bits.h b/sh7091_bits.h index 794b464..e5996c1 100644 --- a/sh7091_bits.h +++ b/sh7091_bits.h @@ -28,3 +28,74 @@ #define SCFSR2__PER (1 << 2) /* parity error */ #define SCFSR2__RDF (1 << 1) /* receive FIFO data full */ #define SCFSR2__DR (1 << 0) /* receive data ready */ + +#define DMAOR__DDT (1 << 15) /* on-demand data transfer mode */ +/* priority mode */ +#define DMAOR__PR__CH0_CH1_CH2_CH3 (0b11 << 8) +#define DMAOR__PR__CH0_CH2_CH3_CH1 (0b01 << 8) +#define DMAOR__PR__CH2_CH0_CH1_CH3 (0b10 << 8) +#define DMAOR__PR__ROUND_ROBIN (0b11 << 8) +#define DMAOR__AE (1 << 2) /* address error flag; clear-only */ +#define DMAOR__NMIF (1 << 1) /* non-maskable interrupt flag; clear-only */ +#define DMAOR__DME (1 << 0) /* DMAC master enable */ + +/* source address space attribute specification */ +#define CHCR2__SSA__RESERVED_IN_PCMCIA_ACCESS (0b000 << 29) +#define CHCR2__SSA__DYNAMIC_BUS_SIZING_IO_SPACE (0b001 << 29) +#define CHCR2__SSA__8BIT_IO_SPACE (0b010 << 29) +#define CHCR2__SSA__16BIT_IO_SPACE (0b011 << 29) +#define CHCR2__SSA__8BIT_COMMON_MEMORY_SPACE (0b100 << 29) +#define CHCR2__SSA__16BIT_COMMON_MEMORY_SPACE (0b101 << 29) +#define CHCR2__SSA__8BIT_ATTRIBUTE_MEMORY_SPACE (0b110 << 29) +#define CHCR2__SSA__16BIT_ATTRIBUTE_MEMORY_SPACE (0b111 << 29) +/* source address wait control select */ +#define CHCR2__STC__C5_SPACE_WAIT_CYCLE_SELECTION (0 << 28) +#define CHCR2__STC__C6_SPACE_WAIT_CYCLE_SELECTION (1 << 28) +/* destination address space attribute specification */ +#define CHCR2__DSA__RESERVED_IN_PCMCIA_ACCESS (0b000 << 25) +#define CHCR2__DSA__DYNAMIC_BUS_SIZING_IO_SPACE (0b001 << 25) +#define CHCR2__DSA__8BIT_IO_SPACE (0b010 << 25) +#define CHCR2__DSA__16BIT_IO_SPACE (0b011 << 25) +#define CHCR2__DSA__8BIT_COMMON_MEMORY_SPACE (0b100 << 25) +#define CHCR2__DSA__16BIT_COMMON_MEMORY_SPACE (0b101 << 25) +#define CHCR2__DSA__8BIT_ATTRIBUTE_MEMORY_SPACE (0b110 << 25) +#define CHCR2__DSA__16BIT_ATTRIBUTE_MEMORY_SPACE (0b111 << 25) +/* destination address wait control select */ +#define CHCR2__DTC__C5_SPACE_WAIT_CYCLE_SELECTION (0 << 24) +#define CHCR2__DTC__C6_SPACE_WAIT_CYCLE_SELECTION (1 << 24) +/* DREQ select */ +#define CHCR2__DS__LOW_LEVEL_DETECTION (0 << 19) +#define CHCR2__DS__FALLING_EDGE_DETECTION (1 << 19) +/* request check level */ +#define CHCR2__RL__DRAK_IS_AN_ACTIVE_HIGH_OUTPUT (0 << 18) +#define CHCR2__RL__DRAK_IS_AN_ACTIVE_LOW_OUTPUT (1 << 18) +/* acknowledge mode */ +#define CHCR2__AM__DACK_IS_OUTPUT_IN_READ_CYCLE (0 << 17) +#define CHCR2__AM__DACK_IS_OUTPUT_IN_WRITE_CYCLE (1 << 17) +/* acknowledge level */ +#define CHCR2__AL__ACTIVE_HIGH_OUTPUT (0 << 16) +#define CHCR2__AL__ACTIVE_LOW_OUTPUT (1 << 16) +/* destination address mode */ +#define CHCR2__DM__DESTINATION_ADDRESS_FIXED (0b00 << 14) +#define CHCR2__DM__DESTINATION_ADDRESS_INCREMENTED (0b01 << 14) +#define CHCR2__DM__DESTINATION_ADDRESS_DECREMENTED (0b10 << 14) +/* source address mode */ +#define CHCR2__SM__SOURCE_ADDRESS_FIXED (0b00 << 12) +#define CHCR2__SM__SOURCE_ADDRESS_INCREMENTED (0b01 << 12) +#define CHCR2__SM__SOURCE_ADDRESS_DECREMENTED (0b10 << 12) +/* resource select */ +#define CHCR2__RS(n) (((n) & 0b1111) << 8) +/* transmit mode */ +#define CHCR2__TM__CYCLE_STEAL_MODE (0 << 7) +#define CHCR2__TM__BURST_MODE (1 << 7) +/* transmit size */ +#define CHCR2__TS__64_BIT (0b000 << 4) +#define CHCR2__TS__8_BIT (0b001 << 4) +#define CHCR2__TS__16_BIT (0b010 << 4) +#define CHCR2__TS__32_BIT (0b011 << 4) +#define CHCR2__TS__32_BYTE (0b100 << 4) +#define CHCR2__IE (1 << 2) /* interrupt enable */ +#define CHCR2__TE (1 << 1) /* transfer end; clear only */ +#define CHCR2__DE (1 << 0) /* DMAC (channel) enable */ + +#define DMATCR2__TRANSFER_COUNT(n) (((n) & 0xffffff) << 0) diff --git a/storequeue.cpp b/storequeue.cpp index be5f210..e3d05ed 100644 --- a/storequeue.cpp +++ b/storequeue.cpp @@ -4,8 +4,7 @@ void sq_transfer_32byte(volatile void * dst) { // dst typically 0x10000000 (ta polygon converter) - //sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; - sh7091.CCN.QACR0 = 0xac; + sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; // start 32-byte transfer from store queue 0 (SQ0) to QACR0 asm volatile ("pref @%0" diff --git a/systembus_bits.h b/systembus_bits.h new file mode 100644 index 0000000..f93ebcb --- /dev/null +++ b/systembus_bits.h @@ -0,0 +1,28 @@ +#define C2DST__STATUS (1 << 0) + +#define CD2LEN__LENGTH(n) (((n) & 0xffffe0) << 0) + +#define C2DSTAT__ADDRESS(n) ((((n) & 0x13ffffe0) | 0x10000000) << 0) + +#define ISTNRM__END_OF_TRANSFERRING_PUNCH_THROUGH_LIST (1 << 21) +#define ISTNRM__END_OF_DMA_SORT_DMA (1 << 20) +#define ISTNRM__END_OF_DMA_CH2_DMA (1 << 19) +#define ISTNRM__END_OF_DMA_DEV_DMA (1 << 18) +#define ISTNRM__END_OF_DMA_EXT_DMA2 (1 << 17) +#define ISTNRM__END_OF_DMA_EXT_DMA1 (1 << 16) +#define ISTNRM__END_OF_DMA_AICA_DMA (1 << 15) +#define ISTNRM__END_OF_DMA_GD_DMA (1 << 14) +#define ISTNRM__MAPLE_V_BLANK_OVER_INTERRUPT (1 << 13) +#define ISTNRM__END_OF_DMA_MAPLE_DMA (1 << 12) +#define ISTNRM__END_OF_DMA_PVR_DMA (1 << 11) +#define ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_MODIFIER_VOLUME_LIST (1 << 10) +#define ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_LIST (1 << 9) +#define ISTNRM__END_OF_TRANSFERRING_OPAQUE_MODIFIER_VOLUME_LIST (1 << 8) +#define ISTNRM__END_OF_TRANSFERRING_OPAQUE_LIST (1 << 7) +#define ISTNRM__END_OF_TRANSFERRING_YUV (1 << 6) +#define ISTNRM__H_BLANK_IN_INTERRUPT (1 << 5) +#define ISTNRM__V_BLANK_OUT_INTERRUPT (1 << 4) +#define ISTNRM__V_BLANK_IN_INTERRUPT (1 << 3) +#define ISTNRM__END_OF_RENDER_TSP (1 << 2) +#define ISTNRM__END_OF_RENDER_ISP (1 << 1) +#define ISTNRM__END_OF_RENDER_VIDEO (1 << 0) diff --git a/ta.h b/ta.h deleted file mode 100644 index 6dd6715..0000000 --- a/ta.h +++ /dev/null @@ -1,84 +0,0 @@ -#define ISP_FEED_CFG__TRANSLUCENCY_CACHE_SIZE(n) (((n) & 0x3ff) << 14) - -#define FPU_SHAD_SCALE__INTENSITY_SHADOW_ENABLE (1 << 8) -#define FPU_SHAD_SCALE__SCALE_FACTOR(n) (((n) & 0xff) << 0) - -#define SPAN_SORT_CFG__CACHE_BYPASS (1 << 16) -#define SPAN_SORT_CFG__OFFSET_SORT_ENABLE (1 << 8) -#define SPAN_SORT_CFG__SPAN_SORT_ENABLE (1 << 0) - -#define FOG_COL_RAM__RED(n) (((n) & 0xff) << 16) -#define FOG_COL_RAM__GREEN(n) (((n) & 0xff) << 8) -#define FOG_COL_RAM__BLUE(n) (((n) & 0xff) << 0) - -#define FOG_COL_VERT__RED(n) (((n) & 0xff) << 16) -#define FOG_COL_VERT__GREEN(n) (((n) & 0xff) << 8) -#define FOG_COL_VERT__BLUE(n) (((n) & 0xff) << 0) - -#define FOG_CLAMP_MIN__ALPHA(n) (((n) & 0xff) << 24) -#define FOG_CLAMP_MIN__RED(n) (((n) & 0xff) << 16) -#define FOG_CLAMP_MIN__GREEN(n) (((n) & 0xff) << 8) -#define FOG_CLAMP_MIN__BLUE(n) (((n) & 0xff) << 0) - -#define FOG_CLAMP_MAX__ALPHA(n) (((n) & 0xff) << 24) -#define FOG_CLAMP_MAX__RED(n) (((n) & 0xff) << 16) -#define FOG_CLAMP_MAX__GREEN(n) (((n) & 0xff) << 8) -#define FOG_CLAMP_MAX__BLUE(n) (((n) & 0xff) << 0) - -#define HALF_OFFSET__TSP_TEXEL_SAMPLE_POSITION_CENTER (1 << 2) -#define HALF_OFFSET__TSP_PIXEL_SAMPLE_POSITION_CENTER (1 << 1) -#define HALF_OFFSET__FPU_PIXEL_SAMPLE_POSITION_CENTER (1 << 0) - -#define FPU_PARAM_CFG__REGION_HEADER_TYPE__1 (0 << 21) -#define FPU_PARAM_CFG__REGION_HEADER_TYPE__2 (1 << 21) -#define FPU_PARAM_CFG__TSP_PARAMETER_BURST_TRIGGER(n) (((n) & 0x3f) << 14) -#define FPU_PARAM_CFG__ISP_PARAMETER_BURST_TRIGGER(n) (((n) & 0x3f) << 8) -#define FPU_PARAM_CFG__POINTER_BURST_SIZE(n) (((n) & 0xf) << 4) -#define FPU_PARAM_CFG__POINTER_FIRST_BURST_SIZE(n) (((n) & 0xf) << 0) - -// -------------------- - -#define TA_GLOB_TILE_CLIP__TILE_Y_NUM(n) (((n) & 0b1111) << 16) -#define TA_GLOB_TILE_CLIP__TILE_X_NUM(n) (((n) & 0b11111) << 0) - -#define TA_ALLOC_CTRL__OPB_MODE_INCREASING (0 << 20) -#define TA_ALLOC_CTRL__OPB_MODE_DECREASING (1 << 20) -#define TA_ALLOC_CTRL__PT_OPB__NONE (0b00 << 16) -#define TA_ALLOC_CTRL__PT_OPB__8 (0b01 << 16) -#define TA_ALLOC_CTRL__PT_OPB__16 (0b10 << 16) -#define TA_ALLOC_CTRL__PT_OPB__32 (0b11 << 16) -#define TA_ALLOC_CTRL__TM_OPB__NONE (0b00 << 12) -#define TA_ALLOC_CTRL__TM_OPB__8 (0b01 << 12) -#define TA_ALLOC_CTRL__TM_OPB__16 (0b10 << 12) -#define TA_ALLOC_CTRL__TM_OPB__32 (0b11 << 12) -#define TA_ALLOC_CTRL__T_OPB__NONE (0b00 << 8) -#define TA_ALLOC_CTRL__T_OPB__8 (0b01 << 8) -#define TA_ALLOC_CTRL__T_OPB__16 (0b10 << 8) -#define TA_ALLOC_CTRL__T_OPB__32 (0b11 << 8) -#define TA_ALLOC_CTRL__OM_OPB__NONE (0b00 << 4) -#define TA_ALLOC_CTRL__OM_OPB__8 (0b01 << 4) -#define TA_ALLOC_CTRL__OM_OPB__16 (0b10 << 4) -#define TA_ALLOC_CTRL__OM_OPB__32 (0b11 << 4) -#define TA_ALLOC_CTRL__O_OPB__NONE (0b00 << 0) -#define TA_ALLOC_CTRL__O_OPB__8 (0b01 << 0) -#define TA_ALLOC_CTRL__O_OPB__16 (0b10 << 0) -#define TA_ALLOC_CTRL__O_OPB__32 (0b11 << 0) - -#define SOFTRESET__SDRAM_IF_SOFT_RESET (1 << 2) -#define SOFTRESET__CORE_SOFT_RESET (1 << 1) -#define SOFTRESET__TA_SOFT_RESET (1 << 0) - -#define TA_LIST_INIT__LIST_INIT (1 << 31) - -#define SB_ISTNRM__TAEOINT (1 << 7) // End of Transferring interrupt : Opaque List - -#define FB_W_CTRL__FB_PACKMODE__565_RGB (1 << 0); - -#define ISP_BACKGND_T__CACHE_BYPASS (1 << 28) -#define ISP_BACKGND_T__SHADOW (1 << 27) -#define ISP_BACKGND_T__SKIP(n) (((n) & 0b111) << 24) -//#define ISP_BACKGND_T__TAG_ADDRESS(n) ((n) & 0xfffff8) -#define ISP_BACKGND_T__TAG_ADDRESS(n) (((n) & 0x3fffff) << 3) -#define ISP_BACKGND_T__TAG_OFFSET(n) (((n) & 0b111) << 0) - -// ---------- diff --git a/texture_memory_alloc.h b/texture_memory_alloc.h new file mode 100644 index 0000000..5118577 --- /dev/null +++ b/texture_memory_alloc.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct __attribute__((__packed__)) texture_memory_alloc { + uint32_t isp_tsp_parameters[0x00100000 / 4]; // TA_ISP_BASE / PARAM_BASE (the actual objects) + uint32_t object_list[0x00100000 / 4]; // TA_OL_BASE (contains object pointer blocks) + uint32_t _res0[ 0x20 / 4]; // (the TA may clobber 4 bytes starting at TA_OL_LIMIT) + uint32_t region_array[0x00002000 / 4]; // REGION_BASE + uint32_t background[0x00000020 / 4]; // ISP_BACKGND_T + uint32_t framebuffer[2][0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 +};