var Memory = require('chip/memory'); class Bank{ constructor(mem){ this.__mem = [mem]; this.__idx = 0; } get mem(){return this.__mem[this.__idx];} get idx(){return this.__idx;} set idx(i){ if (i >= 0 && i < this.__mem.length) this.__idx = i; } addMemModule(mem){ if (!(mem instanceof Memory)) throw new ValueError("Only Memory instances can be added to MMC Banks."); if (this.__mem.length >= 4) throw new RangeError("Bank handling maximum memory modules."); if (this.__mem.length > 0 && mem.size !== this.__mem[0].size) throw new RangeError("Memory module does not match size of already connected memory modules on this bank."); this.__mem.push(mem); } } class MMC{ constructor(){ this.__banks = []; this.__addr = 0; this.__bnkidx = 0; } get size(){ return this.__banks.reduce((acc, b)=>{ acc += b.mem.size; }, 0); } get banks(){return this.__banks.length;} get address(){return this.__addr;} set address(a){ if (a >= 0 && a < this.size){ this.__addr = a; offset = 0; for (let b=0; b < this.__banks.length; b++){ if (a >= offset && a < offset + this.__banks[b].mem.size){ this.__bnkidx = b; this.__banks[b].mem.address = a - offset; break; } else { offset += this.__banks[b].mem.size; } } } } get byte(){return (this.__banks.length > 0) ? this.__banks[this.__bnkidx].mem.byte : -1;} set byte(b){ if (this.__banks.length > 0){ this.__banks[this.__bnkidx].mem.byte = b; } } connectMemory(mem, addroff){ addroff = (typeof(addroff) === 'number' && addroff >= 0) ? addroff : -1; if (addroff < 0 || addroff === this.size){ this.__banks.push(new Bank(mem)); } else { offset = 0; for (let b=0; b < this.__banks.length; b++){ if (addroff === offset){ if (this.__banks[b].mem.size !== mem.size) throw new RangeError("Memory modules assigned to the same bank must be the same byte size."); this.__banks[b].addMemModule(mem); offset = -1; break; } else { offset += this.__banks[b].mem.size; } } if (offset >= 0) throw new RangeError("Cannot align memory module to bank at address " + addroff); } return this; } mmSwitchCallback(){ return (function(byte){ // TODO: Check the bits to determin which bank and bank index is being switched on. }).bind(this); } } module.exports = MMC;