mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-26 00:29:27 +00:00
Beginnings of Mockingboard tracing for automated testing
This commit is contained in:
parent
5883545390
commit
8921f79a14
|
@ -132,7 +132,7 @@ EXTRA_testprefs_SOURCES = $(ASM_SRC_x86) $(VIDEO_SRC) $(AUDIO_SRC) $(META_SRC)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
testtrace_SOURCES = src/test/testtrace.c $(A2_TEST_SOURCES)
|
testtrace_SOURCES = src/test/testtrace.c $(A2_TEST_SOURCES)
|
||||||
testtrace_CFLAGS = $(A2_TEST_CFLAGS) -DTEST_TRACE=1 -DCPU_TRACING=1 -DDISK_TRACING=1 -DVM_TRACING=1 -DSPEAKER_TRACING=1
|
testtrace_CFLAGS = $(A2_TEST_CFLAGS) -DTEST_TRACE=1 -DCPU_TRACING=1 -DDISK_TRACING=1 -DVM_TRACING=1 -DSPEAKER_TRACING=1 -DMB_TRACING=1
|
||||||
testtrace_CCASFLAGS = $(testtrace_CFLAGS)
|
testtrace_CCASFLAGS = $(testtrace_CFLAGS)
|
||||||
testtrace_LDFLAGS = $(apple2ix_LDFLAGS)
|
testtrace_LDFLAGS = $(apple2ix_LDFLAGS)
|
||||||
testtrace_LDADD = @testtrace_ASM_O@ @testtrace_VIDEO_O@ @testtrace_AUDIO_O@ @testtrace_META_O@ @X_LIBS@
|
testtrace_LDADD = @testtrace_ASM_O@ @testtrace_VIDEO_O@ @testtrace_AUDIO_O@ @testtrace_META_O@ @X_LIBS@
|
||||||
|
|
|
@ -1047,6 +1047,7 @@ void CAY8910::SaveSnapshot(YamlSaveHelper& yamlSaveHelper, std::string& suffix)
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]);
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]);
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_PERIOD, ay_noise_period);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_PERIOD, ay_noise_period);
|
||||||
|
// APPLE2IX FIXME WHAT ABOUT : SS_YAML_KEY_ENV_PERIOD "Env Period" ... AppleWin forgot about this? Also do this on load ...
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_RNG, rng);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_RNG, rng);
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TOGGLE, noise_toggle);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TOGGLE, noise_toggle);
|
||||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_FIRST, env_first);
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_FIRST, env_first);
|
||||||
|
@ -1184,6 +1185,36 @@ static uint64_t g_uLastCumulativeCycles = 0;
|
||||||
static unsigned __int64 g_uLastCumulativeCycles = 0;
|
static unsigned __int64 g_uLastCumulativeCycles = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
void _mb_trace_AY8910(int chip, FILE *mb_trace_fp) {
|
||||||
|
if (!mb_trace_fp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(chip < MAX_8910);
|
||||||
|
CAY8910 *_this = &g_AY8910[chip];
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\tAY8910(%d):\n", chip);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_tone_tick:%u,%u,%u\n", _this->ay_tone_tick[0], _this->ay_tone_tick[1], _this->ay_tone_tick[2]);
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_tone_high:%u,%u,%u\n", _this->ay_tone_high[0], _this->ay_tone_high[1], _this->ay_tone_high[2]);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_noise_tick:%u ay_tone_subcycles:%u ay_env_subcycles:%u\n", _this->ay_noise_tick, _this->ay_tone_subcycles, _this->ay_env_subcycles);
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_env_internal_tick:%u ay_env_tick:%u ay_tick_incr:%u\n", _this->ay_env_internal_tick, _this->ay_env_tick, _this->ay_tick_incr);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_tone_period:%u,%u,%u\n", _this->ay_tone_period[0], _this->ay_tone_period[1], _this->ay_tone_period[2]);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_noise_period:%u ay_env_period:%u rng:%d noise_toggle:%d\n", _this->ay_noise_period, _this->ay_env_period, _this->rng, _this->noise_toggle);
|
||||||
|
fprintf(mb_trace_fp, "\t\tenv_first:%d env_rev:%d env_counter:%d\n", _this->env_first, _this->env_rev, _this->env_counter);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tenv_first:%d env_rev:%d env_counter:%d\n", _this->env_first, _this->env_rev, _this->env_counter);
|
||||||
|
fprintf(mb_trace_fp, "\t\tsound_ay_registers: %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\n", _this->sound_ay_registers[0], _this->sound_ay_registers[1], _this->sound_ay_registers[2], _this->sound_ay_registers[3], _this->sound_ay_registers[4], _this->sound_ay_registers[5], _this->sound_ay_registers[6], _this->sound_ay_registers[7], _this->sound_ay_registers[8], _this->sound_ay_registers[9], _this->sound_ay_registers[10], _this->sound_ay_registers[11], _this->sound_ay_registers[12], _this->sound_ay_registers[13], _this->sound_ay_registers[14], _this->sound_ay_registers[15]);
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\t\tay_change_count:(%d)\n", _this->ay_change_count);
|
||||||
|
for (unsigned int i=0; i<_this->ay_change_count; i++) {
|
||||||
|
fprintf(mb_trace_fp, "\t\t\t%u: tstates:%lu ofs:%04X reg:%02X val:%02X\n", i, _this->ay_change[i].tstates, _this->ay_change[i].ofs, _this->ay_change[i].reg, _this->ay_change[i].val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void _AYWriteReg(int chip, int r, int v)
|
void _AYWriteReg(int chip, int r, int v)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,9 @@ void AY8910UpdateSetCycles();
|
||||||
UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix);
|
UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix);
|
||||||
UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix);
|
UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix);
|
||||||
#endif
|
#endif
|
||||||
|
#if MB_TRACING
|
||||||
|
void _mb_trace_AY8910(int chip, FILE *mb_trace_fp);
|
||||||
|
#endif
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// FUSE stuff
|
// FUSE stuff
|
||||||
|
|
|
@ -19,7 +19,7 @@ Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
AppleWin is free software; you can redistribute it and/or modify
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
AppleWin is distributed in the hope that it will be useful,
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
@ -258,6 +258,13 @@ static short g_nMixBuffer[g_dwDSBufferSize / sizeof(short)];
|
||||||
|
|
||||||
|
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
|
# if MB_TRACING
|
||||||
|
static FILE *mb_trace_fp = NULL;
|
||||||
|
static FILE *mb_trace_samples_fp = NULL;
|
||||||
|
static unsigned long cycles_mb_toggled_r = 0;
|
||||||
|
static unsigned long cycles_mb_toggled_w = 0;
|
||||||
|
# endif
|
||||||
|
|
||||||
static AudioBuffer_s *MockingboardVoice = NULL;
|
static AudioBuffer_s *MockingboardVoice = NULL;
|
||||||
static AudioBuffer_s *SSI263Voice[64] = { 0 };
|
static AudioBuffer_s *SSI263Voice[64] = { 0 };
|
||||||
static pthread_cond_t ssi263_cond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t ssi263_cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
@ -361,6 +368,9 @@ static void AY8910_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue, uint8_t
|
||||||
{
|
{
|
||||||
// RESET: Reset AY8910 only
|
// RESET: Reset AY8910 only
|
||||||
AY8910_reset(nDevice+2*nAYDevice);
|
AY8910_reset(nDevice+2*nAYDevice);
|
||||||
|
#if MB_TRACING
|
||||||
|
_mb_trace_AY8910(nDevice+2*nAYDevice, mb_trace_fp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -382,6 +392,9 @@ static void AY8910_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue, uint8_t
|
||||||
|
|
||||||
case AY_WRITE: // 6: WRITE TO PSG
|
case AY_WRITE: // 6: WRITE TO PSG
|
||||||
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
||||||
|
#if MB_TRACING
|
||||||
|
_mb_trace_AY8910(nDevice+2*nAYDevice, mb_trace_fp);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AY_LATCH: // 7: LATCH ADDRESS
|
case AY_LATCH: // 7: LATCH ADDRESS
|
||||||
|
@ -393,6 +406,10 @@ static void AY8910_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue, uint8_t
|
||||||
pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F;
|
pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F;
|
||||||
// else Pro-Mockingboard (clone from HK)
|
// else Pro-Mockingboard (clone from HK)
|
||||||
break;
|
break;
|
||||||
|
#if 1 // APPLE2IX
|
||||||
|
default:
|
||||||
|
mb_assert(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,6 +436,11 @@ static void UpdateIFR(SY6522_AY8910* pMB)
|
||||||
if (bIRQ)
|
if (bIRQ)
|
||||||
{
|
{
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\t%s\n", "IRQ_6522");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
cpu65_interrupt(IS_6522);
|
cpu65_interrupt(IS_6522);
|
||||||
#else
|
#else
|
||||||
CpuIrqAssert(IS_6522);
|
CpuIrqAssert(IS_6522);
|
||||||
|
@ -427,6 +449,11 @@ static void UpdateIFR(SY6522_AY8910* pMB)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\t%s\n", "!IRQ_6522");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
cpu65_uninterrupt(IS_6522);
|
cpu65_uninterrupt(IS_6522);
|
||||||
#else
|
#else
|
||||||
CpuIrqDeassert(IS_6522);
|
CpuIrqDeassert(IS_6522);
|
||||||
|
@ -434,8 +461,44 @@ static void UpdateIFR(SY6522_AY8910* pMB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
static void _mb_traceWriteSample(INOUT char **tracingBufPtr, INOUT size_t *tracingBufSize, const char *samPrefix, int dat) {
|
||||||
|
int sz = INT_MAX;
|
||||||
|
|
||||||
|
char *buf = *tracingBufPtr;
|
||||||
|
int max = (int)*tracingBufSize;
|
||||||
|
|
||||||
|
sz = snprintf(buf, max, "%s[%08x]", samPrefix, dat);
|
||||||
|
assert(sz > 0 && sz < max);
|
||||||
|
buf += sz;
|
||||||
|
max -= sz;
|
||||||
|
assert(max >= 0);
|
||||||
|
|
||||||
|
*tracingBufPtr = buf;
|
||||||
|
*tracingBufSize = (size_t)max;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _mb_traceSY6522_AY8910(uint8_t nDevice) {
|
||||||
|
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||||
|
|
||||||
|
fprintf(mb_trace_fp, "\tSYS6522_AY8910(%d) nAY8910Number:%02X nAYCurrentRegister:%02X nTimerStatus:%02X\n", nDevice, pMB->nAY8910Number, pMB->nAYCurrentRegister, pMB->nTimerStatus);
|
||||||
|
|
||||||
|
SY6522 *sy6522 = &pMB->sy6522;
|
||||||
|
fprintf(mb_trace_fp, "\t\tSYS6522 : ORB:%02X ORA:%02X DDRB:%02X DDRA:%02X TIMER1_COUNTER:%04X TIMER1_LATCH:%04X TIMER2_COUNTER:%04X TIMER2_LATCH:%04X SERIAL_SHIFT:%02X ACR:%02X PCR:%02X IFR:%02X IER:%02X ORA_NO_HS:%02X\n", sy6522->ORB, sy6522->ORA, sy6522->DDRB, sy6522->DDRA, sy6522->TIMER1_COUNTER.w, sy6522->TIMER1_LATCH.w, sy6522->TIMER2_COUNTER.w, sy6522->TIMER2_LATCH.w, sy6522->SERIAL_SHIFT, sy6522->ACR, sy6522->PCR, sy6522->IFR, sy6522->IER, sy6522->ORA_NO_HS);
|
||||||
|
|
||||||
|
#if 0 // ENABLE_SSI263
|
||||||
|
TODO FIXME : trace SSI263 stuff
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void SY6522_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue)
|
static void SY6522_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue)
|
||||||
{
|
{
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\tSY6522_Write(%02X, %02X, %02X)...\n", nDevice, nReg, nValue);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
g_bMB_Active = true;
|
g_bMB_Active = true;
|
||||||
|
|
||||||
SY6522_AY8910* pMB = &g_MB[nDevice];
|
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||||
|
@ -563,12 +626,23 @@ static void SY6522_Write(uint8_t nDevice, uint8_t nReg, uint8_t nValue)
|
||||||
case 0x0f: // ORA_NO_HS
|
case 0x0f: // ORA_NO_HS
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
_mb_traceSY6522_AY8910(nDevice);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static uint8_t SY6522_Read(uint8_t nDevice, uint8_t nReg)
|
static uint8_t SY6522_Read(uint8_t nDevice, uint8_t nReg)
|
||||||
{
|
{
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\tSY6522_Read(%02X, %02X)...\n", nDevice, nReg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// g_bMB_RegAccessedFlag = true;
|
// g_bMB_RegAccessedFlag = true;
|
||||||
g_bMB_Active = true;
|
g_bMB_Active = true;
|
||||||
|
|
||||||
|
@ -630,6 +704,13 @@ static uint8_t SY6522_Read(uint8_t nDevice, uint8_t nReg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
_mb_traceSY6522_AY8910(nDevice);
|
||||||
|
fprintf(mb_trace_fp, "\tret:%02X\n", nValue);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return nValue;
|
return nValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,6 +946,11 @@ static void MB_Update()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
# if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "%s", "\tMB_Update()\n");
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
char szDbg[200];
|
char szDbg[200];
|
||||||
|
|
||||||
|
@ -874,6 +960,7 @@ static void MB_Update()
|
||||||
|
|
||||||
if (g_bFullSpeed)
|
if (g_bFullSpeed)
|
||||||
{
|
{
|
||||||
|
#if !MB_TRACING
|
||||||
// Keep AY reg writes relative to the current 'frame'
|
// Keep AY reg writes relative to the current 'frame'
|
||||||
// - Required for Ultima3:
|
// - Required for Ultima3:
|
||||||
// . Tune ends
|
// . Tune ends
|
||||||
|
@ -886,6 +973,7 @@ static void MB_Update()
|
||||||
// If any AY regs have changed then push them out to the AY chip
|
// If any AY regs have changed then push them out to the AY chip
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1016,26 +1104,65 @@ static void MB_Update()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "%s", "\tsubmitting samples...\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const double fAttenuation = g_bPhasorEnable ? 2.0/3.0 : 1.0;
|
const double fAttenuation = g_bPhasorEnable ? 2.0/3.0 : 1.0;
|
||||||
|
|
||||||
for(int i=0; i<nNumSamples; i++)
|
for(int i=0; i<nNumSamples; i++)
|
||||||
{
|
{
|
||||||
|
#if MB_TRACING
|
||||||
|
# define TRACING_BUF_SIZ 1024
|
||||||
|
size_t tracingBufLSize = TRACING_BUF_SIZ;
|
||||||
|
size_t tracingBufRSize = TRACING_BUF_SIZ;
|
||||||
|
char tracingBufL[TRACING_BUF_SIZ];
|
||||||
|
char *tracingBufLPtr = tracingBufL;
|
||||||
|
char tracingBufR[TRACING_BUF_SIZ];
|
||||||
|
char *tracingBufRPtr = tracingBufR;
|
||||||
|
#endif
|
||||||
// Mockingboard stereo (all voices on an AY8910 wire-or'ed together)
|
// Mockingboard stereo (all voices on an AY8910 wire-or'ed together)
|
||||||
// L = Address.b7=0, R = Address.b7=1
|
// L = Address.b7=0, R = Address.b7=1
|
||||||
int nDataL = 0, nDataR = 0;
|
int nDataL = 0, nDataR = 0;
|
||||||
|
|
||||||
for(unsigned int j=0; j<NUM_VOICES_PER_AY8910; j++)
|
for(unsigned int j=0; j<NUM_VOICES_PER_AY8910; j++)
|
||||||
{
|
{
|
||||||
|
int datL, datR;
|
||||||
|
|
||||||
// Slot4
|
// Slot4
|
||||||
nDataL += (int) ((double)ppAYVoiceBuffer[0*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
datL = (int) ((double)ppAYVoiceBuffer[0*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
||||||
nDataR += (int) ((double)ppAYVoiceBuffer[1*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
datR = (int) ((double)ppAYVoiceBuffer[1*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
_mb_traceWriteSample(&tracingBufLPtr, &tracingBufLSize, "+4", datL);
|
||||||
|
_mb_traceWriteSample(&tracingBufRPtr, &tracingBufRSize, "+4", datR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
nDataL += datL;
|
||||||
|
nDataR += datR;
|
||||||
|
|
||||||
// Slot5
|
// Slot5
|
||||||
nDataL += (int) ((double)ppAYVoiceBuffer[2*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
datL = (int) ((double)ppAYVoiceBuffer[2*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
||||||
nDataR += (int) ((double)ppAYVoiceBuffer[3*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
datR = (int) ((double)ppAYVoiceBuffer[3*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
_mb_traceWriteSample(&tracingBufLPtr, &tracingBufLSize, "+5", datL);
|
||||||
|
_mb_traceWriteSample(&tracingBufRPtr, &tracingBufRSize, "+5", datR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
nDataL += datL;
|
||||||
|
nDataR += datR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
_mb_traceWriteSample(&tracingBufLPtr, &tracingBufLSize, "==", nDataL);
|
||||||
|
_mb_traceWriteSample(&tracingBufRPtr, &tracingBufRSize, "==", nDataR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Cap the superpositioned output
|
// Cap the superpositioned output
|
||||||
if(nDataL < nWaveDataMin)
|
if(nDataL < nWaveDataMin)
|
||||||
nDataL = nWaveDataMin;
|
nDataL = nWaveDataMin;
|
||||||
|
@ -1047,6 +1174,14 @@ static void MB_Update()
|
||||||
else if(nDataR > nWaveDataMax)
|
else if(nDataR > nWaveDataMax)
|
||||||
nDataR = nWaveDataMax;
|
nDataR = nWaveDataMax;
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
_mb_traceWriteSample(&tracingBufLPtr, &tracingBufLSize, "=>", nDataL);
|
||||||
|
_mb_traceWriteSample(&tracingBufRPtr, &tracingBufRSize, "=>", nDataR);
|
||||||
|
fprintf(mb_trace_samples_fp, "L:%s\nR:%s\n", tracingBufL, tracingBufR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
g_nMixBuffer[i*g_nMB_NumChannels+0] = (short)nDataL * samplesScale; // L
|
g_nMixBuffer[i*g_nMB_NumChannels+0] = (short)nDataL * samplesScale; // L
|
||||||
g_nMixBuffer[i*g_nMB_NumChannels+1] = (short)nDataR * samplesScale; // R
|
g_nMixBuffer[i*g_nMB_NumChannels+1] = (short)nDataR * samplesScale; // R
|
||||||
}
|
}
|
||||||
|
@ -1080,6 +1215,9 @@ static void MB_Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// make at least 2 attempts to submit data (could be at a ringBuffer boundary)
|
// make at least 2 attempts to submit data (could be at a ringBuffer boundary)
|
||||||
|
# if MB_TRACING
|
||||||
|
if (!g_bFullSpeed) {
|
||||||
|
# endif
|
||||||
do {
|
do {
|
||||||
if (MockingboardVoice->Lock(MockingboardVoice, requestedBufSize, &pDSLockedBuffer0, &dwDSLockedBufferSize0)) {
|
if (MockingboardVoice->Lock(MockingboardVoice, requestedBufSize, &pDSLockedBuffer0, &dwDSLockedBufferSize0)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1097,6 +1235,9 @@ static void MB_Update()
|
||||||
++counter;
|
++counter;
|
||||||
} while (bufIdx < originalRequestedBufSize && counter < 2);
|
} while (bufIdx < originalRequestedBufSize && counter < 2);
|
||||||
assert(bufIdx == originalRequestedBufSize);
|
assert(bufIdx == originalRequestedBufSize);
|
||||||
|
# if MB_TRACING
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RIFF_MB
|
#ifdef RIFF_MB
|
||||||
|
@ -1848,6 +1989,12 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
|
# if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
unsigned long uCycles = cycles_count_total - g_uLastCumulativeCycles;
|
||||||
|
fprintf(mb_trace_fp, "MB_Read|%04X|%lu\n", ea, uCycles);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
MB_UpdateCycles();
|
MB_UpdateCycles();
|
||||||
#else
|
#else
|
||||||
MB_UpdateCycles(nCyclesLeft);
|
MB_UpdateCycles(nCyclesLeft);
|
||||||
|
@ -1922,11 +2069,23 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO
|
||||||
#else
|
#else
|
||||||
mb_assert(false);
|
mb_assert(false);
|
||||||
#endif
|
#endif
|
||||||
else
|
|
||||||
#if 1 // APPLE2IX
|
#if MB_TRACING
|
||||||
return MemReadFloatingBus();
|
# if 1 // APPLE2IX
|
||||||
|
uint8_t b = MemReadFloatingBus();
|
||||||
|
# else
|
||||||
|
BYTE b = MemReadFloatingBus(nCyclesLeft);
|
||||||
|
# endif
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\tfall through ret:%02X\n", b);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
#else
|
#else
|
||||||
|
# if 1 // APPLE2IX
|
||||||
|
return MemReadFloatingBus();
|
||||||
|
# else
|
||||||
return MemReadFloatingBus(nCyclesLeft);
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1940,6 +2099,13 @@ static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
|
# if MB_TRACING
|
||||||
|
// output cycle count delta when toggled
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
unsigned long uCycles = cycles_count_total - g_uLastCumulativeCycles;
|
||||||
|
fprintf(mb_trace_fp, "MB_Write|%04X|%02X|%lu\n", ea, b, uCycles);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
MB_UpdateCycles();
|
MB_UpdateCycles();
|
||||||
#else
|
#else
|
||||||
MB_UpdateCycles(nCyclesLeft);
|
MB_UpdateCycles(nCyclesLeft);
|
||||||
|
@ -2150,6 +2316,11 @@ void MB_EndOfVideoFrame()
|
||||||
{
|
{
|
||||||
if(g_SoundcardType == CT_Empty)
|
if(g_SoundcardType == CT_Empty)
|
||||||
return;
|
return;
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "%s", "MB_EndOfVideoFrame\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!g_bMBTimerIrqActive)
|
if(!g_bMBTimerIrqActive)
|
||||||
MB_Update();
|
MB_Update();
|
||||||
|
@ -2172,8 +2343,8 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||||
g_uLastCumulativeCycles = cycles_count_total;
|
g_uLastCumulativeCycles = cycles_count_total;
|
||||||
#if 1 // APPLE2IX
|
#if 1 // APPLE2IX
|
||||||
if (uCycles >= 0x10000) {
|
if (uCycles >= 0x10000) {
|
||||||
printf("OOPS!!! Mockingboard failed assert!\n");
|
LOG("OOPS!!! Mockingboard failed assert!");
|
||||||
return;
|
uCycles %= 0x10000;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
_ASSERT(uCycles < 0x10000);
|
_ASSERT(uCycles < 0x10000);
|
||||||
|
@ -2194,6 +2365,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||||
|
|
||||||
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
|
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
|
||||||
{
|
{
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\ttimer1 (%d) underflow\n", i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 0 // _DEBUG
|
#if 0 // _DEBUG
|
||||||
g_uTimer1IrqCount++; // DEBUG
|
g_uTimer1IrqCount++; // DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
@ -2206,6 +2382,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||||
// One-shot mode
|
// One-shot mode
|
||||||
// - Phasor's playback code uses one-shot mode
|
// - Phasor's playback code uses one-shot mode
|
||||||
// - Willy Byte sets to one-shot to stop the timer IRQ
|
// - Willy Byte sets to one-shot to stop the timer IRQ
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\tstop timer %d\n", i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
StopTimer(pMB);
|
StopTimer(pMB);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2213,6 +2394,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||||
// Free-running mode
|
// Free-running mode
|
||||||
// - Ultima4/5 change ACCESS_TIMER1 after a couple of IRQs into tune
|
// - Ultima4/5 change ACCESS_TIMER1 after a couple of IRQs into tune
|
||||||
pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w;
|
pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w;
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\tstart timer %d\n", i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
StartTimer(pMB);
|
StartTimer(pMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2223,6 +2409,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||||
&& (pMB->sy6522.IFR & IxR_TIMER1) // IRQ
|
&& (pMB->sy6522.IFR & IxR_TIMER1) // IRQ
|
||||||
&& ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT) ) // One-shot mode
|
&& ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT) ) // One-shot mode
|
||||||
{
|
{
|
||||||
|
#if MB_TRACING
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fprintf(mb_trace_fp, "\ttimer1 (%d) alt underflow\n", i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Fix for Willy Byte - need to confirm that 6522 really does this!
|
// Fix for Willy Byte - need to confirm that 6522 really does this!
|
||||||
// . It never accesses IER/IFR/TIMER1 regs to clear IRQ
|
// . It never accesses IER/IFR/TIMER1 regs to clear IRQ
|
||||||
pMB->sy6522.IFR &= ~IxR_TIMER1; // Deassert the TIMER IRQ
|
pMB->sy6522.IFR &= ~IxR_TIMER1; // Deassert the TIMER IRQ
|
||||||
|
@ -2742,3 +2933,38 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
||||||
}
|
}
|
||||||
#endif // !APPLE2IX
|
#endif // !APPLE2IX
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if MB_TRACING
|
||||||
|
void mb_traceBegin(const char *trace_file) {
|
||||||
|
if (trace_file) {
|
||||||
|
mb_trace_fp = fopen(trace_file, "w");
|
||||||
|
char *samp_file = NULL;
|
||||||
|
ASPRINTF(&samp_file, "%s.samp", trace_file);
|
||||||
|
assert(samp_file);
|
||||||
|
mb_trace_samples_fp = fopen(samp_file, "w");
|
||||||
|
FREE(samp_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mb_traceFlush(void) {
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fflush(mb_trace_fp);
|
||||||
|
}
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
fflush(mb_trace_samples_fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mb_traceEnd(void) {
|
||||||
|
mb_traceFlush();
|
||||||
|
if (mb_trace_fp) {
|
||||||
|
fclose(mb_trace_fp);
|
||||||
|
mb_trace_fp = NULL;
|
||||||
|
}
|
||||||
|
if (mb_trace_samples_fp) {
|
||||||
|
fclose(mb_trace_samples_fp);
|
||||||
|
mb_trace_samples_fp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MOCKINGBOARD_H__
|
#ifndef _MOCKINGBOARD_H_
|
||||||
#define _MOCKINGBOARD_H__
|
#define _MOCKINGBOARD_H_
|
||||||
|
|
||||||
#ifdef APPLE2IX
|
#ifdef APPLE2IX
|
||||||
#include "audio/peripherals.h"
|
#include "audio/peripherals.h"
|
||||||
|
@ -123,6 +123,11 @@ bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT ve
|
||||||
#endif
|
#endif
|
||||||
#ifdef APPLE2IX
|
#ifdef APPLE2IX
|
||||||
void mb_io_initialize(unsigned int slot4, unsigned int slot5);
|
void mb_io_initialize(unsigned int slot4, unsigned int slot5);
|
||||||
|
# if MB_TRACING
|
||||||
|
void mb_traceBegin(const char *trace_file);
|
||||||
|
void mb_traceFlush(void);
|
||||||
|
void mb_traceEnd(void);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNBREAK_SOON
|
#if UNBREAK_SOON
|
||||||
|
@ -130,4 +135,5 @@ std::string Phasor_GetSnapshotCardName(void);
|
||||||
void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||||
bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // whole file
|
#endif // whole file
|
||||||
|
|
|
@ -38,6 +38,7 @@ void test_breakpoint(void *arg);
|
||||||
void test_common_init(void);
|
void test_common_init(void);
|
||||||
void test_common_setup(void);
|
void test_common_setup(void);
|
||||||
void test_type_input(const char *input);
|
void test_type_input(const char *input);
|
||||||
|
void test_type_input_deterministically(const char *input);
|
||||||
int test_setup_boot_disk(const char *fileName, int readonly);
|
int test_setup_boot_disk(const char *fileName, int readonly);
|
||||||
void sha1_to_str(const uint8_t * const md, char *buf);
|
void sha1_to_str(const uint8_t * const md, char *buf);
|
||||||
|
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
* Apple // emulator for *ix
|
|
||||||
*
|
|
||||||
* This software package is subject to the GNU General Public License
|
|
||||||
* version 3 or later (your choice) as published by the Free Software
|
|
||||||
* Foundation.
|
|
||||||
*
|
|
||||||
* Copyright 2016 Aaron Culliney
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "testcommon.h"
|
|
||||||
|
|
||||||
#define BLANK_DSK "blank.dsk.gz"
|
|
||||||
|
|
||||||
static bool test_thread_running = false;
|
|
||||||
|
|
||||||
extern pthread_mutex_t interface_mutex; // TODO FIXME : raw access to CPU mutex because stepping debugger ...
|
|
||||||
|
|
||||||
static void testspeaker_setup(void *unused) {
|
|
||||||
test_common_setup();
|
|
||||||
apple_ii_64k[0][WATCHPOINT_ADDR] = 0x00;
|
|
||||||
apple_ii_64k[0][TESTOUT_ADDR] = 0x00;
|
|
||||||
joy_button0 = 0xff; // OpenApple
|
|
||||||
if (test_do_reboot) {
|
|
||||||
cpu65_interrupt(ResetSig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void testspeaker_teardown(void *unused) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Spaker tests ...
|
|
||||||
|
|
||||||
extern unsigned long (*testing_getCyclesCount)(void);
|
|
||||||
extern void (*testing_cyclesOverflow)(void);
|
|
||||||
static bool cycles_overflowed = false;
|
|
||||||
|
|
||||||
static unsigned long testspeaker_getCyclesCount(void) {
|
|
||||||
// advance cycles count to near overflow
|
|
||||||
return ULONG_MAX - (CLK_6502_INT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void testspeaker_cyclesOverflow(void) {
|
|
||||||
cycles_overflowed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// TESTS ...
|
|
||||||
|
|
||||||
TEST test_timing_overflow() {
|
|
||||||
|
|
||||||
// force an almost overflow
|
|
||||||
|
|
||||||
testing_getCyclesCount = &testspeaker_getCyclesCount;
|
|
||||||
testing_cyclesOverflow = &testspeaker_cyclesOverflow;
|
|
||||||
|
|
||||||
ASSERT(!cycles_overflowed);
|
|
||||||
test_setup_boot_disk(BLANK_DSK, /*readonly:*/1);
|
|
||||||
BOOT_TO_DOS();
|
|
||||||
ASSERT(cycles_overflowed);
|
|
||||||
|
|
||||||
// appears emulator handled cycle count overflow gracefully ...
|
|
||||||
testing_getCyclesCount = NULL;
|
|
||||||
testing_cyclesOverflow = NULL;
|
|
||||||
|
|
||||||
PASS();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EXPECTED_BEEP_TRACE_FILE_SIZE 770
|
|
||||||
#define EXPECTED_BEEP_TRACE_SHA "69C728A65B5933D73F91D77694BEE7F674C9EDF7"
|
|
||||||
TEST test_boot_sound() {
|
|
||||||
|
|
||||||
const char *homedir = HOMEDIR;
|
|
||||||
char *testout = NULL;
|
|
||||||
ASPRINTF(&testout, "%s/a2_speaker_beep_test.txt", homedir);
|
|
||||||
if (testout) {
|
|
||||||
unlink(testout);
|
|
||||||
speaker_traceBegin(testout);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setup_boot_disk(BLANK_DSK, /*readonly:*/1);
|
|
||||||
BOOT_TO_DOS();
|
|
||||||
|
|
||||||
speaker_traceEnd();
|
|
||||||
disk6_eject(0);
|
|
||||||
|
|
||||||
do {
|
|
||||||
uint8_t md[SHA_DIGEST_LENGTH];
|
|
||||||
char mdstr0[(SHA_DIGEST_LENGTH*2)+1];
|
|
||||||
|
|
||||||
FILE *fp = fopen(testout, "r");
|
|
||||||
|
|
||||||
fseek(fp, 0, SEEK_END);
|
|
||||||
long expectedSize = ftell(fp);
|
|
||||||
ASSERT(expectedSize == EXPECTED_BEEP_TRACE_FILE_SIZE);
|
|
||||||
fseek(fp, 0, SEEK_SET);
|
|
||||||
|
|
||||||
unsigned char *buf = MALLOC(EXPECTED_BEEP_TRACE_FILE_SIZE);
|
|
||||||
if (fread(buf, 1, EXPECTED_BEEP_TRACE_FILE_SIZE, fp) != EXPECTED_BEEP_TRACE_FILE_SIZE) {
|
|
||||||
ASSERT(false);
|
|
||||||
}
|
|
||||||
fclose(fp); fp = NULL;
|
|
||||||
SHA1(buf, EXPECTED_BEEP_TRACE_FILE_SIZE, md);
|
|
||||||
FREE(buf);
|
|
||||||
|
|
||||||
sha1_to_str(md, mdstr0);
|
|
||||||
ASSERT(strcmp(mdstr0, EXPECTED_BEEP_TRACE_SHA) == 0);
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
unlink(testout);
|
|
||||||
FREE(testout);
|
|
||||||
|
|
||||||
PASS();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Test Suite
|
|
||||||
|
|
||||||
GREATEST_SUITE(test_suite_speaker) {
|
|
||||||
pthread_mutex_lock(&interface_mutex);
|
|
||||||
|
|
||||||
test_thread_running = true;
|
|
||||||
|
|
||||||
GREATEST_SET_SETUP_CB(testspeaker_setup, NULL);
|
|
||||||
GREATEST_SET_TEARDOWN_CB(testspeaker_teardown, NULL);
|
|
||||||
//GREATEST_SET_BREAKPOINT_CB(test_breakpoint, NULL);
|
|
||||||
|
|
||||||
// TESTS --------------------------
|
|
||||||
|
|
||||||
RUN_TESTp(test_timing_overflow);
|
|
||||||
RUN_TESTp(test_boot_sound);
|
|
||||||
|
|
||||||
// --------------------------------
|
|
||||||
pthread_mutex_unlock(&interface_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
SUITE(test_suite_speaker);
|
|
||||||
GREATEST_MAIN_DEFS();
|
|
||||||
|
|
||||||
static char **test_argv = NULL;
|
|
||||||
static int test_argc = 0;
|
|
||||||
|
|
||||||
static int _test_thread(void) {
|
|
||||||
int argc = test_argc;
|
|
||||||
char **argv = test_argv;
|
|
||||||
GREATEST_MAIN_BEGIN();
|
|
||||||
RUN_SUITE(test_suite_speaker);
|
|
||||||
GREATEST_MAIN_END();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *test_thread(void *dummyptr) {
|
|
||||||
_test_thread();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_speaker(int _argc, char **_argv) {
|
|
||||||
test_argc = _argc;
|
|
||||||
test_argv = _argv;
|
|
||||||
|
|
||||||
test_common_init();
|
|
||||||
|
|
||||||
pthread_t p;
|
|
||||||
pthread_create(&p, NULL, (void *)&test_thread, (void *)NULL);
|
|
||||||
while (!test_thread_running) {
|
|
||||||
struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
|
||||||
nanosleep(&ts, NULL);
|
|
||||||
}
|
|
||||||
pthread_detach(p);
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,13 +32,14 @@ static void testtrace_setup(void *arg) {
|
||||||
if (test_do_reboot) {
|
if (test_do_reboot) {
|
||||||
cpu65_interrupt(ResetSig);
|
cpu65_interrupt(ResetSig);
|
||||||
}
|
}
|
||||||
|
c_debugger_set_watchpoint(WATCHPOINT_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testtrace_teardown(void *arg) {
|
static void testtrace_teardown(void *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Cycles counter overflow test
|
// Speaker/timing tests
|
||||||
|
|
||||||
extern unsigned long (*testing_getCyclesCount)(void);
|
extern unsigned long (*testing_getCyclesCount)(void);
|
||||||
extern void (*testing_cyclesOverflow)(void);
|
extern void (*testing_cyclesOverflow)(void);
|
||||||
|
@ -72,9 +73,6 @@ TEST test_timing_overflow() {
|
||||||
PASS();
|
PASS();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Tracing TESTS ...
|
|
||||||
|
|
||||||
#define EXPECTED_BEEP_TRACE_FILE_SIZE 770
|
#define EXPECTED_BEEP_TRACE_FILE_SIZE 770
|
||||||
#define EXPECTED_BEEP_TRACE_SHA "69C728A65B5933D73F91D77694BEE7F674C9EDF7"
|
#define EXPECTED_BEEP_TRACE_SHA "69C728A65B5933D73F91D77694BEE7F674C9EDF7"
|
||||||
TEST test_boot_sound() {
|
TEST test_boot_sound() {
|
||||||
|
@ -122,6 +120,97 @@ TEST test_boot_sound() {
|
||||||
PASS();
|
PASS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Mockingboard tracing
|
||||||
|
|
||||||
|
#define NSCT_DSK "NSCT.dsk.gz"
|
||||||
|
#define NSCT_TRACE_SHA "35C58FEEB70E76FC31CEB55DB4C830B471B48AE3" // WARNING unstable if tests changed before this ...
|
||||||
|
#define NSCT_SAMPS_SHA "C48AFC2ABFECC98CECB8A5B63E2261181195E1B2"
|
||||||
|
#define NSCT_TRACE_TARGET_SIZ (512 * 65536) // 2^25
|
||||||
|
#define NSCT_SAMPS_TARGET_SIZ (2048 * 65536) // 2^27
|
||||||
|
TEST test_mockingboard_1() {
|
||||||
|
test_setup_boot_disk(NSCT_DSK, 0);
|
||||||
|
|
||||||
|
const char *homedir = HOMEDIR;
|
||||||
|
|
||||||
|
char *mbTraceFile = NULL;
|
||||||
|
ASPRINTF(&mbTraceFile, "%s/a2_mb_nsct", homedir);
|
||||||
|
ASSERT(mbTraceFile);
|
||||||
|
unlink(mbTraceFile);
|
||||||
|
|
||||||
|
char *mbSampsFile = NULL;
|
||||||
|
ASPRINTF(&mbSampsFile, "%s.samp", mbTraceFile);
|
||||||
|
ASSERT(mbSampsFile);
|
||||||
|
unlink(mbSampsFile);
|
||||||
|
|
||||||
|
// Poll for trace file of particular size
|
||||||
|
mb_traceBegin(mbTraceFile); // ".samp" file is automatically created ...
|
||||||
|
c_debugger_clear_watchpoints();
|
||||||
|
c_debugger_set_timeout(1);
|
||||||
|
do {
|
||||||
|
c_debugger_go();
|
||||||
|
|
||||||
|
FILE *fpTrace = fopen(mbTraceFile, "r");
|
||||||
|
fseek(fpTrace, 0, SEEK_END);
|
||||||
|
long minSizeTrace = ftell(fpTrace);
|
||||||
|
|
||||||
|
FILE *fpSamps = fopen(mbSampsFile, "r");
|
||||||
|
fseek(fpSamps, 0, SEEK_END);
|
||||||
|
long minSizeSamps = ftell(fpSamps);
|
||||||
|
|
||||||
|
if ( (minSizeTrace < NSCT_TRACE_TARGET_SIZ) || (minSizeSamps < NSCT_SAMPS_TARGET_SIZ) ) {
|
||||||
|
fclose(fpTrace);
|
||||||
|
fclose(fpSamps);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace has generated files of sufficient length
|
||||||
|
|
||||||
|
uint8_t md[SHA_DIGEST_LENGTH];
|
||||||
|
char mdstr0[(SHA_DIGEST_LENGTH*2)+1];
|
||||||
|
|
||||||
|
// verify trace file
|
||||||
|
do {
|
||||||
|
unsigned char *buf = MALLOC(NSCT_TRACE_TARGET_SIZ);
|
||||||
|
fseek(fpTrace, 0, SEEK_SET);
|
||||||
|
ASSERT(fread(buf, 1, NSCT_TRACE_TARGET_SIZ, fpTrace) == NSCT_TRACE_TARGET_SIZ);
|
||||||
|
fclose(fpTrace); fpTrace = NULL;
|
||||||
|
SHA1(buf, NSCT_TRACE_TARGET_SIZ, md);
|
||||||
|
FREE(buf);
|
||||||
|
sha1_to_str(md, mdstr0);
|
||||||
|
ASSERT(strcmp(mdstr0, NSCT_TRACE_SHA) == 0);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// verify trace samples file
|
||||||
|
do {
|
||||||
|
unsigned char *buf = MALLOC(NSCT_SAMPS_TARGET_SIZ);
|
||||||
|
fseek(fpSamps, 0, SEEK_SET);
|
||||||
|
ASSERT(fread(buf, 1, NSCT_SAMPS_TARGET_SIZ, fpSamps) == NSCT_SAMPS_TARGET_SIZ);
|
||||||
|
fclose(fpSamps); fpSamps = NULL;
|
||||||
|
SHA1(buf, NSCT_SAMPS_TARGET_SIZ, md);
|
||||||
|
FREE(buf);
|
||||||
|
sha1_to_str(md, mdstr0);
|
||||||
|
ASSERT(strcmp(mdstr0, NSCT_SAMPS_SHA) == 0);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
c_debugger_set_timeout(0);
|
||||||
|
mb_traceEnd();
|
||||||
|
|
||||||
|
unlink(mbTraceFile);
|
||||||
|
FREE(mbTraceFile);
|
||||||
|
unlink(mbSampsFile);
|
||||||
|
FREE(mbSampsFile);
|
||||||
|
|
||||||
|
disk6_eject(0);
|
||||||
|
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// CPU tracing
|
||||||
|
|
||||||
// This test is majorly abusive ... it creates an ~800MB file in $HOME
|
// This test is majorly abusive ... it creates an ~800MB file in $HOME
|
||||||
// ... but if it's correct, you're fairly assured the cpu/vm is working =)
|
// ... but if it's correct, you're fairly assured the cpu/vm is working =)
|
||||||
#if ABUSIVE_TESTS
|
#if ABUSIVE_TESTS
|
||||||
|
@ -320,6 +409,9 @@ TEST test_cputrace_hello_po() {
|
||||||
PASS();
|
PASS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// VM tracing
|
||||||
|
|
||||||
#define EXPECTED_VM_TRACE_FILE_SIZE 2832136
|
#define EXPECTED_VM_TRACE_FILE_SIZE 2832136
|
||||||
#define EXPECTED_VM_TRACE_SHA "E39658183FF87974D8538B38B772A193C6C3276C"
|
#define EXPECTED_VM_TRACE_SHA "E39658183FF87974D8538B38B772A193C6C3276C"
|
||||||
TEST test_boot_disk_vmtrace() {
|
TEST test_boot_disk_vmtrace() {
|
||||||
|
@ -479,6 +571,8 @@ GREATEST_SUITE(test_suite_trace) {
|
||||||
RUN_TESTp(test_timing_overflow);
|
RUN_TESTp(test_timing_overflow);
|
||||||
RUN_TESTp(test_boot_sound);
|
RUN_TESTp(test_boot_sound);
|
||||||
|
|
||||||
|
RUN_TESTp(test_mockingboard_1);
|
||||||
|
|
||||||
#if ABUSIVE_TESTS
|
#if ABUSIVE_TESTS
|
||||||
RUN_TESTp(test_boot_disk_cputrace);
|
RUN_TESTp(test_boot_disk_cputrace);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user