153 lines
4.1 KiB
C++
153 lines
4.1 KiB
C++
#include "aica/aica.hpp"
|
|
|
|
#include "xm/xm.h"
|
|
#include "xm/milkypack01.xm.h"
|
|
|
|
extern volatile uint32_t dram[0x200000] __asm("dram");
|
|
|
|
constexpr int max_patterns = 64;
|
|
constexpr int max_instruments = 128;
|
|
struct xm_state {
|
|
xm_header_t * header;
|
|
xm_pattern_header_t * pattern_header[max_patterns];
|
|
xm_instrument_header_t * instrument_header[max_instruments];
|
|
xm_sample_header_t * sample_header; // array
|
|
};
|
|
|
|
static xm_state xm = {0};
|
|
|
|
int s16(void * buf)
|
|
{
|
|
uint8_t * b = (uint8_t *)buf;
|
|
int16_t v = (b[0] << 0) | (b[1] << 8);
|
|
return v;
|
|
}
|
|
|
|
int s32(void * buf)
|
|
{
|
|
uint8_t * b = (uint8_t *)buf;
|
|
int32_t v = (b[0] << 0) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
|
|
return v;
|
|
}
|
|
|
|
int xm_samples_init(int buf, int offset, int number_of_samples)
|
|
{
|
|
xm_sample_header_t * sample_header[number_of_samples];
|
|
for (int i = 0; i < number_of_samples; i++) {
|
|
sample_header[i] = (xm_sample_header_t *)(buf + offset);
|
|
offset += (sizeof (xm_sample_header_t));
|
|
}
|
|
|
|
for (int i = 0; i < number_of_samples; i++) {
|
|
offset += s32(&sample_header[i]->sample_length);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
void print(int i)
|
|
{
|
|
for (int i = 0; i < 100000; i++) {
|
|
asm volatile ("nop");
|
|
}
|
|
dram[0] = i;
|
|
}
|
|
|
|
void xm_init()
|
|
{
|
|
int buf = (int)(&_binary_xm_milkypack01_xm_start);
|
|
|
|
while (xm.header != (xm_header_t *)(buf))
|
|
xm.header = (xm_header_t *)(buf);
|
|
|
|
int offset = s32(&xm.header->header_size) + (offsetof (struct xm_header, header_size));
|
|
|
|
int number_of_patterns = s16(&xm.header->number_of_patterns);
|
|
print(0x12345678);
|
|
print(number_of_patterns);
|
|
|
|
for (int i = 0; i < number_of_patterns; i++) {
|
|
xm_pattern_header_t * pattern_header = (xm_pattern_header_t *)(buf + offset);
|
|
|
|
xm.pattern_header[i] = pattern_header;
|
|
|
|
offset += s32(&pattern_header->pattern_header_length) + s16(&pattern_header->packed_pattern_data_size);
|
|
print(offset);
|
|
}
|
|
|
|
int number_of_instruments = s16(&xm.header->number_of_instruments);
|
|
for (int i = 0; i < number_of_instruments; i++) {
|
|
xm_instrument_header_t * instrument_header = (xm_instrument_header_t *)(buf + offset);
|
|
|
|
xm.instrument_header[i] = instrument_header;
|
|
offset += s32(&instrument_header->instrument_size);
|
|
|
|
int number_of_samples = s16(&instrument_header->number_of_samples);
|
|
offset = xm_samples_init(buf, offset, number_of_samples);
|
|
}
|
|
|
|
print(0x11223344);
|
|
print(offset);
|
|
}
|
|
|
|
extern "C"
|
|
void main()
|
|
{
|
|
volatile uint32_t * slot = reinterpret_cast<volatile uint32_t*>(0x00800000);
|
|
for (uint32_t i = 0; i < (sizeof (struct aica_channel)) * 64 / 4; i++) {
|
|
slot[i] = 0;
|
|
}
|
|
|
|
volatile uint32_t * dsp = reinterpret_cast<volatile uint32_t*>(0x00803000);
|
|
for (int i = 0; i < 0xb00 / 4; i++) {
|
|
dsp[i] = 0;
|
|
}
|
|
|
|
aica_sound.channel[0].KYONB(1);
|
|
aica_sound.channel[0].LPCTL(1);
|
|
aica_sound.channel[0].PCMS(0);
|
|
aica_sound.channel[0].LSA(0);
|
|
aica_sound.channel[0].LEA(128);
|
|
aica_sound.channel[0].D2R(0x0);
|
|
aica_sound.channel[0].D1R(0x0);
|
|
aica_sound.channel[0].RR(0x0);
|
|
aica_sound.channel[0].AR(0x1f);
|
|
|
|
aica_sound.channel[0].OCT(0);
|
|
aica_sound.channel[0].FNS(0);
|
|
aica_sound.channel[0].DISDL(0xf);
|
|
aica_sound.channel[0].DIPAN(0x0);
|
|
|
|
aica_sound.channel[0].Q(0b00100);
|
|
aica_sound.channel[0].TL(0);
|
|
aica_sound.channel[0].LPOFF(1);
|
|
|
|
aica_sound.common.mono_mem8mb_dac18b_ver_mvol =
|
|
aica::mono_mem8mb_dac18b_ver_mvol::MONO(0) // enable panpots
|
|
| aica::mono_mem8mb_dac18b_ver_mvol::MEM8MB(0) // 16Mbit SDRAM
|
|
| aica::mono_mem8mb_dac18b_ver_mvol::DAC18B(0) // 16-bit DAC
|
|
| aica::mono_mem8mb_dac18b_ver_mvol::MVOL(0xf) // 15/15 volume
|
|
;
|
|
|
|
uint32_t segment = 0;
|
|
|
|
constexpr uint32_t timer_a_interrupt = (1 << 6);
|
|
aica_sound.common.scire = timer_a_interrupt;
|
|
bool started = 0;
|
|
|
|
xm_init();
|
|
|
|
while (1) {
|
|
if (!started || (aica_sound.common.SCIPD() & timer_a_interrupt)) {
|
|
//aica_sound.channel[0].SA(next_sa);
|
|
aica_sound.common.tactl_tima =
|
|
aica::tactl_tima::TACTL(0) // increment once every 128 samples
|
|
| aica::tactl_tima::TIMA(256 - 128) // interrupt after 128 counts
|
|
;
|
|
|
|
if (!started) { aica_sound.channel[0].KYONEX(1); started = 1; }
|
|
|
|
aica_sound.common.scire = timer_a_interrupt;
|
|
}
|
|
}
|
|
}
|