mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-01-02 23:30:21 +00:00
atari8: fixed VSCROL, pokey freq, performance
This commit is contained in:
parent
9f1c5377b3
commit
30342d2618
@ -202,7 +202,7 @@ export var POKEYDeviceChannel = function() {
|
||||
|
||||
this.setSampleRate = function (rate) {
|
||||
sampleRate = rate;
|
||||
baseDelta = FREQ_17_EXACT / rate / 1.2; // TODO?
|
||||
baseDelta = FREQ_17_EXACT / rate;
|
||||
};
|
||||
|
||||
function updateValues(addr) {
|
||||
|
@ -61,7 +61,7 @@ const linesPerFrame = 262;
|
||||
const numVisibleLines = 258-16;
|
||||
const colorClocksPerLine = 454; // 456?
|
||||
const colorClocksPreDMA = 28;
|
||||
const audioOversample = 4;
|
||||
const audioOversample = 2;
|
||||
const audioSampleRate = linesPerFrame*60*audioOversample;
|
||||
|
||||
// TIA chip
|
||||
|
@ -53,7 +53,7 @@ export class Atari800 extends BasicScanlineMachine {
|
||||
firstVisibleClock = (44 - 6) * 2; // ... to 215 * 2
|
||||
defaultROMSize = 0x8000;
|
||||
overscan = true;
|
||||
audioOversample = 4;
|
||||
audioOversample = 2;
|
||||
sampleRate = this.numTotalScanlines * 60 * this.audioOversample;
|
||||
run_address = -1;
|
||||
|
||||
|
@ -73,6 +73,7 @@ export class ANTIC {
|
||||
ch: number = 0; // char read
|
||||
linesleft: number = 0; // # of lines left in mode
|
||||
yofs: number = 0; // yofs fine
|
||||
isfirstline: boolean = false;
|
||||
v: number = 0; // vertical scanline #
|
||||
h: number = 0; // horizontal color clock
|
||||
|
||||
@ -81,7 +82,7 @@ export class ANTIC {
|
||||
dmaidx: number = 0;
|
||||
output: number = 0;
|
||||
dramrefresh = false;
|
||||
vscroll = 0;
|
||||
in_vscroll = 0;
|
||||
|
||||
constructor(readfn, nmifn) {
|
||||
this.read = readfn; // bus read function
|
||||
@ -159,7 +160,6 @@ export class ANTIC {
|
||||
//console.log('scanaddr', hex(this.scanaddr));
|
||||
}
|
||||
this.startaddr = this.scanaddr;
|
||||
}
|
||||
// horiz scroll
|
||||
let effwidth = this.regs[DMACTL] & 3;
|
||||
let hscroll = (this.dliop & 0x10) ? (this.regs[HSCROL] & 15) >> 1 : 0;
|
||||
@ -168,14 +168,16 @@ export class ANTIC {
|
||||
this.right = PF_RIGHT[effwidth] + hscroll;
|
||||
// vertical scroll
|
||||
let vscrol = this.regs[VSCROL] & 0xf;
|
||||
if ((this.dliop & 0x20) ^ this.vscroll) {
|
||||
if (this.vscroll) {
|
||||
this.linesleft -= vscrol;
|
||||
if ((this.dliop & 0x20) ^ this.in_vscroll) {
|
||||
if (this.in_vscroll) {
|
||||
this.linesleft = vscrol+1; // exiting
|
||||
} else {
|
||||
this.linesleft -= vscrol;
|
||||
this.linesleft -= vscrol; // entering
|
||||
this.yofs += vscrol;
|
||||
}
|
||||
this.vscroll ^= 0x20;
|
||||
this.linesleft &= 0xf;
|
||||
this.in_vscroll ^= 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +185,7 @@ export class ANTIC {
|
||||
if (this.linesleft > 0) {
|
||||
this.linesleft--;
|
||||
this.yofs++;
|
||||
this.isfirstline = false;
|
||||
if (this.mode >= 8 && this.linesleft) {
|
||||
this.scanaddr = this.startaddr; // reset line addr
|
||||
}
|
||||
@ -254,6 +257,7 @@ export class ANTIC {
|
||||
this.mode = op & 0xf;
|
||||
this.dliop = op;
|
||||
this.yofs = 0;
|
||||
this.isfirstline = true;
|
||||
did_dma = true;
|
||||
}
|
||||
break;
|
||||
@ -265,7 +269,7 @@ export class ANTIC {
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
if (this.isPlayfieldDMAEnabled() && this.yofs == 0 && (this.jmp || this.lms)) {
|
||||
if (this.isPlayfieldDMAEnabled() && this.isfirstline && (this.jmp || this.lms)) {
|
||||
if (this.h == 6) this.dlarg_lo = this.nextInsn();
|
||||
if (this.h == 7) this.dlarg_hi = this.nextInsn();
|
||||
did_dma = true;
|
||||
@ -273,7 +277,7 @@ export class ANTIC {
|
||||
break;
|
||||
case 8:
|
||||
// TODO? is this at cycle 8?
|
||||
if (this.yofs == 0) {
|
||||
if (this.isfirstline) {
|
||||
this.processDLIEntry();
|
||||
}
|
||||
if (this.dliop & 0x80) { // TODO: what if DLI disabled?
|
||||
@ -299,7 +303,7 @@ export class ANTIC {
|
||||
if (this.h == this.left) { this.dmaclock |= 1; this.dmaidx = 0; }
|
||||
if (this.h == this.right) { this.dmaclock &= ~1; this.dmaidx++; }
|
||||
if (this.dmaclock & 1) {
|
||||
if (this.mode < 8 && this.yofs == 0) { // only read chars on 1st line
|
||||
if (this.mode < 8 && this.isfirstline) { // only read chars on 1st line
|
||||
if (candma) {
|
||||
this.linebuf[this.dmaidx] = this.nextScreen(); // read char name
|
||||
} else {
|
||||
|
@ -65,7 +65,6 @@ export class GTIA {
|
||||
regs = new Uint8Array(0x20);
|
||||
readregs = new Uint8Array(0x20);
|
||||
shiftregs = new Uint32Array(8);
|
||||
priortab = new Uint8Array(12);
|
||||
|
||||
count = 0;
|
||||
an = 0;
|
||||
@ -159,20 +158,37 @@ export class GTIA {
|
||||
return 0x100; // black
|
||||
}
|
||||
anySpriteActive() {
|
||||
return this.shiftregs[0] | this.shiftregs[1] | this.shiftregs[2]
|
||||
| this.shiftregs[3] | this.shiftregs[4] | this.shiftregs[5]
|
||||
| this.shiftregs[6] | this.shiftregs[7];
|
||||
return this.shiftregs[0] || this.shiftregs[1] || this.shiftregs[2]
|
||||
|| this.shiftregs[3] || this.shiftregs[4] || this.shiftregs[5]
|
||||
|| this.shiftregs[6] || this.shiftregs[7];
|
||||
}
|
||||
processPlayerMissile() {
|
||||
// no p/m gfx, no collisions in blank area, but shift and trigger anyway
|
||||
if (this.an == 2 || !this.anySpriteActive()) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
this.shiftObject(i);
|
||||
}
|
||||
// no p/m gfx, just evaluate horiz. triggers
|
||||
if (!this.anySpriteActive()) {
|
||||
this.evalTrigger(0);
|
||||
this.evalTrigger(1);
|
||||
this.evalTrigger(2);
|
||||
this.evalTrigger(3);
|
||||
this.evalTrigger(4);
|
||||
this.evalTrigger(5);
|
||||
this.evalTrigger(6);
|
||||
this.evalTrigger(7);
|
||||
this.pmcol = -1;
|
||||
return;
|
||||
}
|
||||
// no collisions in blank area, but shift and trigger anyway
|
||||
if (this.an == 2) {
|
||||
this.shiftObject(0);
|
||||
this.shiftObject(1);
|
||||
this.shiftObject(2);
|
||||
this.shiftObject(3);
|
||||
this.shiftObject(4);
|
||||
this.shiftObject(5);
|
||||
this.shiftObject(6);
|
||||
this.shiftObject(7);
|
||||
this.pmcol = -1;
|
||||
return;
|
||||
}
|
||||
// TODO: multiple color player enable
|
||||
// TODO: gtia, hi-res mode collisions
|
||||
// compute gfx and collisions for players/missiles
|
||||
let priobias = (this.regs[PRIOR] & 15) << 4; // TODO
|
||||
@ -203,7 +219,9 @@ export class GTIA {
|
||||
this.readregs[M0PF + i] |= 1 << pfset;
|
||||
}
|
||||
this.readregs[M0PL + i] |= ppmask;
|
||||
let prio = PRIOR_TABLE[i + priobias];
|
||||
let prio = (this.regs[PRIOR] & 0x10)
|
||||
? PRIOR_TABLE[priobias + 15]
|
||||
: PRIOR_TABLE[i + priobias];
|
||||
if (prio < topprio) {
|
||||
topobj = i + 4;
|
||||
topprio = prio;
|
||||
@ -221,9 +239,7 @@ export class GTIA {
|
||||
shiftObject(i: number) {
|
||||
let bit = (this.shiftregs[i] & 0x80000000) != 0;
|
||||
this.shiftregs[i] <<= 1;
|
||||
if (this.regs[HPOSP0 + i] + this.hbias == this.count) {
|
||||
this.triggerObject(i);
|
||||
}
|
||||
this.evalTrigger(i);
|
||||
return bit;
|
||||
}
|
||||
getObjectColor(i: number) {
|
||||
@ -233,6 +249,11 @@ export class GTIA {
|
||||
return this.regs[COLPM0 + (i & 3)];
|
||||
}
|
||||
}
|
||||
evalTrigger(i: number) {
|
||||
if (this.regs[HPOSP0 + i] + this.hbias == this.count) {
|
||||
this.triggerObject(i);
|
||||
}
|
||||
}
|
||||
triggerObject(i: number) {
|
||||
let size, data;
|
||||
if (!(this.pmDebugMask & (1<<i))) return;
|
||||
@ -246,7 +267,7 @@ export class GTIA {
|
||||
}
|
||||
if (size & 1) data = expandBits(data); else data <<= 8;
|
||||
if (size == 3) data = expandBits(data); else data <<= 16;
|
||||
this.shiftregs[i] = data;
|
||||
this.shiftregs[i] |= data;
|
||||
}
|
||||
|
||||
clockPulse1(): void {
|
||||
|
@ -369,14 +369,17 @@ describe('Platform Replay', () => {
|
||||
it('Should run atari5200', async () => {
|
||||
await testPlatform('atari8-5200', 'acid5200.rom', 1200, (platform, frameno) => {
|
||||
if (frameno == 1199) {
|
||||
let s = '';
|
||||
for (let i=0; i<40; i++) {
|
||||
let c = platform.readAddress(0x722+i-40) & 0x7f;
|
||||
for (let j=0; j<1024; j+=40) {
|
||||
var s = '';
|
||||
for (let i=0; i<38; i++) {
|
||||
let c = platform.readAddress(0x402+j+i) & 0x7f;
|
||||
if (c < 0x40) c += 0x20;
|
||||
s += String.fromCharCode(c);
|
||||
}
|
||||
s = s.trim();
|
||||
assert.equal(s, "Passed: 13 Failed: 33 Skipped: 1");
|
||||
if (s.startsWith("Passed:")) break;
|
||||
}
|
||||
assert.equal(s, "Passed: 14 Failed: 32 Skipped: 1");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user