1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-02-11 10:55:09 +00:00

Commit DCMCP transcription as of 2012-07-15; implement transfer,

test, and other misc. character-mode syllables; reclone 
B5500Testbed.html from B5500Console.html.
This commit is contained in:
paul
2012-07-16 01:47:41 +00:00
parent ded6eb4bb0
commit bc99d5e906
4 changed files with 596 additions and 205 deletions

View File

@@ -6671,3 +6671,61 @@ EXIT: SPOUTER(I&TUSTA[9:9:9],TUSTA,LIBMSG) 07351000
$ SET OMIT = PACKETS 07351099
;UNLOCKCONTROLDECKS; 07352000
END;% 07353000
PROCEDURE DECKREMOVER(B); BALUE B; REAL B;% 07354000
BEGIN REAL K,N,F;% 07355000
INTEGER U; LABEL ON,ERR; 07355100
REAL D; 07355200
LABEL L,TRYIT,GIVEUP; 07356000
K ~ B.[15:15]-1;% 07357000
L: STREAM(X~12,B:A~0);% 07358000
BEGIN SI ~ B;% 07359000
U: IF SC = " " THEN BEGIN SI~SI+1; GO TO U END;% 07360000
IF SC="=" THEN BEGIN DI~LOC X; DI~DI+6; DS~CHR; 07360100
SI~SI-1; B~SI; GO TO E END;07360200
IF SC = "#" THEN SI:=SI+1; 07361000
BL: IF SC=" " THEN BEGIN SI:=SI+1;GO TO BL; END; 07361500
DI:=LOC X; DI:=DI+1; DS:=5 LIT "#0000"; 07362000
4(IF SC < "0" THEN JUMP OUT TO EN; 07363000
IF SC > "9" THEN JUMP OUT TO EN; 07364000
SI:=SI+1; TALLY:=TALLY+1); 07365000
EN: A:=TALLY; SI:=SI-A; DI:=DI-A; DS:=A CHR; 07365500
N: IF SC = " " THEN BEGIN SI~SI+1; GO TO N END;% 07366000
DS ~ CHR; B ~ SI;% 07367000
E: END;% 07368000
P(.B,~,.N,~);% 07369000
F~N.[36:6]; N.[36:6]~"~"; 07370000
IF F="~" OR F="," OR F="=" THEN 07371000
BEGIN IF F="=" THEN 07371100
BEGIN IF D=0 THEN D~SPACE(30); 07371200
LOCKCONTROLDECKS; 07371300
IF (N:=FIRSTDECK)=0 THEN 07371400
GIVEUP: 07371450
BEGIN F:="~"; 07371500
UNLOCKCONTROLDECKS; 07371600
GO ON; 07371700
END; 07371750
TRYIT: DISKWAIT(-D,30,N); 07371800
$ SET OMIT = NOT(SHAREDISK) 07371809
N:=M[D+2]; 07371900
UNLOCKCONTROLDECKS; 07371950
END; 07372000
FOR U ~ 0 STEP 1 UNTIL PSEUDOMAX DO 07372090
IF CIDROW[U]!0 THEN 07372100
IF(CIDTABLE[U,2] EQV N)=NOT 0 THEN 07372200
IF LABELTABLE[U+32]}0 07372300
$ SET OMIT = NOT(PACKETS) 07372309
AND LABELTABLE[U+32]!@214 AND 07372310
PACKETACT[U]=0 07372320
$ POP OMIT 07372321
THEN 07372330
BEGIN 07372400
ENDOFDECK(U,M[K-1]); 07372500
GO ON; 07372600
END ELSE GO TO ERR; 07372700
REMOVEDECK(N,M[K-1]); 07372800
ON: IF F!"~" THEN GO TO L; 07372900
FORGETSPACE(K);% 07373000
END ELSE 07374000
ERR: SPOUT(K INX M[K-1]); 07374100
IF D!0 THEN FORGETSPACE(D); 07374200
END;% 07375000

View File

