'use strict'; const { Op, AddrMode} = require('./enum.js'); function mod(a, N) { const A = a % N; if (A < 0) { return A + N; } else { return A; } } class Range { constructor(start, end, coresize) { this.start = start; this.end = end; this.coresize = coresize; } // thanks to https://fgiesen.wordpress.com/2015/09/24/intervals-in-modular-arithmetic/ // c: contains(n) { return mod(n - this.start, this.coresize) <= mod(this.end - this.start, this.coresize); } overlaps(other) { return ( this.contains(other.start) || other.contains(this.start) ); } } function randomRange(coresize, length) { const start = Math.floor(Math.random() * coresize); const end = mod(start + length - 1, coresize); return new Range(start, end, coresize); } class Core { constructor(size) { this.data = new Array(size); // initialize core to all DAT 0, 0 for (let i=0; i r.overlaps(range)) .reduce((acc, overlap) => acc || overlap, false) ); return this.getRanges(lengths.slice(1), [...ranges, range]); } normalize(pc, value) { return mod((pc + value), this.data.length); } getLocation(pc, address) { switch(address.mode) { case AddrMode.Immediate: throw "Cannot get location from immediate-mode address"; case AddrMode.Direct: return this.normalize(pc, address.value); case AddrMode.Indirect: { let loc = this.normalize(pc, address.value); let b = this.data[loc].b.value; return this.normalize(pc, b); } case AddrMode.Predecrement: { let loc = this.normalize(pc, address.value); this.data[loc].b.value -= 1; let b = this.data[loc].b.value; return this.normalize(pc, b); } default: throw `Invalid addressing mode "${address.mode}"`; } } getValue(pc, address) { const index = this.getLocation(pc, address); return this.data[index]; } } exports.mod = mod; exports.Range = Range; exports.Core = Core;