draw 1 triangle

This commit is contained in:
Zack Buhman 2023-11-30 10:02:22 +08:00
parent 060977091d
commit ff2dcc7d71
38 changed files with 1312 additions and 211 deletions

26
addresses.lds Normal file
View File

@ -0,0 +1,26 @@
sh7091_ic_a = 0xf0000000;
sh7091_ic_d = 0xf1000000;
sh7091_oc_a = 0xf4000000;
sh7091_oc_d = 0xf5000000;
sh7091 = 0xff000000;
system = 0xa05f6800;
maple_if = 0xa05f6c00;
gdrom_if = 0xa05f7000;
g1_if = 0xa05f7400;
g2_if = 0xa05f7800;
pvr_if = 0xa05f7c00;
holly = 0xa05f8000;
modem = 0xa0600000;
system_boot_rom = 0xa0000000;
aica_wave_memory = 0xa0800000;
texture_memory = 0xa5000000;
system_memory = 0xac000000;
ta_fifo_polygon_converter = 0x10000000;
ta_fifo_yuv_converter = 0x10800000;
ta_fifo_texture_memory = 0x11000000;
ta_fifo_polygon_converter_mirror = 0x12000000;
ta_fifo_yuv_converter_mirror = 0x12800000;
ta_fifo_texture_memory_mirror = 0x13000000;
store_queue = 0xe0000000;

12
alt.lds
View File

@ -58,14 +58,4 @@ SECTIONS
__p1ram_start = ORIGIN(p1ram);
__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram);
SH7091_IC_A = 0xf0000000;
SH7091_IC_D = 0xf1000000;
SH7091_OC_A = 0xf4000000;
SH7091_OC_D = 0xf5000000;
SH7091 = 0xff000000;
HOLLY = 0xa05f8000;
SYSTEM = 0xa05F6800;
MAPLE_IF = 0xa05F6C00;
G1_IF = 0xa05F7400;
G2_IF = 0xa05F7800;
PVR_IF = 0xa05F7C00;
INCLUDE "addresses.lds"

25
cache.c
View File

@ -1,25 +0,0 @@
#include "type.h"
#include "sh7091.h"
#include "sh7091_bits.h"
#include "cache.h"
extern volatile reg32 SH7091_IC_A[256][(1 << 5) / 4] __asm("SH7091_IC_A");
extern volatile reg32 SH7091_OC_A[512][(1 << 5) / 4] __asm("SH7091_OC_A");
void cache_init()
{
for (int i = 0; i < 256; i++) {
SH7091_IC_A[i][0] = 0;
}
for (int i = 0; i < 512; i++) {
SH7091_OC_A[i][0] = 0;
}
SH7091.CCN.CCR = CCR__ICI | CCR__ICE | CCR__OCI | CCR__OCE;
SH7091.CCN.MMUCR = 0;
asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;");
}

25
cache.cpp Normal file
View File

@ -0,0 +1,25 @@
#include "type.h"
#include "sh7091.h"
#include "sh7091_bits.h"
#include "cache.h"
extern volatile reg32 sh7091_ic_a[256][(1 << 5) / 4] __asm("sh7091_ic_a");
extern volatile reg32 sh7091_oc_a[512][(1 << 5) / 4] __asm("sh7091_oc_a");
void cache_init()
{
for (int i = 0; i < 256; i++) {
sh7091_ic_a[i][0] = 0;
}
for (int i = 0; i < 512; i++) {
sh7091_oc_a[i][0] = 0;
}
sh7091.CCN.CCR = CCR__ICI | CCR__ICE | CCR__OCI | CCR__OCE;
sh7091.CCN.MMUCR = 0;
asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;");
}

View File

@ -32,6 +32,7 @@ def sync(ser, b):
return bytes(l)
def do(ser, b):
ser.read(ser.in_waiting)
ser.flush()
ser.flushInput()
ser.flushOutput()
@ -55,14 +56,19 @@ def do(ser, b):
args = struct.pack("<I", dest)
ser.write(args)
print()
console(ser)
def console(ser):
while True:
b = ser.read(1)
if b:
sys.stderr.buffer.write(b)
sys.stderr.flush()
with open(sys.argv[1], 'rb') as f:
b = f.read()
with serial.Serial('/dev/ttyUSB0', 120192, timeout=1) as ser:
#console(ser)
do(ser, b)

View File

