diff --git a/tests/manual/trk/adapter.cpp b/tests/manual/trk/adapter.cpp
index 2d16408df581aa9b4214fcd393f9302af92df613..e6acd6ecc3654b30cf3deab84ffa398b659b3fe6 100644
--- a/tests/manual/trk/adapter.cpp
+++ b/tests/manual/trk/adapter.cpp
@@ -55,6 +55,8 @@ BOOL WINAPI TryReadFile(HANDLE          hFile,
         qDebug() << "ClearCommError() failed";
         return FALSE;
     }
+    if (!comStat.cbInQue)
+        return FALSE;
     return ReadFile(hFile,
                     lpBuffer,
                     qMin(comStat.cbInQue, nNumberOfBytesToRead),
@@ -200,6 +202,8 @@ private:
     void handleWaitForFinished(const TrkResult &result);
     void handleStop(const TrkResult &result);
     void handleSupportMask(const TrkResult &result);
+    void handleTrkVersions(const TrkResult &result);
+    void handleDisconnect(const TrkResult &result);
 
     void handleAndReportCreateProcess(const TrkResult &result);
     void handleAndReportReadRegisters(const TrkResult &result);
@@ -257,6 +261,7 @@ private:
     int m_verbose;
     Endianness m_registerEndianness;
     bool m_useSocket;
+    bool m_startInferiorTriggered;
 };
 
 Adapter::Adapter() :
@@ -271,7 +276,8 @@ Adapter::Adapter() :
     m_gdbAckMode(true),
     m_verbose(1),
     m_registerEndianness(BigEndian),
-    m_useSocket(false)
+    m_useSocket(false),
+    m_startInferiorTriggered(false)
 {
     startTimer(100);
 }
@@ -317,8 +323,8 @@ bool Adapter::startServer()
     sendTrkMessage(0x01); // Connect
     sendTrkMessage(0x05, CB(handleSupportMask));
     sendTrkMessage(0x06, CB(handleCpuType));
-    sendTrkMessage(0x04); // Versions
-    sendTrkMessage(0x09); // Unrecognized command
+    sendTrkMessage(0x04, CB(handleTrkVersions)); // Versions
+    //sendTrkMessage(0x09); // Unrecognized command
     //sendTrkMessage(0x4a, 0,
     //    "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File
     //sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File
@@ -358,6 +364,7 @@ void Adapter::handleGdbConnection()
             m_gdbConnection, SLOT(deleteLater()));
     connect(m_gdbConnection, SIGNAL(readyRead()),
             this, SLOT(readFromGdb()));
+    m_startInferiorTriggered = false;
 }
 
 void Adapter::readFromGdb()
@@ -422,7 +429,7 @@ void Adapter::readFromGdb()
         }
 
         QByteArray response = ba.left(pos);
-        ba = ba.mid(pos + 3);
+        ba.remove(0, pos + 3);
         handleGdbResponse(response);
     }
 }
@@ -554,17 +561,12 @@ void Adapter::handleGdbResponse(const QByteArray &response)
         //sendGdbMessage("00000000", "read registers");
         sendGdbAckMessage();
         QByteArray ba;
-        appendByte(&ba, 0); // ?
-        appendByte(&ba, 0); // ?
-        appendByte(&ba, 0); // ?
-
-        appendByte(&ba, 0); // first register
-        // FIXME: off by one?
-        appendByte(&ba, RegisterCount - 1); // last register
+        appendByte(&ba, 0); // Register set, only 0 supported
+        appendShort(&ba, 0);
+        appendShort(&ba, RegisterCount - 1); // last register
         appendInt(&ba, m_session.pid);
         appendInt(&ba, m_session.tid);
