Skip to content

Commit

Permalink
sanitized peek_word()
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertvanheusden committed Jun 24, 2024
1 parent d531407 commit ddf9080
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 41 deletions.
12 changes: 9 additions & 3 deletions breakpoint_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
7 changes: 3 additions & 4 deletions bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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 changes: 1 addition & 1 deletion bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class bus: public device
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);

Expand Down
12 changes: 9 additions & 3 deletions console_ncurses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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:");

Expand Down
135 changes: 110 additions & 25 deletions cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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) } };

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(b->peek_word(run_mode, get_register(reg)) & mask) };
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("@#%06o", next_word), 4, int(next_word), uint16_t(temp2.value() & mask) } };
}

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) };
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("%06o", (pc + next_word + 2) & 65535), 4, int(next_word), uint16_t(temp2.value() & mask) } };
}

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) };
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 { };

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(b->peek_word(run_mode, b->peek_word(run_mode, get_register(reg) + next_word)) & mask) };
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
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class cpu
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();
Expand Down
19 changes: 15 additions & 4 deletions debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit ddf9080

Please sign in to comment.