Dual-display demo with side-by-side MDA and CGA screens
This commit is contained in:
parent
f3b254ebcd
commit
cd38446f68
7 changed files with 96 additions and 28 deletions
|
|
@ -38,8 +38,9 @@ Some pre-configured machines are shown below, ready to run BASIC, DOS, Windows 1
|
|||

|
||||
|
||||
Check out the rest of the PCjs [Application](/apps/pc/), [Boot Disk](/disks/pc/) and [Machine](/devices/pc/machine/)
|
||||
demos, including the [IBM PC XT "Server Array"](/devices/pc/machine/5160/cga/256kb/array/) and
|
||||
[Windows 1.01 "Server Array"](/devices/pc/machine/5160/ega/640kb/array/) demos of multiple PCs running side-by-side.
|
||||
demos, including an [IBM PC Dual Display System](/devices/pc/machine/5150/dual/64kb/) demo of multiple monitor support,
|
||||
and [IBM PC XT "Server Array"](/devices/pc/machine/5160/cga/256kb/array/) and [Windows 1.01 "Server Array"](/devices/pc/machine/5160/ega/640kb/array/)
|
||||
demos of multiple machines running side-by-side.
|
||||
|
||||
C1Pjs
|
||||
---
|
||||
|
|
|
|||
18
devices/pc/machine/5150/dual/64kb/machine.xml
Normal file
18
devices/pc/machine/5150/dual/64kb/machine.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pcjs/1.18.2/machine.xsl"?>
|
||||
<machine id="ibm5150" class="pc" border="1" pos="center" style="background-color:#FAEBD7">
|
||||
<name pos="center">IBM PC (Model 5150) with Dual Display</name>
|
||||
<computer id="pc-dual-64k" name="IBM PC" resume="1"/>
|
||||
<ram id="ramLow" addr="0x00000"/>
|
||||
<rom id="romBASIC" addr="0xf6000" size="0x8000" file="/devices/pc/basic/ibm-basic-1.00.json"/>
|
||||
<rom id="romBIOS" addr="0xfe000" size="0x2000" file="/devices/pc/bios/5150/1981-04-24.json"/>
|
||||
<video ref="/devices/pc/video/ibm/mda/ibm-mda-dual.xml"/>
|
||||
<video ref="/devices/pc/video/ibm/cga/ibm-cga-dual.xml"/>
|
||||
<cpu id="cpu8088" model="8088" autostart="true" padleft="8px">
|
||||
<control type="button" binding="run">Run</control>
|
||||
<control type="button" binding="reset">Reset</control>
|
||||
</cpu>
|
||||
<keyboard ref="/devices/pc/keyboard/keyboard-minimal.xml"/>
|
||||
<fdc ref="/disks/pc/samples.xml" pos="right"/>
|
||||
<chipset id="chipset" model="5150" sw1="01000001" sw2="11110000"/>
|
||||
</machine>
|
||||
|
|
@ -13,6 +13,7 @@ Here you'll find sample Machine Configurations for all the IBM PC models that PC
|
|||
* [IBM PC, MDA, 64K, Debugger](/devices/pc/machine/5150/mda/64kb/debugger/)
|
||||
* [IBM PC, CGA, 64K, DONKEY.BAS](/devices/pc/machine/5150/cga/64kb/donkey/)
|
||||
* [IBM PC, CGA, 64K, DONKEY.BAS, Debugger](/devices/pc/machine/5150/cga/64kb/donkey/debugger/)
|
||||
* [IBM PC, Dual Display, 64K](/devices/pc/machine/5150/dual/64kb/)
|
||||
|
||||
### Model 5160 Machine Configurations
|
||||
|
||||
|
|
|
|||
6
devices/pc/video/ibm/cga/ibm-cga-dual.xml
Normal file
6
devices/pc/video/ibm/cga/ibm-cga-dual.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<video id="videoCGA" model="cga" screenwidth="960" screenheight="480" scale="true" charset="/devices/pc/video/ibm/cga/ibm-cga.json" pos="center" padding="8px">
|
||||
<menu>
|
||||
<title>Color Display</title>
|
||||
</menu>
|
||||
</video>
|
||||
11
devices/pc/video/ibm/mda/ibm-mda-dual.xml
Normal file
11
devices/pc/video/ibm/mda/ibm-mda-dual.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<video id="videoMDA" model="mda" screenwidth="720" screenheight="350" scale="true" charset="/devices/pc/video/ibm/mda/ibm-mda.json" pos="center" padding="8px">
|
||||
<menu>
|
||||
<title>Monochrome Display</title>
|
||||
<control type="container" pos="right">
|
||||
<control type="led" label="Caps" binding="caps-lock" padleft="8px"/>
|
||||
<control type="led" label="Num" binding="num-lock" padleft="8px"/>
|
||||
<control type="led" label="Scroll" binding="scroll-lock" padleft="8px"/>
|
||||
</control>
|
||||
</menu>
|
||||
</video>
|
||||
|
|
@ -984,7 +984,14 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control)
|
|||
if (this.bindings[id] === undefined) {
|
||||
switch (sBinding) {
|
||||
case "kbd":
|
||||
this.bindings[id] = control;
|
||||
/*
|
||||
* Recording the binding ID prevents multiple controls (or components) from attempting to erroneously
|
||||
* bind a control to the same ID, but in the case of a "dual display" configuration, we actually want
|
||||
* to allow BOTH video components to call setBinding() for "kbd", so that it doesn't matter which
|
||||
* display the user gives focus to.
|
||||
*
|
||||
* this.bindings[id] = control;
|
||||
*/
|
||||
control.onkeydown = function onKeyDown(event) {
|
||||
return kbd.onKeyDown(event, true);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1046,7 +1046,7 @@ Card.STATUS1 = {
|
|||
* EGA/VGA Attribute Controller Registers (regATCIndx and regATCData)
|
||||
*
|
||||
* The current ATC INDX value is stored in cardEGA.regATCIndx (including the Card.ATC.INDX_ENABLE bit), and the
|
||||
* ATC DATA values are stored in cardEGA.regATCData. Also, the state of the ATC INDX/DATA flip-flop is stored in fATCData.
|
||||
* ATC DATA values are stored in cardEGA.regATCData. The state of the ATC INDX/DATA flip-flop is stored in fATCData.
|
||||
*
|
||||
* Note that the ATC palette registers (0x0-0xf) all use the following 6 bit assignments, with bits 6 and 7 unused:
|
||||
*
|
||||
|
|
@ -2078,9 +2078,32 @@ Video.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
|
||||
bus.addPortInputTable(this, Video.aPortInput);
|
||||
bus.addPortOutputTable(this, Video.aPortOutput);
|
||||
/*
|
||||
* The only time we do NOT want to trap MDA ports is when the model has been specifically set to CGA.
|
||||
*/
|
||||
if (Video.CARD.NAMES[this.model] != Video.CARD.CGA) {
|
||||
bus.addPortInputTable(this, Video.aMDAPortInput);
|
||||
bus.addPortOutputTable(this, Video.aMDAPortOutput);
|
||||
}
|
||||
|
||||
/*
|
||||
* Similarly, the only time we do NOT want to trap CGA ports is when the model has been specifically set to MDA.
|
||||
*/
|
||||
if (Video.CARD.NAMES[this.model] != Video.CARD.MDA) {
|
||||
bus.addPortInputTable(this, Video.aCGAPortInput);
|
||||
bus.addPortOutputTable(this, Video.aCGAPortOutput);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that in the case of EGA and VGA models, the above code ensures that we will trap both MDA and CGA
|
||||
* port ranges -- which is good, because both the EGA and VGA can be reprogrammed to respond to those ports,
|
||||
* but also potentially bad if you want to simulate a "dual display" system, where one of the displays is
|
||||
* driven by either an MDA or CGA.
|
||||
*
|
||||
* However, you should still be able to make that work by loading the MDA or CGA video component first, because
|
||||
* components should be initialized in the order they appear in the machine configuration file. Any attempt
|
||||
* by another component to trap the same ports should be ignored.
|
||||
*/
|
||||
if (this.nCard >= Video.CARD.EGA) {
|
||||
bus.addPortInputTable(this, Video.aEGAPortInput);
|
||||
bus.addPortOutputTable(this, Video.aEGAPortOutput);
|
||||
|
|
@ -2560,7 +2583,8 @@ Video.prototype.reset = function()
|
|||
|
||||
/*
|
||||
* As we noted in the constructor, when a model is specified, that takes precedence over any monitor
|
||||
* switch settings. Conversely, when no model is specified, the nCard setting is considered provisional.
|
||||
* switch settings. Conversely, when no model is specified, the nCard setting is considered provisional,
|
||||
* so the monitor switch settings, if any, are allowed to determine the card type.
|
||||
*/
|
||||
if (!this.model) {
|
||||
this.nCard = (nMonitorType == ChipSet.MONITOR.MONO? Video.CARD.MDA : Video.CARD.CGA);
|
||||
|
|
@ -5309,15 +5333,24 @@ Video.prototype.dumpVideo = function(sParm)
|
|||
* TODO: At one point, I'd added some "duplicate" entries for the MDA because, according to docs I'd read,
|
||||
* MDA ports are decoded at multiple addresses. However, if this is important, then it should be verified
|
||||
* and implemented consistently (eg, for CGA as well). For now, I'm decoding only the standard port addresses.
|
||||
*
|
||||
* For example, 0x3B5 is apparently also decoded at 0x3B1, 0x3B3, and 0x3B7, while 0x3B4 is also decoded at
|
||||
* 0x3B0, 0x3B2, and 0x3B6.
|
||||
*/
|
||||
Video.aPortInput = {
|
||||
// 0x3B1: Video.prototype.inMDAData, // duplicate
|
||||
// 0x3B3: Video.prototype.inMDAData, // duplicate
|
||||
Video.aMDAPortInput = {
|
||||
0x3B4: Video.prototype.inMDAIndx, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3B5: Video.prototype.inMDAData, // technically, the only Data registers that are readable are R14-R17
|
||||
// 0x3B7: Video.prototype.inMDAData, // duplicate
|
||||
0x3B8: Video.prototype.inMDAMode, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3BA: Video.prototype.inMDAStatus,
|
||||
0x3BA: Video.prototype.inMDAStatus
|
||||
};
|
||||
|
||||
Video.aMDAPortOutput = {
|
||||
0x3B4: Video.prototype.outMDAIndx,
|
||||
0x3B5: Video.prototype.outMDAData,
|
||||
0x3B8: Video.prototype.outMDAMode
|
||||
};
|
||||
|
||||
Video.aCGAPortInput = {
|
||||
0x3D4: Video.prototype.inCGAIndx, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3D5: Video.prototype.inCGAData, // technically, the only Data registers that are readable are R14-R17
|
||||
0x3D8: Video.prototype.inCGAMode, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
|
|
@ -5325,16 +5358,7 @@ Video.aPortInput = {
|
|||
0x3DA: Video.prototype.inCGAStatus
|
||||
};
|
||||
|
||||
Video.aPortOutput = {
|
||||
// 0x3B0: Video.prototype.outMDAIndx, // duplicate
|
||||
// 0x3B1: Video.prototype.outMDAData, // duplicate
|
||||
// 0x3B2: Video.prototype.outMDAIndx, // duplicate
|
||||
// 0x3B3: Video.prototype.outMDAData, // duplicate
|
||||
0x3B4: Video.prototype.outMDAIndx, // 0x3B4 is decoded at 0x3B0, 0x3B2 and 0x3B6 as well (at least on an MDA), hence the duplicate mappings
|
||||
0x3B5: Video.prototype.outMDAData, // 0x3B5 is decoded at 0x3B1, 0x3B3 and 0x3B7 as well (at least on an MDA), hence the duplicate mappings
|
||||
// 0x3B6: Video.prototype.outMDAIndx, // duplicate
|
||||
// 0x3B7: Video.prototype.outMDAData, // duplicate
|
||||
0x3B8: Video.prototype.outMDAMode,
|
||||
Video.aCGAPortOutput = {
|
||||
0x3D4: Video.prototype.outCGAIndx,
|
||||
0x3D5: Video.prototype.outCGAData,
|
||||
0x3D8: Video.prototype.outCGAMode,
|
||||
|
|
@ -5342,13 +5366,13 @@ Video.aPortOutput = {
|
|||
};
|
||||
|
||||
Video.aEGAPortInput = {
|
||||
0x3C0: Video.prototype.inATC, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3C1: Video.prototype.inATC, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3C0: Video.prototype.inATC, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
0x3C1: Video.prototype.inATC, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
0x3C2: Video.prototype.inStatus0,
|
||||
0x3C4: Video.prototype.inSEQIndx, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3C5: Video.prototype.inSEQData, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3CE: Video.prototype.inGRCIndx, // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3CF: Video.prototype.inGRCData // technically, not actually readable, but I want the Debugger to be able to read this
|
||||
0x3C4: Video.prototype.inSEQIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
0x3C5: Video.prototype.inSEQData, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
0x3CE: Video.prototype.inGRCIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
0x3CF: Video.prototype.inGRCData // technically, only readable on a VGA, but I want the Debugger to be able to read this, too
|
||||
};
|
||||
|
||||
Video.aEGAPortOutput = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue