Added Video callout to make resolutions adjustments (eg, from 80-column mode to 132-column mode); work in Video component ready to begin
This commit is contained in:
parent
a6376d3e8b
commit
e516070375
11 changed files with 577 additions and 400 deletions
|
|
@ -235,24 +235,52 @@ ChipSet.VT100 = {
|
|||
PORT: 0x42, // write-only
|
||||
INIT: 0x00 // for lack of a better guess
|
||||
},
|
||||
NVR: {
|
||||
LATCH: {
|
||||
PORT: 0x62 // write-only
|
||||
},
|
||||
CMD: {
|
||||
ACCEPT_DATA: 0x0,
|
||||
ACCEPT_ADDR: 0x1,
|
||||
SHIFT_OUT: 0x2,
|
||||
WRITE: 0x4,
|
||||
ERASE: 0x5,
|
||||
READ: 0x6,
|
||||
STANDBY: 0x7
|
||||
},
|
||||
WORDMASK: 0x3fff // NVR words are 14-bit
|
||||
/*
|
||||
* The Technical Manual, p. 4-18, also notes that "Early VT100s can disable the receiver interrupt by
|
||||
* programming D4 in the NVR latch. However, this is never used by the VT100."
|
||||
*/
|
||||
/*
|
||||
* DC011 is referred to as a Timing Chip.
|
||||
*
|
||||
* As p. 4-55 (105) of the VT100 Technical Manual (July 1982) explains:
|
||||
*
|
||||
* The DCO11 is a custom designed bipolar circuit that provides most of the timing signals required by the
|
||||
* video processor. Internal counters divide the output of a 24.0734 MHz oscillator (located elsewhere on the
|
||||
* terminal controller module) into the lower frequencies that define dot, character, scan, and frame timing.
|
||||
* The counters are programmable through various input pins to control the number of characters per line,
|
||||
* the frequency at which the screen is refreshed, and whether the display is interlaced or noninterlaced.
|
||||
* These parameters can be controlled through SET-UP mode or by the host.
|
||||
*
|
||||
* Table 4-6-1: Video Mode Selection (Write Address 0xC2)
|
||||
*
|
||||
* D5 D4 Configuration
|
||||
* -- -- -------------
|
||||
* 0 0 80-column mode, interlaced
|
||||
* 0 1 132-column mode, interlaced
|
||||
* 1 0 60Hz, non-interlaced
|
||||
* 1 1 50Hz, non-interlaced
|
||||
*
|
||||
* On p. 4-56, the DC011 Block Diagram shows 8 outputs labeled LBA0 through LBA7. From p. 4-61:
|
||||
*
|
||||
* Several of the LBAs are used as general purpose clocks in the VT100. LBA 3 and LBA 4 are used to generate
|
||||
* timing for the keyboard. These signals satisfy the keyboard's requirement of two square-waves, one twice the
|
||||
* frequency of the other, even though every 16th transition is delayed (the second stage of the horizontal
|
||||
* counter divides by 17, not 16). LBA 7 is used by the nonvolatile RAM.
|
||||
*
|
||||
* And on p. 4-62, timings are provided for the LBA0 through LBA7 when the VT100 is in 80-column mode; in particular:
|
||||
*
|
||||
* LBA6: 16.82353us (when LBA6 is low, for a period of 33.64706us)
|
||||
* LBA7: 31.77778us (when LBA7 is high, for a period of 63.55556us)
|
||||
*
|
||||
* If we assume that the CPU cycle count increments once every 361.69ns, it will increment roughly 88 times every
|
||||
* time LBA7 toggles. So we can divide the CPU cycle count by 88 and set LBA to the low bit of that truncated
|
||||
* result. An even faster (but less accurate) solution would be to mask bit 6 of the CPU cycle count, which will
|
||||
* doesn't change until the count has been incremented 64 times. See getVT100LBA() for the chosen implementation.
|
||||
*/
|
||||
DC011: { // generates Line Buffer Addresses (LBAs) for the Video Processor
|
||||
PORT: 0xC2, // write-only
|
||||
COLS80: 0x00,
|
||||
COLS132: 0x10,
|
||||
RATE60: 0x20,
|
||||
RATE50: 0x30,
|
||||
INITCOLS: 0x00, // ie, COLS80
|
||||
INITRATE: 0x20 // ie, RATE60
|
||||
},
|
||||
/*
|
||||
* DC012 is referred to as a Control Chip.
|
||||
|
|
@ -302,40 +330,33 @@ ChipSet.VT100 = {
|
|||
*/
|
||||
DC012: { // generates scan counts for the Video Processor
|
||||
PORT: 0xA2, // write-only
|
||||
INIT: 0x00 // for lack of a better guess
|
||||
SCROLL_LO: 0x00,
|
||||
INITSCROLL: 0x00,
|
||||
INITBLINK: 0x00,
|
||||
INITREVERSE:0x00,
|
||||
INITATTR: 0x00
|
||||
},
|
||||
/*
|
||||
* DC011 is referred to as a Timing Chip.
|
||||
*
|
||||
* As p. 4-55 (105) of the VT100 Technical Manual (July 1982) explains:
|
||||
*
|
||||
* The DCO11 is a custom designed bipolar circuit that provides most of the timing signals required by the
|
||||
* video processor. Internal counters divide the output of a 24.0734 MHz oscillator (located elsewhere on the
|
||||
* terminal controller module) into the lower frequencies that define dot, character, scan, and frame timing.
|
||||
* The counters are programmable through various input pins to control the number of characters per line,
|
||||
* the frequency at which the screen is refreshed, and whether the display is interlaced or noninterlaced.
|
||||
* These parameters can be controlled through SET-UP mode or by the host.
|
||||
*
|
||||
* On p. 4-56, the DC011 Block Diagram shows 8 outputs labeled LBA0 through LBA7. From p. 4-61:
|
||||
*
|
||||
* Several of the LBAs are used as general purpose clocks in the VT100. LBA 3 and LBA 4 are used to generate
|
||||
* timing for the keyboard. These signals satisfy the keyboard's requirement of two square-waves, one twice the
|
||||
* frequency of the other, even though every 16th transition is delayed (the second stage of the horizontal
|
||||
* counter divides by 17, not 16). LBA 7 is used by the nonvolatile RAM.
|
||||
*
|
||||
* And on p. 4-62, timings are provided for the LBA0 through LBA7 when the VT100 is in 80-column mode; in particular:
|
||||
*
|
||||
* LBA6: 16.82353us (when LBA6 is low, for a period of 33.64706us)
|
||||
* LBA7: 31.77778us (when LBA7 is high, for a period of 63.55556us)
|
||||
*
|
||||
* If we assume that the CPU cycle count increments once every 361.69ns, it will increment roughly 88 times every
|
||||
* time LBA7 toggles. So we can divide the CPU cycle count by 88 and set LBA to the low bit of that truncated
|
||||
* result. An even faster (but less accurate) solution would be to mask bit 6 of the CPU cycle count, which will
|
||||
* doesn't change until the count has been incremented 64 times. See getVT100LBA() for the chosen implementation.
|
||||
* ER1400 Non-Volatile RAM (NVR) Chip Definitions
|
||||
*/
|
||||
DC011: { // generates Line Buffer Addresses (LBAs) for the Video Processor
|
||||
PORT: 0xC2, // write-only
|
||||
INIT: 0x00 // for lack of a better guess
|
||||
NVR: {
|
||||
LATCH: {
|
||||
PORT: 0x62 // write-only
|
||||
},
|
||||
CMD: {
|
||||
ACCEPT_DATA: 0x0,
|
||||
ACCEPT_ADDR: 0x1,
|
||||
SHIFT_OUT: 0x2,
|
||||
WRITE: 0x4,
|
||||
ERASE: 0x5,
|
||||
READ: 0x6,
|
||||
STANDBY: 0x7
|
||||
},
|
||||
WORDMASK: 0x3fff // NVR words are 14-bit
|
||||
/*
|
||||
* The Technical Manual, p. 4-18, also notes that "Early VT100s can disable the receiver interrupt by
|
||||
* programming D4 in the NVR latch. However, this is never used by the VT100."
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -402,7 +423,8 @@ ChipSet.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
this.cmp = cmp;
|
||||
this.kbd = cmp.getMachineComponent("Keyboard");
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
this.video = /** @type {Video} */ (cmp.getMachineComponent("Video"));
|
||||
bus.addPortInputTable(this, this.config.portsInput);
|
||||
bus.addPortOutputTable(this, this.config.portsOutput);
|
||||
};
|
||||
|
|
@ -452,9 +474,17 @@ ChipSet.SI1978.INIT = [
|
|||
ChipSet.VT100.INIT = [
|
||||
[
|
||||
ChipSet.VT100.BRIGHTNESS.INIT,
|
||||
ChipSet.VT100.FLAGS_BUFFER.NO_AVO | ChipSet.VT100.FLAGS_BUFFER.NO_GFX,
|
||||
ChipSet.VT100.DC012.INIT,
|
||||
ChipSet.VT100.DC011.INIT
|
||||
ChipSet.VT100.FLAGS_BUFFER.NO_AVO | ChipSet.VT100.FLAGS_BUFFER.NO_GFX
|
||||
],
|
||||
[
|
||||
ChipSet.VT100.DC011.INITCOLS,
|
||||
ChipSet.VT100.DC011.INITRATE
|
||||
],
|
||||
[
|
||||
ChipSet.VT100.DC012.INITSCROLL,
|
||||
ChipSet.VT100.DC012.INITBLINK,
|
||||
ChipSet.VT100.DC012.INITREVERSE,
|
||||
ChipSet.VT100.DC012.INITATTR
|
||||
],
|
||||
[
|
||||
0, 0, 0, 0,
|
||||
|
|
@ -501,8 +531,10 @@ ChipSet.prototype.save = function()
|
|||
state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);
|
||||
break;
|
||||
case ChipSet.VT100.MODEL:
|
||||
state.set(0, [this.bBrightness, this.bFlagsBuffer, this.bDC012, this.bDC011]);
|
||||
state.set(1, [this.dNVRAddr, this.wNVRData, this.bNVRLatch, this.bNVROut, this.aNVRWords]);
|
||||
state.set(0, [this.bBrightness, this.bFlagsBuffer]);
|
||||
state.set(1, [this.bDC011Cols, this.bDC011Rate]);
|
||||
state.set(2, [this.bDC012Scroll, this.bDC012Blink, this.bDC012Reverse, this.bDC012Attr]);
|
||||
state.set(3, [this.dNVRAddr, this.wNVRData, this.bNVRLatch, this.bNVROut, this.aNVRWords]);
|
||||
break;
|
||||
}
|
||||
return state.data();
|
||||
|
|
@ -534,9 +566,15 @@ ChipSet.prototype.restore = function(data)
|
|||
case ChipSet.VT100.MODEL:
|
||||
this.bBrightness = a[0];
|
||||
this.bFlagsBuffer = a[1];
|
||||
this.bDC012 = a[2];
|
||||
this.bDC011 = a[3];
|
||||
a = data[1];
|
||||
this.bDC011Cols = a[0];
|
||||
this.bDC011Rate = a[1];
|
||||
a = data[2];
|
||||
this.bDC012Scroll = a[0];
|
||||
this.bDC012Blink = a[1];
|
||||
this.bDC012Reverse = a[2];
|
||||
this.bDC012Attr = a[3];
|
||||
a = data[3];
|
||||
this.dNVRAddr = a[0]; // 20-bit address
|
||||
this.wNVRData = a[1]; // 14-bit word
|
||||
this.bNVRLatch = a[2]; // 1 byte
|
||||
|
|
@ -909,9 +947,8 @@ ChipSet.prototype.outVT100NVRLatch = function(port, b, addrFrom)
|
|||
/**
|
||||
* outVT100DC012(port, b, addrFrom)
|
||||
*
|
||||
* TODO: Consider whether we should disable any interrupts (eg, vertical retrace) until the
|
||||
* this port is initialized at runtime. We initialize it ourselves at start-up, but our initial
|
||||
* value is just a guess.
|
||||
* TODO: Consider whether we should disable any interrupts (eg, vertical retrace) until
|
||||
* this port is initialized at runtime.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} port (0xA2)
|
||||
|
|
@ -921,7 +958,34 @@ ChipSet.prototype.outVT100NVRLatch = function(port, b, addrFrom)
|
|||
ChipSet.prototype.outVT100DC012 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "DC012");
|
||||
this.bDC012 = b;
|
||||
|
||||
var bOpt = b & 0x3;
|
||||
var bCmd = (b >> 2) & 0x3;
|
||||
switch(bCmd) {
|
||||
case 0x0:
|
||||
this.bDC012Scroll = (this.bDC012Scroll & ~0x3) | bOpt;
|
||||
break;
|
||||
case 0x1:
|
||||
this.bDC012Scroll = (this.bDC012Scroll & ~0xC) | (bOpt << 2);
|
||||
break;
|
||||
case 0x2:
|
||||
switch(bOpt) {
|
||||
case 0x0:
|
||||
this.bDC012Blink = ~this.bDC012Blink;
|
||||
break;
|
||||
case 0x1:
|
||||
// TODO: Clear vertical frequency interrupt
|
||||
break;
|
||||
case 0x2:
|
||||
case 0x3:
|
||||
this.bDC012Reverse = 0x3 - bOpt;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
this.bDC012Attr = bOpt;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -935,7 +999,25 @@ ChipSet.prototype.outVT100DC012 = function(port, b, addrFrom)
|
|||
ChipSet.prototype.outVT100DC011 = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "DC011");
|
||||
this.bDC011 = b;
|
||||
if (b & ChipSet.VT100.DC011.RATE60) {
|
||||
b &= ChipSet.VT100.DC011.RATE50;
|
||||
if (this.bDC011Rate != b) {
|
||||
this.bDC011Rate = b;
|
||||
if (this.video) {
|
||||
this.video.updateRate(this.bDC011Rate == ChipSet.VT100.DC011.RATE50? 50 : 60);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
b &= ChipSet.VT100.DC011.COLS132;
|
||||
if (this.bDC011Cols != b) {
|
||||
this.bDC011Cols = b;
|
||||
if (this.video) {
|
||||
var nCols = (this.bDC011Cols == ChipSet.VT100.DC011.COLS132? 132 : 80);
|
||||
var nRows = (nCols > 80 && (this.bFlagsBuffer & ChipSet.VT100.FLAGS_BUFFER.NO_AVO)? 14 : 24);
|
||||
this.video.updateDimensions(nCols, nRows);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -176,13 +176,13 @@ CPU.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
/*
|
||||
* We need to know the refresh rate (and corresponding interrupt rate, if any) of the Video component.
|
||||
*/
|
||||
var video = cmp.getMachineComponent("Video");
|
||||
var video = /** @type {Video} */ (cmp.getMachineComponent("Video"));
|
||||
this.refreshRate = video && video.getRefreshRate() || CPU.VIDEO_UPDATES_PER_SECOND;
|
||||
|
||||
/*
|
||||
* Attach the ChipSet component to the CPU so that it can be notified whenever the CPU stops and starts.
|
||||
*/
|
||||
this.chipset = cmp.getMachineComponent("ChipSet");
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
|
||||
/*
|
||||
* We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.
|
||||
|
|
|
|||
|
|
@ -72,9 +72,9 @@ Component.subclass(Keyboard);
|
|||
/**
|
||||
* Alphanumeric and other common (printable) ASCII codes.
|
||||
*
|
||||
* TODO: Determine what we can do to get ALL constants like these inlined (enum doesn't seem to
|
||||
* get the job done); the problem seems to be limited to property references that use quotes, which
|
||||
* is why I've 'unquoted' as many of them as possible.
|
||||
* TODO: Determine what we can do to get ALL constants like these inlined by the Closure Compiler
|
||||
* (enum doesn't seem to get the job done); the problem seems to be limited to property references
|
||||
* that use quotes, which is why I've 'unquoted' as many of them as possible.
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
|
|
@ -101,8 +101,8 @@ Keyboard.ASCII = {
|
|||
*
|
||||
* keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.
|
||||
*
|
||||
* Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined
|
||||
* them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).
|
||||
* Most of these represent non-ASCII characters (eg, the LEFT arrow key), yet for some reason, browsers
|
||||
* defined them using ASCII codes (eg, the LEFT arrow key uses 37, which is the ASCII code for '%').
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
|
|
@ -282,13 +282,15 @@ Keyboard.VT100 = {
|
|||
KEYMAP: {},
|
||||
ALTCODES: {},
|
||||
LEDCODES: {},
|
||||
SOFTCODES: {},
|
||||
SOFTCODES: {
|
||||
'setup': Keyboard.KEYCODE.F9
|
||||
},
|
||||
/*
|
||||
* Reading port 0x82 returns a key address from the VT100 keyboard's UART data output.
|
||||
*
|
||||
* Every time a keyboard scan is initiated (by setting the START bit of the status byte),
|
||||
* an internal address index is reset to zero, and an interrupt is generated for each entry
|
||||
* in the aKeysActive array, along with a final interrupt for KEYLAST.
|
||||
* our internal address index (iKeyNext) is set to zero, and an interrupt is generated for
|
||||
* each entry in the aKeysActive array, along with a final interrupt for KEYLAST.
|
||||
*/
|
||||
ADDRESS: {
|
||||
PORT: 0x82,
|
||||
|
|
@ -320,9 +322,12 @@ Keyboard.VT100 = {
|
|||
CLICK: 0x80,
|
||||
INIT: 0x00
|
||||
},
|
||||
KEYLAST: 0x7F
|
||||
KEYLAST: 0x7F // special end-of-scan key address (all valid key addresses are < KEYLAST)
|
||||
};
|
||||
|
||||
/*
|
||||
* Table to map host key codes to VT100 key addresses (ie, unique 7-bit values representing key positions on the VT100)
|
||||
*/
|
||||
Keyboard.VT100.KEYMAP[Keyboard.KEYCODE.DEL] = 0x03;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.P] = 0x05;
|
||||
Keyboard.VT100.KEYMAP[Keyboard.ASCII.O] = 0x06;
|
||||
|
|
@ -486,16 +491,25 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
default:
|
||||
if (this.config.SOFTCODES && this.config.SOFTCODES[sBinding] !== undefined) {
|
||||
this.bindings[id] = control;
|
||||
var fnDown = function(kbd, sSoftCode) {
|
||||
return function onMouseOrTouchDownKeyboard(event) {
|
||||
kbd.onSoftKeyDown(sSoftCode, true);
|
||||
var fnDown = function(kbd, softCode) {
|
||||
return function onKeyboardBindingDown(event) {
|
||||
kbd.onSoftKeyDown(softCode, true);
|
||||
/*
|
||||
* I'm assuming we only need to give focus back on the "up" event...
|
||||
*
|
||||
* if (kbd.cmp) kbd.cmp.updateFocus();
|
||||
*/
|
||||
};
|
||||
}(this, sBinding);
|
||||
var fnUp = function (kbd, sSoftCode) {
|
||||
return function onMouseOrTouchUpKeyboard(event) {
|
||||
kbd.onSoftKeyDown(sSoftCode, false);
|
||||
}(this, this.config.SOFTCODES[sBinding]);
|
||||
var fnUp = function (kbd, softCode) {
|
||||
return function onKeyboardBindingUp(event) {
|
||||
kbd.onSoftKeyDown(softCode, false);
|
||||
/*
|
||||
* Give focus back to the machine (since clicking the button takes focus away).
|
||||
*/
|
||||
if (kbd.cmp) kbd.cmp.updateFocus();
|
||||
};
|
||||
}(this, sBinding);
|
||||
}(this, this.config.SOFTCODES[sBinding]);
|
||||
if ('ontouchstart' in window) {
|
||||
control.ontouchstart = fnDown;
|
||||
control.ontouchend = fnUp;
|
||||
|
|
@ -522,9 +536,10 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
*/
|
||||
Keyboard.prototype.initBus = function(cmp, bus, cpu, dbg)
|
||||
{
|
||||
this.cmp = cmp;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg; // NOTE: The "dbg" property must be set for the message functions to work
|
||||
this.chipset = cmp.getMachineComponent("ChipSet");
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
bus.addPortInputTable(this, this.config.portsInput);
|
||||
bus.addPortOutputTable(this, this.config.portsOutput);
|
||||
};
|
||||
|
|
@ -873,8 +888,8 @@ Keyboard.prototype.checkBusy = function()
|
|||
*
|
||||
* We take our cue from iKeyNext. If it's -1 (default), we simply return the last value latched
|
||||
* in bVT100Address. Otherwise, if iKeyNext is a valid index into aKeysActive, we look up the key
|
||||
* in the VT100.KEYMAP, latch it, and increment iKeyNext, else we latch Keyboard.VT100.KEYLAST
|
||||
* and set iKeyNext to -1 again.
|
||||
* in the VT100.KEYMAP, latch it, and increment iKeyNext. Failing that, we latch Keyboard.VT100.KEYLAST
|
||||
* and reset iKeyNext to -1.
|
||||
*
|
||||
* @this {Keyboard}
|
||||
* @param {number} port (0x82)
|
||||
|
|
@ -893,8 +908,8 @@ Keyboard.prototype.inVT100UARTAddress = function(port, addrFrom)
|
|||
/*
|
||||
* In MAXDEBUG builds, this code removes the key as soon as it's been reported, because
|
||||
* when debugging, it's easy for the window to lose focus and never receive the keyUp event,
|
||||
* thereby leaving us with a stuck key. However, this causes more problems than it solves,
|
||||
* and seems to illustrate that key presses need to be persist for more than a single poll.
|
||||
* thereby leaving us with a stuck key. However, this may cause more problems than it solves,
|
||||
* because the VT100's ROM seems to require that key presses persist for more than a single poll.
|
||||
*/
|
||||
this.aKeysActive.splice(this.iKeyNext, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ Panel.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
this.kbd = cmp.getMachineComponent("Keyboard");
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ SerialPort.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
this.bus = bus;
|
||||
this.cpu = cpu;
|
||||
this.dbg = dbg;
|
||||
this.chipset = cmp.getMachineComponent("ChipSet");
|
||||
this.chipset = /** @type {ChipSet} */ (cmp.getMachineComponent("ChipSet"));
|
||||
bus.addPortInputTable(this, SerialPort.aPortInput, this.portBase);
|
||||
bus.addPortOutputTable(this, SerialPort.aPortOutput, this.portBase);
|
||||
this.setReady();
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ Video.prototype.initBus = function(cmp, bus, cpu, dbg)
|
|||
* If we have an associated keyboard, then ensure that the keyboard will be notified
|
||||
* whenever the canvas gets focus and receives input.
|
||||
*/
|
||||
this.kbd = cmp.getMachineComponent("Keyboard");
|
||||
this.kbd = /** @type {Keyboard} */ (cmp.getMachineComponent("Keyboard"));
|
||||
if (this.kbd) {
|
||||
for (var s in this.ledBindings) {
|
||||
this.kbd.setBinding("led", s, this.ledBindings[s]);
|
||||
|
|
@ -712,6 +712,34 @@ Video.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* updateDimensions(nCols, nRows)
|
||||
*
|
||||
* Called from the ChipSet component whenever the screen dimensions have been dynamically altered.
|
||||
*
|
||||
* @this {Video}
|
||||
* @param {number} nCols (should be either 80 or 132; 80 is the default)
|
||||
* @param {number} nRows (should be either 24 or 14; 24 is the default)
|
||||
*/
|
||||
Video.prototype.updateDimensions = function(nCols, nRows)
|
||||
{
|
||||
this.println("updateDimensions(" + nCols + "," + nRows + ")");
|
||||
};
|
||||
|
||||
/**
|
||||
* updateRate(nRate)
|
||||
*
|
||||
* Called from the ChipSet component whenever the monitor refresh rate has been dynamically altered.
|
||||
*
|
||||
* @this {Video}
|
||||
* @param {number} nRate (should be either 50 or 60; 60 is the default)
|
||||
*/
|
||||
Video.prototype.updateRate = function(nRate)
|
||||
{
|
||||
this.println("updateRate(" + nRate + ")");
|
||||
this.rateMonitor = nRate;
|
||||
};
|
||||
|
||||
/**
|
||||
* doFullScreen()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1220,7 +1220,7 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
if (Keyboard.CLICKCODES[sCode] !== undefined && sHTMLType == "button") {
|
||||
this.bindings[id] = control;
|
||||
control.onclick = function(kbd, sKey, simCode) {
|
||||
return function onClickKeyboard(event) {
|
||||
return function onKeyboardBindingClick(event) {
|
||||
if (!COMPILED && kbd.messageEnabled()) kbd.printMessage(sKey + " clicked", Messages.KEYS);
|
||||
if (kbd.cmp) kbd.cmp.updateFocus();
|
||||
kbd.updateShiftState(simCode, true); // future-proofing if/when any LOCK keys are added to CLICKCODES
|
||||
|
|
@ -1233,12 +1233,12 @@ Keyboard.prototype.setBinding = function(sHTMLType, sBinding, control, sValue)
|
|||
this.cSoftCodes++;
|
||||
this.bindings[id] = control;
|
||||
var fnDown = function(kbd, sKey, simCode) {
|
||||
return function onMouseOrTouchDownKeyboard(event) {
|
||||
return function onKeyboardBindingDown(event) {
|
||||
kbd.addActiveKey(simCode);
|
||||
};
|
||||
}(this, sBinding, Keyboard.SOFTCODES[sBinding]);
|
||||
var fnUp = function (kbd, sKey, simCode) {
|
||||
return function onMouseOrTouchUpKeyboard(event) {
|
||||
return function onKeyboardBindingUp(event) {
|
||||
kbd.removeActiveKey(simCode);
|
||||
};
|
||||
}(this, sBinding, Keyboard.SOFTCODES[sBinding]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue