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

xtUc.cpp (5213B)


      1 #include "xtUc.h"
      2 
      3 #include <cassert>
      4 #include <cstring>
      5 
      6 #include "xtRom.h"
      7 
      8 #include "mc68k/logging.h"
      9 
     10 #define MC68K_CLASS xt::XtUc
     11 #include "mc68k/musashiEntry.h"
     12 
     13 #include "dsp56kEmu/utils.h"
     14 
     15 namespace xt
     16 {
     17 	XtUc::XtUc(const Rom& _rom)
     18 	: m_flash(m_romRuntimeData.data(), m_romRuntimeData.size(), false, true)
     19 	, m_pic(*this, m_lcd)
     20 	{
     21 		if(!_rom.isValid())
     22 			return;
     23 
     24 		memcpy(m_romRuntimeData.data(), _rom.getData().data(), g_romSize);
     25 		m_memory.fill(0);
     26 
     27 //		dumpAssembly("xt_68k.asm", g_romAddr, g_romSize);
     28 
     29 		reset();
     30 		setPC(0x100100);
     31 
     32 		getPortGP().setWriteTXCallback([this](const mc68k::Port&)
     33 		{
     34 //			onPortGPWritten();
     35 		});
     36 
     37 		getPortE().setWriteTXCallback([this](const mc68k::Port&)
     38 		{
     39 //			onPortEWritten();
     40 		});
     41 
     42 		getPortF().setWriteTXCallback([this](const mc68k::Port&)
     43 		{
     44 //			onPortFWritten();
     45 		});
     46 
     47 		getPortQS().setDirectionChangeCallback([this](const mc68k::Port&)
     48 		{
     49 			onPortQSWritten();
     50 		});
     51 
     52 		getPortQS().setWriteTXCallback([this](const mc68k::Port&)
     53 		{
     54 			onPortQSWritten();
     55 		});
     56 	}
     57 
     58 	uint32_t XtUc::exec()
     59 	{
     60 //		LOG("PC: " << HEX(getPC()));
     61 		const auto cycles = Mc68k::exec();
     62 		m_hdiA.exec(cycles);
     63 		return cycles;
     64 	}
     65 
     66 	uint16_t XtUc::readImm16(const uint32_t _addr)
     67 	{
     68 		const auto addr = _addr & g_addrMask;
     69 
     70 		if(addr < g_ramSize)
     71 		{
     72 			return mc68k::memoryOps::readU16(m_memory.data(), addr);
     73 		}
     74 
     75 		if(addr >= g_romAddr && addr < g_romAddr + Rom::Size)
     76 		{
     77 			const auto r = mc68k::memoryOps::readU16(m_romRuntimeData.data(), addr - g_romAddr);
     78 //			LOG("read16 from ROM addr=" << HEXN(_addr, 8) << " val=" << HEXN(r, 4));
     79 			return r;
     80 		}
     81 #ifdef _DEBUG
     82 		dsp56k::nativeDebugBreak();
     83 #endif
     84 		return 0;
     85 	}
     86 
     87 	uint16_t XtUc::read16(const uint32_t _addr)
     88 	{
     89 		const auto addr = _addr & g_addrMask;
     90 
     91 		if(addr < g_ramSize)
     92 		{
     93 			return mc68k::memoryOps::readU16(m_memory.data(), addr);
     94 		}
     95 
     96 		if(addr >= g_romAddr && addr < g_romAddr + Rom::Size)
     97 		{
     98 			const auto r = mc68k::memoryOps::readU16(m_romRuntimeData.data(), addr - g_romAddr);
     99 //			LOG("read16 from ROM addr=" << HEXN(_addr, 8) << " val=" << HEXN(r, 4));
    100 			return r;
    101 		}
    102 
    103 		const auto pa = static_cast<mc68k::PeriphAddress>(addr & mc68k::g_peripheralMask);
    104 
    105 		if (m_hdiA.isInRange(pa))
    106 			return m_hdiA.read16(pa);
    107 
    108 //		LOG("read16 addr=" << HEXN(_addr, 8) << ", pc=" << HEXN(getPC(), 8));
    109 
    110 		return Mc68k::read16(addr);
    111 	}
    112 
    113 	uint8_t XtUc::read8(const uint32_t _addr)
    114 	{
    115 		const auto addr = _addr & g_addrMask;
    116 
    117 		if(addr < g_ramSize)
    118 			return m_memory[addr];
    119 
    120 		if(addr >= g_romAddr && addr < g_romAddr + Rom::Size)
    121 			return m_romRuntimeData[addr - g_romAddr];
    122 
    123 		const auto pa = static_cast<mc68k::PeriphAddress>(addr & mc68k::g_peripheralMask);
    124 
    125 		if(m_hdiA.isInRange(pa))
    126 			return m_hdiA.read8(pa);
    127 
    128 //		LOG("read8 addr=" << HEXN(addr, 8) << ", pc=" << HEXN(getPC(), 8));
    129 
    130 		return Mc68k::read8(addr);
    131 	}
    132 
    133 	void XtUc::write16(const uint32_t _addr, uint16_t val)
    134 	{
    135 		const auto addr = _addr & g_addrMask;
    136 
    137 		if(addr < g_ramSize)
    138 		{
    139 			mc68k::memoryOps::writeU16(m_memory.data(), addr, val);
    140 			return;
    141 		}
    142 
    143 		if(addr >= g_romAddr && addr < g_romAddr + Rom::Size)
    144 		{
    145 #if defined(_DEBUG) && defined(_WIN32)
    146 			MCLOG("write16 TO ROM addr=" << MCHEXN(addr, 8) << ", value=" << MCHEXN(val,4) << ", pc=" << MCHEXN(getPC(), 8));
    147 #endif
    148 			m_flash.write(addr - g_romAddr, val);
    149 			return;
    150 		}
    151 
    152 		const auto pa = static_cast<mc68k::PeriphAddress>(addr & mc68k::g_peripheralMask);
    153 
    154 		if (m_hdiA.isInRange(pa))
    155 		{
    156 			m_hdiA.write16(pa, val);
    157 			return;
    158 		}
    159 
    160 		Mc68k::write16(addr, val);
    161 	}
    162 
    163 	void XtUc::write8(const uint32_t _addr, uint8_t val)
    164 	{
    165 		const auto addr = _addr & g_addrMask;
    166 
    167 		if(addr < g_ramSize)
    168 		{
    169 			m_memory[addr] = val;
    170 			return;
    171 		}
    172 
    173 		if(addr >= g_romAddr && addr < g_romAddr + Rom::Size)
    174 		{
    175 #if defined(_DEBUG) && defined(_WIN32)
    176 			MCLOG("write8 TO ROM addr=" << MCHEXN(addr, 8) << ", value=" << MCHEXN(val,2) << ", pc=" << MCHEXN(getPC(), 8));
    177 #endif
    178 			m_flash.write(addr - g_romAddr, val);
    179 			return;
    180 		}
    181 
    182 //		LOG("write8 addr=" << HEXN(addr, 8) << ", value=" << HEXN(val,2) << ", pc=" << HEXN(getPC(), 8));
    183 
    184 		const auto pa = static_cast<mc68k::PeriphAddress>(addr & mc68k::g_peripheralMask);
    185 		if (m_hdiA.isInRange(pa))
    186 		{
    187 			m_hdiA.write8(pa, val);
    188 			return;
    189 		}
    190 
    191 		Mc68k::write8(addr, val);
    192 	}
    193 
    194 	void XtUc::onPortQSWritten()
    195 	{
    196 		const bool resetIsOutput = getPortQS().getDirection() & (1<<3);
    197 
    198 		if(resetIsOutput)
    199 		{
    200 			if(!(getPortQS().read() & (1<<3)))
    201 			{
    202 				if(!m_dspResetRequest)
    203 				{
    204 #ifdef _DEBUG
    205 					MCLOG("Request DSP RESET");
    206 #endif
    207 					m_dspResetRequest = true;
    208 					m_dspResetCompleted = false;
    209 				}
    210 			}
    211 		}
    212 		else
    213 		{
    214 			if(m_dspResetCompleted)
    215 			{
    216 				m_dspResetRequest = false;
    217 				getPortQS().writeRX(1<<3);
    218 			}
    219 		}
    220 	}
    221 
    222 	void XtUc::setButton(ButtonType _type, const bool _pressed)
    223 	{
    224 		m_pic.setButton(_type, _pressed);
    225 	}
    226 
    227 	void XtUc::setLcdDirtyCallback(const Pic::DirtyCallback& _callback)
    228 	{
    229 		m_pic.setLcdDirtyCallback(_callback);
    230 	}
    231 
    232 	void XtUc::setLedsDirtyCallback(const Pic::DirtyCallback& _callback)
    233 	{
    234 		m_pic.setLedsDirtyCallback(_callback);
    235 	}
    236 
    237 	bool XtUc::getLedState(LedType _led) const
    238 	{
    239 		return m_pic.getLedState(_led);
    240 	}
    241 
    242 	bool XtUc::getButton(ButtonType _button) const
    243 	{
    244 		return m_pic.getButton(_button);
    245 	}
    246 }