@ -7,7 +7,7 @@ AARCH = --isa=sh4 --little
AFLAGS = --fatal-warnings
CARCH = -m4-single-only -ml
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -Wno-error=narrowing
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable
DEPFLAGS = -MMD -E
# --print-gc-sections
@ -22,6 +22,13 @@ LD = $(TARGET)ld
OBJCOPY = $(TARGET)objcopy
OBJDUMP = $(TARGET)objdump
define BUILD_BINARY_O
$(OBJCOPY) \
-I binary -O elf32-shl -B sh4 \
--rename-section .data=.data.$(basename $@) \
$< $@
endef
IP_OBJ = \
systemid.o \
toc.o \
@ -37,6 +44,19 @@ IP_OBJ = \
sg/sg_ini.o \
sg/aip.o
MAIN_OBJ = \
start.o \
main.o \
load.o \
cache.o \
vga.o \
rgb.o \
holly/background.o \
holly/region_array.o \
holly/ta_parameter.o \
storequeue.o \
scene.o
all: main.cdi
%.o: %.obj
@ -59,10 +79,10 @@ all: main.cdi
%.o: %.cpp %.cpp.d
$(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) -c $< -o $@
main.elf: start.o main.o cache.o vga.o load.o rgb.o
main.elf: $(MAIN_OBJ)
$(LD) $(LDFLAGS) -T $(LIB)/main.lds $^ -o $@
test.elf: test.o rgb.o vga.o
test.elf: test.o rgb.o vga.o DSC08384.data.o
$(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@
%.bin: %.elf
@ -109,6 +129,9 @@ audio.pcm:
%.cdi: %.iso
./cdi4dc $< $@ >/dev/null
%.data.o: %.data
$(BUILD_BINARY_O)
.SUFFIXES:
.INTERMEDIATE:
.SECONDARY:

View File

@ -164,5 +164,4 @@ static_assert((offsetof (struct holly_reg, FOG_TABLE)) == 0x200);
static_assert((offsetof (struct holly_reg, TA_OL_POINTERS)) == 0x600);
static_assert((offsetof (struct holly_reg, PALETTE_RAM)) == 0x1000);
extern struct holly_reg HOLLY __asm("HOLLY");
extern struct holly_reg holly __asm("holly");

49
holly/background.cpp Normal file
View File

@ -0,0 +1,49 @@
#include <cstdint>
#include "isp_tsp.h"
struct vertex_parameter {
float x;
float y;
float z;
uint32_t base_color;
}; // ISP_BACKGND_T skip(1)
struct isp_tsp_parameter {
uint32_t isp_tsp_instruction_word;
uint32_t tsp_instruction_word;
uint32_t texture_control_word;
vertex_parameter vertex[3];
};
void background_parameter(volatile uint32_t * buf)
{
volatile isp_tsp_parameter * parameter = reinterpret_cast<volatile isp_tsp_parameter *>(buf);
parameter->isp_tsp_instruction_word
= isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling;
parameter->tsp_instruction_word
= tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog;
parameter->texture_control_word
= 0;
parameter->vertex[0].x = 0.f;
parameter->vertex[0].y = 0.f;
parameter->vertex[0].z = 1.f/100000;
parameter->vertex[0].base_color = 0xff300000;
parameter->vertex[1].x = 0.f;
parameter->vertex[1].y = 480.f;
parameter->vertex[1].z = 1.f/100000;
parameter->vertex[1].base_color = 0xff300000;
parameter->vertex[2].x = 640.f;
parameter->vertex[2].y = 0.f;
parameter->vertex[2].z = 1.f/100000;
parameter->vertex[2].base_color = 0xff300000;
}

5
holly/background.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <cstdint>
void background_parameter(volatile uint32_t * buf);

10
holly/float_uint32.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <cstdint>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
constexpr uint32_t _i(float f) {
return *(reinterpret_cast<uint32_t *>(&f));
}
#pragma GCC diagnostic pop

113
holly/isp_tsp.h Normal file
View File

@ -0,0 +1,113 @@
#include <cstdint>
namespace isp_tsp_instruction_word {
namespace depth_compare_mode {
constexpr uint32_t never = 0 << 29;
constexpr uint32_t less = 1 << 29;
constexpr uint32_t equal = 2 << 29;
constexpr uint32_t less_or_equal = 3 << 29;
constexpr uint32_t greater = 4 << 29;
constexpr uint32_t not_equal = 5 << 29;
constexpr uint32_t greater_or_equal = 6 << 29;
constexpr uint32_t always = 7 << 29;
}
namespace culling_mode {
constexpr uint32_t no_culling = 0 << 27;
constexpr uint32_t cull_if_small = 1 << 27; // compared to FPU_CULL_VAL
constexpr uint32_t cull_if_negative = 2 << 27;
constexpr uint32_t cull_if_positive = 3 << 27;
}
constexpr uint32_t z_write_disable = 1 << 26;
constexpr uint32_t texture = 1 << 25;
constexpr uint32_t offset = 1 << 24;
constexpr uint32_t gouraud_shading = 1 << 23;
constexpr uint32_t _16bit_uv = 1 << 22;
constexpr uint32_t cache_bypass = 1 << 21;
constexpr uint32_t dcalc_ctrl = 1 << 20;
}
namespace tsp_instruction_word {
namespace src_alpha_instr {
constexpr uint32_t zero = 0 << 29;
constexpr uint32_t one = 1 << 29;
constexpr uint32_t other_color = 2 << 29;
constexpr uint32_t inverse_other_color = 3 << 29;
constexpr uint32_t src_alpha = 4 << 29;
constexpr uint32_t inverse_src_alpha = 5 << 29;
constexpr uint32_t dst_alpha = 6 << 29;
constexpr uint32_t inverse_dst_alpha = 7 << 29;
}
namespace dst_alpha_instr {
constexpr uint32_t zero = 0 << 26;
constexpr uint32_t one = 1 << 26;
constexpr uint32_t other_color = 2 << 26;
constexpr uint32_t inverse_other_color = 3 << 26;
constexpr uint32_t src_alpha = 4 << 26;
constexpr uint32_t inverse_src_alpha = 5 << 26;
constexpr uint32_t dst_alpha = 6 << 26;
constexpr uint32_t inverse_dst_alpha = 7 << 26;
}
constexpr uint32_t src_select = 1 << 25;
constexpr uint32_t dst_select = 1 << 24;
namespace fog_control {
constexpr uint32_t look_up_table = 0b00 << 22;
constexpr uint32_t per_vertex = 0b01 << 22;
constexpr uint32_t no_fog = 0b10 << 22;
constexpr uint32_t look_up_table_mode_2 = 0b11 << 22;
}
constexpr uint32_t color_clamp = 1 << 21;
constexpr uint32_t use_alpha = 1 << 20;
constexpr uint32_t ignore_tex_alpha = 1 << 19;
// flip_uv
// clamp_uv
namespace filter_mode {
constexpr uint32_t point_sampled = 0b00 << 13;
constexpr uint32_t bilinear_filter = 0b01 << 13;
constexpr uint32_t trilinear_pass_a = 0b10 << 13;
constexpr uint32_t trilinear_pass_b = 0b11 << 13;
}
constexpr uint32_t super_sample_texture = 1 << 12;
constexpr uint32_t mip_map_d_adjust(uint32_t fp)
{
return (fp & 0b1111) << 8;
}
namespace texture_shading_instruction {
constexpr uint32_t decal = 0 << 6;
constexpr uint32_t modulate = 1 << 6;
constexpr uint32_t decal_alpha = 2 << 6;
constexpr uint32_t modulate_alpha = 3 << 6;
}
namespace texture_u_size {
constexpr uint32_t _8 = 0 << 3;
constexpr uint32_t _16 = 1 << 3;
constexpr uint32_t _32 = 2 << 3;
constexpr uint32_t _64 = 3 << 3;
constexpr uint32_t _128 = 4 << 3;
constexpr uint32_t _256 = 5 << 3;
constexpr uint32_t _512 = 6 << 3;
constexpr uint32_t _1024 = 7 << 3;
}
namespace texture_v_size {
constexpr uint32_t _8 = 0 << 0;
constexpr uint32_t _16 = 1 << 0;
constexpr uint32_t _32 = 2 << 0;
constexpr uint32_t _64 = 3 << 0;
constexpr uint32_t _128 = 4 << 0;
constexpr uint32_t _256 = 5 << 0;
constexpr uint32_t _512 = 6 << 0;
constexpr uint32_t _1024 = 7 << 0;
}
}

61
holly/region_array.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "region_array.h"
#define REGION_ARRAY__LAST_REGION (1 << 31)
#define REGION_ARRAY__Z_CLEAR (1 << 30)
#define REGION_ARRAY__PRE_SORT (1 << 29)
#define REGION_ARRAY__FLUSH_ACCUMULATE (1 << 28)
#define REGION_ARRAY__TILE_Y_POSITION(n) (((n) & 0x3f) << 8)
#define REGION_ARRAY__TILE_X_POSITION(n) (((n) & 0x3f) << 2)
#define REGION_ARRAY__LIST_POINTER__EMPTY (1 << 31)
#define REGION_ARRAY__LIST_POINTER(n) ((n) & 0xfffffc)
// this is for a "type 2" region array.
// region header type is specified in FPU_PARAM_CFG
struct region_array_entry {
uint32_t tile; /* 3.7.7 page 216 */
uint32_t opaque_list_pointer;
uint32_t opaque_modifier_volume_list_pointer;
uint32_t translucent_list_pointer;
uint32_t translucent_modifier_volume_list_pointer;
uint32_t punch_through_list_pointer;
};
// opaque list pointer offset: OPB size * tile index * 4
void region_array(volatile uint32_t * buf,
uint32_t ol_base,
const uint32_t width, // in tile units (1 tile unit = 32 pixels)
const uint32_t height) // in tile units (1 tile unit = 32 pixels)
{
volatile region_array_entry * region_array = reinterpret_cast<volatile region_array_entry *>(buf);
uint32_t ix = 0;
// create a "dummy region array [item]" for CORE & TA-related bug #21:
// "Misshapen tiles or missing tiles occur"
region_array[ix].tile = REGION_ARRAY__FLUSH_ACCUMULATE;
region_array[ix].opaque_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].opaque_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].translucent_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].translucent_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].punch_through_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
ix += 1;
for (uint32_t y = 0; y < height; y++) {
for (uint32_t x = 0; x < width; x++) {
region_array[ix].tile = REGION_ARRAY__TILE_Y_POSITION(y)
| REGION_ARRAY__TILE_X_POSITION(x);
uint32_t tile_index = y * width + x;
constexpr uint32_t opaque_list_opb_size = 16 * 4; // in bytes; this must match O_OPB in TA_ALLOC_CTRL
region_array[ix].opaque_list_pointer = ol_base + (opaque_list_opb_size * tile_index);
region_array[ix].opaque_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].translucent_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].translucent_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
region_array[ix].punch_through_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY;
ix += 1;
}
}
}

8
holly/region_array.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <cstdint>
void region_array(volatile uint32_t * buf,
uint32_t ol_base,
const uint32_t width, // in tile units (1 tile unit = 32 pixels)
const uint32_t height); // in tile units (1 tile unit = 32 pixels)

185
holly/ta_parameter.cpp Normal file
View File

