This commit is contained in:
Zack Buhman 2025-06-22 09:05:54 -05:00
parent 7bbd5f3775
commit c46ffcb0fb
7 changed files with 195 additions and 6 deletions

View File

@ -18,6 +18,7 @@ AICA_XM_OBJ = \
xm/xmtest.xm.o \
xm/catch_this_rebel.xm.o \
xm/middle_c.xm.o \
xm/reign.xm.o \
font/tandy1k/tandy1k.data.o \
holly/core.o \
holly/region_array.o \

View File

@ -42,6 +42,7 @@
#include "xm/test.xm.h"
#include "xm/xmtest.xm.h"
#include "xm/catch_this_rebel.xm.h"
#include "xm/reign.xm.h"
#include "font/tandy1k/tandy1k.data.h"
@ -57,7 +58,18 @@ struct xm_state {
int sample_data_offset[max_instruments];
};
xm_state xm = {0};
xm_state xm = {};
struct channel_state {
float rate;
int bytes_per_sample;
int last_tick;
int address_start;
int address_end;
int address_current;
};
channel_state channel_state[64] = {};
struct interpreter_state {
int tick_rate;
@ -73,7 +85,7 @@ struct interpreter_state {
int song_length;
};
struct interpreter_state state;
interpreter_state state = {};
union aica_sandbox_channel {
struct {
@ -167,7 +179,7 @@ int s32(void * buf)
return v;
}
uint8_t __attribute__((aligned(32))) sample_data[1024 * 1024];
uint8_t __attribute__((aligned(32))) sample_data[1024 * 1024 * 2];
int sample_data_ix;
int unpack_sample(int buf, int offset, xm_sample_header_t * sample_header)
@ -377,6 +389,106 @@ const static int cent_to_fns[] = {
};
const int cent_to_fns_length = (sizeof (cent_to_fns)) / (sizeof (cent_to_fns[0]));
const static float note_to_period[] = {
3942038.8292065524, // 0.011187104417456076
3720789.190481886, // 0.011852324263038545
3511957.339799563, // 0.012557100139068576
3314846.320270742, // 0.013303784169517129
3128798.292190988, // 0.01409486834292482
2953192.337561424, // 0.014932992829182009
2787442.3878326337, // 0.015820954790850335
2630995.267955346, // 0.01676171771843281
2483328.850210139, // 0.01775842132074786
2343950.311654716, // 0.018814392003415604
2212394.489373137, // 0.019933153970427473
2088222.3280378345, // 0.021118440985849373
1971019.4146032773, // 0.02237420883491214
1860394.595240943, // 0.02370464852607709
1755978.6698997815, // 0.025114200278137152
1657423.160135371, // 0.026607568339034257
1564399.146095494, // 0.02818973668584964
1476596.168780712, // 0.029865985658364017
1393721.1939163168, // 0.03164190958170067
1315497.633977673, // 0.03352343543686562
1241664.4251050695, // 0.03551684264149572
1171975.155827358, // 0.03762878400683121
1106197.2446865684, // 0.039866307940854946
1044111.1640189172, // 0.042236881971698746
985509.7073016387, // 0.04474841766982428
930197.2976204715, // 0.04740929705215418
877989.3349498907, // 0.050228400556274304
828711.5800676855, // 0.053215136678068514
782199.573047747, // 0.05637947337169928
738298.084390356, // 0.059731971316728034
696860.5969581584, // 0.06328381916340134
657748.8169888363, // 0.06704687087373126
620832.2125525348, // 0.07103368528299144
585987.577913679, // 0.07525756801366242
553098.622343284, // 0.07973261588170992
522055.5820094586, // 0.08447376394339749
492754.85365081934, // 0.08949683533964856
465098.64881023555, // 0.09481859410430839
438994.66747494537, // 0.10045680111254861
414355.7900338427, // 0.10643027335613703
391099.78652387334, // 0.1127589467433986
369149.042195178, // 0.11946394263345607
348430.2984790792, // 0.12656763832680268
328874.40849441814, // 0.13409374174746252
310416.1062762674, // 0.14206737056598287
292993.7889568395, // 0.15051513602732483
276549.311171642, // 0.15946523176341984
261027.7910047293, // 0.16894752788679498
246377.42682540967, // 0.1789936706792971
232549.32440511778, // 0.18963718820861677
219497.33373747268, // 0.20091360222509722
207177.89501692136, // 0.21286054671227406
195549.89326193667, // 0.2255178934867972
184574.521097589, // 0.23892788526691214
174215.14923953955, // 0.2531352766536054
164437.20424720907, // 0.26818748349492505
155208.0531381337, // 0.28413474113196574
146496.89447841974, // 0.30103027205464966
138274.655585821, // 0.3189304635268397
130513.89550236466, // 0.33789505577358997
123188.71341270483, // 0.3579873413585942
116274.66220255889, // 0.37927437641723355
109748.66686873636, // 0.4018272044501944
103588.94750846067, // 0.42572109342454817
97774.94663096833, // 0.4510357869735944
92287.26054879451, // 0.4778557705338242
87107.57461976977, // 0.5062705533072108
82218.60212360453, // 0.5363749669898501
77604.02656906686, // 0.5682694822639314
73248.44723920985, // 0.6020605441092994
69137.3277929105, // 0.6378609270536794
65256.94775118234, // 0.6757901115471798
61594.35670635241, // 0.7159746827171886
58137.331101279444, // 0.7585487528344671
54874.33343436817, // 0.8036544089003889
51794.47375423034, // 0.8514421868490962
48887.47331548417, // 0.9020715739471888
46143.63027439725, // 0.9557115410676486
43553.7873098849, // 1.0125411066144214
41109.30106180227, // 1.0727499339797002
38802.01328453342, // 1.136538964527863
36624.223619604934, // 1.2041210882185986
34568.66389645525, // 1.2757218541073587
32628.473875591164, // 1.3515802230943599
30797.17835317621, // 1.431949365434377
29068.665550639722, // 1.5170975056689342
27437.166717184085, // 1.6073088178007777
25897.23687711517, // 1.7028843736981925
24443.736657742083, // 1.8041431478943777
23071.815137198624, // 1.911423082135297
21776.89365494245, // 2.025082213228843
20554.650530901134, // 2.1454998679594004
19401.00664226671, // 2.273077929055726
18312.111809802467, // 2.4082421764371973
17284.331948227624, // 2.5514437082147174
16314.236937795582, // 2.7031604461887198
15398.589176588104, // 2.863898730868754
};
uint16_t
note_to_oct_fns(const int8_t note)
{
@ -689,6 +801,11 @@ static inline void pump_events(uint32_t istnrm)
}
}
static inline void aica_events()
{
}
static inline void tmu0_events()
{
xm_pattern_header_t * pattern_header = xm.pattern_header[state.pattern_index];
@ -747,6 +864,12 @@ void vbr600()
}
pump_events(istnrm);
} else if (sh7091.CCN.EXPEVT == 0 && sh7091.CCN.INTEVT == 0x360) { // AICA
aica_sound.common.mcire = (1 << 6); // interrupt timer A
aica_sound.common.tactl_tima =
aica::tactl_tima::TACTL(0) // increment once every samples
| aica::tactl_tima::TIMA(0xffff) // interrupt after 1 counts
;
} else if (sh7091.CCN.EXPEVT == 0 && sh7091.CCN.INTEVT == 0x400) { // TMU0
sh7091.TMU.TCR0
= tmu::tcr0::UNIE
@ -1211,8 +1334,9 @@ void sound_init()
//int buf = (int)&_binary_xm_milkypack01_xm_start;
//int buf = (int)&_binary_xm_middle_c_xm_start;
//int buf = (int)&_binary_xm_test_xm_start;
int buf = (int)&_binary_xm_xmtest_xm_start;
//int buf = (int)&_binary_xm_xmtest_xm_start;
//int buf = (int)&_binary_xm_catch_this_rebel_xm_start;
int buf = (int)&_binary_xm_reign_xm_start;
xm_init(buf);
wait(); aica_sound.common.vreg_armrst = aica::vreg_armrst::ARMRST(1);
@ -1327,6 +1451,15 @@ void sound_init()
sh7091.TMU.TSTR = tmu::tstr::str0::counter_start;
sh7091.INTC.IPRA = intc::ipra::TMU0(1);
aica_sound.common.tactl_tima =
aica::tactl_tima::TACTL(0) // increment once every samples
| aica::tactl_tima::TIMA(0xffff) // interrupt after 1 counts
;
aica_sound.common.mcieb = (1 << 6); // interrupt timer A
aica_sound.common.mcire = (1 << 6); // interrupt timer A
}
static ft0::data_transfer::data_format data[4];
@ -1376,6 +1509,29 @@ void do_get_condition()
}
}
constexpr int intmax(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int channel_state_execute_note(int ch,
int bytes_per_sample,
int address_start,
int address_end,
int offset)
{
int sa = address_start + offset;
int lsa = 0;
int lea = intmax();
wait(); aica_sound.channel[ch].SA(address_start);
wait(); aica_sound.channel[ch].LSA((lsa) & ~(0b11));
wait(); aica_sound.channel[ch].LEA((lsa + len) & ~(0b11));
}
void execute_note(int ch, const aica_sandbox_channel& channel)
{
xm_sample_header_t * sample_header = xm.sample_header[channel.instrument - 1];
@ -1386,8 +1542,8 @@ void execute_note(int ch, const aica_sandbox_channel& channel)
int loop_type = sample_header->type & 0b11;
int lsa = s32(&sample_header->sample_loop_start) / bytes_per_sample;
int len = s32(&sample_header->sample_loop_length) / bytes_per_sample;
int loop_start = s32(&sample_header->sample_loop_start);
int loop_length = s32(&sample_header->sample_loop_length);
if (len == 0) {
len = s32(&sample_header->sample_length) / bytes_per_sample;
@ -1555,6 +1711,8 @@ void main()
| istnrm::v_blank_in
| istnrm::end_of_transferring_opaque_list;
system.IML4EXT = istext::aica;
static uint8_t __attribute__((aligned(32))) ta_parameter_buf[1024 * 1024 * 1];
ta_parameter_writer writer = ta_parameter_writer(ta_parameter_buf, (sizeof (ta_parameter_buf)));

View File

@ -60,3 +60,8 @@
"FFST",,"5","holly_cpu_if_block_internal_write_buffer",,,
"FFST",,"4","holly_g2_if_block_internal_write_buffer",,,
"FFST",,"0","aica_internal_write_buffer",,,
,,,,,,
"ISTEXT",,3,"external_device",1,,
"ISTEXT",,2,"modem",1,,
"ISTEXT",,1,"aica",1,,
"ISTEXT",,0,"gdrom",1,,

1 register_name enum_name bits bit_name value mask description
60 FFST 5 holly_cpu_if_block_internal_write_buffer
61 FFST 4 holly_g2_if_block_internal_write_buffer
62 FFST 0 aica_internal_write_buffer
63
64 ISTEXT 3 external_device 1
65 ISTEXT 2 modem 1
66 ISTEXT 1 aica 1
67 ISTEXT 0 gdrom 1

Binary file not shown.

View File

@ -131,3 +131,13 @@ constexpr uint32_t holly_g2_if_block_internal_write_buffer(uint32_t reg) { retur
constexpr uint32_t aica_internal_write_buffer(uint32_t reg) { return (reg >> 0) & 0x1; }
}
namespace istext {
constexpr uint32_t external_device = 1 << 3;
constexpr uint32_t modem = 1 << 2;
constexpr uint32_t aica = 1 << 1;
constexpr uint32_t gdrom = 1 << 0;
}

BIN
xm/reign.xm Normal file

Binary file not shown.

15
xm/reign.xm.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_xm_reign_xm_start __asm("_binary_xm_reign_xm_start");
extern uint32_t _binary_xm_reign_xm_end __asm("_binary_xm_reign_xm_end");
extern uint32_t _binary_xm_reign_xm_size __asm("_binary_xm_reign_xm_size");
#ifdef __cplusplus
}
#endif