diff --git a/example/aica/aica.mk b/example/aica/aica.mk index 99feb9b..0515701 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 \ + xm/reign.xm.o \ font/tandy1k/tandy1k.data.o \ holly/core.o \ holly/region_array.o \ diff --git a/example/aica/aica_xm.cpp b/example/aica/aica_xm.cpp index 63f82ab..bf9c159 100644 --- a/example/aica/aica_xm.cpp +++ b/example/aica/aica_xm.cpp @@ -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))); diff --git a/regs/systembus_bits.csv b/regs/systembus_bits.csv index 5eea483..310596b 100644 --- a/regs/systembus_bits.csv +++ b/regs/systembus_bits.csv @@ -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,, diff --git a/regs/systembus_bits.ods b/regs/systembus_bits.ods index a0baeb0..20fade0 100644 Binary files a/regs/systembus_bits.ods and b/regs/systembus_bits.ods differ diff --git a/systembus_bits.hpp b/systembus_bits.hpp index 9438840..80fce39 100644 --- a/systembus_bits.hpp +++ b/systembus_bits.hpp @@ -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; + +} + diff --git a/xm/reign.xm b/xm/reign.xm new file mode 100644 index 0000000..04b7587 Binary files /dev/null and b/xm/reign.xm differ diff --git a/xm/reign.xm.h b/xm/reign.xm.h new file mode 100644 index 0000000..f654c29 --- /dev/null +++ b/xm/reign.xm.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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