Mercurial > vba-linux
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 +