Project

General

Profile

#include "stdio.h"
#include "stdlib.h"
#include <math.h>

int ima_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};

int main(void)
{
/*
SATURATE_NEXT <= flash_do(0));
-- 1 reserved...
CHANNEL_MODE_NEXT <= flash_do(2);
IRQ_EN_NEXT <= flash_do(3);
DETECT_RIGHT_NEXT <= flash_do(4);
-- 5-7 reserved
POST_DIVIDE_NEXT <= flash_do(15 downto 8);
GTIA_DIVIDE_NEXT <= flash_do(19 downto 16);
-- 23 downto 20 reserved
PSG_FREQ_NEXT <= flash_do(25 downto 24);
PSG_STEREOMODE_NEXT <= flash_do(27 downto 26);
PSG_ENVELOPE16_NEXT <= flash_do(28);
-- 31 downto 29 reserved
*/
/* DETECT_RIGHT_REG <= '1';
IRQ_EN_REG <= '0';
CHANNEL_MODE_REG <= '0';
SATURATE_REG <= '1';
POST_DIVIDE_REG <= "10100000"; -- 1/2 5v, 3/4 1v
GTIA_ENABLE_REG <= "1100"; -- external only
CONFIG_ENABLE_REG <= '0';
VERSION_LOC_REG <= (others=>'0');
PSG_FREQ_REG <= "00"; --2MHz
PSG_STEREOMODE_REG <= "01"; --Polish
PSG_ENVELOPE16_REG <= '0'; --32 step
*/

char * buffer = (char *) malloc(32768);
int i=0;
for (i=0;i!=32768;++i)
buffer[i] = 0;

int saturate = 1;
int channel_mode = 0;
int irq_en = 0;
int detect_right = 1;
int pal = 1;
buffer[0] |= (saturate&3)<<0;
buffer[0] |= (channel_mode&1)<<2;
buffer[0] |= (irq_en&1)<<3;
buffer[0] |= (detect_right&1)<<4;
buffer[0] |= (pal&1)<<5;
int post_divide = 0b10100101;
buffer[1] |= (post_divide&0xff)<<0;
int gtia_enable = 0b1100;
buffer[2] |= (gtia_enable&0xf)<<0;
int psg_freq = 0;
int psg_stereomode = 1;
int psg_envelope16 = 0;
buffer[3] |= (psg_freq&3)<<0;
buffer[3] |= (psg_stereomode&3)<<2;
buffer[3] |= (psg_envelope16&1)<<4;

//buffer[4] = 0x22; // 8580 filter, with digifix
buffer[4] = 0x11; // 6581 filter
buffer[5] = 0xff; // enable_all

buffer[6] = 0x10; // enable_all

// 0x80(0x200 8-bit) adpcm step table - 90
for (i=0x0; i!=89; ++i)
{
buffer[((0x80+i)<<2) + 0] = ima_step_table[i]&0xff;
buffer[((0x80+i)<<2) + 1] = (ima_step_table[i]>>8)&0xff;
buffer[((0x80+i)<<2) + 2] = (ima_step_table[i]>>16)&0xff;
buffer[((0x80+i)<<2) + 3] = (ima_step_table[i]>>24)&0xff;
}

// 0x100(0x400 8-bit) psg volume table - 128
int psgvoltablebase = 0x400;
unsigned int * psgvoltable[4];
psgvoltable[0] = (unsigned int *)(buffer+psgvoltablebase);
psgvoltable[1] = (unsigned int *)(buffer+psgvoltablebase+(32*4));
psgvoltable[2] = (unsigned int *)(buffer+psgvoltablebase+(64*4));
psgvoltable[3] = (unsigned int *)(buffer+psgvoltablebase+(96*4));
i = 0;
psgvoltable[0][i++] = 0b0000000000000000; //ym2149 from octave capture I think (CONFIRM!!)
psgvoltable[0][i++] = 0b0000000000011100;
psgvoltable[0][i++] = 0b0000000000111101;
psgvoltable[0][i++] = 0b0000000001100110;
psgvoltable[0][i++] = 0b0000000010011001;
psgvoltable[0][i++] = 0b0000000011010111;
psgvoltable[0][i++] = 0b0000000100100011;
psgvoltable[0][i++] = 0b0000000110000000;
psgvoltable[0][i++] = 0b0000000111110001;
psgvoltable[0][i++] = 0b0000001001111101;
psgvoltable[0][i++] = 0b0000001100100111;
psgvoltable[0][i++] = 0b0000001111111000;
psgvoltable[0][i++] = 0b0000010011111000;
psgvoltable[0][i++] = 0b0000011000110001;
psgvoltable[0][i++] = 0b0000011110110001;
psgvoltable[0][i++] = 0b0000100110000111;
psgvoltable[0][i++] = 0b0000101111000111;
psgvoltable[0][i++] = 0b0000111010001000;
psgvoltable[0][i++] = 0b0001000111101000;
psgvoltable[0][i++] = 0b0001011000001010;
psgvoltable[0][i++] = 0b0001101100011001;
psgvoltable[0][i++] = 0b0010000101001100;
psgvoltable[0][i++] = 0b0010100011100011;
psgvoltable[0][i++] = 0b0011001000101111;
psgvoltable[0][i++] = 0b0011110110010010;
psgvoltable[0][i++] = 0b0100101110000100;
psgvoltable[0][i++] = 0b0101110010011000;
psgvoltable[0][i++] = 0b0111000110000011;
psgvoltable[0][i++] = 0b1000101100100001;
psgvoltable[0][i++] = 0b1010101010000001;
psgvoltable[0][i++] = 0b1101000011101111;
psgvoltable[0][i++] = 0b1111111111111111;
for (i=0;i!=32;++i)
{
//psgvoltable[1][i] = psgvoltable[0][i]; //ym2149
psgvoltable[1][i] = psgvoltable[0][i]; //ay3 TODO
psgvoltable[2][i] = (256*(pow(sqrt(2),i)/pow(sqrt(2),15)))-1; //datasheet of ym2149!
psgvoltable[3][i] = i<<11; //linear
}

for (i=0;i!=32;++i)
{
printf("psg:%d:%ld:%ld:%ld:%ld\n",i,psgvoltable[0][i],psgvoltable[1][i],psgvoltable[2][i],psgvoltable[3][i]);
}

// 0x180(0x600 8-bit) pokey volume table - 128
int pokeyvoltablebase = 0x600;
unsigned int * pokeyvoltable[2];
pokeyvoltable[0] = (unsigned int *)(buffer+pokeyvoltablebase);
pokeyvoltable[1] = (unsigned int *)(buffer+pokeyvoltablebase+(64*4));
i = 0;
pokeyvoltable[1][i++] = 0x0022;
pokeyvoltable[1][i++] = 0x0993;
pokeyvoltable[1][i++] = 0x135E;
pokeyvoltable[1][i++] = 0x1D9A;
pokeyvoltable[1][i++] = 0x2842;
pokeyvoltable[1][i++] = 0x3345;
pokeyvoltable[1][i++] = 0x3E84;
pokeyvoltable[1][i++] = 0x49E0;
pokeyvoltable[1][i++] = 0x5538;
pokeyvoltable[1][i++] = 0x606E;
pokeyvoltable[1][i++] = 0x6B69;
pokeyvoltable[1][i++] = 0x7612;
pokeyvoltable[1][i++] = 0x805A;
pokeyvoltable[1][i++] = 0x8A34;
pokeyvoltable[1][i++] = 0x9399;
pokeyvoltable[1][i++] = 0x9C84;
pokeyvoltable[1][i++] = 0xA4F4;
pokeyvoltable[1][i++] = 0xACEA;
pokeyvoltable[1][i++] = 0xB468;
pokeyvoltable[1][i++] = 0xBB70;
pokeyvoltable[1][i++] = 0xC207;
pokeyvoltable[1][i++] = 0xC830;
pokeyvoltable[1][i++] = 0xCDEE;
pokeyvoltable[1][i++] = 0xD343;
pokeyvoltable[1][i++] = 0xD833;
pokeyvoltable[1][i++] = 0xDCC0;
pokeyvoltable[1][i++] = 0xE0EB;
pokeyvoltable[1][i++] = 0xE4B6;
pokeyvoltable[1][i++] = 0xE824;
pokeyvoltable[1][i++] = 0xEB36;
pokeyvoltable[1][i++] = 0xEDEF;
pokeyvoltable[1][i++] = 0xF053;
pokeyvoltable[1][i++] = 0xF265;
pokeyvoltable[1][i++] = 0xF42B;
pokeyvoltable[1][i++] = 0xF5AB;
pokeyvoltable[1][i++] = 0xF6E9;
pokeyvoltable[1][i++] = 0xF7EF;
pokeyvoltable[1][i++] = 0xF8C3;
pokeyvoltable[1][i++] = 0xF96D;
pokeyvoltable[1][i++] = 0xF9F4;
pokeyvoltable[1][i++] = 0xFA61;
pokeyvoltable[1][i++] = 0xFABB;
pokeyvoltable[1][i++] = 0xFB07;
pokeyvoltable[1][i++] = 0xFB4C;
pokeyvoltable[1][i++] = 0xFB8D;
pokeyvoltable[1][i++] = 0xFBCE;
pokeyvoltable[1][i++] = 0xFC11;
pokeyvoltable[1][i++] = 0xFC56;
pokeyvoltable[1][i++] = 0xFC9F;
pokeyvoltable[1][i++] = 0xFCEA;
pokeyvoltable[1][i++] = 0xFD37;
pokeyvoltable[1][i++] = 0xFD85;
pokeyvoltable[1][i++] = 0xFDD5;
pokeyvoltable[1][i++] = 0xFE28;
pokeyvoltable[1][i++] = 0xFE82;
pokeyvoltable[1][i++] = 0xFEE7;
pokeyvoltable[1][i++] = 0xFF5D;
pokeyvoltable[1][i++] = 0xFFEB;
pokeyvoltable[1][i++] = 0xFFFF;
pokeyvoltable[1][i++] = 0xFFFF;
pokeyvoltable[1][i++] = 0xFFFF;
for (i=0;i!=64;++i)
{
//pokeyvoltable[1][i] = pokeyvoltable[0][i]; //ym2149
pokeyvoltable[0][i] = i<<10; //linear
}

for (i=0;i!=64;++i)
{
printf("pokey:%d:%d:%d\n",i,pokeyvoltable[0][i],pokeyvoltable[1][i]);
}

// 0x200(0x800 8-bit) sid q table - 32 (4 32-bit, 4 32-bit)
// 8580=0,6581=1
int sidqtablebase = 0x800;
unsigned int * sidqtable[2];
sidqtable[0] = (unsigned int *)(buffer+sidqtablebase);
sidqtable[1] = (unsigned int *)(buffer+sidqtablebase+(16*4));
for (i=0;i!=16;++i)
{
double Q = 1.0/pow(2.0,(4.0-(double)i)/8.0);
sidqtable[0][i] = round(32768.0/Q);
}
for (i=0;i!=16;++i)
{
//-- --_1_div_Q = 1.f / (0.5f + resonanceFactor * res / 18f);
double Q = 0.5 + ((double)i)/18.0;
sidqtable[1][i] = round(32768.0/Q);
}
for (i=0;i!=16;++i)
{
printf("sidq:%d:%d:%d\n",i,sidqtable[0][i],sidqtable[1][i]);
}
//-- Q := 1.0/(2.0**((4.0-real(Qval))/8.0));
//-- ret := to_signed(integer(32768.0/Q),18);
//-- return ret;
//--
//-- -- q = 1.0 / Q;
//-- -- q = int64(round(q*32768));%3.15u
//-- function compute_q(Qval : integer) return signed is
//-- variable Q : real;
//-- variable ret : signed(17 downto 0);
//-- begin
//-- Q := 1.0/(2.0**((4.0-real(Qval))/8.0));
//-- ret := to_signed(integer(32768.0/Q),18);
//-- return ret;
//--
//-- -- resonanceFactor is 1!
//-- --8580:
//-- --_1_div_Q = 1.f / (0.707f + resonanceFactor * res / 15.f);
//-- --6581:
//-- --_1_div_Q = 1.f / (0.5f + resonanceFactor * res / 18f);
//-- end function compute_q;
//--
//-- process(Q)
//-- begin
//-- q_next <= (others=>'0');
//--
//-- for I in 0 to 15 loop
//-- if (to_integer(unsigned(Q)) = I) then
//-- q_next <= compute_q(I);
//-- end if;
//-- end loop;
//-- end process;


// 0x100(0x400 8-bit) sid tables --TODO!!
// to store:
// i) 6581 channel mixing:
// wire [7:0] wave__st[4096]; (sawtooth + triangle)
// wire [7:0] wave_p_t[2048]; (pulse + triangle - symmetric)
// wire [7:0] wave_ps_[4096]; (pulse + sawtooth)
// wire [7:0] wave_pst[4096]; (pulse + sawtooth + triangle)
// _st_out <= wave__st[sawtooth];
// p_t_out <= wave_p_t[triangle[11:1]];
// ps__out <= wave_ps_[sawtooth];
// pst_out <= wave_pst[sawtooth];
// 4'b0001: wave_out = triangle;
// 4'b0010: wave_out = sawtooth;
// 4'b0011: wave_out = {_st_out, 4'b0000};
// 4'b0100: wave_out = pulse;
// 4'b0101: wave_out = {p_t_out, 4'b0000} & pulse;
// 4'b0110: wave_out = {ps__out, 4'b0000} & pulse;
// 4'b0111: wave_out = {pst_out, 4'b0000} & pulse;
// 4'b1000: wave_out = noise;
// default: wave_out = 0;
// ii) 8580 channel mixing: just and?
// iii) linear filter
// iv) 6581 filter frequency table
// v) 8580 filter frequency table
// vi) 6581 volume non-linearity filter adjustment
// CLKSPEED : IN integer; --In Hz 58333333
// FMIN : IN integer; --In Hz (30)
// FMAX : IN integer --In Hz (12500 on 8580)
// process(CUTOFF_FREQUENCY)
// constant f_min : real := 2.0*sin(MATH_PI*real(FMIN)/real(CLKSPEED));
// constant f_max : real := 2.0*sin(MATH_PI*real(FMAX)/real(CLKSPEED));
//
// variable f_offset : unsigned(17 downto 0); --0.21(000,18)
// variable f_scale : unsigned(17 downto 0); --0.21(000,18)
//
// variable F_MULT : UNSIGNED(35 DOWNTO 0);
// begin
// --f = 2*sin(pi*10000/inrate);
// --CUTOFF_FREQUENCY : IN STD_LOGIC_VECTOR(10 downto 0);
// --CLKSPEED : IN integer; --In Hz
// --FMIN : IN integer; --In Hz
// --FMAX : IN integer; --In Hz
//
// f_offset := to_unsigned(integer(f_min*2.0**21.0),18);
// f_scale := to_unsigned(integer(2.0**21.0*((f_max-f_min)/2.0**11.0)),18);
//
// -- TODO: Could use a real curve captured from a chip? Lets start with it correctly then...
// f_mult := f_scale * resize(unsigned(CUTOFF_FREQUENCY),18);
// f_next <= f_mult(17 downto 0) + f_offset;
// end process;

// 0x400(0x1000 8-bit) sid frequency tables
int sidfreqtablebase = 2048*2;
unsigned short * sidfreqtable = (unsigned short *)(buffer+sidfreqtablebase);

// We have a table of tadj values - 39 positions - for interp
// sigmoidreal = @(x) 1./(1.+e.^-x);
// rescale = 0.133923834850281;
// reoffset = 0.00188312488556502;
// low = -8;
// high = 8;
// vals = low:(high-low)/ceil(32*300/256):high; % I lookup in a range 1:300... shift is 0-255...
// t = sigmoidreal(vals)*rescale + reoffset;
//
// clockorig = 985248.400000;
// clocknew = 58333333.0;
//
// %origscale = 2.0*sin(M_PI*freqval/clockorig);
// freqval = asin(t/2)*clockorig/pi;
// tadj = 2*sin(pi*freqval/clocknew);
//
// in 8580 mode, state is 0, so we just use this directly
// in 6581 mode, we add the voltage, so we shift the sigmoid..
double interp[] = {68.000000,69.000000,70.000000,72.000000,75.000000,79.000000,86.000000,96.000000,112.000000,136.000000,171.000000,224.000000,303.000000,417.000000,581.000000,809.000000,1112.000000,1495.000000,1946.000000,2439.000000,2931.000000,3383.000000,3766.000000,4070.000000,4297.000000,4462.000000,4577.000000,4655.000000,4708.000000,4744.000000,4768.000000,4783.000000,4794.000000,4801.000000,4805.000000,4808.000000,4810.000000,4811.000001,4812.000000};

// Lets write 2 tables...
// i) linear
double CLKSPEED = 58333333.0;
double FMIN = 30;
double FMAX = 12500;
double f_min = 2.0*sin(M_PI*FMIN/CLKSPEED);
double f_max = 2.0*sin(M_PI*FMAX/CLKSPEED);
for (int i=0;i!=2048;++i)
{
double f_offset = f_min*pow(2,21);
double f_scale = pow(2,21)*((f_max-f_min)/pow(2,11));
double f_mult = f_scale*((double)i);
double f_next = f_mult+f_offset;
// printf("%d:%f:%f\n",i,f_next,round(f_next));
sidfreqtable[i] = (unsigned short)round(f_next);
}
// i) 8580 (which?)
FILE * f;
// f = fopen("8580.csv","r"); //fc-curves/Trurl_Ext/8580R5_3691.txt
// for (int i=0;i!=2048;++i)
// {
// double freqval;
// fscanf(f,"%lf",&freqval);
//
// double freq = 2.0*sin(M_PI*freqval/CLKSPEED);
//
// double f_next = pow(2,21)*(freq);
//// printf("%d:%f:%f\n",i,f_next,round(f_next));
// sidfreqtable[i] = (unsigned short)round(f_next);
// }
// fclose(f);
// ii) 6581 (which?)
//printf("%f - %f\n",f_min,f_max);
f = fopen("6581.csv","r"); //fc-curves/Trurl_Ext/6581R4AR_3789.txt
for (int i=0;i!=2048;++i)
{
double freqval;
fscanf(f,"%lf",&freqval);

double freq = 2.0*sin(M_PI*freqval/CLKSPEED);
// printf("freqval %lf - freq %lf\n",freqval,freq);

double f_next = pow(2,21)*(freq);
// We want f_next, but we need to work out which val in interp table to use...
int j;
for (j=0;j<38;++j)
if (interp[j+1]>f_next)
break;
if (j==38)
j = 37;
double l = interp[j];
double h = interp[j+1];
double f_in_range = fmax(fmin(h,f_next),l);
double lookup = round(128*((double)(j) + (f_in_range-l)/(h-l)));
double f_got = ((h-l)*((lookup/128) - j))+l;
double freq_got = CLKSPEED*asin((f_got/2)/pow(2,21))/M_PI;
printf("%d: 6581 interp %d:%f<%f<%f at %d - wanted:%f got:%f %f %f lookup:%f - %f\n",sizeof(interp)/sizeof(double),i,l,f_next,h,j,freqval,freq_got,f_in_range, f_got, lookup/128, lookup);
sidfreqtable[i+2048] = (unsigned short)lookup;
}
fclose(f);

FILE * x =fopen("init.bin","w");
fwrite(&buffer[0],1,32768,x);
fclose(x);

return 0;
}

(16-16/79)