More build option groundwork

This commit is contained in:
Jeff Parsons 2016-02-10 17:52:50 -08:00
commit 7913ef2a0a
7 changed files with 111 additions and 35 deletions

View file

@ -1 +1 @@
<div id="{{ include.id }}"></div>
<div class="pcbuild" id="{{ include.id }}"></div>

View file

@ -142,10 +142,10 @@ FOOTBALL Design Document
---
The following text is from an email titled "3xBox Design Document" sent to the
*football* alias on Saturday, February 28, 1987, at 5:02pm.
### Overview
Microsoft *football* alias on Saturday, February 28, 1987, at 5:02pm.
Overview
--------
The goal for this research project was to demonstrate the feasability of
supporting multiple virtual DOS 3.x machines on a 286DOS-based kernel running
on an 386 personal computer. Each "3xBox" would have its own virtual screen,
@ -174,8 +174,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
Unless stated otherwise, most of the concepts extant in 286DOS apply to 386DOS.
### V86 Mode and the 386
V86 Mode and the 386
----------------------
The 386 CPU has three distinct execution modes: REAL, PROT, and V86. REAL
and PROT modes are largely compatible with the corresponding modes of an 286.
V86 modes is exactly the same as RING 3 PROT mode, with the following
@ -203,8 +203,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
sensitive.
This allows the OS to simulate the Interrupt Flag, if desired.
### V86 IRETD Frame
V86 IRETD Frame
---------------
When any interrupt, trap, exception, or fault occurs in V86 mode, the CPU
switches to PROT mode and switches to the TSS Ring 0 Stack and builds the
following stack frame:
@ -219,8 +219,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
(0) (old CS)
(old EIP) <- (SS:SP)
### CPU Mode Determination
CPU Mode Determination
----------------------
A new implementation of the WHATMODE macro was written in order to distinguish
between the three CPU modes: REAL, PROT, and V86. REAL mode is indicated by
a 0 PE bit in CR0 (a.k.a. MSW on a 286). If the PE bit is 1, then the mode
@ -230,8 +230,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
be changed. So, we change IOPL and then check to see if it changed. If so,
PROT mode, else V86 mode.
### CPU Mode Switching
CPU Mode Switching
------------------
The 286DOS kernel relies extensively on switching inbetween REAL and PROT.
This functionality is provided by the RealMode and ProtMode routines.
In 386DOS, RealMode is no longer needed. As soon as we switch to PROT mode
@ -256,28 +256,28 @@ The following text is from an email titled "3xBox Design Document" sent to the
the caller. NOTE: V86 Services is also used for completing the 386 LOADALL
used by PhysToVirt to map "high" memory in "REAL" mode.
### Stack Switching
Stack Switching
---------------
In order to maintain the 286DOS mode switch and stack switch semantics
when V86 mode is used, we have a new stack (the V86 Stack) in the 3xBox PTDA.
### 286DOS Modes and Stacks
286DOS Modes and Stacks
-----------------------
The RealMode and ProtMode procedures in 286DOS are the only ways to switch
the CPU execution mode. These routines both maintain SS:SP, allowing
RealMode and ProtMode to be reentrant. The TSS Ring 0 stack is always the
current TCB stack in the current PTDA. The only other stacks in the system
are the Interrupt Stack and user stack(s).
### 386DOS Modes and Stacks
386DOS Modes and Stacks
-----------------------
In 386DOS, any interrupt or exception while in V86 mode causes a switch to
PROT mode and the TSS Ring 0 Stack. So we have a new way to mode switch with
an incompatible stack semantic. We had to fix this mode switch to make it
compatible with 286DOS.
### Observation
Observation
-----------
In V86 mode, the current stack must not be the TSS Ring 0 Stack. The CPU
only leaves V86 mode via an interrupt/exception, which causes a stack switch
to the TSS Ring 0 Stack. If the current stack was the same as the TSS Ring 0
@ -285,8 +285,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
the PTDA. Since we run on this stack in V86 mode, we need a new Ring 0 stack
when a 3xBox is running.
### Approach
Approach
--------
1) When a PMBox is running, the TSS Ring 0 Stack is a PTDA TCB stack.
+ This is consistent with the 286DOS model.
@ -298,8 +298,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
+ Otherwise, copy the V86 IRETD frame to the previous stack and
switch back to the previous stack.
### Details
Details
-------
1) Leaving V86 mode
a. V86ToProt (analog of ProtMode)
+ Issue special V86ToProt software interrupt. If the interrupt
@ -341,8 +341,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
+ Execute 386 LOADALL with VM bit set in EFLAGS image in loadall
buffer.
### Interrupt Management
Interrupt Management
--------------------
All software interrupts, hardware interrupts, and CPU traps and exceptions
are vectored through a common IDT, regardless of whether the CPU is in PROT
or V86 mode.
@ -352,8 +352,8 @@ The following text is from an email titled "3xBox Design Document" sent to the
keyboard and mouse (since those are implicitly for the foreground box),
can be given to background 3xBoxes.
### Passing Hardware Interrupts to the Foreground 3xBox
Passing Hardware Interrupts to the Foreground 3xBox
---------------------------------------------------
In the interrupt manager:
IF a 3xBox is foreground -AND-

