1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-04-20 10:26:12 +00:00

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

This commit is contained in:
paul
2012-06-17 01:37:26 +00:00
parent 2e55dc2c81
commit beaf621394
6 changed files with 358 additions and 46 deletions

View File

@@ -3669,3 +3669,138 @@ FROG: DI:=BITLOCN; DI:=DI-5; 04662300
PTR:=PTR+12; 04662800
END; 04662900
MEMORY[KEY]:= P(DUP,LOD) & 0[1:1:2] & 39[39:39:9]; 04663000
MEMORY[KEY+2]:= P(DUP,LOD) & OPTION[2:2:1]; 04663100
LINKUP(20,KEY); 04663200
END;END; 04663300
END TAPEPARITYRETRY;% 04666000
REAL PROCEDURE WRITEPARITYREELSWITCH(OIOD,RC); 04667000
VALUE OIOD,RC; REAL OIOD,RC; 04667050
% 04667100
% THE PURPOSE OF THIS ROUTINE IS TO ALLOW OBJECT PROGRAMS 04667150
% TO CHANGE MAG TAPE UNITS WHEN ENCOUNTERING A WRITE PARITY 04667200
% ERROR. THIS ROUTINE IS CALLED FROM EITHER TAPEPARITYRETRY 04667250
% IN RESPONSE TO A FATAL WRITE PARITY ERROR OR FROM 04667300
% REELCHANGER AFTER AN "RC" KEYBOARD REQUEST BY THE OPERATOR. 04667350
% 04667400
% BASICALLY, THIS ROUTINE READS INTO CORE THE LAST TWO 04667450
% SUCESSFULLY WRITTEN BLOCKS ON THE TAPE, CLOSES THE FILE 04667500
% (MARKING THE TAPE AS AN END OF REEL), OBTAINS ANOTHER 04667550
% TAPE UNIT, RE-WRITES THE TWO BLOCKS IN CORE FOLLOWED 04667600
% BY THE BLOCK IN WHICH THE PARITY ERROR OCURRED, AND 04667650
% ALLOWS THE PROGRAM TO CONTINUE WRITING ON THE NEW TAPE. 04667700
% 04667750
% WHEN THIS ROUTINE IS CALLED DUE TO AN OPERATOR "RC" 04667800
% MESSAGE, THERE IS NO FATAL PARITY ERROR AT THIS POINT. 04667850
% SO THE SAVING OF THE LAST TWO RECORDS IS UNNECESSARY 04667900
% AND ONLY THE CLOSING OF THE FILE AND OBTAINING OF A NEW 04667950
% UNIT ARE REQUIRED. 04668000
% 04668050
% THE PARAMETERS ARE USED AS FOLLOWS: 04668100
% OIOD THE ORIGINAL I/O DESCRIPTOR ON WHICH 04668150
% A FATAL ERROR OCCURRED 04668200
% 04668250
% RC 1 IF CALLED FROM REELCHANGER, 0 OTHERWISE 04668300
% 04668350
BEGIN 04668400
INTEGER I,LOGICLRC; 04668450
REAL BSIZE,FNUM,NUMBUFFS,NUMRECS,REEL); 04668500
REAL S,Y,U,OLDU,SAVEU,MIX; 04668550
REAL TEMP,T1,T2,T3,T4; 04668600
REAL IOD,RESULT,MODE,TOPIOD,TM,HOLDCT; 04668650
REAL FIRSTREC,SECREC,FIRSTRECIO,SECRECIO; 04668700
BOOLEAN TOGGLES; 04668750
ARRAY FIB[*],FPB[*],LABELA[*],TANK[*]; 04668800
% 04668850
% THE LOCAL VARIABLES ARE USED AS FOLLOWS: 04668900
% INTEGERS 04668950
% I TEMPORARY 04669000
% LOGICLRC CONTAINS THE LOGICAL RECORD COUNT 04669050
% REALS 04669100
% BSIZE BLOCK SIZE OF FILE 04669150
% FNUM FILE NUMBER WITHIN FPB 04669200
% NUMBUFFS TOTAL NUMBER OF BUFFERS DECLARED FOR FILE 04669250
% NUMRECS RECORDS PER BLOCK (BSIZE DIV RECORD SIZE) 04669275
% REEL CONTAINS THE CURRENT REEL NUMBER +1 04669300
% S INDEX INTO IOQUE OF UNSUCCESSFUL I/O 04669350
% Y TEMPORARY 04669400
% U LOGICAL UNIT NUMBER OF TAPE UNIT BEING WRITTEN 04669450
% OLDU HARDWARE UNIT NUMBER OF TAPE UNIT 04669500
% SAVEU LOGICAL UNIT OF ORIGINAL TAPE UNIT WITH ERROR 04669550
% MIX MIX INDEX OF JOB FOR WHICH RECOVERY IS ATTEMPTED 04669600
% TEMP 04669650
% T1,T2,T3,T4 TEMPORARY 04669700
% IOD HOLDS THE I/O DESCRIPTOR FOR EACH I/O ATTEMPTED 04669750
% RESULT RECEIVES THE LAST I/O RESULT DESCRIPTOR 04669800
% MODE USED TO INDICATE A SUCCESSFUL RECOVERY ATTEMPT 04669850
% TOPIOD LOCATION OF TOP I/O DESCRIPTOR IN TANK 04669900
% TM TEMPORARY, USED FOR WRITING TAPE MARK 04669950
% HOLDCT CONTAINS THE NUMBER OF FILLED BUFFERS 04670000
% FIRSTREC 04670050
% SECREC ADDRESSES OF AREAS TO HOLD LAST TWO BLOCKS 04670100
% FIRSTRECIO 04670150
% SECRECIO VARIABLE LENGTH BLOCK I/O DESCRIPTORS 04670200
% BOOLEAN 04670250
% TOGGLES USED TO HOLD VARIOUS BOOLEANS (SEE DEFINES) 04670300
% ARRAYS 04670350
% FIB FIB ARRAY, USED FOR CLOSEING THE FILE 04670400
% FPB FPB ARRAY, USED FOR OPENING NEW FILE 04670450
% LABELA ARRAY DESCRIPTOR FOR IN-CORE LABEL RECORD 04670500
% TANK TANK ARRAY, CONTAINING I/O DESCRIPTORS 04670550
% 04670600
LABEL L1,RETRY,PROB,KAPUT,RESETUNITS,ARN,ERROROUT,XIO,EXIT; 04670650
DEFINE ALFA = TOGGLES.[47:1]#, 04670700
DSED = TOGGLES.[46:1]#, 04670750
LABELED = TOGGLES.[45:1]#, 04670800
NORMALPROCESS = TOGGLES.[44:1]#, 04670850
PBT = TOGGLES.[43:1]#; 04670900
$ SET OMIT = NOT(PACKETS) 04670950
DEFINE UNITNO = PSEUDOMIX[MIX]#; 04671000
$ POP OMIT 04671050
SUBROUTINE DOIONOW; 04671100
BEGIN 04671150
% DOIONOW IS COPIED FROM TAPEPARITYRETRY 04671200
FOR Y ~ 1 STEP 1 UNTIL 18 DO 04671250
BEGIN IF IOD.[24:1] THEN 04671300
BEGIN % WAIT 1/15 SECOND BETWEEN READ RETRIES 04671350
WHILE T4 > CLOCK+P(RTR) DO SLEEP(1,1); 04671400
T4 ~ CLOCK+P(RTR)+4; 04671450
END; 04671500
IF IOQUESLOTS=0 THEN SLEEP([IOQUESLOTS],63); 04671550
IOQUESLOTS ~ IOQUESLOTS-1; 04671600
IOQUEAVAIL ~ IOQUE[T1~IOQUEAVAIL]; 04671650
IOQUE[T1] ~ IOD; 04671700
IF (T2~(T3~UNIT[U]).[FF])=@77777 THEN T3.[CF]~T1; 04671750
LOCATQUE[T1] ~ [RESULT] & MIX[3:43:5] & 04671800
U[12:42:6] & T2[CTF]; 04671850
UNIT[U] ~ T3 & T1[CTF] & 100[5:35:13]; 04671900
STARTIO(U); 04671950
FINALQUE[T1] ~ NABS(IOD) & 0[25:40:8] OR IOMASK; 04672000
RESULT ~ 0; 04672050
SLEEP([UNIT[U]],@100000000000); 04672100
IF RESULT.[30:1] THEN GO ERROROUT; % NOT READY 04672150
IF RESULT.[29:1] AND RESLT.[2:1] THEN 04672200
BEGIN 04672250
IF RESLT.[12:1] THEN % BLANK TAPE 04672300
IF IOD.[24:1] THEN % READ 04672350
TRANSACTION[U] ~ (*P(DUP))-(1 & IOD[1:22:1]) ELSE 04672400
BEGIN % WRITE 04672450
STREAM(A~TINU[U], T~T2~SPACE(3)); 04672500
BEGIN SI~LOC A; SI~SI+5; DS~3 CHR; 04672550
DS~21 LIT" BLANK TAPE ON WRITE~"; 04672600
END; 04672650
SPOUTER(T2,UNITNO,35); 04672700
GO ERROROUT; 04672750
END; 04672800
IF RESULT.[11:1] THEN % MEM PARITY 04672850
BEGIN 04672900
STREAM(A~TINU[U], T~T2~SPACE(3)); 04672950
BEGIN SI~LOC A; SI~SI+5; DS~3 CHR; 04673000
DS~13 LIT" I/O MEM PAR~"; 04673050
END; 04673100
SPOUTER(T2,UNITNO,35); 04673150
GO ERROROUT; 04673200
END; 04673250
IF RESULT.[13:2]!0 THEN Y ~ 18; 04673300
END ELSE 04673350
GO XIO; 04673400
END; 04673450

