diff src/gba/remote.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children ecd30c5e2f5a
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gba/remote.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,712 @@
     1.4 +#include <cstdlib>
     1.5 +#include <cstdio>
     1.6 +#include <cstring>
     1.7 +
     1.8 +#ifndef WIN32
     1.9 +# include <unistd.h>
    1.10 +# include <sys/socket.h>
    1.11 +# include <netdb.h>
    1.12 +# ifdef HAVE_NETINET_IN_H
    1.13 +#  include <netinet/in.h>
    1.14 +# endif // HAVE_NETINET_IN_H
    1.15 +# ifdef HAVE_ARPA_INET_H
    1.16 +#  include <arpa/inet.h>
    1.17 +# else // ! HAVE_ARPA_INET_H
    1.18 +#  define socklen_t int
    1.19 +# endif // ! HAVE_ARPA_INET_H
    1.20 +#else // WIN32
    1.21 +# include "../win32/stdafx.h"
    1.22 +# include <winsock.h>
    1.23 +# include <io.h>
    1.24 +# define socklen_t int
    1.25 +# define close closesocket
    1.26 +# define read _read
    1.27 +# define write _write
    1.28 +#endif // WIN32
    1.29 +
    1.30 +#include "GBA.h"
    1.31 +#include "GBAGlobals.h"
    1.32 +
    1.33 +extern bool debugger;
    1.34 +extern void CPUUpdateCPSR();
    1.35 +#ifdef SDL
    1.36 +extern void (*dbgMain)();
    1.37 +extern void (*dbgSignal)(int, int);
    1.38 +extern void debuggerMain();
    1.39 +extern void debuggerSignal(int, int);
    1.40 +#endif
    1.41 +
    1.42 +int  remotePort         = 55555;
    1.43 +int  remoteSignal       = 5;
    1.44 +int  remoteSocket       = -1;
    1.45 +int  remoteListenSocket = -1;
    1.46 +bool remoteConnected    = false;
    1.47 +bool remoteResumed      = false;
    1.48 +
    1.49 +int  (*remoteSendFnc)(char *, int) = NULL;
    1.50 +int  (*remoteRecvFnc)(char *, int) = NULL;
    1.51 +bool (*remoteInitFnc)()    = NULL;
    1.52 +void (*remoteCleanUpFnc)() = NULL;
    1.53 +
    1.54 +#if (defined WIN32 && !defined SDL)
    1.55 +void remoteSetSockets(SOCKET l, SOCKET r)
    1.56 +{
    1.57 +	remoteSocket       = r;
    1.58 +	remoteListenSocket = l;
    1.59 +}
    1.60 +
    1.61 +#endif
    1.62 +
    1.63 +int remoteTcpSend(char *data, int len)
    1.64 +{
    1.65 +	return send(remoteSocket, data, len, 0);
    1.66 +}
    1.67 +
    1.68 +int remoteTcpRecv(char *data, int len)
    1.69 +{
    1.70 +	return recv(remoteSocket, data, len, 0);
    1.71 +}
    1.72 +
    1.73 +bool remoteTcpInit()
    1.74 +{
    1.75 +	if (remoteSocket == -1)
    1.76 +	{
    1.77 +#ifdef WIN32
    1.78 +		WSADATA wsaData;
    1.79 +		int     error = WSAStartup(MAKEWORD(1, 1), &wsaData);
    1.80 +#endif // WIN32
    1.81 +		int s = socket(PF_INET, SOCK_STREAM, 0);
    1.82 +
    1.83 +		remoteListenSocket = s;
    1.84 +
    1.85 +		if (s < 0)
    1.86 +		{
    1.87 +			fprintf(stderr, "Error opening socket\n");
    1.88 +			exit(-1);
    1.89 +		}
    1.90 +		int tmp = 1;
    1.91 +		setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof(tmp));
    1.92 +
    1.93 +		//    char hostname[256];
    1.94 +		//    gethostname(hostname, 256);
    1.95 +
    1.96 +		//    hostent *ent = gethostbyname(hostname);
    1.97 +		//    unsigned long a = *((unsigned long *)ent->h_addr);
    1.98 +
    1.99 +		sockaddr_in addr;
   1.100 +		addr.sin_family      = AF_INET;
   1.101 +		addr.sin_port        = htons(remotePort);
   1.102 +		addr.sin_addr.s_addr = htonl(0);
   1.103 +		int count = 0;
   1.104 +		while (count < 3)
   1.105 +		{
   1.106 +			if (bind(s, (sockaddr *)&addr, sizeof(addr)))
   1.107 +			{
   1.108 +				addr.sin_port = htons(ntohs(addr.sin_port)+1);
   1.109 +			}
   1.110 +			else
   1.111 +				break;
   1.112 +		}
   1.113 +		if (count == 3)
   1.114 +		{
   1.115 +			fprintf(stderr, "Error binding \n");
   1.116 +			exit(-1);
   1.117 +		}
   1.118 +
   1.119 +		fprintf(stderr, "Listening for a connection at port %d\n",
   1.120 +		        ntohs(addr.sin_port));
   1.121 +
   1.122 +		if (listen(s, 1))
   1.123 +		{
   1.124 +			fprintf(stderr, "Error listening\n");
   1.125 +			exit(-1);
   1.126 +		}
   1.127 +		socklen_t len = sizeof(addr);
   1.128 +
   1.129 +#ifdef WIN32
   1.130 +		int flag = 0;
   1.131 +		ioctlsocket(s, FIONBIO, (unsigned long *)&flag);
   1.132 +#endif // WIN32
   1.133 +		int s2 = accept(s, (sockaddr *)&addr, &len);
   1.134 +		if (s2 > 0)
   1.135 +		{
   1.136 +			fprintf(stderr, "Got a connection from %s %d\n",
   1.137 +			        inet_ntoa((in_addr)addr.sin_addr),
   1.138 +			        ntohs(addr.sin_port));
   1.139 +		}
   1.140 +		else
   1.141 +		{
   1.142 +#ifdef WIN32
   1.143 +			int error = WSAGetLastError();
   1.144 +#endif // WIN32
   1.145 +		}
   1.146 +		char dummy;
   1.147 +		recv(s2, &dummy, 1, 0);
   1.148 +		if (dummy != '+')
   1.149 +		{
   1.150 +			fprintf(stderr, "ACK not received\n");
   1.151 +			exit(-1);
   1.152 +		}
   1.153 +		remoteSocket = s2;
   1.154 +		//    close(s);
   1.155 +	}
   1.156 +	return true;
   1.157 +}
   1.158 +
   1.159 +void remoteTcpCleanUp()
   1.160 +{
   1.161 +	if (remoteSocket > 0)
   1.162 +	{
   1.163 +		fprintf(stderr, "Closing remote socket\n");
   1.164 +		close(remoteSocket);
   1.165 +		remoteSocket = -1;
   1.166 +	}
   1.167 +	if (remoteListenSocket > 0)
   1.168 +	{
   1.169 +		fprintf(stderr, "Closing listen socket\n");
   1.170 +		close(remoteListenSocket);
   1.171 +		remoteListenSocket = -1;
   1.172 +	}
   1.173 +}
   1.174 +
   1.175 +int remotePipeSend(char *data, int len)
   1.176 +{
   1.177 +	int res = write(1, data, len);
   1.178 +	return res;
   1.179 +}
   1.180 +
   1.181 +int remotePipeRecv(char *data, int len)
   1.182 +{
   1.183 +	int res = read(0, data, len);
   1.184 +	return res;
   1.185 +}
   1.186 +
   1.187 +bool remotePipeInit()
   1.188 +{
   1.189 +	char dummy;
   1.190 +	read(0, &dummy, 1);
   1.191 +	if (dummy != '+')
   1.192 +	{
   1.193 +		fprintf(stderr, "ACK not received\n");
   1.194 +		exit(-1);
   1.195 +	}
   1.196 +
   1.197 +	return true;
   1.198 +}
   1.199 +
   1.200 +void remotePipeCleanUp()
   1.201 +{}
   1.202 +
   1.203 +void remoteSetPort(int port)
   1.204 +{
   1.205 +	remotePort = port;
   1.206 +}
   1.207 +
   1.208 +void remoteSetProtocol(int p)
   1.209 +{
   1.210 +	if (p == 0)
   1.211 +	{
   1.212 +		remoteSendFnc    = remoteTcpSend;
   1.213 +		remoteRecvFnc    = remoteTcpRecv;
   1.214 +		remoteInitFnc    = remoteTcpInit;
   1.215 +		remoteCleanUpFnc = remoteTcpCleanUp;
   1.216 +	}
   1.217 +	else
   1.218 +	{
   1.219 +		remoteSendFnc    = remotePipeSend;
   1.220 +		remoteRecvFnc    = remotePipeRecv;
   1.221 +		remoteInitFnc    = remotePipeInit;
   1.222 +		remoteCleanUpFnc = remotePipeCleanUp;
   1.223 +	}
   1.224 +}
   1.225 +
   1.226 +void remoteInit()
   1.227 +{
   1.228 +	if (remoteInitFnc)
   1.229 +		remoteInitFnc();
   1.230 +}
   1.231 +
   1.232 +void remotePutPacket(char *packet)
   1.233 +{
   1.234 +	char *hex = "0123456789abcdef";
   1.235 +	char  buffer[1024];
   1.236 +
   1.237 +	int count = strlen(packet);
   1.238 +
   1.239 +	unsigned char csum = 0;
   1.240 +
   1.241 +	char *p = buffer;
   1.242 +	*p++ = '$';
   1.243 +
   1.244 +	for (int i = 0; i < count; i++)
   1.245 +	{
   1.246 +		csum += packet[i];
   1.247 +		*p++  = packet[i];
   1.248 +	}
   1.249 +	*p++ = '#';
   1.250 +	*p++ = hex[csum>>4];
   1.251 +	*p++ = hex[csum & 15];
   1.252 +	*p++ = 0;
   1.253 +	//  printf("Sending %s\n", buffer);
   1.254 +	remoteSendFnc(buffer, count + 4);
   1.255 +
   1.256 +	char c = 0;
   1.257 +	remoteRecvFnc(&c, 1);
   1.258 +	/*
   1.259 +	   if(c == '+')
   1.260 +	   printf("ACK\n");
   1.261 +	   else if(c=='-')
   1.262 +	   printf("NACK\n");
   1.263 +	 */
   1.264 +}
   1.265 +
   1.266 +void remoteOutput(char *s, u32 addr)
   1.267 +{
   1.268 +	char buffer[16384];
   1.269 +
   1.270 +	char *d = buffer;
   1.271 +	*d++ = 'O';
   1.272 +
   1.273 +	if (s)
   1.274 +	{
   1.275 +		char c = *s++;
   1.276 +		while (c)
   1.277 +		{
   1.278 +			sprintf(d, "%02x", c);
   1.279 +			d += 2;
   1.280 +			c  = *s++;
   1.281 +		}
   1.282 +	}
   1.283 +	else
   1.284 +	{
   1.285 +		char c = debuggerReadByte(addr);
   1.286 +		addr++;
   1.287 +		while (c)
   1.288 +		{
   1.289 +			sprintf(d, "%02x", c);
   1.290 +			d += 2;
   1.291 +			c  = debuggerReadByte(addr);
   1.292 +			addr++;
   1.293 +		}
   1.294 +	}
   1.295 +	remotePutPacket(buffer);
   1.296 +	//  fprintf(stderr, "Output sent %s\n", buffer);
   1.297 +}
   1.298 +
   1.299 +void remoteSendSignal()
   1.300 +{
   1.301 +	char buffer[1024];
   1.302 +	sprintf(buffer, "S%02x", remoteSignal);
   1.303 +	remotePutPacket(buffer);
   1.304 +}
   1.305 +
   1.306 +void remoteSendStatus()
   1.307 +{
   1.308 +	char buffer[1024];
   1.309 +	sprintf(buffer, "T%02x", remoteSignal);
   1.310 +	char *s = buffer;
   1.311 +	s += 3;
   1.312 +	for (int i = 0; i < 15; i++)
   1.313 +	{
   1.314 +		u32 v = reg[i].I;
   1.315 +		sprintf(s, "%02x:%02x%02x%02x%02x;", i,
   1.316 +		        (v & 255),
   1.317 +		        (v >> 8) & 255,
   1.318 +		        (v >> 16) & 255,
   1.319 +		        (v >> 24) & 255);
   1.320 +		s += 12;
   1.321 +	}
   1.322 +	u32 v = armNextPC;
   1.323 +	sprintf(s, "0f:%02x%02x%02x%02x;", (v & 255),
   1.324 +	        (v >> 8) & 255,
   1.325 +	        (v >> 16) & 255,
   1.326 +	        (v >> 24) & 255);
   1.327 +	s += 12;
   1.328 +	CPUUpdateCPSR();
   1.329 +	v = reg[16].I;
   1.330 +	sprintf(s, "19:%02x%02x%02x%02x;", (v & 255),
   1.331 +	        (v >> 8) & 255,
   1.332 +	        (v >> 16) & 255,
   1.333 +	        (v >> 24) & 255);
   1.334 +	s += 12;
   1.335 +	*s = 0;
   1.336 +	//  printf("Sending %s\n", buffer);
   1.337 +	remotePutPacket(buffer);
   1.338 +}
   1.339 +
   1.340 +void remoteBinaryWrite(char *p)
   1.341 +{
   1.342 +	u32 address;
   1.343 +	int count;
   1.344 +	sscanf(p, "%x,%x:", &address, &count);
   1.345 +	//  printf("Binary write for %08x %d\n", address, count);
   1.346 +
   1.347 +	p = strchr(p, ':');
   1.348 +	p++;
   1.349 +	for (int i = 0; i < count; i++)
   1.350 +	{
   1.351 +		u8 b = *p++;
   1.352 +		switch (b)
   1.353 +		{
   1.354 +		case 0x7d:
   1.355 +			b = *p++;
   1.356 +			debuggerWriteByte(address, (b^0x20));
   1.357 +			address++;
   1.358 +			break;
   1.359 +		default:
   1.360 +			debuggerWriteByte(address, b);
   1.361 +			address++;
   1.362 +			break;
   1.363 +		}
   1.364 +	}
   1.365 +	//  printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
   1.366 +	remotePutPacket("OK");
   1.367 +}
   1.368 +
   1.369 +void remoteMemoryWrite(char *p)
   1.370 +{
   1.371 +	u32 address;
   1.372 +	int count;
   1.373 +	sscanf(p, "%x,%x:", &address, &count);
   1.374 +	//  printf("Memory write for %08x %d\n", address, count);
   1.375 +
   1.376 +	p = strchr(p, ':');
   1.377 +	p++;
   1.378 +	for (int i = 0; i < count; i++)
   1.379 +	{
   1.380 +		u8   v = 0;
   1.381 +		char c = *p++;
   1.382 +		if (c <= '9')
   1.383 +			v = (c - '0') << 4;
   1.384 +		else
   1.385 +			v = (c + 10 - 'a') << 4;
   1.386 +		c = *p++;
   1.387 +		if (c <= '9')
   1.388 +			v += (c - '0');
   1.389 +		else
   1.390 +			v += (c + 10 - 'a');
   1.391 +		debuggerWriteByte(address, v);
   1.392 +		address++;
   1.393 +	}
   1.394 +	//  printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
   1.395 +	remotePutPacket("OK");
   1.396 +}
   1.397 +
   1.398 +void remoteMemoryRead(char *p)
   1.399 +{
   1.400 +	u32 address;
   1.401 +	int count;
   1.402 +	sscanf(p, "%x,%x:", &address, &count);
   1.403 +	//  printf("Memory read for %08x %d\n", address, count);
   1.404 +
   1.405 +	char buffer[1024];
   1.406 +
   1.407 +	char *s = buffer;
   1.408 +	for (int i = 0; i < count; i++)
   1.409 +	{
   1.410 +		u8 b = debuggerReadByte(address);
   1.411 +		sprintf(s, "%02x", b);
   1.412 +		address++;
   1.413 +		s += 2;
   1.414 +	}
   1.415 +	*s = 0;
   1.416 +	remotePutPacket(buffer);
   1.417 +}
   1.418 +
   1.419 +void remoteStepOverRange(char *p)
   1.420 +{
   1.421 +	u32 address;
   1.422 +	u32 final;
   1.423 +	sscanf(p, "%x,%x", &address, &final);
   1.424 +
   1.425 +	remotePutPacket("OK");
   1.426 +
   1.427 +	remoteResumed = true;
   1.428 +	do
   1.429 +	{
   1.430 +		CPULoop(1);
   1.431 +		if (debugger)
   1.432 +			break;
   1.433 +	}
   1.434 +	while (armNextPC >= address && armNextPC < final);
   1.435 +
   1.436 +	remoteResumed = false;
   1.437 +
   1.438 +	remoteSendStatus();
   1.439 +}
   1.440 +
   1.441 +void remoteWriteWatch(char *p, bool active)
   1.442 +{
   1.443 +	u32 address;
   1.444 +	int count;
   1.445 +	sscanf(p, ",%x,%x#", &address, &count);
   1.446 +
   1.447 +	fprintf(stderr, "Write watch for %08x %d\n", address, count);
   1.448 +
   1.449 +	if (address < 0x2000000 || address > 0x3007fff)
   1.450 +	{
   1.451 +		remotePutPacket("E01");
   1.452 +		return;
   1.453 +	}
   1.454 +
   1.455 +	if (address > 0x203ffff && address < 0x3000000)
   1.456 +	{
   1.457 +		remotePutPacket("E01");
   1.458 +		return;
   1.459 +	}
   1.460 +
   1.461 +	u32 final = address + count;
   1.462 +
   1.463 +	if (address < 0x2040000 && final > 0x2040000)
   1.464 +	{
   1.465 +		remotePutPacket("E01");
   1.466 +		return;
   1.467 +	}
   1.468 +	else if (address < 0x3008000 && final > 0x3008000)
   1.469 +	{
   1.470 +		remotePutPacket("E01");
   1.471 +		return;
   1.472 +	}
   1.473 +
   1.474 +	for (int i = 0; i < count; i++)
   1.475 +	{
   1.476 +		if ((address >> 24) == 2)
   1.477 +			freezeWorkRAM[address & 0x3ffff] = active;
   1.478 +		else
   1.479 +			freezeInternalRAM[address & 0x7fff] = active;
   1.480 +		address++;
   1.481 +	}
   1.482 +
   1.483 +	remotePutPacket("OK");
   1.484 +}
   1.485 +
   1.486 +void remoteReadRegisters(char *p)
   1.487 +{
   1.488 +	char buffer[1024];
   1.489 +
   1.490 +	char *s = buffer;
   1.491 +	int   i;
   1.492 +	// regular registers
   1.493 +	for (i = 0; i < 15; i++)
   1.494 +	{
   1.495 +		u32 v = reg[i].I;
   1.496 +		sprintf(s, "%02x%02x%02x%02x",  v & 255, (v >> 8) & 255,
   1.497 +		        (v >> 16) & 255, (v >> 24) & 255);
   1.498 +		s += 8;
   1.499 +	}
   1.500 +	// PC
   1.501 +	u32 pc = armNextPC;
   1.502 +	sprintf(s, "%02x%02x%02x%02x", pc & 255, (pc >> 8) & 255,
   1.503 +	        (pc >> 16) & 255, (pc >> 24) & 255);
   1.504 +	s += 8;
   1.505 +
   1.506 +	// floating point registers (24-bit)
   1.507 +	for (i = 0; i < 8; i++)
   1.508 +	{
   1.509 +		sprintf(s, "000000000000000000000000");
   1.510 +		s += 24;
   1.511 +	}
   1.512 +
   1.513 +	// FP status register
   1.514 +	sprintf(s, "00000000");
   1.515 +	s += 8;
   1.516 +	// CPSR
   1.517 +	CPUUpdateCPSR();
   1.518 +	u32 v = reg[16].I;
   1.519 +	sprintf(s, "%02x%02x%02x%02x",  v & 255, (v >> 8) & 255,
   1.520 +	        (v >> 16) & 255, (v >> 24) & 255);
   1.521 +	s += 8;
   1.522 +	*s = 0;
   1.523 +	remotePutPacket(buffer);
   1.524 +}
   1.525 +
   1.526 +void remoteWriteRegister(char *p)
   1.527 +{
   1.528 +	int r;
   1.529 +
   1.530 +	sscanf(p, "%x=", &r);
   1.531 +
   1.532 +	p = strchr(p, '=');
   1.533 +	p++;
   1.534 +
   1.535 +	char c = *p++;
   1.536 +
   1.537 +	u32 v = 0;
   1.538 +
   1.539 +	u8 data[4] = {0, 0, 0, 0};
   1.540 +
   1.541 +	int i = 0;
   1.542 +
   1.543 +	while (c != '#')
   1.544 +	{
   1.545 +		u8 b = 0;
   1.546 +		if (c <= '9')
   1.547 +			b = (c - '0') << 4;
   1.548 +		else
   1.549 +			b = (c + 10 - 'a') << 4;
   1.550 +		c = *p++;
   1.551 +		if (c <= '9')
   1.552 +			b += (c - '0');
   1.553 +		else
   1.554 +			b += (c + 10 - 'a');
   1.555 +		data[i++] = b;
   1.556 +		c         = *p++;
   1.557 +	}
   1.558 +
   1.559 +	v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
   1.560 +
   1.561 +	//  printf("Write register %d=%08x\n", r, v);
   1.562 +	reg[r].I = v;
   1.563 +	if (r == 15)
   1.564 +	{
   1.565 +		armNextPC = v;
   1.566 +		if (armState)
   1.567 +			reg[15].I = v + 4;
   1.568 +		else
   1.569 +			reg[15].I = v + 2;
   1.570 +	}
   1.571 +	remotePutPacket("OK");
   1.572 +}
   1.573 +
   1.574 +void remoteStubMain()
   1.575 +{
   1.576 +	if (!debugger)
   1.577 +		return;
   1.578 +
   1.579 +	if (remoteResumed)
   1.580 +	{
   1.581 +		remoteSendStatus();
   1.582 +		remoteResumed = false;
   1.583 +	}
   1.584 +
   1.585 +	while (true)
   1.586 +	{
   1.587 +		char buffer[1024];
   1.588 +		int  res = remoteRecvFnc(buffer, 1024);
   1.589 +
   1.590 +		if (res == -1)
   1.591 +		{
   1.592 +			fprintf(stderr, "GDB connection lost\n");
   1.593 +#ifdef SDL
   1.594 +			dbgMain   = debuggerMain;
   1.595 +			dbgSignal = debuggerSignal;
   1.596 +#endif
   1.597 +			debugger = false;
   1.598 +			break;
   1.599 +		}
   1.600 +
   1.601 +		//    fprintf(stderr, "Received %s\n", buffer);
   1.602 +		char *p  = buffer;
   1.603 +		char  c  = *p++;
   1.604 +		char  pp = '+';
   1.605 +		remoteSendFnc(&pp, 1);
   1.606 +
   1.607 +		if (c != '$')
   1.608 +			continue;
   1.609 +		c = *p++;
   1.610 +		switch (c)
   1.611 +		{
   1.612 +		case '?':
   1.613 +			remoteSendSignal();
   1.614 +			break;
   1.615 +		case 'D':
   1.616 +			remotePutPacket("OK");
   1.617 +#ifdef SDL
   1.618 +			dbgMain   = debuggerMain;
   1.619 +			dbgSignal = debuggerSignal;
   1.620 +#endif
   1.621 +			remoteResumed = true;
   1.622 +			debugger      = false;
   1.623 +			return;
   1.624 +		case 'e':
   1.625 +			remoteStepOverRange(p);
   1.626 +			break;
   1.627 +		case 'k':
   1.628 +			remotePutPacket("OK");
   1.629 +#ifdef SDL
   1.630 +			dbgMain   = debuggerMain;
   1.631 +			dbgSignal = debuggerSignal;
   1.632 +#endif
   1.633 +			debugger  = false;
   1.634 +			emulating = false;
   1.635 +			return;
   1.636 +		case 'C':
   1.637 +			remoteResumed = true;
   1.638 +			debugger      = false;
   1.639 +			return;
   1.640 +		case 'c':
   1.641 +			remoteResumed = true;
   1.642 +			debugger      = false;
   1.643 +			return;
   1.644 +		case 's':
   1.645 +			remoteResumed = true;
   1.646 +			remoteSignal  = 5;
   1.647 +			CPULoop(1);
   1.648 +			if (remoteResumed)
   1.649 +			{
   1.650 +				remoteResumed = false;
   1.651 +				remoteSendStatus();
   1.652 +			}
   1.653 +			break;
   1.654 +		case 'g':
   1.655 +			remoteReadRegisters(p);
   1.656 +			break;
   1.657 +		case 'P':
   1.658 +			remoteWriteRegister(p);
   1.659 +			break;
   1.660 +		case 'M':
   1.661 +			remoteMemoryWrite(p);
   1.662 +			break;
   1.663 +		case 'm':
   1.664 +			remoteMemoryRead(p);
   1.665 +			break;
   1.666 +		case 'X':
   1.667 +			remoteBinaryWrite(p);
   1.668 +			break;
   1.669 +		case 'H':
   1.670 +			remotePutPacket("OK");
   1.671 +			break;
   1.672 +		case 'q':
   1.673 +			remotePutPacket("");
   1.674 +			break;
   1.675 +		case 'Z':
   1.676 +			if (*p++ == '2')
   1.677 +			{
   1.678 +				remoteWriteWatch(p, true);
   1.679 +			}
   1.680 +			else
   1.681 +				remotePutPacket("");
   1.682 +			break;
   1.683 +		case 'z':
   1.684 +			if (*p++ == '2')
   1.685 +			{
   1.686 +				remoteWriteWatch(p, false);
   1.687 +			}
   1.688 +			else
   1.689 +				remotePutPacket("");
   1.690 +			break;
   1.691 +		default:
   1.692 +		{
   1.693 +			*(strchr(p, '#') + 3) = 0;
   1.694 +			fprintf(stderr, "Unknown packet %s\n", --p);
   1.695 +			remotePutPacket("");
   1.696 +			break;
   1.697 +		}
   1.698 +		}
   1.699 +	}
   1.700 +}
   1.701 +
   1.702 +void remoteStubSignal(int sig, int number)
   1.703 +{
   1.704 +	remoteSignal  = sig;
   1.705 +	remoteResumed = false;
   1.706 +	remoteSendStatus();
   1.707 +	debugger = true;
   1.708 +}
   1.709 +
   1.710 +void remoteCleanUp()
   1.711 +{
   1.712 +	if (remoteCleanUpFnc)
   1.713 +		remoteCleanUpFnc();
   1.714 +}
   1.715 +