From 42fc44b206f017fa863f217e2e53bc6f08133f1a Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Fri, 24 Jun 2022 20:03:32 +0200 Subject: [PATCH] page written bit only when written double trap: use stack from 000004 --- bus.cpp | 30 +++++++++++++++++------------- cpu.cpp | 44 ++++++++++++++++++++++++++------------------ cpu.h | 1 - debugger.cpp | 7 +++++-- tests.h | 3 --- 5 files changed, 48 insertions(+), 37 deletions(-) delete mode 100644 tests.h diff --git a/bus.cpp b/bus.cpp index 4378d01..e264a14 100644 --- a/bus.cpp +++ b/bus.cpp @@ -278,8 +278,6 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, DOLOG(debug, !peek_only, "UNHANDLED read %o(%c)", a, word_mode ? 'B' : ' '); -// c -> busError(); - return -1; } @@ -297,7 +295,6 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, return temp; } - void bus::setMMR0(int value) { value &= ~(3 << 10); // bit 10 & 11 always read as 0 @@ -345,10 +342,11 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if ((a & 1) && word_mode == 0 && peek_only == false) { DOLOG(debug, true, "TRAP(004) (throw 5) on address %06o, page %d, run mode %d, MMR0 %06o, MMR2 %06o", a, apf, run_mode, MMR0, MMR2); - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + //MMR0 &= ~14; // add current page + //MMR0 |= apf << 1; c->schedule_trap(004); // invalid access @@ -375,7 +373,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c c->schedule_trap(0250); // invalid address - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I if ((MMR0 & 0160000) == 0) { MMR0 &= 017777; @@ -398,7 +397,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c c->schedule_trap(0250); // invalid address - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I if ((MMR0 & 0160000) == 0) { MMR0 &= 017777; @@ -435,21 +435,24 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= run_mode << 5; } - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I c->schedule_trap(04); throw 3; } - uint16_t pdr_len = ((pages[run_mode][0][apf].pdr >> 8) & 127) * 64; // TODO: D/I + // uint16_t pdr_len = ((pages[run_mode][0][apf].pdr >> 8) & 127) * 64; // TODO: D/I + uint16_t pdr_len = (pages[run_mode][0][apf].pdr >> 8) & 127; + uint16_t pdr_cmp = (a >> 6) & 127; bool direction = pages[run_mode][0][apf].pdr & 8; // TODO: D/I // DOLOG(debug, true, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][0][apf].pdr); - if ((p_offset > pdr_len && direction == false) || (p_offset < pdr_len && direction == true)) { - DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o >= %o", p_offset, pdr_len); + if ((pdr_cmp > pdr_len && direction == false) || (pdr_cmp < pdr_len && direction == true)) { + DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o versus %o direction %d", pdr_cmp, pdr_len, direction); DOLOG(debug, true, "TRAP(0250) (throw 4) on address %06o", a); c->schedule_trap(0250); // invalid access @@ -464,7 +467,8 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c MMR0 |= run_mode << 5; } - pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I + if (is_write) + pages[run_mode][0][apf].pdr |= 1 << 7; // TODO: D/I throw 4; } diff --git a/cpu.cpp b/cpu.cpp index e513721..cf2dbe6 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -1645,11 +1645,6 @@ bool cpu::misc_operations(const uint16_t instr) return false; } -void cpu::busError() -{ - trap(4); -} - void cpu::schedule_trap(const uint16_t vector) { scheduled_trap = vector; @@ -1658,7 +1653,7 @@ void cpu::schedule_trap(const uint16_t vector) // 'is_interrupt' is not correct naming; it is true for mmu faults and interrupts void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) { - DOLOG(debug, true, "*** CPU::TRAP ***"); + DOLOG(debug, true, "*** CPU::TRAP, MMR0: %06o, MMR2: %06o ***", b->getMMR0(), b->getMMR2()); int processing_trap_depth = 0; uint16_t before_psw = 0; @@ -1668,8 +1663,15 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) try { processing_trap_depth++; + bool kernel_mode = psw >> 14; + if (processing_trap_depth >= 2) { - vector = 4; + DOLOG(debug, true, "Trap depth %d", processing_trap_depth); + + if (kernel_mode) + vector = 4; + + setRegister(6, 04); if (processing_trap_depth >= 3) { // TODO: halt? @@ -1678,22 +1680,22 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) else { before_psw = getPSW(); before_pc = getPC(); + + if ((b->getMMR0() & 0160000) == 0 && vector != 4) { + b->setMMR2(vector); + b->addToMMR1(-2, 6); + b->addToMMR1(-2, 6); + } + + if (is_interrupt) + b->clearMMR0Bit(12); + else + b->setMMR0Bit(12); // it's a trap } // make sure the trap vector is retrieved from kernel space psw &= 037777; // mask off 14/15 - if ((b->getMMR0() & 0160000) == 0 && vector != 4) { - b->setMMR2(vector); - b->addToMMR1(-2, 6); - b->addToMMR1(-2, 6); - } - - if (is_interrupt) - b->clearMMR0Bit(12); - else - b->setMMR0Bit(12); // it's a trap - setPC(b->readWord(vector + 0)); // switch to kernel mode & update 'previous mode' @@ -1704,6 +1706,9 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) setPSW(new_psw, false); // DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); + // + if (processing_trap_depth >= 2 && kernel_mode) + setRegister(6, 04); pushStack(before_psw); pushStack(before_pc); @@ -2192,6 +2197,9 @@ std::map > cpu::disassemble(const uint16_t work_values_str.push_back(format("%06o", v)); out.insert({ "work-values", work_values_str }); + out.insert({ "MMR0", { format("%06o", b->getMMR0()) } }); + out.insert({ "MMR2", { format("%06o", b->getMMR2()) } }); + return out; } diff --git a/cpu.h b/cpu.h index 295d92c..00ced1b 100644 --- a/cpu.h +++ b/cpu.h @@ -95,7 +95,6 @@ public: void init_interrupt_queue(); void queue_interrupt(const uint8_t level, const uint8_t vector); - void busError(); void trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false); void schedule_trap(const uint16_t vector); diff --git a/debugger.cpp b/debugger.cpp index 88c58a2..66e7076 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -28,6 +28,9 @@ int disassemble(cpu *const c, console *const cnsl, const int pc, const bool inst std::string instruction = data["instruction-text"].at(0); + std::string MMR0 = data["MMR0"].at(0); + std::string MMR2 = data["MMR2"].at(0); + std::string result; if (instruction_only) @@ -38,13 +41,13 @@ int disassemble(cpu *const c, console *const cnsl, const int pc, const bool inst work_values.c_str() ); else - result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s, instr: %s: %s - %s", + result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s, instr: %s: %s - MMR0/2: %s/%s", registers[0].c_str(), registers[1].c_str(), registers[2].c_str(), registers[3].c_str(), registers[4].c_str(), registers[5].c_str(), registers[6].c_str(), pc, psw.c_str(), instruction_values.c_str(), instruction.c_str(), - work_values.c_str() + MMR0.c_str(), MMR2.c_str() ); if (cnsl) diff --git a/tests.h b/tests.h deleted file mode 100644 index 163bd5c..0000000 --- a/tests.h +++ /dev/null @@ -1,3 +0,0 @@ -// (C) 2018 by Folkert van Heusden -// Released under Apache License v2.0 -void tests(cpu *const c);