Merge branch 'next-release'

This commit is contained in:
Jeff Parsons 2016-10-21 22:43:18 -07:00
commit baac8d4ea8
221 changed files with 6475 additions and 2731 deletions

View file

@ -283,6 +283,129 @@ web.getResource = function(sURL, dataPost, fAsync, done)
return response;
};
/**
* parseMemoryResource(sURL, sData)
*
* @param {string} sData
* @return {Object|null} (resource)
*/
web.parseMemoryResource = function(sURL, sData)
{
var i;
var resource = {
aBytes: null,
aSymbols: null,
addrLoad: null,
addrExec: null
};
if (sData.charAt(0) == "[" || sData.charAt(0) == "{") {
try {
var a, ib, data;
if (sData.substr(0, 1) == "<") { // if the "data" begins with a "<"...
/*
* Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,
* but more recent server configs now display a somewhat friendlier HTML error page. The downside,
* however, is that the original error has been buried, and we've received "data" that isn't actually
* tape data. So if the data we've received appears to be "HTML-like", we treat it as an error message.
*/
throw new Error(sData);
}
/*
* TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to
* eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in
* IE9 with an "Out of memory" exception. One work-around would be to chop the data into chunks
* (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.
*
* However, it turns out that using JSON.parse(sDiskData) instead of eval("(" + sDiskData + ")")
* is a much easier fix. The only drawback is that we must first quote any unquoted property names
* and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;
* the following RegExp replacements take care of those requirements.
*
* The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and
* while I've stopped using hex values in DumpAPI responses (at least when "format=json" is specified),
* I can't guarantee they won't show up in "legacy" images, and there's no simple RegExp replacement
* for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect
* any hex prefixes ("0x") in the sequence. Ditto for error messages, which appear like so:
*
* ["unrecognized disk path: test.img"]
*/
if (sData.indexOf("0x") < 0 && sData.substr(0, 2) != "[\"") {
data = JSON.parse(sData.replace(/([a-z]+):/gm, "\"$1\":").replace(/\/\/[^\n]*/gm, ""));
} else {
data = eval("(" + sData + ")");
}
resource.addrLoad = data['load'];
resource.addrExec = data['exec'];
if (a = data['bytes']) {
resource.aBytes = a;
}
else if (a = data['words']) {
/*
* Convert all words into bytes
*/
resource.aBytes = new Array(a.length * 2);
for (i = 0, ib = 0; i < a.length; i++) {
resource.aBytes[ib++] = a[i] & 0xff;
resource.aBytes[ib++] = (a[i] >> 8) & 0xff;
Component.assert(!(a[i] & ~0xffff));
}
}
else if (a = data['data']) {
/*
* Convert all dwords (longs) into bytes
*/
resource.aBytes = new Array(a.length * 4);
for (i = 0, ib = 0; i < a.length; i++) {
resource.aBytes[ib++] = a[i] & 0xff;
resource.aBytes[ib++] = (a[i] >> 8) & 0xff;
resource.aBytes[ib++] = (a[i] >> 16) & 0xff;
resource.aBytes[ib++] = (a[i] >> 24) & 0xff;
}
}
else {
resource.aBytes = data;
}
resource.aSymbols = data['symbols'];
if (!resource.aBytes.length) {
Component.error("Empty resource: " + sURL);
resource = null;
}
else if (resource.aBytes.length == 1) {
Component.error(resource.aBytes[0]);
resource = null;
}
} catch (e) {
Component.error("Resource data error (" + sURL + "): " + e.message);
resource = null;
}
}
else {
/*
* Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.
*/
var ab = [];
var sHexData = sData.replace(/\n/gm, " ").replace(/ +$/, "");
var asHexData = sHexData.split(" ");
for (i = 0; i < asHexData.length; i++) {
var n = parseInt(asHexData[i], 16);
if (isNaN(n)) {
Component.error("Resource data error (" + sURL + "): invalid hex byte (" + asHexData[i] + ")");
break;
}
ab.push(n & 0xff);
}
if (i == asHexData.length) resource.aBytes = ab;
}
return resource;
};
/**
* sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)
*

View file

@ -31,7 +31,7 @@
<div class="common-top-left">
<ul>
<li><a href="/">PCjs</a></li>
<li><a href="/apps/pcx86/">Demos</a></li>
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/docs/">Docs</a></li>

View file

@ -33,7 +33,7 @@
<div class="common-top-left">
<ul>
<li><a href="/">PCjs</a></li>
<li><a href="/apps/pcx86/">Demos</a></li>
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/docs/">Docs</a></li>

View file

@ -55,6 +55,30 @@
line-height: 20px;
vertical-align: middle;
}
.pcjs-progress {
height: 20px;
width: 300px;
margin-top: 8px;
border: 1px solid black;
position: relative;
}
.pcjs-progress-bar {
height: 20px;
width: 0%; /* this will be updated pragmatically */
background-color: gold;
position: absolute;
top: 0px;
}
.pcjs-progress-text {
height: 20px;
width: 300px;
font-size: small;
line-height: 20px;
text-align: center;
position: absolute;
top: 0px;
z-index: 1;
}
.pcjs-register {
font-family: Monaco, "Lucida Console", monospace;
font-size: small;
@ -90,7 +114,7 @@
}
.pcjs-description, .pcjs-status {
font-size: x-small;
line-height: 2em;
line-height: 2.8em;
}
.pcjs-key {
border: 1px solid black;
@ -175,4 +199,8 @@
.pcjs-registers {
width: 100% !important;
}
.pdp11-device {
width: 100% !important;
max-width: none !important;
}
}

