diff --git a/emulator/B5500CentralControl.js b/emulator/B5500CentralControl.js index 0684e48..9ddaa0c 100644 --- a/emulator/B5500CentralControl.js +++ b/emulator/B5500CentralControl.js @@ -62,7 +62,7 @@ function B5500CentralControl() { /**************************************/ /* Global constants */ -B5500CentralControl.version = "0.05"; +B5500CentralControl.version = "0.06"; B5500CentralControl.rtcTick = 1000/60; // Real-time clock period, milliseconds @@ -119,8 +119,8 @@ B5500CentralControl.unitSpecs = { SPO: {unitIndex: 22, designate: 30, unitClass: B5500SPOUnit}, DKA: {unitIndex: 29, designate: 6, unitClass: B5500DiskUnit}, DKB: {unitIndex: 28, designate: 12, unitClass: B5500DiskUnit}, - CRA: {unitIndex: 24, designate: 10, unitClass: null}, - CRB: {unitIndex: 23, designate: 14, unitClass: null}, + CRA: {unitIndex: 24, designate: 10, unitClass: B5500CardReader}, + CRB: {unitIndex: 23, designate: 14, unitClass: B5500CardReader}, CPA: {unitIndex: 25, designate: 10, unitClass: null}, LPA: {unitIndex: 27, designate: 22, unitClass: null}, LPB: {unitIndex: 26, designate: 26, unitClass: null}, @@ -150,7 +150,7 @@ B5500CentralControl.unitSpecs = { /**************************************/ -B5500CentralControl.bindMethod = function(f, context) { +B5500CentralControl.bindMethod = function bindMethod(f, context) { /* Returns a new function that binds the function "f" to the object "context". Note that this is a constructor property function, NOT an instance method of the CC object */ @@ -159,7 +159,7 @@ B5500CentralControl.bindMethod = function(f, context) { }; /**************************************/ -B5500CentralControl.prototype.clear = function() { +B5500CentralControl.prototype.clear = function clear() { /* Initializes (and if necessary, creates) the system and starts the real-time clock */ @@ -218,7 +218,7 @@ B5500CentralControl.prototype.clear = function() { }; /**************************************/ -B5500CentralControl.prototype.bit = function(word, bit) { +B5500CentralControl.prototype.bit = function bit(word, bit) { /* Extracts and returns the specified bit from the word */ var e = 47-bit; // word lower power exponent var p; // bottom portion of word power of 2 @@ -231,7 +231,7 @@ B5500CentralControl.prototype.bit = function(word, bit) { }; /**************************************/ -B5500CentralControl.prototype.bitSet = function(word, bit) { +B5500CentralControl.prototype.bitSet = function bitSet(word, bit) { /* Sets the specified bit in word and returns the updated word */ var ue = 48-bit; // word upper power exponent var le = ue-1; // word lower power exponent @@ -245,7 +245,7 @@ B5500CentralControl.prototype.bitSet = function(word, bit) { }; /**************************************/ -B5500CentralControl.prototype.bitReset = function(word, bit) { +B5500CentralControl.prototype.bitReset = function bitReset(word, bit) { /* Resets the specified bit in word and returns the updated word */ var ue = 48-bit; // word upper power exponent var le = ue-1; // word lower power exponent @@ -258,7 +258,7 @@ B5500CentralControl.prototype.bitReset = function(word, bit) { }; /**************************************/ -B5500CentralControl.prototype.fieldIsolate = function(word, start, width) { +B5500CentralControl.prototype.fieldIsolate = function fieldIsolate(word, start, width) { /* Extracts a bit field [start:width] from word and returns the field */ var le = 48-start-width; // lower power exponent var p; // bottom portion of word power of 2 @@ -269,7 +269,7 @@ B5500CentralControl.prototype.fieldIsolate = function(word, start, width) { }; /**************************************/ -B5500CentralControl.prototype.fieldInsert = function(word, start, width, value) { +B5500CentralControl.prototype.fieldInsert = function fieldInsert(word, start, width, value) { /* Inserts a bit field from the low-order bits of value ([48-width:width]) into word.[start:width] and returns the updated word */ var ue = 48-start; // word upper power exponent @@ -284,7 +284,7 @@ B5500CentralControl.prototype.fieldInsert = function(word, start, width, value) }; /**************************************/ -B5500CentralControl.prototype.fieldTransfer = function(word, wstart, width, value, vstart) { +B5500CentralControl.prototype.fieldTransfer = function fieldTransfer(word, wstart, width, value, vstart) { /* Inserts a bit field from value.[vstart:width] into word.[wstart:width] and returns the updated word */ var ue = 48-wstart; // word upper power exponent @@ -304,7 +304,7 @@ B5500CentralControl.prototype.fieldTransfer = function(word, wstart, width, valu }; /**************************************/ -B5500CentralControl.prototype.fetch = function(acc) { +B5500CentralControl.prototype.fetch = function fetch(acc) { /* Called by a requestor module passing accessor object "acc" to fetch a word from memory. */ var addr = acc.addr; @@ -348,7 +348,7 @@ B5500CentralControl.prototype.fetch = function(acc) { }; /**************************************/ -B5500CentralControl.prototype.store = function(acc) { +B5500CentralControl.prototype.store = function store(acc) { /* Called by requestor module passing accessor object "acc" to store a word into memory. */ var addr = acc.addr; @@ -392,7 +392,7 @@ B5500CentralControl.prototype.store = function(acc) { }; /**************************************/ -B5500CentralControl.prototype.signalInterrupt = function() { +B5500CentralControl.prototype.signalInterrupt = function signalInterrupt() { /* Called by all modules to signal that an interrupt has occurred and to invoke the interrupt prioritization mechanism. This will result in an updated vector address in the IAR. Can also be called to reprioritize @@ -430,7 +430,7 @@ B5500CentralControl.prototype.signalInterrupt = function() { }; /**************************************/ -B5500CentralControl.prototype.clearInterrupt = function() { +B5500CentralControl.prototype.clearInterrupt = function clearInterrupt() { /* Resets an interrupt based on the current setting of this.IAR, then reprioritizes any remaining interrupts, leaving the new vector address in this.IAR. */ @@ -555,7 +555,7 @@ B5500CentralControl.prototype.tock = function tock() { }; /**************************************/ -B5500CentralControl.prototype.haltP2 = function() { +B5500CentralControl.prototype.haltP2 = function haltP2() { /* Called by P1 to halt P2. storeForInterrupt() will set P2BF=0 */ this.HP2F = 1; @@ -566,7 +566,7 @@ B5500CentralControl.prototype.haltP2 = function() { }; /**************************************/ -B5500CentralControl.prototype.initiateP2 = function() { +B5500CentralControl.prototype.initiateP2 = function initiateP2() { /* Called by P1 to initiate P2. Assumes that an INCW has been stored at memory location @10. If P2 is busy or not present, sets the P2 busy interrupt. Otherwise, loads the INCW into P2's A register and initiates @@ -583,7 +583,7 @@ B5500CentralControl.prototype.initiateP2 = function() { }; /**************************************/ -B5500CentralControl.prototype.initiateIO = function() { +B5500CentralControl.prototype.initiateIO = function initiateIO() { /* Selects an I/O unit and initiates an I/O */ if (this.IO1 && this.IO1.REMF && !this.AD1F) { @@ -605,7 +605,7 @@ B5500CentralControl.prototype.initiateIO = function() { }; /**************************************/ -B5500CentralControl.prototype.interrogateIOChannel = function() { +B5500CentralControl.prototype.interrogateIOChannel = function interrogateIOChannel() { /* Returns a value as for the processor TIO syllable indicating the first available and non-busy I/O Unit */ @@ -623,7 +623,7 @@ B5500CentralControl.prototype.interrogateIOChannel = function() { }; /**************************************/ -B5500CentralControl.prototype.interrogateUnitStatus = function() { +B5500CentralControl.prototype.interrogateUnitStatus = function interrogateUnitStatus() { /* Returns a bitmask as for the processor TUS syllable indicating the ready status of all peripheral units */ @@ -631,7 +631,7 @@ B5500CentralControl.prototype.interrogateUnitStatus = function() { }; /**************************************/ -B5500CentralControl.prototype.testUnitReady = function(index) { +B5500CentralControl.prototype.testUnitReady = function testUnitReady(index) { /* Determines whether the unit index "index" is currently in ready status. Returns 1 if ready, 0 if not ready */ @@ -639,7 +639,7 @@ B5500CentralControl.prototype.testUnitReady = function(index) { }; /**************************************/ -B5500CentralControl.prototype.testUnitBusy = function(index) { +B5500CentralControl.prototype.testUnitBusy = function testUnitBusy(index) { /* Determines whether the unit index "index" is currently in use by any other I/O Unit. Returns 1 if busy, 0 if not busy */ @@ -647,7 +647,7 @@ B5500CentralControl.prototype.testUnitBusy = function(index) { }; /**************************************/ -B5500CentralControl.prototype.setUnitBusy = function(index, busy) { +B5500CentralControl.prototype.setUnitBusy = function setUnitBusy(index, busy) { /* Sets or resets the unit-busy mask bit for unit index "index" */ if (index) { @@ -657,7 +657,7 @@ B5500CentralControl.prototype.setUnitBusy = function(index, busy) { }; /**************************************/ -B5500CentralControl.prototype.halt = function() { +B5500CentralControl.prototype.halt = function halt() { /* Halts the processors. Any in-process I/Os are allowed to complete */ if (this.timer) { @@ -723,10 +723,10 @@ B5500CentralControl.prototype.loadComplete = function loadComplete(dontStart) { }; /**************************************/ -B5500CentralControl.prototype.load = function(dontStart) { +B5500CentralControl.prototype.load = function load(dontStart) { /* Initiates a Load operation to start the system. If "dontStart" is truthy, then only the MCP bootstrap is loaded into memory -- P1 is not started */ - var boundLoadComplete = (function(that, dontStart) { + var boundLoadComplete = (function boundLoadComplete(that, dontStart) { return function() {return that.loadComplete(dontStart)} })(this, dontStart); @@ -754,7 +754,7 @@ B5500CentralControl.prototype.load = function(dontStart) { }; /**************************************/ -B5500CentralControl.prototype.loadTest = function(buf, loadAddr) { +B5500CentralControl.prototype.loadTest = function loadTest(buf, loadAddr) { /* Loads a test codestream into memory starting at B5500 word address "loadAddr" from the ArrayBuffer "buf". Returns the number of B5500 words loaded into memory. Note that when loading an ESPOL "DISK" file, @@ -809,7 +809,7 @@ B5500CentralControl.prototype.loadTest = function(buf, loadAddr) { }; /**************************************/ -B5500CentralControl.prototype.runTest = function(runAddr) { +B5500CentralControl.prototype.runTest = function runTest(runAddr) { /* Executes a test program previously loaded by this.loadTest on processor P1. "runAddr" is the B5500 word address at which execution will begin (typically 0x10 [octal 20]) */ @@ -822,7 +822,7 @@ B5500CentralControl.prototype.runTest = function(runAddr) { }; /**************************************/ -B5500CentralControl.prototype.configureSystem = function() { +B5500CentralControl.prototype.configureSystem = function configureSystem() { /* Establishes the hardware module configuration from the B5500SystemConfiguration module */ var cfg = B5500SystemConfiguration; @@ -834,7 +834,7 @@ B5500CentralControl.prototype.configureSystem = function() { var x; function makeChange(cc, maskBit) { - return function(ready) { + return function statusChange(ready) { cc.unitStatusMask = (ready ? cc.bitSet(cc.unitStatusMask, maskBit) : cc.bitReset(cc.unitStatusMask, maskBit)); }; @@ -843,41 +843,41 @@ B5500CentralControl.prototype.configureSystem = function() { function makeSignal(cc, mnemonic) { switch (mnemonic) { case "SPO": - return function() { + return function signalSPO() { cc.CCI05F = 1; cc.signalInterrupt(); }; break; case "LPA": - return function() { + return function signalLPA() { cc.setUnitBusy(27, 0); cc.CCI06F = 1; cc.signalInterrupt(); }; break; case "LPB": - return function() { + return function signalLPB() { cc.setUnitBusy(26, 0); cc.CCI07F = 1; cc.signalInterrupt(); }; break; case "DKA": - return function() { + return function signalDKA() { cc.setUnitBusy(29, 0); cc.CCI15F = 1; cc.signalInterrupt(); }; break; case "DKB": - return function() { + return function signalDKB() { cc.setUnitBusy(28, 0); cc.CCI16F = 1; cc.signalInterrupt(); }; break; default: - return function() {}; + return function signalDefault() {}; break; } } @@ -924,7 +924,7 @@ B5500CentralControl.prototype.configureSystem = function() { }; /**************************************/ -B5500CentralControl.prototype.powerOn = function() { +B5500CentralControl.prototype.powerOn = function powerOn() { /* Powers up the system and establishes the hardware module configuration. Redundant power-ons are ignored. */ @@ -935,7 +935,7 @@ B5500CentralControl.prototype.powerOn = function() { }; /**************************************/ -B5500CentralControl.prototype.powerOff = function() { +B5500CentralControl.prototype.powerOff = function powerOff() { /* Powers down the system and deallocates the hardware modules. Redundant power-offs are ignored. */ var x; diff --git a/emulator/B5500IOUnit.js b/emulator/B5500IOUnit.js index 6555dcf..7bf5335 100644 --- a/emulator/B5500IOUnit.js +++ b/emulator/B5500IOUnit.js @@ -63,6 +63,7 @@ function B5500IOUnit(ioUnitID, cc) { // Establish contexts for asynchronously-called methods this.boundForkIO = B5500CentralControl.bindMethod(this.forkIO, this); this.boundFinishGeneric = this.makeFinish(this.finishGeneric); + this.boundFinishGenericRead = this.makeFinish(this.finishGenericRead); this.boundFinishBusy = this.makeFinish(this.finishBusy); this.boundFinishDiskRead = this.makeFinish(this.finishDiskRead); this.boundFinishSPORead = this.makeFinish(this.finishSPORead); @@ -132,7 +133,7 @@ B5500IOUnit.BCLANSItoBIC = [ // Index by 8-bit BCL-as-ANSI to get 6-b 0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C]; // F0-FF /**************************************/ -B5500IOUnit.prototype.clear = function() { +B5500IOUnit.prototype.clear = function clear() { /* Initializes (and if necessary, creates) the I/O Unit state */ this.W = 0; // Memory buffer register @@ -187,7 +188,7 @@ B5500IOUnit.prototype.clear = function() { }; /**************************************/ -B5500IOUnit.prototype.clearD = function() { +B5500IOUnit.prototype.clearD = function clearD() { /* Clears the D-register and the exploded field variables used internally */ this.D = 0; @@ -209,7 +210,7 @@ B5500IOUnit.prototype.clearD = function() { }; /**************************************/ -B5500IOUnit.prototype.fetch = function(addr) { +B5500IOUnit.prototype.fetch = function fetch(addr) { /* Fetch a word from memory at address "addr" and leave it in the W register. Returns 1 if a memory access error occurred, 0 if no error */ var acc = this.accessor; // get a local reference to the accessor object @@ -231,7 +232,7 @@ B5500IOUnit.prototype.fetch = function(addr) { }; /**************************************/ -B5500IOUnit.prototype.store = function(addr) { +B5500IOUnit.prototype.store = function store(addr) { /* Store a word in memory at address "addr" from the W register. Returns 1 if a memory access error occurred, 0 if no error */ var acc = this.accessor; // get a local reference to the accessor object @@ -250,7 +251,7 @@ B5500IOUnit.prototype.store = function(addr) { }; /**************************************/ -B5500IOUnit.prototype.fetchBuffer = function(mode, words) { +B5500IOUnit.prototype.fetchBuffer = function fetchBuffer(mode, words) { /* Fetches words from memory starting at this.Daddress and coverts the BIC characters to ANSI or BCLANSI in this.buffer. "mode": 0=BCLANSI, 1=ANSI; "words": maximum number of words to transfer. At exit, updates this.Daddress @@ -300,7 +301,7 @@ B5500IOUnit.prototype.fetchBuffer = function(mode, words) { }; /**************************************/ -B5500IOUnit.prototype.fetchBufferWithGM = function(mode, words) { +B5500IOUnit.prototype.fetchBufferWithGM = function fetchBufferWithGM(mode, words) { /* Fetches words from memory starting at this.Daddress and coverts the BIC characters to ANSI or BCLANSI in this.buffer. "mode": 0=BCLANSI, 1=ANSI; "words": maximum number of words to transfer. The transfer can be terminated @@ -356,7 +357,7 @@ B5500IOUnit.prototype.fetchBufferWithGM = function(mode, words) { }; /**************************************/ -B5500IOUnit.prototype.storeBuffer = function(chars, offset, mode, words) { +B5500IOUnit.prototype.storeBuffer = function storeBuffer(chars, offset, mode, words) { /* Converts characters in this.buffer from ANSI or BCLANSI to BIC, assembles them into words, and stores the words into memory starting at this.Daddress. "chars": the number of characters to store, starting at "offset" in the buffer; @@ -428,7 +429,7 @@ B5500IOUnit.prototype.storeBuffer = function(chars, offset, mode, words) { }; /**************************************/ -B5500IOUnit.prototype.storeBufferWithGM = function(chars, offset, mode, words) { +B5500IOUnit.prototype.storeBufferWithGM = function storeBufferWithGM(chars, offset, mode, words) { /* Converts characters in this.buffer from ANSI to BIC, assembles them into words, and stores the words into memory starting at this.Daddress. "chars": the number of characters to store, starting at "offset" in the buffer; @@ -507,7 +508,7 @@ B5500IOUnit.prototype.storeBufferWithGM = function(chars, offset, mode, words) { }; /**************************************/ -B5500IOUnit.prototype.finish = function () { +B5500IOUnit.prototype.finish = function finish() { /* Called to finish an I/O operation on this I/O Unit. Constructs and stores the result descriptor, sets the appropriate I/O Finished interrupt in CC */ @@ -553,7 +554,7 @@ B5500IOUnit.prototype.finish = function () { }; /**************************************/ -B5500IOUnit.prototype.makeFinish = function(f) { +B5500IOUnit.prototype.makeFinish = function makeFinish(f) { /* Utility function to create a closure for I/O finish handlers */ var that = this; @@ -561,7 +562,7 @@ B5500IOUnit.prototype.makeFinish = function(f) { }; /**************************************/ -B5500IOUnit.prototype.decodeErrorMask = function(errorMask) { +B5500IOUnit.prototype.decodeErrorMask = function decodeErrorMask(errorMask) { /* Decodes the errorMask returned by the device drivers and ORs it into the D-register error bits */ @@ -575,7 +576,7 @@ B5500IOUnit.prototype.decodeErrorMask = function(errorMask) { }; /**************************************/ -B5500IOUnit.prototype.finishBusy = function(errorMask, length) { +B5500IOUnit.prototype.finishBusy = function finishBusy(errorMask, length) { /* Handles a generic I/O finish when no word-count update or input data transfer is needed, but leaves the unit marked as busy in CC. This is needed by device operations that have a separate completion signal, such as line @@ -587,7 +588,7 @@ B5500IOUnit.prototype.finishBusy = function(errorMask, length) { }; /**************************************/ -B5500IOUnit.prototype.finishGeneric = function(errorMask, length) { +B5500IOUnit.prototype.finishGeneric = function finishGeneric(errorMask, length) { /* Handles a generic I/O finish when no word-count update or input data transfer is needed. Can also be used to apply common error mask posting at the end of specialized finish handlers. Note that this turns off the @@ -599,7 +600,16 @@ B5500IOUnit.prototype.finishGeneric = function(errorMask, length) { }; /**************************************/ -B5500IOUnit.prototype.finishSPORead = function(errorMask, length) { +B5500IOUnit.prototype.finishGenericRead = function finishGenericRead(errorMask, length) { + /* Handles a generic I/O finish when input data transfer, and optionally, + word-count update, is needed. Note that this turns off the busyUnit mask bit in CC */ + + this.storeBuffer(length, 0, 1, (this.D23F ? this.DwordCount : 0x7FFF)); + this.finishGeneric(errorMask, length); +}; + +/**************************************/ +B5500IOUnit.prototype.finishSPORead = function finishSPORead(errorMask, length) { /* Handles I/O finish for a SPO keyboard input operation */ this.storeBufferWithGM(length, 0, 1, 0x7FFF); @@ -607,7 +617,7 @@ B5500IOUnit.prototype.finishSPORead = function(errorMask, length) { }; /**************************************/ -B5500IOUnit.prototype.finishDiskRead = function(errorMask, length) { +B5500IOUnit.prototype.finishDiskRead = function finishDiskRead(errorMask, length) { /* Handles I/O finish for a DFCU data read operation */ var segWords = Math.floor((length+7)/8); var memWords = (this.D23F ? this.DwordCount : segWords); @@ -620,7 +630,7 @@ B5500IOUnit.prototype.finishDiskRead = function(errorMask, length) { }; /**************************************/ -B5500IOUnit.prototype.initiateDiskIO = function(u) { +B5500IOUnit.prototype.initiateDiskIO = function initiateDiskIO(u) { /* Initiates an I/O to the Disk File Control Unit. The disk address is fetched from the first word of the memory area and converted to binary for the DFCU module. Read check and interrogate operations are determined from their respective IOD bits. If @@ -678,7 +688,7 @@ B5500IOUnit.prototype.initiateDiskIO = function(u) { }; /**************************************/ -B5500IOUnit.prototype.initiatePrinterIO = function(u) { +B5500IOUnit.prototype.initiatePrinterIO = function initiatePrinterIO(u) { /* Initiates an I/O to a Line Printer unit */ var addr = this.Daddress; // initial data transfer address var cc; // carriage control value to driver @@ -766,12 +776,22 @@ B5500IOUnit.prototype.forkIO = function forkIO() { // card #1 reader/punch case 10: - this.D30F = 1; this.finish(); // >>> temp until implemented <<< + if (this.D24F) { // CRA + u.read(this.boundFinishGenericRead, this.buffer, (this.D21F ? 160 : 80), this.D21F, 0); + } else { // CPA + this.D30F = 1; // >>> temp until CPA implemented <<< + this.finish(); + } break; // card #2 reader case 14: - this.D30F = 1; this.finish(); // >>> temp until implemented <<< + if (this.D24F) { + u.read(this.boundFinishGenericRead, this.buffer, (this.D21F ? 160 : 80), this.D21F, 0); + } else { + this.D30F = 1; // can't write to CRB, report as not ready + this.finish(); + } break; // SPO designate @@ -812,7 +832,7 @@ B5500IOUnit.prototype.forkIO = function forkIO() { }; /**************************************/ -B5500IOUnit.prototype.initiate = function() { +B5500IOUnit.prototype.initiate = function initiate() { /* Initiates an I/O operation on this I/O Unit. When P1 executes an IIO instruction, it calls the CentralControl.initiateIO() function, which selects an idle I/O Unit and calls this function for that unit. Thus, at entry we are still running on top of the @@ -842,7 +862,7 @@ B5500IOUnit.prototype.initiate = function() { }; /**************************************/ -B5500IOUnit.prototype.initiateLoad = function(cardLoadSelect, loadComplete) { +B5500IOUnit.prototype.initiateLoad = function initiateLoad(cardLoadSelect, loadComplete) { /* Initiates a hardware load operation on this I/O unit. "cardLoadSelect" is true if the load is to come from the card reader, otherwise it will come from sector 1 of DKA EU0. "loadComplete" is called on completion of the I/O. @@ -850,10 +870,11 @@ B5500IOUnit.prototype.initiateLoad = function(cardLoadSelect, loadComplete) { pressed and released. Since there is no IOD in memory, we must generate one in the D register and initiate the I/O intrinsically. Note that if the I/O has an error, the RD is not stored and the I/O finish interrupt is not set in CC */ + var chars; var index; var u; - function finishDiskLoad(errorMask, length) { + function finishLoad(errorMask, length) { var memWords = Math.floor((length+7)/8); this.storeBuffer(length, 0, this.D21F, memWords); @@ -870,22 +891,28 @@ B5500IOUnit.prototype.initiateLoad = function(cardLoadSelect, loadComplete) { this.clearD(); if (cardLoadSelect) { - alert("Card Load Select is not yet implemented"); - } else { - this.D = 0x0600009F8010; // unit 6, read, 63 segs, addr @00020 - this.Dunit = 6; // 6=DKA + this.D = 0x0A0004800010; // unit 10, read, binary mode, addr @00020 + this.Dunit = 10; // 10=CRA this.D24F = 1; // read + chars = 20*8; + } else { + this.D = 0x0600009F8010; // unit 6, read, alpha mode, 63 segs, addr @00020 + this.Dunit = 6; // 6=DKA + this.D21F = 0; // alpha mode this.LP = 63; // 63 sectors - this.Daddress = 0x10; // memory address @20 - this.busyUnit = index = B5500CentralControl.unitIndex[this.D24F & 1][this.Dunit & 0x1F]; - if (this.cc.testUnitBusy(index)) { - this.D32F = 1; // set unit busy error - } else if (!this.cc.testUnitReady(index)) { - this.D30F = 1; // set unit not-ready error - } else { - this.cc.setUnitBusy(index, 1); - u = this.cc.unit[index]; - u.read(this.makeFinish(finishDiskLoad), this.buffer, 63*240, this.D21F, 1); - } + chars = 63*240; + } + + this.D24F = 1; // read + this.Daddress = 0x10; // memory address @20 + this.busyUnit = index = B5500CentralControl.unitIndex[this.D24F & 1][this.Dunit & 0x1F]; + if (this.cc.testUnitBusy(index)) { + this.D32F = 1; // set unit busy error + } else if (!this.cc.testUnitReady(index)) { + this.D30F = 1; // set unit not-ready error + } else { + this.cc.setUnitBusy(index, 1); + u = this.cc.unit[index]; + u.read(this.makeFinish(finishLoad), this.buffer, chars, this.D21F, 1); } }; \ No newline at end of file diff --git a/emulator/B5500SystemConfiguration.js b/emulator/B5500SystemConfiguration.js index 0e2a4d2..0853924 100644 --- a/emulator/B5500SystemConfiguration.js +++ b/emulator/B5500SystemConfiguration.js @@ -41,7 +41,7 @@ var B5500SystemConfiguration = { SPO: true, // SPO keyboard/printer DKA: true, // Disk File Control A DKB: false, // Disk File Control B - CRA: false, // Card Reader A + CRA: true, // Card Reader A CRB: false, // Card Reader B CPA: false, // Card Punch A LPA: false, // Line Printer A diff --git a/webUI/B5500CardReader.css b/webUI/B5500CardReader.css new file mode 100644 index 0000000..e95cace --- /dev/null +++ b/webUI/B5500CardReader.css @@ -0,0 +1,99 @@ +/*********************************************************************** +* retro-b5500/emulator B5500CardReader.css +************************************************************************ +* Copyright (c) 2013, Nigel Williams and Paul Kimpel. +* Licensed under the MIT License, see http://www.opensource.org/licenses/mit-license.php +************************************************************************ +* B5500 emulator Card Reader web interface style sheet. +************************************************************************ +* 2013-06-09 P.Kimpel +* Original version, from B5500SPOUnit.css. +***********************************************************************/ + +BODY { + position: relative; + background-color: black; + margin: 4px} + +DIV#CRDiv { + position: relative; + background-color: #666; + width: 280px; + height: 112px; + border: 1px solid black; + border-radius: 8px; + padding: 0; + vertical-align: top} + +BUTTON.greenButton { + background-color: #060; + color: white; + font-family: Arial Rounded, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold; + width: 60px; + height: 40px; + border: 1px solid #DDD; + border-radius: 4px} + +BUTTON.blackButton { + background-color: black; + color: white; + font-family: Arial Rounded, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold; + width: 60px; + height: 40px; + border: 1px solid #DDD; + border-radius: 4px} + +BUTTON.redButton { + background-color: #900; + color: white; + font-family: Arial Rounded, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold; + width: 60px; + height: 40px; + border: 1px solid #DDD; + border-radius: 4px} + +BUTTON.greenLit { + background-color: green} + +BUTTON.redLit { + background-color: #F00} + +#CRNotReadyLight { + position: absolute; + top: 8px; + left: 8px} + +#CREOFBtn { + position: absolute; + top: 8px; + left: 76px} + +#CRStopBtn { + position: absolute; + top: 8px; + left: 144px} + +#CRStartBtn { + position: absolute; + top: 8px; + left: 212px;} + +#CRFileSelector { + position: absolute; + border: 1px solid white; + top: 56px; + left: 8px; + width: 120px} + +#CRProgressBar { + position: absolute; + border: 1px solid white; + top: 84px; + left: 8px; + width: 262px} diff --git a/webUI/B5500CardReader.html b/webUI/B5500CardReader.html new file mode 100644 index 0000000..5cb1dd5 --- /dev/null +++ b/webUI/B5500CardReader.html @@ -0,0 +1,26 @@ + +
+