Improved DOS message output (use "m dos on" Debugger command)
This commit is contained in:
parent
75d8e1e193
commit
6295c112fe
6 changed files with 196 additions and 131 deletions
|
|
@ -1159,25 +1159,25 @@ if (DEBUGGER) {
|
|||
0x13: {
|
||||
0x00: "disk reset",
|
||||
0x01: "get status",
|
||||
0x02: "read drive DL (CH:DH:CL,AL) into ES:BX",
|
||||
0x03: "write drive DL (CH:DH:CL,AL) from ES:BX",
|
||||
0x04: "verify drive DL (CH:DH:CL,AL)",
|
||||
0x05: "format drive DL using ES:BX",
|
||||
0x08: "read drive DL parameters into ES:DI",
|
||||
0x15: "get drive DL DASD type",
|
||||
0x16: "get drive DL change line status",
|
||||
0x17: "set drive DL DASD type",
|
||||
0x18: "set drive DL media type"
|
||||
0x02: "read drive %DL (%CH:%DH:%CL,%AL) into %ES:%BX",
|
||||
0x03: "write drive %DL (%CH:%DH:%CL,%AL) from %ES:%BX",
|
||||
0x04: "verify drive %DL (%CH:%DH:%CL,%AL)",
|
||||
0x05: "format drive %DL using %ES:%BX",
|
||||
0x08: "read drive %DL parameters into %ES:%DI",
|
||||
0x15: "get drive %DL DASD type",
|
||||
0x16: "get drive %DL change line status",
|
||||
0x17: "set drive %DL DASD type",
|
||||
0x18: "set drive %DL media type"
|
||||
},
|
||||
0x15: {
|
||||
0x80: "open device",
|
||||
0x81: "close device",
|
||||
0x82: "program termination",
|
||||
0x83: "wait CX:DXus for event",
|
||||
0x83: "wait %CX:%DXus for event",
|
||||
0x84: "joystick support",
|
||||
0x85: "SYSREQ pressed",
|
||||
0x86: "wait CX:DXus",
|
||||
0x87: "move block (CX words)",
|
||||
0x86: "wait %CX:%DXus",
|
||||
0x87: "move block (%CX words)",
|
||||
0x88: "get extended memory size",
|
||||
0x89: "processor to virtual mode",
|
||||
0x90: "device busy loop",
|
||||
|
|
@ -1185,94 +1185,94 @@ if (DEBUGGER) {
|
|||
},
|
||||
0x21: {
|
||||
0x00: "terminate program",
|
||||
0x01: "read character (al) from stdin with echo",
|
||||
0x02: "write character DL to stdout",
|
||||
0x03: "read character (al) from stdaux", // eg, COM1
|
||||
0x04: "write character DL to stdaux", // eg, COM1
|
||||
0x05: "write character DL to stdprn", // eg, LPT1
|
||||
0x06: "direct console output (input if DL=FF)",
|
||||
0x01: "read character (AL) from stdin with echo",
|
||||
0x02: "write character #%DL to stdout",
|
||||
0x03: "read character (AL) from stdaux", // eg, COM1
|
||||
0x04: "write character #%DL to stdaux", // eg, COM1
|
||||
0x05: "write character #%DL to stdprn", // eg, LPT1
|
||||
0x06: "direct console output (input if %DL=FF)",
|
||||
0x07: "direct console input without echo",
|
||||
0x08: "read character (al) from stdin without echo",
|
||||
0x09: "write $-terminated string DS:DX to stdout",
|
||||
0x0A: "buffered input (ds:dx)", // byte 0 is maximum chars, byte 1 is number of previous characters, byte 2 is number of characters read
|
||||
0x08: "read character (AL) from stdin without echo",
|
||||
0x09: "write string $%DS:%DX to stdout",
|
||||
0x0A: "buffered input (DS:DX)", // byte 0 is maximum chars, byte 1 is number of previous characters, byte 2 is number of characters read
|
||||
0x0B: "get stdin status",
|
||||
0x0C: "flush buffer and read stdin", // AL is a function # (0x01, 0x06, 0x07, 0x08, or 0x0A)
|
||||
0x0C: "flush buffer and read stdin", // AL is a function # (0x01, 0x06, 0x07, 0x08, or 0x0A)
|
||||
0x0D: "disk reset",
|
||||
0x0E: "select default drive DL", // returns # of available drives in AL
|
||||
0x0F: "open file using fcb DS:DX", // DS:DX -> unopened File Control Block
|
||||
0x10: "close file using fcb DS:DX",
|
||||
0x11: "find first matching file using fcb DS:DX",
|
||||
0x12: "find next matching file using fcb DS:DX",
|
||||
0x13: "delete file using fcb DS:DX",
|
||||
0x14: "sequential read from file using fcb DS:DX",
|
||||
0x15: "sequential write to file using fcb DS:DX",
|
||||
0x16: "create or truncate file using fcb DS:DX",
|
||||
0x17: "rename file using fcb DS:DX",
|
||||
0x19: "get current default drive (al)",
|
||||
0x1A: "set disk transfer area (dta) DS:DX",
|
||||
0x0E: "select default drive %DL", // returns # of available drives in AL
|
||||
0x0F: "open file using FCB ^%DS:%DX", // DS:DX -> unopened File Control Block
|
||||
0x10: "close file using FCB ^%DS:%DX",
|
||||
0x11: "find first matching file using FCB ^%DS:%DX",
|
||||
0x12: "find next matching file using FCB ^%DS:%DX",
|
||||
0x13: "delete file using FCB ^%DS:%DX",
|
||||
0x14: "sequential read from file using FCB ^%DS:%DX",
|
||||
0x15: "sequential write to file using FCB ^%DS:%DX",
|
||||
0x16: "create or truncate file using FCB ^%DS:%DX",
|
||||
0x17: "rename file using FCB ^%DS:%DX",
|
||||
0x19: "get current default drive (AL)",
|
||||
0x1A: "set disk transfer area (DTA=%DS:%DX)",
|
||||
0x1B: "get allocation information for default drive",
|
||||
0x1C: "get allocation information for specific drive DL",
|
||||
0x1C: "get allocation information for specific drive %DL",
|
||||
0x1F: "get drive parameter block for default drive",
|
||||
0x21: "read random record from file using fcb DS:DX",
|
||||
0x22: "write random record to file using fcb DS:DX",
|
||||
0x23: "get file size using fcb DS:DX",
|
||||
0x24: "set random record number for fcb DS:DX",
|
||||
0x25: "set address DS:DX of interrupt vector AL",
|
||||
0x26: "create new program segment prefix (psp) at segment DX",
|
||||
0x27: "random block read from file using fcb DS:DX",
|
||||
0x28: "random block write to file using fcb DS:DX",
|
||||
0x29: "parse filename DS:SI into fcb ES:DI using AL",
|
||||
0x2A: "get system date (year=cx, mon=dh, day=dl)",
|
||||
0x2B: "set system date (year=CX, mon=DH, day=DL)",
|
||||
0x2C: "get system time (hour=ch, min=cl, sec=dh, 100ths=dl)",
|
||||
0x2D: "set system time (hour=CH, min=CL, sec=DH, 100ths=DL)",
|
||||
0x2E: "set verify flag AL",
|
||||
0x2F: "get disk transfer area address (es:bx)", // DOS 2.00+
|
||||
0x30: "get DOS version (al=major, ah=minor)",
|
||||
0x21: "read random record from file using FCB ^%DS:%DX",
|
||||
0x22: "write random record to file using FCB ^%DS:%DX",
|
||||
0x23: "get file size using FCB ^%DS:%DX",
|
||||
0x24: "set random record number for FCB ^%DS:%DX",
|
||||
0x25: "set address %DS:%DX of interrupt vector %AL",
|
||||
0x26: "create new PSP at segment %DX",
|
||||
0x27: "random block read from file using FCB ^%DS:%DX",
|
||||
0x28: "random block write to file using FCB ^%DS:%DX",
|
||||
0x29: "parse filename $%DS:%SI into FCB %ES:%DI using %AL",
|
||||
0x2A: "get system date (year=CX, mon=DH, day=DL)",
|
||||
0x2B: "set system date (year=%CX, mon=%DH, day=%DL)",
|
||||
0x2C: "get system time (hour=CH, min=CL, sec=DH, 100ths=DL)",
|
||||
0x2D: "set system time (hour=%CH, min=%CL, sec=%DH, 100ths=%DL)",
|
||||
0x2E: "set verify flag %AL",
|
||||
0x2F: "get disk transfer area (DTA=ES:BX)", // DOS 2.00+
|
||||
0x30: "get DOS version (AL=major, AH=minor)",
|
||||
0x31: "terminate and stay resident",
|
||||
0x32: "get drive parameter block (dpb=ds:bx) for drive DL",
|
||||
0x32: "get drive parameter block (DPB=DS:BX) for drive %DL",
|
||||
0x33: "extended break check",
|
||||
0x34: "get address (es:bx) of InDOS flag",
|
||||
0x35: "get address (es:bx) of interrupt vector AL",
|
||||
0x36: "get free disk space of drive DL",
|
||||
0x37: "get(0)/set(1) switch character DL (AL)",
|
||||
0x34: "get address (ES:BX) of InDOS flag",
|
||||
0x35: "get address (ES:BX) of interrupt vector %AL",
|
||||
0x36: "get free disk space of drive %DL",
|
||||
0x37: "get(0)/set(1) switch character %DL (%AL)",
|
||||
0x38: "get country-specific information",
|
||||
0x39: "create subdirectory DS:DX",
|
||||
0x3A: "remove subdirectory DS:DX",
|
||||
0x3B: "set current directory DS:DX",
|
||||
0x3C: "create or truncate file DS:DX with attributes CX",
|
||||
0x3D: "open existing file DS:DX with mode AL",
|
||||
0x3E: "close file BX",
|
||||
0x3F: "read CX bytes from file BX into buffer DS:DX",
|
||||
0x40: "write CX bytes to file BX from buffer DS:DX",
|
||||
0x41: "delete file DS:DX",
|
||||
0x42: "set position CX:DX of file BX relative to AL",
|
||||
0x43: "get(0)/set(1) attributes CX of file DS:DX (AL)",
|
||||
0x39: "create subdirectory $%DS:%DX",
|
||||
0x3A: "remove subdirectory $%DS:%DX",
|
||||
0x3B: "set current directory $%DS:%DX",
|
||||
0x3C: "create or truncate file $%DS:%DX with attributes %CX",
|
||||
0x3D: "open existing file $%DS:%DX with mode %AL",
|
||||
0x3E: "close file %BX",
|
||||
0x3F: "read %CX bytes from file %BX into buffer %DS:%DX",
|
||||
0x40: "write %CX bytes to file %BX from buffer %DS:%DX",
|
||||
0x41: "delete file $%DS:%DX",
|
||||
0x42: "set position %CX:%DX of file %BX relative to %AL",
|
||||
0x43: "get(0)/set(1) attributes %CX of file %DS:%DX (%AL)",
|
||||
0x44: "get device information (IOCTL)",
|
||||
0x45: "duplicate file handle BX",
|
||||
0x46: "force file handle CX to duplicate file handle BX",
|
||||
0x47: "get current directory (ds:si) for drive DL",
|
||||
0x48: "allocate memory segment with BX paragraphs",
|
||||
0x49: "free memory segment ES",
|
||||
0x4A: "resize memory segment ES to BX paragraphs",
|
||||
0x4B: "load program DS:DX using parameter block ES:BX",
|
||||
0x4C: "terminate with return code AL",
|
||||
0x4D: "get return code (al)",
|
||||
0x4E: "find first matching file DS:DX with attributes CX",
|
||||
0x45: "duplicate file handle %BX",
|
||||
0x46: "force file handle %CX to duplicate file handle %BX",
|
||||
0x47: "get current directory (DS:SI) for drive %DL",
|
||||
0x48: "allocate memory segment with %BX paragraphs",
|
||||
0x49: "free memory segment %ES",
|
||||
0x4A: "resize memory segment %ES to %BX paragraphs",
|
||||
0x4B: "load program $%DS:%DX using parameter block %ES:%BX",
|
||||
0x4C: "terminate with return code %AL",
|
||||
0x4D: "get return code (AL)",
|
||||
0x4E: "find first matching file $%DS:%DX with attributes %CX",
|
||||
0x4F: "find next matching file",
|
||||
0x50: "set current psp BX",
|
||||
0x51: "get current psp (bx)",
|
||||
0x52: "get system variables (es:bx)",
|
||||
0x53: "translate bpb DS:SI to dpb (es:bp)",
|
||||
0x54: "get verify flag (al)",
|
||||
0x55: "create child psp at segment DX",
|
||||
0x56: "rename file DS:DX to name ES:DI",
|
||||
0x57: "get(0)/set(1) file date DX and time CX (AL)",
|
||||
0x58: "get(0)/set(1) memory allocation strategy (AL)", // DOS 2.11+
|
||||
0x59: "get extended error information", // DOS 3.00+
|
||||
0x5A: "create temporary file DS:DX with attributes CX", // DOS 3.00+
|
||||
0x5B: "create file DS:DX with attributes CX", // DOS 3.00+ (doesn't truncate existing files like 0x3C)
|
||||
0x5C: "lock(0)/unlock(1) file BX region CX:DX length SI:DI (AL)" // DOS 3.00+
|
||||
0x50: "set current PSP %BX",
|
||||
0x51: "get current PSP (bx)",
|
||||
0x52: "get system variables (ES:BX)",
|
||||
0x53: "translate BPB %DS:%SI to DPB (ES:BP)",
|
||||
0x54: "get verify flag (AL)",
|
||||
0x55: "create child PSP at segment %DX",
|
||||
0x56: "rename file $%DS:%DX to $%ES:%DI",
|
||||
0x57: "get(0)/set(1) file date %DX and time %CX (%AL)",
|
||||
0x58: "get(0)/set(1) memory allocation strategy (%AL)", // DOS 2.11+
|
||||
0x59: "get extended error information", // DOS 3.00+
|
||||
0x5A: "create temporary file $%DS:%DX with attributes %CX", // DOS 3.00+
|
||||
0x5B: "create file $%DS:%DX with attributes %CX", // DOS 3.00+ (doesn't truncate existing files like 0x3C)
|
||||
0x5C: "lock(0)/unlock(1) file %BX region %CX:%DX length %SI:%DI (%AL)" // DOS 3.00+
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1672,7 +1672,7 @@ if (DEBUGGER) {
|
|||
*
|
||||
* @this {Debugger}
|
||||
* @param {{DbgAddr}} dbgAddr
|
||||
* @param {number|undefined} inc contains value to increment dbgAddr by (default is 1)
|
||||
* @param {number} [inc] contains value to increment dbgAddr by (default is 1)
|
||||
*/
|
||||
Debugger.prototype.incAddr = function(dbgAddr, inc)
|
||||
{
|
||||
|
|
@ -1716,25 +1716,27 @@ if (DEBUGGER) {
|
|||
};
|
||||
|
||||
/**
|
||||
* dumpSZ(dbgAddr, cchMax)
|
||||
* getSZ(dbgAddr, cchMax)
|
||||
*
|
||||
* Dump helper for zero-terminated strings.
|
||||
* Get zero-terminated (aka "ASCIIZ") string from dbgAddr. It also stops at the first '$', in case this is
|
||||
* a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.
|
||||
* Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {{DbgAddr}} dbgAddr
|
||||
* @param {number} [cchMax]
|
||||
* @param {number} [cchMax] (default is 256)
|
||||
* @return {string} (and dbgAddr advanced past the terminating zero)
|
||||
*/
|
||||
Debugger.prototype.dumpSZ = function(dbgAddr, cchMax)
|
||||
Debugger.prototype.getSZ = function(dbgAddr, cchMax)
|
||||
{
|
||||
var sChars = "";
|
||||
var s = "";
|
||||
cchMax = cchMax || 256;
|
||||
while (sChars.length < cchMax) {
|
||||
while (s.length < cchMax) {
|
||||
var b = this.getByte(dbgAddr, 1);
|
||||
if (!b) break;
|
||||
sChars += (b >= 32 && b < 128? String.fromCharCode(b) : ".");
|
||||
if (!b || b == 0x24) break;
|
||||
s += (b >= 32 && b < 128? String.fromCharCode(b) : ".");
|
||||
}
|
||||
return sChars;
|
||||
return s;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1765,7 +1767,7 @@ if (DEBUGGER) {
|
|||
var wPID = this.getShort(dbgAddr, 2);
|
||||
var wParas = this.getShort(dbgAddr, 5);
|
||||
if (bSig != 0x4D && bSig != 0x5A) break;
|
||||
this.println(this.hexOffset(0, sel) + ": '" + String.fromCharCode(bSig) + "' PID=" + str.toHexWord(wPID) + " LEN=" + str.toHexWord(wParas) + ' "' + this.dumpSZ(dbgAddr, 8) + '"');
|
||||
this.println(this.hexOffset(0, sel) + ": '" + String.fromCharCode(bSig) + "' PID=" + str.toHexWord(wPID) + " LEN=" + str.toHexWord(wParas) + ' "' + this.getSZ(dbgAddr, 8) + '"');
|
||||
sel += 1 + wParas;
|
||||
}
|
||||
};
|
||||
|
|
@ -2048,10 +2050,14 @@ if (DEBUGGER) {
|
|||
*
|
||||
* @this {Debugger}
|
||||
* @param {string} sReg
|
||||
* @return {number}
|
||||
* @param {number} [off] optional offset into sReg
|
||||
* @return {number} register index, or -1 if not found
|
||||
*/
|
||||
Debugger.prototype.getRegIndex = function(sReg) {
|
||||
return usr.indexOf(Debugger.REGS, sReg.toUpperCase());
|
||||
Debugger.prototype.getRegIndex = function(sReg, off) {
|
||||
off = off || 0;
|
||||
var i = usr.indexOf(Debugger.REGS, sReg.substr(off, 2).toUpperCase());
|
||||
if (i < 0 && sReg.length > 2) i = usr.indexOf(Debugger.REGS, sReg.substr(off, 3).toUpperCase());
|
||||
return i;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2200,11 +2206,55 @@ if (DEBUGGER) {
|
|||
* @return {string}
|
||||
*/
|
||||
Debugger.prototype.replaceRegs = function(s) {
|
||||
for (var iReg = 0; iReg < Debugger.REGS.length; iReg++) {
|
||||
var sReg = Debugger.REGS[iReg];
|
||||
if (s.indexOf(sReg) >= 0) {
|
||||
s = str.replaceAll(sReg, this.getRegValue(iReg), s);
|
||||
/*
|
||||
* Replace every %XX (or %XXX), where XX (or XXX) is a register, with the register's value.
|
||||
*/
|
||||
var i = 0;
|
||||
var b, sChar, sAddr, dbgAddr, sReplace;
|
||||
while ((i = s.indexOf('%', i)) >= 0) {
|
||||
var iReg = this.getRegIndex(s, i+1);
|
||||
if (iReg >= 0) {
|
||||
s = s.replace('%' + Debugger.REGS[iReg], this.getRegValue(iReg));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).
|
||||
*/
|
||||
i = 0;
|
||||
while ((i = s.indexOf('#', i)) >= 0) {
|
||||
sChar = s.substr(i+1, 2);
|
||||
b = str.parseInt(sChar, 16);
|
||||
if (b != null && b >= 32 && b < 128) {
|
||||
sReplace = '#' + sChar + " '" + String.fromCharCode(b) + "'";
|
||||
s = s.replace('#' + sChar, sReplace);
|
||||
i += sReplace.length;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.
|
||||
*/
|
||||
i = 0;
|
||||
while ((i = s.indexOf('$', i)) >= 0) {
|
||||
sAddr = s.substr(i+1, 9);
|
||||
dbgAddr = this.parseAddr(sAddr);
|
||||
sReplace = sAddr + ' "' + this.getSZ(dbgAddr) + '"';
|
||||
s = s.replace('$' + sAddr, sReplace);
|
||||
i += sReplace.length;
|
||||
}
|
||||
/*
|
||||
* Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.
|
||||
*/
|
||||
i = 0;
|
||||
while ((i = s.indexOf('^', i)) >= 0) {
|
||||
sAddr = s.substr(i+1, 9);
|
||||
dbgAddr = this.parseAddr(sAddr);
|
||||
this.incAddr(dbgAddr);
|
||||
sReplace = sAddr + ' "' + this.getSZ(dbgAddr, 11) + '"';
|
||||
s = s.replace('^' + sAddr, sReplace);
|
||||
i += sReplace.length;
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
|
@ -2277,9 +2327,9 @@ if (DEBUGGER) {
|
|||
var sFunc = (aFuncs && aFuncs[AH]) || "";
|
||||
if (sFunc) sFunc = ' ' + this.replaceRegs(sFunc);
|
||||
/*
|
||||
* For purposes of display only, rewind addr to the address of the responsible "INT n" instruction; we
|
||||
* know it's the two-byte "INT n" instruction because that's the only opcode handler that calls checkIntNotify()
|
||||
* at the moment.
|
||||
* For display purposes only, rewind addr to the address of the responsible "INT n" instruction;
|
||||
* we know it's the two-byte "INT n" instruction because that's the only opcode handler that calls
|
||||
* checkIntNotify() at the moment.
|
||||
*/
|
||||
addr -= 2;
|
||||
this.message("INT " + str.toHexByte(nInt) + ": AH=" + str.toHexByte(AH) + " @" + this.hexOffset(addr - this.cpu.segCS.base, this.cpu.getCS()) + sFunc);
|
||||
|
|
@ -3737,13 +3787,13 @@ if (DEBUGGER) {
|
|||
*
|
||||
* @this {Debugger}
|
||||
* @param {string|undefined} sAddr
|
||||
* @param {number|undefined} type is the address segment type, in case sAddr doesn't specify a segment
|
||||
* @param {number|undefined} [type] is the address segment type, in case sAddr doesn't specify a segment
|
||||
* @return {{DbgAddr}}
|
||||
*/
|
||||
Debugger.prototype.parseAddr = function(sAddr, type)
|
||||
{
|
||||
var dbgAddr;
|
||||
var dbgAddrNext = (type == Debugger.ADDR_DATA? this.dbgAddrNextData : this.dbgAddrNextCode);
|
||||
var dbgAddrNext = (type === Debugger.ADDR_CODE? this.dbgAddrNextCode : this.dbgAddrNextData);
|
||||
var off = dbgAddrNext.off, sel = dbgAddrNext.sel, addr = dbgAddrNext.addr;
|
||||
|
||||
if (sAddr !== undefined) {
|
||||
|
|
|
|||
|
|
@ -1279,13 +1279,13 @@ Disk.prototype.updateSector = function(file, pba, off)
|
|||
var cylinder, head, sector;
|
||||
if ((cylinder = this.aDiskData[iCylinder]) && (head = cylinder[iHead]) && (sector = head[iSector])) {
|
||||
this.assert(sector['sector'] == iSector +1);
|
||||
if (sector.file) {
|
||||
if (sector['file']) {
|
||||
if (DEBUG && this.messageEnabled()) {
|
||||
this.printMessage('"' + sector.file.sPath + '" cross-linked at offset ' + sector.file.offFile + ' with "' + file.sPath + '" at offset ' + off);
|
||||
this.printMessage('"' + sector['file'].sPath + '" cross-linked at offset ' + sector['file'].offFile + ' with "' + file.sPath + '" at offset ' + off);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
sector.file = file;
|
||||
sector['file'] = file;
|
||||
sector.offFile = off;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2114,7 +2114,16 @@ Disk.prototype.restore = function(deltas)
|
|||
*/
|
||||
Disk.prototype.toJSON = function()
|
||||
{
|
||||
var s = JSON.stringify(this.aDiskData);
|
||||
var s = JSON.stringify(this.aDiskData, function(key, value) {
|
||||
/*
|
||||
* If BACKTRACK support is enabled, we have to filter out any 'file' properties that may
|
||||
* be attached to the sector objects, lest we risk blowing the stack due to circular references.
|
||||
*/
|
||||
if (key == 'file') {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
s = s.replace(/,"length":512/gm, "").replace(/,"pattern":0/gm, "");
|
||||
/*
|
||||
* I don't really want to strip quotes from disk image property names, since I would have to put them
|
||||
|
|
|
|||
|
|
@ -1172,8 +1172,9 @@ FDC.prototype.autoMount = function(fRemount)
|
|||
*/
|
||||
var iDrive = sDrive.charCodeAt(0) - 0x41;
|
||||
if (iDrive >= 0 && iDrive < this.aDrives.length) {
|
||||
if (!this.loadDiskette(iDrive, configDrive['name'], configDrive['path'], true) && fRemount)
|
||||
if (!this.loadDiskette(iDrive, configDrive['name'], configDrive['path'], true) && fRemount) {
|
||||
this.setReady(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1523,11 +1523,16 @@ X86CPU.prototype.checkIntNotify = function(nInt)
|
|||
}
|
||||
}
|
||||
/*
|
||||
* The enabling of INT messages is one of the criteria that's also included in the Debugger's
|
||||
* checksEnabled() function, and therefore in fDebugCheck, so for maximum speed, we check fDebugCheck first.
|
||||
* The enabling of INT messages is one of the criteria that's also included in the Debugger's checksEnabled()
|
||||
* function, and therefore included in fDebugCheck, so for maximum speed, we check fDebugCheck first.
|
||||
*
|
||||
* NOTE: By wrapping this in MAXDEBUG, we're effectively eliminating the need for any checkIntReturn() calls;
|
||||
* onIntReturn() generates a lot of noise, via dbg.messageIntReturn(), and because there's no way to be be sure
|
||||
* we'll catch the return (or for some interrupts, *whether* they will return), it's safer to disable this
|
||||
* feature unless you really want it.
|
||||
*/
|
||||
if (DEBUGGER && this.aFlags.fDebugCheck) {
|
||||
if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(nInt, this.regLIP)) {
|
||||
if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(nInt, this.regLIP) && MAXDEBUG) {
|
||||
this.addIntReturn(this.regLIP, function(cpu, nCycles) {
|
||||
return function onIntReturn(nLevel) {
|
||||
cpu.dbg.messageIntReturn(nInt, nLevel, cpu.getCycles() - nCycles);
|
||||
|
|
|
|||
|
|
@ -1256,7 +1256,7 @@ X86.fnIRET = function IRET()
|
|||
if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
|
||||
if (this.setCSIP(newIP, newCS, false) != null) {
|
||||
this.setPS(newPS, cpl);
|
||||
if (this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
if (MAXDEBUG && this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1290,7 +1290,7 @@ X86.fnJMPFdw = function JMPFdw(dst, src)
|
|||
return X86.fnGRPUndefined.call(this, dst, src);
|
||||
}
|
||||
this.setCSIP(dst, this.getShort(this.regEA + this.dataSize));
|
||||
if (this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
if (MAXDEBUG && this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
this.nStepCycles -= this.cycleCounts.nOpCyclesJmpDM;
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
|
|
@ -2169,7 +2169,7 @@ X86.fnRETF = function RETF(n)
|
|||
this.segES.load(0);
|
||||
}
|
||||
}
|
||||
if (n == 2 && this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
if (MAXDEBUG && n == 2 && this.cIntReturn) this.checkIntReturn(this.regLIP);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,19 +37,19 @@ var str = {};
|
|||
/**
|
||||
* isValidInt(s, base)
|
||||
*
|
||||
* Since the built-in parseInt() function has the annoying feature of returning a partial value
|
||||
* when it encounters an invalid character (eg, parseInt("foo", 16) returns 0xf), use this function
|
||||
* to validate the entire string first.
|
||||
* The built-in parseInt() function has the annoying feature of returning a partial value (ie,
|
||||
* up to the point where it encounters an invalid character); eg, parseInt("foo", 16) returns 0xf.
|
||||
* So use this function to validate the entire string.
|
||||
*
|
||||
* @param {string} s is the string representation of some number
|
||||
* @param {number} [base] is the radix of the number represented above (only 10 and 16 are supported)
|
||||
* @return {boolean} true if valid (or we're not sure because the base isn't recognized), false if invalid
|
||||
* @return {boolean} true if valid, false if invalid (or the specified base isn't supported)
|
||||
*/
|
||||
str.isValidInt = function(s, base)
|
||||
{
|
||||
if (!base || base == 10) return s.match(/^[0-9]+$/) !== null;
|
||||
if (base == 16) return s.match(/^[0-9a-f]+$/i) !== null;
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -105,7 +105,7 @@ str.parseInt = function(s, base)
|
|||
* an exception, whereas toHex() will simply return '?' characters.
|
||||
*
|
||||
* NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,
|
||||
* taking care of negative values, zero-padding, and upper-casing, but not undefined/NaN values:
|
||||
* taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:
|
||||
*
|
||||
* s = (n < 0? n + 0x100000000 : n).toString(16);
|
||||
* s = "00000000".substr(0, 8 - s.length) + s;
|
||||
|
|
@ -312,7 +312,7 @@ str.replaceArray = function(a, s)
|
|||
/**
|
||||
* pad(s, cch)
|
||||
*
|
||||
* Note that the maximum amount of padding currently supported is 40 spaces.
|
||||
* NOTE: the maximum amount of padding currently supported is 40 spaces.
|
||||
*
|
||||
* @param {string} s is a string
|
||||
* @param {number} cch is desired length
|
||||
|
|
|
|||
Loading…
Reference in a new issue