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 # include <netinet/in.h>
28 # include <arpa/inet.h>
33 # define socklen_t int
34 # define close closesocket
42 extern void CPUUpdateCPSR();
44 extern void (*dbgMain
)();
45 extern void (*dbgSignal
)(int,int);
46 extern void debuggerMain();
47 extern void debuggerSignal(int,int);
50 int remotePort
= 55555;
52 SOCKET remoteSocket
= -1;
53 SOCKET remoteListenSocket
= -1;
54 bool remoteConnected
= false;
55 bool remoteResumed
= false;
57 int (*remoteSendFnc
)(char *, int) = NULL
;
58 int (*remoteRecvFnc
)(char *, int) = NULL
;
59 bool (*remoteInitFnc
)() = NULL
;
60 void (*remoteCleanUpFnc
)() = NULL
;
63 void remoteSetSockets(SOCKET l
, SOCKET r
)
66 remoteListenSocket
= l
;
70 int remoteTcpSend(char *data
, int len
)
72 return send(remoteSocket
, data
, len
, 0);
75 int remoteTcpRecv(char *data
, int len
)
77 return recv(remoteSocket
, data
, len
, 0);
82 if(remoteSocket
== -1) {
85 int error
= WSAStartup(MAKEWORD(1,1),&wsaData
);
87 SOCKET s
= socket(PF_INET
, SOCK_STREAM
, 0);
89 remoteListenSocket
= s
;
92 fprintf(stderr
,"Error opening socket\n");
96 setsockopt (s
, SOL_SOCKET
, SO_REUSEADDR
, (char *) &tmp
, sizeof (tmp
));
98 // char hostname[256];
99 // gethostname(hostname, 256);
101 // hostent *ent = gethostbyname(hostname);
102 // unsigned long a = *((unsigned long *)ent->h_addr);
104 struct sockaddr_in addr
;
105 addr
.sin_family
= AF_INET
;
106 addr
.sin_port
= htons(remotePort
);
107 addr
.sin_addr
.s_addr
= htonl(0);
110 if(bind(s
, (struct sockaddr
*)&addr
, sizeof(addr
))) {
111 addr
.sin_port
= htons(ntohs(addr
.sin_port
)+1);
116 fprintf(stderr
,"Error binding \n");
120 fprintf(stderr
,"Listening for a connection at port %d\n",
121 ntohs(addr
.sin_port
));
124 fprintf(stderr
, "Error listening\n");
127 socklen_t len
= sizeof(addr
);
131 ioctlsocket(s
, FIONBIO
, (unsigned long *)&flag
);
133 SOCKET s2
= accept(s
, (struct sockaddr
*)&addr
, &len
);
135 fprintf(stderr
, "Got a connection from %s %d\n",
136 inet_ntoa((struct in_addr
)addr
.sin_addr
),
137 ntohs(addr
.sin_port
));
140 int error
= WSAGetLastError();
144 recv(s2
, &dummy
, 1, 0);
146 fprintf(stderr
, "ACK not received\n");
155 void remoteTcpCleanUp()
157 if(remoteSocket
> 0) {
158 fprintf(stderr
, "Closing remote socket\n");
162 if(remoteListenSocket
> 0) {
163 fprintf(stderr
, "Closing listen socket\n");
164 close(remoteListenSocket
);
165 remoteListenSocket
= -1;
169 int remotePipeSend(char *data
, int len
)
171 int res
= write(1, data
, len
);
175 int remotePipeRecv(char *data
, int len
)
177 int res
= read(0, data
, len
);
181 bool remotePipeInit()
186 fprintf(stderr
, "ACK not received\n");
193 void remotePipeCleanUp()
197 void remoteSetPort(int port
)
202 void remoteSetProtocol(int p
)
205 remoteSendFnc
= remoteTcpSend
;
206 remoteRecvFnc
= remoteTcpRecv
;
207 remoteInitFnc
= remoteTcpInit
;
208 remoteCleanUpFnc
= remoteTcpCleanUp
;
210 remoteSendFnc
= remotePipeSend
;
211 remoteRecvFnc
= remotePipeRecv
;
212 remoteInitFnc
= remotePipeInit
;
213 remoteCleanUpFnc
= remotePipeCleanUp
;
223 void remotePutPacket(char *packet
)
225 char *hex
= "0123456789abcdef";
228 size_t count
= strlen(packet
);
230 unsigned char csum
= 0;
235 for(size_t i
= 0 ;i
< count
; i
++) {
241 *p
++ = hex
[csum
& 15];
243 // printf("Sending %s\n", buffer);
244 remoteSendFnc(buffer
, (int)count
+ 4);
247 remoteRecvFnc(&c
, 1);
256 #define debuggerReadMemory(addr) \
257 (*(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
259 #define debuggerReadHalfWord(addr) \
260 (*(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])
262 #define debuggerReadByte(addr) \
263 map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
265 #define debuggerWriteMemory(addr, value) \
266 *(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
268 #define debuggerWriteHalfWord(addr, value) \
269 *(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
271 #define debuggerWriteByte(addr, value) \
272 map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
274 void remoteOutput(char *s
, u32 addr
)
284 sprintf(d
, "%02x", c
);
289 char c
= debuggerReadByte(addr
);
292 sprintf(d
, "%02x", c
);
294 c
= debuggerReadByte(addr
);
298 remotePutPacket(buffer
);
299 // fprintf(stderr, "Output sent %s\n", buffer);
302 void remoteSendSignal()
305 sprintf(buffer
, "S%02x", remoteSignal
);
306 remotePutPacket(buffer
);
309 void remoteSendStatus()
312 sprintf(buffer
, "T%02x", remoteSignal
);
315 for(int i
= 0; i
< 15; i
++) {
317 sprintf(s
, "%02x:%02x%02x%02x%02x;",i
,
325 sprintf(s
, "0f:%02x%02x%02x%02x;", (v
& 255),
332 sprintf(s
, "19:%02x%02x%02x%02x;", (v
& 255),
338 // printf("Sending %s\n", buffer);
339 remotePutPacket(buffer
);
342 void remoteBinaryWrite(char *p
)
346 sscanf(p
,"%x,%x:", &address
, &count
);
347 // printf("Binary write for %08x %d\n", address, count);
351 for(int i
= 0; i
< count
; i
++) {
356 debuggerWriteByte(address
, (b
^0x20));
360 debuggerWriteByte(address
, b
);
365 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
366 remotePutPacket("OK");
369 void remoteMemoryWrite(char *p
)
373 sscanf(p
,"%x,%x:", &address
, &count
);
374 // printf("Memory write for %08x %d\n", address, count);
378 for(int i
= 0; i
< count
; i
++) {
384 v
= (c
+ 10 - 'a') << 4;
390 debuggerWriteByte(address
, v
);
393 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
394 remotePutPacket("OK");
397 void remoteMemoryRead(char *p
)
401 sscanf(p
,"%x,%x:", &address
, &count
);
402 // printf("Memory read for %08x %d\n", address, count);
407 for(int i
= 0; i
< count
; i
++) {
408 u8 b
= debuggerReadByte(address
);
409 sprintf(s
, "%02x", b
);
414 remotePutPacket(buffer
);
417 void remoteStepOverRange(char *p
)
421 sscanf(p
, "%x,%x", &address
, &final
);
423 remotePutPacket("OK");
425 remoteResumed
= true;
430 } while(armNextPC
>= address
&& armNextPC
< final
);
432 remoteResumed
= false;
437 void remoteWriteWatch(char *p
, bool active
)
441 sscanf(p
, ",%x,%x#", &address
, &count
);
443 fprintf(stderr
, "Write watch for %08x %d\n", address
, count
);
445 if(address
< 0x2000000 || address
> 0x3007fff) {
446 remotePutPacket("E01");
450 if(address
> 0x203ffff && address
< 0x3000000) {
451 remotePutPacket("E01");
455 u32 final
= address
+ count
;
457 if(address
< 0x2040000 && final
> 0x2040000) {
458 remotePutPacket("E01");
460 } else if(address
< 0x3008000 && final
> 0x3008000) {
461 remotePutPacket("E01");
466 for(int i
= 0; i
< count
; i
++) {
467 if((address
>> 24) == 2)
468 freezeWorkRAM
[address
& 0x3ffff] = active
;
470 freezeInternalRAM
[address
& 0x7fff] = active
;
475 remotePutPacket("OK");
478 void remoteReadRegisters(char *p
)
485 for(i
= 0; i
< 15; i
++) {
487 sprintf(s
, "%02x%02x%02x%02x", v
& 255, (v
>> 8) & 255,
488 (v
>> 16) & 255, (v
>> 24) & 255);
493 sprintf(s
, "%02x%02x%02x%02x", pc
& 255, (pc
>> 8) & 255,
494 (pc
>> 16) & 255, (pc
>> 24) & 255);
497 // floating point registers (24-bit)
498 for(i
= 0; i
< 8; i
++) {
499 sprintf(s
, "000000000000000000000000");
503 // FP status register
504 sprintf(s
, "00000000");
509 sprintf(s
, "%02x%02x%02x%02x", v
& 255, (v
>> 8) & 255,
510 (v
>> 16) & 255, (v
>> 24) & 255);
513 remotePutPacket(buffer
);
516 void remoteWriteRegister(char *p
)
520 sscanf(p
, "%x=", &r
);
529 u8 data
[4] = {0,0,0,0};
538 b
= (c
+ 10 - 'a') << 4;
548 v
= data
[0] | (data
[1] << 8) | (data
[2] << 16) | (data
[3] << 24);
550 // printf("Write register %d=%08x\n", r, v);
559 remotePutPacket("OK");
562 extern int emulating
;
564 void remoteStubMain()
571 remoteResumed
= false;
576 int res
= remoteRecvFnc(buffer
, 1024);
579 fprintf(stderr
, "GDB connection lost\n");
581 dbgMain
= debuggerMain
;
582 dbgSignal
= debuggerSignal
;
588 // fprintf(stderr, "Received %s\n", buffer);
592 remoteSendFnc(&pp
, 1);
602 remotePutPacket("OK");
604 dbgMain
= debuggerMain
;
605 dbgSignal
= debuggerSignal
;
607 remoteResumed
= true;
611 remoteStepOverRange(p
);
614 remotePutPacket("OK");
616 dbgMain
= debuggerMain
;
617 dbgSignal
= debuggerSignal
;
623 remoteResumed
= true;
627 remoteResumed
= true;
631 remoteResumed
= true;
635 remoteResumed
= false;
640 remoteReadRegisters(p
);
643 remoteWriteRegister(p
);
646 remoteMemoryWrite(p
);
652 remoteBinaryWrite(p
);
655 remotePutPacket("OK");
662 remoteWriteWatch(p
, true);
668 remoteWriteWatch(p
, false);
674 *(strchr(p
, '#') + 3) = 0;
675 fprintf(stderr
, "Unknown packet %s\n", --p
);
683 void remoteStubSignal(int sig
, int number
)
686 remoteResumed
= false;