mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
lint
This commit is contained in:
parent
b80436d99c
commit
1e58e2c1b8
21
js/apple2.ts
21
js/apple2.ts
@ -52,7 +52,7 @@ export class Apple2 implements Restorable<State> {
|
||||
};
|
||||
|
||||
constructor(options: Options) {
|
||||
this.cpu = new CPU6502({ '65C02': options.enhanced })
|
||||
this.cpu = new CPU6502({ '65C02': options.enhanced });
|
||||
this.gr = new LoresPage(1, options.characterRom, options.e, options.screen[0]);
|
||||
this.gr2 = new LoresPage(2, options.characterRom, options.e, options.screen[1]);
|
||||
this.hgr = new HiresPage(1, options.screen[2]);
|
||||
@ -68,9 +68,9 @@ export class Apple2 implements Restorable<State> {
|
||||
this.mmu = new MMU(this.cpu, this.vm, this.gr, this.gr2, this.hgr, this.hgr2, this.io, options.rom);
|
||||
this.cpu.addPageHandler(this.mmu);
|
||||
} else {
|
||||
let ram1 = new RAM(0x00, 0x03);
|
||||
let ram2 = new RAM(0x0C, 0x1F);
|
||||
let ram3 = new RAM(0x60, 0xBF);
|
||||
const ram1 = new RAM(0x00, 0x03);
|
||||
const ram2 = new RAM(0x0C, 0x1F);
|
||||
const ram3 = new RAM(0x60, 0xBF);
|
||||
|
||||
this.cpu.addPageHandler(ram1);
|
||||
this.cpu.addPageHandler(this.gr);
|
||||
@ -94,14 +94,15 @@ export class Apple2 implements Restorable<State> {
|
||||
return; // already running
|
||||
}
|
||||
|
||||
let interval = 30;
|
||||
const interval = 30;
|
||||
|
||||
let now, last = Date.now();
|
||||
let runFn = () => {
|
||||
let kHz = this.io.getKHz();
|
||||
const runFn = () => {
|
||||
const kHz = this.io.getKHz();
|
||||
now = Date.now();
|
||||
|
||||
let step = (now - last) * kHz, stepMax = kHz * interval;
|
||||
const stepMax = kHz * interval;
|
||||
let step = (now - last) * kHz;
|
||||
last = now;
|
||||
if (step > stepMax) {
|
||||
step = stepMax;
|
||||
@ -109,7 +110,7 @@ export class Apple2 implements Restorable<State> {
|
||||
|
||||
if (this.DEBUG) {
|
||||
this.cpu.stepCyclesDebug(this.TRACE ? 1 : step, () => {
|
||||
let line = this.cpu.dumpRegisters() + ' ' +
|
||||
const line = this.cpu.dumpRegisters() + ' ' +
|
||||
this.cpu.dumpPC(undefined, SYMBOLS);
|
||||
if (this.TRACE) {
|
||||
debug(line);
|
||||
@ -165,7 +166,7 @@ export class Apple2 implements Restorable<State> {
|
||||
}
|
||||
|
||||
getState(): State {
|
||||
let state: State = {
|
||||
const state: State = {
|
||||
cpu: this.cpu.getState(),
|
||||
};
|
||||
|
||||
|
398
js/apple2io.ts
398
js/apple2io.ts
@ -112,8 +112,8 @@ export default class Apple2IO implements PageHandler {
|
||||
}
|
||||
|
||||
_tick() {
|
||||
let now = this.cpu.getCycles();
|
||||
let phase = this._didAudio ? (this._phase > 0 ? this._high : this._low) : 0.0;
|
||||
const now = this.cpu.getCycles();
|
||||
const phase = this._didAudio ? (this._phase > 0 ? this._high : this._low) : 0.0;
|
||||
for (; this._sampleTime < now; this._sampleTime += this._cycles_per_sample) {
|
||||
this._sample[this._sampleIdx++] = phase;
|
||||
if (this._sampleIdx === this._sample_size) {
|
||||
@ -138,151 +138,151 @@ export default class Apple2IO implements PageHandler {
|
||||
|
||||
_access(off: byte, val?: byte): byte | undefined {
|
||||
let result: number | undefined = 0;
|
||||
let now = this.cpu.getCycles();
|
||||
let delta = now - this._trigger;
|
||||
const now = this.cpu.getCycles();
|
||||
const delta = now - this._trigger;
|
||||
switch (off) {
|
||||
case LOC.CLRTEXT:
|
||||
this._debug('Graphics Mode');
|
||||
this.vm.text(false);
|
||||
break;
|
||||
case LOC.SETTEXT:
|
||||
this._debug('Text Mode');
|
||||
this.vm.text(true);
|
||||
break;
|
||||
case LOC.CLRMIXED:
|
||||
this._debug('Mixed Mode off');
|
||||
this.vm.mixed(false);
|
||||
break;
|
||||
case LOC.SETMIXED:
|
||||
this._debug('Mixed Mode on');
|
||||
this.vm.mixed(true);
|
||||
break;
|
||||
case LOC.CLRHIRES:
|
||||
this._debug('LoRes Mode');
|
||||
this.vm.hires(false);
|
||||
break;
|
||||
case LOC.SETHIRES:
|
||||
this._debug('HiRes Mode');
|
||||
this.vm.hires(true);
|
||||
break;
|
||||
case LOC.PAGE1:
|
||||
this.vm.page(1);
|
||||
break;
|
||||
case LOC.PAGE2:
|
||||
this.vm.page(2);
|
||||
break;
|
||||
case LOC.SETAN0:
|
||||
this._debug('Annunciator 0 on');
|
||||
this._annunciators[0] = true;
|
||||
break;
|
||||
case LOC.SETAN1:
|
||||
this._debug('Annunciator 1 on');
|
||||
this._annunciators[1] = true;
|
||||
break;
|
||||
case LOC.SETAN2:
|
||||
this._debug('Annunciator 2 on');
|
||||
this._annunciators[2] = true;
|
||||
break;
|
||||
case LOC.SETAN3:
|
||||
this._debug('Annunciator 3 on');
|
||||
this._annunciators[3] = true;
|
||||
break;
|
||||
case LOC.CLRAN0:
|
||||
this._debug('Annunciator 0 off');
|
||||
this._annunciators[0] = false;
|
||||
break;
|
||||
case LOC.CLRAN1:
|
||||
this._debug('Annunciator 1 off');
|
||||
this._annunciators[1] = false;
|
||||
break;
|
||||
case LOC.CLRAN2:
|
||||
this._debug('Annunciator 2 off');
|
||||
this._annunciators[2] = false;
|
||||
break;
|
||||
case LOC.CLRAN3:
|
||||
this._debug('Annunciator 3 off');
|
||||
this._annunciators[3] = false;
|
||||
break;
|
||||
case LOC.PB0:
|
||||
result = this._button[0] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PB1:
|
||||
result = this._button[1] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PB2:
|
||||
result = this._button[2] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PADDLE0:
|
||||
result = (delta < (this._paddle[0] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE1:
|
||||
result = (delta < (this._paddle[1] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE2:
|
||||
result = (delta < (this._paddle[2] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE3:
|
||||
result = (delta < (this._paddle[3] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.ACCEL:
|
||||
if (val !== undefined) {
|
||||
this._updateKHz(val & 0x01 ? 1023 : 4096);
|
||||
}
|
||||
break;
|
||||
case LOC.TAPEIN:
|
||||
if (this._tapeOffset == -1) {
|
||||
this._tapeOffset = 0;
|
||||
this._tapeNext = now;
|
||||
}
|
||||
case LOC.CLRTEXT:
|
||||
this._debug('Graphics Mode');
|
||||
this.vm.text(false);
|
||||
break;
|
||||
case LOC.SETTEXT:
|
||||
this._debug('Text Mode');
|
||||
this.vm.text(true);
|
||||
break;
|
||||
case LOC.CLRMIXED:
|
||||
this._debug('Mixed Mode off');
|
||||
this.vm.mixed(false);
|
||||
break;
|
||||
case LOC.SETMIXED:
|
||||
this._debug('Mixed Mode on');
|
||||
this.vm.mixed(true);
|
||||
break;
|
||||
case LOC.CLRHIRES:
|
||||
this._debug('LoRes Mode');
|
||||
this.vm.hires(false);
|
||||
break;
|
||||
case LOC.SETHIRES:
|
||||
this._debug('HiRes Mode');
|
||||
this.vm.hires(true);
|
||||
break;
|
||||
case LOC.PAGE1:
|
||||
this.vm.page(1);
|
||||
break;
|
||||
case LOC.PAGE2:
|
||||
this.vm.page(2);
|
||||
break;
|
||||
case LOC.SETAN0:
|
||||
this._debug('Annunciator 0 on');
|
||||
this._annunciators[0] = true;
|
||||
break;
|
||||
case LOC.SETAN1:
|
||||
this._debug('Annunciator 1 on');
|
||||
this._annunciators[1] = true;
|
||||
break;
|
||||
case LOC.SETAN2:
|
||||
this._debug('Annunciator 2 on');
|
||||
this._annunciators[2] = true;
|
||||
break;
|
||||
case LOC.SETAN3:
|
||||
this._debug('Annunciator 3 on');
|
||||
this._annunciators[3] = true;
|
||||
break;
|
||||
case LOC.CLRAN0:
|
||||
this._debug('Annunciator 0 off');
|
||||
this._annunciators[0] = false;
|
||||
break;
|
||||
case LOC.CLRAN1:
|
||||
this._debug('Annunciator 1 off');
|
||||
this._annunciators[1] = false;
|
||||
break;
|
||||
case LOC.CLRAN2:
|
||||
this._debug('Annunciator 2 off');
|
||||
this._annunciators[2] = false;
|
||||
break;
|
||||
case LOC.CLRAN3:
|
||||
this._debug('Annunciator 3 off');
|
||||
this._annunciators[3] = false;
|
||||
break;
|
||||
case LOC.PB0:
|
||||
result = this._button[0] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PB1:
|
||||
result = this._button[1] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PB2:
|
||||
result = this._button[2] ? 0x80 : 0;
|
||||
break;
|
||||
case LOC.PADDLE0:
|
||||
result = (delta < (this._paddle[0] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE1:
|
||||
result = (delta < (this._paddle[1] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE2:
|
||||
result = (delta < (this._paddle[2] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.PADDLE3:
|
||||
result = (delta < (this._paddle[3] * 2756) ? 0x80 : 0x00);
|
||||
break;
|
||||
case LOC.ACCEL:
|
||||
if (val !== undefined) {
|
||||
this._updateKHz(val & 0x01 ? 1023 : 4096);
|
||||
}
|
||||
break;
|
||||
case LOC.TAPEIN:
|
||||
if (this._tapeOffset == -1) {
|
||||
this._tapeOffset = 0;
|
||||
this._tapeNext = now;
|
||||
}
|
||||
|
||||
if (this._tapeOffset < this._tape.length) {
|
||||
this._tapeCurrent = this._tape[this._tapeOffset][1];
|
||||
while (now >= this._tapeNext) {
|
||||
if ((this._tapeOffset % 1000) === 0) {
|
||||
debug('Read ' + (this._tapeOffset / 1000));
|
||||
}
|
||||
this._tapeCurrent = this._tape[this._tapeOffset][1];
|
||||
this._tapeNext += this._tape[this._tapeOffset++][0];
|
||||
if (this._tapeOffset < this._tape.length) {
|
||||
this._tapeCurrent = this._tape[this._tapeOffset][1];
|
||||
while (now >= this._tapeNext) {
|
||||
if ((this._tapeOffset % 1000) === 0) {
|
||||
debug('Read ' + (this._tapeOffset / 1000));
|
||||
}
|
||||
|
||||
this._tapeCurrent = this._tape[this._tapeOffset][1];
|
||||
this._tapeNext += this._tape[this._tapeOffset++][0];
|
||||
}
|
||||
|
||||
result = this._tapeCurrent ? 0x80 : 0x00;
|
||||
}
|
||||
|
||||
result = this._tapeCurrent ? 0x80 : 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (off & 0xf0) {
|
||||
case LOC.KEYBOARD: // C00x
|
||||
result = this._key;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (off & 0xf0) {
|
||||
case LOC.KEYBOARD: // C00x
|
||||
result = this._key;
|
||||
break;
|
||||
case LOC.STROBE: // C01x
|
||||
this._key &= 0x7f;
|
||||
if (this._buffer.length > 0) {
|
||||
let val = this._buffer.shift() as string;
|
||||
if (val == '\n') {
|
||||
val = '\r';
|
||||
}
|
||||
this._key = val.charCodeAt(0) | 0x80;
|
||||
}
|
||||
result = (this._keyDown ? 0x80 : 0x00) | this._key;
|
||||
break;
|
||||
case LOC.TAPEOUT: // C02x
|
||||
this._phase = -this._phase;
|
||||
this._didAudio = true;
|
||||
this._tick();
|
||||
break;
|
||||
case LOC.SPEAKER: // C03x
|
||||
this._phase = -this._phase;
|
||||
this._didAudio = true;
|
||||
this._tick();
|
||||
break;
|
||||
case LOC.C040STB: // C04x
|
||||
// I/O Strobe
|
||||
break;
|
||||
case LOC.PDLTRIG: // C07x
|
||||
this._trigger = this.cpu.getCycles();
|
||||
break;
|
||||
case LOC.STROBE: // C01x
|
||||
this._key &= 0x7f;
|
||||
if (this._buffer.length > 0) {
|
||||
let val = this._buffer.shift() as string;
|
||||
if (val == '\n') {
|
||||
val = '\r';
|
||||
}
|
||||
this._key = val.charCodeAt(0) | 0x80;
|
||||
}
|
||||
result = (this._keyDown ? 0x80 : 0x00) | this._key;
|
||||
break;
|
||||
case LOC.TAPEOUT: // C02x
|
||||
this._phase = -this._phase;
|
||||
this._didAudio = true;
|
||||
this._tick();
|
||||
break;
|
||||
case LOC.SPEAKER: // C03x
|
||||
this._phase = -this._phase;
|
||||
this._didAudio = true;
|
||||
this._tick();
|
||||
break;
|
||||
case LOC.C040STB: // C04x
|
||||
// I/O Strobe
|
||||
break;
|
||||
case LOC.PDLTRIG: // C07x
|
||||
this._trigger = this.cpu.getCycles();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (val !== undefined) {
|
||||
@ -305,8 +305,8 @@ export default class Apple2IO implements PageHandler {
|
||||
if (off < 0x80) {
|
||||
result = this._access(off, val);
|
||||
} else {
|
||||
let slot = (off & 0x70) >> 4;
|
||||
let card = this._slot[slot];
|
||||
const slot = (off & 0x70) >> 4;
|
||||
const card = this._slot[slot];
|
||||
if (card && card.ioSwitch) {
|
||||
result = card.ioSwitch(off, val);
|
||||
}
|
||||
@ -317,7 +317,7 @@ export default class Apple2IO implements PageHandler {
|
||||
|
||||
reset() {
|
||||
for (let slot = 0; slot < 8; slot++) {
|
||||
let card = this._slot[slot];
|
||||
const card = this._slot[slot];
|
||||
if (card && card.reset) {
|
||||
card.reset();
|
||||
}
|
||||
@ -326,7 +326,7 @@ export default class Apple2IO implements PageHandler {
|
||||
}
|
||||
|
||||
blit() {
|
||||
let card = this._slot[3];
|
||||
const card = this._slot[3];
|
||||
if (card && card.blit) {
|
||||
return card.blit();
|
||||
}
|
||||
@ -334,36 +334,36 @@ export default class Apple2IO implements PageHandler {
|
||||
}
|
||||
|
||||
read(page: byte, off: byte) {
|
||||
var result = 0;
|
||||
var slot;
|
||||
var card;
|
||||
let result = 0;
|
||||
let slot;
|
||||
let card;
|
||||
|
||||
switch (page) {
|
||||
case 0xc0:
|
||||
result = this.ioSwitch(off, undefined);
|
||||
break;
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
case 0xc3:
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
case 0xc6:
|
||||
case 0xc7:
|
||||
slot = page & 0x0f;
|
||||
card = this._slot[slot];
|
||||
if (this._auxRom != card) {
|
||||
// _debug('Setting auxRom to slot', slot);
|
||||
this._auxRom = card;
|
||||
}
|
||||
if (card) {
|
||||
result = card.read(page, off);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this._auxRom) {
|
||||
result = this._auxRom.read(page, off);
|
||||
}
|
||||
break;
|
||||
case 0xc0:
|
||||
result = this.ioSwitch(off, undefined);
|
||||
break;
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
case 0xc3:
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
case 0xc6:
|
||||
case 0xc7:
|
||||
slot = page & 0x0f;
|
||||
card = this._slot[slot];
|
||||
if (this._auxRom != card) {
|
||||
// _debug('Setting auxRom to slot', slot);
|
||||
this._auxRom = card;
|
||||
}
|
||||
if (card) {
|
||||
result = card.read(page, off);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this._auxRom) {
|
||||
result = this._auxRom.read(page, off);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -373,31 +373,31 @@ export default class Apple2IO implements PageHandler {
|
||||
let card;
|
||||
|
||||
switch (page) {
|
||||
case 0xc0:
|
||||
this.ioSwitch(off, val);
|
||||
break;
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
case 0xc3:
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
case 0xc6:
|
||||
case 0xc7:
|
||||
slot = page & 0x0f;
|
||||
card = this._slot[slot];
|
||||
if (this._auxRom != card) {
|
||||
// _debug('Setting auxRom to slot', slot);
|
||||
this._auxRom = card;
|
||||
}
|
||||
if (card) {
|
||||
card.write(page, off, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this._auxRom) {
|
||||
this._auxRom.write(page, off, val);
|
||||
}
|
||||
break;
|
||||
case 0xc0:
|
||||
this.ioSwitch(off, val);
|
||||
break;
|
||||
case 0xc1:
|
||||
case 0xc2:
|
||||
case 0xc3:
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
case 0xc6:
|
||||
case 0xc7:
|
||||
slot = page & 0x0f;
|
||||
card = this._slot[slot];
|
||||
if (this._auxRom != card) {
|
||||
// _debug('Setting auxRom to slot', slot);
|
||||
this._auxRom = card;
|
||||
}
|
||||
if (card) {
|
||||
card.write(page, off, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this._auxRom) {
|
||||
this._auxRom.write(page, off, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,7 +448,7 @@ export default class Apple2IO implements PageHandler {
|
||||
this._buffer = buffer.split(''); // split to charaters
|
||||
if (this._buffer.length > 0) {
|
||||
this._keyDown = true;
|
||||
let key = this._buffer.shift() as string; // never undefined
|
||||
const key = this._buffer.shift() as string; // never undefined
|
||||
this._key = key.charCodeAt(0) | 0x80;
|
||||
}
|
||||
}
|
||||
@ -469,7 +469,7 @@ export default class Apple2IO implements PageHandler {
|
||||
|
||||
tick() {
|
||||
this._tick();
|
||||
for (var idx = 0; idx < 8; idx++) {
|
||||
for (let idx = 0; idx < 8; idx++) {
|
||||
if (this._slot[idx] && this._slot[idx].tick) {
|
||||
this._slot[idx].tick();
|
||||
}
|
||||
|
145
js/canvas.ts
145
js/canvas.ts
@ -24,7 +24,7 @@ let altCharMode = false;
|
||||
let an3 = false;
|
||||
let doubleHiresMode = false;
|
||||
let monoDHRMode = false;
|
||||
let colorDHRMode = false;
|
||||
const colorDHRMode = false;
|
||||
let mixedDHRMode = false;
|
||||
let highColorHGRMode = false;
|
||||
let highColorTextMode = false;
|
||||
@ -74,9 +74,9 @@ function dim(c: Color): Color {
|
||||
}
|
||||
|
||||
function rowToBase(row: number) {
|
||||
let ab = (row >> 3) & 3;
|
||||
let cd = (row >> 1) & 0x3;
|
||||
let e = row & 1;
|
||||
const ab = (row >> 3) & 3;
|
||||
const cd = (row >> 1) & 0x3;
|
||||
const e = row & 1;
|
||||
return (cd << 8) | (e << 7) | (ab << 5) | (ab << 3);
|
||||
}
|
||||
|
||||
@ -192,22 +192,22 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
}
|
||||
|
||||
_drawPixel(data: number[], off: number, color: Color) {
|
||||
let c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
data[off + 0] = data[off + 4] = c0;
|
||||
data[off + 1] = data[off + 5] = c1;
|
||||
data[off + 2] = data[off + 6] = c2;
|
||||
let nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = data[nextOff + 4] = c0;
|
||||
data[nextOff + 1] = data[nextOff + 5] = c1;
|
||||
data[nextOff + 2] = data[nextOff + 6] = c2;
|
||||
}
|
||||
|
||||
_drawHalfPixel(data: number[], off: number, color: Color) {
|
||||
let c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
data[off + 0] = c0;
|
||||
data[off + 1] = c1;
|
||||
data[off + 2] = c2;
|
||||
let nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = c0;
|
||||
data[nextOff + 1] = c1;
|
||||
data[nextOff + 2] = c2;
|
||||
@ -240,13 +240,13 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
_end() { return (0x04 * this.page) + 0x03; }
|
||||
|
||||
_read(page: byte, off: byte, bank: bank) {
|
||||
var addr = (page << 8) | off, base = addr & 0x3FF;
|
||||
const addr = (page << 8) | off, base = addr & 0x3FF;
|
||||
return this._buffer[bank][base];
|
||||
}
|
||||
|
||||
_write(page: byte, off: byte, val: byte, bank: bank) {
|
||||
let addr = (page << 8) | off;
|
||||
let base = addr & 0x3FF;
|
||||
const addr = (page << 8) | off;
|
||||
const base = addr & 0x3FF;
|
||||
let fore, back;
|
||||
|
||||
if (this._buffer[bank][base] == val && !this._refreshing) {
|
||||
@ -254,16 +254,16 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
}
|
||||
this._buffer[bank][base] = val;
|
||||
|
||||
let col = (base % 0x80) % 0x28;
|
||||
let adj = off - col;
|
||||
const col = (base % 0x80) % 0x28;
|
||||
const adj = off - col;
|
||||
|
||||
// 000001cd eabab000 -> 000abcde
|
||||
let ab = (adj & 0x18);
|
||||
let cd = (page & 0x03) << 1;
|
||||
let ee = adj >> 7;
|
||||
let row = ab | cd | ee;
|
||||
const ab = (adj & 0x18);
|
||||
const cd = (page & 0x03) << 1;
|
||||
const ee = adj >> 7;
|
||||
const row = ab | cd | ee;
|
||||
|
||||
let data = this._imageData.data;
|
||||
const data = this._imageData.data;
|
||||
if ((row < 24) && (col < 40)) {
|
||||
let y = row << 4;
|
||||
if (y < this._dirty.top) { this._dirty.top = y; }
|
||||
@ -335,7 +335,7 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
off += 546 * 4 + 560 * 4;
|
||||
}
|
||||
} else {
|
||||
var colorMode = mixedMode && !textMode && !this._monoMode;
|
||||
const colorMode = mixedMode && !textMode && !this._monoMode;
|
||||
// var val0 = col > 0 ? _buffer[0][base - 1] : 0;
|
||||
// var val2 = col < 39 ? _buffer[0][base + 1] : 0;
|
||||
|
||||
@ -461,7 +461,7 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
this._refreshing = true;
|
||||
this._blink = !this._blink;
|
||||
for (let idx = 0; idx < 0x400; idx++, addr++) {
|
||||
let b = this._buffer[0][idx];
|
||||
const b = this._buffer[0][idx];
|
||||
if ((b & 0xC0) == 0x40) {
|
||||
this._write(addr >> 8, addr & 0xff, this._buffer[0][idx], 0);
|
||||
}
|
||||
@ -477,9 +477,9 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
blit(mixed: boolean = false): boolean {
|
||||
if (this._dirty.top === 385) { return false; }
|
||||
let top = this._dirty.top;
|
||||
let bottom = this._dirty.bottom;
|
||||
let left = this._dirty.left;
|
||||
let right = this._dirty.right;
|
||||
const bottom = this._dirty.bottom;
|
||||
const left = this._dirty.left;
|
||||
const right = this._dirty.right;
|
||||
|
||||
if (mixed) {
|
||||
if (bottom < 320) { return false; }
|
||||
@ -545,8 +545,8 @@ export class LoresPage implements Memory, Restorable<GraphicsState> {
|
||||
}
|
||||
|
||||
getText() {
|
||||
var buffer = '', line, charCode;
|
||||
var row, col, base;
|
||||
let buffer = '', line, charCode;
|
||||
let row, col, base;
|
||||
for (row = 0; row < 24; row++) {
|
||||
base = rowToBase(row);
|
||||
line = '';
|
||||
@ -604,23 +604,23 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
}
|
||||
|
||||
_drawPixel(data: number[], off: number, color: Color) {
|
||||
var c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
|
||||
data[off + 0] = data[off + 4] = c0;
|
||||
data[off + 1] = data[off + 5] = c1;
|
||||
data[off + 2] = data[off + 6] = c2;
|
||||
var nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = data[nextOff + 4] = c0;
|
||||
data[nextOff + 1] = data[nextOff + 5] = c1;
|
||||
data[nextOff + 2] = data[nextOff + 6] = c2;
|
||||
}
|
||||
|
||||
_drawHalfPixel(data: number[], off: number, color: Color) {
|
||||
var c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
data[off + 0] = c0;
|
||||
data[off + 1] = c1;
|
||||
data[off + 2] = c2;
|
||||
var nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = c0;
|
||||
data[nextOff + 1] = c1;
|
||||
data[nextOff + 2] = c2;
|
||||
@ -631,24 +631,24 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
//
|
||||
|
||||
_draw3Pixel(data: number[], off: number, color: Color) {
|
||||
var c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
|
||||
data[off + 0] = data[off + 4] = data[off + 8] = c0;
|
||||
data[off + 1] = data[off + 5] = data[off + 9] = c1;
|
||||
data[off + 2] = data[off + 6] = data[off + 10] = c2;
|
||||
var nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = data[nextOff + 4] = data[nextOff + 8] = c0;
|
||||
data[nextOff + 1] = data[nextOff + 5] = data[nextOff + 9] = c1;
|
||||
data[nextOff + 2] = data[nextOff + 6] = data[nextOff + 10] = c2;
|
||||
}
|
||||
|
||||
_draw4Pixel(data: number[], off: number, color: Color) {
|
||||
var c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
const c0 = color[0], c1 = color[1], c2 = color[2];
|
||||
|
||||
data[off + 0] = data[off + 4] = data[off + 8] = data[off + 12] = c0;
|
||||
data[off + 1] = data[off + 5] = data[off + 9] = data[off + 13] = c1;
|
||||
data[off + 2] = data[off + 6] = data[off + 10] = data[off + 14] = c2;
|
||||
var nextOff = off + 560 * 4;
|
||||
const nextOff = off + 560 * 4;
|
||||
data[nextOff] = data[nextOff + 4] = data[nextOff + 8] = data[nextOff + 12] = c0;
|
||||
data[nextOff + 1] = data[nextOff + 5] = data[nextOff + 9] = data[nextOff + 13] = c1;
|
||||
data[nextOff + 2] = data[nextOff + 6] = data[nextOff + 10] = data[nextOff + 14] = c2;
|
||||
@ -677,13 +677,13 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
_end() { return (0x020 * this.page) + 0x1f; }
|
||||
|
||||
_read(page: byte, off: byte, bank: bank) {
|
||||
let addr = (page << 8) | off, base = addr & 0x1FFF;
|
||||
const addr = (page << 8) | off, base = addr & 0x1FFF;
|
||||
return this._buffer[bank][base];
|
||||
}
|
||||
|
||||
_write(page: byte, off: byte, val: byte, bank: bank) {
|
||||
let addr = (page << 8) | off;
|
||||
let base = addr & 0x1FFF;
|
||||
const addr = (page << 8) | off;
|
||||
const base = addr & 0x1FFF;
|
||||
|
||||
if (this._buffer[bank][base] == val && !this._refreshing) {
|
||||
return;
|
||||
@ -692,18 +692,19 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
|
||||
let hbs = val & 0x80;
|
||||
|
||||
let col = (base % 0x80) % 0x28;
|
||||
let adj = off - col;
|
||||
const col = (base % 0x80) % 0x28;
|
||||
const adj = off - col;
|
||||
|
||||
// 000001cd eabab000 -> 000abcde
|
||||
let ab = (adj & 0x18);
|
||||
let cd = (page & 0x03) << 1;
|
||||
let e = adj >> 7;
|
||||
const ab = (adj & 0x18);
|
||||
const cd = (page & 0x03) << 1;
|
||||
const e = adj >> 7;
|
||||
|
||||
let rowa = ab | cd | e,
|
||||
const rowa = ab | cd | e,
|
||||
rowb = base >> 10;
|
||||
|
||||
let dx, dy, data = this._imageData.data;
|
||||
const data = this._imageData.data;
|
||||
let dx, dy;
|
||||
if ((rowa < 24) && (col < 40)) {
|
||||
if (!multiScreen && !hiresMode) {
|
||||
return;
|
||||
@ -722,8 +723,8 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
let bz, b0, b1, b2, b3, b4, c, hb;
|
||||
if (oneSixtyMode && !this._monoMode) {
|
||||
// 1 byte = two pixels, but 3:4 ratio
|
||||
let c3 = val & 0xf;
|
||||
let c4 = val >> 4;
|
||||
const c3 = val & 0xf;
|
||||
const c4 = val >> 4;
|
||||
|
||||
dx = col * 2 + (bank ^ 1);
|
||||
off = dx * 28 + dy * 280 * 4 * 2;
|
||||
@ -741,7 +742,7 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
// 76543210 76543210 76543210 76543210
|
||||
// 1111222 2333344 4455556 6667777
|
||||
|
||||
let mod = col % 2, mcol = col - mod, baseOff = base - mod;
|
||||
const mod = col % 2, mcol = col - mod, baseOff = base - mod;
|
||||
bz = this._buffer[0][baseOff - 1];
|
||||
b0 = this._buffer[1][baseOff];
|
||||
b1 = this._buffer[0][baseOff];
|
||||
@ -759,17 +760,17 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
((b3 & 0x78) >> 3), // 6
|
||||
0
|
||||
], // 7
|
||||
hb = [
|
||||
0,
|
||||
b0 & 0x80, // 0
|
||||
b0 & 0x80, // 1
|
||||
b1 & 0x80, // 2
|
||||
b2 & 0x80, // 3
|
||||
b2 & 0x80, // 4
|
||||
b3 & 0x80, // 5
|
||||
b3 & 0x80, // 6
|
||||
0
|
||||
]; // 7
|
||||
hb = [
|
||||
0,
|
||||
b0 & 0x80, // 0
|
||||
b0 & 0x80, // 1
|
||||
b1 & 0x80, // 2
|
||||
b2 & 0x80, // 3
|
||||
b2 & 0x80, // 4
|
||||
b3 & 0x80, // 5
|
||||
b3 & 0x80, // 6
|
||||
0
|
||||
]; // 7
|
||||
if (col > 0) {
|
||||
c[0] = (bz & 0x78) >> 3;
|
||||
hb[0] = bz & 0x80;
|
||||
@ -788,7 +789,7 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
|
||||
for (let idx = 1; idx < 8; idx++) {
|
||||
hbs = hb[idx];
|
||||
let dcolor = dcolors[r4[c[idx]]];
|
||||
const dcolor = dcolors[r4[c[idx]]];
|
||||
let bits = c[idx - 1] | (c[idx] << 4) | (c[idx + 1] << 8);
|
||||
for (let jdx = 0; jdx < 4; jdx++, off += 4) {
|
||||
if (monoColor) {
|
||||
@ -833,9 +834,9 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
|
||||
if (!this._refreshing) {
|
||||
this._refreshing = true;
|
||||
let bb: bank = bank ? 0 : 1;
|
||||
const bb: bank = bank ? 0 : 1;
|
||||
for (let rr = addr - 1; rr <= addr + 1; rr++) {
|
||||
let vv = this._buffer[bb][rr - 0x2000 * this.page];
|
||||
const vv = this._buffer[bb][rr - 0x2000 * this.page];
|
||||
this._write(rr >> 8, rr & 0xff, vv, bb);
|
||||
}
|
||||
this._refreshing = false;
|
||||
@ -848,11 +849,11 @@ export class HiresPage implements Memory, Restorable<GraphicsState> {
|
||||
b0 = col > 0 ? this._buffer[0][base - 1] : 0;
|
||||
b2 = col < 39 ? this._buffer[0][base + 1] : 0;
|
||||
val |= (b2 & 0x3) << 7;
|
||||
var v0 = b0 & 0x20, v1 = b0 & 0x40, v2 = val & 0x1,
|
||||
let v0 = b0 & 0x20, v1 = b0 & 0x40, v2 = val & 0x1,
|
||||
odd = !(col & 0x1),
|
||||
color,
|
||||
oddCol = (hbs ? orangeCol : greenCol),
|
||||
evenCol = (hbs ? blueCol : violetCol);
|
||||
color;
|
||||
const oddCol = (hbs ? orangeCol : greenCol);
|
||||
const evenCol = (hbs ? blueCol : violetCol);
|
||||
|
||||
off = dx * 4 + dy * 280 * 4 * 2;
|
||||
|
||||
@ -1027,7 +1028,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
}
|
||||
|
||||
text(on: boolean) {
|
||||
var old = textMode;
|
||||
const old = textMode;
|
||||
textMode = on;
|
||||
|
||||
if (old != on) {
|
||||
@ -1038,7 +1039,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
_80col(on: boolean) {
|
||||
if (!this.e) { return; }
|
||||
|
||||
var old = _80colMode;
|
||||
const old = _80colMode;
|
||||
_80colMode = on;
|
||||
|
||||
if (old != on) {
|
||||
@ -1049,7 +1050,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
altchar(on: boolean) {
|
||||
if (!this.e) { return; }
|
||||
|
||||
var old = altCharMode;
|
||||
const old = altCharMode;
|
||||
altCharMode = on;
|
||||
if (old != on) {
|
||||
this._refresh();
|
||||
@ -1057,7 +1058,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
}
|
||||
|
||||
hires(on: boolean) {
|
||||
var old = hiresMode;
|
||||
const old = hiresMode;
|
||||
hiresMode = on;
|
||||
if (!on) {
|
||||
this._flag = 0;
|
||||
@ -1071,7 +1072,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
an3(on: boolean) {
|
||||
if (!this.e) { return; }
|
||||
|
||||
var old = an3;
|
||||
const old = an3;
|
||||
an3 = on;
|
||||
|
||||
if (on) {
|
||||
@ -1088,7 +1089,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
}
|
||||
|
||||
mixed(on: boolean) {
|
||||
var old = mixedMode;
|
||||
const old = mixedMode;
|
||||
mixedMode = on;
|
||||
if (old != on) {
|
||||
this._refresh();
|
||||
@ -1096,7 +1097,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
}
|
||||
|
||||
page(pageNo: pageNo) {
|
||||
var old = pageMode;
|
||||
const old = pageMode;
|
||||
pageMode = pageNo;
|
||||
if (old != pageNo) {
|
||||
this._refresh();
|
||||
@ -1140,7 +1141,7 @@ export class VideoModes implements Restorable<VideoModesState> {
|
||||
}
|
||||
|
||||
blit() {
|
||||
var blitted = false;
|
||||
let blitted = false;
|
||||
if (multiScreen) {
|
||||
blitted = this._grs[0].blit() || blitted;
|
||||
blitted = this._grs[1].blit() || blitted;
|
||||
|
118
js/cpu6502.ts
118
js/cpu6502.ts
@ -1008,68 +1008,68 @@ export default class CPU6502 {
|
||||
let off, val;
|
||||
let result = '';
|
||||
switch (m) {
|
||||
case 'implied':
|
||||
break;
|
||||
case 'immediate':
|
||||
result = '#' + toHexOrSymbol(this.readByteDebug(addr));
|
||||
break;
|
||||
case 'absolute':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4);
|
||||
break;
|
||||
case 'zeroPage':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr));
|
||||
break;
|
||||
case 'relative':
|
||||
{
|
||||
let off = this.readByteDebug(addr);
|
||||
if (off > 127) {
|
||||
off -= 256;
|
||||
}
|
||||
addr += off + 1;
|
||||
result = '' + toHexOrSymbol(addr, 4) + ' (' + off + ')';
|
||||
}
|
||||
break;
|
||||
case 'absoluteX':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X';
|
||||
break;
|
||||
case 'absoluteY':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',Y';
|
||||
break;
|
||||
case 'zeroPageX':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr)) + ',X';
|
||||
break;
|
||||
case 'zeroPageY':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr)) + ',Y';
|
||||
break;
|
||||
case 'absoluteIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ')';
|
||||
break;
|
||||
case 'zeroPageXIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + ',X)';
|
||||
break;
|
||||
case 'zeroPageIndirectY':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + '),Y';
|
||||
break;
|
||||
case 'accumulator':
|
||||
result = 'A';
|
||||
break;
|
||||
case 'zeroPageIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + ')';
|
||||
break;
|
||||
case 'absoluteXIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X)';
|
||||
break;
|
||||
case 'zeroPage_relative':
|
||||
val = this.readByteDebug(addr);
|
||||
off = this.readByteDebug(addr + 1);
|
||||
case 'implied':
|
||||
break;
|
||||
case 'immediate':
|
||||
result = '#' + toHexOrSymbol(this.readByteDebug(addr));
|
||||
break;
|
||||
case 'absolute':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4);
|
||||
break;
|
||||
case 'zeroPage':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr));
|
||||
break;
|
||||
case 'relative':
|
||||
{
|
||||
let off = this.readByteDebug(addr);
|
||||
if (off > 127) {
|
||||
off -= 256;
|
||||
}
|
||||
addr += off + 2;
|
||||
result = '' + toHexOrSymbol(val) + ',' + toHexOrSymbol(addr, 4) + ' (' + off + ')';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
addr += off + 1;
|
||||
result = '' + toHexOrSymbol(addr, 4) + ' (' + off + ')';
|
||||
}
|
||||
break;
|
||||
case 'absoluteX':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X';
|
||||
break;
|
||||
case 'absoluteY':
|
||||
result = '' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',Y';
|
||||
break;
|
||||
case 'zeroPageX':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr)) + ',X';
|
||||
break;
|
||||
case 'zeroPageY':
|
||||
result = '' + toHexOrSymbol(this.readByteDebug(addr)) + ',Y';
|
||||
break;
|
||||
case 'absoluteIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ')';
|
||||
break;
|
||||
case 'zeroPageXIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + ',X)';
|
||||
break;
|
||||
case 'zeroPageIndirectY':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + '),Y';
|
||||
break;
|
||||
case 'accumulator':
|
||||
result = 'A';
|
||||
break;
|
||||
case 'zeroPageIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readByteDebug(addr)) + ')';
|
||||
break;
|
||||
case 'absoluteXIndirect':
|
||||
result = '(' + toHexOrSymbol(this.readWordDebug(addr), 4) + ',X)';
|
||||
break;
|
||||
case 'zeroPage_relative':
|
||||
val = this.readByteDebug(addr);
|
||||
off = this.readByteDebug(addr + 1);
|
||||
if (off > 127) {
|
||||
off -= 256;
|
||||
}
|
||||
addr += off + 2;
|
||||
result = '' + toHexOrSymbol(val) + ',' + toHexOrSymbol(addr, 4) + ' (' + off + ')';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ export const detrans62 = [
|
||||
* From Beneath Apple DOS
|
||||
*/
|
||||
export function fourXfour(val: byte): [xx: byte, yy: byte] {
|
||||
var xx = val & 0xaa;
|
||||
var yy = val & 0x55;
|
||||
let xx = val & 0xaa;
|
||||
let yy = val & 0x55;
|
||||
|
||||
xx >>= 1;
|
||||
xx |= 0xaa;
|
||||
@ -128,7 +128,7 @@ export function explodeSector16(volume: byte, track: byte, sector: byte, data: m
|
||||
* Address Field
|
||||
*/
|
||||
|
||||
let checksum = volume ^ track ^ sector;
|
||||
const checksum = volume ^ track ^ sector;
|
||||
buf = buf.concat([0xd5, 0xaa, 0x96]); // Address Prolog D5 AA 96
|
||||
buf = buf.concat(fourXfour(volume));
|
||||
buf = buf.concat(fourXfour(track));
|
||||
@ -150,7 +150,7 @@ export function explodeSector16(volume: byte, track: byte, sector: byte, data: m
|
||||
|
||||
buf = buf.concat([0xd5, 0xaa, 0xad]); // Data Prolog D5 AA AD
|
||||
|
||||
let nibbles: byte[] = [];
|
||||
const nibbles: byte[] = [];
|
||||
const ptr2 = 0;
|
||||
const ptr6 = 0x56;
|
||||
|
||||
@ -216,7 +216,7 @@ export function explodeSector13(volume: byte, track: byte, sector: byte, data: b
|
||||
* Address Field
|
||||
*/
|
||||
|
||||
let checksum = volume ^ track ^ sector;
|
||||
const checksum = volume ^ track ^ sector;
|
||||
buf = buf.concat([0xd5, 0xaa, 0xb5]); // Address Prolog D5 AA B5
|
||||
buf = buf.concat(fourXfour(volume));
|
||||
buf = buf.concat(fourXfour(track));
|
||||
@ -238,24 +238,24 @@ export function explodeSector13(volume: byte, track: byte, sector: byte, data: b
|
||||
|
||||
buf = buf.concat([0xd5, 0xaa, 0xad]); // Data Prolog D5 AA AD
|
||||
|
||||
let nibbles = [];
|
||||
const nibbles = [];
|
||||
|
||||
let jdx = 0;
|
||||
for (let idx = 0x32; idx >= 0; idx--) {
|
||||
var a5 = data[jdx] >> 3;
|
||||
var a3 = data[jdx] & 0x07;
|
||||
const a5 = data[jdx] >> 3;
|
||||
const a3 = data[jdx] & 0x07;
|
||||
jdx++;
|
||||
var b5 = data[jdx] >> 3;
|
||||
var b3 = data[jdx] & 0x07;
|
||||
const b5 = data[jdx] >> 3;
|
||||
const b3 = data[jdx] & 0x07;
|
||||
jdx++;
|
||||
var c5 = data[jdx] >> 3;
|
||||
var c3 = data[jdx] & 0x07;
|
||||
const c5 = data[jdx] >> 3;
|
||||
const c3 = data[jdx] & 0x07;
|
||||
jdx++;
|
||||
var d5 = data[jdx] >> 3;
|
||||
var d3 = data[jdx] & 0x07;
|
||||
const d5 = data[jdx] >> 3;
|
||||
const d3 = data[jdx] & 0x07;
|
||||
jdx++;
|
||||
var e5 = data[jdx] >> 3;
|
||||
var e3 = data[jdx] & 0x07;
|
||||
const e5 = data[jdx] >> 3;
|
||||
const e3 = data[jdx] & 0x07;
|
||||
jdx++;
|
||||
nibbles[idx + 0x00] = a5;
|
||||
nibbles[idx + 0x33] = b5;
|
||||
@ -294,14 +294,14 @@ export function explodeSector13(volume: byte, track: byte, sector: byte, data: b
|
||||
}
|
||||
|
||||
export function readSector(drive: Drive, track: byte, sector: byte) {
|
||||
let _sector = drive.format == 'po' ? _PO[sector] : _DO[sector];
|
||||
const _sector = drive.format == 'po' ? _PO[sector] : _DO[sector];
|
||||
let val, state = 0;
|
||||
let idx = 0;
|
||||
let retry = 0;
|
||||
let cur = drive.tracks[track];
|
||||
const cur = drive.tracks[track];
|
||||
|
||||
function _readNext() {
|
||||
var result = cur[idx++];
|
||||
const result = cur[idx++];
|
||||
if (idx >= cur.length) {
|
||||
idx = 0;
|
||||
retry++;
|
||||
@ -316,73 +316,73 @@ export function readSector(drive: Drive, track: byte, sector: byte) {
|
||||
}
|
||||
}
|
||||
let t = 0, s = 0, v = 0, checkSum;
|
||||
let data = [];
|
||||
const data = [];
|
||||
while (retry < 4) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
val = _readNext();
|
||||
state = (val === 0xd5) ? 1 : 0;
|
||||
break;
|
||||
case 1:
|
||||
val = _readNext();
|
||||
state = (val === 0xaa) ? 2 : 0;
|
||||
break;
|
||||
case 2:
|
||||
val = _readNext();
|
||||
state = (val === 0x96) ? 3 : (val === 0xad ? 4 : 0);
|
||||
break;
|
||||
case 3: // Address
|
||||
v = defourXfour(_readNext(), _readNext()); // Volume
|
||||
t = defourXfour(_readNext(), _readNext());
|
||||
s = defourXfour(_readNext(), _readNext());
|
||||
checkSum = defourXfour(_readNext(), _readNext());
|
||||
if (checkSum != (v ^ t ^ s)) {
|
||||
debug('Invalid header checksum:', toHex(v), toHex(t), toHex(s), toHex(checkSum));
|
||||
case 0:
|
||||
val = _readNext();
|
||||
state = (val === 0xd5) ? 1 : 0;
|
||||
break;
|
||||
case 1:
|
||||
val = _readNext();
|
||||
state = (val === 0xaa) ? 2 : 0;
|
||||
break;
|
||||
case 2:
|
||||
val = _readNext();
|
||||
state = (val === 0x96) ? 3 : (val === 0xad ? 4 : 0);
|
||||
break;
|
||||
case 3: // Address
|
||||
v = defourXfour(_readNext(), _readNext()); // Volume
|
||||
t = defourXfour(_readNext(), _readNext());
|
||||
s = defourXfour(_readNext(), _readNext());
|
||||
checkSum = defourXfour(_readNext(), _readNext());
|
||||
if (checkSum != (v ^ t ^ s)) {
|
||||
debug('Invalid header checksum:', toHex(v), toHex(t), toHex(s), toHex(checkSum));
|
||||
}
|
||||
_skipBytes(3); // Skip footer
|
||||
state = 0;
|
||||
break;
|
||||
case 4: // Data
|
||||
if (s === _sector && t === track) {
|
||||
const data2 = [];
|
||||
let last = 0;
|
||||
for (let jdx = 0x55; jdx >= 0; jdx--) {
|
||||
val = detrans62[_readNext() - 0x80] ^ last;
|
||||
data2[jdx] = val;
|
||||
last = val;
|
||||
}
|
||||
_skipBytes(3); // Skip footer
|
||||
state = 0;
|
||||
break;
|
||||
case 4: // Data
|
||||
if (s === _sector && t === track) {
|
||||
var data2 = [];
|
||||
var last = 0;
|
||||
for (let jdx = 0x55; jdx >= 0; jdx--) {
|
||||
val = detrans62[_readNext() - 0x80] ^ last;
|
||||
data2[jdx] = val;
|
||||
last = val;
|
||||
}
|
||||
for (let jdx = 0; jdx < 0x100; jdx++) {
|
||||
val = detrans62[_readNext() - 0x80] ^ last;
|
||||
data[jdx] = val;
|
||||
last = val;
|
||||
}
|
||||
checkSum = detrans62[_readNext() - 0x80] ^ last;
|
||||
if (checkSum) {
|
||||
debug('Invalid data checksum:', toHex(v), toHex(t), toHex(s), toHex(checkSum));
|
||||
}
|
||||
for (let kdx = 0, jdx = 0x55; kdx < 0x100; kdx++) {
|
||||
data[kdx] <<= 1;
|
||||
if ((data2[jdx] & 0x01) !== 0) {
|
||||
data[kdx] |= 0x01;
|
||||
}
|
||||
data2[jdx] >>= 1;
|
||||
|
||||
data[kdx] <<= 1;
|
||||
if ((data2[jdx] & 0x01) !== 0) {
|
||||
data[kdx] |= 0x01;
|
||||
}
|
||||
data2[jdx] >>= 1;
|
||||
|
||||
if (--jdx < 0) jdx = 0x55;
|
||||
}
|
||||
return data;
|
||||
for (let jdx = 0; jdx < 0x100; jdx++) {
|
||||
val = detrans62[_readNext() - 0x80] ^ last;
|
||||
data[jdx] = val;
|
||||
last = val;
|
||||
}
|
||||
else
|
||||
_skipBytes(0x159); // Skip data, checksum and footer
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
checkSum = detrans62[_readNext() - 0x80] ^ last;
|
||||
if (checkSum) {
|
||||
debug('Invalid data checksum:', toHex(v), toHex(t), toHex(s), toHex(checkSum));
|
||||
}
|
||||
for (let kdx = 0, jdx = 0x55; kdx < 0x100; kdx++) {
|
||||
data[kdx] <<= 1;
|
||||
if ((data2[jdx] & 0x01) !== 0) {
|
||||
data[kdx] |= 0x01;
|
||||
}
|
||||
data2[jdx] >>= 1;
|
||||
|
||||
data[kdx] <<= 1;
|
||||
if ((data2[jdx] & 0x01) !== 0) {
|
||||
data[kdx] |= 0x01;
|
||||
}
|
||||
data2[jdx] >>= 1;
|
||||
|
||||
if (--jdx < 0) jdx = 0x55;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
else
|
||||
_skipBytes(0x159); // Skip data, checksum and footer
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
@ -391,7 +391,7 @@ export function readSector(drive: Drive, track: byte, sector: byte) {
|
||||
export function jsonEncode(cur: Drive, pretty: boolean) {
|
||||
// For 'nib', tracks are encoded as strings. For all other formats,
|
||||
// tracks are arrays of sectors which are encoded as strings.
|
||||
let data: string[] | string[][] = [];
|
||||
const data: string[] | string[][] = [];
|
||||
let format = 'dsk';
|
||||
for (let t = 0; t < cur.tracks.length; t++) {
|
||||
data[t] = [];
|
||||
@ -399,7 +399,7 @@ export function jsonEncode(cur: Drive, pretty: boolean) {
|
||||
format = 'nib';
|
||||
data[t] = base64_encode(cur.tracks[t]);
|
||||
} else {
|
||||
for (var s = 0; s < 0x10; s++) {
|
||||
for (let s = 0; s < 0x10; s++) {
|
||||
(data[t] as string[])[s] = base64_encode(readSector(cur, t, s));
|
||||
}
|
||||
}
|
||||
@ -414,21 +414,21 @@ export function jsonEncode(cur: Drive, pretty: boolean) {
|
||||
}
|
||||
|
||||
export function jsonDecode(data: string) {
|
||||
let tracks: memory[] = [];
|
||||
let json = JSON.parse(data);
|
||||
let v = json.volume;
|
||||
let readOnly = json.readOnly;
|
||||
const tracks: memory[] = [];
|
||||
const json = JSON.parse(data);
|
||||
const v = json.volume;
|
||||
const readOnly = json.readOnly;
|
||||
for (let t = 0; t < json.data.length; t++) {
|
||||
let track: byte[] = [];
|
||||
for (let s = 0; s < json.data[t].length; s++) {
|
||||
let _s = 15 - s;
|
||||
let sector: string = json.data[t][_s];
|
||||
const _s = 15 - s;
|
||||
const sector: string = json.data[t][_s];
|
||||
const d = base64_decode(sector);
|
||||
track = track.concat(explodeSector16(v, t, s, d));
|
||||
}
|
||||
tracks[t] = bytify(track);
|
||||
}
|
||||
let cur: Drive = {
|
||||
const cur: Drive = {
|
||||
volume: v,
|
||||
format: json.type,
|
||||
tracks,
|
||||
|
572
js/mmu.ts
572
js/mmu.ts
@ -106,7 +106,7 @@ class Switches implements Memory {
|
||||
|
||||
constructor(private readonly mmu: MMU, private readonly io: any) {
|
||||
Object.keys(LOC).forEach((loc: keyof typeof LOC) => {
|
||||
let v = LOC[loc];
|
||||
const v = LOC[loc];
|
||||
this.locs[v] = loc;
|
||||
});
|
||||
}
|
||||
@ -120,7 +120,7 @@ class Switches implements Memory {
|
||||
}
|
||||
|
||||
read(_page: byte, off: byte) {
|
||||
var result;
|
||||
let result;
|
||||
if (off in this.locs) {
|
||||
result = this.mmu._access(off);
|
||||
} else {
|
||||
@ -306,7 +306,7 @@ export default class MMU implements Memory {
|
||||
}
|
||||
// I/O Switches
|
||||
{
|
||||
let idx = 0xc0;
|
||||
const idx = 0xc0;
|
||||
this._pages[idx] = this.memC0_C0;
|
||||
this._readPages[idx] = this._pages[idx][0];
|
||||
this._writePages[idx] = this._pages[idx][0];
|
||||
@ -329,7 +329,7 @@ export default class MMU implements Memory {
|
||||
this._readPages[idx] = this._pages[idx][0];
|
||||
this._writePages[idx] = this._pages[idx][0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_initSwitches() {
|
||||
this._bank1 = true;
|
||||
@ -482,306 +482,306 @@ export default class MMU implements Memory {
|
||||
|
||||
_access(off: byte, val?: byte) {
|
||||
let result;
|
||||
let readMode = val === undefined;
|
||||
let writeMode = val !== undefined;
|
||||
const readMode = val === undefined;
|
||||
const writeMode = val !== undefined;
|
||||
switch (off) {
|
||||
|
||||
// Apple //e memory management
|
||||
// Apple //e memory management
|
||||
|
||||
case LOC._80STOREOFF:
|
||||
if (writeMode) {
|
||||
this._80store = false;
|
||||
this._debug('80 Store Off');
|
||||
this.vm.page(this._page2 ? 2 : 1);
|
||||
} else {
|
||||
// Chain to io for keyboard
|
||||
result = this.io.ioSwitch(off, val);
|
||||
}
|
||||
break;
|
||||
case LOC._80STOREON:
|
||||
if (writeMode) {
|
||||
this._80store = true;
|
||||
this._debug('80 Store On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMRDOFF:
|
||||
if (writeMode) {
|
||||
this._auxRamRead = false;
|
||||
this._debug('Aux RAM Read Off');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMRDON:
|
||||
if (writeMode) {
|
||||
this._auxRamRead = true;
|
||||
this._debug('Aux RAM Read On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMWROFF:
|
||||
if (writeMode) {
|
||||
this._auxRamWrite = false;
|
||||
this._debug('Aux RAM Write Off');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMWRON:
|
||||
if (writeMode) {
|
||||
this._auxRamWrite = true;
|
||||
this._debug('Aux RAM Write On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC._80STOREOFF:
|
||||
if (writeMode) {
|
||||
this._80store = false;
|
||||
this._debug('80 Store Off');
|
||||
this.vm.page(this._page2 ? 2 : 1);
|
||||
} else {
|
||||
// Chain to io for keyboard
|
||||
result = this.io.ioSwitch(off, val);
|
||||
}
|
||||
break;
|
||||
case LOC._80STOREON:
|
||||
if (writeMode) {
|
||||
this._80store = true;
|
||||
this._debug('80 Store On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMRDOFF:
|
||||
if (writeMode) {
|
||||
this._auxRamRead = false;
|
||||
this._debug('Aux RAM Read Off');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMRDON:
|
||||
if (writeMode) {
|
||||
this._auxRamRead = true;
|
||||
this._debug('Aux RAM Read On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMWROFF:
|
||||
if (writeMode) {
|
||||
this._auxRamWrite = false;
|
||||
this._debug('Aux RAM Write Off');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
case LOC.RAMWRON:
|
||||
if (writeMode) {
|
||||
this._auxRamWrite = true;
|
||||
this._debug('Aux RAM Write On');
|
||||
} else
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case LOC.INTCXROMOFF:
|
||||
if (writeMode) {
|
||||
this._intcxrom = false;
|
||||
this._intc8rom = false;
|
||||
this._debug('Int CX ROM Off');
|
||||
}
|
||||
break;
|
||||
case LOC.INTCXROMON:
|
||||
if (writeMode) {
|
||||
this._intcxrom = true;
|
||||
this._debug('Int CX ROM On');
|
||||
}
|
||||
break;
|
||||
case LOC.ALTZPOFF: // 0x08
|
||||
if (writeMode) {
|
||||
this._altzp = false;
|
||||
this._debug('Alt ZP Off');
|
||||
}
|
||||
break;
|
||||
case LOC.ALTZPON: // 0x09
|
||||
if (writeMode) {
|
||||
this._altzp = true;
|
||||
this._debug('Alt ZP On');
|
||||
}
|
||||
break;
|
||||
case LOC.SLOTC3ROMOFF: // 0x0A
|
||||
if (writeMode) {
|
||||
this._slot3rom = false;
|
||||
this._debug('Slot 3 ROM Off');
|
||||
}
|
||||
break;
|
||||
case LOC.SLOTC3ROMON: // 0x0B
|
||||
if (writeMode) {
|
||||
this._slot3rom = true;
|
||||
this._debug('Slot 3 ROM On');
|
||||
}
|
||||
break;
|
||||
case LOC.INTCXROMOFF:
|
||||
if (writeMode) {
|
||||
this._intcxrom = false;
|
||||
this._intc8rom = false;
|
||||
this._debug('Int CX ROM Off');
|
||||
}
|
||||
break;
|
||||
case LOC.INTCXROMON:
|
||||
if (writeMode) {
|
||||
this._intcxrom = true;
|
||||
this._debug('Int CX ROM On');
|
||||
}
|
||||
break;
|
||||
case LOC.ALTZPOFF: // 0x08
|
||||
if (writeMode) {
|
||||
this._altzp = false;
|
||||
this._debug('Alt ZP Off');
|
||||
}
|
||||
break;
|
||||
case LOC.ALTZPON: // 0x09
|
||||
if (writeMode) {
|
||||
this._altzp = true;
|
||||
this._debug('Alt ZP On');
|
||||
}
|
||||
break;
|
||||
case LOC.SLOTC3ROMOFF: // 0x0A
|
||||
if (writeMode) {
|
||||
this._slot3rom = false;
|
||||
this._debug('Slot 3 ROM Off');
|
||||
}
|
||||
break;
|
||||
case LOC.SLOTC3ROMON: // 0x0B
|
||||
if (writeMode) {
|
||||
this._slot3rom = true;
|
||||
this._debug('Slot 3 ROM On');
|
||||
}
|
||||
break;
|
||||
|
||||
// Graphics Switches
|
||||
|
||||
case LOC.CLR80VID:
|
||||
if (writeMode) {
|
||||
this._debug('80 Column Mode off');
|
||||
this.vm._80col(false);
|
||||
}
|
||||
break;
|
||||
case LOC.SET80VID:
|
||||
if (writeMode) {
|
||||
this._debug('80 Column Mode on');
|
||||
this.vm._80col(true);
|
||||
}
|
||||
break;
|
||||
case LOC.CLRALTCH:
|
||||
if (writeMode) {
|
||||
this._debug('Alt Char off');
|
||||
this.vm.altchar(false);
|
||||
}
|
||||
break;
|
||||
case LOC.SETALTCH:
|
||||
if (writeMode) {
|
||||
this._debug('Alt Char on');
|
||||
this.vm.altchar(true);
|
||||
}
|
||||
break;
|
||||
case LOC.PAGE1:
|
||||
this._page2 = false;
|
||||
if (!this._80store) {
|
||||
result = this.io.ioSwitch(off, val);
|
||||
}
|
||||
this._debug('Page 2 off');
|
||||
break;
|
||||
case LOC.PAGE2:
|
||||
this._page2 = true;
|
||||
if (!this._80store) {
|
||||
result = this.io.ioSwitch(off, val);
|
||||
}
|
||||
this._debug('Page 2 on');
|
||||
break;
|
||||
|
||||
case LOC.RESET_HIRES:
|
||||
this._hires = false;
|
||||
case LOC.CLR80VID:
|
||||
if (writeMode) {
|
||||
this._debug('80 Column Mode off');
|
||||
this.vm._80col(false);
|
||||
}
|
||||
break;
|
||||
case LOC.SET80VID:
|
||||
if (writeMode) {
|
||||
this._debug('80 Column Mode on');
|
||||
this.vm._80col(true);
|
||||
}
|
||||
break;
|
||||
case LOC.CLRALTCH:
|
||||
if (writeMode) {
|
||||
this._debug('Alt Char off');
|
||||
this.vm.altchar(false);
|
||||
}
|
||||
break;
|
||||
case LOC.SETALTCH:
|
||||
if (writeMode) {
|
||||
this._debug('Alt Char on');
|
||||
this.vm.altchar(true);
|
||||
}
|
||||
break;
|
||||
case LOC.PAGE1:
|
||||
this._page2 = false;
|
||||
if (!this._80store) {
|
||||
result = this.io.ioSwitch(off, val);
|
||||
this._debug('Hires off');
|
||||
break;
|
||||
|
||||
case LOC.DHIRESON:
|
||||
if (this._iouDisable) {
|
||||
this.vm.doubleHires(true);
|
||||
} else {
|
||||
result = this.io.ioSwitch(off, val); // an3
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC.DHIRESOFF:
|
||||
if (this._iouDisable) {
|
||||
this.vm.doubleHires(false);
|
||||
} else {
|
||||
result = this.io.ioSwitch(off, val); // an3
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC.SET_HIRES:
|
||||
this._hires = true;
|
||||
}
|
||||
this._debug('Page 2 off');
|
||||
break;
|
||||
case LOC.PAGE2:
|
||||
this._page2 = true;
|
||||
if (!this._80store) {
|
||||
result = this.io.ioSwitch(off, val);
|
||||
this._debug('Hires on');
|
||||
break;
|
||||
}
|
||||
this._debug('Page 2 on');
|
||||
break;
|
||||
|
||||
case LOC.IOUDISON:
|
||||
if (writeMode) {
|
||||
this._iouDisable = true;
|
||||
}
|
||||
result = this._iouDisable ? 0x00 : 0x80;
|
||||
break;
|
||||
case LOC.RESET_HIRES:
|
||||
this._hires = false;
|
||||
result = this.io.ioSwitch(off, val);
|
||||
this._debug('Hires off');
|
||||
break;
|
||||
|
||||
case LOC.IOUDISOFF:
|
||||
if (writeMode) {
|
||||
this._iouDisable = false;
|
||||
}
|
||||
result = this.vm.isDoubleHires() ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.DHIRESON:
|
||||
if (this._iouDisable) {
|
||||
this.vm.doubleHires(true);
|
||||
} else {
|
||||
result = this.io.ioSwitch(off, val); // an3
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC.DHIRESOFF:
|
||||
if (this._iouDisable) {
|
||||
this.vm.doubleHires(false);
|
||||
} else {
|
||||
result = this.io.ioSwitch(off, val); // an3
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC.SET_HIRES:
|
||||
this._hires = true;
|
||||
result = this.io.ioSwitch(off, val);
|
||||
this._debug('Hires on');
|
||||
break;
|
||||
|
||||
case LOC.IOUDISON:
|
||||
if (writeMode) {
|
||||
this._iouDisable = true;
|
||||
}
|
||||
result = this._iouDisable ? 0x00 : 0x80;
|
||||
break;
|
||||
|
||||
case LOC.IOUDISOFF:
|
||||
if (writeMode) {
|
||||
this._iouDisable = false;
|
||||
}
|
||||
result = this.vm.isDoubleHires() ? 0x80 : 0x00;
|
||||
break;
|
||||
|
||||
// Language Card Switches
|
||||
|
||||
case LOC.READBSR2: // 0xC080
|
||||
case LOC._READBSR2: // 0xC084
|
||||
this._bank1 = false;
|
||||
this._readbsr = true;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 2 Read');
|
||||
break;
|
||||
case LOC.WRITEBSR2: // 0xC081
|
||||
case LOC._WRITEBSR2: // 0xC085
|
||||
this._bank1 = false;
|
||||
this._readbsr = false;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 2 Write');
|
||||
break;
|
||||
case LOC.OFFBSR2: // 0xC082
|
||||
case LOC._OFFBSR2: // 0xC086
|
||||
this._bank1 = false;
|
||||
this._readbsr = false;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 2 Off');
|
||||
break;
|
||||
case LOC.READWRBSR2: // 0xC083
|
||||
case LOC._READWRBSR2: // 0xC087
|
||||
this._bank1 = false;
|
||||
this._readbsr = true;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 2 Read/Write');
|
||||
break;
|
||||
case LOC.READBSR1: // 0xC088
|
||||
case LOC._READBSR1: // 0xC08c
|
||||
this._bank1 = true;
|
||||
this._readbsr = true;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 1 Read');
|
||||
break;
|
||||
case LOC.WRITEBSR1: // 0xC089
|
||||
case LOC._WRITEBSR1: // 0xC08D
|
||||
this._bank1 = true;
|
||||
this._readbsr = false;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 1 Write');
|
||||
break;
|
||||
case LOC.OFFBSR1: // 0xC08A
|
||||
case LOC._OFFBSR1: // 0xC08E
|
||||
this._bank1 = true;
|
||||
this._readbsr = false;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 1 Off');
|
||||
break;
|
||||
case LOC.READWRBSR1: // 0xC08B
|
||||
case LOC._READWRBSR1: // 0xC08F
|
||||
this._bank1 = true;
|
||||
this._readbsr = true;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
//_debug('Bank 1 Read/Write');
|
||||
break;
|
||||
case LOC.READBSR2: // 0xC080
|
||||
case LOC._READBSR2: // 0xC084
|
||||
this._bank1 = false;
|
||||
this._readbsr = true;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 2 Read');
|
||||
break;
|
||||
case LOC.WRITEBSR2: // 0xC081
|
||||
case LOC._WRITEBSR2: // 0xC085
|
||||
this._bank1 = false;
|
||||
this._readbsr = false;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 2 Write');
|
||||
break;
|
||||
case LOC.OFFBSR2: // 0xC082
|
||||
case LOC._OFFBSR2: // 0xC086
|
||||
this._bank1 = false;
|
||||
this._readbsr = false;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 2 Off');
|
||||
break;
|
||||
case LOC.READWRBSR2: // 0xC083
|
||||
case LOC._READWRBSR2: // 0xC087
|
||||
this._bank1 = false;
|
||||
this._readbsr = true;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 2 Read/Write');
|
||||
break;
|
||||
case LOC.READBSR1: // 0xC088
|
||||
case LOC._READBSR1: // 0xC08c
|
||||
this._bank1 = true;
|
||||
this._readbsr = true;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 1 Read');
|
||||
break;
|
||||
case LOC.WRITEBSR1: // 0xC089
|
||||
case LOC._WRITEBSR1: // 0xC08D
|
||||
this._bank1 = true;
|
||||
this._readbsr = false;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
// _debug('Bank 1 Write');
|
||||
break;
|
||||
case LOC.OFFBSR1: // 0xC08A
|
||||
case LOC._OFFBSR1: // 0xC08E
|
||||
this._bank1 = true;
|
||||
this._readbsr = false;
|
||||
this._writebsr = false;
|
||||
this._prewrite = false;
|
||||
// _debug('Bank 1 Off');
|
||||
break;
|
||||
case LOC.READWRBSR1: // 0xC08B
|
||||
case LOC._READWRBSR1: // 0xC08F
|
||||
this._bank1 = true;
|
||||
this._readbsr = true;
|
||||
if (readMode) { this._writebsr = this._prewrite; }
|
||||
this._prewrite = readMode;
|
||||
//_debug('Bank 1 Read/Write');
|
||||
break;
|
||||
|
||||
// Status registers
|
||||
|
||||
case LOC.BSRBANK2:
|
||||
this._debug('Bank 2 Read ' + !this._bank1);
|
||||
result = !this._bank1 ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.BSRREADRAM:
|
||||
this._debug('Bank SW RAM Read ' + this._readbsr);
|
||||
result = this._readbsr ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.RAMRD: // 0xC013
|
||||
this._debug('Aux RAM Read ' + this._auxRamRead);
|
||||
result = this._auxRamRead ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RAMWRT: // 0xC014
|
||||
this._debug('Aux RAM Write ' + this._auxRamWrite);
|
||||
result = this._auxRamWrite ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.INTCXROM: // 0xC015
|
||||
// _debug('Int CX ROM ' + _intcxrom);
|
||||
result = this._intcxrom ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.ALTZP: // 0xC016
|
||||
this._debug('Alt ZP ' + this._altzp);
|
||||
result = this._altzp ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.SLOTC3ROM: // 0xC017
|
||||
this._debug('Slot C3 ROM ' + this._slot3rom);
|
||||
result = this._slot3rom ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC._80STORE: // 0xC018
|
||||
this._debug('80 Store ' + this._80store);
|
||||
result = this._80store ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.VERTBLANK: // 0xC019
|
||||
// result = cpu.getCycles() % 20 < 5 ? 0x80 : 0x00;
|
||||
result = (this.cpu.getCycles() < this._vbEnd) ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.RDTEXT:
|
||||
result = this.vm.isText() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDMIXED:
|
||||
result = this.vm.isMixed() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDPAGE2:
|
||||
result = this.vm.isPage2() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDHIRES:
|
||||
result = this.vm.isHires() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RD80VID:
|
||||
result = this.vm.is80Col() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDALTCH:
|
||||
result = this.vm.isAltChar() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.BSRBANK2:
|
||||
this._debug('Bank 2 Read ' + !this._bank1);
|
||||
result = !this._bank1 ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.BSRREADRAM:
|
||||
this._debug('Bank SW RAM Read ' + this._readbsr);
|
||||
result = this._readbsr ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.RAMRD: // 0xC013
|
||||
this._debug('Aux RAM Read ' + this._auxRamRead);
|
||||
result = this._auxRamRead ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RAMWRT: // 0xC014
|
||||
this._debug('Aux RAM Write ' + this._auxRamWrite);
|
||||
result = this._auxRamWrite ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.INTCXROM: // 0xC015
|
||||
// _debug('Int CX ROM ' + _intcxrom);
|
||||
result = this._intcxrom ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.ALTZP: // 0xC016
|
||||
this._debug('Alt ZP ' + this._altzp);
|
||||
result = this._altzp ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.SLOTC3ROM: // 0xC017
|
||||
this._debug('Slot C3 ROM ' + this._slot3rom);
|
||||
result = this._slot3rom ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC._80STORE: // 0xC018
|
||||
this._debug('80 Store ' + this._80store);
|
||||
result = this._80store ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.VERTBLANK: // 0xC019
|
||||
// result = cpu.getCycles() % 20 < 5 ? 0x80 : 0x00;
|
||||
result = (this.cpu.getCycles() < this._vbEnd) ? 0x80 : 0x00;
|
||||
break;
|
||||
case LOC.RDTEXT:
|
||||
result = this.vm.isText() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDMIXED:
|
||||
result = this.vm.isMixed() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDPAGE2:
|
||||
result = this.vm.isPage2() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDHIRES:
|
||||
result = this.vm.isHires() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RD80VID:
|
||||
result = this.vm.is80Col() ? 0x80 : 0x0;
|
||||
break;
|
||||
case LOC.RDALTCH:
|
||||
result = this.vm.isAltChar() ? 0x80 : 0x0;
|
||||
break;
|
||||
|
||||
default:
|
||||
debug('MMU missing register ' + toHex(off));
|
||||
break;
|
||||
default:
|
||||
debug('MMU missing register ' + toHex(off));
|
||||
break;
|
||||
}
|
||||
|
||||
if (result !== undefined)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const apple2_charset = bytify([
|
||||
0x00,0x1c,0x22,0x2a,0x2e,0x2c,0x20,0x1e,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
/* exported apple2e_charset */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const apple2enh_charset = bytify([
|
||||
0x1c,0x22,0x2a,0x3a,0x1a,0x02,0x3c,0x00,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0x6f,0xd8,0x65,0xd7,0xf8,0xdc,0x94,0xd9,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const apple2j_charset = bytify([
|
||||
0xff,0xef,0xe1,0xed,0xd5,0xfb,0xf7,0xef,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const apple2lc_charset = bytify([
|
||||
0x1c,0x22,0x2a,0x2a,0x2c,0x20,0x1e,0x00,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
/*
|
||||
* http://dreher.net/?s=projects/CFforAppleII&c=projects/CFforAppleII/downloads1.php
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
export const P5_16 = bytify([
|
||||
0xa2,0x20,0xa0,0x00,0xa2,0x03,0x86,0x3c,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
export const rom = bytify([
|
||||
0x18,0xb0,0x38,0x48,0x8a,0x48,0x98,0x48,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
export const rom = bytify([
|
||||
0x43,0x4f,0x50,0x59,0x52,0x49,0x47,0x48,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
/*
|
||||
$Cn01=$20
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
export const rom = bytify([
|
||||
0x08,0x78,0x28,0x2c,0x58,0xff,0x70,0x05, // 00
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { bytify } from "../../util";
|
||||
import { bytify } from '../../util';
|
||||
|
||||
export var ROM = bytify([
|
||||
export const ROM = bytify([
|
||||
0xad,0x7b,0x07,0x29,0xf8,0xc9,0x30,0xf0,
|
||||
0x21,0xa9,0x30,0x8d,0x7b,0x07,0x8d,0xfb,
|
||||
0x07,0xa9,0x00,0x8d,0xfb,0x06,0x20,0x61,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0x6f, 0xd8, 0x65, 0xd7, 0xf8, 0xdc, 0x94, 0xd9,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0xa9, 0x20, 0x8d, 0x26, 0x03, 0xad, 0x57, 0xc0,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { bytify } from "../util";
|
||||
import ROM from "./rom";
|
||||
import { bytify } from '../util';
|
||||
import ROM from './rom';
|
||||
|
||||
const rom = bytify([
|
||||
0xa9, 0x20, 0x8d, 0x26, 0x03, 0xad, 0x57, 0xc0,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const pigfont_charset = bytify([
|
||||
0x00,0x1c,0x22,0x2a,0x2e,0x20,0x1e,0x00,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { bytify } from "../util";
|
||||
import { bytify } from '../util';
|
||||
|
||||
const rmfont_charset = bytify([
|
||||
0x3c,0x42,0x59,0x55,0x55,0x39,0x02,0x3c,
|
||||
|
@ -1,27 +1,27 @@
|
||||
import { PageHandler } from "../cpu6502";
|
||||
import { byte, memory } from "../types";
|
||||
import { PageHandler } from '../cpu6502';
|
||||
import { byte, memory } from '../types';
|
||||
|
||||
export default class ROM implements PageHandler {
|
||||
|
||||
constructor(
|
||||
constructor(
|
||||
private readonly startPage: byte,
|
||||
private readonly endPage: byte,
|
||||
private readonly rom: memory) {
|
||||
const expectedLength = (endPage-startPage+1) * 256;
|
||||
if (rom.length != expectedLength) {
|
||||
throw Error(`rom does not have the correct length: expected ${expectedLength} was ${rom.length}`);
|
||||
}
|
||||
const expectedLength = (endPage-startPage+1) * 256;
|
||||
if (rom.length != expectedLength) {
|
||||
throw Error(`rom does not have the correct length: expected ${expectedLength} was ${rom.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
return this.startPage;
|
||||
}
|
||||
end() {
|
||||
return this.endPage;
|
||||
}
|
||||
read(page: byte, off: byte) {
|
||||
return this.rom[(page - this.startPage) << 8 | off];
|
||||
}
|
||||
write() {
|
||||
}
|
||||
start() {
|
||||
return this.startPage;
|
||||
}
|
||||
end() {
|
||||
return this.endPage;
|
||||
}
|
||||
read(page: byte, off: byte) {
|
||||
return this.rom[(page - this.startPage) << 8 | off];
|
||||
}
|
||||
write() {
|
||||
}
|
||||
}
|
||||
|
@ -7,18 +7,18 @@ import Apple2enhROM from '../../js/roms/apple2enh';
|
||||
import Apple2jROM from '../../js/roms/apple2j';
|
||||
|
||||
const roms: { [name: string]: { new(): ROM } } = {
|
||||
'original': OriginalROM,
|
||||
'integer': IntegerROM,
|
||||
'fpbasic': FPBasicROM,
|
||||
'apple2e': Apple2eROM,
|
||||
'apple2enh': Apple2enhROM,
|
||||
'apple2j': Apple2jROM,
|
||||
'original': OriginalROM,
|
||||
'integer': IntegerROM,
|
||||
'fpbasic': FPBasicROM,
|
||||
'apple2e': Apple2eROM,
|
||||
'apple2enh': Apple2enhROM,
|
||||
'apple2j': Apple2jROM,
|
||||
};
|
||||
|
||||
for (let rom of Object.keys(roms)) {
|
||||
describe(`${rom}`, () => {
|
||||
it('is constructable', () => {
|
||||
new roms[rom]();
|
||||
for (const rom of Object.keys(roms)) {
|
||||
describe(`${rom}`, () => {
|
||||
it('is constructable', () => {
|
||||
new roms[rom]();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user