diff --git a/.gitignore b/.gitignore index 6d27ab2..ed0332d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ Debug-Legacy-1.1.14/ *.VC.opendb *.suo *.sln.ecd -*.vcxproj.user \ No newline at end of file +*.vcxproj.user +*.o +*.so diff --git a/Visual Studio/SimpleSerialAnalyzer.sln b/Visual Studio/C64SerialAnalyzer.sln similarity index 91% rename from Visual Studio/SimpleSerialAnalyzer.sln rename to Visual Studio/C64SerialAnalyzer.sln index 4b1727f..9bb1f1f 100644 --- a/Visual Studio/SimpleSerialAnalyzer.sln +++ b/Visual Studio/C64SerialAnalyzer.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSerialAnalyzer", "SimpleSerialAnalyzer.vcxproj", "{D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "C64SerialAnalyzer", "C64SerialAnalyzer.vcxproj", "{D7556E7E-A6BF-4BCE-BDC8-E66D2874C301}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Visual Studio/SimpleSerialAnalyzer.vcxproj b/Visual Studio/C64SerialAnalyzer.vcxproj similarity index 89% rename from Visual Studio/SimpleSerialAnalyzer.vcxproj rename to Visual Studio/C64SerialAnalyzer.vcxproj index 93aca51..2e371bb 100644 --- a/Visual Studio/SimpleSerialAnalyzer.vcxproj +++ b/Visual Studio/C64SerialAnalyzer.vcxproj @@ -28,7 +28,7 @@ {D7556E7E-A6BF-4BCE-BDC8-E66D2874C301} - SimpleSerialAnalyzer + C64SerialAnalyzer Win32Proj 8.1 @@ -118,7 +118,7 @@ Disabled $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -138,7 +138,7 @@ Disabled $(ProjectDir)..\LegacyAnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug @@ -159,7 +159,7 @@ Disabled $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -178,7 +178,7 @@ Disabled $(ProjectDir)..\LegacyAnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -198,7 +198,7 @@ MaxSpeed true $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -220,7 +220,7 @@ MaxSpeed true $(ProjectDir)..\AnalyzerSDK\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;SIMPLESERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;C64SERIALANALYZER_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -238,16 +238,16 @@ - - - - + + + + - - - - + + + + diff --git a/source/.clang-format b/source/.clang-format new file mode 100644 index 0000000..0c60597 --- /dev/null +++ b/source/.clang-format @@ -0,0 +1,6 @@ +{ + BasedOnStyle: LLVM, + IndentWidth: 4, + ColumnLimit: 80, + AccessModifierOffset: -4, +} diff --git a/source/C64SerialAnalyzer.cpp b/source/C64SerialAnalyzer.cpp new file mode 100644 index 0000000..75ae7cc --- /dev/null +++ b/source/C64SerialAnalyzer.cpp @@ -0,0 +1,173 @@ +#include "C64SerialAnalyzer.h" +#include "C64SerialAnalyzerSettings.h" +#include + +C64SerialAnalyzer::C64SerialAnalyzer() + : Analyzer2(), mSettings(new C64SerialAnalyzerSettings()), + mSimulationInitilized(false) { + SetAnalyzerSettings(mSettings.get()); +} + +C64SerialAnalyzer::~C64SerialAnalyzer() { KillThread(); } + +void C64SerialAnalyzer::SetupResults() { + mResults.reset(new C64SerialAnalyzerResults(this, mSettings.get())); + SetAnalyzerResults(mResults.get()); + mResults->AddChannelBubblesWillAppearOn(mSettings->mDataChannel); +} + +U64 C64SerialAnalyzer::AdvanceTo(U64 sample) { + mData->AdvanceToAbsPosition(sample); + mClock->AdvanceToAbsPosition(sample); + //mAttention->AdvanceToAbsPosition(sample); + + return sample; +} + +bool C64SerialAnalyzer::ReceiveByte() { + // Advance until both clock and data lines are asserted. + while (mData->GetBitState() == BIT_LOW || + mClock->GetBitState() == BIT_LOW) { + AdvanceTo(std::min(mData->GetSampleOfNextEdge(), + mClock->GetSampleOfNextEdge())); + } + + bool eoi = mData->GetSampleOfNextEdge() < mClock->GetSampleOfNextEdge(); + if (eoi) { + // An EOI happened, go back to idle after finishing. + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::X, + mSettings->mClockChannel); + } + + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::Start, + mSettings->mDataChannel); + U64 start_sample = AdvanceTo(mClock->GetSampleOfNextEdge()); + + // Receive a byte + U8 byte = 0; + for (int i = 0; i < 8; i++) { + AdvanceTo(mClock->GetSampleOfNextEdge()); + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::Dot, + mSettings->mDataChannel); + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::UpArrow, + mSettings->mClockChannel); + + byte |= mData->GetBitState() << i; + + AdvanceTo(mClock->GetSampleOfNextEdge()); + mResults->AddMarker(mClock->GetSampleNumber(), + AnalyzerResults::DownArrow, + mSettings->mClockChannel); + } + + // We have a byte to save + Frame frame; + frame.mData1 = byte; + frame.mType = static_cast(mState); + frame.mStartingSampleInclusive = start_sample; + frame.mEndingSampleInclusive = mData->GetSampleNumber(); + + mResults->AddFrame(frame); + mResults->CommitResults(); + ReportProgress(frame.mEndingSampleInclusive); + + // Wait until data is high and back down. + if (mData->GetBitState() == BIT_LOW) { + AdvanceTo(mData->GetSampleOfNextEdge()); + } + AdvanceTo(mData->GetSampleOfNextEdge()); + + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::Stop, + mSettings->mDataChannel); + + return eoi; +} + +enum class FrameType { + Attention, + Talking, +}; + +void C64SerialAnalyzer::Update() { + mResults->AddMarker(mClock->GetSampleNumber(), AnalyzerResults::Dot, + mSettings->mAttentionChannel); + + if (mState == State::Idle) { + // Advance until both clock and data lines are asserted. + while (mData->GetBitState() == BIT_HIGH || + mClock->GetBitState() == BIT_HIGH) { + AdvanceTo(std::min(mData->GetSampleOfNextEdge(), + mClock->GetSampleOfNextEdge())); + } + + // Check if attention was asserted. + BitState old_attention = mAttention->GetBitState(); + mAttention->AdvanceToAbsPosition(mClock->GetSampleOfNextEdge()); + BitState new_attention = mAttention->GetBitState(); + + if (new_attention == BIT_LOW) { + mState = State::Attention; + } else if (old_attention == BIT_LOW) { + // If attention was low but is now high, check if talking continues. + if (mData->GetSampleOfNextEdge() > mClock->GetSampleOfNextEdge()) { + mState = State::Talking; + } else { + AdvanceTo(mAttention->GetSampleNumber()); + } + } else { + mState = State::Talking; + } + } else if (mState == State::Attention) { + ReceiveByte(); + mState = State::Idle; + } else if (mState == State::Talking) { + bool eoi = ReceiveByte(); + + if (eoi) { + mState = State::Idle; + } + } else if (mState == State::TurnAround) { + } +} + +void C64SerialAnalyzer::WorkerThread() { + mSampleRateHz = GetSampleRate(); + + mAttention = GetAnalyzerChannelData(mSettings->mAttentionChannel); + mData = GetAnalyzerChannelData(mSettings->mDataChannel); + mClock = GetAnalyzerChannelData(mSettings->mClockChannel); + + mState = State::Idle; + while (true) { + Update(); + CheckIfThreadShouldExit(); + } +} + +bool C64SerialAnalyzer::NeedsRerun() { return false; } + +U32 C64SerialAnalyzer::GenerateSimulationData( + U64 minimum_sample_index, U32 device_sample_rate, + SimulationChannelDescriptor **simulation_channels) { + if (mSimulationInitilized == false) { + mSimulationDataGenerator.Initialize(GetSimulationSampleRate(), + mSettings.get()); + mSimulationInitilized = true; + } + + return mSimulationDataGenerator.GenerateSimulationData( + minimum_sample_index, device_sample_rate, simulation_channels); +} + +U32 C64SerialAnalyzer::GetMinimumSampleRateHz() { + // return mSettings->mBitRate * 4; + return 4000000; +} + +const char *C64SerialAnalyzer::GetAnalyzerName() const { return "C64 Serial"; } + +const char *GetAnalyzerName() { return "C64 Serial"; } + +Analyzer *CreateAnalyzer() { return new C64SerialAnalyzer(); } + +void DestroyAnalyzer(Analyzer *analyzer) { delete analyzer; } diff --git a/source/C64SerialAnalyzer.h b/source/C64SerialAnalyzer.h new file mode 100644 index 0000000..7fc59ff --- /dev/null +++ b/source/C64SerialAnalyzer.h @@ -0,0 +1,57 @@ +#ifndef C64SERIAL_ANALYZER_H +#define C64SERIAL_ANALYZER_H + +#include "C64SerialAnalyzerResults.h" +#include "C64SerialSimulationDataGenerator.h" +#include + +class C64SerialAnalyzerSettings; +class ANALYZER_EXPORT C64SerialAnalyzer : public Analyzer2 { +public: + C64SerialAnalyzer(); + virtual ~C64SerialAnalyzer(); + + virtual void SetupResults(); + virtual void WorkerThread(); + + virtual U32 + GenerateSimulationData(U64 newest_sample_requested, U32 sample_rate, + SimulationChannelDescriptor **simulation_channels); + + virtual U32 GetMinimumSampleRateHz(); + + virtual const char *GetAnalyzerName() const; + virtual bool NeedsRerun(); + + enum class State : U8 { + Idle, + Attention, + Talking, + TurnAround, + } mState; + +protected: + void Update(); + bool ReceiveByte(); + U64 AdvanceTo(U64 sample); + + std::auto_ptr mSettings; + std::auto_ptr mResults; + AnalyzerChannelData *mAttention; + AnalyzerChannelData *mData; + AnalyzerChannelData *mClock; + + C64SerialSimulationDataGenerator mSimulationDataGenerator; + bool mSimulationInitilized; + + // Serial analysis vars: + U32 mSampleRateHz; + U32 mStartOfStopBitOffset; + U32 mEndOfStopBitOffset; +}; + +extern "C" ANALYZER_EXPORT const char *__cdecl GetAnalyzerName(); +extern "C" ANALYZER_EXPORT Analyzer *__cdecl CreateAnalyzer(); +extern "C" ANALYZER_EXPORT void __cdecl DestroyAnalyzer(Analyzer *analyzer); + +#endif // C64SERIAL_ANALYZER_H diff --git a/source/C64SerialAnalyzerResults.cpp b/source/C64SerialAnalyzerResults.cpp new file mode 100644 index 0000000..d198840 --- /dev/null +++ b/source/C64SerialAnalyzerResults.cpp @@ -0,0 +1,103 @@ +#include "C64SerialAnalyzerResults.h" +#include "C64SerialAnalyzer.h" +#include "C64SerialAnalyzerSettings.h" +#include +#include +#include + +C64SerialAnalyzerResults::C64SerialAnalyzerResults( + C64SerialAnalyzer *analyzer, C64SerialAnalyzerSettings *settings) + : AnalyzerResults(), mSettings(settings), mAnalyzer(analyzer) {} + +C64SerialAnalyzerResults::~C64SerialAnalyzerResults() {} + +void ControlCodeName(char *buffer, U8 code) { + if (code >= 0x20 && code <= 0x3E) { + sprintf(buffer, "Listen %d", code - 0x20); + } else if (code == 0x3F) { + sprintf(buffer, "Unlisten"); + } else if (code >= 0x40 && code <= 0x5E) { + sprintf(buffer, "Talk %d", code - 0x40); + } else if (code == 0x5F) { + sprintf(buffer, "Untalk"); + } else if (code >= 0x60 && code <= 0x6F) { + sprintf(buffer, "Reopen ch. %d", code & 0x0F); + } else if (code >= 0xE0 && code <= 0xEF) { + sprintf(buffer, "Close ch. %d", code & 0x0F); + } else if (code >= 0xF0 && code <= 0xFF) { + sprintf(buffer, "Open ch. %d", code & 0x0F); + } +} + +void C64SerialAnalyzerResults::GenerateBubbleText(U64 frame_index, + Channel &channel, + DisplayBase display_base) { + ClearResultStrings(); + Frame frame = GetFrame(frame_index); + + char buffer[128]; + if (frame.mType == static_cast(C64SerialAnalyzer::State::Attention)) { + ControlCodeName(buffer, frame.mData1); + } else { + AnalyzerHelpers::GetNumberString(frame.mData1, display_base, 8, buffer, + sizeof(buffer)); + } + AddResultString(buffer); +} + +void C64SerialAnalyzerResults::GenerateExportFile(const char *file, + DisplayBase display_base, + U32 export_type_user_id) { + std::ofstream file_stream(file, std::ios::out); + + U64 trigger_sample = mAnalyzer->GetTriggerSample(); + U32 sample_rate = mAnalyzer->GetSampleRate(); + + file_stream << "Time [s],Value" << std::endl; + + U64 num_frames = GetNumFrames(); + for (U32 i = 0; i < num_frames; i++) { + Frame frame = GetFrame(i); + + char time_str[128]; + AnalyzerHelpers::GetTimeString(frame.mStartingSampleInclusive, + trigger_sample, sample_rate, time_str, + 128); + + char number_str[128]; + AnalyzerHelpers::GetNumberString(frame.mData1, display_base, 8, + number_str, 128); + + file_stream << time_str << "," << number_str << std::endl; + + if (UpdateExportProgressAndCheckForCancel(i, num_frames) == true) { + file_stream.close(); + return; + } + } + + file_stream.close(); +} + +void C64SerialAnalyzerResults::GenerateFrameTabularText( + U64 frame_index, DisplayBase display_base) { +#ifdef SUPPORTS_PROTOCOL_SEARCH + Frame frame = GetFrame(frame_index); + ClearTabularText(); + + char number_str[128]; + AnalyzerHelpers::GetNumberString(frame.mData1, display_base, 8, number_str, + 128); + AddTabularText(number_str); +#endif +} + +void C64SerialAnalyzerResults::GeneratePacketTabularText( + U64 packet_id, DisplayBase display_base) { + // not supported +} + +void C64SerialAnalyzerResults::GenerateTransactionTabularText( + U64 transaction_id, DisplayBase display_base) { + // not supported +} diff --git a/source/SimpleSerialAnalyzerResults.h b/source/C64SerialAnalyzerResults.h similarity index 54% rename from source/SimpleSerialAnalyzerResults.h rename to source/C64SerialAnalyzerResults.h index dfdd212..1120b8d 100644 --- a/source/SimpleSerialAnalyzerResults.h +++ b/source/C64SerialAnalyzerResults.h @@ -1,16 +1,16 @@ -#ifndef SIMPLESERIAL_ANALYZER_RESULTS -#define SIMPLESERIAL_ANALYZER_RESULTS +#ifndef C64SERIAL_ANALYZER_RESULTS +#define C64SERIAL_ANALYZER_RESULTS #include -class SimpleSerialAnalyzer; -class SimpleSerialAnalyzerSettings; +class C64SerialAnalyzer; +class C64SerialAnalyzerSettings; -class SimpleSerialAnalyzerResults : public AnalyzerResults +class C64SerialAnalyzerResults : public AnalyzerResults { public: - SimpleSerialAnalyzerResults( SimpleSerialAnalyzer* analyzer, SimpleSerialAnalyzerSettings* settings ); - virtual ~SimpleSerialAnalyzerResults(); + C64SerialAnalyzerResults( C64SerialAnalyzer* analyzer, C64SerialAnalyzerSettings* settings ); + virtual ~C64SerialAnalyzerResults(); virtual void GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base ); virtual void GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id ); @@ -22,8 +22,8 @@ public: protected: //functions protected: //vars - SimpleSerialAnalyzerSettings* mSettings; - SimpleSerialAnalyzer* mAnalyzer; + C64SerialAnalyzerSettings* mSettings; + C64SerialAnalyzer* mAnalyzer; }; -#endif //SIMPLESERIAL_ANALYZER_RESULTS +#endif //C64SERIAL_ANALYZER_RESULTS diff --git a/source/C64SerialAnalyzerSettings.cpp b/source/C64SerialAnalyzerSettings.cpp new file mode 100644 index 0000000..98fd37c --- /dev/null +++ b/source/C64SerialAnalyzerSettings.cpp @@ -0,0 +1,78 @@ +#include "C64SerialAnalyzerSettings.h" +#include + +C64SerialAnalyzerSettings::C64SerialAnalyzerSettings() + : mAttentionChannel(UNDEFINED_CHANNEL), mDataChannel(UNDEFINED_CHANNEL), + mClockChannel(UNDEFINED_CHANNEL) { + + mAttentionChannelInterface.reset(new AnalyzerSettingInterfaceChannel()); + mAttentionChannelInterface->SetTitleAndTooltip("Attention", "Standard C64 Serial Attention"); + mAttentionChannelInterface->SetChannel(mAttentionChannel); + AddInterface(mAttentionChannelInterface.get()); + + mDataChannelInterface.reset(new AnalyzerSettingInterfaceChannel()); + mDataChannelInterface->SetTitleAndTooltip("Data", "Standard C64 Serial Data"); + mDataChannelInterface->SetChannel(mDataChannel); + AddInterface(mDataChannelInterface.get()); + + mClockChannelInterface.reset(new AnalyzerSettingInterfaceChannel()); + mClockChannelInterface->SetTitleAndTooltip("Clock", "Standard C64 Serial Clock"); + mClockChannelInterface->SetChannel(mClockChannel); + AddInterface(mClockChannelInterface.get()); + + // AddExportOption(0, "Export as text/csv file"); + // AddExportExtension(0, "text", "txt"); + // AddExportExtension(0, "csv", "csv"); + + ClearChannels(); + AddChannel(mAttentionChannel, "Attention", false); + AddChannel(mDataChannel, "Data", false); + AddChannel(mClockChannel, "Clock", false); +} + +C64SerialAnalyzerSettings::~C64SerialAnalyzerSettings() {} + +bool C64SerialAnalyzerSettings::SetSettingsFromInterfaces() { + mAttentionChannel = mAttentionChannelInterface->GetChannel(); + mDataChannel = mDataChannelInterface->GetChannel(); + mClockChannel = mClockChannelInterface->GetChannel(); + + ClearChannels(); + AddChannel(mAttentionChannel, "Attention", true); + AddChannel(mDataChannel, "Data", true); + AddChannel(mClockChannel, "Clock", true); + + return true; +} + +void C64SerialAnalyzerSettings::UpdateInterfacesFromSettings() { + mAttentionChannelInterface->SetChannel(mAttentionChannel); + mDataChannelInterface->SetChannel(mDataChannel); + mClockChannelInterface->SetChannel(mClockChannel); +} + +void C64SerialAnalyzerSettings::LoadSettings(const char *settings) { + SimpleArchive text_archive; + text_archive.SetString(settings); + + text_archive >> mAttentionChannel; + text_archive >> mDataChannel; + text_archive >> mClockChannel; + + ClearChannels(); + AddChannel(mAttentionChannel, "Attention", true); + AddChannel(mDataChannel, "Data", true); + AddChannel(mClockChannel, "Clock", true); + + UpdateInterfacesFromSettings(); +} + +const char *C64SerialAnalyzerSettings::SaveSettings() { + SimpleArchive text_archive; + + text_archive << mAttentionChannel; + text_archive << mDataChannel; + text_archive << mClockChannel; + + return SetReturnString(text_archive.GetString()); +} diff --git a/source/C64SerialAnalyzerSettings.h b/source/C64SerialAnalyzerSettings.h new file mode 100644 index 0000000..6af830e --- /dev/null +++ b/source/C64SerialAnalyzerSettings.h @@ -0,0 +1,27 @@ +#ifndef C64SERIAL_ANALYZER_SETTINGS +#define C64SERIAL_ANALYZER_SETTINGS + +#include +#include + +class C64SerialAnalyzerSettings : public AnalyzerSettings { +public: + C64SerialAnalyzerSettings(); + virtual ~C64SerialAnalyzerSettings(); + + virtual bool SetSettingsFromInterfaces(); + void UpdateInterfacesFromSettings(); + virtual void LoadSettings(const char *settings); + virtual const char *SaveSettings(); + + Channel mAttentionChannel; + Channel mDataChannel; + Channel mClockChannel; + +protected: + std::auto_ptr mAttentionChannelInterface; + std::auto_ptr mDataChannelInterface; + std::auto_ptr mClockChannelInterface; +}; + +#endif // C64SERIAL_ANALYZER_SETTINGS diff --git a/source/C64SerialSimulationDataGenerator.cpp b/source/C64SerialSimulationDataGenerator.cpp new file mode 100644 index 0000000..86cef9c --- /dev/null +++ b/source/C64SerialSimulationDataGenerator.cpp @@ -0,0 +1,67 @@ +#include "C64SerialSimulationDataGenerator.h" +#include "C64SerialAnalyzerSettings.h" + +#include + +C64SerialSimulationDataGenerator::C64SerialSimulationDataGenerator() + : mSerialText("My first analyzer, woo hoo!"), mStringIndex(0) {} + +C64SerialSimulationDataGenerator::~C64SerialSimulationDataGenerator() {} + +void C64SerialSimulationDataGenerator::Initialize( + U32 simulation_sample_rate, C64SerialAnalyzerSettings *settings) { + mSimulationSampleRateHz = simulation_sample_rate; + mSettings = settings; + + mSerialSimulationData.SetChannel(mSettings->mDataChannel); + mSerialSimulationData.SetSampleRate(simulation_sample_rate); + mSerialSimulationData.SetInitialBitState(BIT_HIGH); +} + +U32 C64SerialSimulationDataGenerator::GenerateSimulationData( + U64 largest_sample_requested, U32 sample_rate, + SimulationChannelDescriptor **simulation_channel) { + U64 adjusted_largest_sample_requested = + AnalyzerHelpers::AdjustSimulationTargetSample( + largest_sample_requested, sample_rate, mSimulationSampleRateHz); + + while (mSerialSimulationData.GetCurrentSampleNumber() < + adjusted_largest_sample_requested) { + CreateSerialByte(); + } + + *simulation_channel = &mSerialSimulationData; + return 1; +} + +void C64SerialSimulationDataGenerator::CreateSerialByte() { + U32 samples_per_bit = mSimulationSampleRateHz / 15000; + + U8 byte = mSerialText[mStringIndex]; + mStringIndex++; + if (mStringIndex == mSerialText.size()) + mStringIndex = 0; + + // we're currenty high + // let's move forward a little + mSerialSimulationData.Advance(samples_per_bit * 10); + + mSerialSimulationData.Transition(); // low-going edge for start bit + mSerialSimulationData.Advance(samples_per_bit); // add start bit time + + U8 mask = 0x1 << 7; + for (U32 i = 0; i < 8; i++) { + if ((byte & mask) != 0) + mSerialSimulationData.TransitionIfNeeded(BIT_HIGH); + else + mSerialSimulationData.TransitionIfNeeded(BIT_LOW); + + mSerialSimulationData.Advance(samples_per_bit); + mask = mask >> 1; + } + + mSerialSimulationData.TransitionIfNeeded(BIT_HIGH); // we need to end high + + // lets pad the end a bit for the stop bit: + mSerialSimulationData.Advance(samples_per_bit); +} diff --git a/source/C64SerialSimulationDataGenerator.h b/source/C64SerialSimulationDataGenerator.h new file mode 100644 index 0000000..f4e4e38 --- /dev/null +++ b/source/C64SerialSimulationDataGenerator.h @@ -0,0 +1,29 @@ +#ifndef C64SERIAL_SIMULATION_DATA_GENERATOR +#define C64SERIAL_SIMULATION_DATA_GENERATOR + +#include +#include +class C64SerialAnalyzerSettings; + +class C64SerialSimulationDataGenerator +{ +public: + C64SerialSimulationDataGenerator(); + ~C64SerialSimulationDataGenerator(); + + void Initialize( U32 simulation_sample_rate, C64SerialAnalyzerSettings* settings ); + U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel ); + +protected: + C64SerialAnalyzerSettings* mSettings; + U32 mSimulationSampleRateHz; + +protected: + void CreateSerialByte(); + std::string mSerialText; + U32 mStringIndex; + + SimulationChannelDescriptor mSerialSimulationData; + +}; +#endif //C64SERIAL_SIMULATION_DATA_GENERATOR \ No newline at end of file diff --git a/source/SimpleSerialAnalyzer.cpp b/source/SimpleSerialAnalyzer.cpp deleted file mode 100644 index ff54965..0000000 --- a/source/SimpleSerialAnalyzer.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "SimpleSerialAnalyzer.h" -#include "SimpleSerialAnalyzerSettings.h" -#include - -SimpleSerialAnalyzer::SimpleSerialAnalyzer() -: Analyzer2(), - mSettings( new SimpleSerialAnalyzerSettings() ), - mSimulationInitilized( false ) -{ - SetAnalyzerSettings( mSettings.get() ); -} - -SimpleSerialAnalyzer::~SimpleSerialAnalyzer() -{ - KillThread(); -} - -void SimpleSerialAnalyzer::SetupResults() -{ - mResults.reset( new SimpleSerialAnalyzerResults( this, mSettings.get() ) ); - SetAnalyzerResults( mResults.get() ); - mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel ); -} - -void SimpleSerialAnalyzer::WorkerThread() -{ - mSampleRateHz = GetSampleRate(); - - mSerial = GetAnalyzerChannelData( mSettings->mInputChannel ); - - if( mSerial->GetBitState() == BIT_LOW ) - mSerial->AdvanceToNextEdge(); - - U32 samples_per_bit = mSampleRateHz / mSettings->mBitRate; - U32 samples_to_first_center_of_first_data_bit = U32( 1.5 * double( mSampleRateHz ) / double( mSettings->mBitRate ) ); - - for( ; ; ) - { - U8 data = 0; - U8 mask = 1 << 7; - - mSerial->AdvanceToNextEdge(); //falling edge -- beginning of the start bit - - U64 starting_sample = mSerial->GetSampleNumber(); - - mSerial->Advance( samples_to_first_center_of_first_data_bit ); - - for( U32 i=0; i<8; i++ ) - { - //let's put a dot exactly where we sample this bit: - mResults->AddMarker( mSerial->GetSampleNumber(), AnalyzerResults::Dot, mSettings->mInputChannel ); - - if( mSerial->GetBitState() == BIT_HIGH ) - data |= mask; - - mSerial->Advance( samples_per_bit ); - - mask = mask >> 1; - } - - - //we have a byte to save. - Frame frame; - frame.mData1 = data; - frame.mFlags = 0; - frame.mStartingSampleInclusive = starting_sample; - frame.mEndingSampleInclusive = mSerial->GetSampleNumber(); - - mResults->AddFrame( frame ); - mResults->CommitResults(); - ReportProgress( frame.mEndingSampleInclusive ); - } -} - -bool SimpleSerialAnalyzer::NeedsRerun() -{ - return false; -} - -U32 SimpleSerialAnalyzer::GenerateSimulationData( U64 minimum_sample_index, U32 device_sample_rate, SimulationChannelDescriptor** simulation_channels ) -{ - if( mSimulationInitilized == false ) - { - mSimulationDataGenerator.Initialize( GetSimulationSampleRate(), mSettings.get() ); - mSimulationInitilized = true; - } - - return mSimulationDataGenerator.GenerateSimulationData( minimum_sample_index, device_sample_rate, simulation_channels ); -} - -U32 SimpleSerialAnalyzer::GetMinimumSampleRateHz() -{ - return mSettings->mBitRate * 4; -} - -const char* SimpleSerialAnalyzer::GetAnalyzerName() const -{ - return "Simple Serial"; -} - -const char* GetAnalyzerName() -{ - return "Simple Serial"; -} - -Analyzer* CreateAnalyzer() -{ - return new SimpleSerialAnalyzer(); -} - -void DestroyAnalyzer( Analyzer* analyzer ) -{ - delete analyzer; -} \ No newline at end of file diff --git a/source/SimpleSerialAnalyzer.h b/source/SimpleSerialAnalyzer.h deleted file mode 100644 index 69ae85d..0000000 --- a/source/SimpleSerialAnalyzer.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SIMPLESERIAL_ANALYZER_H -#define SIMPLESERIAL_ANALYZER_H - -#include -#include "SimpleSerialAnalyzerResults.h" -#include "SimpleSerialSimulationDataGenerator.h" - -class SimpleSerialAnalyzerSettings; -class ANALYZER_EXPORT SimpleSerialAnalyzer : public Analyzer2 -{ -public: - SimpleSerialAnalyzer(); - virtual ~SimpleSerialAnalyzer(); - - virtual void SetupResults(); - virtual void WorkerThread(); - - virtual U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channels ); - virtual U32 GetMinimumSampleRateHz(); - - virtual const char* GetAnalyzerName() const; - virtual bool NeedsRerun(); - -protected: //vars - std::auto_ptr< SimpleSerialAnalyzerSettings > mSettings; - std::auto_ptr< SimpleSerialAnalyzerResults > mResults; - AnalyzerChannelData* mSerial; - - SimpleSerialSimulationDataGenerator mSimulationDataGenerator; - bool mSimulationInitilized; - - //Serial analysis vars: - U32 mSampleRateHz; - U32 mStartOfStopBitOffset; - U32 mEndOfStopBitOffset; -}; - -extern "C" ANALYZER_EXPORT const char* __cdecl GetAnalyzerName(); -extern "C" ANALYZER_EXPORT Analyzer* __cdecl CreateAnalyzer( ); -extern "C" ANALYZER_EXPORT void __cdecl DestroyAnalyzer( Analyzer* analyzer ); - -#endif //SIMPLESERIAL_ANALYZER_H diff --git a/source/SimpleSerialAnalyzerResults.cpp b/source/SimpleSerialAnalyzerResults.cpp deleted file mode 100644 index 4e81695..0000000 --- a/source/SimpleSerialAnalyzerResults.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "SimpleSerialAnalyzerResults.h" -#include -#include "SimpleSerialAnalyzer.h" -#include "SimpleSerialAnalyzerSettings.h" -#include -#include - -SimpleSerialAnalyzerResults::SimpleSerialAnalyzerResults( SimpleSerialAnalyzer* analyzer, SimpleSerialAnalyzerSettings* settings ) -: AnalyzerResults(), - mSettings( settings ), - mAnalyzer( analyzer ) -{ -} - -SimpleSerialAnalyzerResults::~SimpleSerialAnalyzerResults() -{ -} - -void SimpleSerialAnalyzerResults::GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base ) -{ - ClearResultStrings(); - Frame frame = GetFrame( frame_index ); - - char number_str[128]; - AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); - AddResultString( number_str ); -} - -void SimpleSerialAnalyzerResults::GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id ) -{ - std::ofstream file_stream( file, std::ios::out ); - - U64 trigger_sample = mAnalyzer->GetTriggerSample(); - U32 sample_rate = mAnalyzer->GetSampleRate(); - - file_stream << "Time [s],Value" << std::endl; - - U64 num_frames = GetNumFrames(); - for( U32 i=0; i < num_frames; i++ ) - { - Frame frame = GetFrame( i ); - - char time_str[128]; - AnalyzerHelpers::GetTimeString( frame.mStartingSampleInclusive, trigger_sample, sample_rate, time_str, 128 ); - - char number_str[128]; - AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); - - file_stream << time_str << "," << number_str << std::endl; - - if( UpdateExportProgressAndCheckForCancel( i, num_frames ) == true ) - { - file_stream.close(); - return; - } - } - - file_stream.close(); -} - -void SimpleSerialAnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayBase display_base ) -{ -#ifdef SUPPORTS_PROTOCOL_SEARCH - Frame frame = GetFrame( frame_index ); - ClearTabularText(); - - char number_str[128]; - AnalyzerHelpers::GetNumberString( frame.mData1, display_base, 8, number_str, 128 ); - AddTabularText( number_str ); -#endif -} - -void SimpleSerialAnalyzerResults::GeneratePacketTabularText( U64 packet_id, DisplayBase display_base ) -{ - //not supported - -} - -void SimpleSerialAnalyzerResults::GenerateTransactionTabularText( U64 transaction_id, DisplayBase display_base ) -{ - //not supported -} \ No newline at end of file diff --git a/source/SimpleSerialAnalyzerSettings.cpp b/source/SimpleSerialAnalyzerSettings.cpp deleted file mode 100644 index 174dc7d..0000000 --- a/source/SimpleSerialAnalyzerSettings.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "SimpleSerialAnalyzerSettings.h" -#include - - -SimpleSerialAnalyzerSettings::SimpleSerialAnalyzerSettings() -: mInputChannel( UNDEFINED_CHANNEL ), - mBitRate( 9600 ) -{ - mInputChannelInterface.reset( new AnalyzerSettingInterfaceChannel() ); - mInputChannelInterface->SetTitleAndTooltip( "Serial", "Standard Simple Serial" ); - mInputChannelInterface->SetChannel( mInputChannel ); - - mBitRateInterface.reset( new AnalyzerSettingInterfaceInteger() ); - mBitRateInterface->SetTitleAndTooltip( "Bit Rate (Bits/S)", "Specify the bit rate in bits per second." ); - mBitRateInterface->SetMax( 6000000 ); - mBitRateInterface->SetMin( 1 ); - mBitRateInterface->SetInteger( mBitRate ); - - AddInterface( mInputChannelInterface.get() ); - AddInterface( mBitRateInterface.get() ); - - AddExportOption( 0, "Export as text/csv file" ); - AddExportExtension( 0, "text", "txt" ); - AddExportExtension( 0, "csv", "csv" ); - - ClearChannels(); - AddChannel( mInputChannel, "Serial", false ); -} - -SimpleSerialAnalyzerSettings::~SimpleSerialAnalyzerSettings() -{ -} - -bool SimpleSerialAnalyzerSettings::SetSettingsFromInterfaces() -{ - mInputChannel = mInputChannelInterface->GetChannel(); - mBitRate = mBitRateInterface->GetInteger(); - - ClearChannels(); - AddChannel( mInputChannel, "Simple Serial", true ); - - return true; -} - -void SimpleSerialAnalyzerSettings::UpdateInterfacesFromSettings() -{ - mInputChannelInterface->SetChannel( mInputChannel ); - mBitRateInterface->SetInteger( mBitRate ); -} - -void SimpleSerialAnalyzerSettings::LoadSettings( const char* settings ) -{ - SimpleArchive text_archive; - text_archive.SetString( settings ); - - text_archive >> mInputChannel; - text_archive >> mBitRate; - - ClearChannels(); - AddChannel( mInputChannel, "Simple Serial", true ); - - UpdateInterfacesFromSettings(); -} - -const char* SimpleSerialAnalyzerSettings::SaveSettings() -{ - SimpleArchive text_archive; - - text_archive << mInputChannel; - text_archive << mBitRate; - - return SetReturnString( text_archive.GetString() ); -} diff --git a/source/SimpleSerialAnalyzerSettings.h b/source/SimpleSerialAnalyzerSettings.h deleted file mode 100644 index 1b34136..0000000 --- a/source/SimpleSerialAnalyzerSettings.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SIMPLESERIAL_ANALYZER_SETTINGS -#define SIMPLESERIAL_ANALYZER_SETTINGS - -#include -#include - -class SimpleSerialAnalyzerSettings : public AnalyzerSettings -{ -public: - SimpleSerialAnalyzerSettings(); - virtual ~SimpleSerialAnalyzerSettings(); - - virtual bool SetSettingsFromInterfaces(); - void UpdateInterfacesFromSettings(); - virtual void LoadSettings( const char* settings ); - virtual const char* SaveSettings(); - - - Channel mInputChannel; - U32 mBitRate; - -protected: - std::auto_ptr< AnalyzerSettingInterfaceChannel > mInputChannelInterface; - std::auto_ptr< AnalyzerSettingInterfaceInteger > mBitRateInterface; -}; - -#endif //SIMPLESERIAL_ANALYZER_SETTINGS diff --git a/source/SimpleSerialSimulationDataGenerator.cpp b/source/SimpleSerialSimulationDataGenerator.cpp deleted file mode 100644 index d9bab05..0000000 --- a/source/SimpleSerialSimulationDataGenerator.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "SimpleSerialSimulationDataGenerator.h" -#include "SimpleSerialAnalyzerSettings.h" - -#include - -SimpleSerialSimulationDataGenerator::SimpleSerialSimulationDataGenerator() -: mSerialText( "My first analyzer, woo hoo!" ), - mStringIndex( 0 ) -{ -} - -SimpleSerialSimulationDataGenerator::~SimpleSerialSimulationDataGenerator() -{ -} - -void SimpleSerialSimulationDataGenerator::Initialize( U32 simulation_sample_rate, SimpleSerialAnalyzerSettings* settings ) -{ - mSimulationSampleRateHz = simulation_sample_rate; - mSettings = settings; - - mSerialSimulationData.SetChannel( mSettings->mInputChannel ); - mSerialSimulationData.SetSampleRate( simulation_sample_rate ); - mSerialSimulationData.SetInitialBitState( BIT_HIGH ); -} - -U32 SimpleSerialSimulationDataGenerator::GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel ) -{ - U64 adjusted_largest_sample_requested = AnalyzerHelpers::AdjustSimulationTargetSample( largest_sample_requested, sample_rate, mSimulationSampleRateHz ); - - while( mSerialSimulationData.GetCurrentSampleNumber() < adjusted_largest_sample_requested ) - { - CreateSerialByte(); - } - - *simulation_channel = &mSerialSimulationData; - return 1; -} - -void SimpleSerialSimulationDataGenerator::CreateSerialByte() -{ - U32 samples_per_bit = mSimulationSampleRateHz / mSettings->mBitRate; - - U8 byte = mSerialText[ mStringIndex ]; - mStringIndex++; - if( mStringIndex == mSerialText.size() ) - mStringIndex = 0; - - //we're currenty high - //let's move forward a little - mSerialSimulationData.Advance( samples_per_bit * 10 ); - - mSerialSimulationData.Transition(); //low-going edge for start bit - mSerialSimulationData.Advance( samples_per_bit ); //add start bit time - - U8 mask = 0x1 << 7; - for( U32 i=0; i<8; i++ ) - { - if( ( byte & mask ) != 0 ) - mSerialSimulationData.TransitionIfNeeded( BIT_HIGH ); - else - mSerialSimulationData.TransitionIfNeeded( BIT_LOW ); - - mSerialSimulationData.Advance( samples_per_bit ); - mask = mask >> 1; - } - - mSerialSimulationData.TransitionIfNeeded( BIT_HIGH ); //we need to end high - - //lets pad the end a bit for the stop bit: - mSerialSimulationData.Advance( samples_per_bit ); -} diff --git a/source/SimpleSerialSimulationDataGenerator.h b/source/SimpleSerialSimulationDataGenerator.h deleted file mode 100644 index c5dc2e9..0000000 --- a/source/SimpleSerialSimulationDataGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SIMPLESERIAL_SIMULATION_DATA_GENERATOR -#define SIMPLESERIAL_SIMULATION_DATA_GENERATOR - -#include -#include -class SimpleSerialAnalyzerSettings; - -class SimpleSerialSimulationDataGenerator -{ -public: - SimpleSerialSimulationDataGenerator(); - ~SimpleSerialSimulationDataGenerator(); - - void Initialize( U32 simulation_sample_rate, SimpleSerialAnalyzerSettings* settings ); - U32 GenerateSimulationData( U64 newest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel ); - -protected: - SimpleSerialAnalyzerSettings* mSettings; - U32 mSimulationSampleRateHz; - -protected: - void CreateSerialByte(); - std::string mSerialText; - U32 mStringIndex; - - SimulationChannelDescriptor mSerialSimulationData; - -}; -#endif //SIMPLESERIAL_SIMULATION_DATA_GENERATOR \ No newline at end of file