Some early functionality for the new display panel
This commit is contained in:
parent
2637a4ca85
commit
0ffe6c7637
5 changed files with 251 additions and 35 deletions
11
blog/2015/01/28/README.md
Normal file
11
blog/2015/01/28/README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
New PCjs Control Panel
|
||||
---
|
||||
A new PCjs Control Panel is under development, featuring a new "Display Panel" that will provide a variety of
|
||||
information about the machine, in real-time, and operate more efficiently than previous DOM-based Control Panels.
|
||||
|
||||
A preview of the layout is shown below. There's not much to see yet, as this is very much a work-in-progress.
|
||||
|
||||
[Embedded IBM PC](/devices/pc/machine/5170/ega/1152kb/rev3/backtrack/ "PCjs:at-ega-1152k-rev3::uncompiled:debugger")
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*January 28, 2015*
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pcjs/1.17.0/machine.xsl"?>
|
||||
<machine id="ibm5170rev3" class="pc" border="1" pos="center" style="background-color:#FAEBD7">
|
||||
<name>IBM PC AT (8Mhz), 128Kb EGA, 1152Kb RAM, 20Mb Hard Disk</name>
|
||||
<computer id="at-ega-1152k-rev3" name="IBM PC AT" buswidth="24"/>
|
||||
<cpu id="cpu286" model="80286" cycles="8000000"/>
|
||||
<ram id="ramLow" addr="0x00000" test="true" size="0xa0000" comment="ROM BIOS memory test has been disabled"/>
|
||||
<ram id="ramExt" addr="0x100000" size="0x80000" comment=""/>
|
||||
<rom id="romEGA" addr="0xc0000" size="0x4000" file="/devices/pc/video/ibm-ega.json" notify="videoEGA"/>
|
||||
<rom id="romBIOS" addr="0xf0000" size="0x10000" alias="0xff0000" file="/devices/pc/bios/5170/1985-11-15.json"/>
|
||||
<video ref="/devices/pc/video/video-ega-128kb-lock.xml"/>
|
||||
<keyboard ref="/devices/pc/keyboard/keyboard-minimal-functions.xml"/>
|
||||
<debugger id="debugger" messages="fault" commands=""/>
|
||||
<fdc ref="/disks/pc/library.xml" automount='{A: {name: "PC-DOS 3.20 (Disk 1)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK1.json"}, B: {name: "PC-DOS 3.20 (Disk 2)", path: "/disks/pc/dos/ibm/3.20/PCDOS320-DISK2.json"}}'/>
|
||||
<panel ref="/devices/pc/panel/btpanel.xml"/>
|
||||
<hdc id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2}]'/>
|
||||
<chipset id="chipset" model="5170" floppies="[1440,1200]" monitor="ega"/>
|
||||
<serial id="com1" adapter="1"/>
|
||||
<serial id="com2" adapter="2" binding="print"/>
|
||||
<mouse serial="com1"/>
|
||||
</machine>
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
"use strict";
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
var str = require("../../shared/lib/strlib");
|
||||
var web = require("../../shared/lib/weblib");
|
||||
var Component = require("../../shared/lib/component");
|
||||
var Bus = require("./bus");
|
||||
|
|
@ -59,6 +60,30 @@ function Panel(parmsPanel) {
|
|||
|
||||
Component.subclass(Component, Panel);
|
||||
|
||||
/*
|
||||
* The "Live" canvases that we create internally have the following fixed dimensions, to make drawing
|
||||
* simpler. We then render, via drawImage(), these canvases onto the supplied canvas, which will automatically
|
||||
* stretch the live images to fit.
|
||||
*/
|
||||
Panel.LIVECANVAS = {
|
||||
WIDTH: 1280,
|
||||
HEIGHT: 720,
|
||||
FONT: {
|
||||
NAME: "Monaco",
|
||||
HEIGHT: 18
|
||||
}
|
||||
};
|
||||
|
||||
Panel.LIVEMEMORY = {
|
||||
WIDTH: (Panel.LIVECANVAS.WIDTH * 3) >> 2,
|
||||
HEIGHT: Panel.LIVECANVAS.HEIGHT
|
||||
};
|
||||
|
||||
Panel.LIVEREGISTERS = {
|
||||
WIDTH: (Panel.LIVECANVAS.WIDTH - Panel.LIVEMEMORY.WIDTH),
|
||||
HEIGHT: Panel.LIVECANVAS.HEIGHT
|
||||
};
|
||||
|
||||
/**
|
||||
* setBinding(sHTMLType, sBinding, control)
|
||||
*
|
||||
|
|
@ -85,10 +110,29 @@ Panel.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
}
|
||||
if (fPanel) {
|
||||
this.canvas = control;
|
||||
this.canvasContext = this.canvas.getContext("2d");
|
||||
/*
|
||||
* NOTE: this.canvas.width and this.canvas.height contain the width and height of the canvas, in pixels
|
||||
*/
|
||||
this.context = this.canvas.getContext("2d");
|
||||
|
||||
this.xMemory = this.yMemory = 0;
|
||||
this.cxMemory = ((this.canvas.width * Panel.LIVEMEMORY.WIDTH) / Panel.LIVECANVAS.WIDTH) | 0;
|
||||
this.cyMemory = this.canvas.height;
|
||||
this.xRegisters = this.cxMemory;
|
||||
this.yRegisters = 0;
|
||||
this.cxRegisters = this.canvas.width - this.cxMemory;
|
||||
this.cyRegisters = this.canvas.height;
|
||||
|
||||
this.canvasLiveMemory = window.document.createElement("canvas");
|
||||
this.canvasLiveMemory.width = Panel.LIVEMEMORY.WIDTH;
|
||||
this.canvasLiveMemory.height = Panel.LIVEMEMORY.HEIGHT;
|
||||
this.contextLiveMemory = this.canvasLiveMemory.getContext("2d");
|
||||
this.contextLiveMemory.font = Panel.LIVECANVAS.FONT.HEIGHT + "px " + Panel.LIVECANVAS.FONT.NAME;
|
||||
this.imageLiveMemory = this.contextLiveMemory.createImageData(this.canvasLiveMemory.width, this.canvasLiveMemory.height);
|
||||
|
||||
this.canvasLiveRegisters = window.document.createElement("canvas");
|
||||
this.canvasLiveRegisters.width = Panel.LIVEREGISTERS.WIDTH;
|
||||
this.canvasLiveRegisters.height = Panel.LIVEREGISTERS.HEIGHT;
|
||||
this.contextLiveRegisters = this.canvasLiveRegisters.getContext("2d");
|
||||
this.contextLiveRegisters.font = Panel.LIVECANVAS.FONT.HEIGHT + "px " + Panel.LIVECANVAS.FONT.NAME;
|
||||
|
||||
this.fRedraw = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -151,20 +195,17 @@ Panel.prototype.powerDown = function(fSave)
|
|||
*/
|
||||
Panel.prototype.updateAnimation = function()
|
||||
{
|
||||
var context = this.canvasContext;
|
||||
if (context) {
|
||||
if (this.fRedraw) {
|
||||
if (BACKTRACK && this.fBackTrack) {
|
||||
context.font = "40px Arial";
|
||||
/*
|
||||
* Even when the canvas from whence the context came has an explicit "color" style,
|
||||
* the context still defaults to "black", so we must manually propagate the canvas color.
|
||||
*/
|
||||
context.fillStyle = this.canvas.style.color;
|
||||
context.fillText("BackTrack Panel",10,50);
|
||||
}
|
||||
this.fRedraw = false;
|
||||
if (this.fRedraw) {
|
||||
if (this.fBackTrack) {
|
||||
if (MAXDEBUG) this.log("begin scanMemory()");
|
||||
this.stats = this.bus.scanMemory(this.stats);
|
||||
this.findRegions();
|
||||
if (MAXDEBUG) this.log("end scanMemory(): total bytes: " + this.stats.cbTotal + ", total blocks: " + this.stats.cBlocks + ", total regions: " + this.stats.cRegions);
|
||||
}
|
||||
this.initPen(10, Panel.LIVECANVAS.FONT.HEIGHT, this.canvasLiveMemory, this.contextLiveMemory);
|
||||
this.drawText("This space intentionally left blank");
|
||||
this.context.drawImage(this.canvasLiveMemory, 0, 0, this.canvasLiveMemory.width, this.canvasLiveMemory.height, this.xMemory, this.yMemory, this.cxMemory, this.cyMemory);
|
||||
this.fRedraw = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -180,12 +221,7 @@ Panel.prototype.updateAnimation = function()
|
|||
Panel.prototype.updateStatus = function()
|
||||
{
|
||||
if (this.canvas) {
|
||||
if (this.fBackTrack) {
|
||||
if (MAXDEBUG) this.log("begin scanMemory()");
|
||||
this.stats = this.bus.scanMemory(this.stats);
|
||||
this.findRegions();
|
||||
if (MAXDEBUG) this.log("end scanMemory(): total bytes: " + this.stats.cbTotal + ", total blocks: " + this.stats.cBlocks + ", total regions: " + this.stats.cRegions);
|
||||
}
|
||||
this.updateRegisters();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -237,6 +273,154 @@ Panel.prototype.addRegion = function(addr, iBlock, cBlocks, type)
|
|||
if (MAXDEBUG) this.log("region " + this.stats.cRegions + " (addr " + str.toHex(addr) + ", type " + Memory.TYPE.NAMES[type] + ") contains " + cBlocks + " blocks");
|
||||
};
|
||||
|
||||
/**
|
||||
* updateRegisters()
|
||||
*
|
||||
* Updates the live register portion of the panel.
|
||||
*
|
||||
* @this {Panel}
|
||||
*/
|
||||
Panel.prototype.updateRegisters = function()
|
||||
{
|
||||
if (this.context && this.canvasLiveRegisters && this.contextLiveRegisters) {
|
||||
|
||||
this.contextLiveRegisters.fillStyle = "black";
|
||||
this.contextLiveRegisters.fillRect(0, 0, this.canvasLiveRegisters.width, this.canvasLiveRegisters.height);
|
||||
|
||||
this.initPen(10, Panel.LIVECANVAS.FONT.HEIGHT, this.canvasLiveRegisters, this.contextLiveRegisters);
|
||||
this.initCols(3);
|
||||
this.drawText("CPU");
|
||||
this.drawText("Target");
|
||||
this.drawText("Current");
|
||||
this.skipLines();
|
||||
this.drawText(this.cpu.model);
|
||||
this.drawText(this.cpu.getSpeedTarget());
|
||||
this.drawText(this.cpu.getSpeedCurrent());
|
||||
this.skipLines(2);
|
||||
this.initCols(8);
|
||||
this.initNumberFormat(16, 4);
|
||||
this.drawText("AX", this.cpu.regEAX, 2);
|
||||
this.drawText("SI", this.cpu.regESI, 0, 1);
|
||||
this.drawText("BX", this.cpu.regEBX, 2);
|
||||
this.drawText("DI", this.cpu.regEDI, 0, 1);
|
||||
this.drawText("CX", this.cpu.regECX, 2);
|
||||
this.drawText("SP", this.cpu.regESP, 0, 1);
|
||||
this.drawText("DX", this.cpu.regEDX, 2);
|
||||
this.drawText("BP", this.cpu.regEBP, 0, 2);
|
||||
this.drawText("CS", this.cpu.segCS.sel, 2);
|
||||
this.drawText("DS", this.cpu.segDS.sel, 0, 1);
|
||||
this.drawText("SS", this.cpu.segSS.sel, 2);
|
||||
this.drawText("ES", this.cpu.segES.sel, 0, 2);
|
||||
this.drawText("IP", this.cpu.regEIP, 2);
|
||||
var regPS;
|
||||
this.drawText("PS", regPS = this.cpu.getPS(), 0, 2);
|
||||
this.initCols(9);
|
||||
this.drawText("V" + ((regPS & X86.PS.OF)? 1 : 0));
|
||||
this.drawText("D" + ((regPS & X86.PS.DF)? 1 : 0));
|
||||
this.drawText("I" + ((regPS & X86.PS.IF)? 1 : 0));
|
||||
this.drawText("T" + ((regPS & X86.PS.TF)? 1 : 0));
|
||||
this.drawText("S" + ((regPS & X86.PS.SF)? 1 : 0));
|
||||
this.drawText("Z" + ((regPS & X86.PS.ZF)? 1 : 0));
|
||||
this.drawText("A" + ((regPS & X86.PS.AF)? 1 : 0));
|
||||
this.drawText("P" + ((regPS & X86.PS.PF)? 1 : 0));
|
||||
this.drawText("C" + ((regPS & X86.PS.CF)? 1 : 0), 0, 2);
|
||||
this.context.drawImage(this.canvasLiveRegisters, 0, 0, this.canvasLiveRegisters.width, this.canvasLiveRegisters.height, this.xRegisters, this.yRegisters, this.cxRegisters, this.cyRegisters);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* initPen(xLeft, yTop, canvasText, contextText)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {number} xLeft
|
||||
* @param {number} yTop
|
||||
* @param {Object} [canvasText]
|
||||
* @param {Object} [contextText]
|
||||
*/
|
||||
Panel.prototype.initPen = function(xLeft, yTop, canvasText, contextText)
|
||||
{
|
||||
this.xLeftMargin = this.xLeft = xLeft;
|
||||
this.yTop = yTop;
|
||||
if (canvasText) {
|
||||
this.canvasText = canvasText;
|
||||
}
|
||||
if (contextText) {
|
||||
this.contextText = contextText;
|
||||
this.contextText.fillStyle = this.canvas.style.color
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* initCols(nCols)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {number} nCols
|
||||
*/
|
||||
Panel.prototype.initCols = function(nCols)
|
||||
{
|
||||
this.cxColumn = (this.canvasText.width / nCols) | 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* skipCols(nCols)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {number} nCols
|
||||
*/
|
||||
Panel.prototype.skipCols = function(nCols)
|
||||
{
|
||||
this.xLeft += this.cxColumn * nCols;
|
||||
};
|
||||
|
||||
/**
|
||||
* skipLines(nLines)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {number} [nLines]
|
||||
*/
|
||||
Panel.prototype.skipLines = function(nLines)
|
||||
{
|
||||
this.xLeft = this.xLeftMargin;
|
||||
this.yTop += (Panel.LIVECANVAS.FONT.HEIGHT + 2) * (nLines || 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* initNumberFormat(nBase, nDigits)
|
||||
*
|
||||
* @param {number} nBase
|
||||
* @param {number} nDigits
|
||||
*/
|
||||
Panel.prototype.initNumberFormat = function(nBase, nDigits)
|
||||
{
|
||||
this.nDefaultBase = nBase;
|
||||
this.nDefaultDigits = nDigits;
|
||||
};
|
||||
|
||||
/**
|
||||
* drawText(sText)
|
||||
*
|
||||
* @this {Panel}
|
||||
* @param {string} sText
|
||||
* @param {number} [nValue]
|
||||
* @param {number} [nColsSkip]
|
||||
* @param {number} [nLinesSkip]
|
||||
*/
|
||||
Panel.prototype.drawText = function(sText, nValue, nColsSkip, nLinesSkip)
|
||||
{
|
||||
this.contextText.fillText(sText, this.xLeft, this.yTop);
|
||||
this.xLeft += this.cxColumn;
|
||||
if (nValue !== undefined) {
|
||||
var sValue = nValue.toString();
|
||||
if (this.nDefaultBase == 16) {
|
||||
sValue = "0x" + str.toHex(nValue, this.nDefaultDigits);
|
||||
}
|
||||
this.contextText.fillText(sValue, this.xLeft, this.yTop);
|
||||
this.xLeft += this.cxColumn;
|
||||
}
|
||||
if (nColsSkip) this.skipCols(nColsSkip);
|
||||
if (nLinesSkip) this.skipLines(nLinesSkip);
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel.init()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4299,10 +4299,10 @@ Video.prototype.updateScreenGraphicsCGA = function(addrScreen, addrScreenLimit)
|
|||
* artifacts along the edges of those rectangles. So it appears I must continue to redraw the entire canvasScreenBuffer
|
||||
* on every change.
|
||||
*
|
||||
var xScreen = ((xDirty * this.cxScreen) / this.nCols);
|
||||
var yScreen = ((yDirty * this.cyScreen) / this.nRows);
|
||||
var cxScreen = ((cxDirty * this.cxScreen) / this.nCols);
|
||||
var cyScreen = ((cyDirty * this.cyScreen) / this.nRows);
|
||||
var xScreen = (((xDirty * this.cxScreen) / this.nCols) | 0);
|
||||
var yScreen = (((yDirty * this.cyScreen) / this.nRows) | 0);
|
||||
var cxScreen = (((cxDirty * this.cxScreen) / this.nCols) | 0);
|
||||
var cyScreen = (((cyDirty * this.cyScreen) / this.nRows) | 0);
|
||||
this.contextScreen.drawImage(this.canvasScreenBuffer, xDirty, yDirty, cxDirty, cyDirty, xScreen, yScreen, cxScreen, cyScreen);
|
||||
*/
|
||||
this.contextScreen.drawImage(this.canvasScreenBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);
|
||||
|
|
|
|||
|
|
@ -2654,15 +2654,15 @@ X86CPU.prototype.updateStatus = function(fForce)
|
|||
this.displayReg("IP", this.regEIP);
|
||||
var regPS = this.getPS();
|
||||
this.displayReg("PS", regPS);
|
||||
this.displayReg("C", (regPS & X86.PS.CF)? 1 : 0, 1);
|
||||
this.displayReg("P", (regPS & X86.PS.PF)? 1 : 0, 1);
|
||||
this.displayReg("A", (regPS & X86.PS.AF)? 1 : 0, 1);
|
||||
this.displayReg("Z", (regPS & X86.PS.ZF)? 1 : 0, 1);
|
||||
this.displayReg("S", (regPS & X86.PS.SF)? 1 : 0, 1);
|
||||
this.displayReg("T", (regPS & X86.PS.TF)? 1 : 0, 1);
|
||||
this.displayReg("I", (regPS & X86.PS.IF)? 1 : 0, 1);
|
||||
this.displayReg("D", (regPS & X86.PS.DF)? 1 : 0, 1);
|
||||
this.displayReg("V", (regPS & X86.PS.OF)? 1 : 0, 1);
|
||||
this.displayReg("D", (regPS & X86.PS.DF)? 1 : 0, 1);
|
||||
this.displayReg("I", (regPS & X86.PS.IF)? 1 : 0, 1);
|
||||
this.displayReg("T", (regPS & X86.PS.TF)? 1 : 0, 1);
|
||||
this.displayReg("S", (regPS & X86.PS.SF)? 1 : 0, 1);
|
||||
this.displayReg("Z", (regPS & X86.PS.ZF)? 1 : 0, 1);
|
||||
this.displayReg("A", (regPS & X86.PS.AF)? 1 : 0, 1);
|
||||
this.displayReg("P", (regPS & X86.PS.PF)? 1 : 0, 1);
|
||||
this.displayReg("C", (regPS & X86.PS.CF)? 1 : 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue