home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / remote.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-20  |  14.1 KB  |  699 lines

  1. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
  2. // Copyright (C) 1999-2003 Forgotten
  3. // Copyright (C) 2004 Forgotten and the VBA development team
  4.  
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2, or(at your option)
  8. // any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software Foundation,
  17. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. #ifndef WIN32
  24. # include <unistd.h>
  25. # include <sys/socket.h>
  26. # include <netdb.h>
  27. # ifdef HAVE_NETINET_IN_H
  28. #  include <netinet/in.h>
  29. # endif // HAVE_NETINET_IN_H
  30. # ifdef HAVE_ARPA_INET_H
  31. #  include <arpa/inet.h>
  32. # else // ! HAVE_ARPA_INET_H
  33. #  define socklen_t int
  34. # endif // ! HAVE_ARPA_INET_H
  35. #else // WIN32
  36. # include <winsock.h>
  37. # include <io.h>
  38. # define socklen_t int
  39. # define close closesocket
  40. # define read _read
  41. # define write _write
  42. #endif // WIN32
  43.  
  44. #include "GBA.h"
  45.  
  46. extern bool debugger;
  47. extern void CPUUpdateCPSR();
  48. #ifdef SDL
  49. extern void (*dbgMain)();
  50. extern void (*dbgSignal)(int,int);
  51. extern void debuggerMain();
  52. extern void debuggerSignal(int,int);
  53. #endif
  54.  
  55. int remotePort = 55555;
  56. int remoteSignal = 5;
  57. int remoteSocket = -1;
  58. int remoteListenSocket = -1;
  59. bool remoteConnected = false;
  60. bool remoteResumed = false;
  61.  
  62. int (*remoteSendFnc)(char *, int) = NULL;
  63. int (*remoteRecvFnc)(char *, int) = NULL;
  64. bool (*remoteInitFnc)() = NULL;
  65. void (*remoteCleanUpFnc)() = NULL;
  66.  
  67. #ifndef SDL
  68. void remoteSetSockets(SOCKET l, SOCKET r)
  69. {
  70.   remoteSocket = r;
  71.   remoteListenSocket = l;
  72. }
  73. #endif
  74.  
  75. int remoteTcpSend(char *data, int len)
  76. {
  77.   return send(remoteSocket, data, len, 0);
  78. }
  79.  
  80. int remoteTcpRecv(char *data, int len)
  81. {
  82.   return recv(remoteSocket, data, len, 0);
  83. }
  84.  
  85. bool remoteTcpInit()
  86. {
  87.   if(remoteSocket == -1) {
  88. #ifdef WIN32
  89.     WSADATA wsaData;
  90.     int error = WSAStartup(MAKEWORD(1,1),&wsaData);
  91. #endif // WIN32
  92.     int s = socket(PF_INET, SOCK_STREAM, 0);
  93.     
  94.     remoteListenSocket = s;
  95.     
  96.     if(s < 0) {
  97.       fprintf(stderr,"Error opening socket\n");
  98.       exit(-1);
  99.     }
  100.     int tmp = 1;
  101.     setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));    
  102.     
  103.     //    char hostname[256];
  104.     //    gethostname(hostname, 256);
  105.     
  106.     //    hostent *ent = gethostbyname(hostname);
  107.     //    unsigned long a = *((unsigned long *)ent->h_addr);
  108.     
  109.     sockaddr_in addr;
  110.     addr.sin_family = AF_INET;
  111.     addr.sin_port = htons(remotePort);
  112.     addr.sin_addr.s_addr = htonl(0);
  113.     int count = 0;
  114.     while(count < 3) {
  115.       if(bind(s, (sockaddr *)&addr, sizeof(addr))) {
  116.         addr.sin_port = htons(ntohs(addr.sin_port)+1);
  117.       } else
  118.         break;
  119.     }
  120.     if(count == 3) {
  121.       fprintf(stderr,"Error binding \n");
  122.       exit(-1);
  123.     }
  124.     
  125.     fprintf(stderr,"Listening for a connection at port %d\n",
  126.             ntohs(addr.sin_port));
  127.     
  128.     if(listen(s, 1)) {
  129.       fprintf(stderr, "Error listening\n");
  130.       exit(-1);
  131.     }
  132.     socklen_t len = sizeof(addr);
  133.  
  134. #ifdef WIN32
  135.     int flag = 0;    
  136.     ioctlsocket(s, FIONBIO, (unsigned long *)&flag);
  137. #endif // WIN32
  138.     int s2 = accept(s, (sockaddr *)&addr, &len);
  139.     if(s2 > 0) {
  140.       fprintf(stderr, "Got a connection from %s %d\n",
  141.               inet_ntoa((in_addr)addr.sin_addr),
  142.               ntohs(addr.sin_port));
  143.     } else {
  144. #ifdef WIN32
  145.       int error = WSAGetLastError();
  146. #endif // WIN32
  147.     }
  148.     char dummy;
  149.     recv(s2, &dummy, 1, 0);
  150.     if(dummy != '+') {
  151.       fprintf(stderr, "ACK not received\n");
  152.       exit(-1);
  153.     }
  154.     remoteSocket = s2;
  155.     //    close(s);
  156.   }
  157.   return true;
  158. }
  159.  
  160. void remoteTcpCleanUp()
  161. {
  162.   if(remoteSocket > 0) {
  163.     fprintf(stderr, "Closing remote socket\n");
  164.     close(remoteSocket);
  165.     remoteSocket = -1;
  166.   }
  167.   if(remoteListenSocket > 0) {
  168.     fprintf(stderr, "Closing listen socket\n");    
  169.     close(remoteListenSocket);
  170.     remoteListenSocket = -1;
  171.   }  
  172. }
  173.  
  174. int remotePipeSend(char *data, int len)
  175. {
  176.   int res = write(1, data, len);
  177.   return res;
  178. }
  179.  
  180. int remotePipeRecv(char *data, int len)
  181. {
  182.   int res = read(0, data, len);
  183.   return res;
  184. }
  185.  
  186. bool remotePipeInit()
  187. {
  188.   char dummy;
  189.   read(0, &dummy, 1);
  190.   if(dummy != '+') {
  191.     fprintf(stderr, "ACK not received\n");
  192.     exit(-1);
  193.   }
  194.   
  195.   return true;
  196. }
  197.  
  198. void remotePipeCleanUp()
  199. {
  200. }
  201.  
  202. void remoteSetPort(int port)
  203. {
  204.   remotePort = port;
  205. }
  206.  
  207. void remoteSetProtocol(int p)
  208. {
  209.   if(p == 0) {
  210.     remoteSendFnc = remoteTcpSend;
  211.     remoteRecvFnc = remoteTcpRecv;
  212.     remoteInitFnc = remoteTcpInit;
  213.     remoteCleanUpFnc = remoteTcpCleanUp;
  214.   } else {
  215.     remoteSendFnc = remotePipeSend;
  216.     remoteRecvFnc = remotePipeRecv;
  217.     remoteInitFnc = remotePipeInit;
  218.     remoteCleanUpFnc = remotePipeCleanUp;    
  219.   }
  220. }
  221.  
  222. void remoteInit()
  223. {
  224.   if(remoteInitFnc)
  225.     remoteInitFnc();
  226. }
  227.  
  228. void remotePutPacket(char *packet)
  229. {
  230.   char *hex = "0123456789abcdef";  
  231.   char buffer[1024];
  232.  
  233.   int count = strlen(packet);
  234.  
  235.   unsigned char csum = 0;
  236.  
  237.   char *p = buffer;
  238.   *p++ = '$';
  239.   
  240.   for(int i = 0 ;i < count; i++) {
  241.     csum += packet[i];
  242.     *p++ = packet[i];
  243.   }
  244.   *p++ = '#';
  245.   *p++ = hex[csum>>4];
  246.   *p++ = hex[csum & 15];
  247.   *p++ = 0;
  248.   //  printf("Sending %s\n", buffer);
  249.   remoteSendFnc(buffer, count + 4);
  250.  
  251.   char c = 0;
  252.   remoteRecvFnc(&c, 1);
  253.   /*
  254.   if(c == '+')
  255.     printf("ACK\n");
  256.   else if(c=='-')
  257.     printf("NACK\n");
  258.   */
  259. }
  260.  
  261. #define debuggerReadMemory(addr) \
  262.   (*(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
  263.  
  264. #define debuggerReadHalfWord(addr) \
  265.   (*(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
  266.  
  267. #define debuggerReadByte(addr) \
  268.   map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
  269.  
  270. #define debuggerWriteMemory(addr, value) \
  271.   *(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
  272.  
  273. #define debuggerWriteHalfWord(addr, value) \
  274.   *(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
  275.  
  276. #define debuggerWriteByte(addr, value) \
  277.   map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
  278.  
  279. void remoteOutput(char *s, u32 addr)
  280. {
  281.   char buffer[16384];
  282.  
  283.   char *d = buffer;
  284.   *d++ = 'O';
  285.   
  286.   if(s) {
  287.     char c = *s++;
  288.     while(c) {
  289.       sprintf(d, "%02x", c);
  290.       d += 2;
  291.       c = *s++;
  292.     }
  293.   } else {
  294.     char c= debuggerReadByte(addr);
  295.     addr++;
  296.     while(c) {
  297.       sprintf(d, "%02x", c);
  298.       d += 2;
  299.       c = debuggerReadByte(addr);
  300.       addr++;
  301.     }
  302.   }
  303.   remotePutPacket(buffer);
  304.   //  fprintf(stderr, "Output sent %s\n", buffer);
  305. }
  306.  
  307. void remoteSendSignal()
  308. {
  309.   char buffer[1024];
  310.   sprintf(buffer, "S%02x", remoteSignal);
  311.   remotePutPacket(buffer);
  312. }
  313.  
  314. void remoteSendStatus()
  315. {
  316.   char buffer[1024];
  317.   sprintf(buffer, "T%02x", remoteSignal);
  318.   char *s = buffer;
  319.   s += 3;
  320.   for(int i = 0; i < 15; i++) {
  321.     u32 v = reg[i].I;
  322.     sprintf(s, "%02x:%02x%02x%02x%02x;",i,
  323.             (v & 255),
  324.             (v >> 8) & 255,
  325.             (v >> 16) & 255,
  326.             (v >> 24) & 255);
  327.     s += 12;
  328.   }
  329.   u32 v = armNextPC;
  330.   sprintf(s, "0f:%02x%02x%02x%02x;", (v & 255),
  331.           (v >> 8) & 255,
  332.           (v >> 16) & 255,
  333.           (v >> 24) & 255);
  334.   s += 12;
  335.   CPUUpdateCPSR();
  336.   v = reg[16].I;
  337.   sprintf(s, "19:%02x%02x%02x%02x;", (v & 255),
  338.           (v >> 8) & 255,
  339.           (v >> 16) & 255,
  340.           (v >> 24) & 255);
  341.   s += 12;  
  342.   *s = 0;
  343.   //  printf("Sending %s\n", buffer);
  344.   remotePutPacket(buffer);  
  345. }
  346.  
  347. void remoteBinaryWrite(char *p)
  348. {
  349.   u32 address;
  350.   int count;
  351.   sscanf(p,"%x,%x:", &address, &count);
  352.   //  printf("Binary write for %08x %d\n", address, count);
  353.  
  354.   p = strchr(p, ':');
  355.   p++;
  356.   for(int i = 0; i < count; i++) {
  357.     u8 b = *p++;
  358.     switch(b) {
  359.     case 0x7d:
  360.       b = *p++;
  361.       debuggerWriteByte(address, (b^0x20));
  362.       address++;
  363.       break;
  364.     default:
  365.       debuggerWriteByte(address, b);
  366.       address++;
  367.       break;
  368.     }
  369.   }
  370.   //  printf("ROM is %08x\n", debuggerReadMemory(0x8000254));  
  371.   remotePutPacket("OK");  
  372. }
  373.  
  374. void remoteMemoryWrite(char *p)
  375. {
  376.   u32 address;
  377.   int count;
  378.   sscanf(p,"%x,%x:", &address, &count);
  379.   //  printf("Memory write for %08x %d\n", address, count);
  380.  
  381.   p = strchr(p, ':');
  382.   p++;
  383.   for(int i = 0; i < count; i++) {
  384.     u8 v = 0;
  385.     char c = *p++;
  386.     if(c <= '9')
  387.       v = (c - '0') << 4;
  388.     else
  389.       v = (c + 10 - 'a') << 4;
  390.     c = *p++;
  391.     if(c <= '9')
  392.       v += (c - '0');
  393.     else
  394.       v += (c + 10 - 'a');
  395.     debuggerWriteByte(address, v);
  396.     address++;
  397.   }
  398.   //  printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
  399.   remotePutPacket("OK");  
  400. }
  401.  
  402. void remoteMemoryRead(char *p)
  403. {
  404.   u32 address;
  405.   int count;
  406.   sscanf(p,"%x,%x:", &address, &count);
  407.   //  printf("Memory read for %08x %d\n", address, count);
  408.  
  409.   char buffer[1024];
  410.  
  411.   char *s = buffer;  
  412.   for(int i = 0; i < count; i++) {
  413.     u8 b = debuggerReadByte(address);
  414.     sprintf(s, "%02x", b);
  415.     address++;
  416.     s += 2;
  417.   }
  418.   *s = 0;
  419.   remotePutPacket(buffer);
  420. }
  421.  
  422. void remoteStepOverRange(char *p)
  423. {
  424.   u32 address;
  425.   u32 final;
  426.   sscanf(p, "%x,%x", &address, &final);
  427.  
  428.   remotePutPacket("OK");
  429.  
  430.   remoteResumed = true;
  431.   do {
  432.     CPULoop(1);
  433.     if(debugger)
  434.       break;
  435.   } while(armNextPC >= address && armNextPC < final);
  436.  
  437.   remoteResumed = false;
  438.  
  439.   remoteSendStatus();
  440. }
  441.  
  442. void remoteWriteWatch(char *p, bool active)
  443. {
  444.   u32 address;
  445.   int count;
  446.   sscanf(p, ",%x,%x#", &address, &count);
  447.  
  448.   fprintf(stderr, "Write watch for %08x %d\n", address, count);
  449.  
  450.   if(address < 0x2000000 || address > 0x3007fff) {
  451.     remotePutPacket("E01");
  452.     return;
  453.   }
  454.     
  455.   if(address > 0x203ffff && address < 0x3000000) {
  456.     remotePutPacket("E01");
  457.     return;
  458.   }
  459.   
  460.   u32 final = address + count;
  461.   
  462.   if(address < 0x2040000 && final > 0x2040000) {
  463.     remotePutPacket("E01");
  464.     return;
  465.   } else if(address < 0x3008000 && final > 0x3008000) {
  466.     remotePutPacket("E01");
  467.     return;
  468.   }
  469.  
  470.   for(int i = 0; i < count; i++) {
  471.     if((address >> 24) == 2)
  472.       freezeWorkRAM[address & 0x3ffff] = active;
  473.     else
  474.       freezeInternalRAM[address & 0x7fff] = active;
  475.     address++;
  476.   }  
  477.   
  478.   remotePutPacket("OK");
  479. }
  480.  
  481. void remoteReadRegisters(char *p)
  482. {
  483.   char buffer[1024];
  484.  
  485.   char *s = buffer;
  486.   int i;
  487.   // regular registers
  488.   for(i = 0; i < 15; i++) {
  489.     u32 v = reg[i].I;
  490.     sprintf(s, "%02x%02x%02x%02x",  v & 255, (v >> 8) & 255,
  491.             (v >> 16) & 255, (v >> 24) & 255);
  492.     s += 8;
  493.   }
  494.   // PC
  495.   u32 pc = armNextPC;
  496.   sprintf(s, "%02x%02x%02x%02x", pc & 255, (pc >> 8) & 255,
  497.           (pc >> 16) & 255, (pc >> 24) & 255);
  498.   s += 8;
  499.  
  500.   // floating point registers (24-bit)
  501.   for(i = 0; i < 8; i++) {
  502.     sprintf(s, "000000000000000000000000");
  503.     s += 24;
  504.   }
  505.  
  506.   // FP status register
  507.   sprintf(s, "00000000");
  508.   s += 8;
  509.   // CPSR
  510.   CPUUpdateCPSR();
  511.   u32 v = reg[16].I;
  512.   sprintf(s, "%02x%02x%02x%02x",  v & 255, (v >> 8) & 255,
  513.           (v >> 16) & 255, (v >> 24) & 255);
  514.   s += 8;
  515.   *s = 0;
  516.   remotePutPacket(buffer);
  517. }
  518.  
  519. void remoteWriteRegister(char *p)
  520. {
  521.   int r;
  522.  
  523.   sscanf(p, "%x=", &r);
  524.  
  525.   p = strchr(p, '=');
  526.   p++;
  527.  
  528.   char c = *p++;
  529.  
  530.   u32 v = 0;
  531.  
  532.   u8 data[4] = {0,0,0,0};
  533.   
  534.   int i = 0;
  535.   
  536.   while(c != '#') {
  537.     u8 b = 0;
  538.     if(c <= '9')
  539.       b = (c - '0') << 4;
  540.     else
  541.       b = (c + 10 - 'a') << 4;
  542.     c = *p++;
  543.     if(c <= '9')
  544.       b += (c - '0');
  545.     else
  546.       b += (c + 10 - 'a');
  547.     data[i++] = b;
  548.     c = *p++;
  549.   }
  550.  
  551.   v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
  552.  
  553.   //  printf("Write register %d=%08x\n", r, v);
  554.   reg[r].I = v;
  555.   if(r == 15) {
  556.     armNextPC = v;
  557.     if(armState)
  558.       reg[15].I = v + 4;
  559.     else
  560.       reg[15].I = v + 2;
  561.   }
  562.   remotePutPacket("OK");
  563. }
  564.  
  565. extern int emulating;
  566.  
  567. void remoteStubMain()
  568. {
  569.   if(!debugger)
  570.     return;
  571.  
  572.   if(remoteResumed) {
  573.     remoteSendStatus();
  574.     remoteResumed = false;
  575.   }
  576.   
  577.   while(1) {
  578.     char buffer[1024];
  579.     int res = remoteRecvFnc(buffer, 1024);
  580.     
  581.     if(res == -1) {
  582.       fprintf(stderr, "GDB connection lost\n");
  583. #ifdef SDL
  584.       dbgMain = debuggerMain;
  585.       dbgSignal = debuggerSignal;
  586. #endif
  587.       debugger = false;
  588.       break;
  589.     }
  590.  
  591.     //    fprintf(stderr, "Received %s\n", buffer);
  592.     char *p = buffer;
  593.     char c = *p++;
  594.     char pp = '+';
  595.     remoteSendFnc(&pp, 1);
  596.  
  597.     if(c != '$')
  598.       continue;
  599.     c= *p++;
  600.     switch(c) {
  601.     case '?':
  602.       remoteSendSignal();
  603.       break;
  604.     case 'D':
  605.       remotePutPacket("OK");
  606. #ifdef SDL
  607.       dbgMain = debuggerMain;
  608.       dbgSignal = debuggerSignal;
  609. #endif
  610.       remoteResumed = true;
  611.       debugger = false;
  612.       return;
  613.     case 'e':
  614.       remoteStepOverRange(p);
  615.       break;
  616.     case 'k':
  617.       remotePutPacket("OK");
  618. #ifdef SDL
  619.       dbgMain = debuggerMain;
  620.       dbgSignal = debuggerSignal;
  621. #endif
  622.       debugger = false;
  623.       emulating = false;
  624.       return;
  625.     case 'C':
  626.       remoteResumed = true;
  627.       debugger = false;
  628.       return;
  629.     case 'c':
  630.       remoteResumed = true;
  631.       debugger = false;
  632.       return;
  633.     case 's':
  634.       remoteResumed = true;
  635.       remoteSignal = 5;
  636.       CPULoop(1);
  637.       if(remoteResumed) {
  638.         remoteResumed = false;
  639.         remoteSendStatus();
  640.       }
  641.       break;
  642.     case 'g':
  643.       remoteReadRegisters(p);
  644.       break;
  645.     case 'P':
  646.       remoteWriteRegister(p);
  647.       break;
  648.     case 'M':
  649.       remoteMemoryWrite(p);
  650.       break;
  651.     case 'm':
  652.       remoteMemoryRead(p);
  653.       break;
  654.     case 'X':
  655.       remoteBinaryWrite(p);
  656.       break;
  657.     case 'H':
  658.       remotePutPacket("OK");
  659.       break;
  660.     case 'q':
  661.       remotePutPacket("");
  662.       break;
  663.     case 'Z':
  664.       if(*p++ == '2') {
  665.         remoteWriteWatch(p, true);
  666.       } else
  667.         remotePutPacket("");
  668.       break;
  669.     case 'z':
  670.       if(*p++ == '2') {
  671.     remoteWriteWatch(p, false);
  672.       } else
  673.     remotePutPacket("");
  674.       break;
  675.     default:
  676.       {
  677.         *(strchr(p, '#') + 3) = 0;      
  678.         fprintf(stderr, "Unknown packet %s\n", --p);
  679.         remotePutPacket("");
  680.       }
  681.       break;
  682.     }
  683.   }    
  684. }
  685.  
  686. void remoteStubSignal(int sig, int number)
  687. {
  688.   remoteSignal = sig;
  689.   remoteResumed = false;
  690.   remoteSendStatus();
  691.   debugger = true;
  692. }
  693.  
  694. void remoteCleanUp()
  695. {
  696.   if(remoteCleanUpFnc)
  697.     remoteCleanUpFnc();
  698. }
  699.