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 SH8253_CLOCK (CRYSTAL_OSC / 2)
#define SH6840_CLOCK (CRYSTAL_OSC / 4)
@ -523,13 +523,19 @@ static UINT32 sh6840_clock_count;
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 INT32 nCurrentPosition;
static INT32 nFractionalPosition;
static void exidy_sound_init()
{
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);
nCurrentPosition = 0;
nFractionalPosition = 0;
sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)SH8253_CLOCK * (double)(1 << 24));
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 exidy_sync_stream(); // forward
static void exidy_sound_reset()
{
@ -577,6 +584,8 @@ static void exidy_sound_reset()
static void exidy_sound_write(UINT8 offset, UINT8 data)
{
exidy_sync_stream();
switch (offset)
{
/* 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:
{
/* latch the timer value */
int ch = (offset - 3) / 2;
INT32 ch = (offset - 3) / 2;
sh6840_timer[ch].timer = (sh6840_MSB << 8) | (data & 0xff);
/* 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)
{
exidy_sync_stream();
switch (offset)
{
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 */
if (t->cr & 0x04)
@ -679,22 +690,19 @@ static void sh6840_apply_clock(struct sh6840_timer_channel *t, int clocks)
}
}
/*************************************
*
* Noise generation helper
*
*************************************/
static int sh6840_update_noise(int clocks)
static INT32 sh6840_update_noise(INT32 clocks)
{
UINT32 newxor;
int noise_clocks = 0;
int i;
INT32 noise_clocks = 0;
/* 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
* 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 */
while (length--)
{
struct sh6840_timer_channel *t;
//struct sh8253_timer_channel *c;
int clocks_this_sample;
INT32 clocks_this_sample;
INT16 sample = 0;
/* determine how many 6840 clocks this sample */
@ -749,7 +757,7 @@ static void exidy_update(INT16 *buffer, int length)
/* skip if nothing enabled */
if ((sh6840_timer[0].cr & 0x01) == 0)
{
int noise_clocks_this_sample = 0;
INT32 noise_clocks_this_sample = 0;
UINT32 chan0_clocks;
/* 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;
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);
if (t->state && !(exidy_sfxctrl & 0x02))
sample += sh6840_volume[0];
@ -775,7 +783,7 @@ static void exidy_update(INT16 *buffer, int length)
t = &sh6840_timer[1];
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);
if (t->state)
sample += sh6840_volume[1];
@ -785,7 +793,7 @@ static void exidy_update(INT16 *buffer, int length)
t = &sh6840_timer[2];
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 */
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++)
{
INT32 k = (samples_from * j) / nBurnSoundLen;
static void exidy_sync_stream()
{
UpdateStream(SyncInternal());
}
INT32 l = mix[k];
INT32 r = mix[k];
buffer[0] = BURN_SND_CLIP(l);
buffer[1] = BURN_SND_CLIP(r);
buffer += 2;
void exidy_render(INT16 *buffer, INT32 length)
{
if (mixer_buffer == NULL || samples_from == 0) return;
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
exidy_sound_reset();
s14001a_reset();
magicram_control = 0xff;
magicram_latch = 0xff;
@ -1265,6 +1319,7 @@ static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
ZetScan(nAction);
exidy_sound_scan();
s14001a_scan(nAction, pnMin);
SCAN_VAR(magicram_control);
SCAN_VAR(magicram_latch);

View File

@ -132,6 +132,7 @@
*
*/
#include <stddef.h>
#include "burnint.h"
#include "s14001a.h"
@ -155,9 +156,11 @@ typedef struct
UINT8 OldDelta; // 2-bit old delta value
UINT8 DACOutput; // 4-bit DAC Accumulator/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];
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;
static S14001AChip *our_chip = NULL;
@ -166,12 +169,12 @@ static S14001AChip *our_chip = NULL;
static UINT32 nSampleSize;
static INT32 nFractionalPosition;
static INT32 samples_from; // "re"sampler
static INT32 samples_from; // (samples per frame)
static INT16 *mixer_buffer;
static INT32 (*pCPUTotalCycles)() = NULL;
static UINT32 nDACCPUMHZ = 0;
static INT32 nCurrentPosition = 0;
static INT32 nCurrentPosition;
//#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;
for (int i = 0; i < length; i++)
for (INT32 i = 0; i < length; i++)
{
s14001a_clock(chip);
#if 0
// this block introduces a nasty "whine" into the stream.
if (chip->audioout == ALTFLAG) // input from test pins -> output
{
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]);
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 + 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)
{
S14001AChip *chip;
int i;
our_chip = chip = (S14001AChip*)BurnMalloc(sizeof(S14001AChip));
memset(chip, 0, sizeof(S14001AChip));
chip->GlobalSilenceState = 1;
chip->OldDelta = 0x02;
chip->DACOutput = SILENCE;
for (i = 0; i < 8; i++)
{
chip->filtervals[i] = SILENCE;
}
s14001a_reset();
chip->SpeechRom = rom;
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?
nCurrentPosition = 0;
nFractionalPosition = 0;
s14001a_set_clock(nBurnSoundRate);
}
@ -561,19 +573,28 @@ void s14001a_exit()
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());
return (our_chip->machineState != 0);
}
void s14001a_reg_write(int data)
void s14001a_reg_write(INT32 data)
{
UpdateStream(SyncInternal());
our_chip->WordInput = data;
}
void s14001a_rst_write(int data)
void s14001a_rst_write(INT32 data)
{
UpdateStream(SyncInternal());
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;
}
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;
}
void s14001a_set_volume(int volume)
void s14001a_set_volume(INT32 volume)
{
our_chip->VSU1000_amp = volume;
}

View File

@ -1,9 +1,11 @@
void s14001a_render(INT16 *buffer, INT32 length);
void s14001a_init(UINT8 *rom, INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ);
void s14001a_exit();
int s14001a_bsy_read();
void s14001a_reg_write(int data);
void s14001a_rst_write(int data);
void s14001a_set_clock(int clock);
void s14001a_set_volume(int volume);
void s14001a_reset();
void s14001a_scan(INT32 nAction, INT32 *pnMin);
INT32 s14001a_bsy_read();
void s14001a_reg_write(INT32 data);
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);
soundbuf = (INT16*)BurnMalloc(0x1000);
soundbuf = (INT16*)BurnMalloc(0x1000);
nPosition = 0;
nFractionalPosition = 0;
}
void tms5200_init()