@ -0,0 +1,185 @@
#include <cstdint>
#include <cstddef>
#include "float_uint32.h"
#include "ta_parameter.h"
#include "isp_tsp.h"
static_assert((sizeof (float)) == (sizeof (uint32_t)));
struct vertex_polygon_type_0 {
uint32_t parameter_control_word;
float x;
float y;
float z;
uint32_t _res0;
uint32_t _res1;
uint32_t base_color;
uint32_t _res2;
};
static_assert((sizeof (vertex_polygon_type_0)) == 32);
static_assert((offsetof (struct vertex_polygon_type_0, parameter_control_word)) == 0x00);
static_assert((offsetof (struct vertex_polygon_type_0, x)) == 0x04);
static_assert((offsetof (struct vertex_polygon_type_0, y)) == 0x08);
static_assert((offsetof (struct vertex_polygon_type_0, z)) == 0x0c);
static_assert((offsetof (struct vertex_polygon_type_0, _res0)) == 0x10);
static_assert((offsetof (struct vertex_polygon_type_0, _res1)) == 0x14);
static_assert((offsetof (struct vertex_polygon_type_0, base_color)) == 0x18);
static_assert((offsetof (struct vertex_polygon_type_0, _res2)) == 0x1c);
struct global_polygon_type_0 {
uint32_t parameter_control_word;
uint32_t isp_tsp_instruction_word;
uint32_t tsp_instruction_word;
uint32_t texture_control_word;
uint32_t _res0;
uint32_t _res1;
uint32_t data_size_for_sort_dma;
uint32_t next_address_for_sort_dma;
};
static_assert((sizeof (global_polygon_type_0)) == 32);
static_assert((offsetof (struct global_polygon_type_0, parameter_control_word)) == 0x00);
static_assert((offsetof (struct global_polygon_type_0, isp_tsp_instruction_word)) == 0x04);
static_assert((offsetof (struct global_polygon_type_0, tsp_instruction_word)) == 0x08);
static_assert((offsetof (struct global_polygon_type_0, texture_control_word)) == 0x0c);
static_assert((offsetof (struct global_polygon_type_0, _res0)) == 0x10);
static_assert((offsetof (struct global_polygon_type_0, _res1)) == 0x14);
static_assert((offsetof (struct global_polygon_type_0, data_size_for_sort_dma)) == 0x18);
static_assert((offsetof (struct global_polygon_type_0, next_address_for_sort_dma)) == 0x1c);
struct global_end_of_list {
uint32_t parameter_control_word;
uint32_t _res0;
uint32_t _res1;
uint32_t _res2;
uint32_t _res3;
uint32_t _res4;
uint32_t _res5;
uint32_t _res6;
};
static_assert((sizeof (global_end_of_list)) == 32);
static_assert((offsetof (struct global_end_of_list, parameter_control_word)) == 0x00);
static_assert((offsetof (struct global_end_of_list, _res0)) == 0x04);
static_assert((offsetof (struct global_end_of_list, _res1)) == 0x08);
static_assert((offsetof (struct global_end_of_list, _res2)) == 0x0c);
static_assert((offsetof (struct global_end_of_list, _res3)) == 0x10);
static_assert((offsetof (struct global_end_of_list, _res4)) == 0x14);
static_assert((offsetof (struct global_end_of_list, _res5)) == 0x18);
static_assert((offsetof (struct global_end_of_list, _res6)) == 0x1c);
namespace para_control {
namespace para_type {
constexpr uint32_t end_of_list = 0 << 29;
constexpr uint32_t user_tile_clip = 1 << 29;
constexpr uint32_t object_list_set = 2 << 29;
constexpr uint32_t polygon_or_modifier_volume = 4 << 29;
constexpr uint32_t sprite = 5 << 29;
constexpr uint32_t vertex_parameter = 7 << 29;
}
constexpr uint32_t end_of_strip = 1 << 28;
namespace list_type {
constexpr uint32_t opaque = 0 << 24;
constexpr uint32_t opaque_modifier_volume = 1 << 24;
constexpr uint32_t translucent = 2 << 24;
constexpr uint32_t translucent_modifier_volume = 3 << 24;
constexpr uint32_t punch_through = 4 << 24;
}
}
namespace group_control {
constexpr uint32_t group_en = 1 << 23;
namespace strip_len {
constexpr uint32_t _1_strip = 0 << 18;
constexpr uint32_t _2_strip = 1 << 18;
constexpr uint32_t _4_strip = 2 << 18;
constexpr uint32_t _6_strip = 3 << 18;
}
namespace user_clip {
constexpr uint32_t disabled = 0 << 16;
constexpr uint32_t inside_enable = 2 << 16;
constexpr uint32_t outside_enable = 3 << 16;
}
}
namespace obj_control {
constexpr uint32_t shadow = 1 << 7;
constexpr uint32_t volume = 1 << 6;
namespace col_type {
constexpr uint32_t packed_color = 0 << 4;
constexpr uint32_t floating_color = 1 << 4;
constexpr uint32_t intensity_mode_1 = 2 << 4;
constexpr uint32_t intensity_mode_2 = 3 << 4;
}
constexpr uint32_t texture = 1 << 3;
constexpr uint32_t offset = 1 << 2;
constexpr uint32_t gouraud = 1 << 1;
constexpr uint32_t _16bit_uv = 1 << 0;
}
void vertex(volatile uint32_t * buf,
const float x,
const float y,
const float z,
const uint32_t base_color,
bool end_of_strip
)
{
volatile vertex_polygon_type_0 * parameter = reinterpret_cast<volatile vertex_polygon_type_0 *>(buf);
parameter->parameter_control_word = para_control::para_type::vertex_parameter;
if (end_of_strip)
parameter->parameter_control_word |= para_control::end_of_strip;
parameter->x = x;
parameter->y = y;
parameter->z = z;
parameter->_res0 = 0;
parameter->_res1 = 0;
parameter->base_color = base_color;
parameter->_res2 = 0;
}
void triangle(volatile uint32_t * buf)
{
volatile global_polygon_type_0 * parameter = reinterpret_cast<volatile global_polygon_type_0 *>(buf);
parameter->parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::packed_color;
parameter->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling;
parameter->tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog;
parameter->texture_control_word = 0;
parameter->_res0 = 0;
parameter->_res1 = 0;
parameter->data_size_for_sort_dma = 0;
parameter->next_address_for_sort_dma = 0;
}
void end_of_list(volatile uint32_t * buf)
{
volatile global_end_of_list * parameter = reinterpret_cast<volatile global_end_of_list *>(buf);
parameter->parameter_control_word = para_control::para_type::end_of_list;
parameter->_res0 = 0;
parameter->_res1 = 0;
parameter->_res2 = 0;
parameter->_res3 = 0;
parameter->_res4 = 0;
parameter->_res5 = 0;
parameter->_res6 = 0;
}

15
holly/ta_parameter.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
void vertex(volatile uint32_t * buf,
const float x,
const float y,
const float z,
const uint32_t base_color,
bool end_of_strip
);
void triangle(volatile uint32_t * buf);
void end_of_list(volatile uint32_t * buf);

View File

