several addressing fixes for disassembler
This commit is contained in:
parent
da7df5db42
commit
4f21efdf57
2 changed files with 53 additions and 32 deletions
81
cpu.cpp
81
cpu.cpp
|
@ -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
2
cpu.h
|
@ -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:
|
||||||
|
|
Loading…
Add table
Reference in a new issue