Changed C1Pjs to display 25 rows instead of 24

This commit is contained in:
Jeff Parsons 2015-02-24 13:56:26 -08:00 committed by jeffpar
commit 9ba73970a4
15 changed files with 64 additions and 43 deletions

View file

@ -82,7 +82,7 @@ The "S40344" indicates that it's a B1 stepping, although I'm not currently able
According to [OS/2 Museum](http://os2museum.com) proprietor Michal Necasek, the "L8260347" means:
[I]t was actually manufactured in mid-1988. It took me many years to realize how Intel marked the chips.
[I]t was actually manufactured in mid-1988. It took me many years to realize how Intel marked the chips.
The initial 'L' (or whatever number/letter it is) can be ignored and the following 3 digits (826) are the
date code. The first is the last digit of the year.... The last two digits are the week of manufacture,
so week 26 of 1988. Many Intel CPUs actually have 2 or 3 date codes on them, probably related to when the
@ -90,10 +90,10 @@ According to [OS/2 Museum](http://os2museum.com) proprietor Michal Necasek, the
there might be another date code on the bottom side, but if there is, it's not going to be too far apart
from the one on the top and it's going to be slightly older.
One good thing about my 80386-B1 CPU is that it's also marked with a "ΣΣ" (double sigma),
which is how Intel marked parts that tested safe for 32-bit multiplication. Some 80386 CPUs suffered
from a manufacturing defect that could occasionally result in multiplication errors; those that Intel
caught were marked with "16 BIT S/W ONLY" instead of the double sigma.
Fortunately, my 80386-B1 CPU is also marked with a "ΣΣ" (double sigma), which is how Intel marked
parts that tested safe for 32-bit multiplication. Some 80386 CPUs suffered from a manufacturing defect that
could occasionally result in multiplication errors; defective parts that Intel caught were marked with "16 BIT S/W ONLY"
instead of the double sigma.
The only other information I have about revision levels comes from a March 30, 1987 document titled
"**80386-C0 STEPPING INFORMATION**":

View file

@ -19,7 +19,7 @@
<rom id="romNull" size="0x2000"/>
<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="512" screenheight="384" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<video id="video" screenwidth="512" screenheight="400" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<name>Video Display</name>
</video>
<keyboard id="keyboard" padleft="8px">

View file

@ -18,7 +18,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="512" screenheight="384" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<video id="video" screenwidth="512" screenheight="400" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<name>Video Display</name>
</video>
<keyboard id="keyboard" padleft="8px">

View file

@ -15,7 +15,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" width="256px" padding="8px"/>
<video id="video" screenwidth="256" screenheight="200" cols="32" rows="32" charset="/devices/c1p/video/chargen1x.png" width="256px" padding="8px"/>
<keyboard id="keyboard" pos="center">
<control type="button" binding="ctrl-c">CTRL-C</control>
<control type="button" binding="ctrl-o">CTRL-O</control>

View file

@ -18,7 +18,7 @@
<rom id="romNull" size="0x8000"/>
<rom id="romBasic" size="0x2000" image="../../../../rom/basic-gcpatch.hex"/>
<rom id="romSystem" size="0x0800" image="../../../../rom/system.hex"/>
<video id="video" screenwidth="512" screenheight="384" cols="32" rows="32" charset="../../../../video/chargen2x.png" width="512px" padding="8px">
<video id="video" screenwidth="512" screenheight="400" cols="32" rows="32" charset="../../../../video/chargen2x.png" width="512px" padding="8px">
<name>Video Display</name>
</video>
<keyboard id="keyboard" padleft="8px">

View file

@ -18,7 +18,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="512" screenheight="384" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<video id="video" screenwidth="512" screenheight="400" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" width="512px" padding="8px">
<name>Video Display</name>
</video>
<keyboard id="keyboard" padleft="8px">

View file

@ -16,7 +16,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="512" screenheight="384" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" padding="8px"/>
<video id="video" screenwidth="512" screenheight="400" cols="32" rows="32" charset="/devices/c1p/video/chargen2x.png" padding="8px"/>
<cpu id="cpu6502" autostart="false" pos="left" padleft="8px">
<control type="button" binding="run">Run</control>
</cpu>

View file

@ -16,7 +16,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" width="256px" padding="8px"/>
<video id="video" screenwidth="256" screenheight="200" cols="32" rows="32" charset="/devices/c1p/video/chargen1x.png" width="256px" padding="8px"/>
<keyboard id="keyboard" padleft="8px">
<control type="button" binding="ctrl-c">CTRL-C</control>
<control type="button" binding="ctrl-o">CTRL-O</control>

View file

@ -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>

View file

@ -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);
};

