DIV, JMP & RTS fix

This commit is contained in:
folkert van heusden 2022-03-24 16:17:35 +01:00
parent c761ff824d
commit 85327f0d6b

43
cpu.cpp
View file

@ -294,20 +294,14 @@ uint16_t cpu::getGAMAddress(const uint8_t mode, const int reg, const bool word_m
return getRegister(reg, prev_mode);
case 2:
temp = getRegister(reg, prev_mode);
if (reg == 6 || reg == 7)
addRegister(reg, prev_mode, 2);
else
addRegister(reg, prev_mode, word_mode ? 1 : 2);
addRegister(reg, prev_mode, !word_mode || reg == 6 || reg == 7 ? 2 : 1);
return temp;
case 3:
temp = b -> readWord(getRegister(reg, prev_mode));
addRegister(reg, prev_mode, 2);
return temp;
case 4:
if (reg == 6 || reg == 7)
addRegister(reg, prev_mode, -2);
else
addRegister(reg, prev_mode, word_mode ? -1 : -2);
addRegister(reg, prev_mode, !word_mode || reg == 6 || reg == 7 ? -2 : -1);
return getRegister(reg, prev_mode);
case 5:
addRegister(reg, prev_mode, -2);
@ -496,7 +490,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
setPSW_v(true);
setPSW_c(true);
break;
return true;
}
int32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg + 1);
@ -508,13 +502,20 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
// TODO: handle results out of range
setPSW_n(quot < 0);
setPSW_z(quot == 0);
setPSW_c(false);
if (quot > 32767 || quot < -32768) {
setPSW_v(true);
return true;
}
setRegister(reg, quot);
setRegister(reg + 1, rem);
setPSW_n(quot < 0);
setPSW_z(quot == 0);
setPSW_v(quot > 32767 || quot < -32768);
setPSW_c(false);
setPSW_v(false);
return true;
}
@ -1168,14 +1169,22 @@ bool cpu::misc_operations(const uint16_t instr)
}
if ((instr & ~0b111111) == 0b0000000001000000) { // JMP
int dst_mode = (instr >> 3) & 7, dst_reg = instr & 7;
int dst_mode = (instr >> 3) & 7;
if (dst_mode == 0) // cannot jump to a register
trap(010);
else {
int dst_reg = instr & 7;
bool word_mode = false;
setPC(getGAMAddress(dst_mode, dst_reg, word_mode, false));
}
return true;
}
if ((instr & 0b1111111000000000) == 0b0000100000000000) { // JSR
const int link_reg = (instr >> 6) & 7;
int link_reg = (instr >> 6) & 7;
uint16_t dst_value = getGAMAddress((instr >> 3) & 7, instr & 7, false, false);
// PUSH link
@ -1193,11 +1202,13 @@ bool cpu::misc_operations(const uint16_t instr)
if ((instr & 0b1111111111111000) == 0b0000000010000000) { // RTS
const int link_reg = instr & 7;
uint16_t v = popStack();
// MOVE link, PC
setPC(getRegister(link_reg, false));
// POP link
setRegister(link_reg, false, popStack());
setRegister(link_reg, false, v);
return true;
}