View file

@ -24,7 +24,14 @@
<xsl:template name="componentScripts">
<xsl:param name="component"/>
<script type="text/javascript" src="/versions/{$APPCLASS}/{$APPVERSION}/{$component}.js"> </script>
<xsl:choose>
<xsl:when test="$APPNAME = 'PDPjs'">
<script type="text/javascript" src="/versions/pdpjs/{$APPVERSION}/{$component}.js"> </script>
</xsl:when>
<xsl:otherwise>
<script type="text/javascript" src="/versions/{$APPCLASS}/{$APPVERSION}/{$component}.js"> </script>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="componentIncludes">
@ -182,10 +189,10 @@
<xsl:choose>
<xsl:when test="@padding">padding:<xsl:value-of select="@padding"/>;</xsl:when>
<xsl:otherwise>
<xsl:if test="@padtop">padding-top:<xsl:value-of select="@padtop"/>;</xsl:if>
<xsl:if test="@padright">padding-right:<xsl:value-of select="@padright"/>;</xsl:if>
<xsl:if test="@padbottom">padding-bottom:<xsl:value-of select="@padbottom"/>;</xsl:if>
<xsl:if test="@padleft">padding-left:<xsl:value-of select="@padleft"/>;</xsl:if>
<xsl:if test="@padTop">padding-top:<xsl:value-of select="@padTop"/>;</xsl:if>
<xsl:if test="@padRight">padding-right:<xsl:value-of select="@padRight"/>;</xsl:if>
<xsl:if test="@padBottom">padding-bottom:<xsl:value-of select="@padBottom"/>;</xsl:if>
<xsl:if test="@padLeft">padding-left:<xsl:value-of select="@padLeft"/>;</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
@ -318,10 +325,10 @@
<xsl:choose>
<xsl:when test="@padding">padding:<xsl:value-of select="@padding"/>;</xsl:when>
<xsl:otherwise>
<xsl:if test="@padtop">padding-top:<xsl:value-of select="@padtop"/>;</xsl:if>
<xsl:if test="@padright">padding-right:<xsl:value-of select="@padright"/>;</xsl:if>
<xsl:if test="@padbottom">padding-bottom:<xsl:value-of select="@padbottom"/>;</xsl:if>
<xsl:if test="@padleft">padding-left:<xsl:value-of select="@padleft"/>;</xsl:if>
<xsl:if test="@padTop">padding-top:<xsl:value-of select="@padTop"/>;</xsl:if>
<xsl:if test="@padRight">padding-right:<xsl:value-of select="@padRight"/>;</xsl:if>
<xsl:if test="@padBottom">padding-bottom:<xsl:value-of select="@padBottom"/>;</xsl:if>
<xsl:if test="@padLeft">padding-left:<xsl:value-of select="@padLeft"/>;</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
@ -330,6 +337,7 @@
<xsl:when test="@pos = 'left'">float:left;</xsl:when>
<xsl:when test="@pos = 'right'">float:right;</xsl:when>
<xsl:when test="@pos = 'center'">margin:0 auto;</xsl:when>
<xsl:when test="@pos = 'default'">clear:both;</xsl:when>
<xsl:when test="@pos">position:<xsl:value-of select="@pos"/>;</xsl:when>
<xsl:when test="$left != '' or $top != ''">position:relative;</xsl:when>
<xsl:when test="@container">text-align:<xsl:value-of select="@container"/>;</xsl:when>
@ -390,7 +398,7 @@
</xsl:when>
<xsl:when test="@type = 'list'">
<select class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$fontsize}{$style}" data-value="{{{$type},{$binding}}}">
<xsl:apply-templates select="disk|app|manifest" mode="component"/>
<xsl:apply-templates select="disk|tape|app|manifest" mode="component"/>
</select>
</xsl:when>
<xsl:when test="@type = 'text'">
@ -416,6 +424,12 @@
<xsl:when test="@type = 'led' or @type = 'rled'">
<div class="{$APPCLASS}-binding {$CSSCLASS}-{@type}" data-value="{{{$type},{$binding}}}" style="display:inline-block;"><xsl:value-of select="."/></div>
</xsl:when>
<xsl:when test="@type = 'progress'">
<div class="{$APPCLASS}-binding {$CSSCLASS}-{@type}" style="-webkit-user-select:none;{$border}{$width}{$height}{$fontsize}{$style}" data-value="{{{$type},{$binding},{$value}}}">
<div class="{$CSSCLASS}-{@type}-text" style="{$width}"><xsl:apply-templates/></div>
<div class="{$CSSCLASS}-{@type}-bar"></div>
</div>
</xsl:when>
<xsl:when test="@type = 'separator'">
<hr/>
</xsl:when>
@ -452,7 +466,38 @@
</xsl:if>
</xsl:if>
</xsl:variable>
<option value="{@path}" data-value="{{{$desc}}}"><xsl:if test="name"><xsl:value-of select="name"/></xsl:if><xsl:if test="not(name)"><xsl:value-of select="."/></xsl:if></option>
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="@name"><xsl:value-of select="@name"/></xsl:when>
<xsl:when test="name"><xsl:value-of select="name"/></xsl:when>
<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<option value="{@path}" data-value="{{{$desc}}}"><xsl:value-of select="$name"/></option>
</xsl:template>
<xsl:template match="tape[@ref]" mode="component">
<xsl:variable name="componentFile"><xsl:value-of select="$rootDir"/><xsl:value-of select="@ref"/></xsl:variable>
<xsl:apply-templates select="document($componentFile)/tape" mode="component"/>
</xsl:template>
<xsl:template match="tape[not(@ref)]" mode="component">
<xsl:variable name="desc">
<xsl:if test="@desc">
<xsl:text>desc:'</xsl:text><xsl:value-of select="@desc"/><xsl:text>'</xsl:text>
<xsl:if test="@href">
<xsl:text>,href:'</xsl:text><xsl:value-of select="@href"/><xsl:text>'</xsl:text>
</xsl:if>
</xsl:if>
</xsl:variable>
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="@name"><xsl:value-of select="@name"/></xsl:when>
<xsl:when test="name"><xsl:value-of select="name"/></xsl:when>
<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<option value="{@path}" data-value="{{{$desc}}}"><xsl:value-of select="$name"/></option>
</xsl:template>
<xsl:template match="app[@ref]" mode="component">
@ -582,9 +627,9 @@
<xsl:otherwise>null</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="resetAddr">
<xsl:variable name="addrReset">
<xsl:choose>
<xsl:when test="@resetAddr"><xsl:value-of select="@resetAddr"/></xsl:when>
<xsl:when test="@addrReset"><xsl:value-of select="@addrReset"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
@ -612,7 +657,7 @@
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class" select="'cpu'"/>
<xsl:with-param name="parms">,model:'<xsl:value-of select="$model"/>',stepping:'<xsl:value-of select="$stepping"/>',fpu:<xsl:value-of select="$fpu"/>,cycles:<xsl:value-of select="$cycles"/>,multiplier:<xsl:value-of select="$multiplier"/>,autoStart:<xsl:value-of select="$autoStart"/>,resetAddr:<xsl:value-of select="$resetAddr"/>,csStart:<xsl:value-of select="$csStart"/>,csInterval:<xsl:value-of select="$csInterval"/>,csStop:<xsl:value-of select="$csStop"/></xsl:with-param>
<xsl:with-param name="parms">,model:'<xsl:value-of select="$model"/>',stepping:'<xsl:value-of select="$stepping"/>',fpu:<xsl:value-of select="$fpu"/>,cycles:<xsl:value-of select="$cycles"/>,multiplier:<xsl:value-of select="$multiplier"/>,autoStart:<xsl:value-of select="$autoStart"/>,addrReset:<xsl:value-of select="$addrReset"/>,csStart:<xsl:value-of select="$csStart"/>,csInterval:<xsl:value-of select="$csInterval"/>,csStop:<xsl:value-of select="$csStop"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
@ -709,21 +754,44 @@
<xsl:template match="device[@ref]">
<xsl:param name="machine" select="''"/>
<xsl:variable name="componentFile"><xsl:value-of select="$rootDir"/><xsl:value-of select="@ref"/></xsl:variable>
<xsl:apply-templates select="document($componentFile)/device"><xsl:with-param name="machine" select="$machine"/></xsl:apply-templates>
<xsl:apply-templates select="document($componentFile)/device">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="mount" select="@automount"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="device[not(@ref)]">
<xsl:param name="machine" select="''"/>
<xsl:param name="mount" select="''"/>
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="@type"><xsl:value-of select="@type"/></xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="baudReceive">
<xsl:choose>
<xsl:when test="@baudReceive"><xsl:value-of select="@baudReceive"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="baudTransmit">
<xsl:choose>
<xsl:when test="@baudTransmit"><xsl:value-of select="@baudTransmit"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="autoMount">
<xsl:choose>
<xsl:when test="$mount != ''"><xsl:value-of select="$mount"/></xsl:when>
<xsl:when test="@automount"><xsl:value-of select="@automount"/></xsl:when>
<xsl:otherwise><xsl:value-of select="@autoMount"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">device</xsl:with-param>
<xsl:with-param name="parms">,type:'<xsl:value-of select="$type"/>'</xsl:with-param>
<xsl:with-param name="parms">,type:'<xsl:value-of select="$type"/>',baudReceive:<xsl:value-of select="$baudReceive"/>,baudTransmit:<xsl:value-of select="$baudTransmit"/>,autoMount:'<xsl:value-of select="$autoMount"/>'</xsl:with-param>
</xsl:call-template>
</xsl:template>
@ -789,6 +857,18 @@
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="baudReceive">
<xsl:choose>
<xsl:when test="@baudReceive"><xsl:value-of select="@baudReceive"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="baudTransmit">
<xsl:choose>
<xsl:when test="@baudTransmit"><xsl:value-of select="@baudTransmit"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="binding">
<xsl:choose>
<xsl:when test="@binding"><xsl:value-of select="@binding"/></xsl:when>
@ -809,10 +889,17 @@
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="upperCase">
<xsl:choose>
<xsl:when test="@uppercase"><xsl:value-of select="@uppercase"/></xsl:when>
<xsl:when test="@upperCase"><xsl:value-of select="@upperCase"/></xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">serial</xsl:with-param>
<xsl:with-param name="parms">,adapter:<xsl:value-of select="$adapter"/>,binding:'<xsl:value-of select="$binding"/>',tabSize:<xsl:value-of select="$tabSize"/>,charBOL:<xsl:value-of select="$charBOL"/></xsl:with-param>
<xsl:with-param name="parms">,adapter:<xsl:value-of select="$adapter"/>,baudReceive:<xsl:value-of select="$baudReceive"/>,baudTransmit:<xsl:value-of select="$baudTransmit"/>,binding:'<xsl:value-of select="$binding"/>',tabSize:<xsl:value-of select="$tabSize"/>,charBOL:<xsl:value-of select="$charBOL"/>,upperCase:<xsl:value-of select="$upperCase"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
@ -849,10 +936,11 @@
<xsl:template match="fdc[not(@ref)]">
<xsl:param name="machine" select="''"/>
<xsl:param name="mount" select="''"/>
<xsl:variable name="automount">
<xsl:variable name="autoMount">
<xsl:choose>
<xsl:when test="$mount != ''"><xsl:value-of select="$mount"/></xsl:when>
<xsl:otherwise><xsl:value-of select="@automount"/></xsl:otherwise>
<xsl:when test="@automount"><xsl:value-of select="@automount"/></xsl:when>
<xsl:otherwise><xsl:value-of select="@autoMount"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sortBy">
@ -864,7 +952,7 @@
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">fdc</xsl:with-param>
<xsl:with-param name="parms">,autoMount:'<xsl:value-of select="$automount"/>',sortBy:'<xsl:value-of select="$sortBy"/>'</xsl:with-param>
<xsl:with-param name="parms">,autoMount:'<xsl:value-of select="$autoMount"/>',sortBy:'<xsl:value-of select="$sortBy"/>'</xsl:with-param>
</xsl:call-template>
</xsl:template>
@ -933,16 +1021,10 @@
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="writable">
<xsl:choose>
<xsl:when test="@writable"><xsl:value-of select="@writable"/></xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">rom</xsl:with-param>
<xsl:with-param name="parms">,addr:<xsl:value-of select="$addr"/>,size:<xsl:value-of select="$size"/>,alias:<xsl:value-of select="$alias"/>,file:'<xsl:value-of select="$file"/>',notify:'<xsl:value-of select="$notify"/>',writable:<xsl:value-of select="$writable"/></xsl:with-param>
<xsl:with-param name="parms">,addr:<xsl:value-of select="$addr"/>,size:<xsl:value-of select="$size"/>,alias:<xsl:value-of select="$alias"/>,file:'<xsl:value-of select="$file"/>',notify:'<xsl:value-of select="$notify"/>'</xsl:with-param>
</xsl:call-template>
</xsl:template>
@ -966,6 +1048,24 @@
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="file">
<xsl:choose>
<xsl:when test="@file"><xsl:value-of select="@file"/></xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:variable name="load">
<xsl:choose>
<xsl:when test="@load"><xsl:value-of select="@load"/></xsl:when>
<xsl:otherwise>null</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="exec">
<xsl:choose>
<xsl:when test="@exec"><xsl:value-of select="@exec"/></xsl:when>
<xsl:otherwise>null</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="test">
<xsl:choose>
<xsl:when test="@test"><xsl:value-of select="@test"/></xsl:when>
@ -975,7 +1075,7 @@
<xsl:call-template name="component">
<xsl:with-param name="machine" select="$machine"/>
<xsl:with-param name="class">ram</xsl:with-param>
<xsl:with-param name="parms">,addr:<xsl:value-of select="$addr"/>,size:<xsl:value-of select="$size"/>,test:<xsl:value-of select="$test"/></xsl:with-param>
<xsl:with-param name="parms">,addr:<xsl:value-of select="$addr"/>,size:<xsl:value-of select="$size"/>,file:'<xsl:value-of select="$file"/>',load:<xsl:value-of select="$load"/>,exec:<xsl:value-of select="$exec"/>,test:<xsl:value-of select="$test"/></xsl:with-param>
</xsl:call-template>
</xsl:template>

View file

@ -10,8 +10,7 @@
<xsl:output doctype-system="about:legacy-compat" method="html"/>
<xsl:include href="common.xsl"/>
<!-- There is no "shared" components.xsl, so we just pick one to eliminate IDE inspection warnings -->
<xsl:include href="../../pcjs/templates/components.xsl"/>
<xsl:include href="../../shared/templates/components.xsl"/>
<xsl:template match="/machine">
<html lang="en">