Fixed fault generation on invalid memory accesses; PDP-11 BASIC now starts up!
This commit is contained in:
parent
22e24697fe
commit
5f05913036
9 changed files with 360 additions and 351 deletions
|
|
@ -667,7 +667,7 @@ Memory.prototype = {
|
|||
*/
|
||||
readNone: function readNone(off, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {
|
||||
this.dbg.message("attempt to read invalid block %" + str.toHex(this.addr), true);
|
||||
this.dbg.message("attempt to read invalid block %" + str.toHex(addr), true);
|
||||
}
|
||||
return 0xff;
|
||||
},
|
||||
|
|
@ -681,7 +681,7 @@ Memory.prototype = {
|
|||
*/
|
||||
writeNone: function writeNone(off, v, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {
|
||||
this.dbg.message("attempt to write " + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr), true);
|
||||
this.dbg.message("attempt to write " + str.toHexWord(v) + " to invalid block %" + str.toHex(addr), true);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -556,7 +556,7 @@ BusPDP11.prototype.unknownAccess = function(addr, fByte, data)
|
|||
* TODO: For 22-bit machines, let's display addr as a 3-byte value (for a total of 9 octal digits)
|
||||
*/
|
||||
this.dbg.printMessage("warning: unknown I/O access (" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(data, fByte?1:2) + ")", true, true);
|
||||
if (this.dbg.stopInstruction()) return 0;
|
||||
this.dbg.stopInstruction();
|
||||
}
|
||||
if (!this.nDisableFaults) {
|
||||
this.cpu.trap(PDP11.TRAP.BUS_ERROR, addr);
|
||||
|
|
@ -1255,18 +1255,20 @@ BusPDP11.prototype.addResetHandler = function(fnReset)
|
|||
};
|
||||
|
||||
/**
|
||||
* fault(addr)
|
||||
* fault(addr, access)
|
||||
*
|
||||
* Memory interface for signaling alignment errors.
|
||||
* Memory interface for signaling alignment errors, invalid memory
|
||||
*
|
||||
* @this {BusPDP11}
|
||||
* @param {number} addr
|
||||
* @param {number} [access] (for diagnostic purposes only)
|
||||
*/
|
||||
BusPDP11.prototype.fault = function(addr)
|
||||
BusPDP11.prototype.fault = function(addr, access)
|
||||
{
|
||||
if (!this.nDisableFaults) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.WARN)) {
|
||||
this.dbg.printMessage("memory fault on address " + this.dbg.toStrBase(addr), true, true);
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {
|
||||
this.dbg.printMessage("memory fault (" + access + ") on address " + this.dbg.toStrBase(addr), true, true);
|
||||
this.dbg.stopInstruction();
|
||||
}
|
||||
this.cpu.trap(PDP11.TRAP.BUS_ERROR, addr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1664,7 +1664,12 @@ if (DEBUGGER) {
|
|||
if (cpu.isRunning()) {
|
||||
cpu.setPC(this.cpu.getLastPC());
|
||||
this.stopCPU();
|
||||
throw -1; // TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop the instruction
|
||||
/*
|
||||
* TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop
|
||||
* the instruction. It's handy, but it also means that we no longer actually return true, so callers
|
||||
* of either stopInstruction() or undefinedInstruction() may have unreachable code paths.
|
||||
*/
|
||||
throw -1;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
@ -2091,8 +2096,8 @@ if (DEBUGGER) {
|
|||
|
||||
/*
|
||||
* If getOperand() returns an Array rather than a string, then the first element is the original
|
||||
* operand, and the second element contains an alternate representation of the operand (eg, target address,
|
||||
* memory contents, etc).
|
||||
* operand, and the second element contains an alternate representation of the operand (eg, target
|
||||
* address, memory contents, etc).
|
||||
*/
|
||||
if (typeof sOperand != "string") {
|
||||
sTarget = sOperand[1];
|
||||
|
|
@ -2278,7 +2283,7 @@ if (DEBUGGER) {
|
|||
/**
|
||||
* parseInstruction(sOp, sOperand, addr)
|
||||
*
|
||||
* TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation.
|
||||
* TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a sample implementation.
|
||||
*
|
||||
* @this {DebuggerPDP11}
|
||||
* @param {string} sOp
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ var PDP11 = {
|
|||
*/
|
||||
TRAP: {
|
||||
UNDEFINED: 0x00, // 000 (reserved)
|
||||
BUS_ERROR: 0x04, // 004 illegal instructions, bus errors, stack limit, illegal internal address, microbreak
|
||||
BUS_ERROR: 0x04, // 004 illegal instruction, unaligned address, invalid memory, stack limit, microbreak
|
||||
RESERVED: 0x08, // 010 reserved instructions
|
||||
BPT: 0x0C, // 014 BPT: breakpoint trap (trace)
|
||||
IOT: 0x10, // 020 IOT: input/output trap
|
||||
|
|
|
|||
|
|
@ -587,9 +587,10 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
readNone: function readNone(off, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {
|
||||
this.dbg.printMessage("attempt to read invalid block %" + str.toHex(this.addr), true);
|
||||
this.dbg.stopCPU();
|
||||
this.dbg.printMessage("attempt to read invalid address " + this.dbg.toStrBase(addr), true);
|
||||
this.dbg.stopInstruction();
|
||||
}
|
||||
this.bus.fault(addr, PDP11.ACCESS.READ);
|
||||
return 0xff;
|
||||
},
|
||||
/**
|
||||
|
|
@ -602,9 +603,10 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
writeNone: function writeNone(off, v, addr) {
|
||||
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {
|
||||
this.dbg.printMessage("attempt to write " + str.toHexWord(v) + " to invalid block %" + str.toHex(this.addr), true);
|
||||
this.dbg.stopCPU();
|
||||
this.dbg.printMessage("attempt to write " + this.dbg.toStrBase(v) + " to invalid addresses " + this.dbg.toStrBase(addr), true);
|
||||
this.dbg.stopInstruction();
|
||||
}
|
||||
this.bus.fault(addr, PDP11.ACCESS.WRITE);
|
||||
},
|
||||
/**
|
||||
* readWordDefault(off, addr)
|
||||
|
|
@ -653,7 +655,7 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
readWordMemory: function readWordMemory(off, addr) {
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.READ_WORD);
|
||||
}
|
||||
if (BYTEARRAYS) {
|
||||
return this.ab[off] | (this.ab[off + 1] << 8);
|
||||
|
|
@ -697,7 +699,7 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
writeWordMemory: function writeWordMemory(off, w, addr) {
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.WRITE_WORD);
|
||||
}
|
||||
if (BYTEARRAYS) {
|
||||
this.ab[off] = (w & 0xff);
|
||||
|
|
@ -807,7 +809,7 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
readWordBE: function readWordBE(off, addr) {
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.READ_WORD);
|
||||
}
|
||||
return this.dv.getUint16(off, true);
|
||||
},
|
||||
|
|
@ -822,7 +824,7 @@ MemoryPDP11.prototype = {
|
|||
readWordLE: function readWordLE(off, addr) {
|
||||
var w;
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.READ_WORD);
|
||||
}
|
||||
/*
|
||||
* TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset
|
||||
|
|
@ -875,7 +877,7 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
writeWordBE: function writeWordBE(off, w, addr) {
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.WRITE_WORD);
|
||||
}
|
||||
this.dv.setUint16(off, w, true);
|
||||
this.fDirty = true;
|
||||
|
|
@ -890,7 +892,7 @@ MemoryPDP11.prototype = {
|
|||
*/
|
||||
writeWordLE: function writeWordLE(off, w, addr) {
|
||||
if (PDP11.MEMFAULT && (off & 0x1)) {
|
||||
this.bus.fault(addr);
|
||||
this.bus.fault(addr, PDP11.ACCESS.WRITE_WORD);
|
||||
}
|
||||
/*
|
||||
* TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset
|
||||
|
|
|
|||
Loading…
Reference in a new issue