mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-21 23:30:58 +00:00
AddressDecoder
This commit is contained in:
parent
f649f0ec03
commit
dfbd584207
22
src/emu.js
22
src/emu.js
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 = {
|
||||
|
@ -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
33
test/cli/testdecoder.js
Normal 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));
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user