| 
    
       #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);
 
     | 
  
  
     | 
    
       ADC_VOLUME_NEXT <= flash_do_slow(21 downto 20);
 
     | 
  
  
     | 
    
       SIO_DATA_VOLUME_NEXT <= flash_do_slow(23 downto 22);
 
     | 
  
  
     | 
    
       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;
 
     | 
  
  
     | 
    
       	int sio_data_volume = 2;
 
     | 
  
  
     | 
    
       	int adc_volume = 3;
 
     | 
  
  
     | 
    
       	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 = 0b10100000;
 
     | 
  
  
     | 
    
       	buffer[1] |= (post_divide&0xff)<<0;
 
     | 
  
  
     | 
    
       	int gtia_enable = 0b1100;
 
     | 
  
  
     | 
    
       	buffer[2] |= (gtia_enable&0xf)<<0;
 
     | 
  
  
     | 
    
       	buffer[2] |= (adc_volume&0x3)<<4;
 
     | 
  
  
     | 
    
       	buffer[2] |= (sio_data_volume&0x3)<<6;
 
     | 
  
  
     | 
    
       	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
 
     | 
  
  
     | 
    
       	buffer[7] = 0xff; // 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);
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	int fir_base = 0xc00*4;
 
     | 
  
  
     | 
    
       	unsigned short * fir = (unsigned short *)(buffer+fir_base);
 
     | 
  
  
     | 
    
       	FILE * fr =fopen("fir_rom.bin","rb");
 
     | 
  
  
     | 
    
       	        fread(fir,2,2032,fr);
 
     | 
  
  
     | 
    
       	fclose(fr);
 
     | 
  
  
     | 
    
       	
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	FILE * x =fopen("init_0.bin","w");
 
     | 
  
  
     | 
    
       		fwrite(&buffer[0],1,32768,x);
 
     | 
  
  
     | 
    
       	fclose(x);
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	post_divide = 0b10100101;
 
     | 
  
  
     | 
    
       	buffer[1] |= (post_divide&0xff)<<0;
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	x =fopen("init_1.bin","w");
 
     | 
  
  
     | 
    
       		fwrite(&buffer[0],1,32768,x);
 
     | 
  
  
     | 
    
       	fclose(x);
 
     | 
  
  
     | 
    
       
     | 
  
  
     | 
    
       	return 0;
 
     | 
  
  
     | 
    
       }
 
     | 
  
  
     | 
    
       
     |