-
-        sendTrkMessage(0x12, CB(handleAndReportReadRegisters), ba);
+        sendTrkMessage(0x12, CB(handleAndReportReadRegisters), ba, QVariant(), true);
     }
 
     else if (response.startsWith("Hc")) {
@@ -597,15 +599,26 @@ void Adapter::handleGdbResponse(const QByteArray &response)
 
     else if (response.startsWith("m")) {
         // m addr,length
-        sendGdbAckMessage();
-        int pos = response.indexOf(',');
-        bool ok = false;
-        uint addr = response.mid(1, pos - 1).toInt(&ok, 16);
-        uint len = response.mid(pos + 1).toInt(&ok, 16);
-        //qDebug() << "GDB ADDR: " << hexNumber(addr) << " " << hexNumber(len);
-        readMemory(addr, len);
+        sendGdbAckMessage();        
+        uint addr = 0, len = 0;
+        do {
+            const int pos = response.indexOf(',');
+            if (pos == -1)
+                break;
+            bool ok;
+            addr = response.mid(1, pos - 1).toUInt(&ok, 16);
+            if (!ok)
+                break;
+            len = response.mid(pos + 1).toUInt(&ok, 16);
+            if (!ok)
+                break;
+        } while (false);
+        if (len) {
+            readMemory(addr, len);
+        } else {
+            sendGdbMessage("E20", "Error " + response);
+        }
     }
-
     else if (response.startsWith("p")) {
         // 0xf == current instruction pointer?
         //sendGdbMessage("0000", "current IP");
@@ -843,7 +856,9 @@ void Adapter::sendTrkMessage(byte code, TrkCallBack callBack,
 {
     TrkMessage msg;
     msg.code = code;
-    msg.token = nextTrkWriteToken();
+    // Tokens must be strictly sequential
+    if (msg.code != TRK_SYNC)
+        msg.token = nextTrkWriteToken();
     msg.callBack = callBack;
     msg.data = data;
     msg.cookie = cookie;
@@ -896,7 +911,7 @@ void Adapter::tryTrkWrite()
 
     TrkMessage msg = m_trkWriteQueue.dequeue();
     if (msg.code == TRK_SYNC) {
-        //logMessage("TRK SYNC");
+        logMessage(QString::fromLatin1("TRK SYNC [token=%1]").arg(msg.token));
         TrkResult result;
         result.code = msg.code;
         result.token = msg.token;
@@ -917,8 +932,10 @@ void Adapter::trkWrite(const TrkMessage &msg)
     m_writtenTrkMessages.insert(msg.token, msg);
     m_trkWriteBusy = true;
 
-    if (m_verbose > 1)
-        logMessage("WRITE: " + stringFromArray(ba));
+    if (m_verbose > 1) {
+        const QString logMsg = QString::fromLatin1("WRITE: 0x%1 [token=%2]: %3").arg(msg.code, 0, 16).arg(msg.token).arg(stringFromArray(ba));
+        logMessage(logMsg);
+    }
 
     if (m_useSocket) {
         if (!m_socketDevice->write(ba))
@@ -945,16 +962,19 @@ void Adapter::tryTrkRead()
         QByteArray res = m_socketDevice->readAll();
         m_trkReadQueue.append(res);
     } else {
-#ifdef Q_OS_WIN    
+#ifdef Q_OS_WIN  
         const DWORD BUFFERSIZE = 1024;
         char buffer[BUFFERSIZE];
         DWORD charsRead;
-
+        DWORD totalCharsRead = 0;
         while (TryReadFile(m_winComDevice, buffer, BUFFERSIZE, &charsRead, NULL)) {
             m_trkReadQueue.append(buffer, charsRead);
+            totalCharsRead += charsRead;
             if (isValidTrkResult(m_trkReadQueue))
                 break;
         }
+        if (!totalCharsRead)
+            return;
 #endif // USE_NATIVE
     }
 
@@ -979,9 +999,8 @@ void Adapter::handleResult(const TrkResult &result)
     switch (result.code) {
         case 0x80: { // ACK
             //logMessage(prefix + "ACK: " + str);
-            if (!result.data.isEmpty() && result.data.at(0))
-                logMessage(prefix + "ERR: " +QByteArray::number(result.data.at(0)));
-            //logMessage("READ RESULT FOR TOKEN: " << token);
+            if (const int ec = result.errorCode())
+                logMessage(QString::fromLatin1("READ BUF ACK/ERR %1 for token=%2").arg(ec).arg(result.token), true);
             if (!m_writtenTrkMessages.contains(result.token)) {
                 logMessage("NO ENTRY FOUND!");
             }
@@ -998,15 +1017,17 @@ void Adapter::handleResult(const TrkResult &result)
             }
             break;
         }
-        case 0xff: { // NAK
-            logMessage(prefix + "NAK: " + str);
-            logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0)));
-            TrkMessage msg = m_writtenTrkMessages.take(result.token);
+        case 0xff: { // NAK. This mostly means transmission error, not command failed.
+            const TrkMessage writtenMsg = m_writtenTrkMessages.take(result.token);
+            QString logMsg;
+            QTextStream(&logMsg) << prefix << "NAK: for 0x" << QString::number(int(writtenMsg.code), 16)
+                    << " token=" << result.token << " ERROR: " << errorMessage(result.data.at(0)) << ' ' << str;
+            logMessage(logMsg, true);
             // Invoke failure if desired
-            if (msg.callBack && msg.invokeOnFailure) {
+            if (writtenMsg.callBack && writtenMsg.invokeOnFailure) {
                 TrkResult result1 = result;
-                result1.cookie = msg.cookie;
-                (this->*msg.callBack)(result1);
+                result1.cookie = writtenMsg.cookie;
+                (this->*writtenMsg.callBack)(result1);
             }
             break;
         }
@@ -1036,28 +1057,25 @@ void Adapter::handleResult(const TrkResult &result)
 
         // target->host OS notification
         case 0xa0: { // Notify Created
-            /*
             const char *data = result.data.data();
-            byte error = result.data.at(0);
-            byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
-            uint pid = extractInt(data + 2); //  ProcessID: 4 bytes;
-            uint tid = extractInt(data + 6); //threadID: 4 bytes
-            uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library
-            uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library
-            uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow
-            QByteArray name = result.data.mid(20, len); // name: library name
-
-            logMessage(prefix + "NOTE: LIBRARY LOAD: " + str);
-            logMessage(prefix + "TOKEN: " + result.token);
-            logMessage(prefix + "ERROR: " + int(error));
-            logMessage(prefix + "TYPE:  " + int(type));
-            logMessage(prefix + "PID:   " + pid);
-            logMessage(prefix + "TID:   " + tid);
-            logMessage(prefix + "CODE:  " + codeseg);
-            logMessage(prefix + "DATA:  " + dataseg);
-            logMessage(prefix + "LEN:   " + len);
-            logMessage(prefix + "NAME:  " + name);
-            */
+            const byte error = result.data.at(0);
+            const byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
+            const uint pid = extractInt(data + 2); //  ProcessID: 4 bytes;
+            const uint tid = extractInt(data + 6); //threadID: 4 bytes
+            const uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library
+            const uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library
+            const uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow
+            const QByteArray name = result.data.mid(20, len); // name: library name
+            QString logMsg;
+            QTextStream str(&logMsg);
+            str<< prefix << " NOTE: LIBRARY LOAD: token=" + result.token << " ERROR: "
+                    << int(error) << " TYPE: " << int(type) << " PID: " << pid
+                    << " TID:   " <<  tid;
+            str.setIntegerBase(16);
+            str << " CODE: 0x" + codeseg << " DATA: 0x"  << dataseg;
+            str.setIntegerBase(10);
+            str << " LEN: " << len << " NAME: " << name;
+            logMessage(logMsg);
 
             QByteArray ba;
             appendInt(&ba, m_session.pid);
@@ -1095,7 +1113,6 @@ void Adapter::handleResult(const TrkResult &result)
 
 void Adapter::handleCpuType(const TrkResult &result)
 {
-    logMessage("HANDLE CPU TYPE: " + result.toString());
     //---TRK------------------------------------------------------
     //  Command: 0x80 Acknowledge
     //    Error: 0x00
@@ -1107,6 +1124,12 @@ void Adapter::handleCpuType(const TrkResult &result)
     m_session.fpTypeSize = result.data[4];
     m_session.extended1TypeSize = result.data[5];
     //m_session.extended2TypeSize = result.data[6];
+    QString logMsg;
+    QTextStream(&logMsg) << "HANDLE CPU TYPE: " << " CPU=" << m_session.cpuMajor << '.'
+            << m_session.cpuMinor << " bigEndian=" << m_session.bigEndian
+            << " defaultTypeSize=" << m_session.defaultTypeSize
+            << " fpTypeSize=" << m_session.fpTypeSize << " extended1TypeSize=" <<  m_session.extended1TypeSize;
+    logMessage(logMsg);
 }
 
 void Adapter::handleCreateProcess(const TrkResult &result)
@@ -1119,10 +1142,9 @@ void Adapter::handleCreateProcess(const TrkResult &result)
     m_session.tid = extractInt(data + 5);
     m_session.codeseg = extractInt(data + 9);
     m_session.dataseg = extractInt(data + 13);
-    qDebug() << "    READ PID: " << m_session.pid;
-    qDebug() << "    READ TID: " << m_session.tid;
-    qDebug() << "    READ CODE: " << m_session.codeseg;
-    qDebug() << "    READ DATA: " << m_session.dataseg;
+    QString logMsg = QString::fromLatin1("handleCreateProcess PID=%1 TID=%2 CODE=0x%3 (%4) DATA=0x%5 (%6)")
+                     .arg(m_session.pid).arg(m_session.tid).arg(m_session.codeseg, 0 ,16).arg(m_session.codeseg).arg(m_session.dataseg, 0, 16).arg(m_session.dataseg);
+    logMessage(logMsg);
 
 #if 0
     /*
@@ -1196,12 +1218,11 @@ void Adapter::handleAndReportReadRegisters(const TrkResult &result)
     //logMessage("       RESULT: " + result.toString());
     // [80 0B 00   00 00 00 00   C9 24 FF BC   00 00 00 00   00
     //  60 00 00   00 00 00 00   78 67 79 70   00 00 00 00   00...]
-    const char *data = result.data.data();
+
+    const char *data = result.data.data() + 1; // Skip ok byte
     for (int i = 0; i < RegisterCount; ++i) {
         m_snapshot.registers[i] = extractInt(data + 4 * i);
-        //qDebug() << i << hexNumber(m_snapshot.registers[i], 8);
     }
-    //QByteArray ba = result.data.toHex();
     QByteArray ba;
     for (int i = 0; i < 16; ++i) {
         const uint reg = m_registerEndianness == LittleEndian ? swapEndian(m_snapshot.registers[i]) : m_snapshot.registers[i];
@@ -1215,16 +1236,16 @@ void Adapter::handleAndReportReadRegisters(const TrkResult &result)
     sendGdbMessage(ba, logMsg);
 }
 
-static inline QString msgMemoryReadError(uint addr)
+static inline QString msgMemoryReadError(int code, uint addr)
 {
-    return QString::fromLatin1("Memory read error at: 0x%1").arg(addr, 0 ,16);
+    return QString::fromLatin1("Memory read error %1 at: 0x%2").arg(code).arg(addr, 0 ,16);
 }
 
 void Adapter::handleReadMemory(const TrkResult &result)
 {
     const uint blockaddr = result.cookie.toInt();
-    if (result.code == 0xff) {
-        logMessage(msgMemoryReadError(blockaddr));
+    if (const int errorCode = result.errorCode()) {
+        logMessage(msgMemoryReadError(errorCode, blockaddr));
     } else {
         const QByteArray ba = result.data.mid(1);
         m_snapshot.memory.insert(blockaddr , ba);
@@ -1285,7 +1306,7 @@ void Adapter::reportReadMemory(const TrkResult &result)
         ba.truncate(len);
     if (ba.isEmpty()) {
         ba = "E20";
-        sendGdbMessage(ba, msgMemoryReadError(addr).toLatin1());
+        sendGdbMessage(ba, msgMemoryReadError(32, addr).toLatin1());
     } else {
         sendGdbMessage(ba.toHex(), memoryReadLogMessage(addr, len, ba));
     }
@@ -1381,8 +1402,24 @@ void Adapter::handleSupportMask(const TrkResult &result)
             str.append(QByteArray::number(i * 8 + j, 16));
     }
     logMessage("SUPPORTED: " + str);
+ }
+
+void Adapter::handleTrkVersions(const TrkResult &result)
+{
+    QString logMsg;
+    QTextStream str(&logMsg);
+    str << "Versions: ";
+    if (result.data.size() >= 5) {
+        str << "Trk version " << int(result.data.at(1)) << '.' << int(result.data.at(2))
+                << ", Protocol version " << int(result.data.at(3)) << '.' << int(result.data.at(4));
+    }
+    logMessage(logMsg);
 }
 
+void Adapter::handleDisconnect(const TrkResult & /*result*/)
+{
+    logMessage(QLatin1String("Trk disconnected"), true);
+}
 
 void Adapter::cleanUp()
 {
@@ -1392,6 +1429,10 @@ void Adapter::cleanUp()
     //  Sub Cmd: Delete Process
     //ProcessID: 0x0000071F (1823)
     // [41 24 00 00 00 00 07 1F]
+    logMessage(QString::fromLatin1("Cleanup PID=%1").arg(m_session.pid), true);
+    if (!m_session.pid)
+        return;
+
     QByteArray ba;
     appendByte(&ba, 0x00);
     appendByte(&ba, 0x00);
@@ -1406,6 +1447,8 @@ void Adapter::cleanUp()
     foreach (const Breakpoint &bp, m_breakpoints)
         clearTrkBreakpoint(bp);
 
+    sendTrkMessage(0x02, CB(handleDisconnect));
+    m_startInferiorTriggered = false;
     //---IDE------------------------------------------------------
     //  Command: 0x1C Clear Break
     // [1C 25 00 00 00 0A 78 6A 43 40]
@@ -1446,12 +1489,14 @@ void Adapter::readMemory(uint addr, uint len)
     Q_ASSERT(len < (2 << 16));
 
     // We try to get medium-sized chunks of data from the device
+    if (m_verbose > 2)
+        logMessage(QString::fromLatin1("readMemory %1 bytes from 0x%2 blocksize=%3").arg(len).arg(addr, 0, 16).arg(MemoryChunkSize));
 
-    QList <uint> blocksToFetch;
     uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
     for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
-        QByteArray blockdata = m_snapshot.memory[blockaddr];
-        if (blockdata.isEmpty()) {
+        if (!m_snapshot.memory.contains(blockaddr)) {
+            if (m_verbose > 2)
+                logMessage(QString::fromLatin1("Requesting memory from 0x%1").arg(blockaddr, 0, 16));
             // fetch it
             QByteArray ba;
             appendByte(&ba, 0x08); // Options, FIXME: why?
@@ -1469,11 +1514,14 @@ void Adapter::readMemory(uint addr, uint len)
 
 void Adapter::startInferiorIfNeeded()
 {
+    if (m_startInferiorTriggered)
+        return;
     if (m_session.pid != 0) {
         qDebug() << "Process already 'started'";
         return;
     }
     // It's not started yet
+    m_startInferiorTriggered = true;
     QByteArray ba;
     appendByte(&ba, 0); // ?
     appendByte(&ba, 0); // ?
diff --git a/tests/manual/trk/trkserver.cpp b/tests/manual/trk/trkserver.cpp
index 911d87b2c9ee46d8977bb38cc09c017e64424974..6deae2ea576d30de098fefb8ae1091a7e5aac4eb 100644
--- a/tests/manual/trk/trkserver.cpp
+++ b/tests/manual/trk/trkserver.cpp
@@ -341,13 +341,12 @@ void TrkServer::handleAdapterMessage(const TrkResult &result)
             if (handleMemoryRequest(addr, len, option, &data)) {
                 writeToAdapter(0x80, result.token, data);
             } else {
-                data[0] =32; // NAK, bad hair day
-                writeToAdapter(0xff, result.token, data);
+                data[0] = 32; // NAK, bad hair day
+                writeToAdapter(0x80, result.token, data);
             }
             break;
         }
         case 0x12: { // Read Registers
-            data.clear();
             for (int i = 0; i < RegisterCount; ++i)
                 appendInt(&data, m_inferior.registers[i], BigEndian);
             writeToAdapter(0x80, result.token, data);
diff --git a/tests/manual/trk/trkutils.cpp b/tests/manual/trk/trkutils.cpp
index 1a1c7345edfab24c5a9885c069a21dea5d552eaa..067687975d1940047ce3c033eda89616fe979552 100644
--- a/tests/manual/trk/trkutils.cpp
+++ b/tests/manual/trk/trkutils.cpp
@@ -115,7 +115,7 @@ TrkResult extractResult(QByteArray *buffer)
     // FIXME: what happens if the length contains 0xfe?
     // Assume for now that it passes unencoded!
     QByteArray data = decode7d(buffer->mid(5, len - 2));
-    *buffer = buffer->mid(4 + len);
+    *buffer->remove(0, 4 + len);
 
     byte sum = 0;
     for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum
@@ -305,5 +305,16 @@ uint swapEndian(uint in)
 {
     return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24);
 }
+
+int TrkResult::errorCode() const
+{
+    // NAK means always error, else data sized 1 with a non-null element
+    const bool isNAK = code == 0xff;
+    if (data.size() != 1 && !isNAK)
+        return 0;
+    if (const int errorCode = data.at(0))
+        return errorCode;
+    return isNAK ? 0xff : 0;
+}
 } // namespace trk
 
diff --git a/tests/manual/trk/trkutils.h b/tests/manual/trk/trkutils.h
index b8066466606b2a7407517c7071b683bc96f2198b..652ef4fe50fb1389b965eea0d9c7358c16c8e14b 100644
--- a/tests/manual/trk/trkutils.h
+++ b/tests/manual/trk/trkutils.h
@@ -173,6 +173,8 @@ struct TrkResult
 {
     TrkResult() { code = token = 0; }
     QString toString() const;
+    // 0 for no error.
+    int errorCode() const;
 
     byte code;
     byte token;