several addressing fixes for disassembler

This commit is contained in:
folkert van heusden 2022-03-16 19:29:10 +01:00
parent da7df5db42
commit 4f21efdf57
2 changed files with 53 additions and 32 deletions

81
cpu.cpp
View file

@ -1117,11 +1117,13 @@ void cpu::busError()
setPC(b -> readWord(4)); setPC(b -> readWord(4));
} }
std::string cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc) std::pair<std::string, int> cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc)
{ {
assert(mode_register < 64); assert(mode_register < 64);
uint16_t next_word = b->readWord((pc + 2) & 65535); int pc_offset = 0;
uint16_t next_word = b->readWord(pc & 65535);
int reg = mode_register & 7; int reg = mode_register & 7;
@ -1135,47 +1137,48 @@ std::string cpu::addressing_to_string(const uint8_t mode_register, const uint16_
switch(mode_register >> 3) { switch(mode_register >> 3) {
case 0: case 0:
return reg_name; return { reg_name, 2 };
case 1: case 1:
return format("(%s)", reg_name.c_str()); return { format("(%s)", reg_name.c_str()), 2 };
case 2: case 2:
if (reg == 7) if (reg == 7)
return format("#%06o", next_word); return { format("#%06o!2", next_word), 4 };
return format("(%s)+", reg_name.c_str()); return { format("(%s)+", reg_name.c_str()), 2 };
case 3: case 3:
if (reg == 7) if (reg == 7)
return format("@#%06o", next_word); return { format("@#%06o|%x|%d!3", next_word, next_word, next_word), 4 };
return format("@(%s)+", reg_name.c_str()); return { format("@(%s)+", reg_name.c_str()), 2 };
case 4: case 4:
return format("-(%s)", reg_name.c_str()); return { format("-(%s)", reg_name.c_str()), 2 };
case 5: case 5:
return format("@-(%s)", reg_name.c_str()); return { format("@-(%s)", reg_name.c_str()), 2 };
case 6: case 6:
if (reg == 7) if (reg == 7)
return format("%06o", next_word); return { format("%06o!6a", (pc + next_word + 2) & 65535), 4 };
return format("o%o(%s)", next_word, reg_name.c_str()); return { format("o%o(%s)!6b", next_word, reg_name.c_str()), 4 };
case 7: case 7:
if (reg == 7) if (reg == 7)
return format("@%06o", next_word); return { format("@%06o!7a", next_word), 4 };
return format("@o%o(%s)", next_word, reg_name.c_str()); return { format("@o%o(%s)!7b", next_word, reg_name.c_str()), 4 };
} }
return "??"; return { "??", 0 };
} }
void cpu::disassemble() void cpu::disassemble()
{ {
#if !defined(ESP32)
uint16_t pc = getPC(); uint16_t pc = getPC();
uint16_t instruction = b->readWord(pc); uint16_t instruction = b->readWord(pc);
@ -1188,21 +1191,21 @@ void cpu::disassemble()
std::string text; std::string text;
std::string name; std::string name;
std::string space = " ";
std::string comma = ",";
uint8_t src_register = (instruction >> 6) & 63; uint8_t src_register = (instruction >> 6) & 63;
uint8_t dst_register = (instruction >> 0) & 63; uint8_t dst_register = (instruction >> 0) & 63;
std::string src_text; // ASH, ASHC, MUL, DIV
std::string dst_text = addressing_to_string(dst_register, pc + 2); // for single as src can have an extra operand as well
// TODO: 100000011 // TODO: 100000011
if (do_opcode == 0b000) { if (do_opcode == 0b000) {
dst_text = addressing_to_string(dst_register, pc); auto dst_text = addressing_to_string(src_register, pc);
// single_operand_instructions // single_operand_instructions
switch(so_opcode) { switch(so_opcode) {
case 0b00000011: case 0b00000011:
text = "SWAB " + dst_text; text = "SWAB " + dst_text.first;
break; break;
case 0b000101000: case 0b000101000:
@ -1275,10 +1278,11 @@ void cpu::disassemble()
} }
if (text.empty() && name.empty() == false) if (text.empty() && name.empty() == false)
text = name + word_mode_str + " " + dst_text; text = name + word_mode_str + space + dst_text.first;
} }
else if (do_opcode == 0b111) { else if (do_opcode == 0b111) {
src_text = format("R%d", (instruction >> 6) & 7); std::string src_text = format("R%d", (instruction >> 6) & 7);
auto dst_text = addressing_to_string(dst_register, pc);
switch(ado_opcode) { switch(ado_opcode) {
case 0: case 0:
@ -1302,12 +1306,12 @@ void cpu::disassemble()
break; break;
case 7: case 7:
text = std::string("SOB") + dst_text; text = std::string("SOB") + dst_text.first;
break; break;
} }
if (text.empty() && name.empty() == false) if (text.empty() && name.empty() == false)
text = name + " " + src_text + "," + dst_text; text = name + space + src_text + comma + dst_text.first;
} }
else { else {
switch(do_opcode) { switch(do_opcode) {
@ -1339,7 +1343,10 @@ void cpu::disassemble()
break; break;
} }
text = name + word_mode_str + " " + addressing_to_string(src_register, pc) + "," + dst_text; auto src_text = addressing_to_string(src_register, (pc + 2) & 65535);
auto dst_text = addressing_to_string(dst_register, (pc + src_text.second) & 65535);
text = name + word_mode_str + space + src_text.first + comma + dst_text.first;
} }
if (text.empty()) { // conditional branch instructions if (text.empty()) { // conditional branch instructions
@ -1410,7 +1417,7 @@ void cpu::disassemble()
} }
if (text.empty() && name.empty() == false) if (text.empty() && name.empty() == false)
text = name + " " + format("%06o", new_pc); text = name + space + format("%06o", new_pc);
} }
if (text.empty()) { if (text.empty()) {
@ -1467,11 +1474,17 @@ void cpu::disassemble()
if ((instruction >> 8) == 0b10001001) if ((instruction >> 8) == 0b10001001)
text = format("TRAP %d", instruction & 255); text = format("TRAP %d", instruction & 255);
if ((instruction & ~0b111111) == 0b0000000001000000) if ((instruction & ~0b111111) == 0b0000000001000000) {
text = std::string("JMP ") + dst_text; auto dst_text = addressing_to_string(src_register, pc);
if ((instruction & 0b1111111000000000) == 0b0000100000000000) text = std::string("JMP ") + dst_text.first;
text = std::string("JSR ") + dst_text; }
if ((instruction & 0b1111111000000000) == 0b0000100000000000) {
auto dst_text = addressing_to_string(src_register, pc);
text = std::string("JSR ") + dst_text.first;
}
if ((instruction & 0b1111111111111000) == 0b0000000010000000) if ((instruction & 0b1111111111111000) == 0b0000000010000000)
text = "RTS"; text = "RTS";
@ -1480,6 +1493,7 @@ void cpu::disassemble()
fprintf(stderr, "PC: %06o, SP: %06o, PSW: %d%d|%d|%d|%d%d%d%d%d, instr: %06o: %s\n", pc, sp[psw >> 14], fprintf(stderr, "PC: %06o, SP: %06o, PSW: %d%d|%d|%d|%d%d%d%d%d, instr: %06o: %s\n", pc, sp[psw >> 14],
psw >> 14, (psw >> 12) & 3, (psw >> 11) & 1, (psw >> 5) & 7, !!(psw & 16), !!(psw & 8), !!(psw & 4), !!(psw & 2), psw & 1, psw >> 14, (psw >> 12) & 3, (psw >> 11) & 1, (psw >> 5) & 7, !!(psw & 16), !!(psw & 8), !!(psw & 4), !!(psw & 2), psw & 1,
instruction, text.c_str()); instruction, text.c_str());
#endif
} }
bool cpu::step() bool cpu::step()
@ -1487,6 +1501,13 @@ bool cpu::step()
if (getPC() & 1) if (getPC() & 1)
busError(); busError();
if (getPC() == 03332) {
FILE *fh = fopen("debug.dat", "wb");
for(int i=0; i<256; i++)
fputc(b -> readByte(getPC() + i), fh);
fclose(fh);
}
disassemble(); disassemble();
b -> setMMR2(getPC()); b -> setMMR2(getPC());

2
cpu.h
View file

@ -39,7 +39,7 @@ private:
bool condition_code_operations(const uint16_t instr); bool condition_code_operations(const uint16_t instr);
bool misc_operations(const uint16_t instr); bool misc_operations(const uint16_t instr);
std::string addressing_to_string(const uint8_t mode_register, const uint16_t pc); std::pair<std::string, int> addressing_to_string(const uint8_t mode_register, const uint16_t pc);
void disassemble(); void disassemble();
public: public: