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:
@@ -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.
47
webUI/tools/tests/CHARMODE.esp_m
Normal file
47
webUI/tools/tests/CHARMODE.esp_m
Normal 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
|
||||
Reference in New Issue
Block a user