sanitized peek_word()
This commit is contained in:
parent
d531407d30
commit
ddf908027a
7 changed files with 148 additions and 41 deletions
|
@ -22,10 +22,16 @@ std::optional<std::string> breakpoint_memory::is_triggered() const
|
|||
{
|
||||
uint16_t v = 0;
|
||||
|
||||
if (is_virtual)
|
||||
v = b->peek_word(rm_cur, addr); // FIXME rm_cur
|
||||
else
|
||||
if (is_virtual) {
|
||||
auto temp = b->peek_word(rm_cur, addr); // FIXME rm_cur
|
||||
if (temp.has_value() == false)
|
||||
return { };
|
||||
|
||||
v = temp.value();
|
||||
}
|
||||
else {
|
||||
v = b->read_physical(addr);
|
||||
}
|
||||
|
||||
auto it = values.find(v);
|
||||
if (it == values.end())
|
||||
|
|
7
bus.cpp
7
bus.cpp
|
@ -854,13 +854,13 @@ uint16_t bus::read_word(const uint16_t a, const d_i_space_t s)
|
|||
return read(a, wm_word, rm_cur, s);
|
||||
}
|
||||
|
||||
uint16_t bus::peek_word(const int run_mode, const uint16_t a)
|
||||
std::optional<uint16_t> bus::peek_word(const int run_mode, const uint16_t a)
|
||||
{
|
||||
auto meta = mmu_->calculate_physical_address(run_mode, a);
|
||||
|
||||
uint32_t io_base = mmu_->get_io_base();
|
||||
if (meta.physical_instruction >= io_base) // TODO: I/O always returns 0xffff
|
||||
return 0xffff;
|
||||
if (meta.physical_instruction >= io_base)
|
||||
return { };
|
||||
|
||||
return m->read_word(meta.physical_instruction);
|
||||
}
|
||||
|
@ -882,7 +882,6 @@ uint8_t bus::read_unibus_byte(const uint32_t a)
|
|||
void bus::write_unibus_byte(const uint32_t a, const uint8_t v)
|
||||
{
|
||||
TRACE("write_unibus_byte[%08o]=%03o", a, v);
|
||||
|
||||
if (a < m->get_memory_size())
|
||||
m->write_byte(a, v);
|
||||
}
|
||||
|
|
2
bus.h
2
bus.h
|
@ -126,7 +126,7 @@ public:
|
|||
uint8_t read_byte(const uint16_t a) override { return read(a, wm_byte, rm_cur); }
|
||||
uint16_t read_word(const uint16_t a, const d_i_space_t s);
|
||||
uint16_t read_word(const uint16_t a) override { return read_word(a, i_space); }
|
||||
uint16_t peek_word(const int run_mode, const uint16_t a);
|
||||
std::optional<uint16_t> peek_word(const int run_mode, const uint16_t a);
|
||||
uint8_t read_unibus_byte(const uint32_t a);
|
||||
uint16_t read_physical(const uint32_t a);
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ void console_ncurses::panel_update_thread()
|
|||
uint16_t current_PC = c->getPC();
|
||||
memory_addresses_t rc = b->getMMU()->calculate_physical_address(run_mode, current_PC);
|
||||
|
||||
uint16_t current_instr = b->peek_word(run_mode, current_PC);
|
||||
auto current_instr = b->peek_word(run_mode, current_PC);
|
||||
|
||||
auto data = c->disassemble(current_PC);
|
||||
|
||||
|
@ -167,8 +167,14 @@ void console_ncurses::panel_update_thread()
|
|||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b, "%c", current_PSW & (1 << b) ? '1' : '0');
|
||||
|
||||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "%c", current_instr & (1 << b) ? '1' : '0');
|
||||
if (current_instr.has_value()) {
|
||||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "%c", current_instr.value() & (1 << b) ? '1' : '0');
|
||||
}
|
||||
else {
|
||||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "-");
|
||||
}
|
||||
|
||||
mvwprintw(w_panel->win, 4, 1, "LEDs:");
|
||||
|
||||
|
|
135
cpu.cpp
135
cpu.cpp
|
@ -1898,15 +1898,20 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt)
|
|||
while(0);
|
||||
}
|
||||
|
||||
cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const
|
||||
std::optional<cpu::operand_parameters> cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const
|
||||
{
|
||||
assert(mode_register < 64);
|
||||
|
||||
int run_mode = getPSW_runmode();
|
||||
uint16_t next_word = b->peek_word(run_mode, pc & 65535);
|
||||
auto temp = b->peek_word(run_mode, pc & 65535);
|
||||
if (temp.has_value() == false)
|
||||
return { };
|
||||
uint16_t next_word = temp.value();
|
||||
int reg = mode_register & 7;
|
||||
uint16_t mask = word_mode == wm_byte ? 0xff : 0xffff;
|
||||
|
||||
std::optional<uint16_t> temp2;
|
||||
|
||||
std::string reg_name;
|
||||
if (reg == 6)
|
||||
reg_name = "SP";
|
||||
|
@ -1917,49 +1922,111 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c
|
|||
|
||||
switch(mode_register >> 3) {
|
||||
case 0:
|
||||
return { reg_name, 2, -1, uint16_t(get_register(reg) & mask) };
|
||||
return { { reg_name, 2, -1, uint16_t(get_register(reg) & mask) } };
|
||||
|
||||
case 1:
|
||||
return { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) };
|
||||
temp2 = b->peek_word(run_mode, get_register(reg));
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 2:
|
||||
if (reg == 7)
|
||||
return { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) };
|
||||
return { { format("#%06o", next_word), 4, int(next_word), uint16_t(next_word & mask) } };
|
||||
|
||||
return { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg)) & mask) };
|
||||
temp2 = b->peek_word(run_mode, get_register(reg));
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("(%s)+", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 3:
|
||||
if (reg == 7)
|
||||
return { format("@#%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, next_word) & mask) };
|
||||
if (reg == 7) {
|
||||
temp2 = b->peek_word(run_mode, next_word);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg))) & mask) };
|
||||
return { { format("@#%06o", next_word), 4, int(next_word), uint16_t(temp2.value() & mask) } };
|
||||
}
|
||||
|
||||
temp2 = b->peek_word(run_mode, get_register(reg));
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
temp2 = b->peek_word(run_mode, temp2.value());
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 4:
|
||||
return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, get_register(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) };
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1));
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 5:
|
||||
return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) - 2)) & mask) };
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) - 2);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
temp2 = b->peek_word(run_mode, temp2.value());
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 6:
|
||||
if (reg == 7)
|
||||
return { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) };
|
||||
if (reg == 7) {
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) + next_word);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, get_register(reg) + next_word) & mask) };
|
||||
return { { format("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(temp2.value() & mask) } };
|
||||
}
|
||||
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) + next_word);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(temp2.value() & mask) } };
|
||||
|
||||
case 7:
|
||||
if (reg == 7)
|
||||
return { format("@%06o", next_word), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) };
|
||||
if (reg == 7) {
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) + next_word);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) };
|
||||
temp2 = b->peek_word(run_mode, temp2.value());
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("@%06o", next_word), 4, int(next_word), uint16_t(temp2.value() & mask) } };
|
||||
}
|
||||
|
||||
temp2 = b->peek_word(run_mode, get_register(reg) + next_word);
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
temp2 = b->peek_word(run_mode, temp2.value());
|
||||
if (temp2.has_value() == false)
|
||||
return { };
|
||||
|
||||
return { { format("@%o(%s)", next_word, reg_name.c_str()), 4, int(next_word), uint16_t(temp2.value() & mask) } };
|
||||
}
|
||||
|
||||
return { "??", 0, -1, 0123456 };
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t addr) const
|
||||
{
|
||||
uint16_t instruction = b->peek_word(getPSW_runmode(), addr);
|
||||
auto temp = b->peek_word(getPSW_runmode(), addr);
|
||||
if (temp.has_value() == false)
|
||||
return { };
|
||||
|
||||
uint16_t instruction = temp.value();
|
||||
word_mode_t word_mode = instruction & 0x8000 ? wm_byte : wm_word;
|
||||
std::string word_mode_str = word_mode == wm_byte ? "B" : "";
|
||||
uint8_t ado_opcode = (instruction >> 9) & 7; // additional double operand
|
||||
|
@ -1981,7 +2048,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
// TODO: 100000011
|
||||
|
||||
if (do_opcode == 0b000) {
|
||||
auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) };
|
||||
auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode);
|
||||
if (addressing.has_value() == false)
|
||||
return { };
|
||||
auto dst_text { addressing.value() };
|
||||
|
||||
auto next_word = dst_text.instruction_part;
|
||||
|
||||
|
@ -2074,7 +2144,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
name = "?";
|
||||
else {
|
||||
std::string src_text = format("R%d", (instruction >> 6) & 7);
|
||||
auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) };
|
||||
auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode);
|
||||
if (addressing.has_value() == false)
|
||||
return { };
|
||||
auto dst_text { addressing.value() };
|
||||
|
||||
auto next_word = dst_text.instruction_part;
|
||||
|
||||
|
@ -2144,7 +2217,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
}
|
||||
|
||||
// source
|
||||
auto src_text { addressing_to_string(src_register, (addr + 2) & 65535, word_mode) };
|
||||
auto addressing_src = addressing_to_string(src_register, (addr + 2) & 65535, word_mode);
|
||||
if (addressing_src.has_value() == false)
|
||||
return { };
|
||||
auto src_text { addressing_src.value() };
|
||||
|
||||
auto next_word_src = src_text.instruction_part;
|
||||
if (next_word_src != -1)
|
||||
|
@ -2153,7 +2229,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
work_values.push_back(src_text.work_value);
|
||||
|
||||
// destination
|
||||
auto dst_text { addressing_to_string(dst_register, (addr + src_text.length) & 65535, word_mode) };
|
||||
auto addressing_dst = addressing_to_string(dst_register, (addr + src_text.length) & 65535, word_mode);
|
||||
if (addressing_dst.has_value() == false)
|
||||
return { };
|
||||
auto dst_text { addressing_dst.value() };
|
||||
|
||||
auto next_word_dst = dst_text.instruction_part;
|
||||
if (next_word_dst != -1)
|
||||
|
@ -2304,7 +2383,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
text = format("TRAP %o", instruction & 255);
|
||||
|
||||
if ((instruction & ~0b111111) == 0b0000000001000000) {
|
||||
auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) };
|
||||
auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode);
|
||||
if (addressing.has_value() == false)
|
||||
return { };
|
||||
auto dst_text { addressing.value() };
|
||||
|
||||
auto next_word = dst_text.instruction_part;
|
||||
if (next_word != -1)
|
||||
|
@ -2316,7 +2398,10 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
|||
}
|
||||
|
||||
if ((instruction & 0b1111111000000000) == 0b0000100000000000) {
|
||||
auto dst_text { addressing_to_string(dst_register, (addr + 2) & 65535, word_mode) };
|
||||
auto addressing = addressing_to_string(dst_register, (addr + 2) & 65535, word_mode);
|
||||
if (addressing.has_value() == false)
|
||||
return { };
|
||||
auto dst_text { addressing.value() };
|
||||
|
||||
auto next_word = dst_text.instruction_part;
|
||||
if (next_word != -1)
|
||||
|
|
2
cpu.h
2
cpu.h
|
@ -105,7 +105,7 @@ private:
|
|||
uint16_t work_value;
|
||||
};
|
||||
|
||||
operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const;
|
||||
std::optional<operand_parameters> addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const;
|
||||
|
||||
void add_to_stack_trace(const uint16_t p);
|
||||
void pop_from_stack_trace();
|
||||
|
|
19
debugger.cpp
19
debugger.cpp
|
@ -431,6 +431,8 @@ void configure_disk(bus *const b, console *const cnsl)
|
|||
int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool instruction_only)
|
||||
{
|
||||
auto data = c->disassemble(pc);
|
||||
if (data.empty())
|
||||
return 2; // problem!
|
||||
|
||||
auto registers = data["registers"];
|
||||
auto psw = data["psw"][0];
|
||||
|
@ -933,11 +935,20 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
|||
|
||||
for(int i=0; i<n; i++) {
|
||||
uint32_t cur_addr = addr + i * 2;
|
||||
int val = parts[2] == "v" ? b->peek_word(c->getPSW_runmode(), cur_addr) : b->read_physical(cur_addr);
|
||||
uint16_t val = 0;
|
||||
|
||||
if (val == -1) {
|
||||
cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr));
|
||||
break;
|
||||
if (parts[2] == "v") {
|
||||
auto v = b->peek_word(c->getPSW_runmode(), cur_addr);
|
||||
|
||||
if (v.has_value() == false) {
|
||||
cnsl->put_string_lf(format("Can't read from %06o\n", cur_addr));
|
||||
break;
|
||||
}
|
||||
|
||||
val = v.value();
|
||||
}
|
||||
else {
|
||||
val = b->read_physical(cur_addr);
|
||||
}
|
||||
|
||||
if (n == 1)
|
||||
|
|
Loading…
Add table
Reference in a new issue