@ -24,10 +24,10 @@ struct load_state {
static struct load_state state;
void move(void *dest, const void *src, size_t n)
void move(void *dst, const void *src, size_t n)
{
uint8_t *d = dest;
const uint8_t *s = src;
uint8_t * d = reinterpret_cast<uint8_t *>(dst);
const uint8_t * s = reinterpret_cast<const uint8_t *>(src);
if (d==s) return;
if (d<s) {
@ -47,7 +47,7 @@ void debug(const char * s)
{
char c;
while ((c = *s++)) {
SH7091.SCIF.SCFTDR2 = (uint8_t)c;
sh7091.SCIF.SCFTDR2 = (uint8_t)c;
}
}
@ -92,9 +92,9 @@ void load_recv(uint8_t c)
case CMD_DATA:
{
uint32_t * size = &state.addr1;
uint8_t * dest = (uint8_t *)state.addr2;
if (size > 0) {
SH7091.SCIF.SCFTDR2 = c;
uint8_t * dest = reinterpret_cast<uint8_t *>(state.addr2);
if (*size > 0) {
sh7091.SCIF.SCFTDR2 = c;
// write c to dest
*dest = c;
@ -109,19 +109,19 @@ void load_recv(uint8_t c)
}
return;
break;
case CMD_JUMP:
// jump
state.len = 0;
state.command = CMD_NONE;
debug("prejump\n");
HOLLY.VO_BORDER_COL = (31 << 11);
void (*fptr)(void) = (void (*)(void))state.addr1;
HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0);
fptr();
debug("postjump\n");
return;
break;
}
case CMD_JUMP:
// jump
state.len = 0;
state.command = CMD_NONE;
debug("prejump\n");
holly.VO_BORDER_COL = (31 << 11);
void (*fptr)(void) = (void (*)(void))state.addr1;
holly.VO_BORDER_COL = (63 << 5) | (31 << 0);
fptr();
debug("postjump\n");
return;
break;
}
}
}

66
main.c
View File

@ -1,66 +0,0 @@
#include <stdint.h>
#include "cache.h"
#include "load.h"
#include "sh7091.h"
#include "sh7091_bits.h"
extern uint32_t __bss_link_start __asm("__bss_link_start");
extern uint32_t __bss_link_end __asm("__bss_link_end");
void serial()
{
SH7091.SCIF.SCSCR2 = 0;
SH7091.SCIF.SCSMR2 = 0;
SH7091.SCIF.SCBRR2 = 12;
#define SCFCR2__TFRST (1 << 2)
#define SCFCR2__RFRST (1 << 1)
SH7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST;
// tx/rx trigger on 1 byte
SH7091.SCIF.SCFCR2 = 0;
SH7091.SCIF.SCSPTR2 = 0;
SH7091.SCIF.SCLSR2 = 0;
#define SCSCR2__TE (1 << 5)
#define SCSCR2__RE (1 << 4)
SH7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE;
}
void main()
{
cache_init();
// clear BSS
uint32_t * start = &__bss_link_start;
uint32_t * end = &__bss_link_end;
while (start < end) {
*start++ = 0;
}
serial();
load_init();
while (1) {
#define SCFSR2__ER (1 << 7) /* read error */
#define SCFSR2__TEND (1 << 6) /* transmit end */
#define SCFSR2__TFDE (1 << 5) /* transmit fifo data empty */
#define SCFSR2__BRK (1 << 4) /* break detect */
#define SCFSR2__FER (1 << 3) /* framing error */
#define SCFSR2__PER (1 << 2) /* parity error */
#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */
#define SCFSR2__DR (1 << 0) /* receive data ready */
while ((SH7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) {
// wait
}
while ((SH7091.SCIF.SCFDR2 & 0b11111) > 0) {
uint8_t c = SH7091.SCIF.SCFRDR2;
load_recv(c);
}
SH7091.SCIF.SCFSR2 = SH7091.SCIF.SCFSR2 & (~SCFSR2__RDF);
}
}

96
main.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <stdint.h>
#include "cache.h"
#include "load.h"
#include "vga.h"
#include "sh7091.h"
#include "sh7091_bits.h"
#include "memorymap.h"
#include "rgb.h"
#include "scene.h"
extern uint32_t __bss_link_start __asm("__bss_link_start");
extern uint32_t __bss_link_end __asm("__bss_link_end");
void serial()
{
sh7091.SCIF.SCSCR2 = 0;
sh7091.SCIF.SCSMR2 = 0;
sh7091.SCIF.SCBRR2 = 1; // 520833.3
sh7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST;
// tx/rx trigger on 1 byte
sh7091.SCIF.SCFCR2 = 0;
sh7091.SCIF.SCSPTR2 = 0;
sh7091.SCIF.SCLSR2 = 0;
sh7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE;
}
extern "C"
void main()
{
cache_init();
// clear BSS
uint32_t * start = &__bss_link_start;
uint32_t * end = &__bss_link_end;
while (start < end) {
*start++ = 0;
}
serial();
vga();
v_sync_in();
volatile uint16_t * framebuffer = reinterpret_cast<volatile uint16_t *>(&texture_memory[0]);
for (int y = 0; y < 480; y++) {
for (int x = 0; x < 640; x++) {
struct hsv hsv = {(y * 255) / 480, 255, 255};
struct rgb rgb = hsv_to_rgb(hsv);
framebuffer[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0);
}
}
while (1) {
v_sync_in();
scene_holly_init();
scene_init_texture_memory();
scene_ta_init();
scene_geometry_transfer();
scene_wait_opaque_list();
scene_start_render();
// I do not understand why, but flycast does not show the first-rendered
// framebuffer.
v_sync_in();
scene_ta_init();
scene_geometry_transfer();
scene_wait_opaque_list();
scene_start_render();
// do nothing forever
while(1);
/*
load_init();
while (1) {
while ((sh7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) {
// wait
}
while ((sh7091.SCIF.SCFDR2 & 0b11111) > 0) {
uint8_t c = sh7091.SCIF.SCFRDR2;
load_recv(c);
}
sh7091.SCIF.SCFSR2 = sh7091.SCIF.SCFSR2 & (~SCFSR2__RDF);
}
*/
}
}

View File

@ -64,11 +64,7 @@ SECTIONS
__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors);
}
SH7091_IC_A = 0xf0000000;
SH7091_IC_D = 0xf1000000;
SH7091_OC_A = 0xf4000000;
SH7091_OC_D = 0xf5000000;
SH7091 = 0xff000000;
HOLLY = 0xa05f8000;
__p1ram_start = ORIGIN(p1ram);
__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram);
INCLUDE "addresses.lds"

13
memorymap.h Normal file
View File

@ -0,0 +1,13 @@
#include <stdint.h>
extern volatile uint32_t system_boot_rom[0x200000] __asm("system_boot_rom");
extern volatile uint32_t aica_wave_memory[0x200000] __asm("aica_wave_memory");
extern volatile uint32_t texture_memory[0x800000] __asm("texture_memory");
extern volatile uint32_t system_memory[0x1000000] __asm("system_memory");
extern volatile uint32_t ta_fifo_polygon_converter[0x800000] __asm("ta_fifo_polygon_converter");
extern volatile uint32_t ta_fifo_yuv_converter[0x800000] __asm("ta_fifo_yuv_converter");
extern volatile uint32_t ta_fifo_texture_memory[0x800000] __asm("ta_fifo_texture_memory");
extern volatile uint32_t ta_fifo_polygon_converter_mirror[0x800000] __asm("ta_fifo_polygon_converter_mirror");
extern volatile uint32_t ta_fifo_yuv_converter_mirror[0x800000] __asm("ta_fifo_yuv_converter_mirror");
extern volatile uint32_t ta_fifo_texture_memory_mirror[0x800000] __asm("ta_fifo_texture_memory_mirror");
extern volatile uint32_t store_queue[0x4000000] __asm("store_queue");

176
notes.txt Normal file
View File

