mirror of
https://github.com/pkimpel/retro-b5500.git
synced 2026-04-15 01:13:41 +00:00
1. Enable (finally!) functioning of P2, the second processor, in CentralControl and Processor. 2. Fix bugs in Character Mode syllables FAD, FSU: initial compare of operands was alphanumeric instead of numeric. 3. Fix bugs in Character Mode syllables TRN, TRZ, TBN: non-boundary destination words were not being fetched into the B register. 4. Enable configuration of additional tape drives (up to the maximum of 16). 5. Implement new flip-flop latching mechanism in CentralControl for use by B5500Console. 6. Optimize clearing of interrupts in Central Control. 7. Implement preliminary mechanism to allow P2 to be added to the configuration temporarily without altering B5500SystemConfiguration.js. 8. Implement new average slack and delay algorithms in Processor.schedule(). 9. Optimize some Character Mode syllables by substituting local variables for "this" properties. 10. Fix bugs in Processor single-precision divide syllables leaving the stack in an incorrect state after a divide by zero in Control State. 11. Further minor tweaks to performance throttling. 12. Optimize references to this.cc in Processor.run(). 13. Minor improvements to B5500MagTapeDrive: eliminate oscillation at load point, improve timing of rewind operations. 14. Implement build-release.cmd script to generate emulator release archive files. 15. Commit initial Mark-XVI TSSINT transcription from Fausto Saporito.
191 lines
7.8 KiB
JavaScript
191 lines
7.8 KiB
JavaScript
/***********************************************************************
|
|
* retro-b5500/emulator Register.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 generalized Register prototype.
|
|
* Maximum register width is 52 bits, since Javascript stores numbers
|
|
* internally as 64-bit IEEE 754 floating point numbers. All registers
|
|
* implement unsigned arithmetic modulo their bit width.
|
|
*
|
|
* Constructor spec members:
|
|
* width: size of the register in bits.
|
|
* value: initial register value (defaults to 0).
|
|
************************************************************************
|
|
* Modification Log.
|
|
* 2012-04-28 P.Kimpel
|
|
* Original version, from many frustrating attempts to wrap my head
|
|
* around this technique.
|
|
***********************************************************************/
|
|
|
|
define(["exports", "emu/compose"], function(exports, Compose) {
|
|
|
|
/***********************************************************************
|
|
* Register() supports binary registers up to 31 bits in width. Where
|
|
* applicable, this constructor is more efficient than LongRegister(),
|
|
* since it can use Javascript bitmask operators, which are limited to
|
|
* operating on 32-bit SIGNED integers.
|
|
***********************************************************************/
|
|
var Register = Compose(function(width, value) {
|
|
this.width = (width > this.maxBits ? this.maxBits : width);
|
|
this.mask = Register.mask2[this.width];
|
|
this.modulus = Register.pow2[this.width];
|
|
this.bits = (value ? value % this.modulus : 0); // initial register value
|
|
},{
|
|
maxBits: 31, // maximum register size
|
|
|
|
isolate: function(start, width) {
|
|
var ue = this.width-start; // upper power exponent
|
|
var le = ue-width; // lower power exponent
|
|
|
|
return (le > 0 ? this.bits >>> le : this.bits) & Register.mask2[width];
|
|
},
|
|
|
|
bit: function(bit) {
|
|
var e = this.width - bit - 1;
|
|
|
|
return (e > 0 ? this.bits >>> e : this.bits) & 1;
|
|
},
|
|
|
|
insert: function(start, width, value) {
|
|
var ue = this.width-start; // upper power exponent
|
|
var le = ue-width; // lower power exponent
|
|
|
|
this.bits = (this.bits & ((this.mask & ~Register.mask2[ue]) | Register.mask2[le])) |
|
|
((value & Register.mask2[width]) << le);
|
|
},
|
|
|
|
bitSet: function(bit) {
|
|
this.bits |= Register.pow2[bit];
|
|
},
|
|
|
|
bitReset: function(bit) {
|
|
this.bits &= ~Register.pow2[bit];
|
|
},
|
|
|
|
add: function(value) {
|
|
var temp = this.bits + value;
|
|
|
|
this.bits = (temp < 0 ? (this.modulus + temp) : temp) & this.mask;
|
|
},
|
|
|
|
sub: function(value) {
|
|
var temp = this.bits - value;
|
|
|
|
this.bits = (temp < 0 ? (this.modulus + temp) : temp) & this.mask;
|
|
},
|
|
|
|
set: function(value) {
|
|
this.bits = (value < 0 ? -value : value) & this.mask;
|
|
},
|
|
|
|
valueOf: function() {
|
|
return this.bits;
|
|
},
|
|
|
|
toString: function(radix) {
|
|
return this.bits.toString(radix)
|
|
}
|
|
});
|
|
|
|
Register.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];
|
|
|
|
Register.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];
|
|
|
|
|
|
/***********************************************************************
|
|
* LongRegister() supports binary registers up to 52 bits in width.
|
|
* Since Javascript bitmask operators only with up to 32 bits, this
|
|
* contructor must use div/mod operations to manipulate the bit fields.
|
|
***********************************************************************/
|
|
var LongRegister = Compose(Register, {
|
|
maxBits: 52, // maximum register size
|
|
|
|
isolate: function(start, width) {
|
|
var ue = this.width-start; // upper power exponent
|
|
var le = ue-width; // lower power exponent
|
|
|
|
return (le > 0 ? Math.floor(this.bits/Register.pow2[le]) : this.bits) % Register.pow2[width];
|
|
},
|
|
|
|
bit: function(bit) {
|
|
var e = this.width - bit - 1;
|
|
|
|
return (e > 0 ? Math.floor(this.bits/Register.pow2[e]) : this.bits) % 2;
|
|
},
|
|
|
|
insert: function(start, width, value) {
|
|
var ue = this.width-start; // upper power exponent
|
|
var le = ue-width; // lower power exponent
|
|
var tpower; // top portion power of 2
|
|
var bpower = Register.pow2[le]; // bottom portion power of 2
|
|
var top = 0; // unaffected top portion of register
|
|
var bottom = 0; // unaffected bottom portion of register
|
|
|
|
if (start > 0) {
|
|
tpower = Register.pow2[ue];
|
|
top = Math.floor(this.bits/tpower)*tpower;
|
|
}
|
|
if (le > 0) {
|
|
bottom = this.bits % bpower;
|
|
}
|
|
this.bits = (value % Register.pow2[width])*bpower + top + bottom;
|
|
},
|
|
|
|
bitSet: function(bit) {
|
|
this.insert(bit, 1, 1);
|
|
},
|
|
|
|
bitReset: function(bit) {
|
|
this.insert(bit, 1, 0);
|
|
},
|
|
|
|
add: function(value) {
|
|
var temp = this.bits + value;
|
|
|
|
this.bits = (temp < 0 ? (this.modulus + temp) : temp) % this.modulus;
|
|
},
|
|
|
|
sub: function(value) {
|
|
var temp = this.bits - value;
|
|
|
|
this.bits = (temp < 0 ? (this.modulus + temp) : temp) % this.modulus;
|
|
},
|
|
|
|
set: function(value) {
|
|
this.bits = (value < 0 ? -value : value) % this.modulus;
|
|
}
|
|
});
|
|
|
|
exports.Register = Register;
|
|
exports.LongRegister = LongRegister;
|
|
}); |