From f43f0a889ce195e12dc45307b3de38a9324107bf Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 1 Apr 2024 11:27:50 +0200 Subject: [PATCH] rework for PSW-access --- bus.cpp | 12 +++++++++--- bus.h | 2 ++ cpu.cpp | 13 ++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/bus.cpp b/bus.cpp index bd93541..d9a4741 100644 --- a/bus.cpp +++ b/bus.cpp @@ -487,8 +487,10 @@ memory_addresses_t bus::calculate_physical_address(const int run_mode, const uin { const uint8_t apf = a >> 13; // active page field - if ((MMR0 & 1) == 0) - return { a, apf, a, a }; + if ((MMR0 & 1) == 0) { + bool is_psw = a == ADDR_PSW; + return { a, apf, a, is_psw, a, is_psw }; + } uint32_t physical_instruction = pages[run_mode][0][apf].par * 64; uint32_t physical_data = pages[run_mode][1][apf].par * 64; @@ -506,7 +508,11 @@ memory_addresses_t bus::calculate_physical_address(const int run_mode, const uin if (get_use_data_space(run_mode) == false) physical_data = physical_instruction; - return { a, apf, physical_instruction, physical_data }; + uint32_t io_base = get_io_base(); + bool physical_instruction_is_psw = (physical_instruction - io_base + 0160000) == ADDR_PSW; + bool physical_data_is_psw = (physical_data - io_base + 0160000) == ADDR_PSW; + + return { a, apf, physical_instruction, physical_instruction_is_psw, physical_data, physical_data_is_psw }; } bool bus::get_use_data_space(const int run_mode) diff --git a/bus.h b/bus.h index 7899ce6..714e455 100644 --- a/bus.h +++ b/bus.h @@ -75,7 +75,9 @@ typedef struct { uint16_t virtual_address; uint8_t apf; // active page field uint32_t physical_instruction; + bool physical_instruction_is_psw; uint32_t physical_data; + bool physical_data_is_psw; } memory_addresses_t; typedef struct { diff --git a/cpu.cpp b/cpu.cpp index c10d80b..705ba69 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1272,15 +1272,16 @@ bool cpu::single_operand_instructions(const uint16_t instr) // calculate address in current address space auto a = getGAMAddress(dst_mode, dst_reg, wm_word); - set_flags = a.addr.value() != ADDR_PSW; - int prev_run_mode = getPSW_prev_runmode(); 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; + bool phys_psw = word_mode == wm_byte ? phys.physical_data_is_psw : phys.physical_instruction_is_psw; if (phys_a >= b->get_io_base()) { // read from previous space v = b->read(a.addr.value(), wm_word, rm_prev); + + set_flags = !phys_psw; } 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 @@ -1313,14 +1314,16 @@ bool cpu::single_operand_instructions(const uint16_t instr) else { auto a = getGAMAddress(dst_mode, dst_reg, wm_word); - set_flags = a.addr.value() != ADDR_PSW; - int prev_run_mode = getPSW_prev_runmode(); 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; + bool phys_psw = word_mode == wm_byte ? phys.physical_data_is_psw : phys.physical_instruction_is_psw; - if (phys_a >= b->get_io_base()) + if (phys_a >= b->get_io_base()) { b->write(a.addr.value(), wm_word, v, rm_prev); // put in '13/12' address space + + set_flags = phys_psw; + } else { mtpi_count++; 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);