@ -0,0 +1,176 @@
======= KMYINIT.C ========
- ISP_FEED_CFG -- TRANSLUCENCY_CACHE_SIZE(0x200)
- FPU_SHAD_SCALE -- SCALE_FACTOR(1)
- FPU_CULL_VAL -- 1.0f
- FPU_PERP_VAL -- 0.0f
- SPAN_SORT_CFG -- SPAN_SORT_ENABLE | OFFSET_SORT_ENABLE
- FOG_COL_RAM -- RED(127) | GREEN(127) | BLUE(127)
- FOG_COL_VERT -- RED(127) | GREEN(127) | BLUE(127)
- FOG_CLAMP_MIN -- ALPHA(0) | RED(0) | GREEN(0) | BLUE(0)
- FOG_CLAMP_MAX -- ALPHA(255) | RED(255) | GREEN(255) | BLUE(255)
- HALF_OFFSET -- TSP_TEXEL_SAMPLE_POSITION_CENTER
| TSP_PIXEL_SAMPLE_POSITION_CENTER
| FPU_PIXEL_SAMPLE_POSITION_CENTER
- FPU_PARAM_CFG -- REGION_HEADER_TYPE__2
| TSP_PARAMETER_BURST_TRIGGER(31)
| ISP_PARAMETER_BURST_TRIGGER(31)
| POINTER_BURST_SIZE(7) // must be less than OPB size
| POINTER_FIRST_BURST_SIZE(7) // half of pointer burst size(?)
===========================
jargon:
OPB - Object Pointer Block (a list of pointers to objects in the object list)
OL - Object list
ISP - Image Synthesis Processor
TSP - Texture Shading Processor
====== KMYSETUPTA.C ======
The OPB initial area size that is needed for one TA input list is the
product of the total OPB size for all lists specified by the
TA_ALLOC_CTRL register before the input of that list, multiplied by
the number of Tiles in the Global Tile Clip area that is specified by
the TA_GLOB_TILE_CLIP register. The amount of memory that should be
reserved in texture memory as the OPB initial area is the sum of the
OPB initial area size for the one list added together for each of the
polygon lists that are input to the TA.
(OPB initial area size for one list) = {(Opaque list OPB size)} * (Number of Tiles in Global Tile Clip area) x 4 bytes
+ 4byte
- TA_GLOB_TILE_CLIP -- TILE_Y_NUM(480 / 32)
| TILE_X_NUM(640 / 32)
(removes polygons that are entirely outside the clip area)
- 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
- TA_ISP_BASE --
(Base address for ISP/TSP parameters (relative address from the start of texture memory) (read by PARAM_BASE))
- TA_OL_LIMIT - The last address of the object list (relative address from the start of texture memory)
- TA_PARAM_LIMIT aka TA_ISP_LIMIT - The last address of the ISP/TSP parameter list (relative address from the start of texture memory)
- TA_NEXT_OPB_INIT - the address for storing additional OPBs during list initialization (relative address from the start of texture memory)
The value in the TA_NEXT_OPB_INIT register, which should be set prior
to list initialization, is the sum starting address value of the
Object List that is stored in texture memory and the OPB initial area
size.
(TA_NEXT_OPB_INIT register value) = (TA_OL_BASE register value at list initialization) + (OPB initial area size at list initialization)
-- &object_list[0] + (sizeof (mem->object_list))
(end of object_list)
- SOFTRESET = SOFTRESET__TA_SOFT_RESET
- SOFTRESET = 0
- TA_GLOB_TILE_CLIP = TILE_Y_NUM(15)
| TILE_X_NUM(20) // 640x480
- TA_ISP_BASE = 0x00000000
- TA_ISP_LIMIT = 0x00100000
- TA_OL_BASE = 0x00100000
- TA_OL_LIMIT = 0x00200000
- TA_NEXT_OPB_INIT = 0x00100000
- TA_LIST_INIT
- dummy read on TA_LIST_INIT
==== BGPLANE ====
KMYSETPASSDEPTH.C
KMYINITIALIZEBGPLANE.C
[ 0] = DEPTH_COMPARE_MODE(GREATER)
[ 1] = SRC_ALPHA(One)
| FOG_CONTROL(NO_FOG)
[ 2] = 0
[ 3] = 0.0 // x
[ 4] = 0.0 // y
[ 5] = 1.f/100000 // 1/z
[ 6] = 0x0FF000000 // color
[ 7] = 0.0 // x
[ 8] = 0.0 // y
[ 9] = 1.f/100000 // 1/z
[10] = 0x0FF000000 // color
[11] = 0.0 // x
[12] = 0.0 // y
[13] = 1.f/100000 // 1/z
[14] = 0x0FF000000 // color
==== KMYSTARTRENDER.C ====
region array diagram on page 179
REGION_BASE the region array is not generated by the TA
PARAM_BASE -- equal to TA_ISP_BASE
FB_W_CTRL -- FB_PACKMODE__565_RGB
ISP_BACKGND_T // address of ISP/TSP parameters, without using TA
-- TAG_ADDRESS(0x00200000/4)
-- TAG_OFFSET(0)
-- SKIP(1)
ISP_BACKGND_D -- Z coordinate ; 0x03727c5ac (1.f/100000)
FB_W_LINESTRIDE -- 640 / 8;
FB_W_SOF1 -- framebuffer address
STARTRENDER
==== store queue ====
store queue write: 0xe000_0000 - 0xe3ff_fffc
write vertex list to: 0x10000000
TA:
"List of Input Parameters"
page 201 (TA) Parameter Format
control:
- End of List 0x0000_0000
- User Tile Clip 0x2000_0000
- Object List Set 0x4000_0000
page 196 Parameter Control Word
page 222 ISP/TSP Instruction Word
page 226 TSP Instruction Word
page 233 Texture Control Word
Volume 0
Col_Type
0 Packed (32-bit ARGB)
1 Floating (32-bit float * 4)
Textured 0
Offset 0
Gouraud 0
16bit_UV 0
Global: Polygon Type 0
Vertex: Polygon Type 0
- x y are 32-bit floating point in screen space
- z specified as reciprocal 1/z

View File

@ -1,5 +1,12 @@
import io
def should_autonewline(line):
return (
"static_assert" not in line
and "extern" not in line
and line.split()[1] != '=' # hacky; meh
)
def _render(out, lines):
indent = " "
level = 0
@ -14,7 +21,7 @@ def _render(out, lines):
level += 2
if level == 0 and l and l[-1] == ";":
if "static_assert" not in l:
if should_autonewline(l):
out.write("\n")
return out

View File

@ -6,7 +6,7 @@ from sh7091 import headers
from generate import renderer
def block():
yield 'extern struct holly_reg HOLLY __asm("HOLLY");'
yield 'extern struct holly_reg holly __asm("holly");'
input_file = sys.argv[1]
rows = read_input(input_file)

42
regs/gen/memorymap.py Normal file
View File

@ -0,0 +1,42 @@
import sys
from sh7091 import read_input
from generate import renderer
def includes():
yield "#include <stdint.h>"
yield ""
def process_rows(rows):
for row in rows:
name = row["name"].strip()
if not name:
continue
start = int(row["start"].strip(), 16)
size = row["size"].strip()
assert size.endswith("MB"), size
size = int(size.rstrip("MB"))
yield name, start, size * 1024 * 1024
def header(processed):
for name, _, size in processed:
yield f"extern volatile uint32_t {name}[0x{size:x}] __asm(\"{name}\");"
def lds(processed):
for name, address, size in processed:
if address < 0x1000_0000:
address = address | 0xa000_0000
yield f"{name} = 0x{address:08x};"
input_file = sys.argv[1]
rows = read_input(input_file)
processed = list(process_rows(rows))
render, out = renderer()
render(includes())
render(header(processed))
sys.stdout.write(out.getvalue())
render, out = renderer()
render(lds(processed))
sys.stderr.write(out.getvalue())

View File

@ -142,7 +142,7 @@ def blocks(rows):
yield f"static_assert((offsetof (struct sh7091_reg, {block})) == {hex(offset << 16)});"
yield ""
yield 'extern struct sh7091_reg SH7091 __asm("SH7091");'
yield 'extern struct sh7091_reg sh7091 __asm("sh7091");'
def headers():
yield "#include <stdint.h>"

43
regs/memorymap.csv Normal file
View File

