mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
Fix acceleration, normalize heavily used signatures. (#18)
This commit is contained in:
parent
680de778ee
commit
f75a2fa962
@ -12,8 +12,6 @@ export function Apple2(options) {
|
||||
renderedFrames: 0
|
||||
};
|
||||
|
||||
var kHz = 1023;
|
||||
|
||||
var paused = false;
|
||||
|
||||
var DEBUG = false;
|
||||
@ -77,6 +75,7 @@ export function Apple2(options) {
|
||||
|
||||
var now, last = Date.now();
|
||||
var runFn = function() {
|
||||
var kHz = io.getKHz();
|
||||
now = Date.now();
|
||||
|
||||
var step = (now - last) * kHz, stepMax = kHz * interval;
|
||||
|
@ -16,11 +16,11 @@ export default function Apple2IO(cpu, callbacks)
|
||||
var _slot = [];
|
||||
var _auxRom = null;
|
||||
|
||||
var _hz = 1023000;
|
||||
var _khz = 1023;
|
||||
var _rate = 44000;
|
||||
var _sample_size = 4096;
|
||||
|
||||
var _cycles_per_sample = _hz / _rate;
|
||||
var _cycles_per_sample;
|
||||
|
||||
var _buffer = [];
|
||||
var _key = 0;
|
||||
@ -88,10 +88,15 @@ export default function Apple2IO(cpu, callbacks)
|
||||
PADDLE3: 0x67, // bit 7: status of pdl-3 timer (read)
|
||||
PDLTRIG: 0x70, // trigger paddles
|
||||
BANK: 0x73, // Back switched RAM card bank
|
||||
ACCEL: 0x74, // CPU Speed control
|
||||
SETIOUDIS:0x7E, // Enable double hires
|
||||
CLRIOUDIS:0x7F // Disable double hires
|
||||
};
|
||||
|
||||
function init() {
|
||||
_calcSampleRate();
|
||||
}
|
||||
|
||||
function _debug() {
|
||||
// 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) {
|
||||
var result = 0;
|
||||
var now = cpu.cycles();
|
||||
@ -271,6 +287,11 @@ export default function Apple2IO(cpu, callbacks)
|
||||
case LOC.PDLTRIG:
|
||||
_trigger = cpu.cycles();
|
||||
break;
|
||||
case LOC.ACCEL:
|
||||
if (val !== undefined) {
|
||||
_updateKHz(val & 0x01 ? 1023 : 4096);
|
||||
}
|
||||
break;
|
||||
case LOC.RDDHIRES:
|
||||
if (callbacks.isDoubleHires) {
|
||||
result = callbacks.isDoubleHires() ? 0x80 : 0x0;
|
||||
@ -353,7 +374,7 @@ export default function Apple2IO(cpu, callbacks)
|
||||
|
||||
switch (page) {
|
||||
case 0xc0:
|
||||
result = this.ioSwitch(off);
|
||||
result = this.ioSwitch(off, undefined);
|
||||
break;
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
@ -448,14 +469,12 @@ export default function Apple2IO(cpu, callbacks)
|
||||
_paddle[p] = v;
|
||||
},
|
||||
|
||||
updateHz: function apple2io_updateHz(hz) {
|
||||
_hz = hz;
|
||||
|
||||
_cycles_per_sample = _hz / _rate;
|
||||
updateKHz: function apple2io_updateKHz(khz) {
|
||||
_updateKHz(khz);
|
||||
},
|
||||
|
||||
getHz: function apple2io_updateHz() {
|
||||
return _hz;
|
||||
getKHz: function apple2io_updateKHz() {
|
||||
return _khz;
|
||||
},
|
||||
|
||||
setKeyBuffer: function apple2io_setKeyBuffer(buffer) {
|
||||
@ -474,7 +493,7 @@ export default function Apple2IO(cpu, callbacks)
|
||||
|
||||
sampleRate: function sampleRate(rate) {
|
||||
_rate = rate;
|
||||
_cycles_per_sample = _hz / _rate;
|
||||
_calcSampleRate();
|
||||
},
|
||||
|
||||
tick: function tick() {
|
||||
|
@ -121,7 +121,7 @@ export default function ApplesoftDump(mem)
|
||||
var page = addr >> 8,
|
||||
off = addr & 0xff;
|
||||
|
||||
return _mem.read(page, off, true);
|
||||
return _mem.read(page, off);
|
||||
}
|
||||
|
||||
function readWord(addr) {
|
||||
|
@ -203,12 +203,12 @@ export default function LanguageCard(io, rom) {
|
||||
ioSwitch: function(off, val) {
|
||||
return _access(off, val);
|
||||
},
|
||||
read: function(page, off, dbg) {
|
||||
read: function(page, off) {
|
||||
var result = 0;
|
||||
if (page < 0xe0) {
|
||||
result = _read1.read(page, off, dbg);
|
||||
result = _read1.read(page, off);
|
||||
} else {
|
||||
result = _read2.read(page, off, dbg);
|
||||
result = _read2.read(page, off);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
@ -170,33 +170,38 @@ export default function CPU6502(options)
|
||||
return testNZ((a + 0xff) & 0xff);
|
||||
}
|
||||
|
||||
function readBytePC(dbg) {
|
||||
var addr = (pc++) & 0xffff,
|
||||
function readBytePC() {
|
||||
var addr = pc,
|
||||
page = addr >> 8,
|
||||
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++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function readByte(addr, dbg) {
|
||||
function readByte(addr) {
|
||||
var page = addr >> 8,
|
||||
off = addr & 0xff;
|
||||
|
||||
var result = readPages[page].read(page, off, dbg);
|
||||
var result = readPages[page].read(page, off);
|
||||
|
||||
if (!dbg) {
|
||||
cycles++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function readByteDebug(addr) {
|
||||
var page = addr >> 8,
|
||||
off = addr & 0xff;
|
||||
|
||||
return readPages[page].read(page, off);
|
||||
}
|
||||
|
||||
function writeByte(addr, val) {
|
||||
var page = addr >> 8,
|
||||
off = addr & 0xff;
|
||||
@ -206,19 +211,23 @@ export default function CPU6502(options)
|
||||
cycles++;
|
||||
}
|
||||
|
||||
function readWord(addr, dbg) {
|
||||
return readByte(addr, dbg) | (readByte(addr + 1, dbg) << 8);
|
||||
function readWord(addr) {
|
||||
return readByte(addr) | (readByte(addr + 1) << 8);
|
||||
}
|
||||
|
||||
function readWordPC(dbg) {
|
||||
return readBytePC(dbg) | (readBytePC(dbg) << 8);
|
||||
function readWordDebug(addr) {
|
||||
return readByteDebug(addr) | (readByteDebug(addr + 1) << 8);
|
||||
}
|
||||
|
||||
function readZPWord(addr, dbg) {
|
||||
function readWordPC() {
|
||||
return readBytePC() | (readBytePC() << 8);
|
||||
}
|
||||
|
||||
function readZPWord(addr) {
|
||||
var lsb, msb;
|
||||
|
||||
lsb = readByte(addr & 0xff, dbg);
|
||||
msb = readByte((addr + 1) & 0xff, dbg);
|
||||
lsb = readByte(addr & 0xff);
|
||||
msb = readByte((addr + 1) & 0xff);
|
||||
|
||||
return (msb << 8) | lsb;
|
||||
}
|
||||
@ -1310,17 +1319,17 @@ export default function CPU6502(options)
|
||||
case modes.implied:
|
||||
break;
|
||||
case modes.immediate:
|
||||
result = '#' + toHexOrSymbol(readByte(addr, true));
|
||||
result = '#' + toHexOrSymbol(readByteDebug(addr));
|
||||
break;
|
||||
case modes.absolute:
|
||||
result = '' + toHexOrSymbol(readWord(addr, true), 4);
|
||||
result = '' + toHexOrSymbol(readWordDebug(addr), 4);
|
||||
break;
|
||||
case modes.zeroPage:
|
||||
result = '' + toHexOrSymbol(readByte(addr, true));
|
||||
result = '' + toHexOrSymbol(readByteDebug(addr));
|
||||
break;
|
||||
case modes.relative:
|
||||
{
|
||||
off = readByte(addr, true);
|
||||
off = readByteDebug(addr);
|
||||
if (off > 127) {
|
||||
off -= 256;
|
||||
}
|
||||
@ -1329,38 +1338,38 @@ export default function CPU6502(options)
|
||||
}
|
||||
break;
|
||||
case modes.absoluteX:
|
||||
result = '' + toHexOrSymbol(readWord(addr, true), 4) + ',X';
|
||||
result = '' + toHexOrSymbol(readWordDebug(addr), 4) + ',X';
|
||||
break;
|
||||
case modes.absoluteY:
|
||||
result = '' + toHexOrSymbol(readWord(addr, true), 4) + ',Y';
|
||||
result = '' + toHexOrSymbol(readWordDebug(addr), 4) + ',Y';
|
||||
break;
|
||||
case modes.zeroPageX:
|
||||
result = '' + toHexOrSymbol(readByte(addr, true)) + ',X';
|
||||
result = '' + toHexOrSymbol(readByteDebug(addr)) + ',X';
|
||||
break;
|
||||
case modes.zeroPageY:
|
||||
result = '' + toHexOrSymbol(readByte(addr, true)) + ',Y';
|
||||
result = '' + toHexOrSymbol(readByteDebug(addr)) + ',Y';
|
||||
break;
|
||||
case modes.absoluteIndirect:
|
||||
result = '(' + toHexOrSymbol(readWord(addr, true), 4) + ')';
|
||||
result = '(' + toHexOrSymbol(readWordDebug(addr), 4) + ')';
|
||||
break;
|
||||
case modes.zeroPageXIndirect:
|
||||
result = '(' + toHexOrSymbol(readByte(addr, true)) + ',X)';
|
||||
result = '(' + toHexOrSymbol(readByteDebug(addr)) + ',X)';
|
||||
break;
|
||||
case modes.zeroPageIndirectY:
|
||||
result = '(' + toHexOrSymbol(readByte(addr, true)) + '),Y';
|
||||
result = '(' + toHexOrSymbol(readByteDebug(addr)) + '),Y';
|
||||
break;
|
||||
case modes.accumulator:
|
||||
result = 'A';
|
||||
break;
|
||||
case modes.zeroPageIndirect:
|
||||
result = '(' + toHexOrSymbol(readByte(addr, true)) + ')';
|
||||
result = '(' + toHexOrSymbol(readByteDebug(addr)) + ')';
|
||||
break;
|
||||
case modes.absoluteXIndirect:
|
||||
result = '(' + toHexOrSymbol(readWord(addr, true), 4) + ',X)';
|
||||
result = '(' + toHexOrSymbol(readWordDebug(addr), 4) + ',X)';
|
||||
break;
|
||||
case modes.zeroPage_relative:
|
||||
val = readByte(addr, true);
|
||||
off = readByte(addr + 1, true);
|
||||
val = readByteDebug(addr);
|
||||
off = readByteDebug(addr + 1);
|
||||
if (off > 127) {
|
||||
off -= 256;
|
||||
}
|
||||
@ -1534,7 +1543,7 @@ export default function CPU6502(options)
|
||||
for (idx = 0; idx < 16; idx++) {
|
||||
result += toHex(page) + toHex(idx << 4) + ': ';
|
||||
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 += ' ';
|
||||
@ -1618,7 +1627,7 @@ export default function CPU6502(options)
|
||||
},
|
||||
|
||||
read: function(page, off) {
|
||||
return readPages[page].read(page, off, false);
|
||||
return readPages[page].read(page, off);
|
||||
},
|
||||
|
||||
write: function(page, off, val) {
|
||||
|
@ -153,7 +153,7 @@ export default function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom)
|
||||
if (off in locs) {
|
||||
result = _access(off);
|
||||
} else {
|
||||
result = io.ioSwitch(off);
|
||||
result = io.ioSwitch(off, undefined);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
@ -656,8 +656,8 @@ export default function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom)
|
||||
vm.reset();
|
||||
io.reset();
|
||||
},
|
||||
read: function mmu_read(page, off, debug) {
|
||||
return _readPages[page].read(page, off, debug);
|
||||
read: function mmu_read(page, off) {
|
||||
return _readPages[page].read(page, off);
|
||||
},
|
||||
write: function mmu_write(page, off, val) {
|
||||
_writePages[page].write(page, off, val);
|
||||
|
@ -13,8 +13,6 @@ import ApplesoftCompiler from '../applesoft/compiler';
|
||||
import { debug, gup, hup } from '../util';
|
||||
import Prefs from '../prefs';
|
||||
|
||||
var kHz = 1023;
|
||||
|
||||
var focused = false;
|
||||
var startTime = Date.now();
|
||||
var lastCycles = 0;
|
||||
@ -149,8 +147,8 @@ export function loadAjax(drive, url) {
|
||||
initGamepad(data.gamepad);
|
||||
MicroModal.close('loading-modal');
|
||||
}).catch(function(error) {
|
||||
window.alert(error.message);
|
||||
MicroModal.close('loading-modal');
|
||||
window.alert(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
@ -494,7 +492,7 @@ function processHash(hash) {
|
||||
} else {
|
||||
doLoadHTTP(idx + 1, file);
|
||||
}
|
||||
} else {
|
||||
} else if (file) {
|
||||
loadAjax(idx + 1, 'json/disks/' + file + '.json');
|
||||
}
|
||||
}
|
||||
@ -593,8 +591,8 @@ export function updateScreen() {
|
||||
|
||||
export function updateCPU() {
|
||||
var accelerated = document.querySelector('#accelerator_toggle').checked;
|
||||
kHz = accelerated ? 4092 : 1023;
|
||||
io.updateHz(kHz * 1000);
|
||||
var kHz = accelerated ? 4092 : 1023;
|
||||
io.updateKHz(kHz);
|
||||
}
|
||||
|
||||
export function updateUI() {
|
||||
|
@ -19,7 +19,7 @@ export default function Tape(io) {
|
||||
|
||||
return {
|
||||
doLoadLocalTape: function(file, done) {
|
||||
var kHz = io.getHz() / 1000;
|
||||
var kHz = io.getKHz();
|
||||
|
||||
// Audio Buffer Source
|
||||
var context;
|
||||
|
Loading…
Reference in New Issue
Block a user