View file

@ -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)

View file

@ -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);

View file

@ -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.

View file

@ -97,7 +97,7 @@ function T(a,b,c,d){var e=!1;c||(a.ea[b]=null,a.za==b&&(a.za=0));var g=0,h=a.k[b
f.bc=function(a,b){var c=Ga(this.l);if(!a)if(this.l.speed==this.l.Na)a=void 0!==b&&32<=this.Ec;else{var d=c-this.Md;a=0>d||d>=this.Xf}a&&(d=this.lc.shift(),void 0!==d&&(this.yd=d),this.Ec=0,this.Md=c);for(d=c=0;8>d;d++)this.zd&1<<d&&(c|=this.yd[d]);c^=this.rc;if(void 0!==b)this.a[b]=c;else if(b=this.Rd,c!=this.Ad)for(d=b;d<this.ag;d++)this.a[d]=c;this.Ad=c};y(function(){for(var a=F(window.document,"c1pjs","keyboard"),b=0;b<a.length;b++){var c=a[b],d=D(c),d=new La(d);E(d,c)}});
function Ra(a,b,c,d){A.call(this,"C1PVideo",a);this.zc=a.model;this.Nd=a.charCols;this.Od=a.charRows;this.Lf=a.screenWidth;this.Mf=a.screenHeight;this.Pb=a.charWidth;this.Qb=a.charHeight;Sa(this);this.Rb=b;this.Jf=c;this.mb=d;this.kb=56832}C(Ra);f=Ra.prototype;f.reset=function(a){this.vb(this.zc);if(this.a)for(var b=this.Zb;b<this.Ic;b++)this.a[b]=a?Math.floor(256*Math.random()):32};
f.J=function(a,b,c){switch(b){case "refresh":return this.s[b]=c,c.onclick=function(a){return function(){Ta(a);va(a)}}(this),!0}return!1};f.W=function(a,b,c,d){this.a=a;this.Zb=b;this.If=c-b+1;this.Ic=this.Zb+this.If;d&&(this.l=d,void 0!==this.kb&&(wa(d,this.kb,this.kb,this,this.I),N(d,this.kb,this.kb,this,this.P)));this.reset(!0)};
function Sa(a,b,c,d,e){a.Wb=void 0!==b?b:a.Nd;a.Yf=void 0!==c?c:a.Od;a.Sa=a.Wb*a.Yf;a.Ic=a.Zb+a.Sa;a.Fd=void 0!==d?d:0;a.Pd=void 0!==e?e:c;a.Bd=Math.floor(a.Lf/a.Wb);a.Cd=Math.floor(a.Mf/a.Pd)}f.X=function(){this.Rb.focus()};f.vb=function(a){this.sb=a;600==this.sb?(Sa(this,this.Nd,this.Od,4,24),1024==this.Sa&&this.l&&(this.Lb=this.Ic+this.Sa-1,N(this.l,this.Lb,this.Lb,this,this.ne))):(this.i("updated video model: "+this.sb),Sa(this,64,32));Ta(this);va(this)};
function Sa(a,b,c,d,e){a.Wb=void 0!==b?b:a.Nd;a.Yf=void 0!==c?c:a.Od;a.Sa=a.Wb*a.Yf;a.Ic=a.Zb+a.Sa;a.Fd=void 0!==d?d:0;a.Pd=void 0!==e?e:c;a.Bd=Math.floor(a.Lf/a.Wb);a.Cd=Math.floor(a.Mf/a.Pd)}f.X=function(){this.Rb.focus()};f.vb=function(a){this.sb=a;600==this.sb?(Sa(this,this.Nd,this.Od,3,25),1024==this.Sa&&this.l&&(this.Lb=this.Ic+this.Sa-1,N(this.l,this.Lb,this.Lb,this,this.ne))):(this.i("updated video model: "+this.sb),Sa(this,64,32));Ta(this);va(this)};
f.ca=function(a,b){if(a&&!this.o.C&&K(this)){if(this.o.C=!0,this.m=L(b,"debugger"),this.H=L(b,"keyboard"))this.H.J("canvas","keyDown",this.Rb),this.H.J("canvas","keyPress",this.Rb),this.H.J("canvas","keyUp",this.Rb)}else!a&&this.o.C&&(this.o.C=!1)};f.Q=function(){this.Pb||(this.Pb=Math.floor(this.mb.width/16));this.Qb||(this.Qb=Math.floor(this.mb.height/16));A.prototype.Q.call(this)};
f.I=function(a,b){var c=this.l.I(a);void 0!==b&&this.m&&S(this.m,this,a,b,this.m.Bb);this.l.P(a,c&127|(Math.floor(Ga(this.l)/8333)&1?128:0))};f.P=function(a,b){void 0!==b&&this.m&&S(this.m,this,a,b,this.m.Bb)};
f.ne=function(a,b){if(void 0!==b){this.m&&S(this.m,this,a,b,this.m.Bb,!0);this.vb(540);this.H&&this.H.vb(542);var c=this.l,d=c.ua,e=[],g=xa(d,this.Lb,this.Lb,this,this.ne);if(0<=g){e.push(d[g][0]);e.push(d[g][1]);d.splice(g,1);for(var h=65536,k=0,g=0;g<d.length;g++)h>d[g][0]&&(h=d[g][0]),k<d[g][1]&&(k=d[g][1]);e.push(h);e.push(k)}4==e.length&&(c.Mb=e[2],c.Nb=e[3])}};function Ta(a){a.mc=Array(a.Sa);for(var b=0;b<=a.Sa;b++)a.mc[b]=-1}

View file

@ -93,7 +93,7 @@ function U(a,b,c,d){var f=!1;c||(a.R[b]=null,a.aa==b&&(a.aa=0));var g=0,k=a.j[b]
e.Ya=function(a,b){var c=ya(this.t);if(!a)if(this.t.speed==this.t.pa)a=void 0!==b&&32<=this.tb;else{var d=c-this.kc;a=0>d||d>=this.Vd}a&&(d=this.cb.shift(),void 0!==d&&(this.Wb=d),this.tb=0,this.kc=c);for(d=c=0;8>d;d++)this.Xb&1<<d&&(c|=this.Wb[d]);c^=this.jb;if(void 0!==b)this.a[b]=c;else if(b=this.pc,c!=this.Yb)for(d=b;d<this.Xd;d++)this.a[d]=c;this.Yb=c};y(function(){for(var a=I(window.document,"c1pjs","keyboard"),b=0;b<a.length;b++){var c=a[b],d=G(c),d=new Ba(d);H(d,c)}});
function Ga(a,b,c,d){B.call(this,"C1PVideo",a);this.pb=a.model;this.lc=a.charCols;this.mc=a.charRows;this.Kd=a.screenWidth;this.Ld=a.screenHeight;this.Ma=a.charWidth;this.Na=a.charHeight;Ha(this);this.Oa=b;this.Id=c;this.ta=d;this.qa=56832}E(Ga);e=Ga.prototype;e.reset=function(a){this.Ba(this.pb);if(this.a)for(var b=this.Va;b<this.xb;b++)this.a[b]=a?Math.floor(256*Math.random()):32};
e.I=function(a,b,c){switch(b){case "refresh":return this.p[b]=c,c.onclick=function(a){return function(){Ia(a);qa(a)}}(this),!0}return!1};e.Q=function(a,b,c,d){this.a=a;this.Va=b;this.Hd=c-b+1;this.xb=this.Va+this.Hd;d&&(this.t=d,void 0!==this.qa&&(ra(d,this.qa,this.qa,this,this.O),O(d,this.qa,this.qa,this,this.M)));this.reset(!0)};
function Ha(a,b,c,d,f){a.Sa=void 0!==b?b:a.lc;a.Wd=void 0!==c?c:a.mc;a.ia=a.Sa*a.Wd;a.xb=a.Va+a.ia;a.dc=void 0!==d?d:0;a.nc=void 0!==f?f:c;a.Zb=Math.floor(a.Kd/a.Sa);a.$b=Math.floor(a.Ld/a.nc)}e.ea=function(){this.Oa.focus()};e.Ba=function(a){this.ya=a;600==this.ya?(Ha(this,this.lc,this.mc,4,24),1024==this.ia&&this.t&&(this.Ia=this.xb+this.ia-1,O(this.t,this.Ia,this.Ia,this,this.Mc))):(this.u("updated video model: "+this.ya),Ha(this,64,32));Ia(this);qa(this)};
function Ha(a,b,c,d,f){a.Sa=void 0!==b?b:a.lc;a.Wd=void 0!==c?c:a.mc;a.ia=a.Sa*a.Wd;a.xb=a.Va+a.ia;a.dc=void 0!==d?d:0;a.nc=void 0!==f?f:c;a.Zb=Math.floor(a.Kd/a.Sa);a.$b=Math.floor(a.Ld/a.nc)}e.ea=function(){this.Oa.focus()};e.Ba=function(a){this.ya=a;600==this.ya?(Ha(this,this.lc,this.mc,3,25),1024==this.ia&&this.t&&(this.Ia=this.xb+this.ia-1,O(this.t,this.Ia,this.Ia,this,this.Mc))):(this.u("updated video model: "+this.ya),Ha(this,64,32));Ia(this);qa(this)};
e.T=function(a,b){if(a&&!this.m.B&&J(this)){if(this.m.B=!0,this.D=L(b,"keyboard"))this.D.I("canvas","keyDown",this.Oa),this.D.I("canvas","keyPress",this.Oa),this.D.I("canvas","keyUp",this.Oa)}else!a&&this.m.B&&(this.m.B=!1)};e.K=function(){this.Ma||(this.Ma=Math.floor(this.ta.width/16));this.Na||(this.Na=Math.floor(this.ta.height/16));B.prototype.K.call(this)};e.O=function(a){var b=this.t.O(a);this.t.M(a,b&127|(Math.floor(ya(this.t)/8333)&1?128:0))};e.M=function(){};
e.Mc=function(a,b){if(void 0!==b){this.Ba(540);this.D&&this.D.Ba(542);var c=this.t,d=c.U,f=[],g=sa(d,this.Ia,this.Ia,this,this.Mc);if(0<=g){f.push(d[g][0]);f.push(d[g][1]);d.splice(g,1);for(var k=65536,h=0,g=0;g<d.length;g++)k>d[g][0]&&(k=d[g][0]),h<d[g][1]&&(h=d[g][1]);f.push(k);f.push(h)}4==f.length&&(c.Ja=f[2],c.Ka=f[3])}};function Ia(a){a.eb=Array(a.ia);for(var b=0;b<=a.ia;b++)a.eb[b]=-1}
function qa(a){var b=0;if(a.m.B)for(;b<a.ia;){var c=a.a[a.Va+b];if(a.eb[b]!=c){var d=Math.floor(b/a.Sa);if(d>=a.dc&&(d-=a.dc,d<a.nc)){var f=c*a.Ma;a.Id.drawImage(a.ta,f%a.ta.width,Math.floor(f/a.ta.width)*a.Na,a.Ma,a.Na,b%a.Sa*a.Zb,d*a.$b,a.Zb,a.$b)}a.eb[b]=c}b++}}