@ -0,0 +1,43 @@
"area","start","end","function","size","access","name"
"0","0x00000000","0x001FFFFF","System/Boot ROM","2MB",,"system_boot_rom"
"0","0x00200000","0x0021FFFF","Flash Memory","128KB",,
"0","0x00400000","0x005F67FF","Unassigned","-",,
"0","0x005F6800","0x005F69FF","System Control Registers","512B",,
"0","0x005F6C00","0x005F6CFF","Maple interface Control Registers","256B",,
"0","0x005F7000","0x005F70FF","GD-ROM","256B",,
"0","0x005F7400","0x005F74FF","G1 interface Control Registers","256B",,
"0","0x005F7800","0x005F78FF","G2 interface Control Registers","256B",,
"0","0x005F7C00","0x005F7CFF","PVR interface Control Registers","256B",,
"0","0x005F8000","0x005F9FFF","TA / PVR Core Registers","8KB",,
"0","0x00600000","0x006007FF","MODEM","2KB",,
"0","0x00600800","0x006FFFFF","G2","-",,
"0","0x00700000","0x00707FFF","AICA- Sound Control Registers","32KB",,
"0","0x00710000","0x0071000B","AICA- RTC Control Registers","12B",,
"0","0x00800000","0x00FFFFFF","AICA- Wave Memory","2MB",,"aica_wave_memory"
"0","0x01000000","0x01FFFFFF","External Device","16MB",,
"0","0x02000000","0x03FFFFFF","Mirror of 0x00000000 - 0x1FFFFFFF","32MB",,
,,,,,,
"1","0x04000000","0x04FFFFFF","Texture memory 64bit access","8MB",,
"1","0x05000000","0x05FFFFFF","Texture memory 32bit access","8MB",,"texture_memory"
"1","0x06000000","0x06FFFFFF","Mirror of 0x04000000 - 0x06FFFFFF","32MB",,
,,,,,,
"2","0x08000000","0x0bffffff","Unassigned","-",,
,,,,,,
"3","0x0c000000","0x0cffffff","System memory","16MB",,"system_memory"
"3","0x0d000000","0x0dffffff","Mirror of 0x0c000000 - 0x0cffffff","16MB",,
"3","0x0e000000","0x0fffffff","Mirror of 0x0c000000 - 0x0dffffff","32MB",,
,,,,,,
"4","0x10000000","0x107FFFFF","TA FIFO Polygon Converter","8MB",,"ta_fifo_polygon_converter"
"4","0x10800000","0x10FFFFFF","TA FIFO YUV Converter","8MB",,"ta_fifo_yuv_converter"
"4","0x11000000","0x11FFFFFF","TA FIFO Texture memory","8MB",,"ta_fifo_texture_memory"
"4","0x12000000","0x127FFFFF","Mirror of TA FIFO Polygon Converter","8MB",,"ta_fifo_polygon_converter_mirror"
"4","0x12800000","0x137FFFFF","Mirror of TA FIFO YUV Converter","8MB",,"ta_fifo_yuv_converter_mirror"
"4","0x13000000","0x13FFFFFF","Mirror of TA FIFO Texture memory","8MB",,"ta_fifo_texture_memory_mirror"
,,,,,,
"5","0x14000000","0x17FFFFFF","External device","64MB",,
,,,,,,
"6","0x18000000","0x1BFFFFFF","Unassigned","-",,
,,,,,,
"7","0x1C000000","0x1FFFFFFF","SH4 Internal area","-",,
,,,,,,
,"0xE0000000","0xE3FFFFFF","Store Queue","64MB",,"store_queue"
1 area start end function size access name
2 0 0x00000000 0x001FFFFF System/Boot ROM 2MB system_boot_rom
3 0 0x00200000 0x0021FFFF Flash Memory 128KB
4 0 0x00400000 0x005F67FF Unassigned -
5 0 0x005F6800 0x005F69FF System Control Registers 512B
6 0 0x005F6C00 0x005F6CFF Maple interface Control Registers 256B
7 0 0x005F7000 0x005F70FF GD-ROM 256B
8 0 0x005F7400 0x005F74FF G1 interface Control Registers 256B
9 0 0x005F7800 0x005F78FF G2 interface Control Registers 256B
10 0 0x005F7C00 0x005F7CFF PVR interface Control Registers 256B
11 0 0x005F8000 0x005F9FFF TA / PVR Core Registers 8KB
12 0 0x00600000 0x006007FF MODEM 2KB
13 0 0x00600800 0x006FFFFF G2 -
14 0 0x00700000 0x00707FFF AICA- Sound Control Registers 32KB
15 0 0x00710000 0x0071000B AICA- RTC Control Registers 12B
16 0 0x00800000 0x00FFFFFF AICA- Wave Memory 2MB aica_wave_memory
17 0 0x01000000 0x01FFFFFF External Device 16MB
18 0 0x02000000 0x03FFFFFF Mirror of 0x00000000 - 0x1FFFFFFF 32MB
19
20 1 0x04000000 0x04FFFFFF Texture memory 64bit access 8MB
21 1 0x05000000 0x05FFFFFF Texture memory 32bit access 8MB texture_memory
22 1 0x06000000 0x06FFFFFF Mirror of 0x04000000 - 0x06FFFFFF 32MB
23
24 2 0x08000000 0x0bffffff Unassigned -
25
26 3 0x0c000000 0x0cffffff System memory 16MB system_memory
27 3 0x0d000000 0x0dffffff Mirror of 0x0c000000 - 0x0cffffff 16MB
28 3 0x0e000000 0x0fffffff Mirror of 0x0c000000 - 0x0dffffff 32MB
29
30 4 0x10000000 0x107FFFFF TA FIFO Polygon Converter 8MB ta_fifo_polygon_converter
31 4 0x10800000 0x10FFFFFF TA FIFO YUV Converter 8MB ta_fifo_yuv_converter
32 4 0x11000000 0x11FFFFFF TA FIFO Texture memory 8MB ta_fifo_texture_memory
33 4 0x12000000 0x127FFFFF Mirror of TA FIFO Polygon Converter 8MB ta_fifo_polygon_converter_mirror
34 4 0x12800000 0x137FFFFF Mirror of TA FIFO YUV Converter 8MB ta_fifo_yuv_converter_mirror
35 4 0x13000000 0x13FFFFFF Mirror of TA FIFO Texture memory 8MB ta_fifo_texture_memory_mirror
36
37 5 0x14000000 0x17FFFFFF External device 64MB
38
39 6 0x18000000 0x1BFFFFFF Unassigned -
40
41 7 0x1C000000 0x1FFFFFFF SH4 Internal area -
42
43 0xE0000000 0xE3FFFFFF Store Queue 64MB store_queue

Binary file not shown.

View File

153
scene.cpp Normal file
View File

@ -0,0 +1,153 @@
#include <cstdint>
#include "holly/region_array.h"
#include "holly/background.h"
#include "holly/ta_parameter.h"
#include "holly.h"
#include "ta.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[0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1
};
float scene_triangle[3][3] = {
{ 320.f, 120.f, 1/10.f},
{ 440.f, 360.f, 1/10.f},
{ 200.f, 360.f, 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, region_array)); // the end of the 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;
}
void scene_geometry_transfer()
{
triangle(store_queue);
sq_transfer_32byte(ta_fifo_polygon_converter);
for (int i = 0; i < 3; i++) {
bool end_of_strip = i == 2;
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);
}
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()
{
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 = FB_W_CTRL__FB_PACKMODE__565_RGB;
holly.FB_W_LINESTRIDE = 640 / 8;
holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer));
holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer));
holly.STARTRENDER = 1;
}

8
scene.h Normal file
View File

@ -0,0 +1,8 @@
#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();

View File

@ -374,5 +374,4 @@ static_assert((offsetof (struct sh7091_reg, SCI)) == 0xe00000);
static_assert((offsetof (struct sh7091_reg, SCIF)) == 0xe80000);
static_assert((offsetof (struct sh7091_reg, UDI)) == 0xf00000);
extern struct sh7091_reg SH7091 __asm("SH7091");
extern struct sh7091_reg sh7091 __asm("sh7091");

