void mon_memory_compare(MON_ADDR start_addr, MON_ADDR end_addr, MON_ADDR dest) { WORD start; MEMSPACE src_mem, dest_mem; BYTE byte1, byte2; unsigned int i, dst; int len; len = mon_evaluate_address_range(&start_addr, &end_addr, TRUE, -1); if (len < 0) { mon_out("Invalid range.\n"); return; } src_mem = addr_memspace(start_addr); start = addr_location(start_addr); mon_evaluate_default_addr(&dest); dst = addr_location(dest); dest_mem = addr_memspace(dest); for (i = 0; (int)i < len; i++) { byte1 = mon_get_mem_val(src_mem, (WORD)ADDR_LIMIT(start + i)); byte2 = mon_get_mem_val(dest_mem, (WORD)ADDR_LIMIT(dst + i)); if (byte1 != byte2) { mon_out("$%04x $%04x: %02x %02x\n", ADDR_LIMIT(start + i), ADDR_LIMIT(dst + i), byte1, byte2); } } }
static void print_checkpoint_info(breakpoint_t *bp) { if (bp->trace) { mon_out("TRACE: "); } else if (bp->watch_load || bp->watch_store) { mon_out("WATCH: "); } else { if (bp->temporary) mon_out("UNTIL: "); else mon_out("BREAK: "); } mon_out("%d %s:$%04x",bp->brknum, mon_memspace_string[addr_memspace(bp->start_addr)],addr_location(bp->start_addr)); if (mon_is_valid_addr(bp->end_addr) && (bp->start_addr != bp->end_addr)) mon_out("-$%04x",addr_location(bp->end_addr)); if (bp->watch_load) mon_out(" load"); if (bp->watch_store) mon_out(" store"); mon_out(" %s\n", (bp->enabled==e_ON) ? "enabled" : "disabled"); if (bp->condition) { mon_out("\tCondition: "); mon_print_conditional(bp->condition); mon_out("\n"); } if (bp->command) mon_out("\tCommand: %s\n", bp->command); }
void mon_memory_move(MON_ADDR start_addr, MON_ADDR end_addr, MON_ADDR dest) { unsigned int i, dst; int len; WORD start; MEMSPACE src_mem, dest_mem; BYTE *buf; len = mon_evaluate_address_range(&start_addr, &end_addr, TRUE, -1); if (len <= 0) { mon_out("Invalid range.\n"); return; } src_mem = addr_memspace(start_addr); start = addr_location(start_addr); mon_evaluate_default_addr(&dest); dst = addr_location(dest); dest_mem = addr_memspace(dest); buf = lib_malloc(sizeof(BYTE) * len); for (i = 0; (int)i < len; i++) { buf[i] = mon_get_mem_val(src_mem, (WORD)ADDR_LIMIT(start + i)); } for (i = 0; (int)i < len; i++) { mon_set_mem_val(dest_mem, (WORD)ADDR_LIMIT(dst + i), buf[i]); } lib_free(buf); }
static void mon_register_print(int mem) { z80_regs_t *regs; if (monitor_diskspace_dnr(mem) >= 0) { if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) return; } else if (mem != e_comp_space) { log_error(LOG_ERR, "Unknown memory space!"); return; } regs = mon_interfaces[mem]->z80_cpu_regs; mon_out(" ADDR AF BC DE HL IX IY SP I R AF' BC' DE' HL'\n"); mon_out(".;%04x %04x %04x %04x %04x %04x %04x %04x %02x %02x %04x %04x %04x %04x\n", addr_location(mon_register_get_val(mem, e_PC)), mon_register_get_val(mem, e_AF), mon_register_get_val(mem, e_BC), mon_register_get_val(mem, e_DE), mon_register_get_val(mem, e_HL), mon_register_get_val(mem, e_IX), mon_register_get_val(mem, e_IY), mon_register_get_val(mem, e_SP), mon_register_get_val(mem, e_I), mon_register_get_val(mem, e_R), mon_register_get_val(mem, e_AF2), mon_register_get_val(mem, e_BC2), mon_register_get_val(mem, e_DE2), mon_register_get_val(mem, e_HL2)); }
/* TODO: should use mon_register_list_get */ static void mon_register_print(int mem) { h6809_regs_t *regs; if (monitor_diskspace_dnr(mem) >= 0) { if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) { return; } } else if (mem != e_comp_space) { log_error(LOG_ERR, "Unknown memory space!"); return; } regs = mon_interfaces[mem]->h6809_cpu_regs; mon_out(" ADDR A B X Y SP U DP EFHINZVC\n"); mon_out(".;%04x %02x %02x %04x %04x %04x %04x %02x %c%c%c%c%c%c%c%c\n", addr_location(mon_register_get_val(mem, e_PC)), mon_register_get_val(mem, e_A), mon_register_get_val(mem, e_B), mon_register_get_val(mem, e_X), mon_register_get_val(mem, e_Y), mon_register_get_val(mem, e_SP), mon_register_get_val(mem, e_U), mon_register_get_val(mem, e_DP), (H6809_REGS_TEST_E(regs) ? '1' : '.'), (H6809_REGS_TEST_F(regs) ? '1' : '.'), (H6809_REGS_TEST_H(regs) ? '1' : '.'), (H6809_REGS_TEST_I(regs) ? '1' : '.'), (H6809_REGS_TEST_N(regs) ? '1' : '.'), (H6809_REGS_TEST_Z(regs) ? '1' : '.'), (H6809_REGS_TEST_V(regs) ? '1' : '.'), (H6809_REGS_TEST_C(regs) ? '1' : '.') ); }
static void print_checkpoint_info(checkpoint_t *cp) { if (!cp->stop) { mon_out("TRACE: "); } else if (cp->check_load || cp->check_store) { mon_out("WATCH: "); } else { if (cp->temporary) { mon_out("UNTIL: "); } else { mon_out("BREAK: "); } } mon_out("%d %s:$%04x", cp->checknum, mon_memspace_string[addr_memspace(cp->start_addr)], addr_location(cp->start_addr)); if (mon_is_valid_addr(cp->end_addr) && (cp->start_addr != cp->end_addr)) { mon_out("-$%04x", addr_location(cp->end_addr)); } mon_out(cp->stop ? " (Stop on" : " (Trace"); if (cp->check_load) { mon_out(" load"); } if (cp->check_store) { mon_out(" store"); } if (cp->check_exec) { mon_out(" exec"); } mon_out(")"); if (cp->enabled != e_ON) { mon_out(" disabled"); } mon_out("\n"); if (cp->condition) { mon_out("\tCondition: "); mon_print_conditional(cp->condition); mon_out("\n"); } if (cp->command) { mon_out("\tCommand: %s\n", cp->command); } }
static int compare_checkpoints(checkpoint_t *bp1, checkpoint_t *bp2) { unsigned addr1, addr2; /* Returns < 0 if bp1 < bp2 = 0 if bp1 = bp2 > 0 if bp1 > bp2 */ addr1 = addr_location(bp1->start_addr); addr2 = addr_location(bp2->end_addr); if (addr1 < addr2) return -1; if (addr1 > addr2) return 1; return 0; }
static void mon_register_print(int mem) { mos6510_regs_t *regs; if (monitor_diskspace_dnr(mem) >= 0) { if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) { return; } } else if (mem != e_comp_space) { log_error(LOG_ERR, "Unknown memory space!"); return; } regs = mon_interfaces[mem]->cpu_regs; mon_out(" ADDR AC XR YR SP 00 01 NV-BDIZC "); if (mon_interfaces[mem]->get_line_cycle != NULL) { mon_out("LIN CYC STOPWATCH\n"); } else { mon_out(" STOPWATCH\n"); } mon_out(".;%04x %02x %02x %02x %02x %02x %02x %d%d%c%d%d%d%d%d", addr_location(mon_register_get_val(mem, e_PC)), mon_register_get_val(mem, e_A), mon_register_get_val(mem, e_X), mon_register_get_val(mem, e_Y), mon_register_get_val(mem, e_SP), mon_get_mem_val(mem, 0), mon_get_mem_val(mem, 1), TEST(MOS6510_REGS_GET_SIGN(regs)), TEST(MOS6510_REGS_GET_OVERFLOW(regs)), '1', TEST(MOS6510_REGS_GET_BREAK(regs)), TEST(MOS6510_REGS_GET_DECIMAL(regs)), TEST(MOS6510_REGS_GET_INTERRUPT(regs)), TEST(MOS6510_REGS_GET_ZERO(regs)), TEST(MOS6510_REGS_GET_CARRY(regs))); if (mon_interfaces[mem]->get_line_cycle != NULL) { unsigned int line, cycle; int half_cycle; mon_interfaces[mem]->get_line_cycle(&line, &cycle, &half_cycle); if (half_cycle == -1) { mon_out(" %03i %03i", line, cycle); } else { mon_out(" %03i %03i %i", line, cycle, half_cycle); } } mon_stopwatch_show(" ", "\n"); }
mon_breakpoint_type_t mon_breakpoint_is(MON_ADDR address) { MEMSPACE mem = addr_memspace(address); WORD addr = addr_location(address); checkpoint_list_t *ptr; ptr = search_checkpoint_list(breakpoints[mem], addr); if (!ptr) return BP_NONE; return (ptr->checkpt->enabled == e_ON) ? BP_ACTIVE : BP_INACTIVE; }
void mon_breakpoint_unset(MON_ADDR address) { MEMSPACE mem = addr_memspace(address); WORD addr = addr_location(address); checkpoint_list_t *ptr; ptr = search_checkpoint_list(breakpoints[mem], addr); if (ptr) { /* there's a breakpoint, so remove it */ remove_checkpoint_from_list( &breakpoints[mem], ptr->checkpt ); } }
void mon_breakpoint_disable(MON_ADDR address) { MEMSPACE mem = addr_memspace(address); WORD addr = addr_location(address); checkpoint_list_t *ptr; ptr = search_checkpoint_list(breakpoints[mem], addr); if (ptr) { /* there's a breakpoint, so disable it */ ptr->checkpt->enabled = e_OFF; } }
void mon_memory_hunt(MON_ADDR start_addr, MON_ADDR end_addr, unsigned char *data) { BYTE *buf; WORD start, next_read; MEMSPACE mem; unsigned int i; int len; len = mon_evaluate_address_range(&start_addr, &end_addr, TRUE, -1); if (len < 0 || len < (int)(data_buf_len)) { mon_out("Invalid range.\n"); return; } mem = addr_memspace(start_addr); start = addr_location(start_addr); buf = lib_malloc(sizeof(BYTE) * data_buf_len); /* Fill buffer */ for (i = 0; i < data_buf_len; i++) { buf[i] = mon_get_mem_val(mem, (WORD)ADDR_LIMIT(start + i)); } /* Do compares */ next_read = start + (WORD)data_buf_len; for (i = 0; i <= (len - data_buf_len); i++, next_read++) { int not_found = 0; unsigned int j; for (j = 0; j < data_buf_len; j++) { if ((buf[j] & data_mask_buf[j]) != data_buf[j]) { not_found = 1; break; } } if (!not_found) { mon_out("%04x\n", ADDR_LIMIT(start + i)); } if (data_buf_len > 1) { memmove(&(buf[0]), &(buf[1]), data_buf_len - 1); } buf[data_buf_len - 1] = mon_get_mem_val(mem, next_read); } mon_clear_buffer(); lib_free(buf); }
void mon_breakpoint_set(MON_ADDR address) { MEMSPACE mem = addr_memspace(address); WORD addr = addr_location(address); checkpoint_list_t *ptr; ptr = search_checkpoint_list(breakpoints[mem], addr); if (ptr) { /* there's a breakpoint, so enable it */ ptr->checkpt->enabled = e_ON; } else { /* there's no breakpoint, so set a new one */ breakpoint_add_checkpoint(address, address, TRUE, e_exec, FALSE, FALSE); } }
unsigned mon_disassemble_instr(MON_ADDR addr) { MEMSPACE mem; WORD loc; char *label; unsigned opc_size; mem = addr_memspace(addr); loc = addr_location(addr); /* Print the label for this location - if we have one */ label = mon_symbol_table_lookup_name(mem, loc); if (label) { mon_out(".%s:%04x %s:\n", mon_memspace_string[mem], loc, label); } /* Print the disassembled instruction */ mon_out("%s\n", mon_disassemble_instr_interal(&opc_size, addr)); return opc_size; /* asm_addr_mode_get_size(asm_opcode_info_get(op)->addr_mode); */ }
/* display binary data (sprites/chars) */ void mon_memory_display_data(MON_ADDR start_addr, MON_ADDR end_addr, unsigned int x, unsigned int y) { unsigned i, j, len, cnt = 0; WORD addr = 0; MEMSPACE mem; len = mon_evaluate_address_range(&start_addr, &end_addr, FALSE, (WORD)((x * y) / 8)); mem = addr_memspace(start_addr); addr = addr_location(start_addr); while (cnt < len) { for (i = 0; i < y; i++) { mon_out(">%s:%04x ", mon_memspace_string[mem], addr); for (j = 0; j < (x / 8); j++) { mon_print_bin(mon_get_mem_val(mem, (WORD)(ADDR_LIMIT(addr + j))), '.', '*'); cnt++; } mon_out("\n"); addr = ADDR_LIMIT(addr + (x / 8)); if (mon_stop_output != 0) { break; } } mon_out("\n"); if (mon_stop_output != 0) { break; } } if ((x == 24) && (y == 21)) { addr++; /* continue at next even address when showing sprites */ } set_addr_location(&(dot_addr[mem]), addr); }
static const char* mon_disassemble_instr_interal(unsigned *opc_size, MON_ADDR addr) { static char buff[256]; BYTE opc[5]; MEMSPACE mem; WORD loc; int hex_mode = 1; const char *dis_inst; mem = addr_memspace(addr); loc = addr_location(addr); opc[0] = mon_get_mem_val(mem, loc); opc[1] = mon_get_mem_val(mem, (WORD)(loc + 1)); opc[2] = mon_get_mem_val(mem, (WORD)(loc + 2)); opc[3] = mon_get_mem_val(mem, (WORD)(loc + 3)); opc[4] = mon_get_mem_val(mem, (WORD)(loc + 4)); dis_inst = mon_disassemble_to_string_internal(mem, loc, opc, hex_mode, opc_size, monitor_cpu_for_memspace[mem]); sprintf(buff, ".%s:%04x %s", mon_memspace_string[mem], loc, dis_inst); return buff; }
void mon_memory_fill(MON_ADDR start_addr, MON_ADDR end_addr, unsigned char *data) { WORD start; MEMSPACE dest_mem; unsigned int i, mon_index; int len; len = mon_evaluate_address_range(&start_addr, &end_addr, FALSE, (WORD)data_buf_len); if (len < 0) { mon_out("Invalid range.\n"); return; } start = addr_location(start_addr); if (!mon_is_valid_addr(start_addr)) { mon_out("Invalid start address\n"); return; } dest_mem = addr_memspace(start_addr); i = 0; mon_index = 0; while ((int)i < len) { mon_set_mem_val(dest_mem, (WORD)ADDR_LIMIT(start + i), data_buf[mon_index++]); if (mon_index >= data_buf_len) { mon_index = 0; } i++; } mon_clear_buffer(); }
static int mon_assemble_instr(const char *opcode_name, asm_mode_addr_info_t operand) { WORD operand_value = operand.param; WORD operand_mode = operand.addr_mode; BYTE operand_extra_value = operand.addr_submode; BYTE i = 0, opcode = 0; int len, branch_offset; bool found = FALSE; MEMSPACE mem; WORD loc; mem = addr_memspace(asm_mode_addr); loc = addr_location(asm_mode_addr); do { const asm_opcode_info_t *opinfo; opinfo = (monitor_cpu_for_memspace[mem]->asm_opcode_info_get)(i, 0, 0); if (!strcasecmp(opinfo->mnemonic, opcode_name)) { /* Special case: ZERO PAGE RELATIVE mode needs special handling. */ if (opinfo->addr_mode == ASM_ADDR_MODE_ZERO_PAGE_RELATIVE && operand_mode == ASM_ADDR_MODE_DOUBLE) { branch_offset = (operand_value - loc - 3) & 0xffff; if (branch_offset > 0x7f && branch_offset < 0xff80) { mon_out("Branch offset too large.\n"); return -1; } operand_value = (operand_extra_value & 0xff) | ((branch_offset & 0xff) << 8); opcode = i; operand_mode = ASM_ADDR_MODE_ZERO_PAGE_RELATIVE; found = TRUE; break; } if (opinfo->addr_mode == operand_mode && found == FALSE) { opcode = i; found = TRUE; break; } /* Special case: Register A not specified for ACCUMULATOR mode. */ if (operand_mode == ASM_ADDR_MODE_IMPLIED && opinfo->addr_mode == ASM_ADDR_MODE_ACCUMULATOR) { opcode = i; operand_mode = ASM_ADDR_MODE_ACCUMULATOR; found = TRUE; break; } /* Special case: RELATIVE mode looks like ZERO_PAGE or ABSOLUTE modes. */ if ((operand_mode == ASM_ADDR_MODE_ZERO_PAGE || operand_mode == ASM_ADDR_MODE_ABSOLUTE) && opinfo->addr_mode == ASM_ADDR_MODE_RELATIVE) { branch_offset = (operand_value - loc - 2) & 0xffff; if (branch_offset > 0x7f && branch_offset < 0xff80) { mon_out("Branch offset too large.\n"); return -1; } operand_value = (branch_offset & 0xff); operand_mode = ASM_ADDR_MODE_RELATIVE; opcode = i; found = TRUE; break; } /* Special case: opcode A - is A a register or $A? */ /* If second case, is it zero page or absolute? */ if (operand_mode == ASM_ADDR_MODE_ACCUMULATOR && opinfo->addr_mode == ASM_ADDR_MODE_ZERO_PAGE) { opcode = i; operand_mode = ASM_ADDR_MODE_ZERO_PAGE; operand_value = 0x000a; found = TRUE; break; } /* It's safe to assume ABSOLUTE if ZERO_PAGE not yet found since * ZERO_PAGE versions always precede ABSOLUTE versions if they * exist. */ if (operand_mode == ASM_ADDR_MODE_ACCUMULATOR && opinfo->addr_mode == ASM_ADDR_MODE_ABSOLUTE) { opcode = i; operand_mode = ASM_ADDR_MODE_ABSOLUTE; operand_value = 0x000a; found = TRUE; break; } /* It's safe to assume ABSOULTE if ZERO_PAGE not yet found since * ZERO_PAGE versions always precede ABSOLUTE versions if they * exist. */ if (operand_mode == ASM_ADDR_MODE_ZERO_PAGE && opinfo->addr_mode == ASM_ADDR_MODE_ABSOLUTE) { opcode = i; operand_mode = ASM_ADDR_MODE_ABSOLUTE; found = TRUE; break; } } i++; } while (i != 0); if (!found) { mon_out("Instruction not valid.\n"); return -1; } len = (monitor_cpu_for_memspace[mem]->asm_addr_mode_get_size) ((unsigned int)(operand_mode), 0, 0, 0); /* EP 98.08.23 use correct memspace for assembling. */ mon_set_mem_val(mem, loc, opcode); if (len >= 2) { mon_set_mem_val(mem, (WORD)(loc + 1), (BYTE)(operand_value & 0xff)); } if (len >= 3) { mon_set_mem_val(mem, (WORD)(loc + 2), (BYTE)((operand_value >> 8) & 0xff)); }
void mon_memory_display(int radix_type, MON_ADDR start_addr, MON_ADDR end_addr, mon_display_format_t format) { unsigned int i, cnt = 0, len, max_width, real_width; WORD addr = 0; char printables[50]; char prefix; MEMSPACE mem; WORD display_number; BYTE v; prefix = (format == DF_PETSCII) ? '>' : '*'; if (radix_type) { if (radix_type != e_hexadecimal && radix_type != e_decimal && radix_type != e_octal) { max_width = (console_log->console_xres - 12) / (radix_chars_per_byte[radix_type] + 2); } else { max_width = (4 * (console_log->console_xres - 12)) / (4 * (radix_chars_per_byte[radix_type] + 2) + 1); } max_width &= ~3; display_number = max_width * ((console_log->console_yres - 6) / 2); } else { max_width = 40; display_number = 128; } len = mon_evaluate_address_range(&start_addr, &end_addr, FALSE, display_number); mem = addr_memspace(start_addr); addr = addr_location(start_addr); while (cnt < len) { mon_out("%c%s:%04x ", prefix, mon_memspace_string[mem], addr); for (i = 0, real_width = 0; i < max_width; i++) { v = mon_get_mem_val(mem, (WORD)ADDR_LIMIT(addr + i)); switch (radix_type) { case 0: /* special case == petscii text */ if (format == DF_PETSCII) { mon_out("%c", charset_p_toascii(v, 1)); } else { mon_out("%c", charset_p_toascii( charset_screencode_to_petcii(v), 1)); } real_width++; cnt++; break; case e_decimal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%03d ", v); real_width++; cnt++; } else { mon_out(" "); } break; case e_hexadecimal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%02x ", v); real_width++; } else { mon_out(" "); } cnt++; break; case e_octal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%03o ", v); real_width++; cnt++; } else { mon_out(" "); } break; case e_binary: memset(printables, 0, 50); if (cnt < len) { mon_print_bin(v, '1', '0'); mon_out(" "); real_width++; cnt++; } else { mon_out(" "); } break; default: return; } } if (radix_type != 0) { memory_to_string(printables, mem, addr, real_width, FALSE); mon_out(" %s", printables); } mon_out("\n"); addr = ADDR_LIMIT(addr + real_width); if (mon_stop_output != 0) { break; } } set_addr_location(&(dot_addr[mem]), addr); }
/* TODO: should use mon_register_list_get */ static void mon_register_print(int mem) { WDC65816_regs_t *regs; unsigned int line = 0, cycle = 0; int half_cycle = -1; if (monitor_diskspace_dnr(mem) >= 0) { if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) { return; } } else if (mem != e_comp_space) { log_error(LOG_ERR, "Unknown memory space!"); return; } regs = mon_interfaces[mem]->cpu_65816_regs; if (mem == e_comp_space && mon_interfaces[mem]->get_line_cycle != NULL) { mon_interfaces[mem]->get_line_cycle(&line, &cycle, &half_cycle); } if (mon_register_get_val(mem, e_E)) { mon_out(" PB ADDR A B X Y SP DPRE DB NV-BDIZC E"); if (mem == e_comp_space && mon_interfaces[mem]->get_line_cycle != NULL) { mon_out(" LIN CYC"); if (half_cycle != -1) { mon_out(".SB"); } } mon_out("\n.;%02x %04x %02x %02x %02x %02x %02x %04x %02x %d%d1%d%d%d%d%d 1", mon_register_get_val(mem, e_PBR), addr_location(mon_register_get_val(mem, e_PC)), mon_register_get_val(mem, e_A), mon_register_get_val(mem, e_B), mon_register_get_val(mem, e_X) & 0xff, mon_register_get_val(mem, e_Y) & 0xff, mon_register_get_val(mem, e_SP) & 0xff, mon_register_get_val(mem, e_DPR), mon_register_get_val(mem, e_DBR), TEST(WDC65816_REGS_GET_SIGN(regs)), TEST(WDC65816_REGS_GET_OVERFLOW(regs)), TEST(WDC65816_REGS_GET_BREAK(regs)), TEST(WDC65816_REGS_GET_DECIMAL(regs)), TEST(WDC65816_REGS_GET_INTERRUPT(regs)), TEST(WDC65816_REGS_GET_ZERO(regs)), TEST(WDC65816_REGS_GET_CARRY(regs))); } else { mon_out(" PB ADDR"); mon_out(WDC65816_REGS_GET_65816_M(regs) ? " A B " : " CREG"); mon_out(WDC65816_REGS_GET_65816_X(regs) ? " XH X YH Y " : " X Y "); mon_out(" STCK DPRE DB NVMXDIZC E"); if (mem == e_comp_space && mon_interfaces[mem]->get_line_cycle != NULL) { mon_out(" LIN CYC"); if (half_cycle != -1) { mon_out(".SB"); } } mon_out("\n.;%02x %04x", mon_register_get_val(mem, e_PBR), addr_location(mon_register_get_val(mem, e_PC))); if (WDC65816_REGS_GET_65816_M(regs)) { mon_out(" %02x %02x", mon_register_get_val(mem, e_A), mon_register_get_val(mem, e_B)); } else { mon_out(" %02x%02x", mon_register_get_val(mem, e_B), mon_register_get_val(mem, e_A)); } if (WDC65816_REGS_GET_65816_X(regs)) { mon_out(" %02x %02x %02x %02x", mon_register_get_val(mem, e_X) >> 8, mon_register_get_val(mem, e_X) & 0xff, mon_register_get_val(mem, e_Y) >> 8, mon_register_get_val(mem, e_Y) & 0xff); } else { mon_out(" %04x %04x", mon_register_get_val(mem, e_X), mon_register_get_val(mem, e_Y)); } mon_out(" %04x %04x %02x %d%d%d%d%d%d%d%d 0", mon_register_get_val(mem, e_SP), mon_register_get_val(mem, e_DPR), mon_register_get_val(mem, e_DBR), TEST(WDC65816_REGS_GET_SIGN(regs)), TEST(WDC65816_REGS_GET_OVERFLOW(regs)), TEST(WDC65816_REGS_GET_65816_M(regs)), TEST(WDC65816_REGS_GET_65816_X(regs)), TEST(WDC65816_REGS_GET_DECIMAL(regs)), TEST(WDC65816_REGS_GET_INTERRUPT(regs)), TEST(WDC65816_REGS_GET_ZERO(regs)), TEST(WDC65816_REGS_GET_CARRY(regs))); }
void mon_drive_block_cmd(int op, int track, int sector, MON_ADDR addr) { vdrive_t *vdrive; mon_evaluate_default_addr(&addr); vdrive = file_system_get_vdrive(8); if (!vdrive || vdrive->image == NULL) { mon_out("No disk attached\n"); return; } if (!op) { BYTE readdata[256]; int i, j, dst; MEMSPACE dest_mem; /* We ignore disk error codes here. */ if (vdrive_read_sector(vdrive, readdata, track, sector) < 0) { mon_out("Error reading track %d sector %d\n", track, sector); return; } if (mon_is_valid_addr(addr)) { dst = addr_location(addr); dest_mem = addr_memspace(addr); for (i = 0; i < 256; i++) { mon_set_mem_val(dest_mem, ADDR_LIMIT(dst + i), readdata[i]); } mon_out("Read track %d sector %d into address $%04x\n", track, sector, dst); } else { for (i = 0; i < 16; i++) { mon_out(">%04x", i * 16); for (j = 0; j < 16; j++) { if ((j & 3) == 0) { mon_out(" "); } mon_out(" %02x", readdata[i * 16 + j]); } mon_out("\n"); } } } else { BYTE writedata[256]; int i, src; MEMSPACE src_mem; src = addr_location(addr); src_mem = addr_memspace(addr); for (i = 0; i < 256; i++) { writedata[i] = mon_get_mem_val(src_mem, ADDR_LIMIT(src + i)); } if (vdrive_write_sector(vdrive, writedata, track, sector)) { mon_out("Error writing track %d sector %d\n", track, sector); return; } mon_out("Write data from address $%04x to track %d sector %d\n", src, track, sector); } }
static int mon_assemble_instr(const char *opcode_name, asm_mode_addr_info_t operand) { WORD operand_value = operand.param; WORD operand_mode = operand.addr_mode; WORD operand_submode = operand.addr_submode; BYTE i = 0, j = 0, opcode = 0; int len, branch_offset; bool found = FALSE; MEMSPACE mem; WORD loc; int const prefix[3] = { -1, 0x10, 0x11 }; BYTE opc[5]; int opc_offset; int prefixlen; mem = addr_memspace(asm_mode_addr); loc = addr_location(asm_mode_addr); /* * Convert generic addressing modes to 6809 addressing modes. * The reason we have different numbers for them is that the disassembler * needs to skip prefix bytes in a 6809-specific manner. */ switch (operand_mode) { case ASM_ADDR_MODE_IMMEDIATE: operand_mode = ASM_ADDR_MODE_IMM_BYTE; break; case ASM_ADDR_MODE_IMMEDIATE_16: operand_mode = ASM_ADDR_MODE_IMM_WORD; break; case ASM_ADDR_MODE_ZERO_PAGE: /* we have no zero page */ operand_mode = ASM_ADDR_MODE_EXTENDED; break; case ASM_ADDR_MODE_ABSOLUTE: operand_mode = ASM_ADDR_MODE_EXTENDED; break; } /* * Fix up another parsing ambiguity, for addr,X and addr,Y and addr,S. */ if (operand_mode == ASM_ADDR_MODE_ZERO_PAGE_X || operand_mode == ASM_ADDR_MODE_ABSOLUTE_X) { int reg = 0 << 5; operand_mode = ASM_ADDR_MODE_INDEXED; operand_submode = reg | make_offset_mode(operand_value); } else if (operand_mode == ASM_ADDR_MODE_ZERO_PAGE_Y || operand_mode == ASM_ADDR_MODE_ABSOLUTE_Y) { int reg = 1 << 5; operand_mode = ASM_ADDR_MODE_INDEXED; operand_submode = reg | make_offset_mode(operand_value); } else if (operand_mode == ASM_ADDR_MODE_STACK_RELATIVE) { int reg = 3 << 5; operand_mode = ASM_ADDR_MODE_INDEXED; operand_submode = reg | make_offset_mode(operand_value); } DBG(printf("mon_assemble_instr: '%s' mode %d submode $%02x oper $%04x\n", opcode_name, operand_mode, operand_submode, operand_value)); for (j = 0; j < 3 && !found; j++) { do { const asm_opcode_info_t *opinfo; if (prefix[j] == -1) { opinfo = (monitor_cpu_for_memspace[mem]->asm_opcode_info_get)(i, 0, 0); prefixlen = 0; } else { opinfo = (monitor_cpu_for_memspace[mem]->asm_opcode_info_get)(prefix[j], i, 0); prefixlen = 1; } if (!strcasecmp(opinfo->mnemonic, opcode_name)) { if (opinfo->addr_mode == operand_mode) { opcode = i; found = TRUE; DBG(printf("found, prefix $%02x opcode $%02x\n", prefix[j], opcode)); break; } /* Special case: RELATIVE mode looks like EXTENDED mode. */ if (operand_mode == ASM_ADDR_MODE_EXTENDED && opinfo->addr_mode == ASM_ADDR_MODE_REL_BYTE) { branch_offset = operand_value - (loc + prefixlen + 2); if (branch_offset > 127 || branch_offset < -128) { mon_out("Branch offset too large.\n"); return -1; } operand_value = (branch_offset & 0xff); operand_mode = ASM_ADDR_MODE_REL_BYTE; opcode = i; found = TRUE; break; } /* Special case: RELATIVE mode looks like EXTENDED mode. */ if (operand_mode == ASM_ADDR_MODE_EXTENDED && opinfo->addr_mode == ASM_ADDR_MODE_REL_WORD) { branch_offset = operand_value - (loc + prefixlen + 3); operand_value = (branch_offset & 0xffff); operand_mode = ASM_ADDR_MODE_REL_WORD; opcode = i; found = TRUE; break; } #if 0 /* Special case: opcode A - is A a register or $A? */ /* If second case, is it zero page or absolute? */ if (operand_mode == ASM_ADDR_MODE_ACCUMULATOR && opinfo->addr_mode == ASM_ADDR_MODE_ZERO_PAGE) { opcode = i; operand_mode = ASM_ADDR_MODE_ZERO_PAGE; operand_value = 0x000a; found = TRUE; break; } #endif /* If there is no operand and the opcode wants a register * list, it could be an empty list. */ if (operand_mode == ASM_ADDR_MODE_IMPLIED && (opinfo->addr_mode == ASM_ADDR_MODE_SYS_POST || opinfo->addr_mode == ASM_ADDR_MODE_USR_POST)) { opcode = i; operand_mode = opinfo->addr_mode; operand_value = 0x00; found = TRUE; break; } /* If there are exactly 2 registers the parser thought it * would be _REG_POST but it could also be a 2-item list. * Fortunately it kept the other interpretation hidden away * in the submode field. */ if (operand_mode == ASM_ADDR_MODE_REG_POST && (opinfo->addr_mode == ASM_ADDR_MODE_SYS_POST || opinfo->addr_mode == ASM_ADDR_MODE_USR_POST)) { opcode = i; operand_mode = opinfo->addr_mode; operand_value = operand_submode; found = TRUE; break; } /* The parser doesn't distinguish 2 kinds of register lists. * Too bad if you write PSHS S or PSHU U. */ if (operand_mode == ASM_ADDR_MODE_SYS_POST && opinfo->addr_mode == ASM_ADDR_MODE_USR_POST) { opcode = i; found = TRUE; break; } } i++; } while (i != 0); if (found) { break; } } if (!found) { mon_out("Instruction not valid.\n"); return -1; } opc_offset = 0; if (prefix[j] != -1) { opc[opc_offset++] = prefix[j]; } opc[opc_offset++] = opcode; if (operand_mode == ASM_ADDR_MODE_INDEXED) { opc[opc_offset++] = (BYTE)operand_submode; } len = (monitor_cpu_for_memspace[mem]->asm_addr_mode_get_size) ((unsigned int)operand_mode, opc[0], opc[1], opc[2]); DBG(printf("len = %d\n", len)); if (len == opc_offset + 1) { opc[opc_offset++] = operand_value & 0xFF; } else if (len == opc_offset + 2) { opc[opc_offset++] = operand_value >> 8; opc[opc_offset++] = operand_value & 0xFF; }
static void mon_register_print(int mem) { mos6510dtv_regs_t *regs; if (monitor_diskspace_dnr(mem) >= 0) { if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) return; } else if (mem != e_comp_space) { #ifdef CELL_DEBUG printf("ERROR: Unknown memory space!\n"); #endif return; } regs = mon_interfaces[mem]->dtv_cpu_regs; mon_out(" ADDR AC XR YR SP 00 01 NV-BDIZC"); if (mem == e_comp_space && mon_interfaces[mem]->get_line_cycle != NULL) mon_out(" LIN CYC\n"); else mon_out("\n"); mon_out(".;%04x %02x %02x %02x %02x %02x %02x %d%d%c%d%d%d%d%d", addr_location(mon_register_get_val(mem, e_PC)), mon_register_get_val(mem, e_A), mon_register_get_val(mem, e_X), mon_register_get_val(mem, e_Y), mon_register_get_val(mem, e_SP), mon_get_mem_val(mem, 0), mon_get_mem_val(mem, 1), TEST(MOS6510DTV_REGS_GET_SIGN(regs)), TEST(MOS6510DTV_REGS_GET_OVERFLOW(regs)), '1', TEST(MOS6510DTV_REGS_GET_BREAK(regs)), TEST(MOS6510DTV_REGS_GET_DECIMAL(regs)), TEST(MOS6510DTV_REGS_GET_INTERRUPT(regs)), TEST(MOS6510DTV_REGS_GET_ZERO(regs)), TEST(MOS6510DTV_REGS_GET_CARRY(regs))); if (mem == e_comp_space && mon_interfaces[mem]->get_line_cycle != NULL) { unsigned int line, cycle; int half_cycle; mon_interfaces[mem]->get_line_cycle(&line, &cycle, &half_cycle); if (half_cycle==-1) mon_out(" %03i %03i\n", line, cycle); else mon_out(" %03i %03i %i\n", line, cycle, half_cycle); } else { mon_out("\n"); } if (mem == e_comp_space) { mon_out("R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ACM YXM\n"); mon_out("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", mon_register_get_val(mem, e_R3), mon_register_get_val(mem, e_R4), mon_register_get_val(mem, e_R5), mon_register_get_val(mem, e_R6), mon_register_get_val(mem, e_R7), mon_register_get_val(mem, e_R8), mon_register_get_val(mem, e_R9), mon_register_get_val(mem, e_R10), mon_register_get_val(mem, e_R11), mon_register_get_val(mem, e_R12), mon_register_get_val(mem, e_R13), mon_register_get_val(mem, e_R14), mon_register_get_val(mem, e_R15), mon_register_get_val(mem, e_ACM), mon_register_get_val(mem, e_YXM)); } }