_bits: use more bits generated from spreadsheets

This rearranges scene.cpp to a file organization that more closely
follows which code is responsible for what area of (hardware)
initialization.

All TA and CORE register accesses now use the new ta_bits.h and
core_bits.h, respectively.
This commit is contained in:
Zack Buhman 2023-12-05 00:16:38 +08:00
parent 963aa75990
commit b99722a6df
20 changed files with 382 additions and 308 deletions

View File

@ -55,7 +55,8 @@ MAIN_OBJ = \
holly/background.o \ holly/background.o \
holly/region_array.o \ holly/region_array.o \
holly/ta_parameter.o \ holly/ta_parameter.o \
storequeue.o \ holly/ta_fifo_polygon_converter.o \
holly/core.o \
scene.o scene.o
all: main.cdi all: main.cdi
@ -139,6 +140,12 @@ audio.pcm:
%.data.o: %.data %.data.o: %.data
$(BUILD_BINARY_O) $(BUILD_BINARY_O)
clean:
find -P \
-regextype posix-egrep \
-regex '.*\.(iso|o|bin|elf|cue|gch)$$' \
-exec rm {} \;
.SUFFIXES: .SUFFIXES:
.INTERMEDIATE: .INTERMEDIATE:
.SECONDARY: .SECONDARY:

84
holly/core.cpp Normal file
View File

@ -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<volatile texture_memory_alloc *>(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;
}

5
holly/core.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void core_init();
void core_init_texture_memory();
void core_start_render(int fb);

View File