View file

@ -1210,10 +1210,10 @@ function lr(a,b,c){for(var d=hb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]
h.Wf=function(a){void 0===a&&(a=this.Oc||(this.O?1:ir));if(!this.C){this.C++;var b=!1,c=!1;this.da=!1;var d=this.ia||new bf(this,kr);if(-1==a)b=!0;else if(a>ir){if(d.load(this.O)){this.R=new bf(this,kr,"failsafe");this.R.load()&&(nr(this,d),a=2,dr(this.R));cf(this.R,"timestamp",ta());er(this.R);var e=this.Oc&&!this.P;if(1==a||Ca("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=fr(d)){var f=gr(d,"code"),g=gr(d,"data");f&&("ok"==f?d.load(g):("error"==f&&
"no machine state"!=g?(this.Va("Error: "+g),"unable to verify user"==g&&(Ha("user",""),this.A=null)):this.S(f+": "+g),dr(d),d.load()?(c=fr(d),e=!0):c=!1))}e&&mr(this,c?d:null)}else 2==a&&d.clear()}else mr(this);delete this.O;delete this.ia}e=hb(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.M&&(c=or(this,g,d,b,c));b=[d,a,c];-1!=a?lr(this,this.Ki,b):this.Ki(b)}};
function or(a,b,c,d,e){if(!b.ra.hc){b.ra.hc=!0;if(b.lc){var f=null;e&&((f=gr(c,b.id))||(f=gr(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.lc(f,d)&&f&&(Ba("Unable to restore state for "+b.type),a.X&&!a.ka?(c.clear(),a.Oc=ir,window&&window.location.reload()):a.da=!0,b.lc(null),e=!1)}if(!d&&b.sk)for(a=b.sk.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
h.Ki=function(a){var b=a[0],c=0>a[1];a=a[2];this.ra.hc=!0;var d=this.ya.power;d&&(d.textContent="On");this.tk||(this.S("PCjs v"+kr+"\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>"),this.tk=!0);this.M&&(or(this,this.M,b,c,a),Xc(this.M));this.da&&(nr(this,b),b.clear());!c&&this.R&&(this.R.clear(),delete this.R);this.C=0};
h.Ki=function(a){var b=a[0],c=0>a[1];a=a[2];this.ra.hc=!0;var d=this.ya.power;d&&(d.textContent="Shutdown");this.tk||(this.S("PCjs v"+kr+"\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>"),this.tk=!0);this.M&&(or(this,this.M,b,c,a),Xc(this.M));this.da&&(nr(this,b),b.clear());!c&&this.R&&(this.R.clear(),delete this.R);this.C=0};
function nr(a,b){if(Ca("There may be a problem with your PCjs machine.\n\nTo help us diagnose it, click OK to send this PCjs machine state to http://www.pcjs.org.")){var c=a.qa,d=a.ie(),e=b.toString(),f={app:"PCjs"};f.ver=kr;f.url=c;f.user=d;f.type="bug";f.data=e;za("http://www.pcjs.org/api/v1/report",!0,f)}}
function br(a,b,c){var d,e="none";if(a.C)return null;a.C--;var f=new bf(a,kr),g=new bf(a,kr,"validate"),k=ta();cf(g,"timestamp",k);cf(f,"timestamp",k);cf(f,"version","1.20.9");cf(f,"url",window?window.location.href:null);cf(f,"browser",window?window.navigator.userAgent:"");a.M&&a.M.kc&&(c&&a.M.bc(),d=a.M.kc(b,c),"object"===typeof d&&cf(f,a.M.id,d),c&&(a.M.ra.hc=!1,!1===d&&(e=null)));for(var k=hb(a.id),q=0;q<k.length;q++){var r=k[q];r.ra.hc&&(r.kc&&(d=r.kc(b,c),"object"===typeof d&&cf(f,r.id,d)),c&&
(r.ra.hc=!1,!1===d&&(e=null)))}e&&(c?(k=d=!1,b?(a.A&&pr(a,a.A,f.toString()),er(g)&&er(f)||(e=null,d=k=!0)):a.Oc&&(d=!0,k=3==a.Oc),d&&f.clear(k)):e=f.toString());c&&(a.ra.hc=!1,b=a.ya.power)&&(b.textContent="Off");a.C=0;return e}h.reset=function(){this.ja&&this.ja.reset&&(qb(this,"Resetting "+this.ja.type),this.ja.reset());for(var a=hb(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ja&&c.reset&&(qb(this,"Resetting "+c.type),c.reset())}};
(r.ra.hc=!1,!1===d&&(e=null)))}e&&(c?(k=d=!1,b?(a.A&&pr(a,a.A,f.toString()),er(g)&&er(f)||(e=null,d=k=!0)):a.Oc&&(d=!0,k=3==a.Oc),d&&f.clear(k)):e=f.toString());c&&(a.ra.hc=!1,b=a.ya.power)&&(b.textContent="Power");a.C=0;return e}h.reset=function(){this.ja&&this.ja.reset&&(qb(this,"Resetting "+this.ja.type),this.ja.reset());for(var a=hb(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.ja&&c.reset&&(qb(this,"Resetting "+c.type),c.reset())}};
h.start=function(a,b){for(var c=hb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}};h.stop=function(a,b){for(var c=hb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}};
h.Ub=function(a,b,c){var d=this;switch(b){case "power":return this.ya[b]=c,c.onclick=function(){d.C||(d.ra.hc?br(d,!1,!0):lr(d,d.Wf))},!0;case "reset":return this.ya[b]=c,c.onclick=function(){if(d.ra.hc&&!d.C)if(d.Oc&&!d.Eg){var a=Ca("Click OK to save changes to this PCjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");br(d,a,!0);!a&&d.X?window&&window.location.reload():(a||(d.gh=!0),d.Wf(ir),d.gh=!1)}else d.reset(),d.M&&Xc(d.M)},!0;case "save":return this.ya[b]=c,c.onclick=
function(){var a=jr(d,!0);if(a){var b=!!(d.Oc&&!d.Eg||d.X),c=br(d,b);b?pr(d,a,c):d.Va("Resume disabled, machine state not saved")}},!0}return!1};function jr(a,b){var c=a.A;c||(c=Ga("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=qr(a,c))||a.Va("The user ID is invalid."))):b&&a.Va("Browser local storage is not available"));return c}

View file

@ -1029,10 +1029,10 @@ function Qm(a,b,c){for(var d=Ra(a.id),e=0;e<=d.length;e++){var k=e<d.length?d[e]
f.cf=function(a){void 0===a&&(a=this.rc||(this.J?1:Nm));if(!this.D){this.D++;var b=!1,c=!1;this.S=!1;var d=this.K||new Rd(this,Pm);if(-1==a)b=!0;else if(a>Nm){if(d.load(this.J)){this.F=new Rd(this,Pm,"failsafe");this.F.load()&&(Sm(this,d),a=2,Im(this.F));D(this.F,"timestamp",la());Jm(this.F);var e=this.rc&&!this.H;if(1==a||sa("Click OK to restore the previous PCjs machine state, or CANCEL to reset the machine.")){if(c=Km(d)){var k=Lm(d,"code"),l=Lm(d,"data");k&&("ok"==k?d.load(l):("error"==k&&"no machine state"!=
l?(this.Ka("Error: "+l),"unable to verify user"==l&&(wa("user",""),this.B=null)):this.cc(k+": "+l),Im(d),d.load()?(c=Km(d),e=!0):c=!1))}e&&Rm(this,c?d:null)}else 2==a&&d.clear()}else Rm(this);delete this.J;delete this.K}e=Ra(this.id);for(k=0;k<e.length;k++)l=e[k],l!==this&&l!=this.A&&(c=Tm(this,l,d,b,c));b=[d,a,c];-1!=a?Qm(this,this.Rh,b):this.Rh(b)}};
function Tm(a,b,c,d,e){if(!b.ja.Qb){b.ja.Qb=!0;if(b.Tb){var k=null;e&&((k=Lm(c,b.id))||(k=Lm(c,b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof k&&(k=null);!b.Tb(k,d)&&k&&(ra("Unable to restore state for "+b.type),a.O&&!a.W?(c.clear(),a.rc=Nm,window&&window.location.reload()):a.S=!0,b.Tb(null),e=!1)}if(!d&&b.Ch)for(a=b.Ch.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
f.Rh=function(a){var b=a[0],c=0>a[1];a=a[2];this.ja.Qb=!0;var d=this.qa.power;d&&(d.textContent="On");this.Dh||(this.cc("PCjs v"+Pm+"\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>"),this.Dh=!0);this.A&&(Tm(this,this.A,b,c,a),kc(this.A));this.S&&(Sm(this,b),b.clear());!c&&this.F&&(this.F.clear(),delete this.F);this.D=0};
f.Rh=function(a){var b=a[0],c=0>a[1];a=a[2];this.ja.Qb=!0;var d=this.qa.power;d&&(d.textContent="Shutdown");this.Dh||(this.cc("PCjs v"+Pm+"\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>"),this.Dh=!0);this.A&&(Tm(this,this.A,b,c,a),kc(this.A));this.S&&(Sm(this,b),b.clear());!c&&this.F&&(this.F.clear(),delete this.F);this.D=0};
function Sm(a,b){if(sa("There may be a problem with your PCjs machine.\n\nTo help us diagnose it, click OK to send this PCjs machine state to http://www.pcjs.org.")){var c=a.da,d=a.yd(),e=b.toString(),k={app:"PCjs"};k.ver=Pm;k.url=c;k.user=d;k.type="bug";k.data=e;pa("http://www.pcjs.org/api/v1/report",!0,k)}}
function Um(a,b,c){var d,e="none";if(a.D)return null;a.D--;var k=new Rd(a,Pm),l=new Rd(a,Pm,"validate"),p=la();D(l,"timestamp",p);D(k,"timestamp",p);D(k,"version","1.20.9");D(k,"url",window?window.location.href:null);D(k,"browser",window?window.navigator.userAgent:"");a.A&&a.A.Sb&&(c&&nc(a.A),d=a.A.Sb(b,c),"object"===typeof d&&D(k,a.A.id,d),c&&(a.A.ja.Qb=!1,!1===d&&(e=null)));for(var p=Ra(a.id),q=0;q<p.length;q++){var w=p[q];w.ja.Qb&&(w.Sb&&(d=w.Sb(b,c),"object"===typeof d&&D(k,w.id,d)),c&&(w.ja.Qb=
!1,!1===d&&(e=null)))}e&&(c?(p=d=!1,b?(a.B&&Vm(a,a.B,k.toString()),Jm(l)&&Jm(k)||(e=null,d=p=!0)):a.rc&&(d=!0,p=3==a.rc),d&&k.clear(p)):e=k.toString());c&&(a.ja.Qb=!1,b=a.qa.power)&&(b.textContent="Off");a.D=0;return e}f.reset=function(){this.na&&this.na.reset&&this.na.reset();for(var a=Ra(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.na&&c.reset&&c.reset()}};f.start=function(a,b){for(var c=Ra(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}};
!1,!1===d&&(e=null)))}e&&(c?(p=d=!1,b?(a.B&&Vm(a,a.B,k.toString()),Jm(l)&&Jm(k)||(e=null,d=p=!0)):a.rc&&(d=!0,p=3==a.rc),d&&k.clear(p)):e=k.toString());c&&(a.ja.Qb=!1,b=a.qa.power)&&(b.textContent="Power");a.D=0;return e}f.reset=function(){this.na&&this.na.reset&&this.na.reset();for(var a=Ra(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.na&&c.reset&&c.reset()}};f.start=function(a,b){for(var c=Ra(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}};
f.stop=function(a,b){for(var c=Ra(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}};
f.Eb=function(a,b,c){var d=this;switch(b){case "power":return this.qa[b]=c,c.onclick=function(){d.D||(d.ja.Qb?Um(d,!1,!0):Qm(d,d.cf))},!0;case "reset":return this.qa[b]=c,c.onclick=function(){if(d.ja.Qb&&!d.D)if(d.rc&&!d.uf){var a=sa("Click OK to save changes to this PCjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");Um(d,a,!0);!a&&d.O?window&&window.location.reload():(a||(d.mg=!0),d.cf(Nm),d.mg=!1)}else d.reset(),d.A&&kc(d.A)},!0;case "save":return this.qa[b]=c,c.onclick=
function(){var a=Om(d,!0);if(a){var b=!!(d.rc&&!d.uf||d.O),c=Um(d,b);b?Vm(d,a,c):d.Ka("Resume disabled, machine state not saved")}},!0}return!1};function Om(a,b){var c=a.B;c||(c=va("user"),void 0!==c?!c&&b&&(c=null,window&&(c=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c&&((c=Wm(a,c))||a.Ka("The user ID is invalid."))):b&&a.Ka("Browser local storage is not available"));return c}

View file

@ -1134,7 +1134,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
reIncludes.lastIndex = 0; // reset lastIndex, since we just modified the string that reIncludes is iterating over
}
sBlock = sBlock.replace(/\{%\s*include\s+build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div id=$1$2$1></div>');
sBlock = sBlock.replace(/\{%\s*include\s+build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div class="pcbuild" id=$1$2$1></div>');
/*
* Start looking for Markdown-style machine links now...

View file

@ -36,6 +36,76 @@
* This file provides all the UI options for building a functional PCjs PC.
*/
var typeAddress = {
type: "address"
};
var typeBoolean = {
type: "boolean"
};
var typeNumber = {
type: "number"
};
var typePath = {
type: "string"
};
var typeString = {
type: "string"
};
var machineTypes = {
'5150': "IBM PC (Model 5150)",
'5160': "IBM PC XT (Model 5160)",
'5170': "IBM PC AT (Model 5170)",
'deskpro386': "COMPAQ DeskPro 386"
};
var aMachineElements = {
'machine': {
choices: machineTypes
},
'name': {
desc: "Machine Description"
},
'computer': {
desc: "General Computer Features",
'buswidth': {
type: typeNumber,
values: [20, 24, 32]
},
'resume': {
type: typeNumber,
value: [0, 1, 2],
descs: ["Resume Disabled", "Resume Enabled", "Resume with Prompt"]
}
},
'ram': {
desc: "Read-Write Memory (Conventional or Extended)",
'addr': {
type: typeAddress
},
'size': {
type: typeNumber
}
},
'rom': {
desc: "Read-Only Memory",
'addr': {
type: typeAddress
},
'size': {
type: typeNumber
},
'file': {
type: typePath
}
}
};
/**
* buildPC(idElement)
*

View file

@ -104,14 +104,20 @@ if (NODE) {
*
* The parmsMachine object, if provided, may contain any of:
*
* url: the location of the machine XML file
*
* autoMount: if set, this should override any 'autoMount' property in the FDC's
* parmsFDC object.
*
* autoPower: if set, this should override any 'autoPower' property in the Computer's
* parmsComputer object.
*
* messages: if set, this should override any 'messages' property in the Debugger's
* parmsDbg object.
*
* state: if set, this should override any 'state' property in the Computer's
* parmsComputer object.
*
* url: the location of the machine XML file
*
* If a predefined state is supplied AND it's successfully loaded, then resume behavior
* defaults to '1' (ie, resume enabled without prompting).
*