AddressDecoder

This commit is contained in:
Steven Hugg 2017-01-17 16:50:57 -05:00
parent f649f0ec03
commit dfbd584207
5 changed files with 89 additions and 91 deletions

View File

@ -643,3 +643,25 @@ function padBytes(data, len) {
r.mem.set(data);
return r.mem;
}
// TODO: better performance, check values
function AddressDecoder(table) {
var self = this;
function makeFunction(lo, hi) {
var s = "";
for (var i=0; i<table.length; i++) {
var entry = table[i];
var start = entry[0];
var end = entry[1];
var mask = entry[2];
var func = entry[3];
self['__fn'+i] = func;
s += "if (a>=" + start + " && a<="+end + "){";
s += "a&="+(mask?mask:0xffff)+";";
s += "return this.__fn"+i+"(a,v)&0xff;}\n";
}
s += "return 0;"; // TODO: noise()?
return new Function('a', 'v', s);
}
return makeFunction(0x0, 0xffff).bind(self);
}

View File

@ -150,72 +150,24 @@ var GalaxianPlatform = function(mainElement) {
oram = new RAM(0x100);
outlatches = new RAM(0x8);
membus = {
read: function(address) {
if (address < 0x4000) {
return (rom ? rom[address] : 0) & 0xff;
} else if (address < 0x4800) {
address &= 0x3ff;
return ram.mem[address] & 0xff;
} else if (address >= 0x5000 && address < 0x5800) {
address &= 0x3ff;
return vram.mem[address] & 0xff;
} else if (address >= 0x5800 && address < 0x6000) {
address &= 0xff;
return oram.mem[address] & 0xff;
} else if (address >= 0x6000 && address < 0x6800) {
address &= 0x7;
switch (address) {
case 0:
return inputs[0];
}
} else if (address >= 0x6800 && address < 0x7000) {
return inputs[1];
} else if (address >= 0x7000 && address < 0x7800) {
address &= 0x7;
switch (address) {
case 0:
return inputs[2];
}
} else if (address >= 0x7800 && address < 0x8000) {
watchdog_counter = INITIAL_WATCHDOG;
} else {
console.log("read", hex(address));
return 0;
}
},
write: function(address, value) {
//console.log("write", hex(address,4), hex(value,2));
if (address >= 0x4000 && address < 0x4800) {
address &= 0x3ff;
ram.mem[address] = value;
} else if (address >= 0x5000 && address < 0x5800) {
address &= 0x3ff;
vram.mem[address] = value;
} else if (address >= 0x5800 && address < 0x6000) {
address &= 0xff;
oram.mem[address] = value;
} else if (address >= 0x6000 && address < 0x6800) {
address &= 0x7;
outlatches.mem[address] = value;
} else if (address >= 0x6800 && address < 0x7000) {
address &= 0x7;
// TODO: sound
} else if (address >= 0x7000 && address < 0x7800) {
address &= 0x7;
switch (address) {
case 1:
interruptEnabled = value;
break;
case 4:
starsEnabled = value;
break;
}
} else if (address >= 0x7800 && address < 0x8000) {
// TODO: sound
} else {
console.log("write", hex(address), hex(value));
}
},
read: new AddressDecoder([
[0x0000, 0x3fff, 0, function(a) { return rom ? rom[a] : null; }],
[0x4000, 0x47ff, 0x3ff, function(a) { return ram.mem[a]; }],
[0x5000, 0x57ff, 0x3ff, function(a) { return vram.mem[a]; }],
[0x5800, 0x5fff, 0xff, function(a) { return oram.mem[a]; }],
[0x6000, 0x6000, 0, function(a) { return inputs[0]; }],
[0x6800, 0x6800, 0, function(a) { return inputs[1]; }],
[0x7000, 0x7000, 0, function(a) { return inputs[2]; }],
[0x7800, 0x7800, 0, function(a) { watchdog_counter = INITIAL_WATCHDOG; }],
]),
write: new AddressDecoder([
[0x4000, 0x47ff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
[0x5000, 0x57ff, 0x3ff, function(a,v) { vram.mem[a] = v; }],
[0x5800, 0x5fff, 0xff, function(a,v) { oram.mem[a] = v; }],
[0x6000, 0x67ff, 0x7, function(a,v) { outlatches.mem[a] = v; }],
[0x7001, 0x7001, 0, function(a,v) { interruptEnabled = v; }],
[0x7004, 0x7004, 0, function(a,v) { starsEnabled = v; }],
]),
isContended: function() { return false; },
};
iobus = {
@ -323,7 +275,7 @@ var GalaxianPlatform = function(mainElement) {
watchdog_counter = state.wdc;
interruptEnabled = state.ie;
starsEnabled = state.se;
frameCounter = fc;
frameCounter = state.fc;
inputs[0] = state.in0;
inputs[1] = state.in1;
inputs[2] = state.in2;
@ -356,7 +308,6 @@ var GalaxianPlatform = function(mainElement) {
this.pause = function() {
timer.stop();
audio.stop();
console.log(JSON.stringify(this.saveState()));
}
this.resume = function() {
timer.start();

View File

@ -46,29 +46,20 @@ var SpaceInvadersPlatform = function(mainElement) {
ram = new RAM(0x2000);
displayPCs = new Uint16Array(new ArrayBuffer(0x2000*2));
membus = {
read: function(address) {
if (address < 0x2000) {
return (rom ? rom[address] : 0) & 0xff;
} else {
address &= 0x1fff;
return ram.mem[address] & 0xff;
}
},
write: function(address, value) {
//console.log("write", hex(address,4), hex(value,2));
if (address >= 0x2000) {
address &= 0x1fff;
value &= 0xff;
ram.mem[address] = value;
if (address >= 0x400) {
// TODO: dirty flags
var ofs = (address - 0x400)*8;
for (var i=0; i<8; i++)
pixels[ofs+i] = (value & (1<<i)) ? PIXEL_ON : PIXEL_OFF;
displayPCs[address] = cpu.getPC(); // save program counter
}
}
},
read: new AddressDecoder([
[0x0000, 0x1fff, 0x1fff, function(a) { return rom ? rom[a] : 0; }],
[0x2000, 0x3fff, 0x1fff, function(a) { return ram.mem[a]; }],
]),
write: new AddressDecoder([
[0x2000, 0x23ff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
[0x2400, 0x3fff, 0x1fff, function(a,v) {
ram.mem[a] = v;
var ofs = (a - 0x400)<<3;
for (var i=0; i<8; i++)
pixels[ofs+i] = (v & (1<<i)) ? PIXEL_ON : PIXEL_OFF;
displayPCs[a] = cpu.getPC(); // save program counter
}],
]),
isContended: function() { return false; },
};
iobus = {

View File

@ -381,6 +381,7 @@ worker.onmessage = function(e) {
}
if (rom_changed || trace_pending_at_pc) {
// update editor annotations
// TODO: do incrementally for performance
editor.clearGutter("gutter-info");
editor.clearGutter("gutter-bytes");
editor.clearGutter("gutter-offset");

33
test/cli/testdecoder.js Normal file
View File

@ -0,0 +1,33 @@
var vm = require('vm');
var fs = require('fs');
var includeInThisContext = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
};
includeInThisContext("src/emu.js");
function assert(b, msg) {
if (!b) { throw new Error(msg); }
}
function assertEquals(a,b) {
assert(a==b, a + " != " + b);
}
describe('Test address decoder', function() {
it('Should work empty', function() {
var decoder = new AddressDecoder([]);
assertEquals(0, decoder(0x1234));
assertEquals(0, decoder(0x123456));
});
it('Should work with 1 range', function() {
var decoder = new AddressDecoder([
[0x1000, 0x7fff, 0xff, function(a) { return a+2; }]
]);
assertEquals(0, decoder(0xfff));
assertEquals(2, decoder(0x1000));
assertEquals(1, decoder(0x7fff));
assertEquals(0, decoder(0x8000));
});
});