Changed C1Pjs to display 25 rows instead of 24
This commit is contained in:
parent
ae12b3293b
commit
9ba73970a4
15 changed files with 64 additions and 43 deletions
|
|
@ -20,7 +20,7 @@
|
|||
<rom id="romNull" size="0x8000"/>
|
||||
<rom id="romBasic" size="0x2000" image="/devices/c1p/rom/basic-gcpatch.hex"/>
|
||||
<rom id="romSystem" size="0x0800" image="/devices/c1p/rom/system.hex"/>
|
||||
<video id="video" screenwidth="256" screenheight="192" cols="32" rows="32" charset="/devices/c1p/video/chargen1x.png" padding="8px"/>
|
||||
<video id="video" screenwidth="256" screenheight="200" cols="32" rows="32" charset="/devices/c1p/video/chargen1x.png" padding="8px"/>
|
||||
<keyboard id="keyboard">
|
||||
<control type="button" binding="ctrl-c">CTRL-C</control>
|
||||
<control type="button" binding="break">BREAK</control>
|
||||
|
|
|
|||
|
|
@ -67,17 +67,21 @@
|
|||
* to the lack of a "guard band feature." Similarly, BASIC defaults to a width of 24 columns
|
||||
* avoid display problems near the right edge. BASIC will let you choose a width SMALLER than
|
||||
* 24 but not larger. So, while the video buffer supports a theoretical maximum of 32 rows x 32
|
||||
* 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.
|
||||
* columns, the practical maximum is 25 rows x 24 columns; the last 4 rows of the video buffer
|
||||
* are never used, and while content DOES scroll through the top 4 lines of the buffer, it should
|
||||
* never be assumed that you can see the top 3 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,
|
||||
* confirming that the first 4 lines are not assumed to be visible. However, the comment
|
||||
* 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.
|
||||
* visible character in the upper left of the screen is accessed via address 53379," or 0xD083.
|
||||
*
|
||||
* They actually meant 0xD085, because as mentioned earlier, the C1P indents every row by 5
|
||||
* characters, not 3. Even so, the difference between 0xD365 (where the bottom line starts)
|
||||
* and 0xD085 is 0x2E0, or 736. And 736 divided by 32 gives 23; add the bottom row, and that
|
||||
* gives you 24 visible rows, not 25. Since we now have screenshots of a C1P monitor displaying
|
||||
* 25 rows (courtesy of Stephan Mühlstrasser <stephan.muehlstrasser@web.de>), C1Pjs now assumes
|
||||
* 25 rows, which means that only the first 3 lines are not visible, which necessarily puts
|
||||
* the address of the first visible character at 0xD065.
|
||||
*
|
||||
* Model 540 Video Board vs. Model 600 "Superboard II"
|
||||
* ---------------------------------------------------
|
||||
|
|
@ -274,7 +278,7 @@ C1PVideo.prototype.setModel = function(nModel)
|
|||
* the only other supported model is 540 (2K video buffer).
|
||||
*/
|
||||
if (this.nModel == 600) {
|
||||
this.setDimensions(this.nDefaultCols, this.nDefaultRows, 4, 24);
|
||||
this.setDimensions(this.nDefaultCols, this.nDefaultRows, 3, 25);
|
||||
if (this.cbScreen == 1024 && this.cpu) {
|
||||
/*
|
||||
* NOTE: We deliberately set the guard address to the LAST byte of the 2K
|
||||
|
|
@ -466,7 +470,6 @@ C1PVideo.prototype.writeByte = function(offset, b)
|
|||
{
|
||||
var col = offset % this.nCols;
|
||||
var row = Math.floor(offset / this.nCols);
|
||||
// if (b == 0) this.cpu.halt(); // I must have been testing something here...
|
||||
return this.updateWindow(col, row, b);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -807,8 +807,26 @@ X86CPU.prototype.reset = function()
|
|||
* the test. A nonzero value in EAX after self-test indicates that the particular 80386 unit is faulty.
|
||||
* If the self-test is not requested, the contents of EAX after RESET is undefined.
|
||||
*
|
||||
* DX holds a component identifier and revision number after RESET as Figure 10-1 illustrates. DH contains 3,
|
||||
* which indicates an 80386 component. DL contains a unique identifier of the revision level.
|
||||
* DX holds a component identifier and revision number after RESET as Figure 10-1 illustrates. DH contains
|
||||
* 3, which indicates an 80386 component. DL contains a unique identifier of the revision level.
|
||||
*
|
||||
* EFLAGS = 0x00000002
|
||||
* IP = 0x0000FFF0
|
||||
* CS selector = 0xF000 (base of 0xFFFF0000 and limit of 0xFFFF)
|
||||
* DS selector = 0x0000
|
||||
* ES selector = 0x0000
|
||||
* SS selector = 0x0000
|
||||
* FS selector = 0x0000
|
||||
* GS selector = 0x0000
|
||||
* IDTR = base of 0 and limit of 0x3FF
|
||||
*
|
||||
* All other 80386 registers are undefined after a reset (that is, Intel declined to document precisely how
|
||||
* the hardware initializes any other registers, as if that would stop everyone from making any assumptions).
|
||||
*
|
||||
* We've elected to set DX to 0x0304 on a reset, which is consistent with a 80386-C0, since we have no desire to
|
||||
* try to emulate all the bugs in older (eg, B1) steppings. At least not initially. We leave stepping-accurate
|
||||
* emulation for another day. It's also known that the B1 reported 0x0303 in DX, but other than the B1 and C0
|
||||
* steppings, it's not known exactly what other revision numbers Intel used in 80386 CPUs.
|
||||
*
|
||||
* We define some additional "registers", such as regLIP. which mirrors the linear address corresponding to
|
||||
* CS:IP (the address of the next opcode byte). In fact, regLIP functions as our internal IP register, so any
|
||||
|
|
@ -879,7 +897,7 @@ X86CPU.prototype.resetRegs = function()
|
|||
this.setSS(0);
|
||||
|
||||
if (I386 && this.model >= X86.MODEL_80386) {
|
||||
this.regEDX = 0x0303; // Intel documentation indicates this is what an 80386-B1 reported
|
||||
this.regEDX = 0x0304; // Intel errata sheets indicate this is what an 80386-C0 reported
|
||||
this.regCR0 = X86.CR0.ET; // formerly MSW
|
||||
this.regCR1 = 0; // reserved
|
||||
this.regCR2 = 0; // page fault linear address (PFLA)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ var X86Help = {
|
|||
* @this {X86CPU}
|
||||
* @param {number} dst (current value, ignored)
|
||||
* @param {number} src (new value)
|
||||
* @return {number} dst (src is overridden, replaced with regMD16, as specified by opMOVSegSrc)
|
||||
* @return {number} dst (src is overridden, replaced with regMD16, as specified by opMOVwsr())
|
||||
*/
|
||||
opHelpMOVSegSrc: function(dst, src) {
|
||||
return X86Help.opHelpMOV.call(this, dst, this.regMD16);
|
||||
|
|
|
|||
|
|
@ -1937,21 +1937,21 @@ var X86OpXX = {
|
|||
var bModRM = this.getIPByte();
|
||||
var reg = (bModRM & 0x38) >> 3;
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
this.regMD16 = this.segES.sel;
|
||||
break;
|
||||
case 0x1:
|
||||
this.regMD16 = this.segCS.sel;
|
||||
break;
|
||||
case 0x0:
|
||||
this.regMD16 = this.segES.sel;
|
||||
break;
|
||||
case 0x1:
|
||||
this.regMD16 = this.segCS.sel;
|
||||
break;
|
||||
case 0x2:
|
||||
this.regMD16 = this.segSS.sel;
|
||||
break;
|
||||
case 0x3:
|
||||
this.regMD16 = this.segDS.sel;
|
||||
break;
|
||||
default:
|
||||
X86Help.opHelpUndefined.call(this);
|
||||
return;
|
||||
this.regMD16 = this.segSS.sel;
|
||||
break;
|
||||
case 0x3:
|
||||
this.regMD16 = this.segDS.sel;
|
||||
break;
|
||||
default:
|
||||
X86Help.opHelpUndefined.call(this);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
|
|
|
|||
Loading…
Reference in a new issue