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:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user