diff --git a/my_modules/pcjs-client/bin/pcjs b/my_modules/pcjs-client/bin/pcjs index c82d198f5..410f6d817 100644 --- a/my_modules/pcjs-client/bin/pcjs +++ b/my_modules/pcjs-client/bin/pcjs @@ -245,12 +245,6 @@ function loadMachine(sFile) } console.log(obj['id'] + " object created"); - if (fDebug) { - /* - * TODO: Determine why a simple "console.log(obj)" call fails on the Video object - */ - console.log(JSON.stringify(obj)); - } aComponents[i].objects.push(obj); if (obj.type == "Debugger") { diff --git a/my_modules/pcjs-client/lib/chipset.js b/my_modules/pcjs-client/lib/chipset.js index 8a4d1bf16..0fe9bb932 100644 --- a/my_modules/pcjs-client/lib/chipset.js +++ b/my_modules/pcjs-client/lib/chipset.js @@ -38,6 +38,7 @@ if (typeof module !== 'undefined') { var web = require("../../shared/lib/weblib"); var Component = require("../../shared/lib/component"); var State = require("./state"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/computer.js b/my_modules/pcjs-client/lib/computer.js index bea44bb70..634cef180 100644 --- a/my_modules/pcjs-client/lib/computer.js +++ b/my_modules/pcjs-client/lib/computer.js @@ -74,6 +74,7 @@ if (typeof module !== 'undefined') { var Component = require("../../shared/lib/component"); var Bus = require("./bus"); var State = require("./state"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/cpu.js b/my_modules/pcjs-client/lib/cpu.js index b7349a94a..e7587f7d1 100644 --- a/my_modules/pcjs-client/lib/cpu.js +++ b/my_modules/pcjs-client/lib/cpu.js @@ -36,6 +36,7 @@ if (typeof module !== 'undefined') { var str = require("../../shared/lib/strlib"); var usr = require("../../shared/lib/usrlib"); var Component = require("../../shared/lib/component"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/disk.js b/my_modules/pcjs-client/lib/disk.js index 2f54b078d..52b424ed6 100644 --- a/my_modules/pcjs-client/lib/disk.js +++ b/my_modules/pcjs-client/lib/disk.js @@ -164,6 +164,7 @@ if (typeof module !== 'undefined') { var DiskAPI = require("../../shared/lib/diskapi"); var DumpAPI = require("../../shared/lib/dumpapi"); var Component = require("../../shared/lib/component"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/fdc.js b/my_modules/pcjs-client/lib/fdc.js index 73b2ccca0..d1d3e8628 100644 --- a/my_modules/pcjs-client/lib/fdc.js +++ b/my_modules/pcjs-client/lib/fdc.js @@ -41,6 +41,7 @@ if (typeof module !== 'undefined') { var Disk = require("./disk"); var Computer = require("./computer"); var State = require("./state"); + var Debugger = require("./debugger"); } /* diff --git a/my_modules/pcjs-client/lib/hdc.js b/my_modules/pcjs-client/lib/hdc.js index bb3bb8d2f..d7c2bc937 100644 --- a/my_modules/pcjs-client/lib/hdc.js +++ b/my_modules/pcjs-client/lib/hdc.js @@ -40,6 +40,7 @@ if (typeof module !== 'undefined') { var ChipSet = require("./chipset"); var Disk = require("./disk"); var State = require("./state"); + var Debugger = require("./debugger"); } /** @@ -2430,22 +2431,26 @@ HDC.prototype.readByte = function(drive, done, fAutoInc) */ if (done) { var hdc = this; - drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, false, function(sector, fAsync) { - var b = -1; - if ((drive.sector = sector)) { - drive.ibSector = 0; - /* - * We "pre-advance" bSector et al now, instead of waiting to advance it right before the seek(). - * This allows the initial call to readByte() to perform a seek without triggering an unwanted advance. - */ - hdc.advanceSector(drive); - b = drive.disk.read(drive.sector, drive.ibSector); - drive.ibSector += inc; - } else { - drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR; - } - done(b, fAsync); - }); + if (drive.disk) { + drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, false, function(sector, fAsync) { + if ((drive.sector = sector)) { + drive.ibSector = 0; + /* + * We "pre-advance" bSector et al now, instead of waiting to advance it right before the seek(). + * This allows the initial call to readByte() to perform a seek without triggering an unwanted advance. + */ + hdc.advanceSector(drive); + b = drive.disk.read(drive.sector, drive.ibSector); + drive.ibSector += inc; + } else { + drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR; + } + done(b, fAsync); + }); + return b; + } + drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR; + done(b, false); } return b; }; @@ -2487,9 +2492,11 @@ HDC.prototype.writeByte = function(drive, b) * hence the bSectorBias below. I could change how sector numbers are stored in the image, * but it seems preferable to keep the image format consistent and controller-independent. */ - drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, true, function(sector, fAsync) { - drive.sector = sector; - }); + if (drive.disk) { + drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, true, function(sector, fAsync) { + drive.sector = sector; + }); + } if (!drive.sector) { drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR; b = -1; diff --git a/my_modules/pcjs-client/lib/keyboard.js b/my_modules/pcjs-client/lib/keyboard.js index 3d5c23932..091dff3f5 100644 --- a/my_modules/pcjs-client/lib/keyboard.js +++ b/my_modules/pcjs-client/lib/keyboard.js @@ -39,6 +39,7 @@ if (typeof module !== 'undefined') { var ChipSet = require("./chipset"); var State = require("./state"); var CPU = require("./cpu"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/mem.js b/my_modules/pcjs-client/lib/mem.js index 7c867ca67..791695c3b 100644 --- a/my_modules/pcjs-client/lib/mem.js +++ b/my_modules/pcjs-client/lib/mem.js @@ -51,6 +51,7 @@ if (typeof module !== 'undefined') { var str = require("../../shared/lib/strlib"); var Component = require("../../shared/lib/component"); + var Debugger = require("./debugger"); } /** * @class DataView diff --git a/my_modules/pcjs-client/lib/mouse.js b/my_modules/pcjs-client/lib/mouse.js index 14c5dd258..68a5249d0 100644 --- a/my_modules/pcjs-client/lib/mouse.js +++ b/my_modules/pcjs-client/lib/mouse.js @@ -38,6 +38,7 @@ if (typeof module !== 'undefined') { var Component = require("../../shared/lib/component"); var SerialPort = require("./serial"); var State = require("./state"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/serial.js b/my_modules/pcjs-client/lib/serial.js index 5f0dad244..2324b9b37 100644 --- a/my_modules/pcjs-client/lib/serial.js +++ b/my_modules/pcjs-client/lib/serial.js @@ -36,6 +36,7 @@ if (typeof module !== 'undefined') { var web = require("../../shared/lib/weblib"); var Component = require("../../shared/lib/component"); var ChipSet = require("./chipset"); + var Debugger = require("./debugger"); var State = require("./state"); } diff --git a/my_modules/pcjs-client/lib/video.js b/my_modules/pcjs-client/lib/video.js index d4f507f1f..429be0957 100644 --- a/my_modules/pcjs-client/lib/video.js +++ b/my_modules/pcjs-client/lib/video.js @@ -102,6 +102,7 @@ if (typeof module !== 'undefined') { var ChipSet = require("./chipset"); var Keyboard = require("./keyboard"); var State = require("./state"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/x86cpu.js b/my_modules/pcjs-client/lib/x86cpu.js index 6dc7e31ff..e97abe0b4 100644 --- a/my_modules/pcjs-client/lib/x86cpu.js +++ b/my_modules/pcjs-client/lib/x86cpu.js @@ -46,6 +46,7 @@ if (typeof module !== 'undefined') { var X86Mods = require("./x86mods"); var X86OpXX = require("./x86opxx"); var X86Op0F = require("./x86op0f"); + var Debugger = require("./debugger"); } /** diff --git a/my_modules/pcjs-client/lib/x86seg.js b/my_modules/pcjs-client/lib/x86seg.js index 222919d9e..892b3c355 100644 --- a/my_modules/pcjs-client/lib/x86seg.js +++ b/my_modules/pcjs-client/lib/x86seg.js @@ -67,7 +67,7 @@ function X86Seg(cpu, sName, fProt) /** * loadReal(sel, fSuppress) * - * This is the default real-mode load() function. + * The default segment load() function for real-mode. * * @this {X86Seg} * @param {number} sel @@ -77,7 +77,7 @@ function X86Seg(cpu, sName, fProt) X86Seg.loadReal = function loadReal(sel, fSuppress) { this.sel = sel; - this.limit = 0xffff; // TODO: Consider NOT setting the limit field in real-mode (unless it's required for, say, LOADALL support?) + this.limit = 0xffff; this.cpl = this.dpl = 0; return this.base = sel << 4; }; @@ -85,8 +85,8 @@ X86Seg.loadReal = function loadReal(sel, fSuppress) /** * loadProt(sel, fSuppress) * - * This replaces the segment's default load() function whenever the segment is notified (eg, by the CPU's setProtMode() - * function) the processor is now in protected-mode. + * This replaces the segment's default load() function whenever the segment is notified via updateAccess() by the + * CPU's setProtMode() that the processor is now in protected-mode. * * Segments in protected-mode are referenced by selectors, which are indexes into descriptor tables (GDT, LDT, IDT) whose * descriptors are 4-word (8-byte) entries: diff --git a/my_modules/shared/lib/weblib.js b/my_modules/shared/lib/weblib.js index cf7790c70..99b1e1f5d 100644 --- a/my_modules/shared/lib/weblib.js +++ b/my_modules/shared/lib/weblib.js @@ -118,14 +118,6 @@ /* global window: true, setTimeout: false, clearTimeout: false, SITEHOST: false */ -/* - * We must defer loading the Component module until the function(s) requiring it are - * called; otherwise, we create an initialization cycle in which Component requires weblib - * and weblib requires Component. - * - * In an ideal world, weblib would not be dependent on Component, but we really want to use - * its logging functions. - */ if (typeof module !== 'undefined') { var Component; require("./defines"); @@ -135,6 +127,49 @@ if (typeof module !== 'undefined') { var web = {}; +/* + * We must defer loading the Component module until the function(s) requiring it are + * called; otherwise, we create an initialization cycle in which Component requires weblib + * and weblib requires Component. + * + * In an ideal world, weblib would not be dependent on Component, but we really want to use + * its I/O functions. The simplest solution is to create wrapper functions. + */ + +/** + * log(s, type) + * + * For diagnostic output only. DEBUG must be true (or "--debug" specified via the command-line) + * for Component.log() to display anything. + * + * @param {string} [s] is the message text + * @param {string} [type] is the message type + */ +web.log = function(s, type) +{ + if (typeof module !== 'undefined') { + if (!Component) Component = require("./component"); + } + Component.log(s, type); +}; + +/** + * notice(s, fPrintOnly, id) + * + * If Component.notice() calls web.alertUser(), it will fall back to web.log() if all else fails. + * + * @param {string} s is the message text + * @param {boolean} [fPrintOnly] + * @param {string} [id] is the caller's ID, if any + */ +web.notice = function(s, fPrintOnly, id) +{ + if (typeof module !== 'undefined') { + if (!Component) Component = require("./component"); + } + Component.notice(s, fPrintOnly, id); +}; + /** * loadResource(sURL, fAsync, data, componentNotify, fnNotify, pNotify) * @@ -188,11 +223,11 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti * from the local file system (ie, when using the "file:" protocol), we have to be a bit more "flexible". */ if (xmlHTTP.status == 200 || !xmlHTTP.status && sURLData.length && web.getHostProtocol() == "file:") { - Component.log("xmlHTTP.onreadystatechange(" + sURL + "): returned " + sURLData.length + " bytes"); + web.log("xmlHTTP.onreadystatechange(" + sURL + "): returned " + sURLData.length + " bytes"); } else { nErrorCode = xmlHTTP.status || -1; - Component.log("xmlHTTP.onreadystatechange(" + sURL + "): error code " + nErrorCode); + web.log("xmlHTTP.onreadystatechange(" + sURL + "): error code " + nErrorCode); } if (fnNotify) { if (!componentNotify) { @@ -212,12 +247,12 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti sData += p + '=' + encodeURIComponent(data[p]); } sData = sData.replace(/%20/g, '+'); - Component.log("web.loadResource(POST " + sURL + "): " + sData.length + " bytes"); + web.log("web.loadResource(POST " + sURL + "): " + sData.length + " bytes"); xmlHTTP.open("POST", sURL, fAsync); xmlHTTP.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlHTTP.send(sData); } else { - Component.log("web.loadResource(GET " + sURL + ")"); + web.log("web.loadResource(GET " + sURL + ")"); xmlHTTP.open("GET", sURL, fAsync); xmlHTTP.send(); } @@ -225,10 +260,10 @@ web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNoti if (!fAsync) { sURLData = xmlHTTP.responseText; if (xmlHTTP.status == 200) { - Component.log("web.loadResource(" + sURL + "): returned " + sURLData.length + " bytes"); + web.log("web.loadResource(" + sURL + "): returned " + sURLData.length + " bytes"); } else { nErrorCode = xmlHTTP.status || -1; - Component.log("web.loadResource(" + sURL + "): error code " + nErrorCode); + web.log("web.loadResource(" + sURL + "): error code " + nErrorCode); } if (fnNotify) { if (!componentNotify) { @@ -315,11 +350,7 @@ web.getUserAgent = function() */ web.alertUser = function(sMessage) { - if (window) { - window.alert(sMessage); - } else { - console.log(sMessage); - } + if (window) window.alert(sMessage); else web.log(sMessage); }; /** @@ -393,7 +424,7 @@ web.hasLocalStorage = function() { */ web.logLocalStorageError = function(e) { - Component.log(e.message, "localStorage error"); + web.log(e.message, "localStorage error"); }; /** @@ -504,13 +535,9 @@ web.isUserAgent = function(s) { if (window) { var userAgent = web.getUserAgent(); + web.log("agent: " + userAgent); /* - * Here's one case where we have to be careful with Component, because when isUserAgent() is called by - * the init code below, component.js hasn't been loaded yet. The simplest solution is to remove the call. - * - * if (Component) Component.log("agent: " + userAgent); - * - * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure + * Yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure * Compiler (v20130823) failing to detect the entire expression as a boolean. */ return (s == "iOS" && userAgent.match(/(iPod|iPhone|iPad)/) && userAgent.match(/AppleWebKit/) || s == "MSIE" && userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0))? true : false; @@ -596,7 +623,7 @@ web.onClickRepeat = function(e, msDelay, msRepeat, fn) } }; e.onmousedown = function() { - // Component.println("onMouseDown()"); + // web.log("onMouseDown()"); if (!fIgnoreMouseEvents) { if (!timer) { ms = msDelay; @@ -605,21 +632,21 @@ web.onClickRepeat = function(e, msDelay, msRepeat, fn) } }; e.ontouchstart = function() { - // Component.println("onTouchStart()"); + // web.log("onTouchStart()"); if (!timer) { ms = msDelay; fnRepeat(); } }; e.onmouseup = e.onmouseout = function() { - // Component.println("onMouseUp()/onMouseOut()"); + // web.log("onMouseUp()/onMouseOut()"); if (timer) { clearTimeout(timer); timer = null; } }; e.ontouchend = e.ontouchcancel = function() { - // Component.println("onTouchEnd()/onTouchCancel()"); + // web.log("onTouchEnd()/onTouchCancel()"); if (timer) { clearTimeout(timer); timer = null; @@ -722,7 +749,7 @@ web.doPageEvent = function(afn) afn[i](); } } catch(e) { - Component.notice("An unexpected exception occurred:\n\n" + e.message + "\n\nPlease send this information to Jeff@pcjs.org. Thanks."); + web.notice("An unexpected exception occurred:\n\n" + e.message + "\n\nPlease send this information to Jeff@pcjs.org. Thanks."); } } };