## Re: [stella] TIA polynomials revisited

 Subject: Re: [stella] TIA polynomials revisited From: Adam Wozniak Date: Sun, 7 Dec 2003 07:57:42 -0800 (PST)
```See if this is more palatable:

#include <stdio.h>

// sound.c
// version 0.5
//
//
// Permission granted to freely copy and use for any purpose, provided

#define DIV(name, hi, lo)                       \
int div_ ## name (void)                         \
{                                               \
static int spot = 0;                         \
static int count = 0;                        \
static const int array[] = { hi, lo, -1 };   \
static int lastval = 0;                      \
count++;                                     \
if (count == array[spot])                    \
{                                            \
spot++;                                   \
count = 0;                                \
}                                            \
if (array[spot] == -1) spot = 0;             \
if (lastval == !(spot^1))                    \
{                                            \
return 0;                                 \
}                                            \
else                                         \
{                                            \
lastval = !lastval;                       \
return 1;                                 \
}                                            \
}

#define LFSR(name, t1, t2)                                      \
int lfsr_ ## name (void)                                        \
{                                                               \
static int lastval = 1;                                      \
static int value = 1;                                        \
static const int taps[] = { t1, t2 };                        \
int next = ((value & (1 << (taps[0] - 1))) ? 1 : 0) ^        \
((value & (1 << (taps[1] - 1))) ? 1 : 0);         \
value = value << 1;                                          \
value |= next;                                               \
if ((value & 1) == lastval)                                  \
{                                                            \
return 0;                                                 \
}                                                            \
else                                                         \
{                                                            \
lastval = !lastval;                                       \
return 1;                                                 \
}                                                            \
}

DIV(2,   1,   1);
DIV(6,   3,   3);
DIV(31,  13, 18);
LFSR(poly4,  4,   3);
LFSR(poly5,  5,   3);
LFSR(poly9,  9,   5);

int vardiv(int count)
{
static int lastval = 1;
static int value = 1;
static int counter;

counter++;
if (counter >= count)
{
(value = !value);
counter = -1;
}

if (value == lastval)
{
return 0;
}
else
{
lastval = !lastval;
return 1;
}
}

void TIASOUND_fill(int F, int V, int C,
int infrequency, int outfrequency, int channels,
char *buf, int size)
{
static int value = 1;
static int rate = 0;

while(size > 0)
{
switch (C)
{
case 0:
value = 1;
break;
case 1:
vardiv(F) && lfsr_poly4() && (value = !value);
break;
case 2:
vardiv(F) && div_31() && lfsr_poly4() && (value = !value);
break;
case 3:
vardiv(F) && lfsr_poly5() && lfsr_poly4() && (value = !value);
break;
case 4:
vardiv(F) && div_2() && (value = !value);
break;
case 5:
vardiv(F) && div_2() && (value = !value);
break;
case 6:
vardiv(F) && div_31() && (value = !value);
break;
case 7:
vardiv(F) && lfsr_poly5() && div_2() && (value = !value);
// yes it looks different from 9, but it has the same output
break;
case 8:
vardiv(F) && lfsr_poly9() && (value = !value);
break;
case 9:
vardiv(F) && lfsr_poly5() && (value = !value);
break;
case 10:
vardiv(F) && div_31() && (value = !value);
break;
case 11:
value = 1;
break;
case 12:
vardiv(F) && div_6() && (value = !value);
break;
case 13:
vardiv(F) && div_6() && (value = !value);
break;
case 14:
vardiv(F) && div_31() && div_6() && (value = !value);
break;
case 15:
vardiv(F) && lfsr_poly5() && div_6() && (value = !value);
break;
}

rate += outfrequency;

while (rate >= infrequency && size)
{
*buf += value ? (V << 3) : 0;
rate -= infrequency;

buf += channels;
size -= channels;
}
}
}

void main(int argc, char **argv)
{
char buf[44100];
int i;

// usage
if (argc != 4)
{
fprintf(stderr, "Usage: %s <F:0-31> <V:0-15> <C:0-15>\n", argv[0]);
exit(-1);
}

// clear the buffer
bzero(buf, sizeof(buf));

// fill the buffer
TIASOUND_fill(atoi(argv[1]),
atoi(argv[2]),
atoi(argv[3]),
31400, 44100, 1,
buf, sizeof(buf));

// write it to stdout
write(1, buf, sizeof(buf));
}

--