1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-02-13 03:34:29 +00:00

Commit DCMCP transcription and emulator WIP as of 2012-06-20.

This commit is contained in:
paul
2012-06-21 04:05:10 +00:00
parent 7531c4f747
commit 60e8bc3594
7 changed files with 216 additions and 28 deletions

View File

@@ -4096,3 +4096,108 @@ EXIT: 04687550
% THIS SITUATION MAY NEVER OCCUR, BUT JUST IN CASE 04688000
WRITEPARITYREELSWITCH ~ UNIT[U] & MODE[5:40:8]; 04688050
END WRITEPARITYREELSWITCH; 04688100
REAL PROCEDURE PLACEFINDER(S, A, L); 04700000
VALUE S, A; 04701000
REAL S, A, L; 04702000
BEGIN INTEGER I; ARRAY B[*]; 04703000
REAL T, W, E, J, AA; 04704000
LABEL NULL, FOUND, EXIT; 04705000
LABEL SANDA; REAL SS; 04705500
W ~ -1; 04706000
B ~ [M[T ~ SPACE(30)]]&30[8:38:10]; 04707000
SS:=S; 04707500
IF S=0 THEN 04708000
NULL: BEGIN STREAM(T); DS:=20 LIT " "; GO EXIT; END; 04709000
DISKWAIT(-T,30,JAR[P1MIX,10]); 04710000
IF (JAR[P1MIX,10]=0) OR (AA~B[0].[FF])=0 THEN 04711000
SANDA: BEGIN STREAM(S:=SS,A,K:=M[PRT[P1MIX,8]].[10:2],T); 04712000
BEGIN DS~5 LIT ", S ="; 04713000
SI~LOC S; DS~4 DEC; 04714000
DS~5 LIT ", A ="; 04715000
DS~4 DEC; 04716000
DS:=LIT ":"; SI:=SI+7; DS:=CHR; 04716100
DI~T; DI~DI+5; DS~3 FILL; 04717000
DI~T; DI~DI+14; DS~3 FILL; 04718000
END STREAM; 04719000
GO EXIT; 04720000
END; 04721000
DISKWAIT(-T,30,I:=JAR[P1MIX,AA DIV JAR[P1MIX,8]+10+ 04722000
AA MOD JAR[P1MIX,8]+S DIV 30); 04723000
IF (J~B[S MOD 30])<0 THEN GO TO NULL; 04725000
AA ~ I ~ JAR[P1MIX,J.[CF] DIV JAR[P1MIX,8]+10]+ 04726000
J.[CF] MOD JAR[P1MIX,8]; 04727000
I~0; J~J.[FF]; 04728000
DO BEGIN S~(I+J).[36:11]; 04729000
IF W!(W:=S DIV 30) THEN DISKWAIT(-T,30,AA+W); 04731000
IF (E ~ B[S-W|30].[38:10])=A THEN GO TO FOUND; 04732000
IF E<A THEN I~S ELSE J~S; 04733000
END UNTIL J-I=1; 04734000
S~I; 04735000
FOUND: L ~ -B[S MOD 30].[28:10]; 04736000
IF L=0 THEN GO TO SANDA; 04736500
STREAM(L~ABS(L),T); 04737000
BEGIN DS:=11 LIT ",NEAR LINE "; 04738000
SI~LOC L; DS~8 DEC; 04739000
DS:=LIT " "; DI:=DI-9; DS:=7 FILL; 04740000
END STREAM; 04741000
EXIT: PLACEFINDER ~ T; 04742000
END PLACEFINDER; 04743000
$ SET OMIT = NOT(DATACOM ) 04999999
PROCEDURE LOGOUT(A); VALUE A; REAL A; FORWARD; %154-05606900
PROCEDURE FORMTIME(W,T); VALUE W,T; REAL W,T; %154-05607000
BEGIN INTEGER S,M; %154-05608000
T~(T+60) DIV 60; %154-05609000
S~T MOD 60; %154-05610000
T~T DIV 60; %154-05611000
M~T MOD 60; %154-05612000
T~T DIV 60; %154-05613000
STREAM(T,M,S,W~[W]); %154-05614000
BEGIN SI~LOC T; DS~2 DEC; %154-05615000
2(DS~LIT ":"; DS~2 DEC); %154-05616000
DI~W; DS~7 FILL; %154-05617000
END; %154-05618000
END; %154-05619000
PROCEDURE LOGSPACE(W,L); % THIS MAY ZIP 05700000
VALUE W,L; NAME W; INTEGER L; % FIRST WORD,WORD COUNT 05701000
COMMENT THIS WILL CLOBBER WORDS AROUND THOSE LOGGED; 05701010
BEGIN INTEGER B,I,J,K,N; ARRAY A[*]; LABEL OK; DEFINE Z=LOGFREE#; 05702000
N~L DIV 5; %NO REMAINDER ALLOWED 05702500
A:=[M[B:=SPACE(30)]]&30[8:38:10]; 05703000
IF Z>0 THEN SLEEP([Z],-0); Z~-Z; 05703500
$ SET OMIT = NOT(SHAREDISK) 05703699
DISKWAIT(-B,30,Z); 05704000
IF (I~A[0])+6+N}(J~A[1]) THEN BEGIN I~0; K~1 END %WRAP AROUND 05705000
ELSE IF I+N+100 GEQ J THEN 05706000
BEGIN INDEPENDTRUNNER(P(.LOGOUT),1,128); 05706100
K:=2; 05706200
END 05706300
ELSE IF I<J DIV 2 AND J DIV 2<I+N THEN K~3 % HALF FULL 05707000
ELSE GO TO OK; 05708000
STREAM(K:=K-1, J:=J:=SPACE(3)); 05709000
BEGIN CI:=CI+K; GO TO L2; GO TO L1; 05710000
DS:=14 LIT"#LOG HALF FULL"; GO TO L3; 05710500
L1: DS:=19 LIT" LOG FULL - AUTO LN"; GO TO L3; 05711000
L2: DS:=17 LIT"**LOG WRAP AROUND"; 05711500
L3: DS:=LIT"~"; 05712000
END; 05713000
SPOUT(J); 05714000
OK: A[0]~N+I; A[3]~K; A[2]~I~I+1; %WE NOW PUT THE WORDS IN I 05715000
W[L]~4; % END OF LOG 05715100
J~(I MOD 6)|5; %SIZE OF NEIGHBORHOOD (NBD) 05716000
$ SET OMIT = NOT(SHAREDISK) 05716999
IF (I~I DIV 6)!0 THEN DISKWAIT(B,30,Z); %DUMP RECORD ZERO 05722000
IF J!0 THEN % GET NBD 05723000
BEGIN IF I!0 THEN DISKWAIT(-B,30,Z+I); 05724000
MOVE(30-J,W INX 0,A INX J) 05725000
END 05726000
ELSE B:=W INX 0; 05727000
DISKWAIT(B,30,Z+I); 05728000
IF (L+J) GEQ 30 THEN 05728100
BEGIN K:=L-(J:=30-J)+1; 05728120
I:=I+1; 05728140
DO 05728160
BEGIN DISKWAIT(W INX J,IF K>1020 THEN 1020 ELSE K,Z+I); 05728180
J:=J+1020; 05728200
I:=I+34; 05728220
END UNTIL (K:=K-1020) LEQ 0; 05728240
END; 05728260

