Removed all obsolete @suppress directives

This commit is contained in:
Jeff Parsons 2014-10-30 16:36:23 -07:00 committed by jeffpar
commit 426fd0ff40
60 changed files with 6221 additions and 340 deletions

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs Computer component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-15
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -53,7 +52,7 @@
* The C1Pjs JavaScript files do have some initialization-order dependencies.
* If you load the files individually, it's recommended that you load them in
* the same order that they're compiled (see above).
*
*
* Generally speaking, component.js should be first, computer.js should be
* last (of the files based on component.js), and panel.js should be listed
* early so that the Control Panel is ready as soon as possible.
@ -74,13 +73,13 @@
* play nice and use only its assigned section of abMemory -- and pretend it's an array
* of bytes, when in fact it's an array of floating-point values (the only primitive
* numeric data type that JavaScript provides).
*
*
* This component also insures that all the other components are ready; in particular,
* this means that the ROM and Video components have finished loading their resources
* and are ready for operation. Other components become ready as soon as we call their
* setBuffer() method (eg, CPU, RAM, Keyboard, Debugger, SerialPort, DiskController), and
* others, like Panel, become ready even earlier, at the end of their initialization.
*
*
* Once every component has indicated it's ready, we call its setPower() notification
* function (if it has one; it's optional). We call the CPU's setPower() function last,
* so that the CPU is assured that all other components are ready and "powered".
@ -91,7 +90,7 @@
function C1PComputer(parmsComputer, modules)
{
Component.call(this, "C1PComputer", parmsComputer);
this.modules = modules;
}
@ -126,7 +125,7 @@ C1PComputer.prototype.reset = function(fPowerOn)
/**
* @this {C1PComputer}
*
*
* Called by the CPU to notify all component start() handlers
*/
C1PComputer.prototype.start = function()
@ -146,7 +145,7 @@ C1PComputer.prototype.start = function()
* @this {C1PComputer}
* @param {number} msStart
* @param {number} nCycles
*
*
* Called by the CPU to notify all component stop() handlers
*/
C1PComputer.prototype.stop = function(msStart, nCycles)
@ -191,7 +190,7 @@ C1PComputer.prototype.setBinding = function(c, t, s, e)
* @this {C1PComputer}
* @param {string} sType
* @return {Component}
*
*
* NOTE: If there are multiple components for a given type, we may need to provide a means of discriminating.
*/
C1PComputer.prototype.getComponentByType = function(sType)
@ -232,11 +231,11 @@ C1PComputer.power = function(computer)
}
}
}
/*
* The entire computer is finally ready; we call our own setReady() for completeness, not because any
* other component actually cares when we're ready.
*/
*/
computer.setReady();
computer.println(C1PComputer.sAppName + " v" + C1PComputer.sAppVer + "\n" + C1PComputer.sCopyright);
@ -273,13 +272,13 @@ C1PComputer.init = function()
var abMemory;
var addrStart = 0, addrEnd = 0;
for (var iAddr=0; iAddr < parmsComputer['modules'].length; iAddr++) {
var addrInfo = parmsComputer['modules'][iAddr];
/*
* The first address range (ie, the CPU range) must specify the range for the entire
* address space (abMemory), which we allocate and zero-initialize.
*
*
* NOTE: We might consider doing what the Video component does on first reset: initializing
* the entire memory buffer to random values. However, a constant (eg, 0xA5) might be
* more useful, acting as a crude indicator of memory the client code hasn't written yet.
@ -308,7 +307,7 @@ C1PComputer.init = function()
return;
}
}
if (abMemory === undefined) {
Component.error("<module type=\"cpu\"> definition must appear first in the <computer> specification");
return;
@ -317,7 +316,7 @@ C1PComputer.init = function()
/*
* Let's see if the Debugger is installed (NOTE: its ID must be "debugger", and only one per machine is supported);
* the Debugger needs our setBuffer(), setPower() and reset() notifications, and this relieves us from having an explicit
* <module> entry for type="debugger".
* <module> entry for type="debugger".
*/
component = Component.getComponentByID('debugger', parmsComputer['id']);
if (component) {
@ -326,12 +325,12 @@ C1PComputer.init = function()
component.setBuffer(abMemory, addrStart, addrEnd, modules['cpu'][0]);
}
}
var computer = new C1PComputer(parmsComputer, modules);
/*
* Let's see if the Control Panel is installed (NOTE: its ID must be "panel", and only one per machine is supported);
* the Panel needs our setPower() notifications, and this relieves us from having an explicit <module> entry for type="panel".
* Let's see if the Control Panel is installed (NOTE: its ID must be "panel", and only one per machine is supported);
* the Panel needs our setPower() notifications, and this relieves us from having an explicit <module> entry for type="panel".
*/
var panel = Component.getComponentByID('panel', parmsComputer['id']);
if (panel) {
@ -355,7 +354,7 @@ C1PComputer.init = function()
* We may eventually add a "Power" button, but for now, all we have is a "Reset" button
*/
Component.bindComponentControls(computer, eComputer, C1PJSCLASS);
/*
* "Power" the computer automatically
*/

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs 6502 CPU component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-15
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs Debugger component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-21
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -35,12 +34,12 @@
/**
* C1PDebugger(parmsDbg)
*
*
* The C1PDebugger component has no required (parmsDbg) properties.
*
* The C1PDebugger component is an optional component that implements a variety of user
* commands for controlling the CPU, dumping and editing memory, etc.
*
*
* @constructor
* @extends Component
*/
@ -49,7 +48,7 @@ function C1PDebugger(parmsDbg)
if (DEBUGGER) {
Component.call(this, "C1PDebugger", parmsDbg);
/*
* This keeps track of instruction activity, but only when tracing or when
* Debugger checks have been enabled (eg, one or more breakpoints have been set).
@ -58,25 +57,25 @@ function C1PDebugger(parmsDbg)
* We set it here to -1 to indicate that the CPU has not yet initialized us.
*/
this.cIns = -1;
/*
* Some commands, like the dump (d) command, start at nextAddr when no address
* is given (and they also update nextAddr when they're done).
*/
this.nextAddr = 0;
/*
* When Enter is pressed on an empty input buffer, we default to the previous
* command, which is preserved here.
*/
this.prevCmd = null;
/*
* fAssemble is true when "assemble mode" is active, false when not.
*/
this.fAssemble = false;
this.addrAssembleNext = 0;
/*
* Initialize the lists of breakpoint addresses. aExecBreak is a list (Array) of addresses
* to halt at whenever attempting to execute an instruction at the corresponding address,
@ -84,7 +83,7 @@ function C1PDebugger(parmsDbg)
* respectively, occurs at the corresponding address.
*/
this.clearBreakpoints();
/*
* Instead of pre-allocating these arrays, we wait until our reset() function is called.
* These arrays are updated in checkInstruction(), but the CPU will never actually call it
@ -94,7 +93,7 @@ function C1PDebugger(parmsDbg)
this.iStepHistory = 0;
this.aStepHistory = [];
this.aaOpcodeFreqs = [];
/*
* This "info" buffer is a lightweight logging mechanism that has minimal impact on the
* browser (unlike printing to either window.console.log or an HTML control, which can make
@ -106,7 +105,7 @@ function C1PDebugger(parmsDbg)
this.iInfoBuffer = 0;
this.aInfoBuffer = new Array(10000);
}
/*
* Message categories supported by the message() function; they are designed to be combined
* (ie, OR'ed) as needed. The Debugger's "option" command is used to turn message categories
@ -131,7 +130,7 @@ function C1PDebugger(parmsDbg)
'disk': this.MESSAGE_DISK,
'serial': this.MESSAGE_SERIAL
};
/*
* The aaOperations array is indexed by opcode, and each element is a sub-array that
* describes the corresponding opcode. The sub-elements are as follows:
@ -202,7 +201,7 @@ function C1PDebugger(parmsDbg)
this.OP_TYA = 55;
this.OP_SIM = 56;
this.OP_DB = 57;
this.aOpCodes = [
"ADC","AND","ASL","BCC","BCS","BEQ","BIT","BMI",
"BNE","BPL","BRK","BVC","BVS","CLC","CLD","CLI",
@ -213,13 +212,13 @@ function C1PDebugger(parmsDbg)
"STX","STY","TAX","TAY","TSX","TXA","TXS","TYA",
"SIM",".DB"
];
this.aOpSimCodes = [
"HLT", "MSG"
];
this.setOpModes(true);
this.aaOperations = [
/* 0x00 */ [this.OP_BRK],
/* 0x01 */ [this.OP_ORA, 1, this.MODE_INDX],
@ -657,7 +656,7 @@ if (DEBUGGER) {
var sRegEx = "";
var iMode, sMode;
if (fClassic) {
this.aOpModes = [
"A", // MODE_ACC
@ -986,7 +985,7 @@ if (DEBUGGER) {
* NOTE: We keep track of zero-page writes mainly as a reminder to look into whether it makes sense
* for the CPU to calculate zero-page EAs using a different variable (eg, regEAWriteZP instead of regEAWrite),
* because write-notification handlers never care about page zero accesses, and while write breakpoints *may*
* care, it may not be worth the cost of tracking writes to page zero if there's an associated perf penalty.
* care, it may not be worth the cost of tracking writes to page zero if there's an associated perf penalty.
*/
if (!(addr & 0xff00))
this.cWritesZP++;
@ -1207,7 +1206,7 @@ if (DEBUGGER) {
/**
* @this {C1PDebugger}
* @param {number} addr to compare to addrTempBP; the latter is cleared if there's a match
* @param {number} addr to compare to addrTempBP; the latter is cleared if there's a match
*/
C1PDebugger.prototype.clearTempBreakpoint = function(addr)
{
@ -1517,7 +1516,6 @@ if (DEBUGGER) {
* @this {C1PDebugger}
* @param {string|undefined} [sAddr]
* @return {number|undefined}
* @suppress {checkTypes}
*/
C1PDebugger.prototype.getUserAddr = function(sAddr)
{
@ -1843,7 +1841,7 @@ if (DEBUGGER) {
};
/**
* Prints the contents of the Debugger's "info" buffer (filled by calls like cpu.dbg.info())
* Prints the contents of the Debugger's "info" buffer (filled by calls like cpu.dbg.info())
* @this {C1PDebugger}
* @param {string|undefined} sCount
* @return {boolean|undefined} true only if the "info" command is supported
@ -2127,7 +2125,7 @@ if (DEBUGGER) {
sCmd = dbg.prevCmd;
}
if (dbg.isReady() && !dbg.isBusy(true) && sCmd.length > 0) {
if (dbg.fAssemble) {
sCmd = "a " + str.toHexWord(dbg.addrAssembleNext) + " " + sCmd;
}
@ -2139,10 +2137,10 @@ if (DEBUGGER) {
var ch = sCmd.charAt(0).toLowerCase();
sCmd = ch + " " + sCmd.substr(1);
}
var asArgs = sCmd.split(" ");
dbg.prevCmd = asArgs[0];
switch(asArgs[0].toLowerCase()) {
case "a":
dbg.doAssemble(asArgs);
@ -2189,14 +2187,14 @@ if (DEBUGGER) {
break;
case "i":
if (dbg.doInfo(asArgs[1])) break;
/* falls through */
/* falls through */
default:
dbg.println("unknown command: " + sCmd);
break;
}
}
};
/**
* C1PDebugger.init()
*
@ -2217,7 +2215,7 @@ if (DEBUGGER) {
Component.bindComponentControls(dbg, eDbg, C1PJSCLASS);
}
};
/*
* Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))
*/

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs DiskController component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Aug-09
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs Keyboard component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-20
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -327,7 +326,7 @@ C1PKeyboard.prototype.reset = function()
*
* Like bitsShift, this 8x8 array (8 byte values, each with 8 bits) represents
* the physical state of the keyboard, encoded in C1P format; the C1P won't
* actually see data this until updateMemory() decides it's time to propagate it.
* actually see data this until updateMemory() decides it's time to propagate it.
*/
this.abKbdCols = [this.BIT_SHIFTLOCK,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
@ -539,7 +538,7 @@ C1PKeyboard.prototype.setReady = function()
/**
* calcReleaseDelay(fRepeat
*
*
* This attempts to scale our default "release" delay appropriately for the current CPU speed.
*
* Note that if the effective CPU speed exceeds 16Mhz, it becomes very difficult to rely on timer-driven key events
@ -631,7 +630,7 @@ C1PKeyboard.prototype.injectKeysFromBuffer = function(msDelay)
*
* UPDATE: Even though keyPressSimulate() currently has some code to do this automatically now,
* it's really intended as a work-around for a SHIFT-related problem on iOS devices only, so
* we can't rely on that in the general case.
* we can't rely on that in the general case.
*/
if (ch >= 0x41 && ch <= 0x5A)
ch += 0x20;
@ -711,7 +710,7 @@ C1PKeyboard.prototype.keyEvent = function(event, fDown)
* browser will see it and give focus to the next control. But the "down" side is that
* that no "press" event will be generated. This puts it in the same category as ESC,
* which also generates "down" and "up" events (LOTS of "down" events for that matter),
* but no "press" event. However, the C1P has no TAB key, so it's safe to completely ignore.
* but no "press" event. However, the C1P has no TAB key, so it's safe to completely ignore.
*/
fPass = fAutoClear = false;
}

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs Panel component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-19
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -44,7 +43,7 @@
function C1PPanel(parmsPanel)
{
Component.call(this, "C1PPanel", parmsPanel);
this.fPower = false;
}
@ -90,19 +89,19 @@ C1PPanel.prototype.setPower = function(fOn, cmp)
/**
* C1PPanel.init()
*
*
* This function operates on every element (e) of class "panel", and initializes
* all the necessary HTML to construct the Panel module(s) as spec'ed.
*
* Note that each element (e) of class "panel" is expected to have a "data-value"
* attribute containing the same JSON-encoded parameters that the Panel constructor
* expects.
*
*
* NOTE: Unlike most other component init() functions, this one is designed to be
* called multiple times: once at load time, so that we can binding our print()
* function to the panel's output control ASAP, and again when the Computer component
* is verifying that all components are ready and invoking their setPower() functions.
*
*
* Our setPower() method gives us a second opportunity to notify any components that
* that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they
* might want to use.

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs RAM component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-15
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs ROM component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-15
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs SerialPort component.
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jul-01
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -47,7 +46,7 @@ function C1PSerialPort(parmsSerial)
this.fPower = false;
this.fDemo = parmsSerial['demo'];
this.STATUS_NONE = 0x00;
this.STATUS_DATA = 0x01; // indicates data available
@ -155,7 +154,7 @@ C1PSerialPort.prototype.setBuffer = function(abMemory, start, end, cpu)
* @this {C1PSerialPort}
* @param {boolean} fOn
* @param {C1PComputer} cmp
*
*
* We make a note of the Computer component, so that we can invoke its reset() method whenever we need to
* simulate a warm start, and we query the Keyboard component so that we can use its injectKeys() function.
*/

View file

@ -2,7 +2,6 @@
* @fileoverview This file implements the C1Pjs Video component
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a>
* @version 1.0
* @suppress {missingProperties}
* Created 2012-Jun-15
*
* Copyright © 2012-2014 Jeff Parsons <Jeff@pcjs.org>
@ -35,7 +34,7 @@
/**
* C1PVideo(parmsVideo, eCanvas, context, imgChars)
*
*
* The Video component can be configured with the following (parmsVideo) properties:
*
* model: model number (one of: 540 or 600; 600 is the default)
@ -56,7 +55,7 @@
* must be given to it by the Computer object. We allocate a separate buffer, called
* the screen buffer, into which we periodically copy the contents of the video buffer
* via updateScreen(); any differences between the two buffers are then rendered in the
* associated window, via updateWindow().
* associated window, via updateWindow().
*
* When updateScreen() finds a byte in the screen buffer must be redisplayed, it converts
* the offset of that byte into a (col,row) character position for the updateWindow() function,
@ -71,7 +70,7 @@
* columns, the practical maximum is 24 rows x 24 columns; the last 4 rows of the video buffer
* are never used, and while content scrolls through the top 4 lines of the buffer, it is never
* assumed that you can see the top 4 lines.
*
*
* This is partially confirmed by the "C1P Character Graphics Reference Manual", p3, which says
* that the "the visible character field consists of 25 lines of 25 columns" and that the "first
* visible character in the upper left of the screen is accessed via address 53379," or 0xD083,
@ -79,66 +78,66 @@
* regarding "25 lines of 25 columns" seems to be off by one in both dimensions. And why would
* they say that the first visible address is 0xD083 instead of 0xD085? An indentation of 5 bytes,
* rather than 3, would be more consistent with how the C1P ROMs use video memory.
*
*
* Model 540 Video Board vs. Model 600 "Superboard II"
* ---------------------------------------------------
* This emulation was originally written for the Model 600 "Superboard II" (eg, Challenger 1P).
* Support for the Model 540 video board (as used in the Challenger II-4P and II-8P) was added
* later.
*
*
* NOTE: When Model 540 video emulation is enabled, Model 542 keyboard emulation must also be
* enabled, because the former always came with the latter keyboard interface; this is why when
* we call this.setModel(540), we must also notify the Keyboard via kbd.setModel(542).
*
*
* Key features/differences of the Model 540 video board include:
*
*
* 2K (8 pages) of video memory located at 0xD000-0xD7FF
* Two display modes: 32 rows x 64 cols (default on power up), and 32 rows x 32 cols
* 64 bytes per screen row, regardless which display mode is selected
* The following options can be selected via WRITE to port address 0xDE00:
* Bit 0: clear to enable 32/64 mode (default on power up), set to enable 32/32
* Bit 1: 1=tone on (542 keyboard)
* Bit 2: 1=color on (Rev. B only?)
* Bit 2: 1=color on (Rev. B only?)
* bit 3: 1=enable 38-40Khz AC Home control output (Rev. B only?)
* Video timing counter status via READ from port address 0xDE00:
* Bit 7: 0 for 1/120 second, then 1 for 1/120 second, based on video clock (60Hz)
*
*
* @constructor
* @extends Component
*/
function C1PVideo(parmsVideo, eCanvas, context, imgChars)
{
Component.call(this, "C1PVideo", parmsVideo);
this.nDefaultModel = parmsVideo['model'];
this.nDefaultCols = parmsVideo['charCols'];
this.nDefaultRows = parmsVideo['charRows'];
this.cxScreen = parmsVideo['screenWidth'];
this.cyScreen = parmsVideo['screenHeight'];
/*
* These (source) character dimensions are tentative, and may not even be provided,
* but they will become definitive once imgChars has finished loading and setReady() is called.
*/
this.cxChar = parmsVideo['charWidth'];
this.cyChar = parmsVideo['charHeight'];
/*
* This is a preliminary call to setDimensions(), to initialize default screen buffer and
* window dimensions. A more extensive call to setDimensions() will take place when setModel()
* is called later, from reset() and possibly via the tripGuard() handler.
*
*
* This preliminary call merely establishes a default screen buffer size, so that when
* setBuffer() is called, it's able to verify the assigned address space is at least as big
* setBuffer() is called, it's able to verify the assigned address space is at least as big
* as the screen buffer.
*/
this.setDimensions();
this.eCanvas = eCanvas;
this.context = context;
this.imgChars = imgChars;
/*
* QUESTION: Does this video port exist only on the Model 540?
*/
@ -155,7 +154,7 @@ Component.subclass(Component, C1PVideo);
C1PVideo.prototype.reset = function(fPowerOn)
{
this.setModel(this.nDefaultModel);
if (this.abMem) {
/*
* Let's treat every reset like a power-cycle, just for fun.
@ -245,7 +244,7 @@ C1PVideo.prototype.setDimensions = function(nCols, nRows, iRowTop, nRowsVisible)
/**
* @this {C1PVideo}
*
*
* cxScreen and cyScreen give us the overall dimensions of the destination surface. Dividing that by the number of
* columns and rows yields a target cell size (cxCharDst,cyCharDst), which may or may not map 1-1 to the source cell size
* (cxChar,cyChar).
@ -283,7 +282,7 @@ C1PVideo.prototype.setModel = function(nModel)
* buffer range, not the FIRST byte, which has the same effect but with the
* added benefit of deferring any screen update until after the "Model 540"
* screen initialization code has completely blanked the entire 2K buffer,
* avoiding a brief flicker of unsightly characters.
* avoiding a brief flicker of unsightly characters.
*/
this.addrGuard = this.offVideoLimit + this.cbScreen - 1;
this.cpu.addWriteNotify(this.addrGuard, this.addrGuard, this, this.tripGuard);
@ -315,7 +314,7 @@ C1PVideo.prototype.setPower = function(fOn, cmp)
/*
* If we have an associated keyboard, then ensure that the keyboard will be notified whenever
* the canvas gets focus and receives input.
*
*
* Also, when simulating a Model 540 video board, we need to access to the Keyboard component due
* to some shared I/O responsibilities; ie, bit 1 of the video control port at 0xDE00 enables whatever
* tone has been selected via the keyboard frequency port at 0xDF01 (frequency == 49152/n, where n
@ -340,7 +339,7 @@ C1PVideo.prototype.setPower = function(fOn, cmp)
/**
* @this {C1PVideo}
*
*
* cxChar and cyChar are the source cell size. Originally, those values came strictly from the parmsVideo
* 'charWidth' and 'charHeight' properties. Now, if those aren't defined (which is normally the case now),
* then we infer the source cell size from the dimensions of imgChars, which is expected to be a 16x16 array of
@ -372,7 +371,7 @@ C1PVideo.prototype.getByte = function(addr, addrFrom)
* The only documented READ bit in addrVideoPort is bit 7, which is supposed to alternate between
* 0 and 1 every 1/120 of a second. There's no way we're going to add special code to the emulator to update
* this stupid byte every 8,333 cycles (assuming 1Mhz operation), so clearly we're going to fake it.
*
*
* Faking it means that any polling code will unavoidably get a stale value the FIRST time it reads bit 7.
* However, we can still do a pretty good job of faking any EXTENSIVE polling: get the number of cycles
* executed so far, divide that by 8333, floor the quotient, and then set/clear bit 7 according to whether the
@ -410,7 +409,7 @@ C1PVideo.prototype.tripGuard = function(addr, addrFrom)
/*
* The CPU has just written to the guard address we established just beyond the video buffer's 1K boundary,
* implying that the system thinks we have a 2K buffer instead. So we bump our model to 540, bump the
* associated keyboard model to 542, and remove this guard handler.
* associated keyboard model to 542, and remove this guard handler.
*/
this.setModel(540);
if (this.kbd) this.kbd.setModel(542);
@ -431,7 +430,7 @@ C1PVideo.prototype.initScreen = function()
/**
* updateScreen() updates the screen buffer from the video buffer and updates the window with any changes.
*
*
* @this {C1PVideo}
* @return {boolean}
*
@ -474,19 +473,19 @@ C1PVideo.prototype.writeByte = function(offset, b)
/**
* updateWindow() updates a particular position (row,col) in the associated window with the given byte (b)
*
*
* @this {C1PVideo}
* @param {number} col
* @param {number} row
* @param {number} b
* @return {boolean} true if successful, false if not
*
* @return {boolean} true if successful, false if not
*
* I originally used (screenWidth,screenHeight) == (512,448) and (cols,rows) == (32,32) and (cxChar,cyChar) == (16,16),
* and I simply copied the source cells 1-to-1 to the destination (16,16), knowing that we would never try to display more
* than 28 rows (the last 4 rows of the 32 possible rows were never used to display any content). However, I should still
* have ignored any attempt to draw past row 28 (aka screenHeight 448). I now perform row clipping and biasing, according
* to the first visible row (iRowTop) and total visible rows (nRowsVisible).
*
*
* Moreover, I no longer copy the source cell images to the destination 1-to-1. I calculate (cxCharDst,cyCharDst) separately
* (see setDrawingDimensions). And I no longer assume that (cxChar,cyChar) are (16,16); once the source image file has finished
* loading, I calculate (cxChar,cyChar) based on the size of image file (see setReady). I made this change when I created
@ -527,7 +526,7 @@ C1PVideo.init = function()
for (var iVideo=0; iVideo < aeVideo.length; iVideo++) {
var eVideo = aeVideo[iVideo];
var parmsVideo = Component.getComponentParms(eVideo);
/*
* As noted in keyboard.js, the keyboard on an iOS device pops up with the SHIFT key depressed,
* which is not the initial keyboard state that the C1P expects. I originally tried to fix that by
@ -545,7 +544,7 @@ C1PVideo.init = function()
eCanvas.setAttribute("class", C1PJSCLASS + "-canvas");
eCanvas.setAttribute("width", parmsVideo['screenWidth']);
eCanvas.setAttribute("height", parmsVideo['screenHeight']);
eCanvas.setAttribute("contenteditable", "true");
eCanvas.setAttribute("autocapitalize", "off");
eCanvas.setAttribute("autocorrect", "off");
@ -569,7 +568,7 @@ C1PVideo.init = function()
/*
* Now we can create the Video object, record it, and wire it up to the associated document elements.
*
*
* Regarding "new Image()", see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement.Image:
*
* This constructor exists for historical reasons only and returns an HTMLImageElement instance just as
@ -577,7 +576,7 @@ C1PVideo.init = function()
*/
var imgCharSet = new Image();
var contextVideo = eCanvas.getContext("2d");
var video = new C1PVideo(parmsVideo, eCanvas, contextVideo, imgCharSet);
var video = new C1PVideo(parmsVideo, eCanvas, contextVideo, imgCharSet);
imgCharSet.onload = function(video, sCharSet) {
return function() {
if (DEBUG) video.log("onload(): finished loading " + sCharSet);
@ -588,7 +587,7 @@ C1PVideo.init = function()
/*
* Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;
* even the "Refresh" button is just a diagnostic tool, to verify that the screen contents are up-to-date.
* even the "Refresh" button is just a diagnostic tool, to verify that the screen contents are up-to-date.
*/
Component.bindComponentControls(video, eVideo, C1PJSCLASS);
}