Fixed the 8080's subByteBorrow(), and improved the Debugger's doDump()

This commit is contained in:
Jeff Parsons 2016-04-29 08:30:21 -07:00
commit a64a6e7e05
3 changed files with 31 additions and 23 deletions

View file

@ -848,7 +848,7 @@ CPUSim.prototype.subByte = function(src)
*/ */
CPUSim.prototype.subByteBorrow = function(src) CPUSim.prototype.subByteBorrow = function(src)
{ {
src = -(src + (this.resultZeroCarry & 0x100)? 1 : 0) & 0xff; src = -(src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff;
this.resultAuxOverflow = this.regA ^ src; this.resultAuxOverflow = this.regA ^ src;
return this.resultParitySign = (this.resultZeroCarry = (this.regA + src) ^ 0x100) & 0xff; return this.resultParitySign = (this.resultZeroCarry = (this.regA + src) ^ 0x100) & 0xff;
}; };

View file

@ -3523,7 +3523,8 @@ if (DEBUGGER) {
* var nPart = +sBytes; * var nPart = +sBytes;
* if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000); * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);
* *
* So, the best way to capture a large machine state is to run your own local server and use * So, the best way to capture a large machine state is to use the new "Save Machine" link
* that downloads a machine's entire state. Alternatively, run your own local server and use
* server-side storage. Take a look at the "Save" binding in computer.js, which binds an HTML * server-side storage. Take a look at the "Save" binding in computer.js, which binds an HTML
* control to the computer.powerOff() and computer.saveServerState() functions. * control to the computer.powerOff() and computer.saveServerState() functions.
*/ */
@ -3567,34 +3568,37 @@ if (DEBUGGER) {
var dbgAddr = this.parseAddr(sAddr); var dbgAddr = this.parseAddr(sAddr);
if (!dbgAddr) return; if (!dbgAddr) return;
var cb = 0; // 0 is not a default; it triggers the appropriate default below var len = 0; // 0 is not a default; it triggers the appropriate default below
if (sLen) { if (sLen) {
if (sLen.charAt(0) == 'l') { if (sLen.charAt(0) == 'l') {
sLen = sLen.substr(1) || sBytes; sLen = sLen.substr(1) || sBytes;
} }
cb = this.parseValue(sLen) >>> 0; // negative lengths not allowed len = this.parseValue(sLen) >>> 0; // negative lengths not allowed
if (cb > 0x10000) cb = 0x10000; // prevent bad user (or register) input from producing excessive output if (len > 0x10000) len = 0x10000; // prevent bad user (or variable) input from producing excessive output
} }
var sDump = ""; var sDump = "";
var cLines = (((cb || 128) + 15) >> 4) || 1;
var size = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1)); var size = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1));
for (var iLine = 0; iLine < cLines; iLine++) { var cb = (size * len) || 128;
var data = 0, iByte = 0; var cLines = ((cb + 15) >> 4) || 1;
while (cLines-- && cb > 0) {
var data = 0, iByte = 0, i;
var sData = "", sChars = ""; var sData = "", sChars = "";
sAddr = this.toHexAddr(dbgAddr); sAddr = this.toHexAddr(dbgAddr);
for (var i = 0; i < 16; i++) { for (i = 16; i > 0 && cb > 0; i--) {
var b = this.getByte(dbgAddr, 1); var b = this.getByte(dbgAddr, 1);
data |= (b << (iByte++ << 3)); data |= (b << (iByte++ << 3));
if (iByte == size) { if (iByte == size) {
sData += str.toHex(data, size * 2); sData += str.toHex(data, size * 2);
sData += (size == 1? (i == 7? '-' : ' ') : " "); sData += (size == 1? (i == 9? '-' : ' ') : " ");
data = iByte = 0; data = iByte = 0;
} }
sChars += (b >= 32 && b < 128? String.fromCharCode(b) : '.'); sChars += (b >= 32 && b < 128? String.fromCharCode(b) : '.');
cb--;
} }
if (sDump) sDump += '\n'; if (sDump) sDump += '\n';
sDump += sAddr + " " + sData + ' ' + sChars; sDump += sAddr + " " + sData + ((i == 0)? (' ' + sChars) : "");
} }
if (sDump) this.println(sDump); if (sDump) this.println(sDump);
@ -4292,7 +4296,7 @@ if (DEBUGGER) {
if (n > 2) { if (n > 2) {
dbgAddr.addr = addr; dbgAddr.addr = addr;
var s = this.getInstruction(dbgAddr); var s = this.getInstruction(dbgAddr);
if (s.indexOf("CALL") > 0) { if (s.indexOf("CALL") >= 0) {
/* /*
* Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT), * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),
* matches the original return address. We do this by getting the string index of the opcode bytes, * matches the original return address. We do this by getting the string index of the opcode bytes,

View file

@ -6434,7 +6434,8 @@ if (DEBUGGER) {
* var nPart = +sBytes; * var nPart = +sBytes;
* if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000); * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);
* *
* So, the best way to capture a large machine state is to run your own local server and use * So, the best way to capture a large machine state is to use the new "Save Machine" link
* that downloads a machine's entire state. Alternatively, run your own local server and use
* server-side storage. Take a look at the "Save" binding in computer.js, which binds an HTML * server-side storage. Take a look at the "Save" binding in computer.js, which binds an HTML
* control to the computer.powerOff() and computer.saveServerState() functions. * control to the computer.powerOff() and computer.saveServerState() functions.
*/ */
@ -6524,34 +6525,37 @@ if (DEBUGGER) {
var dbgAddr = this.parseAddr(sAddr); var dbgAddr = this.parseAddr(sAddr);
if (!dbgAddr || dbgAddr.sel == null && dbgAddr.addr == null) return; if (!dbgAddr || dbgAddr.sel == null && dbgAddr.addr == null) return;
var cb = 0; // 0 is not a default; it triggers the appropriate default below var len = 0; // 0 is not a default; it triggers the appropriate default below
if (sLen) { if (sLen) {
if (sLen.charAt(0) == 'l') { if (sLen.charAt(0) == 'l') {
sLen = sLen.substr(1) || sBytes; sLen = sLen.substr(1) || sBytes;
} }
cb = this.parseValue(sLen) >>> 0; // negative lengths not allowed len = this.parseValue(sLen) >>> 0; // negative lengths not allowed
if (cb > 0x10000) cb = 0x10000; // prevent bad user (or register) input from producing excessive output if (len > 0x10000) len = 0x10000; // prevent bad user (or variable) input from producing excessive output
} }
var sDump = ""; var sDump = "";
var cLines = (((cb || 128) + 15) >> 4) || 1;
var size = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1)); var size = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1));
for (var iLine = 0; iLine < cLines; iLine++) { var cb = (size * len) || 128;
var data = 0, iByte = 0; var cLines = ((cb + 15) >> 4) || 1;
while (cLines-- && cb > 0) {
var data = 0, iByte = 0, i;
var sData = "", sChars = ""; var sData = "", sChars = "";
sAddr = this.toHexAddr(dbgAddr); sAddr = this.toHexAddr(dbgAddr);
for (var i = 0; i < 16; i++) { for (i = 16; i > 0 && cb > 0; i--) {
var b = this.getByte(dbgAddr, 1); var b = this.getByte(dbgAddr, 1);
data |= (b << (iByte++ << 3)); data |= (b << (iByte++ << 3));
if (iByte == size) { if (iByte == size) {
sData += str.toHex(data, size * 2); sData += str.toHex(data, size * 2);
sData += (size == 1? (i == 7? '-' : ' ') : " "); sData += (size == 1? (i == 9? '-' : ' ') : " ");
data = iByte = 0; data = iByte = 0;
} }
sChars += (b >= 32 && b < 128? String.fromCharCode(b) : '.'); sChars += (b >= 32 && b < 128? String.fromCharCode(b) : '.');
cb--;
} }
if (sDump) sDump += '\n'; if (sDump) sDump += '\n';
sDump += sAddr + " " + sData + ' ' + sChars; sDump += sAddr + " " + sData + ((i == 0)? (' ' + sChars) : "");
} }
if (sDump) this.println(sDump); if (sDump) this.println(sDump);
@ -7656,7 +7660,7 @@ if (DEBUGGER) {
dbgAddr.off = off; dbgAddr.off = off;
dbgAddr.addr = null; dbgAddr.addr = null;
var s = this.getInstruction(dbgAddr); var s = this.getInstruction(dbgAddr);
if (s.indexOf("CALL") > 0 || fFar && s.indexOf("INT") > 0) { if (s.indexOf("CALL") >= 0 || fFar && s.indexOf("INT") >= 0) {
/* /*
* Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT), * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),
* matches the original return address. We do this by getting the string index of the opcode bytes, * matches the original return address. We do this by getting the string index of the opcode bytes,