View File

@@ -49,9 +49,9 @@ function B5500CentralControl() {
/**************************************/
/* Global constants */
B5500CentralControl.prototype.rtcTick = 1000/60; // Real-time clock period, milliseconds
B5500CentralControl.rtcTick = 1000/60; // Real-time clock period, milliseconds
B5500CentralControl.prototype.pow2 = [ // powers of 2 from 0 to 52
B5500CentralControl.pow2 = [ // powers of 2 from 0 to 52
1, 2, 4, 8,
16, 32, 64, 128,
256, 512, 1024, 2048,
@@ -67,7 +67,7 @@ B5500CentralControl.prototype.pow2 = [ // powers of 2 from 0 to 52
281474976710656, 562949953421312, 1125899906842624, 2251799813685248,
4503599627370496];
B5500CentralControl.prototype.mask2 = [ // (2**n)-1 for n from 0 to 52
B5500CentralControl.mask2 = [ // (2**n)-1 for n from 0 to 52
0, 1, 3, 7,
15, 31, 63, 127,
255, 511, 1023, 2047,
@@ -91,8 +91,8 @@ B5500CentralControl.prototype.clear = function() {
clearTimeout(this.timer);
}
this.nextTimeStamp = new Date().getTime() + this.rtcTick;
this.timer = setTimeout(this.tock, this.rtcTick);
this.nextTimeStamp = new Date().getTime() + B5500CentralControl.rtcTick;
this.timer = setTimeout(this.tock, B5500CentralControl.rtcTick);
this.IAR = 0; // Interrupt address register
this.TM = 0; // Real-time clock (6 bits, 60 ticks per second)
@@ -148,7 +148,7 @@ B5500CentralControl.prototype.bit = function(word, bit) {
/* Extracts and returns the specified bit from the word */
var e = 47-bit;
return (e > 0 ? Math.floor(word/this.pow2[e]) : word) % 2;
return (e > 0 ? Math.floor(word/B5500CentralControl.pow2[e]) : word) % 2;
}
/**************************************/
@@ -171,7 +171,7 @@ B5500CentralControl.prototype.fieldIsolate = function(word, start, width) {
var ue = 48-start; // upper power exponent
var le = ue-width; // lower power exponent
return (le > 0 ? Math.floor(word/this.pow2[le]) : word) % this.pow2[width];
return (le > 0 ? Math.floor(word/B5500CentralControl.pow2[le]) : word) % B5500CentralControl.pow2[width];
}
/**************************************/
@@ -184,13 +184,13 @@ B5500CentralControl.prototype.fieldInsert = function(word, start, width, value)
var top = 0; // unaffected top portion of word
if (start > 0) {
top = word - (word % this.pow2[ue]);
top = word - (word % B5500CentralControl.pow2[ue]);
}
if (le > 0) {
bpower = this.pow2[le];
bpower = B5500CentralControl.pow2[le];
bottom = word % bpower;
}
return (value % this.pow2[width])*bpower + top + bottom;
return (value % B5500CentralControl.pow2[width])*bpower + top + bottom;
}
/**************************************/
@@ -430,7 +430,7 @@ B5500CentralControl.prototype.tock = function tock() {
that.CCI03F = 1; // set timer interrupt
// inhibit for now // that.signalInterrupt();
}
that.nextTimeStamp += that.rtcTick;
that.nextTimeStamp += B5500CentralControl.rtcTick;
that.timer = setTimeout(function() {that.tock()},
(that.nextTimeStamp < thisTime ? 0 : that.nextTimeStamp-thisTime));
}

View File

@@ -29,7 +29,7 @@ function B5500Processor() {
/**************************************/
B5500Processor.prototype.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
B5500Processor.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
/**************************************/
B5500Processor.prototype.clear = function() {
@@ -1172,7 +1172,7 @@ B5500Processor.prototype.schedule = function schedule() {
var that = schedule.that;
that.scheduler = null;
that.cycleLimit = that.timeSlice;
that.cycleLimit = B5500Processor.timeSlice;
that.cycleCount = 0;
that.run();

View File

@@ -5,6 +5,12 @@
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<link id=defaultStyleSheet rel=stylesheet type="text/css" href="B5500DistributionAndDisplay.css">
<script>
window.onload = function() {
window.open("B5500ProcessorPanel.html", "PAPanel", "resizable=yes,scrollbars=yes");
}
</script>
</head>
<body class=consoleBody>

View File

@@ -1,4 +1,4 @@
/***********************************************************************
/***********************************************************************
* retro-b5500/emulator B5500DDPanel.js
************************************************************************
* Copyright (c) 2012, Nigel Williams and Paul Kimpel.
@@ -39,7 +39,7 @@ B5500DDLamp.prototype.set = function(v) {
var newState = v & 1;
if (this.state ^ newState) { // the state has changed
this.element.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.element.style.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.state = newState;
}
}
@@ -49,7 +49,7 @@ B5500DDLamp.prototype.flip = function() {
/* Complements the visible state of the lamp */
var newState = this.state ^ 1;
this.element.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.element.style.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.state = newState;
}
@@ -133,7 +133,21 @@ B5500DDRegister.vSpacing = 24; // vertical lamp spacing, pixels
B5500DDRegister.vOffset = 5; // vertical lamp offset within container
/**************************************/
B5500DDRegister.prototype.update = function(value) {
B5500DDRegister.prototype.xCoord = function(col) {
/* Returns the horizontal lamp coordinate in "px" format */
return String((col-1)*B5500DDRegister.hSpacing + B5500DDRegister.hOffset) + "px";
}
/**************************************/
B5500DDRegister.prototype.yCoord = function(row) {
/* Returns the vertical lamp coordinate in "px" format */
return String((row-1)*B5500DDRegister.vSpacing + B5500DDRegister.vOffset) + "px";
}
/**************************************/
B5500DDRegister.prototype.YYupdate = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var low = (this.lastValue % 0x1000000) ^ (value % 0x1000000);
@@ -155,4 +169,34 @@ B5500DDRegister.prototype.update = function(value) {
high >>>= 1;
}
this.lastValue = value;
}
}
/**************************************/
B5500DDRegister.prototype.XXupdate = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var bit;
var mask = value % 0x1000000000000;
while (mask) {
bitNr++;
bit = mask % 2;
this.lamps[bitNr].set(bit);
mask = (mask-bit)/2;
}
}
/**************************************/
B5500DDRegister.prototype.update = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var bit;
var mask = value % 0x1000000000000;
while (mask) {
bitNr++;
bit = mask % 2;
this.lamps[bitNr].element.style.backgroundColor = (bit ? B5500DDLamp.onColor : B5500DDLamp.offColor);
mask = (mask-bit)/2;
}
}

View File

@@ -10,34 +10,60 @@
<script src="B5500ProcessorPanel.js"></script>
<script>
var panel;
var displayRefreshPeriod = 50; // milliseconds
var displayRefreshPeriod = 200; // milliseconds
var lastRefresh = new Date().getTime();
var nextRefresh = 0;
var panel;
var refreshTimer = null;
var totalTime = 0;
var totalDelay = 0;
var totalTime = 0;
var updateDisplay = function updateDisplay() {
/* Schedules itself to update the display on a periodic basis. */
var that = updateDisplay.that;
var thisTime = new Date().getTime();
var delta;
var meter = document.getElementById("idleMeter");
var that = updateDisplay.that;
panel.X.update(Math.random()*0x8000000000);
panel.A.update(Math.random()*0x1000000000000);
panel.B.update(Math.random()*0x1000000000000);
panel.P.update(Math.random()*0x1000000000000);
panel.J.update(Math.random()*0x10);
panel.Q.update(Math.random()*0x200000);
panel.R.update(Math.random()*0x200);
panel.AROF.update(thisTime%2);
panel.BROF.update(thisTime%4>>1);
panel.G.update(Math.random()*0x08);
panel.H.update(Math.random()*0x08);
panel.Y.update(Math.random()*0x40);
panel.Z.update(Math.random()*0x40);
panel.M.update(Math.random()*0x8000);
panel.K.update(Math.random()*0x08);
panel.V.update(Math.random()*0x08);
panel.N.update(Math.random()*0x10);
panel.S.update(Math.random()*0x8000);
panel.PROF.update(thisTime%7);
panel.T.update(Math.random()*0x1000);
panel.TROF.update(thisTime%8>>2);
panel.C.update(Math.random()*0x8000);
panel.I.update(Math.random()*0x200);
panel.E.update(Math.random()*0x40);
panel.TM.update(Math.random()*0x200);
panel.F.update(Math.random()*0x8000);
// Schedule ourself for the next period
nextRefresh += displayRefreshPeriod;
delta = nextRefresh-thisTime;
refreshTimer = setTimeout(updateDisplay, (delta < 0 ? 0 : delta));
totalTime += displayRefreshPeriod;
totalDelay += delta;
refreshTimer = setTimeout(updateDisplay, (delta < 0 ? (delta=0) : delta));
totalTime = (totalTime*99 + displayRefreshPeriod)/100;
totalDelay = (totalDelay*99 + delta)/100;
meter.value = (totalDelay/totalTime*100).toFixed(1) + "%";
};
window.onload = function() {
window.resizeTo(screen.availWidth, screen.availHeight*0.8);
window.moveTo(0, 300);
window.resizeTo(750, 600);
window.moveTo(screen.availWidth-750, screen.availHeight-600);
document.title = "B5500 Processor A";
panel = new B5500ProcessorPanel(window);
updateDisplay.that = this;

View File

@@ -15,6 +15,7 @@ function B5500ProcessorPanel(win) {
/* Constructor for the B5500 D&D Processor Panel object. Creates the
panel UI on window "win" */
var body = win.document.body;
var x;
// Row 1
@@ -28,7 +29,7 @@ function B5500ProcessorPanel(win) {
this.J.lamps[3].setCaption("4");
this.J.lamps[4].setCaption("8");
// adjust the weird position of the "8" bit
this.J.lamps[4].element.style.top = String(B5500DDRegister.vOffset) + "px";
this.J.lamps[4].element.style.top = this.J.yCoord(1);
this.Q = new B5500DDRegister(21, 16, 1, 3, "Q REG");
body.appendChild(this.Q.element);
@@ -77,6 +78,12 @@ function B5500ProcessorPanel(win) {
this.Z = new B5500DDRegister(6, 22, 5, 6, "Z");
body.appendChild(this.Z.element);
// adjust position of the Y & Z numeric bits
for (x=1; x<=4; x++) {
this.Y.lamps[x].element.style.top = this.Y.yCoord(8-x);
this.Z.lamps[x].element.style.top = this.Z.yCoord(8-x);
}
this.M = new B5500DDRegister(15, 23, 5, 3, "M REG");
body.appendChild(this.M.element);