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