View File

@ -13,3 +13,18 @@
#define PDTRA__RESERVED (0b01 << 8)
#define PDTRA__RGB (0b10 << 8)
#define PDTRA__AV (0b11 << 8)
#define SCFCR2__TFRST (1 << 2)
#define SCFCR2__RFRST (1 << 1)
#define SCSCR2__TE (1 << 5)
#define SCSCR2__RE (1 << 4)
#define SCFSR2__ER (1 << 7) /* read error */
#define SCFSR2__TEND (1 << 6) /* transmit end */
#define SCFSR2__TFDE (1 << 5) /* transmit fifo data empty */
#define SCFSR2__BRK (1 << 4) /* break detect */
#define SCFSR2__FER (1 << 3) /* framing error */
#define SCFSR2__PER (1 << 2) /* parity error */
#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */
#define SCFSR2__DR (1 << 0) /* receive data ready */

34
storequeue.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "sh7091.h"
#include "memorymap.h"
void sq_transfer_32byte(volatile void * dst)
{
// dst typically 0x10000000 (ta polygon converter)
sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(dst) >> 26) & 0b111) << 2;
// start 32-byte transfer from store queue 0 (SQ0) to QACR0
asm volatile ("pref @%0"
: // output
: "r" (&store_queue[0]) // input
);
}
void sq_transfer_64byte(volatile void * dst)
{
// dst typically 0x10000000 (ta polygon converter)
sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(dst) >> 26) & 0b111) << 2;
sh7091.CCN.QACR1 = ((reinterpret_cast<uint32_t>(dst) >> 26) & 0b111) << 2;
// start 32-byte transfer from store queue 0 (SQ0) to QACR0
asm volatile ("pref @%0"
: // output
: "r" (&store_queue[0]) // input
);
// start 32-byte transfer from store queue 1 (SQ1) to QACR1
asm volatile ("pref @%0"
: // output
: "r" (&store_queue[8]) // input
);
}

4
storequeue.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void sq_transfer_32byte(volatile void * dst);
void sq_transfer_64byte(volatile void * dst);

View File

@ -301,13 +301,12 @@ static_assert((offsetof (struct pvr_if_reg, PDSTAPD)) == 0xf0);
static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4);
static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8);
extern struct system_reg SYSTEM __asm("SYSTEM");
extern struct system_reg system __asm("system");
extern struct maple_if_reg MAPLE_IF __asm("MAPLE_IF");
extern struct maple_if_reg maple_if __asm("maple_if");
extern struct g1_if_reg G1_IF __asm("G1_IF");
extern struct g1_if_reg g1_if __asm("g1_if");
extern struct g2_if_reg G2_IF __asm("G2_IF");
extern struct pvr_if_reg PVR_IF __asm("PVR_IF");
extern struct g2_if_reg g2_if __asm("g2_if");
extern struct pvr_if_reg pvr_if __asm("pvr_if");

88
ta.h Normal file
View File

@ -0,0 +1,88 @@
#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 FPU_CULL_VAL__COMPARISON_VALUE(n) (_u32(__builtin_fabsf(n)))
#define FPU_PERP_VAL__COMPARISON_VALUE(n) (_u32(__builtin_fabsf(n)))
#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)
// ----------

59
test.c
View File

@ -13,6 +13,8 @@ void *memcpy(void *restrict dest, const void *restrict src, size_t n)
return dest;
}
extern uint32_t _binary_DSC08384_data_start __asm("_binary_DSC08384_data_start");
void start(void)
{
/*
@ -25,35 +27,35 @@ void start(void)
G2_IF.G2APRO = 0x4659404f;
*/
HOLLY.SOFTRESET = 0b111;
HOLLY.TEXT_CONTROL = 3;
holly.SOFTRESET = 0b111;
holly.TEXT_CONTROL = 3;
uint16_t xsize = 640;
uint16_t ysize = 480;
uint16_t fb_xclip_min = 0;
uint16_t fb_xclip_max = xsize-1;
HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0);
holly.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0);
uint16_t fb_yclip_min = 0;
uint16_t fb_yclip_max = ysize-1;
HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0);
holly.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0);
uint32_t fb_xsize = (xsize * 16)/(32) - 1;
uint32_t fb_ysize = ysize - 3;
uint32_t fb_mod = 1;
HOLLY.FB_R_SIZE = 0
holly.FB_R_SIZE = 0
| (fb_xsize << 0)
| (fb_ysize << 10)
| (fb_mod << 20);
uint32_t fb_linestride = (xsize * 16) / 64;
HOLLY.FB_W_LINESTRIDE = fb_linestride;
holly.FB_W_LINESTRIDE = fb_linestride;
HOLLY.FB_W_CTRL = 0
holly.FB_W_CTRL = 0
| 0b001 << 0 // fb_packmode: RGB 565
;
HOLLY.FB_R_CTRL = 0
holly.FB_R_CTRL = 0
| 1 << 23 // vclk_div
| 0 << 22 // fb_strip_buf_en
| 0 << 16 // fb_strip_size
@ -64,43 +66,43 @@ void start(void)
| 1 << 0 // fb_enable
;
HOLLY.FB_W_SOF1 = 0;
HOLLY.FB_W_SOF2 = 0;
HOLLY.FB_R_SOF1 = 0;
HOLLY.FB_R_SOF2 = 0;
holly.FB_W_SOF1 = 0;
holly.FB_W_SOF2 = 0;
holly.FB_R_SOF1 = 0;
holly.FB_R_SOF2 = 0;
HOLLY.VO_BORDER_COL = (31 << 11) | (31 << 0);
holly.VO_BORDER_COL = (31 << 11) | (31 << 0);
uint16_t startx = 0x0a8;
uint16_t starty = 0x028;
HOLLY.VO_STARTX = startx;
HOLLY.VO_STARTY = (starty << 16) | (starty << 0);
holly.VO_STARTX = startx;
holly.VO_STARTY = (starty << 16) | (starty << 0);
HOLLY.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default
holly.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default
uint16_t hbstart = 0x0345; // default
uint16_t hbend = 0x007e; // default
HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0);
holly.SPG_HBLANK = (hbend << 16) | (hbstart << 0);
uint16_t hcount = 0x0359; // default
uint16_t vcount = 0x020c; // non-default
HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0);
holly.SPG_LOAD = (vcount << 16) | (hcount << 0);
uint16_t vbstart = 0x0208; // non-default
uint16_t vbend = 0x0028; // non-default
HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0);
holly.SPG_VBLANK = (vbend << 16) | (vbstart << 0);
uint16_t hswidth = 0x003f;
uint16_t vswidth = 0x0003;
uint16_t bpwidth = 0x0319;
uint16_t eqwidth = 0x000f;
HOLLY.SPG_WIDTH =
holly.SPG_WIDTH =
(hswidth << 0)
| (vswidth << 8)
| (bpwidth << 12)
| (eqwidth << 22);
HOLLY.SPG_HBLANK_INT = hbstart << 16;
holly.SPG_HBLANK_INT = hbstart << 16;
uint32_t hsync_pol = 0;
uint32_t vsync_pol = 0;
@ -109,7 +111,7 @@ void start(void)
uint32_t field_mode = 0;
uint32_t pixel_double = 0;
uint32_t pclk_delay = 0x16;
HOLLY.VO_CONTROL = 0
holly.VO_CONTROL = 0
| (( pclk_delay & 0x3f) << 16 )
| (( pixel_double & 0x01) << 8 )
| (( field_mode & 0x0f) << 4 )
@ -119,7 +121,9 @@ void start(void)
| (( hsync_pol & 0x01) << 0 );
HOLLY.SOFTRESET = 0b000;
holly.SOFTRESET = 0b000;
const uint8_t * buf = (const uint8_t *)&_binary_DSC08384_data_start;
reg16 * vram = (reg16 *)0xa5000000;
v_sync_in();
@ -130,15 +134,22 @@ void start(void)
struct rgb rgb = hsv_to_rgb(hsv);
vram[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0);
*/
vram[y * 640 + x] = 30 << 5 | 31 << 11;
//vram[y * 640 + x] = 30 << 5 | 31 << 11;
uint32_t ix = y * 640 + x;
uint8_t r = buf[ix * 3 + 0];
uint8_t g = buf[ix * 3 + 1];
uint8_t b = buf[ix * 3 + 2];
vram[ix] = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
}
}
/*
vram[0] = 0xffff;
vram[10] = 0xffff;
vram[639] = 0xffff;
vram[307199 - (640 * 3) - 1] = 0xffff;
vram[307199 - (640 * 2) - 10] = 31 << 11;
vram[307199 - (640 * 1) - 1] = 0xffff;
*/
//vram[307199 - (640 * 2) - 10] = 0xf0ff;
//vram[307199 - 640 - 10] = 0xf0ff;
//vram[307199 - 10] = 0xf0ff;

