update 0.8.1
This commit is contained in:
parent
6432fdb542
commit
dd3bb23b86
24 changed files with 10461 additions and 9746 deletions
441
sae/amiga.js
441
sae/amiga.js
|
|
@ -52,58 +52,58 @@ function Amiga() {
|
|||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.setup = function() {
|
||||
this.mem.setup();
|
||||
this.expansion.setup();
|
||||
this.events.setup();
|
||||
this.playfield.setup();
|
||||
this.video.setup();
|
||||
this.cia.setup();
|
||||
this.rtc.setup();
|
||||
this.input.setup();
|
||||
this.disk.setup();
|
||||
this.audio.setup();
|
||||
this.custom.setup();
|
||||
this.cpu.setup();
|
||||
}
|
||||
this.setup = function () {
|
||||
this.mem.setup();
|
||||
this.expansion.setup();
|
||||
this.events.setup();
|
||||
this.playfield.setup();
|
||||
this.video.setup();
|
||||
this.cia.setup();
|
||||
this.rtc.setup();
|
||||
this.input.setup();
|
||||
this.disk.setup();
|
||||
this.audio.setup();
|
||||
this.custom.setup();
|
||||
this.cpu.setup();
|
||||
};
|
||||
|
||||
this.cleanup = function() {
|
||||
this.audio.cleanup();
|
||||
this.video.cleanup();
|
||||
this.playfield.cleanup();
|
||||
this.input.cleanup();
|
||||
}
|
||||
this.cleanup = function () {
|
||||
this.audio.cleanup();
|
||||
this.video.cleanup();
|
||||
this.playfield.cleanup();
|
||||
this.input.cleanup();
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
BUG.info('Amiga.reset()');
|
||||
|
||||
this.delay = 0;
|
||||
this.spcflags = 0;
|
||||
//this.loading = 0;
|
||||
|
||||
this.intena = 0;
|
||||
this.intreq = 0;
|
||||
this.dmacon = 0;
|
||||
this.adkcon = 0;
|
||||
|
||||
this.expansion.reset();
|
||||
this.events.reset();
|
||||
this.playfield.reset();
|
||||
this.cia.reset();
|
||||
this.disk.reset();
|
||||
this.input.reset();
|
||||
this.serial.reset();
|
||||
this.blitter.reset();
|
||||
this.copper.reset();
|
||||
this.audio.reset();
|
||||
this.custom.reset();
|
||||
this.cpu.reset(this.mem.rom.lower);
|
||||
}
|
||||
this.reset = function () {
|
||||
BUG.info('Amiga.reset()');
|
||||
|
||||
this.dump = function() {
|
||||
this.cpu.dump();
|
||||
//this.cia.dump();
|
||||
}
|
||||
this.delay = 0;
|
||||
this.spcflags = 0;
|
||||
//this.loading = 0;
|
||||
|
||||
this.intena = 0;
|
||||
this.intreq = 0;
|
||||
this.dmacon = 0;
|
||||
this.adkcon = 0;
|
||||
|
||||
this.expansion.reset();
|
||||
this.events.reset();
|
||||
this.playfield.reset();
|
||||
this.cia.reset();
|
||||
this.disk.reset();
|
||||
this.input.reset();
|
||||
this.serial.reset();
|
||||
this.blitter.reset();
|
||||
this.copper.reset();
|
||||
this.audio.reset();
|
||||
this.custom.reset();
|
||||
this.cpu.reset(this.mem.rom.lower);
|
||||
};
|
||||
|
||||
this.dump = function () {
|
||||
this.cpu.dump();
|
||||
//this.cia.dump();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
|
|
@ -122,28 +122,28 @@ function Amiga() {
|
|||
}*/
|
||||
|
||||
|
||||
this.start = function() {
|
||||
if (this.state == ST_STOP) {
|
||||
this.setup();
|
||||
this.reset();
|
||||
this.state = ST_CYCLE;
|
||||
setTimeout('AMIGA.cycle()', 0);
|
||||
}
|
||||
}
|
||||
this.start = function () {
|
||||
if (this.state == ST_STOP) {
|
||||
this.setup();
|
||||
this.reset();
|
||||
this.state = ST_CYCLE;
|
||||
setTimeout('AMIGA.cycle()', 0);
|
||||
}
|
||||
};
|
||||
|
||||
this.stop = function() {
|
||||
if (this.state != ST_STOP) {
|
||||
this.state = ST_STOP;
|
||||
this.cleanup();
|
||||
}
|
||||
}
|
||||
this.stop = function () {
|
||||
if (this.state != ST_STOP) {
|
||||
this.state = ST_STOP;
|
||||
this.cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
this.pause = function(state) {
|
||||
if (this.state != ST_STOP) {
|
||||
this.state = state ? ST_PAUSE : ST_CYCLE;
|
||||
this.audio.pauseResume(state);
|
||||
}
|
||||
}
|
||||
this.pause = function (state) {
|
||||
if (this.state != ST_STOP) {
|
||||
this.state = state ? ST_PAUSE : ST_CYCLE;
|
||||
this.audio.pauseResume(state);
|
||||
}
|
||||
};
|
||||
|
||||
/*this.insert = function(unit, name, data) {
|
||||
//this.disk.insert_data(unit, data);
|
||||
|
|
@ -161,194 +161,193 @@ function Amiga() {
|
|||
}
|
||||
*/
|
||||
|
||||
this.insert = function(unit) {
|
||||
if (this.state != ST_STOP)
|
||||
this.disk.insert(unit);
|
||||
}
|
||||
this.insert = function (unit) {
|
||||
if (this.state != ST_STOP)
|
||||
this.disk.insert(unit);
|
||||
};
|
||||
|
||||
this.eject = function(unit) {
|
||||
if (this.state != ST_STOP)
|
||||
this.disk.eject(unit);
|
||||
}
|
||||
this.eject = function (unit) {
|
||||
if (this.state != ST_STOP)
|
||||
this.disk.eject(unit);
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
/* mainloop */
|
||||
|
||||
this.cycle = function() {
|
||||
try {
|
||||
this.cpu.cycle();
|
||||
} catch (e) {
|
||||
if (e instanceof VSync) {
|
||||
//console.log(e.error, e.message);
|
||||
this.state = ST_IDLE;
|
||||
} else
|
||||
if (e instanceof FatalError) {
|
||||
this.state = ST_STOP;
|
||||
this.stop();
|
||||
this.config.hooks.error(e.error, e.message);
|
||||
} else /* normal exception */ {
|
||||
this.state = ST_STOP;
|
||||
this.stop();
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
if (this.state == ST_IDLE) {
|
||||
this.state = ST_CYCLE;
|
||||
setTimeout('AMIGA.cycle()', this.delay);
|
||||
}
|
||||
else if (this.state == ST_PAUSE)
|
||||
AMIGA.cyclePause();
|
||||
else
|
||||
AMIGA.cycleExit();
|
||||
}
|
||||
this.cycle = function () {
|
||||
try {
|
||||
this.cpu.cycle();
|
||||
} catch (e) {
|
||||
if (e instanceof VSync) {
|
||||
//console.log(e.error, e.message);
|
||||
this.state = ST_IDLE;
|
||||
} else if (e instanceof FatalError) {
|
||||
this.state = ST_STOP;
|
||||
this.stop();
|
||||
this.config.hooks.error(e.error, e.message);
|
||||
} else /* normal exception */ {
|
||||
this.state = ST_STOP;
|
||||
this.stop();
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
if (this.state == ST_IDLE) {
|
||||
this.state = ST_CYCLE;
|
||||
setTimeout('AMIGA.cycle()', this.delay);
|
||||
}
|
||||
else if (this.state == ST_PAUSE)
|
||||
AMIGA.cyclePause();
|
||||
else
|
||||
AMIGA.cycleExit();
|
||||
};
|
||||
|
||||
this.cyclePause = function() {
|
||||
if (this.state == ST_CYCLE)
|
||||
setTimeout('AMIGA.cycle()', 0);
|
||||
else if (this.state == ST_PAUSE)
|
||||
setTimeout('AMIGA.cyclePause()', 500);
|
||||
else
|
||||
AMIGA.cycleExit();
|
||||
}
|
||||
this.cyclePause = function () {
|
||||
if (this.state == ST_CYCLE)
|
||||
setTimeout('AMIGA.cycle()', 0);
|
||||
else if (this.state == ST_PAUSE)
|
||||
setTimeout('AMIGA.cyclePause()', 500);
|
||||
else
|
||||
AMIGA.cycleExit();
|
||||
};
|
||||
|
||||
this.cycleExit = function() {
|
||||
this.dump();
|
||||
//this.cia.dump();
|
||||
}
|
||||
this.cycleExit = function () {
|
||||
this.dump();
|
||||
//this.cia.dump();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.dmaen = function (dmamask) {
|
||||
return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0);
|
||||
}
|
||||
return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0);
|
||||
};
|
||||
|
||||
this.DMACONR = function(hpos) {
|
||||
this.playfield.decide_line(hpos);
|
||||
this.playfield.decide_fetch(hpos);
|
||||
this.dmacon &= ~(0x4000 | 0x2000);
|
||||
var iz = this.blitter.getIntZero();
|
||||
this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0));
|
||||
return this.dmacon;
|
||||
}
|
||||
this.DMACONR = function (hpos) {
|
||||
this.playfield.decide_line(hpos);
|
||||
this.playfield.decide_fetch(hpos);
|
||||
this.dmacon &= ~(0x4000 | 0x2000);
|
||||
var iz = this.blitter.getIntZero();
|
||||
this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0));
|
||||
return this.dmacon;
|
||||
};
|
||||
|
||||
this.DMACON = function (v, hpos) {
|
||||
var oldcon = this.dmacon;
|
||||
|
||||
this.playfield.decide_line(hpos);
|
||||
this.playfield.decide_fetch(hpos);
|
||||
var oldcon = this.dmacon;
|
||||
|
||||
if (v & INTF_SETCLR)
|
||||
this.dmacon |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.dmacon &= ~v;
|
||||
|
||||
this.dmacon &= 0x1fff;
|
||||
|
||||
var changed = this.dmacon ^ oldcon;
|
||||
this.playfield.decide_line(hpos);
|
||||
this.playfield.decide_fetch(hpos);
|
||||
|
||||
var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0;
|
||||
var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0;
|
||||
if (oldcop != newcop) {
|
||||
if (newcop && !oldcop) {
|
||||
this.copper.compute_spcflag_copper(this.events.hpos());
|
||||
} else if (!newcop) {
|
||||
this.copper.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
}
|
||||
}
|
||||
if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done)
|
||||
set_special(SPCFLAG_BLTNASTY);
|
||||
if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init)
|
||||
this.blitter.setState(BLT_work);
|
||||
if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN))
|
||||
clr_special(SPCFLAG_BLTNASTY);
|
||||
|
||||
if (changed & (DMAF_DMAEN | 0x0f))
|
||||
this.audio.state_machine();
|
||||
|
||||
if (changed & (DMAF_DMAEN | DMAF_BPLEN)) {
|
||||
this.playfield.update_ddf_change();
|
||||
if (this.dmaen(DMAF_BPLEN))
|
||||
this.playfield.maybe_start_bpl_dma(hpos);
|
||||
}
|
||||
this.events.schedule();
|
||||
}
|
||||
if (v & INTF_SETCLR)
|
||||
this.dmacon |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.dmacon &= ~v;
|
||||
|
||||
this.dmacon &= 0x1fff;
|
||||
|
||||
var changed = this.dmacon ^ oldcon;
|
||||
|
||||
var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0;
|
||||
var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0;
|
||||
if (oldcop != newcop) {
|
||||
if (newcop && !oldcop) {
|
||||
this.copper.compute_spcflag_copper(this.events.hpos());
|
||||
} else if (!newcop) {
|
||||
this.copper.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
}
|
||||
}
|
||||
if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done)
|
||||
set_special(SPCFLAG_BLTNASTY);
|
||||
if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init)
|
||||
this.blitter.setState(BLT_work);
|
||||
if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN))
|
||||
clr_special(SPCFLAG_BLTNASTY);
|
||||
|
||||
if (changed & (DMAF_DMAEN | 0x0f))
|
||||
this.audio.state_machine();
|
||||
|
||||
if (changed & (DMAF_DMAEN | DMAF_BPLEN)) {
|
||||
this.playfield.update_ddf_change();
|
||||
if (this.dmaen(DMAF_BPLEN))
|
||||
this.playfield.maybe_start_bpl_dma(hpos);
|
||||
}
|
||||
this.events.schedule();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.ADKCONR = function () {
|
||||
return this.adkcon;
|
||||
}
|
||||
return this.adkcon;
|
||||
};
|
||||
|
||||
this.ADKCON = function (v, hpos) {
|
||||
if (this.config.audio.enabled)
|
||||
this.audio.update();
|
||||
if (this.config.audio.enabled)
|
||||
this.audio.update();
|
||||
|
||||
this.disk.update(hpos);
|
||||
this.disk.update_adkcon(v);
|
||||
|
||||
if (v & INTF_SETCLR)
|
||||
this.adkcon |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.adkcon &= ~v;
|
||||
|
||||
this.audio.update_adkmasks();
|
||||
}
|
||||
this.disk.update(hpos);
|
||||
this.disk.update_adkcon(v);
|
||||
|
||||
if (v & INTF_SETCLR)
|
||||
this.adkcon |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.adkcon &= ~v;
|
||||
|
||||
this.audio.update_adkmasks();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.INTENAR = function () {
|
||||
return this.intena;
|
||||
}
|
||||
return this.intena;
|
||||
};
|
||||
|
||||
this.INTENA = function(v) {
|
||||
if (v & INTF_SETCLR)
|
||||
this.intena |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.intena &= ~v;
|
||||
this.INTENA = function (v) {
|
||||
if (v & INTF_SETCLR)
|
||||
this.intena |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.intena &= ~v;
|
||||
|
||||
if (v & INTF_SETCLR)
|
||||
this.doint();
|
||||
}
|
||||
if (v & INTF_SETCLR)
|
||||
this.doint();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.INTREQR = function () {
|
||||
return this.intreq;
|
||||
}
|
||||
return this.intreq;
|
||||
};
|
||||
|
||||
this.INTREQ_0 = function(v) {
|
||||
var old = this.intreq;
|
||||
|
||||
if (v & INTF_SETCLR)
|
||||
this.intreq |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.intreq &= ~v;
|
||||
this.INTREQ_0 = function (v) {
|
||||
var old = this.intreq;
|
||||
|
||||
if ((v & INTF_SETCLR) && this.intreq != old)
|
||||
this.doint();
|
||||
}
|
||||
if (v & INTF_SETCLR)
|
||||
this.intreq |= v & ~INTF_SETCLR;
|
||||
else
|
||||
this.intreq &= ~v;
|
||||
|
||||
this.INTREQ = function(v) {
|
||||
this.INTREQ_0(v);
|
||||
this.cia.rethink();
|
||||
}
|
||||
if ((v & INTF_SETCLR) && this.intreq != old)
|
||||
this.doint();
|
||||
};
|
||||
|
||||
this.INTREQ = function (v) {
|
||||
this.INTREQ_0(v);
|
||||
this.cia.rethink();
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.intlev = function() {
|
||||
var imask = this.intreq & this.intena;
|
||||
this.intlev = function () {
|
||||
var imask = this.intreq & this.intena;
|
||||
|
||||
if (imask && (this.intena & INTF_INTEN)) {
|
||||
if (imask & 0x2000) return 6;
|
||||
if (imask & 0x1800) return 5;
|
||||
if (imask & 0x0780) return 4;
|
||||
if (imask & 0x0070) return 3;
|
||||
if (imask & 0x0008) return 2;
|
||||
if (imask & 0x0007) return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (imask && (this.intena & INTF_INTEN)) {
|
||||
if (imask & 0x2000) return 6;
|
||||
if (imask & 0x1800) return 5;
|
||||
if (imask & 0x0780) return 4;
|
||||
if (imask & 0x0070) return 3;
|
||||
if (imask & 0x0008) return 2;
|
||||
if (imask & 0x0007) return 1;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
this.doint = function() {
|
||||
if (AMIGA.config.cpu.compatible)
|
||||
|
|
@ -361,6 +360,9 @@ function Amiga() {
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* This API will change in the future. */
|
||||
|
||||
var BUG = null;
|
||||
var AMIGA = null;
|
||||
|
||||
function SAE(x) {
|
||||
try {
|
||||
switch (x.cmd) {
|
||||
|
|
@ -383,10 +385,6 @@ function SAE(x) {
|
|||
BUG.info('API.stop()');
|
||||
AMIGA.stop();
|
||||
break;
|
||||
case 'reset':
|
||||
BUG.info('API.reset()');
|
||||
AMIGA.reset();
|
||||
break;
|
||||
case 'pause':
|
||||
BUG.info('API.pause() %d', x.state);
|
||||
AMIGA.pause(x.state);
|
||||
|
|
@ -424,4 +422,5 @@ function SAE(x) {
|
|||
}
|
||||
//return SAEE_None;
|
||||
//return { error:SAEE_None, message:'' };
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
1175
sae/audio.js
1175
sae/audio.js
File diff suppressed because it is too large
Load diff
404
sae/blitter.js
404
sae/blitter.js
|
|
@ -52,8 +52,8 @@ function Blitter() {
|
|||
[0 ] /* F */
|
||||
];
|
||||
const blit_cycle_diagram_line = [4, 0,3,5,4, 0,3,5,4];
|
||||
const blit_cycle_diagram_finald = [2, 0,4, 0,4];
|
||||
const blit_cycle_diagram_finalld = [2, 0,0, 0,0];
|
||||
//const blit_cycle_diagram_finald = [2, 0,4, 0,4];
|
||||
//const blit_cycle_diagram_finalld = [2, 0,0, 0,0];
|
||||
|
||||
var blit_filltable = [];
|
||||
var blit_masktable = [];
|
||||
|
|
@ -84,8 +84,7 @@ function Blitter() {
|
|||
var blinea = 0, blineb = 0;
|
||||
var blitline = 0, blitfc = 0, blitfill = 0, blitife = 0, blitsing = 0, blitdesc = 0;
|
||||
var blitonedot = 0, blitsign = 0, blitlinepixel = 0;
|
||||
|
||||
var ddat1 = 0, ddat2 = 0;
|
||||
|
||||
var ddat1use = 0, ddat2use = 0;
|
||||
var last_blitter_hpos = 0;
|
||||
|
||||
|
|
@ -101,7 +100,7 @@ function Blitter() {
|
|||
|
||||
//function build_blitfilltable()
|
||||
{
|
||||
var blit_masktable = new Uint16Array(BLITTER_MAX_WORDS);
|
||||
blit_masktable = new Uint16Array(BLITTER_MAX_WORDS);
|
||||
for (var i = 0; i < BLITTER_MAX_WORDS; i++)
|
||||
blit_masktable[i] = 0xffff;
|
||||
|
||||
|
|
@ -130,18 +129,18 @@ function Blitter() {
|
|||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.reset = function() {
|
||||
bltstate = BLT_done;
|
||||
blit_interrupt = true;
|
||||
blit_stuck = 0;
|
||||
}
|
||||
this.reset = function () {
|
||||
bltstate = BLT_done;
|
||||
blit_interrupt = true;
|
||||
blit_stuck = 0;
|
||||
};
|
||||
|
||||
function blitter_dump() {
|
||||
/*function blitter_dump() {
|
||||
BUG.info('PT A=%08X B=%08X C=%08X D=%08X', bltapt, bltbpt, bltcpt, bltdpt);
|
||||
BUG.info('CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X', bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat);
|
||||
//BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff);
|
||||
BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod, blt_info.bltbmod, blt_info.bltcmod, blt_info.bltdmod);
|
||||
}
|
||||
}*/
|
||||
|
||||
function castWord(v) {
|
||||
return (v & 0x8000) ? (v - 0x10000) : v;
|
||||
|
|
@ -167,7 +166,7 @@ function Blitter() {
|
|||
return diag[1 + diag[0] + cycles];
|
||||
}
|
||||
|
||||
function channel_pos(cycles) {
|
||||
/*function channel_pos(cycles) {
|
||||
if (cycles < 0)
|
||||
return 0;
|
||||
var diag = get_ch();
|
||||
|
|
@ -176,7 +175,7 @@ function Blitter() {
|
|||
cycles -= diag[0];
|
||||
cycles %= diag[0];
|
||||
return cycles;
|
||||
}
|
||||
}*/
|
||||
|
||||
function blitter_interrupt() {
|
||||
if (blit_interrupt)
|
||||
|
|
@ -2012,6 +2011,7 @@ function Blitter() {
|
|||
case 0xfd: return (~c) | (b) | (a);
|
||||
case 0xfe: return (c) | (b) | (a);
|
||||
case 0xff: return 0xffff;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2217,7 +2217,7 @@ function Blitter() {
|
|||
if (bltcon0 & 0x200) {
|
||||
if (AMIGA.dmaen(DMAF_BLTEN))
|
||||
//blt_info.bltcdat = AMIGA.mem.load16_chip(bltcpt);
|
||||
blt_info.bltcdat = dat = AMIGA.mem.chip.data[bltcpt >>> 1];
|
||||
blt_info.bltcdat = AMIGA.mem.chip.data[bltcpt >>> 1];
|
||||
}
|
||||
bltstate = BLT_work;
|
||||
}
|
||||
|
|
@ -2382,7 +2382,7 @@ function Blitter() {
|
|||
if (blt_info.vblitsize <= 0)
|
||||
bltstate = BLT_done;
|
||||
} while (bltstate != BLT_done);
|
||||
bltapt_line = null;
|
||||
//bltapt_line = null;
|
||||
bltdpt = bltcpt;
|
||||
} else {
|
||||
if (blitdesc)
|
||||
|
|
@ -2400,26 +2400,26 @@ function Blitter() {
|
|||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.handler = function(data) {
|
||||
if (!AMIGA.dmaen(DMAF_BLTEN)) {
|
||||
AMIGA.events.newevent(EV2_BLITTER, 10, 0);
|
||||
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
|
||||
return;
|
||||
this.handler = function (data) {
|
||||
if (!AMIGA.dmaen(DMAF_BLTEN)) {
|
||||
AMIGA.events.newevent(EV2_BLITTER, 10, 0);
|
||||
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
|
||||
return;
|
||||
|
||||
BUG.info('blitter_handler() force-unstuck!');
|
||||
}
|
||||
blit_stuck = 0;
|
||||
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
|
||||
//console.log('Blitter.handler () slowdown', blit_slowdown);
|
||||
AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
|
||||
blit_slowdown = -1;
|
||||
return;
|
||||
}
|
||||
blitter_do();
|
||||
}
|
||||
BUG.info('blitter_handler() force-unstuck!');
|
||||
}
|
||||
blit_stuck = 0;
|
||||
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
|
||||
//console.log('Blitter.handler () slowdown', blit_slowdown);
|
||||
AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
|
||||
blit_slowdown = -1;
|
||||
return;
|
||||
}
|
||||
blitter_do();
|
||||
};
|
||||
|
||||
var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0;
|
||||
var freezes = 10;
|
||||
//var freezes = 10;
|
||||
function blit_bltset(con) {
|
||||
if (con & 2) {
|
||||
blitdesc = bltcon1 & 2;
|
||||
|
|
@ -2518,9 +2518,8 @@ function Blitter() {
|
|||
warned1--;
|
||||
BUG.info('waiting_blits detected');
|
||||
}
|
||||
if (bltstate == BLT_done)
|
||||
return true;
|
||||
return false;
|
||||
return bltstate == BLT_done;
|
||||
|
||||
}
|
||||
|
||||
function do_blitter(hpos, copper) {
|
||||
|
|
@ -2533,17 +2532,12 @@ function Blitter() {
|
|||
cleanstart = 1;
|
||||
}
|
||||
|
||||
bltstate = BLT_done;
|
||||
|
||||
blt_info.blitzero = 1;
|
||||
preva = 0;
|
||||
prevb = 0;
|
||||
blt_info.got_cycle = 0;
|
||||
|
||||
blit_firstline_cycles = blit_first_cycle = AMIGA.events.currcycle;
|
||||
blit_last_cycle = 0;
|
||||
last_blitter_hpos = hpos + 1;
|
||||
blit_cyclecounter = 0;
|
||||
|
||||
blit_bltset(1 | 2);
|
||||
ddat1use = ddat2use = 0;
|
||||
|
|
@ -2615,164 +2609,228 @@ function Blitter() {
|
|||
}
|
||||
|
||||
var warned2 = 10;
|
||||
this.maybe_blit = function(hpos, hack) {
|
||||
if (bltstate == BLT_done)
|
||||
return;
|
||||
this.maybe_blit = function (hpos, hack) {
|
||||
if (bltstate == BLT_done)
|
||||
return;
|
||||
|
||||
if (AMIGA.dmaen(DMAF_BLTEN)) {
|
||||
var doit = false;
|
||||
if (AMIGA.config.blitter.waiting == 3) { // always
|
||||
doit = true;
|
||||
} else if (AMIGA.config.blitter.waiting == 2) { // no idle
|
||||
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
|
||||
doit = true;
|
||||
} else if (AMIGA.config.blitter.waiting == 1) { // automatic
|
||||
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
|
||||
doit = true;
|
||||
else if (AMIGA.config.cpu.speed < 0)
|
||||
doit = true;
|
||||
}
|
||||
if (doit) {
|
||||
if (waitingblits())
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (AMIGA.dmaen(DMAF_BLTEN)) {
|
||||
var doit = false;
|
||||
if (AMIGA.config.blitter.waiting == 3) { // always
|
||||
doit = true;
|
||||
} else if (AMIGA.config.blitter.waiting == 2) { // no idle
|
||||
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
|
||||
doit = true;
|
||||
} else if (AMIGA.config.blitter.waiting == 1) { // automatic
|
||||
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
|
||||
doit = true;
|
||||
else if (AMIGA.config.cpu.speed < 0)
|
||||
doit = true;
|
||||
}
|
||||
if (doit) {
|
||||
if (waitingblits())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) {
|
||||
warned2--;
|
||||
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
|
||||
}
|
||||
if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) {
|
||||
warned2--;
|
||||
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
|
||||
}
|
||||
|
||||
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
|
||||
return;
|
||||
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
|
||||
return;
|
||||
|
||||
AMIGA.blitter.handler(0);
|
||||
}
|
||||
AMIGA.blitter.handler(0);
|
||||
};
|
||||
|
||||
this.blitnasty = function() {
|
||||
if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
|
||||
return 0;
|
||||
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
|
||||
return 0;
|
||||
this.blitnasty = function () {
|
||||
if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
|
||||
return 0;
|
||||
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
|
||||
return 0;
|
||||
|
||||
var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
|
||||
var ccnt = 0;
|
||||
while (blit_last_cycle < cycles) {
|
||||
if (!channel_state(blit_last_cycle++))
|
||||
ccnt++;
|
||||
}
|
||||
return ccnt;
|
||||
}
|
||||
var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
|
||||
var ccnt = 0;
|
||||
while (blit_last_cycle < cycles) {
|
||||
if (!channel_state(blit_last_cycle++))
|
||||
ccnt++;
|
||||
}
|
||||
return ccnt;
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0;
|
||||
this.slowdown = function() {
|
||||
var data = AMIGA.playfield.getData();
|
||||
var ddfstrt = data[0];
|
||||
var ddfstop = data[1];
|
||||
var totalcycles = data[2];
|
||||
var freecycles = data[3];
|
||||
this.slowdown = function () {
|
||||
var data = AMIGA.playfield.getData();
|
||||
var ddfstrt = data[0];
|
||||
var ddfstop = data[1];
|
||||
var totalcycles = data[2];
|
||||
var freecycles = data[3];
|
||||
|
||||
if (!totalcycles || ddfstrt < 0 || ddfstop < 0)
|
||||
return;
|
||||
if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) {
|
||||
var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles);
|
||||
var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles);
|
||||
var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]);
|
||||
|
||||
oddfstrt = ddfstrt;
|
||||
oddfstop = ddfstop;
|
||||
ototal = totalcycles;
|
||||
ofree = freecycles;
|
||||
slow = 0;
|
||||
if (dmacycles > freelinecycles)
|
||||
slow = dmacycles - freelinecycles;
|
||||
}
|
||||
if (blit_slowdown < 0 || blitline)
|
||||
return;
|
||||
|
||||
blit_slowdown += slow;
|
||||
}
|
||||
if (!totalcycles || ddfstrt < 0 || ddfstop < 0)
|
||||
return;
|
||||
if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) {
|
||||
var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles);
|
||||
var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles);
|
||||
var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]);
|
||||
|
||||
oddfstrt = ddfstrt;
|
||||
oddfstop = ddfstop;
|
||||
ototal = totalcycles;
|
||||
ofree = freecycles;
|
||||
slow = 0;
|
||||
if (dmacycles > freelinecycles)
|
||||
slow = dmacycles - freelinecycles;
|
||||
}
|
||||
if (blit_slowdown < 0 || blitline)
|
||||
return;
|
||||
|
||||
blit_slowdown += slow;
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.BLTADAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltadat = v; }
|
||||
this.BLTBDAT = function(hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
if (bltcon1 & 2)
|
||||
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
|
||||
else
|
||||
blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff;
|
||||
this.BLTADAT = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.bltadat = v;
|
||||
};
|
||||
this.BLTBDAT = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
if (bltcon1 & 2)
|
||||
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
|
||||
else
|
||||
blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff;
|
||||
|
||||
blt_info.bltbdat = v;
|
||||
}
|
||||
this.BLTCDAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); }
|
||||
blt_info.bltbdat = v;
|
||||
};
|
||||
this.BLTCDAT = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.bltcdat = v;
|
||||
reset_blit(0);
|
||||
};
|
||||
|
||||
this.BLTAMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltamod = castWord(v & 0xfffe); reset_blit(0); }
|
||||
this.BLTBMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltbmod = castWord(v & 0xfffe); reset_blit(0); }
|
||||
this.BLTCMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltcmod = castWord(v & 0xfffe); reset_blit(0); }
|
||||
this.BLTDMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltdmod = castWord(v & 0xfffe); reset_blit(0); }
|
||||
this.BLTAMOD = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 1);
|
||||
blt_info.bltamod = castWord(v & 0xfffe);
|
||||
reset_blit(0);
|
||||
};
|
||||
this.BLTBMOD = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 1);
|
||||
blt_info.bltbmod = castWord(v & 0xfffe);
|
||||
reset_blit(0);
|
||||
};
|
||||
this.BLTCMOD = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 1);
|
||||
blt_info.bltcmod = castWord(v & 0xfffe);
|
||||
reset_blit(0);
|
||||
};
|
||||
this.BLTDMOD = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 1);
|
||||
blt_info.bltdmod = castWord(v & 0xfffe);
|
||||
reset_blit(0);
|
||||
};
|
||||
|
||||
this.BLTCON0 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); }
|
||||
this.BLTCON0L = function( hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
|
||||
reset_blit(1);
|
||||
}
|
||||
this.BLTCON1 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); }
|
||||
this.BLTCON0 = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 2);
|
||||
bltcon0 = v;
|
||||
reset_blit(1);
|
||||
};
|
||||
this.BLTCON0L = function (hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 2);
|
||||
bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
|
||||
reset_blit(1);
|
||||
};
|
||||
this.BLTCON1 = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 2);
|
||||
bltcon1 = v;
|
||||
reset_blit(2);
|
||||
};
|
||||
|
||||
this.BLTAFWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltafwm = v; reset_blit(0); }
|
||||
this.BLTALWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltalwm = v; reset_blit(0); }
|
||||
this.BLTAFWM = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 2);
|
||||
blt_info.bltafwm = v;
|
||||
reset_blit(0);
|
||||
};
|
||||
this.BLTALWM = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 2);
|
||||
blt_info.bltalwm = v;
|
||||
reset_blit(0);
|
||||
};
|
||||
|
||||
this.BLTAPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; }
|
||||
this.BLTAPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; }
|
||||
this.BLTBPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; }
|
||||
this.BLTBPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
|
||||
this.BLTCPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; }
|
||||
this.BLTCPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
|
||||
this.BLTDPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; }
|
||||
this.BLTDPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
|
||||
this.BLTAPTH = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0;
|
||||
};
|
||||
this.BLTAPTL = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
this.BLTBPTH = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0;
|
||||
};
|
||||
this.BLTBPTL = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
this.BLTCPTH = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0;
|
||||
};
|
||||
this.BLTCPTL = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
this.BLTDPTH = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0;
|
||||
};
|
||||
this.BLTDPTL = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
|
||||
this.BLTSIZE = function(hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
this.BLTSIZE = function (hpos, v) {
|
||||
this.maybe_blit(hpos, 0);
|
||||
|
||||
blt_info.vblitsize = v >> 6;
|
||||
blt_info.hblitsize = v & 0x3F;
|
||||
if (!blt_info.vblitsize)
|
||||
blt_info.vblitsize = 1024;
|
||||
if (!blt_info.hblitsize)
|
||||
blt_info.hblitsize = 64;
|
||||
|
||||
do_blitter(hpos, AMIGA.copper.access);
|
||||
}
|
||||
blt_info.vblitsize = v >> 6;
|
||||
blt_info.hblitsize = v & 0x3F;
|
||||
if (!blt_info.vblitsize)
|
||||
blt_info.vblitsize = 1024;
|
||||
if (!blt_info.hblitsize)
|
||||
blt_info.hblitsize = 64;
|
||||
|
||||
this.BLTSIZV = function(hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.vblitsize = v & 0x7FFF;
|
||||
}
|
||||
do_blitter(hpos, AMIGA.copper.access);
|
||||
};
|
||||
|
||||
this.BLTSIZH = function(hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.hblitsize = v & 0x7FF;
|
||||
if (!blt_info.vblitsize)
|
||||
blt_info.vblitsize = 0x8000;
|
||||
if (!blt_info.hblitsize)
|
||||
blt_info.hblitsize = 0x0800;
|
||||
|
||||
do_blitter(hpos, AMIGA.copper.access);
|
||||
}
|
||||
this.BLTSIZV = function (hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.vblitsize = v & 0x7FFF;
|
||||
};
|
||||
|
||||
this.BLTSIZH = function (hpos, v) {
|
||||
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
|
||||
this.maybe_blit(hpos, 0);
|
||||
blt_info.hblitsize = v & 0x7FF;
|
||||
if (!blt_info.vblitsize)
|
||||
blt_info.vblitsize = 0x8000;
|
||||
if (!blt_info.hblitsize)
|
||||
blt_info.hblitsize = 0x0800;
|
||||
|
||||
do_blitter(hpos, AMIGA.copper.access);
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.getState = function() {
|
||||
return bltstate;
|
||||
}
|
||||
this.setState = function(s) {
|
||||
bltstate = s;
|
||||
}
|
||||
this.getState = function () {
|
||||
return bltstate;
|
||||
};
|
||||
this.setState = function (s) {
|
||||
bltstate = s;
|
||||
};
|
||||
this.getIntZero = function() {
|
||||
return [blit_interrupt, blt_info.blitzero];
|
||||
}
|
||||
|
|
|
|||
475
sae/cia.js
475
sae/cia.js
|
|
@ -11,13 +11,13 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
const CIAA_DEBUG_R = 0;
|
||||
/*const CIAA_DEBUG_R = 0;
|
||||
const CIAA_DEBUG_W = 0;
|
||||
const CIAB_DEBUG_R = 0;
|
||||
const CIAB_DEBUG_W = 0;
|
||||
const DONGLE_DEBUG = 0;
|
||||
const KB_DEBUG = 0;
|
||||
const CLOCK_DEBUG = 0;
|
||||
const CLOCK_DEBUG = 0;*/
|
||||
|
||||
const TOD_HACK = 1;
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ function CIA() {
|
|||
var div10 = 0;
|
||||
//var kbstate = 0, kblostsynccnt = 0, kbcode = 0;
|
||||
|
||||
var serbits = 0;
|
||||
//var serbits = 0;
|
||||
var warned = 10;
|
||||
//var rtc_delayed_write = 0;
|
||||
|
||||
|
|
@ -101,23 +101,23 @@ function CIA() {
|
|||
}
|
||||
}
|
||||
|
||||
this.SetICRA = function(icr, sdr) {
|
||||
ciaaicr |= icr;
|
||||
ciaasdr = sdr;
|
||||
RethinkICRA();
|
||||
}
|
||||
this.SetICRA = function (icr, sdr) {
|
||||
ciaaicr |= icr;
|
||||
ciaasdr = sdr;
|
||||
RethinkICRA();
|
||||
};
|
||||
|
||||
this.SetICRB = function(icr, sdr) {
|
||||
ciabicr |= icr;
|
||||
if (sdr !== null)
|
||||
ciabsdr = sdr;
|
||||
RethinkICRB();
|
||||
}
|
||||
this.SetICRB = function (icr, sdr) {
|
||||
ciabicr |= icr;
|
||||
if (sdr !== null)
|
||||
ciabsdr = sdr;
|
||||
RethinkICRB();
|
||||
};
|
||||
|
||||
this.rethink = function() {
|
||||
RethinkICRA();
|
||||
RethinkICRB();
|
||||
}
|
||||
this.rethink = function () {
|
||||
RethinkICRA();
|
||||
RethinkICRB();
|
||||
};
|
||||
|
||||
/* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */
|
||||
function compute_passed_time() {
|
||||
|
|
@ -343,10 +343,10 @@ function CIA() {
|
|||
AMIGA.events.schedule();
|
||||
}
|
||||
|
||||
this.handler = function() {
|
||||
CIA_update();
|
||||
CIA_calctimers();
|
||||
}
|
||||
this.handler = function () {
|
||||
CIA_update();
|
||||
CIA_calctimers();
|
||||
};
|
||||
|
||||
/*this.diskindex = function() {
|
||||
ciabicr |= 0x10;
|
||||
|
|
@ -476,41 +476,41 @@ function CIA() {
|
|||
|
||||
//this.hsync_prehandler = function() {}
|
||||
|
||||
this.hsync_posthandler = function(dotod) {
|
||||
if (ciabtodon && dotod) {
|
||||
ciabtod++;
|
||||
ciabtod &= 0xFFFFFF;
|
||||
ciab_checkalarm(1);
|
||||
}
|
||||
if (AMIGA.config.cia.tod_hack && ciaatodon)
|
||||
do_tod_hack(dotod);
|
||||
this.hsync_posthandler = function (dotod) {
|
||||
if (ciabtodon && dotod) {
|
||||
ciabtod++;
|
||||
ciabtod &= 0xFFFFFF;
|
||||
ciab_checkalarm(1);
|
||||
}
|
||||
if (AMIGA.config.cia.tod_hack && ciaatodon)
|
||||
do_tod_hack(dotod);
|
||||
|
||||
/*if (resetwarning_phase) {
|
||||
resetwarning_check ();
|
||||
while (keys_available ())
|
||||
get_next_key ();
|
||||
} else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
|
||||
switch (kbstate) {
|
||||
case 0:
|
||||
kbcode = 0;
|
||||
kbstate++;
|
||||
break;
|
||||
case 1:
|
||||
setcode(AK_INIT_POWERUP);
|
||||
kbstate++;
|
||||
break;
|
||||
case 2:
|
||||
setcode(AK_TERM_POWERUP);
|
||||
kbstate++;
|
||||
break;
|
||||
case 3:
|
||||
kbcode = ~get_next_key();
|
||||
break;
|
||||
}
|
||||
keyreq();
|
||||
}*/
|
||||
AMIGA.input.keyboard.hsync();
|
||||
}
|
||||
/*if (resetwarning_phase) {
|
||||
resetwarning_check ();
|
||||
while (keys_available ())
|
||||
get_next_key ();
|
||||
} else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
|
||||
switch (kbstate) {
|
||||
case 0:
|
||||
kbcode = 0;
|
||||
kbstate++;
|
||||
break;
|
||||
case 1:
|
||||
setcode(AK_INIT_POWERUP);
|
||||
kbstate++;
|
||||
break;
|
||||
case 2:
|
||||
setcode(AK_TERM_POWERUP);
|
||||
kbstate++;
|
||||
break;
|
||||
case 3:
|
||||
kbcode = ~get_next_key();
|
||||
break;
|
||||
}
|
||||
keyreq();
|
||||
}*/
|
||||
AMIGA.input.keyboard.hsync();
|
||||
};
|
||||
|
||||
function calc_led(old_led) {
|
||||
var c = AMIGA.events.currcycle;
|
||||
|
|
@ -560,43 +560,43 @@ function CIA() {
|
|||
led_cycles_off = 0;
|
||||
}
|
||||
|
||||
this.vsync_prehandler = function() {
|
||||
/*if (rtc_delayed_write < 0) {
|
||||
rtc_delayed_write = 50;
|
||||
} else if (rtc_delayed_write > 0) {
|
||||
rtc_delayed_write--;
|
||||
if (rtc_delayed_write == 0)
|
||||
write_battclock ();
|
||||
}*/
|
||||
led_vsync();
|
||||
this.handler();
|
||||
/*if (kblostsynccnt > 0) {
|
||||
kblostsynccnt -= maxvpos;
|
||||
if (kblostsynccnt <= 0) {
|
||||
kblostsynccnt = 0;
|
||||
keyreq ();
|
||||
write_log (_T('lostsync\n'));
|
||||
}
|
||||
}*/
|
||||
AMIGA.input.keyboard.vsync();
|
||||
}
|
||||
this.vsync_prehandler = function () {
|
||||
/*if (rtc_delayed_write < 0) {
|
||||
rtc_delayed_write = 50;
|
||||
} else if (rtc_delayed_write > 0) {
|
||||
rtc_delayed_write--;
|
||||
if (rtc_delayed_write == 0)
|
||||
write_battclock ();
|
||||
}*/
|
||||
led_vsync();
|
||||
this.handler();
|
||||
/*if (kblostsynccnt > 0) {
|
||||
kblostsynccnt -= maxvpos;
|
||||
if (kblostsynccnt <= 0) {
|
||||
kblostsynccnt = 0;
|
||||
keyreq ();
|
||||
write_log (_T('lostsync\n'));
|
||||
}
|
||||
}*/
|
||||
AMIGA.input.keyboard.vsync();
|
||||
};
|
||||
|
||||
this.vsync_posthandler = function(dotod) {
|
||||
//if (heartbeat_cnt > 0) heartbeat_cnt--;
|
||||
if (TOD_HACK) {
|
||||
if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1)
|
||||
return;
|
||||
}
|
||||
if (ciaatodon && dotod) {
|
||||
ciaatod++;
|
||||
ciaatod &= 0xFFFFFF;
|
||||
ciaa_checkalarm (1);
|
||||
}
|
||||
/*if (vpos == 0) {
|
||||
write_log ('%d', vsync_counter);
|
||||
this.dump();
|
||||
}*/
|
||||
}
|
||||
this.vsync_posthandler = function (dotod) {
|
||||
//if (heartbeat_cnt > 0) heartbeat_cnt--;
|
||||
if (TOD_HACK) {
|
||||
if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1)
|
||||
return;
|
||||
}
|
||||
if (ciaatodon && dotod) {
|
||||
ciaatod++;
|
||||
ciaatod &= 0xFFFFFF;
|
||||
ciaa_checkalarm(1);
|
||||
}
|
||||
/*if (vpos == 0) {
|
||||
write_log ('%d', vsync_counter);
|
||||
this.dump();
|
||||
}*/
|
||||
};
|
||||
|
||||
function bfe001_change() {
|
||||
var v = ciaapra;
|
||||
|
|
@ -782,7 +782,7 @@ function CIA() {
|
|||
}
|
||||
return tmp;
|
||||
case 1:
|
||||
if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0));
|
||||
//if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0));
|
||||
tmp = ciabprb;
|
||||
//tmp = dongle_cia_read(1, reg, tmp);
|
||||
if (ciabcrb & 2) {
|
||||
|
|
@ -790,14 +790,14 @@ function CIA() {
|
|||
if (ciabcrb & 4)
|
||||
pb7 = ciabcrb & 1;
|
||||
tmp &= ~0x80;
|
||||
tmp |= pb7 ? 0x80 : 00;
|
||||
tmp |= pb7 ? 0x80 : 0;
|
||||
}
|
||||
if (ciabcra & 2) {
|
||||
var pb6 = 0;
|
||||
if (ciabcra & 4)
|
||||
pb6 = ciabcra & 1;
|
||||
tmp &= ~0x40;
|
||||
tmp |= pb6 ? 0x40 : 00;
|
||||
tmp |= pb6 ? 0x40 : 0;
|
||||
}
|
||||
return tmp;
|
||||
case 2:
|
||||
|
|
@ -993,7 +993,7 @@ function CIA() {
|
|||
//if ((addr >= 8 && addr <= 10) || CIAB_DEBUG_W > 1) write_log (_T('W_CIAB: bfd%x00 %02X %08X\n'), reg, val, M68K_GETPC);
|
||||
switch (reg) {
|
||||
case 0:
|
||||
if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0));
|
||||
//if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0));
|
||||
//dongle_cia_write (1, reg, val);
|
||||
ciabpra = val;
|
||||
//if (currprefs.use_serial)
|
||||
|
|
@ -1117,52 +1117,59 @@ function CIA() {
|
|||
}
|
||||
}
|
||||
|
||||
this.setup = function() {}
|
||||
this.setup = function () {
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
if (TOD_HACK) {
|
||||
tod_hack_tv = 0;
|
||||
tod_hack_tod = 0;
|
||||
tod_hack_enabled = 0;
|
||||
if (AMIGA.config.cia.tod_hack)
|
||||
tod_hack_enabled = TOD_HACK_TIME;
|
||||
}
|
||||
//kblostsynccnt = 0;
|
||||
//serbits = 0;
|
||||
//oldcd32mute = 1;
|
||||
oldled = true;
|
||||
//resetwarning_phase = resetwarning_timer = 0;
|
||||
//heartbeat_cnt = 0;
|
||||
this.reset = function () {
|
||||
if (TOD_HACK) {
|
||||
tod_hack_tv = 0;
|
||||
tod_hack_tod = 0;
|
||||
tod_hack_enabled = 0;
|
||||
if (AMIGA.config.cia.tod_hack)
|
||||
tod_hack_enabled = TOD_HACK_TIME;
|
||||
}
|
||||
//kblostsynccnt = 0;
|
||||
//serbits = 0;
|
||||
//oldcd32mute = 1;
|
||||
oldled = true;
|
||||
//resetwarning_phase = resetwarning_timer = 0;
|
||||
//heartbeat_cnt = 0;
|
||||
|
||||
//oldovl = true;
|
||||
//kbstate = 0;
|
||||
ciaatlatch = ciabtlatch = 0;
|
||||
ciaapra = 0; ciaadra = 0;
|
||||
ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
|
||||
ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
|
||||
ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
|
||||
ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
|
||||
ciaaalarm = ciabalarm = 0;
|
||||
ciabpra = 0x8C; ciabdra = 0;
|
||||
div10 = 0;
|
||||
ciaasdr_cnt = 0; ciaasdr = 0;
|
||||
ciabsdr_cnt = 0; ciabsdr = 0;
|
||||
ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
|
||||
|
||||
CIA_calctimers();
|
||||
AMIGA.disk.select_set(ciabprb);
|
||||
//oldovl = true;
|
||||
//kbstate = 0;
|
||||
ciaatlatch = ciabtlatch = 0;
|
||||
ciaapra = 0;
|
||||
ciaadra = 0;
|
||||
ciaatod = ciabtod = 0;
|
||||
ciaatodon = ciabtodon = 0;
|
||||
ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
|
||||
ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4;
|
||||
/* outmode = toggle; */
|
||||
ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
|
||||
ciaaalarm = ciabalarm = 0;
|
||||
ciabpra = 0x8C;
|
||||
ciabdra = 0;
|
||||
div10 = 0;
|
||||
ciaasdr_cnt = 0;
|
||||
ciaasdr = 0;
|
||||
ciabsdr_cnt = 0;
|
||||
ciabsdr = 0;
|
||||
ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
|
||||
|
||||
//map_overlay (0);
|
||||
|
||||
//if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */
|
||||
}
|
||||
CIA_calctimers();
|
||||
AMIGA.disk.select_set(ciabprb);
|
||||
|
||||
this.dump = function() {
|
||||
BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
|
||||
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV);
|
||||
BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
|
||||
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV);
|
||||
}
|
||||
//map_overlay (0);
|
||||
|
||||
//if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */
|
||||
};
|
||||
|
||||
this.dump = function () {
|
||||
BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
|
||||
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV);
|
||||
BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
|
||||
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV);
|
||||
};
|
||||
|
||||
// Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected
|
||||
// Old Gary based Amigas enable both CIAs in this situation
|
||||
|
|
@ -1203,115 +1210,117 @@ function CIA() {
|
|||
return mask == 0xe000 || mask == 0xd000;
|
||||
}
|
||||
|
||||
this.load8 = function(addr) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var v = 0xff;
|
||||
this.load8 = function (addr) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var v = 0xff;
|
||||
|
||||
if (!isgaylenocia(addr))
|
||||
return v;
|
||||
if (!isgaylenocia(addr))
|
||||
return v;
|
||||
|
||||
cia_wait_pre();
|
||||
switch ((addr >> 12) & 3) {
|
||||
case 0:
|
||||
if (!issinglecia())
|
||||
v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
|
||||
break;
|
||||
case 1:
|
||||
v = (addr & 1) ? 0xff : ReadCIAB(r);
|
||||
break;
|
||||
case 2:
|
||||
v = (addr & 1) ? ReadCIAA(r) : 0xff;
|
||||
break;
|
||||
case 3: {
|
||||
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
|
||||
if (warned > 0) {
|
||||
BUG.info('cia_bget: unknown CIA address %x', addr);
|
||||
warned--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
cia_wait_post(v);
|
||||
return v;
|
||||
}
|
||||
cia_wait_pre();
|
||||
switch ((addr >> 12) & 3) {
|
||||
case 0:
|
||||
if (!issinglecia())
|
||||
v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
|
||||
break;
|
||||
case 1:
|
||||
v = (addr & 1) ? 0xff : ReadCIAB(r);
|
||||
break;
|
||||
case 2:
|
||||
v = (addr & 1) ? ReadCIAA(r) : 0xff;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
|
||||
if (warned > 0) {
|
||||
BUG.info('cia_bget: unknown CIA address %x', addr);
|
||||
warned--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
cia_wait_post(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
this.load16 = function(addr) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var v = 0xffff;
|
||||
this.load16 = function (addr) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var v = 0xffff;
|
||||
|
||||
if (!isgaylenocia(addr))
|
||||
return v;
|
||||
if (!isgaylenocia(addr))
|
||||
return v;
|
||||
|
||||
cia_wait_pre();
|
||||
switch ((addr >> 12) & 3) {
|
||||
case 0:
|
||||
if (!issinglecia())
|
||||
v = (ReadCIAB(r) << 8) | ReadCIAA(r);
|
||||
break;
|
||||
case 1:
|
||||
v = (ReadCIAB(r) << 8) | 0xff;
|
||||
break;
|
||||
case 2:
|
||||
v = (0xff << 8) | ReadCIAA(r);
|
||||
break;
|
||||
case 3: {
|
||||
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
|
||||
if (warned > 0) {
|
||||
BUG.info('cia_wget: unknown CIA address %x', addr);
|
||||
warned--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
cia_wait_post(v);
|
||||
return v;
|
||||
}
|
||||
cia_wait_pre();
|
||||
switch ((addr >> 12) & 3) {
|
||||
case 0:
|
||||
if (!issinglecia())
|
||||
v = (ReadCIAB(r) << 8) | ReadCIAA(r);
|
||||
break;
|
||||
case 1:
|
||||
v = (ReadCIAB(r) << 8) | 0xff;
|
||||
break;
|
||||
case 2:
|
||||
v = (0xff << 8) | ReadCIAA(r);
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
|
||||
if (warned > 0) {
|
||||
BUG.info('cia_wget: unknown CIA address %x', addr);
|
||||
warned--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
cia_wait_post(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
this.load32 = function(addr) {
|
||||
var v = this.load16(addr) << 16;
|
||||
v |= this.load16(addr + 2);
|
||||
return v >>> 0;
|
||||
}
|
||||
this.load32 = function (addr) {
|
||||
var v = this.load16(addr) << 16;
|
||||
v |= this.load16(addr + 2);
|
||||
return v >>> 0;
|
||||
};
|
||||
|
||||
this.store8 = function (addr, value) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
|
||||
if (!isgaylenocia(addr))
|
||||
return;
|
||||
if (!isgaylenocia(addr))
|
||||
return;
|
||||
|
||||
cia_wait_pre();
|
||||
if (!issinglecia() || (addr & 0x3000) != 0) {
|
||||
if ((addr & 0x2000) == 0)
|
||||
WriteCIAB(r, value);
|
||||
if ((addr & 0x1000) == 0)
|
||||
WriteCIAA(r, value);
|
||||
if (((addr & 0x3000) == 0x3000) && warned > 0) {
|
||||
BUG.info('cia_bput: unknown CIA address %x %x', addr, value);
|
||||
warned--;
|
||||
}
|
||||
}
|
||||
cia_wait_post(value);
|
||||
}
|
||||
cia_wait_pre();
|
||||
if (!issinglecia() || (addr & 0x3000) != 0) {
|
||||
if ((addr & 0x2000) == 0)
|
||||
WriteCIAB(r, value);
|
||||
if ((addr & 0x1000) == 0)
|
||||
WriteCIAA(r, value);
|
||||
if (((addr & 0x3000) == 0x3000) && warned > 0) {
|
||||
BUG.info('cia_bput: unknown CIA address %x %x', addr, value);
|
||||
warned--;
|
||||
}
|
||||
}
|
||||
cia_wait_post(value);
|
||||
};
|
||||
|
||||
this.store16 = function (addr, value) {
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
var r = (addr & 0xf00) >> 8;
|
||||
|
||||
if (!isgaylenocia(addr))
|
||||
return;
|
||||
if (!isgaylenocia(addr))
|
||||
return;
|
||||
|
||||
cia_wait_pre();
|
||||
if (!issinglecia() || (addr & 0x3000) != 0) {
|
||||
if ((addr & 0x2000) == 0)
|
||||
WriteCIAB(r, value >> 8);
|
||||
if ((addr & 0x1000) == 0)
|
||||
WriteCIAA(r, value & 0xff);
|
||||
if (((addr & 0x3000) == 0x3000) && warned > 0) {
|
||||
BUG.info('cia_wput: unknown CIA address %x %x', addr, value);
|
||||
warned--;
|
||||
}
|
||||
}
|
||||
cia_wait_post(value);
|
||||
}
|
||||
cia_wait_pre();
|
||||
if (!issinglecia() || (addr & 0x3000) != 0) {
|
||||
if ((addr & 0x2000) == 0)
|
||||
WriteCIAB(r, value >> 8);
|
||||
if ((addr & 0x1000) == 0)
|
||||
WriteCIAA(r, value & 0xff);
|
||||
if (((addr & 0x3000) == 0x3000) && warned > 0) {
|
||||
BUG.info('cia_wput: unknown CIA address %x %x', addr, value);
|
||||
warned--;
|
||||
}
|
||||
}
|
||||
cia_wait_post(value);
|
||||
};
|
||||
|
||||
this.store32 = function (addr, value) {
|
||||
this.store16(addr, value >> 16);
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ function Config() {
|
|||
size: 0
|
||||
},
|
||||
slow: {
|
||||
size: 0,
|
||||
},
|
||||
size: 0
|
||||
},
|
||||
fast: {
|
||||
size: 0,
|
||||
}
|
||||
size: 0
|
||||
}
|
||||
};
|
||||
this.rom = {
|
||||
size: 0,
|
||||
|
|
@ -177,7 +177,7 @@ function Config() {
|
|||
c.video.scanlines = 0 ? true : false;
|
||||
c.video.extrawidth = 0;
|
||||
c.video.xcenter = 0;
|
||||
c.video.ycenter = 0
|
||||
c.video.ycenter = 0;
|
||||
|
||||
c.audio.enabled = true;
|
||||
//c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
|
||||
|
|
@ -203,11 +203,16 @@ function Config() {
|
|||
c.cia.tod = 0;
|
||||
c.cia.tod_hack = true;
|
||||
|
||||
c.hooks.error = function(err, msg) {}
|
||||
c.hooks.power_led = function(on) {}
|
||||
c.hooks.floppy_motor = function(unit, on) {}
|
||||
c.hooks.floppy_step = function(unit, cyl) {}
|
||||
c.hooks.fps = function(fps) {}
|
||||
c.hooks.error = function (err, msg) {
|
||||
};
|
||||
c.hooks.power_led = function (on) {
|
||||
};
|
||||
c.hooks.floppy_motor = function (unit, on) {
|
||||
};
|
||||
c.hooks.floppy_step = function (unit, cyl) {
|
||||
};
|
||||
c.hooks.fps = function (fps) {
|
||||
};
|
||||
c.hooks.cpu = function(usage) {}
|
||||
}
|
||||
configSetDefaults(this);
|
||||
|
|
|
|||
|
|
@ -10,20 +10,14 @@
|
|||
|
||||
const SAEV_Version = 0;
|
||||
const SAEV_Revision = 8;
|
||||
const SAEV_Revision_Sub = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
const SAEV_Null = null;
|
||||
|
||||
const SAEV_True = true;
|
||||
const SAEV_False = false;
|
||||
const SAEV_Revision_Sub = 1;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* info */
|
||||
|
||||
const SAEI_Audio_Webkit = 1;
|
||||
const SAEI_Audio_Mozilla = 2;
|
||||
const SAEI_Audio_Default = 1;
|
||||
const SAEI_Audio_Webkit = 2;
|
||||
const SAEI_Audio_Mozilla = 4;
|
||||
|
||||
const SAEI_Video_Canvas2D = 1;
|
||||
const SAEI_Video_WebGL = 2;
|
||||
|
|
@ -83,7 +77,7 @@ const SAEV_Config_EXT_Size_None = 0;
|
|||
const SAEV_Config_EXT_Size_256K = 1;
|
||||
const SAEV_Config_EXT_Size_512K = 2;
|
||||
|
||||
const SAEV_Config_EXT_Addr_A0 = 1;
|
||||
//const SAEV_Config_EXT_Addr_A0 = 1;
|
||||
const SAEV_Config_EXT_Addr_E0 = 2;
|
||||
const SAEV_Config_EXT_Addr_F0 = 3;
|
||||
|
||||
|
|
@ -138,7 +132,7 @@ const SAEV_Config_RTC_Type_RF5C01A = 2;
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* erros */
|
||||
|
||||
const SAEE_None = 0;
|
||||
//const SAEE_None = 0;
|
||||
|
||||
const SAEE_CPU_Internal = 1;
|
||||
const SAEE_CPU_68020_Required = 2;
|
||||
|
|
@ -148,32 +142,25 @@ const SAEE_Disk_File_Too_Big = 3;
|
|||
const SAEE_Video_Shader_Error = 4;
|
||||
const SAEE_Video_ID_Not_Found = 5;
|
||||
const SAEE_Video_Canvas_Not_Supported = 6;
|
||||
const SAEE_Video_WebGL_Not_Avail = 7;
|
||||
//const SAEE_Video_WebGL_Not_Avail = 7;
|
||||
|
||||
const SAEE_Audio_WebAudio_Not_Avail = 8;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* methods */
|
||||
|
||||
const SAEM_Init = 1;
|
||||
/*const SAEM_Init = 1;
|
||||
const SAEM_Start = 2;
|
||||
const SAEM_Stop = 3;
|
||||
const SAEM_Pause = 4;
|
||||
const SAEM_Reset = 5;
|
||||
const SAEM_Insert = 6;
|
||||
const SAEM_Eject = 7;
|
||||
const SAEM_Eject = 7;*/
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* debug */
|
||||
|
||||
var BUG = null;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* amiga */
|
||||
|
||||
var AMIGA = null;
|
||||
|
||||
const ST_STOP = 0;
|
||||
const ST_CYCLE = 1;
|
||||
const ST_PAUSE = 2;
|
||||
|
|
@ -251,8 +238,6 @@ const DMAF_BZERO = 1 << 13;
|
|||
const DMAF_BBUSY = 1 << 14;
|
||||
const DMAF_SETCLR = 1 << 15;
|
||||
|
||||
const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* blitter */
|
||||
|
||||
|
|
@ -301,7 +286,7 @@ const EQU_ENDLINE_NTSC = 10;
|
|||
const CSMASK_ECS_AGNUS = 1;
|
||||
const CSMASK_ECS_DENISE = 2;
|
||||
const CSMASK_AGA = 4;
|
||||
const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA);
|
||||
//const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA);
|
||||
|
||||
const CHIPSET_CLOCK_PAL = 3546895;
|
||||
const CHIPSET_CLOCK_NTSC = 3579545;
|
||||
|
|
@ -338,7 +323,7 @@ const HARD_DDF_START = 0x18;
|
|||
const MAX_PLANES = 6; /* 8 = AGA */
|
||||
|
||||
const AMIGA_WIDTH_MAX = 752 / 2;
|
||||
const AMIGA_HEIGHT_MAX = 574 / 2;
|
||||
//const AMIGA_HEIGHT_MAX = 574 / 2;
|
||||
|
||||
const DIW_DDF_OFFSET = 1;
|
||||
const HBLANK_OFFSET = 9;
|
||||
|
|
@ -366,13 +351,13 @@ const COLOR_CHANGE_BRDBLANK = 0x80000000;
|
|||
|
||||
const BPLCON_DENISE_DELAY = 1;
|
||||
|
||||
const SPRITE_DEBUG = 0;
|
||||
const SPRITE_DEBUG_MINY = 0x0;
|
||||
const SPRITE_DEBUG_MAXY = 0x100;
|
||||
const SPR0_HPOS = 0x15;
|
||||
const MAX_SPRITES = 8;
|
||||
//const SPRITE_DEBUG = 0;
|
||||
//const SPRITE_DEBUG_MINY = 0x0;
|
||||
//const SPRITE_DEBUG_MAXY = 0x100;
|
||||
//const AUTOSCALE_SPRITES = 1;
|
||||
//const SPRBORDER = 0;
|
||||
const SPR0_HPOS = 0x15;
|
||||
const MAX_SPRITES = 8;
|
||||
|
||||
const MAX_PIXELS_PER_LINE = 1760;
|
||||
|
||||
|
|
@ -382,8 +367,6 @@ const MAX_REG_CHANGE = ((MAXVPOS + 1) * 2 * MAXHPOS);
|
|||
const MAX_STOP = 30000;
|
||||
const NO_BLOCK = -3;
|
||||
|
||||
const FRAMES_UNTIL_RES_SWITCH = 1;
|
||||
|
||||
const MAX_WORDS_PER_LINE = 100;
|
||||
|
||||
const DO_SPRITES = 1;
|
||||
|
|
|
|||
873
sae/copper.js
873
sae/copper.js
|
|
@ -50,7 +50,7 @@ function Copper() {
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
];
|
||||
this.cop1lc = 0;
|
||||
this.cop2lc = 0,
|
||||
this.cop2lc = 0;
|
||||
this.copcon = 0;
|
||||
this.enabled_thisline = false;
|
||||
this.access = false;
|
||||
|
|
@ -73,68 +73,68 @@ function Copper() {
|
|||
};
|
||||
|
||||
this.reset = function () {
|
||||
this.copcon = 0;
|
||||
cop_state.state = COP_stop;
|
||||
}
|
||||
this.copcon = 0;
|
||||
cop_state.state = COP_stop;
|
||||
};
|
||||
|
||||
this.reset2 = function () {
|
||||
cop_state.hpos = 0;
|
||||
cop_state.last_write = 0;
|
||||
this.compute_spcflag_copper(AMIGA.playfield.maxhpos);
|
||||
}
|
||||
cop_state.hpos = 0;
|
||||
cop_state.last_write = 0;
|
||||
this.compute_spcflag_copper(AMIGA.playfield.maxhpos);
|
||||
};
|
||||
|
||||
this.COPCON = function (v) {
|
||||
this.copcon = v;
|
||||
}
|
||||
this.copcon = v;
|
||||
};
|
||||
this.COP1LCH = function (v) {
|
||||
this.cop1lc = ((v << 16) | (this.cop1lc & 0xffff)) >>> 0;
|
||||
}
|
||||
this.cop1lc = ((v << 16) | (this.cop1lc & 0xffff)) >>> 0;
|
||||
};
|
||||
this.COP1LCL = function (v) {
|
||||
this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
|
||||
}
|
||||
this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
this.COP2LCH = function (v) {
|
||||
this.cop2lc = ((v << 16) | (this.cop2lc & 0xffff)) >>> 0;
|
||||
}
|
||||
this.cop2lc = ((v << 16) | (this.cop2lc & 0xffff)) >>> 0;
|
||||
};
|
||||
this.COP2LCL = function (v) {
|
||||
this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
|
||||
}
|
||||
this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
|
||||
};
|
||||
|
||||
this.COPJMP = function (num, vblank) {
|
||||
var oldstrobe = cop_state.strobe;
|
||||
var oldstrobe = cop_state.strobe;
|
||||
|
||||
//if (AMIGA.dmaen(DMAF_COPEN) && (cop_state.saved_i1 != 0xffff || cop_state.saved_i2 != 0xfffe))
|
||||
//BUG.info('COPJMP(%d) vblank without copper ending %08x (%08x %08x) (%08x %08x)', num, cop_state.ip, this.cop1lc, this.cop2lc, cop_state.saved_i1, cop_state.saved_i2);
|
||||
//if (AMIGA.dmaen(DMAF_COPEN) && (cop_state.saved_i1 != 0xffff || cop_state.saved_i2 != 0xfffe))
|
||||
//BUG.info('COPJMP(%d) vblank without copper ending %08x (%08x %08x) (%08x %08x)', num, cop_state.ip, this.cop1lc, this.cop2lc, cop_state.saved_i1, cop_state.saved_i2);
|
||||
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
cop_state.ignore_next = 0;
|
||||
if (!oldstrobe)
|
||||
cop_state.state_prev = cop_state.state;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
cop_state.ignore_next = 0;
|
||||
if (!oldstrobe)
|
||||
cop_state.state_prev = cop_state.state;
|
||||
|
||||
if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank)
|
||||
cop_state.state = COP_strobe_delay1x;
|
||||
else
|
||||
cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra);
|
||||
if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank)
|
||||
cop_state.state = COP_strobe_delay1x;
|
||||
else
|
||||
cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra);
|
||||
|
||||
//BUG.info('COPJMP(%d) %d', num, cop_state.state);
|
||||
|
||||
cop_state.vpos = AMIGA.playfield.vpos;
|
||||
cop_state.hpos = AMIGA.playfield.hpos() & ~1;
|
||||
cop_state.strobe = num;
|
||||
this.enabled_thisline = false;
|
||||
|
||||
if (0) {
|
||||
this.immediate_copper(num);
|
||||
return;
|
||||
}
|
||||
//BUG.info('COPJMP(%d) %d', num, cop_state.state);
|
||||
|
||||
if (AMIGA.dmaen(DMAF_COPEN))
|
||||
this.compute_spcflag_copper(AMIGA.playfield.hpos());
|
||||
else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) {
|
||||
/* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */
|
||||
cop_state.state = COP_stop;
|
||||
//BUG.info('COPJMP(%d) COP_stop');
|
||||
}
|
||||
}
|
||||
cop_state.vpos = AMIGA.playfield.vpos;
|
||||
cop_state.hpos = AMIGA.playfield.hpos() & ~1;
|
||||
cop_state.strobe = num;
|
||||
this.enabled_thisline = false;
|
||||
|
||||
if (0) {
|
||||
this.immediate_copper(num);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AMIGA.dmaen(DMAF_COPEN))
|
||||
this.compute_spcflag_copper(AMIGA.playfield.hpos());
|
||||
else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) {
|
||||
/* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */
|
||||
cop_state.state = COP_stop;
|
||||
//BUG.info('COPJMP(%d) COP_stop');
|
||||
}
|
||||
};
|
||||
|
||||
/*function get_copper_address(copno) {
|
||||
switch (copno) {
|
||||
|
|
@ -146,440 +146,453 @@ function Copper() {
|
|||
}*/
|
||||
|
||||
this.test_copper_dangerous = function (address) {
|
||||
var addr = address & 0x1fe;
|
||||
if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
|
||||
cop_state.state = COP_stop;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var addr = address & 0x1fe;
|
||||
if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
|
||||
cop_state.state = COP_stop;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
this.immediate_copper = function (num) {
|
||||
var pos = 0;
|
||||
var oldpos = 0;
|
||||
var pos = 0;
|
||||
var oldpos = 0;
|
||||
|
||||
cop_state.state = COP_stop;
|
||||
cop_state.vpos = AMIGA.playfield.vpos;
|
||||
cop_state.hpos = AMIGA.playfield.hpos() & ~1;
|
||||
cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc;
|
||||
cop_state.state = COP_stop;
|
||||
cop_state.vpos = AMIGA.playfield.vpos;
|
||||
cop_state.hpos = AMIGA.playfield.hpos() & ~1;
|
||||
cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc;
|
||||
|
||||
while (pos < (AMIGA.playfield.maxvpos << 5)) {
|
||||
if (oldpos > pos)
|
||||
pos = oldpos;
|
||||
if (!AMIGA.dmaen(DMAF_COPEN))
|
||||
break;
|
||||
if (cop_state.ip >= AMIGA.mem.chip.size)
|
||||
break;
|
||||
pos++;
|
||||
oldpos = pos;
|
||||
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2);
|
||||
cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1];
|
||||
AMIGA.custom.last_value = cop_state.i2;
|
||||
cop_state.ip += 4;
|
||||
if (!(cop_state.i1 & 1)) { // move
|
||||
cop_state.i1 &= 0x1fe;
|
||||
if (cop_state.i1 == 0x88) {
|
||||
cop_state.ip = this.cop1lc;
|
||||
continue;
|
||||
}
|
||||
if (cop_state.i1 == 0x8a) {
|
||||
cop_state.ip = this.cop2lc;
|
||||
continue;
|
||||
}
|
||||
if (this.test_copper_dangerous(cop_state.i1))
|
||||
break;
|
||||
AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0);
|
||||
} else { // wait or skip
|
||||
if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff))
|
||||
pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3);
|
||||
if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
cop_state.state = COP_stop;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
}
|
||||
while (pos < (AMIGA.playfield.maxvpos << 5)) {
|
||||
if (oldpos > pos)
|
||||
pos = oldpos;
|
||||
if (!AMIGA.dmaen(DMAF_COPEN))
|
||||
break;
|
||||
if (cop_state.ip >= AMIGA.mem.chip.size)
|
||||
break;
|
||||
pos++;
|
||||
oldpos = pos;
|
||||
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2);
|
||||
cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1];
|
||||
AMIGA.custom.last_value = cop_state.i2;
|
||||
cop_state.ip += 4;
|
||||
if (!(cop_state.i1 & 1)) { // move
|
||||
cop_state.i1 &= 0x1fe;
|
||||
if (cop_state.i1 == 0x88) {
|
||||
cop_state.ip = this.cop1lc;
|
||||
continue;
|
||||
}
|
||||
if (cop_state.i1 == 0x8a) {
|
||||
cop_state.ip = this.cop2lc;
|
||||
continue;
|
||||
}
|
||||
if (this.test_copper_dangerous(cop_state.i1))
|
||||
break;
|
||||
AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0);
|
||||
} else { // wait or skip
|
||||
if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff))
|
||||
pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3);
|
||||
if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
cop_state.state = COP_stop;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
};
|
||||
|
||||
this.copper_cant_read = function (hpos, alloc) {
|
||||
//BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos);
|
||||
if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot
|
||||
return 1;
|
||||
if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) {
|
||||
return -1;
|
||||
}
|
||||
return AMIGA.playfield.is_bitplane_dma(hpos);
|
||||
}
|
||||
//BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos);
|
||||
if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot
|
||||
return 1;
|
||||
if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) {
|
||||
return -1;
|
||||
}
|
||||
return AMIGA.playfield.is_bitplane_dma(hpos);
|
||||
};
|
||||
|
||||
this.custom_store16_copper = function (hpos, addr, value, noget) {
|
||||
//if (addr == 0x88 || addr == 0x8a)
|
||||
//BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.playfield.vpos, AMIGA.playfield.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos);
|
||||
//value = debug_wputpeekdma (0xdff000 + addr, value);
|
||||
this.access = true;
|
||||
var v = AMIGA.custom.store16_real(hpos, addr, value, noget);
|
||||
this.access = false;
|
||||
return v;
|
||||
}
|
||||
//if (addr == 0x88 || addr == 0x8a)
|
||||
//BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.playfield.vpos, AMIGA.playfield.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos);
|
||||
//value = debug_wputpeekdma (0xdff000 + addr, value);
|
||||
this.access = true;
|
||||
var v = AMIGA.custom.store16_real(hpos, addr, value, noget);
|
||||
this.access = false;
|
||||
return v;
|
||||
};
|
||||
|
||||
this.dump_copper = function (error, until_hpos) {
|
||||
BUG.info('\n');
|
||||
BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.playfield.vpos, until_hpos, AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80));
|
||||
BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2);
|
||||
BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline?1:0);
|
||||
BUG.info('\n');
|
||||
}
|
||||
BUG.info('\n');
|
||||
BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.playfield.vpos, until_hpos, AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80));
|
||||
BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2);
|
||||
BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline ? 1 : 0);
|
||||
BUG.info('\n');
|
||||
};
|
||||
|
||||
this.update = function (until_hpos) {
|
||||
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
var c_hpos = cop_state.hpos;
|
||||
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
var c_hpos = cop_state.hpos;
|
||||
|
||||
//BUG.info('update() until_hpos %d, vp %d', until_hpos, vp);
|
||||
//BUG.info('update() until_hpos %d, vp %d', until_hpos, vp);
|
||||
|
||||
if (cop_state.state == COP_wait && vp < cop_state.vcmp) {
|
||||
this.dump_copper('error2', until_hpos);
|
||||
this.enabled_thisline = false;
|
||||
cop_state.state = COP_stop;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return;
|
||||
}
|
||||
if (cop_state.state == COP_wait && vp < cop_state.vcmp) {
|
||||
this.dump_copper('error2', until_hpos);
|
||||
this.enabled_thisline = false;
|
||||
cop_state.state = COP_stop;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (until_hpos <= this.last_copper_hpos)
|
||||
return;
|
||||
if (until_hpos <= this.last_copper_hpos)
|
||||
return;
|
||||
|
||||
if (until_hpos > (AMIGA.playfield.maxhpos & ~1))
|
||||
until_hpos = AMIGA.playfield.maxhpos & ~1;
|
||||
if (until_hpos > (AMIGA.playfield.maxhpos & ~1))
|
||||
until_hpos = AMIGA.playfield.maxhpos & ~1;
|
||||
|
||||
for (;;) {
|
||||
var old_hpos = c_hpos;
|
||||
var hp;
|
||||
for (; ;) {
|
||||
var old_hpos = c_hpos;
|
||||
var hp;
|
||||
|
||||
if (c_hpos >= until_hpos)
|
||||
break;
|
||||
if (c_hpos >= until_hpos)
|
||||
break;
|
||||
|
||||
/* So we know about the fetch state. */
|
||||
AMIGA.playfield.decide_line(c_hpos);
|
||||
AMIGA.playfield.decide_fetch(c_hpos);
|
||||
/* So we know about the fetch state. */
|
||||
AMIGA.playfield.decide_line(c_hpos);
|
||||
AMIGA.playfield.decide_fetch(c_hpos);
|
||||
|
||||
if (cop_state.movedelay > 0) {
|
||||
cop_state.movedelay--;
|
||||
if (cop_state.movedelay == 0) {
|
||||
this.custom_store16_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0);
|
||||
}
|
||||
}
|
||||
if (cop_state.movedelay > 0) {
|
||||
cop_state.movedelay--;
|
||||
if (cop_state.movedelay == 0) {
|
||||
this.custom_store16_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1))
|
||||
c_hpos += 1;
|
||||
else
|
||||
c_hpos += 2;
|
||||
if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1))
|
||||
c_hpos += 1;
|
||||
else
|
||||
c_hpos += 2;
|
||||
|
||||
switch (cop_state.state) {
|
||||
case COP_wait_in2: {
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
cop_state.state = COP_wait1;
|
||||
break;
|
||||
}
|
||||
case COP_skip_in2: {
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
cop_state.state = COP_skip1;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_extra: {
|
||||
// Wait 1 copper cycle doing nothing
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay1: {
|
||||
// First cycle after COPJMP is just like normal first read cycle
|
||||
// Cycle is used and needs to be free.
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_strobe_delay2;
|
||||
cop_state.ip += 2;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay2: {
|
||||
// Second cycle after COPJMP. This is the strange one.
|
||||
// This cycle does not need to be free
|
||||
// But it still gets allocated by copper if it is free = CPU and blitter can't use it.
|
||||
cop_state.state = COP_read1;
|
||||
// Next cycle finally reads from new pointer
|
||||
if (cop_state.strobe == 1)
|
||||
cop_state.ip = this.cop1lc;
|
||||
else
|
||||
cop_state.ip = this.cop2lc;
|
||||
cop_state.strobe = 0;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay1x: {
|
||||
// First cycle after COPJMP and Copper was waiting. This is the buggy one.
|
||||
// Cycle can be free and copper won't allocate it.
|
||||
// If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer..
|
||||
cop_state.state = COP_strobe_delay2x;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay2x: {
|
||||
// Second cycle fetches following word and tosses it away. Must be free cycle
|
||||
// but is not allocated, blitter or cpu can still use it.
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_read1;
|
||||
// Next cycle finally reads from new pointer
|
||||
if (cop_state.strobe == 1)
|
||||
cop_state.ip = this.cop1lc;
|
||||
else
|
||||
cop_state.ip = this.cop2lc;
|
||||
cop_state.strobe = 0;
|
||||
break;
|
||||
}
|
||||
case COP_start_delay: {
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_read1;
|
||||
cop_state.ip = this.cop1lc;
|
||||
break;
|
||||
}
|
||||
case COP_read1: {
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
/* workaround for a bug in kick 1.x */
|
||||
if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) {
|
||||
//BUG.info('COP_read1() invalid addr $%08x', cop_state.ip);
|
||||
cop_state.state = COP_stop;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return;
|
||||
}
|
||||
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
cop_state.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.ip += 2;
|
||||
cop_state.state = COP_read2;
|
||||
break;
|
||||
}
|
||||
case COP_read2: {
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
cop_state.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.ip += 2;
|
||||
cop_state.saved_i1 = cop_state.i1;
|
||||
cop_state.saved_i2 = cop_state.i2;
|
||||
cop_state.saved_ip = cop_state.ip;
|
||||
switch (cop_state.state) {
|
||||
case COP_wait_in2:
|
||||
{
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
cop_state.state = COP_wait1;
|
||||
break;
|
||||
}
|
||||
case COP_skip_in2:
|
||||
{
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
cop_state.state = COP_skip1;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_extra:
|
||||
{
|
||||
// Wait 1 copper cycle doing nothing
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay1:
|
||||
{
|
||||
// First cycle after COPJMP is just like normal first read cycle
|
||||
// Cycle is used and needs to be free.
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_strobe_delay2;
|
||||
cop_state.ip += 2;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay2:
|
||||
{
|
||||
// Second cycle after COPJMP. This is the strange one.
|
||||
// This cycle does not need to be free
|
||||
// But it still gets allocated by copper if it is free = CPU and blitter can't use it.
|
||||
cop_state.state = COP_read1;
|
||||
// Next cycle finally reads from new pointer
|
||||
if (cop_state.strobe == 1)
|
||||
cop_state.ip = this.cop1lc;
|
||||
else
|
||||
cop_state.ip = this.cop2lc;
|
||||
cop_state.strobe = 0;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay1x:
|
||||
{
|
||||
// First cycle after COPJMP and Copper was waiting. This is the buggy one.
|
||||
// Cycle can be free and copper won't allocate it.
|
||||
// If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer..
|
||||
cop_state.state = COP_strobe_delay2x;
|
||||
break;
|
||||
}
|
||||
case COP_strobe_delay2x:
|
||||
{
|
||||
// Second cycle fetches following word and tosses it away. Must be free cycle
|
||||
// but is not allocated, blitter or cpu can still use it.
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_read1;
|
||||
// Next cycle finally reads from new pointer
|
||||
if (cop_state.strobe == 1)
|
||||
cop_state.ip = this.cop1lc;
|
||||
else
|
||||
cop_state.ip = this.cop2lc;
|
||||
cop_state.strobe = 0;
|
||||
break;
|
||||
}
|
||||
case COP_start_delay:
|
||||
{
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
cop_state.state = COP_read1;
|
||||
cop_state.ip = this.cop1lc;
|
||||
break;
|
||||
}
|
||||
case COP_read1:
|
||||
{
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
/* workaround for a bug in kick 1.x */
|
||||
if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) {
|
||||
//BUG.info('COP_read1() invalid addr $%08x', cop_state.ip);
|
||||
cop_state.state = COP_stop;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
return;
|
||||
}
|
||||
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
cop_state.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.ip += 2;
|
||||
cop_state.state = COP_read2;
|
||||
break;
|
||||
}
|
||||
case COP_read2:
|
||||
{
|
||||
if (this.copper_cant_read(old_hpos, 1))
|
||||
continue;
|
||||
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip);
|
||||
cop_state.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
|
||||
cop_state.ip += 2;
|
||||
cop_state.saved_i1 = cop_state.i1;
|
||||
cop_state.saved_i2 = cop_state.i2;
|
||||
cop_state.saved_ip = cop_state.ip;
|
||||
|
||||
if (cop_state.i1 & 1) { // WAIT or SKIP
|
||||
cop_state.ignore_next = 0;
|
||||
if (cop_state.i2 & 1)
|
||||
cop_state.state = COP_skip_in2;
|
||||
else
|
||||
cop_state.state = COP_wait_in2;
|
||||
} else { // MOVE
|
||||
//uaecptr debugip = cop_state.ip;
|
||||
var reg = cop_state.i1 & 0x1fe;
|
||||
var data = cop_state.i2;
|
||||
cop_state.state = COP_read1;
|
||||
this.test_copper_dangerous(reg);
|
||||
if (!this.enabled_thisline) {
|
||||
//goto out; // was 'dangerous' register -> copper stopped
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
if (cop_state.ignore_next)
|
||||
reg = 0x1fe;
|
||||
if (cop_state.i1 & 1) { // WAIT or SKIP
|
||||
cop_state.ignore_next = 0;
|
||||
if (cop_state.i2 & 1)
|
||||
cop_state.state = COP_skip_in2;
|
||||
else
|
||||
cop_state.state = COP_wait_in2;
|
||||
} else { // MOVE
|
||||
//uaecptr debugip = cop_state.ip;
|
||||
var reg = cop_state.i1 & 0x1fe;
|
||||
var data = cop_state.i2;
|
||||
cop_state.state = COP_read1;
|
||||
this.test_copper_dangerous(reg);
|
||||
if (!this.enabled_thisline) {
|
||||
//goto out; // was 'dangerous' register -> copper stopped
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
if (cop_state.ignore_next)
|
||||
reg = 0x1fe;
|
||||
|
||||
cop_state.last_write = reg;
|
||||
cop_state.last_write_hpos = old_hpos;
|
||||
if (reg == 0x88) {
|
||||
cop_state.strobe = 1;
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
} else if (reg == 0x8a) {
|
||||
cop_state.strobe = 2;
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
} else {
|
||||
/*if (0) {
|
||||
AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write);
|
||||
AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0);
|
||||
});
|
||||
//this.custom_store16_copper(old_hpos, reg, data, 0);
|
||||
} else*/
|
||||
{
|
||||
// FIX: all copper writes happen 1 cycle later than CPU writes
|
||||
if (customdelay[reg >> 1]) {
|
||||
cop_state.moveaddr = reg;
|
||||
cop_state.movedata = data;
|
||||
cop_state.movedelay = customdelay[cop_state.moveaddr >> 1];
|
||||
} else {
|
||||
var hpos2 = old_hpos;
|
||||
this.custom_store16_copper(hpos2, reg, data, 0);
|
||||
hpos2++;
|
||||
if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES)
|
||||
AMIGA.playfield.do_sprites(hpos2);
|
||||
}
|
||||
}
|
||||
}
|
||||
cop_state.ignore_next = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COP_wait1: {
|
||||
/*#if 0
|
||||
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break;
|
||||
#endif*/
|
||||
cop_state.state = COP_wait;
|
||||
cop_state.last_write = reg;
|
||||
cop_state.last_write_hpos = old_hpos;
|
||||
if (reg == 0x88) {
|
||||
cop_state.strobe = 1;
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
} else if (reg == 0x8a) {
|
||||
cop_state.strobe = 2;
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
} else {
|
||||
/*if (0) {
|
||||
AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write);
|
||||
AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0);
|
||||
});
|
||||
//this.custom_store16_copper(old_hpos, reg, data, 0);
|
||||
} else*/
|
||||
{
|
||||
// FIX: all copper writes happen 1 cycle later than CPU writes
|
||||
if (customdelay[reg >> 1]) {
|
||||
cop_state.moveaddr = reg;
|
||||
cop_state.movedata = data;
|
||||
cop_state.movedelay = customdelay[cop_state.moveaddr >> 1];
|
||||
} else {
|
||||
var hpos2 = old_hpos;
|
||||
this.custom_store16_copper(hpos2, reg, data, 0);
|
||||
hpos2++;
|
||||
if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES)
|
||||
AMIGA.playfield.do_sprites(hpos2);
|
||||
}
|
||||
}
|
||||
}
|
||||
cop_state.ignore_next = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COP_wait1:
|
||||
{
|
||||
/*#if 0
|
||||
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break;
|
||||
#endif*/
|
||||
cop_state.state = COP_wait;
|
||||
|
||||
cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
|
||||
cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
|
||||
cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
|
||||
cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
|
||||
|
||||
vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
|
||||
if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) {
|
||||
cop_state.state = COP_waitforever;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
if (vp < cop_state.vcmp) {
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case COP_wait: {
|
||||
var ch_comp = c_hpos;
|
||||
if (ch_comp & 1)
|
||||
ch_comp = 0;
|
||||
if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) {
|
||||
cop_state.state = COP_waitforever;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
if (vp < cop_state.vcmp) {
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case COP_wait:
|
||||
{
|
||||
var ch_comp = c_hpos;
|
||||
if (ch_comp & 1)
|
||||
ch_comp = 0;
|
||||
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
|
||||
hp = ch_comp & (cop_state.saved_i2 & 0xfe);
|
||||
if (vp == cop_state.vcmp && hp < cop_state.hcmp)
|
||||
break;
|
||||
hp = ch_comp & (cop_state.saved_i2 & 0xfe);
|
||||
if (vp == cop_state.vcmp && hp < cop_state.hcmp)
|
||||
break;
|
||||
|
||||
/* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */
|
||||
if ((cop_state.saved_i2 & 0x8000) == 0) {
|
||||
if (AMIGA.blitter.getState() != BLT_done) {
|
||||
//We need to wait for the blitter.
|
||||
cop_state.state = COP_bltwait;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cop_state.state = COP_read1;
|
||||
break;
|
||||
}
|
||||
case COP_skip1: {
|
||||
var vcmp, hcmp, vp1, hp1;
|
||||
/* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */
|
||||
if ((cop_state.saved_i2 & 0x8000) == 0) {
|
||||
if (AMIGA.blitter.getState() != BLT_done) {
|
||||
//We need to wait for the blitter.
|
||||
cop_state.state = COP_bltwait;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
//goto out;
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cop_state.state = COP_read1;
|
||||
break;
|
||||
}
|
||||
case COP_skip1:
|
||||
{
|
||||
var vcmp, hcmp, vp1, hp1;
|
||||
|
||||
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1))
|
||||
break;
|
||||
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1))
|
||||
break;
|
||||
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
if (this.copper_cant_read(old_hpos, 0))
|
||||
continue;
|
||||
|
||||
vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
|
||||
hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
|
||||
vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
hp1 = c_hpos & (cop_state.saved_i2 & 0xfe);
|
||||
vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
|
||||
hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
|
||||
vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
hp1 = c_hpos & (cop_state.saved_i2 & 0xfe);
|
||||
|
||||
if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done))
|
||||
cop_state.ignore_next = 1;
|
||||
if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done))
|
||||
cop_state.ignore_next = 1;
|
||||
|
||||
cop_state.state = COP_read1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cop_state.state = COP_read1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//out:
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
}
|
||||
//out:
|
||||
cop_state.hpos = c_hpos;
|
||||
this.last_copper_hpos = until_hpos;
|
||||
};
|
||||
|
||||
this.compute_spcflag_copper = function (hpos) {
|
||||
//BUG.info('compute_spcflag_copper() hpos %d', hpos);
|
||||
var wasenabled = this.enabled_thisline;
|
||||
//BUG.info('compute_spcflag_copper() hpos %d', hpos);
|
||||
var wasenabled = this.enabled_thisline;
|
||||
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait)
|
||||
return;
|
||||
this.enabled_thisline = false;
|
||||
clr_special(SPCFLAG_COPPER);
|
||||
if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait)
|
||||
return;
|
||||
|
||||
if (cop_state.state == COP_wait) {
|
||||
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
if (cop_state.state == COP_wait) {
|
||||
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
|
||||
if (vp < cop_state.vcmp)
|
||||
return;
|
||||
}
|
||||
// do not use past cycles if starting for the first time in this line
|
||||
// (write to DMACON for example) hpos+1 for long lines
|
||||
if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) {
|
||||
hpos = (hpos + 2) & ~1;
|
||||
if (hpos > AMIGA.playfield.maxhpos_short)
|
||||
hpos = AMIGA.playfield.maxhpos_short;
|
||||
cop_state.hpos = hpos;
|
||||
//BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short);
|
||||
}
|
||||
if (vp < cop_state.vcmp)
|
||||
return;
|
||||
}
|
||||
// do not use past cycles if starting for the first time in this line
|
||||
// (write to DMACON for example) hpos+1 for long lines
|
||||
if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) {
|
||||
hpos = (hpos + 2) & ~1;
|
||||
if (hpos > AMIGA.playfield.maxhpos_short)
|
||||
hpos = AMIGA.playfield.maxhpos_short;
|
||||
cop_state.hpos = hpos;
|
||||
//BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short);
|
||||
}
|
||||
|
||||
// if COPJMPx was written while DMA was disabled, advance to next state,
|
||||
// COP_strobe_extra is single cycle only and does not need free bus.
|
||||
// (copper state emulation does not run if DMA is disabled)
|
||||
if (!wasenabled && cop_state.state == COP_strobe_extra)
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
// if COPJMPx was written while DMA was disabled, advance to next state,
|
||||
// COP_strobe_extra is single cycle only and does not need free bus.
|
||||
// (copper state emulation does not run if DMA is disabled)
|
||||
if (!wasenabled && cop_state.state == COP_strobe_extra)
|
||||
cop_state.state = COP_strobe_delay1;
|
||||
|
||||
this.enabled_thisline = true;
|
||||
set_special(SPCFLAG_COPPER);
|
||||
}
|
||||
this.enabled_thisline = true;
|
||||
set_special(SPCFLAG_COPPER);
|
||||
};
|
||||
|
||||
this.blitter_done_notify = function (hpos) {
|
||||
if (cop_state.state != COP_bltwait)
|
||||
return;
|
||||
if (cop_state.state != COP_bltwait)
|
||||
return;
|
||||
|
||||
//BUG.info('blitter_done_notify() hpos %d', hpos);
|
||||
//BUG.info('blitter_done_notify() hpos %d', hpos);
|
||||
|
||||
var vp = AMIGA.playfield.vpos;
|
||||
hpos += 3;
|
||||
hpos &= ~1;
|
||||
if (hpos >= AMIGA.playfield.maxhpos) {
|
||||
hpos -= AMIGA.playfield.maxhpos;
|
||||
vp++;
|
||||
}
|
||||
cop_state.hpos = hpos;
|
||||
cop_state.vpos = vp;
|
||||
cop_state.state = COP_read1;
|
||||
var vp = AMIGA.playfield.vpos;
|
||||
hpos += 3;
|
||||
hpos &= ~1;
|
||||
if (hpos >= AMIGA.playfield.maxhpos) {
|
||||
hpos -= AMIGA.playfield.maxhpos;
|
||||
vp++;
|
||||
}
|
||||
cop_state.hpos = hpos;
|
||||
cop_state.vpos = vp;
|
||||
cop_state.state = COP_read1;
|
||||
|
||||
if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) {
|
||||
this.enabled_thisline = true;
|
||||
set_special(SPCFLAG_COPPER);
|
||||
}
|
||||
}
|
||||
if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) {
|
||||
this.enabled_thisline = true;
|
||||
set_special(SPCFLAG_COPPER);
|
||||
}
|
||||
};
|
||||
|
||||
this.cycle = function () {
|
||||
this.update(AMIGA.playfield.hpos());
|
||||
}
|
||||
this.update(AMIGA.playfield.hpos());
|
||||
};
|
||||
|
||||
this.sync_copper_with_cpu = function (hpos, do_schedule) {
|
||||
/* Need to let the copper advance to the current position. */
|
||||
if (this.enabled_thisline)
|
||||
this.update(hpos);
|
||||
}
|
||||
/* Need to let the copper advance to the current position. */
|
||||
if (this.enabled_thisline)
|
||||
this.update(hpos);
|
||||
};
|
||||
|
||||
this.check = function (n) {
|
||||
/*this.check = function (n) {
|
||||
if (cop_state.state == COP_wait) {
|
||||
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
|
||||
if (vp < cop_state.vcmp) {
|
||||
|
|
@ -587,5 +600,5 @@ function Copper() {
|
|||
BUG.info('COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d', n, vp, AMIGA.playfield.vpos, cop_state.vcmp, this.enabled_thisline?1:0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
298
sae/cpu.js
298
sae/cpu.js
|
|
@ -40,7 +40,7 @@ function CPU() {
|
|||
const ccNames = ['T', 'F', 'HI', 'LS', 'CC', 'CS', 'NE', 'EQ', 'VC', 'VS', 'PL', 'MI', 'GE', 'LT', 'GT', 'LE'];
|
||||
|
||||
/* Effective Address */
|
||||
function effAddr(m, r) {
|
||||
function EffAddr(m, r) {
|
||||
this.m = m; /* Mode M_ */
|
||||
this.t = 0; /* Type T_ */
|
||||
this.r = r; /* Register An/Dn */
|
||||
|
|
@ -49,31 +49,31 @@ function CPU() {
|
|||
}
|
||||
|
||||
/* Instruction Condition */
|
||||
function iCon(cc, dp, dr) {
|
||||
function ICon(cc, dp, dr) {
|
||||
this.cc = cc; /* Condition Code */
|
||||
this.dp = dp; /* Displacement */
|
||||
this.dr = dr; /* Data Register for DBcc */
|
||||
}
|
||||
|
||||
/* Instruction Paramenter */
|
||||
function iPar() {
|
||||
this.z; /* size B,W,L */
|
||||
function IPar() {
|
||||
this.z = 0; /* size B,W,L */
|
||||
/* Filled on demand
|
||||
this.s = new effAddr();
|
||||
this.d = new effAddr();
|
||||
this.c = new iCon();
|
||||
this.s = new EffAddr();
|
||||
this.d = new EffAddr();
|
||||
this.c = new ICon();
|
||||
this.ms = 0;
|
||||
this.mz = 0;
|
||||
this.cyc = 0;*/
|
||||
}
|
||||
|
||||
/* Instruction Definition */
|
||||
function iDef() {
|
||||
this.op; /* OP-code */
|
||||
this.pr; /* Privileged */
|
||||
this.mn; /* Mnemonic */
|
||||
this.f; /* Function */
|
||||
this.p = new iPar();
|
||||
function IDef() {
|
||||
this.op = 0; /* OP-code */
|
||||
//this.pr = false; /* Privileged */
|
||||
this.mn = ''; /* Mnemonic */
|
||||
this.f = null; /* Function */
|
||||
this.p = new IPar();
|
||||
}
|
||||
|
||||
/* Exception 2/3 error */
|
||||
|
|
@ -118,31 +118,31 @@ function CPU() {
|
|||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
this.setup = function() {
|
||||
if (iTab === null) {
|
||||
BUG.say('cpu.setup() no instruction table, generating...');
|
||||
if (!mkiTab())
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table');
|
||||
} else
|
||||
BUG.say('cpu.setup() instruction table is cached');
|
||||
}
|
||||
this.setup = function () {
|
||||
if (iTab === null) {
|
||||
BUG.say('cpu.setup() no instruction table, generating...');
|
||||
if (!mkiTab())
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table');
|
||||
} else
|
||||
BUG.say('cpu.setup() instruction table is cached');
|
||||
};
|
||||
|
||||
this.reset = function (addr) {
|
||||
for (var i = 0; i < 8; i++)
|
||||
regs.d[i] = regs.a[i] = 0;
|
||||
for (var i = 0; i < 8; i++)
|
||||
regs.d[i] = regs.a[i] = 0;
|
||||
|
||||
regs.t = false;
|
||||
regs.s = true;
|
||||
regs.intmask = 7;
|
||||
regs.x = regs.n = regs.z = regs.v = regs.c = false;
|
||||
regs.usp = 0;
|
||||
regs.isp = 0;
|
||||
regs.a[7] = AMIGA.mem.load32(addr);
|
||||
regs.pc = AMIGA.mem.load32(addr + 4);
|
||||
regs.stopped = false;
|
||||
regs.t = false;
|
||||
regs.s = true;
|
||||
regs.intmask = 7;
|
||||
regs.x = regs.n = regs.z = regs.v = regs.c = false;
|
||||
regs.usp = 0;
|
||||
regs.isp = 0;
|
||||
regs.a[7] = AMIGA.mem.load32(addr);
|
||||
regs.pc = AMIGA.mem.load32(addr + 4);
|
||||
regs.stopped = false;
|
||||
|
||||
BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc));
|
||||
}
|
||||
BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc));
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
|
@ -154,6 +154,7 @@ function CPU() {
|
|||
case 4: return 'L';
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.szChr() invalid size');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,6 +204,7 @@ function CPU() {
|
|||
case 4: return r > 0xffffffff ? r - 0x100000000 : r;
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.addAuto() invalid size');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
function sub32(a, b) {
|
||||
|
|
@ -217,6 +219,7 @@ function CPU() {
|
|||
case 4: return r < 0 ? r + 0x100000000 : r;
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.subAuto() invalid size');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,9 +244,10 @@ function CPU() {
|
|||
//var scale = 1 << ((ext & 0x600) >> 9); if (scale != 1) alert('exII() scale '+scale);
|
||||
function exII(base) {
|
||||
var ext = nextIWord();
|
||||
if (ext & 0x100)
|
||||
Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)');
|
||||
else {
|
||||
if (ext & 0x100) {
|
||||
Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)');
|
||||
return 0;
|
||||
} else {
|
||||
var disp = extByte(ext & 0xff);
|
||||
var r = (ext & 0x7000) >> 12;
|
||||
var reg = (ext & 0x8000) ? regs.a[r] : regs.d[r];
|
||||
|
|
@ -394,6 +398,7 @@ function CPU() {
|
|||
case 4: return regs.d[ea.a];
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RD invalid size');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case T_RA: {
|
||||
|
|
@ -402,6 +407,7 @@ function CPU() {
|
|||
case 4: return regs.a[ea.a];
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RA invalid size');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case T_AD: {
|
||||
|
|
@ -427,12 +433,14 @@ function CPU() {
|
|||
case 4: return AMIGA.mem.load32(ea.a);
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_AD invalid size');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case T_IM:
|
||||
return ea.a;
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() invalid type (' + ea.t + ')');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,6 +509,7 @@ function CPU() {
|
|||
case 15: return regs.z || (regs.n != regs.v); //LE
|
||||
default:
|
||||
Fatal(SAEE_CPU_Internal, 'cpu.ccTrue() invalid condition code (' + cc + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -698,7 +707,7 @@ function CPU() {
|
|||
|
||||
function I_PEA(p) {
|
||||
var sea = exEA(p.s, p.z);
|
||||
var dea = exEA(new effAddr(M_ripr, 7), p.z);
|
||||
var dea = exEA(new EffAddr(M_ripr, 7), p.z);
|
||||
stEA(dea, p.z, sea.a);
|
||||
//ccna
|
||||
return p.cyc;
|
||||
|
|
@ -710,7 +719,7 @@ function CPU() {
|
|||
var dea = exEA(p.d, p.z);
|
||||
var dp = ldEA(dea, p.z); if (p.z == 2) dp = extWord(dp);
|
||||
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.a[An]);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.a[An]);
|
||||
regs.a[An] = regs.a[7];
|
||||
regs.a[7] = add32(regs.a[7], dp);
|
||||
//ccna
|
||||
|
|
@ -726,7 +735,7 @@ function CPU() {
|
|||
var sea = exEA(p.s, p.z);
|
||||
var An = sea.a;
|
||||
regs.a[7] = regs.a[An];
|
||||
regs.a[An] = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
|
||||
regs.a[An] = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
|
||||
//ccna
|
||||
//BUG.say(sprintf('I_UNLK.%s A%d', szChr(p.z), An));
|
||||
return p.cyc;
|
||||
|
|
@ -987,7 +996,7 @@ function CPU() {
|
|||
|
||||
function I_CLR(p) {
|
||||
var dea = exEA(p.d, p.z);
|
||||
var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
|
||||
//var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
|
||||
stEA(dea, p.z, 0);
|
||||
|
||||
regs.n = false;
|
||||
|
|
@ -1812,7 +1821,7 @@ function CPU() {
|
|||
var cyc;
|
||||
|
||||
if (!ccTrue(cc)) {
|
||||
var ea = exEA(new effAddr(M_rdd, p.c.dr), p.z);
|
||||
var ea = exEA(new EffAddr(M_rdd, p.c.dr), p.z);
|
||||
var dr = ldEA(ea, p.z);
|
||||
|
||||
if (dr--) {
|
||||
|
|
@ -1833,7 +1842,7 @@ function CPU() {
|
|||
//var cc = p.s.r;
|
||||
var cc = p.c.cc;
|
||||
var dea = exEA(p.d, p.z);
|
||||
var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
|
||||
//var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
|
||||
var isTrue = ccTrue(cc);
|
||||
stEA(dea, p.z, isTrue ? 0xff : 0);
|
||||
//ccna
|
||||
|
|
@ -1868,7 +1877,7 @@ function CPU() {
|
|||
//else if (dp == 255) Fatal(SAEE_CPU_68020_Required, 'cpu.I_BSR() Full extension index detected (not a 68000 programm)');
|
||||
else pc = add32(regs.pc, extByte(dp));
|
||||
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
setPC(pc);
|
||||
//ccna
|
||||
return p.cycTaken;
|
||||
|
|
@ -1884,7 +1893,7 @@ function CPU() {
|
|||
|
||||
function I_JSR(p) {
|
||||
var dea = exEA(p.d, p.z);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
setPC(dea.a);
|
||||
//ccna
|
||||
//BUG.say(sprintf('I_JSR $%08x', dea.a));
|
||||
|
|
@ -1892,8 +1901,8 @@ function CPU() {
|
|||
}
|
||||
|
||||
function I_RTR(p) {
|
||||
var ccr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2) & 0xff;
|
||||
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
|
||||
var ccr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2) & 0xff;
|
||||
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
|
||||
setCCR(ccr);
|
||||
setPC(pc);
|
||||
//BUG.say(sprintf('I_RTR crr $%04x pc $%08x', crr, pc));
|
||||
|
|
@ -1901,7 +1910,7 @@ function CPU() {
|
|||
}
|
||||
|
||||
function I_RTS(p) {
|
||||
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
|
||||
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
|
||||
//BUG.say(sprintf('I_RTS() regs.pc $%08x newpc $%08x', regs.pc, pc));
|
||||
setPC(pc);
|
||||
//ccna
|
||||
|
|
@ -2039,7 +2048,7 @@ function CPU() {
|
|||
function I_MOVE_SR2(p) {
|
||||
var sr = getSR();
|
||||
var dea = exEA(p.d, p.z);
|
||||
var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */
|
||||
//var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */
|
||||
stEA(dea, p.z, sr);
|
||||
//ccna
|
||||
//BUG.say(sprintf('I_MOVE_SR2.%s sr $%04x', szChr(p.z), sr));
|
||||
|
|
@ -2144,8 +2153,8 @@ function CPU() {
|
|||
|
||||
function I_RTE(p) {
|
||||
if (regs.s) {
|
||||
var sr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2);
|
||||
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
|
||||
var sr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2);
|
||||
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
|
||||
setSR(sr);
|
||||
//BUG.say(sprintf('I_RTE sr $%04x newpc $%08x oldpc $%08x', sr, pc, regs.pc));
|
||||
setPC(pc);
|
||||
|
|
@ -2239,11 +2248,12 @@ function CPU() {
|
|||
case M_absl: return z == 4 ? [16,4,0] : [12,3,0];
|
||||
case M_imm:
|
||||
case M_list: return z == 4 ? [ 8,2,0] : [ 4,1,0];
|
||||
}
|
||||
default: return [0,0,0];
|
||||
}
|
||||
}
|
||||
|
||||
function mkN(op, mn, cyc) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
|
|
@ -2254,14 +2264,14 @@ function CPU() {
|
|||
}
|
||||
|
||||
function mkS(op, mn, z, s, r, cyc, add) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
i.f = null;
|
||||
i.p = {};
|
||||
i.p.z = z;
|
||||
i.p.s = new effAddr(s, r);
|
||||
i.p.s = new EffAddr(s, r);
|
||||
i.p.s.c = mkCyc(z, s);
|
||||
i.p.cyc = cyc;
|
||||
if (add) i.p.cyc[0] += i.p.s.c[0];
|
||||
|
|
@ -2271,14 +2281,14 @@ function CPU() {
|
|||
}
|
||||
|
||||
function mkD(op, mn, z, d, r, cyc, add) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
i.f = null;
|
||||
i.p = {};
|
||||
i.p.z = z;
|
||||
i.p.d = new effAddr(d, r);
|
||||
i.p.d = new EffAddr(d, r);
|
||||
i.p.d.c = mkCyc(z, d);
|
||||
i.p.cyc = cyc;
|
||||
if (add) i.p.cyc[0] += i.p.d.c[0];
|
||||
|
|
@ -2288,7 +2298,7 @@ function CPU() {
|
|||
}
|
||||
|
||||
function mkSD(op, mn, z, sm, sr, dm, dr, cyc, sa, da) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
|
|
@ -2297,8 +2307,8 @@ function CPU() {
|
|||
i.p.z = z;
|
||||
i.p.ms = z == 1 ? 0x80 : (z == 2 ? 0x8000 : 0x80000000);
|
||||
i.p.mz = z == 1 ? 0xff : (z == 2 ? 0xffff : 0xffffffff);
|
||||
i.p.s = new effAddr(sm, sr);
|
||||
i.p.d = new effAddr(dm, dr);
|
||||
i.p.s = new EffAddr(sm, sr);
|
||||
i.p.d = new EffAddr(dm, dr);
|
||||
i.p.s.c = mkCyc(z, sm);
|
||||
i.p.d.c = mkCyc(z, dm);
|
||||
i.p.cyc = cyc;
|
||||
|
|
@ -2312,28 +2322,28 @@ function CPU() {
|
|||
}
|
||||
|
||||
function mkC(op, mn, sz, cc, dp, dr, cycTaken, cyc) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
i.f = null;
|
||||
i.p = {};
|
||||
i.p.z = sz;
|
||||
i.p.c = new iCon(cc, dp, dr);
|
||||
i.p.c = new ICon(cc, dp, dr);
|
||||
if (cycTaken !== null) i.p.cycTaken = cycTaken;
|
||||
if (cyc !== null) i.p.cyc = cyc;
|
||||
return i;
|
||||
}
|
||||
|
||||
function mkDBcc(op, mn, sz, cc, dp, dr, cycTrue, cycFalseTaken, cycFalse) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
i.f = null;
|
||||
i.p = {};
|
||||
i.p.z = sz;
|
||||
i.p.c = new iCon(cc, dp, dr);
|
||||
i.p.c = new ICon(cc, dp, dr);
|
||||
i.p.cycTrue = cycTrue;
|
||||
i.p.cycFalseTaken = cycFalseTaken;
|
||||
i.p.cycFalse = cycFalse;
|
||||
|
|
@ -2341,15 +2351,15 @@ function CPU() {
|
|||
}
|
||||
|
||||
function mkCD(op, mn, z, cc, dp, dr, m, r, cycTrue, cycFalse, add) {
|
||||
var i = new iDef();
|
||||
var i = new IDef();
|
||||
i.op = op;
|
||||
i.pr = false;
|
||||
i.mn = mn;
|
||||
i.f = null;
|
||||
i.p = {};
|
||||
i.p.z = z;
|
||||
i.p.c = new iCon(cc, dp, dr);
|
||||
i.p.d = new effAddr(m, r);
|
||||
i.p.c = new ICon(cc, dp, dr);
|
||||
i.p.d = new EffAddr(m, r);
|
||||
i.p.d.c = mkCyc(z, m);
|
||||
i.p.cycTrue = cycTrue;
|
||||
i.p.cycFalse = cycFalse;
|
||||
|
|
@ -2395,7 +2405,7 @@ function CPU() {
|
|||
|
||||
iTab = new Array(0x10000);
|
||||
for (op = 0; op < 0x10000; op++) {
|
||||
iTab[op] = new iDef();
|
||||
iTab[op] = new IDef();
|
||||
iTab[op].op = -1;
|
||||
iTab[op].pr = false;
|
||||
iTab[op].mn = 'ILLEGAL';
|
||||
|
|
@ -3590,7 +3600,7 @@ function CPU() {
|
|||
op = (275 << 6) | ea[0];
|
||||
|
||||
if (iTab[op].op === -1) {
|
||||
iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
|
||||
iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd);
|
||||
iTab[op].f = I_MOVE_2CCR;
|
||||
cnt++;
|
||||
} else {
|
||||
|
|
@ -3632,7 +3642,7 @@ function CPU() {
|
|||
op = (283 << 6) | ea[0];
|
||||
|
||||
if (iTab[op].op === -1) {
|
||||
iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
|
||||
iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd);
|
||||
iTab[op].pr = true;
|
||||
iTab[op].f = I_MOVE_2SR;
|
||||
cnt++;
|
||||
|
|
@ -4668,29 +4678,29 @@ function CPU() {
|
|||
}
|
||||
|
||||
this.diss = function (offset, limit) {
|
||||
var pc = offset === null ? regs.pc : offset;
|
||||
var cnt = 0;
|
||||
var pc = offset === null ? regs.pc : offset;
|
||||
var cnt = 0;
|
||||
|
||||
while (cnt++ < limit) {
|
||||
var o = '';
|
||||
while (cnt++ < limit) {
|
||||
var o = '';
|
||||
|
||||
o += sprintf('$%08x: ', pc);
|
||||
for (var i = 0; i < 5; i++)
|
||||
o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2));
|
||||
o += sprintf('$%08x: ', pc);
|
||||
for (var i = 0; i < 5; i++)
|
||||
o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2));
|
||||
|
||||
var op = AMIGA.mem.load16(pc);
|
||||
pc += 2;
|
||||
var op = AMIGA.mem.load16(pc);
|
||||
pc += 2;
|
||||
|
||||
var ip = printI(iTab[op], pc);
|
||||
o += ip[0];
|
||||
pc = ip[1];
|
||||
var ip = printI(iTab[op], pc);
|
||||
o += ip[0];
|
||||
pc = ip[1];
|
||||
|
||||
BUG.say(o);
|
||||
}
|
||||
}
|
||||
this.dissFault = function (limit) {
|
||||
this.diss(fault.pc, limit);
|
||||
}
|
||||
BUG.say(o);
|
||||
}
|
||||
};
|
||||
/*this.dissFault = function (limit) {
|
||||
this.diss(fault.pc, limit);
|
||||
};*/
|
||||
|
||||
/*function nextIWordData(data, pc) {
|
||||
return (data[pc] << 8) | data[pc + 1];
|
||||
|
|
@ -4866,37 +4876,37 @@ function CPU() {
|
|||
return getName(AMIGA.mem.load32(task + 10));
|
||||
}
|
||||
|
||||
this.getThisTaskName = function() {
|
||||
var tn = '';
|
||||
/* Extract current task-name form SysBase */
|
||||
var sysBase = AMIGA.mem.load32(4);
|
||||
if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) {
|
||||
var thisTask = AMIGA.mem.load32(sysBase + 276);
|
||||
if (thisTask)
|
||||
tn = getTaskName(thisTask);
|
||||
}
|
||||
return tn;
|
||||
}
|
||||
this.getThisTaskName = function () {
|
||||
var tn = '';
|
||||
/* Extract current task-name form SysBase */
|
||||
var sysBase = AMIGA.mem.load32(4);
|
||||
if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) {
|
||||
var thisTask = AMIGA.mem.load32(sysBase + 276);
|
||||
if (thisTask)
|
||||
tn = getTaskName(thisTask);
|
||||
}
|
||||
return tn;
|
||||
};
|
||||
|
||||
this.dump = function() {
|
||||
var i, out = '', tn = 1 ? this.getThisTaskName() : '';
|
||||
this.dump = function () {
|
||||
var i, out = '', tn = 1 ? this.getThisTaskName() : '';
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>';
|
||||
}
|
||||
//out += '<br/>';
|
||||
out += "\n";
|
||||
for (i = 0; i < 8; i++) {
|
||||
out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>';
|
||||
}
|
||||
//out += '<br/>';
|
||||
out += "\n";
|
||||
out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp);
|
||||
out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn);
|
||||
out += "\n";
|
||||
out += "\n";
|
||||
BUG.say(out);
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>';
|
||||
}
|
||||
//out += '<br/>';
|
||||
out += "\n";
|
||||
for (i = 0; i < 8; i++) {
|
||||
out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>';
|
||||
}
|
||||
//out += '<br/>';
|
||||
out += "\n";
|
||||
out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp);
|
||||
out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn);
|
||||
out += "\n";
|
||||
out += "\n";
|
||||
BUG.say(out);
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
@ -5025,7 +5035,7 @@ function CPU() {
|
|||
regs.t = 0;
|
||||
}
|
||||
|
||||
function exception_cycles(n) {
|
||||
/*function exception_cycles(n) {
|
||||
var c;
|
||||
if (n < 16)
|
||||
switch (n) {
|
||||
|
|
@ -5051,7 +5061,7 @@ function CPU() {
|
|||
c = [4,0,0];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}*/
|
||||
|
||||
function exception(n) {
|
||||
//BUG.say(sprintf('cpu.exception() nr %d', n));
|
||||
|
|
@ -5076,8 +5086,8 @@ function CPU() {
|
|||
if (n == 2) {
|
||||
BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0));
|
||||
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
|
||||
} else if (n == 3) {
|
||||
BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0));
|
||||
|
||||
|
|
@ -5085,14 +5095,14 @@ function CPU() {
|
|||
var wa = 0;
|
||||
var cd = (wa ? 0 : 16) | (olds ? 4 : 0) | (ia ? 2 : 1);
|
||||
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.pc);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, fault.op);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.ad);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, cd);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.pc);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, fault.op);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.ad);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, cd);
|
||||
} else {
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
|
||||
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
|
||||
}
|
||||
|
||||
var pc = AMIGA.mem.load32(n * 4);
|
||||
|
|
@ -5113,14 +5123,14 @@ function CPU() {
|
|||
regs.pc = pc;
|
||||
|
||||
exception_trace(n);
|
||||
return exception_cycles(n);
|
||||
return [4,0,0];//exception_cycles(n);
|
||||
}
|
||||
|
||||
function exception2(ad) {
|
||||
/*function exception2(ad) {
|
||||
fault.ad = ad;
|
||||
fault.ia = 0;
|
||||
throw new Exception23(2);
|
||||
}
|
||||
}*/
|
||||
|
||||
function exception3(ad, ia) {
|
||||
fault.ad = ad;
|
||||
|
|
@ -5139,19 +5149,13 @@ function CPU() {
|
|||
AMIGA.doint();
|
||||
}
|
||||
|
||||
function trace() {
|
||||
if (regs.t) {
|
||||
clr_special(SPCFLAG_TRACE);
|
||||
set_special(SPCFLAG_DOTRACE);
|
||||
}
|
||||
}
|
||||
|
||||
function cycle_spc(cycles) {
|
||||
if (AMIGA.spcflags & SPCFLAG_COPPER)
|
||||
AMIGA.copper.cycle();
|
||||
|
||||
while ((AMIGA.spcflags & SPCFLAG_BLTNASTY) && AMIGA.dmaen(DMAF_BLTEN) && cycles > 0) {
|
||||
var c = AMIGA.blitter.blitnasty();
|
||||
//console.log('nasty', cycles, c);
|
||||
if (c > 0) {
|
||||
cycles -= c * CYCLE_UNIT * 2;
|
||||
if (cycles < CYCLE_UNIT)
|
||||
|
|
@ -5166,6 +5170,7 @@ function CPU() {
|
|||
|
||||
if (AMIGA.spcflags & SPCFLAG_DOTRACE)
|
||||
exception(9);
|
||||
|
||||
if (AMIGA.spcflags & SPCFLAG_TRAP) {
|
||||
clr_special(SPCFLAG_TRAP);
|
||||
exception(3);
|
||||
|
|
@ -5183,21 +5188,26 @@ function CPU() {
|
|||
if (intr > 0 && intr > regs.intmask)
|
||||
interrupt(intr);
|
||||
}
|
||||
/*if (AMIGA.spcflags & SPCFLAG_BRK) {
|
||||
clr_special(SPCFLAG_BRK);
|
||||
//if (AMIGA.spcflags & SPCFLAG_BRK) {
|
||||
if (AMIGA.state != ST_CYCLE) {
|
||||
//clr_special(SPCFLAG_BRK);
|
||||
clr_special(SPCFLAG_STOP);
|
||||
regs.stopped = false;
|
||||
return true;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
if (AMIGA.spcflags & SPCFLAG_TRACE)
|
||||
trace();
|
||||
if (AMIGA.spcflags & SPCFLAG_TRACE) {
|
||||
if (regs.t) {
|
||||
clr_special(SPCFLAG_TRACE);
|
||||
set_special(SPCFLAG_DOTRACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (AMIGA.spcflags & SPCFLAG_INT) {
|
||||
clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
|
||||
var intr = AMIGA.intlev();
|
||||
if (intr > 0 && (intr > regs.intmask || intr == 7))
|
||||
if (intr > 0 && intr > regs.intmask)
|
||||
interrupt(intr);
|
||||
}
|
||||
if (AMIGA.spcflags & SPCFLAG_DOINT) {
|
||||
|
|
|
|||
943
sae/custom.js
943
sae/custom.js
File diff suppressed because it is too large
Load diff
2747
sae/disk.js
2747
sae/disk.js
File diff suppressed because it is too large
Load diff
938
sae/events.js
938
sae/events.js
File diff suppressed because it is too large
Load diff
114
sae/expansion.js
114
sae/expansion.js
|
|
@ -14,7 +14,7 @@ function Board_A2058() {
|
|||
const MEM_2MB = 0x06;
|
||||
const MEM_1MB = 0x05;
|
||||
const MEM_512KB = 0x04;
|
||||
const MEM_256KB = 0x03;
|
||||
//const MEM_256KB = 0x03;
|
||||
//const MEM_128KB = 0x02;
|
||||
//const MEM_64KB = 0x01;
|
||||
|
||||
|
|
@ -80,74 +80,74 @@ function Expansion() {
|
|||
var boards = [];
|
||||
var board = 0;
|
||||
|
||||
this.setup = function() {
|
||||
mem.data = new Uint16Array(0x8000);
|
||||
boards = [];
|
||||
if (AMIGA.mem.fast.size > 0)
|
||||
boards[0] = new Board_A2058();
|
||||
else
|
||||
boards[0] = new Board_Dummy();
|
||||
this.setup = function () {
|
||||
mem.data = new Uint16Array(0x8000);
|
||||
boards = [];
|
||||
if (AMIGA.mem.fast.size > 0)
|
||||
boards[0] = new Board_A2058();
|
||||
else
|
||||
boards[0] = new Board_Dummy();
|
||||
|
||||
for (var i = 1; i < MAX_EXPANSION_BOARDS; i++)
|
||||
boards[i] = new Board_Dummy();
|
||||
}
|
||||
for (var i = 1; i < MAX_EXPANSION_BOARDS; i++)
|
||||
boards[i] = new Board_Dummy();
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
board = 0;
|
||||
this.config(board);
|
||||
}
|
||||
this.reset = function () {
|
||||
board = 0;
|
||||
this.config(board);
|
||||
};
|
||||
|
||||
this.clear = function() {
|
||||
for (var i = 0; i < mem.data.length; i++)
|
||||
mem.data[i] = 0;
|
||||
}
|
||||
this.clear = function () {
|
||||
for (var i = 0; i < mem.data.length; i++)
|
||||
mem.data[i] = 0;
|
||||
};
|
||||
|
||||
this.write = function (addr, value) {
|
||||
mem.data[(addr >> 1)] = (value & 0xf0) << 8;
|
||||
mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12;
|
||||
}
|
||||
mem.data[(addr >> 1)] = (value & 0xf0) << 8;
|
||||
mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12;
|
||||
};
|
||||
|
||||
this.load8 = function (addr) {
|
||||
addr &= 0xffff;
|
||||
var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff;
|
||||
if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42)
|
||||
return value;
|
||||
return ~value & 0xff;
|
||||
}
|
||||
addr &= 0xffff;
|
||||
var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff;
|
||||
if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42)
|
||||
return value;
|
||||
return ~value & 0xff;
|
||||
};
|
||||
|
||||
this.store8 = function (addr, value) {
|
||||
switch (addr & 0xff) {
|
||||
case 0x30:
|
||||
case 0x32:
|
||||
mem.hi = 0;
|
||||
mem.lo = 0;
|
||||
this.write(0x48, 0x00);
|
||||
break;
|
||||
switch (addr & 0xff) {
|
||||
case 0x30:
|
||||
case 0x32:
|
||||
mem.hi = 0;
|
||||
mem.lo = 0;
|
||||
this.write(0x48, 0x00);
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
mem.hi = value;
|
||||
//BUG.info('Expansion.store8() board %d done.', board + 1);
|
||||
++board;
|
||||
if (board <= MAX_EXPANSION_BOARDS)
|
||||
this.config(board);
|
||||
else
|
||||
this.clear();
|
||||
break;
|
||||
case 0x48:
|
||||
mem.hi = value;
|
||||
//BUG.info('Expansion.store8() board %d done.', board + 1);
|
||||
++board;
|
||||
if (board <= MAX_EXPANSION_BOARDS)
|
||||
this.config(board);
|
||||
else
|
||||
this.clear();
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
mem.lo = value;
|
||||
break;
|
||||
case 0x4a:
|
||||
mem.lo = value;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
//BUG.info('Expansion.store8() board %d faild.', board + 1);
|
||||
++board;
|
||||
if (board <= MAX_EXPANSION_BOARDS)
|
||||
this.config(board);
|
||||
else
|
||||
this.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0x4c:
|
||||
//BUG.info('Expansion.store8() board %d faild.', board + 1);
|
||||
++board;
|
||||
if (board <= MAX_EXPANSION_BOARDS)
|
||||
this.config(board);
|
||||
else
|
||||
this.clear();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this.config = function(board) {
|
||||
var info = boards[board].info();
|
||||
|
|
|
|||
699
sae/input.js
699
sae/input.js
|
|
@ -19,55 +19,55 @@ function Mouse() {
|
|||
var lx = -1;
|
||||
var ly = -1;
|
||||
|
||||
this.reset = function() {
|
||||
this.button = [0, 0, 0];
|
||||
cx = cy = 0;
|
||||
lx = ly = -1;
|
||||
}
|
||||
this.reset = function () {
|
||||
this.button = [0, 0, 0];
|
||||
cx = cy = 0;
|
||||
lx = ly = -1;
|
||||
};
|
||||
|
||||
this.mousedown = function (e) {
|
||||
e = e || window.event;
|
||||
if (!e) return;
|
||||
e = e || window.event;
|
||||
if (!e) return;
|
||||
|
||||
this.button[e.button] = true;
|
||||
}
|
||||
this.button[e.button] = true;
|
||||
};
|
||||
|
||||
this.mouseup = function (e) {
|
||||
e = e || window.event;
|
||||
if (!e) return;
|
||||
e = e || window.event;
|
||||
if (!e) return;
|
||||
|
||||
this.button[e.button] = false;
|
||||
}
|
||||
this.button[e.button] = false;
|
||||
};
|
||||
|
||||
this.mouseover = function (e) {
|
||||
//AMIGA.video.hideCursor(1);
|
||||
this.mousemove(e);
|
||||
lx = cx;
|
||||
ly = cy;
|
||||
}
|
||||
//AMIGA.video.hideCursor(1);
|
||||
this.mousemove(e);
|
||||
lx = cx;
|
||||
ly = cy;
|
||||
};
|
||||
|
||||
this.mouseout = function (e) {
|
||||
//AMIGA.video.hideCursor(0);
|
||||
this.mouseup(e);
|
||||
}
|
||||
//AMIGA.video.hideCursor(0);
|
||||
this.mouseup(e);
|
||||
};
|
||||
|
||||
this.mousemove = function (e) {
|
||||
e = e || window.event;
|
||||
if (!e || !AMIGA.video) return;
|
||||
e = e || window.event;
|
||||
if (!e || !AMIGA.video) return;
|
||||
|
||||
if (e.pageX || e.pageY) {
|
||||
cx = e.pageX;
|
||||
cy = e.pageY;
|
||||
} else if (e.clientX || e.clientY) {
|
||||
cx = e.clientX;
|
||||
cy = e.clientY;
|
||||
}
|
||||
if (lx == -1) {
|
||||
lx = cx;
|
||||
ly = cy;
|
||||
}
|
||||
//BUG.info('USER() mousemove %d %d', cx, cy);
|
||||
}
|
||||
if (e.pageX || e.pageY) {
|
||||
cx = e.pageX;
|
||||
cy = e.pageY;
|
||||
} else if (e.clientX || e.clientY) {
|
||||
cx = e.clientX;
|
||||
cy = e.clientY;
|
||||
}
|
||||
if (lx == -1) {
|
||||
lx = cx;
|
||||
ly = cy;
|
||||
}
|
||||
//BUG.info('USER() mousemove %d %d', cx, cy);
|
||||
};
|
||||
|
||||
this.update = function() {
|
||||
if (lx != -1) {
|
||||
|
|
@ -97,13 +97,11 @@ function Joystick(type) {
|
|||
this.button = [false, false, false];
|
||||
this.state = [false, false, false, false];
|
||||
this.dir = 0;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
this.reset = function() {
|
||||
this.button = [false, false, false];
|
||||
this.state = [false, false, false, false];
|
||||
}
|
||||
this.reset = function () {
|
||||
this.button = [false, false, false];
|
||||
this.state = [false, false, false, false];
|
||||
};
|
||||
|
||||
this.update = function() {
|
||||
var u = this.state[1];
|
||||
|
|
@ -144,7 +142,7 @@ function Keyboard() {
|
|||
const RAWKEY_0 = 0x0A;
|
||||
const RAWKEY_MINUS = 0x0B;
|
||||
const RAWKEY_EQUAL = 0x0C;
|
||||
const RAWKEY_BACKSLASH = 0x0D;
|
||||
//const RAWKEY_BACKSLASH = 0x0D;
|
||||
const RAWKEY_KP_0 = 0x0F;
|
||||
const RAWKEY_Q = 0x10;
|
||||
const RAWKEY_W = 0x11;
|
||||
|
|
@ -194,7 +192,7 @@ function Keyboard() {
|
|||
const RAWKEY_SPACE = 0x40;
|
||||
const RAWKEY_BACKSPACE = 0x41;
|
||||
const RAWKEY_TAB = 0x42;
|
||||
const RAWKEY_KP_ENTER = 0x43;
|
||||
//const RAWKEY_KP_ENTER = 0x43;
|
||||
const RAWKEY_RETURN = 0x44;
|
||||
const RAWKEY_ESCAPE = 0x45;
|
||||
const RAWKEY_DELETE = 0x46;
|
||||
|
|
@ -226,7 +224,7 @@ function Keyboard() {
|
|||
const RAWKEY_CAPSLOCK = 0x62;
|
||||
const RAWKEY_CONTROL = 0x63;
|
||||
const RAWKEY_LALT = 0x64;
|
||||
const RAWKEY_RALT = 0x65;
|
||||
//const RAWKEY_RALT = 0x65;
|
||||
const RAWKEY_LAMIGA = 0x66;
|
||||
const RAWKEY_RAMIGA = 0x67;
|
||||
/*const RAWKEY_SCRLOCK = 0x6B;
|
||||
|
|
@ -247,9 +245,9 @@ function Keyboard() {
|
|||
const RAWKEY_NM_WHEEL_LEFT = 0x7C;
|
||||
const RAWKEY_NM_WHEEL_RIGHT = 0x7D;
|
||||
const RAWKEY_NM_BUTTON_FOURTH = 0x7E;*/
|
||||
const RAWKEY_BAD_CODE = 0xF9;
|
||||
/*const RAWKEY_BAD_CODE = 0xF9;
|
||||
const RAWKEY_BUFFER_OVERFLOW = 0xFA;
|
||||
const RAWKEY_SELFTEST_FAILED = 0xFC;
|
||||
const RAWKEY_SELFTEST_FAILED = 0xFC;*/
|
||||
const RAWKEY_INIT_POWER_UP = 0xFD;
|
||||
const RAWKEY_TERM_POWER_UP = 0xFE;
|
||||
|
||||
|
|
@ -486,214 +484,313 @@ function Keyboard() {
|
|||
function _onkeydown(e) { AMIGA.input.keyboard.handleKey(e, true); }
|
||||
function _onkeyup(e) { AMIGA.input.keyboard.handleKey(e, false); }
|
||||
|
||||
this.setup = function() {
|
||||
/*document.onkeydown = function (e) {
|
||||
AMIGA.input.keyboard.keydownup(e, true);
|
||||
}
|
||||
document.onkeyup = function (e) {
|
||||
AMIGA.input.keyboard.keydownup(e, false);
|
||||
}*/
|
||||
window.document.addEventListener('keydown', _onkeydown, false);
|
||||
window.document.addEventListener('keyup', _onkeyup, false);
|
||||
}
|
||||
this.setup = function () {
|
||||
/*document.onkeydown = function (e) {
|
||||
AMIGA.input.keyboard.keydownup(e, true);
|
||||
}
|
||||
document.onkeyup = function (e) {
|
||||
AMIGA.input.keyboard.keydownup(e, false);
|
||||
}*/
|
||||
window.document.addEventListener('keydown', _onkeydown, false);
|
||||
window.document.addEventListener('keyup', _onkeyup, false);
|
||||
};
|
||||
|
||||
this.cleanup = function() {
|
||||
//BUG.info('Keyboard.cleanup()');
|
||||
//document.onkeydown = null;
|
||||
//document.onkeyup = null;
|
||||
window.document.removeEventListener('keydown', _onkeydown, false);
|
||||
window.document.removeEventListener('keyup', _onkeyup, false);
|
||||
}
|
||||
this.cleanup = function () {
|
||||
//BUG.info('Keyboard.cleanup()');
|
||||
//document.onkeydown = null;
|
||||
//document.onkeyup = null;
|
||||
window.document.removeEventListener('keydown', _onkeydown, false);
|
||||
window.document.removeEventListener('keyup', _onkeyup, false);
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
|
||||
state = 0;
|
||||
code = 0;
|
||||
first = last = 0;
|
||||
hsynccnt = 0;
|
||||
this.lostsynccnt = 0;
|
||||
}
|
||||
this.reset = function () {
|
||||
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
|
||||
state = 0;
|
||||
code = 0;
|
||||
first = last = 0;
|
||||
hsynccnt = 0;
|
||||
this.lostsynccnt = 0;
|
||||
};
|
||||
|
||||
this.keysAvail = function() {
|
||||
return first != last;
|
||||
}
|
||||
this.keysAvail = function () {
|
||||
return first != last;
|
||||
};
|
||||
|
||||
this.nextKey = function() {
|
||||
//assert (first != last);
|
||||
var key = keyBuf[last];
|
||||
if (++last == KEYBUFSIZE) last = 0;
|
||||
return key;
|
||||
}
|
||||
this.nextKey = function () {
|
||||
//assert (first != last);
|
||||
var key = keyBuf[last];
|
||||
if (++last == KEYBUFSIZE) last = 0;
|
||||
return key;
|
||||
};
|
||||
|
||||
this.recordKey = function (kc) {
|
||||
var next = first + 1;
|
||||
var next = first + 1;
|
||||
|
||||
if (next == KEYBUFSIZE) next = 0;
|
||||
if (next == last) {
|
||||
BUG.info('Keyboard() buffer overrun!');
|
||||
return false;
|
||||
}
|
||||
keyBuf[first] = kc;
|
||||
first = next;
|
||||
return true;
|
||||
}
|
||||
if (next == KEYBUFSIZE) next = 0;
|
||||
if (next == last) {
|
||||
BUG.info('Keyboard() buffer overrun!');
|
||||
return false;
|
||||
}
|
||||
keyBuf[first] = kc;
|
||||
first = next;
|
||||
return true;
|
||||
};
|
||||
|
||||
this.processKey = function (code, down) {
|
||||
/* Caps-lock */
|
||||
if (code == 20) {
|
||||
if (down) {
|
||||
capsLock = !capsLock;
|
||||
if (!capsLock) return;
|
||||
} else {
|
||||
if (capsLock) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* joystick emul */
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
var l,u,r,d,f1,f2;
|
||||
switch (AMIGA.config.ports[0].move) {
|
||||
case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; }
|
||||
case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; }
|
||||
case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; }
|
||||
}
|
||||
f1 = AMIGA.config.ports[0].fire[0];
|
||||
f2 = AMIGA.config.ports[0].fire[1];
|
||||
switch (code) {
|
||||
case f1: { AMIGA.input.joystick[0].button[0] = down; break; }
|
||||
case f2: { AMIGA.input.joystick[0].button[1] = down; break; }
|
||||
case l: { AMIGA.input.joystick[0].state[0] = down; if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false; break; }
|
||||
case u: { AMIGA.input.joystick[0].state[1] = down; if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false; break; }
|
||||
case r: { AMIGA.input.joystick[0].state[2] = down; if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false; break; }
|
||||
case d: { AMIGA.input.joystick[0].state[3] = down; if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false; break; }
|
||||
}
|
||||
}
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
var l,u,r,d,f1,f2;
|
||||
switch (AMIGA.config.ports[1].move) {
|
||||
case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; }
|
||||
case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; }
|
||||
case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; }
|
||||
}
|
||||
f1 = AMIGA.config.ports[1].fire[0];
|
||||
f2 = AMIGA.config.ports[1].fire[1];
|
||||
switch (code) {
|
||||
case f1: { AMIGA.input.joystick[1].button[0] = down; break; }
|
||||
case f2: { AMIGA.input.joystick[1].button[1] = down; break; }
|
||||
case l: { AMIGA.input.joystick[1].state[0] = down; if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false; break; }
|
||||
case u: { AMIGA.input.joystick[1].state[1] = down; if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false; break; }
|
||||
case r: { AMIGA.input.joystick[1].state[2] = down; if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false; break; }
|
||||
case d: { AMIGA.input.joystick[1].state[3] = down; if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false; break; }
|
||||
}
|
||||
}
|
||||
|
||||
if (!AMIGA.config.keyboard.enabled)
|
||||
return;
|
||||
this.processKey = function (code, down) {
|
||||
/* Caps-lock */
|
||||
if (code == 20) {
|
||||
if (down) {
|
||||
capsLock = !capsLock;
|
||||
if (!capsLock) return;
|
||||
} else {
|
||||
if (capsLock) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* map shift-keys (team17 pinball games) */
|
||||
if (AMIGA.config.keyboard.mapShift) {
|
||||
switch (code) {
|
||||
case 37: { //left arrow
|
||||
var rawkey = RAWKEY_LSHIFT;
|
||||
if (!down) {
|
||||
this.recordKey((rawkey << 1) | 1);
|
||||
} else {
|
||||
this.recordKey(rawkey << 1);
|
||||
}
|
||||
//break;
|
||||
return;
|
||||
}
|
||||
case 39: { //right arrow
|
||||
var rawkey = RAWKEY_RSHIFT;
|
||||
if (!down) {
|
||||
this.recordKey((rawkey << 1) | 1);
|
||||
} else {
|
||||
this.recordKey(rawkey << 1);
|
||||
}
|
||||
//break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* joystick emul */
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
var l, u, r, d, f1, f2;
|
||||
switch (AMIGA.config.ports[0].move) {
|
||||
case SAEV_Config_Ports_Move_Arrows:
|
||||
{
|
||||
l = 37;
|
||||
u = 38;
|
||||
r = 39;
|
||||
d = 40;
|
||||
break;
|
||||
}
|
||||
case SAEV_Config_Ports_Move_Numpad:
|
||||
{
|
||||
l = 100;
|
||||
u = 104;
|
||||
r = 102;
|
||||
d = 101;
|
||||
break;
|
||||
}
|
||||
case SAEV_Config_Ports_Move_WASD:
|
||||
{
|
||||
l = 65;
|
||||
u = 87;
|
||||
r = 68;
|
||||
d = 83;
|
||||
break;
|
||||
}
|
||||
}
|
||||
f1 = AMIGA.config.ports[0].fire[0];
|
||||
f2 = AMIGA.config.ports[0].fire[1];
|
||||
switch (code) {
|
||||
case f1:
|
||||
{
|
||||
AMIGA.input.joystick[0].button[0] = down;
|
||||
break;
|
||||
}
|
||||
case f2:
|
||||
{
|
||||
AMIGA.input.joystick[0].button[1] = down;
|
||||
break;
|
||||
}
|
||||
case l:
|
||||
{
|
||||
AMIGA.input.joystick[0].state[0] = down;
|
||||
if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false;
|
||||
break;
|
||||
}
|
||||
case u:
|
||||
{
|
||||
AMIGA.input.joystick[0].state[1] = down;
|
||||
if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false;
|
||||
break;
|
||||
}
|
||||
case r:
|
||||
{
|
||||
AMIGA.input.joystick[0].state[2] = down;
|
||||
if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false;
|
||||
break;
|
||||
}
|
||||
case d:
|
||||
{
|
||||
AMIGA.input.joystick[0].state[3] = down;
|
||||
if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
var l, u, r, d, f1, f2;
|
||||
switch (AMIGA.config.ports[1].move) {
|
||||
case SAEV_Config_Ports_Move_Arrows:
|
||||
{
|
||||
l = 37;
|
||||
u = 38;
|
||||
r = 39;
|
||||
d = 40;
|
||||
break;
|
||||
}
|
||||
case SAEV_Config_Ports_Move_Numpad:
|
||||
{
|
||||
l = 100;
|
||||
u = 104;
|
||||
r = 102;
|
||||
d = 101;
|
||||
break;
|
||||
}
|
||||
case SAEV_Config_Ports_Move_WASD:
|
||||
{
|
||||
l = 65;
|
||||
u = 87;
|
||||
r = 68;
|
||||
d = 83;
|
||||
break;
|
||||
}
|
||||
}
|
||||
f1 = AMIGA.config.ports[1].fire[0];
|
||||
f2 = AMIGA.config.ports[1].fire[1];
|
||||
switch (code) {
|
||||
case f1:
|
||||
{
|
||||
AMIGA.input.joystick[1].button[0] = down;
|
||||
break;
|
||||
}
|
||||
case f2:
|
||||
{
|
||||
AMIGA.input.joystick[1].button[1] = down;
|
||||
break;
|
||||
}
|
||||
case l:
|
||||
{
|
||||
AMIGA.input.joystick[1].state[0] = down;
|
||||
if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false;
|
||||
break;
|
||||
}
|
||||
case u:
|
||||
{
|
||||
AMIGA.input.joystick[1].state[1] = down;
|
||||
if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false;
|
||||
break;
|
||||
}
|
||||
case r:
|
||||
{
|
||||
AMIGA.input.joystick[1].state[2] = down;
|
||||
if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false;
|
||||
break;
|
||||
}
|
||||
case d:
|
||||
{
|
||||
AMIGA.input.joystick[1].state[3] = down;
|
||||
if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rawkey = false;
|
||||
if (BrowserDetect.browser == 'Firefox') {
|
||||
if (typeof(mozKeyCodeMap[code]) != 'undefined')
|
||||
rawkey = mozKeyCodeMap[code];
|
||||
} else {
|
||||
if (typeof(defKeyCodeMap[code]) != 'undefined')
|
||||
rawkey = defKeyCodeMap[code];
|
||||
}
|
||||
//BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey);
|
||||
if (!AMIGA.config.keyboard.enabled)
|
||||
return;
|
||||
|
||||
if (rawkey !== false) {
|
||||
if (down)
|
||||
this.recordKey(rawkey << 1);
|
||||
else
|
||||
this.recordKey((rawkey << 1) | 1);
|
||||
}
|
||||
}
|
||||
/* map shift-keys (team17 pinball games) */
|
||||
if (AMIGA.config.keyboard.mapShift) {
|
||||
switch (code) {
|
||||
case 37:
|
||||
{ //left arrow
|
||||
if (!down) {
|
||||
this.recordKey((RAWKEY_LSHIFT << 1) | 1);
|
||||
} else {
|
||||
this.recordKey(RAWKEY_LSHIFT << 1);
|
||||
}
|
||||
//break;
|
||||
return;
|
||||
}
|
||||
case 39:
|
||||
{ //right arrow
|
||||
if (!down) {
|
||||
this.recordKey((RAWKEY_RSHIFT << 1) | 1);
|
||||
} else {
|
||||
this.recordKey(RAWKEY_RSHIFT << 1);
|
||||
}
|
||||
//break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rawkey = false;
|
||||
if (BrowserDetect.browser == 'Firefox') {
|
||||
if (typeof(mozKeyCodeMap[code]) != 'undefined')
|
||||
rawkey = mozKeyCodeMap[code];
|
||||
} else {
|
||||
if (typeof(defKeyCodeMap[code]) != 'undefined')
|
||||
rawkey = defKeyCodeMap[code];
|
||||
}
|
||||
//BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey);
|
||||
|
||||
if (rawkey !== false) {
|
||||
if (down)
|
||||
this.recordKey(rawkey << 1);
|
||||
else
|
||||
this.recordKey((rawkey << 1) | 1);
|
||||
}
|
||||
};
|
||||
|
||||
this.handleKey = function (e, down) {
|
||||
e = e || window.event;
|
||||
var code = e.which ? e.which : e.keyCode;
|
||||
e = e || window.event;
|
||||
var code = e.which ? e.which : e.keyCode;
|
||||
|
||||
if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12
|
||||
e.preventDefault();
|
||||
|
||||
//BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0);
|
||||
if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12
|
||||
e.preventDefault();
|
||||
|
||||
/* Ctrl-Alt fix */
|
||||
if (!down && code == 17 && keyState[18]) {
|
||||
keyState[18] = false;
|
||||
this.processKey(18, keyState[18]);
|
||||
}
|
||||
|
||||
var oldstate = keyState[code];
|
||||
if (down && !keyState[code]) {
|
||||
keyState[code] = true;
|
||||
}
|
||||
else if (!down) {
|
||||
keyState[code] = false;
|
||||
}
|
||||
if (keyState[code] != oldstate) {
|
||||
this.processKey(code, keyState[code]);
|
||||
}
|
||||
}
|
||||
//BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0);
|
||||
|
||||
/* Ctrl-Alt fix */
|
||||
if (!down && code == 17 && keyState[18]) {
|
||||
keyState[18] = false;
|
||||
this.processKey(18, keyState[18]);
|
||||
}
|
||||
|
||||
var oldstate = keyState[code];
|
||||
if (down && !keyState[code]) {
|
||||
keyState[code] = true;
|
||||
}
|
||||
else if (!down) {
|
||||
keyState[code] = false;
|
||||
}
|
||||
if (keyState[code] != oldstate) {
|
||||
this.processKey(code, keyState[code]);
|
||||
}
|
||||
};
|
||||
|
||||
this.setCode = function (keycode) {
|
||||
code = ~((keycode << 1) | (keycode >> 7)) & 0xff;
|
||||
}
|
||||
code = ~((keycode << 1) | (keycode >> 7)) & 0xff;
|
||||
};
|
||||
|
||||
this.keyReq = function() {
|
||||
this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; /* 8 frames * 8 bits */
|
||||
this.keyReq = function () {
|
||||
this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8;
|
||||
/* 8 frames * 8 bits */
|
||||
|
||||
//AMIGA.cia.setICR(CIA_A, 8, code);
|
||||
AMIGA.cia.SetICRA(8, code);
|
||||
}
|
||||
//AMIGA.cia.setICR(CIA_A, 8, code);
|
||||
AMIGA.cia.SetICRA(8, code);
|
||||
};
|
||||
|
||||
this.hsync = function() {
|
||||
if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
code = 0;
|
||||
state++;
|
||||
break;
|
||||
case 1:
|
||||
this.setCode(RAWKEY_INIT_POWER_UP);
|
||||
state++;
|
||||
break;
|
||||
case 2:
|
||||
this.setCode(RAWKEY_TERM_POWER_UP);
|
||||
state++;
|
||||
break;
|
||||
case 3:
|
||||
code = ~this.nextKey() & 0xff;
|
||||
break;
|
||||
}
|
||||
this.keyReq();
|
||||
}
|
||||
}
|
||||
this.hsync = function () {
|
||||
if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
code = 0;
|
||||
state++;
|
||||
break;
|
||||
case 1:
|
||||
this.setCode(RAWKEY_INIT_POWER_UP);
|
||||
state++;
|
||||
break;
|
||||
case 2:
|
||||
this.setCode(RAWKEY_TERM_POWER_UP);
|
||||
state++;
|
||||
break;
|
||||
case 3:
|
||||
code = ~this.nextKey() & 0xff;
|
||||
break;
|
||||
}
|
||||
this.keyReq();
|
||||
}
|
||||
};
|
||||
|
||||
this.vsync = function() {
|
||||
if (this.lostsynccnt > 0) {
|
||||
|
|
@ -719,82 +816,82 @@ function Input() {
|
|||
count: 0
|
||||
};
|
||||
|
||||
this.setup = function() {
|
||||
this.keyboard.setup();
|
||||
}
|
||||
this.setup = function () {
|
||||
this.keyboard.setup();
|
||||
};
|
||||
|
||||
this.cleanup = function() {
|
||||
this.keyboard.cleanup();
|
||||
}
|
||||
this.cleanup = function () {
|
||||
this.keyboard.cleanup();
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
this.mouse.reset();
|
||||
this.joystick[0].reset();
|
||||
this.joystick[1].reset();
|
||||
this.keyboard.reset();
|
||||
potgo.data = 0;
|
||||
potgo.count = 0;
|
||||
}
|
||||
this.reset = function () {
|
||||
this.mouse.reset();
|
||||
this.joystick[0].reset();
|
||||
this.joystick[1].reset();
|
||||
this.keyboard.reset();
|
||||
potgo.data = 0;
|
||||
potgo.count = 0;
|
||||
};
|
||||
|
||||
this.POTGO = function (v) {
|
||||
//BUG.info('Input.POTGO() $%04x', v);
|
||||
potgo.data = v;
|
||||
}
|
||||
//BUG.info('Input.POTGO() $%04x', v);
|
||||
potgo.data = v;
|
||||
};
|
||||
|
||||
this.POTGOR = function() {
|
||||
var v = (potgo.data | (potgo.data << 1)) & 0xaa00;
|
||||
v |= v >> 1;
|
||||
this.POTGOR = function () {
|
||||
var v = (potgo.data | (potgo.data << 1)) & 0xaa00;
|
||||
v |= v >> 1;
|
||||
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
if (this.mouse.button[2]) v &= 0xfbff;
|
||||
if (this.mouse.button[1]) v &= 0xfeff;
|
||||
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
if (this.joystick[0].button[1]) v &= 0xfbff;
|
||||
if (this.joystick[0].button[2]) v &= 0xfeff;
|
||||
}
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
if (this.joystick[1].button[1]) v &= 0xbfff;
|
||||
if (this.joystick[1].button[2]) v &= 0xefff;
|
||||
}
|
||||
//BUG.info('Input.POTGOR() $%04x', v);
|
||||
return v;
|
||||
}
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
if (this.mouse.button[2]) v &= 0xfbff;
|
||||
if (this.mouse.button[1]) v &= 0xfeff;
|
||||
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
if (this.joystick[0].button[1]) v &= 0xfbff;
|
||||
if (this.joystick[0].button[2]) v &= 0xfeff;
|
||||
}
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
if (this.joystick[1].button[1]) v &= 0xbfff;
|
||||
if (this.joystick[1].button[2]) v &= 0xefff;
|
||||
}
|
||||
//BUG.info('Input.POTGOR() $%04x', v);
|
||||
return v;
|
||||
};
|
||||
|
||||
this.POT0DAT = function() {
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff);
|
||||
if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff;
|
||||
}
|
||||
//BUG.info('Input.POT0DAT() $%04x', v);
|
||||
return potgo.count;
|
||||
}
|
||||
this.POT0DAT = function () {
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff);
|
||||
if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff;
|
||||
}
|
||||
//BUG.info('Input.POT0DAT() $%04x', v);
|
||||
return potgo.count;
|
||||
};
|
||||
|
||||
this.POT1DAT = function() {
|
||||
//BUG.info('Input.POT1DAT() NOT IMPLEMENTED');
|
||||
return 0xffff;
|
||||
}
|
||||
this.POT1DAT = function () {
|
||||
//BUG.info('Input.POT1DAT() NOT IMPLEMENTED');
|
||||
return 0xffff;
|
||||
};
|
||||
|
||||
this.JOY0DAT = function() {
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
this.mouse.update();
|
||||
return this.mouse.pos;
|
||||
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
this.joystick[0].update();
|
||||
return this.joystick[0].dir;
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
this.JOY0DAT = function () {
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
this.mouse.update();
|
||||
return this.mouse.pos;
|
||||
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
|
||||
this.joystick[0].update();
|
||||
return this.joystick[0].dir;
|
||||
}
|
||||
return 0xffff;
|
||||
};
|
||||
|
||||
this.JOY1DAT = function() {
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
this.mouse.update();
|
||||
return this.mouse.pos;
|
||||
} else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
this.joystick[1].update();
|
||||
return this.joystick[1].dir;
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
this.JOY1DAT = function () {
|
||||
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
this.mouse.update();
|
||||
return this.mouse.pos;
|
||||
} else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
|
||||
this.joystick[1].update();
|
||||
return this.joystick[1].dir;
|
||||
}
|
||||
return 0xffff;
|
||||
};
|
||||
|
||||
this.JOYTEST = function (v) {
|
||||
//BUG.info('Input.JOYTEST() $%04x', v);
|
||||
|
|
|
|||
884
sae/memory.js
884
sae/memory.js
|
|
@ -40,8 +40,8 @@ function Memory() {
|
|||
align: 0,
|
||||
data: null,
|
||||
lower: 0,
|
||||
upper: 0,
|
||||
};
|
||||
upper: 0
|
||||
};
|
||||
this.slow = {
|
||||
enabled: false,
|
||||
size: 0,
|
||||
|
|
@ -91,11 +91,11 @@ function Memory() {
|
|||
lower: 0x00E80000,
|
||||
upper: 0x00E90000
|
||||
};
|
||||
this.aros = {
|
||||
/*this.aros = {
|
||||
cached: false,
|
||||
rom: '',
|
||||
ext: ''
|
||||
};
|
||||
};*/
|
||||
|
||||
function getChipSize(v) {
|
||||
switch (v) {
|
||||
|
|
@ -154,396 +154,403 @@ function Memory() {
|
|||
}
|
||||
}*/
|
||||
|
||||
this.setup = function() {
|
||||
this.chip.size = getChipSize(AMIGA.config.ram.chip.size);
|
||||
this.chip.align = this.chip.size >>> 1;
|
||||
this.chip.data = new Uint16Array(this.chip.align); for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0;
|
||||
this.chip.lower = 0;
|
||||
this.chip.upper = this.chip.size;
|
||||
this.setup = function () {
|
||||
this.chip.size = getChipSize(AMIGA.config.ram.chip.size);
|
||||
this.chip.align = this.chip.size >>> 1;
|
||||
this.chip.data = new Uint16Array(this.chip.align);
|
||||
for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0;
|
||||
this.chip.lower = 0;
|
||||
this.chip.upper = this.chip.size;
|
||||
|
||||
if (AMIGA.config.ram.slow.size) {
|
||||
this.slow.enabled = true;
|
||||
this.slow.size = getSlowSize(AMIGA.config.ram.slow.size);
|
||||
this.slow.align = this.slow.size >>> 1;
|
||||
this.slow.data = new Uint16Array(this.slow.align); for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0;
|
||||
this.slow.upper = this.slow.lower + this.slow.size;
|
||||
} else {
|
||||
this.slow.enabled = false;
|
||||
this.slow.size = 0;
|
||||
this.slow.align = 0;
|
||||
this.slow.data = null;
|
||||
this.slow.upper = 0;
|
||||
}
|
||||
if (AMIGA.config.ram.fast.size) {
|
||||
this.fast.enabled = true;
|
||||
this.fast.size = getFastSize(AMIGA.config.ram.fast.size);
|
||||
this.fast.align = this.fast.size >>> 1;
|
||||
this.fast.data = new Uint16Array(this.fast.align); for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0;
|
||||
this.fast.upper = this.fast.lower + this.fast.size;
|
||||
} else {
|
||||
this.fast.enabled = false;
|
||||
this.fast.size = 0;
|
||||
this.fast.align = 0;
|
||||
this.fast.data = null;
|
||||
this.fast.upper = 0;
|
||||
}
|
||||
BUG.info('Memory.init() chip %d, slow %d, fast %d', this.chip.size >>> 10, this.slow.size >>> 10, this.fast.size >>> 10);
|
||||
if (AMIGA.config.ram.slow.size) {
|
||||
this.slow.enabled = true;
|
||||
this.slow.size = getSlowSize(AMIGA.config.ram.slow.size);
|
||||
this.slow.align = this.slow.size >>> 1;
|
||||
this.slow.data = new Uint16Array(this.slow.align);
|
||||
for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0;
|
||||
this.slow.upper = this.slow.lower + this.slow.size;
|
||||
} else {
|
||||
this.slow.enabled = false;
|
||||
this.slow.size = 0;
|
||||
this.slow.align = 0;
|
||||
this.slow.data = null;
|
||||
this.slow.upper = 0;
|
||||
}
|
||||
if (AMIGA.config.ram.fast.size) {
|
||||
this.fast.enabled = true;
|
||||
this.fast.size = getFastSize(AMIGA.config.ram.fast.size);
|
||||
this.fast.align = this.fast.size >>> 1;
|
||||
this.fast.data = new Uint16Array(this.fast.align);
|
||||
for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0;
|
||||
this.fast.upper = this.fast.lower + this.fast.size;
|
||||
} else {
|
||||
this.fast.enabled = false;
|
||||
this.fast.size = 0;
|
||||
this.fast.align = 0;
|
||||
this.fast.data = null;
|
||||
this.fast.upper = 0;
|
||||
}
|
||||
BUG.info('Memory.init() chip %d, slow %d, fast %d', this.chip.size >>> 10, this.slow.size >>> 10, this.fast.size >>> 10);
|
||||
|
||||
this.rom.size = getROMSize(AMIGA.config.rom.size);
|
||||
this.rom.align = this.rom.size >>> 1;
|
||||
this.rom.data = new Uint16Array(this.rom.align); for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0;
|
||||
|
||||
this.res_d8.data = new Uint16Array(this.res_d8.align); for (var i = 0; i < this.res_d8.align; i++) this.res_d8.data[i] = 0;
|
||||
this.res_e0.data = new Uint16Array(this.res_e0.align); for (var i = 0; i < this.res_e0.align; i++) this.res_e0.data[i] = 0;
|
||||
this.res_f0.data = new Uint16Array(this.res_f0.align); for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0;
|
||||
|
||||
this.copy_rom(AMIGA.config.rom.data);
|
||||
this.rom.size = getROMSize(AMIGA.config.rom.size);
|
||||
this.rom.align = this.rom.size >>> 1;
|
||||
this.rom.data = new Uint16Array(this.rom.align);
|
||||
for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0;
|
||||
|
||||
if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) {
|
||||
if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0)
|
||||
this.copy_e0(AMIGA.config.ext.data);
|
||||
else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0)
|
||||
this.copy_f0(AMIGA.config.ext.data);
|
||||
}
|
||||
//this.mirror_rom_to_chipram();
|
||||
this.res_d8.data = new Uint16Array(this.res_d8.align);
|
||||
for (var i = 0; i < this.res_d8.align; i++) this.res_d8.data[i] = 0;
|
||||
this.res_e0.data = new Uint16Array(this.res_e0.align);
|
||||
for (var i = 0; i < this.res_e0.align; i++) this.res_e0.data[i] = 0;
|
||||
this.res_f0.data = new Uint16Array(this.res_f0.align);
|
||||
for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0;
|
||||
|
||||
/*if (AMIGA.config.rom.mode == 1) {
|
||||
if (!this.aros.cached) {
|
||||
BUG.info('Memory.setup() AROS-ROM is not cached, downloading...');
|
||||
AMIGA.loading += 2;
|
||||
loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) {
|
||||
AMIGA.mem.aros.cached = true;
|
||||
AMIGA.mem.aros.rom = data;
|
||||
AMIGA.mem.copy_rom(data);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) {
|
||||
AMIGA.mem.aros.cached = true;
|
||||
AMIGA.mem.aros.ext = data;
|
||||
AMIGA.mem.copy_e0(data);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
} else {
|
||||
BUG.info('Memory.setup() AROS-ROM is cached, download skipped.');
|
||||
this.copy_rom(this.aros.rom);
|
||||
this.copy_e0(this.aros.ext);
|
||||
}
|
||||
} else {
|
||||
AMIGA.loading++;
|
||||
loadLocal('cfg_rom_name', function(event) {
|
||||
AMIGA.mem.copy_rom(event.target.result);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
if (AMIGA.config.ext.size > 0) {
|
||||
AMIGA.loading++;
|
||||
loadLocal('cfg_ext_name', function(event) {
|
||||
if (AMIGA.config.ext.addr == 0xe00000)
|
||||
AMIGA.mem.copy_e0(event.target.result);
|
||||
else
|
||||
AMIGA.mem.copy_f0(event.target.result);
|
||||
this.copy_rom(AMIGA.config.rom.data);
|
||||
|
||||
AMIGA.loading--;
|
||||
});
|
||||
}
|
||||
}*/
|
||||
}
|
||||
if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) {
|
||||
if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0)
|
||||
this.copy_e0(AMIGA.config.ext.data);
|
||||
else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0)
|
||||
this.copy_f0(AMIGA.config.ext.data);
|
||||
}
|
||||
//this.mirror_rom_to_chipram();
|
||||
|
||||
/*if (AMIGA.config.rom.mode == 1) {
|
||||
if (!this.aros.cached) {
|
||||
BUG.info('Memory.setup() AROS-ROM is not cached, downloading...');
|
||||
AMIGA.loading += 2;
|
||||
loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) {
|
||||
AMIGA.mem.aros.cached = true;
|
||||
AMIGA.mem.aros.rom = data;
|
||||
AMIGA.mem.copy_rom(data);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) {
|
||||
AMIGA.mem.aros.cached = true;
|
||||
AMIGA.mem.aros.ext = data;
|
||||
AMIGA.mem.copy_e0(data);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
} else {
|
||||
BUG.info('Memory.setup() AROS-ROM is cached, download skipped.');
|
||||
this.copy_rom(this.aros.rom);
|
||||
this.copy_e0(this.aros.ext);
|
||||
}
|
||||
} else {
|
||||
AMIGA.loading++;
|
||||
loadLocal('cfg_rom_name', function(event) {
|
||||
AMIGA.mem.copy_rom(event.target.result);
|
||||
AMIGA.loading--;
|
||||
});
|
||||
if (AMIGA.config.ext.size > 0) {
|
||||
AMIGA.loading++;
|
||||
loadLocal('cfg_ext_name', function(event) {
|
||||
if (AMIGA.config.ext.addr == 0xe00000)
|
||||
AMIGA.mem.copy_e0(event.target.result);
|
||||
else
|
||||
AMIGA.mem.copy_f0(event.target.result);
|
||||
|
||||
AMIGA.loading--;
|
||||
});
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
this.load8 = function (addr) {
|
||||
//BUG.info('Memory.load8() addr $%08x', addr);
|
||||
//BUG.info('Memory.load8() addr $%08x', addr);
|
||||
|
||||
if (addr >= 0x000000 && addr < this.chip.size) {
|
||||
return (addr & 1) ? (this.chip.data[addr >>> 1] & 0xff) : (this.chip.data[addr >>> 1] >> 8);
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) {
|
||||
return (addr & 1) ? (this.slow.data[(addr - this.slow.lower) >>> 1] & 0xff) : (this.slow.data[(addr - this.slow.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) {
|
||||
return (addr & 1) ? (this.fast.data[(addr - this.fast.lower) >>> 1] & 0xff) : (this.fast.data[(addr - this.fast.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper) {
|
||||
return (addr & 1) ? (this.rom.data[(addr - this.rom.lower) >>> 1] & 0xff) : (this.rom.data[(addr - this.rom.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000) {
|
||||
return AMIGA.custom.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
|
||||
return AMIGA.cia.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02) {
|
||||
return AMIGA.cia.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000) {
|
||||
return AMIGA.rtc.load8(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) {
|
||||
return (addr & 1) ? (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] & 0xff) : (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) {
|
||||
return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
|
||||
return (addr & 1) ? (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] & 0xff) : (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
|
||||
return AMIGA.expansion.load8(addr);
|
||||
}
|
||||
//else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
if (addr >= 0x000000 && addr < this.chip.size) {
|
||||
return (addr & 1) ? (this.chip.data[addr >>> 1] & 0xff) : (this.chip.data[addr >>> 1] >> 8);
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) {
|
||||
return (addr & 1) ? (this.slow.data[(addr - this.slow.lower) >>> 1] & 0xff) : (this.slow.data[(addr - this.slow.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) {
|
||||
return (addr & 1) ? (this.fast.data[(addr - this.fast.lower) >>> 1] & 0xff) : (this.fast.data[(addr - this.fast.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper) {
|
||||
return (addr & 1) ? (this.rom.data[(addr - this.rom.lower) >>> 1] & 0xff) : (this.rom.data[(addr - this.rom.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000) {
|
||||
return AMIGA.custom.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
|
||||
return AMIGA.cia.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02) {
|
||||
return AMIGA.cia.load8(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000) {
|
||||
return AMIGA.rtc.load8(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) {
|
||||
return (addr & 1) ? (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] & 0xff) : (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) {
|
||||
return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
|
||||
return (addr & 1) ? (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] & 0xff) : (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] >> 8);
|
||||
}
|
||||
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
|
||||
return AMIGA.expansion.load8(addr);
|
||||
}
|
||||
//else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
|
||||
return NULL8;
|
||||
}
|
||||
return NULL8;
|
||||
};
|
||||
|
||||
this.load16 = function (addr) {
|
||||
//BUG.info('Memory.load16() addr $%08x', addr);
|
||||
//BUG.info('Memory.load16() addr $%08x', addr);
|
||||
|
||||
if (addr >= 0 && addr < this.chip.size - 1) {
|
||||
return this.chip.data[addr >>> 1];
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
|
||||
return this.slow.data[(addr - this.slow.lower) >>> 1];
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
|
||||
return this.fast.data[(addr - this.fast.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper - 1) {
|
||||
return this.rom.data[(addr - this.rom.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
|
||||
return AMIGA.custom.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
|
||||
return AMIGA.cia.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
|
||||
return AMIGA.cia.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
|
||||
return AMIGA.rtc.load16(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
|
||||
return this.res_e0.data[(addr - this.res_e0.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
|
||||
return this.res_f0.data[(addr - this.res_f0.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
|
||||
return this.res_d8.data[(addr - this.res_d8.lower) >>> 1];
|
||||
}
|
||||
//else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
if (addr >= 0 && addr < this.chip.size - 1) {
|
||||
return this.chip.data[addr >>> 1];
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
|
||||
return this.slow.data[(addr - this.slow.lower) >>> 1];
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
|
||||
return this.fast.data[(addr - this.fast.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper - 1) {
|
||||
return this.rom.data[(addr - this.rom.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
|
||||
return AMIGA.custom.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
|
||||
return AMIGA.cia.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
|
||||
return AMIGA.cia.load16(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
|
||||
return AMIGA.rtc.load16(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
|
||||
return this.res_e0.data[(addr - this.res_e0.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
|
||||
return this.res_f0.data[(addr - this.res_f0.lower) >>> 1];
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
|
||||
return this.res_d8.data[(addr - this.res_d8.lower) >>> 1];
|
||||
}
|
||||
//else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
|
||||
return NULL16;
|
||||
}
|
||||
return NULL16;
|
||||
};
|
||||
|
||||
this.load32 = function (addr) {
|
||||
//BUG.info('Memory.load32() addr $%08x', addr);
|
||||
//BUG.info('Memory.load32() addr $%08x', addr);
|
||||
|
||||
if (addr >= 0 && addr < this.chip.size - 3) {
|
||||
addr >>>= 1;
|
||||
return ((this.chip.data[addr] << 16) | this.chip.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
return ((this.slow.data[addr] << 16) | this.slow.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper - 3) {
|
||||
addr = (addr - this.rom.lower) >>> 1;
|
||||
return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
|
||||
return AMIGA.custom.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
|
||||
return AMIGA.cia.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
|
||||
return AMIGA.cia.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
|
||||
return AMIGA.rtc.load32(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
return ((this.res_e0.data[addr] << 16) | this.res_e0.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0;
|
||||
}
|
||||
//else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
if (addr >= 0 && addr < this.chip.size - 3) {
|
||||
addr >>>= 1;
|
||||
return ((this.chip.data[addr] << 16) | this.chip.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
return ((this.slow.data[addr] << 16) | this.slow.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.rom.lower && addr < this.rom.upper - 3) {
|
||||
addr = (addr - this.rom.lower) >>> 1;
|
||||
return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
|
||||
return AMIGA.custom.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
|
||||
return AMIGA.cia.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
|
||||
return AMIGA.cia.load32(addr);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
|
||||
return AMIGA.rtc.load32(addr);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
return ((this.res_e0.data[addr] << 16) | this.res_e0.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0;
|
||||
}
|
||||
//else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr);
|
||||
|
||||
return NULL32;
|
||||
}
|
||||
return NULL32;
|
||||
};
|
||||
|
||||
this.store8 = function (addr, value) {
|
||||
//BUG.info('Memory.store8() addr $%08x, val $%02x', addr, value);
|
||||
//BUG.info('Memory.store8() addr $%08x, val $%02x', addr, value);
|
||||
|
||||
if (addr >= 0 && addr < this.chip.size) {
|
||||
if (addr & 1) {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000) {
|
||||
AMIGA.custom.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
|
||||
AMIGA.cia.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02) {
|
||||
AMIGA.cia.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000) {
|
||||
AMIGA.rtc.store8(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = (value << 8) | (this.res_e0.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = (value << 8) | (this.res_f0.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
|
||||
AMIGA.expansion.store8(addr, value);
|
||||
}
|
||||
//else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value);
|
||||
}
|
||||
if (addr >= 0 && addr < this.chip.size) {
|
||||
if (addr & 1) {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000) {
|
||||
AMIGA.custom.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
|
||||
AMIGA.cia.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02) {
|
||||
AMIGA.cia.store8(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000) {
|
||||
AMIGA.rtc.store8(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = (value << 8) | (this.res_e0.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = (value << 8) | (this.res_f0.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
|
||||
if (addr & 1) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value;
|
||||
} else {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff);
|
||||
}
|
||||
}
|
||||
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
|
||||
AMIGA.expansion.store8(addr, value);
|
||||
}
|
||||
//else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value);
|
||||
};
|
||||
|
||||
this.store16 = function (addr, value) {
|
||||
//BUG.info('Memory.store16() addr $%08x, val $%04x', addr, value);
|
||||
//BUG.info('Memory.store16() addr $%08x, val $%04x', addr, value);
|
||||
|
||||
if (addr >= 0 && addr < this.chip.size - 1) {
|
||||
this.chip.data[addr >>> 1] = value;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
|
||||
this.slow.data[(addr - this.slow.lower) >>> 1] = value;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
|
||||
this.fast.data[(addr - this.fast.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
|
||||
AMIGA.custom.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
|
||||
AMIGA.cia.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
|
||||
AMIGA.cia.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
|
||||
AMIGA.rtc.store16(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
|
||||
this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
|
||||
this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
|
||||
this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value;
|
||||
}
|
||||
//else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value);
|
||||
}
|
||||
if (addr >= 0 && addr < this.chip.size - 1) {
|
||||
this.chip.data[addr >>> 1] = value;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
|
||||
this.slow.data[(addr - this.slow.lower) >>> 1] = value;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
|
||||
this.fast.data[(addr - this.fast.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
|
||||
AMIGA.custom.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
|
||||
AMIGA.cia.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
|
||||
AMIGA.cia.store16(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
|
||||
AMIGA.rtc.store16(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
|
||||
this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
|
||||
this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
|
||||
this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value;
|
||||
}
|
||||
//else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value);
|
||||
};
|
||||
|
||||
this.store32 = function (addr, value) {
|
||||
//BUG.info('Memory.store32() addr $%08x, val $%08x', addr, value);
|
||||
//BUG.info('Memory.store32() addr $%08x, val $%08x', addr, value);
|
||||
|
||||
if (addr >= 0 && addr < this.chip.size - 3) {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = value >>> 16;
|
||||
this.chip.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = value >>> 16;
|
||||
this.slow.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = value >>> 16;
|
||||
this.fast.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
|
||||
AMIGA.custom.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
|
||||
AMIGA.cia.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
|
||||
AMIGA.cia.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
|
||||
AMIGA.rtc.store32(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = value >>> 16;
|
||||
this.res_e0.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = value >>> 16;
|
||||
this.res_f0.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = value >>> 16;
|
||||
this.res_d8.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
//else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value);
|
||||
}
|
||||
if (addr >= 0 && addr < this.chip.size - 3) {
|
||||
addr >>>= 1;
|
||||
this.chip.data[addr] = value >>> 16;
|
||||
this.chip.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
|
||||
addr = (addr - this.slow.lower) >>> 1;
|
||||
this.slow.data[addr] = value >>> 16;
|
||||
this.slow.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
|
||||
addr = (addr - this.fast.lower) >>> 1;
|
||||
this.fast.data[addr] = value >>> 16;
|
||||
this.fast.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
|
||||
AMIGA.custom.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
|
||||
AMIGA.cia.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
|
||||
AMIGA.cia.store32(addr, value);
|
||||
}
|
||||
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
|
||||
AMIGA.rtc.store32(addr, value);
|
||||
}
|
||||
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
|
||||
addr = (addr - this.res_e0.lower) >>> 1;
|
||||
this.res_e0.data[addr] = value >>> 16;
|
||||
this.res_e0.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
|
||||
addr = (addr - this.res_f0.lower) >>> 1;
|
||||
this.res_f0.data[addr] = value >>> 16;
|
||||
this.res_f0.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
|
||||
addr = (addr - this.res_d8.lower) >>> 1;
|
||||
this.res_d8.data[addr] = value >>> 16;
|
||||
this.res_d8.data[addr + 1] = value & 0xffff;
|
||||
}
|
||||
//else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value);
|
||||
};
|
||||
|
||||
this.check16_chip = function (addr, size) {
|
||||
return (addr >= 0 && addr + size < this.chip.size - 1);
|
||||
}
|
||||
/*this.load16_chip = function (addr) {
|
||||
/*this.check16_chip = function (addr, size) {
|
||||
return (addr >= 0 && addr + size < this.chip.size - 1);
|
||||
};*/
|
||||
/*this.load16_chip = function (addr) {
|
||||
if (this.check16_chip(addr, 1)) {
|
||||
var v = this.chip.data[addr >>> 1];
|
||||
AMIGA.custom.last_value = v;
|
||||
|
|
@ -572,82 +579,77 @@ function Memory() {
|
|||
AMIGA.custom.last_value = 0xffff;
|
||||
}*/
|
||||
|
||||
this.copy_rom = function(data) {
|
||||
//BUG.info('copyrom() size %d', data.length);
|
||||
//BUG.info('copyrom() crc32 $%08x', crc32(data));
|
||||
|
||||
if (data.length == 0x80000) {
|
||||
/*var lo = crc32(data.substr(0, 0x40000));
|
||||
var hi = crc32(data.substr(0x40000, 0x80000));
|
||||
if (lo != hi) {
|
||||
BUG.info('copyrom() lo crc32 $%08x', lo);
|
||||
BUG.info('copyrom() hi crc32 $%08x', hi);
|
||||
}*/
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
this.rom.lower = 0xf80000;
|
||||
}
|
||||
else if (data.length == 0x40000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
|
||||
this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff);
|
||||
this.rom.data[0x20000 + j] = (v << 8) | (this.rom.data[0x20000 + j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
this.rom.lower = 0xfc0000;
|
||||
}
|
||||
}
|
||||
this.copy_rom = function (data) {
|
||||
//BUG.info('copyrom() size %d', data.length);
|
||||
//BUG.info('copyrom() crc32 $%08x', crc32(data));
|
||||
|
||||
if (data.length == 0x80000) {
|
||||
/*var lo = crc32(data.substr(0, 0x40000));
|
||||
var hi = crc32(data.substr(0x40000, 0x80000));
|
||||
if (lo != hi) {
|
||||
BUG.info('copyrom() lo crc32 $%08x', lo);
|
||||
BUG.info('copyrom() hi crc32 $%08x', hi);
|
||||
}*/
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
this.rom.lower = 0xf80000;
|
||||
}
|
||||
else if (data.length == 0x40000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
|
||||
this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff);
|
||||
this.rom.data[0x20000 + j] = (v << 8) | (this.rom.data[0x20000 + j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
this.rom.lower = 0xfc0000;
|
||||
}
|
||||
};
|
||||
|
||||
this.copy_e0 = function(data) {
|
||||
if (data.length <= 0x80000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.copy_f0 = function(data) {
|
||||
if (data.length <= 0x80000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.res_f0.data[j] = (v << 8) | (this.res_f0.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.copy_e0 = function (data) {
|
||||
if (data.length <= 0x80000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
this.copy_f0 = function (data) {
|
||||
if (data.length <= 0x80000) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var v = data.charCodeAt(i) & 0xff;
|
||||
if (i & 1) {
|
||||
var j = i >>> 1;
|
||||
this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v;
|
||||
} else {
|
||||
var j = i >>> 1;
|
||||
this.res_f0.data[j] = (v << 8) | (this.res_f0.data[j] & 0x00ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.mirror_rom_to_chipram = function() {
|
||||
/*this.mirror_rom_to_chipram = function() {
|
||||
for (var i = 0; i < this.rom.size; i++)
|
||||
this.chip.data[i] = this.rom.data[i];
|
||||
|
||||
/*if (this.ext.size > 0) {
|
||||
for (var i = 0; i < this.ext.size; i++)
|
||||
this.chip.data[this.rom.size + i] = this.ext.data[i];
|
||||
}*/
|
||||
}
|
||||
}*/
|
||||
}
|
||||
7483
sae/playfield.js
7483
sae/playfield.js
File diff suppressed because it is too large
Load diff
330
sae/rtc.js
330
sae/rtc.js
|
|
@ -18,171 +18,215 @@ function RTC() {
|
|||
var rtc_memory = null;
|
||||
var rtc_alarm = null;
|
||||
|
||||
this.read = function() {
|
||||
/*struct zfile *f;
|
||||
f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
|
||||
if (f) {
|
||||
zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fclose (f);
|
||||
}*/
|
||||
}
|
||||
this.write = function() {
|
||||
/*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
|
||||
if (!f) {
|
||||
f = zfile_fopen (currprefs.flashfile, L"wb", 0);
|
||||
if (f) {
|
||||
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fclose (f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
zfile_fseek (f, 0, SEEK_END);
|
||||
if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) {
|
||||
zfile_fseek (f, 0, SEEK_SET);
|
||||
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
}
|
||||
zfile_fclose (f);*/
|
||||
}
|
||||
this.read = function () {
|
||||
/*struct zfile *f;
|
||||
f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
|
||||
if (f) {
|
||||
zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fclose (f);
|
||||
}*/
|
||||
};
|
||||
this.write = function () {
|
||||
/*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
|
||||
if (!f) {
|
||||
f = zfile_fopen (currprefs.flashfile, L"wb", 0);
|
||||
if (f) {
|
||||
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fclose (f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
zfile_fseek (f, 0, SEEK_END);
|
||||
if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) {
|
||||
zfile_fseek (f, 0, SEEK_SET);
|
||||
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
|
||||
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
|
||||
}
|
||||
zfile_fclose (f);*/
|
||||
};
|
||||
|
||||
this.setup = function() {
|
||||
BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A'));
|
||||
this.setup = function () {
|
||||
BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A'));
|
||||
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
clock_control_d = 0x1;
|
||||
clock_control_e = 0;
|
||||
clock_control_f = 0x4; /* 24/12 */
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
clock_control_d = 0x4; /* Timer EN */
|
||||
clock_control_e = 0;
|
||||
clock_control_f = 0;
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
clock_control_d = 0x1;
|
||||
clock_control_e = 0;
|
||||
clock_control_f = 0x4;
|
||||
/* 24/12 */
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
clock_control_d = 0x4;
|
||||
/* Timer EN */
|
||||
clock_control_e = 0;
|
||||
clock_control_f = 0;
|
||||
|
||||
rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE);
|
||||
rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE);
|
||||
rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE);
|
||||
rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE);
|
||||
|
||||
for (var i = 0; i < RF5C01A_RAM_SIZE; i++)
|
||||
rtc_memory[i] = rtc_alarm[i] = 0;
|
||||
for (var i = 0; i < RF5C01A_RAM_SIZE; i++)
|
||||
rtc_memory[i] = rtc_alarm[i] = 0;
|
||||
|
||||
this.read();
|
||||
}
|
||||
}
|
||||
this.read();
|
||||
}
|
||||
};
|
||||
|
||||
this.load8 = function (addr) {
|
||||
addr &= 0x3f;
|
||||
if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) {
|
||||
if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible)
|
||||
return 0xff; //regs.irc >> 8;
|
||||
return 0;
|
||||
}
|
||||
var t = new Date();
|
||||
addr &= 0x3f;
|
||||
if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) {
|
||||
if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible)
|
||||
return 0xff; //regs.irc >> 8;
|
||||
return 0;
|
||||
}
|
||||
var t = new Date();
|
||||
|
||||
addr >>= 2;
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
switch (addr) {
|
||||
case 0x0: return t.getSeconds() % 10;
|
||||
case 0x1: return Math.floor(t.getSeconds() / 10);
|
||||
case 0x2: return t.getMinutes() % 10;
|
||||
case 0x3: return Math.floor(t.getMinutes() / 10);
|
||||
case 0x4: return t.getHours() % 10;
|
||||
case 0x5: return Math.floor(t.getHours() / 10);
|
||||
case 0x6: return t.getDate() % 10;
|
||||
case 0x7: return Math.floor(t.getDate() / 10);
|
||||
case 0x8: return (t.getMonth() + 1) % 10;
|
||||
case 0x9: return Math.floor((t.getMonth() + 1) / 10);
|
||||
case 0xA: return (t.getFullYear() - 1900) % 10;
|
||||
case 0xB: return Math.floor((t.getFullYear() - 1900) / 10);
|
||||
case 0xC: return t.getDay();
|
||||
case 0xD: return clock_control_d;
|
||||
case 0xE: return clock_control_e;
|
||||
case 0xF: return clock_control_f;
|
||||
}
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
var bank = clock_control_d & 3;
|
||||
addr >>= 2;
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
switch (addr) {
|
||||
case 0x0:
|
||||
return t.getSeconds() % 10;
|
||||
case 0x1:
|
||||
return Math.floor(t.getSeconds() / 10);
|
||||
case 0x2:
|
||||
return t.getMinutes() % 10;
|
||||
case 0x3:
|
||||
return Math.floor(t.getMinutes() / 10);
|
||||
case 0x4:
|
||||
return t.getHours() % 10;
|
||||
case 0x5:
|
||||
return Math.floor(t.getHours() / 10);
|
||||
case 0x6:
|
||||
return t.getDate() % 10;
|
||||
case 0x7:
|
||||
return Math.floor(t.getDate() / 10);
|
||||
case 0x8:
|
||||
return (t.getMonth() + 1) % 10;
|
||||
case 0x9:
|
||||
return Math.floor((t.getMonth() + 1) / 10);
|
||||
case 0xA:
|
||||
return (t.getFullYear() - 1900) % 10;
|
||||
case 0xB:
|
||||
return Math.floor((t.getFullYear() - 1900) / 10);
|
||||
case 0xC:
|
||||
return t.getDay();
|
||||
case 0xD:
|
||||
return clock_control_d;
|
||||
case 0xE:
|
||||
return clock_control_e;
|
||||
case 0xF:
|
||||
return clock_control_f;
|
||||
}
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
var bank = clock_control_d & 3;
|
||||
|
||||
if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
|
||||
if (bank == 1 && addr < 0x0d) return rtc_alarm[addr];
|
||||
if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
|
||||
if (bank == 1 && addr < 0x0d) return rtc_alarm[addr];
|
||||
|
||||
switch (addr) {
|
||||
case 0x0: return t.getSeconds() % 10;
|
||||
case 0x1: return Math.floor(t.getSeconds() / 10);
|
||||
case 0x2: return t.getMinutes() % 10;
|
||||
case 0x3: return Math.floor(t.getMinutes() / 10);
|
||||
case 0x4: return t.getHours() % 10;
|
||||
case 0x5: return Math.floor(t.getHours() / 10);
|
||||
case 0x6: return t.getDate() % 10;
|
||||
case 0x7: return Math.floor(t.getDate() / 10);
|
||||
case 0x8: return (t.getMonth() + 1) % 10;
|
||||
case 0x9: return Math.floor((t.getMonth() + 1) / 10);
|
||||
case 0xA: return (t.getFullYear() - 1900) % 10;
|
||||
case 0xB: return Math.floor((t.getFullYear() - 1900) / 10);
|
||||
case 0xC: return t.getDay();
|
||||
case 0xD: return clock_control_d;
|
||||
/* E and F = write-only */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
switch (addr) {
|
||||
case 0x0:
|
||||
return t.getSeconds() % 10;
|
||||
case 0x1:
|
||||
return Math.floor(t.getSeconds() / 10);
|
||||
case 0x2:
|
||||
return t.getMinutes() % 10;
|
||||
case 0x3:
|
||||
return Math.floor(t.getMinutes() / 10);
|
||||
case 0x4:
|
||||
return t.getHours() % 10;
|
||||
case 0x5:
|
||||
return Math.floor(t.getHours() / 10);
|
||||
case 0x6:
|
||||
return t.getDate() % 10;
|
||||
case 0x7:
|
||||
return Math.floor(t.getDate() / 10);
|
||||
case 0x8:
|
||||
return (t.getMonth() + 1) % 10;
|
||||
case 0x9:
|
||||
return Math.floor((t.getMonth() + 1) / 10);
|
||||
case 0xA:
|
||||
return (t.getFullYear() - 1900) % 10;
|
||||
case 0xB:
|
||||
return Math.floor((t.getFullYear() - 1900) / 10);
|
||||
case 0xC:
|
||||
return t.getDay();
|
||||
case 0xD:
|
||||
return clock_control_d;
|
||||
/* E and F = write-only */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
this.load16 = function (addr) {
|
||||
return (this.load8(addr) << 8) | this.load8(addr + 1);
|
||||
}
|
||||
return (this.load8(addr) << 8) | this.load8(addr + 1);
|
||||
};
|
||||
|
||||
this.load32 = function (addr) {
|
||||
return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0;
|
||||
}
|
||||
return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0;
|
||||
};
|
||||
|
||||
this.store8 = function (addr, value) {
|
||||
addr &= 0x3f;
|
||||
if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return;
|
||||
addr &= 0x3f;
|
||||
if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return;
|
||||
|
||||
addr >>= 2;
|
||||
value &= 0x0f;
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
switch (addr) {
|
||||
case 0xD: clock_control_d = value & (1 | 8); break;
|
||||
case 0xE: clock_control_e = value; break;
|
||||
case 0xF: clock_control_f = value; break;
|
||||
}
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
var bank = clock_control_d & 3;
|
||||
addr >>= 2;
|
||||
value &= 0x0f;
|
||||
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
|
||||
switch (addr) {
|
||||
case 0xD:
|
||||
clock_control_d = value & (1 | 8);
|
||||
break;
|
||||
case 0xE:
|
||||
clock_control_e = value;
|
||||
break;
|
||||
case 0xF:
|
||||
clock_control_f = value;
|
||||
break;
|
||||
}
|
||||
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
|
||||
var bank = clock_control_d & 3;
|
||||
|
||||
if (bank >= 2 && addr < 0x0d) {
|
||||
rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
|
||||
rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
|
||||
|
||||
var ov = rtc_memory[addr];
|
||||
if (rtc_memory[addr] != value) this.write();
|
||||
return;
|
||||
}
|
||||
if (bank == 1 && addr < 0x0d) {
|
||||
rtc_alarm[addr] = value;
|
||||
rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
|
||||
rtc_alarm[3] &= ~0x8;
|
||||
rtc_alarm[5] &= ~0xc;
|
||||
rtc_alarm[6] &= ~0x8;
|
||||
rtc_alarm[8] &= ~0xc;
|
||||
rtc_alarm[10] &= ~0xe;
|
||||
rtc_alarm[11] &= ~0xc;
|
||||
if (bank >= 2 && addr < 0x0d) {
|
||||
rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
|
||||
rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
|
||||
|
||||
var ov = rtc_alarm[addr];
|
||||
if (rtc_alarm[addr] != value) this.write();
|
||||
return;
|
||||
}
|
||||
switch (addr) {
|
||||
case 0xD: clock_control_d = value; break;
|
||||
case 0xE: clock_control_e = value; break;
|
||||
case 0xF: clock_control_f = value; break;
|
||||
}
|
||||
}
|
||||
//var ov = rtc_memory[addr];
|
||||
if (rtc_memory[addr] != value) this.write();
|
||||
return;
|
||||
}
|
||||
if (bank == 1 && addr < 0x0d) {
|
||||
rtc_alarm[addr] = value;
|
||||
rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
|
||||
rtc_alarm[3] &= ~0x8;
|
||||
rtc_alarm[5] &= ~0xc;
|
||||
rtc_alarm[6] &= ~0x8;
|
||||
rtc_alarm[8] &= ~0xc;
|
||||
rtc_alarm[10] &= ~0xe;
|
||||
rtc_alarm[11] &= ~0xc;
|
||||
|
||||
}
|
||||
//var ov = rtc_alarm[addr];
|
||||
if (rtc_alarm[addr] != value) this.write();
|
||||
return;
|
||||
}
|
||||
switch (addr) {
|
||||
case 0xD:
|
||||
clock_control_d = value;
|
||||
break;
|
||||
case 0xE:
|
||||
clock_control_e = value;
|
||||
break;
|
||||
case 0xF:
|
||||
clock_control_f = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.store16 = function (addr, value) {
|
||||
this.store8(addr, (value >> 8) & 0xff);
|
||||
this.store8(addr + 1, value & 0xff);
|
||||
}
|
||||
this.store8(addr, (value >> 8) & 0xff);
|
||||
this.store8(addr + 1, value & 0xff);
|
||||
};
|
||||
|
||||
this.store32 = function (addr, value) {
|
||||
this.store16(addr, (value >>> 16) & 0xffff);
|
||||
|
|
|
|||
110
sae/serial.js
110
sae/serial.js
|
|
@ -14,69 +14,65 @@ function Serial()
|
|||
var pos = 0, dtr = false;
|
||||
var serper = 0, serdat = 0x2000;
|
||||
|
||||
this.reset = function()
|
||||
{
|
||||
this.flushBuffer();
|
||||
|
||||
pos = 0;
|
||||
dtr = false;
|
||||
serper = 0;
|
||||
serdat = 0x2000;
|
||||
}
|
||||
this.reset = function () {
|
||||
this.flushBuffer();
|
||||
|
||||
pos = 0;
|
||||
dtr = false;
|
||||
serper = 0;
|
||||
serdat = 0x2000;
|
||||
};
|
||||
|
||||
this.flushBuffer = function()
|
||||
{
|
||||
if (pos > 0) {
|
||||
var str = ''
|
||||
for (var i = 0; i < pos; i++) {
|
||||
/*if (buf[i] == 13)
|
||||
str += '<br/>';
|
||||
else if (buf[i] == 9)
|
||||
str += ' ';
|
||||
else*/
|
||||
str += String.fromCharCode(buf[i]);
|
||||
}
|
||||
pos = 0;
|
||||
BUG.col = 3;
|
||||
BUG.info(str);
|
||||
BUG.col = 1;
|
||||
}
|
||||
}
|
||||
this.flushBuffer = function () {
|
||||
if (pos > 0) {
|
||||
var str = '';
|
||||
for (var i = 0; i < pos; i++) {
|
||||
/*if (buf[i] == 13)
|
||||
str += '<br/>';
|
||||
else if (buf[i] == 9)
|
||||
str += ' ';
|
||||
else*/
|
||||
str += String.fromCharCode(buf[i]);
|
||||
}
|
||||
pos = 0;
|
||||
BUG.col = 3;
|
||||
BUG.info(str);
|
||||
BUG.col = 1;
|
||||
}
|
||||
};
|
||||
|
||||
this.readStatus = function()
|
||||
{
|
||||
//ciabpra |= 0x20; //Push up Carrier Detect line
|
||||
//ciabpra |= 0x08; //DSR ON
|
||||
return 0;
|
||||
}
|
||||
this.readStatus = function () {
|
||||
//ciabpra |= 0x20; //Push up Carrier Detect line
|
||||
//ciabpra |= 0x08; //DSR ON
|
||||
return 0;
|
||||
};
|
||||
|
||||
this.writeStatus = function(old, nw)
|
||||
{
|
||||
if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true;
|
||||
if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false;
|
||||
//if ((old & 0x40) != (nw & 0x40)) BUG.info('RTS %s.', (nw & 0x40) == 0x40 ? 'set' : 'clr');
|
||||
//if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr');
|
||||
return nw;
|
||||
}
|
||||
this.writeStatus = function (old, nw) {
|
||||
if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true;
|
||||
if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false;
|
||||
//if ((old & 0x40) != (nw & 0x40)) BUG.info('RTS %s.', (nw & 0x40) == 0x40 ? 'set' : 'clr');
|
||||
//if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr');
|
||||
return nw;
|
||||
};
|
||||
|
||||
this.SERPER = function(v)
|
||||
{
|
||||
if (serper != v)
|
||||
serper = v;
|
||||
}
|
||||
this.SERPER = function (v) {
|
||||
if (serper != v)
|
||||
serper = v;
|
||||
};
|
||||
|
||||
this.SERDAT = function(v)
|
||||
{
|
||||
//BUG.info('SERDAT $%04x', v);
|
||||
this.SERDAT = function (v) {
|
||||
//BUG.info('SERDAT $%04x', v);
|
||||
|
||||
if (AMIGA.config.serial.enabled) {
|
||||
buf[pos++] = v & 0xff;
|
||||
if (pos == 1024)
|
||||
this.flushBuffer();
|
||||
}
|
||||
serdat |= 0x2000; /* Set TBE in the SERDATR ... */
|
||||
AMIGA.intreq |= 1; /* ... and in INTREQ register */
|
||||
}
|
||||
if (AMIGA.config.serial.enabled) {
|
||||
buf[pos++] = v & 0xff;
|
||||
if (pos == 1024)
|
||||
this.flushBuffer();
|
||||
}
|
||||
serdat |= 0x2000;
|
||||
/* Set TBE in the SERDATR ... */
|
||||
AMIGA.intreq |= 1;
|
||||
/* ... and in INTREQ register */
|
||||
};
|
||||
|
||||
this.SERDATR = function()
|
||||
{
|
||||
|
|
|
|||
351
sae/utils.js
351
sae/utils.js
|
|
@ -10,18 +10,18 @@
|
|||
|
||||
/* moving average algorithm */
|
||||
|
||||
function mavg(size) {
|
||||
function MAvg(size) {
|
||||
this.values = new Array(size);
|
||||
this.size = size;
|
||||
this.usage = 0;
|
||||
this.offset = 0;
|
||||
this.average = 0;
|
||||
|
||||
this.clr = function() {
|
||||
this.usage = 0;
|
||||
this.offset = 0;
|
||||
this.average = 0;
|
||||
}
|
||||
this.clr = function () {
|
||||
this.usage = 0;
|
||||
this.offset = 0;
|
||||
this.average = 0;
|
||||
};
|
||||
|
||||
this.set = function(newval) {
|
||||
if (this.usage < this.size) {
|
||||
|
|
@ -92,131 +92,127 @@ function mavg(size) {
|
|||
*/
|
||||
|
||||
sprintfWrapper = {
|
||||
init: function () {
|
||||
if (typeof arguments == "undefined") {
|
||||
return null;
|
||||
}
|
||||
if (arguments.length < 1) {
|
||||
return null;
|
||||
}
|
||||
if (typeof arguments[0] != "string") {
|
||||
return null;
|
||||
}
|
||||
if (typeof RegExp == "undefined") {
|
||||
return null;
|
||||
}
|
||||
init: function () {
|
||||
if (typeof arguments == "undefined") {
|
||||
return null;
|
||||
}
|
||||
if (arguments.length < 1) {
|
||||
return null;
|
||||
}
|
||||
if (typeof arguments[0] != "string") {
|
||||
return null;
|
||||
}
|
||||
if (typeof RegExp == "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
var string = arguments[0];
|
||||
var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
|
||||
var matches = new Array();
|
||||
var strings = new Array();
|
||||
var convCount = 0;
|
||||
var stringPosStart = 0;
|
||||
var stringPosEnd = 0;
|
||||
var matchPosEnd = 0;
|
||||
var newString = '';
|
||||
var match = null;
|
||||
var string = arguments[0];
|
||||
var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
|
||||
var matches = [];
|
||||
var strings = [];
|
||||
var convCount = 0;
|
||||
var stringPosStart = 0;
|
||||
var stringPosEnd = 0;
|
||||
var matchPosEnd = 0;
|
||||
var newString = '';
|
||||
var match;
|
||||
|
||||
while (match = exp.exec(string)) {
|
||||
if (match[9]) {
|
||||
convCount += 1;
|
||||
}
|
||||
while (match = exp.exec(string)) {
|
||||
if (match[9]) {
|
||||
convCount += 1;
|
||||
}
|
||||
|
||||
stringPosStart = matchPosEnd;
|
||||
stringPosEnd = exp.lastIndex - match[0].length;
|
||||
strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
|
||||
stringPosStart = matchPosEnd;
|
||||
stringPosEnd = exp.lastIndex - match[0].length;
|
||||
strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
|
||||
|
||||
matchPosEnd = exp.lastIndex;
|
||||
matches[matches.length] = {
|
||||
match: match[0],
|
||||
left: match[3] ? true : false,
|
||||
sign: match[4] || '',
|
||||
pad: match[5] || ' ',
|
||||
min: match[6] || 0,
|
||||
precision: match[8],
|
||||
code: match[9] || '%',
|
||||
negative: parseInt(arguments[convCount]) < 0 ? true : false,
|
||||
argument: String(arguments[convCount])
|
||||
};
|
||||
}
|
||||
strings[strings.length] = string.substring(matchPosEnd);
|
||||
matchPosEnd = exp.lastIndex;
|
||||
matches[matches.length] = {
|
||||
match: match[0],
|
||||
left: match[3] ? true : false,
|
||||
sign: match[4] || '',
|
||||
pad: match[5] || ' ',
|
||||
min: match[6] || 0,
|
||||
precision: match[8],
|
||||
code: match[9] || '%',
|
||||
negative: !!(parseInt(arguments[convCount]) < 0),
|
||||
argument: String(arguments[convCount])
|
||||
};
|
||||
}
|
||||
strings[strings.length] = string.substring(matchPosEnd);
|
||||
|
||||
if (matches.length == 0) {
|
||||
return string;
|
||||
}
|
||||
if ((arguments.length - 1) < convCount) {
|
||||
return null;
|
||||
}
|
||||
if (matches.length == 0) {
|
||||
return string;
|
||||
}
|
||||
if ((arguments.length - 1) < convCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var code = null;
|
||||
var match = null;
|
||||
var i = null;
|
||||
for (var i = 0; i < matches.length; i++) {
|
||||
var substitution;
|
||||
|
||||
for (i = 0; i < matches.length; i++) {
|
||||
if (matches[i].code == '%') {
|
||||
substitution = '%'
|
||||
} else if (matches[i].code == 'b') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'c') {
|
||||
matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'd') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'f') {
|
||||
matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'o') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 's') {
|
||||
matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'x') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'X') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
|
||||
substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
|
||||
} else {
|
||||
substitution = matches[i].match;
|
||||
}
|
||||
newString += strings[i];
|
||||
newString += substitution;
|
||||
|
||||
if (matches[i].code == '%') {
|
||||
substitution = '%'
|
||||
} else if (matches[i].code == 'b') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'c') {
|
||||
matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'd') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'f') {
|
||||
matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'o') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 's') {
|
||||
matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
|
||||
substitution = sprintfWrapper.convert(matches[i], true);
|
||||
} else if (matches[i].code == 'x') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
|
||||
substitution = sprintfWrapper.convert(matches[i]);
|
||||
} else if (matches[i].code == 'X') {
|
||||
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
|
||||
substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
|
||||
} else {
|
||||
substitution = matches[i].match;
|
||||
}
|
||||
}
|
||||
newString += strings[i];
|
||||
|
||||
newString += strings[i];
|
||||
newString += substitution;
|
||||
return newString;
|
||||
|
||||
}
|
||||
newString += strings[i];
|
||||
},
|
||||
|
||||
return newString;
|
||||
|
||||
},
|
||||
|
||||
convert: function (match, nosign) {
|
||||
if (nosign) {
|
||||
match.sign = '';
|
||||
} else {
|
||||
match.sign = match.negative ? '-' : match.sign;
|
||||
}
|
||||
var l = match.min - match.argument.length + 1 - match.sign.length;
|
||||
var pad = new Array(l < 0 ? 0 : l).join(match.pad);
|
||||
if (!match.left) {
|
||||
if (match.pad == "0" || nosign) {
|
||||
return match.sign + pad + match.argument;
|
||||
} else {
|
||||
return pad + match.sign + match.argument;
|
||||
}
|
||||
} else {
|
||||
if (match.pad == "0" || nosign) {
|
||||
return match.sign + match.argument + pad.replace(/0/g, ' ');
|
||||
} else {
|
||||
return match.sign + match.argument + pad;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
convert: function (match, nosign) {
|
||||
if (nosign) {
|
||||
match.sign = '';
|
||||
} else {
|
||||
match.sign = match.negative ? '-' : match.sign;
|
||||
}
|
||||
var l = match.min - match.argument.length + 1 - match.sign.length;
|
||||
var pad = new Array(l < 0 ? 0 : l).join(match.pad);
|
||||
if (!match.left) {
|
||||
if (match.pad == "0" || nosign) {
|
||||
return match.sign + pad + match.argument;
|
||||
} else {
|
||||
return pad + match.sign + match.argument;
|
||||
}
|
||||
} else {
|
||||
if (match.pad == "0" || nosign) {
|
||||
return match.sign + match.argument + pad.replace(/0/g, ' ');
|
||||
} else {
|
||||
return match.sign + match.argument + pad;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sprintf = sprintfWrapper.init;
|
||||
|
||||
|
|
@ -240,10 +236,11 @@ var BrowserDetect = {
|
|||
if (dataString.indexOf(data[i].subString) != -1) return data[i].identity;
|
||||
} else if (dataProp) return data[i].identity;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
searchVersion: function (dataString) {
|
||||
var index = dataString.indexOf(this.versionSearchString);
|
||||
if (index == -1) return;
|
||||
if (index == -1) return 0.0;
|
||||
return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
|
||||
},
|
||||
dataBrowser: [{
|
||||
|
|
@ -323,7 +320,7 @@ BrowserDetect.init();
|
|||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
function dump(obj) {
|
||||
/*function dump(obj) {
|
||||
var out = '';
|
||||
if (obj) {
|
||||
for (var i in obj) {
|
||||
|
|
@ -333,7 +330,7 @@ function dump(obj) {
|
|||
out = 'undefined';
|
||||
|
||||
alert(out);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
|
@ -396,25 +393,25 @@ function loadRemote(file, crc, callback) {
|
|||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
function Debug() {
|
||||
this.col = 1;
|
||||
//this.col = 1;
|
||||
this.on = 1;
|
||||
|
||||
this.say = function (str) {
|
||||
if (this.on) {
|
||||
/*var e = document.createElement('span');
|
||||
e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484');
|
||||
e.innerHTML = buf;
|
||||
this.debug.appendChild(e);
|
||||
this.debug.appendChild(document.createElement('br'));
|
||||
this.debug.scrollTop = this.debug.scrollHeight;*/
|
||||
|
||||
console.log(str);
|
||||
/*console.info(str);
|
||||
console.warn(str);
|
||||
console.error(str);
|
||||
console.assert(str);*/
|
||||
}
|
||||
}
|
||||
if (this.on) {
|
||||
/*var e = document.createElement('span');
|
||||
e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484');
|
||||
e.innerHTML = buf;
|
||||
this.debug.appendChild(e);
|
||||
this.debug.appendChild(document.createElement('br'));
|
||||
this.debug.scrollTop = this.debug.scrollHeight;*/
|
||||
|
||||
console.log(str);
|
||||
/*console.info(str);
|
||||
console.warn(str);
|
||||
console.error(str);
|
||||
console.assert(str);*/
|
||||
}
|
||||
};
|
||||
|
||||
this.info = function () {
|
||||
if (this.on) {
|
||||
|
|
@ -426,56 +423,56 @@ function Debug() {
|
|||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
function Uint64(hi, lo) {
|
||||
/*function Uint64(hi, lo) {
|
||||
this.hi = hi;
|
||||
this.lo = lo;
|
||||
|
||||
this.or = function(v) {
|
||||
this.hi = (this.hi | v.hi) >>> 0;
|
||||
this.lo = (this.lo | v.lo) >>> 0;
|
||||
}
|
||||
this.or = function (v) {
|
||||
this.hi = (this.hi | v.hi) >>> 0;
|
||||
this.lo = (this.lo | v.lo) >>> 0;
|
||||
};
|
||||
|
||||
this.lshift = function(n) {
|
||||
if (n) {
|
||||
if (n < 32) {
|
||||
var m = Math.pow(2, n) - 1;
|
||||
var t = this.lo & m;
|
||||
this.hi = ((this.hi << n) | t) >>> 0;
|
||||
this.lo = (this.lo << n) >>> 0;
|
||||
this.lshift = function (n) {
|
||||
if (n) {
|
||||
if (n < 32) {
|
||||
var m = Math.pow(2, n) - 1;
|
||||
var t = this.lo & m;
|
||||
this.hi = ((this.hi << n) | t) >>> 0;
|
||||
this.lo = (this.lo << n) >>> 0;
|
||||
|
||||
//BUG.info('lshift %d %x', n, m, t);
|
||||
} else {
|
||||
var t = this.lo;
|
||||
this.hi = (t << (n-32)) >>> 0;
|
||||
this.lo = 0;
|
||||
//BUG.info('lshift %d %x', n, m, t);
|
||||
} else {
|
||||
var t = this.lo;
|
||||
this.hi = (t << (n - 32)) >>> 0;
|
||||
this.lo = 0;
|
||||
|
||||
//BUG.info('lshift %d %x', n, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
//BUG.info('lshift %d %x', n, t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.rshift = function(n) {
|
||||
if (n) {
|
||||
if (n < 32) {
|
||||
var m = Math.pow(2, n) - 1;
|
||||
var t = this.hi & m;
|
||||
this.hi = (this.hi >>> n) >>> 0;
|
||||
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
|
||||
this.rshift = function (n) {
|
||||
if (n) {
|
||||
if (n < 32) {
|
||||
var m = Math.pow(2, n) - 1;
|
||||
var t = this.hi & m;
|
||||
this.hi = (this.hi >>> n) >>> 0;
|
||||
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
|
||||
|
||||
//BUG.info('rshift %d %x %x', n, m, t);
|
||||
} else {
|
||||
var t = this.hi;
|
||||
this.hi = 0;
|
||||
this.lo = (t >>> (n-32)) >>> 0;
|
||||
//BUG.info('rshift %d %x %x', n, m, t);
|
||||
} else {
|
||||
var t = this.hi;
|
||||
this.hi = 0;
|
||||
this.lo = (t >>> (n - 32)) >>> 0;
|
||||
|
||||
//BUG.info('rshift %d %x %x', n, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
//BUG.info('rshift %d %x %x', n, t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.print = function() {
|
||||
BUG.info('$%08x%08x', this.hi, this.lo);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
|
|
|||
177
sae/video.js
177
sae/video.js
|
|
@ -60,7 +60,6 @@ function Vide0() {
|
|||
this.available |= SAEI_Video_Canvas2D;
|
||||
test2 = null;
|
||||
}
|
||||
test = null;
|
||||
}
|
||||
test = document.createElement('canvas');
|
||||
if (test && test.getContext) {
|
||||
|
|
@ -143,92 +142,104 @@ function Vide0() {
|
|||
ctx.colorMask(true, true, true, false);
|
||||
}
|
||||
|
||||
this.setup = function() {
|
||||
if (!AMIGA.config.video.enabled) return;
|
||||
if (open) this.cleanup();
|
||||
this.setup = function () {
|
||||
if (!AMIGA.config.video.enabled) return;
|
||||
if (open) this.cleanup();
|
||||
|
||||
div = document.getElementById(AMIGA.config.video.id);
|
||||
if (!div)
|
||||
Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: '+AMIGA.config.video.id+')');
|
||||
div = document.getElementById(AMIGA.config.video.id);
|
||||
if (!div)
|
||||
Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: ' + AMIGA.config.video.id + ')');
|
||||
|
||||
scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false;
|
||||
width = VIDEO_WIDTH << (scale ? 1 : 0);
|
||||
height = VIDEO_HEIGHT << (scale ? 1 : 0);
|
||||
size = width * height;
|
||||
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
|
||||
scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false;
|
||||
width = VIDEO_WIDTH << (scale ? 1 : 0);
|
||||
height = VIDEO_HEIGHT << (scale ? 1 : 0);
|
||||
size = width * height;
|
||||
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
|
||||
|
||||
if (this.available & SAEI_Video_Canvas2D) {
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.oncontextmenu = function() { return false; }
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); }
|
||||
canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); }
|
||||
canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); }
|
||||
canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); }
|
||||
canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); }
|
||||
}
|
||||
if (this.available & SAEI_Video_WebGL) {
|
||||
ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams);
|
||||
initGL();
|
||||
pixels = new Uint16Array(size);
|
||||
for (var i = 0; i < size; i++) pixels[i] = 0;
|
||||
|
||||
this.drawpixel = drawpixel_gl;
|
||||
this.drawline = drawline_gl;
|
||||
this.render = render_gl;
|
||||
this.show = show_gl;
|
||||
} else {
|
||||
ctx = canvas.getContext('2d');
|
||||
imagedata = ctx.createImageData(width, height);
|
||||
pixels = imagedata.data;
|
||||
|
||||
this.drawpixel = drawpixel_2d;
|
||||
this.drawline = drawline_2d;
|
||||
this.render = render_2d;
|
||||
this.show = show_2d;
|
||||
}
|
||||
} else {
|
||||
if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?'))
|
||||
Fatal(SAEE_Video_Canvas_Not_Supported, null);
|
||||
else
|
||||
AMIGA.config.video.enabled = false;
|
||||
}
|
||||
|
||||
video = document.createElement('div');
|
||||
video.style.width = width + 'px';
|
||||
video.style.height = height + 'px';
|
||||
video.style.margin = 'auto';
|
||||
video.style.webkitTouchCallout = 'none';
|
||||
video.style.webkitUserSelect = 'none';
|
||||
video.style.khtmlUserSelect = 'none';
|
||||
video.style.mozUserSelect = 'none';
|
||||
video.style.msUserSelect = 'none';
|
||||
video.style.userSelect = 'none';
|
||||
if (AMIGA.config.video.enabled)
|
||||
video.appendChild(canvas);
|
||||
if (this.available & SAEI_Video_Canvas2D) {
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.oncontextmenu = function () {
|
||||
return false;
|
||||
};
|
||||
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
|
||||
canvas.onmousedown = function (e) {
|
||||
AMIGA.input.mouse.mousedown(e);
|
||||
};
|
||||
canvas.onmouseup = function (e) {
|
||||
AMIGA.input.mouse.mouseup(e);
|
||||
};
|
||||
canvas.onmouseover = function (e) {
|
||||
AMIGA.input.mouse.mouseover(e);
|
||||
};
|
||||
canvas.onmouseout = function (e) {
|
||||
AMIGA.input.mouse.mouseout(e);
|
||||
};
|
||||
canvas.onmousemove = function (e) {
|
||||
AMIGA.input.mouse.mousemove(e);
|
||||
}
|
||||
}
|
||||
if (this.available & SAEI_Video_WebGL) {
|
||||
ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams);
|
||||
initGL();
|
||||
pixels = new Uint16Array(size);
|
||||
for (var i = 0; i < size; i++) pixels[i] = 0;
|
||||
|
||||
div.appendChild(video);
|
||||
open = true;
|
||||
}
|
||||
//this.drawpixel = drawpixel_gl;
|
||||
this.drawline = drawline_gl;
|
||||
this.render = render_gl;
|
||||
this.show = show_gl;
|
||||
} else {
|
||||
ctx = canvas.getContext('2d');
|
||||
imagedata = ctx.createImageData(width, height);
|
||||
pixels = imagedata.data;
|
||||
|
||||
this.cleanup = function() {
|
||||
if (open) {
|
||||
div.removeChild(video);
|
||||
canvas = null;
|
||||
imagedata = null;
|
||||
pixels = null;
|
||||
video = null;
|
||||
open = false;
|
||||
}
|
||||
}
|
||||
//this.drawpixel = drawpixel_2d;
|
||||
this.drawline = drawline_2d;
|
||||
this.render = render_2d;
|
||||
this.show = show_2d;
|
||||
}
|
||||
} else {
|
||||
if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?'))
|
||||
Fatal(SAEE_Video_Canvas_Not_Supported, null);
|
||||
else
|
||||
AMIGA.config.video.enabled = false;
|
||||
}
|
||||
|
||||
video = document.createElement('div');
|
||||
video.style.width = width + 'px';
|
||||
video.style.height = height + 'px';
|
||||
video.style.margin = 'auto';
|
||||
video.style.webkitTouchCallout = 'none';
|
||||
video.style.webkitUserSelect = 'none';
|
||||
video.style.khtmlUserSelect = 'none';
|
||||
video.style.mozUserSelect = 'none';
|
||||
video.style.msUserSelect = 'none';
|
||||
video.style.userSelect = 'none';
|
||||
if (AMIGA.config.video.enabled)
|
||||
video.appendChild(canvas);
|
||||
|
||||
div.appendChild(video);
|
||||
open = true;
|
||||
};
|
||||
|
||||
this.cleanup = function () {
|
||||
if (open) {
|
||||
div.removeChild(video);
|
||||
canvas = null;
|
||||
imagedata = null;
|
||||
pixels = null;
|
||||
video = null;
|
||||
open = false;
|
||||
}
|
||||
};
|
||||
|
||||
/*---------------------------------*/
|
||||
|
||||
this.hideCursor = function(hide) {
|
||||
canvas.style.cursor = hide ? 'none' : 'auto';
|
||||
}
|
||||
/*this.hideCursor = function (hide) {
|
||||
canvas.style.cursor = hide ? 'none' : 'auto';
|
||||
};*/
|
||||
|
||||
/*this.clear_pixels = function () {
|
||||
for (var i = 0; i < size; i++)
|
||||
|
|
@ -238,9 +249,9 @@ function Vide0() {
|
|||
/*---------------------------------*/
|
||||
/* Canvas 2D */
|
||||
|
||||
function drawpixel_2d(x, y, rgb) {
|
||||
/*function drawpixel_2d(x, y, rgb) {
|
||||
pixels[y * width + x] = rgb;
|
||||
}
|
||||
}*/
|
||||
|
||||
function drawline_2d(y, data, offs) {
|
||||
var yoffs = (y * width) << 2;
|
||||
|
|
@ -261,9 +272,9 @@ function Vide0() {
|
|||
/*---------------------------------*/
|
||||
/* WebGL */
|
||||
|
||||
function drawpixel_gl(x, y, rgb) {
|
||||
/*function drawpixel_gl(x, y, rgb) {
|
||||
pixels[y * width + x] = rgb;
|
||||
}
|
||||
}*/
|
||||
|
||||
function drawline_gl(y, data, offs) {
|
||||
var yoffs = y * width;
|
||||
|
|
|
|||
Loading…
Reference in a new issue