# HG changeset patch # User Michael Pavone # Date 1392184335 28800 # Node ID 450c7745379ac1e4d23aff8bc8c58890f0221f7e # Parent 6a14c5a95648ea85d4dbb33df4678eae6bb1bf59# Parent 0b21a1a73fb7d193522606a28eea1981344d88c3 Merge diff -r 6a14c5a95648 -r 450c7745379a 68kinst.c --- a/68kinst.c Tue Feb 11 12:52:28 2014 -0800 +++ b/68kinst.c Tue Feb 11 21:52:15 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #include "68kinst.h" @@ -434,8 +434,8 @@ } break; case 7: - - + + break; } } @@ -459,7 +459,7 @@ } break; case MISC: - + if ((*istream & 0x1C0) == 0x1C0) { decoded->op = M68K_LEA; decoded->extra.size = OPSIZE_LONG; @@ -682,7 +682,7 @@ } } } - break; + break; case 6: //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL #ifdef M68020 @@ -918,7 +918,7 @@ decoded->op = M68K_INVALID; return start+1; } - break; + break; } } else { decoded->op = M68K_OR; @@ -1259,7 +1259,7 @@ } decoded->dst.addr_mode = MODE_REG; decoded->dst.params.regs.pri = *istream & 0x7; - + } else { #ifdef M68020 //TODO: Implement bitfield instructions for M68020+ support @@ -1273,6 +1273,79 @@ return istream+1; } +uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) +{ + if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) { + return inst->address + 2 + inst->src.params.immed; + } else if(inst->op == M68K_JMP || inst->op == M68K_JSR) { + uint32_t ret = 0; + switch(inst->src.addr_mode) + { + case MODE_AREG_INDIRECT: + ret = aregs[inst->src.params.regs.pri]; + break; + case MODE_AREG_INDEX_DISP8: { + uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7; + ret = aregs[inst->src.params.regs.pri]; + uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs; + if (inst->src.params.regs.sec & 1) { + //32-bit index register + ret += regfile[sec_reg]; + } else { + //16-bit index register + if (regfile[sec_reg] & 0x8000) { + ret += (0xFFFF0000 | regfile[sec_reg]); + } else { + ret += regfile[sec_reg]; + } + } + ret += inst->src.params.regs.displacement; + break; + } + case MODE_PC_DISPLACE: + ret = inst->src.params.regs.displacement + inst->address + 2; + break; + case MODE_PC_INDEX_DISP8: { + uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7; + ret = inst->address + 2; + uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs; + if (inst->src.params.regs.sec & 1) { + //32-bit index register + ret += regfile[sec_reg]; + } else { + //16-bit index register + if (regfile[sec_reg] & 0x8000) { + ret += (0xFFFF0000 | regfile[sec_reg]); + } else { + ret += regfile[sec_reg]; + } + } + ret += inst->src.params.regs.displacement; + break; + } + case MODE_ABSOLUTE: + case MODE_ABSOLUTE_SHORT: + ret = inst->src.params.immed; + break; + } + return ret; + } + return 0; +} + +uint8_t m68k_is_branch(m68kinst * inst) +{ + return (inst->op == M68K_BCC && inst->extra.cond != COND_FALSE) + || (inst->op == M68K_DBCC && inst->extra.cond != COND_TRUE) + || inst->op == M68K_BSR || inst->op == M68K_JMP || inst->op == M68K_JSR; +} + +uint8_t m68k_is_noncall_branch(m68kinst * inst) +{ + return m68k_is_branch(inst) && inst->op != M68K_BSR && inst->op != M68K_JSR; +} + + char * mnemonics[] = { "abcd", "add", @@ -1504,7 +1577,7 @@ break; case M68K_BSR: if (labels) { - ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", + ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", decoded->address + 2 + decoded->src.params.immed); } else { ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); @@ -1540,9 +1613,9 @@ return ret; default: size = decoded->extra.size; - ret = sprintf(dst, "%s%s%s", - mnemonics[decoded->op], - decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), + ret = sprintf(dst, "%s%s%s", + mnemonics[decoded->op], + decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); } if (decoded->op == M68K_MOVEM) { diff -r 6a14c5a95648 -r 450c7745379a 68kinst.h --- a/68kinst.h Tue Feb 11 12:52:28 2014 -0800 +++ b/68kinst.h Tue Feb 11 21:52:15 2014 -0800 @@ -1,6 +1,6 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #ifndef M68KINST_H_ @@ -230,7 +230,9 @@ } m68k_vector; uint16_t * m68k_decode(uint16_t * istream, m68kinst * dst, uint32_t address); -uint32_t m68k_cycles(m68kinst * inst); +uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs); +uint8_t m68k_is_branch(m68kinst * inst); +uint8_t m68k_is_noncall_branch(m68kinst * inst); int m68k_disasm(m68kinst * decoded, char * dst); int m68k_disasm_labels(m68kinst * decoded, char * dst); diff -r 6a14c5a95648 -r 450c7745379a Makefile --- a/Makefile Tue Feb 11 12:52:28 2014 -0800 +++ b/Makefile Tue Feb 11 21:52:15 2014 -0800 @@ -26,8 +26,8 @@ all : dis zdis stateview vgmplay blastem -blastem : blastem.o vdp.o render_sdl.o io.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(Z80OBJS) $(TRANSOBJS) $(AUDIOOBJS) - $(CC) -ggdb -o blastem blastem.o vdp.o render_sdl.o io.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(Z80OBJS) $(TRANSOBJS) $(AUDIOOBJS) $(LDFLAGS) +blastem : blastem.o gdb_remote.o vdp.o render_sdl.o io.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(Z80OBJS) $(TRANSOBJS) $(AUDIOOBJS) + $(CC) -ggdb -o blastem blastem.o gdb_remote.o vdp.o render_sdl.o io.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(Z80OBJS) $(TRANSOBJS) $(AUDIOOBJS) $(LDFLAGS) dis : dis.o 68kinst.o $(CC) -o dis dis.o 68kinst.o diff -r 6a14c5a95648 -r 450c7745379a blastem.c --- a/blastem.c Tue Feb 11 12:52:28 2014 -0800 +++ b/blastem.c Tue Feb 11 21:52:15 2014 -0800 @@ -10,6 +10,7 @@ #include "vdp.h" #include "render.h" #include "blastem.h" +#include "gdb_remote.h" #include "gst.h" #include "util.h" #include @@ -1410,7 +1411,7 @@ case 'd': param = find_param(input_buf); if (!param) { - fputs("b command requires a parameter\n", stderr); + fputs("d command requires a parameter\n", stderr); break; } value = atoi(param); @@ -1464,16 +1465,80 @@ printf(format, param, value); break; case 'n': - //TODO: Deal with jmp, dbcc, rtr and rte + if (inst.op == M68K_RTS) { + after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); + } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { + after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); + } else if(m68k_is_noncall_branch(&inst)) { + if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { + branch_f = after; + branch_t = m68k_branch_target(&inst, context->dregs, context->aregs); + insert_breakpoint(context, branch_t, (uint8_t *)debugger); + } else if(inst.op == M68K_DBCC) { + if ( inst.extra.cond == COND_FALSE) { + if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) { + after = m68k_branch_target(&inst, context->dregs, context->aregs); + } + } else { + branch_t = after; + branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); + insert_breakpoint(context, branch_f, (uint8_t *)debugger); + } + } else { + after = m68k_branch_target(&inst, context->dregs, context->aregs); + } + } + insert_breakpoint(context, after, (uint8_t *)debugger); + debugging = 0; + break; + case 'o': if (inst.op == M68K_RTS) { after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); - } else if(inst.op == M68K_BCC && inst.extra.cond != COND_FALSE) { - if (inst.extra.cond = COND_TRUE) { - after = inst.address + 2 + inst.src.params.immed; + } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { + after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); + } else if(m68k_is_noncall_branch(&inst)) { + if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { + branch_t = m68k_branch_target(&inst, context->dregs, context->aregs); + if (branch_t < after) { + branch_t = 0; + } else { + branch_f = after; + insert_breakpoint(context, branch_t, (uint8_t *)debugger); + } + } else if(inst.op == M68K_DBCC) { + uint32_t target = m68k_branch_target(&inst, context->dregs, context->aregs); + if (target > after) { + if (inst.extra.cond == COND_FALSE) { + after = target; + } else { + branch_f = target; + branch_t = after; + insert_breakpoint(context, branch_f, (uint8_t *)debugger); + } + } } else { + after = m68k_branch_target(&inst, context->dregs, context->aregs); + } + } + insert_breakpoint(context, after, (uint8_t *)debugger); + debugging = 0; + break; + case 's': + if (inst.op == M68K_RTS) { + after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); + } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { + after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); + } else if(m68k_is_branch(&inst)) { + if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { branch_f = after; - branch_t = inst.address + 2 + inst.src.params.immed; + branch_t = m68k_branch_target(&inst, context->dregs, context->aregs); insert_breakpoint(context, branch_t, (uint8_t *)debugger); + } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { + branch_t = after; + branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); + insert_breakpoint(context, branch_f, (uint8_t *)debugger); + } else { + after = m68k_branch_target(&inst, context->dregs, context->aregs); } } insert_breakpoint(context, after, (uint8_t *)debugger); @@ -1585,7 +1650,7 @@ printf("Saved SRAM to %s\n", sram_filename); } -void init_run_cpu(genesis_context * gen, int debug, FILE * address_log, char * statefile) +void init_run_cpu(genesis_context * gen, FILE * address_log, char * statefile, uint8_t * debugger) { m68k_context context; x86_68k_options opts; @@ -1706,15 +1771,15 @@ exit(1); } printf("Loaded %s\n", statefile); - if (debug) { - insert_breakpoint(&context, pc, (uint8_t *)debugger); + if (debugger) { + insert_breakpoint(&context, pc, debugger); } adjust_int_cycle(gen->m68k, gen->vdp); gen->z80->native_pc = z80_get_native_address_trans(gen->z80, gen->z80->pc); start_68k_context(&context, pc); } else { - if (debug) { - insert_breakpoint(&context, address, (uint8_t *)debugger); + if (debugger) { + insert_breakpoint(&context, address, debugger); } m68k_reset(&context); } @@ -1808,6 +1873,7 @@ char * romfname = NULL; FILE *address_log = NULL; char * statefile = NULL; + uint8_t * debuggerfun = NULL; uint8_t fullscreen = 0, use_gl = 1; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { @@ -1822,7 +1888,11 @@ exit_after = atoi(argv[i]); break; case 'd': - debug = 1; + debuggerfun = (uint8_t *)debugger; + break; + case 'D': + gdb_remote_init(); + debuggerfun = (uint8_t *)gdb_debug_enter; break; case 'f': fullscreen = 1; @@ -1980,6 +2050,6 @@ } set_keybindings(); - init_run_cpu(&gen, debug, address_log, statefile); + init_run_cpu(&gen, address_log, statefile, debuggerfun); return 0; } diff -r 6a14c5a95648 -r 450c7745379a gdb_remote.c --- a/gdb_remote.c Tue Feb 11 12:52:28 2014 -0800 +++ b/gdb_remote.c Tue Feb 11 21:52:15 2014 -0800 @@ -3,14 +3,15 @@ This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ -#include "blastem.h" +#include "gdb_remote.h" #include #include #include #include #include +#include -#define INITIAL_BUFFER_SIZE 4096 +#define INITIAL_BUFFER_SIZE (16*1024) char * buf = NULL; char * curbuf = NULL; @@ -20,9 +21,261 @@ int expect_break_response=0; uint32_t resume_pc; -void gdb_debug_enter(genesis_context * gen, uint32_t pc) + +void hex_32(uint32_t num, char * out) +{ + for (int32_t shift = 28; shift >= 0; shift -= 4) + { + uint8_t nibble = num >> shift & 0xF; + *(out++) = nibble > 9 ? nibble - 0xA + 'A' : nibble + '0'; + } +} + +void hex_16(uint16_t num, char * out) +{ + for (int16_t shift = 14; shift >= 0; shift -= 4) + { + uint8_t nibble = num >> shift & 0xF; + *(out++) = nibble > 9 ? nibble - 0xA + 'A' : nibble + '0'; + } +} + +void hex_8(uint8_t num, char * out) +{ + uint8_t nibble = num >> 4; + *(out++) = nibble > 9 ? nibble - 0xA + 'A' : nibble + '0'; + nibble = num & 0xF; + *out = nibble > 9 ? nibble - 0xA + 'A' : nibble + '0'; +} + +void gdb_calc_checksum(char * command, char *out) +{ + uint8_t checksum = 0; + while (*command) + { + checksum += *(command++); + } + hex_8(checksum, out); +} + +void write_or_die(int fd, const void *buf, size_t count) +{ + if (write(fd, buf, count) < count) { + fputs("Error writing to stdout\n", stderr); + exit(1); + } +} + +void gdb_send_command(char * command) +{ + char end[3]; + write_or_die(STDOUT_FILENO, "$", 1); + write_or_die(STDOUT_FILENO, command, strlen(command)); + end[0] = '#'; + gdb_calc_checksum(command, end+1); + write_or_die(STDOUT_FILENO, end, 3); + fprintf(stderr, "Sent $%s#%c%c\n", command, end[1], end[2]); +} + +uint32_t calc_status(m68k_context * context) +{ + uint32_t status = context->status << 3; + for (int i = 0; i < 5; i++) + { + status <<= 1; + status |= context->flags[i]; + } + return status; +} + +uint8_t read_byte(m68k_context * context, uint32_t address) +{ + uint16_t * word; + //TODO: Use generated read/write functions so that memory map is properly respected + if (address < 0x400000) { + word = context->mem_pointers[0] + address/2; + } else if (address >= 0xE00000) { + word = context->mem_pointers[1] + (address & 0xFFFF)/2; + } else { + return 0; + } + if (address & 1) { + return *word; + } + return *word >> 8; +} + +void gdb_run_command(m68k_context * context, uint32_t pc, char * command) { - fcntl(STDIN_FILENO, FD_SETFL, 0); + char send_buf[512]; + fprintf(stderr, "Received command %s\n", command); + switch(*command) + { + + case 'c': + if (*(command+1) != 0) { + //TODO: implement resuming at an arbitrary address + goto not_impl; + } + cont = 1; + expect_break_response = 1; + break; + case 'H': + if (command[1] == 'g' || command[1] == 'c') {; + //no thread suport, just acknowledge + gdb_send_command("OK"); + } else { + goto not_impl; + } + break; + case 'Z': { + uint8_t type = command[1]; + if (type < '2') { + uint32_t address = strtoul(command+3, NULL, 16); + insert_breakpoint(context, address, (uint8_t *)gdb_debug_enter); + gdb_send_command("OK"); + } else { + //watchpoints are not currently supported + gdb_send_command(""); + } + break; + } + case 'z': { + uint8_t type = command[1]; + if (type < '2') { + uint32_t address = strtoul(command+3, NULL, 16); + remove_breakpoint(context, address); + gdb_send_command("OK"); + } else { + //watchpoints are not currently supported + gdb_send_command(""); + } + break; + } + case 'g': { + char * cur = send_buf; + for (int i = 0; i < 8; i++) + { + hex_32(context->dregs[i], cur); + cur += 8; + } + for (int i = 0; i < 8; i++) + { + hex_32(context->aregs[i], cur); + cur += 8; + } + hex_32(calc_status(context), cur); + cur += 8; + hex_32(pc, cur); + cur += 8; + *cur = 0; + gdb_send_command(send_buf); + break; + } + case 'm': { + char * rest; + uint32_t address = strtoul(command+1, &rest, 16); + uint32_t size = strtoul(rest+1, NULL, 16); + if (size > sizeof(send_buf-1)/2) { + size = sizeof(send_buf-1)/2; + } + char *cur = send_buf; + while (size) + { + hex_8(read_byte(context, address), cur); + cur += 2; + address++; + size--; + } + *cur = 0; + gdb_send_command(send_buf); + break; + } + case 'p': { + unsigned long reg = strtoul(command+1, NULL, 16); + + if (reg < 8) { + hex_32(context->dregs[reg], send_buf); + } else if (reg < 16) { + hex_32(context->aregs[reg-8], send_buf); + } else if (reg == 16) { + hex_32(calc_status(context), send_buf); + } else if (reg == 17) { + hex_32(pc, send_buf); + } else { + send_buf[0] = 0; + } + send_buf[8] = 0; + gdb_send_command(send_buf); + break; + } + case 'q': + if (!memcmp("Supported", command+1, strlen("Supported"))) { + sprintf(send_buf, "PacketSize=%X", (int)bufsize); + gdb_send_command(send_buf); + } else if (!memcmp("Attached", command+1, strlen("Supported"))) { + //not really meaningful for us, but saying we spawned a new process + //is probably closest to the truth + gdb_send_command("0"); + } else if (!memcmp("Offsets", command+1, strlen("Offsets"))) { + //no relocations, so offsets are all 0 + gdb_send_command("Text=0;Data=0;Bss=0"); + } else if (!memcmp("Symbol", command+1, strlen("Symbol"))) { + gdb_send_command(""); + } else if (!memcmp("TStatus", command+1, strlen("TStatus"))) { + //TODO: actual tracepoint support + gdb_send_command("T0;tnotrun:0"); + } else if (!memcmp("TfV", command+1, strlen("TfV")) || !memcmp("TfP", command+1, strlen("TfP"))) { + //TODO: actual tracepoint support + gdb_send_command(""); + } else if (command[1] == 'C') { + //we only support a single thread currently, so send 1 + gdb_send_command("1"); + } else { + goto not_impl; + } + break; + case 'v': + if (!memcmp("Cont?", command+1, strlen("Cont?"))) { + gdb_send_command("vCont;c;C;s;S"); + } else if (!memcmp("Cont;", command+1, strlen("Cont;"))) { + switch (*(command + 1 + strlen("Cont;"))) + { + case 'c': + case 'C': + //might be interesting to have continue with signal fire a + //trap exception or something, but for no we'll treat it as + //a normal continue + cont = 1; + expect_break_response = 1; + break; + default: + goto not_impl; + } + } else { + goto not_impl; + } + break; + case '?': + gdb_send_command("S05"); + break; + default: + goto not_impl; + + } + return; +not_impl: + fprintf(stderr, "Command %s is not implemented, exiting...\n", command); + exit(1); +} + +m68k_context * gdb_debug_enter(m68k_context * context, uint32_t pc) +{ + fprintf(stderr, "Entered debugger at address %X\n", pc); + if (expect_break_response) { + gdb_send_command("S05"); + expect_break_response = 0; + } resume_pc = pc; cont = 0; uint8_t partial = 0; @@ -35,7 +288,7 @@ } else if (partial) { if (curbuf != buf) { memmove(curbuf, buf, end-curbuf); - end -= cufbuf - buf; + end -= curbuf - buf; } int numread = read(STDIN_FILENO, end, bufsize - (end-buf)); end += numread; @@ -55,10 +308,13 @@ if (end-curbuf >= 2) { //TODO: verify checksum //Null terminate payload - *curbuf = 0 + *curbuf = 0; //send acknowledgement - write(FILENO_STDOUT, "+", 1); - gdb_run_command(genesis_context * gen, start); + if (write(STDOUT_FILENO, "+", 1) < 1) { + fputs("Error writing to stdout\n", stderr); + exit(1); + } + gdb_run_command(context, pc, start); curbuf += 2; } } else { @@ -66,115 +322,20 @@ partial = 1; break; } + } else { + fprintf(stderr, "Ignoring character %c\n", *curbuf); } } + if (curbuf == end) { + curbuf = NULL; + } } - fcntl(STDIN_FILENO, FD_SETFL, O_NONBLOCK); -} - -void gdb_run_command(genesis_context * gen, char * command) -{ - switch(*command) - { - case 'c': - if (*(command+1) != 0) { - resume_pc = - } - cont = 1; - expect_break_response = 1; - break; - case 's': - - } + return context; } -void gdb_run_commands(genesis_context * gen) +void gdb_remote_init(void) { - int enter_debugger = 0; - char * cur = buf; - while(cur < curbuf); - { - if(*cur == '$') { - cur++ - char * start = cur; - while (cur < curbuf && *cur != '#') { - cur++; - } - if (*cur == '#') { - //check to make sure we've received the checksum bytes - if (curbuf-cur >= 2) { - //TODO: verify checksum - //Null terminate payload - //send acknowledgement - write(FILENO_STDOUT, "+", 1); - gdb_run_command(genesis_context * gen, start); - cur += 2; - } else { - cur = start - 1; - break; - } - } else { - cur = start - 1; - break; - } - } else { - if (*cur == 0x03) { - enter_debugger = 1; - } - cur++; - } - } - - //FIXME - if (consumed == curbuf-buf) { - curbuf = buf; - } else if (consumed > 0) { - memmove(buf, buf + consumed, curbuf - buf - consumed); - curbuf -= consumed; - } + buf = malloc(INITIAL_BUFFER_SIZE); + curbuf = NULL; + bufsize = INITIAL_BUFFER_SIZE; } - -int gdb_command_poll(genesis_context * gen) -{ - for(;;) - { - if (curbuf == buf + bufsize) { - //buffer is full, expand it - bufsize *= 2; - buf = realloc(buf, bufsize); - if (!buf) { - fprintf(stderr, "Failed to grow GDB command buffer to %d bytes\n", (int)bufsize); - exit(1); - } - curbuf = buf + bufsize/2; - } - int numread = read(STDIN_FILENO, buf, bufsize); - if (numread < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return 0; - } else { - fprintf(stderr, "Error %d while reading GDB commands from stdin", errno); - exit(1); - } - } else if (numread == 0) { - exit(0); - } - for (curbuf = buf, end = buf+numread; curbuf < end; curbuf++) - { - if (*curbuf = 0x03) - { - curbuf++; - return 1; - } - } - } - return 0; -} - -void gdb_remote_init() -{ - fcntl(STDIN_FILENO, FD_SETFL, O_NONBLOCK); - buf = malloc(INITIAL_BUFFER_SIZE); - curbuf = buf; - bufzie = INITIAL_BUFFER_SIZE; -} diff -r 6a14c5a95648 -r 450c7745379a m68k_to_x86.c --- a/m68k_to_x86.c Tue Feb 11 12:52:28 2014 -0800 +++ b/m68k_to_x86.c Tue Feb 11 21:52:15 2014 -0800 @@ -1953,6 +1953,7 @@ } sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; if (inst->src.params.regs.sec & 1) { + //32-bit index register if (inst->src.params.regs.sec & 0x10) { if (opts->aregs[sec_reg] >= 0) { dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); @@ -1967,6 +1968,7 @@ } } } else { + //16-bit index register if (inst->src.params.regs.sec & 0x10) { if (opts->aregs[sec_reg] >= 0) { dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); diff -r 6a14c5a95648 -r 450c7745379a vdp.c --- a/vdp.c Tue Feb 11 12:52:28 2014 -0800 +++ b/vdp.c Tue Feb 11 21:52:15 2014 -0800 @@ -197,7 +197,7 @@ uint8_t pal = context->vdpmem[address + 4] >> 5 & 0x3; uint8_t pri = context->vdpmem[address + 4] >> 7; uint16_t pattern = ((context->vdpmem[address + 4] << 8 | context->vdpmem[address + 5]) & 0x7FF) << 5; - //printf("Sprite %d: X=%d(%d), Y=%d(%d), Width=%u, Height=%u, Link=%u, Pal=%u, Pri=%u, Pat=%X\n", current_index, x, x-128, y, y-128, width, height, link, pal, pri, pattern); + printf("Sprite %d: X=%d(%d), Y=%d(%d), Width=%u, Height=%u, Link=%u, Pal=%u, Pri=%u, Pat=%X\n", current_index, x, x-128, y, y-128, width, height, link, pal, pri, pattern); current_index = link; count++; } while (current_index != 0 && count < 80);