View File

@ -10,45 +10,45 @@
uint32_t get_cable_type()
{
/* set all pins to input */
SH7091.BSC.PCTRA = 0;
sh7091.BSC.PCTRA = 0;
/* get cable type from pins 9 + 8 */
return SH7091.BSC.PDTRA & PDTRA__MASK;
return sh7091.BSC.PDTRA & PDTRA__MASK;
}
void vga1()
{
uint32_t fb_r_ctrl = HOLLY.FB_R_CTRL;
HOLLY.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0
uint32_t fb_r_ctrl = holly.FB_R_CTRL;
holly.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0
uint32_t blank_video = 1;
HOLLY.VO_CONTROL |= (blank_video << 3); // blank_video
holly.VO_CONTROL |= (blank_video << 3); // blank_video
HOLLY.FB_R_SIZE = 0;
holly.FB_R_SIZE = 0;
uint32_t vblank_in = 0x0208;
uint32_t vblank_out = 0x0015;
HOLLY.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0);
holly.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0);
uint32_t sync_direction = 1;
HOLLY.SPG_CONTROL = (sync_direction << 8);
holly.SPG_CONTROL = (sync_direction << 8);
uint32_t hbstart = 0x0345; // default
uint32_t hbend = 0x007e; // default
HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0);
holly.SPG_HBLANK = (hbend << 16) | (hbstart << 0);
uint32_t hcount = 0x0359; // default
uint32_t vcount = 0x020c; // non-default
HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0);
holly.SPG_LOAD = (vcount << 16) | (hcount << 0);
uint32_t vbstart = 0x0208; // non-default
uint32_t vbend = 0x0028; // non-default
HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0);
holly.SPG_VBLANK = (vbend << 16) | (vbstart << 0);
uint32_t hswidth = 0x003f;
uint32_t vswidth = 0x0003;
uint32_t bpwidth = 0x0319;
uint32_t eqwidth = 0x000f;
HOLLY.SPG_WIDTH =
holly.SPG_WIDTH =
(hswidth << 0)
| (vswidth << 8)
| (bpwidth << 12)
@ -56,54 +56,47 @@ void vga1()
uint32_t startx = 0x0a8;
uint32_t starty = 0x028;
HOLLY.VO_STARTX = startx;
HOLLY.VO_STARTY = (starty << 16) | (starty << 0);
holly.VO_STARTX = startx;
holly.VO_STARTY = (starty << 16) | (starty << 0);
HOLLY.SPG_HBLANK_INT = hbstart << 16;
holly.SPG_HBLANK_INT = hbstart << 16;
}
void vga2()
{
HOLLY.FB_BURSTCTRL = 0x00093f39;
holly.FB_BURSTCTRL = 0x00093f39;
uint32_t xsize = 640;
uint32_t ysize = 480;
uint32_t fb_xclip_min = 0;
uint32_t fb_xclip_max = xsize-1;
HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0);
holly.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0);
uint32_t fb_yclip_min = 0;
uint32_t fb_yclip_max = ysize-1;
HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0);
holly.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0);
uint32_t fb_xsize = (xsize * 16)/(32) - 1;
uint32_t fb_ysize = ysize - 3;
uint32_t fb_mod = 1;
HOLLY.FB_R_SIZE = 0
holly.FB_R_SIZE = 0
| (fb_xsize << 0)
| (fb_ysize << 10)
| (fb_mod << 20);
uint32_t coeff0 = 0x40;
uint32_t coeff1 = 0x80;
HOLLY.Y_COEFF = (coeff1 << 8) | (coeff0 << 0);
holly.Y_COEFF = (coeff1 << 8) | (coeff0 << 0);
uint32_t vscale_factor = 0x0400;
HOLLY.SCALER_CTL = (vscale_factor << 0);
holly.SCALER_CTL = (vscale_factor << 0);
uint32_t fb_linestride = (xsize * 16) / 64;
HOLLY.FB_W_LINESTRIDE = fb_linestride;
holly.FB_W_SOF1 = 0;
holly.FB_W_SOF2 = 0;
holly.FB_R_SOF1 = 0;
holly.FB_R_SOF2 = 0;
HOLLY.FB_W_CTRL = 0
| 0b001 << 0 // fb_packmode: RGB 565
;
HOLLY.FB_W_SOF1 = 0;
HOLLY.FB_W_SOF2 = 0;
HOLLY.FB_R_SOF1 = 0;
HOLLY.FB_R_SOF2 = 0;
HOLLY.FB_R_CTRL = 0
holly.FB_R_CTRL = 0
| 1 << 23 // vclk_div
| 0 << 22 // fb_strip_buf_en
| 0 << 16 // fb_strip_size
@ -121,7 +114,7 @@ void vga2()
uint32_t field_mode = 0;
uint32_t pixel_double = 0;
uint32_t pclk_delay = 0x16;
HOLLY.VO_CONTROL = 0
holly.VO_CONTROL = 0
| (( pclk_delay & 0x3f) << 16 )
| (( pixel_double & 0x01) << 8 )
| (( field_mode & 0x0f) << 4 )
@ -136,10 +129,10 @@ void vga2()
void v_sync_in()
{
#define V_SYNC (1<<13)
while (!(V_SYNC & HOLLY.SPG_STATUS)) {
while (!(V_SYNC & holly.SPG_STATUS)) {
asm volatile ("nop");
}
while ((V_SYNC & HOLLY.SPG_STATUS)) {
while ((V_SYNC & holly.SPG_STATUS)) {
asm volatile ("nop");
}
#undef V_SYNC
@ -148,10 +141,10 @@ void v_sync_in()
void v_sync_out()
{
#define V_SYNC (1<<13)
while ((V_SYNC & HOLLY.SPG_STATUS)) {
while ((V_SYNC & holly.SPG_STATUS)) {
asm volatile ("nop");
}
while (!(V_SYNC & HOLLY.SPG_STATUS)) {
while (!(V_SYNC & holly.SPG_STATUS)) {
asm volatile ("nop");
}
#undef V_SYNC
@ -161,9 +154,9 @@ void vga()
{
get_cable_type();
HOLLY.SOFTRESET = 0b111;
HOLLY.TEXT_CONTROL = 3;
HOLLY.FB_W_CTRL = 9;
holly.SOFTRESET = 0b111;
holly.TEXT_CONTROL = 3;
holly.FB_W_CTRL = 9;
/*
*/
@ -172,10 +165,10 @@ void vga()
v_sync_in();
HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0);
HOLLY.VO_CONTROL = 0x0016;
holly.VO_BORDER_COL = (63 << 5) | (31 << 0);
holly.VO_CONTROL = 0x0016;
HOLLY.SOFTRESET = 0b000;
holly.SOFTRESET = 0b000;
}
void fill_framebuffer()