View File

@@ -36,7 +36,6 @@ function B5500CentralControl() {
this.PB1L = 0; // 0=> PA is P1, 1=> PB is P1
this.cardLoadSelect = 0; // 0=> load from disk/drum; 1=> load from cards
this.rtcTick = 1000/60; // Real-time clock period, milliseconds
this.nextTimeStamp = 0; // Next actual Date.getTime() expected
this.timer = null; // Reference to the RTC setTimeout id.
this.loadTimer = null; // Reference to the load setTimeout id.
@@ -47,6 +46,43 @@ function B5500CentralControl() {
this.loadComplete.that = this;
}
/**************************************/
/* Global constants */
B5500CentralControl.prototype.rtcTick = 1000/60; // Real-time clock period, milliseconds
B5500CentralControl.prototype.pow2 = [ // powers of 2 from 0 to 52
1, 2, 4, 8,
16, 32, 64, 128,
256, 512, 1024, 2048,
4096, 8192, 16384, 32768,
65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608,
16777216, 33554432, 67108864, 134217728,
268435456, 536870912, 1073741824, 2147483648,
4294967296, 8589934592, 17179869184, 34359738368,
68719476736, 137438953472, 274877906944, 549755813888,
1099511627776, 2199023255552, 4398046511104, 8796093022208,
17592186044416, 35184372088832, 70368744177664, 140737488355328,
281474976710656, 562949953421312, 1125899906842624, 2251799813685248,
4503599627370496];
B5500CentralControl.prototype.mask2 = [ // (2**n)-1 for n from 0 to 52
0, 1, 3, 7,
15, 31, 63, 127,
255, 511, 1023, 2047,
4095, 8191, 16383, 32767,
65535, 131071, 262143, 524287,
1048575, 2097151, 4194303, 8388607,
16777215, 33554431, 67108863, 134217727,
268435455, 536870911, 1073741823, 2147483647,
4294967295, 8589934591, 17179869183, 34359738367,
68719476735, 137438953471, 274877906943, 549755813887,
1099511627775, 2199023255551, 4398046511103, 8796093022207,
17592186044415, 35184372088831, 70368744177663, 140737488355327,
281474976710655, 562949953421311, 1125899906842623, 2251799813685247,
4503599627370495];
/**************************************/
B5500CentralControl.prototype.clear = function() {
/* Initializes the system and starts the real-time clock */
@@ -107,39 +143,6 @@ B5500CentralControl.prototype.clear = function() {
}
}
/**************************************/
B5500CentralControl.prototype.pow2 = [ // powers of 2 from 0 to 52
1, 2, 4, 8,
16, 32, 64, 128,
256, 512, 1024, 2048,
4096, 8192, 16384, 32768,
65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608,
16777216, 33554432, 67108864, 134217728,
268435456, 536870912, 1073741824, 2147483648,
4294967296, 8589934592, 17179869184, 34359738368,
68719476736, 137438953472, 274877906944, 549755813888,
1099511627776, 2199023255552, 4398046511104, 8796093022208,
17592186044416, 35184372088832, 70368744177664, 140737488355328,
281474976710656, 562949953421312, 1125899906842624, 2251799813685248,
4503599627370496];
B5500CentralControl.prototype.mask2 = [ // (2**n)-1 for n from 0 to 52
0, 1, 3, 7,
15, 31, 63, 127,
255, 511, 1023, 2047,
4095, 8191, 16383, 32767,
65535, 131071, 262143, 524287,
1048575, 2097151, 4194303, 8388607,
16777215, 33554431, 67108863, 134217727,
268435455, 536870911, 1073741823, 2147483647,
4294967295, 8589934591, 17179869183, 34359738367,
68719476735, 137438953471, 274877906943, 549755813887,
1099511627775, 2199023255551, 4398046511103, 8796093022207,
17592186044415, 35184372088831, 70368744177663, 140737488355327,
281474976710655, 562949953421311, 1125899906842623, 2251799813685247,
4503599627370495];
/**************************************/
B5500CentralControl.prototype.bit = function(word, bit) {
/* Extracts and returns the specified bit from the word */

View File

@@ -9,37 +9,42 @@
<body class=consoleBody>
<div id=NotReadyBtn class=blackButton style="right:1200px">
<div style="position:relative; width:1300px; height:128px">
<div id=HaltBtn class=blackButton style="right:1200px">
<span class=buttonCaption>HALT</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:1050px">
<span class=buttonCaption>NOT READY</span>
</div>
<div id=NotReadyBtn class=blackButton style="right:975px">
<div id=LoadSelectBtn class=blackButton style="right:975px">
<span class=buttonCaption>LOAD SELECT</span>
</div>
<div id=NotReadyBtn class=blackButton style="right:900px">
<div id=LoadBtn class=blackButton style="right:900px">
<span class=buttonCaption>LOAD</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:750px">
<div id=MemoryCheckBtn class=yellowButton style="right:750px">
<span class=buttonCaption>MEMORY CHECK</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:675px">
<div id=ANormalBtn class=yellowButton style="right:675px">
<span class=buttonCaption>A NORMAL</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:600px">
<div id=AControlBtn class=yellowButton style="right:600px">
<span class=buttonCaption>A CONTROL</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:525px">
<div id=BNormalBtn class=yellowButton style="right:525px">
<span class=buttonCaption>B NORMAL</span>
</div>
<div id=NotReadyBtn class=yellowButton style="right:450px">
<div id=BControlBtn class=yellowButton style="right:450px">
<span class=buttonCaption>B CONTROL</span>
</div>
<div id=NotReadyBtn class=whiteButton style="right:300px">
<div id=PowerOnBtn class=whiteButton style="right:300px">
<span class=buttonCaption>POWER ON</span>
</div>
<div id=NotReadyBtn class=blackButton style="right:225px">
<div id=PowerOffBtn class=blackButton style="right:225px">
<span class=buttonCaption>POWER OFF</span>
</div>
@@ -48,5 +53,7 @@
</div>
<div id=B5500Logo> B 5500 </div>
</div>
</body>
</html>

View File

@@ -73,6 +73,18 @@ DIV.yellowButton {
border: 1px solid #DDDDDD;
border-radius: 4px}
DIV.ddLamp {
position: absolute;
width: 12px;
height: 12px;
font-size: 4px;
border-radius: 8px;
border: 2px solid black}
DIV.ddRegister {
position: absolute;
font-size: 6px}
IMG#BurroughsLogoImage {
width: 150px;
text-align: center;

View File

@@ -0,0 +1,153 @@
/***********************************************************************
* retro-b5500/emulator B5500DistributionAndDisplay.js
************************************************************************
* Copyright (c) 2012, Nigel Williams and Paul Kimpel.
* Licensed under the MIT License, see http://www.opensource.org/licenses/mit-license.php
************************************************************************
* JavaScript object definition for the B5500 Distribution & Display module.
************************************************************************
* 2012-06-16 P.Kimpel
* Original version, from thin air.
***********************************************************************/
/***********************************************************************
* Panel Lamp *
************************************************************************
function B5500DDLamp(x, y) {
/* Constructor for the lamp objects used within D&D. x & y are the
coordinates of the lamp within its containing element */
this.state = 0; // current lamp state, 0=off
this.element = // visible DOM element
document.createElement("div");
this.element.className = "ddLamp";
this.element.style.left = String(x) + "px";
this.element.style.top = String(y) + "px";
}
/**************************************/
B5500DDLamp.prototype.onColor = "#FF9900";
B5500DDLamp.prototype.offColor = "#999999";
/**************************************/
B5500DDLamp.prototype.set = function(v) {
/* Changes the visible state of the lamp according to the low-order
bit of "v". */
newState = v & 1;
if (this.state ^ newState) { // the state has changed
this.element.backgroundColor = (v & 1 ? this.onColor : this.offColor);
this.state = newState;
}
}
/***********************************************************************
* Panel Register *
***********************************************************************/
B5500DDRegister(bits, x, y, rows, deltax, deltay) {
/* Constructor for the register objects used within D&D.
*/
var cols = Math.floor((bits+rows-1)/rows);
var height = rows*this.vSpacing;
var width = cols*this.hSpacing;
this.bits = bits; // number of bits in the register
this.left = x; // horizontal offset relative to container
this.top = y; // vertical offset relative to container
this.element = // visible DOM element
document.createElement("div");
this.element.className = "ddRegister";
this.element.style.left = String(x) + "px";
this.element.style.top = String(y) + "px";
}
/**************************************/
B5500DDRegister.prototype.hSpacing = 18; // horizontal lamp spacing, pixels
B5500DDRegister.prototype.vSpacing = 18; // vertical lamp spacing, pixels
/***********************************************************************
* Distribution And Display Module *
************************************************************************/
function B5500DistributionAndDisplay() {
/* Constructor for the Distribution And Display module object */
/* Global system modules */
this.nextTimeStamp = 0; // Next actual Date.getTime() expected
this.timer = null; // Reference to the RTC setTimeout id.
this.clear(); // Create and initialize the Central Control state
this.tock.that = this; // Establish contexts for when called from setTimeout().
}
/**************************************/
/* Global constants */
B5500DistributionAndDisplay.prototype.refreshPeriod = 50; // milliseconds
/**************************************/
B5500DistributionAndDisplay.prototype.clear = function() {
/* Initializes the system and starts the real-time clock */
if (this.timer) {
clearTimeout(this.timer);
}
this.nextTimeStamp = new Date().getTime() + this.rtcTick;
this.timer = setTimeout(this.tock, this.rtcTick);
this.IAR = 0; // Interrupt address register
this.TM = 0; // Real-time clock (6 bits, 60 ticks per second)
this.CCI03F = 0; // Time interval interrupt
this.CCI04F = 0; // I/O busy interrupt
this.CCI05F = 0; // Keyboard request interrupt
this.CCI06F = 0; // Printer 1 finished interrupt
this.CCI07F = 0; // Printer 2 finished interrupt
this.CCI08F = 0; // I/O unit 1 finished interrupt (RD in @14)
this.CCI09F = 0; // I/O unit 2 finished interrupt (RD in @15)
this.CCI10F = 0; // I/O unit 3 finished interrupt (RD in @16)
this.CCI11F = 0; // I/O unit 4 finished interrupt (RD in @17)
this.CCI12F = 0; // P2 busy interrupt
this.CCI13F = 0; // Remote inquiry request interrupt
this.CCI14F = 0; // Special interrupt #1 (not used)
this.CCI15F = 0; // Disk file #1 read check finished
this.CCI16F = 0; // Disk file #2 read check finished
this.MCYF = 0; // Memory cycle FFs (one bit per M0..M7)
this.PAXF = 0; // PA memory exchange select (M0..M7)
this.PBXF = 0; // PB memory exchange select (M0..M7)
this.I1XF = 0; // I/O unit 1 exchange select (M0..M7)
this.I2XF = 0; // I/O unit 2 exchange select (M0..M7)
this.I3XF = 0; // I/O unit 3 exchange select (M0..M7)
this.I4XF = 0; // I/O unit 4 exchange select (M0..M7)
this.AD1F = 0; // I/O unit 1 busy
this.AD2F = 0; // I/O unit 2 busy
this.AD3F = 0; // I/O unit 3 busy
this.AD4F = 0; // I/O unit 4 busy
this.LOFF = 0; // Load button pressed on console
this.CTMF = 0; // Commence timing FF
this.P2BF = 0; // Processor 2 busy FF
this.HP2F = 1; // Halt processor 2 FF
if (this.PA) {
this.PA.clear();
}
if (this.PB) {
this.PB.clear();
}
this.P1 = (this.PB1L ? this.PB : this.PA);
this.P2 = (this.PB1L ? this.PA : this.PB);
if (!this.P2) {
this.P2BF = 1; // mark non-existent P2 as busy
}
}

View File

@@ -14,8 +14,6 @@
function B5500Processor() {
/* Constructor for the Processor module object */
this.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
this.scheduler = null; // Reference to current setTimeout id
this.accessor = { // Memory access control block
addr: 0, // Memory address
@@ -29,6 +27,10 @@ function B5500Processor() {
this.schedule.that = this; // Establish context for when called from setTimeout()
}
/**************************************/
B5500Processor.prototype.timeSlice = 5000; // Standard run() timeslice, about 5ms (we hope)
/**************************************/
B5500Processor.prototype.clear = function() {
/* Initializes the processor state */