@ -148,18 +148,18 @@ namespace fpu_param_cfg {
namespace half_offset { namespace half_offset {
namespace tsp_texel_sampling_position { namespace tsp_texel_sampling_position {
constexpr uint32_t top_left(uint32_t reg) { return (reg >> 2) & 0x1; } constexpr uint32_t top_left = 1 << 2;
constexpr uint32_t center(uint32_t reg) { return (reg >> 2) & 0x1; } constexpr uint32_t center = 1 << 2;
} }
namespace tsp_pixel_sampling_position { namespace tsp_pixel_sampling_position {
constexpr uint32_t top_left(uint32_t reg) { return (reg >> 1) & 0x1; } constexpr uint32_t top_left = 1 << 1;
constexpr uint32_t center(uint32_t reg) { return (reg >> 1) & 0x1; } constexpr uint32_t center = 1 << 1;
} }
namespace fpu_pixel_sampling_position { namespace fpu_pixel_sampling_position {
constexpr uint32_t top_left(uint32_t reg) { return (reg >> 0) & 0x1; } constexpr uint32_t top_left = 1 << 0;
constexpr uint32_t center(uint32_t reg) { return (reg >> 0) & 0x1; } constexpr uint32_t center = 1 << 0;
} }
} }

View File

@ -33,8 +33,8 @@ namespace ta_glob_tile_clip {
namespace ta_alloc_ctrl { namespace ta_alloc_ctrl {
namespace opb_mode { namespace opb_mode {
constexpr uint32_t decreasing_addresses = 0 << 20; constexpr uint32_t increasing_addresses = 0 << 20;
constexpr uint32_t increasing_addresses = 1 << 20; constexpr uint32_t decreasing_addresses = 1 << 20;
} }
namespace pt_opb { namespace pt_opb {

View File

@ -0,0 +1,87 @@
#include <cstdint>
#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<uint32_t>(&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;
}

View File

@ -0,0 +1,7 @@
#pragma once
#include <cstdint>
void ta_polygon_converter_init();
void ta_polygon_converter_transfer(volatile uint32_t * buf, uint32_t size);
void ta_wait_opaque_list();

View File

@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
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
};

View File

@ -1,16 +1,18 @@
#include <stdint.h> #include <stdint.h>
#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 "cache.h"
#include "load.h" #include "load.h"
#include "vga.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 "rgb.h"
#include "scene.h" #include "scene.h"
@ -43,12 +45,15 @@ inline void serial_char(const char c)
void serial_string(const char * s) void serial_string(const char * s)
{ {
return;
while (*s != '\0') { while (*s != '\0') {
serial_char(*s++); 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" extern "C"
void main() void main()
{ {
@ -76,7 +81,6 @@ void main()
} }
} }
holly.SOFTRESET = softreset::pipeline_soft_reset holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset; | softreset::ta_soft_reset;
holly.SOFTRESET = 0; holly.SOFTRESET = 0;
@ -86,22 +90,29 @@ void main()
v_sync_out(); v_sync_out();
v_sync_in(); v_sync_in();
scene_holly_init();
scene_init_texture_memory(); core_init();
core_init_texture_memory();
int frame = 0; 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<uint32_t>(scene) & 31) != 0) {
serial_string("unaligned\n");
while(1);
}
while (1) { while (true) {
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.
v_sync_out(); v_sync_out();
v_sync_in(); 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;
} }
} }

View File

@ -83,12 +83,12 @@
"FPU_PARAM_CFG",,"7-4","pointer_burst_size",,"0xf",,,,,, "FPU_PARAM_CFG",,"7-4","pointer_burst_size",,"0xf",,,,,,
"FPU_PARAM_CFG",,"3-0","pointer_first_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,"top_left",1,,,,,,,
"HALF_OFFSET","tsp_texel_sampling_position",2,"center",,,,,,,, "HALF_OFFSET","tsp_texel_sampling_position",2,"center",1,,,,,,,
"HALF_OFFSET","tsp_pixel_sampling_position",1,"top_left",,,,,,,, "HALF_OFFSET","tsp_pixel_sampling_position",1,"top_left",1,,,,,,,
"HALF_OFFSET","tsp_pixel_sampling_position",1,"center",,,,,,,, "HALF_OFFSET","tsp_pixel_sampling_position",1,"center",1,,,,,,,
"HALF_OFFSET","fpu_pixel_sampling_position",0,"top_left",,,,,,,, "HALF_OFFSET","fpu_pixel_sampling_position",0,"top_left",1,,,,,,,
"HALF_OFFSET","fpu_pixel_sampling_position",0,"center",,,,,,,, "HALF_OFFSET","fpu_pixel_sampling_position",0,"center",1,,,,,,,
,,,,,,,,,,, ,,,,,,,,,,,
"FPU_PERP_VAL",,"30-0","perpendicular_triangle_compare",,"float_0_8_23",,,,,, "FPU_PERP_VAL",,"30-0","perpendicular_triangle_compare",,"float_0_8_23",,,,,,
,,,,,,,,,,, ,,,,,,,,,,,

1 register_name enum_name bits bit_name value mask description
83 FPU_PARAM_CFG 7-4 pointer_burst_size 0xf
84 FPU_PARAM_CFG 3-0 pointer_first_burst_size 0xf
85
86 HALF_OFFSET tsp_texel_sampling_position 2 top_left 1
87 HALF_OFFSET tsp_texel_sampling_position 2 center 1
88 HALF_OFFSET tsp_pixel_sampling_position 1 top_left 1
89 HALF_OFFSET tsp_pixel_sampling_position 1 center 1
90 HALF_OFFSET fpu_pixel_sampling_position 0 top_left 1
91 HALF_OFFSET fpu_pixel_sampling_position 0 center 1
92
93 FPU_PERP_VAL 30-0 perpendicular_triangle_compare float_0_8_23
94

Binary file not shown.

View File

@ -14,8 +14,8 @@
"TA_GLOB_TILE_CLIP",,"19-16","tile_y_num",,"0xf", "TA_GLOB_TILE_CLIP",,"19-16","tile_y_num",,"0xf",
"TA_GLOB_TILE_CLIP",,"5-0","tile_x_num",,"0x1f", "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",0,,
"TA_ALLOC_CTRL","opb_mode",20,"increasing_addresses",1,, "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","no_list",0,,
"TA_ALLOC_CTRL","pt_opb","17-16","_8x4byte",1,, "TA_ALLOC_CTRL","pt_opb","17-16","_8x4byte",1,,
"TA_ALLOC_CTRL","pt_opb","17-16","_16x4byte",2,, "TA_ALLOC_CTRL","pt_opb","17-16","_16x4byte",2,,

1 register_name enum_name bits bit_name value mask description
14 TA_GLOB_TILE_CLIP 19-16 tile_y_num 0xf
15 TA_GLOB_TILE_CLIP 5-0 tile_x_num 0x1f
16
17 TA_ALLOC_CTRL opb_mode 20 decreasing_addresses increasing_addresses 0
18 TA_ALLOC_CTRL opb_mode 20 increasing_addresses decreasing_addresses 1
19 TA_ALLOC_CTRL pt_opb 17-16 no_list 0
20 TA_ALLOC_CTRL pt_opb 17-16 _8x4byte 1
21 TA_ALLOC_CTRL pt_opb 17-16 _16x4byte 2

Binary file not shown.

192
scene.cpp
View File

@ -1,31 +1,11 @@
#include <cstdint> #include <cstdint>
#include "holly/region_array.h"
#include "holly/background.h"
#include "holly/ta_parameter.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 -0.5,0.5 | 0.5,0.5
*/ */
@ -35,108 +15,16 @@ float scene_triangle[3][3] = {
{ -0.5f, 0.5f, 1/10.f}, { -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; 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)
{ {
/* uint32_t ix = 0;
triangle(store_queue);
sq_transfer_32byte(ta_fifo_polygon_converter);
for (int i = 0; i < 3; i++) { triangle(&scene[(32 * ix) / 4]);
bool end_of_strip = i == 2; 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++) { for (int i = 0; i < 3; i++) {
bool end_of_strip = i == 2; bool end_of_strip = i == 2;
@ -150,69 +38,19 @@ void scene_geometry_transfer()
x += 320.f; x += 320.f;
y += 240.f; y += 240.f;
vertex(&scene[(32 * (i + 1)) / 4], vertex(&scene[(32 * ix) / 4],
x, // x x, // x
y, // y y, // y
scene_triangle[i][2], // z scene_triangle[i][2], // z
0xffff00ff, // base_color 0xffff00ff, // base_color
end_of_strip); end_of_strip);
ix++;
} }
end_of_list(&scene[(32 * 4) / 4]);
theta += degree;
volatile uint32_t _dummy = sh7091.DMAC.CHCR2; end_of_list(&scene[(32 * ix) / 4]);
(void)_dummy; ix++;
sh7091.DMAC.CHCR2 = 0;
sh7091.DMAC.SAR2 = reinterpret_cast<uint32_t>(&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;
while ((system.ISTNRM & (1 << 19)) == 0); theta += one_degree;
system.ISTNRM = (1 << 19);
} return ix;
void scene_init_texture_memory()
{
volatile texture_memory_alloc * mem = reinterpret_cast<volatile texture_memory_alloc *>(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;
} }

View File

@ -1,8 +1,5 @@
#pragma once #pragma once
void scene_holly_init(); #include <cstdint>
void scene_ta_init();
void scene_init_texture_memory(); uint32_t scene_transform(volatile uint32_t * scene);
void scene_geometry_transfer();
void scene_wait_opaque_list();
void scene_start_render(int fb);

View File

@ -28,3 +28,74 @@
#define SCFSR2__PER (1 << 2) /* parity error */ #define SCFSR2__PER (1 << 2) /* parity error */
#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */ #define SCFSR2__RDF (1 << 1) /* receive FIFO data full */
#define SCFSR2__DR (1 << 0) /* receive data ready */ #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)

View File

@ -4,8 +4,7 @@
void sq_transfer_32byte(volatile void * dst) void sq_transfer_32byte(volatile void * dst)
{ {
// dst typically 0x10000000 (ta polygon converter) // dst typically 0x10000000 (ta polygon converter)
//sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(dst) >> 26) & 0b111) << 2; sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(dst) >> 26) & 0b111) << 2;
sh7091.CCN.QACR0 = 0xac;
// start 32-byte transfer from store queue 0 (SQ0) to QACR0 // start 32-byte transfer from store queue 0 (SQ0) to QACR0
asm volatile ("pref @%0" asm volatile ("pref @%0"

28
systembus_bits.h Normal file
View File

@ -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)

84
ta.h
View File

@ -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)
// ----------

12
texture_memory_alloc.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
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
};