page written bit only when written

double trap: use stack from 000004
This commit is contained in:
folkert van heusden 2022-06-24 20:03:32 +02:00
parent 88933e303c
commit 42fc44b206
5 changed files with 48 additions and 37 deletions

30
bus.cpp
View file

@ -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' : ' '); DOLOG(debug, !peek_only, "UNHANDLED read %o(%c)", a, word_mode ? 'B' : ' ');
// c -> busError();
return -1; return -1;
} }
@ -297,7 +295,6 @@ uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev,
return temp; return temp;
} }
void bus::setMMR0(int value) void bus::setMMR0(int value)
{ {
value &= ~(3 << 10); // bit 10 & 11 always read as 0 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) { 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); 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 &= ~14; // add current page
MMR0 |= apf << 1; //MMR0 |= apf << 1;
c->schedule_trap(004); // invalid access 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 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) { if ((MMR0 & 0160000) == 0) {
MMR0 &= 017777; 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 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) { if ((MMR0 & 0160000) == 0) {
MMR0 &= 017777; 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; 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); c->schedule_trap(04);
throw 3; 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 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); // 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)) { if ((pdr_cmp > pdr_len && direction == false) || (pdr_cmp < pdr_len && direction == true)) {
DOLOG(debug, !peek_only, "bus::calculate_physical_address::p_offset %o >= %o", p_offset, pdr_len); 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); DOLOG(debug, true, "TRAP(0250) (throw 4) on address %06o", a);
c->schedule_trap(0250); // invalid access 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; 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; throw 4;
} }

44
cpu.cpp
View file

@ -1645,11 +1645,6 @@ bool cpu::misc_operations(const uint16_t instr)
return false; return false;
} }
void cpu::busError()
{
trap(4);
}
void cpu::schedule_trap(const uint16_t vector) void cpu::schedule_trap(const uint16_t vector)
{ {
scheduled_trap = 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 // '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) 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; int processing_trap_depth = 0;
uint16_t before_psw = 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 { try {
processing_trap_depth++; processing_trap_depth++;
bool kernel_mode = psw >> 14;
if (processing_trap_depth >= 2) { 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) { if (processing_trap_depth >= 3) {
// TODO: halt? // TODO: halt?
@ -1678,22 +1680,22 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt)
else { else {
before_psw = getPSW(); before_psw = getPSW();
before_pc = getPC(); 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 // make sure the trap vector is retrieved from kernel space
psw &= 037777; // mask off 14/15 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)); setPC(b->readWord(vector + 0));
// switch to kernel mode & update 'previous mode' // 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); setPSW(new_psw, false);
// DOLOG(info, true, "R6: %06o, before PSW: %06o, new PSW: %06o", getRegister(6), before_psw, new_psw); // 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_psw);
pushStack(before_pc); pushStack(before_pc);
@ -2192,6 +2197,9 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
work_values_str.push_back(format("%06o", v)); work_values_str.push_back(format("%06o", v));
out.insert({ "work-values", work_values_str }); out.insert({ "work-values", work_values_str });
out.insert({ "MMR0", { format("%06o", b->getMMR0()) } });
out.insert({ "MMR2", { format("%06o", b->getMMR2()) } });
return out; return out;
} }

1
cpu.h
View file

@ -95,7 +95,6 @@ public:
void init_interrupt_queue(); void init_interrupt_queue();
void queue_interrupt(const uint8_t level, const uint8_t vector); 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 trap(uint16_t vector, const int new_ipl = -1, const bool is_interrupt = false);
void schedule_trap(const uint16_t vector); void schedule_trap(const uint16_t vector);

View file

@ -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 instruction = data["instruction-text"].at(0);
std::string MMR0 = data["MMR0"].at(0);
std::string MMR2 = data["MMR2"].at(0);
std::string result; std::string result;
if (instruction_only) 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() work_values.c_str()
); );
else 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[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, registers[6].c_str(), pc,
psw.c_str(), psw.c_str(),
instruction_values.c_str(), instruction_values.c_str(),
instruction.c_str(), instruction.c_str(),
work_values.c_str() MMR0.c_str(), MMR2.c_str()
); );
if (cnsl) if (cnsl)

View file

@ -1,3 +0,0 @@
// (C) 2018 by Folkert van Heusden
// Released under Apache License v2.0
void tests(cpu *const c);