Fix compile and remove redundant files

This commit is contained in:
Barry Harris 2015-03-05 14:19:49 +00:00
parent 854e628fea
commit 6cd35ee287
3 changed files with 1 additions and 328 deletions

View File

@ -9,7 +9,7 @@
#include <malloc.h>
#include <math.h>
#include <limits.h>
#include <zlib.h>
#include "zlib.h"
#include "sms.h"
#include "smspio.h"

View File

@ -1,249 +0,0 @@
/*
SN76489 emulation
by Maxim in 2001 and 2002
converted from my original Delphi implementation
I'm a C newbie so I'm sure there are loads of stupid things
in here which I'll come back to some day and redo
Includes:
- Super-high quality tone channel "oversampling" by calculating fractional positions on transitions
- Noise output pattern reverse engineered from actual SMS output
- Volume levels taken from actual SMS output
07/08/04 Charles MacDonald
Modified for use with SMS Plus:
- Added support for multiple PSG chips.
- Added reset/config/update routines.
- Added context management routines.
- Removed SN76489_GetValues().
- Removed some unused variables.
*/
#include "smsshared.h"
#define NoiseInitialState 0x8000 /* Initial state of shift register */
#define PSG_CUTOFF 0x6 /* Value below which PSG does not output */
/* These values are taken from a real SMS2's output */
static const int PSGVolumeValues[2][16] = {
{892,892,892,760,623,497,404,323,257,198,159,123,96,75,60,0}, /* I can't remember why 892... :P some scaling I did at some point */
{892,774,669,575,492,417,351,292,239,192,150,113,80,50,24,0}
};
static SN76489_Context SN76489[MAX_SN76489];
void SN76489_Init(int which, int PSGClockValue, int SamplingRate)
{
SN76489_Context *p = &SN76489[which];
p->dClock=(float)PSGClockValue/16/SamplingRate;
SN76489_Config(which, MUTE_ALLON, BOOST_ON, VOL_FULL, FB_SEGAVDP);
SN76489_Reset(which);
}
void SN76489_Reset(int which)
{
SN76489_Context *p = &SN76489[which];
int i;
p->PSGStereo = 0xFF;
for(i = 0; i <= 3; i++)
{
/* Initialise PSG state */
p->Registers[2*i] = 1; /* tone freq=1 */
p->Registers[2*i+1] = 0xf; /* vol=off */
p->NoiseFreq = 0x10;
/* Set counters to 0 */
p->ToneFreqVals[i] = 0;
/* Set flip-flops to 1 */
p->ToneFreqPos[i] = 1;
/* Set intermediate positions to do-not-use value */
p->IntermediatePos[i] = LONG_MIN;
}
p->LatchedRegister=0;
/* Initialise noise generator */
p->NoiseShiftRegister=NoiseInitialState;
/* Zero clock */
p->Clock=0;
}
void SN76489_Shutdown(void)
{
}
void SN76489_Config(int which, int mute, int boost, int volume, int feedback)
{
SN76489_Context *p = &SN76489[which];
p->Mute = mute;
p->BoostNoise = boost;
p->VolumeArray = volume;
p->WhiteNoiseFeedback = feedback;
}
void SN76489_SetContext(int which, uint8 *data)
{
memcpy(&SN76489[which], data, sizeof(SN76489_Context));
}
void SN76489_GetContext(int which, uint8 *data)
{
memcpy(data, &SN76489[which], sizeof(SN76489_Context));
}
uint8 *SN76489_GetContextPtr(int which)
{
return (uint8 *)&SN76489[which];
}
int SN76489_GetContextSize(void)
{
return sizeof(SN76489_Context);
}
void SN76489_Write(int which, int data)
{
SN76489_Context *p = &SN76489[which];
if (data&0x80) {
/* Latch/data byte %1 cc t dddd */
p->LatchedRegister=((data>>4)&0x07);
p->Registers[p->LatchedRegister]=
(p->Registers[p->LatchedRegister] & 0x3f0) /* zero low 4 bits */
| (data&0xf); /* and replace with data */
} else {
/* Data byte %0 - dddddd */
if (!(p->LatchedRegister%2)&&(p->LatchedRegister<5))
/* Tone register */
p->Registers[p->LatchedRegister]=
(p->Registers[p->LatchedRegister] & 0x00f) /* zero high 6 bits */
| ((data&0x3f)<<4); /* and replace with data */
else
/* Other register */
p->Registers[p->LatchedRegister]=data&0x0f; /* Replace with data */
}
switch (p->LatchedRegister) {
case 0:
case 2:
case 4: /* Tone channels */
if (p->Registers[p->LatchedRegister]==0) p->Registers[p->LatchedRegister]=1; /* Zero frequency changed to 1 to avoid div/0 */
break;
case 6: /* Noise */
p->NoiseShiftRegister=NoiseInitialState; /* reset shift register */
p->NoiseFreq=0x10<<(p->Registers[6]&0x3); /* set noise signal generator frequency */
break;
}
}
void SN76489_GGStereoWrite(int which, int data)
{
SN76489_Context *p = &SN76489[which];
p->PSGStereo=data;
}
void SN76489_Update(int which, INT16 **buffer, int length)
{
SN76489_Context *p = &SN76489[which];
int i, j;
for(j = 0; j < length; j++)
{
for (i=0;i<=2;++i)
if (p->IntermediatePos[i]!=LONG_MIN)
p->Channels[i]=(p->Mute >> i & 0x1)*PSGVolumeValues[p->VolumeArray][p->Registers[2*i+1]]*p->IntermediatePos[i]/65536;
else
p->Channels[i]=(p->Mute >> i & 0x1)*PSGVolumeValues[p->VolumeArray][p->Registers[2*i+1]]*p->ToneFreqPos[i];
p->Channels[3]=(short)((p->Mute >> 3 & 0x1)*PSGVolumeValues[p->VolumeArray][p->Registers[7]]*(p->NoiseShiftRegister & 0x1));
if (p->BoostNoise) p->Channels[3]<<=1; /* Double noise volume to make some people happy */
buffer[0][j] =0;
buffer[1][j] =0;
for (i=0;i<=3;++i) {
buffer[0][j] +=(p->PSGStereo >> (i+4) & 0x1)*p->Channels[i]; /* left */
buffer[1][j] +=(p->PSGStereo >> i & 0x1)*p->Channels[i]; /* right */
}
p->Clock+=p->dClock;
p->NumClocksForSample=(int)p->Clock; /* truncates */
p->Clock-=p->NumClocksForSample; /* remove integer part */
/* Looks nicer in Delphi... */
/* Clock:=Clock+p->dClock; */
/* NumClocksForSample:=Trunc(Clock); */
/* Clock:=Frac(Clock); */
/* Decrement tone channel counters */
for (i=0;i<=2;++i)
p->ToneFreqVals[i]-=p->NumClocksForSample;
/* Noise channel: match to tone2 or decrement its counter */
if (p->NoiseFreq==0x80) p->ToneFreqVals[3]=p->ToneFreqVals[2];
else p->ToneFreqVals[3]-=p->NumClocksForSample;
/* Tone channels: */
for (i=0;i<=2;++i) {
if (p->ToneFreqVals[i]<=0) { /* If it gets below 0... */
if (p->Registers[i*2]>PSG_CUTOFF) {
/* Calculate how much of the sample is + and how much is - */
/* Go to floating point and include the clock fraction for extreme accuracy :D */
/* Store as long int, maybe it's faster? I'm not very good at this */
p->IntermediatePos[i]=(long)((p->NumClocksForSample-p->Clock+2*p->ToneFreqVals[i])*p->ToneFreqPos[i]/(p->NumClocksForSample+p->Clock)*65536);
p->ToneFreqPos[i]=-p->ToneFreqPos[i]; /* Flip the flip-flop */
} else {
p->ToneFreqPos[i]=1; /* stuck value */
p->IntermediatePos[i]=LONG_MIN;
}
p->ToneFreqVals[i]+=p->Registers[i*2]*(p->NumClocksForSample/p->Registers[i*2]+1);
} else p->IntermediatePos[i]=LONG_MIN;
}
/* Noise channel */
if (p->ToneFreqVals[3]<=0) { /* If it gets below 0... */
p->ToneFreqPos[3]=-p->ToneFreqPos[3]; /* Flip the flip-flop */
if (p->NoiseFreq!=0x80) /* If not matching tone2, decrement counter */
p->ToneFreqVals[3]+=p->NoiseFreq*(p->NumClocksForSample/p->NoiseFreq+1);
if (p->ToneFreqPos[3]==1) { /* Only once per cycle... */
int Feedback;
if (p->Registers[6]&0x4) { /* White noise */
/* Calculate parity of fed-back bits for feedback */
switch (p->WhiteNoiseFeedback) {
/* Do some optimised calculations for common (known) feedback values */
case 0x0006: /* SC-3000 %00000110 */
case 0x0009: /* SMS, GG, MD %00001001 */
/* If two bits fed back, I can do Feedback=(nsr & fb) && (nsr & fb ^ fb) */
/* since that's (one or more bits set) && (not all bits set) */
/* which one? Feedback=((p->NoiseShiftRegister&p->WhiteNoiseFeedback) && (p->NoiseShiftRegister&p->WhiteNoiseFeedback^p->WhiteNoiseFeedback)); */
Feedback=((p->NoiseShiftRegister&p->WhiteNoiseFeedback) && ((p->NoiseShiftRegister&p->WhiteNoiseFeedback)^p->WhiteNoiseFeedback));
break;
case 0x8005: /* BBC Micro */
/* fall through :P can't be bothered to think too much */
default: /* Default handler for all other feedback values */
Feedback=p->NoiseShiftRegister&p->WhiteNoiseFeedback;
Feedback^=Feedback>>8;
Feedback^=Feedback>>4;
Feedback^=Feedback>>2;
Feedback^=Feedback>>1;
Feedback&=1;
break;
}
} else /* Periodic noise */
Feedback=p->NoiseShiftRegister&1;
p->NoiseShiftRegister=(p->NoiseShiftRegister>>1) | (Feedback<<15);
/* Original code: */
/* p->NoiseShiftRegister=(p->NoiseShiftRegister>>1) | ((p->Registers[6]&0x4?((p->NoiseShiftRegister&0x9) && (p->NoiseShiftRegister&0x9^0x9)):p->NoiseShiftRegister&1)<<15); */
}
}
}
}

