Fix acceleration, normalize heavily used signatures. (#18)

This commit is contained in:
Will Scullin 2019-12-29 19:13:59 -08:00 committed by GitHub
parent 680de778ee
commit f75a2fa962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 61 deletions

View File

@ -12,8 +12,6 @@ export function Apple2(options) {
renderedFrames: 0 renderedFrames: 0
}; };
var kHz = 1023;
var paused = false; var paused = false;
var DEBUG = false; var DEBUG = false;
@ -77,6 +75,7 @@ export function Apple2(options) {
var now, last = Date.now(); var now, last = Date.now();
var runFn = function() { var runFn = function() {
var kHz = io.getKHz();
now = Date.now(); now = Date.now();
var step = (now - last) * kHz, stepMax = kHz * interval; var step = (now - last) * kHz, stepMax = kHz * interval;

View File

@ -16,11 +16,11 @@ export default function Apple2IO(cpu, callbacks)
var _slot = []; var _slot = [];
var _auxRom = null; var _auxRom = null;
var _hz = 1023000; var _khz = 1023;
var _rate = 44000; var _rate = 44000;
var _sample_size = 4096; var _sample_size = 4096;
var _cycles_per_sample = _hz / _rate; var _cycles_per_sample;
var _buffer = []; var _buffer = [];
var _key = 0; var _key = 0;
@ -88,10 +88,15 @@ export default function Apple2IO(cpu, callbacks)
PADDLE3: 0x67, // bit 7: status of pdl-3 timer (read) PADDLE3: 0x67, // bit 7: status of pdl-3 timer (read)
PDLTRIG: 0x70, // trigger paddles PDLTRIG: 0x70, // trigger paddles
BANK: 0x73, // Back switched RAM card bank BANK: 0x73, // Back switched RAM card bank
ACCEL: 0x74, // CPU Speed control
SETIOUDIS:0x7E, // Enable double hires SETIOUDIS:0x7E, // Enable double hires
CLRIOUDIS:0x7F // Disable double hires CLRIOUDIS:0x7F // Disable double hires
}; };
function init() {
_calcSampleRate();
}
function _debug() { function _debug() {
// debug.apply(this, arguments); // debug.apply(this, arguments);
} }
@ -111,6 +116,17 @@ export default function Apple2IO(cpu, callbacks)
} }
} }
function _calcSampleRate() {
_cycles_per_sample = _khz * 1000 / _rate;
}
function _updateKHz(khz) {
_khz = khz;
_calcSampleRate();
}
init();
function _access(off, val) { function _access(off, val) {
var result = 0; var result = 0;
var now = cpu.cycles(); var now = cpu.cycles();
@ -271,6 +287,11 @@ export default function Apple2IO(cpu, callbacks)
case LOC.PDLTRIG: case LOC.PDLTRIG:
_trigger = cpu.cycles(); _trigger = cpu.cycles();
break; break;
case LOC.ACCEL:
if (val !== undefined) {
_updateKHz(val & 0x01 ? 1023 : 4096);
}
break;
case LOC.RDDHIRES: case LOC.RDDHIRES:
if (callbacks.isDoubleHires) { if (callbacks.isDoubleHires) {
result = callbacks.isDoubleHires() ? 0x80 : 0x0; result = callbacks.isDoubleHires() ? 0x80 : 0x0;
@ -353,7 +374,7 @@ export default function Apple2IO(cpu, callbacks)
switch (page) { switch (page) {
case 0xc0: case 0xc0:
result = this.ioSwitch(off); result = this.ioSwitch(off, undefined);
break; break;
case 0xc1: case 0xc1:
case 0xc2: case 0xc2:
@ -448,14 +469,12 @@ export default function Apple2IO(cpu, callbacks)
_paddle[p] = v; _paddle[p] = v;
}, },
updateHz: function apple2io_updateHz(hz) { updateKHz: function apple2io_updateKHz(khz) {
_hz = hz; _updateKHz(khz);
_cycles_per_sample = _hz / _rate;
}, },
getHz: function apple2io_updateHz() { getKHz: function apple2io_updateKHz() {
return _hz; return _khz;
}, },
setKeyBuffer: function apple2io_setKeyBuffer(buffer) { setKeyBuffer: function apple2io_setKeyBuffer(buffer) {
@ -474,7 +493,7 @@ export default function Apple2IO(cpu, callbacks)
sampleRate: function sampleRate(rate) { sampleRate: function sampleRate(rate) {
_rate = rate; _rate = rate;
_cycles_per_sample = _hz / _rate; _calcSampleRate();
}, },
tick: function tick() { tick: function tick() {

View File

@ -121,7 +121,7 @@ export default function ApplesoftDump(mem)
var page = addr >> 8, var page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
return _mem.read(page, off, true); return _mem.read(page, off);
} }
function readWord(addr) { function readWord(addr) {

View File

@ -203,12 +203,12 @@ export default function LanguageCard(io, rom) {
ioSwitch: function(off, val) { ioSwitch: function(off, val) {
return _access(off, val); return _access(off, val);
}, },
read: function(page, off, dbg) { read: function(page, off) {
var result = 0; var result = 0;
if (page < 0xe0) { if (page < 0xe0) {
result = _read1.read(page, off, dbg); result = _read1.read(page, off);
} else { } else {
result = _read2.read(page, off, dbg); result = _read2.read(page, off);
} }
return result; return result;
}, },

View File

@ -170,33 +170,38 @@ export default function CPU6502(options)
return testNZ((a + 0xff) & 0xff); return testNZ((a + 0xff) & 0xff);
} }
function readBytePC(dbg) { function readBytePC() {
var addr = (pc++) & 0xffff, var addr = pc,
page = addr >> 8, page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
var result = readPages[page].read(page, off, dbg); var result = readPages[page].read(page, off);
pc = (pc + 1) & 0xffff;
if (!dbg) {
cycles++; cycles++;
}
return result; return result;
} }
function readByte(addr, dbg) { function readByte(addr) {
var page = addr >> 8, var page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
var result = readPages[page].read(page, off, dbg); var result = readPages[page].read(page, off);
if (!dbg) {
cycles++; cycles++;
}
return result; return result;
} }
function readByteDebug(addr) {
var page = addr >> 8,
off = addr & 0xff;
return readPages[page].read(page, off);
}
function writeByte(addr, val) { function writeByte(addr, val) {
var page = addr >> 8, var page = addr >> 8,
off = addr & 0xff; off = addr & 0xff;
@ -206,19 +211,23 @@ export default function CPU6502(options)
cycles++; cycles++;
} }
function readWord(addr, dbg) { function readWord(addr) {
return readByte(addr, dbg) | (readByte(addr + 1, dbg) << 8); return readByte(addr) | (readByte(addr + 1) << 8);
} }
function readWordPC(dbg) { function readWordDebug(addr) {
return readBytePC(dbg) | (readBytePC(dbg) << 8); return readByteDebug(addr) | (readByteDebug(addr + 1) << 8);
} }
function readZPWord(addr, dbg) { function readWordPC() {
return readBytePC() | (readBytePC() << 8);
}
function readZPWord(addr) {
var lsb, msb; var lsb, msb;
lsb = readByte(addr & 0xff, dbg); lsb = readByte(addr & 0xff);
msb = readByte((addr + 1) & 0xff, dbg); msb = readByte((addr + 1) & 0xff);
return (msb << 8) | lsb; return (msb << 8) | lsb;
} }
@ -1310,17 +1319,17 @@ export default function CPU6502(options)
case modes.implied: case modes.implied:
break; break;
case modes.immediate: case modes.immediate:
result = '#' + toHexOrSymbol(readByte(addr, true)); result = '#' + toHexOrSymbol(readByteDebug(addr));
break; break;
case modes.absolute: case modes.absolute:
result = '' + toHexOrSymbol(readWord(addr, true), 4); result = '' + toHexOrSymbol(readWordDebug(addr), 4);
break; break;
case modes.zeroPage: case modes.zeroPage:
result = '' + toHexOrSymbol(readByte(addr, true)); result = '' + toHexOrSymbol(readByteDebug(addr));
break; break;
case modes.relative: case modes.relative:
{ {
off = readByte(addr, true); off = readByteDebug(addr);
if (off > 127) { if (off > 127) {
off -= 256; off -= 256;
} }
@ -1329,38 +1338,38 @@ export default function CPU6502(options)
} }
break; break;
case modes.absoluteX: case modes.absoluteX:
result = '' + toHexOrSymbol(readWord(addr, true), 4) + ',X'; result = '' + toHexOrSymbol(readWordDebug(addr), 4) + ',X';
break; break;
case modes.absoluteY: case modes.absoluteY:
result = '' + toHexOrSymbol(readWord(addr, true), 4) + ',Y'; result = '' + toHexOrSymbol(readWordDebug(addr), 4) + ',Y';
break; break;
case modes.zeroPageX: case modes.zeroPageX:
result = '' + toHexOrSymbol(readByte(addr, true)) + ',X'; result = '' + toHexOrSymbol(readByteDebug(addr)) + ',X';
break; break;
case modes.zeroPageY: case modes.zeroPageY:
result = '' + toHexOrSymbol(readByte(addr, true)) + ',Y'; result = '' + toHexOrSymbol(readByteDebug(addr)) + ',Y';
break; break;
case modes.absoluteIndirect: case modes.absoluteIndirect:
result = '(' + toHexOrSymbol(readWord(addr, true), 4) + ')'; result = '(' + toHexOrSymbol(readWordDebug(addr), 4) + ')';
break; break;
case modes.zeroPageXIndirect: case modes.zeroPageXIndirect:
result = '(' + toHexOrSymbol(readByte(addr, true)) + ',X)'; result = '(' + toHexOrSymbol(readByteDebug(addr)) + ',X)';
break; break;
case modes.zeroPageIndirectY: case modes.zeroPageIndirectY:
result = '(' + toHexOrSymbol(readByte(addr, true)) + '),Y'; result = '(' + toHexOrSymbol(readByteDebug(addr)) + '),Y';
break; break;
case modes.accumulator: case modes.accumulator:
result = 'A'; result = 'A';
break; break;
case modes.zeroPageIndirect: case modes.zeroPageIndirect:
result = '(' + toHexOrSymbol(readByte(addr, true)) + ')'; result = '(' + toHexOrSymbol(readByteDebug(addr)) + ')';
break; break;
case modes.absoluteXIndirect: case modes.absoluteXIndirect:
result = '(' + toHexOrSymbol(readWord(addr, true), 4) + ',X)'; result = '(' + toHexOrSymbol(readWordDebug(addr), 4) + ',X)';
break; break;
case modes.zeroPage_relative: case modes.zeroPage_relative:
val = readByte(addr, true); val = readByteDebug(addr);
off = readByte(addr + 1, true); off = readByteDebug(addr + 1);
if (off > 127) { if (off > 127) {
off -= 256; off -= 256;
} }
@ -1534,7 +1543,7 @@ export default function CPU6502(options)
for (idx = 0; idx < 16; idx++) { for (idx = 0; idx < 16; idx++) {
result += toHex(page) + toHex(idx << 4) + ': '; result += toHex(page) + toHex(idx << 4) + ': ';
for (jdx = 0; jdx < 16; jdx++) { for (jdx = 0; jdx < 16; jdx++) {
b = readByte(page * 256 + idx * 16 + jdx, true); b = readByteDebug(page * 256 + idx * 16 + jdx);
result += toHex(b) + ' '; result += toHex(b) + ' ';
} }
result += ' '; result += ' ';
@ -1618,7 +1627,7 @@ export default function CPU6502(options)
}, },
read: function(page, off) { read: function(page, off) {
return readPages[page].read(page, off, false); return readPages[page].read(page, off);
}, },
write: function(page, off, val) { write: function(page, off, val) {

View File

@ -153,7 +153,7 @@ export default function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom)
if (off in locs) { if (off in locs) {
result = _access(off); result = _access(off);
} else { } else {
result = io.ioSwitch(off); result = io.ioSwitch(off, undefined);
} }
return result; return result;
}, },
@ -656,8 +656,8 @@ export default function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom)
vm.reset(); vm.reset();
io.reset(); io.reset();
}, },
read: function mmu_read(page, off, debug) { read: function mmu_read(page, off) {
return _readPages[page].read(page, off, debug); return _readPages[page].read(page, off);
}, },
write: function mmu_write(page, off, val) { write: function mmu_write(page, off, val) {
_writePages[page].write(page, off, val); _writePages[page].write(page, off, val);

View File

@ -13,8 +13,6 @@ import ApplesoftCompiler from '../applesoft/compiler';
import { debug, gup, hup } from '../util'; import { debug, gup, hup } from '../util';
import Prefs from '../prefs'; import Prefs from '../prefs';
var kHz = 1023;
var focused = false; var focused = false;
var startTime = Date.now(); var startTime = Date.now();
var lastCycles = 0; var lastCycles = 0;
@ -149,8 +147,8 @@ export function loadAjax(drive, url) {
initGamepad(data.gamepad); initGamepad(data.gamepad);
MicroModal.close('loading-modal'); MicroModal.close('loading-modal');
}).catch(function(error) { }).catch(function(error) {
window.alert(error.message);
MicroModal.close('loading-modal'); MicroModal.close('loading-modal');
window.alert(error.message);
}); });
} }
@ -494,7 +492,7 @@ function processHash(hash) {
} else { } else {
doLoadHTTP(idx + 1, file); doLoadHTTP(idx + 1, file);
} }
} else { } else if (file) {
loadAjax(idx + 1, 'json/disks/' + file + '.json'); loadAjax(idx + 1, 'json/disks/' + file + '.json');
} }
} }
@ -593,8 +591,8 @@ export function updateScreen() {
export function updateCPU() { export function updateCPU() {
var accelerated = document.querySelector('#accelerator_toggle').checked; var accelerated = document.querySelector('#accelerator_toggle').checked;
kHz = accelerated ? 4092 : 1023; var kHz = accelerated ? 4092 : 1023;
io.updateHz(kHz * 1000); io.updateKHz(kHz);
} }
export function updateUI() { export function updateUI() {

View File

@ -19,7 +19,7 @@ export default function Tape(io) {
return { return {
doLoadLocalTape: function(file, done) { doLoadLocalTape: function(file, done) {
var kHz = io.getHz() / 1000; var kHz = io.getKHz();
// Audio Buffer Source // Audio Buffer Source
var context; var context;