diff --git a/Makefile.am b/Makefile.am index 2112dcda..fbc8fa2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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_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_LDFLAGS = $(apple2ix_LDFLAGS) testtrace_LDADD = @testtrace_ASM_O@ @testtrace_VIDEO_O@ @testtrace_AUDIO_O@ @testtrace_META_O@ @X_LIBS@ diff --git a/src/audio/AY8910.c b/src/audio/AY8910.c index ecadf804..b8514ee6 100644 --- a/src/audio/AY8910.c +++ b/src/audio/AY8910.c @@ -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_TONE2_PERIOD, ay_tone_period[2]); 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_NOISE_TOGGLE, noise_toggle); 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; #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) { diff --git a/src/audio/AY8910.h b/src/audio/AY8910.h index 1d596de0..9440698f 100644 --- a/src/audio/AY8910.h +++ b/src/audio/AY8910.h @@ -32,6 +32,9 @@ void AY8910UpdateSetCycles(); UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix); UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix); #endif +#if MB_TRACING +void _mb_trace_AY8910(int chip, FILE *mb_trace_fp); +#endif //------------------------------------- // FUSE stuff diff --git a/src/audio/mockingboard.c b/src/audio/mockingboard.c index 9d08c544..49d4b9d2 100644 --- a/src/audio/mockingboard.c +++ b/src/audio/mockingboard.c @@ -19,7 +19,7 @@ Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski AppleWin is free software; you can redistribute it and/or modify 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. 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 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 *SSI263Voice[64] = { 0 }; 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 AY8910_reset(nDevice+2*nAYDevice); +#if MB_TRACING + _mb_trace_AY8910(nDevice+2*nAYDevice, mb_trace_fp); +#endif } 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 _AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA); +#if MB_TRACING + _mb_trace_AY8910(nDevice+2*nAYDevice, mb_trace_fp); +#endif break; 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; // else Pro-Mockingboard (clone from HK) break; +#if 1 // APPLE2IX + default: + mb_assert(false); +#endif } } } @@ -419,6 +436,11 @@ static void UpdateIFR(SY6522_AY8910* pMB) if (bIRQ) { #if 1 // APPLE2IX +#if MB_TRACING + if (mb_trace_fp) { + fprintf(mb_trace_fp, "\t%s\n", "IRQ_6522"); + } +#endif cpu65_interrupt(IS_6522); #else CpuIrqAssert(IS_6522); @@ -427,6 +449,11 @@ static void UpdateIFR(SY6522_AY8910* pMB) else { #if 1 // APPLE2IX +#if MB_TRACING + if (mb_trace_fp) { + fprintf(mb_trace_fp, "\t%s\n", "!IRQ_6522"); + } +#endif cpu65_uninterrupt(IS_6522); #else 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) { +#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; 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 break; } + +#if MB_TRACING + if (mb_trace_fp) { + _mb_traceSY6522_AY8910(nDevice); + } +#endif } //----------------------------------------------------------------------------- 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_Active = true; @@ -630,6 +704,13 @@ static uint8_t SY6522_Read(uint8_t nDevice, uint8_t nReg) break; } +#if MB_TRACING + if (mb_trace_fp) { + _mb_traceSY6522_AY8910(nDevice); + fprintf(mb_trace_fp, "\tret:%02X\n", nValue); + } +#endif + return nValue; } @@ -865,6 +946,11 @@ static void MB_Update() { return; } +# if MB_TRACING + if (mb_trace_fp) { + fprintf(mb_trace_fp, "%s", "\tMB_Update()\n"); + } +# endif #else char szDbg[200]; @@ -874,6 +960,7 @@ static void MB_Update() if (g_bFullSpeed) { +#if !MB_TRACING // Keep AY reg writes relative to the current 'frame' // - Required for Ultima3: // . Tune ends @@ -886,6 +973,7 @@ static void MB_Update() // If any AY regs have changed then push them out to the AY chip return; +#endif } // @@ -1016,26 +1104,65 @@ static void MB_Update() 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; for(int i=0; i 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+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) +# if MB_TRACING + if (!g_bFullSpeed) { +# endif do { if (MockingboardVoice->Lock(MockingboardVoice, requestedBufSize, &pDSLockedBuffer0, &dwDSLockedBufferSize0)) { return; @@ -1097,6 +1235,9 @@ static void MB_Update() ++counter; } while (bufIdx < originalRequestedBufSize && counter < 2); assert(bufIdx == originalRequestedBufSize); +# if MB_TRACING + } +# endif #endif #ifdef RIFF_MB @@ -1848,6 +1989,12 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO #endif { #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(); #else MB_UpdateCycles(nCyclesLeft); @@ -1922,11 +2069,23 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO #else mb_assert(false); #endif - else -#if 1 // APPLE2IX - return MemReadFloatingBus(); + +#if MB_TRACING +# 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 +# if 1 // APPLE2IX + return MemReadFloatingBus(); +# else return MemReadFloatingBus(nCyclesLeft); +# endif #endif } @@ -1940,6 +2099,13 @@ static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL #endif { #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(); #else MB_UpdateCycles(nCyclesLeft); @@ -2150,6 +2316,11 @@ void MB_EndOfVideoFrame() { if(g_SoundcardType == CT_Empty) return; +#if MB_TRACING + if (mb_trace_fp) { + fprintf(mb_trace_fp, "%s", "MB_EndOfVideoFrame\n"); + } +#endif if(!g_bMBTimerIrqActive) MB_Update(); @@ -2172,8 +2343,8 @@ void MB_UpdateCycles(ULONG uExecutedCycles) g_uLastCumulativeCycles = cycles_count_total; #if 1 // APPLE2IX if (uCycles >= 0x10000) { - printf("OOPS!!! Mockingboard failed assert!\n"); - return; + LOG("OOPS!!! Mockingboard failed assert!"); + uCycles %= 0x10000; } #else _ASSERT(uCycles < 0x10000); @@ -2194,6 +2365,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles) 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 g_uTimer1IrqCount++; // DEBUG #endif @@ -2206,6 +2382,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles) // One-shot mode // - Phasor's playback code uses one-shot mode // - 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); } else @@ -2213,6 +2394,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles) // Free-running mode // - Ultima4/5 change ACCESS_TIMER1 after a couple of IRQs into tune 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); } @@ -2223,6 +2409,11 @@ void MB_UpdateCycles(ULONG uExecutedCycles) && (pMB->sy6522.IFR & IxR_TIMER1) // IRQ && ((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! // . It never accesses IER/IFR/TIMER1 regs to clear 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 +//----------------------------------------------------------------------------- + +#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 diff --git a/src/audio/mockingboard.h b/src/audio/mockingboard.h index 2b74a894..83e54b9c 100644 --- a/src/audio/mockingboard.h +++ b/src/audio/mockingboard.h @@ -9,8 +9,8 @@ * */ -#ifndef _MOCKINGBOARD_H__ -#define _MOCKINGBOARD_H__ +#ifndef _MOCKINGBOARD_H_ +#define _MOCKINGBOARD_H_ #ifdef APPLE2IX #include "audio/peripherals.h" @@ -123,6 +123,11 @@ bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT ve #endif #ifdef APPLE2IX 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 #if UNBREAK_SOON @@ -130,4 +135,5 @@ std::string Phasor_GetSnapshotCardName(void); void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); #endif + #endif // whole file diff --git a/src/test/testcommon.h b/src/test/testcommon.h index 75daa394..72378830 100644 --- a/src/test/testcommon.h +++ b/src/test/testcommon.h @@ -38,6 +38,7 @@ void test_breakpoint(void *arg); void test_common_init(void); void test_common_setup(void); 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); void sha1_to_str(const uint8_t * const md, char *buf); diff --git a/src/test/testspeaker.c b/src/test/testspeaker.c deleted file mode 100644 index 8681112b..00000000 --- a/src/test/testspeaker.c +++ /dev/null @@ -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); -} - diff --git a/src/test/testtrace.c b/src/test/testtrace.c index 66197bbb..2ac90d45 100644 --- a/src/test/testtrace.c +++ b/src/test/testtrace.c @@ -32,13 +32,14 @@ static void testtrace_setup(void *arg) { if (test_do_reboot) { cpu65_interrupt(ResetSig); } + c_debugger_set_watchpoint(WATCHPOINT_ADDR); } static void testtrace_teardown(void *arg) { } // ---------------------------------------------------------------------------- -// Cycles counter overflow test +// Speaker/timing tests extern unsigned long (*testing_getCyclesCount)(void); extern void (*testing_cyclesOverflow)(void); @@ -72,9 +73,6 @@ TEST test_timing_overflow() { PASS(); } -// ---------------------------------------------------------------------------- -// Tracing TESTS ... - #define EXPECTED_BEEP_TRACE_FILE_SIZE 770 #define EXPECTED_BEEP_TRACE_SHA "69C728A65B5933D73F91D77694BEE7F674C9EDF7" TEST test_boot_sound() { @@ -122,6 +120,97 @@ TEST test_boot_sound() { 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 // ... but if it's correct, you're fairly assured the cpu/vm is working =) #if ABUSIVE_TESTS @@ -320,6 +409,9 @@ TEST test_cputrace_hello_po() { PASS(); } +// ---------------------------------------------------------------------------- +// VM tracing + #define EXPECTED_VM_TRACE_FILE_SIZE 2832136 #define EXPECTED_VM_TRACE_SHA "E39658183FF87974D8538B38B772A193C6C3276C" TEST test_boot_disk_vmtrace() { @@ -479,6 +571,8 @@ GREATEST_SUITE(test_suite_trace) { RUN_TESTp(test_timing_overflow); RUN_TESTp(test_boot_sound); + RUN_TESTp(test_mockingboard_1); + #if ABUSIVE_TESTS RUN_TESTp(test_boot_disk_cputrace); #endif