1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
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)
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.
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.
25 # include <sys/socket.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
39 # define socklen_t int
40 # define close closesocket
48 extern void CPUUpdateCPSR();
50 extern void (*dbgMain
)();
51 extern void (*dbgSignal
)(int,int);
52 extern void debuggerMain();
53 extern void debuggerSignal(int,int);
56 int remotePort
= 55555;
58 SOCKET remoteSocket
= -1;
59 SOCKET remoteListenSocket
= -1;
60 bool remoteConnected
= false;
61 bool remoteResumed
= false;
63 int (*remoteSendFnc
)(char *, int) = NULL
;
64 int (*remoteRecvFnc
)(char *, int) = NULL
;
65 bool (*remoteInitFnc
)() = NULL
;
66 void (*remoteCleanUpFnc
)() = NULL
;
69 void remoteSetSockets(SOCKET l
, SOCKET r
)
72 remoteListenSocket
= l
;
76 int remoteTcpSend(char *data
, int len
)
78 return send(remoteSocket
, data
, len
, 0);
81 int remoteTcpRecv(char *data
, int len
)
83 return recv(remoteSocket
, data
, len
, 0);
88 if(remoteSocket
== -1) {
91 int error
= WSAStartup(MAKEWORD(1,1),&wsaData
);
93 SOCKET s
= socket(PF_INET
, SOCK_STREAM
, 0);
95 remoteListenSocket
= s
;
98 fprintf(stderr
,"Error opening socket\n");
102 setsockopt (s
, SOL_SOCKET
, SO_REUSEADDR
, (char *) &tmp
, sizeof (tmp
));
104 // char hostname[256];
105 // gethostname(hostname, 256);
107 // hostent *ent = gethostbyname(hostname);
108 // unsigned long a = *((unsigned long *)ent->h_addr);
111 addr
.sin_family
= AF_INET
;
112 addr
.sin_port
= htons(remotePort
);
113 addr
.sin_addr
.s_addr
= htonl(0);
116 if(bind(s
, (sockaddr
*)&addr
, sizeof(addr
))) {
117 addr
.sin_port
= htons(ntohs(addr
.sin_port
)+1);
122 fprintf(stderr
,"Error binding \n");
126 fprintf(stderr
,"Listening for a connection at port %d\n",
127 ntohs(addr
.sin_port
));
130 fprintf(stderr
, "Error listening\n");
133 socklen_t len
= sizeof(addr
);
137 ioctlsocket(s
, FIONBIO
, (unsigned long *)&flag
);
139 SOCKET s2
= accept(s
, (sockaddr
*)&addr
, &len
);
141 fprintf(stderr
, "Got a connection from %s %d\n",
142 inet_ntoa((in_addr
)addr
.sin_addr
),
143 ntohs(addr
.sin_port
));
146 int error
= WSAGetLastError();
150 recv(s2
, &dummy
, 1, 0);
152 fprintf(stderr
, "ACK not received\n");
161 void remoteTcpCleanUp()
163 if(remoteSocket
> 0) {
164 fprintf(stderr
, "Closing remote socket\n");
168 if(remoteListenSocket
> 0) {
169 fprintf(stderr
, "Closing listen socket\n");
170 close(remoteListenSocket
);
171 remoteListenSocket
= -1;
175 int remotePipeSend(char *data
, int len
)
177 int res
= write(1, data
, len
);
181 int remotePipeRecv(char *data
, int len
)
183 int res
= read(0, data
, len
);
187 bool remotePipeInit()
192 fprintf(stderr
, "ACK not received\n");
199 void remotePipeCleanUp()
203 void remoteSetPort(int port
)
208 void remoteSetProtocol(int p
)
211 remoteSendFnc
= remoteTcpSend
;
212 remoteRecvFnc
= remoteTcpRecv
;
213 remoteInitFnc
= remoteTcpInit
;
214 remoteCleanUpFnc
= remoteTcpCleanUp
;
216 remoteSendFnc
= remotePipeSend
;
217 remoteRecvFnc
= remotePipeRecv
;
218 remoteInitFnc
= remotePipeInit
;
219 remoteCleanUpFnc
= remotePipeCleanUp
;
229 void remotePutPacket(char *packet
)
231 char *hex
= "0123456789abcdef";
234 size_t count
= strlen(packet
);
236 unsigned char csum
= 0;
241 for(size_t i
= 0 ;i
< count
; i
++) {
247 *p
++ = hex
[csum
& 15];
249 // printf("Sending %s\n", buffer);
250 remoteSendFnc(buffer
, (int)count
+ 4);
253 remoteRecvFnc(&c
, 1);
262 #define debuggerReadMemory(addr) \
263 (*(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
265 #define debuggerReadHalfWord(addr) \
266 (*(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
268 #define debuggerReadByte(addr) \
269 map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
271 #define debuggerWriteMemory(addr, value) \
272 *(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
274 #define debuggerWriteHalfWord(addr, value) \
275 *(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
277 #define debuggerWriteByte(addr, value) \
278 map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
280 void remoteOutput(char *s
, u32 addr
)
290 sprintf(d
, "%02x", c
);
295 char c
= debuggerReadByte(addr
);
298 sprintf(d
, "%02x", c
);
300 c
= debuggerReadByte(addr
);
304 remotePutPacket(buffer
);
305 // fprintf(stderr, "Output sent %s\n", buffer);
308 void remoteSendSignal()
311 sprintf(buffer
, "S%02x", remoteSignal
);
312 remotePutPacket(buffer
);
315 void remoteSendStatus()
318 sprintf(buffer
, "T%02x", remoteSignal
);
321 for(int i
= 0; i
< 15; i
++) {
323 sprintf(s
, "%02x:%02x%02x%02x%02x;",i
,
331 sprintf(s
, "0f:%02x%02x%02x%02x;", (v
& 255),
338 sprintf(s
, "19:%02x%02x%02x%02x;", (v
& 255),
344 // printf("Sending %s\n", buffer);
345 remotePutPacket(buffer
);
348 void remoteBinaryWrite(char *p
)
352 sscanf(p
,"%x,%x:", &address
, &count
);
353 // printf("Binary write for %08x %d\n", address, count);
357 for(int i
= 0; i
< count
; i
++) {
362 debuggerWriteByte(address
, (b
^0x20));
366 debuggerWriteByte(address
, b
);
371 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
372 remotePutPacket("OK");
375 void remoteMemoryWrite(char *p
)
379 sscanf(p
,"%x,%x:", &address
, &count
);
380 // printf("Memory write for %08x %d\n", address, count);
384 for(int i
= 0; i
< count
; i
++) {
390 v
= (c
+ 10 - 'a') << 4;
396 debuggerWriteByte(address
, v
);
399 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
400 remotePutPacket("OK");
403 void remoteMemoryRead(char *p
)
407 sscanf(p
,"%x,%x:", &address
, &count
);
408 // printf("Memory read for %08x %d\n", address, count);
413 for(int i
= 0; i
< count
; i
++) {
414 u8 b
= debuggerReadByte(address
);
415 sprintf(s
, "%02x", b
);
420 remotePutPacket(buffer
);
423 void remoteStepOverRange(char *p
)
427 sscanf(p
, "%x,%x", &address
, &final
);
429 remotePutPacket("OK");
431 remoteResumed
= true;
436 } while(armNextPC
>= address
&& armNextPC
< final
);
438 remoteResumed
= false;
443 void remoteWriteWatch(char *p
, bool active
)
447 sscanf(p
, ",%x,%x#", &address
, &count
);
449 fprintf(stderr
, "Write watch for %08x %d\n", address
, count
);
451 if(address
< 0x2000000 || address
> 0x3007fff) {
452 remotePutPacket("E01");
456 if(address
> 0x203ffff && address
< 0x3000000) {
457 remotePutPacket("E01");
461 u32 final
= address
+ count
;
463 if(address
< 0x2040000 && final
> 0x2040000) {
464 remotePutPacket("E01");
466 } else if(address
< 0x3008000 && final
> 0x3008000) {
467 remotePutPacket("E01");
471 for(int i
= 0; i
< count
; i
++) {
472 if((address
>> 24) == 2)
473 freezeWorkRAM
[address
& 0x3ffff] = active
;
475 freezeInternalRAM
[address
& 0x7fff] = active
;
479 remotePutPacket("OK");
482 void remoteReadRegisters(char *p
)
489 for(i
= 0; i
< 15; i
++) {
491 sprintf(s
, "%02x%02x%02x%02x", v
& 255, (v
>> 8) & 255,
492 (v
>> 16) & 255, (v
>> 24) & 255);
497 sprintf(s
, "%02x%02x%02x%02x", pc
& 255, (pc
>> 8) & 255,
498 (pc
>> 16) & 255, (pc
>> 24) & 255);
501 // floating point registers (24-bit)
502 for(i
= 0; i
< 8; i
++) {
503 sprintf(s
, "000000000000000000000000");
507 // FP status register
508 sprintf(s
, "00000000");
513 sprintf(s
, "%02x%02x%02x%02x", v
& 255, (v
>> 8) & 255,
514 (v
>> 16) & 255, (v
>> 24) & 255);
517 remotePutPacket(buffer
);
520 void remoteWriteRegister(char *p
)
524 sscanf(p
, "%x=", &r
);
533 u8 data
[4] = {0,0,0,0};
542 b
= (c
+ 10 - 'a') << 4;
552 v
= data
[0] | (data
[1] << 8) | (data
[2] << 16) | (data
[3] << 24);
554 // printf("Write register %d=%08x\n", r, v);
563 remotePutPacket("OK");
566 extern int emulating
;
568 void remoteStubMain()
575 remoteResumed
= false;
580 int res
= remoteRecvFnc(buffer
, 1024);
583 fprintf(stderr
, "GDB connection lost\n");
585 dbgMain
= debuggerMain
;
586 dbgSignal
= debuggerSignal
;
592 // fprintf(stderr, "Received %s\n", buffer);
596 remoteSendFnc(&pp
, 1);
606 remotePutPacket("OK");
608 dbgMain
= debuggerMain
;
609 dbgSignal
= debuggerSignal
;
611 remoteResumed
= true;
615 remoteStepOverRange(p
);
618 remotePutPacket("OK");
620 dbgMain
= debuggerMain
;
621 dbgSignal
= debuggerSignal
;
627 remoteResumed
= true;
631 remoteResumed
= true;
635 remoteResumed
= true;
639 remoteResumed
= false;
644 remoteReadRegisters(p
);
647 remoteWriteRegister(p
);
650 remoteMemoryWrite(p
);
656 remoteBinaryWrite(p
);
659 remotePutPacket("OK");
666 remoteWriteWatch(p
, true);
672 remoteWriteWatch(p
, false);
678 *(strchr(p
, '#') + 3) = 0;
679 fprintf(stderr
, "Unknown packet %s\n", --p
);
687 void remoteStubSignal(int sig
, int number
)
690 remoteResumed
= false;