From acce2f637970ef97033bc0840989002fed389aff Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 21 Jun 2025 14:41:55 -0500 Subject: [PATCH] aica_xm: add font --- example/aica/aica.mk | 1 + example/aica/aica_xm.cpp | 146 +++++++++++++++++++++++++----- font/tandy1k/tandy1k.data | Bin 8192 -> 16384 bytes font/tandy1k/tandy1k.data.h | 15 +++ tools/texture_memory_allocator.py | 2 +- 5 files changed, 139 insertions(+), 25 deletions(-) create mode 100644 font/tandy1k/tandy1k.data.h diff --git a/example/aica/aica.mk b/example/aica/aica.mk index bcb103a..d65bb31 100644 --- a/example/aica/aica.mk +++ b/example/aica/aica.mk @@ -18,6 +18,7 @@ AICA_XM_OBJ = \ xm/xmtest.xm.o \ xm/catch_this_rebel.xm.o \ xm/middle_c.xm.o \ + font/tandy1k/tandy1k.data.o \ holly/core.o \ holly/region_array.o \ holly/background.o \ diff --git a/example/aica/aica_xm.cpp b/example/aica/aica_xm.cpp index 89b358c..3366d05 100644 --- a/example/aica/aica_xm.cpp +++ b/example/aica/aica_xm.cpp @@ -9,7 +9,7 @@ #include "holly/ta_global_parameter.hpp" #include "holly/ta_parameter.hpp" #include "holly/ta_vertex_parameter.hpp" -#include "holly/texture_memory_alloc5.hpp" +#include "holly/texture_memory_alloc7.hpp" #include "holly/video_output.hpp" #include "memorymap.hpp" @@ -34,6 +34,8 @@ #include "xm/xmtest.xm.h" #include "xm/catch_this_rebel.xm.h" +#include "font/tandy1k/tandy1k.data.h" + #include "interrupt.hpp" constexpr int max_patterns = 64; @@ -839,6 +841,55 @@ void core_param_init() holly.FB_W_LINESTRIDE = (framebuffer.px_width * bytes_per_pixel) / 8; } +void transfer_ta_fifo_texture_memory_32byte(void * dst, void * src, int length) +{ + uint32_t out_addr = (uint32_t)dst; + sh7091.CCN.QACR0 = ((reinterpret_cast(out_addr) >> 24) & 0b11100); + sh7091.CCN.QACR1 = ((reinterpret_cast(out_addr) >> 24) & 0b11100); + + volatile uint32_t * base = &store_queue[(out_addr & 0x03ffffe0) / 4]; + uint32_t * src32 = reinterpret_cast(src); + + length = (length + 31) & ~31; // round up to nearest multiple of 32 + while (length > 0) { + base[0] = src32[0]; + base[1] = src32[1]; + base[2] = src32[2]; + base[3] = src32[3]; + base[4] = src32[4]; + base[5] = src32[5]; + base[6] = src32[6]; + base[7] = src32[7]; + asm volatile ("pref @%0" + : // output + : "r" (&base[0]) // input + : "memory"); + length -= 32; + base += 8; + src32 += 8; + } +} + +void transfer_textures() +{ + system.LMMODE0 = 0; // 64-bit address space + system.LMMODE1 = 0; // 64-bit address space + + uint32_t offset = texture_memory_alloc.texture.start + 0; + void * dst = reinterpret_cast(&ta_fifo_texture_memory[offset / 4]); + void * src = reinterpret_cast(&_binary_font_tandy1k_tandy1k_data_start); + int size = reinterpret_cast(&_binary_font_tandy1k_tandy1k_data_size); + transfer_ta_fifo_texture_memory_32byte(dst, src, size); +} + +void transfer_palettes() +{ + holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::argb1555; + + holly.PALETTE_RAM[0] = 0; + holly.PALETTE_RAM[1] = 0x7fff; +} + void graphics_init() { holly.SOFTRESET = softreset::pipeline_soft_reset @@ -860,6 +911,9 @@ void graphics_init() ta_cont_count, texture_memory_alloc.region_array.start, texture_memory_alloc.object_list.start); + + transfer_textures(); + transfer_palettes(); } void global_polygon_type_0(ta_parameter_writer& writer) @@ -867,20 +921,28 @@ void global_polygon_type_0(ta_parameter_writer& writer) const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume | para_control::list_type::opaque | obj_control::col_type::packed_color - | obj_control::gouraud; + | obj_control::texture + ; const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater | isp_tsp_instruction_word::culling_mode::no_culling; const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one | tsp_instruction_word::dst_alpha_instr::zero - | tsp_instruction_word::fog_control::no_fog; + | tsp_instruction_word::fog_control::no_fog + | tsp_instruction_word::texture_u_size::from_int(128) + | tsp_instruction_word::texture_v_size::from_int(256); + + const uint32_t texture_address = texture_memory_alloc.texture.start; + const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette + | texture_control_word::scan_order::twiddled + | texture_control_word::texture_address(texture_address / 8); writer.append() = ta_global_parameter::polygon_type_0(parameter_control_word, isp_tsp_instruction_word, tsp_instruction_word, - 0, + texture_control_word, 0, // data_size_for_sort_dma 0 // next_address_for_sort_dma ); @@ -888,39 +950,75 @@ void global_polygon_type_0(ta_parameter_writer& writer) struct vertex { vec3 p; - uint32_t c; + vec2 t; }; -static inline void triangle(ta_parameter_writer& writer, - const vertex& a, const vertex& b, const vertex& c) +static inline void quad(ta_parameter_writer& writer, + const vec3& ap, const vec2& at, + const vec3& bp, const vec2& bt, + const vec3& cp, const vec2& ct, + const vec3& dp, const vec2& dt) { - writer.append() = - ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false), - a.p.x, a.p.y, a.p.z, - a.c); + writer.append() = + ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), + ap.x, ap.y, ap.z, + at.x, at.y, + 0, 0); - writer.append() = - ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false), - b.p.x, b.p.y, b.p.z, - b.c); + writer.append() = + ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), + bp.x, bp.y, bp.z, + bt.x, bt.y, + 0, 0); - writer.append() = - ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(true), - c.p.x, c.p.y, c.p.z, - c.c); + writer.append() = + ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(false), + dp.x, dp.y, dp.z, + dt.x, dt.y, + 0, 0); + + writer.append() = + ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(true), + cp.x, cp.y, cp.z, + ct.x, ct.y, + 0, 0); } -const vertex triangle_vertices[] = { - { { 320.000f, 50.f, 0.1f }, 0xffff0000 }, - { { 539.393f, 430.f, 0.1f }, 0xff00ff00 }, - { { 100.607f, 430.f, 0.1f }, 0xff0000ff }, +const vertex quad_vertices[] = { + { { 0, 0, 0.1f }, {0, 0} }, + { { 1, 0, 0.1f }, {1, 0} }, + { { 1, 1, 0.1f }, {1, 1} }, + { { 0, 1, 0.1f }, {0, 1} }, }; +vec3 transform(const vec3& p) +{ + return { + p.x * 128 + 64, + p.y * 256 + 64, + p.z + }; +} + void transfer_scene(ta_parameter_writer& writer) { global_polygon_type_0(writer); - triangle(writer, triangle_vertices[0], triangle_vertices[1], triangle_vertices[2]); + vec3 ap = transform(quad_vertices[0].p); + vec3 bp = transform(quad_vertices[1].p); + vec3 cp = transform(quad_vertices[2].p); + vec3 dp = transform(quad_vertices[3].p); + + vec2 at = quad_vertices[0].t; + vec2 bt = quad_vertices[1].t; + vec2 ct = quad_vertices[2].t; + vec2 dt = quad_vertices[3].t; + + quad(writer, + ap, at, + bp, bt, + cp, ct, + dp, dt); writer.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); diff --git a/font/tandy1k/tandy1k.data b/font/tandy1k/tandy1k.data index abc9ce8ed781ab3e42ac8afb07c619ec2c263880..3387a1bd443fade3ca493c0f07a1eff90fad2eb8 100644 GIT binary patch literal 16384 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 literal 8192 zcmeI0TXN(e3`N^Ju=l^&x##MEu#?Grq>}k)DuqEvR}Unh^Ll+lJ6}hkTxv`YwW5vh z+2iv%uHqQ-W7w>(*Lis&eu-I`l`xV(;|z&?7`B|&&iFVO$6TC&ZjlR2cRPY-=hd9j zdCG<&NJtG)wU=DGE(Ku2X;HJv?%+jiEXkb%A3tmG;_~Yhyx5+cqD%LZ$I&&jj5I)b z?9q_I52o@)pM@9Hh1Vl-A=7h(CwX^!;FIme7x>pHpMxkNK-3*uE{H=b?Fqx0qzI70 zg^>*auGO$6_8C~gZ*%Kx`@;&v)J8mImUe#G9}L-R=WBkED_DXJ?qY@EW|hdYH5P?y zbnK7O#;TYsd_@t9i_j{>W7|d0-;l3pm4$3S_J#7{qOv1`tNIx7E$0Clgss{+mr>Ov z$(dqX9&5h@I^ZJu_%Miqc3v-OsVY(aqp+=HRjnb>)B!A8*)-+(9Q#r zM5Y%VaeGoGXfFFsVowCfS=08bC|*<54)9a=~&3g^Ks9e3)!n=P*;CCZHy?$wd-#7l%9IU(~yK&{K zQA-7-{N6!bJ^hQD@;5;6E#A8=eoY7|&kycQH{R^Dcx){Bc+Ysrooo`M4O8zsmxlT7QN-g0z+RGH*dBIqx$Zj>90emj@rH$x2+hVOOO-0>?s*W{g@6-mSk+Y34N!Xxy4l@QA^zA zO9zregxQ`Lk98!feG!9X>;Em3SkXsnjisgEfs^}6hOVRKGyj!XvjI>;{DmR>{hZYS zt~`Q2Q_48G35+8r_t=>(J?70W;%vQ>>mvHc{x$|7asDZi< z$Pm}4gEjTs + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_font_tandy1k_tandy1k_data_start __asm("_binary_font_tandy1k_tandy1k_data_start"); +extern uint32_t _binary_font_tandy1k_tandy1k_data_end __asm("_binary_font_tandy1k_tandy1k_data_end"); +extern uint32_t _binary_font_tandy1k_tandy1k_data_size __asm("_binary_font_tandy1k_tandy1k_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/tools/texture_memory_allocator.py b/tools/texture_memory_allocator.py index fc570d9..7f8787b 100644 --- a/tools/texture_memory_allocator.py +++ b/tools/texture_memory_allocator.py @@ -1,7 +1,7 @@ import struct # make ./example/memory_map.bin -# ./tools/ftdi_transfer ./example/memory_map.bin +# ./tools/ftdi_transfer.sh ./example/memory_map.bin # ./tools/dump_texture_memory.sh # sha256sum