comparison gdb_remote.c @ 803:236a184bf6f0

Merge
author Michael Pavone <pavone@retrodev.com>
date Sun, 26 Jul 2015 16:51:03 -0700
parents 6811f601008f 092524bb2e8f
children 59e664fa2da8
comparison
equal deleted inserted replaced
802:6811f601008f 803:236a184bf6f0
21 #endif 21 #endif
22 22
23 #include "gdb_remote.h" 23 #include "gdb_remote.h"
24 #include "68kinst.h" 24 #include "68kinst.h"
25 #include "debug.h" 25 #include "debug.h"
26 #include "util.h"
26 #include <unistd.h> 27 #include <unistd.h>
27 #include <fcntl.h> 28 #include <fcntl.h>
28 #include <stddef.h> 29 #include <stddef.h>
29 #include <stdlib.h> 30 #include <stdlib.h>
30 #include <stdio.h> 31 #include <stdio.h>
93 } 94 }
94 95
95 void write_or_die(int fd, const void *buf, size_t count) 96 void write_or_die(int fd, const void *buf, size_t count)
96 { 97 {
97 if (GDB_WRITE(fd, buf, count) < count) { 98 if (GDB_WRITE(fd, buf, count) < count) {
98 fputs("Error writing to stdout\n", stderr); 99 fatal_error("Error writing to stdout\n");
99 exit(1);
100 } 100 }
101 } 101 }
102 102
103 void gdb_send_command(char * command) 103 void gdb_send_command(char * command)
104 { 104 {
132 } 132 }
133 } 133 }
134 134
135 uint8_t read_byte(m68k_context * context, uint32_t address) 135 uint8_t read_byte(m68k_context * context, uint32_t address)
136 { 136 {
137 uint16_t * word; 137
138 //TODO: Use generated read/write functions so that memory map is properly respected 138 genesis_context *gen = context->system;
139 if (address < 0x400000) { 139 //TODO: Use generated read/write functions to support access to hardware that is not ROM or RAM
140 word = context->mem_pointers[0] + address/2; 140 uint16_t * word = get_native_pointer(address & 0xFFFFFFFE, (void **)context->mem_pointers, &context->options->gen);
141 } else if (address >= 0xE00000) { 141 if (word) {
142 word = context->mem_pointers[1] + (address & 0xFFFF)/2;
143 } else if (address >= 0xA00000 && address < 0xA04000) {
144 return z80_ram[address & 0x1FFF];
145 } else {
146 return 0;
147 }
148 if (address & 1) { 142 if (address & 1) {
149 return *word; 143 return *word;
150 } 144 }
151 return *word >> 8; 145 return *word >> 8;
152 } 146 }
147 if (address >= 0xA00000 && address < 0xA04000) {
148 return gen->zram[address & 0x1FFF];
149 }
150 return 0;
151 }
153 152
154 void write_byte(m68k_context * context, uint32_t address, uint8_t value) 153 void write_byte(m68k_context * context, uint32_t address, uint8_t value)
155 { 154 {
156 uint16_t * word; 155 genesis_context *gen = context->system;
157 //TODO: Use generated read/write functions so that memory map is properly respected 156 //TODO: Use generated read/write functions so that memory map is properly respected
158 if (address < 0x400000) { 157 uint16_t * word = get_native_pointer(address & 0xFFFFFFFE, (void **)context->mem_pointers, &context->options->gen);
159 //TODO: Invalidate translated code 158 if (word) {
160 word = context->mem_pointers[0] + address/2; 159 if (address & 1) {
161 } else if (address >= 0xE00000) { 160 *word = (*word & 0xFF00) | value;
162 m68k_handle_code_write(address & 0xFFFF, context); 161 } else {
163 word = context->mem_pointers[1] + (address & 0xFFFF)/2; 162 *word = (*word & 0xFF) | value << 8;
164 } else if (address >= 0xA00000 && address < 0xA04000) { 163 }
164 //TODO: Deal with this more generally once m68k_handle_code_write can handle it
165 if (address >= 0xE00000) {
166 m68k_handle_code_write(address, context);
167 }
168 return;
169 }
170 if (address >= 0xA00000 && address < 0xA04000) {
165 z80_ram[address & 0x1FFF] = value; 171 z80_ram[address & 0x1FFF] = value;
166 genesis_context * gen = context->system; 172 genesis_context * gen = context->system;
167 #ifndef NO_Z80 173 #ifndef NO_Z80
168 z80_handle_code_GDB_WRITE(address & 0x1FFF, gen->z80); 174 z80_handle_code_GDB_WRITE(address & 0x1FFF, gen->z80);
169 #endif 175 #endif
170 return; 176 return;
171 } else { 177 } else {
172 return; 178 return;
173 } 179 }
174 if (address & 1) {
175 *word = (*word & 0xFF00) | value;
176 } else {
177 *word = (*word & 0xFF) | value << 8;
178 }
179 } 180 }
180 181
181 void gdb_run_command(m68k_context * context, uint32_t pc, char * command) 182 void gdb_run_command(m68k_context * context, uint32_t pc, char * command)
182 { 183 {
183 char send_buf[512]; 184 char send_buf[512];
197 if (*(command+1) != 0) { 198 if (*(command+1) != 0) {
198 //TODO: implement resuming at an arbitrary address 199 //TODO: implement resuming at an arbitrary address
199 goto not_impl; 200 goto not_impl;
200 } 201 }
201 m68kinst inst; 202 m68kinst inst;
202 uint16_t * pc_ptr; 203 genesis_context *gen = context->system;
203 if (pc < 0x400000) { 204 uint16_t * pc_ptr = get_native_pointer(pc, (void **)context->mem_pointers, &context->options->gen);
204 pc_ptr = cart + pc/2; 205 if (!pc_ptr) {
205 } else if(pc > 0xE00000) { 206 fatal_error("Entered gdb remote debugger stub at address %X\n", pc);
206 pc_ptr = ram + (pc & 0xFFFF)/2;
207 } else {
208 fprintf(stderr, "Entered gdb remote debugger stub at address %X\n", pc);
209 exit(1);
210 } 207 }
211 uint16_t * after_pc = m68k_decode(pc_ptr, &inst, pc & 0xFFFFFF); 208 uint16_t * after_pc = m68k_decode(pc_ptr, &inst, pc & 0xFFFFFF);
212 uint32_t after = pc + (after_pc-pc_ptr)*2; 209 uint32_t after = pc + (after_pc-pc_ptr)*2;
213 210
214 if (inst.op == M68K_RTS) { 211 if (inst.op == M68K_RTS) {
300 } 297 }
301 case 'm': { 298 case 'm': {
302 char * rest; 299 char * rest;
303 uint32_t address = strtoul(command+1, &rest, 16); 300 uint32_t address = strtoul(command+1, &rest, 16);
304 uint32_t size = strtoul(rest+1, NULL, 16); 301 uint32_t size = strtoul(rest+1, NULL, 16);
305 if (size > sizeof(send_buf-1)/2) { 302 if (size > (sizeof(send_buf)-1)/2) {
306 size = sizeof(send_buf-1)/2; 303 size = (sizeof(send_buf)-1)/2;
307 } 304 }
308 char *cur = send_buf; 305 char *cur = send_buf;
309 while (size) 306 while (size)
310 { 307 {
311 hex_8(read_byte(context, address), cur); 308 hex_8(read_byte(context, address), cur);
418 expect_break_response = 1; 415 expect_break_response = 1;
419 break; 416 break;
420 case 's': 417 case 's':
421 case 'S': { 418 case 'S': {
422 m68kinst inst; 419 m68kinst inst;
423 uint16_t * pc_ptr; 420 genesis_context *gen = context->system;
424 if (pc < 0x400000) { 421 uint16_t * pc_ptr = get_native_pointer(pc, (void **)context->mem_pointers, &context->options->gen);
425 pc_ptr = cart + pc/2; 422 if (!pc_ptr) {
426 } else if(pc > 0xE00000) { 423 fatal_error("Entered gdb remote debugger stub at address %X\n", pc);
427 pc_ptr = ram + (pc & 0xFFFF)/2;
428 } else {
429 fprintf(stderr, "Entered gdb remote debugger stub at address %X\n", pc);
430 exit(1);
431 } 424 }
432 uint16_t * after_pc = m68k_decode(pc_ptr, &inst, pc & 0xFFFFFF); 425 uint16_t * after_pc = m68k_decode(pc_ptr, &inst, pc & 0xFFFFFF);
433 uint32_t after = pc + (after_pc-pc_ptr)*2; 426 uint32_t after = pc + (after_pc-pc_ptr)*2;
434 427
435 if (inst.op == M68K_RTS) { 428 if (inst.op == M68K_RTS) {
469 goto not_impl; 462 goto not_impl;
470 463
471 } 464 }
472 return; 465 return;
473 not_impl: 466 not_impl:
474 fprintf(stderr, "Command %s is not implemented, exiting...\n", command); 467 fatal_error("Command %s is not implemented, exiting...\n", command);
475 exit(1);
476 } 468 }
477 469
478 m68k_context * gdb_debug_enter(m68k_context * context, uint32_t pc) 470 m68k_context * gdb_debug_enter(m68k_context * context, uint32_t pc)
479 { 471 {
480 dfprintf(stderr, "Entered debugger at address %X\n", pc); 472 dfprintf(stderr, "Entered debugger at address %X\n", pc);
538 //TODO: verify checksum 530 //TODO: verify checksum
539 //Null terminate payload 531 //Null terminate payload
540 *curbuf = 0; 532 *curbuf = 0;
541 //send acknowledgement 533 //send acknowledgement
542 if (GDB_WRITE(GDB_OUT_FD, "+", 1) < 1) { 534 if (GDB_WRITE(GDB_OUT_FD, "+", 1) < 1) {
543 fputs("Error writing to stdout\n", stderr); 535 fatal_error("Error writing to stdout\n");
544 exit(1);
545 } 536 }
546 gdb_run_command(context, pc, start); 537 gdb_run_command(context, pc, start);
547 curbuf += 2; 538 curbuf += 2;
548 } 539 }
549 } else { 540 } else {