berzerk slight cleanup

This commit is contained in:
dinkc64 2019-06-09 00:13:33 -04:00
parent 06afaea53c
commit 89f2c2c3bc
4 changed files with 139 additions and 57 deletions

View File

@ -485,7 +485,7 @@ static void __fastcall berzerk_write(UINT16 address, UINT8 data)
} }
} }
// --- berzerk/exidy sound custom, code by Aaron Giles --- // --- berzerk/exidy sound custom, original code by Aaron Giles ---
#define CRYSTAL_OSC (3579545) #define CRYSTAL_OSC (3579545)
#define SH8253_CLOCK (CRYSTAL_OSC / 2) #define SH8253_CLOCK (CRYSTAL_OSC / 2)
#define SH6840_CLOCK (CRYSTAL_OSC / 4) #define SH6840_CLOCK (CRYSTAL_OSC / 4)
@ -523,13 +523,19 @@ static UINT32 sh6840_clock_count;
static UINT8 exidy_sfxctrl; static UINT8 exidy_sfxctrl;
static INT32 samples_from; // "re"sampler static UINT32 nSampleSize;
static INT32 samples_from; // samples per frame
static INT16 *mixer_buffer; static INT16 *mixer_buffer;
static INT32 nCurrentPosition;
static INT32 nFractionalPosition;
static void exidy_sound_init() static void exidy_sound_init()
{ {
samples_from = (INT32)((double)((SH8253_CLOCK * 100) / nBurnFPS) + 0.5); samples_from = (INT32)((double)((SH8253_CLOCK * 100) / nBurnFPS) + 0.5);
nSampleSize = (UINT64)SH8253_CLOCK * (1 << 16) / nBurnSoundRate;
mixer_buffer = (INT16*)BurnMalloc(2 * sizeof(INT16) * SH8253_CLOCK); mixer_buffer = (INT16*)BurnMalloc(2 * sizeof(INT16) * SH8253_CLOCK);
nCurrentPosition = 0;
nFractionalPosition = 0;
sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)SH8253_CLOCK * (double)(1 << 24)); sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)SH8253_CLOCK * (double)(1 << 24));
s14001a_init(DrvSndROM, ZetTotalCycles, 2500000); s14001a_init(DrvSndROM, ZetTotalCycles, 2500000);
@ -554,6 +560,7 @@ static void exidy_sound_scan()
} }
static void berzerk_sound_write(UINT8 offset, UINT8 data); //forward static void berzerk_sound_write(UINT8 offset, UINT8 data); //forward
static void exidy_sync_stream(); // forward
static void exidy_sound_reset() static void exidy_sound_reset()
{ {
@ -577,6 +584,8 @@ static void exidy_sound_reset()
static void exidy_sound_write(UINT8 offset, UINT8 data) static void exidy_sound_write(UINT8 offset, UINT8 data)
{ {
exidy_sync_stream();
switch (offset) switch (offset)
{ {
/* offset 0 writes to either channel 0 control or channel 2 control */ /* offset 0 writes to either channel 0 control or channel 2 control */
@ -605,7 +614,7 @@ static void exidy_sound_write(UINT8 offset, UINT8 data)
case 7: case 7:
{ {
/* latch the timer value */ /* latch the timer value */
int ch = (offset - 3) / 2; INT32 ch = (offset - 3) / 2;
sh6840_timer[ch].timer = (sh6840_MSB << 8) | (data & 0xff); sh6840_timer[ch].timer = (sh6840_MSB << 8) | (data & 0xff);
/* if CR4 is clear, the value is loaded immediately */ /* if CR4 is clear, the value is loaded immediately */
@ -618,6 +627,8 @@ static void exidy_sound_write(UINT8 offset, UINT8 data)
static void exidy_sfx_write(UINT8 offset, UINT8 data) static void exidy_sfx_write(UINT8 offset, UINT8 data)
{ {
exidy_sync_stream();
switch (offset) switch (offset)
{ {
case 0: case 0:
@ -632,7 +643,7 @@ static void exidy_sfx_write(UINT8 offset, UINT8 data)
} }
} }
static void sh6840_apply_clock(struct sh6840_timer_channel *t, int clocks) static void sh6840_apply_clock(struct sh6840_timer_channel *t, INT32 clocks)
{ {
/* dual 8-bit case */ /* dual 8-bit case */
if (t->cr & 0x04) if (t->cr & 0x04)
@ -679,22 +690,19 @@ static void sh6840_apply_clock(struct sh6840_timer_channel *t, int clocks)
} }
} }
/************************************* /*************************************
* *
* Noise generation helper * Noise generation helper
* *
*************************************/ *************************************/
static int sh6840_update_noise(int clocks) static INT32 sh6840_update_noise(INT32 clocks)
{ {
UINT32 newxor; UINT32 newxor;
int noise_clocks = 0; INT32 noise_clocks = 0;
int i;
/* loop over clocks */ /* loop over clocks */
for (i = 0; i < clocks; i++) for (INT32 i = 0; i < clocks; i++)
{ {
/* shift the LFSR. its a LOOOONG LFSR, so we need /* shift the LFSR. its a LOOOONG LFSR, so we need
* four longs to hold it all! * four longs to hold it all!
@ -729,16 +737,16 @@ static int sh6840_update_noise(int clocks)
* *
*************************************/ *************************************/
static void exidy_update(INT16 *buffer, int length) static void exidy_update(INT16 *buffer, INT32 length)
{ {
int noisy = ((sh6840_timer[0].cr & sh6840_timer[1].cr & sh6840_timer[2].cr & 0x02) == 0); INT32 noisy = ((sh6840_timer[0].cr & sh6840_timer[1].cr & sh6840_timer[2].cr & 0x02) == 0);
/* loop over samples */ /* loop over samples */
while (length--) while (length--)
{ {
struct sh6840_timer_channel *t; struct sh6840_timer_channel *t;
//struct sh8253_timer_channel *c; //struct sh8253_timer_channel *c;
int clocks_this_sample; INT32 clocks_this_sample;
INT16 sample = 0; INT16 sample = 0;
/* determine how many 6840 clocks this sample */ /* determine how many 6840 clocks this sample */
@ -749,7 +757,7 @@ static void exidy_update(INT16 *buffer, int length)
/* skip if nothing enabled */ /* skip if nothing enabled */
if ((sh6840_timer[0].cr & 0x01) == 0) if ((sh6840_timer[0].cr & 0x01) == 0)
{ {
int noise_clocks_this_sample = 0; INT32 noise_clocks_this_sample = 0;
UINT32 chan0_clocks; UINT32 chan0_clocks;
/* generate E-clocked noise if configured to do so */ /* generate E-clocked noise if configured to do so */
@ -761,7 +769,7 @@ static void exidy_update(INT16 *buffer, int length)
chan0_clocks = t->clocks; chan0_clocks = t->clocks;
if (t->cr & 0x80) if (t->cr & 0x80)
{ {
int clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample; INT32 clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample;
sh6840_apply_clock(t, clocks); sh6840_apply_clock(t, clocks);
if (t->state && !(exidy_sfxctrl & 0x02)) if (t->state && !(exidy_sfxctrl & 0x02))
sample += sh6840_volume[0]; sample += sh6840_volume[0];
@ -775,7 +783,7 @@ static void exidy_update(INT16 *buffer, int length)
t = &sh6840_timer[1]; t = &sh6840_timer[1];
if (t->cr & 0x80) if (t->cr & 0x80)
{ {
int clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample; INT32 clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample;
sh6840_apply_clock(t, clocks); sh6840_apply_clock(t, clocks);
if (t->state) if (t->state)
sample += sh6840_volume[1]; sample += sh6840_volume[1];
@ -785,7 +793,7 @@ static void exidy_update(INT16 *buffer, int length)
t = &sh6840_timer[2]; t = &sh6840_timer[2];
if (t->cr & 0x80) if (t->cr & 0x80)
{ {
int clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample; INT32 clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample;
/* prescale */ /* prescale */
if (t->cr & 0x01) if (t->cr & 0x01)
@ -805,23 +813,68 @@ static void exidy_update(INT16 *buffer, int length)
} }
} }
static void exidy_render(INT16 *buffer, int length) // Streambuffer handling
static INT32 SyncInternal()
{ {
INT32 samples = (samples_from * length) / nBurnSoundLen; return (INT32)(float)(samples_from * (ZetTotalCycles() / (2500000 / (nBurnFPS / 100.0000))));
}
exidy_update(mixer_buffer, samples); static void UpdateStream(INT32 length)
{
length -= nCurrentPosition;
if (length <= 0) return;
INT16 *mix = mixer_buffer; INT16 *mix = mixer_buffer + 5 + nCurrentPosition;
memset(mix, 0, length * sizeof(INT16));
exidy_update(mix, length);
nCurrentPosition += length;
}
for (INT32 j = 0; j < length; j++) static void exidy_sync_stream()
{ {
INT32 k = (samples_from * j) / nBurnSoundLen; UpdateStream(SyncInternal());
}
INT32 l = mix[k]; void exidy_render(INT16 *buffer, INT32 length)
INT32 r = mix[k]; {
buffer[0] = BURN_SND_CLIP(l); if (mixer_buffer == NULL || samples_from == 0) return;
buffer[1] = BURN_SND_CLIP(r);
buffer += 2; if (length != nBurnSoundLen) {
bprintf(0, _T("exidy_render(): once per frame, please!\n"));
return;
}
UpdateStream(samples_from);
INT16 *pBufL = mixer_buffer + 5;
for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < (length << 1); i += 2, nFractionalPosition += nSampleSize) {
INT32 nLeftSample[4] = {0, 0, 0, 0};
INT32 nTotalLeftSample; // it's mono!
nLeftSample[0] += (INT32)(pBufL[(nFractionalPosition >> 16) - 3]);
nLeftSample[1] += (INT32)(pBufL[(nFractionalPosition >> 16) - 2]);
nLeftSample[2] += (INT32)(pBufL[(nFractionalPosition >> 16) - 1]);
nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition >> 16) - 0]);
nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample * 0.45);
buffer[i + 0] = nTotalLeftSample;
buffer[i + 1] = nTotalLeftSample;
}
nCurrentPosition = 0;
if (length >= nBurnSoundLen) {
INT32 nExtraSamples = samples_from - (nFractionalPosition >> 16);
for (INT32 i = -4; i < nExtraSamples; i++) {
pBufL[i] = pBufL[(nFractionalPosition >> 16) + i];
}
nFractionalPosition &= 0xFFFF;
nCurrentPosition = nExtraSamples;
} }
} }
@ -995,6 +1048,7 @@ static INT32 DrvDoReset()
// sound // sound
exidy_sound_reset(); exidy_sound_reset();
s14001a_reset();
magicram_control = 0xff; magicram_control = 0xff;
magicram_latch = 0xff; magicram_latch = 0xff;
@ -1265,6 +1319,7 @@ static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
ZetScan(nAction); ZetScan(nAction);
exidy_sound_scan(); exidy_sound_scan();
s14001a_scan(nAction, pnMin);
SCAN_VAR(magicram_control); SCAN_VAR(magicram_control);
SCAN_VAR(magicram_latch); SCAN_VAR(magicram_latch);

View File

@ -132,6 +132,7 @@
* *
*/ */
#include <stddef.h>
#include "burnint.h" #include "burnint.h"
#include "s14001a.h" #include "s14001a.h"
@ -155,9 +156,11 @@ typedef struct
UINT8 OldDelta; // 2-bit old delta value UINT8 OldDelta; // 2-bit old delta value
UINT8 DACOutput; // 4-bit DAC Accumulator/output UINT8 DACOutput; // 4-bit DAC Accumulator/output
UINT8 audioout; // filtered audio output UINT8 audioout; // filtered audio output
UINT8 *SpeechRom; // array to hold rom contents, mame will not need this, will use a pointer
INT16 filtervals[8]; INT16 filtervals[8];
UINT8 VSU1000_amp; // amplitude setting on VSU-1000 board UINT8 VSU1000_amp; // amplitude setting on VSU-1000 board
INT32 clock; // for savestates, to restore the clock
UINT8 *SpeechRom; // array to hold rom contents, mame will not need this, will use a pointer
} S14001AChip; } S14001AChip;
static S14001AChip *our_chip = NULL; static S14001AChip *our_chip = NULL;
@ -166,12 +169,12 @@ static S14001AChip *our_chip = NULL;
static UINT32 nSampleSize; static UINT32 nSampleSize;
static INT32 nFractionalPosition; static INT32 nFractionalPosition;
static INT32 samples_from; // "re"sampler static INT32 samples_from; // (samples per frame)
static INT16 *mixer_buffer; static INT16 *mixer_buffer;
static INT32 (*pCPUTotalCycles)() = NULL; static INT32 (*pCPUTotalCycles)() = NULL;
static UINT32 nDACCPUMHZ = 0; static UINT32 nDACCPUMHZ = 0;
static INT32 nCurrentPosition = 0; static INT32 nCurrentPosition;
//#define DEBUGSTATE //#define DEBUGSTATE
@ -442,14 +445,15 @@ static void s14001a_clock(S14001AChip *chip) /* called once per clock */
} }
} }
static void s14001a_pcm_update(INT16 *buffer, int length) static void s14001a_pcm_update(INT16 *buffer, INT32 length)
{ {
S14001AChip *chip = our_chip; S14001AChip *chip = our_chip;
for (int i = 0; i < length; i++) for (INT32 i = 0; i < length; i++)
{ {
s14001a_clock(chip); s14001a_clock(chip);
#if 0 #if 0
// this block introduces a nasty "whine" into the stream.
if (chip->audioout == ALTFLAG) // input from test pins -> output if (chip->audioout == ALTFLAG) // input from test pins -> output
{ {
shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout. shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
@ -508,7 +512,7 @@ void s14001a_render(INT16 *buffer, INT32 length)
nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition >> 16) - 0]); nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition >> 16) - 0]);
nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]); nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample * 0.30); nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample * 0.75);
buffer[i + 0] = BURN_SND_CLIP(buffer[i + 0] + nTotalLeftSample); buffer[i + 0] = BURN_SND_CLIP(buffer[i + 0] + nTotalLeftSample);
buffer[i + 1] = BURN_SND_CLIP(buffer[i + 1] + nTotalLeftSample); buffer[i + 1] = BURN_SND_CLIP(buffer[i + 1] + nTotalLeftSample);
@ -528,23 +532,28 @@ void s14001a_render(INT16 *buffer, INT32 length)
} }
} }
void s14001a_reset()
{
our_chip->GlobalSilenceState = 1;
our_chip->OldDelta = 0x02;
our_chip->DACOutput = SILENCE;
our_chip->machineState = 0;
our_chip->resetState = 0;
for (INT32 i = 0; i < 8; i++)
{
our_chip->filtervals[i] = SILENCE;
}
}
void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ) void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
{ {
S14001AChip *chip; S14001AChip *chip;
int i;
our_chip = chip = (S14001AChip*)BurnMalloc(sizeof(S14001AChip)); our_chip = chip = (S14001AChip*)BurnMalloc(sizeof(S14001AChip));
memset(chip, 0, sizeof(S14001AChip)); memset(chip, 0, sizeof(S14001AChip));
chip->GlobalSilenceState = 1; s14001a_reset();
chip->OldDelta = 0x02;
chip->DACOutput = SILENCE;
for (i = 0; i < 8; i++)
{
chip->filtervals[i] = SILENCE;
}
chip->SpeechRom = rom; chip->SpeechRom = rom;
pCPUTotalCycles = pCPUCyclesCB; pCPUTotalCycles = pCPUCyclesCB;
@ -552,6 +561,9 @@ void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
mixer_buffer = (INT16*)BurnMalloc(2 * sizeof(INT16) * 200000); // should be enough? mixer_buffer = (INT16*)BurnMalloc(2 * sizeof(INT16) * 200000); // should be enough?
nCurrentPosition = 0;
nFractionalPosition = 0;
s14001a_set_clock(nBurnSoundRate); s14001a_set_clock(nBurnSoundRate);
} }
@ -561,19 +573,28 @@ void s14001a_exit()
BurnFree(our_chip); BurnFree(our_chip);
} }
int s14001a_bsy_read() void s14001a_scan(INT32 nAction, INT32 *pnMin)
{
ScanVar(our_chip, STRUCT_SIZE_HELPER(S14001AChip, clock), "s14001a SpeechSynth Chip");
if (nAction & ACB_WRITE) {
s14001a_set_clock(our_chip->clock);
}
}
INT32 s14001a_bsy_read()
{ {
UpdateStream(SyncInternal()); UpdateStream(SyncInternal());
return (our_chip->machineState != 0); return (our_chip->machineState != 0);
} }
void s14001a_reg_write(int data) void s14001a_reg_write(INT32 data)
{ {
UpdateStream(SyncInternal()); UpdateStream(SyncInternal());
our_chip->WordInput = data; our_chip->WordInput = data;
} }
void s14001a_rst_write(int data) void s14001a_rst_write(INT32 data)
{ {
UpdateStream(SyncInternal()); UpdateStream(SyncInternal());
our_chip->LatchedWord = our_chip->WordInput; our_chip->LatchedWord = our_chip->WordInput;
@ -581,14 +602,15 @@ void s14001a_rst_write(int data)
our_chip->machineState = our_chip->resetState ? 1 : our_chip->machineState; our_chip->machineState = our_chip->resetState ? 1 : our_chip->machineState;
} }
void s14001a_set_clock(int clock) void s14001a_set_clock(INT32 clock)
{ {
samples_from = (INT32)((double)((clock * 100) / nBurnFPS) + 0.5); our_chip->clock = clock;
samples_from = (INT32)((double)((clock * 100) / nBurnFPS) + 0.5);
nSampleSize = (UINT32)clock * (1 << 16) / nBurnSoundRate; nSampleSize = (UINT32)clock * (1 << 16) / nBurnSoundRate;
} }
void s14001a_set_volume(int volume) void s14001a_set_volume(INT32 volume)
{ {
our_chip->VSU1000_amp = volume; our_chip->VSU1000_amp = volume;
} }

View File

@ -1,9 +1,11 @@
void s14001a_render(INT16 *buffer, INT32 length); void s14001a_render(INT16 *buffer, INT32 length);
void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ); void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ);
void s14001a_exit(); void s14001a_exit();
int s14001a_bsy_read(); void s14001a_reset();
void s14001a_reg_write(int data); void s14001a_scan(INT32 nAction, INT32 *pnMin);
void s14001a_rst_write(int data); INT32 s14001a_bsy_read();
void s14001a_set_clock(int clock); void s14001a_reg_write(INT32 data);
void s14001a_set_volume(int volume); void s14001a_rst_write(INT32 data);
void s14001a_set_clock(INT32 clock);
void s14001a_set_volume(INT32 volume);

View File

@ -1529,7 +1529,10 @@ static void tms5220_init_int(INT32 chipvariant)
tms5220_volume(1.00); tms5220_volume(1.00);
soundbuf = (INT16*)BurnMalloc(0x1000); soundbuf = (INT16*)BurnMalloc(0x1000);
nPosition = 0;
nFractionalPosition = 0;
} }
void tms5200_init() void tms5200_init()