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