Skip to content

Commit

Permalink
fix a bunch of bugs - mst roms work pretty well now
Browse files Browse the repository at this point in the history
  • Loading branch information
shicks committed Jan 10, 2016
1 parent f5677b8 commit 2244f4f
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 50 deletions.
26 changes: 13 additions & 13 deletions apu/apu.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@ export default class Apu {

this.frameCounter_ = 0;

mem.register(0x4015, {
get: this.getStatus.bind(this),
set: this.setStatus.bind(this),
});
// mem.register(0x4015, {
// get: this.getStatus.bind(this),
// set: this.setStatus.bind(this),
// });

this.status_ = 0;
// this.status_ = 0;
}

getStatus() {
// console.log('get status');
return this.status_;;
}
// getStatus() {
// // console.log('get status');
// return this.status_;
// }

setStatus(value) {
// console.log('set status: ' + value);
this.status_ = value;
}
// setStatus(value) {
// // console.log('set status: ' + value);
// this.status_ = value;
// }

clock() {
if (++this.frameCounter_ == FRAME_LIMIT) this.frameCounter_ = 0;
Expand Down
1 change: 1 addition & 0 deletions apu/lengthcounter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class LengthCounter {

clock() {
if (this.counter_ > 0) this.counter_--;
if (!this.counter_ && this.enabled_.get()) this.enabled_.set(false);
}

start() {
Expand Down
4 changes: 2 additions & 2 deletions audio/stepbufferwriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class StepBufferWriter {

// TODO(sdh): consider having the input always start at zero?

//console.log('WRITE: [' + steps.map(s=>`[${s[0]},${s[1]}]`) + ']');
// console.log('WRITE: [' + steps.map(s=>`[${s[0]},${s[1]}]`) + ']');
if (!steps.length) return new Promise(resolve => setTimeout(resolve, 50));

const samples = [];
Expand Down Expand Up @@ -83,7 +83,7 @@ export default class StepBufferWriter {
this.steps_.push([s, v]);
}
// now write the buffer.
//console.log(`Writing ${samples.length} samples`, samples);
// console.log(`Writing ${samples.length} samples`, samples);
return this.buffer_.write(samples);
}
}
Expand Down
18 changes: 13 additions & 5 deletions bankswitcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,21 @@ export default class BankSwitcher {
}
}


get pages() {
return this.pages_.length;
}


/**
* Loads the banks.
* @param {number} padding Padding, only the low 12 bits are used.
* @param {!Uint8Array} data
* @param {number} padding Padding, only the low 12 bits are used.
*/
load(padding, data) {
load(data, padding) {
padding &= 0xfff;
let bufferSize = padding + data.length;
if (bufferSize & 0xfff) bufferSize = (bufferSize & ~0xfff + 0x1000);
if (bufferSize & 0xfff) bufferSize = ((bufferSize & ~0xfff) + 0x1000);
let buffer;
if (data.length < bufferSize) {
buffer = new Uint8Array(bufferSize);
Expand All @@ -33,8 +38,9 @@ export default class BankSwitcher {
buffer = data;
}
for (let i = 0; i < (bufferSize >>> 12); i++) {
this.pages_[i] = new Uint8Array(buffer, i << 12, 0x1000);
this.pages_[i] = new Uint8Array(buffer.buffer, i << 12, 0x1000);
}
console.log('Loaded ' + this.pages_.length + ' pages from ' + data.length);
}


Expand All @@ -44,8 +50,10 @@ export default class BankSwitcher {
* @private
*/
swap_(bank, page) {
console.log('BANK SWITCH: ' + bank + ' <= ' + page);
if (!this.pages_.length) return; // bank switching not loaded/enabled
if (page >= this.pages_.length) throw new Error('invalid bank index');
this.mem_.loadBank(this.pages_[page], (bank & 0xf) << 12);
this.mem_.load(this.pages_[page], (bank & 0xf) << 12);
console.log(' ==> done');
}
}
43 changes: 26 additions & 17 deletions cpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default class Cpu {
var logdiv = document.getElementById('log');
this.log = logdiv ? msg => logdiv.textContent += msg + '\n' : msg => console.log(msg);
this.log = () => {};
this.log = msg => console.log(msg);
}

init() {
Expand All @@ -63,13 +64,13 @@ export default class Cpu {
if (--this.wait > 1) return;
if (this.opcode) {
// Actually execute the opcode.
try {
// try {
this.opcode.op.call(this);
} finally {
//if (window.msg) {
this.log(this.message);
//window.msg = false; }
}
// } finally {
// //if (window.msg) {
// this.log(this.message);
// //window.msg = false; }
// }

if (!this.opcode.extraCycles) this.wait = 0;
this.opcode = null;
Expand All @@ -89,7 +90,7 @@ export default class Cpu {
}
this.wait += this.opcode.cycles;
const lastPc = hex(this.PC - this.opcode.mode.bytes, 2);
this.message = `${lastPc}: ${this.opcode.format(this.operand)}`;
// this.message = `${lastPc}: ${this.opcode.format(this.operand)}`;
}


Expand Down Expand Up @@ -306,7 +307,8 @@ export default class Cpu {
}
// Return from Subroutine
RTS() { this.PC = this.pullWord();
this.message += '\t\t\tPC=' + hex(this.PC); }
// this.message += '\t\t\tPC=' + hex(this.PC);
}
// Return from Interrupt
RTI() {
this.SR = this.pullByte();
Expand Down Expand Up @@ -334,7 +336,14 @@ export default class Cpu {
// No Operation
NOP() {}
// Break: 1 -> B, 1 -> I
BRK() { this.B = this.I = 1; }
BRK() {
this.B = this.I = 1;

if (!this.mem_.getWord(this.PC) && !this.mem_.getWord(this.PC + 2)) {
throw new Error('Executing zeros!');
}

}


get MP() {
Expand All @@ -359,37 +368,37 @@ export default class Cpu {
if (addr < 0) throw new Error('Cannot write to immediate value.');
if (addr == null) {
this.A = value;
this.message += '\t\tA=' + hex(value);
// this.message += '\t\tA=' + hex(value);
} else {
this.mem_.set(addr, value);
this.message += '\t\t(' + hex(addr, 2) + ')=' + hex(value);
// this.message += '\t\t(' + hex(addr, 2) + ')=' + hex(value);
}
}

/** @param {number} value A one-byte integer. */
pushByte(value) {
this.mem_.set(this.SP--, value);
this.message += `\t\t(SP)=${hex(value)}, SP=${hex(this.SP,2)}`;
// this.message += `\t\t(SP)=${hex(value)}, SP=${hex(this.SP,2)}`;
}

/** @param {number} value A two-byte integer. */
pushWord(value) {
this.mem_.setWord(this.SP - 1, value);
this.SP -= 2;
this.message += `\t\t(SP)=${hex(value, 2)}, SP=${hex(this.SP,2)}`;
// this.message += `\t\t(SP)=${hex(value, 2)}, SP=${hex(this.SP,2)}`;
}

/** @return {number} */
pullByte(value) {
const result = this.mem_.get(++this.SP);
this.message += `\t\t${hex(result)}<-(SP), SP=${hex(this.SP,2)}`;
// this.message += `\t\t${hex(result)}<-(SP), SP=${hex(this.SP,2)}`;
return result;
}

/** @return {number} */
pullWord(value) {
const result = this.mem_.getWord((this.SP += 2) - 1);
this.message += `\t\t${hex(result, 2)}<-(SP), SP=${hex(this.SP,2)}`;
// this.message += `\t\t${hex(result, 2)}<-(SP), SP=${hex(this.SP,2)}`;
return result;
}

Expand All @@ -414,7 +423,7 @@ export default class Cpu {
cmpFlags_(reg, mem) {
this.C = !(this.S = reg < mem);
this.Z = reg == mem;
this.message += `\t\tR=${hex(reg)}, M=${hex(mem)}, C=${this.C?1:0}, S=${this.S?1:0}, Z=${this.Z?1:0}`;
// this.message += `\t\tR=${hex(reg)}, M=${hex(mem)}, C=${this.C?1:0}, S=${this.S?1:0}, Z=${this.Z?1:0}`;
}

/**
Expand All @@ -425,7 +434,7 @@ export default class Cpu {
* @private
*/
checkBranch_(addr) {
this.message += `\t\tPC=${hex(this.PC, 2)}->${hex(addr, 2)}`;
// this.message += `\t\tPC=${hex(this.PC, 2)}->${hex(addr, 2)}`;
this.wait = ((this.PC & 0xf000) == (addr & 0xf000)) ? 1 : 2;
return addr;
}
Expand Down
11 changes: 8 additions & 3 deletions mem.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default class Memory {
* @return {number}
*/
get(addr) {
return this.data8_[addr];
const reg = this.registers_[addr];
return reg ? reg.get() : this.data8_[addr];
}
Expand All @@ -36,6 +37,7 @@ export default class Memory {
if (opt_wrap) {
next = (next & opt_wrap) | (addr & ~opt_wrap);
}
return this.data8_[addr] | (this.data8_[next] << 8);
return this.get(addr) | (this.get(next) << 8);
}

Expand All @@ -45,9 +47,12 @@ export default class Memory {
* @param {number} value
*/
set(addr, value) {
const reg = this.registers_[addr];
if (reg) reg.set(value);
else this.data8_[addr] = value;
if (addr & 0xfff0 == 0x4000) {
console.log(`($${addr.toString(16)}) <- $${value.toString(16)}`);
}
// const reg = this.registers_[addr];
// if (reg) reg.set(value);
this.data8_[addr] = value;
this.call_(addr, value);
}

Expand Down
5 changes: 5 additions & 0 deletions nsf.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ export default class Nsf {
// Bank switching is enabled.
if (!banks) throw new Error('Bank switcher required for this ROM');
banks.load(this.data_, this.loadAddress_);
const fds = this.extraSupport_.indexOf('FDS') >= 0;
for (let i = 0; i < 8; i++) {
const addr = (i > 5 && fds) ? 0x5ff0 + i : 0x5ff8 + i;
mem.set(addr, this.bankInits_[i]);
}
} else {
// No bank switching, so load directly.
mem.load(this.data_, this.loadAddress_);
Expand Down
24 changes: 14 additions & 10 deletions nsfplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,24 @@ export default class NsfPlayer {
// dump the whole log...?

if (this.promise != promise) return;
for (let frameCycle = this.cyclesPerFrame; frameCycle >= 0; frameCycle--) {
if (frameCycle != frameCycle) throw new Error('NaN');
if (this.cpu.PC != 0xFFFF) this.cpu.clock();
this.apu.clock();
this.clock.tick();
}
if (this.cpu.PC == 0xFFFF) {
// console.log('New frame');
this.nsf.frame(this.cpu);
if (this.node.bufferTime() == 0) console.log('buffer underrun!');
for (let i = 0; i < 10; i++) {
for (let frameCycle = this.cyclesPerFrame; frameCycle >= 0; frameCycle--) {
if (frameCycle != frameCycle) throw new Error('NaN');
if (this.cpu.PC != 0xFFFF) this.cpu.clock();
this.apu.clock();
this.clock.tick();
}
if (this.cpu.PC == 0xFFFF) {
// console.log('New frame');
this.nsf.frame(this.cpu);
}
}
// Yield a single frame worth of steps
promise = this.promise =
this.writer.write(this.apu.steps(), this.clock.time)
.then(() => { setTimeout(() => this.play(promise), 1); });
//.then(() => this.play(promise));
.then(() => { setTimeout(() => this.play(promise), 0); });
// console.log('Yield data', data);
}

Expand Down

0 comments on commit 2244f4f

Please sign in to comment.