DIV tweak (signed divisor) / RTI: clear TRAP flag
This commit is contained in:
parent
cc41de0d8a
commit
d020492384
3 changed files with 33 additions and 18 deletions
9
bus.cpp
9
bus.cpp
|
@ -523,6 +523,15 @@ memory_addresses_t bus::calculate_physical_address(const int run_mode, const uin
|
||||||
return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw };
|
return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bus::mmudebug(const uint16_t a)
|
||||||
|
{
|
||||||
|
for(int rm=0; rm<4; rm++) {
|
||||||
|
auto ma = calculate_physical_address(rm, a);
|
||||||
|
|
||||||
|
DOLOG(debug, true, "RM %d, a: %06o, apf: %d, PI: %08o (PSW: %d), PD: %08o (PSW: %d)", rm, ma.virtual_address, ma.apf, ma.physical_instruction, ma.physical_instruction_is_psw, ma.physical_data, ma.physical_data_is_psw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool bus::get_use_data_space(const int run_mode)
|
bool bus::get_use_data_space(const int run_mode)
|
||||||
{
|
{
|
||||||
return !!(MMR3 & di_ena_mask[run_mode]);
|
return !!(MMR3 & di_ena_mask[run_mode]);
|
||||||
|
|
2
bus.h
2
bus.h
|
@ -126,6 +126,8 @@ public:
|
||||||
uint16_t get_console_switches() { return console_switches; }
|
uint16_t get_console_switches() { return console_switches; }
|
||||||
void set_debug_mode() { console_switches |= 128; }
|
void set_debug_mode() { console_switches |= 128; }
|
||||||
|
|
||||||
|
void mmudebug(const uint16_t a);
|
||||||
|
|
||||||
uint16_t get_console_leds() { return console_leds; }
|
uint16_t get_console_leds() { return console_leds; }
|
||||||
|
|
||||||
void add_cpu (cpu *const c);
|
void add_cpu (cpu *const c);
|
||||||
|
|
40
cpu.cpp
40
cpu.cpp
|
@ -279,6 +279,7 @@ void cpu::setPSW(const uint16_t v, const bool limited)
|
||||||
{
|
{
|
||||||
if (limited) {
|
if (limited) {
|
||||||
// cannot replace the run-mode bits nor the set of registers
|
// cannot replace the run-mode bits nor the set of registers
|
||||||
|
// psw = (psw & ~0340) | (v & 0174340);
|
||||||
psw = (psw & 0177400) | (v & 037777);
|
psw = (psw & 0177400) | (v & 037777);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -653,7 +654,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (divider == 0177777 && R0R1 == 0x80000000) { // maximum negative value; too big
|
else if (divider == -1 && uint32_t(R0R1) == 0x80000000) { // maximum negative value; too big
|
||||||
setPSW_n(false);
|
setPSW_n(false);
|
||||||
setPSW_z(false);
|
setPSW_z(false);
|
||||||
setPSW_v(true);
|
setPSW_v(true);
|
||||||
|
@ -662,10 +663,8 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t quot = R0R1 / divider;
|
int32_t quot = R0R1 / divider;
|
||||||
uint16_t rem = R0R1 % divider;
|
int16_t rem = R0R1 % divider;
|
||||||
|
|
||||||
// TODO: handle results out of range
|
|
||||||
|
|
||||||
setPSW_n(quot < 0);
|
setPSW_n(quot < 0);
|
||||||
setPSW_z(quot == 0);
|
setPSW_z(quot == 0);
|
||||||
|
@ -1276,9 +1275,10 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
||||||
|
|
||||||
int prev_run_mode = getPSW_prev_runmode();
|
int prev_run_mode = getPSW_prev_runmode();
|
||||||
|
bool is_d = word_mode == wm_byte;
|
||||||
auto phys = b->calculate_physical_address(prev_run_mode, a.addr.value());
|
auto phys = b->calculate_physical_address(prev_run_mode, a.addr.value());
|
||||||
uint32_t phys_a = word_mode == wm_byte ? phys.physical_data : phys.physical_instruction;
|
uint32_t phys_a = is_d ? phys.physical_data : phys.physical_instruction;
|
||||||
bool phys_psw = word_mode == wm_byte ? phys.physical_data_is_psw : phys.physical_instruction_is_psw;
|
bool phys_psw = is_d ? phys.physical_data_is_psw : phys.physical_instruction_is_psw;
|
||||||
|
|
||||||
if (phys_a >= b->get_io_base()) {
|
if (phys_a >= b->get_io_base()) {
|
||||||
// read from previous space
|
// read from previous space
|
||||||
|
@ -1289,7 +1289,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
else {
|
else {
|
||||||
b->check_odd_addressing(phys_a, prev_run_mode, word_mode ? d_space : i_space, false); // TODO d/i space must depend on the check done in calculate_physical_address
|
b->check_odd_addressing(phys_a, prev_run_mode, word_mode ? d_space : i_space, false); // TODO d/i space must depend on the check done in calculate_physical_address
|
||||||
|
|
||||||
v = b->readPhysical(word_mode == wm_byte ? phys.physical_data : phys.physical_instruction);
|
v = b->readPhysical(is_d ? phys.physical_data : phys.physical_instruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,29 +1308,32 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
// always words: word_mode-bit is to select between MTPI and MTPD
|
// always words: word_mode-bit is to select between MTPI and MTPD
|
||||||
|
|
||||||
// retrieve word from '15/14'-stack
|
// retrieve word from '15/14'-stack
|
||||||
uint16_t v = popStack();
|
uint16_t v = popStack();
|
||||||
|
|
||||||
bool set_flags = true;
|
|
||||||
|
|
||||||
|
bool set_flags = true;
|
||||||
|
mtpi_count++;
|
||||||
if (dst_mode == 0)
|
if (dst_mode == 0)
|
||||||
setRegister(dst_reg, v, rm_prev);
|
setRegister(dst_reg, v, rm_prev);
|
||||||
else {
|
else {
|
||||||
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
int prev_run_mode = getPSW_prev_runmode();
|
||||||
|
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
||||||
|
|
||||||
int prev_run_mode = getPSW_prev_runmode();
|
b->mmudebug(a.addr.value());
|
||||||
|
|
||||||
|
bool is_d = word_mode == wm_byte;
|
||||||
auto phys = b->calculate_physical_address(prev_run_mode, a.addr.value());
|
auto phys = b->calculate_physical_address(prev_run_mode, a.addr.value());
|
||||||
uint32_t phys_a = word_mode == wm_byte ? phys.physical_data : phys.physical_instruction;
|
uint32_t phys_a = is_d ? phys.physical_data : phys.physical_instruction;
|
||||||
bool phys_psw = word_mode == wm_byte ? phys.physical_data_is_psw : phys.physical_instruction_is_psw;
|
bool phys_psw = is_d ? phys.physical_data_is_psw : phys.physical_instruction_is_psw;
|
||||||
|
|
||||||
if (phys_a >= b->get_io_base()) {
|
if (phys_a >= b->get_io_base()) {
|
||||||
|
DOLOG(debug, true, "%lu %06o MTP%c %06o: %06o (I/O: %o/%d)", mtpi_count, pc-2, is_d ? 'D' : 'I', a.addr.value(), v, phys_a, prev_run_mode);
|
||||||
b->write(a.addr.value(), wm_word, v, rm_prev); // put in '13/12' address space
|
b->write(a.addr.value(), wm_word, v, rm_prev); // put in '13/12' address space
|
||||||
|
|
||||||
set_flags = phys_psw;
|
set_flags = phys_psw;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mtpi_count++;
|
DOLOG(debug, true, "%lu %06o MTP%c %06o: %06o (physical: %o/%d)", mtpi_count, pc-2, is_d ? 'D' : 'I', a.addr.value(), v, phys_a, prev_run_mode);
|
||||||
DOLOG(debug, true, "%lu %06o MTP%c %06o: %06o (physical: %o)", mtpi_count, pc-2, word_mode == wm_byte ? 'D' : 'I', a.addr.value(), v, phys_a);
|
b->check_odd_addressing(phys_a, prev_run_mode, is_d ? d_space : i_space, true); // TODO d/i space must depend on the check done in calculate_physical_address
|
||||||
b->check_odd_addressing(phys_a, prev_run_mode, word_mode == wm_byte ? d_space : i_space, true); // TODO d/i space must depend on the check done in calculate_physical_address
|
|
||||||
b->writePhysical(phys_a, v);
|
b->writePhysical(phys_a, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1571,6 +1574,7 @@ bool cpu::misc_operations(const uint16_t instr)
|
||||||
case 0b0000000000000010: // RTI
|
case 0b0000000000000010: // RTI
|
||||||
setPC(popStack());
|
setPC(popStack());
|
||||||
setPSW(popStack(), !!getPSW_runmode());
|
setPSW(popStack(), !!getPSW_runmode());
|
||||||
|
psw &= ~020; // disable TRAP flag
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 0b0000000000000011: // BPT
|
case 0b0000000000000011: // BPT
|
||||||
|
|
Loading…
Add table
Reference in a new issue