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 }