@@ -28,8 +28,10 @@ function B5500CentralControl() {
this.P1 = null; // Reference for Processor 1 (control) [PA or PB]
this.P1 = null; // Reference for Processor 2 (slave) [PA or PB]
this.AddressSpace = new Array(8); // Array of memory module address spaces (8 x 32KB each)
this.MemMod = new Array(8); // Array of memory module words as Float64s (8 x 4KW each)
this.AddressSpace = [ // Array of memory module address spaces (8 x 32KB each)
null, null, null, null, null, null, null, null];
this.MemMod = [ // Array of memory module words as Float64s (8 x 4KW each)
null, null, null, null, null, null, null, null];
// Instance variables and flags
this.poweredUp = 0; // System power indicator
@@ -148,12 +150,11 @@ B5500CentralControl.prototype.clear = function() {
/**************************************/
B5500CentralControl.prototype.bit = function(word, bit) {
/* Extracts and returns the specified bit from the word */
var e = 47-bit;
var p;
var e = 47-bit; // word lower power exponent
var p; // bottom portion of word power of 2
if (e > 0) {
p = B5500CentralControl.pow2[e];
return ((word - word%p)/p) % 2;
return ((word - word % (p = B5500CentralControl.pow2[e]))/p) % 2;
} else {
return word % 2;
}
@@ -162,51 +163,76 @@ B5500CentralControl.prototype.bit = function(word, bit) {
/**************************************/
B5500CentralControl.prototype.bitSet = function(word, bit) {
/* Sets the specified bit in word and returns the updated word */
var ue = 48-bit; // word upper power exponent
var le = ue-1; // word lower power exponent
var bpower = 1; // bottom portion of word power of 2
var bottom = // unaffected bottom portion of word
(le == 0 ? 0 : (word % (bpower = B5500CentralControl.pow2[le])));
var top = // unaffected top portion of word
(bit == 0 ? 0 : (word - (word % B5500CentralControl.pow2[ue])));
return this.fieldInsert(word, bit, 1, 1);
return bpower + top + bottom;
};
/**************************************/
B5500CentralControl.prototype.bitReset = function(word, bit) {
/* Resets the specified bit in word and returns the updated word */
var ue = 48-bit; // word upper power exponent
var le = ue-1; // word lower power exponent
var bottom = // unaffected bottom portion of word
(le == 0 ? 0 : (word % B5500CentralControl.pow2[le]));
var top = // unaffected top portion of word
(bit == 0 ? 0 : (word - (word % B5500CentralControl.pow2[ue])));
return this.fieldInsert(word, bit, 1, 0);
return top + bottom;
};
/**************************************/
B5500CentralControl.prototype.fieldIsolate = function(word, start, width) {
/* Extracts a bit field [start:width] from word and returns the field */
var ue = 48-start; // upper power exponent
var le = ue-width; // lower power exponent
var p;
var le = 48-start-width; // lower power exponent
var p; // bottom portion of word power of 2
if (le > 0) {
p = B5500CentralControl.pow2[le];
return ((word - word%p)/p) % B5500CentralControl.pow2[width];
} else {
return word % B5500CentralControl.pow2[width];
}
return (le == 0 ? word :
(word - word % (p = B5500CentralControl.pow2[le]))/p
) % B5500CentralControl.pow2[width];
};
/**************************************/
B5500CentralControl.prototype.fieldInsert = function(word, start, width, value) {
/* Inserts a bit field into word.[start:width] and returns the updated word */
var ue = 48-start; // upper power exponent
var le = ue-width; // lower power exponent
var bpower = 1; // bottom portion power of 2
var bottom = 0; // unaffected bottom portion of word
var top = 0; // unaffected top portion of word
/* Inserts a bit field from value.[48-width:width] into word.[start:width] and
returns the updated word */
var ue = 48-start; // word upper power exponent
var le = ue-width; // word lower power exponent
var bpower = 1; // bottom portion of word power of 2
var bottom = // unaffected bottom portion of word
(le == 0 ? 0 : (word % (bpower = B5500CentralControl.pow2[le])));
var top = // unaffected top portion of word
(bit == 0 ? 0 : (word - (word % B5500CentralControl.pow2[ue])));
if (start > 0) {
top = word - (word % B5500CentralControl.pow2[ue]);
}
if (le > 0) {
bpower = B5500CentralControl.pow2[le];
bottom = word % bpower;
}
return (value % B5500CentralControl.pow2[width])*bpower + top + bottom;
};
/**************************************/
B5500CentralControl.prototype.fieldTransfer = function(word, wstart, width, value, vstart) {
/* Inserts a bit field from value.[vstart:width] into word.[wstart:width] and
returns the updated word */
var ue = 48-vstart; // word upper power exponent
var le = ue-width; // word lower power exponent
var ve = 48-vstart-width; // value lower power exponent
var vpower; // bottom port of value power of 2
var bpower = 1; // bottom portion of word power of 2
var bottom = // unaffected bottom portion of word
(le == 0 ? 0 : (word % (bpower = B5500CentralControl.pow2[le])));
var top = // unaffected top portion of word
(bit == 0 ? 0 : (word - (word % B5500CentralControl.pow2[ue])));
return ((ve == 0 ? value :
(value - value % (vpower = B5500CentralControl.pow2[ve]))/vpower
) % B5500CentralControl.pow2[width]
)*bpower + top + bottom;
};
/**************************************/
B5500CentralControl.prototype.fetch = function(acc) {
/* Called by requestor module passing accessor object "acc" to fetch a

View File

@@ -49,7 +49,17 @@ function B5500Processor(procID) {
/**************************************/
B5500Processor.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
B5500Processor.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
B5500Processor.collation = [ // index by BIC to get collation value
53, 54, 55, 56, 57, 58, 59, 60, // @00: 0 1 2 3 4 5 6 7
61, 62, 19, 20, 63, 21, 22, 23, // @10: 8 9 # @ ? : > }
24, 25, 26, 27, 28, 29, 30, 31, // @20: + A B C D E F G
32, 33, 1, 2, 6, 3, 4, 5, // @30: H I . [ & ( < ~
34, 35, 36, 37, 38, 39, 40, 41, // @40: | J K L M N O P
42, 43, 7, 8, 12, 9, 10, 11, // @50: Q R $ * - ) ; {
0, 13, 45, 46, 47, 48, 49, 50, // @60: _ / S T U V W X (_ = blank)
51, 52, 14, 15, 44, 16, 17, 18]; // @70: Y Z , % ! = ] "
/**************************************/
B5500Processor.prototype.clear = function() {
@@ -328,6 +338,136 @@ B5500Processor.prototype.exchangeTOS = function() {
}
};
/**************************************/
B5500Processor.prototype.streamAdjustSourceChar = function() {
/* Adjusts the character-mode source pointer to the next character
boundary, as necessary. If the adjustment crosses a word boundary,
AROF is reset to force reloading later at the new source address */
if (this.H > 0) {
this.H = 0;
if (this.G < 7) {
this.G++;
} else {
this.G = 0;
this.AROF = 0;
this.M++;
}
}
};
/**************************************/
B5500Processor.prototype.streamAdjustDestChar = function() {
/* Adjusts the character-mode destination pointer to the next character
boundary, as necessary. If the adjustment crosses a word boundary and
BROF is set, B is stored at S before S is incremented and BROF is reset
to force reloading later at the new destination address */
if (this.V > 0) {
this.V = 0;
if (this.K < 7) {
this.K++;
} else {
this.K = 0;
if (this.BROF) {
this.access(0x0B);
this.BROF = 0;
}
this.S++;
}
}
};
/**************************************/
B5500Processor.prototype.streamSourceToDest = function(count, transform) {
/* General driver for character-mode character transfers from source to
destination. "count" is the number of source characters to transfer.
"transform" is a function(bBit, count) that determines how the
characters are transferred from the source (A) to destination (B). The
Y register will contain the current char during this call */
var aBit;
var bBit;
this.streamAdjustSourceChar();
this.streamAdjustDestChar();
if (count) {
if (!this.BROF) {
this.access(0x03); // B = [S]
}
if (!this.AROF) {
this.access(0x04); // A = [M]
}
this.cycleCount += count; // approximate the timing
aBit = this.G*6; // A-bit number
bBit = this.K*6; // B-bit number
while (count) {
this.Y = cc.fieldIsolate(this.A, aBit, 6);
transform(bBit, count)
count--;
if (bBit < 42) {
bBit += 6;
this.K++;
} else {
bBit = 0;
this.K = 0;
this.access(0x0B); // [S] = B
this.S++;
if (count < 8) { // just a partial word left
this.access(0x03); // B = [S]
}
}
if (aBit < 42) {
aBit += 6;
this.G++;
} else {
aBit = 0;
this.G = 0;
this.M++;
this.access(0x04); // A = [M]
}
}
}
};
/**************************************/
B5500Processor.prototype.streamToDest = function(count, transform) {
/* General driver for character-mode character operations on the
destination from a non-A register source. "count" is the number of
characters to transfer. "transform" is a function(bBit, count) that
determines how the characters are stored to the destination (B).
Returning truthy terminates the process without incrementing the
destination address */
var bBit;
this.streamAdjustDestChar();
if (count) {
if (!this.BROF) {
this.access(0x03); // B = [S]
}
this.cycleCount += count; // approximate the timing
bBit = this.K*6; // B-bit number
while (count) {
if (transform(bBit, count)) {
count = 0;
} else {
count--;
if (bBit < 42) {
bBit += 6;
this.K++;
} else {
bBit = 0;
this.K = 0;
this.access(0x0B); // [S] = B
this.S++;
if (count < 8) { // just a partial word left
this.access(0x03); // B = [S]
}
}
}
}
}
};
/**************************************/
B5500Processor.storeForInterrupt = function(forTest) {
/* Implements the 3011=SFI operator and the parts of 3411=SFT that are
@@ -678,7 +818,7 @@ B5500Processor.prototype.indexDescriptor = function() {
};
/**************************************/
B5500Processor.prototype.presenceTest(word) {
B5500Processor.prototype.presenceTest = function(word) {
/* Tests and returns the presence bit [2:1] of the "word" parameter. If
0, the p-bit interrupt is set; otherwise no further action */
@@ -767,7 +907,7 @@ B5500Processor.prototype.applyRCW = function(word, inline) {
};
/**************************************/
B5500Processor.prototype.enterCharModeInline() {
B5500Processor.prototype.enterCharModeInline = function() {
/* Implements the 4441=CMN syllable */
var bw; // local copy of B reg
@@ -1027,6 +1167,7 @@ B5500Processor.prototype.run = function() {
current program word must be in P with PROF set, and the C & L registers
must point to the next syllable to be executed.
This routine will run until cycleCount >= cycleLimit or !this.busy */
var noSECL = 0; // to support char mode dynamic count from CRF
var opcode;
var t1;
var t2;
@@ -1045,213 +1186,386 @@ B5500Processor.prototype.run = function() {
* Character Mode Syllables *
***********************************************************/
variant = opcode >>> 6;
switch (opcode & 0x3F) {
case 0x00: // XX00: CMX, EXC: Exit character mode
this.adjustBEmpty(); // store destination string
this.S = this.F;
this.access(0x03); // B = [S], fetch the RCW
this.exitSubroutine(variant & 0x01); // exit vs. exit inline
this.AROF = this.BROF = 0;
this.X = this.M = this.N = 0;
this.CWMF = 0;
break;
case 0x02: // XX02: BSD=Skip bit destination
break;
case 0x03: // XX03: BSS=Skip bit source
break;
case 0x04: // XX04: RDA=Recall destination address
break;
case 0x05: // XX05: TRW=Transfer words
break;
case 0x06: // XX06: SED=Set destination address
break;
case 0x07: // XX07: TDA=Transfer destination address
break;
case 0x0A: // XX12: TBN=Transfer blank for numeric
break;
case 0x0C: // XX14: SDA=Store destination address
break;
case 0x0D: // XX15: SSA=Store source address
break;
case 0x0E: // XX16: SFD=Skip forward destination
break;
case 0x0F: // XX17: SRD=Skip reverse destination
break;
case 0x11: // XX11: control state ops
switch (variant) {
case 0x14: // 2411: ZPI=Conditional Halt
// TODO: this needs to test for the STOP OPERATOR switch
// TODO: on the maintenance panel otherwise it is a NOP.
do { // inner loop to support CRF dynamic repeat count
noSECL = 0; // force off by default (set by CRF)
switch (opcode & 0x3F) {
case 0x00: // XX00: CMX, EXC: Exit character mode
this.adjustBEmpty(); // store destination string
this.S = this.F;
this.access(0x03); // B = [S], fetch the RCW
this.exitSubroutine(variant & 0x01);// exit vs. exit inline
this.AROF = this.BROF = 0;
this.X = this.M = this.N = 0;
this.CWMF = 0;
break;
case 0x18: // 3011: SFI=Store for Interrupt
this.storeForInterrupt(0);
case 0x02: // XX02: BSD=Skip bit destination
break;
case 0x1C: // 3411: SFT=Store for Test
this.storeForInterrupt(1);
case 0x03: // XX03: BSS=Skip bit source
break;
default: // Anything else is a no-op
case 0x04: // XX04: RDA=Recall destination address
break;
} // end switch for XX11 ops
break;
case 0x12: // XX22: SES=Set source address
break;
case 0x05: // XX05: TRW=Transfer words
if (this.BROF) {
this.access(0x0B); // [S] = B
this.BROF = 0;
}
if (this.G || this.H) {
this.G = this.H = 0;
this.M++;
this.AROF = 0;
}
if (this.K || this.V) {
this.K = this.V = 0;
this.S++;
}
if (variant) { // count > 0
if (!this.AROF) {
this.access(0x04); // A = [M]
}
do {
this.access(0x0A); // [S] = A
this.S++;
this.M++;
this.access(0x04); // A = [M]
} while (--variant);
}
break;
case 0x14: // XX24: TEQ=Test for equal
break;
case 0x06: // XX06: SED=Set destination address
break;
case 0x15: // XX25: TNE=Test for not equal
break;
case 0x07: // XX07: TDA=Transfer destination address
break;
case 0x16: // XX26: TEG=Test for greater or equal
break;
case 0x0A: // XX12: TBN=Transfer blank for numeric
this.MSFF = 1; // initialize true-false FF
this.streamToDest(variant, function(bb, count) {
var c = this.Z = cc.fieldIsolate(this.B, bb, 6);
var result = 0;
case 0x17: // XX27: TGR=Test for greater
break;
if (c > 0 && c <= 9) {
this.MSFF = 0; // numeric, non-zero: stop blanking
this.Q |= 0x04; // set Q03F (display only)
result = 1; // terminate, pointing at this char
} else {
this.B = cc.fieldInsert(this.B, bb, 6, 0x30); // replace with blank
}
return result;
});
break;
case 0x18: // XX30: SRS=Skip reverse source
break;
case 0x0C: // XX14: SDA=Store destination address
break;
case 0x19: // XX31: SFS=Skip forward source
break;
case 0x0D: // XX15: SSA=Store source address
break;
case 0x1A: // XX32: ---=Field subtract (aux) !! ??
break;
case 0x0E: // XX16: SFD=Skip forward destination
break;
case 0x1B: // XX33: ---=Field add (aux) !! ??
break;
case 0x0F: // XX17: SRD=Skip reverse destination
break;
case 0x1C: // XX34: TEL=Test for equal
break;
case 0x11: // XX11: control state ops
switch (variant) {
case 0x14: // 2411: ZPI=Conditional Halt
// TODO: this needs to test for the STOP OPERATOR switch
// TODO: on the maintenance panel otherwise it is a NOP.
break;
case 0x1D: // XX35: TLS=Test for less
break;
case 0x18: // 3011: SFI=Store for Interrupt
this.storeForInterrupt(0);
break;
case 0x1E: // XX36: TAN=Test for alphanumeric
break;
case 0x1C: // 3411: SFT=Store for Test
this.storeForInterrupt(1);
break;
case 0x1F: // XX37: BIT=Test bit
break;
default: // Anything else is a no-op
break;
} // end switch for XX11 ops
break;
case 0x20: // XX40: INC=Increase TALLY
if (variant) {
this.R = (this.R + variant) & 0x3F;
case 0x12: // XX22: SES=Set source address
break;
case 0x14: // XX24: TEQ=Test for equal
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 == t2 ? 1 : 0);
break;
case 0x15: // XX25: TNE=Test for not equal
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 != t2 ? 1 : 0);
break;
case 0x16: // XX26: TEG=Test for equal or greater
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 >= t2 ? 1 : 0);
break;
case 0x17: // XX27: TGR=Test for greater
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 > t2 ? 1 : 0);
break;
case 0x18: // XX30: SRS=Skip reverse source
break;
case 0x19: // XX31: SFS=Skip forward source
break;
case 0x1A: // XX32: ---=Field subtract (aux) !! ??
break;
case 0x1B: // XX33: ---=Field add (aux) !! ??
break;
case 0x1C: // XX34: TEL=Test for equal or less
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 <= t2 ? 1 : 0);
break;
case 0x1D: // XX35: TLS=Test for less
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = B5500Processor.collate[cc.fieldIsolate(this.A, this.G*6, 6)];
t2 = B5500Processor.collate[variant];
this.MSFF = (t1 < t2 ? 1 : 0);
break;
case 0x1E: // XX36: TAN=Test for alphanumeric
this.streamAdjustSource();
if (!this.AROF) {
this.access(0x04); // A = [M]
}
this.Y = t1 = cc.fieldIsolate(this.A, this.G*6, 6);
this.Z = variant; // for display only
if (B5500Processor.collate[t1] > B5500Processor.collate[variant]) { // alphanumeric unless | or !
this.MSFF = (t1 == 0x20 ? 0 : (t1 == 0x3C ? 0 : 1));
} else { // alphanumeric if equal
this.Q |= 0x04; // set Q03F (display only)
this.MSFF = (t1 == variant ? 1 : 0);
}
break;
case 0x1F: // XX37: BIT=Test bit
if (!this.AROF) {
this.access(0x04); // A = [M]
}
t1 = (this.Y = cc.fieldIsolate(this.A, this.G*6, 6)) >>> 5-this.H;
this.MSFF = ((t1 & 0x01) == (variant & 0x01) ? 1 : 0);
break;
case 0x20: // XX40: INC=Increase TALLY
if (variant) {
this.R = (this.R + variant) & 0x3F;
// else it's a character-mode no-op
}
break;
}
break;
case 0x21: // XX41: STC=Store TALLY
break;
case 0x21: // XX41: STC=Store TALLY
break;
case 0x22: // XX42: SEC=Set TALLY
this.R = variant;
break;
case 0x22: // XX42: SEC=Set TALLY
this.R = variant;
break;
case 0x23: // XX43: CRF=Call variant field
break;
case 0x23: // XX43: CRF=Call repeat field
this.A = this.B; // save B in A
this.AROF = this.BROF;
t1 = this.S; // save S (not the way the hardware did it)
this.S = this.F - variant; // compute parameter address
this.access(0x03); // B = [S]
variant = this.B % 0x40; // dynamic repeat count is low-order 6 bits
this.S = t1; // restore S
this.B = this.A; // restore B
this.BROF = this.AROF;
this.AROF = 0;
noSECL = 1; // override normal instruction fetch
opcode = cc.fieldIsolate(this.P, this.L*12, 12);
if (variant) {
this.T = opcode & 0x3F + variant*64; // use repeat count from parameter
} else {
if (opcode & 0xFC) { // repeat field in next syl > 0
this.T = opcode;
variant = opcode >>> 6; // execute next syl as is
} else {
this.T = opcode = 0x27; // inject JFW 0 into T (effectively a no-op)
}
}
break;
case 0x24: // XX44: JNC=Jump out of loop conditional
break;
case 0x24: // XX44: JNC=Jump out of loop conditional
break;
case 0x25: // XX45: JFC=Jump forward conditional
break;
case 0x25: // XX45: JFC=Jump forward conditional
break;
case 0x26: // XX46: JNS=Jump out of loop
break;
case 0x26: // XX46: JNS=Jump out of loop
break;
case 0x27: // XX47: JFW=Jump forward unconditional
break;
case 0x27: // XX47: JFW=Jump forward unconditional
break;
case 0x28: // XX50: RCA=Recall control address
break;
case 0x28: // XX50: RCA=Recall control address
break;
case 0x29: // XX51: ENS=End loop
break;
case 0x29: // XX51: ENS=End loop
break;
case 0x2A: // XX52: BNS=Begin loop
break;
case 0x2A: // XX52: BNS=Begin loop
break;
case 0x2B: // XX53: RSA=Recall source address
break;
case 0x2B: // XX53: RSA=Recall source address
break;
case 0x2C: // XX54: SCA=Store control address
break;
case 0x2C: // XX54: SCA=Store control address
break;
case 0x2D: // XX55: JRC=Jump reverse conditional
break;
case 0x2D: // XX55: JRC=Jump reverse conditional
break;
case 0x2E: // XX56: TSA=Transfer source address
break;
case 0x2E: // XX56: TSA=Transfer source address
break;
case 0x2F: // XX57: JRV=Jump reverse unconditional
break;
case 0x2F: // XX57: JRV=Jump reverse unconditional
break;
case 0x30: // XX60: CEQ=Compare equal
break;
case 0x30: // XX60: CEQ=Compare equal
break;
case 0x31: // XX61: CNE=Compare not equal
break;
case 0x31: // XX61: CNE=Compare not equal
break;
case 0x32: // XX62: CEG=Compare greater or equal
break;
case 0x32: // XX62: CEG=Compare greater or equal
break;
case 0x33: // XX63: CGR=Compare greater
break;
case 0x33: // XX63: CGR=Compare greater
break;
case 0x34: // XX64: BIS=Set bit
break;
case 0x34: // XX64: BIS=Set bit
break;
case 0x35: // XX65: BIR=Reset bit
break;
case 0x35: // XX65: BIR=Reset bit
break;
case 0x36: // XX66: OCV=Output convert
break;
case 0x36: // XX66: OCV=Output convert
break;
case 0x37: // XX67: ICV=Input convert
break;
case 0x37: // XX67: ICV=Input convert
break;
case 0x38: // XX70: CEL=Compare equal or less
break;
case 0x38: // XX70: CEL=Compare equal or less
break;
case 0x39: // XX71: CLS=Compare less
break;
case 0x39: // XX71: CLS=Compare less
break;
case 0x3A: // XX72: FSU=Field subtract
break;
case 0x3A: // XX72: FSU=Field subtract
break;
case 0x3B: // XX73: FAD=Field add
break;
case 0x3B: // XX73: FAD=Field add
break;
case 0x3C: // XX74: TRP=Transfer program characters
break;
case 0x3C: // XX74: TRP=Transfer program characters
this.streamAdjustDestChar();
if (variant) { // count > 0
if (!this.BROF) {
this.access(0x03); // B = [S]
}
this.cycleCount += variant; // approximate the timing
t1 = (this.L*2 + variant & 0x01)*6; // P-bit number
t2 = this.K*6; // B-bit number
while (variant--) {
this.Y = cc.fieldIsolate(this.P, t1, 6);
this.B = cc.fieldInsert(this.B, t2, 6, this.Y)
if (t2 < 42) {
t2 += 6;
this.K++;
} else {
t2 = 0;
this.K = 0;
this.access(0x0B); // [S] = B
this.S++;
if (variant < 8) { // just a partial word left
this.access(0x03); // B = [S]
}
}
if (t1 < 42) {
t1 += 6;
if (!(variant & 0x01)) {
this.L++;
}
} else {
t1 = 0;
this.L = 0;
this.C++;
this.access(0x30); // P = [C]
}
}
}
break;
case 0x3D: // XX75: TRN=Transfer numerics
break;
case 0x3D: // XX75: TRN=Transfer numerics
this.MSFF = 0; // initialize true-false FF
this.streamSourceToDest(variant, function(bb, count) {
var c = this.Y;
case 0x3E: // XX76: TRZ=Transfer zones
break;
if (count == 1 && (c & 0x30) == 0x20) {
this.MSFF = 1; // neg. sign
}
this.B = cc.fieldInsert(this.B, bb, 6, c & 0x0F);
});
break;
case 0x3F: // XX77: TRS=Transfer source characters
break;
case 0x3E: // XX76: TRZ=Transfer zones
this.streamSourceToDest(variant, function(bb, count) {
this.B = cc.fieldInsert(this.B, bb, 2, this.Y);
});
break;
default: // everything else is a no-op
break;
} // end switch for character mode operators
case 0x3F: // XX77: TRS=Transfer source characters
this.streamSourceToDest(variant, function(bb, count) {
this.B = cc.fieldInsert(this.B, bb, 6, this.Y);
});
break;
default: // everything else is a no-op
break;
} // end switch for character mode operators
} while (noSECL);
} else {
/***********************************************************
* Word Mode Syllables *
@@ -1276,7 +1590,7 @@ B5500Processor.prototype.run = function() {
case 3: // DESC: Descriptor (name) Call
this.adjustAEmpty();
computeRelativeAddr(opcode >>> 2, 1);
this.access(0x04); // A = [M]
this.access(0x04); // A = [M]
this.descriptorCall();
break;
@@ -1453,11 +1767,11 @@ B5500Processor.prototype.run = function() {
break;
case 0x10: // 2015: MOP=reset flag bit (make operand)
this.A = cc.fieldInsert(this.A, 0, 1, 0);
this.A = cc.bitReset(this.A, 0);
break;
case 0x20: // 4015: MDS=set flag bit (make descriptor)
this.A = cc.fieldInsert(this.A, 0, 1, 1);
this.A = cc.bitSet(this.A, 0);
break;
}
break;
@@ -1476,13 +1790,6 @@ B5500Processor.prototype.run = function() {
case 0x08: // 1021: SND=Store nondestructive
break;
case 0x09: // 0431: SSN=Set Sign Bit
// the sign-bit is bit 1
// assert(this.AROF == 1);
this.A = cc.fieldInsert(this.A, 1, 1, 1);
this.AROF = 1;
break;
case 0x10: // 2021: LOD=Load operand
break;
@@ -1569,7 +1876,7 @@ B5500Processor.prototype.run = function() {
case 0x04: // 0431: SSN=set sign bit (set negative)
// assert(this.AROF == 1);
this.A = cc.fieldInsert(this.A, 1, 1, 1);
this.A = cc.bitSet(this.A, 1);
this.AROF = 1;
break;
@@ -1577,9 +1884,9 @@ B5500Processor.prototype.run = function() {
// the sign-bit is bit 1
// assert(this.AROF == 1);
if (cc.bit(this.A, 1)) {
this.A = cc.fieldInsert(this.A, 1, 1, 0);
this.A = cc.bitReset(this.A, 1);
} else {
this.A = cc.fieldInsert(this.A, 1, 1, 1);
this.A = cc.bitSet(this.A, 1);
}
this.AROF = 1;
break;
@@ -1611,7 +1918,7 @@ B5500Processor.prototype.run = function() {
case 0x24: // 4431: SSP=reset sign bit (set positive)
// the sign-bit is bit 1
// assert(this.AROF == 1);
this.A = cc.fieldInsert(this.A, 1, 1, 0);
this.A = cc.bitReset(this.A, 1);
this.AROF = 1;
break;
@@ -1827,7 +2134,7 @@ B5500Processor.prototype.run = function() {
variant = 48-t2;
}
if (variant > 0) {
this.B = cc.fieldInsert(this.B, t2, variant, cc.fieldIsolate(this.A, t1, variant));
this.B = cc.fieldTransfer(this.B, t2, variant, this.A, t1);
}
this.AROF = 0;
this.cycleCount += variant + this.G + this.K; // approximate the shift counts
@@ -1843,7 +2150,7 @@ B5500Processor.prototype.run = function() {
if (t2+variant > 48) {
variant = 48-t2;
}
if (variant > 0 && cc.fieldIsolate(this.B, t2, variant) < cc.fieldIsolate(this.A, t1, variant)) {
if (variant > 0 && (cc.fieldIsolate(this.B, t2, variant) < cc.fieldIsolate(this.A, t1, variant))) {
this.A = 1;
} else {
this.A = 0;
@@ -1861,7 +2168,7 @@ B5500Processor.prototype.run = function() {
if (t2+variant > 48) {
variant = 48-t2;
}
if (variant > 0 && cc.fieldIsolate(this.B, t2, variant) == cc.fieldIsolate(this.A, t1, variant)) {
if (variant > 0 && (cc.fieldIsolate(this.B, t2, variant) == cc.fieldIsolate(this.A, t1, variant))) {
this.A = 1;
} else {
this.A = 0;

View File

@@ -14,7 +14,7 @@
"use strict";
var cc;
function stackIt(e) {
function testIt(e) {
/* Simple test driver for the Processor module */
cc.powerOn();
@@ -81,7 +81,7 @@ window.onload = function() {
<span class=buttonCaption>B CONTROL</span>
</div>
<div id=PowerOnBtn class=whiteButton style="right:300px" onclick="stackIt(this)">
<div id=PowerOnBtn class=whiteButton style="right:300px" onclick="testIt(this)">
<span class=buttonCaption>POWER ON</span>
</div>
<div id=PowerOffBtn class=blackButton style="right:225px">