gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

hdi08Queue.cpp (1961B)


      1 #include "hdi08Queue.h"
      2 
      3 #include "dsp56kEmu/hdi08.h"
      4 
      5 namespace virusLib
      6 {
      7 	Hdi08Queue::Hdi08Queue(dsp56k::HDI08& _hdi08) : m_hdi08(_hdi08)
      8 	{
      9 	}
     10 
     11 	void Hdi08Queue::writeRX(const std::vector<dsp56k::TWord>& _data)
     12 	{
     13 		if(_data.empty())
     14 			return;
     15 
     16 		writeRX(&_data.front(), _data.size());
     17 	}
     18 
     19 	void Hdi08Queue::writeRX(const dsp56k::TWord* _data, size_t _count)
     20 	{
     21 		if(_count == 0 || !_data)
     22 			return;
     23 
     24 		std::lock_guard lock(m_mutex);
     25 
     26 		m_dataRX.push_back(_data[0] | m_nextHostFlags);
     27 		m_nextHostFlags = 0;
     28 
     29 		for(size_t i=1; i<_count; ++i)
     30 			m_dataRX.push_back(_data[i]);
     31 
     32 		sendPendingData();
     33 	}
     34 
     35 	void Hdi08Queue::writeHostFlags(uint8_t _flag0, uint8_t _flag1)
     36 	{
     37 		std::lock_guard lock(m_mutex);
     38 
     39 		if(m_lastHostFlag0 == _flag0 && m_lastHostFlag1 == _flag1)
     40 			return;
     41 
     42 		m_lastHostFlag0 = _flag0;
     43 		m_lastHostFlag1 = _flag1;
     44 
     45 		m_nextHostFlags |= static_cast<dsp56k::TWord>(_flag0) << 24;
     46 		m_nextHostFlags |= static_cast<dsp56k::TWord>(_flag1) << 25;
     47 		m_nextHostFlags |= 0x80000000;
     48 	}
     49 
     50 	void Hdi08Queue::exec()
     51 	{
     52 		std::lock_guard lock(m_mutex);
     53 
     54 		sendPendingData();
     55 	}
     56 
     57 	bool Hdi08Queue::rxEmpty() const
     58 	{
     59 		std::lock_guard lock(m_mutex);
     60 
     61 		if(!m_dataRX.empty())
     62 			return false;
     63 
     64 		if(m_hdi08.hasRXData())
     65 			return false;
     66 		return true;
     67 	}
     68 
     69 	bool Hdi08Queue::rxFull() const
     70 	{
     71 		return m_hdi08.dataRXFull();
     72 	}
     73 
     74 	bool Hdi08Queue::needsToWaitforHostFlags(uint8_t _flag0, uint8_t _flag1) const
     75 	{
     76 		return m_hdi08.needsToWaitForHostFlags(_flag0, _flag1);
     77 	}
     78 
     79 	void Hdi08Queue::sendPendingData()
     80 	{
     81 		while(!m_dataRX.empty() && !rxFull())
     82 		{
     83 			auto d = m_dataRX.front();
     84 
     85 			if(d & 0x80000000)
     86 			{
     87 				const auto hostFlag0 = static_cast<uint8_t>((d >> 24) & 1);
     88 				const auto hostFlag1 = static_cast<uint8_t>((d >> 25) & 1);
     89 
     90 				if(needsToWaitforHostFlags(hostFlag0, hostFlag1))
     91 					break;
     92 
     93 				m_hdi08.setHostFlagsWithWait(hostFlag0, hostFlag1);
     94 
     95 				d &= 0xffffff;
     96 			}
     97 
     98 			m_hdi08.writeRX(&d, 1);
     99 
    100 			m_dataRX.pop_front();
    101 		}
    102 	}
    103 }