View File

@ -1,78 +0,0 @@
#ifndef _SN76489_H_
#define _SN76489_H_
#define MAX_SN76489 4
/*
More testing is needed to find and confirm feedback patterns for
SN76489 variants and compatible chips.
*/
enum feedback_patterns {
FB_BBCMICRO = 0x8005, /* Texas Instruments TMS SN76489N (original) from BBC Micro computer */
FB_SC3000 = 0x0006, /* Texas Instruments TMS SN76489AN (rev. A) from SC-3000H computer */
FB_SEGAVDP = 0x0009 /* SN76489 clone in Sega's VDP chips (315-5124, 315-5246, 315-5313, Game Gear) */
};
enum volume_modes {
VOL_TRUNC = 0, /* Volume levels 13-15 are identical */
VOL_FULL = 1 /* Volume levels 13-15 are unique */
};
enum boost_modes {
BOOST_OFF = 0, /* Regular noise channel volume */
BOOST_ON = 1 /* Doubled noise channel volume */
};
enum mute_values {
MUTE_ALLOFF = 0, /* All channels muted */
MUTE_TONE1 = 1, /* Tone 1 mute control */
MUTE_TONE2 = 2, /* Tone 2 mute control */
MUTE_TONE3 = 4, /* Tone 3 mute control */
MUTE_NOISE = 8, /* Noise mute control */
MUTE_ALLON = 15 /* All channels enabled */
};
typedef struct
{
/* expose this for inspection/modification for channel muting */
int Mute;
int BoostNoise;
int VolumeArray;
/* Variables */
float Clock;
float dClock;
int PSGStereo;
int NumClocksForSample;
int WhiteNoiseFeedback;
/* PSG registers: */
UINT16 Registers[8]; /* Tone, vol x4 */
int LatchedRegister;
UINT16 NoiseShiftRegister;
INT16 NoiseFreq; /* Noise channel signal generator frequency */
/* Output calculation variables */
INT16 ToneFreqVals[4]; /* Frequency register values (counters) */
INT8 ToneFreqPos[4]; /* Frequency channel flip-flops */
INT16 Channels[4]; /* Value of each channel, before stereo is applied */
INT32 IntermediatePos[4]; /* intermediate values used at boundaries between + and - */
} SN76489_Context;
/* Function prototypes */
void SN76489_Init(int which, int PSGClockValue, int SamplingRate);
void SN76489_Reset(int which);
void SN76489_Shutdown(void);
void SN76489_Config(int which, int mute, int boost, int volume, int feedback);
void SN76489_SetContext(int which, uint8 *data);
void SN76489_GetContext(int which, uint8 *data);
uint8 *SN76489_GetContextPtr(int which);
int SN76489_GetContextSize(void);
void SN76489_Write(int which, int data);
void SN76489_GGStereoWrite(int which, int data);
void SN76489_Update(int which, INT16 **buffer, int length);
#endif /* _SN76489_H_ */