debugger-master/0000755000175000017500000000000013560352104013466 5ustar shevekshevekdebugger-master/src/0000755000175000017500000000000013560352104014255 5ustar shevekshevekdebugger-master/src/VDPRegViewer.h0000644000175000017500000000257113560352104016704 0ustar shevekshevek#ifndef VDPREGVIEWER_H #define VDPREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPRegistersExplained.h" #include class InteractiveButton; /** See remarks for the highlightDispatcher in VDPStatusRegViewer.h :-) */ class buttonHighlightDispatcher : public QObject { Q_OBJECT public: buttonHighlightDispatcher(); public slots: void receiveState(bool state); signals: void dispatchState(bool state); private: int counter; }; class VDPRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPRegisters { Q_OBJECT public: VDPRegViewer(QWidget* parent = 0); ~VDPRegViewer(); private: void decodeVDPRegs(); void decodeStatusVDPRegs(); void setRegisterVisible(int r, bool visible); void connectHighLights(); void doConnect(InteractiveButton* lab, buttonHighlightDispatcher* dis); buttonHighlightDispatcher* makeGroup( QList, InteractiveLabel*); void reGroup(InteractiveButton*, buttonHighlightDispatcher*); void monoGroup(InteractiveButton*, InteractiveLabel*); virtual void DataHexRequestReceived(); unsigned char* regs; buttonHighlightDispatcher* modeBitsDispat; int vdpid; public slots: void refresh(); void registerBitChanged(int reg, int bit, bool state); //quick hack while no autodetection... void on_VDPcomboBox_currentIndexChanged(int index); }; #endif /* VDPSTATUSREGVIEWER_H */ debugger-master/src/StackViewer.cpp0000644000175000017500000001071013560352104017207 0ustar shevekshevek#include "StackViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "Settings.h" #include #include #include #include class StackRequest : public ReadDebugBlockCommand { public: StackRequest(unsigned offset_, unsigned size, unsigned char* target, StackViewer& viewer_) : ReadDebugBlockCommand("memory", offset_, size, target) , offset(offset_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.memdataTransfered(this); } virtual void cancel() { viewer.transferCancelled(this); } // TODO public members are ugly!! unsigned offset; private: StackViewer& viewer; }; StackViewer::StackViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred)); setFont(Settings::get().font(Settings::HEX_FONT)); stackPointer = 0; topAddress = 0; waitingForData = false; vertScrollBar = new QScrollBar(Qt::Vertical, this); vertScrollBar->hide(); frameL = frameT = frameB = frameWidth(); frameR = frameL + vertScrollBar->sizeHint().width(); setMinimumHeight(frameT+frameB+fontMetrics().height()); connect(vertScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setLocation(int))); } QSize StackViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("FFFFWFFFF ") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB); } void StackViewer::setScrollBarValues() { vertScrollBar->setMinimum(stackPointer); visibleLines = double(height() - frameT - frameB) / fontMetrics().height(); int lines = (memoryLength - stackPointer) / 2; vertScrollBar->setMaximum(stackPointer + 2 * (lines - int(visibleLines))); vertScrollBar->setSingleStep(2); vertScrollBar->setPageStep(2 * int(visibleLines)); } void StackViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); setScrollBarValues(); vertScrollBar->setGeometry(width() - frameR, frameT, vertScrollBar->sizeHint().width(), height() - frameT - frameB); vertScrollBar->show(); // calc the number of lines that can be displayed // partial lines count as a whole } void StackViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); int h = fontMetrics().height(); int d = fontMetrics().descent(); // set font p.setPen(Qt::black); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); // calc layout (not optimal) int xAddr = frameL + 8; int xStack = xAddr + fontMetrics().width("FFFFF"); int y = frameT + h - 1; int address = topAddress; for (int i = 0; i < int(ceil(visibleLines)); ++i) { // print address QString hexStr; hexStr.sprintf("%04X", address); p.drawText(xAddr, y - d, hexStr); hexStr.sprintf("%02X%02X", memory[address + 1], memory[address]); p.drawText(xStack, y - d, hexStr); y += h; address += 2; if (address >= memoryLength - 1) break; } } void StackViewer::setData(unsigned char* memPtr, int memLength) { memory = memPtr; memoryLength = memLength; setScrollBarValues(); } void StackViewer::setLocation(int addr) { if (waitingForData) { // ignore return; } int start = (addr & ~1) | (stackPointer & 1); int size = 2 * int(ceil(visibleLines)); if (start + size >= memoryLength) { size = memoryLength - start; } StackRequest* req = new StackRequest(start, size, &memory[start], *this); CommClient::instance().sendCommand(req); waitingForData = true; } void StackViewer::setStackPointer(quint16 addr) { stackPointer = addr; setScrollBarValues(); vertScrollBar->setValue(addr); setLocation(addr); } void StackViewer::memdataTransfered(StackRequest* r) { topAddress = r->offset; update(); waitingForData = false; delete r; // check whether a new value is available if ((topAddress & ~1) != (vertScrollBar->value() & ~1)) { setLocation(vertScrollBar->value()); } } void StackViewer::transferCancelled(StackRequest* r) { waitingForData = false; delete r; } debugger-master/src/openmsx/0000755000175000017500000000000013560352104015746 5ustar shevekshevekdebugger-master/src/openmsx/MSXException.h0000644000175000017500000000114413560352104020445 0ustar shevekshevek#ifndef MSXEXCEPTION_H #define MSXEXCEPTION_H #include namespace openmsx { class MSXException { public: explicit MSXException(const std::string& message_) : message(message_) { } virtual ~MSXException() { } const std::string& getMessage() const { return message; } private: const std::string message; }; class FatalError { public: explicit FatalError(const std::string& message_) : message(message_) { } virtual ~FatalError() { } const std::string& getMessage() const { return message; } private: const std::string message; }; } // namespace openmsx #endif // MSXEXCEPTION_H debugger-master/src/openmsx/SspiUtils.h0000644000175000017500000000422013560352104020054 0ustar shevekshevek#ifndef SSPI_UTILS_HH #define SSPI_UTILS_HH #ifdef _WIN32 #include #ifdef __GNUC__ // MinGW32 requires that subauth.h be included before security.h, in order to define several things // This differs from VC++, which only needs security.h #include // MinGW32 does not define NEGOSSP_NAME_W anywhere. It should. #define NEGOSSP_NAME_W L"Negotiate" #endif #ifndef SECURITY_WIN32 #define SECURITY_WIN32 #endif #include #include #include "openmsx.h" // // NOTE: This file MUST be kept in sync between the openmsx and openmsx-debugger projects // namespace openmsx { namespace sspiutils { const unsigned STREAM_ERROR = 0xffffffff; class StreamWrapper { public: virtual uint32 Read(void* buffer, uint32 cb) = 0; virtual uint32 Write(void* buffer, uint32 cb) = 0; }; class SspiPackageBase { protected: CredHandle hCreds; CtxtHandle hContext; StreamWrapper& stream; const unsigned int cbMaxTokenSize; SspiPackageBase(StreamWrapper& stream, const SEC_WCHAR* securityPackage); ~SspiPackageBase(); }; // Generic access control flags, used with AccessCheck const DWORD ACCESS_READ = 0x1; const DWORD ACCESS_WRITE = 0x2; const DWORD ACCESS_EXECUTE = 0x4; const DWORD ACCESS_ALL = ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE; const GENERIC_MAPPING mapping = { ACCESS_READ, ACCESS_WRITE, ACCESS_EXECUTE, ACCESS_ALL }; void InitTokenContextBuffer(PSecBufferDesc pSecBufferDesc, PSecBuffer pSecBuffer); void ClearContextBuffers(PSecBufferDesc pSecBufferDesc); void DebugPrintSecurityStatus(const char* context, SECURITY_STATUS ss); void DebugPrintSecurityBool(const char* context, BOOL ret); void DebugPrintSecurityPackageName(PCtxtHandle phContext); void DebugPrintSecurityPrincipalName(PCtxtHandle phContext); void DebugPrintSecurityDescriptor(PSECURITY_DESCRIPTOR psd); PSECURITY_DESCRIPTOR CreateCurrentUserSecurityDescriptor(); unsigned long GetPackageMaxTokenSize(const SEC_WCHAR* package); bool SendChunk(StreamWrapper& stream, void* buffer, uint32 cb); bool RecvChunk(StreamWrapper& stream, std::vector& buffer, uint32 cbMaxSize); } // namespace sspiutils } // namespace openmsx #endif // _WIN32 #endif // SSPI_UTILS_HH debugger-master/src/openmsx/SspiUtils.cpp0000644000175000017500000001614213560352104020415 0ustar shevekshevek#ifdef _WIN32 #include "SspiUtils.h" #include "MSXException.h" #include #include // // NOTE: This file MUST be kept in sync between the openmsx and openmsx-debugger projects // namespace openmsx { namespace sspiutils { SspiPackageBase::SspiPackageBase(StreamWrapper& userStream, const SEC_WCHAR* securityPackage) : stream(userStream) , cbMaxTokenSize(GetPackageMaxTokenSize(securityPackage)) { memset(&hCreds, 0, sizeof(hCreds)); memset(&hContext, 0, sizeof(hContext)); if (!cbMaxTokenSize) { throw MSXException("GetPackageMaxTokenSize failed"); } } SspiPackageBase::~SspiPackageBase() { DeleteSecurityContext(&hContext); FreeCredentialsHandle(&hCreds); } void InitTokenContextBuffer(PSecBufferDesc pSecBufferDesc, PSecBuffer pSecBuffer) { pSecBuffer->BufferType = SECBUFFER_TOKEN; pSecBuffer->cbBuffer = 0; pSecBuffer->pvBuffer = nullptr; pSecBufferDesc->ulVersion = SECBUFFER_VERSION; pSecBufferDesc->cBuffers = 1; pSecBufferDesc->pBuffers = pSecBuffer; } void ClearContextBuffers(PSecBufferDesc pSecBufferDesc) { for (ULONG i = 0; i < pSecBufferDesc->cBuffers; i ++) { FreeContextBuffer(pSecBufferDesc->pBuffers[i].pvBuffer); pSecBufferDesc->pBuffers[i].cbBuffer = 0; pSecBufferDesc->pBuffers[i].pvBuffer = nullptr; } } void DebugPrintSecurityStatus(const char* context, SECURITY_STATUS ss) { (void)&context; (void)&ss; #ifdef DEBUG switch (ss) { case SEC_E_OK: PRT_DEBUG(context << ": SEC_E_OK"); break; case SEC_I_CONTINUE_NEEDED: PRT_DEBUG(context << ": SEC_I_CONTINUE_NEEDED"); break; case SEC_E_INVALID_TOKEN: PRT_DEBUG(context << ": SEC_E_INVALID_TOKEN"); break; case SEC_E_BUFFER_TOO_SMALL: PRT_DEBUG(context << ": SEC_E_BUFFER_TOO_SMALL"); break; case SEC_E_INVALID_HANDLE: PRT_DEBUG(context << ": SEC_E_INVALID_HANDLE"); break; case SEC_E_WRONG_PRINCIPAL: PRT_DEBUG(context << ": SEC_E_WRONG_PRINCIPAL"); break; default: PRT_DEBUG(context << ": " << ss); break; } #endif } void DebugPrintSecurityBool(const char* context, BOOL ret) { (void)&context; (void)&ret; #ifdef DEBUG if (ret) { PRT_DEBUG(context << ": true"); } else { PRT_DEBUG(context << ": false - " << GetLastError()); } #endif } void DebugPrintSecurityPackageName(PCtxtHandle phContext) { (void)&phContext; #ifdef DEBUG SecPkgContext_PackageInfoA package; SECURITY_STATUS ss = QueryContextAttributesA(phContext, SECPKG_ATTR_PACKAGE_INFO, &package); if (ss == SEC_E_OK) { PRT_DEBUG("Using " << package.PackageInfo->Name << " package"); } #endif } void DebugPrintSecurityPrincipalName(PCtxtHandle phContext) { (void)&phContext; #ifdef DEBUG SecPkgContext_NamesA name; SECURITY_STATUS ss = QueryContextAttributesA(phContext, SECPKG_ATTR_NAMES, &name); if (ss == SEC_E_OK) { PRT_DEBUG("Client principal " << name.sUserName); } #endif } void DebugPrintSecurityDescriptor(PSECURITY_DESCRIPTOR psd) { (void)&psd; #ifdef DEBUG char* sddl; BOOL ret = ConvertSecurityDescriptorToStringSecurityDescriptorA( psd, SDDL_REVISION, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, &sddl, nullptr); if (ret) { PRT_DEBUG("SecurityDescriptor: " << sddl); LocalFree(sddl); } #endif } // If successful, caller must free the results with LocalFree() // If unsuccessful, returns null PTOKEN_USER GetProcessToken() { PTOKEN_USER pToken = nullptr; HANDLE hProcessToken; BOOL ret = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hProcessToken); DebugPrintSecurityBool("OpenProcessToken", ret); if (ret) { DWORD cbToken; ret = GetTokenInformation(hProcessToken, TokenUser, nullptr, 0, &cbToken); assert(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && cbToken); pToken = (TOKEN_USER*)LocalAlloc(LMEM_ZEROINIT, cbToken); if (pToken) { ret = GetTokenInformation(hProcessToken, TokenUser, pToken, cbToken, &cbToken); DebugPrintSecurityBool("GetTokenInformation", ret); if (!ret) { LocalFree(pToken); pToken = nullptr; } } CloseHandle(hProcessToken); } return pToken; } // If successful, caller must free the results with LocalFree() // If unsuccessful, returns null PSECURITY_DESCRIPTOR CreateCurrentUserSecurityDescriptor() { PSECURITY_DESCRIPTOR psd = nullptr; PTOKEN_USER pToken = GetProcessToken(); if (pToken) { PSID pUserSid = pToken->User.Sid; const DWORD cbEachAce = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD); const DWORD cbACL = sizeof(ACL) + cbEachAce + GetLengthSid(pUserSid); // Allocate the SD and the ACL in one allocation, so we only have one buffer to manage // The SD structure ends with a pointer, so the start of the ACL will be well aligned BYTE* buffer = (BYTE*)LocalAlloc(LMEM_ZEROINIT, SECURITY_DESCRIPTOR_MIN_LENGTH + cbACL); if (buffer) { psd = (PSECURITY_DESCRIPTOR)buffer; PACL pacl = (PACL)(buffer + SECURITY_DESCRIPTOR_MIN_LENGTH); PACCESS_ALLOWED_ACE pUserAce; if (InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION) && InitializeAcl(pacl, cbACL, ACL_REVISION) && AddAccessAllowedAce(pacl, ACL_REVISION, ACCESS_ALL, pUserSid) && SetSecurityDescriptorDacl(psd, TRUE, pacl, FALSE) && // Need to set the Group and Owner on the SD in order to use it with AccessCheck() GetAce(pacl, 0, (void**)&pUserAce) && SetSecurityDescriptorGroup(psd, &pUserAce->SidStart, FALSE) && SetSecurityDescriptorOwner(psd, &pUserAce->SidStart, FALSE)) { buffer = nullptr; } else { psd = nullptr; } LocalFree(buffer); } LocalFree(pToken); } if (psd) { assert(IsValidSecurityDescriptor(psd)); DebugPrintSecurityDescriptor(psd); } return psd; } unsigned long GetPackageMaxTokenSize(const SEC_WCHAR* package) { PSecPkgInfoW pkgInfo; SECURITY_STATUS ss = QuerySecurityPackageInfoW(const_cast(package), &pkgInfo); DebugPrintSecurityStatus("QuerySecurityPackageInfoW", ss); if (ss != SEC_E_OK) { return 0; } unsigned long cbMaxToken = pkgInfo->cbMaxToken; FreeContextBuffer(pkgInfo); return cbMaxToken; } bool Send(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t sent = 0; while (sent < cb) { uint32_t ret = stream.Write((char*)buffer + sent, cb - sent); if (ret == STREAM_ERROR) { return false; } sent += ret; } return true; } bool SendChunk(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t nl = htonl(cb); if (!Send(stream, &nl, sizeof(nl))) { return false; } return Send(stream, buffer, cb); } bool Recv(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t recvd = 0; while (recvd < cb) { uint32_t ret = stream.Read((char*)buffer + recvd, cb - recvd); if (ret == STREAM_ERROR) { return false; } recvd += ret; } return true; } bool RecvChunkSize(StreamWrapper& stream, uint32_t* pcb) { uint32_t cb; bool ret = Recv(stream, &cb, sizeof(cb)); if (ret) { *pcb = ntohl(cb); } return ret; } bool RecvChunk(StreamWrapper& stream, std::vector& buffer, uint32_t cbMaxSize) { uint32_t cb; if (!RecvChunkSize(stream, &cb) || cb > cbMaxSize) { return false; } buffer.resize(cb); if (!Recv(stream, &buffer[0], cb)) { return false; } return true; } } // namespace sspiutils } // namespace openmsx #endif debugger-master/src/openmsx/QAbstractSocketStreamWrapper.h0000644000175000017500000000103213560352104023665 0ustar shevekshevek#ifndef QTCP_SOCKET_STREAM_WRAPPER_H #define QTCP_SOCKET_STREAM_WRAPPER_H #ifdef _WIN32 #include #include "SspiUtils.h" namespace openmsx { using namespace sspiutils; class QAbstractSocketStreamWrapper : public StreamWrapper { private: QAbstractSocket* sock; public: QAbstractSocketStreamWrapper(QAbstractSocket* userSock); unsigned int Read(void* buffer, unsigned int cb); unsigned int Write(void* buffer, unsigned int cb); }; } // namespace openmsx #endif // _WIN32 #endif // QTCP_SOCKET_STREAM_WRAPPER_H debugger-master/src/openmsx/QAbstractSocketStreamWrapper.cpp0000644000175000017500000000133113560352104024222 0ustar shevekshevek#ifdef _WIN32 #include "QAbstractSocketStreamWrapper.h" namespace openmsx { QAbstractSocketStreamWrapper::QAbstractSocketStreamWrapper(QAbstractSocket* userSock) : sock(userSock) { } unsigned int QAbstractSocketStreamWrapper::Read(void* buffer, unsigned int cb) { sock->waitForReadyRead(30); qint64 recvd = sock->read(static_cast(buffer), cb); if (recvd == -1) { return STREAM_ERROR; } return static_cast(recvd); } unsigned int QAbstractSocketStreamWrapper::Write(void* buffer, unsigned int cb) { qint64 sent = sock->write(static_cast(buffer), cb); if (sent == -1 || !sock->flush()) { return STREAM_ERROR; } return static_cast(sent); } } // namespace openmsx #endif debugger-master/src/openmsx/openmsx.h0000644000175000017500000000200613560352104017606 0ustar shevekshevek#ifndef OPENMSX_H #define OPENMSX_H // don't just always include this, saves about 1 minute build time!! #ifdef DEBUG #include #endif /// Namespace of the openMSX emulation core. /** openMSX: the MSX emulator that aims for perfection * * Copyrights: see AUTHORS file. * License: GPL. */ namespace openmsx { /** 4 bit integer */ typedef unsigned char nibble; /** 8 bit signed integer */ typedef signed char signed_byte; /** 8 bit unsigned integer */ typedef unsigned char byte; /** 16 bit signed integer */ typedef short signed_word; /** 16 bit unsigned integer */ typedef unsigned short word; /** 32 bit signed integer */ typedef int int32; /** 32 bit unsigned integer */ typedef unsigned uint32; /** 64 bit signed integer */ typedef long long int64; /** 64 bit unsigned integer */ typedef unsigned long long uint64; #ifdef DEBUG #define PRT_DEBUG(mes) \ do { \ std::cout << mes << std::endl; \ } while (0) #else #define PRT_DEBUG(mes) #endif } // namespace openmsx #endif // OPENMSX_H debugger-master/src/openmsx/node.mk0000644000175000017500000000024713560352104017227 0ustar shevekshevekinclude build/node-start.mk SRC_HDR:= \ QAbstractSocketStreamWrapper SspiNegotiateClient SspiUtils HDR_ONLY:= \ openmsx \ MSXException include build/node-end.mk debugger-master/src/openmsx/SspiNegotiateClient.h0000644000175000017500000000055713560352104022043 0ustar shevekshevek#ifndef SSPI_NEGOTIATE_CLIENT_H #define SSPI_NEGOTIATE_CLIENT_H #ifdef _WIN32 #include "SspiUtils.h" namespace openmsx { using namespace sspiutils; class SspiNegotiateClient : public SspiPackageBase { public: SspiNegotiateClient(StreamWrapper& clientStream); bool Authenticate(); }; } // namespace openmsx #endif // _WIN32 #endif // SSPI_NEGOTIATE_CLIENT_H debugger-master/src/openmsx/SspiNegotiateClient.cpp0000644000175000017500000000471713560352104022400 0ustar shevekshevek#ifdef _WIN32 #include "SspiNegotiateClient.h" #include "openmsx.h" namespace openmsx { SspiNegotiateClient::SspiNegotiateClient(StreamWrapper& clientStream) : SspiPackageBase(clientStream, NEGOSSP_NAME_W) { } bool SspiNegotiateClient::Authenticate() { TimeStamp tsCredsExpiry; SECURITY_STATUS ss = AcquireCredentialsHandleW( NULL, const_cast(NEGOSSP_NAME_W), SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &hCreds, &tsCredsExpiry); DebugPrintSecurityStatus("AcquireCredentialsHandleW", ss); if (ss != SEC_E_OK) { return false; } SecBufferDesc secClientBufferDesc, secServerBufferDesc; SecBuffer secClientBuffer, secServerBuffer; InitTokenContextBuffer(&secClientBufferDesc, &secClientBuffer); InitTokenContextBuffer(&secServerBufferDesc, &secServerBuffer); std::vector buffer; PCtxtHandle phContext = NULL; PSecBufferDesc psecServerBufferDesc = NULL; while (true) { ULONG fContextAttr; TimeStamp tsContextExpiry; ss = InitializeSecurityContextA( &hCreds, phContext, NULL, // To use Kerberos, we'll need an SPN here ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONNECTION | ISC_REQ_STREAM, 0, SECURITY_NETWORK_DREP, psecServerBufferDesc, 0, &hContext, &secClientBufferDesc, &fContextAttr, &tsContextExpiry); DebugPrintSecurityStatus("InitializeSecurityContextA", ss); if (ss != SEC_E_OK && ss != SEC_I_CONTINUE_NEEDED) { return false; } // If we have something for the server, send it if (secClientBuffer.cbBuffer) { PRT_DEBUG("Sending " << secClientBuffer.cbBuffer << " bytes to server"); bool ret = SendChunk(stream, secClientBuffer.pvBuffer, secClientBuffer.cbBuffer); ClearContextBuffers(&secClientBufferDesc); if (!ret) { PRT_DEBUG("SendChunk failed"); return false; } } // SEC_E_OK means that we're done if (ss == SEC_E_OK) { DebugPrintSecurityPackageName(&hContext); DebugPrintSecurityPrincipalName(&hContext); return true; } // Receive another buffer from the server PRT_DEBUG("Receiving server chunk"); bool ret = RecvChunk(stream, buffer, cbMaxTokenSize); if (!ret) { PRT_DEBUG("RecvChunk failed"); return false; } PRT_DEBUG("Received " << buffer.size() << " bytes"); // Another time around the loop secServerBuffer.cbBuffer = static_cast(buffer.size()); secServerBuffer.pvBuffer = &buffer[0]; phContext = &hContext; psecServerBufferDesc = &secServerBufferDesc; } } } // namespace openmsx #endif // _WIN32 debugger-master/src/DebugSession.cpp0000644000175000017500000000553513560352104017363 0ustar shevekshevek#include "DebugSession.h" #include #include #include #include DebugSession::DebugSession() : modified(false) { } bool DebugSession::existsAsFile() const { return !fileName.isEmpty(); } const QString& DebugSession::filename() const { return fileName; } bool DebugSession::isModified() const { if(fileName.isEmpty() && symTable.size() == 0) return false; else return modified; } Breakpoints& DebugSession::breakpoints() { return breaks; } SymbolTable& DebugSession::symbolTable() { return symTable; } void DebugSession::clear() { // clear everything symTable.clear(); breaks.clear(); fileName.clear(); modified = false; } void DebugSession::open(const QString& file) { QFile f(file); if (!f.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(0, tr("Open session ..."), tr("Cannot read file %1:\n%2.") .arg(file) .arg(f.errorString())); return; } // clear current project and start reading xml file clear(); QXmlStreamReader ses; ses.setDevice(&f); while (!ses.atEnd()) { ses.readNext(); if (ses.isStartElement() && (ses.name() == "DebugSession")) { // debug session data while (!ses.atEnd()) { ses.readNext(); // end tag if (ses.isEndElement()) break; // begin tag if (ses.isStartElement()) { if (ses.name() == "Symbols") { symTable.loadSymbols(ses); } else if (ses.name() == "Breakpoints") { breaks.loadBreakpoints(ses); } else { skipUnknownElement(ses); } } } } } fileName = file; modified = false; } void DebugSession::skipUnknownElement(QXmlStreamReader& ses) { while (!ses.atEnd()) { ses.readNext(); if (ses.isEndElement()) break; if (ses.isStartElement()) skipUnknownElement(ses); } } bool DebugSession::save() { return saveAs(fileName); } bool DebugSession::saveAs(const QString& newFileName) { // open file for save QFile file(newFileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(0, tr("Save session ..."), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } // start xml file QXmlStreamWriter ses; ses.setDevice(&file); ses.setAutoFormatting(true); ses.writeDTD(""); ses.writeStartElement("DebugSession"); ses.writeAttribute("version", "0.1"); // write symbols ses.writeStartElement("Symbols"); symTable.saveSymbols(ses); ses.writeEndElement(); // write breakpoints ses.writeStartElement("Breakpoints"); breaks.saveBreakpoints(ses); ses.writeEndElement(); // end ses.writeEndDocument(); modified = false; fileName = newFileName; // only set after successful save return true; } void DebugSession::sessionModified() { modified = true; } debugger-master/src/CommClient.cpp0000644000175000017500000000212013560352104017006 0ustar shevekshevek#include "CommClient.h" #include "OpenMSXConnection.h" CommClient::CommClient() : connection(NULL) { } CommClient::~CommClient() { closeConnection(); } CommClient& CommClient::instance() { static CommClient oneInstance; return oneInstance; } void CommClient::connectToOpenMSX(OpenMSXConnection* conn) { closeConnection(); connection = conn; connect(connection, SIGNAL(disconnected()), SLOT(closeConnection())); connect(connection, SIGNAL(logParsed(const QString&, const QString&)), SIGNAL(logParsed(const QString&, const QString&))); connect(connection, SIGNAL(updateParsed(const QString&, const QString&, const QString&)), SIGNAL(updateParsed(const QString&, const QString&, const QString&))); emit connectionReady(); } void CommClient::closeConnection() { if (connection) { connection->disconnect(this, SLOT(closeConnection())); delete connection; connection = NULL; emit connectionTerminated(); } } void CommClient::sendCommand(Command* command) { if (connection) { connection->sendCommand(command); } else { command->cancel(); } } debugger-master/src/DasmTables.h0000644000175000017500000000043713560352104016451 0ustar shevekshevek#ifndef DASMTABLES_H #define DASMTABLES_H extern const char* const mnemonic_xx_cb[256]; extern const char* const mnemonic_cb[256]; extern const char* const mnemonic_ed[256]; extern const char* const mnemonic_xx[256]; extern const char* const mnemonic_main[256]; #endif // DASMTABLES_H debugger-master/src/DockableWidgetLayout.h0000644000175000017500000000371313560352104020500 0ustar shevekshevek#ifndef DOCKABLEWIDGETLAYOUT_H #define DOCKABLEWIDGETLAYOUT_H #include #include class QLayoutItem; class DockableWidget; class QStringList; class DockableWidgetLayout : public QLayout { Q_OBJECT; public: enum DockSide { TOP, LEFT, RIGHT, BOTTOM }; DockableWidgetLayout(QWidget* parent = 0, int margin = 0, int spacing = -1); DockableWidgetLayout(int spacing); ~DockableWidgetLayout(); void addItem(QLayoutItem* item); void addItem(QLayoutItem* item, int index, DockSide side = RIGHT, int dist = 0, int w = -1, int h = -1); void addWidget(DockableWidget* widget, const QRect& rect); void addWidget(DockableWidget* widget, DockSide side, int distance, int width = -1, int height = -1); bool insertLocation(QRect& rect, const QSizePolicy& sizePol); QLayoutItem* itemAt(int index) const; QLayoutItem* takeAt(int index); int count() const; Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; QSize minimumSize() const; QSize maximumSize() const; void setGeometry(const QRect &rect); QSize sizeHint() const; void changed(); void getConfig(QStringList& list); private: class DockInfo { public: QRect bounds() const { return QRect(left, top, width, height); } int right() const { return left + width; } int bottom() const { return top + height; } DockableWidget* widget; QLayoutItem* item; DockSide dockSide; int dockDistance; int left; int top; int width; int height; bool useHintHeight; bool useHintWidth; }; QList dockedWidgets; int layoutWidth, layoutHeight; int minWidth, minHeight; int maxWidth, maxHeight; int checkWidth, checkHeight; void calcSizeLimits(); void sizeMove(int dx, int dy); void doLayout(bool check = false); bool insertLocation(QRect& rect, int& index, DockSide& side, const QSizePolicy& sizePol); bool overlaysWithFirstNWidgets(const QRect& r, int n) const; }; #endif // DOCKABLEWIDGETLAYOUT_H debugger-master/src/PreferencesDialog.ui0000644000175000017500000001352513560352104020203 0ustar shevekshevek PreferencesDialog 0 0 654 512 Preferences 9 6 Fonts 9 6 QAbstractItemView::SelectRows 0 6 0 6 false false Use default fixed font false Use custom font 0 6 7 0 0 0 0 80 QFrame::WinPanel QFrame::Sunken openMSX debugger! false Select custom font Select font color Qt::Vertical 20 40 0 6 Qt::Horizontal 131 31 Close okButton clicked() PreferencesDialog accept() 278 253 96 254 debugger-master/src/FlagsViewer.h0000644000175000017500000000112513560352104016643 0ustar shevekshevek#ifndef FLAGSVIEWER_H #define FLAGSVIEWER_H #include class QPainter; class QResizeEvent; class QPaintEvent; class QString; class FlagsViewer : public QFrame { Q_OBJECT; public: FlagsViewer(QWidget* parent = 0); QSize sizeHint() const; public slots: void setFlags(quint8 newFlags); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void drawValue(QPainter& p, int x, int y, const QString& str, const bool changed); int frameL, frameR, frameT, frameB; unsigned char flags; unsigned char flagsChanged; }; #endif // FLAGSVIEWER_H debugger-master/src/VDPRegistersExplained.ui0000644000175000017500000137363513560352104021011 0ustar shevekshevek VDPRegisters 0 0 820 777 Dialog QFrame::NoFrame QFrame::Raised 0 0 0 Qt::Horizontal 10 10 9 Mode registers 1 3 0 45 21 30 0 R#0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 0 FF Qt::AlignCenter 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) DG true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) IE2 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) IE1 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) M5 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) M4 true false 0 0 27 21 27 21 8 Used to change the display mode. M3 true false 0 0 27 21 27 21 8 register 0 bit 0 0 true false 45 21 30 0 R#1 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 1 FF Qt::AlignCenter 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) 0 true false false 0 0 27 21 27 21 8 When 1, screen display enabled. When 0, screen disabled. BL true false 0 0 27 21 27 21 8 Enables interrupt from Horizontal scanning line by Interrupt Enable 0. IE0 true false 0 0 27 21 27 21 8 Used to change the display mode. M1 true false 0 0 27 21 27 21 8 Used to change the display mode. M2 true false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 When 1, sprite size is 16 x 16. When 0, 8 x 8. SI true false 0 0 27 21 27 21 8 Sprite expansion; when 1: expanded. When 0, normal. MAG true false 45 21 30 0 R#8 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 8 FF Qt::AlignCenter 0 0 27 21 27 21 8 When 1, sets the color bus to input mode and enables mouse. MS true false 0 0 27 21 27 21 8 When 1, enables light pen. When 0, disables light pen. LP true false 0 0 27 21 27 21 8 Sets the color of code 0 to the color of the palette. TP true false 0 0 27 21 27 21 8 When 1, sets the color bus to input mode. When 0, sets the color bus to output mode. CB true false 0 0 27 21 27 21 8 Selects the type of Video RAM. 1 = 64K x 1 bit or 64K x 4 bits. 0 = 16K x 1 bit or 16K x 4 bits. VR true false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 When 1, disables display of sprites. When 0, displays sprites. SPD true false 0 0 27 21 27 21 8 When 1, sets black and white in 32 tones. When 0, sets color (available only with a composite encoder). BW true false 45 21 30 0 R#9 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 9 FF Qt::AlignCenter 0 0 27 21 27 21 8 When 1, sets the horizontal dot count to 212. When 0, sets the horizontal dot count to 192. LN true false false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 Selects simultaneous mode. S1 true false 0 0 27 21 27 21 8 Selects simultaneous mode. S0 true false 0 0 27 21 27 21 8 When 1, interlace (Complete NTSC timing) When 0, non-interlace (Incomplete NTSC timing) IL true false 0 0 27 21 27 21 8 When 1, displays two graphic screens interchangably by Even field/Odd field. When 0, displays the same graphic screen by Even field/Odd field. E0 true false 0 0 27 21 27 21 8 When 1, PAL (313 lines) When 0, NTSC (262 lines) (For RGB output only) NT true false 0 0 27 21 27 21 8 When 1, sets *DLCLK to input mode. When 0, sets *DLCLK to output mode. DC true false Qt::Vertical 20 4 V9958 Registers 1 3 0 45 21 30 0 R#25 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 25 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display adjust register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Video Command Mode</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Screen 2-4 as screen 8</p></body></html> CMD true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Attribute Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=No Attribute</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=With Attribute</p></body></html> VDS true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Attribute Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=No Attribute</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=With Attribute</p></body></html> YAE true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Mode Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal RGB</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=YJK System</p></body></html> YJK true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VRAM Access Waitstates</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Enable CPU Waitstate</p></body></html> WTE true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">H-Scroll Mask 8 Pixels</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Hide Leftmost Pixels</p></body></html> MSK true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">H-Scroll Screen Width</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=One page</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Two pages</p></body></html> SP2 true false 45 21 30 0 R#26 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 26 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display offset register 0 true false 0 0 27 21 27 21 8 Display offset register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H08 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H07 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H06 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H05 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H04 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H03 true false 45 21 30 0 R#27 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 27 FF Qt::AlignCenter 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H02 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H01 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H00 true false Qt::Vertical 20 4 Table Base Address Registers 1 3 0 45 21 30 0 R#2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 2 FF Qt::AlignCenter 0 0 27 21 27 21 8 Pattern name table base address register 0 true false false 0 0 27 21 27 21 8 Pattern name table base address register A16 true false 0 0 27 21 27 21 8 Pattern name table base address register A15 true false 0 0 27 21 27 21 8 Pattern name table base address register A14 true false 0 0 27 21 27 21 8 Pattern name table base address register A13 true false 0 0 27 21 27 21 8 Pattern name table base address register A12 true false 0 0 27 21 27 21 8 Pattern name table base address register A11 true false 0 0 27 21 27 21 8 Pattern name table base address register A10 true false 45 21 30 0 R#3 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 3 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color table base address register low A13 true false 0 0 27 21 27 21 8 Color table base address register low A12 true false 0 0 27 21 27 21 8 Color table base address register low A11 true false 0 0 27 21 27 21 8 Color table base address register low A10 true false 0 0 27 21 27 21 8 Color table base address register low A9 true false 0 0 27 21 27 21 8 Color table base address register low A8 true false 0 0 27 21 27 21 8 Color table base address register low A7 true false 0 0 27 21 27 21 8 Color table base address register low A6 true false 45 21 30 0 R#10 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 10 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high A16 true false 0 0 27 21 27 21 8 Color table base address register high A15 true false 0 0 27 21 27 21 8 Color table base address register high A14 true false 45 21 30 0 R#4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 4 FF Qt::AlignCenter 0 0 27 21 27 21 8 Pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Pattern generator table base address register A16 true false 0 0 27 21 27 21 8 Pattern generator table base address register A15 true false 0 0 27 21 27 21 8 Pattern generator table base address register A14 true false 0 0 27 21 27 21 8 Pattern generator table base address register A13 true false 0 0 27 21 27 21 8 Pattern generator table base address register A12 true false 0 0 27 21 27 21 8 Pattern generator table base address register A11 true false 45 21 30 0 R#5 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 5 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite attribute table base address register low A14 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A13 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A12 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A11 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A10 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A9 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A8 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A7 true false 45 21 30 0 R#11 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 11 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high A16 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high A15 true false 45 21 30 0 R#6 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 6 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A16 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A15 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A14 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A13 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A12 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A11 true false Qt::Horizontal 10 10 9 Color Registers QLayout::SetMinimumSize 0 0 1 3 60 21 30 0 R#7 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 7 FF Qt::AlignCenter 0 0 27 21 27 21 8 Text color/Back drop color register TC3 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC2 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC1 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC0 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD3 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD2 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD1 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD0 true false 60 21 30 0 R#12 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 12 FF Qt::AlignCenter 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T23 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T22 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T21 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T20 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC3 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC2 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC1 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC0 true false 60 21 30 0 R#13 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 13 FF Qt::AlignCenter 0 0 27 21 27 21 8 Blinking period register ON3 true false 0 0 27 21 27 21 8 Blinking period register ON2 true false 0 0 27 21 27 21 8 Blinking period register ON1 true false 0 0 27 21 27 21 8 Blinking period register ON0 true false 0 0 27 21 27 21 8 Blinking period register OF3 true false 0 0 27 21 27 21 8 Blinking period register OF2 true false 0 0 27 21 27 21 8 Blinking period register OF1 true false 0 0 27 21 27 21 8 Blinking period register OF0 true false 60 21 30 0 R#20 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 20 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 60 21 30 0 R#21 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 21 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 60 21 30 0 R#22 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 22 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 1 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 1 true false Qt::Vertical 20 4 Display Registers 0 0 1 3 45 21 30 0 R#18 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 18 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display adjust register V3 true false 0 0 27 21 27 21 8 Display adjust register V2 true false 0 0 27 21 27 21 8 Display adjust register V1 true false 0 0 27 21 27 21 8 Display adjust register V0 true false 0 0 27 21 27 21 8 Display adjust register H3 true false 0 0 27 21 27 21 8 Display adjust register H2 true false 0 0 27 21 27 21 8 Display adjust register H1 true false 0 0 27 21 27 21 8 Display adjust register H0 true false 45 21 30 0 R#23 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 23 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display offset register DO7 true false 0 0 27 21 27 21 8 Display offset register DO6 true false 0 0 27 21 27 21 8 Display offset register DO5 true false 0 0 27 21 27 21 8 Display offset register DO4 true false 0 0 27 21 27 21 8 Display offset register DO3 true false 0 0 27 21 27 21 8 Display offset register DO2 true false 0 0 27 21 27 21 8 Display offset register DO1 true false 0 0 27 21 27 21 8 Display offset register DO0 true false 45 21 30 0 R#19 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 19 FF Qt::AlignCenter 0 0 27 21 27 21 8 Interrupt line register IL7 true false 0 0 27 21 27 21 8 Interrupt line register IL6 true false 0 0 27 21 27 21 8 Interrupt line register IL5 true false 0 0 27 21 27 21 8 Interrupt line register IL4 true false 0 0 27 21 27 21 8 Interrupt line register IL3 true false 0 0 27 21 27 21 8 Interrupt line register IL2 true false 0 0 27 21 27 21 8 Interrupt line register IL1 true false 0 0 27 21 27 21 8 Interrupt line register IL0 true false Qt::Vertical 20 4 Access Registers 0 0 1 3 45 21 30 0 R#14 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 14 FF Qt::AlignCenter 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register A16 true false 0 0 27 21 27 21 8 VRAM Access base address register A15 true false 0 0 27 21 27 21 8 VRAM Access base address register A14 true false 45 21 30 0 R#15 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 15 FF Qt::AlignCenter 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer S3 true false 0 0 27 21 27 21 8 Status register pointer S2 true false 0 0 27 21 27 21 8 Status register pointer S1 true false 0 0 27 21 27 21 8 Status register pointer S0 true false 45 21 30 0 R#16 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 16 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register C3 true false 0 0 27 21 27 21 8 Color palette address register C2 true false 0 0 27 21 27 21 8 Color palette address register C1 true false 0 0 27 21 27 21 8 Color palette address register C0 true false 45 21 30 0 R#17 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 17 FF Qt::AlignCenter 0 0 27 21 27 21 8 Control register pointer AII true false 0 0 27 21 27 21 8 Control register pointer 0 true false 0 0 27 21 27 21 8 Control register pointer RS5 true false 0 0 27 21 27 21 8 Control register pointer RS4 true false 0 0 27 21 27 21 8 Control register pointer RS3 true false 0 0 27 21 27 21 8 Control register pointer RS2 true false 0 0 27 21 27 21 8 Control register pointer RS1 true false 0 0 27 21 27 21 8 Control register pointer RS0 true false Qt::Horizontal 10 10 2 Qt::Horizontal 9 Qt::Horizontal 40 20 Decoding the mode registers 0 0 5 0 0 Screen mode Screen 0 PAL 0 0 , 212 lines, Display enabeled interlaced alternate pages Interrupt from Horizontal scanning line enabled. Interrupt from Horizontal scanning line enabled. Interrupt from Horizontal scanning line enabled. 16x16 sprites ,magnified sprites ,enabled Color 0 is transparent DG explained Uses 4/16K memory Decoding the V9958 registers 0 0 5 0 0 explaining SP2 explaining msk explaining wte explaining yjk explaining yae explaining vds explaining cmd explaining h0x Decoding the Table Base Registers QFormLayout::ExpandingFieldsGrow 3 2 0 5 0 0 Pattern name table 40 0 Screen mode 0x0000 Color table Screen mode 0x0000 Pattern generator table Screen mode 0x0000 Sprite attribute table Screen mode 0x0000 Sprite pattern generator table Screen mode 0x0000 Decoding the Display registers QFormLayout::ExpandingFieldsGrow 3 2 0 9 0 0 Display adjust Screen mode (0,0) Display offset Screen mode 255 Interrupt line Screen mode 255 Color Registers 3 2 0 5 5 0 Text color 15 0 Screen mode 15 Backdrop color Screen mode 15 Blinking text color Screen mode 15 Blinking backdrop Screen mode 15 Blinking time on Screen mode 15 Blinking time off Screen mode 15 Access registers 3 2 0 5 5 0 Access address 22 0 Screen mode 255 status register Screen mode 255 color Screen mode 255 VDP register Screen mode 255 Qt::Horizontal 40 20 Qt::Vertical 20 3 Qt::Horizontal 40 20 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600; font-style:italic;">Quick hack</span><span style=" font-size:10pt; font-style:italic;"> use this to switch between VDP chip, since no autodetection yet in the code</span></p></body></html> Qt::RichText V9958 V9938 TMS99x8 InteractiveButton QPushButton
InteractiveButton.h
InteractiveLabel QLabel
InteractiveLabel.h
debugger-master/src/VDPStatusRegViewer.cpp0000644000175000017500000001503513560352104020442 0ustar shevekshevek#include "VDPStatusRegViewer.h" #include "VramBitMappedView.h" #include "VDPDataStore.h" #include "InteractiveLabel.h" #include #include highlightDispatcher::highlightDispatcher() { counter = 0; } void highlightDispatcher::receiveState(bool state) { if (state) { if (counter == 0) { emit dispatchState(true); } ++counter; } else { --counter; if (counter == 0) { emit dispatchState(false); } } } VDPStatusRegViewer::VDPStatusRegViewer(QWidget* parent) : QDialog(parent) { setupUi(this); //statusregs = VDPDataStore::instance().getStatusRegsPointer(); statusregs = new unsigned char[16]; // now hook up some signals and slots connectHighLights(); // get initiale data refresh(); } VDPStatusRegViewer::~VDPStatusRegViewer() { delete[] statusregs; } void VDPStatusRegViewer::decodeVDPStatusRegs() { // first update all hex values label_val_0->setText(QString("%1").arg(statusregs[0],2,16,QChar('0')).toUpper()); label_val_1->setText(QString("%1").arg(statusregs[1],2,16,QChar('0')).toUpper()); label_val_2->setText(QString("%1").arg(statusregs[2],2,16,QChar('0')).toUpper()); label_val_3->setText(QString("%1").arg(statusregs[3],2,16,QChar('0')).toUpper()); label_val_4->setText(QString("%1").arg(statusregs[4],2,16,QChar('0')).toUpper()); label_val_5->setText(QString("%1").arg(statusregs[5],2,16,QChar('0')).toUpper()); label_val_6->setText(QString("%1").arg(statusregs[6],2,16,QChar('0')).toUpper()); label_val_7->setText(QString("%1").arg(statusregs[7],2,16,QChar('0')).toUpper()); label_val_8->setText(QString("%1").arg(statusregs[8],2,16,QChar('0')).toUpper()); label_val_9->setText(QString("%1").arg(statusregs[9],2,16,QChar('0')).toUpper()); // update all the individual bits for (int r = 0; r <= 9; ++r) { for (int b = 7; b >= 0; --b) { QString name = QString("label_%1_%2").arg(r).arg(b); InteractiveLabel* l = findChild(name); l->setText((statusregs[r] & (1 << b)) ? "1" : "0"); } } // Start the interpretation label_I_0_7->setText((statusregs[0] & 128) ? "Interrupt" : "No int"); label_I_0_6->setText((statusregs[0] & 64) ? "5th sprite" : "No 5th"); label_I_0_5->setText((statusregs[0] & 32) ? "Collision" : "No collision"); label_I_0_0->setText(QString("sprnr:%1").arg(statusregs[0] & 31)); label_I_1_7->setText((statusregs[1] & 128) ? "Light" : "No light"); label_I_1_6->setText((statusregs[1] & 64) ? "switch on" : "Switch off"); label_I_1_0->setText((statusregs[1] & 1) ? "hor scanline int" : "no hor int"); QString id; switch (statusregs[1] & 62) { case 0: id = QString("v9938"); break; case 2: id = QString("v9948"); break; case 4: id = QString("v9958"); break; default: id = QString("unknown VDP"); } label_I_1_1->setText(id); label_I_2_7->setText((statusregs[2] & 128) ? "Transfer ready" : "Transfering"); label_I_2_6->setText((statusregs[2] & 64) ? "Vertical scanning" : "Not vert scan"); label_I_2_5->setText((statusregs[2] & 32) ? "Horizontal scanning" : "Not hor scan"); label_I_2_4->setText((statusregs[2] & 16) ? "Boundary color detected" : "BC not deteced"); label_I_2_1->setText((statusregs[2] & 2) ? "First field" : "Second field"); label_I_2_0->setText((statusregs[2] & 1) ? "Command execution" : "No command exec"); label_I_3->setText(QString("Column: %1").arg(statusregs[3] | ((statusregs[4] & 1) << 8))); label_I_5->setText(QString("Row: %1").arg(statusregs[5] | ((statusregs[6] & 3) << 8))); label_I_7->setText(QString("Color: %1").arg(statusregs[7])); label_I_8->setText(QString("Border X: %1").arg(statusregs[8] | ((statusregs[9] & 1) << 8))); } void VDPStatusRegViewer::doConnect(InteractiveLabel* lab, highlightDispatcher* dis) { connect(lab, SIGNAL(mouseOver(bool)), dis, SLOT(receiveState(bool))); connect(dis, SIGNAL(dispatchState(bool)), lab, SLOT(highlight(bool))); } void VDPStatusRegViewer::makeGroup(QList list, InteractiveLabel* explained) { // First "steal" the Tooltip of the explained widget. InteractiveLabel* item; foreach (item, list) { item->setToolTip(explained->toolTip()); } // now create a dispatcher and connect all to them list << explained; highlightDispatcher* dispat = new highlightDispatcher(); foreach (item, list) { doConnect(item, dispat); } } void VDPStatusRegViewer::connectHighLights() { QList list; list.clear(); list << label_0_7; makeGroup(list, label_I_0_7); list.clear(); list << label_0_6; makeGroup(list, label_I_0_6); list.clear(); list << label_0_5; makeGroup(list, label_I_0_5); list.clear(); list << label_0_4 << label_0_3 << label_0_2 << label_0_1 << label_0_0; makeGroup(list, label_I_0_0); list.clear(); list << label_1_7; makeGroup(list, label_I_1_7); list.clear(); list << label_1_6; makeGroup(list, label_I_1_6); list.clear(); list << label_1_4 << label_1_3 << label_1_2 << label_1_1; makeGroup(list, label_I_1_1); list.clear(); list << label_1_0; makeGroup(list, label_I_1_0); list.clear(); list << label_2_7; makeGroup(list, label_I_2_7); list.clear(); list << label_2_6; makeGroup(list, label_I_2_6); list.clear(); list << label_2_5; makeGroup(list, label_I_2_5); list.clear(); list << label_2_4; makeGroup(list, label_I_2_4); list.clear(); list << label_2_1; makeGroup(list, label_I_2_1); list.clear(); list << label_2_0; makeGroup(list, label_I_2_0); list.clear(); list << label_2_0; makeGroup(list, label_I_2_0); list.clear(); list << label_3_7 << label_3_6 << label_3_5 << label_3_4; list << label_3_3 << label_3_2 << label_3_1 << label_3_0; list << label_4_7 << label_4_6 << label_4_5 << label_4_4; list << label_4_3 << label_4_2 << label_4_1 << label_4_0; makeGroup(list, label_I_3); list.clear(); list << label_5_7 << label_5_6 << label_5_5 << label_5_4; list << label_5_3 << label_5_2 << label_5_1 << label_5_0; list << label_6_7 << label_6_6 << label_6_5 << label_6_4; list << label_6_3 << label_6_2 << label_6_1 << label_6_0; makeGroup(list, label_I_5); list.clear(); list << label_7_7 << label_7_6 << label_7_5 << label_7_4; list << label_7_3 << label_7_2 << label_7_1 << label_7_0; makeGroup(list, label_I_7); list.clear(); list << label_8_7 << label_8_6 << label_8_5 << label_8_4; list << label_8_3 << label_8_2 << label_8_1 << label_8_0; list << label_9_7 << label_9_6 << label_9_5 << label_9_4; list << label_9_3 << label_9_2 << label_9_1 << label_9_0; makeGroup(list, label_I_8); } void VDPStatusRegViewer::refresh() { new SimpleHexRequest("{VDP status regs}", 0, 16, statusregs, *this); } void VDPStatusRegViewer::DataHexRequestReceived() { decodeVDPStatusRegs(); } debugger-master/src/BitMapViewer.cpp0000644000175000017500000001752713560352104017333 0ustar shevekshevek#include "BitMapViewer.h" #include "VramBitMappedView.h" #include "VDPDataStore.h" #include static const unsigned char defaultPalette[32] = { // RB G 0x00, 0, 0x00, 0, 0x11, 6, 0x33, 7, 0x17, 1, 0x27, 3, 0x51, 1, 0x27, 6, 0x71, 1, 0x73, 3, 0x61, 6, 0x64, 6, 0x11, 4, 0x65, 2, 0x55, 5, 0x77, 7, }; BitMapViewer::BitMapViewer(QWidget* parent) : QDialog(parent) , screenMod(0) // avoid UMR { setupUi(this); // hand code entering the actual display widget in the scrollarea With // the designer-qt4 there is an extra scrollAreaWidget between the // imageWidget and the QScrollArea so the scrollbars are not correctly // handled when the image is resized. (since the intermediate widget // stays the same size). I did not try to have this intermediate widget // resize and all, since it was superflous anyway. imageWidget = new VramBitMappedView(); QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(imageWidget->sizePolicy().hasHeightForWidth()); imageWidget->setSizePolicy(sizePolicy1); imageWidget->setMinimumSize(QSize(256, 212)); scrollArea->setWidget(imageWidget); useVDP = true; const unsigned char* vram = VDPDataStore::instance().getVramPointer(); const unsigned char* palette = VDPDataStore::instance().getPalettePointer(); imageWidget->setVramSource(vram); imageWidget->setVramAddress(0); imageWidget->setPaletteSource(palette); //now hook up some signals and slots connect(&VDPDataStore::instance(), SIGNAL(dataRefreshed()), this, SLOT(VDPDataStoreDataRefreshed())); connect(&VDPDataStore::instance(), SIGNAL(dataRefreshed()), imageWidget, SLOT(refresh())); connect(refreshButton, SIGNAL(clicked(bool)), &VDPDataStore::instance(), SLOT(refresh())); connect(imageWidget, SIGNAL(imagePosition(int,int,int,unsigned int,int)), this, SLOT(imagePositionUpdate(int,int,int,unsigned int,int))); connect(imageWidget, SIGNAL(imageClicked (int,int,int,unsigned int,int)), this, SLOT(imagePositionUpdate(int,int,int,unsigned int,int))); // and now go fetch the initial data VDPDataStore::instance().refresh(); } void BitMapViewer::decodeVDPregs() { const unsigned char* regs = VDPDataStore::instance().getRegsPointer(); // Get the number of lines int v1 = (regs[9] & 128) ? 212 : 192; printf("\nlines acording to the bits %i,: %i\n", (regs[9] & 128), v1); linesLabel->setText(QString("%1").arg(v1, 0, 10)); if (useVDP) linesVisible->setCurrentIndex((regs[9] & 128) ? 1 : 0); // Get the border color int v2 = regs[7] & 15; printf("\nborder acording to the regs %i,: %i\n", regs[7], v2); if (regs[8] & 32) v2 = 0; printf("\ncolor 0 is pallet regs %i,: %i\n", (regs[8] & 32), v2); borderLabel->setText(QString("%1").arg(v2, 0, 10)); if (useVDP) bgColor->setValue(v2); // Get current screenmode static const int bits_modetxt[128] = { 1, 3, 0, 255, 2, 255, 255, 255, 4, 255, 80, 255, 5, 255, 255, 255, 6, 255, 255, 255, 7, 255, 255, 255, 255, 255, 255, 255, 8, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 12, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 11, 255, 255, 255, }; static const int bits_mode[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, }; int v3 = ((regs[0] & 0x0E) << 1) | ((regs[1] & 0x18) >> 3) | ((regs[25] & 0x18) << 2); printf("screenMod according to the bits: %i\n", v3); modeLabel->setText(QString("%1").arg(bits_modetxt[v3], 0, 10)); if (useVDP) screenMode->setCurrentIndex(bits_mode[v3]); // Get the current visible page unsigned p = (regs[2] >> 5) & 3; unsigned q = 1 << 15; if (bits_modetxt[v3] > 6) { p &= 1; q <<= 1; } printf("visible page according to the bits: %i\n",p); setPages(); addressLabel->setText(QString("0x%1").arg(p * q, 5, 16, QChar('0'))); if (useVDP) showPage->setCurrentIndex(p); } void BitMapViewer::refresh() { // All of the code is in the VDPDataStore; VDPDataStore::instance().refresh(); } void BitMapViewer::on_screenMode_currentIndexChanged(const QString& text) { screenMod = text.toInt(); printf("\nnew screenMod: %i\n", screenMod); //change then number of visibe pages when this changes imageWidget->setVramAddress(0); // make sure that we are decoding new mode from page 0, imagine viewing // page 3 of screen5 and then switching to screen 8 without changing the // starting vram address.... imageWidget->setScreenMode(screenMod); setPages(); } void BitMapViewer::setPages() { showPage->clear(); showPage->insertItem(0, "0"); showPage->insertItem(1, "1"); if (screenMod < 7 && VDPDataStore::instance().getVRAMSize() > 0x10000) { showPage->insertItem(2, "2"); showPage->insertItem(3, "3"); } } void BitMapViewer::on_showPage_currentIndexChanged(int index) { //if this is the consequence of a .clear() in the // on_screenMode_currentIndexChanged we do nothing! if (index == -1) return; static const int m1[4] = { 0x00000, 0x08000, 0x10000, 0x18000 }; printf("\nvoid BitMapViewer::on_showPage_currentIndexChanged( int %i);\n", index); if (screenMod >= 7) index *= 2; int vramAddress = m1[index]; printf("vramAddress %i\n", vramAddress); imageWidget->setVramAddress(vramAddress); } void BitMapViewer::on_linesVisible_currentIndexChanged(int index) { static const int m[3] = { 192, 212, 256 }; int lines = m[index]; imageWidget->setLines(lines); } void BitMapViewer::on_bgColor_valueChanged(int value) { imageWidget->setBorderColor(value); } void BitMapViewer::on_useVDPRegisters_stateChanged(int state) { useVDP = state; screenMode->setEnabled(!state); linesVisible->setEnabled(!state); showPage->setEnabled(!state); bgColor->setEnabled(!state); decodeVDPregs(); imageWidget->refresh(); } void BitMapViewer::on_zoomLevel_valueChanged(double d) { imageWidget->setZoom(float(d)); } void BitMapViewer::on_saveImageButton_clicked(bool checked) { QMessageBox::information( this, "Not yet implemented", "Sorry, the save image dialog is not yet implemented"); } void BitMapViewer::on_editPaletteButton_clicked(bool checked) { useVDPPalette->setChecked(false); QMessageBox::information( this, "Not yet implemented", "Sorry, the palette editor is not yet implemented, " "only disabling 'Use VDP palette registers' for now"); } void BitMapViewer::on_useVDPPalette_stateChanged(int state) { if (state) { const unsigned char* palette = VDPDataStore::instance().getPalettePointer(); imageWidget->setPaletteSource(palette); } else { imageWidget->setPaletteSource(defaultPalette); } imageWidget->refresh(); } /* void BitMapViewer::on_refreshButton_clicked(bool checked) { refresh(); decodeVDPregs(); imageWidget->refresh(); } */ void BitMapViewer::VDPDataStoreDataRefreshed() { decodeVDPregs(); } void BitMapViewer::imagePositionUpdate( int x, int y, int color, unsigned addr, int byteValue) { labelX->setText(QString("%1").arg(x, 3, 10, QChar('0'))); labelY->setText(QString("%1").arg(y, 3, 10, QChar('0'))); labelColor->setText(QString("%1").arg(color, 3, 10, QChar('0'))); labelByte->setText(QString("0x%1").arg(byteValue, 2, 16, QChar('0'))); labelVramAddr->setText(QString("0x%1").arg(addr, 5, 16, QChar('0'))); } debugger-master/src/VDPStatusRegViewer.h0000644000175000017500000000323613560352104020107 0ustar shevekshevek#ifndef VDPSTATUSREGVIEWER_H #define VDPSTATUSREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPStatusRegisters.h" #include #include /** The highlightDispatcher serves 2 purposes for the InteractiveLabel widgets * a) keep a correct state: Assume widget A and B are related (both are * highlighted at the same time) and they are touching each other. I don't * think that there is a garuanteed order in the enterEvent,leaveEvent, so if * we use the MouseOver signal to connect to the highlight slots of A and B * then this sequence might arise if our mouse moves from A to B and produce * a wrong result: * B.mouseOver(true); A.mouseOver(false) -> highlights are false for both A and B. * * b) serve as a central hub (star toplogy) to dispatch events from one widget * to all others. This way all InteractiveLabel widgets only need to connect * to this highlightDispatcher */ class highlightDispatcher : public QObject { Q_OBJECT public: highlightDispatcher(); public slots: void receiveState(bool state); signals: void dispatchState(bool state); private: int counter; }; class VDPStatusRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPStatusRegisters { Q_OBJECT public: VDPStatusRegViewer(QWidget* parent = 0); ~VDPStatusRegViewer(); public slots: void refresh(); private: void decodeVDPStatusRegs(); void connectHighLights(); void doConnect(InteractiveLabel* lab, highlightDispatcher* dis); void makeGroup(QList list, InteractiveLabel* explained); virtual void DataHexRequestReceived(); unsigned char* statusregs; }; #endif // VDPSTATUSREGVIEWER_H debugger-master/src/MainMemoryViewer.cpp0000644000175000017500000000661313560352104020226 0ustar shevekshevek#include "MainMemoryViewer.h" #include "HexViewer.h" #include "CPURegs.h" #include "CPURegsViewer.h" #include "SymbolTable.h" #include "Convert.h" #include #include #include #include #include const int MainMemoryViewer::linkRegisters[] = { CpuRegs::REG_BC, CpuRegs::REG_DE, CpuRegs::REG_HL, CpuRegs::REG_IX, CpuRegs::REG_IY, CpuRegs::REG_BC2, CpuRegs::REG_DE2, CpuRegs::REG_HL2, CpuRegs::REG_PC, CpuRegs::REG_SP }; MainMemoryViewer::MainMemoryViewer(QWidget* parent) : QWidget(parent) { // create selection list, address edit line and viewer addressSourceList = new QComboBox(); addressSourceList->setEditable(false); addressSourceList->addItem("Address:"); for (int i = 0; i < 10; ++i) { QString txt = QString("Linked to "); txt.append(CpuRegs::regNames[linkRegisters[i]]); addressSourceList->addItem(txt); } addressValue = new QLineEdit(); addressValue->setText(hexValue(0, 4)); //addressValue->setEditable(false); hexView = new HexViewer(); hexView->setUseMarker(true); hexView->setIsEditable(true); hexView->setIsInteractive(true); hexView->setDisplayMode(HexViewer::FILL_WIDTH_POWEROF2); QHBoxLayout* hbox = new QHBoxLayout(); hbox->setMargin(0); hbox->addWidget(addressSourceList); hbox->addWidget(addressValue); QVBoxLayout* vbox = new QVBoxLayout(); vbox->setMargin(0); vbox->addLayout(hbox); vbox->addWidget(hexView); setLayout(vbox); isLinked = false; linkedId = 0; regsViewer = NULL; symTable = 0; connect(hexView, SIGNAL(locationChanged(int)), this, SLOT(hexViewChanged(int))); connect(addressValue, SIGNAL(returnPressed()), this, SLOT(addressValueChanged())); connect(addressSourceList, SIGNAL(currentIndexChanged(int)), this, SLOT(addressSourceListChanged(int))); } void MainMemoryViewer::settingsChanged() { hexView->settingsChanged(); } void MainMemoryViewer::setLocation(int addr) { addressValue->setText(hexValue(addr, 4).toUpper()); hexView->setLocation(addr); } void MainMemoryViewer::setDebuggable(const QString& name, int size) { hexView->setDebuggable(name, size); } void MainMemoryViewer::setRegsView(CPURegsViewer* viewer) { regsViewer = viewer; } void MainMemoryViewer::setSymbolTable(SymbolTable* symtable) { symTable = symtable; } void MainMemoryViewer::refresh() { hexView->refresh(); } void MainMemoryViewer::hexViewChanged(int addr) { addressValue->setText(hexValue(addr, 4).toUpper()); } void MainMemoryViewer::addressValueChanged() { int addr = stringToValue(addressValue->text()); if (addr == -1 && symTable) { // try finding a label Symbol *s = symTable->getAddressSymbol(addressValue->text()); if (!s) s = symTable->getAddressSymbol(addressValue->text(), Qt::CaseInsensitive); if (s) addr = s->value(); } if(addr >= 0) hexView->setLocation(addr); } void MainMemoryViewer::registerChanged(int id, int value) { if (!isLinked || (id != linkedId)) { return; } addressValue->setText(hexValue(value, 4).toUpper()); hexView->setLocation(value); //hexView->refresh(); } void MainMemoryViewer::addressSourceListChanged(int index) { if (index == 0) { isLinked = false; addressValue->setReadOnly(false); hexView->setIsInteractive(true); } else { isLinked = true; linkedId = linkRegisters[index - 1]; addressValue->setReadOnly(true); hexView->setIsInteractive(false); if (regsViewer) { setLocation(regsViewer->readRegister(linkedId)); } } } debugger-master/src/DebugSession.h0000644000175000017500000000125113560352104017017 0ustar shevekshevek#ifndef DEBUGSESSION_H #define DEBUGSESSION_H #include "DebuggerData.h" #include "SymbolTable.h" #include class QXmlStreamReader; class DebugSession : public QObject { Q_OBJECT public: DebugSession(); // session void clear(); void open(const QString& file); bool save(); bool saveAs(const QString& file); bool existsAsFile() const; const QString& filename() const; bool isModified() const; Breakpoints& breakpoints(); SymbolTable& symbolTable(); private: void skipUnknownElement(QXmlStreamReader& ses); Breakpoints breaks; SymbolTable symTable; QString fileName; bool modified; public slots: void sessionModified(); }; #endif // DEBUGSESSION_H debugger-master/src/VDPStatusRegisters.ui0000644000175000017500000026510313560352104020350 0ustar shevekshevek VDPStatusRegisters 0 0 516 324 Dialog 0 0 140 0 Status registers 10 20 121 271 0 0 Qt::Horizontal QSizePolicy::Expanding 5 5 Qt::Horizontal QSizePolicy::Expanding 5 5 0 0 S#0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus test 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#1 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#3 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#5 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#6 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#7 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#8 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#9 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 345 300 Interpretation F: Vertical scanning interrupt flag When S#0 is read, this flag is reset. --- 5S: Flag for the fifth sprite Five sprites are aligned on the first horizontal line (In the G3 to G7 modes, 9 sprites are allowed) --- C: Collision flag Two sprites have collided. --- Fifth sprite number: The number of the fifth (or ninth) sprite. --- Qt::Horizontal 40 20 FL: Lightpen flag (Lightpen flag set) If the lightpen is to detect light, this bit as well as the IE2 bit must both set in order for an interrupt to be enabled. When S#1 is read, FL is reset. Mouse switch 2 (Mouse flag set) The second switch on the mouse was pressed. In this case, when S#1 is read, FL is not reset. --- LPS: Lightpen switch (Lightpen flag set) The lightpen switch was pressed. In this case, when S#1 is read, LPS is not reset. Mouse switch 1 (Mouse flag set) The first switch on the mouse was pressed. In this case, when S#1 is read, LPS is not reset. --- Identification number: The identification number (ID #) of the MSX-VIDEO. ( 0 if V9938, 1 if V9948, 2 if V9958) --- FH: Horizontal scanning interrupt flag Horizontal scanning interrupt (which is specified in R#19) flag. If IE1 is set, an interrupt is enabled. When S#1 is read, FH is reset. --- Qt::Horizontal 40 20 5 TR: Transfer ready flag When the CPU sends commands to the VRAM and other devices, the CPU checks this flag while transferring data. When this flag is set to 1, transfer may be done. --- VR: Vertical scanning line timing flag During vertical scanning, this flag is set to 1. --- HR: Horizontal scanning line timing flag During horizontal scanning, this flag is set to 1. --- BD: Boundary color detect flag When the search command is executed, this flag detects whether the boundary color was detected or not. --- EO: Display field flag When 0, indicates the first field. When 1, indicates the second field. --- CE: Command execution flag Indicates that a command is being executed. --- Qt::Horizontal 40 20 Column register Is set to indicate the collision location of sprites, the location of lightpen detection, and the relative movement of the mouse. --- Row register Is set to indicate the collision location of sprites, the location of lightpen detection, and the relative movement of the mouse. --- Color register The color register is used when the POINT and VRAM to CPU commands are executed. The VRAM data is set in this register. --- Border X register When the search command is executed and the border color has been detected, the X coordinate is set in the above registers. --- Qt::Vertical 20 40 InteractiveLabel QLabel
InteractiveLabel.h
debugger-master/src/DebuggerData.h0000644000175000017500000000343613560352104016752 0ustar shevekshevek#ifndef DEBUGGERDATA_H #define DEBUGGERDATA_H #include #include #include #include struct MemoryLayout { MemoryLayout(); int primarySlot[4]; int secondarySlot[4]; int mapperSegment[4]; int romBlock[8]; bool isSubslotted[4]; int mapperSize[4][4]; }; class Breakpoints { public: Breakpoints(); enum Type { BREAKPOINT = 0, WATCHPOINT_MEMREAD, WATCHPOINT_MEMWRITE, WATCHPOINT_IOREAD, WATCHPOINT_IOWRITE, CONDITION }; void clear(); void setMemoryLayout(MemoryLayout* ml); void setBreakpoints(const QString& str); QString mergeBreakpoints(const QString& str); int breakpointCount(); bool isBreakpoint(quint16 addr, QString *id = 0); bool isWatchpoint(quint16 addr, QString *id = 0); /* xml session file functions */ void saveBreakpoints(QXmlStreamWriter& xml); void loadBreakpoints(QXmlStreamReader& xml); int findBreakpoint(quint16 addr); int findNextBreakpoint(); static QString createSetCommand(Type type, int address, char ps = -1, char ss = -1, int segment = -1, int endRange = -1, QString condition = QString()); static QString createRemoveCommand(const QString& id); private: struct Breakpoint { Type type; QString id; quint16 address; // end for watchpoint region quint16 regionEnd; // gui specific condition variables char ps; char ss; qint16 segment; // general condition QString condition; // compare content bool operator==(const Breakpoint &bp) const; }; typedef QLinkedList BreakpointList; BreakpointList breakpoints; MemoryLayout* memLayout; void parseCondition(Breakpoint& bp); void insertBreakpoint(Breakpoint& bp); bool inCurrentSlot(const Breakpoint& bp); }; #endif // DEBUGGERDATA_H debugger-master/src/GotoDialog.ui0000644000175000017500000000623113560352104016646 0ustar shevekshevek GotoDialog 0 0 304 118 0 0 Go to address 6 9 6 0 0 0 Address or label: Qt::Vertical 20 5 6 0 Qt::Horizontal 131 31 OK Cancel okButton clicked() GotoDialog accept() 278 253 96 254 cancelButton clicked() GotoDialog reject() 369 253 179 282 debugger-master/src/CommClient.h0000644000175000017500000000121013560352104016452 0ustar shevekshevek#ifndef COMMCLIENT_H #define COMMCLIENT_H #include class OpenMSXConnection; class Command; class QString; class CommClient : public QObject { Q_OBJECT public: static CommClient& instance(); void sendCommand(Command* command); public slots: void connectToOpenMSX(OpenMSXConnection* conn); void closeConnection(); signals: void connectionReady(); void connectionTerminated(); void logParsed(const QString& level, const QString& message); void updateParsed(const QString& type, const QString& name, const QString& message); private: CommClient(); ~CommClient(); OpenMSXConnection* connection; }; #endif // COMMCLIENT_H debugger-master/src/InteractiveButton.cpp0000644000175000017500000000331713560352104020436 0ustar shevekshevek#include "InteractiveButton.h" #include #include InteractiveButton::InteractiveButton(QWidget* parent) : QPushButton(parent) { setEnabled(true); setAutoFillBackground(true); _mustBeSet=false; _highlight=false; connect(this, SIGNAL(toggled(bool)), this, SLOT(newBitValueSlot(bool))); } void InteractiveButton::highlight(bool state) { if (_highlight == state) return; _highlight=state; setColor(); } void InteractiveButton::setColor() { // No style sheet since this will not work for Mac OS X atm. QPalette fiddle = QApplication::palette(); int colorset=(_mustBeSet?4:0)+(_highlight?2:0)+((_mustBeSet&!_state)?1:0); switch (colorset) { case 6: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::green); break; case 4: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::darkGreen); break; case 3: case 7: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::red); break; case 2: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::yellow); break; case 5: case 1: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::darkRed); break; }; setPalette(fiddle); update(); } void InteractiveButton::enterEvent(QEvent* event) { emit mouseOver(true); } void InteractiveButton::leaveEvent(QEvent* event) { emit mouseOver(false); } void InteractiveButton::newBitValueSlot(bool state) { _state=state; QString name = objectName(); int bit = name.right(1).toInt(); int reg = name.mid( 1 + name.indexOf('_'), name.lastIndexOf('_') - name.indexOf('_') - 1).toInt(); emit newBitValue(reg, bit, state); setColor(); } void InteractiveButton::mustBeSet(bool state) { if (state == _mustBeSet) return; _mustBeSet=state; setColor(); } debugger-master/src/SlotViewer.cpp0000644000175000017500000001453513560352104017074 0ustar shevekshevek#include "SlotViewer.h" #include "DebuggerData.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include #include #include class DebugMemMapperHandler : public SimpleCommand { public: DebugMemMapperHandler(SlotViewer& viewer_) : SimpleCommand("debug_memmapper") , viewer(viewer_) { } virtual void replyOk(const QString& message) { viewer.slotsUpdated(message); delete this; } private: SlotViewer& viewer; }; SlotViewer::SlotViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum)); memLayout = NULL; for (int p = 0; p < 4; ++p) { slotsChanged[p] = false; segmentsChanged[p] = false; } frameR = frameL = frameT = frameB = frameWidth(); headerSize1 = 8 + fontMetrics().width("Page"); headerSize2 = 8 + fontMetrics().width("Address"); headerSize3 = 8 + fontMetrics().width("Slot"); headerSize4 = 8 + fontMetrics().width("Segment"); headerHeight = 8 + fontMetrics().height(); } void SlotViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void SlotViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); QStyleOptionHeader so; so.init(this); so.state |= QStyle::State_Raised; so.orientation = Qt::Horizontal; so.position = QStyleOptionHeader::Beginning; so.sortIndicator = QStyleOptionHeader::None; so.textAlignment = Qt::AlignHCenter; so.rect.setTop(frameT); so.rect.setHeight(headerHeight); so.rect.setLeft(frameL); so.rect.setWidth(headerSize1); so.section = 0; so.text = "Page"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize1); so.rect.setWidth(headerSize2); so.section = 1; so.text = "Address"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize2); so.rect.setWidth(headerSize3); so.section = 2; so.text = "Slot"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize3); so.rect.setWidth(headerSize4); so.section = 3; so.text = "Segment"; style()->drawControl(QStyle::CE_Header, &so, &p, this); int mid1 = frameL + headerSize1 / 2; int mid2 = frameL + headerSize1 + headerSize2 / 2; int mid3 = frameL + headerSize1 + headerSize2 + headerSize3 / 2; int mid4 = frameL + headerSize1 + headerSize2 + headerSize3 + headerSize4 / 2; int dy = (height() - frameT - frameB - headerHeight) / 4; int y = frameT + headerHeight + dy / 2 + fontMetrics().height() / 2 - fontMetrics().descent(); int isOn = isEnabled() && memLayout != NULL; for (int i = 0; i < 4; ++i) { QString str; p.setPen(palette().color(QPalette::Text)); // print page nr str.sprintf("%i", i); p.drawText(mid1 - fontMetrics().width(str) / 2, y, str); // print address str.sprintf("$%04X", i * 0x4000); p.drawText(mid2 - fontMetrics().width(str) / 2, y, str); // print slot if (isOn) { if (memLayout->isSubslotted[memLayout->primarySlot[i]]) { str.sprintf("%i-%i", memLayout->primarySlot[i], memLayout->secondarySlot[i]); } else { str = QString::number(memLayout->primarySlot[i]); } } else { str = "-"; } // set pen colour to red if slot was recently changed if (slotsChanged[i] && isOn) { p.setPen(Qt::red); } else { p.setPen(palette().color(QPalette::Text)); } p.drawText(mid3 - fontMetrics().width(str) / 2, y, str); // print segment if (isOn) { int ms; if (memLayout->isSubslotted[memLayout->primarySlot[i] & 3]) { ms = memLayout->mapperSize[memLayout->primarySlot[i] & 3] [memLayout->secondarySlot[i] & 3]; } else { ms = memLayout->mapperSize[memLayout->primarySlot[i] & 3][0]; } if (ms > 0) { str.sprintf("%i", memLayout->mapperSegment[i]); } else if(memLayout->romBlock[2*i] >= 0) { if (memLayout->romBlock[2*i] == memLayout->romBlock[2*i+1]) { str.sprintf("R%i", memLayout->romBlock[2*i]); } else { str.sprintf("R%i/%i", memLayout->romBlock[2*i], memLayout->romBlock[2*i+1]); } } else { str = "-"; } } else { str = "-"; } // set pen colour to red if slot was recently changed if (segmentsChanged[i] && isOn) { p.setPen(Qt::red); } else { p.setPen(palette().color(QPalette::Text)); } p.drawText(mid4 - fontMetrics().width(str) / 2, y, str); y += dy; } } QSize SlotViewer::sizeHint() const { return QSize(headerSize1 + headerSize2 + headerSize3 + headerSize4 + frameL + frameR, headerHeight + 4*fontMetrics().height()); } void SlotViewer::refresh() { CommClient::instance().sendCommand(new DebugMemMapperHandler(*this)); } void SlotViewer::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } void SlotViewer::slotsUpdated(const QString& message) { QStringList lines = message.split('\n'); // parse page slots and segments for (int p = 0; p < 4; ++p) { slotsChanged[p] = (memLayout->primarySlot [p] != lines[p * 2][0].toLatin1()-'0') || (memLayout->secondarySlot[p] != lines[p * 2][1].toLatin1()-'0' && memLayout->isSubslotted[p]); memLayout->primarySlot [p] = lines[p * 2][0].toLatin1()-'0'; memLayout->secondarySlot[p] = lines[p * 2][1].toLatin1()-'0'; segmentsChanged[p] = memLayout->mapperSegment[p] != lines[p * 2 + 1].toInt(); memLayout->mapperSegment[p] = lines[p * 2 + 1].toInt(); } // parse slot layout int l = 8; for (int ps = 0; ps < 4; ++ps) { memLayout->isSubslotted[ps] = lines[l++][0] == '1'; if (memLayout->isSubslotted[ps]) { for (int ss = 0; ss < 4; ++ss) { memLayout->mapperSize[ps][ss] = lines[l++].toUShort(); } } else { memLayout->mapperSize[ps][0] = lines[l++].toUShort(); } } // parse rom blocks for (int i = 0; i < 8; ++i, ++l) { if (lines[l][0] == 'X') memLayout->romBlock[i] = -1; else memLayout->romBlock[i] = lines[l].toInt(); } update(); } debugger-master/src/PreferencesDialog.h0000644000175000017500000000102513560352104020005 0ustar shevekshevek#ifndef PREFERENCESDIALOG_OPENMSX_H #define PREFERENCESDIALOG_OPENMSX_H #include "ui_PreferencesDialog.h" #include class PreferencesDialog : public QDialog, private Ui::PreferencesDialog { Q_OBJECT public: PreferencesDialog(QWidget* parent = 0); private: void initFontList(); void setFontPreviewColor(const QColor& c); bool updating; private slots: void fontSelectionChange(int row); void fontTypeChanged(bool state); void fontSelectCustom(); void fontSelectColor(); }; #endif // PREFERENCESDIALOG_OPENMSX_H debugger-master/src/BreakpointDialog.h0000644000175000017500000000217513560352104017651 0ustar shevekshevek#ifndef BREAKPOINTDIALOG_OPENMSX_H #define BREAKPOINTDIALOG_OPENMSX_H #include "ui_BreakpointDialog.h" #include "DebuggerData.h" #include struct MemoryLayout; class DebugSession; class Symbol; class BreakpointDialog : public QDialog, private Ui::BreakpointDialog { Q_OBJECT public: BreakpointDialog(const MemoryLayout& ml, DebugSession *session = 0, QWidget* parent = 0); ~BreakpointDialog(); Breakpoints::Type type(); int address(); int addressEndRange(); int slot(); int subslot(); int segment(); QString condition(); void setData(Breakpoints::Type type, int address = -1, int ps = -1, int ss = -1, int segment = -1, int addressEnd = -1, QString condition = QString()); private: const MemoryLayout& memLayout; DebugSession *debugSession; Symbol *currentSymbol; int idxSlot, idxSubSlot; int value, valueEnd; int conditionHeight; QCompleter *jumpCompleter, *allCompleter; private slots: void addressChanged(const QString& text); void typeChanged(int i); void slotChanged(int i); void subslotChanged(int i); void hasCondition(int state); }; #endif // BREAKPOINTDIALOG_OPENMSX_H debugger-master/src/VDPDataStore.cpp0000644000175000017500000000543713560352104017232 0ustar shevekshevek#include "VDPDataStore.h" #include "CommClient.h" class VDPDataStoreVersionCheck : public SimpleCommand { public: VDPDataStoreVersionCheck(VDPDataStore& dataStore_) : SimpleCommand("debug desc {physical VRAM}") , dataStore(dataStore_) { } virtual void replyOk(const QString& message) { dataStore.debuggableNameVRAM = "physical VRAM"; dataStore.got_version = true; dataStore.refresh(); delete this; } virtual void replyNok(const QString& message) { dataStore.debuggableNameVRAM = "VRAM"; dataStore.got_version = true; dataStore.refresh(); delete this; } private: VDPDataStore& dataStore; }; class VDPDataStoreVRAMSizeCheck : public SimpleCommand { public: VDPDataStoreVRAMSizeCheck(VDPDataStore& dataStore_) : SimpleCommand("debug size {" + QString::fromStdString(dataStore_.debuggableNameVRAM) + "}") , dataStore(dataStore_) { } virtual void replyOk(const QString& message) { dataStore.vramSize = message.toInt(); dataStore.refresh2(); delete this; } virtual void replyNok(const QString& message) { delete this; } private: VDPDataStore& dataStore; }; static const unsigned MAX_VRAM_SIZE = 0x30000; static const unsigned MAX_TOTAL_SIZE = MAX_VRAM_SIZE + 32 + 16 + 64 + 2; VDPDataStore::VDPDataStore() { vram = new unsigned char[MAX_TOTAL_SIZE]; memset(vram, 0x00, MAX_TOTAL_SIZE); got_version = false; CommClient::instance().sendCommand(new VDPDataStoreVersionCheck(*this)); } VDPDataStore::~VDPDataStore() { delete[] vram; } VDPDataStore& VDPDataStore::instance() { static VDPDataStore oneInstance; return oneInstance; } void VDPDataStore::refresh() { if (!got_version) return; refresh1(); } void VDPDataStore::refresh1() { CommClient::instance().sendCommand(new VDPDataStoreVRAMSizeCheck(*this)); } void VDPDataStore::refresh2() { QString req = QString( "debug_bin2hex " "[ debug read_block {" + QString::fromStdString(debuggableNameVRAM) + "} 0 " + QString::number(vramSize) + " ]" "[ debug read_block {VDP palette} 0 32 ]" "[ debug read_block {VDP status regs} 0 16 ]" "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VRAM pointer} 0 2 ]"); new SimpleHexRequest(req, MAX_TOTAL_SIZE - MAX_VRAM_SIZE + vramSize, vram, *this); } void VDPDataStore::DataHexRequestReceived() { emit dataRefreshed(); } const unsigned char* VDPDataStore::getVramPointer() const { return vram; } const unsigned char* VDPDataStore::getPalettePointer() const { return vram + vramSize; } const unsigned char* VDPDataStore::getStatusRegsPointer() const { return vram + vramSize + 32; } const unsigned char* VDPDataStore::getRegsPointer() const { return vram + vramSize + 32 + 16; } const unsigned char* VDPDataStore::getVdpVramPointer() const { return vram + vramSize + 32 + 16 + 64; } const size_t VDPDataStore::getVRAMSize() const { return vramSize; } debugger-master/src/DockableWidgetArea.cpp0000644000175000017500000000220413560352104020420 0ustar shevekshevek#include "DockableWidgetArea.h" #include "DockableWidgetLayout.h" #include "DockableWidget.h" DockableWidgetArea::DockableWidgetArea(QWidget* parent) : QWidget(parent) { layout = new DockableWidgetLayout(); setLayout(layout); } void DockableWidgetArea::removeWidget(DockableWidget* widget) { layout->removeWidget(widget); widget->setParent(0); } void DockableWidgetArea::addWidget(DockableWidget* widget, const QRect& rect) { widget->setParent(this); QRect r(rect); r.moveTopLeft(mapFromGlobal(r.topLeft())); layout->addWidget(widget, r); } void DockableWidgetArea::addWidget( DockableWidget* widget, DockableWidgetLayout::DockSide side, int distance, int w, int h) { widget->setParent(this); layout->addWidget(widget, side, distance, w, h); } void DockableWidgetArea::paintEvent(QPaintEvent* e) { QWidget::paintEvent(e); } bool DockableWidgetArea::insertLocation(QRect& r, const QSizePolicy& sizePol) { r.moveTopLeft(mapFromGlobal(r.topLeft())); bool ok = layout->insertLocation(r, sizePol); r.moveTopLeft(mapToGlobal(r.topLeft())); return ok; } void DockableWidgetArea::getConfig(QStringList& list) { layout->getConfig(list); } debugger-master/src/BreakpointDialog.ui0000644000175000017500000002115713560352104020040 0ustar shevekshevek BreakpointDialog 0 0 401 376 0 0 Add breakpoint 6 9 6 0 Type: Breakpoint Memory read watchpoint Memory write watchpoint IO read watchpoint IO write watchpoint Condition Qt::Horizontal 40 20 0 0 Add breakpoint at address: 0 6 any Subslot: cmbxSubslot Segment: cmbxSegment any 0 1 2 3 Slot: cmbxSlot any 0 1 2 3 Qt::Horizontal 40 20 With PC in Condition true 0 48 6 0 Qt::Horizontal 131 31 OK true Cancel edtAddress edtAddressRange cmbxSlot cmbxSubslot cmbxSegment cbCondition txtCondition okButton cancelButton cmbxType okButton clicked() BreakpointDialog accept() 278 253 96 254 cancelButton clicked() BreakpointDialog reject() 369 253 179 282 debugger-master/src/DebuggerForm.h0000644000175000017500000001114613560352104017001 0ustar shevekshevek#ifndef DEBUGGERFORM_H #define DEBUGGERFORM_H #include "DockManager.h" #include "DebugSession.h" #include #include class DockableWidgetArea; class DisasmViewer; class MainMemoryViewer; class CPURegsViewer; class FlagsViewer; class StackViewer; class SlotViewer; class CommClient; class QAction; class QMenu; class QToolBar; class VDPStatusRegViewer; class VDPRegViewer; class VDPCommandRegViewer; class DebuggerForm : public QMainWindow { Q_OBJECT; public: DebuggerForm(QWidget* parent = 0); ~DebuggerForm(); public slots: void showAbout(); private: void closeEvent(QCloseEvent* e); void createActions(); void createMenus(); void createToolbars(); void createStatusbar(); void createForm(); void openSession(const QString& file); void updateRecentFiles(); void addRecentFile(const QString& file); void removeRecentFile(const QString& file); void finalizeConnection(bool halted); void pauseStatusChanged(bool isPaused); void breakOccured(); void setBreakMode(); void setRunMode(); void updateData(); void refreshBreakpoints(); void addressSlot(int addr, int& ps, int& ss, int& segment); QMenu* fileMenu; QMenu* systemMenu; QMenu* searchMenu; QMenu* viewMenu; QMenu* viewVDPDialogsMenu; QMenu* executeMenu; QMenu* breakpointMenu; QMenu* helpMenu; QToolBar* systemToolbar; QToolBar* executeToolbar; QAction* fileNewSessionAction; QAction* fileOpenSessionAction; QAction* fileSaveSessionAction; QAction* fileSaveSessionAsAction; QAction* fileQuitAction; enum { MaxRecentFiles = 5 }; QAction *recentFileActions[MaxRecentFiles]; QAction *recentFileSeparator; QAction* systemConnectAction; QAction* systemDisconnectAction; QAction* systemPauseAction; QAction* systemRebootAction; QAction* systemSymbolManagerAction; QAction* systemPreferencesAction; QAction* searchGotoAction; QAction* viewRegistersAction; QAction* viewFlagsAction; QAction* viewStackAction; QAction* viewSlotsAction; QAction* viewMemoryAction; QAction* viewDebuggableViewerAction; QAction* viewBitMappedAction; QAction* viewVDPStatusRegsAction; QAction* viewVDPRegsAction; QAction* viewVDPCommandRegsAction; QAction* executeBreakAction; QAction* executeRunAction; QAction* executeStepAction; QAction* executeStepOverAction; QAction* executeRunToAction; QAction* executeStepOutAction; QAction* executeStepBackAction; QAction* breakpointToggleAction; QAction* breakpointAddAction; QAction* helpAboutAction; DockManager dockMan; DockableWidgetArea* mainArea; QStringList recentFiles; DisasmViewer* disasmView; MainMemoryViewer* mainMemoryView; CPURegsViewer* regsView; FlagsViewer* flagsView; StackViewer* stackView; SlotViewer* slotView; VDPStatusRegViewer* VDPStatusRegView; VDPRegViewer* VDPRegView; VDPCommandRegViewer* VDPCommandRegView; CommClient& comm; DebugSession session; MemoryLayout memLayout; unsigned char* mainMemory; bool mergeBreakpoints; QMap debuggables; private slots: void fileNewSession(); void fileOpenSession(); void fileSaveSession(); void fileSaveSessionAs(); void fileRecentOpen(); void systemConnect(); void systemDisconnect(); void systemPause(); void systemReboot(); void systemSymbolManager(); void systemPreferences(); void searchGoto(); void toggleRegisterDisplay(); void toggleFlagsDisplay(); void toggleStackDisplay(); void toggleSlotsDisplay(); void toggleMemoryDisplay(); void toggleBitMappedDisplay(); void toggleVDPRegsDisplay(); void toggleVDPStatusRegsDisplay(); void toggleVDPCommandRegsDisplay(); void addDebuggableViewer(); void executeBreak(); void executeRun(); void executeStep(); void executeStepOver(); void executeRunTo(); void executeStepOut(); void executeStepBack(); void breakpointToggle(int addr = -1); void breakpointAdd(); void handleCommandReplyStatus(bool status); void toggleView(DockableWidget* widget); void initConnection(); void handleUpdate(const QString& type, const QString& name, const QString& message); void setDebuggables(const QString& list); void setDebuggableSize(const QString& debuggable, int size); void connectionClosed(); void dockWidgetVisibilityChanged(DockableWidget* w); void updateViewMenu(); void updateVDPViewMenu(); void updateWindowTitle(); void symbolFileChanged(); friend class QueryPauseHandler; friend class QueryBreakedHandler; friend class ListBreakPointsHandler; friend class CPURegRequest; friend class ListDebuggablesHandler; friend class DebuggableSizeHandler; signals: void settingsChanged(); void symbolsChanged(); void debuggablesChanged(const QMap& list); void emulationChanged(); }; #endif // DEBUGGERFORM_H debugger-master/src/Settings.cpp0000644000175000017500000000632313560352104016565 0ustar shevekshevek#include "Settings.h" #include static const char *DebuggerFontNames[Settings::FONT_END] = { "Application Font", "Default Fixed Font", "Code Font", "Label Font", "Hex viewer font" }; static QString fontLocation(Settings::DebuggerFont f) { return QString("Fonts/").append(DebuggerFontNames[f]); } static QString fontColorLocation(Settings::DebuggerFont f) { return QString("Fonts/%1 Color").arg(DebuggerFontNames[f]); } Settings::Settings() : QSettings("openMSX", "debugger") { getFontsFromSettings(); } Settings::~Settings() { } Settings& Settings::get() { static Settings instance; return instance; } void Settings::getFontsFromSettings() { // first get application default QVariant v = value(fontLocation(APP_FONT)); if (v.type() == QVariant::Font) { fonts[APP_FONT] = v.value(); fontTypes[APP_FONT] = CUSTOM; } else { fontTypes[APP_FONT] = APPLICATION_DEFAULT; fonts[APP_FONT] = qApp->font(); } // then get default fixed spacing font v = value(fontLocation(FIXED_FONT)); if (v.type() == QVariant::Font) { fonts[FIXED_FONT] = v.value(); fontTypes[FIXED_FONT] = CUSTOM; } else { fontTypes[FIXED_FONT] = APPLICATION_DEFAULT; fonts[FIXED_FONT] = fonts[APP_FONT]; } // then the rest for (int f = CODE_FONT; f < FONT_END; ++f) { v = value(fontLocation((DebuggerFont)f)); if (v.type() == QVariant::Font) { fonts[f] = v.value(); fontTypes[f] = CUSTOM; } else if (v.toString() == "FixedDefault") { fonts[f] = fonts[FIXED_FONT]; fontTypes[f] = FIXED_DEFAULT; } else { fonts[f] = fonts[APP_FONT]; fontTypes[f] = CUSTOM; } } // read colors for (int f =CODE_FONT; f < FONT_END; ++f) { fontColors[f] = value(fontColorLocation((DebuggerFont)f), QColor(Qt::black)) .value(); } } QString Settings::fontName(DebuggerFont f) const { return QString(DebuggerFontNames[f]); } const QFont& Settings::font(DebuggerFont f) const { return fonts[f]; } void Settings::setFont(DebuggerFont f, const QFont& ft) { fontTypes[f] = CUSTOM; fonts[f] = ft; setValue(fontLocation(f), fonts[f]); if (f <= FIXED_FONT) updateFonts(); } Settings::DebuggerFontType Settings::fontType(DebuggerFont f) const { return fontTypes[f]; } void Settings::setFontType(DebuggerFont f, DebuggerFontType t) { if (fontTypes[f] == t) return; fontTypes[f] = t; switch (t) { case APPLICATION_DEFAULT: setValue(fontLocation(f), "AppDefault"); if (f == APP_FONT) { fonts[f] = qApp->font(); } else { fonts[f] = fonts[APP_FONT]; } break; case FIXED_DEFAULT: if (f > FIXED_FONT) { setValue(fontLocation(f), "FixedDefault"); fonts[f] = fonts[FIXED_FONT]; } break; case CUSTOM: setValue(fontLocation(f), fonts[f]); break; } if (f > FIXED_FONT) updateFonts(); } const QColor& Settings::fontColor(DebuggerFont f) const { return fontColors[f]; } void Settings::setFontColor(DebuggerFont f, const QColor& c) { if (f > FIXED_FONT) { fontColors[f] = c; setValue(fontColorLocation(f), c); } } void Settings::updateFonts() { for (int f = CODE_FONT; f < FONT_END; ++f) { switch (fontTypes[f]) { case APPLICATION_DEFAULT: fonts[f] = fonts[APP_FONT]; break; case FIXED_DEFAULT: fonts[f] = fonts[FIXED_FONT]; break; default: break; } } } debugger-master/src/SymbolManager.h0000644000175000017500000000471113560352104017171 0ustar shevekshevek#ifndef SYMBOLMANAGER_OPENMSX_H #define SYMBOLMANAGER_OPENMSX_H #include "ui_SymbolManager.h" class SymbolTable; class QTreeWidgetItem; class SymbolManager : public QDialog, private Ui::SymbolManager { Q_OBJECT public: SymbolManager(SymbolTable& symtable, QWidget* parent = 0); private: void closeEvent(QCloseEvent* e); void initFileList(); void initSymbolList(); void closeEditor(); // formatting functions void updateItemName(QTreeWidgetItem* item); void updateItemType(QTreeWidgetItem* item); void updateItemValue(QTreeWidgetItem* item); void updateItemSlots(QTreeWidgetItem* item); void updateItemSegments(QTreeWidgetItem* item); void updateItemRegisters(QTreeWidgetItem* item); void beginTreeLabelsUpdate(); void endTreeLabelsUpdate(); SymbolTable& symTable; int treeLabelsUpdateCount; QCheckBox* chkSlots[16]; QCheckBox* chkRegs[18]; QTreeWidgetItem* editItem; int editColumn; private slots: void fileSelectionChange(); void addFile(); void removeFile(); void reloadFiles(); void addLabel(); void removeLabel(); void labelEdit(QTreeWidgetItem* item, int column); void labelChanged(QTreeWidgetItem* item, int column); void labelSelectionChanged(); void changeType(bool checked); void changeSlot(int id, int state); void changeSlot00(int state); void changeSlot01(int state); void changeSlot02(int state); void changeSlot03(int state); void changeSlot10(int state); void changeSlot11(int state); void changeSlot12(int state); void changeSlot13(int state); void changeSlot20(int state); void changeSlot21(int state); void changeSlot22(int state); void changeSlot23(int state); void changeSlot30(int state); void changeSlot31(int state); void changeSlot32(int state); void changeSlot33(int state); void changeRegister(int id, int state); void changeRegisterA(int state); void changeRegisterB(int state); void changeRegisterC(int state); void changeRegisterD(int state); void changeRegisterE(int state); void changeRegisterH(int state); void changeRegisterL(int state); void changeRegisterBC(int state); void changeRegisterDE(int state); void changeRegisterHL(int state); void changeRegisterIX(int state); void changeRegisterIY(int state); void changeRegisterIXL(int state); void changeRegisterIXH(int state); void changeRegisterIYL(int state); void changeRegisterIYH(int state); void changeRegisterOffset(int state); void changeRegisterI(int state); signals: void symbolTableChanged(); }; #endif // SYMBOLMANAGER_OPENMSX_H debugger-master/src/VramBitMappedView.cpp0000644000175000017500000001746313560352104020322 0ustar shevekshevek#include "VramBitMappedView.h" #include #include #include /** Clips x to the range [LO,HI]. * Slightly faster than std::min(HI, std::max(LO, x)) * especially when no clipping is required. */ template static inline int clip(int x) { return unsigned(x - LO) <= unsigned(HI - LO) ? x : (x < HI ? LO : HI); } VramBitMappedView::VramBitMappedView(QWidget* parent) : QWidget(parent) , image(512, 512, QImage::Format_RGB32) { lines = 212; screenMode = 5; borderColor = 0; pallet = NULL; vramBase = NULL; vramAddress = 0; for (int i = 0; i < 15; ++i) { msxpallet[i] = qRgb(80, 80, 80); } setZoom(1.0f); // mouse update events when mouse is moved over the image, Quibus likes this // better then my preferd click-on-the-image setMouseTracking(true); } void VramBitMappedView::setZoom(float zoom) { zoomFactor = std::max(1.0f, zoom); setFixedSize(int(512 * zoomFactor), int(lines * 2 * zoomFactor)); update(); } void VramBitMappedView::decode() { if (!vramBase) return; printf("\n" "screenMode: %i\n" "vram to start decoding: %i\n", screenMode, vramAddress); switch (screenMode) { case 12: decodeSCR12(); break; case 11: case 10: decodeSCR10(); break; case 8: decodeSCR8(); break; case 7: decodeSCR7(); break; case 6: decodeSCR6(); break; case 5: decodeSCR5(); break; } piximage = piximage.fromImage(image); update(); } void VramBitMappedView::decodePallet() { if (!pallet) return; for (int i = 0; i < 16; ++i) { int r = (pallet[2 * i + 0] & 0xf0) >> 4; int b = (pallet[2 * i + 0] & 0x0f); int g = (pallet[2 * i + 1] & 0x0f); r = (r >> 1) | (r << 2) | (r << 5); b = (b >> 1) | (b << 2) | (b << 5); g = (g >> 1) | (g << 2) | (g << 5); msxpallet[i] = qRgb(r, g, b); } } static unsigned interleave(unsigned x) { return (x >> 1) | ((x & 1) << 16); } void VramBitMappedView::setPixel2x2(int x, int y, QRgb c) { image.setPixel(2 * x + 0, 2 * y + 0, c); image.setPixel(2 * x + 1, 2 * y + 0, c); image.setPixel(2 * x + 0, 2 * y + 1, c); image.setPixel(2 * x + 1, 2 * y + 1, c); } void VramBitMappedView::setPixel1x2(int x, int y, QRgb c) { image.setPixel(x, 2 * y + 0, c); image.setPixel(x, 2 * y + 1, c); } void VramBitMappedView::decodeSCR12() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 4) { unsigned p[4]; p[0] = vramBase[interleave(offset++)]; p[1] = vramBase[interleave(offset++)]; p[2] = vramBase[interleave(offset++)]; p[3] = vramBase[interleave(offset++)]; int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3); int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3); for (unsigned n = 0; n < 4; ++n) { int z = p[n] >> 3; int r = clip<0, 31>(z + j); int g = clip<0, 31>(z + k); int b = clip<0, 31>((5 * z - 2 * j - k) / 4); r = (r << 3) | (r >> 2); b = (b << 3) | (b >> 2); g = (g << 3) | (g >> 2); setPixel2x2(x + n, y, qRgb(r, g, b)); } } } } void VramBitMappedView::decodeSCR10() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 4) { unsigned p[4]; p[0] = vramBase[interleave(offset++)]; p[1] = vramBase[interleave(offset++)]; p[2] = vramBase[interleave(offset++)]; p[3] = vramBase[interleave(offset++)]; int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3); int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3); for (unsigned n = 0; n < 4; ++n) { QRgb c; if (p[n] & 0x08) { // YAE c = msxpallet[p[n] >> 4]; } else { // YJK int z = p[n] >> 3; int r = clip<0, 31>(z + j); int g = clip<0, 31>(z + k); int b = clip<0, 31>((5 * z - 2 * j - k) / 4); r = (r << 3) | (r >> 2); b = (b << 3) | (b >> 2); g = (g << 3) | (g >> 2); c = qRgb(r, g, b); } setPixel2x2(x + n, y, c); } } } } void VramBitMappedView::decodeSCR8() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; ++x) { unsigned char val = vramBase[interleave(offset++)]; int b = val & 0x03; int r = val & 0x1C; int g = val & 0xE0; b = b | (b << 2) | (b << 4) | (b << 6); r = (r >> 2) | r | (r << 3); g = g | (g >> 3) | (g >> 6); setPixel2x2(x, y, qRgb(r, g, b)); } } } QRgb VramBitMappedView::getColor(int c) { // TODO do we need to look at the TP bit??? return msxpallet[c ? c : borderColor]; } void VramBitMappedView::decodeSCR7() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 512; x += 2) { int val = vramBase[interleave(offset++)]; setPixel1x2(x + 0, y, getColor((val >> 4) & 15)); setPixel1x2(x + 1, y, getColor((val >> 0) & 15)); } } } void VramBitMappedView::decodeSCR6() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 512; x += 4) { int val = vramBase[offset++]; setPixel1x2(x + 0, y, getColor((val >> 6) & 3)); setPixel1x2(x + 1, y, getColor((val >> 4) & 3)); setPixel1x2(x + 2, y, getColor((val >> 2) & 3)); setPixel1x2(x + 3, y, getColor((val >> 0) & 3)); } } } void VramBitMappedView::decodeSCR5() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 2) { int val = vramBase[offset++]; setPixel2x2(x + 0, y, getColor((val >> 4) & 15)); setPixel2x2(x + 1, y, getColor((val >> 0) & 15)); } } } void VramBitMappedView::paintEvent(QPaintEvent* event) { QRect srcRect(0, 0, 512, 2 * lines); QRect dstRect(0, 0, int(512 * zoomFactor), int(2 * lines * zoomFactor)); QPainter qp(this); //qp.drawImage(rect(),image,srcRect); qp.drawPixmap(dstRect, piximage, srcRect); } void VramBitMappedView::refresh() { decodePallet(); decode(); update(); } void VramBitMappedView::mouseMoveEvent(QMouseEvent* e) { static const unsigned bytes_per_line[] = { 0, //screen 0 1, //screen 1 2, // 2 3, // 3 4, 128, // 5 128, 256, // 7 256, 256, // 9 256, 256, 256 }; static const unsigned pixels_per_byte[] = { 0,1,2,3,4, 2, // 5 4, 2, // 7 1, 1, //9 1, 1, 1 }; int x = int(e->x() / zoomFactor); int y = int(e->y() / zoomFactor) / 2; // I see negative y-coords sometimes, so for safety clip the coords x = std::max(0, std::min(511, x)); y = std::max(0, std::min(255, y)); if ((screenMode != 6) && (screenMode != 7)) { x /= 2; } unsigned offset = bytes_per_line[screenMode] * y + x / pixels_per_byte[screenMode]; unsigned addr = offset + vramAddress; int val = (screenMode >= 7) ? vramBase[interleave(addr)] : vramBase[addr]; int color; switch (screenMode) { case 5: case 7: color = ((x & 1) ? val : (val >> 4)) & 15; break; case 6: color = (val >> (2 * (3 - (x & 3)))) & 3; break; case 8: case 10: case 11: case 12: color = val; break; default: color = 0; // avoid warning } emit imagePosition(x, y, color, addr, val); } void VramBitMappedView::mousePressEvent(QMouseEvent* e) { // since mouseMove only emits the correct signal we reuse/abuse that method mouseMoveEvent(e); decodePallet(); decode(); update(); } void VramBitMappedView::setBorderColor(int value) { borderColor = clip<0, 15>(value); decodePallet(); decode(); update(); } void VramBitMappedView::setScreenMode(int mode) { screenMode = mode; decode(); update(); } void VramBitMappedView::setLines(int nrLines) { lines = nrLines; decode(); setFixedSize(int(512 * zoomFactor), int(lines * 2 * zoomFactor)); update(); //setZoom(zoomFactor); } void VramBitMappedView::setVramAddress(int adr) { vramAddress = adr; decodePallet(); decode(); update(); } void VramBitMappedView::setVramSource(const unsigned char* adr) { vramBase = adr; decodePallet(); decode(); update(); } void VramBitMappedView::setPaletteSource(const unsigned char* adr) { pallet = adr; decodePallet(); decode(); update(); } debugger-master/src/DasmTables.cpp0000644000175000017500000003136413560352104017007 0ustar shevekshevek#include "DasmTables.h" /* * Letter codes in the instructions: * * A - Address * B - Byte value * R - Relative jump offset * W - Word value * X - Indexed address ( 3 byte ) * Y - Indexed address ( 4 byte ) * I - IX or IY register * ! - Invalid opcode * @ - Invalid opcode * # - Invalid opcode */ const char* const mnemonic_xx_cb[256] = { "#","#","#","#","#","#","rlc Y" ,"#", "#","#","#","#","#","#","rrc Y" ,"#", "#","#","#","#","#","#","rl Y" ,"#", "#","#","#","#","#","#","rr Y" ,"#", "#","#","#","#","#","#","sla Y" ,"#", "#","#","#","#","#","#","sra Y" ,"#", "#","#","#","#","#","#","sll Y" ,"#", "#","#","#","#","#","#","srl Y" ,"#", "#","#","#","#","#","#","bit 0,Y","#", "#","#","#","#","#","#","bit 1,Y","#", "#","#","#","#","#","#","bit 2,Y","#", "#","#","#","#","#","#","bit 3,Y","#", "#","#","#","#","#","#","bit 4,Y","#", "#","#","#","#","#","#","bit 5,Y","#", "#","#","#","#","#","#","bit 6,Y","#", "#","#","#","#","#","#","bit 7,Y","#", "#","#","#","#","#","#","res 0,Y","#", "#","#","#","#","#","#","res 1,Y","#", "#","#","#","#","#","#","res 2,Y","#", "#","#","#","#","#","#","res 3,Y","#", "#","#","#","#","#","#","res 4,Y","#", "#","#","#","#","#","#","res 5,Y","#", "#","#","#","#","#","#","res 6,Y","#", "#","#","#","#","#","#","res 7,Y","#", "#","#","#","#","#","#","set 0,Y","#", "#","#","#","#","#","#","set 1,Y","#", "#","#","#","#","#","#","set 2,Y","#", "#","#","#","#","#","#","set 3,Y","#", "#","#","#","#","#","#","set 4,Y","#", "#","#","#","#","#","#","set 5,Y","#", "#","#","#","#","#","#","set 6,Y","#", "#","#","#","#","#","#","set 7,Y","#" }; const char* const mnemonic_cb[256] = { "rlc b" ,"rlc c" ,"rlc d" ,"rlc e" ,"rlc h" ,"rlc l" ,"rlc (hl)" ,"rlc a" , "rrc b" ,"rrc c" ,"rrc d" ,"rrc e" ,"rrc h" ,"rrc l" ,"rrc (hl)" ,"rrc a" , "rl b" ,"rl c" ,"rl d" ,"rl e" ,"rl h" ,"rl l" ,"rl (hl)" ,"rl a" , "rr b" ,"rr c" ,"rr d" ,"rr e" ,"rr h" ,"rr l" ,"rr (hl)" ,"rr a" , "sla b" ,"sla c" ,"sla d" ,"sla e" ,"sla h" ,"sla l" ,"sla (hl)" ,"sla a" , "sra b" ,"sra c" ,"sra d" ,"sra e" ,"sra h" ,"sra l" ,"sra (hl)" ,"sra a" , "sll b" ,"sll c" ,"sll d" ,"sll e" ,"sll h" ,"sll l" ,"sll (hl)" ,"sll a" , "srl b" ,"srl c" ,"srl d" ,"srl e" ,"srl h" ,"srl l" ,"srl (hl)" ,"srl a" , "bit 0,b","bit 0,c","bit 0,d","bit 0,e","bit 0,h","bit 0,l","bit 0,(hl)","bit 0,a", "bit 1,b","bit 1,c","bit 1,d","bit 1,e","bit 1,h","bit 1,l","bit 1,(hl)","bit 1,a", "bit 2,b","bit 2,c","bit 2,d","bit 2,e","bit 2,h","bit 2,l","bit 2,(hl)","bit 2,a", "bit 3,b","bit 3,c","bit 3,d","bit 3,e","bit 3,h","bit 3,l","bit 3,(hl)","bit 3,a", "bit 4,b","bit 4,c","bit 4,d","bit 4,e","bit 4,h","bit 4,l","bit 4,(hl)","bit 4,a", "bit 5,b","bit 5,c","bit 5,d","bit 5,e","bit 5,h","bit 5,l","bit 5,(hl)","bit 5,a", "bit 6,b","bit 6,c","bit 6,d","bit 6,e","bit 6,h","bit 6,l","bit 6,(hl)","bit 6,a", "bit 7,b","bit 7,c","bit 7,d","bit 7,e","bit 7,h","bit 7,l","bit 7,(hl)","bit 7,a", "res 0,b","res 0,c","res 0,d","res 0,e","res 0,h","res 0,l","res 0,(hl)","res 0,a", "res 1,b","res 1,c","res 1,d","res 1,e","res 1,h","res 1,l","res 1,(hl)","res 1,a", "res 2,b","res 2,c","res 2,d","res 2,e","res 2,h","res 2,l","res 2,(hl)","res 2,a", "res 3,b","res 3,c","res 3,d","res 3,e","res 3,h","res 3,l","res 3,(hl)","res 3,a", "res 4,b","res 4,c","res 4,d","res 4,e","res 4,h","res 4,l","res 4,(hl)","res 4,a", "res 5,b","res 5,c","res 5,d","res 5,e","res 5,h","res 5,l","res 5,(hl)","res 5,a", "res 6,b","res 6,c","res 6,d","res 6,e","res 6,h","res 6,l","res 6,(hl)","res 6,a", "res 7,b","res 7,c","res 7,d","res 7,e","res 7,h","res 7,l","res 7,(hl)","res 7,a", "set 0,b","set 0,c","set 0,d","set 0,e","set 0,h","set 0,l","set 0,(hl)","set 0,a", "set 1,b","set 1,c","set 1,d","set 1,e","set 1,h","set 1,l","set 1,(hl)","set 1,a", "set 2,b","set 2,c","set 2,d","set 2,e","set 2,h","set 2,l","set 2,(hl)","set 2,a", "set 3,b","set 3,c","set 3,d","set 3,e","set 3,h","set 3,l","set 3,(hl)","set 3,a", "set 4,b","set 4,c","set 4,d","set 4,e","set 4,h","set 4,l","set 4,(hl)","set 4,a", "set 5,b","set 5,c","set 5,d","set 5,e","set 5,h","set 5,l","set 5,(hl)","set 5,a", "set 6,b","set 6,c","set 6,d","set 6,e","set 6,h","set 6,l","set 6,(hl)","set 6,a", "set 7,b","set 7,c","set 7,d","set 7,e","set 7,h","set 7,l","set 7,(hl)","set 7,a" }; const char* const mnemonic_ed[256] = { "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "in b,(c)","out (c),b","sbc hl,bc","ld (A),bc","neg","retn","im 0","ld i,a", "in c,(c)","out (c),c","adc hl,bc","ld bc,(A)","!" ,"reti","!" ,"ld r,a", "in d,(c)","out (c),d","sbc hl,de","ld (A),de","!" ,"!" ,"im 1","ld a,i", "in e,(c)","out (c),e","adc hl,de","ld de,(A)","!" ,"!" ,"im 2","ld a,r", "in h,(c)","out (c),h","sbc hl,hl","ld (A),hl","!" ,"!" ,"!" ,"rrd" , "in l,(c)","out (c),l","adc hl,hl","ld hl,(A)","!" ,"!" ,"!" ,"rld" , "in f,(c)","out (c),0","sbc hl,sp","ld (A),sp","!" ,"!" ,"!" ,"!" , "in a,(c)","out (c),a","adc hl,sp","ld sp,(A)","!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "ldi" ,"cpi" ,"ini" ,"outi" ,"!" ,"!" ,"!" ,"!" , "ldd" ,"cpd" ,"ind" ,"outd" ,"!" ,"!" ,"!" ,"!" , "ldir" ,"cpir" ,"inir" ,"otir" ,"!" ,"!" ,"!" ,"!" , "lddr" ,"cpdr" ,"indr" ,"otdr" ,"!" ,"!" ,"!" ,"!" , "!" ,"mulub a,b","!" ,"muluw hl,bc","!","!" ,"!" ,"!" , "!" ,"mulub a,c","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,d","!" ,"muluw hl,de","!","!" ,"!" ,"!" , "!" ,"mulub a,e","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,h","!" ,"muluw hl,hl","!","!" ,"!" ,"!" , "!" ,"mulub a,l","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,(hl)","!" ,"muluw hl,sp","!","!" ,"!" ,"!" , "!" ,"mulub a,a","!" ,"!" ,"!", "!" ,"!" ,"!" }; const char* const mnemonic_xx[256] = { "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"add I,bc","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"add I,de","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"ld I,W" ,"ld (A),I","inc I" ,"inc Ih" ,"dec Ih" ,"ld Ih,B","@" , "@" ,"add I,I" ,"ld I,(A)","dec I" ,"inc Il" ,"dec Il" ,"ld Il,B","@" , "@" ,"@" ,"@" ,"@" ,"inc X" ,"dec X" ,"ld X,B" ,"@" , "@" ,"add I,sp","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld b,Ih" ,"ld b,Il" ,"ld b,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld c,Ih" ,"ld c,Il" ,"ld c,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld d,Ih" ,"ld d,Il" ,"ld d,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld e,Ih" ,"ld e,Il" ,"ld e,X" ,"@" , "ld Ih,b","ld Ih,c" ,"ld Ih,d" ,"ld Ih,e" ,"ld Ih,h" ,"ld Ih,l" ,"ld h,X" ,"ld Ih,a", "ld Il,b","ld Il,c" ,"ld Il,d" ,"ld Il,e" ,"ld Il,h" ,"ld Il,l" ,"ld l,X" ,"ld Il,a", "ld X,b" ,"ld X,c" ,"ld X,d" ,"ld X,e" ,"ld X,h" ,"ld X,l" ,"@" ,"ld X,a" , "@" ,"@" ,"@" ,"@" ,"ld a,Ih" ,"ld a,Il" ,"ld a,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"add a,Ih","add a,Il","add a,X","@" , "@" ,"@" ,"@" ,"@" ,"adc a,Ih","adc a,Il","adc a,X","@" , "@" ,"@" ,"@" ,"@" ,"sub Ih" ,"sub Il" ,"sub X" ,"@" , "@" ,"@" ,"@" ,"@" ,"sbc a,Ih","sbc a,Il","sbc a,X","@" , "@" ,"@" ,"@" ,"@" ,"and Ih" ,"and Il" ,"and X" ,"@" , "@" ,"@" ,"@" ,"@" ,"xor Ih" ,"xor Il" ,"xor X" ,"@" , "@" ,"@" ,"@" ,"@" ,"or Ih" ,"or Il" ,"or X" ,"@" , "@" ,"@" ,"@" ,"@" ,"cp Ih" ,"cp Il" ,"cp X" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"fd cb" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"pop I" ,"@" ,"ex (sp),I","@" ,"push I" ,"@" ,"@" , "@" ,"jp (I)" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"ld sp,I" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" }; const char* const mnemonic_main[256] = { "nop" ,"ld bc,W" ,"ld (bc),a","inc bc" ,"inc b" ,"dec b" ,"ld b,B" ,"rlca" , "ex af,af'","add hl,bc","ld a,(bc)","dec bc" ,"inc c" ,"dec c" ,"ld c,B" ,"rrca" , "djnz R" ,"ld de,W" ,"ld (de),a","inc de" ,"inc d" ,"dec d" ,"ld d,B" ,"rla" , "jr R" ,"add hl,de","ld a,(de)","dec de" ,"inc e" ,"dec e" ,"ld e,B" ,"rra" , "jr nz,R" ,"ld hl,W" ,"ld (A),hl","inc hl" ,"inc h" ,"dec h" ,"ld h,B" ,"daa" , "jr z,R" ,"add hl,hl","ld hl,(A)","dec hl" ,"inc l" ,"dec l" ,"ld l,B" ,"cpl" , "jr nc,R" ,"ld sp,W" ,"ld (A),a" ,"inc sp" ,"inc (hl)" ,"dec (hl)" ,"ld (hl),B" ,"scf" , "jr c,R" ,"add hl,sp","ld a,(A)" ,"dec sp" ,"inc a" ,"dec a" ,"ld a,B" ,"ccf" , "ld b,b" ,"ld b,c" ,"ld b,d" ,"ld b,e" ,"ld b,h" ,"ld b,l" ,"ld b,(hl)" ,"ld b,a" , "ld c,b" ,"ld c,c" ,"ld c,d" ,"ld c,e" ,"ld c,h" ,"ld c,l" ,"ld c,(hl)" ,"ld c,a" , "ld d,b" ,"ld d,c" ,"ld d,d" ,"ld d,e" ,"ld d,h" ,"ld d,l" ,"ld d,(hl)" ,"ld d,a" , "ld e,b" ,"ld e,c" ,"ld e,d" ,"ld e,e" ,"ld e,h" ,"ld e,l" ,"ld e,(hl)" ,"ld e,a" , "ld h,b" ,"ld h,c" ,"ld h,d" ,"ld h,e" ,"ld h,h" ,"ld h,l" ,"ld h,(hl)" ,"ld h,a" , "ld l,b" ,"ld l,c" ,"ld l,d" ,"ld l,e" ,"ld l,h" ,"ld l,l" ,"ld l,(hl)" ,"ld l,a" , "ld (hl),b","ld (hl),c","ld (hl),d","ld (hl),e" ,"ld (hl),h","ld (hl),l","halt" ,"ld (hl),a", "ld a,b" ,"ld a,c" ,"ld a,d" ,"ld a,e" ,"ld a,h" ,"ld a,l" ,"ld a,(hl)" ,"ld a,a" , "add a,b" ,"add a,c" ,"add a,d" ,"add a,e" ,"add a,h" ,"add a,l" ,"add a,(hl)","add a,a" , "adc a,b" ,"adc a,c" ,"adc a,d" ,"adc a,e" ,"adc a,h" ,"adc a,l" ,"adc a,(hl)","adc a,a" , "sub b" ,"sub c" ,"sub d" ,"sub e" ,"sub h" ,"sub l" ,"sub (hl)" ,"sub a" , "sbc a,b" ,"sbc a,c" ,"sbc a,d" ,"sbc a,e" ,"sbc a,h" ,"sbc a,l" ,"sbc a,(hl)","sbc a,a" , "and b" ,"and c" ,"and d" ,"and e" ,"and h" ,"and l" ,"and (hl)" ,"and a" , "xor b" ,"xor c" ,"xor d" ,"xor e" ,"xor h" ,"xor l" ,"xor (hl)" ,"xor a" , "or b" ,"or c" ,"or d" ,"or e" ,"or h" ,"or l" ,"or (hl)" ,"or a" , "cp b" ,"cp c" ,"cp d" ,"cp e" ,"cp h" ,"cp l" ,"cp (hl)" ,"cp a" , "ret nz" ,"pop bc" ,"jp nz,A" ,"jp A" ,"call nz,A","push bc" ,"add a,B" ,"rst 00h" , "ret z" ,"ret" ,"jp z,A" ,"cb" ,"call z,A" ,"call A" ,"adc a,B" ,"rst 08h" , "ret nc" ,"pop de" ,"jp nc,A" ,"out (B),a" ,"call nc,A","push de" ,"sub B" ,"rst 10h" , "ret c" ,"exx" ,"jp c,A" ,"in a,(B)" ,"call c,A" ,"dd" ,"sbc a,B" ,"rst 18h" , "ret po" ,"pop hl" ,"jp po,A" ,"ex (sp),hl","call po,A","push hl" ,"and B" ,"rst 20h" , "ret pe" ,"jp (hl)" ,"jp pe,A" ,"ex de,hl" ,"call pe,A","ed" ,"xor B" ,"rst 28h" , "ret p" ,"pop af" ,"jp p,A" ,"di" ,"call p,A" ,"push af" ,"or B" ,"rst 30h" , "ret m" ,"ld sp,hl" ,"jp m,A" ,"ei" ,"call m,A" ,"fd" ,"cp B" ,"rst 38h" }; debugger-master/src/StackViewer.h0000644000175000017500000000145513560352104016662 0ustar shevekshevek#ifndef STACKVIEWER_H #define STACKVIEWER_H #include class StackRequest; class QScrollBar; class QPaintEvent; class StackViewer : public QFrame { Q_OBJECT; public: StackViewer(QWidget* parent = 0); void setData(unsigned char* memPtr, int memLength); QSize sizeHint() const; public slots: void setLocation(int addr); void setStackPointer(quint16 addr); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void setScrollBarValues(); void memdataTransfered(StackRequest* r); void transferCancelled(StackRequest* r); QScrollBar* vertScrollBar; int frameL, frameR, frameT, frameB; double visibleLines; bool waitingForData; int stackPointer; int topAddress; unsigned char* memory; int memoryLength; friend class StackRequest; }; #endif // STACKVIEWER_H debugger-master/src/GotoDialog.cpp0000644000175000017500000000251013560352104017007 0ustar shevekshevek#include "GotoDialog.h" #include "DebugSession.h" #include "Convert.h" #include GotoDialog::GotoDialog(const MemoryLayout& ml, DebugSession *session, QWidget* parent) : QDialog(parent), memLayout(ml), currentSymbol(0) { setupUi(this); debugSession = session; if( session ) { // create address completer QCompleter *completer = new QCompleter(session->symbolTable().labelList(true, &ml), this); completer->setCaseSensitivity(Qt::CaseInsensitive); edtAddress->setCompleter(completer); connect(completer, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); } connect(edtAddress, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); } int GotoDialog::address() { if(currentSymbol) return currentSymbol->value(); else return stringToValue(edtAddress->text()); } void GotoDialog::addressChanged(const QString& text) { int addr = stringToValue(text); if (addr == -1 && debugSession) { // try finding a label currentSymbol = debugSession->symbolTable().getAddressSymbol(text); if (!currentSymbol) currentSymbol = debugSession->symbolTable().getAddressSymbol(text, Qt::CaseInsensitive); if (currentSymbol) addr = currentSymbol->value(); } QPalette pal; pal.setColor(QPalette::Text, addr==-1 ? Qt::red : Qt::black); edtAddress->setPalette(pal); } debugger-master/src/InteractiveButton.h0000644000175000017500000000133413560352104020100 0ustar shevekshevek#ifndef INTERACTIVEBUTTON #define INTERACTIVEBUTTON #include class InteractiveButton : public QPushButton { Q_OBJECT public: InteractiveButton(QWidget* parent = 0); protected: virtual void enterEvent(QEvent* event); virtual void leaveEvent(QEvent* event); signals: void mouseOver(bool state); // this one is specific for the VDPRegViewer and depends on the // name of the button also void newBitValue(int reg, int bit, bool state); public slots: void highlight(bool state); void mustBeSet(bool state); private slots: // this one is specific for the VDPRegViewer void newBitValueSlot(bool); private: void setColor(); bool _mustBeSet; bool _highlight; bool _state; }; #endif // INTERACTIVEBUTTON debugger-master/src/DisasmViewer.h0000644000175000017500000000375113560352104017036 0ustar shevekshevek#ifndef DISASMVIEWER_H #define DISASMVIEWER_H #include "Dasm.h" #include #include class CommMemoryRequest; class QScrollBar; class Breakpoints; class SymbolTable; struct MemoryLayout; class DisasmViewer : public QFrame { Q_OBJECT; public: DisasmViewer(QWidget* parent = 0); void setMemory(unsigned char* memPtr); void setBreakpoints(Breakpoints* bps); void setMemoryLayout(MemoryLayout* ml); void setSymbolTable(SymbolTable* st); void memoryUpdated(CommMemoryRequest* req); void updateCancelled(CommMemoryRequest* req); quint16 programCounter() const; quint16 cursorAddress() const; QSize sizeHint() const; enum {Top, Middle, Bottom, Closest, TopAlways, MiddleAlways, BottomAlways}; public slots: void setAddress(quint16 addr, int infoLine = FIRST_INFO_LINE, int method = Top); void setCursorAddress(quint16 addr, int infoLine = FIRST_INFO_LINE, int method = Top); void setProgramCounter(quint16 pc); void scrollBarAction(int action); void scrollBarChanged(int value); void settingsChanged(); void symbolsChanged(); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void keyPressEvent(QKeyEvent* e); void mousePressEvent(QMouseEvent* e); void wheelEvent(QWheelEvent* e); QScrollBar* scrollBar; QPixmap breakMarker; QPixmap watchMarker; QPixmap pcMarker; quint16 programAddr; quint16 cursorAddr; int cursorLine; QList jumpStack; // layout information int frameL, frameR, frameT, frameB; int labelFontHeight, labelFontAscent; int codeFontHeight, codeFontAscent; int xAddr, xMCode[4], xMnem, xMnemArg; int visibleLines, partialBottomLine; int disasmTopLine; DisasmLines disasmLines; // display data unsigned char* memory; bool waitingForData; CommMemoryRequest* nextRequest; Breakpoints* breakpoints; MemoryLayout* memLayout; SymbolTable* symTable; int findDisasmLine(quint16 lineAddr, int infoLine = 0); int lineAtPos(const QPoint& pos); signals: void toggleBreakpoint(int addr); }; #endif // DISASMVIEWER_H debugger-master/src/Version.cpp0000644000175000017500000000030713560352104016406 0ustar shevekshevek#include "Version.h" #include "Version.ii" std::string Version::full() { return std::string("openMSX Debugger ") + VERSION + (RELEASE ? "" : (std::string("-") + REVISION)); } debugger-master/src/OpenMSXConnection.h0000644000175000017500000000514013560352104017737 0ustar shevekshevek#ifndef OPENMSXCONNECTION_HH #define OPENMSXCONNECTION_HH #include #include #include #include #include class QXmlInputSource; class QXmlSimpleReader; class Command { public: virtual ~Command() {} virtual QString getCommand() const = 0; virtual void replyOk (const QString& message) = 0; virtual void replyNok(const QString& message) = 0; virtual void cancel() = 0; }; class SimpleCommand : public QObject, public Command { Q_OBJECT public: SimpleCommand(const QString& command); virtual QString getCommand() const; virtual void replyOk (const QString& message); virtual void replyNok(const QString& message); virtual void cancel(); signals: void replyStatusOk(bool status); private: QString command; }; class ReadDebugBlockCommand : public SimpleCommand { public: ReadDebugBlockCommand(const QString& commandString, unsigned size, unsigned char* target); ReadDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char* target); protected: void copyData(const QString& message); private: unsigned size; unsigned char* target; }; class WriteDebugBlockCommand : public SimpleCommand { public: WriteDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char* source); }; class OpenMSXConnection : public QObject, private QXmlDefaultHandler { Q_OBJECT public: /** require: socket must be in connected state */ OpenMSXConnection(QAbstractSocket* socket); ~OpenMSXConnection(); void sendCommand(Command* command); signals: void disconnected(); void logParsed(const QString& level, const QString& message); void updateParsed(const QString& type, const QString& name, const QString& message); private slots: void processData(); void socketStateChanged(QAbstractSocket::SocketState state); void socketError(QAbstractSocket::SocketError state); private: void cleanup(); void cancelPending(); // QXmlDefaultHandler bool fatalError(const QXmlParseException& exception); bool startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName); bool characters(const QString& ch); //std::unique_ptr socket; QAbstractSocket* socket; std::unique_ptr input; std::unique_ptr reader; QString xmlData; QXmlAttributes xmlAttrs; QQueue commands; bool connected; }; #endif debugger-master/src/DebuggerData.cpp0000644000175000017500000002606513560352104017310 0ustar shevekshevek#include "DebuggerData.h" #include "Convert.h" #include #include // class MemoryLayout MemoryLayout::MemoryLayout() { for (int p = 0; p < 4; ++p) { primarySlot[p] = '0'; secondarySlot[p] = 'X'; mapperSegment[p] = 0; isSubslotted[p] = false; for (int q = 0; q < 4; ++q) { mapperSize[p][q] = 0; } } } // class Breakpoints static const char *BreakpointSetCodes[] = { "set_bp", "set_watchpoint read_mem", "set_watchpoint write_mem", "set_watchpoint read_io", "set_watchpoint write_io", "set_condition" }; static QString getNextArgument(QString& data, int& pos) { QString result; while (data[pos] == ' ' || data[pos] == '\t') ++pos; while (true) { if (data[pos] == ' ' || data[pos] == '\t') break; if (data[pos] == '}' || data[pos] == ']') break; result += data[pos]; ++pos; } return result; } bool Breakpoints::Breakpoint::operator==(const Breakpoint &bp) const { if (bp.type != type) return false; // compare address if (type != CONDITION) { if (bp.address != address) return false; if (type != BREAKPOINT) { int re1 = -1, re2 = -1; if (bp.regionEnd != -1 && bp.regionEnd != bp.address) re1 = bp.regionEnd; if ( regionEnd != -1 && regionEnd != address) re2 = regionEnd; if (re1 != re2) return false; } // compare slot if (bp.ps != ps || bp.ss != ss || bp.segment != segment) return false; } // compare condition return bp.condition == condition; } Breakpoints::Breakpoints() : memLayout(NULL) { } void Breakpoints::clear() { breakpoints.clear(); } void Breakpoints::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } QString Breakpoints::createSetCommand(Type type, int address, char ps, char ss, int segment, int endRange, QString condition) { QString cmd("debug %1 %2 %3"); QString addr, cond; // address or range if (type > BREAKPOINT && type < CONDITION && endRange > address) addr = QString("{%1 %2}").arg(address).arg(endRange); else addr = QString::number(address); // condition if (type == CONDITION) { cond = QString("{%1}").arg(condition); } else { condition = condition.simplified(); cond = QString("{ [ %1_in_slot %2 %3 %4 ] %5}") .arg(type == WATCHPOINT_MEMREAD || type == WATCHPOINT_MEMWRITE ? "watch" : "pc") .arg(ps==-1 ? 'X' : char('0'+ps)) .arg(ss==-1 ? 'X' : char('0'+ss)) .arg(segment==-1 ? QString('X') : QString::number(segment)) .arg(condition.isEmpty() ? QString() : QString("&& ( %1 ) ").arg(condition)); } return cmd.arg(BreakpointSetCodes[type]) .arg(addr) .arg(escapeXML(cond)); } QString Breakpoints::createRemoveCommand(const QString& id) { // find breakpoint QString cmd("debug remove_"); if (id.startsWith("bp")) cmd += "bp "; else if (id.startsWith("wp")) cmd += "watchpoint "; else cmd += "condition "; cmd += id; return cmd; } void Breakpoints::setBreakpoints(const QString& str) { breakpoints.clear(); QStringList bps = str.split('\n'); for (QStringList::Iterator it = bps.begin(); it != bps.end(); ++it) { if ( it->trimmed().isEmpty() ) continue; Breakpoint newBp; // set id int p = 0; newBp.id = getNextArgument(*it, p); // determine type if( it->startsWith("bp#") ) newBp.type = BREAKPOINT; else if( it->startsWith("wp#") ) { // determine watchpoint type QString wptype = getNextArgument(*it, p); if(wptype == "read_mem") newBp.type = WATCHPOINT_MEMREAD; else if(wptype == "write_mem") newBp.type = WATCHPOINT_MEMWRITE; else if(wptype == "read_io") newBp.type = WATCHPOINT_IOREAD; else if(wptype == "write_io") newBp.type = WATCHPOINT_IOWRITE; else //unknown continue; } else if( it->startsWith("cond#") ) { newBp.type = CONDITION; } else { // unknown continue; } // get address p++; if( newBp.type != CONDITION ) { if ((*it)[p] == '{') { p++; newBp.address = stringToValue(getNextArgument(*it, p)); int q = it->indexOf('}', p); newBp.regionEnd = stringToValue(it->mid(p, q-p)); p = q+1; } else { newBp.address = stringToValue(getNextArgument(*it, p)); newBp.regionEnd = newBp.address; } } else newBp.address = -1; // check and clip command (skip non-default commands) int q = it->lastIndexOf('{'); if (it->mid(q).simplified() != "{debug break}") continue; newBp.condition = it->mid(p, q-p).simplified(); unescapeXML(newBp.condition); parseCondition(newBp); insertBreakpoint(newBp); } } QString Breakpoints::mergeBreakpoints(const QString& str) { // copy breakpoints BreakpointList oldBps(breakpoints); // parse new list setBreakpoints(str); // check old list against new one QStringList mergeSet; while (!oldBps.empty()) { Breakpoint& old = oldBps.first(); BreakpointList::iterator newit = breakpoints.begin(); for (/**/; newit != breakpoints.end(); ++newit) { // check for identical data if (old == *newit) break; } if (newit == breakpoints.end()) { // create command to set this breakpoint again QString cmd = createSetCommand(old.type, old.address, old.ps, old.ss, old.segment, old.regionEnd, old.condition); mergeSet << cmd; } oldBps.removeFirst(); } return mergeSet.join(" ; "); } void Breakpoints::parseCondition(Breakpoint& bp) { bp.ps = -1; bp.ss = -1; bp.segment = -1; // first split off braces if (bp.condition[0] == '{' && bp.condition.endsWith('}')) { if (bp.type != CONDITION) { // check for slot argument QRegExp rx("^\\{\\s*\\[\\s*(pc|watch)_in_slot\\s([X0123])\\s([X0123])\\s(X|\\d{1,3})\\s*\\]\\s*(&&\\s*\\((.+)\\)\\s*)?\\}$"); if (rx.indexIn(bp.condition) == 0) { bool ok; bp.ps = rx.cap(2).toInt(&ok); if (!ok) bp.ps = -1; bp.ss = rx.cap(3).toInt(&ok); if (!ok) bp.ss = -1; bp.segment = rx.cap(4).toInt(&ok); if (!ok) bp.segment = -1; bp.condition = rx.cap(6).trimmed(); } else { bp.condition.chop(1); bp.condition = bp.condition.mid(1).trimmed(); } } else { bp.condition.chop(1); bp.condition = bp.condition.mid(1).trimmed(); } } } bool Breakpoints::inCurrentSlot(const Breakpoint& bp) { if (memLayout == NULL) return true; int page = (bp.address & 0xC000) >> 14; if (bp.ps == -1 || bp.ps == memLayout->primarySlot[page]) { if (memLayout->isSubslotted[bp.ps & 3]) { if (bp.ss == -1 || bp.ss == memLayout->secondarySlot[page]) { if (memLayout->mapperSize[bp.ps & 3][bp.ss & 3] > 0) { if (bp.segment == memLayout->mapperSegment[page]) { return true; } } else { return true; } } } else if (memLayout->mapperSize[bp.ps & 3][0] > 0) { if (bp.segment == memLayout->mapperSegment[page]) { return true; } } else { return true; } } return false; } void Breakpoints::insertBreakpoint(Breakpoint& bp) { for (BreakpointList::iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { if (it->address > bp.address) { breakpoints.insert(it, bp); return; } } breakpoints.append(bp); } int Breakpoints::breakpointCount() { return breakpoints.size(); } bool Breakpoints::isBreakpoint(quint16 addr, QString *id) { for (BreakpointList::const_iterator it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) { if (it->type == BREAKPOINT && it->address == addr) { if (inCurrentSlot(*it)) { if (id) *id = it->id; return true; } } } return false; } bool Breakpoints::isWatchpoint(quint16 addr, QString *id) { for (BreakpointList::const_iterator it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) { if (it->type == WATCHPOINT_MEMREAD || it->type == WATCHPOINT_MEMWRITE) if ( (it->address == addr && it->regionEnd < it->address) || (addr >= it->address && addr <= it->regionEnd) ) { if (inCurrentSlot(*it)) { if (id) *id = it->id; return true; } } } return false; } int Breakpoints::findBreakpoint(quint16 addr) { // stub // will implement findfirst/findnext scheme for speed return addr; } int Breakpoints::findNextBreakpoint() { // stub // will implement findfirst/findnext scheme for speed return -1; } void Breakpoints::saveBreakpoints(QXmlStreamWriter& xml) { // write symbols for (BreakpointList::iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { xml.writeStartElement("Breakpoint"); // type switch (it->type) { case BREAKPOINT: xml.writeAttribute("type", "breakpoint"); break; case WATCHPOINT_IOREAD: xml.writeAttribute("type", "ioread"); break; case WATCHPOINT_IOWRITE: xml.writeAttribute("type", "iowrite"); break; case WATCHPOINT_MEMREAD: xml.writeAttribute("type", "memread"); break; case WATCHPOINT_MEMWRITE: xml.writeAttribute("type", "memwrite"); break; case CONDITION: xml.writeAttribute("type", "condition"); break; } // id xml.writeAttribute("id", it->id); // slot/segment xml.writeAttribute("primarySlot", QString(it->ps < 0 ? '*' : char('0'+it->ps))); xml.writeAttribute("secondarySlot", QString(it->ss < 0 ? '*' : char('0'+it->ss))); xml.writeAttribute("segment", QString::number(it->segment)); // address if (it->type == BREAKPOINT) { xml.writeTextElement("address", QString::number(it->address)); } else if (it->type != CONDITION) { xml.writeTextElement("regionStart", QString::number(it->address)); xml.writeTextElement("regionEnd", QString::number(it->regionEnd)); } // condition xml.writeTextElement("condition", it->condition); // complete xml.writeEndElement(); } } void Breakpoints::loadBreakpoints(QXmlStreamReader& xml) { Breakpoint bp; while (!xml.atEnd()) { xml.readNext(); // exit if closing of main tag if (xml.isEndElement()) { if (xml.name() == "Breakpoints") { break; } else if (xml.name() == "Breakpoint") { insertBreakpoint(bp); } } // begin tag if (xml.isStartElement()) { if (xml.name() == "Breakpoint") { // set type QString type = xml.attributes().value("type").toString().toLower(); if (type == "ioread") { bp.type = WATCHPOINT_IOREAD; } else if (type == "iowrite") { bp.type = WATCHPOINT_IOWRITE; } else if (type == "memread") { bp.type = WATCHPOINT_MEMREAD; } else if (type == "memwrite") { bp.type = WATCHPOINT_MEMWRITE; } else if (type == "condition") { bp.type = CONDITION; } else { bp.type = BREAKPOINT; } // id bp.id = xml.attributes().value("id").toString(); // slot/segment char c = xml.attributes().value("primarySlot").at(0).toLatin1(); bp.ps = c >= '0' && c <= '3' ? c - '0' : -1; c = xml.attributes().value("secondarySlot").at(0).toLatin1(); bp.ss = c >= '0' && c <= '3' ? c - '0' : -1; bp.segment = xml.attributes().value("segment").toString().toInt(); } else if (xml.name() == "address" || xml.name() == "regionStart") { // read symbol name bp.address = xml.readElementText().toInt(); if (bp.type == BREAKPOINT) bp.regionEnd = bp.address; } else if (xml.name() == "regionEnd") { // read symbol name bp.regionEnd = xml.readElementText().toInt(); } else if (xml.name() == "condition") { bp.condition = xml.readElementText().simplified(); } } } } debugger-master/src/DebuggerForm.cpp0000644000175000017500000012672613560352104017347 0ustar shevekshevek#include "DebuggerForm.h" #include "BitMapViewer.h" #include "DockableWidgetArea.h" #include "DockableWidget.h" #include "DisasmViewer.h" #include "MainMemoryViewer.h" #include "CPURegsViewer.h" #include "FlagsViewer.h" #include "StackViewer.h" #include "SlotViewer.h" #include "CommClient.h" #include "ConnectDialog.h" #include "SymbolManager.h" #include "PreferencesDialog.h" #include "BreakpointDialog.h" #include "GotoDialog.h" #include "DebuggableViewer.h" #include "VDPRegViewer.h" #include "VDPStatusRegViewer.h" #include "VDPCommandRegViewer.h" #include "Settings.h" #include "Version.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QueryPauseHandler : public SimpleCommand { public: QueryPauseHandler(DebuggerForm& form_) : SimpleCommand("set pause") , form(form_) { } virtual void replyOk(const QString& message) { // old openmsx versions returned 'on','false' // new versions return 'true','false' // so check for 'false' bool checked = message.trimmed() != "false"; form.systemPauseAction->setChecked(checked); delete this; } private: DebuggerForm& form; }; class QueryBreakedHandler : public SimpleCommand { public: QueryBreakedHandler(DebuggerForm& form_) : SimpleCommand("debug breaked") , form(form_) { } virtual void replyOk(const QString& message) { form.finalizeConnection(message.trimmed() == "1"); delete this; } private: DebuggerForm& form; }; class ListBreakPointsHandler : public SimpleCommand { public: ListBreakPointsHandler(DebuggerForm& form_, bool merge_ = false) : SimpleCommand("debug_list_all_breaks") , form(form_), merge(merge_) { } virtual void replyOk(const QString& message) { if (merge) { QString bps = form.session.breakpoints().mergeBreakpoints(message); if (!bps.isEmpty()) { form.comm.sendCommand(new SimpleCommand(bps)); form.comm.sendCommand(new ListBreakPointsHandler(form, false)); } else { form.disasmView->update(); form.session.sessionModified(); form.updateWindowTitle(); } } else { form.session.breakpoints().setBreakpoints(message); form.disasmView->update(); form.session.sessionModified(); form.updateWindowTitle(); } delete this; } private: DebuggerForm& form; bool merge; }; class CPURegRequest : public ReadDebugBlockCommand { public: CPURegRequest(DebuggerForm& form_) : ReadDebugBlockCommand("{CPU regs}", 0, 28, buf) , form(form_) { } virtual void replyOk(const QString& message) { copyData(message); form.regsView->setData(buf); delete this; } private: DebuggerForm& form; unsigned char buf[28]; }; class ListDebuggablesHandler : public SimpleCommand { public: ListDebuggablesHandler(DebuggerForm& form_) : SimpleCommand("debug list") , form(form_) { } virtual void replyOk(const QString& message) { form.setDebuggables(message); delete this; } private: DebuggerForm& form; }; class DebuggableSizeHandler : public SimpleCommand { public: DebuggableSizeHandler(const QString& debuggable_, DebuggerForm& form_) : SimpleCommand(QString("debug size %1").arg(debuggable_)) , debuggable(debuggable_) , form(form_) { } virtual void replyOk(const QString& message) { form.setDebuggableSize(debuggable, message.toInt()); delete this; } private: QString debuggable; DebuggerForm& form; }; DebuggerForm::DebuggerForm(QWidget* parent) : QMainWindow(parent) , comm(CommClient::instance()) { VDPRegView = NULL; VDPStatusRegView = NULL; VDPCommandRegView = NULL; createActions(); createMenus(); createToolbars(); createStatusbar(); createForm(); recentFiles = Settings::get().value("MainWindow/RecentFiles").toStringList(); updateRecentFiles(); connect(&session.symbolTable(), SIGNAL(symbolFileChanged()), this, SLOT(symbolFileChanged())); } void DebuggerForm::createActions() { fileNewSessionAction = new QAction(tr("&New Session"), this); fileNewSessionAction->setStatusTip(tr("Clear the current session.")); fileOpenSessionAction = new QAction(tr("&Open Session ..."), this); fileOpenSessionAction->setShortcut(tr("Ctrl+O")); fileOpenSessionAction->setStatusTip(tr("Clear the current session.")); fileSaveSessionAction = new QAction(tr("&Save Session"), this); fileSaveSessionAction->setShortcut(tr("Ctrl+S")); fileSaveSessionAction->setStatusTip(tr("Save the the current debug session")); fileSaveSessionAsAction = new QAction(tr("Save Session &As"), this); fileSaveSessionAsAction->setStatusTip(tr("Save the debug session in a selected file")); fileQuitAction = new QAction(tr("&Quit"), this); fileQuitAction->setShortcut(tr("Ctrl+Q")); fileQuitAction->setStatusTip(tr("Quit the openMSX debugger")); for (int i = 0; i < MaxRecentFiles; ++i) { recentFileActions[i] = new QAction(this); connect(recentFileActions[i], SIGNAL(triggered()), this, SLOT(fileRecentOpen())); } systemConnectAction = new QAction(tr("&Connect"), this); systemConnectAction->setShortcut(tr("Ctrl+C")); systemConnectAction->setStatusTip(tr("Connect to openMSX")); systemConnectAction->setIcon(QIcon(":/icons/connect.png")); systemDisconnectAction = new QAction(tr("&Disconnect"), this); systemDisconnectAction->setShortcut(tr("")); systemDisconnectAction->setStatusTip(tr("Disconnect from openMSX")); systemDisconnectAction->setIcon(QIcon(":/icons/disconnect.png")); systemDisconnectAction->setEnabled(false); systemPauseAction = new QAction(tr("&Pause emulator"), this); systemPauseAction->setShortcut(Qt::Key_Pause); systemPauseAction->setStatusTip(tr("Pause the emulation")); systemPauseAction->setIcon(QIcon(":/icons/pause.png")); systemPauseAction->setCheckable(true); systemPauseAction->setEnabled(false); systemRebootAction = new QAction(tr("&Reboot emulator"), this); systemRebootAction->setStatusTip(tr("Reboot the emulation and start if needed")); systemRebootAction->setEnabled(false); systemSymbolManagerAction = new QAction(tr("&Symbol manager ..."), this); systemSymbolManagerAction->setStatusTip(tr("Start the symbol manager")); systemSymbolManagerAction->setIcon(QIcon(":/icons/symmanager.png")); systemPreferencesAction = new QAction(tr("Pre&ferences ..."), this); systemPreferencesAction->setStatusTip(tr("Set the global debugger preferences")); searchGotoAction = new QAction(tr("&Goto ..."), this); searchGotoAction->setStatusTip(tr("Jump to a specific address or label in the disassembly view")); searchGotoAction->setShortcut(tr("Ctrl+G")); viewRegistersAction = new QAction(tr("CPU &Registers"), this); viewRegistersAction->setStatusTip(tr("Toggle the cpu registers display")); viewRegistersAction->setCheckable(true); viewFlagsAction = new QAction(tr("CPU &Flags"), this); viewFlagsAction->setStatusTip(tr("Toggle the cpu flags display")); viewFlagsAction->setCheckable(true); viewStackAction = new QAction(tr("Stack"), this); viewStackAction->setStatusTip(tr("Toggle the stack display")); viewStackAction->setCheckable(true); viewSlotsAction = new QAction(tr("Slots"), this); viewSlotsAction->setStatusTip(tr("Toggle the slots display")); viewSlotsAction->setCheckable(true); viewMemoryAction = new QAction(tr("Memory"), this); viewMemoryAction->setStatusTip(tr("Toggle the main memory display")); viewMemoryAction->setCheckable(true); viewDebuggableViewerAction = new QAction(tr("Add debuggable viewer"), this); viewDebuggableViewerAction->setStatusTip(tr("Add a hex viewer for debuggables")); viewVDPStatusRegsAction = new QAction(tr("Status Registers"), this); viewVDPStatusRegsAction->setStatusTip(tr("The VDP status registers interpreted")); viewVDPStatusRegsAction->setCheckable(true); viewVDPCommandRegsAction = new QAction(tr("Command Registers"), this); viewVDPCommandRegsAction->setStatusTip(tr("Interact with the VDP command registers")); viewVDPCommandRegsAction->setCheckable(true); viewVDPRegsAction = new QAction(tr("Registers"), this); viewVDPRegsAction->setStatusTip(tr("Interact with the VDP registers")); viewVDPRegsAction->setCheckable(true); viewBitMappedAction = new QAction(tr("Bitmapped VRAM"), this); viewBitMappedAction->setStatusTip(tr("Decode VRAM as screen 5/6/7/8 image")); //viewBitMappedAction->setCheckable(true); executeBreakAction = new QAction(tr("Break"), this); executeBreakAction->setShortcut(tr("CRTL+B")); executeBreakAction->setStatusTip(tr("Halt the execution and enter debug mode")); executeBreakAction->setIcon(QIcon(":/icons/break.png")); executeBreakAction->setEnabled(false); executeRunAction = new QAction(tr("Run"), this); executeRunAction->setShortcut(tr("F9")); executeRunAction->setStatusTip(tr("Leave debug mode and resume execution")); executeRunAction->setIcon(QIcon(":/icons/run.png")); executeRunAction->setEnabled(false); executeStepAction = new QAction(tr("Step into"), this); executeStepAction->setShortcut(tr("F7")); executeStepAction->setStatusTip(tr("Execute a single instruction")); executeStepAction->setIcon(QIcon(":/icons/stepinto.png")); executeStepAction->setEnabled(false); executeStepOverAction = new QAction(tr("Step over"), this); executeStepOverAction->setShortcut(tr("F8")); executeStepOverAction->setStatusTip(tr("Execute the next instruction including any called subroutines")); executeStepOverAction->setIcon(QIcon(":/icons/stepover.png")); executeStepOverAction->setEnabled(false); executeStepOutAction = new QAction(tr("Step out"), this); executeStepOutAction->setShortcut(tr("F11")); executeStepOutAction->setStatusTip(tr("Resume execution until the current routine has finished")); executeStepOutAction->setIcon(QIcon(":/icons/stepout.png")); executeStepOutAction->setEnabled(false); executeStepBackAction = new QAction(tr("Step back"), this); executeStepBackAction->setShortcut(tr("F12")); executeStepBackAction->setStatusTip(tr("Reverse the last instruction")); executeStepBackAction->setIcon(QIcon(":/icons/stepback.png")); executeStepBackAction->setEnabled(false); executeRunToAction = new QAction(tr("Run to"), this); executeRunToAction->setShortcut(tr("F4")); executeRunToAction->setStatusTip(tr("Resume execution until the selected line is reached")); executeRunToAction->setIcon(QIcon(":/icons/runto.png")); executeRunToAction->setEnabled(false); breakpointToggleAction = new QAction(tr("Toggle"), this); breakpointToggleAction->setShortcut(tr("F5")); breakpointToggleAction->setStatusTip(tr("Toggle breakpoint on/off at cursor")); breakpointToggleAction->setIcon(QIcon(":/icons/break.png")); breakpointToggleAction->setEnabled(false); breakpointAddAction = new QAction(tr("Add ..."), this); breakpointAddAction->setShortcut(tr("CTRL+B")); breakpointAddAction->setStatusTip(tr("Add a breakpoint at a location")); breakpointAddAction->setEnabled(false); helpAboutAction = new QAction(tr("&About"), this); executeRunToAction->setStatusTip(tr("Show the appliction information")); connect(fileNewSessionAction, SIGNAL(triggered()), this, SLOT(fileNewSession())); connect(fileOpenSessionAction, SIGNAL(triggered()), this, SLOT(fileOpenSession())); connect(fileSaveSessionAction, SIGNAL(triggered()), this, SLOT(fileSaveSession())); connect(fileSaveSessionAsAction, SIGNAL(triggered()), this, SLOT(fileSaveSessionAs())); connect(fileQuitAction, SIGNAL(triggered()), this, SLOT(close())); connect(systemConnectAction, SIGNAL(triggered()), this, SLOT(systemConnect())); connect(systemDisconnectAction, SIGNAL(triggered()), this, SLOT(systemDisconnect())); connect(systemPauseAction, SIGNAL(triggered()), this, SLOT(systemPause())); connect(systemRebootAction, SIGNAL(triggered()), this, SLOT(systemReboot())); connect(systemSymbolManagerAction, SIGNAL(triggered()), this, SLOT(systemSymbolManager())); connect(systemPreferencesAction, SIGNAL(triggered()), this, SLOT(systemPreferences())); connect(searchGotoAction, SIGNAL(triggered()), this, SLOT(searchGoto())); connect(viewRegistersAction, SIGNAL(triggered()), this, SLOT(toggleRegisterDisplay())); connect(viewFlagsAction, SIGNAL(triggered()), this, SLOT(toggleFlagsDisplay())); connect(viewStackAction, SIGNAL(triggered()), this, SLOT(toggleStackDisplay())); connect(viewSlotsAction, SIGNAL(triggered()), this, SLOT(toggleSlotsDisplay())); connect(viewMemoryAction, SIGNAL(triggered()), this, SLOT(toggleMemoryDisplay())); connect(viewDebuggableViewerAction, SIGNAL(triggered()), this, SLOT(addDebuggableViewer())); connect(viewBitMappedAction, SIGNAL(triggered()), this, SLOT(toggleBitMappedDisplay())); connect(viewVDPRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPRegsDisplay())); connect(viewVDPCommandRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPCommandRegsDisplay())); connect(viewVDPStatusRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPStatusRegsDisplay())); connect(executeBreakAction, SIGNAL(triggered()), this, SLOT(executeBreak())); connect(executeRunAction, SIGNAL(triggered()), this, SLOT(executeRun())); connect(executeStepAction, SIGNAL(triggered()), this, SLOT(executeStep())); connect(executeStepOverAction, SIGNAL(triggered()), this, SLOT(executeStepOver())); connect(executeRunToAction, SIGNAL(triggered()), this, SLOT(executeRunTo())); connect(executeStepOutAction, SIGNAL(triggered()), this, SLOT(executeStepOut())); connect(executeStepBackAction, SIGNAL(triggered()), this, SLOT(executeStepBack())); connect(breakpointToggleAction, SIGNAL(triggered()), this, SLOT(breakpointToggle())); connect(breakpointAddAction, SIGNAL(triggered()), this, SLOT(breakpointAdd())); connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(showAbout())); } void DebuggerForm::createMenus() { // create file menu fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(fileNewSessionAction); fileMenu->addAction(fileOpenSessionAction); fileMenu->addAction(fileSaveSessionAction); fileMenu->addAction(fileSaveSessionAsAction); recentFileSeparator = fileMenu->addSeparator(); for (int i = 0; i < MaxRecentFiles; ++i) fileMenu->addAction(recentFileActions[i]); fileMenu->addSeparator(); fileMenu->addAction(fileQuitAction); // create system menu systemMenu = menuBar()->addMenu(tr("&System")); systemMenu->addAction(systemConnectAction); systemMenu->addAction(systemDisconnectAction); systemMenu->addSeparator(); systemMenu->addAction(systemPauseAction); systemMenu->addSeparator(); systemMenu->addAction(systemRebootAction); systemMenu->addSeparator(); systemMenu->addAction(systemSymbolManagerAction); systemMenu->addSeparator(); systemMenu->addAction(systemPreferencesAction); // create system menu searchMenu = menuBar()->addMenu(tr("Se&arch")); searchMenu->addAction(searchGotoAction); // create view menu viewMenu = menuBar()->addMenu(tr("&View")); viewMenu->addAction(viewRegistersAction); viewMenu->addAction(viewFlagsAction); viewMenu->addAction(viewStackAction); viewMenu->addAction(viewSlotsAction); viewMenu->addAction(viewMemoryAction); viewVDPDialogsMenu = viewMenu->addMenu("VDP"); viewMenu->addSeparator(); viewMenu->addAction(viewDebuggableViewerAction); connect(viewMenu, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu())); // create VDP dialogs menu viewVDPDialogsMenu->addAction(viewVDPRegsAction); viewVDPDialogsMenu->addAction(viewVDPCommandRegsAction); viewVDPDialogsMenu->addAction(viewVDPStatusRegsAction); viewVDPDialogsMenu->addAction(viewBitMappedAction); connect(viewVDPDialogsMenu, SIGNAL(aboutToShow()), this, SLOT(updateVDPViewMenu())); // create execute menu executeMenu = menuBar()->addMenu(tr("&Execute")); executeMenu->addAction(executeBreakAction); executeMenu->addAction(executeRunAction); executeMenu->addSeparator(); executeMenu->addAction(executeStepAction); executeMenu->addAction(executeStepOverAction); executeMenu->addAction(executeStepOutAction); executeMenu->addAction(executeStepBackAction); executeMenu->addAction(executeRunToAction); // create breakpoint menu breakpointMenu = menuBar()->addMenu(tr("&Breakpoint")); breakpointMenu->addAction(breakpointToggleAction); breakpointMenu->addAction(breakpointAddAction); // create help menu helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(helpAboutAction); } void DebuggerForm::createToolbars() { // create debug toolbar systemToolbar = addToolBar(tr("System")); systemToolbar->addAction(systemConnectAction); systemToolbar->addAction(systemDisconnectAction); systemToolbar->addSeparator(); systemToolbar->addAction(systemPauseAction); systemToolbar->addSeparator(); systemToolbar->addAction(systemSymbolManagerAction); // create debug toolbar executeToolbar = addToolBar(tr("Execution")); executeToolbar->addAction(executeBreakAction); executeToolbar->addAction(executeRunAction); executeToolbar->addSeparator(); executeToolbar->addAction(executeStepAction); executeToolbar->addAction(executeStepOverAction); executeToolbar->addAction(executeStepOutAction); executeToolbar->addAction(executeStepBackAction); executeToolbar->addAction(executeRunToAction); } void DebuggerForm::createStatusbar() { // create the statusbar statusBar()->showMessage("No emulation running."); } void DebuggerForm::createForm() { updateWindowTitle(); mainArea = new DockableWidgetArea(); dockMan.addDockArea(mainArea); setCentralWidget(mainArea); // Create main widgets and append them to the list first DockableWidget* dw = new DockableWidget(dockMan); // create the disasm viewer widget disasmView = new DisasmViewer(); dw->setWidget(disasmView); dw->setTitle(tr("Code view")); dw->setId("CODEVIEW"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(false); dw->setClosable(false); connect(this, SIGNAL(settingsChanged()), disasmView, SLOT(settingsChanged())); connect(this, SIGNAL(symbolsChanged()), disasmView, SLOT(symbolsChanged())); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create the memory view widget mainMemoryView = new MainMemoryViewer(); dw = new DockableWidget(dockMan); dw->setWidget(mainMemoryView); dw->setTitle(tr("Main memory")); dw->setId("MEMORY"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); mainMemoryView->setSymbolTable(&session.symbolTable()); // create register viewer regsView = new CPURegsViewer(); dw = new DockableWidget(dockMan); dw->setWidget(regsView); dw->setTitle(tr("CPU registers")); dw->setId("REGISTERS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // Hook up the register viewer with the MainMemory viewer connect(regsView, SIGNAL(registerChanged(int,int)), mainMemoryView, SLOT(registerChanged(int,int))); mainMemoryView->setRegsView(regsView); // create flags viewer flagsView = new FlagsViewer(); dw = new DockableWidget(dockMan); dw->setWidget(flagsView); dw->setTitle(tr("Flags")); dw->setId("FLAGS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create stack viewer stackView = new StackViewer(); dw = new DockableWidget(dockMan); dw->setWidget(stackView); dw->setTitle(tr("Stack")); dw->setId("STACK"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create slot viewer slotView = new SlotViewer(); dw = new DockableWidget(dockMan); dw->setWidget(slotView); dw->setTitle(tr("Memory layout")); dw->setId("SLOTS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // restore layout restoreGeometry(Settings::get().value("Layout/WindowGeometry", saveGeometry()).toByteArray()); QStringList list = Settings::get().value("Layout/WidgetLayout").toStringList(); // defaults needed? if (list.empty() || !list.at(0).startsWith("CODEVIEW ")) { list.clear(); list.append("CODEVIEW D V R 0 -1 -1"); list.append("REGISTERS D V R 0 -1 -1"); list.append("FLAGS D V R 0 -1 -1"); int regW = dockMan.findDockableWidget("REGISTERS")->sizeHint().width(); int regH = dockMan.findDockableWidget("REGISTERS")->sizeHint().height(); int codeW = dockMan.findDockableWidget("CODEVIEW")->sizeHint().width(); int codeH = dockMan.findDockableWidget("CODEVIEW")->sizeHint().height(); int flagW = dockMan.findDockableWidget("FLAGS")->sizeHint().width(); int slotW = dockMan.findDockableWidget("SLOTS")->sizeHint().width(); list.append(QString("SLOTS D V R 0 -1 %1").arg(regH)); list.append(QString("STACK D V R 0 -1 %1").arg(codeH)); list.append(QString("MEMORY D V B %1 %2 %3").arg(codeW) .arg(regW + flagW + slotW) .arg(codeH - regH)); } // add widgets for (int i = 0; i < list.size(); ++i) { QStringList s = list.at(i).split(" ", QString::SkipEmptyParts); // get widget if ((dw = dockMan.findDockableWidget(s.at(0)))) { if (s.at(1) == "D") { // dock widget DockableWidgetLayout::DockSide side; if (s.at(3) == "T") { side = DockableWidgetLayout::TOP; } else if (s.at(3) == "L") { side = DockableWidgetLayout::LEFT; } else if (s.at(3) == "R") { side = DockableWidgetLayout::RIGHT; } else { side = DockableWidgetLayout::BOTTOM; } dockMan.insertWidget(dw, 0, side, s.at(4).toInt(), s.at(5).toInt(), s.at(6).toInt()); if (s.at(2) == "H") dw->hide(); } else if (s.at(1) == "F") { // float widget dw->setFloating(true, s.at(2) == "V"); dw->resize(s.at(5).toInt(), s.at(6).toInt()); dw->move (s.at(3).toInt(), s.at(4).toInt()); } } } // disable all widgets connectionClosed(); connect(regsView, SIGNAL(pcChanged(quint16)), disasmView, SLOT(setProgramCounter(quint16))); connect(regsView, SIGNAL(flagsChanged(quint8)), flagsView, SLOT(setFlags(quint8))); connect(regsView, SIGNAL(spChanged(quint16)), stackView, SLOT(setStackPointer(quint16))); connect(disasmView, SIGNAL(toggleBreakpoint(int)), SLOT(breakpointToggle(int))); connect(&comm, SIGNAL(connectionReady()), SLOT(initConnection())); connect(&comm, SIGNAL(updateParsed(const QString&, const QString&, const QString&)), SLOT(handleUpdate(const QString&, const QString&, const QString&))); connect(&comm, SIGNAL(connectionTerminated()), SLOT(connectionClosed())); // init main memory // added four bytes as runover buffer for dasm // otherwise dasm would need to check the buffer end continously. session.breakpoints().setMemoryLayout(&memLayout); mainMemory = new unsigned char[65536 + 4]; memset(mainMemory, 0, 65536 + 4); disasmView->setMemory(mainMemory); disasmView->setBreakpoints(&session.breakpoints()); disasmView->setMemoryLayout(&memLayout); disasmView->setSymbolTable(&session.symbolTable()); mainMemoryView->setDebuggable("memory", 65536); stackView->setData(mainMemory, 65536); slotView->setMemoryLayout(&memLayout); } DebuggerForm::~DebuggerForm() { delete[] mainMemory; delete mainArea; } void DebuggerForm::closeEvent(QCloseEvent* e) { // handle unsaved session fileNewSession(); // cancel if session is still modified if (session.isModified()) { e->ignore(); return; } // store layout Settings::get().setValue("Layout/WindowGeometry", saveGeometry()); QStringList layoutList; // fill layout list with docked widgets dockMan.getConfig(0, layoutList); // append floating widgets for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { if ((*it)->isFloating()) { QString s("%1 F %2 %3 %4 %5 %6"); s = s.arg((*it)->id()); if ((*it)->isHidden()) { s = s.arg("H"); } else { s = s.arg("V"); } s = s.arg((*it)->x()).arg((*it)->y()) .arg((*it)->width()).arg((*it)->height()); layoutList.append(s); } } Settings::get().setValue("Layout/WidgetLayout", layoutList); QMainWindow::closeEvent(e); } void DebuggerForm::updateRecentFiles() { // store settings Settings::get().setValue("MainWindow/RecentFiles", recentFiles); // update actions for(int i = 0; i < MaxRecentFiles; i++) if(i < recentFiles.size()) { recentFileActions[i]->setVisible(true); QString text = QString("&%1 %2").arg(i + 1).arg(QFileInfo(recentFiles[i]).fileName()); recentFileActions[i]->setText(text); recentFileActions[i]->setData(recentFiles[i]); } else recentFileActions[i]->setVisible(false); // show separator only when recent files exist recentFileSeparator->setVisible(recentFiles.size()); } void DebuggerForm::addRecentFile(const QString& file) { recentFiles.removeAll(file); recentFiles.prepend(file); while (recentFiles.size() > MaxRecentFiles) recentFiles.removeLast(); updateRecentFiles(); } void DebuggerForm::removeRecentFile(const QString& file) { recentFiles.removeAll(file); updateRecentFiles(); } void DebuggerForm::updateWindowTitle() { QString title = "openMSX debugger [%1%2]"; if (session.existsAsFile()) { title = title.arg(session.filename()); } else { title = title.arg("unnamed session"); } if (session.isModified()) { title = title.arg('*'); } else { title = title.arg(""); } setWindowTitle(title); } void DebuggerForm::initConnection() { systemConnectAction->setEnabled(false); systemDisconnectAction->setEnabled(true); comm.sendCommand(new QueryPauseHandler(*this)); comm.sendCommand(new QueryBreakedHandler(*this)); comm.sendCommand(new SimpleCommand("openmsx_update enable status")); comm.sendCommand(new ListDebuggablesHandler(*this)); // define 'debug_bin2hex' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_bin2hex { input } {\n" " set result \"\"\n" " foreach i [split $input {}] {\n" " append result [format %02X [scan $i %c]] \"\"\n" " }\n" " return $result\n" "}\n")); // define 'debug_hex2bin' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_hex2bin { input } {\n" " set result \"\"\n" " foreach {h l} [split $input {}] {\n" " append result [binary format H2 $h$l] \"\"\n" " }\n" " return $result\n" "}\n")); // define 'debug_memmapper' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_memmapper { } {\n" " set result \"\"\n" " for { set page 0 } { $page < 4 } { incr page } {\n" " set tmp [get_selected_slot $page]\n" " append result [lindex $tmp 0] [lindex $tmp 1] \"\\n\"\n" " if { [lsearch [debug list] \"MapperIO\"] != -1} {\n" " append result [debug read \"MapperIO\" $page] \"\\n\"\n" " } else {\n" " append result \"0\\n\"\n" " }\n" " }\n" " for { set ps 0 } { $ps < 4 } { incr ps } {\n" " if [machine_info issubslotted $ps] {\n" " append result \"1\\n\"\n" " for { set ss 0 } { $ss < 4 } { incr ss } {\n" " append result [get_mapper_size $ps $ss] \"\\n\"\n" " }\n" " } else {\n" " append result \"0\\n\"\n" " append result [get_mapper_size $ps 0] \"\\n\"\n" " }\n" " }\n" " for { set page 0 } { $page < 4 } { incr page } {\n" " set tmp [get_selected_slot $page]\n" " set ss [lindex $tmp 1]\n" " if { $ss == \"X\" } { set ss 0 }\n" " set device_list [machine_info slot [lindex $tmp 0] $ss $page]\n" " set name \"[lindex $device_list 0] romblocks\"\n" " if { [lsearch [debug list] $name] != -1} {\n" " append result \"[debug read $name [expr {$page * 0x4000}] ]\\n\"\n" " append result \"[debug read $name [expr {$page * 0x4000 + 0x2000}] ]\\n\"\n" " } else {\n" " append result \"X\\nX\\n\"\n" " }\n" " }\n" " return $result\n" "}\n")); // define 'debug_list_all_breaks' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_list_all_breaks { } {\n" " set result [debug list_bp]\n" " append result [debug list_watchpoints]\n" " append result [debug list_conditions]\n" " return $result\n" "}\n")); } void DebuggerForm::connectionClosed() { systemPauseAction->setEnabled(false); systemRebootAction->setEnabled(false); executeBreakAction->setEnabled(false); executeRunAction->setEnabled(false); executeStepAction->setEnabled(false); executeStepOverAction->setEnabled(false); executeStepOutAction->setEnabled(false); executeStepBackAction->setEnabled(false); executeRunToAction->setEnabled(false); systemDisconnectAction->setEnabled(false); systemConnectAction->setEnabled(true); breakpointToggleAction->setEnabled(false); breakpointAddAction->setEnabled(false); for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { (*it)->widget()->setEnabled(false); } } void DebuggerForm::finalizeConnection(bool halted) { systemPauseAction->setEnabled(true); systemRebootAction->setEnabled(true); breakpointToggleAction->setEnabled(true); breakpointAddAction->setEnabled(true); // merge breakpoints on connect mergeBreakpoints = true; if (halted) { setBreakMode(); breakOccured(); } else { setRunMode(); updateData(); } for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { (*it)->widget()->setEnabled(true); } } void DebuggerForm::handleUpdate(const QString& type, const QString& name, const QString& message) { if (type == "status") { if (name == "cpu") { if (message == "suspended") { breakOccured(); } else { setRunMode(); } } else if (name == "paused") { pauseStatusChanged(message == "true"); } } } void DebuggerForm::pauseStatusChanged(bool isPaused) { systemPauseAction->setChecked(isPaused); } void DebuggerForm::breakOccured() { setBreakMode(); updateData(); } void DebuggerForm::updateData() { comm.sendCommand(new ListBreakPointsHandler(*this, mergeBreakpoints)); // only merge the first time after connect mergeBreakpoints = false; // refresh memory viewer mainMemoryView->refresh(); // update registers // note that a register update is processed, a signal is sent to other // widgets as well. Any dependent updates shoud be called before this one. CPURegRequest* regs = new CPURegRequest(*this); comm.sendCommand(regs); // refresh slot viewer slotView->refresh(); emit emulationChanged(); } void DebuggerForm::setBreakMode() { executeBreakAction->setEnabled(false); executeRunAction->setEnabled(true); executeStepAction->setEnabled(true); executeStepOverAction->setEnabled(true); executeStepOutAction->setEnabled(true); executeStepBackAction->setEnabled(true); executeRunToAction->setEnabled(true); } void DebuggerForm::setRunMode() { executeBreakAction->setEnabled(true); executeRunAction->setEnabled(false); executeStepAction->setEnabled(false); executeStepOverAction->setEnabled(false); executeStepOutAction->setEnabled(false); executeStepBackAction->setEnabled(false); executeRunToAction->setEnabled(false); } void DebuggerForm::fileNewSession() { if (session.isModified()) { // save current session? int choice = QMessageBox::warning(this, tr("Unsaved session"), tr("The current session has unsaved data.\n" "Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); if (choice == QMessageBox::Cancel) { return; } else if (choice == QMessageBox::Save) { fileSaveSession(); // skip new if session is still modified (save was cancelled) if (session.isModified()) return; } } session.clear(); updateWindowTitle(); } void DebuggerForm::fileOpenSession() { QString fileName = QFileDialog::getOpenFileName( this, tr("Open debug session"), QDir::currentPath(), tr("Debug Session Files (*.omds)")); if (!fileName.isEmpty()) openSession(fileName); } void DebuggerForm::openSession(const QString& file) { fileNewSession(); session.open(file); if (systemDisconnectAction->isEnabled()) { // active connection, merge loaded breakpoints comm.sendCommand(new ListBreakPointsHandler(*this, true)); } // update recent if(session.existsAsFile()) addRecentFile(file); else removeRecentFile(file); updateWindowTitle(); } void DebuggerForm::fileSaveSession() { if (session.existsAsFile()) { session.save(); } else { fileSaveSessionAs(); } updateWindowTitle(); } void DebuggerForm::fileSaveSessionAs() { QFileDialog d(this, tr("Save debug session")); d.setNameFilter(tr("Debug Session Files (*.omds)")); d.setDefaultSuffix("omds"); d.setDirectory(QDir::currentPath()); d.setAcceptMode(QFileDialog::AcceptSave); d.setFileMode(QFileDialog::AnyFile); if (d.exec()) { session.saveAs(d.selectedFiles().at(0)); // update recent if(session.existsAsFile()) addRecentFile(session.filename()); } updateWindowTitle(); } void DebuggerForm::fileRecentOpen() { QAction *action = qobject_cast(sender()); if (action) openSession(action->data().toString()); } void DebuggerForm::systemConnect() { if (OpenMSXConnection* connection = ConnectDialog::getConnection(this)) { comm.connectToOpenMSX(connection); } } void DebuggerForm::systemDisconnect() { comm.closeConnection(); } void DebuggerForm::systemPause() { comm.sendCommand(new SimpleCommand(QString("set pause ") + (systemPauseAction->isChecked() ? "true" : "false"))); } void DebuggerForm::systemReboot() { if (systemPauseAction->isChecked()) { systemPauseAction->trigger(); } if (executeRunAction->isEnabled()) { executeRun(); } comm.sendCommand(new SimpleCommand("reset")); } void DebuggerForm::systemSymbolManager() { SymbolManager symManager(session.symbolTable(), this); connect(&symManager, SIGNAL(symbolTableChanged()), &session, SLOT(sessionModified())); symManager.exec(); emit symbolsChanged(); updateWindowTitle(); } void DebuggerForm::systemPreferences() { PreferencesDialog prefs(this); prefs.exec(); emit settingsChanged(); } void DebuggerForm::searchGoto() { GotoDialog gtd(memLayout, &session, this); if (gtd.exec()) { int addr = gtd.address(); if ( addr >= 0) { disasmView->setCursorAddress(addr, 0, DisasmViewer::MiddleAlways); } } } void DebuggerForm::executeBreak() { comm.sendCommand(new SimpleCommand("debug break")); } void DebuggerForm::executeRun() { comm.sendCommand(new SimpleCommand("debug cont")); setRunMode(); } void DebuggerForm::executeStep() { comm.sendCommand(new SimpleCommand("debug step")); setRunMode(); } void DebuggerForm::executeStepOver() { SimpleCommand *sc = new SimpleCommand("step_over"); connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool))); comm.sendCommand(sc); setRunMode(); } void DebuggerForm::executeRunTo() { comm.sendCommand(new SimpleCommand( "run_to " + QString::number(disasmView->cursorAddress()))); setRunMode(); } void DebuggerForm::executeStepOut() { comm.sendCommand(new SimpleCommand("step_out")); setRunMode(); } void DebuggerForm::executeStepBack() { SimpleCommand *sc = new SimpleCommand("step_back"); connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool))); comm.sendCommand(sc); setRunMode(); } void DebuggerForm::handleCommandReplyStatus(bool status) { if(status) { finalizeConnection(true); } } void DebuggerForm::breakpointToggle(int addr) { // toggle address unspecified, use cursor address if (addr < 0) addr = disasmView->cursorAddress(); QString cmd, id; if (session.breakpoints().isBreakpoint(addr, &id)) { cmd = Breakpoints::createRemoveCommand(id); } else { // get slot int ps, ss, seg; addressSlot(addr, ps, ss, seg); // create command cmd = Breakpoints::createSetCommand(Breakpoints::BREAKPOINT, addr, ps, ss, seg); } comm.sendCommand(new SimpleCommand(cmd)); comm.sendCommand(new ListBreakPointsHandler(*this)); } void DebuggerForm::breakpointAdd() { BreakpointDialog bpd(memLayout, &session, this); int addr = disasmView->cursorAddress(); int ps, ss, seg; addressSlot(addr, ps, ss, seg); bpd.setData(Breakpoints::BREAKPOINT, addr, ps, ss, seg); if (bpd.exec()) { if (bpd.address() >= 0) { QString cmd = Breakpoints::createSetCommand( bpd.type(), bpd.address(), bpd.slot(), bpd.subslot(), bpd.segment(), bpd.addressEndRange(), bpd.condition() ); comm.sendCommand(new SimpleCommand(cmd)); comm.sendCommand(new ListBreakPointsHandler(*this)); } } } void DebuggerForm::showAbout() { QMessageBox::about( this, "openMSX Debugger", QString(Version::full().c_str())); } void DebuggerForm::toggleRegisterDisplay() { toggleView(qobject_cast(regsView->parentWidget())); } void DebuggerForm::toggleFlagsDisplay() { toggleView(qobject_cast(flagsView->parentWidget())); } void DebuggerForm::toggleStackDisplay() { toggleView(qobject_cast(stackView->parentWidget())); } void DebuggerForm::toggleSlotsDisplay() { toggleView(qobject_cast(slotView->parentWidget())); } void DebuggerForm::toggleBitMappedDisplay() { //toggleView( qobject_cast(slotView->parentWidget())); // not sure if this a good idea for a docable widget // create new debuggable viewer window BitMapViewer* viewer = new BitMapViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(viewer); dw->setTitle(tr("Bitmapped VRAM View")); dw->setId("BITMAPVRAMVIEW"); dw->setFloating(true); dw->setDestroyable(true); dw->setMovable(true); dw->setClosable(true); /* connect( dw, SIGNAL( visibilityChanged(DockableWidget*) ), this, SLOT( dockWidgetVisibilityChanged(DockableWidget*) ) ); connect( this, SIGNAL( debuggablesChanged(const QMap&) ), viewer, SLOT( setDebuggables(const QMap&) ) ); */ // TODO: refresh should be being hanled by VDPDataStore... connect(this, SIGNAL(emulationChanged()), viewer, SLOT(refresh())); /* viewer->setDebuggables( debuggables ); viewer->setEnabled( disasmView->isEnabled() ); */ } void DebuggerForm::toggleVDPCommandRegsDisplay() { if (VDPCommandRegView == NULL) { VDPCommandRegView = new VDPCommandRegViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(VDPCommandRegView); dw->setTitle(tr("VDP registers view")); dw->setId("VDPCommandRegView"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPCommandRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPCommandRegView->parentWidget())); } } void DebuggerForm::toggleVDPRegsDisplay() { if (VDPRegView == NULL) { VDPRegView = new VDPRegViewer(); DockableWidget *dw = new DockableWidget(dockMan); dw->setWidget(VDPRegView); dw->setTitle(tr("VDP registers view")); dw->setId("VDPREGVIEW"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPRegView->parentWidget())); } } void DebuggerForm::toggleVDPStatusRegsDisplay() { if (VDPStatusRegView == NULL) { VDPStatusRegView = new VDPStatusRegViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(VDPStatusRegView); dw->setTitle(tr("VDP status registers view")); dw->setId("VDPSTATUSREGVIEW"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPStatusRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPStatusRegView->parentWidget())); } } void DebuggerForm::toggleMemoryDisplay() { toggleView(qobject_cast(mainMemoryView->parentWidget())); } void DebuggerForm::toggleView(DockableWidget* widget) { if (widget->isHidden()) { widget->show(); } else { widget->hide(); } dockMan.visibilityChanged(widget); } void DebuggerForm::addDebuggableViewer() { // create new debuggable viewer window DebuggableViewer* viewer = new DebuggableViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(viewer); dw->setTitle(tr("Debuggable hex view")); dw->setId("DEBUGVIEW"); dw->setFloating(true); dw->setDestroyable(true); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); connect(this, SIGNAL(debuggablesChanged(const QMap&)), viewer, SLOT(setDebuggables(const QMap&))); connect(this, SIGNAL(emulationChanged()), viewer, SLOT(refresh())); viewer->setDebuggables(debuggables); viewer->setEnabled(disasmView->isEnabled()); } void DebuggerForm::dockWidgetVisibilityChanged(DockableWidget* w) { dockMan.visibilityChanged(w); updateViewMenu(); } void DebuggerForm::updateViewMenu() { viewRegistersAction->setChecked(regsView->parentWidget()->isVisible()); viewFlagsAction->setChecked(flagsView->isVisible()); viewStackAction->setChecked(stackView->isVisible()); viewSlotsAction->setChecked(slotView->isVisible()); viewMemoryAction->setChecked(mainMemoryView->isVisible()); } void DebuggerForm::updateVDPViewMenu() { if (VDPCommandRegView) { viewVDPCommandRegsAction->setChecked(VDPCommandRegView->isVisible()); } if (VDPRegView) { viewVDPRegsAction->setChecked(VDPRegView->isVisible()); } if (VDPStatusRegView) { viewVDPStatusRegsAction->setChecked(VDPStatusRegView->isVisible()); } } void DebuggerForm::setDebuggables(const QString& list) { debuggables.clear(); // process result string QStringList l = list.split(" ", QString::SkipEmptyParts); for (int i = 0; i < l.size(); ++i) { QString d = l[i]; // combine multiple words if (d[0] == '{') { while (!d.endsWith("}")) { d.push_back(' '); d.append(l[++i]); } } // set initial size to zero debuggables[d] = 0; } // find the size for all debuggables for (QMap::iterator it = debuggables.begin(); it != debuggables.end(); ++it) { comm.sendCommand(new DebuggableSizeHandler(it.key(), *this)); } } void DebuggerForm::setDebuggableSize(const QString& debuggable, int size) { debuggables[debuggable] = size; // emit update if size of last debuggable was set if (debuggable == debuggables.keys().last()) { emit debuggablesChanged(debuggables); } } void DebuggerForm::symbolFileChanged() { static bool shown(false); if(shown) return; shown = true; int choice = QMessageBox::question(this, tr("Symbol file changed"), tr("One or more symbol file have changed.\n" "Reload now?"), QMessageBox::Yes | QMessageBox::No); shown = false; if (choice == QMessageBox::Yes) session.symbolTable().reloadFiles(); } void DebuggerForm::addressSlot(int addr, int& ps, int& ss, int& segment) { int p = (addr & 0xC000) >> 14; ps = memLayout.primarySlot[p]; // figure out secondary slot ss = memLayout.isSubslotted[ps] ? memLayout.secondarySlot[p] : -1; // figure out (rom) mapper segment segment = -1; if (memLayout.mapperSize[ps][ss==-1 ? 0 : ss] > 0) segment = memLayout.mapperSegment[p]; else { int q = 2*p + ((addr & 0x2000) >> 13); if (memLayout.romBlock[q] >= 0) segment = memLayout.romBlock[q]; } } debugger-master/src/Convert.cpp0000644000175000017500000000275213560352104016407 0ustar shevekshevek#include "Convert.h" #include "Settings.h" #include int stringToValue(const QString& str) { QString s = str.trimmed(); int base = 10; // find base (prefix or postfix) if (s.startsWith("&") && s.size() >= 2) { switch (s[1].toUpper().toLatin1()) { case 'H': base = 16; break; case 'B': base = 2; break; case 'O': base = 8; break; } s = s.remove(0, 2); } else if (s.startsWith("#") || s.startsWith("$")) { base = 16; s = s.remove(0, 1); } else if (s.startsWith("0x")) { base = 16; s = s.remove(0, 2); } else if (s.startsWith("%")) { base = 2; s = s.remove(0, 1); } else if (!s.isEmpty()) { switch (s.right(1)[0].toUpper().toLatin1()) { case 'H': case '#': base = 16; break; case 'B': base = 2; break; case 'O': base = 8; break; } if (base != 10) s.chop(1); } // convert value bool ok; int value = s.toInt(&ok, base); if (!ok) return -1; return value; } QString hexValue(int value, int width) { Settings& s = Settings::get(); return QString("%1%2%3").arg(s.value("Preferences/HexPrefix", "$").toString()) .arg(value, width, 16, QChar('0')) .arg(s.value("Preferences/HexPostfix", "").toString()); } QString& escapeXML(QString& str) { return str.replace('&', "&").replace('<', "<").replace('>', ">"); } QString& unescapeXML(QString& str) { return str.replace("&", "&").replace("<", "<").replace(">", ">"); } debugger-master/src/DockManager.h0000644000175000017500000000221113560352104016575 0ustar shevekshevek#ifndef DOCKMANAGER_H #define DOCKMANAGER_H #include "DockableWidgetLayout.h" #include #include class QRect; class QPoint; class DockableWidget; class DockableWidgetArea; class DockManager { public: void addDockArea(DockableWidgetArea* area); int dockAreaIndex(DockableWidgetArea* area) const; void insertWidget(DockableWidget* widget, int index, DockableWidgetLayout::DockSide side, int distance, int w = -1, int h = -1); void dockWidget(DockableWidget* widget, const QPoint& p, const QRect& r); void undockWidget(DockableWidget* widget); bool insertLocation(QRect& r, const QSizePolicy& sizePol); void visibilityChanged(DockableWidget* widget); void getConfig(int index, QStringList& list) const; void attachWidget(DockableWidget* widget); void detachWidget(DockableWidget* widget); const QList& managedWidgets() const; DockableWidget* findDockableWidget(const QString& id) const; private: typedef QMap AreaMap; AreaMap areaMap; QList areas; QList dockWidgets; }; #endif // DOCKMANAGER_H debugger-master/src/DockManager.cpp0000644000175000017500000000401113560352104017130 0ustar shevekshevek#include "DockManager.h" #include "DockableWidget.h" #include "DockableWidgetArea.h" void DockManager::addDockArea(DockableWidgetArea* area) { if (areas.indexOf(area) == -1) { areas.append(area); } } int DockManager::dockAreaIndex(DockableWidgetArea* area) const { return areas.indexOf(area); } void DockManager::dockWidget(DockableWidget* widget, const QPoint& p, const QRect& r) { AreaMap::iterator it = areaMap.begin(); // TODO if (it != areaMap.end()) { areaMap[widget] = it.value(); return it.value()->addWidget(widget, r); } } void DockManager::undockWidget(DockableWidget* widget) { AreaMap::iterator it = areaMap.find(widget); if (it != areaMap.end()) { it.value()->removeWidget(widget); } } void DockManager::insertWidget( DockableWidget* widget, int index, DockableWidgetLayout::DockSide side, int distance, int w, int h) { if (index < 0 || index >= areas.size()) return; //Q_ASSERT(areaMap.find(widget) == areaMap.end()); areas[index]->addWidget(widget, side, distance, w, h); areaMap[widget] = areas[index]; } bool DockManager::insertLocation(QRect& r, const QSizePolicy& sizePol) { AreaMap::iterator it = areaMap.begin(); // TODO if (it == areaMap.end()) return false; return it.value()->insertLocation(r, sizePol); } void DockManager::visibilityChanged(DockableWidget* widget) { AreaMap::iterator it = areaMap.find(widget); if (it != areaMap.end()) { it.value()->layout->changed(); } } void DockManager::getConfig(int index, QStringList& list) const { areas[index]->getConfig(list); } void DockManager::attachWidget(DockableWidget* widget) { dockWidgets.append(widget); } void DockManager::detachWidget(DockableWidget* widget) { dockWidgets.removeAll(widget); } const QList& DockManager::managedWidgets() const { return dockWidgets; } DockableWidget* DockManager::findDockableWidget(const QString& id) const { for (QList::const_iterator it = dockWidgets.begin(); it != dockWidgets.end(); ++it) { if ((*it)->id() == id) return *it; } return 0; } debugger-master/src/BreakpointDialog.cpp0000644000175000017500000002147213560352104020205 0ustar shevekshevek#include "BreakpointDialog.h" #include "DebugSession.h" #include "Convert.h" #include #include BreakpointDialog::BreakpointDialog(const MemoryLayout& ml, DebugSession *session, QWidget* parent) : QDialog(parent), memLayout(ml), currentSymbol(0) { setupUi(this); value = valueEnd = -1; debugSession = session; if( session ) { // create address completer jumpCompleter = new QCompleter(session->symbolTable().labelList(), this); allCompleter = new QCompleter(session->symbolTable().labelList(true), this); jumpCompleter->setCaseSensitivity(Qt::CaseInsensitive); allCompleter->setCaseSensitivity(Qt::CaseInsensitive); connect(jumpCompleter, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); connect(allCompleter, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); } connect(edtAddress, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); connect(edtAddressRange, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); connect(cmbxType, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); connect(cmbxSlot, SIGNAL(activated(int)), this, SLOT(slotChanged(int))); connect(cmbxSubslot, SIGNAL(activated(int)), this, SLOT(subslotChanged(int))); connect(cbCondition, SIGNAL(stateChanged(int)), this, SLOT(hasCondition(int))); typeChanged(0); slotChanged(0); idxSlot = idxSubSlot = 0; hasCondition(0); } BreakpointDialog::~BreakpointDialog() { delete jumpCompleter; delete allCompleter; } Breakpoints::Type BreakpointDialog::type() { return Breakpoints::Type(cmbxType->currentIndex()); } int BreakpointDialog::address() { return value; } int BreakpointDialog::addressEndRange() { if (valueEnd < value) return value; else return valueEnd; } int BreakpointDialog::slot() { return cmbxSlot->currentIndex() - 1; } int BreakpointDialog::subslot() { return cmbxSubslot->currentIndex() - 1; } int BreakpointDialog::segment() { return cmbxSegment->currentIndex() - 1; } QString BreakpointDialog::condition() { if( cbCondition->checkState() == Qt::Checked ) return txtCondition->toPlainText(); else return QString(); } void BreakpointDialog::setData(Breakpoints::Type type, int address, int ps, int ss, int segment, int addressEnd, QString condition) { // set type cmbxType->setCurrentIndex(int(type)); typeChanged(cmbxType->currentIndex()); // set address if (address >= 0) { edtAddress->setText( hexValue(address) ); addressChanged(edtAddress->text()); } // primary slot if (cmbxSlot->isEnabled() && ps >= 0) { cmbxSlot->setCurrentIndex(ps+1); slotChanged(cmbxSlot->currentIndex()); } // secondary slot if (cmbxSubslot->isEnabled() && ss >= 0) { cmbxSubslot->setCurrentIndex(ss+1); subslotChanged(cmbxSubslot->currentIndex()); } // segment if (cmbxSegment->isEnabled() && segment >= 0) { cmbxSegment->setCurrentIndex(segment+1); } // end address if (edtAddressRange->isEnabled() && addressEnd >= 0) { edtAddressRange->setText( hexValue(addressEnd) ); addressChanged(edtAddressRange->text()); } // condition condition = condition.trimmed(); if (cbCondition->isChecked() == condition.isEmpty()) cbCondition->setChecked(!condition.isEmpty()); txtCondition->setText(condition); } void BreakpointDialog::addressChanged(const QString& text) { // determine source QLineEdit *ed; if (text == edtAddress->text()) ed = edtAddress; else ed = edtAddressRange; bool first = ed == edtAddress; // convert value int v = stringToValue(text); if (v == -1 && debugSession) { Symbol *s = debugSession->symbolTable().getAddressSymbol(text); if (s) v = s->value(); if (first) currentSymbol = s; } // assign address if (first) value = v; else { if (v > value) valueEnd = v; else { valueEnd = -1; v = -1; } } // adjust controls for (in)correct values QStandardItemModel* model = qobject_cast(cmbxSlot->model()); QPalette pal; if (v == -1) { // set line edit text to red for invalid values TODO: make configurable pal.setColor(QPalette::Normal, QPalette::Text, Qt::red); ed->setPalette(pal); if (first) { cmbxSlot->setCurrentIndex(0); cmbxSlot->setEnabled(false); } } else { //pal.setColor(QPalette::Normal, QPalette::Text, Qt::black); ed->setPalette(pal); if (!first) return; cmbxSlot->setEnabled(true); if(currentSymbol) { // enable allowed slots int s = currentSymbol->validSlots(); int num = 0, last = 0; for(int i = 4; i >= 0; i--) { QModelIndex index = model->index(i, 0, cmbxSlot->rootModelIndex()); if(i) { bool ena = (s & (15<<(4*(i-1)))) != 0; model->itemFromIndex(index)->setEnabled(ena); if(ena) { num++; last = i; } } else { model->itemFromIndex(index)->setEnabled( num == 4 ); if(num == 4) last = 0; } } cmbxSlot->setCurrentIndex(last); } else { // enable everything for(int i = 0; i < 5; i++) { QModelIndex index = model->index(i, 0, cmbxSlot->rootModelIndex()); model->itemFromIndex(index)->setEnabled(true); } cmbxSlot->setCurrentIndex(idxSlot); } } slotChanged(cmbxSlot->currentIndex()); } void BreakpointDialog::typeChanged(int s) { switch(s) { case 1: case 2: lblAddress->setText(tr("Add watchpoint at memory address or range:")); edtAddressRange->setVisible(true); edtAddress->setCompleter(allCompleter); edtAddressRange->setCompleter(allCompleter); break; case 3: case 4: lblAddress->setText(tr("Add watchpoint on IO port or range:")); edtAddressRange->setVisible(true); edtAddress->setCompleter(0); edtAddressRange->setCompleter(0); break; default: lblAddress->setText(tr("Add breakpoint at address:")); edtAddressRange->setVisible(false); edtAddress->setCompleter(jumpCompleter); } switch(s) { case 1: case 2: lblInSlot->setText(tr("With address in")); break; default: lblInSlot->setText(tr("With PC in")); } if(s == 5) { lblAddress->setEnabled(false); edtAddress->setEnabled(false); lblSlot->setEnabled(false); lblSubslot->setEnabled(false); lblSegment->setEnabled(false); cmbxSlot->setEnabled(false); cmbxSubslot->setEnabled(false); cmbxSegment->setEnabled(false); cbCondition->setCheckState(Qt::Checked); cbCondition->setEnabled(false); } else { lblAddress->setEnabled(true); edtAddress->setEnabled(true); lblSlot->setEnabled(true); lblSubslot->setEnabled(true); lblSegment->setEnabled(true); addressChanged(edtAddress->text()); cbCondition->setEnabled(true); cbCondition->setCheckState( txtCondition->toPlainText().isEmpty() ? Qt::Unchecked : Qt::Checked ); } } void BreakpointDialog::slotChanged(int s) { if(!currentSymbol) idxSlot = s; if (s && memLayout.isSubslotted[s - 1]) { if(currentSymbol) { // enable subslots int v = (currentSymbol->validSlots() >> (4*(s-1))) & 15; int num = 0, last = 0; QStandardItemModel* model = qobject_cast(cmbxSubslot->model()); for(int i = 4; i >= 0; i--) { QModelIndex index = model->index(i, 0, cmbxSubslot->rootModelIndex()); if(i) { bool ena = (v & (1<<(i-1))) != 0; model->itemFromIndex(index)->setEnabled(ena); if(ena) { num++; last = i; } } else { model->itemFromIndex(index)->setEnabled( num == 4 ); if(num == 4) last = 0; } } cmbxSubslot->setCurrentIndex(last); } else { cmbxSubslot->setCurrentIndex(idxSubSlot); } cmbxSubslot->setEnabled(true); } else { cmbxSubslot->setEnabled(false); cmbxSubslot->setCurrentIndex(0); } subslotChanged(cmbxSubslot->currentIndex()); } void BreakpointDialog::subslotChanged(int i) { if(!currentSymbol) idxSubSlot = i; int oldseg = cmbxSegment->currentIndex()-1; cmbxSegment->clear(); cmbxSegment->addItem("any"); int ps = cmbxSlot->currentIndex() - 1; int ss = i - 1; if (ps >=0 && !memLayout.isSubslotted[ps]) ss = 0; int mapsize; if (ps < 0 || ss < 0 || memLayout.mapperSize[ps][ss] == 0) { // no memory mapper, maybe rom mapper? if (value >= 0 && memLayout.romBlock[((value & 0xE000)>>13)] >= 0) { mapsize = 256; // TODO: determine real size } else { cmbxSegment->setEnabled(false); cmbxSegment->setCurrentIndex(0); return; } } else mapsize = memLayout.mapperSize[ps][ss]; for (int s = 0; s < mapsize; ++s) { cmbxSegment->addItem(QString("%1").arg(s)); } cmbxSegment->setEnabled(true); if (oldseg >= 0 && oldseg < mapsize) cmbxSegment->setCurrentIndex(oldseg+1); } void BreakpointDialog::hasCondition(int state) { if( state == Qt::Checked ) { txtCondition->setVisible(true); layout()->setSizeConstraint(QLayout::SetDefaultConstraint); resize( width(), conditionHeight ); } else { conditionHeight = height(); txtCondition->setVisible(false); resize( width(), sizeHint().height() ); layout()->setSizeConstraint(QLayout::SetMaximumSize); } } debugger-master/src/VDPCommandRegViewer.cpp0000644000175000017500000002547413560352104020545 0ustar shevekshevek#include "VDPCommandRegViewer.h" #include "CommClient.h" static const int VIEW_HEX = 1; static const int VIEW_SEPERATE = 2; static QString hex8bit(int val) { return QString("0x%1").arg(val, 2, 16, QChar('0')).toUpper(); } VDPCommandRegViewer::VDPCommandRegViewer(QWidget* parent) : QDialog(parent) { setupUi(this); regs = new unsigned char[64 + 16]; memset(regs, 0, 64 + 16); statusregs = regs + 64; // create the needed groups grp_sx = new view88to16(lineEdit_r32, lineEdit_r33, lineEdit_sx); connect(lineEdit_r32, SIGNAL(editingFinished()), grp_sx, SLOT(finishRL())); connect(lineEdit_r33, SIGNAL(editingFinished()), grp_sx, SLOT(finishRH())); connect(lineEdit_sx, SIGNAL(editingFinished()), grp_sx, SLOT(finishRW())); grp_sy = new view88to16(lineEdit_r34, lineEdit_r35, lineEdit_sy); connect(lineEdit_r34, SIGNAL(editingFinished()), grp_sy, SLOT(finishRL())); connect(lineEdit_r35, SIGNAL(editingFinished()), grp_sy, SLOT(finishRH())); connect(lineEdit_sy, SIGNAL(editingFinished()), grp_sy, SLOT(finishRW())); grp_dx = new view88to16(lineEdit_r36, lineEdit_r37, lineEdit_dx); connect(lineEdit_r36, SIGNAL(editingFinished()), grp_dx, SLOT(finishRL())); connect(lineEdit_r37, SIGNAL(editingFinished()), grp_dx, SLOT(finishRH())); connect(lineEdit_dx, SIGNAL(editingFinished()), grp_dx, SLOT(finishRW())); grp_dy = new view88to16(lineEdit_r38, lineEdit_r39, lineEdit_dy); connect(lineEdit_r38, SIGNAL(editingFinished()), grp_dy, SLOT(finishRL())); connect(lineEdit_r39, SIGNAL(editingFinished()), grp_dy, SLOT(finishRH())); connect(lineEdit_dy, SIGNAL(editingFinished()), grp_dy, SLOT(finishRW())); grp_nx = new view88to16(lineEdit_r40, lineEdit_r41, lineEdit_nx); connect(lineEdit_r40, SIGNAL(editingFinished()), grp_nx, SLOT(finishRL())); connect(lineEdit_r41, SIGNAL(editingFinished()), grp_nx, SLOT(finishRH())); connect(lineEdit_nx, SIGNAL(editingFinished()), grp_nx, SLOT(finishRW())); grp_ny = new view88to16(lineEdit_r42, lineEdit_r43, lineEdit_ny); connect(lineEdit_r42, SIGNAL(editingFinished()), grp_ny, SLOT(finishRL())); connect(lineEdit_r43, SIGNAL(editingFinished()), grp_ny, SLOT(finishRH())); connect(lineEdit_ny, SIGNAL(editingFinished()), grp_ny, SLOT(finishRW())); grp_sx->setRW(QString("0")); grp_sy->setRW(QString("0")); grp_dx->setRW(QString("0")); grp_dy->setRW(QString("0")); grp_nx->setRW(QString("0")); grp_ny->setRW(QString("0")); grp_l_sx = new view88to16(label_r_32, label_r_33, label_r_sx); grp_l_sy = new view88to16(label_r_34, label_r_35, label_r_sy); grp_l_dx = new view88to16(label_r_36, label_r_37, label_r_dx); grp_l_dy = new view88to16(label_r_38, label_r_39, label_r_dy); grp_l_nx = new view88to16(label_r_40, label_r_41, label_r_nx); grp_l_ny = new view88to16(label_r_42, label_r_43, label_r_ny); //Connect the checkboxes QList list = this->findChildren(); QCheckBox* item; foreach(item, list) { connect(item, SIGNAL(stateChanged(int)), this, SLOT(R45BitChanged(int))); } lineEdit_r44->setText("0x00"); lineEdit_r45->setText("0x00"); lineEdit_r46->setText("0x00"); R46 = 0; comboBox_cmd->setCurrentIndex(0); //decodeR46(R46); //on_comboBox_cmd_currentIndexChanged(); //get initiale data refresh(); } VDPCommandRegViewer::~VDPCommandRegViewer() { delete[] regs; } void VDPCommandRegViewer::on_lineEdit_r45_editingFinished() { //for now simply recheck all the checkBoxes and recreate R45 int val = lineEdit_r45->text().toInt(NULL, 0); int r45 = 0; QList list = findChildren(); QCheckBox* item; foreach(item, list) { int order = QString(item->objectName().right(1)).toInt(); if (val & (1 << order)) { r45 = r45 | (1 << order); item->setChecked(true); } else { item->setChecked(false); } } lineEdit_r45->setText(QString("0x%1").arg(r45, 2, 16, QChar('0')).toUpper()); label_arg->setText(QString("%1").arg(r45, 8, 2, QChar('0'))); } void VDPCommandRegViewer::on_comboBox_cmd_currentIndexChanged(int index) { if ((index < 7 || index > 9) && index != 11 && index != 5) { comboBox_operator->setEnabled(false); comboBox_operator->setCurrentIndex(5); } else { if (!comboBox_operator->isEnabled()) { comboBox_operator->setCurrentIndex(R46 & 15); } comboBox_operator->setEnabled(true); } R46 = (15 & R46) + 16 * index; decodeR46(R46); lineEdit_r46->setText(QString("0x%1").arg(R46, 2, 16, QChar('0')).toUpper()); } void VDPCommandRegViewer::on_comboBox_operator_currentIndexChanged(int index) { //if the cmd disables the combox then no influence on R45 if (!comboBox_operator->isEnabled()) return; R46 = index + (R46 & 0xF0); decodeR46(R46); lineEdit_r46->setText(QString("0x%1").arg(R46, 2, 16, QChar('0')).toUpper()); } void VDPCommandRegViewer::decodeR46(int val) { static const QString words[16] = { "-", "VDP", "VRAM", "CPU", "Byte", "Dot", "Stop", "Invalid", "Point", "Pset", "Search", "Line", "Logical move", "High-speed move" }; static const int dest[16] = { 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2 //refers to words }; static const int srce[16] = { 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 3, 1, 2, 2, 3 //refers to words }; static const int data[16] = { 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 //refers to words }; static const int cnam[16] = { 6, 7, 7, 7, 8, 9,10,11,12,12,12,12,13,13,13,13 //refers to words }; static const QString oper[16] = { "IMP", "AND", "OR", "EOR", "NOT", "---", "---", "---", "TIMP", "TAND", "TOR", "TEOR", "TNOT", "---", "---", "---", }; static const int argbold[16] = { 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x26, 0x2D, 0x2C, 0x2C, 0x1C, 0x2C, 0x2C, 0x3C, 0x2C, 0x2C, }; static const int regbold[16] = { 0x00, 0x00, 0x00, 0x00, 0x83, 0xCC, 0xC3, 0xFC, 0xFC, 0xBF, 0xB3, 0xFC, 0xFC, 0xBF, 0xAE, 0xFC, }; int operat = (val >> 0) & 15; int cmd = (val >> 4) & 15; QString explication = QString( "Command: %1 " "Destination: %2 " "Source: %3
" "Data: %4 " "Operation: %5"). arg(words[cnam[cmd]]). arg(words[dest[cmd]]). arg(words[srce[cmd]]). arg(words[data[cmd]]). arg(oper[operat]); label_expl1->setText(explication); //a Normal and a Bold font QFont fontN; QFont fontB; fontB.setBold(true); //set the checkbox font in bold if command uses the corresponding bit for (int b = 0; b < 7; ++b) { QCheckBox* item = findChild(QString("checkBoxBit_%1").arg(b)); item->setFont((argbold[cmd] & (1 << b)) ? fontB : fontN); } labelSX ->setFont((regbold[cmd] & 0x01) ? fontB : fontN); labelSY ->setFont((regbold[cmd] & 0x02) ? fontB : fontN); labelDX ->setFont((regbold[cmd] & 0x04) ? fontB : fontN); labelDY ->setFont((regbold[cmd] & 0x08) ? fontB : fontN); labelNX ->setFont((regbold[cmd] & 0x10) ? fontB : fontN); labelNY ->setFont((regbold[cmd] & 0x20) ? fontB : fontN); labelCOLOR->setFont((regbold[cmd] & 0x40) ? fontB : fontN); labelARG ->setFont((regbold[cmd] & 0x80) ? fontB : fontN); //TODO: create basic equivalent //TODO: warn about wrong stuff (majorant < minorant when line drawing for instance) } void VDPCommandRegViewer::on_syncPushButton_clicked() { syncRegToCmd(); } void VDPCommandRegViewer::on_launchPushButton_clicked() { unsigned char newregs[64]; memset(newregs, 0, 64); newregs[32] = lineEdit_r32->text().toInt(NULL, 0); newregs[33] = lineEdit_r33->text().toInt(NULL, 0); newregs[34] = lineEdit_r34->text().toInt(NULL, 0); newregs[35] = lineEdit_r35->text().toInt(NULL, 0); newregs[36] = lineEdit_r36->text().toInt(NULL, 0); newregs[37] = lineEdit_r37->text().toInt(NULL, 0); newregs[38] = lineEdit_r38->text().toInt(NULL, 0); newregs[39] = lineEdit_r39->text().toInt(NULL, 0); newregs[40] = lineEdit_r40->text().toInt(NULL, 0); newregs[41] = lineEdit_r41->text().toInt(NULL, 0); newregs[42] = lineEdit_r42->text().toInt(NULL, 0); newregs[43] = lineEdit_r43->text().toInt(NULL, 0); newregs[44] = lineEdit_r44->text().toInt(NULL, 0); newregs[45] = lineEdit_r45->text().toInt(NULL, 0); newregs[46] = lineEdit_r46->text().toInt(NULL, 0); WriteDebugBlockCommand* req = new WriteDebugBlockCommand( "{VDP regs}", 32, 15, newregs); CommClient::instance().sendCommand(req); } void VDPCommandRegViewer::on_lineEdit_r44_editingFinished() { int val = lineEdit_r44->text().toInt(NULL, 0); label_color->setText(QString("%1 %2"). arg((val >> 4) & 15, 4, 2, QChar('0')). arg((val >> 0) & 15, 4, 2, QChar('0'))); } void VDPCommandRegViewer::R45BitChanged(int state) { //for now simply recheck all the checkBoxes and recreate R45 int r45 = 0; QList list = findChildren(); QCheckBox* item; foreach(item, list) { if (item->isChecked()) { int order = QString(item->objectName().right(1)).toInt(); r45 = r45 | (1 << order); } } lineEdit_r45->setText(QString("0x%1").arg(r45, 2, 16, QChar('0')).toUpper()); label_arg->setText(QString("%1").arg(r45, 8, 2, QChar('0'))); } void VDPCommandRegViewer::on_lineEdit_r46_editingFinished() { int val = lineEdit_r46->text().toInt(NULL, 0) & 0xFF; lineEdit_r46->setText(QString("0x%1").arg(val, 2, 16, QChar('0')).toUpper()); R46 = val; decodeR46(R46); comboBox_operator->setCurrentIndex(R46 & 15); comboBox_cmd->setCurrentIndex((R46 >> 4) & 15); // this might hide the operator again :-) } void VDPCommandRegViewer::refresh() { //new SimpleHexRequest("{VDP regs}",0,64,regs, *this); //new SimpleHexRequest("{VDP status regs}",0,16,regs, *this); // now combined in one request: new SimpleHexRequest( "debug_bin2hex " "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VDP status regs} 0 16 ]", 64 + 16, regs, *this); } void VDPCommandRegViewer::syncRegToCmd() { grp_sx->setRL(hex8bit(regs[32])); grp_sx->setRH(hex8bit(regs[33])); grp_sy->setRL(hex8bit(regs[34])); grp_sy->setRH(hex8bit(regs[35])); grp_dx->setRL(hex8bit(regs[36])); grp_dx->setRH(hex8bit(regs[37])); grp_dy->setRL(hex8bit(regs[38])); grp_dy->setRH(hex8bit(regs[39])); grp_nx->setRL(hex8bit(regs[40])); grp_nx->setRH(hex8bit(regs[41])); grp_ny->setRL(hex8bit(regs[42])); grp_ny->setRH(hex8bit(regs[43])); lineEdit_r44->setText(hex8bit(regs[44])); on_lineEdit_r44_editingFinished(); lineEdit_r45->setText(hex8bit(regs[45])); on_lineEdit_r45_editingFinished(); lineEdit_r46->setText(hex8bit(regs[46])); on_lineEdit_r46_editingFinished(); } void VDPCommandRegViewer::DataHexRequestReceived() { grp_l_sx->setRL(hex8bit(regs[32])); grp_l_sx->setRH(hex8bit(regs[33])); grp_l_sy->setRL(hex8bit(regs[34])); grp_l_sy->setRH(hex8bit(regs[35])); grp_l_dx->setRL(hex8bit(regs[36])); grp_l_dx->setRH(hex8bit(regs[37])); grp_l_dy->setRL(hex8bit(regs[38])); grp_l_dy->setRH(hex8bit(regs[39])); grp_l_nx->setRL(hex8bit(regs[40])); grp_l_nx->setRH(hex8bit(regs[41])); grp_l_ny->setRL(hex8bit(regs[42])); grp_l_ny->setRH(hex8bit(regs[43])); label_r_44->setText(hex8bit(regs[44])); label_r_45->setText(hex8bit(regs[45])); label_r_46->setText(hex8bit(regs[46])); if (autoSyncRadioButton->isChecked()) syncRegToCmd(); } debugger-master/src/ConnectDialog.ui0000644000175000017500000000447413560352104017336 0ustar shevekshevek ConnectDialog 0 0 382 246 Dialog 9 6 Active sessions: 0 6 Connect Cancel Rescan Qt::Vertical 20 40 QAbstractItemView::SelectRows cancelButton clicked() ConnectDialog reject() 330 66 197 125 debugger-master/src/DisasmViewer.cpp0000644000175000017500000004502013560352104017364 0ustar shevekshevek#include "DisasmViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "DebuggerData.h" #include "Settings.h" #include #include #include #include #include #include #include #include #include #include #include class CommMemoryRequest : public ReadDebugBlockCommand { public: CommMemoryRequest(unsigned offset_, unsigned size_, unsigned char* target, DisasmViewer& viewer_) : ReadDebugBlockCommand("memory", offset_, size_, target) , offset(offset_), size(size_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.memoryUpdated(this); } virtual void cancel() { viewer.updateCancelled(this); } // TODO Refactor: public members are ugly unsigned offset; unsigned size; int address; int line; int method; private: DisasmViewer& viewer; }; DisasmViewer::DisasmViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred)); breakMarker = QPixmap(":/icons/breakpoint.png"); watchMarker = QPixmap(":/icons/watchpoint.png"); pcMarker = QPixmap(":/icons/pcarrow.png"); memory = NULL; cursorAddr = 0; cursorLine = 0; visibleLines = 0; programAddr = 0xFFFF; waitingForData = false; nextRequest = NULL; scrollBar = new QScrollBar(Qt::Vertical, this); scrollBar->setMinimum(0); scrollBar->setMaximum(0xFFFF); scrollBar->setSingleStep(0); scrollBar->setPageStep(0); settingsChanged(); // manual scrollbar handling routines (real size of the data is not known) connect(scrollBar, SIGNAL(actionTriggered(int)), this, SLOT(scrollBarAction(int))); connect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); } QSize DisasmViewer::sizeHint() const { return QSize(xMnemArg + xMCode[0], 20 * codeFontHeight); } void DisasmViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); scrollBar->setGeometry(width() - frameR, frameT, scrollBar->sizeHint().width(), height() - frameT - frameB); // reset the address in order to trigger a check on the disasmLines if (!waitingForData) { setAddress(scrollBar->value()); } } void DisasmViewer::settingsChanged() { frameL = frameT = frameB = frameWidth(); frameR = frameL + scrollBar->sizeHint().width(); setMinimumHeight(frameT + 5 * fontMetrics().height() + frameB); // set font sizes Settings& s = Settings::get(); QFontMetrics lfm(s.font(Settings::LABEL_FONT)); QFontMetrics cfm(s.font(Settings::CODE_FONT)); labelFontHeight = lfm.height(); labelFontAscent = lfm.ascent(); codeFontHeight = cfm.height(); codeFontAscent = cfm.ascent(); // calculate layout locations int charWidth = cfm.width("0"); xAddr = frameL + 40; xMCode[0] = xAddr + 6 * charWidth; xMCode[1] = xMCode[0] + 3 * charWidth; xMCode[2] = xMCode[1] + 3 * charWidth; xMCode[3] = xMCode[2] + 3 * charWidth; xMnem = xMCode[3] + 4 * charWidth; xMnemArg = xMnem + 7 * charWidth; setMinimumSize(xMCode[0], 2*codeFontHeight); setMaximumSize(QApplication::desktop()->width(), QApplication::desktop()->height()); update(); } void DisasmViewer::symbolsChanged() { int disasmStart = disasmLines.front().addr; int disasmEnd = disasmLines.back().addr + disasmLines.back().numBytes; CommMemoryRequest* req = new CommMemoryRequest( disasmStart, disasmEnd - disasmStart, &memory[disasmStart], *this); req->address = disasmLines[disasmTopLine].addr; req->line = disasmLines[disasmTopLine].infoLine; req->method = TopAlways; if (waitingForData) { delete nextRequest; nextRequest = req; } else { waitingForData = true; CommClient::instance().sendCommand(req); } } void DisasmViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop(frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // draw background p.fillRect(frameL + 32, frameT, width() - 32 - frameL - frameR, height() - frameT - frameB, palette().color(QPalette::Base)); // calculate lines while drawing visibleLines = 0; int y = frameT; QString hexStr; const DisasmRow* row; bool displayDisasm = memory != NULL && isEnabled(); Settings& s = Settings::get(); p.setFont(s.font(Settings::CODE_FONT)); while (y < height() - frameB) { // fetch the data for this line row = displayDisasm ? &disasmLines[disasmTopLine+visibleLines] : &DISABLED_ROW; int h, a; switch (row->rowType) { case DisasmRow::LABEL: h = labelFontHeight; a = labelFontAscent; break; case DisasmRow::INSTRUCTION: h = codeFontHeight; a = codeFontAscent; break; } // draw cursor line bool isCursorLine = cursorAddr >= row->addr && cursorAddr < row->addr+row->numBytes && row->infoLine == cursorLine; if (isCursorLine) { cursorAddr = row->addr; p.fillRect(frameL + 32, y, width() - 32 - frameL - frameR, h, palette().color(QPalette::Highlight)); if (hasFocus()) { QStyleOptionFocusRect so; so.backgroundColor = palette().color(QPalette::Highlight); so.rect = QRect(frameL + 32, y, width() - 32 - frameL - frameR, h); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &so, &p, this); } p.setPen(palette().color(QPalette::HighlightedText)); } // if there is a label here, draw the label, otherwise code if (row->rowType == DisasmRow::LABEL) { // draw label hexStr = QString("%1:").arg(row->instr.c_str()); p.setFont(s.font(Settings::LABEL_FONT)); if (!isCursorLine) { p.setPen(s.fontColor(Settings::LABEL_FONT)); } p.drawText(xAddr, y + a, hexStr); p.setFont(s.font(Settings::CODE_FONT)); } else { // draw code line // default to text pen if (!isCursorLine) { p.setPen(s.fontColor(Settings::CODE_FONT)); } // draw breakpoint marker if (row->infoLine == 0) { if (breakpoints->isBreakpoint(row->addr)) { p.drawPixmap(frameL + 2, y + h / 2 -5, breakMarker); if (!isCursorLine) { p.fillRect(frameL + 32, y, width() - 32 - frameL - frameR, h, Qt::red); p.setPen(Qt::white); } } else if (breakpoints->isWatchpoint(row->addr)) { p.drawPixmap(frameL + 2, y + h / 2 -5, watchMarker); } } // draw PC marker if (row->addr == programAddr && row->infoLine == 0) { p.drawPixmap(frameL + 18, y + h / 2 - 5, pcMarker); } // print the address hexStr.sprintf("%04X", row->addr); p.drawText(xAddr, y + a, hexStr); // print 1 to 4 bytes for (int j = 0; j < row->numBytes; ++j) { hexStr.sprintf("%02X", displayDisasm ? memory[row->addr + j] : 0); p.drawText(xMCode[j], y + a, hexStr); } // print the instruction and arguments p.drawText(xMnem, y + a, row->instr.substr(0, 7).c_str()); p.drawText(xMnemArg, y + a, row->instr.substr(7 ).c_str()); } // next line y += h; ++visibleLines; // check for end of data if (disasmTopLine+visibleLines == int(disasmLines.size())) break; } partialBottomLine = y > height() - frameB; visibleLines -= partialBottomLine; } void DisasmViewer::setCursorAddress(quint16 addr, int infoLine, int method) { cursorAddr = addr; cursorLine = 0; setAddress(addr, infoLine, method); } void DisasmViewer::setAddress(quint16 addr, int infoLine, int method) { int line = findDisasmLine(addr, infoLine); if (line >= 0) { int dt, db; switch (method) { case Top: case Middle: case Bottom: case Closest: dt = db = 10; break; case TopAlways: dt = 10; db = visibleLines + 10; break; case MiddleAlways: dt = db = 10 + visibleLines / 2; break; case BottomAlways: dt = 10 + visibleLines; db = 10; break; default: assert(false); dt = db = 0; // avoid warning } if ((line > dt || disasmLines[0].addr == 0) && (line < int(disasmLines.size()) - db || disasmLines.back().addr+disasmLines.back().numBytes > 0xFFFF)) { // line is within existing disasm'd data. Find where to put it. if (method == Top || method == TopAlways || (method == Closest && line < disasmTopLine)) { // Move line to top disasmTopLine = line; } else if (method == Bottom || method == BottomAlways || (method == Closest && line >= disasmTopLine + visibleLines)) { // Move line to bottom disasmTopLine = line - visibleLines + 1; } else if (method == MiddleAlways || (method == Middle && (line < disasmTopLine || line >= disasmTopLine + visibleLines))) { // Move line to middle disasmTopLine = line - visibleLines / 2; } disasmTopLine = std::min( disasmTopLine, int(disasmLines.size()) - visibleLines); disasmTopLine = std::max(disasmTopLine, 0); update(); return; } } if (method == Closest) { if (addr < disasmLines[disasmTopLine].addr) { method = Top; } else { method = Bottom; } } // The requested address it outside the pre-disassembled bounds. // This means that a new block of memory must be transfered from // openMSX and disassembled. // determine disasm bounds int disasmStart; int disasmEnd; int extra = 4 * (visibleLines > 9 ? visibleLines+partialBottomLine : 10); switch (method) { case Middle: case MiddleAlways: disasmStart = addr - 3 * extra / 2; disasmEnd = addr + 3 * extra / 2; break; case Bottom: case BottomAlways: disasmStart = addr - 2 * extra; disasmEnd = addr + extra; break; default: disasmStart = addr - extra; disasmEnd = addr + 2 * extra; } disasmStart = std::max(disasmStart, 0); disasmEnd = std::min(disasmEnd, 0xFFFF); CommMemoryRequest* req = new CommMemoryRequest( disasmStart, disasmEnd - disasmStart + 1, &memory[disasmStart], *this); req->address = addr; req->line = infoLine; req->method = method; if (waitingForData) { delete nextRequest; nextRequest = req; } else { waitingForData = true; CommClient::instance().sendCommand(req); } } void DisasmViewer::memoryUpdated(CommMemoryRequest* req) { // disassemble the newly received memory dasm(memory, req->offset, req->offset + req->size - 1, disasmLines, memLayout, symTable, programAddr); // locate the requested line disasmTopLine = findDisasmLine(req->address, req->line); switch (req->method) { case Middle: case MiddleAlways: disasmTopLine -= visibleLines / 2; break; case Bottom: case BottomAlways: disasmTopLine -= visibleLines - 1; break; } disasmTopLine = std::max(disasmTopLine, 0); disasmTopLine = std::min(disasmTopLine, int(disasmLines.size()) - visibleLines); updateCancelled(req); // sync the scrollbar with the actual address reached if (!waitingForData) { // set the slider with without the signal disconnect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); scrollBar->setSliderPosition(disasmLines[disasmTopLine].addr); connect (scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); // set the line setAddress(disasmLines[disasmTopLine].addr, disasmLines[disasmTopLine].infoLine); update(); } } void DisasmViewer::updateCancelled(CommMemoryRequest* req) { delete req; if (nextRequest) { CommClient::instance().sendCommand(nextRequest); nextRequest = NULL; } else { waitingForData = false; } } quint16 DisasmViewer::cursorAddress() const { return cursorAddr; } quint16 DisasmViewer::programCounter() const { return programAddr; } void DisasmViewer::setProgramCounter(quint16 pc) { cursorAddr = pc; programAddr = pc; setAddress(pc, 0, MiddleAlways); } int DisasmViewer::findDisasmLine(quint16 lineAddr, int infoLine) { int line = disasmLines.size() - 1; while( line >= 0 ) { if( lineAddr >= disasmLines[line].addr ) { if( infoLine == 0 ) return line; if (infoLine == LAST_INFO_LINE) return line-1; while (disasmLines[line].infoLine != infoLine && disasmLines[line].addr == lineAddr) { line--; if (line < 0) return -1; } return line; } line--; } return -1; } void DisasmViewer::scrollBarAction(int action) { switch (action) { case QScrollBar::SliderSingleStepAdd: setAddress(disasmLines[disasmTopLine + 1].addr, disasmLines[disasmTopLine + 1].infoLine, TopAlways); break; case QScrollBar::SliderSingleStepSub: if (disasmTopLine > 0) { setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, TopAlways); } break; case QScrollBar::SliderPageStepAdd: { int line = disasmTopLine + visibleLines + partialBottomLine - 1; if (line < int(disasmLines.size())) { setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); } break; } case QScrollBar::SliderPageStepSub: if (disasmTopLine > 0) { setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, BottomAlways); } break; default: break; } } // moving the slider is handled separately because // the SliderMoved action won't catch the extreme values void DisasmViewer::scrollBarChanged(int value) { setAddress(value, FIRST_INFO_LINE, TopAlways); } void DisasmViewer::setMemory(unsigned char* memPtr) { memory = memPtr; // init disasmLines DisasmRow newRow; newRow.rowType = DisasmRow::INSTRUCTION; newRow.numBytes = 1; newRow.infoLine = 0; newRow.instr = "nop"; newRow.instr.resize(8, ' '); for (int i = 0; i < 150; ++i) { newRow.addr = i; disasmLines.push_back(newRow); } disasmTopLine = 50; } void DisasmViewer::setBreakpoints(Breakpoints* bps) { breakpoints = bps; } void DisasmViewer::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } void DisasmViewer::setSymbolTable(SymbolTable* st) { symTable = st; } void DisasmViewer::keyPressEvent(QKeyEvent* e) { switch (e->key()) { case Qt::Key_Up: { int line = findDisasmLine(cursorAddr, cursorLine); if (line > 0) { cursorAddr = disasmLines[line - 1].addr; cursorLine = disasmLines[line - 1].infoLine; } setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_Down: { int line = findDisasmLine(cursorAddr, cursorLine); if (line >= 0 && line < int(disasmLines.size()) - 1) { cursorAddr = disasmLines[line + 1].addr; cursorLine = disasmLines[line + 1].infoLine; } setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_PageUp: { int line = findDisasmLine(cursorAddr, cursorLine); if( line >= disasmTopLine && line < disasmTopLine+visibleLines ) { line -= visibleLines; if(line >= 0) { cursorAddr = disasmLines[line].addr; cursorLine = disasmLines[line].infoLine; setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, BottomAlways); } else { setCursorAddress(disasmLines[0].addr, disasmLines[0].infoLine, Closest); } } else setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_PageDown: { int line = findDisasmLine(cursorAddr, cursorLine); if( line >= disasmTopLine && line < disasmTopLine+visibleLines ) { line += visibleLines; if( line < int(disasmLines.size()) ) { cursorAddr = disasmLines[line].addr; cursorLine = disasmLines[line].infoLine; line = disasmTopLine + visibleLines + partialBottomLine - 1; line = std::min(line, int(disasmLines.size())); setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); } else { setCursorAddress(disasmLines.back().addr, disasmLines.back().infoLine, Closest); } } else setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_Home: { setCursorAddress(0, 0, Middle); e->accept(); break; } case Qt::Key_End: { setCursorAddress(0xffff, 0, Middle); e->accept(); break; } case Qt::Key_Right: case Qt::Key_Return: { int line = findDisasmLine(cursorAddr, cursorLine); if (line >= 0 && line < int(disasmLines.size())) { int naddr = INT_MAX; const DisasmRow &row = disasmLines[line]; std::string instr = row.instr; std::regex re_absolute("(call|jp)\\ .*"); std::regex re_relative("(djnz|jr)\\ .*"); if (std::regex_match(instr, re_absolute)) naddr = memory[row.addr + 1] + memory[row.addr + 2] * 256; else if (std::regex_match(instr, re_relative)) naddr = (row.addr + 2 + (signed char)memory[row.addr + 1]) & 0xFFFF; if(naddr != INT_MAX) { jumpStack.push_back(cursorAddr); setCursorAddress(naddr, 0, Middle); } } e->accept(); break; } case Qt::Key_Left: case Qt::Key_Backspace: { if(!jumpStack.empty()){ int addr = jumpStack.takeLast(); setCursorAddress(addr, 0, Middle); } e->accept(); break; } default: QFrame::keyReleaseEvent(e); } } void DisasmViewer::wheelEvent(QWheelEvent* e) { int line = std::max(0, disasmTopLine - e->delta() / 40); if (e->orientation() == Qt::Vertical) { setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); e->accept(); } } void DisasmViewer::mousePressEvent(QMouseEvent* e) { if (!(e->button() == Qt::LeftButton)) { QFrame::mousePressEvent(e); return; } if (e->x() >= frameL && e->x() < width() - frameR && e->y() >= frameT && e->y() < height() - frameB) { int line = lineAtPos(e->pos()); if (e->x() > frameL + 32) { // check if the line exists // (bottom of memory could have an empty line) if (line + disasmTopLine < int(disasmLines.size())) { cursorAddr = disasmLines[disasmTopLine + line].addr; cursorLine = disasmLines[disasmTopLine + line].infoLine; } else { return; } // scroll if partial line if (line == visibleLines) { setAddress(disasmLines[disasmTopLine + 1].addr, TopAlways); } else { update(); } } else if (e->x() < frameL + 16) { // clicked on the breakpoint area if (line + disasmTopLine < int(disasmLines.size())) { emit toggleBreakpoint(disasmLines[line + disasmTopLine].addr); } } } } int DisasmViewer::lineAtPos(const QPoint& pos) { int line = -1; int y = frameT; do { ++line; switch (disasmLines[disasmTopLine+line].rowType) { case DisasmRow::LABEL: y += labelFontHeight; break; case DisasmRow::INSTRUCTION: y += codeFontHeight; break; } } while (y < pos.y()); return line; } debugger-master/src/VDPCommandRegViewer.h0000644000175000017500000000702313560352104020200 0ustar shevekshevek#ifndef VDPCOMMANDREGVIEWER_H #define VDPCOMMANDREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPCommandRegisters.h" #include class view88to16 : public QObject { Q_OBJECT public: view88to16(QWidget* a, QWidget* b, QWidget* c) { rl = rh = rw = -1; disp_rl = disp_rh = 1; disp_rw = 2; w_rl = a; w_rh = b; w_rw = c; } int getRL() const { return rl; } int getRH() const { return rh; } int getRW() const { return rw; } void setDispRL(int mode) { disp_rl = mode; } void setDispRH(int mode) { disp_rh = mode; } void setDispRW(int mode) { disp_rw = mode; } void setWidgetRL(QWidget* wdgt) { w_rl = wdgt; } void setWidgetRH(QWidget* wdgt) { w_rh = wdgt; } void setWidgetRW(QWidget* wdgt) { w_rw = wdgt; } public slots: void finishRH() { setRH(getWidgetText(w_rh)); } void finishRL() { setRL(getWidgetText(w_rl)); } void finishRW() { setRW(getWidgetText(w_rw)); } void setRH(const QString& newval) { bool ok; int val = newval.toInt(&ok, 0) & 0xFF; if (!ok || (val == rh)) return; rh = val; updaterw(); updaterh(); } void setRL(const QString& newval) { bool ok; int val = newval.toInt(&ok, 0) & 0xFF; if (!ok || (val == rl)) return; rl = val; updaterw(); updaterl(); } void setRW(const QString& newval) { //TODO: build a split-in-two method bool ok; int val = newval.toInt(&ok, 0) & 0xFFFF; if (!ok || (val == rw)) return; rw = val; updaterl(); updaterh(); updaterw(); } private: int rh; int rl; int rw; int disp_rw; int disp_rl; int disp_rh; QWidget* w_rh; QWidget* w_rl; QWidget* w_rw; QString convert(int val, int mode) { if (mode & 1) { return QString("0x%1").arg(val, 2, 16, QChar('0')); } else { return QString("%1").arg(val); } } QString getWidgetText(QWidget* wdg) { if (wdg == NULL) return QString(); if (QLabel* ql = dynamic_cast(wdg)) { return ql->text(); } else { QLineEdit* qe = dynamic_cast(wdg); return qe->text(); } } void updateWidget(QWidget* wdg, int val, int mode) { if (QLabel* ql = dynamic_cast(wdg)) { ql->setText(convert(val, mode)); } else { QLineEdit* qe = dynamic_cast(wdg); qe->setText(convert(val, mode)); } } void updaterw() { if (w_rw == NULL) return; rw = rl + 256 * rh; updateWidget(w_rw, rw, disp_rw); } void updaterl() { if (w_rl == NULL) return; rl = rw & 255; updateWidget(w_rl, rl, disp_rl); } void updaterh() { if (w_rh == NULL) return; rh = (rw >> 8) & 255; updateWidget(w_rh, rh, disp_rh); } }; class VDPCommandRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPCmdRegs { Q_OBJECT public: VDPCommandRegViewer(QWidget* parent = 0); ~VDPCommandRegViewer(); private: virtual void DataHexRequestReceived(); void decodeR46(int val); void syncRegToCmd(); unsigned char* regs; unsigned char* statusregs; view88to16* grp_l_sx; view88to16* grp_l_sy; view88to16* grp_l_dx; view88to16* grp_l_dy; view88to16* grp_l_nx; view88to16* grp_l_ny; view88to16* grp_sx; view88to16* grp_sy; view88to16* grp_dx; view88to16* grp_dy; view88to16* grp_nx; view88to16* grp_ny; int R46; public slots: void refresh(); void R45BitChanged(int); void on_lineEdit_r44_editingFinished(); void on_lineEdit_r45_editingFinished(); void on_lineEdit_r46_editingFinished(); void on_comboBox_cmd_currentIndexChanged(int index); void on_comboBox_operator_currentIndexChanged(int index); void on_syncPushButton_clicked(); void on_launchPushButton_clicked(); }; #endif /* VDPCOMMANDREGVIEWER_H */ debugger-master/src/Settings.h0000644000175000017500000000156713560352104016237 0ustar shevekshevek#ifndef SETTINGS_H #define SETTINGS_H #include #include #include class Settings : public QSettings { Q_OBJECT public: enum DebuggerFont { APP_FONT, FIXED_FONT, CODE_FONT, LABEL_FONT, HEX_FONT, FONT_END }; enum DebuggerFontType { APPLICATION_DEFAULT, FIXED_DEFAULT, CUSTOM }; static Settings& get(); QString fontName(DebuggerFont f) const; const QFont& font(DebuggerFont f) const; void setFont(DebuggerFont f, const QFont& ft); DebuggerFontType fontType(DebuggerFont f) const; void setFontType(DebuggerFont f, DebuggerFontType t); const QColor& fontColor(DebuggerFont f) const; void setFontColor(DebuggerFont f, const QColor& c); private: Settings(); ~Settings(); QFont fonts[FONT_END]; DebuggerFontType fontTypes[FONT_END]; QColor fontColors[FONT_END]; void getFontsFromSettings(); void updateFonts(); }; #endif // SETTINGS_H debugger-master/src/GotoDialog.h0000644000175000017500000000077513560352104016467 0ustar shevekshevek#ifndef GOTODIALOG_H #define GOTODIALOG_H #include "ui_GotoDialog.h" #include struct MemoryLayout; class DebugSession; class Symbol; class GotoDialog : public QDialog, private Ui::GotoDialog { Q_OBJECT public: GotoDialog(const MemoryLayout& ml, DebugSession *session = 0, QWidget* parent = 0); int address(); private: const MemoryLayout& memLayout; DebugSession *debugSession; Symbol *currentSymbol; private slots: void addressChanged(const QString& text); }; #endif // GOTODIALOG_H debugger-master/src/DockableWidget.h0000644000175000017500000000257313560352104017305 0ustar shevekshevek#ifndef DOCKABLEWIDGET_H #define DOCKABLEWIDGET_H #include #include class QLabel; class QToolButton; class QHBoxLayout; class QVBoxLayout; class QRubberBand; class DockManager; class DockableWidget : public QWidget { Q_OBJECT; public: DockableWidget(DockManager& manager, QWidget* parent = 0); ~DockableWidget(); QWidget* widget() const; void setWidget(QWidget* widget); const QString& id() const; void setId(const QString& str); QString title() const; void setTitle(const QString& title); bool isFloating() const; void setFloating(bool enable, bool showNow = true); bool isMovable() const; void setMovable(bool enable); bool isClosable() const; void setClosable(bool enable); bool isDestroyable() const; void setDestroyable(bool enable); private: virtual void mousePressEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); virtual void closeEvent(QCloseEvent* event); DockManager& dockManager; QString widgetId; bool floating; bool closable, movable, destroyable; bool dragging; QPoint dragStart, dragOffset; QRubberBand* rubberBand; QWidget* mainWidget; QHBoxLayout* headerLayout; QVBoxLayout* widgetLayout; QWidget* headerWidget; QLabel* titleLabel; QToolButton* closeButton; signals: void visibilityChanged(DockableWidget* w); }; #endif // DOCKABLEWIDGET_H debugger-master/src/Dasm.h0000644000175000017500000000125513560352104015315 0ustar shevekshevek#ifndef DASM_H #define DASM_H #include #include class SymbolTable; struct MemoryLayout; struct DisasmRow { enum RowType { INSTRUCTION, LABEL }; RowType rowType; unsigned short addr; char numBytes; int infoLine; std::string instr; }; static const DisasmRow DISABLED_ROW = {DisasmRow::INSTRUCTION, 0, 1, 0, "- "}; static const int FIRST_INFO_LINE = 1; static const int LAST_INFO_LINE = -65536; typedef std::vector DisasmLines; void dasm(const unsigned char* membuf, unsigned short startAddr, unsigned short endAddr, DisasmLines& disasm, MemoryLayout *memLayout, SymbolTable *symTable, int currentPC); #endif // DASM_H debugger-master/src/MainMemoryViewer.h0000644000175000017500000000156013560352104017667 0ustar shevekshevek#ifndef MAINMEMORYVIEWER_H #define MAINMEMORYVIEWER_H #include class HexViewer; class CPURegsViewer; class SymbolTable; class QComboBox; class QLineEdit; class MainMemoryViewer : public QWidget { Q_OBJECT public: MainMemoryViewer(QWidget* parent = 0); void setDebuggable(const QString& name, int size); void setRegsView(CPURegsViewer* viewer); void setSymbolTable(SymbolTable* symtable); public slots: void setLocation(int addr); void settingsChanged(); void refresh(); void registerChanged(int id, int value); void hexViewChanged(int addr); void addressValueChanged(); void addressSourceListChanged(int index); private: HexViewer* hexView; QComboBox* addressSourceList; QLineEdit* addressValue; static const int linkRegisters[]; CPURegsViewer* regsViewer; SymbolTable* symTable; int linkedId; bool isLinked; }; #endif // MAINMEMORYVIEWER_H debugger-master/src/CPURegsViewer.h0000644000175000017500000000217313560352104017063 0ustar shevekshevek#ifndef CPUREGSVIEWER_H #define CPUREGSVIEWER_H #include class QPaintEvent; class CPURegsViewer : public QFrame { Q_OBJECT; public: CPURegsViewer(QWidget* parent = 0); void setData(unsigned char* datPtr); int readRegister(int id); QSize sizeHint() const; private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void mousePressEvent(QMouseEvent* e); //void mouseMoveEvent(QMouseEvent* e); //void mouseReleaseEvent(QMouseEvent* e); void keyPressEvent(QKeyEvent* e); void focusOutEvent(QFocusEvent* e); bool event(QEvent* e); // layout int frameL, frameR, frameT, frameB; int leftRegPos, leftValuePos, rightRegPos, rightValuePos; int rowHeight; int regs[16], regsCopy[16]; bool regsModified[16]; bool regsChanged[16]; int cursorLoc; void drawValue(QPainter& p, int id, int x, int y); void setRegister(int id, int value); void getRegister(int id, unsigned char* data); void applyModifications(); void cancelModifications(); signals: void registerChanged(int id, int value); void pcChanged(quint16); void flagsChanged(quint8); void spChanged(quint16); }; #endif // CPUREGSVIEWER_H debugger-master/src/SymbolTable.h0000644000175000017500000001050513560352104016644 0ustar shevekshevek#ifndef SYMBOLTABLE_H #define SYMBOLTABLE_H #include #include #include #include #include #include #include #include struct MemoryLayout; class SymbolTable; class Symbol { public: Symbol(const QString& str, int addr, int val = 0xFFFF); Symbol(const Symbol& symbol); // ACTIVE status is for regular symbols. HIDDEN is for symbols // that are in the list but not shown anywhere. LOST is a special // status for symbols that were once loaded from a symbol file, but // weren't found later. These aren't deleted immediately because // the possible custom settings would be lost even if the reload // was of a bad file (after a failed assembler run for instance). enum SymbolStatus { ACTIVE, HIDDEN, LOST }; enum SymbolType { JUMPLABEL, VARIABLELABEL, VALUE }; enum Register { REG_A = 1, REG_B = 2, REG_C = 4, REG_D = 8, REG_E = 16, REG_H = 32, REG_L = 64, REG_BC = 128, REG_DE = 256, REG_HL = 512, REG_IX = 1024, REG_IY = 2048, REG_IXL = 4096, REG_IXH = 8192, REG_IYL = 16384, REG_IYH = 32768, REG_OFFSET = 65536, REG_I = 131072, REG_ALL8 = 1+2+4+8+16+32+64+4096+8192+16384+32768+65536+131072, REG_ALL16 = 128+256+512+1024+2048, REG_ALL = 0x3FFFF }; const QString& text() const; void setText(const QString& str); int value() const; void setValue(int addr); int validSlots() const; void setValidSlots(int val); int validRegisters() const; void setValidRegisters(int regs); const QString* source() const; void setSource(const QString* name); SymbolStatus status() const; void setStatus(SymbolStatus s); SymbolType type() const; void setType(SymbolType t); bool isSlotValid(const MemoryLayout* ml = 0) const; private: SymbolTable* table; QString symText; int symValue; int symSlots; QList symSegments; int symRegisters; const QString* symSource; SymbolStatus symStatus; SymbolType symType; friend class SymbolTable; }; class SymbolTable : public QObject { Q_OBJECT public: enum FileType { DETECT_FILE, TNIASM0_FILE, TNIASM1_FILE, SJASM_FILE, ASMSX_FILE, LINKMAP_FILE, HTC_FILE, PASMO_FILE }; SymbolTable(); ~SymbolTable(); void add(Symbol* symbol); void removeAt(int index); void remove(Symbol *symbol); void clear(); int size() const; /* xml session file functions */ void saveSymbols(QXmlStreamWriter& xml); void loadSymbols(QXmlStreamReader& xml); /* Symbol access functions */ Symbol* findFirstAddressSymbol(int addr, MemoryLayout* ml = 0); Symbol* getCurrentAddressSymbol(); Symbol* findNextAddressSymbol(MemoryLayout* ml = 0); Symbol* getValueSymbol(int val, Symbol::Register reg, MemoryLayout* ml = 0); Symbol* getAddressSymbol(int val, MemoryLayout* ml = 0); Symbol* getAddressSymbol(const QString& label, bool case_sensitive = false); QStringList labelList(bool include_vars = false, const MemoryLayout* ml = 0) const; void symbolTypeChanged(Symbol* symbol); void symbolValueChanged(Symbol* symbol); int symbolFilesSize() const; const QString& symbolFile(int index) const; const QDateTime& symbolFileRefresh(int index) const; bool readFile(const QString& filename, FileType type = DETECT_FILE); void reloadFiles(); void unloadFile(const QString& file, bool keepSymbols = false); private: void appendFile(const QString& file, FileType type); bool readSymbolFile( const QString& filename, FileType type, const QString& equ); bool readTNIASM0File(const QString& filename); bool readTNIASM1File(const QString& filename); bool readASMSXFile(const QString& filename); bool readSJASMFile(const QString& filename); bool readHTCFile(const QString& filename); bool readLinkMapFile(const QString& filename); bool readPASMOFile(const QString& filename); void mapSymbol(Symbol* symbol); void unmapSymbol(Symbol* symbol); QList symbols; QMultiMap addressSymbols; QMultiHash valueSymbols; QMultiMap::iterator currentAddress; struct SymbolFileRecord { QString fileName; QDateTime refreshTime; FileType fileType; }; QList symbolFiles; QFileSystemWatcher fileWatcher; private slots: void fileChanged(const QString & path); signals: void symbolFileChanged(); }; #endif // SYMBOLTABLE_H debugger-master/src/SymbolManager.cpp0000644000175000017500000005661613560352104017537 0ustar shevekshevek#include "SymbolManager.h" #include "SymbolTable.h" #include "Settings.h" #include "Convert.h" #include #include #include SymbolManager::SymbolManager(SymbolTable& symtable, QWidget* parent) : QDialog(parent), symTable(symtable) { setupUi(this); // restore layout Settings& s = Settings::get(); restoreGeometry(s.value("SymbolManager/WindowGeometry", saveGeometry()).toByteArray()); treeFiles->header()->restoreState(s.value("SymbolManager/HeaderFiles", treeFiles->header()->saveState()).toByteArray()); treeLabels->header()->restoreState(s.value("SymbolManager/HeaderSymbols", treeLabels->header()->saveState()).toByteArray()); treeLabelsUpdateCount = 0; editColumn = -1; // put slot checkboxes in a convenience array chkSlots[ 0] = chk00; chkSlots[ 1] = chk01; chkSlots[ 2] = chk02; chkSlots[ 3] = chk03; chkSlots[ 4] = chk10; chkSlots[ 5] = chk11; chkSlots[ 6] = chk12; chkSlots[ 7] = chk13; chkSlots[ 8] = chk20; chkSlots[ 9] = chk21; chkSlots[10] = chk22; chkSlots[11] = chk23; chkSlots[12] = chk30; chkSlots[13] = chk31; chkSlots[14] = chk32; chkSlots[15] = chk33; chkRegs[ 0] = chkRegA; chkRegs[ 1] = chkRegB; chkRegs[ 2] = chkRegC; chkRegs[ 3] = chkRegD; chkRegs[ 4] = chkRegE; chkRegs[ 5] = chkRegH; chkRegs[ 6] = chkRegL; chkRegs[ 7] = chkRegBC; chkRegs[ 8] = chkRegDE; chkRegs[ 9] = chkRegHL; chkRegs[10] = chkRegIX; chkRegs[11] = chkRegIY; chkRegs[12] = chkRegIXL;chkRegs[13] = chkRegIXH;chkRegs[14] = chkRegIYL;chkRegs[15] = chkRegIYH; chkRegs[16] = chkRegOffset; chkRegs[17] = chkRegI; connect(treeFiles, SIGNAL(itemSelectionChanged()), this, SLOT(fileSelectionChange())); connect(btnAddFile, SIGNAL(clicked()), this, SLOT(addFile())); connect(btnRemoveFile, SIGNAL(clicked()), this, SLOT(removeFile())); connect(btnReloadFiles, SIGNAL(clicked()), this, SLOT(reloadFiles())); connect(treeLabels, SIGNAL(itemSelectionChanged()), this, SLOT(labelSelectionChanged())); connect(treeLabels, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(labelEdit(QTreeWidgetItem*, int))); connect(treeLabels, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(labelChanged(QTreeWidgetItem*, int))); connect(btnAddSymbol, SIGNAL(clicked()), this, SLOT(addLabel())); connect(btnRemoveSymbol, SIGNAL(clicked()), this, SLOT(removeLabel())); connect(radJump, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(radVar, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(radValue, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(chk00, SIGNAL(stateChanged(int)), this, SLOT(changeSlot00(int))); connect(chk01, SIGNAL(stateChanged(int)), this, SLOT(changeSlot01(int))); connect(chk02, SIGNAL(stateChanged(int)), this, SLOT(changeSlot02(int))); connect(chk03, SIGNAL(stateChanged(int)), this, SLOT(changeSlot03(int))); connect(chk10, SIGNAL(stateChanged(int)), this, SLOT(changeSlot10(int))); connect(chk11, SIGNAL(stateChanged(int)), this, SLOT(changeSlot11(int))); connect(chk12, SIGNAL(stateChanged(int)), this, SLOT(changeSlot12(int))); connect(chk13, SIGNAL(stateChanged(int)), this, SLOT(changeSlot13(int))); connect(chk20, SIGNAL(stateChanged(int)), this, SLOT(changeSlot20(int))); connect(chk21, SIGNAL(stateChanged(int)), this, SLOT(changeSlot21(int))); connect(chk22, SIGNAL(stateChanged(int)), this, SLOT(changeSlot22(int))); connect(chk23, SIGNAL(stateChanged(int)), this, SLOT(changeSlot23(int))); connect(chk30, SIGNAL(stateChanged(int)), this, SLOT(changeSlot30(int))); connect(chk31, SIGNAL(stateChanged(int)), this, SLOT(changeSlot31(int))); connect(chk32, SIGNAL(stateChanged(int)), this, SLOT(changeSlot32(int))); connect(chk33, SIGNAL(stateChanged(int)), this, SLOT(changeSlot33(int))); connect(chkRegA, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterA(int))); connect(chkRegB, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterB(int))); connect(chkRegC, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterC(int))); connect(chkRegD, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterD(int))); connect(chkRegE, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterE(int))); connect(chkRegH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterH(int))); connect(chkRegL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterL(int))); connect(chkRegBC, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterBC(int))); connect(chkRegDE, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterDE(int))); connect(chkRegHL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterHL(int))); connect(chkRegIX, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIX(int))); connect(chkRegIY, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIY(int))); connect(chkRegIXL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIXL(int))); connect(chkRegIXH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIXH(int))); connect(chkRegIYL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIYL(int))); connect(chkRegIYH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIYH(int))); connect(chkRegOffset, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterOffset(int))); connect(chkRegI, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterI(int))); groupSlots->setEnabled(false); groupSegments->setEnabled(false); btnRemoveFile->setEnabled(false); btnRemoveSymbol->setEnabled(false); initFileList(); initSymbolList(); } void SymbolManager::closeEvent(QCloseEvent* e) { // store layout Settings& s = Settings::get(); s.setValue("SymbolManager/WindowGeometry", saveGeometry()); s.setValue("SymbolManager/HeaderFiles", treeFiles->header()->saveState()); s.setValue("SymbolManager/HeaderSymbols", treeLabels->header()->saveState()); QDialog::closeEvent(e); } /* * File list support functions */ void SymbolManager::initFileList() { treeFiles->clear(); for (int i = 0; i < symTable.symbolFilesSize(); ++i) { QTreeWidgetItem* item = new QTreeWidgetItem(treeFiles); item->setText(0, symTable.symbolFile(i)); item->setText(1, symTable.symbolFileRefresh(i).toString(Qt::LocaleDate)); } } void SymbolManager::addFile() { // create dialog QFileDialog* d = new QFileDialog(this); QStringList types; types << "All supported files (*.sym *.map *.symbol *.publics *.sys)" << "tniASM 0.x symbol files (*.sym)" << "tniASM 1.x symbol files (*.sym)" << "asMSX 0.x symbol files (*.sym)" << "HiTech C symbol files (*.sym)" << "HiTech C link map files (*.map)" << "pasmo symbol files (*.symbol *.publics *.sys)"; d->setNameFilters(types); d->setAcceptMode(QFileDialog::AcceptOpen); d->setFileMode(QFileDialog::ExistingFile); // set default directory d->setDirectory(Settings::get().value("SymbolManager/OpenDir", QDir::currentPath()).toString()); // run if (d->exec()) { QString f = d->selectedNameFilter(); QString n = d->selectedFiles().at(0); // load file from the correct type bool read = false; if (f.startsWith("tniASM 0")) { read = symTable.readFile(n, SymbolTable::TNIASM0_FILE); } else if (f.startsWith("tniASM 1")) { read = symTable.readFile(n, SymbolTable::TNIASM1_FILE); } else if (f.startsWith("asMSX")) { read = symTable.readFile(n, SymbolTable::ASMSX_FILE); } else if (f.startsWith("HiTech C symbol")) { read = symTable.readFile(n, SymbolTable::HTC_FILE); } else if (f.startsWith("HiTech C link")) { read = symTable.readFile(n, SymbolTable::LINKMAP_FILE); } else if (f.startsWith("pasmo")) { read = symTable.readFile(n, SymbolTable::PASMO_FILE); } else { read = symTable.readFile(n); } // if read succesful, add it to the list if (read) { initFileList(); initSymbolList(); emit symbolTableChanged(); } } // store last used path Settings::get().setValue("SymbolManager/OpenDir", d->directory().absolutePath()); } void SymbolManager::removeFile() { int r = QMessageBox::question( this, tr("Remove symbol file(s)"), tr("When removing the symbol file(s), do you want keep or " "delete the attached symbols?"), "Keep symbols", "Delete symbols", "Cancel", 1, 2); if (r == 2) return; for (int i = 0; i < treeFiles->selectedItems().size(); ++i) { symTable.unloadFile(treeFiles->selectedItems().at(i)->text(0), r == 0); } initFileList(); initSymbolList(); emit symbolTableChanged(); } void SymbolManager::reloadFiles() { symTable.reloadFiles(); initFileList(); initSymbolList(); emit symbolTableChanged(); } void SymbolManager::fileSelectionChange() { btnRemoveFile->setEnabled(treeFiles->selectedItems().size()); } void SymbolManager::labelEdit(QTreeWidgetItem* item, int column) { // only symbol name and value are editable if (column == 0 || column == 2) { // open editor if manually added symbol Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); if (sym->source() == 0) { // first close possible existing editor closeEditor(); // open new editor treeLabels->openPersistentEditor(item, column); editItem = item; editColumn = column; } } } /* * Symbol support functions */ void SymbolManager::initSymbolList() { treeLabels->clear(); beginTreeLabelsUpdate(); for (Symbol* sym = symTable.findFirstAddressSymbol(0); sym != 0; sym = symTable.findNextAddressSymbol()) { QTreeWidgetItem* item = new QTreeWidgetItem(treeLabels); // attach a pointer to the symbol object to the tree item item->setData(0L, Qt::UserRole, quintptr(sym)); // update columns updateItemName(item); updateItemType(item); updateItemValue(item); updateItemSlots(item); updateItemSegments(item); updateItemRegisters(item); } endTreeLabelsUpdate(); } void SymbolManager::beginTreeLabelsUpdate() { ++treeLabelsUpdateCount; } void SymbolManager::endTreeLabelsUpdate() { if (treeLabelsUpdateCount > 0) { --treeLabelsUpdateCount; } } void SymbolManager::closeEditor() { if (editColumn >= 0) { treeLabels->closePersistentEditor(editItem, editColumn); editColumn = -1; } } void SymbolManager::addLabel() { // create an empty symbol Symbol* sym = new Symbol(tr("New symbol"), 0); symTable.add(sym); beginTreeLabelsUpdate(); QTreeWidgetItem* item = new QTreeWidgetItem(treeLabels); item->setData(0, Qt::UserRole, quintptr(sym)); updateItemName(item); updateItemType(item); updateItemValue(item); updateItemSlots(item); updateItemSegments(item); updateItemRegisters(item); endTreeLabelsUpdate(); closeEditor(); treeLabels->setFocus(); treeLabels->setCurrentItem(item, 0); treeLabels->scrollToItem(item); treeLabels->openPersistentEditor(item, 0); editItem = item; editColumn = 0; // emit notification that something has changed emit symbolTableChanged(); } void SymbolManager::removeLabel() { QList selection = treeLabels->selectedItems(); // check for selection if (selection.empty()) return; // remove selected items bool deleted = false; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { // get symbol Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // check if symbol is from symbol file if (!sym->source()) { // remove from table symTable.remove(sym); deleted = true; } } if (deleted) { // refresh tree initSymbolList(); emit symbolTableChanged(); } } void SymbolManager::labelChanged(QTreeWidgetItem* item, int column) { if (!treeLabelsUpdateCount) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // Set symbol text from tree item if any QString symText = item->text(0).trimmed(); if (symText.isEmpty()) symText = "[unnamed]"; sym->setText(symText); // set value TODO: proper decoding of value int value = stringToValue(item->text(2)); if (value >= 0 && value < 65536) sym->setValue(value); treeLabels->closePersistentEditor(item, column); editColumn = -1; // update item name and value beginTreeLabelsUpdate(); updateItemName(item); updateItemValue(item); endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } } void SymbolManager::labelSelectionChanged() { // remove possible editor closeEditor(); QList selection = treeLabels->selectedItems(); // check if is available at all if (selection.empty()) { // disable everything btnRemoveSymbol->setEnabled(false); groupSlots->setEnabled(false); groupSegments->setEnabled(false); groupType->setEnabled(false); groupRegs8->setEnabled(false); groupRegs16->setEnabled(false); return; } // check selection for "manual insertion", identical slot mask, // identical register mask, identical types and value size bool removeButActive = true; bool anyEight = false; bool sameType = true; Symbol::SymbolType type; int slotMask, slotMaskMultiple = 0; int regMask, regMaskMultiple = 0; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { // get symbol Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // check if symbol is from symbol file if (sym->source()) removeButActive = false; if (selit == selection.begin()) { // first item, reference for slotMask and regMask slotMask = sym->validSlots(); regMask = sym->validRegisters(); type = sym->type(); } else { // other, set all different bits slotMaskMultiple |= slotMask ^ sym->validSlots(); regMaskMultiple |= regMask ^ sym->validRegisters(); // check for different type if (type != sym->type()) sameType = false; } // check for 8 bit values if ((sym->value() & 0xFF00) == 0) { anyEight = true; } } btnRemoveSymbol->setEnabled(removeButActive); groupSlots->setEnabled(true); groupType->setEnabled(true); groupRegs8->setEnabled(anyEight); groupRegs16->setEnabled(true); beginTreeLabelsUpdate(); // set slot selection for (int i = 0; i < 16; ++i) { chkSlots[i]->setTristate(false); if (slotMaskMultiple & 1) { chkSlots[i]->setCheckState(Qt::PartiallyChecked); } else if (slotMask & 1) { chkSlots[i]->setCheckState(Qt::Checked); } else { chkSlots[i]->setCheckState(Qt::Unchecked); } slotMask >>= 1; slotMaskMultiple >>= 1; } // set register selection for (int i = 0; i < 18; ++i) { chkRegs[i]->setTristate(false); if (regMaskMultiple & 1) { chkRegs[i]->setCheckState(Qt::PartiallyChecked); } else if (regMask & 1) { chkRegs[i]->setCheckState(Qt::Checked); } else { chkRegs[i]->setCheckState(Qt::Unchecked); } regMask >>= 1; regMaskMultiple >>= 1; } // temporarily disable exclusive radiobuttons to be able to // deselect them all. radJump->setAutoExclusive (false); radVar->setAutoExclusive (false); radValue->setAutoExclusive(false); // set type radio buttons radJump->setChecked (sameType && type == Symbol::JUMPLABEL); radVar->setChecked (sameType && type == Symbol::VARIABLELABEL); radValue->setChecked(sameType && type == Symbol::VALUE); // enable exclusive radiobuttons (this won't immediately activate // one if none are active). radJump->setAutoExclusive (true); radVar->setAutoExclusive (true); radValue->setAutoExclusive(true); endTreeLabelsUpdate(); } void SymbolManager::changeSlot(int id, int state) { if (treeLabelsUpdateCount) return; // disallow another tristate selection chkSlots[id]->setTristate(false); // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); int bit = 1 << id; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // set or clear bit if (state == Qt::Checked) { sym->setValidSlots(sym->validSlots() | bit); } else { sym->setValidSlots(sym->validSlots() & ~bit); } // update item in treewidget updateItemSlots(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } void SymbolManager::changeRegister(int id, int state) { if (treeLabelsUpdateCount) return; // disallow another tristate selection chkRegs[id]->setTristate(false); // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); int bit = 1 << id; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // set or clear bit if (state == Qt::Checked) { sym->setValidRegisters(sym->validRegisters() | bit); } else { sym->setValidRegisters(sym->validRegisters() & ~bit); } // update item in treewidget updateItemRegisters(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } void SymbolManager::changeType(bool /*checked*/) { if (treeLabelsUpdateCount) return; // determine selected type Symbol::SymbolType newType = Symbol::JUMPLABEL; if (radVar->isChecked()) { newType = Symbol::VARIABLELABEL; } else if (radValue->isChecked()) { newType = Symbol::VALUE; } // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); sym->setType(newType); updateItemType(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } /* * Symbol tree layout functions */ void SymbolManager::updateItemName(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // set text and icon item->setText(0, sym->text()); if (sym->source()) { item->setIcon(0, QIcon(":/icons/symfil.png")); item->setText(6, *sym->source()); } else { item->setIcon(0, QIcon(":/icons/symman.png")); } // set color based on status as well as status in 2nd column switch (sym->status()) { case Symbol::HIDDEN: item->setTextColor(0, QColor(128, 128, 128)); break; case Symbol::LOST: item->setTextColor(0, QColor(128, 0, 0)); break; default: break; } } void SymbolManager::updateItemType(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // set symbol type in 2nd column switch (sym->type()) { case Symbol::JUMPLABEL: item->setText(1, tr("Jump label")); break; case Symbol::VARIABLELABEL: item->setText(1, tr("Variable label")); break; case Symbol::VALUE: item->setText(1, tr("Value")); break; } } void SymbolManager::updateItemValue(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // symbol value in 3rd column // TODO: Custom prefix/postfix item->setText(2, QString("$%1").arg(sym->value(), 4, 16, QChar('0'))); } void SymbolManager::updateItemSlots(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); QString slotText; int slotmask = sym->validSlots(); // value represents 16 bits for 4 subslots in 4 slots if (slotmask == 0xFFFF) { slotText = tr("All"); } else if (slotmask == 0) { slotText = tr("None"); } else { // create a list of valid slots // loop over all primary slots for (int ps = 0; ps < 4; ++ps) { QString subText; int subslots = (slotmask >> (4 * ps)) & 15; if (subslots == 15) { // all subslots are ok subText = QString("%1-*").arg(ps); } else if (subslots) { // some subslots are ok if (subslots & 1) subText += "/0"; if (subslots & 2) subText += "/1"; if (subslots & 4) subText += "/2"; if (subslots & 8) subText += "/3"; subText = QString("%1-").arg(ps) + subText.mid(1); } // add to string if any subslots were ok if (!subText.isEmpty()) { if (!slotText.isEmpty()) slotText += ", "; slotText += subText; } } } // valid slots in 4th column item->setText(3, slotText); } void SymbolManager::updateItemSegments(QTreeWidgetItem* item) { item->data(0, Qt::UserRole).value(); } void SymbolManager::updateItemRegisters(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); QString regText; int regmask = sym->validRegisters(); // value represents 16 bits for 4 subslots in 4 slots if (regmask == 0x3FFFF) { regText = tr("All"); } else if (regmask == 0) { regText = tr("None"); } else { if ((regmask & Symbol::REG_ALL8) == Symbol::REG_ALL8) { // all 8 bit registers selected regText = "All 8 bit, "; regmask ^= Symbol::REG_ALL8; } else if ((regmask & Symbol::REG_ALL16) == Symbol::REG_ALL16) { // all 16 bit registers selected regText = "All 16 bit, "; regmask ^= Symbol::REG_ALL16; } // register list for remaining registers static const char* const registers[] = { "A", "B", "C", "D", "E", "H", "L", "BC", "DE", "HL", "IX", "IY", "IXL", "IXH", "IYL", "IYH", "Offset", "I" }; for (int i = 0; i < 18; ++i) { if (regmask & 1) { regText += QString("%1, ").arg(registers[i]); } regmask >>= 1; } regText.chop(2); } // valid slots in 4th column item->setText(5, regText); } // load of functions that shouldn't really be necessary void SymbolManager::changeSlot00(int state) { changeSlot(0, state); } void SymbolManager::changeSlot01(int state) { changeSlot(1, state); } void SymbolManager::changeSlot02(int state) { changeSlot(2, state); } void SymbolManager::changeSlot03(int state) { changeSlot(3, state); } void SymbolManager::changeSlot10(int state) { changeSlot(4, state); } void SymbolManager::changeSlot11(int state) { changeSlot(5, state); } void SymbolManager::changeSlot12(int state) { changeSlot(6, state); } void SymbolManager::changeSlot13(int state) { changeSlot(7, state); } void SymbolManager::changeSlot20(int state) { changeSlot(8, state); } void SymbolManager::changeSlot21(int state) { changeSlot(9, state); } void SymbolManager::changeSlot22(int state) { changeSlot(10, state); } void SymbolManager::changeSlot23(int state) { changeSlot(11, state); } void SymbolManager::changeSlot30(int state) { changeSlot(12, state); } void SymbolManager::changeSlot31(int state) { changeSlot(13, state); } void SymbolManager::changeSlot32(int state) { changeSlot(14, state); } void SymbolManager::changeSlot33(int state) { changeSlot(15, state); } void SymbolManager::changeRegisterA(int state) { changeRegister(0, state); } void SymbolManager::changeRegisterB(int state) { changeRegister(1, state); } void SymbolManager::changeRegisterC(int state) { changeRegister(2, state); } void SymbolManager::changeRegisterD(int state) { changeRegister(3, state); } void SymbolManager::changeRegisterE(int state) { changeRegister(4, state); } void SymbolManager::changeRegisterH(int state) { changeRegister(5, state); } void SymbolManager::changeRegisterL(int state) { changeRegister(6, state); } void SymbolManager::changeRegisterBC(int state) { changeRegister(7, state); } void SymbolManager::changeRegisterDE(int state) { changeRegister(8, state); } void SymbolManager::changeRegisterHL(int state) { changeRegister(9, state); } void SymbolManager::changeRegisterIX(int state) { changeRegister(10, state); } void SymbolManager::changeRegisterIY(int state) { changeRegister(11, state); } void SymbolManager::changeRegisterIXL(int state) { changeRegister(12, state); } void SymbolManager::changeRegisterIXH(int state) { changeRegister(13, state); } void SymbolManager::changeRegisterIYL(int state) { changeRegister(14, state); } void SymbolManager::changeRegisterIYH(int state) { changeRegister(15, state); } void SymbolManager::changeRegisterOffset(int state) { changeRegister(16, state); } void SymbolManager::changeRegisterI(int state) { changeRegister(17, state); } debugger-master/src/main.cpp0000644000175000017500000000105513560352104015706 0ustar shevekshevek#include "DebuggerForm.h" #include "Settings.h" #include #include int main(int argc, char** argv) { QApplication app(argc, argv); // Don't set the icon on OS X, because it will replace the high-res version // with a lower resolution one, even though openMSX-debugger-logo-256.png is 256x256. #ifndef __APPLE__ app.setWindowIcon(QIcon(":icons/openMSX-debugger-logo-256.png")); #endif // restore main settings app.setFont(Settings::get().font(Settings::APP_FONT)); DebuggerForm debugger; debugger.show(); return app.exec(); } debugger-master/src/node.mk0000644000175000017500000000152113560352104015532 0ustar shevekshevekinclude build/node-start.mk SUBDIRS:= \ openmsx MOC_SRC_HDR:= \ DockableWidget DockableWidgetArea DockableWidgetLayout \ CPURegsViewer CommClient DebuggerForm DisasmViewer FlagsViewer HexViewer \ SlotViewer StackViewer ConnectDialog OpenMSXConnection SymbolManager \ Settings PreferencesDialog BreakpointDialog DebuggableViewer \ DebugSession MainMemoryViewer BitMapViewer VramBitMappedView \ VDPDataStore VDPStatusRegViewer VDPRegViewer InteractiveLabel \ InteractiveButton VDPCommandRegViewer GotoDialog SymbolTable SRC_HDR:= \ DockManager Dasm DasmTables DebuggerData SymbolTable Convert Version \ CPURegs SimpleHexRequest SRC_ONLY:= \ main UI:= \ ConnectDialog SymbolManager PreferencesDialog BreakpointDialog \ BitMapViewer VDPStatusRegisters VDPRegistersExplained VDPCommandRegisters \ GotoDialog include build/node-end.mk debugger-master/src/DebuggableViewer.cpp0000644000175000017500000000406213560352104020166 0ustar shevekshevek#include "DebuggableViewer.h" #include "HexViewer.h" #include #include DebuggableViewer::DebuggableViewer(QWidget* parent) : QWidget(parent) { // create selection list and viewer debuggableList = new QComboBox(); debuggableList->setEditable(false); hexView = new HexViewer(); hexView->setIsInteractive(true); hexView->setIsEditable(true); QVBoxLayout* vbox = new QVBoxLayout(); vbox->setMargin(0); vbox->addWidget(debuggableList); vbox->addWidget(hexView); setLayout(vbox); connect(hexView, SIGNAL(locationChanged(int)), this, SLOT(locationChanged(int))); } void DebuggableViewer::settingsChanged() { hexView->settingsChanged(); } void DebuggableViewer::refresh() { hexView->refresh(); } void DebuggableViewer::debuggableSelected(int index) { QString name = debuggableList->itemText(index); int size = debuggableList->itemData(index).toInt(); if (index >= 0) lastSelected = name; // add braces when the name contains a space if (name.contains(QChar(' '))) { name.append(QChar('}')); name.prepend(QChar('{')); } hexView->setDebuggable(name, size); } void DebuggableViewer::locationChanged(int loc) { lastLocation = loc; } void DebuggableViewer::setDebuggables(const QMap& list) { int select = -1; // disconnect signal to prevent updates debuggableList->disconnect(this, SLOT(debuggableSelected(int))); debuggableList->clear(); for (QMap::const_iterator it = list.begin(); it != list.end(); ++it) { // set name and strip braces if necessary QString name = it.key(); if (name.contains(QChar(' '))) { name = name.mid(1, name.size() - 2); } // check if this was the previous selection if (name == lastSelected) select = debuggableList->count(); debuggableList->addItem(name, it.value()); } // reconnect signal before selecting item connect(debuggableList, SIGNAL(currentIndexChanged(int)), this, SLOT(debuggableSelected(int))); if (!list.empty() && select >= 0) { debuggableList->setCurrentIndex(select); hexView->setLocation(lastLocation); } } debugger-master/src/BitMapViewer.ui0000644000175000017500000003751113560352104017161 0ustar shevekshevek BitMapViewer 0 0 604 619 Dialog 0 QFrame::StyledPanel QFrame::Raised 0 2 Screen mode: false 5 6 7 8 10 11 12 false 0 1 2 3 Lines visible false 192 212 256 Show page Replace color 0 by false Displayed as: Qt::Vertical QSizePolicy::Fixed 0 13 Qt::Horizontal 22 17 0 Border color VDP mode: Vram address start: 5 Lines visible 0x00000 212 Use current VDP settings true Qt::Horizontal 22 17 1 Save image... Edit palette.. Use VDP palette registers true Qt::Vertical QSizePolicy::Minimum 0 0 Zoom 2 1.000000000000000 16.000000000000000 0.250000000000000 Take VRAM snapshot 0 0 0 0 QFrame::Panel Qt::ScrollBarAsNeeded Qt::ScrollBarAsNeeded false Qt::AlignCenter 38 0 508 420 X: 0 0 18 0 000 Y: 0 0 18 0 000 Color: 0 0 18 0 000 Qt::Horizontal 40 20 Vram address: 0 0 42 0 0x00000 byte value: 0 0 24 0 0x00 debugger-master/src/PreferencesDialog.cpp0000644000175000017500000000644013560352104020346 0ustar shevekshevek#include "PreferencesDialog.h" #include "Settings.h" #include #include #include PreferencesDialog::PreferencesDialog(QWidget* parent) : QDialog(parent) { setupUi(this); connect(listFonts, SIGNAL(currentRowChanged(int)), this, SLOT(fontSelectionChange(int))); connect(rbUseAppFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(rbUseFixedFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(rbUseCustomFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(btnSelectFont, SIGNAL(clicked()), this, SLOT(fontSelectCustom())); connect(btnFontColor, SIGNAL(clicked()), this, SLOT(fontSelectColor())); initFontList(); listFonts->setCurrentRow(0); } /* * Font settings */ void PreferencesDialog::initFontList() { Settings& s = Settings::get(); listFonts->clear(); for (int f = Settings::APP_FONT; f < Settings::FONT_END; ++f) { new QListWidgetItem(s.fontName((Settings::DebuggerFont)f), listFonts); } } void PreferencesDialog::fontSelectionChange(int row) { updating = true; if (row == 0) { rbUseAppFont->setText(tr("Use system font")); } else { rbUseAppFont->setText(tr("Use application font")); } rbUseAppFont->setEnabled(row >= 0); rbUseFixedFont->setEnabled(row > 1); rbUseCustomFont->setEnabled(row >= 0); switch (Settings::get().fontType( (Settings::DebuggerFont)row)) { case Settings::APPLICATION_DEFAULT: rbUseAppFont->setChecked(true); break; case Settings::FIXED_DEFAULT: rbUseFixedFont->setChecked(true); break; case Settings::CUSTOM: rbUseCustomFont->setChecked(true); break; } lblPreview->setFont(Settings::get().font ((Settings::DebuggerFont)row)); setFontPreviewColor(Settings::get().fontColor((Settings::DebuggerFont)row)); btnSelectFont->setEnabled(rbUseCustomFont->isChecked()); btnFontColor->setEnabled(row > 1); updating = false; } void PreferencesDialog::fontTypeChanged(bool state) { if (!state || updating) return; Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); Settings& s = Settings::get(); if (rbUseAppFont->isChecked()) { s.setFontType(f, Settings::APPLICATION_DEFAULT); } else if (rbUseFixedFont->isChecked()) { s.setFontType(f, Settings::FIXED_DEFAULT); } else { s.setFontType(f, Settings::CUSTOM); } lblPreview->setFont(s.font(f)); btnSelectFont->setEnabled(rbUseCustomFont->isChecked()); } void PreferencesDialog::fontSelectCustom() { bool ok; Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); QFont newFont = QFontDialog::getFont(&ok, Settings::get().font(f)); if (ok) { lblPreview->setFont(newFont); Settings::get().setFont(f, newFont); } } void PreferencesDialog::fontSelectColor() { Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); QColor newColor = QColorDialog::getColor(Settings::get().fontColor(f), this); if (newColor.isValid()) { Settings::get().setFontColor(f, newColor); setFontPreviewColor(newColor); } } void PreferencesDialog::setFontPreviewColor(const QColor& c) { if (listFonts->currentRow() > 1) { QPalette pal = lblPreview->palette(); pal.setColor(QPalette::WindowText, c); lblPreview->setPalette(pal); } else { lblPreview->setPalette(QPalette()); } } debugger-master/src/FlagsViewer.cpp0000644000175000017500000000444313560352104017204 0ustar shevekshevek#include "FlagsViewer.h" #include #include FlagsViewer::FlagsViewer(QWidget* parent) : QFrame(parent) { flags = flagsChanged = 0; // avoid UMR setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); frameR = frameL = frameT = frameB = frameWidth(); } void FlagsViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void FlagsViewer::paintEvent(QPaintEvent* e) { const char* const flagNames[8] = { "C" , "N", "P" , "", "H", "", "Z" , "S" }; const char* const flagOn[8] = { "(C)" , "" , "(PE)", "", "", "", "(Z)" , "(M)" }; const char* const flagOff[8] = { "(NC)", "" , "(PO)", "", "", "", "(NZ)", "(P)" }; // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); p.setPen(palette().color(QPalette::Text)); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int h = fontMetrics().height(); int flagWidth = fontMetrics().width("ZW"); int valWidth = fontMetrics().width("0 "); int d = fontMetrics().descent(); int y = frameT + h - 1 - d; for (int flag = 7; flag >= 0; --flag) { int x = frameL + 4; p.drawText(x, y, flagNames[flag]); x += flagWidth; int bit = 1 << flag; drawValue(p, x, y, (flags & bit) ? "1" : "0", flagsChanged & bit); x += valWidth; p.drawText(x, y, (flags & bit) ? flagOn[flag] : flagOff[flag]); y += h; } } QSize FlagsViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("ZW0 (PE) ") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB); } void FlagsViewer::drawValue(QPainter& p, int x, int y, const QString& str, bool changed) { if (changed) { p.setPen(Qt::red); } p.drawText(x, y, str); if (changed) { p.setPen(palette().color(QPalette::Text)); } } void FlagsViewer::setFlags(quint8 newFlags) { flagsChanged = flags ^ newFlags; flags = newFlags; update(); } debugger-master/src/BitMapViewer.h0000644000175000017500000000176513560352104016775 0ustar shevekshevek#ifndef BITMAPVIEWER_OPENMSX_H #define BITMAPVIEWER_OPENMSX_H #include "ui_BitMapViewer.h" #include class VramBitMappedView; class BitMapViewer : public QDialog, private Ui::BitMapViewer { Q_OBJECT public: BitMapViewer(QWidget* parent = 0); private: void decodeVDPregs(); void setPages(); VramBitMappedView* imageWidget; int screenMod; bool useVDP; private slots: void refresh(); void on_screenMode_currentIndexChanged(const QString& text); void on_showPage_currentIndexChanged(int index); void on_linesVisible_currentIndexChanged(int index); void on_bgColor_valueChanged(int value); void on_useVDPRegisters_stateChanged(int state); void on_saveImageButton_clicked(bool checked); void on_editPaletteButton_clicked(bool checked); void on_useVDPPalette_stateChanged(int state); void on_zoomLevel_valueChanged(double d); void imagePositionUpdate(int x, int y, int color, unsigned addr, int byteValue); void VDPDataStoreDataRefreshed(); }; #endif /* BITMAPVIEWER_OPENMSX_H */ debugger-master/src/DockableWidgetLayout.cpp0000644000175000017500000005513413560352104021037 0ustar shevekshevek#include "DockableWidgetLayout.h" #include "DockableWidget.h" #include #include #include static const int SNAP_DISTANCE = 16; DockableWidgetLayout::DockableWidgetLayout(QWidget* parent, int margin, int spacing) : QLayout(parent) { setMargin(margin); setSpacing(spacing); minWidth = minHeight = 0; maxWidth = maxHeight = 0; } DockableWidgetLayout::DockableWidgetLayout(int spacing) { setSpacing(spacing); minWidth = minHeight = 0; maxWidth = maxHeight = 0; } DockableWidgetLayout::~DockableWidgetLayout() { while (!dockedWidgets.empty()) { DockInfo* info = dockedWidgets.takeFirst(); delete info->item; delete info->widget; delete info; } } void DockableWidgetLayout::addItem(QLayoutItem* item) { addItem(item, -1); } void DockableWidgetLayout::addItem( QLayoutItem* item, int index, DockSide side, int dist, int w, int h) { DockInfo* info = new DockInfo(); info->item = item; info->widget = qobject_cast(item->widget()); info->dockSide = side; info->dockDistance = dist; info->left = 0; info->top = 0; info->width = -1; info->height = -1; info->useHintWidth = true; info->useHintHeight = true; if (info->widget->sizePolicy().horizontalPolicy() != QSizePolicy::Fixed && w > 0) { info->width = w; info->useHintWidth = false; } if (info->widget->sizePolicy().verticalPolicy() != QSizePolicy::Fixed && h > 0 ) { info->height = h; info->useHintHeight = false; } // first widget is the resize widget, set initial size if (dockedWidgets.empty()) { if (info->width == -1) { info->width = item->sizeHint().width(); } if (info->height == -1) { info->height = item->sizeHint().height(); } info->useHintWidth = false; info->useHintHeight = false; } for (int i = 0; i < dockedWidgets.size(); ++i) { Q_ASSERT(dockedWidgets.at(i)->widget != item->widget()); } if (index > -1 && index < dockedWidgets.size()) { dockedWidgets.insert(index, info); } else { dockedWidgets.append(info); } // recalculate size limits calcSizeLimits(); } void DockableWidgetLayout::addWidget(DockableWidget* widget, const QRect& rect) { int index; DockSide side; QRect r(rect); if (insertLocation(r, index, side, widget->sizePolicy())) { DockInfo* d = dockedWidgets.first(); int dist; switch (side) { case TOP: case BOTTOM: dist = r.left() - d->left; break; case LEFT: case RIGHT: dist = r.top() - d->top; break; } widget->show(); addItem(new QWidgetItem(widget), index, side, dist, r.width(), r.height()); update(); } } void DockableWidgetLayout::addWidget( DockableWidget* widget, DockSide side, int dist, int w, int h) { // append item at the back addItem(new QWidgetItem(widget), -1, side, dist, w, h); } void DockableWidgetLayout::changed() { calcSizeLimits(); update(); } Qt::Orientations DockableWidgetLayout::expandingDirections() const { return Qt::Horizontal | Qt::Vertical; } bool DockableWidgetLayout::hasHeightForWidth() const { return false; } int DockableWidgetLayout::count() const { return dockedWidgets.size(); } QLayoutItem* DockableWidgetLayout::takeAt(int index) { if (index < 0 || index >= dockedWidgets.size()) return 0; DockInfo* info = dockedWidgets.takeAt(index); QLayoutItem* item = info->item; delete info; calcSizeLimits(); return item; } QLayoutItem* DockableWidgetLayout::itemAt(int index) const { if (index < 0 || index >= dockedWidgets.size()) return 0; return dockedWidgets.at(index)->item; } QSize DockableWidgetLayout::minimumSize() const { return QSize(minWidth, minHeight); } QSize DockableWidgetLayout::maximumSize() const { return QSize(maxWidth, maxHeight); } QSize DockableWidgetLayout::sizeHint() const { return QSize(layoutWidth, layoutHeight); } void DockableWidgetLayout::setGeometry(const QRect& rect) { QLayout::setGeometry(rect); // Qt sometimes sets the geometry outside the minimumSize/maximumSize range. :/ int W = std::min(maxWidth, std::max(minWidth, rect.width ())); int H = std::min(maxHeight, std::max(minHeight, rect.height())); // set main widget size int dx = W - layoutWidth; int dy = H - layoutHeight; if (dx != 0 || dy != 0) { sizeMove(dx, dy); calcSizeLimits(); } // resize the widgets for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; if (!d->widget->isHidden()) { d->item->setGeometry(d->bounds()); } } } void DockableWidgetLayout::calcSizeLimits() { if (dockedWidgets.empty()) return; // layout with current sizes doLayout(); DockInfo* d = dockedWidgets.first(); // store current size int curWidth = d->width; int curHeight = d->height; QVector distStore; for (int i = 0; i < dockedWidgets.size(); ++i) { distStore.push_back(dockedWidgets.at(i)->dockDistance); } // first check minimum width (blunt method) for (int i = d->widget->minimumWidth(); i <= curWidth; ++i) { // trial layout sizeMove(i - d->width, 0); doLayout(true); // restore d->width = curWidth; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutHeight == checkHeight && layoutWidth - checkWidth == d->width - i) { break; } } minWidth = checkWidth; // first check maximum width (blunt method) for (int i = d->widget->maximumWidth(); i >= curWidth; --i) { // trial layout sizeMove(i - d->width, 0); doLayout(true); // restore d->width = curWidth; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutHeight == checkHeight && layoutWidth - checkWidth == d->width - i) { break; } } maxWidth = checkWidth; // first check minimum height (blunt method) for (int i = d->widget->minimumHeight(); i <= curHeight; ++i) { // trial layout sizeMove(0, i - d->height); doLayout(true); // restore d->height = curHeight; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutWidth == checkWidth && layoutHeight - checkHeight == d->height - i) { break; } } minHeight = checkHeight; // first check maximum width (blunt method) for (int i = d->widget->maximumHeight(); i >= curHeight; --i) { // trial layout sizeMove(0, i - d->height); doLayout(true); // restore d->height = curHeight; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutWidth == checkWidth && layoutHeight - checkHeight == d->height - i) { break; } } maxHeight = checkHeight; // restore layout doLayout(); } void DockableWidgetLayout::sizeMove(int dx, int dy) { DockInfo* d0 = dockedWidgets.first(); for (int i = 1; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets.at(i); if (d->dockSide == TOP || d->dockSide == BOTTOM) { if (d->dockDistance >= d0->width) { d->dockDistance += dx; } } if (d->dockSide == LEFT || d->dockSide == RIGHT) { if (d->dockDistance >= d0->height) { d->dockDistance += dy; } } } d0->width += dx; d0->height += dy; } void DockableWidgetLayout::doLayout(bool check) { if (dockedWidgets.empty()) return; DockInfo* d = dockedWidgets.first(); d->left = 0; d->top = 0; int W = d->width; int H = d->height; int dx = 0, dy = 0; for (int i = 1; i < dockedWidgets.size(); ++i) { d = dockedWidgets[i]; // only process visible widgets if (d->widget->isHidden()) { d->left = -10000; d->top = -10000; continue; } // determine size if (d->useHintWidth) { d->width = d->item->sizeHint().width(); } if (d->useHintHeight) { d->height = d->item->sizeHint().height(); } // determine location switch (d->dockSide) { case TOP: d->left = d->dockDistance; if (d->dockDistance >= W || d->dockDistance+d->width <= 0) { d->top = H - d->height; } else { d->top = -d->height; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top - QWIDGETSIZE_MAX, d->width, d->height + QWIDGETSIZE_MAX); if (r.intersects(d2->bounds())) { d->top = d2->top - d->height; } } break; case LEFT: d->top = d->dockDistance; if (d->dockDistance >= H || d->dockDistance+d->height <= 0) { d->left = W - d->width; } else { d->left = -d->width; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left - QWIDGETSIZE_MAX, d->top, d->width + QWIDGETSIZE_MAX, d->height); if (r.intersects(d2->bounds())) { d->left = d2->left - d->width; } } break; case RIGHT: d->top = d->dockDistance; if (d->dockDistance >= H || d->dockDistance+d->height <= 0) { d->left = 0; } else { d->left = W; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top, d->width + QWIDGETSIZE_MAX, d->height); if (r.intersects(d2->bounds())) { d->left = d2->left + d2->width; } } break; case BOTTOM: d->left = d->dockDistance; if (d->dockDistance >= W || d->dockDistance+d->width <= 0) { d->top = 0; } else { d->top = H; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top, d->width, d->height + QWIDGETSIZE_MAX); if (r.intersects(d2->bounds())) { d->top = d2->top + d2->height; } } break; } // check negative coordinates if (d->left < dx) dx = d->left; if (d->top < dy) dy = d->top; } // translate widgets and calculate size int& w = check ? checkWidth : layoutWidth; int& h = check ? checkHeight : layoutHeight; w = h = 0; for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; if (!d->widget->isHidden()) { d->left -= dx; d->top -= dy; w = std::max(w, d->right()); h = std::max(h, d->bottom()); } } } bool DockableWidgetLayout::overlaysWithFirstNWidgets(const QRect& r, int n) const { for (int i = 0; i < n; ++i) { if (r.intersects(dockedWidgets[i]->bounds())) { return true; } } return false; } static bool isClose(int a, int b) { return abs(a - b) < SNAP_DISTANCE; } bool DockableWidgetLayout::insertLocation( QRect& rect, int& index, DockSide& side, const QSizePolicy& sizePol) { // best insertion data // Distance is a number that represents the how far // the insertion rectangle is from the final location. unsigned bestDistance = 0xFFFFFFFF; int bestIndex = 0; DockSide bestSide; QRect bestRect; // loop over all widgets and find appropriate matching sides for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; /***************************************************** * Check for placement against the top of the widget * *****************************************************/ if (i == 0 || d->dockSide != BOTTOM) { if (!(rect.left() > d->right() - SNAP_DISTANCE || rect.right() < d->left + SNAP_DISTANCE) && isClose(rect.bottom(), d->top)) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.bottom() - d->top); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->top == d2->top) { sidePoints.insert(d2->left); sidePoints.insert(d2->right()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->bottom() == d2->top) { sidePoints.insert(d3->left); sidePoints.insert(d3->right()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.left()); if (newDist1 < bestDistance && isClose(*it, rect.left())) { QRect r(QPoint(*it, d->top - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = TOP; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.right()); if (newDist2 < bestDistance && isClose(*it, rect.right())) { QRect r(QPoint(*it - rect.width(), d->top - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = TOP; bestRect = r; } } } // check for resized placement options if (sizePol.horizontalPolicy() != QSizePolicy::Fixed) { int mid = rect.left() + rect.width() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(*itb, d->top - rect.height(), sp_diff, rect.height()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = TOP; bestRect = r; } } } } } } } /******************************************************** * Check for placement against the bottom of the widget * ********************************************************/ if (i == 0 || d->dockSide != TOP) { if (!(rect.left() > d->right() - SNAP_DISTANCE || rect.right() < d->left + SNAP_DISTANCE) && isClose(rect.top(), d->bottom())) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.top() - d->bottom()); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->bottom() == d2->bottom()) { sidePoints.insert(d2->left); sidePoints.insert(d2->right()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->top == d2->bottom()) { sidePoints.insert(d3->left); sidePoints.insert(d3->right()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.left()); if (newDist1 < bestDistance && isClose(*it, rect.left())) { QRect r(QPoint(*it, d->bottom()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.right()); if (newDist2 < bestDistance && isClose(*it, rect.right())) { QRect r(QPoint(*it - rect.width(), d->bottom()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } } // check for resized placement options if (sizePol.horizontalPolicy() != QSizePolicy::Fixed) { int mid = rect.left() + rect.width() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(*itb, d->bottom(), sp_diff, rect.height()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } } } } } } /****************************************************** * Check for placement against the left of the widget * ******************************************************/ if (i == 0 || d->dockSide != RIGHT) { if (!(rect.top() > d->bottom() - SNAP_DISTANCE || rect.bottom() < d->top + SNAP_DISTANCE) && isClose(rect.right(), d->left)) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.right() - d->left); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->left == d2->left) { sidePoints.insert(d2->top); sidePoints.insert(d2->bottom()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->right() == d2->left) { sidePoints.insert(d3->top); sidePoints.insert(d3->bottom()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.top()); if (newDist1 < bestDistance && isClose(*it, rect.top())) { QRect r(QPoint(d->left - rect.width(), *it), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.bottom()); if (newDist2 < bestDistance && isClose(*it, rect.bottom())) { QRect r(QPoint(d->left - rect.width(), *it - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } } // check for resized placement options if (sizePol.verticalPolicy() != QSizePolicy::Fixed) { int mid = rect.top() + rect.height() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(d->left - rect.width(), *itb, rect.width(), sp_diff); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } } } } } } /******************************************************* * Check for placement against the right of the widget * *******************************************************/ if (i == 0 || d->dockSide != LEFT) { if (!(rect.top() > d->bottom() - SNAP_DISTANCE || rect.bottom() < d->top + SNAP_DISTANCE) && isClose(rect.left(), d->right())) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.left() - d->right()); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->right() == d2->right()) { sidePoints.insert(d2->top); sidePoints.insert(d2->bottom()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->left == d2->right()) { sidePoints.insert(d3->top); sidePoints.insert(d3->bottom()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.top()); if (newDist1 < bestDistance && isClose(*it, rect.top())) { QRect r(QPoint(d->left + d->width, *it), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.bottom()); if (newDist2 < bestDistance && isClose(*it, rect.bottom())) { QRect r(QPoint(d->right(), *it - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } } // check for resized placement options if (sizePol.verticalPolicy() != QSizePolicy::Fixed) { int mid = rect.top() + rect.height() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(d->right(), *itb, rect.width(), sp_diff); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } } } } } } } if (bestIndex) { rect = bestRect; index = bestIndex; side = bestSide; return true; } else { return false; } } bool DockableWidgetLayout::insertLocation(QRect& rect, const QSizePolicy& sizePol) { int index; DockSide side; return insertLocation(rect, index, side, sizePol); } void DockableWidgetLayout::getConfig(QStringList& list) { for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets.at(i); // string format D [Hidden/Visible] [Side] [Distance] [Width] [Height] QString s("%1 D %2 %3 %4 %5 %6"); s = s.arg(d->widget->id()); if (d->widget->isHidden()) { s = s.arg("H"); } else { s = s.arg("V"); } switch (d->dockSide) { case TOP: s = s.arg("T"); break; case LEFT: s = s.arg("L"); break; case RIGHT: s = s.arg("R"); break; case BOTTOM: s = s.arg("B"); break; } s = s.arg(d->dockDistance); if (d->useHintWidth) { s = s.arg(-1); } else { s = s.arg(d->width); } if (d->useHintHeight) { s = s.arg(-1); } else { s = s.arg(d->height); } list.append(s); } } debugger-master/src/Convert.h0000644000175000017500000000034313560352104016046 0ustar shevekshevek#ifndef CONVERT_H #define CONVERT_H class QString; int stringToValue(const QString& str); QString hexValue(int value, int width = 0); QString& escapeXML(QString& str); QString& unescapeXML(QString& str); #endif // CONVERT_H debugger-master/src/OpenMSXConnection.cpp0000644000175000017500000001300313560352104020267 0ustar shevekshevek#include "OpenMSXConnection.h" #include #include #include SimpleCommand::SimpleCommand(const QString& command_) : command(command_) { } QString SimpleCommand::getCommand() const { return command; } void SimpleCommand::replyOk (const QString& message) { emit replyStatusOk(true); delete this; } void SimpleCommand::replyNok(const QString& message) { emit replyStatusOk(false); cancel(); } void SimpleCommand::cancel() { delete this; } static QString createDebugCommand(const QString& debuggable, unsigned offset, unsigned size) { return QString("debug_bin2hex [ debug read_block %1 %2 %3 ]") .arg(debuggable).arg(offset).arg(size); } ReadDebugBlockCommand::ReadDebugBlockCommand(const QString& commandString, unsigned size_, unsigned char* target_) : SimpleCommand(commandString) , size(size_), target(target_) { } ReadDebugBlockCommand::ReadDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size_, unsigned char* target_) : SimpleCommand(createDebugCommand(debuggable, offset, size_)) , size(size_), target(target_) { } static QString createDebugWriteCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char *data ) { QString cmd = QString("debug write_block %1 %2 [ debug_hex2bin \"") .arg(debuggable).arg(offset); for (unsigned i = offset; i < offset + size; ++i) { cmd += QString("%1").arg(int(data[i]), 2, 16, QChar('0')).toUpper(); } cmd += "\" ]"; return cmd; } WriteDebugBlockCommand::WriteDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size_, unsigned char* source_) : SimpleCommand(createDebugWriteCommand(debuggable, offset, size_, source_)) { } static unsigned char hex2val(char c) { return (c <= '9') ? (c - '0') : (c - 'A' + 10); } void ReadDebugBlockCommand::copyData(const QString& message) { assert(static_cast(message.size()) == 2 * size); for (unsigned i = 0; i < size; ++i) { target[i] = (hex2val(message[2 * i + 0].toLatin1()) << 4) + (hex2val(message[2 * i + 1].toLatin1()) << 0); } } OpenMSXConnection::OpenMSXConnection(QAbstractSocket* socket_) : socket(socket_) , reader(new QXmlSimpleReader()) , connected(true) { assert(socket->isValid()); reader->setContentHandler(this); reader->setErrorHandler(this); connect(socket, SIGNAL(readyRead()), this, SLOT(processData())); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); socket->write("\n"); } OpenMSXConnection::~OpenMSXConnection() { cleanup(); assert(commands.empty()); assert(!connected); socket->deleteLater(); } void OpenMSXConnection::sendCommand(Command* command) { assert(command); if (connected && socket->isValid()) { commands.enqueue(command); QString cmd = "" + command->getCommand() + ""; socket->write(cmd.toUtf8()); } else { command->cancel(); } } void OpenMSXConnection::cleanup() { if (!connected) return; connected = false; if (socket->isValid()) { socket->disconnect(this, SLOT(processData())); socket->disconnect(this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); socket->disconnect(this, SLOT(socketError(QAbstractSocket::SocketError))); socket->write("\n"); socket->disconnectFromHost(); } cancelPending(); emit disconnected(); } void OpenMSXConnection::cancelPending() { assert(!connected); while (!commands.empty()) { Command* command = commands.dequeue(); command->cancel(); } } void OpenMSXConnection::socketStateChanged(QAbstractSocket::SocketState state) { if (state != QAbstractSocket::ConnectedState) { cleanup(); } } void OpenMSXConnection::socketError(QAbstractSocket::SocketError /*state*/) { cleanup(); } void OpenMSXConnection::processData() { if (input.get()) { // continue input->setData(socket->readAll()); reader->parseContinue(); } else { // first time input.reset(new QXmlInputSource()); input->setData(socket->readAll()); reader->parse(input.get(), true); // incremental parsing } } bool OpenMSXConnection::fatalError(const QXmlParseException& exception) { qWarning("Fatal error on line %i, column %i: %s", exception.lineNumber(), exception.columnNumber(), exception.message().toLatin1().data()); cleanup(); return false; } bool OpenMSXConnection::startElement( const QString& /*namespaceURI*/, const QString& /*localName*/, const QString& /*qName*/, const QXmlAttributes& atts) { xmlAttrs = atts; xmlData.clear(); return true; } bool OpenMSXConnection::endElement( const QString& /*namespaceURI*/, const QString& /*localName*/, const QString& qName) { if (qName == "openmsx-output") { // ignore } else if (qName == "reply") { if (connected) { Command* command = commands.dequeue(); if (xmlAttrs.value("result") == "ok") { command->replyOk (xmlData); } else { command->replyNok(xmlData); } } else { // still receive a reply while we're already closing // the connection, ignore it } } else if (qName == "log") { emit logParsed(xmlAttrs.value("level"), xmlData); } else if (qName == "update") { emit updateParsed(xmlAttrs.value("type"), xmlAttrs.value("name"), xmlData); } else { qWarning("Unknown XML tag: %s", qName.toLatin1().data()); } return true; } bool OpenMSXConnection::characters(const QString& ch) { xmlData += ch; return true; } debugger-master/src/HexViewer.cpp0000644000175000017500000005015713560352104016677 0ustar shevekshevek#include "HexViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "Settings.h" #include #include #include #include #include #include #include static const int EXTRA_SPACING = 4; class HexRequest : public ReadDebugBlockCommand { public: HexRequest(const QString& debuggable, unsigned offset_, unsigned size, unsigned char* target, HexViewer& viewer_) : ReadDebugBlockCommand(debuggable, offset_, size, target) , offset(offset_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.hexdataTransfered(this); } virtual void cancel() { viewer.transferCancelled(this); } unsigned offset; private: HexViewer& viewer; }; HexViewer::HexViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding)); horBytes = 16; hexTopAddress = 0; hexMarkAddress = 0; hexData = NULL; previousHexData = NULL; debuggableSize = 0; waitingForData = false; displayMode = FILL_WIDTH; highlitChanges = true; addressLength = 4; isEditable = false; isInteractive = false; beingEdited = false; editedChars = false; useMarker = false; hasFocus = false; vertScrollBar = new QScrollBar(Qt::Vertical, this); vertScrollBar->setMinimum(0); vertScrollBar->setSingleStep(1); frameL = frameT = frameB = frameWidth(); frameR = frameL + vertScrollBar->sizeHint().width(); settingsChanged(); createActions(); connect(vertScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); } HexViewer::~HexViewer() { delete[] hexData; delete[] previousHexData; } void HexViewer::createActions() { fillWidthAction = new QAction(tr("&Fill with"), this); fillWidthAction->setShortcut(tr("Ctrl+F")); fillWidthAction->setStatusTip(tr("Fill the width with as many bytes as possible.")); fillWidth2Action = new QAction(tr("Power of &2"), this); fillWidth2Action->setShortcut(tr("Ctrl+2")); fillWidth2Action->setStatusTip(tr("Fill the with with the maximum power of 2 possible.")); setWith8Action = new QAction(tr("&8 bytes."), this); setWith8Action->setShortcut(tr("Ctrl+8")); setWith8Action->setStatusTip(tr("Set width to 8 bytes.")); setWith16Action = new QAction(tr("&16 bytes."), this); setWith16Action->setShortcut(tr("Ctrl+6")); setWith16Action->setStatusTip(tr("Set width to 16 bytes.")); setWith32Action = new QAction(tr("&32 bytes."), this); setWith32Action->setShortcut(tr("Ctrl+3")); setWith32Action->setStatusTip(tr("Set width to 32 bytes.")); connect(fillWidthAction, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(fillWidth2Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith8Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith16Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith32Action, SIGNAL(triggered()), this, SLOT(changeWidth())); addAction(fillWidthAction); addAction(fillWidth2Action); addAction(setWith8Action); addAction(setWith16Action); addAction(setWith32Action); setContextMenuPolicy(Qt::ActionsContextMenu); } void HexViewer::changeWidth() { if (sender() == fillWidthAction) setDisplayMode(FILL_WIDTH); else if (sender() == fillWidth2Action) setDisplayMode(FILL_WIDTH_POWEROF2); else if (sender() == setWith8Action) setDisplayWidth(8); else if (sender() == setWith16Action) setDisplayWidth(16); else if (sender() == setWith32Action) setDisplayWidth(32); } void HexViewer::setIsEditable(bool enabled) { isEditable = enabled; setUseMarker(true); } void HexViewer::setUseMarker(bool enabled) { useMarker = enabled; // below we should check if current marker is visible etc // but since in the debugger we will set this at instanciation // and then never change it again this is a quicky in case we do later on if (useMarker){ hexMarkAddress = hexTopAddress; } update(); } void HexViewer::setIsInteractive(bool enabled) { isInteractive = enabled; vertScrollBar->setEnabled(enabled); } void HexViewer::setDisplayMode(Mode mode) { displayMode = mode; setSizes(); } void HexViewer::setDisplayWidth(short width) { displayMode = FIXED; horBytes = width; setSizes(); } void HexViewer::settingsChanged() { QFontMetrics fm(Settings::get().font(Settings::HEX_FONT)); lineHeight = fm.height(); charWidth = fm.width("W"); hexCharWidth = fm.width("0ABCDEF") / 7; xAddr = frameL + 8; xData = xAddr + addressLength * hexCharWidth + charWidth; dataWidth = 3 * hexCharWidth; setSizes(); } void HexViewer::setSizes() { visibleLines = (height() - frameT - frameB) / lineHeight; partialBottomLine = (height() - frameT - frameB) != lineHeight * visibleLines; frameR = frameL; int w; // fit display to width if (displayMode != FIXED) { // scrollbar width int sbw = vertScrollBar->sizeHint().width(); horBytes = 1; int hb2 = 1; w = width() - frameL - frameR - xData - dataWidth - 2 * charWidth - 8; // calculate how many additional bytes can by displayed while (w-sbw >= dataWidth + charWidth) { ++horBytes; if( horBytes == 2*hb2 ) hb2 = horBytes; w -= dataWidth + charWidth; if ((horBytes & 3) == 0) w -= EXTRA_SPACING; if ((horBytes & 7) == 0) w -= EXTRA_SPACING; // remove scrollbar if (horBytes * visibleLines >= debuggableSize) sbw = 0; } // limit to power of two if needed if (displayMode == FILL_WIDTH_POWEROF2) horBytes = hb2; } // check if a scrollbar is needed if (horBytes * visibleLines < debuggableSize) { int maxLine = int(ceil(double(debuggableSize) / horBytes)) - visibleLines; maxLine = std::max(maxLine, 0); vertScrollBar->setMaximum(maxLine); vertScrollBar->setPageStep(visibleLines); frameR += vertScrollBar->sizeHint().width(); vertScrollBar->setGeometry(width() - frameR, frameT, vertScrollBar->sizeHint().width(), height() - frameT - frameB); vertScrollBar->show(); } else { vertScrollBar->hide(); hexTopAddress = 0; hexMarkAddress = 0; } // now see were the chars are drawn rightValuePos = xData + horBytes * dataWidth; xChar = rightValuePos + charWidth + EXTRA_SPACING * (int(horBytes / 4) + int(horBytes / 8)); rightCharPos = xChar + horBytes * charWidth; if (isEnabled()) { ///vertScrollBar->setValue(hexTopAddress / horBytes); setTopLocation(horBytes * int(hexTopAddress / horBytes)); } else { update(); } } QSize HexViewer::sizeHint() const { return QSize(frameL + 16 + (6 + 3 * horBytes / 2) * fontMetrics().width("A") + frameR, frameT + 10 * fontMetrics().height() + frameB ); } void HexViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); setSizes(); } void HexViewer::wheelEvent(QWheelEvent* e) { int v = vertScrollBar->value() - e->delta() / 40; vertScrollBar->setValue(v); e->accept(); } void HexViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); // exit if no debuggable is set if (debuggableName.isEmpty()) return; QPainter p(this); // set font info p.setFont(Settings::get().font(Settings::HEX_FONT)); QColor fc(Settings::get().fontColor(Settings::HEX_FONT)); int a = p.fontMetrics().ascent(); p.setPen(fc); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int y = frameT; int address = hexTopAddress; for (int i = 0; i < visibleLines+partialBottomLine; ++i) { // print address QString hexStr = QString("%1").arg(address, addressLength, 16, QChar('0')); p.setPen(palette().color(QPalette::Text)); p.drawText(xAddr, y + a, hexStr.toUpper()); // print bytes int x = xData; for (int j = 0; j < horBytes; ++j) { // print data if (address + j < debuggableSize) { hexStr.sprintf("%02X", hexData[address + j]); // draw marker if needed if (useMarker || beingEdited) { QRect b(x, y, dataWidth, lineHeight); if ((address + j) == hexMarkAddress) { p.fillRect(b, hasFocus ? Qt::cyan : Qt::lightGray); } // are we being edited ?? if (hasFocus && isEditable && !editedChars && ((address + j) == hexMarkAddress)) { if (beingEdited) { p.fillRect(b, Qt::darkGreen); if (cursorPosition) { hexStr.sprintf("%2X", editValue); } } else { p.drawRect(b); } } } // determine value colour if (highlitChanges) { QColor penClr = palette().color(QPalette::Text); if (hexData[address + j] != previousHexData[address + j]) { if ((address + j) != hexMarkAddress || !beingEdited) { penClr = Qt::red; } } if (((address + j) == hexMarkAddress ) && beingEdited && (cursorPosition == 0)) { penClr = Qt::white; } p.setPen(penClr); } p.drawText(x, y + a, hexStr); } x += dataWidth; // at extra spacing if ((j & 3) == 3) x += EXTRA_SPACING; if ((j & 7) == 7) x += EXTRA_SPACING; } // print characters x += charWidth; for (int j = 0; j < horBytes; ++j) { if (address + j >= debuggableSize) break; unsigned char chr = hexData[address + j]; if (chr < 32 || chr > 127) chr = '.'; // draw marker if needed if (useMarker || beingEdited) { QRect b(x, y, charWidth, lineHeight); if ((address + j) == hexMarkAddress) { p.fillRect(b, hasFocus ? Qt::cyan : Qt::lightGray); } // are we being edited ?? if (hasFocus && isEditable && editedChars && ((address + j) == hexMarkAddress)) { if (beingEdited) { p.fillRect(b, Qt::darkGreen); } else { p.drawRect(b); } } } // determine value colour if (highlitChanges) { QColor penClr = palette().color(QPalette::Text); if (hexData[address + j] != previousHexData[address + j]) { penClr = Qt::red; } if (((address + j) == hexMarkAddress ) && beingEdited && (cursorPosition == 0)) { penClr = Qt::white; } p.setPen(penClr); } p.drawText(x, y + a, QString(chr)); x += charWidth; } y += lineHeight; address += horBytes; if (address >= debuggableSize) break; } // copy the new values to the old-values buffer memcpy(previousHexData, hexData, debuggableSize); } void HexViewer::setDebuggable(const QString& name, int size) { delete[] hexData; hexData = NULL; delete[] previousHexData; previousHexData = NULL; if (size) { debuggableName = name; debuggableSize = size; addressLength = 2 * int(ceil(log(double(size)) / log(2.0) / 8)); hexTopAddress = 0; hexMarkAddress = 0; hexData = new unsigned char[size]; memset(hexData, 0, size); previousHexData = new unsigned char[size]; memset(previousHexData, 0, size); settingsChanged(); } else { debuggableName.clear(); debuggableSize = 0; } } void HexViewer::scrollBarChanged(int addr) { int start = addr * horBytes; if (start == hexTopAddress) { // nothing changed or a callback since we changed the value to // the current hexTopAddress return; } if (!useMarker) { setTopLocation(addr * horBytes); emit locationChanged(addr * horBytes); } else { //maybe marker is still "fully" visible? int size = horBytes * visibleLines; hexTopAddress = start; if ((start > hexMarkAddress) || ((start + size -1) < hexMarkAddress)) { hexMarkAddress = (hexMarkAddress % horBytes) + ((start < hexMarkAddress) ? size - horBytes : 0); hexMarkAddress += start; emit locationChanged(hexMarkAddress); } refresh(); } } void HexViewer::setLocation(int addr) { if (!useMarker) { setTopLocation(addr); } else { // check if newmarker is in fully visible lines, // if so we do not change hexTopAddress if (addr != hexMarkAddress) { emit locationChanged(addr); } hexMarkAddress = addr; int size = horBytes * visibleLines; if ((addr < hexTopAddress) || (addr >= (hexTopAddress+size))) { setTopLocation(addr); } refresh(); } } void HexViewer::setTopLocation(int addr) { if (debuggableName.isEmpty()) { return; } int start = horBytes * int(addr / horBytes); if (!waitingForData || (start != hexTopAddress)) { hexTopAddress = start; refresh(); } } void HexViewer::hexdataTransfered(HexRequest* r) { transferCancelled(r); update(); } void HexViewer::transferCancelled(HexRequest* r) { delete r; waitingForData = false; // check whether a new value is available if (int(hexTopAddress / horBytes) != vertScrollBar->value()) { vertScrollBar->setValue(hexTopAddress / horBytes); } } void HexViewer::refresh() { // calculate data request int size = horBytes * (visibleLines + partialBottomLine); size = std::min(size, debuggableSize - hexTopAddress); // send data request HexRequest* req = new HexRequest( debuggableName, hexTopAddress, size, hexData + hexTopAddress, *this); CommClient::instance().sendCommand(req); waitingForData = true; } void HexViewer::keyPressEvent(QKeyEvent* e) { // don't hanlde if not interactive if ((!beingEdited && !useMarker) || !isInteractive) { QFrame::keyPressEvent(e); return; } bool setValue = false; int newAddress = hexMarkAddress; // entering a new digit ? // for now hex only, do we need decimal entry also ?? if (!editedChars && ((e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9) || (e->key() >= Qt::Key_A && e->key() <= Qt::Key_F))) { // calculate numercial value int v = e->key() - Qt::Key_0; if (v > 9) v -= Qt::Key_A - Qt::Key_0 - 10; if (beingEdited) { editValue = (editValue << 4) + v; ++cursorPosition; if (cursorPosition == 2){ setValue = true; ++newAddress; } } else { editValue = v; beingEdited = true; cursorPosition = 1; } } else if (useMarker && e->key() == Qt::Key_Right) { setValue = beingEdited & !editedChars; ++newAddress; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Left) { setValue = beingEdited & !editedChars; --newAddress; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Up) { setValue = beingEdited & !editedChars; newAddress -= horBytes; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Down) { setValue = beingEdited & !editedChars; newAddress += horBytes; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Home) { setValue = beingEdited & !editedChars; newAddress = 0; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_PageUp) { setValue = beingEdited & !editedChars; hexTopAddress -= horBytes * visibleLines; newAddress -= horBytes * visibleLines; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_PageDown) { setValue = beingEdited & !editedChars; hexTopAddress += horBytes * visibleLines; newAddress += horBytes * visibleLines; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_End) { setValue = beingEdited & !editedChars; newAddress = debuggableSize - 1; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Backspace) { editedChars = !editedChars; } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { if (beingEdited) setValue = true; else cursorPosition = 0; if (editedChars) editValue = previousHexData[hexMarkAddress]; newAddress++; } else if (e->key() == Qt::Key_Shift || e->key() == Qt::Key_Control || e->key() == Qt::Key_Meta || e->key() == Qt::Key_Alt || e->key() == Qt::Key_AltGr || e->key() == Qt::Key_CapsLock || e->key() == Qt::Key_NumLock || e->key() == Qt::Key_ScrollLock) { // do nothing for these keys if editing chars // if not editing chars they do nothing by deafult :-) } else if (e->key() == Qt::Key_Escape) { beingEdited = false; e->accept(); update(); return; } else if (editedChars) { editValue = (e->text().toLatin1())[0]; setValue = true; ++newAddress; } else { QFrame::keyPressEvent(e); return; } //apply changes if (setValue) { //TODO actually write the values to openMSX memory //for now we change the value in our local buffer previousHexData[hexMarkAddress] = char(editValue); WriteDebugBlockCommand* req = new WriteDebugBlockCommand( debuggableName, hexMarkAddress, 1, previousHexData); CommClient::instance().sendCommand(req); editValue = 0; cursorPosition = 0; beingEdited = editedChars; // keep editing if we were inputing chars refresh(); } // indicate key Event handled e->accept(); // Move Marker if needed if ((editedChars || useMarker) && (hexMarkAddress != newAddress)) { if (newAddress < 0) newAddress += debuggableSize; if (newAddress >= debuggableSize) newAddress -= debuggableSize; // influencing hexTopAddress during Key_PageUp/Down might need following 2 lines. if (hexTopAddress < 0) hexTopAddress += debuggableSize; if (hexTopAddress >= debuggableSize) hexTopAddress -= debuggableSize; // Make scrolling downwards using cursors more "intuitive" int addr = hexTopAddress + horBytes * visibleLines; if ((newAddress >= addr) && (newAddress <= (addr + horBytes))) { hexTopAddress += horBytes; } if (useMarker) { setLocation(newAddress); } else { //we can only get here when not using Markers but if we //are typing in chars in charEdit mode, so scrolling //one line is covered in code above hexMarkAddress = newAddress; refresh(); } } else { update(); } } int HexViewer::coorToOffset(int x, int y) { int offset = -1; if (x >= xData && x < rightValuePos) { offset = 0; x -= xData; while (x > 4*dataWidth) { offset += 4; x -= 4*dataWidth + EXTRA_SPACING; if (offset % 8 == 0) x -= EXTRA_SPACING; } offset += x / dataWidth; } else if (x >= xChar && x < rightCharPos) { offset = (x - xChar) / charWidth; } int yMaxOffset = frameT + (visibleLines+partialBottomLine) * lineHeight; if (offset >= 0 && y < yMaxOffset) { offset += horBytes * ((y - frameT) / lineHeight); } return offset; } bool HexViewer::event(QEvent* e) { if (e->type() != QEvent::ToolTip) { return QWidget::event(e); } // calculate address for tooltip QHelpEvent* helpEvent = static_cast(e); int offset = coorToOffset(helpEvent->x(), helpEvent->y()); if (offset >= 0 && (hexTopAddress + offset) < debuggableSize) { // create text with binary and decimal values int address = hexTopAddress + offset; unsigned char chr = hexData[address]; QString text = QString("Address: %1").arg(address, addressLength, 16, QChar('0')); // print 8 bit values text += "\nBinary: "; text += QString("%1 ").arg(chr >> 4, 4, 2, QChar('0')); text += QString("%1") .arg(chr & 0x000F, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(chr); // print 16 bit values if possible if ((address + 1) < debuggableSize) { unsigned int wd = chr; wd += 256 * hexData[address + 1]; text += QString("\n\nWord: %1").arg(wd, 4, 16, QChar('0')); text += "\nBinary: "; text += QString("%1 ").arg((wd & 0xF000) >> 12, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x0F00) >> 8, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x00F0) >> 4, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x000F) >> 0, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(wd); } QToolTip::showText(helpEvent->globalPos(), text); } else { QToolTip::hideText(); } return QWidget::event(e); } void HexViewer::mousePressEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton && isInteractive) { int offset=coorToOffset(e->x(), e->y()); if (offset >= 0) { int addr = hexTopAddress + offset; if (useMarker && (hexMarkAddress != addr)) { setLocation(addr); } else { if (!useMarker) hexMarkAddress = addr; editValue = 0; cursorPosition = 0; beingEdited = isEditable; } editedChars = (e->x() >= xChar); } update(); } } void HexViewer::focusInEvent(QFocusEvent* e) { hasFocus = true; update(); } void HexViewer::focusOutEvent(QFocusEvent* e) { if (e->lostFocus()) { editValue = 0; cursorPosition = 0; beingEdited = false; hasFocus = false; } update(); } debugger-master/src/VDPCommandRegisters.ui0000644000175000017500000005057313560352104020446 0ustar shevekshevek VDPCmdRegs 0 0 489 659 Dialog 75 true New command Qt::Vertical 75 true Current registers R32 0x00 0x00 R33 0x00 R34 0x00 0x00 R35 0x00 R36 0x00 0x00 R37 0x00 R38 0x00 0x00 R39 0x00 R40 0x00 0x00 R41 0x00 R42 0x00 0x00 R43 0x00 COLOR R44 0x00 ARG R45 0x00 CMD explained SX SY DX DY NY NX Direction from source: 0: Down 1: Up DIY 50 false Direction from source: 0: RIght 1: Left DIX When 1, ends execution when border color found. When 0, ends execution when a color other than the border color is found. EQ Direction for long side 0: Long side is in x-axis 1: Long side is in y-axis MAJ Select source memory 0: Video RAM 1: Expansion RAM MXS Select destination memory 0: Video RAM 1: Expansion RAM MXD Select memory 0: Video RAM 1: Expansion RAM MXC CMD R46 0: Stop 1: Invalid 2: Invalid 3: Invalid 4: POINT 5: PSET 6: SRCH 7: LINE 8: LMMV 9: LMMM A: LMCM B: LMMC C: HMMV D: HMMM E: YMMM F: HMMC INP AND OR EOR NOT --- --- --- TIMP TAND TOR TEOR TNOT --- --- --- 0x00 00000000 0000 0000 CMD explained Sync regs to new cmd Auto sync true Launch command Qt::Horizontal 138 24 debugger-master/src/HexViewer.h0000644000175000017500000000376513560352104016347 0ustar shevekshevek#ifndef HEXVIEWER_H #define HEXVIEWER_H #include class HexRequest; class QScrollBar; class QPaintEvent; class HexViewer : public QFrame { Q_OBJECT public: HexViewer(QWidget* parent = 0); ~HexViewer(); enum Mode { FIXED, FILL_WIDTH, FILL_WIDTH_POWEROF2 }; void setDebuggable(const QString& name, int size); void setIsInteractive(bool enabled); void setUseMarker(bool enabled); void setIsEditable(bool enabled); void setDisplayMode(Mode mode); void setDisplayWidth(short width); QSize sizeHint() const; public slots: void setLocation(int addr); void setTopLocation(int addr); void scrollBarChanged(int addr); void settingsChanged(); void refresh(); private: void wheelEvent(QWheelEvent* e); void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void mousePressEvent(QMouseEvent* e); bool event(QEvent* e); void keyPressEvent(QKeyEvent* e); void focusInEvent(QFocusEvent* e); void focusOutEvent(QFocusEvent* e); void createActions(); void setSizes(); void hexdataTransfered(HexRequest* r); void transferCancelled(HexRequest* r); int coorToOffset(int x, int y); QScrollBar* vertScrollBar; QAction *fillWidthAction; QAction *fillWidth2Action; QAction *setWith8Action; QAction *setWith16Action; QAction *setWith32Action; // layout int frameL, frameR, frameT, frameB; int leftCharPos, leftValuePos, rightValuePos, rightCharPos; Mode displayMode; short horBytes; int visibleLines, partialBottomLine; int lineHeight, xAddr, xData, xChar, dataWidth, charWidth, hexCharWidth; int addressLength; // data QString debuggableName; int debuggableSize; int hexTopAddress; int hexMarkAddress; unsigned char* hexData; unsigned char* previousHexData; bool waitingForData; bool highlitChanges; bool useMarker; bool isInteractive; bool isEditable; bool beingEdited; bool editedChars; bool hasFocus; int cursorPosition,editValue; friend class HexRequest; private slots: void changeWidth(); signals: void locationChanged(int addr); }; #endif // HEXVIEWER_H debugger-master/src/CPURegsViewer.cpp0000644000175000017500000002720013560352104017414 0ustar shevekshevek#include "CPURegsViewer.h" #include "CPURegs.h" #include "CommClient.h" #include "OpenMSXConnection.h" #include #include #include #include CPURegsViewer::CPURegsViewer(QWidget* parent) : QFrame(parent) { // avoid UMR memset(®s, 0, sizeof(regs)); memset(®sChanged, 0, sizeof(regsChanged)); memset(®sModified, 0, sizeof(regsModified)); setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed)); frameR = frameL = frameT = frameB = frameWidth(); cursorLoc = -1; } void CPURegsViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void CPURegsViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); p.setPen(palette().color(QPalette::Text)); rowHeight = fontMetrics().height(); int regWidth = fontMetrics().width("HLW"); int valWidth = fontMetrics().width("FFFFWW"); int d = fontMetrics().descent(); leftRegPos = frameL + 4; leftValuePos = leftRegPos + regWidth; rightRegPos = leftValuePos + valWidth; rightValuePos = rightRegPos + regWidth; // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > (width() - frameR - 1)) r.setRight (width() - frameR - 1); if (r.bottom() > (height() - frameB - 1)) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int y = frameT + rowHeight - 1 - d; for (int r = 0; r < 14; r += 2) { p.drawText(leftRegPos, y, CpuRegs::regNames[r + 0]); drawValue(p, r + 0, leftValuePos, y); p.drawText(rightRegPos, y, CpuRegs::regNames[r + 1]); drawValue(p, r + 1, rightValuePos, y); y += rowHeight; } // draw interrupt mode p.drawText(leftRegPos, y, "IM"); drawValue(p, 14, leftValuePos, y); // draw interrupt state if (regsChanged[CpuRegs::REG_IFF] & 1) { p.setPen(Qt::red); } p.drawText(rightRegPos, y, regs[CpuRegs::REG_IFF] ? "EI" : "DI"); } QSize CPURegsViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("HLWFFFFWWHLWFFFFW") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB ); } void CPURegsViewer::drawValue(QPainter& p, int id, int x, int y) { // determine value colour QColor penClr = palette().color(QPalette::Text); if (regsModified[id]) { penClr = Qt::darkGreen; } else if (regsChanged[id]) { penClr = Qt::red; } // print (edit) value if ((cursorLoc >> 2) == id) { // cursor is in this value, print separate digits int digit = 3; if (id < CpuRegs::REG_I) { digit = 0; } else if (id < CpuRegs::REG_IM) { digit = 2; } // write all digit for (/**/; digit < 4; ++digit) { // create string with a single digit QString digitTxt = QString("%1") .arg((regs[id] >> (4 * (3 - digit))) & 15, 0, 16) .toUpper(); // if digit has cursor, draw as cursor if ((cursorLoc & 3) == digit) { // draw curser background QBrush b(palette().color(QPalette::Highlight)); p.fillRect(x, frameT + (cursorLoc >> 3) * rowHeight, fontMetrics().width(digitTxt), rowHeight, b); p.setPen(palette().color(QPalette::HighlightedText)); } else { p.setPen(penClr); } p.drawText(x, y, digitTxt); x += fontMetrics().width(digitTxt); } } else { // regular value print p.setPen(penClr); // create string QString str; if (id < CpuRegs::REG_I) { str.sprintf("%04X", regs[id]); } else if (id < CpuRegs::REG_IM) { str.sprintf("%02X", regs[id]); } else { str.sprintf("%01X", regs[id]); } // draw p.drawText(x, y, str); } // reset pen p.setPen(palette().color(QPalette::Text)); } void CPURegsViewer::setRegister(int id, int value) { regsChanged[id] = regs[id] != value; regs[id] = value; if (regsChanged[id]) { emit registerChanged(id, value); } } void CPURegsViewer::setData(unsigned char* datPtr) { setRegister(CpuRegs::REG_AF , datPtr[ 0] * 256 + datPtr[ 1]); setRegister(CpuRegs::REG_BC , datPtr[ 2] * 256 + datPtr[ 3]); setRegister(CpuRegs::REG_DE , datPtr[ 4] * 256 + datPtr[ 5]); setRegister(CpuRegs::REG_HL , datPtr[ 6] * 256 + datPtr[ 7]); setRegister(CpuRegs::REG_AF2, datPtr[ 8] * 256 + datPtr[ 9]); setRegister(CpuRegs::REG_BC2, datPtr[10] * 256 + datPtr[11]); setRegister(CpuRegs::REG_DE2, datPtr[12] * 256 + datPtr[13]); setRegister(CpuRegs::REG_HL2, datPtr[14] * 256 + datPtr[15]); setRegister(CpuRegs::REG_IX , datPtr[16] * 256 + datPtr[17]); setRegister(CpuRegs::REG_IY , datPtr[18] * 256 + datPtr[19]); setRegister(CpuRegs::REG_PC , datPtr[20] * 256 + datPtr[21]); setRegister(CpuRegs::REG_SP , datPtr[22] * 256 + datPtr[23]); setRegister(CpuRegs::REG_I , datPtr[24]); setRegister(CpuRegs::REG_R , datPtr[25]); setRegister(CpuRegs::REG_IM , datPtr[26]); // IFF separately to only check bit 0 for change regsChanged[CpuRegs::REG_IFF] = (regs[CpuRegs::REG_IFF] & 1) != (datPtr[27] & 1); regs[CpuRegs::REG_IFF] = datPtr[27]; // reset modifications cursorLoc = -1; memset(®sModified, 0, sizeof(regsModified)); memcpy(®sCopy, ®s, sizeof(regs)); update(); emit pcChanged(regs[CpuRegs::REG_PC]); emit spChanged(regs[CpuRegs::REG_SP]); emit flagsChanged(regs[CpuRegs::REG_AF] & 0xFF); } void CPURegsViewer::focusOutEvent(QFocusEvent* e) { if (e->lostFocus()) { cancelModifications(); cursorLoc = -1; update(); } } void CPURegsViewer::mousePressEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton) { int pos = -1; if (e->x() >= leftValuePos && e->x() < rightRegPos) { pos = 0; } if (e->x() >= rightValuePos) { pos = 4; } if (pos >= 0 && e->y() < frameT + 7 * rowHeight) { int row = (e->y() - frameT) / rowHeight; cursorLoc = pos + 8 * row; if (row == 6) cursorLoc += 2; } update(); } } void CPURegsViewer::keyPressEvent(QKeyEvent* e) { // don't accept when not editting if (cursorLoc < 0) { QFrame::keyPressEvent(e); return; } int move = e->key(); if ((e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9) || (e->key() >= Qt::Key_A && e->key() <= Qt::Key_F) ) { // calculate numercial value int v = e->key() - Qt::Key_0; if (v > 9) v -= Qt::Key_A - Qt::Key_0 - 10; // modify value int id = cursorLoc >> 2; int digit = cursorLoc & 3; regs[id] &= ~(0xF000 >> (4 * digit)); regs[id] |= v << (12 - 4 * digit); regsModified[id] = true; move = Qt::Key_Right; } if (move == Qt::Key_Right) { ++cursorLoc; if (cursorLoc == 4 * CpuRegs::REG_I || cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc += 2; } else if (cursorLoc == 4 * CpuRegs::REG_IM) { cursorLoc = 0; } } else if (move == Qt::Key_Left) { --cursorLoc; if (cursorLoc == -1) { cursorLoc = 4 * CpuRegs::REG_R + 3; } else if (cursorLoc == 4 * CpuRegs::REG_R + 1 || cursorLoc == 4 * CpuRegs::REG_I + 1) { cursorLoc -= 2; } } else if (move == Qt::Key_Up) { cursorLoc -= 8; if (cursorLoc < 0) { cursorLoc += 4 * CpuRegs::REG_IM; // move to lowest row if (cursorLoc == 4 * CpuRegs::REG_I) { cursorLoc = 4 * CpuRegs::REG_I + 2; } else if (cursorLoc < 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_I + 3; } else if (cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_R + 2; } else { cursorLoc = 4 * CpuRegs::REG_R + 3; } } else if (cursorLoc >= 4 * CpuRegs::REG_PC) { // move from lowest row cursorLoc -= 2; } } else if (move == Qt::Key_Down) { cursorLoc += 8; if (cursorLoc >= 4 * CpuRegs::REG_IM) { // move from lowest row cursorLoc -= 4 * CpuRegs::REG_IM + 2; } else if (cursorLoc >= 4 * CpuRegs::REG_I) { // move to lowest row if (cursorLoc == 4 * CpuRegs::REG_I) { cursorLoc = 4 * CpuRegs::REG_I + 2; } else if (cursorLoc < 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_I + 3; } else if( cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_R + 2; } else { cursorLoc = 4 * CpuRegs::REG_R + 3; } } } else if (move == Qt::Key_Escape) { // cancel changes cancelModifications(); cursorLoc = -1; } else if (move == Qt::Key_Return || move == Qt::Key_Enter) { // apply changes applyModifications(); } else { QFrame::keyPressEvent(e); return; } e->accept(); update(); } //void CPURegsViewer::mouseMoveEvent(QMouseEvent* e) //{ // QToolTip::hideText(); // QFrame::mouseMoveEvent(e); //} int CPURegsViewer::readRegister(int id) { return regs[id]; } void CPURegsViewer::getRegister(int id, unsigned char* data) { data[0] = regs[id] >> 8; data[1] = regs[id] & 255; } void CPURegsViewer::applyModifications() { unsigned char data[26]; getRegister(CpuRegs::REG_AF, &data[ 0]); getRegister(CpuRegs::REG_BC, &data[ 2]); getRegister(CpuRegs::REG_DE, &data[ 4]); getRegister(CpuRegs::REG_HL, &data[ 6]); getRegister(CpuRegs::REG_AF2, &data[ 8]); getRegister(CpuRegs::REG_BC2, &data[10]); getRegister(CpuRegs::REG_DE2, &data[12]); getRegister(CpuRegs::REG_HL2, &data[14]); getRegister(CpuRegs::REG_IX, &data[16]); getRegister(CpuRegs::REG_IY, &data[18]); getRegister(CpuRegs::REG_PC, &data[20]); getRegister(CpuRegs::REG_SP, &data[22]); data[24] = regs[CpuRegs::REG_I]; data[25] = regs[CpuRegs::REG_R]; // send new data to openmsx WriteDebugBlockCommand* req = new WriteDebugBlockCommand( "{CPU regs}", 0, 26, data); CommClient::instance().sendCommand(req); // turn off editing cursorLoc = -1; // update copy for (int i = 0; i < 14; ++i) { if (regsModified[i]) { regsModified[i] = false; regsCopy[i] = regs[i]; regsChanged[i] = true; } } // update screen update(); } void CPURegsViewer::cancelModifications() { bool mod = false; for (int i = 0; i < 14; ++i) mod |= regsModified[i]; if (!mod) return; int ret = QMessageBox::warning( this, tr("CPU registers changes"), tr("You made changes to the CPU registers.\n" "Do you want to apply your changes or ignore them?"), QMessageBox::Apply | QMessageBox::Ignore, QMessageBox::Ignore); if (ret == QMessageBox::Ignore) { memcpy(®s, ®sCopy, sizeof(regs)); memset(®sModified, 0, sizeof(regsModified)); } else { applyModifications(); } } bool CPURegsViewer::event(QEvent* e) { if (e->type() != QEvent::ToolTip) { return QWidget::event(e); } QHelpEvent* helpEvent = static_cast(e); // calc register number int pos = -1; if (helpEvent->x() >= leftValuePos && helpEvent->x() < rightRegPos) { pos = 0; } if (helpEvent->x() >= rightValuePos) { pos = 1; } if (pos >= 0 && helpEvent->y() < frameT + 7 * rowHeight) { pos += 2 * ((helpEvent->y() - frameT) / rowHeight); } if (pos >= 0 && pos != 10 && pos != 11) { // create text with binary and decimal values QString text(CpuRegs::regNames[pos]); text += "\nBinary: "; if (pos < 12) { text += QString("%1 ") .arg((regs[pos] & 0xF000) >> 12, 4, 2, QChar('0')); text += QString("%1 ") .arg((regs[pos] & 0x0F00) >> 8, 4, 2, QChar('0')); } text += " "; text += QString("%1 ").arg((regs[pos] & 0x00F0) >> 4, 4, 2, QChar('0')); text += QString("%1") .arg((regs[pos] & 0x000F) >> 0, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(regs[pos]); // print 8 bit values if (pos < 8) { text += QString("\n%1: %2 %3: %4") .arg(CpuRegs::regNames[pos][0]) .arg(regs[pos] >> 8) .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] & 255); } else if (pos < 10) { text += QString("\nI%1H: %2 I%3L: %4") .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] >> 8) .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] & 255); } QToolTip::showText(helpEvent->globalPos(), text); } else { QToolTip::hideText(); } return QWidget::event(e); } debugger-master/src/DockableWidget.cpp0000644000175000017500000001345613560352104017642 0ustar shevekshevek#include "DockableWidget.h" #include "DockManager.h" #include #include #include #include #include #include #include #include #include #include DockableWidget::DockableWidget( DockManager& manager, QWidget* parent) : QWidget(parent), dockManager(manager) { mainWidget = 0; floating = false; movable = true; closable = true; destroyable = true; dragging = false; setAttribute(Qt::WA_DeleteOnClose, true); titleLabel = new QLabel(); closeButton = new QToolButton(); closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); closeButton->setToolButtonStyle(Qt::ToolButtonIconOnly); int sz = style()->pixelMetric(QStyle::PM_SmallIconSize); closeButton->setIconSize(style()->standardIcon( QStyle::SP_TitleBarCloseButton).actualSize(QSize(sz, sz))); closeButton->setAutoRaise(true); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); headerLayout = new QHBoxLayout(); headerLayout->setMargin(0); headerLayout->addWidget(titleLabel, 1); headerLayout->addWidget(closeButton, 0); headerWidget = new QWidget(); headerWidget->setLayout(headerLayout); widgetLayout = new QVBoxLayout(); widgetLayout->setMargin(3); widgetLayout->setSpacing(1); widgetLayout->addWidget(headerWidget); setLayout(widgetLayout); dockManager.attachWidget(this); rubberBand = new QRubberBand(QRubberBand::Rectangle); } DockableWidget::~DockableWidget() { delete mainWidget; delete rubberBand; dockManager.detachWidget(this); } QWidget* DockableWidget::widget() const { return mainWidget; } void DockableWidget::setWidget(QWidget* widget) { if (mainWidget) { widgetLayout->removeWidget(mainWidget); } mainWidget = widget; if (widget) { widgetLayout->addWidget(widget, 1); int minW = sizeHint().width() - widget->sizeHint().width() + widget->minimumWidth(); int minH = sizeHint().height() - widget->sizeHint().height() + widget->minimumHeight(); int maxW = sizeHint().width() - widget->sizeHint().width() + widget->maximumWidth(); int maxH = sizeHint().height() - widget->sizeHint().height() + widget->maximumHeight(); maxW = std::min(maxW, QWIDGETSIZE_MAX); maxH = std::min(maxH, QWIDGETSIZE_MAX); setMinimumSize(minW, minH); setMaximumSize(maxW, maxH); setSizePolicy(widget->sizePolicy()); } } const QString& DockableWidget::id() const { return widgetId; } void DockableWidget::setId(const QString& str) { widgetId = str; } QString DockableWidget::title() const { return windowTitle(); } void DockableWidget::setTitle(const QString& title) { setWindowTitle(title); titleLabel->setText(title + ':'); } bool DockableWidget::isFloating() const { return floating; } void DockableWidget::setFloating(bool enable, bool showNow) { if (floating == enable) return; floating = enable; setWindowFlags(floating ? Qt::Tool : Qt::Widget); if (floating && showNow) { show(); } } bool DockableWidget::isMovable() const { return movable; } void DockableWidget::setMovable(bool enable) { movable = enable; } bool DockableWidget::isClosable() const { return closable; } void DockableWidget::setClosable(bool enable) { if (closable == enable) return; closable = enable; if (enable) { closeButton->show(); } else { closeButton->hide(); } dragging = false; rubberBand->hide(); } bool DockableWidget::isDestroyable() const { return destroyable; } void DockableWidget::setDestroyable(bool enable) { destroyable = enable; setAttribute(Qt::WA_DeleteOnClose, enable); } void DockableWidget::closeEvent(QCloseEvent* event) { if (closable || destroyable) { if (destroyable && floating) { dockManager.undockWidget(this); event->accept(); } else { hide(); event->ignore(); emit visibilityChanged(this); } } else { event->ignore(); } } void DockableWidget::mousePressEvent(QMouseEvent* event) { if (movable && event->button() == Qt::LeftButton) { dragging = true; dragStart = event->globalPos(); dragOffset = event->pos(); } } void DockableWidget::mouseMoveEvent(QMouseEvent* event) { if (!dragging) return; if (event->buttons() & Qt::LeftButton) { // dragging of widget in progress, update rubberband if (!rubberBand->isVisible()) { if (abs(event->globalX() - dragStart.x()) > 20 || abs(event->globalY() - dragStart.y()) > 20 ) { rubberBand->resize(width(), height()); rubberBand->move(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y()); rubberBand->show(); } } else { QRect r(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y(), width(), height()); if (floating && dockManager.insertLocation(r, sizePolicy())) { rubberBand->move(r.x(), r.y()); rubberBand->resize(r.width(), r.height()); } else { rubberBand->move(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y()); rubberBand->resize(width(), height()); } } } else { dragging = false; rubberBand->hide(); } } void DockableWidget::mouseReleaseEvent(QMouseEvent* event) { if (!dragging) return; dragging = false; rubberBand->hide(); // only do anything if this was a meaningful drag if (!movable || (abs(event->globalX() - dragStart.x()) <= 20 && abs(event->globalY() - dragStart.y()) <= 20)) { return; } if (floating) { QRect mouseRect(event->globalX() - dragOffset.x(), event->globalY() - dragOffset.y(), width(), height()); QRect r(mouseRect); if (dockManager.insertLocation(r, sizePolicy())) { setFloating(false); dockManager.dockWidget(this, QPoint(), mouseRect); } else { move(event->globalPos() - dragOffset); } } else { dockManager.undockWidget(this); setFloating(true); move(event->globalPos() - dragOffset); } } debugger-master/src/InteractiveLabel.cpp0000644000175000017500000000150113560352104020173 0ustar shevekshevek#include "InteractiveLabel.h" #include #include InteractiveLabel::InteractiveLabel(QWidget *parent) : QLabel(parent) { setEnabled(true); setAutoFillBackground(true); } void InteractiveLabel::highlight(bool state) { // I first tried with style sheets, but then I found in the // documentation that Qt style sheets are currently not supported for // QMacStyle (the default style on Mac OS X). // So I use a QPalette for now. if (state) { QPalette fiddle = QApplication::palette(); fiddle.setColor(QPalette::Active, QPalette::Window, Qt::yellow); setPalette(fiddle); } else { setPalette(QApplication::palette()); } update(); } void InteractiveLabel::enterEvent(QEvent* event) { emit mouseOver(true); } void InteractiveLabel::leaveEvent(QEvent* event) { emit mouseOver(false); } debugger-master/src/SlotViewer.h0000644000175000017500000000114613560352104016533 0ustar shevekshevek#ifndef SLOTVIEWER_H #define SLOTVIEWER_H #include struct MemoryLayout; class QString; class SlotViewer : public QFrame { Q_OBJECT; public: SlotViewer(QWidget* parent = 0); void refresh(); void setMemoryLayout(MemoryLayout* ml); void slotsUpdated(const QString& message); QSize sizeHint() const; private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); int frameL, frameR, frameT, frameB; int headerSize1, headerSize2, headerSize3, headerSize4; int headerHeight; MemoryLayout* memLayout; bool slotsChanged[4]; bool segmentsChanged[4]; }; #endif // SLOTVIEWER_H debugger-master/src/CPURegs.cpp0000644000175000017500000000124513560352104016233 0ustar shevekshevek#include "CPURegs.h" const int CpuRegs::REG_AF = 0; const int CpuRegs::REG_AF2 = 1; const int CpuRegs::REG_BC = 2; const int CpuRegs::REG_BC2 = 3; const int CpuRegs::REG_DE = 4; const int CpuRegs::REG_DE2 = 5; const int CpuRegs::REG_HL = 6; const int CpuRegs::REG_HL2 = 7; const int CpuRegs::REG_IX = 8; const int CpuRegs::REG_IY = 9; const int CpuRegs::REG_PC = 10; const int CpuRegs::REG_SP = 11; const int CpuRegs::REG_I = 12; const int CpuRegs::REG_R = 13; const int CpuRegs::REG_IM = 14; const int CpuRegs::REG_IFF = 15; const char* const CpuRegs::regNames[14] = { "AF", "AF'", "BC", "BC'", "DE", "DE'", "HL", "HL'", "IX", "IY", "PC", "SP", "I", "R" }; debugger-master/src/ConnectDialog.h0000644000175000017500000000275513560352104017150 0ustar shevekshevek#ifndef CONNECTDIALOG_HH #define CONNECTDIALOG_HH #include "OpenMSXConnection.h" #include "ui_ConnectDialog.h" #include #include class QString; class ConnectionInfoRequest; class ConnectDialog : public QDialog { Q_OBJECT public: static OpenMSXConnection* getConnection(QWidget* parent = 0); private slots: void on_connectButton_clicked(); void on_rescanButton_clicked(); private: ConnectDialog(QWidget* parent); ~ConnectDialog(); void clear(); void connectionOk(OpenMSXConnection& connection, const QString& title); void connectionBad(OpenMSXConnection& connection); void timerEvent(QTimerEvent *event); int delay; Ui::ConnectDialog ui; typedef QList OpenMSXConnections; OpenMSXConnections pendingConnections; OpenMSXConnections confirmedConnections; OpenMSXConnection* result; QList connectionInfos; friend class ConnectionInfoRequest; }; // Command handler to get initial info from new openmsx connections class ConnectionInfoRequest : public QObject, Command { Q_OBJECT public: ConnectionInfoRequest(ConnectDialog& dialog, OpenMSXConnection& connection); virtual QString getCommand() const; virtual void replyOk (const QString& message); virtual void replyNok(const QString& message); virtual void cancel(); private: enum State { GET_MACHINE, GET_TITLE, DONE }; ConnectDialog& dialog; OpenMSXConnection& connection; State state; QString title; private slots: void terminate(); }; #endif debugger-master/src/SymbolManager.ui0000644000175000017500000004740213560352104017363 0ustar shevekshevek SymbolManager 0 0 760 577 Symbol Manager false true 0 Symbol files Loaded symbol files: QAbstractItemView::ExtendedSelection false false true File Last refresh Add Remove Qt::Vertical 20 40 Address labels Address labels: Add Remove Qt::Vertical 20 40 QAbstractItemView::ExtendedSelection false true false true true Symbol Type Value Slots Segments Registers Source 0 0 0 Locations 0 0 Active slots 0-0 0-1 0-2 0-3 1-0 1-1 1-2 1-3 2-0 2-1 2-2 2-3 3-0 3-1 3-2 3-3 0 0 Active segments 0 0 Usage Symbol type Jump label Variable label Value 8 bit registers 16 A I Offset value B C D E IXH IXL H L IYH IYL 16 bit registers BC DE HL IX IY Qt::Horizontal 40 20 Reload all Close btnClose clicked() SymbolManager close() 571 420 233 29 debugger-master/src/VDPRegViewer.cpp0000644000175000017500000010016113560352104017231 0ustar shevekshevek#include "VDPRegViewer.h" #include "VDPDataStore.h" #include "InteractiveButton.h" #include "CommClient.h" static const int VDP_TMS99X8 = 1; static const int VDP_V9938 = 0; static const int VDP_V9958 = 4; // class buttonHighlightDispatcher buttonHighlightDispatcher::buttonHighlightDispatcher() : counter(0) { } void buttonHighlightDispatcher::receiveState(bool state) { if (state) { if (counter == 0) { emit dispatchState(true); } ++counter; } else { --counter; if (counter == 0) { emit dispatchState(false); } } } // class VDPRegViewer VDPRegViewer::VDPRegViewer(QWidget *parent) : QDialog(parent) { setupUi(this); regs = new unsigned char[64 + 16 + 2]; vdpid = 99; // make sure that we parse the first time the status registers are read vdpid = VDP_V9958; //quick hack for now //now hook up some signals and slots connectHighLights(); //get initiale data refresh(); decodeStatusVDPRegs(); // part of the quick hack :-) } VDPRegViewer::~VDPRegViewer() { delete[] regs; } void VDPRegViewer::setRegisterVisible(int r, bool visible) { QString name1 = QString("label_R%1").arg(r); QLabel* l1 = findChild(name1); l1->setVisible(visible); QString name2 = QString("label_val_%1").arg(r); QLabel* l2 = findChild(name2); l2->setVisible(visible); for (int b = 7; b >= 0; --b) { QString name3 = QString("pushButton_%1_%2").arg(r).arg(b); InteractiveButton *i = findChild(name3); i->setVisible(visible); } // now hide/show the explications of the give register switch (r) { case 8: label_dec_tp->setVisible(visible); label_dec_spd->setVisible(visible); break; case 9: label_dec_nt->setVisible(visible); label_dec_nt2->setVisible(visible); label_dec_il->setVisible(visible); label_dec_eo->setVisible(visible); label_dec_ln->setVisible(visible); label_dec_ln2->setVisible(visible); break; case 12: label_t2->setVisible(visible); label_bc->setVisible(visible); label_dec_t2->setVisible(visible); label_dec_bc->setVisible(visible); break; case 13: label_on->setVisible(visible); label_off->setVisible(visible); label_dec_on->setVisible(visible); label_dec_off->setVisible(visible); break; } } void VDPRegViewer::decodeStatusVDPRegs() { //const unsigned char* statusregs = regs + 64; //int id = statusregs[1] & 62; // + (machine_has_TMS99x8 ? 1 : 0) // test MSX1 id = 1; //if (vdpid != id) { // vdpid = id; if (vdpid == VDP_TMS99X8) { // TMS9918 = MSX1 VDP groupBox_V9958->setVisible(false); groupBox_TableBase->setVisible(true); groupBox_Color->setVisible(true); groupBox_Display->setVisible(false); groupBox_Access->setVisible(false); groupBox_dec_V9958->setVisible(false); groupBox_dec_TableBase->setVisible(true); groupBox_dec_Color->setVisible(true); groupBox_dec_Display->setVisible(false); groupBox_dec_Access->setVisible(false); label_dec_416K->setVisible(true); label_dec_ie1->setVisible(false); label_dec_ie2->setVisible(false); label_dec_dg->setVisible(false); setRegisterVisible( 8, false); setRegisterVisible( 9, false); setRegisterVisible(10, false); setRegisterVisible(11, false); setRegisterVisible(12, false); setRegisterVisible(13, false); setRegisterVisible(20, false); setRegisterVisible(21, false); setRegisterVisible(22, false); pushButton_0_2->setText("0"); pushButton_0_2->setToolTip(""); pushButton_0_3->setText("0"); pushButton_0_3->setToolTip(""); pushButton_0_4->setText("0"); pushButton_0_4->setToolTip(""); pushButton_0_5->setText("0"); pushButton_0_5->setToolTip(""); pushButton_0_6->setText("0"); pushButton_0_6->setToolTip(""); pushButton_1_7->setText("4/16"); pushButton_1_7->setToolTip( "4/16K selection\n" "0 selects 4027 RAM operation\n" "1 selects 4108/4116 RAM operation"); // mask all A16 bits of regs < 7 pushButton_2_6->setText("0"); pushButton_4_5->setText("0"); pushButton_6_5->setText("0"); // mask all A15 pushButton_2_5->setText("0"); pushButton_4_4->setText("0"); pushButton_6_4->setText("0"); // mask all A14 bits of regs < 7 pushButton_2_4->setText("0"); pushButton_4_3->setText("0"); pushButton_6_3->setText("0"); disconnect(modeBitsDispat, 0, pushButton_0_2, 0); disconnect(modeBitsDispat, 0, pushButton_0_3, 0); disconnect(pushButton_0_2, 0, 0, 0); disconnect(pushButton_0_3, 0, 0, 0); disconnect(pushButton_0_4, 0, 0, 0); disconnect(pushButton_0_5, 0, 0, 0); disconnect(pushButton_0_6, 0, 0, 0); monoGroup(pushButton_1_7, label_dec_416K); } else { // V9938 = MSX2 VDP // or // V9958 = MSX2+ VDP groupBox_TableBase->setVisible(true); groupBox_Color->setVisible(true); groupBox_Display->setVisible(true); groupBox_Access->setVisible(true); groupBox_dec_TableBase->setVisible(true); groupBox_dec_Color->setVisible(true); groupBox_dec_Display->setVisible(true); groupBox_dec_Access->setVisible(true); label_dec_416K->setVisible(false); label_dec_ie1->setVisible(true); label_dec_dg->setVisible(true); setRegisterVisible( 8, true); setRegisterVisible( 9, true); setRegisterVisible(10, true); setRegisterVisible(11, true); setRegisterVisible(12, true); setRegisterVisible(13, true); setRegisterVisible(20, true); setRegisterVisible(21, true); setRegisterVisible(22, true); pushButton_0_2->setText("M4"); pushButton_0_3->setText("M5"); pushButton_0_4->setText("IE1"); pushButton_0_6->setText("DG"); pushButton_1_7->setText("0"); pushButton_0_2->setToolTip("Used to change the display mode."); pushButton_0_3->setToolTip("Used to change the display mode."); pushButton_0_4->setToolTip("Enables interrupt from Horizontal scanning line by Interrupt Enable 1."); pushButton_0_6->setToolTip("Sets the color bus to input mode, and inputs data into the VRAM."); pushButton_1_7->setToolTip(""); // all A16 bits of regs < 7 pushButton_4_5->setText("A16"); pushButton_6_5->setText("A16"); // all A15 pushButton_4_4->setText("A15"); pushButton_6_4->setText("A15"); // all A14 pushButton_4_3->setText("A14"); pushButton_6_3->setText("A14"); ////pushButton_0_5->setText("IE2"); ////disconnect(pushButton_0_7, 0, 0, 0); ////disconnect(label_dec_416K, 0, 0, 0); ////reGroup(pushButton_0_2, modeBitsDispat); ////reGroup(pushButton_0_3, modeBitsDispat); ////monoGroup(pushButton_0_4, label_dec_ie1); ////monoGroup(pushButton_0_5, label_dec_ie2); ////monoGroup(pushButton_0_6, label_dec_dg); //break; // V9958 = MSX2+ VDP ////groupBox_TableBase->setVisible(true); ////groupBox_Color->setVisible(true); ////groupBox_Display->setVisible(true); ////groupBox_Access->setVisible(true); ////groupBox_dec_TableBase->setVisible(true); ////groupBox_dec_Color->setVisible(true); ////groupBox_dec_Display->setVisible(true); ////groupBox_dec_Access->setVisible(true); ////label_dec_416K->setVisible(false); ////label_dec_ie1->setVisible(true); ////label_dec_dg->setVisible(true); ////setRegisterVisible( 8, true); ////setRegisterVisible( 9, true); ////setRegisterVisible(10, true); ////setRegisterVisible(11, true); ////setRegisterVisible(12, true); ////setRegisterVisible(13, true); ////setRegisterVisible(20, true); ////setRegisterVisible(21, true); ////setRegisterVisible(22, true); ////pushButton_0_2->setText("M4"); ////pushButton_0_3->setText("M5"); ////pushButton_0_4->setText("IE1"); ////pushButton_0_6->setText("DG"); ////pushButton_1_7->setText("0"); ////pushButton_0_2->setToolTip("Used to change the display mode."); ////pushButton_0_3->setToolTip("Used to change the display mode."); ////pushButton_0_4->setToolTip("Enables interrupt from Horizontal scanning line by Interrupt Enable 1."); ////pushButton_0_6->setToolTip("Sets the color bus to input mode, and inputs data into the VRAM."); ////pushButton_1_7->setToolTip(""); pushButton_1_7->setToolTip(""); disconnect(pushButton_0_7, 0, 0, 0); disconnect(label_dec_416K, 0, 0, 0); reGroup(pushButton_0_2, modeBitsDispat); reGroup(pushButton_0_3, modeBitsDispat); monoGroup(pushButton_0_4, label_dec_ie1); monoGroup(pushButton_0_5, label_dec_ie2); monoGroup(pushButton_0_6, label_dec_dg); if (vdpid == VDP_V9938){ groupBox_V9958->setVisible(false); groupBox_dec_V9958->setVisible(false); label_dec_ie2->setVisible(true); pushButton_0_5->setText("IE2"); pushButton_0_5->setToolTip("Enables interrupt from Lightpen by Interrupt Enable 2."); pushButton_8_6->setText("LP"); pushButton_8_6->setToolTip(""); pushButton_8_7->setText("MS"); pushButton_8_7->setToolTip(""); } else { groupBox_V9958->setVisible(true); groupBox_dec_V9958->setVisible(true); label_dec_ie2->setVisible(false); pushButton_0_5->setText("0"); pushButton_0_5->setToolTip(""); pushButton_8_7->setText("0"); pushButton_8_7->setToolTip(""); pushButton_8_6->setText("0"); pushButton_8_6->setToolTip(""); /* Since mouse/lightpen are disabled this will affect * status reg1 bit 7 (LPS) and * status reg1 bit 6 (FL) */ } //break; } //} } static QString dec2(int val) { return QString("%1").arg(val, 2, 10, QChar('0')); } static QString dec3(int val) { return QString("%1").arg(val, 3, 10, QChar('0')); } static QString hex2(int val) { return QString("%1").arg(val, 2, 16, QChar('0')).toUpper(); } static QString hex5(int val) { return QString("%1").arg(val, 5, 16, QChar('0')).toUpper(); } void VDPRegViewer::decodeVDPRegs() { // first update all hex values label_val_0->setText(hex2(regs[0])); label_val_1->setText(hex2(regs[1])); label_val_2->setText(hex2(regs[2])); label_val_3->setText(hex2(regs[3])); label_val_4->setText(hex2(regs[4])); label_val_5->setText(hex2(regs[5])); label_val_6->setText(hex2(regs[6])); label_val_7->setText(hex2(regs[7])); // Only on V9938 and V9958 this makes sence if (vdpid != VDP_TMS99X8) { label_val_8 ->setText(hex2(regs[ 8])); label_val_9 ->setText(hex2(regs[ 9])); label_val_10->setText(hex2(regs[10])); label_val_11->setText(hex2(regs[11])); label_val_12->setText(hex2(regs[12])); label_val_13->setText(hex2(regs[13])); label_val_14->setText(hex2(regs[14])); label_val_15->setText(hex2(regs[15])); label_val_16->setText(hex2(regs[16])); label_val_17->setText(hex2(regs[17])); label_val_18->setText(hex2(regs[18])); label_val_19->setText(hex2(regs[19])); label_val_20->setText(hex2(regs[20])); label_val_21->setText(hex2(regs[21])); label_val_22->setText(hex2(regs[22])); label_val_23->setText(hex2(regs[23])); } // Only on V9958 this makes sence if (vdpid == VDP_V9958) { label_val_25->setText(hex2(regs[25])); label_val_26->setText(hex2(regs[26])); label_val_27->setText(hex2(regs[27])); } // determine screenmode int m = ((regs[0] & 0x0E) << 1) | ((regs[1] & 0x18) >> 3); const char* const screen[32] = { "SCREEN 1", "SCREEN 3", "SCREEN 0", "let's find out 3", "SCREEN 2", "let's find out 5", "let's find out 6", "let's find out 7", "SCREEN 4", "let's find out 9", "SCREEN 0 width 80", "let's find out 11", "SCREEN 5", "let's find out 13", "let's find out 14", "let's find out 15", "SCREEN 6", "let's find out 17", "let's find out 18", "let's find out 19", "SCREEN 7", "let's find out 21", "let's find out 22", "let's find out 23", "let's find out 24", "let's find out 25", "let's find out 26", "let's find out 27", "SCREEN 8", "let's find out 29", "let's find out 30", "let's find out 31" }; int basicscreen; switch (m){ case 2: basicscreen=0;break; case 0: basicscreen=1;break; case 4: basicscreen=2;break; case 1: basicscreen=3;break; case 8: basicscreen=4;break; case 12: basicscreen=5;break; case 16: basicscreen=6;break; case 20: basicscreen=7;break; case 28: basicscreen=8;break; case 10: basicscreen=9;break; //screen 0 width 80 default: basicscreen=10; //not a valid basic screen mode }; // 2 vdps, 11 basic screenmodes, 12 registers static const int mustbeone[][11][12] = { { // TMS99x8 MSX1 VDP chip {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 1; {0, 0, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 2; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 3; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 4; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 5; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 6; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 7; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 8; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0 width 80; {0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0} // undefined basic screen; }, { // V9938 and V9958 MSX2/2+ VDP chip // Note that there is a hardcoded check for reg5 bit 2 (A9) in spritemode 2 // which deliberatly isn't set here in the table! {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 1; {0, 0, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 2; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 3; {0, 0, 0x00, 0x7f, 0x03, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 4; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 5; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 6; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 7; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 8; {0, 0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0 width 80; {0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} // undefined basic screen; } }; static const int bitsused[][11][12] = { {// MSX1 = static const int VDP_TMS99X8 = 1 {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 0; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 1; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 2; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 3; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 4; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 5; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 6; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 7; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 8; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 0 width 80; {255,255,255,255,255,255,255,255,255,255,255,255} // undefined basic screen; }, { // MSX2 = static const int VDP_V9938 = 0; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 0; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 1; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 2; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 3; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 4; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 5; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 6; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 7; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 8; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 0 width 80; {255,255,255,255,255,255,255,255,255,255,255,255} // undefined basic screen; } }; // update all the individual bits int upper_r = (vdpid == VDP_TMS99X8) ? 7 : (vdpid == VDP_V9938) ? 23 : 27; for (int r = 0; r <= upper_r; ++r) { if (r == 24) continue; for (int b = 7; b >= 0; --b) { QString name = QString("pushButton_%1_%2").arg(r).arg(b); InteractiveButton* i = findChild(name); i->setChecked((regs[r] & (1 << b)) ? true : false); if (r<12){ i->mustBeSet((mustbeone[ (vdpid == VDP_TMS99X8)?0:1 ][basicscreen][r] & (1 << b)) ? true : false); // if A8 of R5 is a 'mustbeone' then we indicate this for A9 also // This bit is cleared in the table since it isn't used in the Sprite // Attribute Table address calculation otherwise, but will only impact the // Sprite Color Table if (r==5 && b==2 && vdpid!=VDP_TMS99X8 && mustbeone[1][basicscreen][5] ){ i->mustBeSet(true); } } } } // Start the interpretation label_dec_ie2->setText((regs[0] & 32) ? "Interrupt from lightpen enabled" : "Interrupt from lightpen disabled"); label_dec_ie1->setText((regs[0] & 16) ? "Reg 19 scanline interrupt enabled" : "Reg 19 scanline interrupt disabled"); if (vdpid != VDP_TMS99X8) { if (m == 20 || m == 28) { pushButton_2_6->setText("0"); pushButton_2_5->setText("A16"); pushButton_2_4->setText("A15"); pushButton_2_3->setText("A14"); pushButton_2_2->setText("A13"); pushButton_2_1->setText("A12"); pushButton_2_0->setText("A11"); } else { pushButton_2_6->setText("A16"); pushButton_2_5->setText("A15"); pushButton_2_4->setText("A14"); pushButton_2_3->setText("A13"); pushButton_2_2->setText("A12"); pushButton_2_1->setText("A11"); pushButton_2_0->setText("A10"); } } if (m == 28 && vdpid == VDP_V9958) { bool yjk = (regs[25] & 8); bool yae = (regs[25] & 16); int scr = yjk ? (yae ? 10 : 12) : 8; label_dec_m->setText(QString("M=%1%2%3 : SCREEN %4") .arg(m) .arg(yjk ? "+YJK" : "") .arg(yae ? "+YAE" : "") .arg(scr)); } else { label_dec_m->setText(QString("M=%1 : %2") .arg(m) .arg(screen[m])); } label_dec_bl->setText((regs[1] & 64) ? "Display enabled" : "Display disabled"); label_dec_ie0->setText((regs[1] & 32) ? "V-Blank interrupt enabled" : "V-Blank interrupt disabled"); label_dec_si->setText((regs[1] & 2) ? "16x16 sprites" : "8x8 sprites"); label_dec_mag->setText((regs[1] & 1) ? "magnified sprites" : "regular sized"); // Now calculate the addresses of all tables // TODO : clean up code and get rid of all the mustbeset bits for regs>5 since there are never must bits. // some variables used for readability of the code below int row = vdpid==VDP_TMS99X8?0:1; QString regtexttext; int must,must2; // the pattern name table address must=mustbeone[row][basicscreen][2] ; long nameTable = ((255^must) & bitsused[row][basicscreen][2] & regs[2]) << 10; if ((m == 20 || m == 28) && vdpid != VDP_TMS99X8) nameTable = ((nameTable & 0xffff) << 1) | ((nameTable & 0x10000) >> 16); regtexttext = hex5(nameTable); if ((must & regs[2]) != must ) { label_dec_r2->setText("" + regtexttext +""); label_dec_r2->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r2->setText(regtexttext); label_dec_r2->setToolTip(NULL); } // the color table address must=mustbeone[row][basicscreen][3] ; must2=mustbeone[row][basicscreen][10] ; regtexttext=hex5( ( ((255^must) & bitsused[row][basicscreen][ 3] & regs[ 3]) << 6 ) | ( ((255^must2) & bitsused[row][basicscreen][10] & regs[10]) << 14 ) ); if (((must & regs[3]) != must ) || ((must2 & regs[10]) != must2 ) ){ label_dec_r3->setText("" + regtexttext +""); label_dec_r3->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r3->setText(regtexttext); label_dec_r3->setToolTip(NULL); } // the pattern generator address must=mustbeone[row][basicscreen][4] ; regtexttext=hex5( ( ( 255^must) & bitsused[row][basicscreen][4] & regs[4]) << 11 ); if ((must & regs[4]) != must ){ label_dec_r4->setText("" + regtexttext +""); label_dec_r4->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r4->setText(regtexttext); label_dec_r4->setToolTip(NULL); } // the sprite attribute tabel address must=mustbeone[row][basicscreen][5] ; must2=mustbeone[row][basicscreen][11] ; regtexttext=hex5( ( (((255^must) & bitsused[row][basicscreen][ 5] & regs[ 5]) << 7) | (((255^must2) & bitsused[row][basicscreen][11] & regs[11]) << 15)) ); if (((must & regs[5]) != must ) || ((must2 & regs[11]) != must2 ) ){ label_dec_r5->setText("" + regtexttext +""); label_dec_r5->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r5->setText(regtexttext); label_dec_r5->setToolTip(NULL); }; // special case for sprite mode 2 if (must && !( 4 & regs[ 5])) { // only in mode2 there are some 'must'-bits :-) label_dec_r5->setText("" + regtexttext +""); label_dec_r5->setToolTip("Bit A9 should be set, to obtain the Sprite Color Table address this bit is masked
With the current bit reset the Color Tabel will use the same address as the Sprite Atribute Tabel!"); }; // the sprite pattern generator address label_dec_r6->setText(hex5( ((255^mustbeone[row][basicscreen][6]) & bitsused[row][basicscreen][6] & regs[6]) << 11)); // end of address calculations label_dec_tc->setText(dec2((regs[7] >> 4) & 15)); label_dec_bd->setText(dec2((regs[7] >> 0) & 15)); if (vdpid != VDP_TMS99X8) { label_dec_tp->setText((regs[8] & 32) ? "Color 0 uses the color registers" : "Color 0 is transparent (=shows border)"); label_dec_spd->setText((regs[8] & 2) ? "Sprites disabled" : "Sprites enabled"); label_dec_ln->setText((regs[9] & 128) ? "212" : "192"); label_dec_il->setText((regs[9] & 8) ? "interlaced" : "non-interlaced"); label_dec_eo->setText((regs[9] & 4) ? "alternate pages" : "same page"); label_dec_nt->setText((regs[9] & 2) ? "PAL" : "NTSC"); label_dec_t2 ->setText(dec2((regs[12] >> 4) & 15)); label_dec_bc ->setText(dec2((regs[12] >> 0) & 15)); label_dec_on ->setText(dec2((regs[13] >> 4) & 15)); label_dec_off->setText(dec2((regs[13] >> 0) & 15)); int x = ((regs[18] >> 0) & 15); int y = ((regs[18] >> 4) & 15); x = x > 7 ? 16 - x : -x; y = y > 7 ? 16 - y : -y; label_dec_r18->setText(QString("(%1,%2)").arg(x).arg(y)); label_dec_r19->setText(dec3(regs[19])); label_dec_r23->setText(dec3(regs[23])); label_dec_r14->setText(hex5(((regs[14] & 7) << 14) | ((regs[81] & 63) << 8) | regs[80])); label_dec_r15->setText(dec2(regs[15] & 15)); label_dec_r16->setText(dec2(regs[16] & 15)); label_dec_r17->setText(dec3(regs[17] & 63).append((regs[17] & 128) ? ", auto incr" : "")); } //V9958 registers if (vdpid == VDP_V9958) { label_dec_r26->setText(QString("horizontal scroll %1") .arg((regs[26] & 63) * 8 - (7 & regs[27]))); label_dec_sp2->setText((regs[25] & 1) ? "Scroll uses 2 pages" : "Scroll same page"); label_dec_msk->setText((regs[25] & 2) ? "Hide 8 leftmost pixels" : "No masking"); label_dec_wte->setText((regs[25] & 4) ? "Disabled CPU Waitstate" : "Enable CPU Waitstate"); if (regs[25] & 8) { label_dec_yjk->setText("YJK System"); label_dec_yae->setText((regs[25] & 16) ? "Attribute enabled (Y=4bits)" : "regular YJK (Y=5bits)"); } else { label_dec_yjk->setText("Normal RGB"); label_dec_yae->setText("Ignored (YJK disabled)"); } label_dec_vds->setText((regs[25] & 32) ? "Pin8 is /VDS" : "Pin8 is CPUCLK"); label_dec_cmd->setText((regs[25] & 64) ? "CMD engine in char modes" : "V9938 VDP CMD engine"); } } void VDPRegViewer::doConnect(InteractiveButton* but, buttonHighlightDispatcher* dis) { connect(but, SIGNAL(mouseOver(bool)), dis, SLOT(receiveState(bool))); connect(dis, SIGNAL(dispatchState(bool)), but, SLOT(highlight(bool))); } void VDPRegViewer::monoGroup(InteractiveButton* but, InteractiveLabel* lab) { connect(lab, SIGNAL(mouseOver(bool)), but, SLOT(highlight(bool))); connect(but, SIGNAL(mouseOver(bool)), lab, SLOT(highlight(bool))); connect(lab, SIGNAL(mouseOver(bool)), lab, SLOT(highlight(bool))); connect(but, SIGNAL(mouseOver(bool)), but, SLOT(highlight(bool))); } void VDPRegViewer::reGroup(InteractiveButton* item, buttonHighlightDispatcher* dispat) { //button must rehighlight itself connect(item, SIGNAL(mouseOver(bool)), item, SLOT(highlight(bool))); // and then talk to dispatcher doConnect(item, dispat); } buttonHighlightDispatcher* VDPRegViewer::makeGroup( QList list, InteractiveLabel* explained) { // First "steal" the Tooltip of the explained widget. InteractiveButton* item; //foreach(item, list) { // item->setToolTip(explained->toolTip()); //} // Create a dispatcher and connect all to them buttonHighlightDispatcher* dispat = new buttonHighlightDispatcher(); connect(explained, SIGNAL(mouseOver(bool)), dispat, SLOT(receiveState(bool))); connect(dispat, SIGNAL(dispatchState(bool)), explained, SLOT(highlight(bool))); foreach(item, list){ doConnect(item, dispat); } return dispat; } void VDPRegViewer::connectHighLights() { // Before connecting the highlights we connect the special // 'Toggled Bit' event // Warning: This function is not available with MSVC 6!! Not that it // matters to me on my Linux environment :-) QList list = findChildren(); InteractiveButton* item; foreach(item, list) { connect(item, SIGNAL(newBitValue(int,int,bool)), this, SLOT(registerBitChanged(int,int,bool))); } // register 0 (+M1,M2) monoGroup(pushButton_0_5, label_dec_ie2); monoGroup(pushButton_0_4, label_dec_ie1); list.clear(); list << pushButton_0_3 << pushButton_0_2 << pushButton_0_1; list << pushButton_1_4 << pushButton_1_3; modeBitsDispat = makeGroup(list, label_dec_m); // register 1 monoGroup(pushButton_1_6, label_dec_bl); monoGroup(pushButton_1_5, label_dec_ie0); monoGroup(pushButton_1_1, label_dec_si); monoGroup(pushButton_1_0, label_dec_mag); // register 8 //monoGroup(pushButton_8_7, label_dec_ms); //monoGroup(pushButton_8_6, label_dec_lp); monoGroup(pushButton_8_5, label_dec_tp); //monoGroup(pushButton_8_4, label_dec_cb); //monoGroup(pushButton_8_3, label_dec_vr); monoGroup(pushButton_8_1, label_dec_spd); //monoGroup(pushButton_8_0, label_dec_bw); // register 9 monoGroup(pushButton_9_7, label_dec_ln); list.clear(); list << pushButton_9_5 << pushButton_9_4; makeGroup(list, label_dec_m); //TODO fix label monoGroup(pushButton_9_3, label_dec_il); monoGroup(pushButton_9_2, label_dec_eo); monoGroup(pushButton_9_1, label_dec_nt); //monoGroup(pushButton_9_0, label_dec_dc); // register 2 list.clear(); list << pushButton_2_7 << pushButton_2_6 << pushButton_2_5; list << pushButton_2_4 << pushButton_2_3 << pushButton_2_2; list << pushButton_2_1 << pushButton_2_0; makeGroup(list, label_dec_r2); // register 3 + 10 list.clear(); list << pushButton_3_7 << pushButton_3_6 << pushButton_3_5; list << pushButton_3_4 << pushButton_3_3 << pushButton_3_2; list << pushButton_3_1 << pushButton_3_0; list << pushButton_10_7 << pushButton_10_6 << pushButton_10_5; list << pushButton_10_4 << pushButton_10_3 << pushButton_10_2; list << pushButton_10_1 << pushButton_10_0; makeGroup(list, label_dec_r3); // register 4 list.clear(); list << pushButton_4_7 << pushButton_4_6 << pushButton_4_5; list << pushButton_4_4 << pushButton_4_3 << pushButton_4_2; list << pushButton_4_1 << pushButton_4_0; makeGroup(list, label_dec_r4); // register 5 + 11 list.clear(); list << pushButton_5_7 << pushButton_5_6 << pushButton_5_5; list << pushButton_5_4 << pushButton_5_3 << pushButton_5_2; list << pushButton_5_1 << pushButton_5_0; list << pushButton_11_7 << pushButton_11_6 << pushButton_11_5; list << pushButton_11_4 << pushButton_11_3 << pushButton_11_2; list << pushButton_11_1 << pushButton_11_0; makeGroup(list, label_dec_r5); // register 6 list.clear(); list << pushButton_6_7 << pushButton_6_6 << pushButton_6_5; list << pushButton_6_4 << pushButton_6_3 << pushButton_6_2; list << pushButton_6_1 << pushButton_6_0; makeGroup(list, label_dec_r6); // register 7 list.clear(); list << pushButton_7_7 << pushButton_7_6; list << pushButton_7_5 << pushButton_7_4; makeGroup(list, label_dec_tc); list.clear(); list << pushButton_7_3 << pushButton_7_2; list << pushButton_7_1 << pushButton_7_0; makeGroup(list, label_dec_bd); // register 12 list.clear(); list << pushButton_12_7 << pushButton_12_6; list << pushButton_12_5 << pushButton_12_4; makeGroup(list, label_dec_t2); list.clear(); list << pushButton_12_3 << pushButton_12_2; list << pushButton_12_1 << pushButton_12_0; makeGroup(list, label_dec_bc); // register 13 list.clear(); list << pushButton_13_7 << pushButton_13_6; list << pushButton_13_5 << pushButton_13_4; makeGroup(list, label_dec_on); list.clear(); list << pushButton_13_3 << pushButton_13_2; list << pushButton_13_1 << pushButton_13_0; makeGroup(list, label_dec_off); // register 14 list.clear(); list << pushButton_14_7 << pushButton_14_6 << pushButton_14_5; list << pushButton_14_4 << pushButton_14_3 << pushButton_14_2; list << pushButton_14_1 << pushButton_14_0; makeGroup(list, label_dec_r14); // register 15 list.clear(); list << pushButton_15_7 << pushButton_15_6 << pushButton_15_5; list << pushButton_15_4 << pushButton_15_3 << pushButton_15_2; list << pushButton_15_1 << pushButton_15_0; makeGroup(list, label_dec_r15); // register 16 list.clear(); list << pushButton_16_7 << pushButton_16_6 << pushButton_16_5; list << pushButton_16_4 << pushButton_16_3 << pushButton_16_2; list << pushButton_16_1 << pushButton_16_0; makeGroup(list, label_dec_r16); // register 17 list.clear(); list << pushButton_17_7 << pushButton_17_6 << pushButton_17_5; list << pushButton_17_4 << pushButton_17_3 << pushButton_17_2; list << pushButton_17_1 << pushButton_17_0; makeGroup(list, label_dec_r17); // register 18 list.clear(); list << pushButton_18_7 << pushButton_18_6 << pushButton_18_5; list << pushButton_18_4 << pushButton_18_3 << pushButton_18_2; list << pushButton_18_1 << pushButton_18_0; makeGroup(list, label_dec_r18); // register 19 list.clear(); list << pushButton_19_7 << pushButton_19_6 << pushButton_19_5; list << pushButton_19_4 << pushButton_19_3 << pushButton_19_2; list << pushButton_19_1 << pushButton_19_0; makeGroup(list, label_dec_r19); // register 23 list.clear(); list << pushButton_23_7 << pushButton_23_6 << pushButton_23_5; list << pushButton_23_4 << pushButton_23_3 << pushButton_23_2; list << pushButton_23_1 << pushButton_23_0; makeGroup(list, label_dec_r23); // register 25 monoGroup(pushButton_25_0, label_dec_sp2); monoGroup(pushButton_25_1, label_dec_msk); monoGroup(pushButton_25_2, label_dec_wte); monoGroup(pushButton_25_3, label_dec_yjk); monoGroup(pushButton_25_4, label_dec_yae); monoGroup(pushButton_25_5, label_dec_vds); monoGroup(pushButton_25_6, label_dec_cmd); // register 26 list.clear(); list << pushButton_26_7 << pushButton_26_6 << pushButton_26_5; list << pushButton_26_4 << pushButton_26_3 << pushButton_26_2; list << pushButton_26_1 << pushButton_26_0; list << pushButton_27_7 << pushButton_27_6 << pushButton_27_5; list << pushButton_27_4 << pushButton_27_3 << pushButton_27_2; list << pushButton_27_1 << pushButton_27_0; makeGroup(list, label_dec_r26); } void VDPRegViewer::refresh() { //new SimpleHexRequest("{VDP regs}",0,64,regs, *this); //new SimpleHexRequest("{VDP status regs}",0,16,regs, *this); // now combined in one request: new SimpleHexRequest( "debug_bin2hex " "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VDP status regs} 0 16 ]" "[ debug read_block {VRAM pointer} 0 2 ]", 64 + 16 + 2, regs, *this); } void VDPRegViewer::DataHexRequestReceived() { decodeStatusVDPRegs(); decodeVDPRegs(); } void VDPRegViewer::registerBitChanged(int reg, int bit, bool state) { // maybe this call is the result of our own SetChecked (VDPDataStorte // update event) if ((state ? 1 : 0) == (regs[reg] & (1 << bit))) { return; } // state does not correspond to the current register setting so we send // an update command if (state) { regs[reg] |= (1 << bit); } else { regs[reg] &= ~(1 << bit); } CommClient::instance().sendCommand( new SimpleCommand( QString("debug write {VDP regs} %1 %2").arg(reg).arg(regs[reg]))); // Update display without waiting for the VDPDataStore update decodeVDPRegs(); // and then we could request an update nevertheless since some other // objects might want to see this change through the VDPDataStore also // :-) // VDPDataStore::instance().refresh(); } void VDPRegViewer::on_VDPcomboBox_currentIndexChanged(int index) { switch (index) { case 0: vdpid = VDP_V9958; break; case 1: vdpid = VDP_V9938; break; case 2: vdpid = VDP_TMS99X8; break; } decodeStatusVDPRegs(); decodeVDPRegs(); } debugger-master/src/InteractiveLabel.h0000644000175000017500000000057113560352104017646 0ustar shevekshevek#ifndef INTERACTIVELABEL #define INTERACTIVELABEL #include class InteractiveLabel : public QLabel { Q_OBJECT public: InteractiveLabel(QWidget* parent = 0); protected: virtual void enterEvent(QEvent* event); virtual void leaveEvent(QEvent* event); signals: void mouseOver(bool state); public slots: void highlight(bool state); }; #endif // INTERACTIVELABEL debugger-master/src/VDPDataStore.h0000644000175000017500000000251213560352104016666 0ustar shevekshevek#ifndef VDPDATASTORE_H #define VDPDATASTORE_H #include "SimpleHexRequest.h" #include #include class VDPDataStore : public QObject, public SimpleHexRequestUser { Q_OBJECT public: static VDPDataStore& instance(); const unsigned char* getVramPointer() const; const unsigned char* getPalettePointer() const; const unsigned char* getRegsPointer() const; const unsigned char* getStatusRegsPointer() const; const unsigned char* getVdpVramPointer() const; const size_t getVRAMSize() const; private: VDPDataStore(); ~VDPDataStore(); virtual void DataHexRequestReceived(); void refresh1(); void refresh2(); unsigned char* vram; size_t vramSize; std::string debuggableNameVRAM; // VRAM debuggable name bool got_version; // is the above boolean already filled in? friend class VDPDataStoreVersionCheck; friend class VDPDataStoreVRAMSizeCheck; public slots: void refresh(); signals: void dataRefreshed(); // The refresh got the new data /** This might become handy later on, for now we only need the dataRefreshed * void dataChanged(); //any of the contained data has changed void vramChanged(); //only the vram changed void paletteChanged(); //only the palette changed void regsChanged(); //only the regs changed void statusRegsChanged(); //only the regs changed */ }; #endif /* VDPDATASTORE_H */ debugger-master/src/Version.h0000644000175000017500000000045113560352104016053 0ustar shevekshevek#ifndef VERSION_H #define VERSION_H #include class Version { public: // Defined by build system: static const bool RELEASE; static const char* const VERSION; static const char* const REVISION; // Computed using constants above: static std::string full(); }; #endif // VERSION_H debugger-master/src/ConnectDialog.cpp0000644000175000017500000002045713560352104017502 0ustar shevekshevek#include "ConnectDialog.h" #include #include #include #include #include #include #include #ifdef _WIN32 #include "SspiNegotiateClient.h" #include "QAbstractSocketStreamWrapper.h" #include #include #include using namespace openmsx; #else #include #include #include #include #include #endif // Helper functions to setup a connection static QString getUserName() { #ifdef _WIN32 return "default"; #else struct passwd* pw = getpwuid(getuid()); return pw->pw_name ? pw->pw_name : ""; #endif } static bool checkSocketDir(const QDir& dir) { if (!dir.exists()) { return false; } #ifndef _WIN32 // only do permission and owner checks on *nix QFileInfo info(dir.absolutePath()); if (info.ownerId() != getuid()) { return false; } int all = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; QFile::Permissions needed = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; if ((info.permissions() & all) != needed) { return false; } #endif return true; } static bool checkSocket(const QFileInfo& info) { if (!info.fileName().startsWith("socket.")) { // wrong name return false; } #ifndef _WIN32 // only do permission and owner checks on *nix int all = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; QFile::Permissions needed = QFile::ReadOwner | QFile::WriteOwner; if ((info.permissions() & all) != needed) { return false; } if (info.ownerId() != getuid()) { return false; } #endif return true; } static void deleteSocket(const QFileInfo& info) { QFile::remove(info.absoluteFilePath()); // ignore errors QDir dir; dir.rmdir(info.absolutePath()); // ignore errors } static OpenMSXConnection* createConnection(const QDir& dir, const QString& socketName) { QFileInfo info(dir, socketName); if (!checkSocket(info)) { // invalid socket return NULL; } QAbstractSocket* socket = NULL; #ifdef _WIN32 int port = -1; std::ifstream in(info.absoluteFilePath().toLatin1().data()); in >> port; if (port != -1) { QHostAddress localhost(QHostAddress::LocalHost); socket = new QTcpSocket(); socket->connectToHost(localhost, port); QAbstractSocketStreamWrapper stream(socket); SspiNegotiateClient client(stream); if (!socket->waitForConnected(1000) || !client.Authenticate()) { delete socket; socket = NULL; } } #else int sd = ::socket(AF_UNIX, SOCK_STREAM, 0); if (sd != -1) { sockaddr_un addr; addr.sun_family = AF_UNIX; strcpy(addr.sun_path, info.absoluteFilePath().toLatin1().data()); if (connect(sd, (sockaddr*)&addr, sizeof(addr)) != -1) { socket = new QTcpSocket(); if (!socket->setSocketDescriptor(sd)) { // failed to wrap socket in QTcpSocket delete socket; socket = NULL; close(sd); } } else { // failed to connect to UNIX socket close(sd); } } #endif if (socket) { return new OpenMSXConnection(socket); } else { // cannot connect, must be a stale socket, try to clean it up deleteSocket(socketName); return NULL; } } static void collectServers(QList& servers) { #ifdef _WIN32 DWORD len = GetTempPathW(0, nullptr); assert(len > 0); // nothing we can do to recover this //VLA(wchar_t, bufW, (len+1)); //wchar_t bufW[len+1]; auto bufW = static_cast(_alloca(sizeof(wchar_t) * (len+1))); len = GetTempPathW(len, bufW); assert(len > 0); // nothing we can do to recover this QDir dir(QString::fromWCharArray(bufW, len)); #else QDir dir((getenv("TMPDIR")) ? getenv("TMPDIR") : QDir::tempPath()); #endif dir.cd("openmsx-" + getUserName()); if (!checkSocketDir(dir)) { // no correct socket directory return; } QDir::Filters filters = #ifdef _WIN32 QDir::Files; // regular files for win32 #else QDir::System; // sockets for *nix #endif foreach (QString name, dir.entryList(filters)) { if (OpenMSXConnection* connection = createConnection(dir, name)) { servers.push_back(connection); } } } // ConnectionInfoRequest class ConnectionInfoRequest::ConnectionInfoRequest( ConnectDialog& dialog_, OpenMSXConnection& connection_) : dialog(dialog_), connection(connection_) { state = GET_MACHINE; connection.sendCommand(this); } QString ConnectionInfoRequest::getCommand() const { switch (state) { case GET_MACHINE: return "machine_info config_name"; case GET_TITLE: return "guess_title"; default: assert(false); return ""; } } void ConnectionInfoRequest::replyOk(const QString& message) { switch (state) { case GET_MACHINE: title = message; state = GET_TITLE; connection.sendCommand(this); break; case GET_TITLE: { if (!message.isEmpty()) { title += " (" + message + ")"; } dialog.connectionOk(connection, title); state = DONE; connect(&connection, SIGNAL(disconnected()), this, SLOT(terminate())); break; } default: assert(false); } } void ConnectionInfoRequest::replyNok(const QString& /*message*/) { cancel(); } void ConnectionInfoRequest::cancel() { dialog.connectionBad(connection); } void ConnectionInfoRequest::terminate() { cancel(); } // class ConnectDialog OpenMSXConnection* ConnectDialog::getConnection(QWidget* parent) { ConnectDialog dialog(parent); // delay for at most 500ms while checking the connections dialog.delay = 1; dialog.startTimer(500); while (!dialog.pendingConnections.empty() && dialog.delay) { qApp->processEvents(QEventLoop::AllEvents, 200); } // if there is only one valid connection, use it immediately, // otherwise execute the dialog. if (dialog.pendingConnections.empty() && dialog.confirmedConnections.size() == 1 ) { dialog.on_connectButton_clicked(); } else { dialog.exec(); } return dialog.result; } ConnectDialog::ConnectDialog(QWidget* parent) : QDialog(parent) , result(NULL) { ui.setupUi(this); on_rescanButton_clicked(); } ConnectDialog::~ConnectDialog() { clear(); } void ConnectDialog::timerEvent(QTimerEvent* event) { killTimer(event->timerId()); delay = 0; } void ConnectDialog::clear() { ui.listConnections->clear(); // First kill the infos. That will remove the disconnect signals. qDeleteAll(connectionInfos); connectionInfos.clear(); qDeleteAll(pendingConnections); pendingConnections.clear(); qDeleteAll(confirmedConnections); confirmedConnections.clear(); } void ConnectDialog::on_connectButton_clicked() { int row = ui.listConnections->currentRow(); if (row != -1) { assert((0 <= row) && (row < confirmedConnections.size())); result = confirmedConnections[row]; confirmedConnections.removeAt(row); } accept(); } void ConnectDialog::on_rescanButton_clicked() { clear(); collectServers(pendingConnections); foreach (OpenMSXConnection* connection, pendingConnections) { connectionInfos.append(new ConnectionInfoRequest(*this, *connection)); } } void ConnectDialog::connectionOk(OpenMSXConnection& connection, const QString& title) { OpenMSXConnections::iterator it = qFind(pendingConnections.begin(), pendingConnections.end(), &connection); if (it == pendingConnections.end()) { // connection is already beiing destoyed return; } pendingConnections.erase(it); confirmedConnections.push_back(&connection); new QListWidgetItem(title, ui.listConnections); if (ui.listConnections->count() == 1) { // automatically select first row ui.listConnections->setCurrentRow(0); } } void ConnectDialog::connectionBad(OpenMSXConnection& connection) { OpenMSXConnections::iterator it = qFind(pendingConnections.begin(), pendingConnections.end(), &connection); if (it == pendingConnections.end()) { // was this connection established but terminated? int id = confirmedConnections.indexOf(&connection); if (id >= 0) { OpenMSXConnection* conn = confirmedConnections.takeAt(id); QListWidgetItem* item = ui.listConnections->takeItem(id); delete item; conn->deleteLater(); } return; } pendingConnections.erase(it); connection.deleteLater(); } debugger-master/src/SimpleHexRequest.cpp0000644000175000017500000000202413560352104020226 0ustar shevekshevek#include "SimpleHexRequest.h" #include "CommClient.h" // class SimpleHexRequest SimpleHexRequest::SimpleHexRequest( const QString& debuggable, unsigned size, unsigned char* target, SimpleHexRequestUser& user_) : ReadDebugBlockCommand(debuggable, size, target) , offset(0) , user(user_) { CommClient::instance().sendCommand(this); } SimpleHexRequest::SimpleHexRequest( const QString& debuggable, unsigned offset_, unsigned size, unsigned char* target, SimpleHexRequestUser& user_) : ReadDebugBlockCommand(debuggable, offset_, size, target) , offset(offset_) , user(user_) { CommClient::instance().sendCommand(this); } void SimpleHexRequest::replyOk(const QString& message) { copyData(message); user.DataHexRequestReceived(); delete this; } void SimpleHexRequest::cancel() { user.DataHexRequestCanceled(); delete this; } // class SimpleHexRequestUser SimpleHexRequestUser::~SimpleHexRequestUser() { } void SimpleHexRequestUser::DataHexRequestReceived() { } void SimpleHexRequestUser::DataHexRequestCanceled() { } debugger-master/src/DebuggableViewer.h0000644000175000017500000000103413560352104017627 0ustar shevekshevek#ifndef DEBUGGABLEVIEWER_H #define DEBUGGABLEVIEWER_H #include class HexViewer; class QComboBox; class DebuggableViewer : public QWidget { Q_OBJECT public: DebuggableViewer(QWidget* parent = 0); public slots: void settingsChanged(); void setDebuggables(const QMap& list); void refresh(); private: HexViewer* hexView; QComboBox* debuggableList; QString lastSelected; int lastLocation; private slots: void debuggableSelected(int index); void locationChanged(int loc); }; #endif // DEBUGGABLEVIEWER_H debugger-master/src/SymbolTable.cpp0000644000175000017500000005034213560352104017202 0ustar shevekshevek#include "SymbolTable.h" #include "DebuggerData.h" #include #include #include #include #include #include #include // class SymbolTable SymbolTable::SymbolTable() { connect(&fileWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(const QString&))); } SymbolTable::~SymbolTable() { clear(); } void SymbolTable::add(Symbol* symbol) { symbols.append(symbol); symbol->table = this; mapSymbol(symbol); } void SymbolTable::removeAt(int index) { Symbol* symbol = symbols.takeAt(index); unmapSymbol(symbol); delete symbol; } void SymbolTable::remove(Symbol* symbol) { symbols.removeAll(symbol); unmapSymbol(symbol); delete symbol; } void SymbolTable::clear() { addressSymbols.clear(); valueSymbols.clear(); qDeleteAll(symbols); symbols.clear(); } int SymbolTable::size() const { return symbols.size(); } void SymbolTable::mapSymbol(Symbol* symbol) { if (symbol->type() != Symbol::VALUE) { addressSymbols.insert(symbol->value(), symbol); } if (symbol->type() != Symbol::JUMPLABEL) { valueSymbols.insert(symbol->value(), symbol); } } void SymbolTable::unmapSymbol(Symbol* symbol) { QMutableMapIterator i(addressSymbols); while (i.hasNext()) { i.next(); if (i.value() == symbol) i.remove(); } QMutableHashIterator j(valueSymbols); while (j.hasNext()) { j.next(); if (j.value() == symbol) j.remove(); } } void SymbolTable::symbolTypeChanged(Symbol* symbol) { unmapSymbol(symbol); mapSymbol(symbol); } void SymbolTable::symbolValueChanged(Symbol* symbol) { unmapSymbol(symbol); mapSymbol(symbol); } Symbol* SymbolTable::findFirstAddressSymbol(int addr, MemoryLayout* ml) { for (currentAddress = addressSymbols.begin(); currentAddress != addressSymbols.end(); ++currentAddress) { if ((*currentAddress)->value() >= addr) { if ((*currentAddress)->isSlotValid(ml)) { return *currentAddress; } } } return 0; } Symbol* SymbolTable::getCurrentAddressSymbol() { return currentAddress != addressSymbols.end() ? *currentAddress : 0; } Symbol* SymbolTable::findNextAddressSymbol(MemoryLayout* ml) { for (++currentAddress; currentAddress != addressSymbols.end(); ++currentAddress) { if ((*currentAddress)->isSlotValid(ml)) { return *currentAddress; } } return 0; } Symbol* SymbolTable::getValueSymbol(int val, Symbol::Register reg, MemoryLayout* ml) { for (QMultiHash::iterator it = valueSymbols.find(val); it != valueSymbols.end() && it.key() == val; ++it) { if ((it.value()->validRegisters() & reg) && it.value()->isSlotValid(ml)) { return it.value(); } } return 0; } Symbol* SymbolTable::getAddressSymbol(int addr, MemoryLayout* ml) { for (QMultiMap::iterator it = addressSymbols.find(addr); it != addressSymbols.end() && it.key() == addr; ++it) { if (it.value()->isSlotValid(ml)) { return it.value(); } } return 0; } Symbol* SymbolTable::getAddressSymbol(const QString& label, bool case_sensitive) { for (QMultiMap::iterator it = addressSymbols.begin(); it != addressSymbols.end(); ++it) { if (it.value()->text().compare(label, Qt::CaseSensitive)==0) return it.value(); if (!case_sensitive && it.value()->text().compare(label, Qt::CaseInsensitive)==0) return it.value(); } return 0; } QStringList SymbolTable::labelList(bool include_vars, const MemoryLayout* ml) const { QStringList labels; for (QMultiMap::const_iterator it = addressSymbols.begin(); it != addressSymbols.end(); ++it) { if (it.value()->type() == Symbol::JUMPLABEL || (include_vars && it.value()->type() == Symbol::VARIABLELABEL ) ) if( ml == 0 || it.value()->isSlotValid(ml) ) labels << it.value()->text(); } return labels; } int SymbolTable::symbolFilesSize() const { return symbolFiles.size(); } const QString& SymbolTable::symbolFile(int index) const { return symbolFiles.at(index).fileName; } const QDateTime& SymbolTable::symbolFileRefresh(int index) const { return symbolFiles.at(index).refreshTime; } bool SymbolTable::readFile(const QString& filename, FileType type) { if (type == DETECT_FILE) { if (filename.toLower().endsWith(".map")) { // HiTech link map file type = LINKMAP_FILE; } else if (filename.toLower().endsWith(".sym")) { // auto detect which sym file QFile file(filename); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); QString line = in.readLine(); if (line[0] == ';') { type = ASMSX_FILE; } else if (line.contains("; last def. pass")) { type = TNIASM0_FILE; } else if (line.contains(": %equ ")) { type = TNIASM1_FILE; } else if (line.contains(": equ ")) { type = SJASM_FILE; } else { // this is a blunt conclusion but I // don't know a way to detect this file // type type = HTC_FILE; } } } else { QString ext = filename.toLower(); /* They are the same type of file. For some reason the Debian * manpage uses the extension ".sys" * pasmo doc -> pasmo [options] file.asm file.bin [file.symbol [file.publics] ] * pasmo manpage in Debian -> pasmo [options] file.asm file.bin [file.sys] */ if (ext.endsWith(".symbol") || ext.endsWith(".publics") || ext.endsWith(".sys") ) { type = PASMO_FILE; } } } switch (type) { case TNIASM0_FILE: return readTNIASM0File(filename); case TNIASM1_FILE: return readTNIASM1File(filename); case SJASM_FILE: return readSJASMFile(filename); case ASMSX_FILE: return readASMSXFile(filename); case HTC_FILE: return readHTCFile(filename); case LINKMAP_FILE: return readLinkMapFile(filename); case PASMO_FILE: return readPASMOFile(filename); default: return false; } } void SymbolTable::appendFile(const QString& file, FileType type) { SymbolFileRecord rec; rec.fileName = file; rec.fileType = type; rec.refreshTime = QDateTime::currentDateTime(); symbolFiles.append(rec); fileWatcher.addPath(file); } // Universal value parsing routine. Accepts: // - 0123h, 1234h, 1234H (hex) // - 0x1234 (hex) // - 1234 (dec) // - 0123 (oct) // The string may (optionally) end with a '; comment' part (with or without // whitespace around the ';' character). static bool parseValue(const QString& str, int& result) { QStringList l = str.split(";"); // ignore stuff after ';' QString s = l.at(0).trimmed(); bool success; if (s.endsWith('h', Qt::CaseInsensitive)) { s.chop(1); result = s.toInt(&success, 16); } else { result = s.toInt(&success, 0); // any base (e.g. 0x..) } return success; } bool SymbolTable::readSymbolFile( const QString& filename, FileType type, const QString& equ) { QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, type); QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList l = line.split(equ); if (l.size() != 2) continue; int value; if (!parseValue(l.at(1), value)) continue; Symbol* sym = new Symbol(l.at(0), value); sym->setSource(&symbolFiles.back().fileName); add(sym); } return true; } bool SymbolTable::readTNIASM0File(const QString& filename) { return readSymbolFile(filename, TNIASM0_FILE, ": equ "); } bool SymbolTable::readTNIASM1File(const QString& filename) { return readSymbolFile(filename, TNIASM1_FILE, ": %equ "); } bool SymbolTable::readSJASMFile(const QString& filename) { return readSymbolFile(filename, SJASM_FILE, ": equ "); } bool SymbolTable::readASMSXFile(const QString& filename) { QFile file( filename ); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, ASMSX_FILE); QTextStream in(&file); int filePart = 0; while (!in.atEnd()) { QString line = in.readLine(); if (line[0] == ';') { if (line.startsWith("; global and local")) { filePart = 1; } else if (line.startsWith("; other")) { filePart = 2; } } else { if ((line[0] == '$') || (line[4] == 'h') || (line[5] == 'h') || (line[8] == 'h')) { if (filePart == 1) { QStringList l = line.split(" "); Symbol* sym; if (line[0] == '$') { sym = new Symbol(l.at(1).trimmed(), l.at(0).right(4).toInt(0, 16)); } else if ((line[4] == 'h') || (line[5] == 'h')) { sym = new Symbol(l.at(1).trimmed(), l.at(0).mid(l.at(0).indexOf('h') - 4, 4).toInt(0, 16)); } else { QString m = l.at(0); QStringList n = m.split(":"); // n.at(0) = MegaROM page sym = new Symbol(l.at(1).trimmed(), n.at(1).left(4).toInt(0, 16)); } sym->setSource(&symbolFiles.back().fileName); add(sym); } else if (filePart == 2) { // } } } } return true; } bool SymbolTable::readPASMOFile(const QString& filename) { QFile file( filename ); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, PASMO_FILE); QTextStream in(&file); while (!in.atEnd()) { QString line; QStringList l; Symbol* sym; line = in.readLine(); l = line.split(QRegExp("(\t+)|( +)")); if (l.size() == 3) { sym = new Symbol(l.at(0), l.at(2).left(5).toInt(0, 16)); sym->setSource(&symbolFiles.back().fileName); add(sym); } } return true; } bool SymbolTable::readHTCFile(const QString& filename) { QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, HTC_FILE); QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList l = line.split(' '); if (l.size() != 3) continue; int value; if (!parseValue("0x" + l.at(1), value)) continue; Symbol* sym = new Symbol(l.at(0), value); sym->setSource(&symbolFiles.back().fileName); add(sym); } return true; } bool SymbolTable::readLinkMapFile(const QString& filename) { const QString magic("Machine type"); const QString tableStart("*\tSymbol Table"); QRegExp rx(" [0-9A-Fa-f]{4} (?![ 0-9])"); QRegExp rp("^([^ ]+) +[^ ]* +([0-9A-Fa-f]{4}) $"); QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, LINKMAP_FILE); QTextStream in(&file); if (in.atEnd()) return false; if (!in.readLine().startsWith(magic)) return false; while (true) { if (in.atEnd()) return false; if (in.readLine().startsWith(tableStart)) break; } while (!in.atEnd()) { QString line = in.readLine(); Q_ASSERT(!line.endsWith("\r")); if (line.isEmpty()) continue; line += " "; int len = line.length(); int l; int pos = 0; bool ok = false; // HiTech uses multiple columns of non-fixed width and // a column for psect may be blank so the address may in // the first or second match. for (int tries = 0; (tries < 2) && !ok; ++tries) { pos = rx.indexIn(line, pos); l = pos + rx.matchedLength(); if ((l > 0) && (len % l) == 0) { ok = true; for (int posn = pos + l; (posn < len) && ok; posn += l) { ok = (posn == rx.indexIn(line, posn)); } } pos = l - 1; } if (!ok) continue; for (pos = 0; pos < len; pos += l) { QString part = line.mid(pos, l); if (rp.indexIn(part) == 0) { QStringList l = rp.capturedTexts(); Symbol* sym = new Symbol(l.at(1), l.last().toInt(0, 16)); sym->setSource(&symbolFiles.back().fileName); add(sym); } } } return true; } void SymbolTable::fileChanged(const QString & /*path*/) { emit symbolFileChanged(); } void SymbolTable::reloadFiles() { for (int i = 0; i < symbolFiles.size(); ++i) { // check if file is newer QFileInfo fi = QFileInfo(symbolFiles[i].fileName); if (fi.lastModified() <= symbolFiles[i].refreshTime) continue; // file info QString name = symbolFiles[i].fileName; FileType type = symbolFiles[i].fileType; // symbol file is newer QMap symCopy; // copy all symbols originating from this file QMutableListIterator si(symbols); while (si.hasNext()) { si.next(); if (si.value()->source() == &symbolFiles[i].fileName) { symCopy.insert(si.value()->text(), Symbol(*si.value())); } } // remove existing file unloadFile(name); // read the new file readFile(name, type); // find old symbols in newly loaded file QMutableListIterator ni(symbols); QString* newFile = &symbolFiles.back().fileName; while (ni.hasNext()) { ni.next(); if (ni.value()->source() != newFile) continue; // find symbol in old list QMap::iterator sit = symCopy.find(ni.value()->text()); if (sit == symCopy.end()) continue; // symbol existed before, copy settings ni.value()->setValidSlots(sit->validSlots()); ni.value()->setValidRegisters(sit->validRegisters()); ni.value()->setType(sit->type()); if (sit->status() == Symbol::LOST) { ni.value()->setStatus(Symbol::ACTIVE); } else { ni.value()->setStatus(sit->status()); } symCopy.erase(sit); } // all symbols left in map are lost for (QMap::iterator sit = symCopy.begin(); sit != symCopy.end(); ++sit) { Symbol* sym = new Symbol(sit.value()); sym->setStatus(Symbol::LOST); sym->setSource(newFile); add(sym); } } } void SymbolTable::unloadFile(const QString& file, bool keepSymbols) { int index = -1; for (int i = 0; i < symbolFiles.size(); ++i) { if (symbolFiles[i].fileName == file) { index = i; break; } } if (index >= 0) { QString* name = &symbolFiles[index].fileName; if (!keepSymbols) { // remove symbols from address map QMutableMapIterator mi(addressSymbols); while (mi.hasNext()) { mi.next(); if (mi.value()->source() == name) mi.remove(); } // remove symbols from value hash QMutableHashIterator hi(valueSymbols); while (hi.hasNext()) { hi.next(); if (hi.value()->source() == name) hi.remove(); } } // remove symbols from value hash QMutableListIterator i(symbols); while (i.hasNext()) { i.next(); Symbol* sym = i.value(); if (sym->source() == name) { if (keepSymbols) { sym->setSource(0); } else { i.remove(); delete sym; } } } // remove record fileWatcher.removePath(symbolFiles[index].fileName); symbolFiles.removeAt(index); } } /* * Session loading/saving */ void SymbolTable::saveSymbols(QXmlStreamWriter& xml) { // write files QMap fileIds; for (int i = 0; i < symbolFiles.size(); ++i) { // add id mapping fileIds[&symbolFiles[i].fileName] = i; // write element xml.writeStartElement("SymbolFile"); switch (symbolFiles[i].fileType) { case TNIASM0_FILE: xml.writeAttribute("type","tniasm0"); break; case TNIASM1_FILE: xml.writeAttribute("type","tniasm1"); break; case ASMSX_FILE: xml.writeAttribute("type","asmsx"); break; case LINKMAP_FILE: xml.writeAttribute("type","linkmap"); break; default: break; } xml.writeAttribute("refreshTime", QString::number(symbolFiles[i].refreshTime.toTime_t())); xml.writeCharacters(symbolFiles[i].fileName); xml.writeEndElement(); } // write symbols for (QList::iterator sit = symbols.begin(); sit != symbols.end(); ++sit) { Symbol* sym = *sit; xml.writeStartElement("Symbol"); // status if (sym->status() == Symbol::HIDDEN) { xml.writeAttribute("status", "hidden"); } else if (sym->status() == Symbol::LOST) { xml.writeAttribute("status", "lost"); } // type if (sym->type() == Symbol::JUMPLABEL) { xml.writeTextElement("type", "jump"); } else if (sym->type() == Symbol::VARIABLELABEL) { xml.writeTextElement("type", "variable"); } else { xml.writeTextElement("type", "value"); } // text, value, slots and registers xml.writeTextElement("name", sym->text()); xml.writeTextElement("value", QString::number(sym->value())); xml.writeTextElement("validSlots", QString::number(sym->validSlots())); xml.writeTextElement("validRegisters", QString::number(sym->validRegisters())); // write source filename if (sym->source()) { xml.writeTextElement("source", QString::number(fileIds[sym->source()])); } // complete xml.writeEndElement(); } } void SymbolTable::loadSymbols(QXmlStreamReader& xml) { Symbol* sym; while (!xml.atEnd()) { xml.readNext(); // exit if closing of main tag if (xml.isEndElement() && xml.name() == "Symbols") break; // begin tag if (xml.isStartElement()) { if (xml.name() == "SymbolFile") { // read attributes and text QString ftype = xml.attributes().value("type").toString().toLower(); QString rtime = xml.attributes().value("refreshTime").toString(); QString fname = xml.readElementText(); // check type FileType type = TNIASM0_FILE; if (ftype == "tniasm1") { type = TNIASM1_FILE; } else if (ftype == "asmsx") { type = ASMSX_FILE; } else if (ftype == "linkmap") { type = LINKMAP_FILE; } // append file appendFile(fname, type); // change time symbolFiles.back().refreshTime.setTime_t(rtime.toUInt()); } else if (xml.name() == "Symbol") { // add empty symbol sym = new Symbol("", 0); add(sym); // get status attribute QString stat = xml.attributes().value("status").toString().toLower(); if (stat == "hidden") { sym->setStatus(Symbol::HIDDEN); } else if( stat == "lost" ) { sym->setStatus(Symbol::LOST); } } else if (xml.name() == "type") { // read symbol type element QString type = xml.readElementText().trimmed().toLower(); if (type == "jump") { sym->setType(Symbol::JUMPLABEL); } else if( type == "variable" ) { sym->setType(Symbol::VARIABLELABEL); } else if( type == "value" ) { sym->setType(Symbol::VALUE); } } else if (xml.name() == "name") { // read symbol name sym->setText(xml.readElementText()); } else if (xml.name() == "value") { // read symbol value sym->setValue(xml.readElementText().toInt()); } else if (xml.name() == "validSlots") { // read numeric valid slot mask sym->setValidSlots(xml.readElementText().toInt()); } else if (xml.name() == "validRegisters") { // read numeric valid registers mask sym->setValidRegisters(xml.readElementText().toInt()); } else if (xml.name() == "source") { // read source file id int id = xml.readElementText().toInt(); if (id >= 0 && id < symbolFiles.size()) { sym->setSource(&symbolFiles[id].fileName); } } } } } // class Symbol Symbol::Symbol(const QString& str, int addr, int val) : symText(str), symValue(addr), symSlots(val) { symStatus = ACTIVE; symType = JUMPLABEL; symSource = 0; if (addr & 0xFF00) { symRegisters = REG_ALL16; } else { symRegisters = REG_ALL; } table = 0; } Symbol::Symbol(const Symbol& symbol) { table = 0; symStatus = symbol.symStatus; symText = symbol.symText; symValue = symbol.symValue; symSlots = symbol.symSlots; symSegments = symbol.symSegments; symRegisters = symbol.symRegisters; symSource = symbol.symSource; symType = symbol.symType; } const QString& Symbol::text() const { return symText; } void Symbol::setText(const QString& str) { symText = str; } int Symbol::value() const { return symValue; } void Symbol::setValue(int addr) { if (addr == symValue) return; symValue = addr; if (table) table->symbolValueChanged(this); } int Symbol::validSlots() const { return symSlots; } void Symbol::setValidSlots(int val) { symSlots = val & 0xFFFF; } int Symbol::validRegisters() const { return symRegisters; } void Symbol::setValidRegisters(int regs) { symRegisters = regs; if (symValue & 0xFF00) { symRegisters &= REG_ALL16; } } const QString* Symbol::source() const { return symSource; } void Symbol::setSource(const QString* name) { symSource = name; } Symbol::SymbolStatus Symbol::status() const { return symStatus; } void Symbol::setStatus(SymbolStatus s) { symStatus = s; } Symbol::SymbolType Symbol::type() const { return symType; } void Symbol::setType(SymbolType t) { if (symType == t) return; symType = t; if (table) table->symbolTypeChanged(this); } bool Symbol::isSlotValid(const MemoryLayout* ml) const { if (!ml) return true; int page = symValue >> 14; int ps = ml->primarySlot[page] & 3; int ss = 0; if (ml->isSubslotted[page]) ss = ml->secondarySlot[page] & 3; if (symSlots & (1 << (4 * ps + ss))) { if (symSegments.empty()) return true; for (int i = 0; i < symSegments.size(); ++i) { if (ml->mapperSegment[page] == symSegments[i]) { return true; } } } return false; } debugger-master/src/Dasm.cpp0000644000175000017500000001112313560352104015643 0ustar shevekshevek#include "Dasm.h" #include "DasmTables.h" #include "SymbolTable.h" #include #include static char sign(unsigned char a) { return (a & 128) ? '-' : '+'; } static int abs(unsigned char a) { return (a & 128) ? (256 - a) : a; } static std::string toHex(unsigned value, unsigned width) { std::ostringstream s; s << std::hex << std::setw(width) << std::setfill('0') << value; return s.str(); } static std::string translateAddress( int address, MemoryLayout* memLayout, SymbolTable* symTable) { if (Symbol* label = symTable->getAddressSymbol(address, memLayout)) { return label->text().toStdString(); } else { return '#' + toHex(address, 4); } } static int get16(const unsigned char* memBuf, int address) { return memBuf[address] + 256 * memBuf[address + 1]; } void dasm(const unsigned char* membuf, unsigned short startAddr, unsigned short endAddr, DisasmLines& disasm, MemoryLayout* memLayout, SymbolTable* symTable, int currentPC) { int pc = startAddr; int labelCount = 0; Symbol* symbol = symTable->findFirstAddressSymbol(pc, memLayout); disasm.clear(); while (pc <= int(endAddr)) { // check for a label while (symbol && symbol->value() == pc) { ++labelCount; DisasmRow destsym; destsym.rowType = DisasmRow::LABEL; destsym.numBytes = 0; destsym.infoLine = labelCount; destsym.addr = pc; destsym.instr = symbol->text().toStdString(); disasm.push_back(destsym); symbol = symTable->findNextAddressSymbol(memLayout); } labelCount = 0; DisasmRow dest; dest.rowType = DisasmRow::INSTRUCTION; dest.addr = pc; dest.numBytes = 0; dest.infoLine = 0; dest.instr.clear(); const char* s; const char* r = 0; switch (membuf[pc]) { case 0xCB: s = mnemonic_cb[membuf[pc + 1]]; dest.numBytes = 2; break; case 0xED: s = mnemonic_ed[membuf[pc + 1]]; dest.numBytes = 2; break; case 0xDD: case 0xFD: r = (membuf[pc] == 0xDD) ? "ix" : "iy"; if (membuf[pc + 1] != 0xcb) { s = mnemonic_xx[membuf[pc + 1]]; dest.numBytes = 2; } else { s = mnemonic_xx_cb[membuf[pc + 3]]; dest.numBytes = 4; } break; default: s = mnemonic_main[membuf[pc]]; dest.numBytes = 1; } for (int j = 0; s[j]; ++j) { switch (s[j]) { case 'A': { int address = get16(membuf, pc + dest.numBytes); dest.instr += translateAddress(address, memLayout, symTable); dest.numBytes += 2; break; } case 'B': dest.instr += '#' + toHex(membuf[pc + dest.numBytes], 2); dest.numBytes += 1; break; case 'R': { int address = (pc + 2 + (signed char)membuf[pc + dest.numBytes]) & 0xFFFF; dest.instr += translateAddress(address, memLayout, symTable); dest.numBytes += 1; break; } case 'W': dest.instr += '#' + toHex(get16(membuf, pc + dest.numBytes), 4); dest.numBytes += 2; break; case 'X': { unsigned char offset = membuf[pc + dest.numBytes]; dest.instr += '(' + std::string(r) + sign(offset) + '#' + toHex(abs(offset), 2) + ')'; dest.numBytes += 1; break; } case 'Y': { unsigned char offset = membuf[pc + 2]; dest.instr += '(' + std::string(r) + sign(offset) + '#' + toHex(abs(offset), 2) + ')'; break; } case 'I': dest.instr += r; break; case '!': dest.instr = "db #ED,#" + toHex(membuf[pc + 1], 2); dest.numBytes = 2; case '@': dest.instr = "db #" + toHex(membuf[pc], 2); dest.numBytes = 1; case '#': dest.instr = "db #" + toHex(membuf[pc + 0], 2) + "#CB,#" + toHex(membuf[pc + 2], 2); dest.numBytes = 2; case ' ': { dest.instr.resize(7, ' '); break; } default: dest.instr += s[j]; break; } } // handle overflow at end or label int dataBytes = 0; if (symbol && pc + dest.numBytes > symbol->value()) { dataBytes = symbol->value() - pc; } else if (pc + dest.numBytes > endAddr) { dataBytes = endAddr - pc; } else if (pc + dest.numBytes > currentPC) { dataBytes = currentPC - pc; } switch (dataBytes) { case 1: dest.instr = "db #" + toHex(membuf[pc + 0], 2); dest.numBytes = 1; break; case 2: dest.instr = "db #" + toHex(membuf[pc + 0], 2) + ",#" + toHex(membuf[pc + 1], 2); dest.numBytes = 2; break; case 3: dest.instr = "db #" + toHex(membuf[pc + 0], 2) + ",#" + toHex(membuf[pc + 1], 2) + ",#" + toHex(membuf[pc + 2], 2); dest.numBytes = 3; break; default: break; } if (dest.instr.size() < 8) dest.instr.resize(8, ' '); disasm.push_back(dest); pc += dest.numBytes; } } debugger-master/src/SimpleHexRequest.h0000644000175000017500000000252413560352104017700 0ustar shevekshevek#ifndef SIMPLEHEXREQUEST_H #define SIMPLEHEXREQUEST_H #include "OpenMSXConnection.h" /** * A set of helper classes if code needs to read openmsx debugables into an array of unsigned chars * if class A needs to read a given debugable then this schem will suffice * - Class A inherits from SimpleHexRequestUser * - Class A can reimplement the DataHexRequestReceived if it wants to react when new data has arrived * - Class A can reimplement the DataHexRequestCanceled if it wants to react to failures of the request * - to read the debuggable into the memmory just create a new SimpleHexRequest, fi. * new SimpleHexRequest("{VDP status regs}",0,16,statusregs, *this); * */ class SimpleHexRequestUser { protected: virtual ~SimpleHexRequestUser(); virtual void DataHexRequestReceived(); virtual void DataHexRequestCanceled(); friend class SimpleHexRequest; }; class SimpleHexRequest : public ReadDebugBlockCommand { public: SimpleHexRequest(const QString& debuggable, unsigned size, unsigned char* target, SimpleHexRequestUser& user); SimpleHexRequest(const QString& debuggable, unsigned offset, unsigned size, unsigned char* target, SimpleHexRequestUser& user); virtual void replyOk(const QString& message); virtual void cancel(); unsigned offset; private: SimpleHexRequestUser& user; }; #endif // SIMPLEHEXREQUEST_H debugger-master/src/DockableWidgetArea.h0000644000175000017500000000135013560352104020066 0ustar shevekshevek#ifndef DOCKABLETWIDGETAREA_H #define DOCKABLETWIDGETAREA_H #include "DockableWidgetLayout.h" #include class DockableWidget; class QPaintEvent; class DockableWidgetArea : public QWidget { Q_OBJECT; public: DockableWidgetArea(QWidget* parent = 0); private: void paintEvent(QPaintEvent* e); void removeWidget(DockableWidget* widget); void addWidget(DockableWidget* widget, const QRect& rect); void addWidget(DockableWidget* widget, DockableWidgetLayout::DockSide side, int distance, int width = -1, int height = -1); bool insertLocation(QRect& r, const QSizePolicy& sizePol); void getConfig(QStringList& list); DockableWidgetLayout* layout; friend class DockManager; }; #endif // DOCKABLETWIDGETAREA_H debugger-master/src/CPURegs.h0000644000175000017500000000103113560352104015671 0ustar shevekshevek#ifndef CPUREGS_H #define CPUREGS_H struct CpuRegs { static const int REG_AF; static const int REG_AF2; static const int REG_BC; static const int REG_BC2; static const int REG_DE; static const int REG_DE2; static const int REG_HL; static const int REG_HL2; static const int REG_IX; static const int REG_IY; static const int REG_PC; static const int REG_SP; static const int REG_I; static const int REG_R; static const int REG_IM; static const int REG_IFF; static const char* const regNames[14]; }; #endif //CPUREGS_H debugger-master/src/VramBitMappedView.h0000644000175000017500000000262213560352104017756 0ustar shevekshevek#ifndef VRAMBITMAPPEDVIEW #define VRAMBITMAPPEDVIEW #include #include #include #include #include #include class VramBitMappedView : public QWidget { Q_OBJECT public: VramBitMappedView(QWidget* parent = 0); void setZoom(float zoom); void setScreenMode(int mode); void setLines(int nrLines); void setVramSource(const unsigned char* adr); void setVramAddress(int adr); void setPaletteSource(const unsigned char* adr); void setBorderColor(int value); void mousePressEvent(QMouseEvent* e); void mouseMoveEvent (QMouseEvent* e); public slots: void refresh(); signals: void imageChanged(); void imagePosition(int xcoormsx, int ycoormsx, int color, unsigned addr, int byte); void imageClicked (int xcoormsx, int ycoormsx, int color, unsigned addr, int byte); private: void paintEvent(QPaintEvent*); void decode(); void decodePallet(); void decodeSCR5(); void decodeSCR6(); void decodeSCR7(); void decodeSCR8(); void decodeSCR10(); void decodeSCR12(); void setPixel2x2(int x, int y, QRgb c); void setPixel1x2(int x, int y, QRgb c); QRgb getColor(int c); QRgb msxpallet[16]; QImage image; QPixmap piximage; const unsigned char* pallet; const unsigned char* vramBase; float zoomFactor; unsigned int vramAddress; int lines; int screenMode; int borderColor; }; #endif // VRAMBITMAPPEDVIEW debugger-master/resources/0000755000175000017500000000000013560352104015500 5ustar shevekshevekdebugger-master/resources/resources.qrc0000644000175000017500000000125213560352104020221 0ustar shevekshevek icons/openMSX-debugger-logo-256.png icons/connect.png icons/disconnect.png icons/pause.png icons/break.png icons/run.png icons/stepinto.png icons/stepover.png icons/runto.png icons/stepout.png icons/stepback.png icons/breakpoint.png icons/watchpoint.png icons/pcarrow.png icons/symmanager.png icons/symman.png icons/symfil.png debugger-master/resources/icons/0000755000175000017500000000000013560352104016613 5ustar shevekshevekdebugger-master/resources/icons/symfil.png0000644000175000017500000000031713560352104020625 0ustar shevekshevek‰PNG  IHDR 2ЯН pHYs  šœtIMEж.С^ŠtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“3IDAT•cиѓџ?ќЧ‡2001€ РЊн$œ I6‘ BВLЄŽё*$&РAъrуй йU+IENDЎB`‚debugger-master/resources/icons/pause.png0000644000175000017500000000044013560352104020434 0ustar shevekshevek‰PNG  IHDRѓџa pHYs ‰ ‰7ЩЫ­tIMEе9Iч$atEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“„IDAT8cxњє)%Ю8У`Ьpsў*м ЁЇ9ттџђp т#Ж„A?сФ)HLLФ)‡тlŠ@šЕфCqЪ4Є— ё!bЎ@$к‚Ў#dяњ€-ЙТ Р%‡br†eЄ”ˆ!‘qa˜!0>,ja|;сл–АЄОIENDЎB`‚debugger-master/resources/icons/pcarrow.png0000644000175000017500000000040713560352104020777 0ustar shevekshevek‰PNG  IHDR Vu\ч pHYs  šœtIMEе$дЮыtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“kIDAT(‘cx№р:>ў<ЃЫa€pooя0Fз„UHсМџ џMncjB1 ƒ4А}cРа7 i@зФ€l> гDОѕЅ ІФ†; —Їaу V˜-СJ•ˆУ—4ХG5М‚fV№IENDЎB`‚debugger-master/resources/icons/break.png0000644000175000017500000000053413560352104020407 0ustar shevekshevek‰PNG  IHDRѓџa pHYs  šœtIMEе#ŠзЉ$tEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“РIDAT8c`4рџџџ$aМ4здќЗедќo (Ц vSuѕЂ ˆ№іўяЭШј6Pш ƒи Бp ^Z€6{r?€„цЮ§џЪ‰фъЫЪўу4фTmAмyѓ@ЪРјT $gЋЁл}~~А“A6У4У№Јw@jhgВў!iFі‚ >/€Ђ 9C1r Vт6„УёDcАЛ;ўh„с†ђr”„rve~>q ‰ьЄ<`^ŸJjЄiCIENDЎB`‚debugger-master/resources/icons/openmsx-debugger.ico0000644000175000017500000036211613560352104022573 0ustar shevekshevek€€(Ші€€(LЩ€€h(F@@(2Ў=@@(жo@@h ў…00Јf00Ј­00hЖЛ Ј Т ЈЦЮ шnзhVкhОн(&у(€Р'(,-+-,./113:<22$$  .09;FHZ^os…’—ЁЇЋБВЙИПОХЦЭЫгазглзолумфдлˆ79RThl}‚”ŸЅ­ГЙПУЪЬввкирмфоцршпчнхктенЯжШЮОХГЙІЌ—†‹sw]`EG)*           !?AVYqu’Ї­НУЧЮаиир пч рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршКСHK{€­Джн рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршТЩ–œ]`  -$$<44MFFhbb}xx…‡„„†ƒƒ‚€€urr\XXA>>300   .0PStyš МУвкироц рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршvz Эд рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршJ€‚Š‚‚ЌЈЈШХХнммъщщєѓѓїїїњњњќќќ§§§§§§§§§§§§ќќќљљљіііёёёхффжжжМЛЛžœœwvvPNN*)) PR Ž“СШип оц рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршглЃIM./11DFЁЇ рш рш рш рш пч рш рш рш рш рш рш ршЦЬ‘–hkg|}­БВњњњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџппп555VVVwvv———ИИИйййЖЖЖeeeООО§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўыыыЇЇЇY[[ -- <>`cˆЊАСШЬгвкирмф оц пч пчнфиразЧЮВИ‚‡KN') () GI­ВпчмфдлЧЮЖМ І…Šmp7ƒo†‡””нррўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўџџџўўўЬЬЬ€€€еееџџџџџџ‡‡‡"""CCCddd„…„ІІІЦЦЦццч№№№ЭЭЭћћћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћћћъъъЛЛЛ“““YZZ055#11 (),.7:@CFIJMMPLODF23 ! ""QQQRR ЁАТТдноєѕѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђђђ†††###†††###100RRQrrr’“’ДДГддд№№№хххвгвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўрппRNN 58‡kjёююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЉЉЉ###?>>```€€€ЁЁЁТТТтттђёёзззрррџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўгвв:447hCAфннўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒƒƒ&# ,-,NNMnnnŽŽААЏаааююющшщЦЦЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќЕВВ!  8KЦЗЖ§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёё{{{-*&":::\\\|||œœОООооођђђлмлЮЮЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџііі€{{  :<srїѕѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїŸŸŸkiiGEE40,($!(((HIHiijŠŠŠЋЋЋЬЬЬььььььЪЪЪюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўнммB88  <Y*'мгвўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђђђ†……  973/,'$  666WWWxvw˜˜˜КККкккєєєрррФФФџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќžšš  >@—zxњјјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљљљ”’’ 0>:62.*&"EDDeff†††ЅЄЃЧШЧшшш№№№вввзззџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтссD::жъ?RгЦХўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТТТ4,, D@<851-)%"FFFttt”””ЕЕЕжжжђђђфффЕЕЕѕѕѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњњњ††@yPMђяяўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџсссOOO0GC?<840,($  aaaЃЃЃУУУфффђђђжжжЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЮЫЫ)CG ІŠ‰ћњњџџџџџџџџџџџџџџџџџџџџџџџџџџџРРР  LJFB>:72/*'#YYZУУУяяяшшшШШШпппџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыъъTHGDOЫКЙўўўџџџџџџџџџџџџџџџџџџџџџ§§§ˆˆˆ "%#!.QMIEA>962.*&"%%%@@@```џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњњњ|rrF_($нвбўўўџџџџџџџџџџџџџџџџџџ§§§eee &*(&#!QTOLHD@<841,)%!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§ ˜˜ Hp=:юшшўўўџџџџџџџџџџџџџџџљљљeee -.,*(&$!.ZVRNKGC?;83/,($  ˆˆˆџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўФОО&IxFBѕђђўўўџџџџџџџџџџџџљљљ___ .21.,*(&$" *\YURNJFB>:62.*&# ЇЇЇџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўвЮЮ*Ju@=јѕѕџџџџџџџџџџџџўўўnnn57530.,*(&#C`\XTPLHD@<952-)&" ёёёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнкк+Kj2-љїїџџџџџџџџџџџџƒƒƒ9<:8541/,*( fc_ZWSOLHD?<840,($  yyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђ№№-M~JGїєєџџџџџџџџџГГГ>@><:8641/-+9ifb^ZVRNJFB>;730+'#  ”””џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№ююC.,Nq84№ъъўўўџџџЩЩЩ>DC@><:8632/-flhd`\XUQMIEB=:62.*&" )))џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўурр8 Po3.ътсўўўххх7IGECA?=;8642&6sokhc_[XTPLHD@<851-)%! ДДДџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўкжж6Ri($ргвњњњ333NLJHFCA?<:864^vrnjfb^ZVSOJGC?<840,($   yyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЫФФ3 SbвПО~~~ MPNLJHFCA?=;95z x upmiea]ZVQNJFB>:62.*'# yyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЖЌЋ, !TZ —ƒ‚<URQNLJHFDA?>;3' { wtolhd`\XTPLIE@=:62.*&" mllџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЃ•”(#VQ  TfWUSQNLJHFDB?= C‚ ~ z v rnjgb_[WTPKHD@<840,)$! oooџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќ˜ˆ†'$W9nbZXUSQOMJIFDB@I… € } y uqnifb^ZVRNJFB?;74/,($ БББ§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїіі€lj(&7lj^\ZXVTQOLKIFDB!D‡ „ € | xtplhda]XUQMIFB>:62.*&#ѓѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№ээ]@?('Vne`^\ZXVTROMKIGE-4Š † ‚ { wsokgd`\XTPLHDA=951-*%!d``џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўчууJ(&)) 4njeca^\ZXVTRONLIG;%Ž ‰ †  ~zvrnjfb_[WROKGD?<840,($!ХХХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЩПО<+* kmjgfca^]ZXVTRONKJB Œ ˆ „ € } xuqmiea^ZVRNJFB>:73/+'---џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќЈ––1,,Annljheda_][YWTRPNLI Ž ‹ ‡ ƒ  | xtplhd`\XTPMIEA=962(жжжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїіі‚ig0.-7pnpnljhfda_][YVTRPNL0R Ž Š † ‚ ~ z wrokgc`\XTPLHD@<4YYYщщщџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьшшY540/# sossqoljhfdb`][YWTSQNH Š  Œ ‰ …  } yvqnjfb^ZWRNJE0sssкккўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЪООC10D€ {w vsqnmjhfdb`^[YWUSQN?1T~ Œ ˆ „ € | x tplhea]YS:$ №№№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћњњ Š‰632 v | zwusqomjigdb`^\ZWUSQOJ." 3FDLLG@DB=1 BBBsssССС§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёююkGE544 9€ € ~ | z xvsromkigdb`^\ZXUSRP_*'лОМѓѓѓKKK000///111:::GGGTTS[[[RRReffghh”””лллџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўаФФJ665x€ ‚  ~ | zx vtromkigdca^\ZXVIž{yќћћџџџввв"##HHHjjjŒŒŒЌЌЌЭЭЭььььььЬЬЬЌЌЌzzz§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћњњ„‚;876ˆ ‡ … ƒ € ~ } z xvtrgYMA!8#!0$$*%$%$$"!! "A<;ddd†††ЏЏЏccc 222QQQzzzВВВлллђђђпппОООІІІџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўъффe:8:99: ‹ ‡ † „   } w dP)&?43GGGccc~~~–––ЋЋЋННМЪЪЪдддййййиигггШШШЖЖЖžžž~~XXX666MMM```rrrŸ ŸЪЪЪЯЮЯААА‚‚‚ыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўМЉЈD ;::L Œ Š ˆ † „ qW2.HCDeeeŒ‹‹ЎЏЏКЛЛœœœ‚‚‚kkkZZZNNNGGGDDDFEEKKKUTUbbbsss‡‡‡Ÿ ŸКККзззааа–––SRS++,PQQvvvŠŠŠ‚‚‚xxx„„„‹‹‹џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓ№№zRP><<<| Ž Œ ‡ p%!TB@`__‰‰‰ААЏ™™šlllCCC)))&'HvyГсфё§§ј§§№ќ§мљќЩїњЦїњžѓјVъєхђ&ъі;žЄI|Z``~~~Ё ЁШШШммм”•”DDDHHHiiifffRRRлллџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўШИЗN?>==‚   w(#YKJlkk———ЂЂЂhhhA,*;\Z J 9 !**#NRBknjŸЂŽШЬсш‡яѕѓјmч№.ЬжЅАpv:=%@BˆŒŒггг­ЊЊBRSŠ‹ŠЎЎЎйкйДДДMMM;;;іііџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџє№№‚ZXA@65   ƒdKJkkj”•”“““NNN<I [ZZYYWH2&%fj†afDH4735 9< DH,Y\t‚ЎЊЉЪЧЧяююџџџЛЗЗ œІJКРqЈЋЊЉЊзззФФФABB///ЦЦЦџџџџџџююю™ŸŸt‹ŒOŒŽ{€qupt}2”ŠЅЅ‘ššЫЭЭ§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЧОНw[Y: "   q96eee‡‡‡’““LLL%f^]\[ZYXV\ l2-ƒsrКгеОабМССЛЙЙКИИМММТФФбббъшшўўўўўўўўўўўўЦХФbhцєрю7бк|ГЖДДДтттЇЈЈGGHHy|‹ ФЫ рш рш рш рш рш рш рш рш ршЦЭ0ЁЌ­дййџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ—aB@+('%"   ihiYYXvvv•••^^^he_^\[ZYXW[ €C?ЬАЎ§љјџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўлккFA@:>чірюрюрю;епВВВЩЩЩсрр^^^#&ЌВz†]… ob``bqZ…~†Ыв рш ршХЬbГЖлннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџš41/-*)&$"   mnnmmm€€„„ƒ-,- da_^\\[ZX[ n(#šifюччўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўєєєŒ…….1мъсярюрюрюоыŽХЩФФФххх˜˜˜ zОМЕКИКМРЗ€LvНФ рш ршШЯЄХЦљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:8631/-*(&$"   ssssss†‡‡gfgnha`^]\\ZY^€C>О žљјјўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўИГГЂ­уђрюрюрюрюся5итЫЫЪпппЮЮЮgПОООПОППРР~rˆ пч рш'уъЃбгъъъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁ@><:7521.,*(&$!   xwwwwx……„LLL khb`_^]\Z\ l" rpъррў§§џџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЬЪЪ()lrхѓрюрюрюрюрюрю7мчЁзлпопннн(((]РРППППОРПР\57 Ъв ршршQексффџџџџџџџџџџџџџџџџџџ§§§ўўўЂ€~FDB@><97521.,*(&$!  |||{{z‚??? gfa``^]]Z`?;Кš—ќњњўџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўъъъqrrDIпэсярюрюрюрюрюрюмюЈптцццффф,,,]ПНРРРРРРŠФЫ рш ршLкпчшшџџџџџџџџџџџџџџџЊ‡…MKHFDB@=<97520.,*(%#!  ~~~}}~:99 yfcba`_^][b VSжТРўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўВЏЏ›ЅфђрюрюрюрюрюрюрюоюЏцъюююццц()(gРПЅКРДp .0ˆлу рш`оучээџџџџџџЊ‚]QOMJHFDB@=;97520.,*(%#!   ††…‚‚‚zzz;;; mhccba`_^^v0*Ж‘ѓююџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЮгг!/0EJхєрюрюрюрюрюрюрюрюоюЗюёїїјррс€ППЖp #%˜žрш ЉЏjn78*LSQNMKHFCB@=;87420.,)'%#   ‹Š‹‡‡‡wwvBBB mjddba`_]cŠNJаЙИў§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўѓііˆŠŠ!#МШтёрюрюрюрюрюрюрюрюныОѕљќ§§ааа b6WZйр рш ршЈ­^c)RQNLJHFDA?<:86420.,)'$#  zzzPPP  kiedcba`^d ’XTпЮЮџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўСХЦ !]bлшсярюрюрюрюрюрюрюрюмъјјјѕѕѕ˜˜˜23ЮжршршсяПЫ!!QPNLJGECA>=:86420-+)'$" ’’’‚‚```hhfdcba`_nЊ|zьутџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўыююryy ~†цєрюрюрюрюрюрюрюрюрю@х№юююђђё___ (* ОЦрэсясяТЮ$RPNLJHECA?=:8642/-+)&%" –——jjj$$$hgfedcb`a‚>9бИЖјєєўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўОТТ 58амс№рюрюрюрюрюрюрюрюрюvфыфффррр.0оьсясяся€ˆGRPNKJGEC@?<:8631/-+)&$" œ›œ™™™ttt???liggfddc`g žheьттў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўя№№|}}Z_цѕрюрюрюрюрюрюрюрюрюрюЈптоооІЅІ.0Шд˜Ёw~qxU[wсясясякш&TRPNLJGDC@><:8531/,*(&$"  žžŒŒŒXXXmjhgfedc`jЊzwѕ№№ўџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЬЬЬ&"".1еусярюрюрюрюрюрюрюрюрю:пщеееуттEDEˆсясясярюпэЏКelЬимърюсяILVTRPMKIGDC@><:8531/,*(&$" ЃЃЃ   iii222nlihgfedanБ…‚јѕѕџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўїїїš—— ‰хєрюрюрюрюрюрюрюрюрюрюiиоЫЬЬППП!йцсясясясясясякчz€ekЩж­ИсяhoXVTQOMKIFDB@><97531.,*(&$! ЅЅЅŒŒŒMNMmljhgfeecw'"РœšћјјўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўуффZ[\'*ГОфђрюрюрюрюрюрюрюрюрюрюХХЦгггQRQ†Žсясясясясясясясязф[`ДПСЭсяipZXVTQOMJIFDB@>;:7530.,*(&#!ЈЈЈgff010mljihgffe„:4бЗЖќќќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўУФФ$//LPШдуёрюрюрюрюрюрюрюрюрюbазМММЖЖЖ *,сясясясясясясясясяся€ˆ ovсясяJM\ZXVSQOLJHFDB@=;97520.,*(& ­ЌЌ———KLK###lkjjihgff ŒHDсаЯўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўјљљЃЄЄV[ФбуёрюрюрюрюрюрюрюрюсюЖЖЖЬЬЬ>>>ЄЏсясясясясясясясясясяrz– сякш+ ^\YWUSPNLJHFDB?=;96420.,*%АЏЏrrr888&%%mlljihgem ЄnjьттўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўѓѓєˆˆˆEJИФт№рюрюрюрюрюрюрюрюˆНРАЏА••• QWсясясясясясясясясясяны OTпэся‰Q `^\ZWUSQNLJHFCB?=;86420.( ДДДЎЎЎPPP---lllkjihfpЎ{xѕ№№џџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџюяяxvuMQицрюсярюрюрюрюрюрю3гоІЇЇХХХ дссясясясясярюЪжицЪз– hnЙХрюсяТЮdb`^[YWUSPNLJGFCA?=:8642, ЗЖЗ“““@@@.-,џџџџџџllmlkjhfuО•’ћјјўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџњњњЩЩЩxxxKKK[[[ŸŸŸщщщџџџыыыrppipфђрюсярюрюрюрюрюрюЂЁЂВВВUUU ™Ђсясясязфу№сяЬй  ЉАМкч*хёу№сяОЪ $&)Zdb`^\YWTRPNLIHECA?=;86. ЙЙЙppp888џџџџџџnnmlkjie-'кУС§ќќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўфффrrr((( DDDЌЌЌўўўыыыyxx{„фѓсярюрюрюрюрюрюPОХ™™™“““]bсясяся‰‘@OPЈБ2цђЖіњЊєјІѓј­єљ8кфz‚*+Cfdb_][XVTRPMLJHEC@><:&МММOOO666џџџџџџoonmlkje‡94№ццўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўцццiii ...ЌЌЌџџџ№№№\bЦвфђрюсярюрюрюMЛТ’’’БББ*,сясясяUZњњњЈЊЊb}Usuq|~{‚‚f{|821%*,-2ffca_][YVTRPMKIGEC@:РРРЏАЏ<<<888џџџџџџџџџpoonmlkfŒA<ћјј§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўћћћЈЈЈ DDDщщщџџџєєєЎЌЌ:@@48ŸЉцѕфђсярюрюрюŒВВВ000Хбсярю(9:џџџџџџџџџџџџџџџџџџџџџРДД4 ,./1Zhfca_\ZXVTQOMLIGD. УУУ•–•:;:>>>џџџџџџџџџppoonmlfŒ@;њіі§§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўсссVVVŸŸŸўўўўўўњњњдвв||} %';?†дрцѕт№рю‡ˆˆ˜˜˜\\\ ЇсяТЮtuuџџџџџџџџџџџџџџџџџџџџџіѕѕcDB.012Kihfca_\ZXVTRONK5ЦХХ|||<<ljgeca_\ZXUTRAШШШfff?@?џџџџџџџџџrqpponmhˆ72ыоо§ќќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўУУУ555›››ttt KKKўўўўўўўўўўўўўўўўўўцццЛКК~xx&',/KP>fhxxx_cсяmrўўўџџџџџџџџџџџџџџџџџџџџџџџџюъъZ424568hkigeb`^\ZW?ЫЫЪRRREEEџџџџџџџџџrrrpooni†4.цдд§ќќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўггг,,,"""КККњњњцццttt xxxўўўўўўўўўўўўўўўўўўўўўўўўя№№ЬЭЭОНМПТТšsss˜˜™JLЬи“”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆlj678:`mkigeb`^DЭЭЮBBBLKKџџџџџџџџџџџџqqrqppnj†2,уаЯў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў№№№zzz,,,фффџџџњњњ›››(((ЩЩЩўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџИИИnnnœœœ9; IMёђђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩЛК89:<XomkifdHааа445RRRџџџџџџџџџџџџqqsrqpok†1,таЮўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўШШШ:::nnnфффККК555 rrrњњњўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЕЕЕhhhžžž#,+‹‹‹џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџє№№O;<>QqomgHввв++,YYYџџџџџџџџџџџџqrtrrqpl‡2,фааџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўјјјВВВ:::,,,""" iiiфффџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўВВВcbcœœœ(((§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњјјg<9=>?Lsh5 еее'&&___џџџџџџџџџџџџџџџt qussrqlˆ4.цедўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўјјјШШШzzz,,,VVVЈЈЈцццўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўАЏА^^^™™™+++џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўŒjh?ABHззи'''ddcџџџџџџџџџџџџџџџ][oqvutrrl‹60ъмлџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў№№№гггУУУШШШсссћћћўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў­­­XXX””•000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГ›šBBDHккк,,,fefџџџџџџџџџџџџџџџkoqvutssnŒ50щйиў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЊЊЊSSS;;:џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжЩШDEFHммн667eeeџџџџџџџџџџџџџџџџџџmpwuuttp†,&иМКћјјўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЈЈЈNNN‹‹‹KKJџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяиииџџџјііFGHIпппGGGaaaџџџџџџџџџџџџџџџџџџhqxvvutr‚$С“јєєўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЅЅЅHIH‡‡‡```џџџџџџџџџџџџџџџџџџџџџџџџџџџЫЫЫ|||ђђђџџџѓяяHIJKссс^^^YXYџџџџџџџџџџџџџџџџџџџџџYuyxwvus~Д|yљѕѕџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЂЂЂDCC„„„zzzџџџџџџџџџџџџџџџџџџёёёЌЌЌpppeeeцццяяяииичооJKLMффф||}KKKƒ‚‚џџџџџџџџџџџџџџџџџџџџџuvyxvus|ДzwњііўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўBBBBBB€€€XXX€€€‚‚‚‡‡‡‡‡‡VVV333ЪЪЪџџџЫЫЫ|||ђђђтизLMNPцхцЂЂЂ787ˆˆˆџџџџџџџџџџџџџџџџџџџџџџџџrtzywvt| Аrnђщщўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў==>>€€€ТТТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџvy~~| |z}ЄYTюрпџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўWWWppoџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќњњ˜^Z`ab`іѕіЎ­Ў(((ЧШЧџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpu€~}||{2+ЮІЄћљљўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЦЦЦFFFrrrЙЙЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфжеpbcb]јјјіїі878ƒƒƒбббџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgs€ ~}|{„ЖyvѕююџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўRSS€€€oooљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ќќЌzxddedјљјКККЪЫЫџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ*v{~}|~ ›D>йКЗќћћџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў‹‹‹PPPsssОООџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтаЯsfggbћњћљњњVVVffgсррџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpu€~~|ˆ Пˆ„іяюўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўФФФ‚‚‚‚ўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљііœ\XhiigћћћсссДДДъъыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтаЯu‚  €€~|€ŸLEнСП§ќќџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўMMMmmlpppнннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ќќЗˆ…m kkkeќќќŸŸŸ! пппѕѕєџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџдБЏ| ‚ €~|ˆЙ{xяттўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўMMMGFF}}}wPMнХФўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§ќќШЄЁs lmmk\ў§ўќ§§fffPPPљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљѕєЭЅЂ‚€€~€ ›A;иЖГќњњџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўУУУ $$$€qa`p "ЬЇЅќњњџџџџџџџџџџџџџџџџџџџџџџџџџџџљѕєР”‘xnnopg§ўўёёё...|||њњњџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§ёчцйЗДІPI‚‚€€~ˆЖrnюпоўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўУУТ zzzwqprrrv Іe`рЪШћљљўўўџџџџџџџџџџџџ§ќќоЦХŸYTs pqqrmўўўрср‹‹‹ёёёџџџџџџџџџџџџџџџџџџџџџџџџџџџѕюэмПНмЙЗТ…‚ށ€ €€ ’/(٘”і№яџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўТТТ rqr}}}w.(ttttt |šMGХ™–вАЎі№№цдвХš—˜JD~rrsssreўўџжжжŒŒŒццчџџџџџџџџџџџџџџџџџџџџџџџџќњњщижйДВжЎЌвЅЂ­]X‡ ‚C=жАЎњјјџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўТТТ kll‚{?:xww vvvuutttutuuuuuvvkџџџддгнннџџџџџџџџџџџџџџџџџџџџџџџџёццгЎЌдЉЇбЄЁЮŸœЦІPJ† €… ЇUPпТС§ќќџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўТТТ jjj„……HC{ zzy yx x xww www wwwwwwxqџџџзззgggгггЯЮЮџџџџџџџџџџџџџџџџџџџџџљіѕпЦФбЃ Яž›Ь™–Щ”‘ЧŒРƒ€ІPLŒŠАfaцаЯў§§џџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўJIJ kkkˆˆˆƒJE~ } | |{ {{ zz zzzy y zy y zz zv dџџџттт...>>>ЙЙЙУФУџџџџџџџџџџџџџџџџџџымлЪž›Э˜•Ъ“ЦŽŠФˆ†С„€О€|ЛzvЌ^YЂKEК|wъзж§ќќўўўџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўУУУHHI**)qqqŒŒŒ†FA€ €   ~ ~ ~} | | | | | | || || | | x hџџџђѓђgff‘‘‘КККЖЕЖџџџџџџџџџџџџљіілНЛЩ’ЧŽŠФ‰…Т„€П~zМyuЙupЖpkДkgЙxsЯЂŸэнмњііўўўџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџ‡†† ?@@~~~‘‰‰ˆ60„ ƒ ‚  ‚ € € €    ~ ~ ~ ~ ~ ~ ~ ~ ~zlџџџўўў   PPPЄЄЄЊЋЊџџџџџџџџџџџџшижТŽ‹Хˆ„ТƒО~zМyuЙtoЗojДjeАd`Ўa\ДmhШ•‘фЬЪљѕє§ќ§џџџўўўўўўўўўўўўўўўўўўўўўўўўџџџФФФIHH !^^^‰ˆˆ–‚Š† … … „ „ ƒ ƒ ‚ ‚ ‚    € € € € € € € { lџџџўўўуууWWWdddŸ ŸœœœџџџѓььЭЅЂО|Р}yНxtКsnЗniДhdБd_Ў_ZЋZUЈUPЊZTИwsжАЎ№ффќњњў§§џџџўўўўўўўўўўўўџџџФФФLLKDDDwwwššš•[WЉ ˆ ˆ ‡ † † † … … „ „ „ ƒ ƒ ƒ ƒ ƒ ‚ ƒ ‚ {gўўў§ќќМММ888___ŽŠŠŠm{—(  <5ІJDЊSM­YS­ZTЋXSЉTNІNH D?ž@9ЅNHЗsnвЈІ№уу§ќќўўўџџџџџџŒŒŒ;;;iii•”” ˆ†’,$ Œ Œ ‹ Š Š ‰ ˆ ˆ ‡ ‡ † † † † † … … … † … u]ўўўќќќњћћААА>>>GGGrrr€€€z{zupos}‰ ˆ ‡ ‡ † … … „ ƒƒƒ ˆ š;4ИuqІ†„…{{OMM&&&>>>ghg””“Ј›ššJD   Ž Ž  Œ Œ Œ Š Š Š ‰ ‰ ‰ ˆ ˆ ˆ ˆ ˆ ˆ ~ lќќќњљњјјјФФФfff$$$DDD^^^llliihlROr83p4/n0+l-(j*&g($d&!a$_"[V--.))($$$""")))555LLLvuuŸ  ГГГБББ‡_\{†      Ž Ž  Œ Œ Œ Œ Œ ‹ ‹ Š Š Š € vXїјјіііььь­­Ўhhh../***888BBBHGHJJJIIIGGGCCC>>>:9:454112././//121777PPPtssšššЙЙЙКККИИИRs Œ       Ž Ž Ž Ž   ‰ | pPѕѕѕѓєєђёё№№№дддЇІЇ€€€```HHH677+++&&&%%%*+*444BBBSTThhhœœœИИИЦЦЦУФФСССППП^o„ |  ‰ Ž Ž ‰  | ƒ n^яяяэьэыыыщщщцчцфффтттррроннлллйййжжждддввбЯЯаЭЭЭЫЫЫџџџџџџџџџџџџџќџџ№џ€џџјџџџќџќРџќџќџќџўџўџџџџ€?џџРџџрџџџ№џџџјџџџќџџџџџџџџџрџџџџџр?џџџџџРџџџџџ€џџџџџ€џџџџџџџџџџџџџџўџџџџўџџџџўџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџќџџџќџџџќџџџќџџќџџќ?џџќ?џџјџџјџџ№џџ№џџрџџрџџРџџРџџ€џџ€џџџџџџџџџџџџџџџўџќ<џ№|џсќџуќџЧјџјџјўјў?јќјќ№јџ№?јџ№?ёџ№ёџ№џуџ№џуџ№џуџ№џЧџ№џЧџ№џЧџ№џЧџ№џџџ№џџџ№џџџ№?џџџ№џџџџ№џџџџ№џџџџ№џџџџ№џџџџџ№џџџџџ№џџџџџ№џџџџџјџџџџ‡ЯјџџџџЧ‡јџџџџЧјџџџџЧјџџџџЧќџџџџуќџџџџу€ќџџџџс€|џџџџё€~џџџџёР>џџџџјРџџџџјрџџџџќpџџџџќ0џџџџў8џџџџў?џџџџџ?џџџџџ‡џџџџџУ€џџџџџџсРџџџџџџррџџџџџџ№xџџџџџџќџџџџџџўџџџџџџџрџџџџџџџ€ј?џџџџџџџр<џџџџџџџјџџџџџџџџўџџџџџџџџџ€рџџџџџџџџџ№ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(€@pu9/сь&TWХˆ‚ ?@?˜?:y~фспŸ=4КМК}€~UWVˆ 6/218;)) ~„BOQB))o0*! !ЕАВпш0•'ГЗЕ,$#№ѓё‹jjЂYRCУГВ+$x?<e r"kstnущX``7Ѓmj+Р ž36днояыьицHхё{rq“—n514зтO9@Ax{zZ'#,Q./Ў›™кРОVW0, Ява“–”Ье>'$„€€§љћEHG`cQгВАИЭЫ^_^“ЪЬ›ŸЬРПaPСХOшёqІЊŸ№ѕk1ЅЈІ#::ЦЭФ‘Žјћљ …ZX)Е{zЛytCqq JGEˆ d rus‰=8797p†B>—[RфвбХШЦxusПєјNPNegedCB(*’ СШїѓєrˆвЇЃˆžœѓќ§W\6^ Š;…‹ПУСABђєRmok€ гк_ГИД—ƒ‚{PN­сх$00русd%  †2+Kx] ŠšKHOќџўmЏИоїљ<43n ЅNHЬ™2hkГjeGIv ?‡ˆСр№`f]JGŸ\W*++r^^qGIœЄ7*(Ѕ­Ÿфэюƒ†„‹‚NFEзйзлтhmпед;[…Id<9Й=ЛТLPPJ~€cmфє0Ќ|x03dqtэтрџќїшыщЋЏ­џ§њ@SR+>A$%$"IEwЪЧЧЃФШ ЅЂЂBжм€ W 1žЂ^­ZSknl vz<fˆ‹ŽŒ…nl..............................................................................................................a a   vƒƒƒƒ3о........................aЗaЗ aa aaЗ aaaa ЗaaaaaaЗaaa.........ССС____СС_a_Н_a_aa.......................... ƒВ‹;РЊЊд…ee——ЫЫЫ—...................aavеЬ;РУдee—ЫЫЫЫЫ—Le…ЊУРQВƒ aНСС_a_С___ССС_____СС___aН ЗЗЗ.............. ‹;УдeLЫ9ЫЫЫ9Ы9ЫЫ9…љ................ВЊЫЫЫЫЫЫ9Ы9Ы9ЫЫ9Ы9Ыe;QљССnСH!ЌЩU:ШNNN~UЛ&Z_____ЗЗaЗЗ......оеРд—ЫЫ9Ы9Ы9Ы9Ы9Ы9ЫЫ ................LЫ9ЫЫ9Ы99Ы9ЫЫ9ЫЫЫЫ9ЫЫЫзNы 5†gggЈЈЈЈgg"" Ъ ю~qЛZ_aН_ЗvЬР…—ЫЫЫ99ЫЫ9ЫЫЫЫЫ9Ы—В.................9Ы9ЫЫ9Ы9ЫЫЫ9Ы9ЫЫ9Ы9NЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgт}WUчље;…ЫЫЫЫ9Ы9ЫЫ9Ы9Ы9ЫЫЫ9Ы9Ыдv.................ЫЫ99Ы9Ы9ЫЫ99Ы9Ы9Ы9дdќЪggЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфЈЈЈOтV—99Ы9ЫЫ9ЫЫЫ99Ы9Ы999ЫЬ...................ЫЫЫ9ЫЫ9Ы9Ы9Ы9ЫЫ9Ы—тЈЈЈЈЈЈЈЈЈЈЈOЈЈЈЈЈЈOOЈЈOЈЈЈЈЈЈЋ\ЫЫЫ99Ы9ЫЫ9ЫЫЫЫЫ9Ы9ЫЫЫЫЊ................... e9ЫЫЫ9ЫЫЫ9ЫЫЫ9Ы9Ы‹4ЈЈЈЈЈЈЈЈЈЈOOЈЈЈЈЈЈЈЈЈЈЈЈЈ5NNюыХ”ЫЫЫЫ9Ы999ЫЫ9Ы9ЫЫЫ‹.....................ƒЫ999Ы99ЫЫЫ9ЫЫЫ9ЫЫ9ЬcЈЈЈЈЈЈЈЈЈOЈЈЈOЈЈЈЈЈЈЈЈЈЈЈЈgЈgт‘KPД…99ЫЫЫЫ9ЫЫЫ99Ы9Ы9Ы9Ыљ......................ВЫЫ9ЫЫ99ЫЫ9ЫЫЫ9Ы9ЫQcЈЈЈЈЈЈЈЈЈЈЈЈO" ЛЭЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈт,ƒЫЫЫ9Ы9ЫЫЫ9ЫЫ9Ы9ЫУƒ........................В—ЫЫ9ЫЫ9Ы9Ы99Ыe}ЈЈЈЈЈЈЈЈЈЈЈфю@ &ZcЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈcДЫЫЫЫ9ЫЫЫ9Ы9ЫЫ9Ы9ЫЫЫЊо..........................ЫЫ9ЫЫЫ99Ы99ЫЫ—п"ЈЈЈЈЈЈЈЈЈЈЈЈ†л ZЩKтЈOOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgюА…99Ы999ЫЫЫ9Ы9У............................ƒ…99ЫЫЫ9Ы9—•IЈЈЈЈЈЈЈЈЈЈЈЈЈфWa_лЛл:IЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈхд9Ы9Ы99Ы999Ы9ЫЫЫL..............................vРЫЫЫ9ЫЫЫЫЫЊИпЪЈЈЈЈЈЈЈЈЈЈЈOЈЈЈOЗНЛP ЛюOOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈтN?е;…ЫЫЫЫЫЫЫ9ЫЫ—Ре.................................ВУЫ9Ы999…;И–уgЈЈЈЈЈЈЈфЈЈOOOЈЈЈЈž Нлx ~KЪ  ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈтю оQ;Њ…LLЫЫЫЫЫЫЫLeЊе.....................................ВЊЫЫ—eЊРЬД–KžЈЈЈЈЈЈЈЈЈЈЈЈЈЈO} ЪЈON_Н!UNcыт"ыgЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgт K ƒВВеееВо...........................................Сi€‰T4"ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈ†NчaНЗЗaЦч_6Л uKIт IЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЪ€СС..................................................#5ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфc&nЧnС_aчЗНлЩUNю‘ †ЪžЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЭЌ__................................................б ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOOOЈ ntnСaa_ ЛPѕќI"тыЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ&_С..............................................Ї'ЈЈЈЈЈЈЈЈЈЈЈЈфЈЈOOOЈ"@мшtnn_ЗНлUNW Ъ" ыЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ"NСС_.............................................#OЈЈЈЈЈЈЈЈЈЈЈЈЈЈфgWqaŒммшttn__НЛPѕЦы"5}тЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOO Ќ_С............................................јAЭЈЈЈЈЈЈЈЈЈЈЈЈфO†NZ___СŒbмt_Н6Ќ :K Ъ"Ъ‘ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgюЅСС...........................................јэOЈЈЈЈЈЈЈЈOЈOЈgKHnЅС_ЗbјŒŒмBшttnЗ PЦюыт5ЭЪЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ ЩСС..........................................јЇXOЈЈЈЈЈЈЈЈфЈO}!ЧnnС_С8’јŒмBt_Зq~ќ Э"ž "ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфШССС.........................................“›†ЈЈЈЈЈЈЈЈЈЈ €ntЧЧnС_м8“’јbммtnЗ Uю‘ž"Э}ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈЈЈЈЈЈЈЈЈЈЈgы1СС.........................................эgЈЈЈЈЈЈЈOЈ‘ZttttЧn_С8а8“јјŒммttСЗЗ ы55ыžЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ5Щnn........................................RXфЈЈЈЈЈЈфЈNСшttЧaм>>88“јŒbмttn__ чUфЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOO:nnn.......................................’A|OЈЈЈOOOфСшtСaжF>88“’јŒbBшtnС__a ќЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgюЅnn.......................................8) ЈЈЈЈЈЈgUСмBмtt_мFFF>>8““мммttЧnС____NЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOXkn.......................................ащ†ЈЈЈЈOфUСBмммBшСFѓF>>88јјŒbмtnССС_6cOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈы1n.......................................8щ†ЈЈЈOЈnŒŒŒмммш 8њёFж>>8“јјbbмшttnСС___Z"ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЪkЧЧ.......................................аAgЈЈфO СјјŒbŒммBaњѓѓѓFF>8а8“јŒŒмBtnС_Сa@OЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈ5t.......................................>щ†ЈOЈуn’“јјŒbммBBnњњѓѓёFF>88“јјŒŒммtЧnСС___KЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ"Тtt.......................................><5ЈO}&ј8“јјјŒŒŒммnњЉњњњѓѓF>>8’“јŒммtnnСaС_ЛOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ tt.......................................><рOži>888’јјbbbŒГ­њњѓѓЃFF>>>“’јŒммBttЧnnaa  ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOфЭ1nЗЗЗЗ...................................FŸ|gt>>88““’’јјŒŒЧъЉГЉњњѓёF>>888’јŒŒмшtnС_СН~ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈыСЗЗЗЗЗЗ.................................>YXNa>F8>8>88’’јŒnГГъЉ­њsѓѓѓFF>8““’ŒммttnС_С@ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈg'шnЗЗЗЗЗЗЗЗ...............................FЃšaF>>>8>88“’јјјŒъГЉ­њњњѓFF>а88’јŒммBnnССOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфDшСЗЗЗЗЗЗЗЗЗ..............................F>&жњёF>>>888888’јt8ъГЉЉЉњѓѓѓёF>>8“’јbмBBшttЅ_~gЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOфOШnЗЗЗЗЗЗЗЗЗЗ.............................FtЉњёFFF>>>>88“’’t>ъъГЉњњњFF>>88“’јŒŒмBшttЧnСЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ†:BЅЗЗЗЗЗЗЗЗЗЗ.............................Чy­ѓѓѓFFжF>8>888““ГъЉГ­њњѓѓFF>>88’јŒbмtЧС"ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈт‚nЗЗЗЗЗЗЗЗЗЗЗ............................СF­њѓѓѓѓFF>>>888“ŒГГЉњњѓѓѓFFFа8“’јŒмBBttUЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ GBСЗЗЗЗЗЗЗЗЗЗЗ...........................ЗŒ­ЉѓѓѓѓЃFFFж>>>>8ајpъъГЉ­њњѓѓF>>>а8’јŒмшС}ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈфXгBЗЗЗЗЗЗЗЗЗЗЗЗЗ..........................С­Љ­њњњњѓёёёFFF>>8а’СprъГЉЉњњѓѓFF>8’’’јŒŒмBnЛOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ"DмBЗЗЗЗЗЗЗЗЗЗЗЗЗ.........................a’y­ЉњЉњѓѓњѓѓѓFжF>>>8tЄЄp№ГГЉњњѓёFж>>>8’јŒBniЪЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфс§bмBЗЗЗЗЗЗЗЗЗЗЗЗЗЗ........................Љ­ЉЉњ­њsњњѓѓѓёFF>ж>8мFppГъГЉњњѓѓѓёF>а8“’јt_ тЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ5CмBшЗЗЗЗЗЗЗЗЗЗЗЗЗЗ.......................СyЉъГyГЉ­њњѓsѓѓѓѓFF>>>аppЄЄъГyЉ­њњѓFЃF>а8bn6uЪЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфX%ммЧЗЗЗЗЗЗЗЗЗЗЗЗЗЗ.......................8ъГъЉ­­њњњњњѓѓёFFFF>>јbж№ЄЄ№ъъЉ­*њѓѓѓFјСZќ"ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфšŒbbЧЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ.....................aГГЉГЉЉ­yњњњњѓѓёѓFFF>>>bЧktааааа8’t_u‘ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈф5‚ŒŒŒСЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ.....................№ГъъЉ­Љњ­њѓsѓѓёёжжFёAE†ЩлЛЛxP U ќЪЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOOЈфXЇŒŒŒЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ.................... ъъГГъГЉЉ*Љ**ёёёаэgOIлчЩ,Цы5тыу@ЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOšЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ....................ЅъъъГysYЇM!!!чi!&ЌЦлiЌ @Ъgž ююЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈффрбtЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ...................ЗЄ№№ъ`GТqNKыЪЪ ыы WN лZлPU~юыы тЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈg'јјtЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ................... >pp№їGЩќ юN PPPqЩ NNю ЪIK Л :ќЦ~NќЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈ†›’јјјЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ...................ЗъpЄЄ+ЙUќ KѕPЛoœŠŠŠЋ^\99ђзUNюы KPq ЪЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈфЈЈg'Rјј’јНЗaЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ..................З№pЄ+Й~KWMbѓЃŒo]V^””-яРdќIcхNуЪ€лOOЈЈЈЈЈффЈфффЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈgтj’’ŒtСС__a_ЗaЗЗЗЗЗЗЗЗЗЗ.................._ћ‚~ќќqЮѓѓѓFѓё8ТИИП33П–ы5OXљР[]уЪыЛыOф†W–ДЬ‰WыфЈффЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈффgфXjЮшtttЧnЅСЅ_С___ЗЗЗЗЗЗЗ................... )ЦќPkњѓѓѓёѓFёёЃ:TT‘ ‘I5ЈOЈg‘Ьк7я]у5ciPзд99ЫЫЫЫЫ9…ђ]ЪфЈЈЈЈЈЈЈЈЈЈЈЈЈЈOффgggсš‚BtttnnnnСС_С__aЗЗЗЗЗ................... ~KUi..њѓѓѓFѓёѓёщSфOЈЈOOЈЈЈЈЈOO ЩккЖЖяу‘ЪUУЯиииииіЯe99…˜ gЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈссэbммBBtЧtnСССС____aЗЗЗЗ..................ѕNNЛ....ѓѓѓѓёѓёёЃŸj5ЈOЈЈЈЈЈЈOЈOЈЈ"Шо7Ж997VытюНŽЕввввввввŽЂдЫeьсфЈЈЈЈЈЈЈЈЈЈOссэŒŒммBBttnnnС___a_aЗЗЗ.................~Nл....њњѓѓѓѓѓѓFЃ)2сOЈЈOOЈЈЈЈЈЈOЈgvУк7ЖЖЖЖ=ыЪыiивЕЕЕЕЕЕЕЕЕі‡Ыœ OЈЈЈOЈЈЈфффэ“јјbмммBBttЧЧnСnССС___aЗЗ...............@~NP .....њњѓѓѓёЃYнрфЈЈЈOЈЈЈOOЈOЈЈЈыЬЖЖЖ99=œЪ чиЕЕвЕЕЕЕЕввиLЫЫяžЈOЈЈЈффЈ#8“““’јŒŒŒммBшtttnСС_____ЗЗ..............@N .......њѓѓѓѓѓѓёz2фЈOЈЈЈЈЈЈЈЈЈЈOЈOтѕеЖЖЖЖЖЖЖ7œтžЛиЕЕввввЕЕŽНЗve9ЫятЈЈЈЈgэ>888“јјјŒbмBBBшtnnnЅСС__aЗЗ..............NNx........њњѓѓѓѓё{EЈOЈЈЈOЈOOOЈЈOЈЈOЈvРкЖ997ЖЖœт5ЛиввввЕвОНЗЗЗоЫ-"фЈнY>>>>88“““јјŒbммBшtttЧnССС_С_ЗЗ.............N@x........њњњѓѓњѓѓw™5ЈЈOЈЈЈЈЈЈЈOЈЈOЈЈO4еЖ9ЖЖЖЖЖ99Ж"žiŽвЕвОНЗЗЗЗЗЗЗРУЬ3жF>>88а8““јјŒbŒммBtttЅnСС__ЗЗ............N~.........њњњѓњѓѓsщ'фЈOЈЈЈOЈOЈЈЈЈЈЈЈЈЈŠЦдкЖЖЖЖ97Жк7OIНи/JaЗЗЗЗЗЗЗЗЗ еЫЫ9УИkжж>>>888“јјŒbммммtnССС_З............ќ@ ..........*њњњѓњs{|OЈЈOЈЈЈЈЈOOOЈOOЈOOO}Q7кЫ99ЖЖЖЫЖ"gKНЗЗaЗЗЗЗЗЗЗЗЗЗљоLЫЫЖдh>>>888““’јbŒŒммшшttttЧnnС_З...........KNUZ..........њњњѓњѓѓ`нрфЈЈЈЈЈOЈOЈЈЈЈЈЈЈЈЈЈ",к7ЖЖЖЖ9ЖЖ\†5U__З ЗЗЗЗЗЗЗЗЗЗƒ…ЖЖ9…1Fж>>>88’“јјјŒŒŒмммBttЧnЅn_З...........ќч...........њњњњњњњѓz'†OЈOOЈЈЈЈЈOЈЈЈOЈЈOЈЈЈ‘Lк9Ж9ЖЖЖ7к-т hННa_ЗЗЗЗЗЗЗЗЗЗƒ99Жк8>>>8888“’’јŒbмммBttnСЗЗ..........W~............њ*њњњѓњЃ0рфЈЈЈЈЈЈOЈOЈЈЈOOЈЈOЈЈO"@Н‹кЖкЫЖЖ9Ж9Ж7œЪю3L;‹Н_НЗЗЗЗЗЗкЖЖ7k>F>8>>88“’јјbŒммBшtttСЗ...........N i...........њњњњњњйн†ЈЈЈOЈЈЈЈЈЈOЈЈЈЈЈЈЈЈЈЈOы!о7Ж7к9ЖЖк9Ж=I5к9кЖЖЊЬљaЗЗЗЗЗНL79ЖПFFFж>88888’јјbbмммBшtЧaЗ..........c............њњ­њњњњ+н†фЈOOЈЈOOЈOЈЈЈOЈЈOOЈOOЈ"юЖ9Ж7ЖЫЖ7ЖЖЖ-ы v7ЖЖ79997љ_ЗЗЗaЬLЊкЬFFж>>>8а“““’’јbŒŒмммttСЗ...........N€i............ЉЉ*­њњ­њ+2OOЈЈЈЈЈЈЈЈЈOЈЈЈOЈЈЈЈЈЈOЈž ƒдкЖЖЖЖ9ЖЫ79ыЪ 9ЖккЖЖЖ97QН_aНљЊдкЬёѓFF>>>8>8’’’’ŒŒммшшшnЗЗ..........ю.............­­њњњњњswSOЈЈЈЈЈOOЈЈOЈЈЈOЈЈЈЈЈOЈЈЈЈ‘еeЖ9Ж9ЖЖЖЖЖЖ- кЖ9Ы9Ж9ЖЖ_ НЖкПѓѓFF>>>а88888јјјbŒbмBBB_З...........юPч.............*­Љ­њњњњz|ЈЈЈOOЈЈЈOЈЈOЈЈЈOЈOOЈЈOOЈOgю‹eЖ9Ж9Ж9Ж977уыУЖЖЖЖЖ9ЖЖЖк__;9шѓёFFF>>>888’8јјјŒŒммBBB_З...........у~x..............Љ­*њњњњй0рЈЈOOЈЈЈЈЈЈЈЈЈЈOЈЈЈЈЈЈЈЈЈЈЈ†ќ ВдкЖЖЖЖ9ЖЖVKе79Ж9Ж9кЖ9Ж7v_еЖЖ>њѓёёFF>>>8>8“8“’јŒŒŒŒммСЗ............€Л..............­Љ­њЉњ*їн†ЈЈЈЈЈЈOOOЈOOЈЈЈOЈOфЈggЈOgЈЈт~НеЫ9Ж7ЖЖ7=cыh7Ж9Ж9кЖe7=РЬд99дiњѓsѓѓѓFFF>>8888““ј’ŒbbBСЗ.............KЛ..............ЉЉ­yЉњ*й™OOЈOЈЈOOЈЈЈЈЈЈЈOЈЈgЈЈOыNq юžЈ5ѕ ЬкЖЖ9ЖЖЖ7Жюу РЖ9к7к9LУЊЫкЖдѓѓњѓѓѓёFF>>>>8>’’’’јмСЗ............. ѕx...............Љ­­њњњЉЁEЈЈЈЈOЈЈЈЈЈЈOЈЈЈЈOЈфO5ѕЛ З лqЈ5~‡кЖЖЖ79ЖЖ[юќИ9Ж7У^^^яZB“­ѓњѓѓѓFFжF>>>8>8“’ј’_З.............. PЌ...............ЉЉЉЉ­Љ*wрOOЈOЈЈЈЈЈOOOЈЈOOЈЈg5 ЗЗЗЗЗЗcO†ќvИ…ЖЖ9ЖЖЖ[ќЖЖЖ‹Oc–•– –ЌммњњѓњѓѓёFF>жа8а88“’јЧЗЗ...............x...............ЉГЉ­y­ЉwOЈЈЈЈOЈOOЈЈЈЈЈЈЈЈOЈсc ЗЗЗЗЗЗЗaqтЈ"c?УкккЖЖЖќЌeк7цЈЈЈЈЈЈЈмммммF*њњѓѓFѓFFF>>>888мСЗ.................Kx...............Гy­­*њњw†gЈЈOЈЈЈЈЈЈЈЈЈOOЈЈЈ ЗЗЗЗЗЗЗЗЗлWЈЈgЭ 7ЖкЖNK РЖ…@ЈЈЈЈЈЈЈ†‚мммм>њњњѓѓѓѓёѓFжж>ж>СЗЗ.................‘~................ЉЉyЉЉЉ*w5фOЈЈOЈOЈЈOOOЈЈЈOOЈ}лЗННЗЗЗЗ_aНUOOЈЈ5Uvƒ‹дЖ]NNЖ;‘ЈЈЈЈЈЈЈф'ммŒbјЉ­њњњњѓѓFѓFFF’nЗЗ...................ы................ЉГГЉyy*ЁрфЈЈЈЈЈЈЈЈOЈЈЈЈЈЈЈЈ‘aНЌю~_ЗЗЗ  qOЈЈЈЈЈт :ƒеo:ќИ9ИOЈЈЈЈЈЈЈЈ5CŒŒŒњ­њњњѓѓѓѓF’naЗ.....................ы P................ГЉЉyЉЉЉЁ|фOЈOOЈOЈЈЈЈЈЈOOOЈЈЭЛi gт@ЗЗЗ__@ЈЈЈOOOOO"I ыWuKПL‰gЈЈЈЈЈЈЈЈф#ŒŒ­­­њњѓѓѓЅЗЗ.......................ыqq................ЉъЉГЉyЉЁ|OOЈЈЈЈЈЈЈOЈOOOЈЈЈЈ5@Л5ЈgKЗЗЗ_ч}ЈЈOOЈЈЈЈЈЈOЈюdП"ЈЈЈЈЈЈЈЈЈЈ'ŒјёЉ­њњњњаЧЗЗ.........................I ................ГЉъЉГЉЉЁ|ЈЈЈOЈЈOЈЈЈЈЈЈЈЈЈЈOЈы ЌЗЗa uOOЈЈЈЈЈЈЈЈOЈЈ юќфЈЈЈЈЈЈЈЈЈO†Їјј>ГyЉњ8СЗЗ...........................IЛ ................ЉГЉГъЉЉЁ|ЈЈЈOЈЈOЈЈOЈOЈЈЈOOOЈOуxЛчa _Z5ЈЈЈЈЈЈOOOOOЈЈUюЛЈЈЈЈЈЈЈЈЈЈЈЈgбј’’>ъњСЗ..............................Э!U................ГъЉГЉъЉЁ|OOЈЈЈЈЈЈЈЈЈЈOOЈЈЈЈЈЈOыNЛ_Z c5gOЈЈOOЈЈЈЈЈЈЈgUKЛЈЈЈЈЈЈЈЈЈЈЈЈg#’“’аn_З................................ЪЛU................ЉъГЉГЉЉЁрЈЈЈЈЈOOЈOOЈOЈЈЈЈЈЈЈOЈЈ"I}}žgOЈЈЈЈOЈЈЈЈЈЈЈЈO KЈЈЈЈЈЈЈЈЈЈOOЈ28““а................................... Л................ЉГъъъЉГЁ|фЈЈOЈЈЈЈЈЈЈЈOЈЈOOOЈЈOЈOЈOЈOЈЈЈOЈЈЈЈЈOOOOOOЈу ФxЈЈЈЈЈOЈЈЈЈЈЈOX“888................................... ................ЉъъГГЉъ+EOOOOЈЈЈЈOЈЈOЈЈЈOЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈЈOЈOOЈЈЈЈЈЈуЩќPЈЈЈЈЈЈЈЈЈЈ5 фg888...................................ЪqU................ГГГъЉъГ(f"ЈЈЈЈOOЈЈOЈЈOЈЈЈЈЈЈOOЈOЈOЈOЈOЈЈЈЈЈЈЈЈЈЈЈЈOЈюPЦUЈЈЈЈЈЈЈЈЈы "Ј58>8а...................................ЪUU.................ГъъъГїl†ЈЈЈЈOЈЈЈЈЈЈЈЈЈOЈOOOЈЈЈЈЈЈЈЈЈЈЈЈOOЈOЈЈOOOOgWЩЦNЈЈЈOOЈ5ѕт5Ър>88>...................................žNPN.....ЈЈ.........ъъъГГЉГlсЈOOЈЈЈЈOOЈOOЈЈЈЈЈЈЈЈЈOЈOЈOЈOЈOЈЈЈЈЈOЈЈЈЈЈЈqN NNЦќЦ ќыOы "Э8>>ж....................................юN....ЈЈЈЈ........ГъГъъћm5OOЈЈЈЈOOЈЈЈЈЈЈOЈOЈЈЈOOЈЈЈЈЈЈЈЈЈЈЈЈOЈЈЈЈЈЈŠЌ ѕќќ ќюы"O†~žЈ|>ж>F....................................Iiќ...ЈЈЈЈЈ........ГъъГЉГІEЈЈЈЈOЈЈЈЈЈOЈЈЈЈЈЈOOЈЈЈЈOЈOЈOЈOЈOOЈЈOЈOOOOы~qqNNNNKN ќ}ЈфOр>>FF....................................5Л@...ЈЈЈЈЈЈ.......ЉГГъГ(SЈЈЈOOЈЈЈЈOOЈЈOOЈOЈЈЈЈЈЈOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈK@ ž ќЦЦW}"ЈЈЈЈЈO'>FFF....................................тU...ЈЈЈЈЈЈ........ъъГъїˆOOЈЈЈЈOOЈЈЈЈЈЈЈЈЈOЈЈOOЈЈЈOЈOЈOЈOЈЈOOЈOЈЈЈЌЦЦЈЈЈЈЈЈЈЈЈЈЈOЈЈ2FFёё.....................................cЌю..ЈЈЈЈЈЈЈ.......ГъъъъћmрЈЈЈЈЈOЈЈЈЈЈOOЈЈOЈЈЈOЈЈЈЈOЈЈЈЈЈЈЈЈOЈЈЈЈOOЛqыOЈЈЈЈЈЈЈЈЈЈЈЈOнёFё......................................5лK...ЈЈЈЈЈЈЈ......ъъГГІ|фЈOOЈЈЈЈOOЈЈЈOЈЈOЈЈЈЈЈOЈЈЈOЈOЈOЈЈЈЈЈOЈOKЛ@ gЈЈЈЈЈЈЈЈЈЈЈЈЈЈщѓёѓ......................................"U..ЈЈЈЈЈЈЈЈ.....Љъъ SOЈOЈЈЈЈOOЈЈЈЈЈЈЈЈЈЈOЈOOЈЈЈOЈЈЈЈЈЈOЈOOЈЈчЛNNOЈЈЈЈЈЈЈЈЈЈЈЈЈр`ѓѓѓ....................................... i ..ЈЈЈЈЈЈЈЈ......ъъїl5ЈЈЈЈOЈЈЈЈЈOOOЈOOЈЈЈЈЈЈЈOЈЈЈOЈOЈЈЈЈЈЈOыч IЈЈЈЈЈЈЈЈЈЈЈЈЈЈ2Ѓѓѓѓ......................................."@...ЈЈЈЈЈЈЈЈ.....Г№ъГ$рЈOЈOOЈЈЈЈOOЈЈЈЈЈЈЈOЈOЈЈOЈЈЈOЈЈЈЈOЈOЈO л@~ЈЈЈЈЈЈЈЈЈЈЈЈOЈф{њњѓ.........................................Л}..ЈЈЈЈЈЈЈЈЈ....ъ(ˆOЈЈЈЈЈOOЈЈЈЈЈЈOЈЈЈЈЈЈOЈЈЈOЈЈЈOЈЈЈЈЈO‘лP~ ЈЈЈЈЈЈЈЈЈЈЈЈЈOЭ`sѓњ.........................................gxN...ЈЈЈЈЈЈЈЈЈ...Г№ћm†фЈOЈЈOЈЈЈЈЈOOOЈЈOOЈOЈЈЈЈOЈЈЈOЈЈOЈфO лN~gЈЈЈЈЈЈЈЈЈЈЈЈЈфнњњњњ..........................................iы...ЈЈЈЈЈЈЈЈЈ...№ъІSOOЈOЈЈЈЈOOЈЈЈЈЈЈЈЈЈЈOЈOЈЈЈOЈЈЈOЈgфќZ u ЈЈЈЈЈЈЈЈЈЈЈЈЈЈ|`њњњ...........................................g  ..ЈЈЈЈЈЈЈЈЈЈ..Г№ъћ†ЈЈЈЈЈЈOOЈЈЈЈЈЈOOЈЈOЈЈЈЈЈЈOЈЈЈOЈсы6i NЈЈЈЈЈЈЈЈЈЈOфЈЈфКњ­њњ............................................Ъл ...ЈЈЈЈЈЈЈЈЈЈ.ъr№ГЎEфЈOЈOЈЈЈЈЈOOOЈЈЈOЈЈOЈOЈOЈЈЈOЈЈЈЈ€ZuЪфЈфЈЈЈЈЈЈOЈЈOснњ­њ­њ............................................gю!Ъ...ЈЈЈЈЈЈЈЈЈЈˆЄ№№ћlрЈЈЈЈЈЈЈЈOOЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈЈOЈфOqZq ›EЈЈфЈЈЈЈЈЈЈЈсс2ї­ЉЉЉ..............................................Ј€O...ЈЈЈЈЈЈЈЈЈOˆ„r№№№ SOOЈOЈOOЈЈЈЈЈЈOOOЈOOЈOЈOЈOЈЈOg‘6ч М­їˆсЈфЈЈЈЈЈЈЈOЏїyy­yњ..............................................."ЛNЈ...ЈЈЈЈЈЈЈЈOрSЎЄ№№№№ћmрфЈЈЈЈЈЈЈЈЈOOOЈЈЈЈЈЈЈЈЈЈЈЈЈO ZZN:­ГГїК|†ЈЈфOgфE$­yЉyЉЉ.................................................žiN"...ЈЈЈЈЈЈЈЈ†ES„№r№(Џ†ЈOЈOЈЈOOЈЈЈЈЈЈЈOЈЈOЈOOOOg‘Z6~~ŸГГГъГГІЏˆ5|ЏІїyЉъГyГ...................................................Iлќт...ЈЈЈЈЈЈЈOрSˆˆєr№№№SOЈЈЈЈЈOЈЈЈЈЈЈOOOЈЈOЈЈЈgЈ‘ZZN)ъГъъъГъъГЉъъЉъъЉъъГъЉ...................................................ЈЭлNЪ...ЈЈЈЈЈЈOрˆˆˆЏfЎr№rЎEЈЈOЈЈЈЈЈOOOЈЈЈЈЈOЈЈOЈфы_6ЦщГъГГГъГГъГГъГЉГГъy.....................................................ЈЪiЭ....ЈЈЈЈЈ†EˆЏffЎ„ћБ|OЈЈЈOЈOOЈЈЈЈЈЈЈOЈфgЈq лѕNщъъГъъГъъГГъ........................................................ Л ы...ЈЈЈЈфрˆffflmєЎm|OЈфЈЈЈЈЈЈЈOOOфЈЈЈыq Л~NщъъГъъъ.........................................................."Zќ ....ЈЈЈ†EfmmmmБmЏ|†ЈЈЈOЈЈOOOЈЈЈЈЈNZ6NШwr№............................................................Oюлqюc.....ЈЭfmmББББ$mf|†OЈЈOЈЈЈЈЈЈOыq iUќšћrr№№№№..............................................................Јž люю.....ˆlmББББєєєєmSрgOЈЈЈЈЈOыq6л@ю{rr№№№.................................................................ф ЌлUќќ....Г„ ЎєєєєЎЎЎБˆрOЈЈONлZлxKэ(Єpprъ....................................................................gулq~N@:.№pЄЄЄЄ№Є№Єr mэШqiлЛKDІppЄpЄpp........................................................................gылчqU~Й)<ŸŸŸŸŸŸŸŸЛЛччЛЌP~W ..ppppppЄpppЄЄЄ№ъ..........................................................................."туЛлЛxqPqqPqЛЛЛЌq~K .......pppppppppp.................................................................................†"IюNUqЛччЛЌ  W }‘.............№ppЄ№........................................................................................ттžžžž ЪЪIЪII...................................................................................................................................................................................................................џџџџџџџџџџџџџќџџ№џ€џџјџџџќџќРџќџќџќџўџўџџџџ€?џџРџџрџџџ№џџџјџџџќџџџџџџџџџрџџџџџр?џџџџџРџџџџџ€џџџџџ€џџџџџџџџџџџџџџўџџџџўџџџџўџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџќџџџќџџџќџџџќџџќџџќ?џџќ?џџјџџјџџ№џџ№џџрџџрџџРџџРџџ€џџ€џџџџџџџџџџџџџџџўџќ<џ№|џсќџуќџЧјџјџјўјў?јќјќ№јџ№?јџ№?ёџ№ёџ№џуџ№џуџ№џуџ№џЧџ№џЧџ№џЧџ№џЧџ№џџџ№џџџ№џџџ№?џџџ№џџџџ№џџџџ№џџџџ№џџџџ№џџџџџ№џџџџџ№џџџџџ№џџџџџјџџџџ‡ЯјџџџџЧ‡јџџџџЧјџџџџЧјџџџџЧќџџџџуќџџџџу€ќџџџџс€|џџџџё€~џџџџёР>џџџџјРџџџџјрџџџџќpџџџџќ0џџџџў8џџџџў?џџџџџ?џџџџџ‡џџџџџУ€џџџџџџсРџџџџџџррџџџџџџ№xџџџџџџќџџџџџџўџџџџџџџрџџџџџџџ€ј?џџџџџџџр<џџџџџџџјџџџџџџџџўџџџџџџџџџ€рџџџџџџџџџ№ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(€ [a ŠМП4 w WZYВЂSNЭЫЪ R—žћўќž”“ошКfffffffffffffffffffffffffffffffffffffffffffffffffffffff‘ffffffffffff‘‘‘™™‘‘ffffiffffffffffffa ЛЛыююююfffffffffЛООююююююОЛА‘™™™™‘‘‘fffffff‘ЛОююююююююююсffffffffОююююююююююююююююы‘™™U]]ее‘‘‘fffОююююююююююююююffffffffюююююююююююююююююююю иˆЬЬЬЬЬЬШU‘ ОююююююююююююююююffffffffОюююююююююююююююююююнŒЬЬЬЬЬЬЬЬЬЬШе юююююююююююююююююююffffffffююююююююююююююююююхиЬЬЬЬЬЬЬЬЬЬЬЬЬТюююююююююююююююююююрfffffffffkююююююююююююююююююЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬюююююююююююююююююююБfffffffffaюююююююююююююююююрŒЬЬЬЬЬЬЬЬЬЬЬЬЭеиТююююююююююююююююююffffffffffююююююююююююююююЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬQЛююююююююююююююююыffffffffff`юююююююююююююююрмЬЬЬЬЬЬХЬЬЬЬЬЬЬЬЬUююююююююююююююююБffffffffffffююююююююююююююЬЬЬЬЬЬнЬЬЬЬЬЬЬЬЬШююююююююююююююыffffffffffffaюююююююююююююЕЬЬЬЬЬЬЬмЬЬЬЬЬЬЬЬЬЬаОюююююююююююююАffffffffffffffюююююююююююŒЬЬЬЬЬЬЭиЬЬЬЬЬЬЬЬЬШPююююююююююююыffffffffffffffaОююююююююы ŒЬЬЬЬЬЬЬХ]Q]ЬЬЬЬЬЬЬЬЬХPОюююююююююыffffffffffffffffОююююююАXЬЬЬЬЬЬЬЬЬUнˆ…ŒЬЬЬЬЬЬЬЬЬЭQЛююююОюЛffffffffffffffffffОюыЛ-ŒЬЬЬЬЬЬЬиЬбU]ˆШЬЬЬЬЬЬЬЬЬЬЬШQQfffffffffffffffffffffi•вŒЬЬЬЬЬЬЬЬЬбUиŒШЬЬЬЬЬЬЬЬЬЬЬЬЬЬШYffffffffffffffffffffffffc\ЬЬЬЬЬЬЬЬЬЬй™™™UиЬˆЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ‰ffffffffffffffffffffffff7ŒЬЬЬЬЬЬЬЬЬЭ™9™™нˆШŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ‘–ffffffffffffffffffffffc­ЬЬЬЬЬЬЬЬЬШй33™™‘U]ˆШŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬYffffffffffffffffffffffjмЬЬЬЬЬЬЬЬеQ“3™9™UнŒШЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ…‘ffffffffffffffffffffffЃŒЬЬЬЬЬЬЬй3339™‘UиŒˆЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ‘–fffffffffffffffffffff­ЬЬЬЬЬЬЬй‘ЃЃ39™‘UˆЬˆЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШY–ffffffffffffffffffffc8ЬЬЬЬЬЬ‰™™‘“Ѓ3339‘нˆШŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬй™ffffffffffffffffffffj|ЬЬЬЬЬ…™™™‘:Њ333“™]ˆШŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ‰™ffffffffffffffffffffjмЬЬЬЬШ™9™™Њ::339™‘ŒˆŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ…™ffffffffffffffffffffЊŒЬЬЬЬб““™™ЊЊ33399™UЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ™–fffffffffffffffffff:ŒЬЬЬХ“““™ЊЊ:Ѓ333™‘мЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ™–fffffffffffffffffffЃЬЬЬЬY339™‘:JЊЊ3339“™‘ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ™–fffffffffffffffffff7ЬЬЬХ“33““‘:ЊЊЃЃЃ33™™‘‘мЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ9–fffffffffffffffffffЇЬЬЬY33339‘ЊЄЊЊ:333™™™‘ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ™–fffffffffffffffffffЃЬЬЭ“ЃЃ3331JJЊЊЊ:33“™™™ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ9–fffffffffffffffffffЇŒЬ‰::3333“DЄЊЊЃ3:39™™™мЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ™–fffffffffffffffffffЇЬШЊ::333šJJJЊЊЊЃ333™™‘ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ9–fffffffffffffffffffЇŒС:ЃЊ3Ѓ394JJЊЊЊЃ33399™™‘ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ9‘fffffffffffffffffЊŒЊЊЊ::3ЉDDDJJЊЊЊЃ339™™ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШ™‘ffffffffffffffffЊЊЊЃЊ339DDJJЊJЊ:3339“™™ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ9‘fffffffffffffffЊбЊЊЊЊЃЃЃ3DDDЄЄЊЊЊЃЃ33™™™ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ3‘fffffffffffffffЊЊЊЊЊЊЃ:šDDDЄЄЊЊЊЃ333™™™•ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ9‘ffffffffffffffЉ4JJЊЊЊ::”DDDDЄЊЊЊ::3399™ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬХ9‘ffffffffffffff9JJЊЊЊЊЊ:šDDDDЄЊJЊЊЃ333™™œЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬХ3‘ffffffffffffffDЄЊJЊЊЊЊ:DDDDJDЊЊЊ::33“™\ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬУ9‘fffffffffffffa4JJЄЊЊЊЊЃ3DDDDJJЄЊЊЊЃ33“™ŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬƒ3ffffffffffffaDЄJJJJЊЊЊЉDDDDDJJJЊЃЃ333‘ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬг3ffffffffffffЄЄЊJJЊЊЊЊЉDDDDDЄЄЊЊЊЊ:39ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬг3ffffffffffff4DDDJЄЄЄЊЊЃDDDDDDJЄЊЊЃЃ9ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ39fffffffffffaDDDЄЄJЄЊЊЊЊ”DDDDJJJJЊЊ9ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ39fffffffffffdDDDJDЄJЄЊЊЊЃЄDDDDDJЊЃ9ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ39ffffffffffDDDDDЄЊJЄЊЊЊ93:ЊЊЊ:9XЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЧ39ffffffffffЄDDDDЄJDЄЊJЊЊЈХ•UU]ŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬƒ31fffffffffaDDDDDDJJDJJJ­ЬU]иЬˆ\ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬк:1fffffffffcDDDDDDЊ3™UXQ]ˆШмЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ33‘fffffffffDDDDJ5UниˆˆˆнеU]ˆ…ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭ:3‘fffffffffDDDЃUиеUUUUниШе]енЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЧ3:fffffffffDDЅ]U"ЬЬЬ.юАUиUUXЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬƒЃЃ‘fffffffffDЅ]е3ЊЃR"тОАи…иˆY\ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬzЃ9‘‘fffffffffE]е:ЊЄЊЉ QP]иЬЛ-ˆQŒŒнЛŒЬЬЬЬЬЬЬЬЬЬЬЬЬе99™™™‘™fffffffff]е”ЄЄЊЊЇиˆииˆЬЬю(ˆ+Оююююы(ЬЬЬЬЬЬЬЬЬЬЬе“““™™™™‘fffffffffUеdЄЊJJЇмЬЬЬЬЬЬ…ююˆ…АёёёОы(ЬЬЬЬЬЬЬЬЬг3393“™™™‘ffffffffeнfjJЄЊЊwŒЬЬЬЬЬЬЭюютŒйџџџџџ№юю,ЬЬЬЬЬЬЬгЃ333““™™™‘™ffffffff]QffJJЄЊJ}ЬЬЬЬЬЬЬЭюююшШџџџџџ№ютЬЬЬЬЬЬк:333339™™™™‘™fffffffUеffЊJJJЇxЬЬЬЬЬЬЬЬюююю(Сџџџџёю,ЬЬЬЬкЊ::3333™9™™™‘ffffffm]VfffJJJЊGмЬЬЬЬЬЬЬШPюююютЬџџџџљююŒЬЬкЊ:Њ33333“™™™™™‘ffffffmUffffJJЄЄЇмЬЬЬЬЬЬЬЬОюююю,СџџџюьЬкЊЊЊЃЃ:Ѓ3333“™™™‘‘ffffffеVfffdЄЊDЊwЬЬЬЬЬЬЬЬЬюююютЬџџ‘ы:ЊЊЊ::33333“™™™™™fffffmUffffjDЄЊЄ}ЬЬЬЬЬЬЬЬЬТююююю,‰ёюА:ЊЊ:Ѓ:3333““9™™™™ffffffнVffffdJJDЄxЬЬЬЬЬЬЬЬЬШюююююьЭююБЊЊЊЊЊ3Ѓ3339™™™™™fffffmеffffdЄЄЊGxЬЬЬЬЬЬЬЬЬЬQюююююŒQююšЊЊЃЃЃ3333339™™™fffffmQfffffdЄЄЄGмЬЬЬЬЬЬЬЬЬЬюююююьСююКЊЊЊЊ3Ѓ3333™9™™™fffffеVfffffjDЄЄGŒЬЬЬЬЬЬЬЬЬЬююююютААюуЊЊЊЃЃЃЃ333339™™fffffеfffffJDЄЄ­ЬЬЬЬЬЬЬЬЬЬЬШОюююююЬ[ююыюрЊЊЊ::3Ѓ3333““™‘ffffmUffffffDЄЄЄGЬЬЬЬЬЬЬЬЬЬЬЬбОюююююИююююБырЊЊЊЊЊЃЃЃ33993™‘fffffmQffffffJDЄD}ЬЬЬЬЬЬЬЬЬЬЬЬХюююююь…ОююююырЊJЊЊ3:Ѓ3Ѓ333“™fffff…ffffffDЄJЄMЬЬЬЬЬЬЬЬЬЬЬЬШюююююыиююююррJЊЊЊЊЊ:Ѓ33333‘fffffеffffffJDЄDxЬЬЬЬЬЬЬЬЬЬЬЬЬбюююююˆ[юююююБОуЄЊЊЊЊЃЃ3Ѓ3339‘fffffmUfffffffDЄЄDxЬЬЬЬЬЬЬЬЬЬЬЬЬЭОюююю(аюююююсюКЊJJЊЊ:ЃЊЃЃ339fffffmUfffffffDЄDЄмЬЬЬЬЬЬЬЬЬЬЬЬЬЬQююююэюююююАОюЄЊЊЊЊЊ:Ѓ3333ffffffmQfffffffЄDJG|ЬЬЬЬЬЬЬЬЬЬШU]Œююююэ…ОюююОююс:JJJЄЊЊЊЃЊ:39ffffff…fffffffJDЄDЬЬЬЬЬЬЬЬЬЬШбXЬQюююыюЕО""ы“:ЄЄЊJЊЊЊ:::3fffffffеVfffffffDDЄG|ЬЬЬЬЬЬЬЬЬХмЭюююыню н ]33JJЄЊЊЊЊЊЊЃ‘fffffff…fffffffDJDGЬЬЬЬЬЬЬЬЬЬбXЬе юююн^ю\ЬЬЬƒ33ЄJJЄЊЊЊЊЃ9ffffffffбVfffffffJDDDЬЬЬЬЬЬЬЬЬШQЬШбююи[ю\ЬЬЬЧ33ЄЄЄЊJJЊЊ9ffffffffhUffffffffDJJGЬЬЬЬЬЬЬЬЬШЬЬЭQю-PыŒЬЬЬЭ33ЄJJDЊЊЊЉfffffffffhUffffffffDDDDŒЬЬЬЬ|ЬЬЬШ]Q•ЬЬЬˆQарЬЬЬЬЬ334JJJЊJ9ffffffffffhUffffffffJJDGŒЬЬЬЬЬЬЬЬШŒЬЬЬЬШˆе ВЬЬЬЬЬк::JDЄЄ9fffffffffffmUffffffffDDDDŒЬЬЬЬЬЬЬЬШйЬЭ8ЬЬЬЬЬЬ…е ЬЬЬЬЬƒ3:DJJЉffffffffffffhUffffffffDDDGŒЬЬЬЬЬЬЬЬЬ…X…мЬЬЬЬЬЬ…бмЬЬЬЬЬУЃЊDЄЉffffffffffffflffffffffDDDDŒЬЬЬЬЬЬЬЬЬШUŒЬЬЬЬЬЬ…ЬЬЬЬЬЬУ3:D9ffffffffffffffhffffffffDDDGŒЬЬЬЬЬЬЬЬЬЬ}3—мЬЬЬЬЬЬЬебЬЬЬЬЬЬЧ:Њ‘fffffffffffffffhUffffffffDDDDŒЬЬЬЬЬЬЬЬЬЬЬˆЬЬЬЬЬЬЬЬ…еЬЬЬЬЬЬЭ::fffffffffffffffffhffffffffDDDGЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬебЬЬЬЬЬЬШЊЊfffffffffffffffffhUffffffffDDDDмЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ…еЬЬЬЬЬШЬ::fffffffffffffffffhUffffffffDDDDмЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬеUЬЬЬЬШмЬЊЊffffffffffffffffflUffffffffdDDG|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬееЬЬЬШUЬˆЊЊffffffffffffffffflUVffЬffffdDDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬQев]UŒ…ШЊЊffffffffffffffffffежflЬЦfffdDDDxЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШU]енŒЬ…\ШЊЊffffffffffffffffffжfЬЬЦfffdDDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШUU]]нQиЬШЊЄffffffffffffffffffСжfЬЬЬfffdDDDMЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭUXниЬЬЬШЊЊffffffffffffffffffХVfЬЬЬffffDDDHЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬХмЬЬЬЬЬЬЭЄЊffffffffffffffffffm]fЬЬЬЦfffDDDGŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬСUŒЬЬЬЬЬЬЧЊІfffffffffffffffffflflЬЬЬfffDDDGЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬбеЬЬЬЬЬЬЬЧЄІfffffffffffffffffflU†lЬЬЬЦffDDDGмЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬQнЬЬЬЬЬЬЬЪЊІfffffffffffffffffffжlЬЬЬЦffdDDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬШXЬЬЬЬЬЬЬкJFfffffffffffffffffff…жfЬЬЬЬffdDDDxЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬХ\ЬЬЬЬЬЬЬzJffffffffffffffffffffhfЬЬЬЬЦfdDDDxЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬUŒЬЬЬЬЬЬЬЄЄffffffffffffffffffffh]flЬЬЬЬfdDDDGЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬQеЬЬЬЬЬЬЬЧЄЄfffffffffffffffffffff†fЬЬЬЬЦfDDDGЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЭиЬЬЬЬЬЬЬ„ЄІfffffffffffffffffffffХXfЬЬЬЬЬfDDDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬмЬЬЬЬЬЬЬzЄFfffffffffffffffffffffhflЬЬЬЬЦDDDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬQ]ŒЬЬЬЬЬЬЭDDІfffffffffffffffffffffl†fЬЬЬЬЬ„DDDGŒЬЬЬЬЬЬЬЬЬЬЬЬЬЬХзŒЬЬЬЬЬЬкDЄfffffffffffffffffffffffХ\flЬЬЬЬЭDDDGЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬTHЬЬЬЬЬЭDJDffffffffffffffffffffffflЦfЬЬЬЬЬ‡DDD|ЬЬЬЬЬЬЬЬЬЬЬЬЬШнDDxЬЬЬШtJDFffffffffffffffffffffffffмflЬЬЬШ|tDDwЬЬЬЬЬЬЬЬЬЬЬЬЬзDDD}ŒtDDDfffffffffffffffffffffffffhЦfЬЬЬЬШˆtDGмЬЬЬЬЬЬЬЬЬЬЬШиtDDDDDDDDDDffffffffffffffffffffffffflиflЬЬЬЭ‡ЧtD|ЬЬЬЬЬЬЬЬЬЬЬзDDDDDDDDDDFffffffffffffffffffffffffffШ†flЬЬЬx||wGŒЬЬЬЬЬЬЬЬЬХ‘иtDDDDDDDDDDffffffffffffffffffffffffffff…X†fЬЬШwЧ‡wwŒЬЬЬЬЬЬЬЬШQзDDDDDDDDDDFfffffffffffffffffffffffffffflQиffЬЬˆxw‡‡wŒЬЬЬЬЬЬЬб•иtDDDDDDDDDDffffffffffffffffffffffffffffffЭиfflxxwwwˆЬЬЬЬЬЬ…XдDDDDDDDDDDFffffffffffffffffffffffffffffffl…нffhwwwwwwŒЬЬЬЬ…]‡DDDDDDDDDDDffffffffffffffffffffffffffffffffl…нffDwwwwwwмЬЬбUнDDDDDDDDDDDFffffffffffffffffffffffffffffffffflе]нdDDDDDDwеQUнtDDDDDDDDDDFfffffffffffffffffffffffffffffffffffl…UUWЃЊЇЃЃQUиfDDDDDDDDDDDffffffffffffffffffffffffffffffffffffflˆQUUU]ˆfffdDDDDDDDFffffffffffffffffffffffffffffffffffffffffЬеQQUнˆ†ffffffDDDDDffffffffffffffffffffffffffffffffffffffffffffШШШŒˆˆ†fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffџџџџџџџџџџџџџќџџ№џ€џџјџџџќџќРџќџќџќџўџўџџџџ€?џџРџџрџџџ№џџџјџџџќџџџџџџџџџрџџџџџр?џџџџџРџџџџџ€џџџџџ€џџџџџџџџџџџџџџўџџџџўџџџџўџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџџќџџџќџџџќџџџќџџџќџџќџџќ?џџќ?џџјџџјџџ№џџ№џџрџџрџџРџџРџџ€џџ€џџџџџџџџџџџџџџџўџќ<џ№|џсќџуќџЧјџјџјўјў?јќјќ№јџ№?јџ№?ёџ№ёџ№џуџ№џуџ№џуџ№џЧџ№џЧџ№џЧџ№џЧџ№џџџ№џџџ№џџџ№?џџџ№џџџџ№џџџџ№џџџџ№џџџџ№џџџџџ№џџџџџ№џџџџџ№џџџџџјџџџџ‡ЯјџџџџЧ‡јџџџџЧјџџџџЧјџџџџЧќџџџџуќџџџџу€ќџџџџс€|џџџџё€~џџџџёР>џџџџјРџџџџјрџџџџќpџџџџќ0џџџџў8џџџџў?џџџџџ?џџџџџ‡џџџџџУ€џџџџџџсРџџџџџџррџџџџџџ№xџџџџџџќџџџџџџўџџџџџџџрџџџџџџџ€ј?џџџџџџџр<џџџџџџџјџџџџџџџџўџџџџџџџџџ€рџџџџџџџџџ№ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(@€0 -/@CVY`cjnpt~ƒ„ˆ†‹”`cW[nr„‰žЄГКУЪЯжипнхршпчмфжнЬдПЦЎД˜ž|[_ ! '>66GBAEAA622 %'MPosˆЂЈНФбикт рш рш рш рш рш рш рш рш рш_bУЪ рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш луŒ•–ЬЪЪёёёњњњ§§§ўўўўўў§§§љљљюююжееЏЎЎ|||A@@ ;>~ƒВИдмпч рш рш рш рш рш рш рш рш рш рш рш рш рш ршгл)*„ рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш охIиии§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўЯчшкрпч рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршŒ‘ЕЛ рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш-”˜ёѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфффЛЛЛЎЎЎ~›œПЦ рш рш рш рш рш рш рш рш рш рш рш рш рш рш рш ршЧЮ23*+КР рш рш рш рш рш рш рш рш рш рш рш рш рш йр;•™щщщџџџџџџџџџџџџџџџХХХ‹‹‹nnnџџџџџџџџџџџџџџџџџџџџџџџџљљљ„‘‘ЧЮ рш рш рш ршоц рш рш рш рш рш рш рш рш ршвкZ]­Г рш рш рш рш рш рш рш рш рш рш мфІЋЎЎќќќџџџџџџџџџџџџџџџффф '''sssаааџџџџџџџџџџџџџџџџџџџџџџџџўўўЁЎЎšž жн рш рш рш рш рш рш рш рш рш рш ршЦЭeiƒ‡аи рш рш рш рш рш кс ЎДI­АЖЗіііџџџџџџџџџџџџџџџџџџџџџˆˆˆ>>>}}}†††ьььџџџџџџџџџџџџџџџџџџџџџџџџлллtˆˆ#vy”™МТдлкт пч рш нх жнОХ’>B11()01€ƒ„LЏГtОСЛМПЦЦіііџџџџџџџџџџџџџџџќќќЉЉЉSSSUUUЂЂЂ+++[[ZœœœмммнннўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљљљгггЂЃЃp{{$%,.KNHK*+FжЭЭџџџџџџџџџџџџџџџџџџџџџџџџџџџррр@11 665wwwЙЙИыъъпппџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџА­­:ІŽўўўџџџџџџџџџџџџџџџџџџ§§§ССС€€€% -%RRR”““ееесссюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќlee >]/+ѕђђџџџџџџџџџџџџџџџ§§§ЈЅЅ0&& :2+# nnoЏЏЏъъъгггџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџпоо @Є‰‡ўўўџџџџџџџџџџџџЫЫЫH;;1@80(!‚‚‚ЭЭЭшшшнннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўf\\I кЯЮџџџџџџџџџџџџ”““ MF>6.&yyy’’’їїїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­ЈЇXђюэџџџџџџ§§§trr"*&!8SKD<4,$………џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџидд`$ њљљџџџџџџtqq*3.*&JXQIA92*" ЉЉЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыщщ! a$ќњњџџџ1<84/*f^VOG?80(  фффџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјїї*e&!іђђГГГ6E@<84-Gld\TLE=5.&yyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџюьь*_ЭЦХ* NJFA<8$rqjbZRJB;3+$ >==џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџплл( U G.,TSNJFB=/~ wog_XPH@91)!=77џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЭЦХ&/_^XTOJFB2„ | tme^UNF>7/' qkkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџБЄЃ' Bh`\XTOLG0Š ‚ zrjc\SLD<4-$ЪЩЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўŽxw*mjfa]XTPL.Ž ˆ € xphaYQJB:2"LHHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќcCA-bqnjfb]YTPDc † ~ vnf_WOG/5"!ŒŒŒљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэщщ?&9~ xsojfb^ZUQBFU_a^VQA7XMMЈЈЈћћћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџОЎЎ4#l€ | xtokgb^ZVb#ЭИЗ‰‰‰,-,TTT|||ЁЁ ›œœіііџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўў|[Y7Š …  } r ]Z30fTRtkk{yy|||xvu~~‚‚‚)))(((^^^ЈЈЈкккЃЃЃуууџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшттH:5Ž ‰ skMK}|}zzzdiixЃЈЈ– Ёˆ ЁjЅЉNВИwŸ ЁЁ”””{{{cccrrrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁ„‚><As_\yyyeKIL ZM0*)9~‚R”˜N’–,Œ’+|h{|вггjqrcЃЇЊИИhhhёёёћћћУЪژСУЗЙТФЦЯЯёёёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШММB-  ihiZGExxxXWWW ^\ZWi$ТМЛоффмллоппюээўўўўўў}}}šЄмщ\ЦЭСССdkl€„ŸЏtЈrЄvЉІЗУЪ[ЪЮЮуфџџџџџџџџџџџџџџџџџџџџџџџџџџџВ ŸU2/*'" sssvwwcbc&%&oc_\[Z ’]YљїїўўўўўўўўўўўўўўўўўўЮЪЪqxсярю&йфЊве””—pММННž…Ќ кс™мпњњњџџџџџџџџџџџџџџџЗ ŸT# 83/*&" |||{{{TTT id`^[jаКИўўўўўўўўўўўўўўўўўўўўўььь#RVсярюрюпь‹мтДДД jПРПРkGJ йсbнсљљљџџџџџџНЁ ^#D@<72.*&! ††…~~~KKK hca_]ˆJFђыыўўўўўўўўўўўўўўўўўўўўўўўўhrrЊЕрюрюрюпэ–шэЙККqИЈL.0žЄUекw’“["QLHD@;72.*%! „„„NNN jdb`` Г‹‰ўўўўўўўўўўўўўўўўўўўўўўўўўўўЮббV\рюрюрюрюпэЎђіšš›]`мф ВК&=?PLHC>:62.)$ ‘’’\\\hecalиУТўўўўўўўўўўўўўўўўўўўўўўўўўўўљњњOVVšЄрюрюрюрюсюЮъьW`aEHрюкч0)(PLHC?:61-)$ žž{{{,,,mhfdb†B>їєєўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЭЮЮ ,.пэрюрюрюрю:ръЯЮЯsyДПЂЌhn!Š“рю…TPLGB>:51,($ ˜˜˜FGFmkhfc–XTќњњўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўќќќvxy™сярюрюрюрювзz€Шдсясяпэ’š ЛЦЅАXTOKFB>950,($­ЌЌ{{z,,,lkigfА‚ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўююю3LMБМсярюрюрюмшННН{‚сясясясяЩе "ВН…‹\XSNJFB=940,' ЏЏЏLLL&%%lljhj ЭЏ­ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўккк02АЛрюрюрюрю„КН_rtнысясялшйч}…z‚йц4,+`\WSNJFA=84/”””999џџџџџџmmlipфгвўўўўўўўўўўўўўўўўўўўўўўўўўўўјјј———444FFFЖЖЖвбб>@Щжрюрюрю?Шб ЎИсяЄ­Ял\Юж`ъђЦб=@<d`[VRNJEA<4РРР|||777џџџџџџpomkx њііўўўўўўўўўўўўўўўўўўўўўўўў§§§€€€ ЖЖЖммм>Y[ŸЉуёрюзу   €‡сяˆЂЃТЩЪБЛМИППT=<,0dc_ZVRMIE-РППbbb???џџџџџџppoly!њїїўўўўўўўўўўўўўўўўўўўўўўўўщщщFFFўўўђђђŒ‘’MPŽ–йч>}ФбЬЭЭџџџџџџџџџХКЙ12Xhc_ZVR;ВВВOOOџџџџџџrqpnxѓъъўўўўўўўўўўўўўўўўўўўўўўўўфффЁЁЁvvv444ўўўўўўўўўччч–——_~q||Vtv(ЋГџџџџџџџџџџџџћњњS*'6Okgb^CЌЌЌEEEџџџџџџqrqox№чцўўўўўўўўўўўўўўўўўўўўўўўўњњњjjjЭЭЭЁЁЁ———ўўўўўўўўўўўўўўўўўў‘‘‘^hhЂБВџџџџџџџџџџџџџџџ‘tr:IojHЏЏЏBBBџџџџџџџџџs srqzђшшўўўўўўўўўўўўўўўўўўўўўўўўўўўшшшjjj€€€јјјўўўўўўўўўўўўўўўўўў‰ˆ‰abbўўўџџџџџџџџџџџџџџџЛЇІ?E?ММНGGGџџџџџџџџџk\ottr|єььўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўњњњфффщщщ§§§ўўўўўўўўўўўўўўўўўўўўў€€€cccџџџџџџџџџџџџџџџџџџтииCFвввQQQџџџџџџџџџktvtzуЯЮўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўyyynnnџџџџџџџџџџџџђђђЭЭЭњљљHJттт`_`ƒ‚‚џџџџџџџџџџџџYwxvx зИЗўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўZZZvvvРРРФФФЗЗǘ˜˜ЈЈЈЧЧЧхррLNчцчqrqŒŒŒџџџџџџџџџџџџszwx Ч›™ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўђђђNNNbbbƒƒƒŒŒŒГГГžžžвввђээPTrrrџџџџџџџџџџџџџџџq{yvЌieў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўОООZZZБББбббТТТкккћћћџџџџџџтдгUWЮЮЮYYXџџџџџџџџџџџџџџџџџџty{y’92єьыўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўyyybabьььџџџџџџџџџџџџџџџџџџШЎЌY[ђђђhhhГГГџџџџџџџџџџџџџџџjz|{‚рШЦўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў№№№221џџџџџџџџџџџџџџџџџџџџџŸlh^^ЇЇЇzzzџџџџџџџџџџџџџџџџџџv~|| М„€ў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўŽUUUЪЪЩџџџџџџџџџџџџџџџџџџјєѓr"b`їјїdddЫЬЬџџџџџџџџџџџџџџџџџџr~~|•82ђшшўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўссс444ˆˆˆ§§§џџџџџџџџџџџџџџџџџџР™–eeМММ~~~ььэџџџџџџџџџџџџџџџхгв|€~€ЬЁžўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўMMM___зззџџџџџџџџџџџџџџџџџџыооwjfќќќ„„„ИИИџџџџџџџџџџџџџџџџџџТ‹…€~—94№фуўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў‡‡†>>>uNLЪЃЁўўўџџџџџџџџџџџџэсрˆ60nl\ѕѕѕjjjЫЫЫџџџџџџџџџџџџџџџјєѓЮ œ•-&€‚ Р†‚ќћњўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЄЄЃ***yecs t žTNжЗЕђшчълкМŠ‡~rrkъъъdccКККџџџџџџџџџџџџўўўрХФгЈІВhc‹‰жАЎўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЃЃЃ&&&{nmyxwwvvvvvvqыыыeeeШЩШџџџџџџџџџяфуЮž›Щ”Уˆ„ЋZUЂJDтШЦўўўўўўўўўўўўўўўўўўўўўўўўяяяfff/..€qo€~ } |{ {{ {z { w dіїіƒ‚‚gggЈЈЈџџџџџџ§§§бЈІФˆ„П~zЙtpДjfКzvхЭЫ§ќќўўўўўўўўўўўўўўўТТТ000MMM‹ig† „ ‚   €     zlўўўООО[[[gggЅЅЅЧšЅOIЏ\WА`[Ў]XЈTOЈUPШ•’яррўўўўўўЈЈЈPOO322{uu“JE‹ ‰ ˆ ‡ † … … „ „ „ { gћћћЉЉЉbbbLLL^]]qB?|&{xurpjB?\RQ222@@@|||œ…‚  Ž  ‹ ‹ Š ‰ ‰ ƒ xіїїггг“““oooVVVDDD888444999FGG_`_›ššКККИИИR{ † ‰ ‹ Ž Š ‡ ƒ xPюэюъъъхххссснммииигггЮЮЯЫЫЫџ№ўџ№ў|ўўџџ€џРџр?џјџџјџџ№џџ№џџ№џџрџџрџџрџџрџџрџџрџрџрџрџРџРџ€џ€џџџџў`ќрљрѓРїРчРЯРпРпРŸР?ПРПРџПРџ?Рџ?Рџ?РџџПРџџЛРџџГРџџ‘рџџрџџирџџШ`џџь0џџфџџђџџљџџќ€џџў`џџџ8?џџџŽџџџрџџџџј|џџџџџџџџџџџ(@€$QWpu|€~C@?=@ЦГБvaagop\.-6ЮВЎJВК[Ьб‚…„ЅegB‰…„B/1!ЪŸšцгбпш'‹Ž%wxx{yCUtwДНОSVT||$$o]ХЯžlgАFHFЎЊЊЛzuX``oяыь>€…AОЂžЏЗВ‹‡H_b`l{}XB@9 єщщлщ4"!XPOGH„Ÿ kllšЖЗ ЃЏ jќџўTдм"кц­АЎ}šMMOMˆv ˜9. ГЛСр№H‚.&%лфх>A? -2nBAЌXT ЎВˆ ’ООeOMNАБЧ“Žебб231tkjŠ‚baПШЩ687sMP”~~ЉЗЛБfc„IW""dfePС‡†‡ЛП# птрcму0вЋЉэтрY\Z„‹sЉшыщB›–;3273vОРгЙИŒЎЋœSPЖНwttkЄЉЮчч"№єђ03ЕИЖ4‘–K BHBV€ W _sr+.z€+}^™ннY]рЦФr!x}ви<ЖЂЂfv’_~биm ЄLEFIwŽŽŽŽŽŽŽŽŽŽŽŽЅHЅЅЅЅЅЅHЅŽŽŽŽŽŽŽŽŽHЈHHŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽцˆыыzzЩBŽŽŽŽŽŽŽŽŽыЩ7š:ѕiiiœi\ѕnšGчыeHЈoŸЮЮxHŒHŽŽŽŽŽjB7n‘iiiœiiiiiŽŽŽŽŽŽŽŽviiiiiœiiœii\O6лJPЫf(г-zж…œiiiœœiiѕцŽŽŽŽŽŽŽŽziiiiiiiiiižA>>>>й‘iiiiiœiiiiiiBŽŽŽŽŽŽŽŽŽŽжiiiiiiiiiEл>JУн’‰viœiiiivŽŽŽŽŽŽŽŽŽŽŽŽжiiiiiiiiiiо,6ŠJniiiiiœiiiiiѕыŽŽŽŽŽŽŽŽŽŽŽŽŽ}iiiiiiii7вP>>ЫŒlзЏ>Љ”\iiiiiiiivŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽЩѕi\}m‹л>>H!!ЫA“Bnѕii\nBŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽzЛ­аЋЕP>J(– (lx dAfPsKeцŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ[>>>AЮ]ДЈŒŒЖ!н,У(HŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽw>RХ]UHг‡LsqЫJБHŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ >>>>(ŸHUwХХ]ЈxŠ’,sAoŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽN>>1rUHХЬwХкUгs,AЈŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽп[PL]]]Ј3Ь№tХЈЂзOP>>(UŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽН,Pз4кUw33№t4UH>>fUŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ5>>>з4ХХ4Uщ3{wХ]UЈH’>ЫТŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ5JLХ{ t44]ђщт3{tХUHxqл9ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ5>’ ЬЬ№ t4М+ђфт№tХUЈH,9ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽba93{ww˜+іщщт3{№t4UЈЁf9HŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽПтт3№4Ѓ˜˜ђщт33№wХ4к]UЮ>aHŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽIщщщт3Ь{IЊљљіђщт3{{ ХŠ>ёHŽŽŽŽŽŽŽŽŽŽŽŽŽŽ{+щфтт33ХВЊЃ+іђф33wI4Д6>И4HŽŽŽŽŽŽŽŽŽŽŽŽŽ]+іђuщщППIWЊЃ˜+ђщщт{wt>>M4ŽŽŽŽŽŽŽŽŽŽŽŽщ++ђђђфщтП{ђWЊуљ+ђщфтМI†PPqрŽŽŽŽŽŽŽŽŽŽŽwЃљ˜+іђuuтт3тuщщфПƒ‡KP>tкŽŽŽŽŽŽŽŽŽŽŽіуЃљ++kђђuщт5бl‡!dLdл>Г ]ŽŽŽŽŽŽŽŽŽ]WЊЃуіbpЌБ!з!ll€KA(У>>>q8№ЈŽŽŽŽŽŽŽŽŽtЊЊюЌ!ѓKd‰и g(L!€з>>>>>>>PN{№ŽŽŽŽŽŽŽŽŽ№XзЌпт3Ÿ@__ошsZЙО,PЕЋСЋhJ>>>PaХ]ЈЈHHЅŽŽŽŽŽŽŽŽŽ‚ тщщщт5a fУ,>!G‘$6Л7ЪЪЪn  >>>>P>ёp4]]ЈHЈHŽŽŽŽŽŽŽŽз0ŽŽђщщщПcP>>>6чœœ‘TL#FF››`2iъ>|НttХ4]UUЈHHŽŽŽŽŽŽŽ ŽŽŽђuщфэб>>,œœQн#F›F›#ј\Ф>>|НЬЬ{tХХк]ДUЈHHЅŽŽŽŽŽŽ!'ŽŽŽŽђuщфс,>>>}œ‘œœQa#›`•ЄGѓ5ПМЬ№wtХХ4]UЈЈHŽŽŽŽŽŽ–ŽŽŽŽ+ђuuщ~>>hыœœœœœ>>>J ”œœœœй*ŒHјœiŸт3{{wtХХ4]UUŽŽŽŽŽlŽŽŽŽŽ+ђђђсJ>>>sЄ…œœ‘Џš7"HBœzт33Ь{wtХ4к]ЈŽŽŽŽL'ŽŽŽŽŽŽіђђђcJ>>>Bœœœœiя!:œœ…Bеeжтт3ЬЬ{w Х44ДHŽŽŽŽŽŽŽŽŽŽŽŽ+іђђ&>>>>>>,S}œœ…œiRЛœœœ:eжzщтт3{№ tХ4ЈŽŽŽŽŽŽ‡ŽŽŽŽŽŽŽђђђђ >>>Aм}…œœ…Сх…œ……œччŸщщфт3Ь{{wIIЈŽŽŽŽŽŽOЖŽŽŽŽŽŽŽ+++k>>>POА'’Џ:iœ/L}œ7: =v№ђuщттММ{№tЈŽŽŽŽŽŽŽ!ŽŽŽŽŽŽŽŽ++і?>>>>>>P!ŒaУSœœ‘(Л…‰Ен‚ХХђђщтт334HŽŽŽŽŽŽŽŽ€ŽŽŽŽŽŽŽŽ+ііэJ>P,xHH'>лB…“@:1aIХтђщђщфт№UŽŽŽŽŽŽŽŽŽ‡ŽŽŽŽŽŽŽŽ+љ+?„>>ЫЂdА>ЫOє7> ПіђђщUŽŽŽŽŽŽŽŽŽŽ’'ŽŽŽŽŽŽŽŽ˜++V„>>>>>JŠ6ЭHO>>>Љ>>;№+іДŽŽŽŽŽŽŽŽŽŽŽŽŽ(ŽŽŽŽŽŽŽŽљ˜+ю,>Ы0Ђx!P>P0>Pё{{{ДŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽR'ŽŽŽŽŽŽŽŽ˜˜˜V„>>>ЫЫ>>>>ОЧ{ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ–ŽŽŽŽŽŽŽŽљ˜љV>>>>>>>>>>PP!Š>>>JЏ>ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ0ŽŽŽŽŽŽŽ˜љ˜+б>>>>>ШзR1RL(1f3ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŠŽŽŽŽŽŽ˜љљ+>>>>>л‡0L(Эds,ПтŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽL^ŽŽŽŽŽЃљЃК>>>>>>>>>>aШ’sRA>тфŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽsШŽŽŽŽљљЃЯ,>>>>>з0Ы> фщŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ0ŽŽŽŽŽЃуљXь>>>>ЫА>%щŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽKŽŽŽљуЃЃР>>>>>>>>>P01>JэщŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽОŽŽŽŽљљЃЯ„>>>PqА>>>ђђŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽнŽŽуууљ>>>>>–Шf>>PЧ?ђŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽaŽ>ЎЊЃЃ™„>>>>>>>>>PЗЦ>>ЧЯ++ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŠ1ŽJYЊ.РP>>PKlі˜д „[ЎV˜˜ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ0RŽ>ьЦК..Ц>>>>>(xDVЃљљљљљљ˜љ+ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŠЭŽŽ>„ЎЎРЇїь>PP,ŠlDVуљљљЃљЃЃљљŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ!ОŽŽŽЦC))К)ь>>>6А–Г—ЊЃЊууЃЃЃЃЃŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽR0ŠŽŽŽїЇКЇЇЇЎЧ>(‡АзсВWЊЊЊуЊЊуЊЃŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽK0‡0І?юююkkІ‡АЁИ.WWЊWЊВЊЊЊЊŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽsOŠ 'ЖАЖ'€ЭŽŽŽŽŽЊЊВWВЊЊŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽџ№ўџ№ў|ўўџџ€џРџр?џјџџјџџ№џџ№џџ№џџрџџрџџрџџрџџрџџрџрџрџрџРџРџ€џ€џџџџў`ќрљрѓРїРчРЯРпРпРŸР?ПРПРџПРџ?Рџ?Рџ?РџџПРџџЛРџџГРџџ‘рџџрџџирџџШ`џџь0џџфџџђџџљџџќ€џџў`џџџ8?џџџŽџџџрџџџџј|џџџџџџџџџџџ(@€ 1|Љ­џџџ_c“žWX\[ЮЫЪw œ”“ћўќмцК qWV33333333330у33333333фDDEU33334E\ЬЬЬЬЬUTю~pююу33DUЬЬЬЬЬЬC333<ЬЬЬЬЬЬЬЬЬЪ‹ЛЛЛИ‡~E\ЬЬЬЬЬЬЬЬу3335ЬЬЬЬЬЬЬЬЬxЛЛЛЛЛЛЛЬЬЬЬЬЬЬЬЬХ33333\ЬЬЬЬЬЬЬХЛЛЛЛЛЛИŠ%ЬЬЬЬЬЬЬЬУ33333<ЬЬЬЬЬЬЬ[ЛЛИЇЛЛЛЛКЬЬЬЬЬЬЬЬC333333\ЬЬЬЬЬRЛЛЛŽч‹ЛЛЛЛ…ЬЬЬЬЬЬФ33333335ЬЬЬХXЛЛЛЛЎwЊ‹ЛЛЛИ$\ЬЬЬХ3333333334U"‹ЛЛЛЇz~zИЛЛЛЛЛЛŠЎC333333333331‹ЛЛЛЛюЈИЛЛЛЛЛЛЛК33333333333ЛЛЛЛŠчЈ‹ЛЛЛЛЛЛЛЛ~33333333333ЛЛЛ ръЋ‹ЛЛЛЛЛЛЛЛ€33333333333ЋЛЛ‡сaч‹‹ЛЛЛЛЛЛЛЛЗ3333333336‹ЛКfЊЛЛЛЛЛЛЛЛЛК3333333336ЛЛqfюЋЛЛЛЛЛЛЛЛИ3333333336ЛЗffъЛЛЛЛЛЛЛЛЛ3333333336ЛЁiffЛЛЛЛЛЛЛЛЛ3333333336Иa™ff{ЛЛЛЛЛЛЛЛ3333333336f––fa{ЛЛЛЛЛЛЛИюу33333336ffa™–faћЛЛЛЛЛЛЛИюю33333331ifffi™™ffa{ЛЛЛЛЛЛЛКююу3333331–fff™™–fa‹ЛЛЛЛЛЛЛПююу333333 ™™–f™™iffЛЛЛЛЛЛЛЛПююю333333™––fff™™™ffЋЛЛЛЛЛЛЛЛБююю333336™™–––ff––fЋЛЛЛЛЛЛЛЛЛЁююю333339™™™––fŠчЂЊЛЛЛЛЛЛЛЛЛЛЛёюююу3333™™oџЇЊЎwЈЈЛЛЛЛЛЛЛЛЛЛИюююу3333™њw*"%*ЇzЋЛЛЛЛЛЛЛЛЛЛКaююююу3333їі–є"$xЂŠ{И"+ЛЛЛЛЛЛЛюююу3333їvffhˆ‹ЛЅХЗUTUUЛЛЛЛЛЁюу333:s6™ikЛЛЛ„ЬЫЎннеТЛЛЛЁюу333Ї39fiЛЛЛЛДЬЬ(нннEЫЛІюу337s39i–‹ЛЛЛЗЬЬЬ­нюU!ffa333Ї33––ŸЛЛЛЛИLЬЬВююфХvfa333s33™™˜ЛЛЛЛЛuЬЬЫ~юююLРff337у33––ћЛЛЛЛЛŽЬЬЬДU^юхХffaa33Ї333–™kЛЛЛЛЛЗ\ЬЬ*ЬЬ^юUffу33s333™™ћЛЛЛЛЛЛ|ЬЬШ\ЬЬюХ–fff333s333–™ЋЛЛЛЛЛЛŽ\ЬТ|ЬЬTР–ffaa33:у333™™‹ЛЛЛЛКчˆ|ЬХЌХХХFifff333:3333–™ЛЛЛЛЛЎю‡\ЬЄТŠ™fffaу33373333™–ЛЛЛЛЛюючЛЄ\ЄШЛИiifa333373333™™ЛЛЛЛЛъ~ЛИЂr[ЛЛiif33333Ї3333™™ЛЛЛЛЛјŽъЛЛЛЇ+ЛЛёi–333333Ї3333™™‹ЛЛЛЛПћЛЛЛЇЛЛЛІ3333333‡3333™™ЛЛЛЛЛЛ‹ЛЛЛЛwЛЛЛ†c3333333373333™™‹ЛЛЛЛЛЛЛЛЛЛЇЛЛИЖc3333333373;33™™‹ЛЛЛЛЛЛЛЛЛЛwˆŠˆ†c3333333373Л33™™ЋЛЛЛЛЛЛЛЛЛЛwЊŠЈЖc33333333:sЛГ39™ћЛЛЛЛЛЛЛЛЛИzˆ‹Л‰c333333338sЛЛ39™›ЛЛЛЛЛЛЛЛЛК{ЛЛЛІc333333333s;Л39™›ЛЛЛЛЛЛЛЛЛОЋЛЛЛљ3333333333Њ;ЛГ9™ŸЛЛЛЛЛЛЛЛЛЇ‹ЛЛЛf333333333373ЛЛ3™™ЛЛЛЛЛЛЛЛИwЛЛЛК™33333333338sЛЛГ™™ЋЛЛЛЛЛЛЛПјЛЛЛЖ“33333333333Ј;ЛЛЉ™›ЛЛЛЛЛЛЛwјЛЛИi“333333333337ƒЛЛИ™ŸЛЛЛЛЛЛКњ™˜ИЉ™3333333333333x;ЛИЊ™ЛЛЛЛЛЛЎЉ™™™™™33333333333337Ѓ;ЛЙЊ˜ЛЛЛЛЗњ™™™™™“33333333333333Ї3;Њњ˜ЛЛЛИъљ™™™™™3333333333333338w3?šŸš‹КїЉ™™™™™“3333333333333333:w™––џчz™™™™™“3333333333333333338ЇwччzЃ33™™™“333333333333333333333333333333333333333333333џ№ўџ№ў|ўўџџ€џРџр?џјџџјџџ№џџ№џџ№џџрџџрџџрџџрџџрџџрџрџрџрџРџРџ€џ€џџџџў`ќрљрѓРїРчРЯРпРпРŸР?ПРПРџПРџ?Рџ?Рџ?РџџПРџџЛРџџГРџџ‘рџџрџџирџџШ`џџь0џџфџџђџџљџџќ€џџў`џџџ8?џџџŽџџџрџџџџј|џџџџџџџџџџџ(0`%&8:BDEGEGDGBD;=*+   =?Y\nq~ƒ…ŠŽ“•š›ЁžЄ—œ‰ŽНФ ен рш рш рш рш рш рш рш рш рш ктЦЭЃ>\]rlkމ‰ІЃЃВАА­ЋЋ•““ywwUSS)((JM~ƒ–œБЗЭд му рш рш рш рш рш рш рш рш›ЁŒ‘ рш рш рш рш рш рш рш рш рш рш рш рш ршКРЎЙЙѓѓѓџџџџџџџџџџџџџџџџџџџџџћћћпппZМП лу рш рш рш рш рш рш рш рш рш рш рш рш нхaeДК рш рш рш рш рш рш рш рш рш рш ршЧЮЏЪЫџџџџџџџџџџџџтттїїїџџџџџџџџџ№№№ЪЪЪЖЛЛ3ЁЅ рч рш рш рш рш рш рш рш рш рш рш ршЁІ46ЉЏ рш рш рш рш рш рш рш рш нх(ДКНабџџџџџџџџџџџџGGGЪЪЪџџџџџџџџџџџџџџџџџџтххD­Б кт рш рш рш рш рш рш рш рш ршБИ;=$%“˜ зп рш рш рш пч СШCКПžХЦіїїџџџџџџџџџџџџщщщCCCvvvœœœєєєџџџџџџџџџџџџџџџюяя„ЄЅ&‘” ­ГЯз лу пч пч йсСШ’—IL()FH(pryХШšЭЯНЯа№ђђџџџџџџџџџ§§§ЎЌЌOIIJII^^^kkkТТТсссџџџџџџџџџџџџџџџџџџџџџџџџћћћиииЏГГIWX"$LO13> КЉЈџџџџџџџџџџџџџџџўўўъъъsfe$999‘‘пппфффџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџъщщ*"" >wQNќћћџџџџџџџџџўўўЎЋЋ:325.# ^^^ЖЖЖтттѓђђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЁЁишBТАЏџџџџџџџџџдддN@?+?5+! ^^^ииииииџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђёё+QющшџџџџџџВАА,$MG=2( )''~}}ўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўў`TS_$ћњњџџџАЎЎ, 0*$&YOD:/%œœœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚vuџџb$ ќњњЧЦХ7 <60(H`VLA7-"нннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘…„џџc зггAHB=7-ph]SI>4* ~~џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†vuW N.,RNIC=Az oe[PF;1'njjџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp[Y*b[UOIDG wlbXMC9.$ œœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§W:8Mga[UPJG‰  tj_UK@6,#ё№№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђяя= 7omga\VPA‰ † { qg\RG/O@?ЩЩЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮУУ1 jy smhb\WPF k/+P O L JR/,}rrЬЬЬџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”zx15„  z r c XX'$U*'M$!}|ttt999ŽŽŽнннЈЈЈѓѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљїїU(%+K‹ {sD@rhhfhhžЊЎЎЎЏ~ВЕw­Аƒ„xxxjjj‚‚‚ЋЋЋџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУБА>!Q {NKnfe_1.UR=65]šža”—F•r“•Юаа]tumРХŽ–—‡‡‡екк ЬЮpЧЫgХШвеЫссћќќџџџџџџџџџџџџџџџџџџџџџќћћЩППT0-* qppiiiQQQ_^[Y[Wћјјўўўўўўўўўўўў}ƒƒЯмлч‹ЫЯuˆ‰PŒЁŸ=Ќ†З6ЭгХщъџџџџџџџџџџџџќћћНЋЉV-*/)# zzzhhh,,,e_\cгНМўўўўўўўўўўўўўўўПППžЈрюрю`лфŸЁЉОПЛ4WЪб цшџџџџџџРЇІe0,@:4.)# ƒƒƒccc lda^„D@їѓѓўўўўўўўўўўўўўўўїїј%glрюрюрюVфюЇЉБ‘ˆ- ‰Ž\ЦЪTRQNKE?:4.(" “’’jjj&&&ifb`Ўƒ€ўўўўўўўўўўўўўўўўўўўўўŠ•–ЅАрюрюрюvъёyyzWZкхyNJE?93-'"ŸŸŸ556ifdh раЯўўўўўўўўўўўўўўўўўўўўўьээ!KNрюрюрюрюЇло0dg…Žfl!#z‚ны8'&PJD>82-'!  ЁЁVVVlhfs ячцўўўўўўўўўўўўўўўўўўўўўўўўЊЌЌ”сярюрю%нщ–œУЯсярю•žСЭ/DEUOIC=82,&………555ljg‰A<њїїўўўўўўўўўўўўўўўўўўўўўўўўќќќiz{ŸЉсярюрю‡ФШ,Ž•сясяся­И "ЦвGZTNIC=71( ЙИЙiiiIIHџџџmlhЁgcў§§ўўўўўўўўўўўўўўўўўўююю‡‡‡mmmЮЮЮ[klЖТрюрю7Эжh‚ƒоьПЪ ЮкEЫд"ЮйKNW`ZTNHB</ ИИИNNNџџџџџџonkМ‘ўўўўўўўўўўўўўўўўўўћћћRRRппп~Ž — еумщ…††РЬpГЗЬддЪЯЯrq-He_YSMF'ЂЂЂ=>>џџџџџџqplЙ‹‰ўўўўўўўўўўўўўўўўўўъъъEEEЃЃЃўўўЭЬЬYuw…Œ|‰ŠІЙЬЭџџџџџџэщщ< >jd^V4†††EEEџџџџџџrqnД€~ўўўўўўўўўўўўўўўўўўљљљmmmммм зззўўўўўў§§§їїї‘OsvњћћџџџџџџџџџrMJ<kf=€€€PPPџџџџџџ[ЎЦЧrspЖƒ€ўўўўўўўўўўўўўўўўўўўўўмммbbb>>>ДДДўўўўўўўўўўўўўўў„„„ЊЊЊџџџџџџџџџџџџЁ…ƒAAŽŽŽTTTџџџџџџќљљdrusГ{yўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўў|||ЏАЏџџџџџџџџџ№№№ЦГБFIГГГONOџџџџџџџџџuwuЁXTў§§ўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўnnn›››вввСССЕЕЕПППТ­ЌLNййй___џџџџџџџџџџџџpxw“=7љѕєўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўюююUUU}}}zzzЏЏЏВВВдддШАЏRXььь{{{ЪЪЪџџџџџџџџџhzy‚эооўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўЗЗЗgggњњњџџџџџџџџџџџџЖ”‘XZ№№№†††џџџџџџџџџџџџx|{ бЋЉўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўeeeЄЄЄџџџџџџџџџџџџџџџ”\X]\сссuuuќќќџџџџџџџџџџџџu~|Ї[V§ќќўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўвввOOOрррџџџџџџџџџџџџєээlbјјј’’“ЂЂЂџџџџџџџџџџџџЬЅЃ}~†щзеўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўњњњQQQџџџџџџџџџџџџџџџЏ|xhdѕѕѕхххџџџџџџџџџўў§ЇWQ~Бlg§ћћўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўƒƒƒ\TT̘–џўўџџџџџџџўўЬЈІp kVЭЭЭцццџџџџџџџџџђшчЛyu‰†мНЛўўўўўўўўўўўўўўўўўўўўўўўўўўў›››KIIw+%t ›OIЩŸœаЋЉЂZUt rkџџџФУУxxxЧЧЧџџџџџџў§§иГБЩ“ЅOJœ>8ыйиўўўўўўўўўўўўўўўўўўќќќ†††KJJ€93{ z y xx x xrџџџЭЭЭxwx‰‰‰ыььџџџфЭЬЦŒˆП~zЖokЛ{wясрўўўўўўўўўўўўнммOOO`YX‡4.ƒ  €   ~ ~ xhїїї‘‘‘hhhoooЂŸžžGAІHBЅJD C<ЂICЫ›˜эфуТТТjjjFFE‡a^Š ‰ ‡ † † … ƒ yќќќхххrrrWPOU42Y2/T.+M(%C+)FBBccc‰‰‰ЉЂЂ† ‹ Ž Ž  Œ ‡ ƒ wѕѕѕђђђпппЙЙЙœœœ”””šššАЏАТТТУУУctƒ ‰ ukџ~ќј€јќўџџРџџРџџ€џ€џџ?џ?џџџџўўќќќ§ћїяпоОООО>џ>џ~џПџЇџЇџГџб€џШ€?џш?џєџѓџџќРџџў џџџ€ џџџјџџџџ(0` ѕђэоспXtvb”–W }€~E0ЁЃˆ ƒЃЇ№рмM@?-|АГ%glЫср№цхктadbv**ггпшЪШУЭж?’gihSVT[СУ‘–Ыде˘˜љќњНРО ›Ѕv!ЃB;К{xЋЎ­}‹Ž”zv‡ŽsvttPK“[YЫСС-DD’”>\^NQO~OHOВmjnqƒuq,EЎАХЩЇЂЅlГЕЯваtgcnjlX]::~z”œއb]KQ*ДКАИo i *#"яђ№ЩЩГЖДo[[DЬд†ЙTфюИ’‘PœЁ16ОЧ€ƒsE>_ DGE‡4/‰ЧЭўљќ ŠW:9s“–ЇАюъыЕ‡ƒ<54ПаЬOsw]khU'%П{wy–>2JWZЂЄЄщйдTQQЁ’ސєїїS0.УЮ––W/+6;,ЙТ=()AЕЭЭ„‡…BdhŒзкиo/dgH798xzzСЏГŸgeE‘“Žœ …}BЛП~џ§јќџў€†щьъPEЃJEg~~X QŠЧЫШwъ№р№ € јѓіЈXTV pgg^TSбЌЋ:2lomЮжБ­ЏmФШ>Ќ††C;"IvФШ}ts'–œ"$x*')P'*УЌЌb#кш@A@0 … ЈOKMplnГ€{Ілпm.+ЦъчC (“N(#ЗРНЎЊ˜ЭбЂXVVžЎЋz€^Ч<f 2Эд7 ™œš]`^LIGcуЯЭ*>лижЁцц5UЩœv Ђž ‹ŽŒАЙКзНМттттттттОCЬЬЬЬЬCТттттттЌтттттттттттB7гš1НXX1тттттт+[ХХХ 89Ймммй5ŽМ:тттттттттттПŒŒl™™™™c™kMх:=™?š)$†˜ckщоŒпмй€ЌтттттттzхтттттŒŒŒЮc™™cc™"‹Шр‹™™c{o"™™™-оKпоdттттттттт3тттттŒюПЮ™cc™™™cъAГ™™c™™•(™™c˜Щ……тттттттттттт№ттттттюПŒЮ™™™™™™c™™™™™cc™™s(""cOжвттттттттттттттxттттттюПЉ˜c™™cc™™™™c™™™™™Аяъ/QУ5ттттттттттттттфт™™тттППtЈ™™cc™™™ccc™c™™Oxs(Q?Уйттттттттттттттт™™тттІІ— c™™™™™c™™™™™c™Г"™™™˜!йтттттттттттттт№тт™™ттПППЎ™™c™™cc™™™™cc"v™™ccc.ттттттттттттттт,т™™™ттЇІи˜™™cc™™™ccc"™ъxc™™™kLпттттттттттттттт=т™™™тІІЖч™™™™™™™c™™™˜3у˜˜™˜"Юпттттттттттттттттт\т™™™cЉЇП6ccc™™cc™™˜c\­!™™˜"ЎKKттттттттттттттттттт™™c'ŠŠђc™™cc™™™cухюœэЎиююттттттттттттттттттт,тт™cЎн&w™™™™c™˜№хЏІІПІПюПттттттттттттттттттттттszттчн'6' cc™™ъxx`ЇІІІІПІПтттттттттттттттттттттттAЭт&&э/_GŠ Ї Ї тттттттттттттттттттттттттттА­|д„х‡ттfeeee ттттттттттттттттттттттттттттттттууттттттттттттттттттттттттттттттттџ~ќј€јќўџџРџџРџџ€џ€џџ?џ?џџџџўўќќќ§ћїяпоОООО>џ>џ~џПџЇџЇџГџб€џШ€?џш?џєџѓџџќРџџў џџџ€ џџџјџџџџ(0`€ Ѓњ§ћ [^ВY ЩЮЬвм5MЋАY^]r[Y ؗx Ž••3333В"""#33;НГ33333"ˆ††ƒ338ffffffh*ќ_њ›Л8†fffffƒ338fffffffQXfffffff#333ffffffeQU†fffffh33336fffffQ•Xfffffc33333†ffhQ™Сјfffh3333333(U™›ЅQU›333333333С­}Кѕ33333333:НwнЙUг3333333<­зw}йUг3333333A]}дDwлпЃ3333333Aw}tDw}лё3333333AWGwDDG}неЭ3333333EtwwюDGwнпЋЛ333333GDDtюфDG}й­ЛГ33333tфDDюфDGwп­ЛЛ33333NфDDююфGwб}ЛЛ33337юDфDююDDzQ}ЛЛГ333>ююNDDDDzQ{ЛЛГ333~юфGЇЩŸU{ЛЛГ333NъЉѕџљџTлЛЛГ333JЇDЂјѕ˜_UˆwнлЛГ333“NюЁіe№awwннЛГ3393фDСXfl&twwннЛГ33“3Nфff№ Лˆ”DGw}ннГ3933NL†foЛЛВhDDGwннГ3ѓ33юх&fe"‹Л&дDww}н33“3>фAјffVf‹Ж”DGwwл3?334юA†fˆffЖtDDGwГ3933>юЁ•–fofhbDфDt}33933>юС›Н_†ihU—NфDGГ33933>юЁйЛёY…T~NGг333™33>юС•лQ‘~чг3333љ33>юСYŸёt333333ѓ33>юСQC3333339333юЁѕ\\C333333913юсŸѕ\C333333?13юсYу333333?33юьŸC3333333“>ь•Tу3333333џ1>юQёЮ33333333?1юСњСю333333333“ЮьєфЬЎу333333333_3ЬюљNююю33333333333Ÿ3ЬЬZўюююю33333333333?™4фьСЩšюююю3333333333333?šЇЇyŸ3юююу333333333333333?џ3333333333333333џ~ќј€јќўџџРџџРџџ€џ€џџ?џ?џџџџўўќќќ§ћїяпоОООО>џ>џ~џПџЇџЇџГџб€џШ€?џш?џєџѓџџќРџџў џџџ€ џџџјџџџџ( @ OSsx}‚‚†‚‡€…†€…y}Z] %0,+`cˆ™žЁЇЇ­­ГГЙЗН^a›Ё рш рш рш рш рш рш рш рш рчiЇЉюээ§§§ўўў§§§№№№ЪЪЪ†‹ŒЁЇвй рш рш рш рш рш рш ршЩа!"ЖМ рш рш рш рш рш рш оцWМРћћћџџџёёёНННџџџџџџјјјккк„ИЛ ир рш рш рш рш рш рш нх„ˆІЌ мф рш рш вй>ЧЭІвгўўўџџџџџџ___VVVЕЕЕњњњџџџџџџџџџІШЩ*­БУЪму рш нхЦЭ“™()HI~ЌЎРноэяяџџџџџџЦУУK??A>> ŠŠ‰рррџџџџџџџџџџџџџџџ§§§ннн~†† ;=>™~|џџџџџџџџџЕВВJDD-$:::СРРшшшџџџџџџџџџџџџџџџџџџџџџўўў_XX F педџџџфффUDC%?/+''АААєєєџџџџџџџџџџџџџџџџџџџџџџџџФРР\!њљљллл=*LJ:+ џџџџџџџџџџџџџџџџџџџџџџџџ№яяc% щччO'%<4.eUF6'зззџџџџџџџџџџџџџџџџџџџџџљјј$ [ fEBNF=Pp`QA2"žџџџџџџџџџџџџџџџџџџџџџъшш;aXOG\{l\M=.ЮЭЭџџџџџџџџџџџџџџџџџџџџџЯЦЦ[jbXPX‡ wgXH3 |ssџџџџџџџџџџџџџџџџџџџџџџџџЃŽG| tjbZR vHFM!pFBpNKЁ••шшшџџџџџџџџџџџџџџџџџџџџџџџџџџџiDB`t84o^\ƒƒ†Žl’”pz{eee–––ХХХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтйи?ihii<9kQN[Veba–ЙЛ‰ЕИЭвгSŠŽfЗМ•››qЗНH—ВXЋН—птѓјјџџџџџџџџџџџџСГГJ$!" |||mmmCBBd^^ жУТўўўўўўўўўxžЁрю9кфv‹ІЈО&,ЖЛеєѕџџџЦАЏc308.& pppBBBe`~95ћљљўўўўўўўўўЬааАЛрю(сэ‚“Ѕ] qu2„ˆEH?6.%„„„FFFmgbА…‚ўўўўўўўўўўўў§§§Jz~рюрюHуьOƒV["$lršЃPH>6-$ ­ЌЌfffljfаДГўўўўўўўўўўўўўўўиииœЄрюрюuЛП СЭрю•žЅЏXOF>4,žžžEEEllk ырпўўўўўўўўўўўўуууžžž ЄЅ ІАрю3ак>ЃЉ водрЊВ"QT`WNF<* xxxfffџџџporќњњўўўўўўўўўјјј'''BBBТЩЪ+˜ŸШд]ŠŽWХЬмрсД­­0b_VI&kkkџџџџџџrqs јѓѓўўўўўўўўўііі|||FFF333ўўўјјјМФФnz{ВжйџџџўўўU*&]_7 nnnџџџџџџq sv јєєўўўўўўўўўўўўвввнннўўўўўўўўўrssџџџџџџџџџˆb`E{z{ыыыџџџџџџjvw юсрўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўmmmррргггЬЬЬyvL†††ЅЅЅџџџџџџxxмРОўўўўўўўўўўўўўўўўўўўўўўўўўўўыыыllkЈЈЈЪЪЪлллžtpUиииmmmџџџџџџџџџy{К‚}ўўўўўўўўўўўўўўўўўўўўўўўўўўўІІІЗЗЗџџџџџџџџџˆJE\Žѓєєџџџџџџ™HC~’3-ћјјўўўўўўўўўўўўўўўўўўўўўїїїgggёёёџџџџџџюутh`ЦЦЦ“““џџџџџџћљљ)" дЏ­ўўўўўўўўўўўўўўўўўўўўў„„„˜џџџџџџњјї–NIjЇЇЇžџџџџџџчваІQL–2,єъщўўўўўўўўўўўўўўў››šeECu˜GAВupŠ.'skЅЅЅ…„„цццњііЫ˜•КuqМ~zјёёўўўўўўяяяtttoGD  } } | u ШШШ………ccc†VS–@:‘93•E@­œ†††d[Z‹:4Œ Š ˆ ‡ ‚ z нн톆†uuummmkkkyzyІІІИИИz ˆ Œ ‰  ј№№јўќќќќќјј№№№ьијИјxx?xџxџXџˆџЄџРџрџєџјџўџ( @*&(j=5аЦХV)'cEDA=?ІШЬГunѕјі}€~ћіљагб] ~†‡5 чъшЇ­AтяЅ–%(&пш&#RRДЗЕx{y# нРН? ЋА˜E;Рно—ЙМ„‚LDCдзе ЪЮГ†~‡ŽwŠІ3…‡d[Z’20oЋ:6 ž™єъщeacOнрогр,‹JB™@6ХЩTVUX]§њѕзєі‚‰§љћfгЏАRŠrtЁІa22ЅВьчъšЃtМО \<ЃЋkзлйЕО8:9™~zсзжƒИЛяђ№ ­žšx~N€‚1сфтЁЇ6  pЖП бЕБ%ХСУипrusˆb^gЈЈЗ­ЌŸyu E—ЕJ{}mpdge нхдТЦr Ђвг’•“ 6ќљє_ ЛurЛФФA„‡…M!xIBK% HРЩЪ…Ž‡ЖЗ(рюwЃщвв(˜ŸCƒ’ІТЬTХЪhE@ЄЇЅT hki@BAУДА%Ÿ<+­БУСМќџўˆ…€Ÿ•”­АЎrNI>ЦЮ—3%rz{ломw _Ср№r_Xr857кцwcЗМ •псšG=ˆ :2oFDM@<~Ќ­+алTЋНš›вйМƒzݘ”э№ю"IВЙІQIШЫЩP~z|0аЮЩКНЛ†VP)$132…–NJaXW­ДjRNAj ’86ЕБГ"%bec™VїђѕW € /+-œІ^l“’knlŒ-(ьтсљ§ћ ]`^Оym ,ЖНДжкSНП|srw‹ŽŒ’’’’’ЬЬЬЬЬЬZ>M)eм—Ј’’’’’*з^ЯСR’’’’’ssssskйB››йfэG7ssss'’’’’’Rssssssъу›WШBBQVЛssssA’’’’’’sg w?››х=žу›››™еЈqз55z8j:’’r’’’/Cd›››››UнˆaŽЇK#Iо5б˜z8j’’’’’’’ввтBB›B]К‘IЇИO77оо5„˜8’’’Х’’’’/u?›››Ј”…‹ŽE6l\C|иР’’’’“’’’’/­йB››BХ%Ы› ~Ђщ››оо_’’’’’’р’’’’/­ ›››B 6›B›h›››i’’’’’’’’Х’’’’Џ/т››››B›BB››4JЧfm5’’’’’’’’€’›’’ьЄB›BB››››уы‘УQm’’’’’’’’’’р››’ЄьМ››››B›B››‘›?у9’’’’’’’’’’э’››’л.B›B›››››{4й›BтP’’’’’’’’’’’x››ЪлD››B?BB?$››Эч’’’’’’’’’’’’2?›ŠТЁ3B?››уКьВсЄ’’’’’’’’’’’’’’Х’ Н}цйB›ОhЕлЏЏЏЏ’’’’’’’’’’’’’’’’€жЩ;г Y€-1cГГГл’’’’’’’’’’’’’’’’’’’€hр“’’’’c’’’’’’’’’’’’’’’ј№№јўќќќќќјј№№№ьијИјxx?xџxџXџˆџЄџРџрџєџјџўџ( @Ўhlњ§ћ* аЮЭx В КŠ†ис –yЊБnOL””’`dc[ ffjЊЊЁswvffЊЉЊ–ff™™™™›""$к™™™™–ff™™™™Ђ$B"+™™™™Іffj™™Ђ".ф""К™™–ffffkB"GЧд"""Mvfffff‚"о3~D""""цfffffBLsѓ7в""""Ffffff$3?ѓ3}""""#fffff#35џ37B"""#fffffЯѓѕџѓ7в"""Gwfffc_џU_џ3B"""Cwvffo_џUU_>""""‡wvffѕU_ќ<Э"""""ЧwvffѕўнОэB""""$їwvffЬџэДЛлЋВ""C7wvfnfѕB"Й "O33wvfцeџ""I™рw??37vffeX""+™›qЏџѓ3vnfeT""$Љ›™ЇЏџ33fffeє""-к™Љšяџџ6fжfeR""wфЉКD?_ѓffцfeR""юr$ф"?SfffцfeR""MB"т"ЯffffцfeT"""""тDffffж&eT"""""эD†ffffn"eX""""-B"Цffffmb&U""""."$Vfffffв"UB"""и",Vfffffm"%R""-ХјUfffffffж(ˆ""мUUVfffffffmь…§оѕUUfffffffffmюэffVfffffffј№№јўќќќќќјј№№№ьијИјxx?xџxџXџˆџЄџРџрџєџјџўџ( ‰ŽКСЖМДЛ АЖ7™ œœЂ  ’‘‘?z}ЎДУЩХЬЩаЊАЛТ пч нф;дйдэюгггЖЖЖќќќзфф.СЦир пчЮ傆>›ЈЈыѓѓЙИЗ>'&>::ХХФџџџџџџџџџгее1;<TэъъhSQ'<! ‡…„џџџџџџџџџџџџ‘ˆˆ`{VS=TS4нннџџџџџџџџџ–‹‹LaPljJ? ѓѓѓџџџџџџџџџgVUn t/*ƒc`vvpZXГЇІљљљџџџџџџџџџјіѕ.nnne:6[ ДЗЗестMАЖ^œГ'OЕn­ЬєќќЩИЗP&# „„„ZZZf|2.§§§ўўў†ОТ рюFŽЇ!(W[=.,?.iiikЃifўўўўўўжжж/ВК+гнЦб‰:A@N=yyyџџџpЖ„‚ўўўњњњ:::zЧЬYЋБутуS T1џџџtЕ}zўўўўўўгггіііўўў—ЅІчччvD@ŽŽŽџџџ„ЂTOўўўўўўўўўўўўуууБББщщщƒGB›››рррѓъъˆѓщшўўўўўўўўў ›šћћћпЪШi ЃЂЂйииЯЂŸР„€ќћћњњњ —–v‘4,} k”””„sr…ROŽqo}ppŠŠ „ z РРррррРРрРРр €Рр?( ! „srКС пчЙИЗ…RO „ ? 7™љљљŠ [ пЪШЩИЗЃif‡…„‘4,e:6 АЖР„€ннн{VS.†ОТуту§§§ —–йииХХФ œœŠƒGBNP;дйS'OЕTzЧЬMАЖгггƒc`gVUэъъЖ„‚ ›šѓъъыѓѓ—ЅІестДЛpZXЂ  ДЗЗѓѓѓ нф.СЦŽqoєќќvќќќYЋБЊАn W[ѓщш:::t/*'ЂTO>::vvрррit_ рю>'&щщщЎДJP&#ир!(‘ˆˆзфф›ЈЈЖЖЖ’‘‘јіѕS ХЬћћћќћћ^œГжжжЮеБББˆЯЂŸдэюіііЕ}zЩа.ГЇІџџџ?z}}ppЖМ‰:A@ЛТ1ууу4} њњњn­Ь<=гее?hSQ=.,FŽЇЦб–‹‹|2.УЩaчччvD@ўўўj+гнklp/ВКPPt8 #:]qTˆ`lDPPw=(i.\BZ>WePPPP[5RM"ooo€PPPPPP1‚K~ooooYPPPPP+)zooo†PPPPP‰'U џс333РРррррРРрРРр €Рр?debugger-master/resources/icons/openMSX-debugger-logo-256.png0000644000175000017500000012614213560352104023712 0ustar shevekshevek‰PNG  IHDR\rЈfbKGDџџџ НЇ“ pHYs  šœ IDATxкьw|\х•їПЯНS5MНK–фо л€  $„’bH%dй4x7ьц ЄПЛ›Кl …аH !Х@6 1ЖeЦ’›\%ЫВњЬмчМм™ббŒ,pС!ѓ|>ѓ™ЂЋ™;sŸѓ;Пѓ;ч9фG~фG~фG~фЧ?оPљŸіЕяЋCЫ-в$"ѕ"КF„JбКL#E"-ёˆˆKDаZт":*HЏhщжЂ;EГODv‹ш6AЖ‰–ysцЬ™лѓПr~фр8:LєIZsЂgiašˆŽˆЖakA4ˆh’Џ§]б@тБ4бщЧйЏ ˆF4]ZєzY#"ЏˆШK'tRs~њхGŽђшющ™(ZŸ%Ђ‹АPД.з"ˆ xћО}ДnйЪіэлйЕk'{їюeџўшЂЛЛ›ОО~А, ­5J)\nПЯG P@0"‰PTXHqq1ЅЅЅ”••QQQA8F'С$ Zіjє_Eф­хЉ…ЇžњЦ1ћQ<џЪїipOoх5P>РИ31;,Ш а2Ј!к б7;‰оѓ‹М хрИНННЇ"rFЮ-SДл№ккvАцеПБ~§z6lмШ[›6бйй‰2 ”RЉ{C)ћоP ŒЁчJa ЪHЃАџзP e(†}Џсp˜ккZjkkЉЋЏЃЁ~ ‘ЂТkаˆ€жz№ˆжњ‹/~ўˆў оO} Оˆ ЂЪ†$ЧLaO†+•x)ёКDAі вsњnd№ЎoхM*яЪшŸЁ5—ˆшЅ"2жІтšŽŽ§ќх/aхЪ•МєвKlпО•2\R~ПŸЯ‡ЧуСхrу2 иѓоДж 6 hmaY–Жа–ЖэBkDBa˜&n—ЫЅŸeee4651Жi,MMM ќшTЁ7‹цw"њ—œ}ікwєƒј>ѓ3] e^Œpі+/9^P #‡ёЃ‡H–KМІЛAі BЯ/МѓъМyхршўрРehљДˆœ–4 -­[xьЯёфOВъЅ—АјW.**ІИЄ˜H8L(Ђ   г[–mШZtЪЈЕЖа–иЯЕ§К8е–NЇБDлїVт8mй€cИ]n<>Ÿo EcCуЧgТј D #vШ`ы ‘;пїОїн~ШУ§ЁrŒђWQЅ5˜Ѕ)ЛцэГzx† \IЦŸВНQЮ7O€AшŽ6и;‡шіцM-GlDcБjД\ЉбŸ‘rDшъ:ШВeЫјУф…Wa т†ЂИЈ˜šš***(--Х0Э”БІ<КжhЫzœ4f­maY ЃжЯЏ-Dkћoкё7ЫБ’РЮДeЁE№zНј§ўћ(H…uѕuLœ8‘‰'тvЛэ0AЫ^љ•љх\А3=ІџФBTбŸ1ъ PžWZeёъYМxЖзEй ЭёЋи‚nыCœKєоПцM.яxФуёqZЫUˆўЂ h /ОјїмsїпПэiQЪ ІЎ†Ц†&ЦŒЉO‰pIЯi№–Жје]c_ €J ‚№Ў”сЈl†"NG$ŠШ"ЊoжЄЦiЫrА›]$?[kћu—Ы$ ‰ G@)L—ЩЄ‰™8i"хЮ,УЂхчМфwJзa6 QtЇcVЙЯ7›Бцђцiљ;8€Х9›DвŸkйж‡ьŸNєЗ-yгЫРЈ‡eYu"ђu§Х„`ЦВe№ы_пЦЪ•+1”‰ИzъдЉL˜8H8’0v Ыс•ќЃ)Мџђ-PзЃ LT(DŸьJ%b^IŸаЮX8sЂЫ1xН&С ›ЪŠеU!Њ*CT”ју_NБ ­­ФMcY6CpЛ]—P^VF @)ƒЊЊJ&NšDӘ;M)šЧž8Рƒєббa9XНЪ №2‚Бч№оiFЎ†ОЃdшУ ?L`экFє–1yѓЫРˆCkэ‘ыД–o‚VZ„Ляњ ПМщ&жoXŸRсgLŸСЌйГhjjrФэіэњыЏњŽоOдЁ‚'BсgСsЪ Ъэ№b’§—Щ/;iЕ —Љ№ћ]њЈЌ 0a\ Ч—PSЂЌ4@$т%№ yњ‚Aoћ‚гыЕ3ŒА†XJ$ЁЊЊ‚ЪЪJ”aPTXЬЄIihh@DАДц?іАь=Xкљ$8”з—с?хь%‡Q;ўAe!чБ)To:~ФрзцЭ0йŒџ2-ђбК~{п}ќєЇ?eCѓ”ЁpЙ\,+–O•йhцПц вB(GЈ Q]O3xы™yГќ™ŠШ Zф сWПњпќц7щющFЁXИp!^x!ххх)хќSŸќ”:Ф{†™Рє––}sпиДЏЎuKї„}ћъЕ(Д&aь:ѕ8 Z VмёX'ю“Ч'AИ=‘—ВВъk#44RSІМЌ€pШ‹ЯыёWЮJЅџSoo”†ЦšT&!0eЪdšššpЙм455QYY‰haУыQю]жУЮ]–ƒž“<“”=УJ%ƒцЇРCхЮ$ЄŽЁXhX2HHл>n)Я›ц?ˆШ"мˆhї[›[ј—Џ§ >ђЪP456qЩЅ—0sЦЬT>ўт‹?z(УŸ Ьf`=ЙќѕйЭіЬэя'ЈЕ;ЁиF'ѓѓ њŸTу-I7њ4 СчuŽxЉЉ б0&BScuЕaBA/nЗivn”ДŒ ДДtXhPYYЩЌ™Г(--ЅЈЄ˜1ѕѕx<^bq‹{зЫѓ/Dг3WІР)є‘%іЯ)цв2ПDR/Ш4*И'ЦрMžМyОЧ@Dn‘/ˆwмqW]u}}}(ЅјјЧ?ЮХН8Uiwс…ЉоЧ œ ,ЪИY€ѕч'о8ЉyУољZXкL3ъЁєлЧ'М|ZЬзvб”Љ(№Л(/R[ЂК:DMUˆŠŠ ХE>мnгўa•ЕЧёg2‚ККŠЁtb"Э9}њtN8сLгЄЎЎžтт"D4Я­фопїƒJxџTfcЯ>Ђс‚Œњkц К]3ј 3oЂGwИо%Ум!Ш)"Т?§г•мvл­(Ѕ˜2e W^y%уЦГWо‰тќѓЯW9оЧ|8№& >iј  НЃ'‹сsЙ<ФуЩxеіЪ–•œt*ёo 1EйЏ:ЈЏТРВхR„‚JK hj,b\SeЅ„B^‚A.—1Єъ†С 8 мьппIqQбCЗызЏggлNц/˜RаззKuu5ЇЬїPYwнзGћ~эА5ХРsеў;C“3с/ŒР2пGeЯ@%о/iaфЭє=ФDфlрn)_ЗnW\~/ПВC).Нєу\qљхЉкњ3Я<3—с+р#Р…иkXSоољИЅЕНlsKGню=§ЕФЪ, Дdx§ИэеS4?хO~ №љL*Ћ‚њSІЉБ˜’?~7n9ЬS)‰ФуšввтŒ‹O<‰9'ЬСя+ ЂВлУСn‹Л~лЧ›ЌсFŸ*|ЪцЁГа{дмaA.ж@@ШШF(zПфAр="r№kaйя—qйg/ЃЏЏH$Т7Оё -Z˜ ГšE‹х2ўs€K€в,†Ÿіќљ•-SпмДof4ЊмZ›iТпС;шПЄAЌ˜Fћк{Б,MSC'ЯЏcЪф2jЊCј§юTпЋГ‹˜јМЂЂЂŒХIš††ŸБ˜@A€ВВ2ќўсопїёвпbYlVgf./#dШ.џgy5МА(kХ€юд о˜ўž@DЎўCDјЩO~ТЕз\‹2sцЬсКыЎЃКК ЫвЬ›7/—сO.feёіˆ;A`07^\Еmкц–§гД6А,•0v=”ъЫ№ќщ`Лeы^Гƒн{zhj,ф„йUœВ ŽЙГЋЉЌ ИГx}оN|Dй€ˆиЋ S‹—4С`€%KЮЂЎЎžp$L0DDxјЯ<ћ|ŒCЏPYŒŸ p0ШU*œѕ_еP–BЗЧМ9/ ў=€ˆ|фџŠ†kП~-?љёQ†С‡>є!ЎПюњ”’=gЮь\ЦџyрS‡ђјЩЧбhЬиПП/Асѕ§уЖo?8Юв8”ўьоп Н}1^]Г‹зжюЁc?с‡šš'ЯЏуД…ѕЬžYESc>пч?–4€ GвV5jmqцYg1cЦ hЭ“ЯFyт™oЋЧЏяИХ—Оќ%ўљЪ+SЋфІOŸЎВќя4р`r.cЯ``mлОПtћŽUээƒх=НVФВВОƒ$тќm]МјRЏМк†Nад@РMSC!3fTАш”zЬЋЅООHи—хЛ[Я(F‰D Ll˜7oЇ.\ˆЯуС_@аќхљ(=O/ЮЕ•Ѕт/Гд7#{рЌ@tNЙдgЈєЯ•E.Hcэ]MєжѓІћwpџЅ—\Ъ}їп‡Ёп§юwЙфcУвТЄ уsy§O_svІš”вОїъР’НћzcQ\†2ьwЂЅtк[(omоЯsЯoe]ѓ^œUq>ŸIIБ‰J8щ„jfЭЈЄБЁˆ`а{\zўLсБЋЋЫ ТCV­ZХ@џчœ{єїсѕzYИР…жšЧŸŽ ё3+љœР œй‚фё5тd jHWH} ,$7+HЁЋU2Яgў•шџ/oОЧ1ˆШїЎбНјb~џћпc7мpœ–hЦ64dѓњ&№џ€ 2Œ_e|.ЉAЙУeš‰tŸж Жё[ЪNѕ)eаМaO=нJѓыћвWќ‰рі˜T”˜<Б”9ГЊ˜3ЋŠ1ѕ…žaqїё>К$ cЇ?aэКЕDcƒ\tс‰FqЙ\œКРE,Ўyњ9+aИЮ:qRœŒЅб:Cа“єЅЩш БпБpˆ\`с •QaЈB?LЬ‘ќ8@DЎјП"šK/Н”п/[†2 nЛэ6Ю=чДждзжg3ўqРOЉ уMшЂœра?ѓŠ(ЗiКЌQ#ЂРДћџ‰XДlытсGоdЭк=ЄЅЙЬt„B ™=Ћ’йГ*™8Ё„т"џ0/{<ф9*Ѕ8иuаn4bУЏПўЫЌe,]њтq C)N;йdpPГbUсrЎњsЦцY›8‡f)+&‹ёЇРХf8GzгP~№~!Ър-yQ№xгDф2D~­EИќђЫЙуі;P†тЮ;яр}чОKk***Вџbр@8G|( РкПП7Дw_OQ{Ч@ЩСƒБBч"ЫвьнзЫВ_ч™ПnЩ>‘ЕSQ\d/у=eA=Ї:†г+S_ˆлmў]@І&GRэЬДЅ?a<НјЃ‰Џoї!ќУc1^[ge‰пIgЪѓ;sљђЮЇcf“Шдkџ ЂЗš7ууDфly\DИікkљщOŠRŠ_џњз|№ƒФвХEХйŒџbрЦ УЮ4|}0оКЅЃfћŽuƒƒтБ,вVћ-ћУF~{3qK'&Ћ Сыs1nl1sfUqЦiœМ Žšъ0юу6ц;@ "FRн‡ДЅ™ŸћяоѓФ"……CmЯЕцМ|€љѓцбййI<чok-ž|V‹LCб0І˜K?6‡%gL`т„rЪЫCяјœb1‹ƒXГЖляz‰??Б‘ЮЮ~Д †O[€С_ц7К}УuŒџ О "\ёљ+шяыхЌ3—№ѓŸџKk\.W6уПјI5п:HЉ;HОўXАѓ@ёр`мwЫ­ЏrзНыг›^бМгѓ.E0рІЖ6ФЄ‰%46RZR€ЯыJЋёЏ gvр@g'EЩ…(§гŸ(--ЅЉБ‘і}эЬœІиНжmЊŸ№ћ\Ь=Ё–+.[РћЯBQ‘У8Мѕ:nЗIII€SOnЂБЁ˜)“ЪЙїЗЏђЦІНФ­Dц7[/B(/x.пAєжкМIПНqXWM[zЊn­ЙђЪ+yх•WЈЉЉуЦ_о„ЮmќўлсСЭ™ЗфkFЦыУž[–x6mnї|юŸtпuЯКt#ЯlYх|=С м”—ЈЋа0ІђВ~7$кwНЇ) R8pг41]†iђРВшяяЇАА­5‹ ХEіO {8џМЩ\џЭsЙј#Г)) Жё;‡зыЂБЁ„Я|rпџЮћ9ѕф\FВžРЦщŒkь­Сѓ‰<K En@Ф}ЧwrлmЗa(ХЯў3*ЪЫэт›сЦ?Ис•}ц!Т5ТkЌ~eGыв§ІВаФоЫƒєИейЯ>хљэ{УPFМдж„hЈ‹P[І0тУ0‡DПї*8™€i˜$К аззЧƒ>ШхŸЛœСшvsк)šgџъчтЬц —ŸТŒщеЃŠёп)(UU…9ћ,ЛпсР@ŒеЏl'ЎL лЂ#eО иiфќ8к џЋˆ>у­ЭoqѕеWЃ”С5з~гO?­5С@@eLЖ*р—‰+f%hМхxЌсщГБзŽЖ§wœїСЛWѕš eцXІЪрќ›>Ÿ‹ŠŠуЧ•0n\ uu"aŸН+pъмпћЁЃЃУ41 Л•й[›7ѓФ“OPVVŽЫхЂЎ>uiџrеbfЯЊ=jЦя‚gŸ5‰/џѓ"&M*Ч42+ŠјBx>1;oжGтёј љЁˆpЭ5заззЧЂгqеU_A[………й\цЯjrєXp9ю]9@AНёцЮыъЦ~ѓ%0Ъ‡іЕAэwюђИ<&сА‡њк“&–вдXDyYЏЯ•aєяmHn9жбоn‡†‰Ы0xц™gxkѓ[”WT ZmІР=ІчцѓЙЙргљќgOІЖ6‚J…ozшІЁžђ>—7ыЃ "ђя"ТџќъW<њшЃ˜ІСuпњVмЂЌМ<[мџ-рd†ЇѓтЏYŽѓrРvž4у{ЛСНє,[RУщПѓ^Ѕ”KТ!/uЕ&L(eђЄ2*+ƒЉM;оыБЎБoп>Œ„`˜&?ќ0С`ТЂ"D >ј‡c~NС ]|џи\Š‹ ЏГžC†^УФsqОЋ№б€X,z™ˆМoїюн|ы[пТPЧЦПбии„eeћЯ.ЫтэГхіу‰›ф0~АјRъepOу"ЉiонY‹Ž#Б|НЈаGC}!уЧ–аиPDQЁ?Ы{*эїv‡iиЁ€Ы4шhярO?LMm ІiвммЬŠ•+Žљ9••…јЬ'pоћІтѓšщFŸd’˜6*ќZоДФЂ1Зп­ЙўњoгннЭIѓцёЩO}­-ъъыВХ§зх№єё!Й­MІёџИP)ЕХўЗ\х9˜(‡чwjІнлЏАаGeeђ2{зŸЯ•PДџ1Нєіьйc3УVЎXAkk+55Еh­љуC$ѓѓ7ЖŒЫ>=Ÿ9sъБ/“NзRЊЬ›іQОNk]їЬГЯђ›ЛяFŠ/љKvŸМІІlVs-іЖлNК?аЧ%uЧ€ѓ•R‡ооэ—a ~Gь/C€щ6=”—йЛі$vя1ВФ?тиН{З- š&†ЫфЯ§™ŠŠrТс0ћїw№№УѓsRJ1{f=~`ХХў!ЃOіxФєQ&x/{Š1CЩ‚_fЊ(ƒЊ*ƒŒ[ТЄ ЅTTqЙŒ”зџGіќNцГГm'ІiиB.“ЇžxПпOyYЂ…Gyє]asfсќїЯ М,”Є5,q)<Ÿ8#oтGЦiб_дР џu†ЁјдЇ>E0dцЬ™й\ц@ ‡Qы<Пs<Ў”Z:ќЌ}SPЎѓ™’}gЪЛй*pЙ ‚ХХ~Š‹ќ„У>МYњљч‡=кккRZРР`”ЇžzŠ1 ˆO>ѕ{іь>цчфё˜Мяœi,ЪЫD">мŽ|ђ#;0 #Q єьГЯbi‹Њъ*D„ЧћѓБŸД†Ayyˆ9Гы)- ІЊсЮ‹‡ }}}еZєЕ7пќK ЅјШвЗ4'”Е‡џЧГљЁbќЬл›РeJЉбib”ЄŸО^0œТћщRƒЦд2}j%uu Џ”[К 0сЋ§ВT:bЗл В`ЪфrjЊ#ЉТgь›УdZа0 ž~(Euu5Z„Їž|т]9ПЂЂ“&TЅЕкFЏ /€ыЧљ+y E^DИ§ŽлQJёїŸ‡жVЎ­Л.Ъ!юeЃџЙXС—”RЭ9OШ§сТя‰ IDAT?ЪхAЙ‡N_2ѓ§dh‚2I0рЁ0тЃЈапяЮ{џQŽжжV\ІišИLƒчŸžІІ&[ xђЉwхœJJ‚|tщITW…•€ @ЅТ€Вќе{‡аггs™ˆ”ЏZѕ/О№n›%gŸЮ^ёЗ;Šx?>8|G)Е<ч Љ)n”ЗŒHJ§— ёG2™€]2j(pSTш'ђтѓЙ0|ьџvи@В<и0LVЎ\Iqq1%ХХtuuёєгOП+чU^ЂЎЎ—iЕT)№\:!пˆшOkбм{я=( –œy&>Ÿ%K–ds›чfёъёC„ЮПнЃ”КkФГѕ,œŠrєддN1Ю ?П$ёzMЊ*CLœPJmM„`Р›J§хЧшЦ[oНe— ›&бXŒ_x!Хž}ійwЪУœо,BaЯPIАвщŒ@y~•Пzo<8C„гКvГlй2”ЁXДhQ.я?3‡ї?T(|}ЕRъћ‡>]з4P€5mh“ˆЬE!у—ЁІAUe уKЉЉуїЛŽњ’жїЂ`š†НZа4YѕђKŒ7У0XП~=[Жl9цчxij(Ѓ Р“ §:НРž'чЏтлЙDkЭ<€Ѕ-&MšLm]V–дp:йгyЃYа|o”Ї[Ць­С 3цOПW‰ќ(фЅЌ,@8ьMџђcєУ4 {Е aА{ч.ZZZhj‹ˆ№мsЧ~%ЎaлX†ЉFЏєPXˆхЮ_ЙЗKE„‡џјG”2˜7я$Dk.КшЂЬЊПrвЗьЮЌы?Tрп•R­ЃsEfŒвДoи є5џ†Љ№Иm0ђRPр&KŸвќХhnоlA№еW_eьи&D +VЌxWЮiъ”N9y‚нХЩYфмNЬsЩфќе%8pрT=vЫ–-МИj•]~9gN.яП`с/зѓdmРCJЉбз“*УУMІrЏ2nŽђPЅ~Џ‹HиG8ь%№рё˜GДн?мЄ1‡њМікkджд йЙsЭЭЭЧќ| и+гњЄщпЭ_ЙQ€ˆ\ ExќёЧ1 ХЌ™3ёz<|єЃЫц6O`фjПL!0љ|'vsаЗC@•}ЪЋџdxЗŸфk !№PZZ@qQ€л•3ЦЭCkыз­OБ€h4ЦкЕЏбидˆˆfеЊUЧќМтq‹ТТ*ЪУŽ€Ье gцЏрЈ@Ÿ'–?§4 ƒiгІчjђ9(fф‚Ÿ\aР/sWњeоЯСєЂ\Yџє.ПЮНўŒDу1ѕEджF(+ фѓџGŠ$@`нњfšэlРЛ†Ё8qюX&NЈrПsъ (Ћ0еFЕfJGG;/ПєЪPLš4ЫЪJџgф љz„з4№ЈRjхЈЯвuЊмu  УqкYЊ%sЗ_!ёQ[ІІ:Lqq~П+яѕsИLWЊрЦЉЏЏЧыѓВuыVЖoп~LЯE)EMu1~Плž^’Б.@ ˆ•Gќб€ˆœ%ЂyўљчQJ1vьXМ^Ÿ§ьgГ§€“9tК/ГЈИѓэхфqˆyшqЙЛѕ8ЗŠJ_фq."?wЌ^Нкж\бш ›6НIC}"ТЋЏОzЬ@)бCA™ЬЯХСќ•;hНXД№Т‹/  ƒБcЧцЪ§‚Ѓќ2Р=JЉюЗwšюё Ю=~иХun%ЦЏьнj].лО9‹ђ,р№ДгБ@hгІЗг0aЭš5яЪy•–„ёІњfщЅМŸЮ_Н &—љ‚FŠРъ—WЃ”ЂОО>—њ?.aмfфšYєф§›JЉЗ_8ЎЬrP“QT Зу^{џ%€мn мј§n\.#mЃќ2рwюqэeТFъgoйМ™… OEkЭkk^уЕз^уѕз_ЇЙЙ™з_––vьиAWWбhЧC$ЁЖЖ–ІІ&&MšФдЉS™4iѕѕѕО-Цуq1sF=ЗпЙм.ќP™{ ЈїcoCŸй`Яž=SEKy[[;vьРчѕR]]+ўo`ј>~™@ МCЂСоSРŸЊя– уЦ Џ‹PШK$т#єрrX–ЮЇ H‚кmлБƒ@ @8цР\yх•”””аннM?ZыTЧЅф-‹q№рAZ[[йГg>њ(лЖmуoћў№‡Йф’KXА`@`Фsёћ=LR—с2і1™‘Пj#€ˆœ$"МікkЖАRSƒЅ5W_}ufё7aVyyЋБ•RпЁЯёЂІ]œЕџj8#АLEпEYi€šъ05е"!_^§?‚cхŠ•œzЪ)X‰=ЗlйJmm-ј§~&MšФЄI“hllЄЊЊŠввRЪЪвчэлЗііvvэкEkk+ЏПў:Лvэ`яоНќц7Псk_ћSІLспј3fdЗaЗл…Чуrˆ~Щmр’l@R’Пj#€жr‚ йаМЅ•ЙМ­ƒў;=~цkN…ю‘У ‚kШјUzЭПsgG`ПЯMq‘ŸЊЪ5еaТyћ?r€™ §uЧŽэTWWГvэZ>№pѕеWђНЪЪЪ(++cђфс…zЋV­т‰'ž`нКuДЗЗѓэo›}ћіqћэЗ3nмИaЧїіžVaaм›Пz#i"Гx§з1”ЂЌЌ,kу ’єэYГНѓёsJЉ]‡A6SLЅCJЖцŽ{гPxН.BA/…?~Ÿ+ЯŽ№0M3‘QьlлЩЂгNC‹А|љr^xс…УŠ§чЭ›ЧМyѓјжЗОХ‹/ОШ­ЗоЪж­[ЙъЊЋИшЂ‹ИќђЫгЮep0–X˜иMX=c€Ю_ќ€Ш4Э[oН…2ХEХЙ@Y†ЗЯЖ'—ЫёxљaЪNщїj(ЧŸiєЮSPЪ.ёx\ј|.мn­ѓЂпУHДф‚н{їP]]hMWW===G,іŸ?>ѓчЯgУ† |я{пcХŠtvvrЭ5зd0gfHљ Q ђЕ9`GлŽ:б:вОo]К№xНСЌл}%9@Їu%wїyA)u˜ ф8Ѓ2`&CчIfиHN #A"ђрШ3€$н>иuЗЫE  @wO7W_}5“'O>ЂБџ”)Sјпџ§_nП§v^|ёEVЏ^ЭмЙsбZл)^•0z‡ЈК@~dбz‚ˆАuл6”Ё(,,D[пљЮЗ3@?рs„™a@&(ќѕАЮаѓљ оЌ4?›ё'Р0вA ›чЯЇ<ўјуœ{Ю9X‰@`o{;eхЅь>H]]]жиўHФў—]v Ќ]Л–ЙsчbYŸЯушфS;ыќЫ Ў“&ЃEšДvьиRŠp(œ+џ_ШЁwјMНЊ”кїŽЯЮ{IхšЮіЮBюэКкPИ]^iЗў2ѕЬkGa9 ‚:їяЇДД ­5mmmяш§’qџ+ЏМТwПћ]Š‹‹щыыуЊЋЎтж[oMЗxёт4 ‡§ ‰ТЩrрФЎA">+?œр-ѕ"bя g( ЙтџЙ{ћg‚СъУ §CuР (]—sх_ZР!0 EпшџgІХŸљqЄuУДї 8p ‹ттbD„нЛvі{ЯŸ?Ÿ[oН•ЛяО›P(ФŠ+јб~”њћ‚ ьЉЂХE‰‚Фб’ЬнЂѓ#ˆHˆАwя^Р Р_‹yУфmЋRjыaN­r”1 ‘Š4=№PN$R‚Ђ†ъGђ#+„AЪD ]]]JсvЛs1/C .с/Ќ?ьГU Dв2Љ2oчвп ё…|TUF(*єуv›љ РQ—=%єї…-ьпtv ZМx1>Ÿ/ƒ(ЖlйЭА‘ф*MЩ4аZ‰@OOJ)LгDЧ­\џc1МшЧYћПA)%G(UŠ"0Д€ШGzЌx(). Д[€чџЅР0RкЫ`t€P(ˆЛрhdьŸ–Ѕy§эC,P‘ХcфУР\@PDB"šОО~0 ”2ВvJ@Ж.?Ю%Пoћ/пCoћь”ђСtЩЇo ц2 М^љwЕ€JджПлЛЫь €Ыp‹Ц№ћ§h­щэщ9fчЦx~Х:RЊZ_@M^<hаZ‹E1”Bф йЛќ$A #kйяРvя'G_­p%@ CљwФћ’cэЗу–i$Ч; ШЌšЭэнfF" -ЯчCњњњŽй9єєєГqуж!#чі`IчgЙB€€€„xЩ]dЪŽчZ –ЅбљџЬѓ;x№ лЗogЫ–-ьоН›§ћї‹ХpЛнSYYICCuuu„УсarЌ€JiŠЦэі ЂŒFй9tvvЃŒ„с'7ƒРй'B%рП€џ6yHtбтв‰Š9Ѕ–жЈьuBzРЬИ]ъ/zOмљє…• NўP Ќј€QXyЏЛ{аb§#Ѕrdиў–жФbквЧ}PђќD„ŽŽZZZXНz5ЋV­b§њѕlнК•ўў~ќ~?cЦŒaкДiЬ›7ЙsчвддDIIЩЛІq˜Љў *Q’kї\ŒЧbЧьЗлГЇ“П­йфX§—№JK`~ЌЏ$ўѕрgиѕ*]џШрбЂ-v ­Rhm‘=HЎАH[№“няДюпiќІЫЇё^5JeѕќЃZk,KАЌу›ђ'iЧŽЌYГ†5kжАvэZZZZиЙs'эээФЦдззЧрр нннlлЖеЋW3yђdІM›ЦŒ3ЈЉЉ9ц,Р0] ЌФїАлА‰ЂMо=ЗиЖ}§}§CЁЁгѓ'gЋiтqќ-j8k-HћyРy‰Зљ6pА јGSDт‚vЛLZФŽџГ{ЬЙзџя8ВаžбьУЩљsf†b­…x\sМ†ќN‹ХXГf Ы–-cхЪ•Мљц›#ФЛ=lкД‰M›6ёьГЯ2aТN>љd,ЫЂММЗл=ь§n$i 3ЁhбЧŒqEЃ1Z[wВkw‡#ЬЂљ‰‡Јљ…й(з,А6ЃтБ\ ј6Аxј5№к?  ЕDEФэіxˆFЃФЂq”'ыŒ“о—л ь:ВbOумТПщ%уŠЋЄ>x|ЏPJЅ<џЃ>Ъ+ЏМBQQў№‡ Фуq6lи@sssŠdŽЭ›mй%Йtvіьй)&plD@3uЉLг nYˆЖѕЄa9ћ#qZЗьdXfZ9V  <щ‚Бйˆ˜_ђЂ‚ѕ XЏб:р+‰л#РWVоЃe„IАDtЏˆќ>БX ЫŠcYЦHй T{ŽД} oњ‘ХѓK.†PЩ9~A йEwйВeМђЪ+єііrжYgБtщRЪЪЪиЗo=єЄ­­СССaяaYVŠ1єііbš&еееЧьћšІi‡зЪЮDЃ1ДBœOњгмwп}Glл–,Rщ-Сœ§#•›a{I(ї"pЭЋт§$ТƒѓЌрgР–ї$-<*"н"ППУ0ˆЧcшь"Р йэ="Х?Ѓ3›4І—Ю2ЫВdјнччwttАfЭVЎ\IAA^x!gžy&“'OfьиБLž<™3Я<“ЅK—2}њєпwѓцЭЌ\Й’ѕызгббqЬОЏ+БAˆiј§~њњ­ ‡4їп?ЏПўњQаоо~vяйO*ч/ЙЖŒѓ2lУДѕApЭяХ`ЬС.AQIV№vaђ{ DKЇˆ QJ‹ЦsЅЃdпЄуЈиyъ–^ф“Ўњgћ›8BAAыуС8ўьЗлпяO[5788ШъеЋ‡ЕМzЛУяїЇ*GыёwьhуЕзж№№—ёиcГ{ON 9§Xz‘mЬ6h­јя;эB K)Š‹‹йЖmЂ…†КЁхu5PUЫ—/gЩ’%‡§лEЃ1^\Е–ЕЏН9dœJ96Щ0~хrj$сЯ‘Ar: бйMN,з1Ж/Д6оъ ~\ ќИnxЯё} ,ш|~ХŠЎ`0 …ƒєѕіaХ5‹ЯX,Я<§Œrx KDАs*ЩRрЃ#=ЯPџ%}@ЗЫФŸЛ шјХХХŒ3†СССQ |ЃС`1cЦP\\|HЯFyхе5МАroМБ…-[Згкђ7:˜2Ц6A8ХE0sКbжtƒЊ E0.SёŸЗ|УАE( ЏЏŽŽ q*+†d!Gё‘ ?љёїD„ііNокДƒннŽ~џ’ХјT8#%8§O‘‡,:@N1љУj;д0Їƒ*Гt:рЧџЊ ќWТ~Ž ˆк 'ы9ЅКЊŠЭ-­X:–+—ќC\)uПH–]@$ dжИ\vCг4ˆgяnєЎŽЪЪJІM›Fww7›6m:bя[UUХДiгЈЌЌбˆйКu+~ьOмsЯohmнж1JK`Ъ$XВXБxЁЂЎF иoi@њћэп9ЕEИR”•–Бyѓ[ˆууУ@gl“тџѓмaПОО~xp9Ћ^^ыи (YєЁВˆ…†HЋ8(ОЪсЭ%ƒђK&d†Э Fх`”оcktj?–џ<œ%Є>ц`EбkDє)ее5ДДЖк§5Гы}CЊ ЧnбЗS”,БFІРж<‰ xќ 0 Ь›7mлЖQЈЉЉaоМy444dѕњћYПО™W^ifЭšЕДЖМH8А%Ї[45@yTVТф ŠІƒЂˆ-јY–b0 vdЈ™–ФЮ@JQ^QЮњѕыбZ3qмp§aў\…жА~§zІM›іŽНџн<ўФ ЖmнщˆЯ“КЮиX Є ЦЮТŸLёO9кŠ+'`do?Ÿ6SяяHe`”‚о ж[N ˜‡]^|№ХЃЎЃl §Šддж`({3 +>Ђ(‰ЧЧЕ`(N3 u\ЗЋЋЋcюмЙЌ^НšgŸ}іˆНocc#sчЮMKЙ9ћ 477ѓшЃт‘GžbнКWпg-†sЮ4XpЂЂРƒбфvj00ЈшоRK)…a˜ЉЭ8+++ЙџўћІLN ъэћпўіЗ|џћпЧБџъеЭМёF+бX,ЃOЄ“љ'гЧPf:Ѕ—^[9[ˆЂг”шє-щгP–АС(Ѓє>А6`/ЊрSРт„Xјчc­TЅ[‡–—аB]m- …aЙŠ’Љ@}t@Ў%Р‰+Y˜б30ГˆЅ&ыёЦТс0MMMLž<™ &ићьЦ0M“ &0yђdšššRUЩяПaУFnКщnКщv{ь)аoВфtјаpЮ0mВЂЈP(‚AЏGЅj(’k§3й„i˜†]XYYСkk^CkЭŒ)УРу18c‘тСпљт ЖЖ=ќЯmПcЫ–YŒT;Ъy“ЗтсŸіиqЌsžIЎy˜)ір“aЅыŽ73JР}*г3,x;m<–s0œОxqѓђхЫї†У‘ђт’b8€Ь;щ$YѕвKN!PDЄ?хЖ/yнДM3=ПJc§1ш'ђлэЂrn&xl‡s~II гІMуф“OБРЁЦиБc9љф“™6m%%%ižПЗЗ—'Ÿ|’[nЙ™Э-­јxпјШ…S&)ЪKСх‚юI‘њ мћ№Я0M{нiiЛwяaчюZŒ›=Ќ§РЙŠЏ§пЗ†НоккЪ§їпЯC=ФІM›шщщappP(Ԙ1c7nsцœ@(\Щš5‰ХуУХр]wь h††h}*Ўз9МК3ШH fўOf •Ё/ Ћ!ащ,ж,Ц'В)іE‚ | x’cАy˜ТЇEџUD>ГЌm З'э}\"И'шc hžсУ Ќ_П—ЫХРРРH:€u”нeFЌ5‚чWщŠpOЯ{іЄЂ<„пя>.+E„ššЪЫЫ{=џлeIЯюЙчrЮ9чрvЛSѕњлЖmcйВeмrЫDЃL™K/‚K>bPQ $œЄбЫ0–’x ”В'@uu їм{/"ТМr@ЉMLИёЦљС~РФ ѕќцЖцЭnУќ nџћQf%J€ќ~?MM546ј9gI)?ИўnVНј,7нК—ЇŸлЊŠЎžТ ֘쯠|xio6Cv xт4в  Г(ѓ}e„ЃвБа!JЂЊ‚ Є У>TŸфH7к DєS"Ҙњz”Ё№zНY—•*Ѕb"=К%УХ•эЯ™A›­tvѕБ}v SЇ IDATG'55…”–KуЪXИ™={6Іi2eЪ6nмHkk+mmmькЕ+­N  RUUEMM Љž€3gЮLџDЃQўђ—П№Ш#№Ч‡ЇЏ/Ъœ№БУЂ“ХE —ЫNыi "*]Љ,:‰нc7Б#лэЁЊКŠчWЌ@D8e^|DЦѓЯWpУ џЩoюќ чžў4:fo"Ѕ­эhЋ %ƒшиФcы@wcИ&уђЮAЌн˜юёœxТпјѕь(/­ж|хыЛˆFЛшЌOАEхPєУщsC>­'щuУ6œ%Ыc=м)†ГєXх*&0 Aљь"ЂЁКК3—SmГнЗЫ@ГНјиc5‹–)їџўwьмБƒЮŒВvэk*cћСЃЖШ§хыAОъ9э,і‘ епyБЂ1№К8ёФ–œ1‰%gLцФЙ о45ќx ŽDWрh4JKK 7мp7п|3eЅpхч_јŒЂЈHбпЯЈc§lчљЧgoMД]ЗЈЋЋ—^z)c-_6raшК.fNЏмшј&‡…PЪH?Hњђг3г=mэ >ј<Шаg|љZ‹џЄшэ‡-іів]sl–˜>“Цk†-њ‘ ŸŠсД_ž}˜їз#ГдЪХЧщіmhNЗ%РрЃЂх-zJcc#ЛvюДЫUћГ.lŠUUMЩIEжЮ@ŽuниНћ њˆХŽПB LЃJо—––тёxŒ3†E‹z_­5Я=ї|№AќУ“дVУG.‚… #vAO2Ф;н‚l Аћы›І‰JLркк:юМѓND„гOШx”RLŸl ­Н }ЉkЈЕ№Л?рok; QŒЄ8aІbLН}+њjжї§яџ4Љ­ЖјŸ;7бг?ŽС(v!Ю0f(Y ”,4^2ЈПГСLц"ЁLЊ–’Va@ЎЬBђxЃ№%B‚8@ Аќh€@VаЂџ("з455ђТЪ•Сд’еŒ q”@2–yfЩ ф*ЁП?Jgg/нн ЦаZЗЭA3=p(bЪ”џЯо™ЧзU—љџ§=чЎйnіДЭв6m“ю…В‰lBY ƒ" ŒƒQuD”Ÿ(Ј#Šр6"Ђh+"ЪІ8 ‹,ВS,ншBїІMв4{rss—ѓ§ўў8'7чž{ЮMЗДЉфћz…”,w99Яіyžчѓ™ЭьйГїљїЅ”ьиБƒG}”;яќEњ{‹Я\qЉ ЖуLq@‘X\У—Ўџ}ТGMM-O=љJIЮ>#5Ђ“Ch bщПU*ЅX§ЖЂq†рЌг?єєТІ­Š{ю—<ѓœС™Їk|ѓzoзыПЈгг›тбПю`Wы<“оЫ™†;ku‘‹ФКБ 9ЃЙУ9и‡’™AMyD~{+RVkƒi'А8xщPнwЎЈи…^ј’RjKQa!е“Њб4A~~>3gЭTG 4’VzЩшћ+Чр…ћЏ !HЅ тёЉ”ѓ AC†ВПК€B^yхe~њгŸђчGž2НЛчœ я9^Ѓf’  _XFПŸ<Т~ЛјјлђЅ–˜Nmm-ЏНі*;vь Жкр„…r„ 3 #ŸOАpЦ1ѓ4*Ъ5"КZEgшмxїгД[P=3ЩMпSЌп8м­АŸя~УЧŒiq&Mшw1H™ЉG”•sдэžlB2NAц6~Ї#Д" LЧщ<рEЬQтбsј ’0mњ4@PXXˆLf^=%rЇLOv:gСY$“Б‰dъЈPо=РЁЯ]]]ќѕЏOpч?cW“йA8ѓ4Иш_ цš=ўaЃћЇ)Ј2РЈ.tjkjyєбGQJqў9Љ}xЛўE’и ќфЮg^˜ф3зщщЭvbЗоЌгкВ` цˆўрОЬƒG­.н#ГЪС Є\К і@ЅmlЗ]ƒЁЧQC хШhc_‹ЙK0z@JѕЉѕѕѕш>Т‚BќA?3f4N ЭЪН+ріужk_џ {кzhяшg` A*)нSвЃј!XГz5wнu'O<ё4‰„AY |№BИ№|г˜4б$хP’tp`н—зў.M).&RсOўRIўѕќбСYКК%xxјEЧ№р#§œ|NNŠ„щѕŸўHоЖH,ны{чП•ГVЗЎђXNПGIЁ%ˆыВЫЎНфљf9Щ?К h5№С~pЕRђнчcz§t„%Х%^ЃСЃhџжlЅRžТLgї7юњХЌ^ѕЪJсМГсђKgПOP? Ь%C лімн.CєпšІS[[УC?D_?'.4˜е8:зіПo“Ьœ‘§ѕ–жv}2ѕѕOBаељŽ#ЅvAтНfќŽAљ=сечW™ЊФžS†nЅЌ ј˜БЄфГ`ПНxиD GСXYРo•’L›6 !4Ъ+Ъ§ŸŽРs.Рй-АОgŠDТ П?No_Œи`тŸТ еў­­ЛyьБGxс…йЕЛ™šjИpБЙЦ;oЖЦ„Js 9аЗ.lНsн’ќдежђ‡ћў€T’Kўut№рћLёып)ЖnЯўžпW_“нrœ\Ћ1ЋAГhКœЉЛєN§Гx'Ѕ•ŽлМЂ89JTхо)p•ЗOо-lђ ЇПs0З GЧ|јУ—,UJЕ••—QUY…Ўћ(//cЪ”)‡ЧІŠx!\і§eAv7@YN Kан=РР@Т‹ъќЈŒќЫ—ПС§їпЫъеџ АN>>xЁрН'jTV€п/H&!•:иШoў!VlyЭЊџkkjyѕЕзxcљrЪJ—^|шЏыЃO\§ee•sйп/+…s –ў>;+]МHЧ'6х0p™#Jл}уРžЃОЮYœ€r›"tЩœќ"п\pВ™щСр#ЮЦ*Љ~Љ”Ђ~Z=šTM˜И_sъ]!3цМE&4MfЯ`$ЩdŠОўAК{b $Ц$=јўF~)SьоЕ“хЫWёвKo’LьтЄуL0ЋAЃВBрїл‡|Эsћ,]зЉЉ­fйВe џvЩЁўП§ƒфcWхv*С€ркЋ5ўїёь7xђI 4ЛЄї2ЛœtS Ъи9!­w‚y9ї ”;ў€Ч6@pшuˆіёeР”бqJн)•dвЄID"ТЁUЊЈЉ­9–d0ДmшК€;Лы9Œ!‰Ч“єї ве%“Jн€RŠццнЌXБœ+VБ}ћN*Ы%‹о'8ўXђ235NЅLƒ‹ќУgнЎчб4 ЭвмМy3ќхЄ”|ьВC{Moј–СПj0’жЦŽ&ХЬ8ѓtСК™ЏЁqК"‘ШЌБХ>ЄшТ мсў ›Sвc*а+УP#(K2ГC АВ€ <р`•xDpљх—7#еJ)ІNŠаuЕЕШУ‘J+R(‹pDИЇљїˆ“ШQJ’IƒО~Ы Ф1ŒЃB№жŠ•мћћћXНњ JŠaС“mgj™іѕљ6ђgю§›Т>MЃККš_ќт.”R,Йм`BеЁyoы6HN97ЩП–eЖзЃБјl“˜tF=ќу­ЬŸA2щЉгг|ічЯH[њэ21˜QЛ;lнЫЩичlВuо™…эћNЌ@I“фDлMјрл‡мHЅ~Ќ”ЄКК†ЂТ"Тс№ЧоОSrЮ І.0xрOћўЂ}>?б8љѓoXiS3џž=Нv#ЮњИЖs*_@ж§шд+tП_3žhƒаNfтм(!{)№?‡мX€кї•RЊВЊŠтт~ŸŸiгІQUU5šЫ@= šЊЧНU‚#5b˜’ЩЦ2 ‰ЩdŠTЪАœРб•(ЅXБb<№ЋV­р˜љpжщ‚њ)&кOкШŠцў•шšMгЉš0W_{•‡z”фsWиѓ<§œС’ЋR{šС›+ф~ПмТ‚$w§XKsNЈ‚K/Юt[Ж Г4nK?’l\Ifэdэќл"БPо^йЯnАр=ќуТхwМКЅџ…Рё‡м|ќуoRJўЗ”ŠККЩMЃ~к4ŠŠŠЈЊЌ-kъ@АЅ:rd й С.ЦcЎЎJ CZ[iЮыЉџ [ЗneљђхtДя  Њ' Š#XнCлmh‹Пfё§хфSQ^ЮїПї}ЄTќзU’ъ‰ЙgpЧ%OўЭркџ—Ђaa’ќ‡фЩgО @ЬЫгшъ6лCЧ”)ЫМ•пXЁ@›рBрсlПI@7Gя>ЋЕшЖBьрАЇі^‡нСлы^›Ъb=Ъиыћљ>gSћ$пRJ.‰DŠj+++ioogжЌYМђЪЫЃїкPj0Ѕц Ућ%'еŸiј‰DŠј`’СС$ЩЄІ‰tЦrB`ђїogгІMŠПE…&ƒЏп1uHЫЅКІ#LЭ/Њ**ИчžпёТп_`b•фкЯyџююЩšЗoќCёъrƒзп4Џo0C$гёт’)ЩЃдёћ‡ о­}ъYкя-œ+Н€I9 еsŽпЃ­'rŒgpJЧ В’юdЏ%›@ї РYРГ‡д|ђЪO&яњх]пTJ§ІІІ†ююnЊЊ*ЉЏŸ†ебоqˆCЉhB№”:.“ƒнЃєwЫ0Йл;њhkяЃГ+J$’‡ЯЇ>†qˆЂёлoЏфЩ'чѕз—PYgŸ)8ё8 ]7?W<єžkЈ„ш[,ТO(Ъ/"™JqѓЭ7Ѓ”тЫŸ—ьй +з(–џCБќ-иК]бйi^ѓВ˜8С\щнй4Мr?HўшpHqСЙ‚SOЮ§wлб$YЙZ‚VBжа˜нАEŽ–pFrЕИrЇГЗЇ…[_z€‚*ћБфЄ3ЫШBќ tl }_;фргŸњєв;яќљ‡}>пљеееьоН›cŽ=†жжV(UЊЃГѓа9Сџщ!xеZ­ю[Иo fhХA4gO[/Л›ЛhnщІИ8ŸPШo’ZŒq,P)ХЪЗофOџUЋЬшцщ№ё І›i<.\к#~bўшвьУћќ>JKKљЏ/~‘={Z)+‘|ю:ŸBAС@ ЋєавзПЕMбк6’wоПЃы„odЇ}чЏОрttЁёВГ‹‘ЄТШdvЊЙёp]5ЪД–Ж{VКѓрр%P.†TSГ€г€ 0щЦШеWЅ%%)*B: ]ˆ!Ga6 ў‹ўє,@АЪѕГ… ЄRqZZЛйВЕ––.тcR.ЬYћwїtБ}ЧnойД)“”УдЩ‚†щхЅXJЮфNіьГNЏћъ%‘žxт ~}їЏRвВG>R)ш*kВв Q?ДЧ0рЙЧ|фчОe7m‘ќr™Є?6?ГfЯXБuv‘\:Ъ0ф ѓАэ 8BсU*HлCHйr‰'a–Г№лџцAрK‡ ДŸЋЏОzЕ’ъЅ•UUhКFuM5sцЮ%);Рџ№hЉ8іЋЅ’ &imэaгцVvяюЂЗ7F2™b,ŸООnЖnйШЮІfz{ушТl§ее ††~ru4д~;Uи–žј+(,Ф0R\wнueјЬсЛnyyцkЛтђbцЯйЁ}ёk’Ттy6э79/щє';}ъOxx(‡ЯѕЬœ­CЇ‘Ф}yШ9_@іЖЃ8xЮ–r№љЯю%еГ~ŸŸŠŠ 4!XИp!'N ‰Z' ЌPnWu tYн€ЁЕ@E<žЂНЃІІNZіtгл7H"aŒйy!7ЎцЩ'fэš• …О_А`Ў0…:\-‘}+/†~OЏЄгьљы:@ТќОtЭЕlнЖ)§hšk:gЖ``@qї~~pЫ IЁW^ы7|KВ~S„оhcІсzБє(/€Ъ№Йбƒ‘‰и ! Ќ$[)тЄїГ€JщТ?Ž™ ИtT€u}A*™,,,ЄАЈMN=ѕT‚Ё‘HфCg šyE„[КЇZѓ№зЬ‰РооAкіівооOOЯёxrЬЮ(Ѕx{эjžxќЯlпО– Upњ)№ўѓ3)C4Јfw~сЪОєІŸOз)ШЯчю_пЭ=їќiHф~•wwMujk4о^ЇXz—Ÿ Яїe8—”Ыmћ­[їќСGWпYйF,мвe‰ч@FIу&џюƒрО регC>.z„ЪFf;:2;–ŠGЭ|ёK_|[)uЕRŠ’т………œqњщв˜qуЁDh)Яш"<…2”c‡‰3єѕЇЦT`-ёxŒ;їВqуn ђ Ю8Ž[ QUЉ:д_A{‡Bї™ЦЏщЁp˜+VpѕеWЃЄкOу?ИуѓСiЇ švIy Рљчљ\мKцпьK_“ќт7>ЂЩѓ‡S|чФ\ЦPŽГўwЦ!‡QЛŒ+л(p{АР(eЊKЖ’ЕшТ'(\$ЪввhУО}дРЕз^ћ+%е]JI"‘BгЈ›<™SO9•‚ќuˆ,Ук `@уЗ]dM3Щ1тё$ННФ7їXqJ&йгК›ІІіЖЧЉ™gПO0ЋQ k 7ёpэyяCІ1§иЄUїkј}љдЇ>…R’х‡б–•ТŠŠ7^ №žuзВ"™€ш€Ю“ЯъМчlƒGŸ*%–КР\СށїРd0њ*Жпtš-ё$ьpЩhнIЧуЫLЌJyƒ8AсбЂtFЬ0ыкQuз}хКЋЄR/ћ|:E…h–онТ… )ШЯ?x' шбlrIpƒ Зџ7ϘJЅˆ &шыбз7Ш`,qxЖїгvьx‡з^{† 6PU ѓчj&™УKййЋі93О>EСЄ У@Тміѓщ|тŸ`эк5Ь6$ПQПDp №Iрh”РСOwH"ПRŠ /аYНgуЖ“шш=#S•Gxl9dС„r™ёуrQ„‘]nˆ\=|™§|N Kо\КH• }d˜uNЪ0п!‹ZJ§‡Tъe_Р_’!ЩЇœr БСыж­Sбhє`ТkJ­GЈ|PS\\хЈus$)њњbtuEioяЃЛg€ш@œЂ"}Ь8ЅяМГŽчž}œmлLP=ъjЬзўЈJ rl-^6ЕiщшЃщ:_љЪWјгŸџDФ\oнJ%(оŸОM%џJ’GМ‚N‡“чnы} JJ НyРѕ!: йЛWБvмwПППмC*ЙєyУЪ?^C3CcnB N /21зшžc*0#кЛ87l@9Ы2w „s@Шэy; їGО•4Z№ЕЏ}m3R^Ё”ТяїуїљšрмsЯeЦŒђ&Pb№7”к”єœX€3кўЇшщ‰Бkw›Зьaыж6š[Кщя3щП‚­лZxљ•UФv3wLlюН .8ЗŸYѓQ…VмŽ!%)k7BгunП§v~јУЁЄт`’уvв­fŠkќЩёˆЮB!0$|цJл7гЦ/Ѕdэ:ѓо3$XќЏA>љй"ž}q:)БДЩ~хRщё"щ”ŽШ*sютТ№ЋFрћЫ)ќ1Ž`П•­[сF~уІu}/_4Њ%Раљ_џњSJЊO(Ѕ№щц™&јР…LЋŸF^о:ќЭѕBmЖ…JїšIЙа2[оZ&SєѕЦhmэfыЖ66oйУіэ{щю8ЂнЛѓ1 ƒ;;XЗО‰М0Мї$˜6UGJH&=к ћQћ+ЅP-†aў@€ЅK—r§WЏG)ЩuJqУ:@ sРД== €ZпУрg(о lлЋSuХх:kо rѕUўє:3@ИрC„‹~ЫŠ•§$’ЎЎ^”м‹J­ВšхvЦ† йGж”йiЕђhџe їШьчХƒШФk"а>оŽЧŒpОПКƒ^žЁDdžЫ‹јЦ7n\*•К^ЅЙ<Bh|шC3}њ4ђђђіпвЗФ-Єюl‚Pм•ƒ]эDY<ƒƒIіЖївДЋƒЎюhкиеvњЭЭЭttt‚‚†ipцi‚щг,…#c$Р#ѓыщ{b(ђї+;‘†”]h„УaюПџ~ЎМђJ”T|J).p<šlСG/‚(‚”эвњ€ЙHЎAёcдˆ{Ј‘"Иwi–m!О§Эх™З`0яb6lЙšcŽ]ьКЋЁтїЃтА№˜)фчмWhЦэж†S з‰НœЃС2З0.mЙЌ™•™q87нf9ОЅXж™xиРЭ7нtЋ’ђ;ц”šDZЂ—|јfЭšE^8МџN ў‹~ёсЁ šџі -•щ „0#mWw”нЭtuѕЇХCd&акК‡ѕызгнеNI1Ьž ',дV›йƒ?Й'э~L)EД`+в00ЄФЇћ((,рс‡цЃ§(J)>ЊT:TЄЉ)f’Ђ…ЯnЌО —у=^§™ЇОзнЩѓ.цэwЎdцЬйфхххМVџx§єwнGeEQvЭ=уŽзzяˆЄž.@]Ўя;‡‹”—ƒ!лЙИ:&7МХ‘)ЄeШ3NџauпњіЗoTJў@IE2™Ф0$š\|ёХЛp!сqшЪМz#ХЁšJ3ПŸHІшвеЅГГŸОўСД8’<[Зnхх—_ІЅe+%%PYХA(ИЕП3ђ'лЦ ™Т0$С`Hq„ћяПŸK/НЅ—*Х'mщ~ ‘1нКЏWЂИ=ЋЎћR€Я^ЉЇзА3П_Р›Ћў™3чR\\МЯзlЯЎeЈФ#Уg•Ѓ~wІЫj|3Иќ\X…ХОАџz ьуІŸ+ŽKцEM>ђ<ЊћАџ§пп§ЪŒ‘L$šрТ пЯщЇ~N@“-™Ažс•хГэ.т‰Н}1КЛLаейOOO”d"•A~И+-[ЖёвK/Бwя6*+Ltќ@И œ‘П#o FJ"S…”””ВtщвtфПT)ЎВн):ДЎ›кG„AкУS1јjњ‘Ьѓ?? ђљЯј№ЙіМќц­wмI”••Xљ”ј_TќQя:Y8чцЅKћЭыїpС ЄGI`ьь+С"‡ž ’йїАЪсЬ—|P#Ш|dMЏІ јfž}хŸ)%%%ћ}нЄ”$IR)SіMЦ#9№(žЊЛvфе”Уа•!jЛ §8)НpдіB1Ђ–€№’ Ы5ƒйp9bрж[oНQ)uНњЃ§єѕіЂi‚O8џќФ'‰D"ћ БxT{fчёЧЮкп6^% ЂqzzилоЫ–-{XГЖ‰нЛ;I$’Рсч TJббйMss3~ъ' *Ъu”žќх~н›л^СІсkК ІЖ†H$Тuз]Чѕ_ЙоdєUŠOXЦ<єa8>†L$хИit2;Uіг|+ Ч_ oНdЪфь9@x1"p?O<=•Ы.ћ7Тс№]7Mгќј|ОДуѓљ|ЈФ“ЈФS™h;n=~ЇРE—Я–!ˆвў,эA™йEРЃž9ИKK‚мŠьћФDРmЗнvЋ”ъJJњћћиЛЗ…)?ўЙЯ}ŽYГgяƒазџ jэ№˜Џ#=ГїP=1‚с e’=m=МГЉ•–==$“FVЄ­l cяПЛ›оЋ™4#Ј™”{пИж~,Ќп§†4љѓ LЦ&ЅјШG>Т~єCЄ’\‡тпЌЫсЫё1”ШћG(&‡.йуaј ќЧЗ|мvk0‹Ћ ?ђџјћЋWoНъ IDATА~c”K.ЙdTГ-•x•x†Œ•^5Bmn7FЇь—}чп‹@$упрЪњk№qыфŒъœ‚Й aЕ#ъ~єЃ.UJЇ”jˆА{w3ёСA ђѓYВd ‹/&/œЇ ѓ ‰њtsѓnЈЉЉЁООžkЎЙ†П>ёWžzњ)Ѕы:НННЖUАЛbј?оЇvDvхˆќ™‚ШШЈb ’‰ЁŸPШGЫž.ЖяhЃА0dqЫѕhnnfеЊUДДь6› ј}ц^|.Ь@С‹ЋFзt4нЬZъъъЈЏЏ'ђЩ+ЏфžeЫP(>r‰рœE>~ўCЩM B03ЊїЊ’’0Сo нPh( ы:Ц6 -;C№Ž&XЂЂ>sЕŸNе((№Ž%zєDњcgђ™/|‘H$ТX8*i2Y џ{ШтѕIУoШyиA<Ѕ\вsЧd p›ђ#г1Ић*;‰)#М.Я3`шмљ‹;Џ:ўјуч/XpЬЩєіі1yrЅЅЅќЫ…А`С{ќ16lи њњњ†€а†CМРЁЕ–ЋoІ2WiJaQ„k45uёњђƒ…””V зж[Їц*)š›[XГf ]-BA>VЏ\XРоpдWJ(Фhр™WП‚І™ѕAiY 3(*Š№иcёх/™-[Ж ыŠ[Охуп/7џдџВbƒ’;Ћз*^Н'Хк5а$Ё7 t пЖšѕФдiЬ?^pТyяŸ+˜їь)TOъ`Hd в˜й3с#:ДЗРs/–№—0Ѓс}\ѕ™XЊПпŽ ѕІх2ђАѓ~s™3PNуЧcппэОt)œЋЫb{УУЇд­iузОЂЛЛ›'ž)cоƒ…ѓ[hiiaяоНдззS[SУЩя9‰їž|2O=ѕO?ѓДŠўžЎЫПъLр8”%–юVѓЋŒКР‘Ji€F"!Œ )ь!RаЩН4я\СЎэао™ Ћл Ћ[впЏTЄR •BгРч:ЁŸp8ТТeeTUMЂІІšI“&рs™~БяєtїбккJ( q†ЦФ*‘Fџ… ђб|3јг“ŸEз44=…пЂББ‘ЦЦF4MуЗП]Ц7ПљMZ[ї ”т;пљз^{-/Ој,Зпі}ЎўвJЮ_|<'ŸАŠ“NшЅЖцаР?MЛџXyЄбOЄh€‰U)ІNЩcъф2JJЋ),ЊЅЄЄ”вв"JKK(.)Ђ(пGAž"ŒтїЧРЭr юb К•ўžЕtwoЁГSВЗCЇeAыhяєE‹0TP=ххuдзOgўќLœ8ћ~B79љ4MЃДД„††FLGЇ”фџ§?~ўѓ;yѕеWˆD"Lœ8‘ђђrŠŠŠшээх ЂЂbмZG1 шяёиуЏёуŸ>ФŠЗо!™2№’Nў},Н˜ М36@шk Эц\PгќМІе63ЕЖеЌ‘•ЄВЂ’Ц™&fЮƒ›дYяМГ‰U+WВzЭкїюEшКІS\RЩо=[ˆЧлЈž3K8сјљwм{ЈŸ~2•ѓ№љK0 Эъ(&*…’ƒ(е‹R}ћЌЊeьEЭЉ-‰з1o™й>|>A*хЃНЋ”M[#<ћwƒч_ŠrЦFh:КfО&Ёi”••2cњtІЯ˜NMM-š&HІ юјйЯXЖlлЗogЮœ9Lž<™ттb‚С Щd’и@ŒЮЮN–§v“&MЪИaХX><ЪŽalоМ›_ќђљнНOгбе›YbfД­{8љтXr V)0€џR‰џ=Z6hgKл­š(ш3ЅІ…кI-ј§I”Tј|>gаа8“Щuu!аЌIЙ]ЛwГ~нz6lмРцЭ›I&’hКfR–iП[іeЊkІPV6Э7б‘)%@ХQr)ЛQВЯтЅІ`ьЦ0ЖAj=ЪиŽю Ѓы|СB>љ… taђэы–ф–Іi„BaІLžЬ”ЉSЈЏЏЇЊВ4 M^zљeюџуљЫ_ўBQQsцЬaкДi”••!„ ‹100@,Kџћф“OцкkЏ=*ц, Џo€Gџя~ђ?Бrецay9c†РњBъЅБђђ{,Р}зXs J%сmwo.юГскЉzB+еU{(‰є ЅYб0cгg40uъ”tV04:Л}ћЖmлFгЮькЕ›ц–fДŒгt Уœ>є5ЫiшКцђuыkіпб5„І№ћЈЊš@uu5е5едежQ]= !4ѓЕ СkЏНЦгЯ<Э_ўђкллЉ­ЋeъдЉTOЊІЊЊŠМ<Г‹ЧГ@qq1э{їђ__ќ"'œpТИЅŽтIЅRlкД›џЙуaў№ЧПбнгOŽ5мБфЖbNwŒ5№Qр^@О]3Їќ†2ЧXха$” ErA^U{Љ,нK88ˆD‚T„ТaъыыЉЏŸF}§T**MCЁYb!‚жжVкіюЅЃНнкЬыЅ?кЯРРёxœd*I*i ”Д нGРя# Ю “ŸŸOaa!‘H„Hq1e%Ѕ”U”QQQЩ„Њ*3#б„eє‚;wђЦo№ЪЫ/ѓмѓЯгййI^^Е55TVUQQQAQQ!сpсp˜ММ<|~?F*•vЕЕЕ”••‹ХшщюІЋЛ›o{ЬѕPкгЯƒ=ЯOіыжmЗTБ•УЊЌћ3ѕђXyй/џDЧZ`mѕSQ…ŽМЫОOcЦ8#шШЃG[vд)шЁЌЄƒ’H†ŒВjѕ*VЎZ…R’HQ„КЩ“ЉЋ­ЅІЖ†ššZŠŠŠЈЎЎІІІЁ™ЕПfъа‡ІiщВ‚!CfиЈ‡‰˜С№з:Л:йєЮ&жoиР Я?Я†ѕhяhOK•3eЪJKJ)Œ’6ћщЩT *E*•"™JЂћЬlуєгNЃДЌŒш]н](ЅˆƒькЕ‹h4њЎiЯЉ“—bсБ38fСtЖmkІ?ЫэiўїBђ•Б№Вǘѕlц рLб‚Zd3h67jgOЕƒ+^єЭf–агW@O_>ˆZТ(‘ТnŠ Л)ЬяЁЋЋ‹ЮЮоZБТ”SŠќ‚ЊЊЊЈЈЈЄЂМŒввR"%%D"Eц’—ŸG0" |>4%в •J‘ˆЧ‰ЦbєїѕбннMgg'mmm4ЗДАЋЉ‰элЗгобŽ™HњћћQJ‘——G(ТяїSXXhbH%SЄќІбЉЉT’TЪЯ„Њ œrъ)LЎ›Ь`|юЎnŒ”A0$  …ЈЎЎсЕз^cбЂEуV:ŠЧчгЉЋЋbўМz^zeлcHЏ™ќБ#>Л]їБрbР#Рч1оŸх”Cп]ф’mvYЌА~.‹‡hэЈЅЃф…{Щѕѕ DщээЅЇЇ›7ІЃ2J!­–у~ ’цзА˜Ž•R(i2+LzЊЁ6ЅВ}ПА Ц™Ь;ЅwмqyyyФуqќ~Пс“Щс[‘? 3ўЈЌЌЄЄЄЅ@€P(D04“х*++ИџўћЧРa8a.ldіЌЩД4w0ЛѓOŒГйе™‘їgрѓШ5 ЮfИЙъŽќЪAœ€Cч]Œ ѕl§лtA:ЈH—~п A †_ФЇЂщ t-&’’ ”()MƒW)†дв‘Š!U…Eu|шƒ'qЬ1ГЈЋЋcкДiщY0WŸxт zzzHYщН§# 1uЪdjkыЈЌЌЄ8RŒRŠxшСп?fЮL‡дXtцNІъ•ВњьЪz­:9еH‹^ђIУ?—4ќ$Sˆ’Х#(TQ9_вељ*ПЙg*ЗЭ9‹SO=5Ћ-W^^ЮYgХяџ{ЫwIBС хххTTTPZZJ^^О%c>Ш`(N<'žˆ’H„ёћ§Cщp8 ˜7oїо{/п§юwЧ­t”Ю&T\\ШМЙѕL:ююs0Шiќ №ЉзєЫnvѓHcЅiЖЖ6 шщю!•LбОw/]]]tuuэїХЋЊЊЂААI“&R^^С 7мРдЉSYА`—\rЩИ3%'ŸbС‚LЋЏІЕЕƒD2щX>3X€ыёXЏі Э€РЅ |йЦщi№ћђa‹цCњij'EиœŠrf nМ№жїeRoRVy•хНЌ_ї’уђћ٘ЂDа1^:h­0чaŽ+;#MT”`PЧгпЉЋЋуЂ‹.bоМyддд№ОїНP(4nСyLЦfƒ-[vsыmПуС‡žЁЏ?црЇДўFуа:їKŽCЃС+†ГeщбdЅђіщ@F6Dd6—š}І@xЉМ8™`Ѕ;јˆнБ(P1›@ю1— њЫИ{@Ћ}&h…6gdи№ŽЁџwАТкёЌЏїƒьйВшLƒПBjjj˜;w.з\s gœqFZTcќ@X•’Н{Лјѕoў—_н§gv6эAк‡зьњu6ЖЁУ|.ДьъЈps€Еf№o6ђћ(›HяYЛdYТ 9#§HЌ/nмmH3Rk­Ÿ ‚o>јЯСЮGiФvЎј}0rь`ЈvЪFLЃ wБ шХ$—Ю–,YТe—]ЦйgŸэJ_6~rgбhŒчŸџЗџш^^yuЕYЄЌm›GЮLZмОЁСkК8е9}B„‡%o†В{ .ЄKфvIзEMЕŒ_йoG‘!ќh{%СX Њ|ч@№R№Ÿje3ŽЙсЦk3l!s—%N•XћяЛcбAƒЏжzхжiЪ}ЌZЕŠћюЛMг(//ЧяїАTзЛё ЕzW­~‡M›w’кV5џЮВѕHНФЏzaњНІk€Я :њ+}2<У М#Оr ђТ+zЛьˆ\Ђ‹N —ч6РxгФVƒW‚o й˜ˆ$Ў ЏщУCˆТс”‹P…Г]šБJmЫ„4Ы­Д* J<џќГмyчЌ]Л–N8Ппдм_1љ$“)6mjbУЦmєїE‡oSЛH:"`/№}Oч5†Руf§МS KUЩTКб+лњѕТ.=ТPPЦ@.УwSт2ЪPmр;ДтсПОrЮ"ИЗ—p}~щјОЃdŽ@(iЩhЕрŸњ,LЮHСc=FCC‘H„я|ч;tvvbxщ“wа4‚‚0sчNЃІІ ŸюѓРŠŽШљrЮьe _л/MЄ^™PХAЂ$kHЧЎ•–S[]fџўн3Ю‘cщЅЃaлMD_ŸЫхxжѓ‰\ ŽрUЮ83Лp%.ЮF9;.™ˆ(п1р;Д™ Lљ›nК‰ВВ2ўѓ?џ“жжжq‹ї8сpˆгk™PUŠЯЇй„> Cь№ŸП­`=№ф&HНЊ2Yzl’ŽРr8ъЋ‘4зСН­(mNGйфŒМŽЙc3ш A/q)S\P|{Ўd&ђ/Tw1dЗЧ‘ю‚=ыа" зƒ6 0зГћлпrт‰'ђрƒ’JЅі!ЗdКЎQRRDeE Ёo8SД3RыѓT рyє1~mпЮEюЈA €>9гВ%УA(—n€‡’KЮ1п{C†#ћЬє?ќyлe•й БЎs2“W.ЋЮЯQ.xu вѕО­*r8 хxЅ@ š™0Hoo7>ј Щd’їНя}#bяЖжb2™ЂЉЉ•ѕЖбггoN*[eо#‡я|xюhvш.AЕЦацћ~шэ!ђ; зЎшjŸєЫ…ў;•`ІJˆj6лmўГ,эBчМ‚­kсж ШшїЛПWћвЋ5™%O­ВK!Н%Ќ3оoДRыkМєвKьмЙ“‹.Кh<їwœAVЎоHKs†!ЉџawњŽж`шќx“rа, Џ”—-Gйѕ}Ињ!ѕwsє,д=HЦ0+&sЄЗN0ббыWЮvЃ=ъік2<Чs )лW…W?^9zўrx2gЯпуЕЙ‚вcбіњœ†я†—Ј!yѕ0їо{яИх[Ччг‰D ЩЫ ’н%UццчшžЛ1йў)€љХDЬR`Ћу­hй„!JЙxa'уђнЂЁr„0ЉU9к}2iћКЯкlУ…ќSцFЪ3JЇЇЮa`*eЛ”ЖК_ИдшТžвЛwŽ)>/тg'Сm? #pЩœNЮЙ`$œuП ^ў<№РА‡N&пеN 1er5EEљж4ЄltгŸяя/Н{žњl„Ш3KУЖЄ"ђLPаЉ!рlцbвЛžVЮЅ”УQxDP‘#›.` t2ь{ЋЯi№аЋ%ЈЄ;@˜сtДŒv ЎыяZу73€uu)*Ъ7РtW†бjД"ЫЛС˜уЉў№qV)№Ц№€анfа.ЈЖк—ZпЩ*ф\ў‘.]ЏЁ Œ‰>P'ма}7ЎB™gиk~х1-)dіrSF фUюHляOHЎ]Л–;v˜7еЛœ?РяїSVVL(ЬфtеЖ8$ч: ч]тЌ ˜Ьф) ,@№o {@%AЄВo\ћОПpШ„(дMж3 IDATЇѕ{FЖ IГэ2[“ТƒЉЧuсFzєц]Ъхю+ЗіœЧіa.G˜3Ћp™“p|ПЉiлЖmЧЌЭРp8ˆпяГФЎ,V‡іln?а_>z3~ŸЦйч~œ3Я<лt‰{Сxд юГѓ„žЙјўВH8pDf@L’&у‹змОл.Оp›0$”ћЯHlУТQ(УЧ Г‘7ЄПп?nљiРGYY С1:3ЅРA`Е€а……!JJђёљ4nОљfОљЭoZЖВе’br‹жnНv\FvUіZЏ'ёˆˆ€Œ™ZыП2ЛnvfЪЃМpю$x‰Ђ(ЧnПлsŠ\„ЄЖёiO`аА>м№ ГbWA~З—~ПђВbBЁР0phœ@'Я~Lћ§sfšFA~в’|>!_јТЈ­­5oJc аяОшт…l+• њ9‚НжyЕJ ф6м[wЪ;Б/( Эщ0j<Ц™ФвiіMЦ\;Ъ#3N–сЁŸжˆFЃужo@РOyE Ё`pxррЩAПT‡ъu@™@^~€ЂЂ0КnОввR~ќу[?гЦІь›кn”­.\xўqlнyЏR–SR[ВG…;NоТŒ(oи†wьsв›-иљ•[‹qЄљіЄзќ@V‰Т8spFрЇ8RD шsYWпяІџЭ!'ŸЪЪrКККmќvg>юТ˜ЕИУ4L#сЮ@фF0кЩqР6d: {ЛPX3ёЊХ…ЌУ%т;Ч…GЏіАЫЁ#ё8™#ФЊТ9eіњ—,YТuз]їЎ“џк' ,ЌЪќ/8tЫJ‹0 ЙЯДдпўіЗmN`ЈNrj8їу]ЩE]д‚еаeMёюЋХ^C8Й$ФЅƒєд9Єа2(РЩt6ТC\$ <4Яuз]7љsœT*EKK*0="!џl%Р№M>aBё~)ањ|>Оёo˜ІšЏбInA—4= ;pžm0Щф-ьsЄт<^JТЪ‹šїЭF/тЯ E#91зR%sтЄ“NЂЎЎnмЪGРšššЭрЄЩ№ИШєЂ– J…RjŸГ€p8ЬЏ§ыa' 7ƒьТ](з4Ыєž=j‹Jыхікј dvI м˜xœS‰D ži?™ƒMТ)qцвmШЂ-Sй ЧжЙѓЮ;ЧWїС Єƒ“p`Kj8x' †!їЋ:&LА9ЄYЛ№fхѕ’ si‹eЅxSби#К‹‘DGœ‘иЩSрмсwЈ +ЇЬ,ХkR1ѓч/ИрV­ZХ1Ч3nс#УЄR)ГPЪ!43ž<ЈБXœССФq,d:iВљШЎс%  Њ0и—–&wќQэTY< Z=ђˆю.ƒ9Й(И„ѓ›0Њ)ˆr{^ЗLGІ7нtѓчЯўіс$“I0ŒTіай8pАРќшэвлн/Рщ–-[Ц’%KЬ]юДx§rˆ‚ИЭюлЙtšm‰мl~2JЙЭў;j~%нp‰ъТЅu'<КТ‹$Х ІвЮ`Щ’%Ь;wмВї1§Хщьь&‘Hк&+@іИ88АЇ­‹Нэ=ЦзTмuз]–H;\ZCЉО›Ђoњk![>ИЩ%BЛЬж;й‹IШs ШхЕ ўC•4пЏŠ› Ѕъ5`šЈИѕ§сaŸЅK—‡Ч­{Ž”’оо>š›[ŒХЩ5W їŠqpРЙеSbшЦlnю ЅЅƒTъріаƒС Зп~ЛUЄЬ5bеFЮ‰Л,O`Јљ0З8еrЗїуЙЅнЪm`шё rвy+ЛШЉtСzAu[н‰ЙS–.]ЪЧ>іБёД?3€ююvюмХР@П-cД…AоE  RьmяЂНур2€ЁSVVЦC=dЭ ({Ь‰Aхб*9кvщV[О- ир’ўCNЖ"ЗY\œžл~v'У”2љ\zщЅ,YВф]Яѓ @KK+ƒƒёaЃWrLЅџp˜жGХˆFcєєD‰Ч(eFлƒ‰Tсp˜[nЙ…… rэЕзвддdrivw@йeШ‹iv! №[Љv‡ХVrЬИЌнŠќТЃ•(rI IƒVДOdНя)SІP__Oqq1 ”–•1R__?љ њ'“IњњњщээЕ@@л6щыјŽо+ ёx‚––іьщЂДДШs5xЯ‡?ќafЯžЭWОђ“O@&AЋp‰ЌйИDцЬН6Ра† o^ю‘^хф РIы Ѓdz2^ГЎы|ј’Kјз‹.Ђnr3g …ŒЧщъъЂЛЛ›юЎ.жЏ_ЯЌYГЦ-{?@oo;wю"0л€i№OьSѕшЬэ’ ˆFcМГЉ‰Э[v›hы!ЕИЦЃHЛъ64%шФэvq№рС)mУњ744В}ћ.кллSw?{j6wE™$OKZДДtђж[{9tшиyЩœ ^yхNœ8Цуа‡r2и Ž1f›ЏQљGЖќ‹Љ(}kЌ!ЅNХўz<+˜I ъ™0!}LJ‰гщЬx^oоЄЋ јАЪoY­­mlйВC‡ъбѕиp—Q1у-FHѓьоSЧжmЕуVpж7VQ˜1cЋV­Т0’46ІІц-^{эeюћЏŸЯ =`6 wѕХЭIЦЄјЮŠфiюiІи'­фњЂ'єс€ F2‰ІЉ(**тнwпвќ,‰FЃдж КК†іі6фШ%у9.“j™—ФЂЕЕ‹ПnмЭоw38ЈO˜-‡ƒ9sцАlй2nНѕV~їЛпвппЯЛяОЫ§їпo/=ЖкG„dН †WŽd$OГRЩDrи,€э $NїR‘IЦу€Рщдlp;ЇjВяk2Icу1о|s‡е‘H$FфdФœ7/`Лˆщ:ћ4АўЭ=к2ЁЁР™Є  €E‹ёєгOѓњыЏу6-™ХкgOfЏ3cѕqkЬф˜q~<'‘†гѓ†a ЊZЦ (++# M€”tvvБys5[Зжалл›5ЮЌ\Nќ7N“ъЉX-пAЉZЅыq ќЬ˜QF~ОїЌˆœoB0wю\t]gлж7РХЯш}§В•н#іOŽ ІjhšŠцдP5 MгRћFnЮaŸN'H›ыощtбееIeeхE­ќ‘H„ššЌ^§<ЕЕћэХhB‚Љ™о˜˜€ ёi*WI)‰FбѕeeETT”рv;svmЛ‚+VPRRТkЏНhЯ w*Y8Z3аЌ‚!1eЙ1ъ u8ЖтPzUUSяе0Јh™}68ІibIŽ;Ю%щсtжџрС:VЏ~žЗокB8AєЛ`H&X­пAЉXe$ B§Q г ЊЊ”iгŠЦь"œ+rѕеWГhб"vьиB8tЪЖђ2]@tЂa›]C )--ЭИыRJЛkmЦђЋЈЃXч(сt:QU›км0’ИœnТс0ХХХђ›ІЩБcЧyўљxљхWщшшr§3ќџцwІ`BA э;(Ћтё}§aЁPYQJQQ‡’г Аhб"nП§v"‘>о=А Ы Ї,Н‹бK lІŸA ЂШЬєTee%===Уr Ѓ)§№@ЭМЯ>зщtЂ( Іi’4’9|фЂ# Б,‹іі^}ѕ5жЌљ GХДRIк U|ќ‚ЂPšTГЧ=JЧ ЗWJ„Чm—ŸРHЖq№аzжОVЭёуmЉf ЙЁ™3gПљЭoЈЉЉaхЪ[X-`ЕЅИ ;СъБЇ #Drи M[ЋЯ}юsLŸ>=sЬ4ЭЌiРј№Т auњˆW{}€УЁиЩ@Ї›|ўEU`Yнннlкє/М№‡БЩh‡kХ/8ўДЩBј&Бk‹їюхсЎ.юБ,T@Иœ 9СыQ(,єPVЄЊВŒЊЊщTUЭІjњ<*+0­l6……г№x<9G‚Y[[Ы3Я<У‹/Θт)=n“>mк4ОўѕЏѓ№Уѓрƒђф“OfЮs:ј§~С С@€@ @АА0ѓ>‚УоAМy^ У П?D(дЎы\sЭ5…ђїѕѕБiгf~ћлџCuu ‘hŠk!Эџ(Є.]№pч”ОН‹ŽDЙSZ”Ьœ)’ы^вtEЏaтN&ƒ1ŒI"a…%Н}ан-9е)iяДЖJšOJš[$sfrузpнђ›XВфo˜={!чѕw™ІysM2™dчЮ<џќѓМєвKДДДіЂЄ{яН—‡zшДь|mm-W^ye†KQ|>_Fйƒ€ Срщ ,HНƒфччЃЊ*бh”ОО~ъыыИуŽ;.hХЖ,‹D"A8ІЕЕ•††ъъъhoo'388H?ээmДЕЖ‰FвД'№Зл€@RиЌЋƒЄ D„ *%Q)‰!‰›НRrЬВЈšАi› В;БLР™хОћpзlуŸZZљf,FбmŸPњПќЕЄXЩЋЊT>№яJ$$Ч$G,ъKжYдюЗтюЛ>Цw~ŽeзоТŒ3&М=іЩ“'Qх=Їф>љЩOВvэкЬgЗлПРŸБђС`0хHяK@њ5 PФуѕH$шяяЇЏЏŸЙsчрїћ/˜qcёxœP(Ф‰'иЗoћїяЇЇЇ‡ОО>:;;шшh%щУЁ€Ы!јѓљљ‚Z8e™єy<Д84о‚wuž–0~<,ЬЗoяьфл==\3žHќы?Ћт–›ˆqгШ“-ЛїZМНлЂfЇ чЧљтПЬuЫo$ ць={ійgљТОЩ}8ђѓг^РѕШ†@РіEЁООž––М^/7п|sЮ[њzzz8|ј07nфwоЁЏЏžžSєіДЃiС Fe… Њв ЊЪЪ ИXрЫx<рq \.p:СЉІЊ PdZљг %˜&˜–ФHк@гapP‹!c:єїKš›-ыHЃŒж–'b1yи4й ГестHs3Ёёє .(Z№iг(э‹ёЇі–.Й\ФџпŸДјМ9яйќm2)бДŽwгЋІW)мљwічж6‹Эелје/Жpзн0gvпќзoqлmwQTT”SїэškЎA‘лэMЂЇ“#J€уё §єЊA=ЇІf;Я<ѓ4лЗoGзuюЙч,X@YY.—+чЌ}? lоМ™M›6qьX‘H7†ІЄXaЩe*—.T˜7*+!P pЛUм.‰Ы%p:гJ§žcG ЯЩлд!7ŒшЈ.ьPO2S”PˆРЩЋрРAы’Э[Ќылђ&Ї“Wzzиц Љ Ц%уzСx—Ьчгѕ ЌЉ(g№‰WЭ7jяЋA}z||šфѕ7-^]gђв+з^{ЋV=СѕзпˆІi9qџF†šІ‘яЫrяA{ кyloР2-:ШКuы8pрRJІOŸЮwмСC=ФьйГsjЌ$“IКККиГg6l`уЦ„Bhj„Ъ Иќ2K.7˜;ЧЂИHСуЖ]}UE™8•А,ItйбaБя€ЅПѕ–9pHющюфгgБ}џ~N2Z•з$Ххфпт ЛщЅѕз?е‚Џ№ˆЬD$yбdЭ_ ію“ќЧ|›јъ„{6lр–[nЩL*Š‚зуЅ P0”Ш€@0@oO/ЛvэЂООžЛ ѓmЗнЦC=ФвЅKёљ|9wџЛЛЛyчwјѓŸџЬ† p8b”‡Иb‰‹+ЏАXИ AqИœM›X…?ФуШц“[Њ­фЖfs[‡ЌV5^‚ъ={шс­6Шu(p8Xkš\їшУŽ–Џ=Ј•gœЎЅf‡ЩяŸ3yёe“ќŸч~ыћTTTLШЕDЃQ-ZDsssfŸгщТяЯѓчћђI$дззгдд4Ькпџ§,^М8g“{`экЕЌ_ПžоžF.0ИvЉ“%—RU'/ЯТс9ЉєЃ‰iIЂ)7Xr[лГЯ<онЭ‹*ЌўшR?ѕЩЩ Г&Ÿа/~ЌEWмш(B|hкВЮџЈ?bёд3Я§ЩфЋ_ЙŸo?ўФ„x_§ъWљЩO~2фZ9фyНRZZJ__mmmшК~AXћД В~§zž{ю9Ž;РТљQ>vСтЫLЪЇ Ђ9MСйча.?FііIjЖ›жКѕfЈсЈмŒѓыЙЊ_?z–^/0ИиАs‹ѓдŒщJЉ˜]*еYќјg/НjђГŸў'_њяЂЊч/[[[ЫW\‘IRRRТрр ­­­ŒЕЯ–оо^^{э5~џћптPкИёуз/яczeф‚Бєg+‰„”oя6yсe#БчЙ-т—z’з{zˆL&PЄУљƒяkнŸЙЫQ"„˜T%Ы6š|я?“œlёАyѓ6–,Yr^“лЖmC‘!Б,‹хЫ—ѓљЯž+VажжЦЌYГ†•чЂєєє№Цo№ќѓЯR^т–1>ri+ОМ0“ULSЪw™<џ‚™иВек ѓыXŒ—Тaz?ШїхZ<э‚цМ<oНс _ЗЬQ:й”`Юl…ћюULђпюџNg‚ыЎЛсМИЈЫ–-уЩ'Ÿ$‰P^^Ю}їнЧc=FMM Я>ћ,O=ѕ/Пќ2НННvcд•ЊЋЗ№т‹Яё‘E’Ля,œwЗЋџœєЁH%KeЎyžB Š‹ЪЫpФb”4Ÿ”њ .7Эё8Б й-W, ЏНфD ,с"ъ“y,I087жo?/Йя}я{|іГŸЅЂЂЗлMmm-з_§Аs/^ЬцЭ›sг Q6m|•_§њ—\ЗTgХ &E…'D‚…wh!(ŠА2:—c ЅФ0с№aKўщ/Fтѕѕжож6~jYЌХюж’+же _8_TЏ{бU€—q‘ШЧЎu№њK.І•6R\\L}§јsя?ђШ#Ь™3Зл @^^—_~yцјШЯЙ&ПќеwљЬ=їГЕК†Џ?FqбФ‡,˜Г,Ы^u-DвЁˆ˜$8Яuљgя4UpЩBE|њNеuг Ъе…ОVPРпёОъcr%88o.‡Ћпt%$тJ!„ƒ‹H\.СэŸT …%ї?№SnЛэoЉЌПј{фЏзЫьйГЉЏЏ'ВrхJ}єбœ+o^Нz5_њв<ѕдjtнр/*мєёŠb}hЪ7ћя‘)ЃшHхЂ”\N>+Š X(( "NuЩТо^ЪЭEEД†BgW0$&Эјc^• м1рZpдю) ЦIDAT!„‹XžјA’НЇжGBƒСш›фћšёzв mІD?БтUж–yсˆuWWЧ?cѓф^ kgЭ$Д§-ї)YpБХ§g#ŸК+ЮТK–№џА'чЏ5™L~ …O–eIbYQLЃ}`ёСЕF=–CJ&A}и9“x\Ъ­лM~ў+#YГCЎ–’ћ9C2sЂ”юrEсбšъЗ[Йѕ\”јNFY|™Т#пhс’…*ЙьorђMгDQ”LŽ2Ж[F ёиЫФ"П#{ г<ŽШ2hBLР0ev =Нв<~B–G"шР^@Я)PUVџУ§ЪЁ[oVЏBЉ˜ztЃKi‰ f‡Щ~М‘eKЏdоМ…9ЫЇyЧC Ѓ›Dl=сЇHЦw!eџА9ўДоOРp0ujрёхd‹Ь;v\ъ–Eа:–0p™лХ—_Xэ*Bˆљ‚)зџLђщПwpјˆХЗW=G8цвK/=яќ„#•~<Я0ьйЋИоJИяЏё­VзŸžђ›RўгEQ„њz%G›Ќтpи‰Э?ё ЊЌЙїЅgХъUSЪvЈўЉлјѓп{b?њбиЗoНННX–•щй—ю<ž$уЉp–e188Hgg'uuuькЙ…ЦЃе8”fђђЈŽ‰Wv9œO>Ћ А].˜; €@іvщjj’ІХ }4/р|_Д[ТGі;цч;–LЉїћ“„ќ6•БzѕjvьиРвЅKЙчž{И§іл),,Ьйkй‹СВ,’Щ$ЁPˆŽŽNž<ЩбЃЈтѕє(ќнgцPXЄЌЌ„ввRJK‹ЉЈ(ЇЄЄŸЯ‡Я—‡пŸЧуAгTGfК.§> gњй|фІы:бш‘H„h4Joo/эээttœЂЛЛ›ŽŽКККщяя#‹ ‹ХH$ЖЩ”#ЇL I9bриЄ……ммеEy2Щ,Eсj_——”WV*\ххТ=}КPчЬbж Ay™ ?_IQw“ІюЮщФa6œ o&—МКЮд[•ьъяg№/РБ‰ђ\ ?š,П§SпѕЫ•‹ОŽћlDз%›ЗZМОофkL м„ТЧ!2–_гTмn;!шѕz((№STTˆпŸзыСчѓ ())ІЈЈ‚?^ЏЇSУсPQ‘ЁO+}2™$г ‡УєіівннMwwOJ™c вллCooбЕИN"‘HyIЛ#2KЇпЫƒ>эИtкк;qэГ,І…#T†#”56ЩЫ5M~ЬчcК?ЏпЛ((м•UB=S0kІ`F•Bq‘ЭяЏj Љ60фR9ёЙa\.Ay‘?§Ё ЄЄЛDиœЈ$ Р РF€kЎRф•W(тВE‚K/UX8_L:Її#–%9м ЉЋГ8pPВwŸХЮЗГ]у<ъ’ЄћвАžŠАяcZБEAг4мn<.— UudК%{2ХEg`&‰„н3`p0mСу˜І™9Ч~o0шrИŸ9ьр{zКяgh€(‚yyЬsЛЙ6‘р*У`šЫ‰ЫэЦуѕ’_R,Д™г…2k–`ц Сє*…’Ч NM Ѕ~иУф‡ fыwŸHЖlи( “Iў7№2а?‘FёРw€џ’}`о\СœY‚гэTYiЛseгьҘгмcЂ%™”tvI:N‘щGxВХЂљЄЄщИфhЃуVЙьзŒ’О‡•2ЋW§hЇШЁvж"kŸCЧвV[Œи/Гмє3*ЖхњФXЪЎЊœx МБ> BUљp•ЬдфkNМšJЫMп/МхeˆЊJAEyzЌ‰TƒлjџхЗK i8єѕ[]/МhДў№ЇІЛЛ›MР“@§D@ЖзїŸ}Я“ƒPT$(*ƒ,ќ~ШЯфћ //Ћw[жCt:эшдРЁ‚ъШŽ ‡ыeйm LIH&эоzмvIu]28ƒ00 ‰DэОс0„B’Он ЎЇWвгc7$=Kљ№,А Fсz>[ћF*pЖžeмюŠ*ФЧВОcД}gvгGœ'†<9Ў 6ЂІМWj+*K„рR \Uёj>‡ƒ ЂPЂЉ§~œЅХB””иэСŠэ1'ƒA?щё <7ѕъvЇZ‡ЙЩ‰š…Д˜І8pаhyфFУс^N&yЛ& g [ X,n–NrЯАи Кј@L4^yšzЩ,Ѓxй`СX@ ЯЏП'@фЂЉ '§аьиŠ  ˜ T ACС#ќŠB‘"˜&хЊŠЧчC№лѕїў|№ћ…ЬЯј|HЏђМG‘З›”AВлŽч‚&)ЅьъЖы^7Л~і”ЙЕљ$пOБd.? б˜(f MmЮПўі‚ŒНРЛРaра‰няMžŸЛш–ЃYy9,ѕ6м‚gƒЪPжbВ%lвр В€!{•Р ?хIx…Р/ ˆ ˜&lpЙ\H_ј|_žPМ^№zmoСыТуЏœNЄЫ% M#сtwi$T{‹k*1ЏgОin(а4Ё85„ЊŠTђвє{mЈI)0 d[›emйf†оќЋЙу`?яюf3#z N†ЈЄHрO=А P” /ŠSяƒЉЯЉѓђSРтТц$TтHДА{Ащ@ЇХ7‰я—аК†.<ІгћБ<{;хoЋtм—ђГЄ'˜‘$ыD#в7ЗДmіњЂ?њRЮ2ф=5?š№Uzм—ђb‰=`72]ЋZЭЧЖЏюжВ) s)рI_ЪIЕkHkЄ{$н`jЇCsešВ+eй+V(ŒXШ Rc%vbŒ‡ЖXт;K\фс^ЈˆДШТпPŠ”БAЃ7[ќ`…яn0—Ф_t4ƒy‡јw–$џђ'& +є3Ѓ IENDЎB`‚debugger-master/resources/icons/symman.png0000644000175000017500000000031613560352104020625 0ustar shevekshevek‰PNG  IHDR 2ЯН pHYs  šœtIMEжGW#itEXtCommentCreated with The GIMPяd%nbKGDМ>>Ур‹[2IDATгcиѓџ?ќЧ‡џCд€xTœƒ.‰S!66NБй@ОедUH0xˆ pЗх§|L).IENDЎB`‚debugger-master/resources/icons/watchpoint.png0000644000175000017500000000074213560352104021504 0ustar shevekshevek‰PNG  IHDR Vu\чsRGBЎЮщbKGDџџџ НЇ“ pHYs  šœtIMEм*0f@л’tEXtCommentCreated with The GIMPяd%n9IDAT(Я•‘;K‚qХiшb:4tЁPИИ‡Dйu‡lЌ/AZ‘давi,0$К№Е;КxЇHЊЁ@п^jIOƒXI yЖ‡чќxЮ1’hG?‡X<Ў”uЭ“э0рqMБšІЧ4/,FVtљќŠf–РчolsYŒ•fЎЯЭХЩq’Фцn\fr^œgDЁЂЄSwЂPч™Щy­ЧЖ$ЉŒŽФABm9u™ВdЪїuQДХAB#cAIТ№PЕСч'9ьfЕђѕ.ЦшъŸŸЧj Д#РзЙ,ke‡Ÿ1K‚ї7Шeєє~саЦJC)Žj5TЋcC)БвЬNŒЗЦКАбе‹ѓgЌгоNЌг”i6ЖwtvsћU\oЁ`€У§НпХ§WŸO”Ё+!тטIENDЎB`‚debugger-master/resources/icons/run.png0000644000175000017500000000044113560352104020124 0ustar shevekshevek‰PNG  IHDRэнтR pHYs ‰ ‰7ЩЫ­tIMEе!)œМtEXtCommentCreated with The GIMPяd%nPLTEххх€Z`Ѕaaa€€€š™šЊŸЊЕЙЕџџџyэfDtRNS@циfbKGD ёйЅьSIDATСБ 1Р9D@xkЄm*Щ%аР—@п73@5рзИіўd‚•рёнI€‘4Ў§J*ЃšъJцde4ŽЄWУ-ЮdїЈчЈД?rЊsс3IENDЎB`‚debugger-master/resources/icons/openMSX-debugger-logo-16.png0000644000175000017500000000164313560352104023622 0ustar shevekshevek‰PNG  IHDRѓџabKGDџџџ НЇ“ pHYs  šœtIMEж 22KUГ\tEXtCommentCreated with The GIMPяd%nIDAT8Ou’{H“QЦЯtюћfІiVF7Ъ(бnЌдŠ(ˆЪRЛM(CДVБV‰ 6(§ђRИ2DЋY­E)•ЂiГ2Є‹ZЪ0cЮTXЮ&­YіЯrфmOgKVKzрѓЧїќої<п!d\………QЇNs™б1чЛOœTДЩdrЅ№…ЛФћB=ёцВˆ0н‡ќOjѕC]ЗoЉпuŸх^`ddУУУ(*VС/(ЁЋ 09@оHиc^ТJЅ2Тh4оьяЗжL›•;ђХb…нnwљКRE#xлвО$q@ЁP$ШœЭэ‹ŽSЛ…6™LЈЊЊ‚ХbСЦ-Yљљљ)А˜А)ђtљcWPЇгСfГ9ЯїюУl6c§ІTсљњКввв#ЫЭф4Ю€уў"‘—.хCћ&UіУєЩс”XAм с/ПBx?'@"‘ˆцXNВфŽkƒŽŽ<{ƒn)о7рrž/жoQР~oЮ!„уИ БXCЩЩa+Ю`llЬ xUŸяЦЩ(UlЦтyё{§Fƒќ(Я0`тUщ.•JCW‹’2>ёікк|ъеCSЙе%№8:кr)FG іI3,кIЇЯІсIдМzW<ЁдА$<Хž˜…ддsи'–с^i5†††№Зm?1еŸn@ˆУъ?m ЖЩsˆо‘N`ŽSёкŠ9sЃ`ЕZн ЛїЖКђгƒVЦюЩј] Žš6Ю_žg ƒртХЂ^Щ іpІЭˆ[жп?€]БGhA!4МЌpИѓ9јWЙЙZ2AќH^Y™Веj§JЫzŠE!‘є-DЂЁБб-ЌзыАnэђ“3ƒўšЮВФѓUSfюЂЯ DWћZ|hwОFFCџР(њњ> щe˜ниЩкпщ[йЮьLў|'@‘'Xјђгђ\У|ЎЋaОi*НЭ7Ў­б—”ЈкU*ѕЧ‚‚+ ђє(uM… Мљ5Ће6В–ЖfжVyŸЙњ bщA03ЏIENDЎB`‚debugger-master/resources/icons/openMSX-debugger-logo-128.png0000644000175000017500000003655413560352104023717 0ustar shevekshevek‰PNG  IHDR€€У>aЫ pHYs  šœtIMEж 11ІрЅtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“<аIDATxкэ]XTщзПг3”Јv‹…]ЈЈиэкЈЈˆ *Ј€‚иБюКvk­КЖЂЎКv'Љэ*‹ХљЮyя{с2 ЂŽпяѓќžAРaю§~Я{^Aјяњяњз‹/ ќѓьŸЖOŸ>їјёуаŒŒМ}їюн—Зoпўq3іњѕыЎ]ЛіђђхЫЗ/^МxємљѓЁgЯœwъдЉЖ'Nœ(№пSќЎЗoпfxѓцuЛ—/_­ˆŠŠК„ТъUЋСппКuыnnnPБb(^М88::BЁB… Xёbрьь Еkз†ж­[ЛЛ;Р‚ `ЧŽpфШ‘ћ‡§ЕтРэТТТ2ЄшƒшКфєƒ}Ујy‚Ся…`ˆ,&‚`1M„ПІяБŸ›'шљВџѓп•Ж+&ц_ЗшшшѕЯž=‹оА~=#БTЩ’5kV(VЌTЊT‰ьVп 6l 4€њѕыC:u FPЅrp.я eЫ”’ЅJBЉRЅ Lй2(,Ёyѓц0tш0˜7oьмЙ3zзЎ]ыQ0м}MK­ :R0ŒН#XLAЂg˜Рєx!ˆУT П;‚ЮsЄ mЎ§еdЎ?оП{? &&&ќаЁCаЇOШ‘#,X\]]ЁK—.рссю§њAГ–/ЫUђzRЪйѓMёвƒ>)сŽХњCС"}!Ÿc/ШSА;фЪп56GžŽ1йsЕ*YЂ)Z”НWўќљЁ(~]О|yhмИ1 ю K–,†-[Ж„џёЧ:uQаћN С?O8‘<Х&sLŠ‡СџЃ ѓž"hлщџcкшŠU љю>МмДiг`ћ,іLЃНМ̘Йх;ЪАч№ Ј‘н§hбќB№# Сˆ Žё шЧ1( уРЪ.œЋЮƒ!УwРјрUрыєБI“f19sц„lйВ2зAГЏ{_јyіl˜7MЌkУy XІ„tЩь3M_-BLУ0&Fаyєјѕxђ+ќјщьž={˜Y'якЕ+LŸ>ІO›6iв$—x?<АЄожїFо"s |Е%ркp4i ­кЏ‡жжCЋvПCгжkС­щ*ЈщК*Л,ТЏWТ Ёлaеšѓpя^рпќ› ]SІL‰%Зb—93ћлUЋV…~hafЯў‚C–@AЇYFЄO6"\"wЦрxЄW.˜AќgјЊОGаvЖџŸ%ŸН%1ѕоН{№гO?єъе Ѓ)Ц`Эпшw3?{іКоВ•Їљн#Gя‡a#і"БЛ п эаЫ}+tэѕtшКкtјšЗYƒ C}vР†M—!22 оПџŸ>‰Ф“ШAЙœFш2dАцr|||Xœ№SЧ_@k;‰kw'нˆl ™ѕ!Xа d`џ_-№Uяћ\аї­ђПHО#>ј+K–,{{{”­XБBѕ—§ŽсŒ№BЬО|ѕбкЩг~rЦŽ;ЃЦьƒс#їРрa;ЁџрэаЛџVшжktъОмn…™П…у'#сЭлw№ ЕоёI ‚›[АВВ‚|yѓВИ#$d"ў іЙ'%дh‰ш8’eСџ3№E—Pѓ‰ќ6Џ^ПŠъгЇ/њпь0sцLР( Sg†HМefдD?ОaрЗМХ4?=Щ—p№рAААА€L™2Aџў§!(h<дqOЖDЊžˆ!BO№СЏ}ФWуЏ_7фцџ/ђccН/_ОЬШ'ѓљ№С9љMз—ч'ЙРШ}џхЋЏmоz жmИ ЫVž‡vзc^И}Џn,hlЁz…,к‰yџUШ— Ѕ…%икꂇЧ €*5}ˆі–a8Ч0†Ы^СџŸnРЦџ/9~›лwn3Г?yђdxљђЅœќˆgˆˆ;ˆ\Юs!јћŸчoЯю ЛЛ}ч  :YѓL‰'пЋї%О)5 fџv ^DEUђЅГ^CМ`єшбPЄЄЩУ@aЖY§ ~“yшЖЃ€ž‡(ќŒч/>€9ѓƒkУпаuQЬрХ1TќЗЎwƒœќOŽHx|~~~˜‡П—“я Ц^r!xˆИЫ…р СЇOŸЮŸўИфŠЕќєщуЊхSŽџюн;cЭџШƒx…јёˆ Aт*ця7–­<ѕ.kžщœј€фЋ-§Ёj­љАeлUVфљкoœ!XaŠHk ўа­ћP[yBЮќcaхъ“qŸ)Й‹ъ3gя‡LYЩ т, „ЖЏџКЈ3uётХ7o>Иuыоф[)кwCDqэ— СkФs.ї77ўqq­вТOЬБуШ+ІY:?pШ#|wТнЛ/О)ёr4iвlll ^НњЬ4iю‡G˜дјЯ]d –Ў8 жvd lпu >|јј]Е_e8YьВ№F“ЁАoп>Hы…жнЙ‚>ˆО"Д=§<1†шЃ#+UЌуЦƒsчЮIІ??Ѕtto<чП&‚Ч’йGgoЄэ›SЁUbЊ'#Ÿ*mZ_ŒЖЧƒїШm№ќљ[Г _BЋV-YЗѕ. <˜п4Л‚ЃжЁАїтшMЏЧЭ^ЂпFиА~)Rў>њЗ<ъŸN‹lˆcˆг2!ИЩ‰'aЈПцяY ЭџЛ8Ÿ/‘кЏ@ЋPМь XБъt\ze.8rффШžТzЌ‰…ж9вz]К Ysc ышЩ_;g5kxѓцM8-№|#џ9sцШ#wФ2Ф*Ф:.лИl@dJ,CjКaБЂцћХ“Џ‰бП/дkМNŸ‰4[ђ ГgЯ†Т…СЧл‡YtiЪp\н‚ќxџDAаu)ov№ќљѓvЁЁЁPЖlYXЖl™Є§ˆ™ˆˆ%\~Їѕ}ОЮ_йф›щМ]Х•5Пš/hЉжŽбѕАЭpїо Гєџr899Aг&MY ћў§ћг$є>CН—сНЗуhаЩзьрйГg+ЈцпЉS'XДh‘ќ9sј1Ÿ СJосуeђД]­PћG$$ŸЏЉЋ‡CžBСАxй Г6џШвF”   /r э…Ў-’Oј‰`~UСЧп/‰7K=s2ѓп 1 1ё bѕіёзŒІЕпЃ$К€KbG з|СoмŠ”œ6]0{ђ дIL‘2ЂЖmкТЭ›7YY|жЌYЌR8aТВ–pьи1 h_$)[Жž•О оkНЖ;jVф?zєЈEКДо?}њtЉьЋDŒ@q! :РlФ\DЃ$пŒхџ^яуЬОдdЁŽщпHpkВО Ÿ>}2{8uълу@!ЊвюЃ‘#G2`ъдЉь•ЪцхЪ•cћ Ž?ž@"n>Bв[ Z"Z‘D›•<Иџ -IrХJЩдIў?+b$b bAрЪ… YВЉ_\89Є&#œ™~ЏxђužLœЪN€Гg#гељ›7o†*UЊ0ђilŒBЁ ћ` m`4(Sн4§]zяž=zВСTД:HЌд\ДЫЉrЕОxџе55ХL€)‡;ўЛќGAaMŸѕbщб7ЗgЯž}YойZЖl)€j\(Hй”,нqCФа„фыуЇ2Сpњьнt_Л'ђ ФHІ^Fš$ €$днѓў}ъыўљ'ы XДhw*Р‚Сд\QQo gžfxџUеD!аДрGѓЖёОм-ивчAЌ@”ќf1РщSЇnSБЃQЃЦr(KiЂ6Т:…Р‘|ЖSfоxДСpцьНt ЩчKf_вp"yўќљ €@кKUЛдЮ qt$\dЊVЮMXazї2ХАkї1МїJˆЪˆ*ЂаЊ`љФЮa]Бwнƒ p>їnФW_:ЮsќФ‰ЃЄ§uыж• 5‚TBЄ|є‰ж €o­’4Ÿ ЦСpётйžџ/|’й'Э'ђЩп6,‘аА#FЄ@Ј^РЉS'aЯо}p№`,\8uЯ§э7hм0;\=Љ†й?ЄXњ{„рНW@Tф‚P…кТтЩ[Цyгhёgк.bАЈА—>џyD›Џ'dB3JKС5]jЪ 7ЗES%ЄљЄѕ’h‘|-оЌЪЪV ›7ŸІ›PДOљ|2ћЄљD>‘m,*u'ѕ^$8ЛvэF!…sA)'š7РНO &8”іьš^мб€зРЌ)к3№фЩs(ымIw&_Я…@ы.г|jчфы8љЌ{ЈƒИtL1ƒСтš+ˆŽUКV>2Ž*WеЊUƒZЕkIНvдпШ™ђwђD mŽє5_G;d<˜TЈ6 ž={n@ўŸЂ}SdCЅRAЧŽНЧ‹QшчwBїю=!{V 8 ]+N†)сUЄЮыЩšCй€Џ-€пІ)aџўфї lиИд:"П,Ђ„|лXљ=‘lо7G~;ОtмZ\EЄ B‘YКŸKˆvEКHjRл_~§ЊT­B#_фн@Ž&[О’€С"Hє\д} ЊЫЖ”^KС”чSЊ—Ш–-а>Gщџ’Л8ў"а"XсBPГЊСcpћЂ о>PCд] <П­† №šj”YНаŠ Рщƒj>|иgЩћ6jЛ"БЊ’ˆвˆ2Ђ hqГяЮ§~OБc˜5ЪЩoO>­$jšŠџW…–Da+нз„г Рў§ћ lмД‘Y€J•*љЫњђ’ ЄNd~_в~2w(еjMсeрє*ђPžOQўчШ'Aут?~,юф}ѓж­л..U ’Гk+щЏ"UŒ`"^Т”ЉSY*HE s‡uq?ЏRЙШg`ыж§`aЏr…@] Q†ї‘ЏK‚|Ъи2rq5‘­%дуzOСZЪF~Б[иГgЯ§fЭšA… фq€§gзў Р`—фы9љ:4wЊор\yњкЈtMЩwSžŸ”љ4л€VъФД,Š-лцЮe=: pўˆŠ™z"嘝ƒЛ›Аѕџ?ўј]ƒћЙ„mЬŠ„†ЎБЃ{Р№Ёm`Œп є?п>PІ,њze!Мяb\Jˆ€oD>u k;Ч‚ 4П9'П‘Œ|*'зAИˆЅ2ЛtЏдeT,ЭАsчЮД”I02 ЁO)<Еƒ\XаЇ7"_‹&Oн — ў OЗ@Ѕ€”чSЊ'€фѓЩь“цљє{OŸ>Х€n$иfPТx_^3'В/с№ОцЌјѓЯ?CЮРЬ‰jhоЬўX“^=( яЃЗAЬ›PˆyН оНY‘с• p”lm3s!(ŽЯ N|КЧ‚>в|‰ќv‰Щз4‹FД‚Ш‘8љj^TЊЦ…РяYEї§Q?MА}ліvtЃ...рTЂЄфT4ш1хррoњi{ДЖПѕЊњ€Cюс0ы—}щО(хџ”чSФNб>|фѓ%ГOф{zzN+€g?3їІД>ZXЖt3џдДlЎ!D^бCдНььыk'uАv‰ьйЄ‚‡сjxyПXмЯŽяSƒcA+PЊ‹rѓпЫDФпž7‹Ъ5П)яh|M-^VЎЮ‹K•Фь‚Й Щ%4NЕlнК5У† ЂЉї­D‰ai’"’HФ“h%ђyРƒ1€­Н'Œ№н€fјлm—fŸУpяшhбDЎ&OўЭ х`ѕъUpј№aШ›Чю\д$€w(а2ыqљИпS W№uЩЏ*фЎ„У;5ьgRа˜+WV‘|­œќŽ2ђлˆ§‚NОVвќњ|БŽ˜ Ј%ђЋФ“Џц™ЙQ>"МRЭпЦ›ж“)%7PЈЃKъЪ5E р!’Oy.i?Ѕ;шЌ3„ўƒVРнЛЯОйrю›зЏYKЗVЋ€†u8ДC‰~вf_„ія a AПќђ ќдТвˆќЄё4BщЄJЅ­›YР?ЗФяO P‚ЮЊE|ЁGžыKфГЦQ9љn"љф:и"’)Э—Ш/Э3Ž"(quNЉтoнКѕnД+ЈQуFP @џд €GM4ћБЂп— €–jн}@eшЎnSрЬй;п„ќwяb`ХŠхЩV л pю^оKŽ|Ф=lлЖ Nž<Щ&Ёn\ЁKБŒђRB)а"ˆпЎk›т&ЬОDО‘цk9љёЋЩЏœPѓељNbМAСЇ ЇЯ№&еi"ІUс4џЗt™вЉoZаЃаyˆ “r]Œа‡AЁЧL ЪxиЖ§‚_cШЁCAЉRЁyc.UЅŒ|Ф•Г=€Цо“8ГH1љ!ўЪˆЕоƒ•q?oваЦЈагVІљЭŒ>N>г|#ђ+Š•E•\ѓ%ђбЈ0(TцХЯ ”ЪШ)?мbхЪ•hd“ІMh‹Д*  Р;QИцSдЋэ-Bгђіy іѕЖАШШ{аЉc(VX€}[”<еKž|ТєћДЮаЂe ˜œМіG^QCЗŽЪD)hцL„mUСЉbМсйOЩїЪ#~YЎЯШo`ЄљRФ_•ћ§Šb1ˆ*‹ІШЇŒ@Y‘EщГЬM1‡Ы—/7,YВ$’rkк“:0Ј< РуО_ЖвеьВ ‚Р ?рэ똏ўћяП0gЮ<АЖаї*рЭ§”“ѓj?4§' ,, ђхбУƒkIOП?ІzіvІыz+сђ15ьX/˜ЛЋ’&?.з7ж|)н“k~9БЈФ Lœ|•D~A‘|eD.рНЊUХE‹К“ VЈœ9r„ЅТ8ЂіяOЌ§§іФл 2dщ>ЃBy&№uДŸ|wўќŽPІЄї.Љ>э'Фу[UрвЅKЄоƒКЎuaFHBТщwўЙЅ†]UрфкgIКњHщ&­>Й_djмР&…W1ш3ЮѕYаЧ5Ÿ‘_*^ѓU’й'ђѓ‹ц_™‘с -$ЅœЧѓ(цЮ{–VжjжЌ ™э2Ї,#а{d@эЫШ—@š‘УР2c_шэОˆe_Ѓ9”–sGі­F€ЎФoJШ'мНЕ†эџ[Еr”.ЉСИA KSС%ŒЂ„Žm,РЃŸМЄШЇŸѕQ& m39šЮѕув=зјBЦˆ|еgШW“Ÿ‹“Ÿ @\•4хZЬ™ѓkeZЅ‰к4E3хЕwзИРO'г~Ъ5н@Љя•kТЖчОЪў€ƒїAЦŒVPЉМ7ЮЊ!*…кџ4в›Uoпg"gШ ЕZ"U‘Ђ' ЅK*рйMuЂQЅЏŸ|Іљ –x™цз4вќ Fф—+‹ЊЂёфЋфšŸ3ž|eљтQъъ;ГfЭšШ6D88dMйжКЛˆЉ_Ÿ„фГхЮnlе+[žA0Ъ/юо{–ЎqРѓчOaфH/}QТ›)#?ъО ўпч№ђе+жЋT(SEИK ŠQТ‘}јчЖ6Ž|*й;ЩЇBЦ8з—Uљ>[ш1E~!#ГŸS\ˆ#?3‚њ 4єiObн РŒщ3,ЇNz…кЎЈBhmcэМPн@lп/u0иє‚жэfСщгЗвUŽ>љђZBЮ<КЎцu~ І…|45–О}ћ–-ћ*•i#?FќхЪbаwZn‹ ђO„Љ!_Оl|eߘ|Йцзт>пљ*)з—‘Џ*ŒрšЏ2&?ЋиM$‘ЏШ€ŸQ'}жоЉВ“'Mvœ0aB”Зл$ieiщ’L XСч"љНiП щ z›žаАщ$иБѓ,ФІS§&M љ8КG /я&Џ§O#T№юэ>ŒE>ТйГg!‹Е5єРмЙ>ЈЌ,‡N™щЇx УOJИ}ˆ70Ќ_c=ЛшСЦЖ(7ћ-Œ|ОTхsхэтІЬОs|ЎЏ–в=љ,нћљ™DђY& —>яˆTзw‚‚ƒлаŽXВtŸХч„@70К€пEЭ7в~Жєй}a(VкІЯЄA‘ЏгХ \ИpJ—ЪЧЪНbк—ŒіЃ~љ|;Ф`Ъx‡ћ}|@aлž(ж‚ђГС^Ё Xє›–iќЦЕд_•*fhl1GVтеHП›ЌОЯг=МФ[1!љ*cђ %MОвљ ЙЌHг:O@@€7M3z4TЎ\…жпM vЄЃџжІ|ПXэŒ7з,m{@ЋЖ3`џСЫщb6nм YэX9ŸŠ>Щh?’џфСFцїЉŸ Hб"аЮ~NўJAЛјПЗ2AЈ-к(аSТTLя]ЕўоЭn№Я?уBЦ†BЛЮ"љšf|i7U>S%^ёSAYЎoЄљJ;#ђ-ёѓZщГGЅЙgРЯЯoм(__6L™вCƒС`Zt}kŠA`wОђ%uКvЁю€n T­9цЬлХgђЇќ'Ož€—зhр*`žЎ2ђ§FИ!І{D>#ЦРx`|P™‚–РпD XгСбШДŸШчЕpЅЁфЬяž^K0ѕzђE'„?~ŠЩ ^МОŸ4љoT„ыW–Т­›Зи8xj щ,#9ЬћdпЇзN˜T,Џ‚ѓЧ œќ ~Љ в$[УЄўЧ1ўЫ—x5ІЊ|eуЋ|& =В*‘Џ|ОЄљ2ђœ|–ФЙВO_мC8tшPoъ•Ÿ0!њіщKGЎьO*€А=оќsгЯШч‹!šіhК@:ўАh 5‰МKГиВeds`§2МК—иќ“EИ{Е<?q‚|!ЭCъ+#ZB˜ь5L&cд„xЁнЩrЏ0\8ЗœYŸд\c–šЈђЩЭО‰/‘Џ’Ш7*єа&Ѕ)ђбя+tмєЋŒк/П иfрРQўў0nќx(сT3+б%шІ+0hпъмEF~G.э@kе }њЭƒ‡гv^5xMaeп'7›џЇ7Еpь№4vР§ћїYЊ—йЪ FqЂї ўDэ ŸПв.ФNњvŒю§‘xяЦJ8ДWgђЯЕС”sEš'‰‹‚А0™B‘цЋLUљьM“Of_ЁчšЏ2•Э8І‹єsячиЎ}ћoooж8AЛhsHkЌ длH8љДŽ Ј= AMД6„˜wЉ?5$<ќ:ИдЊ5Њ§0aWЯ­KUYKЕŠнО}‡}>ЧJиМN СЃддYƒ­а‰юІEрУЁЏ‡8( Јƒ ‚ЧЈсќ‰x_ђpFиЖЅКы^зи€ẙӘќЂ&JМЙ–xЉаЃ4ЁљТgЩOнТPr—FЃЙRЁђ6]„ЦЈќќѓ,dЬThf'ќёц@#šQк‚оК”(ы^CЧСЅ Лрмй}pрРиЙs7ьиБ‹­Ы:tЮ-Р@ыIт5џУG ‹ ИїP№ЪŸТЯUDЂќиL?:тvЭšеь№ ЗњѕСoЄLŸœ ƒ8Ы8b?‡SGьaщТвА~нXИvэ"|­klРpЉн],єАeнТITљ8љ Y•/љкЯ‘OpKЯE1t]ЮqаАQ/ш?`Ьўe6ыЄЅб*Ж™ЊEi ^Ц›~.ъіЬЈѕnPШБ,єя“Іgƒ>нэСЭ53TtЖ…ђх2CЕЪVјo шдо †Ска №їпЧ1…GГmпОВАjьпе~_3Bз†oKfПvэZlк' ]”ў-^<ІLгІ4_{>DУ<е0:ЬžQVЎœѓцЭ„SЇNЄzKј—\{ї§ э;њ€СЊŠщ/ њ8љJ[žюI>_"?йjцАє:,VА˜„E|PкУ€lш4MйЂэеХœjMFЬu5Р`ƒi UCААЉ ХŠхƒ–M Р Еaйтўpђш4xtg:М}1b^O…Ј‡сђЩ’АiЅМ=ѕPНŠjЛ‚)SBXгFhшzhеВ6Lš< 6lизТЏ1ЭЇC rхЪХ Wббб№#]ДЅМ]‡@Phk‰ЃЊ‚ИШЂ~KОКgЎ•j§)ХДєН€iˆ) Дšљ yЂIk ]Лvƒ‰'ТЦM›`омЙl№r:u hбЂPи1 ŒєvƒШ;[PЫ^"bргЧ(јјюМџїт С"xѓЄ-МКябOaХЂЊ0жЏtыжЕ]Кd)л#xуЦ fyh€››л,B^iзѓѕыз( зЖ}ЧQШьа”/IkегДNa“вS šЦ\І &!Bа*абьуС.ћ(Yі'p­уЦт„Щ“ЇРЦ`їю]lЯ=•˜щ$я:0—AуъˆФКuыБўў6­л@=@L;'Рт%‹йVp2ёTПџѕз_бДšpвЂEs €tвЄIь}iЭїKэPѓАЏЁyЫQ ˆK9вGЇЇГt† Рd$}ОŠфГГ cйбь*KШ’Н8mхœk2Ђ{іьЩĘHќ§їпaЯоНlвцХ‹1рКWЏ^cfž4œ4iJטБcXЇ™ї 2@іьййv62љДlMmэ$$є>gNŸMhyHhcШfжЌнV\e§€UФ4№Ы ~z @y0­Gђ Aјѕ8ё`hУFО85œфѓƒt6}!c–і5gШЏф+P ,  УзB/_~Ш“'/фЬ‘ВeЯUЋеbулƒƒƒб‚ldТC‡ZцЭ›—ѕ.Жhб‚-VQкG&Ÿ†4Rб‡Ž~[Иp!ЌZЕъ‡€ШШ'PЉJoN~e ~ЙLO НƒOСŒt~JЈA:.Щ7$$?ёx”ОМuLк0й%QћДFпFњ.Š;c№ќљѓlя_љ™ЯЇЮ%ъcЄ}€4хћйГg дHп#сј–б|z\яп€Рё 1S’ЏVHАLя)##˜t2№'?ц'_g<EЖ_.љвЦ Б•ЊpБЎАgпux§њ5‹ВЂажmJѕЪ”)УF‘{iеК5лHA`Ÿ>Н1щЫŽљ‘BqoУYШžГ!ЏVKЦ_.щ~i1}Цˆf>ŸkО42–‘/ŸŠХ7Žш?CОЮxЫT3q9UU”Њ`Ар92ЕHKЌйЁЎЯыэвТKu ІЪ0ѓЉгYГЦ *8`іVсљѓ—PЗўОVр,Baѕ%фяњZУІFАЮN ЅгB|dš?„ЇЮЩзЛm“ўЬfIЉ™‚в!eБЋ–, Ы8BxАщЯ-Ююf<љіtw>|Љ;_Œj/О' І В|šN ЅБя47Р\нРФIKа №ѕZ-Єj`к`ТзKб хš>дHѓ=’&_зйˆќжFфЛ‰кЮRЬœќ‰bРЩтбќ|o™АѕчЇЗ,вFЬ–М#ЗЁиGыю [Шœ93Г сссi>4њkЙ}ћŽƒ}Ж:тz5‰P50эађkŽœы"Ј*ЦЯŒ{•†"Й‹‡)3ђЛ H01Cj $’ш{Œќi\‚yР9†Ч>Вs-zrыв‰Ч­yWncоœсЪ]E5бДRЅMPБ‰Љв\sИ=zЮхлѓ&‘RbSHк@ћ5@СF•Јk}‰ФEpђuНуЩзvMBѓ7M4@‰Яё•ЦЩJ7ЧЩт #гЯўVЏФфK;qи.œКМГzќn[f^‹0‹@§—/_6 ˆŽўњі ЅFj+‘VђW‹ЩЃ•1H‰Ѓ|Щчї5š‹гE$_—ФD,љІ тhН;ЮєЃпЗќўhNўpnњђДRђћ’щooњY_^=о’UCжQŽ/Ч/ёo–(QТ,€vRџњыаъЫ№.!ЇД @[с]“и7Г§9!rђ?3MЎљд7OU0Zeк?‘›ў~(ѕ(юїНLј§ЎмКќ$ЕжˆПЇЋlїM%о[š?м"ё­W 6!Ф,т€Аc`ŸЕаbi!?Rј†Щ-AСШeBа›З…w1Б?^> 7OjeБXƒ„Гшї мяыЩєћrП?дШяsгЏ3ђћZЙпЏХW*ѓєЊL|#ыКЭЧ—`ГAЗnНЬBюн{ŽEђж№Ђђ§~)Хс›^ЊŠ YДЊ—b€ЄШ—ЖH7цк@–зз5‘Оf~_–ђщMЅ|Нd)ŸTDj!ѓћѕx]@2§мя3ПZLьРa-зyтЖWщtYбщ{_џќ5]:ѓ6БТђЉЁ)A8B§m@ћ“ПB•[д2ВЌCиИК—‚сŠœтїYЪЧ§ОaЄЬя’Mлю‘ияkŒ§~MОИRQД,q;m‹№­VyyѓEVБпNАasПwСˆСўў Tѓ>Сд @Cс›_кЖўj‹`eэ j:›‚Hљв(4ЪџiПМ<х3љ}dћ})ъod"ху~_]:~ЧM\Ыu.YУeFЖЙ‚N5‡@08ф7Pi ‹Ÿ•у”‘?[ј.—ЖЕП…m7GьMcsђл|~Ÿл0QKжQU,ѕRœAюї‡ЩŠKмєkMЅ|уS>‹lуeОљBfњYћUnnњэyЇ­ kЕђ№hqРь_–c&PDЌАПЩ’џ—№нŽЂбЖђwШбЃзѓќ@j ф5OBѓчрё­Rl8r&ЎљRЪч™0хc;:ЫL‹„ІпияГў{N>љSЅфїљD жjmЫkюZv^А9РяыЖu'žЁ$+{ПНпO -§ щч/мfS<щhUf^5ІvШЪЩ7БC–6?o—Ї|:SЅ^iъV3йіы:ŸOљи† ЙпЯO>лY#˜:tьЪ‰Ÿ7~шƒ1hчOсЛ_кцў%Ы †;wХVnк”Aе5|ЩЋ?3ў4n‡ЌЃјoyЪЧLO^NюhТєsПЏ‘ћ}yЪW”яЕ“ќ~vОХŠ›~–fiидdjpљr8фЬYAtU ;:N&ёыЧw§SpsИДM§+ 'OЂтWhƒFцЬмfNмN>C]B$…4>AЪ'їћВ”O+•zk'эїU&ќОRкUkЩїд)YѓЊЙ, нО}ђф­Ф6ЇП`ж—ЖIX§†cрЭ›мШ–-[D2™˜š„%D1š‡CiХђ”Og"хг—zЅ”OšЋЧKНЊ MПBцїYЛЕИ›–šHЬЇ7 œJж‘v‡™ЗhA‰В§спяŸ7nЫЏХJœё4NОкxV^qз‹ОOМщ[тm%+&IІ?ПЏ’ійI-ј›ИНє Г№§ ;…_Aћмbe3З ЁКЫ№ИЦцŒŽb-AyйюиrІ‡"Ју—@йЬ}ЃRo’~ПВlЄj й~ЛЄS>ig ;оœЎ№№€тžIЈЪ%,ѕ*e)Ÿ‚—z•‰§>—7Чб}ћAF6Щvg1wЈVАHW8w>тГ-VTc…РР!™}љD Šˆ$эЗNьїKНЊ2ВRoЁ„Ѕ^VJеIG­ФЮ2Ч‹žгoП-ƒE..Иvfžh\§mэšСЮ]'’эБЃ›#­гщЌИцГpт–eeУ‰(В Vљъђr„н=I•zYM$žђќB… БЃrhg‘љюx^^~ ”B(3™ЛдqбY應“VБЮж”\ћїяGџkЯ‰JbѓгY)™Ї|yw4UГпg/ѓћlhЂРBvhпž>њтХ tUи4кMє­LzjЎ'OžB}ЗжМV‘бЬЭПtЁInв|$>рW)Оa: ’ŽЏїП?Д‹/RZЧК{ŒJН*Sн=’пWаЌ­­Ё{їюА|љr&4-ŒЖ’Q э)4GџтФiШžН(ЏUи~ПР“ЫЉ8ЎT]г?{ю–pјШ…TKќСƒСЩЩ™ŸХhь)™oЫфKНq6ИщчУыеЋЧЮІ"OФ“ аПilЌЙ™џррЉ бкёŒХЦџБ5\дz1jФФМOѕS–0kжlt ЙуЩKзИH*хKPъЭЗzF>пеЕ.л.FM—ЏX §›ЙкB{iыЙ9]wюм…*U\y­Тц1џqБ@ЕАТХкУљ 7вМс‚Д3((!ЏдICЌd3іф)_с„ІŸMФ:*№аvђŸ~њ |МGАЉa4o€6„аФ1OЃeЬхЂFyѓЅЅ~+џKдUа TЏЁ3аДўћEƒŽ‚ЁУ ћѕuыж­‘kЊЋ—eвPЅ,qЃRѕz=щжР њїыЧ†IаlкE,э(І8€ц™ƒяПq#*UЊЭk–?˜іЧ AЅАl9СЖэGвЕЗŽJЕООО"Щqуе’(ѕђСIJ…‚ • ]Фt"ИŸŸ,XАЭ гBШк\Пq “ќўBЂёўќAЋЕхej сGНhІkеq‡ˆˆШtп{Ч—ШЧЋф]НFн=8j4т %k+kp*сMš6ekгІMg3Œhф iўуGLћ^Іѓц?![Ж|М1Х&ќа—КМ‹F_ њ˜РЖ<ЇїЕvэZ|Xyx‘$aW/™…BI‡aВгМш`ijNЉQЃ&+ўјћћУвЅKYцAs_О|ХAŠО—щ?ў8;Wс%j‚Юх‡хОE СкжVшЏейнЩš-;Дlй–.™Ž|мŒИˆБС›typdО)В'ЂЃ#мШїЫfkk ЅK—-[ВЙBГ~ž[Жneѓ‰( ІѓЮђoнК M›ЖЅЪ‚—ЋPђ‹ђXY ЫдW>лМ^ћњс-}Lф =\ПЈ‡гыaЯ6ЌZЂ…IA№Ј‡qaB№`ЬЯЇЃіEЄкUHП/РД›Ž‚“.š4F еj!ўќldЭ4žЭ"гџ№С&4jцУ‡_…hz_4Н{їn6TГC‡іPО|i(SІ-b%PЅЂъИ(ЁA=х‡& •oš7Q>nжXyЃžЋђ\ЙВŠCљђ 3ьэ„yѓхђч ‚ŠЭзМ­ˆєЩъЅкnbхуWЅ‰лIсф=ќ:S м3СhПОАљѕЌ’•zЩ"ьВисC/mлЖoo6иrЧŽlBM%ЃE* г+p%СЄieДдмБc{(Q"/дЈf =ЛЉajˆ6…jсш\8Љ‡№ѓzИ}UЄ0nbё™1DFшcёћБWЮъcQ‰bwlжЦNTПhкHVДАаСZ/dјЎфыДB~{ХщЅѓ5б)™Х›HX6Ўе{/5r ІEс_Lˆ!+`0 paG6dŠІ™’Е ™„ХŠcПC)'Ѕžщq=|ј-xеЈ^ Z6З…ŸЇY йzИu•ќХЯщњ}ьђ…š›4Pю,URЈ[ІŒ љќ7v*Ўxpъˆ.]Ш7i՘Qшяо._Кf2ˆXiAˆFФ8—w†тХ‹Гв4%фЬ™3щКŒK}­ZеŸЁ№з[Иw=§Ÿ SФхгКи)дQU+ ГœЛoI~гљ1hžbОЦЭЩqѓВ|Мд0dHЏ4mмЄџурр–––1cF6OxцЬ™Ќ”о5ќЅK— Р–‡#ћэсk?Йе ]ЁљXЕВbk–,BоoAОЋkmхЭoAОЧџвCы–y0pћ+ефЬŸ?ŸіюнЫ C™2e‚аааtŒц?Т†ѕЫaЦдкpѓjОІ'ФІŸшaѓяšЮх;еj!Яз$П{G№О§–фKˆМa€>=дьL€Дd TџЇ)Ѓфїi!(=.š/4tЈ8RУэpыdясСMіё1Н-СКUšX ЗeЫ&8| ђГ.ЄињшЖўсї _ЏAjXЛілƒЅ4Žќ;™y №h’ЅstX†‹Ku ЈЧъс{?Ъ"ІMRШb'Ьв{@”С ЬЛpBwў{пЄ„ЎеpёТБЏRœ1NIЫif1-&Q)zоМy№їпУЫ—wсMдtxp+{јц№\".ыcjЃŒR(„ЦщFОJ%T №SэЦ?№Щ\oЃљ,№ЯГЇщJ~Š­ТћpјчaŒЦm™~pг<€Аs‹іcО<Š#H}К@ОМŠхјЦoЬх%„эдAѕj…йрhЊчSS -Ќ|э…rGLD!ܘ^ї+УПп§ шЋzŠыўХУŠхљЧŒTп77ђуnіfaVЩ b•Нє*чJЎ€NЇ2.•›ща *-Z ь2ы QЬ™ЉfН;зtiЖ”p|’}ћ™L!YAйНUћ1kVсRјeеBkkСїтЉєKYО§B`р$Ьжa€v”5V<~ќ^П~УЊ{М‘цЁrаїШjаZ<ѕDFоg=ƒЛwяAВБ’qгІЭсЖ3JЅNp:(mc-DфШ.\­YMqg№елХѓ4ŸэбBФ%БДKю!я76%)ф­+њиFnЪ'TГљВ•]ЕPЉ‘›ъЄПЏЖЎз1пћН ?†ї‚_Еа­ГьГЈ@ЅЖ…2Ј5™РТТ2eЮ  –gчjPЏ^дZw1b4Сјё0 џ@№ђэкu‚5jAщвх WЎМ`k› єzKPЋЕ (”МЙ$б‘lД^/oи щйе-,„1yr ”.ЉxаЊЙђѕШaъOKцiр/ Љцџ­т…QоЊpвщдЌїХ=TBЬA<Юž]•+*ЁuKxИЋ!pДfOзТЪХZи‚BBО™ 7ч-tшйбыЄї#єp7\Я4хђ=œ>Њ‡УћєРш0ŸеТТ9Z˜ЌŸЁjFt§К*(VT˜ХЯЂ_†6Ъ_PX‡‰Їg[ё^:K~Д?qKъ-dыэ:ЃгЗд2Ј8с‰H—OбR- Ч~I|эaam3b,uЅVMEdћЖЪ‡QУЌЉjXПZ эеХžў[{ѕЌјЌ’[@K)ьвоБЫ,,Хd›о5Š.[ Ц!цђ%ЄЯ!GrDёїžЫџV‹ф#[jЅ’`№‰зёSЕeФ+фФс*ќ;Jќ}…jШN…‘• ‰TЉsAсhЋбУtZa%Кй§yђ'аjDT­ЌxэVOљБKх‡ЁƒеŸ‚дБsfibW/еЦўёЛі§ЮЭК7a;tЯяг=>uDїўТ =\AСЙ~A7Џшйї|>vjˆъ–}–~ГЅcТ‘ QQбб 11 1†cџ^/ў;uјџЩХпC%ќя\J.фFJRХ•[мvќЭ@,Ум~FіЫQpVъtBhž\Т_E +.”pRD”(Ўˆ,щЄx\І”ђUЙ2ЪgеЊ(6–-+д/X0~rиџsž”R;Š13IENDЎB`‚debugger-master/resources/icons/stepinto.png0000644000175000017500000000043713560352104021172 0ustar shevekshevek‰PNG  IHDRэнтR pHYs ‰ ‰7ЩЫ­tIMEе-3Ч›k`tEXtCommentCreated with The GIMPяd%nPLTEхххъшу*Uaaa­­­Ь™™дџџџщЦФФtRNSv“Э8bKGDaˆыVIDATСБ У0 0BF3чA~ ШA.шдY‹§џ %йЛСС =R›є§hяЅЫZIљэo$хи"™>ЫH‘4Х„‘ЇHŠS$Х)’ћС{1г 1Љj;IENDЎB`‚debugger-master/resources/icons/runto.png0000644000175000017500000000037613560352104020476 0ustar shevekshevek‰PNG  IHDRэнтR pHYs ‰ ‰7ЩЫ­tIMEе6 ъс$tEXtCommentCreated with The GIMPяd%nPLTEххх*UaaaЊŸЊЬ3йŸЊџџџž‘B,tRNS@циfbKGDafИ}9IDAT[c`€W#ЪrqqqPd‹0 3*€д0 €`a(00‚PŒСЃ j2€ьЮSO.ЎЗIENDЎB`‚debugger-master/resources/icons/openMSX-debugger-logo-32.png0000644000175000017500000000433013560352104023614 0ustar shevekshevek‰PNG  IHDR szzє pHYs  šœtIMEж 18€­ tEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“Цо0nоМ91<<|ГNЇK]ЕjеiŸc6D&&&:gee)˜* /So_СдЛ73ѕІ žЮўЃ  Р&,,ьŒЛЛ{ќ|—№c6яGПАžќМoеpшp*ШTУЂХŸ>›`ГЋžр`ъЄэЄmЄЩ˜еџ OHH№ ;qџў}їššКшЈ˜ПеЌе}‡€ l<{f@CCƒЄЪЪJјњњТЮq І[@oOкдЈР*ІвMљЏсIII~‡ЧKњGqЩƒВйѓ1v|4ўRн oЉ/cc1гоLаa†c ДКtXŽЃˆы+˜ргЋг№ќќ|›§ћїЇјЩP[[_8lдоЇru0R^~-МIЁЁЁоƒІёмP‡YsЂЩФg{;m "2тduuеящљЫЄѓ3ЮfBоБоƒЁО]ЯŸ?‡——mбГfwЫŸ€яЖВŠqnЊсЅЅЅ)Ыwгs{HщЄALиТ„иђ]Л№&Qe 33-‡Н3%&ЗФЁCbЉQђ}дhРIšќП— ў8[ж)=‚FƒффdтЦањЦ‘O|;4А1`уЗД€5С5$у?S2СOЯu§њ;O:e@EzН—.]ТХ‹сЗс0˜НЙCЋWЏО@р‘Єётп&ъЕн)‹L{њЁКкаTRR‚рр`PЃj5П~§КV[рЖ‚Ж@i_РdнgДk€:\§О?ЉЇ4С­ыЮјЕ0эБUU­ ддд 00АЖЖ–ц ЮŸЯЦЦ€еИv%]‚‹ѓЃ?Ё,у]СL~[Ъd]нХел№їїєєє'…_2 %kа­ї:деНhe@„YZZ‚~[[[^8‹?ЦŒСх‘;—тbомб—!5ѕ˜ТŠр+Шр\(ГШˆХ-&уfЕ2чlooян<СiШ€\мж?jГххх g№еŸ–ЈЦНз‹­ёѕ‘iИUЂ†ўђ`Є3ЯF`7вв2р@ІІ’‰б LІв5ѓRRRŒц ^cF‰ј’qžШ8Vќк„ЃвХW‡Ь$ИЈяOщPtFEп•ˆ‹2AЯю Gx/$Эm„O#M cСd)Šђ›™дЭмh_5Ц\eТ8ЏŒ[АД6№—/_"(РЙўЯr'l ž‹Х.r Ц ЃэYЇ1С‘/{ќwwj„џ†ря€Щ‡“DЊ'D3nћо={eZ­іЯДЏSлр‘%†oтф P[ne Иј"NЅсяŒDТў,%ho’Љ)ƒnm_lГ^і№щ№qЄFИМ7Ф\гЪnj9йжvцJЦ}РИeрM—сьЙ+­ ФЧљK№{з'#q—’хrœ&јa 9N‹Wџ$UТбД|XYЛ|R#м‚РцFИЬ”р&ЂЏV щНв[>yЊїУ9ѓ|ЪњМНјЅœwСђ8u2YЧwрRIeћ|dgz"66 9™k‘~Р 9YˆЛЗP•Tсе‘‘qC‡;˜’Rж“ ]Ф§—*‰ДЄmcрнpf[0a’я‹%Ыж`ыж-ˆŒЧћ4TыZxxx ::yyyшь(Нv azг[З”K[JЧнtЉ удWX ѓh п‚Ю&TR šC№ў4ЏFDDD‡9PYљœ00ЋCИTjЛЫ?н–Мwяfкб[Ыћ‘F;›ЩЛє}Œc––Fї†ъ фцžЇgzvЪѕnE`аС-HO?;;ч_ћ9•” -|ІУR;шТ…ЎЯщNаЏSќQ#™|–г@ПoS‚^мК™Kс{мМиЙsљ˜>§L›6C† СŽ;ЅЋиы†xp‰7Ї№№ Ья{oŠмЊ?жўMЙooйл)‰мй{e*TшКVЂBбгЈ'Joг4\]]стт‚уЧгхЅЎќBA"ўš:…ч”— в:?пT5хѓ•ї+u}њ0yИ А.й'јšРЏъў-rГ ОО^‚ˆџ фффДШtЎ_ПŽSYЁа—vmzЎсеuШ˜ŠЖ} >–гО оЄЄЏ“Мёјё)ФMw„ЇOŸJWђнЛТ‘п­ўZ‰ам№Њ‘т B§АЁВQ­ ЬŸЋюП^ВI™ЂЬлЂМЖYy+|‹є™Зiƒ2eщ"хffъЭ‚а3Ц|аˆЌ1c­r ”ЭqТ!ъутџ“Hrѓ2 w7“%л•лтrп$ХsЉIмэŒTўч“|uN&_Г|™‰уŽдЫ Ѕ bIENDЎB`‚debugger-master/resources/icons/symmanager.png0000644000175000017500000000052013560352104021461 0ustar shevekshevek‰PNG  IHDRѓџa pHYs ‰ ‰7ЩЫ­tIMEж ˜#њCtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“ДIDAT8ЭSС Т0 LЬб?_fa€LЦПџФ [T2qф‹ЎЎ >DВ_ьЫйQR)%§b}ѓH—ДмІя ДXI>%jМУчœ›GСyМnтА‚Ѓе ˆ Р,^-OьFр=_q`ТrЬ/е†jsЕ“#&†"qDпВSА™шždА^ХчБё ‚>УГFђъ5Ax\БА…ˆ‰GјŸ з‰ў†юy6o? ,ьЖлВш{О<IENDЎB`‚debugger-master/resources/icons/openMSX-debugger-logo.xcf0000644000175000017500000047576513560352104023416 0ustar shevekshevekgimp xcf fileBBYS gimp-commentCreated with The GIMPgimp-image-grid(style intersections) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) ої"ˆJѕѓсz1ЭЫt8yЭ New Layerџ     QŒЈпыє$4DTdt„”ЄДФ J (§8<ќ‚ыD;њЋџŽ:єqџџАj7 5їaЙёёЙaЬџў;;ќ'Иш9§™шш9ўAшш9ќkшш:ў{ў:ћ &2ўшљ6ešО1ўші4c›Цксц4јB€Йиуцшш3јGФрхчшш1њ'wЦцшш0ћ =žкш ш-јNЗсчш ш,јд:rЩхчш ш,ћ5 Ючч ш+љoучш ш,ќ8žршш*њ#ЮЫХфшш(ј?фшцпмчшш&іџыццччхфчшш%ќџхшччћшцхчшш%јкчцччшшччш%ћчшччшш%ќУцчшш%љ&TwІЦошш&ѓ)Mr—Згфцччш ш'№ $CGKMPSW[^`_]R<%$-љ ќ $?Ьц%Hf‚˜­НЪдлпплдЪЗšuM%?p њQ†ДнррљЋ[)( ќ7РррњЯk=ќ$~ЭррћУK*ўЈр$рћŠ9р'рћЗ)7Œ(рћг= ƒїљрќDeм "3CP]gqx„‡‰Š‰‡ƒ|seTD4##$ррќ=Cж 8Wr‹ŸЋДЛТШЭвжйлнопонкигЬФКБЉ™{X1(%ррќв&ѕIs˜ГТЪбйопррѕндХЉ~@(. ррќЗћЫгкоррёогЛŽN$.рр $рђозК}E-23р\! &рѓобЌrB..fи!р 'рєпмЫ’L(!$”5 *рјкІX'D +рљнГa% рп#рјпмЖd  рп#рљпмЕb рпќрппр$рљмГ] рп'рљл­J/рљпгœ80рћпа" 1рћнРX2рћй 92рћпЮq3рћмЏH4рћж} рп"рћнЏM рпрћпг{ р п рпрћпЂ8"рпрќТi "рпрќй7рќЈљСЩЮдйнр0рќНGђ(@[tŒЃВКТЩбинр)рќа€ъ !5J^qƒ”ЁЊГМХЭенр!рћнВ*ф )9GVcq~Š“ІЏЗПЧЯжмпррћпЫƒз "-7AJT]flsx~ƒˆ‘šІЏДЙНСХШЬадзййеЛ€=$х(6KRUX\biow€ˆ‘œЇГМУЪЮвйфшцЯ‘T*€€@@r-footџ     šЖ"p"|"2BRbr‚ЇЗЧз„"5"`™ўџe™ўџe™ўeўп}ўх=ўџXшњџчпръ6ёI !*4;?.яQ-фццтнгЩМ­›‡,ј_% KЗЬш ш+љ+'Ёш ш*њ6Фшшўушш)ћ(Єш шўчшш(њCочшш'ќvшш'ќ Ѓчшшўцшш'§Щчшш%ќ‘чшш#ћ Ччшш#§1чшш"ќ'шчшш!ќ$шчшшћ ччшш§Ншшў}шшћ!шчшшќзчшш§hшшќ ччшш§bш ш§лш ш§:;ш!ш§Ÿш!ш§сш!шћRЁршшњ6i–Пцшш#ї$FdœЕЭушш+ы%8IZiw„‘œЇБЙСЩЯдкнсџўп}ўЬ=ўџXјрсџапрф6ёI  )29=.яQ ,нонкеЬУЕЇ–‚,ј_$ HБХр р,њ+&›р р*њ4Оррўлрр)ћ%žр рўпрр(њAепрр'ќqрр'ќ пррўорр'§Тпрр%ќŒпрр#ћ Рпрр#ў/рр"ќ%ппрр!ќ#ппррћ ппрр§Жрр§yпррћ рпррќЯпррќeпрр§ прр§^р р§гр рќ89пр р§™р!р§йр!рћOœиррњ4eЙорр#ї#C`|—ЏЦлрр+ы$6GVes€Œ—ЁЋГЛТШЭвжйџ3§ D3§ў0ќ /ќ -§  ў  ,ў ў  *ќ  )§  (§  ў  '§  &§  %§  #§  "ќ  "§  ! §  §   §  §   ў ў ў ў ! ў ! ќ  њ  #ї  ,їў}ў=ў=ўј  &5№1ЂњўўџќјюрЫЏŽ.ї‹мёьфэїџџ-јsьџяѓўџ џ+јHЦќіїќџ џ*њПї№ѕџџ)ћUџѕђџџ'љ„џфѕўџџ&њФџуќџџ%њ!џ№фњџџ$њ5џџшўџџ#њџќш§џџ"њыяч§џџ!ћєЯЯџџ њ№Зоќџџ ћйНДќџџћЇТЙѓџџћUх№џџћ џЃдџџћЕІжќџџћ.чˆјџџќПЉгџџћ-тињџџ§РОџ џќњЯџ џќ‚жѕџ џ§эќџ!џўџ#џќкѓџ!џћAџџўџџќGШџџќMЈџџ"њB~Чџџ'ї #Bi•Чљџџ/я "2CVh| ВСЯмш>@ќ@:(;іpW<(.5шѕтП™qF#0 шјЫ—b(- шљЭŽL*шљфœP 'шњлˆ2%шћЎP#шћРZ!шћОOшћЄ+шќqшќЋ" шћкJ "шќe#шќr#$шќo'%шќ[&ш§56&шќНa'шќxЎ*ш+ш+ш,ш,ш*шч'шњрЁY#"шњцП–i7шїуЭЕœdF$§фцччщцфснкдЯЩСЙБЇœ‘„wiZI8%$@ќ=8';іlT9',5рѕкЙ”mD"0 рјФ’^'- рљЦ‰I *рљм—N 'рњгƒ0%рћЈN#рћКW!рћЗLрћž*рќmрќІ! рћвH "рќb#рќn"$рќl&%рќX&р§34&рќЖ^'рќsЈ*р+р+р,р,р*рп'рњиœV""рњоЙe5рїлЦЏ—|`C#§моппщомйжвЭШТЛГЋЁ—Œ€seVG6$$@ў;љ6 і1 ћ0 ќ- ќ* ќ' §% §# §! § ў § §" ў# ќ$ ќ% ў& & ќ' ќ* + + , , * ' њ" њ ї ћ%@њiC" 9џњэЗt64џљўџТh!/џќПS,џћ§уf)џћўбG&џ§$џ§Ѓ"џ§ џ§sџ§ѕ0 џ§†!џ§к#џў)$џў:%џў;&џў)&џ§ў 'џўЮ(џўm)џў )џў{*џў*џўq+џў+џў:+џўш+џўn*џўA'џќШG$џќЈMџњЧ~BџїљЧ•iB# чяїћ§§ћїяшмЯСВ |hVC2" f ”ў;ў;ў;ў:ўs€€@@ mag-gripџ     #-#IJнJщ#•#Ѕ#Е#Х#е#х#ѕ$Ё%™%Љ21:ђ?|?ŒGЌJЁ­ ;  , . 3 s 8 5 4  3  3  3  2  ­‘;‘‘,‘.‘3‘s‘8 ‘5 ‘4‘‘3‘‘3‘‘3‘‘2‘‘Р 4 3 ; < ; < ; < < ; < < ; < ; < ; < ; ; < < ; < < < < ; (Р ‘4 ‘3 ‘;‘<‘;‘<‘;‘<‘<‘;‘<‘<‘;‘<‘;‘<‘;‘<‘;‘;‘<‘<‘;‘<‘<‘<‘<‘;‘(&ј(љ  ќў   ў  њ§  ќ  § ѓњ   §јў   § ќќќў   ќў§   ї   § ў   ќ ўљ§   ў  ќ ќў  ќ  ќќў  ў   ќ §ў§ћ   ў §ќў   ў ўќ  љ   њўўї   §ћ  § ў  § §ћ  § њў  ў  ќ§ћў  ў§ §  § ўўћў  §ї§§ў  ќїњћ   њњќў  §§ћћќ јўњ  §§ў§ў§ќїўћўўў§ў§њўњњўў§ў§ћќћ ўќў  ѕ !!  ќ $рAH9Nvƒ€}{yxutrpnljhfdb`TB.йJŒ‰‡…ƒ‚€~|zxvtrpnljhgeba_][YWL0еZŽ‘ŽŒŠˆ†„‚€|zyvusqomkhgecb`]\YWVTRPN;д}ސŽŒ‹‰†…ƒ|{ywusqonkjgfcb`^\ZXWTRPNLJH?дQ‘‹‰‡…ƒ~{zwvtronljhfdca^]ZXWUSQNMKIGEг}‘‹Šˆ†„‚€~|zyvtrqolkigdca_][YWVSQONKJGFDг7ސŽŒŠˆ†„‚€~}zxwusqomkiheca`^\ZXVTRPNLJHFDCв ŽŠˆ†„ƒ}{yxvsronligedb`^\ZXVTRPOMJIGECAв ‘Œ‰‡†ƒ‚€}|zxutrpnmjifdca_][YWUSQOMKIGEDB?в‘ŽŒŠˆ†„‚€}zxwtrqnmkigeca_][YXUTRPNLJHFDB@?в'‘ŽŠˆ†„ƒ}{ywusqomkigeca_^\ZXVTSPNLJIFDC@><в7‹‰‡†ƒ€~|zwutronljhfdba_][XWTRQNMKIGECA?=;б\ŽŒ‰‡…„~|zxvtrpoljhgec`^][YWUSQPNKJHEDB@=<:бfŒŠˆ†…‚€|zywurqomkigedb_][YWVTRPNLJHFDBA?=;8бfŠˆ‡…‚}|ywvsqonkjgeda`^\ZXVUSQOLJIGECA?=;97б}‰ˆ…ƒ~|zwvtrpnljhfdba^]ZXWURQOMKIGECA?>;986бЇ…„‚€~|{xwtspnlkigeca_][YWUSQOMLIHFDB@>=:874б ‰†…‚€}{ywtsqomkigecb`^[ZXVTRPNLJHFDB@?<;9753б ‡…ƒ}{ywvtqpnljgfdb`^\[XVTRQOMJIGECA?=;97542б †„€~{zxvtrpnljifdba_][YWUSQOMKJGFCA@><:76420бv‚€~|{ywuspnlkigeca`][YWUTRPNKJHFDB@><:86521/б^~}{ywutqomkjhedb_^\ZXVTRPNLKHGEB@?<;97531/-в<€~|ywusrpmljhfeb`^][YVURQOLKIGECA?=;:86420.,в"~|zxwtrpoljifec`^][YWVSQONKIGEDB@>;:86420.,*вu{yvusqomkigecb`]\ZXVTQPNLJHFDBA><:97421/,+)вTywvsqpmljhfdb`^]ZXVURQOLJIGEBA?=;986320.+*'г1xvtrpnljhgeba^\ZXWUSQOMKIHEDA?=<:76420.,*)&гvtrqnmjigeca_][YWVSRONLJHEDB@><:86531/-+)&%дKsromkihfcb`]\YXVTRPNLJIGDCA?=;87531/-+)'&#д#qpnljhfdb`^\ZXVUSQOMKIGECA@=<:7532/.,)(&$"дInljhgdc`_][YWUSQOMKIGEDB@=;:86421.-*(&$#!е"mkigeca_][ZWVTRPMLIHFDB@><;97531/-+)'%#!е Mihfdb`^\ZXVURPNMKIFEC@?=;975310.+*'%#! жhfeb`_\ZYWTSQOMKIGECA?=<:86320.,*(&$" зgeca_][YWUTQONLJHFDB?><:86420.,*(&%#!Єќ/@@ў?@@ќ%§*@@ћGuШўџџўџіўсЬŸqЁrћ /ZДџџіѓ§џџс‘dHќ‘тџ џћўтЖD§Бџ&џ§ џ(џ§Дџ)џў#џ*џўfџ*џ§тџ*џў4џ+џ§uџ+џ§%хџ+џў џ,џў-џ,џўPџ,џў€џ,џўЖџ,џўтџ,џ.џў џ-џўџ-џўџ-џ§Еџ,џўDџ,џўџ,џўџ,џ§Еџ+џўDџ+џ§тџ*џў’џ*џў/џ*џ+џў‡џ)џўџ)џ*џ§џ(џў"џ(џ,  2  4  5 ў  6 7 9 ; ; : 9 6 9 = \§ 6 § 1 ќ  .  §  *  љ  %  ў   ў  ў  ў    ў   ў   ў ў   ќ   ќ    ќ                    ў     ќ   ў   ќ ! ќ § " ќў " ћ " §ў " ќ " ўў " ў§ " ќќ " ў " њ§ " ўќ " ўї  ќў   ў       ќ   ў    ћ њ         §§    ќ    §   ў њ   §      ўќ  ќ ! ќ § " ќў " §ў§ " ,‘‘2‘‘4‘‘5‘ў‘‘6‘7‘9‘;‘;‘:‘9 ‘6‘9‘=‘\§‘6‘§‘1‘ќ‘‘‘.‘§‘‘‘* ‘љ‘‘‘‘‘% ‘ў‘‘ў‘‘ў‘ ‘ ў‘‘ ў‘ ‘ў‘‘ў ў‘ ‘ќ‘ ‘ќ‘‘‘ ‘ќ‘‘‘ ‘‘ ‘‘‘‘ ‘‘‘ ‘‘ў‘‘ ‘‘ќ‘‘ ‘ ‘ќ'‘ ‘њDA. ‘!і‘B@><:(‘"і@><;974$  ‘"є?=;:7532/ ‘"ѓ>;976420.,* ‘"ђ=:96431/-*(' ‘"ё;87532/-,)(&$ ‘"№:75320.,*(&$"! ‘"я86420.,+(&%"! ‘"ю7531.-+)'%#!‘"ю532/.+*(%$! ‘"э42/.,*(&%# ‘"э21/,+('%#!‘ ‘э0/-+)(&#" ‘‘э/.,*(&$"  ‘‘э.,+)&$"! ‘‘ь-+)'%#! ‘‘ы+)'&$"  ‘‘ы*(&$"! ‘‘э('$#! ‘‘э'%$! ‘‘ю&$"  ‘‘я$#  ‘‘ю"! ‘‘я!  ‘‘№   ‘‘№  ‘ ‘№  ‘!№‘  ‘"ђ  ‘"ѓ  ‘"@§<ћџ H:џћў,8џћД%5џќ3 џ§ 2 џќтU0 џ§‡/ џў /џўK.џ/џў5-џ§Д,џў,џўm,џ§т+џў++џћ(џћЖ(џ§т*џў@*џў-*џў *џў*џ,џў *џў*џ§т*џ§тB+џўЭ,џўŽ,џўI,џ§`,џ§x- џ§ . ; ; : 9 9 9 8 7 5 . 0 2 5 О < : 9 8 4 1 1 5 6 $ў  #ў  "  !  ! §   !§  ў   ћ          њ        ќ    ќ  ў     ў  §    ќ ћ   њ  ќ    ћ    љ    ў                    ў       ў    ў   ќ  !   "    " ў   $   % &ў  (  +ќ 0‘;‘;‘:‘9‘9‘9‘8‘7‘5‘.‘0 ‘2 ‘5‘О‘<‘:‘9‘8 ‘4‘1‘1‘5 ‘6 ‘$ў‘‘#ў‘‘"‘‘!‘‘!§‘‘‘!§‘ ў‘‘ ћ‘‘‘‘‘ ‘‘‘‘ њ‘‘‘‘‘‘‘ќ‘‘‘‘ќ‘‘‘ў‘‘‘ў‘‘§‘‘‘ќ‘‘ћ‘‘‘‘њ‘‘‘‘ќ‘‘‘‘ћ‘‘‘‘‘љ‘‘‘‘ ‘‘ў‘‘‘ ‘‘‘‘ ‘‘‘‘‘‘‘‘ў‘ ‘ ‘ ў‘‘‘ў ‘ ќ‘‘ ‘!‘ ‘"‘‘ ‘"‘ў‘‘ ‘$‘ ‘%‘&ў‘‘(‘+ќ‘‘ ‘0јњ§§ўќўќўїў§ўќќ§ќўќў§§§єљћў§ќў§ўўњўў § §§ў §ќ§јў ў§њў ќ ў§ §§ §ќўўў §§ћ§§ўњўў§љ§"ќјў#њќ§§%ўњњў'§01ў§25ў зAda`]\ZWVSRPNLJIFDB@><;86531/-+)'%#! зW`^\ZYVTRQOMKHGDCA?=;:85420.+)(&$" зO^\[YWUSQOMKIGFDA@><:86420.,+(&$# зT][ZWUSRPNLJHFDB@>=:87520/-+('%#!з$\[YXVTRPNMKIFDCA?=;97531/-+)'&#" и8[YWTSPOMKIGECA?>;98632/-,*(&$" иYWUSQONLJGEDB@><:86521.,+)'%#! л>UTRPMLJHGDB@>=:97521/-+)'%#"мTRQNMKIFECA?=;97541/.+)'%$"  мIQOMKIGEDA?><986420.,*(&$" п"ONKJHECA@><:97421/,*)&%#!рELJIGDB@><:87531/.+)(%#!ўу+KHFECA?=;985310-,)(&$" у AGFCB?><:86420.-*(&%"!х(FDB@><:97520.,+)&%#!хEC@><;875310.+*'%#" ўŽч0A?>;986420-,*(&$" ўŽч @><:87531/-*(&%#!Žўш,<;96521/-+)'&#!§Ž§Ž‘ш497531/.,*(%$" љŽŽъ86420.,*(&$# њŽŽ‹!ы421.-+)&%#! ќŽ$ь1/-+*'&#! §ˆ&э-,*(&$"!ўŒ)ю *('$#!ўU*я "%#!/я  0ѕ6бў џ(џ)џўOџ'џ§§џ&џўЌџ&џ§Cёџ%џ§Еџ%џ§Dјџ$џ§ тџ$џўmџ#џўў§тџ!џ§њˆў’џ џ§яqў/џџ§ЙGўЕџџўqў5џџў™ўўЕџџ!ўDџџўЭ §ЕџџўZўўDџџўТў§Шџџў†#§7тџџ§љZ$ўUџџ§љ/%ў‡џџќўк%ќGћџџ§ўЬ'ќ‡ўџџўц)ўjџџўб*§Uтџџ§ю™+ќ"žћџ џћ§џљС-§5Еџџўўџџ§њq/ќ/’тџџњўќћуq2і<‘рќќц‹9§ ! ќ  ! њ ў ќ   љ   ќ    ќ         ў  ў    ўў  ќ  ћ ћ  ќ  §  ќ  ќ  § §  ї § і ў  ў  2 §  Ÿѓ  ‘!ѓ‘  ‘!ѓ‘  ‘ ѓ‘  ‘ђ‘‘ ‘є‘  ‘‘ј‘‘  ‘‘ ‘‘ ‘ў‘ў‘ ‘‘ ќŽ ‘ќ‘‘ ў§Œˆ ‘ ћ‘‘ Ž‹ ‘ ‘§‘њŽ‰s ‘ќ‘‘‘§‘ћŽ‹m ‘ї‘‘‘‘ћŒx ‘і‘‘‘‘§Ž‡‘ў‘ў‘§‘ Ÿ џў+/ џ§Ш / џў10 џќЕ.0 џў52 џ§  2џ§`3џ§`4џ§…5їџлЙЈyYY6§/Н§О§;§ <ў ~ћ :§ <ў =ў >ћ‘‘‘:§‘<ў‘=ў‘>€€@@magџ     aK•KБѓЩѓеK§hty. PЏ О"О2ЦNткфmф}фыЌѓЙќћ№яээ6їѓђё№яэьы3ѕіѓђ№№югЃwM0ёјіѕєѓђп f0.јёїѕєд‹F%7F+њюјїїш•E "=Thjhf)ъќњњљїПd )Jiwurpnki'ь§ќћњјЅC Kq€~|ywt)юў§ћћљœ3 8hЇ…ƒ,№ўќћћЃ1 I‘ŒŠў$№џўќћЛA Q˜–”‘ќ3K!ўєќфbP—Ÿ›џњv{yvџє§ќ–B‘ЇЄЂџјнЖ•€~|yѓџўўкM&ЎЋЊџјК†„}єџў§ _ЕГБџјЗŒŠ‡„џѕў§e-–КИЖџїыВŒŠ‡…‚џіўб6]ТРН џінКЂ’‹ˆ†џіўЋ ‰ЧФТ џіУ—•“Šˆџїў‹4ВЬЩ џѕјР›˜•“‹џїўtTгбЮ џєљчН ›™–“‘Žџї§bnиег џєсФАЄЁž›™–”‘џј§W„нкџєбЎЉІЄЁžœ™–”џј§T”тпџєаЎЌЊЇЄЂŸœšoіџў§WŸчхџєіЯБЏЌЉЇЅЁ}0џј§aЃьщџѕэзУЕВЏ­Њ”Aіџў§s ёюџіоСКЗДВЏ\іџў§Š–ѕѓџјнПМКИƒ#їў§Њ„њјџњоУРКOїў§а iџ§џљіъжХŠїў§ќ5FљќџћьйЯ^їўќќeлїџќщД2ќљœ­ђєџ§Е їќћи yэ№џўуїќћњMAщыџўи ў јћњ•Пцџў їћњтруџ§# їћњљa;моџ§ 3 јљјИЈйџќIїљјїA_дзџќ-nјјї РбџќF“јјіѕ2oЬџћ&XЅјїіšШЪџћ 6nДјіѕє2 rФџњU›бјієЃПТџњ%tХьљєѓB hНџљ1„жѕјєѓМ ­ЛџљB’ојљѓёb SЕџљ 2iЎъќђњф ‘ГџљKЩѓџјё№’ 4­АџјXЄзљџљ№яE kЌџјdВсќџј№яЯ Љџї )rОчўџљяэˆ>Єџї=„ЩэўџљюьEjЁџї(\ оіџџјэьй’žџї7xЛ№џўџљьы4™џї=ƒЦњџўџљыъdW—џїA‰Ьўџўўљщш0u” џїK’а§џўџјщшЭ‘ џіZžдњџўџљшчž6Œ џі2uЙућџўџљцхtM‰ џіDŽдёќџўџљцхLb‡ џїK›фњ§џўџќя§эь6їєђё№юэьы3єѕєєђ№яядЂvM0ёјіѕєѓђп f0.яљїіѕєг‹E%8F+ьћљљјїш•E "=Thkif)ъќњљљїПd *Jivurpnli'ш§ќћњјЅC Kr€~|zwu%юў§ћћњœ2 7hŠˆ…ƒўў $№ў§ћњЃ1 H€’ŽŒŠќ "№џўќћЛA Q™–”‘ўќ";Q!ђў§§фbP— ž›џњ„y}zђџў§ќ–B‘ЇЅЃџјнȘƒ‚€}ѓџў§кN&€ЎЌЊџјМ’‰‡…ƒєџў§ _ЖГБџјЙ‹ˆ…ƒџі§e-–КИЕџїьД“Ž‹‰†џіўб5]СПН џіоМЅ•’‘ŒŠџіўЊ ‰ЧХТ џіХ š˜–“‹џїў‹4ВЬЩ џѕљТ ž›˜–“Žџї§tTваЮ џєљчПЂ žœ™–”‘џїўanзжг џєтЦВЇЄЁžœ™—”џјўW„мкџєвБЋЈЇЃЁŸœ™—іџўўT”срџєвАЎЌЊІЄЂŸsџј§WŸцфџѓїбГБЎЋЉЇЃ6іџў§aЃыщџѕэиХЗДБЏЌ—F  іџў§s ёяџѕпУМЙЖДБa   іџў§‹–ѕѓџјоСОМК†) їў§Њ…њјџњпФТМUїў§Я iў§џјіъзЧŽ$ њ  їў§ќ5Eљќџњэкаc ќ  §љћeмїџњъЗ8 ў ќ  їќћœ­ђѕџњЗ ў їќћи yэ№џќф  ў ў їќћњMBщъџћй  ќ јћњ”Пхџў  њ  їћњт~ртџљ ќ * њљјa;моџў і  : јњјИЈйџў њ OїљјїA^дзџћ ў њ3sјјі Рбџ§  і !K–јјїі1oЬџќ  ј ,]ЇјіѕšШЪџўў § ћ=sЖјіѕє2rХџњ   ј [žгјѕєЃРТџў є ,yЧэљєѓC gОџў ј 7ˆзіјєѓМ ­Лџ§ћ ј G•пјљѓђb RЕџ§ ј8mАъќђњф Вџю  P’Ъѓџјё№’ 4­Аџ ѕ  ]Їиљџљ№яDkЋџ њ і !hДтќџј№яЯ Љџ §   і /vПшўџљяюˆ>Ѓџ ў ђ  C‡ЪэўџљюьFjЁџ ў ѓ  .aЃоіџџјэьй’žџ ўћ ѕ =|Н№џўџљьы4™џ ю  B‡ШњџўџљъщeW–џ ќ і FŒЭўџўўљъш0u” џ  №P•б§џўџјщшЭ‘ џ ь  $_Ёжњџўџљшчž6 џ ћ ѓ 8yЛућџўџцћsNŠ џ ђ  I‘еђќџўџљхфLc‡ џ ѕ"Pфњ§џўџќћ№ююь6їєђ№№юээы3єѕєѓђё№ягЂvM0їѓѕєѓёп f0.яјїіѕєд‹F&8F+ьћњјїіш•D "=Thkhf)ъќћљјјПd )Kiwurpnli'ш§ќњњјІC Kq€~{zwust~%юў§ќњљ3 8hЇ…ƒњ\hx~ƒ$№ў§ћњЃ1 I€‘ŽŠњgk|ˆ‰"№џўќќЛA Q™–”‘ўqњrtŒ Ќ!ўє§фcP—Ÿ›џњНИОППђџў§ќ–B‘ЇЄЂџјъеШРССПџѕ§лN&ЎЌЉџјзРРХФТСєџў§ _ЕГАџјиТФЧХУТџѕў§f-–КИЖџїѓиШЧЧЦФУџіўб6^ТПН џіыиЯЪЪЩЧЦХџіўЋ ‰ЦФТ џінШЩЬЬЪШЦХџїў‹4ВЫЩ џѕћнЫЭЮЭЫЩШЧѕџўўtTгбЯ џєњ№оааЯЮЬЪЩШџїўanзег џєэнжгваЮЭЬЪЩџјўX„млџєхввдгбаЮЭЫЪџјўT”трџєцдеждгбаЮЭИџј§WŸцфџѓњчиижедгаП™‚іџў§aЂыщџђєшрлкизеЪЂ‚іџў§s ёюџ§ьмллїйиЏ„‚€€іџў§Š–ѕѓџђьммнмТ”ƒ‚€€їў§Њ…њјџіюппнЉ‚ƒ‚€€§ља iў§џєљђщтХƒƒ‚‚€€ў§љќ5FљќџієщхА„‚ƒ‚€€§~ їў§ћeмїџіѓе”ƒ„‚‚€€ќ~} ї§ќœ­ђѕџ№зy|‚ƒ€€€~}| їќћи zэ№џяэz|‚‚€€~~}| їќћњMBшъџђхh|‚€€€~~}}ў јћњ”Пхџљhmz‚ƒ€€ј~~}{}† њљтсуџѕmoy‚€€~~ћ}{}Ž їћњјb;лоџїrsz€€€~~}ќ|€– јљјИЇйџwј|€~~}}|ќ~†ЁїњјїA^джџњ*gy|~ў~}}њ{|‚’Гјјі Рбџєbiy€~~}}||њz{ˆžЦјјіі2oЬџїjmx€€~~}}|њz}ŽЇЯјїѕ›ЧЩџіnpw€~~}}||{ћ€–Взјіѕє2rХџіqry€~}}||{њ|†ІЪцјієЃ РТџuњz~~}||ї{zz~ŒЖрѕљєѓB gНџћ`yz|~~ў}||ї{y{’ОщњјєѓН ­Лџі*g{}~}}||{{їzy{†›Хэћљђёb RЕџљgly~~}||{zјy~“Џдє§ђњф Гџјkmv}~||{{ўzyyљ€ŸУтјџјё№’ 5­Аџјmov}~||{{ўzyyљ‚ІЮщћџљ№яDkЋџ єpqv|}||{{zzyyјz…Ќеюќџј№юЯ Јџ ъrsw|}||{{zyyxz~Глёўџљяэˆ>Ѓџ uьy{|{{zzyyxwy„—НсѕўџэћFkЁџ їcxyz{|{zyyxіuyŒЈЬьњџџэњй‘žџ іИЛОРФЦШЫЮбгжилнпз+ўџџўщџџэŽЖЙЛОСУХШЫЭЯгеикнC§ …џџўaџџэ=БГЖИЛОПУХЧЪЭавез^ќ&”џџўРџџю…­АГЕЗКМРТХЧЪЬЯв|ќ0rПџџў.џџю/ЈЊ­АВЕЗКНПТФЧЪЬžќ\Рыџџў‡џџюoЅЇЊЌЏБДЗКМОСФЧТ!§qцџџўмџџюŸЂЄЇЉ­ЏВДЗЙМОСФJ§|њџџў<џџяOœŸЁЄІЉЌЏБГЖЙМНu ў~џџўŠџџя‚™œžЁЃІЈЋ­АГЕИЃ ўџџўеџџя&”–™œž ЃІЉЋ­АВЖ: § †џџў'џџ№T‘“–˜›ž ЃЅЈЋ­Аl ќ)–џџўkџџ№}Ž‘“–˜› ЃЅЇЊŸ ќ+hКџџўЌџџ№‰‹“•—šŸЂЅЇD ќPЋпџџўщџџёC…ˆŠ’•—šœŸЁ{ ќfдіџџў+џџёc‚…ˆŠŒ‘”–™œŸ) §uюџџўaџџё}‚…†ŠŒ‘”–™d §|њџџў”џџё#y|„†‰ŒŽ‘”— §~ўџџўФџџђ;wy{~ƒ†‰‹Ž‘V ўџџыщщшчцхутсрпомлкйзжедгвб%сыъщшцхфутсрпнммкйзжедгвааЯЭЬЫЪ нъжŘiWG:0)&$%)/8CO]n€”ЉРЮЬЫЪШШЦХУк)!!#$&&')*,-.01234B^z—ЗЦХФУССПз$-5;?CDEDDB@=;963110/02789:;Pq”ЖСПОНМЛеS]][XVTQOMKHFCB?=;8641/,+()+06>?@Ab‡­МКЙИЗвdb_][XVTQPMKHFDA@=;86410-+(&$" '0;DFGd‹ВЗЖЕДВўfш0.+)&$",;JJMuœГВБАЏ&х+E^u'%" -CNOhЏЎ­­Ћ"с 6\ƒžГТЮлч !:RSdŒЌЋЉЈЈ ї$1;CIMPPзNKGB<4-'%*5IjšЧфѕћћ§ўџўџ3SVgЈЈІЅ у`nlifca_\YWUROLJGDCM]v‘ЊОдщљџџя1U[n“ЅЄЃЂсtqnlifda_\YWUROMJLRgƒЈЬтёјњ§ўџўўяџў 5]_yЁЁŸчvtqoljgdb_]ZWURQVez˜Игщїџџўџ№ў ?ae‡Ÿžœхywuroljheb`][XW_mˆЈЪчєљќўџўў№џў !Qev•›š™щ}zxusomkheba^_i›Еачљўџџ ўџђў 4gj‡™˜—ч}zxurpnkhfcboƒЅЩоыї§џўџўўёџ Rk}—••“ыƒ€}{xuspnkiiq‰›Кмяљўџџўџл ;mv“’‘…ƒ€~{yvtqnlWTvАкѕў§ўўџўўпџў &gr‡Žˆ†ƒ~|ywW/9lЇлѓўџџўџсў Wt‚ŽŒŒ‰†„vD+eЄеїџўџў!ўцџ Hv‹‹Œ‰m5 -[™в№џџ!ўџѓ ўўџў=ўўџў=ўўџў=ўўџў=ўўџў=ўўџўНўчьъщшчцффусрпомллйижеддвб%сыъщшццфутсрпнммкиижедгббаЮЭЬЫЪ нъеŘiWG:0)&$%*08CO^n€”ЉРЭЬЫЩЩЧЧЦФк(!"#$%'()*,,./1134B^z˜ЖЧХФУССПз$-5;?BDEEDB@=;96411/003789:;Pr”ЖРПОНЛКеS]][XUTROMJHFDB?<:8632/,*(),06>?@Bb‡ЌМЛЙИЗвdb`][YWTRPMJHFDB@=;9742/-+(&$! '0;DFFd‹ВЗЖДГВўg    ў  т 0-,)&%" ,;IJNuГВБАЎ§  ѕ    т2Kcy'$" .CNOhЏЏЎ­Ћ     к  %=a†ЁЕФЯмш!!:RTdŒЌЋЊЈЈ Ы +7AIPSVUUSQMIB:3.,1;OoШфѕћћ§ўџўџ4SWgЈЈЇЅ уesqnkhfda^\[XUROLIJScz•ЌПещјџџя1U[n“ЅЄЃЁсxurqnkheda^\[XTRQRWl‡ЋЭуёјњ§ўџўўяџў 5]_zЂ Ÿцzxutqokhfdb_\YVW]j›Леъїўџџўџ№ў ?ae‡Ÿœ›х}{yvtqnlifdb`]]dsŒЋЬшєљќўџўў№џў !Pdw•›š™ш~|ywtqpmjfdben„žИбшљўўџџ ўџђў 4gj‡™˜–чƒ~|yvtspmjght‡ЈЪоыї§џўџўўёџ Rk}—•”“ы†„|ywusommuŽžЛмяјўџџўџл ;nvŽ“’‘ˆ†ƒ‚}zxvqq]ZzВлѕў§ўўџўўпџў &hr‡Ž‹‰†…‚€}{\6@qЊлѓўџџўџсў WtƒŽŒŒ‰‡„zJ 2jЇжїџўџў!ўцџ HvŒŠ’Œq; 3aœгёџџ!ўџц ўўџў=ўўџў=ўўџў=ўўџў=ўўџў=ўўџўНўчыъщшццфутсрпонлкйззждгвб%сьъщшцххутсрпомлкйзжедгвбЯЯЭЬЫЪ нъеЖ™iVG:1)&$%)08BO^n€”ЉРЮЬЫЪЩШЦХФк( "#$%'')*+,./0234B^z—ЖЦХУУССПз$-5;@BDEEDB@=<96311//03789;;Pr•ЗРПОММКеS]\[XVTQOLKHFCB?=:8531/,+()+06>?ABb‡­МКЙИЗвdb`][YVTROMKHGDA?=;8742/-+('$! '0;EFGd‹ВЗЕДГВўf‰‰ˆ‡†…„фƒ‚‚0-+)'%"+;JKNuœГВБАЏћˆŠˆˆ‡‡ќˆ‡†……„ƒ‚х…Š•ЂЏК'%# .CNPhАЏ­­Ќ ќˆ‰ˆ‡‡ў†……ў„ƒƒп‚ƒ„ˆ›ЎСЮйрцьѓ "9QSeŒЌЋЊЉЇ Ы‡‰‘—ЁЅЈЉЋЊЊЈЈІЃŸ›˜•”–›ЄДЬтёљќќўўџўџ4RWgЉЈІЅ уДКЙИЗДДВБЎ­ЌЊЉЇІЄЁЂЈЏЛШдощѓћџџя1U[o“ЅЄЃЂсНМКЙЗЖДГБАЎ­ЋЊЈЇЅІЈГСгф№їћћ§ўџўўяџў 5]^zœЂЁŸНщЛКИЗЖДГБАЎЌЋЉЉЋВМЫлщѓњџџўџ№ў >`e‡ŸžœхОНМЛЙИЗЖДВБЏЎ­ЌАЗФгфђљћ§ўџўў№џў !Qew•œš™шРПОМЛЙИЗЕДВАЏАДРЭкчѓћўўџџ ўџђў 4gjˆ™——СщПОМКЙИЖДДББЗСвуэєњ§џўџўўёџ Rj}—–”“ыУТРПНЛКИЗЕДЕИФЭлэіћўџџўџл ;mw“’ФУСРОНЛКИЖЖЋЉКзьљў§ўўџўўпџў &gr‡‘ŽХФТСПОНЛЋ˜ŒœЕвьљўџџўџсў Vt‚ŽŒЧХУТРЛЂ‹‚ˆ•Ващњџўџў!ўцџ HvŒŠШЧХЖ›€€†–­Ычїџџ ўџђ ўўџў=ўўџў=ўўџў=ўўџў=ўўџў=ўўџўНўчCeƒžЖЫмщєњўўњєщмЫЖžƒeC%ў№џџњ№Ф”a+ џћщЌk'!џќеŠ<$џќм‡.'џ§Рa)џќщƒїџЦалхэѕћџ џњћѕэхлџџ§”$.џ§” џ§ѕсџ џќўƒ 1џ§тa $џўњџ џ§Ж.5џўy)џўѕџ џ§Н+7џ§њe-џўѕџ џў˜:џ§Ф$0џўћџџћщFџ<џ§aџ=џўvџјџўўџ …џ€ў‰=§ˆ‡<ќ‡†…;ћ…ƒ‚:њ€ƒ€9љ+‚‚€}8ј0…‚}|{7ї 8ˆ{zx6ї DŠxw6і S‹zvu5ѕў g‰utr4џі €…rqp3єўџ /“~pn3ѓўџџ M“tnl2ўѕџ oŠmkj1ўѕџў"–}ji1ўєџўJ˜mhf0ўѓџўџwˆfed/ўѕџў/Ÿtdb/ўєџўa‘ca`.ўіџšy`_.ўџїV˜_]]-ўѕџў•x\[-ўєџўџTš[ZX,ўіџ šuXX,ўџј!^—WV,ўѕџў# $ЉjUT+ўѕџўџ#!qŒTS+ ўіџ&$":АVQP* ўіџ)&$"ŽxPN* ўіџў)'%\›ON* ўѕџў+)'-З[LK) ўїџ,*'‰|KJ) ўїџ.,*\žJI) ўіџ2/-3МQGF( ўіџў1/-—qFE(ўј420rEC( ўіџў743PЏCC( ўѕџў9752КQA@' ўѕџўџ;86šm@?'ўїџ<:8~‡?='ўїџ?=;dЂ=<'€ў‰=§‰‡<ќ‡†„;ћ…„‚:њ€‚€9љ,‚‚€~}8ј0…‚}|{7ї 7‡{zx6ї C‰~yw6і T‹zvt5ѕў h‰ttr4џі €„rqp3єўџ /’~po3ѓўџџ M“tnl2ўѕџ p‹llj1ўѕџў#—}ji1ўєџўJ™mhg0ўѓџўџxˆfed/ўѕџў/Ÿtdc/ўєџўb‘cba.ўіџšx`_.ўџїV˜_^]-ўѕџў–y][-ўєџўџU™[ZY,ўіџ šuYX,ўџј ^—XV,ўѕџў#!$ЉjUT+ўѕџўџ#!pŒTS+ ўіџ&#";АVQP* ўіџ)'$!ŽxPO* ўіџў)'$\›NN* ўѕџў,*'-Ж[LK) ўїџ,*'ˆ}KJ) ўїџ/,*\žJI) ўіџ2/,3МRGG( ўіџў20-—pFE(ўј530rED( ўіџў752OЏCB( ўѕџў:753КQA@' ўѕџўџ:86šm@?'ўїџ=;9~‡?>'ўїџ@=;cЂ><'€ў‰=§ˆ‡<ќ‡†…;ћ€„„‚:њ‚€9љ+‚‚€~8ј0…‚}|{7ї 8‡zzx6ї CŠ~yx6і T‹zvu5ѕў h‰utr4џі €…rqp3єўџ /“}po3ѓўџџ M“tnl2ўѕџ o‹lki1ўѕџў"—}ji1ўєџўJ˜mhf0ўѓџўџw‰fec/ўѕџў/Ÿtcb/ўєџўb‘ca`.ўіџšx`_.ўџїV™_^\-ўѕџў–x][-ўєџўџT™[ZY,ўіџ šuYW,ўџј ^—XV,ўѕџў#!$ЉjUS+ўѕџўџ$!pŒTS+ ўіџ&$":АVQP* ўіџ(&$!ŽyPO* ўіџў)&$\›ON* ўѕџў+)'-З[MK) ўїџ,)(ˆ|KJ) ўїџ.,*]žJH) ўіџ2/-4МQGF( ўіџў2/-–qFE(ўј520rEC( ўіџў752OЎCC( ўѕџў9753ЙQA@' ўѕџўџ:86šm@>'ўїџ=:8}‡?>'ўїџ@=;cЂ><'€ўƒ=§џŠ<џўŠ;џўƒ:џўv9џўa8џўF7џ§щ$6џўФ6џў˜5џўe4џ§њ+3 џўН3 џўy2 џў.1 џўЖ1 џўa0џўўџџ§т/ џўƒ/ џ§ў.џў”.џў$-џў”-џў,џўƒ,џўщ,џўa+џўР+џў.*џў‡*џўм*џў<)џўŠ)џўе)џў'(џўk(џўЌ(џўщ(џў+'џўa'џў”'џўФ'љфу(t„ џэMЁьџ§џўџфуЯ џэLЁюџўџўџутА/} џэL ьџўџўўср”=z џэ%TЃыўџџўўрп|Gw џэ /bЋъ§ўџўўпоfQt џэ9{Кэ§ўџўўннUWr џюE•Ы№§ўџўўнмF!\o џюRЎмѕўўџўўлк:"_m џ ю]Сщљџўџўўкй0"`j џ юaШя§џўџўўйз+$agџ!њaШ№ўџўўљиз'&adџ!њ_Хюџџўўљзе%&^bџ ўЧ§§ њ\Рьўџўўљед'(\`џ"њZНщўџўўљдг+)Y\џ"њXЙшўџўўљвб0*TZџ"њWИчџџўўљба9+QWџ"њWЗцўџўўљаЯB-MUџ#юWЗцўџўџўўЯЮN.HRџ#юWЗхќџўџўўЮЬ\/DOџ#юYКцћџўџўўЬЪk0@Mџ#ю[НчљџўџўўЪЩ|2=Jџ$ю]ТъљџўџўўЩШŽ3:Hџ$юaШэљџўџўўЩЧЂ47Dџ$юfбђњџўџўўЧЦЗ57Bџ$іjйїњџўџўўљФУB8?Aџ$іoтќћўўџўўљУТ\9+џ%і(bЎяџўџўўљДГЃHI**іQЁш§ўџўўљВБcK5()і RсљџџўўљБА†KB&)і!R˜зѓўџўўјЏЎЈNO+%(і;„Эяўџўџљ­ЋrP<#(і!oРщ§џўџљЋЊ•QP#(іcВрќџўџљЉЈhS7 'іZЂжљџўџљЈЇŠUN'іM’ЬїџўџјЇЅЄdW4'ї AСѓџўџљЅЃ…XR'ї4pЖ№џўџјЃЂ f[7&ї)`ЌэџўџљЁŸ‡\Z'ј#WЅыўџџјŸžl_?&јQ чќўџ ј›Š`a%%јOфћџџ јœš™vbN%јI–мі§џ ј™˜’fe6$ј5€Ъыњџ ј—–ff#јeАкѓ§ ј•”“uiP#јLСщљ ј“’‹kk;#љ 4hІлє ј‘€mm("љ KЭю їŽzod"њ5yОчјŒ‹uqU "њ3qБрј‹Š„rsH !њ4jЃзˆњ€uv> њ+]–Яї‡…„}wy5 њ L‚Пї…ƒ‚|z{0 њ0^ї‚€|}~- ћBџќёsтќћўўџўўУћ\:,џўѓ.fАяџўџўўљДГЄHI*ќѓ%UЃш§ўџўўљВБbK5)ўя&VŸсљџџўўљБЏ†KB%ўўѓ&VšиєўџўўјЏЎЈON,%їѓ@‡Юяўџўџљ­ЌqP<#ўє 'sСщ§џўџЋћ”QQ#њє !gДсќџўџљЊЈgT7 єє ^ЄзљџўџљЈЇŠUO§єR•ЭїџўџјЇІЄdW5§ўіE„ТѓџўџљЄЃ…YRэ 9sИ№џўџјЃЂ f[7ўўѕ.dЎэџўџљЁŸ‡\Zќўѕ([ЇыўџџјŸžžl^?љі%UЂчќўџ јœŠ`b%ўі$SŸфћџџ ј›š™vbNќќі!M—мі§џ јš˜’fe6ўі:ƒЫыњџ ј—–fgњє $iВлѓ§ •њ“thOўєQТщљ ј“’‹kk<ќ ј9lЇлє ј€ln(§ј &OЮю їŽzodќє:|ПчјŒŠuqU ўј8tГрјŠ‰„stH ќ№9mЅиˆњuv= ўј1a˜Яї‡†…}xx5 њі$P„Р„љ‚|z{0 њ5ažї‚||~- њі@{ї€}|€. ќњ8gљху(t„ џtсwyyxwvvuutrt„žЬєў§џўџфуЮ€‚ џwтxyyxwvvuutruƒЫѕџўџўџтсА/} џўfyyxwvuыtru„œЪєџўџўўср”=z џњYjwyywwvщuttsw‡ Ьѓўџџўўрп|Gw џњfjuxxvvutsэxŒЇЯђ§ўџўўпоfQt џњiltxxvvutыspu‘Еиє§ўџўўомUWr џlќswwuuчtuttrmq—УтіўўџўўнлF \o џњmnswwuutsьlqŸвыљўўџўўлл:!_l џіnosvwuuttssыrkqЅмђћџўџўўкй1#aj џўk oјsvwvuttssъrqjqЇрѕ§џўџўўиз+$agџў]іopsuvuutsrrіqpipІпіўџўўљиж'&aeџ§[ZoјsuvuttsrrіqpipЅнѕџџўўљзе&'_bџ ўЎљјvosuussrqїpioЃкѓўџўўљед&(\_џpќsutssrqїpioЁйђўџўўљдв*)Y]џњqpsttrrqpїohn зђўџўўљгб0*UZџqќsttrrqpoјhn жёџџўўљба8+QWџъqprssrrqqppoonhnŸе№ўџўўљаЮB-LTџљqprssrqqpoыnhnŸе№ўџўџўўЯЭN.HRџ§qprrqћpqponnьgmŸеяќџўџўўЭЬ\/DPџqњrsrqqppўonnьgmŸз№ќџўџўўЬЫk0@Mџ§rqrr§qpoonыmfl иёћџўџўўЫЪ|1,џlmlќkjihhєdgЁЮѕџўџўўљДГЃHJ*§lkllыklkkiihhgdfy–Ц№§ўџўўљВАcK5(lmљlkkjjihhѓgdfy—УьћџџўўАћ†LB&цmlmlljjiihhghgcey–РцїўџўўЏњЈNO+&єmllkkjjiihhggєdeq‡Дрѕўџўџљ­ЌrO<#цlkkjkjjiihhggfeehwЇиё§џўџљЌЊ•QP#ќmlkjjiўhggѓfeegt ЯыќџўџљЉЈhT6 цmlljjiihhggfgfedgsšХхњџўџљЈЇŠUOmћlkjihhgfєedeo’МпљџўџјЇЅЄdW4mіljjhhghgfeeѕdcjŠБиїџўџљЄЃ…XQmњljihhggўfeedіag‚ІбіџўџјЃЁЁf[7цnmkiihhggffeeddc`c{œЫѓўўџљЁŸ†]Yїnlkiihggffёeddcc_bw–ЧђўџџјŸžl^?цmkjhhggffeeddccb_at’Уя§ўџ œњ‹`b%цmkihhggffeeddccb_as‘Сэќўџ јœš™vbNіljighggfeddcѕb_`qМшљ§џ ј™˜’fd6ќmjhgg§feddcѕb_`k€Џнђћџ –њffhgfedcbѕa``držЭшїў •њ“tiPшhggffeedccbbaa``akŽЗз№ћ ј”’‹kk<ёhggffedccbbaa`__љfŸЦчї ј‘€ln(шihhfeedccbbaa``_^brЖпє їŽzodшkiheeddccbbaa``_]^jЊеяјŒ‹uqU шlkhfeddcbbaa``__]^i}ЄЭыј‹‰„stH шmkieedcbbaa``__^\^j}ŸУхјˆ‡€uv> ќmlhddюcbbaa``__^]^fw–Лпї‡†…}wy5 ќmkgccba`_ї^]]bn‹Ўе„љ‚|z{1 ќnkfccbўa``_ї^]]^ez—Пїƒ€}|}. шyjeccbbaa``__^^]]\Z\jЈї€}}€. њhedcbaa`_^]њ\YZg|šў№џџђPsvy|~€ƒ…‰‹ ўџџўџџѓcpsvy{}€ƒ†ˆRўџџўCџџђ knpsux{}€ƒ… § †џџќeџџѓhknoruxz}S ќ8žџџќƒџџѓ&ehjmortwz| ќ,kЛџџќžџџє1begjloqtw]ќB“вџџќЖџџє:_bdgilort-ќUЕхџџќ*ЫџџєA\^adgilniќdЯєџџќ8мџџѕEY[^acfhk?§oуџџќDщџџѕIWY[^`cfhў §vяџџќPєџџіJSVY[^`cUў§zіџџќ[њџџіKPSVX[]`2§§}ћџџќcўџџіJMPRUWZ\ ўќ…§џџќiўџџїHKLPRUWM§~ўџџќlњџџїCGJLORT1§~ўџџќlєџџї?EGILNQў~џџќiщџџї;ADFIKLўџџќcмџџј4>@DFH6ўџџќ[Ыџџј.;>ACE#ўџџќPЖџџј&8;>@BўџџќDžџџј 58:=@ўџџќ8ƒџџљ257:0ўџџќ*eџџљ/247#ўџџќCџџљ ,/24ўџџќџџљ*+/1 ўџџћ№џџњ")+.ўџџћФџџћ&)'ўџџў”џџћ#%ўџџўaџџћ "ўџџў+џџћ ўџџўщџџќ ўџџўЌџџќ  ўџџўkџџќўџџў'џџ§ўџџўеџџ§ ўџџўŠџџ§ўџџў<џџўџџўмџџўџџў‡џџўџџў.џџў~џџўРџџ§~ўџџўaџџ§~ўџџўщџџ§~§џџўƒџџ§}ћџџўџџ§zіџџў”џџ§vяџџў$џџ§oуџџ ў”џџќdЯєџџ §ўџџќUЕхџџ ўƒџџќB“вџџ §тџџќ,kЛџџ ўaџџќ8žџџ ўЖџџ§ †џџ ў.џџўџџ ўyџџўџџўНџџўџџ§+њџџўк§~ўџџўeџџ§|њџџў˜џџ§uюџџўФџџќfдіџџ§$щџџќPЋпџџўFџџ ќ+hКџџўaџџ ќ)–џџўvџџ § †џџeў џoўџєёдДœŠ…ŠœДдёџџ-ўюџўыЩ•^2 2^•Щыўџў+ўџјуГƒU3і %@aŠЖфџџў'ўјџўџњГ`& ј&`Гњџўџў%ўџѕуГi-7S^Z0ј&kГфџџў%ўђџўГ`-"qЦлЦw"њ&`Жўџў#ў№џўџыƒ&7qДяўяКw4ј&Šыџўџў!ў№џўёЩUSЦяўџўяЦ_њaЩёўџў!ўіџўд•3^лўџџќўлkњ@•дўџў!ў№џўД^ZЦяўџўяЦ_њ%^Дўџў!ў№џўœ20wКяўяКw4њ 2œўџў!ў№џўŠ"wЦлЦw"ћŠўџў!ўћџў… ј4_k_4 ћ …ўџўўўџўўћџўŠћŠўџў!ўњџўœ2 њ 2œўџўўџўњџўД^%њ%^Дўџўўќџўїўўњџўд•@ћ@•дўџџќюТўўњџўёЩaєaЩёўџўџўУx-ўўјџўџыŠ& ћ&Šыџџње”Y/-ўўњџўЖ`& ђ&`Жўџўџє)YўўџњфГk& №&kГхџџ§Ф~;7tЊўўјџўџњГ`& №&`Гњџў§пq .ŒхѕўўџјфЖŠa@% ь %@aŠЖхџџјЙn 2ŠЪїћў!ўтџўыЩ•^2 2^•Щыўџўјжh~хіэюў ўџєёдДœŠ…ŠœДдёџџѓќКipЛѕњююў/ўњџўќнmјdЭъэ№юяў#ў џѕТoEœщіюяя.ўюџўџюzE•Ыэѓюяююў-ўџѓв‡1Q‘Ых№ђяюю.ўђџў ZЊеэђюяюю,ўџѓчГQ_Ÿзэѓѓяюю,ўђџўВ\#XАйэђюяюю*ўџѓ§у} H‘йяђђяюю*ўђџўуБK4‹Хэєюяюю*ўџѕВUcУцђѓяюю(ўђџўџіx?™ыјюяюю(ўџѕсЋB,†Цѓјяю ю(ўєџўЏU\Шшюёю ю&ўђџўџѕ hујяяю ю§ўџў#ўњџўјжhњvэ§юяю ю§ўџў#ўџіЭ†1ZЌ№љю ю§ўџў#ўєџў4WЛсюђю ю§ўџў!ўђџўџю}xсѕяяю ю§ўџў!ўєџўђЬ_6–юњююџ"ўџіЫ…35‡Хђїюю§ўџў!ўєџў <sдэю№ююџ ўђџўџїXІыіюяю юњя§џўџўўєџўўрd;œЯюєююњяћџўџўўџіпЈ<RЪы№ђю юјяюя№ўўџўўєџўЙgmшњюяю юјяюѕжђџџўўџј—,,Ž№ќю юяљ№ђЖтўџўўєџўџќyfБюїю юїяюыэя™б§џџўєџўўтfBЇеяѓю юяќцщыђeў џoўџєёдДœŠ…ŠœДдёџџ-ўюџўыЩ•^2 2^•Щыўџў+ўџјуГƒU3і %@aŠЖфџџў'ўјџўџњГ`& ј&`Гњџўџў%ўџѕуГi-7S^Z0ј&kГфџџў%ўђџўГ`-"qЦлЦw"њ&`Жўџў#ў№џўџыƒ&7qДяўяКw4ј&Šыџўџў!ў№џўёЩUSЦяўџўяЦ_њaЩёўџў!ўіџўд•3^лўџџќўлkњ@•дўџў!ў№џўД^ZЦяўџўяЦ_њ%^Дўџў!ў№џўœ20wКяўяКw4њ 2œўџў!ў№џўŠ"wЦлЦw"ћŠўџў!ўћџў… ј4_k_4 ћ …ўџўўўџўўћџўŠћŠўџў!ўњџўœ2 њ 2œўџўўџўњџўД^%њ%^Дўџўўќџўїўўњџўд•@ћ@•дўџџќюТўўњџўёЩaєaЩёўџўџўУx-ўўјџўџыŠ& ћ&Šыџџње”Y/+ўўњџўЖ`& ђ&`Жўџўџє)TўўџњфГk& №&kГхџџ§Ф~;3l ўўјџўџњГ`& №&`Гњџў§пq +ƒзцўўџјфЖŠa@% ь %@aŠЖхџџјЙn!.Ншьў!ўтџўыЩ•^2 2^•Щыўџўјжhwзшпрў ўџєёдДœŠ…ŠœДдёџџѓќКijАцыррў/ўњџўќнmј_Снптрсў#ў џѕТoA“лшрсс.ўюџўџюz@ŒПпхрсррў-ўџѓб‡1L‰Питусрр.ўђџўU Щпфрсрр,ўџѓчГQZ–Ъпххсрр,ўђџўВ\#SІЬпфрсрр*ўџѓ§т} C‰Ьсффсрр*ўђџўуАK1ƒКпцрсрр*ўџѕБU\Зифхсрр(ўђџўџіx;нщрсрр(ўџѕсЋC(~Кхщср р(ўєџўЏUVМкрур р&ўђџўџѕ bжщсср р§ўџў#ўњџўјжhњoпюрср р§ўџў#ўџіЭ†1UЂтър р§ўџў#ўєџўœ3RАдрур р§ўџў!ўђџўџя}qдцсср р§ўџў!ўєџўђЬ`2рыррџ"ўџіЫ…32Йушрр§ўџў!ўєџўŸ;mШпртррџ ўђџўџїSœошрср рњс§џўџўўєџў§пd7“УрхррњсњџўџўўџіоЇ<MОнтур рјсрс№ўўџўўєџўИefкырср рјсрѕзђџџўўџј—+)…тэр рсљ№ѓЗтўџўўєџўџќy`Іршр рїсрыэ№›в§џџўєџўўтf=Щсхр рсќцшыёeў џoўџєёдДœŠ…ŠœДдёџџ-ўюџўыЩ•^2 2^•Щыўџў+ўџјуГƒU3і %@aŠЖфџџў'ўјџўџњГ`& ј&`Гњџўџў%ўџѕуГi-7S^Z0ј&kГфџџў%ўђџўГ`-"qЦлЦw"њ&`Жўџў#ў№џўџыƒ&7qДяўяКw4ј&Šыџўџў!ў№џўёЩUSЦяўџўяЦ_њaЩёўџў!ўіџўд•3^лўџџќўлkњ@•дўџў!ў№џўД^ZЦяўџўяЦ_њ%^Дўџў!ў№џўœ20wКяўяКw4њ 2œўџў!ў№џўŠ"wЦлЦw"ћŠўџў!ўћџў… ј4_k_4 ћ …ўџўўўџўўћџўŠћŠўџў!ўњџўœ2 њ 2œўџўўџўњџўД^%њ%^Дўџўўќџўїўўњџўд•@ћ@•дўџџќэТ—ўўњџўёЩaєaЩёўџўџўТv2ўўјџўџыŠ& ћ&Šыџџњж—a2 ўўњџўЖ`& ђ&`Жўџўџє‘)ўўџњфГk& ѓ&kГхџџ§Ф};ўјџўџњГ`& ѕ&`Гњџў§пq§ўўџјфЖŠa@% ђ %@aŠЖхџџјЙn'ќў!ўъџўыЩ•^2 2^•Щыўџўјжhњў ўџєёдДœŠ…ŠœДдёџџћќЙh#0ўњџўќнlјў#ў џќСo&.ўљџўџюxїў-ўџќб…3іў-ўћџўŽљ,ўџќфЎQј,ўђџўЎR*ўџїћр*ўђџўрЋP*ўџєАQ(ўњџўџі{њ(ўџєсЋJ(ўєџўЏU  §ўџў#ўђџўџі  §ўџў#ўњџўјжhњ §ўџў#ўџјШ~3ў §ўџў#ўєџў”% §ўџў!ўђџўџэyў§ўџў!ўњџўяЦ_ќџ"ўџіСs/ §ўџў!ўєџў“" џ ўіџўџѕ~ўњ§џўџўўєџўњкkњћџўџўўџід–CўјєўўџўўєџўЊLјѕфіџџўўџ§‘ўљ№ѓЯьўџўўњџўџќ~ќ їыэ№Мс§џџўєџўџтlўўќцшыђ џџўўџўџўёџ{џўѓџwџўўџџўђџџўїџB@=LМ<;'ўіџEB@>СG:8&ўіџўFC@Ћ\97&ўіџўHFCšp76&ўіџўKHFŠ‚65&ўіџўMKH|”54&ўіџўPNKqЂ42&ўіџўSPNhА30&ўіџўUSPaН1/&ўіџўXVT\Ц/.&ўіџўZXVZЮ.-&ўіџў][YYг-+&ўіџў`][Yз,+&ўіџўb`^[й+*&ўіџўec`aз)(&ўіџўgfcfг('&ўіџўjhfnЭ&&&ўіџўnkiwФ%$&ўіџўpnk‚И%#&ў џјspnЉ#"&ўіџўusq—! &ўџяѓаЋŽz|„‡‰xvsЌƒ!&ўьџўюЭM" "(+{xvЛj&џъўфЙŒqW+ B_w}zyЭN&їўџўтГfђMЂЯчяэ€~{п0&шљЦfF%/R`rЁвыїћ…‚€‹е'ши~#>ƒФсэёюяююˆ…ƒ В'ш_>1Gi—Рцї§њѓ№яяŠˆ…ЖŠ(і%iАщѓьююяююїяŒŠˆЮ`'шEwАмњўјѕёяяююяюя‹ц1'ї­зэёэююяююіяю•’ЁЮ(їиюієююяяююіяю—”’М™(ћэююяююіяюš˜•жa(љђ№яюяяююяјœšя%(§юяю юїяЁŸœЙЙ)яюѕяюяЄЂŸеv) юѕяюяЇЅІё0) юіяюЌЉЇУЙ* юіяюЏЌЊрl* юіяГБЏЙя * юїяЖДБж› +юѕяюяЙЖЗєB +юіяюНЛЙдЛ ,юяјСОМ№[ ,юіяХУРжЬ ,юѕяюяШЦФёd -юѕяюЬЫШнЭ -юяјЯЮЮі].юіяевахН .юяїйзекњF/юѕяюмкзёœ/юєяюяспншь0юѕяюцфсуњi1ђюяюяющчфєБ1ѓюяюяэыщ№ё&2єюяяѓ№юя§b3єюяјѕѓђћ™3яїћјѕњЩ4іюџ§њњђ/5їњќџ§ўT6јјњќўt7љєљў‹8њѕў9ћўЇ:ўїџB@=MМ<;'ўіџEC@>РF:9&ўіџўEC@Ќ\97&ўіџўHFCšp76&ўіџўJIFŠ‚64&ўіџўMKI|“53&ўіџўPMKqЃ43&ўіџўSPNhА21&ўіџўUSQbН10&ўіџўXVS\Ц//&ўіџўZXVYЮ.-&ўіџў][XXг-,&ўіџў_][Yз,+&ўіџўb`^[й+)&ўіџўeb`aж*(&ўіџўgecfг(&&ўіџўjhfnЭ'&&ўіџўmjiwХ%$&ўіџўpmk‚И$#&ў џјspnЉ#"&ўіџўusp—" &ўџяѓаЊŽ{|„‡‰xutЌ‚ &ўьџўюЭŽL!  &)zxvЛj&џъўфЙŒqX, =Xoww}{yЭN&їўџўтГeђH˜Тйсп€}|п0&шљЧfG%+MZk˜Хмщь…‚€‹е'ши~#;|Йдптрсрр‡…ƒŸВ'ш_=.BbwЕйшюыхтссŠˆ†ЖŠ(і"cІлфоррсррїсŒ‹ˆЮ`'ш@pЅЯыяъцуссррсрс‹ц0'їЃЫпупррсрріср”’ЁЮ(їЬршцррссрріср—•’Лš(ћпррсррісрš˜•еa(љфтсрссррісрšя&(§рср рїсЁŸœЙЙ)срѕсрсЄЁŸеv) рѕсрсЇЅІё/)рєсрсрЌЉЈУЙ* рісрЏЌЉпl* рісДБЏЙя * рїсЖДБжœ +рѕсртИЖЗѓB +рісрОЛЙгЛ ,рсјСОМ№[ ,рісХУСжЬ ,рѕсрсШХУёd -рѕсрЭЫЩнЭ -рсјаЭЮѕ] .рісевЯцН .рсїкзелњE/рѕсрмйи№œ/рєсрсспншь0рѕсрцфсфњj1ђрсрсрщчфѓБ1ѓрсрсэыъё№&2єрссђ№ю№ќb3єрсїѕѓёћ™3сїћјіњЩ4ірџ§ћњђ/5їњќў§ўT6їїљћўt6љєјў‹8њѕў9ћўЇ:ўїџB?=LМ<;'ўіџEB@>РG:8&ўіџўECAЌ[97&ўіџўHFDšp76&ўіџўKHF‹‚64&ўіџўMKI|“53&ўіџўONLqЃ42&ўіџўSPNiА31&ўіџўURPaМ10&ўіџўXUT\Х//&ўіџўZXVZЭ/-&ўіџў]ZXXг-,&ўіџў_][Yз,+&ўіџўc`^\и+)&ўіџўeca`ж)(&ўіџўhedfг('&ўіџўkhfnЮ'%&ўіџўnkhwФ%$&ўіџўpnl‚И$#&ў џјrpnЉ#!&ўіџўusq—" &ўџљѓЭІŽ|јwvsЋ‚!&ўјџўяЭŠDј{yvЛj&џјфЗŠvc=ј}{xЭN&јўџўуГ`ѓ€}|п0&љљЩ’rU$ѓ…‚€‹е'ћи}!я‡…ƒ Б'ќi1ўјŠ‡†ЖŠ*јї‹‰Ю`*ўє‹х1'ўўі”’ЂЮ(ўі—•’Лš(ћі™—•жa(ўјšя&(§ їЁ ИЙ)ѕЄЂŸеv) ѕ ІЄІђ0) і ЋЉЇУЙ* і ЎЌЊрl*є ГБЏКя *ѕЖГВж› +ѕИЖЗѓB + јОЛЙдЛ , їРОМя[ , їХТСжЫ ,ѕШХУёd -ѕЭЪШнЬ -јЯЭЮі] .їегацН .їйзелњF/ѕмки№/єспмшь0ѕцутуњj1їщцфєБ1їюыщё№&2єђ№ю№§c3єјѕѓёћ™3їћјѕњЩ4іџ§њћђ/5їњќў§ўT6јїљћўt7љѕјў‹8њѕў9ћўЇ:џў№'џў&џўC&џўe&џўƒ&џўž&џўЖ&џўЫ&џўм&џўщ&џўє&џўњ&џўў&џўў&џўњ&џўє&џўщ&џўм&џўЫ&џўЖ&џўž&џўƒ&џўe&џўC&џў&џў№'џўФ'џў”'џўa'џў+'џўщ(џўЌ(џўk(џў'(џўе)џўŠ) џўўџџў<)џўм*џў‡*џў.*џўР+ џўёџџўa+џўщ,џўƒ,џў,џў№џџў”-џў$-џўўџџў”. џ§ў. џўƒ/ џ§т/ џўa0 џўЖ1§џўџџў.1 џўy2 џўН3џ§њ+3§џъџџўe4џў˜5џўФ6џ§щ$6џўF7џўa8џўv9ї~|{}‚3 ќ1Sї{zx~„…; ќ%Bїywv†‡G ќ2іvut}ˆŠW ќ іtsq{Œl ўіqpowŒ†3 ўѕonmqˆ’’R ўѕlkji”•v' ў ѕiggw“˜™Q 5ѕfediˆšœ€5 5єdcb`w˜ž i"5є`_^b„ЁЂЃ]4ѓ^]\[kЄЅ \4ђ[YXWq—ЈЉЅe'2ёXWVUSr™Ћ­Ўz?ў'шUSRQPn•ААВ™b.  )ъQPONLb‰АДЕЗ‘b4 !$&3+ьNMKIHLs™ИЙЛМ wO+&(*.HёGEDRxœНОРСТЂd0ёECCB@@HjŒЎУХЦЦ3єA@>=;:9Hf„ 6ї;:987653:ћ6443 ?ї}|{~ƒ3 єњ5Wї{yy~„…; ўћњ*Gїxwv~‡‡F ўќњ6іvus}‰ŠW ўћ$іtsr{ŒŒk љљіqpowŒ†4 ўўїѕonlq‡‘“R њіѕlkki”•v' ўўќhїgw“˜™P јѕfediˆšœ5 ўўўўѓdca`w™ž j"љў!`є^b„ ЂЃ]ќ"ё^][[lЅІ \ў$№ZYXWq—ЈЉЅe'ќў%юXWVUSr™Ќ­Ўy@ў'шTSRQPn•ААВ™c/)ъQONMLa‰АДЕЗ‘a4"$'1+ьMLKJHLsšИЙКЛ vO+%(*.яIHGEDRwœНОРСТЂc0ёEDBAA?HjŒЎФХХЦ3є@?>=<;:Hg„Ё6ї<:997653:ћ6433 ?ї}|{~‚3 њfedaa``§_^]]љ[YZgyzљyƒ…; њiheba``§_^]]ј\[YZcq„xљv~†ˆG ъkjfba``__^^]]\\[ZZ_hyіvus~‰ŠW јlkgbaa`__є^]]\\[Z[[`mіtsr{‹Œl јmkfaa`_^^ў]\\ў[ZZќXYcіrpnwŒ†4 єpkea``_^^]]\\ў[ZZќWXbѕommr‡‘“R іib``__^]\\[ZћYWWbѕlkki”•v' ћgdcb__ў]\\ў[ZZћYXW]ѕihfw“˜™Q ьgec__^]\\[[ZZYZYXWWfїdjˆš›€5 ђihd_^^]]\[[ZZYYXўUрdbaaw˜žŸj"ljd^^]]\\[[ZZYYXXWU!э`_^b„ ЁЃ]jc^^]]\[[Z§YXWW#э^]\ZkЄЅ \^^\\[[ZZљYXWWVW$я[ZYWq—ЈЉЅf'\[[ZZYћZ\\R%цXWUTTsšЌ­Ўz@[ZZYYXXWYVE'TъRQPn•ААБ™c/YZWMB5))ъQPONLb‰АДЖЖ‘a4!$-+ьMLKJIMršИЙКЛ wO+&(+.яIGFEDRwНППРСЂc0ёEDBB@?HjЎУФХЧ3@і>=;;9Hg„ 6ї;:987553:ћ6432 ?ўƒџџ ўџџўŠџџ ў~џџўŠџџ §|њџџўƒџџ§qцџџўvџџќ\Рыџџўaџџќ0rПџџ§Fщџџќ&”џџ§$Фџџ§ …џџў˜џџўџџ§eњџџўџџ §+Нџџќsъџџ"ўyџџќТѕџ џ#§.Жџџ§бѓџ џ%§aтџ џќЕжіџџ&ќƒўџ џўгџџ(§”џ џћŸЖаэџџ*§$”џ џћюќџџ+ќƒщџџ/§aРџ џ1ќ.‡мџ џ4ќ<Šеџџ7ћ'kЌщџџ;ћ+a”Ф ?љ~РјџўџўўєџўцЙVlмђю№ю юѕяюсфцяўlГѓџџўєџўФ~=$‚ьњюяю юяёмосэўЇZЂфњ§џўџўўєџўЁB(:“эљюяю юёяюзймэўB€ПфљџџўџјŠ VІяјююяюавезяў‹-]’Щѓџўџўўіџўw%xЛюіююшяюяЫЭазѓўs*FlАюўўџўџўўєџўџюi?ЊзяѓююяіюЦШЪлљђTѕ'2K˜уњ§џўџўўєџўівY\ж№ю№ююєяюПСУЦу§Щ-ѕ3€ЯяќџўџўўєџўоЉ?gшњюяююяіКМПЭю§™ѕ $gЏмїџўџўўєџўФz&oэ§юяююєяВЕЗЙкќёaљ&JxЖэџџўіџўЊM{я§ююёяююяЎАВЧэћБ%і)3J“мїўџўўіџў’& &ŠюћююђяюІЉЊЗоћьiч !8Y“ТРЌ›Š~vrprv}…Ž›ЎХсћџџцўџџƒMЃяјяяюŸЂЄЋвљћœф@l’ЅŒcE+  !0Cb‡Енѓўџўўщџўx#uЙюію—šЄЬєљНD ђ(Cf‚‚zuplihiiнhfeeffhm|ЃЪєџџїn8šЪސ“•ЄЫєјЬX Э #'/Pu“­Удршяё№щпЯНІ‰e8K“гўџъiH‡‰ŒŽЋгіїС] ѓ4Uv‡”ЅЗЩйчѓњџџоїэсбПЊ‘yeXU[oŠВЩ~‚„–МтєѓЇ=,@I ѓ[УхњўћќћќћњљљћјїєёююуђюкЕs3rsvyzВжђєя„$/N^e`WE ћ,Жт§џџќўќћњњљоіѕєїњџcfhkmow—Зй№№ђЖ_Il€wmd[Q ЬH./1357:Uj‘ ЏМЦЭдикидЮУЗЇ•eI) *4=FPYclušеєьмЬЛЋ›{ Ъ10/.-++)(&&%##! &/9BKUkšРжчѓђфгТВЂ‘% .щ-+*(''&%#"! ш"+5Jl‰ŸЏПЯряѕылЪЙЉ™b(ш *?Tfv‡—ЇИШйщєёсбСА 'ш .=N_o€ БСвт№ѕшзШЗЇ—2'ш&6GXhx‰™ЊКЪкыіяпЯОЎže(ш0@Qar‚’ЃГУгфѓѕцжХЕЅ”'ш)9IZk{ŒœЌМЬнэїэнЭНЌœQ(ш!2BRct„”ЅЕЦжцѕєфдУГЂ‚'ш +;K[l}žЎОЯпяїылЪКЉ™('ш$4DTev†–ЇЗШишіётбСА g(ш -=N^o АСбсђѕщйШИЇ–'ш&6GWgxˆ˜ЉЙЪкыѕярЯПЎžR(ш/@P`q’ЂВУгфѓѓчжЦЖЅ…'ш(8IYjz‹›ЋМЭнэѕэоЭНЌœ#'ш!1ARbs„”ЄЕХецѓђхдФДЄV(ш *:K[k|ЎОЮпюєьмЫЛЋ‰'ш$4DTdu…•ІЗЧзшѓёувТБЁ*(ш ,=M]n~ŽŸАПар№ѕъйЩЙЈm'ш%6FWgwˆ˜ЉЙЩкщє№саРЏŸ(щ.?P_p‘ЂВТгуёєчзЧЖІW(ш(8IXiy‰šЋЛЬмьіяоЮО­Œ'ш 1AQar‚“ЃДФдхѓєхеФДЄ*(ш ):J[k{ŒœЌНЭнэіьмЫМЋo'ш"3CTdt„•ІЖЦжчѕєугУВЂ 'ш ,N^o€ БСвтѓішиШЗЇ (ш'7GXiy‰™ЊКЫльїюоЮОЎ\'ш 0AQar‚’ЃГУдфєѓхжХД“ (щ )9JZj{ŒœЌМЭнэѕьнЬМЋ-(щ"2CSdt„•ЅЕХжцєђфдУГu)ъ +;L\l|ŽžЎОЯпяѕылЪКЉ)ъ#4DUev†—ЇЗШишєётбСБ)ъ ->N^oŸАСбсёєщйШИ*ы'7GWgxˆ™ЉЙЪкыєярЯП*ы/?P`q’ЂГУгуёѓчжЦ+ь(8IYjz‹›ЌМЬмьѕюоЭ+ь 1ARcsƒ”ЄЕХецѓѓхд+ь *;K\l|­ОЮоюіьл,э$4DUeu†–ІЗЧзшѕѓт,э ,=N^oŸЏРас№іщ-я%5FWgxˆ˜ЈЙЩкъїёљСјџўџўўєџўцЙUeЯфртр рѕсрсуцюўoЕѓџџўєџўФ~<"zоырср рсёнпрэўЇ]Ѓфљ§џўџўўєџўЁB'7‹пърср рёсрзйлэўFƒРфљџџўџјŠQœсъррсюавджяў‹2`”Щѓџўџўўіџўx!pАрчрршсрсЫЮЯзѓўs/JoВюўўџўџўўєџўџюi: ЪсхррсірЦЩЫмљђTѕ,7Ošуњ§џўџўўєџўівZVЪтртррєсрПСУЦуќЩ-ѕ!8‚ЯяќџўџўўєџўоЉ@aлырсррсіКМОЭя§˜ѕ )kАмїџўџўўєџўФz'hпюрсррєсВДЗЙкќёbј+N{ЗюџџўіџўЊM sсюррёсррсЎАВЧэћБ%ѕ.8N•міўџўўіџў“& $‚рьррђсрІЈЋЗоћэhц%;ZОМЊšŠ~vrqsw}…Ž›ЎХсћџџцўџџƒI™съссрŸЁЄЋвљћœу AiŒ…^B) .Ba†Днѓўџўўшџўx nЎршр—šœЄЬєњНDѓ '@a{|upkgddкedcb`_adfin}ЃЪєџџїo3‘ОŽ“•ЃЬєјЬX Э  #,LqЉНЬирчщчреХГœ`6K“гўџъjB‡ŠŒŽЋвѕїС] Э3Sr„’ЃЕЧиуэєљ§џ§їяфеХГ ‰r_TS[oŠВЩ}€‚„–МтѕєЇ=,@I ыXŒПуљўћќћњјїіїїіѓ№ьцрруфрЯ­o3rtvxzБжђє№„$/N^e`VD ћ,Впћџџќўќњјјлїѕђющхшыѓdehjmow–ЗйяёђЗ_Il€wmd[Q ЬG..1357:<>@CEHJLNQSUXZ\_af}˜ДбьэюяЗs$.Oi€Š‹„{qh_oZ ЫШЩБœˆxi^TMIDCEHMT^iv…•ІЛачшъыьޘ] 1H]kt}‡Œˆu’ЅœŒ ЫНЫЬЭЯабвгджзикллнорстффцчжАˆH +Uj~ЁАЛЦЮдийидЭФЗЇ•fI) *4=FPYclušжєэмЫЛЋ›{ Ъ10/.-+*)(&&$#"! &/9BLUkšРжчѓѓфгУВЂ‘% ч/--+*)('%$$"! ш"+5Jl‰ŸЎПЯряѕыкЪКЉ™b(ш )?Tfv‡—ЇИЩйщєёсбСА 'ш .>N_o€ЁБСвтёѕшиЧЗЇ–2'ш'7GWhx‰™ЊКЫлыі№рЯПЎe(ш 0@Qaq‚’ЃГУдфђѕцжЦЕЅ”'ш(8JZj{‹œЌМЭньїэнЭМЌ›Q(ш!1BScs„”ЅЕЦжчіѕфдУГЃ‚'ш +;L\m}žЎОЯр№јылЪКЊ™('ш$4EUfv†–ЇЗШищїётбСА g(ш ->M^o~ АСбсђіщйШИЈ—'ш&6GWgxˆ™ЉЙЪкыіярЯПЏžS(ш/@P`q’ЂВУгфѓѓчзЦЖІ…'ш(8HYjz‹›ЋМЬнэѕэоЭНЌœ#'ш!1ARbsƒ“ЄДХецѓђхдФДЃV(ш *:K[k|Œœ­ОЮпяєьмЫЛЊ‰'ш#3DTdu…–ЇЗЧзшѓётвТБЁ*(ш -O_o БТвтђішиЧЗЇ(ш'7HXhx‰™ЊКЫлыіюпЮОЎ\'ш 0AQar‚’ЃГУдфѓєцжХЕ’ (щ )9JZk{‹›ЌМЭнэіэнЬМЋ-(щ!2CScs„”ЅЕХжцєђфгУГt)ъ +N^o АРбсёєщиШИ*ы&7GWgx‰™ЉЙЪкъє№рЯП*ы/?P`q’ЂВУгуёєцжЦ+ь(9IZjz‹›ЋЛЬмьѕюнЭ+ь!2BScsƒ”ЄДХецѓѓфе+ь *;L\l|­ОЮоюіым,э$4DTeu…–ІЗЧишѕђт,э -=M^nŸАРас№іщ-я&6GWgxˆ˜ЈЙЩкъї№љЊењџўџўўєџўшЙX №туцяўžЭїџўџўџўўєџўЦ~6 ёмосэўЇ’Сьћ§џўџўўєџўЅB ёзклэџƒЋгьћџџўџњўюЯгезяў‹u”Жкіўўџўўіџў ъЫЭажѓўss…žЫѓўўџўџўўєџўџюsєЦЩЫмљђTѕpxˆЛьћ§џўџўўєџўівfѓПСУЦу§Ш.ѕeixЋпє§џўџўўєџўоЉOіКМОЭя§˜ѕY^mšЩчљџўџўўєџўФz4єВЕЗЙкќёbјW_o‰ЋжќџџўхџўЋM­ЏВШэќБ%ѕVbpw†Зчљўџўўіџў•&ђЇЉЋЗоњэhцY`fa^q……|zyxxwwx{€Š™ЎШућџџїўџџˆѓŸЁЃЋвљћ›VѕQE7.% є-U‚Гнєўџўўщџў—šЅЬєњНC ЫD2  !%&"#&% $B[py…ЈЫєџџїw“•ЃЬєјЬX Э.+JeqtoiqwtgL- K“гўџъs‡‰‹ŽЋвіїС] Э%8Sp‚ЁЏГВЇžЄЉЁsQ%-OmŠГЩ~‚„•МуѕѓЇ>,@I Ь@xБояёёьшрвХШЪОЉl5 *'qtvy{Беђѓ№„$/N^e`WE њ-oЇжјџџдљђшиЫЬЭСЎ‘j5cfhjmox—ЗйяёђЗ_Il€wmd[Q ЬH..1367:<>ACFHJLOQSUXZ\^ae}˜Гбыэя№Иs$-Ni€Š‹„{qh_oZ ЫШЩБœˆxj^TMHECEIMU^iv…•ЇКачшщыьޘ] 1H]jt}‡Œˆu’ЅœŒ ЫНЫЬЭЯЯбвгджзийлмнпрссухцчеАˆH +=JT]fpy‚ŠŠМЯХДЄ“L Ъ2>Uk~ЁЏМЦЮдикидЭФЗЇ•fI) *4=FPYbkušеєьмЬЛЋ›| Ъ10..-+*)(&&%$"! &/9BLUkšРжчѓђфгУВЂ‘% ч/.-,*)('%%#" ш"+5Jk‰ŸЏПаряѕыкЪЙЉ™b(ш )?Tfv‡—ЈИЩищєёсбСА 'ш ->N_o€ЁБСбт№ѕшиШЗЇ–2'ш&7GXhx‰™ЊКЫлыіяпЮО­e(ш 0@Paq‚’ЃГФдфђѕцжХДЄ”'ш(9IZk{‹œЌМЭнэјэнЬМЌ›Q(ш!2CScs„”ЅЕЦжцієфдУГЂ‚'ш +;L\l}žЎПЯпяјылЪЛЊ™''ш$4EUev†–ЇЗШищїётбСБ g(ш ->N^o АСбсђіщйШИЇ–'ш&6GWgxˆ˜ЉЙЪкыіярЯПЏžS(ш/@O`q‘ЂВУгфѓѓчзЦЖІ…'ш(8HYjyŠ›ЋМЬнэѕэоЭН­œ#'ш!1ARcrƒ”ЄЕХецѓђхдФДЃV(ш *:K[k|ŒЎОЮпяѕьлЫЛЊ‰'ш$4DTeu…•ЇЗЧзшєёувТБЁ*(ш -N_o БТбтѓішиЧЗЇ(ш'7GXhy‰™ЊКЪльіюпЮО­\'ш 0AQar‚’ЂГУдхѓєцжХЕ’ (щ )9JZk{‹›ЌМЭнюіэнЬМЋ-(щ"2CSdt„”ЅЖХжцєёфдУГt)ъ +;L\m}ЎОЯп№ѕылЪКЉ)ъ$4EUev†—ЇЗШишєётбСА)ъ -=N_o АРбсёєщйШЗ*ы&6GXhxˆ˜ЉЙЪкыєярЯП*ы/?P`q‘ЂВТгуёѓчзЦ+ь(8IYjz‹›ЋЛЬмьѕюоЭ+ь!1ARbsƒ”ЄДХецѓѓхе+ь *:K\l|­ОЮоюіым,э#4DUdu…–ІЗЧзшѕђт,э -=N^n~ŸЏРас№іщ-я&6FWgxˆ˜ЈЙЩйъїёtџўўџџўщџФџўvџ-џўўџџўщџџ§aџ:џћщFџ/џўфџџ§Ф$9џў˜,џ§ёЫџџ§њe6џ§Н+(џ§ђЭџ џўy3џ§Ж.#џ§ўкџ џ§уh "џўјџ џќК  џќювЖџ џќїи 1џўўіџІГРЭкх№њџџјљ№хкЭСГџџ§~ 2џў5 2џў‘ 2џ§т џќјїўџџўD ў№џџљ№Ф”іьџџўД чCeƒžЖЫмщєњўўњєщмЫЖžƒeCќдхџџў*$ћ’эњџџў‘%ќтрџџ§т%§‘тџџў<%ќ<єёџџў‘%ќ роџџ§т %ќ‘пўџџўD%ќ/ђчџџўД&§Дгџџў*%ќDрїџџў‘%ќ рсџџ§т%§‘уџџў<%ќ/єђџџў‘&§Доџџ§т %§DцџџўD%ќ рэџџўД&§‘щџџў/%ќ/іљџџў‘&§Дчџџ§т%§Dыџџў<%ќ рѕџџў‘&§‘ъџџ§т %§<ыџџўD%ќ рюџџўД&§‘ъџџў/%ќ/іњџџў‘&§Дщџџ§т %§Dьџџў<%ќ ріџџў‘&§‘яџџўт&§/јџџ(§Дђџџ(§Dёџџ(ќ рћџџ)§‘єџџ)§/љџџ*§Дјџџ*§Dђџџ*§јџџ+§Дѓџџ+§DёџџќЋ;§<ў ~ў=ў =ў]=§•<§Ў!<§Еa<ќМ™ ;ќФД/;ћЫЛz:ћвТБ!:ћкЩИb:њсаП 9ќЋ;§<ў ~ў=ў =ў]=§•<§Ў!<§Еa<ќН™ ;ќФГ/;ћЫКz:ћвТБ!:ћйЩЙb:њраРœ 9ќЋ;§<ў ~ў=ў =ў]=§•<§Ў!<§Еa<ќН™ ;ќФГ/;ћЫКz:ћвСА!:ћйШИa:њраПœ 9џўƒ:џўŠ;§џŠ<ўƒ >ў =ўD=ўД=§џ/<§џ‘<§џт<џў/;џў‘;џ§т :џўD:џўД:џў/9.ю/?P`q‘ЁВТвуѓі-ю'8HYjzŠšЋЛЫмьї.я 0ARbsƒ“ЃДФехѕ.я ):J[k{Œ­НЭою/№"3CTdu…–ЅЖЦзч/№ ,O_o€ЁБСв1ђ'7GXhy‰šЊЛЫ1ђ 0AQar‚’ЃГФ2ѓ):JZj{‹œЌН2ѓ"2BSct„”ЅЖ2ѓ +;L\m}žЏ3є$4EUfv†—Ј3є -=N_o 4ѕ&6GWhxˆ™4ѕ0@Par’4ѕ (9IYjz‹5і!2BRcsƒ5і *;K\l|6ї#4DTeu6ї -=M^n6ї&6FWg7ј/?P`7ј(8HY8љ 1AR9њ *:J9њ#3C9њ ,<:ћ$5:ћ.;ќ';ќ ;ќ <§<§ =ў=ў.ю.?P`q‘ЁВТвуђі-ю '8HXizŠšЋЛЫмьї.я 0AQbsƒ“ЃДФефє.я ):J[k{Œ­НЭню/№"3CTdt…–ЅЖЦжч/№ ,O_o€‘ЁВТв1ђ'7GXhyŠšЊКЫ1ђ 0@Qar‚’ЃГУ2ѓ):JZj{‹œЌМ2ѓ"2CTct„•ЅЕ2ѓ +;L\m}ŽžЏ3є$4EVfv†—Ј3є ->N_o 4ѕ&7GWhxˆ™4ѕ0@Par’4ѕ (9IZjz‹5і!2ARcsƒ5і *:K\k|6ї#4DUdu6ї ,=M]n7ј%6FWg7ј/?P`7ј(9IY8љ!1BR9њ *:J9њ#3C9њ ,<:ћ%5:ћ.;ќ';ќ ;ќ <§<§ =ў=ў.ю.>O`q‘ЁВТвуѓі-ю '7HYiyŠšЋЛЫмьї.я 0AQbsƒ“ЃДФехє.я *:J[l|Œœ­НЭою/№#3CTdu„•ЅЖЦзч/№ ,O_o€‘ЁБТв1ђ&7HXhy‰šЊЛЫ1ђ0AQaq‚’ЃДФ2ѓ ):JZj{‹œЌМ2ѓ"3CSct„•ЅЕ2ѓ +N_o 4ѕ&6GWhx‰™4ѕ0@Qaq‚’4ѕ (9IYj{‹5і!2BRbsƒ5і *;K\l|6ї#4DTeu6ї ,=M]n6ї&6FWg7ј/?P`7ј'8IY8љ 1BR9њ *:K9њ#3D9њ ,=:ћ%5:ћ.;ќ';ќ;ќ <§<§ =ў=ў+ќ рќџџ,§‘ѕџџ,§/љџџ-§Дјџџ-§Dѕџџ-§ сџџ.§‘љџ џ.§/ћџ џ/§Д§џ џ/§Dјџ џ/§ сџ џ0§‘јџ џ0§/ѕџ џ1ўДџ џ1§Dљџ џ1§ћџ џ2§Дўџ џ2§Dјџ џ2§ сџ џ3§‘ќџџ3§/ќџџ4ўДџџ4§Dћџџ4§ сџџ5§’ўџџ5§/§џџ6ўДџџ6§Dќџџ6§ пџџ4ћ‘џџ7§/ќџџ8ўДџџ8§[ўџџ8§%§џџ9ўДџџ9§D§џџ9§ сџџ:ў’џџ:њ/ўџџэ:ћДяюі:ћ!іџт;ќy";ўAњшзЦЗ*9њюоЮОe9љєхеФ  8љіьмЫЛ28јѕђугТ€7јёѕъкЩЙ"7јщѕ№саРf7їтёєшиЧЃ 6їлыєюпЮО26їдфђѓцеХ‚6іЭнэѕэмЬМ#5іЦжцѓђфдУi5ѕПапюѕылЪІ4ѕИШищѕёсвС$4ѕАСбс№ѕщйШk4єЉКЪлыі№рЯЊ 3єЂВУгфѓіцжЦ43є›ЋМЫнэјюнЭ‡3ѓ”ЄЕХецієфдУ%2ѓЎОЮпяїылЫm2ђ…–ІЗЧишіётвЌ 1ђŽŸАРбсђіщйШ01ђw‡˜ЈЙЩкъіярЯo1ёp‘ЁВТгуђѓчжБ 0ёizŠšЋЛЬмьѕюоЭ70ёbrƒ“ЃДХехѓѓхеŽ0№[k|Œ­ОЮоюєьмЬ'/№Tdt…–ЅЖЦзчѓёувq/яM]m~ŽžЎПЯр№єъйГ .яEVgw‡—ЈИШйъє№рб8.я?O`p€ЁБТву№єшз.ю7HXiy‰šЊЛЫмьѕяпЮ -ю0AQbr‚’ЃГФдхђєЬЌ)-ю):JZk{ŒœЌНЭнЉ> -ѓ"3CSct…•ЅЂn 2ѕ+O`p€‘ЁВСву№єшз.ю7HYiy‰™ЊКЫмыѕяпЮ -ю0AQbr‚“ЃГУдхђєЬЌ)-ю)9JZk{‹œЌМЭоЉ> -ѓ"3CSdt…•ЅЁn 2ѕ+O`p€ЁБТву№єши.ю7HYhy‰šЊЛЫльѕяпЯ -ю0AQar‚’ЃГФдхђєЬЌ)-ю)9JZk|‹œЌНЭоЊ> -ѓ"2CTdt„•ЅЂn 2ѕ+&>ќ>0>§&>>§>>§)4>§>=§&,>ў=>ў@>ў@ў = = < ; : § 8 ў 8 § 7§  ќ 6§   7  6ѕ 4 ќ 4  § 3ј  3  §  3 њ   ў 1 ў  ў 1§  ў  ў  1 ў  1ў  ў  0 ў  ў  ќ /  ј   . ў  љ  . ў  § .ќ   ѕ    -   .   њ  , ў   ќ -ќ §   ў ,ќ   њ  ќ  +@ў=§‘<ќ‘;ў;ўŽŽ:ўŽ9Œ9Œ‹8§‹Œ‹‹Š7ў‹ŠŠ‰7њŠ‰Š‰‰ˆˆ6љ‰ˆ‰‰ˆˆ‡‡5ў‰ˆˆќ‡†‡††5ўˆ‡‡†§…†……4†…„ўƒ2ќ†…†„„ƒ3…„ƒ‚§‚1„ƒ‚ў€1ƒ‚њ€€0ƒ‚ћ€€€1‚€њ~~~}/ў€€~}0ќ€€~}|ў{.~}{/~}|{z/ў~}}|{zњyzzyy-ў}||{zyx.|ў{zzyxћwxww,{zћyzyyxxwv-ў{zzyxwќxwwvvu-ўzyyўxwwvut,§  ў  ќ  ў  §  §  ќ   ў  §   §   §   §   §   §   ќ  ў  ў  ў  ў  §  ў  ў §  §  ў  §§  § ќ §  §  § §  § ў§  §§  ў§   ќ  §  §ў  ў   ћ ўћ  ќ  §ў§ўў§ ў§ ўўў§ў§§§ў§љ ў § §ўўћў ќ §ўў§ ў ў§ ў§ўјˆŒŽŽіŽŽŒ‹‹Š‰‰ˆў‡††љ…„„ƒ‚‚ї€~~}}||шŠŒŽŽŒŒ‹‹Š‰ˆ‰ˆ‡††…ю„ƒƒ‚‚€€~~}||{{њŒŽ§ŽњŒ‹‹Š‰ˆˆў‡††ќ…„„ƒƒё‚€~~}||{zzќ‘ŽŽћŒŒ‹ŠŠє‰ˆˆ‡‡†……„ƒƒ‚‚љ€€~~}}њ|{{zzѓŒŽŽŒ‹‹іŠ‰‰ˆˆ‡††…„„љƒ‚‚€~§}|{{ќzyyсސŽŽŒŒ‹‹ŠŠ‰ˆˆ‡‡†……„„ƒƒ‚‚€€ў~}}ј|{{zzyx§ўŽфŒ‹‹ŠŠ‰‰ˆˆ‡††…„„ƒƒ‚‚€€~~}||ќ{zzyyўxŽљŒŒ‹‹Š‰‰ыˆ‡‡†……„„ƒƒ‚‚€~}}||ћ{zyyxxўwјŒŽŽŒ‹‹єŠ‰‰ˆˆ‡††……„ƒƒ‚ѕ€€~~}}||{{ќzyxwwўvўŒŠ‰ˆ§‡†……„ўƒ‚‚і€~~}}||{zzјyxxwvvuўћŒ‹‹Š‰‰ˆљ‡†……„„ƒƒљ‚€€~~љ}||{{zyyљxwvvuuŒх‹Œ‹‹Š‰‰ˆˆ‡‡††…„„ƒƒ‚‚€€~}}ќ|{{zzіyxxwvvuutћ„ŒŒ‹ŠŠ‰јˆ‡‡†……„ƒƒі‚€€~~}||{ўzyyќxwwvvќuttщ…Š‹‹Š‰‰ˆˆ‡‡†…„„ƒƒ‚‚€№~}}||{zzyyxxwvvuuќtssў‡ŠŠ‰ўˆ‡‡†§…„ƒƒ‚і€€~~}||{{ќzyyxxіwvvuttsrrн‰Š‰‰ˆˆ‡††……„„ƒ‚‚€€~~}|{{zzyyxwwvўuttќsrqўˆˆ‡†§…„ƒƒ‚ў€€х~~}}||{zzyyxxwvvuuttssrqqˆ‡†і…„„ƒƒ‚€~}њ|{{zzyyўwvvўuttљsrrqqpў‹‡‡ў†……„ƒ‚љ€€~~}}|ћ{zzyxxљwvuuttssњrqqpoѕ…‡††……„„ƒ‚‚ћ€€~~і}||{{zyyxwwќvuuttїsrrqpponъ…††……„„ƒ‚‚€€~~}}|{{zxwєvuuttssrqqpooўnљ††……„ƒƒѓ‚€€~~}}||zzyўxwwќvuuttјsrqppoonn№„…„„ƒƒ‚‚€€~}}|ђ{zzyxxwwvvuutssљrqqpoonnўmѓƒƒ„ƒƒ‚‚€~~ќ}||{{јzyyxwwvuu№tssrrqppoonnmmlљ„„ƒƒ‚і€~~}}||{zzљyxxwvvuuяtssrrqppoonnmmlkіƒ‚ƒ‚€€~~§}|{{чzyyxxwwvuuttsrrqqppoonnmllўkі‚‚€~~ъ}|{{zzyyxxwwvuuttsrqqppoїnmmllkkjј€€€~~}ў|{{љzyyxwwvvіuttssrqppooіnmmllkjjiў€€~}§|{zzќyxxwwѕvuutssrqqpoonќmllkkќjiiћ€~~}}ј|{{zzyxwwvљuttsrrqq№poonnmllkkjjiihљs~}}||љ{zzyyxwwљvuutssrrэqppoonmmllkkjjihhgјy}~~}||{{ыzyyxxwvvuutssrrqqpponnќmllkkљjihhggщ|}}||{{zzyxxwwvvuuttsrrєqpponnmmlkkjjљihhgffћf{}|{{zyїxwwvvuutssэrqqpoonnmmllkjjiihgg§fe|{zyћxwwvuuєtssrrqppoonmmlўkjjћihhgffўeћUyz{zzљyxxwvvuutјsrrqpoonnљmllkkjiiќhggff§edњz{zzyyєxwvvuuttssrqqіponnmmllkjjљihhggfee§dcф|xzzyxxwvvuuttssrrqpponnmmlkkjјihhgffeddcѕryxyxwwvvuttsћrqqpoomlkjihњgffeeccbь_yxxwwvuuttssrrqqppnnmіlkjjiihhgff§edcc§baћ?uxwvvђuttssrrqqpoonmmlљkjjihhggѕfeddccbba`ѕfuwvvuutssrrqћpoonmmэlkkjiihhggffeedccbaaў`їsuuvuutsrrјqpponnmllђkjjiihhggfeedccљba`a`_ўruutўsrrqхponnmmllkkjiihhggfeedccbba``§_^іytsttssrqpp§onmmlћkjjihhюgffeedccbbaa``_^^ѕtstsrrqqponnmќlkkjjѓihggffeedccbaa`ў_^^љnrsrqqppnљmllkjjiiћhggfeeёdccbbaa``__^]]љnqrqqpoo№nmmlkkjjiihhggfeeљdccbba``љ_^^]\\ўmqqpo§nmllыkjjiihggffeeddcbbaa`__^ћ]\\[ћhqppooљnmmlkkjjєihhgffeedccbbћa``_^^§]\[[onmќlkjiiќhggffeћdcbbaaє`__^]]\\[[Znml§kjiiћhggfeedћcbaa``є_^^]]\\[[ZYўlmmlkjўihhљgffeddccќba`__^ў]\\[ќZYYmlќkjjiiъhggfeeddccbba``_^^]]\[[Z§YXљkmllkjiihўgff§edccbіa``_^^]]\[[ўZYY§XWјillkjjihh§gfeedшcbbaa``_^^]]\[[ZZYYXXWVkjѓihggfeeddccbaa`ј_^^]\\[ZZYўXWWўVўgiihћgfeeddљcbba``__ѓ^]]\[[ZYYXXWVVўUhgьfeddccbaa``__^^]]\[ZZYјXWWVVUT§ghggfфeddccbaa``__^]]\\[[ZZYXXWVVUUўTgfњeddccbbћa`_`^^§]\[[їZYYXWWVVUU§TSfeыdccbbaa`__^^]]\\[ZZYXXіWVVUUTTSRedcћbaa`__^]ћ\[[ZYYќXWWVV§UTSSўRdcћbaa`__^ў]\\і[ZZYXXWWVUUўTSSўRQў ќ  ў  ќ  ўќ  љ    § њ  њ   § ћ  ј   ќ  ќ   ў ўќ  § §   ј  ўј    ўі   њ  ќў  љ ўћ ўў §ўћ §ћњјќњќђќўќќќўћў љў§ћ ќўўќўўќ њ §ќў ќќў ћўўќ§   ўўўў ўћ ќ ўў ў  ўў     ўўћќ§§њўўўўўўўўўўќ ўў§ ѕ{zzyyxxwwvuu§tsrrіqpponnmmlkkъjiihhggffeddca_~~}}||{zyzyѓxwwvvuuttssrqqќponmmlkћjiihggяfeeddcbb^f}}|}||{{ќzyzyyўxyyўxwwљvuutssrrpo§nmllїkjjihhggffэedccbaa`^||{|{{zzyyxѓwyyxxwvvuttsrrљqppoonmml§kjiiяhgffeeddcbba`_]P{{zyxwьyxwwvuuttsrrqqppoonmmlћkjjihhљgffeedcca`њ_ZUzzyyxw§xwvvїuxxvvuutss§rqppўonnпmllkkjjiihggffeddccbbaa``_^\\zyyxxћwvwwvvђutwwvuuttssrqppoљnmmllkjjљihhgffeeљdccbba``ј_^]\[*xwwvќuvvttvuts§rqppўonnљmllkjjiigfьedccbbaa``__^]]\[Qwwљvuuvuuttќsuuttћsrrqppomlўkjj№ihhgffeedccbbaa``і_^]\\[ZWUvvutsіruutssrrqppъonnmllkkjjiihggffeedcbba`_є^]]\[[ZYV3uttsrt№srrqqppoonnmllkjjќihhggіfeddccbaa``ђ_^^]\\[[ZZXVWtts§rsrrqsqpњonmmlkkihgfјeddccba``ј_^^]\\[ZZY§XVssrќqrqppќsrrqqњpoonmllћkjjihhgљfeeddcbbѓa``_^^]]\\[[YYXњWUHsrqq§pqpporїqppoonnmllkшjiihggffeeddcbbaa`__^]]\\[ћZYYXWWљVRHqpqpponqћpoonmmlћkjjihhgэfeeddcbbaa``_^^]]\[[ѓZYYXXWVVUSHUpponјmqppoonmmїlkkjjihhggцfeddccbbaa``_^^]\\[[ZZYYXWWVјUSQ?poonnmpўonn№mllkkjiihhggffeddъcbba``__^^]\\[[ZZYXXWVVUєTSRM?nnmmlmllћpoonmmќlkjiih№gffeeddccbaa``_^^]ђ\[[ZZYXXWWVUUTTћSRQNmmlkѕonnmmllkjjii§hgffіeddcbbaa`__љ^]]\\[ZZіYXXWWVVUTSSћRQPGllkjўnmmљlkkjjihhіgffeeddcbaa`_№^]]\[[ZZYYXXWVVUUSRQќOM:kkj§imllќkjjiiљhggfeeddэcbaa``__^^]]\[[ZZYXXWўVUUћTSRRQQњPNJkjii№himllkjjiihhgffeeїdccbba``__ѕ^]\\[[ZYYXWWVўUTTќSRRQQњPOMHEiihћmlkjiihьgffeeddccbaa``__^]]\\і[ZYYXXWVVUU№TSSRRQQPPONMMEihhgёlkjjiihhggfeedccєbaa``__^]]\[[YЯZYXXWVVUTTSSRRQQPOONNMLGghhggffkjjiihhgffeddccbbaaј`__^]]\[[ўZYYіXWWVVUTTSRRѓQPPONNMMLKJIffejъihhggffeddccbbaa``_^^]]і\[[ZZYXXWVVщUTTSSRQQPPOONMMLLKIIffeeќdiihhіgffeddccbaa`ў_^^ѓ]\\[ZZYYXWWVUU№TSSRRQQPPOONNMLKKIќededdiэhggffeddccbba``__^]]і\[[ZYYXWWVVљUTTSSRQQќPOONNMіLKJJHGHddcchўgffeэdcbbaa``_^^]]\\[[ZYYѓXWWVUUTSSRRQPPOђNMMLLKJJIIHFcbbgіfeeddccba``_ў^]][ZяYXXWWVUUTTSSRRQPOONљMLLKKJIIћHGEEaaфgffeddccbbaa`__^^]]\\[[ZYYXWWєVUUTSSRRQQPOOќNMMLLэKJJIHHGGFEba``feedccba`§_^]]\ђ[ZZYYXWWVVUUTSSкRQQPOONNMMLLKKJIIHGGFFEDa`_`eeddccbba``§_^]]ћ\[[ZYYэXWWVVUTTSSRRQQPOONMMќLKKJJщIHHGGFEECC__^eddccbaa`__љ^]]\\[ZZіYXXWVVUUTSSRQ§PONNLKўJIIHўGFFDC^dяcbbaa`__^^]\\[[ZYYќXWWVVљUTSSRRQQPћONNMLLхKJJIIHGGFEEDCCBA^]]dccbaa`__ћ^]]\[[ћZYYXWWћVUUTSSRіQPPOONMMLKKJIHюGFFEDDCCBAA]\cbba``љ_^^]\\[[љZYYXWWVVTSќRQPOOњNMMLKJJIHGљFEEDCCBB@љ\[baa`__ў^]]ы\[[ZZYXXWVVUUTTSSRRQPPќONNMM§LKJJћIHHGFF§EDCCёBAA??[Zba``__^]]ф\[[ZYYXXWWVVUTTSSRQQPPOONNMLLќKJJIIцHGGFFEDCCBBAA@?>>Ya`__^^]\\№[ZZYYXXWVVUUTTSRR№QPPONNMMLLKKJIIHHкGFFEEDCCBBAA@@?==Y`__^^]\\[[ZZYYXXWVVUUѓTSSRQQPOONNMLLљKJJIIHGGљFEEDCCBBѓA@@??>==<<§_^]]ќ\[[ZZіYXWWVVUUTSSљRQQPOONNMњLKJJIHHўGFFіEDDCBBAA@??ї>==<<;^]\\[ўZYYэXWWVVUUTSSRRQQPOONMMLћKJJIHHцGFFEDDCCBBA@@??>>==<<;:^]\\ќ[ZYXXќWVVUUTѕSRRQPPOONNLLKJI№HGGFEEDDCCBBAA@??щ>==<<;:9]\\[[ZZYXXWVVUTTSчRQQPPOONMMLLKKJJIHHGGFFEDDўCBBэA@??>>==<;;:99\[[ZYYXWэVUUTTSSRQQPPOONMMLKKJћIHGGFFљEDDCCBAAё@??>>=<<;;::98[[§ZYXXћWVVUTTS§RQPPOљNMMLLKJJ§IHGGFјEDDCBBA@@?>=х<;;::987[ZZYYXWWVVUUTSSRQQPPќONNMMіLKKJIIHHGFFECBAќ@??>>ё=<<;;:99877ZZYXXэWVVUUTSSRQQPPOONNMLLіKJJIIHGGFEEDўCBBќA@?>>=ђ<;;:998876YYXWWљVUUTTSRRоQPPOONNMMLKKJJIHHGGFFEDDCCBBAA@??>>і=<<;::99877ї6YXXWVVUTTїSRRQQPPONNљMLLKJJIIіHGGFFEDDCBBљA@@??>==і<;;::998766ј5XWWVVUTTўSRRљQPPOONMMK§JIHHїGFFEEDCCBBђA@@??>==<<;;:99ё8776554XWVVUTTSSQљPOONNMLLKљJIHHGGFFіEDDCBBA@@??ќ>==<<т;::9887665544WVVUTTSSRRQPPOONMMќLKKJJHўGFFEўDCCшBA@@??>>==<<;;:9987765544§3VUUэTSSRQQPPOONNMLLKKJIIіHGGFEEDDCBBѕA@@??>>==<;;:і98876654433UTћSRRQPPOљNMMLLKJJIјHGFFEDDCCѓBAA@@??>==<<;;:ј987766544њ322TTSS§RQPPNєMLLKKJIIHHGFFіEDCCBBAA@??ќ>==<<ь;::998776654433221TSSћRQQPOOљNMMLKKJJёIHHGFFEEDCCBBA@@ќ?>>==љ<;;:9988љ76654433є211SSRRQPPONNљMLLKKJIIфHGGFFEDDCCBBAA@@??>==<<;::9887љ65544322є100RRQQPOONMMLKJљIHHGGFEEћDCCBAA@ї?>>==<;;::ў988я766544332110//RQPPќONNMMѓLKKJIIHHGFFEDDCўBAAќ@??>>ќ=<;::987љ65543322ї100/.QQPOOшNMMLLKJJIIHGGFFEEDDCCBA@@ќ?>>==<ђ;::988776654433ю2110//..QPOONNMMLKKJіIHGGFFEEDCCфBAA@@??>>=<<;::99887665544322љ100//.--љ   ў ,ў ћ  ў +њ   +ё      +ў ў ќ)§  *ћ)ў ћў)ў( ўў) ћ)њў(јћћ'ќў(њђ'ћў'ћ ў'ўўќљ&љў'ћў%ўљ &ўў&ћ ќ& ќ%ўў%є%§ј$ ўў$њ§%§ўѓ%ўє%ќўў$ќќ§$ќ$§§ћ $ўўћ $ћў $ўў$ўў$ў ўљ"ў ўќ"ўўўћ"§ў"ўўє"ўћј"ўїќ#§ўњў#ѓќ"§ї"јі#њ§ўў#њў#јўў§"ћќў"ћќ#ќ#ќ ў§"ќ ўў"ћў#ќўњ"ќўўњ"ўњ§#љћ#§њ§"xwv§uvuuts,wњxwwvvuutsr+wvutsrўq*vutsr§qrqq+ўvuutsrњqrqpqppўo)tsrqpoўn)srqћpoopoo§nm)srqpon§ml)ёrqrqqppoopoonnmml)qponќmnmllk)ќqppoonmќlmlkkќjkj(ќpoonnmlkћjkjjii(њnonmnmmlkjiўh'mlћklkkjjih§gh'mlќkjkjjihgўf'lkjќijihhgfe'kћjkjjiihgfeўd&ўkjjihgfed'jihg§fgffedc'ihgfedcћbcab%hgfed§cdcc§bcaa&gfedcba`&ўgffeќdedccba`ў_%eћdeddccba`_ў^%edcba`_ќ^]^%dcbћa``a``_^]\%њcbcbbaaђ`a`_`_^_^]^^]\\%baљ`_`_^_^^]ћ\]\\[[%a`_^ћ]^]]\\[Z%a`_^]\ј[Z[ZZYY$ў`__^ї]^^]\\[\[[Z§YZYY%њ`^_^^]]\[ZћYZYYXXW$^]\ї[\[[Z[ZZYYXњWXWWV#]ќ\]\[[ZњYXYXXWWV$ў]\\[њZ[ZYZYYXWVU$[ZYXWVUT$[эZYZZYXXWWXWWVVUVVUTTўS#ZYXўWVVUјTSSTSSR#YњXYXWXWWVUTSњRSRQQ#љYXWXWWVVUTS§RSRRQўP"ћWXWWVVUTќSTSRRQ§OP"ўWVVјUVUTTUTSSRQPO#њVUVUUTTSR§QRQQPON#ћ:UTTSSRQPONM#ј8TTSTSSRRўQPP§OPOOјNMNMMLM"ў7SSRQPOўPOONўMLLўK"6RѕQRQQPPOPOONNMLK#§65QQўPOON§MNMMLKћJKJJ"§65PPOјNONMNMMLLKJI#ќ632OONMLK§JKJJIўH"ќ541NNMLKJIHG#ћ43.NMMўLKKћJKJJIIHG#ћ430*LLKJIHGFўE"3њ1-LKKJJіIHIIGHGFGFFE#2ќ0(JJIHGFED#і210-JIJIHHGFEDC#1ї/.(HHIHHGGFEDC#і10/-'HHGHGGFEDCB#0њ.-)*GFFEDCBAў@"/љ.,'FFEEDCBA@#.ё-,(FEDEDDCCBCBBA@?#ј.--,*DDCћBABA@@ј?@@?>?>"ј.-,,*CCBA@?ћ>=>>"ј-,++)$CBBAќ@A@??>=#ў§љ § ў   ў   §ў  ў  ў§  !§  !љ  ў  !ў   !ў !ћ  !ў !ў ћ  !ў  ќ  §  !ў  ў   ў  ў!ў  ћ   ћ  !ў   ћ  "ў  ћ  §  њ  !ў   ў  ў  љ   "ў   ќ  ў ў!ќ  ў  ў "ў  ў  ў  § ў"ў  § ќ"ў  ј   ў ў"§  ў  њ  ћ$ў  ў  §#§  ќ$ѓ    ў%§  ћ   §&є   ќ§%ў 'ўў'ўћ(ўў)ўћ§)ўў*ўўќ*ўў+ћў,ќћ§,ќќ-љ.ќ§/є§.ўћ§/љ0№0ћў2ўќ2§ў4§љ4§њ4ј6ўў6њ8ў8ј8љ9њ:ћ;ќ<ўdўcbbљa``__^]]і\[[ZZYXXWVVќUTTSSќRQPcљbaa``_^^\љ[ZZYYXWWѓVUUTTSSRRQQPbўa``_љ^]]\[[ZZіYXWWVVUTTSSљRQQPPOaў^]]ї\[[ZZYYXWWљVUUTSSRRњQPPOO§a`]\њ…†ˆZYXXћWVVUTTѕSRRQQPPONNў_\ђ„…†ˆˆŠYXWWVUUTTєSRRQQPOONNMў^„†їˆ‰Š‹ŒWWVUUіTSSRRQPOONN§MLў]ѕ…††ˆ‰Š‹ŒVVѓUTTSSRQQPOONMML!ё…‡ˆ‰Š‹ŽUUTSS§RQPPћONNMLLўK ўVŽŽјŠ‹ŽTTѓSRRQQPPOONMMLLўK юzŒŒŽ‘TTSRRQPPOћNMMLKKўJ ц{Œ‘ŽSRQQPPOONMMLLKK§JI ёs‘ŽŒQPPќONNMMјLKKJJIH хsŽ‘Œ‹ŠPPOONMMLLKKJIIўH ўrё‘ŽŒ‹‹‰ˆ‡‡…NMMKљJIIHHG ўyх‘ŒŒŠ‰ˆˆ†…„ƒ‚LLKJJIIHHGG ўyьŽŒ‹Š‰ˆ‡†…„ƒ‚€JJIHHќGFF ўWэŽ‹Š‰ˆ‡†„„‚‚&Ee~‘‘GќFEE ўъŒ‹Š‰ˆ‡†„„ƒ‚}|1^‡‘‘§ED!тŒŠŠ‰‡‡…„ƒƒ‚~}|{zxxvvtte‰!т‚ŒŠˆˆ††„„‚€~}|{zywwuttrqp!тhˆ‡††…„‚€~}{{yxwvvtsrqpo!т=Ž‡†…„ƒ‚€~}{zyxwvutsrqpon!т€……„ƒ‚€~}}{zyxwvutrqppnnl"у}€€„ƒ‚€~|{zyxwvutsqppnmlk"ўc€€ч‚~}}{zyxwvutsrponmlkj"§z€€щ~}|{zyxwvusrrponmlkji#ў]€€ш~}|{zyxwutsrrponmlkjig#ф%|€€~}|{zxwvutsrqponmljjigg$х]€€|{zyxvvttrqponllkiihgf$х%€€|yxwwuusrqpnnmljjhhfed%цn€€~xwvuusrqpnmmkjihgfedc%ц%}zqpsutsrpponlkkihgfedbb&ч_wnnotsrqpommkjihgfedcb`&§%xnnьoqqoonlkjihgfedba`_'§?tnno№mlkiihffedcaa_^(ў0nnяmlkiihfeedca`_^])ўennюmlkjihfedcba`_^\\)ў'nnюlkjhhgfdcba`^]][[)ъcnnmjhgfedcba`_]]\ZY*ы lnnkggedcba`^]][[ZX+ьCnnmheccaa`^]][ZYXW+ь ^nnldcaa_^]\[ZYXWV,э knnkb`_^]\[ZXWWVT-юInnmd_^]\[ZXXWVTT-юgnnj^\\[ZXXWVUTR.ў nnѓa\[ZYWVUTSRQ/№Vnnk`ZXXVUUSRQP/№ cnncXWVUTSRQPO0ё _i_WVUTSRQONM1ђ>WUUTRQQONML2ѓLUTSQQPNMLK3є$TSQPONMLKJ3є:RPONMLKJI4ѕ FONMKJJIH5і!NMLJJHGF5і6KJJIGFE6їKIHGFED7јHGFDCC8љ%FECCB8љ0DCB@9њ.AA?:ћ-?>;§+< ў&=ќЁ  ;ќЁџУ;ќЁџЭ;ћЁџїa:љЁџ§џћ‹8ўЁџџћљo5ўЖџџњёЈT3ўтџџњсЈh&1џўўџџњјч—8/џў§џџћк,-џўўџ џћсˆ*+џўўџ џњсŒ)(џў§џџјђГZ! $ќЕџ§џџїьСš…‚qB ќ[џ§џџўѕў/џџ§ тџџ ў’џџ ўAџџ ў џџ!ўЏџџ!ў.џџ"ўЕџџ"ўџџ#ўЕџџ#ў+џџ$ќЕџўџџ$ў-џџ%ќЕџўџџ%§)тџџ&ќmџўџџ&§Шџџ'ќXџіџџ'§Еџџ(§)тџџ)ўmџџ)§Еџџ*§&тџџ+ўiџџ+§Еџџ,ў,џџ-ў›џџ-§тџџ.ўRџџ/ўЏџ џ/§Еџ џ0ў,џ џ1ў‚џ џ1§€џ џ2§тџ џ3ўRџ џ4ўjџџ5ў‡џџ5§ Еџџ6§Еџџ7§+тџџ8ў#џџ9ўjџџ:ў‡џџ ўў§ўќ   ћўўўў§  ўў   ў  ќє јё ќўќљ ћєў§јўў§ћўўњ  ўї  ў њўћ ќў§ ўўњ јўћўњўњ ў§§ў§ў ўњ њ ў §њ §§ўќ  ўћў§  ўњў§   ў§ўќ  ў §ўў  ўњњ §  §ў ќћ  ќњќ ў  ќў§њ  ў љќ§ј ќћ ћј§є ћўў ўўўў њ§ ўѕўћ ќћ јћ њѕњ ќќќ § ўћўќўќ  ўўљўўўўўў§ ўј§ќ ќ ў  § юPOONMMLLKKJJIIHGGFFјEDDCBBA@@?ќ>==<<ѓ;:9887766554332ѓ100//.--,OONMMљLKKJJIHH№GFFEEDCCBBAA@??>>ѓ=<<;;:99877655ў433ъ21100//.--,,ONMMLLKKJIIљHGGFFEDDіCBAA@@?>>==<ј;::998877ѓ65443321100/..,+іNMMLLKJJIHHўGFF§EDCCBўA@@№?>==<<;;::9988766ѓ544322100//.--,+MѕLKKJJIHHGGFFоEDCCBBAA@@??>>=<<;;::99877665443322ю10//..--,++**LLKKJJљIHHGFFEEљDCCBAA@@>=ў<;;:ђ988776654433211ћ0//.--ѓ,++**)LKKJIIHH§GFEEDпCBBAA@??>==<<;;::99887765544322100ю/..--,,++**)(KJJIHHGўFEEDяCBBAA@??>==<<;;:99№877665544332110//-,ќ+**))ї'JJIIHHGFFђEDDCCBAA@@??>==<і;:9988776554ћ322100р/..--,,++*))(('JIHHGGFFEEDDCBBA@@?ў>==<њ;::987765ћ433211љ0//.--,,+ћ*))(''IюHGGFFEEDCCBBA@@??>>љ=<<;;:99ѓ87765544322100ќ/..--ѓ,++**))(('&&HH§GFEEќDCCBBіA@@?>>==<;;ё:9988766554433110/.љ-,,+**))х(''&&%HHGGFEDDCCBBAA@??>==<<ѓ;::9987766554421і0/..--,,+**ю)(('&&%%$GGFEEDDCBBAћ@?>>==љ<;;::9886543№21100/..--,,+**))ђ('&&%%$$FFEDDCCљBAA@@?>>љ=<<;::99ћ8776554А322100//..--,++**))(('&&%$$##FEEDDCBBAA@??>>==<<;::998877655443321100//..-,,+**))ќ(''&&ю%$$#"EEDCCBBAA@@?>><;љ:99877664ѓ3221100//.--,,ј+**)(('&&%њ$##""DD№CBBAA@??>>==<;;::ё9887665543322100/ћ.--,++ѓ*))((''&&%$$##ї"!DCCBBA@@і?>>==<;;:99ќ87766і544322110//є.--,++**))(''є&%%$$##""! ‘‘?ђ>fec<;;:99887665э43321100//..-,,++*))Г(''&&%$$##""! om.@Qhz‚fdcba`_]]\ZY7665443322110//..-,,++**))(''&&%%$##""!  уnmlkihgfed#Rzƒ_]\[ZZXW5544322љ100/..--љ,++**)((&љ%$$##"!!к mkjjhggedbba_^] 9Wn†WVUT3322110//..і-,,++*))(''ћ&%%$##н"!! lkihgfedcba`_^\[ZY@oUSS322ъ100/..--,++**))((''&%$$#љ"!! оjihfeedcba_^]\[ZYXWUYRRP2110//.--,ќ+**))љ(''&&%$$з#"!! iggfddcba_^]][ZYXWUUSS)nON00//ј.--,,+*))(э'&&%%$##""!! уhgfedcaa__]\[ZYWVVTSSRQP=‘‘..ї-,,++*))((ў'&&ќ%$#""!й ffdcba`_^][[ZYXVUTSRQPONM&n‘--ќ,++**љ)((''&%%і$##"!! рedcba`_^][ZZXWVVUSRQPOMMLKa‘,,++ћ*))(''§&%$$#љ"!! ўзdcba`_]]\ZYYXVUTSRQPNNMKJJHG`‘++**)((''§%$##"љ! йcba__^\[ZYXWVUTSRQPONLKKIHGFn‘*))ќ(''&&§%$##ћ"!! дb`__^\[[YXWVUSSRQONMMKJIHGFDD t*(('ў&%%$ј#""! §мa`^]\[ZYXWVTTRRQOOMMKJIHGFDDCB6‘(('&&%ћ$##"!!ћ Ы`^]\[ZYXWUUSSRPPOMLKJIHGFECCB@?o(''&%%$$#""!  ўХ^]][ZYWWUTSSQQONMLKJIGFEDCBA@?>H‘&&%%$$#""!! іе]\[YYWWUUTRQPONMLKJIHFEDCBA@?>=<‘‘%%$$##""  §ћж\[ZYXVUTSRQPONMLJIHGFEECBA@?>=;;f‘$$##"я! ”ZZXXWVTSRQPNMMKKJIGFEECBA@?><;:9'‘$##""!! YXXVUTSRQOONLKKJHGFEDCB@@?==;;987…‘#"!!  іќжXWVUTSRQONNLKJIHGFEDBBA??=<;:9976n‘"!  ЙWVUTSRPPONMLJIHGFDCBB@@?><;;986544‘!! ўќйVTSSRQONMLKJIHGFECBAA@?==;:9865543‘! ТUTSQQOOMLKJIHGFECBAA?>=<;:88754321‘‘ќљЭTRRPONMLKJIHGEDDBA@?>=<::887653210‘‘јљзRQPONMLKJIGGFDCBA@?>=<;:987543210/‘‘љўЩQPONLKKIHHGEECBA@>>=<::976543210/.‘‘ўШPONMKKJIHFEDCBA@?==<:997754321//.-‘‘ћЮONLLKIIGFEDCAA@?=<;:9876543210/.-o‘‘љЧ NMKKIHGGEDCB@@>>=<::87653310/..,+*‘‘г LKJIHGFEDBB@?>=<;:986654310/.--+*)‘‘я   гKJIHGFEDBA@??=<;:987654210/.-,+*)(‘‘Э JIHFFECBA@?>><;:987643210/.-,+*)(‘‘ќ§ќг IGFFDCBA@?>=<;9987653220/.-,+))'&‘‘ёћ  м HGFDCCA@?><<;9986643210/--,+*('&%‘‘ќѓ   г GEDCBA@>>=;::876543110/-,,+)('&%$‘‘љЫ FDDBA??><;:9976543210/.-+**('&%$‘є  б DCBA@?><;;:976543210..-,*)('&%$#*‘і  Ш CBA?>>=<;:876542210.--+*)(&&%$""G‘і жB@?>><;:986553221/.-,+*)('&%$#! d‘ю нA??=<;:987653211/.-,+*)(&%$$"!!mћћ  і н?>=<::986654210/.-,+*)''%%##! cѓ    й?<<::986553220/.-,+*)'&&$##! љ§    д=;::987544210/-,,*)((&&$#"! §   ў  љ Ю<::876544210/.-,+)(('%$#!   ё РљЫ€q_,Ё2џўўџџўѕџџ§ю=+џќ§в*џќћХ)џќћв*(џћ§юb&џ§Ж%џ§e#џ§ТF"џ§сr!џ§ў‡ џ§ўJџў›џ§ыџўЂџ§іџ§Њ џўm џўЏ џ§у!џў’!џўр!џўу"џў"џўв"џўв"џўП"џўП"џўП"џўП"џўЏ"џў~"џў^"џўI!џ§д!џўK џў№ џўУ џўnџ§уџў€џў)џџџы#ѕ§#ќ§#ѕљ#ћ§ў#іў#њќ #ўћў #ў#§ќ ўќ"§#ќћ"ќ §#љї#ќ$ћќ#ќ§ќ#њќ$љ $§ў$њј§#їў$њў %ў%ў§ %ќ §$ўњ ќ$ў %ќў&ўў&ўўќ%ўћ%ћ§&ўћ&љ§' ќ&ў§&ћ'( ў'ў(ў (§ )§ )) ў)ў2 ў+ўћ1ў3 3ќљ2ћ4ў4ў4њ3§ў3њ5љ3ў5 5 4§5ў0љ,+**)'BBAњ@A@?@??>=ћ<=<<"ы,+**)'AA@@?@??>?>=>==<;#ј+*))(&@@ў?>>=<;:#і*)(('%"??>>=ќ<;<;;:9#)ѓ(''%>==>==<<;:9ў8"('ј&% >==<<ѕ;<;;::9:9988ў7"§('&&ќ$#<<;:ћ9:99887#'&ћ%$!;;:9ў8776#&%ћ$"!;;:9876ќ565"і&%%$##"::§8988765§45"%ў$##§"99ў877654ў3"$#"§ 8876543ў2"ѕ$##""!877і656554544332##ј"!! 6654321#"љ! 554321ў0#ў"!!ј454433210$є! 4433210/$ ўі432322110/ћ./..#ћ њ22110/.-$ўѓ2110100//.-ў,#њ00/ќ.-.--,ў+#ј//..-ў,++$і/..-,ј+,,++**$і..-.--,ў+**ў)$№--,-,++*)ў($ї,,+*)(ў'$є,++*)('%ќї++)*))('&%і*))('ћ&'%&%љ))('&%&ђ('(''ў&%%$&ўљ''&§%&%%$#&ё&&%&%%$#ў"%№&&%$%$$#ќ"!"%є%$$ћ#"##""!'ўљ $$##"! 'ќ##"! ў&§њ #"!!ћ ! §&љ "!!  њ'љ !  (ј  ў'ђ ў'љ )і )ў  љ ў(є ј) ї * ј ў*ў   ћ*ў  љ +ї њ+ ї+§ ќў+ўљ,њљ,љ§-ўќ§,ћћ-ћў-ѕ/ћ/љ /њ ў /ўў  0зў'>ўП=§*=ў:§‡џџ;ћ Еџџ;ќЕџ<§Е=ўПўљ ўў§ќ ўњќ ќўњ§ §ўў§ §ў§ќ ўќ ўў§ћ§іў !їќ$ќў' њў ў§ў&ў§§)ўўўўўќўўљў#Rў9ў$ћ$>ў ў,§:ўў?ўлж;987654320//.,++)('&%$#"!   С )87654320/.-,++)('&%$#!!    љ д'654221/.-,+*)('&%##! № љй43110.-,+*((&%%##"     љ їл#21/.--+*)('&$$#!   ѓ ќс"0.-,+*)(&&$##!    њ ўќь -,+*)('&%#"! ј љ  ѓ б**)(&%$#"!   ќ ю)''%$#"! ѕ    §ју&%$#"   љ љя$#! љ    ѓўл"   §  № ю ў § к  ў ђі ћ ѓ їў ќы  ўўю §ё ўќѕ їњ §ў ўўќ  #ў ў'њќў+ў7ў7ўў:žџџџ џ§џЕџџќџ џџџќ џџџ§Еџџџ§ ‡џџџ§Uтџџџ§+Еџџџ§Еџџџ ќ mтџџџ §+Еџџ џ§5Еџџ џќ mтџџџ§€џџџ§5Еџ$џ§5Еџ!џ§5Еџџќ€џџ%њ"9I џџ,њ+.A џ џ3њaЖтџџ;ў}ўX6ќ4њ6§6њ5љ5ќ7§7љ5;ќў6>ў=ћ9 ~ў  ў 4 ї 4  ћ 4    5   5  ў4 5ў 65ќќ5§ў67§8§99ў:ћ:ў ОAџ;џ;џ<џ<џ=џ=ўџ=ўџ ў€€@@headџ     TzвzюЭГЭП{:{Jˆ}šš%š5Ў[ЦЧЦзЦчЩЫЭcЭsЭƒЭ“ЭЃёў8ђJ…Бау€bd\=,ыFvЃЩсѕќјђэьюЪ’m6,)љ -kШіќџџїќћыМ|4'%љ[Ояњџ џљщТ}#("њ+…рјџџљ§ьЂ= њ@ЏшўџџћјМVњ8БіўџџќќЮgћ,Ѕјџџўкћ’єџџќzыџџќ^кџџћ:Пўџџќ‰ђџџћFХўџџќ“јџџћVн§џџќˆєџ џќGмџ!џќ oяџ!џ§&Цџ"џќCпџ"џќєџ"џќГ§џ"џќ>Ъџ#џќyёџ#џ§Šџ$џќŸћџ#џќEе§џ#џќNэўџ#џќMэџ$џќ cыџ$џ§–ёџ$џ§Тњџ$џўЩџ%џўСџџљЪ__Ъџ џўКџџ§ћa§aћџџ=ќ7њ 4 § 1љ  0ќ    . ќ  -ї  +ћ  ў *§    ў  (§ љ &ќ  ў   ў  &§   і  %ў ќ  љ #ў      §    #ќ     ў   ў !ў њ   ў  !ў  ќ  ќ  љ ў     ў  ў  ў  ў  ў  і  ў  ў  ћ   ў § §  ќ  њ  ў  §   њ  ђ  ў  њ    ў  ў  ўњ    я P‰Гбу„ghaC%  ўў  р LzІЪтѕќјђэьюЫ•r<2#  ў  ё 4pЩіќџџєќћыО€;. њ  ї `Ряњџ џјщУ)/ љ  њ 3‰сјџџљ§ьЄC№ FБшўџџћјО[ў  ї ?ГіўџџќќЯkќ  њ 3Јјџџўлў  ќ&•єџџў  ќ~ыџџў  љ cлџџ§  ћ @Сўџџў  ћђџџў  ћ KЦўџџќ  ќ!–јџџў  ћ [о§џџў  ќŒєџ џ§  ћ Lнџ!џў  ћtяџ!џў  §-Шџ"џќ   ќ Hрџ"џў  љ “єџ"џў  ќ"Е§џ"џў  ћ DЫџ#џѕ   }ёџ#џћ §џ$џў  љ %Ђћџ#џѕ  Jж§џ#џў  ќSэўџ#џѕ   Rэџ$џћ gыџ$џў §™ёџ$џњ  §Уњџ$џўЪџ%џў ўТџџљЪ__Ъџ џќ ўЛџџ§ћa§aћџџ=ќ[ch7ћ^huА5ќ`m‚2ќRh|‘ў/ќ\mАў‘.ќZnњ‘ŽŽ-§jˆў‘ާŒ*§dz‘јŽŽŽŒ*ўm§‘ŽŒ‹§Š‹'љby‘‘ŽŒ‹Šў‰&ќi‰‘ŽћŒŒ‹‹Š‰ўˆ%§n‘ўŽŽќŒŒ‹‹іŠ‰‰ˆ‰‰‡ˆ‡$§s‘ŽŒў‹ŠŠ‰ˆ‡†$іvŽŽŒŒ‹‹ќŠ‰‰ˆˆ‡ћ…†…„"їxŽŒ‹‹Š‰ˆ‡†ў…„„"ќxŽўŒ‹‹Šљ‰ˆ‰‡ˆ‡††…„ƒ!§wŽќŒ‹‹ŠŠ‰ˆў‡††ќ„…„ƒƒ‚ўєsŽŒŒ‹‹Š‰‰ˆˆј†‡††……„ƒƒў‚€їpŒŒ‹ŠŠ‰‰јˆ‡‡††……„„ƒ‚ћ€€яmŒŒ‹ŠŠ‰‰ˆˆ‡‡†…†„„ƒ‚љ€~~ђh‹Œ‹‹ŠŠ‰‰ˆˆ‡†……„ƒ‚ў€€љ~~}~}ю}Œ‹ŠŠ‰ˆˆ‡‡††……„„ƒ‚‚ќ€€~}|ѕt‹‹Š‰‰ˆˆ‡†……ў„ƒƒ‚ў€~}|{ўzќm‹Š‰‰‡…„ƒ‚ѓ€€~~}}||{{zрd‚ŠŠ‰ˆˆ‡†……„„ƒƒ‚‚ŠЅТич№ОЎЏЋ›‹~{zzyќu‰‰ˆˆ†т…„„ƒƒ‹ЃЛбфяљ§ћјѕѕіуЦВ–‡xyxwwэl‰ˆˆ‡‡†…„…ƒƒˆ˜Еуњ§џџє§ќєлЙ“‹ƒwwvя|ˆˆ‡‡†…„ƒƒ‚ŠЎоїќџ џјѓоЙ‰‹yu№pˆ‡††……„ƒƒ„—Тяћџџљ§єЬ–|ќf‚‡††§…„ƒƒћ зѓўџџћћкЂ{ёq‡‡……„ƒƒ‚ƒœињўџџќ§уЊђg„†……„ƒ‚‚ƒ–бћџџўъѓr……„ƒƒ‚Шљџџѓc‚…„ƒƒ‚€‰Мєџџєp„„ƒƒ€ƒЎьџџє|„ƒƒ€€œоўџџўmƒƒњ€ˆУјџџєvƒ‚€€~ сўџџєh‚‚~~‰Чћџџєp‚€~~Јэ§џџѕx€€~~}‡Сљџ џѕj€€~}}|Ÿьџ!џѕp€~}}|Гіџ!џіv}}|{сџ"џѕh~~}||{|œюџ"џѕn~}||{zФљџ"џѕq}}|{zz†ж§џ"џіv||{zyz˜тџ#џѕh||{yyxyЗїџ#џіm|{zzxwzРџ$џѕp{zyxww†Ыќџ#џѕrzzywvvšш§џ#џѕuzywvuuŸѕўџ#џѕgzyxwvuvѕџ$џѕkywwvutyЈѓџ$џѕmxvvuusrФїџ$џѕowvuttsrнќџ$џіpvvussqqрџ%џіpvttsrqpлџџљЪ__Ъџ џіqussrqpoиџџ§ћa§aћџџ=ќlЫђ7ќƒюўџџ5§јџџ2§фџ џ0§=ѕџ џ.§"ѕџ џ-ўсџџ+ўŠџџ*ў№џџ(ўWџџ'ўНџџ&ўъџџ%ўњџџ$ў§џџ#ўўџџ"ўўџџ!ў§џџ ўњџџўюџџўЫџџўyџџ!џўњџ џўФџ!џў'џ"џўќџ"џўЎџ#џ%џўфџ$џўџ%џўђџ%џў1џ&џўѓџ&џўџ'џўчџ'џ)џўЙџ(џўўџ(џўBџ)џўчџ)џ+џў^џ*џўъџ*џ,џў&џ+џўРџ+џўњџ+џ-џў)џ,џўЋџ,џўюџ,џўўџ,џ.џў џ-џўkџ-џўЕџ-џўуџ-џўіџ-џў§џ-џўўџ-џђFZ`~ѕсР™vF/ы 6m’ЪюьэђјќѕсР™vF)ј4|МыћќџџљќѕТk- &њ#}Тщџ џљњьМ[#њ =Ђь§џџњјн…+ў ћVМјџџњўхЏ@§#ћgЮќџџњўѕБ8ќs#ќsкџџћїЅ,ћуuќuуџџћѓ’њќз^ћ^зќџџќъzєџљНGGНљџџќк^џїњА;&;АњџџћўП:џљѕŠ/Šѕџ!џќ№‰џћкpwкџ"џћўХFџУ%џќї“џі%џћ§мV -џќђˆ .џќлG .џќьo /џ§Ц& /џќмC /џќђ /џќ§В 0џќФ> 0џќяy 1џ§Š 0џќћš 0џќ§ЯE 0џќўъN 1џќыM 1џќыa џьўюаЈ}U33U}Јаюўџ џ§ё џцєЛb8LL?*.G\f^@bЛєџџ§њЛ џђбY$1EtœНжъџџѓъжНœtEL_/YбџџўС џїл<"2‚ШџџјШ‚2EQ<лџџўЖ џц›cЧўюаЈ}U33U}ЈаюўџџњЧc2K›џџўЏ §  ћ ў/   ў  ћ +   ў  ќ( ќ  ќ% ў  ў  ќ # ў  ў  ў  ќ! ў  §   ў  ў  љ   ѕ  ј   ў   ї  ќ  ћ       ћ  і  ў  љ    ќ  љ  њ   §    љ    ў  ў  ў  ў ў ў  ўў  ў  ћ  ў ў  §  ў ї    ў ў  ў  ў  ў  љ   ў   ќ   ў  ћ  ў  ћ   њ   љ    ї    ў ћ   №       љ   §   і    ї   љ  ў  њ   ў  ў §    ў  њ  ћ  ќ   § ќ  ѓ "K_e‚ѕсСœzKў ў ў ў ј   ь §ГссўкссљhЉссЈ ќDЪрссўЩссњ‰Иссо ќLУссўЋсс§лЯссўr §-šссў{ссўпссќк љVœкснс сў8сс§Іћ/i›Чсс§ Хсс§Pђ4c—Црсс§cссќжљlФўОссўЛўўссў{3ў.ссћоJ1ў ссњрн“1ўссрќЉ 1§ЎссрќУ 1ќ'œссрћж_ 2њ8‹КдррњопЉ5ѓ Ёнрйпиx6§‚ррњЬa)ў-§œрр§x іqtsrqpooжџџњa#ЧЧ#ўaџџѕqsrqqoonж§џџљЪЧџџЧўЪџџѕrsrpponmйќџџљ_ЧџџЧў_џџѕrqqponmlпќџџљ#ЧЧ#ўџџѕqrqpnmmkщќџџўўџџ§Дpјonmlkђ§џџў_ў_џџ§й"pїonmlkjњ§џџўЪўЪџџњwonљlkkiьўџџўaѕaџџѕ*ѕonmlkkiiдќџџ§ћaїaћџрѕmnmlkiihАљџџђЪ__Ъџџзѕlmlljihg—ёџџњоmїkjihhf—чџџњяєlkkjihgfxйўџџћєmkjihggetЦћџџћSєmkihhffekВјџџћЌєmjihgfeddєџџћїєlihgfedcb“№џџќV ѓkhhgeedcaŽщўџџћз ѓihgfedcbasЮјџџќ& єhgfdcba`g шџџќЧ ў єjfedcba`_€жџџќ#ўўѓlfecba`__~Фўџџќл ў5ѓlddcba`_^oЏѕџџќMўўMѓjdcba`_^]]‚аџџќ§ ўJѓfbaa`^^\[zЋћџџќК ў;ђjca`_^]\[i“эўџ џќC ќ6uђlba__]][[ZvЗїџ џ§ ќSЉШёja`_]]\[ZXq‰эўџ џќг ќ|гођf`_]\[ZZXZnЪњџ џќ{ ќ{змђj_^]\[ZYXWq‡шџ џ§' ќpЫЭ№k_]\[[ZXWWR8& ћ.ƒоџџ§ ќlЦЦфc]\[ZYXW/,fujxh.•џы ќhССфj\\[ZV.yпђэсЦЫЊm +€ ќPЋэj][ZXЎёєєјєуЦЦЊ_њ 2  ў ќ"U…юe[X$cјќћїьцХolN §ўI№kU'ќ§ќјбN§ў ў3ё.pј§ќэ}ў'ѓ8>іјяЛSўѓЧіыWђNђђМёЗяыy  љзъе5љ ўї0ЙЫ ќ ўї0~?ўї--§ўќўњўќўњў§ўў ўўў ўћ ўќўљўўі ўў ў§ ў ќ"§§)§ ўў§ћў#ўњ 5ўј ў§ўі њљ!є ќ*ў  ћћ,ў  §ћ ў/џ/џ/џ/џ/џ/џ/џ/џ/џ/џ/џ/џўўџ-џў§џ-џўіџ-џўуџ-џўЕџ-џўkџ-џў џ-џ.џўўџ,џўюџ,џўЋџ,џў)џ,џ-џўњџ+џўРџ+џў&џ+џ,џўъџ*џў^џ*џ+џўчџ)џўBџ)џўўџ(џўЙџ(џ)џў€џ(џќџўџ'џ§їџ(џ§)џќ7їўџ(џќ–№ўџ(џ§кчџ)џ§љкџ)џ§џвџ)џ§џжџ)џ§љъџ)џ§кљџ)џ§–ћџ)џ§7ћџ)џўўџ)џ§—ћџ(џќџќџ'џќhяўџ&џќУзћџ%џћцТыџ$џћуађџ#џћДѓѕџ"џњTњшбѓџџєj№ѕнтцшљўўќџџѕ!wЦёўѓШХЭјџџ$ћОБћџџ%ћ уЮ§џџ џтŠXЫЛb8LL?*.G\f^@bЛєџџћеX`ŠџџўЎ џяЪY$1EtœНжъџџѓъжНœtEL_/YбџџљžfЫџ§В џі<,"2‚ШџџјШ‚2EQ<лџџњОџњК яЮN #,9P0KcЧџџњЧc2K›џџћЦџњШ ђЃшюяюхХZ EбіџџћеX`Šџџ§ћк §ХюяяіюыН3'кџџќџџќžfЫџџ§ќъ яўыяяњюьyџџ§Оџџ§§џ яюћыl0јџџўЦџџ§ўп яюќЕ$рџџ§ћЗ яіюэюяююГзџџ§ѕ{ яюќоџџ§щR яё яюќn яџџ§иS яёўэя яљюьm$џ§џџќўС" яќёђня яћюс[џџќњЃ яѓўИя яћюŸВџџ§є‚ яћёѕєИя яћюŒїџџ§юa яћђѕєЎяяќуVџџ§шC яћєїѕЕяяћюŒзџџќўн+ яћіљѕ•яяќэ6-џџ§єБ љђѓјјѕŽяяќЪЭџџ§мi љіїњћј†яяќю™=џџ§П1 љјљќќћŽяяќы1тџџќўЄ јњћћ§ќюяяќюž`џџќёƒ јњќќ§ќDюяяќЫ§џџ§З= јћќќ§ќэяяќшКџџќљ §ўяяќюnGџџћўх[ §ўяя§‘џџќє“$§ўяяќЩгџ џћўфLўќ§§ўяяќщ{џ џќјА%ўћ§§ўяя§B*џ џќнKљљќќ§§яя§Žџџѓоˆ9-Qƒљљћќ§ќяяэйыџ•#sЎиђћѓкБmљњћќ§ќяяѕэ€,ИяѕњћќќјћјђЛQ јћќћћњыяящюjЉёяяѓјљїѓѓѕљїѕ№яЙ' јќ§ќћњэяяќТёёяяў№яяќђѕѓяя§\ јћќћћњэяяўюяяјэ˜g_sаяяќx љљњњћјяяєыНПкрбЌr.oюяя§i љєѕљљјя"яњR oЦьяя§AяћїњїFя"яљ`UряяќЫwяћїјїuя!я§о§шяя§k%яћѕїіšя!я§c/ў›яя§бљэяёѕѓЙя яќ• §яяў0яќђѓЮяяўЂќLŽяя§{яќёђояяўќП@яя§Дяќёф№яяўiќчХяя§йяўшяя§Х*њHяІ’яя§ъяўыяя§пV њ ДяДoяяўъя§Я4 љэяФ’яяўйя§ЊN љ™яямщяяўЗяіыяшЈb љ ъяяэяяўяїдЇq8 §Гяяў9 яѓэгЃn91"§ Sяя§б  яјюНK ќуяя§i§BЪяяќщ•ўПяя§Ыћkшяя§хћ ^юяя§< љдявќ+œшшўэяя§l њЋћŸшшўщяя§v .ћ@Ашшя§c ј-XmMћЪшшњщяЕ( ё#Cv•ЙООННЎrdNћcршшў>ќЛМПРРПНќMћАшшњнШ JўПРРОїРПРПРПЃ4 є}ршшцЛ(ђЛМИММРРПРПМІЛРРћМ”MћeгшшўLћНООПРРїПРМ™˜АМПРРќПЃ4ќЊчшшў  џтŠXЫЛb8LL?*.G\f^@bЛєџџћеX`ŠџџіЏ џяЪY$1EtœНжъџџѓъжНœtEL_/YбџџіžfЫџ§Гў џі<,"2‚ШџџјШ‚2EQ<лџџњОџњЛњяЮM !*5M.KcЧџџњЧc2K›џџѓЦџњЩђ™крсрзЙT EбіџџћеX`Šџџ§ћкў§КрссірнВ0'кџџќџџќžfЫџџ§ќъсўнссњроˆyџџ§Оџџ§§џў срћоe0јџџўЦџџ§ўп срќЊ#рџџћћИ сірпрсррЈзџџ§ѕ}ўст срќzоџџѕщTсф срќh яџџћиVсћтццрс сљроg#џ§џџєўС&сћучшвссўтссћрд[џџљњЄ§сћуъыАс сћр•Вџџ§єƒўсћхььАс сћр„їџџ§юcњсћшюэІссќжVџџєшEљстэёюЌссћр„зџџќўн.ўљсуяѓяссќп2-џџ§єВќўљчыѓѕю†ссќОЭџџ§мkўўљюёљјђ~ссќр<џџћР4љѓѕљћљ‡ссќн/тџџјўЅўјїљћќћŠрссќр•_џџњё„ ўјјњћќњBрссќП§џџњИ@ўјїћћ§ќпссќкКџџјљўќ§§§ќссќрgFџџљўх\ўўќ§§§ќсс§‰џџќє”'§ўўќ§§ўссќНгџ џљўфNўўќ§§ўссќл{џ џњјА'ў§њќ§§ўсс§>*џ џќнMўљјњћќќсс§†џџѓоˆ9-Qƒ‘ўќљѕїќ§ќссьЬыџ•!nЉеяљђйЏiўљїљћќћс стсъп€+АсэіљњњћћљєшАLўјљћћњјнссшрeІцссъѓѕ№ыщэєёэус­$ ўјњќћљїпссќИххссќтутссћчьщтссљW јјћћјіпссћрсстссјпaYl”Уссњq љѓіјјѓссўтссєнВДЭвФЂl+iрссќcљъэѕіѓс"сњNiКосс§>сћђіђAс"сљZPгссќПpсћ№ѓ№nс!с§б§ксс§d#сћьёю‘с!с§],ў“сс§ХљпсцьъЏс сќŒ сў-сћтщъХссў˜ќH†сс§sсћхшдтссўˆќГ<сс§Њ сћтцйуссўcќйzКсс§Ьсќтлтсс§Й'њDсœ‰сс§мсўнсс§вR њ ЊсЉhссўмсќУ2 љпсИ‰ссўЬс§ I љссЯлссўЌсінскž\ љ мсспссўzсїШj5 §Јссў6 сѓпЧšg6. §Nсс§Х сјрВG ќжсс§c§>ОссќлŒўЕсс§Пћdксс§зћ Zрсс§8 љШсХќ*—ррс§f њЁћ™ррс§o .ћ?Њррс§] ўћ УррћсЊ& ўћ`иррў<0ћЊррњжСšG0єxирроД&1ћaЬррўI3ќЄпррў  џтŠXЫЛb8LL?*.G\f^@bЛєџџћеX`ŠџџіЦMMNNOOPS џяЪY$1EtœНжъџџѓъжНœtEL_/YбџџёžfЫџ§ШKLLMMNNQ џі<,"2‚ШџџјШ‚2EQ<лџџіОџћЮKKLLMMўO§ЮEєJcЧџџњЧc2K›џџћЦџћзJJK§LMђ  EбіџџћеX`ŠџџѕќфIHIJJKKL§і!кџџќџџќžfЫџџњќяGGHIIJўњyџџ§Оџџѕ§џFGHGHIIJ ќ%јџџўЦџџјўчEFFGGHH ќрџџ§ќЪEEўFGGўI ізџџѕїCCDDEEFHћ  ќиџџѕю~BCBCDEEJћ$$ўќяџџѕс~@ABBCCDLћ66§ љџ§џџљўаY?@ABB§CNћHL"§ ћ[џџєћЙP??@@AABQћ$ae, ћВџџєіŸ==>??@@AUћ2ol, ћїџџєђ…<<==>>?@YљL|x ќVџџєэm;<<==>>?Zљt›{ћзџџѓўф[9:;<<==>Yљ‹Ѓ‚ ќ-џџѓіТ899:;;<<=Tљ8dЊДќЧџџєуˆ87899:;;Cљz˜ЯбЃќ#џџћЬ[6788ћ9::LљЇИчэйќтџџѓўЖD56767899UјПеяѓш&ќ\џџѓѓ›745566778YјЯйяѓшќ§џџѓХc233556678Uјгц№ѕы ќКџџѓњ—=22334456Aљюіљїєќ>џџћўщy0112ћ344Oљјћћќј§џџђѕІK//0022344Xљјћќ§§ќгџ џёўшk1../001123U§ѓљ§§ўќ{џ џђљНJ,--.//012Bљшёњќћ§$џ џђтh.+,,--//01SљЬкъђэ§џџшоˆ9-Q„œ?**++,,-../WљМЦэѕ№ ў уыџ• cЅдшчЩ”.)**+,--.>љЪгыяч §у€# nИапрщфвЈK )*++--SјлъъуЮў у s1QБŠ]PyЋp ()*++TјуыызХў і &+ћ7hLљ')+CјбхубПі §ќ&)UљЅДЭЬЎњ ћќ4љSpЖНЈќ ќ§&ћžУž"ў§ ќћŽЋŽ!ўўўћq—~ !ўў ўљ:n` ў њMV0ў§ўњ0E:ўќўћ2(ќќўќўњўў§ ћў§ љў§ њўњљўќќў ќўўў ћўўў§њўў ћ§ќ љ ўљў њћ ўў ћњ ў ї ћ  ќћ љ§  ўћў  ћ!ќ ј ўўќ §  ў!ў§  ;џ;џ;џ;џ;џ;џ;џ;џ;џ;џ;џ;џ:џўў:џў§:џўі:џўу:џўЕ:џўk:џў :џ9џўў9џўю9џўЋ9џў)9џ8џўњ8џўР8џў&8џ7џўъ7џў^7џ6џўч6џўB5џўў5џўЙ5џ 4џўѓ5џў4џ§ќš4џ§ў§5џ§ј75џ§ѕ™5џ§јп5џ§ќњ5џ§њџ5џ§ћџ5џ§§љ5џ§ћк5џ§њ–5џ§ћ74џў4џ§ћ“3џќўџ)џўџ§њu2џ§љЬ 1џќіъ 0џќјц ,џљљєюљР +џњтuињT )џњњцѕ№j%џјјіўђЦw!$џќЋR#џќЊ: &ќPЇшш§4 ѕTНРПДЎЗПРР'§Ёшшіо‰ПРРППР)§ˆшшћи‰РРўМРР+ўшшјкeРРПДРР,§ гшшћт`JБППРўП,§~шшњЃ†ХРППР.ќ$жшшѕйf/…СРРПЛЛ/§vшшњЮc gžРР1ќ…шшљм1Mu4§BлшшќпР’6§>Єшш7ї  Ышш:ћ H П&ќMЁррј2 0§›ррќз5§„рр§б7ўррќв6§ Ьррћк]%ў0§zррћ`!ў/ќ"Юррњбb"& 4§rррћЧ`%4ќррљд˜$ 4§@дррќиЙ6§<žрр7ї ˆФрр:ћ E П&ќ  ўќ ќ+ў  љ 3ў  ћ 5ў  §ў3ў  §8ў  ћ5§  ћ6ў  ћ6ў  §8§  ќ6§  :њ :ћ П&ћэиўџџ'ќыцџџ(ћуоўџџ)ћ Джџџ*њВРўџџ,ћFуЌіџ џ-ћТДшџ џ/ћUяп§џ џ0њ•црёџџўќџџ2њšиєџџ4ј~њиіўўџџ6љHПяЛюџџ9љ :Ÿњўў<§ & РїПРРМРРППРР§Г3§zцшшўРћПНИПР РќПƒќuфшшўРПРњОПРП‹§”тшшў)РПћНМОПРРћН(ШшшўўПММќПНЛПП§РПРРћБ?\тшшў™ Р§ПРППјРППРvŸшшў§ОНОО№НОНЙЛППНПРР}.fйшш§Ю єОЗБІАНГВДЗНРРњŸb^Юшш§y!ћЇЖОРРНіЖЇ‘sM4мшш§v#№Y-.\’Рпшшќлt.%шќ ;%'шћЫy *юn‘­ФерццреФЉh: .ѓ,% ," В§wоррў3ќqмррў4§кррў'2ќСррў2ќ Vкррў“2ќ ‹ррў1ћ bбрр§Ч/њDЧрр§t!љј-˜дрр§r#§/љDЙиррќдp-%рќ›9$'рћФu *юjŒЇНЮиооиЮНЃd8 .ѓ*# *! В§  !ў §ў  2љ  ў2ќ  5§  ў4ў  5§  ў"і§  §1§  ў$ўћ  ќ% ќ' §,ћњ1 Д"џќЉ?!џќђH џќј`џўўџџћтy[ џўўџџћД2TџќQ=џќЃtџќўфZ!ўўџџўўџџўўџџћўУ"ўўџџ§§ќџџћірЃ$џњўъе”&џјўћФЈЈB(ўќўўџїю­БЬп—: +№MƒШэњ§ўќ№оШO&  А€€@@l-armџ     ўЮmЮ‰ьјЮеЮхЮѕЯЯлPэ'Z@ФqЌМЬмО:њ7ќ5ў3ўњ0ў§-§ћ,ўўўў*ў*ў§ ,ў§)ј&ўў%ќ љ$їў$ўќўў"§ћ § ќ ќўўњў§ўў§єўћўўўўў§§ ќўћўњќќўўћћўў§ў§ў ћјўўћјћўь ќ  њ§ўќў§ќўќ§ќў§њњќњўўўќ ќ§§ўћќј§ћ ў њўўўљўўў§ўўќћќ ћ  §ћ ќ ћўўќўќ §љќњ§ўќ ќО§DE9њ@ABb7ј=>_`a5ў:њ\]^_`2ў7јXZ[\]^_0ў4іUVXYY[\]^-§/1єRTUUVWYZ[\],ў.ђOPQSSUUVWYZ[]*§+,№KMNOPRRTUUVXYZ[)ў)юHJKLMNOPRSSTVWXYZ+ьEGHHJKLNNOPRRSUUWXY)ъBDEEGHIJKLNNOQQSTUVWX%ц#$?@ABCDEGHIJKMMOPPRRTUVW$х!=>?AABDEFGHIKLLMNOPQSTUW#ф;<=>@@BCCEFGHJJLLMOOQRSTU#ф9:;==>?@BCDEFGHIJKLMOPQRST!т5789:;<=??AACDEFGIIJKMMOPQSS с3446789:;<=>?ABCDFFHIJJLLMOPQRр122356789:<<>?@ABCDEGHHIJLMNPPQп.002245678:;<==?@ABDDEGGHJKLMNPPо,-.0123456789:<=>>@ABCDEGHHJKLMNO+п,-//123456789:<<>?@ABCEEFGIJKLMN)о+,--//12355678:;<=>?@ACCDFFHIJKMMл&'))*,,./012345679:;<=>?@BBDEFGHIJLLк$%&'(**+-..012346779:;<=>?@ABDEFGHIJKк#$%''))+,-./012355789:;<=>?ABCDEFGHIKи !"$%&''))+,-./013356789:;<>>?ABCDEFGHIи !"$$%''))+,-./012456789:;<=?@ABCDEFGHз ""#$%''(*+,-./013456789;;<=>?@BCDEFGж !"#$&'()*+,-.012235678::<=>?@ABCDFGж!!"$%%'()*+,-./123456789:;=>>@ABCEEе ""#%%'()++--/0113466889:<<>?@ABCEе!!#$%&'(**,,-/012345679:;;=>?@ACDд !!"$%&'()++--/013345779:;<=>?@BBд!!#$%&'()++-./012345679:;<=>?AAг!"#$&&')**+,./012455779:;<=??Aе !"#$&&')*+,-./012356789:;<>>@е !##$&''))+,-./012345789:;<>?в  !"#%%&')*+,-./023456789:;<>в  !"$%&'')*+--./022356889:<= д !"#$%'()*+,-//123456799:;б  ""#%%'()*,,-//02345678::б !!#$%%'(**+--/0123556899г  "#$$&'()*,-./012345679б  "#$%&'()*,--/01244578б  "#$%&'()++-./0133467б  !"#$%'()*++--/012356б !"#$%''))*,-./01235д  !"#$%&()*+,-./0234е  !"#$%'()*+,.//012Э§7§Ёў?§?ў Эќ  ,ћ   ќ   %ќ    љ  ћ    ў  ў  § §   ў  њ  ў    њў  ќ    ў  ў  ў њќў  ќ  љ  ў  ў   ќ  ќ ў ћ     ў  ў  ћ  ў  ќ  §   ј  § ў§ўњ    ў  ќ  ўўћ§   ў  ў   ў  ў  ќ ќј ў  ў  њ  ўўќўў  њ  ў§ќ њ    ў   ќ  ќўљ     њ  § ўќў ќ   § ў  љ  ў  ў    ў    ћ ў   ў     ј§ ќ   ў§ќї      §   ўўў  ї  ўќћ  ў  ќ  §ў §§   ќ    § §ў§ ј    ќ ћљ  §   ў  ўќ јўўњ ћћ§ў  ћў§ћў §   ќќў§§   ў љ ў ќ§іў љ   ћўњћ њў ћњќ  ўўўў јєљў ќўў§јў§ћј§ўќ  њћ ќўћ§јњўўљќ§  ћќљ §єќћї§ўњў  !§ўўў" §ў$§ ў§&ѕ‚…†‡‡‰Š‹Œ+чxyz{}~~€‚‚„„…†‡‰‰‹Ž‘$цtvvxyy{|}~€ƒƒ„††ˆ‰ŠŒŒŽмpqrsu xxy{|}~€‚‚„……‡ˆ‰ŠŒŒ‘иmnqrstvwxyz{|}~€€‚‚ƒ…††ˆ‰‹‹Œ‘ŽŒгIJklmnopqrsuuvxyz{}}~‚ƒƒ…†‡ˆ‰Š‹Ž‘ŽŒаFefghijlmnopqrsuvvxyz{|~~‚‚„…†‡ˆŠ‹ŒŒŽŽ‘ ‹Юcdefhiijlmnopqsstvwwy{||}~ƒ„…†‡‰‰Š‹‘Ž;x Ыbcdefhijklmnopqstuvwxyz{}}€‚ƒ„…‡ˆˆŠŠŒŽ‘ŽŒyz{ дabddeghijklmnopqrtuvwxy{{}~~€€‚ƒ……†ˆ‰Š‹ŒŽќŽќ{|}Ю`abcefghijkmmnoqqstuvwxzz{|~‚„„††‡‰ŠŠŒŽ‘Ž Э_`accefghijklmnoqrstuvxyz{||~€‚ƒ„…‡ˆ‰Š‹ŒŽ‘‘ Э^_`accefghikklmnpqrstuwwxzz|}~€‚‚ƒ……†ˆ‰Š‹ŽŽ‘‘Ž Ь]^_aacdefghijkmmopqrstuvwyy{{}~€‚„…†‡ˆ‰Š‹Œ‘Ž ]Ю_``bcdefghiklmmopqrsuuvxyy{|}~€ƒƒ……‡ˆ‰Š‹ŒŽŽ‘ Ы[\^^`aacdefgijkllnopqsstuwwyz{|}~€‚„……‡ˆ‰Š‹ŒŽ‘ [Э]^_`abcdeggiijlmmoprrsuuvwyz{|~€‚„…†‡ˆ‰Š‹Ž‘ ЪY[[\]_``bceffhhjklmnoprrstuvxyz||}~‚ƒ„…†‡ˆ‰‹‹Ž‘ ЪXYZ[\]_`abceeghhjklmnopqstuuvxyz{}}~€‚ƒ„…†‡ˆŠŠŒŽ‘ ЪWYZ[\]^_`abceffhijklmnpprrsuvwxy{{|~~ƒ„…†ˆˆŠ‹ŒŽ WYЮZ\]^_`abceffhhjklmnoqrstuuwxyz||~€€‚ƒ……†‡ˆ‰ŠŒŒŽ ЪUWXYZ[[]^_`abcefghijllmnoqrstuvwxzz{}~€‚ƒ……†‡‰Š‹ŒŽ ЪTUWWXZ[\]^_`abdeeghijklmnpqqrtuvxyzz{}~€‚ƒ„…‡ˆ‰Š‹Œ ЪTUUVWYZ[]]^_abbddfghijklmopqrstuvwxz{{}~€‚ƒ„†‡ˆ‰Š‹ ЫSTTVWXYZ[\^_`abbcefghijlmnnpqrstuwwxz{|}~‚‚„……‡ˆ‰Š ЫQRSTVWXY[\\]^`abcdefgiijlmnopqsttuwxyy{|}~€‚‚ƒ……‡ˆ‰ ЫPRRTUVWXYZ[]]_`abceefghikllnopqsttuwwxz{|~€ƒ„…†‡ˆ ЬOPRSTUVWXYZ[]^__abceeghhjkkmnopqrsuvvwyz{}}€‚ƒ„…† ЬNOQQSTUVWYY[\]^_`abcdefgiiklmnopqrtuvvxy{{|~‚ƒ„… ЬMOPQQSTUVWXZZ\]^^`abcdefhijklmnoprrtuuvxyz{}}~‚ƒ„ ЭMNOOPQSTUVWXY[\]]_`bbcdffhijklnnopqsttvwxz{{}~€‚ ЭKLMOPQRSTUVXXY[\]^_`bccdfggijklnopqqssuvwxy{|}~€ KаLMOPQRSTUVXYZ[\]^_aabcdfghijlmmnoprstuvwyyz|}~ ЯIJKMNOPQRTUVWWXZ[\]^_abccefgiijllnopprstuwwyy{|}ЯIJJLMNOPQSTUVVXYZ[\]^_`bbdeeghikklnopqrstuwxyz{{аHIJJKMNOPQRSTVWXYZ\\]^_`bbdefghikklmnpqrstuwxxyбFHIJKLMNOQRRTUVWXYZ[\^__`bcdefhijkllmopqrtuuwxбEGHHJKLNNOPQSTTUWXYZ\\^^_abcdefhiiklmnoqrrsuvwEGжIJKLMOOQQSTUVWYYZ[]^_`abcdefgijkklnoprsstDеFGGIJKLMNPQQRTUVXYY[[\]_`abcdefghjklmnoqqrдCDDFGHIKLLMOPQRSTUWWXY[[]^_`abcdffghjjlmoppеBCDDFGHJKKLNNPQRSTUVXXY[\\^_`abcefghijklmnж@BCCEFGIJJKLNOOQRSTUVWXZZ[\^_`acddefhijll@йBCDEFGHJJLMMOOQRSUVWXXZ[\]^_`bbdefghijи?@ABCDEGGIJJKMNOPQRSTVVXYZ[\]^_`abddfghй>?@ABCDEFHHJJLMNOPQSTTVWXYZ[\]^_`abdef=м>?ABCDEGGHIKLMNOPRSTUUWXYZ[\]^`aacdл<=>?@ABCDEGGIJJLMNOPQRSUVWXYZ[]]_`abм:<<=?@ABDEEGHIJKLMOOQRSSUVWXY[[\^__о9;<=>?@ACDDFGHIJKLMNOQRRTUWWYY[[\п8:;<=>@@BCCDFGHIKLMMNPPRSTUWWYZ[п79:;<=??@ABCDFGHJJLMMOPQRSTUVWXZс789:;<=>?ABCCEFGIIJKLNNPQRSTUV у6789;;<=>@ABCDEFGHJKLMNOPQRS"х56789:<<=?@@BCDEFGHIKLMMOP$ч356789;;<=?@ABCDEFGHJKLM&{ ў:§:ў f! і  њ" ў  ў  ћ   ў   ќ  ў  њ ў  ў  ќ  њ  ў  ћ   ў  ў ўќ   њ  њ   ћ   ў  ў   ћ    ў  ў   §   ќ   њ   §     ў  ў  ќ  ќ ё     ў  ў   ў  ў  § љ §  ў   њ  ў  ў  ћ§  ў  §    ќ ў ўќ   ќ   ў  њ     ћ  њ  љ   ўќ  ѕ      ў њ ќ§  ў  ќ  ў  љ   ќў  ў  ћ      ў  §  љ       ў   ў  § љ    њ  љў   ћ   §   љ   ў§  ў  ў  ї  ў ўўќ  ў ў   ў  ў  љ § §   ќ   § § ќ § ќ   њ  §ўћ  ў  ў ќ  ў  § љ  ћ   љ  њ§  ў  њ  ў њўў§  ў  §  ў §љ  ў  ј  § ў ћ§ћ  ќ   і  § §ўњ  ќ   љ ў №   ќ ў§ ў ў ћњўћ   ўќ  њћў  ќ  ќ§ ўўќ  §  ў љєќ  ўўўўў  § ќўўќ §§ ўћї ў  ў§ў јњ§§ў њўќњћў§ќ ћњў  ќўќ ћ §їњў ўўї§ўќњўўњќ ќ§ўўэљ  ,хn!*Myˆ††„ƒƒ€~nWM<  п‘ŒŒŠ‰ˆ‡……„‚‚€~}|{yxx BмŒŽ‘Œ‹‹‰ˆ††…ƒ‚‚€€~}|{zyxwvtsrOлŒŽ‘Ž‹Š‰ˆ‡†…ƒƒ‚~}}{zyxvuusrqpк‹ ‘ŽŽŒŒ‹Šˆ‡†…„‚‚~~|{zyxvvusrqpoиx;Ž‘‹Š‰‰‡†…„ƒ~}||{ywwvtssqponе{zyxŒŽ‘ŽŒŠŠˆˆ‡…„ƒ‚€}}{zyxwvutsqponmі}|{zyxŽоŽŒ‹Š‰ˆ†……ƒ‚€€~~}{{yxwvutrqponmlа~}||{yxwŽ‘ŽŒŠŠ‰‡††„„‚~|{zzxwvutsqqonmmk Ю€~}{{zyx‘‘ŽŒ‹Š‰ˆ‡…„ƒ‚€~||{zyxvutsrqonmlkj Ь€~~|{zyxwŽ‘‘ŽŽ‹Š‰ˆ†……ƒ‚‚€~}|zzxwwutsrqpnmlkki Ъƒ€~}}|zzywŽ‘Œ‹Š‰ˆ‡†…„‚€~}{{yywvutsrqpommkjihЩƒ‚€~||{yxxv‘ŽŽŒ‹Š‰ˆ‡……ƒƒ€~}|{yyxvuusrqpommlkihgШ„ƒ‚€€~}}{zyxw‘ŽŒ‹Š‰ˆ‡……„‚€~}|{zywwutssqponllkjigf…Шƒ‚€~}{zyxww‘Ž‹Š‰ˆ‡†…„‚€~|{zywvuusrrpommljiiggeХ…„ƒƒ€~}|{zxxv‘Ž‹‹‰ˆ‡†…„ƒ‚~}||zyxvutsrrponmlkjhhffeФ†…„ƒ€€~}||zyxwv‘ŽŒŠŠˆ‡†…„ƒ‚€~}}{zyxvuutsqponmlkjhhgeecУ†…„ƒ‚€~~}{{yxwvuŽŒ‹Šˆˆ†…„ƒ~~|{{yxwvusrrppnmlkjihffecb†Ф…„‚€~}|{zyxwutŽŒŒŠ‰ˆ‡†……ƒ‚€€~||zyxwuutsrqonmlkjhhffecba€О†…„‚€~}}{{yxwuutŽŒ‹Š‰‡†……ƒ‚€~}{zzxwvutsrqonmlljihgfecba`†…„ƒ‚€}||{yxwwutsŒ‹Š‰ˆ‡…„ƒ‚€~}{zzyxvutrqqpnmlkjihgeedba`_‡†…„‚€~}|{zxxwvttr‹Š‰ˆ‡†„ƒ‚€~}{{zxwvutsrqpomlkjihgfddbba_^†…„ƒ‚€€~||zyxwvusrqpЉˆ‡……„‚‚~}|{zxwwutsrqpnnmljihgfecbba`_^†„ƒ‚€~}||zyywvvtsrqp‰ˆ‡……ƒ‚‚€~}|{yyxwuttsqponmljiigfedcba`^]\…„„ƒ‚€}|{zyxwuusrqpoˆ‡†…„ƒ€~|{zxwwuttsqponllkihgfeecba`_]][„„ƒ‚€}||{yxwvutsrqpnm†…„ƒ‚€}}{zywvvusrqponmkkjhhgeecba__^][Z„ƒ‚€~||{yxwvutsrqoonm…„ƒ‚~|{{yxvvutrqponmlkiigfedcba`_^]\[Y„ƒ‚€}|{zxwwvttsqponml„ƒ‚~}}{zyxvuutrrponmlkjihfedcba`^^]\ZZXƒ‚~|{zyywvutsrqoonllj‚€~}{{zxwvttsqponnlkjihffdcbb`_]]\[YXW‚€}}|zzxxvvtsrqponlljj€~}|{yxwvussqqponlkjiggfdccb`_^]\[YXXV€~}|{zxwwvttrrponmlkjhh~}|zyywvutsrponmmljihgfdcbaa_^]\[ZYXVU€}|{zyxwvttsrppnnmkkihgf}|{yywwutsrpponlljiigfeccba_^]\[ZXWWVU€~}|{zyxvutssqponmljihggf{{zyxwutsrqponlkkihgeedbb`_^]\[ZYXVVUT}|{zyxwuutrrppnmlkjihgfdcyxxwutsrqpnmlkkihgfedbb`_^]\\ZYXWVTSR~||zzxwvutsrqpnmlkjihgfedcbxwuutrqpomllkjihfedcb`__^\[ZYXWVUTRR}|zyyxwvtsrqponmljihggfdcbawvusrrqonmlkiihfedcba_^^\\ZYXWUTTSQP|{zyxwvussqppnmlkjihffecbaa`tssrponlkkjigfedcba`_^][ZYYWVUTSQQOzyywvutsqqpomlkkjhhfedcaa`^]rqqonmlkjhgfedcba`_]\[[YYXVUTRQQPNТywwvussqponmljihgffecba`_^]\ppomljjhgffdcba`_^][[YXWWUTSRQPOMТxwvutsrpoonlkjihgfedcb`__]][Znmlkjihgfecba`_^\\[YXXVUTSRQPNNLУvutsrqponlkjiigfedcb``^^]\[YXlljihfeddca`_^\[ZZXWVUTSRQOONLKФtsrrponmlkiigfedcba`_^]\[ZXWVjihgfedbb`_^]\[ZXXWVUSRQOOMMLJХsrqonmmkjhhgfedcba`^]\[ZYXWVUhgfddba`_^]\[ZYXVVTSRQPONMKJJЦqponlljihggedcba`_^]\[YYXVUTSfedba`_^]\[ZYXWVTTSQPONMLJJHШnllkjiggeddba`_^]\ZZYWVVUTSQdcaa`^]\[ZYXWUUTSRPONMLKIHGЩlkjihgfedcb`_^]\[ZYXWVTTRQPPba`_]][ZYXWVUSRQPONMLJJIGG Ъjihgfedcaa__^\[[YXWVVTSRQOON__^\[[YXWVUSSRQOOMLKJIHGE Ьgfeecbaa_^]\[YXWVUUTRRPONMLK\[[YYWWUTRRQONMLKJIHGFD Юedbba`_^\[ZYXWVTTSRQONMLKJI[ZYWWUTSRPPNMMLKIHGFDCаba__^][ZYYWWUTSRQPNMMLKIHZXWVUTSRQPOMMLJJHGFDCBв`^]\[ZYXVVTTSQPONMLKIIHGFVUTSRQPNNLKJIIGFECCBж[ZYXWVUTSQPPOMMLKIHGFEDCSRQPONMLKJHGFEDCBAdї@ƒГОЯ6§UёџџњтЖgG@@ќ- 'ўuџџћт‘8 џўДџ§ыЮџџ"џ#џџўрџ џќ.pŸџ"џћ/>џ$џќ@"&џ§-;&џ§,5'џ §%'џ ў(џ(џ)џ)џ*џ*џ*џ*џ*џ*џ*џ)џ)џ)џ(џ(џ(џ'џ'џ&џ%џ%џ$џ#џ#џ"џ!џ џџ џ!џ"џ#џ$џ%џ&џ(џ)џ)џ+џ-§Эєџџ€ў ~€ў=ќ;њ9§§7њ4ќў)љў'§јў%ўј§#ќїў"ўў ўў ў§ў ќ&ўўўў%ќѕ#ќўўў!§ўўќљўў§§ў§ ћў њўќўќўўќ§ўћќ§ў§ћўўў§ўђўіќўўўў§ўў іњў§ў ћўў§ќў§ўўўўќќћўњћў§ћћўћ§ §§ ьљўњ  ў ўќ§ўў ўўњ§ќў јјў ћўўќњ љ§ќ ў ћћўў є§ј њњ ќ  ўў ќўўўўћ іўћўќў ј§  § ћў ќ §ўўќќ §ўљ§ ў €ў=ћoa.:љnml];8іmljiih2 5єlkjihfedE3ђkjihgeddbaCў8)№jihgfecba`_^A§5'юihgfecca`_^]\[>§2%эhgfecca`_^]\[ZYW<§/#ъgfedcaa_^]][ZYWVUU3§.,!шfedcb``_]][ZYXVUUTRRF!§+ цedcaa`^^\[ZYXWVTSSRPON6%хdcba`_^][[YXWUUSRRPONNLK4$уcb``_]\[[YXWVUTSQQONNLKJIH2"сba`_]\[ZYXWVUTRRPPOMMKJIHGED/ пa`_^]\[ZYWWUTSQPONMLLKIHGFEDBA-о`_^]\ZYYWWUTSRQOOMLLJJHGFECCB@@+ м_^][[ZYXWUTSRQPOMLKJIHGFEDCB@?>==л^]\[ZXWWUTSSQPOMMKJIIGFEDCAA??=<;:( ]м[ZYWVUUTRQPOMLLJJIHFFDCBA?>=<;:980 и\[ZYXWVTTSQPPNMLJIHHGEDCBA@?><<:98765з\[YXWVTSRQPPNMLKJHGGEDDBA@?==<;:876542#жZYXWVUTRRPONMLKJHHGEDCBA@>>=<:987654321!еYXWVUTSRPONMLKJIGFEECBA@?><<:987654321//дYWVUTSQQONMMKJIHFFDCCA@?>=<;:87655321//--гWVUTSQQPOMLLJIHGFEDBB@?>=<;:976543210/.,,*$вVUTSQPOONMKJIHGFEDBA@?>=<;:977643210..-+**(бUTSRQPOMLKKIHGFEDCBA?>=<;:987553210/.-,+))''бTSRQPOMLKKIHGFEDCBA?>><;:987653310/.-,+))''&%аTRQPONMKJIHGFEDCBA@?=<;:987654210/.-,+))''%$$" ЯSQPONMLJJIGFEDCB@?>=<;;987654310/.-,+*(''%$#""ЮQPONMKJJIHGFDCBA@?>=<::876532210.-,+*)('&$#"!  ЮQONMLKJIHFEECBA@>>=;:987654321/.-,+*)('%%$"!! ЭONNLKJHHGEECBA@?><<:9886643110/--++)('%%#""  ЭOMLKJIGGEEDCA@?>=;;:976543210/-,,**('&%$#!! ЬMLKJIGGFDDBB@?>=<;:977543310/--++)('&%$"!!  LЮKIHGFDDCAA?>=<;:976543210/.-++)('&%$#!! KЭJHGFDDCBA??=<;:977554210/.,+**)'&&$#"! JЭIGFECCB@@>><;:987653210/.-,+*)'&&$#"!  ЪJHGFEDCB@@?><;:987543210/.-,+))''&$##!  ЪIGGEDCBA@?><;:987654320/.-,+*)'&%%#"!  ЪHFEDCBA@?>=<:988653220/.--+*)''&%$"!  ЩGEDCBA?>==;:997654321//-,+*)('%$#"! ЩEDCBA@?>=<::87654320//-,,*)('%%#""  ЩEDBA@?=<<:9986553210/--+**('%%$#!! ЩDCA@?>=<;9976543210/.-,*)('&$$#"  ЩCB@@>=<;:887544210/--,*)('&%$#"  ЩA@??=<;:977643310/.-++)('&%$#"  ЩA?>=<;:987653210/--++*)('%$#"!  Щ@>=<;;987653210/.-,*))''%$#"! §C<џќ!9јјќџџт‘/7џќД#4џќт‘ 2 џќт‘)0 џќД9-џќД+џќтj )џќтg 'џќт{%џќтy #џќтs !џќтsџќШPџ§Ё  џќтI"џ§š #џќлG%џ§Є&џ§М'џ§ф(џ§ф')џ§ф'*џ§ѕ<,џўŒ-џўU-џ§ѕ'.џ§д /џўЊ 0џўU 0џ§ѕ 1џ§Ъ 2џў 3џў 3џўГ 4џў44џўЪ5џўB5џўЛ5џ§јJ6џўЛ6џ§§_7џўЖ7џўЦ7џўЯ7џўь7џўє8џў8џўm8џўЦ8џўпњўўќ ў ј§ § ўљ§ў ў§ќљљўљўќљыў ўўњ јў§њў(§ў§ Шг  !"$%&&()*+,-.012г  ""$%&&()*+,..01д  !"$%%'()*+-..0д  "#$%&'()*+,-.ж !""$$&'()*,-.ж  !""$%&'))*,,з  "#$%''))*+и  !"#$%&()*+й  !"#%%''()к  !#$%&'()м  !"#$&'(у  !"&ь  Шўў)ћ$ў-ўў§.ј1ў3§5ў7§8<ў ~щ3456789:<==>@ABCDEFGHI(х12456789;;=>?@ABCDEF889;<=$э122457789;<=>?@ACD,я011345678:;<==?@.ё/012346789::;<0ѓ./012345788:2ѕ-./01244674ї,-./02336љ+,-./18ќ*+,;ў) ~ њ§ўў§ќ §ўў$ўњ79§;=WкVTSRQPOMMLKJHHFEECBA@POMMLKIHGFEDCB@@лTRQPONMLKJHHFEECCA@?>=MLKJHGFEDCBA@?пNMLLJIHGFDDCA@?>==;:IHGFEDCBA@>=$GчEDCBA@?>=<;988FEDCBA@?>=6їDCA@?>=<8љ@?==<;:ћ<;::<§:8 џ/ўщџ џ1 џ3 џ/љџџ7џ9џ;џ=џ ќў§њќќ  ќќўўўњ§ј ќ ў§ § §ў§їќ §ў §љљўўќўћќ§юћњўўўќўњ%ўњ(љў§ [Щ?=<<:987654320/.-,+*)(&%$#"!  Щ=<;;987653210//.,+*)('%$#"!  Щ=<:9876543210.-,+*)(&&%$"!  ;Ы9876542110..,+*)(&&%$""  Ъ;9877542210..-+*)('%%$"!   Ъ:876543110.-,+*)('&%$#"   Ь987643210/.-,*)('&$$""!  Ь87543210/.,,*))'&%$""!   Э7644210/.-+*))''%$#"  3в20/.-,+*)(&%$#"!  г1/.-,+)(''%%#"!  з,+*)('&%$#!  л)('&$#"!  у"!  'ь  Y8џўв8џўЯ5џћ~џџь5џћ^џџё4џњIџџє4џ§џџ3џџў3џћъџџ22џћxъЊ/џ+џ'џ#џ џ(§џџџ Z€€@@bodyџ     uЅСt t, -=M |0ёAЌE4OP-P=[Юa_gЈm ?ў < = < <ќ :ћ  :ћ  9 ў9§   :њ  8љ  8љ  7ј   7 7  ў6  ?ў€<§€<<~<ќ}~}:}ў|:|ў{9|{:§|{zz:њz{zzy8zy9yx8xw8xw7ќxwwvvўu6ўwvv§uvu ?ўџ<џ=џ<џ<џ;џ;џ:џ:џ:џ9џ9џ8џ8џ7џ7џЕє .я":[v…˜ЄБЛТ+ь /HlЃИбхяѓѕїњќ§)№&EdГЩнюѕјћ§ўџџ'ё"GošФмьїњ§ўўџџ$є9h•Суёњ§ўў џ"ѕ &N‚Би№њўџџ є +Z”Ххіќўўџџє +_œЮэњ§ўўџџї &\œб№ќџџїR•аюћўџџї?ƒТъњўџџї +hАуїўўџџїI‘аѓ§ўџџј(iЕцњўџ!џї?‹бє§ўџ"џјWЉхћўџ$џј'oР№ўўџ%џљ 6…Яѕўџ'џљ C™нљўџ(џ јLЈчќўџ)џ јXБэ§ўџ*џ јaЙя§ўџ+џ јdНё§ўџ,џ љdНёўџ.џљcОёўџ/џљ`Пђўџ0џјVИё§ўџ0џњMЏю§џ2џљ CЄъќўџ2џј4“тќўўџ2џњ(ƒкћџ5џљnЬїўџ5џљVОђўџ6џ9 § 3 ў   1ќ    ќ -§  ў  + ў  ў  ў  )  ў ' њ  ў  %   ў "ћ  ћ § !  §  љ   ў  ў  ў  ќ   ў  ў  њ §  ќ ѕ  ў ћ  ў     ў  ў  ў  ї  ў    і  њ  ї     ў   ћ   ў  ў  ќ   §       ћ  ў  ў  ќ  ћ  ў  њ  ў  ў  ћ     ў  ќ     ў  ћ  ї      §    ў   ў  ў  ќ  ў  ў  ћ     ў  ў   ј  ў  ј   ў  ў   ќ   ћ  ў  њ  њ    ј  љ  є  ћ    ў  ў       ћ  ў   ћ  ђ  ў ќ  ў  ў  ј   ђ  ј ј № )@`z‰‘›ЇГНУ  њ  ћ  ў  ў  э #6Nq’ІКвхяѓѕїњќ§і  њ  ў № -Ki’ЕЪоюѕјћ§ўџџ    є ё )LtЦньїњ§ўўџџ    ў ѕ#?m˜Ууёњ§ўў џ  ў ѕ -S…Гй№њўџџ §    ў  ў  є 2_—Цхіќўўџџ ј  ў  ѕ2dŸЯэњ§ўўџџ   ј,aŸв№ќџџљ  ў  є  &X˜бюћўџџ   ў  є E†Фъњўџџ ў  і1mВуїўўџџ§  ѕ N”бѓ§ўџџ§  є  /nЗцњўџ!џў  ў  јEвє§ўџ"џ ў  ї \Ћхћўџ$џ ў  ј.sТ№ўўџ%џ ў  ў  ј =‰аѕўџ'џ ў  љIœољўџ(џ љQЊчќўџ)џ ў   љ]Гэ§ўџ*џ ў  є  "eЛя§ўџ+џ ё    "hПё§ўџ,џќ   і "iПёўџ.џ  њ gРёўџ/џ ї eСђўџ0џќ  ј [Кё§ўџ0џ і SБю§џ2џ љIІъќўџ2џ ј;–тќўўџ2џ њ .†лћџ5џі  "rЭїўџ5џњ[Рђўџ6џ9ў‘3ќ‘‘0‘ў-ў‘+‘Ž)‘ާŽ&‘љŽŽŽ%‘ћŽŽћŒŒŒ"‘ŽŒ‹"ў‘ŽћŽŽŒ‹ўŠ‘§ŽŽŽ§ŒŒŒ‹Šќ‘њŽŽŽŒ‹§Œ‹ŠŠ‰ўˆў‘ŽŒ‹Šљ‰Š‰‰ˆˆќ‘‘їŽŽŽŒŒŒ‹Š‰ˆ‘ŽŒ‹Š‰ˆ‡ŽŒ‹Š‰§ˆ‰ˆˆ‡†ŽћŽŒŒŒ‹Šљ‰ˆˆ‰ˆˆ‡‡†ўŽŒ‹§Š‹ŠŠ‰ˆќ‡ˆ‡††ќ…„…ўŽіŽŒŒ‹Œ‹‹ŠŠї‰Š‰‰ˆ‰ˆˆ‡‡†ў…„„ŽћŽŒŒ‹Š‰§ˆ‰ˆˆ‡†…„ƒёŽŽŽŒŒ‹‹Œ‹‹ŠŠ‰ˆћ‡ˆ‡‡††…§„…„„ƒ‚ŽŒ‹Šј‰ˆ‰ˆ‰ˆˆ‡‡†…§„…„„ƒ‚ўљŽŒŒŒ‹Š‰ˆ‡§†‡††…„ƒ§‚ƒ‚‚Œ‹Šњ‰ˆ‰ˆˆ‡‡†…„ƒњ‚ƒƒ‚‚€њŒŒ‹Œ‹‹Š‰§ˆ‰ˆˆ‡†ќ‡…†……ќ„…„ƒƒљ‚ƒ‚‚‚€ў Œ§‹Œ‹‹Š‰ˆў‡††…ќ„ƒ„ƒƒ‚€§€ ўŒ‹‹Š‰ћˆ‰‡ˆ‡‡†…„ќƒ„ƒ‚‚ў€~ ‹Š‰љˆ‡ˆˆ‡‡††…ќ„ƒ„ƒƒ‚ў€€~} Љˆ‡†…„ƒ‚€ў~}}§|} Љˆ‡§†‡††…§„…„„ƒ‚§‚€§~~~}ћ|}|| Љˆ‡†§…†……„ƒ§‚ƒ‚‚ћ€€€~є}€‚‚ƒƒ„„……ќŠ‰‰ˆˆљ‡†‡‡††……„‚ћ€€€я~„ˆŽ™ЊИПУЩЯжлп‰ˆ‡†ќ…†…„„ƒ‚€ш€~€„‹”ЁДХЯкчёіјљњќ§§ˆќ‡ˆ‡††…„ƒ‚€я~…‘ АХзуэіљћќ§ўџџўˆ‡‡љ†…††……„„ƒ‚€ё€…ЁЕЫрэѕњќ§ўўџџ‡†…„ќƒ„ƒ‚‚€ѕ‚‹šВШп№їќ§ўў џ‡†§…†……„ўƒ‚‚€ѕ€ƒ‘ЄПзъїќўџџ†…„ƒ‚€ѓ~„“ЋШсёњ§ўўџџ…ћ„…„„ƒƒ‚€~ѕ„“­Ьхѕќ§ўўџџі…„…„„ƒ„ƒƒ‚‚ќ‚€€§€~ј‚‘ЋЬчї§џџў…„„ƒ‚§‚€~ї€ŒІШчіќўџџ§ƒ„ƒƒ‚§€€€ѓ~}~~†Ппєќўџџƒ‚љ€€€€~}ї’Бж№њўўџџƒќ‚‚€~}ї~†ЁЦцј§ўџџў‚‚€№~}~~}|}€Биђќўџ!џ§‚€њ€€~~ђ}~}|}|„›Тчљ§ўџ"џљ€€€~ќ}~}||ј}‡Јвёќўџ$џ€~§}~}}|ї{~Гоїўўџ%џї€~~~~}}|і{|{€–Пхљўџ'џў~~}§|}||і{zz€œЩэћўџ(џ~ю}|}||{|{{zzƒЁбђ§ўџ)џ}|{zљ†Їжѕ§ўџ*џќ}||{{zїy{‡Ћкі§ўџ+џ|{ћz{zzyyљ‡Ќмї§ўџ,џ§|{zzyљx…Ќмїўџ.џzѓyzyyxyx…Ћмїўџ/џyћzyxyxxњ‚Њмјўџ0џyxїwvЄиї§ўџ0џxїwvv~Ÿдѕ§џ2џwіvwv{™Эѓ§ўџ2џўwvvјx‘Фя§ўўџ2џіvuvvwŠЛъќџ5џuљvƒЏуњўџ5џtњ|Ђлїўџ6џ9џ4 џ1 џ.џ+џ)џ'џ%џ#џ"џ џ џ!џ"џ$џ%џ&џ(џ)џ*џ+џ,џ-џ.џ/џ0џ 1џ 2џ 2џ 3џ 4џ 5џ6џ6џ7џ8џ9џ9џ:џ;џ;џ<џ=џ=џўџ=џўџОџ€ўѕ +§ЦШЪЪэЩШЦСЙЏЂ•‹ƒqT5 'ўь§ћљїєёэсЬГ ˆdA, # џўё§ћјєыиФ­†\? !џўѓќњіщиНf> џўѕќјянИŒ^2џєў§љьбЈvDџўіќєрМˆO# џўі§љшХS$ !џїўљьЧP"џўјјщФ†E$џіў§јуЖu4 &џїў§ѕлЃY!(џїўќяХ‚< *џјўјрЈZ +џјўќяХ{2 -џјўљм™G .џјўћщА^/џўњ№Тs)1џљўѕб†32џљўњо•< 3џљўќх F4џјўќщЉO5џљў§ыЎR7џњ§ъ­R8џј§ъЎRџ7џјўќыЎLџ8џљўќщЄD џ9џњўћфš<џ:џћўћрџ:џў§њжџ=џўјџ=џўўџ>џ / ў ќ ) ў  ќ & ў     ќ # ў   ћ  ! ќ  і  ў   ќ  ў   і    ў  ў  і  ў  ќ  њ  і  ў   х    ћ  ќ  ў  ќ  §  ў  ќ  ў  ў  ћ  ї  ў    ѓ  ў  ў  ў  ћ ў   ў  ў   ћ  љ  ў  ў  ќ   ћ  ћ  ў  ў   ў  ў ћ   ќ   ќ  ў  ў  ќ   ћ    ў    ў  ў  ў  ў  ј    § ў § ў я        ћ   ў  ѓ       ћ   ќ   ћ   њ  ў  ў ў  §   §  ў ѓ     ќ  § ќ ї   ћ  §  њ  ѕ    ў њћ    і     ћ  ўў ќ   є    њ   ў  њўў    љ   ўўўы   ў јјШЩЫЫэЪЩЧУЛБЅ˜†uY;&  ўјћўэ§ћљїєёэсЭЕЂŒhF2  ўљ џўё§ћјєыйХЏ‰aE& ўњћџў№ќњіщйП“jD" јўўўџџўёќјяоКc8 љџѕў§љьвЊyI%ўїћџџўђќєрО‹T)іўџџўѕ§љшЦ“W*ўў!џїўљьШ’U$ћ "џўіјщХ‰J $џїў§јуИx9ў &џїў§ѕлЅ]' ў(џјўќяЦ…A §џ)џіўјрЊ^% §џ*џјўќяЦ~7-џіўљм›Lў.џјўћщВb$ ўўџ.џўі№Уv. 1џѕўѕвˆ7ўџ1џїўњо—Aўџ2џљўќхЂKўџ3џљўќщЋSўџ4џѕў§ыАVџ6џї§ъЎVџ7џј§ъЏVџ7џјўќыЏPџ8џљўќщІHџ9џњўћфœ@џ:џћўћр‘џ:џў§њжџ=џўјџ=џўўџ>џ‘ў§ŽŽŽŒ/ŽŒ‹Š*ŽњŒŒ‹‹Š‰ўˆ&ћŽŽŒ‹Š‰ˆ‡$Œ‹Šљ‰Šˆ‰ˆ‡ˆˆќ‡†‡††!іŒŒŒ‹Œ‹‹ŠŠў‰ˆˆљ‡ˆˆ‡†‡††…ў„Œ‹Š‰ˆ‡і†…†…„……„„ƒƒ‹Š‰ˆ‡†…ї„……„ƒƒ‚ƒ‚‚ўў‹ŠŠњ‰Š‰ˆ‰ˆˆ‡§†‡††…„ƒ‚їƒ‚‚€Š‰ˆ‡†…„ƒ§‚ƒ‚‚€‰§‡ˆ‡‡†ї…†…„„…„„ƒƒ‚€ќ€~~њˆ‰ˆ‡ˆ‡‡†…„ƒ‚ћ€€€~}ќ~}|њˆ‡ˆ‡‡††…„ƒ‚€~}|ў{ўˆ††…„ƒћ‚ƒ‚‚€ў~~ћ}~}}||{ўzљ†‡††……„„ќƒ„ƒ‚‚ќ€€€~}|{ўzyyќ†…†„„ƒї‚ƒƒ‚‚€€~}|§{|{{zњyzyyx…„ƒ‚€ћ€~~}§|}||{zyxўw „ƒ‚€љ~~}~~}}|{zyxwv ќ„ƒƒ‚‚§‚ў€~ћ}~}}||ќ{z{zzyxwњvuvuu ўƒ‚‚§‚€~}|{zyxwvut ‚€~}|{zyxwўvuuts €ў€ў~}}|ћ{|{{zzyћxyxxwwvutsr€~}~є|}|{||{{z{zyyxwvќututtўsrrќqrqў€~}|{zyxwvutsћrsrrqqp~}ў|{{zyјxwxwxwwvvutsrqћpqppoo~}§|}||{zyx§wxwwvutsrїpqppopoonnўm}|§{|{{zyxwvutsrqponmў}||{ќzyzyyўxwwvљuvuuttssrq§rqppћopoonnml|{ѓz{zyzzyyxxwxwwўvuutsњrssrrqqpoћnomnmmlk{zyњxwxxwvv§uvuutњstsrsrrqponmlkj…„ѓ‚€~||ywvuutt§stssrљqrqqppoonћmnmmllћklkkjjуihстууттсройдЭЦРМВЂ‘…€zutssrrqponmlkќjkjiihўэ§ќћњљїѕюуеЫНЉ–‹€vtrrqponmlkjiљhiihggџ џўэ§ќћјєщобЛЄ”‚wsqpopoonmlkјjkkjijihhњghgfgџџўя§ќњђщйСЉ’upnonnmmlkjihgfџўє§ћѕыжОЄŠzpnmmlkjўihhgfeџєў§ћєфЭА“~plkkњjkkjjiihgfeўdџџўї§јэиʘojjihѕghgfgfeefeddўcџџўє§ћёнОš~ojiihhgќhggffњededdcc!џђўћѓо͘zlhghggffe§deddcўbџ!џўїњёмЗtigffedcbўaџ#џѕў§њюгЌ…mffeedcba&џїў§љщЧšxgddќcbcbbaў`џ'џѕў§ѕлГˆmdccbbљabaa`a``ў_џ)џјўњьЩšuebba`_ў^џ*џјў§ѕл­gaa`_^ў]џ,џїўћщПŒk``__^].џѕўќёЭ™qa_^_]]ў\џ.џўјѕиІxa]^]]\1џёўјсВ}b]]\[\\[[џ1џјўћъЛ‚c\[[ќZ[Zџ2џїў§юСˆd[[ZZўYџ3џљў§№ЧeYYўXџ4џљў§ёЪŽdXX7џї§ёЩcXWWџ7џј§ёЩbWVџ7џјў§ёЩ‰_Vџ8џљў§№Т‚]џ9џњўќьЛ|џ:џћўќъГџ:џў§ћуџ=џўњџ=џўўџ>џџ/џ*џ'џ$џ!џ!џ#џ%џ&џ(џ*џ+џ,џ.џ/џ0џ2џ 3џ 4џ 5џ 6џ7џ8џ9џ:џ;џ<џ<џ=џ>џўџ?џ€ў =§3<ќ%;ћЬn:ћѓОY:њ§э­? 9ў=ў==<;ў:§99ћ887ў66ў5ў4ќ4§4ќ23§2ў2 1 ў00љ/ўў/ўў§.ќ7 ѕ.ќ‚*ћ-њЭpў-ћѓП\ќ-ї§эЎB-ўg=ўf=§fe<eўd;dc;ћdccb:њbcbba9љbaba``8a`9`њ_``_^7_§^_^^7њ_^_^^]]7ў^]]ћ\]\\5]\[6\[Z5\[ZўY4[§Z[ZZYўX3ZYXW3ZўYXXњWXWWV2YXWV2XїWXWWVWVVUU2ўXWWVUT1WVUTS1VUTSўR/§VUTT§STSSќRQQ/љTUTSTTSSRћQRQQ/њZSTSSRRQћPQPO.§uWRRQPћOPPO.јЈkTRRQQPPON.њмœbPQPPONM.њівZPOONML-э§ђЦzUONONMNMMLMLKK,ўџ=ўџ=џ=џ<џ;џ;џ:џ9џ9џ8џ7џ7џ6џ6 џ5 џ5 џ4 џ3 џ3 џ2 џ2 џ1 џ1џ0џ0џ0џ/џ/џ.џ.џ-џ-?ў<§<§ E;ќ&Ž:ћ`Ю:ћ7Ї№9њvйћ9њCЖєў8љ„рћў8љ KНѕўџ7ј ‰уќџџ7ј LОіўџџ6њ!‰ф§џџ7њ IКѕўџџ6њƒсќџџ6ћ@Гѕџџ5њvкћџџ5њ1Ѓёўџџ5ћbЭњџџ4њ!ыўџџ4њGИіўџџ4ћwп§џџ3ћ+œёџџ3ћ VЦљџџ3ћ|ц§џџ2њ-žђўџџ2ћ WШљџџ2ћyцўџџ1њ'–ёўџџ1ћLОјџџ1ћ lо§џџ0њƒьўџџ0њ4Ѓђўџџ0њ TШјўџџ0њlсќўџџ/љ~щ§ўџџ/њ.™яўџ џ/њIМіўџ џ/њ _зњўџ џ/њ kу§ўџ џ.њzшўџ џ.њ(‘эўџ џ.њ>Ўђўџ џ.њ PШјўџ џ.њ ]йћўџ џ.ћ cр§џ џ.ћjу§џ џ-њwц§џ џ-њ$ˆщ§џ џ-њ1™эўџ џ-њ=Ћёўџ џ-њGЙєўџ џ-њ PЦіўџ џ-њ Wаљўџ џ-њ \жћўџ џ-њ _кћўџ џ-ќ›њџ џ-њ `нќўџ џ.ќZяўџ џ.§[№џ џ7ў 6ќ  6ў ќ 4ў 5ў ў 4§ ў3§J3њ ,‘3ўќdЯ2ћ =Љ№2ћ zкћ2њHИєў2ўљ &‡рћў1ќљPПѕўџ1ѕ &Œуќџџ1ђQРіўџџ0ўњ'Œф§џџ1їNМѕўџџ1ѕ"†сќџџ1љ EЕѕџџ0їyлћџџ0њ 6Ѕёўџџ0ћfЮњџџ0і '“ыўџџ/љLЙіўџџ/ћzп§џџ/ўћ 0žёџџ/њZЧљџџ/ћц§џџ.њ 2 ђўџџ.ћ[Щљџџ.ћ|цўџџ.њ ,˜ёўџџ.ћ PПјџџ.њpо§џџ-ї†ьўџџ-њ 9Ѕђўџџ-їXЩјўџџ-љoсќўџџ-їщ§ўџџ-њ 2›яўџ џ-њMНіўџ џ-јbињўџ џ,њnу§ўџ џ,ћ}шўџ џ,ј-“эўџ џ,њ BЏђўџ џ,њTЩјўџ џ,њ`йћўџ џ,ћfр§џ џ,ћmу§џ џ,ћzц§џ џ,љ(Šщ§џ џ,љ 5›эўџ џ,љ @Ќёўџ џ,љ KКєўџ џ,љTЧіўџ џ,љZаљўџ џ,љ_жћўџ џ,љbкћўџ џ,ћњџ џ+њcнќўџ џ+ќ]яўџ џ+ќ^№џ џ7vuўt5ўvuuњtutst5uћtustss5ѕtuttstssrr4tsr§qs4srqў|3ќsrrqqћpqu–3rqpќq„П3qpћoxЄу2qpoћrЬі2ponћ|Ащќ2ѓonoonmmq“ејў2nmњ~Иэќў1nmјlq—иљўџ1mѕlmlm~Кю§џџ1lїkq—йљўџџ0ќmklkkћ}Кя§џџ1kjљin”жљўџџ1ўkjjiћxЖэ§џџ1jiњhmŽбљџџ0ihћt­щќџџ0ўihhљgi„Шіўџџ0ўhggћo сћџџ0ўgffњhyЛђўџџ/gјfeiдљўџџ/feћpЌы§џџ/eњde}Тіџџ/ўeddћi—мћџџ/dcћnЎя§џџ.cјbcd}Уіўџџ.ўcbbћg–мћџџ.baћlЋяўџџ.aћxНіўџџ.јa``dŽжњџџ.ј`__gЂъ§џџ-_ћmАѓўџџ-^њa~Фіўџџ-ї^]]b’лњўџџ-]њdЁы§ўџџ-\њjЌ№§ўџџ-ј\[]xНєўџ џ-ј[Z_‰гљўџ џ-Zњa–фћўџ џ,їZYYažь§ўџ џ,XћgЇяўџ џ,XњYrЖѓўџ џ,WњZЩіўџ џ,јWV[Šкњўџ џ,јVU[“хќўџ џ,љVU\–ъ§џ џ,љUT^šь§џ џ,љTScЃю§џ џ,љSUkЎ№§џ џ,љSTsЙђўџ џ,љRVzХѕўџ џ,љQU€Юїўџ џ,љPV†зјўџ џ,љOU‹оњўџ џ,љNTŽтќўџ џ,љNTхќўџ џ,ћM\Йћџ џ+јLMSчќўџ џ+љLKLŠѓўџ џ+KќJŠєџ џ7џ6џ6џ5 џ5 џ5 џ4 џ4 џ4 џ3 џ3 џ3 џ3 џ2 џ2 џ2 џ1 џ1 џ1 џ1 џ0џ0џ0џ0џ/џ/џ/џ/џ/џ.џ.џ.џ.џ.џ.џ-џ-џ-џ-џ-џ-џ-џ-џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ,џ+џ+џ+џљ >Ѕэ§ўџ6џј+‰рћўџ7џљjЮјўџ8џњ KЖѓўџ9џћ,–ч§џ:џћnдњўџ:џќИѓўџ;џ§ч§џ<џ§љўџ<џўўџ=џўўџ ~џї DЇэ§ўџ6џј 1Œрћўџ7џљnЯјўџ8џњPИѓўџ9џћ2™ч§џ:џћrењўџ:џќКѓўџ;џ§ч§џ<џ§љўџ<џўўџ=џўўџ ~џtљx•Эѕ§ўџ6џјsu‰Нэќўџ7џљrЌућўџ8џњvšжјўџ9џћ‰Фё§џ:џћ­цќўџ:џќзјўџ;џ§ё§џ<џ§ћўџ<џўўџ=џўўџ ~џџџџџџљўќц,8јџўњжt7џњўіОV7џњўьЃ:6џљўњл€ 5џњўѕУY5џљўќыЁ54џљўћйv3џњўєИK 3џњ§хŽ'2џњўјШ^2џњўьž11џњўљбk1џњў№Ѕ70 џћћжo0 џњўђЇ7/ џћќиp/ џњўёЄ5. џћћжi. џћ№›-- џћњЭ] - џњўы‹!, џњўїНK, џњўќсv, џњўёЃ6+ џњўњб^ +џњ§шƒ*џњўѓВA*џњўћиb *џњ§ш… )џњўѓГ@)џњўњж\ )џљўќф{(џњў№Ї7(џњўљЬO (џћќнe(џњ§ш‰$'џњўѓД<'џњўњаM'џњўќл_'џњ§х&џњўяІ2&џњўїХA&џњўћдK&џћќк\&џњ§тw%џњ§ы—(%џњўѓЕ6%џњўјШ>%џћћбC%џћќеK %џћќйY%џњќоl$џњ§у€$џњ§щ”%$џњўюЄ+$џњўђГ1$џњўѕО5$џњўїХ8$џњўљЩ:$џќєh $џњўњЬ;$џќўт*%џ§у+%ђўќц’0 -іџўњжw#ўў+џюўіПY+џђўьЅ= +џіўњл‚$+џїўѕФ\+џљўќыЂ8 ў)џњўћйx *џѕўєЙN*џњ§х+ў)џњўјЩ`)џњўьŸ5§(џёўљбm(џєў№І: ( џјћжqќ' џђўђЈ: ' џіќиrў& џѕўёЅ8 ' џћћжk' џћ№œ0ў& џљњЭ_ў% џљўыŒ%& џјўїОN & џњўќсx& џњўёЄ9§$ џњўњб`%џњ§ш„!%џїўѓГC %џєўћиd$џњ§ш†"$џјўѓГB ў#џјўњж^ў#џњўќф|ў#џѕў№Ј:#џњўљЬQ $џјќнf#џѕ§шŠ&"џјўѓД?#џњўњаO §"џњўќл`#џњ§х€ #џњўяЇ4#џњўїХC#џњўћдM "џћќк]"џі§тx!џњ§ы—*ў!џіўѓЕ8!џіўјШ@!џїћбE!џїќеL !џћќйZ"џћќоm"џњ§у€"џњ§щ•&"џњўюЄ-"џњўђГ2"џњўѕО6"џњўїХ9"џњўљЩ<"џќєi "џњўњЬ<!џћўт+!џ§у,!ѕўќэБmQNNMMLLK§JK,јџўћтžaNLLKJ,џњўјб‰VLLKJI,џњўёОtOKKќJIJIIќHIH*џљўћхЄ`LJJIHG+џљўїд‰TJIIHGF+џљўќ№ЛnLHHGF§EF)џїўќуœYHGGFFE*џјўїЬ}MFFEED*џѕ§ь­bHFFEDECC)џљўљз‰PEDDCB)џљўёИhEDCCBўA(џљўњн’QCBBAў@(џљўѓМjEBAA@ў?' џљќр”OAA@@?( џњўѕНiC@@?>( џѕќс“N@@??>>==' џњўєКfB>>ћ=<=<& џјћрJ>==<<' џњѓГ_?=<<;' џћћиƒE<<;:& џљўяЅT<;::ў9% џјўјЬsA::99& џњўќч•J998& џњўєЗb;887% џјўћлA88776%џљ§эN87665%џјўѕТi;6655ў4$џљўћрƒ?6554%џє§ьžM6443432#џїўѕТf834322$џєўћо|<332121#џњўќщ•G221$џљўђИ^6100$џњўњеp800/$џљќуЃђўџ џ,љ*яўџ џ,њш§ўџ џ,јhбњўџ џ-љ CЎєўџ џ-њ&э§ўџ џ-јrзћўџ џ.љ DЏѕўџ џ.ћ#Šш§џ џ.њ\Хјўџџ/љ/˜эўџџ/јaЪњўџџ0ћ.šэ§џџ0њZУјўџџ1ћ'ˆтќџџ1њ FБђўџџ2њlЮљўџџ3ј.Žсќўџџ3њ EЋэ§џџ4ј\Рѕўџџ5ј qЭјўџџ5ѕ,ƒињўџџ5ј3Žпћўџ6ї :—ућў7ј >›ућ8ћ ?šс9ќ ;“:§ 3;ў<>ў+KћJ˜ђўџ џ+JћIЈ№ўџ џ+IћЈя§ўџ џ+јIHHІэќўџ џ+HњGŸчќўџ џ+GњF”мњўџ џ+FњEƒЭјўџ џ,EћpКѕўџ џ,Dћ_Ћѓўџ џ,CњV э§ўџ џ,CњPмћўџ џ-љBGpСіўџ џ-јA@ZЊё§ўџ џ-јA@N“рћўџ џ.љ?EoТїўџ џ.?ћVЅэ§џ џ.ј>=I€вљўџџ/љ=?\Џёўџџ/ј=;I„ећўџџ0љ;<[Џё§џџ0:њE}аљўџџ1љ9:TЁшќџџ1ј98?mСєўџџ2ј87HŠињўџџ3ј78WЅчќўџџ36њў*+џ+џ+џ+џ+џ+џ+џ,џ,џ,џ,џ-џ-џ-џ.џ.џ.џ/џ/џ0џ0џ1 џ1 џ2 џ3 џ3 џ4 џ5 џ5 џ6џ7џ8џ9џ:џ;џ<џ=џ>ўџџўћџ=џќнњўџ;џњˆзјўўџ9џљ*yЪє§ўџ8џј fЙэќўџ7џїOЃтћўџ6џј 9ˆбѕ§ўџ4џј#gЖшњўџ3џїD‘гѕ§ўџ1џј#dГчњўџ0џї :‚Цюћўџ.џ їM”Яёќўџ,џ ј$Y жѕўџ+џ і)_Ѓжє§ўўџ'џі *]Я№њўўџ%џі $Q‘Фъї§ўџ#џї>{Внђћџ"џѕ*]’Фцєќўџџѕ :l›Цсѓќџџѕ ?h”Нкюћџџё6Y€ЉЩсѓќ§ўўџџ!я&Ca†ЇУйыіњћќўўџ џ$ъ$9QoЈСгфяѓїљћќ§ўўџџ)щ "2D\rˆЂЗУЯнцыю№ѓіјњ,э )8KYco€•ЈЗС3є "+26џўћџ=џќнњўџ;џњ‰зјўўџ9џљ,zЪє§ўџ8џј"gЙэќўџ7џїPЄтћўџ6џј ;ˆбѕ§ўџ4џє%hЖшњўџ3џіE’гѕ§ўџ1џѕ$eГчњўџ0џє;ƒЦюћўџ.џїO•Яёќўџ,џўј %Z жѕўџ+џѓ *`Ѓжє§ўўџ'џ ё +^Я№њўўџ%џ ѓ %R‘Фъї§ўџ#џ ї?|Внђћџ"џѕ+^’Фцєќўџџі ;m›Цсѓќџџѓ ?i”Нкюћџџўё7Z€ЉЩсѓќ§ўўџџўь'Ca†ЇУйыіњћќўўџ џјы$9QoЈСгфяѓїљћќ§ўўџџ§ўщ "2D\rˆЂЗУЯнцыю№ѓіјњ э )8KYco€•ЈЗС" ўє "+26& ўў,ўѕ5њ:њ€џўћџ=џќуњўџ;џњœнљўўџ9џљMвѕ§ўџ8џј-DФяќўџ7џї)*:kБцћўџ6џ)ї(1Xšиі§ўџ4џє(''+D}Рыњўџ3џє'&&'4_ йі§ўџ1џѕ&%%*ByНъњўџ0џ$ї%.U’Э№ћўџ.џў$##ї'7dЂеђќўџ,џє"!"!'@nЌліўџ+џё! ! &CrЎкѕ§ўўџ'џ ё  &CpЈдёњўўџ%џ §і$OdzŽЇКЦбочыю№ѓіјњю#*3AS`iu…™ЋЙУ"§ ё !*3:=&     ў+§     њ 0  9ўў~ Рџўџ=џ=џ;џ:џ9џ7џ6џ 4џ 2џ 1џ/џ-џ+џ(џ&џ#џ!џ џ#џ'џ,џ1 џ9џ€ џўўџ;џўїљџїЭачТтџ3џєўќ№Щџл=lџ1џўљјсЈ\џаў>џ0џёўћюЧ~5 џл=lџ.џяўќѓж™PџїЛ=dоџ,џєў§їоЉd' џ2џїўњуГp1.џўї§јтЕv7-џўїќєн­r7,џіўњяеŸf0*џі§ѕцУŠS"  &џѕў§јъвЂl: #џєў§јчЯЋyI !џє§єсЦЄvJ'џўѓќїшаГe@" џўё§ќњїярЪЏmJ. џўь§ќћњјє№щйЧБ•z[@* ћшњљїєёюышрдЧЛЉxdL7' цЧЪЬЭЬЫЩФЛ­›‡se\Q?-" %§9:;;ђ:73-% Ќ џўўџ;џўїљџїЭачТтџ3џєўќ№Щџл=lџ1џўљјсЈ\џаў>џ0џёўћюЧ~5 џл=lџ.џяўќѓж™PџїЛ=dоџ,џєў§їоЉd' џ2џїўњуГp1.џўї§јтЕv7-џўіќєн­r7,џіўњяеŸf0*џі§ѕцУŠS"  &џѕў§јъвЂl: #џєў§јчЯЋyI !џє§єсЦЄvJ'џўѓќїшаГe@" џўё§ќњїярЪЏmJ. џўь§ќћњјє№щйЧБ•z[@* ћчњљїєёюышрдЧЛЉxdL7'хЧЪЬЭЬЫЩФЛ­›‡se\Q?-" $§9:;;ё:73-% ў$њў.ўў'ў7Д џўўџ;џўїљџїЭачТтџ3џєўќ№Щџл=lџ1џўљјсЉ]џаў>џ0џёўћюЧ7џл=lџ.џяўќѓжšQџїЛ=dоџ,џєў§їоЊe) џ2џіўњуГq2.џўј§јтЕw8-џўіќєн­s8,џѓўњяеŸg1*џѕ§ѕцУŠT"  &џѓў§јъвЂm; #џѓў§јчЯЋzJ! !џє§єсЦЅwK'џўђќїшаГfA" џўё§ќњїярЪЏnK0 џўь§ќћњјє№щйЧВ–|\B+ ћщњљїєёюышреШМЊ‘zfN:)§цШЬЭЮЭЬЪХНЏ‰vh_UB1% §?@AAђ@?;81*  "ѓ§"ћ&ў*ўБ Оџ<џ:џ8џ6џ4џ 1џ /џ-џ*џ'џ$џ џџ"џ(џБџќћЪ*%џћўі­)%џћўѕЋ)%џћўђЇ(%џћўэ%%џћ§ф‹%џћћжq%џћњЦS %џћјИ:%џњўѓЋ,%џњ§х!%џћњЭ_&џњўіЖ;&џњ§щ–(&џњўњЮa'џњўѓЏ9'џњќл|'џњўѕЙG(џњќпƒ"(џњўѕКJ )џљўќк| )џњў№Ћ?* џљўљЭf* џњ§уŽ*+ џњў№ЏF , џњўїШc- џљўћи{!- џњќт‘0. џњ§шЁ? /џњ§ьЋJ 0џљў§юГS1џјў§юЕX1џјў§эГX2џјў§ы­S3џљўќцЄJ5џљўњн•@ 6јў§іЯ‚2 7љ§яЛh#8њсЃO9ќ4 ;§§џќћЪ+§ џіўі­* џћўѕЋ*ў џіўђЇ) џіўэ& џњ§ф‹ !џїћжq!џїњЦS !џћјИ:ў!џіўѓЋ,!џї§х!"џїњЭ`"џіўіЖ;"џњ§щ–($џљўњЮb$џњўѓЏ9$џћќл|%џіўѕЙG$џћќпƒ"'џњўѕКJ &џњўќк| 'џњў№Ћ?( џњўљЭf( џї§уŽ*( џіў№ЏF ( џњўїШc+ џіўћи{!* џњќт‘0, џї§шЁ? ,џі§ьЋJ ,џљў§юГS-џљў§юЕX0џєў§эГX.џјў§ы­S3џіўќцЄJ2џіўњн•@ 3єў§іЯ‚2 3і§яЛh#5њсЃO9ќ4 ;ќќџќћЯ>!џћўіЕ=!џњўѕГ=ў џљўѓЏ;!џљўюЅ7!џњ§ц•2!џїћй}+!џїњЪa!џїјНI!џњўѓБ;"џћ§ц•1ў"џїњаj "џіўіКH"џї§ъœ5#џњўњбj$џњўѓДDў#џћќнƒ)%џіўѕМQ $џћќр‰.  &џљўѕНS  &џіўќл‚+ &џњў№ЎH  ' џіўљЯm ' џі§ф’3 ' џіў№ВM ( џњўїЪi  * џљўћй( ў) џњќу”6 ў* џљ§шЃE,џњ§ь­Nў,џјў§юЕW-џљў§юЗ[.џљў§эД[§.џјў§ыЎVў/џїўќцЅM1џјўњн—Cў1іў§іЯ„6 3љ§яМj&ў3љсЄQ5њ‚67ј 79;=џ!џ!џ!џ!џ!џ!џ"џ"џ"џ"џ#џ#џ#џ$џ$џ$џ%џ%џ&џ&џ'џ'џ(џ(џ)џ*џ*џ+џ,џ-џ-џ.џ/џ0 џ1 џ2 џ3 џ4 џ5џ7џ8џ9џ;џ<ўџў€€@@ l-arm IIџ     tнtљyЕyСuEuUueuuu…u•uЅuЕvзvчvїwyuy…y•yЅ ѕ2yУѓѓУy22§*Яџџ§Я*.§іџ џ§і*§{џџ§{'§ эџџ§э %ўџџў#ўџџў!ўџџў§кџџ§кўtџџўtў&џџў&ўџ џўўmџ џўmўџ"џўў›џ"џў›ўџ$џўў‘џ$џў‘ўџ&џўўXџ&џўXўџ(џўўџ(џўў‚џ(џў‚ўџ*џўўџ*џўў^џ*џў^ўъџ*џўъ ўџ,џўўџ,џўўKџ,џўOўЁџ,џўЋ/џўџ.џў ў џ.џў ўџ.џў7 ў6џ.џўT ўUџ.џўg ўyџ.џ§y ўџ.џ§ ўРџ.џ§Р ўнџ.џ§н ў№џ.џ§№% ўќџ.џ§ќ& ўќџ.џ§ќ" ў№џ.џ§№ ўнџ.џ§н ўРџ.џ§Р ўџ.џ§ ўyџ.џ§y ўUџ.џ§U ў6џ.џ§6 ўџ.џ§ ў џ.џ§  ўџ.џў /џўЏџ,џўЁўeџ,џўKў5џ,џўўџ,џў§ ъџ*џўъ§^џ*џў^ў/џ*џўў'џ*џў§‚џ(џў‚§џ(џўўџ(џў§Vџ&џўX§џ&џўўŒџ$џў‘§џ$џўў›џ"џў›ўџ"џўўlџ џўm§ўџџўў#џџў&ўrџџўt§кџџ§кўџџў!ўџџў#ўџџў%§ эџџ§э '§{џџ§{*§іџ џ§і.§*Яџџ§Я*2ѕ2yУѓђЛj(˜€€@@ New Layer#1џ     zuz‘{н{щzнzэz§{ {{-{={M{]{m{}{{{­{Н{ЭŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџŸ.žџ€€@@debugger-master/resources/icons/openMSX-debugger-logo-64.png0000644000175000017500000001332313560352104023623 0ustar shevekshevek‰PNG  IHDR@@Њiqо pHYs  šœtIMEж 1ЬФпtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“7IDATxкн[ XNiџ~ї% Љ$Me­!ЭŒef$1ВWЈ(‰Ёmв&I’/dŒБЏ™l3У$ыXЃšdi(%{–L3іtПчœѓцM‹(пїПўЯuнзлх=я9чОŸпѓлž‡HTƒё№СCГ‚‚‚~7oоєЙvэZXvvNDVVV`ffІ[zZZЧ3gЮЈEџпЦгЇOКСe‹/ЮŸ2e œбГgOtюмŸ}іКtщ{ћоpїpЧєщгŸ­XёуСЄЄЄIћіэгчn "ЉУœEъ˜Э"9љ"8ˆtцўE˜/RЯм,R;‹ƒ$џЇˆП|љвiыж­cЦŒƒƒFŽuЄ[ПKц–сOŒ> +60 FуяPЯаѕ|_tысƒСCмJlll^ййй!<<ќIдЌ•I Mчнщ, ВёёyрEˆD˜УC=3Ÿ„ў?'^RRby№рСЃЎЎЎ?~|n||МяІM› WЌ:йГяРMO†Йэ€ЋЧN ™ˆŽ ф”€EпŸB^^!шЗ0pр ии|ŠяО CЏoC\'N ЫfžC˜ХCMŸдa;EЊёzџђOž>qŠšљ˜ˆ _ѕ ЎЏ^НZИ9!#;:іB#С7№7ŒѓљAЁI8“zХХЏJЩkушбЃАЖЖFџў§1~Bt bxВъ(Т ‘„щeЁ M)'еџЏ’Пwя^„——V­Z•~ъєЉfDм…А‹АѓњТЄWЇaС’гˆŽ§N.џFЯoжуФЉќ ‰kЃААуЦCЛvэ1Х/ 3Т„iD4œЭ8}†i}†ђЋЇІ‰cыўWШ“g№є r^kˆАa=сТ "‘|ьxо­Э ™№єо Cг84l2‰;/О•М66lиKKK|;9 z†!D6˜0U@PХPњmјрф?~ьъуу aŒМ™@ќ!›pюяžeЌ\›ЫOОЇ—Š„\7 Q1‡ётeё; Р‰Аq#кДiOЏШt б ФЧејeяEмОS„ЫW 0ћ_Щ02# Qљ ˜иџƒ‘/..ЖŒŽŽ~L!ы‘е'd^ŠwWутц*єfqфEЊ|жeЎпxєЮф5ˆ™=ЖЖЖp№жmHсўэЭ‘wэЌ;’ГTM&LК*RИI?ˆЩЩЩG#"" мПЏ/˜§=ТcB1сбЙЬ›ўДNѓ5фUѕ"Бzнйї&ЏsŠюююИtщ*WЏоC#3Ж<|h)ŒsЏ§чйSЇБcЧтьй3ƒшyN„ѓ„\BЁ0HЄєяЩˆsP†УІѓїИCІZS(‹ф’ЈииXP„ЉT„Ѕ?Іg{бГНвj]€-[Жd„††2гЏKиM8-ˆУ"w‘*h5/@8$ъpDF'г —дX†љѓцСЩЩ ЇSR*€ќL?&? ‘ТЃy­‘/**ъъээ={іАйwH&œ$r)}ъS<ОФ…* OњЃ(ьхе y†GЁƒ ,X€Њ†їЄ5D~‰0jr­ ––ЖlјˆЬм%„љ„ЭBЬ_JёZˆT!|lV†РІЫ"мЛџO­ Р‚1ЃЧрў§ћ• А-ё 0‚рК­ж еѓ§§§™єЭ ьs…р›–^ЄєУ‘g"(‚р5a[­™П”rУХХЛvэBFF—9^О|T‡” y>bЅНУАsЕBўі­лf~ў~˜;w.3џЏ б‚И•ЙPАŠ–—ЈШuƒёУ'k•<-E 0Ќрš9s&{'Ж,Бzѕj–‘тмЙsx№ ˆШ"8зŠљљљ§<м=@9П‘J&DВМџѕьёЭ|ЖuН`ьнwЉж``„У‡уиБcиЛw/–/_ЮT'OžЄ"ы&‘w @­@Њњ<˜Л‘N˜Dp(s‘rЂОHx•OGб Q(ввЏ˜˜#ъН$žUE‚I…-ZXVмxTNВ)yr8 o(u}А}Gъ{Хy–ккX›aџЮВфц)p )ўюИ—#ч(МІР+rniЬš&ATЈЗў”Ѓ­еgЌ$ИБ”˜0T‹<…G#п•а™@кžDЈ_BL*‰лѕCУТžXYYyT*€rb‰H94žrёq˜ЕѓЩ?|ј§>Eђ. ‘“•рNЖ)8€Ј0Cќk\8-УЧ"Шd"и-CмЌљся!яТ“gЫ…-IKZ‚:ЏˆM 9RКЙДЗ}ямŠјж”xЦf_ЄG№„у№Ѕф•Ћп,..FHp~XPž<УЅsг1#2чOН&ў WŽ‹Є0nФћ 31Nь—aч&Љ@ž|‚‚ЂЂŸy[ќчZф[šLщ>в‚ CхъеЋLТТТў&+ˆ,їЅълКфqгyђДіфc`л#џќѓДкЄЅЅЂ•‘*OО я ЄЇЅ#$Р‡~–aлz)&{KадМlєXќ/)w§МYѕђƒјК@nЏEў |žМTCо‚а„–‚ЛWd…НhбB?7774jdl]о МзŠ^мь‹ЃaиdŽўžUЭTј9œbу i9ђЏ5Ф§‚4ŒіЙ\T.d2H%"єщХ~KўрВ­Z[k‘яУЇЦ,;фШwШSЖж"OГ/iФТ#Л' ‘ ЪїтHЃЃЃїSIšЃ[ЇNY‡ЈєYЮЭО‚kGAІіРœИ=е ## nЮхЩ?Ш•тIQ"~\БцDT!W(€ЧH)ndЋД[n]-yђrf!o№kђђžDжŽO|dјIЪШЗ!Д вM_“—фХu4јV)1jJў Ябᑉ`С[Р3В€W|јЁДSю c3ьKњЃJђЌНх<ЄYЧw?ЗђГу№ѓЯ?УЇN"В‡ šЯ‰$Ц7і2\ћSзrЦP ќМ4\ЛюЬ›в"џUф-ђi‘ЏOа%тJgiUя2˜M”с9ЦѓБe ЫA”ЋЩŽђiЇ—€Шд.1rЅХЯ+ %% С~Џ=џ?-qсмOXЖd |iц“‰0УЋ Dи6KŽk—u›§WPU4жЌн ‹fŽBЌџ”ѕЅф?Ш7.K^ЌbQ@ГДŽНЕN˜р=AЇ—НKQpp0† ОKІіЭ~ /ЅŸВa0o>ћ“RсsWЎd#7ї*Г„‰;§УсNxLsJи|OсЋщЧŸs› кёў}ЧнЛ oи‡U `єnнS‰ЩA*ŠДf~Д@~xйТ„%#œгŒх— g5ОBћjД ж`О|х ˜/ј$†ТWŸ>5€UнПіфkЪЩzŸr zс<­z\S’ U™дš?яЧN~q[iў‚hžТo†ђзЪzОюиА—хŠœ>Rc?05x>Ÿ”ћкp|ПMiћЋМ *K^ЛСŠюш[Ир,Пe„п8 Э‹оBИъ$dp-…ЂЅEП[С†Лј{r9@9ђЇиЂ~/ў2Ї#Vэьт•tb$э…u?Up–у…ЎэpСGєrј.BйкZШлMњшдЉk8~"™Ѕ§•!џˆ`љоЛHЦю‡йЭыъЕЉ їŸ—3SцЬžэ#јQТ…oZ–Ўћ/…ќНэыN —ГыЂkWл pхJ.д:­о ‹`]ЃmДІ–^‡‹Šžp[жreGОћZZ‘u~Нžeі|™unЙuя(јˆ^BПюsЁrГђv#!qQp›Ѓ5їя?DНњmXљDЏЭаћНЗЮД‡yѓб…ЌШЦМy ˆ@‡ВфeBE&6"…&і !ыкtц%зЊВ ИѕjffЦэ&еt<}њ ѕѕYqdт[ЋЉ,š{pлгšсчШцЬYЋ7фЭ[їƒљ n™tъі6Bеж„[їЌI!—+БuыжZI†юоН]цWEжЊ?^јрaQщƒиЮП OFЛ!"RвЮ‚Ѓь'4/4!ЯъѕКg3/дшГfЭЊЕl№ќљ,(TL\CZ@UЗяЮДєЫхИxёШцoєпъ лTšз‘З‰АюiЭqk~б"жTyZklIиЮ[–DпЂvЪьW1В­sv† ''Їж "7Зqlвkџ,­ЬЖ~лі# ‹ŠWјpЖ$6mJ€ЅЅ5Ÿ„АnŒ&ехB^3ЁJSТТТS&OЦŽ;PPP€ЬЬЬZръе\4аџˆž]зCє!†DёEфќјЭ•žраСZ_lgXWЏ…ъЖњtFHdhиА!† Т-Ÿ .pЧeйжYMы/ЏIЬЉц~а#ѕF{ЇЇІ^ЌжKхххЁC;-п ‡Кuѕ “Щ№yЧŽ˜:u*і§іYС=фццжH€элwBЁdљ„ЪюƒoнJЄъ`-?3Ru1qVЏ0CЮETї}RO(_N№’,54Љо‰<™б УIЪЂwy˜yЊёУї_rg…*ЌкŽG\\\…#+2ї… Ѓ‘vвМмsn]U–Tч}.ŸS•Œt‘lhмXЄЈ^тЃYэџEyх}Шkcљ’O№їпяояgVВџ~šѕDЌќ1'ЃІя’vRYђЉјЛj =]Ж­Їš>єцU5fLя‹ЌЌЌ*џGHefчv:ђ.гњVНэYеzз…sх…‰Јъ,бШHд2хwеГš’зрњ],§~.RRЮrЛ?lЯOћи,ћ›™9Ы.\ИHГОƒkЅлйuGНzКА§Rќ|f„єёОнЪтьѓЊЪФ(бBЅТ\ЩT•Дi-ŽЎ:щ“‰є\‡ЩЂ§'ЫђцDЫЙmъЄ=J(ȘЎBn– 7sиK№/Уіяs.ЊpўЌŠLUEA‰еЫ˜.‡ЛЋьQS х5БИnЁLVzzЦ03o‰ŽmбН‡=Кwя›Ž055G:zJKЗВX:Л@Ћ…­R*Eэ[ЖOд_В6`Š4u^ЌќaТzХЋc”ШЪP•АHP у.нЯ6ўЊы Mі„Ile6~Ƙ oО‹ЎЕ~Ћ5иvЛ%**JU•TЎ*2Њп%vяаЙaaMG,Y*ЂоdЕук"ŽљкNВj„Гt—Ї‡єьdYj Џ,ef„ьFlДќQ\ŒќЩ’xљ-OЩHvƒџчЭ†јccЪIENDЎB`‚debugger-master/resources/icons/stepback.png0000644000175000017500000000044313560352104021116 0ustar shevekshevek‰PNG  IHDRэнтRsRGBЎЮщPLTEџџџ*Uaaa­­­Ь™™дAvtRNS@циfbKGDˆH pHYs ‰ ‰7ЩЫ­tIMEл!+ЪЕ”tEXtCommentCreated with The GIMPяd%nTIDATз]Œ;€0DŸzЃˆ7БIŸ"мџ*.ФJ˜ЧЮВ 2wВzЖ„9ЗжRѕlЇŽУZЃь>(№žPi>‚-u)DF0|ц(%O_|Мі(мBIENDЎB`‚debugger-master/resources/icons/connect.png0000644000175000017500000000151513560352104020754 0ustar shevekshevek‰PNG  IHDRѓџa pHYs  šœtIMEе0ˆШDbKGDџџџ НЇ“кIDAT8Ѕ“MhTW†пямsяœ;sН™L&уhtшЖ"Д S—ю‚+7"QС•"ЁtуR nKн-- ДЋv“HЉ Šu!ЈИPќУпбcr'NюЬ§9їœЯ…ˆVЄ›ОЫї{ПgїўgшCхd4ўЩллЙGрщЋрџLЖAпю}є)j˜ањїВвy шО=И ќp LožЇN@ h ž€Џ вŒ`hШ$УM=Я‚r€"ЛИМfiВ šњІ.а–№]RH”…€u„e012В№ДAъˆдBЋкаГ)ˆM›ЗЙ№K.<с‚]Ыь €Р`[0`hSФYf^Є 5R'&žй"Q =HЏ‚‚4ji=•yѓHЊžЋд–ˆЌ В.ц{vИ’Nфљэ UQ=G<зђ †„PpЉќ|§eгoџ9ќќ№Юlс—ntызSCхрŸ( ЉжбCЊзпГtчЗ“жwц> kёL[ЁžћPЂ4g­ъі“гjн~й{ђчJuЧзЃЂ&Йз§§FYэлЎя]ьuO–WšѕвгZ1в%>ћ…B ўCCcЃе§‹з6Ќ .џ-ГŠDьhl=8ь:Ќ]<Е0ПђзO”з7ее}%ƒE@|zЇК_СXЙ?Ц§ЧwЎОVd–НA<0A‘Еќи§*VљљаїЎ7G6<вя"чQ/ЇшєЧЊOМ;ŠWћ&ЅrsDѕѕ ыHeГ4-G/уБ^Ќ‡У@.lЌQTж!m†$зX\+ˆЯ4М›ЫiUknлRIƒ Ьрљ В@nK…›Ї‰tнRтH/ƒІ‰6(^˜Йѓk–x r9 нFЩ#Ј*Cx@Љ 8p,СИ„D3XYим"ЕŒт‘™˜гЬФФ8€ фя9P)Щ„Фaфp:мyўўь[ЙоШD“mр]?”ГАяwЏ‡dRкnУg9IENDЎB`‚debugger-master/resources/icons/stepout.png0000644000175000017500000000043113560352104021022 0ustar shevekshevek‰PNG  IHDRэнтR pHYs ‰ ‰7ЩЫ­tIMEе2"`qE tEXtCommentCreated with The GIMPяd%nPLTEххх*Uaaa­­­Ь3Ь™™дџџџчœТъtRNS@циfbKGDaˆыQIDATСБТ0 РW"ЈЅd{ІЇШБџ(ќCю ,$3cHŽ;ЯK•њ§ќDбЏ§EлK ІчЋ•Ф`B Q4DбpмЮ L1№оAнГЄ:BIENDЎB`‚debugger-master/resources/icons/stepover.png0000644000175000017500000000043113560352104021166 0ustar shevekshevek‰PNG  IHDRэнтR pHYs ‰ ‰7ЩЫ­tIMEе00ЁўVЦtEXtCommentCreated with The GIMPяd%nPLTEххх*Uaaa­­­Ь3Ь™™дџџџчœТъtRNS@циfbKGDaˆыQIDATСБТ0091дўž о #И8zŠ<і‰ЊЊB› :ћэвйы>ЇЮy??B^ѕ!Dm&ЫѓеmtL! ЌћœрэТЄ,•t?$IENDЎB`‚debugger-master/resources/icons/openMSX-debugger-logo-48.png0000644000175000017500000000762413560352104023634 0ustar shevekshevek‰PNG  IHDR00Wљ‡ pHYs  šœtIMEж 3`–юўtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“јIDAThоНY Xiџ~пГŸ$…d›™K”= 3""1u,eЫоPdIЄMYТЄЭEJіЕ-Ы4!-Цђй2Ъž ЃсЃRїџїМчдзЎ“яћ?зu_g{{оћ~опr?OWƒёў§{.77ЗбУ‡U ‹"##7†‡‡GmкД)ќPм!ЏѓчЯОpс‚~™?’;‰9Х‚o9e@?NдSxtтфЎrюџs|њєIќєщSЛwwїЊaЃџнем!ЏSзБEІэбкФЖЈщ€O§ћ‚““гЛ   ƒлЖэШыЌ№хtжdp:СPуgТZТЪД‘SxЖјŸ“џ№сC—ааа$—WsчЮ]Н­ЗЅuд•ўƒwСjШNќ0`+иlУ/›Џтё“W ЇP4sцL 4ЇЌ„сзыˆ№jB#NЙ‚^ Ъ@BР{Nсэњ?!€OMMщхщѕžV4$'ч/sњЮ3%ѕЩЉUk“руŸзЙЧсщ{™YoPTTT RЉ0fьdt4gФK K‹5№WCсЕ’“Л№џUђ.ќОФЫЫ+ћвЅKЖєй—XXXtьpќ7!aW0DЕпYDтЮнП*/…VЌX!C†Ђ[/Fм—рC№fЄщUі^с>яП&€­ќвЅKГŸ={fAФOЎ?‘{лУћt‘A“ ш5Zгg3Њ$_›7o†ЭPД6ѕЏ\еfDF_Со§зр0nФu0љ”мІ_Lž*M"ŸKIkEЄOђ o ‹ŠюН;‹SP(ќс<ы0 k$€! ііуБё—3є%ƒНпЕ'ВКn4Џы)N6Њіф?~ќ([П>iлЖmKinoТcТ[Т“э;STœТЏ€‘oаtnнЮЎ1y†ќќ| >[ЖlAeУkQ( 9љOнj- ++ЫЮУУу>ХЎ Эyžpƒ№/BЊпГyNБЃwS|j%€сњѕыBbgffV№ъе;ш7šE"І†жŠќпџЭ­ Y—@I7›ц[@8Іa%\ №:ЩШ‹t|)vџаš|1ІM›†;vTњЦŒ'nsђёкWЄœœœFОООЏ“““ПІЙ6vц ?Ъ\t8…O&еl6[†?џ|Uk'Nœ€ГГГRхGhјqpВ1…œl\}­мН{W5iвЄпižN„U„Е=Еp3Ї'PH=ћ„снћМZ x§њ5рччФХХсШ‘#Иyѓ&т]&#˜ˆоZ ˆїSйЉB‰t_–S%Ё#№Аfфщіcb@§ жцЬ™#”V–чЮУБcЧ˜˜ˆЯƒ“ўHьњi- 88xЋНН§b"nI˜–—їЉ.UїU”Ф$`>М}уПˆ<УЂE‹hЕуЪ„х Ч'‘€Aэ,YВф№АaУ–а\Нъ фŽмЅЄXŽWИGpŠљ$Р KŽWK.##SЇN………Ž=Zщ5Ы—/ЧО}ћ*ф@@` 8‰% АМСё НˆAѓ  ъГcрРL€)СИЌ%&ђy$`ќ—­’|^^fЯž-ˆ022‚ЎЎ.nпО]ђ{aa!Ш"4$ чЋЈ–Mф!Жю$ржаш^гщ}ŸŽ7мG Ь еW&j^‹,,њг<ЭuЫ ˜СVŸ“ЭBаš„*М|љ …€X,ЯѓиО}Л№[JJ*<=Цbm`CЌZ„][ъ#5%Ё„|vі+шж#ђ "?“№a"нs}g^Шёњ'‰IеЩ}ђфЩСvvvчh.]‚ЄЌ€ЙlѕЩЋ`]ш™*`ФЊ"фš6m кќ јglаХу[dgд#ƒˆ”п8яFе'щщ٘чNюTмТg0нga‘KIАUч†Иэ'Њщ4З^ 'єgܘёbАM=PіGйl@]Rц'чъЋ+“+WЎB)-- Г\qўИЏ3%ў•кЫ\ѓЇЩ‰И—fŒ›WтnZKи mHїMф'гы8‚=ЋHjQвўъ№wЧзЙFЌšUxА{їюЮ~ЯŠЋЬ?XQчЖв0+эы3{ЃХx“%)pљї•иlFпIKpђ -EИž$…QSыrфmX>z’€.Zaх O"&fЋхЈQЃnV" ”Œ–XЭŒчуйѓ7ŸpрР>l —”!Ÿ§ 5ЖDnDњ™@ќuІQФhи€Cƒњbќѕ@Š6m‰ЈlBАR'5#/щЊЮq["п‚аŒBI—r‚+ы^зЏkI{кgmкДщZJ@ONЦL/›LН ЖZ7ЌЦЁт2оО\oяТХ‰8Œ-Сг{2,і6в„ #?Hї%є"t+EОЅzѕEH@=6Чц C›‘NNN[iBЈ1­ў_œl н`"њY-Ч?џ|Ј”ќGЊѓГœ[—]§'Ѓpxяn„JЅXХёш !пЌ)р :HNс#ьiqљЁЅШїf%”ˆwTЧ}1yž‘7`ЩLѓ№ч+-ЋdДœ\\\2ЭЬЬzЉ+бД4NЦJлxш5tТ™Г7*Р<Эž(™†МOюOЦо˜hЌ“Щ№+‘N$œ&Œ6сфЦxёlkI/иЕћ7˜uІ*щWŽ|;"ў-с+"mTŠМŒ-Ф§*{ƒ›л<[*­џаNj1/ŸД’­>'s/‹бŽ!јјБ ’­Ѓ2в%x~П1вЏЎAа*Ќ&GЬ7"DХу@NЌсFjМЬОXСN|Ђ§ЦYДя0J]2yБ†МЈ1ЏЯbŸРШ 9”MV)ЂŽў№ќЁvΘ6}ЮЛŽ]&J(F {>ˆк4сSА!d6„ЙукЕ4x,˜€‹ПЭFФЦ`ЁмЛw i)[qѕ’._tЦ­ыы•u•ЪlЊLHbтtшLхTм^CОžfхЅХфђеьЄCs85аkфKБ?..ю„щˆкВББћЛЧŽјуаAO,X ///Аƒ­eЫ–aџў§јвqш№№R uх)WJ аЏZ€ЄћNNЙ\sх^щ}'4j6­кŽAліhбЪ‹ќ~Ц‚ аЋW/5ЧƒАgЯJіОHР‡yhmB}AlZ•€Їqеxžд… е‡QdЉГЁnjS…„Z?еmЉrL;ЙBQwфК*дЉї#ъ5ГN#рююGf.Ѕж"М|Те˜U&ртчœ6O-|?Ї˜Ћ!яL˜Ђ!?Jнt˜‡ggŸьм“О)цЉЏЎ!s'Е/щ„О§TИrхŠж.\HƒHЦШ+X“эBKNjћw yЙЃІнwLk 3ХžЄОFЈыЌ,іl@=§oiїѕV+oофТаЈ&ЫgИCЭv<тіеaуXЮЋXЉАƒ[ЖoVЬв„зњоVуeziъy+JЦІˆŒмЊ•ЖњЎїhu§/+`_wlrнбыЬ:кiN ЪЛDKѕЁ- 3цх‘Уд^ђНЦAЖе4ЂњTЅцhFcнŠ­C12†U.П%hfьДюЦлhвмВ”?/ЖИфSnšфž о„0‚3здёo†DBўў‹ЕрБђ‹зgњ:!ŒаЈк//РИед}љљŸp1щ”К=е› з’ЮjŸ"ьЄ&Ћ›H-џ#NмRгˆєhЫйP(БкŽхЁЬЎцj;Оi5)1?_н=ccAІ4гoЏŽmцб…- Jcƒ{kЌ@kѕеЇ=Вœт?ВVЅдcс2šЧ(Кж ‡GНШ~§Ÿyшєы›iѓkЕG’жZZТцУDˆ{‘И.кЖm??С/i;ипŒДЇЇ+jрVcТ/ю”§,’ѕwш|™‰йq`п~vleд ЦКЅ`ƒЛЋпSћgф'Nœˆ;wюЈЭxћ6ЭП2eOБu­Ÿ%ЄвnИчsfВЪЏЮў§Бшк­7dr љŽћлuъд?~=BnЎіж"&f'x‘о1юK‡RзbЪžНЇЊ|Ьь\hкєљšАj.<v>ФќQHhЈpФђфЩ­ШggПDЫ–эѓЉz™љv&œd№ БЃЛ›ЩлЫН‘žК звЯвŠў]Ёщ8 aˆАњFFсъъЪўKV:ыГЄйљ Зјј8ŒmƒV-ЅПЊ~9tыТhк„3lа@Kђ­[ё~ “І?М­,z‘ЉD1ž?Tтђ9$ž€Є‹Qфџ]Щ fCOO РТ… …*єюнЛ*,УkьмБсЁmP‰лщ <ОЏОCж]v?љ‡ˆѕвэ?к№Ц5"пУ\д-nЏ,Ї4ёЪ№єЇŽšрkg+[Мx1Ќ­­‘œœ\хЊ?}њ‡Zсб=вѓUuП“‡eЯћ|ЯїЈ–МBС59uT~ѓsфK#э’Ў&ЧU Ш˜ь–?RgЂNŸ>Ž1н№\‹ћ0ьŠ‘>ЎoPЩ ]ё]+]ѓBЫI~;eˆ„„иЯnfXЌГФN<3N•*ц+ЊюЉO›"о\Ѕ€р щЙпЯЪёрVЭˆ?КЇDj’лЗШ1aМ\gЙ#((лЗяпў§Жžžо9в&&э —+IЅ\„эбмЩžШв‡'ЫѓoІRќg|ўž1›e/DЂЊ}‘X"с:72фЇЗiЭЏщ§h‡Uё1ыт‹„4k+ёUњќkŸяELл‹"›4цН)ьlщЯŒ8ОЎ)љї‰TўR0’ЄёFj‹дQyЋЅЗƒ2}sR…œkіѕWМeп>ЂщуЧŠƒцЭ‘ь №—žY(Н,НЛiƒє!Ян%Ы‹Œžегуъ§єu‹+у+гDIENDЎB`‚debugger-master/resources/icons/breakpoint.png0000644000175000017500000000052413560352104021460 0ustar shevekshevek‰PNG  IHDR Vu\ч pHYs  šœtIMEе*Љ5 ЛtEXtCommentCreated with The GIMPяd%nbKGDџџџ НЇ“ИIDAT(‘cјџџ?)…г\SѓпVSѓП  ƒиMееџБjˆ№іўяЭШј6Pш ƒи Бp І Щ^@‰у@юамЙџCй 1\}YйИе г>‚ИѓцA„јT $gЋЁа ЯЯvШd˜bўuH љєI1В“l :dOџ†bdOWўG жp<Сьюў#@ИЁМ%т@ЮЈЬЯЧqФb“ JОг6IENDЎB`‚debugger-master/resources/openmsx-debugger.rc0000644000175000017500000000707313560352104021310 0ustar shevekshevek// Originally a Microsoft Developer Studio generated resource script, // but now maintained manually because we want to build with MinGW32+MSYS. // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif // Include resource info from the openMSX Debugger build process. #include "resource-info.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. OPENMSX ICON DISCARDABLE "icons/openmsx-debugger.ico" #ifndef _MAC ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION OPENMSXDEBUGGER_VERSION_INT PRODUCTVERSION OPENMSXDEBUGGER_VERSION_INT FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080004b0" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "openMSX Debugger\0" VALUE "FileVersion", OPENMSXDEBUGGER_VERSION_STR VALUE "InternalName", "openmsx-debugger\0" VALUE "LegalCopyright", "Copyright 2006\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "openmsx-debugger.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "openMSX Debugger\0" VALUE "ProductVersion", OPENMSXDEBUGGER_VERSION_STR VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x800, 1200 END END #endif // !_MAC #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // English (U.S.) (unknown sub-lang: 0xC) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, 0xC #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) (unknown sub-lang: 0xC) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED debugger-master/AUTHORS0000644000175000017500000000033113560352104014533 0ustar shevekshevekPrime Developers: Edwin Velds Additional Development: Wouter Vermaelen Albert Beevendorp Build System: Maarten ter Huurne debugger-master/GPL0000644000175000017500000004311013560352104014032 0ustar shevekshevek GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. debugger-master/README0000644000175000017500000000115313560352104014346 0ustar shevekshevek---------------- openMSX debugger ---------------- The openMSX debugger is a separate program that interfaces with openMSX and controls its debugger from within a graphical user interface. * Requirements The debugger requires the Qt5 GUI library to be installed. If you are installing from binary packages, make sure you install the development package (name ending with "-dev" or "-devel") as well. For Mac OS X use "brew install qt5" to install the library. A (reasonably) new version of openMSX. * Building Build with: make * Installing Install derived/bin/openmsx-debugger manually in any place you want. debugger-master/node.mk0000644000175000017500000000011113560352104014735 0ustar shevekshevekinclude build/node-start.mk SUBDIRS:= \ src include build/node-end.mk debugger-master/.gitignore0000644000175000017500000000002513560352104015453 0ustar shevekshevekbuild/*.pyc derived/ debugger-master/build/0000755000175000017500000000000013560352104014565 5ustar shevekshevekdebugger-master/build/detectsys.py0000644000175000017500000000566113560352104017156 0ustar shevekshevek# Detect the native CPU and OS. # Actually we rely on the Python "platform" module and map its output to names # that the openMSX build understands. from platform import machine, python_version, system import sys def detectCPU(): '''Detects the CPU family (not the CPU model) of the machine were are running on. Raises ValueError if no known CPU is detected. ''' cpu = machine().lower() dashIndex = cpu.find('-') if dashIndex != -1: # Hurd returns "cputype-cpusubtype" instead of just "cputype". cpu = cpu[ : dashIndex] if cpu in ('x86_64', 'amd64'): return 'x86_64' elif cpu in ('x86', 'i386', 'i486', 'i586', 'i686'): return 'x86' elif cpu.startswith('ppc') or cpu.endswith('ppc') or cpu.startswith('power'): return 'ppc64' if cpu.endswith('64') else 'ppc' elif cpu.startswith('arm'): return 'arm' elif cpu == 'aarch64': return 'aarch64' elif cpu == 'aarch64_be': return 'aarch64_be' elif cpu.startswith('mips') or cpu == 'sgi': return 'mipsel' if cpu.endswith('el') else 'mips' elif cpu == 'm68k': return 'm68k' elif cpu == 'ia64': return 'ia64' elif cpu.startswith('alpha'): return 'alpha' elif cpu.startswith('hppa') or cpu.startswith('parisc'): return 'hppa' elif cpu.startswith('s390'): return 's390' elif cpu.startswith('sparc') or cpu.startswith('sun4u'): return 'sparc' elif cpu.startswith('sh'): return 'sheb' if cpu.endswith('eb') else 'sh' elif cpu == 'avr32': return 'avr32' elif cpu == '': # Python couldn't figure it out. os = system().lower() if os == 'windows': # Relatively safe bet. return 'x86' raise ValueError('Unable to detect CPU') else: raise ValueError('Unsupported or unrecognised CPU "%s"' % cpu) def detectOS(): '''Detects the operating system of the machine were are running on. Raises ValueError if no known OS is detected. ''' os = system().lower() if os in ('linux', 'darwin', 'freebsd', 'netbsd', 'openbsd', 'gnu'): return os elif os.startswith('gnu/'): # GNU userland on non-Hurd kernel, for example Debian GNU/kFreeBSD. # For openMSX the kernel is not really relevant, so treat it like # a generic GNU system. return 'gnu' elif os.startswith('mingw') or os == 'windows': return 'mingw32' elif os == 'sunos': return 'solaris' elif os == '': # Python couldn't figure it out. raise ValueError('Unable to detect OS') else: raise ValueError('Unsupported or unrecognised OS "%s"' % os) if __name__ == '__main__': try: print >> sys.stderr, ' Using Python %s native system detection...' % ( python_version() ) hostCPU = detectCPU() hostOS = detectOS() if hostOS == 'mingw32' and hostCPU == 'x86_64': # It is possible to run MinGW on 64-bit Windows, but producing # 64-bit code is not supported yet. hostCPU = 'x86' print >> sys.stderr, ' Detected system: %s-%s' % (hostCPU, hostOS) print 'OPENMSX_TARGET_CPU=%s' % hostCPU print 'OPENMSX_TARGET_OS=%s' % hostOS except ValueError, ex: print >> sys.stderr, ex sys.exit(1) debugger-master/build/msvc/0000755000175000017500000000000013560352104015535 5ustar shevekshevekdebugger-master/build/msvc/openmsx-debugger.vcxproj.filters0000644000175000017500000004050413560352104024077 0ustar shevekshevekяЛП {d10bffda-03ce-4fc1-806b-60d0691c4f3d} cpp;c;cxx;rc;def;r;odl;idl;hpj;bat {8389e4f3-199a-41f9-9ac6-ee09f539bd31} h;hpp;hxx;hm;inl {0e0c2a83-0825-437e-8c46-f9ddd76f91ee} ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe {2862c03e-1d7e-477e-94db-e6571e6b1b7c} {16070eac-bd01-46d0-97ec-caed480f2586} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files Moc files openmsx openmsx openmsx Source Files openmsx openmsx openmsx openmsx openmsx UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files UI Header Files Source Files Source Files Source Files Source Files Source Files Resource Files Resource Files debugger-master/build/msvc/openmsx-debugger.sln0000644000175000017500000000266513560352104021537 0ustar shevekshevekяЛП Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27703.2035 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmsx-debugger", "openmsx-debugger.vcxproj", "{A9B5A99F-45C3-4BF9-B596-568F082A59D6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|Win32.ActiveCfg = Debug|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|Win32.Build.0 = Debug|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|x64.ActiveCfg = Debug|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|x64.Build.0 = Debug|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|Win32.ActiveCfg = Release|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|Win32.Build.0 = Release|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|x64.ActiveCfg = Release|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2ABAA41E-895B-48B7-9665-752AAC63C190} EndGlobalSection EndGlobal debugger-master/build/msvc/openmsx-debugger.vcxproj0000644000175000017500000032121413560352104022430 0ustar shevekshevekяЛП Debug Win32 Debug x64 Release Win32 Release x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6} wxCatapult 10.0 Application v142 Application v142 Application v142 Application v142 <_ProjectFileVersion>10.0.30319.1 $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ $(OpenMSXOutDir)\ $(OpenMSXIntDir)\ X64 /MP %(AdditionalOptions) Disabled $(BuildDir)\config;$(OpenMSXSrcDir)\ui;$(OpenMSXSrcDir)\openmsx;$(LibQtIncludeDir);$(LibQtIncludeDir)\QtCore;$(LibQtIncludeDir)\QtGui;$(LibQtIncludeDir)\QtNetwork;$(LibQtIncludeDir)\QtWidgets;$(LibQtIncludeDir)\QtXml;%(AdditionalIncludeDirectories) __SSE2__;WIN32;_WIN64;__x86_64;UNICODE;_UNICODE;WIN32_LEAN_AND_MEAN;SECURITY_WIN32;DEBUG;_DEBUG;_CONSOLE;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions) MultiThreadedDebug Level4 ProgramDatabase 4324;4063;4121;4125;4127;4189;4201;4244;4310;4355;4505;4512;4611;4702;%(DisableSpecificWarnings) $(LibQtDir)\lib;%(AdditionalLibraryDirectories) true Console MachineX64 secur32.lib;ws2_32.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Networkd.lib;Qt5Widgetsd.lib;Qt5Xmld.lib;%(AdditionalDependencies) $(BuildDir)\config $(BuildDir)\config secur32.lib;ws2_32.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Networkd.lib;Qt5Widgetsd.lib;Qt5Xmld.lib;%(AdditionalDependencies) $(LibQtDir)\lib;%(AdditionalLibraryDirectories) $(BuildDir)\config;$(OpenMSXSrcDir)\ui;$(OpenMSXSrcDir)\openmsx;$(LibQtIncludeDir);$(LibQtIncludeDir)\QtCore;$(LibQtIncludeDir)\QtGui;$(LibQtIncludeDir)\QtNetwork;$(LibQtIncludeDir)\QtWidgets;$(LibQtIncludeDir)\QtXml;%(AdditionalIncludeDirectories) $(BuildDir)\config /MP %(AdditionalOptions) Full AnySuitable true Size true true true $(BuildDir)\config;$(OpenMSXSrcDir)\ui;$(OpenMSXSrcDir)\openmsx;$(LibQtIncludeDir);$(LibQtIncludeDir)\QtCore;$(LibQtIncludeDir)\QtGui;$(LibQtIncludeDir)\QtNetwork;$(LibQtIncludeDir)\QtWidgets;$(LibQtIncludeDir)\QtXml;%(AdditionalIncludeDirectories) true false MultiThreaded true Level4 ProgramDatabase 4324;4063;4121;4125;4127;4189;4201;4244;4310;4355;4505;4512;4611;4702;%(DisableSpecificWarnings) secur32.lib;ws2_32.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Network.lib;Qt5Widgets.lib;Qt5Xml.lib;%(AdditionalDependencies) $(LibQtDir)\lib;%(AdditionalLibraryDirectories) $(BuildDir)\config /MP %(AdditionalOptions) Full AnySuitable true Size true true $(BuildDir)\config;$(OpenMSXSrcDir)\ui;$(OpenMSXSrcDir)\openmsx;$(LibQtIncludeDir);$(LibQtIncludeDir)\QtCore;$(LibQtIncludeDir)\QtGui;$(LibQtIncludeDir)\QtNetwork;$(LibQtIncludeDir)\QtWidgets;$(LibQtIncludeDir)\QtXml;%(AdditionalIncludeDirectories) true MultiThreaded true Level4 ProgramDatabase 4324;4063;4121;4125;4127;4189;4201;4244;4310;4355;4505;4512;4611;4702;%(DisableSpecificWarnings) secur32.lib;ws2_32.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Network.lib;Qt5Widgets.lib;Qt5Xml.lib;%(AdditionalDependencies) $(LibQtDir)\lib;%(AdditionalLibraryDirectories) @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating config headers... Version.ii Generating config headers... Version.ii Generating config headers... Version.ii Generating config headers... Version.ii for /f "delims=" %%d in ("$(OpenMSXConfigDir)") do set CONFIG_DIR=%%~fd rem echo CONFIG_DIR=%CONFIG_DIR% set PYTHONPATH=%PYTHONPATH%;$(OpenMSXRootDir)\build python "$(OpenMSXRootDir)\build\msvc\\genconfig.py" $(PlatformName) "$(ConfigurationName)" "%CONFIG_DIR% " for /f "delims=" %%d in ("$(OpenMSXConfigDir)") do set CONFIG_DIR=%%~fd rem echo CONFIG_DIR=%CONFIG_DIR% set PYTHONPATH=%PYTHONPATH%;$(OpenMSXRootDir)\build python "$(OpenMSXRootDir)\build\msvc\\genconfig.py" $(PlatformName) "$(ConfigurationName)" "%CONFIG_DIR% " for /f "delims=" %%d in ("$(OpenMSXConfigDir)") do set CONFIG_DIR=%%~fd rem echo CONFIG_DIR=%CONFIG_DIR% set PYTHONPATH=%PYTHONPATH%;$(OpenMSXRootDir)\build python "$(OpenMSXRootDir)\build\msvc\\genconfig.py" $(PlatformName) "$(ConfigurationName)" "%CONFIG_DIR% " for /f "delims=" %%d in ("$(OpenMSXConfigDir)") do set CONFIG_DIR=%%~fd rem echo CONFIG_DIR=%CONFIG_DIR% set PYTHONPATH=%PYTHONPATH%;$(OpenMSXRootDir)\build python "$(OpenMSXRootDir)\build\msvc\\genconfig.py" $(PlatformName) "$(ConfigurationName)" "%CONFIG_DIR% " Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... Generating moc_%(Filename).cpp... @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp @rem copy %0 foo.bat if not exist "$(MocOutDir)" (md "$(MocOutDir)") "$(LibQtToolsDir)\moc.exe" "%(FullPath)" -o "$(MocOutDir)\moc_%(Filename).cpp" $(MocOutDir)\moc_%(Filename).cpp Generating qrc_%(FileName).cpp... Generating qrc_%(FileName).cpp... Generating qrc_%(FileName).cpp... Generating qrc_%(FileName).cpp... "$(LibQtToolsDir)\rcc.exe" -name resources "%(FullPath)" -o "$(QrcOutDir)\qrc_%(Filename).cpp "$(LibQtToolsDir)\rcc.exe" -name resources "%(FullPath)" -o "$(QrcOutDir)\qrc_%(Filename).cpp "$(LibQtToolsDir)\rcc.exe" -name resources "%(FullPath)" -o "$(QrcOutDir)\qrc_%(Filename).cpp "$(LibQtToolsDir)\rcc.exe" -name resources "%(FullPath)" -o "$(QrcOutDir)\qrc_%(Filename).cpp $(QrcOutDir)\qrc_%(Filename).cpp $(QrcOutDir)\qrc_%(Filename).cpp $(QrcOutDir)\qrc_%(Filename).cpp $(QrcOutDir)\qrc_%(Filename).cpp if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h Designer if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" if not exist "$(UiOutDir)" (md "$(UiOutDir)") "$(LibQtToolsDir)\uic.exe" -o "$(UiOutDir)\ui_%(Filename).h" "%(FullPath)" Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... Generating ui_%(Filename).h... $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h $(UiOutDir)\ui_%(Filename).h debugger-master/build/msvc/openmsx-debugger.vcproj0000644000175000017500000031735613560352104022254 0ustar shevekshevek debugger-master/build/msvc/genconfig.py0000644000175000017500000000165013560352104020050 0ustar shevekshevek# Generates configuration headers for VC++ builds import sys import os.path import outpututils import win_resource import version2code # # platform: one of { Win32, x64 } # configuration: one of { Debug, Developer, Release } # outputPath: the location in which to generate config files # def genConfig(platform, configuration, outputPath): # # resource-info.hh # resourceInfoHeader = os.path.join(outputPath, 'resource-info.h') generator = win_resource.iterResourceHeader() outpututils.rewriteIfChanged(resourceInfoHeader, generator) # # version.ii # versionHeader = os.path.join(outputPath, 'version.ii') generator = version2code.iterVersionInclude() outpututils.rewriteIfChanged(versionHeader, generator) if len(sys.argv) == 4: genConfig(sys.argv[1], sys.argv[2], sys.argv[3]) else: print >> sys.stderr, 'Usage: python genconfig.py platform configuration outputPath' sys.exit(2) debugger-master/build/msvc/openmsx-debugger.props0000644000175000017500000000723413560352104022103 0ustar shevekshevekяЛП ..\.. $(OpenMSXRootDir)\derived $(DerivedDir)\$(Platform)-VC-$(Configuration) $(DerivedDir)\3rdparty\src $(ThirdPartySrcDir)\$(LibQtName)\lib $(OpenMSXRootDir)\src $(BuildDir)\build $(BuildDir)\install $(BuildDir)\config $(OpenMSXSrcDir)\moc $(OpenMSXSrcDir)\ui $(OpenMSXSrcDir)\qrc Qt5.7.0 $(ThirdPartySrcDir)\$(LibQtName)\5.7\msvc2015 $(ThirdPartySrcDir)\$(LibQtName)\5.7\msvc2015_64 $(LibQtDir)\include $(LibQtDir)\lib $(LibQtDir)\bin <_ProjectFileVersion>14.0.25431.1 $(OpenMSXRootDir) true $(DerivedDir) true $(BuildDir) true $(ThirdPartySrcDir) true $(ThirdPartyIntDir) true $(ThirdPartyOutDir) true $(OpenMSXSrcDir) true $(OpenMSXIntDir) true $(OpenMSXOutDir) true $(OpenMSXConfigDir) true $(MocOutDir) true $(UiOutDir) true $(QrcOutDir) true $(LibQtName) true $(LibQtToolsDir) true debugger-master/build/msysutils.py0000644000175000017500000000430313560352104017213 0ustar shevekshevekfrom os import environ from os.path import isfile from subprocess import PIPE, Popen import sys def _determineMounts(): # The MSYS shell provides a Unix-like file system by translating paths on # the command line to Windows paths. Usually this is transparent, but not # for us since we call GCC without going through the shell. # Figure out the root directory of MSYS. proc = Popen( [ msysShell(), '-c', '"%s" -c \'import sys ; print sys.argv[1]\' /' % sys.executable.replace('\\', '\\\\') ], stdin = None, stdout = PIPE, stderr = PIPE, ) stdoutdata, stderrdata = proc.communicate() if stderrdata or proc.returncode: if stderrdata: print >> sys.stderr, 'Error determining MSYS root:', stderrdata if proc.returncode: print >> sys.stderr, 'Exit code %d' % proc.returncode raise IOError('Error determining MSYS root') msysRoot = stdoutdata.strip() # Figure out all mount points of MSYS. mounts = { '/': msysRoot + '/' } fstab = msysRoot + '/etc/fstab' if isfile(fstab): try: inp = open(fstab, 'r') try: for line in inp: line = line.strip() if line and not line.startswith('#'): nativePath, mountPoint = ( path.rstrip('/') + '/' for path in line.split() ) mounts[mountPoint] = nativePath finally: inp.close() except IOError, ex: print >> sys.stderr, 'Failed to read MSYS fstab:', ex except ValueError, ex: print >> sys.stderr, 'Failed to parse MSYS fstab:', ex return mounts def msysPathToNative(path): if path.startswith('/'): if len(path) == 2 or (len(path) > 2 and path[2] == '/'): # Support drive letters as top-level dirs. return '%s:/%s' % (path[1], path[3 : ]) longestMatch = '' for mountPoint in msysMounts.iterkeys(): if path.startswith(mountPoint): if len(mountPoint) > len(longestMatch): longestMatch = mountPoint return msysMounts[longestMatch] + path[len(longestMatch) : ] else: return path def msysActive(): return environ.get('OSTYPE') == 'msys' or 'MSYSCON' in environ def msysShell(): return environ.get('MSYSCON') or environ.get('SHELL') or 'sh.exe' if msysActive(): msysMounts = _determineMounts() else: msysMounts = None if __name__ == '__main__': print 'MSYS mounts:', msysMounts debugger-master/build/version.py0000644000175000017500000000447213560352104016633 0ustar shevekshevek# Contains the openMSX version number and versioning related functions. from executils import captureStdout from makeutils import filterLines from os import makedirs from os.path import isdir import re # Name used for packaging. packageName = 'openmsx-debugger' # Version number. packageVersionNumber = '0.10.0' # Note: suffix should be empty or with dash, like "-rc1" or "-test1" packageVersionSuffix = '' packageVersion = packageVersionNumber + packageVersionSuffix # Is this a release version ("True") or development version ("False"). releaseFlag = False def _extractRevisionFromStdout(log, command, regex): text = captureStdout(log, command) if text is None: # Error logging already done by captureStdout(). return None # pylint 0.18.0 somehow thinks captureStdout() returns a list, not a string. lines = text.split('\n') # pylint: disable-msg=E1103 for revision, in filterLines(lines, regex): print >> log, 'Revision number found by "%s": %s' % (command, revision) return revision else: print >> log, 'Revision number not found in "%s" output:' % command print >> log, text return None def extractGitRevision(log): return _extractRevisionFromStdout( log, 'git describe --dirty', r'\S+?-(\S+)$' ) def extractNumberFromGitRevision(revisionStr): if revisionStr is None: return None return re.match(r'(\d+)+', revisionStr).group(0) _cachedRevision = False # because None is a valid result def extractRevision(): global _cachedRevision if _cachedRevision is not False: return _cachedRevision if releaseFlag: # Not necessary, we do not append revision for a release build. return None if not isdir('derived'): makedirs('derived') log = open('derived/version.log', 'w') print >> log, 'Extracting revision info...' try: revision = extractGitRevision(log) print >> log, 'Revision string: %s' % revision print >> log, 'Revision number: %s' % extractNumberFromGitRevision(revision) finally: log.close() _cachedRevision = revision return revision def extractRevisionNumber(): return int(extractNumberFromGitRevision(extractRevision()) or 1) def extractRevisionString(): return extractRevision() or 'unknown' def getVersionedPackageName(): if releaseFlag: return '%s-%s' % (packageName, packageVersion) else: return '%s-%s-%s' % ( packageName, packageVersion, extractRevisionString() ) debugger-master/build/makeutils.py0000644000175000017500000000346613560352104017146 0ustar shevekshevekimport re def filterLines(lines, regex): '''Filters each line of the given line iterator using the given regular expression string. For each match, a tuple containing the text matching each capture group from the regular expression is yielded. ''' matcher = re.compile(regex) for line in lines: if line.endswith('\n'): line = line[ : -1] match = matcher.match(line) if match: yield match.groups() def filterFile(filePath, regex): '''Filters each line of the given text file using the given regular expression string. For each match, a tuple containing the text matching each capture group from the regular expression is yielded. ''' inp = open(filePath, 'r') try: for groups in filterLines(inp, regex): yield groups finally: inp.close() def joinContinuedLines(lines): '''Iterates through the given lines, replacing lines that are continued using a trailing backslash with a single line. ''' buf = '' for line in lines: if line.endswith('\\\n'): buf += line[ : -2] elif line.endswith('\\'): buf += line[ : -1] else: yield buf + line buf = '' if buf: raise ValueError('Continuation on last line') def extractMakeVariables(filePath): '''Extract all variable definitions from the given Makefile. Returns a dictionary that maps each variable name to its value. ''' makeVars = {} inp = open(filePath, 'r') try: for name, value in filterLines( joinContinuedLines(inp), r'[ ]*([A-Za-z0-9_]+)[ ]*:=(.*)' ): makeVars[name] = value.strip() finally: inp.close() return makeVars def parseBool(valueStr): '''Parses a string containing a boolean value. Accepted values are "true" and "false"; anything else raises ValueError. ''' if valueStr == 'true': return True elif valueStr == 'false': return False else: raise ValueError('Invalid boolean "%s"' % valueStr) debugger-master/build/package-darwin/0000755000175000017500000000000013560352104017442 5ustar shevekshevekdebugger-master/build/package-darwin/debugger-logo.icns0000644000175000017500000012766413560352104023062 0ustar shevekshevekicnsЏДics#HРр№џ№џ№џќџўџ?џ?џ?џўќќ?ў?џРр№џ№џ№џќџўџ?џ?џ?џўќќ?ў?џis32С}Z:YX† ЭŒmњљ„ ‚…жт у€ў‰њН‚yџ<ўнЂф- vџgўўЪєў–т, bџoўљ)}ТЂн URўўЭ­жЧ~. _A§ўЖъ—G‚ Q#ЉмЈЅЇТћЉƒLbE–ј€џѓ ‡№€џ@ @‚ж€џwх>qџs‚•№Љ)И€џЬ(ГтобъЪЈћоЙзтЩinГЌЌІ‰‰|gЃОРФ }\bџZЈўљ){gFн@?UU“ўўЭ  );,_APi§ўs4 ,-QNEІЬ:JZёО=€Z^pn\Ѕј€џі6M=XV7-№€џQKh,A@$ ж€џ‚:щT+tџ}‚ˆчЌ,,Й€џЪ‚ *ЫЪЈћЯ€€#Œ~*€s8mk?‚ка›ЅОƒ aЁкџџџџџџХ=žДћџџџџџџџce†XџџџџџџџџЎt(}џџџџџџџџгeˆџџџџџџџџџѕ’Z‡џџџџџџџџџџџэRfџџџџџџџџџџџџА,ЌўџџџџџџџџџџџОнўџџџџџџџџџџџЂpџџџџџџџџџџўџ_3џџџџџџџџџџс{0џџџџџџџџџџЬЮџџџџџџџџџqЈџџџџџџџџўўџи"%ЪцьчедоФЂ­Ьщі˜ICN#љРџ№џј?џќ?џўџўџџџџџџџџџџџ€џџџрџџџјџџџќџџўџџў?џџўџџџџџџџџџџџўџџўџџўџџќџџ№џџ№џџ№џџрџџрџџќџџўџџўџёџљРџ№џј?џќ?џўџўџџџџџџџџџџџ€џџџрџџџјџџџќџџўџџў?џџўџџџџџџџџџџџўџџўџџўџџќџџ№џџ№џџ№џџрџџрџџќџџўџџўџёџil32\ƒЮo^WUb?“ ДpL>'#,‹qD"‘ nкё]gюўўы`2Ž’ˆџџУ9ф‚ў‰1/\‰Д~џџіž„ўqlџџѕ6ˆyэџџ+і„ўѕSюџџм†ЪU€џj†ў–Љ€џ3†oџџ€Б†ўчW˜Пг\†eцџџй‡ўYйЪТb†Wџџ€ёўЩlж€ў_€џL†Uџџ€№€ў єi4#ўіИhбџў†bHџ€љ€ў і0ПŽЫ|Ткž‡†3иў н•Ёъв™зйЄA†?O‚Ѕ‚ў а”ъъВУъ  ‡l1oў §kъъшpG^“ˆY*€%ј€ў ЦЎъщ•I auˆ?V,Ж€ў ‘ъо–˜БŒЎѓџ  ‰&8 MЎЊЪ|ЏŠАЄАміџЅˆ "Hp|‚hQ„Й‡џаŒ408ƒу†џ0’_…џ|”У„џЛˆ0ˆŒ„џу‡т†Я„џі†јг…{…џыˆЫџо1‚Ёё…џДˆg€џЄ2€)Ду„џўCˆ 1зыџџЗ-,vй‚џ§жs%† ›оуубУЪўџџKCЇљ€џОЂПнунС„ƒЌƒу рДњџюАџџівЎйусупq…ут™щ§ў§эПz•Яуусс€уФ €8alprpqpgF  Jx•œЃЊЎGƒ Юo^WUd? ДpLA,(1ŒqE'Œ nкё…akюўўы`5€Š’ˆџџЧ>"х‚ўŠ35aˆД~џџі „ўqnџџі;‡yэџџ2#і„ўѕSюџџн†ЪU€џo†ў–Љ€џ7†oџџД†ўчX˜Пг`†eцџџк‡ўYйЪТf†Wџџ ёўЩlж€ў_€џN†Uџџ №€ў єi4#ўіИgЭџў„bHџ љ€ў і0О‡НwЙйž€‚†3€йў н”–йЦ“ЩЫ›>‚?O€І‚ў а‹ййЎЕйƒ•‚l1€rў §gййнlCX‰€Y*(ј€ў ЦЁйк]q €?V,З€ў йвyЈёџЁ#„)< NЌЇЩwЉŠЉ†œиіџЅ† %Jp{€gQ„Й‡џб‡€64;ƒу†џ2‡€_…џ}ˆ€У„џЛ‡3€Œ„џу‡т€Я„џі†јг€{…џы‡ Ьџо2Ёё…џДˆh€џЄ2)Ду„џўCˆ 1›жыџџЗ-,wй‚џ§жs† ”еййЩМЩўџџKCЇљ€џНžЗейдЙ~ƒІƒй зЏњџюАџџівЊайзйжm††й —щ§ў§эПyЧййзз€йМ €1[glmjlkcC  Hq‡Ž•›ЃЇDƒ Юo^WUb?QowreŽДpLq‚žqNwzwutl_‹pкіО­Џіўўы`[nljjgZ‰’Šџџп–„ё‚ўŠQa‡Єw]C‡Д~џџј|lЫ„ўq‡џџљ„U‡yъџџ‚k€њ„ўѕSюџџъR…ЪU€џfh­†ў–Љ€џuA…oџџbeе†ўчX˜Пг?…eцџџ3`dъ‡ўYйЪТŒ5…Wџџ?]bіўЩlж€ў^€џu3„Uџџ?]_і€ўєi4#ўіЏZЄџўBIK$‚bHџ?[^ћ€ўі0ЖIDеІ NKC6†3?XWчўн#,LD;4+€?OUTRЦ‚ўаaE<4,$€l1UQNЁў§76< =6,&€Y*NLkњ€ўТo€ "36-& €?V,MJJЭ€ўe(bЬџЛO' ‚SUECQ„vУ@Rƒ]6E†№џЕ7 ƒ In^[nsX\Q„Й‡џм-… 3i`VNF?b:\\‘у†џU† EVNE=EtdSE6#i…џ“ † &ME<5HhXH:,Ф„џХ † DR;4,=\L>/" „џх † Kф<+$QB4& Я„џј† Eљг,97){…џэ† -иџоB- Ёё…џИ‡…€џЇ7)Еу„џўIˆ iДщџџЛ8/wй‚џ§жk‰,–ўџџKCЇљ€џ–€„„ DњџюАџџівq‚ƒ† Uъ§ў§эПs€‹†€l8mk5€­ОДŽJb€x?:СЁДќџўџўёћџџџџЮ0vЖc–іџџџџџџџџџџџџѓ;v—›бмџџџџџџџџџџџџџџш:­œјЪ№џџџџџџџџџџџџџџџЙYдФLџџџџџџџџџџџџџџџџѓ 5ŒВ‚џџџџџџџџџџџџџџџџџF€RHПџџџџџџџџџџџџџџџџџtЎ3lрџџџџџџџџџџџџџџџџџ€Щ(2ўџџџџџџџџџџџџџџџџџШAНџџџџџџџџџџџџџџџџџџџџиcŽ.џџџџџџџџџџџџџџџџџџџџџџоIJiџџџџџџџџџџџџџџџџџџџџџџџўuГ§џџџџџџџџџџџџџџџџџџџџџџџџT`lлџџџџџџџџџџџџџџџџџџџџџџџџюЂ<Иџџџџџџџџџџџџџџџџџџџџџџџџџ+Јhzџџџџџџџџџџџџџџџџџџџџџџџџџgщм§џџџџџџџџџџџџџџџџџџџџџџџџ\чџќџџџџџџџџџџџџџџџџџџџџџџџџVŒџџџџџџџџџџџџџџџџџџџџџџџџџџ4ђџџџџџџџџџџџџџџџџџџџџџџџџя—џџџџџџџџџџџџџџџџџџџџџџџџ‡aџџџџџџџџџџџџџџџџџџџџџћџО lџџџџџџџџџџџџџџџџџџџџџВ/|џџџџџџџџџџџџџџџџџџџџџИDџџџџџџџџџџџџџџџџџџџџџ|лџџџџџџџџџџџџџџџџџџџїvќџџџџџџџџџџџџџџџџџџ’0 Тџџџџџџџџџџџџџџџџџџџџџўяu Чџџџџџџџџџџџџџџџџџџџўџџџџџ‡pџџџџџџџџџџџџџџџџџћўџџўўџџџћ)$~ЌХжожХЌ”€˜ИРМœt8&\‡ЊШпхєіGich#HРРџџјџџўџџџџџџ€џџџ€џџџР?џџџРџџџрџџџрџџџрџџџџрџџџџ№џџџџ№џџџџјџџџџўџџџџџ€џџџџџрџџџџ№џџџџјџџџџќ?џџџџќџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџќџџџџќџџџџјџџџџ№џџџџРџџџџРџџџџРџџџџ€џџџ€џџџџџџРџџџџ№џџџџјџџџџќџџџџўџџџџўџчјўРРџџјџџўџџџџџџ€џџџ€џџџР?џџџРџџџрџџџрџџџрџџџџрџџџџ№џџџџ№џџџџјџџџџўџџџџџ€џџџџџрџџџџ№џџџџјџџџџќ?џџџџќџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџўџџџџќџџџџќџџџџјџџџџ№џџџџРџџџџРџџџџРџџџџ€џџџ€џџџџџџРџџџџ№џџџџјџџџџќџџџџўџџџџўџчјўih32R‡мбЈˆ†БŸЁ Њл|\: 0MtŒžя|RXˆ-02+1‡нДV3J š џРcsсџПugWdйўеŒ‚џeд_ђџ€Cћ‰ўЩ<йџщŒzpџ€™‹ўQ”‚џE‹мfЛ€џ з‹ўЉSљџ‹ЫHџ&ё‹ўъBjg ЄЫ ‹Ё:€џ‚A§ŒўZŠЩЕЇВ‹y>џџз‚fўi €џэЂ‹j9џџƒm„ўеN,І‚ўq›џp‹o/џџƒkƒў јYе Яўў§ѕbњ€џ7‹)џџƒvƒўх 3“ўТdzw–Уџџф‹Њ8џџƒ}ƒўњ?и|нфsТЉЫХ]ŒS3„O§ƒўъtYФXЖъъЭpшПвЫб;Œp „+ѕ…ўћh™ыъъНƒ€ыЊЩ ‹‰@„р…ўŒыъъфŒХыъ У3Œk"ƒХ„ўщ;ъ зS|XoчŒxTƒm„ў„Ё€ъюgFпlŽkM‚.№‚ўіXъЂu|П>aQЏ‚ў˜ъъо™}БВЎDЧуџџ–VU:Dіў pетХvz‘ŽЉЪхџњ™Ž8O%†ƒƒЦaЙ†tвФРНЬкћ„џњВŽ .TTŸ ЇЁqeVoœџЁ‘  i`(|昹Œџѕ•^Т‹џež-О‰џЗžэˆџы Ÿ‹ˆџ§'ŽV‰џFŒ Ъk‰џaŒљЙ‹ ж‰џqŒљџŸŠ‹ŠџaŒуџџЁ†jў‰џў@ €џЫ-„JааŠџю9њ€џўœ"JЈмя‰џ‘˜‚џўхQ€(~иоˆџфŽ2\НХЦя€џ§66J WЖк…џњаЅE<Š…ж€утНВЛѕџф1b‹ё‚џ ы•‚ЅЯнтткЛƒ/†#ž…уп­Чџl5ПƒџпЂмуусƒуЊ%…ЊˆуФРџмѕ€џэПЎ•тˆу”„|ŠуДЌ№„џњиВн‚усƒупNƒyИж†умУ“IWv“Ёœd@7m‰ЇЫн…уŽ… &/2230)  -D[mu~†’‰‡мбЈˆ†БŸЁЊл|\;" 0MtŒ–я|RXˆ26716ŠоДV4M€“ џРbsсџСzk[hкўеŒ‚џiŒд_ђџGћ‰ўЩ<йџщ Œ|pџœ‹ўQ”‚џHŠмfЛ€џз‹ўЉSљџ‚‹ЫHџ,ѓ‹ўъBjg ЄЫЁŠЁ8€џ€E§ŒўZŠЩЕЇВžŠy>џџз€hўiЁ€џэЅŠj9џџ€p„ўеN,І‚ўq›џrŠo/џџmƒў јYе Яўў§ѕ~_њ€џ:ˆ)џџyƒўх 3“ўТarvŒТџџф€†Њ8џџƒўњ?и{†ЬеsДЅЫХ^„S3‚S§ƒўъtYФWЈййУoзВФРФ8ƒƒp ‚/ѕ…ўћgŽкййИ|€кžЛ„‚‰@‚т…ў‚кййж‹Зкйƒ Е2ƒ‚k" Ц„ўщ8й гPrRgжƒ‚xT€€p„ўƒ•€йхfDвfƒ‚ƒkM€2№‚ўѕS€йvЛ?ƒ†aQ А‚ўВййг‘€$Прџџ— €ˆVU:Gіў pХгРu=,sУфџњœ‚‰;P&‰‚~Ц`Д„tвТМЙЩкћ„џњВ ‹ 2TTŒŸŸЄžpeVoœџЂ‹ j`(|昹Œџѕ‹€€  ^Т‹џgŒ€.О‰џЗ€эˆџы ƒ€€‹ˆџ§)Œƒ€V‰џGŒЪ€k‰џbŒљЛ€€ ж‰џrŒљџŸ€€‹ŠџbŒ фџџЁ €jў‰џўAЁ€џЫ.€JааŠџю<њ€џўœ#€JЈмя‰џ‘Ž™‚џ ўхR(иоˆџфŽ/YЙУХя€џ§66J WЖк…џњаЅD9Š~Э€йиЕ­Йѕџф1b‹ё‚џ ы”žХгиибГ}'†#—…йжІЦџl5Пƒџпžвййзƒй !…ЄˆйМПџмѕ€џэПЎ‘‰й„wŠй­Ќ№„џњиЏг‚йзƒйжJƒtАЬ†йвЛŒHXv“Ёœd@2h‚ Уе…йˆ… %.11/-(  (CXhpz‡‹„‡мбЈˆ†БŸWkoV$˜Њл|\B@DA8/4Mt“ow||{zrlU•я|RXŒ‹–•’РщДV4t}wvtssrna’ џРcsсџлЛВЈЎыў жŒ‚џ RP‹д_ђџ]ki—§‰ўЩ<йџёXK‹zpџbihЧ‹ўQ”‚џ‚GŠмfЛ€џ3efoщ‹ўЉSљџЈC*‰ЫHџScdј‹ў ъBjg ЄЫН?=‰Ё:€џ]da‘ўZŠЩЕЇВЖ93‰ y>џџз[a_Ѕўi €џэЛ4/‰j9џџ€[_\Ј„ўеN,І‚ўq›џ‘/,ˆo/џџ€[]ZІƒў јYе Яўў§ѕ~<љ€џ^+WR* †)џџ€[\XЌƒўх 3“ўУF i Ќџџщ+,VPJC"„Њ8џџ€WZWЏƒўњ?иkr\ТПl6QKF@:4ƒS3VXT‘„ўъtYФG&T 3 DLFA;60+ ‚p VVSvљ…ўћU€t 5FA;61,&!‰@VTR_ы…ў›„€ B<61,'"‚k"€QRPTй„ўш€— € '=72,'" xTNRNLŸ„ўw€bf‚ ;73-(# ‚ kMUNMJqѕ‚ўѕ€C—HA;83-)$ ƒaQOKHOЪ‚ўВ€LŽ€џџДQ.)$ „YU:GJGF~њў jya&Йџ ћАC  †Ипвзўџџџџџџџџџџџџџџџџџџџџџњ+1ђDЛњяйсџџџџџџџџџџџџџџџџџџџџџџџКЦyуёфOћџџџџџџџџџџџџџџџџџџџџџџџ§3Nл(Тгж1mџџџџџџџџџџџџџџџџџџџџџџџџџ‘ЙmtЕТDИџџџџџџџџџџџџџџџџџџџџџџџџџзю•Ѕo рџџџџџџџџџџџџџџџџџџџџџџџџџ§OФ/ˆŒ4§џџџџџџџџџџџџџџџџџџџџџџџџџџ:}‘?xDGџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ Ae ˆџџџџџџџџџџџџџџџџџџџџџџџџџџџ@Б€9@—џџџџџџџџџџџџџџџџџџџџџџџџџџџгxЄ€+ —џџџџџџџџџџџџџџџџџџџџџџџџџџџџџћЊ4|Ž —џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§И:HС —џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ—ш—џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа­g—џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџиAд‘џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸЖx[џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ3"ц27џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›Sп$ыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТcр9ЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлMѓ‡џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщњџє§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџх7§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХЋџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…"№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ-–џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЊџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџив“ЊџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpQџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ% чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕaџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњ4[ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџОUC-ЯўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїЃ 3ьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџч6дџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџу‹џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџ›Сџџџџџџџџџџџџџџџџџџџџџџџџт—oЈпњџџџџџџџџџџш0f‹ЄЕХЮЫОЌœyM+^vŸŸŸ–pO%Af‰ЈМейпђљНit32C…џ™сфуфнмйздбЯЫЩЦТНЖшюэьъЫ—mL6&$0ATn‹ЊИЕАЊт№ёцŸT '067651,)$" !&=_‰€Њн"ЦѕєИR2JXT:! %9aЃ<й їјЁ, 5^mcXŠ $]qf8,S‡2жіјЏ'K}zo€%2:@A@;6-(6Z–нћўџџx *U‚sвџћнD Pއ€џсif`ZUPKFB=A_Ÿољ§џў џИ8 2d‰DЯџќ =”—џЪwqlga[VQLHTПё§џ…ўџИ6Jun ЭџюRЊЃџђЋ}wrmga\WS_Žеєўџˆўџs.kv Ыџм,ЌГƒџ бˆƒ~wsmibF3dЭћўЗ6]z/ЩџЯSЪП„џ№ЖŠ„zm9 MХ§џў7 Wu3ЧџЪ lд…џ о›—‘‹{7=Ећџ‘ўЖ Vr1ХџЭ zр…џ їЫЄ’E,Ÿіџ“ўЖXo)Уќйyь†џчЎЉo€‚ыџ•ўЖ ^j‚5„ŸэЩ†2 Гёюiі†џћоІ6‚ Z瘢 Ж g\ LНјўџћЙAАаћR=ѕ‡џю‚*Ѕљџ˜ўЗnL•љ†џё ЏїŽиыˆџžƒ eм›ў:4j:Иўˆџћ‘­ёк ІпˆџР„3Вћџ›ў:X\жŠџћrЌїCSж‰џ…qъўИ noўŠџєEЋђ­Рˆџ…,Љњџўy =_Б‹џХ ЉЦђ'pПˆџ† bъџŸў@m[јŠџћeЉ№ŸЙ‡џ‡”ј ўЛ4^Ќ‹џЬЈя,mЏ‡џ‡AиџЁўDn[‹џљFЇщДЄ†џˆ hыЂўНDTФ‹џ˜ІыPLЁ†џ‰"ЇљЃўpu‹џе Ѕнр††џˆ4ФЄў‚dDёŠџњ2Ѕф›"†џ‰ [мџЄў;XДŠџў_ЅцRH‡…џŠŽљЅўP ru‹џ‹Ѕтk…џŠŸІў ‰"mCзІ€ot’ОыƒџЅЃкФz…џŠ6И§ЅўУ'[=9fmot{tC#}П€џжЄл’&q…џŠZфЇў+BUy€ot’Оыџю\QрџбЄлj8k„џ‹dєЇў00mEmot{tC#}ПџРiяЯЄиJF„џ‹ fѓџІў’1qgƒџю\QрыазЄж5MƒџŒ~ёЇў•6tL†џРiяџыЄг&QƒџŒ­іЇў˜;y7‡џыаџєЄаR‚џ а§Їў›@~)ŠџНЄЮO‚џ гџ’ўэЪЗНкњŒўžEƒ Šџ‰ЄЪK‚џЫ‘ўіНg C˜р‹ўЁJˆ‰џўTЄЧFџŽЦџўіЄ)€Uоџ‰ўЄO‹§ˆџі(ЄФ%?џŽФўН)Zо­%€^љ‰ўЇTyˆџэЄТ08џŽХ§ŽўэgоџљŠОˆўџЊZ‹*:я‡џ­ЅМ?3€џЫћŽўЪ­љр`e…ў эУЏЖŒ_ˆ9а‚‡џVЅНR-€џ"зћŽўЗ%Š`‚8ƒў р­e =Te~Oы^ў…џх"ЅЖi+'€џ&шћŽўН †GўыЇMEТяŒnmoы‡Д…џŸЅБƒ))€џ*є§ŽўкC†ŽўўљЩj-sйѓэъu‡H—ыФa„џѓ0ІЇ +#€џ+іўњ˜… 2фџё.'™ѓяы€ъzЄ Чыъ)„џІЇ­<&џџ$рўрUƒ џэ}NЩяъы€ъЖ€Ђ€ыFљ›lakoi!ЈЉ\'џџЕћўо^2ўчeq№ыƒъЙˆN€ы =ЂяљііјоoІЅ.џџ €іўџљОe8GŽфџч\\яъыƒъ’ЄB’€ы оэыб™ЏтюэыПЄ™=’eэџ–ўџыa>ръыƒъз—Йк‚ы ъЭрЯZЙъыФЅ^'‘Vм—ўёu7Иэ…ъДЁƒD‡ычAщыvЄ˜†8‘2Х–ўј” GЧю†ъЈТ, ‡ыgыуЅ•R ’$Јћ•ўИ =Ыю†ъЯЏЈ‡ыu€bыы:Ѕ‘z: ‘‰і”ўоHБя‡ъЛЪ>|…ыоL ВУы\ЅqŒU"‘ oѓџ’ўѕ†vё‡ъзТВрƒытm ‚WЭЊы[І‰zEdэџ’ўТ!ны†ъфЬм3~€ыъщ­X ƒахъы9Ї…`-Qм§‘ўэjKѓ‡ъ мз– Ы‘keG„l€ыуЇ}~V(Јё‘ўЖ 'еэ†ъчойŠ ш€ыuЈ|oL gмџўъfsё†ъэъюKŠЛщыыФ Љ\xg=ŽAФџўЛNуы…ъхіѓ‡Š #ЭууыРЋrrb0Ž7ЊўєwНю…ъчј§Ц N&ˆFйууžO­rog*}ъџўЪ 7ё†ъ юікmВВЈ\ƒу Z'Бikk(@ДŽў •я…ъ хърSДВ•­ДІ\€ {нунщџџlАegn-Œ*†љџ‹ўх^6щы„ъмроIВАƒДwРууиу‚џrАaeq9Š\й§џŠўП^№ƒътгижIДДВ БДВДH&Щуувоƒџ§ўkЏZ_tS Š,і‹ўЅžяъымПиФSВ€Б ВБВВДДkuтухЪхˆџlЎZWnp‰RтŠўёr!хы€ъчОИп‡ gБЏЇ­Њ­ЏДЉmbИууХЛј‹џl­ICbƒJ ˆ-Ÿіџˆўв.,є€ъиЄОйJЄsr[NLLN]rsЩууТЈжџl­&Qt9† ^ЬЧЕЌЊЏИЧуўИ TёъвЈІм˜6i}Р†уУ‘žб“џl.Ћ 7V‚;„)V{R6&%+6Ho™МъџЉ –Дœ›ЯИ0 ЛџџъŽz|ma`n‚•‰У§—џАFЊ%7W†’T?Z’ТуѓіэЭЁb,0zЪ›@wŸбІ:*єЈџэEЋ .Kv ‰X1fо€§ћљљіёяє”lLk‘Не‚26UR?гЈџўЉ ­! 2Qy Ў‹oWF;5238BN_tŽ­ЯЦ„@>bwoeqyЉџэ=Џ  #5Ok„œЏПЫбаЪНЈkE&:L^ŽПХЁoчЈџў˜В €*Ps O ">gЄгяиБŒ–Јџўо'ОfњџЩ6VzУшшТg§ЈџљoПЏ№8 !)5@G?RT‚гЇџўИРŠ0_Е§Єџъ3г{эЂџљvд _вўŸџўБ зFфŸџу$иЭžџєSиžџћ„йЙџўБ йLџўнй№џщ-кЂ§œџєVЇ­[џћsЇo­Xџў‚Ї БkЌfџўœЇЩљ#ЋfџўИ ЇкўпЉІџўЭЇ$хўџО ЈžџўйЇ5ё€џЅЈ‚ŸџъЇѕџpІf џэ Ї,ѓџўZЄю џв Ї0яўџјKЂ — џўФ Ї)уў‚џјQЁuЁџўБ ЇЧўƒџ§QŸ}Ђџ§‡ЇЌў„џ§u™.LЃџљ^Їvљ†џД –FЗыуНи–џўˆџх5Љ:ыў†џк<”M“ЗояЭПЁџўРЉЙўˆџЖ’4`‚ЇЭяоЇѓ џљsЉeі‰џј€  2Rs“МуэЩЯ џк)ЋЩўŠџяr  &Dd‡­вёйИŸџћ‰Ћ^ѓŒџѕŽU3Š 6VwœТшшПъџўе'­Ј§џюhˆ )Hi‹БзягФџєhЎ/жўџp† :Z| ЦъфЛœџћЄЏVъ‘џ™„ ,Lm‘ЖмюЯйšџўЩ$Ў'?‘ЖзѓŽџяs s >^€ЅЫэпЩ™џўи;Ќ3ЂрогФЏ–w\pt‚йўˆџўџўТnmЬџџt1Pq–ЛтэУњ’џњхЎF%!)148;92 Ё2•с€ут„уТ„WjЄљŽџ и %Cb†ЊбЈQБ§Žџўч—G,O{ЁНЪвйооррмзЭТЈr9ž Žут Tgеџ 06TmN0ŽѕŽџтu,?Нируб‘8›С’увkVЭ‹џŽ$_Хџ§Ѕ@dЗн’утЫx( ˜з•узd]№‰џ№  *шџљ‘VЛ—ут™'—0з˜уПAЛ‰џŠiА ›џўŸ~з…утрутЂ"•2рšуоR˜ˆџўџё>ЩŽџф_й…у€рут›“су^™—џ њ§љтЙ9.rПуоz‘ШŸуKЫ‘џў§€џ ф wp‰МюёроžудD‘kсŸужщџў‡џњщттрŸуЊсЁуВ,zЯјћ”џћтНжŽу€сŽупUŽiЃупЈrЊњŽџ ў§іхТ‹N 8†НкрŠу„р‚ус…уЌ ЩЄу oo˜Йеф№ѕљћ§ ћјєюоЭЎ‹b;€ +YŒИжотуср…уж6Ž7mІжуО‹L  $4Nenqpm^E, Š =dЗвйр–уe’(AXo‚•ЅВПЩвйорутпмжЭФЙЌŒydL5Љ -Da€žЕТайтŽуГх(4H]p„• ЊАЗСЪЯгзнобyђ !(€џ™сфуфрмйздбЯЫЩЩТНЖшюэьъЫ–mL6&$0ATn‹ЊИЕАЊˆ€Э№ёцžT'057651,(%! "&=_‰€Њƒ‹Ч$ЦѕєИR2JXU=%"%9aЃKФїјЁ, 5^meX„ *asf8,T‚ˆ7Š„РіјЏ'K}yo€+7@FFEA;2.;_˜нћўџџx *U‚u„€€МџћнD P‡€џс’lje_ZTPKFBFdЁољ§џў џИ9 2d‰G‚€€Кџќ =”™џЭzupkf`[VPMYƒТѓћџ…ў џИ6Juo€ŒИџюRЊŸџђЎ€|vqkfa\We’жєўџˆўџs.kv&’Жџм,ЌЕƒџ ⋇|uqmgJ8iЯћўЗ6]z4‘ДџЯSЪП„џђЙ“ˆ‚}p=RЦ§џў6 Wu7‘ВџЫ lд…џ о™”Ž~=  BЖћџ‘ўЖ Vr6‘АњЭ zн…џ їЮІŸ•I 1Ёіџ“ўЖXn-‘Ўќкyь†џчАЌr ‡эџ•ўЖ ]j‚:ˆЁэЫ‰7ƒ­ёюiі†џћсЉ=^蘢 З g] QПјўџћЛFЋаћR=ѕ‡џё“/Јљџ˜ўЗmM—љ†џѓ‚ЋїŽиыˆџŸ‚hм›ў:4j=Йўˆџћ” €Љёк ІпˆџТ‚9Ећџ›ў:Y\жŠџћuЉїCRж‰џ‚uыўИ ooўŠџєHЇѕ­Рˆџ‚2­њџўy =_Б‹џЦ€ІЦѓ&pПˆџ‚fъџŸў@m[јŠџћg€ЅюžК‡џ€"–ј ўЛ4^Ќ‹џЭ€Ѕя,mЏ‡џ‚FйџЁўDn\‹џљJ€ЄщЕЄ†џ‚‚kыЂўНDTФ‹џ›ЃыPKŸ†џ‚ƒ'ЉљЃўpu‹џжЂнр††џ‚9ХЄў‚bDёŠџњ6Ђф›"†џƒ‚`нџЄў:XДŠџўb€ЂцRH‡…џ„‚’љЅўP ru‹џЂт k…џƒ€ЁІў ‰"mBзІ€ot’ОыƒџІЁкФz…џ„:Й§ЅўУ'[=9fmot{tC#}П€џз€Ёл’'q…џ„‚ ^фЇў,BVy€ot’Оыџю\Qрџб€Ёлi8k„џ… gєЇў00mEmot{tC#}ПџРiяа иJE„џ…iѓџІў’1qgƒџю\Qрыаз ж5Mƒџ…ёЇў•6tL†џРiяџы г&Qƒџ… ЏіЇў˜;y8‡џыаџє аQ‚џ†%б§Їў›@~*ŠџО ЭP‚џ† &еџ’ўэЪЗНкњŒўžE‚ ŠџŠ ЪK‚џ… $Ь‘ўіНg C˜р‹ў Jˆ‰џўV ЧFџ‡€"ЦџўіЄ)€Uоџ‰ўЄN‹§ˆџі+žФ$?џ‡!ЦўН)Zо­%€^љ‰ўЇTyˆџэ›С08џ‡€"Ц§ŽўэgоџљŠОˆўџЊZ‹(6я‡џЎ‚€€™Н?3€џˆ$ЫћŽўЪ­љр`e…ў эУАЖŒ_‡7Т‡џX‚€€€—НR.€џˆ &зћŽўЗ%Š`‚8ƒў р­e8Re~KкYў…џх$‚‚•Жi++€џˆ€+шћŽўН †GўыЇM@Во‰nmhк|Д…џ †“Б„*)€џˆ .є§ŽўкC†ŽўўљЩi*lЫрмйu‡HŒкЖa„џѓ2€…‘ЇЁ+#€џˆ/іўњ˜… 2фџё.$Žрок€й{Є Йкй(„џІ€ƒˆ­<&џџˆ€(рўрUƒ џэ}HЛойк€йЎ€Ђ€кBљ›j_ioh"‚ŒŽЉ\'џџˆ€Зћўо^2ўчehокƒйБˆI€к v<˜рєё№ёвg‚Ђ.џџˆ€ƒіўџљОe8GŽфџч\Uойкƒй‘ЄBˆ€к ЯнкТЁвпнкБ€Œ™=‹ hэџ–ўџыb:айкƒйЪ—ЙЫ‚к йПаП„TЌйкЖ’Œ^'Š  Zм—ў№u3Њм…йА ƒ>‡кж<икn‘€‹˜†9Š€6Ц–ўј”CИн…йкЈТ,”‡к^„кв“‹•R!Ё)Љћ•ўИ 9Нн†йЦЏЈ‡кm€[кк7…Š‘z; ‰€‹і”ўоGЅо‡йЙЪ?s…кЯG ІЕкU…ŠqŒU"‰ rѓџ’ўѕ†nп‡йаТВбƒквg ‚QОžкTބЉzE ˆ gэџ’ўТЬк†йиЬм2u€кйи Q ƒТейк6ˆŠ…`-ˆ€ Tм§‘ўэjFр‡й из•Н‡d]B„d€кв ‹‰Š}~Vˆ,Њё‘ўЖ %Цк†йоойŠз€кmŠ‹|nL ‡…iнџўъfkр†йпъяK‹БйккЖ ŠŒ\xg=†„EФџўЙIгк…йеіѓ‡Š "ФййкВŒˆkrd0†„;Ќ§ŽўєwЏм…йжѓ§Ц‹Dбйй˜JŒ‡‘rog*†‚ ъџўЪ 3п…йзъѕй‰‡й™V&‹’ikj(……CЖŽў  Šо„йзрър‰ uгйзщџџo ˆ“eho-„‚-‰љџ‹ўх^2икƒйеиро‰Иййву‚џtŠŠ”adr9‚„^й§џŠўПXпƒйеЯзж‰%ПййЬоƒџ§ўm†‡šZ_tR …1і‹ўЅ ’нйкаРиФˆ^ийнЧхˆџn…†™ZWmq…UтŠўёrек€йзЙИ9АййНЙј‹џn‚Š›IDbƒJ †1Ёјџˆўв/)т€йЬЄОйJgI FkРййЙЅжџn‹(Qt9„ "_ЪЦЕЌЊЏИЧуўЙ NрйЧЅІм˜5fyИ†йЛŒб“џn0‡ 8Wƒ;„)RsM2$#(2Fn›МъџЉ ‹­˜™ЯИ0 ЛџџъŽyzh]\j~•‰У§—џБG‚€ž(8W†’T ;WŽНкы№тТ•\).zЪ›?yŸвІ:*єЈџэF€Ђ€$0KvЁˆX1bк§§ћјѕѕ№хпхiLkНеƒ26UR?гЈџўЊ Ѓ#"1Qy Ў‹oWF;5238AN_t­ЯЦ„?>bwoeqyЉџэ?Ђ $5Ok„œАПЫбаЪНЈlE&:L^ПФЁoчЈџў™€Ђ… +Ps O ">gЄгяиБŒ–Јџўо)€Ђ‹ƒhњџЩ6VzУшшТg§Јџљq€Ђ‡‚„Б№8 !)5AG?RT‚гЇџўИ€Ѓˆ‚‡0_Е§Єџъ5€Ѓ‡†…{эЂџљwЃ†‚……€ƒ _вўŸџўБЄƒ…„€‡FфŸџу%Ѕƒ†„€ˆЭžџєUЅƒ†ƒ€‰€žџћ„Ѕƒˆ€„€ˆ‚ЙџўВІ‰…ˆƒLџўнЇŠ…ˆ…№џщ.І‹„€ˆ†Ђ§œџєXІŠ…‰…[џћuІp‹„Š„€XџўƒІВkŠ‚‰„€fџўІЪљ#Š€ˆ…fџўИ І#мўп‰€ˆƒ‚ІџўЭІ'хўџО ˆ‰…žџўйІ7ё€џЅ†€‡…ƒ‚ŸџъЅ"ѕџp…ˆ„ƒf џэ Є.ѓџўZ‚ƒ‡…‚ю џв Є4яўџјK„ˆ… — џўФ Є,уў‚џјQ†‡„uЁџўБ ЅЩўƒџ§Q…‡„ƒ}Ђџ§‡І ­ў„џ§u……„€.LЃџљ^Їwљ†џД „…ƒFЗыуНи–џўˆџх6Ї=ыў†џк<€‚„ M“ЗояЭПЁџўРЉЛўˆџЖ„ƒƒ 4`‚ЇЭяоЇѓ џљsЉgі‰џј€ ‚ƒ 2Rs”НуэЩЯ џк)ЋЪўŠџяr €„ &Db‡­вёйИŸџћ‰Ћ_ѓŒџѕŽU3… 6UwœТшшПъџўе'­Љ§џюh… )Hi‹БзяеФџєh­1жўџpƒ ;Z|ЁЦъуЛœџћЄЏWъ‘џ™€€ ,Lm‘ЖмюЯйšџўЩ$Ў'?ЖжѓŽџяs s ?^ІЫэпЪ™џўи;Ќ3œжеЫМЈrYns‚йўˆџўџўТnmЬџџt1Pr–ЛрэУњ’џњхЎF%!&.2577/ Ё/з€йи„йЛTiЂљŽџ и %Cb†ЊбЈQБ§Žџўч—G+Lu›ЕТЩаеежждЮФКЂm5ž ˆŽйи™Pfеџ 06TmN0ŽѕŽџтu,=|ЕазйШŠ4›Й’йЩgTЬ‹џŽ%_Хџ§Ѕ@_Џг“йТr$™Ю•йЭ^]№‰џ№  *шџљ‘TД—йи’&—-ޘйЗ?Л‰џŠiА ›џўž{а…йижйиš!•/жšйеN˜ˆџўџё>ЩŽџф_в…йзжжйи”“зйZ™—џ њ§љтЙ9.nЖйеu‘ОŸйGЪ‘џў§€џ ф wp‰МюэиеžйЫ@‘iзŸйЭшџў‡џљтйизŸйЃзЁйЌ+zЯјћ”џћтЛЭŽй€зŽйжQŽdЃйзЈrЊњŽџ ў§іхТ‹N 6ЕбзŠй„ж‚йз…йЄ СЄй mo˜Йеф№ѕљћ§ ћјєюоЭЎ‹b; €  (U‡ЏЬеийзж…йЭ4Ž4hžЭйЖ„I  $4Nenqpm^E, Š ;^‰ЏЩаз–й_’&?Tj}ŽžЌЗТЩаезйижвЬХНБЅ–†s_I3Љ +A]{—ЎКЦаиŽйЋх&2DYl~šЁЈЏЙРЦЪЯгеЩsђ '€џ™сфуфнмйзебЯЫЩЩТНЖшюъьъЫ—mL6&$0@Tn‹ЊИДАЊ† =Wnglv||vlgmW=Ы№ёцžT'067651,)$! !&=`‰€Њ‚\jz‚~}|{{vgXЦ$ЦѕєИR2JXUV\ZXXVSPMIEA%9bŽЃifq~}||{‚zyy€wk^ТїїЁ, 5^mc^\hvuttsrrq€pu‰Њ–p:,S‚–‰~~}||{€z€w€vƒuiSП3іћЏ'K}zoSf†–›žžœ™–•ЉЩэ§ўџџx *Uƒ€{zzywwvuutt‚s€rsr^9ЛџћнD Pއ€џщРБДА­ЉІЂŸœ˜›ЊЭэћўџў џИ9 2d‰ƒwvuut€srr€q‚popofJЙџќ =”—џрДЙЖБЏЌЉІЁŸІНој§џ…ўџИ6Jv„wsrrqqpp€o€n„mfUЗџюSЊЃџѕбОМИЖВЏЌЈІЌХщљўџˆў џt-kuqpono€m€l†kgSЕџм,ЌГƒџфНУПЛИЕБЎ’­х§ўџ‹ў З6]zsmmll€kj‰icNГџЯSЪП„џіжЧХТОМД–zwЁрўџў 7 Wupkjii€h‚gffgff€g`PБџЫ lд…џ ыШЫЧФЛ–smr—и§џ‘ў Ж Vqlhggff€eˆdeZАњЭ zн…џ јтбЭЩžtnloŒЭљџ“ўЖWnhedd€baa€`a`‚abbTЎќйyь†џёгеЖ|n€m€Оєџ•ўЖ ^jd‚` i‰ЙЩєрЙ‡k^^€_^LЌёюiі†џ ћьб–oommkuЈъ˜ўЗ gd€^b–йњўџ§зŽ_\]]^WЋаљR=ѕ‡џ ѕС}onmmkmŠаћџ˜ўЗn]\lТћ†џјДeZZ[\OЊїŽиыˆџ ШionmlkiuЌы›ў:5jdжўˆџ§Н_XYYU*Јёк Іпˆџ з^onmmkimŽж§џ›ў:Y\жŠџ§ЉY€WNЈіCRи‰џ V_nmlkkiuВєўИ noўŠџј‹TUUQЇђ­Пˆџ [hllkjikŠбћџўy =_Б‹џм_RSSJЅЦђ'pПˆџ H\mlkjihqЈѓџŸў?m[јŠџ§PPQNЅ№ŸЙ‡џ U_mkjiih~Фњ ўЛ4^Ќ‹џо\NON5Єя,mЏ‡џ€ [fkkiigj”ъџЁўDn\‹џћ‡LMNIЃщЕЄ†џ€ ']kjihhgqЌєЂўНDTФ‹џНMKKIЃыPLЁ†џ U\kihhgf€ЯћЃўpu‹џуVHIGЂнр††џ V^iihgfh‹оЄў‚dDёŠџћrFFHCЁф›"†џ‚ ]eihgfdmЄыџЄў;XДŠџў’EEFDЁцRH‡…џ‚ *]ihgeeasРћЅўP ru‹џЏCCD@Ёт k…џ‚ MZhgffdbzЪІў ‰"mCзІ€ot’ОыƒџТBABC кФz…џƒ U\gfedaf‹з§ЅўУ'[=9fmot{tC#}П€џу>?@C л’&q…џƒ Y`gfdb`iЁяЇў,BVy€ot’Оыџю\Qрџо<==? лi8m„џ„ [bfeba_iІљЇў00mEmot{tC#}ПџРiям9:;= иJF„џ„ ]fedba_kІјџІў’2qgƒџ ю\Qрыат789: ж5Mƒџ„ HZebba`^oЕіЇў•6tL†џРiяџ№6678 г&Qƒџ„ SZdaa``\sањЇў˜;y8‡џыаџі4566 аR‚џU‚ UZba`__ZzфЈў›@~*ŠџЭ2346 ЭP‚џ… V[ba`^^Xyхџ’ўэЪЗНкњŒўžE‚ ŠџЅ0026 ЪK‚џ… Z[a__^]Xuр‘ўіНg C˜р‹ўЁJˆ‰џўz-/06 ŸЧFџ† U^`^^]\XtоџўіЄ)€Uоџ‰ўЄO‹§ˆџ љS,,-9_T#œФ$?џ† W]_^]\[WsмўН)Zо­%€^љ‰ўЇTyˆџ ё<*+,>][YS6šС09џ† W]^]\\ZVsнўэgоџљŠОˆўџЊZ‹ю‡џ О'()+E[YWURP6 ˜Н?3€џ‡ W^^\[[ZUsр§ŽўЪ­љр`e…ў ыТБВ‰_‡n‡џu&&')LYWUSQNLJ2 –НR-€џ‡ W]\\[ZYTuч§ŽўЗ%Š`‚8ƒў рЎk,e~ ў…џъF$%&'TWUSQNLJHFD- ”Иi+'€џ‡ W\]\ZYXTw№§ŽўН †GўэЌOOnmБ…џА$"#$,XVSQOMKHFEBA?/ ’Бƒ))€џ‡ W\[[ZYXRzљ§ŽўкC† ŽўўљЫi€t‡H`„џєO !"8UTROMKHFECA?<;8%Ї +#€џ‡ W[[ZYXWRzњ§Žўњ˜… 2фџёŸ){Є „џД$ !FTROMKHFECA><:9652­<&џџ‡ S[ZYXWVQtэўрUƒџэ}ƒ:€Ђ €"љ˜NB]hR'"RROMKIGFCA?=:86531.)ŽЉ\'џџ‡ SZYXWVUQlв§ўо^2ўчf„=ˆ#."Ј›–ž' 1RPNKIGECA?=:97631.,+)ŒЅ.џџ‡ SXYXWVTRaБњў џљОe8GŽфџч^…’ЄB€%FPNLJHFDA?=;96631/-,*'&‹™=Š SXXWVUTR\Ÿѓџ–ўџъe…#–Й ‚PNLJGFDB@=;97541/-,)'&$"‹Ÿ^'‰ UXXVUTSQY”ш—ў№u…uЁƒˆ >LJHFDB@>;976410-,*'&$" Š˜†8‰ UUVVUTSRRzк–ўі“†ЈТ,‡€€JHFDB@=;976420-,*(&$" Š•S ‰ UVVUTSRRQqЧћ•ўЗ‡NЏЈ‡HFEC@><976420.,*(&%" ‰‘z: ˆ UVVTSRQQOdДњ”ўнFˆЙЪ>†‚FECA><:76420.,*)&%#  ‰qŒU"ˆ QVUTSRQPMZЂіџ’ўѕ‰ˆUРВ…ƒ!ECA><:86420.,+(&%#!‰‰zE ‡ PUTSRQPOLV›ѓ“ўТ‡)Ьн3ƒ…CA?=:86521.,+)'%#!  Š…`-† URSSRPPOLSш’ўыiˆ˜з–€ˆA?=;97521.,+)'%#!  ‰}~V‡ NSRQPONLMoЧі‘ўБˆbойŒ5?=;87531.-+)'&#!  Š|oL † OTRPONMLKZ›шџўч^‡.ъяK‹ ?=;97631/-,)'&$"  ‰\xg=… RSQPONMLJP€иџўЕˆіѓ‡‹€#>=;97531/,,)'&$"  Šrrd0… STPPNMLKIOwЦў№u†БћЦˆ€$ ?>;97642/-+)'&$"  ‹rog*„ JROONMLKJJbЈ№џўФ‡Љѕй…) 9@>;:86410.,*'&$"  Œikj)„ NONMLKJIGN~ЭŽўЄ† ър€…,Lтџџ›I><:76420.,*(&%"  ehn-ƒ LRMLLJIIFLl­ћŒўх]…˜р9т‚џ"›:86420.,+(&%"  Žadr9RRNLKJIHFHXхўџŠўТ„&‘ижˆ>кƒџ"§ў’420.,+(&%"! Z_sS € PRMLJIHHFFJmБј‹ўЊƒ%РиФ‰“хˆџ‘.,+)&%"! ‘WWmq€ JMKJHHGFEGZ‰ъŠўёz‚|И„”ј‹џŒ)'&#!  “IDbƒJ OQKJHGFFEDGmТ§џˆўг4*ЄОкJƒ€ Nгџ‰$!  –]Qt€9PHIHGFFECHXp­БЏЎ­ЏЖЧхўЛ&iІм—56† lЫ“џ†M — npPW‚;)4GF*D6"  `ŸПыџЎ7]›ЯИ/ Лџџъˆ`< "wР§—џМd) ˜(m}}dFX†’T/*HF7(0V|}t{YuЪž0wŸбІ:*єЈџ ёo/.&%€›(g}|zt\ALvЁˆX1 6ЅюіэеОЛC *6Fk‘Не‚26UR?гЈџўН;-€,Ђ(7}zwusq]D6QzŸ­‹oWF;5248BN_tŽ­ЯЦ„@=bwoeqyЉџ№g,€+Ђ))}ytsqnljdP=-5Ok„œАПЫббЪНЈkE&:L^ŽПХЁoчЈџўЏ2*))Ё) utrpmkjgeb`^SF:/' /Ps O ">gЄгяиБŒ–ЈџўхQ)((Ђ)emonkigeb`^[YWUSPOMJHFEC6ћџЩ6VzУшшТg§ЈџњŒ*'&&Ђ*(mmkigeb_^[YWUSPNLJHFEB@?=Kг№8 !)5AG?QS‚гЇџўЦ7&&%Ђ.bligda_][YVUSPNLJHFDB@><7#42995.20,!0_Е§ЄџюW%$$Ђ/2mhdb_]ZYVTRPNLJGFDB@>;-!Akzuqmie`\XTQMIF@){эЂџњ&#"Ђ2_[__][XVTRPNLIGFDA@>;6w~zvrnjfb]ZVRNJFD?;73  _вўŸџўП1! Ѓ2&\Z\ZXVTRPMKIGFCA?=;9 ?~|wsokgd^[WSOLHEA=962.+$FфŸџшF Є2-ZZXVTQPMKIGFDA?=;96}|ytplie`\XTPLHEA=:63/,(&"Эžџѕo Є2WYVSROMJIFECA?<;870 ~zuqmjea]YUQMJFC?;740,)&#  žџћ˜!Ѕ2$ZVQOMJHFECA?<;965*|vsnkgb^ZVRNKGD?<852-+'$ ЙџўО+Ѕ2CZQLJHFECA?<:8653$wsolhd_[WSPLHEA=962/,(%!Pџўт7Є3#XVJHFECA><9864202tqmie`\XTPMIEB>:640,)&" №џэI Є4A(ZNFEB@><:76420.6rmjfa]ZURNJFC?;740-*&$  Ђ§œџѕm Є3?> ARDB@>;976420-,1okgb^ZVSNKGDA=862.+'$  [џћ‡ Є3=F†+B?>;97642/-,*#lhd`[XTPLHEA=963.,)&" Yџў“ Є3=NЩk:=;97641/-,*(% gea\YUQMIFC>;740,)&" fџўЈ Є3;Uйљ#;97641/-+)'&$ Jb^ZVRNJFC@<751-+'$  fџўР#Є39[хўп&6531/-,*'&$"&_[WTOKGEA=962.+'%! Іџўв& Є27]эўџО ,21.,+)'&#" RXTPLHEB>:630,)&" žџўн' Є8kѕ€џ,Ѕ,.,+)'&$!  (URNJFC?;740,*&#  ‚Ÿџэ1 Є8Vјџ*p(+)'%$! ROKFD@<962-+'$  f џяЄ7aіџ*ўZ%&%# 1LHEA=962.+(%" ю џжЄ6eѓўџ(јK"!HFB?;740,)&"  — џўЩ Є6\ъў‚џ&јQFC?;851-*'#  uЁџўИ Є1Kжўƒџ §Q>A<962.+'$! €}Ђџ§ Є/<Рў„џ"§u >:63/,(&" .LЃџљi Є+5–њ†џ!Д  9740,)&" FЗыуНи–џўˆџчA І.fяў†џ к<   51-+'$  M“ЗояЭПЁџўФІ)?ЪўˆџЖ$ 2.+'%!4`‚ЇЭяоЇѓ џљ{ І'.†љ‰џј‚  ,)&" 3Qs•МуэЩЯ џм2Ј)FеўŠџяs(&# &De‡­вёйИŸџћ Ј#+~ѕŒџѕŽW5$  6UwœТшшПъџўж0Њ%8Л§џюh )HiŒБзягФџєmЋ&Tоўџp  ;Z}ЁЦъфЛœџћЇЌ'tю‘џ™  -Lm‘ЖмяЯйšџўЪ)Ў >}ЁЫёŽџяs s!?^€ІЫэпЩ™џўй?Џ€&[}жўˆџўџўТnmЬџџt1Pq–ЛрэУњ’џ њхЎF ­‰ SžљŽџ и %Cd†ЊбЈQБ§Žџ ўч—F„ЄYвџ 06TmN0ŽѕŽџтu Ÿ“=Ъ‹џŽ$_Хџ§Ѕ/ ”œ–P№‰џ№  *шџљ% ˜š™З‰џŠiА ›џћ“0†˜›—ˆџўџё>ЩŽџфX…‘––—џњ§љтЙ9,&Ÿ”ŸО‘џў§€џф wp‰Мм}Ÿ“  чџў‡џв:Ё’ЁzЯјћ”џћтv Ž€‘ЃЈrЊњŽџ ў§іхТ‹N‹„‚…Є 7wНжхёѕљћ§ ћјєюпЭЏd= †“…Ÿ +:TjrtsoaH/# ™”‹‚€€ƒ€•€‘КƒЇƒџt8mk@#VƒЊШрёћўћёрШЊƒV#XЄхџџџџџџџџџџџџџџџџџхЄX!{šяўџџџџўяš{!H­іџџџџџџџџџџџџџџџџџџџџџџџі­Hyсџџџџџџџџџџџџџџсy kкџџџџџџџџёъєќџџџџџўј№џџџџџџџџџкkŒќџџџџџџџџџџџџџџџџџџќŒhфџџџџџџ€‡aўџџџџџџџџџџџџџџџќјџџџџџџўџџџџџџџџџџџџџџџџџџџџџџјb9аџџџџџП@.мџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџМ џџџџџ€Fžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџю:&зџџџџ€4r”Љќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџў?U№џџџП@@’ЄŸ Ъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@vџџџџ€.˜ДЏЊЅЙўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџў>ƒџџџџ@ tХПКЕАБзџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћ3ƒџџџП#ИаЪЦРЛЖФўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџоvџџџПNдлжбЬЦСРйџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏUџџџПkьцсмжвЬЧаўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџI&№џџПvіёьчтмзвЯнџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџы зџџПkќќјђэштнимљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџ@H№іќќјѓюшуоЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќ 9џџџ@зь№іћўљєютn”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚аџџПДрцъ№єњўњх;;јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљhџџџlекпфъяєљщ,Nџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџn фџџ@"ЧЯдйпфщют+ІџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪkџџПФЩЮдйотп6<љџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкџџ@3ИОФШЮгинQCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџzHџџПˆГИНТЧЭвl {џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЙ­џџ€(Ј­ВЗМСЧ“3фџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўіџџhЂІЌВЖМЎ>ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ5Xџџ€ ‘œ ІЋАЕ9Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{Єџџ@4‘–› ЅЊr xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚хџџ\А•šŸš.еџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШ#џџПx…Š”™K<њџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџіVџџ€y~„‰Ž„?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўƒџџ€-sy~ƒˆ<@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЊџџ=nrx}vZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџHhlrw>ЃџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрџџNaglo .зџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёџџP[`fK9єџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ+ћџџNV[`">ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ23ўџџJPUVAўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓь”(6ћџџDJO<?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџмx 3ёџџB @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЛ5Шџџ(8:@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвUЊџџ2)@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџз[ƒџџ@,@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџеXVџџ€ &@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЦ,#џџ€ @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјyхџџ@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШ*Єџџ @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџюGXџџ€@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјLіџП@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќr­џџ@?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ\Hџџ€?ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџє,кџџ?ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвkџџ€<љџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™ фџџ5щџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ5hџџП&РџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПаџџ@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?9џџџDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџП@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўE зџџv>ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџe&№џџ@7юџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџxUџџџ@ЋџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄvџџџ@Tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№ƒџџџ@?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєƒџџџ€;јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§vџџџР#ЗџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџU№џџџ@Rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&&јџџџП@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ5зџџџџџœЫќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHјџџџџџџџ№ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџtџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠФўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџo†џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџG5џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$ыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡ ьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџR^џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇ9јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVŠџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџф нџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџк€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџН€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§f€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЛЊэыЄu €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџП€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџП@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ jсџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ЃьѓјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћєщмбФZ3 ‚ъћўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўяПZ"ЮіџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўїЙELціџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџў№’NјјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќД DојџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџќЙ8ЦѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћќџџџџџџџџџџџџџџџџџџџџўЖДчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћ‘šвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџў№L;Л§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќЦЃєџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўџџџџџџџџџџџџџџџџџџњh"хџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўў§ўўўўџџџџџўџџџџџџџџќЩ{ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнисѕ§џџџџџџџџџџџџџџџџџџџџџџџўўџџџџџџџџўъN8ЬџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџП€=~Бцѓ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкD—щџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщ—Ђ€ПџџџџџџџџџџџџџџџџџџџџџџџП€@.b‚ЕзфїџџџўўџџџџџџџџџџџџџџџџџџџџсЁQƒ™П№џџџџџџџџџџџџџџџџџџџџ№П™ƒQ€€€€џџџџџџџџџџП€€€@ @VtЅРЫнѓќћ§ўўўњєющњџџџџџџўпL0CTdqz~~zqdTC0 .8DXqЂЂЃЅЊУгнфщђьЏGdebugger-master/build/package-darwin/Info.plist0000644000175000017500000000171613560352104021417 0ustar shevekshevek NSRequiresAquaSystemAppearance NSHighResolutionCapable CFBundleExecutable openmsx-debugger CFBundleGetInfoHTML openMSX Debugger %VERSION% CFBundleIconFile %ICON% CFBundleIdentifier org.openmsx.openmsx-debugger CFBundleName openMSX Debugger CFBundlePackageType APPL CFBundleShortVersionString %VERSION% CFBundleSignature oMXD CFBundleVersion %VERSION% NSPrefPaneIconFile %ICON% NSPrefPaneIconLabel openMSX Debugger debugger-master/build/main.mk0000644000175000017500000003016513560352104016047 0ustar shevekshevek# openMSX Build System # ==================== # # This is the home made build system for openMSX, adapted for the openMSX # debugger. # # Used a lot of ideas from Peter Miller's excellent paper # "Recursive Make Considered Harmful". # http://www.tip.net.au/~millerp/rmch/recu-make-cons-harm.html # # TODO: Rename OPENMSX_SUBSET to SUBSET? # Python Interpreter # ================== # We need Python from the 2.x series, version 2.5 or higher. # Usually this executable is available as just "python", but on some systems # you might have to be more specific, for example "python2" or "python2.6". # Or if the Python interpreter is not in the search path, you can specify its # full path. PYTHON?=python # Logical Targets # =============== # Logical targets which require dependency files. #DEPEND_TARGETS:=all app default install run bindist DEPEND_TARGETS:=all app default # Logical targets which do not require dependency files. #NODEPEND_TARGETS:=clean config probe dist NODEPEND_TARGETS:=clean dist # Mark all logical targets as such. .PHONY: $(DEPEND_TARGETS) $(NODEPEND_TARGETS) # Default target; make sure this is always the first target in this Makefile. MAKECMDGOALS?=default default: all # Base Directories # ================ # All created files will be inside this directory. BUILD_BASE:=derived # All global Makefiles are inside this directory. MAKE_PATH:=build # Platforms # ========= ifeq ($(origin OPENMSX_TARGET_OS),environment) # Do not perform autodetection if platform was specified by the user. else # OPENMSX_TARGET_OS not from environment DETECTSYS_PATH:=$(BUILD_BASE)/detectsys DETECTSYS_MAKE:=$(DETECTSYS_PATH)/detectsys.mk DETECTSYS_SCRIPT:=$(MAKE_PATH)/detectsys.py -include $(DETECTSYS_MAKE) $(DETECTSYS_MAKE): $(DETECTSYS_SCRIPT) @echo "Autodetecting native system:" @mkdir -p $(@D) @$(PYTHON) $< > $@ endif # OPENMSX_TARGET_OS PLATFORM:= ifneq ($(origin OPENMSX_TARGET_OS),undefined) PLATFORM:=$(OPENMSX_TARGET_OS) endif # Ignore rest of Makefile if autodetection was not performed yet. # Note that the include above will force a reload of the Makefile. ifneq ($(PLATFORM),) # Load OS specific settings. #$(call DEFCHECK,OPENMSX_TARGET_OS) #include $(MAKE_PATH)/platform-$(OPENMSX_TARGET_OS).mk # Check that all expected variables were defined by OS specific Makefile: # - executable file name extension #$(call DEFCHECK,EXEEXT) # - platform supports symlinks? #$(call BOOLCHECK,USE_SYMLINK) # Paths # ===== #BUILD_PATH:=$(BUILD_BASE)/$(PLATFORM)-$(OPENMSX_FLAVOUR) BUILD_PATH:=$(BUILD_BASE) GEN_SRC_PATH:=$(BUILD_PATH)/src SOURCES_PATH:=src RESOURCES_PATH:=resources ifeq ($(OPENMSX_TARGET_OS),darwin) # Note: Make cannot deal with spaces inside paths: it will even see BINARY_FULL # as two files instead of one. Therefore, we use an underscore during # development and we'll have to rename the app folder for the release # versions. APP_SUPPORT_PATH:=build/package-darwin APP_PATH:=$(BUILD_PATH)/openMSX_Debugger.app APP_PLIST:=$(APP_PATH)/Contents/Info.plist APP_ICON:=$(APP_PATH)/Contents/Resources/debugger-logo.icns APP_RESOURCES:=$(APP_ICON) BINARY_PATH:=$(APP_PATH)/Contents/MacOS PKGINFO_FULL:=$(APP_PATH)/Contents/PkgInfo else BINARY_PATH:=$(BUILD_PATH)/bin endif #BINARY_FILE:=openmsx-debugger$(EXEEXT) BINARY_FILE:=openmsx-debugger BINARY_FULL:=$(BINARY_PATH)/$(BINARY_FILE) VERSION_SCRIPT:=build/version2code.py VERSION_HEADER:=$(BUILD_PATH)/config/Version.ii GENERATED_HEADERS:=$(VERSION_HEADER) # Filesets # ======== # If there will be more resource files, introduce a new category in node.mk. RESOURCES_FULL:=$(RESOURCES_PATH)/resources.qrc # Force evaluation upon assignment. SOURCES_FULL:= HEADERS_FULL:= MOC_HDR_FULL:= UI_FULL:= # Include root node. CURDIR:= include node.mk # Remove "./" in front of file names. # It can cause trouble because Make removes it automatically in rules. SOURCES_FULL:=$(SOURCES_FULL:./%=%) HEADERS_FULL:=$(HEADERS_FULL:./%=%) MOC_HDR_FULL:=$(MOC_HDR_FULL:./%=%) UI_FULL:=$(UI_FULL:./%=%) # Apply subset to sources list. SOURCES_FULL:=$(filter $(SOURCES_PATH)/$(OPENMSX_SUBSET)%,$(SOURCES_FULL)) ifeq ($(SOURCES_FULL),) $(error Sources list empty $(if \ $(OPENMSX_SUBSET),after applying subset "$(OPENMSX_SUBSET)*")) endif # Sanity check: only .cpp files are allowed in sources list, # because we don't have any way to build other sources. NON_CPP_SOURCES:=$(filter-out %.cpp,$(SOURCES_FULL)) ifneq ($(NON_CPP_SOURCES),) $(error The following sources files do not have a .cpp extension: \ $(NON_CPP_SOURCES)) endif MOC_SRC_FULL:=$(patsubst \ $(SOURCES_PATH)/%.h,$(GEN_SRC_PATH)/moc_%.cpp,$(MOC_HDR_FULL) \ ) RES_SRC_FULL:=$(patsubst \ $(RESOURCES_PATH)/%.qrc,$(GEN_SRC_PATH)/qrc_%.cpp,$(RESOURCES_FULL) \ ) UI_HDR_FULL:=$(patsubst \ $(SOURCES_PATH)/%.ui,$(GEN_SRC_PATH)/ui_%.h,$(UI_FULL) \ ) GEN_SRC_FULL:=$(MOC_SRC_FULL) $(RES_SRC_FULL) SOURCES:=$(SOURCES_FULL:$(SOURCES_PATH)/%.cpp=%) GEN_SRC:=$(GEN_SRC_FULL:$(GEN_SRC_PATH)/%.cpp=%) HEADERS:=$(HEADERS_FULL:$(SOURCES_PATH)/%=%) DEPEND_PATH:=$(BUILD_PATH)/dep DEPEND_FULL:=$(addsuffix .d,$(addprefix $(DEPEND_PATH)/,$(SOURCES))) DEPEND_FULL+=$(addsuffix .d,$(addprefix $(DEPEND_PATH)/,$(GEN_SRC))) OBJECTS_PATH:=$(BUILD_PATH)/obj OBJECTS_FULL:=$(addsuffix .o,$(addprefix $(OBJECTS_PATH)/,$(SOURCES))) GEN_OBJ_FULL:=$(addsuffix .o,$(addprefix $(OBJECTS_PATH)/,$(GEN_SRC))) ifeq ($(OPENMSX_TARGET_OS),mingw32) RESOURCE_SRC:=$(RESOURCES_PATH)/openmsx-debugger.rc RESOURCE_OBJ:=$(OBJECTS_PATH)/resources.o RESOURCE_SCRIPT:=build/win_resource.py RESOURCE_HEADER:=$(BUILD_PATH)/config/resource-info.h else RESOURCE_OBJ:= endif # Build Rules # =========== # Include dependency files. ifneq ($(filter $(DEPEND_TARGETS),$(MAKECMDGOALS)),) -include $(DEPEND_FULL) endif # Clean up build tree of current flavour. # We don't have flavours (yet?), so clean up everything except "detectsys". clean: @echo "Cleaning up..." @rm -rf $(OBJECTS_PATH) @rm -rf $(DEPEND_PATH) @rm -rf $(GEN_SRC_PATH) ifeq ($(OPENMSX_TARGET_OS),darwin) @rm -rf $(APP_PATH) else @rm -rf $(BINARY_PATH) endif # Generate version header. .PHONY: forceversionextraction forceversionextraction: $(VERSION_HEADER): forceversionextraction @$(PYTHON) $(VERSION_SCRIPT) $@ # Default target. ifeq ($(OPENMSX_TARGET_OS),darwin) all: app else all: $(BINARY_FULL) endif ifeq ($(QMAKE),) QMAKE:=qmake QT_VERSION:=$(shell $(QMAKE) -query QT_VERSION 2> /dev/null) ifeq ($(QT_VERSION),) QMAKE:=/usr/local/opt/qt5/bin/qmake QT_VERSION:=$(shell $(QMAKE) -query QT_VERSION) endif else QT_VERSION:=$(shell $(QMAKE) -query QT_VERSION) endif ifeq ($(QT_VERSION),) $(error qmake not found, please install and/or pass QMAKE) else ifeq ($(filter 5.%,$(QT_VERSION)),) $(error Qt version $(QT_VERSION) found; please pass QMAKE pointing to Qt 5.x instead) endif QT_INSTALL_HEADERS:=$(shell $(QMAKE) -query QT_INSTALL_HEADERS) QT_INSTALL_LIBS:=$(shell $(QMAKE) -query QT_INSTALL_LIBS) QT_INSTALL_BINS:=$(shell $(QMAKE) -query QT_INSTALL_BINS) # On MingW32 you get backslashes from qmake -query, which we don't want: ifeq ($(OPENMSX_TARGET_OS),mingw32) QT_INSTALL_HEADERS:=$(subst \,/,$(QT_INSTALL_HEADERS)) QT_INSTALL_LIBS:=$(subst \,/,$(QT_INSTALL_LIBS)) QT_INSTALL_BINS:=$(subst \,/,$(QT_INSTALL_BINS)) endif QT_COMPONENTS:=Core Widgets Gui Network Xml QT_HEADER_DIRS:=$(addprefix $(QT_INSTALL_HEADERS)/Qt,$(QT_COMPONENTS)) QT_HEADER_DIRS+=$(QT_INSTALL_HEADERS) ifeq ($(OPENMSX_TARGET_OS),darwin) QT_HEADER_DIRS+=$(patsubst %,/Library/Frameworks/Qt%.framework/Headers,$(QT_COMPONENTS)) endif CXX?=c++ WINDRES?=windres CXXFLAGS:= -g -fPIC INCLUDE_INTERNAL:=$(sort $(foreach header,$(HEADERS_FULL),$(patsubst %/,%,$(dir $(header))))) INCLUDE_INTERNAL+=$(BUILD_PATH)/config COMPILE_FLAGS:=$(addprefix -I,$(QT_HEADER_DIRS) $(INCLUDE_INTERNAL) $(GEN_SRC_PATH)) # Enable C++11 COMPILE_FLAGS+=-std=c++11 ifeq ($(OPENMSX_TARGET_OS),darwin) LINK_FLAGS:=-F$(QT_INSTALL_LIBS) $(addprefix -framework Qt,$(QT_COMPONENTS)) OSX_VER:=10.7 COMPILE_FLAGS+=-mmacosx-version-min=$(OSX_VER) -stdlib=libc++ LINK_FLAGS+=-mmacosx-version-min=$(OSX_VER) -stdlib=libc++ else COMPILE_ENV:= LINK_ENV:= ifeq ($(OPENMSX_TARGET_OS),mingw32) COMPILE_FLAGS+=-static-libgcc -static-libstdc++ LINK_FLAGS:=-Wl,-rpath,$(QT_INSTALL_BINS) -L$(QT_INSTALL_BINS) $(addprefix -lQt5,$(QT_COMPONENTS)) -lws2_32 -lsecur32 -mwindows -static-libgcc -static-libstdc++ else LINK_FLAGS:=-Wl,-rpath,$(QT_INSTALL_LIBS) -L$(QT_INSTALL_LIBS) $(addprefix -lQt5,$(QT_COMPONENTS)) endif endif DEPEND_FLAGS:= # GCC flags: # (these should be omitted if we ever want to support other compilers) # Generic compilation flags. CXXFLAGS+=-pipe # Stricter warning and error reporting. CXXFLAGS+=-Wall # Empty definition of used headers, so header removal doesn't break things. DEPEND_FLAGS+=-MP # Generate Meta Object Compiler sources. $(MOC_SRC_FULL): $(GEN_SRC_PATH)/moc_%.cpp: $(SOURCES_PATH)/%.h @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/moc -o $@ $< # Generate resource source. $(RES_SRC_FULL): $(GEN_SRC_PATH)/qrc_%.cpp: $(RESOURCES_PATH)/%.qrc @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/rcc -name $(<:$(RESOURCES_PATH)/%.qrc=%) $< -o $@ # Generate ui files. $(UI_HDR_FULL): $(GEN_SRC_PATH)/ui_%.h: $(SOURCES_PATH)/%.ui @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/uic -o $@ $< # This is a workaround for the lack of order-only dependencies in GNU Make # versions before than 3.80 (for example Mac OS X 10.3 still ships with 3.79). # It creates a dummy file, which is never modified after its initial creation. # If a rule that produces a file does not modify that file, Make considers the # target to be up-to-date. That way, the targets "ui-dummy-file" depends on # will always be checked before compilation, but they will not cause all object # files to be considered outdated. GEN_DUMMY_FILE:=$(GEN_SRC_PATH)/dummy-file $(GEN_DUMMY_FILE): $(UI_HDR_FULL) $(GENERATED_HEADERS) @test -e $@ || touch $@ # Compile and generate dependency files in one go. SRC_DEPEND_SUBST=$(patsubst $(SOURCES_PATH)/%.cpp,$(DEPEND_PATH)/%.d,$<) GEN_DEPEND_SUBST=$(patsubst $(GEN_SRC_PATH)/%.cpp,$(DEPEND_PATH)/%.d,$<) $(OBJECTS_FULL): $(GEN_DUMMY_FILE) $(OBJECTS_FULL): $(OBJECTS_PATH)/%.o: $(SOURCES_PATH)/%.cpp $(DEPEND_PATH)/%.d @echo "Compiling $(patsubst $(SOURCES_PATH)/%,%,$<)..." @mkdir -p $(@D) @mkdir -p $(patsubst $(OBJECTS_PATH)%,$(DEPEND_PATH)%,$(@D)) @$(COMPILE_ENV) $(CXX) \ $(DEPEND_FLAGS) -MMD -MF $(SRC_DEPEND_SUBST) \ -o $@ $(CXXFLAGS) $(COMPILE_FLAGS) -c $< @touch $@ # Force .o file to be newer than .d file. $(GEN_OBJ_FULL): $(OBJECTS_PATH)/%.o: $(GEN_SRC_PATH)/%.cpp $(DEPEND_PATH)/%.d @echo "Compiling $(patsubst $(GEN_SRC_PATH)/%,%,$<)..." @mkdir -p $(@D) @mkdir -p $(patsubst $(OBJECTS_PATH)%,$(DEPEND_PATH)%,$(@D)) @$(COMPILE_ENV) $(CXX) \ $(DEPEND_FLAGS) -MMD -MF $(GEN_DEPEND_SUBST) \ -o $@ $(CXXFLAGS) $(COMPILE_FLAGS) -c $< @touch $@ # Force .o file to be newer than .d file. # Generate dependencies that do not exist yet. # This is only in case some .d files have been deleted; # in normal operation this rule is never triggered. $(DEPEND_FULL): # Windows resources that are added to the executable. ifeq ($(OPENMSX_TARGET_OS),mingw32) $(RESOURCE_HEADER): forceversionextraction @$(PYTHON) $(RESOURCE_SCRIPT) $@ $(RESOURCE_OBJ): $(RESOURCE_SRC) $(RESOURCE_HEADER) @echo "Compiling resources..." @mkdir -p $(@D) @$(WINDRES) $(addprefix --include-dir=,$(^D)) -o $@ -i $< endif # Link executable. $(BINARY_FULL): $(OBJECTS_FULL) $(GEN_OBJ_FULL) $(RESOURCE_OBJ) ifeq ($(OPENMSX_SUBSET),) @echo "Linking $(@F)..." @mkdir -p $(@D) @$(LINK_ENV) $(CXX) -o $@ $(CXXFLAGS) $^ $(LINK_FLAGS) else @echo "Not linking $(notdir $@) because only a subset was built." endif # Application folder. ifeq ($(OPENMSX_TARGET_OS),darwin) app: $(BINARY_FULL) $(PKGINFO_FULL) $(APP_PLIST) $(APP_RESOURCES) $(PKGINFO_FULL): @echo "Generating $(@F)..." @mkdir -p $(@D) @echo "APPLoMXD" > $@ $(APP_PLIST): $(APP_PATH)/Contents/%: $(APP_SUPPORT_PATH)/% @echo "Generating $(@F)..." @mkdir -p $(@D) @sed -e 's/%ICON%/$(notdir $(APP_ICON))/' \ -e 's/%VERSION%/$(PACKAGE_DETAILED_VERSION)/' < $< > $@ $(APP_RESOURCES): $(APP_PATH)/Contents/Resources/%: $(APP_SUPPORT_PATH)/% @echo "Copying $(@F)..." @mkdir -p $(@D) @cp $< $@ endif # Source Packaging # ================ dist: @$(PYTHON) build/gitdist.py endif # PLATFORM debugger-master/build/package-windows/0000755000175000017500000000000013560352104017650 5ustar shevekshevekdebugger-master/build/package-windows/packagewindows.py0000644000175000017500000000516313560352104023235 0ustar shevekshevekimport os, sys def DeleteDirectoryIfExists(top): if os.path.exists(top): DeleteDirectory(top) def DeleteDirectory(top): for root, dirs, files in os.walk(top, topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) def GenerateInstallFiles(info): DeleteDirectoryIfExists(info.makeInstallPath) install.installAll(info.makeInstallPath + os.sep, 'bin', 'share', 'doc', info.openmsxExePath, 'mingw32', True, True) def WalkPath(sourcePath): if os.path.isfile(sourcePath): filenames = list() filenames.append(os.path.basename(sourcePath)) yield os.path.dirname(sourcePath), list(), filenames else: for dirpath, dirnames, filenames in os.walk(sourcePath): yield dirpath, dirnames, filenames class PackageInfo: def __init__(self, platform, configuration, version, catapultPath): self.platform = platform.lower() if self.platform == 'win32': self.architecture = 'x86' self.platform = 'Win32' self.win64 = False elif self.platform == 'x64': self.architecture = 'x64' self.platform = 'x64' self.win64 = True else: raise ValueError, 'Wrong platform: ' + platform self.configuration = configuration.lower() if self.configuration == 'release': self.configuration = 'Release' self.catapultConfiguration = 'Unicode Release' elif self.configuration == 'Developer': self.configuration = 'Developer' self.catapultConfiguration = 'Unicode Debug' elif self.configuration == 'Debug': self.configuration = 'Debug' self.catapultConfiguration = 'Unicode Debug' else: raise ValueError, 'Wrong configuration: ' + architecture self.version = version self.catapultPath = catapultPath # Useful variables self.buildFlavor = self.platform + '-VC-' + self.configuration self.buildPath = os.path.join('derived', self.buildFlavor) self.installPath = os.path.join(self.buildPath, 'install') self.sourcePath = 'src' self.codecPath = 'Contrib\\codec\\Win32' self.packageWindowsPath = 'build\\package-windows' self.packagePath = os.path.join(self.buildPath, 'package-windows') self.makeInstallPath = os.path.join(self.packagePath, 'install') self.installerFileName = 'openmsx-debugger-' + version + '-VC-' + self.architecture if __name__ == '__main__': if len(sys.argv) == 5: info = PackageInfo(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) else: print >> sys.stderr, \ 'Usage: python packagewindowsinfo.py architecture, configuration, version, catapultPath' sys.exit(2) debugger-master/build/package-windows/package.cmd0000644000175000017500000000171013560352104021727 0ustar shevekshevek@echo off rem rem **** Run this from the top of the debugger source tree: **** rem rem Usage: package.cmd DEBUGGER_PLATFORM DEBUGGER_CONFIGURATION DEBUGGER_VERSION rem rem **** DEBUGGER_PLATFORM is { Win32, x64 } **** rem **** DEBUGGER_CONFIGURATION is { Release, Debug } **** rem **** DEBUGGER_VERSION is a version string; e.g. 0.7.0 **** if "%3" == "" goto usage if "%4" NEQ "" goto usage setlocal set DEBUGGER_PLATFORM=%1 echo DEBUGGER_PLATFORM is %DEBUGGER_PLATFORM% set DEBUGGER_CONFIGURATION=%2 echo DEBUGGER_CONFIGURATION is %DEBUGGER_CONFIGURATION% set DEBUGGER_VERSION=%3 echo DEBUGGER_VERSION is %DEBUGGER_VERSION% set DEBUGGER_PACKAGE_WINDOWS_PATH=.\build\package-windows set PYTHONPATH=%PYTHONPATH%;.\build python %DEBUGGER_PACKAGE_WINDOWS_PATH%\packagezip.py %DEBUGGER_PLATFORM% %DEBUGGER_CONFIGURATION% %DEBUGGER_VERSION% endlocal goto end :usage echo Usage: package.cmd platform configuration version :end debugger-master/build/package-windows/packagezip.py0000644000175000017500000000327713560352104022351 0ustar shevekshevekimport os, sys import zipfile import packagewindows def AddFile(zip, path, zipPath): print 'Adding ' + path zip.write(path, zipPath, zipfile.ZIP_DEFLATED) def AddDirectory(zip, root, zipPath): for path, dirs, files in os.walk(root): if '.svn' in dirs: dirs.remove('.svn') # don't visit .svn directories for name in files: thisZipPath = zipPath if os.path.abspath(root) != os.path.abspath(path): thisZipPath = os.path.join(thisZipPath, os.path.relpath(path, root)) AddFile(zip, os.path.join(path, name), os.path.join(thisZipPath, name)) def PackageZip(info): if not os.path.exists(info.packagePath): os.mkdir(info.packagePath) zipFileName = info.installerFileName + '.zip' zipFilePath = os.path.join(info.packagePath, zipFileName) if os.path.exists(zipFilePath): os.unlink(zipFilePath) print 'Generating ' + zipFilePath zip = zipfile.ZipFile(zipFilePath, 'w') AddFile(zip, os.path.join(info.installPath, 'openmsx-debugger.exe'), 'openmsx-debugger.exe') zip.close() zipFileName = info.installerFileName + '-pdb.zip' zipFilePath = os.path.join(info.packagePath, zipFileName) if os.path.exists(zipFilePath): os.unlink(zipFilePath) print 'Generating ' + zipFilePath zip = zipfile.ZipFile(zipFilePath, 'w') AddFile(zip, os.path.join(info.installPath, 'openmsx-debugger.pdb'), 'openmsx-debugger.pdb') zip.close() if __name__ == '__main__': if len(sys.argv) != 4: print >> sys.stderr, 'Usage: python packagezip.py platform configuration version' # E.g. build\package-windows\package.cmd x64 Release 0.7.1 sys.exit(2) else: info = packagewindows.PackageInfo(sys.argv[1], sys.argv[2], sys.argv[3], '') PackageZip(info) debugger-master/build/install-recursive.sh0000755000175000017500000000116013560352104020575 0ustar shevekshevek#!/bin/sh if [ $# -lt 2 ] then echo "Usage: $0 (|)+ " >&2 exit 1 fi if [ $# -eq 2 ] then src="$1" shift if [ -d "$src" ] then src="$src"/* fi else src="" while [ $# -ne 1 ] do src="$src $1" shift done fi dst="$1" for path in $src do name=$(basename "$path") dir=$(dirname "$path") if [ -L "$path" ] then echo "skipping symbolic link: $path" elif [ -d "$path" ] then if [ "$name" != .svn ] then $0 "$path" "$dst" fi else install -m 0755 -d "$dst/$dir" mode=0644 if [ -x "$path" ] then mode=0755 fi install -m $mode "$path" "$dst/$dir" fi done debugger-master/build/node-end.mk0000644000175000017500000000141713560352104016612 0ustar shevekshevek# Should be included at the end of each node.mk file. # Process this node. SOURCES_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .cpp, \ $(MOC_SRC_HDR) $(SRC_HDR) $(SRC_ONLY) \ ))) HEADERS_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .h, \ $(MOC_SRC_HDR) $(SRC_HDR) $(HDR_ONLY) \ ))) MOC_HDR_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .h, \ $(MOC_SRC_HDR) \ ))) UI_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .ui, \ $(UI) \ ))) # Process subnodes. ifneq ($(SUBDIRS),) SUBDIRS:=$(addsuffix /,$(SUBDIRS)) SUBDIRSTACK:=$(SUBDIRS) $(SUBDIRSTACK) include $(addprefix $(CURDIR),$(addsuffix node.mk,$(SUBDIRS))) endif # Pop current directory off directory stack. CURDIR:=$(firstword $(DIRSTACK)) DIRSTACK:=$(wordlist 2,$(words $(DIRSTACK)),$(DIRSTACK)) debugger-master/build/node-start.mk0000644000175000017500000000061713560352104017202 0ustar shevekshevek# Should be included at the start of each node.mk file. # Get name of current directory. SUBDIR:=$(firstword $(SUBDIRSTACK)) SUBDIRSTACK:=$(wordlist 2,$(words $(SUBDIRSTACK)),$(SUBDIRSTACK)) # Push current directory on directory stack. DIRSTACK:=$(CURDIR) $(DIRSTACK) CURDIR:=$(CURDIR)$(SUBDIR) # Initialise node vars with empty value. SUBDIRS:= MOC_SRC_HDR:= SRC_HDR:= SRC_ONLY:= HDR_ONLY:= UI:= debugger-master/build/executils.py0000644000175000017500000000375413560352104017155 0ustar shevekshevekfrom msysutils import msysActive, msysShell from os import environ from shlex import split as shsplit from subprocess import PIPE, Popen def captureStdout(log, commandLine): '''Run a command and capture what it writes to stdout. If the command fails or writes something to stderr, that is logged. Returns the captured string, or None if the command failed. ''' # TODO: This is a modified copy-paste from compilers._Command. commandParts = shsplit(commandLine) env = dict(environ) while commandParts: if '=' in commandParts[0]: name, value = commandParts[0].split('=', 1) del commandParts[0] env[name] = value else: break else: raise ValueError( 'No command specified in "%s"' % commandLine ) if msysActive() and commandParts[0] != 'sh': commandParts = [ environ.get('MSYSCON') or environ.get('SHELL') or 'sh.exe', '-c', shjoin(commandParts) ] try: proc = Popen( commandParts, bufsize = -1, env = env, stdin = None, stdout = PIPE, stderr = PIPE, ) except OSError, ex: print >> log, 'Failed to execute "%s": %s' % (commandLine, ex) return None stdoutdata, stderrdata = proc.communicate() if stderrdata: severity = 'warning' if proc.returncode == 0 else 'error' log.write('%s executing "%s"\n' % (severity.capitalize(), commandLine)) # pylint 0.18.0 somehow thinks stderrdata is a list, not a string. # pylint: disable-msg=E1103 stderrdata = stderrdata.replace('\r', '') log.write(stderrdata) if not stderrdata.endswith('\n'): log.write('\n') if proc.returncode == 0: return stdoutdata else: print >> log, 'Execution failed with exit code %d' % proc.returncode return None def shjoin(parts): '''Joins the given sequence into a single string with space as a separator. Characters that have a special meaning for the shell are escaped. This is the counterpart of shlex.split(). ''' def escape(part): return ''.join( '\\' + ch if ch in '\\ \'"$()[]' else ch for ch in part ) return ' '.join(escape(part) for part in parts) debugger-master/build/version2code.py0000644000175000017500000000125213560352104017541 0ustar shevekshevek# Generates version include file. from outpututils import rewriteIfChanged from version import extractRevisionString, packageVersion, releaseFlag import sys def iterVersionInclude(): revision = extractRevisionString() yield '// Automatically generated by build process.' yield 'const bool Version::RELEASE = %s;' % str(releaseFlag).lower() yield 'const char* const Version::VERSION = "%s";' % packageVersion yield 'const char* const Version::REVISION = "%s";' % revision if __name__ == '__main__': if len(sys.argv) == 2: rewriteIfChanged(sys.argv[1], iterVersionInclude()) else: print >> sys.stderr, \ 'Usage: python version2code.py VERSION_HEADER' sys.exit(2) debugger-master/build/win_resource.py0000644000175000017500000000146013560352104017644 0ustar shevekshevek# Generates Windows resource header. from outpututils import rewriteIfChanged from version import extractRevisionNumber, packageVersion import sys def iterResourceHeader(): if '-' in packageVersion: versionNumber = packageVersion[ : packageVersion.index('-')] else: versionNumber = packageVersion revision = str(extractRevisionNumber()) versionComponents = versionNumber.split('.') + [ revision ] assert len(versionComponents) == 4, versionComponents yield '#define OPENMSXDEBUGGER_VERSION_INT %s' % ', '.join(versionComponents) yield '#define OPENMSXDEBUGGER_VERSION_STR "%s\\0"' % packageVersion if __name__ == '__main__': if len(sys.argv) == 2: rewriteIfChanged(sys.argv[1], iterResourceHeader()) else: print >> sys.stderr, \ 'Usage: python win-resource.py RESOURCE_HEADER' sys.exit(2) debugger-master/build/gitdist.py0000755000175000017500000000660013560352104016613 0ustar shevekshevek#!/usr/bin/env python2 # Creates a source distribution package. from os import makedirs, remove from os.path import isdir from subprocess import CalledProcessError, PIPE, Popen, check_output from tarfile import TarError, TarFile import stat, sys verbose = False def archiveFromGit(versionedPackageName, committish): prefix = '%s/' % versionedPackageName distBase = 'derived/dist/' umask = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH ) def exclude(info): '''Returns True iff the given tar entry should be excluded. ''' return any(( info.name.endswith('/.gitignore'), )) proc = Popen( ('git', 'archive', '--prefix=' + prefix, '--format=tar', committish), bufsize = -1, stdin = None, stdout = PIPE, stderr = sys.stderr, ) try: outTarPath = distBase + versionedPackageName + '.tar.gz' print 'archive:', outTarPath if not isdir(distBase): makedirs(distBase) outTar = TarFile.open(outTarPath, 'w:gz') try: # Copy entries from "git archive" into output tarball, except for # excluded entries. numIncluded = numExcluded = 0 inTar = TarFile.open(mode = 'r|', fileobj = proc.stdout) try: for info in inTar: if exclude(info): if verbose: print 'EX', info.name numExcluded += 1 else: if verbose: print 'IN', info.name numIncluded += 1 info.uid = info.gid = 1000 info.uname = info.gname = 'openmsx' info.mode = info.mode & umask outTar.addfile(info, inTar.extractfile(info)) finally: inTar.close() print 'entries: %d included, %d excluded' % ( numIncluded, numExcluded) except: # Clean up partial output file. outTar.close() remove(outTarPath) raise else: outTar.close() except: proc.terminate() raise else: data, _ = proc.communicate() if len(data) != 0: print >> sys.stderr, ( 'WARNING: %d more bytes of data from "git archive" after ' 'tar stream ended' % len(data)) def niceVersionFromGitDescription(description): '''Our release tag names are still based on naming limitations from CVS; convert them to something more pleasing to the eyes. ''' parts = description.split('-') if parts[0].startswith('RELEASE_'): tagParts = tag.split('_')[1 : ] i = 0 while i < len(tagParts) and tagParts[i].isdigit(): i += 1 parts[0] = '-'.join( ['.'.join(tagParts[ : i])] + [s.lower() for s in tagParts[i : ]] ) if len(parts) >= 2: parts[1] = 'dev' + parts[1] if parts[0] == 'INIT': del parts[0] return '-'.join(parts) def getDescription(committish): args = ['git', 'describe', '--abbrev=9'] if committish is not None: args.append(committish) try: return check_output(args).rstrip('\n') except CalledProcessError as ex: print >> sys.stderr, '"%s" returned %d' % ( ' '.join(args), ex.returncode ) raise def main(committish = None): try: description = getDescription(committish) except CalledProcessError: sys.exit(1) version = niceVersionFromGitDescription(description) try: archiveFromGit('openmsx-debugger-%s' % version, description) except (OSError, TarError) as ex: print >> sys.stderr, 'ERROR: %s' % ex sys.exit(1) if __name__ == '__main__': if len(sys.argv) == 1: main() elif len(sys.argv) == 2: main(sys.argv[1]) else: print >> sys.stderr, 'Usage: gitdist.py [branch | tag]' sys.exit(2) debugger-master/build/outpututils.py0000644000175000017500000000203313560352104017556 0ustar shevekshevek# Various utility functions for generating output files and directories. from os import makedirs from os.path import dirname, isdir, isfile def createDirFor(filePath): '''Creates an output directory for containing the given file path. Nothing happens if the directory already exsits. ''' dirPath = dirname(filePath) if dirPath and not isdir(dirPath): makedirs(dirPath) def rewriteIfChanged(path, lines): '''Writes the file with the given path if it does not exist yet or if its contents should change. The contents are given by the "lines" sequence. Returns True if the file was (re)written, False otherwise. ''' newLines = [ line + '\n' for line in lines ] if isfile(path): inp = open(path, 'r') try: oldLines = inp.readlines() finally: inp.close() if newLines == oldLines: print 'Up to date: %s' % path return False else: print 'Updating %s...' % path else: print 'Creating %s...' % path createDirFor(path) out = open(path, 'w') try: out.writelines(newLines) finally: out.close() return True debugger-master/GNUmakefile0000644000175000017500000000002613560352104015536 0ustar shevekshevekinclude build/main.mk