DIV, JMP & RTS fix
This commit is contained in:
parent
c761ff824d
commit
85327f0d6b
1 changed files with 31 additions and 20 deletions
51
cpu.cpp
51
cpu.cpp
|
@ -294,20 +294,14 @@ uint16_t cpu::getGAMAddress(const uint8_t mode, const int reg, const bool word_m
|
||||||
return getRegister(reg, prev_mode);
|
return getRegister(reg, prev_mode);
|
||||||
case 2:
|
case 2:
|
||||||
temp = getRegister(reg, prev_mode);
|
temp = getRegister(reg, prev_mode);
|
||||||
if (reg == 6 || reg == 7)
|
addRegister(reg, prev_mode, !word_mode || reg == 6 || reg == 7 ? 2 : 1);
|
||||||
addRegister(reg, prev_mode, 2);
|
|
||||||
else
|
|
||||||
addRegister(reg, prev_mode, word_mode ? 1 : 2);
|
|
||||||
return temp;
|
return temp;
|
||||||
case 3:
|
case 3:
|
||||||
temp = b -> readWord(getRegister(reg, prev_mode));
|
temp = b -> readWord(getRegister(reg, prev_mode));
|
||||||
addRegister(reg, prev_mode, 2);
|
addRegister(reg, prev_mode, 2);
|
||||||
return temp;
|
return temp;
|
||||||
case 4:
|
case 4:
|
||||||
if (reg == 6 || reg == 7)
|
addRegister(reg, prev_mode, !word_mode || reg == 6 || reg == 7 ? -2 : -1);
|
||||||
addRegister(reg, prev_mode, -2);
|
|
||||||
else
|
|
||||||
addRegister(reg, prev_mode, word_mode ? -1 : -2);
|
|
||||||
return getRegister(reg, prev_mode);
|
return getRegister(reg, prev_mode);
|
||||||
case 5:
|
case 5:
|
||||||
addRegister(reg, prev_mode, -2);
|
addRegister(reg, prev_mode, -2);
|
||||||
|
@ -496,25 +490,32 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
setPSW_v(true);
|
setPSW_v(true);
|
||||||
setPSW_c(true);
|
setPSW_c(true);
|
||||||
|
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg + 1);
|
int32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg + 1);
|
||||||
|
|
||||||
int32_t quot = R0R1 / divider;
|
int32_t quot = R0R1 / divider;
|
||||||
uint16_t rem = R0R1 % divider;
|
uint16_t rem = R0R1 % divider;
|
||||||
fprintf(stderr, "value: %d, divider: %d, gives: %d / %d\n", R0R1, divider, quot, rem);
|
fprintf(stderr, "value: %d, divider: %d, gives: %d / %d\n", R0R1, divider, quot, rem);
|
||||||
fprintf(stderr, "value: %o, divider: %o, gives: %o / %o\n", R0R1, divider, quot, rem);
|
fprintf(stderr, "value: %o, divider: %o, gives: %o / %o\n", R0R1, divider, quot, rem);
|
||||||
|
|
||||||
// TODO: handle results out of range
|
// 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, quot);
|
||||||
setRegister(reg + 1, rem);
|
setRegister(reg + 1, rem);
|
||||||
|
|
||||||
setPSW_n(quot < 0);
|
setPSW_v(false);
|
||||||
setPSW_z(quot == 0);
|
|
||||||
setPSW_v(quot > 32767 || quot < -32768);
|
|
||||||
setPSW_c(false);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1168,14 +1169,22 @@ bool cpu::misc_operations(const uint16_t instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((instr & ~0b111111) == 0b0000000001000000) { // JMP
|
if ((instr & ~0b111111) == 0b0000000001000000) { // JMP
|
||||||
int dst_mode = (instr >> 3) & 7, dst_reg = instr & 7;
|
int dst_mode = (instr >> 3) & 7;
|
||||||
bool word_mode = false;
|
|
||||||
setPC(getGAMAddress(dst_mode, dst_reg, word_mode, false));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((instr & 0b1111111000000000) == 0b0000100000000000) { // JSR
|
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);
|
uint16_t dst_value = getGAMAddress((instr >> 3) & 7, instr & 7, false, false);
|
||||||
|
|
||||||
// PUSH link
|
// PUSH link
|
||||||
|
@ -1193,11 +1202,13 @@ bool cpu::misc_operations(const uint16_t instr)
|
||||||
if ((instr & 0b1111111111111000) == 0b0000000010000000) { // RTS
|
if ((instr & 0b1111111111111000) == 0b0000000010000000) { // RTS
|
||||||
const int link_reg = instr & 7;
|
const int link_reg = instr & 7;
|
||||||
|
|
||||||
|
uint16_t v = popStack();
|
||||||
|
|
||||||
// MOVE link, PC
|
// MOVE link, PC
|
||||||
setPC(getRegister(link_reg, false));
|
setPC(getRegister(link_reg, false));
|
||||||
|
|
||||||
// POP link
|
// POP link
|
||||||
setRegister(link_reg, false, popStack());
|
setRegister(link_reg, false, v);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue