@@ -32,20 +34,20 @@
A very fast computer
A browser capable of HTML5 with:
- - WegGL
- - WebAudio
+ - WegGL or Canvas 2D (optional)
+ - WebAudio (optional)
+ - FileReader (GUI)
- Typed arrays
- - FileReader (GUI)
A ROM:
- - Amiga Kickstart 1.x-2.04 (not included for copyright reasons)
- - AROS Kickstart (included)
+ - Amiga Kickstart 1.0-2.05 (not included for copyright reasons)
+ - AROS Kickstart (included)
- And a bunch of ADF-files to test (optional)
+ And a bunch of ADF-files to test (optional)
@@ -53,8 +55,8 @@
| Supported browsers |
- | Chrome | Fastest |
- | Firefox | Medium speed |
+ | Chrome | Very fast |
+ | Firefox | Medium speed |
| Opera | Slow speed, no audio |
| IE | No support |
| Other | Untested |
@@ -86,30 +88,17 @@
Usage/Hints
- Press F11 for fullscreen. Most browsers support that.
- - If something does crash, try another memory setting or a different ROM. The original kickstart (1.3) work's best.
+ - If something does crash, try another memory setting or a different ROM.
+ The original kickstart (1.3) does work best.
- Known bugs/problems
- - There may be graphics-errors:
-
- - Graphics may be at a wrong position or a wrong color.
- - Fast blinking sprites are not displayed if 'Frameskip' is active.
- - Copper initiated color-changes within a scanline are not recognized.
- - The next update (0.8) will deal with this.
-
-
- - Left/right shift/alt/ctrl are the same. That's a browser 'feature' and can't be fixed.
-
-
-
-
- - Missing features
-
- - User-config
- - Maybe ECS support
+ - Blinking sprites are not shown if "Frameskip" is active.
+ - There may be short and heavy speed-fluctuations in the beginning of the emulation.
+ - Left/right shift/alt/ctrl are the same. That's a browser "feature" and can't be fixed.
@@ -121,7 +110,7 @@
- - Source code
+
- Source-code
@@ -130,24 +119,25 @@
- License
- - This is a free project.
+ - This is a free project.
- You may use the emulator in your own website.
- - If you use the emulator in your own website, you must provide a link to this homepage.
- - If you use the emulator in your own website, you must not change the copyright header in the source-files.
- - Commercial use in any form is prohibited. This includes donations.
+ - If you use the emulator in your own website, you must provide a link to this homepage.
+ - If you use the emulator in your own website, you must not change the copyright header in the source-files.
+ - Commercial use in any form is prohibited. This includes donations.
- No warranty expressed or implied. Use at your own risk.
-
+
- History
+ - 0.8.0 (16.01.2013):
+
+ - Display
+
+ - Ported and optimized playfield-code from WinUAE.
+ This adds ECS and AGA support and fixes graphics-errors.
+ The AGA part is commented out, because there is no 68020 yet.
+ - Added support for drawing via 'Canvas 2D' if 'WebGL' is not avail.
+ - Added support for auto-driver detection.
+
+
+ - Audio
+
+ - While disk access, audio performance is much better now.
+ - Added support for the A500 lowpass-filter. Not enabled by default.
+ - Added support for auto-driver detection.
+
+
+ - Memory
+
+ - To gain speed, all memory is now accessed directly and not via functions.
+ So, don't care for a possible illegal memory access.
+ - Fixed bug, where kickstart 1.2 failed to load.
+ - Fixed incorrect extended-address bug.
+
+
+ - CPU
+
+ - Splitted address-types of ADDQ/SUBQ into separate functions for more speed.
+ - Added bus-read/write cycles tables. For internal use only.
+
+
+ - CIA
+
+ - I decided to port the latest cia-code from WinUAE while i was trying to find a bug.
+ Well, the bug is still there. Let's keep the code nevertheless.
+
+
+ - GUI
+
+ - Added info box of supported drivers.
+ - Added a 'Chipset'-section and various options.
+ - Packed the main GUI.
+
+
+ - Common
+
+ - Added support for easy URL sharing. E.g. to show the Multica-demo to a friend,
+ one may send the link "http://scriptedamigaemulator.net/#Multica"
+ and the demo will start immediately. (thanks mrdoob)
+ - Many small optimizations.
+
+
+
+
+
- 0.7.0 (24.12.2012):
- Common
@@ -246,7 +291,8 @@
- Audio
- Added a ring-buffer before output. No more "bagpipe"-like audio.
- - Added a option to just emulate the hardware, but not to play any sound, e.g. "Agony" was not starting, if audio was disabled.
+ - Added a option to just emulate the hardware, but not to play any sound,
+ e.g. "Agony" was not starting, if audio was disabled.
- Display
diff --git a/sae/amiga.js b/sae/amiga.js
index 84b8fc7..41ac979 100644
--- a/sae/amiga.js
+++ b/sae/amiga.js
@@ -12,6 +12,14 @@ function set_special(x) { AMIGA.spcflags |= x; }
function clr_special(x) { AMIGA.spcflags &= ~x; }
function Amiga() {
+ this.info = {
+ version: SAEV_Version+'.'+SAEV_Revision+'.'+SAEV_Revision_Sub,
+ browser_name: BrowserDetect.browser,
+ browser_version: BrowserDetect.version,
+ os: BrowserDetect.OS,
+ video:0,
+ audio:0
+ };
this.config = new Config();
this.mem = new Memory();
this.expansion = new Expansion();
@@ -29,35 +37,31 @@ function Amiga() {
this.audio = new Audi0();
this.cpu = new CPU();
- this.state = CMD_STOP;
+ this.state = ST_STOP;
this.delay = 0;
this.spcflags = 0;
//this.loading = 0;
this.intena = 0;
- this.intena_internal = 0;
this.intreq = 0;
- this.intreq_internal = 0;
this.dmacon = 0;
this.adkcon = 0;
- configSetDefaults(this.config);
+ this.info.video = this.video.available;
+ this.info.audio = this.audio.available;
/*---------------------------------*/
this.setup = function() {
- if (this.config.chipset.type == SAEV_Config_Chipset_Type_OCS)
- this.config.chipset.agnus = this.config.video.ntsc ? AGNUS_8370 : AGNUS_8371;
-
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.playfield.setup();
- this.video.setup();
this.audio.setup();
this.custom.setup();
this.cpu.setup();
@@ -72,26 +76,25 @@ function Amiga() {
this.reset = function() {
BUG.info('Amiga.reset()');
-
+
this.delay = 0;
+ this.spcflags = 0;
//this.loading = 0;
-
+
this.intena = 0;
- this.intena_internal = 0;
this.intreq = 0;
- this.intreq_internal = 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.playfield.reset();
this.audio.reset();
this.custom.reset();
this.cpu.reset(this.mem.rom.lower);
@@ -109,7 +112,7 @@ function Amiga() {
setTimeout('AMIGA.waitForStart()', 10);
else {
this.reset();
- this.state = CMD_CYCLE;
+ this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0);
}
}
@@ -120,24 +123,24 @@ function Amiga() {
this.start = function() {
- if (this.state == CMD_STOP) {
+ if (this.state == ST_STOP) {
this.setup();
this.reset();
- this.state = CMD_CYCLE;
+ this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0);
}
}
this.stop = function() {
- if (this.state != CMD_STOP) {
- this.state = CMD_STOP;
+ if (this.state != ST_STOP) {
+ this.state = ST_STOP;
this.cleanup();
}
}
this.pause = function(state) {
- if (this.state != CMD_STOP) {
- this.state = state ? CMD_PAUSE : CMD_CYCLE;
+ if (this.state != ST_STOP) {
+ this.state = state ? ST_PAUSE : ST_CYCLE;
this.audio.pauseResume(state);
}
}
@@ -159,97 +162,100 @@ function Amiga() {
*/
this.insert = function(unit) {
- if (this.state != CMD_STOP)
+ if (this.state != ST_STOP)
this.disk.insert(unit);
}
this.eject = function(unit) {
- if (this.state != CMD_STOP)
+ if (this.state != ST_STOP)
this.disk.eject(unit);
}
/*---------------------------------*/
- /* mainloop */
+ /* mainloop */
this.cycle = function() {
try {
- while (this.state == CMD_CYCLE)
- this.cpu.cycle();
+ 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
+ } else /* normal exception */ {
+ this.state = ST_STOP;
+ this.stop();
console.log(e);
+ }
}
-
- if (this.state == CMD_IDLE) {
- this.state = CMD_CYCLE;
+ if (this.state == ST_IDLE) {
+ this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', this.delay);
}
- else if (this.state == CMD_PAUSE)
- setTimeout('AMIGA.cyclePause()', 0);
+ else if (this.state == ST_PAUSE)
+ AMIGA.cyclePause();
else
- setTimeout('AMIGA.cycleExit()', 0);
+ AMIGA.cycleExit();
}
this.cyclePause = function() {
- if (this.state == CMD_CYCLE)
+ if (this.state == ST_CYCLE)
setTimeout('AMIGA.cycle()', 0);
- else if (this.state == CMD_PAUSE)
+ else if (this.state == ST_PAUSE)
setTimeout('AMIGA.cyclePause()', 500);
else
- setTimeout('AMIGA.cycleExit()', 0);
+ AMIGA.cycleExit();
}
this.cycleExit = function() {
this.dump();
+ //this.cia.dump();
}
/*---------------------------------*/
this.dmaen = function (dmamask) {
- return ((this.dmacon & DMAF_DMAEN) && (this.dmacon & dmamask));
+ 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);
- //this.dmacon |= (this.blitter.state == BLT_STOP ? 0 : 0x4000) | (this.blitter.zero ? 0x2000 : 0); //old
- //this.dmacon |= ((blit_interrupt || (!blit_interrupt && currprefs.cs_agnusbltbusybug && !blt_info.got_cycle)) ? 0 : 0x4000) | (blt_info.blitzero ? 0x2000 : 0); //new org
var iz = this.blitter.getIntZero();
- this.dmacon |= (iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0);
+ 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);
+
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) && (oldcon & DMAF_DMAEN);
- var newcop = (this.dmacon & DMAF_COPEN) && (this.dmacon & DMAF_DMAEN);
+ 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);
+ clr_special(SPCFLAG_COPPER);
}
}
- //if ((this.dmacon & DMAF_COPEN) > (oldcon & DMAF_COPEN))
- //this.copper.COPJMP(1, 0);
-
- if ((this.dmacon & DMAF_SPREN) > (oldcon & DMAF_SPREN)) {
- for (var i = 0; i < 8; i++)
- this.playfield.sprites.sprite[i].dmastate = 1;
- }
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)
@@ -260,12 +266,12 @@ function Amiga() {
if (changed & (DMAF_DMAEN | 0x0f))
this.audio.state_machine();
- /*if (this.copper.active && !this.events.eventtab[EV_COPPER].active) {
- this.events.eventtab[EV_COPPER].active = true;
- this.events.eventtab[EV_COPPER].oldcycles = this.events.currcycle;
- this.events.eventtab[EV_COPPER].evtime = 1 * CYCLE_UNIT + this.events.currcycle;
- this.events.schedule();
- }*/
+ 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();
}
/*---------------------------------*/
@@ -296,27 +302,13 @@ function Amiga() {
}
this.INTENA = function(v) {
- var old = this.intena;
-
if (v & INTF_SETCLR)
this.intena |= v & ~INTF_SETCLR;
else
this.intena &= ~v;
- if (!(v & INTF_SETCLR) && old == this.intena)
- return;
-
- if (AMIGA.config.cpu.exact) {
- this.events.event2_newevent_xx(-1, INT_PROCESSING_DELAY, this.intena, function(v) {
- //console.log('INTENA()', v);
- AMIGA.intena_internal = v;
- AMIGA.doint();
- });
- } else {
- this.intena_internal = this.intena;
- if (v & INTF_SETCLR)
- this.doint();
- }
+ if (v & INTF_SETCLR)
+ this.doint();
}
/*---------------------------------*/
@@ -333,64 +325,36 @@ function Amiga() {
else
this.intreq &= ~v;
- if (AMIGA.config.cpu.exact) {
- if (old == this.intreq && this.intreq_internal == this.intreq)
- return;
-
- this.events.event2_newevent_xx(-1, INT_PROCESSING_DELAY, this.intreq, function(v) {
- //console.log('INTREQ_0()', v);
- AMIGA.intreq_internal = v;
- AMIGA.doint();
- });
- } else {
- this.intreq_internal = this.intreq;
- if (this.intreq == old)
- return;
- if (v & INTF_SETCLR)
- this.doint();
- }
+ if ((v & INTF_SETCLR) && this.intreq != old)
+ this.doint();
}
this.INTREQ = function(v) {
this.INTREQ_0(v);
- this.cia.reThink();
+ this.cia.rethink();
}
-
+
+ /*---------------------------------*/
+
this.intlev = function() {
- var imask = this.intreq_internal & this.intena_internal;
-
- if (imask && (this.intena_internal & INTF_INTEN)) {
+ var imask = this.intreq & this.intena;
+
+ if (imask && (this.intena & INTF_INTEN)) {
if (imask & 0x2000) return 6;
- if (imask & (0x1000 | 0x0800)) return 5;
- if (imask & (0x0400 | 0x0200 | 0x0100 | 0x0080)) return 4;
- if (imask & (0x0040 | 0x0020 | 0x0010)) return 3;
+ if (imask & 0x1800) return 5;
+ if (imask & 0x0780) return 4;
+ if (imask & 0x0070) return 3;
if (imask & 0x0008) return 2;
- if (imask & (0x0001 | 0x0002 | 0x0004)) return 1;
+ if (imask & 0x0007) return 1;
}
return -1;
}
this.doint = function() {
- if (AMIGA.config.cpu.exact) {
- this.cpu.setIPL(this.intlev());
- clr_special(SPCFLAG_INT);
- return;
- }
if (AMIGA.config.cpu.compatible)
set_special(SPCFLAG_INT);
else
- set_special(SPCFLAG_DOINT);
- }
-
- this.send_interrupt = function(num, delay) {
- if (AMIGA.config.cpu.exact && delay > 0) {
- if (!(this.intreq & (1 << num))) {
- this.events.event2_newevent_xx(-1, delay, num, function(v) {
- AMIGA.INTREQ_0(INTF_SETCLR | (1 << v));
- });
- }
- } else
- this.INTREQ_0(INTF_SETCLR | (1 << num));
+ set_special(SPCFLAG_DOINT);
}
}
@@ -405,7 +369,8 @@ function SAE(x) {
BUG.info('API.init() SEA %d.%d.%d', SAEV_Version, SAEV_Revision, SAEV_Revision_Sub);
AMIGA = new Amiga();
- return AMIGA.config;
+ //return AMIGA.config;
+ break;
case 'reset':
BUG.info('API.reset()');
AMIGA.reset();
@@ -438,10 +403,13 @@ function SAE(x) {
BUG.info('API.eject() DF%d', x.unit);
AMIGA.eject(x.unit);
break;
- /*case 'getConfig':
+ case 'getInfo':
+ BUG.info('API.getInfo()');
+ return AMIGA.info;
+ case 'getConfig':
BUG.info('API.getConfig()');
return AMIGA.config;
- case 'setConfig':
+ /*case 'setConfig':
BUG.info('API.setConfig() size '+x.data.ext.size);
AMIGA.config = x.data;
break;*/
diff --git a/sae/audio.js b/sae/audio.js
index b5945ef..a1e98f0 100644
--- a/sae/audio.js
+++ b/sae/audio.js
@@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes: Ported from WinUAE 2.5.0
+*
**************************************************************************/
/*const DEBUG_CHANNEL_MASK = 15
@@ -70,9 +73,7 @@ function Filter() {
}
this.filter = function(input, state) {
- if (!this.on)
- return input;
-
+ //if (!this.on) return input;
var o, fs = filter_state[state];
fs.rc1 = filter1_a0 * input + (1 - filter1_a0) * fs.rc1 + DENORMAL_OFFSET;
@@ -83,12 +84,11 @@ function Filter() {
fs.rc3 = filter_a0 * no + (1 - filter_a0) * fs.rc3;
fs.rc4 = filter_a0 * fs.rc3 + (1 - filter_a0) * fs.rc4;
fs.rc5 = filter_a0 * fs.rc4 + (1 - filter_a0) * fs.rc5;
- o = fs.rc5;
+ o = Math.floor(fs.rc5);
} else
- o = no;
+ o = Math.floor(no);
- if (o > 32767) o = 32767; else if (o < -32768) o = -32768;
- return o;
+ return o > 32767 ? 32767 : (o < -32768 ? -32768 : o);
}
}
@@ -367,6 +367,9 @@ function Channel(num) {
}
function Audi0() {
+ const SAMPLE_BUFFER_SIZE = 8192 >> 0;
+ this.available = 0;
+
var channel = null;
var last_cycles = 0;
@@ -410,6 +413,35 @@ function Audi0() {
/*---------------------------------*/
+ //this.init = function()
+ {
+ var test;
+
+ /*try {
+ test = new AudioContext();
+ test = null;
+ this.available |= SAEI_Audio_Default;
+ } catch (e) {}*/
+
+ try {
+ test = new webkitAudioContext();
+ if (test && test.createJavaScriptNode)
+ this.available |= SAEI_Audio_Webkit;
+ test = null;
+ } catch (e) {}
+
+ try {
+ test = new Audio();
+ if (test && test.mozSetup)
+ this.available |= SAEI_Audio_Mozilla;
+ test = null;
+ } catch (e) {}
+
+ //console.log(this.available);
+ }
+
+ /*---------------------------------*/
+
function getRate(v) {
switch (v) {
case SAEV_Config_Audio_Rate_11025: return 11025;
@@ -420,30 +452,29 @@ function Audi0() {
}
}
- this.recalc_sample_evtime = function() {
- var hpos, lines = 0;
+ this.calc_sample_evtime = function(freq, longframe, linetoggle) {
+ var lines = 0.0;
+ var hpos;
- if (AMIGA.config.video.ntsc) {
- hpos = 227.5;
+ if (linetoggle) {
+ hpos = AMIGA.playfield.maxhpos_short + 0.5;
lines += 0.5;
} else {
- var longframe = (AMIGA.playfield.bplcon0 & 4) ? -1 : AMIGA.events.lofStore;
- hpos = 227;
+ hpos = AMIGA.playfield.maxhpos_short + 0.0;
if (longframe < 0)
lines += 0.5;
else if (longframe > 0)
lines += 1.0;
}
- lines += AMIGA.events.maxvpos;
-
- scaled_sample_evtime_orig = Math.floor(hpos * lines * AMIGA.events.hz * CYCLE_UNIT / getRate(AMIGA.config.audio.rate));
+ lines += AMIGA.playfield.maxvpos_nom;
+ scaled_sample_evtime_orig = Math.floor(hpos * lines * freq * CYCLE_UNIT / getRate(AMIGA.config.audio.rate));
scaled_sample_evtime = scaled_sample_evtime_orig;
- //sampler_evtime = hpos * lines * AMIGA.events.hz * CYCLE_UNIT;
-
- //scaled_sample_evtime = Math.floor((AMIGA.events.maxhpos * AMIGA.events.maxvpos * AMIGA.events.hz + getRate(AMIGA.config.audio.rate) - 1) / getRate(AMIGA.config.audio.rate)) * CYCLE_UNIT;
-
- console.log('Audio.recalc_sample_evtime() scaled_sample_evtime %f (%f) | hpos %d, lines %d', scaled_sample_evtime, scaled_sample_evtime * CYCLE_UNIT_INV, hpos, lines);
- }
+/*#if 0
+ lines -= AMIGA.playfield.maxvpos_nom;
+ BUG.info('%d.%d %d.%d %.2f', maxhpos_short, linetoggle ? 5 : 0, maxvpos_nom + (lines == 1.0 ? 1 : 0), lines > 0 && lines < 1 ? 5 : 0, scaled_sample_evtime);
+#endif*/
+ BUG.info('Audio.calc_sample_evtime() scaled_sample_evtime %f (%f) | hpos %d, lines %d', scaled_sample_evtime, scaled_sample_evtime * CYCLE_UNIT_INV, hpos, lines);
+ }
this.setup = function() {
if (channel === null) {
@@ -455,53 +486,32 @@ function Audi0() {
return;
if (driver.ctx === null) {
- if (BrowserDetect.browser == 'Firefox') {
- try {
- driver.ctx = new Audio();
- BUG.info('Audio.setup() using "Audio()"');
- } catch (e) {}
- } else {
- try {
- driver.ctx = new AudioContext();
- BUG.info('Audio.setup() using "AudioContext()"');
- } catch (e) {
- try {
- driver.ctx = new webkitAudioContext();
- BUG.info('Audio.setup() using "webkitAudioContext()"');
- } catch (e) {}
- }
- }
+ if (this.available & SAEI_Audio_Webkit)
+ driver.ctx = new webkitAudioContext();
+ else if (this.available & SAEI_Audio_Mozilla)
+ driver.ctx = new Audio();
}
if (driver.ctx === null) {
if (confirm('Can\'t initialise WebAudio. Continue without audio-playback?')) {
AMIGA.config.audio.mode = SAEV_Config_Audio_Mode_Emul;
return;
} else
- Fatal(SAEE_Audio_WebAudio_Not_Avail, 'Can\'t initialise WebAudio.');
+ Fatal(SAEE_Audio_WebAudio_Not_Avail, null);
}
- this.filter.setup(0);
+ this.filter.setup(AMIGA.config.audio.filter); /* A500 lowpass-filter */
- this.recalc_sample_evtime();
+ var hz = AMIGA.config.video.ntsc ? 60 : 50;
+ this.calc_sample_evtime(hz, 1, AMIGA.config.video.ntsc);
- sampleBuffer.size = 8192 >> 0;
+ sampleBuffer.size = SAMPLE_BUFFER_SIZE;
sampleBuffer.realSize = sampleBuffer.size << 1;
sampleBuffer.data = new Float32Array(sampleBuffer.realSize << (AMIGA.config.audio.channels - 1));
- ringBuffer.size = sampleBuffer.size << 1;
+ ringBuffer.size = sampleBuffer.size + (sampleBuffer.size >> 1);
ringBuffer.data = new Float32Array(ringBuffer.size << (AMIGA.config.audio.channels - 1));
- if (BrowserDetect.browser == 'Firefox') {
- driver.ctx.mozSetup(AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
-
- /*driver.moz.currentWritePosition = 0;
- driver.moz.prebufferSize = getRate(AMIGA.config.audio.rate) >> 1; //prebuffer 500ms
- driver.moz.tail = null;*/
- //driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / (getRate(AMIGA.config.audio.rate) / sampleBuffer.size)));
- driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / AMIGA.events.hz * (sampleBuffer.size / (getRate(AMIGA.config.audio.rate) / AMIGA.events.hz))));
-
- BUG.info('Audio.setup() enabled mozilla audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
- } else {
+ if (this.available & SAEI_Audio_Webkit) {
var inputs = BrowserDetect.browser == 'Safari' ? 1 : 0;
//if (inputs == 1) BUG.info('Audio.setup() Safari fix enabled.');
@@ -510,32 +520,36 @@ function Audi0() {
driver.def.node.connect(driver.ctx.destination);
BUG.info('Audio.setup() enabled webkit audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
}
+ else if (this.available & SAEI_Audio_Mozilla) {
+ driver.ctx.mozSetup(AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
+
+ /*driver.moz.currentWritePosition = 0;
+ driver.moz.prebufferSize = getRate(AMIGA.config.audio.rate) >> 1; //prebuffer 500ms
+ driver.moz.tail = null;*/
+ //driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / (getRate(AMIGA.config.audio.rate) / sampleBuffer.size)));
+ driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / hz * (sampleBuffer.size / (getRate(AMIGA.config.audio.rate) / hz))));
+
+ BUG.info('Audio.setup() enabled mozilla audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
+ }
}
this.cleanup = function() {
if (driver.ctx !== null) {
- if (BrowserDetect.browser == 'Firefox') {
- clearInterval(driver.moz.interval);
- } else {
+ if (this.available & SAEI_Audio_Webkit) {
driver.def.node.disconnect(0);
driver.def.node = null;
}
+ else if (this.available & SAEI_Audio_Mozilla) {
+ clearInterval(driver.moz.interval);
+ }
}
}
this.pauseResume = function(pause) {
if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) return;
-
+
if (driver.ctx !== null) {
- if (BrowserDetect.browser == 'Firefox') {
- if (pause && !driver.paused) {
- clearInterval(driver.moz.interval);
- driver.paused = true;
- } else if (!pause && driver.paused) {
- driver.moz.interval = setInterval(mozHandler, 100);
- driver.paused = false;
- }
- } else {
+ if (this.available & SAEI_Audio_Webkit) {
if (driver.def.node) {
if (pause && !driver.paused) {
driver.def.node.disconnect(0);
@@ -546,20 +560,29 @@ function Audi0() {
}
}
}
+ else if (this.available & SAEI_Audio_Mozilla) {
+ if (pause && !driver.paused) {
+ clearInterval(driver.moz.interval);
+ driver.paused = true;
+ } else if (!pause && driver.paused) {
+ driver.moz.interval = setInterval(mozHandler, 100);
+ driver.paused = false;
+ }
+ }
}
}
this.reset = function() {
for (var i = 0; i < 4; i++)
channel[i].reset();
-
+
last_cycles = AMIGA.events.currcycle;
next_sample_evtime = scaled_sample_evtime;
this.schedule();
AMIGA.events.schedule();
work_to_do = 0;
- prevcon = -1;
+ prevcon = 0;
sampleBuffer.pos = 0;
sampleBuffer.rate.clr();
@@ -592,7 +615,7 @@ function Audi0() {
ret = 1;
this.event_reset();
}
- work_to_do = 4 * AMIGA.events.maxvpos * 50;
+ work_to_do = 4 * AMIGA.playfield.maxvpos_nom * 50;
return ret;
}
@@ -716,16 +739,16 @@ function Audi0() {
}
this.hsync = function() {
- //if (!AMIGA.config.audio.enabled) return; /* done in events.hSyncPre() */
-
if (work_to_do > 0) {
- work_to_do--;
- if (work_to_do == 0)
+ //work_to_do--;
+ if (--work_to_do == 0)
this.deactivate();
}
this.update();
}
+ this.vsync = function() { }
+
/*---------------------------------*/
this.AUDxDAT = function(nr, v) {
@@ -763,7 +786,7 @@ function Audi0() {
if (per < PERIOD_MIN * CYCLE_UNIT)
per = PERIOD_MIN * CYCLE_UNIT;
- if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && !AMIGA.config.cpu.exact && channel[nr].dmaenstore)
+ if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && channel[nr].dmaenstore)
per = PERIOD_MIN_NONCE * CYCLE_UNIT;
if (channel[nr].per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) {
@@ -853,8 +876,10 @@ function Audi0() {
data1 += data2;
data2 = data0 << 1;
data3 = data1 << 1;
- data2 = this.filter.filter(data2, 0);
- data3 = this.filter.filter(data3, 1);
+ if (AMIGA.config.audio.filter) {
+ data2 = this.filter.filter(data2, 0);
+ data3 = this.filter.filter(data3, 1);
+ }
if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@@ -910,8 +935,10 @@ function Audi0() {
data1 += data2;
data2 = data0 << 1;
data3 = data1 << 1;
- data2 = this.filter.filter(data2, 0);
- data3 = this.filter.filter(data3, 1);
+ if (AMIGA.config.audio.filter) {
+ data2 = this.filter.filter(data2, 0);
+ data3 = this.filter.filter(data3, 1);
+ }
if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@@ -921,7 +948,7 @@ function Audi0() {
} else
sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5);
} else
- BUG.info('Audio.sample_handler() audio buffer over-run!');
+ BUG.info('Audio.sample_handler_crux() audio buffer over-run!');
}
this.sample_handler_rh = function() {
@@ -938,23 +965,25 @@ function Audi0() {
var delta, ratio;
delta = channel[0].per;
- ratio = ((channel[0].evtime % delta) << 8) / delta;
+ ratio = Math.floor(((channel[0].evtime % delta) << 8) / delta);
data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
delta = channel[1].per;
- ratio = ((channel[1].evtime % delta) << 8) / delta;
+ ratio = Math.floor(((channel[1].evtime % delta) << 8) / delta);
data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
delta = channel[2].per;
- ratio = ((channel[2].evtime % delta) << 8) / delta;
+ ratio = Math.floor(((channel[2].evtime % delta) << 8) / delta);
data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
delta = channel[3].per;
- ratio = ((channel[3].evtime % delta) << 8) / delta;
+ ratio = Math.floor(((channel[3].evtime % delta) << 8) / delta);
data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
}
data2 = data0 << 1;
data3 = data1 << 1;
- data2 = this.filter.filter(data2, 0);
- data3 = this.filter.filter(data3, 1);
+ if (AMIGA.config.audio.filter) {
+ data2 = this.filter.filter(data2, 0);
+ data3 = this.filter.filter(data3, 1);
+ }
if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@@ -964,13 +993,13 @@ function Audi0() {
} else
sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5);
} else
- BUG.info('Audio.sample_handler() audio buffer over-run!');
+ BUG.info('Audio.sample_handler_rh() audio buffer over-run!');
}
/*---------------------------------*/
//var avg = 0, cnt = 0;
-
+
function fillRingBuffer() {
if (sampleBuffer.pos == 0) return false;
@@ -1042,10 +1071,8 @@ function Audi0() {
ringBuffer.usage = 0;
}
}
-
//console.log(sampleBuffer.pos, ringBuffer.usage, rate);
sampleBuffer.pos = 0;
-
return [playBuffer, rate];
}
diff --git a/sae/blitter.js b/sae/blitter.js
index e34b4a9..0b39b76 100644
--- a/sae/blitter.js
+++ b/sae/blitter.js
@@ -3,27 +3,79 @@
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
-* ©2012 Rupert Hausberger
+* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes: Ported from WinUAE 2.5.0
+*
**************************************************************************/
function Blitter() {
+ const FAST = true;
const BLITTER_MAX_WORDS = 2048;
- /*const BLITTER_STARTUP_CYCLES = 2;
- const BLIT_MODE_IMMEDIATE = -1;
- const BLIT_MODE_APPROXIMATE = 0;
- const BLIT_MODE_COMPATIBLE = 1;
- const BLIT_MODE_EXACT = 2;*/
+ const blit_cycle_diagram = [
+ [2, 0,0, 0,0 ], /* 0 -- */
+ [2, 0,0, 0,4 ], /* 1 -D */
+ [2, 0,3, 0,3 ], /* 2 -C */
+ [3, 0,3,0, 0,3,4 ], /* 3 -CD */
+ [3, 0,2,0, 0,2,0 ], /* 4 -B- */
+ [3, 0,2,0, 0,2,4 ], /* 5 -BD */
+ [3, 0,2,3, 0,2,3 ], /* 6 -BC */
+ [4, 0,2,3,0, 0,2,3,4], /* 7 -BCD */
+ [2, 1,0, 1,0 ], /* 8 A- */
+ [2, 1,0, 1,4 ], /* 9 AD */
+ [2, 1,3, 1,3 ], /* A AC */
+ [3, 1,3,0, 1,3,4 ], /* B ACD */
+ [3, 1,2,0, 1,2,0 ], /* C AB- */
+ [3, 1,2,0, 1,2,4 ], /* D ABD */
+ [3, 1,2,3, 1,2,3 ], /* E ABC */
+ [4, 1,2,3,0, 1,2,3,4] /* F ABCD */
+ ];
+ const blit_cycle_diagram_fill = [
+ [0 ], /* 0 */
+ [3, 0,0,0, 0,4,0 ], /* 1 */
+ [0 ], /* 2 */
+ [0 ], /* 3 */
+ [0 ], /* 4 */
+ [4, 0,2,0,0, 0,2,4,0], /* 5 */
+ [0 ], /* 6 */
+ [0 ], /* 7 */
+ [0 ], /* 8 */
+ [3, 1,0,0, 1,4,0 ], /* 9 */
+ [0 ], /* A */
+ [0 ], /* B */
+ [0 ], /* C */
+ [4, 1,2,0,0, 1,2,4,0], /* D */
+ [0 ], /* E */
+ [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];
var blit_filltable = [];
var blit_masktable = [];
+ var blit_interrupt = true;
+ var blit_ch = 0;
+ var blit_slowdown = 0;
+ var blit_stuck = 0;
+ var blit_cyclecounter = 0;
+ var blit_firstline_cycles = 0;
+ var blit_first_cycle = 0;
+ var blit_last_cycle = 0, blit_dmacount = 0, blit_dmacount2 = 0;
+ var blit_nod = 0;
+ var blit_diag = [];
+ var blit_faulty = 0;
+ var original_ch = 0, original_fill = 0, original_line = 0;
+
+ var bltstate = BLT_done;
var bltcon0 = 0;
var bltcon1 = 0;
var bltapt = 0;
- var bltapt_line = 0;
+ var bltapt_line = null;
var bltbpt = 0;
var bltcpt = 0;
var bltdpt = 0;
@@ -32,10 +84,11 @@ 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 blit_add = 0;
- //var blit_modadda = 0, blit_modaddb = 0, blit_modaddc = 0, blit_modaddd = 0;
- var blit_ch = 0;
-
+
+ var ddat1 = 0, ddat2 = 0;
+ var ddat1use = 0, ddat2use = 0;
+ var last_blitter_hpos = 0;
+
var blt_info = {
blitzero:0,
blitashift:0, blitbshift:0, blitdownashift:0, blitdownbshift:0,
@@ -46,75 +99,6 @@ function Blitter() {
got_cycle:0
};
- var bltstate = BLT_done;
-
- var original_ch = 0, original_fill = 0, original_line = 0;
- var blit_interrupt = true;
- var blitter_cycle_exact = false;
-
- var blit_cyclecounter = 0;
- //var blit_waitcyclecounter = 0;
- //var blit_maxcyclecounter = 0;
- //var blit_totalcyclecounter = 0;
- //var blit_startcycles = 0;
- //var blit_misscyclecounter = 0;
- var blit_slowdown = 0;
- //var last_blitter_hpos = 0;
- var blit_stuck = 0;
-
- var blit_firstline_cycles = 0;
- var blit_first_cycle = 0;
- var blit_last_cycle = 0, blit_dmacount = 0, blit_dmacount2 = 0;
- //var blit_linecycles = 0, blit_extracycles = 0
- var blit_nod = 0;
- var blit_diag = [];
- //var blit_frozen = 0;
- var blit_faulty = 0;
- var blit_final = 0;
- //var blt_delayed_irq = 0;
- var ddat1 = 0, ddat2 = 0;
- var ddat1use = 0, ddat2use = 0;
-
- const blit_cycle_diagram = [
- [ 2, 0,0, 0,0 ], /* 0 -- */
- [ 2, 0,0, 0,4 ], /* 1 -D */
- [ 2, 0,3, 0,3 ], /* 2 -C */
- [ 3, 0,3,0, 0,3,4 ], /* 3 -CD */
- [ 3, 0,2,0, 0,2,0 ], /* 4 -B- */
- [ 3, 0,2,0, 0,2,4 ], /* 5 -BD */
- [ 3, 0,2,3, 0,2,3 ], /* 6 -BC */
- [ 4, 0,2,3,0, 0,2,3,4 ], /* 7 -BCD */
- [ 2, 1,0, 1,0 ], /* 8 A- */
- [ 2, 1,0, 1,4 ], /* 9 AD */
- [ 2, 1,3, 1,3 ], /* A AC */
- [ 3, 1,3,0, 1,3,4, ], /* B ACD */
- [ 3, 1,2,0, 1,2,0 ], /* C AB- */
- [ 3, 1,2,0, 1,2,4 ], /* D ABD */
- [ 3, 1,2,3, 1,2,3 ], /* E ABC */
- [ 4, 1,2,3,0, 1,2,3,4 ] /* F ABCD */
- ];
- const blit_cycle_diagram_fill = [
- [ 0 ], /* 0 */
- [ 3, 0,0,0, 0,4,0 ], /* 1 */
- [ 0 ], /* 2 */
- [ 0 ], /* 3 */
- [ 0 ], /* 4 */
- [ 4, 0,2,0,0, 0,2,4,0 ], /* 5 */
- [ 0 ], /* 6 */
- [ 0 ], /* 7 */
- [ 0 ], /* 8 */
- [ 3, 1,0,0, 1,4,0 ], /* 9 */
- [ 0 ], /* A */
- [ 0 ], /* B */
- [ 0 ], /* C */
- [ 4, 1,2,0,0, 1,2,4,0 ], /* D */
- [ 0 ], /* E */
- [ 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];
-
//function build_blitfilltable()
{
var blit_masktable = new Uint16Array(BLITTER_MAX_WORDS);
@@ -165,12 +149,9 @@ function Blitter() {
function get_ch() {
if (blit_faulty) {
- console.log('get_ch() blit_faulty');
- //FIXME
+ console.log('get_ch() blit_faulty');
return blit_cycle_diagram[0]; //&blit_diag[0];
}
- if (blit_final)
- return blitline ? blit_cycle_diagram_finalld : blit_cycle_diagram_finald;
return blit_diag;
}
@@ -186,7 +167,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();
@@ -195,58 +176,45 @@ function Blitter() {
cycles -= diag[0];
cycles %= diag[0];
return cycles;
- }*/
+ }
- /*function canblit(hpos) {
- if (is_bitplane_dma (hpos))
- return 0;
- if (cycle_line[hpos] & CYCLE_MASK) return 0;
- return 1;
- }*/
-
- function blitter_interrupt(hpos, done) {
+ function blitter_interrupt() {
if (blit_interrupt)
return;
- if (!done && (!AMIGA.config.blitter.exact || AMIGA.config.cpu.model >= 68020))
- return;
blit_interrupt = true;
- AMIGA.send_interrupt(6, 3 * CYCLE_UNIT);
- //if (debug_dma) record_dma_event (DMA_EVENT_BLITIRQ, hpos, vpos);
+ AMIGA.INTREQ_0(INT_BLIT);
}
function blitter_done(hpos) {
ddat1use = ddat2use = 0;
- //bltstate = blit_startcycles == 0 || !AMIGA.config.blitter.exact ? BLT_done : BLT_init;
- bltstate = !AMIGA.config.blitter.exact ? BLT_done : BLT_init;
- blitter_interrupt(hpos, 1);
+ bltstate = BLT_done;
+ blitter_interrupt();
AMIGA.copper.blitter_done_notify(hpos);
- //if (debug_dma) record_dma_event (DMA_EVENT_BLITFINISHED, hpos, vpos);
- AMIGA.events.event2_remevent(EV2_BLITTER);
- clr_special (SPCFLAG_BLTNASTY);
- //BUG.info('blitter_done() cycles %d, missed %d, total %d', blit_totalcyclecounter, blit_misscyclecounter, blit_totalcyclecounter + blit_misscyclecounter);
+ AMIGA.events.remevent(EV2_BLITTER);
+ clr_special(SPCFLAG_BLTNASTY);
}
/*---------------------------------*/
- /* ~1500 lines of auto-generated functions are folling... */
+ /* ~1500 lines of auto-generated functions are follwing... */
/*---------------------------------*/
function blitdofast_0(pta, ptb, ptc, ptd, b) {
var i,j;
var totald = 0;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (0) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
}
if (ptd) ptd += b.bltdmod;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -258,14 +226,14 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (0) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
}
if (ptd) ptd -= b.bltdmod;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -274,18 +242,18 @@ function Blitter() {
var totald = 0;
var preva = 0;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((~srca & srcc)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -295,7 +263,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -309,12 +277,12 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((~srca & srcc)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -324,7 +292,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -334,23 +302,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & ~(srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -362,7 +330,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -377,17 +345,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & ~(srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -399,7 +367,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -408,22 +376,22 @@ function Blitter() {
var totald = 0;
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca & ~srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -433,7 +401,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -448,15 +416,15 @@ function Blitter() {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca & ~srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -466,7 +434,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -476,23 +444,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcb ^ (srca | (srcb ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -504,7 +472,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -519,17 +487,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcb ^ (srca | (srcb ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -541,7 +509,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -550,22 +518,22 @@ function Blitter() {
var totald = 0;
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca ^ srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -575,7 +543,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -590,15 +558,15 @@ function Blitter() {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca ^ srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -608,7 +576,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -618,23 +586,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & (srcb | srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -646,7 +614,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -661,17 +629,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & (srcb | srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -683,7 +651,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -693,23 +661,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -721,7 +689,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -736,17 +704,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -758,7 +726,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -768,23 +736,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & (~srca | srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -796,7 +764,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -811,17 +779,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & (~srca | srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -833,7 +801,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -843,23 +811,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcb & (~srca | srcc))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -871,7 +839,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -886,17 +854,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcb & (~srca | srcc))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -908,7 +876,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -918,23 +886,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & ~srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -946,7 +914,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -961,17 +929,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & ~srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -983,7 +951,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -993,23 +961,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & (srca | srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1021,7 +989,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1036,17 +1004,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc & (srca | srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1058,7 +1026,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1066,14 +1034,14 @@ function Blitter() {
var i,j;
var totald = 0;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srcc) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1082,7 +1050,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1095,8 +1063,8 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srcc) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1105,7 +1073,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1115,23 +1083,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (~(srca ^ (srcc | (srca ^ srcb)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1143,7 +1111,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1158,17 +1126,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (~(srca ^ (srcc | (srca ^ srcb)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1180,7 +1148,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1190,23 +1158,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & (srcb ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1218,7 +1186,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1233,17 +1201,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srca & (srcb ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1255,7 +1223,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1263,18 +1231,18 @@ function Blitter() {
var i,j;
var totald = 0;
var prevb = 0, srcb = b.bltbhold;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srcb) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1283,7 +1251,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1297,11 +1265,11 @@ function Blitter() {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srcb) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1310,7 +1278,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1320,23 +1288,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca ^ (srcc & (srca ^ srcb)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1348,7 +1316,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1363,17 +1331,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca ^ (srcc & (srca ^ srcb)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1385,7 +1353,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1395,23 +1363,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srcb & (srca ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1423,7 +1391,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1438,17 +1406,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc ^ (srcb & (srca ^ srcc)))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1460,7 +1428,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1470,23 +1438,23 @@ function Blitter() {
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc | (srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1498,7 +1466,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1513,17 +1481,17 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srcc | (srca & srcb))) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1535,7 +1503,7 @@ function Blitter() {
}
b.bltbhold = srcb;
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1543,17 +1511,17 @@ function Blitter() {
var i,j;
var totald = 0;
var preva = 0;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srca) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1561,7 +1529,7 @@ function Blitter() {
if (pta) pta += b.bltamod;
if (ptd) ptd += b.bltdmod;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1574,11 +1542,11 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = (srca) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1586,7 +1554,7 @@ function Blitter() {
if (pta) pta -= b.bltamod;
if (ptd) ptd -= b.bltdmod;
}
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1595,18 +1563,18 @@ function Blitter() {
var totald = 0;
var preva = 0;
var srcc = b.bltcdat;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc += 2; }
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc += 2; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca | srcc)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1616,7 +1584,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1630,12 +1598,12 @@ function Blitter() {
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
- if (ptc) { srcc = AMIGA.mem.load16_chip(ptc); ptc -= 2; }
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (ptc) { srcc = AMIGA.mem.chip.data[ptc >>> 1]; ptc -= 2; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca | srcc)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1645,7 +1613,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltcdat = srcc;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1654,22 +1622,22 @@ function Blitter() {
var totald = 0;
var preva = 0;
var prevb = 0, srcb = b.bltbhold;
- var dstd=0;
+ var dstd = 0;
var dstp = 0;
for (j = 0; j < b.vblitsize; j++) {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb += 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb += 2;
srcb = ((((prevb << 16) | bltbdat) >>> 0) >>> b.blitbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta += 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta += 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((preva << 16) | bltadat) >>> 0) >>> b.blitashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca | srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd += 2; }
@@ -1679,7 +1647,7 @@ function Blitter() {
if (ptd) ptd += b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -1694,15 +1662,15 @@ function Blitter() {
for (i = 0; i < b.hblitsize; i++) {
var bltadat, srca;
if (ptb) {
- var bltbdat = blt_info.bltbdat = AMIGA.mem.load16_chip(ptb); ptb -= 2;
+ var bltbdat = blt_info.bltbdat = AMIGA.mem.chip.data[ptb >>> 1]; ptb -= 2;
srcb = ((((bltbdat << 16) | prevb) >>> 0) >>> b.blitdownbshift) & 0xffff;
prevb = bltbdat;
}
- if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(pta); pta -= 2; } else { bltadat = blt_info.bltadat; }
+ if (pta) { bltadat = blt_info.bltadat = AMIGA.mem.chip.data[pta >>> 1]; pta -= 2; } else { bltadat = blt_info.bltadat; }
bltadat &= blit_masktable[i];
srca = ((((bltadat << 16) | preva) >>> 0) >>> b.blitdownashift) & 0xffff;
preva = bltadat;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
dstd = ((srca | srcb)) & 0xffff;
totald |= dstd;
if (ptd) { dstp = ptd; ptd -= 2; }
@@ -1712,7 +1680,7 @@ function Blitter() {
if (ptd) ptd -= b.bltdmod;
}
b.bltbhold = srcb;
- if (dstp) AMIGA.mem.store16_chip(dstp, dstd);
+ if (dstp) AMIGA.mem.chip.data[dstp >>> 1] = dstd;
if (totald != 0) b.blitzero = 0;
}
@@ -2048,6 +2016,7 @@ function Blitter() {
}
function blitter_dofast() {
+ //console.log('blitter_dofast');
var i,j;
var bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0;
var mt = bltcon0 & 0xFF;
@@ -2072,7 +2041,7 @@ function Blitter() {
bltdpt += (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize;
}
- if (blitfunc_dofast[mt] !== 0 && !blitfill)
+ if (FAST && blitfunc_dofast[mt] !== 0 && !blitfill)
blitfunc_dofast[mt](bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, blt_info);
else {
var blitbhold = blt_info.bltbhold;
@@ -2086,7 +2055,8 @@ function Blitter() {
var bltadat, blitahold;
var bltbdat;
if (bltadatptr) {
- blt_info.bltadat = bltadat = AMIGA.mem.load16_chip(bltadatptr);
+ //blt_info.bltadat = bltadat = AMIGA.mem.load16_chip(bltadatptr);
+ blt_info.bltadat = bltadat = AMIGA.mem.chip.data[bltadatptr >>> 1];
bltadatptr += 2;
} else
bltadat = blt_info.bltadat;
@@ -2095,19 +2065,23 @@ function Blitter() {
preva = bltadat;
if (bltbdatptr) {
- blt_info.bltbdat = bltbdat = AMIGA.mem.load16_chip(bltbdatptr);
+ //blt_info.bltbdat = bltbdat = AMIGA.mem.load16_chip(bltbdatptr);
+ blt_info.bltbdat = bltbdat = AMIGA.mem.chip.data[bltbdatptr >>> 1];
bltbdatptr += 2;
blitbhold = (((prevb << 16) | bltbdat) >>> 0) >>> blt_info.blitbshift;
prevb = bltbdat;
}
if (bltcdatptr) {
- blt_info.bltcdat = AMIGA.mem.load16_chip(bltcdatptr);
+ //blt_info.bltcdat = AMIGA.mem.load16_chip(bltcdatptr);
+ blt_info.bltcdat = AMIGA.mem.chip.data[bltcdatptr >>> 1];
bltcdatptr += 2;
}
if (dodst)
- AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
- blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xffff;
+ //AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ AMIGA.mem.chip.data[dstp >>> 1] = blt_info.bltddat;
+
+ blt_info.bltddat = (blit_func(blitahold & 0xffff, blitbhold & 0xffff, blt_info.bltcdat & 0xffff, mt) >>> 0) & 0xffff;
if (blitfill) {
var d = blt_info.bltddat;
var ifemode = blitife ? 2 : 0;
@@ -2129,7 +2103,9 @@ function Blitter() {
if (bltddatptr) bltddatptr += blt_info.bltdmod;
}
if (dodst)
- AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ //AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ AMIGA.mem.chip.data[dstp >>> 1] = blt_info.bltddat;
+
blt_info.bltbhold = blitbhold;
}
blit_masktable[0] = 0xffff;
@@ -2139,6 +2115,7 @@ function Blitter() {
}
function blitter_dofast_desc() {
+ //console.log('blitter_dofast_desc');
var i,j;
var bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0;
var mt = bltcon0 & 0xFF;
@@ -2163,7 +2140,7 @@ function Blitter() {
bltdpt -= (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize;
}
- if (blitfunc_dofast_desc[mt] !== 0 && !blitfill)
+ if (FAST && blitfunc_dofast_desc[mt] !== 0 && !blitfill)
blitfunc_dofast_desc[mt](bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, blt_info);
else {
var blitbhold = blt_info.bltbhold;
@@ -2177,7 +2154,8 @@ function Blitter() {
var bltadat, blitahold;
var bltbdat;
if (bltadatptr) {
- bltadat = blt_info.bltadat = AMIGA.mem.load16_chip(bltadatptr);
+ //blt_info.bltadat = bltadat = AMIGA.mem.load16_chip(bltadatptr);
+ blt_info.bltadat = bltadat = AMIGA.mem.chip.data[bltadatptr >>> 1];
bltadatptr -= 2;
} else
bltadat = blt_info.bltadat;
@@ -2186,19 +2164,23 @@ function Blitter() {
preva = bltadat;
if (bltbdatptr) {
- blt_info.bltbdat = bltbdat = AMIGA.mem.load16_chip(bltbdatptr);
+ //blt_info.bltbdat = bltbdat = AMIGA.mem.load16_chip(bltbdatptr);
+ blt_info.bltbdat = bltbdat = AMIGA.mem.chip.data[bltbdatptr >>> 1];
bltbdatptr -= 2;
blitbhold = (((bltbdat << 16) | prevb) >>> 0) >> blt_info.blitdownbshift;
prevb = bltbdat;
}
if (bltcdatptr) {
- blt_info.bltcdat = blt_info.bltbdat = AMIGA.mem.load16_chip(bltcdatptr);
+ //blt_info.bltcdat = blt_info.bltbdat = AMIGA.mem.load16_chip(bltcdatptr);
+ blt_info.bltcdat = blt_info.bltbdat = AMIGA.mem.chip.data[bltcdatptr >>> 1];
bltcdatptr -= 2;
}
if (dodst)
- AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
- blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xffff;
+ //AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ AMIGA.mem.chip.data[dstp >>> 1] = blt_info.bltddat;
+
+ blt_info.bltddat = (blit_func(blitahold & 0xffff, blitbhold & 0xffff, blt_info.bltcdat & 0xffff, mt) >>> 0) & 0xffff;
if (blitfill) {
var d = blt_info.bltddat;
var ifemode = blitife ? 2 : 0;
@@ -2220,7 +2202,9 @@ function Blitter() {
if (bltddatptr) bltddatptr -= blt_info.bltdmod;
}
if (dodst)
- AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ //AMIGA.mem.store16_chip(dstp, blt_info.bltddat);
+ AMIGA.mem.chip.data[dstp >>> 1] = blt_info.bltddat;
+
blt_info.bltbhold = blitbhold;
}
blit_masktable[0] = 0xffff;
@@ -2232,7 +2216,8 @@ function Blitter() {
function blitter_read() {
if (bltcon0 & 0x200) {
if (AMIGA.dmaen(DMAF_BLTEN))
- blt_info.bltcdat = AMIGA.mem.load16_chip(bltcpt);
+ //blt_info.bltcdat = AMIGA.mem.load16_chip(bltcpt);
+ blt_info.bltcdat = dat = AMIGA.mem.chip.data[bltcpt >>> 1];
}
bltstate = BLT_work;
}
@@ -2243,7 +2228,8 @@ function Blitter() {
if (bltcon0 & 0x200) {
if (AMIGA.dmaen(DMAF_BLTEN))
- AMIGA.mem.store16_chip(bltdpt, blt_info.bltddat);
+ //AMIGA.mem.store16_chip(bltdpt, blt_info.bltddat);
+ AMIGA.mem.chip.data[bltdpt >>> 1] = blt_info.bltddat;
}
bltstate = BLT_next;
}
@@ -2254,7 +2240,7 @@ function Blitter() {
blt_info.bltbhold = (blineb & 1) ? 0xffff : 0;
blitlinepixel = !blitsing || (blitsing && !blitonedot);
- blt_info.bltddat = blit_func (blitahold, blt_info.bltbhold, blitchold, bltcon0 & 0xFF);
+ blt_info.bltddat = blit_func(blitahold, blt_info.bltbhold, blitchold, bltcon0 & 0xff);
blitonedot++;
}
@@ -2396,26 +2382,27 @@ function Blitter() {
if (blt_info.vblitsize <= 0)
bltstate = BLT_done;
} while (bltstate != BLT_done);
+ bltapt_line = null;
bltdpt = bltcpt;
} else {
if (blitdesc)
blitter_dofast_desc();
else
- blitter_dofast();
+ blitter_dofast();
bltstate = BLT_done;
}
}
- function blitter_doit() {
+ function blitter_do() {
actually_do_blit();
- blitter_done(AMIGA.events.hpos());
+ blitter_done(AMIGA.playfield.hpos());
}
/*---------------------------------*/
this.handler = function(data) {
if (!AMIGA.dmaen(DMAF_BLTEN)) {
- AMIGA.events.event2_newevent(EV2_BLITTER, 10, 0);
+ AMIGA.events.newevent(EV2_BLITTER, 10, 0);
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
return;
@@ -2423,40 +2410,15 @@ function Blitter() {
}
blit_stuck = 0;
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
- AMIGA.events.event2_newevent(EV2_BLITTER, blit_slowdown, 0);
+ //console.log('Blitter.handler () slowdown', blit_slowdown);
+ AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
blit_slowdown = -1;
return;
}
- blitter_doit();
+ blitter_do();
}
- /*function blitter_force_finish() {
- if (bltstate == BLT_done)
- return;
- if (bltstate != BLT_done) {
- var odmacon = AMIGA.dmacon;
- AMIGA.dmacon |= DMAF_DMAEN | DMAF_BLTEN;
- BUG.info('forcing blitter finish');
-
- if (blitter_cycle_exact) {
- var rounds = 10000;
- while (bltstate != BLT_done && rounds > 0) {
- memset (cycle_line, 0, sizeof cycle_line);
- decide_blitter (-1);
- rounds--;
- }
- if (rounds == 0) BUG.info('blitter froze!?');
- blit_startcycles = 0;
- } else {
- actually_do_blit();
- }
- blitter_done(AMIGA.events.hpos());
- AMIGA.dmacon = odmacon;
- }
- }*/
-
- /*var changetable = new Uint8Array(32 * 32);
- for (var i = 0; i < changetable.length; i++) changetable[i] = 0;*/
+ var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0;
var freezes = 10;
function blit_bltset(con) {
if (con & 2) {
@@ -2498,50 +2460,25 @@ function Blitter() {
blit_diag = blitfill && blit_cycle_diagram_fill[blit_ch][0] ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch];
}
- if ((bltcon1 & 0x80) && (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS))
+ if ((bltcon1 & 0x80) && (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
BUG.info('blit_bltset() ECS BLTCON1 DOFF-bit set');
- /*on the fly switching fillmode from extra cycle to non-extra: blitter freezes
- non-extra cycle to extra cycle: does not freeze but cycle diagram goes weird,
- extra free cycle changes to another D write..
- (Absolute Inebriation vector cube inside semi-filled vector object requires freezing blitter.)*/
- /*if (bltstate != BLT_done) {
- var olddiag = blit_diag;
- var isen = blit_diag >= &blit_cycle_diagram_fill[0][0] && blit_diag <= &blit_cycle_diagram_fill[15][0];
- var iseo = olddiag >= &blit_cycle_diagram_fill[0][0] && olddiag <= &blit_cycle_diagram_fill[15][0];
- if (iseo != isen) {
- if (freezes > 0) {
- BUG.info('BLITTER: on the fly %d (%d) -> %d (%d) switch!', original_ch, iseo, blit_ch, isen);
- freezes--;
- }
- }
- if (original_fill == isen) {
- blit_frozen = 0;
- } else if (iseo && !isen) {
- blit_frozen = 1;
- BUG.info('BLITTER: frozen! %d (%d) -> %d (%d)', original_ch, iseo, blit_ch, isen);
- } else if (!iseo && isen) {
- BUG.info('BLITTER: on the fly %d (%d) -> %d (%d) switch', original_ch, iseo, blit_ch, isen);
- }
- }*/
-
// on the fly switching from CH=1 to CH=D -> blitter stops writing (Rampage/TEK)
// currently just switch to no-channels mode, better than crashing the demo..
if (bltstate != BLT_done) {
- /*var o = original_ch + (original_fill ? 16 : 0);
+ var o = original_ch + (original_fill ? 16 : 0);
var n = blit_ch + (blitfill ? 16 : 0);
if (o != n) {
if (changetable[o * 32 + n] < 10) {
changetable[o * 32 + n]++;
BUG.info('blit_bltset() channel mode changed while active (%02x->%02x)', o, n);
}
- }*/
+ }
if (blit_ch == 13 && original_ch == 1)
blit_faulty = 1;
}
-
if (blit_faulty) {
- //BUG.info('blit_bltset() blit_faulty!');
+ BUG.info('blit_bltset() blitter faulty!');
blit_ch = 0;
blit_diag = blit_cycle_diagram[blit_ch];
}
@@ -2559,15 +2496,6 @@ function Blitter() {
}
}
- /*function blit_modset() {
- blit_add = blitdesc ? -2 : 2;
- var mult = blitdesc ? -1 : 1;
- blit_modadda = mult * blt_info.bltamod;
- blit_modaddb = mult * blt_info.bltbmod;
- blit_modaddc = mult * blt_info.bltcmod;
- blit_modaddd = mult * blt_info.bltdmod;
- }*/
-
function reset_blit(bltcon) {
if (bltcon & 1)
blinea_shift = bltcon0 >> 12;
@@ -2577,7 +2505,6 @@ function Blitter() {
return;
if (bltcon)
blit_bltset(bltcon);
- //blit_modset();
}
var warned1 = 10;
@@ -2596,14 +2523,9 @@ function Blitter() {
return false;
}
- function do_blitter2(hpos, copper) {
+ function do_blitter(hpos, copper) {
var cycles;
- //#ifdef BLITTER_DEBUG_NOWAIT
- if (bltstate != BLT_done) {
- if (blit_final) BUG.info('do_blitter2() blitter was already active!');
- }
- //#endif
var cleanstart = 0;
if (bltstate == BLT_done) {
if (blit_faulty > 0)
@@ -2613,23 +2535,17 @@ function Blitter() {
bltstate = BLT_done;
- blitter_cycle_exact = AMIGA.config.blitter.exact;
blt_info.blitzero = 1;
preva = 0;
prevb = 0;
blt_info.got_cycle = 0;
- //blit_frozen = 0;
blit_firstline_cycles = blit_first_cycle = AMIGA.events.currcycle;
- //blit_misscyclecounter = 0;
blit_last_cycle = 0;
- //blit_maxcyclecounter = 0;
- //last_blitter_hpos = hpos + 1;
+ last_blitter_hpos = hpos + 1;
blit_cyclecounter = 0;
- //blit_totalcyclecounter = 0;
blit_bltset(1 | 2);
- //blit_modset();
ddat1use = ddat2use = 0;
blit_interrupt = false;
@@ -2643,7 +2559,6 @@ function Blitter() {
} else {
blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * blt_info.hblitsize + AMIGA.cpu.cycles) * CYCLE_UNIT;
cycles = blt_info.vblitsize * blt_info.hblitsize;
- //console.log('blit_firstline_cycles', blit_firstline_cycles, cycles);
}
if (cleanstart) {
@@ -2654,14 +2569,10 @@ function Blitter() {
/*if (0) {
var ch = 0;
- if (blit_ch & 1)
- ch++;
- if (blit_ch & 2)
- ch++;
- if (blit_ch & 4)
- ch++;
- if (blit_ch & 8)
- ch++;
+ if (blit_ch & 1) ch++;
+ if (blit_ch & 2) ch++;
+ if (blit_ch & 4) ch++;
+ if (blit_ch & 8) ch++;
BUG.info('do_blitter2() %dx%d ch=%d %d*%d=%d d=%d f=%d n=%d l=%d dma=%04x %s',
blt_info.hblitsize, blt_info.vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles,
blitdesc ? 1 : 0, blitfill ? 1 : 0, AMIGA.dmaen(DMAF_BLTPRI) ? 1 : 0, blitline ? 1 : 0,
@@ -2672,43 +2583,29 @@ function Blitter() {
bltstate = BLT_init;
blit_slowdown = 0;
- clr_special (SPCFLAG_BLTNASTY);
+ clr_special(SPCFLAG_BLTNASTY);
if (AMIGA.dmaen(DMAF_BLTPRI))
- set_special (SPCFLAG_BLTNASTY);
+ set_special(SPCFLAG_BLTNASTY);
if (AMIGA.dmaen(DMAF_BLTEN))
bltstate = BLT_work;
- /*blit_maxcyclecounter = 0x7fffffff;
- if (blitter_cycle_exact) {
- blitter_hcounter1 = blitter_hcounter2 = 0;
- blitter_vcounter1 = blitter_vcounter2 = 0;
- if (blit_nod)
- blitter_vcounter2 = blt_info.vblitsize;
- blit_cyclecounter = -BLITTER_STARTUP_CYCLES;
- blit_waitcyclecounter = copper;
- blit_startcycles = 0;
- blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2;
- return;
- }*/
-
if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
blitter_done(hpos);
return;
}
-
blt_info.got_cycle = 1;
- //blit_waitcyclecounter = 0;
if (AMIGA.config.blitter.immediate) {
- blitter_doit();
+ blitter_do();
return;
}
- blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1));
- AMIGA.events.event2_newevent(EV2_BLITTER, blit_cyclecounter, 0);
+ blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1));
- if (AMIGA.dmaen(DMAF_BLTEN) && (AMIGA.config.cpu.model >= 68020 || !AMIGA.config.cpu.exact)) {
+ AMIGA.events.newevent(EV2_BLITTER, blit_cyclecounter, 0);
+
+ if (AMIGA.dmaen(DMAF_BLTEN)) {
if (AMIGA.config.blitter.waiting) {
// wait immediately if all cycles in use and blitter nastry
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
@@ -2717,28 +2614,16 @@ function Blitter() {
}
}
- function do_blitter(hpos, copper) {
- if (bltstate == BLT_done || !AMIGA.config.blitter.exact) {
- do_blitter2(hpos, copper);
- return;
- }
- if (!AMIGA.dmaen(DMAF_BLTEN) || !blt_info.got_cycle)
- return;
-
- //blit_startcycles = BLITTER_STARTUP_CYCLES;
- //blit_waitcyclecounter = copper;
- }
-
var warned2 = 10;
- function maybe_blit(hpos, hack) {
+ this.maybe_blit = function(hpos, hack) {
if (bltstate == BLT_done)
return;
- if (AMIGA.dmaen(DMAF_BLTEN) && (AMIGA.config.cpu.model >= 68020 || !AMIGA.config.cpu.exact)) {
+ if (AMIGA.dmaen(DMAF_BLTEN)) {
var doit = false;
if (AMIGA.config.blitter.waiting == 3) { // always
doit = true;
- } else if (AMIGA.config.blitter.waiting == 2) { // noidle
+ } 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
@@ -2748,7 +2633,7 @@ function Blitter() {
doit = true;
}
if (doit) {
- if (waitingblits ())
+ if (waitingblits())
return;
}
}
@@ -2758,10 +2643,6 @@ function Blitter() {
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
}
- /*if (blitter_cycle_exact) {
- decide_blitter (hpos);
- return;
- }*/
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
return;
@@ -2769,22 +2650,15 @@ function Blitter() {
}
this.blitnasty = function() {
- var cycles, ccnt;
- if (bltstate == BLT_done)
+ if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
return 0;
- if (!AMIGA.dmaen(DMAF_BLTEN))
- return 0;
- /*if (blitter_cycle_exact) {
- blitter_force_finish();
- return -1;
- }*/
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
return 0;
- cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) / CYCLE_UNIT);
- ccnt = 0;
+
+ var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
+ var ccnt = 0;
while (blit_last_cycle < cycles) {
- var c = channel_state(blit_last_cycle++);
- if (!c)
+ if (!channel_state(blit_last_cycle++))
ccnt++;
}
return ccnt;
@@ -2794,7 +2668,7 @@ function Blitter() {
var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0;
this.slowdown = function() {
- var data = AMIGA.playfield.get_data();
+ var data = AMIGA.playfield.getData();
var ddfstrt = data[0];
var ddfstop = data[1];
var totalcycles = data[2];
@@ -2803,9 +2677,10 @@ function Blitter() {
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 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;
@@ -2818,15 +2693,13 @@ function Blitter() {
return;
blit_slowdown += slow;
- //blit_misscyclecounter += slow;
- //console.log('Blitter.slowdown()', data, blit_slowdown);
}
/*---------------------------------*/
- this.BLTADAT = function(hpos, v) { maybe_blit(hpos, 0); blt_info.bltadat = v; }
+ this.BLTADAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltadat = v; }
this.BLTBDAT = function(hpos, v) {
- maybe_blit(hpos, 0);
+ this.maybe_blit(hpos, 0);
if (bltcon1 & 2)
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
else
@@ -2834,35 +2707,35 @@ function Blitter() {
blt_info.bltbdat = v;
}
- this.BLTCDAT = function(hpos, v) { maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); }
+ this.BLTCDAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); }
- this.BLTAMOD = function(hpos, v) { maybe_blit(hpos, 1); blt_info.bltamod = castWord(v & 0xfffe); reset_blit(0); }
- this.BLTBMOD = function(hpos, v) { maybe_blit(hpos, 1); blt_info.bltbmod = castWord(v & 0xfffe); reset_blit(0); }
- this.BLTCMOD = function(hpos, v) { maybe_blit(hpos, 1); blt_info.bltcmod = castWord(v & 0xfffe); reset_blit(0); }
- this.BLTDMOD = function(hpos, v) { 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) { maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); }
+ this.BLTCON0 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); }
this.BLTCON0L = function( hpos, v) {
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_OCS) return;
- maybe_blit(hpos, 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
+ 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) { maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); }
+ this.BLTCON1 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); }
- this.BLTAFWM = function(hpos, v) { maybe_blit(hpos, 2); blt_info.bltafwm = v; reset_blit(0); }
- this.BLTALWM = function(hpos, v) { 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) { maybe_blit(hpos, 0); bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; }
- this.BLTAPTL = function(hpos, v) { maybe_blit(hpos, 0); bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; }
- this.BLTBPTH = function(hpos, v) { maybe_blit(hpos, 0); bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; }
- this.BLTBPTL = function(hpos, v) { maybe_blit(hpos, 0); bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
- this.BLTCPTH = function(hpos, v) { maybe_blit(hpos, 0); bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; }
- this.BLTCPTL = function(hpos, v) { maybe_blit(hpos, 0); bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
- this.BLTDPTH = function(hpos, v) { maybe_blit(hpos, 0); bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; }
- this.BLTDPTL = function(hpos, v) { 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) {
- maybe_blit(hpos, 0);
+ this.maybe_blit(hpos, 0);
blt_info.vblitsize = v >> 6;
blt_info.hblitsize = v & 0x3F;
@@ -2870,23 +2743,25 @@ function Blitter() {
blt_info.vblitsize = 1024;
if (!blt_info.hblitsize)
blt_info.hblitsize = 64;
+
do_blitter(hpos, AMIGA.copper.access);
}
this.BLTSIZV = function(hpos, v) {
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_OCS) return;
- maybe_blit(hpos, 0);
+ 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.type == SAEV_Config_Chipset_Type_OCS) return;
- maybe_blit(hpos, 0);
+ 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);
}
diff --git a/sae/cia.js b/sae/cia.js
index 1b742e4..d386eaf 100644
--- a/sae/cia.js
+++ b/sae/cia.js
@@ -6,733 +6,1315 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes: Ported from WinUAE 2.5.0
+*
**************************************************************************/
-function CIA_8520(type) {
- const STARTCYCLESHI = 3;
- const STARTCYCLESCRA = 2;
+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;
- this.type = type;
+const TOD_HACK = 1;
- this.icr = 0;
- this.icrReg = 0;
- this.iMask = 0;
- this.iFlag = type == CIA_A ? INTF_PORTS : INTF_EXTER; /* 0x0008 : 0x2000 */
+/* e-clock is 10 CPU cycles, 4 cycles high, 6 low data transfer happens during 4 high cycles */
+const ECLOCK_DATA_CYCLE = 4;
+const ECLOCK_WAIT_CYCLE = 6;
- this.cra = 0;
- this.crb = 0;
- this.dra = 0;
- this.drb = 0;
- this.pra = 0;
- this.prb = 0;
- this.sdr = 0;
- this.sdrCnt = 0;
+const DIV10 = ((ECLOCK_DATA_CYCLE + ECLOCK_WAIT_CYCLE) * CYCLE_UNIT / 2); /* Yes, a bad identifier. */
+const CIASTARTCYCLESHI = 3;
+const CIASTARTCYCLESCRA = 2;
- this.ta = 0;
- this.tb = 0;
- this.taPassed = 0;
- this.tbPassed = 0;
- this.la = 0;
- this.lb = 0;
- this.starta = 0;
- this.startb = 0;
-
- this.todOn = false;
- this.tod = 0;
- this.tol = 0;
- this.tlatch = 0;
- this.alarm = 0;
-
- this.reset = function() {
- this.icr = this.iMask = 0;
- this.cra = this.crb = 0x4;
- this.dra = this.drb = 0;
- this.pra = this.type == CIA_A ? 0 : 0x8c;
- this.sdr = 0;
- this.sdrCnt = 0;
- this.la = this.lb = this.ta = this.tb = 0xffff;
- this.taPassed = this.tbPassed = 0;
- this.tod = 0;
- this.todOn = false;
- this.tlatch = 0;
- this.alarm = 0;
- }
-
- this.dump = function() {
- BUG.info('CIA_8520.dump() %s | pra $%02x prb $%02x | dra $%02x drb $%02x | ta %5d (la %5d) tb %5d (lb %5d) | tod %5d (tol %5d) alarm %5d latch %d | sdr $%02x | icr $%02x iMask $%02x | cra $%02x crb $%02x',
- this.type == CIA_A ? 'A' : 'B', this.pra, this.prb, this.dra, this.drb, this.ta, this.la, this.tb, this.lb, this.tod, this.tol, this.alarm, this.latch ? 1 : 0, this.sdr, this.icr, this.iMask, this.cra, this.crb);
- }
-
- this.setClr = function (val) {
- if (val & 0x80) this.iMask |= val & 0x7f;
- else this.iMask &= ~val;
- }
-
- this.setICR = function (icr, sdr) {
- if (sdr !== null)
- this.sdr = sdr;
-
- this.icr |= icr;
- this.reThink();
- }
-
- this.ICR = function() {
- if (this.iMask & this.icr) {
- this.icr |= 0x80;
- AMIGA.INTREQ_0(INTF_SETCLR | this.iFlag);
- }
- this.icrReg |= this.icr;
- }
-
- this.reThink = function() {
- if (this.icr) {
- if (AMIGA.config.cpu.exact)
- AMIGA.events.event2_newevent_xx(-1, CIA_RETHINK_DELAY, this.type, function(v) { AMIGA.cia.ICR(v); });
- else
- this.ICR();
- }
- }
-
- this.updateCheck = function (ciaclocks) {
- var ovfla = false;
- var ovflb = false;
- var sp = false;
- var needReThink = false;
-
- if ((this.cra & 0x21) == 0x01) {
- //BUG.info('CIA.updateCheck() ciaclocks %d, starta %d, ta %d', ciaclocks, this.starta, this.ta);
- var check = true;
- var cc = ciaclocks;
- if (this.starta > 0) {
- if (cc > this.starta) {
- cc -= this.starta;
- this.starta = 0;
- } else {
- this.starta -= cc;
- check = false;
- }
- }
- if (check) {
- //assert ((this.ta + 1) >= cc);
- if ((this.ta + 1) == cc) {
- if ((this.cra & 0x48) == 0x40 && this.sdrCnt > 0 && --this.sdrCnt == 0) sp = true;
-
- ovfla = true;
- if ((this.crb & 0x61) == 0x41 || (this.crb & 0x61) == 0x61) {
- if (this.tb-- == 0) ovflb = true;
- }
- }
- this.ta -= cc;
- }
- }
- if ((this.crb & 0x61) == 0x01) {
- //BUG.info('CIA.updateCheck() ciaclocks %d, startb %d, tb %d', ciaclocks, this.startb, this.tb);
- var check = true;
- var cc = ciaclocks;
- if (this.startb > 0) {
- if (cc > this.startb) {
- cc -= this.startb;
- this.startb = 0;
- } else {
- this.startb -= cc;
- check = false;
- }
- }
- if (check) {
- //assert ((this.tb + 1) >= cc);
- if ((this.tb + 1) == cc) ovflb = true;
- this.tb -= cc;
- }
- }
-
- if (ovfla) {
- this.icr |= 1;
- needReThink = true;
- this.ta = this.la;
- if (this.cra & 0x8) {
- this.cra &= ~1;
- }
- }
- if (ovflb) {
- this.icr |= 2;
- needReThink = true;
- this.tb = this.lb;
- if (this.crb & 0x8) {
- this.crb &= ~1;
- }
- }
- if (sp) {
- this.icr |= 8;
- needReThink = true;
- }
- return needReThink;
- }
-
- this.calcTimers = function (div10diff) {
- var time = [-1, -1];
-
- if ((this.cra & 0x21) == 0x01) time[0] = div10diff + DIV10 * (this.ta + this.starta);
- if ((this.crb & 0x61) == 0x01) time[1] = div10diff + DIV10 * (this.tb + this.startb);
-
- //if (time[0] != -1 || time[1] != -1) BUG.info('CIA.calcTimers() div10diff %d, timea %d, timeb %d', div10diff, time[0], time[1]);
- return time;
- }
-
- this.checkAlarm = function (inc) {
- var alarm;
-
- if (this.tod == this.alarm) alarm = true;
- else if (!inc) alarm = false;
- else if (this.tod & 0x000fff) alarm = false;
- else if (((this.tod - 1) & 0xfff000) == this.alarm) alarm = true;
- else alarm = false;
-
- if (alarm) {
- this.icr |= 4;
- this.reThink();
- }
- }
-
- this.calcPassedTime = function() {
- var ccount = AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles + AMIGA.cia.div10;
- var ciaclocks = Math.floor(ccount / DIV10);
-
- this.taPassed = this.tbPassed = 0;
-
- if ((this.cra & 0x21) == 0x01) {
- var cc = ciaclocks;
- if (cc > this.starta) cc -= this.starta;
- else cc = 0;
- //assert ((this.ta + 1) >= cc);
- this.taPassed = cc;
- }
- if ((this.crb & 0x61) == 0x01) {
- var cc = ciaclocks;
- if (cc > this.startb) cc -= this.startb;
- else cc = 0;
- //assert ((this.tb + 1) >= cc);
- this.tbPassed = cc;
- }
- }
-
- this.read = function (addr) {
- var reg = addr & 15;
- var tmp;
-
- this.calcPassedTime();
-
- switch (reg) {
- case 0: {
- if (this.type == CIA_A) {
- tmp = AMIGA.disk.status() & 0x3c;
-
- if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
- if (!AMIGA.input.mouse.button[0]) tmp |= 0x40;
- if (this.dra & 0x40) tmp = (tmp & ~0x40) | (this.pra & 0x40);
- } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
- if (!AMIGA.input.joystick[0].button[0]) tmp |= 0x40;
- if (this.dra & 0x40) tmp = (tmp & ~0x40) | (this.pra & 0x40);
- } else tmp |= 0x40;
-
- if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
- if (!AMIGA.input.joystick[1].button[0]) tmp |= 0x80;
- if (this.dra & 0x80) tmp = (tmp & ~0x80) | (this.pra & 0x80);
- } else tmp |= 0x80;
-
- tmp |= (this.pra | (this.dra ^ 3)) & 3;
- } else {
- //tmp = 0xf8;
- tmp = AMIGA.serial.readStatus(this.dra);
- }
- return tmp;
- }
- case 1: {
- if (this.type == CIA_A) {
- tmp = 0;
- } else {
- tmp = this.prb;
- }
- if (this.crb & 2) {
- var pb7 = 0;
- if (this.crb & 4) pb7 = this.crb & 1;
- tmp &= ~0x80;
- tmp |= pb7 ? 0x80 : 0;
- }
- if (this.cra & 2) {
- var pb6 = 0;
- if (this.cra & 4) pb6 = this.cra & 1;
- tmp &= ~0x40;
- tmp |= pb6 ? 0x40 : 0;
- }
- return tmp;
- }
- case 2:
- return this.dra;
- case 3:
- return this.drb;
- case 4:
- return ((this.ta - this.taPassed) & 0xff);
- case 5:
- return ((this.ta - this.taPassed) >> 8) & 0xff;
- case 6:
- return ((this.tb - this.tbPassed) & 0xff);
- case 7:
- return ((this.tb - this.tbPassed) >> 8) & 0xff;
- case 8: {
- if (this.tlatch) {
- this.tlatch = 0;
- return this.tol & 0xff;
- } else return this.tod & 0xff;
- }
- case 9: {
- if (this.tlatch) return (this.tol >> 8) & 0xff;
- else return (this.tod >> 8) & 0xff;
- }
- case 10: {
- if (!this.tlatch) {
- if (!(this.crb & 0x80)) this.tlatch = 1;
- this.tol = this.tod;
- }
- return (this.tol >>> 16) & 0xff;
- }
- case 12:
- return this.sdr;
- case 13: {
- tmp = this.icrReg;
- this.icr &= ~this.icrReg;
- this.icrReg = 0;
- this.reThink();
- return tmp;
- }
- case 14:
- return this.cra;
- case 15:
- return this.crb;
- }
- }
-
- this.write = function (addr, val) {
- var reg = addr & 15;
-
- switch (reg) {
- case 0: {
- if (this.type == CIA_A) {
- this.pra = (this.pra & 0x3c) | (val & 0xc3);
- AMIGA.cia.handlePowerLED(this.pra, this.dra);
- } else {
- this.pra = val;
- AMIGA.serial.writeStatus(this.pra, this.dra);
- }
- break;
- }
- case 1: {
- if (this.type == CIA_A) {
- this.prb = val;
- } else {
- this.prb = val;
- AMIGA.disk.select(val);
- }
- break;
- }
- case 2: {
- if (this.type == CIA_A) {
- this.dra = val;
- AMIGA.cia.handlePowerLED(this.pra, this.dra);
- } else {
- this.dra = val;
- AMIGA.serial.writeStatus(this.pra, this.dra);
- }
- break;
- }
- case 3: {
- if (this.type == CIA_A) {
- this.drb = val;
- } else {
- this.drb = val;
- }
- break;
- }
- case 4: {
- AMIGA.cia.update();
- this.la = (this.la & 0xff00) | val;
- AMIGA.cia.calcTimers();
- break;
- }
- case 5: {
- AMIGA.cia.update();
- this.la = (this.la & 0x00ff) | (val << 8);
- if ((this.cra & 1) == 0) this.ta = this.la;
- if (this.cra & 8) {
- this.ta = this.la;
- this.cra |= 1;
- this.starta = STARTCYCLESHI;
- }
- AMIGA.cia.calcTimers();
- break;
- }
- case 6: {
- AMIGA.cia.update();
- this.lb = (this.lb & 0xff00) | val;
- AMIGA.cia.calcTimers();
- break;
- }
- case 7: {
- AMIGA.cia.update();
- this.lb = (this.lb & 0x00ff) | (val << 8);
- if ((this.crb & 1) == 0) this.tb = this.lb;
- if (this.crb & 8) {
- this.tb = this.lb;
- this.crb |= 1;
- this.startb = STARTCYCLESHI;
- }
- AMIGA.cia.calcTimers();
- break;
- }
- case 8: {
- if (this.crb & 0x80) {
- this.alarm = (this.alarm & 0xffff00) | val;
- } else {
- this.tod = (this.tod & 0xffff00) | val;
- this.todOn = true;
- this.checkAlarm(0);
- }
- break;
- }
- case 9: {
- if (this.crb & 0x80) {
- this.alarm = (this.alarm & 0xff00ff) | (val << 8);
- } else {
- this.tod = (this.tod & 0xff00ff) | (val << 8);
- }
- break;
- }
- case 10: {
- if (this.crb & 0x80) {
- this.alarm = (this.alarm & 0x00ffff) | (val << 16);
- } else {
- this.tod = (this.tod & 0x00ffff) | (val << 16);
- this.todOn = false;
- }
- break;
- }
- case 12: {
- AMIGA.cia.update();
- this.sdr = val;
- if (this.type == CIA_B && (this.cra & 0x40) == 0) this.sdrCnt = 0;
- if ((this.cra & 0x41) == 0x41 && this.sdrCnt == 0) this.sdrCnt = 8 * 2;
- AMIGA.cia.calcTimers();
- break;
- }
- case 13: {
- this.setClr(val);
- break;
- }
- case 14: {
- AMIGA.cia.update();
- val &= 0x7f;
- if ((val & 1) && !(this.cra & 1)) this.starta = STARTCYCLESCRA;
- if (this.type == CIA_A && (val & 0x40) != (this.cra & 0x40)) {
- AMIGA.input.keyboard.lostsynccnt = 0;
- //BUG.info('KB_ACK %02x to %02x', val, this.cra);
- }
- this.cra = val;
- if (this.cra & 0x10) {
- this.cra &= ~0x10;
- this.ta = this.la;
- }
- AMIGA.cia.calcTimers();
- break;
- }
- case 15: {
- AMIGA.cia.update();
- if ((val & 1) && !(this.crb & 1)) this.startb = STARTCYCLESCRA;
- this.crb = val;
- if (this.crb & 0x10) {
- this.crb &= ~0x10;
- this.tb = this.lb;
- }
- AMIGA.cia.calcTimers();
- break;
- }
- }
- }
-}
+//console.log('DIV10', CYCLE_UNIT, DIV10);
function CIA() {
- this.A = new CIA_8520(CIA_A);
- this.B = new CIA_8520(CIA_B);
- this.div10 = 0;
+ var ciaaicr = 0, ciaaimask = 0, ciabicr = 0, ciabimask = 0;
+ var ciaacra = 0, ciaacrb = 0, ciabcra = 0, ciabcrb = 0;
+ var ciaastarta = 0, ciaastartb = 0, ciabstarta = 0, ciabstartb = 0;
+ var ciaaicr_reg = 0, ciabicr_reg = 0;
- var led = true;
+ var ciaata = 0, ciaatb = 0, ciabta = 0, ciabtb = 0;
+ var ciaata_passed = 0, ciaatb_passed = 0, ciabta_passed = 0, ciabtb_passed = 0;
- var todHack = {
- active: true,
- enabled: false,
- rate: 0.0,
- tv: 0.0
- };
+ var ciaatod = 0, ciabtod = 0, ciaatol = 0, ciabtol = 0, ciaaalarm = 0, ciabalarm = 0;
+ var ciaatlatch = 0, ciabtlatch = 0;
+ var oldled = false;//, oldovl = false, oldcd32mute = false;
+ var led = false;
+ var led_old_brightness = 0;
+ var led_cycles_on = 0, led_cycles_off = 0, led_cycle = 0;
- this.setup = function() {
- if (todHack.active) todHack.rate = 1000.0 / AMIGA.events.hz;
+ var ciaala = 0, ciaalb = 0, ciabla = 0, ciablb = 0;
+ var ciaatodon = 0, ciabtodon = 0;
+ var ciaapra = 0, ciaaprb = 0, ciaadra = 0, ciaadrb = 0, ciaasdr = 0, ciaasdr_cnt = 0;
+ var ciabpra = 0, ciabprb = 0, ciabdra = 0, ciabdrb = 0, ciabsdr = 0, ciabsdr_cnt = 0;
+ var div10 = 0;
+ //var kbstate = 0, kblostsynccnt = 0, kbcode = 0;
+
+ var serbits = 0;
+ var warned = 10;
+ //var rtc_delayed_write = 0;
+
+ /*function setclr (unsigned int *p, unsigned int val) {
+ if (val & 0x80) {
+ *p |= val & 0x7F;
+ } else {
+ *p &= ~val;
+ }
+ }*/
+
+ function setclra(val) {
+ if (val & 0x80) {
+ ciaaimask |= val & 0x7F;
+ } else {
+ ciaaimask &= ~val;
+ }
}
-
- this.reset = function() {
- this.A.reset();
- this.B.reset();
- this.div10 = 0;
- this.calcTimers();
-
- led = true;
- AMIGA.disk.select_set(this.B.prb);
-
- if (todHack.active) {
- todHack.enabled = AMIGA.events.maxvpos * AMIGA.events.hz * 10;
- todHack.tv = 0.0;
+ function setclrb(val) {
+ if (val & 0x80) {
+ ciabimask |= val & 0x7F;
+ } else {
+ ciabimask &= ~val;
}
}
- this.dump = function() {
- this.A.dump();
- this.B.dump();
- }
-
- this.handlePowerLED = function (pra, dra) {
- var v = pra | (~dra & 0xff);
- var newled = (v & 2) ? 0 : 1;
-
- if (led != newled) {
- led = newled;
- AMIGA.audio.filter.led_filter_on = led;
- AMIGA.config.hooks.power_led(led);
+ function RethinkICRA() {
+ if (ciaaicr) {
+ if (ciaaimask & ciaaicr) {
+ ciaaicr |= 0x80;
+ AMIGA.INTREQ_0(0x8000 | 0x0008);
+ }
+ ciaaicr_reg |= ciaaicr;
}
}
- this.setICR = function (type, icr, sdr) {
- if (type == CIA_A)
- this.A.setICR(icr, sdr);
- else
- this.B.setICR(icr, sdr);
+ function RethinkICRB() {
+ if (ciabicr) {
+ if (ciabimask & ciabicr) {
+ ciabicr |= 0x80;
+ AMIGA.INTREQ_0(0x8000 | 0x2000);
+ }
+ ciabicr_reg |= ciabicr;
+ }
}
- this.ICR = function(type) {
- if (type == CIA_A)
- this.A.ICR();
- else
- this.B.ICR();
+ this.SetICRA = function(icr, sdr) {
+ ciaaicr |= icr;
+ ciaasdr = sdr;
+ RethinkICRA();
+ }
+
+ this.SetICRB = function(icr, sdr) {
+ ciabicr |= icr;
+ if (sdr !== null)
+ ciabsdr = sdr;
+ RethinkICRB();
+ }
+
+ this.rethink = function() {
+ RethinkICRA();
+ RethinkICRB();
}
- this.reThink = function() {
- this.A.reThink();
- this.B.reThink();
- }
-
- this.update = function() {
- var ccount = AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles + this.div10;
+ /* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */
+ function compute_passed_time() {
+ var ccount = (AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles + div10);
var ciaclocks = Math.floor(ccount / DIV10);
- this.div10 = ccount % DIV10;
+ ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
- //BUG.info('CIA.update() %d %d', ciaclocks, this.div10);
+ /* CIA A timers */
+ if ((ciaacra & 0x21) == 0x01) {
+ var cc = ciaclocks;
+ if (cc > ciaastarta)
+ cc -= ciaastarta;
+ else
+ cc = 0;
+ //assert((ciaata + 1) >= cc);
+ ciaata_passed = cc;
+ }
+ if ((ciaacrb & 0x61) == 0x01) {
+ var cc = ciaclocks;
+ if (cc > ciaastartb)
+ cc -= ciaastartb;
+ else
+ cc = 0;
+ //assert((ciaatb + 1) >= cc);
+ ciaatb_passed = cc;
+ }
- var a = this.A.updateCheck(ciaclocks);
- var b = this.B.updateCheck(ciaclocks);
- if (a) this.A.reThink();
- if (b) this.B.reThink();
+ /* CIA B timers */
+ if ((ciabcra & 0x21) == 0x01) {
+ var cc = ciaclocks;
+ if (cc > ciabstarta)
+ cc -= ciabstarta;
+ else
+ cc = 0;
+ //assert((ciabta + 1) >= cc);
+ ciabta_passed = cc;
+ }
+ if ((ciabcrb & 0x61) == 0x01) {
+ var cc = ciaclocks;
+ if (cc > ciabstartb)
+ cc -= ciabstartb;
+ else
+ cc = 0;
+ //assert((ciabtb + 1) >= cc);
+ ciabtb_passed = cc;
+ }
}
- this.calcTimers = function() {
+ /* Called to advance all CIA timers to the current time. This expects that
+ one of the timer values will be modified, and CIA_calctimers will be called
+ in the same cycle. */
+
+ function CIA_update_check() {
+ var ccount = (AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles + div10);
+ var ciaclocks = Math.floor(ccount / DIV10);
+
+ var aovfla = 0, aovflb = 0, asp = 0, bovfla = 0, bovflb = 0, bsp = 0;
+ var icr = 0;
+
+ div10 = ccount % DIV10;
+
+ /* CIA A timers */
+ if ((ciaacra & 0x21) == 0x01) {
+ var check = true;
+ var cc = ciaclocks;
+ if (ciaastarta > 0) {
+ if (cc > ciaastarta) {
+ cc -= ciaastarta;
+ ciaastarta = 0;
+ } else {
+ ciaastarta -= cc;
+ check = false;
+ }
+ }
+ if (check) {
+ //assert((ciaata + 1) >= cc);
+ if ((ciaata + 1) == cc) {
+ if ((ciaacra & 0x48) == 0x40 && ciaasdr_cnt > 0 && --ciaasdr_cnt == 0)
+ asp = 1;
+ aovfla = 1;
+ if ((ciaacrb & 0x61) == 0x41 || (ciaacrb & 0x61) == 0x61) {
+ if (ciaatb-- == 0)
+ aovflb = 1;
+ }
+ }
+ ciaata -= cc;
+ }
+ }
+ if ((ciaacrb & 0x61) == 0x01) {
+ var check = true;
+ var cc = ciaclocks;
+ if (ciaastartb > 0) {
+ if (cc > ciaastartb) {
+ cc -= ciaastartb;
+ ciaastartb = 0;
+ } else {
+ ciaastartb -= cc;
+ check = false;
+ }
+ }
+ if (check) {
+ //assert((ciaatb + 1) >= cc);
+ if ((ciaatb + 1) == cc)
+ aovflb = 1;
+ ciaatb -= cc;
+ }
+ }
+
+ /* CIA B timers */
+ if ((ciabcra & 0x21) == 0x01) {
+ var check = true;
+ var cc = ciaclocks;
+ if (ciabstarta > 0) {
+ if (cc > ciabstarta) {
+ cc -= ciabstarta;
+ ciabstarta = 0;
+ } else {
+ ciabstarta -= cc;
+ check = false;
+ }
+ }
+ if (check) {
+ //assert((ciabta + 1) >= cc);
+ if ((ciabta + 1) == cc) {
+ if ((ciabcra & 0x48) == 0x40 && ciabsdr_cnt > 0 && --ciabsdr_cnt == 0)
+ bsp = 1;
+ bovfla = 1;
+ if ((ciabcrb & 0x61) == 0x41 || (ciabcrb & 0x61) == 0x61) {
+ if (ciabtb-- == 0)
+ bovflb = 1;
+ }
+ }
+ ciabta -= cc;
+ }
+ }
+ if ((ciabcrb & 0x61) == 0x01) {
+ var check = true;
+ var cc = ciaclocks;
+ if (ciabstartb > 0) {
+ if (cc > ciabstartb) {
+ cc -= ciabstartb;
+ ciabstartb = 0;
+ } else {
+ ciabstartb -= cc;
+ check = false;
+ }
+ }
+ if (check) {
+ //assert((ciabtb + 1) >= cc);
+ if ((ciabtb + 1) == cc)
+ bovflb = 1;
+ ciabtb -= cc;
+ }
+ }
+
+ if (aovfla) {
+ ciaaicr |= 1; icr = 1;
+ ciaata = ciaala;
+ if (ciaacra & 0x8) {
+ ciaacra &= ~1;
+ }
+ }
+ if (aovflb) {
+ ciaaicr |= 2; icr = 1;
+ ciaatb = ciaalb;
+ if (ciaacrb & 0x8) {
+ ciaacrb &= ~1;
+ }
+ }
+ if (asp) {
+ ciaaicr |= 8; icr = 1;
+ }
+ if (bovfla) {
+ ciabicr |= 1; icr |= 2;
+ ciabta = ciabla;
+ if (ciabcra & 0x8) {
+ ciabcra &= ~1;
+ }
+ }
+ if (bovflb) {
+ ciabicr |= 2; icr |= 2;
+ ciabtb = ciablb;
+ if (ciabcrb & 0x8) {
+ ciabcrb &= ~1;
+ }
+ }
+ if (bsp) {
+ ciabicr |= 8; icr |= 2;
+ }
+ return icr;
+ }
+
+ function CIA_update() {
+ var icr = CIA_update_check ();
+ if (icr & 1)
+ RethinkICRA();
+ if (icr & 2)
+ RethinkICRB();
+ }
+
+ /* Call this only after CIA_update has been called in the same cycle. */
+ function CIA_calctimers() {
+ var ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
+ var div10diff = DIV10 - div10;
+
+ if ((ciaacra & 0x21) == 0x01) ciaatimea = div10diff + DIV10 * (ciaata + ciaastarta);
+ if ((ciaacrb & 0x61) == 0x01) ciaatimeb = div10diff + DIV10 * (ciaatb + ciaastartb);
+ if ((ciabcra & 0x21) == 0x01) ciabtimea = div10diff + DIV10 * (ciabta + ciabstarta);
+ if ((ciabcrb & 0x61) == 0x01) ciabtimeb = div10diff + DIV10 * (ciabtb + ciabstartb);
+
AMIGA.events.eventtab[EV_CIA].oldcycles = AMIGA.events.currcycle;
+ AMIGA.events.eventtab[EV_CIA].active = (ciaatimea != -1 || ciaatimeb != -1 || ciabtimea != -1 || ciabtimeb != -1);
- var div10diff = DIV10 - this.div10;
- var a = this.A.calcTimers(div10diff);
- var b = this.B.calcTimers(div10diff);
-
- AMIGA.events.eventtab[EV_CIA].active = (a[0] != -1 || a[1] != -1 || b[0] != -1 || b[1] != -1);
if (AMIGA.events.eventtab[EV_CIA].active) {
- var evtime = 0xffffffff;
-
- if (a[0] != -1) evtime = a[0];
- if (a[1] != -1 && a[1] < evtime) evtime = a[1];
- if (b[0] != -1 && b[0] < evtime) evtime = b[0];
- if (b[1] != -1 && b[1] < evtime) evtime = b[1];
-
- AMIGA.events.eventtab[EV_CIA].evtime = evtime + AMIGA.events.currcycle;
- //BUG.info('CIA.calcTimers() evtime %d', evtime);
+ var ciatime = CYCLE_MAX;
+ if (ciaatimea != -1) ciatime = ciaatimea;
+ if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
+ if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
+ if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
+ AMIGA.events.eventtab[EV_CIA].evtime = ciatime + AMIGA.events.currcycle;
}
AMIGA.events.schedule();
}
this.handler = function() {
- this.update();
- this.calcTimers();
+ CIA_update();
+ CIA_calctimers();
}
- this.handleTodHack = function() {
- if (todHack.enabled > 1) {
- todHack.enabled--;
- if (todHack.enabled == 1) {
- todHack.tv = new Date().getTime();
- BUG.info('CIA.handleTodHack() enabled');
+ /*this.diskindex = function() {
+ ciabicr |= 0x10;
+ RethinkICRB();
+ }
+ this.parallelack = function() {
+ ciaaicr |= 0x10;
+ RethinkICRA();
+ }*/
+
+ function checkalarm (tod, alarm, inc) {
+ if (tod == alarm)
+ return 1;
+ if (!inc)
+ return 0;
+ /* emulate buggy TODMED counter.
+ * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 ..
+ * (2F->20->30 only takes couple of cycles but it will trigger alarm..
+ */
+ if (tod & 0x000fff)
+ return 0;
+ if (((tod - 1) & 0xfff000) == alarm)
+ return 1;
+ return 0;
+ }
+
+ function ciab_checkalarm(inc) {
+ if (checkalarm(ciabtod, ciabalarm, inc)) {
+ ciabicr |= 4;
+ RethinkICRB();
+ }
+ }
+
+ function ciaa_checkalarm(inc) {
+ if (checkalarm(ciaatod, ciaaalarm, inc)) {
+ ciaaicr |= 4;
+ RethinkICRA();
+ }
+ }
+
+ function gettimeofday() {
+ return Math.floor(new Date().getTime());
+ }
+
+//#ifdef TOD_HACK
+ var tod_hack_tv = 0, tod_hack_tod = 0, tod_hack_tod_last = 0;
+ var tod_hack_enabled = -1;
+ const TOD_HACK_TIME = 312 * 50 * 10;
+ function tod_hack_reset() {
+ //var tv;
+ //gettimeofday (&tv, NULL);
+ //tod_hack_tv = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec;
+ tod_hack_tv = gettimeofday();
+ tod_hack_tod = ciaatod;
+ tod_hack_tod_last = tod_hack_tod;
+ }
+//#endif
+
+ /*var heartbeat_cnt = 0;
+ function cia_heartbeat() {
+ heartbeat_cnt = 10;
+ }*/
+
+ var oldrate = 0;
+ function do_tod_hack(dotod) {
+ //console.log('tod',tod_hack_enabled);
+ //var tv;
+ var t;
+ var rate;
+ var docount = 0;
+
+ if (tod_hack_enabled == 0)
+ return;
+ /*if (!heartbeat_cnt) {
+ if (tod_hack_enabled > 0)
+ tod_hack_enabled = -1;
+ return;
+ }*/
+ if (tod_hack_enabled < 0) {
+ tod_hack_enabled = TOD_HACK_TIME;
+ return;
+ }
+ if (tod_hack_enabled > 1) {
+ tod_hack_enabled--;
+ if (tod_hack_enabled == 1) {
+ BUG.info('TOD HACK enabled');
+ tod_hack_reset();
}
return;
}
- if (new Date().getTime() - todHack.tv >= todHack.rate) {
- this.A.tod++;
- this.A.tod &= 0xffffff;
- this.A.checkAlarm(0);
- todHack.tv += todHack.rate;
+
+ if (AMIGA.config.cia.tod == 0)
+ rate = Math.floor(AMIGA.playfield.vblank_hz + 0.5);
+ else if (AMIGA.config.cia.tod == 1)
+ rate = 50;
+ else
+ rate = 60;
+ if (rate <= 0)
+ return;
+ if (rate != oldrate || ciaatod != tod_hack_tod_last) {
+ if (ciaatod != 0) BUG.info('TOD HACK reset %d,%d %d,%d', rate, oldrate, ciaatod, tod_hack_tod_last);
+ tod_hack_reset();
+ oldrate = rate;
+ docount = 1;
+ }
+ if (!dotod && AMIGA.config.cia.tod == 0)
+ return;
+
+ /*gettimeofday (&tv, NULL);
+ t = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec;
+ if (t - tod_hack_tv >= 1000000 / rate) {
+ tod_hack_tv += 1000000 / rate;
+ docount = 1;
+ }*/
+ t = gettimeofday();
+ if (t - tod_hack_tv >= Math.floor(1000 / rate)) {
+ tod_hack_tv += Math.floor(1000 / rate);
+ docount = 1;
+ }
+ if (docount) {
+ ciaatod++;
+ ciaatod &= 0x00ffffff;
+ tod_hack_tod_last = ciaatod;
+ ciaa_checkalarm(0);
}
}
- this.hSyncPre = function() {
+ //this.hsync_prehandler = function() {}
- }
-
- this.hSyncPost = function (doTod) {
- if (this.B.todOn && doTod) {
- this.B.tod++;
- this.B.tod &= 0xffffff;
- this.B.checkAlarm(1);
+ 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 (todHack.active && this.A.todOn) this.handleTodHack();
-
+ /*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();
}
- this.vSyncPre = function() {
+ function calc_led(old_led) {
+ var c = AMIGA.events.currcycle;
+ var t = Math.floor((c - led_cycle) * CYCLE_UNIT_INV);
+ if (old_led)
+ led_cycles_on += t;
+ else
+ led_cycles_off += t;
+ led_cycle = c;
+ }
+
+ var powerled_brightness = 255;
+ var powerled = true;
+ function led_vsync() {
+ var v;
+
+ calc_led(led);
+ if (led_cycles_on && !led_cycles_off)
+ v = 255;
+ else if (led_cycles_off && !led_cycles_on)
+ v = 0;
+ else if (led_cycles_off)
+ v = Math.floor(led_cycles_on * 255 / (led_cycles_on + led_cycles_off));
+ else
+ v = 255;
+ if (v < 0) v = 0;
+ if (v > 255) v = 255;
+
+ /*gui_data.powerled_brightness = v;
+ if (led_old_brightness != gui_data.powerled_brightness) {
+ gui_data.powerled = gui_data.powerled_brightness > 127;
+ gui_led (LED_POWER, gui_data.powerled);
+ led_filter_audio ();
+ }
+ led_old_brightness = gui_data.powerled_brightness;*/
+
+ powerled_brightness = v;
+ if (led_old_brightness != powerled_brightness) {
+ powerled = powerled_brightness > 127;
+ AMIGA.config.hooks.power_led(powerled);
+ AMIGA.audio.filter.led_filter_on = powerled;
+ }
+ led_old_brightness = powerled_brightness;
+
+ led_cycle = AMIGA.events.currcycle;
+ led_cycles_on = 0;
+ 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.vSyncPost = function (doTod) {
- if (todHack.active && todHack.enabled == 1) return;
-
- if (this.A.todOn && doTod) {
- this.A.tod++;
- this.A.tod &= 0xffffff;
- this.A.checkAlarm(1);
+ 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;
}
- }
-
- this.waitPre = function() {
- //if (AMIGA.config.cpu.cachesize) return;
-
-//#ifndef CUSTOM_SIMPLE
- /*var div = (AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles) % DIV10;
- var div2 = Math.floor(DIV10 * ECLOCK_DATA_CYCLE / 10);
- var cycles;
-
- if (div >= div2)
- cycles = DIV10 - div + div2;
- else if (div)
- cycles = DIV10 + div2 - div;
- else
- cycles = div2 - div;
-
- //BUG.info('CIA.waitPre() %d %d', div, cycles);
-
- if (cycles) {
- if (AMIGA.config.cpu.exact)
- AMIGA.events.cycle(cycles);
- else
- AMIGA.events.cycle(cycles);
+ if (ciaatodon && dotod) {
+ ciaatod++;
+ ciaatod &= 0xFFFFFF;
+ ciaa_checkalarm (1);
+ }
+ /*if (vpos == 0) {
+ write_log ('%d', vsync_counter);
+ this.dump();
}*/
-//#endif
}
- this.waitPost = function () {
- AMIGA.events.cycle(6 * CYCLE_UNIT / 2);
+ function bfe001_change() {
+ var v = ciaapra;
+ var led2;
- /*if (AMIGA.config.cpu.cachesize)
- AMIGA.events.cycle(8 * CYCLE_UNIT /2);
- else*/ {
- var c = 6 * CYCLE_UNIT / 2;
- if (AMIGA.config.cpu.exact)
- AMIGA.events.cycle(c);
+ v |= ~ciaadra; /* output is high when pin's direction is input */
+ led2 = (v & 2) ? 0 : 1;
+ if (led2 != led) {
+ calc_led(led);
+ led = led2;
+ led_old_brightness = -1;
+ }
+ /*if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
+ oldovl = v & 1;
+ if (!oldovl) {
+ map_overlay (1);
+ } else {
+ //activate_debugger ();
+ map_overlay (0);
+ }
+ }
+ if (currprefs.cs_cd32cd && (v & 1) != oldcd32mute) {
+ oldcd32mute = v & 1;
+ akiko_mute (oldcd32mute ? 0 : 1);
+ }*/
+ }
+
+ function handle_joystick_buttons(pra, dra) {
+ var tmp = 0;
+ if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
+ if (!AMIGA.input.mouse.button[0]) tmp |= 0x40;
+ if (dra & 0x40) tmp = (tmp & ~0x40) | (pra & 0x40);
+ } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
+ if (!AMIGA.input.joystick[0].button[0]) tmp |= 0x40;
+ if (dra & 0x40) tmp = (tmp & ~0x40) | (pra & 0x40);
+ } else tmp |= 0x40;
+
+ if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
+ if (!AMIGA.input.joystick[1].button[0]) tmp |= 0x80;
+ if (dra & 0x80) tmp = (tmp & ~0x80) | (pra & 0x80);
+ } else tmp |= 0x80;
+
+ return tmp;
+ }
+
+ function handle_parport_joystick (port, pra, dra) {
+ var v;
+ switch (port) {
+ case 0:
+ v = (pra & dra) | (dra ^ 0xff);
+ return v;
+ case 1:
+ v = ((pra & dra) | (dra ^ 0xff)) & 0x7;
+ return v;
+ default:
+ return 0;
+ }
+ }
+
+ function ReadCIAA(addr) {
+ var tmp;
+ var reg = addr & 15;
+
+ compute_passed_time();
+
+ //if (CIAA_DEBUG_R) write_log (_T('R_CIAA: bfe%x01 %08X\n'), reg, M68K_GETPC);
+
+ switch (reg) {
+ case 0:
+ tmp = AMIGA.disk.status() & 0x3c;
+ tmp |= handle_joystick_buttons(ciaapra, ciaadra);
+ tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
+ //tmp = dongle_cia_read (0, reg, tmp);
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE001 R %02X %s\n'), tmp, debuginfo(0));
+ return tmp;
+ case 1:
+/*#ifdef PARALLEL_PORT
+ if (isprinter () > 0) {
+ tmp = ciaaprb;
+ } else if (isprinter () < 0) {
+ uae_u8 v;
+ parallel_direct_read_data (&v);
+ tmp = v;
+ } else if (currprefs.win32_samplersoundcard >= 0) {
+ tmp = sampler_getsample ((ciabpra & 4) ? 1 : 0);
+ } else
+#endif*/
+ {
+ tmp = handle_parport_joystick(0, ciaaprb, ciaadrb);
+ //tmp = dongle_cia_read (1, reg, tmp);
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE101 R %02X %s\n'), tmp, debuginfo(0));
+ }
+ if (ciaacrb & 2) {
+ var pb7 = 0;
+ if (ciaacrb & 4)
+ pb7 = ciaacrb & 1;
+ tmp &= ~0x80;
+ tmp |= pb7 ? 0x80 : 0;
+ }
+ if (ciaacra & 2) {
+ var pb6 = 0;
+ if (ciaacra & 4)
+ pb6 = ciaacra & 1;
+ tmp &= ~0x40;
+ tmp |= pb6 ? 0x40 : 0;
+ }
+ return tmp;
+ case 2:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE201 R %02X %s\n'), ciaadra, debuginfo(0));
+ return ciaadra;
+ case 3:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE301 R %02X %s\n'), ciaadrb, debuginfo(0));
+ return ciaadrb;
+ case 4:
+ return (ciaata - ciaata_passed) & 0xff;
+ case 5:
+ return ((ciaata - ciaata_passed) >> 8) & 0xff;
+ case 6:
+ return (ciaatb - ciaatb_passed) & 0xff;
+ case 7:
+ return ((ciaatb - ciaatb_passed) >> 8) & 0xff;
+ case 8:
+ if (ciaatlatch) {
+ ciaatlatch = 0;
+ return ciaatol & 0xff;
+ } else
+ return ciaatod & 0xff;
+ case 9:
+ if (ciaatlatch)
+ return (ciaatol >> 8) & 0xff;
else
- AMIGA.events.cycle(c);
+ return (ciaatod >> 8) & 0xff;
+ case 10:
+ if (!ciaatlatch) {
+ if (!(ciaacrb & 0x80))
+ ciaatlatch = 1;
+ ciaatol = ciaatod;
+ }
+ return (ciaatol >> 16) & 0xff;
+ case 12:
+ return ciaasdr;
+ case 13:
+ tmp = ciaaicr_reg;
+ ciaaicr &= ~ciaaicr_reg;
+ ciaaicr_reg = 0;
+ RethinkICRA();
+ return tmp;
+ case 14:
+ return ciaacra;
+ case 15:
+ return ciaacrb;
+ }
+ return 0;
+ }
+
+ function ReadCIAB(addr) {
+ var tmp;
+ var reg = addr & 15;
+
+ //if ((addr >= 8 && addr <= 10) || CIAB_DEBUG_R > 1) write_log (_T('R_CIAB: bfd%x00 %08X\n'), reg, M68K_GETPC);
+
+ compute_passed_time ();
+
+ switch (reg) {
+ case 0:
+ //if (currprefs.use_serial)
+ tmp = AMIGA.serial.readStatus(ciabdra);
+/*#ifdef PARALLEL_PORT
+ if (isprinter () > 0) {
+ //tmp |= ciabpra & (0x04 | 0x02 | 0x01);
+ tmp &= ~3; // clear BUSY and PAPEROUT
+ tmp |= 4; // set SELECT
+ } else if (isprinter () < 0) {
+ uae_u8 v;
+ parallel_direct_read_status (&v);
+ tmp |= v & 7;
+ } else
+#endif*/
+ {
+ tmp |= handle_parport_joystick(1, ciabpra, ciabdra);
+ //tmp = dongle_cia_read (1, reg, tmp);
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 R %02X %s\n'), tmp, debuginfo(0));
+ }
+ return tmp;
+ case 1:
+ 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) {
+ var pb7 = 0;
+ if (ciabcrb & 4)
+ pb7 = ciabcrb & 1;
+ tmp &= ~0x80;
+ tmp |= pb7 ? 0x80 : 00;
+ }
+ if (ciabcra & 2) {
+ var pb6 = 0;
+ if (ciabcra & 4)
+ pb6 = ciabcra & 1;
+ tmp &= ~0x40;
+ tmp |= pb6 ? 0x40 : 00;
+ }
+ return tmp;
+ case 2:
+ return ciabdra;
+ case 3:
+ return ciabdrb;
+ case 4:
+ return (ciabta - ciabta_passed) & 0xff;
+ case 5:
+ return ((ciabta - ciabta_passed) >> 8) & 0xff;
+ case 6:
+ return (ciabtb - ciabtb_passed) & 0xff;
+ case 7:
+ return ((ciabtb - ciabtb_passed) >> 8) & 0xff;
+ case 8:
+ if (ciabtlatch) {
+ ciabtlatch = 0;
+ return ciabtol & 0xff;
+ } else
+ return ciabtod & 0xff;
+ case 9:
+ if (ciabtlatch)
+ return (ciabtol >> 8) & 0xff;
+ else
+ return (ciabtod >> 8) & 0xff;
+ case 10:
+ if (!ciabtlatch) {
+ if (!(ciabcrb & 0x80))
+ ciabtlatch = 1;
+ ciabtol = ciabtod;
+ }
+ return (ciabtol >> 16) & 0xff;
+ case 12:
+ return ciabsdr;
+ case 13:
+ tmp = ciabicr_reg;
+ ciabicr &= ~ciabicr_reg;
+ ciabicr_reg = 0;
+ RethinkICRB();
+ return tmp;
+ case 14:
+ //write_log (_T('CIABCRA READ %d %x\n'), ciabcra, M68K_GETPC);
+ return ciabcra;
+ case 15:
+ return ciabcrb;
+ }
+ return 0;
+ }
+
+ function WriteCIAA(addr, val) {
+ var reg = addr & 15;
+
+ //if (CIAA_DEBUG_W) write_log (_T('W_CIAA: bfe%x01 %02X %08X\n'), reg, val, M68K_GETPC);
+
+ /*if (!currprefs.cs_ciaoverlay && oldovl) {
+ map_overlay (1);
+ oldovl = 0;
+ }*/
+ switch (reg) {
+ case 0:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE001 W %02X %s\n'), val, debuginfo(0));
+ ciaapra = (ciaapra & ~0xc3) | (val & 0xc3);
+ bfe001_change();
+ //handle_cd32_joystick_cia(ciaapra, ciaadra);
+ //dongle_cia_write (0, reg, val);
+ break;
+ case 1:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE101 W %02X %s\n'), val, debuginfo(0));
+ ciaaprb = val;
+ //dongle_cia_write (0, reg, val);
+/*#ifdef PARALLEL_PORT
+ if (isprinter() > 0) {
+ doprinter (val);
+ this.parallelack();
+ } else if (isprinter() < 0) {
+ parallel_direct_write_data (val, ciaadrb);
+ this.parallelack();
+ }
+#endif*/
+ break;
+ case 2:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE201 W %02X %s\n'), val, debuginfo(0));
+ ciaadra = val;
+ //dongle_cia_write (0, reg, val);
+ bfe001_change();
+ break;
+ case 3:
+ ciaadrb = val;
+ //dongle_cia_write (0, reg, val);
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFE301 W %02X %s\n'), val, debuginfo(0));
+ break;
+ case 4:
+ CIA_update();
+ ciaala = (ciaala & 0xff00) | val;
+ CIA_calctimers();
+ break;
+ case 5:
+ CIA_update();
+ ciaala = (ciaala & 0xff) | (val << 8);
+ if ((ciaacra & 1) == 0)
+ ciaata = ciaala;
+ if (ciaacra & 8) {
+ ciaata = ciaala;
+ ciaacra |= 1;
+ ciaastarta = CIASTARTCYCLESHI;
+ }
+ CIA_calctimers();
+ break;
+ case 6:
+ CIA_update();
+ ciaalb = (ciaalb & 0xff00) | val;
+ CIA_calctimers();
+ break;
+ case 7:
+ CIA_update();
+ ciaalb = (ciaalb & 0xff) | (val << 8);
+ if ((ciaacrb & 1) == 0)
+ ciaatb = ciaalb;
+ if (ciaacrb & 8) {
+ ciaatb = ciaalb;
+ ciaacrb |= 1;
+ ciaastartb = CIASTARTCYCLESHI;
+ }
+ CIA_calctimers();
+ break;
+ case 8:
+ if (ciaacrb & 0x80) {
+ ciaaalarm = (ciaaalarm & ~0xff) | val;
+ } else {
+ ciaatod = (ciaatod & ~0xff) | val;
+ ciaatodon = 1;
+ ciaa_checkalarm(0);
+ }
+ break;
+ case 9:
+ if (ciaacrb & 0x80) {
+ ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
+ } else {
+ ciaatod = (ciaatod & ~0xff00) | (val << 8);
+ }
+ break;
+ case 10:
+ if (ciaacrb & 0x80) {
+ ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
+ } else {
+ ciaatod = (ciaatod & ~0xff0000) | (val << 16);
+ ciaatodon = 0;
+ }
+ break;
+ case 12:
+ CIA_update();
+ ciaasdr = val;
+ if ((ciaacra & 0x41) == 0x41 && ciaasdr_cnt == 0)
+ ciaasdr_cnt = 8 * 2;
+ CIA_calctimers();
+ break;
+ case 13:
+ setclra(val);
+ break;
+ case 14:
+ CIA_update();
+ val &= 0x7f; /* bit 7 is unused */
+ if ((val & 1) && !(ciaacra & 1))
+ ciaastarta = CIASTARTCYCLESCRA;
+ if ((val & 0x40) == 0 && (ciaacra & 0x40) != 0) {
+ AMIGA.input.keyboard.lostsynccnt = 0;
+ //if (KB_DEBUG) BUG.info('KB_ACK %02x->%02x', ciaacra, val);
+ }
+ ciaacra = val;
+ if (ciaacra & 0x10) {
+ ciaacra &= ~0x10;
+ ciaata = ciaala;
+ }
+ CIA_calctimers();
+ break;
+ case 15:
+ CIA_update();
+ if ((val & 1) && !(ciaacrb & 1))
+ ciaastartb = CIASTARTCYCLESCRA;
+ ciaacrb = val;
+ if (ciaacrb & 0x10) {
+ ciaacrb &= ~0x10;
+ ciaatb = ciaalb;
+ }
+ CIA_calctimers();
+ break;
}
}
- this.load8 = function (addr) {
- var v, r = (addr & 0xf00) >> 8;
+ function WriteCIAB(addr, val) {
+ var reg = addr & 15;
- this.waitPre();
+ //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));
+ //dongle_cia_write (1, reg, val);
+ ciabpra = val;
+ //if (currprefs.use_serial)
+ AMIGA.serial.writeStatus(ciabpra, ciabdra);
+/*#ifdef PARALLEL_PORT
+ if (isprinter () < 0)
+ parallel_direct_write_status (val, ciabdra);
+#endif*/
+ break;
+ case 1:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 W %02X %s\n'), val, debuginfo(0));
+ //dongle_cia_write (1, reg, val);
+ ciabprb = val;
+ AMIGA.disk.select(val);
+ break;
+ case 2:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD200 W %02X %s\n'), val, debuginfo(0));
+ //dongle_cia_write (1, reg, val);
+ ciabdra = val;
+ //if (currprefs.use_serial)
+ AMIGA.serial.writeStatus(ciabpra, ciabdra);
+ break;
+ case 3:
+ //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD300 W %02X %s\n'), val, debuginfo(0));
+ //dongle_cia_write (1, reg, val);
+ ciabdrb = val;
+ break;
+ case 4:
+ CIA_update();
+ ciabla = (ciabla & 0xff00) | val;
+ CIA_calctimers();
+ break;
+ case 5:
+ CIA_update();
+ ciabla = (ciabla & 0xff) | (val << 8);
+ if ((ciabcra & 1) == 0)
+ ciabta = ciabla;
+ if (ciabcra & 8) {
+ ciabta = ciabla;
+ ciabcra |= 1;
+ ciabstarta = CIASTARTCYCLESHI;
+ }
+ CIA_calctimers();
+ break;
+ case 6:
+ CIA_update();
+ ciablb = (ciablb & 0xff00) | val;
+ CIA_calctimers();
+ break;
+ case 7:
+ CIA_update();
+ ciablb = (ciablb & 0xff) | (val << 8);
+ if ((ciabcrb & 1) == 0)
+ ciabtb = ciablb;
+ if (ciabcrb & 8) {
+ ciabtb = ciablb;
+ ciabcrb |= 1;
+ ciabstartb = CIASTARTCYCLESHI;
+ }
+ CIA_calctimers();
+ break;
+ case 8:
+ if (ciabcrb & 0x80) {
+ ciabalarm = (ciabalarm & ~0xff) | val;
+ } else {
+ ciabtod = (ciabtod & ~0xff) | val;
+ ciabtodon = 1;
+ ciab_checkalarm (0);
+ }
+ break;
+ case 9:
+ if (ciabcrb & 0x80) {
+ ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
+ } else {
+ ciabtod = (ciabtod & ~0xff00) | (val << 8);
+ }
+ break;
+ case 10:
+ if (ciabcrb & 0x80) {
+ ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
+ } else {
+ ciabtod = (ciabtod & ~0xff0000) | (val << 16);
+ ciabtodon = 0;
+ }
+ break;
+ case 12:
+ CIA_update();
+ ciabsdr = val;
+ if ((ciabcra & 0x40) == 0)
+ ciabsdr_cnt = 0;
+ if ((ciabcra & 0x41) == 0x41 && ciabsdr_cnt == 0)
+ ciabsdr_cnt = 8 * 2;
+ CIA_calctimers();
+ break;
+ case 13:
+ setclrb(val);
+ break;
+ case 14:
+ CIA_update();
+ val &= 0x7f; /* bit 7 is unused */
+ if ((val & 1) && !(ciabcra & 1))
+ ciabstarta = CIASTARTCYCLESCRA;
+ ciabcra = val;
+ if (ciabcra & 0x10) {
+ ciabcra &= ~0x10;
+ ciabta = ciabla;
+ }
+ CIA_calctimers();
+ break;
+ case 15:
+ CIA_update();
+ if ((val & 1) && !(ciabcrb & 1))
+ ciabstartb = CIASTARTCYCLESCRA;
+ ciabcrb = val;
+ if (ciabcrb & 0x10) {
+ ciabcrb &= ~0x10;
+ ciabtb = ciablb;
+ }
+ CIA_calctimers();
+ break;
+ }
+ }
+
+ 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;
+
+ //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);
+
+ //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
+ function issinglecia() {
+ return false; //currprefs.cs_ide || currprefs.cs_pcmcia || currprefs.cs_mbdmac;
+ }
+ function isgayle() {
+ return false; //currprefs.cs_ide || currprefs.cs_pcmcia;
+ }
+
+ function cia_wait_pre() {
+ if (!CUSTOM_SIMPLE) {
+ var div = (AMIGA.events.currcycle - AMIGA.events.eventtab[EV_CIA].oldcycles) % DIV10;
+ var tmp = Math.floor(DIV10 * ECLOCK_DATA_CYCLE / 10);
+ var cycles;
+
+ if (div >= tmp)
+ cycles = DIV10 - div + tmp;
+ else if (div)
+ cycles = DIV10 + tmp - div;
+ else
+ cycles = tmp - div;
+
+ if (cycles)
+ AMIGA.events.cycle(cycles);
+ }
+ }
+
+ function cia_wait_post(value) {
+ AMIGA.events.cycle(6 * CYCLE_UNIT / 2);
+ }
+
+ function isgaylenocia(addr) {
+ // gayle CIA region is only 4096 bytes at 0xbfd000 and 0xbfe000
+ if (!isgayle())
+ return true;
+ var mask = addr & 0xf000;
+ return mask == 0xe000 || mask == 0xd000;
+ }
+
+ this.load8 = function(addr) {
+ var r = (addr & 0xf00) >> 8;
+ var v = 0xff;
+
+ if (!isgaylenocia(addr))
+ return v;
+
+ cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
- v = (addr & 1) ? this.A.read(r) : this.B.read(r);
+ if (!issinglecia())
+ v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
break;
case 1:
- v = (addr & 1) ? 0xff : this.B.read(r);
+ v = (addr & 1) ? 0xff : ReadCIAB(r);
break;
case 2:
- v = (addr & 1) ? this.A.read(r) : 0xff;
+ v = (addr & 1) ? ReadCIAA(r) : 0xff;
break;
case 3: {
- v = 0xff;
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
- BUG.info('CIA.load8() unknown CIA address $%08x', addr);
+ if (warned > 0) {
+ BUG.info('cia_bget: unknown CIA address %x', addr);
+ warned--;
+ }
break;
}
}
- this.waitPost();
+ cia_wait_post(v);
return v;
}
- this.load16 = function (addr) {
- var v, r = (addr & 0xf00) >> 8;
+ this.load16 = function(addr) {
+ var r = (addr & 0xf00) >> 8;
+ var v = 0xffff;
- this.waitPre();
+ if (!isgaylenocia(addr))
+ return v;
+
+ cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
- v = (this.B.read(r) << 8) | this.A.read(r);
+ if (!issinglecia())
+ v = (ReadCIAB(r) << 8) | ReadCIAA(r);
break;
case 1:
- v = (this.B.read(r) << 8) | 0xff;
+ v = (ReadCIAB(r) << 8) | 0xff;
break;
case 2:
- v = (0xff << 8) | this.A.read(r);
+ v = (0xff << 8) | ReadCIAA(r);
break;
case 3: {
- v = 0xffff;
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
- BUG.info('CIA.load16() unknown CIA address $%08x', addr);
+ if (warned > 0) {
+ BUG.info('cia_wget: unknown CIA address %x', addr);
+ warned--;
+ }
break;
}
}
- this.waitPost();
+ cia_wait_post(v);
return v;
}
- this.load32 = function (addr) {
- return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 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;
- this.waitPre();
- if ((addr & 0x3000) != 0) {
- if ((addr & 0x2000) == 0) this.B.write(r, value);
- if ((addr & 0x1000) == 0) this.A.write(r, value);
+ 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--;
+ }
}
- this.waitPost();
+ cia_wait_post(value);
}
this.store16 = function (addr, value) {
var r = (addr & 0xf00) >> 8;
- this.waitPre();
- if ((addr & 0x3000) != 0) {
- if ((addr & 0x2000) == 0) this.B.write(r, value >> 8);
- if ((addr & 0x1000) == 0) this.A.write(r, value & 0xff);
+ 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--;
+ }
}
- this.waitPost();
+ cia_wait_post(value);
}
this.store32 = function (addr, value) {
- this.store16(addr, value >>> 16);
+ this.store16(addr, value >> 16);
this.store16(addr + 2, value & 0xffff);
}
}
diff --git a/sae/config.js b/sae/config.js
index c501f38..87deb45 100644
--- a/sae/config.js
+++ b/sae/config.js
@@ -12,23 +12,22 @@ function Config() {
this.init = false;
this.cpu = {
- model: 68000,
- speed: 0, /* 0 if cpu.exact */
- exact: false,
- compatible: true
+ model: 0,
+ speed: 0,
+ compatible: false
};
this.blitter = {
- exact: false, /* do not change */
- immediate: false, /* false if blitter.exact */
- waiting: 1 /* 0 if cpu.exact or blitter.immediate */
+ immediate: false,
+ waiting: 0
};
this.chipset = {
- type: 0,
- agnus: 0,
+ mask: 0,
+ agnus_dip: 0,
agnus_rev: 0,
- denise: 0,
- paula: 0,
- colLevel: 0
+ denise_rev: 0,
+ collision_level: 0,
+ genlock: false,
+ refreshrate: 0
};
this.ram = {
chip: {
@@ -71,17 +70,25 @@ function Config() {
speed:0
};
this.video = {
+ id: '',
enabled: false,
scale: false,
- ntsc: false,
- skip: false,
- id: ''
+ ntsc: false, //~
+ framerate: 0,
+ hresolution: 0,
+ vresolution: 0,
+ scandoubler: false,
+ scanlines: false,
+ extrawidth: 0,
+ xcenter: 0,
+ ycenter: 0
};
this.audio = {
enabled: false,
mode:0,
channels: 0,
- rate: 0
+ rate: 0,
+ filter: false
};
this.ports = [{
type: 0,
@@ -102,6 +109,10 @@ function Config() {
this.rtc = {
type: 0
};
+ this.cia = {
+ tod: 0,
+ tod_hack: 0
+ };
this.hooks = {
error: null,
power_led: null,
@@ -110,79 +121,94 @@ function Config() {
fps: null,
cpu: null
};
-}
-function configSetDefaults(c) {
- c.init = true;
+ function configSetDefaults(c) {
+ c.init = true;
- c.cpu.speed = SAEV_Config_CPU_Speed_Original;
+ c.cpu.model = 68000;
+ c.cpu.speed = SAEV_Config_CPU_Speed_Original;
+ c.cpu.compatible = false;
- c.chipset.type = SAEV_Config_Chipset_Type_OCS;
- if (c.chipset.type == SAEV_Config_Chipset_Type_OCS) {
- c.chipset.agnus = c.video.ntsc ? AGNUS_8370 : AGNUS_8371;
- c.chipset.agnus_rev = 0;
- c.chipset.denise = DENISE_8362;
- } else if (c.chipset.type == SAEV_Config_Chipset_Type_ECS) {
- c.chipset.agnus = AGNUS_8372;
- c.chipset.agnus_rev = 5;
- c.chipset.denise = DENISE_8373;
+ //c.chipset.mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
+ //c.chipset.mask = CSMASK_ECS_AGNUS;
+ c.chipset.mask = 0;
+ c.chipset.agnus_dip = false; /* A1000 */
+ c.chipset.agnus_rev = -1;
+ c.chipset.denise_rev = -1;
+ c.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None;
+ c.chipset.genlock = false;
+ c.chipset.refreshrate = -1;
+
+ c.blitter.immediate = 0 ? true : false;
+ c.blitter.waiting = 1; /* 0 if blitter.immediate */
+
+ c.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K;
+ c.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K;
+ c.ram.fast.size = SAEV_Config_RAM_Fast_Size_1M;
+
+ c.rom.size = SAEV_Config_ROM_Size_None;
+ c.rom.data = null;
+ c.ext.addr = SAEV_Config_EXT_Addr_E0;
+ c.ext.size = SAEV_Config_EXT_Size_None;
+ c.ext.data = null;
+
+ c.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD;
+ c.floppy.drive[0].name = null;
+ c.floppy.drive[0].data = null;
+ c.floppy.drive[1].type = SAEV_Config_Floppy_Type_35_DD;
+ c.floppy.drive[1].name = null;
+ c.floppy.drive[1].data = null;
+ c.floppy.drive[2].type = SAEV_Config_Floppy_Type_None;
+ c.floppy.drive[2].name = null;
+ c.floppy.drive[2].data = null;
+ c.floppy.drive[3].type = SAEV_Config_Floppy_Type_None;
+ c.floppy.drive[3].name = null;
+ c.floppy.drive[3].data = null;
+ c.floppy.speed = SAEV_Config_Floppy_Speed_Original;
+
+ c.video.id = 'video';
+ c.video.enabled = true;
+ c.video.scale = false;
+ c.video.ntsc = false;
+ c.video.framerate = 2;
+ c.video.hresolution = 1 ? RES_HIRES : RES_LORES;
+ c.video.vresolution = 1 ? VRES_DOUBLE : VRES_NONDOUBLE;
+ c.video.scandoubler = 0 ? true : false;
+ c.video.scanlines = 0 ? true : false;
+ c.video.extrawidth = 0;
+ c.video.xcenter = 0;
+ c.video.ycenter = 0
+
+ c.audio.enabled = true;
+ //c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
+ c.audio.mode = SAEV_Config_Audio_Mode_Play;
+ c.audio.channels = SAEV_Config_Audio_Channels_Stereo;
+ c.audio.rate = SAEV_Config_Audio_Rate_44100;
+ c.audio.filter = false;
+
+ c.ports[0].type = SAEV_Config_Ports_Type_Mouse;
+ c.ports[0].move = SAEV_Config_Ports_Move_WASD;
+ c.ports[0].fire[0] = 49;
+ c.ports[0].fire[1] = 50;
+ c.ports[1].type = SAEV_Config_Ports_Type_Joy1;
+ c.ports[1].move = SAEV_Config_Ports_Move_Arrows;
+ c.ports[1].fire[0] = 16;
+ c.ports[1].fire[1] = 17;
+
+ c.keyboard.enabled = true;
+ c.keyboard.mapShift = false;
+
+ c.rtc.type = 1 ? SAEV_Config_RTC_Type_MSM6242B : SAEV_Config_RTC_Type_RF5C01A;
+
+ 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.cpu = function(usage) {}
}
- c.chipset.paula = PAULA_8364;
- c.chipset.colLevel = SAEV_Config_Chipset_ColLevel_None;
-
- c.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K;
- c.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K;
- c.ram.fast.size = SAEV_Config_RAM_Fast_Size_512K;
-
- c.rom.size = SAEV_Config_ROM_Size_None;
- c.rom.data = null;
- c.ext.addr = SAEV_Config_EXT_Addr_E0;
- c.ext.size = SAEV_Config_EXT_Size_None;
- c.ext.data = null;
-
- c.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD;
- c.floppy.drive[0].name = null;
- c.floppy.drive[0].data = null;
- c.floppy.drive[1].type = SAEV_Config_Floppy_Type_35_DD;
- c.floppy.drive[1].name = null;
- c.floppy.drive[1].data = null;
- c.floppy.drive[2].type = SAEV_Config_Floppy_Type_None;
- c.floppy.drive[2].name = null;
- c.floppy.drive[2].data = null;
- c.floppy.drive[3].type = SAEV_Config_Floppy_Type_None;
- c.floppy.drive[3].name = null;
- c.floppy.drive[3].data = null;
- c.floppy.speed = SAEV_Config_Floppy_Speed_Original;
-
- c.video.enabled = true;
- c.video.scale = false;
- c.video.ntsc = false;
- c.video.skip = true;
- c.video.id = 'video';
-
- c.audio.enabled = true;
- c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
- c.audio.channels = SAEV_Config_Audio_Channels_Stereo;
- c.audio.rate = SAEV_Config_Audio_Rate_44100;
-
- c.ports[0].type = SAEV_Config_Ports_Type_Mouse;
- c.ports[0].move = SAEV_Config_Ports_Move_WASD;
- c.ports[0].fire[0] = 49;
- c.ports[0].fire[1] = 50;
- c.ports[1].type = SAEV_Config_Ports_Type_Joy1;
- c.ports[1].move = SAEV_Config_Ports_Move_Arrows;
- c.ports[1].fire[0] = 16;
- c.ports[1].fire[1] = 17;
-
- c.keyboard.enabled = true;
- c.keyboard.mapShift = false;
-
- c.rtc.type = 1 ? SAEV_Config_RTC_Type_MSM6242B : SAEV_Config_RTC_Type_RF5C01A;
-
- 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);
}
diff --git a/sae/constants.js b/sae/constants.js
index 56ce764..5e4407c 100644
--- a/sae/constants.js
+++ b/sae/constants.js
@@ -9,7 +9,7 @@
**************************************************************************/
const SAEV_Version = 0;
-const SAEV_Revision = 7;
+const SAEV_Revision = 8;
const SAEV_Revision_Sub = 0;
/*-----------------------------------------------------------------------*/
@@ -19,6 +19,15 @@ const SAEV_Null = null;
const SAEV_True = true;
const SAEV_False = false;
+/*-----------------------------------------------------------------------*/
+/* info */
+
+const SAEI_Audio_Webkit = 1;
+const SAEI_Audio_Mozilla = 2;
+
+const SAEI_Video_Canvas2D = 1;
+const SAEI_Video_WebGL = 2;
+
/*-----------------------------------------------------------------------*/
/* cpu */
@@ -29,11 +38,18 @@ const SAEV_Config_CPU_Speed_Original = 0;
/* chipset */
const SAEV_Config_Chipset_Type_OCS = 1;
-const SAEV_Config_Chipset_Type_ECS = 2;
+const SAEV_Config_Chipset_Type_ECS_AGNUS = 2;
+const SAEV_Config_Chipset_Type_ECS_DENISE = 3;
+
+const SAEV_Config_Chipset_Mask_OCS = 0;
+const SAEV_Config_Chipset_Mask_ECS_AGNUS = 1;
+const SAEV_Config_Chipset_Mask_ECS_DENISE = 1 | 2;
+
const SAEV_Config_Chipset_ColLevel_None = 0;
const SAEV_Config_Chipset_ColLevel_Sprite_Sprite = 1;
const SAEV_Config_Chipset_ColLevel_Sprite_Playfield = 2;
+const SAEV_Config_Chipset_ColLevel_Full = 3;
/*-----------------------------------------------------------------------*/
/* ram */
@@ -158,10 +174,10 @@ var BUG = null;
var AMIGA = null;
-const CMD_STOP = 0;
-const CMD_CYCLE = 1;
-const CMD_PAUSE = 2;
-const CMD_IDLE = 3;
+const ST_STOP = 0;
+const ST_CYCLE = 1;
+const ST_PAUSE = 2;
+const ST_IDLE = 3;
/*-----------------------------------------------------------------------*/
/* events */
@@ -171,51 +187,18 @@ const EV_AUDIO = 1;
const EV_MISC = 2;
const EV_HSYNC = 3;
const EV_MAX = 4;
-//const EV_COPPER = ;
-//const EV_BLITTER = ;
-//const EV_RENDER = ;
const EV2_BLITTER = 0;
const EV2_DISK = 1;
-const EV2_MISC = 2;
-const EV2_MAX = 12;
+const EV2_DMAL = 2;
+const EV2_MISC = 3;
+const EV2_MAX = 3 + 10;
const CYCLE_UNIT = 512;
const CYCLE_UNIT_INV = 1.0 / CYCLE_UNIT; /* mul is always faster than div */
const CYCLE_MAX = 0xffffffff * CYCLE_UNIT;
-/*-----------------------------------------------------------------------*/
-/* cia */
-
-const CIA_A = 1;
-const CIA_B = 2;
-
-const ECLOCK_DATA_CYCLE = 4;
-const ECLOCK_WAIT_CYCLE = 6;
-
-const DIV10 = ((ECLOCK_DATA_CYCLE + ECLOCK_WAIT_CYCLE) * CYCLE_UNIT) >> 1;
-
-const CIA_RETHINK_DELAY = (CYCLE_UNIT << 1) + (CYCLE_UNIT >> 1);
-
-/*-----------------------------------------------------------------------*/
-/* config */
-
-//OCS
-const AGNUS_8361 = 1; /* Amiga 1000 NTSC */
-const AGNUS_8367 = 2; /* Amiga 1000 PAL */
-const AGNUS_8370 = 3; /* OCS NTSC */
-const AGNUS_8371 = 4; /* OCS PAL */
-//ECS
-const AGNUS_8372 = 5; /* ECS */
-//AGA
-const AGNUS_8374 = 6; /* AGA */
-
-const DENISE_8362 = 1; /* OCS */
-const DENISE_8373 = 2; /* ECS */
-
-const PAULA_8364 = 1;
-
/*-----------------------------------------------------------------------*/
/* cpu */
@@ -227,9 +210,7 @@ const SPCFLAG_TRACE = 64;
const SPCFLAG_DOTRACE = 128;
const SPCFLAG_DOINT = 256;
const SPCFLAG_BLTNASTY = 512;
-//const SPCFLAG_EXEC = 1024;
-//const SPCFLAG_ACTION_REPLAY = 2048;
-//const SPCFLAG_TRAP = 4096;
+const SPCFLAG_TRAP = 1024;
/*-----------------------------------------------------------------------*/
/* amiga */
@@ -272,25 +253,9 @@ const DMAF_SETCLR = 1 << 15;
const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT;
-/*-----------------------------------------------------------------------*/
-/* copper */
-
-/*const COP_STOP = 0;
-const COP_READ = 1;
-const COP_MOVE = 2;
-const COP_WAIT = 3;
-const COP_SKIP = 4;*/
-
/*-----------------------------------------------------------------------*/
/* blitter */
-/*const BLT_STOP = 0;
-const BLT_INIT = 1;
-const BLT_READ = 2;
-const BLT_WORK = 3;
-const BLT_WRITE = 4;
-const BLT_NEXT = 5;*/
-
const BLT_done = 0;
const BLT_init = 1;
const BLT_read = 2;
@@ -302,16 +267,124 @@ const BLT_next = 5;
/* video */
const VIDEO_WIDTH = 720; /* == 360*2 */
-const VIDEO_HEIGHT = 576; /* == 288*2 */
-
-/*-----------------------------------------------------------------------*/
-/* playfield */
-
-const MAX_FRAMESKIP_COUNT = 4;
+const VIDEO_HEIGHT = 568; /* == 284*2 */
+const VIDEO_DEPTH = 32;
/*-----------------------------------------------------------------------*/
/* audio */
const PERIOD_MIN = 4;
const PERIOD_MIN_NONCE = 60;
-const PERIOD_MAX = 0xffffffff;
+const PERIOD_MAX = 0xffffffff * CYCLE_UNIT;
+
+/*-----------------------------------------------------------------------*/
+/* playfield, sprites */
+
+const CUSTOM_SIMPLE = 0;
+const SMART_UPDATE = 0;
+
+const MAXHPOS = 227;
+const MAXHPOS_PAL = 227;
+const MAXHPOS_NTSC = 227;
+const MAXVPOS = 312;
+const MAXVPOS_PAL = 312;
+const MAXVPOS_NTSC = 262;
+const VBLANK_ENDLINE_PAL = 26;
+const VBLANK_ENDLINE_NTSC = 21;
+const VBLANK_SPRITE_PAL = 25;
+const VBLANK_SPRITE_NTSC = 20;
+const VBLANK_HZ_PAL = 50;
+const VBLANK_HZ_NTSC = 60;
+const EQU_ENDLINE_PAL = 8;
+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 CHIPSET_CLOCK_PAL = 3546895;
+const CHIPSET_CLOCK_NTSC = 3579545;
+
+const RES_LORES = 0;
+const RES_HIRES = 1;
+const RES_SUPERHIRES = 2;
+const RES_MAX = 2;
+
+const VRES_NONDOUBLE = 0;
+const VRES_DOUBLE = 1;
+const VRES_QUAD = 2;
+const VRES_MAX = 1;
+
+const DIW_WAITING_START = 0;
+const DIW_WAITING_STOP = 1;
+
+const LINE_UNDECIDED = 1;
+const LINE_DECIDED = 2;
+const LINE_DECIDED_DOUBLE = 3;
+const LINE_AS_PREVIOUS = 4;
+const LINE_BLACK = 5;
+const LINE_REMEMBERED_AS_BLACK = 6;
+const LINE_DONE = 7;
+const LINE_DONE_AS_PREVIOUS = 8;
+const LINE_REMEMBERED_AS_PREVIOUS = 9;
+
+const LOF_TOGGLES_NEEDED = 4;
+const NLACE_CNT_NEEDED = 50;
+
+const HARD_DDF_STOP = 0xd4;
+const HARD_DDF_START = 0x18;
+
+const MAX_PLANES = 6; /* 8 = AGA */
+
+const AMIGA_WIDTH_MAX = 752 / 2;
+const AMIGA_HEIGHT_MAX = 574 / 2;
+
+const DIW_DDF_OFFSET = 1;
+const HBLANK_OFFSET = 9;
+const DISPLAY_LEFT_SHIFT = 0x38;
+
+const NLN_NORMAL = 0;
+const NLN_DOUBLED = 1;
+const NLN_UPPER = 2;
+const NLN_LOWER = 3;
+const NLN_NBLACK = 4;
+
+const PLF_IDLE = 0;
+const PLF_START = 1;
+const PLF_ACTIVE = 2;
+const PLF_PASSED_STOP = 3;
+const PLF_PASSED_STOP2 = 4;
+const PLF_END = 5;
+
+const FETCH_NOT_STARTED = 0;
+const FETCH_STARTED = 1;
+const FETCH_WAS_PLANE0 = 2;
+
+const COLOR_TABLE_SIZE = (MAXVPOS + 2) * 2;
+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 AUTOSCALE_SPRITES = 1;
+//const SPRBORDER = 0;
+
+const MAX_PIXELS_PER_LINE = 1760;
+
+const MAX_SPR_PIXELS = (((MAXVPOS + 1) * 2 + 1) * MAX_PIXELS_PER_LINE);
+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;
+const FAST_COLORS = 0;
diff --git a/sae/copper.js b/sae/copper.js
index 2bf28e3..d2d630c 100644
--- a/sae/copper.js
+++ b/sae/copper.js
@@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes: Ported from WinUAE 2.5.0
+*
**************************************************************************/
//copper_states
@@ -27,11 +30,31 @@ const COP_strobe_extra = 14;
const COP_start_delay = 15;
function Copper() {
+ const customdelay = [
+ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */
+ 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 0xa0 - 0xde */
+ /* BPLxPTH/BPLxPTL */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
+ /* BPLCON0-3,BPLMOD1-2 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
+ /* SPRxPTH/SPRxPTL */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
+ /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ /* COLORxx */
+ 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,
+ /* RESERVED */
+ 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.copcon = 0;
this.enabled_thisline = false;
this.access = false;
+ this.last_copper_hpos = 0;
var cop_state = {
/* The current instruction words. */
@@ -48,8 +71,6 @@ function Copper() {
last_write:0, last_write_hpos:0,
moveaddr:0, movedata:0, movedelay:0
};
- var last_copper_hpos = 0;
-
this.reset = function () {
this.copcon = 0;
@@ -59,7 +80,7 @@ function Copper() {
this.reset2 = function () {
cop_state.hpos = 0;
cop_state.last_write = 0;
- this.compute_spcflag_copper(AMIGA.events.maxhpos);
+ this.compute_spcflag_copper(AMIGA.playfield.maxhpos);
}
this.COPCON = function (v) {
@@ -96,18 +117,18 @@ function Copper() {
//BUG.info('COPJMP(%d) %d', num, cop_state.state);
- cop_state.vpos = AMIGA.events.vpos;
- cop_state.hpos = AMIGA.events.hpos() & ~1;
- this.enabled_thisline = false;
+ 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.events.hpos());
+ 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;
@@ -126,7 +147,7 @@ function Copper() {
this.test_copper_dangerous = function (address) {
var addr = address & 0x1fe;
- if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) ? 0 : 0x40) : 0x80)) {
+ 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);
@@ -140,11 +161,11 @@ function Copper() {
var oldpos = 0;
cop_state.state = COP_stop;
- cop_state.vpos = AMIGA.events.vpos;
- cop_state.hpos = AMIGA.events.hpos() & ~1;
+ 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.events.maxvpos << 5)) {
+ while (pos < (AMIGA.playfield.maxvpos << 5)) {
if (oldpos > pos)
pos = oldpos;
if (!AMIGA.dmaen(DMAF_COPEN))
@@ -153,8 +174,11 @@ function Copper() {
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.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;
@@ -181,25 +205,18 @@ function Copper() {
}
this.copper_cant_read = function (hpos, alloc) {
- //BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.events.maxhpos);
- if (hpos + 1 >= AMIGA.events.maxhpos) // first refresh slot
+ //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.events.maxhpos - 3) && (AMIGA.events.maxhpos & 1) && alloc >= 0) {
- //if (alloc) alloc_cycle (hpos, CYCLE_COPPER);
+ if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) {
return -1;
}
return AMIGA.playfield.is_bitplane_dma(hpos);
}
- /*this.copper_cant_read = function (hpos, alloc) {
- var cant = this.copper_cant_read2(hpos, alloc);
- //if (cant && debug_dma) record_dma_event (DMA_EVENT_COPPERWANTED, hpos, vpos);
- return cant;
- }*/
-
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.events.vpos, AMIGA.events.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos);
+ //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);
@@ -209,44 +226,17 @@ function Copper() {
this.dump_copper = function (error, until_hpos) {
BUG.info('\n');
- BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.events.vpos, until_hpos, AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80));
+ 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');
}
- // 'emulate' chip internal delays, not the right place but fast and 99.9% programs
- // use only copper to write BPLCON1 etc.. (exception is HulkaMania/TSP..)
- // this table should be filled with zeros and done somewhere else..
- var customdelay = [
- 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */
- 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 0xa0 - 0xde */
- /* BPLxPTH/BPLxPTL */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
- /* BPLCON0-3,BPLMOD1-2 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
- /* SPRxPTH/SPRxPTL */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
- /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- /* COLORxx */
- 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,
- /* RESERVED */
- 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.copper_write = function (v) {
- this.custom_store16_copper(AMIGA.events.hpos(), v >> 16, v & 0xffff, 0);
- }*/
-
- this.update_copper = function (until_hpos) {
- var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
+ this.update = function (until_hpos) {
+ var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
var c_hpos = cop_state.hpos;
- //BUG.info('update_copper() 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);
@@ -256,11 +246,11 @@ function Copper() {
return;
}
- if (until_hpos <= last_copper_hpos)
+ if (until_hpos <= this.last_copper_hpos)
return;
- if (until_hpos > (AMIGA.events.maxhpos & ~1))
- until_hpos = AMIGA.events.maxhpos & ~1;
+ if (until_hpos > (AMIGA.playfield.maxhpos & ~1))
+ until_hpos = AMIGA.playfield.maxhpos & ~1;
for (;;) {
var old_hpos = c_hpos;
@@ -270,8 +260,8 @@ function Copper() {
break;
/* So we know about the fetch state. */
- //decide_line (c_hpos);
- //decide_fetch (c_hpos);
+ AMIGA.playfield.decide_line(c_hpos);
+ AMIGA.playfield.decide_fetch(c_hpos);
if (cop_state.movedelay > 0) {
cop_state.movedelay--;
@@ -280,7 +270,7 @@ function Copper() {
}
}
- if ((c_hpos == AMIGA.events.maxhpos - 3) && (AMIGA.events.maxhpos & 1))
+ if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1))
c_hpos += 1;
else
c_hpos += 2;
@@ -309,8 +299,6 @@ function Copper() {
if (this.copper_cant_read(old_hpos, 1))
continue;
cop_state.state = COP_strobe_delay2;
- //alloc_cycle(old_hpos, CYCLE_COPPER);
- //if (debug_dma) record_dma (0x8c, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
cop_state.ip += 2;
break;
}
@@ -318,10 +306,6 @@ function Copper() {
// 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.
- /*if (this.copper_cant_read(old_hpos, 1)) {
- alloc_cycle (old_hpos, CYCLE_COPPER);
- if (debug_dma) record_dma (0x1fe, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
- }*/
cop_state.state = COP_read1;
// Next cycle finally reads from new pointer
if (cop_state.strobe == 1)
@@ -343,8 +327,6 @@ function Copper() {
// but is not allocated, blitter or cpu can still use it.
if (this.copper_cant_read(old_hpos, 1))
continue;
- //cycle_line[old_hpos] |= CYCLE_COPPER_SPECIAL;
- //if (debug_dma) record_dma (0x1fe, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
cop_state.state = COP_read1;
// Next cycle finally reads from new pointer
if (cop_state.strobe == 1)
@@ -358,8 +340,6 @@ function Copper() {
if (this.copper_cant_read(old_hpos, 1))
continue;
cop_state.state = COP_read1;
- //alloc_cycle(old_hpos, CYCLE_COPPER);
- //if (debug_dma) record_dma (0x1fe, 0, 0xffffffff, old_hpos, vpos, DMARECORD_COPPER);
cop_state.ip = this.cop1lc;
break;
}
@@ -374,9 +354,8 @@ function Copper() {
clr_special(SPCFLAG_COPPER);
return;
}
- cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
- //alloc_cycle(old_hpos, CYCLE_COPPER);
- //if (debug_dma) record_dma (0x8c, cop_state.i1, cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
+ //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;
@@ -384,8 +363,8 @@ function Copper() {
case COP_read2: {
if (this.copper_cant_read(old_hpos, 1))
continue;
- cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip);
- //alloc_cycle(old_hpos, CYCLE_COPPER);
+ //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;
@@ -397,18 +376,16 @@ function Copper() {
cop_state.state = COP_skip_in2;
else
cop_state.state = COP_wait_in2;
- //if (debug_dma) record_dma (0x8c, cop_state.i2, cop_state.ip - 2, old_hpos, vpos, DMARECORD_COPPER);
} else { // MOVE
//uaecptr debugip = cop_state.ip;
var reg = cop_state.i1 & 0x1fe;
var data = cop_state.i2;
cop_state.state = COP_read1;
- //if (debug_dma) record_dma (reg, data, cop_state.ip - 2, old_hpos, vpos, DMARECORD_COPPER);
this.test_copper_dangerous(reg);
if (!this.enabled_thisline) {
//goto out; // was 'dangerous' register -> copper stopped
cop_state.hpos = c_hpos;
- last_copper_hpos = until_hpos;
+ this.last_copper_hpos = until_hpos;
return;
}
if (cop_state.ignore_next)
@@ -423,37 +400,41 @@ function Copper() {
cop_state.strobe = 2;
cop_state.state = COP_strobe_delay1;
} else {
- /*#if 0
- event2_newevent2 (1, (reg << 16) | data, copper_write);
- #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) do_sprites(hpos2);
+ /*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);
+ }
}
- //#endif
}
- //if (debug_copper && !cop_state.ignore_next) record_copper (debugip - 4, old_hpos, vpos);
cop_state.ignore_next = 0;
}
break;
}
case COP_wait1: {
- /*#if 0
- if (c_hpos >= (AMIGA.events.maxhpos & ~1) || (c_hpos & 1)) break;
- #endif*/
+/*#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);
- vp = AMIGA.events.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;
@@ -461,7 +442,7 @@ function Copper() {
clr_special(SPCFLAG_COPPER);
//goto out;
cop_state.hpos = c_hpos;
- last_copper_hpos = until_hpos;
+ this.last_copper_hpos = until_hpos;
return;
}
if (vp < cop_state.vcmp) {
@@ -469,7 +450,7 @@ function Copper() {
clr_special(SPCFLAG_COPPER);
//goto out;
cop_state.hpos = c_hpos;
- last_copper_hpos = until_hpos;
+ this.last_copper_hpos = until_hpos;
return;
}
}
@@ -488,7 +469,6 @@ function Copper() {
/* 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) {
- //decide_blitter (old_hpos);
if (AMIGA.blitter.getState() != BLT_done) {
//We need to wait for the blitter.
cop_state.state = COP_bltwait;
@@ -496,20 +476,17 @@ function Copper() {
clr_special(SPCFLAG_COPPER);
//goto out;
cop_state.hpos = c_hpos;
- last_copper_hpos = until_hpos;
+ this.last_copper_hpos = until_hpos;
return;
- } /*else {
- if (debug_dma) record_dma_event (DMA_EVENT_COPPERWAKE, old_hpos, vp);
- }*/
+ }
}
- //if (debug_copper) record_copper (cop_state.ip - 4, old_hpos, vpos);
cop_state.state = COP_read1;
break;
}
case COP_skip1: {
var vcmp, hcmp, vp1, hp1;
- if (c_hpos >= (AMIGA.events.maxhpos & ~1) || (c_hpos & 1))
+ if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1))
break;
if (this.copper_cant_read(old_hpos, 0))
@@ -517,14 +494,13 @@ function Copper() {
vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
- vp1 = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
+ 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;
cop_state.state = COP_read1;
- //if (debug_copper) record_copper (cop_state.ip - 4, old_hpos, vpos);
break;
}
}
@@ -532,7 +508,7 @@ function Copper() {
//out:
cop_state.hpos = c_hpos;
- last_copper_hpos = until_hpos;
+ this.last_copper_hpos = until_hpos;
}
this.compute_spcflag_copper = function (hpos) {
@@ -545,18 +521,19 @@ function Copper() {
return;
if (cop_state.state == COP_wait) {
- var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
+ 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.events.maxhpos) {
+ if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) {
hpos = (hpos + 2) & ~1;
- if (hpos > 226)
- hpos = 226;
+ 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,
@@ -575,40 +552,39 @@ function Copper() {
//BUG.info('blitter_done_notify() hpos %d', hpos);
- var vp = AMIGA.events.vpos;
+ var vp = AMIGA.playfield.vpos;
hpos += 3;
hpos &= ~1;
- if (hpos >= AMIGA.events.maxhpos) {
- hpos -= AMIGA.events.maxhpos;
+ if (hpos >= AMIGA.playfield.maxhpos) {
+ hpos -= AMIGA.playfield.maxhpos;
vp++;
}
cop_state.hpos = hpos;
cop_state.vpos = vp;
cop_state.state = COP_read1;
- //if (debug_dma) record_dma_event (DMA_EVENT_COPPERWAKE, hpos, vp);
- if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.events.vpos) {
+ if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) {
this.enabled_thisline = true;
set_special(SPCFLAG_COPPER);
}
}
this.cycle = function () {
- this.update_copper(AMIGA.events.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_copper(hpos);
+ this.update(hpos);
}
this.check = function (n) {
if (cop_state.state == COP_wait) {
- var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
+ var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
if (vp < cop_state.vcmp) {
if (this.enabled_thisline)
- BUG.info('COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d', n, vp, AMIGA.events.vpos, cop_state.vcmp, this.enabled_thisline?1:0);
+ 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);
}
}
}
diff --git a/sae/cpu.js b/sae/cpu.js
index a134762..30a58cf 100644
--- a/sae/cpu.js
+++ b/sae/cpu.js
@@ -6,18 +6,16 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
-**************************************************************************
+***************************************************************************
*
* TODO:
* - Faster versions of ASx/LSx/ROx/ROXx and xBCD
-* - Complete exception 2/3 handling
-* - Explode ADDQ,SUBQ
*
* Notes:
* - Based on M68000PRM.pdf
* - Written from scratch.
*
-*************************************************************************/
+**************************************************************************/
function CPU() {
const M_rdd = 1; /* Register Direct Data */
@@ -89,8 +87,10 @@ function CPU() {
const undef = false; /* use undef */
var regs = {
- d: [0, 0, 0, 0, 0, 0, 0, 0], /* Dn */
- a: [0, 0, 0, 0, 0, 0, 0, 0], /* An */
+ //d: [0, 0, 0, 0, 0, 0, 0, 0], /* Dn */
+ //a: [0, 0, 0, 0, 0, 0, 0, 0], /* An */
+ d: new Uint32Array(8),
+ a: new Uint32Array(8),
/* Status Register (SR) */
t: false,
s: false,
@@ -104,10 +104,7 @@ function CPU() {
usp: 0, /* User Stack Ptr (USP) */
isp: 0, /* Interrupt Stack Ptr (ISP) */
pc: 0, /* Program Counter (PC) */
- /* Interrupts */
- ipl:0,
- ipl_pin:0,
- stopped:true
+ stopped:true
};
var fault = {
op: 0,
@@ -116,8 +113,9 @@ function CPU() {
ia: false
};
var iTab = null;
- var doDiss = 0;
-
+ var cpu_cycle_unit = CYCLE_UNIT / 2;
+ var cpu_cycles = 4 * cpu_cycle_unit;
+
/*-----------------------------------------------------------------------*/
this.setup = function() {
@@ -141,11 +139,8 @@ function CPU() {
regs.isp = 0;
regs.a[7] = AMIGA.mem.load32(addr);
regs.pc = AMIGA.mem.load32(addr + 4);
- regs.ipl = regs.ipl_pin = 0;
regs.stopped = false;
- doDiss = 0;
-
BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc));
}
@@ -225,6 +220,13 @@ function CPU() {
}
}
+ function nextOPCode() {
+ var op = AMIGA.mem.load16(regs.pc);
+ fault.pc = regs.pc;
+ fault.op = op;
+ regs.pc += 2;
+ return op;
+ }
function nextIWord() {
var r = AMIGA.mem.load16(regs.pc);
regs.pc += 2;
@@ -249,7 +251,7 @@ function CPU() {
return add32(add32(base, disp), reg);
}
}
-
+
function exEA(ea, z) {
var dp;
@@ -257,23 +259,18 @@ function CPU() {
case M_rdd:
ea.a = ea.r;
ea.t = T_RD;
- //ea.c = 0;
break;
case M_rda:
ea.a = ea.r;
ea.t = T_RA;
- //ea.c = 0;
break;
case M_ria:
ea.a = regs.a[ea.r];
ea.t = T_AD;
- //ea.c = z == 4 ? 8 : 4;
break;
case M_ripo:
ea.a = regs.a[ea.r];
ea.t = T_AD;
- //ea.c = z == 4 ? 8 : 4;
- //regs.a[ea.r] = add32(regs.a[ea.r], z);
regs.a[ea.r] += z;
if (regs.a[ea.r] > 0xffffffff) {
BUG.say(sprintf('exEA() M_ripo A%d > 2^32 ($%x)', ea.r, regs.a[ea.r]));
@@ -284,7 +281,6 @@ function CPU() {
}
break;
case M_ripr:
- //regs.a[ea.r] = sub32(regs.a[ea.r], z);
regs.a[ea.r] -= z;
if (regs.a[ea.r] < 0) {
BUG.say(sprintf('exEA() M_ripr A%d < 0 ($%x)', ea.r, regs.a[ea.r]));
@@ -295,39 +291,32 @@ function CPU() {
}
ea.a = regs.a[ea.r];
ea.t = T_AD;
- //ea.c = z == 4 ? 10 : 6;
break;
case M_rid:
dp = (nextIWord());
ea.a = add32(regs.a[ea.r], extWord(dp));
ea.t = T_AD;
- //ea.c = z == 4 ? 12 : 8;
break;
case M_rii:
ea.a = exII(regs.a[ea.r]);
ea.t = T_AD;
- //ea.c = z == 4 ? 14 : 10;
break;
case M_pcid:
dp = extWord(nextIWord());
ea.a = add32(regs.pc - 2, dp);
ea.t = T_AD;
- //ea.c = z == 4 ? 12 : 8;
break;
case M_pcii:
ea.a = exII(regs.pc);
ea.t = T_AD;
- //ea.c = z == 4 ? 14 : 10;
break;
case M_absw:
ea.a = extWord(nextIWord());
ea.t = T_AD;
- //ea.c = z == 4 ? 12 : 8;
break;
case M_absl:
ea.a = nextILong();
ea.t = T_AD;
- //ea.c = z == 4 ? 16 : 12;
break;
case M_imm: {
if (ea.r == -1) {
@@ -341,7 +330,6 @@ function CPU() {
} else
ea.a = ea.r;
ea.t = T_IM;
- //ea.c = z == 4 ? 8 : 4;
break;
}
default:
@@ -705,15 +693,6 @@ function CPU() {
stEA(dea, p.z, sea.a);
//ccna
//BUG.say(sprintf('I_LEA.%s sea $%08x', szChr(p.z), sea.a));
- /*switch (sea.m) {
- case M_ria: return 4;
- case M_rid: return 8;
- case M_rii: return 12;
- case M_pcid: return 8;
- case M_pcii: return 12;
- case M_absw: return 8;
- case M_absl: return 12;
- }*/
return p.cyc;
}
@@ -735,7 +714,7 @@ function CPU() {
regs.a[An] = regs.a[7];
regs.a[7] = add32(regs.a[7], dp);
//ccna
- return p.cyc;//16;
+ return p.cyc;
/*debug
var newsp = add32(regs.a[7], dp);
@@ -780,7 +759,7 @@ function CPU() {
stEA(dea, p.z, s);
flgLogical(s, p.z);
//BUG.say(sprintf('I_MOVEQ.%s s $%08x', szChr(p.z), s));
- return p.cyc; //4;
+ return p.cyc;
}
function I_MOVEM_R2M(p) {
@@ -827,8 +806,8 @@ function CPU() {
}
}
//ccna
- //BUG.say(sprintf('I_MOVEM_R2M.%s s $%08x d $%08x', szChr(p.z), sea.a, dea.a));
- return p.cyc + (p.z == 2 ? 4 : 8) * n;
+ //BUG.say(sprintf('I_MOVEM_R2M.%s s $%08x d $%08x', szChr(p.z), sea.a, dea.a));
+ return [p.cyc[0] + (p.z == 2 ? 4 : 8) * n, 0,0]; //FIXME
}
function I_MOVEM_M2R(p) {
@@ -858,7 +837,7 @@ function CPU() {
}
//ccna
//BUG.say(sprintf('I_MOVEM_M2R.%s s $%08x d $%08x', szChr(p.z), sea.a, dea.a));
- return p.cyc + (p.z == 2 ? 4 : 8) * n;
+ return [p.cyc[0] + (p.z == 2 ? 4 : 8) * n, 0,0]; //FIXME
}
function I_MOVEP(p) {
@@ -883,7 +862,7 @@ function CPU() {
r += ldEA(sea, 1);
r >>>= 0;
}
- BUG.say(sprintf('I_MOVEP_M2R.%s A%d addr $%08x r $%08x', szChr(p.z), dea.a, sea.a - (p.z == 2 ? 4 : 8), r));
+ //BUG.say(sprintf('I_MOVEP_M2R.%s A%d addr $%08x r $%08x', szChr(p.z), dea.a, sea.a - (p.z == 2 ? 4 : 8), r));
stEA(dea, p.z, r);
}
//R2M
@@ -903,10 +882,10 @@ function CPU() {
dea.a += 2;
stEA(dea, 1, r);
}
- BUG.say(sprintf('I_MOVEP_R2M.%s A%d addr $%08x r $%08x', szChr(p.z), sea.a, dea.a - (p.z == 2 ? 4 : 8), r));
+ //BUG.say(sprintf('I_MOVEP_R2M.%s A%d addr $%08x r $%08x', szChr(p.z), sea.a, dea.a - (p.z == 2 ? 4 : 8), r));
}
//ccna
- return p.cyc; //p.z == 2 ? 16 : 24;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -945,10 +924,10 @@ function CPU() {
stEA(dea, p.z, r);
flgAdd(s, d, r, p.z, false);
//BUG.say(sprintf('I_ADDI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 16 : 8) : (p.z == 4 ? 20 : 12) + dea.c;
+ return p.cyc;
}
- function I_ADDQ(p) {
+ /*function I_ADDQ(p) {
var sea = exEA(p.s, p.z);
var s = ldEA(sea, p.z);
if (p.d.m == M_rda) {
@@ -968,6 +947,29 @@ function CPU() {
}
//BUG.say(sprintf('I_ADDQ.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
return p.cyc;
+ }*/
+
+ function I_ADDQ(p) {
+ var sea = exEA(p.s, p.z);
+ var s = ldEA(sea, p.z);
+ var dea = exEA(p.d, p.z);
+ var d = ldEA(dea, p.z);
+ var r = addAuto(s, d, p.z);
+ stEA(dea, p.z, r);
+ flgAdd(s, d, r, p.z, false);
+ //BUG.say(sprintf('I_ADDQ.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
+ return p.cyc;
+ }
+ function I_ADDQA(p) {
+ var sea = exEA(p.s, p.z);
+ var s = ldEA(sea, p.z);
+ var dea = exEA(p.d, 4);
+ var d = ldEA(dea, 4);
+ var r = add32(s, d);
+ stEA(dea, 4, r);
+ //ccna
+ //BUG.say(sprintf('I_ADDQA.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
+ return p.cyc;
}
function I_ADDX(p) {
@@ -980,7 +982,7 @@ function CPU() {
stEA(dea, p.z, r);
flgAdd(s, d, r, p.z, true);
//BUG.say(sprintf('I_ADDX.%s s $%08x d $%08x xo %d xn %d r $%08x', szChr(p.z), s, d, _x, regs.x?1:0, r));
- return p.cyc;//dea.m == M_rdd ? (p.z == 4 ? 8 : 4) : (p.z == 4 ? 30 : 18);
+ return p.cyc;
}
function I_CLR(p) {
@@ -993,7 +995,7 @@ function CPU() {
regs.v = false;
regs.c = false;
//BUG.say(sprintf('I_CLR.%s', szChr(p.z)));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 6 : 4) : (p.z == 4 ? 12 : 8) + dea.c;
+ return p.cyc;
}
function I_CMP(p) {
@@ -1026,7 +1028,7 @@ function CPU() {
var r = subAuto(d, s, p.z);
flgCmp(s, d, r, p.z);
//BUG.say(sprintf('I_CMPI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 14 : 8) : (p.z == 4 ? 12 : 8) + dea.c;
+ return p.cyc;
}
function I_CMPM(p) {
@@ -1037,7 +1039,7 @@ function CPU() {
var r = subAuto(d, s, p.z);
flgCmp(s, d, r, p.z);
//BUG.say(sprintf('I_CMPM.%s s $%08x d $%08x r $%08x | %c', szChr(p.z), s, d, r, s));
- return p.cyc;//p.z == 4 ? 20 : 12;
+ return p.cyc;
}
function I_DIVS(p) {
@@ -1073,7 +1075,7 @@ function CPU() {
stEA(dea, 4, r);
//BUG.say(sprintf('I_DIVS.%s $%08x / $%08x = $%08x (quo $%08x | rem $%08x)', szChr(p.z), d, s, r, quo, rem));
}
- return p.cyc;// 158 + dea.c;
+ return p.cyc;
}
}
@@ -1110,7 +1112,7 @@ function CPU() {
stEA(dea, 4, r);
//BUG.say(sprintf('I_DIVU.%s $%08x / $%08x = $%08x (quo $%08x | rem $%08x)', szChr(p.z), d, s, r, quo, rem));
}
- return p.cyc; //140 + dea.c;
+ return p.cyc;
}
}
@@ -1122,7 +1124,7 @@ function CPU() {
stEA(dea, p.z, r);
flgLogical(r, p.z);
//BUG.say(sprintf('I_EXT.%s d $%08x r $%08x', szChr(p.z), d, r));
- return p.cyc; //4;
+ return p.cyc;
}
function I_MULS(p) {
@@ -1139,7 +1141,7 @@ function CPU() {
regs.n = (r & 0x80000000) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_MULS.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //70 + dea.c;
+ return p.cyc;
}
function I_MULU(p) {
@@ -1155,7 +1157,7 @@ function CPU() {
regs.n = (r & 0x80000000) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_MULU.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //70 + dea.c;
+ return p.cyc;
}
function I_NEG(p) {
@@ -1165,7 +1167,7 @@ function CPU() {
stEA(dea, p.z, r);
flgNeg(d, r, p.z, false);
//BUG.say(sprintf('I_NEG.%s d $%08x r $%08x', szChr(p.z), d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 6 : 4) : (p.z == 4 ? 12 : 8) + dea.c;
+ return p.cyc;
}
function I_NEGX(p) {
@@ -1175,7 +1177,7 @@ function CPU() {
stEA(dea, p.z, r);
flgNeg(d, r, p.z, true);
//BUG.say(sprintf('I_NEGX.%s d $%08x x %d r $%08x', szChr(p.z), d, regs.x ? 1 : 0, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 6 : 4) : (p.z == 4 ? 12 : 8) + dea.c;
+ return p.cyc;
}
function I_SUB(p) {
@@ -1211,10 +1213,10 @@ function CPU() {
stEA(dea, p.z, r);
flgSub(s, d, r, p.z, false);
//BUG.say(sprintf('I_SUBI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 16 : 8) : (p.z == 4 ? 20 : 12) + dea.c;
+ return p.cyc;
}
- function I_SUBQ(p) {
+ /*function I_SUBQ(p) {
var sea = exEA(p.s, p.z);
var s = ldEA(sea, p.z);
if (p.d.m == M_rda) {
@@ -1234,6 +1236,29 @@ function CPU() {
}
//BUG.say(sprintf('I_SUBQ.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
return p.cyc;
+ }*/
+
+ function I_SUBQ(p) {
+ var sea = exEA(p.s, p.z);
+ var s = ldEA(sea, p.z);
+ var dea = exEA(p.d, p.z);
+ var d = ldEA(dea, p.z);
+ var r = subAuto(d, s, p.z);
+ stEA(dea, p.z, r);
+ flgSub(s, d, r, p.z, false);
+ //BUG.say(sprintf('I_SUBQ.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
+ return p.cyc;
+ }
+ function I_SUBQA(p) {
+ var sea = exEA(p.s, p.z);
+ var s = ldEA(sea, p.z);
+ var dea = exEA(p.d, 4);
+ var d = ldEA(dea, 4);
+ var r = sub32(d, s);
+ stEA(dea, 4, r);
+ //ccna
+ //BUG.say(sprintf('I_SUBQA.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
+ return p.cyc;
}
function I_SUBX(p) {
@@ -1246,7 +1271,7 @@ function CPU() {
stEA(dea, p.z, r);
flgSub(s, d, r, p.z, true);
//BUG.say(sprintf('I_SUBX.%s s $%08x d $%08x xo %d xn %d r $%08x', szChr(p.z), s, d, _x, regs.x?1:0, r));
- return p.cyc;//dea.m == M_rdd ? (p.z == 4 ? 8 : 4) : (p.z == 4 ? 30 : 18);
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -1273,7 +1298,7 @@ function CPU() {
stEA(dea, p.z, r);
flgLogical(r, p.z);
//BUG.say(sprintf('I_ANDI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 16 : 8) : (p.z == 4 ? 20 : 12) + dea.c;
+ return p.cyc;
}
function I_EOR(p) {
@@ -1297,7 +1322,7 @@ function CPU() {
stEA(dea, p.z, r);
flgLogical(r, p.z);
//BUG.say(sprintf('I_EORI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 16 : 8) : (p.z == 4 ? 20 : 12) + dea.c;
+ return p.cyc;
}
function I_NOT(p) {
@@ -1308,7 +1333,7 @@ function CPU() {
stEA(dea, p.z, r);
flgLogical(r, p.z);
//BUG.say(sprintf('I_NOT.%s d $%08x r $%08x', szChr(p.z), d, r));
- return p.cyc;//dea.m == M_rdd ? (p.z == 4 ? 6 : 4) : (p.z == 4 ? 12 : 8) + dea.c;
+ return p.cyc;
}
function I_OR(p) {
@@ -1332,7 +1357,7 @@ function CPU() {
stEA(dea, p.z, r);
flgLogical(r, p.z);
//BUG.say(sprintf('I_ORI.%s s $%08x d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc; //dea.m == M_rdd ? (p.z == 4 ? 16 : 8) : (p.z == 4 ? 20 : 12) + dea.c;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -1364,7 +1389,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ASL.%s num %d d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_ASR(p) {
@@ -1390,7 +1415,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ASR.%s num %d d $%08x r $%08x sign %d', szChr(p.z), s, d, r, sign));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_LSL(p) {
@@ -1416,7 +1441,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_LSL.%s num %d d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_LSR(p) {
@@ -1441,7 +1466,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_LSR.%s num %d d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_ROL(p) {
@@ -1468,7 +1493,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ROL.%s num %d d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_ROR(p) {
@@ -1494,7 +1519,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ROR.%s num %d d $%08x r $%08x', szChr(p.z), s, d, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_ROXL(p) {
@@ -1523,7 +1548,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ROXL.%s num %d d $%08x ox %d nx %d r $%08x', szChr(p.z), s, d, _x, regs.x?1:0, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_ROXR(p) {
@@ -1551,7 +1576,7 @@ function CPU() {
regs.n = (r & p.ms) != 0;
regs.z = r == 0;
//BUG.say(sprintf('I_ROXR.%s num %d d $%08x ox %d nx %d r $%08x', szChr(p.z), s, d, _x, regs.x?1:0, r));
- return p.cyc + (dea.m == M_rdd ? s << 1 : 0);//dea.m == M_rdd ? (p.z == 4 ? 8+n2 : 6+n2) : 8 + dea.c;
+ return [p.cyc[0] + (dea.m == M_rdd ? s << 1 : 0), 0,0]; //FIXME
}
function I_SWAP(p) {
@@ -1565,7 +1590,7 @@ function CPU() {
regs.v = false;
regs.c = false;
//BUG.say(sprintf('I_SWAP.%s d $%08x r $%08x', szChr(p.z), d, r));
- return p.cyc; //4;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -1588,7 +1613,7 @@ function CPU() {
else
BUG.say(sprintf('I_BCHG.%s s $%02x == m $%02x, d $%02x, r $%02x', szChr(p.z), s, m, d, r));*/
- return p.cyc;//dea.m == M_rdd ? 8 : 8 + dea.c;
+ return p.cyc;
}
function I_BCLR(p) {
@@ -1607,7 +1632,7 @@ function CPU() {
BUG.say(sprintf('I_BCLR.%s s $%08x == m $%08x, d $%08x, r $%08x', szChr(p.z), s, m, d, r));
else
BUG.say(sprintf('I_BCLR.%s s $%02x == m $%02x, d $%02x, r $%02x', szChr(p.z), s, m, d, r));*/
- return p.cyc;//dea.m == M_rdd ? 10 : 8 + dea.c;
+ return p.cyc;
}
function I_BSET(p) {
@@ -1626,7 +1651,7 @@ function CPU() {
BUG.say(sprintf('I_BSET.%s s $%08x == m $%08x, d $%08x, r $%08x', szChr(p.z), s, m, d, r));
else
BUG.say(sprintf('I_BSET.%s s $%02x == m $%02x, d $%02x, r $%02x', szChr(p.z), s, m, d, r));*/
- return p.cyc;//dea.m == M_rdd ? 8 : 8 + dea.c;
+ return p.cyc;
}
function I_BTST(p) {
@@ -1643,7 +1668,7 @@ function CPU() {
BUG.say(sprintf('I_BTST.%s s $%08x == m $%08x, d $%08x, r $%08x', szChr(p.z), s, m, d, r));
else
BUG.say(sprintf('I_BTST.%s s $%02x == m $%02x, d $%02x, r $%02x', szChr(p.z), s, m, d, r));*/
- return p.cyc;//dea.m == M_rdd ? 6 : 4 + dea.c;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -1684,7 +1709,7 @@ function CPU() {
regs.v = !regs.v; //undef
}
//BUG.say(sprintf('I_ABCD.%s s $%02x d $%02x x %d | s_h %d s_l %d d_h %d d_l %d | r $%02x c %d', szChr(p.z), s, d, x, s_h, s_l, d_h, d_l, r, c?1:0));
- return p.cyc; //dea.m == M_rdd ? 6 : 18;
+ return p.cyc;
}
function I_NBCD(p) {
@@ -1717,7 +1742,7 @@ function CPU() {
regs.v = !regs.v; //undef
}
//BUG.say(sprintf('I_NBCD.%s s $%02x d $%02x x %d | s_h %d s_l %d d_h %d d_l %d | r $%02x c %d', szChr(p.z), s, d, x, s_h, s_l, d_h, d_l, r, c?1:0));
- return p.cyc; //dea.m == M_rdd ? 6 : 8 + dea.c;
+ return p.cyc;
}
function I_SBCD(p) {
@@ -1755,7 +1780,7 @@ function CPU() {
regs.v = !regs.v; //undef
}
//BUG.say(sprintf('I_SBCD.%s s $%02x d $%02x x %d | s_h %d s_l %d d_h %d d_l %d | r $%02x c %d', szChr(p.z), s, d, x, s_h, s_l, d_h, d_l, r, c?1:0));
- return p.cyc; //dea.m == M_rdd ? 6 : 18;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -1775,10 +1800,10 @@ function CPU() {
else pc = add32(regs.pc, extByte(dp));
//BUG.say(sprintf('I_Bcc pc $%08x', pc));
setPC(pc);
- return p.cycTaken; //10;
+ return p.cycTaken;
}
//ccna
- return p.cyc;//dp == 0 ? 12 : 8;
+ return p.cyc;
}
function I_DBcc(p) {
@@ -1793,13 +1818,13 @@ function CPU() {
if (dr--) {
var pc = add32(regs.pc - 2, extWord(dp));
setPC(pc);
- cyc = p.cycFalseTaken; //10;
+ cyc = p.cycFalseTaken;
} else {
dr = 0xffff;
- cyc = p.cycFalse; //14;
+ cyc = p.cycFalse;
}
stEA(ea, p.z, dr);
- } else cyc = p.cycTrue; //12;
+ } else cyc = p.cycTrue;
//ccna
return cyc;
}
@@ -1813,7 +1838,7 @@ function CPU() {
stEA(dea, p.z, isTrue ? 0xff : 0);
//ccna
//BUG.say(sprintf('I_S%s, cc %d, ccTrue %d, cyc %d', ccNames[cc], cc, ccTrue(cc)?1:0, isTrue ? p.cycTrue : p.cycFalse));
- return isTrue ? p.cycTrue : p.cycFalse; //dea.m == M_rdd ? (isTrue ? 6 : 4) : 8 + dea.c;
+ return isTrue ? p.cycTrue : p.cycFalse;
}
function I_BRA(p) {
@@ -1829,7 +1854,7 @@ function CPU() {
setPC(pc);
//ccna
- return p.cycTaken; //10;
+ return p.cycTaken;
}
function I_BSR(p) {
@@ -1846,7 +1871,7 @@ function CPU() {
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
setPC(pc);
//ccna
- return p.cycTaken; //18;
+ return p.cycTaken;
}
function I_JMP(p) {
@@ -1854,15 +1879,6 @@ function CPU() {
setPC(dea.a);
//ccna
//BUG.say(sprintf('I_JMP $%08x', dea.a));
- /*switch (dea.m) {
- case M_ria: return 8;
- case M_rid: return 10;
- case M_rii: return 14;
- case M_pcid: return 10;
- case M_pcii: return 14;
- case M_absw: return 10;
- case M_absl: return 12;
- }*/
return p.cyc;
}
@@ -1871,16 +1887,7 @@ function CPU() {
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
setPC(dea.a);
//ccna
- //BUG.say(sprintf('I_JSR $%08x', dea.a));
- /*switch (dea.m) {
- case M_ria: return 16;
- case M_rid: return 18;
- case M_rii: return 22;
- case M_pcid: return 18;
- case M_pcii: return 22;
- case M_absw: return 18;
- case M_absl: return 20;
- }*/
+ //BUG.say(sprintf('I_JSR $%08x', dea.a));
return p.cyc;
}
@@ -1906,7 +1913,7 @@ function CPU() {
var r = ldEA(dea, p.z); //r = extAuto(r, p.z);
flgLogical(r, p.z);
//BUG.say(sprintf('I_TST.%s r $%08x', szChr(p.z), r));
- return p.cyc; //dea.m == M_rdd || dea.m == M_rda ? 4 : 4 + dea.c;
+ return p.cyc;
}
function I_NOP(p) {
@@ -2036,7 +2043,7 @@ function CPU() {
stEA(dea, p.z, sr);
//ccna
//BUG.say(sprintf('I_MOVE_SR2.%s sr $%04x', szChr(p.z), sr));
- return p.cyc;//dea.m == M_rdd ? 6 : 8;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -2195,7 +2202,7 @@ function CPU() {
regs.v = false;
regs.c = false;
BUG.say(sprintf('I_TAS.%s d $%02x r $%02x', szChr(p.z), d, r));
- return p.cyc; //dea.m == M_rdd ? 4 : 10 + dea.c;
+ return p.cyc;
}
/*-----------------------------------------------------------------------*/
@@ -2203,7 +2210,7 @@ function CPU() {
/*-----------------------------------------------------------------------*/
function mkCyc(z, m) {
- switch (m) {
+ /*switch (m) {
case M_rdd:
case M_rda: return 0;
case M_ria: return z == 4 ? 8 : 4;
@@ -2217,6 +2224,21 @@ function CPU() {
case M_absl: return z == 4 ? 16 : 12;
case M_imm:
case M_list: return z == 4 ? 8 : 4;
+ }*/
+ switch (m) {
+ case M_rdd:
+ case M_rda: return z == 4 ? [ 0,0,0] : [ 0,0,0];
+ case M_ria: return z == 4 ? [ 8,2,0] : [ 4,1,0];
+ case M_ripo: return z == 4 ? [ 8,2,0] : [ 4,1,0];
+ case M_ripr: return z == 4 ? [10,2,0] : [ 6,1,0];
+ case M_rid: return z == 4 ? [12,3,0] : [ 8,2,0];
+ case M_rii: return z == 4 ? [14,3,0] : [10,2,0];
+ case M_pcid: return z == 4 ? [12,3,0] : [ 8,2,0];
+ case M_pcii: return z == 4 ? [14,3,0] : [10,2,0];
+ case M_absw: return z == 4 ? [12,3,0] : [ 8,2,0];
+ 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];
}
}
@@ -2227,7 +2249,7 @@ function CPU() {
i.mn = mn;
i.f = null;
i.p = {};
- if (cyc) i.p.cyc = cyc;
+ i.p.cyc = cyc;
return i;
}
@@ -2242,7 +2264,9 @@ function CPU() {
i.p.s = new effAddr(s, r);
i.p.s.c = mkCyc(z, s);
i.p.cyc = cyc;
- if (add) i.p.cyc += i.p.s.c;
+ if (add) i.p.cyc[0] += i.p.s.c[0];
+ i.p.cyc[1] += i.p.s.c[1];
+ i.p.cyc[2] += i.p.s.c[2];
return i;
}
@@ -2257,7 +2281,9 @@ function CPU() {
i.p.d = new effAddr(d, r);
i.p.d.c = mkCyc(z, d);
i.p.cyc = cyc;
- if (add) i.p.cyc += i.p.d.c;
+ if (add) i.p.cyc[0] += i.p.d.c[0];
+ i.p.cyc[1] += i.p.d.c[1];
+ i.p.cyc[2] += i.p.d.c[2];
return i;
}
@@ -2276,8 +2302,12 @@ function CPU() {
i.p.s.c = mkCyc(z, sm);
i.p.d.c = mkCyc(z, dm);
i.p.cyc = cyc;
- if (sa) i.p.cyc += i.p.s.c;
- if (da) i.p.cyc += i.p.d.c;
+ if (sa) i.p.cyc[0] += i.p.s.c[0];
+ if (da) i.p.cyc[0] += i.p.d.c[0];
+ i.p.cyc[1] += i.p.s.c[1];
+ i.p.cyc[2] += i.p.s.c[2];
+ i.p.cyc[1] += i.p.d.c[1];
+ i.p.cyc[2] += i.p.d.c[2];
return i;
}
@@ -2324,9 +2354,13 @@ function CPU() {
i.p.cycTrue = cycTrue;
i.p.cycFalse = cycFalse;
if (add) {
- i.p.cycTrue += i.p.d.c;
- i.p.cycFalse += i.p.d.c;
+ i.p.cycTrue[0] += i.p.d.c[0];
+ i.p.cycFalse[0] += i.p.d.c[0];
}
+ i.p.cycTrue[1] += i.p.d.c[1];
+ i.p.cycTrue[2] += i.p.d.c[2];
+ i.p.cycFalse[1] += i.p.d.c[1];
+ i.p.cycFalse[2] += i.p.d.c[2];
return i;
}
@@ -2380,9 +2414,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (rm == 0)
- iTab[op] = mkSD(op, 'ABCD', 1, M_rdd, Ry, M_rdd, Rx, 6, false, false);
+ iTab[op] = mkSD(op, 'ABCD', 1, M_rdd, Ry, M_rdd, Rx, [6,1,0], false, false);
else
- iTab[op] = mkSD(op, 'ABCD', 1, M_ripr, Ry, M_ripr, Rx, 18, false, false);
+ iTab[op] = mkSD(op, 'ABCD', 1, M_ripr, Ry, M_ripr, Rx, [18,3,1], false, false);
iTab[op].f = I_ABCD;
cnt++;
@@ -2412,8 +2446,8 @@ function CPU() {
op = (13 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea[0];
- cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 4) : (z2 == 4 ? 12 : 8);
-
+ cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]);
+
if (iTab[op].op === -1) {
if (dir == 0)
iTab[op] = mkSD(op, 'ADD', z2, ea[1], ea[2], M_rdd, Dn, cyc, true, false);
@@ -2421,7 +2455,6 @@ function CPU() {
iTab[op] = mkSD(op, 'ADD', z2, M_rdd, Dn, ea[1], ea[2], cyc, false, true);
iTab[op].f = I_ADD;
- //iTab[op].p.cyc = ((dir == 0) ? (z2 == 4 ? (ea[1]==M_rdd||ea[1]==M_imm?8:6) : 4) : (z2 == 4 ? 12 : 8)) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS ADD ' + op);
@@ -2448,9 +2481,8 @@ function CPU() {
op = (13 << 12) | (An << 9) | (z3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'ADDA', z2, ea[1], ea[2], M_rda, An, z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 8, true, false);
+ iTab[op] = mkSD(op, 'ADDA', z2, ea[1], ea[2], M_rda, An, z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : [8,1,0], true, false);
iTab[op].f = I_ADDA;
- //iTab[op].p.cyc = (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 8) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS ADDA ' + op);
@@ -2474,7 +2506,7 @@ function CPU() {
op = (6 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'ADDI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 16 : 8) : (z2 == 4 ? 20 : 12), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'ADDI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [16,3,0] : [8,2,0]) : (z2 == 4 ? [20,3,2] : [12,2,1]), false, ea[1] != M_rdd);
iTab[op].f = I_ADDI;
cnt++;
} else {
@@ -2499,11 +2531,12 @@ function CPU() {
if (ea[1] == M_rda && z == 0) continue; //An word and long only
op = (5 << 12) | (id << 9) | (z << 6) | ea[0];
- cyc = ea[1] == M_rda ? 8 : (ea[1] == M_rdd ? (z2 == 4 ? 8 : 4) : (z2 == 4 ? 12 : 8));
+ cyc = ea[1] == M_rda ? [8,1,0] : (ea[1] == M_rdd ? (z2 == 4 ? [8,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]));
if (iTab[op].op === -1) {
iTab[op] = mkSD(op, 'ADDQ', z2, M_imm, id == 0 ? 8 : id, ea[1], ea[2], cyc, false, ea[1] != M_rdd && ea[1] != M_rda);
- iTab[op].f = I_ADDQ;
+ //iTab[op].f = I_ADDQ;
+ iTab[op].f = ea[1] != M_rda ? I_ADDQ : I_ADDQA;
cnt++;
} else {
BUG.say('OP EXISTS ADDQ ' + op);
@@ -2527,9 +2560,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (rm == 0)
- iTab[op] = mkSD(op, 'ADDX', z2, M_rdd, Ry, M_rdd, Rx, z2 == 4 ? 8 : 4, false, false);
- else
- iTab[op] = mkSD(op, 'ADDX', z2, M_ripr, Ry, M_ripr, Rx, z2 == 4 ? 30 : 18, false, false);
+ iTab[op] = mkSD(op, 'ADDX', z2, M_rdd, Ry, M_rdd, Rx, z2 == 4 ? [8,1,0] : [4,1,0], false, false);
+ else
+ iTab[op] = mkSD(op, 'ADDX', z2, M_ripr, Ry, M_ripr, Rx, z2 == 4 ? [30,5,2] : [18,1,0], false, false);
iTab[op].f = I_ADDX;
cnt++;
@@ -2558,7 +2591,7 @@ function CPU() {
if (ea[0] != -1) {
op = (12 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea[0];
- cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 4) : (z2 == 4 ? 12 : 8);
+ cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]);
if (iTab[op].op === -1) {
if (dir == 0)
@@ -2567,7 +2600,6 @@ function CPU() {
iTab[op] = mkSD(op, 'AND', z2, M_rdd, Dn, ea[1], ea[2], cyc, false, true);
iTab[op].f = I_AND;
- //iTab[op].p.cyc = (dir == 0 ? (z2 == 4 ? (ea[1]==M_rdd||ea[1]==M_imm?8:6) : 4) : (z2 == 4 ? 12 : 8)) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS AND ' + op);
@@ -2592,7 +2624,7 @@ function CPU() {
op = (2 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'ANDI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 16 : 8) : (z2 == 4 ? 20 : 12), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'ANDI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [16,3,0] : [8,2,0]) : (z2 == 4 ? [20,3,2] : [12,2,1]), false, ea[1] != M_rdd);
iTab[op].f = I_ANDI;
cnt++;
} else {
@@ -2608,7 +2640,7 @@ function CPU() {
op = 0x23C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'ANDI_CCR', 1, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'ANDI_CCR', 1, M_imm, -1, [20,3,0], false);
iTab[op].f = I_ANDI_CCR;
cnt++;
} else {
@@ -2621,7 +2653,7 @@ function CPU() {
op = 0x27C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'ANDI_SR', 2, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'ANDI_SR', 2, M_imm, -1, [20,3,0], false);
iTab[op].pr = true;
iTab[op].f = I_ANDI_SR;
cnt++;
@@ -2646,9 +2678,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (ir == 0)
- iTab[op] = mkSD(op, dr == 0 ? 'ASR_RI' : 'ASL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ASR_RI' : 'ASL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
else
- iTab[op] = mkSD(op, dr == 0 ? 'ASR_RD' : 'ASL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ASR_RD' : 'ASL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
iTab[op].f = dr == 0 ? I_ASR : I_ASL;
cnt++;
@@ -2668,7 +2700,7 @@ function CPU() {
op = (112 << 9) | (dr << 8) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, dr == 0 ? 'ASR_M' : 'ASL_M', 2, M_imm, 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, dr == 0 ? 'ASR_M' : 'ASL_M', 2, M_imm, 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = dr == 0 ? I_ASR : I_ASL;
cnt++;
} else {
@@ -2684,12 +2716,12 @@ function CPU() {
var cc, dp;
for (cc = 2; cc < 16; cc++) {
- for (dp = 0; dp < 255; dp++) /* 0xff = 68020 only */
+ for (dp = 0; dp < 255; dp++) /* 0xff = long, 68020 only */
{
op = (6 << 12) | (cc << 8) | dp;
if (iTab[op].op === -1) {
- iTab[op] = mkC(op, 'B' + ccNames[cc], dp == 0 ? 1 : 2, cc, dp, -1, 10, dp == 0 ? 12 : 8);
+ iTab[op] = mkC(op, 'B' + ccNames[cc], dp == 0 ? 1 : 2, cc, dp, -1, [10,2,0], dp == 0 ? [12,1,0] : [8,1,0]);
iTab[op].f = I_Bcc;
cnt++;
} else {
@@ -2711,7 +2743,7 @@ function CPU() {
op = (Dn << 9) | (5 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BCHG1', 4, M_rdd, Dn, ea[1], ea[2], 8, false, false);
+ iTab[op] = mkSD(op, 'BCHG1', 4, M_rdd, Dn, ea[1], ea[2], [8,1,0], false, false);
iTab[op].f = I_BCHG;
cnt++;
} else {
@@ -2727,7 +2759,7 @@ function CPU() {
op = (33 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BCHG2', 1, M_imm, -1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, 'BCHG2', 1, M_imm, -1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = I_BCHG;
cnt++;
} else {
@@ -2749,7 +2781,7 @@ function CPU() {
op = (Dn << 9) | (6 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BCLR1', 4, M_rdd, Dn, ea[1], ea[2], 10, false, false);
+ iTab[op] = mkSD(op, 'BCLR1', 4, M_rdd, Dn, ea[1], ea[2], [10,1,0], false, false);
iTab[op].f = I_BCLR;
cnt++;
} else {
@@ -2765,7 +2797,7 @@ function CPU() {
op = (34 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BCLR2', 1, M_imm, - 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, 'BCLR2', 1, M_imm, - 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = I_BCLR;
cnt++;
} else {
@@ -2787,7 +2819,7 @@ function CPU() {
op = (Dn << 9) | (7 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BSET1', 4, M_rdd, Dn, ea[1], ea[2], 8, false, false);
+ iTab[op] = mkSD(op, 'BSET1', 4, M_rdd, Dn, ea[1], ea[2], [8,1,0], false, false);
iTab[op].f = I_BSET;
cnt++;
} else {
@@ -2803,7 +2835,7 @@ function CPU() {
op = (35 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BSET2', 1, M_imm, - 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, 'BSET2', 1, M_imm, - 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = I_BSET;
cnt++;
} else {
@@ -2825,7 +2857,7 @@ function CPU() {
op = (Dn << 9) | (4 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BTST1', 4, M_rdd, Dn, ea[1], ea[2], 6, false, false);
+ iTab[op] = mkSD(op, 'BTST1', 4, M_rdd, Dn, ea[1], ea[2], [6,1,0], false, false);
iTab[op].f = I_BTST;
cnt++;
} else {
@@ -2842,7 +2874,7 @@ function CPU() {
op = (32 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'BTST2', 1, M_imm, -1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, 'BTST2', 1, M_imm, -1, ea[1], ea[2], [4,1,0], false, true);
iTab[op].f = I_BTST;
cnt++;
} else {
@@ -2861,7 +2893,7 @@ function CPU() {
op = (96 << 8) | dp;
if (iTab[op].op === -1) {
- iTab[op] = mkC(op, 'BRA', dp == 0 ? 1 : 2, 0, dp, -1, 10, null);
+ iTab[op] = mkC(op, 'BRA', dp == 0 ? 1 : 2, 0, dp, -1, [10,2,0], null);
iTab[op].f = I_BRA;
cnt++;
} else {
@@ -2879,7 +2911,7 @@ function CPU() {
op = (97 << 8) | dp;
if (iTab[op].op === -1) {
- iTab[op] = mkC(op, 'BSR', dp == 0 ? 1 : 2, 1, dp, -1, 18, null);
+ iTab[op] = mkC(op, 'BSR', dp == 0 ? 1 : 2, 1, dp, -1, [18,2,2], null);
iTab[op].f = I_BSR;
cnt++;
} else {
@@ -2902,7 +2934,7 @@ function CPU() {
op = (4 << 12) | (Dn << 9) | (z3 << 7) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'CHK', z2, ea[1], ea[2], M_rdd, Dn, 10, true, false);
+ iTab[op] = mkSD(op, 'CHK', z2, ea[1], ea[2], M_rdd, Dn, [10,1,0], true, false);
iTab[op].f = I_CHK;
iTab[op].p.cycTaken = iTab[op].p.s.c;
cnt++;
@@ -2927,7 +2959,7 @@ function CPU() {
op = (66 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'CLR', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 6 : 4) : (z2 == 4 ? 12 : 8), ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'CLR', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [6,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]), ea[1] != M_rdd);
iTab[op].f = I_CLR;
cnt++;
} else {
@@ -2954,9 +2986,8 @@ function CPU() {
op = (11 << 12) | (Dn << 9) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'CMP', z2, ea[1], ea[2], M_rdd, Dn, z2 == 4 ? 6 : 4, true, false);
+ iTab[op] = mkSD(op, 'CMP', z2, ea[1], ea[2], M_rdd, Dn, z2 == 4 ? [6,1,0] : [4,1,0], true, false);
iTab[op].f = I_CMP;
- //iTab[op].p.cyc = (z2 == 4 ? 6 : 4) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS CMP ' + op);
@@ -2982,9 +3013,8 @@ function CPU() {
op = (11 << 12) | (An << 9) | (z3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'CMPA', z2, ea[1], ea[2], M_rda, An, 6, true, false);
+ iTab[op] = mkSD(op, 'CMPA', z2, ea[1], ea[2], M_rda, An, [6,1,0], true, false);
iTab[op].f = I_CMPA;
- //iTab[op].p.cyc = 6 + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS CMPA ' + op);
@@ -3008,7 +3038,7 @@ function CPU() {
op = (12 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'CMPI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 14 : 8) : (z2 == 4 ? 12 : 8), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'CMPI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [14,3,0] : [8,2,0]) : (z2 == 4 ? [12,3,0] : [8,2,0]), false, ea[1] != M_rdd);
iTab[op].f = I_CMPI;
cnt++;
} else {
@@ -3030,7 +3060,7 @@ function CPU() {
op = (11 << 12) | (Ax << 9) | (1 << 8) | (z << 6) | (1 << 3) | Ay;
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'CMPM', z2, M_ripo, Ay, M_ripo, Ax, z2 == 4 ? 20 : 12, false, false);
+ iTab[op] = mkSD(op, 'CMPM', z2, M_ripo, Ay, M_ripo, Ax, z2 == 4 ? [20,5,0] : [12,3,0], false, false);
iTab[op].f = I_CMPM;
cnt++;
} else {
@@ -3050,7 +3080,7 @@ function CPU() {
op = (5 << 12) | (cc << 8) | (25 << 3) | dr;
if (iTab[op].op === -1) {
- iTab[op] = mkDBcc(op, 'DB' + ccNames[cc], 2, cc, -1, dr, 12, 10, 14);
+ iTab[op] = mkDBcc(op, 'DB' + ccNames[cc], 2, cc, -1, dr, [12,2,0], [10,2,0], [14,3,0]);
iTab[op].f = I_DBcc;
cnt++;
} else {
@@ -3072,7 +3102,7 @@ function CPU() {
op = (8 << 12) | (Dn << 9) | (7 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'DIVS', 2, ea[1], ea[2], M_rdd, Dn, 158, true, false);
+ iTab[op] = mkSD(op, 'DIVS', 2, ea[1], ea[2], M_rdd, Dn, [158,1,0], true, false);
iTab[op].f = I_DIVS;
cnt++;
} else {
@@ -3095,7 +3125,7 @@ function CPU() {
op = (8 << 12) | (Dn << 9) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'DIVU', 2, ea[1], ea[2], M_rdd, Dn, 140, true, false);
+ iTab[op] = mkSD(op, 'DIVU', 2, ea[1], ea[2], M_rdd, Dn, [140,1,0], true, false);
iTab[op].f = I_DIVU;
cnt++;
} else {
@@ -3121,9 +3151,8 @@ function CPU() {
op = (11 << 12) | (Dn << 9) | (z3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'EOR', z2, M_rdd, Dn, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 8 : 4) : (z2 == 4 ? 12 : 8), false, true);
+ iTab[op] = mkSD(op, 'EOR', z2, M_rdd, Dn, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [8,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]), false, true);
iTab[op].f = I_EOR;
- //iTab[op].p.cyc = ea[1] == M_rdd ? (z2 == 4 ? 8 : 4) : ((z2 == 4 ? 12 : 8) + mkCyc(z2, ea[1]));
cnt++;
} else {
BUG.say('OP EXISTS EOR ' + op);
@@ -3147,7 +3176,7 @@ function CPU() {
op = (10 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'EORI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 16 : 8) : (z2 == 4 ? 20 : 12), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'EORI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [16,3,0] : [8,2,0]) : (z2 == 4 ? [20,3,2] : [12,2,1]), false, ea[1] != M_rdd);
iTab[op].f = I_EORI;
cnt++;
} else {
@@ -3163,7 +3192,7 @@ function CPU() {
op = 0xA3C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'EORI_CCR', 1, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'EORI_CCR', 1, M_imm, -1, [20,3,0], false);
iTab[op].f = I_EORI_CCR;
cnt++;
} else {
@@ -3176,7 +3205,7 @@ function CPU() {
op = 0xA7C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'EORI_SR', 2, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'EORI_SR', 2, M_imm, -1, [20,3,0], false);
iTab[op].pr = true;
iTab[op].f = I_EORI_SR;
cnt++;
@@ -3197,11 +3226,11 @@ function CPU() {
if (iTab[op].op === -1) {
if (m == 0)
- iTab[op] = mkSD(op, 'EXG', 4, M_rdd, Rx, M_rdd, Ry, 6, false, false);
+ iTab[op] = mkSD(op, 'EXG', 4, M_rdd, Rx, M_rdd, Ry, [6,1,0], false, false);
else if (m == 1)
- iTab[op] = mkSD(op, 'EXG', 4, M_rda, Rx, M_rda, Ry, 6, false, false);
+ iTab[op] = mkSD(op, 'EXG', 4, M_rda, Rx, M_rda, Ry, [6,1,0], false, false);
else
- iTab[op] = mkSD(op, 'EXG', 4, M_rdd, Rx, M_rda, Ry, 6, false, false);
+ iTab[op] = mkSD(op, 'EXG', 4, M_rdd, Rx, M_rda, Ry, [6,1,0], false, false);
iTab[op].f = I_EXG;
cnt++;
@@ -3224,7 +3253,7 @@ function CPU() {
op = (36 << 9) | (opm << 6) | Dn;
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'EXT', z2, M_rdd, Dn, 4, false);
+ iTab[op] = mkD(op, 'EXT', z2, M_rdd, Dn, [4,1,0], false);
iTab[op].f = I_EXT;
cnt++;
} else {
@@ -3239,7 +3268,7 @@ function CPU() {
op = 0x4AFC;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'ILLEGAL');
+ iTab[op] = mkN(op, 'ILLEGAL', [0,0,0]);
iTab[op].f = I_ILLEGAL;
cnt++;
} else {
@@ -3257,15 +3286,15 @@ function CPU() {
if (ea[0] != -1) {
op = (315 << 6) | ea[0];
- if (iTab[op].op === -1) {
+ if (iTab[op].op === -1) {
switch (ea[1]) {
- case M_ria: cyc = 8; break;
- case M_rid: cyc = 10; break;
- case M_rii: cyc = 14; break;
- case M_pcid: cyc = 10; break;
- case M_pcii: cyc = 14; break;
- case M_absw: cyc = 10; break;
- case M_absl: cyc = 12; break;
+ case M_ria: cyc = [ 8,2,0]; break;
+ case M_rid: cyc = [10,2,0]; break;
+ case M_rii: cyc = [14,3,0]; break;
+ case M_pcid: cyc = [10,2,0]; break;
+ case M_pcii: cyc = [14,3,0]; break;
+ case M_absw: cyc = [10,2,0]; break;
+ case M_absl: cyc = [12,3,0]; break;
}
iTab[op] = mkD(op, 'JMP', 0, ea[1], ea[2], cyc, false);
iTab[op].f = I_JMP;
@@ -3289,13 +3318,13 @@ function CPU() {
if (iTab[op].op === -1) {
switch (ea[1]) {
- case M_ria: cyc = 16; break;
- case M_rid: cyc = 18; break;
- case M_rii: cyc = 22; break;
- case M_pcid: cyc = 18; break;
- case M_pcii: cyc = 22; break;
- case M_absw: cyc = 18; break;
- case M_absl: cyc = 20; break;
+ case M_ria: cyc = [16,2,2]; break;
+ case M_rid: cyc = [18,2,2]; break;
+ case M_rii: cyc = [22,2,2]; break;
+ case M_pcid: cyc = [18,2,2]; break;
+ case M_pcii: cyc = [22,2,2]; break;
+ case M_absw: cyc = [18,2,2]; break;
+ case M_absl: cyc = [20,3,2]; break;
}
iTab[op] = mkD(op, 'JSR', 0, ea[1], ea[2], cyc, false);
iTab[op].f = I_JSR;
@@ -3320,14 +3349,14 @@ function CPU() {
if (iTab[op].op === -1) {
switch (ea[1]) {
- case M_ria: cyc = 4; break;
- case M_rid: cyc = 8; break;
- case M_rii: cyc = 12; break;
- case M_pcid: cyc = 8; break;
- case M_pcii: cyc = 12; break;
- case M_absw: cyc = 8; break;
- case M_absl: cyc = 12; break;
- }
+ case M_ria: cyc = [ 4,1,0]; break;
+ case M_rid: cyc = [ 8,2,0]; break;
+ case M_rii: cyc = [12,2,0]; break;
+ case M_pcid: cyc = [ 8,2,0]; break;
+ case M_pcii: cyc = [12,2,0]; break;
+ case M_absw: cyc = [ 8,2,0]; break;
+ case M_absl: cyc = [12,3,0]; break;
+ }
iTab[op] = mkSD(op, 'LEA', 4, ea[1], ea[2], M_rda, An, cyc, false, false);
iTab[op].f = I_LEA;
cnt++;
@@ -3347,7 +3376,7 @@ function CPU() {
op = (2506 << 3) | An;
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'LINK', 2, M_rda, An, M_imm, -1, 16, false, false);
+ iTab[op] = mkSD(op, 'LINK', 2, M_rda, An, M_imm, -1, [16,2,2], false, false);
iTab[op].f = I_LINK;
cnt++;
} else {
@@ -3372,9 +3401,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (ir == 0)
- iTab[op] = mkSD(op, dr == 0 ? 'LSR_RI' : 'LSL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'LSR_RI' : 'LSL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
else
- iTab[op] = mkSD(op, dr == 0 ? 'LSR_RD' : 'LSL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'LSR_RD' : 'LSL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
iTab[op].f = dr == 0 ? I_LSR : I_LSL;
cnt++;
@@ -3394,7 +3423,7 @@ function CPU() {
op = (113 << 9) | (dr << 8) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, dr == 0 ? 'LSR_M' : 'LSL_M', 2, M_imm, 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, dr == 0 ? 'LSR_M' : 'LSL_M', 2, M_imm, 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = dr == 0 ? I_LSR : I_LSL;
cnt++;
} else {
@@ -3406,37 +3435,37 @@ function CPU() {
}
}
//MOVE
- {
+ {
var tab2 = [
- [ 4,0, 8, 8, 8,12,0,0,14,12,16,0],
- [ 4,0, 8, 8, 8,12,0,0,14,12,16,0],
- [ 8,0,12,12,12,16,0,0,18,16,20,0],
- [ 8,0,12,12,12,16,0,0,18,16,20,0],
- [10,0,14,14,14,18,0,0,20,18,22,0],
- [12,0,16,16,16,20,0,0,22,20,24,0],
- [14,0,18,18,18,22,0,0,24,22,26,0],
- [12,0,16,16,16,20,0,0,22,20,24,0],
- [14,0,18,18,18,22,0,0,24,22,26,0],
- [12,0,16,16,16,20,0,0,22,20,24,0],
- [16,0,20,20,20,24,0,0,26,24,28,0],
- [ 8,0,12,12,12,16,0,0,18,16,20,0]
+ [[ 4,1,0],null,[ 8,1,1],[ 8,1,1],[ 8,1,1],[12,2,1],[14,2,1],null,null,[12,2,1],[16,3,1],null],
+ [[ 4,1,0],null,[ 8,1,1],[ 8,1,1],[ 8,1,1],[12,2,1],[14,2,1],null,null,[12,2,1],[16,3,1],null],
+ [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null],
+ [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null],
+ [[10,2,0],null,[14,2,1],[14,2,1],[14,2,1],[18,3,1],[20,4,1],null,null,[18,3,1],[22,4,1],null],
+ [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null],
+ [[14,3,0],null,[18,3,1],[18,3,1],[18,3,1],[22,4,1],[24,4,1],null,null,[22,4,1],[26,5,1],null],
+ [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null],
+ [[14,3,0],null,[18,3,1],[18,3,1],[18,3,1],[22,4,1],[24,4,1],null,null,[22,4,1],[26,5,1],null],
+ [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null],
+ [[16,4,0],null,[20,4,1],[20,4,1],[20,4,1],[24,5,1],[26,5,1],null,null,[24,5,1],[28,6,1],null],
+ [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null]
];
var tab4 = [
- [ 4,0,12,12,12,16,0,0,18,16,20,0],
- [ 4,0,12,12,12,16,0,0,18,16,20,0],
- [12,0,20,20,20,24,0,0,26,24,28,0],
- [12,0,20,20,20,24,0,0,26,24,28,0],
- [14,0,22,22,22,26,0,0,28,26,30,0],
- [16,0,24,24,24,28,0,0,30,28,32,0],
- [18,0,26,26,26,30,0,0,32,30,34,0],
- [16,0,24,24,24,28,0,0,30,28,32,0],
- [18,0,26,26,26,30,0,0,32,30,34,0],
- [16,0,24,24,24,28,0,0,30,28,32,0],
- [20,0,28,28,28,32,0,0,34,32,36,0],
- [12,0,20,20,20,24,0,0,26,24,28,0]
- ];
+ [[ 4,1,0],null,[12,1,2],[12,1,2],[12,1,2],[16,2,2],[18,2,2],null,null,[16,2,2],[20,3,2],null],
+ [[ 4,1,0],null,[12,1,2],[12,1,2],[12,1,2],[16,2,2],[18,2,2],null,null,[16,2,2],[20,3,2],null],
+ [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null],
+ [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null],
+ [[14,3,0],null,[22,3,2],[22,3,2],[22,3,2],[26,4,2],[28,4,2],null,null,[26,4,2],[30,5,2],null],
+ [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,6,2],null],
+ [[18,4,0],null,[26,4,2],[26,4,2],[26,4,2],[30,5,2],[32,5,2],null,null,[30,5,2],[34,6,2],null],
+ [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,5,2],null],
+ [[18,4,0],null,[26,4,2],[26,4,2],[26,4,2],[30,5,2],[32,5,2],null,null,[30,5,2],[34,6,2],null],
+ [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,6,2],null],
+ [[20,5,0],null,[28,5,2],[28,5,2],[28,5,2],[32,6,2],[34,6,2],null,null,[32,6,2],[36,7,2],null],
+ [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null]
+ ];
var sen = [M_rdd, M_rda, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm];
- var den = [M_rdd,M_ria, M_ripo, M_ripr, M_rid, M_rii,M_absw, M_absl];
+ var den = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl];
var z, z2, z3, smr, dmr, sea, dea;
for (z = 0; z < 3; z++) {
@@ -3472,8 +3501,34 @@ function CPU() {
}
//MOVEA
{
- var tab2 = [4,4,8,8,10,12,14,12,14,12,16,8];
- var tab4 = [4,4,12,12,14,16,18,16,18,16,20,12];
+ var tab2 = [
+ [ 4,1,0],
+ [ 4,1,0],
+ [ 8,2,0],
+ [ 8,2,0],
+ [10,2,0],
+ [12,3,0],
+ [14,3,0],
+ [12,3,0],
+ [14,3,0],
+ [12,3,0],
+ [16,4,0],
+ [ 8,2,0]
+ ];
+ var tab4 = [
+ [ 4,1,0],
+ [ 4,1,0],
+ [12,3,0],
+ [12,3,0],
+ [14,3,0],
+ [16,4,0],
+ [18,4,0],
+ [16,4,0],
+ [18,4,0],
+ [16,4,0],
+ [20,5,0],
+ [12,3,0]
+ ];
var en = [M_rdd, M_rda, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm];
var z, z2, z3, An, mr, ea;
@@ -3514,7 +3569,7 @@ function CPU() {
op = (267 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'MOVE_CCR2', 2, ea[1], ea[2]);
+ iTab[op] = mkD(op, 'MOVE_CCR2', 2, ea[1], ea[2], [0,0,0], false);
iTab[op].f = I_MOVE_CCR2;
cnt++;
} else {
@@ -3535,7 +3590,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, ea[1] == M_rdd ? false : true);
+ iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
iTab[op].f = I_MOVE_2CCR;
cnt++;
} else {
@@ -3556,7 +3611,7 @@ function CPU() {
op = (259 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'MOVE_SR2', 2, ea[1], ea[2], ea[1] == M_rdd ? 6 : 8, ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'MOVE_SR2', 2, ea[1], ea[2], ea[1] == M_rdd ? [6,1,0] : [8,1,1], ea[1] != M_rdd);
iTab[op].f = I_MOVE_SR2;
cnt++;
} else {
@@ -3577,7 +3632,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, ea[1] == M_rdd ? false : true);
+ iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
iTab[op].pr = true;
iTab[op].f = I_MOVE_2SR;
cnt++;
@@ -3598,9 +3653,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (dr == 0)
- iTab[op] = mkS(op, 'MOVE_A2USP', 4, M_rda, An, 4, false);
+ iTab[op] = mkS(op, 'MOVE_A2USP', 4, M_rda, An, [4,1,0], false);
else
- iTab[op] = mkD(op, 'MOVE_USP2A', 4, M_rda, An, 4, false);
+ iTab[op] = mkD(op, 'MOVE_USP2A', 4, M_rda, An, [4,1,0], false);
iTab[op].pr = true;
iTab[op].f = (dr == 0) ? I_MOVE_A2USP : I_MOVE_USP2A;
@@ -3613,6 +3668,19 @@ function CPU() {
}
}
//MOVEM
+ /*
+ instr size (An) (An)+ -(An) d(An) d(An,ix)+ d(PC) d(PC,ix)* xxx.W xxx.L
+ MOVEM
+ word 12+4n 12+4n - 16+4n 18+4n 16+4n 18+4n 16+4n 20+4n
+ M->R (3+n/0) (3+n/0) - (4+n/0) (4+n/0) (4+n/0) (4+n/0) (4+n/0) (5+n/0)
+ long 12+8n 12+8n - 16+8n 18+8n 16+8n 18+8n 16+8n 20+8n
+ (3+2n/0) (3+2n/0) - (4+2n/0) (4+2n/0) (4+2n/0) (4+2n/0) (4+2n/0) (5+2n/0)
+
+ MOVEM
+ word 8+4n - 8+4n 12+4n 14+4n - - 12+4n 16+4n
+ R->M (2/n) - (2/n) (3/n) (3/n) - - (3/n) (4/n)
+ long 8+8n - 8+8n 12+8n 14+8n - - 12+8n 16+8n
+ (2/2n) - (2/2n) (3/2n) (3/2n) - - (3/2n) (4/2n)*/
{
var z, z2, dr, mr, ea, cyc;
@@ -3630,25 +3698,25 @@ function CPU() {
if (iTab[op].op === -1) {
if (dr == 0) {
switch (ea[1]) {
- case M_ria: cyc = 8; break;
- case M_ripr: cyc = 8; break;
- case M_rid: cyc = 12; break;
- case M_rii: cyc = 14; break;
- case M_absw: cyc = 12; break;
- case M_absl: cyc = 16; break;
+ case M_ria: cyc = [8,2,0]; break;
+ case M_ripr: cyc = [8,2,0]; break;
+ case M_rid: cyc = [12,3,0]; break;
+ case M_rii: cyc = [14,3,0]; break;
+ case M_absw: cyc = [12,3,0]; break;
+ case M_absl: cyc = [16,4,0]; break;
}
iTab[op] = mkSD(op, 'MOVEM_R2M', z2, M_list, -1, ea[1], ea[2], cyc, false, false);
iTab[op].f = I_MOVEM_R2M;
} else {
switch (ea[1]) {
- case M_ria: cyc = 12; break;
- case M_ripo: cyc = 12; break;
- case M_rid: cyc = 16; break;
- case M_rii: cyc = 18; break;
- case M_pcid: cyc = 16; break;
- case M_pcii: cyc = 18; break;
- case M_absw: cyc = 16; break;
- case M_absl: cyc = 20; break;
+ case M_ria: cyc = [12,3,0]; break;
+ case M_ripo: cyc = [12,3,0]; break;
+ case M_rid: cyc = [16,4,0]; break;
+ case M_rii: cyc = [18,4,0]; break;
+ case M_pcid: cyc = [16,4,0]; break;
+ case M_pcii: cyc = [18,4,0]; break;
+ case M_absw: cyc = [16,4,0]; break;
+ case M_absl: cyc = [20,5,0]; break;
}
iTab[op] = mkSD(op, 'MOVEM_M2R', z2, M_list, -1, ea[1], ea[2], cyc, false, false);
iTab[op].f = I_MOVEM_M2R;
@@ -3675,13 +3743,13 @@ function CPU() {
if (iTab[op].op === -1) {
if (m == 0)
- iTab[op] = mkSD(op, 'MOVEP', 2, M_rid, An, M_rdd, Dn, 16, false, false);
+ iTab[op] = mkSD(op, 'MOVEP', 2, M_rid, An, M_rdd, Dn, [16,4,0], false, false);
else if (m == 1)
- iTab[op] = mkSD(op, 'MOVEP', 4, M_rid, An, M_rdd, Dn, 24, false, false);
+ iTab[op] = mkSD(op, 'MOVEP', 4, M_rid, An, M_rdd, Dn, [24,6,0], false, false);
else if (m == 2)
- iTab[op] = mkSD(op, 'MOVEP', 2, M_rdd, Dn, M_rid, An, 16, false, false);
+ iTab[op] = mkSD(op, 'MOVEP', 2, M_rdd, Dn, M_rid, An, [16,2,2], false, false);
else
- iTab[op] = mkSD(op, 'MOVEP', 4, M_rdd, Dn, M_rid, An, 24, false, false);
+ iTab[op] = mkSD(op, 'MOVEP', 4, M_rdd, Dn, M_rid, An, [24,2,4], false, false);
iTab[op].f = I_MOVEP;
cnt++;
@@ -3702,7 +3770,7 @@ function CPU() {
op = (7 << 12) | (Dn << 9) | d;
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'MOVEQ', 4, M_imm, d, M_rdd, Dn, 4, false, false);
+ iTab[op] = mkSD(op, 'MOVEQ', 4, M_imm, d, M_rdd, Dn, [4,1,0], false, false);
iTab[op].f = I_MOVEQ;
cnt++;
} else {
@@ -3724,7 +3792,7 @@ function CPU() {
op = (12 << 12) | (Dn << 9) | (7 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'MULS', 2, ea[1], ea[2], M_rdd, Dn, 70, true, false);
+ iTab[op] = mkSD(op, 'MULS', 2, ea[1], ea[2], M_rdd, Dn, [70,1,0], true, false);
iTab[op].f = I_MULS;
cnt++;
} else {
@@ -3747,7 +3815,7 @@ function CPU() {
op = (12 << 12) | (Dn << 9) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'MULU', 2, ea[1], ea[2], M_rdd, Dn, 70, true, false);
+ iTab[op] = mkSD(op, 'MULU', 2, ea[1], ea[2], M_rdd, Dn, [70,1,0], true, false);
iTab[op].f = I_MULU;
cnt++;
} else {
@@ -3769,7 +3837,7 @@ function CPU() {
op = (288 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'NBCD', 1, ea[1], ea[2], ea[1] == M_rdd ? 6 : 8, ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'NBCD', 1, ea[1], ea[2], ea[1] == M_rdd ? [6,1,0] : [8,1,1], ea[1] != M_rdd);
iTab[op].f = I_NBCD;
cnt++;
} else {
@@ -3792,7 +3860,7 @@ function CPU() {
op = (68 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'NEG', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 6 : 4) : (z2 == 4 ? 12 : 8), ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'NEG', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [6,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]), ea[1] != M_rdd);
iTab[op].f = I_NEG;
cnt++;
} else {
@@ -3816,7 +3884,7 @@ function CPU() {
op = (64 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'NEGX', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 6 : 4) : (z2 == 4 ? 12 : 8), ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'NEGX', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [6,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]), ea[1] != M_rdd);
iTab[op].f = I_NEGX;
cnt++;
} else {
@@ -3832,7 +3900,7 @@ function CPU() {
op = 0x4E71;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'NOP', 4);
+ iTab[op] = mkN(op, 'NOP', [4,1,0]);
iTab[op].f = I_NOP;
cnt++;
} else {
@@ -3853,7 +3921,7 @@ function CPU() {
op = (70 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'NOT', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 6 : 4) : (z2 == 4 ? 12 : 8), ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'NOT', z2, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [6,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]), ea[1] != M_rdd);
iTab[op].f = I_NOT;
cnt++;
} else {
@@ -3880,7 +3948,7 @@ function CPU() {
if (ea[0] != -1) {
op = (8 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea[0];
- cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 4)) : (z2 == 4 ? 12 : 8);
+ cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [4,1,0])) : (z2 == 4 ? [12,1,2] : [8,1,1]);
if (iTab[op].op === -1) {
if (dir == 0)
@@ -3889,7 +3957,6 @@ function CPU() {
iTab[op] = mkSD(op, 'OR', z2, M_rdd, Dn, ea[1], ea[2], cyc, false, true);
iTab[op].f = I_OR;
- //iTab[op].p.cyc = (dir == 0 ? (z2 == 4 ? (ea[1]==M_rdd||ea[1]==M_imm?8:6) : (ea[1]==M_rdd||ea[1]==M_imm?8:4)) : (z2 == 4 ? 12 : 8)) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS OR ' + op);
@@ -3914,7 +3981,7 @@ function CPU() {
op = (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'ORI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 16 : 8) : (z2 == 4 ? 20 : 12), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'ORI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [16,3,0] : [8,2,0]) : (z2 == 4 ? [20,3,2] : [12,2,1]), false, ea[1] != M_rdd);
iTab[op].f = I_ORI;
cnt++;
} else {
@@ -3930,7 +3997,7 @@ function CPU() {
op = 0x3C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'ORI_CCR', 1, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'ORI_CCR', 1, M_imm, -1, [20,3,0], false);
iTab[op].f = I_ORI_CCR;
cnt++;
} else {
@@ -3943,7 +4010,7 @@ function CPU() {
op = 0x7C;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'ORI_SR', 2, M_imm, -1, 20, false);
+ iTab[op] = mkS(op, 'ORI_SR', 2, M_imm, -1, [20,3,0], false);
iTab[op].pr = true;
iTab[op].f = I_ORI_SR;
cnt++;
@@ -3951,7 +4018,7 @@ function CPU() {
BUG.say('OP EXISTS ORI_SR ' + op);
return false;
}
- }
+ }
//PEA
{
var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl];
@@ -3964,13 +4031,13 @@ function CPU() {
if (iTab[op].op === -1) {
switch (ea[1]) {
- case M_ria: cyc = 12; break;
- case M_rid: cyc = 16; break;
- case M_rii: cyc = 20; break;
- case M_pcid: cyc = 16; break;
- case M_pcii: cyc = 20; break;
- case M_absw: cyc = 16; break;
- case M_absl: cyc = 20; break;
+ case M_ria: cyc = [12,1,2]; break;
+ case M_rid: cyc = [16,2,2]; break;
+ case M_rii: cyc = [20,2,2]; break;
+ case M_pcid: cyc = [16,2,2]; break;
+ case M_pcii: cyc = [20,2,2]; break;
+ case M_absw: cyc = [16,2,2]; break;
+ case M_absl: cyc = [20,3,2]; break;
}
iTab[op] = mkS(op, 'PEA', 4, ea[1], ea[2], cyc, false);
iTab[op].f = I_PEA;
@@ -3987,7 +4054,7 @@ function CPU() {
op = 0x4E70;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'RESET', 132);
+ iTab[op] = mkN(op, 'RESET', [132,1,0]);
iTab[op].f = I_RESET;
cnt++;
} else {
@@ -4011,9 +4078,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (ir == 0)
- iTab[op] = mkSD(op, dr == 0 ? 'ROR_RI' : 'ROL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROR_RI' : 'ROL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
else
- iTab[op] = mkSD(op, dr == 0 ? 'ROR_RD' : 'ROL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROR_RD' : 'ROL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
iTab[op].f = dr == 0 ? I_ROR : I_ROL;
cnt++;
@@ -4033,7 +4100,7 @@ function CPU() {
op = (115 << 9) | (dr << 8) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, dr == 0 ? 'ROR_M' : 'ROL_M', 2, M_imm, 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROR_M' : 'ROL_M', 2, M_imm, 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = dr == 0 ? I_ROR : I_ROL;
cnt++;
} else {
@@ -4060,9 +4127,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (ir == 0)
- iTab[op] = mkSD(op, dr == 0 ? 'ROXR_RI' : 'ROXL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROXR_RI' : 'ROXL_RI', z2, M_imm, cr == 0 ? 8 : cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
else
- iTab[op] = mkSD(op, dr == 0 ? 'ROXR_RD' : 'ROXL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? 8 : 6, false, false);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROXR_RD' : 'ROXL_RD', z2, M_rdd, cr, M_rdd, Dy, z2 == 4 ? [8,1,0] : [6,1,0], false, false);
iTab[op].f = dr == 0 ? I_ROXR : I_ROXL;
cnt++;
@@ -4082,7 +4149,7 @@ function CPU() {
op = (114 << 9) | (dr << 8) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, dr == 0 ? 'ROXR_M' : 'ROXL_M', 2, M_imm, 1, ea[1], ea[2], 8, false, true);
+ iTab[op] = mkSD(op, dr == 0 ? 'ROXR_M' : 'ROXL_M', 2, M_imm, 1, ea[1], ea[2], [8,1,1], false, true);
iTab[op].f = dr == 0 ? I_ROXR : I_ROXL;
cnt++;
} else {
@@ -4098,7 +4165,7 @@ function CPU() {
op = 0x4E73;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'RTE', 20);
+ iTab[op] = mkN(op, 'RTE', [20,5,0]);
iTab[op].pr = true;
iTab[op].f = I_RTE;
cnt++;
@@ -4112,7 +4179,7 @@ function CPU() {
op = 0x4E77;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'RTR', 20);
+ iTab[op] = mkN(op, 'RTR', [20,5,0]);
iTab[op].f = I_RTR;
cnt++;
} else {
@@ -4125,7 +4192,7 @@ function CPU() {
op = 0x4E75;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'RTS', 16);
+ iTab[op] = mkN(op, 'RTS', [16,4,0]);
iTab[op].f = I_RTS;
cnt++;
} else {
@@ -4144,9 +4211,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (rm == 0)
- iTab[op] = mkSD(op, 'SBCD', 1, M_rdd, Rx, M_rdd, Ry, 6, false, false);
+ iTab[op] = mkSD(op, 'SBCD', 1, M_rdd, Rx, M_rdd, Ry, [6,3,1], false, false);
else
- iTab[op] = mkSD(op, 'SBCD', 1, M_ripr, Rx, M_ripr, Ry, 18, false, false);
+ iTab[op] = mkSD(op, 'SBCD', 1, M_ripr, Rx, M_ripr, Ry, [18,3,1], false, false);
iTab[op].f = I_SBCD;
cnt++;
@@ -4170,7 +4237,7 @@ function CPU() {
op = (5 << 12) | (cc << 8) | (3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkCD(op, 'S' + ccNames[cc], 1, cc, -1, -1, ea[1], ea[2], ea[1] == M_rdd ? 6 : 8, ea[1] == M_rdd ? 4 : 8, ea[1] != M_rdd);
+ iTab[op] = mkCD(op, 'S' + ccNames[cc], 1, cc, -1, -1, ea[1], ea[2], ea[1] == M_rdd ? [6,1,0] : [8,1,1], ea[1] == M_rdd ? [4,1,0] : [8,1,1], ea[1] != M_rdd);
iTab[op].f = I_Scc;
cnt++;
} else {
@@ -4186,7 +4253,7 @@ function CPU() {
op = 0x4E72;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'STOP', 2, M_imm, -1, 4, false);
+ iTab[op] = mkS(op, 'STOP', 2, M_imm, -1, [4,0,0], false);
iTab[op].pr = true;
iTab[op].f = I_STOP;
cnt++;
@@ -4214,8 +4281,8 @@ function CPU() {
op = (9 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea[0];
- cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 4) : (z2 == 4 ? 12 : 8);
-
+ cyc = dir == 0 ? (z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]);
+
if (iTab[op].op === -1) {
if (dir == 0)
iTab[op] = mkSD(op, 'SUB', z2, ea[1], ea[2], M_rdd, Dn, cyc, true, false);
@@ -4223,7 +4290,6 @@ function CPU() {
iTab[op] = mkSD(op, 'SUB', z2, M_rdd, Dn, ea[1], ea[2], cyc, false, true);
iTab[op].f = I_SUB;
- //iTab[op].p.cyc = ((dir == 0) ? (z2 == 4 ? (ea[1]==M_rdd||ea[1]==M_imm?8:6) : 4) : (z2 == 4 ? 12 : 8)) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS SUB ' + op);
@@ -4250,9 +4316,8 @@ function CPU() {
op = (9 << 12) | (An << 9) | (z3 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'SUBA', z2, ea[1], ea[2], M_rda, An, z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? 8 : 6) : 8, true, false);
+ iTab[op] = mkSD(op, 'SUBA', z2, ea[1], ea[2], M_rda, An, z2 == 4 ? (ea[1] == M_rdd || ea[1] == M_imm ? [8,1,0] : [6,1,0]) : [8,1,0], true, false);
iTab[op].f = I_SUBA;
- //iTab[op].p.cyc = (z2 == 4 ? (ea[1]==M_rdd||ea[1]==M_imm?8:6) : 8) + mkCyc(z2, ea[1]);
cnt++;
} else {
BUG.say('OP EXISTS SUBA ' + op);
@@ -4276,7 +4341,7 @@ function CPU() {
op = (4 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkSD(op, 'SUBI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? 16 : 8) : (z2 == 4 ? 20 : 12), false, ea[1] != M_rdd);
+ iTab[op] = mkSD(op, 'SUBI', z2, M_imm, -1, ea[1], ea[2], ea[1] == M_rdd ? (z2 == 4 ? [16,3,0] : [8,2,0]) : (z2 == 4 ? [20,3,2] : [12,2,1]), false, ea[1] != M_rdd);
iTab[op].f = I_SUBI;
cnt++;
} else {
@@ -4301,11 +4366,12 @@ function CPU() {
if (ea[1] == M_rda && z == 0) continue; //An word and long only
op = (5 << 12) | (id << 9) | (1 << 8) | (z << 6) | ea[0];
- cyc = ea[1] == M_rda ? 8 : (ea[1] == M_rdd ? (z2 == 4 ? 8 : 4) : (z2 == 4 ? 12 : 8));
+ cyc = ea[1] == M_rda ? [8,1,0] : (ea[1] == M_rdd ? (z2 == 4 ? [8,1,0] : [4,1,0]) : (z2 == 4 ? [12,1,2] : [8,1,1]));
if (iTab[op].op === -1) {
iTab[op] = mkSD(op, 'SUBQ', z2, M_imm, id == 0 ? 8 : id, ea[1], ea[2], cyc, false, ea[1] != M_rdd && ea[1] != M_rda);
- iTab[op].f = I_SUBQ;
+ //iTab[op].f = I_SUBQ;
+ iTab[op].f = ea[1] != M_rda ? I_SUBQ : I_SUBQA;
cnt++;
} else {
BUG.say('OP EXISTS SUBQ ' + op);
@@ -4329,9 +4395,9 @@ function CPU() {
if (iTab[op].op === -1) {
if (rm == 0)
- iTab[op] = mkSD(op, 'SUBX', z2, M_rdd, Rx, M_rdd, Ry, z2 == 4 ? 8 : 4, false, false);
+ iTab[op] = mkSD(op, 'SUBX', z2, M_rdd, Rx, M_rdd, Ry, z2 == 4 ? [8,1,0] : [4,1,0], false, false);
else
- iTab[op] = mkSD(op, 'SUBX', z2, M_ripr, Rx, M_ripr, Ry, z2 == 4 ? 30 : 18, false, false);
+ iTab[op] = mkSD(op, 'SUBX', z2, M_ripr, Rx, M_ripr, Ry, z2 == 4 ? [30,5,2] : [18,1,0], false, false);
iTab[op].f = I_SUBX;
cnt++;
@@ -4352,7 +4418,7 @@ function CPU() {
op = (2312 << 3) | Dn;
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'SWAP', 2, M_rdd, Dn, 4, false);
+ iTab[op] = mkD(op, 'SWAP', 2, M_rdd, Dn, [4,1,0], false);
iTab[op].f = I_SWAP;
cnt++;
} else {
@@ -4372,7 +4438,7 @@ function CPU() {
op = (299 << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'TAS', 1, ea[1], ea[2], ea[1] == M_rdd ? 4 : 10, ea[1] != M_rdd);
+ iTab[op] = mkD(op, 'TAS', 1, ea[1], ea[2], ea[1] == M_rdd ? [4,1,0] : [10,1,1], ea[1] != M_rdd);
iTab[op].f = I_TAS;
cnt++;
} else {
@@ -4390,7 +4456,7 @@ function CPU() {
op = (1252 << 4) | v;
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'TRAP', 0, M_imm, v, 38, false);
+ iTab[op] = mkD(op, 'TRAP', 0, M_imm, v, [38,4,3], false);
iTab[op].f = I_TRAP;
cnt++;
} else {
@@ -4404,7 +4470,7 @@ function CPU() {
op = 0x4E76;
if (iTab[op].op === -1) {
- iTab[op] = mkN(op, 'TRAPV', 4);
+ iTab[op] = mkN(op, 'TRAPV', [4,1,0]);
iTab[op].f = I_TRAPV;
cnt++;
} else {
@@ -4425,7 +4491,7 @@ function CPU() {
op = (74 << 8) | (z << 6) | ea[0];
if (iTab[op].op === -1) {
- iTab[op] = mkD(op, 'TST', z2, ea[1], ea[2], 4, ea[1] != M_rdd && ea[1] != M_rda);
+ iTab[op] = mkD(op, 'TST', z2, ea[1], ea[2], [4,1,0], ea[1] != M_rdd && ea[1] != M_rda);
iTab[op].f = I_TST;
cnt++;
} else {
@@ -4444,7 +4510,7 @@ function CPU() {
op = (2507 << 3) | An;
if (iTab[op].op === -1) {
- iTab[op] = mkS(op, 'UNLK', 0, M_rda, An, 12, false);
+ iTab[op] = mkS(op, 'UNLK', 0, M_rda, An, [12,3,0], false);
iTab[op].f = I_UNLK;
cnt++;
} else {
@@ -4959,32 +5025,36 @@ function CPU() {
regs.t = 0;
}
- function exception(n) {
- //BUG.say(sprintf('cpu.exception() nr %d', n));
+ function exception_cycles(n) {
var c;
if (n < 16)
switch (n) {
- case 0: c = 40; break; //Reset Initial Interrupt Stack Pointer
- case 1: c = 40; break; //Reset Initial Program Counter
- case 2: c = 50; break; //Access Fault
- case 3: c = 50; break; //Address Error
- case 4: c = 34; break; //Illegal Instruction
- case 5: c = 42; break; //Integer Divide by Zero
- case 6: c = 44; break; //CHK, CHK2 Instruction
- case 7: c = 34; break; //FTRAPcc, TRAPcc, TRAPV Instructions
- case 8: c = 34; break; //Privilege Violation
- case 9: c = 34; break; //Trace
- case 10: c = 34; break; //Line 1010 Emulator (Unimplemented A- Line Opcode)
- case 11: c = 34; break; //Line 1111 Emulator (Unimplemented F-Line Opcode)
+ case 0: c = [40,6,0]; break; //Reset Initial Interrupt Stack Pointer
+ case 1: c = [40,6,0]; break; //Reset Initial Program Counter
+ case 2: c = [50,4,7]; break; //Access Fault
+ case 3: c = [50,4,7]; break; //Address Error
+ case 4: c = [34,4,3]; break; //Illegal Instruction
+ case 5: c = [42,5,3]; break; //Integer Divide by Zero
+ case 6: c = [44,5,3]; break; //CHK, CHK2 Instruction
+ case 7: c = [34,4,3]; break; //FTRAPcc, TRAPcc, TRAPV Instructions
+ case 8: c = [34,4,3]; break; //Privilege Violation
+ case 9: c = [34,4,3]; break; //Trace
+ case 10: c = [34,4,3]; break; //Line 1010 Emulator (Unimplemented A- Line Opcode)
+ case 11: c = [34,4,3]; break; //Line 1111 Emulator (Unimplemented F-Line Opcode)
}
else if (n >= 24 && n < 32)
- c = 44 + 4;
+ c = [44+4,5,3];
else if (n >= 32 && n < 48)
- c = 38;
+ c = [38,4,3];
else {
BUG.say(sprintf('cpu.exception() no cycle for %d', n));
- c = 4;
+ c = [4,0,0];
}
+ return c;
+ }
+
+ function exception(n) {
+ //BUG.say(sprintf('cpu.exception() nr %d', n));
var olds = regs.s;
if (n >= 24 && n < 24 + 8) {
@@ -4999,7 +5069,7 @@ function CPU() {
regs.s = true;
regs.usp = regs.a[7];
regs.a[7] = regs.isp;
-
+
BUG.col = 2;
}
@@ -5043,7 +5113,7 @@ function CPU() {
regs.pc = pc;
exception_trace(n);
- return c;
+ return exception_cycles(n);
}
function exception2(ad) {
@@ -5058,34 +5128,6 @@ function CPU() {
throw new Exception23(3);
}
- function cycle_real() {
- //if (doDiss) AMIGA.cpu.diss(null, 1);
-
- var op = nextIWord();
- fault.pc = regs.pc - 2;
- fault.op = op;
-
- var cycles;
- try {
- cycles = iTab[op].f(iTab[op].p);
- } catch (e) {
- if (e instanceof Exception23) {
- //BUG.info('cpu.cycle() USER EXCEPTION [%d]', e.num);
- cycles = exception(e.num);
- }
- else if (e instanceof Error) {
- BUG.info('cpu.cycle() ERROR EXCEPTION [%s]', e);
- cycles = 4;
- } else {
- BUG.info('cpu.cycle() UNKNOWN EXCEPTION [%s]', e);
- cycles = 4;
- }
- }
- //if (doDiss) { if (doDiss) doDiss--; AMIGA.cpu.dump(); }
-
- return cycles >> 1;
- }
-
function interrupt(nr) {
regs.stopped = false;
clr_special(SPCFLAG_STOP);
@@ -5097,16 +5139,8 @@ function CPU() {
AMIGA.doint();
}
- var last_trace_ad = 0;
function trace() {
- /*if (regs.t0 && AMIGA.config.cpu.model >= 68020) {
- } else if (regs.t1) {
- last_trace_ad = regs.pc;
- clr_special(SPCFLAG_TRACE);
- set_special(SPCFLAG_DOTRACE);
- }*/
if (regs.t) {
- last_trace_ad = regs.pc;
clr_special(SPCFLAG_TRACE);
set_special(SPCFLAG_DOTRACE);
}
@@ -5116,117 +5150,97 @@ function CPU() {
if (AMIGA.spcflags & SPCFLAG_COPPER)
AMIGA.copper.cycle();
- while ((AMIGA.spcflags & SPCFLAG_BLTNASTY) && AMIGA.dmaen(DMAF_BLTEN) && cycles > 0 && !AMIGA.config.blitter.exact) {
+ while ((AMIGA.spcflags & SPCFLAG_BLTNASTY) && AMIGA.dmaen(DMAF_BLTEN) && cycles > 0) {
var c = AMIGA.blitter.blitnasty();
- if (c < 0) {
- break;
- } else if (c > 0) {
+ if (c > 0) {
cycles -= c * CYCLE_UNIT * 2;
if (cycles < CYCLE_UNIT)
cycles = 0;
- } else {
+ } else
c = 4;
- }
- /*if (c == 0) { //old blitter
- cycles -= 2 * CYCLE_UNIT;
- if (cycles < CYCLE_UNIT) cycles = 0;
- c = 1;
- }*/
+
AMIGA.events.cycle(c * CYCLE_UNIT);
- if (AMIGA.spcflags & SPCFLAG_COPPER) AMIGA.copper.cycle();
+ if (AMIGA.spcflags & SPCFLAG_COPPER)
+ AMIGA.copper.cycle();
}
- /*if (AMIGA.spcflags & SPCFLAG_DOTRACE)
+ if (AMIGA.spcflags & SPCFLAG_DOTRACE)
exception(9);
-
if (AMIGA.spcflags & SPCFLAG_TRAP) {
clr_special(SPCFLAG_TRAP);
exception(3);
- }*/
+ }
while (AMIGA.spcflags & SPCFLAG_STOP) {
- AMIGA.events.cycle (AMIGA.config.cpu.exact ? 2 * CYCLE_UNIT : 4 * CYCLE_UNIT);
+ AMIGA.events.cycle(4 * CYCLE_UNIT);
if (AMIGA.spcflags & SPCFLAG_COPPER)
AMIGA.copper.cycle();
- if (AMIGA.config.cpu.exact) {
- regs.ipl = regs.ipl_pin;
- if (regs.ipl > regs.intmask || regs.ipl == 7)
- interrupt(regs.ipl);
- } else {
- if (AMIGA.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) {
- clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
- var intr = AMIGA.intlev();
- if (intr > 0 && intr > regs.intmask)
- interrupt(intr);
- }
+ if (AMIGA.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) {
+ clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
+ var intr = AMIGA.intlev();
+ if (intr > 0 && intr > regs.intmask)
+ interrupt(intr);
}
-
- /*if ((AMIGA.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) {
- clr_special(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
+ /*if (AMIGA.spcflags & SPCFLAG_BRK) {
+ clr_special(SPCFLAG_BRK);
clr_special(SPCFLAG_STOP);
regs.stopped = false;
- return 1;
- }*/
- if (AMIGA.state != CMD_CYCLE) {
- if (regs.stopped) {
- regs.stopped = false;
- if (AMIGA.config.cpu.exact && AMIGA.config.cpu.model == 68000)
- AMIGA.events.cycle(CYCLE_UNIT / 2 * 6);
- clr_special(SPCFLAG_STOP);
- }
- return 1;
- }
+ return true;
+ }*/
}
if (AMIGA.spcflags & SPCFLAG_TRACE)
trace();
- if (AMIGA.config.cpu.exact) {
- if (regs.ipl > regs.intmask || regs.ipl == 7)
- interrupt(regs.ipl);
- } else {
- if (AMIGA.spcflags & SPCFLAG_INT) {
- clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
- var intr = AMIGA.intlev();
- if (intr > 0 && (intr > regs.intmask || intr == 7))
- interrupt(intr);
- }
+ if (AMIGA.spcflags & SPCFLAG_INT) {
+ clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
+ var intr = AMIGA.intlev();
+ if (intr > 0 && (intr > regs.intmask || intr == 7))
+ interrupt(intr);
}
-
if (AMIGA.spcflags & SPCFLAG_DOINT) {
clr_special(SPCFLAG_DOINT);
set_special(SPCFLAG_INT);
}
-
- /*if ((AMIGA.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) {
- clr_special(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
- return 1;
- }*/
- if (AMIGA.state != CMD_CYCLE)
- return 1;
-
- return 0;
+ /*if (AMIGA.spcflags & SPCFLAG_BRK) {
+ clr_special(SPCFLAG_BRK);
+ return true;
+ }*/
+ return false;
}
- this.cycles = 2;
-
this.cycle = function() {
- AMIGA.events.cycle(this.cycles * CYCLE_UNIT);
- if (AMIGA.state != CMD_CYCLE)
- return;
+ while (AMIGA.state == ST_CYCLE) {
+ AMIGA.events.cycle(cpu_cycles);
- this.cycles = cycle_real();
-
- if (AMIGA.spcflags) {
- if (cycle_spc(this.cycles * CYCLE_UNIT))
- return;
+ var op = nextOPCode();
+ try {
+ var cycles = iTab[op].f(iTab[op].p);
+ cpu_cycles = cycles[0] * cpu_cycle_unit;
+ } catch (e) {
+ if (e instanceof Exception23) {
+ //BUG.info('cpu.cycle_real() USER EXCEPTION [%d]', e.num);
+ var cycles = exception(e.num);
+ cpu_cycles = cycles[0] * cpu_cycle_unit;
+ }
+ else if (e instanceof VSync) {
+ //BUG.info('cpu.cycle_real() VSYNC [%s]', e);
+ cpu_cycles = 48 * cpu_cycle_unit;
+ throw new VSync(e.error, e.message);
+ }
+ else if (e instanceof FatalError) {
+ //BUG.info('cpu.cycle_real() FATAL ERROR [%s]', e);
+ Fatal(e.error, e.message);
+ }
+ else {
+ Fatal(SAEE_CPU_Internal, e.message);
+ }
+ }
+
+ if (AMIGA.spcflags)
+ cycle_spc(cpu_cycles);
}
- regs.ipl = regs.ipl_pin;
- }
-
- this.setIPL = function(lev) {
- regs.ipl_pin = lev;
- }
+ }
}
\ No newline at end of file
diff --git a/sae/custom.js b/sae/custom.js
index 18f96e1..77ad5eb 100644
--- a/sae/custom.js
+++ b/sae/custom.js
@@ -24,12 +24,12 @@ function Custom() {
switch (addr & 0x1fe) {
case 0x002: v = AMIGA.DMACONR(hpos); break;
- case 0x004: v = AMIGA.events.VPOSR(); break;
- case 0x006: v = AMIGA.events.VHPOSR(); break;
+ case 0x004: v = AMIGA.playfield.VPOSR(); break;
+ case 0x006: v = AMIGA.playfield.VHPOSR(); break;
case 0x00A: v = AMIGA.input.JOY0DAT(); break;
case 0x00C: v = AMIGA.input.JOY1DAT(); break;
- case 0x00E: v = AMIGA.playfield.sprites.CLXDAT(); break;
+ case 0x00E: v = AMIGA.playfield.CLXDAT(); break;
case 0x010: v = AMIGA.ADKCONR(); break;
case 0x012: v = AMIGA.input.POT0DAT(); break;
@@ -48,18 +48,18 @@ function Custom() {
break;
}
- /*#ifdef AGA
+/*#ifdef AGA
case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2:
case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
case 0x1BC: case 0x1BE:
- if (AMIGA.config.chipset.type != SAEV_Config_Chipset_Type_AGA)
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
writeonly = true;
- v = COLOR_READ ((addr & 0x3E) / 2);
+ v = COLOR_READ ((addr & 0x3E) >> 1);
break;
- #endif*/
+#endif*/
default:
writeonly = true;
@@ -68,22 +68,24 @@ function Custom() {
if (writeonly) {
v = this.last_value;
if (!noput) {
- var old = this.last_value;
- var l = 0xffff;
+ var l = 0xffff; //AMIGA.config.cpu.compatible && AMIGA.config.cpu.model == 68000 ? regs.irc : 0xffff;
+ AMIGA.playfield.decide_line(hpos);
+ AMIGA.playfield.decide_fetch(hpos);
+
var r = this.store16_real(hpos, addr, l, 1);
- if (r) { // register don't exist
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) {
+ if (r) { /* register don't exist */
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
v = l;
} else {
if ((addr & 0x1fe) == 0) {
/*if (is_cycle_ce())
- v = this.last_value;
+ v = this.last_value;
else*/
- v = l;
+ v = l;
}
}
} else {
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS)
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)
v = 0xffff;
else
v = l;
@@ -98,7 +100,7 @@ function Custom() {
}
this.load16_2 = function (addr) {
- var hpos = AMIGA.events.hpos();
+ var hpos = AMIGA.playfield.hpos();
AMIGA.copper.sync_copper_with_cpu (hpos, 1);
return this.load16_real(hpos, addr, 0);
@@ -129,15 +131,15 @@ function Custom() {
value &= 0xffff;
switch (addr) {
- //case 0x00E: CLXDAT (); break;
+ case 0x00E: AMIGA.playfield.CLXDAT(); break;
case 0x020: AMIGA.disk.DSKPTH(value); break;
case 0x022: AMIGA.disk.DSKPTL(value); break;
case 0x024: AMIGA.disk.DSKLEN(value, hpos); break;
case 0x026: /* AMIGA.disk.DSKDAT(value). Writing to DMA write registers won't do anything */; break;
- case 0x02A: AMIGA.events.VPOSW(value); break;
- case 0x02C: AMIGA.events.VHPOSW(value); break;
+ case 0x02A: AMIGA.playfield.VPOSW(value); break;
+ case 0x02C: AMIGA.playfield.VHPOSW(value); break;
case 0x02E: AMIGA.copper.COPCON(value); break;
case 0x030: AMIGA.serial.SERDAT(value); break;
case 0x032: AMIGA.serial.SERPER(value); break;
@@ -179,13 +181,13 @@ function Custom() {
case 0x088: AMIGA.copper.COPJMP(1, 0); break;
case 0x08A: AMIGA.copper.COPJMP(2, 0); break;
- case 0x08E: AMIGA.playfield.DIWSTRT(value); break;
- case 0x090: AMIGA.playfield.DIWSTOP(value); break;
- case 0x092: AMIGA.playfield.DDFSTRT(value); break;
- case 0x094: AMIGA.playfield.DDFSTOP(value); break;
+ case 0x08E: AMIGA.playfield.DIWSTRT(hpos, value); break;
+ case 0x090: AMIGA.playfield.DIWSTOP(hpos, value); break;
+ case 0x092: AMIGA.playfield.DDFSTRT(hpos, value); break;
+ case 0x094: AMIGA.playfield.DDFSTOP(hpos, value); break;
case 0x096: AMIGA.DMACON(value, hpos); break;
- case 0x098: AMIGA.playfield.sprites.CLXCON(value); break;
+ case 0x098: AMIGA.playfield.CLXCON(value); break;
case 0x09A: AMIGA.INTENA(value); break;
case 0x09C: AMIGA.INTREQ(value); break;
case 0x09E: AMIGA.ADKCON(value, hpos); break;
@@ -218,40 +220,40 @@ function Custom() {
case 0x0D8: AMIGA.audio.AUDxVOL(3, value); break;
case 0x0DA: AMIGA.audio.AUDxDAT(3, value); break;
- case 0x0E0: AMIGA.playfield.BPLxPTx(value, 0, 1); break;
- case 0x0E2: AMIGA.playfield.BPLxPTx(value, 0, 0); break;
- case 0x0E4: AMIGA.playfield.BPLxPTx(value, 1, 1); break;
- case 0x0E6: AMIGA.playfield.BPLxPTx(value, 1, 0); break;
- case 0x0E8: AMIGA.playfield.BPLxPTx(value, 2, 1); break;
- case 0x0EA: AMIGA.playfield.BPLxPTx(value, 2, 0); break;
- case 0x0EC: AMIGA.playfield.BPLxPTx(value, 3, 1); break;
- case 0x0EE: AMIGA.playfield.BPLxPTx(value, 3, 0); break;
- case 0x0F0: AMIGA.playfield.BPLxPTx(value, 4, 1); break;
- case 0x0F2: AMIGA.playfield.BPLxPTx(value, 4, 0); break;
- case 0x0F4: AMIGA.playfield.BPLxPTx(value, 5, 1); break;
- case 0x0F6: AMIGA.playfield.BPLxPTx(value, 5, 0); break;
- /*case 0x0F8: AMIGA.playfield.BPLxPTx(value, 6, 1); break;
- case 0x0FA: AMIGA.playfield.BPLxPTx(value, 6, 0); break;
- case 0x0FC: AMIGA.playfield.BPLxPTx(value, 7, 1); break;
- case 0x0FE: AMIGA.playfield.BPLxPTx(value, 7, 0); break;*/
+ case 0x0E0: AMIGA.playfield.BPLxPTH(hpos, value, 0); break;
+ case 0x0E2: AMIGA.playfield.BPLxPTL(hpos, value, 0); break;
+ case 0x0E4: AMIGA.playfield.BPLxPTH(hpos, value, 1); break;
+ case 0x0E6: AMIGA.playfield.BPLxPTL(hpos, value, 1); break;
+ case 0x0E8: AMIGA.playfield.BPLxPTH(hpos, value, 2); break;
+ case 0x0EA: AMIGA.playfield.BPLxPTL(hpos, value, 2); break;
+ case 0x0EC: AMIGA.playfield.BPLxPTH(hpos, value, 3); break;
+ case 0x0EE: AMIGA.playfield.BPLxPTL(hpos, value, 3); break;
+ case 0x0F0: AMIGA.playfield.BPLxPTH(hpos, value, 4); break;
+ case 0x0F2: AMIGA.playfield.BPLxPTL(hpos, value, 4); break;
+ case 0x0F4: AMIGA.playfield.BPLxPTH(hpos, value, 5); break;
+ case 0x0F6: AMIGA.playfield.BPLxPTL(hpos, value, 5); break;
+ case 0x0F8: AMIGA.playfield.BPLxPTH(hpos, value, 6); break;
+ case 0x0FA: AMIGA.playfield.BPLxPTL(hpos, value, 6); break;
+ case 0x0FC: AMIGA.playfield.BPLxPTH(hpos, value, 7); break;
+ case 0x0FE: AMIGA.playfield.BPLxPTL(hpos, value, 7); break;
- case 0x100: AMIGA.playfield.BPLCON0(value); break;
- case 0x102: AMIGA.playfield.BPLCON1(value); break;
- case 0x104: AMIGA.playfield.BPLCON2(value); break;
- //case 0x106: AMIGA.playfield.BPLCON3(value); break; //ECS_DENISE
+ case 0x100: AMIGA.playfield.BPLCON0(hpos, value); break;
+ case 0x102: AMIGA.playfield.BPLCON1(hpos, value); break;
+ case 0x104: AMIGA.playfield.BPLCON2(hpos, value); break;
+ case 0x106: AMIGA.playfield.BPLCON3(hpos, value); break;
- case 0x108: AMIGA.playfield.BPL1MOD(value); break;
- case 0x10A: AMIGA.playfield.BPL2MOD(value); break;
- //case 0x10E: AMIGA.playfield.sprites.CLXCON2 (value); break; //AGA
+ case 0x108: AMIGA.playfield.BPL1MOD(hpos, value); break;
+ case 0x10A: AMIGA.playfield.BPL2MOD(hpos, value); break;
+ //case 0x10E: AMIGA.playfield.CLXCON2(value); break; //AGA
- case 0x110: AMIGA.playfield.BPLxDAT(value, 0); break;
- case 0x112: AMIGA.playfield.BPLxDAT(value, 1); break;
- case 0x114: AMIGA.playfield.BPLxDAT(value, 2); break;
- case 0x116: AMIGA.playfield.BPLxDAT(value, 3); break;
- case 0x118: AMIGA.playfield.BPLxDAT(value, 4); break;
- case 0x11A: AMIGA.playfield.BPLxDAT(value, 5); break;
- //case 0x11C: AMIGA.playfield.BPLxDAT(value, 6); break;
- //case 0x11E: AMIGA.playfield.BPLxDAT(value, 7); break;
+ case 0x110: AMIGA.playfield.BPLxDAT(hpos, value, 0); break;
+ case 0x112: AMIGA.playfield.BPLxDAT(hpos, value, 1); break;
+ case 0x114: AMIGA.playfield.BPLxDAT(hpos, value, 2); break;
+ case 0x116: AMIGA.playfield.BPLxDAT(hpos, value, 3); break;
+ case 0x118: AMIGA.playfield.BPLxDAT(hpos, value, 4); break;
+ case 0x11A: AMIGA.playfield.BPLxDAT(hpos, value, 5); break;
+ case 0x11C: AMIGA.playfield.BPLxDAT(hpos, value, 6); break;
+ case 0x11E: AMIGA.playfield.BPLxDAT(hpos, value, 7); break;
case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
@@ -259,58 +261,55 @@ function Custom() {
case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
case 0x1BC: case 0x1BE:
- AMIGA.playfield.COLORxx(value & 0xfff, (addr & 0x3E) >> 1);
+ AMIGA.playfield.COLOR_WRITE(hpos, value & 0xFFF, (addr & 0x3E) >> 1);
break;
+
case 0x120: case 0x124: case 0x128: case 0x12C:
case 0x130: case 0x134: case 0x138: case 0x13C:
- AMIGA.playfield.sprites.SPRxPTH(value, (addr - 0x120) >> 2);
+ AMIGA.playfield.SPRxPTH(hpos, value, (addr - 0x120) >> 2);
break;
case 0x122: case 0x126: case 0x12A: case 0x12E:
case 0x132: case 0x136: case 0x13A: case 0x13E:
- AMIGA.playfield.sprites.SPRxPTL(value, (addr - 0x122) >> 2);
+ AMIGA.playfield.SPRxPTL(hpos, value, (addr - 0x122) >> 2);
break;
case 0x140: case 0x148: case 0x150: case 0x158:
case 0x160: case 0x168: case 0x170: case 0x178:
- AMIGA.playfield.sprites.SPRxPOS(value, (addr - 0x140) >> 3);
+ AMIGA.playfield.SPRxPOS(hpos, value, (addr - 0x140) >> 3);
break;
case 0x142: case 0x14A: case 0x152: case 0x15A:
case 0x162: case 0x16A: case 0x172: case 0x17A:
- AMIGA.playfield.sprites.SPRxCTL(value, (addr - 0x142) >> 3);
+ AMIGA.playfield.SPRxCTL(hpos, value, (addr - 0x142) >> 3);
break;
case 0x144: case 0x14C: case 0x154: case 0x15C:
case 0x164: case 0x16C: case 0x174: case 0x17C:
- AMIGA.playfield.sprites.SPRxDATA(value, (addr - 0x144) >> 3);
+ AMIGA.playfield.SPRxDATA(hpos, value, (addr - 0x144) >> 3);
break;
case 0x146: case 0x14E: case 0x156: case 0x15E:
case 0x166: case 0x16E: case 0x176: case 0x17E:
- AMIGA.playfield.sprites.SPRxDATB(value, (addr - 0x146) >> 3);
- break;
-
+ AMIGA.playfield.SPRxDATB(hpos, value, (addr - 0x146) >> 3);
+ break;
+
case 0x36: AMIGA.input.JOYTEST(value); break;
- case 0x5A: AMIGA.blitter.BLTCON0L(hpos, value); break; //ECS
- case 0x5C: AMIGA.blitter.BLTSIZV(hpos, value); break; //ECS
- case 0x5E: AMIGA.blitter.BLTSIZH(hpos, value); break; //ECS
- //case 0x1E4: AMIGA.playfield.DIWHIGH(value); break; //ECS
- //case 0x10C: AMIGA.playfield.BPLCON4(value); break; //AGA
+ case 0x5A: AMIGA.blitter.BLTCON0L(hpos, value); break;
+ case 0x5C: AMIGA.blitter.BLTSIZV(hpos, value); break;
+ case 0x5E: AMIGA.blitter.BLTSIZH(hpos, value); break;
+ case 0x1E4: AMIGA.playfield.DIWHIGH(hpos, value); break;
+ //case 0x10C: AMIGA.playfield.BPLCON4(hpos, value); break; //AGA
- //#ifndef CUSTOM_SIMPLE
- //case 0x1DC: AMIGA.events.BEAMCON0(value); break;
- /*#ifdef ECS_DENISE
- case 0x1C0: if (htotal != value) { htotal = value; varsync (); } break;
- case 0x1C2: if (hsstop != value) { hsstop = value; varsync (); } break;
- case 0x1C4: if (hbstrt != value) { hbstrt = value; varsync (); } break;
- case 0x1C6: if (hbstop != value) { hbstop = value; varsync (); } break;
- case 0x1C8: if (vtotal != value) { vtotal = value; varsync (); } break;
- case 0x1CA: if (vsstop != value) { vsstop = value; varsync (); } break;
- case 0x1CC: if (vbstrt < value || vbstrt > value + 1) { vbstrt = value; varsync (); } break;
- case 0x1CE: if (vbstop < value || vbstop > value + 1) { vbstop = value; varsync (); } break;
- case 0x1DE: if (hsstrt != value) { hsstrt = value; varsync (); } break;
- case 0x1E0: if (vsstrt != value) { vsstrt = value; varsync (); } break;
- case 0x1E2: if (hcenter != value) { hcenter = value; varsync (); } break;
- endif*/
- //endif
+ case 0x1DC: AMIGA.playfield.BEAMCON0(value); break;
+ case 0x1C0: if (AMIGA.playfield.htotal != value) { AMIGA.playfield.htotal = value; AMIGA.playfield.varsync(); } break;
+ case 0x1C2: if (AMIGA.playfield.hsstop != value) { AMIGA.playfield.hsstop = value; AMIGA.playfield.varsync(); } break;
+ case 0x1C4: if (AMIGA.playfield.hbstrt != value) { AMIGA.playfield.hbstrt = value; AMIGA.playfield.varsync(); } break;
+ case 0x1C6: if (AMIGA.playfield.hbstop != value) { AMIGA.playfield.hbstop = value; AMIGA.playfield.varsync(); } break;
+ case 0x1C8: if (AMIGA.playfield.vtotal != value) { AMIGA.playfield.vtotal = value; AMIGA.playfield.varsync(); } break;
+ case 0x1CA: if (AMIGA.playfield.vsstop != value) { AMIGA.playfield.vsstop = value; AMIGA.playfield.varsync(); } break;
+ case 0x1CC: if (AMIGA.playfield.vbstrt < value || AMIGA.playfield.vbstrt > value + 1) { AMIGA.playfield.vbstrt = value; AMIGA.playfield.varsync(); } break;
+ case 0x1CE: if (AMIGA.playfield.vbstop < value || AMIGA.playfield.vbstop > value + 1) { AMIGA.playfield.vbstop = value; AMIGA.playfield.varsync(); } break;
+ case 0x1DE: if (AMIGA.playfield.hsstrt != value) { AMIGA.playfield.hsstrt = value; AMIGA.playfield.varsync(); } break;
+ case 0x1E0: if (AMIGA.playfield.vsstrt != value) { AMIGA.playfield.vsstrt = value; AMIGA.playfield.varsync(); } break;
+ case 0x1E2: if (AMIGA.playfield.hcenter != value) { AMIGA.playfield.hcenter = value; AMIGA.playfield.varsync(); } break;
- //case 0x1FC: FMODE (hpos, value); break; //AGA
+ //case 0x1FC: AMIGA.playfield.FMODE(hpos, value); break; //AGA
//case 0x1FE: FNULL (value); break;
case 0x1FE: break;
@@ -327,7 +326,7 @@ function Custom() {
}
this.store16 = function (addr, value) {
- var hpos = AMIGA.events.hpos();
+ var hpos = AMIGA.playfield.hpos();
AMIGA.copper.sync_copper_with_cpu(hpos, 1);
if (addr & 1) {
addr &= ~1;
@@ -339,7 +338,24 @@ function Custom() {
}
this.store8 = function (addr, value) {
- this.store16(addr & ~1, ((value << 8) | (value & 0xff)) & 0xffff);
+ var rval;
+
+ /*if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ if (addr & 1) {
+ rval = value & 0xff;
+ } else {
+ rval = (value << 8) | (value & 0xFF);
+ }
+ } else*/
+ rval = (value << 8) | (value & 0xff);
+
+ /*if (AMIGA.config.cpu.model == 68060) {
+ if (addr & 1)
+ this.store16(addr & ~1, rval);
+ else
+ this.store16(addr, value << 8);
+ } else*/
+ this.store16(addr & ~1, rval);
}
this.store32 = function (addr, value) {
diff --git a/sae/disk.js b/sae/disk.js
index 490bad8..0800fec 100644
--- a/sae/disk.js
+++ b/sae/disk.js
@@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes: Ported from WinUAE 2.5.0
+*
**************************************************************************/
const LONGWRITEMODE = 0;
@@ -88,7 +91,7 @@ function Drive(number) {
this.cyl = 0;
this.motoroff = true;
this.motordelay = false; /* dskrdy needs some clock cycles before it changes after switching off motor */
- this.state = 0;
+ //this.state = 0;
this.wrprot = false;
this.bigmfmbuf = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.bigmfmbuf[i] = 0;
this.tracktiming = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.tracktiming[i] = 0;
@@ -436,7 +439,7 @@ function Drive(number) {
if (AMIGA.config.cpu.model <= 68010 && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Original) {
this.motordelay = true;
- AMIGA.events.event2_newevent2(30, this.num, function(v) { AMIGA.disk.motordelay_func(v); });
+ AMIGA.events.newevent2(30, this.num, function(v) { AMIGA.disk.motordelay_func(v); });
}
}
this.motoroff = off;
@@ -847,6 +850,7 @@ function Disk() {
AMIGA.config.hooks.floppy_motor(i, false);
AMIGA.config.hooks.floppy_step(i, floppy[i].cyl);
}
+ this.DSKLEN(0, 0);
for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) {
this.eject(i);
this.insert(i);
@@ -1022,9 +1026,8 @@ function Disk() {
var disk_sync_cycle = data >> 8;
//BUG.info('Disk.handler() data $%x, flag %d, disk_sync_cycle %d', data, flag, disk_sync_cycle);
- //AMIGA.events.eventtab[EV_DISK].active = false;
- AMIGA.events.event2_remevent(EV2_DISK);
-
+ AMIGA.events.remevent(EV2_DISK);
+
this.update(disk_sync_cycle);
if (flag & (DISK_REVOLUTION << 0)) this.fetchnextrevolution(0);
@@ -1036,7 +1039,9 @@ function Disk() {
if (flag & DISK_INDEXSYNC) {
if (!indexdecay) {
indexdecay = 2;
- AMIGA.cia.setICR(CIA_B, 0x10, null);
+ //AMIGA.cia.setICR(CIA_B, 0x10, null);
+ //AMIGA.cia.diskindex();
+ AMIGA.cia.SetICRB(0x10, null);
}
}
}
@@ -1239,7 +1244,7 @@ function Disk() {
this.doupdate_predict = function(startcycle) {
//BUG.info('Disk.doupdate_predict() startcycle %d', startcycle);
- var finaleventcycle = AMIGA.events.maxhpos << 8;
+ var finaleventcycle = AMIGA.playfield.maxhpos << 8;
var finaleventflag = 0;
for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
@@ -1252,7 +1257,7 @@ function Disk() {
var tword = word;
var countcycle = startcycle + (floppy[dr].floppybitcounter % floppy[dr].trackspeed);
var mfmpos = floppy[dr].mfmpos;
- while (countcycle < (AMIGA.events.maxhpos << 8)) {
+ while (countcycle < (AMIGA.playfield.maxhpos << 8)) {
if (floppy[dr].tracktiming[0])
this.updatetrackspeed(dr, mfmpos);
if (dskdmaen != DSKDMA_WRITE || (dskdmaen == DSKDMA_WRITE && !dma_enable)) {
@@ -1297,18 +1302,8 @@ function Disk() {
}
}
- if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.events.maxhpos) {
- AMIGA.events.event2_newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag);
-
- /*var evtime = (finaleventcycle - startcycle) >>> 8;
- if (evtime == 0) evtime = 1;
- AMIGA.events.eventtab[EV_DISK].active = true;
- AMIGA.events.eventtab[EV_DISK].oldcycles = AMIGA.events.currcycle;
- AMIGA.events.eventtab[EV_DISK].evtime = AMIGA.events.currcycle + (evtime * CYCLE_UNIT);
- AMIGA.events.eventtab[EV_DISK].data = ((finaleventcycle >>> 8) << 8) | finaleventflag;
- AMIGA.events.schedule();
- */
- }
+ if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.playfield.maxhpos)
+ AMIGA.events.newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag);
}
this.update = function(tohpos) {
@@ -1326,7 +1321,7 @@ function Disk() {
return;
disk_hpos += cycles;
- if (disk_hpos >= (AMIGA.events.maxhpos << 8))
+ if (disk_hpos >= (AMIGA.playfield.maxhpos << 8))
disk_hpos %= (1 << 8);
for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
@@ -1429,7 +1424,7 @@ function Disk() {
this.dmafinished();
return;
}
- this.update(AMIGA.events.maxhpos);
+ this.update(AMIGA.playfield.maxhpos);
}
this.update_adkcon = function(v) {
diff --git a/sae/events.js b/sae/events.js
index b989c28..9d8c7b7 100644
--- a/sae/events.js
+++ b/sae/events.js
@@ -25,50 +25,45 @@ function Event2() {
function Events() {
const SYNCBASE = 1000;
- this.lofChanged = false;
- this.lofStore = 0;
- this.lof = 0;
- this.lol = 0;
-
- this.vpos = 0;
- this.vpos_previous = 0;
- this.hpos_previous = 0;
-
- this.maxhpos = 0;
- this.maxvpos = 0;
- this.hz = 0;
-
- var dmal = 0
- var dmal_hpos = 0;
-
- var vsynctimebase = 0;
- var vsyncmintime = 0;
- var vsynctimeperline = 0;
- var vsyncmaxtime = 0;
- var vsyncwaittime = 0;
- var vsync_rendered = false;
- var is_syncline = 0;
- var is_syncline_end = 0;
-
- var frameskip = new mavg(128);
- var frameskiptime = 0;
-
- var counter = {
- lasttime:0,
- frametime:0,
- frames:0,
- fps:new mavg(10),
- idle:new mavg(10),
- idletime:0,
- bogus:0
- };
- this.timeframes = 0;
-
this.eventtab = null;
this.eventtab2 = null;
this.currcycle = 0;
- var nextEvent = 0;
- var nextEvent2 = EV2_MISC;
+ var nextevent = 0;
+ var nextevent2 = 0;
+
+ var dmal = 0
+ var dmal_hpos = 0;
+
+ var vsynctimebase = 0;
+ var vsyncmintime = 0;
+ var vsyncmaxtime = 0;
+ var vsyncwaittime = 0;
+ var vsynctimeperline = 0;
+ var is_syncline = 0;
+ var is_syncline_end = 0;
+ //var hsync_counter = 0;
+ //var vsync_counter = 0;
+
+ const MAVG_VSYNC_SIZE = 128;
+ var ma_frameskipt = new mavg(MAVG_VSYNC_SIZE);
+
+ const FPSCOUNTER_MAVG_SIZE = 10;
+ var fps_mavg = new mavg(FPSCOUNTER_MAVG_SIZE);
+ var idle_mavg = new mavg(FPSCOUNTER_MAVG_SIZE);
+ var timeframes = 0;
+ var lastframetime = 0;
+ var idletime = 0;
+ var frametime = 0;
+ var frameskiptime = 0;
+ var linecounter = 0;
+
+ var vsync_rendered = false;
+ var frame_rendered = false;
+ var frame_shown = false;
+
+ var vsyncresume = false;
+
+ /*---------------------------------*/
this.setup = function() {
if (this.eventtab === null) {
@@ -78,47 +73,39 @@ function Events() {
this.eventtab[EV_CIA].handler = function() { AMIGA.cia.handler(); }
this.eventtab[EV_AUDIO].handler = function() { AMIGA.audio.handler(); }
- this.eventtab[EV_MISC].handler = function() { var stack = { recursive:0, dorecheck:false }; AMIGA.events.MISC_handler(stack); }
- this.eventtab[EV_HSYNC].handler = function() { AMIGA.events.hSync(); }
- //this.eventtab[EV_COPPER].handler = function() { AMIGA.copper.handler(); }
- //this.eventtab[EV_BLITTER].handler = function() { AMIGA.blitter.handler(); }
- //this.eventtab[EV_RENDER].handler = function() { AMIGA.playfield.hSync(); }
-
- BUG.info('Events.setup() set %d event handlers', EV_MAX);
- } else
- BUG.info('Events.setup() event handlers are cached...');
-
+ this.eventtab[EV_MISC].handler = function() { AMIGA.events.misc_handler(); }
+ this.eventtab[EV_HSYNC].handler = function() { AMIGA.events.hsync_handler(); }
+ }
if (this.eventtab2 === null) {
this.eventtab2 = new Array(EV2_MAX);
for (var i = 0; i < EV2_MAX; i++)
this.eventtab2[i] = new Event2();
- //this.eventtab[EV2_BLITTER].handler = function(data) { AMIGA.blitter.handler(data); }
- //this.eventtab[EV2_DISK].handler = function(data) { AMIGA.disk.handler(data); }
-
- BUG.info('Events.setup() set %d event2 handlers', EV2_MAX);
- } else
- BUG.info('Events.setup() event2 handlers are cached...');
-
- this.initHz();
+ this.eventtab2[EV2_BLITTER].handler = function(data) { AMIGA.blitter.handler(data); }
+ this.eventtab2[EV2_DISK].handler = function(data) { AMIGA.disk.handler(data); }
+ this.eventtab2[EV2_DMAL].handler = function(data) { AMIGA.events.dmal_handler(data); }
+ }
+
+ this.calc_vsynctimebase(AMIGA.config.video.ntsc ? 60 : 50);
}
this.reset = function() {
- this.lofStore = 1;
- this.lof = 1;
- this.lol = 0;
- this.vpos = 0;
-
dmal = 0
dmal_hpos = 0;
-
- frameskip.clr();
- frameskiptime = 0;
- this.fpscounter_reset();
-
- this.initHz();
this.currcycle = 0;
+ nextevent = CYCLE_MAX;
+ nextevent2 = EV2_MISC;
+
+ vsynctimebase = 0;
+ vsyncmintime = 0;
+ vsyncmaxtime = 0;
+ vsyncwaittime = 0;
+ vsynctimeperline = 0;
+ is_syncline = 0;
+ is_syncline_end = 0;
+
+ this.fpscounter_reset();
for (var i = 0; i < EV_MAX; i++) {
this.eventtab[i].active = false;
@@ -129,30 +116,18 @@ function Events() {
this.eventtab2[i].active = false;
this.eventtab2[i].evtime = 0;
}
- this.eventtab[EV_HSYNC].evtime = this.maxhpos * CYCLE_UNIT; /* 0xe3 */
+ this.eventtab[EV_HSYNC].evtime = 227 * CYCLE_UNIT; /* 0xe3 */
this.eventtab[EV_HSYNC].active = true;
- /*if (AMIGA.config.video.enabled) {
- //this.eventtab[EV_RENDER].evtime = 0x38 * CYCLE_UNIT;
- this.eventtab[EV_RENDER].evtime = 0xd4 * CYCLE_UNIT;
- this.eventtab[EV_RENDER].active = true;
- }*/
+
this.schedule();
}
-
- /*---------------------------------*/
-
- this.initHz = function() {
- if (!AMIGA.config.video.ntsc) {
- this.maxvpos = 312;
- this.maxhpos = 227;
- this.hz = 50;
- } else {
- this.maxvpos = 262;
- this.maxhpos = 227;
- this.hz = 60;
- }
- vsynctimebase = SYNCBASE / this.hz;
+
+ this.calc_vsynctimebase = function(hz) {
+ vsynctimebase = Math.floor(SYNCBASE / hz);
+ //vsynctimebase >>= 1;//(AMIGA.config.video.framerate > 1 ? 1 : 0);
}
+
+ /*---------------------------------*/
this.hpos = function() {
return Math.floor((this.currcycle - this.eventtab[EV_HSYNC].oldcycles) * CYCLE_UNIT_INV);
@@ -162,121 +137,6 @@ function Events() {
return (endcycles - this.currcycle > 0);
}
- /*this.get_cycles = function() {
- return this.currcycle;
- }
-
- this.set_cycles = function(x) {
- this.currcycle = x;
- this.eventtab[EV_HSYNC].oldcycles = x;
- }*/
-
- /*---------------------------------*/
-
- this.MISC_handler = function(stack) {
- //console.log('MISC_handler() recursive %d', stack.recursive);
- var mintime;
- var recheck;
- var ct = AMIGA.events.currcycle;
-
- if (stack.recursive) {
- stack.dorecheck = true;
- return;
- }
- stack.recursive++;
- AMIGA.events.eventtab[EV_MISC].active = false;
- recheck = true;
- while (recheck) {
- recheck = false;
- mintime = CYCLE_MAX;
-
- for (var i = 0; i < EV2_MAX; i++) {
- if (AMIGA.events.eventtab2[i].active) {
- if (AMIGA.events.eventtab2[i].evtime == ct) {
- AMIGA.events.eventtab2[i].active = false;
-
- if (i == EV2_BLITTER)
- AMIGA.blitter.handler(AMIGA.events.eventtab2[i].data);
- else if (i == EV2_DISK)
- AMIGA.disk.handler(AMIGA.events.eventtab2[i].data);
- else
- AMIGA.events.eventtab2[i].handler(AMIGA.events.eventtab2[i].data);
-
- if (stack.dorecheck || AMIGA.events.eventtab2[i].active) {
- recheck = true;
- stack.dorecheck = false;
- }
- } else {
- var eventtime = AMIGA.events.eventtab2[i].evtime - ct;
- if (eventtime < mintime)
- mintime = eventtime;
- }
- }
- }
- }
- if (mintime != CYCLE_MAX) {
- AMIGA.events.eventtab[EV_MISC].active = true;
- AMIGA.events.eventtab[EV_MISC].oldcycles = ct;
- AMIGA.events.eventtab[EV_MISC].evtime = ct + mintime;
- AMIGA.events.schedule();
- }
- stack.recursive--;
- }
-
- this.event2_newevent_xx = function(no, t, data, func) {
- var et = this.currcycle + t;
- if (no < 0) {
- no = nextEvent2;
- for (;;) {
- if (!this.eventtab2[no].active)
- break;
- //if (this.eventtab2[no].evtime == et && this.eventtab2[no].handler == func && this.eventtab2[no].data == data)
- if (this.eventtab2[no].evtime == et && this.eventtab2[no].data == data)
- break;
-
- no++;
- if (no == EV2_MAX)
- no = EV2_MISC;
- if (no == nextEvent2) {
- BUG.info('event2_newevent_xx() out of event2\'s!');
- return;
- }
- }
- nextEvent2 = no;
- }
- this.eventtab2[no].active = true;
- this.eventtab2[no].evtime = et;
- this.eventtab2[no].handler = func;
- this.eventtab2[no].data = data;
-
- var stack = { recursive:0, dorecheck:false };
- this.MISC_handler(stack);
- }
-
- this.event2_newevent_x = function(no, t, data, func) {
- if (t <= 0) {
- if (no == EV2_BLITTER)
- AMIGA.blitter.handler(data);
- else if (no == EV2_DISK)
- AMIGA.disk.handler(data);
- else
- func(data);
- } else
- this.event2_newevent_xx(no, t * CYCLE_UNIT, data, func);
- }
-
- this.event2_newevent2 = function(t, data, func) {
- this.event2_newevent_x(-1, t, data, func);
- }
-
- this.event2_newevent = function(no, t, data) {
- this.event2_newevent_x(no, t, data, null); //this.eventtab2[no].handler);
- }
-
- this.event2_remevent = function(no) {
- this.eventtab2[no].active = false;
- }
-
/*---------------------------------*/
this.schedule = function() {
@@ -288,516 +148,483 @@ function Events() {
if (evtime < mintime) mintime = evtime;
}
}
- nextEvent = this.currcycle + mintime;
+ nextevent = this.currcycle + mintime;
}
- this.cycle = function (cycles) {
- while ((nextEvent - this.currcycle) <= cycles) {
+ this.cycle = function(cycles) {
+ if (vsyncresume) {
+ vsyncresume = false;
+ this.hsync_handler_post(1);
+ }
+
+ while ((nextevent - this.currcycle) <= cycles) {
if (is_syncline) {
- var rpt = new Date().getTime();
- var v = rpt - vsyncmintime;
- var v2 = rpt - is_syncline_end;
- if (v > vsynctimebase || v < -vsynctimebase) v = 0;
- if (v < 0 && v2 < 0) return;
+ var rpt = read_processor_time();
+ if (is_syncline > 0) {
+ var v = rpt - vsyncmintime;
+ var v2 = rpt - is_syncline_end;
+ if (v > vsynctimebase || v < -vsynctimebase) v = 0;
+ if (v < 0 && v2 < 0) return;
+ } else if (is_syncline < 0) {
+ var v = rpt - is_syncline_end;
+ if (v < 0) return;
+ }
is_syncline = 0;
- }
+ }
- cycles -= nextEvent - this.currcycle;
- this.currcycle = nextEvent;
+ cycles -= nextevent - this.currcycle;
+ this.currcycle = nextevent;
for (var i = 0; i < EV_MAX; i++) {
if (this.eventtab[i].active && this.eventtab[i].evtime == this.currcycle)
this.eventtab[i].handler(this.eventtab[i].data);
- }
+ }
this.schedule();
}
this.currcycle += cycles;
}
+
+ /*---------------------------------*/
+
+ var stack = { recursive:0, dorecheck:false };
+
+ this.misc_handler = function() {
+ //if (stack.recursive > 1) BUG.info('misc_handler() recursive %d', stack.recursive);
+ var mintime;
+ var ct = this.currcycle;
+
+ if (stack.recursive) {
+ stack.dorecheck = true;
+ return;
+ }
+ stack.recursive++;
+ this.eventtab[EV_MISC].active = false;
+
+ var recheck = true;
+ while (recheck) {
+ recheck = false;
+ mintime = CYCLE_MAX;
+
+ for (var i = 0; i < EV2_MAX; i++) {
+ if (this.eventtab2[i].active) {
+ if (this.eventtab2[i].evtime == ct) {
+ this.eventtab2[i].active = false;
+ this.eventtab2[i].handler(this.eventtab2[i].data);
+
+ if (stack.dorecheck || this.eventtab2[i].active) {
+ recheck = true;
+ stack.dorecheck = false;
+ }
+ } else {
+ var eventtime = this.eventtab2[i].evtime - ct;
+ if (eventtime < mintime)
+ mintime = eventtime;
+ }
+ }
+ }
+ }
+ if (mintime != CYCLE_MAX) {
+ this.eventtab[EV_MISC].active = true;
+ this.eventtab[EV_MISC].oldcycles = ct;
+ this.eventtab[EV_MISC].evtime = ct + mintime;
+ this.schedule();
+ }
+ stack.recursive--;
+ }
+
+ this.newevent2_x = function(t, data, func) {
+ var et = this.currcycle + t;
+ var no = nextevent2;
+ for (;;) {
+ if (!this.eventtab2[no].active)
+ break;
+
+ no++;
+ if (no == EV2_MAX)
+ no = EV2_MISC;
+ if (no == nextevent2) {
+ BUG.info('newevent2_x() out of events!');
+ return;
+ }
+ }
+ nextevent2 = no;
+
+ this.eventtab2[no].active = true;
+ this.eventtab2[no].evtime = et;
+ this.eventtab2[no].handler = func;
+ this.eventtab2[no].data = data;
+ this.misc_handler();
+ }
+
+ this.newevent2 = function(t, data, func) {
+ if (t <= 0)
+ func(data);
+ else
+ this.newevent2_x(t * CYCLE_UNIT, data, func);
+ }
+
+ this.newevent = function(id, t, data) {
+ this.eventtab2[id].active = true;
+ this.eventtab2[id].evtime = this.currcycle + t * CYCLE_UNIT;
+ this.eventtab2[id].data = data;
+ this.misc_handler();
+ }
+
+ this.remevent = function(no) {
+ if (this.eventtab2[no].active) {
+ this.eventtab2[no].active = false;
+ //BUG.info('remevent() %d', no);
+ }
+ }
/*---------------------------------*/
this.dmal_emu = function(v) {
if (!(AMIGA.dmacon & DMAF_DMAEN))
return;
-
- //BUG.info('Events.dmal_emu() %d', v);
+
var hpos = this.hpos();
if (v >= 6) {
v -= 6;
- var nr = v >>> 1;
+ var nr = v >> 1;
var pt = AMIGA.audio.getpt(nr, (v & 1) != 0);
- var dat = AMIGA.mem.load16_chip(pt);
+ //var dat = AMIGA.mem.load16_chip(pt);
+ var dat = AMIGA.mem.chip.data[pt >>> 1];
+ AMIGA.custom.last_value = dat;
AMIGA.audio.AUDxDAT(nr, dat);
} else {
var w = v & 1;
var pt = AMIGA.disk.getpt();
if (w) {
if (AMIGA.disk.fifostatus() <= 0) {
- var dat = AMIGA.mem.load16_chip(pt);
+ //var dat = AMIGA.mem.load16_chip(pt);
+ var dat = AMIGA.mem.chip.data[pt >>> 1];
+ AMIGA.custom.last_value = dat;
AMIGA.disk.DSKDAT(dat);
}
} else {
if (AMIGA.disk.fifostatus() >= 0) {
var dat = AMIGA.disk.DSKDATR();
- AMIGA.mem.store16_chip(pt, dat);
+ //AMIGA.mem.store16_chip(pt, dat);
+ AMIGA.mem.chip.data[pt >>> 1] = dat;
}
}
}
}
- this.dmal_func = function(v) {
- this.dmal_emu(v);
- this.dmal_handle(0);
- }
-
- this.dmal_func2 = function(v) {
+ this.dmal_handler = function(v) {
while (dmal) {
if (dmal & 3)
this.dmal_emu(dmal_hpos + ((dmal & 2) ? 1 : 0));
dmal_hpos += 2;
dmal >>>= 2;
}
+ this.remevent(EV2_DMAL);
}
-
- this.dmal_handle = function(hp) {
- if (!dmal)
- return;
- if (AMIGA.config.cpu.exact) {
- while (dmal) {
- if (dmal & 3)
- break;
- hp += 2;
- dmal >>>= 2;
- dmal_hpos += 2;
- }
- this.event2_newevent2(hp, dmal_hpos + ((dmal & 2) ? 1 : 0), function(v) { AMIGA.events.dmal_func(v); });
- dmal &= ~3;
- } else {
- this.event2_newevent2(hp, 13, function(v) { AMIGA.events.dmal_func2(v); });
- }
- }
-
+
this.dmal_hsync = function() {
- if (dmal) BUG.info('Events.dmal_hsync() DMAL error!? %04x', dmal);
+ if (dmal) BUG.info('dmal_hsync() DMAL error!? %04x', dmal);
dmal = AMIGA.audio.dmal();
dmal <<= 6;
dmal |= AMIGA.disk.dmal();
- if (!dmal)
- return;
- //BUG.info('Events.dmal_hsync() %04x', dmal);
- dmal_hpos = 0;
- this.dmal_handle(7);
- }
-
- /*---------------------------------*/
-
- this.fpscounter_reset = function() {
- counter.frames = 0;
- counter.lasttime = new Date().getTime();
- counter.fps.clr();
- counter.idle.clr();
- counter.idletime = 0;
- counter.bogus = 2;
- this.timeframes = 0;
- }
-
- this.fpscounter = function(frameok) {
- var now = new Date().getTime();
- var last = now - counter.lasttime;
- counter.lasttime = now;
-
- if (counter.bogus || last < 0)
- return;
-
- counter.fps.set(last / 10);
- counter.idle.set(counter.idletime / 10);
- counter.idletime = 0;
-
- counter.frametime += last;
- counter.frames++;
- this.timeframes++;
- if ((counter.frames & 7) == 0) {
- var idle = 1000 - (counter.idle.average == 0 ? 0 : counter.idle.average * 1000 / vsynctimebase);
- var fps = counter.fps.average == 0 ? 0 : SYNCBASE * 10 / counter.fps.average;
- if (fps > 9999) fps = 9999;
- if (idle < 0) idle = 0;
- if (idle > 100 * 10) idle = 100 * 10;
- if (fps < this.hz * 10) idle *= (this.hz * 10 / fps);
-
- if ((counter.frames & 15) == 0) {
- AMIGA.config.hooks.fps(Math.round(fps * 0.1));
- AMIGA.config.hooks.cpu(Math.round(idle * 0.1));
- }
+ if (dmal) {
+ dmal_hpos = 0;
+ this.newevent(EV2_DMAL, 7, 13);
}
}
- var lastskiptime = new Date().getTime();
- this.testFrameSkip = function() {
- var now = new Date().getTime();
- var time = now - lastskiptime;
- lastskiptime = now;
-
- var fps = Math.floor(SYNCBASE / (time * 0.1)) * 0.1;
- if (fps < this.hz) {
- if (AMIGA.playfield.frame.skip) {
- if (++AMIGA.playfield.frame.skipcount >= MAX_FRAMESKIP_COUNT) {
- if (!AMIGA.playfield.state.ilace || (AMIGA.playfield.state.ilace && this.lof == 1)) {
- AMIGA.playfield.frame.skipcount = 0;
- AMIGA.playfield.frame.skip = false;
- //BUG.info('Events.vSyncPost() force frameskip disable');
- }
- }
- } else {
- if (!AMIGA.playfield.state.ilace || (AMIGA.playfield.state.ilace && this.lof == 0))
- AMIGA.playfield.frame.skip = true;
- }
- } else {
- AMIGA.playfield.frame.skip = false;
- AMIGA.playfield.frame.skipcount = 0;
- }
- //AMIGA.playfield.frame.skip = (AMIGA.playfield.frame.count & 1) == 1;
- }
-
/*---------------------------------*/
- /*function getTime() {
- return new Date().getTime();
- }*/
-
- this.sleep = function(ms) {
- //console.log('sleep');
+ function sleep(ms) {
var start = new Date().getTime();
while ((new Date().getTime() - start) < ms);
}
- this.rpt_vsync = function(adjust) {
- var t = new Date().getTime();
- var v = t - vsyncwaittime + adjust;
+ function read_processor_time() {
+ return (new Date().getTime());
+ //return window.performance.now();
+ //return window.performance.webkitNow();
+ }
+
+ function rpt_vsync(adjust) {
+ var curr_time = read_processor_time();
+ var v = curr_time - vsyncwaittime + adjust;
if (v > SYNCBASE || v < -SYNCBASE) {
- vsyncmintime = vsyncmaxtime = vsyncwaittime = t;
+ vsyncmintime = vsyncmaxtime = vsyncwaittime = curr_time;
v = 0;
}
return v;
}
-
- this.framewait = function() {
- var curr_time;
+
+ this.framewait = function() {
var clockadjust = 0;
var vstb = vsynctimebase;
-
- is_syncline = 0;
-
- var frameskip_avg = frameskip.set(frameskiptime);
- frameskiptime = 0;
- //BUG.info(frameskip_avg);
- if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum) {
- curr_time = new Date().getTime();
+ var frameskipt_avg = ma_frameskipt.set(frameskiptime);
+ frameskiptime = 0;
+
+ is_syncline = 0;
+
+ if (AMIGA.config.cpu.speed < 0) {
+ if (!frame_rendered)
+ frame_rendered = AMIGA.playfield.render_screen(false);
+
+ var curr_time = read_processor_time();
var adjust = 0;
- if (curr_time - vsyncwaittime > 0 && curr_time - vsyncwaittime < vstb / 2)
+ if (Math.floor(curr_time - vsyncwaittime) > 0 && Math.floor(curr_time - vsyncwaittime) < (vstb >> 1))
adjust += curr_time - vsyncwaittime;
adjust += clockadjust;
- var max = Math.floor(vstb * (1.0 - adjust));
+ console.log(adjust);
+
vsyncwaittime = curr_time + vstb - adjust;
vsyncmintime = curr_time;
+ var max = Math.floor(vstb - adjust);
if (max < 0) {
max = 0;
vsynctimeperline = 1;
- } else {
- vsynctimeperline = Math.floor(max / (this.maxvpos + 1));
- }
- vsyncmaxtime = curr_time + max;
+ } else
+ vsynctimeperline = Math.floor(max / (AMIGA.playfield.maxvpos_nom + 1));
- //BUG.info("%06d:%06d/%06d", adjust, vsynctimeperline, vstb);
+ vsyncmaxtime = curr_time + max;
} else {
- var start = new Date().getTime();
- while (true) {
- var v = this.rpt_vsync(clockadjust);// / (SYNCBASE / 1000.0);
- if (v >= -4) break;
- this.sleep(2);
- }
- curr_time = start = new Date().getTime();
- while (this.rpt_vsync(clockadjust) < 0);
- counter.idletime += new Date().getTime() - start;
+ var start;
+ var t = 0;
+
+ if (!frame_rendered) {
+ start = read_processor_time();
+ frame_rendered = AMIGA.playfield.render_screen(false);
+ t = read_processor_time() - start;
+ }
+ while (rpt_vsync(clockadjust) < -4)// / (SYNCBASE / 1000.0);
+ sleep(2);
+
+ start = read_processor_time();
+ while (rpt_vsync(clockadjust) < 0);
+ idletime += read_processor_time() - start;
- curr_time = new Date().getTime();
+ var curr_time = read_processor_time();
vsyncmintime = curr_time;
vsyncmaxtime = vsyncwaittime = curr_time + vstb;
-
- var t = frameskip_avg;
- vsynctimeperline = (vstb - t) / 3;
+ if (frame_rendered) {
+ frame_shown = AMIGA.playfield.show_screen();
+ t += read_processor_time() - curr_time;
+ }
+ t += frameskipt_avg;
+
+ vsynctimeperline = Math.floor((vstb - t) / 3);
if (vsynctimeperline < 0)
vsynctimeperline = 0;
- else if (vsynctimeperline > vstb / 3)
- vsynctimeperline = vstb / 3;
+ else if (vsynctimeperline > Math.floor(vstb / 3))
+ vsynctimeperline = Math.floor(vstb / 3);
}
}
-
- this.is_last_line = function() {
- return this.vpos + 1 == this.maxvpos + this.lof_store;
- }
+
this.framewait2 = function() {
- if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum) {
- if (this.is_last_line()) {
- vsyncmintime = vsyncmaxtime;
- is_syncline_end = new Date().getTime() + vsynctimebase;
+ if (AMIGA.config.cpu.speed < 0) {
+ if (AMIGA.playfield.is_last_line()) {
+ /* really last line, just run the cpu emulation until whole vsync time has been used */
+ vsyncmintime = vsyncmaxtime; /* emulate if still time left */
+ is_syncline_end = read_processor_time() + vsynctimebase; /* far enough in future, we never wait that long */
is_syncline = 1;
} else {
+ /* end of scanline, run cpu emulation as long as we still have time */
vsyncmintime += vsynctimeperline;
+ linecounter++;
is_syncline = 0;
- if (vsyncmaxtime - vsyncmintime > 0) {
- if (vsyncwaittime - vsyncmintime > 0) {
- var rpt = new Date().getTime();
- if (vsyncmintime - rpt > 0) {
+ if (Math.floor(vsyncmaxtime - vsyncmintime) > 0) {
+ if (Math.floor(vsyncwaittime - vsyncmintime) > 0) {
+ var rpt = read_processor_time();
+ /* Extra time left? Do some extra CPU emulation */
+ if (Math.floor(vsyncmintime - rpt) > 0) {
is_syncline = 1;
+ /* limit extra time */
is_syncline_end = rpt + vsynctimeperline;
+ linecounter = 0;
}
}
+ // extra cpu emulation time if previous 10 lines without extra time.
+ if (!is_syncline && linecounter >= 10) {
+ is_syncline = -1;
+ is_syncline_end = read_processor_time() + vsynctimeperline;
+ linecounter = 0;
+ }
}
}
} else {
- if (this.is_last_line() && (this.vpos == Math.floor(this.maxvpos * 1 / 3) || this.vpos == Math.floor(this.maxvpos * 2 / 3))) {
+ if (AMIGA.playfield.vpos + 1 < AMIGA.playfield.maxvpos + AMIGA.playfield.lof_store && (AMIGA.playfield.vpos == Math.floor(AMIGA.playfield.maxvpos_nom / 3) || AMIGA.playfield.vpos == Math.floor(AMIGA.playfield.maxvpos_nom * 2 / 3))) {
vsyncmintime += vsynctimeperline;
- var rpt = new Date().getTime();
- while (vsyncmintime - (rpt + vsynctimebase / 10) > 0 && vsyncmintime - rpt < vsynctimebase) {
- this.sleep(1);
- rpt = new Date().getTime();
+ var rpt = read_processor_time();
+ // sleep if more than 2ms "free" time
+ while (Math.floor(vsyncmintime) - Math.floor(rpt + vsynctimebase / 10) > 0 && Math.floor(vsyncmintime - rpt) < vsynctimebase) {
+ sleep(1);
+ rpt = read_processor_time();
+ //console.log('*');
}
}
}
}
-
+
+ this.fpscounter_reset = function() {
+ timeframes = 0;
+ fps_mavg.clr();
+ idle_mavg.clr();
+ lastframetime = read_processor_time();
+ idletime = 0;
+ }
+
+ this.fpscounter = function() {
+ var hz = AMIGA.playfield.vblank_hz;
+
+ var now = read_processor_time();
+ var last = now - lastframetime;
+ lastframetime = now;
+
+ if (AMIGA.config.video.framerate > 1) {
+ last <<= 1;
+ hz /= 2;
+ }
+
+ fps_mavg.set(last / 10);
+ idle_mavg.set(idletime / 10);
+ idletime = 0;
+
+ frametime += last;
+ timeframes++;
+
+ if ((timeframes & 7) == 0) {
+ var idle = 1000 - (idle_mavg.average == 0 ? 0.0 : idle_mavg.average * 1000.0 / vsynctimebase);
+ var fps = fps_mavg.average == 0 ? 0 : SYNCBASE * 10 / fps_mavg.average;
+ if (fps > 9999) fps = 9999;
+ if (idle < 0) idle = 0;
+ if (idle > 100 * 10) idle = 100 * 10;
+ if (hz * 10 > fps) idle *= (hz * 10 / fps);
+
+ if ((timeframes & 15) == 0) {
+ AMIGA.config.hooks.fps(Math.round(fps * 0.1));
+ AMIGA.config.hooks.cpu(Math.round(idle * 0.1));
+ }
+ }
+ }
+
/*---------------------------------*/
- this.vSyncPre = function() {
- if (counter.bogus > 0)
- counter.bogus--;
+ this.hsync_handler_pre = function(onvsync) {
+ var hpos = this.hpos();
+ AMIGA.copper.sync_copper_with_cpu(AMIGA.playfield.maxhpos, 0);
+ AMIGA.playfield.hsync_handler_pre();
+ AMIGA.disk.hsync();
+ if (AMIGA.config.audio.enabled)
+ AMIGA.audio.hsync();
+ //AMIGA.cia.hsync_prehandler(); //empty
+ //hsync_counter++;
+ AMIGA.playfield.hsync_handler_pre_next_vpos(onvsync);
- AMIGA.cia.vSyncPre();
+ this.eventtab[EV_HSYNC].evtime = this.currcycle + AMIGA.playfield.maxhpos * CYCLE_UNIT;
+ this.eventtab[EV_HSYNC].oldcycles = this.currcycle;
+ }
+
+ this.vsync_handler_pre = function() {
+ //AMIGA.audio.vsync(); //empty
+ AMIGA.cia.vsync_prehandler();
if (!vsync_rendered) {
- var start = new Date().getTime();
- if (AMIGA.config.video.enabled) {
- AMIGA.playfield.vSync();
- if (AMIGA.config.video.skip) this.testFrameSkip();
- }
- frameskiptime += new Date().getTime() - start;
+ var start = read_processor_time();
+ AMIGA.playfield.vsync_handle_redraw();
+ frameskiptime += read_processor_time() - start;
+ vsync_rendered = true;
}
-
this.framewait();
+ if (!frame_rendered)
+ frame_rendered = AMIGA.playfield.render_screen(false);
+ if (frame_rendered && !frame_shown)
+ frame_shown = AMIGA.playfield.show_screen();
+
this.fpscounter();
-
vsync_rendered = false;
+ frame_shown = false;
+ frame_rendered = false;
+
+ AMIGA.playfield.checklacecount(null);
}
- this.vSyncPost = function() {
- AMIGA.disk.vsync();
+ var cia_hsync = 256;
+ this.hsync_handler_post = function(onvsync) {
+ AMIGA.copper.last_copper_hpos = 0;
+
+ var ciasyncs = !(AMIGA.playfield.bplcon0 & 2) || ((AMIGA.playfield.bplcon0 & 2) && AMIGA.config.chipset.genlock);
+ AMIGA.cia.hsync_posthandler(ciasyncs);
+ if (AMIGA.config.cia.tod > 0) {
+ cia_hsync -= 256;
+ if (cia_hsync <= 0) {
+ AMIGA.cia.vsync_posthandler(1);
+ cia_hsync += Math.floor((MAXVPOS_PAL * MAXHPOS_PAL * 50 * 256) / (AMIGA.playfield.maxhpos * (AMIGA.config.cia.tod == 2 ? 60 : 50)));
+ }
+ } else if (AMIGA.config.cia.tod == 0 && onvsync)
+ AMIGA.cia.vsync_posthandler(ciasyncs);
- if (AMIGA.playfield.bplcon0 & 4)
- this.lofStore = this.lofStore ? 0 : 1;
- this.lof = this.lofStore;
-
- //if ((this.beamcon0 & (0x20|0x80)) != (this.new_beamcon0 & (0x20|0x80)) || this.hack_vpos)
- //if ((this.beamcon0 & (0x20|0x80)) != (this.new_beamcon0 & (0x20|0x80)) || (abs (vpos_count - vpos_count_prev) > 1)) this.initHz();
- //if (this.lofChanged) this.compute_vsynctime();
-
- this.lofChanged = false;
-
- AMIGA.copper.COPJMP(1, 1);
-
- if (!AMIGA.playfield.state.ilace || (AMIGA.playfield.state.ilace && this.lof == 1))
- AMIGA.state = CMD_IDLE;
- }
-
- this.hSyncPre = function(isvsync) {
- AMIGA.copper.sync_copper_with_cpu(this.maxhpos, 0);
-
- if (AMIGA.config.video.enabled)
- AMIGA.playfield.hSync();
-
- AMIGA.disk.hsync();
-
- if (AMIGA.config.audio.enabled)
- AMIGA.audio.hsync();
-
- //AMIGA.cia.hSyncPre(); //empty
-
- if (AMIGA.config.video.ntsc) {
- this.lol ^= 1;
- this.maxhpos = 227 + this.lol;
- } else {
- this.lol = 0;
- this.maxhpos = 227;
- }
- this.vpos++;
- if (isvsync)
- this.vpos = 0;
-
- AMIGA.playfield.sprites.clear();
-
- this.eventtab[EV_HSYNC].oldcycles = this.currcycle;
- this.eventtab[EV_HSYNC].evtime = this.maxhpos * CYCLE_UNIT + this.currcycle;
- }
-
- this.hSyncPost = function(isvsync) {
- AMIGA.cia.hSyncPost(1);
- if (isvsync)
- AMIGA.cia.vSyncPost(1);
-
+ AMIGA.playfield.hsync_handler_post();
AMIGA.custom.last_value = 0xffff;
- //if (!AMIGA.config.blitter.exact && AMIGA.blitter.getState() != BLT_done && AMIGA.dmaen(DMAF_BPLEN))// && diwstate == DIW_waiting_stop) AMIGA.blitter.slowdown();
-
- if (isvsync) {
- this.vpos = 0;
- this.vSyncPost();
- }
-
- if (AMIGA.config.chipset.agnus == AGNUS_8361) {
- if (this.vpos == 1)
- AMIGA.send_interrupt(5, 1 * CYCLE_UNIT);
- } else {
- if (this.vpos == 0)
- AMIGA.send_interrupt(5, 1 * CYCLE_UNIT);
- }
+ if (!AMIGA.config.blitter.immediate && AMIGA.blitter.getState() != BLT_done && AMIGA.dmaen(DMAF_BPLEN) && AMIGA.playfield.getDiwstate() == DIW_WAITING_STOP)
+ AMIGA.blitter.slowdown();
- this.dmal_hsync();
-
- AMIGA.copper.reset2();
- //AMIGA.copper.check(2);
-
- this.framewait2();
-
- AMIGA.playfield.sprites.cycle(0);
-
- if (this.vpos + 1 == this.maxvpos + this.lof_store && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum && !vsync_rendered) {
- var start = new Date().getTime();
- if (AMIGA.config.video.enabled) {
- AMIGA.playfield.vSync();
- if (AMIGA.config.video.skip) this.testFrameSkip();
- }
- frameskiptime += new Date().getTime() - start;
- vsync_rendered = true;
- }
- }
-
- this.hSync = function() {
- var cvp = this.vpos + 1;
- var mvp = this.maxvpos + this.lofStore;
- var vsync = cvp == mvp || cvp == mvp + 1;
-
- this.hSyncPre(vsync);
- if (vsync)
- this.vSyncPre();
-
- this.hSyncPost(vsync);
- }
-
- /*---------------------------------*/
-
- this.GETVPOS = function() {
- return ((AMIGA.playfield.bplcon0 & 2) ? this.vpos_previous : this.vpos);
- }
- this.GETHPOS = function() {
- return ((AMIGA.playfield.bplcon0 & 2) ? this.hpos_previous : this.hpos());
- }
-
- this.VPOSR = function() {
- var chipset = 0;
-
- switch (AMIGA.config.chipset.agnus) {
- case AGNUS_8367:
- case AGNUS_8371:
- chipset = 0;
- break;
- case AGNUS_8361:
- case AGNUS_8370:
- chipset = 10;
- break;
- case AGNUS_8372: {
- if (AMIGA.config.chipset.agnus_rev <= 4)
- chipset = AMIGA.config.video.ntsc ? 30 : 20;
- else
- chipset = AMIGA.config.video.ntsc ? 31 : 21;
- break;
- }
- /*AGA
- case AGNUS_8374: {
- if (AMIGA.config.chipset.agnus_rev <= 2)
- chipset = AMIGA.config.video.ntsc ? 32 : 22;
- else
- chipset = AMIGA.config.video.ntsc ? 33 : 23;
- break;
+ if (onvsync) {
+ // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely
+ /*if ((AMIGA.playfield.bplcon0 & 8) && !lightpen_triggered) {
+ vpos_lpen = AMIGA.playfield.vpos - 1;
+ hpos_lpen = AMIGA.playfield.maxhpos;
+ lightpen_triggered = 1;
}*/
- }
- var vp = this.GETVPOS();
- var hp = this.GETHPOS();
-
- if (hp + 3 >= this.maxhpos) {
- vp++;
- if (vp >= this.maxvpos + this.lofStore)
- vp = 0;
+ AMIGA.playfield.vpos = 0;
+ this.vsync_handler_post();
+ AMIGA.playfield.vpos_count = 0;
}
- vp = (vp >> 8) & 7;
- vp &= 1;
-
- //vp = (vp >> 8) & 1;
-
- var vpos = (this.lofStore << 15) | (chipset << 8) | (this.lol << 7) | vp;
-
- //BUG.info('Custom.VPOSR() vp %d, hp %d, vpos $%04x', this.vpos, this.hpos(), vpos);
- return vpos;
- }
-
- this.VPOSW = function (v) {
- //BUG.info('Custom.VPOSW() $%04x', v);
-
- if (this.lofStore != ((v & 0x8000) ? 1 : 0)) {
- this.lofChanged = true;
- this.lofStore = (v & 0x8000) ? 1 : 0;
+ if (AMIGA.config.chipset.agnus_dip) {
+ if (AMIGA.playfield.vpos == 1)
+ AMIGA.INTREQ_0(INT_VERTB);
+ } else {
+ if (AMIGA.playfield.vpos == 0)
+ AMIGA.INTREQ_0(INT_VERTB);
}
- if (AMIGA.config.video.ntsc)
- this.lol = (v & 0x0080) ? 1 : 0;
+ this.dmal_hsync();
+ this.framewait2();
+ AMIGA.playfield.hsync_handler_post_nextline_how();
+ AMIGA.copper.reset2();
- if (this.lofChanged)
- return;
-
- this.vpos &= 0x00ff;
- this.vpos |= ((v & 1) << 8);
+ if (CUSTOM_SIMPLE)
+ AMIGA.playfield.do_sprites(0);
+
+ //AMIGA.copper.check(2);
+ AMIGA.playfield.hsync_handler_post_diw_change();
}
-
- this.VHPOSW = function (v) {
- //BUG.info('Custom.VHPOSW() $%04x', v);
-
- this.vpos &= 0xff00;
- this.vpos |= (v >> 8);
- }
-
- this.VHPOSR = function() {
- var vp = this.GETVPOS();
- var hp = this.GETHPOS();
-
- if (hp >= this.maxhpos) {
- //console.log(hp);
- hp -= this.maxhpos;
- vp++;
- if (vp >= this.maxvpos + this.lofStore)
- vp = 0;
- }
- hp += 1;
- if (hp >= this.maxhpos)
- hp -= this.maxhpos;
-
- var vhpos = ((vp & 0xff) << 8) | ((hp >> 1) & 0xff);
-
- //BUG.info('Custom.VHPOSR() vp %d, hp %d, vhpos $%04x', vp, hp, vhpos);
- return vhpos;
- }
- this.BEAMCON0 = function (v) {
- BUG.info('BEAMCON0() $%04x', v);
+ this.vsync_handler_post = function() {
+ //if ((AMIGA.intreq & 0x0020) && (AMIGA.intena & 0x0020)) BUG.info('vblank interrupt not cleared');
+ AMIGA.disk.vsync();
+ AMIGA.playfield.vsync_handler_post();
}
+
+ this.hsync_handler = function() {
+ var vs = AMIGA.playfield.is_custom_vsync();
+ this.hsync_handler_pre(vs);
+ if (vs) {
+ this.vsync_handler_pre();
+
+ if (AMIGA.config.video.framerate > 1) {
+ if (AMIGA.playfield.framecnt == AMIGA.config.video.framerate - 1) {
+ //vsyncresume = true;
+ //throw new VSync(0, 'vsync');
+ AMIGA.state = ST_IDLE;
+ }
+ } else {
+ //vsyncresume = true;
+ //throw new VSync(0, 'vsync');
+ AMIGA.state = ST_IDLE;
+ }
+ }
+ this.hsync_handler_post(vs);
+ }
}
diff --git a/sae/input.js b/sae/input.js
index 43c38c2..9035c55 100644
--- a/sae/input.js
+++ b/sae/input.js
@@ -666,9 +666,10 @@ function Keyboard() {
}
this.keyReq = function() {
- this.lostsynccnt = 8 * AMIGA.events.maxvpos * 8; /* 8 frames * 8 bits */
+ this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; /* 8 frames * 8 bits */
- AMIGA.cia.setICR(CIA_A, 8, code);
+ //AMIGA.cia.setICR(CIA_A, 8, code);
+ AMIGA.cia.SetICRA(8, code);
}
this.hsync = function() {
@@ -696,7 +697,7 @@ function Keyboard() {
this.vsync = function() {
if (this.lostsynccnt > 0) {
- this.lostsynccnt -= AMIGA.events.maxvpos;
+ this.lostsynccnt -= AMIGA.playfield.maxvpos;
if (this.lostsynccnt <= 0) {
this.lostsynccnt = 0;
this.keyReq();
diff --git a/sae/memory.js b/sae/memory.js
index 6afc7fb..343b325 100644
--- a/sae/memory.js
+++ b/sae/memory.js
@@ -197,14 +197,15 @@ function Memory() {
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;
- AMIGA.mem.copy_rom(AMIGA.config.rom.data);
+ this.copy_rom(AMIGA.config.rom.data);
if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) {
if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0)
- AMIGA.mem.copy_e0(AMIGA.config.ext.data);
+ this.copy_e0(AMIGA.config.ext.data);
else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0)
- AMIGA.mem.copy_f0(AMIGA.config.ext.data);
+ this.copy_f0(AMIGA.config.ext.data);
}
+ //this.mirror_rom_to_chipram();
/*if (AMIGA.config.rom.mode == 1) {
if (!this.aros.cached) {
@@ -281,7 +282,7 @@ function Memory() {
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_d0.data[(addr - this.res_d0.lower) >>> 1] & 0xff) : (this.res_d0.data[(addr - this.res_d0.lower) >>> 1] >> 8);
+ 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);
@@ -325,7 +326,7 @@ function Memory() {
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_d0.data[(addr - this.res_d0.lower) >>> 1];
+ return this.res_d8.data[(addr - this.res_d8.lower) >>> 1];
}
//else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr);
@@ -372,8 +373,8 @@ function Memory() {
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_d0.lower) >>> 1;
- return ((this.res_d0.data[addr] << 16) | this.res_d0.data[addr + 1]) >>> 0;
+ 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);
@@ -442,11 +443,11 @@ function Memory() {
}
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
if (addr & 1) {
- addr = (addr - this.res_d0.lower) >>> 1;
- this.res_d0.data[addr] = (this.res_d0.data[addr] & 0xff00) | value;
+ addr = (addr - this.res_d8.lower) >>> 1;
+ this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value;
} else {
- addr = (addr - this.res_d0.lower) >>> 1;
- this.res_d0.data[addr] = (value << 8) | (this.res_d0.data[addr] & 0x00ff);
+ 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) {
@@ -486,7 +487,7 @@ function Memory() {
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_d0.data[(addr - this.res_d0.lower) >>> 1] = value;
+ 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);
}
@@ -532,9 +533,9 @@ function Memory() {
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_d0.lower) >>> 1;
- this.res_d0.data[addr] = value >>> 16;
- this.res_d0.data[addr + 1] = value & 0xffff;
+ 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);
}
@@ -555,7 +556,7 @@ function Memory() {
this.chip.data[addr >>> 1] = value;
AMIGA.custom.last_value = value;
} else BUG.info('store16_chip() ILLEGAL MEMORY ACCESS addr %x, value %x', addr, value);
- }*/
+ }
this.load16_chip = function (addr) {
if (addr < this.chip.size - 1)
AMIGA.custom.last_value = this.chip.data[addr >>> 1];
@@ -569,7 +570,7 @@ function Memory() {
this.chip.data[addr >>> 1] = AMIGA.custom.last_value = value;
else
AMIGA.custom.last_value = 0xffff;
- }
+ }*/
this.copy_rom = function(data) {
//BUG.info('copyrom() size %d', data.length);
@@ -640,13 +641,13 @@ function Memory() {
}
}
- /*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) {
+ /*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];
- }
- }*/
+ }*/
+ }
}
\ No newline at end of file
diff --git a/sae/playfield.js b/sae/playfield.js
index 223c010..c826ee3 100644
--- a/sae/playfield.js
+++ b/sae/playfield.js
@@ -6,214 +6,2927 @@
* ©2012 Rupert Hausberger
* Commercial use is prohibited.
*
+***************************************************************************
+* Notes:
+* - Portet from WinUAE 2.5.0
+* - AGA support is commented out.
+*
**************************************************************************/
-function Sprite(num) {
- this.num = num;
- this.pt = 0;
- this.pos = 0;
- this.ctl = 0;
- this.data = 0;
- this.datb = 0;
+function Playfield() {
+ function decision() {
+ this.plfleft = 0;
+ this.plfright = 0;
+ this.plflinelen = 0;
+ this.diwfirstword = 0;
+ this.diwlastword = 0;
+ this.ctable = 0;
+ this.bplcon0 = 0;
+ this.bplcon2 = 0;
+ this.bplcon3 = 0;
+/*#ifdef AGA
+ this.bplcon4 = 0;
+#endif*/
+ this.nr_planes = 0;
+ this.bplres = 0;
+ this.ehb_seen = false;
+ this.ham_seen = false;
+ this.ham_at_start = false;
- this.xpos = 0;
- this.vstart = 0;
- this.vstop = 0;
- this.armed = false;
- this.dmastate = 0;
- this.dmacycle = 0;
-}
+ this.clr = function() {
+ this.plfleft = 0;
+ this.plfright = 0;
+ this.plflinelen = 0;
+ this.diwfirstword = 0;
+ this.diwlastword = 0;
+ this.ctable = 0;
+ this.bplcon0 = 0;
+ this.bplcon2 = 0;
+ this.bplcon3 = 0;
+/*#ifdef AGA
+ this.bplcon4 = 0;
+#endif*/
+ this.nr_planes = 0;
+ this.bplres = 0;
+ this.ehb_seen = false;
+ this.ham_seen = false;
+ this.ham_at_start = false;
+ }
-function Sprites() {
- const MAX_SPRITES = 8;
+ this.set = function(src) {
+ this.plfleft = src.plfleft;
+ this.plfright = src.plfright;
+ this.plflinelen = src.plflinelen;
+ this.diwfirstword = src.diwfirstword;
+ this.diwlastword = src.diwlastword;
+ this.ctable = src.ctable;
+ this.bplcon0 = src.bplcon0;
+ this.bplcon2 = src.bplcon2;
+ this.bplcon3 = src.bplcon3;
+/*#ifdef AGA
+ this.bplcon4 = src.bplcon4;
+#endif*/
+ this.nr_planes = src.nr_planes;
+ this.bplres = src.bplres;
+ this.ehb_seen = src.ehb_seen;
+ this.ham_seen = src.ham_seen;
+ this.ham_at_start = src.ham_at_start;
+ }
+ }
+
+ function color_entry() {
+ this.color_regs_ecs = new Uint16Array(32);
+//#ifndef AGA
+ this.acolors = new Uint32Array(32);
+/*#else
+ this.acolors = new Uint32Array(256);
+ this.color_regs_aga = new Uint32Array(256);
+#endif*/
+ this.borderblank = false;
+ }
- this.sprite = new Array(MAX_SPRITES);
+ function color_change() {
+ this.linepos = 0;
+ this.regno = 0;
+ this.value = 0;
+
+ this.set = function(v) {
+ this.linepos = v.linepos;
+ this.regno = v.regno;
+ this.value = v.value;
+ }
+ this.cmp = function(v) {
+ return (this.linepos == v.linepos && this.regno == v.regno && this.value == v.value ? 0 : 1);
+ }
+ }
+
+ function draw_info() {
+ this.first_sprite_entry = 0;
+ this.last_sprite_entry = 0;
+ this.first_color_change = 0;
+ this.last_color_change = 0;
+ this.nr_color_changes = 0;
+ this.nr_sprites = 0;
+ }
+
+ function vidbuffer() {
+ this.rowbytes = 0; /* Bytes per row in the memory pointed at by bufmem. */
+ this.pixbytes = 0; /* Bytes per pixel. */
+ /* size of this buffer */
+ this.width_allocated = 0;
+ this.height_allocated = 0;
+ /* size of max visible image */
+ this.outwidth = 0;
+ this.outheight = 0;
+ /* nominal size of image for centering */
+ this.inwidth = 0;
+ this.inheight = 0;
+ /* same but doublescan multiplier included */
+ this.inwidth2 = 0;
+ this.inheight2 = 0;
+ /* extra width, chipset hpos extra in right border */
+ this.extrawidth = 0;
+
+ this.xoffset = 0; /* superhires pixels from left edge */
+ this.yoffset = 0; /* lines from top edge */
+ this.inxoffset = 0; /* positive if sync positioning */
+ this.inyoffset = 0;
+ }
+
+ /*---------------------------------*/
+ /* drawing */
+
+ const dblpfofs = [0, 2, 4, 8, 16, 32, 64, 128];
+
+ var dblpf_ms1 = new Uint8Array(256);
+ var dblpf_ms2 = new Uint8Array(256);
+ var dblpf_ms = new Uint8Array(256);
+ var dblpf_ind1 = new Uint8Array(256);
+ var dblpf_ind2 = new Uint8Array(256);
+ var dblpf_2nd1 = new Uint8Array(256);
+ var dblpf_2nd2 = new Uint8Array(256);
+
+ var linestate = new Uint8Array((MAXVPOS + 2) * 2 + 1); //[(MAXVPOS + 2) * 2 + 1];
+ for (var i = 0; i < linestate.length; i++)
+ linestate[i] = 0;
+
+ var line_data = []; //[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2];
+ for (var i = 0; i < (MAXVPOS + 2) * 2; i++) {
+ line_data[i] = [];
+ for (var j = 0; j < MAX_PLANES; j++) {
+ line_data[i][j] = new Uint32Array(MAX_WORDS_PER_LINE * 2);
+ for (var k = 0; k < MAX_WORDS_PER_LINE * 2; k++)
+ line_data[i][j][k] = 0;
+ }
+ }
+
+ var line_decisions = [];
+ for (var i = 0; i < 2 * (MAXVPOS + 2) + 1; i++)
+ line_decisions[i] = new decision();
+ var color_tables = [];
+ for (var i = 0; i < 2; i++) {
+ color_tables[i] = [];
+ for (var j = 0; j < COLOR_TABLE_SIZE; j++)
+ color_tables[i][j] = new color_entry();
+ }
+ var color_changes = [];
+ for (var i = 0; i < 2; i++) {
+ color_changes[i] = [];
+ for (var j = 0; j < MAX_REG_CHANGE; j++)
+ color_changes[i][j] = new color_change();
+ }
+ var line_drawinfo = [];
+ for (var i = 0; i < 2; i++) {
+ line_drawinfo[i] = [];
+ for (var j = 0; j < 2 * (MAXVPOS + 2) + 1; j++)
+ line_drawinfo[i][j] = new draw_info();
+ }
+
+ var gfxvidinfo = {
+ maxblocklines:0,
+ drawbuffer: new vidbuffer(),
+ gfx_resolution_reserved: 0, // reserved space for currprefs.hresolution
+ gfx_vresolution_reserved: 0, // reserved space for currprefs.hresolution
+ xchange: 0, /* how many superhires pixels in one pixel in buffer */
+ ychange: 0, /* how many interlaced lines in one line in buffer */
+ };
+
+ var xlinebuffer = new Uint32Array(MAX_PIXELS_PER_LINE);
+ for (var i = 0; i < xlinebuffer.length; i++) xlinebuffer[i] = 0;
+
+ var ham_linebuf = new Uint32Array(MAX_PIXELS_PER_LINE << 1);
+ for (var i = 0; i < ham_linebuf.length; i++) ham_linebuf[i] = 0;
+
+ var apixels = new Uint8Array(MAX_PIXELS_PER_LINE << 1);
+ for (var i = 0; i < apixels.length; i++) apixels[i] = 0;
+
+ var colors_for_drawing = new color_entry();
+ var current_colors = new color_entry();
+
+ var xcolors = new Uint32Array(4096);
+ for (var i = 0; i < xcolors.length; i++) xcolors[i] = 0;
+
+ var thisline_decision = new decision();
+ var thisline_changed = 0;
+
+ var amiga2aspect_line_map = null;
+ var native2amiga_line_map = null;
+
+ var curr_sprite_entries = null;
+ var prev_sprite_entries = null;
+ var curr_color_changes = null;
+ var prev_color_changes = null;
+ var curr_drawinfo = null;
+ var prev_drawinfo = null;
+ var curr_color_tables = null;
+ var prev_color_tables = null;
+ var current_change_set = 0;
+
+ var autoscale_bordercolors = 0;
+ var frame_redraw_necessary = 0;
+
+ var first_drawn_line = 0;
+ var last_drawn_line = 0;
+ var first_block_line = 0;
+ var last_block_line = 0;
+ var thisframe_first_drawn_line = 0;
+ var thisframe_last_drawn_line = 0;
+
+ var drawing_color_matches = -1;
+ var linedbl = 0, linedbld = 0;
+ var min_diwstart = 0;
+ var max_diwstop = 0;
+ var min_ypos_for_screen = 0;
+ var max_ypos_thisframe = 0;
+
+ var visible_left_border = 0;
+ var visible_right_border = 0;
+ var visible_left_start = 0;
+ var visible_right_stop = MAX_STOP;
+ var visible_top_start = 0;
+ var visible_bottom_stop = MAX_STOP;
+ var thisframe_y_adjust = 0;
+ var thisframe_y_adjust_real = 0;
+ var max_drawn_amiga_line = 0;
+ var linetoscr_x_adjust_bytes = 0;
+ var last_max_ypos = 0;
+ var extra_y_adjust = 0;
+ var center_reset = true;
+ this.framecnt = 0;
+ var last_redraw_point = 0;
+ var lores_shift = 0;
+
+ var dp_for_drawing = null;
+ var dip_for_drawing = null;
+ var hposblank = 0;
+ var bplxor = 0;
+
+ var playfield_start = 0, playfield_end = 0;
+ var real_playfield_start = 0, real_playfield_end = 0;
+ var linetoscr_diw_start = 0, linetoscr_diw_end = 0;
+ var native_ddf_left = 0, native_ddf_right = 0;
+
+ var unpainted = 0; /* How many pixels in window coordinates which are to the left of the left border. */
+ var pixels_offset = 0;
+ var src_pixel = 0, ham_src_pixel = 0;
+ var ham_decode_pixel = 0;
+ var ham_lastcolor = 0;
+
+ var next_color_change = 0;
+ var next_color_entry = 0;
+ var remembered_color_entry = -1;
+ var color_src_match = -1;
+ var color_dest_match = -1;
+ var color_compare_result = 0;
+
+ var res_shift = 0;
+ var bplres = 0;
+ var bplplanecnt = 0;
+ var bplham = false;
+ var bplehb = false;
+ var issprites = 0;
+ var ecsshres = false;
+ var plf1pri = 0;
+ var plf2pri = 0;
+ var plf_sprite_mask = 0;
+ var bpldualpf = false;
+ var bpldualpfpri = false;
+
+ /*---------------------------------*/
+ /* sprites */
+
+ function sprite() {
+ this.pt = 0;
+ this.xpos = 0;
+ this.vstart = 0;
+ this.vstop = 0;
+ this.dblscan = 0; /* AGA SSCAN2 */
+ this.armed = 0;
+ this.dmastate = 0;
+ this.dmacycle = 0;
+ this.ptxhpos = 0;
+
+ this.clr = function() {
+ this.pt = 0;
+ this.xpos = 0;
+ this.vstart = 0;
+ this.vstop = 0;
+ this.dblscan = 0;
+ this.armed = 0;
+ this.dmastate = 0;
+ this.dmacycle = 0;
+ this.ptxhpos = 0;
+ }
+ }
+
+ function sprite_entry() {
+ this.pos = 0;
+ this.max = 0;
+ this.first_pixel = 0;
+ this.has_attached = false;
+ }
+
+ function spritepixelsbuf() {
+ this.attach = 0;
+ this.stdata = 0;
+ this.data = 0;
+
+ this.clr = function() {
+ this.attach = 0;
+ this.stdata = 0;
+ this.data = 0;
+ }
+ }
+
+ var sprinit = false;
+ var sprtaba = new Uint32Array(256);
+ var sprtabb = new Uint32Array(256);
+ var sprite_ab_merge = new Uint32Array(256);
+ var sprclx = new Uint32Array(16);
+ var clxmask = new Uint32Array(16);
+
+ var sprite_offs = new Uint8Array(256);
+ var clxtab = new Uint32Array(256);
+
+ var spr = [];
for (var i = 0; i < MAX_SPRITES; i++)
- this.sprite[i] = new Sprite(i);
+ spr[i] = new sprite();
+
+ /*union sps_union {
+ uae_u8 bytes[MAX_SPR_PIXELS * 2];
+ uae_u32 words[MAX_SPR_PIXELS * 2 / 4];
+ };*/
+ var spixstate = new Uint8Array(MAX_SPR_PIXELS << 1);
+ var spixels = new Uint16Array(MAX_SPR_PIXELS << 1);
+ for (var i = 0; i < MAX_SPR_PIXELS << 1; i++)
+ spixstate[i] = spixels[i] = 0;
+
+ var sprite_entries = []; //[2][MAX_SPR_PIXELS / 16];
+ for (var i = 0; i < 2; i++) {
+ sprite_entries[i] = [];
+ for (var j = 0; j < MAX_SPR_PIXELS >> 4; j++)
+ sprite_entries[i][j] = new sprite_entry();
+ }
- var spr_data = [];
- var spr_state = [];
- var spr_attach = [];
+ var spritepixels = [];
+ for (var i = 0; i < MAX_PIXELS_PER_LINE; i++)
+ spritepixels[i] = new spritepixelsbuf();
- var dblpf_ms = null;
- var dblpf_ms1 = null;
- var dblpf_ms2 = null;
- var sprite_offs = null;
+ var sprctl = new Uint16Array(MAX_SPRITES);
+ var sprpos = new Uint16Array(MAX_SPRITES);
+ for (var i = 0; i < MAX_SPRITES; i++)
+ sprctl[i] = sprpos[i] = 0;
- var sprtabb = null;
- var sprtaba = null;
- var sprite_ab_merge = null;
- var sprclx = null;
- var clxmask = null;
+/*#ifdef AGA
+ //[MAX_SPRITES][4]
+ var sprdata = [];
+ var sprdatb = [];
+ for (var i = 0; i < MAX_SPRITES; i++) {
+ sprdata[i] = new Uint16Array(4);
+ sprdatb[i] = new Uint16Array(4);
+ for (var j = 0; j < 4; j++) {
+ sprdata[i][j] = 0;
+ sprdatb[i][j] = 0;
+ }
+ }
+#else*/
+ //[MAX_SPRITES][1]
+ var sprdata = [];
+ var sprdatb = [];
+ for (var i = 0; i < MAX_SPRITES; i++) {
+ sprdata[i] = new Uint16Array(1);
+ sprdatb[i] = new Uint16Array(1);
+ sprdata[i][0] = 0;
+ sprdatb[i][0] = 0;
+ }
+//#endif
- this.nr_armed = 0;
- var sprite_vblank_endline = 0;
- var sprite_mask = 0;
- //var sprite_minx, sprite_maxx;
-
- this.clxdat = 0;
- this.clxcon = 0;
+ var clxcon = 0;
var clxcon_bpl_enable = 0;
var clxcon_bpl_match = 0;
+ var clxcon2 = 0;
+ var clxdat = 0;
- this.init_sprite_tables = function() {
- //spr_data = new Array(800);
- //spr_state = new Array(800);
- //spr_attach = new Array(800);
+ var sprres = 0;
+ var nr_armed = 0;
- dblpf_ms = new Array(256);
- dblpf_ms1 = new Array(256);
- dblpf_ms2 = new Array(256);
- sprite_offs = new Array(256);
+ var sprite_buffer_res = 0;
+ var sprite_vblank_endline = VBLANK_SPRITE_PAL;
+ var sprite_minx = 0;
+ var sprite_maxx = 0;
+ var sprite_width = 0;
+ var sprite_first_x = 0;
+ var sprite_last_x = 0;
+
+ var sprite_0 = 0;
+ var sprite_0_width = 0;
+ var sprite_0_height = 0;
+ var sprite_0_doubled = 0;
+ var sprite_0_colors = [0,0,0,0];
- sprtaba = new Array(256);
- sprtabb = new Array(256);
- sprite_ab_merge = new Array(256);
+ var next_sprite_entry = 0;
+ var next_sprite_forced = 1;
+ var prev_next_sprite_entry = 0;
+ var last_sprite_point = 0;
+ //var magic_sprite_mask = 0xff;
+ /*---------------------------------*/
+ /* playfield */
+
+ var bplcon0 = 0;
+ var bplcon1 = 0;
+ var bplcon2 = 0;
+ var bplcon3 = 0;
+ var bplcon4 = 0;
+
+ var bpl1mod = 0;
+ var bpl2mod = 0;
+
+ var bplxdat = [0,0,0,0,0,0,0,0];
+ var bplpt = [0,0,0,0,0,0,0,0];
+ var bplptx = [0,0,0,0,0,0,0,0];
+
+ var diwstrt = 0;
+ var diwstop = 0;
+ var ddfstrt = 0;
+ var ddfstrt_old_hpos = -1;
+ var ddfstop = 0;
+ var ddf_change = 0;
+ var diwhigh = 0;
+ var diwhigh_written = false;
+
+ var hdiwstate = 0;
+
+ var beamcon0 = 0;
+ var new_beamcon0 = 0;
+
+ this.vpos = 0;
+ this.vpos_count = 0;
+ this.vpos_count_diff = 0;
+ this.hpos = function() {
+ return Math.floor((AMIGA.events.currcycle - AMIGA.events.eventtab[EV_HSYNC].oldcycles) * CYCLE_UNIT_INV);
+ }
+ var vpos_previous = 0;
+ var hpos_previous = 0;
+
+ this.maxvpos = MAXVPOS;
+ this.maxvpos_nom = MAXVPOS;
+ this.maxvpos_total = MAXVPOS;
+ this.maxhpos = MAXHPOS;
+ this.maxhpos_short = MAXHPOS;
+
+ this.lof_store = 0;
+ this.lof_current = 0;
+ this.lof_previous = 0;
+ this.lof_changed = 0;
+ this.lof_changing = 0;
+ this.lol = 0;
+
+ this.vblank_hz = 0;
+
+ var aga_mode = 0;
+ var direct_rgb = 0;
+
+ var prevbpl = []; //[2][MAXVPOS][8];
+ for (var i = 0; i < 2; i++) {
+ prevbpl[i] = [];
+ for (var j = 0; j < MAXVPOS; j++) {
+ prevbpl[i][j] = new Uint32Array(8);
+ for (var k = 0; k < 8; k++) {
+ prevbpl[i][j][k] = 0;
+ }
+ }
+ }
+
+ var scandoubled_line = 0;
+ var doublescan = 0;
+ var interlace_seen = 0;
+ var interlace_changed = 0;
+ var lof_togglecnt_nlace = 0;
+ var lof_togglecnt_lace = 0;
+ var nlace_cnt = 0;
+
+ var minfirstline = 0;
+ var equ_vblank_endline = 0;
+ var equ_vblank_toggle = false;
+
+ this.vtotal = MAXVPOS_PAL, this.htotal = MAXHPOS_PAL;
+ this.hsstop = 0, this.hbstrt = 0, this.hbstop = 0;
+ this.vsstop = 0, this.vbstrt = 0, this.vbstop = 0;
+ this.hsstrt = 0, this.vsstrt = 0, this.hcenter = 0;
+ var hsyncstartpos = 0;
+ var hsyncendpos = 0;
+
+ var diwstate = 0;
+ var ddfstate = 0;
+ var diw_change = 2;
+ var diw_hstrt = 0;
+ var diw_hstop = 0;
+ var diw_hcounter = 0;
+ var last_hdiw = 0;
+
+ var diwfirstword = 0;
+ var diwlastword = 0;
+ var plffirstline = 0;
+ var plflastline = 0;
+
+ var plfstrt = 0;
+ var plfstrt_sprite = 0;
+ var plfstrt_start = 0;
+ var plfstop = 0;
+
+ var plf_state = 0;
+
+ var nextline_how = 0;
+ var next_lineno = 0;
+ var prev_lineno = -1;
+
+ var first_bpl_vpos = 0;
+ var first_planes_vpos = 0;
+ var last_planes_vpos = 0;
+ var firstword_bplcon1 = 0;
+ var diwfirstword_total = 0;
+ var diwlastword_total = 0;
+ var ddffirstword_total = 0;
+ var ddflastword_total = 0;
+ var plffirstline_total = 0;
+ var plflastline_total = 0;
+
+ /*var lightpen_active = 0;
+ var lightpen_triggered = 0;
+ var lightpen_cx = 0;
+ var lightpen_cy = 0;
+ var lightpen_y1 = -1;
+ var lightpen_y2 = -1;
+ var vpos_lpen = 0;
+ var hpos_lpen = 0;*/
+
+ var bplcon0_d = 0;
+ var bplcon0_dd = 0;
+ var bplcon1_hpos = 0;
+ var bplcon1t = 0;
+ var bplcon1t2 = 0;
+
+ var badmode = 0;
+ var bplcon0_res = 0;
+ var bplcon0_planes = 0;
+ var bplcon0_planes_limit = 0;
+
+ var fmode = 0;
+ var fetchmode = 0;
+ var fetchunit = 0;
+ var fetchunit_mask = 0;
+ const fetchunits = [ 8,8,8,0, 16,8,8,0, 32,16,8,0 ];
+ var fetchstart = 0;
+ var fetchstart_shift = 0;
+ var fetchstart_mask = 0;
+ const fetchstarts = [ 3,2,1,0, 4,3,2,0, 5,4,3,0 ];
+ var fm_maxplane = 0;
+ var fm_maxplane_shift = 0;
+ const fm_maxplanes = [ 3,2,1,0, 3,3,2,0, 3,3,3,0 ];
+ var real_bitplane_number = []; //[3][3][9];
+
+ var fetch_state = 0;
+ var fetch_cycle = 0;
+ var fetch_modulo_cycle = 0;
+
+ const cycle_sequences = [[2,1,2,1,2,1,2,1], [4,2,3,1,4,2,3,1], [8,4,6,2,7,3,5,1]];
+ var cycle_diagram_shift = 0;
+ var cycle_diagram_table = null; //[3][3][9][32];
+ var cycle_diagram_free_cycles = []; //[3][3][9];
+ var cycle_diagram_total_cycles = []; //[3][3][9];
+ var curr_diagram = [];
+
+ var estimated_last_fetch_cycle = 0;
+
+ var bpldmasetuphpos = -1;
+ var bpldmasetupphase = 0;
+
+ var bpl1dat_written = false;
+ var bpl1dat_written_at_least_once = false;
+ var bpl1dat_early = false;
+ var plfleft_real = -1;
+
+ var out_nbits = 0;
+ var out_offs = 0;
+ var outword = new Uint32Array(MAX_PLANES);
+ var todisplay = []; //[MAX_PLANES][4];
+ for (var i = 0; i < MAX_PLANES; i++) {
+ todisplay[i] = new Uint32Array(4);
+ for (var j = 0; j < 4; j++)
+ todisplay[i][j] = 0;
+ }
+ var fetched = new Uint32Array(MAX_PLANES);
+ for (var i = 0; i < MAX_PLANES; i++)
+ fetched[i] = 0;
+/*#ifdef AGA
+ var fetched_aga0 = new Uint32Array(MAX_PLANES);
+ var fetched_aga1 = new Uint32Array(MAX_PLANES);
+#endif*/
+
+ var toscr_res = 0;
+ var toscr_nr_planes = 0;
+ var toscr_nr_planes2 = 0;
+ var toscr_delay1 = 0;
+ var toscr_delay2 = 0;
+ var toscr_nbits = 0;
+
+ //var fetchwidth = 0;
+ var delayoffset = 0;
+
+ var last_decide_line_hpos = -1;
+ var last_ddf_pix_hpos = -1;
+ var last_sprite_hpos = -1;
+ var last_fetch_hpos = -1;
+
+ /*-----------------------------------------------------------------------*/
+ /* common */
+ /*-----------------------------------------------------------------------*/
+
+ function RES_SHIFT(res) {
+ return res == RES_LORES ? 8 : (res == RES_HIRES ? 4 : 2);
+ }
+ function GET_RES_DENISE(con0) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE)) con0 &= ~0x40; // SUPERHIRES
+ return (con0 & 0x8000) ? RES_HIRES : ((con0 & 0x40) ? RES_SUPERHIRES : RES_LORES);
+ }
+ function GET_RES_AGNUS(con0) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) con0 &= ~0x40; // SUPERHIRES
+ return (con0 & 0x8000) ? RES_HIRES : ((con0 & 0x40) ? RES_SUPERHIRES : RES_LORES);
+ }
+ function GET_SPRITEWIDTH(fmode) {
+ return (((fmode >> 2) & 3) == 3 ? 64 : ((fmode >> 2) & 3) == 0 ? 16 : 32);
+ }
+ function GET_PLANES(con0) {
+ if ((con0 & 0x0010) && (con0 & 0x7000)) return 0; // >8 planes = 0 planes
+ if (con0 & 0x0010) return 8; // AGA 8-planes bit
+ return (con0 >> 12) & 7; // normal planes bits
+ }
+ function GET_PLANES_LIMIT(con0) {
+ var res = GET_RES_AGNUS(con0);
+ var planes = GET_PLANES(con0);
+ return real_bitplane_number[fetchmode][res][planes];
+ }
+
+ this.nodraw = function() {
+ return this.framecnt != 0;
+ }
+
+ this.doflickerfix = function() {
+ return AMIGA.config.video.vresolution && doublescan < 0 && this.vpos < MAXVPOS;
+ }
+
+ this.current_maxvpos = function() {
+ return this.maxvpos + (this.lof_store ? 1 : 0);
+ }
+
+ this.is_custom_vsync = function() {
+ var vp = this.vpos + 1;
+ var vpc = this.vpos_count + 1;
+ /* Agnus vpos counter keeps counting until it wraps around if VPOSW writes put it past maxvpos */
+ if (vp >= this.maxvpos_total)
+ vp = 0;
+ if (vp == this.maxvpos + this.lof_store || vp == this.maxvpos + this.lof_store + 1 || vpc >= MAXVPOS) {
+ // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely
+ return true;
+ }
+ return false;
+ }
+
+ this.is_linetoggle = function() {
+ if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ return true; //NTSC and !LOLDIS -> LOL toggles every line
+ else if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) && AMIGA.config.video.ntsc)
+ return true; //hardwired NTSC Agnus
+ return false;
+ }
+
+ this.is_last_line = function() {
+ return this.vpos + 1 == this.maxvpos + this.lof_store;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* drawing */
+ /*-----------------------------------------------------------------------*/
+
+ function setup_drawing_tables() {
for (var i = 0; i < 256; i++) {
var plane1 = ((i >> 0) & 1) | ((i >> 1) & 2) | ((i >> 2) & 4) | ((i >> 3) & 8);
var plane2 = ((i >> 1) & 1) | ((i >> 2) & 2) | ((i >> 3) & 4) | ((i >> 4) & 8);
- dblpf_ms[i] = i == 0 ? 16 : 8;
+ dblpf_2nd1[i] = plane1 == 0 && plane2 != 0;
+ dblpf_2nd2[i] = plane2 != 0;
+
+/*#ifdef AGA
+ dblpf_ind1_aga[i] = plane1 == 0 ? plane2 : plane1;
+ dblpf_ind2_aga[i] = plane2 == 0 ? plane1 : plane2;
+#endif*/
dblpf_ms1[i] = plane1 == 0 ? (plane2 == 0 ? 16 : 8) : 0;
dblpf_ms2[i] = plane2 == 0 ? (plane1 == 0 ? 16 : 0) : 8;
+ dblpf_ms[i] = i == 0 ? 16 : 8;
- sprite_offs[i] = (i & 15) ? 0 : 2;
-
- sprtaba[i] = ((((i >> 7) & 1) << 0) | (((i >> 6) & 1) << 2) | (((i >> 5) & 1) << 4) | (((i >> 4) & 1) << 6) | (((i >> 3) & 1) << 8) | (((i >> 2) & 1) << 10) | (((i >> 1) & 1) << 12) | (((i >> 0) & 1) << 14));
- sprtabb[i] = sprtaba[i] << 1;
- sprite_ab_merge[i] = (((i & 15) ? 1 : 0) | ((i & 240) ? 2 : 0));
- }
-
- sprclx = new Array(16);
- clxmask = new Array(16);
-
- for (var i = 0; i < 16; i++) {
- clxmask[i] = (((i & 1) ? 0xF : 0x3) | ((i & 2) ? 0xF0 : 0x30) | ((i & 4) ? 0xF00 : 0x300) | ((i & 8) ? 0xF000 : 0x3000));
- sprclx[i] = (((i & 0x3) == 0x3 ? 1 : 0) | ((i & 0x5) == 0x5 ? 2 : 0) | ((i & 0x9) == 0x9 ? 4 : 0) | ((i & 0x6) == 0x6 ? 8 : 0) | ((i & 0xA) == 0xA ? 16 : 0) | ((i & 0xC) == 0xC ? 32 : 0)) << 9;
+ if (plane2 > 0)
+ plane2 += 8;
+ dblpf_ind1[i] = i >= 128 ? i & 0x7F : (plane1 == 0 ? plane2 : plane1);
+ dblpf_ind2[i] = i >= 128 ? i & 0x7F : (plane2 == 0 ? plane1 : plane2);
}
}
- this.setup = function() {
- sprite_vblank_endline = AMIGA.config.video.ntsc ? 20 : 25;
+ this.recreate_aspect_maps = function() {
+ var i, h = gfxvidinfo.drawbuffer.height_allocated;
+ if (h == 0)
+ return;
+
+ linedbld = linedbl = AMIGA.config.video.vresolution;
+ if (doublescan > 0 && interlace_seen <= 0) {
+ linedbl = 0;
+ linedbld = 1;
+ }
- if (dblpf_ms == null) this.init_sprite_tables();
+ if (native2amiga_line_map) native2amiga_line_map = null;
+ if (amiga2aspect_line_map) amiga2aspect_line_map = null;
+
+ amiga2aspect_line_map = new Int32Array((MAXVPOS + 1) * 2 + 1);
+ native2amiga_line_map = new Int32Array(h);
+
+ var maxl = (MAXVPOS + 1) << linedbld;
+ min_ypos_for_screen = minfirstline << linedbl;
+ max_drawn_amiga_line = -1;
+ for (i = 0; i < maxl; i++) {
+ var v = i - min_ypos_for_screen;
+ if (v >= h && max_drawn_amiga_line < 0)
+ max_drawn_amiga_line = i - min_ypos_for_screen;
+ if (i < min_ypos_for_screen || v >= h)
+ v = -1;
+ amiga2aspect_line_map[i] = v;
+ }
+ if (max_drawn_amiga_line < 0)
+ max_drawn_amiga_line = maxl - min_ypos_for_screen;
+ max_drawn_amiga_line >>>= linedbl;
+
+ if (AMIGA.config.video.ycenter) {
+ extra_y_adjust = (h - (this.maxvpos_nom << linedbl)) >> 1;
+ if (extra_y_adjust < 0)
+ extra_y_adjust = 0;
+ }
+
+ for (i = 0; i < h; i++)
+ native2amiga_line_map[i] = -1;
+
+ for (i = maxl - 1; i >= min_ypos_for_screen; i--) {
+ if (amiga2aspect_line_map[i] == -1)
+ continue;
+ for (var j = amiga2aspect_line_map[i]; j < h && native2amiga_line_map[j] == -1; j++)
+ native2amiga_line_map[j] = i >> linedbl;
+ }
+
+ gfxvidinfo.xchange = 1 << (RES_MAX - AMIGA.config.video.hresolution);
+ gfxvidinfo.ychange = linedbl ? 1 : 2;
+
+ visible_left_start = 0;
+ visible_right_stop = MAX_STOP;
+ visible_top_start = 0;
+ visible_bottom_stop = MAX_STOP;
+ //console.log('recreate_aspect_maps', amiga2aspect_line_map, native2amiga_line_map);
+ }
+
+ /*---------------------------------*/
+
+ function xlinecheck(id, start, end) {
+ var xstart = start * gfxvidinfo.drawbuffer.pixbytes;
+ var xend = end * gfxvidinfo.drawbuffer.pixbytes;
+ var end1 = gfxvidinfo.drawbuffer.rowbytes * gfxvidinfo.drawbuffer.height;
+ var min = Math.floor(linetoscr_x_adjust_bytes / gfxvidinfo.drawbuffer.pixbytes);
+ var ok = 1;
+
+ if (xend > end1 || xstart >= end1)
+ ok = 0;
+ if ((xstart % gfxvidinfo.drawbuffer.rowbytes) >= gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes)
+ ok = 0;
+ if ((xend % gfxvidinfo.drawbuffer.rowbytes) >= gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes)
+ ok = 0;
+ if (xstart >= xend)
+ ok = 0;
+ if (xend - xstart > gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes)
+ ok = 0;
+
+ if (!ok) {
+ console.log(id, start, end, min);
+ BUG.info('xlinecheck() ERROR %d-%d (%dx%dx%d %d)',
+ start - min, end - min, gfxvidinfo.drawbuffer.width, gfxvidinfo.drawbuffer.height,
+ gfxvidinfo.drawbuffer.pixbytes, gfxvidinfo.drawbuffer.rowbytes);
+ }
+ }
+
+ /*---------------------------------*/
+
+ function max_diwlastword() {
+ return (0x1d4 - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift;
}
- this.cleanup = function() {}
- this.reset = function() {}
-
- this.clear = function() {
- spr_data = [];
- spr_state = [];
- spr_attach = [];
+ function xshift(x, shift) {
+ return shift < 0 ? x >> (-shift) : x << shift;
}
- this.setMask = function (pf1p, pf2p) {
- sprite_mask = 0xFFFF0000 << (4 * pf2p);
- sprite_mask &= 0xFFFFFFFF;
- sprite_mask |= (0x0000FFFF << (4 * pf1p)) & 0xFFFF;
- sprite_mask &= 0xFFFFFFFF;
+ function coord_hw_to_window_x(x) {
+ return (x - DISPLAY_LEFT_SHIFT) << lores_shift;
+ }
+ function coord_window_to_hw_x(x) {
+ return (x >> lores_shift) + DISPLAY_LEFT_SHIFT;
}
- this.render = function (pos, apixel) {
- if (!spr_data[pos]) return 0;
+ function coord_diw_to_window_x(x) {
+ return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift;
+ }
+ function coord_window_to_diw_x(x) {
+ return (x >> lores_shift) + DISPLAY_LEFT_SHIFT - DIW_DDF_OFFSET;
+ }
+
+ function coord_native_to_amiga_x(x) {
+ return xshift(x + visible_left_border, 1 - lores_shift) + 2 * DISPLAY_LEFT_SHIFT - 2 * DIW_DDF_OFFSET;
+ }
+ function coord_native_to_amiga_y(y) {
+ return native2amiga_line_map[y] + thisframe_y_adjust - minfirstline;
+ }
- var maskshift = AMIGA.playfield.state.dpf ? (AMIGA.playfield.state.pf2pri ? dblpf_ms2[apixel] : dblpf_ms1[apixel]) : dblpf_ms[apixel];
- var plfmask = (sprite_mask >>> maskshift) >>> maskshift;
- var v = spr_data[pos] & ~plfmask;
+ function res_shift_from_window(x) {
+ return res_shift >= 0 ? x >> res_shift : x << -res_shift;
+ }
+ function res_shift_from_amiga(x) {
+ return res_shift >= 0 ? x >> res_shift : x << -res_shift;
+ }
+
+ /*---------------------------------*/
+
+ this.render_screen = function(immediate) {
+ if (AMIGA.config.video.enabled)
+ AMIGA.video.render();
+ return true;
+ }
+ this.show_screen = function() {
+ if (AMIGA.config.video.enabled)
+ AMIGA.video.show(); //flip
+ return true;
+ }
+
+ /*function flush_line(vb, lineno) {
+ AMIGA.video.drawline(lineno, xlinebuffer, linetoscr_x_adjust_bytes >> 2);
+ }
+ function flush_block(vb, first_line, last_line) {
+ console.log('flush_block() called', first_line, last_line);
+ }
+ function flush_screen(vb, first_line, last_line) {
+ console.log('flush_screen() called', first_line, last_line);
+ }
+ this.do_flush_line = function(vb, lineno) {
+ if (lineno < first_drawn_line)
+ first_drawn_line = lineno;
+ if (lineno > last_drawn_line)
+ last_drawn_line = lineno;
- if (v != 0) {
- var v1 = v & 255;
- var offs;
- var col;
-
- if (v1 == 0) offs = sprite_offs[v >> 8] + 4;
- else offs = sprite_offs[v1];
-
- v = (v >> (offs << 1)) & 15;
- //v ^= 8; /* debug */
-
- if (spr_attach[pos] && (spr_state[pos] & (3 << offs))) {
- col = 16 + v;
- } else {
- var vlo = v & 3;
- var vhi = (v & (vlo - 1)) >> 2;
- col = 16 + (vlo | vhi) + offs * 2;
+ if (gfxvidinfo.maxblocklines == 0)
+ flush_line(vb, lineno);
+ else {
+ if ((last_block_line + 2) < lineno) {
+ if (first_block_line != NO_BLOCK)
+ flush_block(vb, first_block_line, last_block_line);
+ first_block_line = lineno;
+ }
+ last_block_line = lineno;
+ if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) {
+ flush_block(vb, first_block_line, last_block_line);
+ first_block_line = last_block_line = NO_BLOCK;
}
- return col;
}
- return 0;
+ }*/
+
+ this.do_flush_line = function(vb, lineno) {
+ if (lineno < first_drawn_line)
+ first_drawn_line = lineno;
+ if (lineno > last_drawn_line)
+ last_drawn_line = lineno;
+
+ AMIGA.video.drawline(lineno, xlinebuffer, linetoscr_x_adjust_bytes >> 2);
}
- this.spr_plf_collision = function() {
- if (clxcon_bpl_enable == 0) {
- this.clxdat |= 0x1fe;
+ /*this.do_flush_screen = function(vb, start, stop) {
+ if (gfxvidinfo.maxblocklines != 0 && first_block_line != NO_BLOCK)
+ flush_block(vb, first_block_line, last_block_line);
+ if (start <= stop)
+ flush_screen(vb, start, stop);
+ }*/
+
+ /*---------------------------------*/
+
+ function is_ehb(con0, con2) {
+ if (AMIGA.config.chipset.mask & CSMASK_AGA)
+ return ((con0 & 0x7010) == 0x6000);
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE)
+ return ((con0 & 0xFC00) == 0x6000 || (con0 & 0xFC00) == 0x7000);
+
+ return ((con0 & 0xFC00) == 0x6000 || (con0 & 0xFC00) == 0x7000);// && !currprefs.cs_denisenoehb;
+ }
+
+ function is_ham(con0) {
+ var p = GET_PLANES(con0);
+ if (!(con0 & 0x800))
+ return false;
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ // AGA only has 6 or 8 plane HAM
+ if (p == 6 || p == 8)
+ return true;
+ } else {
+ // OCS/ECS also supports 5 plane HAM
+ if (GET_RES_DENISE(con0) > 0)
+ return 0;
+ if (p >= 5)
+ return true;
+ }
+ return false;
+ }
+
+ /*function get_sprite_mask() {
+ var hi = new Uint64(0x00000000,0xFFFF0000);
+ hi.lshift(4 * plf2pri);
+ var lo = new Uint64(0x00000000,0x0000FFFF);
+ lo.lshift(4 * plf1pri);
+ hi.or(lo);
+ return hi;
+ }*/
+
+ this.pfield_expand_dp_bplcon = function() {
+ bplres = dp_for_drawing.bplres;
+ bplplanecnt = dp_for_drawing.nr_planes;
+ bplham = dp_for_drawing.ham_seen;
+ bplehb = dp_for_drawing.ehb_seen;
+ if ((AMIGA.config.chipset.mask & CSMASK_AGA) && (dp_for_drawing.bplcon2 & 0x0200))
+ bplehb = 0;
+ issprites = dip_for_drawing.nr_sprites;
+ ecsshres = bplres == RES_SUPERHIRES && (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) && !(AMIGA.config.chipset.mask & CSMASK_AGA);
+
+ plf1pri = dp_for_drawing.bplcon2 & 7;
+ plf2pri = (dp_for_drawing.bplcon2 >> 3) & 7;
+ plf_sprite_mask = 0xFFFF0000 << (4 * plf2pri);
+ plf_sprite_mask |= (0x0000FFFF << (4 * plf1pri)) & 0xFFFF;
+ plf_sprite_mask >>>= 0;
+ //plf_sprite_mask = get_sprite_mask();
+
+ bpldualpf = (dp_for_drawing.bplcon0 & 0x400) == 0x400;
+ bpldualpfpri = (dp_for_drawing.bplcon2 & 0x40) == 0x40;
+
+/*#ifdef AGA
+ bpldualpf2of = (dp_for_drawing.bplcon3 >> 10) & 7;
+ sbasecol[0] = ((dp_for_drawing.bplcon4 >> 4) & 15) << 4;
+ sbasecol[1] = ((dp_for_drawing.bplcon4 >> 0) & 15) << 4;
+ brdsprt = !brdblank && (AMIGA.config.chipset.mask & CSMASK_AGA) && (dp_for_drawing.bplcon0 & 1) && (dp_for_drawing.bplcon3 & 0x02);
+ bplxor = dp_for_drawing.bplcon4 >> 8;
+#endif*/
+ }
+
+ this.pfield_expand_dp_bplconx = function(regno, v) {
+ if (regno == 0xffff) {
+ //hposblank = 1; //FIXME
return;
}
- var collision_mask = clxmask[this.clxcon >> 12];
+ regno -= 0x1000;
+ switch (regno) {
+ case 0x100:
+ dp_for_drawing.bplcon0 = v;
+ dp_for_drawing.bplres = GET_RES_DENISE(v);
+ dp_for_drawing.nr_planes = GET_PLANES(v);
+ dp_for_drawing.ham_seen = is_ham(v);
+ break;
+ case 0x104:
+ dp_for_drawing.bplcon2 = v;
+ break;
+ case 0x106:
+ dp_for_drawing.bplcon3 = v;
+ break;
+/*#ifdef AGA
+ case 0x10c:
+ dp_for_drawing.bplcon4 = v;
+ break;
+#endif*/
+ }
+ this.pfield_expand_dp_bplcon();
+ res_shift = lores_shift - bplres;
+ }
+
+ this.center_image = function() {
+ var prev_x_adjust = visible_left_border;
+ var prev_y_adjust = thisframe_y_adjust;
+ var tmp;
- for (var i = 0; i < MAX_SPRITES; i++) {
- var sprxp = (this.sprite[i].xpos - AMIGA.playfield.state.hstart + 1) * (AMIGA.playfield.state.hires ? 2 : 1);
+ var w = gfxvidinfo.drawbuffer.inwidth;
+ if (AMIGA.config.video.xcenter && max_diwstop > 0) {
+ if (max_diwstop - min_diwstart < w && AMIGA.config.video.xcenter == 2)
+ /* Try to center. */
+ visible_left_border = ((max_diwstop - min_diwstart - w) >> 1) + min_diwstart;
+ else
+ visible_left_border = max_diwstop - w - ((max_diwstop - min_diwstart - w) >> 1);
+ visible_left_border &= ~((xshift(1, lores_shift)) - 1);
- if (!this.sprite[i].armed || sprxp < 0) continue;
+ /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */
+ if (AMIGA.config.video.xcenter == 2) {
+ if (center_reset || (visible_left_border < prev_x_adjust && prev_x_adjust < min_diwstart && min_diwstart - visible_left_border <= 32))
+ visible_left_border = prev_x_adjust;
+ }
+ } else if (gfxvidinfo.drawbuffer.extrawidth) {
+ visible_left_border = max_diwlastword() - w;
+ if (gfxvidinfo.drawbuffer.extrawidth > 0)
+ visible_left_border += gfxvidinfo.drawbuffer.extrawidth << AMIGA.config.video.hresolution;
+ } else {
+ if (gfxvidinfo.drawbuffer.inxoffset < 0) {
+ visible_left_border = 0;
+ } else {
+ visible_left_border = gfxvidinfo.drawbuffer.inxoffset - DISPLAY_LEFT_SHIFT;
+ }
+ }
- var minpos = sprxp;
- var maxpos = sprxp + 16;
+ if (visible_left_border > max_diwlastword() - 32)
+ visible_left_border = max_diwlastword() - 32;
+ if (visible_left_border < 0)
+ visible_left_border = 0;
+ visible_left_border &= ~((xshift(1, lores_shift)) - 1);
+
+ linetoscr_x_adjust_bytes = visible_left_border * gfxvidinfo.drawbuffer.pixbytes;
- for (var j = minpos; j < maxpos; j++) {
- var sprpix = spr_data[j] & collision_mask;
- var match = 1;
+ visible_right_border = visible_left_border + w;
+ if (visible_right_border > max_diwlastword())
+ visible_right_border = max_diwlastword();
- if (sprpix == 0) continue;
+ thisframe_y_adjust = minfirstline;
+ if (AMIGA.config.video.ycenter && thisframe_first_drawn_line >= 0) {
+ if (thisframe_last_drawn_line - thisframe_first_drawn_line < max_drawn_amiga_line && AMIGA.config.video.ycenter == 2)
+ thisframe_y_adjust = ((thisframe_last_drawn_line - thisframe_first_drawn_line - max_drawn_amiga_line) >> 1) + thisframe_first_drawn_line;
+ else
+ thisframe_y_adjust = thisframe_first_drawn_line + (((thisframe_last_drawn_line - thisframe_first_drawn_line) - max_drawn_amiga_line) >> 1);
- sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2);
- sprpix <<= 1;
+ if (AMIGA.config.video.ycenter == 2) {
+ if (center_reset || (thisframe_y_adjust != prev_y_adjust
+ && prev_y_adjust <= thisframe_first_drawn_line
+ && prev_y_adjust + max_drawn_amiga_line > thisframe_last_drawn_line))
+ thisframe_y_adjust = prev_y_adjust;
+ }
+ }
+ if (thisframe_y_adjust + max_drawn_amiga_line > this.maxvpos_nom)
+ thisframe_y_adjust = this.maxvpos_nom - max_drawn_amiga_line;
+ if (thisframe_y_adjust < minfirstline)
+ thisframe_y_adjust = minfirstline;
- for (var k = 1; k >= 0; k--) {
- if (AMIGA.playfield.bplcon0 & 0x400) match = 1;
+ thisframe_y_adjust_real = thisframe_y_adjust << linedbl;
+ tmp = (this.maxvpos_nom - thisframe_y_adjust + 1) << linedbl;
+ if (tmp != max_ypos_thisframe) {
+ last_max_ypos = tmp;
+ if (last_max_ypos < 0)
+ last_max_ypos = 0;
+ }
+ max_ypos_thisframe = tmp;
- for (var l = k; match && l < 6; l += 2) {
- if (clxcon_bpl_enable & (1 << l)) {
- var t = 0;
- if (l < AMIGA.playfield.state.planes) {
- t = (AMIGA.playfield.linedata[j] >> l) & 1;
- }
- if (t != ((clxcon_bpl_match >> l) & 1)) match = 0;
- }
+ if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust)
+ frame_redraw_necessary |= (interlace_seen > 0 && linedbl) ? 2 : 1;
+
+ max_diwstop = 0;
+ min_diwstart = MAX_STOP;
+
+ gfxvidinfo.drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - AMIGA.config.video.hresolution));
+ gfxvidinfo.drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX;
+
+ center_reset = false;
+ }
+
+ /*---------------------------------*/
+
+ const COLOR_MATCH_ACOLORS = 1;
+ const COLOR_MATCH_FULL = 2;
+ var color_match_type = 0;
+
+ this.adjust_drawing_colors = function(ctable, need_full) {
+ if (FAST_COLORS) {
+ if (need_full)
+ color_reg_cpy(colors_for_drawing, current_colors);
+ else
+ color_reg_cpy_acolors(colors_for_drawing, current_colors);
+ return;
+ }
+ if (drawing_color_matches != ctable) {
+ if (need_full) {
+ color_reg_cpy(colors_for_drawing, curr_color_tables[ctable]);
+ color_match_type = COLOR_MATCH_FULL;
+ } else {
+ //memcpy (colors_for_drawing.acolors, curr_color_tables[ctable].acolors, sizeof colors_for_drawing.acolors);
+ //for (var i = 0; i < colors_for_drawing.acolors.length; i++) colors_for_drawing.acolors[i] = curr_color_tables[ctable].acolors[i]; colors_for_drawing.borderblank = curr_color_tables[ctable].borderblank;
+ color_reg_cpy_acolors(colors_for_drawing, curr_color_tables[ctable]);
+ color_match_type = COLOR_MATCH_ACOLORS;
+ }
+ drawing_color_matches = ctable;
+ }
+ else if (need_full && color_match_type != COLOR_MATCH_FULL) {
+ color_reg_cpy(colors_for_drawing, curr_color_tables[ctable]);
+ color_match_type = COLOR_MATCH_FULL;
+ }
+ }
+
+ this.do_color_changes = function(worker_border, worker_pfield, vp) {
+ var lastpos = visible_left_border;
+ var endpos = visible_left_border + gfxvidinfo.drawbuffer.inwidth;
+
+ for (var i = dip_for_drawing.first_color_change; i <= dip_for_drawing.last_color_change; i++) {
+ var regno = curr_color_changes[i].regno;
+ var value = curr_color_changes[i].value;
+ var nextpos, nextpos_in_range;
+
+ if (i == dip_for_drawing.last_color_change)
+ nextpos = endpos;
+ else
+ nextpos = coord_hw_to_window_x(curr_color_changes[i].linepos);
+
+ nextpos_in_range = nextpos;
+ if (nextpos > endpos)
+ nextpos_in_range = endpos;
+
+ if (nextpos_in_range > lastpos) {
+ if (lastpos < playfield_start) {
+ var t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start;
+ worker_border(lastpos, t, false);
+ lastpos = t;
+ }
+ }
+ if (nextpos_in_range > lastpos) {
+ if (lastpos >= playfield_start && lastpos < playfield_end) {
+ var t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
+ worker_pfield(lastpos, t, false);
+ // blank start and end that shouldn't be visible
+ if (lastpos < visible_left_start)
+ worker_border(lastpos, visible_left_start, true);
+ if (t > visible_right_stop)
+ worker_border(visible_right_stop, endpos, true);
+ lastpos = t;
+ }
+ }
+ if (nextpos_in_range > lastpos) {
+ if (lastpos >= playfield_end)
+ worker_border(lastpos, nextpos_in_range, false);
+ lastpos = nextpos_in_range;
+ }
+
+ if (regno >= 0x1000)
+ this.pfield_expand_dp_bplconx(regno, value);
+ else if (regno >= 0) {
+ if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK))
+ colors_for_drawing.borderblank = (value & 1) != 0;
+ else {
+ color_reg_set(colors_for_drawing, regno, value);
+ colors_for_drawing.acolors[regno] = getxcolor(value);
+ }
+ }
+ if (lastpos >= endpos)
+ break;
+ }
+ if (vp < visible_top_start || vp >= visible_bottom_stop) {
+ // outside of visible area
+ // Just overwrite with black. Above code needs to run because of custom registers,
+ // not worth the trouble for separate code path just for max 10 lines or so
+ worker_border(visible_left_border, visible_left_border + gfxvidinfo.drawbuffer.inwidth, true);
+ }
+ }
+
+ /*---------------------------------*/
+
+ function getbgc(blank) {
+/*#if 0
+ if (blank)
+ return xcolors[0x088];
+ else if (hposblank == 1)
+ return xcolors[0xf00];
+ else if (hposblank == 2)
+ return xcolors[0x0f0];
+ else if (hposblank == 3)
+ return xcolors[0x00f];
+ else if (brdblank)
+ return xcolors[0x880];
+ //return colors_for_drawing.acolors[0];
+ return xcolors[0xf0f];
+#endif*/
+ return (blank || hposblank || colors_for_drawing.borderblank) ? 0 : colors_for_drawing.acolors[0];
+ }
+
+ function fill_line_16(buf, start, stop, blank) {
+ console.log('fill_line_16() NI', start, stop, blank);
+ /*uae_u16 *b = (uae_u16 *)buf;
+ var rem = 0;
+ var col = getbgc(blank);
+
+ if (((long)&b[start]) & 1)
+ b[start++] = (uae_u16) col;
+
+ if (start >= stop)
+ return;
+
+ if (((long)&b[stop]) & 1) {
+ rem++;
+ stop--;
+ }
+ for (var i = start; i < stop; i += 2) {
+ uae_u32 *b2 = (uae_u32 *)&b[i];
+ *b2 = col;
+ }
+ if (rem)
+ b[stop] = (uae_u16)col;*/
+ }
+ function fill_line_32(buf, start, stop, blank) {
+ var col = getbgc(blank);
+ for (var i = start; i < stop; i++)
+ buf[i] = col;
+ }
+
+ function pfield_do_fill_line2(start, stop, blank) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: fill_line_16(xlinebuffer, start, stop, blank); break;
+ case 4: fill_line_32(xlinebuffer, start, stop, blank); break;
+ }
+ }
+ function pfield_do_fill_line(start, stop, blank) {
+ //console.log('pfield_do_fill_line()', start, stop, blank);
+ //xlinecheck('pfield_do_fill_line', start, stop);
+ if (!blank) {
+ if (start < visible_left_start) {
+ pfield_do_fill_line2(start, visible_left_start, true);
+ start = visible_left_start;
+ }
+ if (stop > visible_right_stop) {
+ pfield_do_fill_line2(start, visible_right_stop, false);
+ blank = true;
+ start = visible_right_stop;
+ }
+ }
+ pfield_do_fill_line2(start, stop, blank);
+ }
+
+ function fill_line2(startpos, len) {
+ //console.log('fill_line2', startpos, len);
+ var shift = 0;
+ if (gfxvidinfo.drawbuffer.pixbytes == 2) shift = 1;
+ if (gfxvidinfo.drawbuffer.pixbytes == 4) shift = 2;
+
+ var nints = len;// >> (2 - shift);
+ var nrem = nints & 7;
+ nints &= ~7;
+ //int *start = (int *)(((uae_u8*)xlinebuffer) + (startpos << shift));
+ var start = startpos;// << shift >> 2;
+ var val = getbgc(false);
+
+ /*for (; nints > 0; nints -= 8, start += 8) {
+ *start = val;
+ *(start+1) = val;
+ *(start+2) = val;
+ *(start+3) = val;
+ *(start+4) = val;
+ *(start+5) = val;
+ *(start+6) = val;
+ *(start+7) = val;
+ }
+ switch (nrem) {
+ case 7: *start++ = val;
+ case 6: *start++ = val;
+ case 5: *start++ = val;
+ case 4: *start++ = val;
+ case 3: *start++ = val;
+ case 2: *start++ = val;
+ case 1: *start = val;
+ }*/
+
+ for (; nints > 0; nints -= 8, start += 8) {
+ xlinebuffer[start ] = val;
+ xlinebuffer[start + 1] = val;
+ xlinebuffer[start + 2] = val;
+ xlinebuffer[start + 3] = val;
+ xlinebuffer[start + 4] = val;
+ xlinebuffer[start + 5] = val;
+ xlinebuffer[start + 6] = val;
+ xlinebuffer[start + 7] = val;
+ }
+ switch (nrem) {
+ case 7: xlinebuffer[start++] = val;
+ case 6: xlinebuffer[start++] = val;
+ case 5: xlinebuffer[start++] = val;
+ case 4: xlinebuffer[start++] = val;
+ case 3: xlinebuffer[start++] = val;
+ case 2: xlinebuffer[start++] = val;
+ case 1: xlinebuffer[start] = val;
+ }
+ }
+ function fill_line() {
+ var hs = coord_hw_to_window_x(hsyncstartpos * 2);
+ if (hs >= gfxvidinfo.drawbuffer.inwidth || hposblank) {
+ //hposblank = 3; //FIXME
+ fill_line2(visible_left_border, gfxvidinfo.drawbuffer.inwidth);
+ } else {
+ fill_line2(visible_left_border, hs);
+ //hposblank = 2; //FIXME
+ fill_line2(visible_left_border + hs, gfxvidinfo.drawbuffer.inwidth);
+ }
+ }
+
+ /*---------------------------------*/
+
+ this.pfield_init_linetoscr = function() {
+ var ddf_left = dp_for_drawing.plfleft * 2 + DIW_DDF_OFFSET;
+ var ddf_right = dp_for_drawing.plfright * 2 + DIW_DDF_OFFSET;
+
+ native_ddf_left = coord_hw_to_window_x(ddf_left);
+ native_ddf_right = coord_hw_to_window_x(ddf_right);
+
+ linetoscr_diw_start = dp_for_drawing.diwfirstword;
+ linetoscr_diw_end = dp_for_drawing.diwlastword;
+
+ res_shift = lores_shift - bplres;
+
+ if (dip_for_drawing.nr_sprites == 0) {
+ if (linetoscr_diw_start < native_ddf_left)
+ linetoscr_diw_start = native_ddf_left;
+ if (linetoscr_diw_end > native_ddf_right)
+ linetoscr_diw_end = native_ddf_right;
+ }
+ if (linetoscr_diw_end < linetoscr_diw_start)
+ linetoscr_diw_end = linetoscr_diw_start;
+
+ playfield_start = linetoscr_diw_start;
+ playfield_end = linetoscr_diw_end;
+
+ unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start;
+ ham_src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window(playfield_start - native_ddf_left);
+ unpainted = res_shift_from_window(unpainted);
+
+ if (playfield_start < visible_left_border)
+ playfield_start = visible_left_border;
+ if (playfield_start > visible_right_border)
+ playfield_start = visible_right_border;
+ if (playfield_end < visible_left_border)
+ playfield_end = visible_left_border;
+ if (playfield_end > visible_right_border)
+ playfield_end = visible_right_border;
+
+ real_playfield_end = playfield_end;
+ real_playfield_start = playfield_start;
+
+/*#ifdef AGA
+ if (brdsprt && dip_for_drawing.nr_sprites) {
+ var min = visible_right_border, max = visible_left_border, i;
+ for (i = 0; i < dip_for_drawing.nr_sprites; i++) {
+ var x;
+ x = curr_sprite_entries[dip_for_drawing.first_sprite_entry + i].pos;
+ if (x < min)
+ min = x;
+ x = curr_sprite_entries[dip_for_drawing.first_sprite_entry + i].max;
+ if (x > max)
+ max = x;
+ }
+ min = coord_hw_to_window_x (min >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift);
+ max = coord_hw_to_window_x (max >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift);
+ if (min < playfield_start)
+ playfield_start = min;
+ if (playfield_start < visible_left_border)
+ playfield_start = visible_left_border;
+ if (max > playfield_end)
+ playfield_end = max;
+ if (playfield_end > visible_right_border)
+ playfield_end = visible_right_border;
+ }
+#endif*/
+
+ if (sprite_first_x < sprite_last_x) {
+ if (sprite_first_x < 0)
+ sprite_first_x = 0;
+ if (sprite_last_x >= MAX_PIXELS_PER_LINE - 1)
+ sprite_last_x = MAX_PIXELS_PER_LINE - 2;
+ if (sprite_first_x < sprite_last_x) {
+ //memset (spritepixels + sprite_first_x, 0, sizeof (struct spritepixelsbuf) * (sprite_last_x - sprite_first_x + 1));
+ for (var i = sprite_first_x; i <= sprite_last_x; i++) {
+ spritepixels[i].clr();
+ }
+ }
+ }
+ sprite_last_x = 0;
+ sprite_first_x = MAX_PIXELS_PER_LINE - 1;
+
+ ddf_left -= DISPLAY_LEFT_SHIFT;
+ pixels_offset = MAX_PIXELS_PER_LINE - (ddf_left << bplres);
+ ddf_left <<= bplres;
+ src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window(playfield_start - native_ddf_left);
+
+ if (dip_for_drawing.nr_sprites == 0)
+ return;
+
+ /* Must clear parts of apixels. */
+ if (linetoscr_diw_start < native_ddf_left) {
+ var size = res_shift_from_window(native_ddf_left - linetoscr_diw_start);
+ linetoscr_diw_start = native_ddf_left;
+ //memset (apixels + MAX_PIXELS_PER_LINE - size, 0, size);
+ for (var i = 0; i < size; i++) {
+ apixels[MAX_PIXELS_PER_LINE - size + i] = 0;
+ }
+ }
+ if (linetoscr_diw_end > native_ddf_right) {
+ var pos = res_shift_from_window(native_ddf_right - native_ddf_left);
+ var size = res_shift_from_window(linetoscr_diw_end - native_ddf_right);
+ linetoscr_diw_start = native_ddf_left;
+ //memset (apixels + MAX_PIXELS_PER_LINE + pos, 0, size);
+ for (var i = 0; i < size; i++) {
+ apixels[MAX_PIXELS_PER_LINE + pos + i] = 0;
+ }
+ }
+ }
+
+ function dummy_worker(start, stop, blank) { }
+
+
+ function linetoscr_32(spix, dpix, stoppos) {
+ //uae_u32 *buf = (uae_u32 *) xlinebuffer;
+ var buf = xlinebuffer;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ }
+
+ return spix;
+ }
+
+ function linetoscr_32_stretch1(spix, dpix, stoppos) {
+ //uae_u32 *buf = (uae_u32 *) xlinebuffer;
+ var buf = xlinebuffer;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix++;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ }
+ return spix;
+ }
+
+ function linetoscr_32_shrink1(spix, dpix, stoppos) {
+ //uae_u32 *buf = (uae_u32 *) xlinebuffer;
+ var buf = xlinebuffer;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ spix += 2;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix += 2;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix += 2;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix += 2;
+ out_val = dpix_val;
+ buf[dpix++] = out_val;
+ }
+ }
+ return spix;
+ }
+
+
+ function linetoscr_32_spr(spix, dpix, stoppos) {
+ //uae_u32 *buf = (uae_u32 *) xlinebuffer;
+ var buf = xlinebuffer;
+ var sprcol;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ sprpix_val = dpix_val;
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
}
- if (match) {
- this.clxdat |= sprpix << (k * 4);
+ }
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 1, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
}
}
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ }
+
+ return spix;
+ }
+
+ function linetoscr_32_stretch1_spr(spix, dpix, stoppos) {
+ //uae_u32 *buf = (uae_u32 *) xlinebuffer;
+ var buf = xlinebuffer;
+ var sprcol;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ sprpix_val = dpix_val;
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 1, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix++;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ buf[dpix++] = out_val;
+ }
+ }
+ return spix;
+ }
+
+ function linetoscr_32_shrink1_spr(spix, dpix, stoppos) {
+ //var *buf = (var *) xlinebuffer;
+ var buf = xlinebuffer;
+ var sprcol;
+
+ if (dp_for_drawing.ham_seen) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ dpix_val = xcolors[ham_linebuf[spix]];
+ sprpix_val = dpix_val;
+ spix += 2;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ } else if (bpldualpf) {
+ var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1;
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[lookup[spix_val]];
+ spix += 2;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 1, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ } else if (bplehb) {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ if (spix_val <= 31)
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ else
+ dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777];
+ spix += 2;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ } else {
+ while (dpix < stoppos) {
+ var sprpix_val;
+ var spix_val;
+ var dpix_val;
+ var out_val;
+
+ spix_val = apixels[spix];
+ sprpix_val = spix_val;
+ dpix_val = colors_for_drawing.acolors[spix_val];
+ spix += 2;
+ out_val = dpix_val;
+ if (spritepixels[dpix].data) {
+ sprcol = render_sprites (dpix, 0, sprpix_val, 0);
+ if (sprcol) {
+ var spcol = colors_for_drawing.acolors[sprcol];
+ out_val = spcol;
+ }
+ }
+ buf[dpix++] = out_val;
+ }
+ }
+
+ return spix;
+ }
+
+
+ //apixels -> xlinebuffer
+ function pfield_do_linetoscr(start, stop, blank) {
+ //console.log('pfield_do_linetoscr()', start, stop, stop - start);
+ //xlinecheck('pfield_do_linetoscr', start, stop);
+
+/*#ifdef AGA
+ if (issprites && (AMIGA.config.chipset.mask & CSMASK_AGA)) {
+ if (res_shift == 0) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_aga_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 2) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch2_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch2_aga_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch1_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch1_aga_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == -1) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1f_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1f_aga_spr (src_pixel, start, stop); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1_aga_spr (src_pixel, start, stop); break;
+ }
+ }
+ } else if (res_shift == -2) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2f_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink2f_aga_spr (src_pixel, start, stop); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2_aga_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink2_aga_spr (src_pixel, start, stop); break;
+ }
+ }
+ }
+ } else if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ if (res_shift == 0) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_aga (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 2) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch2_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch2_aga (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch1_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch1_aga (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == -1) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1f_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1f_aga (src_pixel, start, stop); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1_aga (src_pixel, start, stop); break;
+ }
+ }
+ } else if (res_shift == -2) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2f_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink2f_aga (src_pixel, start, stop); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2_aga (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink2_aga (src_pixel, start, stop); break;
+ }
+ }
+ }
+ } else
+#endif*/
+
+/*#ifdef ECS_DENISE
+ if (ecsshres) {
+ if (res_shift == 0) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_sh (src_pixel, start, stop, issprites); break;
+ case 4: src_pixel = linetoscr_32_sh (src_pixel, start, stop, issprites); break;
+ }
+ } else if (res_shift == -1) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1f_sh (src_pixel, start, stop, issprites); break;
+ case 4: src_pixel = linetoscr_32_shrink1f_sh (src_pixel, start, stop, issprites); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1_sh (src_pixel, start, stop, issprites); break;
+ case 4: src_pixel = linetoscr_32_shrink1_sh (src_pixel, start, stop, issprites); break;
+ }
+ }
+ } else if (res_shift == -2) {
+ if (currprefs.gfx_lores_mode) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2f_sh (src_pixel, start, stop, issprites); break;
+ case 4: src_pixel = linetoscr_32_shrink2f_sh (src_pixel, start, stop, issprites); break;
+ }
+ } else {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink2_sh (src_pixel, start, stop, issprites); break;
+ case 4: src_pixel = linetoscr_32_shrink2_sh (src_pixel, start, stop, issprites); break;
+ }
+ }
+ }
+ } else
+#endif*/
+
+ if (issprites) {
+ if (res_shift == 0) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 2) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch2_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch2_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch1_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch1_spr (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == -1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1_spr (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1_spr (src_pixel, start, stop); break;
+ }
+ }
+ } else {
+ if (res_shift == 0) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16 (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32 (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 2) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch2 (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch2 (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == 1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_stretch1 (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_stretch1 (src_pixel, start, stop); break;
+ }
+ } else if (res_shift == -1) {
+ switch (gfxvidinfo.drawbuffer.pixbytes) {
+ case 2: src_pixel = linetoscr_16_shrink1 (src_pixel, start, stop); break;
+ case 4: src_pixel = linetoscr_32_shrink1 (src_pixel, start, stop); break;
+ }
+ }
+ }
+ }
+
+ function init_ham_decoding() {
+ var unpainted_amiga = unpainted;
+
+ ham_decode_pixel = ham_src_pixel;
+ ham_lastcolor = color_reg_get(colors_for_drawing, 0);
+
+ if (!bplham) {
+ if (unpainted_amiga > 0) {
+ var pv = apixels[ham_decode_pixel + unpainted_amiga - 1];
+/*#ifdef AGA
+ if (currprefs.chipset_mask & CSMASK_AGA)
+ ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor];
+ else
+#endif*/
+ ham_lastcolor = colors_for_drawing.color_regs_ecs[pv];
+ }
+/*#ifdef AGA
+ } else if (currprefs.chipset_mask & CSMASK_AGA) {
+ if (bplplanecnt >= 7) { // AGA mode HAM8
+ while (unpainted_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel++] ^ bplxor;
+ switch (pv & 0x3) {
+ case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2]; break;
+ case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break;
+ case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break;
+ case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break;
+ }
+ }
+ } else { // AGA mode HAM6
+ while (unpainted_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel++] ^ bplxor;
+ switch (pv & 0x30) {
+ case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv]; break;
+ case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break;
+ case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break;
+ case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break;
+ }
+ }
+ }
+#endif*/
+ } else {
+ /* OCS/ECS mode HAM6 */
+ while (unpainted_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel++];
+ switch (pv & 0x30) {
+ case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; break;
+ case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break;
+ case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break;
+ case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break;
+ }
}
}
}
- this.draw_1 = function (sprxp, bufpos, datab, num, dbl, mask, do_collisions, collision_mask) {
+ function decode_ham(pix, stoppos, blank) {
+ var todraw_amiga = res_shift_from_window(stoppos - pix);
+
+ if (!bplham) {
+ while (todraw_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel];
+/*#ifdef AGA
+ if (currprefs.chipset_mask & CSMASK_AGA)
+ ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor];
+ else
+#endif*/
+ ham_lastcolor = colors_for_drawing.color_regs_ecs[pv];
+
+ ham_linebuf[ham_decode_pixel++] = ham_lastcolor;
+ }
+/*#ifdef AGA
+ } else if (currprefs.chipset_mask & CSMASK_AGA) {
+ if (bplplanecnt >= 7) { // AGA mode HAM8
+ while (todraw_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel] ^ bplxor;
+ switch (pv & 0x3) {
+ case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2]; break;
+ case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break;
+ case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break;
+ case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break;
+ }
+ ham_linebuf[ham_decode_pixel++] = ham_lastcolor;
+ }
+ } else { // AGA mode HAM6
+ while (todraw_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel] ^ bplxor;
+ switch (pv & 0x30) {
+ case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv]; break;
+ case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break;
+ case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break;
+ case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break;
+ }
+ ham_linebuf[ham_decode_pixel++] = ham_lastcolor;
+ }
+ }
+#endif*/
+ } else {
+ /* OCS/ECS mode HAM6 */
+ while (todraw_amiga-- > 0) {
+ var pv = apixels[ham_decode_pixel];
+ switch (pv & 0x30) {
+ case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; break;
+ case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break;
+ case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break;
+ case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break;
+ }
+ ham_linebuf[ham_decode_pixel++] = ham_lastcolor;
+ }
+ }
+ }
+
+ function weird_bitplane_fix() {
+ for (var i = playfield_start >> lores_shift; i < playfield_end >> lores_shift; i++) {
+ if (apixels[pixels_offset + i] > 16) apixels[pixels_offset + i] = 16;
+ }
+ }
+
+ //line_data -> apixels
+ this.pfield_doline_1 = function(lineno, wordcount, planes) {
+ var pixels = MAX_PIXELS_PER_LINE;
+ var tmp, d0, d1, d2, d3, d4, d5, d6, d7;
+ var offs = 0;
+
+ while (wordcount-- > 0) {
+ d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = 0;
+
+ switch (planes) {
+/*#ifdef AGA
+ case 8: d0 = line_data[lineno][7][offs];
+ case 7: d1 = line_data[lineno][6][offs];
+#endif*/
+ case 6: d2 = line_data[lineno][5][offs];
+ case 5: d3 = line_data[lineno][4][offs];
+ case 4: d4 = line_data[lineno][3][offs];
+ case 3: d5 = line_data[lineno][2][offs];
+ case 2: d6 = line_data[lineno][1][offs];
+ case 1: d7 = line_data[lineno][0][offs];
+ }
+ offs++;
+
+ tmp = (d0 ^ (d1 >>> 1)) & 0x55555555; d0 ^= tmp; d1 ^= (tmp << 1);
+ tmp = (d2 ^ (d3 >>> 1)) & 0x55555555; d2 ^= tmp; d3 ^= (tmp << 1);
+ tmp = (d4 ^ (d5 >>> 1)) & 0x55555555; d4 ^= tmp; d5 ^= (tmp << 1);
+ tmp = (d6 ^ (d7 >>> 1)) & 0x55555555; d6 ^= tmp; d7 ^= (tmp << 1);
+
+ tmp = (d0 ^ (d2 >>> 2)) & 0x33333333; d0 ^= tmp; d2 ^= (tmp << 2);
+ tmp = (d1 ^ (d3 >>> 2)) & 0x33333333; d1 ^= tmp; d3 ^= (tmp << 2);
+ tmp = (d4 ^ (d6 >>> 2)) & 0x33333333; d4 ^= tmp; d6 ^= (tmp << 2);
+ tmp = (d5 ^ (d7 >>> 2)) & 0x33333333; d5 ^= tmp; d7 ^= (tmp << 2);
+
+ tmp = (d0 ^ (d4 >>> 4)) & 0x0f0f0f0f; d0 ^= tmp; d4 ^= (tmp << 4);
+ tmp = (d1 ^ (d5 >>> 4)) & 0x0f0f0f0f; d1 ^= tmp; d5 ^= (tmp << 4);
+ tmp = (d2 ^ (d6 >>> 4)) & 0x0f0f0f0f; d2 ^= tmp; d6 ^= (tmp << 4);
+ tmp = (d3 ^ (d7 >>> 4)) & 0x0f0f0f0f; d3 ^= tmp; d7 ^= (tmp << 4);
+
+ tmp = (d0 ^ (d1 >>> 8)) & 0x00ff00ff; d0 ^= tmp; d1 ^= (tmp << 8);
+ tmp = (d2 ^ (d3 >>> 8)) & 0x00ff00ff; d2 ^= tmp; d3 ^= (tmp << 8);
+ tmp = (d4 ^ (d5 >>> 8)) & 0x00ff00ff; d4 ^= tmp; d5 ^= (tmp << 8);
+ tmp = (d6 ^ (d7 >>> 8)) & 0x00ff00ff; d6 ^= tmp; d7 ^= (tmp << 8);
+
+ tmp = (d0 ^ (d2 >>> 16)) & 0x0000ffff; d0 ^= tmp; d2 ^= (tmp << 16);
+ tmp = (d1 ^ (d3 >>> 16)) & 0x0000ffff; d1 ^= tmp; d3 ^= (tmp << 16);
+ tmp = (d4 ^ (d6 >>> 16)) & 0x0000ffff; d4 ^= tmp; d6 ^= (tmp << 16);
+ tmp = (d5 ^ (d7 >>> 16)) & 0x0000ffff; d5 ^= tmp; d7 ^= (tmp << 16);
+
+ apixels[pixels ] = (d0 >>> 24) & 0xff;
+ apixels[pixels + 1] = (d0 >>> 16) & 0xff;
+ apixels[pixels + 2] = (d0 >>> 8) & 0xff;
+ apixels[pixels + 3] = d0 & 0xff;
+ apixels[pixels + 4] = (d4 >>> 24) & 0xff;
+ apixels[pixels + 5] = (d4 >>> 16) & 0xff;
+ apixels[pixels + 6] = (d4 >>> 8) & 0xff;
+ apixels[pixels + 7] = d4 & 0xff;
+ apixels[pixels + 8] = (d1 >>> 24) & 0xff;
+ apixels[pixels + 9] = (d1 >>> 16) & 0xff;
+ apixels[pixels + 10] = (d1 >>> 8) & 0xff;
+ apixels[pixels + 11] = d1 & 0xff;
+ apixels[pixels + 12] = (d5 >>> 24) & 0xff;
+ apixels[pixels + 13] = (d5 >>> 16) & 0xff;
+ apixels[pixels + 14] = (d5 >>> 8) & 0xff;
+ apixels[pixels + 15] = d5 & 0xff;
+ apixels[pixels + 16] = (d2 >>> 24) & 0xff;
+ apixels[pixels + 17] = (d2 >>> 16) & 0xff;
+ apixels[pixels + 18] = (d2 >>> 8) & 0xff;
+ apixels[pixels + 19] = d2 & 0xff;
+ apixels[pixels + 20] = (d6 >>> 24) & 0xff;
+ apixels[pixels + 21] = (d6 >>> 16) & 0xff;
+ apixels[pixels + 22] = (d6 >>> 8) & 0xff;
+ apixels[pixels + 23] = d6 & 0xff;
+ apixels[pixels + 24] = (d3 >>> 24) & 0xff;
+ apixels[pixels + 25] = (d3 >>> 16) & 0xff;
+ apixels[pixels + 26] = (d3 >>> 8) & 0xff;
+ apixels[pixels + 27] = d3 & 0xff;
+ apixels[pixels + 28] = (d7 >>> 24) & 0xff;
+ apixels[pixels + 29] = (d7 >>> 16) & 0xff;
+ apixels[pixels + 30] = (d7 >>> 8) & 0xff;
+ apixels[pixels + 31] = d7 & 0xff;
+ pixels += 32;
+
+ /*apixels[pixels++] = (d0 >>> 24);
+ apixels[pixels++] = (d0 >>> 16) & 0xff;
+ apixels[pixels++] = (d0 >>> 8) & 0xff;
+ apixels[pixels++] = d0 & 0xff;
+ apixels[pixels++] = (d4 >>> 24);
+ apixels[pixels++] = (d4 >>> 16) & 0xff;
+ apixels[pixels++] = (d4 >>> 8) & 0xff;
+ apixels[pixels++] = d4 & 0xff;
+ apixels[pixels++] = (d1 >>> 24);
+ apixels[pixels++] = (d1 >>> 16) & 0xff;
+ apixels[pixels++] = (d1 >>> 8) & 0xff;
+ apixels[pixels++] = d1 & 0xff;
+ apixels[pixels++] = (d5 >>> 24);
+ apixels[pixels++] = (d5 >>> 16) & 0xff;
+ apixels[pixels++] = (d5 >>> 8) & 0xff;
+ apixels[pixels++] = d5 & 0xff;
+ apixels[pixels++] = (d2 >>> 24);
+ apixels[pixels++] = (d2 >>> 16) & 0xff;
+ apixels[pixels++] = (d2 >>> 8) & 0xff;
+ apixels[pixels++] = d2 & 0xff;
+ apixels[pixels++] = (d6 >>> 24);
+ apixels[pixels++] = (d6 >>> 16) & 0xff;
+ apixels[pixels++] = (d6 >>> 8) & 0xff;
+ apixels[pixels++] = d6 & 0xff;
+ apixels[pixels++] = (d3 >>> 24);
+ apixels[pixels++] = (d3 >>> 16) & 0xff;
+ apixels[pixels++] = (d3 >>> 8) & 0xff;
+ apixels[pixels++] = d3 & 0xff;
+ apixels[pixels++] = (d7 >>> 24);
+ apixels[pixels++] = (d7 >>> 16) & 0xff;
+ apixels[pixels++] = (d7 >>> 8) & 0xff;
+ apixels[pixels++] = d7 & 0xff;*/
+ }
+ }
+
+ this.pfield_doline = function(lineno) {
+ if (bplplanecnt)
+ this.pfield_doline_1(lineno, dp_for_drawing.plflinelen, bplplanecnt);
+ else {
+ for (var i = 0; i < dp_for_drawing.plflinelen * 32; i++) apixels[i] = 0; //memset (data, 0, dp_for_drawing.plflinelen * 32);
+ }
+ }
+
+ this.pfield_draw_line = function(vb, lineno, gfx_ypos, follow_ypos) {
+ if (!AMIGA.config.video.enabled) return;
+ //console.log('pfield_draw_line', lineno, gfx_ypos, follow_ypos);
+ var border = 0;
+ var do_double = 0;
+
+ dp_for_drawing = line_decisions[lineno];
+ dip_for_drawing = curr_drawinfo[lineno];
+
+ switch (linestate[lineno]) {
+ case LINE_REMEMBERED_AS_PREVIOUS:
+ BUG.info('pfield_draw_line() Shouldn\'t get here... this is a bug.');
+ return;
+ case LINE_BLACK:
+ linestate[lineno] = LINE_REMEMBERED_AS_BLACK;
+ border = 2;
+ break;
+ case LINE_REMEMBERED_AS_BLACK:
+ return;
+ case LINE_AS_PREVIOUS:
+ //dp_for_drawing--;
+ //dip_for_drawing--;
+ dp_for_drawing = line_decisions[lineno - 1];
+ dip_for_drawing = curr_drawinfo[lineno - 1];
+ linestate[lineno] = LINE_DONE_AS_PREVIOUS;
+ if (dp_for_drawing.plfleft < 0)
+ border = 1;
+ break;
+ case LINE_DONE_AS_PREVIOUS:
+ /* fall through */
+ case LINE_DONE:
+ return;
+ case LINE_DECIDED_DOUBLE:
+ if (follow_ypos >= 0) {
+ do_double = 1;
+ linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS;
+ }
+ /* fall through */
+ default:
+ if (dp_for_drawing.plfleft < 0)
+ border = 1;
+ linestate[lineno] = LINE_DONE;
+ break;
+ }
+
+ if (border == 0) {
+ this.pfield_expand_dp_bplcon();
+ this.pfield_init_linetoscr();
+ this.pfield_doline(lineno);
+
+ this.adjust_drawing_colors(dp_for_drawing.ctable, dp_for_drawing.ham_seen || bplehb || ecsshres);
+
+ if (dp_for_drawing.ham_seen) {
+ init_ham_decoding();
+ if (dip_for_drawing.nr_color_changes == 0)
+ decode_ham(visible_left_border, visible_right_border, false);
+ else {
+ this.do_color_changes(dummy_worker, decode_ham, lineno);
+ this.adjust_drawing_colors(dp_for_drawing.ctable, dp_for_drawing.ham_seen || bplehb);
+ }
+ bplham = dp_for_drawing.ham_at_start;
+ }
+ if (plf2pri > 5 && bplplanecnt == 5 && !(AMIGA.config.chipset.mask & CSMASK_AGA))
+ weird_bitplane_fix();
+
+ if (dip_for_drawing.nr_sprites) {
+/*#ifdef AGA
+ if (brdsprt)
+ this.clear_bitplane_border_aga();
+#endif*/
+ for (var i = 0; i < dip_for_drawing.nr_sprites; i++)
+ draw_sprites(curr_sprite_entries[dip_for_drawing.first_sprite_entry + i]);
+ }
+ this.do_color_changes(pfield_do_fill_line, pfield_do_linetoscr, lineno);
+
+ this.do_flush_line(vb, gfx_ypos);
+ if (do_double)
+ this.do_flush_line(vb, follow_ypos);
+ } else if (border == 1) {
+ var dosprites = 0;
+
+ this.adjust_drawing_colors(dp_for_drawing.ctable, false);
+
+/*#ifdef AGA
+ if (brdsprt && dip_for_drawing->nr_sprites > 0) {
+ dosprites = 1;
+ this.pfield_expand_dp_bplcon();
+ pfield_init_linetoscr ();
+ memset (apixels + MAX_PIXELS_PER_LINE, colors_for_drawing.borderblank ? 0 : colors_for_drawing.acolors[0], MAX_PIXELS_PER_LINE);
+ }
+#endif*/
+ if (!dosprites && dip_for_drawing.nr_color_changes == 0) {
+ fill_line();
+ this.do_flush_line(vb, gfx_ypos);
+ if (do_double)
+ this.do_flush_line(vb, follow_ypos);
+ return;
+ }
+ if (dosprites) {
+ for (var i = 0; i < dip_for_drawing.nr_sprites; i++)
+ this.draw_sprites(curr_sprite_entries[dip_for_drawing.first_sprite_entry + i]);
+ var oxor = bplxor;
+ for (var i = 0; i < apixels.length; i++) apixels[i] = 0; //memset (apixels, 0, sizeof apixels);
+ bplxor = 0;
+ this.do_color_changes(pfield_do_fill_line, pfield_do_linetoscr, lineno);
+ bplxor = oxor;
+ } else {
+ playfield_start = visible_right_border;
+ playfield_end = visible_right_border;
+ this.do_color_changes(pfield_do_fill_line, pfield_do_fill_line, lineno);
+ }
+ this.do_flush_line(vb, gfx_ypos);
+ if (do_double)
+ this.do_flush_line(vb, follow_ypos);
+ } else {
+ var tmp = hposblank;
+ //hposblank = brdblank;
+ hposblank = colors_for_drawing.borderblank;
+ fill_line();
+ this.do_flush_line(vb, gfx_ypos);
+ hposblank = tmp;
+ }
+ }
+
+ this.init_drawing_frame = function() {
+ this.init_hardware_for_drawing_frame();
+
+ if (thisframe_first_drawn_line < 0)
+ thisframe_first_drawn_line = minfirstline;
+ if (thisframe_first_drawn_line > thisframe_last_drawn_line)
+ thisframe_last_drawn_line = thisframe_first_drawn_line;
+
+ var maxline = ((this.maxvpos_nom + 1) << linedbl) + 2;
+
+ if (SMART_UPDATE) {
+ for (var i = 0; i < maxline; i++) {
+ switch (linestate[i]) {
+ case LINE_DONE_AS_PREVIOUS:
+ linestate[i] = LINE_REMEMBERED_AS_PREVIOUS;
+ break;
+ case LINE_REMEMBERED_AS_BLACK:
+ break;
+ default:
+ linestate[i] = LINE_UNDECIDED;
+ break;
+ }
+ }
+ } else {
+ for (var i = 0; i < maxline; i++) linestate[i] = LINE_UNDECIDED; //memset(linestate, LINE_UNDECIDED, maxline);
+ }
+
+ last_drawn_line = 0;
+ first_drawn_line = 0x7fff;
+
+ first_block_line = last_block_line = NO_BLOCK;
+ if (frame_redraw_necessary)
+ frame_redraw_necessary--;
+
+ this.center_image();
+
+ thisframe_first_drawn_line = -1;
+ thisframe_last_drawn_line = -1;
+
+ drawing_color_matches = -1;
+ }
+
+ this.finish_drawing_frame = function() {
+ var vb = gfxvidinfo.drawbuffer;
+
+ if (SMART_UPDATE) {
+ for (var i = 0; i < max_ypos_thisframe; i++) {
+ var i1 = i + min_ypos_for_screen;
+ var line = i + thisframe_y_adjust_real;
+
+ var where2 = amiga2aspect_line_map[i1];
+ if (where2 >= vb.inheight)
+ break;
+ if (where2 < 0)
+ continue;
+ hposblank = 0;
+ this.pfield_draw_line(vb, line, where2, amiga2aspect_line_map[i1 + 1]);
+ }
+ //if (lightpen_active) lightpen_update(vb);
+
+ //this.do_flush_screen(vb, first_drawn_line, last_drawn_line);
+ } /*else {
+ if (!interlace_seen)
+ this.do_flush_screen(vb, first_drawn_line, last_drawn_line);
+ }*/
+ }
+
+ this.hardware_line_completed = function(lineno) {
+ if (!SMART_UPDATE) {
+ var i = lineno - thisframe_y_adjust_real;
+ if (i >= 0 && i < max_ypos_thisframe) {
+ var where = amiga2aspect_line_map[i + min_ypos_for_screen];
+ if (where < gfxvidinfo.drawbuffer.outheight && where >= 0)
+ this.pfield_draw_line(null, lineno, where, amiga2aspect_line_map[i + min_ypos_for_screen+1]);
+ }
+ }
+ }
+
+ this.notice_interlace_seen = function(lace) {
+ var changed = false;
+ if (lace) {
+ if (interlace_seen == 0) {
+ changed = true;
+ //BUG.info('->lace');
+ }
+ interlace_seen = AMIGA.config.video.vresolution ? 1 : -1;
+ } else {
+ if (interlace_seen) {
+ changed = true;
+ //BUG.info('->non-lace');
+ }
+ interlace_seen = 0;
+ }
+ return changed;
+ }
+
+ this.notice_screen_contents_lost = function() {
+ frame_redraw_necessary = 2;
+ }
+
+ /*---------------------------------*/
+
+ this.reset_lores = function() {
+ lores_shift = AMIGA.config.video.hresolution;
+ if (doublescan > 0) {
+ if (lores_shift < 2)
+ lores_shift++;
+ }
+ sprite_buffer_res = AMIGA.config.video.hresolution;
+ if (doublescan > 0 && sprite_buffer_res < RES_SUPERHIRES)
+ sprite_buffer_res++;
+ }
+
+ this.bpldmainitdelay = function(hpos) {
+ var hposa = hpos + (4 + (bplcon0_planes == 8 ? 1 : 0)); //BPLCON_AGNUS_DELAY;
+ ddf_change = this.vpos;
+ if (hposa < 0x14) {
+ this.BPLCON0_Denise(hpos, bplcon0, false);
+ this.setup_fmodes(hpos);
+ return;
+ }
+ if (bpldmasetuphpos < 0) {
+ bpldmasetupphase = 0;
+ bpldmasetuphpos = hpos + BPLCON_DENISE_DELAY;
+ }
+ }
+
+ this.update_ddf_change = function() {
+ ddf_change = this.vpos;
+ }
+
+ /*---------------------------------*/
+
+ this.allocsoftbuffer = function(buf, flags, width, height, depth) {
+ buf.rowbytes = MAX_PIXELS_PER_LINE >> 3; /* for xlinecheck() */
+ buf.pixbytes = Math.floor((depth + 7) / 8);
+ buf.width_allocated = (width + 7) & ~7;
+ buf.height_allocated = height;
+ }
+
+ this.setup_drawing = function() {
+ setup_drawing_tables();
+ this.allocsoftbuffer(gfxvidinfo.drawbuffer, 0, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_DEPTH);
+ }
+
+ this.cleanup_drawing = function() {}
+
+ this.reset_drawing = function() {
+ var i;
+ max_diwstop = 0;
+ this.reset_lores();
+ for (i = 0; i < linestate.length; i++) linestate[i] = LINE_UNDECIDED;
+ this.recreate_aspect_maps();
+ last_redraw_point = 0;
+ for (i = 0; i < spixels.length; i++) spixels[i] = 0; //memset(spixels, 0, sizeof spixels);
+ for (i = 0; i < spixstate.length; i++) spixstate[i] = 0; //memset(&spixstate, 0, sizeof spixstate);
+ this.init_drawing_frame();
+ this.notice_screen_contents_lost();
+ //lightpen_y1 = lightpen_y2 = -1;
+ center_reset = true;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* sprites */
+ /*-----------------------------------------------------------------------*/
+
+ function setup_sprite_tables() {
+ for (var i = 0; i < 256; i++) {
+ sprtaba[i] =
+ (((i >> 7) & 1) << 0)
+ | (((i >> 6) & 1) << 2)
+ | (((i >> 5) & 1) << 4)
+ | (((i >> 4) & 1) << 6)
+ | (((i >> 3) & 1) << 8)
+ | (((i >> 2) & 1) << 10)
+ | (((i >> 1) & 1) << 12)
+ | (((i >> 0) & 1) << 14);
+ sprtabb[i] = sprtaba[i] << 1;
+ sprite_ab_merge[i] = ((i & 15) ? 1 : 0) | ((i & 240) ? 2 : 0);
+ clxtab[i] =
+ ((((i & 3) && (i & 12)) << 9) |
+ (((i & 3) && (i & 48)) << 10) |
+ (((i & 3) && (i & 192)) << 11) |
+ (((i & 12) && (i & 48)) << 12) |
+ (((i & 12) && (i & 192)) << 13) |
+ (((i & 48) && (i & 192)) << 14));
+ sprite_offs[i] = (i & 15) ? 0 : 2;
+ }
+ for (var i = 0; i < 16; i++) {
+ clxmask[i] =
+ ((i & 1) ? 0xF : 0x3)
+ | ((i & 2) ? 0xF0 : 0x30)
+ | ((i & 4) ? 0xF00 : 0x300)
+ | ((i & 8) ? 0xF000 : 0x3000);
+ sprclx[i] =
+ (((i & 0x3) == 0x3 ? 1 : 0)
+ | ((i & 0x5) == 0x5 ? 2 : 0)
+ | ((i & 0x9) == 0x9 ? 4 : 0)
+ | ((i & 0x6) == 0x6 ? 8 : 0)
+ | ((i & 0xA) == 0xA ? 16 : 0)
+ | ((i & 0xC) == 0xC ? 32 : 0)) << 9;
+ }
+ }
+
+ function render_sprites(pos, dualpf, apixel, aga) {
+ if (!DO_SPRITES) return; //FIXME
+ var spb = spritepixels[pos];
+ var v = spb.data;
+ var shift_lookup = dualpf ? (bpldualpfpri ? dblpf_ms2 : dblpf_ms1) : dblpf_ms;
+ var maskshift = shift_lookup[apixel];
+ var plfmask = (plf_sprite_mask >>> maskshift) >>> maskshift;
+
+ v &= ~plfmask;
+ if (v != 0) { //|| SPRITE_DEBUG) {
+ var vlo, vhi, col;
+ var v1 = v & 255;
+ var offs;
+ if (v1 == 0)
+ offs = 4 + sprite_offs[v >> 8];
+ else
+ offs = sprite_offs[v1];
+
+ v >>= offs * 2;
+ v &= 15;
+/*#if SPRITE_DEBUG > 0
+ v ^= 8;
+#endif*/
+ if (spb.attach && (spb.stdata & (3 << offs))) {
+ col = v;
+ if (aga)
+ col += sbasecol[1];
+ else
+ col += 16;
+ } else {
+ vlo = v & 3;
+ vhi = (v & (vlo - 1)) >> 2;
+ col = (vlo | vhi);
+ if (aga) {
+ if (vhi > 0)
+ col += sbasecol[1];
+ else
+ col += sbasecol[0];
+ } else {
+ col += 16;
+ }
+ col += offs * 2;
+ }
+ return col;
+ }
+ return 0;
+ }
+
+ function draw_sprites_1(e, dualpf, has_attach) {
+ //uae_u16 *buf = spixels + e.first_pixel;
+ //uae_u8 *stbuf = spixstate.bytes + e.first_pixel;
+ //buf -= e.pos;
+ //stbuf -= e.pos;
+ var pos2 = e.first_pixel - e.pos;
+
+ var spr_pos = e.pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res);
+
+ if (spr_pos < sprite_first_x)
+ sprite_first_x = spr_pos;
+
+ for (var pos = e.pos; pos < e.max; pos++, spr_pos++) {
+ if (spr_pos >= 0 && spr_pos < MAX_PIXELS_PER_LINE) {
+ //spritepixels[spr_pos].data = buf[pos];
+ //spritepixels[spr_pos].stdata = stbuf[pos];
+ spritepixels[spr_pos].data = spixels[pos2 + pos];
+ spritepixels[spr_pos].stdata = spixstate[pos2 + pos];
+ spritepixels[spr_pos].attach = has_attach;
+ }
+ }
+ if (spr_pos > sprite_last_x)
+ sprite_last_x = spr_pos;
+ }
+
+ function draw_sprites(e) {
+ if (!DO_SPRITES) return; //FIXME
+ draw_sprites_1(e, bpldualpf, e.has_attached);
+ }
+
+ function ecsshres_func() {
+ return bplcon0_res == RES_SUPERHIRES && (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) && !(AMIGA.config.chipset.mask & CSMASK_AGA);
+ }
+
+ /* handle very rarely needed playfield collision (CLXDAT bit 0) only known game needing this is Rotor */
+ this.do_playfield_collisions = function() {
+ var bplres = bplcon0_res;
+ var ddf_left = thisline_decision.plfleft * 2 << bplres;
+ var hw_diwlast = coord_window_to_diw_x(thisline_decision.diwlastword);
+ var hw_diwfirst = coord_window_to_diw_x(thisline_decision.diwfirstword);
+ var i, collided, minpos, maxpos;
+/*#ifdef AGA
+ var planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6;
+#else*/
+ var planes = 6;
+//#endif
+
+ if (clxcon_bpl_enable == 0) {
+ clxdat |= 1;
+ return;
+ }
+ if (clxdat & 1)
+ return;
+
+ collided = 0;
+ minpos = thisline_decision.plfleft * 2;
+ if (minpos < hw_diwfirst)
+ minpos = hw_diwfirst;
+ maxpos = thisline_decision.plfright * 2;
+ if (maxpos > hw_diwlast)
+ maxpos = hw_diwlast;
+ for (i = minpos; i < maxpos && !collided; i+= 32) {
+ var offs = ((i << bplres) - ddf_left) >> 3;
+ var j;
+ var total = 0xffffffff;
+ for (j = 0; j < planes; j++) {
+ var ena = (clxcon_bpl_enable >> j) & 1;
+ var match = (clxcon_bpl_match >> j) & 1;
+ var t = 0xffffffff;
+ if (ena) {
+ if (j < thisline_decision.nr_planes) {
+ //t = *(uae_u32 *)(line_data[next_lineno] + offs + 2 * j * MAX_WORDS_PER_LINE);
+ t = line_data[next_lineno][j][offs];
+ t ^= (match & 1) - 1;
+ } else {
+ t = (match & 1) - 1;
+ }
+ }
+ total &= t;
+ }
+ if (total) {
+ collided = 1;
+ /*if (1) { //debug
+ for (var k = 0; k < 1; k++) {
+ //uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + offs + 2 * k * MAX_WORDS_PER_LINE); *ldata ^= 0x5555555555;
+ line_data[next_lineno][k][offs] ^= 0x5555555555;
+ }
+ }*/
+ }
+ }
+ if (collided)
+ clxdat |= 1;
+ }
+
+ /* Sprite-to-sprite collisions are taken care of in record_sprite. This one does playfield/sprite collisions. */
+ this.do_sprite_collisions = function() {
+ var nr_sprites = curr_drawinfo[next_lineno].nr_sprites;
+ var first = curr_drawinfo[next_lineno].first_sprite_entry;
+ var collision_mask = clxmask[clxcon >> 12];
+ var bplres = bplcon0_res;
+ var ddf_left = thisline_decision.plfleft * 2 << bplres;
+ var hw_diwlast = coord_window_to_diw_x(thisline_decision.diwlastword);
+ var hw_diwfirst = coord_window_to_diw_x(thisline_decision.diwfirstword);
+
+ if (clxcon_bpl_enable == 0) {
+ clxdat |= 0x1fe;
+ return;
+ }
+
+ for (var i = 0; i < nr_sprites; i++) {
+ var e = curr_sprite_entries[first + i];
+ var minpos = e.pos;
+ var maxpos = e.max;
+ var minp1 = minpos >> sprite_buffer_res;
+ var maxp1 = maxpos >> sprite_buffer_res;
+
+ if (maxp1 > hw_diwlast)
+ maxpos = hw_diwlast << sprite_buffer_res;
+ if (maxp1 > thisline_decision.plfright * 2)
+ maxpos = thisline_decision.plfright * 2 << sprite_buffer_res;
+ if (minp1 < hw_diwfirst)
+ minpos = hw_diwfirst << sprite_buffer_res;
+ if (minp1 < thisline_decision.plfleft * 2)
+ minpos = thisline_decision.plfleft * 2 << sprite_buffer_res;
+
+ for (var j = minpos; j < maxpos; j++) {
+ var sprpix = spixels[e.first_pixel + j - e.pos] & collision_mask;
+
+ if (sprpix == 0)
+ continue;
+
+ var match = 1;
+ var offs = ((j << bplres) >> sprite_buffer_res) - ddf_left;
+ sprpix = (sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2)) << 1;
+
+ for (var k = 1; k >= 0; k--) {
+/*#ifdef AGA
+ var planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6;
+#else*/
+ var planes = 6;
+//#endif
+ if (bplcon0 & 0x400)
+ match = 1;
+ for (var l = k; match && l < planes; l += 2) {
+ var t = 0;
+ if (l < thisline_decision.nr_planes) {
+ //uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); var word = ldata[offs >> 5];
+ var word = line_data[next_lineno][l][offs >> 5];
+ t = (word >>> (31 - (offs & 31))) & 1;
+ /*if (1) { //debug: draw collision mask
+ for (var m = 0; m < 5; m++) {
+ //uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * m * MAX_WORDS_PER_LINE); ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31));
+ line_data[next_lineno][m][(offs >> 5) + 0] |= 15 << (31 - (offs & 31));
+ }
+ }*/
+ }
+ if (clxcon_bpl_enable & (1 << l)) {
+ if (t != ((clxcon_bpl_match >> l) & 1))
+ match = 0;
+ }
+ }
+ if (match) {
+ /*if (1) { //debug: mark lines where collisions are detected
+ for (var l = 0; l < 5; l++) {
+ //uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31));
+ line_data[next_lineno][l][(offs >> 5) + 0] |= 15 << (31 - (offs & 31));
+ }
+ }*/
+ clxdat |= (sprpix << (k * 4));
+ }
+ }
+ }
+ }
+ /*{
+ static var olx;
+ if (clxdat != olx) BUG.info('%d: %04x', vpos, clxdat);
+ olx = clxdat;
+ }*/
+ }
+
+ this.record_sprite_1 = function(sprxp, buf, datab, num, dbl, mask, do_collisions, collision_mask) {
var j = 0;
+
while (datab) {
var col = 0;
var coltmp = 0;
- //if ((sprxp >= this.sprite_minx && sprxp < this.sprite_maxx) || (AMIGA.playfield.bplcon3 & 2))
+ if ((sprxp >= sprite_minx && sprxp < sprite_maxx) || (bplcon3 & 2))
col = (datab & 3) << (2 * num);
- /*if (0) {
- if (sprxp == this.sprite_minx || sprxp == this.sprite_maxx - 1)
- col ^= (rand () << 16) | rand ();
- }*/
- //if ((j & mask) == 0)
- {
- var tmp = spr_data[bufpos] | col;
- spr_data[bufpos++] = tmp;
- if (do_collisions) coltmp |= tmp;
- //sprxp++;
+
+ //if (sprxp == sprite_minx || sprxp == sprite_maxx - 1) col ^= Math.floor(Math.random() * 0xffffffff);
+
+ if ((j & mask) == 0) {
+ //var tmp = (*buf) | col; *buf++ = tmp;
+ var tmp = spixels[buf] | col; spixels[buf++] = tmp;
+ if (do_collisions)
+ coltmp |= tmp;
+ sprxp++;
}
if (dbl > 0) {
- var tmp = spr_data[bufpos] | col;
- spr_data[bufpos++] = tmp;
- if (do_collisions) coltmp |= tmp;
- //sprxp++;
+ //var tmp = (*buf) | col; *buf++ = tmp;
+ var tmp = spixels[buf] | col; spixels[buf++] = tmp;
+ if (do_collisions)
+ coltmp |= tmp;
+ sprxp++;
+ }
+ if (dbl > 1) {
+ var tmp;
+ //tmp = (*buf) | col; *buf++ = tmp;
+ tmp = spixels[buf] | col; spixels[buf++] = tmp;
+ if (do_collisions)
+ coltmp |= tmp;
+ //tmp = (*buf) | col; *buf++ = tmp;
+ tmp = spixels[buf] | col; spixels[buf++] = tmp;
+ if (do_collisions)
+ coltmp |= tmp;
+ sprxp++;
+ sprxp++;
}
j++;
datab >>>= 2;
@@ -221,988 +2934,639 @@ function Sprites() {
coltmp &= collision_mask;
if (coltmp) {
var shrunk_tmp = sprite_ab_merge[coltmp & 255] | (sprite_ab_merge[coltmp >> 8] << 2);
- this.clxdat |= sprclx[shrunk_tmp];
+ clxdat |= sprclx[shrunk_tmp];
}
}
}
}
+
+ //this.record_sprite = function(line, num, sprxp, data, datb, ctl) {
+ this.record_sprite = function(line, num, sprxp) {
+ var e = curr_sprite_entries[next_sprite_entry];
+ var word_offs;
+ var collision_mask;
+ var width, dbl, half;
+ var mask = 0;
+ var attachment;
+ var i;
+
+ //var data = 0, datb = 0;
+ var this_sprite_entry = next_sprite_entry;
+ var num2 = 0;
- this.draw = function() {
- //if (this.nr_armed == 0) return;
+ half = 0;
+ dbl = sprite_buffer_res - sprres;
+ if (dbl < 0) {
+ half = -dbl;
+ dbl = 0;
+ mask = 1 << half;
+ }
+ width = (sprite_width << sprite_buffer_res) >> sprres;
+ attachment = sprctl[num | 1] & 0x80;
+
+ /* Try to coalesce entries if they aren't too far apart */
+ //if (!next_sprite_forced && e[-1].max + sprite_width >= sprxp) {
+ if (this_sprite_entry > 0 && !next_sprite_forced && curr_sprite_entries[this_sprite_entry - 1].max + sprite_width >= sprxp) {
+ //e--;
+ e = curr_sprite_entries[this_sprite_entry - 1];
+ this_sprite_entry--;
+ //console.log('RS',this_sprite_entry);
+ } else {
+ next_sprite_entry++;
+ e.pos = sprxp;
+ e.has_attached = 0;
+ }
+ if (sprxp < e.pos)
+ Fatal(333, 'sprxp < e->pos');
+
+ e.max = sprxp + width;
+ //e[1].first_pixel = e.first_pixel + ((e.max - e.pos + 3) & ~3);
+ curr_sprite_entries[this_sprite_entry + 1].first_pixel = e.first_pixel + ((e.max - e.pos + 3) & ~3);
+ next_sprite_forced = 0;
+
+ collision_mask = clxmask[clxcon >> 12];
+ word_offs = e.first_pixel + sprxp - e.pos;
+
+ for (i = 0; i < sprite_width; i += 16) {
+ //var da = *data;
+ //var db = *datb;
+ //var da = sprdata[data][0];
+ //var db = sprdatb[datb][0];
+ var da = sprdata[num][num2];
+ var db = sprdatb[num][num2];
+ var datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]) >>> 0;
+ var off = (i << dbl) >> half;
+ //uae_u16 *buf = spixels + word_offs + off;
+ var buf = word_offs + off;
+ if (AMIGA.config.chipset.collision_level > 0 && collision_mask)
+ this.record_sprite_1(sprxp + off, buf, datab, num, dbl, mask, 1, collision_mask);
+ else
+ this.record_sprite_1(sprxp + off, buf, datab, num, dbl, mask, 0, collision_mask);
+
+ //*data++; *datb++;
+ num2++;
+ }
+
+ /* We have 8 bits per pixel in spixstate, two for every sprite pair.
+ The low order bit records whether the attach bit was set for this pair. */
+ if (attachment && !ecsshres_func()) {
+ var state = ((0x01010101 << (num & ~1)) >>> 0) & 0xff;
+ /*uae_u8 *stb1 = spixstate.bytes + word_offs;
+ for (i = 0; i < width; i += 8) {
+ stb1[0] |= state;
+ stb1[1] |= state;
+ stb1[2] |= state;
+ stb1[3] |= state;
+ stb1[4] |= state;
+ stb1[5] |= state;
+ stb1[6] |= state;
+ stb1[7] |= state;
+ stb1 += 8;
+ }*/
+ var stb1 = word_offs;
+ for (i = 0; i < width; i += 8) {
+ spixstate[stb1 + 0] |= state;
+ spixstate[stb1 + 1] |= state;
+ spixstate[stb1 + 2] |= state;
+ spixstate[stb1 + 3] |= state;
+ spixstate[stb1 + 4] |= state;
+ spixstate[stb1 + 5] |= state;
+ spixstate[stb1 + 6] |= state;
+ spixstate[stb1 + 7] |= state;
+ stb1 += 8;
+ }
+ e.has_attached = 1;
+ }
+ }
+
+ function tospritexdiw(diw) {
+ return coord_window_to_hw_x(diw - (DIW_DDF_OFFSET << lores_shift)) << sprite_buffer_res;
+ }
+ function tospritexddf(ddf) {
+ return (ddf << 1) << sprite_buffer_res;
+ }
+ function fromspritexdiw(ddf) {
+ return coord_hw_to_window_x(ddf >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift);
+ }
+
+ function calcsprite() {
+ sprite_maxx = 0x7fff;
+ sprite_minx = 0;
+ if (thisline_decision.diwlastword >= 0)
+ sprite_maxx = tospritexdiw(thisline_decision.diwlastword);
+ if (thisline_decision.diwfirstword >= 0)
+ sprite_minx = tospritexdiw(thisline_decision.diwfirstword);
+ if (thisline_decision.plfleft >= 0) {
+ var min = tospritexddf(thisline_decision.plfleft);
+ var max = tospritexddf(thisline_decision.plfright);
+ if (min > sprite_minx && min < max) /* min < max = full line ddf */
+ sprite_minx = min;
+ }
+ }
+
+ function add_sprite(count, num, sprxp, posns, nrs) {
+ var bestp, j;
+ for (bestp = 0; bestp < count; bestp++) {
+ if (posns[bestp] > sprxp)
+ break;
+ if (posns[bestp] == sprxp && nrs[bestp] < num)
+ break;
+ }
+ for (j = count; j > bestp; j--) {
+ posns[j] = posns[j - 1];
+ nrs[j] = nrs[j - 1];
+ }
+ posns[j] = sprxp;
+ nrs[j] = num;
+ }
+
+ this.decide_sprites = function(hpos) {
+ if (!DO_SPRITES) return; //FIXME
var nrs = [], posns = [];
- var count = 0;
- var xoffs = (180 - (AMIGA.playfield.state.hlen >> 1)) << (AMIGA.playfield.state.hires ? 1 : 0);
+ var point = hpos * 2 - 3;
+ var width = sprite_width;
+ var sscanmask = 0x100 << sprite_buffer_res;
+ var gotdata = 0;
+ var count, i;
- for (var i = 0; i < MAX_SPRITES; i++) {
- var sprxp = xoffs + ((this.sprite[i].xpos - AMIGA.playfield.state.hstart) << (AMIGA.playfield.state.hires ? 1 : 0));
+ if (thisline_decision.plfleft < 0 && !(bplcon3 & 2))
+ return;
- if (!this.sprite[i].armed || sprxp < 0) continue;
+ if (this.nodraw() || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
+ return;
- var j, bestp;
+ this.decide_diw(hpos);
+ this.decide_line(hpos);
- for (bestp = 0; bestp < count; bestp++) {
- if (posns[bestp] > sprxp) break;
- if (posns[bestp] == sprxp && nrs[bestp] < i) break;
+ calcsprite();
+
+ for (i = 0; i < MAX_SPRITES * 2; i++)
+ nrs[i] = posns[i] = 0;
+
+ count = 0;
+ for (i = 0; i < MAX_SPRITES; i++) {
+ var sprxp = (fmode & 0x8000) ? (spr[i].xpos & ~sscanmask) : spr[i].xpos;
+ var hw_xp = sprxp >> sprite_buffer_res;
+
+ if (!spr[i].armed || spr[i].xpos < 0)
+ continue;
+ /*if (!((debug_sprite_mask & magic_sprite_mask) & (1 << i)))
+ continue;*/
+
+ if (hw_xp > last_sprite_point && hw_xp <= point)
+ add_sprite(count++, i, sprxp, posns, nrs);
+
+ if ((fmode & 0x8000) && !(sprxp & sscanmask)) {
+ sprxp |= sscanmask;
+ hw_xp = sprxp >> sprite_buffer_res;
+ if (hw_xp > last_sprite_point && hw_xp <= point)
+ add_sprite(count++, MAX_SPRITES + i, sprxp, posns, nrs);
}
- for (j = count; j > bestp; j--) {
- posns[j] = posns[j - 1];
- nrs[j] = nrs[j - 1];
- }
- posns[j] = sprxp;
- nrs[j] = i;
- count++;
- }
- //if (count) { for (i = 0; i < count; i++) BUG.info('SPR n %d, x %d', nrs[i], posns[i]); BUG.info('------------'); }
-
- var collision_mask = clxmask[this.clxcon >> 12];
-
+ }
for (i = 0; i < count; i++) {
- var sprxp = posns[i];
- var nr = nrs[i];
- var attachment = this.sprite[nr | 1].ctl & 0x80;
- var da = this.sprite[nr].data;
- var db = this.sprite[nr].datb;
- var datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]);
- var dbl = AMIGA.playfield.state.hires ? 1 : 0;
- var mask = 0;
-
- if (AMIGA.config.chipset.colLevel != SAEV_Config_Chipset_ColLevel_None && collision_mask) this.draw_1(sprxp, sprxp, datab, nr, dbl, mask, 1, collision_mask);
- else this.draw_1(sprxp, sprxp, datab, nr, dbl, mask, 0, collision_mask);
-
- if (attachment) {
- var state = (1 << (nr & ~1)) & 0xff;
- for (j = 0; j < 16; j++) {
- spr_state[sprxp + j] |= state;
- spr_attach[sprxp + j] = true;
+ var nr = nrs[i] & (MAX_SPRITES - 1);
+ //this.record_sprite(next_lineno, nr, posns[i], sprdata[nr], sprdatb[nr], sprctl[nr]);
+ this.record_sprite(next_lineno, nr, posns[i]);
+
+ /* get left and right sprite edge if brdsprt enabled */
+/*#if AUTOSCALE_SPRITES
+ if (AMIGA.dmaen(DMAF_SPREN) && (bplcon0 & 1) && (bplcon3 & 0x02) && !(bplcon3 & 0x20) && nr > 0) {
+ var j, jj;
+ for (j = 0, jj = 0; j < sprite_width; j+= 16, jj++) {
+ var nx = fromspritexdiw (posns[i] + j);
+ if (sprdata[nr][jj] || sprdatb[nr][jj]) {
+ if (diwfirstword_total > nx && nx >= (48 << currprefs.hresolution))
+ diwfirstword_total = nx;
+ if (diwlastword_total < nx + 16 && nx <= (448 << currprefs.hresolution))
+ diwlastword_total = nx + 16;
+ }
}
+ gotdata = 1;
}
+#endif*/
}
- }
+ last_sprite_point = point;
- this.sprite_fetch = function(n, dma, hpos, cycle, mode) {
+ /* get upper and lower sprite position if brdsprt enabled */
+/*#if AUTOSCALE_SPRITES
+ if (gotdata) {
+ if (vpos < first_planes_vpos)
+ first_planes_vpos = vpos;
+ if (vpos < plffirstline_total)
+ plffirstline_total = vpos;
+ if (vpos > last_planes_vpos)
+ last_planes_vpos = vpos;
+ if (vpos > plflastline_total)
+ plflastline_total = vpos;
+ }
+#endif*/
+ }
+
+ this.cursorsprite = function() {
+ if (!AMIGA.dmaen(DMAF_SPREN) || first_planes_vpos == 0)
+ return;
+ sprite_0 = spr[0].pt;
+ sprite_0_height = spr[0].vstop - spr[0].vstart;
+ sprite_0_colors[0] = 0;
+ sprite_0_doubled = 0;
+ if (sprres == 0)
+ sprite_0_doubled = 1;
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ var sbasecol = ((bplcon4 >> 4) & 15) << 4;
+ sprite_0_colors[1] = current_colors.color_regs_aga[sbasecol + 1];
+ sprite_0_colors[2] = current_colors.color_regs_aga[sbasecol + 2];
+ sprite_0_colors[3] = current_colors.color_regs_aga[sbasecol + 3];
+ } else {
+ sprite_0_colors[1] = xcolors[current_colors.color_regs_ecs[17]];
+ sprite_0_colors[2] = xcolors[current_colors.color_regs_ecs[18]];
+ sprite_0_colors[3] = xcolors[current_colors.color_regs_ecs[19]];
+ }
+ sprite_0_width = sprite_width;
+ /*if (currprefs.input_tablet && currprefs.input_magic_mouse) {
+ if (currprefs.input_magic_mouse_cursor == MAGICMOUSE_HOST_ONLY && mousehack_alive ())
+ magic_sprite_mask &= ~1;
+ else
+ magic_sprite_mask |= 1;
+ }*/
+ }
+
+ function sprite_fetch(s, dma, hpos, cycle, mode) {
var data = AMIGA.custom.last_value;
- if (dma)
- data = AMIGA.mem.load16_chip(this.sprite[n].pt);
- this.sprite[n].pt += 2;
+ if (dma) {
+ //data = AMIGA.mem.load16_chip(s.pt);
+ data = AMIGA.custom.last_value = AMIGA.mem.chip.data[s.pt >>> 1];
+ }
+ s.pt += 2;
+ return data;
+ }
+ function sprite_fetch2(s, hpos, cycle, mode) {
+ //var data = AMIGA.mem.load16_chip(s.pt);
+ var data = AMIGA.custom.last_value = AMIGA.mem.chip.data[s.pt >>> 1];
+ s.pt += 2;
return data;
}
- this.cycle_1 = function (vp, n, cycle, hpos) {
- var isdma = AMIGA.dmaen(DMAF_SPREN) || ((n & 1) && this.sprite[n & ~1].dmacycle);
+ this.do_sprites_1 = function(num, cycle, hpos) {
+ var s = spr[num];
+ var isdma = AMIGA.dmaen(DMAF_SPREN) || ((num & 1) && spr[num & ~1].dmacycle);
- if (isdma && vp == sprite_vblank_endline) this.sprArm(n, 0);
-
- if (vp == this.sprite[n].vstart) {
- this.sprite[n].dmastate = 1;
- //if (n == 0 && cycle == 0) cursorsprite();
+ if (isdma && this.vpos == sprite_vblank_endline)
+ spr_arm(num, 0);
+/*#ifdef AGA
+ if (isdma && s.dblscan && (fmode & 0x8000) && (this.vpos & 1) != (s.vstart & 1) && s.dmastate) {
+ spr_arm(num, 1);
+ return;
}
- if (vp == this.sprite[n].vstop || vp == sprite_vblank_endline) {
- this.sprite[n].dmastate = 0;
- if (1) {
- // roots 2.0 flower zoomer bottom part missing if this enabled
- if (vp == this.sprite[n].vstop) {
- this.sprArm(n, 0);
- //return;
- }
+#endif*/
+
+ //if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:slot%d:%d', this.vpos, hpos, num, cycle);
+
+ if (this.vpos == s.vstart) {
+ //if (!s.dmastate && this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:SPR%d START', this.vpos, hpos, num);
+ s.dmastate = 1;
+ if (num == 0 && cycle == 0)
+ this.cursorsprite();
+ }
+ if (this.vpos == s.vstop || this.vpos == sprite_vblank_endline) {
+ //if (s.dmastate && this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:SPR%d STOP', this.vpos, hpos, num);
+ s.dmastate = 0;
+/*#if 0
+ // roots 2.0 flower zoomer bottom part missing if this enabled
+ if (this.vpos == s.vstop) {
+ spr_arm (num, 0);
+ //return;
}
+#endif*/
}
- if (!isdma) return;
- if (cycle && !this.sprite[n].dmacycle) return; /* Superfrog intro flashing bee fix */
+ if (!isdma)
+ return;
+ if (cycle && !s.dmacycle)
+ return; /* Superfrog intro flashing bee fix */
- var dma = hpos < AMIGA.playfield.state.dstart;
+ var dma = hpos < plfstrt_sprite || diwstate != DIW_WAITING_STOP;
var posctl = 0;
- if (vp == this.sprite[n].vstop || vp == sprite_vblank_endline) {
- this.sprite[n].dmastate = 0;
+ if (this.vpos == s.vstop || this.vpos == sprite_vblank_endline) {
+ s.dmastate = 0;
posctl = 1;
if (dma) {
- var data = this.sprite_fetch(n, dma, hpos, cycle, 0);
-
+ var data = sprite_fetch(s, dma, hpos, cycle, 0);
+ switch (sprite_width) {
+ case 64:
+ sprite_fetch2(s, hpos, cycle, 0);
+ sprite_fetch2(s, hpos, cycle, 0);
+ case 32:
+ sprite_fetch2(s, hpos, cycle, 0);
+ break;
+ }
+ //BUG.info('%d:%d: %04X=%04X', this.vpos, hpos, 0x140 + cycle * 2 + num * 8, data);
if (cycle == 0) {
- this.SPRxPOS(data, n);
- this.sprite[n].dmacycle = 1;
+ this.SPRxPOS_1(data, num, hpos);
+ s.dmacycle = 1;
} else {
- this.SPRxCTL(data, n);
- this.sprite[n].dmastate = 0;
- this.sprStartStop(n);
+ this.SPRxCTL_1(data, num, hpos);
+ s.dmastate = 0;
+ this.sprstartstop(s);
}
}
+ //if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:dma:P=%06X '), this.vpos, hpos, s.pt);
}
- if (this.sprite[n].dmastate && !posctl && dma) {
- var data = this.sprite_fetch(n, dma, hpos, cycle, 1);
-
+ if (s.dmastate && !posctl && dma) {
+ var data = sprite_fetch(s, dma, hpos, cycle, 1);
+ //if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:dma:P=%06X '), this.vpos, hpos, s.pt);
if (cycle == 0) {
- this.SPRxDATA(data, n);
- this.sprite[n].dmacycle = 1;
+ this.SPRxDATA_1(data, num, hpos);
+ s.dmacycle = 1;
} else {
- this.SPRxDATB(data, n);
- this.sprArm(n, 1);
+ this.SPRxDATB_1(data, num, hpos);
+ spr_arm(num, 1);
}
+/*#ifdef AGA
+ switch (sprite_width) {
+ case 64: {
+ var data32 = sprite_fetch2 (s, hpos, cycle, 1);
+ var data641 = sprite_fetch2 (s, hpos, cycle, 1);
+ var data642 = sprite_fetch2 (s, hpos, cycle, 1);
+ if (dma) {
+ if (cycle == 0) {
+ sprdata[num][3] = data642;
+ sprdata[num][2] = data641;
+ sprdata[num][1] = data32;
+ } else {
+ sprdatb[num][3] = data642;
+ sprdatb[num][2] = data641;
+ sprdatb[num][1] = data32;
+ }
+ }
+ }
+ break;
+ case 32: {
+ var data32 = sprite_fetch2 (s, hpos, cycle, 1);
+ if (dma) {
+ if (cycle == 0)
+ sprdata[num][1] = data32;
+ else
+ sprdatb[num][1] = data32;
+ }
+ }
+ break;
+ }
+#endif*/
}
}
- this.cycle = function (hpos) {
- var vp = AMIGA.events.vpos;
- if (vp < sprite_vblank_endline) return;
+ this.do_sprites = function(hpos) {
+ if (!DO_SPRITES) return; //FIXME
+ if (this.vpos < sprite_vblank_endline)
+ return;
- for (var i = 0; i < MAX_SPRITES * 2; i++) {
- this.sprite[i >> 1].dmacycle = 1;
- this.cycle_1(vp, i >> 1, i & 1, 0);
+ if (this.doflickerfix() && interlace_seen && (next_lineno & 1))
+ return;
+
+ if (!CUSTOM_SIMPLE) {
+ var minspr = last_sprite_hpos + 1;
+ var maxspr = hpos;
+
+ if (minspr >= maxspr || last_sprite_hpos == hpos)
+ return;
+
+ if (maxspr >= SPR0_HPOS + MAX_SPRITES * 4)
+ maxspr = SPR0_HPOS + MAX_SPRITES * 4 - 1;
+ if (minspr < SPR0_HPOS)
+ minspr = SPR0_HPOS;
+
+ if (minspr == maxspr)
+ return;
+
+ for (var i = minspr; i <= maxspr; i++) {
+ var cycle = -1;
+ var num = (i - SPR0_HPOS) >> 2;
+ switch ((i - SPR0_HPOS) & 3) {
+ case 0:
+ cycle = 0;
+ spr[num].dmacycle = 0;
+ break;
+ case 2:
+ cycle = 1;
+ break;
+ }
+ if (cycle >= 0) {
+ spr[num].ptxhpos = MAXHPOS;
+ this.do_sprites_1(num, cycle, i);
+ }
+ }
+ last_sprite_hpos = hpos;
+ } else {
+ for (var i = 0; i < MAX_SPRITES * 2; i++) {
+ spr[i >> 1].dmacycle = 1;
+ this.do_sprites_1(i >> 1, i & 1, 0);
+ }
+ }
+ }
+
+ function expand_sprres(con0, con3) {
+ switch ((con3 >> 6) & 3) {
+ case 0: {
+ if ((AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) && GET_RES_DENISE(con0) == RES_SUPERHIRES)
+ return RES_HIRES;
+ else
+ return RES_LORES;
+ }
+/*#ifdef AGA
+ case 1:
+ return RES_LORES;
+ case 2:
+ return RES_HIRES;
+ case 3:
+ return RES_SUPERHIRES;
+#endif*/
+ default:
+ return RES_LORES;
}
}
- this.sprArm = function (n, state) {
+ function spr_arm(num, state) {
switch (state) {
case 0:
- this.nr_armed -= this.sprite[n].armed;
- this.sprite[n].armed = 0;
+ nr_armed -= spr[num].armed;
+ spr[num].armed = 0;
break;
default:
- this.nr_armed += 1 - this.sprite[n].armed;
- this.sprite[n].armed = 1;
- }
+ nr_armed += 1 - spr[num].armed;
+ spr[num].armed = 1;
+ break;
+ }
}
- this.sprStartStop = function (n) {
- if (AMIGA.events.vpos + 1 == this.sprite[n].vstart) this.sprite[n].dmastate = 1;
- if (AMIGA.events.vpos + 1 == this.sprite[n].vstop) this.sprite[n].dmastate = 0;
+ this.sprstartstop = function(s) {
+ if (this.vpos == s.vstart)
+ s.dmastate = 1;
+ if (this.vpos == s.vstop)
+ s.dmastate = 0;
}
- this.SPRxCTLPOS = function (n) {
- this.sprStartStop(n);
-
- this.sprite[n].xpos = (this.sprite[n].pos & 0xff) * 2 + (this.sprite[n].ctl & 1);
- this.sprite[n].vstart = (this.sprite[n].pos >> 8) | ((this.sprite[n].ctl << 6) & 0x100);
- this.sprite[n].vstop = (this.sprite[n].ctl >> 8) | ((this.sprite[n].ctl << 7) & 0x100);
- /*if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) {
- this.sprite[n].vstart |= (this.sprite[n].ctl << 3) & 0x200;
- this.sprite[n].vstop |= (this.sprite[n].ctl << 4) & 0x200;
- }*/
- this.sprStartStop(n);
- }
-
- this.SPRxCTL = function (v, n) {
- this.sprite[n].ctl = v;
- this.sprArm(n, 0);
- this.SPRxCTLPOS(n);
- }
-
- this.SPRxPOS = function (v, n) {
- this.sprite[n].pos = v;
- this.SPRxCTLPOS(n);
- }
-
- this.SPRxDATA = function (v, n) {
- this.sprite[n].data = v;
- this.sprArm(n, 1);
- }
-
- this.SPRxDATB = function (v, n) {
- this.sprite[n].datb = v;
- }
-
- this.SPRxPTH = function (v, n) {
- this.sprite[n].pt = ((v << 16) | (this.sprite[n].pt & 0xffff)) >>> 0;
- }
-
- this.SPRxPTL = function (v, n) {
- this.sprite[n].pt = ((this.sprite[n].pt & 0xffff0000) | v) >>> 0;
- }
-
- this.CLXCON = function (v) {
- this.clxcon = v;
+ this.CLXCON = function(v) {
+ clxcon = v;
clxcon_bpl_enable = (v >> 6) & 63;
clxcon_bpl_match = v & 63;
}
+ this.CLXCON2 = function(v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ return;
+ clxcon2 = v;
+ clxcon_bpl_enable |= v & (0x40 | 0x80);
+ clxcon_bpl_match |= (v & (0x01 | 0x02)) << 6;
+ }
+
this.CLXDAT = function() {
- var v = this.clxdat | 0x8000;
- this.clxdat = 0;
+ var v = clxdat | 0x8000;
+ clxdat = 0;
return v;
}
-}
-
-function Plane(num) {
- this.num = num;
- this.pt = 0;
- this.dat = -1;
- this.line = new Uint16Array(45);
-}
-
-function Playfield() {
- /* BPLCON0 flags */
- const BPLF_ERSY = 1 << 1;
- const BPLF_LACE = 1 << 2;
- const BPLF_LPEN = 1 << 3;
- const BPLF_GAUD = 1 << 8;
- const BPLF_COLOR = 1 << 9;
- const BPLF_DBLPF = 1 << 10;
- const BPLF_HOMOD = 1 << 11;
- const BPLF_HIRES = 1 << 15;
- /* BPLCON2 flags */
- const BPLF_PF2PRI = 1 << 6;
-
- this.sprites = new Sprites();
-
- this.plane = new Array(6);
- for (var i = 0; i < 6; i++)
- this.plane[i] = new Plane(i);
-
- this.color_std = new Uint16Array(32);
- this.color_ehb = new Uint16Array(32);
- for (var i = 0; i < 32; i++) this.color_std[i] = this.color_ehb[i] = 0;
-
- this.linedata = [];
-
- this.bplcon0 = 0;
- this.bplcon1 = 0;
- this.bplcon2 = 0;
- this.bplcon3 = 0;
-
- this.bpl1mod = 0;
- this.bpl2mod = 0;
-
- this.diwstrt = 0;
- this.diwstop = 0;
- this.diwhigh = -1; //ECS
- this.ddfstrt = 0;
- this.ddfstop = 0;
-
- this.state = {
- vstart: 0,
- vstop: 0,
- vlen: 0,
- vlenreal: 0,
- vlenrealset: 0,
- vlenrealtmp: 0,
- hstart: 0,
- hstop: 0,
- hlen: 0,
- hnum: 0,
- hpixel: 0,
- hleft: 0,
- dstart: 0,
- dstop: 0,
- dlen: 0,
- dnum: 0,
- dwords: 0,
- ddiff: 0,
- altget: false,
- hires: false,
- ilace: false,
- std: false,
- ehb: false,
- dpf: false,
- ham: false,
- planes: 0,
- delay1: 0,
- delay2: 0,
- pf2pri: false,
- pf1p: 0,
- pf2p: 0,
- colorOnly: true,
- hScale: true,
- vScale: true,
- };
-
- this.frame = {
- skip: false,
- skipcount: 0,
- count: 0
- };
-
- /* for playfield development */
- /*this.lamps = function() {
- var e = document.getElementById('lamp_hir');
- if (e) e.style.color = this.state.hires ? '#8c8' : '#888';
- e = document.getElementById('lamp_ila');
- if (e) e.style.color = this.state.ilace ? '#8c8' : '#888';
- e = document.getElementById('lamp_dpf');
- if (e) e.style.color = this.state.dpf ? '#8c8' : '#888';
- e = document.getElementById('lamp_ham');
- if (e) e.style.color = this.state.ham ? '#8c8' : '#888';
- e = document.getElementById('lamp_ehb');
- if (e) e.style.color = this.state.ehb ? '#8c8' : '#888';
- e = document.getElementById('lamp_scr');
- if (e) e.style.color = this.state.altget ? '#8c8' : '#888';
- e = document.getElementById('lamp_p2p');
- if (e) e.style.color = this.state.pf2pri ? '#8c8' : '#888';
- e = document.getElementById('lamp_nPl');
- if (e) e.innerHTML = this.state.planes;
- e = document.getElementById('lamp_dl1');
- if (e) e.innerHTML = sprintf('%02d', this.state.delay1);
- e = document.getElementById('lamp_dl2');
- if (e) e.innerHTML = sprintf('%02d', this.state.delay2);
- //if (this.state.hlen > 0 && this.state.hlen <= 720 && this.state.vlen > 0 && this.state.vlen <= 288)
- {
- e = document.getElementById('lamp_diw');
- if (e) e.innerHTML = sprintf('%dx%d', this.state.hlen, this.state.vlenreal);
- }
- e = document.getElementById('lamp_dff');
- if (e) e.innerHTML = sprintf('%d (%d)', this.state.dlen, this.state.ddiff);
- }*/
-
- this.setup = function() {
- this.create_cycle_diagram_table();
- this.sprites.setup();
- }
+ this.SPRxCTLPOS = function(num) {
+ var sprxp;
+ var s = spr[num];
- this.cleanup = function() {
- this.sprites.cleanup();
- }
-
- this.reset = function() {
- this.state.colorOnly = true;
- this.state.hScale = true;
- this.state.vScale = true;
-
- for (var i = 0; i < 32; i++)
- this.color_std[i] = this.color_ehb[i] = 0;
-
- this.frame.skip = false;
- this.frame.skipcount = 0;
- }
-
- this.recalc = function() {
- this.state.vlen = this.state.vstop - this.state.vstart;
- this.state.hlen = this.state.hstop - this.state.hstart;
- this.state.hnum = this.state.hlen >> 3;
-
- this.state.dlen = (this.state.dstop - this.state.dstart + 15) & ~7;
- this.state.dnum = this.state.dlen >> 3;
- this.state.ddiff = (this.state.dnum << 1) - this.state.hnum;
- if (this.state.ddiff < 0) this.state.ddiff = 0;
-
- //this.state.hlen = this.state.dlen << 1;
-
- this.state.hpixel = this.state.hlen << (this.state.hires ? 1 : 0);
- this.state.hleft = (180 - Math.min(this.state.hlen >> 1, this.state.dlen)) << (this.state.hires ? 1 : 0);
- this.state.dwords = this.state.dnum << (this.state.hires ? 1 : 0);
-
- this.state.altget = this.state.ddiff != 0 && ((this.state.dstart >> 3) & 1) != 0;
-
- //this.lamps();
- }
-
- this.calcdiw = function() {
- this.state.vstart = this.diwstrt >> 8;
- this.state.vstop = this.diwstop >> 8;
- this.state.hstart = this.diwstrt & 0xff;
- this.state.hstop = this.diwstop & 0xff;
- this.state.hstart &= ~7;
- this.state.hstop &= ~7;
-
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS && this.diwhigh != -1) {
- this.state.vstart |= (this.diwhigh & 7) << 8;
- this.state.vstop |= ((this.diwhigh >> 8) & 7) << 8;
- this.state.hstart |= ((this.diwhigh >> 5) & 1) << 8;
- this.state.hstop |= ((this.diwhigh >> 13) & 1) << 8;
- } else {
- if ((this.state.vstop & 0x80) == 0) this.state.vstop |= 0x100;
- this.state.hstop += 0x100;
- }
-
- this.recalc();
- //BUG.info('Playfield.calcdiw() diwstrt $%04x diwstop $%04x | v %d-%d, h %d-%d | %d x %d', this.diwstrt, this.diwstop, this.state.vstart, this.state.vstop, this.state.hstart, this.state.hstop, this.state.hlen, this.state.vlen);
- }
-
- this.calcddf = function(stop) {
- this.state.dstart = this.ddfstrt & 0xff;
- this.state.dstop = this.ddfstop & 0xff;
- this.state.dstart &= ~3;
- this.state.dstop &= ~3;
-
- if (this.state.dstart < 0x18) this.state.dstart = 0x18;
- if (this.state.dstop > 0xd8) this.state.dstop = 0xd8;
-
- /*if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) {
- if (this.state.dstop > AMIGA.events.maxhpos) this.state.dstart = 0;
- if (this.state.dstart < 0x18) this.state.dstart = 0x18;
- } else {
- if (this.state.dstart >= this.state.dstop && this.state.dstart >= 0x18) this.state.dstop = 0xff;
- }*/
-
- this.recalc();
- //BUG.info('Playfield.calcddf() ddfstrt $%04x ddfstop $%04x | plflinelen %d', this.ddfstrt, this.ddfstop, this.state.dlen);
- }
-
-
- this.drawpixel = function (xpos, ypos, rgb) {
- /*if (this.state.ilace) {
- if (this.state.hires)
- AMIGA.video.drawpixel(xpos, ypos, rgb);
- else {
- AMIGA.video.drawpixel(xpos*2, ypos, rgb);
- AMIGA.video.drawpixel(xpos*2+1, ypos, rgb);
- }
- } else {
- if (this.state.hires) {
- AMIGA.video.drawpixel(xpos, ypos*2, rgb);
- AMIGA.video.drawpixel(xpos, ypos*2+1, rgb);
- } else {
- AMIGA.video.drawpixel(xpos*2, ypos*2, rgb);
- AMIGA.video.drawpixel(xpos*2+1, ypos*2, rgb);
- AMIGA.video.drawpixel(xpos*2, ypos*2+1, rgb);
- AMIGA.video.drawpixel(xpos*2+1, ypos*2+1, rgb);
- }
- }*/
-
- if (this.state.hires)
- AMIGA.video.drawpixel(xpos, ypos, rgb);
- else
- AMIGA.video.draw2pixel(xpos << 1, ypos, rgb);
- }
- this.drawpixel_std = function (xpos, ypos, col) {
- var spritecol = this.sprites.render(xpos, col);
- var rgb = this.color_std[spritecol ? spritecol : col];
- this.linedata[xpos] = col;
- //AMIGA.video.drawpixel(xpos, ypos, rgb);
- this.drawpixel(xpos, ypos, rgb);
- }
-
- this.drawpixel_ehb = function (xpos, ypos, col, ehb) {
- var rgb;
- var spritecol = this.sprites.render(xpos, col);
- if (spritecol) rgb = this.color_std[spritecol];
- else rgb = ehb ? this.color_ehb[col] : this.color_std[col];
- this.linedata[xpos] = col;
- //AMIGA.video.drawpixel(xpos, ypos, rgb);
- this.drawpixel(xpos, ypos, rgb);
- }
-
- this.drawpixel_dpf = function (xpos, ypos, col1, col2) {
- var rgb, col = this.state.pf2pri ? col2 : col1;
- var spritecol = this.sprites.render(xpos, col);
- if (spritecol)
- rgb = this.color_std[spritecol];
- else {
- col = this.state.pf2pri ? (col2 > 0 ? (8 + col2) : col1) : (col1 > 0 ? col1 : (8 + col2));
- rgb = this.color_std[col];
- }
- this.linedata[xpos] = col;
- //AMIGA.video.drawpixel(xpos, ypos, rgb);
- this.drawpixel(xpos, ypos, rgb);
- }
-
- this.drawpixel_ham_col = function (xpos, ypos, col) {
- var spritecol = this.sprites.render(xpos, col);
- var rgb = this.color_std[spritecol ? spritecol : col]
- this.linedata[xpos] = col;
- //AMIGA.video.drawpixel(xpos, ypos, rgb);
- this.drawpixel(xpos, ypos, rgb);
- }
-
- this.drawpixel_ham_rgb = function (xpos, ypos, rgb) {
- var spritecol = this.sprites.render(xpos, 0);
- if (spritecol) rgb = this.color_std[spritecol];
- this.linedata[xpos] = 0;
- //AMIGA.video.drawpixel(xpos, ypos, rgb);
- this.drawpixel(xpos, ypos, rgb);
- }
-
-
- this.drawline_std = function(x, y, o) {
- var i, j, l;
- if (this.state.altget && this.state.ddiff < 4) {
- for (j = 0; j < 4; j++) AMIGA.video.drawpixel(x + j, y, this.color_std[0]);
-
- for (j = 4, l = 11; j < 16; j++, l--) {
- var col = 0;
- switch (this.state.planes) {
- case 5: col = ((this.plane[4].line[o] >> l) & 1);
- case 4: col = (col << 1) | ((this.plane[3].line[o] >> l) & 1);
- case 3: col = (col << 1) | ((this.plane[2].line[o] >> l) & 1);
- case 2: col = (col << 1) | ((this.plane[1].line[o] >> l) & 1);
- case 1: col = (col << 1) | ((this.plane[0].line[o] >> l) & 1);
- }
- this.drawpixel_std(x + j, y, col);
- }
- i = 16; o++;
+ this.sprstartstop(s);
+ sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1);
+ sprxp <<= sprite_buffer_res;
+/*#ifdef AGA
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ sprxp |= ((sprctl[num] >> 3) & 3) >> (RES_MAX - sprite_buffer_res);
+ s.dblscan = sprpos[num] & 0x80;
} else
- i = 0;
-
- for (; i < this.state.hpixel; i += 16, o++) {
- for (j = 0, l = 15; j < 16; j++, l--) {
- var col = 0;
- switch (this.state.planes) {
- case 5: col = ((this.plane[4].line[o] >> l) & 1);
- case 4: col = (col << 1) | ((this.plane[3].line[o] >> l) & 1);
- case 3: col = (col << 1) | ((this.plane[2].line[o] >> l) & 1);
- case 2: col = (col << 1) | ((this.plane[1].line[o] >> l) & 1);
- case 1: col = (col << 1) | ((this.plane[0].line[o] >> l) & 1);
- }
- this.drawpixel_std(x + i + j, y, col);
- }
+#endif*/
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) {
+ sprxp |= ((sprctl[num] >> 3) & 2) >> (RES_MAX - sprite_buffer_res);
}
- }
-
- this.drawline_ehb = function(x, y, o) {
- for (var i = 0; i < this.state.hpixel; i += 16, o++) {
- for (var j = 0, l = 15; j < 16; j++, l--) {
- var ehb = ((this.plane[5].line[o] >> l) & 1);
- var col = ((this.plane[4].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[3].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[2].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[1].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[0].line[o] >> l) & 1);
- this.drawpixel_ehb(x + i + j, y, col, ehb);
- }
- }
- }
-
- this.drawline_dpf = function(x, y, o) {
- for (var i = 0; i < this.state.hpixel; i += 16, o++) {
- for (var j = 0, l = 15; j < 16; j++, l--) {
- var col1 = 0, col2 = 0;
- switch (this.state.planes) {
- case 6: col2 = ((this.plane[5].line[o] >> l) & 1);
- case 5: col1 = ((this.plane[4].line[o] >> l) & 1);
- case 4: col2 = (col2 << 1) | ((this.plane[3].line[o] >> l) & 1);
- case 3: col1 = (col1 << 1) | ((this.plane[2].line[o] >> l) & 1);
- case 2: col2 = (col2 << 1) | ((this.plane[1].line[o] >> l) & 1);
- case 1: col1 = (col1 << 1) | ((this.plane[0].line[o] >> l) & 1);
- }
- this.drawpixel_dpf(x + i + j, y, col1, col2);
- }
- }
+ s.xpos = sprxp;
+ s.vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100);
+ s.vstop = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100);
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
+ s.vstart |= (sprctl[num] << 3) & 0x200;
+ s.vstop |= (sprctl[num] << 4) & 0x200;
+ }
+ this.sprstartstop(s);
}
-
- this.drawline_ham = function(x, y, o) {
- var opm, col, r = 0, g = 0, b = 0;
-
- for (var i = 0; i < this.state.hpixel; i += 16, o++) {
- for (var j = 0, l = 15; j < 16; j++, l--) {
- opm = (((this.plane[5].line[o] >> l) & 1) << 1) | ((this.plane[4].line[o] >> l) & 1);
- col = ((this.plane[3].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[2].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[1].line[o] >> l) & 1);
- col = (col << 1) | ((this.plane[0].line[o] >> l) & 1);
- switch (opm) {
- case 2: { r = col; this.drawpixel_ham_rgb(x + i + j, y, ((r << 1) << 11) | ((g << 2) << 5) | (b << 1)); break; }
- case 3: { g = col; this.drawpixel_ham_rgb(x + i + j, y, ((r << 1) << 11) | ((g << 2) << 5) | (b << 1)); break; }
- case 1: { b = col; this.drawpixel_ham_rgb(x + i + j, y, ((r << 1) << 11) | ((g << 2) << 5) | (b << 1)); break; }
- default: {
- r = ((this.color_std[col] >> 11) & 31) >> 1;
- g = ((this.color_std[col] >> 5) & 63) >> 2;
- b = (this.color_std[col] & 31) >> 1;
- this.drawpixel_ham_col(x + i + j, y, col);
- }
- }
- }
- }
- }
- this.drawline_border = function(y) {
- var l = this.state.hleft;
- var w = this.state.hpixel;
- var r = this.state.hires ? VIDEO_WIDTH : VIDEO_WIDTH >> 1;
- var x, rgb = this.color_std[0];
-
- if (!this.state.hires) {
- l <<= 1;
- w <<= 1;
- r <<= 1;
- }
- AMIGA.video.drawline_from_to(0, l, y, rgb);
- AMIGA.video.drawline_from_to(l + w, r, y, rgb);
+ this.SPRxCTL_1 = function(v, num, hpos) {
+ //struct sprite *s = &spr[num];
+ sprctl[num] = v;
+ spr_arm(num, 0);
+ this.SPRxCTLPOS(num);
+ /*if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) {
+ BUG.info('%d:%d:SPR%dCTL %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x', this.vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC);
+ }*/
}
- this.drawline_empty = function(y) {
- var l = this.state.hleft;
- var w = this.state.hpixel;
- var x, rgb = this.color_std[0];
-
- if (!this.state.hires) {
- l <<= 1;
- w <<= 1;
- }
- AMIGA.video.drawline_from_to(l, l + w, y, rgb);
+
+ this.SPRxPOS_1 = function(v, num, hpos) {
+ //struct sprite *s = &spr[num];
+ sprpos[num] = v;
+ this.SPRxCTLPOS(num);
+ /*if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) {
+ BUG.info('%d:%d:SPR%dPOS %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x', this.vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC);
+ }*/
+ }
+
+ this.SPRxDATA_1 = function(v, num, hpos) {
+ sprdata[num][0] = v;
+/*#ifdef AGA
+ sprdata[num][1] = v;
+ sprdata[num][2] = v;
+ sprdata[num][3] = v;
+#endif*/
+ spr_arm(num, 1);
+ /*if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) {
+ BUG.info('%d:%d:SPR%dDATA %04X P=%06X D=%d A=%d PC=%x', this.vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC);
+ }*/
+ }
+
+ this.SPRxDATB_1 = function(v, num, hpos) {
+ sprdatb[num][0] = v;
+/*#ifdef AGA
+ sprdatb[num][1] = v;
+ sprdatb[num][2] = v;
+ sprdatb[num][3] = v;
+#endif*/
+ /*if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) {
+ BUG.info('%d:%d:SPR%dDATB %04X P=%06X D=%d A=%d PC=%x', this.vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC);
+ }*/
}
- this.fetchline = function() {
- var pt5 = this.plane[5].pt >>> 1;
- var pt4 = this.plane[4].pt >>> 1;
- var pt3 = this.plane[3].pt >>> 1;
- var pt2 = this.plane[2].pt >>> 1;
- var pt1 = this.plane[1].pt >>> 1;
- var pt0 = this.plane[0].pt >>> 1;
+ this.SPRxDATA = function(hpos, v, num) { this.decide_sprites(hpos); this.SPRxDATA_1(v, num, hpos); }
+ this.SPRxDATB = function(hpos, v, num) { this.decide_sprites(hpos); this.SPRxDATB_1(v, num, hpos); }
+ this.SPRxCTL = function(hpos, v, num) { this.decide_sprites(hpos); this.SPRxCTL_1(v, num, hpos); }
+ this.SPRxPOS = function(hpos, v, num) { this.decide_sprites(hpos); this.SPRxPOS_1(v, num, hpos); }
- if (this.state.altget) {
- switch (this.state.planes) {
- case 6: { this.plane[5].line[0] = AMIGA.mem.chip.data[pt5] >> 8; }
- case 5: { this.plane[4].line[0] = AMIGA.mem.chip.data[pt4] >> 8; }
- case 4: { this.plane[3].line[0] = AMIGA.mem.chip.data[pt3] >> 8; }
- case 3: { this.plane[2].line[0] = AMIGA.mem.chip.data[pt2] >> 8; }
- case 2: { this.plane[1].line[0] = AMIGA.mem.chip.data[pt1] >> 8; }
- case 1: { this.plane[0].line[0] = AMIGA.mem.chip.data[pt0] >> 8; }
- }
- for (var i = 1; i < this.state.dwords + 1; i++) {
- switch (this.state.planes) {
- case 6: { this.plane[5].line[i] = ((AMIGA.mem.chip.data[pt5] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt5] >> 8); }
- case 5: { this.plane[4].line[i] = ((AMIGA.mem.chip.data[pt4] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt4] >> 8); }
- case 4: { this.plane[3].line[i] = ((AMIGA.mem.chip.data[pt3] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt3] >> 8); }
- case 3: { this.plane[2].line[i] = ((AMIGA.mem.chip.data[pt2] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt2] >> 8); }
- case 2: { this.plane[1].line[i] = ((AMIGA.mem.chip.data[pt1] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt1] >> 8); }
- case 1: { this.plane[0].line[i] = ((AMIGA.mem.chip.data[pt0] & 0xff) << 8) | (AMIGA.mem.chip.data[++pt0] >> 8); }
- }
- }
- switch (this.state.planes) {
- case 6: { this.plane[5].line[i] = 0; }
- case 5: { this.plane[4].line[i] = 0; }
- case 4: { this.plane[3].line[i] = 0; }
- case 3: { this.plane[2].line[i] = 0; }
- case 2: { this.plane[1].line[i] = 0; }
- case 1: { this.plane[0].line[i] = 0; }
- }
- } else {
- for (var i = 0; i < this.state.dwords; i++) {
- switch (this.state.planes) {
- case 6: { this.plane[5].line[i] = AMIGA.mem.chip.data[pt5++]; }
- case 5: { this.plane[4].line[i] = AMIGA.mem.chip.data[pt4++]; }
- case 4: { this.plane[3].line[i] = AMIGA.mem.chip.data[pt3++]; }
- case 3: { this.plane[2].line[i] = AMIGA.mem.chip.data[pt2++]; }
- case 2: { this.plane[1].line[i] = AMIGA.mem.chip.data[pt1++]; }
- case 1: { this.plane[0].line[i] = AMIGA.mem.chip.data[pt0++]; }
- }
- }
+ this.SPRxPTH = function(hpos, v, num) {
+ this.decide_sprites(hpos);
+ if (hpos - 1 != spr[num].ptxhpos) {
+ spr[num].pt = ((v << 16) | (spr[num].pt & 0xffff)) >>> 0;
}
-
- switch (this.state.planes) {
- case 6: this.plane[5].pt = pt5 << 1;
- case 5: this.plane[4].pt = pt4 << 1;
- case 4: this.plane[3].pt = pt3 << 1;
- case 3: this.plane[2].pt = pt2 << 1;
- case 2: this.plane[1].pt = pt1 << 1;
- case 1: this.plane[0].pt = pt0 << 1;
+ //if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:SPR%dPTH %06X', this.vpos, hpos, num, spr[num].pt);
+ }
+ this.SPRxPTL = function(hpos, v, num) {
+ this.decide_sprites(hpos);
+ if (hpos - 1 != spr[num].ptxhpos) {
+ spr[num].pt = ((spr[num].pt & 0xffff0000) | (v & 0xfffe)) >>> 0;
+ }
+ //if (this.vpos >= SPRITE_DEBUG_MINY && this.vpos <= SPRITE_DEBUG_MAXY) BUG.info('%d:%d:SPR%dPTL %06X', this.vpos, hpos, num, spr[num].pt);
+ }
+
+ this.setup_sprites = function() {
+ if (!sprinit) {
+ sprinit = true;
+ setup_sprite_tables();
}
}
- this.scrollline = function(d1, d2) {
- var d1n = 16 - d1;
- var d2n = 16 - d2;
- for (var i = this.state.dwords - 1; i > 0; i--) {
- switch (this.state.planes) {
- case 6: { if (d2) this.plane[5].line[i] = (this.plane[5].line[i] >> d2) | (this.plane[5].line[i - 1] << d2n); }
- case 5: { if (d1) this.plane[4].line[i] = (this.plane[4].line[i] >> d1) | (this.plane[4].line[i - 1] << d1n); }
- case 4: { if (d2) this.plane[3].line[i] = (this.plane[3].line[i] >> d2) | (this.plane[3].line[i - 1] << d2n); }
- case 3: { if (d1) this.plane[2].line[i] = (this.plane[2].line[i] >> d1) | (this.plane[2].line[i - 1] << d1n); }
- case 2: { if (d2) this.plane[1].line[i] = (this.plane[1].line[i] >> d2) | (this.plane[1].line[i - 1] << d2n); }
- case 1: { if (d1) this.plane[0].line[i] = (this.plane[0].line[i] >> d1) | (this.plane[0].line[i - 1] << d1n); }
- }
- }
- switch (this.state.planes) {
- case 6: { if (d2) this.plane[5].line[i] = this.plane[5].line[i] >> d2; }
- case 5: { if (d1) this.plane[4].line[i] = this.plane[4].line[i] >> d1; }
- case 4: { if (d2) this.plane[3].line[i] = this.plane[3].line[i] >> d2; }
- case 3: { if (d1) this.plane[2].line[i] = this.plane[2].line[i] >> d1; }
- case 2: { if (d2) this.plane[1].line[i] = this.plane[1].line[i] >> d2; }
- case 1: { if (d1) this.plane[0].line[i] = this.plane[0].line[i] >> d1; }
- }
+ this.cleanup_sprites = function() {}
+
+ this.reset_sprites = function() {
+ var i;
+ for (i = 0; i < sprpos.length; i++) sprpos[i] = 0; //memset (sprpos, 0, sizeof sprpos);
+ for (i = 0; i < sprctl.length; i++) sprctl[i] = 0; //memset (sprctl, 0, sizeof sprctl);
+
+ for (i = 0; i < spixels.length; i++) spixels[i] = 0; //memset(spixels, 0, sizeof spixels);
+ for (i = 0; i < spixstate.length; i++) spixstate[i] = 0; //memset(&spixstate, 0, sizeof spixstate);
}
- this.mod = function() {
- switch (this.state.planes) {
- case 6: this.plane[5].pt += this.bpl2mod;
- case 5: this.plane[4].pt += this.bpl1mod;
- case 4: this.plane[3].pt += this.bpl2mod;
- case 3: this.plane[2].pt += this.bpl1mod;
- case 2: this.plane[1].pt += this.bpl2mod;
- case 1: this.plane[0].pt += this.bpl1mod;
- }
- }
-
- this.hSync = function() {
- if (!this.frame.skip) {
- var x = this.state.hleft;
- var y = AMIGA.events.vpos - ((this.state.vlenreal > 256) ? this.state.vstart : 0x2c);
-
- if (this.state.ilace) y = y * 2 + 1 - AMIGA.events.lof;
- if (x < 0) x = 0;
- if (y < 0) y = 0; else if (y >= VIDEO_HEIGHT) y = VIDEO_HEIGHT - 1;
-
- if (AMIGA.events.vpos >= this.state.vstart && AMIGA.events.vpos < this.state.vstop) {
- if (this.state.planes > 0 && AMIGA.dmaen(DMAF_BPLEN)) {
- var offs = this.state.ddiff ? (this.state.ddiff - 1) >> 1 : 0;
- if (this.state.ddiff == 2) { this.state.altget = false; offs++ };
- this.state.colorOnly = false;
-
- if (this.sprites.nr_armed > 0) this.sprites.draw();
-
- this.fetchline();
- this.mod();
-
- if (this.state.delay1 || this.state.delay2) {
- var d1 = this.state.hires ? ((this.state.delay1 & 7) << 1) : this.state.delay1;
- var d2 = this.state.hires ? ((this.state.delay2 & 7) << 1) : this.state.delay2;
- this.scrollline(d1, d2);
- }
-
-
- if (this.state.std) this.drawline_std(x, y, offs);
- else if (this.state.ehb) this.drawline_ehb(x, y, offs);
- else if (this.state.dpf) this.drawline_dpf(x, y, offs);
- else if (this.state.ham) this.drawline_ham(x, y, offs);
- else AMIGA.video.drawline(y, this.color_std[0]);
-
- this.drawline_border(y);
-
- if (this.state.vlenrealset == 0) {
- this.state.vlenrealset++;
- this.state.vlenrealtmp = AMIGA.events.vpos;
- }
- } else {
- AMIGA.video.drawline(y, this.color_std[0]);
- }
- } else {
- if (this.state.vlenrealset == 1) {
- this.state.vlenrealset++;
- this.state.vlenreal = AMIGA.events.vpos - this.state.vlenrealtmp;
- //this.lamps();
- }
- AMIGA.video.drawline(y, this.color_std[0]);
- }
- }
-
- //AMIGA.events.eventtab[EV_RENDER].oldcycles = AMIGA.events.currcycle;
- //AMIGA.events.eventtab[EV_RENDER].evtime = AMIGA.events.currcycle + AMIGA.events.maxhpos * CYCLE_UNIT;
- }
-
- this.vSync = function() {
- if (!this.frame.skip && (!this.state.ilace || (this.state.ilace && AMIGA.events.lof == 0))) {
- AMIGA.video.draw(this.color_std[0], this.state.hScale, this.state.vScale, this.state.colorOnly);
-
- //if (!this.state.colorOnly) AMIGA.video.clear_pixels();
- }
-
- if (this.state.ilace) { if (AMIGA.events.lof == 0) this.frame.count++; } else this.frame.count++; if (this.frame.count == AMIGA.events.hz) this.frame.count = 0;
-
- /*this.state.hires = false;
- this.state.ilace = false;
- this.state.ham = false;
- this.state.dpf = false;
- this.state.ehb = false;
- this.state.std = false;
- this.state.altget = false;
- this.state.hScale = true;
- this.state.vScale = true;*/
-
- this.state.colorOnly = true;
- this.state.vlenrealset = 0;
- }
-
- this.COLORxx = function (v, num) {
- //BUG.info('Playfield.COLOR%02d() $%04x', num, v);
- var r = (v >> 8) & 15;
- var g = (v >> 4) & 15;
- var b = v & 15;
- this.color_std[num] = ((r << 1) << 11) | ((g << 2) << 5) | (b << 1);
- this.color_ehb[num] = (r << 11) | ((g << 1) << 5) | b;
- }
-
- this.BPLxPTx = function (v, num, hi) {
- if (hi) {
- this.plane[num].pt = ((v << 16) | (this.plane[num].pt & 0xffff)) >>> 0;
- } else {
- /*if (AMIGA.copper.access && this.is_bitplane_dma(AMIGA.events.hpos() + 1) == num + 1) {
- console.log('BPLxPTx() SKIP! ', num, AMIGA.events.hpos());
- return;
- }*/
- this.plane[num].pt = ((this.plane[num].pt & 0xffff0000) | v) >>> 0;
- }
- }
-
- this.BPLxDAT = function (v, num) {
- //if (v) BUG.info('Custom.BPL%dDAT() $%04x', num, v);
- this.plane[num].dat = v;
- }
-
- /*this.BPLCON0_getRes = function (v) {
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_OCS)
- v &= ~0x40;
- return (v & 0x8000) ? 2 : ((v & 0x40) ? 3 : 1);
- }*/
-
- this.BPLCON0_getPlanes = function (v) {
- if ((v & 0x0010) && (v & 0x7000))
- return 0;
- if (v & 0x0010)
- return 8;
- return (v >> 12) & 7;
- }
-
- this.BPLCON0 = function (v) {
- //BUG.info('Custom.BPLCON0() $%04x', v);
- //var hires_old = this.state.hires;
- var ilace_old = this.state.ilace;
-
- if (!(this.bplcon0 & 2)) {
- AMIGA.events.vpos_previous = AMIGA.events.vpos;
- AMIGA.events.hpos_previous = AMIGA.events.hpos();
- }
-
- this.bplcon0 = v;
- this.state.planes = this.BPLCON0_getPlanes(v);
-
- this.state.hires = (v & BPLF_HIRES) != 0;
- this.state.ilace = (v & BPLF_LACE) != 0;
- this.state.dpf = (v & BPLF_DBLPF) != 0;
- this.state.ham = (v & BPLF_HOMOD) != 0;
- this.state.ehb = (this.state.planes == 6 && !this.state.dpf && !this.state.ham);
- this.state.std = (!this.state.ehb && !this.state.dpf && !this.state.ham);
-
- this.state.hpixel = this.state.hlen << (this.state.hires ? 1 : 0);
- this.state.hleft = (180 - Math.min(this.state.hlen >> 1, this.state.dlen)) << (this.state.hires ? 1 : 0);
- this.state.dwords = this.state.dnum << (this.state.hires ? 1 : 0);
-
- if (this.state.planes) {
- this.state.hScale = !this.state.hires;
- this.state.vScale = !this.state.ilace;
- }
-
- //if (this.state.hires != hires_old) BUG.info('Custom.BPLCON0() hires change %d, vpos %d, hpos %d', this.state.hires?1:0, AMIGA.events.vpos, AMIGA.events.hpos());
- if (this.state.ilace != ilace_old) {
- //BUG.info('Custom.BPLCON0() ilace change %d, vpos %d, hpos %d', this.state.ilace?1:0, AMIGA.events.vpos, AMIGA.events.hpos());
- if (!this.state.ilace) AMIGA.video.clear_pixels();
- AMIGA.audio.recalc_sample_evtime();
- }
-
- this.setup_fmodes(AMIGA.events.hpos());
-
- //this.lamps();
- }
-
- this.BPLCON1 = function (v) {
- this.bplcon1 = v;
- this.state.delay1 = v & 0xf;
- this.state.delay2 = (v >> 4) & 0xf;
-
- //this.lamps();
- }
-
- this.BPLCON2 = function (v) {
- this.bplcon2 = v;
- this.state.pf2pri = (v & BPLF_PF2PRI) != 0;
- this.state.pf1p = v & 7;
- this.state.pf2p = (v >> 3) & 7;
-
- this.sprites.setMask(this.state.pf1p, this.state.pf2p);
-
- //this.lamps();
- }
-
- this.BPLCON3 = function (v) {
- this.bplcon3 = v;
- }
-
- this.BPL1MOD = function (v) {
- //if (v) BUG.info('Custom.BPL1MOD() $%04x', v);
- this.bpl1mod = (v & 0x8000) ? (v - 0x10000) : v;
- }
-
- this.BPL2MOD = function (v) {
- //if (v) BUG.info('Custom.BPL2MOD() $%04x', v);
- this.bpl2mod = (v & 0x8000) ? (v - 0x10000) : v;
- }
-
- this.DIWSTRT = function (v) {
- //BUG.info('Custom.DIWSTRT() $%04x', v);
- this.diwstrt = v;
- this.calcdiw();
- }
-
- this.DIWSTOP = function (v) {
- //BUG.info('Custom.DIWSTOP() $%04x', v);
- this.diwstop = v;
- this.calcdiw();
- }
-
- this.DDFSTRT = function (v) {
- //BUG.info('Custom.DDFSTRT() $%04x', v);
- this.ddfstrt = v;
- this.calcddf(0);
- }
-
- this.DDFSTOP = function (v) {
- //BUG.info('Custom.DDFSTOP() $%04x', v);
- this.ddfstop = v;
- this.calcddf(1);
- }
-
- /* ECS
- * 7-4 Lisa/Denise/ECS Denise Revision level (decrement to bump revision level, hex F represents 0th rev. level)
- * 3 Maintain as a 1 for future generation
- * 2 When low indicates AA feature set (LISA)
- * 1 When low indicates ECS feature set (LISA or ECS DENISE)
- * 0 Maintain as a 1 for future generation
- *
- * Denise ID: OCS = 0xFF, ECS = 0xFC, AGA = 0xF8
- */
- this.DENISEID___ = function() {
- var smb = 0xff;
-
- var v = ((0xf - AMIGA.config.chipset.agnus_rev) << 4);
- v |= 8;
- v |= 4; /* low = AGA */
- /* v |= 2; low = ECS */
- //v |= 1;
-
- BUG.info('Custom.DENISEID() $%04x', (smb << 8) | v);
- return (smb << 8) | v;
- }
-
- this.DENISEID = function() {
- //if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_AGA) return [0, 0x00F8];
- if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) return [0, 0xFFFC];
- if (AMIGA.config.cpu.model == 68000 && (AMIGA.config.cpu.compatible || AMIGA.config.cpu.exact))
- return [1, 0xFFFF];
- return [0, 0xFFFF];
- }
-
- this.DIWHIGH = function (v) {
- //if (!(AMIGA.config.chipset.type == CHIPSET_AGA))
- v &= ~ (0x0008 | 0x0010 | 0x1000 | 0x0800);
- v &= ~ (0x8000 | 0x4000 | 0x0080 | 0x0040);
-
- //BUG.info('Custom.DIWHIGH() $%04x', v);
- this.diwhigh = v;
- this.calcdiw();
- }
-
- /*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
+ /* playfield */
/*-----------------------------------------------------------------------*/
- var bplcon0_res = 0;
- var bplcon0_planes = 0;
- var bplcon0_planes_limit = 0;
-
- var real_bitplane_number = []; //[3][3][9];
- var fmode = 0;
- var fetchmode = 0;
- var fetchunits = [ 8,8,8,0, 16,8,8,0, 32,16,8,0 ];
- var fetchstarts = [ 3,2,1,0, 4,3,2,0, 5,4,3,0 ];
- var fm_maxplanes = [ 3,2,1,0, 3,3,2,0, 3,3,3,0 ];
- var fetchunit = 0;
+ function debug_cycle_diagram() {
+ var fm, res, planes, cycle, v;
+ var aa, txt = '';
- var fetchunit_mask = 0;
- var fetchstart_shift = 0;
- var fetchstart = 0;
- var fetchstart_mask = 0;
-
- var cycle_diagram_table = []; //[3][3][9][32];
- var cycle_diagram_free_cycles = []; //[3][3][9];
- var cycle_diagram_total_cycles = []; //[3][3][9];
- var cycle_sequences = [ [2,1,2,1,2,1,2,1], [4,2,3,1,4,2,3,1], [8,4,6,2,7,3,5,1] ];
- var curr_diagram = [];
+ for (fm = 0; fm <= 2; fm++) {
+ txt += sprintf('FMODE %d\n=======\n', fm);
+ for (res = 0; res <= 2; res++) {
+ for (planes = 0; planes <= 8; planes++) {
+ txt += sprintf('%d: ',planes);
+ for (cycle = 0; cycle < 32; cycle++) {
+ v = cycle_diagram_table[fm][res][planes][cycle];
+ if (v == 0) aa='-'; else if (v > 0) aa='1'; else aa='X';
+ txt += sprintf('%s', aa);
+ }
+ txt += sprintf(' %d:%d\n', cycle_diagram_free_cycles[fm][res][planes], cycle_diagram_total_cycles[fm][res][planes]);
+ }
+ txt += sprintf('\n');
+ }
+ }
+ BUG.info(txt);
+ }
- this.create_cycle_diagram_table = function () {
+ function create_cycle_diagram_table() {
var fm, res, cycle, planes, rplanes, v;
var fetch_start, max_planes, freecycles;
var cycle_sequence;
- var i, j, k, l;
-
+ var i, j, k, l;
+
for (i = 0; i < 3; i++) {
real_bitplane_number[i] = [];
cycle_diagram_free_cycles[i] = [];
@@ -1218,6 +3582,7 @@ function Playfield() {
}
}
}
+ cycle_diagram_table = [];
for (i = 0; i < 3; i++) {
cycle_diagram_table[i] = [];
for (j = 0; j < 3; j++) {
@@ -1229,7 +3594,7 @@ function Playfield() {
}
}
}
-
+
for (fm = 0; fm <= 2; fm++) {
for (res = 0; res <= 2; res++) {
max_planes = fm_maxplanes[fm * 4 + res];
@@ -1256,65 +3621,1076 @@ function Playfield() {
rplanes = planes;
if (rplanes > max_planes)
rplanes = 0;
- if (rplanes == 7 && fm == 0 && res == 0) //&& !(currprefs.chipset_mask & CSMASK_AGA))
+ if (rplanes == 7 && fm == 0 && res == 0 && !(AMIGA.config.chipset.mask & CSMASK_AGA))
rplanes = 4;
real_bitplane_number[fm][res][planes] = rplanes;
}
}
}
+ //debug_cycle_diagram();
}
-
- //var estimated_last_fetch_cycle = 0;
- //var cycle_diagram_shift = 0;
-
- /*this.estimate_last_fetch_cycle = function (hpos) {
- var fetchunit = fetchunits[fetchmode * 4 + bplcon0_res];
- if (plf_state < plf_passed_stop) {
- var stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop;
- var fetch_cycle_at_stop = fetch_cycle + (stop - hpos);
- var starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1);
+ /*---------------------------------*/
- estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
- } else {
- var starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1);
- if (plf_state == plf_passed_stop2)
- starting_last_block_at -= fetchunit;
+ function doMask(p, bits, shift) {
+ /* scale to 0..255, shift to align msb with mask, and apply mask */
- estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
+ //if (flashscreen) p ^= 0xff;
+ var val = (p << 24) >>> 0;
+ if (!bits)
+ return 0;
+ val >>>= (32 - bits);
+ val <<= shift;
+
+ return val >>> 0;
+ }
+ function doAlpha (alpha, bits, shift) {
+ return ((alpha & ((1 << bits) - 1)) << shift) >>> 0;
+ }
+ function alloc_colors64k (rw, gw, bw, rs, gs, bs, aw, as, alpha, byte_swap) {
+ //#define bswap_16(x) (((x) >> 8) | (((x) & 0xFF) << 8))
+ //#define bswap_32(x) (((x) << 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00) | ((x) >> 24))
+ var bpp = rw + gw + bw + aw;
+ //var j = 256;
+
+ //video_calc_gammatable();
+ for (var i = 0; i < 4096; i++) {
+ var r = ((i >> 8) << 4) | (i >> 8);
+ var g = (((i >> 4) & 0xf) << 4) | ((i >> 4) & 0x0f);
+ var b = ((i & 0xf) << 4) | (i & 0x0f);
+ //r = gamma[r + j];
+ //g = gamma[g + j];
+ //b = gamma[b + j];
+ xcolors[i] = (doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs) | doAlpha(alpha, aw, as)) >>> 0;
+ if (byte_swap) {
+ if (bpp <= 16)
+ xcolors[i] = bswap_16(xcolors[i]);
+ else
+ xcolors[i] = bswap_32(xcolors[i]);
+ }
+ if (bpp <= 16) {
+ /* Fill upper 16 bits of each colour value
+ * with a copy of the colour. */
+ xcolors[i] |= xcolors[i] * 0x00010001;
+ xcolors[i] >>>= 0;
+ }
}
+ //console.log('alloc_colors64k', xcolors);
+ }
+
+ function update_mirrors() {
+ aga_mode = (AMIGA.config.chipset.mask & CSMASK_AGA) != 0;
+ direct_rgb = aga_mode;
+ }
+
+ function docols(colentry) {
+/*#ifdef AGA
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ for (var i = 0; i < 256; i++) {
+ var v = color_reg_get (colentry, i);
+ if (v < 0 || v > 16777215)
+ continue;
+ colentry->acolors[i] = getxcolor (v);
+ }
+ } else {
+#endif*/
+ for (var i = 0; i < 32; i++) {
+ var v = color_reg_get(colentry, i);
+ if (v < 0 || v > 4095)
+ continue;
+ colentry.acolors[i] = getxcolor(v);
+ }
+/*#ifdef AGA
+ }
+#endif*/
+ }
+ function notice_new_xcolors() {
+ update_mirrors();
+ docols(current_colors);
+ docols(colors_for_drawing);
+ for (var i = 0; i < (MAXVPOS + 1) * 2; i++) {
+ docols(color_tables[0][i]);
+ docols(color_tables[1][i]);
+ }
+ }
+
+ /*---------------------------------*/
+
+ function getxcolor(c) {
+/*#ifdef AGA
+ if (direct_rgb)
+ return CONVERT_RGB(c);
+ else
+#endif*/
+ return xcolors[c];
+ }
+
+ function color_reg_get(ce, c) {
+/*#ifdef AGA
+ if (aga_mode)
+ return ce.color_regs_aga[c];
+ else
+#endif*/
+ return ce.color_regs_ecs[c];
+ }
+
+ function color_reg_set(ce, c, v) {
+/*#ifdef AGA
+ if (aga_mode)
+ ce.color_regs_aga[c] = v;
+ else
+#endif*/
+ ce.color_regs_ecs[c] = v;
+ }
+
+ function color_reg_cmp(ce1, ce2) {
+/*#ifdef AGA
+ if (aga_mode) {
+ v = memcmp (ce1->color_regs_aga, ce2->color_regs_aga, sizeof (uae_u32) * 256);
+ } else
+#endif*/
+ {
+ //v = memcmp (ce1.color_regs_ecs, ce2.color_regs_ecs, sizeof (uae_u16) * 32);
+ for (var i = 0; i < 32; i++) {
+ if (ce1.color_regs_ecs[i] != ce2.color_regs_ecs[i])
+ return 1;
+ }
+ return ce1.borderblank == ce2.borderblank ? 0 : 1;
+ }
+ }
+
+ function color_reg_cpy(dst, src) {
+ dst.borderblank = src.borderblank;
+/*#ifdef AGA
+ if (aga_mode)
+ //copy acolors and color_regs_aga
+ memcpy (dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32);
+ else
+#endif*/
+ //copy first 32 acolors and color_regs_ecs
+ //memcpy (dst.color_regs_ecs, src.color_regs_ecs, sizeof(struct color_entry));
+
+ for (var i = 0; i < 32; i++) {
+ dst.acolors[i] = src.acolors[i];
+ dst.color_regs_ecs[i] = src.color_regs_ecs[i];
+ }
+ //console.log('color_reg_cpy()', dst, src);
+ }
+
+ function color_reg_cpy_acolors(dst, src) {
+ dst.borderblank = src.borderblank;
+ for (var i = 0; i < dst.acolors.length; i++)
+ dst.acolors[i] = src.acolors[i];
+ }
+
+ /*---------------------------------*/
+
+ this.remember_ctable = function() {
+ if (next_color_entry >= COLOR_TABLE_SIZE) {
+ BUG.info('remember_ctable() BUG', next_color_entry);
+ return;
+ }
+ if (remembered_color_entry < 0) {
+ color_reg_cpy(curr_color_tables[next_color_entry], current_colors);
+ remembered_color_entry = next_color_entry++;
+ }
+ thisline_decision.ctable = remembered_color_entry;
+
+ if (color_src_match < 0 || color_dest_match != remembered_color_entry || line_decisions[next_lineno].ctable != color_src_match) {
+ var oldctable = line_decisions[next_lineno].ctable;
+ var changed = 0;
+
+ if (oldctable < 0) {
+ changed = 1;
+ color_src_match = color_dest_match = -1;
+ } else {
+ color_compare_result = color_reg_cmp(prev_color_tables[oldctable], current_colors) != 0;
+ if (color_compare_result)
+ changed = 1;
+ color_src_match = oldctable;
+ color_dest_match = remembered_color_entry;
+ }
+ thisline_changed |= changed;
+ } else {
+ if (color_compare_result)
+ thisline_changed = 1;
+ }
+ }
+
+ this.record_color_change2 = function(hpos, regno, value) {
+ //if (FAST_COLORS) //en for better?
+ //return;
+ var pos = hpos * 2;
+ if (regno == 0x1000 + 0x10c) pos++; // BPLCON4 change needs 1 lores pixel delay
+ curr_color_changes[next_color_change].linepos = pos;
+ curr_color_changes[next_color_change].regno = regno;
+ curr_color_changes[next_color_change++].value = value;
+ curr_color_changes[next_color_change].regno = -1;
+ //console.log('record_color_change2()', next_color_change);
+ }
+
+ this.record_color_change = function(hpos, regno, value) {
+ if (FAST_COLORS)
+ return;
+ if (this.vpos < minfirstline || (regno < 0x1000 && this.nodraw()))
+ return;
+
+ this.decide_diw(hpos);
+ this.decide_line(hpos);
+
+ if (thisline_decision.ctable < 0)
+ this.remember_ctable();
+
+ if ((regno < 0x1000 || regno == 0x1000 + 0x10c) && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) {
+ var pdip = curr_drawinfo[prev_lineno];
+ var idx = pdip.last_color_change;
+ var extrahpos = regno == 0x1000 + 0x10c ? 1 : 0;
+ var lastsync = false;
+
+ if (idx > 0 && curr_color_changes[idx - 1].regno == 0xffff) {
+ idx--;
+ lastsync = true;
+ }
+ pdip.last_color_change++;
+ pdip.nr_color_changes++;
+ curr_color_changes[idx].linepos = (hpos + this.maxhpos) * 2 + extrahpos;
+ curr_color_changes[idx].regno = regno;
+ curr_color_changes[idx].value = value;
+ if (lastsync) {
+ curr_color_changes[idx + 1].linepos = hsyncstartpos * 2;
+ curr_color_changes[idx + 1].regno = 0xffff;
+ curr_color_changes[idx + 2].regno = -1;
+ } else
+ curr_color_changes[idx + 1].regno = -1;
+ }
+ this.record_color_change2(hpos, regno, value);
+ }
+
+ this.isbrdblank = function(hpos, con0, con3) {
+ var brdblank = (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) != 0 && (con0 & 1) != 0 && (con3 & 0x20) != 0;
+
+ if (hpos >= 0 && current_colors.borderblank != brdblank) {
+ if (!FAST_COLORS) {
+ this.record_color_change(hpos, 0, (COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0)) >>> 0);
+ remembered_color_entry = -1;
+ }
+ current_colors.borderblank = brdblank;
+ }
+ return brdblank;
+ }
+
+ this.record_register_change = function(hpos, regno, value) {
+ if (regno == 0x100) { // BPLCON0
+ if (value & 0x800)
+ thisline_decision.ham_seen = 1;
+ thisline_decision.ehb_seen = is_ehb(value, bplcon2);
+ this.isbrdblank(hpos, value, bplcon3);
+ } else if (regno == 0x104) // BPLCON2
+ thisline_decision.ehb_seen = is_ehb(bplcon0, value);
+ else if (regno == 0x106) // BPLCON3
+ this.isbrdblank(hpos, bplcon0, value);
+
+ if (!FAST_COLORS)
+ this.record_color_change(hpos, regno + 0x1000, value);
+ }
+
+ /*---------------------------------*/
+
+ this.compute_vsynctime = function() {
+ if (AMIGA.config.chipset.refreshrate > 0)
+ this.vblank_hz = AMIGA.config.chipset.refreshrate;
+
+ AMIGA.events.calc_vsynctimebase(this.vblank_hz);
+
+ if (AMIGA.config.audio.enabled && AMIGA.config.audio.mode > 0)
+ AMIGA.audio.calc_sample_evtime(this.vblank_hz, (bplcon0 & 4) ? -1 : this.lof_store, this.is_linetoggle());
+ }
+
+ this.compute_framesync = function() {
+ var islace = interlace_seen ? 1 : 0;
+ var isntsc = (beamcon0 & 0x20) ? 0 : 1;
+ var found = false;
+
+ interlace_changed = 0;
+ gfxvidinfo.drawbuffer.inxoffset = -1;
+ gfxvidinfo.drawbuffer.inyoffset = -1;
+
+ if (beamcon0 & 0x80) {
+ var res = GET_RES_AGNUS(bplcon0);
+ var vres = islace ? 1 : 0;
+ var res2, vres2;
+
+ res2 = AMIGA.config.video.hresolution;
+ if (doublescan > 0)
+ res2++;
+ if (res2 > RES_MAX)
+ res2 = RES_MAX;
+
+ vres2 = AMIGA.config.video.vresolution;
+ if (doublescan > 0 && !islace)
+ vres2--;
+
+ if (vres2 < 0)
+ vres2 = 0;
+ if (vres2 > VRES_QUAD)
+ vres2 = VRES_QUAD;
+
+ var start = this.hbstrt;
+ var stop = this.hbstop;
+
+ gfxvidinfo.drawbuffer.inwidth = (((start > stop ? (this.maxhpos - (this.maxhpos - start + stop)) : (this.maxhpos - (stop - start) + 2)) * 2) << res2);
+ gfxvidinfo.drawbuffer.inxoffset = ((stop + 1) & ~1) * 2;
+
+ gfxvidinfo.drawbuffer.extrawidth = 0;
+ gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
+
+ gfxvidinfo.drawbuffer.inheight = (this.maxvpos - minfirstline) << vres2;
+ gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
+ } else {
+ gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << AMIGA.config.video.hresolution;
+ gfxvidinfo.drawbuffer.extrawidth = AMIGA.config.video.extrawidth ? AMIGA.config.video.extrawidth : -1;
+ gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
+ gfxvidinfo.drawbuffer.inheight = (this.maxvpos_nom - minfirstline + 1) << AMIGA.config.video.vresolution;
+ gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
+ }
+
+ if (gfxvidinfo.drawbuffer.inwidth > gfxvidinfo.drawbuffer.width_allocated)
+ gfxvidinfo.drawbuffer.inwidth = gfxvidinfo.drawbuffer.width_allocated;
+ if (gfxvidinfo.drawbuffer.inwidth2 > gfxvidinfo.drawbuffer.width_allocated)
+ gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.width_allocated;
+
+ if (gfxvidinfo.drawbuffer.inheight > gfxvidinfo.drawbuffer.height_allocated)
+ gfxvidinfo.drawbuffer.inheight = gfxvidinfo.drawbuffer.height_allocated;
+ if (gfxvidinfo.drawbuffer.inheight2 > gfxvidinfo.drawbuffer.height_allocated)
+ gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.height_allocated;
+
+ gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.inwidth;
+ gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.inheight;
+
+ if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width_allocated)
+ gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width_allocated;
+
+ if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height_allocated)
+ gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height_allocated;
+
+ //if (target_graphics_buffer_update()) this.reset_drawing();
+
+ for (var i = 0; i < 2 * (MAXVPOS + 2) + 1; i++) //memset (line_decisions, 0, sizeof line_decisions);
+ line_decisions[i].clr();
+
+ this.compute_vsynctime();
+
+ BUG.info('%s mode%s%s V=%.4fHz H=%.4fHz (%dx%d+%d)',
+ isntsc ? 'NTSC' : 'PAL',
+ islace ? ' lace' : '',
+ doublescan > 0 ? ' dblscan' : '',
+ this.vblank_hz,
+ (AMIGA.config.video.ntsc ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL) / (this.maxhpos + (this.is_linetoggle() ? 0.5 : 0)),
+ this.maxhpos, this.maxvpos, this.lof_store ? 1 : 0
+ );
+ }
+
+ this.init_hz = function(fullinit) {
+ var isntsc, islace;
+ var odbl = doublescan, omaxvpos = this.maxvpos;
+ var ovblank = this.vblank_hz;
+ var hzc = 0;
+
+ if (fullinit)
+ this.vpos_count = 0;
+
+ this.vpos_count_diff = this.vpos_count;
+
+ doublescan = 0;
+ //programmedmode = false;
+ if ((beamcon0 & 0xA0) != (new_beamcon0 & 0xA0))
+ hzc = 1;
+ if (beamcon0 != new_beamcon0) {
+ BUG.info('init_hz() BEAMCON0 %04x -> %04x', beamcon0, new_beamcon0);
+ this.vpos_count_diff = this.vpos_count = 0;
+ }
+ beamcon0 = new_beamcon0;
+ isntsc = (beamcon0 & 0x20) ? 0 : 1;
+ islace = (interlace_seen) ? 1 : 0;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ isntsc = AMIGA.config.video.ntsc ? 1 : 0;
+ if (!isntsc) {
+ this.maxvpos = MAXVPOS_PAL;
+ this.maxhpos = MAXHPOS_PAL;
+ this.vblank_hz = VBLANK_HZ_PAL;
+ minfirstline = VBLANK_ENDLINE_PAL;
+ sprite_vblank_endline = VBLANK_SPRITE_PAL;
+ equ_vblank_endline = EQU_ENDLINE_PAL;
+ equ_vblank_toggle = true;
+ } else {
+ this.maxvpos = MAXVPOS_NTSC;
+ this.maxhpos = MAXHPOS_NTSC;
+ this.vblank_hz = VBLANK_HZ_NTSC;
+ minfirstline = VBLANK_ENDLINE_NTSC;
+ sprite_vblank_endline = VBLANK_SPRITE_NTSC;
+ equ_vblank_endline = EQU_ENDLINE_NTSC;
+ equ_vblank_toggle = false;
+ }
+ // long/short field refresh rate adjustment
+ //this.vblank_hz >>= (AMIGA.config.video.framerate > 1 ? 1 : 0);
+ this.vblank_hz = this.vblank_hz * (this.maxvpos * 2 + 1) / ((this.maxvpos + this.lof_current) * 2);
+
+ this.maxvpos_nom = this.maxvpos;
+ if (this.vpos_count > 0) {
+ BUG.info('init_hz() poked VPOSW at %d', this.vpos_count);
+ // we come here if this.vpos_count != this.maxvpos and beamcon0 didn't change (someone poked VPOSW)
+ if (this.vpos_count < 10)
+ this.vpos_count = 10;
+ this.vblank_hz = (isntsc ? 15734 : 15625) / this.vpos_count;
+ this.maxvpos_nom = this.vpos_count - (this.lof_current ? 1 : 0);
+ this.reset_drawing();
+ }
+ if (beamcon0 & 0x80) {
+ // programmable scanrates (ECS Agnus)
+ if (this.vtotal >= MAXVPOS)
+ this.vtotal = MAXVPOS - 1;
+ this.maxvpos = this.vtotal + 1;
+ if (this.htotal >= MAXHPOS)
+ this.htotal = MAXHPOS - 1;
+ this.maxhpos = this.htotal + 1;
+ this.vblank_hz = 227 * 312 * 50 / (this.maxvpos * this.maxhpos);
+ minfirstline = this.vsstop > this.vbstop ? this.vsstop : this.vbstop;
+ if (minfirstline > this.maxvpos / 2)
+ minfirstline = this.vsstop > this.vsstop ? this.vbstop : this.vsstop;
+ if (minfirstline < 2)
+ minfirstline = 2;
+ if (minfirstline >= this.maxvpos)
+ minfirstline = this.maxvpos - 1;
+ sprite_vblank_endline = minfirstline - 2;
+ this.maxvpos_nom = this.maxvpos;
+ equ_vblank_endline = -1;
+ doublescan = this.htotal <= 164 ? 1 : 0;
+ //programmedmode = true;
+ this.dumpsync();
+ hzc = 1;
+ }
+ if (this.maxvpos_nom >= MAXVPOS)
+ this.maxvpos_nom = MAXVPOS;
+ if (AMIGA.config.video.scandoubler && doublescan == 0)
+ doublescan = -1;
+
+ if (doublescan != odbl || this.maxvpos != omaxvpos)
+ hzc = 1;
+ if (this.vblank_hz < 10)
+ this.vblank_hz = 10;
+ if (this.vblank_hz > 300)
+ this.vblank_hz = 300;
+ this.maxhpos_short = this.maxhpos;
+ if (beamcon0 & 0x80) {
+ if (this.hbstrt > this.maxhpos)
+ hsyncstartpos = this.hbstrt;
+ else
+ hsyncstartpos = this.maxhpos + this.hbstrt;
+ if (this.hbstop > this.maxhpos)
+ hsyncendpos = this.maxhpos - this.hbstop;
+ else
+ hsyncendpos = this.hbstop;
+ } else {
+ hsyncstartpos = this.maxhpos_short + 13;
+ hsyncendpos = 24;
+ }
+
+ AMIGA.events.eventtab[EV_HSYNC].evtime = AMIGA.events.currcycle + this.maxhpos * CYCLE_UNIT;
+ AMIGA.events.eventtab[EV_HSYNC].oldcycles = AMIGA.events.currcycle;
+ AMIGA.events.schedule();
+
+ if (hzc) {
+ interlace_seen = islace;
+ this.reset_drawing();
+ }
+
+ this.maxvpos_total = (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 2047 : 511;
+ if (this.maxvpos_total > MAXVPOS)
+ this.maxvpos_total = MAXVPOS;
+/*#ifdef PICASSO96
+ if (!p96refresh_active) {
+ maxvpos_stored = this.maxvpos;
+ maxhpos_stored = this.maxhpos;
+ vblank_hz_stored = this.vblank_hz;
+ }
+#endif*/
+ this.compute_framesync();
+/*#ifdef PICASSO96
+ init_hz_p96 ();
+#endif*/
+ if (fullinit)
+ this.vpos_count_diff = this.maxvpos_nom;
+ }
+
+ this.BPLxPTH = function(hpos, v, num) {
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ bplpt[num] = ((v << 16) | (bplpt[num] & 0xffff)) >>> 0;
+ bplptx[num] = ((v << 16) | (bplptx[num] & 0xffff)) >>> 0;
+ //BUG.info('%d:%d:BPL%dPTH %08X', hpos, this.vpos, num, bplpt[num]);
+ }
+
+ this.BPLxPTL = function(hpos, v, num) {
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ //if (AMIGA.copper.access && this.is_bitplane_dma(hpos + 1) == num + 1) return;
+
+ bplpt[num] = ((bplpt[num] & 0xffff0000) | (v & 0xfffe)) >>> 0;
+ bplptx[num] = ((bplptx[num] & 0xffff0000) | (v & 0xfffe)) >>> 0;
+ //BUG.info('%d:%d:BPL%dPTL %08X', hpos, this.vpos, num, bplpt[num]);
+ }
+
+ this.BPLxDAT = function(hpos, v, num) {
+ if (num == 0 && hpos >= 7) {
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ }
+ bplxdat[num] = v;
+ if (num == 0 && hpos >= 7) {
+ bpl1dat_written = true;
+ bpl1dat_written_at_least_once = true;
+ if (thisline_decision.plfleft < 0) {
+ thisline_decision.plfleft = hpos & ~3;
+ this.reset_bpl_vars();
+ this.compute_delay_offset();
+ }
+ this.update_bpldats(hpos);
+ }
+ }
+
+ this.BPLCON0_Denise = function(hpos, v, immediate) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE))
+ v &= ~0x00F1;
+ else if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v &= ~0x00B0;
+ v &= ~(0x0200 | 0x0100 | 0x0080 | 0x0020);
+/*#if SPRBORDER
+ v |= 1;
+#endif*/
+ if (bplcon0_d == v)
+ return;
+
+ bplcon0_dd = -1;
+ if (is_ehb(bplcon0_d, bplcon2))
+ v |= 0x80;
+
+ if (immediate)
+ this.record_register_change(hpos, 0x100, v);
+ else
+ this.record_register_change(hpos, 0x100, (bplcon0_d & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80 | 0x01)));
+
+ bplcon0_d = v & ~0x80;
+
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) {
+ this.decide_sprites(hpos);
+ sprres = expand_sprres(v, bplcon3);
+ }
+ if (thisline_decision.plfleft < 0)
+ this.update_denise(hpos);
+ }
+
+ this.BPLCON0 = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE))
+ v &= ~0x00F1;
+ else if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v &= ~0x00B0;
+ v &= ~(0x0080 | 0x0020);
+
+/*#if SPRBORDER
+ v |= 1;
+#endif*/
+ if (bplcon0 == v)
+ return;
+
+ if (!this.issyncstopped()) {
+ vpos_previous = this.vpos;
+ hpos_previous = hpos;
+ }
+
+ if ((bplcon0 & 4) != (v & 4))
+ this.checklacecount((v & 4) != 0);
+
+ bplcon0 = v;
+
+ this.bpldmainitdelay(hpos);
+
+ if (thisline_decision.plfleft < 0)
+ this.BPLCON0_Denise(hpos, v, true);
+ }
+
+ this.BPLCON1 = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v &= 0xff;
+ if (bplcon1 == v)
+ return;
+ ddf_change = this.vpos;
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ bplcon1_hpos = hpos;
+ bplcon1 = v;
+ }
+
+ this.BPLCON2 = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v &= 0x7f;
+ if (bplcon2 == v)
+ return;
+ this.decide_line(hpos);
+ bplcon2 = v;
+ this.record_register_change(hpos, 0x104, v);
+ }
+
+ this.BPLCON3 = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE))
+ return;
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA)) {
+ v &= 0x003f;
+ v |= 0x0c00;
+ }
+/*#if SPRBORDER
+ v |= 2;
+#endif*/
+ if (bplcon3 == v)
+ return;
+ this.decide_line(hpos);
+ this.decide_sprites(hpos);
+ bplcon3 = v;
+ sprres = expand_sprres(bplcon0, bplcon3);
+ this.record_register_change(hpos, 0x106, v);
+ }
+
+/*#ifdef AGA
+ this.BPLCON4 = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ return;
+ if (bplcon4 == v)
+ return;
+ this.decide_line(hpos);
+ bplcon4 = v;
+ this.record_register_change(hpos, 0x10c, v);
+ }
+#endif*/
+
+ function castWord(v) { return (v & 0x8000) ? (v - 0x10000) : v; }
+
+ this.BPL1MOD = function(hpos, v) {
+ v &= ~1;
+ if (bpl1mod == castWord(v))
+ return;
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ bpl1mod = castWord(v);
+ }
+
+ this.BPL2MOD = function(hpos, v) {
+ v &= ~1;
+ if (bpl2mod == castWord(v))
+ return;
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ bpl2mod = castWord(v);
+ }
+
+ this.calcdiw = function() {
+ var hstrt = diwstrt & 0xFF;
+ var hstop = diwstop & 0xFF;
+ var vstrt = diwstrt >> 8;
+ var vstop = diwstop >> 8;
+
+ // vertical in ECS Agnus
+ if (diwhigh_written && (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) {
+ vstrt |= (diwhigh & 7) << 8;
+ vstop |= ((diwhigh >> 8) & 7) << 8;
+ } else {
+ if ((vstop & 0x80) == 0)
+ vstop |= 0x100;
+ }
+ // horizontal in ECS Denise
+ if (diwhigh_written && (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE)) {
+ hstrt |= ((diwhigh >> 5) & 1) << 8;
+ hstop |= ((diwhigh >> 13) & 1) << 8;
+ } else {
+ hstop += 0x100;
+ }
+
+ diw_hstrt = hstrt;
+ diw_hstop = hstop;
+
+ diwfirstword = coord_diw_to_window_x(hstrt);
+ diwlastword = coord_diw_to_window_x(hstop);
+ if (diwfirstword >= diwlastword) {
+ diwfirstword = 0;
+ diwlastword = max_diwlastword();
+ }
+ if (diwfirstword < 0)
+ diwfirstword = 0;
+
+ plffirstline = vstrt;
+ plflastline = vstop;
+
+ plfstrt = ddfstrt;
+ plfstop = ddfstop;
+ /* probably not the correct place.. should use plf_state instead */
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
+ /* ECS/AGA and ddfstop > maxhpos == always-on display */
+ if (plfstop > this.maxhpos)
+ plfstrt = 0;
+ if (plfstrt < HARD_DDF_START)
+ plfstrt = HARD_DDF_START;
+ plfstrt_start = plfstrt - 4;
+ } else {
+ /* OCS and ddfstrt >= ddfstop == ddfstop = max */
+ if (plfstrt >= plfstop && plfstrt >= HARD_DDF_START)
+ plfstop = 0xff;
+ plfstrt_start = HARD_DDF_START - 2;
+ }
+ diw_change = 2;
+ //console.log('calcdiw', hstrt,hstop,vstrt,vstop, plfstrt,plfstop);
+ }
+
+ this.DIWSTRT = function(hpos, v) {
+ if (diwstrt == v && !diwhigh_written)
+ return;
+ this.decide_diw(hpos);
+ this.decide_line(hpos);
+ diwhigh_written = false;
+ diwstrt = v;
+ this.calcdiw();
+ }
+
+ this.DIWSTOP = function(hpos, v) {
+ if (diwstop == v && !diwhigh_written)
+ return;
+ this.decide_diw(hpos);
+ this.decide_line(hpos);
+ diwhigh_written = false;
+ diwstop = v;
+ this.calcdiw();
+ }
+
+ this.DIWHIGH = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & (CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS)))
+ return;
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v &= ~(0x0008 | 0x0010 | 0x1000 | 0x0800);
+ v &= ~(0x8000 | 0x4000 | 0x0080 | 0x0040);
+ if (diwhigh_written && diwhigh == v)
+ return;
+ this.decide_line(hpos);
+ diwhigh_written = true;
+ diwhigh = v;
+ this.calcdiw();
+ }
+
+ this.DDFSTRT = function(hpos, v) {
+ v &= 0xfe;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ v &= 0xfc;
+ if (ddfstrt == v && hpos + 2 != ddfstrt)
+ return;
+ ddf_change = this.vpos;
+ this.decide_line(hpos);
+ ddfstrt_old_hpos = hpos;
+ ddfstrt = v;
+ this.calcdiw();
+ /*if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) {
+ static int last_warned;
+ last_warned = (last_warned + 1) & 4095;
+ if (last_warned == 0) BUG.info('WARNING! Very strange DDF values (%x %x).', ddfstrt, ddfstop);
+ }*/
+ }
+
+ this.DDFSTOP = function(hpos, v) {
+ v &= 0xfe;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ v &= 0xfc;
+ if (ddfstop == v && hpos + 2 != ddfstop)
+ return;
+ ddf_change = this.vpos;
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+ ddfstop = v;
+ this.calcdiw();
+ if (fetch_state != FETCH_NOT_STARTED)
+ this.estimate_last_fetch_cycle(hpos);
+ /*if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) {
+ static int last_warned;
+ if (last_warned == 0) BUG.info('WARNING! Very strange DDF values (%x).', ddfstop);
+ last_warned = (last_warned + 1) & 4095;
+ }*/
+ }
+
+ this.FMODE = function(hpos, v) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
+ v = 0;
+ v &= 0xC00F;
+ if (fmode == v)
+ return;
+ ddf_change = this.vpos;
+ fmode = v;
+ sprite_width = GET_SPRITEWIDTH(fmode);
+ this.bpldmainitdelay(hpos);
+ }
+
+ this.checkautoscalecol0 = function() {
+ if (!AMIGA.copper.access || this.vpos < 20 || this.isbrdblank(-1, bplcon0, bplcon3))
+ return;
+ // autoscale if copper changes COLOR00 on top or bottom of screen
+ if (this.vpos >= minfirstline) {
+ var vpos2 = autoscale_bordercolors ? minfirstline : this.vpos;
+ if (first_planes_vpos == 0)
+ first_planes_vpos = vpos2 - 2;
+ if (plffirstline_total == this.current_maxvpos())
+ plffirstline_total = vpos2 - 2;
+ if (vpos2 > last_planes_vpos || vpos2 > plflastline_total)
+ plflastline_total = last_planes_vpos = vpos2 + 3;
+ autoscale_bordercolors = 0;
+ } else
+ autoscale_bordercolors++;
+ }
+
+ this.COLOR_WRITE = function(hpos, v, num) {
+ //var colzero = false;
+ v &= 0xFFF;
+/*#ifdef AGA
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ int r,g,b;
+ int cr,cg,cb;
+ int colreg;
+ uae_u32 cval;
+
+ if (bplcon2 & 0x0100)
+ return;
+
+ colreg = ((bplcon3 >> 13) & 7) * 32 + num;
+ r = (v & 0xF00) >> 8;
+ g = (v & 0xF0) >> 4;
+ b = (v & 0xF) >> 0;
+ cr = current_colors.color_regs_aga[colreg] >> 16;
+ cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
+ cb = current_colors.color_regs_aga[colreg] & 0xFF;
+
+ if (bplcon3 & 0x200) {
+ cr &= 0xF0; cr |= r;
+ cg &= 0xF0; cg |= g;
+ cb &= 0xF0; cb |= b;
+ } else {
+ cr = r + (r << 4);
+ cg = g + (g << 4);
+ cb = b + (b << 4);
+ color_regs_aga_genlock[colreg] = v >> 15;
+ }
+ cval = (cr << 16) | (cg << 8) | cb;
+ if (cval && colreg == 0)
+ colzero = true;
+
+ if (cval == current_colors.color_regs_aga[colreg])
+ return;
+
+ if (colreg == 0)
+ this.checkautoscalecol0 ();
+
+ //Call this with the old table still intact.
+ this.record_color_change (hpos, colreg, cval);
+ remembered_color_entry = -1;
+ current_colors.color_regs_aga[colreg] = cval;
+ current_colors.acolors[colreg] = getxcolor (cval);
+
+ } else {
+#endif*/
+ //if (num && v == 0) colzero = true;
+
+ if (!FAST_COLORS) {
+ if (current_colors.color_regs_ecs[num] == v)
+ return;
+ }
+ if (num == 0)
+ this.checkautoscalecol0();
+
+ if (!FAST_COLORS) {
+ this.record_color_change(hpos, num, v);
+ remembered_color_entry = -1;
+ }
+ current_colors.color_regs_ecs[num] = v;
+ current_colors.acolors[num] = getxcolor(v);
+/*#ifdef AGA
+ }
+#endif*/
+ }
+
+ /*this.islightpentriggered = function() {
+ if (beamcon0 & 0x2000) // LPENDIS
+ return 0;
+ return lightpen_triggered > 0;
+ }
+ this.GETVPOS = function() {
+ return this.islightpentriggered() ? vpos_lpen : (this.issyncstopped() ? vpos_previous : this.vpos);
+ }
+ this.GETHPOS = function() {
+ return this.islightpentriggered() ? hpos_lpen : (this.issyncstopped() ? hpos_previous : this.hpos());
}*/
-
- const RES_LORES = 0;
- const RES_HIRES = 1;
- const RES_SUPERHIRES = 2;
+ this.issyncstopped = function() {
+ return (bplcon0 & 2) != 0 && !AMIGA.config.chipset.genlock;
+ }
+ this.GETVPOS = function() {
+ return this.issyncstopped() ? vpos_previous : this.vpos;
+ }
+ this.GETHPOS = function() {
+ return this.issyncstopped() ? hpos_previous : this.hpos();
+ }
- this.GET_RES_DENISE = function (con0) {
- //if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
- con0 &= ~0x40; // SUPERHIRES
- return (con0 & 0x8000) ? RES_HIRES : (con0 & 0x40) ? RES_SUPERHIRES : RES_LORES;
- }
- this.GET_RES_AGNUS = function (con0) {
- //if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
- con0 &= ~0x40; // SUPERHIRES
- return (con0 & 0x8000) ? RES_HIRES : (con0 & 0x40) ? RES_SUPERHIRES : RES_LORES;
- }
- this.GET_PLANES = function (con0) {
- if ((con0 & 0x0010) && (con0 & 0x7000))
- return 0; // >8 planes = 0 planes
- if (con0 & 0x0010)
- return 8; // AGA 8-planes bit
- return (con0 >> 12) & 7; // normal planes bits
- }
-
- this.GET_PLANES_LIMIT = function (con0) {
- var res = this.GET_RES_AGNUS (con0);
- var planes = this.GET_PLANES (con0);
- return real_bitplane_number[fetchmode][res][planes];
- }
+ const HPOS_OFFSET = 3; //(currprefs.cpu_model < 68020 ? 3 : 0)
+ this.VPOSR = function() {
+ var vp = this.GETVPOS();
+ var hp = this.GETHPOS();
+ //var vp = this.vpos;
+ //var hp = this.hpos();
+ var csbit = 0;
- this.setup_fmodes = function (hpos) {
+ if (hp + HPOS_OFFSET >= this.maxhpos) {
+ vp++;
+ if (vp >= this.maxvpos + this.lof_store)
+ vp = 0;
+ }
+ vp = (vp >> 8) & 7;
+
+ if (AMIGA.config.chipset.agnus_rev >= 0)
+ csbit |= AMIGA.config.chipset.agnus_rev << 8;
+ else {
+/*#ifdef AGA
+ csbit |= (AMIGA.config.chipset.mask & CSMASK_AGA) ? 0x2300 : 0;
+#endif*/
+ csbit |= (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0;
+ if (AMIGA.mem.chip.size > 1024 * 1024 && (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ csbit |= 0x2100;
+ if (AMIGA.config.video.ntsc)
+ csbit |= 0x1000;
+ }
+
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ vp &= 1;
+ vp = vp | (this.lof_store ? 0x8000 : 0) | csbit;
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)
+ vp |= this.lol ? 0x80 : 0;
+
+ //BUG.info('VPOSR $%x', vp);
+ return vp;
+ }
+
+ this.VPOSW = function(v) {
+ if (this.lof_store != ((v & 0x8000) ? 1 : 0)) {
+ this.lof_store = (v & 0x8000) ? 1 : 0;
+ this.lof_changing = this.lof_store ? 1 : -1;
+ }
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
+ this.lol = (v & 0x0080) ? 1 : 0;
+ if (!this.is_linetoggle())
+ this.lol = 0;
+ }
+ if (this.lof_changing)
+ return;
+
+ v &= 7;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ v &= 1;
+
+ this.vpos &= 0x00ff;
+ this.vpos |= v << 8;
+ //BUG.info('VPOSW $%x', this.vpos);
+ }
+
+ this.VHPOSW = function(v) {
+ this.vpos &= 0xff00;
+ this.vpos |= v >> 8;
+ //BUG.info('VHPOSW %x %d', v, this.vpos);
+ }
+
+ this.VHPOSR = function() {
+ var vp = this.GETVPOS();
+ var hp = this.GETHPOS();
+ //var vp = this.vpos;
+ //var hp = this.hpos();
+
+ hp += HPOS_OFFSET;
+ if (hp >= this.maxhpos) {
+ hp -= this.maxhpos;
+ vp++;
+ if (vp >= this.maxvpos + this.lof_store)
+ vp = 0;
+ }
+ if (HPOS_OFFSET) {
+ hp += 1;
+ if (hp >= this.maxhpos)
+ hp -= this.maxhpos;
+ }
+ vp &= 0xff;
+ hp &= 0xff;
+
+ vp <<= 8;
+ vp |= hp;
+
+ //BUG.info('VHPOSR $%x', vp);
+ return vp;
+ }
+
+ this.BEAMCON0 = function(v) {
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE))
+ v &= 0x20;
+
+ if (v != new_beamcon0) {
+ new_beamcon0 = v;
+ if (v & ~0x20)
+ BUG.info('BEAMCON0() $%04x written.', v);
+ }
+ }
+ }
+
+ this.DENISEID = function() {
+ if (AMIGA.config.chipset.denise_rev >= 0)
+ return [0, AMIGA.config.chipset.denise_rev];
+/*#ifdef AGA
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ if (currprefs.cs_ide == IDE_A4000) return [0, 0xFCF8];
+ return [0, 0x00F8];
+ }
+#endif*/
+ if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE)
+ return [0, 0xFFFC];
+
+ if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible)
+ return [1, 0xFFFF];
+ return [0, 0xFFFF];
+ }
+
+ /*---------------------------------*/
+
+ this.is_bitplane_dma = function(hpos) {
+ if (hpos < plfstrt)
+ return 0;
+ if ((plf_state == PLF_END && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle)
+ return 0;
+
+ return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
+ }
+
+ this.update_denise = function(hpos) {
+ toscr_res = GET_RES_DENISE(bplcon0_d);
+ if (bplcon0_dd != bplcon0_d) {
+ this.record_color_change2(hpos, 0x100 + 0x1000, bplcon0_d);
+ bplcon0_dd = bplcon0_d;
+ }
+ toscr_nr_planes = GET_PLANES(bplcon0_d);
+
+ if (!(AMIGA.config.chipset.mask & CSMASK_AGA) && bplcon0_res == 0 && bplcon0_planes == 7) { //OCS 7 planes
+ if (toscr_nr_planes2 < 6)
+ toscr_nr_planes2 = 6;
+ } else
+ toscr_nr_planes2 = toscr_nr_planes;
+ }
+
+ this.setup_fmodes = function(hpos) {
switch (fmode & 3) {
case 0:
fetchmode = 0;
@@ -1327,50 +4703,1543 @@ function Playfield() {
fetchmode = 2;
break;
}
- //badmode = GET_RES_AGNUS (bplcon0) != GET_RES_DENISE (this.bplcon0);
- bplcon0_res = this.GET_RES_AGNUS (this.bplcon0);
- bplcon0_planes = this.GET_PLANES (this.bplcon0);
- bplcon0_planes_limit = this.GET_PLANES_LIMIT (this.bplcon0);
- //console.log(bplcon0_res, bplcon0_planes, bplcon0_planes_limit);
+ badmode = GET_RES_AGNUS(bplcon0) != GET_RES_DENISE(bplcon0);
+ bplcon0_res = GET_RES_AGNUS(bplcon0);
+ bplcon0_planes = GET_PLANES(bplcon0);
+ bplcon0_planes_limit = GET_PLANES_LIMIT(bplcon0);
fetchunit = fetchunits[fetchmode * 4 + bplcon0_res];
fetchunit_mask = fetchunit - 1;
fetchstart_shift = fetchstarts[fetchmode * 4 + bplcon0_res];
fetchstart = 1 << fetchstart_shift;
fetchstart_mask = fetchstart - 1;
- /*fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res];
+ fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res];
fm_maxplane = 1 << fm_maxplane_shift;
- fetch_modulo_cycle = fetchunit - fetchstart;
- if (is_bitplane_dma (hpos - 1)) cycle_line[hpos - 1] = 1;*/
+ fetch_modulo_cycle = fetchunit - fetchstart;
curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit];
- //console.log(curr_diagram);
- //console.log(fetchstart_mask);
- //estimate_last_fetch_cycle (hpos);
- //if (bpldmasetuphpos >= 0 && debug_dma) record_dma_event (DMA_EVENT_BPLFETCHUPDATE, hpos, vpos);
- /*bpldmasetuphpos = -1;
+ this.estimate_last_fetch_cycle(hpos);
+ bpldmasetuphpos = -1;
bpldmasetupphase = 0;
- ddf_change = vpos;*/
- //console.log('setup_fmodes()', fetchstart, fetchstart_shift, fetchstart_mask, curr_diagram);
+ ddf_change = this.vpos;
+ }
+
+ this.maybe_setup_fmodes = function(hpos) {
+ switch (bpldmasetupphase) {
+ case 0:
+ this.BPLCON0_Denise(hpos, bplcon0, false);
+ bpldmasetupphase++;
+ bpldmasetuphpos += (4 + (bplcon0_planes == 8 ? 1 : 0)) - BPLCON_DENISE_DELAY;
+ break;
+ case 1:
+ this.setup_fmodes(hpos);
+ break;
+ }
}
- this.is_bitplane_dma = function (hpos) {
- if (hpos < this.state.dstart*2) //plfstrt)
- return 0;
- //if ((plf_state == plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle)
- if (hpos >= this.state.dstop*2) //|| hpos >= estimated_last_fetch_cycle)
- return 0;
+ this.maybe_check = function(hpos) {
+ if (bpldmasetuphpos > 0 && hpos >= bpldmasetuphpos)
+ this.maybe_setup_fmodes(hpos);
+ }
- //console.log(hpos - this.state.hstart);
- //return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask];
- return curr_diagram[hpos & fetchstart_mask];
+ this.compute_delay_offset = function() {
+ delayoffset = (16 << fetchmode) - (((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1);
+ }
+
+ this.compute_toscr_delay_1 = function(con1) {
+ var delay1 = (con1 & 0x0f) | ((con1 & 0x0c00) >> 6);
+ var delay2 = ((con1 >> 4) & 0x0f) | (((con1 >> 4) & 0x0c00) >> 6);
+ var shdelay1 = (con1 >> 12) & 3;
+ var shdelay2 = (con1 >> 8) & 3;
+ var delaymask;
+ var fetchwidth = 16 << fetchmode;
+
+ delay1 += delayoffset;
+ delay2 += delayoffset;
+ delaymask = (fetchwidth - 1) >> toscr_res;
+ toscr_delay1 = (delay1 & delaymask) << toscr_res;
+ toscr_delay1 |= shdelay1 >> (RES_MAX - toscr_res);
+ toscr_delay2 = (delay2 & delaymask) << toscr_res;
+ toscr_delay2 |= shdelay2 >> (RES_MAX - toscr_res);
}
- this.get_data = function() {
- return [
- this.state.hstart,
- this.state.hstop - (16 << fetchmode),
- cycle_diagram_total_cycles[fetchmode][this.GET_RES_AGNUS(this.bplcon0)][this.GET_PLANES_LIMIT(this.bplcon0)],
- cycle_diagram_free_cycles[fetchmode][this.GET_RES_AGNUS(this.bplcon0)][this.GET_PLANES_LIMIT(this.bplcon0)]
- ]
+ this.compute_toscr_delay = function(hpos, con1) {
+ this.update_denise(hpos);
+ this.compute_toscr_delay_1(con1);
+ }
+
+ this.update_toscr_planes = function() {
+ if (toscr_nr_planes2 > thisline_decision.nr_planes) {
+ for (var j = thisline_decision.nr_planes; j < toscr_nr_planes2; j++) {
+ if (!thisline_changed) {
+ for (var i = 0; i < out_offs; i++) {
+ if (line_data[next_lineno][j][i]) {
+ thisline_changed = 1;
+ break;
+ }
+ }
+ }
+ for (var i = 0; i < out_offs; i++) line_data[next_lineno][j][i] = 0; //memset(ptr, 0, out_offs * 4);
+ }
+ thisline_decision.nr_planes = toscr_nr_planes2;
+ }
+ }
+
+ this.maybe_first_bpl1dat = function(hpos) {
+ if (thisline_decision.plfleft >= 0) {
+ if (plfleft_real < 0) {
+ for (var i = 0; i < MAX_PLANES; i++) {
+ todisplay[i][0] = 0;
+/*#ifdef AGA
+ todisplay[i][1] = 0;
+ todisplay[i][2] = 0;
+ todisplay[i][3] = 0;
+#endif*/
+ }
+ plfleft_real = hpos;
+ bpl1dat_early = true;
+ }
+ } else {
+ plfleft_real = thisline_decision.plfleft = hpos;
+ this.compute_delay_offset();
+ }
+ }
+
+ this.checklacecount = function(lace) {
+ if (lace === null)
+ lace = (bplcon0 & 4) != 0;
+
+ if (!interlace_changed) {
+ if (nlace_cnt >= NLACE_CNT_NEEDED && lace) {
+ lof_togglecnt_lace = LOF_TOGGLES_NEEDED;
+ lof_togglecnt_nlace = 0;
+ //BUG.info('immediate lace');
+ nlace_cnt = 0;
+ } else if (nlace_cnt <= -NLACE_CNT_NEEDED && !lace) {
+ lof_togglecnt_nlace = LOF_TOGGLES_NEEDED;
+ lof_togglecnt_lace = 0;
+ //BUG.info('immediate nlace');
+ nlace_cnt = 0;
+ }
+ }
+ if (lace) {
+ if (nlace_cnt > 0)
+ nlace_cnt = 0;
+ nlace_cnt--;
+ if (nlace_cnt < -NLACE_CNT_NEEDED * 2)
+ nlace_cnt = -NLACE_CNT_NEEDED * 2;
+ } else if (!lace) {
+ if (nlace_cnt < 0)
+ nlace_cnt = 0;
+ nlace_cnt++;
+ if (nlace_cnt > NLACE_CNT_NEEDED * 2)
+ nlace_cnt = NLACE_CNT_NEEDED * 2;
+ }
}
+ var dumpcnt = 100;
+ this.dumpsync = function() {
+ if (dumpcnt < 0)
+ return;
+ dumpcnt--;
+ BUG.info('BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X', new_beamcon0, this.vtotal, this.htotal);
+ BUG.info(' HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X', this.hsstop, this.hbstrt, this.hbstop);
+ BUG.info(' VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X', this.vsstop, this.vbstrt, this.vbstop);
+ BUG.info(' HSSTRT=%04X VSSTRT=%04X HCENTER=%04X', this.hsstrt, this.vsstrt, this.hcenter);
+ }
+
+ this.varsync = function() {
+ //console.log('varsync()');
+ if (!CUSTOM_SIMPLE) {
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ return;
+ if (!(beamcon0 & 0x80))
+ return;
+ this.vpos_count = 0;
+ //this.dumpsync();
+ }
+ }
+
+ this.count_frame = function() {
+ if (++this.framecnt >= AMIGA.config.video.framerate)
+ this.framecnt = 0;
+ }
+
+ this.vsync_handle_redraw = function() { //(long_frame, lof_changed, bplcon0p, bplcon3p)
+ last_redraw_point++;
+ if (this.lof_changed || this.lof_store || interlace_seen <= 0 || doublescan < 0 || last_redraw_point >= 2) {
+ last_redraw_point = 0;
+
+ if (this.framecnt == 0)
+ this.finish_drawing_frame();
+/*#if 0
+ if (interlace_seen > 0)
+ interlace_seen = -1;
+ else if (interlace_seen == -1) {
+ interlace_seen = 0;
+ if (currprefs.scandoubler && currprefs.vresolution)
+ notice_screen_contents_lost ();
+ }
+#endif*/
+ this.count_frame();
+
+ if (this.framecnt == 0)
+ this.init_drawing_frame();
+ }
+ }
+
+ this.init_hardware_frame = function() {
+ first_bpl_vpos = -1;
+ next_lineno = 0;
+ prev_lineno = -1;
+ nextline_how = NLN_NORMAL;
+ diwstate = DIW_WAITING_START;
+ ddfstate = DIW_WAITING_START;
+ first_planes_vpos = 0;
+ last_planes_vpos = 0;
+ diwfirstword_total = max_diwlastword();
+ diwlastword_total = 0;
+ ddffirstword_total = max_diwlastword();
+ ddflastword_total = 0;
+ plflastline_total = 0;
+ plffirstline_total = this.current_maxvpos();
+ autoscale_bordercolors = 0;
+ for (var i = 0; i < MAX_SPRITES; i++)
+ spr[i].ptxhpos = MAXHPOS;
+ }
+
+ this.init_hardware_for_drawing_frame = function() {
+ if (prev_sprite_entries) {
+ var first_pixel = prev_sprite_entries[0].first_pixel;
+ var npixels = prev_sprite_entries[prev_next_sprite_entry].first_pixel - first_pixel;
+ for (var i = 0; i < npixels; i++) spixels[first_pixel + i] = 0; //memset (spixels + first_pixel, 0, npixels * sizeof *spixels);
+ for (var i = 0; i < npixels; i++) spixstate[first_pixel + i] = 0; //memset (spixstate.bytes + first_pixel, 0, npixels * sizeof *spixstate.bytes);
+ }
+ prev_next_sprite_entry = next_sprite_entry;
+
+ next_color_change = 0;
+ next_sprite_entry = 0;
+ next_color_entry = 0;
+ remembered_color_entry = -1;
+
+ prev_sprite_entries = sprite_entries[current_change_set];
+ curr_sprite_entries = sprite_entries[current_change_set ^ 1];
+ prev_color_changes = color_changes[current_change_set];
+ curr_color_changes = color_changes[current_change_set ^ 1];
+ prev_color_tables = color_tables[current_change_set];
+ curr_color_tables = color_tables[current_change_set ^ 1];
+
+ prev_drawinfo = line_drawinfo[current_change_set];
+ curr_drawinfo = line_drawinfo[current_change_set ^ 1];
+ current_change_set ^= 1;
+
+ color_src_match = color_dest_match = -1;
+
+ curr_sprite_entries[0].first_pixel = current_change_set * MAX_SPR_PIXELS;
+ next_sprite_forced = 1;
+ }
+
+ this.reset_decisions = function() {
+ if (this.nodraw())
+ return;
+
+ plfleft_real = -1;
+ toscr_nr_planes = toscr_nr_planes2 = 0;
+
+ bpl1dat_written = false;
+ bpl1dat_written_at_least_once = false;
+ bpl1dat_early = false;
+
+ thisline_decision.bplres = bplcon0_res;
+ thisline_decision.nr_planes = 0;
+ thisline_decision.plfleft = -1;
+ thisline_decision.plflinelen = -1;
+ thisline_decision.ham_seen = !!(bplcon0 & 0x800);
+ thisline_decision.ehb_seen = !!is_ehb(bplcon0, bplcon2);
+ thisline_decision.ham_at_start = !!(bplcon0 & 0x800);
+
+ thisline_decision.diwfirstword = -1;
+ thisline_decision.diwlastword = -1;
+ if (hdiwstate == DIW_WAITING_STOP) {
+ thisline_decision.diwfirstword = 0;
+ if (SMART_UPDATE) {
+ if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword)
+ thisline_changed = 1; //MARK_LINE_CHANGED;
+ }
+ }
+ thisline_decision.ctable = -1;
+ thisline_changed = 0;
+
+ curr_drawinfo[next_lineno].first_color_change = next_color_change;
+ curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry;
+
+ next_sprite_forced = 1;
+ last_sprite_point = 0;
+ fetch_state = FETCH_NOT_STARTED;
+ bplcon1_hpos = -1;
+ if (bpldmasetuphpos >= 0) {
+ this.BPLCON0_Denise(0, bplcon0, true);
+ this.setup_fmodes(0);
+ }
+ bpldmasetuphpos = -1;
+ bpldmasetupphase = 0;
+ ddfstrt_old_hpos = -1;
+
+ if (plf_state > PLF_ACTIVE || (plf_state == PLF_ACTIVE && !(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)))
+ plf_state = PLF_IDLE;
+
+ /*memset (todisplay, 0, sizeof todisplay);
+ memset (fetched, 0, sizeof fetched);
+ memset (fetched_aga0, 0, sizeof fetched_aga0);
+ memset (fetched_aga1, 0, sizeof fetched_aga1);
+ memset (outword, 0, sizeof outword);*/
+ for (var i = 0; i < MAX_PLANES; i++) {
+ for (var j = 0; j < 4; j++)
+ todisplay[i][j] = 0;
+
+ fetched[i] = 0;
+/*#ifdef AGA
+ if (AMIGA.config.chipset.mask & CSMASK_AGA) {
+ fetched_aga0[i] = 0;
+ fetched_aga1[i] = 0;
+ }
+#endif*/
+ outword[i] = 0;
+ }
+
+ last_decide_line_hpos = -1;
+ last_ddf_pix_hpos = -1;
+ last_sprite_hpos = -1;
+ last_fetch_hpos = -1;
+
+ thisline_decision.bplcon0 = bplcon0;
+ thisline_decision.bplcon2 = bplcon2;
+ thisline_decision.bplcon3 = bplcon3;
+/*#ifdef AGA
+ thisline_decision.bplcon4 = bplcon4;
+#endif*/
+ }
+
+ this.record_diw_line = function(plfstrt, first, last) {
+ if (last > max_diwstop)
+ max_diwstop = last;
+ if (first < min_diwstart) {
+ min_diwstart = first;
+ /*
+ if (plfstrt * 2 > min_diwstart)
+ min_diwstart = plfstrt * 2;
+ */
+ }
+ }
+
+ this.sprites_differ = function(dip, dip_old) {
+ var this_first = curr_sprite_entries[dip.first_sprite_entry];
+ var this_last = curr_sprite_entries[dip.last_sprite_entry];
+ var prev_first = prev_sprite_entries[dip_old.first_sprite_entry];
+
+ if (dip.nr_sprites != dip_old.nr_sprites)
+ return 1;
+
+ if (dip.nr_sprites == 0)
+ return 0;
+
+ /*for (var i = 0; i < dip.nr_sprites; i++) { //FIXME
+ if (this_first[i].pos != prev_first[i].pos
+ || this_first[i].max != prev_first[i].max
+ || this_first[i].has_attached != prev_first[i].has_attached)
+ return 1;
+ }*/
+ if (this_first.pos != prev_first.pos || this_first.max != prev_first.max || this_first.has_attached != prev_first.has_attached) //FIX
+ return 1;
+
+ var npixels = this_last.first_pixel + (this_last.max - this_last.pos) - this_first.first_pixel;
+
+ //if (memcmp (spixels + this_first.first_pixel, spixels + prev_first.first_pixel, npixels * sizeof (uae_u16)) != 0) return 1;
+ for (i = 0; i < npixels; i++) {
+ if (spixels[this_first.first_pixel + i] != spixels[prev_first.first_pixel + i])
+ return 1;
+ }
+ //if (memcmp (spixstate.bytes + this_first.first_pixel, spixstate.bytes + prev_first.first_pixel, npixels) != 0) return 1;
+ for (i = 0; i < npixels; i++) {
+ if (spixstate[this_first.first_pixel + i] != spixstate[prev_first.first_pixel + i])
+ return 1;
+ }
+ return 0;
+ }
+
+ this.color_changes_differ = function(dip, dip_old) {
+ if (dip.nr_color_changes != dip_old.nr_color_changes)
+ return 1;
+ if (dip.nr_color_changes == 0)
+ return 0;
+ //if (memcmp(curr_color_changes + dip.first_color_change, prev_color_changes + dip_old.first_color_change, dip.nr_color_changes * sizeof *curr_color_changes) != 0)
+ for (i = 0; i < dip.nr_color_changes; i++) {
+ if (curr_color_changes[dip.first_color_change + i].cmp(prev_color_changes[dip_old.first_color_change + i]) != 0)
+ return 1;
+ }
+ return 0;
+ }
+
+ this.finish_decisions = function() {
+ var hpos = this.maxhpos;
+
+ if (this.nodraw())
+ return;
+
+ this.decide_diw(hpos);
+ this.decide_line(hpos);
+ this.decide_fetch(hpos);
+
+ this.record_color_change2(hsyncstartpos, 0xffff, 0);
+ if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) {
+ if (fetch_state != FETCH_NOT_STARTED) {
+ BUG.info('finish_decisions() fetch_state=%d plfleft=%d,len=%d,vpos=%d,hpos=%d', fetch_state, thisline_decision.plfleft, thisline_decision.plflinelen, this.vpos, hpos);
+ Fatal(333, 'finish_decisions() fetch_state != FETCH_NOT_STARTED');
+ }
+ thisline_decision.plfright = thisline_decision.plfleft;
+ thisline_decision.plflinelen = 0;
+ thisline_decision.bplres = RES_LORES;
+ }
+ if (hdiwstate == DIW_WAITING_STOP) {
+ thisline_decision.diwlastword = max_diwlastword();
+ if (thisline_decision.diwfirstword < 0)
+ thisline_decision.diwfirstword = 0;
+ }
+ if (SMART_UPDATE) {
+ if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword)
+ thisline_changed = 1; //MARK_LINE_CHANGED;
+ if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword)
+ thisline_changed = 1; //MARK_LINE_CHANGED;
+ }
+ var dip = curr_drawinfo[next_lineno];
+ var dip_old = prev_drawinfo[next_lineno];
+ var dp = line_decisions[next_lineno];
+ var changed = thisline_changed;
+ if (thisline_decision.plfleft >= 0 && thisline_decision.nr_planes > 0)
+ this.record_diw_line(thisline_decision.plfleft, diwfirstword, diwlastword);
+
+ this.decide_sprites(hpos + 1);
+
+ dip.last_sprite_entry = next_sprite_entry;
+ dip.last_color_change = next_color_change;
+
+ if (thisline_decision.ctable < 0)
+ this.remember_ctable();
+
+ dip.nr_color_changes = next_color_change - dip.first_color_change;
+ dip.nr_sprites = next_sprite_entry - dip.first_sprite_entry;
+
+ if (thisline_decision.plfleft != line_decisions[next_lineno].plfleft)
+ changed = 1;
+ if (!changed && this.color_changes_differ(dip, dip_old))
+ changed = 1;
+ if (!changed && /* bitplane visible in this line OR border sprites enabled */
+ (thisline_decision.plfleft >= 0 || ((thisline_decision.bplcon0 & 1) && (thisline_decision.bplcon3 & 0x02) && !(thisline_decision.bplcon3 & 0x20)))
+ && this.sprites_differ(dip, dip_old))
+ changed = 1;
+
+ if (changed) {
+ thisline_changed = 1;
+ dp.set(thisline_decision); //*dp = thisline_decision;
+ } else
+ line_decisions[next_lineno].ctable = thisline_decision.ctable;
+
+ next_color_change += ((HBLANK_OFFSET + 1) >> 1);
+
+ diw_hcounter += this.maxhpos * 2;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) && this.vpos == this.get_equ_vblank_endline() - 1)
+ diw_hcounter++;
+ if ((AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) || this.vpos > this.get_equ_vblank_endline() || (AMIGA.config.chipset.agnus_dip && this.vpos == 0)) {
+ diw_hcounter = this.maxhpos * 2;
+ last_hdiw = 1; //2 - 1;
+ }
+ if (next_color_change >= MAX_REG_CHANGE - 30) {
+ BUG.info('color_change buffer overflow!');
+ next_color_change = 0;
+ dip.nr_color_changes = 0;
+ dip.first_color_change = 0;
+ dip.last_color_change = 0;
+ }
+ }
+
+ this.hsync_record_line_state = function(lineno, how, changed) {
+ if (this.framecnt != 0)
+ return;
+
+ //changed += ((frame_redraw_necessary ? 1 : 0) + ((lineno >= lightpen_y1 && lineno <= lightpen_y2) ? 1 : 0));
+ changed += (frame_redraw_necessary ? 1 : 0)
+
+ switch (how) {
+ case NLN_NORMAL:
+ linestate[lineno] = changed ? LINE_DECIDED : LINE_DONE;
+ break;
+ case NLN_DOUBLED:
+ linestate[lineno] = changed ? LINE_DECIDED_DOUBLE : LINE_DONE;
+ changed += (linestate[lineno + 1] != LINE_REMEMBERED_AS_PREVIOUS ? 1 : 0);
+ linestate[lineno + 1] = changed ? LINE_AS_PREVIOUS : LINE_DONE_AS_PREVIOUS;
+ break;
+ case NLN_NBLACK:
+ linestate[lineno] = changed ? LINE_DECIDED : LINE_DONE;
+ if (linestate[lineno + 1] != LINE_REMEMBERED_AS_BLACK)
+ linestate[lineno + 1] = LINE_BLACK;
+ break;
+ case NLN_LOWER:
+ if (linestate[lineno - 1] == LINE_UNDECIDED)
+ linestate[lineno - 1] = LINE_DECIDED; //LINE_BLACK;
+ linestate[lineno] = changed ? LINE_DECIDED : LINE_DONE;
+ break;
+ case NLN_UPPER:
+ linestate[lineno] = changed ? LINE_DECIDED : LINE_DONE;
+ if (linestate[lineno + 1] == LINE_UNDECIDED
+ || linestate[lineno + 1] == LINE_REMEMBERED_AS_PREVIOUS
+ || linestate[lineno + 1] == LINE_AS_PREVIOUS)
+ linestate[lineno + 1] = LINE_DECIDED; //LINE_BLACK;
+ break;
+ }
+ }
+
+ this.get_equ_vblank_endline = function() {
+ return equ_vblank_endline + (equ_vblank_toggle ? (this.lof_current ? 1 : 0) : 0);
+ }
+
+ this.decide_diw = function(hpos) {
+ var hdiw = hpos >= this.maxhpos ? this.maxhpos * 2 + 1 : hpos * 2 + 2;
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) && this.vpos <= this.get_equ_vblank_endline())
+ hdiw = diw_hcounter;
+
+ hdiw &= 511;
+ for (;;) {
+ var lhdiw = hdiw;
+ if (last_hdiw > lhdiw)
+ lhdiw = 512;
+
+ if (lhdiw >= diw_hstrt && last_hdiw < diw_hstrt && hdiwstate == DIW_WAITING_START) {
+ if (thisline_decision.diwfirstword < 0)
+ thisline_decision.diwfirstword = diwfirstword < 0 ? 0 : diwfirstword;
+ hdiwstate = DIW_WAITING_STOP;
+ }
+ if (lhdiw >= diw_hstop && last_hdiw < diw_hstop && hdiwstate == DIW_WAITING_STOP) {
+ if (thisline_decision.diwlastword < 0)
+ thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword;
+ hdiwstate = DIW_WAITING_START;
+ }
+ if (lhdiw != 512)
+ break;
+ last_hdiw = -1; //0 - 1;
+ }
+ last_hdiw = hdiw;
+ }
+
+ this.reset_bpl_vars = function(hpos) {
+ out_nbits = 0;
+ out_offs = 0;
+ toscr_nbits = 0;
+ thisline_decision.bplres = bplcon0_res;
+ }
+
+ this.start_bpl_dma = function(hpos, hstart) {
+ if (first_bpl_vpos < 0)
+ first_bpl_vpos = this.vpos;
+
+ if (this.doflickerfix() && interlace_seen > 0 && !scandoubled_line) {
+ for (var i = 0; i < 8; i++) {
+ prevbpl[this.lof_current][this.vpos][i] = bplptx[i];
+ if (!this.lof_current && (bplcon0 & 4))
+ bplpt[i] = prevbpl[1 - this.lof_current][this.vpos][i];
+ if (!(bplcon0 & 4) || interlace_seen < 0)
+ prevbpl[1 - this.lof_current][this.vpos][i] = prevbpl[this.lof_current][this.vpos][i] = 0;
+ }
+ }
+ plfstrt_sprite = plfstrt;
+ fetch_state = FETCH_STARTED;
+ fetch_cycle = 0;
+
+ ddfstate = DIW_WAITING_STOP;
+ this.compute_toscr_delay(last_fetch_hpos, bplcon1);
+
+ if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) {
+ this.update_fetch_x(hstart, fetchmode);
+ bpl1dat_written_at_least_once = false;
+ } else
+ this.reset_bpl_vars();
+/*#if 0
+ if (!this.nodraw ()) {
+ if (thisline_decision.plfleft >= 0) {
+ out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res);
+ out_offs = out_nbits >> 5;
+ out_nbits &= 31;
+ }
+ this.update_toscr_planes();
+ }
+#endif*/
+ last_fetch_hpos = hstart;
+ cycle_diagram_shift = hstart;
+ }
+
+ this.maybe_start_bpl_dma = function(hpos) {
+ //console.log('maybe_start_bpl_dma', hpos);
+ if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))
+ return;
+ if (fetch_state != FETCH_NOT_STARTED)
+ return;
+ if (diwstate != DIW_WAITING_STOP)
+ return;
+ if (hpos <= plfstrt)
+ return;
+ if (hpos > plfstop - fetchunit)
+ return;
+ if (ddfstate != DIW_WAITING_START)
+ plf_state = PLF_PASSED_STOP;
+
+ this.start_bpl_dma(hpos, hpos);
+ }
+
+ this.decide_line = function(hpos) {
+ if (this.vpos == plffirstline) {
+ diwstate = DIW_WAITING_STOP;
+ ddf_change = this.vpos;
+ }
+ if (this.vpos == plflastline) {
+ diwstate = DIW_WAITING_START;
+ ddf_change = this.vpos;
+ }
+ if (hpos <= last_decide_line_hpos)
+ return;
+
+ if (fetch_state == FETCH_NOT_STARTED && (diwstate == DIW_WAITING_STOP || (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS))) {
+ var ok = 0;
+ if (last_decide_line_hpos < plfstrt_start && hpos >= plfstrt_start) {
+ if (plf_state == PLF_IDLE)
+ plf_state = PLF_START;
+ }
+ if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) {
+ if (plf_state == PLF_START)
+ plf_state = PLF_ACTIVE;
+ if (plf_state == PLF_ACTIVE)
+ ok = 1;
+ if (hpos - 2 == ddfstrt_old_hpos)
+ ok = 0;
+ }
+ if (ok && diwstate == DIW_WAITING_STOP) {
+ if (AMIGA.dmaen(DMAF_BPLEN)) {
+ this.start_bpl_dma(hpos, plfstrt);
+ this.estimate_last_fetch_cycle(plfstrt);
+ }
+ last_decide_line_hpos = hpos;
+ if (!CUSTOM_SIMPLE)
+ this.do_sprites(hpos);
+
+ return;
+ }
+ }
+ if (!CUSTOM_SIMPLE) {
+ if (hpos > last_sprite_hpos && last_sprite_hpos < SPR0_HPOS + 4 * MAX_SPRITES)
+ this.do_sprites(hpos);
+ }
+ last_decide_line_hpos = hpos;
+ }
+
+ /*---------------------------------*/
+ /* to screen */
+
+ this.toscr_2_ecs = function(nbits) {
+ var delay1 = toscr_delay1;
+ var delay2 = toscr_delay2;
+ var mask = 0xffff >> (16 - nbits);
+ var i;
+
+ for (i = 0; i < toscr_nr_planes2; i += 2) {
+ outword[i] <<= nbits;
+ outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask;
+ todisplay[i][0] <<= nbits;
+ }
+ for (i = 1; i < toscr_nr_planes2; i += 2) {
+ outword[i] <<= nbits;
+ outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask;
+ todisplay[i][0] <<= nbits;
+ }
+ }
+
+ this.toscr_1 = function(nbits, fm) {
+ switch (fm) {
+ case 0:
+ this.toscr_2_ecs(nbits);
+ break;
+/*#ifdef AGA
+ case 1:
+ this.toscr_3_aga(nbits, 1);
+ break;
+ case 2:
+ this.toscr_3_aga(nbits, 2);
+ break;
+#endif*/
+ }
+ out_nbits += nbits;
+ if (out_nbits == 32) {
+ for (var i = 0; i < thisline_decision.nr_planes; i++) {
+ if (line_data[next_lineno][i][out_offs] != outword[i]) {
+ thisline_changed = 1;
+ line_data[next_lineno][i][out_offs] = outword[i];
+ }
+ outword[i] = 0;
+ }
+ out_offs++;
+ out_nbits = 0;
+ }
+ }
+
+ this.toscr = function(nbits, fm) {
+ if (nbits > 16) {
+ this.toscr(16, fm);
+ nbits -= 16;
+ }
+ var t = 32 - out_nbits;
+ if (t < nbits) {
+ this.toscr_1(t, fm);
+ nbits -= t;
+ }
+ this.toscr_1(nbits, fm);
+ }
+
+ this.flush_plane_data = function(fm) {
+ var i = 0;
+
+ if (out_nbits <= 16) {
+ i += 16;
+ this.toscr_1(16, fm);
+ }
+ if (out_nbits != 0) {
+ i += 32 - out_nbits;
+ this.toscr_1(32 - out_nbits, fm);
+ }
+ i += 32;
+
+ this.toscr_1(16, fm);
+ this.toscr_1(16, fm);
+
+ if (fm == 2) {
+ // flush AGA full 64-bit shift register
+ i += 32;
+ this.toscr_1(16, fm);
+ this.toscr_1(16, fm);
+ }
+ if (bpl1dat_early) {
+ this.toscr_1(16, fm);
+ this.toscr_1(16, fm);
+ }
+ return i >> (1 + toscr_res);
+ }
+
+ this.flush_display = function(fm) {
+ if (toscr_nbits > 0 && thisline_decision.plfleft >= 0)
+ this.toscr(toscr_nbits, fm);
+ toscr_nbits = 0;
+ }
+
+ this.beginning_of_plane_block = function(hpos, fm) {
+ var oleft = thisline_decision.plfleft;
+
+ this.flush_display(fm);
+
+ if (fm == 0)
+ for (var i = 0; i < MAX_PLANES; i++) {
+ todisplay[i][0] |= fetched[i];
+ }
+/*#ifdef AGA
+ else
+ for (i = 0; i < MAX_PLANES; i++) {
+ if (fm == 2)
+ todisplay[i][1] = fetched_aga1[i];
+ todisplay[i][0] = fetched_aga0[i];
+ }
+#endif*/
+
+ this.update_denise(hpos);
+ this.maybe_first_bpl1dat(hpos);
+
+ bplcon1t2 = bplcon1t;
+ bplcon1t = bplcon1;
+ if (bplcon1_hpos != hpos || oleft < 0)
+ bplcon1t2 = bplcon1t;
+
+ this.compute_toscr_delay(hpos, bplcon1t2);
+ }
+
+ this.update_bpldats = function(hpos) {
+ for (var i = 0; i < MAX_PLANES; i++) {
+/*#ifdef AGA
+ fetched_aga0[i] = bplxdat[i];
+ fetched_aga1[i] = 0;
+#endif*/
+ fetched[i] = bplxdat[i];
+ }
+ this.beginning_of_plane_block(hpos, fetchmode);
+ }
+
+ /*---------------------------------*/
+ /* fetch */
+
+ this.finish_final_fetch = function(pos, fm) {
+ if (thisline_decision.plfleft < 0 || plf_state == PLF_END)
+ return;
+
+ plf_state = PLF_END;
+ ddfstate = DIW_WAITING_START;
+ pos += this.flush_plane_data(fm);
+ thisline_decision.plfright = pos;
+ thisline_decision.plflinelen = out_offs;
+
+ if (this.vpos >= minfirstline && (thisframe_first_drawn_line < 0 || this.vpos < thisframe_first_drawn_line))
+ thisframe_first_drawn_line = this.vpos;
+ thisframe_last_drawn_line = this.vpos;
+
+ if (SMART_UPDATE) {
+ if (line_decisions[next_lineno].plflinelen != thisline_decision.plflinelen
+ || line_decisions[next_lineno].plfleft != thisline_decision.plfleft
+ || line_decisions[next_lineno].bplcon0 != thisline_decision.bplcon0
+ || line_decisions[next_lineno].bplcon2 != thisline_decision.bplcon2
+ || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3
+/*#ifdef AGA
+ || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4
+#endif*/
+ ) thisline_changed = 1;
+ } else
+ thisline_changed = 1;
+ }
+
+ this.long_fetch_ecs = function(plane, nwords, weird_number_of_bits, dma) {
+ //uae_u16 *real_pt = (uae_u16 *)pfield_xlateptr (bplpt[plane], nwords * 2);
+ var real_pt = bplpt[plane];
+ var delay = (plane & 1) ? toscr_delay2 : toscr_delay1;
+ var tmp_nbits = out_nbits;
+ var shiftbuffer = todisplay[plane][0];
+ var outval = outword[plane];
+ var fetchval = fetched[plane];
+ //var *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs);
+ var dataptr = out_offs;
+
+ if (dma) {
+ bplpt[plane] += nwords * 2;
+ bplptx[plane] += nwords * 2;
+ }
+
+ //if (real_pt == 0) /* @@@ Don't do this, fall back on chipmem_wget instead. */
+ //return;
+
+ while (nwords > 0) {
+ var bits_left = 32 - tmp_nbits;
+ var t;
+
+ shiftbuffer |= fetchval;
+
+ t = (shiftbuffer >>> delay) & 0xFFFF;
+
+ if (weird_number_of_bits && bits_left < 16) {
+ //outval <<= bits_left;
+ //outval |= t >>> (16 - bits_left);
+ outval = ((outval << bits_left) | (t >>> (16 - bits_left))) >>> 0;
+ //thisline_changed |= *dataptr ^ outval; *dataptr++ = outval;
+ thisline_changed |= line_data[next_lineno][plane][dataptr] ^ outval; line_data[next_lineno][plane][dataptr++] = outval;
+ outval = t;
+ tmp_nbits = 16 - bits_left;
+ //shiftbuffer <<= 16;
+ shiftbuffer = (shiftbuffer << 16) >>> 0;
+ } else {
+ outval = ((outval << 16) | t) >>> 0;
+ shiftbuffer = (shiftbuffer << 16) >>> 0;
+ tmp_nbits += 16;
+ if (tmp_nbits == 32) {
+ //thisline_changed |= *dataptr ^ outval; *dataptr++ = outval;
+ thisline_changed |= line_data[next_lineno][plane][dataptr] ^ outval; line_data[next_lineno][plane][dataptr++] = outval;
+ tmp_nbits = 0;
+ }
+ }
+ nwords--;
+ if (dma) {
+ //fetchval = do_get_mem_word (real_pt); real_pt++;
+ //fetchval = AMIGA.mem.load16_chip(real_pt); real_pt += 2;
+ fetchval = AMIGA.custom.last_value = AMIGA.mem.chip.data[real_pt >>> 1]; real_pt += 2;
+ }
+ }
+ fetched[plane] = fetchval;
+ todisplay[plane][0] = shiftbuffer;
+ outword[plane] = outval;
+ }
+
+ this.do_long_fetch = function(hpos, nwords, dma, fm) {
+ var i;
+
+ this.flush_display(fm);
+ switch (fm) {
+ case 0:
+ if (out_nbits & 15) {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_ecs(i, nwords, 1, dma);
+ } else {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_ecs(i, nwords, 0, dma);
+ }
+ break;
+/*#ifdef AGA
+ case 1:
+ if (out_nbits & 15) {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_aga(i, nwords, 1, 1, dma);
+ } else {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_aga(i, nwords, 0, 1, dma);
+ }
+ break;
+ case 2:
+ if (out_nbits & 15) {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_aga(i, nwords, 1, 2, dma);
+ } else {
+ for (i = 0; i < toscr_nr_planes; i++)
+ this.long_fetch_aga(i, nwords, 0, 2, dma);
+ }
+ break;
+#endif*/
+ }
+ out_nbits += nwords * 16;
+ out_offs += out_nbits >> 5;
+ out_nbits &= 31;
+
+ if (dma && toscr_nr_planes > 0)
+ fetch_state = FETCH_WAS_PLANE0;
+ }
+
+ this.add_modulos = function() {
+ var m1, m2;
+
+ if (fmode & 0x4000) {
+ if (((diwstrt >> 8) ^ this.vpos) & 1)
+ m1 = m2 = bpl2mod;
+ else
+ m1 = m2 = bpl1mod;
+ } else {
+ m1 = bpl1mod;
+ m2 = bpl2mod;
+ }
+
+ switch (bplcon0_planes_limit) {
+/*#ifdef AGA
+ case 8: bplpt[7] += m2; bplptx[7] += m2;
+ case 7: bplpt[6] += m1; bplptx[6] += m1;
+#endif*/
+ case 6: bplpt[5] += m2; bplptx[5] += m2;
+ case 5: bplpt[4] += m1; bplptx[4] += m1;
+ case 4: bplpt[3] += m2; bplptx[3] += m2;
+ case 3: bplpt[2] += m1; bplptx[2] += m1;
+ case 2: bplpt[1] += m2; bplptx[1] += m2;
+ case 1: bplpt[0] += m1; bplptx[0] += m1;
+ }
+ }
+
+ this.fetch = function(nr, fm, hpos) {
+ if (nr < bplcon0_planes_limit) {
+ var p = bplpt[nr];
+ bplpt[nr] += (2 << fm);
+ bplptx[nr] += (2 << fm);
+ if (nr == 0)
+ bpl1dat_written = true;
+
+ switch (fm) {
+ case 0:
+ //fetched[nr] = bplxdat[nr] = last_custom_value1 = chipmem_wget_indirect (p);
+ //fetched[nr] = bplxdat[nr] = AMIGA.mem.load16_chip(p);
+ fetched[nr] = bplxdat[nr] = AMIGA.custom.last_value = AMIGA.mem.chip.data[p >>> 1];
+ break;
+/*#ifdef AGA
+ case 1:
+ fetched_aga0[nr] = chipmem_lget_indirect (p);
+ last_custom_value1 = (uae_u16)fetched_aga0[nr];
+ break;
+ case 2:
+ fetched_aga1[nr] = chipmem_lget_indirect (p);
+ fetched_aga0[nr] = chipmem_lget_indirect (p + 4);
+ last_custom_value1 = (uae_u16)fetched_aga0[nr];
+ break;
+#endif*/
+ }
+ if (plf_state == PLF_PASSED_STOP2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetch_modulo_cycle) {
+ var mod;
+ if (fmode & 0x4000) {
+ if (((diwstrt >> 8) ^ this.vpos) & 1)
+ mod = bpl2mod;
+ else
+ mod = bpl1mod;
+ } else if (nr & 1)
+ mod = bpl2mod;
+ else
+ mod = bpl1mod;
+
+ bplpt[nr] += mod;
+ bplptx[nr] += mod;
+ }
+ } else {
+ if (nr < MAX_PLANES) //FIX for illegal memory access if not #ifdef AGA
+ fetched[nr] = bplxdat[nr];
+ }
+ }
+
+ this.one_fetch_cycle = function(pos, ddfstop_to_test, dma, fm) {
+ if (plf_state < PLF_PASSED_STOP && pos == ddfstop_to_test)
+ plf_state = PLF_PASSED_STOP;
+
+ if ((fetch_cycle & fetchunit_mask) == 0) {
+ if (plf_state == PLF_PASSED_STOP2) {
+ this.finish_final_fetch(pos, fm);
+ return 1;
+ }
+ if (plf_state == PLF_PASSED_STOP)
+ plf_state = PLF_PASSED_STOP2;
+ else if (plf_state == PLF_PASSED_STOP2)
+ plf_state = PLF_END;
+ }
+ this.maybe_check(pos);
+
+ if (dma) {
+ var cycle_start = fetch_cycle & fetchstart_mask;
+ switch (fm_maxplane) {
+ case 8:
+ switch (cycle_start) {
+ case 0: this.fetch(7, fm, pos); break;
+ case 1: this.fetch(3, fm, pos); break;
+ case 2: this.fetch(5, fm, pos); break;
+ case 3: this.fetch(1, fm, pos); break;
+ case 4: this.fetch(6, fm, pos); break;
+ case 5: this.fetch(2, fm, pos); break;
+ case 6: this.fetch(4, fm, pos); break;
+ case 7: this.fetch(0, fm, pos); break;
+ }
+ break;
+ case 4:
+ switch (cycle_start) {
+ case 0: this.fetch(3, fm, pos); break;
+ case 1: this.fetch(1, fm, pos); break;
+ case 2: this.fetch(2, fm, pos); break;
+ case 3: this.fetch(0, fm, pos); break;
+ }
+ break;
+ case 2:
+ switch (cycle_start) {
+ case 0: this.fetch(1, fm, pos); break;
+ case 1: this.fetch(0, fm, pos); break;
+ }
+ break;
+ }
+ }
+ if (bpl1dat_written) {
+ fetch_state = FETCH_WAS_PLANE0;
+ bpl1dat_written = false;
+ }
+
+ fetch_cycle++;
+ toscr_nbits += (2 << toscr_res);
+
+ if (toscr_nbits > 16) {
+ Fatal(333, sprintf('one_fetch_cycle() toscr_nbits > 16 (%d)', toscr_nbits));
+ toscr_nbits = 0;
+ }
+ if (toscr_nbits == 16)
+ this.flush_display(fm);
+
+ return 0;
+ }
+
+ this.update_fetch = function(until, fm) {
+ var dma = AMIGA.dmaen(DMAF_BPLEN);
+
+ if (this.nodraw() || plf_state == PLF_END)
+ return;
+
+ var ddfstop_to_test = HARD_DDF_STOP;
+ if (ddfstop >= last_fetch_hpos && plfstop < ddfstop_to_test)
+ ddfstop_to_test = plfstop;
+
+ this.update_toscr_planes();
+
+ var pos = last_fetch_hpos;
+ var pos2 = last_fetch_hpos;
+ cycle_diagram_shift = last_fetch_hpos - fetch_cycle;
+
+ for (; ; pos++) {
+ if (pos == until) {
+ if (until >= this.maxhpos) {
+ this.finish_final_fetch(pos, fm);
+ return;
+ }
+ this.flush_display(fm);
+ return;
+ }
+ if (fetch_state == FETCH_WAS_PLANE0)
+ break;
+
+ fetch_state = FETCH_STARTED;
+ if (this.one_fetch_cycle(pos, ddfstop_to_test, dma, fm))
+ return;
+ }
+
+ // Unrolled version of the for loop below.
+ if (1
+ && plf_state < PLF_PASSED_STOP && ddf_change != this.vpos && ddf_change + 1 != this.vpos
+ && dma
+ && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask)
+ && !badmode
+ //&& (out_nbits & 15) == 0
+ && toscr_nr_planes == thisline_decision.nr_planes)
+ {
+ var offs = (pos - fetch_cycle) & fetchunit_mask;
+ var ddf2 = ((ddfstop_to_test - offs + fetchunit - 1) & ~fetchunit_mask) + offs;
+ var ddf3 = ddf2 + fetchunit;
+ var stop = until < ddf2 ? until : until < ddf3 ? ddf2 : ddf3;
+ var count = stop - pos;
+
+ if (count >= fetchstart) {
+ count &= ~fetchstart_mask;
+
+ if (thisline_decision.plfleft < 0) {
+ this.compute_delay_offset();
+ this.compute_toscr_delay_1(bplcon1);
+ }
+
+ this.do_long_fetch(pos, count >> (3 - toscr_res), dma, fm);
+
+ this.maybe_first_bpl1dat(pos);
+
+ if (pos <= ddfstop_to_test && pos + count > ddfstop_to_test)
+ plf_state = PLF_PASSED_STOP;
+ if (pos <= ddfstop_to_test && pos + count > ddf2)
+ plf_state = PLF_PASSED_STOP2;
+ if (pos <= ddf2 && pos + count >= ddf2 + fm_maxplane)
+ this.add_modulos();
+ pos += count;
+ fetch_cycle += count;
+ }
+ }
+
+ for (; pos < until; pos++) {
+ if (fetch_state == FETCH_WAS_PLANE0) {
+ this.beginning_of_plane_block(pos, fm);
+ this.estimate_last_fetch_cycle(pos);
+ }
+ fetch_state = FETCH_STARTED;
+ if (this.one_fetch_cycle(pos, ddfstop_to_test, dma, fm))
+ return;
+ }
+ if (until >= this.maxhpos) {
+ this.finish_final_fetch(pos, fm);
+ return;
+ }
+ this.flush_display(fm);
+ }
+
+ this.update_fetch_x = function(until, fm) {
+ if (this.nodraw())
+ return;
+
+ var pos = last_fetch_hpos;
+ this.update_toscr_planes();
+
+ for (; pos < until; pos++) {
+ toscr_nbits += (2 << toscr_res);
+ if (toscr_nbits > 16) {
+ Fatal(333, sprintf('update_fetch_x() xtoscr_nbits > 16 (%d)', toscr_nbits));
+ toscr_nbits = 0;
+ }
+ if (toscr_nbits == 16)
+ this.flush_display(fm);
+ }
+ if (until >= this.maxhpos) {
+ this.finish_final_fetch(pos, fm);
+ return;
+ }
+ this.flush_display(fm);
+ }
+
+ this.decide_fetch = function(hpos) {
+ if (hpos > last_fetch_hpos) {
+ if (fetch_state != FETCH_NOT_STARTED) {
+ this.update_fetch(hpos, fetchmode);
+ //cycle_diagram_shift = hpos - fetch_cycle;
+ } else if (bpl1dat_written_at_least_once) {
+ this.update_fetch_x(hpos, fetchmode);
+ bpl1dat_written = false;
+ }
+ this.maybe_check(hpos);
+ last_fetch_hpos = hpos;
+ }
+ }
+
+ this.decide_fetch_ce = function(hpos) {
+ if ((ddf_change == this.vpos || ddf_change + 1 == this.vpos) && this.vpos < this.current_maxvpos())
+ this.decide_fetch(hpos);
+ }
+
+ this.estimate_last_fetch_cycle = function(hpos) {
+ var fetchunit = fetchunits[fetchmode * 4 + bplcon0_res];
+
+ if (plf_state < PLF_PASSED_STOP) {
+ var stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop;
+ var fetch_cycle_at_stop = fetch_cycle + (stop - hpos);
+ var starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1);
+
+ estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
+ } else {
+ var starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1);
+ if (plf_state == PLF_PASSED_STOP2)
+ starting_last_block_at -= fetchunit;
+
+ estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit;
+ }
+ }
+
+ /*---------------------------------*/
+
+ this.vsync_handler_post = function() {
+ if (bplcon0 & 4)
+ this.lof_store = this.lof_store ? 0 : 1;
+ this.lof_current = this.lof_store;
+ if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) {
+ interlace_changed = this.notice_interlace_seen(true);
+ if (interlace_changed)
+ this.notice_screen_contents_lost();
+ } else if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED) {
+ interlace_changed = this.notice_interlace_seen(false);
+ if (interlace_changed)
+ this.notice_screen_contents_lost();
+ }
+ if (this.lof_changing) {
+ // still same? Trigger change now.
+ if ((!this.lof_store && this.lof_changing < 0) || (this.lof_store && this.lof_changing > 0)) {
+ this.lof_changed = 1;
+ }
+ this.lof_changing = 0;
+ }
+
+/*#ifdef PICASSO96
+ if (p96refresh_active) {
+ vpos_count = p96refresh_active;
+ vtotal = vpos_count;
+ }
+#endif*/
+
+ if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80)) || (this.vpos_count > 0 && Math.abs(this.vpos_count - this.vpos_count_diff) > 1) || this.lof_changed)
+ this.init_hz(false);
+ else if (interlace_changed)
+ this.compute_framesync();
+
+ this.lof_changed = 0;
+
+ AMIGA.copper.COPJMP(1, 1);
+
+ this.init_hardware_frame();
+ }
+
+ this.hsync_scandoubler = function() {
+ console.log('hsync_scandoubler');
+ var bpltmp = [0,0,0,0,0,0,0,0], bpltmpx = [0,0,0,0,0,0,0,0];
+
+ next_lineno++;
+ scandoubled_line = 1;
+
+ for (var i = 0; i < 8; i++) {
+ bpltmp[i] = bplpt[i];
+ bpltmpx[i] = bplptx[i];
+ if (prevbpl[this.lof_store][this.vpos][i] && prevbpl[1 - this.lof_store][this.vpos][i]) {
+ var diff = prevbpl[this.lof_store][this.vpos][i] - prevbpl[1 - this.lof_store][this.vpos][i];
+ if (this.lof_store) {
+ if (bplcon0 & 4)
+ bplpt[i] = prevbpl[this.lof_store][this.vpos][i] - diff;
+ } else {
+ if (bplcon0 & 4)
+ bplpt[i] = prevbpl[this.lof_store][this.vpos][i];
+ else
+ bplpt[i] = bplpt[i] - diff;
+
+ }
+ }
+ }
+
+ this.reset_decisions();
+ plf_state = PLF_IDLE;
+
+ // copy color changes
+ var dip1 = curr_drawinfo[next_lineno - 1];
+ for (var idx1 = dip1.first_color_change; idx1 < dip1.last_color_change; idx1++) {
+ var cs2 = curr_color_changes[idx1];
+ var regno = cs2.regno;
+ var hpos = cs2.linepos;
+ if (regno < 0x1000 && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) {
+ var pdip = curr_drawinfo[next_lineno - 1];
+ var idx = pdip.last_color_change;
+ pdip.last_color_change++;
+ pdip.nr_color_changes++;
+ curr_color_changes[idx].linepos = hpos + this.maxhpos + 1;
+ curr_color_changes[idx].regno = regno;
+ curr_color_changes[idx].value = cs2.value;
+ curr_color_changes[idx + 1].regno = -1;
+ } else {
+ var cs1 = curr_color_changes[next_color_change];
+ cs1.set(cs2); //memcpy (cs1, cs2, sizeof (struct color_change));
+ next_color_change++;
+ }
+ }
+
+ curr_color_changes[next_color_change].regno = -1;
+
+ this.finish_decisions();
+ this.hsync_record_line_state(next_lineno, NLN_NORMAL, thisline_changed);
+ this.hardware_line_completed(next_lineno);
+ scandoubled_line = 0;
+
+ for (var i = 0; i < 8; i++) {
+ bplpt[i] = bpltmp[i];
+ bplptx[i] = bpltmpx[i];
+ }
+ }
+
+ this.hsync_handler_pre = function() {
+ this.finish_decisions();
+ if (thisline_decision.plfleft >= 0) {
+ if (AMIGA.config.chipset.collision_level > 1)
+ this.do_sprite_collisions();
+ if (AMIGA.config.chipset.collision_level > 2)
+ this.do_playfield_collisions();
+ }
+ this.hsync_record_line_state(next_lineno, nextline_how, thisline_changed);
+ if (this.vpos == sprite_vblank_endline) {
+ //lightpen_triggered = 0;
+ sprite_0 = 0;
+ }
+ /*if (lightpen_cx > 0 && (bplcon0 & 8) && !lightpen_triggered && lightpen_cy == this.vpos) {
+ vpos_lpen = this.vpos;
+ hpos_lpen = lightpen_cx;
+ lightpen_triggered = 1;
+ }*/
+ this.hardware_line_completed(next_lineno);
+ if (this.doflickerfix() && interlace_seen > 0)
+ this.hsync_scandoubler();
+ }
+
+ this.hsync_handler_pre_next_vpos = function(onvsync) {
+ if (this.is_linetoggle())
+ this.lol ^= 1;
+ else
+ this.lol = 0;
+
+ this.vpos++;
+ this.vpos_count++;
+ if (this.vpos >= this.maxvpos_total)
+ this.vpos = 0;
+ if (onvsync) {
+ this.vpos = 0;
+ //vsync_counter++;
+ }
+ this.maxhpos = this.maxhpos_short + this.lol;
+ }
+
+ this.hsync_handler_post = function() {
+ if (this.vpos == equ_vblank_endline + 1) {
+ //if (this.lof_current != this.lof_store) {}
+ if (this.lof_store != this.lof_previous) {
+ if (lof_togglecnt_lace < LOF_TOGGLES_NEEDED)
+ lof_togglecnt_lace++;
+ if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED)
+ lof_togglecnt_nlace = 0;
+ } else {
+ if (lof_togglecnt_nlace < LOF_TOGGLES_NEEDED)
+ lof_togglecnt_nlace++;
+ if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED)
+ lof_togglecnt_lace = 0;
+ }
+ this.lof_previous = this.lof_store;
+ }
+ }
+
+ this.hsync_handler_post_nextline_how = function() {
+ var lineno = this.vpos;
+ if (lineno >= MAXVPOS)
+ lineno %= MAXVPOS;
+ nextline_how = NLN_NORMAL;
+ if (this.doflickerfix() && interlace_seen > 0)
+ lineno *= 2;
+ else if (AMIGA.config.video.vresolution && (doublescan <= 0 || interlace_seen > 0)) {
+ lineno *= 2;
+ nextline_how = AMIGA.config.video.vresolution > VRES_NONDOUBLE && AMIGA.config.video.scanlines == false ? NLN_DOUBLED : NLN_NBLACK;
+ if (interlace_seen) {
+ if (!this.lof_current) {
+ lineno++;
+ nextline_how = NLN_LOWER;
+ } else {
+ nextline_how = NLN_UPPER;
+ }
+ }
+ }
+ prev_lineno = next_lineno;
+ next_lineno = lineno;
+ this.reset_decisions();
+
+ plfstrt_sprite = plfstrt;
+ }
+
+ this.hsync_handler_post_diw_change = function() {
+ if (GET_PLANES(bplcon0) > 0 && AMIGA.dmaen(DMAF_BPLEN)) {
+ if (this.vpos > last_planes_vpos)
+ last_planes_vpos = this.vpos;
+ if (this.vpos >= minfirstline && first_planes_vpos == 0)
+ first_planes_vpos = this.vpos > minfirstline ? this.vpos - 1 : this.vpos;
+ else if (this.vpos >= this.current_maxvpos() - 1)
+ last_planes_vpos = this.current_maxvpos();
+ }
+ if (diw_change == 0) {
+ if (this.vpos >= first_planes_vpos && this.vpos <= last_planes_vpos) {
+ if (diwlastword > diwlastword_total) {
+ diwlastword_total = diwlastword;
+ if (diwlastword_total > coord_diw_to_window_x(hsyncstartpos * 2))
+ diwlastword_total = coord_diw_to_window_x(hsyncstartpos * 2);
+ }
+ if (diwfirstword < diwfirstword_total) {
+ diwfirstword_total = diwfirstword;
+ if (diwfirstword_total < coord_diw_to_window_x(hsyncendpos * 2))
+ diwfirstword_total = coord_diw_to_window_x(hsyncendpos * 2);
+ firstword_bplcon1 = bplcon1;
+ }
+ }
+ if (diwstate == DIW_WAITING_STOP) {
+ var f = 8 << fetchmode;
+ if (plfstrt + f < ddffirstword_total + f)
+ ddffirstword_total = plfstrt + f;
+ if (plfstop + 2 * f > ddflastword_total + 2 * f)
+ ddflastword_total = plfstop + 2 * f;
+ }
+ if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && this.vpos > minfirstline)) && plffirstline < (this.vpos >> 1)) {
+ firstword_bplcon1 = bplcon1;
+ if (plffirstline < minfirstline)
+ plffirstline_total = minfirstline;
+ else
+ plffirstline_total = plffirstline;
+ }
+ if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > (this.maxvpos >> 1))
+ plflastline_total = plflastline;
+ }
+ if (diw_change > 0)
+ diw_change--;
+ }
+
+ /*---------------------------------*/
+
+ this.getDiwstate = function() {
+ return diwstate;
+ }
+
+ this.getData = function() {
+ return [
+ thisline_decision.plfleft,
+ thisline_decision.plfright - (16 << fetchmode),
+ cycle_diagram_total_cycles[fetchmode][GET_RES_AGNUS(bplcon0)][GET_PLANES_LIMIT(bplcon0)],
+ cycle_diagram_free_cycles[fetchmode][GET_RES_AGNUS(bplcon0)][GET_PLANES_LIMIT(bplcon0)]
+ ];
+ }
+
+ /*---------------------------------*/
+
+ this.setup = function() {
+ if (cycle_diagram_table === null)
+ create_cycle_diagram_table();
+
+ if (AMIGA.video.available == 1)
+ alloc_colors64k(4,4,4, 8,4,0, 0,0,0, 0);
+ else
+ alloc_colors64k(5,6,5, 11,5,0, 0,0,0, 0);
+
+ notice_new_xcolors();
+
+ this.setup_drawing();
+ this.setup_sprites();
+ }
+
+ this.cleanup = function() {
+ this.cleanup_sprites();
+ this.cleanup_drawing();
+ }
+
+ this.reset = function() {
+ /*lightpen_active = -1;
+ lightpen_triggered = 0;
+ lightpen_cx = lightpen_cy = -1;*/
+
+ update_mirrors();
+
+ if (!aga_mode) {
+ for (i = 0; i < 32; i++) {
+ current_colors.color_regs_ecs[i] = 0;
+ current_colors.acolors[i] = getxcolor(0);
+ }
+/*#ifdef AGA
+ } else {
+ for (i = 0; i < 256; i++) {
+ current_colors.color_regs_aga[i] = 0;
+ current_colors.acolors[i] = getxcolor(0);
+ }
+#endif*/
+ }
+
+ this.clxdat = 0;
+
+ /* Clear the armed flags of all sprites. */
+ for (var i = 0; i < MAX_SPRITES; i++) spr[i].clr();
+ nr_armed = 0;
+
+ bplcon0 = 0;
+ bplcon3 = 0x0C00;
+ bplcon4 = 0x0011; // Get AGA chipset into ECS compatibility mode
+
+ diwhigh = 0;
+ diwhigh_written = false;
+ hdiwstate = DIW_WAITING_START; // this does not reset at vblank
+
+ this.FMODE(0, 0);
+ this.CLXCON(0);
+ this.CLXCON2(0);
+ this.setup_fmodes(0);
+ sprite_width = GET_SPRITEWIDTH(fmode);
+ beamcon0 = new_beamcon0 = AMIGA.config.video.ntsc ? 0x00 : 0x20;
+ this.lof_store = this.lof_current = 1;
+
+ this.vpos = 0;
+ this.vpos_count = this.vpos_count_diff = 0;
+
+ //timehack_alive = 0;
+
+ curr_sprite_entries = null;
+ prev_sprite_entries = null;
+ sprite_entries[0][0].first_pixel = 0;
+ sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS;
+ sprite_entries[0][1].first_pixel = 0;
+ sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS;
+ for (var i = 0; i < spixels.length; i++) spixels[i] = 0; //memset (spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels);
+ for (var i = 0; i < spixstate.length; i++) spixstate[i] = 0; //memset (&spixstate, 0, sizeof spixstate);
+
+ diwstate = DIW_WAITING_START;
+
+ this.init_hz(true);
+ //vpos_lpen = -1;
+ this.lof_changing = 0;
+ this.lof_previous = this.lof_store;
+ lof_togglecnt_nlace = lof_togglecnt_lace = 0;
+ nlace_cnt = NLACE_CNT_NEEDED;
+
+ this.reset_sprites();
+ this.init_hardware_frame();
+ this.reset_drawing();
+ this.reset_decisions();
+
+ sprres = expand_sprres(bplcon0, bplcon3);
+ sprite_width = GET_SPRITEWIDTH(fmode);
+ this.setup_fmodes(0);
+
+/*#ifdef PICASSO96
+ picasso_reset();
+#endif*/
+ }
}
diff --git a/sae/utils.js b/sae/utils.js
index 3fba66f..d3db3f3 100644
--- a/sae/utils.js
+++ b/sae/utils.js
@@ -337,6 +337,12 @@ function dump(obj) {
/*-----------------------------------------------------------------------*/
+function VSync(err, msg) {
+ this.error = err;
+ this.message = msg;
+}
+VSync.prototype = new Error;
+
function FatalError(err, msg) {
this.error = err;
this.message = msg;
@@ -417,3 +423,59 @@ function Debug() {
}
}
}
+
+/*-----------------------------------------------------------------------*/
+
+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.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, 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;
+
+ //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);
+ }
+ }
+ }
+
+ this.print = function() {
+ BUG.info('$%08x%08x', this.hi, this.lo);
+ }
+}
+
+
diff --git a/sae/video.js b/sae/video.js
index 158b961..00124bc 100644
--- a/sae/video.js
+++ b/sae/video.js
@@ -34,130 +34,168 @@ function Vide0() {
antialias: false
};
+ this.available = 0;
+
var width = 0;
var height = 0;
var size = 0;
+ var scale = false;
var pixels = null;
var div = null;
var canvas = null;
- var gl = null;
+ var ctx = null;
+ var imagedata = null;
var video = null;
var open = false;
/*---------------------------------*/
- function getShader(gl, id) {
+ //this.init = function()
+ {
+ var test = document.createElement('canvas');
+ if (test && test.getContext) {
+ var test2 = test.getContext('2d');
+ if (test2) {
+ this.available |= SAEI_Video_Canvas2D;
+ test2 = null;
+ }
+ test = null;
+ }
+ test = document.createElement('canvas');
+ if (test && test.getContext) {
+ test2 = test.getContext('experimental-webgl', glParams) || test.getContext('webgl', glParams);
+ if (test2) {
+ this.available |= SAEI_Video_WebGL;
+ test2 = null;
+ }
+ test = null;
+ }
+ //console.log(this.available);
+ }
+
+ /*---------------------------------*/
+
+ function getShader(ctx, id) {
var shader, source;
if (id == 'vertex') {
- shader = gl.createShader(gl.VERTEX_SHADER);
+ shader = ctx.createShader(ctx.VERTEX_SHADER);
source = vertexShader;
} else if (id == 'fragment') {
- shader = gl.createShader(gl.FRAGMENT_SHADER);
+ shader = ctx.createShader(ctx.FRAGMENT_SHADER);
source = fragmentShader;
}
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
+ ctx.shaderSource(shader, source);
+ ctx.compileShader(shader);
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
- Fatal(SAEE_Video_Shader_Error, gl.getShaderInfoLog(shader));
+ if (!ctx.getShaderParameter(shader, ctx.COMPILE_STATUS))
+ Fatal(SAEE_Video_Shader_Error, ctx.getShaderInfoLog(shader));
return shader;
}
function initGL() {
- var vertexShader = getShader(gl, 'vertex');
- var fragmentShader = getShader(gl, 'fragment');
- var program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragmentShader);
- gl.linkProgram(program);
- if (!gl.getProgramParameter(program, gl.LINK_STATUS))
+ var vertexShader = getShader(ctx, 'vertex');
+ var fragmentShader = getShader(ctx, 'fragment');
+ var program = ctx.createProgram();
+ ctx.attachShader(program, vertexShader);
+ ctx.attachShader(program, fragmentShader);
+ ctx.linkProgram(program);
+ if (!ctx.getProgramParameter(program, ctx.LINK_STATUS))
Fatal(SAEE_Video_Shader_Error, 'Can\'t initialise the shaders for WebGL.');
- gl.useProgram(program);
+ ctx.useProgram(program);
- var positionLocation = gl.getAttribLocation(program, "a_position");
- var texCoordLocation = gl.getAttribLocation(program, "a_texCoord");
+ var positionLocation = ctx.getAttribLocation(program, "a_position");
+ var texCoordLocation = ctx.getAttribLocation(program, "a_texCoord");
- var texCoordBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ var texCoordBuffer = ctx.createBuffer();
+ ctx.bindBuffer(ctx.ARRAY_BUFFER, texCoordBuffer);
+ ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
- 1.0, 1.0]), gl.STATIC_DRAW);
- gl.enableVertexAttribArray(texCoordLocation);
- gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);
+ 1.0, 1.0]), ctx.STATIC_DRAW);
+ ctx.enableVertexAttribArray(texCoordLocation);
+ ctx.vertexAttribPointer(texCoordLocation, 2, ctx.FLOAT, false, 0, 0);
- var texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ var texture = ctx.createTexture();
+ ctx.bindTexture(ctx.TEXTURE_2D, texture);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
- var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
- gl.uniform2f(resolutionLocation, width, height);
+ var resolutionLocation = ctx.getUniformLocation(program, "u_resolution");
+ ctx.uniform2f(resolutionLocation, width, height);
- var buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.enableVertexAttribArray(positionLocation);
- gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+ var buffer = ctx.createBuffer();
+ ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer);
+ ctx.enableVertexAttribArray(positionLocation);
+ ctx.vertexAttribPointer(positionLocation, 2, ctx.FLOAT, false, 0, 0);
- gl.viewport(0, 0, width, height);
- gl.clearColor(0, 0, 0, 1);
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.colorMask(true, true, true, false);
+ ctx.viewport(0, 0, width, height);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ ctx.colorMask(true, true, true, false);
}
this.setup = function() {
if (!AMIGA.config.video.enabled) return;
if (open) this.cleanup();
- width = AMIGA.config.video.scale ? VIDEO_WIDTH << 1 : VIDEO_WIDTH;
- height = AMIGA.config.video.scale ? VIDEO_HEIGHT << 1 : VIDEO_WIDTH;
- size = width * height;
- //BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
-
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+')');
- if ((canvas = document.createElement('canvas'))) {
- canvas.width = width;
+ 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;
- } else {
- if (confirm('Can\'t create a CANVAS-element. Continue without video-playback?'))
- AMIGA.config.video.enabled = false;
- else
- Fatal(SAEE_Video_Canvas_Not_Supported, 'Can\'t create a CANVAS-element. Please update the browser.');
- }
- if (AMIGA.config.video.enabled) {
- if ((gl = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams)))
+ 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
- if (confirm('Can\'t initialise WebGL. Continue without video-playback?'))
- AMIGA.config.video.enabled = false;
- else
- Fatal(SAEE_Video_WebGL_Not_Avail, 'Can\'t initialise WebGL. Is WebGL enabled in the browser-config?');
+ AMIGA.config.video.enabled = false;
}
- if (AMIGA.config.video.enabled) {
- pixels = new Uint16Array(size);
- for (var i = 0; i < size; i++) pixels[i] = 0;
- }
- 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); }
- }
- canvas.oncontextmenu = function() { return false; }
-
+
video = document.createElement('div');
video.style.width = width + 'px';
video.style.height = height + 'px';
@@ -168,15 +206,18 @@ function Vide0() {
video.style.mozUserSelect = 'none';
video.style.msUserSelect = 'none';
video.style.userSelect = 'none';
- video.appendChild(canvas);
+ if (AMIGA.config.video.enabled)
+ video.appendChild(canvas);
+
div.appendChild(video);
- open = true;
+ open = true;
}
this.cleanup = function() {
if (open) {
div.removeChild(video);
canvas = null;
+ imagedata = null;
pixels = null;
video = null;
open = false;
@@ -189,57 +230,59 @@ function Vide0() {
canvas.style.cursor = hide ? 'none' : 'auto';
}
- this.clear_pixels = function () {
+ /*this.clear_pixels = function () {
for (var i = 0; i < size; i++)
pixels[i] = 0;
- }
+ }*/
- this.drawpixel = function (x, y, rgb) {
+ /*---------------------------------*/
+ /* Canvas 2D */
+
+ function drawpixel_2d(x, y, rgb) {
pixels[y * width + x] = rgb;
}
- this.draw2pixel = function (x, y, rgb) {
- var ptr = y * width + x;
- pixels[ptr] = pixels[ptr + 1] = rgb;
- }
-
- this.drawline = function (y, rgb) {
- var ptr = y * width;
-
- for (var i = 0; i < width; i++)
- pixels[ptr++] = rgb;
- }
- this.drawline_from_to = function (x1, x2, y, rgb) {
- var ptr = y * width + x1;
-
- for (var i = 0; i < x2 - x1; i++)
- pixels[ptr++] = rgb;
- }
-
- this.draw = function (rgb, scalex, scaley, colorOnly) {
- var r = 0.0625 * (((rgb >> 11) & 31) >> 1);
- var g = 0.0625 * (((rgb >> 5) & 63) >> 2);
- var b = 0.0625 * ((rgb & 31) >> 1);
-
- gl.viewport(0, 0, width, height);
- gl.clearColor(r, g, b, 1);
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- if (!colorOnly) {
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, pixels);
-
- var s = AMIGA.config.video.scale ? 1 : 0;
- var x1 = 0;
- //var x2 = 0 + (width << (scalex ? (s+1) : s));
- var x2 = 0 + (width << s);
- var y1 = 0;
- var y2 = 0 + (height << (scaley ? (s+1) : s));
- //var y2 = 0 + (height << s);
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
- x1, y1, x2, y1, x1, y2,
- x1, y2, x2, y1, x2, y2]), gl.STATIC_DRAW);
-
- gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ function drawline_2d(y, data, offs) {
+ var yoffs = (y * width) << 2;
+ for (var x = 0, d = 0; x < width << 2; x += 4, d++) {
+ pixels[yoffs + x ] = ((data[offs + d] >> 8) & 0xf) << 4;
+ pixels[yoffs + x + 1] = ((data[offs + d] >> 4) & 0xf) << 4;
+ pixels[yoffs + x + 2] = ((data[offs + d] >> 0) & 0xf) << 4;
+ pixels[yoffs + x + 3] = 255;
}
}
+
+ function render_2d() {
+ ctx.putImageData(imagedata, 0, 0);
+ }
+
+ function show_2d() {}
+
+ /*---------------------------------*/
+ /* WebGL */
+
+ function drawpixel_gl(x, y, rgb) {
+ pixels[y * width + x] = rgb;
+ }
+
+ function drawline_gl(y, data, offs) {
+ var yoffs = y * width;
+ for (var x = 0; x < width; x++)
+ pixels[yoffs + x] = data[offs + x] & 0xffff;
+ }
+
+ function render_gl() {
+ ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGB, width, height, 0, ctx.RGB, ctx.UNSIGNED_SHORT_5_6_5, pixels);
+
+ var x1 = 0;
+ var x2 = width << (scale ? 1 : 0);
+ var y1 = 0;
+ var y2 = height << (scale ? 1 : 0);
+
+ ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]), ctx.STATIC_DRAW);
+ }
+
+ function show_gl() {
+ ctx.drawArrays(ctx.TRIANGLES, 0, 6);
+ }
}
|