1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-02-26 09:03:37 +00:00

Implement LOD; continue debugging character mode tests.

This commit is contained in:
paul
2013-01-28 03:40:08 +00:00
parent fcfbd4bab1
commit 3282dde3eb
3 changed files with 89 additions and 29 deletions

View File

@@ -977,7 +977,7 @@ B5500Processor.prototype.streamSourceToDest = function(count, transform) {
bBit = this.K*6; // B-bit number
do {
this.Y = this.cc.fieldIsolate(this.A, aBit, 6);
transform(bBit, count)
transform.call(this, bBit, count)
count--;
if (bBit < 42) {
bBit += 6;
@@ -1022,7 +1022,7 @@ B5500Processor.prototype.streamToDest = function(count, transform) {
this.cycleCount += count; // approximate the timing
bBit = this.K*6; // B-bit number
do {
if (transform(bBit, count)) {
if (transform.call(this, bBit, count)) {
count = 0;
} else {
count--;
@@ -1339,6 +1339,9 @@ B5500Processor.prototype.preset = function(runAddr) {
this.loadPviaC(); // load the program word to P
this.T = this.cc.fieldIsolate(this.P, 0, 12);
this.TROF = 1;
this.R = 0;
this.S = 0;
};
/**************************************/
@@ -2347,6 +2350,12 @@ B5500Processor.prototype.computeRelativeAddr = function(offset, cEnabled) {
} else {
this.M = (this.R*64) + (offset & 0x3FF);
}
// Reset variant-mode R-relative addressing, if enabled
if (this.VARF) {
this.SALF = 1;
this.VARF = 0;
}
};
/**************************************/
@@ -2399,13 +2408,13 @@ B5500Processor.prototype.indexDescriptor = function() {
// Now we have an integerized index value in xm
if (!interrupted) {
if (xs) { // oops... negative index
if (xs && xm) { // oops... negative index
interrupted = 1;
if (this.NCSF) {
this.I = (this.I & 0x0F) | 0x90; // set I05/8: invalid-index
this.cc.signalInterrupt();
}
} else if (xm >= this.cc.fieldIsolate(aw, 8, 10)) {
} else if (xm % 0x0400 >= this.cc.fieldIsolate(aw, 8, 10)) {
interrupted = 1; // oops... index out of bounds
if (this.NCSF) {
this.I = (this.I & 0x0F) | 0x90; // set I05/8: invalid-index
@@ -2522,6 +2531,7 @@ B5500Processor.prototype.enterCharModeInline = function() {
this.loadAviaS(); // A = [S]: tank the DI address
}
this.B = this.buildRCW(0);
this.BROF = 1;
this.adjustBEmpty();
this.MSFF = 0;
this.SALF = 1;
@@ -2554,7 +2564,7 @@ B5500Processor.prototype.enterCharModeInline = function() {
/**************************************/
B5500Processor.prototype.enterSubroutine = function(descriptorCall) {
/* Enters a subroutine via the present program descriptor in A as part
/* Enters a subroutine via the present Program Descriptor in A as part
of an OPDC or DESC syllable. Also handles accidental entry */
var aw = this.A; // local copy of word in A reg
var bw; // local copy of word in B reg
@@ -2562,7 +2572,7 @@ B5500Processor.prototype.enterSubroutine = function(descriptorCall) {
var mode = this.cc.bit(aw, 4); // descriptor mode bit (1-char mode)
if (arg && !this.MSFF) {
; // just leave the PD on TOS
; // just leave the Program Descriptor on TOS
} else if (mode && !arg) {
; // ditto
} else {
@@ -2577,6 +2587,7 @@ B5500Processor.prototype.enterSubroutine = function(descriptorCall) {
// Push a RCW
this.B = this.buildRCW(descriptorCall);
this.BROF = 1;
this.adjustBEmpty();
// Fetch the first word of subroutine code
@@ -2653,10 +2664,9 @@ B5500Processor.prototype.operandCall = function() {
/* OPDC, the moral equivalent of "load accumulator" on lesser
machines. Assumes the syllable has already loaded a word into A.
See Figures 6-1, 6-3, and 6-4 in the B5500 Reference Manual */
var aw; // local copy of A reg value
var aw = this.A; // local copy of A reg value
var interrupted = 0; // interrupt occurred
aw = this.A;
if (aw >= 0x800000000000) {
// It's not a simple operand
switch (this.cc.fieldIsolate(aw, 1, 3)) {
@@ -2699,12 +2709,6 @@ B5500Processor.prototype.operandCall = function() {
break;
}
}
// Reset variant-mode R-relative addressing, if enabled
if (this.VARF && !interrupted) {
this.SALF = 1;
this.VARF = 0;
}
};
/**************************************/
@@ -2754,12 +2758,6 @@ B5500Processor.prototype.descriptorCall = function() {
break;
}
}
// Reset variant-mode R-relative addressing, if enabled
if (this.VARF && !interrupted) {
this.SALF = 1;
this.VARF = 0;
}
};
/**************************************/
@@ -2834,15 +2832,15 @@ B5500Processor.prototype.run = function() {
this.storeBviaS(); // [S] = B
this.BROF = 0;
}
this.V = 0;
this.S = this.F - variant;
this.loadBviaS(); // B = [S]
this.S = this.B % 0x8000;
this.V = 0;
if (this.B >= 0x800000000000) { // if it's a descriptor,
this.K = 0; // force K to zero and
this.presenceTest(this.B); // just take the side effect of any p-bit interrupt
} else {
this.K = this.cc.fieldIsolate(this.B, 18, 3);
this.K = (this.B % 0x40000) >>> 15;
}
break;
@@ -2990,7 +2988,7 @@ B5500Processor.prototype.run = function() {
this.storeBviaS(); // will skip off the current word,
this.BROF = 0; // so store and invalidate B
}
t1 = this.S*8 + this.K - variant;
t1 = this.S*8 + this.K + variant;
this.S = t1 >>> 3;
this.K = t1 & 0x07;
break;
@@ -3276,15 +3274,15 @@ B5500Processor.prototype.run = function() {
this.cycleCount += variant;
this.A = this.B; // save B
this.AROF = this.BROF;
this.H = 0;
this.M = this.F - variant;
this.loadBviaM(); // B = [M]
this.M = this.B % 0x8000;
this.H = 0;
if (this.B >= 0x800000000000) { // if it's a descriptor,
this.G = 0; // force G to zero and
this.presenceTest(this.B); // just take the side effect of any p-bit interrupt
} else {
this.G = this.cc.fieldIsolate(this.B, 18, 3);
} else { // it's an operand
this.G = (this.B % 0x40000) >>> 15;
}
this.B = this.A; // restore B from A
this.BROF = this.AROF;
@@ -3489,14 +3487,16 @@ B5500Processor.prototype.run = function() {
case 2: // OPDC: Operand Call
this.adjustAEmpty();
this.computeRelativeAddr(opcode >>> 2, 1);
this.loadAviaM(); // A = [M]
this.operandCall();
this.loadAviaM();
if (this.A >= 0x800000000000) { // a small optimization for the
this.operandCall(); // common case when TOS is an operand
}
break;
case 3: // DESC: Descriptor (name) Call
this.adjustAEmpty();
this.computeRelativeAddr(opcode >>> 2, 1);
this.loadAviaM(); // A = [M]
this.loadAviaM();
this.descriptorCall();
break;
@@ -3745,6 +3745,19 @@ B5500Processor.prototype.run = function() {
break;
case 0x10: // 2021: LOD=Load operand
this.adjustAFull();
if (this.A < 0x800000000000) { // simple operand
this.computeRelativeAddr(this.A, 1);
this.loadAviaM();
} else if (this.A < 0xC00000000000) { // absent descriptor
if (this.NCSF) {
this.I = (this.I & 0x0F) | 0x70;// set I05/6/7: p-bit
this.cc.signalInterrupt();
}
} else { // present descriptor
this.M = this.A % 0x8000;
this.loadAviaM();
}
break;
case 0x21: // 4121: ISD=Integer store destructive

Binary file not shown.

View File

@@ -0,0 +1,47 @@
$ SET $ LIST PRT DEBUGN 00000100
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%00000200
%% %%00000300
%% RETRO-B5500 EMULATOR CHARACTER MODE TESTS %%00000400
%% %%00000500
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%00000600
% 2013-01-26 P.KIMPEL 00000700
% ORIGINAL VERSION 00000800
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%00099900
00100000
BEGIN 00100100
INTEGER I; 00100200
REAL R; 00100300
ARRAY S[16]:= 00100400
"01234567","89ABCDEF","GHIJKLMN","OPQRSTUV","WXYZ +-/", 00100500
"NOW IS T","HE TIME ","FOR ALL ","GOOD MEN"," TO COME", 00100600
" TO THE ","AID OF T","HEIR PAR","TY. ","1234567Q","12345678"; 00100700
ARRAY D[16]; 00100800
LABEL ENTRY, START; 00100900
00400000
ENTRY:@20: GO TO START; 00400100
00500000
START:*: 00500100
00500200
D[0]:= 76543210; 00500300
00520000
STREAM(R:=D[0]: S:=S, D:=D); 00520100
BEGIN 00520200
SI:= S; 00520300
SI:= SI+51; 00520400
DI:= DI+6; 00520500
DS:= 5 CHR; 00520600
00520700
SI:= LOC R; 00520800
DI:= D; 00520900
DI:= DI+32; 00521000
DS:= 8 DEC; 00521100
00521200
SI:= SI-8; 00521300
DI:= D; 00521400
2(DI:= DI+40); 00521500
DI:= DI+32; 00521600
DS:= 8 OCT; 00521700
END STREAM; 00521800
00999700
GO TO START; 00999800
END. 00999900