From dd3bb23b86c99eb35728454a1a1513511a96d562 Mon Sep 17 00:00:00 2001 From: Rupert Hausberger Date: Sun, 7 Jul 2013 16:53:47 +0200 Subject: [PATCH] update 0.8.1 --- ga.js | 12 + index.css | 9 +- index.htm | 40 +- index.js | 210 +- readme.htm | 26 +- sae/amiga.js | 441 ++- sae/audio.js | 1175 ++++---- sae/blitter.js | 404 +-- sae/cia.js | 475 +-- sae/config.js | 25 +- sae/constants.js | 49 +- sae/copper.js | 873 +++--- sae/cpu.js | 298 +- sae/custom.js | 943 ++++-- sae/disk.js | 2747 +++++++++-------- sae/events.js | 938 +++--- sae/expansion.js | 114 +- sae/input.js | 699 +++-- sae/memory.js | 884 +++--- sae/playfield.js | 7483 +++++++++++++++++++++++----------------------- sae/rtc.js | 330 +- sae/serial.js | 110 +- sae/utils.js | 351 ++- sae/video.js | 177 +- 24 files changed, 9764 insertions(+), 9049 deletions(-) create mode 100644 ga.js diff --git a/ga.js b/ga.js new file mode 100644 index 0000000..986e4d1 --- /dev/null +++ b/ga.js @@ -0,0 +1,12 @@ +/* google analytics */ + +var _gaq = _gaq || []; +_gaq.push(['_setAccount', 'UA-37232052-1']); +_gaq.push(['_setDomainName', 'scriptedamigaemulator.net']); +_gaq.push(['_trackPageview']); + +(function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); +})(); \ No newline at end of file diff --git a/index.css b/index.css index 282d2d9..8f385aa 100644 --- a/index.css +++ b/index.css @@ -41,7 +41,7 @@ body { left:0; margin:0; padding:0; - font-family:verdana; + font-family:verdana,serif; font-size:small; background-color:#fff; } @@ -81,7 +81,7 @@ body { background-color:#fcfcfc; } .config_simple_hof { - width:480px; + width:380px; margin:auto; padding:10px; border:1px solid #ccc; @@ -114,7 +114,6 @@ body { width:auto; } #config select { - border:0; border:1px solid #ccc; } #config .button { @@ -195,7 +194,7 @@ body { vertical-align:top; } -div.float_box { +/*div.float_box { overflow: hidden; width: 100%; } @@ -204,4 +203,4 @@ div.float_item { } div.float_clear { clear: both; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/index.htm b/index.htm index c6c3a33..20ecadf 100644 --- a/index.htm +++ b/index.htm @@ -47,22 +47,11 @@

Welcome!

This site is the homepage of the project SAE, an experimental Amiga emulator in pure JavaScript and HTML5.
- SAE is based on WinUAE and does use the AROS-kickstart replacement. - For more details, please see the description.
+ SAE is based on WinUAE and does use the AROS-kickstart replacement. + For more details, please see the description.

Below you find a collection of pre-installed games and demos to play and test. Press the 'Config'-button to use your own roms or file-images, with advanced options.
-
- - Update 22.01.2013: The new game-database is now online. It's quite empty yet and will be filled with freeware and public-domain titles.
-
-
- - Your game or demo online
- If you want to have your game or demo on this site, please contact me. - It would be published under a free license, with a link to your homepage and would be free to play for everyone. - This is a non-profit site and an open-source project.
-
-
+
- + - + @@ -154,7 +143,14 @@ - + +
+ + Your game or demo online
+ If you want to have your game or demo on this site, please contact me. + It would be published under a free license, with a link to your homepage and would be free to play for everyone. + This is a non-profit site and an open-source project. +
@@ -533,7 +529,7 @@ Enabled - Move @@ -670,7 +666,7 @@
- + - + \ No newline at end of file diff --git a/index.js b/index.js index ac3d858..ae94e4c 100644 --- a/index.js +++ b/index.js @@ -14,15 +14,45 @@ const URL_TEAM_HOI = 'Team Hoi'; const URL_RETROGURU = 'retroguru'; +const URL_LOEWENSTEIN = 'Richard Löwenstein'; const db = [ /* name company year [disks] [change, turbo] [en,f1,f2,map] load [keys] immediate */ [ + ['Air Ace II', ['SEUCK', '-', 'Public Domain'], '1989', + ['Air Ace II.adf', false, false, false], [false, true], + [true, 16, 17, false], ['...takes very long.'], [], false + ], + ['Asteroids', ['Vertical Developments', '-', 'Public Domain'], '1979', + ['Asteroids.adf', false, false, false], [false, true], + [true, 16, 17, false], [], [], false + ], + ['Crazy Sue', ['Jumpshoe, Hironymous', '-', 'Public Domain'], '1991', + ['Crazy Sue.adf', false, false, false], [false, true], + [true, 16, 17, false], ['...can take some time.'], [], false + ], + ['Deluxe Galaga 2.4', ['Edgar Vigdal', '-', 'Freeware'], '1994', + ['Deluxe Galaga.adf', false, false, false], [false, true], + [true, 16, 17, false], [], [], false + ], ['Hoi', [URL_TEAM_HOI, 'Hollyware', 'Freeware'], '1992', ['Hoi (Disk 1).adf', 'Hoi (Disk 2).adf', false, false], [true, true], - [true, 16, 17, false], ['Press the LMB to skip the intro and insert the 2nd disk manually.'], [], false + [true, 16, 17, false], ['Press the LMB to skip the intro and insert the 2nd disk manually.

'+ + 'Cheat (move mouse-over)'], [], false ], + ['Norse Gods', [URL_LOEWENSTEIN, '-', 'Freeware'], '1991', + ['Norse Gods.adf', false, false, false], [false, true], + [true, 16, 17, false], [], [], false + ], + ['Pollymorf', ['Andrew Campbell', '-', 'Public Domain'], '1993', + ['Pollymorf.adf', false, false, false], [false, true], + [true, 16, 17, false], ['...takes some time, just wait.'], [], false + ], + /*['Rectum', ['Mathias Olsson', '-', 'Freeware'], '1992', + ['Rectum.adf', false, false, false], [false, true], + [true, 16, 17, false], ['Press the LMB to skip the intro...'], [], false + ],*/ ['Sqrxz', [URL_RETROGURU, '-', 'Freeware'], '2012', ['sqrxz.adf', false, false, false], [false, true], [true, 16, 17, false], ['The color-stripes are normal, just wait...'], [], false @@ -31,6 +61,14 @@ const db = [ ['sqrxz2.adf', false, false, false], [false, true], [true, 16, 17, false], ['After the start, click the RMB for the trainer menu.
The color-stripes are normal, just wait...'], [], false ], + ['Super Obliteration', ['David Papworth', '-', 'Freeware'], '1993', + ['Super Obliteration.adf', false, false, false], [false, true], + [true, 16, 17, false], [], [], false + ], + ['Tanx', ['Robertz Gaz', '-', 'Public Domain'], '1991', + ['Tanx.adf', false, false, false], [false, true], + [true, 16, 17, false], [], [], false + ] ], [ ['242', 'Virtual Dreams', '1992', @@ -78,6 +116,10 @@ const db = [ [true, 16, 17, false], ['Insert the 2nd disk manually and
click the RMB when done.'], [], true ], + ['HipHop Hater', 'Mathias Olsson', '1991', + ['HipHop Hater.adf',false,false,false], [false, true], + [true, 16, 17, false], [], [], false + ], ['Ice', 'Silents', '1991', ['Ice.adf',false,false,false], [false, true], [true, 16, 17, false], ['Press LMB at the intro-screen'], [], false @@ -134,12 +176,12 @@ var dbNum = 0; const aros_rom_file = 'aros-amiga-m68k-rom.bin'; const aros_rom_url = 'http://'+window.location.hostname+'/db/'+aros_rom_file; const aros_rom_size = 0x80000; -const aros_rom_crc = 0xea48b4d1; //0xfc4635e1; +const aros_rom_crc = 0x48dfadd; //0xea48b4d1 const aros_ext_file = 'aros-amiga-m68k-ext.bin'; const aros_ext_url = 'http://'+window.location.hostname+'/db/'+aros_ext_file; const aros_ext_size = 0x80000; -const aros_ext_crc = 0x60871435; //0xc612f82e; - +const aros_ext_crc = 0xaaf211d6; //0x60871435 + var mode = 0; var paused = false; var dskchg = false; @@ -163,42 +205,42 @@ function Cache() { var roms = [null,null]; var disks = []; - this.loadRom = function(num) { - if (roms[num]) { - console.log('loadRom.loadRom() %d is cached', num); - return roms[num]; - } - console.log('loadRom.loadRom() downloading %d', num); - - var url, size, crc; - switch (num) { - case 0: - url = aros_rom_url; - size = aros_rom_size; - crc = aros_rom_crc; - break; - case 1: - url = aros_ext_url; - size = aros_ext_size; - crc = aros_ext_crc; - break; - } - var data = loadRemoteSync(url); - if (typeof(data) == 'number') { - alert('Can\'t download '+url+' (http status: '+data+')'); - } else { - if (data.length == size) { - //console.log(dechex(crc32(data))); - if (crc32(data) == crc) { - roms[num] = data; - return data; - } else - alert('Wrong checksum for '+url+' (is $'+dechex(crc32(data))+', should $'+dechex(crc)+')'); - } else - alert('Wrong file-length for '+url+' ('+size+')'); - } - return null; - } + this.loadRom = function (num) { + if (roms[num]) { + console.log('loadRom.loadRom() %d is cached', num); + return roms[num]; + } + console.log('loadRom.loadRom() downloading %d', num); + + var url, size, crc; + switch (num) { + case 0: + url = aros_rom_url; + size = aros_rom_size; + crc = aros_rom_crc; + break; + case 1: + url = aros_ext_url; + size = aros_ext_size; + crc = aros_ext_crc; + break; + } + var data = loadRemoteSync(url); + if (typeof(data) == 'number') { + alert('Can\'t download ' + url + ' (http status: ' + data + ')'); + } else { + if (data.length == size) { + //console.log(dechex(crc32(data))); + if (crc32(data) == crc) { + roms[num] = data; + return data; + } else + alert('Wrong checksum for ' + url + ' (is $' + dechex(crc32(data)) + ', should $' + dechex(crc) + ')'); + } else + alert('Wrong file-length for ' + url + ' (' + size + ')'); + } + return null; + }; this.loadDisk = function(url) { for (var i = 0; i < disks.length; i++) { @@ -230,7 +272,7 @@ function Cache() { /*-----------------------------------------------------------------------*/ /* utils */ -function dump(obj) { +/*function dump(obj) { var out = ''; if (obj) { for (var i in obj) { @@ -238,10 +280,7 @@ function dump(obj) { } } alert(out); - /*var pre = document.createElement('pre'); - pre.innerHTML = out; - document.body.appendChild(pre);*/ -} +}*/ function crc32(str, crc) { @@ -289,11 +328,6 @@ function crc32(str, crc) { return crc < 0 ? crc + 0x100000000 : crc; } -function openNewTab(url) { - window.open(url, '_blank'); - window.focus(); -} - function getSelectValue(e) { for (var i = 0; i < e.length; i++) { if (e[i].selected) return e[i].value; @@ -329,7 +363,7 @@ function disabled(id, d) { document.getElementById(id).disabled = d ? 'disabled' : ''; } -function toggleFullScreen() { +/*function toggleFullScreen() { if ((document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method (!document.mozFullScreenElement && !document.webkitFullScreenElement)) { // current working methods if (document.documentElement.requestFullScreen) { @@ -348,40 +382,40 @@ function toggleFullScreen() { document.webkitCancelFullScreen(); } } -} +}*/ -function loadLocalId(id, callback) { +/*function loadLocalId(id, callback) { var e = document.getElementById(id).files[0]; var reader = new FileReader(); reader.onload = callback; reader.readAsBinaryString(e); -} +}*/ function loadLocal(e, callback) { var reader = new FileReader(); reader.onload = callback; reader.readAsBinaryString(e); } -function loadRemote(url, size, crc, callback) { +/*function loadRemote(url, size, crc, callback) { var req = new XMLHttpRequest(); req.open('GET', url, true); req.overrideMimeType('text\/plain; charset=x-user-defined'); - req.onreadystatechange = function(e) { - if (req.readyState == 4) { - if (req.status == 200) { - if (req.responseText.length == size) { - if (crc === false || crc32(req.responseText) == crc) - callback(0, req.responseText); - else - callback(1, crc32(req.responseText)); - } else - callback(2, req.responseText.length); - } else - callback(3, req.status); - } - } + req.onreadystatechange = function (e) { + if (req.readyState == 4) { + if (req.status == 200) { + if (req.responseText.length == size) { + if (crc === false || crc32(req.responseText) == crc) + callback(0, req.responseText); + else + callback(1, crc32(req.responseText)); + } else + callback(2, req.responseText.length); + } else + callback(3, req.status); + } + }; req.send(null); -} +}*/ function loadRemoteSync(url) { var req = new XMLHttpRequest(); req.open('GET', url, false); @@ -539,7 +573,7 @@ function getSimpleConfig() { config.chipset.mask = SAEV_Config_Chipset_Mask_OCS; config.chipset.agnus_dip = false; /* A1000 */ - config.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None; + config.chipset.collision_level = (item !== null && item[0] == 'Deluxe Galaga 2.4') ? SAEV_Config_Chipset_ColLevel_Sprite_Playfield : SAEV_Config_Chipset_ColLevel_None; config.blitter.immediate = (item !== null && item[8]) ? true : false; config.blitter.waiting = config.blitter.immediate ? 0 : 1; @@ -680,6 +714,7 @@ function fireButtonName(fire) { case 145: return 'Scroll lock'; case 49: return '1'; case 50: return '2'; + default: return 'ERROR'; } } @@ -721,8 +756,8 @@ function setConfig() { e = document.getElementById('cfg_chipset_type'); switch (config.chipset.mask) { - case SAEV_Config_Chipset_Mask_OCS: e[0].selected = true; break - case SAEV_Config_Chipset_Mask_ECS_AGNUS: e[1].selected = true; break + case SAEV_Config_Chipset_Mask_OCS: e[0].selected = true; break; + case SAEV_Config_Chipset_Mask_ECS_AGNUS: e[1].selected = true; break; case SAEV_Config_Chipset_Mask_ECS_DENISE: e[2].selected = true; break } document.getElementById('cfg_chipset_cl_enabled').checked = config.chipset.collision_level != SAEV_Config_Chipset_ColLevel_None; @@ -809,7 +844,6 @@ function setConfig() { styleDisplayBlock('cfg_keyborad_grp', config.keyboard.enabled != 0); document.getElementById('cfg_ports_0_enabled').checked = config.ports[0].type != SAEV_Config_Ports_Type_None; - e = document.getElementById('cfg_ports_0'); switch (config.ports[0].type) { case SAEV_Config_Ports_Type_Mouse: document.getElementById('cfg_ports_0')[0].selected = true; break; case SAEV_Config_Ports_Type_Joy0: document.getElementById('cfg_ports_0')[1].selected = true; break; @@ -824,8 +858,7 @@ function setConfig() { styleDisplayInline('cfg_ports_0_grp', config.ports[0].type != SAEV_Config_Ports_Type_None); styleDisplayInline('cfg_ports_0_grp2', config.ports[0].type == SAEV_Config_Ports_Type_Joy0); - e = document.getElementById('cfg_ports_1_enabled').checked = config.ports[1].type != SAEV_Config_Ports_Type_None; - e = document.getElementById('cfg_ports_1'); + document.getElementById('cfg_ports_1_enabled').checked = config.ports[1].type != SAEV_Config_Ports_Type_None; switch (config.ports[1].type) { case SAEV_Config_Ports_Type_Joy1: document.getElementById('cfg_ports_1')[0].selected = true; break; } @@ -838,7 +871,7 @@ function setConfig() { setFireButton('cfg_ports_1_fire_2', config.ports[1].fire[1]); styleDisplayInline('cfg_ports_1_grp', config.ports[1].type == SAEV_Config_Ports_Type_Joy1); - e = document.getElementById('cfg_serial_enabled').checked = config.serial.enabled != 0; + document.getElementById('cfg_serial_enabled').checked = config.serial.enabled != 0; styleDisplayInline('dskchg_grp', 1); } @@ -848,6 +881,7 @@ function getMask(type) { case SAEV_Config_Chipset_Type_OCS: return SAEV_Config_Chipset_Mask_OCS; case SAEV_Config_Chipset_Type_ECS_AGNUS: return SAEV_Config_Chipset_Mask_ECS_AGNUS; case SAEV_Config_Chipset_Type_ECS_DENISE: return SAEV_Config_Chipset_Mask_ECS_DENISE; + default: return SAEV_Config_Chipset_Mask_OCS; } } @@ -1059,7 +1093,9 @@ function stop() { if (paused) { var e = document.getElementById('status_pr'); e.value = 'pause'; - e.onclick = function() { pause(1); } + e.onclick = function () { + pause(1); + }; paused = false; } if (dskchg) @@ -1078,14 +1114,16 @@ function stop() { document.body.style.backgroundColor = '#fff'; } -function reset(p) { +function reset() { SAE({cmd:'reset'}); } function pause(p) { var e = document.getElementById('status_pr'); e.innerHTML = p ? 'Resume' : 'Pause'; - e.onclick = function() { pause(1 - p); } + e.onclick = function () { + pause(1 - p); + }; paused = p; @@ -1203,7 +1241,8 @@ function romAROS() { document.getElementById('cfg_ext_addr')[0].selected = true; styleDisplayInline('cfg_ext_remove', 1); styleDisplayTableRow('cfg_ext_addr_grp', 1); - disabled('cfg_rom_aros', 0); + disabled('cfg_rom_aros', 0); + return true; } function romSelect() { @@ -1273,7 +1312,7 @@ function floppyUpdate(n) { function floppyInsert(n) { var e = document.getElementById('cfg_df'+n+'_file').files[0]; - var ok = false; + var ok = true; //false; if (!e) return; /*if (e.size == 0xDC000) { @@ -1290,7 +1329,7 @@ function floppyInsert(n) { } else alert('Invalid diskimage-size, 880 or 1460 kb.'); */ - ok = true; + if (ok) loadLocal(e, function (event) { config.floppy.drive[n].name = e.name; @@ -1435,7 +1474,7 @@ function dskchgInsert() { if (!dskchg) return; var n = getSelectValue(document.getElementById('cfg_dskchg_unit')); var e = document.getElementById('cfg_dskchg_file').files[0]; - var ok = false; + var ok = true; //false; if (!e) return; /*if (e.size == 0xDC000) { @@ -1450,8 +1489,7 @@ function dskchgInsert() { alert('DF'+n+' is configured as DD-drive (880kb), but you selected a HD-diskimage (1760kb).'); } else alert('Invalid diskimage-size, 880 or 1460 kb.'); - */ - ok = true; + */ if (ok) { loadLocal(e, function (event) { dskchgClose(); diff --git a/readme.htm b/readme.htm index 1fdd151..d00ccbd 100644 --- a/readme.htm +++ b/readme.htm @@ -5,12 +5,6 @@ -
@@ -101,39 +95,39 @@
  • Some stats
      -
    • The first public version had ~13.000 lines of code, currently ~23.500
    • -
    • About 5 months development time for the first version.
    • -
    • About the half of the first version was written from scratch, the rest was ported from WinUAE.
    • +
    • About 5 months development time for the first public version. (0.5)
    • +
    • About the half of the first version was written from scratch, the rest was ported from various UAE-sources.
    • +
    • The first version had ~13.000 lines of code, currently ~23.500, most new code is ported from WinUAE.
@@ -284,7 +278,7 @@
  • Chaned the project-name from 'Janus' to 'SAE' (Scripted Amiga Emulator).
    This step is necessary because i did'nt enough research before the initial release.
    - There is already a project with that name in it. (janus-uae) + There is already a project with that name in it. (janus-uae) I'm sorry for that, that was kinda stupid :)
  • Separated the GUI form the core and rewrote most of it.
  • Simplified the whole code. This means, that functions are called faster.
  • diff --git a/sae/amiga.js b/sae/amiga.js index 41ac979..73ad94a 100644 --- a/sae/amiga.js +++ b/sae/amiga.js @@ -52,58 +52,58 @@ function Amiga() { /*---------------------------------*/ - this.setup = function() { - this.mem.setup(); - this.expansion.setup(); - this.events.setup(); - this.playfield.setup(); - this.video.setup(); - this.cia.setup(); - this.rtc.setup(); - this.input.setup(); - this.disk.setup(); - this.audio.setup(); - this.custom.setup(); - this.cpu.setup(); - } + this.setup = function () { + this.mem.setup(); + this.expansion.setup(); + this.events.setup(); + this.playfield.setup(); + this.video.setup(); + this.cia.setup(); + this.rtc.setup(); + this.input.setup(); + this.disk.setup(); + this.audio.setup(); + this.custom.setup(); + this.cpu.setup(); + }; - this.cleanup = function() { - this.audio.cleanup(); - this.video.cleanup(); - this.playfield.cleanup(); - this.input.cleanup(); - } + this.cleanup = function () { + this.audio.cleanup(); + this.video.cleanup(); + this.playfield.cleanup(); + this.input.cleanup(); + }; - this.reset = function() { - BUG.info('Amiga.reset()'); - - this.delay = 0; - this.spcflags = 0; - //this.loading = 0; - - this.intena = 0; - this.intreq = 0; - this.dmacon = 0; - this.adkcon = 0; - - this.expansion.reset(); - this.events.reset(); - this.playfield.reset(); - this.cia.reset(); - this.disk.reset(); - this.input.reset(); - this.serial.reset(); - this.blitter.reset(); - this.copper.reset(); - this.audio.reset(); - this.custom.reset(); - this.cpu.reset(this.mem.rom.lower); - } + this.reset = function () { + BUG.info('Amiga.reset()'); - this.dump = function() { - this.cpu.dump(); - //this.cia.dump(); - } + this.delay = 0; + this.spcflags = 0; + //this.loading = 0; + + this.intena = 0; + this.intreq = 0; + this.dmacon = 0; + this.adkcon = 0; + + this.expansion.reset(); + this.events.reset(); + this.playfield.reset(); + this.cia.reset(); + this.disk.reset(); + this.input.reset(); + this.serial.reset(); + this.blitter.reset(); + this.copper.reset(); + this.audio.reset(); + this.custom.reset(); + this.cpu.reset(this.mem.rom.lower); + }; + + this.dump = function () { + this.cpu.dump(); + //this.cia.dump(); + }; /*---------------------------------*/ @@ -122,28 +122,28 @@ function Amiga() { }*/ - this.start = function() { - if (this.state == ST_STOP) { - this.setup(); - this.reset(); - this.state = ST_CYCLE; - setTimeout('AMIGA.cycle()', 0); - } - } + this.start = function () { + if (this.state == ST_STOP) { + this.setup(); + this.reset(); + this.state = ST_CYCLE; + setTimeout('AMIGA.cycle()', 0); + } + }; - this.stop = function() { - if (this.state != ST_STOP) { - this.state = ST_STOP; - this.cleanup(); - } - } + this.stop = function () { + if (this.state != ST_STOP) { + this.state = ST_STOP; + this.cleanup(); + } + }; - this.pause = function(state) { - if (this.state != ST_STOP) { - this.state = state ? ST_PAUSE : ST_CYCLE; - this.audio.pauseResume(state); - } - } + this.pause = function (state) { + if (this.state != ST_STOP) { + this.state = state ? ST_PAUSE : ST_CYCLE; + this.audio.pauseResume(state); + } + }; /*this.insert = function(unit, name, data) { //this.disk.insert_data(unit, data); @@ -161,194 +161,193 @@ function Amiga() { } */ - this.insert = function(unit) { - if (this.state != ST_STOP) - this.disk.insert(unit); - } + this.insert = function (unit) { + if (this.state != ST_STOP) + this.disk.insert(unit); + }; - this.eject = function(unit) { - if (this.state != ST_STOP) - this.disk.eject(unit); - } + this.eject = function (unit) { + if (this.state != ST_STOP) + this.disk.eject(unit); + }; /*---------------------------------*/ /* mainloop */ - this.cycle = function() { - try { - this.cpu.cycle(); - } catch (e) { - if (e instanceof VSync) { - //console.log(e.error, e.message); - this.state = ST_IDLE; - } else - if (e instanceof FatalError) { - this.state = ST_STOP; - this.stop(); - this.config.hooks.error(e.error, e.message); - } else /* normal exception */ { - this.state = ST_STOP; - this.stop(); - console.log(e); - } - } - if (this.state == ST_IDLE) { - this.state = ST_CYCLE; - setTimeout('AMIGA.cycle()', this.delay); - } - else if (this.state == ST_PAUSE) - AMIGA.cyclePause(); - else - AMIGA.cycleExit(); - } + this.cycle = function () { + try { + this.cpu.cycle(); + } catch (e) { + if (e instanceof VSync) { + //console.log(e.error, e.message); + this.state = ST_IDLE; + } else if (e instanceof FatalError) { + this.state = ST_STOP; + this.stop(); + this.config.hooks.error(e.error, e.message); + } else /* normal exception */ { + this.state = ST_STOP; + this.stop(); + console.log(e); + } + } + if (this.state == ST_IDLE) { + this.state = ST_CYCLE; + setTimeout('AMIGA.cycle()', this.delay); + } + else if (this.state == ST_PAUSE) + AMIGA.cyclePause(); + else + AMIGA.cycleExit(); + }; - this.cyclePause = function() { - if (this.state == ST_CYCLE) - setTimeout('AMIGA.cycle()', 0); - else if (this.state == ST_PAUSE) - setTimeout('AMIGA.cyclePause()', 500); - else - AMIGA.cycleExit(); - } + this.cyclePause = function () { + if (this.state == ST_CYCLE) + setTimeout('AMIGA.cycle()', 0); + else if (this.state == ST_PAUSE) + setTimeout('AMIGA.cyclePause()', 500); + else + AMIGA.cycleExit(); + }; - this.cycleExit = function() { - this.dump(); - //this.cia.dump(); - } + this.cycleExit = function () { + this.dump(); + //this.cia.dump(); + }; /*---------------------------------*/ this.dmaen = function (dmamask) { - return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0); - } + return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0); + }; - this.DMACONR = function(hpos) { - this.playfield.decide_line(hpos); - this.playfield.decide_fetch(hpos); - this.dmacon &= ~(0x4000 | 0x2000); - var iz = this.blitter.getIntZero(); - this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0)); - return this.dmacon; - } + this.DMACONR = function (hpos) { + this.playfield.decide_line(hpos); + this.playfield.decide_fetch(hpos); + this.dmacon &= ~(0x4000 | 0x2000); + var iz = this.blitter.getIntZero(); + this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0)); + return this.dmacon; + }; this.DMACON = function (v, hpos) { - var oldcon = this.dmacon; - - this.playfield.decide_line(hpos); - this.playfield.decide_fetch(hpos); + var oldcon = this.dmacon; - if (v & INTF_SETCLR) - this.dmacon |= v & ~INTF_SETCLR; - else - this.dmacon &= ~v; - - this.dmacon &= 0x1fff; - - var changed = this.dmacon ^ oldcon; + this.playfield.decide_line(hpos); + this.playfield.decide_fetch(hpos); - var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0; - var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0; - if (oldcop != newcop) { - if (newcop && !oldcop) { - this.copper.compute_spcflag_copper(this.events.hpos()); - } else if (!newcop) { - this.copper.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - } - } - if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done) - set_special(SPCFLAG_BLTNASTY); - if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init) - this.blitter.setState(BLT_work); - if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) - clr_special(SPCFLAG_BLTNASTY); - - if (changed & (DMAF_DMAEN | 0x0f)) - this.audio.state_machine(); - - if (changed & (DMAF_DMAEN | DMAF_BPLEN)) { - this.playfield.update_ddf_change(); - if (this.dmaen(DMAF_BPLEN)) - this.playfield.maybe_start_bpl_dma(hpos); - } - this.events.schedule(); - } + if (v & INTF_SETCLR) + this.dmacon |= v & ~INTF_SETCLR; + else + this.dmacon &= ~v; + + this.dmacon &= 0x1fff; + + var changed = this.dmacon ^ oldcon; + + var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0; + var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0; + if (oldcop != newcop) { + if (newcop && !oldcop) { + this.copper.compute_spcflag_copper(this.events.hpos()); + } else if (!newcop) { + this.copper.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + } + } + if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done) + set_special(SPCFLAG_BLTNASTY); + if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init) + this.blitter.setState(BLT_work); + if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) + clr_special(SPCFLAG_BLTNASTY); + + if (changed & (DMAF_DMAEN | 0x0f)) + this.audio.state_machine(); + + if (changed & (DMAF_DMAEN | DMAF_BPLEN)) { + this.playfield.update_ddf_change(); + if (this.dmaen(DMAF_BPLEN)) + this.playfield.maybe_start_bpl_dma(hpos); + } + this.events.schedule(); + }; /*---------------------------------*/ this.ADKCONR = function () { - return this.adkcon; - } + return this.adkcon; + }; this.ADKCON = function (v, hpos) { - if (this.config.audio.enabled) - this.audio.update(); + if (this.config.audio.enabled) + this.audio.update(); - this.disk.update(hpos); - this.disk.update_adkcon(v); - - if (v & INTF_SETCLR) - this.adkcon |= v & ~INTF_SETCLR; - else - this.adkcon &= ~v; - - this.audio.update_adkmasks(); - } + this.disk.update(hpos); + this.disk.update_adkcon(v); + + if (v & INTF_SETCLR) + this.adkcon |= v & ~INTF_SETCLR; + else + this.adkcon &= ~v; + + this.audio.update_adkmasks(); + }; /*---------------------------------*/ this.INTENAR = function () { - return this.intena; - } + return this.intena; + }; - this.INTENA = function(v) { - if (v & INTF_SETCLR) - this.intena |= v & ~INTF_SETCLR; - else - this.intena &= ~v; + this.INTENA = function (v) { + if (v & INTF_SETCLR) + this.intena |= v & ~INTF_SETCLR; + else + this.intena &= ~v; - if (v & INTF_SETCLR) - this.doint(); - } + if (v & INTF_SETCLR) + this.doint(); + }; /*---------------------------------*/ this.INTREQR = function () { - return this.intreq; - } + return this.intreq; + }; - this.INTREQ_0 = function(v) { - var old = this.intreq; - - if (v & INTF_SETCLR) - this.intreq |= v & ~INTF_SETCLR; - else - this.intreq &= ~v; + this.INTREQ_0 = function (v) { + var old = this.intreq; - if ((v & INTF_SETCLR) && this.intreq != old) - this.doint(); - } + if (v & INTF_SETCLR) + this.intreq |= v & ~INTF_SETCLR; + else + this.intreq &= ~v; - this.INTREQ = function(v) { - this.INTREQ_0(v); - this.cia.rethink(); - } + if ((v & INTF_SETCLR) && this.intreq != old) + this.doint(); + }; + + this.INTREQ = function (v) { + this.INTREQ_0(v); + this.cia.rethink(); + }; /*---------------------------------*/ - this.intlev = function() { - var imask = this.intreq & this.intena; + this.intlev = function () { + var imask = this.intreq & this.intena; - if (imask && (this.intena & INTF_INTEN)) { - if (imask & 0x2000) return 6; - if (imask & 0x1800) return 5; - if (imask & 0x0780) return 4; - if (imask & 0x0070) return 3; - if (imask & 0x0008) return 2; - if (imask & 0x0007) return 1; - } - return -1; - } + if (imask && (this.intena & INTF_INTEN)) { + if (imask & 0x2000) return 6; + if (imask & 0x1800) return 5; + if (imask & 0x0780) return 4; + if (imask & 0x0070) return 3; + if (imask & 0x0008) return 2; + if (imask & 0x0007) return 1; + } + return -1; + }; this.doint = function() { if (AMIGA.config.cpu.compatible) @@ -361,6 +360,9 @@ function Amiga() { /*-----------------------------------------------------------------------*/ /* This API will change in the future. */ +var BUG = null; +var AMIGA = null; + function SAE(x) { try { switch (x.cmd) { @@ -383,10 +385,6 @@ function SAE(x) { BUG.info('API.stop()'); AMIGA.stop(); break; - case 'reset': - BUG.info('API.reset()'); - AMIGA.reset(); - break; case 'pause': BUG.info('API.pause() %d', x.state); AMIGA.pause(x.state); @@ -424,4 +422,5 @@ function SAE(x) { } //return SAEE_None; //return { error:SAEE_None, message:'' }; + return 0; } diff --git a/sae/audio.js b/sae/audio.js index a1e98f0..fd5b30b 100644 --- a/sae/audio.js +++ b/sae/audio.js @@ -51,26 +51,26 @@ function Filter() { return 1 / (1 + 1 / omega); } - this.setup = function(on) { - this.on = on; - var rate = getRate(AMIGA.config.audio.rate); - filter1_a0 = calc(rate, 6200); - filter2_a0 = calc(rate, 20000); - filter_a0 = calc(rate, 7000); - /*console.log(rate); - console.log(filter1_a0); - console.log(filter2_a0); - console.log(filter_a0);*/ - } + this.setup = function (on) { + this.on = on; + var rate = getRate(AMIGA.config.audio.rate); + filter1_a0 = calc(rate, 6200); + filter2_a0 = calc(rate, 20000); + filter_a0 = calc(rate, 7000); + /*console.log(rate); + console.log(filter1_a0); + console.log(filter2_a0); + console.log(filter_a0);*/ + }; - this.reset = function() { - filter_state = [ - { rc1:0,rc2:0,rc3:0,rc4:0,rc5:0 }, - { rc1:0,rc2:0,rc3:0,rc4:0,rc5:0 }, - { rc1:0,rc2:0,rc3:0,rc4:0,rc5:0 }, - { rc1:0,rc2:0,rc3:0,rc4:0,rc5:0 } - ]; - } + this.reset = function () { + filter_state = [ + { rc1: 0, rc2: 0, rc3: 0, rc4: 0, rc5: 0 }, + { rc1: 0, rc2: 0, rc3: 0, rc4: 0, rc5: 0 }, + { rc1: 0, rc2: 0, rc3: 0, rc4: 0, rc5: 0 }, + { rc1: 0, rc2: 0, rc3: 0, rc4: 0, rc5: 0 } + ]; + }; this.filter = function(input, state) { //if (!this.on) return input; @@ -94,7 +94,6 @@ function Filter() { function Channel(num) { this.num = num; - this.adk_mask = 0; this.enabled = false; this.evtime = 0; this.dmaenstore = false; @@ -118,102 +117,101 @@ function Channel(num) { this.ptx_written = false; this.ptx_tofetch = false; - this.reset = function() { - this.adk_mask = 0; - this.enabled = false; - this.evtime = CYCLE_MAX; - this.dmaenstore = false; - this.intreq = false; - this.dr = false; - this.dsr = false; - this.pbufldl = false; - this.dat_written = false; - this.state = 0; - this.lc = 0; - this.pt = 0; - this.per = PERIOD_MAX - 1; - this.vol = 0; - this.len = 0; - this.wlen = 0; - this.dat = 0; - this.dat2 = 0; - this.current_sample = 0; - this.last_sample = 0; - this.ptx = 0; - this.ptx_written = false; - this.ptx_tofetch = false; - } + this.reset = function () { + this.enabled = false; + this.evtime = CYCLE_MAX; + this.dmaenstore = false; + this.intreq = false; + this.dr = false; + this.dsr = false; + this.pbufldl = false; + this.dat_written = false; + this.state = 0; + this.lc = 0; + this.pt = 0; + this.per = PERIOD_MAX - 1; + this.vol = 0; + this.len = 0; + this.wlen = 0; + this.dat = 0; + this.dat2 = 0; + this.current_sample = 0; + this.last_sample = 0; + this.ptx = 0; + this.ptx_written = false; + this.ptx_tofetch = false; + }; //const audio_channel_mask = 15; - this.newsample = function(sample) { - //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].newsample() %02x', nr, sample); - //if (!(audio_channel_mask & (1 << this.num))) sample = 0; - if (sample & 0x80) sample -= 0x100; - this.last_sample = this.current_sample; - this.current_sample = sample; - } + this.newsample = function (sample) { + //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].newsample() %02x', nr, sample); + //if (!(audio_channel_mask & (1 << this.num))) sample = 0; + if (sample & 0x80) sample -= 0x100; + this.last_sample = this.current_sample; + this.current_sample = sample; + }; - this.isirq = function() { - return (AMIGA.INTREQR() & (0x80 << this.num)) != 0; - } + this.isirq = function () { + return (AMIGA.INTREQR() & (0x80 << this.num)) != 0; + }; - this.setirq = function(which) { - //if (debugchannel(this.num) && this.wlen > 1) BUG.info('Audio.channel[%d].setirq() %d, %d', this.num, which, this.isirq() ? 1 : 0); - AMIGA.INTREQ_0(INTF_SETCLR | (0x80 << this.num)); - } + this.setirq = function (which) { + //if (debugchannel(this.num) && this.wlen > 1) BUG.info('Audio.channel[%d].setirq() %d, %d', this.num, which, this.isirq() ? 1 : 0); + AMIGA.INTREQ_0(INTF_SETCLR | (0x80 << this.num)); + }; - this.zerostate = function() { - //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].zerostate()', this.num); - this.state = 0; - this.evtime = CYCLE_MAX; - this.intreq = false; - this.dmaenstore = false; - } + this.zerostate = function () { + //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].zerostate()', this.num); + this.state = 0; + this.evtime = CYCLE_MAX; + this.intreq = false; + this.dmaenstore = false; + }; - this.setdr = function() { - //if (debugchannel(this.num) && this.dr) BUG.info('Audio.channel[%d].setdr() DR already active (STATE %d)', this.num, this.state); - this.dr = true; - if (this.wlen == 1) { - this.dsr = true; - //if (debugchannel(this.num) && this.wlen > 1) BUG.info('Audio.channel[%d].setdr() DSR on, pt %08x', this.num, this.pt); - } - } + this.setdr = function () { + //if (debugchannel(this.num) && this.dr) BUG.info('Audio.channel[%d].setdr() DR already active (STATE %d)', this.num, this.state); + this.dr = true; + if (this.wlen == 1) { + this.dsr = true; + //if (debugchannel(this.num) && this.wlen > 1) BUG.info('Audio.channel[%d].setdr() DSR on, pt %08x', this.num, this.pt); + } + }; - this.loaddat = function(modper) { - var audav = (AMIGA.adkcon & (0x01 << this.num)) != 0; - var audap = (AMIGA.adkcon & (0x10 << this.num)) != 0; - if (audav || (modper && audap)) { - if (this.num >= 3) - return; - if (modper && audap) { - if (this.dat == 0) - AMIGA.audio.channel[this.num + 1].per = PERIOD_MAX; - else if (this.dat > PERIOD_MIN) - AMIGA.audio.channel[this.num + 1].per = this.dat * CYCLE_UNIT; - else - AMIGA.audio.channel[this.num + 1].per = PERIOD_MIN * CYCLE_UNIT; - } else if (audav) { - AMIGA.audio.channel[this.num + 1].vol = this.dat; - AMIGA.audio.channel[this.num + 1].vol &= 127; - if (AMIGA.audio.channel[this.num + 1].vol > 64) - AMIGA.audio.channel[this.num + 1].vol = 64; - } - } else { - //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].loaddat() new %04x, old %04x', this.num, this.dat, this.dat2); - this.dat2 = this.dat; - } - } + this.loaddat = function (modper) { + var audav = (AMIGA.adkcon & (0x01 << this.num)) != 0; + var audap = (AMIGA.adkcon & (0x10 << this.num)) != 0; + if (audav || (modper && audap)) { + if (this.num >= 3) + return; + if (modper && audap) { + if (this.dat == 0) + AMIGA.audio.channel[this.num + 1].per = PERIOD_MAX; + else if (this.dat > PERIOD_MIN) + AMIGA.audio.channel[this.num + 1].per = this.dat * CYCLE_UNIT; + else + AMIGA.audio.channel[this.num + 1].per = PERIOD_MIN * CYCLE_UNIT; + } else if (audav) { + AMIGA.audio.channel[this.num + 1].vol = this.dat; + AMIGA.audio.channel[this.num + 1].vol &= 127; + if (AMIGA.audio.channel[this.num + 1].vol > 64) + AMIGA.audio.channel[this.num + 1].vol = 64; + } + } else { + //if (debugchannel(this.num)) BUG.info('Audio.channel[%d].loaddat() new %04x, old %04x', this.num, this.dat, this.dat2); + this.dat2 = this.dat; + } + }; - this.loadper = function() { - this.evtime = this.per; - if (this.evtime < CYCLE_UNIT) - BUG.info('Audio.channel[%d].loadper() bug %d', this.num, this.evtime); - } + this.loadper = function () { + this.evtime = this.per; + if (this.evtime < CYCLE_UNIT) + BUG.info('Audio.channel[%d].loadper() bug %d', this.num, this.evtime); + }; - this.state_channel = function(perfin) { - this.state_channel2(perfin); - this.dat_written = false; - } + this.state_channel = function (perfin) { + this.state_channel2(perfin); + this.dat_written = false; + }; this.state_channel2 = function(perfin) { var chan_ena = ((AMIGA.dmacon & DMAF_DMAEN) && (AMIGA.dmacon & (1 << this.num))) ? true : false; @@ -399,7 +397,7 @@ function Audi0() { realSize: 0, data:0, pos: 0, - rate: new mavg(10) + rate: new MAvg(10) }; var ringBuffer = { size: 0, @@ -417,18 +415,19 @@ function Audi0() { { var test; - /*try { - test = new AudioContext(); - test = null; - this.available |= SAEI_Audio_Default; - } catch (e) {}*/ - try { - test = new webkitAudioContext(); + test = new AudioContext(); if (test && test.createJavaScriptNode) - this.available |= SAEI_Audio_Webkit; + this.available |= SAEI_Audio_Default; test = null; - } catch (e) {} + } catch (e) { + try { + test = new webkitAudioContext(); + if (test && test.createJavaScriptNode) + this.available |= SAEI_Audio_Webkit; + test = null; + } catch (e) {} + } try { test = new Audio(); @@ -452,549 +451,549 @@ function Audi0() { } } - this.calc_sample_evtime = function(freq, longframe, linetoggle) { - var lines = 0.0; - var hpos; + this.calc_sample_evtime = function (freq, longframe, linetoggle) { + var lines = 0.0; + var hpos; - if (linetoggle) { - hpos = AMIGA.playfield.maxhpos_short + 0.5; - lines += 0.5; - } else { - hpos = AMIGA.playfield.maxhpos_short + 0.0; - if (longframe < 0) - lines += 0.5; - else if (longframe > 0) - lines += 1.0; - } - 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; -/*#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); - } + if (linetoggle) { + hpos = AMIGA.playfield.maxhpos_short + 0.5; + lines += 0.5; + } else { + hpos = AMIGA.playfield.maxhpos_short + 0.0; + if (longframe < 0) + lines += 0.5; + else if (longframe > 0) + lines += 1.0; + } + 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; + /*#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) { - channel = []; - for (var i = 0; i < 4; i++) - channel[i] = new Channel(i); - } - if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) - return; + this.setup = function () { + if (channel === null) { + channel = []; + for (var i = 0; i < 4; i++) + channel[i] = new Channel(i); + } + if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) + return; - if (driver.ctx === null) { - 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, null); - } + if (driver.ctx === null) { + if (this.available & SAEI_Audio_Default) + driver.ctx = new AudioContext(); + else 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, null); + } + + this.filter.setup(AMIGA.config.audio.filter); + /* A500 lowpass-filter */ + + var hz = AMIGA.config.video.ntsc ? 60 : 50; + this.calc_sample_evtime(hz, 1, AMIGA.config.video.ntsc); + + 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 + (sampleBuffer.size >> 1); + ringBuffer.data = new Float32Array(ringBuffer.size << (AMIGA.config.audio.channels - 1)); + + if ((this.available & SAEI_Audio_Default) || (this.available & SAEI_Audio_Webkit)) { + var inputs = BrowserDetect.browser == 'Safari' ? 1 : 0; + //if (inputs == 1) BUG.info('Audio.setup() Safari fix enabled.'); + + driver.def.node = driver.ctx.createJavaScriptNode(sampleBuffer.size, inputs, AMIGA.config.audio.channels); + driver.def.node.onaudioprocess = defFill; + 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 ((this.available & SAEI_Audio_Default) || (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.filter.setup(AMIGA.config.audio.filter); /* A500 lowpass-filter */ - - var hz = AMIGA.config.video.ntsc ? 60 : 50; - this.calc_sample_evtime(hz, 1, AMIGA.config.video.ntsc); - - sampleBuffer.size = SAMPLE_BUFFER_SIZE; - sampleBuffer.realSize = sampleBuffer.size << 1; - sampleBuffer.data = new Float32Array(sampleBuffer.realSize << (AMIGA.config.audio.channels - 1)); + this.pauseResume = function (pause) { + if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) return; - ringBuffer.size = sampleBuffer.size + (sampleBuffer.size >> 1); - ringBuffer.data = new Float32Array(ringBuffer.size << (AMIGA.config.audio.channels - 1)); + if (driver.ctx !== null) { + if ((this.available & SAEI_Audio_Default) || (this.available & SAEI_Audio_Webkit)) { + if (driver.def.node) { + if (pause && !driver.paused) { + driver.def.node.disconnect(0); + driver.paused = true; + } else if (!pause && driver.paused) { + driver.def.node.connect(driver.ctx.destination); + driver.paused = false; + } + } + } + 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; + } + } + } + }; - if (this.available & SAEI_Audio_Webkit) { - var inputs = BrowserDetect.browser == 'Safari' ? 1 : 0; - //if (inputs == 1) BUG.info('Audio.setup() Safari fix enabled.'); + this.reset = function () { + for (var i = 0; i < 4; i++) + channel[i].reset(); - driver.def.node = driver.ctx.createJavaScriptNode(sampleBuffer.size, inputs, AMIGA.config.audio.channels); - driver.def.node.onaudioprocess = defFill; - 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)); + last_cycles = AMIGA.events.currcycle; + next_sample_evtime = scaled_sample_evtime; + this.schedule(); + AMIGA.events.schedule(); - /*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)))); + work_to_do = 0; + prevcon = 0; - BUG.info('Audio.setup() enabled mozilla audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate)); - } - } + sampleBuffer.pos = 0; + sampleBuffer.rate.clr(); - this.cleanup = function() { - if (driver.ctx !== null) { - 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; + ringBuffer.usage = 0; + ringBuffer.readPos = 0; + ringBuffer.writePos = 0; - if (driver.ctx !== null) { - if (this.available & SAEI_Audio_Webkit) { - if (driver.def.node) { - if (pause && !driver.paused) { - driver.def.node.disconnect(0); - driver.paused = true; - } else if (!pause && driver.paused) { - driver.def.node.connect(driver.ctx.destination); - driver.paused = false; - } - } - } - 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 = 0; - - sampleBuffer.pos = 0; - sampleBuffer.rate.clr(); - - ringBuffer.usage = 0; - ringBuffer.readPos = 0; - ringBuffer.writePos = 0; - - this.filter.reset(); - } + this.filter.reset(); + }; /*---------------------------------*/ - this.event_reset = function() { - for (var i = 0; i < 4; i++) - channel[i].zerostate(); + this.event_reset = function () { + for (var i = 0; i < 4; i++) + channel[i].zerostate(); - last_cycles = AMIGA.events.currcycle; - next_sample_evtime = scaled_sample_evtime; - this.schedule(); - AMIGA.events.schedule(); - } + last_cycles = AMIGA.events.currcycle; + next_sample_evtime = scaled_sample_evtime; + this.schedule(); + AMIGA.events.schedule(); + }; - this.activate = function() { - //BUG.info('Audio.activate()'); - var ret = 0; + this.activate = function () { + //BUG.info('Audio.activate()'); + var ret = 0; - if (!work_to_do) { - this.pauseResume(0); - ret = 1; - this.event_reset(); - } - work_to_do = 4 * AMIGA.playfield.maxvpos_nom * 50; - return ret; - } + if (!work_to_do) { + this.pauseResume(0); + ret = 1; + this.event_reset(); + } + work_to_do = 4 * AMIGA.playfield.maxvpos_nom * 50; + return ret; + }; - this.deactivate = function() { - //BUG.info('Audio.deactivate()'); - this.pauseResume(1); - sampleBuffer.pos = 0; - sampleBuffer.rate.clr(); - this.event_reset(); - } + this.deactivate = function () { + //BUG.info('Audio.deactivate()'); + this.pauseResume(1); + sampleBuffer.pos = 0; + sampleBuffer.rate.clr(); + this.event_reset(); + }; - this.state_machine = function() { - this.update(); - for (var i = 0; i < 4; i++) - channel[i].state_channel(false); + this.state_machine = function () { + this.update(); + for (var i = 0; i < 4; i++) + channel[i].state_channel(false); - this.schedule(); - AMIGA.events.schedule(); - } + this.schedule(); + AMIGA.events.schedule(); + }; - this.schedule = function() { - var best = CYCLE_MAX; + this.schedule = function () { + var best = CYCLE_MAX; - AMIGA.events.eventtab[EV_AUDIO].active = false; - AMIGA.events.eventtab[EV_AUDIO].oldcycles = AMIGA.events.currcycle; - - for (var i = 0; i < 4; i++) { - if (channel[i].evtime != CYCLE_MAX) { - if (best > channel[i].evtime) { - best = channel[i].evtime; - AMIGA.events.eventtab[EV_AUDIO].active = true; - } - } - } - AMIGA.events.eventtab[EV_AUDIO].evtime = AMIGA.events.currcycle + best; - } + AMIGA.events.eventtab[EV_AUDIO].active = false; + AMIGA.events.eventtab[EV_AUDIO].oldcycles = AMIGA.events.currcycle; - this.update = function() { - if (!AMIGA.config.audio.enabled || !work_to_do) { - last_cycles = AMIGA.events.currcycle; - return; - } + for (var i = 0; i < 4; i++) { + if (channel[i].evtime != CYCLE_MAX) { + if (best > channel[i].evtime) { + best = channel[i].evtime; + AMIGA.events.eventtab[EV_AUDIO].active = true; + } + } + } + AMIGA.events.eventtab[EV_AUDIO].evtime = AMIGA.events.currcycle + best; + }; - var n_cycles = AMIGA.events.currcycle - last_cycles; - while (n_cycles > 0) { - var best_evtime = n_cycles + 1; - var i, rounded; + this.update = function () { + if (!AMIGA.config.audio.enabled || !work_to_do) { + last_cycles = AMIGA.events.currcycle; + return; + } - for (i = 0; i < 4; i++) { - if (channel[i].evtime != CYCLE_MAX && best_evtime > channel[i].evtime) - best_evtime = channel[i].evtime; - } + var n_cycles = AMIGA.events.currcycle - last_cycles; + while (n_cycles > 0) { + var best_evtime = n_cycles + 1; + var i, rounded; - rounded = Math.floor(next_sample_evtime); - if ((next_sample_evtime - rounded) >= 0.5) - rounded++; + for (i = 0; i < 4; i++) { + if (channel[i].evtime != CYCLE_MAX && best_evtime > channel[i].evtime) + best_evtime = channel[i].evtime; + } - if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul && best_evtime > rounded) - best_evtime = rounded; + rounded = Math.floor(next_sample_evtime); + if ((next_sample_evtime - rounded) >= 0.5) + rounded++; - if (best_evtime > n_cycles) - best_evtime = n_cycles; + if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul && best_evtime > rounded) + best_evtime = rounded; - next_sample_evtime -= best_evtime; + if (best_evtime > n_cycles) + best_evtime = n_cycles; - /*if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul) { - if (sample_prehandler) - sample_prehandler (best_evtime / CYCLE_UNIT); - }*/ + next_sample_evtime -= best_evtime; - for (i = 0; i < 4; i++) { - if (channel[i].evtime != CYCLE_MAX) - channel[i].evtime -= best_evtime; - } - n_cycles -= best_evtime; + /*if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul) { + if (sample_prehandler) + sample_prehandler (best_evtime / CYCLE_UNIT); + }*/ - if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul) { - if (rounded == best_evtime) { - next_sample_evtime += scaled_sample_evtime; - - this.sample_handler_def(); - //this.sample_handler_crux(); - //this.sample_handler_rh(); - } - } - - for (i = 0; i < 4; i++) { - if (channel[i].evtime == 0) { - channel[i].state_channel(true); - if (channel[i].evtime == 0) { - BUG.info('Audio.update() sound bug in channel %d (evtime == 0)', i); - channel[i].evtime = CYCLE_MAX; - } - } - } - } - last_cycles = AMIGA.events.currcycle - n_cycles; - } + for (i = 0; i < 4; i++) { + if (channel[i].evtime != CYCLE_MAX) + channel[i].evtime -= best_evtime; + } + n_cycles -= best_evtime; - this.update_adkmasks = function() { - var t = AMIGA.adkcon | (AMIGA.adkcon >> 4); + if (AMIGA.config.audio.mode != SAEV_Config_Audio_Mode_Emul) { + if (rounded == best_evtime) { + next_sample_evtime += scaled_sample_evtime; - channel[0].adk_mask = ((t >> 0) & 1) == 0 ? 0xffffffff : 0; - channel[1].adk_mask = ((t >> 1) & 1) == 0 ? 0xffffffff : 0; - channel[2].adk_mask = ((t >> 2) & 1) == 0 ? 0xffffffff : 0; - channel[3].adk_mask = ((t >> 3) & 1) == 0 ? 0xffffffff : 0; - channel[0].enabled = ((t >> 0) & 1) == 0; - channel[1].enabled = ((t >> 1) & 1) == 0; - channel[2].enabled = ((t >> 2) & 1) == 0; - channel[3].enabled = ((t >> 3) & 1) == 0; - - if ((prevcon & 0xff) != (AMIGA.adkcon & 0xff)) { - this.activate(); - prevcon = AMIGA.adkcon; - } - } + this.sample_handler_def(); + //this.sample_handler_crux(); + //this.sample_handler_rh(); + } + } - this.handler = function() { - this.update(); - this.schedule(); - } + for (i = 0; i < 4; i++) { + if (channel[i].evtime == 0) { + channel[i].state_channel(true); + if (channel[i].evtime == 0) { + BUG.info('Audio.update() sound bug in channel %d (evtime == 0)', i); + channel[i].evtime = CYCLE_MAX; + } + } + } + } + last_cycles = AMIGA.events.currcycle - n_cycles; + }; - this.hsync = function() { - if (work_to_do > 0) { - //work_to_do--; - if (--work_to_do == 0) - this.deactivate(); - } - this.update(); - } + this.update_adkmasks = function () { + var t = AMIGA.adkcon | (AMIGA.adkcon >> 4); + + channel[0].enabled = ((t >> 0) & 1) == 0; + channel[1].enabled = ((t >> 1) & 1) == 0; + channel[2].enabled = ((t >> 2) & 1) == 0; + channel[3].enabled = ((t >> 3) & 1) == 0; + + if ((prevcon & 0xff) != (AMIGA.adkcon & 0xff)) { + this.activate(); + prevcon = AMIGA.adkcon; + } + }; + + this.handler = function () { + this.update(); + this.schedule(); + }; + + this.hsync = function () { + if (work_to_do > 0) { + //work_to_do--; + if (--work_to_do == 0) + this.deactivate(); + } + this.update(); + }; - this.vsync = function() { } + this.vsync = function () { + }; /*---------------------------------*/ - this.AUDxDAT = function(nr, v) { - //BUG.info('AUD%dDAT %x', nr, v); - channel[nr].dat = v; - channel[nr].dat_written = true; - if (channel[nr].state == 2 || channel[nr].state == 3) { - var chan_ena = ((AMIGA.dmacon & DMAF_DMAEN) && (AMIGA.dmacon & (1 << nr))) ? true : false; - if (chan_ena) { - if (channel[nr].wlen == 1) { - channel[nr].wlen = channel[nr].len; - channel[nr].intreq = true; - } else { - //channel[nr].wlen = (channel[nr].wlen - 1) & 0xffff; - if ((--channel[nr].wlen) < 0) channel[nr].wlen = 0xffff; - } - } - } else { - this.activate(); - this.update(); - channel[nr].state_channel(false); - this.schedule(); - AMIGA.events.schedule(); - } - channel[nr].dat_written = false; - } + this.AUDxDAT = function (nr, v) { + //BUG.info('AUD%dDAT %x', nr, v); + channel[nr].dat = v; + channel[nr].dat_written = true; + if (channel[nr].state == 2 || channel[nr].state == 3) { + var chan_ena = ((AMIGA.dmacon & DMAF_DMAEN) && (AMIGA.dmacon & (1 << nr))) ? true : false; + if (chan_ena) { + if (channel[nr].wlen == 1) { + channel[nr].wlen = channel[nr].len; + channel[nr].intreq = true; + } else { + //channel[nr].wlen = (channel[nr].wlen - 1) & 0xffff; + if ((--channel[nr].wlen) < 0) channel[nr].wlen = 0xffff; + } + } + } else { + this.activate(); + this.update(); + channel[nr].state_channel(false); + this.schedule(); + AMIGA.events.schedule(); + } + channel[nr].dat_written = false; + }; - this.AUDxPER = function(nr, v) { - this.activate(); - this.update(); + this.AUDxPER = function (nr, v) { + this.activate(); + this.update(); - var per = v * CYCLE_UNIT; - if (per == 0) - per = PERIOD_MAX - 1; + var per = v * CYCLE_UNIT; + if (per == 0) + per = PERIOD_MAX - 1; - if (per < PERIOD_MIN * CYCLE_UNIT) - per = PERIOD_MIN * CYCLE_UNIT; - if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && channel[nr].dmaenstore) - per = PERIOD_MIN_NONCE * CYCLE_UNIT; + if (per < PERIOD_MIN * CYCLE_UNIT) + per = PERIOD_MIN * CYCLE_UNIT; + 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) { - channel[nr].evtime = CYCLE_UNIT; - if (AMIGA.config.audio.enabled) { - this.schedule(); - AMIGA.events.schedule(); - } - } - channel[nr].per = per; - //if (debugchannel(nr)) BUG.info('AUD%dPER() %x', nr, v); - } + if (channel[nr].per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) { + channel[nr].evtime = CYCLE_UNIT; + if (AMIGA.config.audio.enabled) { + this.schedule(); + AMIGA.events.schedule(); + } + } + channel[nr].per = per; + //if (debugchannel(nr)) BUG.info('AUD%dPER() %x', nr, v); + }; - this.AUDxLEN = function(nr, v) { - this.activate(); - this.update(); - channel[nr].len = v; - //if (debugchannel(nr)) BUG.info('AUD%dLEN() %x', nr, v); - } + this.AUDxLEN = function (nr, v) { + this.activate(); + this.update(); + channel[nr].len = v; + //if (debugchannel(nr)) BUG.info('AUD%dLEN() %x', nr, v); + }; - this.AUDxVOL = function(nr, v) { - v &= 127; - if (v > 64) v = 64; - this.activate(); - this.update(); - channel[nr].vol = v; - //if (debugchannel(nr)) BUG.info('AUD%dVOL() %x', nr, v); - } + this.AUDxVOL = function (nr, v) { + v &= 127; + if (v > 64) v = 64; + this.activate(); + this.update(); + channel[nr].vol = v; + //if (debugchannel(nr)) BUG.info('AUD%dVOL() %x', nr, v); + }; - this.AUDxLCH = function(nr, v) { - this.activate(); - this.update(); + this.AUDxLCH = function (nr, v) { + this.activate(); + this.update(); - if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum && ((channel[nr].ptx_tofetch && channel[nr].state == 1) || channel[nr].ptx_written)) { - channel[nr].ptx = channel[nr].lc; - channel[nr].ptx_written = true; - } else - channel[nr].lc = ((channel[nr].lc & 0xffff) | (v << 16)) >>> 0; - } + if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum && ((channel[nr].ptx_tofetch && channel[nr].state == 1) || channel[nr].ptx_written)) { + channel[nr].ptx = channel[nr].lc; + channel[nr].ptx_written = true; + } else + channel[nr].lc = ((channel[nr].lc & 0xffff) | (v << 16)) >>> 0; + }; - this.AUDxLCL = function(nr, v) { - this.activate(); - this.update(); + this.AUDxLCL = function (nr, v) { + this.activate(); + this.update(); - if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum && ((channel[nr].ptx_tofetch && channel[nr].state == 1) || channel[nr].ptx_written)) { - channel[nr].ptx = channel[nr].lc; - channel[nr].ptx_written = true; - } else - channel[nr].lc = ((channel[nr].lc & ~0xffff) | (v & 0xfffe)) >>> 0; - } + if (AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Maximum && ((channel[nr].ptx_tofetch && channel[nr].state == 1) || channel[nr].ptx_written)) { + channel[nr].ptx = channel[nr].lc; + channel[nr].ptx_written = true; + } else + channel[nr].lc = ((channel[nr].lc & ~0xffff) | (v & 0xfffe)) >>> 0; + }; /*---------------------------------*/ - this.getpt = function(nr, reset) { - var p = channel[nr].pt; - channel[nr].pt += 2; - if (reset) - channel[nr].pt = channel[nr].lc; - channel[nr].ptx_tofetch = false; - return p; - } + this.getpt = function (nr, reset) { + var p = channel[nr].pt; + channel[nr].pt += 2; + if (reset) + channel[nr].pt = channel[nr].lc; + channel[nr].ptx_tofetch = false; + return p; + }; - this.dmal = function() { - var dmal = 0; - for (var nr = 0; nr < 4; nr++) { - if (channel[nr].dr) - dmal |= (1 << (nr * 2)); - if (channel[nr].dsr) - dmal |= (1 << (nr * 2 + 1)); - channel[nr].dr = channel[nr].dsr = false; - } - //if (dmal) BUG.info('Audio.dmal() %d', dmal); - return dmal; - } + this.dmal = function () { + var dmal = 0; + for (var nr = 0; nr < 4; nr++) { + if (channel[nr].dr) + dmal |= (1 << (nr * 2)); + if (channel[nr].dsr) + dmal |= (1 << (nr * 2 + 1)); + channel[nr].dr = channel[nr].dsr = false; + } + //if (dmal) BUG.info('Audio.dmal() %d', dmal); + return dmal; + }; /*---------------------------------*/ const inv32768 = 1.0 / 32768; - this.sample_handler_def = function() { - var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; - var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; - var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; - var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; + this.sample_handler_def = function () { + var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; + var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; + var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; + var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; - data0 += data3; - data1 += data2; - data2 = data0 << 1; - data3 = data1 << 1; - if (AMIGA.config.audio.filter) { - data2 = this.filter.filter(data2, 0); - data3 = this.filter.filter(data3, 1); - } + data0 += data3; + data1 += data2; + data2 = data0 << 1; + data3 = data1 << 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) { - sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; - sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; - sampleBuffer.pos++; - } else - sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); - } else - BUG.info('Audio.sample_handler() audio buffer over-run!'); - } + if (sampleBuffer.pos < sampleBuffer.realSize) { + if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { + sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; + sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; + sampleBuffer.pos++; + } else + sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); + } else + BUG.info('Audio.sample_handler() audio buffer over-run!'); + }; - this.sample_handler_crux = function() { - var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; - var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; - var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; - var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; + this.sample_handler_crux = function () { + var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; + var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; + var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; + var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; - var data0p = channel[0].enabled ? (channel[0].last_sample * channel[0].vol) : 0; - var data1p = channel[1].enabled ? (channel[1].last_sample * channel[1].vol) : 0; - var data2p = channel[2].enabled ? (channel[2].last_sample * channel[2].vol) : 0; - var data3p = channel[3].enabled ? (channel[3].last_sample * channel[3].vol) : 0; + var data0p = channel[0].enabled ? (channel[0].last_sample * channel[0].vol) : 0; + var data1p = channel[1].enabled ? (channel[1].last_sample * channel[1].vol) : 0; + var data2p = channel[2].enabled ? (channel[2].last_sample * channel[2].vol) : 0; + var data3p = channel[3].enabled ? (channel[3].last_sample * channel[3].vol) : 0; - { - const INTERVAL = scaled_sample_evtime * 3; - var ratio, ratio1; + { + const INTERVAL = scaled_sample_evtime * 3; + var ratio, ratio1; - ratio1 = channel[0].per - channel[0].evtime; - ratio = Math.floor((ratio1 << 12) / INTERVAL); - if (channel[0].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) - ratio = 4096; - data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12; + ratio1 = channel[0].per - channel[0].evtime; + ratio = Math.floor((ratio1 << 12) / INTERVAL); + if (channel[0].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12; - ratio1 = channel[1].per - channel[1].evtime; - ratio = Math.floor((ratio1 << 12) / INTERVAL); - if (channel[1].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) - ratio = 4096; - data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12; + ratio1 = channel[1].per - channel[1].evtime; + ratio = Math.floor((ratio1 << 12) / INTERVAL); + if (channel[1].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12; - ratio1 = channel[2].per - channel[2].evtime; - ratio = Math.floor((ratio1 << 12) / INTERVAL); - if (channel[2].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) - ratio = 4096; - data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12; + ratio1 = channel[2].per - channel[2].evtime; + ratio = Math.floor((ratio1 << 12) / INTERVAL); + if (channel[2].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12; - ratio1 = channel[3].per - channel[3].evtime; - ratio = Math.floor((ratio1 << 12) / INTERVAL); - if (channel[3].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) - ratio = 4096; - data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12; - } - data0 += data3; - data1 += data2; - data2 = data0 << 1; - data3 = data1 << 1; - if (AMIGA.config.audio.filter) { - data2 = this.filter.filter(data2, 0); - data3 = this.filter.filter(data3, 1); - } + ratio1 = channel[3].per - channel[3].evtime; + ratio = Math.floor((ratio1 << 12) / INTERVAL); + if (channel[3].evtime < scaled_sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12; + } + data0 += data3; + data1 += data2; + data2 = data0 << 1; + data3 = data1 << 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) { - sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; - sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; - sampleBuffer.pos++; - } else - sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); - } else - BUG.info('Audio.sample_handler_crux() audio buffer over-run!'); - } + if (sampleBuffer.pos < sampleBuffer.realSize) { + if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { + sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; + sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; + sampleBuffer.pos++; + } else + sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); + } else + BUG.info('Audio.sample_handler_crux() audio buffer over-run!'); + }; - this.sample_handler_rh = function() { - var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; - var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; - var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; - var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; - var data0p = channel[0].enabled ? (channel[0].last_sample * channel[0].vol) : 0; - var data1p = channel[1].enabled ? (channel[1].last_sample * channel[1].vol) : 0; - var data2p = channel[2].enabled ? (channel[2].last_sample * channel[2].vol) : 0; - var data3p = channel[3].enabled ? (channel[3].last_sample * channel[3].vol) : 0; + this.sample_handler_rh = function () { + var data0 = channel[0].enabled ? (channel[0].current_sample * channel[0].vol) : 0; + var data1 = channel[1].enabled ? (channel[1].current_sample * channel[1].vol) : 0; + var data2 = channel[2].enabled ? (channel[2].current_sample * channel[2].vol) : 0; + var data3 = channel[3].enabled ? (channel[3].current_sample * channel[3].vol) : 0; + var data0p = channel[0].enabled ? (channel[0].last_sample * channel[0].vol) : 0; + var data1p = channel[1].enabled ? (channel[1].last_sample * channel[1].vol) : 0; + var data2p = channel[2].enabled ? (channel[2].last_sample * channel[2].vol) : 0; + var data3p = channel[3].enabled ? (channel[3].last_sample * channel[3].vol) : 0; - { - var delta, ratio; + { + var delta, ratio; - delta = channel[0].per; - ratio = Math.floor(((channel[0].evtime % delta) << 8) / delta); - data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8; - delta = channel[1].per; - ratio = Math.floor(((channel[1].evtime % delta) << 8) / delta); - data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8; - delta = channel[2].per; - ratio = Math.floor(((channel[2].evtime % delta) << 8) / delta); - data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8; - delta = channel[3].per; - ratio = Math.floor(((channel[3].evtime % delta) << 8) / delta); - data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8; - } + delta = channel[0].per; + ratio = Math.floor(((channel[0].evtime % delta) << 8) / delta); + data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8; + delta = channel[1].per; + ratio = Math.floor(((channel[1].evtime % delta) << 8) / delta); + data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8; + delta = channel[2].per; + ratio = Math.floor(((channel[2].evtime % delta) << 8) / delta); + data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8; + delta = channel[3].per; + ratio = Math.floor(((channel[3].evtime % delta) << 8) / delta); + data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8; + } - data2 = data0 << 1; - data3 = data1 << 1; - if (AMIGA.config.audio.filter) { - data2 = this.filter.filter(data2, 0); - data3 = this.filter.filter(data3, 1); - } + data2 = data0 << 1; + data3 = data1 << 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) { - sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; - sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; - sampleBuffer.pos++; - } else - sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); - } else - BUG.info('Audio.sample_handler_rh() audio buffer over-run!'); - } + if (sampleBuffer.pos < sampleBuffer.realSize) { + if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { + sampleBuffer.data[(sampleBuffer.pos << 1) ] = inv32768 * data2; + sampleBuffer.data[(sampleBuffer.pos << 1) + 1] = inv32768 * data3; + sampleBuffer.pos++; + } else + sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); + } else + BUG.info('Audio.sample_handler_rh() audio buffer over-run!'); + }; /*---------------------------------*/ @@ -1125,7 +1124,7 @@ function Audi0() { driver.ctx.mozWriteAudio(soundData); } - function mozHandler_full() { + /*function mozHandler_full() { var written; if (driver.moz.tail) { @@ -1149,5 +1148,5 @@ function Audi0() { } driver.moz.currentWritePosition += written; } - } + }*/ } diff --git a/sae/blitter.js b/sae/blitter.js index 0b39b76..9093ffb 100644 --- a/sae/blitter.js +++ b/sae/blitter.js @@ -52,8 +52,8 @@ function Blitter() { [0 ] /* F */ ]; const blit_cycle_diagram_line = [4, 0,3,5,4, 0,3,5,4]; - const blit_cycle_diagram_finald = [2, 0,4, 0,4]; - const blit_cycle_diagram_finalld = [2, 0,0, 0,0]; + //const blit_cycle_diagram_finald = [2, 0,4, 0,4]; + //const blit_cycle_diagram_finalld = [2, 0,0, 0,0]; var blit_filltable = []; var blit_masktable = []; @@ -84,8 +84,7 @@ function Blitter() { var blinea = 0, blineb = 0; var blitline = 0, blitfc = 0, blitfill = 0, blitife = 0, blitsing = 0, blitdesc = 0; var blitonedot = 0, blitsign = 0, blitlinepixel = 0; - - var ddat1 = 0, ddat2 = 0; + var ddat1use = 0, ddat2use = 0; var last_blitter_hpos = 0; @@ -101,7 +100,7 @@ function Blitter() { //function build_blitfilltable() { - var blit_masktable = new Uint16Array(BLITTER_MAX_WORDS); + blit_masktable = new Uint16Array(BLITTER_MAX_WORDS); for (var i = 0; i < BLITTER_MAX_WORDS; i++) blit_masktable[i] = 0xffff; @@ -130,18 +129,18 @@ function Blitter() { /*---------------------------------*/ - this.reset = function() { - bltstate = BLT_done; - blit_interrupt = true; - blit_stuck = 0; - } + this.reset = function () { + bltstate = BLT_done; + blit_interrupt = true; + blit_stuck = 0; + }; - function blitter_dump() { + /*function blitter_dump() { BUG.info('PT A=%08X B=%08X C=%08X D=%08X', bltapt, bltbpt, bltcpt, bltdpt); BUG.info('CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X', bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); //BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod, blt_info.bltbmod, blt_info.bltcmod, blt_info.bltdmod); - } + }*/ function castWord(v) { return (v & 0x8000) ? (v - 0x10000) : v; @@ -167,7 +166,7 @@ function Blitter() { return diag[1 + diag[0] + cycles]; } - function channel_pos(cycles) { + /*function channel_pos(cycles) { if (cycles < 0) return 0; var diag = get_ch(); @@ -176,7 +175,7 @@ function Blitter() { cycles -= diag[0]; cycles %= diag[0]; return cycles; - } + }*/ function blitter_interrupt() { if (blit_interrupt) @@ -2012,6 +2011,7 @@ function Blitter() { case 0xfd: return (~c) | (b) | (a); case 0xfe: return (c) | (b) | (a); case 0xff: return 0xffff; + default: return 0; } } @@ -2217,7 +2217,7 @@ function Blitter() { if (bltcon0 & 0x200) { if (AMIGA.dmaen(DMAF_BLTEN)) //blt_info.bltcdat = AMIGA.mem.load16_chip(bltcpt); - blt_info.bltcdat = dat = AMIGA.mem.chip.data[bltcpt >>> 1]; + blt_info.bltcdat = AMIGA.mem.chip.data[bltcpt >>> 1]; } bltstate = BLT_work; } @@ -2382,7 +2382,7 @@ function Blitter() { if (blt_info.vblitsize <= 0) bltstate = BLT_done; } while (bltstate != BLT_done); - bltapt_line = null; + //bltapt_line = null; bltdpt = bltcpt; } else { if (blitdesc) @@ -2400,26 +2400,26 @@ function Blitter() { /*---------------------------------*/ - this.handler = function(data) { - if (!AMIGA.dmaen(DMAF_BLTEN)) { - AMIGA.events.newevent(EV2_BLITTER, 10, 0); - if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate) - return; + this.handler = function (data) { + if (!AMIGA.dmaen(DMAF_BLTEN)) { + AMIGA.events.newevent(EV2_BLITTER, 10, 0); + if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate) + return; - BUG.info('blitter_handler() force-unstuck!'); - } - blit_stuck = 0; - if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) { - //console.log('Blitter.handler () slowdown', blit_slowdown); - AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0); - blit_slowdown = -1; - return; - } - blitter_do(); - } + BUG.info('blitter_handler() force-unstuck!'); + } + blit_stuck = 0; + if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) { + //console.log('Blitter.handler () slowdown', blit_slowdown); + AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0); + blit_slowdown = -1; + return; + } + blitter_do(); + }; var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0; - var freezes = 10; + //var freezes = 10; function blit_bltset(con) { if (con & 2) { blitdesc = bltcon1 & 2; @@ -2518,9 +2518,8 @@ function Blitter() { warned1--; BUG.info('waiting_blits detected'); } - if (bltstate == BLT_done) - return true; - return false; + return bltstate == BLT_done; + } function do_blitter(hpos, copper) { @@ -2533,17 +2532,12 @@ function Blitter() { cleanstart = 1; } - bltstate = BLT_done; - blt_info.blitzero = 1; - preva = 0; - prevb = 0; blt_info.got_cycle = 0; blit_firstline_cycles = blit_first_cycle = AMIGA.events.currcycle; blit_last_cycle = 0; last_blitter_hpos = hpos + 1; - blit_cyclecounter = 0; blit_bltset(1 | 2); ddat1use = ddat2use = 0; @@ -2615,164 +2609,228 @@ function Blitter() { } var warned2 = 10; - this.maybe_blit = function(hpos, hack) { - if (bltstate == BLT_done) - return; + this.maybe_blit = function (hpos, hack) { + if (bltstate == BLT_done) + return; - if (AMIGA.dmaen(DMAF_BLTEN)) { - var doit = false; - if (AMIGA.config.blitter.waiting == 3) { // always - doit = true; - } else if (AMIGA.config.blitter.waiting == 2) { // no idle - if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) - doit = true; - } else if (AMIGA.config.blitter.waiting == 1) { // automatic - if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) - doit = true; - else if (AMIGA.config.cpu.speed < 0) - doit = true; - } - if (doit) { - if (waitingblits()) - return; - } - } + if (AMIGA.dmaen(DMAF_BLTEN)) { + var doit = false; + if (AMIGA.config.blitter.waiting == 3) { // always + doit = true; + } else if (AMIGA.config.blitter.waiting == 2) { // no idle + if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) + doit = true; + } else if (AMIGA.config.blitter.waiting == 1) { // automatic + if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) + doit = true; + else if (AMIGA.config.cpu.speed < 0) + doit = true; + } + if (doit) { + if (waitingblits()) + return; + } + } - if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) { - warned2--; - BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter); - } + if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) { + warned2--; + BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter); + } - if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles) - return; + if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles) + return; - AMIGA.blitter.handler(0); - } + AMIGA.blitter.handler(0); + }; - this.blitnasty = function() { - if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN)) - return 0; - if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0]) - return 0; + this.blitnasty = function () { + if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN)) + return 0; + if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0]) + return 0; - var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV); - var ccnt = 0; - while (blit_last_cycle < cycles) { - if (!channel_state(blit_last_cycle++)) - ccnt++; - } - return ccnt; - } + var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV); + var ccnt = 0; + while (blit_last_cycle < cycles) { + if (!channel_state(blit_last_cycle++)) + ccnt++; + } + return ccnt; + }; /*---------------------------------*/ var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0; - this.slowdown = function() { - var data = AMIGA.playfield.getData(); - var ddfstrt = data[0]; - var ddfstop = data[1]; - var totalcycles = data[2]; - var freecycles = data[3]; + this.slowdown = function () { + var data = AMIGA.playfield.getData(); + var ddfstrt = data[0]; + var ddfstop = data[1]; + var totalcycles = data[2]; + var freecycles = data[3]; - if (!totalcycles || ddfstrt < 0 || ddfstop < 0) - return; - if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { - var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles); - var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles); - var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]); - - oddfstrt = ddfstrt; - oddfstop = ddfstop; - ototal = totalcycles; - ofree = freecycles; - slow = 0; - if (dmacycles > freelinecycles) - slow = dmacycles - freelinecycles; - } - if (blit_slowdown < 0 || blitline) - return; - - blit_slowdown += slow; - } + if (!totalcycles || ddfstrt < 0 || ddfstop < 0) + return; + if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { + var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles); + var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles); + var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]); + + oddfstrt = ddfstrt; + oddfstop = ddfstop; + ototal = totalcycles; + ofree = freecycles; + slow = 0; + if (dmacycles > freelinecycles) + slow = dmacycles - freelinecycles; + } + if (blit_slowdown < 0 || blitline) + return; + + blit_slowdown += slow; + }; /*---------------------------------*/ - this.BLTADAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltadat = v; } - this.BLTBDAT = function(hpos, v) { - this.maybe_blit(hpos, 0); - if (bltcon1 & 2) - blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff; - else - blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff; + this.BLTADAT = function (hpos, v) { + this.maybe_blit(hpos, 0); + blt_info.bltadat = v; + }; + this.BLTBDAT = function (hpos, v) { + this.maybe_blit(hpos, 0); + if (bltcon1 & 2) + blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff; + else + blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff; - blt_info.bltbdat = v; - } - this.BLTCDAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); } + blt_info.bltbdat = v; + }; + this.BLTCDAT = function (hpos, v) { + this.maybe_blit(hpos, 0); + blt_info.bltcdat = v; + reset_blit(0); + }; - this.BLTAMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltamod = castWord(v & 0xfffe); reset_blit(0); } - this.BLTBMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltbmod = castWord(v & 0xfffe); reset_blit(0); } - this.BLTCMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltcmod = castWord(v & 0xfffe); reset_blit(0); } - this.BLTDMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltdmod = castWord(v & 0xfffe); reset_blit(0); } + this.BLTAMOD = function (hpos, v) { + this.maybe_blit(hpos, 1); + blt_info.bltamod = castWord(v & 0xfffe); + reset_blit(0); + }; + this.BLTBMOD = function (hpos, v) { + this.maybe_blit(hpos, 1); + blt_info.bltbmod = castWord(v & 0xfffe); + reset_blit(0); + }; + this.BLTCMOD = function (hpos, v) { + this.maybe_blit(hpos, 1); + blt_info.bltcmod = castWord(v & 0xfffe); + reset_blit(0); + }; + this.BLTDMOD = function (hpos, v) { + this.maybe_blit(hpos, 1); + blt_info.bltdmod = castWord(v & 0xfffe); + reset_blit(0); + }; - this.BLTCON0 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); } - this.BLTCON0L = function( hpos, v) { - if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; - this.maybe_blit(hpos, 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); - reset_blit(1); - } - this.BLTCON1 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); } + this.BLTCON0 = function (hpos, v) { + this.maybe_blit(hpos, 2); + bltcon0 = v; + reset_blit(1); + }; + this.BLTCON0L = function (hpos, v) { + if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; + this.maybe_blit(hpos, 2); + bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); + reset_blit(1); + }; + this.BLTCON1 = function (hpos, v) { + this.maybe_blit(hpos, 2); + bltcon1 = v; + reset_blit(2); + }; - this.BLTAFWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltafwm = v; reset_blit(0); } - this.BLTALWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltalwm = v; reset_blit(0); } + this.BLTAFWM = function (hpos, v) { + this.maybe_blit(hpos, 2); + blt_info.bltafwm = v; + reset_blit(0); + }; + this.BLTALWM = function (hpos, v) { + this.maybe_blit(hpos, 2); + blt_info.bltalwm = v; + reset_blit(0); + }; - this.BLTAPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; } - this.BLTAPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; } - this.BLTBPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; } - this.BLTBPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; } - this.BLTCPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; } - this.BLTCPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; } - this.BLTDPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; } - this.BLTDPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0; } + this.BLTAPTH = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; + }; + this.BLTAPTL = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; + }; + this.BLTBPTH = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; + }; + this.BLTBPTL = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; + }; + this.BLTCPTH = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; + }; + this.BLTCPTL = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; + }; + this.BLTDPTH = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; + }; + this.BLTDPTL = function (hpos, v) { + this.maybe_blit(hpos, 0); + bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0; + }; - this.BLTSIZE = function(hpos, v) { - this.maybe_blit(hpos, 0); + this.BLTSIZE = function (hpos, v) { + this.maybe_blit(hpos, 0); - blt_info.vblitsize = v >> 6; - blt_info.hblitsize = v & 0x3F; - if (!blt_info.vblitsize) - blt_info.vblitsize = 1024; - if (!blt_info.hblitsize) - blt_info.hblitsize = 64; - - do_blitter(hpos, AMIGA.copper.access); - } + blt_info.vblitsize = v >> 6; + blt_info.hblitsize = v & 0x3F; + if (!blt_info.vblitsize) + blt_info.vblitsize = 1024; + if (!blt_info.hblitsize) + blt_info.hblitsize = 64; - this.BLTSIZV = function(hpos, v) { - if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; - this.maybe_blit(hpos, 0); - blt_info.vblitsize = v & 0x7FFF; - } + do_blitter(hpos, AMIGA.copper.access); + }; - this.BLTSIZH = function(hpos, v) { - if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; - this.maybe_blit(hpos, 0); - blt_info.hblitsize = v & 0x7FF; - if (!blt_info.vblitsize) - blt_info.vblitsize = 0x8000; - if (!blt_info.hblitsize) - blt_info.hblitsize = 0x0800; - - do_blitter(hpos, AMIGA.copper.access); - } + this.BLTSIZV = function (hpos, v) { + if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; + this.maybe_blit(hpos, 0); + blt_info.vblitsize = v & 0x7FFF; + }; + + this.BLTSIZH = function (hpos, v) { + if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; + this.maybe_blit(hpos, 0); + blt_info.hblitsize = v & 0x7FF; + if (!blt_info.vblitsize) + blt_info.vblitsize = 0x8000; + if (!blt_info.hblitsize) + blt_info.hblitsize = 0x0800; + + do_blitter(hpos, AMIGA.copper.access); + }; /*---------------------------------*/ - this.getState = function() { - return bltstate; - } - this.setState = function(s) { - bltstate = s; - } + this.getState = function () { + return bltstate; + }; + this.setState = function (s) { + bltstate = s; + }; this.getIntZero = function() { return [blit_interrupt, blt_info.blitzero]; } diff --git a/sae/cia.js b/sae/cia.js index d386eaf..63d1a98 100644 --- a/sae/cia.js +++ b/sae/cia.js @@ -11,13 +11,13 @@ * **************************************************************************/ -const CIAA_DEBUG_R = 0; +/*const CIAA_DEBUG_R = 0; const CIAA_DEBUG_W = 0; const CIAB_DEBUG_R = 0; const CIAB_DEBUG_W = 0; const DONGLE_DEBUG = 0; const KB_DEBUG = 0; -const CLOCK_DEBUG = 0; +const CLOCK_DEBUG = 0;*/ const TOD_HACK = 1; @@ -54,7 +54,7 @@ function CIA() { var div10 = 0; //var kbstate = 0, kblostsynccnt = 0, kbcode = 0; - var serbits = 0; + //var serbits = 0; var warned = 10; //var rtc_delayed_write = 0; @@ -101,23 +101,23 @@ function CIA() { } } - this.SetICRA = function(icr, sdr) { - ciaaicr |= icr; - ciaasdr = sdr; - RethinkICRA(); - } + this.SetICRA = function (icr, sdr) { + ciaaicr |= icr; + ciaasdr = sdr; + RethinkICRA(); + }; - this.SetICRB = function(icr, sdr) { - ciabicr |= icr; - if (sdr !== null) - ciabsdr = sdr; - RethinkICRB(); - } + this.SetICRB = function (icr, sdr) { + ciabicr |= icr; + if (sdr !== null) + ciabsdr = sdr; + RethinkICRB(); + }; - this.rethink = function() { - RethinkICRA(); - RethinkICRB(); - } + this.rethink = function () { + RethinkICRA(); + RethinkICRB(); + }; /* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */ function compute_passed_time() { @@ -343,10 +343,10 @@ function CIA() { AMIGA.events.schedule(); } - this.handler = function() { - CIA_update(); - CIA_calctimers(); - } + this.handler = function () { + CIA_update(); + CIA_calctimers(); + }; /*this.diskindex = function() { ciabicr |= 0x10; @@ -476,41 +476,41 @@ function CIA() { //this.hsync_prehandler = function() {} - this.hsync_posthandler = function(dotod) { - if (ciabtodon && dotod) { - ciabtod++; - ciabtod &= 0xFFFFFF; - ciab_checkalarm(1); - } - if (AMIGA.config.cia.tod_hack && ciaatodon) - do_tod_hack(dotod); + this.hsync_posthandler = function (dotod) { + if (ciabtodon && dotod) { + ciabtod++; + ciabtod &= 0xFFFFFF; + ciab_checkalarm(1); + } + if (AMIGA.config.cia.tod_hack && ciaatodon) + do_tod_hack(dotod); - /*if (resetwarning_phase) { - resetwarning_check (); - while (keys_available ()) - get_next_key (); - } else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) { - switch (kbstate) { - case 0: - kbcode = 0; - kbstate++; - break; - case 1: - setcode(AK_INIT_POWERUP); - kbstate++; - break; - case 2: - setcode(AK_TERM_POWERUP); - kbstate++; - break; - case 3: - kbcode = ~get_next_key(); - break; - } - keyreq(); - }*/ - AMIGA.input.keyboard.hsync(); - } + /*if (resetwarning_phase) { + resetwarning_check (); + while (keys_available ()) + get_next_key (); + } else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) { + switch (kbstate) { + case 0: + kbcode = 0; + kbstate++; + break; + case 1: + setcode(AK_INIT_POWERUP); + kbstate++; + break; + case 2: + setcode(AK_TERM_POWERUP); + kbstate++; + break; + case 3: + kbcode = ~get_next_key(); + break; + } + keyreq(); + }*/ + AMIGA.input.keyboard.hsync(); + }; function calc_led(old_led) { var c = AMIGA.events.currcycle; @@ -560,43 +560,43 @@ function CIA() { led_cycles_off = 0; } - this.vsync_prehandler = function() { - /*if (rtc_delayed_write < 0) { - rtc_delayed_write = 50; - } else if (rtc_delayed_write > 0) { - rtc_delayed_write--; - if (rtc_delayed_write == 0) - write_battclock (); - }*/ - led_vsync(); - this.handler(); - /*if (kblostsynccnt > 0) { - kblostsynccnt -= maxvpos; - if (kblostsynccnt <= 0) { - kblostsynccnt = 0; - keyreq (); - write_log (_T('lostsync\n')); - } - }*/ - AMIGA.input.keyboard.vsync(); - } + this.vsync_prehandler = function () { + /*if (rtc_delayed_write < 0) { + rtc_delayed_write = 50; + } else if (rtc_delayed_write > 0) { + rtc_delayed_write--; + if (rtc_delayed_write == 0) + write_battclock (); + }*/ + led_vsync(); + this.handler(); + /*if (kblostsynccnt > 0) { + kblostsynccnt -= maxvpos; + if (kblostsynccnt <= 0) { + kblostsynccnt = 0; + keyreq (); + write_log (_T('lostsync\n')); + } + }*/ + AMIGA.input.keyboard.vsync(); + }; - this.vsync_posthandler = function(dotod) { - //if (heartbeat_cnt > 0) heartbeat_cnt--; - if (TOD_HACK) { - if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1) - return; - } - if (ciaatodon && dotod) { - ciaatod++; - ciaatod &= 0xFFFFFF; - ciaa_checkalarm (1); - } - /*if (vpos == 0) { - write_log ('%d', vsync_counter); - this.dump(); - }*/ - } + this.vsync_posthandler = function (dotod) { + //if (heartbeat_cnt > 0) heartbeat_cnt--; + if (TOD_HACK) { + if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1) + return; + } + if (ciaatodon && dotod) { + ciaatod++; + ciaatod &= 0xFFFFFF; + ciaa_checkalarm(1); + } + /*if (vpos == 0) { + write_log ('%d', vsync_counter); + this.dump(); + }*/ + }; function bfe001_change() { var v = ciaapra; @@ -782,7 +782,7 @@ function CIA() { } return tmp; case 1: - if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0)); + //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0)); tmp = ciabprb; //tmp = dongle_cia_read(1, reg, tmp); if (ciabcrb & 2) { @@ -790,14 +790,14 @@ function CIA() { if (ciabcrb & 4) pb7 = ciabcrb & 1; tmp &= ~0x80; - tmp |= pb7 ? 0x80 : 00; + tmp |= pb7 ? 0x80 : 0; } if (ciabcra & 2) { var pb6 = 0; if (ciabcra & 4) pb6 = ciabcra & 1; tmp &= ~0x40; - tmp |= pb6 ? 0x40 : 00; + tmp |= pb6 ? 0x40 : 0; } return tmp; case 2: @@ -993,7 +993,7 @@ function CIA() { //if ((addr >= 8 && addr <= 10) || CIAB_DEBUG_W > 1) write_log (_T('W_CIAB: bfd%x00 %02X %08X\n'), reg, val, M68K_GETPC); switch (reg) { case 0: - if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0)); + //if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0)); //dongle_cia_write (1, reg, val); ciabpra = val; //if (currprefs.use_serial) @@ -1117,52 +1117,59 @@ function CIA() { } } - this.setup = function() {} + this.setup = function () { + }; - this.reset = function() { - if (TOD_HACK) { - tod_hack_tv = 0; - tod_hack_tod = 0; - tod_hack_enabled = 0; - if (AMIGA.config.cia.tod_hack) - tod_hack_enabled = TOD_HACK_TIME; - } - //kblostsynccnt = 0; - //serbits = 0; - //oldcd32mute = 1; - oldled = true; - //resetwarning_phase = resetwarning_timer = 0; - //heartbeat_cnt = 0; + this.reset = function () { + if (TOD_HACK) { + tod_hack_tv = 0; + tod_hack_tod = 0; + tod_hack_enabled = 0; + if (AMIGA.config.cia.tod_hack) + tod_hack_enabled = TOD_HACK_TIME; + } + //kblostsynccnt = 0; + //serbits = 0; + //oldcd32mute = 1; + oldled = true; + //resetwarning_phase = resetwarning_timer = 0; + //heartbeat_cnt = 0; - //oldovl = true; - //kbstate = 0; - ciaatlatch = ciabtlatch = 0; - ciaapra = 0; ciaadra = 0; - ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0; - ciaaicr = ciabicr = ciaaimask = ciabimask = 0; - ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */ - ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF; - ciaaalarm = ciabalarm = 0; - ciabpra = 0x8C; ciabdra = 0; - div10 = 0; - ciaasdr_cnt = 0; ciaasdr = 0; - ciabsdr_cnt = 0; ciabsdr = 0; - ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; - - CIA_calctimers(); - AMIGA.disk.select_set(ciabprb); + //oldovl = true; + //kbstate = 0; + ciaatlatch = ciabtlatch = 0; + ciaapra = 0; + ciaadra = 0; + ciaatod = ciabtod = 0; + ciaatodon = ciabtodon = 0; + ciaaicr = ciabicr = ciaaimask = ciabimask = 0; + ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; + /* outmode = toggle; */ + ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF; + ciaaalarm = ciabalarm = 0; + ciabpra = 0x8C; + ciabdra = 0; + div10 = 0; + ciaasdr_cnt = 0; + ciaasdr = 0; + ciabsdr_cnt = 0; + ciabsdr = 0; + ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; - //map_overlay (0); - - //if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */ - } + CIA_calctimers(); + AMIGA.disk.select_set(ciabprb); - this.dump = function() { - BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb); - BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV); - BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb); - BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV); - } + //map_overlay (0); + + //if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */ + }; + + this.dump = function () { + BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb); + BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV); + BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb); + BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV); + }; // Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected // Old Gary based Amigas enable both CIAs in this situation @@ -1203,115 +1210,117 @@ function CIA() { return mask == 0xe000 || mask == 0xd000; } - this.load8 = function(addr) { - var r = (addr & 0xf00) >> 8; - var v = 0xff; + this.load8 = function (addr) { + var r = (addr & 0xf00) >> 8; + var v = 0xff; - if (!isgaylenocia(addr)) - return v; + if (!isgaylenocia(addr)) + return v; - cia_wait_pre(); - switch ((addr >> 12) & 3) { - case 0: - if (!issinglecia()) - v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r); - break; - case 1: - v = (addr & 1) ? 0xff : ReadCIAB(r); - break; - case 2: - v = (addr & 1) ? ReadCIAA(r) : 0xff; - break; - case 3: { - //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8; - if (warned > 0) { - BUG.info('cia_bget: unknown CIA address %x', addr); - warned--; - } - break; - } - } - cia_wait_post(v); - return v; - } + cia_wait_pre(); + switch ((addr >> 12) & 3) { + case 0: + if (!issinglecia()) + v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r); + break; + case 1: + v = (addr & 1) ? 0xff : ReadCIAB(r); + break; + case 2: + v = (addr & 1) ? ReadCIAA(r) : 0xff; + break; + case 3: + { + //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8; + if (warned > 0) { + BUG.info('cia_bget: unknown CIA address %x', addr); + warned--; + } + break; + } + } + cia_wait_post(v); + return v; + }; - this.load16 = function(addr) { - var r = (addr & 0xf00) >> 8; - var v = 0xffff; + this.load16 = function (addr) { + var r = (addr & 0xf00) >> 8; + var v = 0xffff; - if (!isgaylenocia(addr)) - return v; + if (!isgaylenocia(addr)) + return v; - cia_wait_pre(); - switch ((addr >> 12) & 3) { - case 0: - if (!issinglecia()) - v = (ReadCIAB(r) << 8) | ReadCIAA(r); - break; - case 1: - v = (ReadCIAB(r) << 8) | 0xff; - break; - case 2: - v = (0xff << 8) | ReadCIAA(r); - break; - case 3: { - //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc; - if (warned > 0) { - BUG.info('cia_wget: unknown CIA address %x', addr); - warned--; - } - break; - } - } - cia_wait_post(v); - return v; - } + cia_wait_pre(); + switch ((addr >> 12) & 3) { + case 0: + if (!issinglecia()) + v = (ReadCIAB(r) << 8) | ReadCIAA(r); + break; + case 1: + v = (ReadCIAB(r) << 8) | 0xff; + break; + case 2: + v = (0xff << 8) | ReadCIAA(r); + break; + case 3: + { + //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc; + if (warned > 0) { + BUG.info('cia_wget: unknown CIA address %x', addr); + warned--; + } + break; + } + } + cia_wait_post(v); + return v; + }; - this.load32 = function(addr) { - var v = this.load16(addr) << 16; - v |= this.load16(addr + 2); - return v >>> 0; - } + this.load32 = function (addr) { + var v = this.load16(addr) << 16; + v |= this.load16(addr + 2); + return v >>> 0; + }; this.store8 = function (addr, value) { - var r = (addr & 0xf00) >> 8; + var r = (addr & 0xf00) >> 8; - if (!isgaylenocia(addr)) - return; + if (!isgaylenocia(addr)) + return; - cia_wait_pre(); - if (!issinglecia() || (addr & 0x3000) != 0) { - if ((addr & 0x2000) == 0) - WriteCIAB(r, value); - if ((addr & 0x1000) == 0) - WriteCIAA(r, value); - if (((addr & 0x3000) == 0x3000) && warned > 0) { - BUG.info('cia_bput: unknown CIA address %x %x', addr, value); - warned--; - } - } - cia_wait_post(value); - } + cia_wait_pre(); + if (!issinglecia() || (addr & 0x3000) != 0) { + if ((addr & 0x2000) == 0) + WriteCIAB(r, value); + if ((addr & 0x1000) == 0) + WriteCIAA(r, value); + if (((addr & 0x3000) == 0x3000) && warned > 0) { + BUG.info('cia_bput: unknown CIA address %x %x', addr, value); + warned--; + } + } + cia_wait_post(value); + }; this.store16 = function (addr, value) { - var r = (addr & 0xf00) >> 8; + var r = (addr & 0xf00) >> 8; - if (!isgaylenocia(addr)) - return; + if (!isgaylenocia(addr)) + return; - cia_wait_pre(); - if (!issinglecia() || (addr & 0x3000) != 0) { - if ((addr & 0x2000) == 0) - WriteCIAB(r, value >> 8); - if ((addr & 0x1000) == 0) - WriteCIAA(r, value & 0xff); - if (((addr & 0x3000) == 0x3000) && warned > 0) { - BUG.info('cia_wput: unknown CIA address %x %x', addr, value); - warned--; - } - } - cia_wait_post(value); - } + cia_wait_pre(); + if (!issinglecia() || (addr & 0x3000) != 0) { + if ((addr & 0x2000) == 0) + WriteCIAB(r, value >> 8); + if ((addr & 0x1000) == 0) + WriteCIAA(r, value & 0xff); + if (((addr & 0x3000) == 0x3000) && warned > 0) { + BUG.info('cia_wput: unknown CIA address %x %x', addr, value); + warned--; + } + } + cia_wait_post(value); + }; this.store32 = function (addr, value) { this.store16(addr, value >> 16); diff --git a/sae/config.js b/sae/config.js index 87deb45..df235b8 100644 --- a/sae/config.js +++ b/sae/config.js @@ -34,11 +34,11 @@ function Config() { size: 0 }, slow: { - size: 0, - }, + size: 0 + }, fast: { - size: 0, - } + size: 0 + } }; this.rom = { size: 0, @@ -177,7 +177,7 @@ function Config() { c.video.scanlines = 0 ? true : false; c.video.extrawidth = 0; c.video.xcenter = 0; - c.video.ycenter = 0 + c.video.ycenter = 0; c.audio.enabled = true; //c.audio.mode = SAEV_Config_Audio_Mode_Play_Best; @@ -203,11 +203,16 @@ function Config() { c.cia.tod = 0; c.cia.tod_hack = true; - c.hooks.error = function(err, msg) {} - c.hooks.power_led = function(on) {} - c.hooks.floppy_motor = function(unit, on) {} - c.hooks.floppy_step = function(unit, cyl) {} - c.hooks.fps = function(fps) {} + c.hooks.error = function (err, msg) { + }; + c.hooks.power_led = function (on) { + }; + c.hooks.floppy_motor = function (unit, on) { + }; + c.hooks.floppy_step = function (unit, cyl) { + }; + c.hooks.fps = function (fps) { + }; c.hooks.cpu = function(usage) {} } configSetDefaults(this); diff --git a/sae/constants.js b/sae/constants.js index 5e4407c..aa17c45 100644 --- a/sae/constants.js +++ b/sae/constants.js @@ -10,20 +10,14 @@ const SAEV_Version = 0; const SAEV_Revision = 8; -const SAEV_Revision_Sub = 0; - -/*-----------------------------------------------------------------------*/ - -const SAEV_Null = null; - -const SAEV_True = true; -const SAEV_False = false; +const SAEV_Revision_Sub = 1; /*-----------------------------------------------------------------------*/ /* info */ -const SAEI_Audio_Webkit = 1; -const SAEI_Audio_Mozilla = 2; +const SAEI_Audio_Default = 1; +const SAEI_Audio_Webkit = 2; +const SAEI_Audio_Mozilla = 4; const SAEI_Video_Canvas2D = 1; const SAEI_Video_WebGL = 2; @@ -83,7 +77,7 @@ const SAEV_Config_EXT_Size_None = 0; const SAEV_Config_EXT_Size_256K = 1; const SAEV_Config_EXT_Size_512K = 2; -const SAEV_Config_EXT_Addr_A0 = 1; +//const SAEV_Config_EXT_Addr_A0 = 1; const SAEV_Config_EXT_Addr_E0 = 2; const SAEV_Config_EXT_Addr_F0 = 3; @@ -138,7 +132,7 @@ const SAEV_Config_RTC_Type_RF5C01A = 2; /*-----------------------------------------------------------------------*/ /* erros */ -const SAEE_None = 0; +//const SAEE_None = 0; const SAEE_CPU_Internal = 1; const SAEE_CPU_68020_Required = 2; @@ -148,32 +142,25 @@ const SAEE_Disk_File_Too_Big = 3; const SAEE_Video_Shader_Error = 4; const SAEE_Video_ID_Not_Found = 5; const SAEE_Video_Canvas_Not_Supported = 6; -const SAEE_Video_WebGL_Not_Avail = 7; +//const SAEE_Video_WebGL_Not_Avail = 7; const SAEE_Audio_WebAudio_Not_Avail = 8; /*-----------------------------------------------------------------------*/ /* methods */ -const SAEM_Init = 1; +/*const SAEM_Init = 1; const SAEM_Start = 2; const SAEM_Stop = 3; const SAEM_Pause = 4; const SAEM_Reset = 5; const SAEM_Insert = 6; -const SAEM_Eject = 7; +const SAEM_Eject = 7;*/ /*-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------*/ -/* debug */ - -var BUG = null; - /*-----------------------------------------------------------------------*/ /* amiga */ -var AMIGA = null; - const ST_STOP = 0; const ST_CYCLE = 1; const ST_PAUSE = 2; @@ -251,8 +238,6 @@ const DMAF_BZERO = 1 << 13; const DMAF_BBUSY = 1 << 14; const DMAF_SETCLR = 1 << 15; -const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT; - /*-----------------------------------------------------------------------*/ /* blitter */ @@ -301,7 +286,7 @@ const EQU_ENDLINE_NTSC = 10; const CSMASK_ECS_AGNUS = 1; const CSMASK_ECS_DENISE = 2; const CSMASK_AGA = 4; -const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA); +//const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA); const CHIPSET_CLOCK_PAL = 3546895; const CHIPSET_CLOCK_NTSC = 3579545; @@ -338,7 +323,7 @@ const HARD_DDF_START = 0x18; const MAX_PLANES = 6; /* 8 = AGA */ const AMIGA_WIDTH_MAX = 752 / 2; -const AMIGA_HEIGHT_MAX = 574 / 2; +//const AMIGA_HEIGHT_MAX = 574 / 2; const DIW_DDF_OFFSET = 1; const HBLANK_OFFSET = 9; @@ -366,13 +351,13 @@ const COLOR_CHANGE_BRDBLANK = 0x80000000; const BPLCON_DENISE_DELAY = 1; -const SPRITE_DEBUG = 0; -const SPRITE_DEBUG_MINY = 0x0; -const SPRITE_DEBUG_MAXY = 0x100; -const SPR0_HPOS = 0x15; -const MAX_SPRITES = 8; +//const SPRITE_DEBUG = 0; +//const SPRITE_DEBUG_MINY = 0x0; +//const SPRITE_DEBUG_MAXY = 0x100; //const AUTOSCALE_SPRITES = 1; //const SPRBORDER = 0; +const SPR0_HPOS = 0x15; +const MAX_SPRITES = 8; const MAX_PIXELS_PER_LINE = 1760; @@ -382,8 +367,6 @@ const MAX_REG_CHANGE = ((MAXVPOS + 1) * 2 * MAXHPOS); const MAX_STOP = 30000; const NO_BLOCK = -3; -const FRAMES_UNTIL_RES_SWITCH = 1; - const MAX_WORDS_PER_LINE = 100; const DO_SPRITES = 1; diff --git a/sae/copper.js b/sae/copper.js index d2d630c..aaf226e 100644 --- a/sae/copper.js +++ b/sae/copper.js @@ -50,7 +50,7 @@ function Copper() { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]; this.cop1lc = 0; - this.cop2lc = 0, + this.cop2lc = 0; this.copcon = 0; this.enabled_thisline = false; this.access = false; @@ -73,68 +73,68 @@ function Copper() { }; this.reset = function () { - this.copcon = 0; - cop_state.state = COP_stop; - } + this.copcon = 0; + cop_state.state = COP_stop; + }; this.reset2 = function () { - cop_state.hpos = 0; - cop_state.last_write = 0; - this.compute_spcflag_copper(AMIGA.playfield.maxhpos); - } + cop_state.hpos = 0; + cop_state.last_write = 0; + this.compute_spcflag_copper(AMIGA.playfield.maxhpos); + }; this.COPCON = function (v) { - this.copcon = v; - } + this.copcon = v; + }; this.COP1LCH = function (v) { - this.cop1lc = ((v << 16) | (this.cop1lc & 0xffff)) >>> 0; - } + this.cop1lc = ((v << 16) | (this.cop1lc & 0xffff)) >>> 0; + }; this.COP1LCL = function (v) { - this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0; - } + this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0; + }; this.COP2LCH = function (v) { - this.cop2lc = ((v << 16) | (this.cop2lc & 0xffff)) >>> 0; - } + this.cop2lc = ((v << 16) | (this.cop2lc & 0xffff)) >>> 0; + }; this.COP2LCL = function (v) { - this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0; - } + this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0; + }; this.COPJMP = function (num, vblank) { - var oldstrobe = cop_state.strobe; + var oldstrobe = cop_state.strobe; - //if (AMIGA.dmaen(DMAF_COPEN) && (cop_state.saved_i1 != 0xffff || cop_state.saved_i2 != 0xfffe)) - //BUG.info('COPJMP(%d) vblank without copper ending %08x (%08x %08x) (%08x %08x)', num, cop_state.ip, this.cop1lc, this.cop2lc, cop_state.saved_i1, cop_state.saved_i2); + //if (AMIGA.dmaen(DMAF_COPEN) && (cop_state.saved_i1 != 0xffff || cop_state.saved_i2 != 0xfffe)) + //BUG.info('COPJMP(%d) vblank without copper ending %08x (%08x %08x) (%08x %08x)', num, cop_state.ip, this.cop1lc, this.cop2lc, cop_state.saved_i1, cop_state.saved_i2); - clr_special(SPCFLAG_COPPER); - cop_state.ignore_next = 0; - if (!oldstrobe) - cop_state.state_prev = cop_state.state; + clr_special(SPCFLAG_COPPER); + cop_state.ignore_next = 0; + if (!oldstrobe) + cop_state.state_prev = cop_state.state; - if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank) - cop_state.state = COP_strobe_delay1x; - else - cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra); + if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank) + cop_state.state = COP_strobe_delay1x; + else + cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra); - //BUG.info('COPJMP(%d) %d', num, cop_state.state); - - cop_state.vpos = AMIGA.playfield.vpos; - cop_state.hpos = AMIGA.playfield.hpos() & ~1; - cop_state.strobe = num; - this.enabled_thisline = false; - - if (0) { - this.immediate_copper(num); - return; - } + //BUG.info('COPJMP(%d) %d', num, cop_state.state); - if (AMIGA.dmaen(DMAF_COPEN)) - this.compute_spcflag_copper(AMIGA.playfield.hpos()); - else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) { - /* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */ - cop_state.state = COP_stop; - //BUG.info('COPJMP(%d) COP_stop'); - } - } + cop_state.vpos = AMIGA.playfield.vpos; + cop_state.hpos = AMIGA.playfield.hpos() & ~1; + cop_state.strobe = num; + this.enabled_thisline = false; + + if (0) { + this.immediate_copper(num); + return; + } + + if (AMIGA.dmaen(DMAF_COPEN)) + this.compute_spcflag_copper(AMIGA.playfield.hpos()); + else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) { + /* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */ + cop_state.state = COP_stop; + //BUG.info('COPJMP(%d) COP_stop'); + } + }; /*function get_copper_address(copno) { switch (copno) { @@ -146,440 +146,453 @@ function Copper() { }*/ this.test_copper_dangerous = function (address) { - var addr = address & 0x1fe; - if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) { - cop_state.state = COP_stop; - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - return true; - } - return false; - } + var addr = address & 0x1fe; + if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) { + cop_state.state = COP_stop; + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + return true; + } + return false; + }; this.immediate_copper = function (num) { - var pos = 0; - var oldpos = 0; + var pos = 0; + var oldpos = 0; - cop_state.state = COP_stop; - cop_state.vpos = AMIGA.playfield.vpos; - cop_state.hpos = AMIGA.playfield.hpos() & ~1; - cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc; + cop_state.state = COP_stop; + cop_state.vpos = AMIGA.playfield.vpos; + cop_state.hpos = AMIGA.playfield.hpos() & ~1; + cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc; - while (pos < (AMIGA.playfield.maxvpos << 5)) { - if (oldpos > pos) - pos = oldpos; - if (!AMIGA.dmaen(DMAF_COPEN)) - break; - if (cop_state.ip >= AMIGA.mem.chip.size) - break; - pos++; - oldpos = pos; - //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); - //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2); - cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1]; - cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1]; - AMIGA.custom.last_value = cop_state.i2; - cop_state.ip += 4; - if (!(cop_state.i1 & 1)) { // move - cop_state.i1 &= 0x1fe; - if (cop_state.i1 == 0x88) { - cop_state.ip = this.cop1lc; - continue; - } - if (cop_state.i1 == 0x8a) { - cop_state.ip = this.cop2lc; - continue; - } - if (this.test_copper_dangerous(cop_state.i1)) - break; - AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0); - } else { // wait or skip - if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff)) - pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3); - if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe) - break; - } - } - cop_state.state = COP_stop; - clr_special(SPCFLAG_COPPER); - } + while (pos < (AMIGA.playfield.maxvpos << 5)) { + if (oldpos > pos) + pos = oldpos; + if (!AMIGA.dmaen(DMAF_COPEN)) + break; + if (cop_state.ip >= AMIGA.mem.chip.size) + break; + pos++; + oldpos = pos; + //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); + //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2); + cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1]; + cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1]; + AMIGA.custom.last_value = cop_state.i2; + cop_state.ip += 4; + if (!(cop_state.i1 & 1)) { // move + cop_state.i1 &= 0x1fe; + if (cop_state.i1 == 0x88) { + cop_state.ip = this.cop1lc; + continue; + } + if (cop_state.i1 == 0x8a) { + cop_state.ip = this.cop2lc; + continue; + } + if (this.test_copper_dangerous(cop_state.i1)) + break; + AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0); + } else { // wait or skip + if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff)) + pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3); + if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe) + break; + } + } + cop_state.state = COP_stop; + clr_special(SPCFLAG_COPPER); + }; this.copper_cant_read = function (hpos, alloc) { - //BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos); - if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot - return 1; - if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) { - return -1; - } - return AMIGA.playfield.is_bitplane_dma(hpos); - } + //BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos); + if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot + return 1; + if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) { + return -1; + } + return AMIGA.playfield.is_bitplane_dma(hpos); + }; this.custom_store16_copper = function (hpos, addr, value, noget) { - //if (addr == 0x88 || addr == 0x8a) - //BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.playfield.vpos, AMIGA.playfield.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos); - //value = debug_wputpeekdma (0xdff000 + addr, value); - this.access = true; - var v = AMIGA.custom.store16_real(hpos, addr, value, noget); - this.access = false; - return v; - } + //if (addr == 0x88 || addr == 0x8a) + //BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.playfield.vpos, AMIGA.playfield.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos); + //value = debug_wputpeekdma (0xdff000 + addr, value); + this.access = true; + var v = AMIGA.custom.store16_real(hpos, addr, value, noget); + this.access = false; + return v; + }; this.dump_copper = function (error, until_hpos) { - BUG.info('\n'); - BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.playfield.vpos, until_hpos, AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80)); - BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2); - BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline?1:0); - BUG.info('\n'); - } + BUG.info('\n'); + BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.playfield.vpos, until_hpos, AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80)); + BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2); + BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline ? 1 : 0); + BUG.info('\n'); + }; this.update = function (until_hpos) { - var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); - var c_hpos = cop_state.hpos; + var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); + var c_hpos = cop_state.hpos; - //BUG.info('update() until_hpos %d, vp %d', until_hpos, vp); + //BUG.info('update() until_hpos %d, vp %d', until_hpos, vp); - if (cop_state.state == COP_wait && vp < cop_state.vcmp) { - this.dump_copper('error2', until_hpos); - this.enabled_thisline = false; - cop_state.state = COP_stop; - clr_special(SPCFLAG_COPPER); - return; - } + if (cop_state.state == COP_wait && vp < cop_state.vcmp) { + this.dump_copper('error2', until_hpos); + this.enabled_thisline = false; + cop_state.state = COP_stop; + clr_special(SPCFLAG_COPPER); + return; + } - if (until_hpos <= this.last_copper_hpos) - return; + if (until_hpos <= this.last_copper_hpos) + return; - if (until_hpos > (AMIGA.playfield.maxhpos & ~1)) - until_hpos = AMIGA.playfield.maxhpos & ~1; + if (until_hpos > (AMIGA.playfield.maxhpos & ~1)) + until_hpos = AMIGA.playfield.maxhpos & ~1; - for (;;) { - var old_hpos = c_hpos; - var hp; + for (; ;) { + var old_hpos = c_hpos; + var hp; - if (c_hpos >= until_hpos) - break; + if (c_hpos >= until_hpos) + break; - /* So we know about the fetch state. */ - AMIGA.playfield.decide_line(c_hpos); - AMIGA.playfield.decide_fetch(c_hpos); + /* So we know about the fetch state. */ + AMIGA.playfield.decide_line(c_hpos); + AMIGA.playfield.decide_fetch(c_hpos); - if (cop_state.movedelay > 0) { - cop_state.movedelay--; - if (cop_state.movedelay == 0) { - this.custom_store16_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0); - } - } + if (cop_state.movedelay > 0) { + cop_state.movedelay--; + if (cop_state.movedelay == 0) { + this.custom_store16_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 0); + } + } - if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1)) - c_hpos += 1; - else - c_hpos += 2; + if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1)) + c_hpos += 1; + else + c_hpos += 2; - switch (cop_state.state) { - case COP_wait_in2: { - if (this.copper_cant_read(old_hpos, 0)) - continue; - cop_state.state = COP_wait1; - break; - } - case COP_skip_in2: { - if (this.copper_cant_read(old_hpos, 0)) - continue; - cop_state.state = COP_skip1; - break; - } - case COP_strobe_extra: { - // Wait 1 copper cycle doing nothing - cop_state.state = COP_strobe_delay1; - break; - } - case COP_strobe_delay1: { - // First cycle after COPJMP is just like normal first read cycle - // Cycle is used and needs to be free. - if (this.copper_cant_read(old_hpos, 1)) - continue; - cop_state.state = COP_strobe_delay2; - cop_state.ip += 2; - break; - } - case COP_strobe_delay2: { - // Second cycle after COPJMP. This is the strange one. - // This cycle does not need to be free - // But it still gets allocated by copper if it is free = CPU and blitter can't use it. - cop_state.state = COP_read1; - // Next cycle finally reads from new pointer - if (cop_state.strobe == 1) - cop_state.ip = this.cop1lc; - else - cop_state.ip = this.cop2lc; - cop_state.strobe = 0; - break; - } - case COP_strobe_delay1x: { - // First cycle after COPJMP and Copper was waiting. This is the buggy one. - // Cycle can be free and copper won't allocate it. - // If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer.. - cop_state.state = COP_strobe_delay2x; - break; - } - case COP_strobe_delay2x: { - // Second cycle fetches following word and tosses it away. Must be free cycle - // but is not allocated, blitter or cpu can still use it. - if (this.copper_cant_read(old_hpos, 1)) - continue; - cop_state.state = COP_read1; - // Next cycle finally reads from new pointer - if (cop_state.strobe == 1) - cop_state.ip = this.cop1lc; - else - cop_state.ip = this.cop2lc; - cop_state.strobe = 0; - break; - } - case COP_start_delay: { - if (this.copper_cant_read(old_hpos, 1)) - continue; - cop_state.state = COP_read1; - cop_state.ip = this.cop1lc; - break; - } - case COP_read1: { - if (this.copper_cant_read(old_hpos, 1)) - continue; - /* workaround for a bug in kick 1.x */ - if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) { - //BUG.info('COP_read1() invalid addr $%08x', cop_state.ip); - cop_state.state = COP_stop; - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - return; - } - //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); - cop_state.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1]; - cop_state.ip += 2; - cop_state.state = COP_read2; - break; - } - case COP_read2: { - if (this.copper_cant_read(old_hpos, 1)) - continue; - //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip); - cop_state.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1]; - cop_state.ip += 2; - cop_state.saved_i1 = cop_state.i1; - cop_state.saved_i2 = cop_state.i2; - cop_state.saved_ip = cop_state.ip; + switch (cop_state.state) { + case COP_wait_in2: + { + if (this.copper_cant_read(old_hpos, 0)) + continue; + cop_state.state = COP_wait1; + break; + } + case COP_skip_in2: + { + if (this.copper_cant_read(old_hpos, 0)) + continue; + cop_state.state = COP_skip1; + break; + } + case COP_strobe_extra: + { + // Wait 1 copper cycle doing nothing + cop_state.state = COP_strobe_delay1; + break; + } + case COP_strobe_delay1: + { + // First cycle after COPJMP is just like normal first read cycle + // Cycle is used and needs to be free. + if (this.copper_cant_read(old_hpos, 1)) + continue; + cop_state.state = COP_strobe_delay2; + cop_state.ip += 2; + break; + } + case COP_strobe_delay2: + { + // Second cycle after COPJMP. This is the strange one. + // This cycle does not need to be free + // But it still gets allocated by copper if it is free = CPU and blitter can't use it. + cop_state.state = COP_read1; + // Next cycle finally reads from new pointer + if (cop_state.strobe == 1) + cop_state.ip = this.cop1lc; + else + cop_state.ip = this.cop2lc; + cop_state.strobe = 0; + break; + } + case COP_strobe_delay1x: + { + // First cycle after COPJMP and Copper was waiting. This is the buggy one. + // Cycle can be free and copper won't allocate it. + // If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer.. + cop_state.state = COP_strobe_delay2x; + break; + } + case COP_strobe_delay2x: + { + // Second cycle fetches following word and tosses it away. Must be free cycle + // but is not allocated, blitter or cpu can still use it. + if (this.copper_cant_read(old_hpos, 1)) + continue; + cop_state.state = COP_read1; + // Next cycle finally reads from new pointer + if (cop_state.strobe == 1) + cop_state.ip = this.cop1lc; + else + cop_state.ip = this.cop2lc; + cop_state.strobe = 0; + break; + } + case COP_start_delay: + { + if (this.copper_cant_read(old_hpos, 1)) + continue; + cop_state.state = COP_read1; + cop_state.ip = this.cop1lc; + break; + } + case COP_read1: + { + if (this.copper_cant_read(old_hpos, 1)) + continue; + /* workaround for a bug in kick 1.x */ + if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) { + //BUG.info('COP_read1() invalid addr $%08x', cop_state.ip); + cop_state.state = COP_stop; + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + return; + } + //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); + cop_state.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1]; + cop_state.ip += 2; + cop_state.state = COP_read2; + break; + } + case COP_read2: + { + if (this.copper_cant_read(old_hpos, 1)) + continue; + //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip); + cop_state.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1]; + cop_state.ip += 2; + cop_state.saved_i1 = cop_state.i1; + cop_state.saved_i2 = cop_state.i2; + cop_state.saved_ip = cop_state.ip; - if (cop_state.i1 & 1) { // WAIT or SKIP - cop_state.ignore_next = 0; - if (cop_state.i2 & 1) - cop_state.state = COP_skip_in2; - else - cop_state.state = COP_wait_in2; - } else { // MOVE - //uaecptr debugip = cop_state.ip; - var reg = cop_state.i1 & 0x1fe; - var data = cop_state.i2; - cop_state.state = COP_read1; - this.test_copper_dangerous(reg); - if (!this.enabled_thisline) { - //goto out; // was 'dangerous' register -> copper stopped - cop_state.hpos = c_hpos; - this.last_copper_hpos = until_hpos; - return; - } - if (cop_state.ignore_next) - reg = 0x1fe; + if (cop_state.i1 & 1) { // WAIT or SKIP + cop_state.ignore_next = 0; + if (cop_state.i2 & 1) + cop_state.state = COP_skip_in2; + else + cop_state.state = COP_wait_in2; + } else { // MOVE + //uaecptr debugip = cop_state.ip; + var reg = cop_state.i1 & 0x1fe; + var data = cop_state.i2; + cop_state.state = COP_read1; + this.test_copper_dangerous(reg); + if (!this.enabled_thisline) { + //goto out; // was 'dangerous' register -> copper stopped + cop_state.hpos = c_hpos; + this.last_copper_hpos = until_hpos; + return; + } + if (cop_state.ignore_next) + reg = 0x1fe; - cop_state.last_write = reg; - cop_state.last_write_hpos = old_hpos; - if (reg == 0x88) { - cop_state.strobe = 1; - cop_state.state = COP_strobe_delay1; - } else if (reg == 0x8a) { - cop_state.strobe = 2; - cop_state.state = COP_strobe_delay1; - } else { - /*if (0) { - AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write); - AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0); - }); - //this.custom_store16_copper(old_hpos, reg, data, 0); - } else*/ - { - // FIX: all copper writes happen 1 cycle later than CPU writes - if (customdelay[reg >> 1]) { - cop_state.moveaddr = reg; - cop_state.movedata = data; - cop_state.movedelay = customdelay[cop_state.moveaddr >> 1]; - } else { - var hpos2 = old_hpos; - this.custom_store16_copper(hpos2, reg, data, 0); - hpos2++; - if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) - AMIGA.playfield.do_sprites(hpos2); - } - } - } - cop_state.ignore_next = 0; - } - break; - } - case COP_wait1: { -/*#if 0 - if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break; -#endif*/ - cop_state.state = COP_wait; + cop_state.last_write = reg; + cop_state.last_write_hpos = old_hpos; + if (reg == 0x88) { + cop_state.strobe = 1; + cop_state.state = COP_strobe_delay1; + } else if (reg == 0x8a) { + cop_state.strobe = 2; + cop_state.state = COP_strobe_delay1; + } else { + /*if (0) { + AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write); + AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0); + }); + //this.custom_store16_copper(old_hpos, reg, data, 0); + } else*/ + { + // FIX: all copper writes happen 1 cycle later than CPU writes + if (customdelay[reg >> 1]) { + cop_state.moveaddr = reg; + cop_state.movedata = data; + cop_state.movedelay = customdelay[cop_state.moveaddr >> 1]; + } else { + var hpos2 = old_hpos; + this.custom_store16_copper(hpos2, reg, data, 0); + hpos2++; + if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) + AMIGA.playfield.do_sprites(hpos2); + } + } + } + cop_state.ignore_next = 0; + } + break; + } + case COP_wait1: + { + /*#if 0 + if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break; + #endif*/ + cop_state.state = COP_wait; - cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; - cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); + cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); - vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); + vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); - if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) { - cop_state.state = COP_waitforever; - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - //goto out; - cop_state.hpos = c_hpos; - this.last_copper_hpos = until_hpos; - return; - } - if (vp < cop_state.vcmp) { - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - //goto out; - cop_state.hpos = c_hpos; - this.last_copper_hpos = until_hpos; - return; - } - } - /* fall through */ - case COP_wait: { - var ch_comp = c_hpos; - if (ch_comp & 1) - ch_comp = 0; + if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) { + cop_state.state = COP_waitforever; + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + //goto out; + cop_state.hpos = c_hpos; + this.last_copper_hpos = until_hpos; + return; + } + if (vp < cop_state.vcmp) { + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + //goto out; + cop_state.hpos = c_hpos; + this.last_copper_hpos = until_hpos; + return; + } + } + /* fall through */ + case COP_wait: + { + var ch_comp = c_hpos; + if (ch_comp & 1) + ch_comp = 0; - if (this.copper_cant_read(old_hpos, 0)) - continue; + if (this.copper_cant_read(old_hpos, 0)) + continue; - hp = ch_comp & (cop_state.saved_i2 & 0xfe); - if (vp == cop_state.vcmp && hp < cop_state.hcmp) - break; + hp = ch_comp & (cop_state.saved_i2 & 0xfe); + if (vp == cop_state.vcmp && hp < cop_state.hcmp) + break; - /* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */ - if ((cop_state.saved_i2 & 0x8000) == 0) { - if (AMIGA.blitter.getState() != BLT_done) { - //We need to wait for the blitter. - cop_state.state = COP_bltwait; - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - //goto out; - cop_state.hpos = c_hpos; - this.last_copper_hpos = until_hpos; - return; - } - } - cop_state.state = COP_read1; - break; - } - case COP_skip1: { - var vcmp, hcmp, vp1, hp1; + /* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */ + if ((cop_state.saved_i2 & 0x8000) == 0) { + if (AMIGA.blitter.getState() != BLT_done) { + //We need to wait for the blitter. + cop_state.state = COP_bltwait; + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + //goto out; + cop_state.hpos = c_hpos; + this.last_copper_hpos = until_hpos; + return; + } + } + cop_state.state = COP_read1; + break; + } + case COP_skip1: + { + var vcmp, hcmp, vp1, hp1; - if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) - break; + if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) + break; - if (this.copper_cant_read(old_hpos, 0)) - continue; + if (this.copper_cant_read(old_hpos, 0)) + continue; - vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; - hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); - vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); - hp1 = c_hpos & (cop_state.saved_i2 & 0xfe); + vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); + vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); + hp1 = c_hpos & (cop_state.saved_i2 & 0xfe); - if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done)) - cop_state.ignore_next = 1; + if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done)) + cop_state.ignore_next = 1; - cop_state.state = COP_read1; - break; - } - } - } + cop_state.state = COP_read1; + break; + } + } + } - //out: - cop_state.hpos = c_hpos; - this.last_copper_hpos = until_hpos; - } + //out: + cop_state.hpos = c_hpos; + this.last_copper_hpos = until_hpos; + }; this.compute_spcflag_copper = function (hpos) { - //BUG.info('compute_spcflag_copper() hpos %d', hpos); - var wasenabled = this.enabled_thisline; + //BUG.info('compute_spcflag_copper() hpos %d', hpos); + var wasenabled = this.enabled_thisline; - this.enabled_thisline = false; - clr_special(SPCFLAG_COPPER); - if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait) - return; + this.enabled_thisline = false; + clr_special(SPCFLAG_COPPER); + if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait) + return; - if (cop_state.state == COP_wait) { - var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); + if (cop_state.state == COP_wait) { + var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); - if (vp < cop_state.vcmp) - return; - } - // do not use past cycles if starting for the first time in this line - // (write to DMACON for example) hpos+1 for long lines - if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) { - hpos = (hpos + 2) & ~1; - if (hpos > AMIGA.playfield.maxhpos_short) - hpos = AMIGA.playfield.maxhpos_short; - cop_state.hpos = hpos; - //BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short); - } + if (vp < cop_state.vcmp) + return; + } + // do not use past cycles if starting for the first time in this line + // (write to DMACON for example) hpos+1 for long lines + if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) { + hpos = (hpos + 2) & ~1; + if (hpos > AMIGA.playfield.maxhpos_short) + hpos = AMIGA.playfield.maxhpos_short; + cop_state.hpos = hpos; + //BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short); + } - // if COPJMPx was written while DMA was disabled, advance to next state, - // COP_strobe_extra is single cycle only and does not need free bus. - // (copper state emulation does not run if DMA is disabled) - if (!wasenabled && cop_state.state == COP_strobe_extra) - cop_state.state = COP_strobe_delay1; + // if COPJMPx was written while DMA was disabled, advance to next state, + // COP_strobe_extra is single cycle only and does not need free bus. + // (copper state emulation does not run if DMA is disabled) + if (!wasenabled && cop_state.state == COP_strobe_extra) + cop_state.state = COP_strobe_delay1; - this.enabled_thisline = true; - set_special(SPCFLAG_COPPER); - } + this.enabled_thisline = true; + set_special(SPCFLAG_COPPER); + }; this.blitter_done_notify = function (hpos) { - if (cop_state.state != COP_bltwait) - return; + if (cop_state.state != COP_bltwait) + return; - //BUG.info('blitter_done_notify() hpos %d', hpos); + //BUG.info('blitter_done_notify() hpos %d', hpos); - var vp = AMIGA.playfield.vpos; - hpos += 3; - hpos &= ~1; - if (hpos >= AMIGA.playfield.maxhpos) { - hpos -= AMIGA.playfield.maxhpos; - vp++; - } - cop_state.hpos = hpos; - cop_state.vpos = vp; - cop_state.state = COP_read1; + var vp = AMIGA.playfield.vpos; + hpos += 3; + hpos &= ~1; + if (hpos >= AMIGA.playfield.maxhpos) { + hpos -= AMIGA.playfield.maxhpos; + vp++; + } + cop_state.hpos = hpos; + cop_state.vpos = vp; + cop_state.state = COP_read1; - if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) { - this.enabled_thisline = true; - set_special(SPCFLAG_COPPER); - } - } + if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) { + this.enabled_thisline = true; + set_special(SPCFLAG_COPPER); + } + }; this.cycle = function () { - this.update(AMIGA.playfield.hpos()); - } + this.update(AMIGA.playfield.hpos()); + }; this.sync_copper_with_cpu = function (hpos, do_schedule) { - /* Need to let the copper advance to the current position. */ - if (this.enabled_thisline) - this.update(hpos); - } + /* Need to let the copper advance to the current position. */ + if (this.enabled_thisline) + this.update(hpos); + }; - this.check = function (n) { + /*this.check = function (n) { if (cop_state.state == COP_wait) { var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); if (vp < cop_state.vcmp) { @@ -587,5 +600,5 @@ function Copper() { BUG.info('COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d', n, vp, AMIGA.playfield.vpos, cop_state.vcmp, this.enabled_thisline?1:0); } } - } + }*/ } \ No newline at end of file diff --git a/sae/cpu.js b/sae/cpu.js index 30a58cf..456b9ae 100644 --- a/sae/cpu.js +++ b/sae/cpu.js @@ -40,7 +40,7 @@ function CPU() { const ccNames = ['T', 'F', 'HI', 'LS', 'CC', 'CS', 'NE', 'EQ', 'VC', 'VS', 'PL', 'MI', 'GE', 'LT', 'GT', 'LE']; /* Effective Address */ - function effAddr(m, r) { + function EffAddr(m, r) { this.m = m; /* Mode M_ */ this.t = 0; /* Type T_ */ this.r = r; /* Register An/Dn */ @@ -49,31 +49,31 @@ function CPU() { } /* Instruction Condition */ - function iCon(cc, dp, dr) { + function ICon(cc, dp, dr) { this.cc = cc; /* Condition Code */ this.dp = dp; /* Displacement */ this.dr = dr; /* Data Register for DBcc */ } /* Instruction Paramenter */ - function iPar() { - this.z; /* size B,W,L */ + function IPar() { + this.z = 0; /* size B,W,L */ /* Filled on demand - this.s = new effAddr(); - this.d = new effAddr(); - this.c = new iCon(); + this.s = new EffAddr(); + this.d = new EffAddr(); + this.c = new ICon(); this.ms = 0; this.mz = 0; this.cyc = 0;*/ } /* Instruction Definition */ - function iDef() { - this.op; /* OP-code */ - this.pr; /* Privileged */ - this.mn; /* Mnemonic */ - this.f; /* Function */ - this.p = new iPar(); + function IDef() { + this.op = 0; /* OP-code */ + //this.pr = false; /* Privileged */ + this.mn = ''; /* Mnemonic */ + this.f = null; /* Function */ + this.p = new IPar(); } /* Exception 2/3 error */ @@ -118,31 +118,31 @@ function CPU() { /*-----------------------------------------------------------------------*/ - this.setup = function() { - if (iTab === null) { - BUG.say('cpu.setup() no instruction table, generating...'); - if (!mkiTab()) - Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table'); - } else - BUG.say('cpu.setup() instruction table is cached'); - } + this.setup = function () { + if (iTab === null) { + BUG.say('cpu.setup() no instruction table, generating...'); + if (!mkiTab()) + Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table'); + } else + BUG.say('cpu.setup() instruction table is cached'); + }; this.reset = function (addr) { - for (var i = 0; i < 8; i++) - regs.d[i] = regs.a[i] = 0; + for (var i = 0; i < 8; i++) + regs.d[i] = regs.a[i] = 0; - regs.t = false; - regs.s = true; - regs.intmask = 7; - regs.x = regs.n = regs.z = regs.v = regs.c = false; - regs.usp = 0; - regs.isp = 0; - regs.a[7] = AMIGA.mem.load32(addr); - regs.pc = AMIGA.mem.load32(addr + 4); - regs.stopped = false; + regs.t = false; + regs.s = true; + regs.intmask = 7; + regs.x = regs.n = regs.z = regs.v = regs.c = false; + regs.usp = 0; + regs.isp = 0; + regs.a[7] = AMIGA.mem.load32(addr); + regs.pc = AMIGA.mem.load32(addr + 4); + regs.stopped = false; - BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc)); - } + BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc)); + }; /*-----------------------------------------------------------------------*/ @@ -154,6 +154,7 @@ function CPU() { case 4: return 'L'; default: Fatal(SAEE_CPU_Internal, 'cpu.szChr() invalid size'); + return ''; } } @@ -203,6 +204,7 @@ function CPU() { case 4: return r > 0xffffffff ? r - 0x100000000 : r; default: Fatal(SAEE_CPU_Internal, 'cpu.addAuto() invalid size'); + return 0; } } function sub32(a, b) { @@ -217,6 +219,7 @@ function CPU() { case 4: return r < 0 ? r + 0x100000000 : r; default: Fatal(SAEE_CPU_Internal, 'cpu.subAuto() invalid size'); + return 0; } } @@ -241,9 +244,10 @@ function CPU() { //var scale = 1 << ((ext & 0x600) >> 9); if (scale != 1) alert('exII() scale '+scale); function exII(base) { var ext = nextIWord(); - if (ext & 0x100) - Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)'); - else { + if (ext & 0x100) { + Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)'); + return 0; + } else { var disp = extByte(ext & 0xff); var r = (ext & 0x7000) >> 12; var reg = (ext & 0x8000) ? regs.a[r] : regs.d[r]; @@ -394,6 +398,7 @@ function CPU() { case 4: return regs.d[ea.a]; default: Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RD invalid size'); + return 0; } } case T_RA: { @@ -402,6 +407,7 @@ function CPU() { case 4: return regs.a[ea.a]; default: Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RA invalid size'); + return 0; } } case T_AD: { @@ -427,12 +433,14 @@ function CPU() { case 4: return AMIGA.mem.load32(ea.a); default: Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_AD invalid size'); + return 0; } } case T_IM: return ea.a; default: Fatal(SAEE_CPU_Internal, 'cpu.ldEA() invalid type (' + ea.t + ')'); + return 0; } } @@ -501,6 +509,7 @@ function CPU() { case 15: return regs.z || (regs.n != regs.v); //LE default: Fatal(SAEE_CPU_Internal, 'cpu.ccTrue() invalid condition code (' + cc + ')'); + return false; } } @@ -698,7 +707,7 @@ function CPU() { function I_PEA(p) { var sea = exEA(p.s, p.z); - var dea = exEA(new effAddr(M_ripr, 7), p.z); + var dea = exEA(new EffAddr(M_ripr, 7), p.z); stEA(dea, p.z, sea.a); //ccna return p.cyc; @@ -710,7 +719,7 @@ function CPU() { var dea = exEA(p.d, p.z); var dp = ldEA(dea, p.z); if (p.z == 2) dp = extWord(dp); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.a[An]); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.a[An]); regs.a[An] = regs.a[7]; regs.a[7] = add32(regs.a[7], dp); //ccna @@ -726,7 +735,7 @@ function CPU() { var sea = exEA(p.s, p.z); var An = sea.a; regs.a[7] = regs.a[An]; - regs.a[An] = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4); + regs.a[An] = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4); //ccna //BUG.say(sprintf('I_UNLK.%s A%d', szChr(p.z), An)); return p.cyc; @@ -987,7 +996,7 @@ function CPU() { function I_CLR(p) { var dea = exEA(p.d, p.z); - var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */ + //var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */ stEA(dea, p.z, 0); regs.n = false; @@ -1812,7 +1821,7 @@ function CPU() { var cyc; if (!ccTrue(cc)) { - var ea = exEA(new effAddr(M_rdd, p.c.dr), p.z); + var ea = exEA(new EffAddr(M_rdd, p.c.dr), p.z); var dr = ldEA(ea, p.z); if (dr--) { @@ -1833,7 +1842,7 @@ function CPU() { //var cc = p.s.r; var cc = p.c.cc; var dea = exEA(p.d, p.z); - var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */ + //var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */ var isTrue = ccTrue(cc); stEA(dea, p.z, isTrue ? 0xff : 0); //ccna @@ -1868,7 +1877,7 @@ function CPU() { //else if (dp == 255) Fatal(SAEE_CPU_68020_Required, 'cpu.I_BSR() Full extension index detected (not a 68000 programm)'); else pc = add32(regs.pc, extByte(dp)); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc); setPC(pc); //ccna return p.cycTaken; @@ -1884,7 +1893,7 @@ function CPU() { function I_JSR(p) { var dea = exEA(p.d, p.z); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc); setPC(dea.a); //ccna //BUG.say(sprintf('I_JSR $%08x', dea.a)); @@ -1892,8 +1901,8 @@ function CPU() { } function I_RTR(p) { - var ccr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2) & 0xff; - var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4); + var ccr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2) & 0xff; + var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4); setCCR(ccr); setPC(pc); //BUG.say(sprintf('I_RTR crr $%04x pc $%08x', crr, pc)); @@ -1901,7 +1910,7 @@ function CPU() { } function I_RTS(p) { - var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4); + var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4); //BUG.say(sprintf('I_RTS() regs.pc $%08x newpc $%08x', regs.pc, pc)); setPC(pc); //ccna @@ -2039,7 +2048,7 @@ function CPU() { function I_MOVE_SR2(p) { var sr = getSR(); var dea = exEA(p.d, p.z); - var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */ + //var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */ stEA(dea, p.z, sr); //ccna //BUG.say(sprintf('I_MOVE_SR2.%s sr $%04x', szChr(p.z), sr)); @@ -2144,8 +2153,8 @@ function CPU() { function I_RTE(p) { if (regs.s) { - var sr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2); - var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4); + var sr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2); + var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4); setSR(sr); //BUG.say(sprintf('I_RTE sr $%04x newpc $%08x oldpc $%08x', sr, pc, regs.pc)); setPC(pc); @@ -2239,11 +2248,12 @@ function CPU() { case M_absl: return z == 4 ? [16,4,0] : [12,3,0]; case M_imm: case M_list: return z == 4 ? [ 8,2,0] : [ 4,1,0]; - } + default: return [0,0,0]; + } } function mkN(op, mn, cyc) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; @@ -2254,14 +2264,14 @@ function CPU() { } function mkS(op, mn, z, s, r, cyc, add) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; i.f = null; i.p = {}; i.p.z = z; - i.p.s = new effAddr(s, r); + i.p.s = new EffAddr(s, r); i.p.s.c = mkCyc(z, s); i.p.cyc = cyc; if (add) i.p.cyc[0] += i.p.s.c[0]; @@ -2271,14 +2281,14 @@ function CPU() { } function mkD(op, mn, z, d, r, cyc, add) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; i.f = null; i.p = {}; i.p.z = z; - i.p.d = new effAddr(d, r); + i.p.d = new EffAddr(d, r); i.p.d.c = mkCyc(z, d); i.p.cyc = cyc; if (add) i.p.cyc[0] += i.p.d.c[0]; @@ -2288,7 +2298,7 @@ function CPU() { } function mkSD(op, mn, z, sm, sr, dm, dr, cyc, sa, da) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; @@ -2297,8 +2307,8 @@ function CPU() { i.p.z = z; i.p.ms = z == 1 ? 0x80 : (z == 2 ? 0x8000 : 0x80000000); i.p.mz = z == 1 ? 0xff : (z == 2 ? 0xffff : 0xffffffff); - i.p.s = new effAddr(sm, sr); - i.p.d = new effAddr(dm, dr); + i.p.s = new EffAddr(sm, sr); + i.p.d = new EffAddr(dm, dr); i.p.s.c = mkCyc(z, sm); i.p.d.c = mkCyc(z, dm); i.p.cyc = cyc; @@ -2312,28 +2322,28 @@ function CPU() { } function mkC(op, mn, sz, cc, dp, dr, cycTaken, cyc) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; i.f = null; i.p = {}; i.p.z = sz; - i.p.c = new iCon(cc, dp, dr); + i.p.c = new ICon(cc, dp, dr); if (cycTaken !== null) i.p.cycTaken = cycTaken; if (cyc !== null) i.p.cyc = cyc; return i; } function mkDBcc(op, mn, sz, cc, dp, dr, cycTrue, cycFalseTaken, cycFalse) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; i.f = null; i.p = {}; i.p.z = sz; - i.p.c = new iCon(cc, dp, dr); + i.p.c = new ICon(cc, dp, dr); i.p.cycTrue = cycTrue; i.p.cycFalseTaken = cycFalseTaken; i.p.cycFalse = cycFalse; @@ -2341,15 +2351,15 @@ function CPU() { } function mkCD(op, mn, z, cc, dp, dr, m, r, cycTrue, cycFalse, add) { - var i = new iDef(); + var i = new IDef(); i.op = op; i.pr = false; i.mn = mn; i.f = null; i.p = {}; i.p.z = z; - i.p.c = new iCon(cc, dp, dr); - i.p.d = new effAddr(m, r); + i.p.c = new ICon(cc, dp, dr); + i.p.d = new EffAddr(m, r); i.p.d.c = mkCyc(z, m); i.p.cycTrue = cycTrue; i.p.cycFalse = cycFalse; @@ -2395,7 +2405,7 @@ function CPU() { iTab = new Array(0x10000); for (op = 0; op < 0x10000; op++) { - iTab[op] = new iDef(); + iTab[op] = new IDef(); iTab[op].op = -1; iTab[op].pr = false; iTab[op].mn = 'ILLEGAL'; @@ -3590,7 +3600,7 @@ function CPU() { op = (275 << 6) | ea[0]; if (iTab[op].op === -1) { - iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true); + iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd); iTab[op].f = I_MOVE_2CCR; cnt++; } else { @@ -3632,7 +3642,7 @@ function CPU() { op = (283 << 6) | ea[0]; if (iTab[op].op === -1) { - iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true); + iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd); iTab[op].pr = true; iTab[op].f = I_MOVE_2SR; cnt++; @@ -4668,29 +4678,29 @@ function CPU() { } this.diss = function (offset, limit) { - var pc = offset === null ? regs.pc : offset; - var cnt = 0; + var pc = offset === null ? regs.pc : offset; + var cnt = 0; - while (cnt++ < limit) { - var o = ''; + while (cnt++ < limit) { + var o = ''; - o += sprintf('$%08x: ', pc); - for (var i = 0; i < 5; i++) - o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2)); + o += sprintf('$%08x: ', pc); + for (var i = 0; i < 5; i++) + o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2)); - var op = AMIGA.mem.load16(pc); - pc += 2; + var op = AMIGA.mem.load16(pc); + pc += 2; - var ip = printI(iTab[op], pc); - o += ip[0]; - pc = ip[1]; + var ip = printI(iTab[op], pc); + o += ip[0]; + pc = ip[1]; - BUG.say(o); - } - } - this.dissFault = function (limit) { - this.diss(fault.pc, limit); - } + BUG.say(o); + } + }; + /*this.dissFault = function (limit) { + this.diss(fault.pc, limit); + };*/ /*function nextIWordData(data, pc) { return (data[pc] << 8) | data[pc + 1]; @@ -4866,37 +4876,37 @@ function CPU() { return getName(AMIGA.mem.load32(task + 10)); } - this.getThisTaskName = function() { - var tn = ''; - /* Extract current task-name form SysBase */ - var sysBase = AMIGA.mem.load32(4); - if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) { - var thisTask = AMIGA.mem.load32(sysBase + 276); - if (thisTask) - tn = getTaskName(thisTask); - } - return tn; - } + this.getThisTaskName = function () { + var tn = ''; + /* Extract current task-name form SysBase */ + var sysBase = AMIGA.mem.load32(4); + if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) { + var thisTask = AMIGA.mem.load32(sysBase + 276); + if (thisTask) + tn = getTaskName(thisTask); + } + return tn; + }; - this.dump = function() { - var i, out = '', tn = 1 ? this.getThisTaskName() : ''; + this.dump = function () { + var i, out = '', tn = 1 ? this.getThisTaskName() : ''; - for (i = 0; i < 8; i++) { - out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '
    '; - } - //out += '
    '; - out += "\n"; - for (i = 0; i < 8; i++) { - out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '
    '; - } - //out += '
    '; - out += "\n"; - out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp); - out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn); - out += "\n"; - out += "\n"; - BUG.say(out); - } + for (i = 0; i < 8; i++) { + out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '
    '; + } + //out += '
    '; + out += "\n"; + for (i = 0; i < 8; i++) { + out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '
    '; + } + //out += '
    '; + out += "\n"; + out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp); + out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn); + out += "\n"; + out += "\n"; + BUG.say(out); + }; /*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/ @@ -5025,7 +5035,7 @@ function CPU() { regs.t = 0; } - function exception_cycles(n) { + /*function exception_cycles(n) { var c; if (n < 16) switch (n) { @@ -5051,7 +5061,7 @@ function CPU() { c = [4,0,0]; } return c; - } + }*/ function exception(n) { //BUG.say(sprintf('cpu.exception() nr %d', n)); @@ -5076,8 +5086,8 @@ function CPU() { if (n == 2) { BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0)); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc); - stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc); + stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr); } else if (n == 3) { BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0)); @@ -5085,14 +5095,14 @@ function CPU() { var wa = 0; var cd = (wa ? 0 : 16) | (olds ? 4 : 0) | (ia ? 2 : 1); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.pc); - stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr); - stEA(exEA(new effAddr(M_ripr, 7), 2), 2, fault.op); - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.ad); - stEA(exEA(new effAddr(M_ripr, 7), 2), 2, cd); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.pc); + stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr); + stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, fault.op); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.ad); + stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, cd); } else { - stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc); - stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr); + stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc); + stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr); } var pc = AMIGA.mem.load32(n * 4); @@ -5113,14 +5123,14 @@ function CPU() { regs.pc = pc; exception_trace(n); - return exception_cycles(n); + return [4,0,0];//exception_cycles(n); } - function exception2(ad) { + /*function exception2(ad) { fault.ad = ad; fault.ia = 0; throw new Exception23(2); - } + }*/ function exception3(ad, ia) { fault.ad = ad; @@ -5139,19 +5149,13 @@ function CPU() { AMIGA.doint(); } - function trace() { - if (regs.t) { - clr_special(SPCFLAG_TRACE); - set_special(SPCFLAG_DOTRACE); - } - } - function cycle_spc(cycles) { if (AMIGA.spcflags & SPCFLAG_COPPER) AMIGA.copper.cycle(); while ((AMIGA.spcflags & SPCFLAG_BLTNASTY) && AMIGA.dmaen(DMAF_BLTEN) && cycles > 0) { var c = AMIGA.blitter.blitnasty(); + //console.log('nasty', cycles, c); if (c > 0) { cycles -= c * CYCLE_UNIT * 2; if (cycles < CYCLE_UNIT) @@ -5166,6 +5170,7 @@ function CPU() { if (AMIGA.spcflags & SPCFLAG_DOTRACE) exception(9); + if (AMIGA.spcflags & SPCFLAG_TRAP) { clr_special(SPCFLAG_TRAP); exception(3); @@ -5183,21 +5188,26 @@ function CPU() { if (intr > 0 && intr > regs.intmask) interrupt(intr); } - /*if (AMIGA.spcflags & SPCFLAG_BRK) { - clr_special(SPCFLAG_BRK); + //if (AMIGA.spcflags & SPCFLAG_BRK) { + if (AMIGA.state != ST_CYCLE) { + //clr_special(SPCFLAG_BRK); clr_special(SPCFLAG_STOP); regs.stopped = false; return true; - }*/ + } } - if (AMIGA.spcflags & SPCFLAG_TRACE) - trace(); + if (AMIGA.spcflags & SPCFLAG_TRACE) { + if (regs.t) { + clr_special(SPCFLAG_TRACE); + set_special(SPCFLAG_DOTRACE); + } + } if (AMIGA.spcflags & SPCFLAG_INT) { clr_special(SPCFLAG_INT | SPCFLAG_DOINT); var intr = AMIGA.intlev(); - if (intr > 0 && (intr > regs.intmask || intr == 7)) + if (intr > 0 && intr > regs.intmask) interrupt(intr); } if (AMIGA.spcflags & SPCFLAG_DOINT) { diff --git a/sae/custom.js b/sae/custom.js index 77ad5eb..f3caed8 100644 --- a/sae/custom.js +++ b/sae/custom.js @@ -11,352 +11,715 @@ function Custom() { this.last_value = 0; - this.setup = function() {} - this.reset = function() {} + this.setup = function () { + }; + this.reset = function () { + }; /*---------------------------------*/ this.load16_real = function (hpos, addr, noput) { - var writeonly = false; - var v; + var writeonly = false; + var v; - addr &= 0xfff; + addr &= 0xfff; - switch (addr & 0x1fe) { - case 0x002: v = AMIGA.DMACONR(hpos); break; - case 0x004: v = AMIGA.playfield.VPOSR(); break; - case 0x006: v = AMIGA.playfield.VHPOSR(); break; + switch (addr & 0x1fe) { + case 0x002: + v = AMIGA.DMACONR(hpos); + 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.CLXDAT(); break; - case 0x010: v = AMIGA.ADKCONR(); break; + case 0x00A: + v = AMIGA.input.JOY0DAT(); + break; + case 0x00C: + v = AMIGA.input.JOY1DAT(); + break; + case 0x00E: + v = AMIGA.playfield.CLXDAT(); + break; + case 0x010: + v = AMIGA.ADKCONR(); + break; - case 0x012: v = AMIGA.input.POT0DAT(); break; - case 0x014: v = AMIGA.input.POT1DAT(); break; - case 0x016: v = AMIGA.input.POTGOR(); break; - case 0x018: v = AMIGA.serial.SERDATR(); break; - case 0x01A: v = AMIGA.disk.DSKBYTR(hpos); break; - case 0x01C: v = AMIGA.INTENAR(); break; - case 0x01E: v = AMIGA.INTREQR(); break; - case 0x07C: { - var result = AMIGA.playfield.DENISEID(); - if (result[0]) - writeonly = true; - else - v = result[1]; - break; - } + case 0x012: + v = AMIGA.input.POT0DAT(); + break; + case 0x014: + v = AMIGA.input.POT1DAT(); + break; + case 0x016: + v = AMIGA.input.POTGOR(); + break; + case 0x018: + v = AMIGA.serial.SERDATR(); + break; + case 0x01A: + v = AMIGA.disk.DSKBYTR(hpos); + break; + case 0x01C: + v = AMIGA.INTENAR(); + break; + case 0x01E: + v = AMIGA.INTREQR(); + break; + case 0x07C: + { + var result = AMIGA.playfield.DENISEID(); + if (result[0]) + writeonly = true; + else + v = result[1]; + break; + } -/*#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.mask & CSMASK_AGA)) - writeonly = true; - v = COLOR_READ ((addr & 0x3E) >> 1); - break; -#endif*/ + /*#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.mask & CSMASK_AGA)) + writeonly = true; + v = COLOR_READ ((addr & 0x3E) >> 1); + break; + #endif*/ - default: - writeonly = true; - } - - if (writeonly) { - v = this.last_value; - if (!noput) { - 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.mask & CSMASK_ECS_AGNUS) { - v = l; - } else { - if ((addr & 0x1fe) == 0) { - /*if (is_cycle_ce()) - v = this.last_value; - else*/ - v = l; - } - } - } else { - if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) - v = 0xffff; - else - v = l; - } - //BUG.info('Custom.load16_real() %08x read = %04x. value written = %04x', 0xdff000 | addr, v, l); - return v; - } - } - - this.last_value = v; - return v; - } + default: + writeonly = true; + } + + if (writeonly) { + v = this.last_value; + if (!noput) { + 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.mask & CSMASK_ECS_AGNUS) { + v = l; + } else { + if ((addr & 0x1fe) == 0) { + /*if (is_cycle_ce()) + v = this.last_value; + else*/ + v = l; + } + } + } else { + if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) + v = 0xffff; + else + v = l; + } + //BUG.info('Custom.load16_real() %08x read = %04x. value written = %04x', 0xdff000 | addr, v, l); + return v; + } + } + + this.last_value = v; + return v; + }; this.load16_2 = function (addr) { - var hpos = AMIGA.playfield.hpos(); + var hpos = AMIGA.playfield.hpos(); - AMIGA.copper.sync_copper_with_cpu (hpos, 1); - return this.load16_real(hpos, addr, 0); - } + AMIGA.copper.sync_copper_with_cpu(hpos, 1); + return this.load16_real(hpos, addr, 0); + }; this.load16 = function (addr) { - if (addr & 1) { - addr &= ~1; - return (this.load16_2(addr) << 8) | (this.load16_2(addr + 2) >> 8); - } - return this.load16_2(addr); - } + if (addr & 1) { + addr &= ~1; + return (this.load16_2(addr) << 8) | (this.load16_2(addr + 2) >> 8); + } + return this.load16_2(addr); + }; this.load8 = function (addr) { - return this.load16_2(addr & ~1) >> ((addr & 1) ? 0 : 8); - } + return this.load16_2(addr & ~1) >> ((addr & 1) ? 0 : 8); + }; this.load32 = function (addr) { - return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0; - } + return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0; + }; /*---------------------------------*/ this.store16_real = function (hpos, addr, value, noget) { - if (!noget) this.last_value = value; + if (!noget) this.last_value = value; - addr &= 0x1fe; - value &= 0xffff; + addr &= 0x1fe; + value &= 0xffff; - switch (addr) { - case 0x00E: AMIGA.playfield.CLXDAT(); break; + switch (addr) { + 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 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.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; - case 0x034: AMIGA.input.POTGO(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; + case 0x034: + AMIGA.input.POTGO(value); + break; - case 0x040: AMIGA.blitter.BLTCON0(hpos, value); break; - case 0x042: AMIGA.blitter.BLTCON1(hpos, value); break; + case 0x040: + AMIGA.blitter.BLTCON0(hpos, value); + break; + case 0x042: + AMIGA.blitter.BLTCON1(hpos, value); + break; - case 0x044: AMIGA.blitter.BLTAFWM(hpos, value); break; - case 0x046: AMIGA.blitter.BLTALWM(hpos, value); break; + case 0x044: + AMIGA.blitter.BLTAFWM(hpos, value); + break; + case 0x046: + AMIGA.blitter.BLTALWM(hpos, value); + break; - case 0x050: AMIGA.blitter.BLTAPTH(hpos, value); break; - case 0x052: AMIGA.blitter.BLTAPTL(hpos, value); break; - case 0x04C: AMIGA.blitter.BLTBPTH(hpos, value); break; - case 0x04E: AMIGA.blitter.BLTBPTL(hpos, value); break; - case 0x048: AMIGA.blitter.BLTCPTH(hpos, value); break; - case 0x04A: AMIGA.blitter.BLTCPTL(hpos, value); break; - case 0x054: AMIGA.blitter.BLTDPTH(hpos, value); break; - case 0x056: AMIGA.blitter.BLTDPTL(hpos, value); break; + case 0x050: + AMIGA.blitter.BLTAPTH(hpos, value); + break; + case 0x052: + AMIGA.blitter.BLTAPTL(hpos, value); + break; + case 0x04C: + AMIGA.blitter.BLTBPTH(hpos, value); + break; + case 0x04E: + AMIGA.blitter.BLTBPTL(hpos, value); + break; + case 0x048: + AMIGA.blitter.BLTCPTH(hpos, value); + break; + case 0x04A: + AMIGA.blitter.BLTCPTL(hpos, value); + break; + case 0x054: + AMIGA.blitter.BLTDPTH(hpos, value); + break; + case 0x056: + AMIGA.blitter.BLTDPTL(hpos, value); + break; - case 0x058: AMIGA.blitter.BLTSIZE(hpos, value); break; + case 0x058: + AMIGA.blitter.BLTSIZE(hpos, value); + break; - case 0x064: AMIGA.blitter.BLTAMOD(hpos, value); break; - case 0x062: AMIGA.blitter.BLTBMOD(hpos, value); break; - case 0x060: AMIGA.blitter.BLTCMOD(hpos, value); break; - case 0x066: AMIGA.blitter.BLTDMOD(hpos, value); break; + case 0x064: + AMIGA.blitter.BLTAMOD(hpos, value); + break; + case 0x062: + AMIGA.blitter.BLTBMOD(hpos, value); + break; + case 0x060: + AMIGA.blitter.BLTCMOD(hpos, value); + break; + case 0x066: + AMIGA.blitter.BLTDMOD(hpos, value); + break; - case 0x070: AMIGA.blitter.BLTCDAT(hpos, value); break; - case 0x072: AMIGA.blitter.BLTBDAT(hpos, value); break; - case 0x074: AMIGA.blitter.BLTADAT(hpos, value); break; + case 0x070: + AMIGA.blitter.BLTCDAT(hpos, value); + break; + case 0x072: + AMIGA.blitter.BLTBDAT(hpos, value); + break; + case 0x074: + AMIGA.blitter.BLTADAT(hpos, value); + break; - case 0x07E: AMIGA.disk.DSKSYNC(value, hpos); break; + case 0x07E: + AMIGA.disk.DSKSYNC(value, hpos); + break; - case 0x080: AMIGA.copper.COP1LCH(value); break; - case 0x082: AMIGA.copper.COP1LCL(value); break; - case 0x084: AMIGA.copper.COP2LCH(value); break; - case 0x086: AMIGA.copper.COP2LCL(value); break; + case 0x080: + AMIGA.copper.COP1LCH(value); + break; + case 0x082: + AMIGA.copper.COP1LCL(value); + break; + case 0x084: + AMIGA.copper.COP2LCH(value); + break; + case 0x086: + AMIGA.copper.COP2LCL(value); + break; - case 0x088: AMIGA.copper.COPJMP(1, 0); break; - case 0x08A: AMIGA.copper.COPJMP(2, 0); break; + case 0x088: + AMIGA.copper.COPJMP(1, 0); + break; + case 0x08A: + AMIGA.copper.COPJMP(2, 0); + 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 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.CLXCON(value); break; - case 0x09A: AMIGA.INTENA(value); break; - case 0x09C: AMIGA.INTREQ(value); break; - case 0x09E: AMIGA.ADKCON(value, hpos); break; + case 0x096: + AMIGA.DMACON(value, hpos); + 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; - case 0x0A0: AMIGA.audio.AUDxLCH(0, value); break; - case 0x0A2: AMIGA.audio.AUDxLCL(0, value); break; - case 0x0A4: AMIGA.audio.AUDxLEN(0, value); break; - case 0x0A6: AMIGA.audio.AUDxPER(0, value); break; - case 0x0A8: AMIGA.audio.AUDxVOL(0, value); break; - case 0x0AA: AMIGA.audio.AUDxDAT(0, value); break; + case 0x0A0: + AMIGA.audio.AUDxLCH(0, value); + break; + case 0x0A2: + AMIGA.audio.AUDxLCL(0, value); + break; + case 0x0A4: + AMIGA.audio.AUDxLEN(0, value); + break; + case 0x0A6: + AMIGA.audio.AUDxPER(0, value); + break; + case 0x0A8: + AMIGA.audio.AUDxVOL(0, value); + break; + case 0x0AA: + AMIGA.audio.AUDxDAT(0, value); + break; - case 0x0B0: AMIGA.audio.AUDxLCH(1, value); break; - case 0x0B2: AMIGA.audio.AUDxLCL(1, value); break; - case 0x0B4: AMIGA.audio.AUDxLEN(1, value); break; - case 0x0B6: AMIGA.audio.AUDxPER(1, value); break; - case 0x0B8: AMIGA.audio.AUDxVOL(1, value); break; - case 0x0BA: AMIGA.audio.AUDxDAT(1, value); break; + case 0x0B0: + AMIGA.audio.AUDxLCH(1, value); + break; + case 0x0B2: + AMIGA.audio.AUDxLCL(1, value); + break; + case 0x0B4: + AMIGA.audio.AUDxLEN(1, value); + break; + case 0x0B6: + AMIGA.audio.AUDxPER(1, value); + break; + case 0x0B8: + AMIGA.audio.AUDxVOL(1, value); + break; + case 0x0BA: + AMIGA.audio.AUDxDAT(1, value); + break; - case 0x0C0: AMIGA.audio.AUDxLCH(2, value); break; - case 0x0C2: AMIGA.audio.AUDxLCL(2, value); break; - case 0x0C4: AMIGA.audio.AUDxLEN(2, value); break; - case 0x0C6: AMIGA.audio.AUDxPER(2, value); break; - case 0x0C8: AMIGA.audio.AUDxVOL(2, value); break; - case 0x0CA: AMIGA.audio.AUDxDAT(2, value); break; + case 0x0C0: + AMIGA.audio.AUDxLCH(2, value); + break; + case 0x0C2: + AMIGA.audio.AUDxLCL(2, value); + break; + case 0x0C4: + AMIGA.audio.AUDxLEN(2, value); + break; + case 0x0C6: + AMIGA.audio.AUDxPER(2, value); + break; + case 0x0C8: + AMIGA.audio.AUDxVOL(2, value); + break; + case 0x0CA: + AMIGA.audio.AUDxDAT(2, value); + break; - case 0x0D0: AMIGA.audio.AUDxLCH(3, value); break; - case 0x0D2: AMIGA.audio.AUDxLCL(3, value); break; - case 0x0D4: AMIGA.audio.AUDxLEN(3, value); break; - case 0x0D6: AMIGA.audio.AUDxPER(3, value); break; - case 0x0D8: AMIGA.audio.AUDxVOL(3, value); break; - case 0x0DA: AMIGA.audio.AUDxDAT(3, value); break; + case 0x0D0: + AMIGA.audio.AUDxLCH(3, value); + break; + case 0x0D2: + AMIGA.audio.AUDxLCL(3, value); + break; + case 0x0D4: + AMIGA.audio.AUDxLEN(3, value); + break; + case 0x0D6: + AMIGA.audio.AUDxPER(3, value); + break; + case 0x0D8: + AMIGA.audio.AUDxVOL(3, value); + break; + case 0x0DA: + AMIGA.audio.AUDxDAT(3, value); + 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 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(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 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(hpos, value); break; - case 0x10A: AMIGA.playfield.BPL2MOD(hpos, value); break; - //case 0x10E: AMIGA.playfield.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(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 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: - 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: - 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.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.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.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.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.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.SPRxDATB(hpos, value, (addr - 0x146) >> 3); - break; - - case 0x36: AMIGA.input.JOYTEST(value); break; - 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 + 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: + AMIGA.playfield.COLOR_WRITE(hpos, value & 0xFFF, (addr & 0x3E) >> 1); + break; - 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 0x120: + case 0x124: + case 0x128: + case 0x12C: + case 0x130: + case 0x134: + case 0x138: + case 0x13C: + 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.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.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.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.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.SPRxDATB(hpos, value, (addr - 0x146) >> 3); + break; - //case 0x1FC: AMIGA.playfield.FMODE(hpos, value); break; //AGA - //case 0x1FE: FNULL (value); break; - case 0x1FE: break; + case 0x36: + AMIGA.input.JOYTEST(value); + break; + 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 - /* writing to read-only register causes read access */ - default: { - if (!noget) { - //BUG.info('Custom.store16_real() %04x written', addr); - this.load16_real(hpos, addr, 1); - } - return true; - } - } - return false; - } + 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: AMIGA.playfield.FMODE(hpos, value); break; //AGA + //case 0x1FE: FNULL (value); break; + case 0x1FE: + break; + + /* writing to read-only register causes read access */ + default: + { + if (!noget) { + //BUG.info('Custom.store16_real() %04x written', addr); + this.load16_real(hpos, addr, 1); + } + return true; + } + } + return false; + }; this.store16 = function (addr, value) { - var hpos = AMIGA.playfield.hpos(); - AMIGA.copper.sync_copper_with_cpu(hpos, 1); - if (addr & 1) { - addr &= ~1; - this.store16_real(hpos, addr, (value >> 8) | (value & 0xff00), 0); - this.store16_real(hpos, addr + 2, (value << 8) | (value & 0x00ff), 0); - return; - } - this.store16_real(hpos, addr, value, 0); - } + var hpos = AMIGA.playfield.hpos(); + AMIGA.copper.sync_copper_with_cpu(hpos, 1); + if (addr & 1) { + addr &= ~1; + this.store16_real(hpos, addr, (value >> 8) | (value & 0xff00), 0); + this.store16_real(hpos, addr + 2, (value << 8) | (value & 0x00ff), 0); + return; + } + this.store16_real(hpos, addr, value, 0); + }; this.store8 = function (addr, value) { - var rval; + 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.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); - } + /*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) { this.store16(addr & 0xfffe, value >>> 16); diff --git a/sae/disk.js b/sae/disk.js index 0800fec..a9e7f42 100644 --- a/sae/disk.js +++ b/sae/disk.js @@ -33,9 +33,8 @@ const DSKREADY_DOWN_TIME = 50; const WORDSYNC_TIME = 11; const DSKDMA_OFF = 0; -const DSKDMA_INIT = 1; -const DSKDMA_READ = 2; -const DSKDMA_WRITE = 3; +const DSKDMA_READ = 1; +const DSKDMA_WRITE = 2; const DRIVE_ID_NONE = 0x00000000; const DRIVE_ID_35DD = 0xFFFFFFFF; @@ -53,18 +52,16 @@ const ADF_NONE = -1; const ADF_NORMAL = 0; const ADF_EXT1 = 1; const ADF_EXT2 = 2; -const ADF_FDI = 3; +/*const ADF_FDI = 3; const ADF_IPF = 4; -const ADF_PCDOS = 5; +const ADF_PCDOS = 5;*/ -function trackid() { - var len = 0; - var offs = 0; - var bitlen = 0; - var track = 0; - var sync = 0; - var type = TRACK_NONE; - var revolutions = 0; +function Track() { + this.len = 0; + this.offs = 0; + this.bitlen = 0; + this.sync = 0; + this.type = TRACK_NONE; } function get_floppy_speed() { @@ -83,8 +80,8 @@ function Drive(number) { this.diskfile = null; //this.writediskfile = null; this.filetype = 0; //drive_filetype - this.trackdata = new Array(MAX_TRACKS); for (var i = 0; i < MAX_TRACKS; i++) this.trackdata[i] = new trackid(); - //this.writetrackdata = new Array(MAX_TRACKS); for (var i = 0; i < MAX_TRACKS; i++) this.trackdata[i] = new trackid(); + this.trackdata = new Array(MAX_TRACKS); for (var i = 0; i < MAX_TRACKS; i++) this.trackdata[i] = new Track(); + //this.writetrackdata = new Array(MAX_TRACKS); for (var i = 0; i < MAX_TRACKS; i++) this.trackdata[i] = new Track(); this.writebuffer = new Uint8Array(544 * MAX_SECTORS); for (var i = 0; i < 544 * MAX_SECTORS; i++) this.writebuffer[i] = 0; this.buffered_cyl = 0; this.buffered_side = 0; @@ -95,16 +92,13 @@ function Drive(number) { 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; - this.multi_revolution = 0; this.skipoffset = 0; this.mfmpos = 0; this.indexoffset = 0; this.tracklen = 0; - this.revolutions = 0; this.prevtracklen = 0; this.trackspeed = 0; this.num_tracks = 0; - this.write_num_tracks = 0; this.num_secs = 0; this.hard_num_cyls = 0; this.dskchange = false; @@ -124,89 +118,93 @@ function Drive(number) { this.useturbo = false; this.floppybitcounter = 0; - this.id_name = function() { - switch (this.drive_id) { - case DRIVE_ID_35HD : return '3.5HD'; - case DRIVE_ID_525SD: return '5.25SD'; - case DRIVE_ID_35DD : return '3.5DD'; - case DRIVE_ID_NONE : return 'NONE'; - } - return 'UNKNOWN'; - } + /*this.id_name = function () { + switch (this.drive_id) { + case DRIVE_ID_35HD : + return '3.5HD'; + case DRIVE_ID_525SD: + return '5.25SD'; + case DRIVE_ID_35DD : + return '3.5DD'; + case DRIVE_ID_NONE : + return 'NONE'; + } + return 'UNKNOWN'; + };*/ - this.set_id = function() { - switch (AMIGA.config.floppy.drive[this.num].type) { - case SAEV_Config_Floppy_Type_35_HD: { - if (FLOPPY_DRIVE_HD) { - if (!this.diskfile || this.ddhd <= 1) - this.drive_id = DRIVE_ID_35DD; - else - this.drive_id = DRIVE_ID_35HD; - } else - this.drive_id = DRIVE_ID_35DD; + this.set_id = function () { + switch (AMIGA.config.floppy.drive[this.num].type) { + case SAEV_Config_Floppy_Type_35_HD: + { + if (FLOPPY_DRIVE_HD) { + if (!this.diskfile || this.ddhd <= 1) + this.drive_id = DRIVE_ID_35DD; + else + this.drive_id = DRIVE_ID_35HD; + } else + this.drive_id = DRIVE_ID_35DD; - break; - } - case SAEV_Config_Floppy_Type_35_DD: - this.drive_id = DRIVE_ID_35DD; - break; - case SAEV_Config_Floppy_Type_525_SD: - this.drive_id = DRIVE_ID_525SD; - break; - case SAEV_Config_Floppy_Type_None: - this.drive_id = DRIVE_ID_NONE; - break; - default: - this.drive_id = DRIVE_ID_35DD; - } - //BUG.info('Drive.set_id() DF%d set to %s', this.num, this.id_name()); - } + break; + } + case SAEV_Config_Floppy_Type_35_DD: + this.drive_id = DRIVE_ID_35DD; + break; + case SAEV_Config_Floppy_Type_525_SD: + this.drive_id = DRIVE_ID_525SD; + break; + case SAEV_Config_Floppy_Type_None: + this.drive_id = DRIVE_ID_NONE; + break; + default: + this.drive_id = DRIVE_ID_35DD; + } + //BUG.info('Drive.set_id() DF%d set to %s', this.num, this.id_name()); + }; - this.get_floppy_speed2 = function() { - var m = Math.floor(get_floppy_speed() * this.tracklen / (2 * 8 * (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd)); - if (m <= 0) m = 1; - return m; - } + this.get_floppy_speed2 = function () { + var m = Math.floor(get_floppy_speed() * this.tracklen / (2 * 8 * (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd)); + if (m <= 0) m = 1; + return m; + }; - this.reset = function() { - //BUG.info('Drive.reset() DF%d', this.num); - this.filetype = ADF_NONE; - this.diskfile = null; - //this.writediskfile = null; - this.motoroff = true; - this.idbit = 0; - this.drive_id = 0; - this.drive_id_scnt = 0; - this.indexhackmode = 0; - this.dskchange_time = 0; - this.dskchange = false; - this.dskready_down_time = 0; - this.dskready_up_time = 0; - this.buffered_cyl = -1; - this.buffered_side = -1; - if (this.num == 0 && AMIGA.config.floppy.drive[this.num].type == SAEV_Config_Floppy_Type_35_DD) - this.indexhackmode = 1; - this.set_id(); - } + this.reset = function () { + //BUG.info('Drive.reset() DF%d', this.num); + this.filetype = ADF_NONE; + this.diskfile = null; + //this.writediskfile = null; + this.motoroff = true; + this.idbit = 0; + this.drive_id = 0; + this.drive_id_scnt = 0; + this.indexhackmode = 0; + this.dskchange_time = 0; + this.dskchange = false; + this.dskready_down_time = 0; + this.dskready_up_time = 0; + this.buffered_cyl = -1; + this.buffered_side = -1; + if (this.num == 0 && AMIGA.config.floppy.drive[this.num].type == SAEV_Config_Floppy_Type_35_DD) + this.indexhackmode = 1; + this.set_id(); + }; - this.updatemfmpos = function() { - if (this.prevtracklen) - this.mfmpos = this.mfmpos * Math.floor(Math.floor(this.tracklen * 1000 / this.prevtracklen) / 1000); - this.mfmpos %= this.tracklen; - this.prevtracklen = this.tracklen; - } + this.updatemfmpos = function () { + if (this.prevtracklen) + this.mfmpos = this.mfmpos * Math.floor(Math.floor(this.tracklen * 1000 / this.prevtracklen) / 1000); + this.mfmpos %= this.tracklen; + this.prevtracklen = this.tracklen; + }; - this.reset_track = function() { - //BUG.info('Drive.reset_track() DF%d', this.num); - this.tracklen = (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd * 2 * 8; - this.revolutions = 1; - this.trackspeed = get_floppy_speed(); - this.buffered_side = -1; - this.skipoffset = -1; - this.tracktiming[0] = 0; - for (var i = 0; i < (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd; i++) this.bigmfmbuf[i] = 0xaaaa; //memset (this.bigmfmbuf, 0xaa, (AMIGA.config.video.ntsc ? 6399 : 6334) * 2 * this.ddhd); - this.updatemfmpos(); - } + this.reset_track = function () { + //BUG.info('Drive.reset_track() DF%d', this.num); + this.tracklen = (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd * 2 * 8; + this.trackspeed = get_floppy_speed(); + this.buffered_side = -1; + this.skipoffset = -1; + this.tracktiming[0] = 0; + for (var i = 0; i < (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd; i++) this.bigmfmbuf[i] = 0xaaaa; //memset (this.bigmfmbuf, 0xaa, (AMIGA.config.video.ntsc ? 6399 : 6334) * 2 * this.ddhd); + this.updatemfmpos(); + }; function strncmp_as(str1, str2, n) { for (var i = 0; i < n; i++) { @@ -215,581 +213,578 @@ function Drive(number) { } return 0; } - function strncmp_aa(str1, str2, n) { + /*function strncmp_aa(str1, str2, n) { for (var i = 0; i < n; i++) { if (str1[i] != str2[i]) return 1; } return 0; - } - this.insert = function() { - //BUG.info('DF%d.insert()', this.num); - //const exeheader = [0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00]; + }*/ + this.insert = function () { + //BUG.info('DF%d.insert()', this.num); + //const exeheader = [0x00,0x00,0x03,0xf3,0x00,0x00,0x00,0x00]; - this.filetype = ADF_NONE; - this.diskfile = null; - //this.writediskfile = null; - this.ddhd = 1; - this.num_secs = 0; - this.hard_num_cyls = AMIGA.config.floppy.drive[this.num].type == SAEV_Config_Floppy_Type_525_SD ? 40 : 80; - this.tracktiming[0] = 0; - this.useturbo = false; - this.indexoffset = 0; + this.filetype = ADF_NONE; + this.diskfile = null; + //this.writediskfile = null; + this.ddhd = 1; + this.num_secs = 0; + this.hard_num_cyls = AMIGA.config.floppy.drive[this.num].type == SAEV_Config_Floppy_Type_525_SD ? 40 : 80; + this.tracktiming[0] = 0; + this.useturbo = false; + this.indexoffset = 0; - var size = 0; - if (this.diskdata !== null) { - this.diskfile = new Uint8Array(this.diskdata.length); - for (var i = 0; i < this.diskdata.length; i++) - this.diskfile[i] = this.diskdata[i]; - size = this.diskfile.length; - } - - if (!this.motoroff) { - this.dskready_up_time = DSKREADY_UP_TIME; - this.dskready_down_time = 0; - } - if (this.diskfile === null) { - this.reset_track(); - return 0; - } + var size = 0; + if (this.diskdata !== null) { + this.diskfile = new Uint8Array(this.diskdata.length); + for (var i = 0; i < this.diskdata.length; i++) + this.diskfile[i] = this.diskdata[i]; + size = this.diskfile.length; + } - if (strncmp_as(this.diskfile, 'UAE-1ADF', 8) == 0) { - //BUG.info('DF%d.insert() UAE-1ADF', this.num); + if (!this.motoroff) { + this.dskready_up_time = DSKREADY_UP_TIME; + this.dskready_down_time = 0; + } + if (this.diskfile === null) { + this.reset_track(); + return 0; + } - //read_header_ext2 (drv->diskfile, drv->trackdata, &drv->num_tracks, &drv->ddhd); - this.filetype = ADF_EXT2; - this.num_secs = 11; - if (this.ddhd > 1) - this.num_secs = 22; - } - else if (strncmp_as(this.diskfile, 'UAE--ADF', 8) == 0) { - //BUG.info('DF%d.insert() UAE--ADF', this.num); - var offs = 160 * 4 + 8; + if (strncmp_as(this.diskfile, 'UAE-1ADF', 8) == 0) { + //BUG.info('DF%d.insert() UAE-1ADF', this.num); - this.wrprot = true; - this.filetype = ADF_EXT1; - this.num_tracks = 160; - this.num_secs = 11; + //read_header_ext2 (drv->diskfile, drv->trackdata, &drv->num_tracks, &drv->ddhd); + this.filetype = ADF_EXT2; + this.num_secs = 11; + if (this.ddhd > 1) + this.num_secs = 22; + } + else if (strncmp_as(this.diskfile, 'UAE--ADF', 8) == 0) { + //BUG.info('DF%d.insert() UAE--ADF', this.num); + var offs = 160 * 4 + 8; - for (var i = 0; i < this.num_tracks; i++) { - var buffer = []; - for (var j = 0; j < 4; j++) - buffer[j] = this.diskfile[8 + i * 4 + j]; - - this.trackdata[i].sync = buffer[0] * 256 + buffer[1]; - this.trackdata[i].len = buffer[2] * 256 + buffer[3]; - this.trackdata[i].offs = offs; - this.trackdata[i].revolutions = 1; + this.wrprot = true; + this.filetype = ADF_EXT1; + this.num_tracks = 160; + this.num_secs = 11; - if (this.trackdata[i].sync == 0) { - this.trackdata[i].type = TRACK_AMIGADOS; - this.trackdata[i].bitlen = 0; - } else { - this.trackdata[i].type = TRACK_RAW1; - this.trackdata[i].bitlen = this.trackdata[i].len * 8; - } - offs += this.trackdata[i].len; - } - } - /*else if (strncmp_aa(this.diskfile, exeheader, 8) == 0) { - //BUG.info('DF%d.insert() EXE', this.num); - //struct zfile *z = zfile_fopen_empty(NULL, "", 512 * 1760); - //createimagefromexe (drv->diskfile, z); - //zfile_fclose (drv->diskfile); - - //this.diskfile = z; - this.filetype = ADF_NORMAL; - this.num_tracks = 160; - this.num_secs = 11; - - for (var i = 0; i < this.num_tracks; i++) { - this.trackdata[i].type = TRACK_AMIGADOS; - this.trackdata[i].len = 512 * this.num_secs; - this.trackdata[i].bitlen = 0; - this.trackdata[i].offs = i * 512 * this.num_secs; - this.trackdata[i].revolutions = 1; - } - this.useturbo = true; - }*/ - else { - this.filetype = ADF_NORMAL; + for (var i = 0; i < this.num_tracks; i++) { + var buffer = []; + for (var j = 0; j < 4; j++) + buffer[j] = this.diskfile[8 + i * 4 + j]; - /* high-density or diskspare disk? */ - var ds = false; - this.num_tracks = 0; - if (size > 160 * 11 * 512 + 511) { /* larger than standard adf? */ - for (var i = 80; i <= 83; i++) { - if (size == i * 22 * 512 * 2) { // HD - this.ddhd = 2; - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 22))); - break; - } - if (size == i * 11 * 512 * 2) { // >80 cyl DD - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 11))); - break; - } - if (size == i * 12 * 512 * 2) { // ds 12 sectors - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 12))); - ds = true; - break; - } - if (size == i * 24 * 512 * 2) { // ds 24 sectors - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 24))); - this.ddhd = 2; - ds = true; - break; - } - } - if (this.num_tracks == 0) { - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 22))); - this.ddhd = 2; - } - } else - this.num_tracks = Math.floor(size / (512 * (this.num_secs = 11))); + this.trackdata[i].sync = buffer[0] * 256 + buffer[1]; + this.trackdata[i].len = buffer[2] * 256 + buffer[3]; + this.trackdata[i].offs = offs; - if (!ds && this.num_tracks > MAX_TRACKS) - Fatal(SAEE_Disk_File_Too_Big, sprintf('The diskfile in DF%d is too big. (%d tracks)', this.num, this.num_tracks)); + if (this.trackdata[i].sync == 0) { + this.trackdata[i].type = TRACK_AMIGADOS; + this.trackdata[i].bitlen = 0; + } else { + this.trackdata[i].type = TRACK_RAW1; + this.trackdata[i].bitlen = this.trackdata[i].len * 8; + } + offs += this.trackdata[i].len; + } + } + /*else if (strncmp_aa(this.diskfile, exeheader, 8) == 0) { + //BUG.info('DF%d.insert() EXE', this.num); + //struct zfile *z = zfile_fopen_empty(NULL, "", 512 * 1760); + //createimagefromexe (drv->diskfile, z); + //zfile_fclose (drv->diskfile); - for (var i = 0; i < this.num_tracks; i++) { - this.trackdata[i].type = ds ? TRACK_DISKSPARE : TRACK_AMIGADOS; - this.trackdata[i].len = 512 * this.num_secs; - this.trackdata[i].bitlen = 0; - this.trackdata[i].offs = i * 512 * this.num_secs; - this.trackdata[i].revolutions = 1; - } - } - this.set_id(); - this.fill_bigbuf(AMIGA.disk.side, 1); + //this.diskfile = z; + this.filetype = ADF_NORMAL; + this.num_tracks = 160; + this.num_secs = 11; - this.mfmpos = uaerand(); - this.mfmpos |= (uaerand() << 16); - this.mfmpos %= this.tracklen; - this.prevtracklen = 0; - return 1; - } + for (var i = 0; i < this.num_tracks; i++) { + this.trackdata[i].type = TRACK_AMIGADOS; + this.trackdata[i].len = 512 * this.num_secs; + this.trackdata[i].bitlen = 0; + this.trackdata[i].offs = i * 512 * this.num_secs; + } + this.useturbo = true; + }*/ + else { + this.filetype = ADF_NORMAL; + + /* high-density or diskspare disk? */ + var ds = false; + this.num_tracks = 0; + if (size > 160 * 11 * 512 + 511) { /* larger than standard adf? */ + for (var i = 80; i <= 83; i++) { + if (size == i * 22 * 512 * 2) { // HD + this.ddhd = 2; + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 22))); + break; + } + if (size == i * 11 * 512 * 2) { // >80 cyl DD + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 11))); + break; + } + if (size == i * 12 * 512 * 2) { // ds 12 sectors + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 12))); + ds = true; + break; + } + if (size == i * 24 * 512 * 2) { // ds 24 sectors + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 24))); + this.ddhd = 2; + ds = true; + break; + } + } + if (this.num_tracks == 0) { + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 22))); + this.ddhd = 2; + } + } else + this.num_tracks = Math.floor(size / (512 * (this.num_secs = 11))); + + if (!ds && this.num_tracks > MAX_TRACKS) + Fatal(SAEE_Disk_File_Too_Big, sprintf('The diskfile in DF%d is too big. (%d tracks)', this.num, this.num_tracks)); + + for (var i = 0; i < this.num_tracks; i++) { + this.trackdata[i].type = ds ? TRACK_DISKSPARE : TRACK_AMIGADOS; + this.trackdata[i].len = 512 * this.num_secs; + this.trackdata[i].bitlen = 0; + this.trackdata[i].offs = i * 512 * this.num_secs; + } + } + this.set_id(); + this.fill_bigbuf(AMIGA.disk.side, 1); + + this.mfmpos = uaerand(); + this.mfmpos |= (uaerand() << 16); + this.mfmpos %= this.tracklen; + this.prevtracklen = 0; + return 1; + }; - this.eject = function() { - //BUG.info('DF%d.eject()', this.num); - this.filetype = ADF_NONE; - this.diskfile = null; - //this.writediskfile = null; - this.dskchange = true; - this.dskchange_time = 0; - this.dskready = false; - this.dskready_up_time = 0; - this.dskready_down_time = 0; - this.ddhd = 1; - this.set_id(); - } + this.eject = function () { + //BUG.info('DF%d.eject()', this.num); + this.filetype = ADF_NONE; + this.diskfile = null; + //this.writediskfile = null; + this.dskchange = true; + this.dskchange_time = 0; + this.dskready = false; + this.dskready_up_time = 0; + this.dskready_down_time = 0; + this.ddhd = 1; + this.set_id(); + }; - this.is_empty = function() { - return this.diskfile === null; - } + this.is_empty = function () { + return this.diskfile === null; + }; - this.set_steplimit = function() { - this.steplimit = 10; - this.steplimitcycle = AMIGA.events.currcycle; - } + this.set_steplimit = function () { + this.steplimit = 10; + this.steplimitcycle = AMIGA.events.currcycle; + }; - this.step = function() { - if (!this.is_empty()) - this.dskchange = 0; - - if (this.steplimit && AMIGA.events.currcycle - this.steplimitcycle < MIN_STEPLIMIT_CYCLE) { - BUG.info('Drive.step() DF%d, ignoring step %d', this.num, Math.floor((AMIGA.events.currcycle - this.steplimitcycle) * CYCLE_UNIT_INV)); - return; - } + this.step = function () { + if (!this.is_empty()) + this.dskchange = 0; - this.set_steplimit(); + if (this.steplimit && AMIGA.events.currcycle - this.steplimitcycle < MIN_STEPLIMIT_CYCLE) { + BUG.info('Drive.step() DF%d, ignoring step %d', this.num, Math.floor((AMIGA.events.currcycle - this.steplimitcycle) * CYCLE_UNIT_INV)); + return; + } + + this.set_steplimit(); + + if (AMIGA.disk.direction) { + if (this.cyl) + this.cyl--; + //else BUG.info('Drive.step() DF%d, program tried to step beyond track zero', this.num); //'no-click' programs does that + } else { + var maxtrack = this.hard_num_cyls; + if (this.cyl < maxtrack + 3) + this.cyl++; + //if (this.cyl >= maxtrack) BUG.info('Drive.step() DF%d, program tried to step over track %d', this.num, maxtrack); //'no-click' programs does that + } + AMIGA.disk.rand_shifter(); + AMIGA.config.hooks.floppy_step(this.num, this.cyl); + }; + + this.is_track0 = function () { + return this.cyl == 0; + }; + + this.is_writeprotected = function () { + return this.wrprot || this.diskfile === null; + }; + + this.is_running = function () { + return !this.motoroff; + }; - if (AMIGA.disk.direction) { - if (this.cyl) - this.cyl--; - //else BUG.info('Drive.step() DF%d, program tried to step beyond track zero', this.num); //'no-click' programs does that - } else { - var maxtrack = this.hard_num_cyls; - if (this.cyl < maxtrack + 3) - this.cyl++; - //if (this.cyl >= maxtrack) BUG.info('Drive.step() DF%d, program tried to step over track %d', this.num, maxtrack); //'no-click' programs does that - } - AMIGA.disk.rand_shifter(); - AMIGA.config.hooks.floppy_step(this.num, this.cyl); - } + this.set_motor = function (off) { + if (this.motoroff && !off) { + this.dskready_up_time = DSKREADY_UP_TIME; + AMIGA.disk.rand_shifter(); + } + if (!this.motoroff && off) { + this.drive_id_scnt = 0; + /* Reset id shift reg counter */ + this.dskready_down_time = DSKREADY_DOWN_TIME; - this.is_track0 = function() { - return this.cyl == 0; - } - - this.is_writeprotected = function() { - return this.wrprot || this.diskfile === null; - } - - this.is_running = function() { - return !this.motoroff; - } - - this.set_motor = function(off) { - if (this.motoroff && !off) { - this.dskready_up_time = DSKREADY_UP_TIME; - AMIGA.disk.rand_shifter(); - } - if (!this.motoroff && off) { - this.drive_id_scnt = 0; /* Reset id shift reg counter */ - this.dskready_down_time = DSKREADY_DOWN_TIME; - - if (AMIGA.config.cpu.model <= 68010 && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Original) { - this.motordelay = true; - AMIGA.events.newevent2(30, this.num, function(v) { AMIGA.disk.motordelay_func(v); }); - } - } - this.motoroff = off; - if (this.motoroff) { - this.dskready = false; - this.dskready_up_time = 0; - } else { - this.dskready_down_time = 0; - } - } + if (AMIGA.config.cpu.model <= 68010 && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Original) { + this.motordelay = true; + AMIGA.events.newevent2(30, this.num, function (v) { + AMIGA.disk.motordelay_func(v); + }); + } + } + this.motoroff = off; + if (this.motoroff) { + this.dskready = false; + this.dskready_up_time = 0; + } else { + this.dskready_down_time = 0; + } + }; /* get one bit from MFM bit stream */ - this.getonebit = function(mfmpos) { - return (this.bigmfmbuf[mfmpos >> 4] & (1 << (15 - (mfmpos & 15)))) ? 1 : 0; - } - this.decode_amigados = function() { - var gap_len = AMIGA.config.video.ntsc ? 415 : 350; - var tr = this.cyl * 2 + AMIGA.disk.side; - var len = this.num_secs * 544 + gap_len; - var bigmfmpos = gap_len; - var sec; - var i; - - for (i = 0; i < len; i++) - this.bigmfmbuf[i] = 0xaaaa; - - this.skipoffset = Math.floor((gap_len * 8) / 3) * 2; - this.tracklen = len * 2 * 8; + this.getonebit = function (mfmpos) { + return (this.bigmfmbuf[mfmpos >> 4] & (1 << (15 - (mfmpos & 15)))) ? 1 : 0; + }; + this.decode_amigados = function () { + var gap_len = AMIGA.config.video.ntsc ? 415 : 350; + var tr = this.cyl * 2 + AMIGA.disk.side; + var len = this.num_secs * 544 + gap_len; + var bigmfmpos = gap_len; + var sec; + var i; - for (sec = 0; sec < this.num_secs; sec++) { - var secbuf = new Uint8Array(544); - var mfmbuf = new Uint16Array(544); - var deven, dodd; - var hck = 0, dck = 0; + for (i = 0; i < len; i++) + this.bigmfmbuf[i] = 0xaaaa; - secbuf[0] = secbuf[1] = 0x00; - secbuf[2] = secbuf[3] = 0xa1; - secbuf[4] = 0xff; - secbuf[5] = tr; - secbuf[6] = sec; - secbuf[7] = this.num_secs - sec; + this.skipoffset = Math.floor((gap_len * 8) / 3) * 2; + this.tracklen = len * 2 * 8; - for (i = 8; i < 24; i++) - secbuf[i] = 0; + for (sec = 0; sec < this.num_secs; sec++) { + var secbuf = new Uint8Array(544); + var mfmbuf = new Uint16Array(544); + var deven, dodd; + var hck = 0, dck = 0; - //read_floppy_data (this.diskfile, ti, sec * 512, &secbuf[32], 512); - { - var offset = this.trackdata[tr].offs + sec * 512; - for (i = 0; i < 512; i++) secbuf[32 + i] = this.diskfile[offset + i]; - } + secbuf[0] = secbuf[1] = 0x00; + secbuf[2] = secbuf[3] = 0xa1; + secbuf[4] = 0xff; + secbuf[5] = tr; + secbuf[6] = sec; + secbuf[7] = this.num_secs - sec; - mfmbuf[0] = mfmbuf[1] = 0xaaaa; - mfmbuf[2] = mfmbuf[3] = 0x4489; + for (i = 8; i < 24; i++) + secbuf[i] = 0; - deven = ((secbuf[4] << 24) | (secbuf[5] << 16) | (secbuf[6] << 8) | (secbuf[7])) >>> 0; - dodd = deven >>> 1; - deven &= 0x55555555; - dodd &= 0x55555555; + //read_floppy_data (this.diskfile, ti, sec * 512, &secbuf[32], 512); + { + var offset = this.trackdata[tr].offs + sec * 512; + for (i = 0; i < 512; i++) secbuf[32 + i] = this.diskfile[offset + i]; + } - mfmbuf[4] = dodd >>> 16; - mfmbuf[5] = dodd & 0xffff; - mfmbuf[6] = deven >>> 16; - mfmbuf[7] = deven & 0xffff; + mfmbuf[0] = mfmbuf[1] = 0xaaaa; + mfmbuf[2] = mfmbuf[3] = 0x4489; - for (i = 8; i < 48; i++) - mfmbuf[i] = 0xaaaa; - for (i = 0; i < 512; i += 4) { - deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16) | (secbuf[i + 34] << 8) | (secbuf[i + 35])) >>> 0; - dodd = deven >>> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[(i >> 1) + 32] = dodd >>> 16; - mfmbuf[(i >> 1) + 33] = dodd & 0xffff; - mfmbuf[(i >> 1) + 256 + 32] = deven >>> 16; - mfmbuf[(i >> 1) + 256 + 33] = deven & 0xffff; - } + deven = ((secbuf[4] << 24) | (secbuf[5] << 16) | (secbuf[6] << 8) | (secbuf[7])) >>> 0; + dodd = deven >>> 1; + deven &= 0x55555555; + dodd &= 0x55555555; - for (i = 4; i < 24; i += 2) - hck ^= ((mfmbuf[i] << 16) | mfmbuf[i + 1]) >>> 0; + mfmbuf[4] = dodd >>> 16; + mfmbuf[5] = dodd & 0xffff; + mfmbuf[6] = deven >>> 16; + mfmbuf[7] = deven & 0xffff; - deven = dodd = hck; - dodd >>>= 1; - mfmbuf[24] = dodd >>> 16; - mfmbuf[25] = dodd & 0xffff; - mfmbuf[26] = deven >>> 16; - mfmbuf[27] = deven & 0xffff; + for (i = 8; i < 48; i++) + mfmbuf[i] = 0xaaaa; + for (i = 0; i < 512; i += 4) { + deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16) | (secbuf[i + 34] << 8) | (secbuf[i + 35])) >>> 0; + dodd = deven >>> 1; + deven &= 0x55555555; + dodd &= 0x55555555; + mfmbuf[(i >> 1) + 32] = dodd >>> 16; + mfmbuf[(i >> 1) + 33] = dodd & 0xffff; + mfmbuf[(i >> 1) + 256 + 32] = deven >>> 16; + mfmbuf[(i >> 1) + 256 + 33] = deven & 0xffff; + } - for (i = 32; i < 544; i += 2) - dck ^= ((mfmbuf[i] << 16) | mfmbuf[i + 1]) >>> 0; + for (i = 4; i < 24; i += 2) + hck ^= ((mfmbuf[i] << 16) | mfmbuf[i + 1]) >>> 0; - deven = dodd = dck; - dodd >>>= 1; - mfmbuf[28] = dodd >>> 16; - mfmbuf[29] = dodd & 0xffff; - mfmbuf[30] = deven >>> 16; - mfmbuf[31] = deven & 0xffff; + deven = dodd = hck; + dodd >>>= 1; + mfmbuf[24] = dodd >>> 16; + mfmbuf[25] = dodd & 0xffff; + mfmbuf[26] = deven >>> 16; + mfmbuf[27] = deven & 0xffff; - //mfmcode (mfmbuf + 4, 544 - 4); static this.mfmcode (var * mfm, var words) - { - var words = 540, lastword = 0, pos = 4; - while (words--) { - //var v = *mfm; - var v = mfmbuf[pos]; - var lv = ((lastword << 16) | v) >>> 0; - var nlv = (0x55555555 & ~lv) >>> 0; - var mfmbits = (((nlv << 1) & (nlv >>> 1)) >>> 0) & 0xffff; - //*mfm++ = v | mfmbits; - mfmbuf[pos] = v | mfmbits; - lastword = v; - pos++; - } - } - - for (i = 0; i < 544; i++) { - this.bigmfmbuf[bigmfmpos % len] = mfmbuf[i]; bigmfmpos++; - } - } - } + for (i = 32; i < 544; i += 2) + dck ^= ((mfmbuf[i] << 16) | mfmbuf[i + 1]) >>> 0; - this.decode_raw = function() { - var tr = this.cyl * 2 + AMIGA.disk.side; + deven = dodd = dck; + dodd >>>= 1; + mfmbuf[28] = dodd >>> 16; + mfmbuf[29] = dodd & 0xffff; + mfmbuf[30] = deven >>> 16; + mfmbuf[31] = deven & 0xffff; - var base_offset = this.trackdata[tr].type == TRACK_RAW ? 0 : 1; - this.tracklen = this.trackdata[tr].bitlen + 16 * base_offset; - this.bigmfmbuf[0] = this.trackdata[tr].sync; - var len = Math.floor((this.trackdata[tr].bitlen + 7) / 8); - var buf = new Uint8Array(len); + //mfmcode (mfmbuf + 4, 544 - 4); static this.mfmcode (var * mfm, var words) + { + var words = 540, lastword = 0, pos = 4; + while (words--) { + //var v = *mfm; + var v = mfmbuf[pos]; + var lv = ((lastword << 16) | v) >>> 0; + var nlv = (0x55555555 & ~lv) >>> 0; + var mfmbits = (((nlv << 1) & (nlv >>> 1)) >>> 0) & 0xffff; + //*mfm++ = v | mfmbits; + mfmbuf[pos] = v | mfmbits; + lastword = v; + pos++; + } + } - //read_floppy_data (this.diskfile, ti, 0, (var*)(this.bigmfmbuf + base_offset), Math.floor((ti->bitlen + 7) / 8)); - { - var offset = this.trackdata[tr].offs; - for (var i = 0; i < len; i++) - buf[i] = this.diskfile[offset + i]; - } + for (i = 0; i < 544; i++) { + this.bigmfmbuf[bigmfmpos % len] = mfmbuf[i]; + bigmfmpos++; + } + } + }; - for (var i = base_offset; i < Math.floor((this.tracklen + 15) / 16); i++) - this.bigmfmbuf[i] = 256 * buf[(i - base_offset) << 1] + buf[((i - base_offset) << 1) + 1]; + this.decode_raw = function () { + var tr = this.cyl * 2 + AMIGA.disk.side; - //BUG.info('DF%d.decode_raw() rawtrack %d, offset %d', this.num, tr, this.trackdata[tr].offs); - } + var base_offset = this.trackdata[tr].type == TRACK_RAW ? 0 : 1; + this.tracklen = this.trackdata[tr].bitlen + 16 * base_offset; + this.bigmfmbuf[0] = this.trackdata[tr].sync; + var len = Math.floor((this.trackdata[tr].bitlen + 7) / 8); + var buf = new Uint8Array(len); + + //read_floppy_data (this.diskfile, ti, 0, (var*)(this.bigmfmbuf + base_offset), Math.floor((ti->bitlen + 7) / 8)); + { + var offset = this.trackdata[tr].offs; + for (var i = 0; i < len; i++) + buf[i] = this.diskfile[offset + i]; + } + + for (var i = base_offset; i < Math.floor((this.tracklen + 15) / 16); i++) + this.bigmfmbuf[i] = 256 * buf[(i - base_offset) << 1] + buf[((i - base_offset) << 1) + 1]; + + //BUG.info('DF%d.decode_raw() rawtrack %d, offset %d', this.num, tr, this.trackdata[tr].offs); + }; - this.fill_bigbuf = function(force) { - var tr = this.cyl * 2 + AMIGA.disk.side; + this.fill_bigbuf = function (force) { + var tr = this.cyl * 2 + AMIGA.disk.side; - if (!this.diskfile || tr >= this.num_tracks) { - this.reset_track(); - return; - } - if (!force && this.buffered_cyl == this.cyl && this.buffered_side == AMIGA.disk.side) - return; - - this.indexoffset = 0; - this.multi_revolution = 0; - this.tracktiming[0] = 0; - this.skipoffset = -1; - this.revolutions = 1; + if (!this.diskfile || tr >= this.num_tracks) { + this.reset_track(); + return; + } + if (!force && this.buffered_cyl == this.cyl && this.buffered_side == AMIGA.disk.side) + return; - /*if (this.writediskfile && this.writetrackdata[tr].bitlen > 0) { - var i; - trackid *wti = &this.writetrackdata[tr]; - this.tracklen = wti->bitlen; - this.revolutions = wti->revolutions; - read_floppy_data (this.writediskfile, wti, 0, (var*)this.bigmfmbuf, Math.floor((wti->bitlen + 7) / 8)); - for (i = 0; i < Math.floor((this.tracklen + 15) / 16); i++) { - var *mfm = this.bigmfmbuf + i; - var *data = (var *) mfm; - *mfm = 256 * *data + *(data + 1); - } - write_log ('track %d, length %d read from \'saveimage\'\n', tr, this.tracklen); - } else*/ - if (this.trackdata[tr].type == TRACK_NONE) { - } - else if (this.trackdata[tr].type == TRACK_AMIGADOS) - this.decode_amigados(); - else if (this.trackdata[tr].type == TRACK_DISKSPARE) - this.decode_diskspare(); - else if (this.trackdata[tr].type == TRACK_PCDOS) - this.decode_pcdos(); - else - this.decode_raw() + this.indexoffset = 0; + this.tracktiming[0] = 0; + this.skipoffset = -1; - this.buffered_side = AMIGA.disk.side; - this.buffered_cyl = this.cyl; - if (this.tracklen == 0) { - this.tracklen = (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd * 2 * 8; - for (var i = 0; i < (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd; i++) this.bigmfmbuf[i] = 0; //memset (this.bigmfmbuf, 0, (AMIGA.config.video.ntsc ? 6399 : 6334) * 2 * this.ddhd); - } + /*if (this.writediskfile && this.writetrackdata[tr].bitlen > 0) { + var i; + Track *wti = &this.writetrackdata[tr]; + this.tracklen = wti->bitlen; + read_floppy_data (this.writediskfile, wti, 0, (var*)this.bigmfmbuf, Math.floor((wti->bitlen + 7) / 8)); + for (i = 0; i < Math.floor((this.tracklen + 15) / 16); i++) { + var *mfm = this.bigmfmbuf + i; + var *data = (var *) mfm; + *mfm = 256 * *data + *(data + 1); + } + write_log ('track %d, length %d read from \'saveimage\'\n', tr, this.tracklen); + } else*/ + if (this.trackdata[tr].type == TRACK_NONE) { + } + else if (this.trackdata[tr].type == TRACK_AMIGADOS) + this.decode_amigados(); + else if (this.trackdata[tr].type == TRACK_DISKSPARE) + this.decode_diskspare(); + else if (this.trackdata[tr].type == TRACK_PCDOS) + this.decode_pcdos(); + else + this.decode_raw(); - this.trackspeed = this.get_floppy_speed2(); - this.updatemfmpos(); - } + this.buffered_side = AMIGA.disk.side; + this.buffered_cyl = this.cyl; + if (this.tracklen == 0) { + this.tracklen = (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd * 2 * 8; + for (var i = 0; i < (AMIGA.config.video.ntsc ? 6399 : 6334) * this.ddhd; i++) this.bigmfmbuf[i] = 0; //memset (this.bigmfmbuf, 0, (AMIGA.config.video.ntsc ? 6399 : 6334) * 2 * this.ddhd); + } - this.getmfmword = function(mbuf, shift) { - return (((this.bigmfmbuf[mbuf] << shift) | (this.bigmfmbuf[mbuf + 1] >>> (16 - shift))) >>> 0) & 0xffff; - } - this.getmfmlong = function(mbuf, shift) { - return (((this.getmfmword(mbuf, shift) << 16) | this.getmfmword(mbuf + 1, shift)) >>> 0) & 0x55555555; - } - this.decode_buffer = function(checkmode) { - var mbuf = 0; - var cyl = this.cyl; - var drvsec = this.num_secs; - var ddhd = this.ddhd; - var filetype = this.filetype; - - var i, secwritten = 0; - var fwlen = (AMIGA.config.video.ntsc ? 6399 : 6334) * ddhd; - var length = 2 * fwlen; - var odd, even, chksum, id, dlong; - var secbuf = new Uint8Array(544); - var sectable = new Array(22); - var mend = length - (4 + 16 + 8 + 512); - var shift = 0; - - for (i = 0; i < sectable.length; i++) sectable[i] = 0; //memset (sectable, 0, sizeof (sectable)); - for (i = 0; i < fwlen; i++) this.bigmfmbuf[fwlen + i] = this.bigmfmbuf[i]; //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof(uae_u16)); - - while (secwritten < drvsec) { - while (this.getmfmword(mbuf, shift) != 0x4489) { - if (mbuf >= mend) return 1; - shift++; - if (shift == 16) { - shift = 0; - mbuf++; - } - } - while (this.getmfmword(mbuf, shift) == 0x4489) { - if (mbuf >= mend) return 10; - mbuf++; - } + this.trackspeed = this.get_floppy_speed2(); + this.updatemfmpos(); + }; - odd = this.getmfmlong(mbuf, shift); - even = this.getmfmlong(mbuf + 2, shift); - mbuf += 4; - id = (((odd << 1) | even) >>> 0) & 0xffffffff; + this.getmfmword = function (mbuf, shift) { + return (((this.bigmfmbuf[mbuf] << shift) | (this.bigmfmbuf[mbuf + 1] >>> (16 - shift))) >>> 0) & 0xffff; + }; + this.getmfmlong = function (mbuf, shift) { + return (((this.getmfmword(mbuf, shift) << 16) | this.getmfmword(mbuf + 1, shift)) >>> 0) & 0x55555555; + }; + this.decode_buffer = function (checkmode) { + var mbuf = 0; + var cyl = this.cyl; + var drvsec = this.num_secs; + var ddhd = this.ddhd; + var filetype = this.filetype; - var trackoffs = (id & 0xff00) >>> 8; - if (trackoffs + 1 > drvsec) { - BUG.info('DF%d.decode_buffer() weird sector number %d', this.num, trackoffs); - if (filetype == ADF_EXT2) return 2; - continue; - } - chksum = (odd ^ even) >>> 0; - for (i = 0; i < 4; i++) { - odd = this.getmfmlong(mbuf, shift); - even = this.getmfmlong(mbuf + 8, shift); - mbuf += 2; + var i, secwritten = 0; + var fwlen = (AMIGA.config.video.ntsc ? 6399 : 6334) * ddhd; + var length = 2 * fwlen; + var odd, even, chksum, id, dlong; + var secbuf = new Uint8Array(544); + var sectable = new Array(22); + var mend = length - (4 + 16 + 8 + 512); + var shift = 0; - dlong = (((odd << 1) | even) >>> 0) & 0xffffffff; - if (dlong && !checkmode) { - if (filetype == ADF_EXT2) return 6; - secwritten = -200; - } - chksum ^= odd ^ even; - chksum &= 0xffffffff; - } - mbuf += 8; - odd = this.getmfmlong(mbuf, shift); - even = this.getmfmlong(mbuf + 2, shift); - mbuf += 4; - if (((((odd << 1) | even) >>> 0) & 0xffffffff) != chksum || ((id & 0x00ff0000) >> 16) != cyl * 2 + AMIGA.disk.side) { - BUG.info('DF%d.decode_buffer() checksum error on sector %d header', this.num, trackoffs); - if (filetype == ADF_EXT2) return 3; - continue; - } - odd = this.getmfmlong(mbuf, shift); - even = this.getmfmlong(mbuf + 2, shift); - mbuf += 4; - chksum = (((odd << 1) | even) >>> 0) & 0xffffffff; - for (i = 0; i < 512; i += 4) { - odd = this.getmfmlong(mbuf, shift); - even = this.getmfmlong(mbuf + 256, shift); - mbuf += 2; - dlong = (((odd << 1) | even) >>> 0) & 0xffffffff; - secbuf[32 + i] = (dlong >>> 24) & 0xff; - secbuf[33 + i] = (dlong >>> 16) & 0xff; - secbuf[34 + i] = (dlong >>> 8) & 0xff; - secbuf[35 + i] = dlong & 0xff; - chksum ^= odd ^ even; - chksum &= 0xffffffff; - } - if (chksum) { - BUG.info('DF%d.decode_buffer() sector %d, data checksum error', this.num, trackoffs); - if (filetype == ADF_EXT2) return 4; - continue; - } - mbuf += 256; - sectable[trackoffs] = 1; - secwritten++; - - for (i = 0; i < 512; i++) this.writebuffer[trackoffs * 512 + i] = secbuf[32 + i]; //memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512); - } - if (filetype == ADF_EXT2 && (secwritten == 0 || secwritten < 0)) - return 5; - if (secwritten == 0) BUG.info('DF%d.decode_buffer() unsupported format', this.num); - if (secwritten < 0) BUG.info('DF%d.decode_buffer() sector labels ignored', this.num); - - return 0; - } + for (i = 0; i < sectable.length; i++) sectable[i] = 0; //memset (sectable, 0, sizeof (sectable)); + for (i = 0; i < fwlen; i++) this.bigmfmbuf[fwlen + i] = this.bigmfmbuf[i]; //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof(uae_u16)); + + while (secwritten < drvsec) { + while (this.getmfmword(mbuf, shift) != 0x4489) { + if (mbuf >= mend) return 1; + shift++; + if (shift == 16) { + shift = 0; + mbuf++; + } + } + while (this.getmfmword(mbuf, shift) == 0x4489) { + if (mbuf >= mend) return 10; + mbuf++; + } + + odd = this.getmfmlong(mbuf, shift); + even = this.getmfmlong(mbuf + 2, shift); + mbuf += 4; + id = (((odd << 1) | even) >>> 0) & 0xffffffff; + + var trackoffs = (id & 0xff00) >>> 8; + if (trackoffs + 1 > drvsec) { + BUG.info('DF%d.decode_buffer() weird sector number %d', this.num, trackoffs); + if (filetype == ADF_EXT2) return 2; + continue; + } + chksum = (odd ^ even) >>> 0; + for (i = 0; i < 4; i++) { + odd = this.getmfmlong(mbuf, shift); + even = this.getmfmlong(mbuf + 8, shift); + mbuf += 2; + + dlong = (((odd << 1) | even) >>> 0) & 0xffffffff; + if (dlong && !checkmode) { + if (filetype == ADF_EXT2) return 6; + secwritten = -200; + } + chksum ^= odd ^ even; + chksum &= 0xffffffff; + } + mbuf += 8; + odd = this.getmfmlong(mbuf, shift); + even = this.getmfmlong(mbuf + 2, shift); + mbuf += 4; + if (((((odd << 1) | even) >>> 0) & 0xffffffff) != chksum || ((id & 0x00ff0000) >> 16) != cyl * 2 + AMIGA.disk.side) { + BUG.info('DF%d.decode_buffer() checksum error on sector %d header', this.num, trackoffs); + if (filetype == ADF_EXT2) return 3; + continue; + } + odd = this.getmfmlong(mbuf, shift); + even = this.getmfmlong(mbuf + 2, shift); + mbuf += 4; + chksum = (((odd << 1) | even) >>> 0) & 0xffffffff; + for (i = 0; i < 512; i += 4) { + odd = this.getmfmlong(mbuf, shift); + even = this.getmfmlong(mbuf + 256, shift); + mbuf += 2; + dlong = (((odd << 1) | even) >>> 0) & 0xffffffff; + secbuf[32 + i] = (dlong >>> 24) & 0xff; + secbuf[33 + i] = (dlong >>> 16) & 0xff; + secbuf[34 + i] = (dlong >>> 8) & 0xff; + secbuf[35 + i] = dlong & 0xff; + chksum ^= odd ^ even; + chksum &= 0xffffffff; + } + if (chksum) { + BUG.info('DF%d.decode_buffer() sector %d, data checksum error', this.num, trackoffs); + if (filetype == ADF_EXT2) return 4; + continue; + } + mbuf += 256; + sectable[trackoffs] = 1; + secwritten++; + + for (i = 0; i < 512; i++) this.writebuffer[trackoffs * 512 + i] = secbuf[32 + i]; //memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512); + } + if (filetype == ADF_EXT2 && (secwritten == 0 || secwritten < 0)) + return 5; + if (secwritten == 0) BUG.info('DF%d.decode_buffer() unsupported format', this.num); + if (secwritten < 0) BUG.info('DF%d.decode_buffer() sector labels ignored', this.num); + + return 0; + }; - this.write_adf_amigados = function() { - //var drvsec, i; - //var sectable[MAX_SECTORS]; + this.write_adf_amigados = function () { + //var drvsec, i; + //var sectable[MAX_SECTORS]; - if (this.decode_buffer(0)) //drv->bigmfmbuf, drv->cyl, drv->num_secs, drv->ddhd, drv->filetype, &drvsec, sectable, 0)) - return 2; - //if (!drvsec) return 2; + if (this.decode_buffer(0)) //drv->bigmfmbuf, drv->cyl, drv->num_secs, drv->ddhd, drv->filetype, &drvsec, sectable, 0)) + return 2; + //if (!drvsec) return 2; - /*for (i = 0; i < drvsec; i++) { - zfile_fseek (drv->diskfile, drv->trackdata[drv->cyl * 2 + AMIGA.disk.side].offs + i * 512, SEEK_SET); - zfile_fwrite (writebuffer + i * 512, sizeof (var), 512, drv->diskfile); - }*/ - for (var i = 0; i < this.num_secs; i++) { - var offset = this.trackdata[this.cyl * 2 + AMIGA.disk.side].offs + i * 512; - for (var j = 0; j < 512; j++) - this.diskfile[offset + j] = this.diskdata[offset + j] = this.writebuffer[i * 512 + j]; - } - return 0; - } + /*for (i = 0; i < drvsec; i++) { + zfile_fseek (drv->diskfile, drv->trackdata[drv->cyl * 2 + AMIGA.disk.side].offs + i * 512, SEEK_SET); + zfile_fwrite (writebuffer + i * 512, sizeof (var), 512, drv->diskfile); + }*/ + for (var i = 0; i < this.num_secs; i++) { + var offset = this.trackdata[this.cyl * 2 + AMIGA.disk.side].offs + i * 512; + for (var j = 0; j < 512; j++) + this.diskfile[offset + j] = this.diskdata[offset + j] = this.writebuffer[i * 512 + j]; + } + return 0; + }; - this.write_data = function() { - var ret = -1; - var tr = this.cyl * 2 + AMIGA.disk.side; + this.write_data = function () { + var tr = this.cyl * 2 + AMIGA.disk.side; - if (this.is_writeprotected() || this.trackdata[tr].type == TRACK_NONE) { - this.buffered_side = 2; - return; - } - //if (this.writediskfile) drive_write_ext2 (this.bigmfmbuf, this.writediskfile, &this.writetrackdata[tr], LONGWRITEMODE ? dsklength2 * 8 : this.tracklen); + if (this.is_writeprotected() || this.trackdata[tr].type == TRACK_NONE) { + this.buffered_side = 2; + return; + } + //if (this.writediskfile) drive_write_ext2 (this.bigmfmbuf, this.writediskfile, &this.writetrackdata[tr], LONGWRITEMODE ? dsklength2 * 8 : this.tracklen); - switch (this.filetype) { - case ADF_NORMAL: { - if (this.write_adf_amigados()) { - //notify_user (NUMSG_NEEDEXT2); - } - return; - } - } - this.tracktiming[0] = 0; - } + switch (this.filetype) { + case ADF_NORMAL: + { + if (this.write_adf_amigados()) { + //notify_user (NUMSG_NEEDEXT2); + } + return; + } + } + this.tracktiming[0] = 0; + }; - this.is_unformatted = function() { - var tr = this.cyl * 2 + AMIGA.disk.side; - if (tr >= this.num_tracks) return true; - if (this.filetype == ADF_EXT2 && this.trackdata[tr].bitlen == 0 && this.trackdata[tr].type != TRACK_AMIGADOS) - return true; - if (this.trackdata[tr].type == TRACK_NONE) - return true; - return false; - } + this.is_unformatted = function () { + var tr = this.cyl * 2 + AMIGA.disk.side; + if (tr >= this.num_tracks) return true; + if (this.filetype == ADF_EXT2 && this.trackdata[tr].bitlen == 0 && this.trackdata[tr].type != TRACK_AMIGADOS) + return true; + + return this.trackdata[tr].type == TRACK_NONE; + }; this.vsync = function() { if (this.dskready_down_time > 0) @@ -808,7 +803,7 @@ function Drive(number) { } function Disk() { - this.side = 0 + this.side = 0; this.direction = 0; var selected = 15; var disabled = 0; @@ -823,7 +818,6 @@ function Disk() { var fifo_filled = false; var dma_enable = false; var bitoffset = 0; - var syncoffset = 0; var word = 0; var dsksync = 0; var dsksync_cycles = 0; @@ -838,817 +832,816 @@ function Disk() { var ledstate = new Array(MAX_FLOPPY_DRIVES); for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) ledstate[i] = false; var floppy = new Array(MAX_FLOPPY_DRIVES); for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) floppy[i] = new Drive(i); - this.setup = function() {} + this.setup = function () { + }; - this.reset = function() { - disk_hpos = 0; - dskdmaen = DSKDMA_OFF; - disabled = 0; - for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { - floppy[i].reset(); - ledstate[i] = false; - 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); - } - } + this.reset = function () { + disk_hpos = 0; + dskdmaen = DSKDMA_OFF; + disabled = 0; + for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { + floppy[i].reset(); + ledstate[i] = false; + 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); + } + }; - this.rand_shifter = function() { - var r = ((uaerand () >>> 4) & 7) + 1; - while (r-- > 0) { - word <<= 1; - word |= (uaerand () & 0x1000) ? 1 : 0; - bitoffset++; - bitoffset &= 15; - } - } + this.rand_shifter = function () { + var r = ((uaerand() >>> 4) & 7) + 1; + while (r-- > 0) { + word <<= 1; + word |= (uaerand() & 0x1000) ? 1 : 0; + bitoffset++; + bitoffset &= 15; + } + }; - this.setdskchangetime = function(num, dsktime) { - if (floppy[num].dskchange_time > 0) - return; - - for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { - if (floppy[i].num != num && floppy[i].dskchange_time > 0 && floppy[i].dskchange_time + 1 >= dsktime) - dsktime = floppy[i].dskchange_time + 1; - } - floppy[num].dskchange_time = dsktime; - //BUG.info('Disk.setdskchangetime() delayed insert enable %d', dsktime); - } + this.setdskchangetime = function (num, dsktime) { + if (floppy[num].dskchange_time > 0) + return; - this.insert2 = function(num, forced) { - //BUG.info('Disk.insert() DF%d', num); + for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { + if (floppy[i].num != num && floppy[i].dskchange_time > 0 && floppy[i].dskchange_time + 1 >= dsktime) + dsktime = floppy[i].dskchange_time + 1; + } + floppy[num].dskchange_time = dsktime; + //BUG.info('Disk.setdskchangetime() delayed insert enable %d', dsktime); + }; - if (AMIGA.config.floppy.drive[num].name && AMIGA.config.floppy.drive[num].data) { - floppy[num].diskdata = new Uint8Array(AMIGA.config.floppy.drive[num].data.length); - for (var i = 0; i < AMIGA.config.floppy.drive[num].data.length; i++) - floppy[num].diskdata[i] = AMIGA.config.floppy.drive[num].data.charCodeAt(i) & 0xff; - } + this.insert2 = function (num, forced) { + //BUG.info('Disk.insert() DF%d', num); - if (forced) { - if (!floppy[num].is_empty()) - floppy[num].eject(); - floppy[num].insert(null); - return; - } + if (AMIGA.config.floppy.drive[num].name && AMIGA.config.floppy.drive[num].data) { + floppy[num].diskdata = new Uint8Array(AMIGA.config.floppy.drive[num].data.length); + for (var i = 0; i < AMIGA.config.floppy.drive[num].data.length; i++) + floppy[num].diskdata[i] = AMIGA.config.floppy.drive[num].data.charCodeAt(i) & 0xff; + } - if (!floppy[num].is_empty() || floppy[num].dskchange_time > 0) { - floppy[num].eject(); - this.setdskchangetime(num, 100); - } else - this.setdskchangetime(num, 1); - } - this.insert = function(num) { - this.insert2(num, false); - } + if (forced) { + if (!floppy[num].is_empty()) + floppy[num].eject(); + floppy[num].insert(null); + return; + } + + if (!floppy[num].is_empty() || floppy[num].dskchange_time > 0) { + floppy[num].eject(); + this.setdskchangetime(num, 100); + } else + this.setdskchangetime(num, 1); + }; + this.insert = function (num) { + this.insert2(num, false); + }; - this.eject = function(num) { - floppy[num].eject(); - floppy[num].diskdata = null; - } + this.eject = function (num) { + floppy[num].eject(); + floppy[num].diskdata = null; + }; - this.is_empty = function(num) { - return floppy[num].is_empty(); - } + this.is_empty = function (num) { + return floppy[num].is_empty(); + }; - this.select_fetch = function(data) { - selected = (data >> 3) & 15; - this.side = 1 - ((data >> 2) & 1); - this.direction = (data >> 1) & 1; - } + this.select_fetch = function (data) { + selected = (data >> 3) & 15; + this.side = 1 - ((data >> 2) & 1); + this.direction = (data >> 1) & 1; + }; - this.select_set = function(data) { - prev_data = data; - prev_step = data & 1; - - this.select_fetch(data); - } + this.select_set = function (data) { + prev_data = data; + prev_step = data & 1; + + this.select_fetch(data); + }; - this.select = function(data) { - //BUG.info('Disk.select() $%02x', data); - var step_pulse, prev_selected, dr; + this.select = function (data) { + //BUG.info('Disk.select() $%02x', data); + var step_pulse, prev_selected, dr; - prev_selected = selected; - this.select_fetch(data); - step_pulse = data & 1; + prev_selected = selected; + this.select_fetch(data); + step_pulse = data & 1; - if ((prev_data & 0x80) != (data & 0x80)) { - for (dr = 0; dr < 4; dr++) { - if (floppy[dr].indexhackmode > 1 && !(selected & (1 << dr))) { - floppy[dr].indexhack = 1; - BUG.info('Disk.select() indexhack!'); - } - } - } - if (prev_step != step_pulse) { - prev_step = step_pulse; - if (prev_step) { - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (!((prev_selected | disabled) & (1 << dr))) { - floppy[dr].step(); - if (floppy[dr].indexhackmode > 1 && (data & 0x80)) - floppy[dr].indexhack = 1; - } - } - } - } - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (!(selected & (1 << dr)) && (prev_selected & (1 << dr)) ) { - floppy[dr].drive_id_scnt++; - floppy[dr].drive_id_scnt &= 31; - floppy[dr].idbit = (floppy[dr].drive_id & (1 << (31 - floppy[dr].drive_id_scnt))) ? 1 : 0; - - if (!(disabled & (1 << dr))) { - if ((prev_data & 0x80) == 0 || (data & 0x80) == 0) - floppy[dr].set_motor(0); /* motor off: if motor bit = 0 in prevdata or data -> turn motor on */ - else if (prev_data & 0x80) - floppy[dr].set_motor(1); /* motor on: if motor bit = 1 in prevdata only (motor flag state in data has no effect) -> turn motor off */ - } - if (dr == 0) - floppy[dr].idbit = 0; - } - } - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - var state = (!(selected & (1 << dr))) | !floppy[dr].motoroff; - if (ledstate[dr] != state) { - ledstate[dr] = state; - AMIGA.config.hooks.floppy_motor(dr, ledstate[dr]); - } - } - prev_data = data; - } + if ((prev_data & 0x80) != (data & 0x80)) { + for (dr = 0; dr < 4; dr++) { + if (floppy[dr].indexhackmode > 1 && !(selected & (1 << dr))) { + floppy[dr].indexhack = 1; + BUG.info('Disk.select() indexhack!'); + } + } + } + if (prev_step != step_pulse) { + prev_step = step_pulse; + if (prev_step) { + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (!((prev_selected | disabled) & (1 << dr))) { + floppy[dr].step(); + if (floppy[dr].indexhackmode > 1 && (data & 0x80)) + floppy[dr].indexhack = 1; + } + } + } + } + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (!(selected & (1 << dr)) && (prev_selected & (1 << dr))) { + floppy[dr].drive_id_scnt++; + floppy[dr].drive_id_scnt &= 31; + floppy[dr].idbit = (floppy[dr].drive_id & (1 << (31 - floppy[dr].drive_id_scnt))) ? 1 : 0; - this.status = function() { - var st = 0x3c; + if (!(disabled & (1 << dr))) { + if ((prev_data & 0x80) == 0 || (data & 0x80) == 0) + floppy[dr].set_motor(0); /* motor off: if motor bit = 0 in prevdata or data -> turn motor on */ + else if (prev_data & 0x80) + floppy[dr].set_motor(1); + /* motor on: if motor bit = 1 in prevdata only (motor flag state in data has no effect) -> turn motor off */ + } + if (dr == 0) + floppy[dr].idbit = 0; + } + } + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + var state = (!(selected & (1 << dr))) | !floppy[dr].motoroff; + if (ledstate[dr] != state) { + ledstate[dr] = state; + AMIGA.config.hooks.floppy_motor(dr, ledstate[dr]); + } + } + prev_data = data; + }; - for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (!((selected | disabled) & (1 << dr))) { - if (floppy[dr].is_running()) { - if (floppy[dr].dskready && !floppy[dr].indexhack) - st &= ~0x20; - } else { - if (dr > 0) { - if (floppy[dr].idbit) - st &= ~0x20; - } else { - /* non-ID internal drive: mirror real dskready */ - if (floppy[dr].dskready) - st &= ~0x20; - } - /* dskrdy needs some cycles after switching the motor off.. (Pro Tennis Tour) */ - if (dr == 0 && floppy[dr].motordelay) - st &= ~0x20; - } - if (floppy[dr].is_track0()) - st &= ~0x10; - if (floppy[dr].is_writeprotected()) - st &= ~8; - if (floppy[dr].dskchange && AMIGA.config.floppy.drive[dr].type != SAEV_Config_Floppy_Type_525_SD) - st &= ~4; - } else if (!(selected & (1 << dr))) { - if (floppy[dr].idbit) - st &= ~0x20; - } - } - //BUG.info('Disk.status() $%02x', st); - return st; - } + this.status = function () { + var st = 0x3c; + + for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (!((selected | disabled) & (1 << dr))) { + if (floppy[dr].is_running()) { + if (floppy[dr].dskready && !floppy[dr].indexhack) + st &= ~0x20; + } else { + if (dr > 0) { + if (floppy[dr].idbit) + st &= ~0x20; + } else { + /* non-ID internal drive: mirror real dskready */ + if (floppy[dr].dskready) + st &= ~0x20; + } + /* dskrdy needs some cycles after switching the motor off.. (Pro Tennis Tour) */ + if (dr == 0 && floppy[dr].motordelay) + st &= ~0x20; + } + if (floppy[dr].is_track0()) + st &= ~0x10; + if (floppy[dr].is_writeprotected()) + st &= ~8; + if (floppy[dr].dskchange && AMIGA.config.floppy.drive[dr].type != SAEV_Config_Floppy_Type_525_SD) + st &= ~4; + } else if (!(selected & (1 << dr))) { + if (floppy[dr].idbit) + st &= ~0x20; + } + } + //BUG.info('Disk.status() $%02x', st); + return st; + }; - this.fetchnextrevolution = function(num) { - floppy[num].trackspeed = floppy[num].get_floppy_speed2(); - } + this.fetchnextrevolution = function (num) { + floppy[num].trackspeed = floppy[num].get_floppy_speed2(); + }; - this.handler = function(data) { - var flag = data & 255; - var disk_sync_cycle = data >> 8; - //BUG.info('Disk.handler() data $%x, flag %d, disk_sync_cycle %d', data, flag, disk_sync_cycle); + this.handler = function (data) { + var flag = data & 255; + 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.remevent(EV2_DISK); - - this.update(disk_sync_cycle); + AMIGA.events.remevent(EV2_DISK); - if (flag & (DISK_REVOLUTION << 0)) this.fetchnextrevolution(0); - if (flag & (DISK_REVOLUTION << 1)) this.fetchnextrevolution(1); - if (flag & (DISK_REVOLUTION << 2)) this.fetchnextrevolution(2); - if (flag & (DISK_REVOLUTION << 3)) this.fetchnextrevolution(3); - if (flag & DISK_WORDSYNC) - AMIGA.INTREQ(INT_DSKSYN); - if (flag & DISK_INDEXSYNC) { - if (!indexdecay) { - indexdecay = 2; - //AMIGA.cia.setICR(CIA_B, 0x10, null); - //AMIGA.cia.diskindex(); - AMIGA.cia.SetICRB(0x10, null); - } - } - } + this.update(disk_sync_cycle); + + if (flag & (DISK_REVOLUTION << 0)) this.fetchnextrevolution(0); + if (flag & (DISK_REVOLUTION << 1)) this.fetchnextrevolution(1); + if (flag & (DISK_REVOLUTION << 2)) this.fetchnextrevolution(2); + if (flag & (DISK_REVOLUTION << 3)) this.fetchnextrevolution(3); + if (flag & DISK_WORDSYNC) + AMIGA.INTREQ(INT_DSKSYN); + if (flag & DISK_INDEXSYNC) { + if (!indexdecay) { + indexdecay = 2; + //AMIGA.cia.setICR(CIA_B, 0x10, null); + //AMIGA.cia.diskindex(); + AMIGA.cia.SetICRB(0x10, null); + } + } + }; - this.update_jitter = function() { - if (random_bits_max > 0) - disk_jitter = ((uaerand() >>> 4) % (random_bits_max - random_bits_min + 1)) + random_bits_min; - else - disk_jitter = 0; - } + this.update_jitter = function () { + if (random_bits_max > 0) + disk_jitter = ((uaerand() >>> 4) % (random_bits_max - random_bits_min + 1)) + random_bits_min; + else + disk_jitter = 0; + }; - this.updatetrackspeed = function(num, mfmpos) { - if (dskdmaen < DSKDMA_WRITE) { - var t = floppy[num].tracktiming[Math.floor(mfmpos / 8)]; - floppy[num].trackspeed = Math.floor(floppy[num].get_floppy_speed2() * t / 1000); - if (floppy[num].trackspeed < 700 || floppy[num].trackspeed > 3000) { - BUG.info('Disk.updatetrackspeed() corrupted trackspeed value %d', floppy[num].trackspeed); - floppy[num].trackspeed = 1000; - } - } - } + this.updatetrackspeed = function (num, mfmpos) { + if (dskdmaen < DSKDMA_WRITE) { + var t = floppy[num].tracktiming[Math.floor(mfmpos / 8)]; + floppy[num].trackspeed = Math.floor(floppy[num].get_floppy_speed2() * t / 1000); + if (floppy[num].trackspeed < 700 || floppy[num].trackspeed > 3000) { + BUG.info('Disk.updatetrackspeed() corrupted trackspeed value %d', floppy[num].trackspeed); + floppy[num].trackspeed = 1000; + } + } + }; - this.fifostatus = function() { - if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) - return 1; - else if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) - return -1; - return 0; - } + this.fifostatus = function () { + if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) + return 1; + else if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) + return -1; + return 0; + }; - this.dmafinished = function() { - //BUG.info('Disk.dmafinished()'); - AMIGA.INTREQ(INT_DSKBLK); - //LONGWRITEMODE = 0; - dskdmaen = DSKDMA_OFF; - dsklength = 0; - } + this.dmafinished = function () { + //BUG.info('Disk.dmafinished()'); + AMIGA.INTREQ(INT_DSKBLK); + //LONGWRITEMODE = 0; + dskdmaen = DSKDMA_OFF; + dsklength = 0; + }; - this.readdma = function() { - if (AMIGA.dmaen(DMAF_DSKEN) && bitoffset == 15 && dma_enable && dskdmaen == DSKDMA_READ && dsklength >= 0) { - if (dsklength > 0) { - if (dsklength == 1 && dsklength2 == 1) { - this.dmafinished(); - return 0; - } - /* fast disk modes, just flush the fifo */ - if (AMIGA.config.floppy.speed > SAEV_Config_Floppy_Speed_Original && fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) { - while (fifo_inuse[0]) { - var w = this.DSKDATR(); - AMIGA.mem.store16(dskpt, w); - dskpt += 2; - } - } - if (this.fifostatus() > 0) { - BUG.info('Disk.readdma() fifo overflow detected, retrying...'); - return -1; - } else { - this.DSKDAT(word); - dsklength--; - } - } - return 1; - } - return 0; - } + this.readdma = function () { + if (AMIGA.dmaen(DMAF_DSKEN) && bitoffset == 15 && dma_enable && dskdmaen == DSKDMA_READ && dsklength >= 0) { + if (dsklength > 0) { + if (dsklength == 1 && dsklength2 == 1) { + this.dmafinished(); + return 0; + } + /* fast disk modes, just flush the fifo */ + if (AMIGA.config.floppy.speed > SAEV_Config_Floppy_Speed_Original && fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) { + while (fifo_inuse[0]) { + var w = this.DSKDATR(); + AMIGA.mem.store16(dskpt, w); + dskpt += 2; + } + } + if (this.fifostatus() > 0) { + BUG.info('Disk.readdma() fifo overflow detected, retrying...'); + return -1; + } else { + this.DSKDAT(word); + dsklength--; + } + } + return 1; + } + return 0; + }; - this.update_read_nothing = function(floppybits) { - //BUG.info('Disk.update_read_nothing() floppybits %d', floppybits); - - while (floppybits >= get_floppy_speed()) { - word <<= 1; - this.readdma(); - word &= 0xffff; - if ((bitoffset & 7) == 7) { - dskbytr_val = word & 0xff; - dskbytr_val |= 0x8000; - } - bitoffset++; - bitoffset &= 15; - floppybits -= get_floppy_speed(); - } - } + this.update_read_nothing = function (floppybits) { + //BUG.info('Disk.update_read_nothing() floppybits %d', floppybits); - /*static this.read_floppy_data (struct zfile *diskfile, trackid *tid, var offset, var *dst, var len) { + while (floppybits >= get_floppy_speed()) { + word <<= 1; + this.readdma(); + word &= 0xffff; + if ((bitoffset & 7) == 7) { + dskbytr_val = word & 0xff; + dskbytr_val |= 0x8000; + } + bitoffset++; + bitoffset &= 15; + floppybits -= get_floppy_speed(); + } + }; + + /*static this.read_floppy_data (struct zfile *diskfile, Track *tid, var offset, var *dst, var len) { if (len == 0) return; zfile_fseek (diskfile, tid->offs + offset, SEEK_SET); zfile_fread (dst, 1, len, diskfile); }*/ - this.update_read = function(num, floppybits) { - //BUG.info('Disk.update_read() DF%d, floppybits %d', num, floppybits); + this.update_read = function (num, floppybits) { + //BUG.info('Disk.update_read() DF%d, floppybits %d', num, floppybits); - while (floppybits >= floppy[num].trackspeed) { - var oldmfmpos = floppy[num].mfmpos; - if (floppy[num].tracktiming[0]) - this.updatetrackspeed(num, floppy[num].mfmpos); - - word <<= 1; - if (!floppy[num].is_empty()) { - if (floppy[num].is_unformatted()) - word |= ((uaerand() & 0x1000) ? 1 : 0); - else - word |= floppy[num].getonebit(floppy[num].mfmpos); - } - word &= 0xffff; + while (floppybits >= floppy[num].trackspeed) { + var oldmfmpos = floppy[num].mfmpos; + if (floppy[num].tracktiming[0]) + this.updatetrackspeed(num, floppy[num].mfmpos); - floppy[num].mfmpos++; - floppy[num].mfmpos %= floppy[num].tracklen; - if (floppy[num].mfmpos == floppy[num].indexoffset) { - //if (floppy[num].indexhack) BUG.info('Disk.update_read() indexhack cleared'); - floppy[num].indexhack = 0; - } - if (floppy[num].mfmpos == floppy[num].skipoffset) { - this.update_jitter(); - floppy[num].mfmpos += disk_jitter; - floppy[num].mfmpos %= floppy[num].tracklen; - } - if (this.readdma() < 0) { - floppy[num].mfmpos = oldmfmpos; - return; - } - if ((bitoffset & 7) == 7) { - dskbytr_val = word & 0xff; - dskbytr_val |= 0x8000; - } - if (word == dsksync) { - dsksync_cycles = AMIGA.events.currcycle + WORDSYNC_TIME * CYCLE_UNIT; - if (dskdmaen != DSKDMA_OFF) { - //if (!dma_enable) BUG.info('Disk.update_read() Sync match, DMA started at %d', floppy[num].mfmpos); - dma_enable = true; - } - if (AMIGA.adkcon & 0x400) { - bitoffset = 15; - } - } - bitoffset++; - bitoffset &= 15; - floppybits -= floppy[num].trackspeed; - } - } + word <<= 1; + if (!floppy[num].is_empty()) { + if (floppy[num].is_unformatted()) + word |= ((uaerand() & 0x1000) ? 1 : 0); + else + word |= floppy[num].getonebit(floppy[num].mfmpos); + } + word &= 0xffff; + + floppy[num].mfmpos++; + floppy[num].mfmpos %= floppy[num].tracklen; + if (floppy[num].mfmpos == floppy[num].indexoffset) { + //if (floppy[num].indexhack) BUG.info('Disk.update_read() indexhack cleared'); + floppy[num].indexhack = 0; + } + if (floppy[num].mfmpos == floppy[num].skipoffset) { + this.update_jitter(); + floppy[num].mfmpos += disk_jitter; + floppy[num].mfmpos %= floppy[num].tracklen; + } + if (this.readdma() < 0) { + floppy[num].mfmpos = oldmfmpos; + return; + } + if ((bitoffset & 7) == 7) { + dskbytr_val = word & 0xff; + dskbytr_val |= 0x8000; + } + if (word == dsksync) { + dsksync_cycles = AMIGA.events.currcycle + WORDSYNC_TIME * CYCLE_UNIT; + if (dskdmaen != DSKDMA_OFF) { + //if (!dma_enable) BUG.info('Disk.update_read() Sync match, DMA started at %d', floppy[num].mfmpos); + dma_enable = true; + } + if (AMIGA.adkcon & 0x400) { + bitoffset = 15; + } + } + bitoffset++; + bitoffset &= 15; + floppybits -= floppy[num].trackspeed; + } + }; - this.update_write = function(num, floppybits) { - var dr, drives = [0,0,0,0]; + this.update_write = function (num, floppybits) { + var dr, drives = [0, 0, 0, 0]; - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - drives[dr] = 0; - if (floppy[dr].motoroff) - continue; - if (selected & (1 << dr)) - continue; - drives[dr] = 1; - } - while (floppybits >= floppy[num].trackspeed) { - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (drives[dr]) { - floppy[dr].mfmpos++; - floppy[dr].mfmpos %= floppy[num].tracklen; - } - } - if (AMIGA.dmaen(DMAF_DSKEN) && dskdmaen == DSKDMA_WRITE && dsklength > 0 && fifo_filled) { - bitoffset++; - bitoffset &= 15; - if (!bitoffset) { - /* fast disk modes, fill the fifo instantly */ - if (AMIGA.config.floppy.speed > SAEV_Config_Floppy_Speed_Original && !fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) { - while (!fifo_inuse[2]) { - var w = AMIGA.mem.load16(dskpt); - this.DSKDAT(w); - dskpt += 2; - } - } - if (this.fifostatus() >= 0) { - var w = this.DSKDATR(); - for (dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) { - if (drives[dr]) { - floppy[dr].bigmfmbuf[floppy[dr].mfmpos >> 4] = w; - floppy[dr].bigmfmbuf[(floppy[dr].mfmpos >> 4) + 1] = 0x5555; - floppy[dr].writtento = 1; - } - } - dsklength--; - if (dsklength <= 0) { - this.dmafinished(); - for (dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) { - floppy[dr].writtento = 0; - if (floppy[dr].motoroff) - continue; - if (selected & (1 << dr)) - continue; - floppy[dr].write_data(); - } - } - } - } - } - floppybits -= floppy[num].trackspeed; - } - } + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + drives[dr] = 0; + if (floppy[dr].motoroff) + continue; + if (selected & (1 << dr)) + continue; + drives[dr] = 1; + } + while (floppybits >= floppy[num].trackspeed) { + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (drives[dr]) { + floppy[dr].mfmpos++; + floppy[dr].mfmpos %= floppy[num].tracklen; + } + } + if (AMIGA.dmaen(DMAF_DSKEN) && dskdmaen == DSKDMA_WRITE && dsklength > 0 && fifo_filled) { + bitoffset++; + bitoffset &= 15; + if (!bitoffset) { + /* fast disk modes, fill the fifo instantly */ + if (AMIGA.config.floppy.speed > SAEV_Config_Floppy_Speed_Original && !fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) { + while (!fifo_inuse[2]) { + var w = AMIGA.mem.load16(dskpt); + this.DSKDAT(w); + dskpt += 2; + } + } + if (this.fifostatus() >= 0) { + var w = this.DSKDATR(); + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (drives[dr]) { + floppy[dr].bigmfmbuf[floppy[dr].mfmpos >> 4] = w; + floppy[dr].bigmfmbuf[(floppy[dr].mfmpos >> 4) + 1] = 0x5555; + floppy[dr].writtento = 1; + } + } + dsklength--; + if (dsklength <= 0) { + this.dmafinished(); + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + floppy[dr].writtento = 0; + if (floppy[dr].motoroff) + continue; + if (selected & (1 << dr)) + continue; + floppy[dr].write_data(); + } + } + } + } + } + floppybits -= floppy[num].trackspeed; + } + }; - this.doupdate_predict = function(startcycle) { - //BUG.info('Disk.doupdate_predict() startcycle %d', startcycle); - var finaleventcycle = AMIGA.playfield.maxhpos << 8; - var finaleventflag = 0; + this.doupdate_predict = function (startcycle) { + //BUG.info('Disk.doupdate_predict() startcycle %d', startcycle); + var finaleventcycle = AMIGA.playfield.maxhpos << 8; + var finaleventflag = 0; + + for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (selected & (1 << dr)) + continue; + else if (floppy[dr].motoroff || !floppy[dr].trackspeed) + continue; + + var diskevent_flag = 0; + var tword = word; + var countcycle = startcycle + (floppy[dr].floppybitcounter % floppy[dr].trackspeed); + var mfmpos = floppy[dr].mfmpos; + while (countcycle < (AMIGA.playfield.maxhpos << 8)) { + if (floppy[dr].tracktiming[0]) + this.updatetrackspeed(dr, mfmpos); + if (dskdmaen != DSKDMA_WRITE || (dskdmaen == DSKDMA_WRITE && !dma_enable)) { + tword <<= 1; + if (!floppy[dr].is_empty()) { + if (floppy[dr].is_unformatted()) + tword |= ((uaerand() & 0x1000) ? 1 : 0); + else + tword |= floppy[dr].getonebit(mfmpos); + } + tword &= 0xffff; + if (tword == dsksync && dsksync != 0) + diskevent_flag |= DISK_WORDSYNC; + } + mfmpos++; + mfmpos %= floppy[dr].tracklen; + if (mfmpos == 0) + diskevent_flag |= (DISK_REVOLUTION << dr); + if (mfmpos == floppy[dr].indexoffset) + diskevent_flag |= DISK_INDEXSYNC; + if (dskdmaen != DSKDMA_WRITE && mfmpos == floppy[dr].skipoffset) { + this.update_jitter(); + var skipcnt = disk_jitter; + while (skipcnt-- > 0) { + mfmpos++; + mfmpos %= floppy[dr].tracklen; + if (mfmpos == 0) + diskevent_flag |= (DISK_REVOLUTION << dr); + if (mfmpos == floppy[dr].indexoffset) + diskevent_flag |= DISK_INDEXSYNC; + } + } + if (diskevent_flag) + break; + countcycle += floppy[dr].trackspeed; + } + if (floppy[dr].tracktiming[0]) + this.updatetrackspeed(dr, floppy[dr].mfmpos); + if (diskevent_flag && countcycle < finaleventcycle) { + finaleventcycle = countcycle; + finaleventflag = diskevent_flag; + } + } + + if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.playfield.maxhpos) + AMIGA.events.newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag); + }; + + this.update = function (tohpos) { + //if (tohpos != 227) BUG.info('Disk.update() disk_hpos %f, to hpos %d', disk_hpos / CYCLE_UNIT, tohpos); + var dr; + var cycles; + + if (disk_hpos < 0) { + disk_hpos = -disk_hpos; + return; + } + cycles = (tohpos << 8) - disk_hpos; + if (cycles <= 0) + return; + + disk_hpos += cycles; + if (disk_hpos >= (AMIGA.playfield.maxhpos << 8)) + disk_hpos %= (1 << 8); + + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (floppy[dr].motoroff || !floppy[dr].tracklen || !floppy[dr].trackspeed) + continue; + floppy[dr].floppybitcounter += cycles; + if (selected & (1 << dr)) { + floppy[dr].mfmpos += Math.floor(floppy[dr].floppybitcounter / floppy[dr].trackspeed); + floppy[dr].mfmpos %= floppy[dr].tracklen; + floppy[dr].floppybitcounter %= floppy[dr].trackspeed; + continue; + } + if (floppy[dr].diskfile) + floppy[dr].fill_bigbuf(0); + floppy[dr].mfmpos %= floppy[dr].tracklen; + } + var didaccess = 0; + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (selected & (1 << dr)) + continue; + else if (floppy[dr].motoroff || !floppy[dr].trackspeed) + continue; + /* write dma and wordsync enabled: read until wordsync match found */ + if (dskdmaen == DSKDMA_WRITE && dma_enable) + this.update_write(dr, floppy[dr].floppybitcounter); + else + this.update_read(dr, floppy[dr].floppybitcounter); + + floppy[dr].floppybitcounter %= floppy[dr].trackspeed; + didaccess = 1; + } + /* no floppy selected but read dma */ + if (!didaccess && dskdmaen == DSKDMA_READ) + this.update_read_nothing(cycles); + + /* instantly finish dma if dsklen==0 and wordsync detected */ + if (dskdmaen != DSKDMA_OFF && dma_enable && dsklength2 == 0 && dsklength == 0) + this.dmafinished(); + + this.doupdate_predict(disk_hpos); + }; + + this.dma_debugmsg = function () { + BUG.info('Disk.dma_debugmsg() LEN=%04x (%d) SYNC=%04x PT=%08x ADKCON=%04x', dsklength, dsklength, (AMIGA.adkcon & 0x400) ? dsksync : 0xffff, dskpt, AMIGA.adkcon); + }; + + this.start = function () { + fifo_filled = false; + for (var i = 0; i < 3; i++) + fifo_inuse[i] = 0; + + for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (!(selected & (1 << dr))) { + if (dskdmaen == DSKDMA_WRITE) { + floppy[dr].tracklen = LONGWRITEMODE ? FLOPPY_WRITE_MAXLEN : (AMIGA.config.video.ntsc ? 6399 : 6334) * floppy[dr].ddhd * 8 * 2; + floppy[dr].trackspeed = get_floppy_speed(); + floppy[dr].skipoffset = -1; + floppy[dr].updatemfmpos(); + } + + var tr = floppy[dr].cyl * 2 + this.side; + if (floppy[dr].trackdata[tr].type == TRACK_RAW1) { + floppy[dr].mfmpos = 0; + bitoffset = 0; + } + } + floppy[dr].floppybitcounter = 0; + } + dma_enable = (AMIGA.adkcon & 0x400) ? false : true; + }; + + this.check_change = function () { + //if (currprefs.floppy_speed != changed_prefs.floppy_speed) currprefs.floppy_speed = changed_prefs.floppy_speed; + /*for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { + if (currprefs.floppyslots[i].dfxtype != changed_prefs.floppyslots[i].dfxtype) { + currprefs.floppyslots[i].dfxtype = changed_prefs.floppyslots[i].dfxtype; + floppy[i].reset(); + } + }*/ + }; + + this.vsync = function () { + this.check_change(); + + for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { + //if (drv->dskchange_time == 0 && _tcscmp (currprefs.floppyslots[i].df, changed_prefs.floppyslots[i].df)) this.insert(i, changed_prefs.floppyslots[i].df); + floppy[i].vsync(); + } + }; + + this.hsync = function () { + for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (floppy[dr].steplimit) + floppy[dr].steplimit--; + } + if (indexdecay) + indexdecay--; + if (linecounter) { + if (!(--linecounter)) + this.dmafinished(); + return; + } + this.update(AMIGA.playfield.maxhpos); + }; + + this.update_adkcon = function (v) { + var vold = AMIGA.adkcon; + var vnew = AMIGA.adkcon; + if (v & 0x8000) + vnew |= v & 0x7FFF; + else + vnew &= ~v; + + if ((vnew & 0x400) && !(vold & 0x400)) + bitoffset = 0; + }; + + this.motordelay_func = function (unit) { + //BUG.info('Disk.motordelay_func(%d)', unit); + floppy[unit].motordelay = false; + }; + + this.DSKLEN = function (v, hpos) { + //BUG.info('Disk.DSKLEN() $%04x', v); + var dr, prev = dsklen; + + this.update(hpos); + + if ((v & 0x8000) && (dsklen & 0x8000)) { + dskdmaen = DSKDMA_READ; + this.start(); + } + if (!(v & 0x8000)) { + if (dskdmaen != DSKDMA_OFF) { + if (dskdmaen == DSKDMA_READ) + BUG.info('Disk.DSKLEN() warning: Disk read DMA aborted, %d words left', dsklength); + else if (dskdmaen == DSKDMA_WRITE) { + BUG.info('Disk.DSKLEN() warning: Disk write DMA aborted, %d words left', dsklength); + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (floppy[dr].writtento) floppy[dr].write_data(); + } + } + dskdmaen = DSKDMA_OFF; + } + } + dsklen = v; + dsklength2 = dsklength = dsklen & 0x3fff; + + if (dskdmaen == DSKDMA_OFF) + return; + if (dsklength == 0 && dma_enable) { + this.dmafinished(); + return; + } + if ((v & 0x4000) && (prev & 0x4000)) { + if (dsklength == 0) + return; + if (dsklength == 1) { + this.dmafinished(); + return; + } + dskdmaen = DSKDMA_WRITE; + this.start(); + } + + var motormask = 0; + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + floppy[dr].writtento = 0; + if (floppy[dr].motoroff) + continue; + motormask |= 1 << dr; + if ((selected & (1 << dr)) == 0) + break; + } + var noselected = dr == 4; + + /* Try to make floppy access from Kickstart faster. */ + if (dskdmaen != DSKDMA_READ && dskdmaen != DSKDMA_WRITE) + return; + + /* no turbo mode if any selected drive has non-standard ADF */ + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + if (selected & (1 << dr)) + continue; + if (floppy[dr].filetype != ADF_NORMAL) + break; + } + if (dr < MAX_FLOPPY_DRIVES) + return; + + { + var done = false; + for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + var pos, i; + + if (selected & (1 << dr)) + continue; + else if (floppy[dr].motoroff) + continue; + else if (!floppy[dr].useturbo && AMIGA.config.floppy.speed != SAEV_Config_Floppy_Speed_Turbo) + continue; + + pos = floppy[dr].mfmpos & ~15; + floppy[dr].fill_bigbuf(0); + + if (dskdmaen == DSKDMA_READ) { //TURBO read + if (AMIGA.adkcon & 0x400) { + for (i = 0; i < floppy[dr].tracklen; i += 16) { + pos += 16; + pos %= floppy[dr].tracklen; + if (floppy[dr].bigmfmbuf[pos >> 4] == dsksync) { + pos += 16; + pos %= floppy[dr].tracklen; + break; + } + } + if (i >= floppy[dr].tracklen) + return; + } + while (dsklength-- > 0) { + AMIGA.mem.store16(dskpt, floppy[dr].bigmfmbuf[pos >> 4]); + dskpt += 2; + pos += 16; + pos %= floppy[dr].tracklen; + } + AMIGA.INTREQ(INT_DSKSYN); + done = true; + } else if (dskdmaen == DSKDMA_WRITE) { //TURBO write + for (i = 0; i < dsklength; i++) { + floppy[dr].bigmfmbuf[pos >> 4] = AMIGA.mem.load16(dskpt + i * 2); + pos += 16; + pos %= floppy[dr].tracklen; + } + floppy[dr].write_data(); + done = true; + } + } + if (!done && noselected) { + while (dsklength-- > 0) { + if (dskdmaen == DSKDMA_WRITE) + AMIGA.mem.load16(dskpt); + else + AMIGA.mem.store16(dskpt, 0); + dskpt += 2; + } + AMIGA.INTREQ(INT_DSKSYN); + done = true; + } + if (done) { + linecounter = 2; + dskdmaen = DSKDMA_OFF; + } + } + }; - for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (selected & (1 << dr)) - continue; - else if (floppy[dr].motoroff || !floppy[dr].trackspeed) - continue; - - var diskevent_flag = 0; - var tword = word; - var countcycle = startcycle + (floppy[dr].floppybitcounter % floppy[dr].trackspeed); - var mfmpos = floppy[dr].mfmpos; - while (countcycle < (AMIGA.playfield.maxhpos << 8)) { - if (floppy[dr].tracktiming[0]) - this.updatetrackspeed(dr, mfmpos); - if (dskdmaen != DSKDMA_WRITE || (dskdmaen == DSKDMA_WRITE && !dma_enable)) { - tword <<= 1; - if (!floppy[dr].is_empty()) { - if (floppy[dr].is_unformatted()) - tword |= ((uaerand() & 0x1000) ? 1 : 0); - else - tword |= floppy[dr].getonebit(mfmpos); - } - tword &= 0xffff; - if (tword == dsksync && dsksync != 0) - diskevent_flag |= DISK_WORDSYNC; - } - mfmpos++; - mfmpos %= floppy[dr].tracklen; - if (mfmpos == 0) - diskevent_flag |= (DISK_REVOLUTION << dr); - if (mfmpos == floppy[dr].indexoffset) - diskevent_flag |= DISK_INDEXSYNC; - if (dskdmaen != DSKDMA_WRITE && mfmpos == floppy[dr].skipoffset) { - this.update_jitter(); - var skipcnt = disk_jitter; - while (skipcnt-- > 0) { - mfmpos++; - mfmpos %= floppy[dr].tracklen; - if (mfmpos == 0) - diskevent_flag |= (DISK_REVOLUTION << dr); - if (mfmpos == floppy[dr].indexoffset) - diskevent_flag |= DISK_INDEXSYNC; - } - } - if (diskevent_flag) - break; - countcycle += floppy[dr].trackspeed; - } - if (floppy[dr].tracktiming[0]) - this.updatetrackspeed(dr, floppy[dr].mfmpos); - if (diskevent_flag && countcycle < finaleventcycle) { - finaleventcycle = countcycle; - finaleventflag = diskevent_flag; - } - } + this.DSKBYTR = function (hpos) { + this.update(hpos); - if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.playfield.maxhpos) - AMIGA.events.newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag); - } + var v = dskbytr_val; + dskbytr_val &= ~0x8000; + if (word == dsksync && AMIGA.events.cycles_in_range(dsksync_cycles)) + v |= 0x1000; + if (dskdmaen != DSKDMA_OFF && AMIGA.dmaen(DMAF_DSKEN)) + v |= 0x4000; + if (dsklen & 0x4000) + v |= 0x2000; - this.update = function(tohpos) { - //if (tohpos != 227) BUG.info('Disk.update() disk_hpos %f, to hpos %d', disk_hpos / CYCLE_UNIT, tohpos); - var dr; - var cycles; - var startcycle = disk_hpos; + //BUG.info('Disk.DSKBYTR() %x', v); + return v; + }; - if (disk_hpos < 0) { - disk_hpos = -disk_hpos; - return; - } - cycles = (tohpos << 8) - disk_hpos; - if (cycles <= 0) - return; + this.DSKSYNC = function (v, hpos) { + if (v == dsksync) + return; - disk_hpos += cycles; - if (disk_hpos >= (AMIGA.playfield.maxhpos << 8)) - disk_hpos %= (1 << 8); + this.update(hpos); + dsksync = v; + }; - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (floppy[dr].motoroff || !floppy[dr].tracklen || !floppy[dr].trackspeed) - continue; - floppy[dr].floppybitcounter += cycles; - if (selected & (1 << dr)) { - floppy[dr].mfmpos += Math.floor(floppy[dr].floppybitcounter / floppy[dr].trackspeed); - floppy[dr].mfmpos %= floppy[dr].tracklen; - floppy[dr].floppybitcounter %= floppy[dr].trackspeed; - continue; - } - if (floppy[dr].diskfile) - floppy[dr].fill_bigbuf(0); - floppy[dr].mfmpos %= floppy[dr].tracklen; - } - var didaccess = 0; - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (selected & (1 << dr)) - continue; - else if (floppy[dr].motoroff || !floppy[dr].trackspeed) - continue; - /* write dma and wordsync enabled: read until wordsync match found */ - if (dskdmaen == DSKDMA_WRITE && dma_enable) - this.update_write(dr, floppy[dr].floppybitcounter); - else - this.update_read(dr, floppy[dr].floppybitcounter); + this.DSKDAT = function (v) { + if (fifo_inuse[2]) { + BUG.info('Disk.DSKDAT() FIFO overflow!'); + return; + } + fifo_inuse[2] = fifo_inuse[1]; + fifo[2] = fifo[1]; + fifo_inuse[1] = fifo_inuse[0]; + fifo[1] = fifo[0]; + fifo_inuse[0] = dskdmaen == DSKDMA_WRITE ? 2 : 1; + fifo[0] = v; + fifo_filled = true; + }; - floppy[dr].floppybitcounter %= floppy[dr].trackspeed; - didaccess = 1; - } - /* no floppy selected but read dma */ - if (!didaccess && dskdmaen == DSKDMA_READ) - this.update_read_nothing(cycles); + this.DSKDATR = function () { + var i, v = 0; - /* instantly finish dma if dsklen==0 and wordsync detected */ - if (dskdmaen != DSKDMA_OFF && dma_enable && dsklength2 == 0 && dsklength == 0) - this.dmafinished(); + for (i = 2; i >= 0; i--) { + if (fifo_inuse[i]) { + fifo_inuse[i] = 0; + v = fifo[i]; + break; + } + } + if (i < 0) + BUG.info('Disk.DSKDATR() FIFO underflow!'); + else if (dskdmaen > 0 && dskdmaen < 3 && dsklength <= 0 && this.fifostatus() < 0) + this.dmafinished(); - this.doupdate_predict(disk_hpos); - } + //BUG.info('Disk.DSKDATR() %x', v); + return v; + }; + + this.DSKPTH = function (v) { + dskpt = ((v << 16) | (dskpt & 0xffff)) >>> 0; + }; + + this.DSKPTL = function (v) { + dskpt = ((dskpt & 0xffff0000) | v) >>> 0; + }; - this.dma_debugmsg = function() { - BUG.info('Disk.dma_debugmsg() LEN=%04x (%d) SYNC=%04x PT=%08x ADKCON=%04x', dsklength, dsklength, (AMIGA.adkcon & 0x400) ? dsksync : 0xffff, dskpt, AMIGA.adkcon); - } - - this.start = function() { - fifo_filled = false; - for (var i = 0; i < 3; i++) - fifo_inuse[i] = 0; - - for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (!(selected & (1 << dr))) { - if (dskdmaen == DSKDMA_WRITE) { - floppy[dr].tracklen = LONGWRITEMODE ? FLOPPY_WRITE_MAXLEN : (AMIGA.config.video.ntsc ? 6399 : 6334) * floppy[dr].ddhd * 8 * 2; - floppy[dr].trackspeed = get_floppy_speed(); - floppy[dr].skipoffset = -1; - floppy[dr].updatemfmpos(); - } - - var tr = floppy[dr].cyl * 2 + this.side; - if (floppy[dr].trackdata[tr].type == TRACK_RAW1) { - floppy[dr].mfmpos = 0; - bitoffset = 0; - } - } - floppy[dr].floppybitcounter = 0; - } - dma_enable = (AMIGA.adkcon & 0x400) ? false : true; - } - - this.check_change = function() { - //if (currprefs.floppy_speed != changed_prefs.floppy_speed) currprefs.floppy_speed = changed_prefs.floppy_speed; - /*for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { - if (currprefs.floppyslots[i].dfxtype != changed_prefs.floppyslots[i].dfxtype) { - currprefs.floppyslots[i].dfxtype = changed_prefs.floppyslots[i].dfxtype; - floppy[i].reset(); - } - }*/ - } - - this.vsync = function() { - this.check_change(); - - for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { - //if (drv->dskchange_time == 0 && _tcscmp (currprefs.floppyslots[i].df, changed_prefs.floppyslots[i].df)) this.insert(i, changed_prefs.floppyslots[i].df); - floppy[i].vsync(); - } - } - - this.hsync = function() { - for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (floppy[dr].steplimit) - floppy[dr].steplimit--; - } - if (indexdecay) - indexdecay--; - if (linecounter) { - if (!(--linecounter)) - this.dmafinished(); - return; - } - this.update(AMIGA.playfield.maxhpos); - } - - this.update_adkcon = function(v) { - var vold = AMIGA.adkcon; - var vnew = AMIGA.adkcon; - if (v & 0x8000) - vnew |= v & 0x7FFF; - else - vnew &= ~v; - - if ((vnew & 0x400) && !(vold & 0x400)) - bitoffset = 0; - } - - this.motordelay_func = function(unit) { - //BUG.info('Disk.motordelay_func(%d)', unit); - floppy[unit].motordelay = false; - } - - this.DSKLEN = function(v, hpos) - { - //BUG.info('Disk.DSKLEN() $%04x', v); - var dr, prev = dsklen; - - this.update(hpos); - - if ((v & 0x8000) && (dsklen & 0x8000)) { - dskdmaen = DSKDMA_READ; - this.start(); - } - if (!(v & 0x8000)) { - if (dskdmaen != DSKDMA_OFF) { - if (dskdmaen == DSKDMA_READ) - BUG.info('Disk.DSKLEN() warning: Disk read DMA aborted, %d words left', dsklength); - else if (dskdmaen == DSKDMA_WRITE) { - BUG.info('Disk.DSKLEN() warning: Disk write DMA aborted, %d words left', dsklength); - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (floppy[dr].writtento) floppy[dr].write_data(); - } - } - dskdmaen = DSKDMA_OFF; - } - } - dsklen = v; - dsklength2 = dsklength = dsklen & 0x3fff; - - if (dskdmaen == DSKDMA_OFF) - return; - if (dsklength == 0 && dma_enable) { - this.dmafinished(); - return; - } - if ((v & 0x4000) && (prev & 0x4000)) { - if (dsklength == 0) - return; - if (dsklength == 1) { - this.dmafinished(); - return; - } - dskdmaen = DSKDMA_WRITE; - this.start(); - } - - var motormask = 0; - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - floppy[dr].writtento = 0; - if (floppy[dr].motoroff) - continue; - motormask |= 1 << dr; - if ((selected & (1 << dr)) == 0) - break; - } - var noselected = dr == 4; - - /* Try to make floppy access from Kickstart faster. */ - if (dskdmaen != DSKDMA_READ && dskdmaen != DSKDMA_WRITE) - return; - - /* no turbo mode if any selected drive has non-standard ADF */ - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - if (selected & (1 << dr)) - continue; - if (floppy[dr].filetype != ADF_NORMAL) - break; - } - if (dr < MAX_FLOPPY_DRIVES) - return; - - { - var done = false; - for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { - var pos, i; - - if (selected & (1 << dr)) - continue; - else if (floppy[dr].motoroff) - continue; - else if (!floppy[dr].useturbo && AMIGA.config.floppy.speed != SAEV_Config_Floppy_Speed_Turbo) - continue; - - pos = floppy[dr].mfmpos & ~15; - floppy[dr].fill_bigbuf(0); - - if (dskdmaen == DSKDMA_READ) { //TURBO read - if (AMIGA.adkcon & 0x400) { - for (i = 0; i < floppy[dr].tracklen; i += 16) { - pos += 16; - pos %= floppy[dr].tracklen; - if (floppy[dr].bigmfmbuf[pos >> 4] == dsksync) { - pos += 16; - pos %= floppy[dr].tracklen; - break; - } - } - if (i >= floppy[dr].tracklen) - return; - } - while (dsklength-- > 0) { - AMIGA.mem.store16(dskpt, floppy[dr].bigmfmbuf[pos >> 4]); - dskpt += 2; - pos += 16; - pos %= floppy[dr].tracklen; - } - AMIGA.INTREQ(INT_DSKSYN); - done = true; - } else if (dskdmaen == DSKDMA_WRITE) { //TURBO write - for (i = 0; i < dsklength; i++) { - var w = AMIGA.mem.load16(dskpt + i * 2); - floppy[dr].bigmfmbuf[pos >> 4] = w; - pos += 16; - pos %= floppy[dr].tracklen; - } - floppy[dr].write_data(); - done = true; - } - } - if (!done && noselected) { - while (dsklength-- > 0) { - if (dskdmaen == DSKDMA_WRITE) - AMIGA.mem.load16(dskpt); - else - AMIGA.mem.store16(dskpt, 0); - dskpt += 2; - } - AMIGA.INTREQ(INT_DSKSYN); - done = true; - } - if (done) { - linecounter = 2; - dskdmaen = DSKDMA_OFF; - } - } - } - - this.DSKBYTR = function(hpos) { - this.update(hpos); - - var v = dskbytr_val; - dskbytr_val &= ~0x8000; - if (word == dsksync && AMIGA.events.cycles_in_range(dsksync_cycles)) - v |= 0x1000; - if (dskdmaen != DSKDMA_OFF && AMIGA.dmaen(DMAF_DSKEN)) - v |= 0x4000; - if (dsklen & 0x4000) - v |= 0x2000; - - //BUG.info('Disk.DSKBYTR() %x', v); - return v; - } - - this.DSKSYNC = function(v, hpos) { - if (v == dsksync) - return; - - this.update(hpos); - dsksync = v; - } - - this.DSKDAT = function(v) { - if (fifo_inuse[2]) { - BUG.info('Disk.DSKDAT() FIFO overflow!'); - return; - } - fifo_inuse[2] = fifo_inuse[1]; - fifo[2] = fifo[1]; - fifo_inuse[1] = fifo_inuse[0]; - fifo[1] = fifo[0]; - fifo_inuse[0] = dskdmaen == DSKDMA_WRITE ? 2 : 1; - fifo[0] = v; - fifo_filled = true; - } - - this.DSKDATR = function() { - var i, v = 0; - - for (i = 2; i >= 0; i--) { - if (fifo_inuse[i]) { - fifo_inuse[i] = 0; - v = fifo[i]; - break; - } - } - if (i < 0) - BUG.info('Disk.DSKDATR() FIFO underflow!'); - else if (dskdmaen > 0 && dskdmaen < 3 && dsklength <= 0 && this.fifostatus() < 0) - this.dmafinished(); - - //BUG.info('Disk.DSKDATR() %x', v); - return v; - } - - this.DSKPTH = function(v) { - dskpt = ((v << 16) | (dskpt & 0xffff)) >>> 0; - } - - this.DSKPTL = function(v) { - dskpt = ((dskpt & 0xffff0000) | v) >>> 0; - } - - this.getpt = function() { - var pt = dskpt; - dskpt += 2; - return pt; - } + this.getpt = function () { + var pt = dskpt; + dskpt += 2; + return pt; + }; this.dmal = function() { var dmal = 0; @@ -1661,7 +1654,7 @@ function Disk() { if (dsklength == 1) dmal &= ~(16 + 32 + 4 + 8); } else { - dmal = 16 * (fifo_inuse[0] ? 1 : 0) + 4 * (fifo_inuse[1] ? 1 : 0) + 1 * (fifo_inuse[2] ? 1 : 0); + dmal = 16 * (fifo_inuse[0] ? 1 : 0) + 4 * (fifo_inuse[1] ? 1 : 0) + (fifo_inuse[2] ? 1 : 0); } } return dmal; diff --git a/sae/events.js b/sae/events.js index 9d8c7b7..30e0a9c 100644 --- a/sae/events.js +++ b/sae/events.js @@ -8,7 +8,7 @@ * **************************************************************************/ -function Event() { +function Event1() { this.active = false; this.evtime = 0; this.oldcycles = 0; @@ -31,7 +31,7 @@ function Events() { var nextevent = 0; var nextevent2 = 0; - var dmal = 0 + var dmal = 0; var dmal_hpos = 0; var vsynctimebase = 0; @@ -45,18 +45,18 @@ function Events() { //var vsync_counter = 0; const MAVG_VSYNC_SIZE = 128; - var ma_frameskipt = new mavg(MAVG_VSYNC_SIZE); + 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 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; @@ -65,279 +65,295 @@ function Events() { /*---------------------------------*/ - this.setup = function() { - if (this.eventtab === null) { - this.eventtab = new Array(EV_MAX); - for (var i = 0; i < EV_MAX; i++) - this.eventtab[i] = new Event(); + this.setup = function () { + if (this.eventtab === null) { + this.eventtab = new Array(EV_MAX); + for (var i = 0; i < EV_MAX; i++) + this.eventtab[i] = new Event1(); - this.eventtab[EV_CIA].handler = function() { AMIGA.cia.handler(); } - this.eventtab[EV_AUDIO].handler = function() { AMIGA.audio.handler(); } - 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[EV_CIA].handler = function () { + AMIGA.cia.handler(); + }; + this.eventtab[EV_AUDIO].handler = function () { + AMIGA.audio.handler(); + }; + 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.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.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.reset = function() { - dmal = 0 - dmal_hpos = 0; - - this.currcycle = 0; - nextevent = CYCLE_MAX; - nextevent2 = EV2_MISC; + this.calc_vsynctimebase(AMIGA.config.video.ntsc ? 60 : 50); + }; - 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; - this.eventtab[i].evtime = 0; - this.eventtab[i].oldcycles = 0; - } - for (var i = 0; i < EV2_MAX; i++) { - this.eventtab2[i].active = false; - this.eventtab2[i].evtime = 0; - } - this.eventtab[EV_HSYNC].evtime = 227 * CYCLE_UNIT; /* 0xe3 */ - this.eventtab[EV_HSYNC].active = true; + this.reset = function () { + dmal = 0; + dmal_hpos = 0; - this.schedule(); - } + 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; + this.eventtab[i].evtime = 0; + this.eventtab[i].oldcycles = 0; + } + for (var i = 0; i < EV2_MAX; i++) { + this.eventtab2[i].active = false; + this.eventtab2[i].evtime = 0; + } + this.eventtab[EV_HSYNC].evtime = 227 * CYCLE_UNIT; + /* 0xe3 */ + this.eventtab[EV_HSYNC].active = true; + + this.schedule(); + }; - this.calc_vsynctimebase = function(hz) { - vsynctimebase = Math.floor(SYNCBASE / hz); - //vsynctimebase >>= 1;//(AMIGA.config.video.framerate > 1 ? 1 : 0); - } + 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); - } + this.hpos = function () { + return Math.floor((this.currcycle - this.eventtab[EV_HSYNC].oldcycles) * CYCLE_UNIT_INV); + }; - this.cycles_in_range = function(endcycles) { - return (endcycles - this.currcycle > 0); - } + this.cycles_in_range = function (endcycles) { + return (endcycles - this.currcycle > 0); + }; /*---------------------------------*/ - this.schedule = function() { - var mintime = CYCLE_MAX; + this.schedule = function () { + var mintime = CYCLE_MAX; - for (var i = 0; i < EV_MAX; i++) { - if (this.eventtab[i].active) { - var evtime = this.eventtab[i].evtime - this.currcycle; - if (evtime < mintime) mintime = evtime; - } - } - nextevent = this.currcycle + mintime; - } + for (var i = 0; i < EV_MAX; i++) { + if (this.eventtab[i].active) { + var evtime = this.eventtab[i].evtime - this.currcycle; + if (evtime < mintime) mintime = evtime; + } + } + nextevent = this.currcycle + mintime; + }; - this.cycle = function(cycles) { - if (vsyncresume) { - vsyncresume = false; - this.hsync_handler_post(1); - } - - while ((nextevent - this.currcycle) <= cycles) { - if (is_syncline) { - 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; - } + this.cycle = function (cycles) { + if (vsyncresume) { + vsyncresume = false; + this.hsync_handler_post(1); + } - cycles -= nextevent - this.currcycle; - this.currcycle = nextevent; + while ((nextevent - this.currcycle) <= cycles) { + if (is_syncline) { + 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; + } - 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; - } + 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; + 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; + 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); + var recheck = true; + while (recheck) { + recheck = false; + mintime = CYCLE_MAX; - 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--; - } + 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); - 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(); - } + 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 = function(t, data, func) { - if (t <= 0) - func(data); - else - this.newevent2_x(t * CYCLE_UNIT, data, func); - } + this.newevent2_x = function (t, data, func) { + var et = this.currcycle + t; + var no = nextevent2; + for (; ;) { + if (!this.eventtab2[no].active) + break; - 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(); - } + no++; + if (no == EV2_MAX) + no = EV2_MISC; + if (no == nextevent2) { + BUG.info('newevent2_x() out of events!'); + return; + } + } + nextevent2 = no; - this.remevent = function(no) { - if (this.eventtab2[no].active) { - this.eventtab2[no].active = false; - //BUG.info('remevent() %d', 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; + this.dmal_emu = function (v) { + if (!(AMIGA.dmacon & DMAF_DMAEN)) + return; - var hpos = this.hpos(); - if (v >= 6) { - v -= 6; - var nr = v >> 1; - var pt = AMIGA.audio.getpt(nr, (v & 1) != 0); - //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.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.chip.data[pt >>> 1] = dat; - } - } - } - } + //var hpos = this.hpos(); + var dat, pt; + if (v >= 6) { + v -= 6; + var nr = v >> 1; + pt = AMIGA.audio.getpt(nr, (v & 1) != 0); + //var dat = AMIGA.mem.load16_chip(pt); + dat = AMIGA.mem.chip.data[pt >>> 1]; + AMIGA.custom.last_value = dat; + AMIGA.audio.AUDxDAT(nr, dat); + } else { + var w = v & 1; + pt = AMIGA.disk.getpt(); + if (w) { + if (AMIGA.disk.fifostatus() <= 0) { + //var dat = AMIGA.mem.load16_chip(pt); + dat = AMIGA.mem.chip.data[pt >>> 1]; + AMIGA.custom.last_value = dat; + AMIGA.disk.DSKDAT(dat); + } + } else { + if (AMIGA.disk.fifostatus() >= 0) { + dat = AMIGA.disk.DSKDATR(); + //AMIGA.mem.store16_chip(pt, dat); + AMIGA.mem.chip.data[pt >>> 1] = dat; + } + } + } + }; - 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_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_hsync = function() { - if (dmal) BUG.info('dmal_hsync() DMAL error!? %04x', dmal); - dmal = AMIGA.audio.dmal(); - dmal <<= 6; - dmal |= AMIGA.disk.dmal(); - if (dmal) { - dmal_hpos = 0; - this.newevent(EV2_DMAL, 7, 13); - } - } + this.dmal_hsync = function () { + if (dmal) BUG.info('dmal_hsync() DMAL error!? %04x', dmal); + dmal = AMIGA.audio.dmal(); + dmal <<= 6; + dmal |= AMIGA.disk.dmal(); + if (dmal) { + dmal_hpos = 0; + this.newevent(EV2_DMAL, 7, 13); + } + }; /*---------------------------------*/ function sleep(ms) { var start = new Date().getTime(); - while ((new Date().getTime() - start) < ms); + while ((new Date().getTime() - start) < ms) {} } function read_processor_time() { @@ -356,256 +372,260 @@ function Events() { return v; } - this.framewait = function() { - var clockadjust = 0; - var vstb = vsynctimebase; + this.framewait = function () { + var clockadjust = 0; + var curr_time; - var frameskipt_avg = ma_frameskipt.set(frameskiptime); - frameskiptime = 0; + 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(); + is_syncline = 0; - var adjust = 0; - if (Math.floor(curr_time - vsyncwaittime) > 0 && Math.floor(curr_time - vsyncwaittime) < (vstb >> 1)) - adjust += curr_time - vsyncwaittime; - adjust += clockadjust; - - console.log(adjust); - - vsyncwaittime = curr_time + vstb - adjust; - vsyncmintime = curr_time; + if (AMIGA.config.cpu.speed < 0) { + if (!frame_rendered) + frame_rendered = AMIGA.playfield.render_screen(false); - var max = Math.floor(vstb - adjust); - if (max < 0) { - max = 0; - vsynctimeperline = 1; - } else - vsynctimeperline = Math.floor(max / (AMIGA.playfield.maxvpos_nom + 1)); + curr_time = read_processor_time(); - vsyncmaxtime = curr_time + max; - } else { - var start; - var t = 0; + var adjust = 0; + if (Math.floor(curr_time - vsyncwaittime) > 0 && Math.floor(curr_time - vsyncwaittime) < (vsynctimebase >> 1)) + adjust += curr_time - vsyncwaittime; + adjust += clockadjust; - 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; - - var curr_time = read_processor_time(); - vsyncmintime = curr_time; - vsyncmaxtime = vsyncwaittime = curr_time + vstb; - 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 > Math.floor(vstb / 3)) - vsynctimeperline = Math.floor(vstb / 3); - } - } + console.log(adjust); - this.framewait2 = function() { - 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 (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 (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 = 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('*'); - } - } - } - } + vsyncwaittime = curr_time + vsynctimebase - adjust; + vsyncmintime = curr_time; + + var max = Math.floor(vsynctimebase - adjust); + if (max < 0) { + max = 0; + vsynctimeperline = 1; + } else + vsynctimeperline = Math.floor(max / (AMIGA.playfield.maxvpos_nom + 1)); + + vsyncmaxtime = curr_time + max; + } else { + 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 = read_processor_time(); + vsyncmintime = curr_time; + vsyncmaxtime = vsyncwaittime = curr_time + vsynctimebase; + if (frame_rendered) { + frame_shown = AMIGA.playfield.show_screen(); + t += read_processor_time() - curr_time; + } + t += frameskipt_avg; + + vsynctimeperline = Math.floor((vsynctimebase - t) / 3); + if (vsynctimeperline < 0) + vsynctimeperline = 0; + else if (vsynctimeperline > Math.floor(vsynctimebase / 3)) + vsynctimeperline = Math.floor(vsynctimebase / 3); + } + }; + + this.framewait2 = function () { + 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 (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 (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 = 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_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; + 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; - } + var now = read_processor_time(); + var last = now - lastframetime; + lastframetime = now; - fps_mavg.set(last / 10); - idle_mavg.set(idletime / 10); - idletime = 0; + if (AMIGA.config.video.framerate > 1) { + last <<= 1; + hz /= 2; + } - frametime += last; - timeframes++; + fps_mavg.set(last / 10); + idle_mavg.set(idletime / 10); + idletime = 0; - 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); + frametime += last; + timeframes++; - if ((timeframes & 15) == 0) { - AMIGA.config.hooks.fps(Math.round(fps * 0.1)); - AMIGA.config.hooks.cpu(Math.round(idle * 0.1)); - } - } - } + 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.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); + 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); - this.eventtab[EV_HSYNC].evtime = this.currcycle + AMIGA.playfield.maxhpos * CYCLE_UNIT; - this.eventtab[EV_HSYNC].oldcycles = this.currcycle; - } + 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(); + this.vsync_handler_pre = function () { + //AMIGA.audio.vsync(); //empty + AMIGA.cia.vsync_prehandler(); - if (!vsync_rendered) { - 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(); + if (!vsync_rendered) { + 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(); + AMIGA.playfield.show_screen(); - this.fpscounter(); - vsync_rendered = false; - frame_shown = false; - frame_rendered = false; + this.fpscounter(); + vsync_rendered = false; + frame_shown = false; + frame_rendered = false; - AMIGA.playfield.checklacecount(null); - } + AMIGA.playfield.checklacecount(null); + }; var cia_hsync = 256; - this.hsync_handler_post = function(onvsync) { - AMIGA.copper.last_copper_hpos = 0; + 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); - - AMIGA.playfield.hsync_handler_post(); - AMIGA.custom.last_value = 0xffff; + 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.config.blitter.immediate && AMIGA.blitter.getState() != BLT_done && AMIGA.dmaen(DMAF_BPLEN) && AMIGA.playfield.getDiwstate() == DIW_WAITING_STOP) - AMIGA.blitter.slowdown(); + AMIGA.playfield.hsync_handler_post(); + AMIGA.custom.last_value = 0xffff; - 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; - }*/ - AMIGA.playfield.vpos = 0; - this.vsync_handler_post(); - AMIGA.playfield.vpos_count = 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); - } - this.dmal_hsync(); - this.framewait2(); - AMIGA.playfield.hsync_handler_post_nextline_how(); - AMIGA.copper.reset2(); + if (!AMIGA.config.blitter.immediate && AMIGA.blitter.getState() != BLT_done && AMIGA.dmaen(DMAF_BPLEN) && AMIGA.playfield.getDiwstate() == DIW_WAITING_STOP) + AMIGA.blitter.slowdown(); - if (CUSTOM_SIMPLE) - AMIGA.playfield.do_sprites(0); + 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; + }*/ + AMIGA.playfield.vpos = 0; + this.vsync_handler_post(); + AMIGA.playfield.vpos_count = 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); + } + this.dmal_hsync(); + this.framewait2(); + AMIGA.playfield.hsync_handler_post_nextline_how(); + AMIGA.copper.reset2(); - //AMIGA.copper.check(2); - AMIGA.playfield.hsync_handler_post_diw_change(); - } + if (CUSTOM_SIMPLE) + AMIGA.playfield.do_sprites(0); + + //AMIGA.copper.check(2); + AMIGA.playfield.hsync_handler_post_diw_change(); + }; - 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.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(); diff --git a/sae/expansion.js b/sae/expansion.js index 254d95f..e822def 100644 --- a/sae/expansion.js +++ b/sae/expansion.js @@ -14,7 +14,7 @@ function Board_A2058() { const MEM_2MB = 0x06; const MEM_1MB = 0x05; const MEM_512KB = 0x04; - const MEM_256KB = 0x03; + //const MEM_256KB = 0x03; //const MEM_128KB = 0x02; //const MEM_64KB = 0x01; @@ -80,74 +80,74 @@ function Expansion() { var boards = []; var board = 0; - this.setup = function() { - mem.data = new Uint16Array(0x8000); - boards = []; - if (AMIGA.mem.fast.size > 0) - boards[0] = new Board_A2058(); - else - boards[0] = new Board_Dummy(); + this.setup = function () { + mem.data = new Uint16Array(0x8000); + boards = []; + if (AMIGA.mem.fast.size > 0) + boards[0] = new Board_A2058(); + else + boards[0] = new Board_Dummy(); - for (var i = 1; i < MAX_EXPANSION_BOARDS; i++) - boards[i] = new Board_Dummy(); - } + for (var i = 1; i < MAX_EXPANSION_BOARDS; i++) + boards[i] = new Board_Dummy(); + }; - this.reset = function() { - board = 0; - this.config(board); - } + this.reset = function () { + board = 0; + this.config(board); + }; - this.clear = function() { - for (var i = 0; i < mem.data.length; i++) - mem.data[i] = 0; - } + this.clear = function () { + for (var i = 0; i < mem.data.length; i++) + mem.data[i] = 0; + }; this.write = function (addr, value) { - mem.data[(addr >> 1)] = (value & 0xf0) << 8; - mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12; - } + mem.data[(addr >> 1)] = (value & 0xf0) << 8; + mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12; + }; this.load8 = function (addr) { - addr &= 0xffff; - var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff; - if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42) - return value; - return ~value & 0xff; - } + addr &= 0xffff; + var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff; + if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42) + return value; + return ~value & 0xff; + }; this.store8 = function (addr, value) { - switch (addr & 0xff) { - case 0x30: - case 0x32: - mem.hi = 0; - mem.lo = 0; - this.write(0x48, 0x00); - break; + switch (addr & 0xff) { + case 0x30: + case 0x32: + mem.hi = 0; + mem.lo = 0; + this.write(0x48, 0x00); + break; - case 0x48: - mem.hi = value; - //BUG.info('Expansion.store8() board %d done.', board + 1); - ++board; - if (board <= MAX_EXPANSION_BOARDS) - this.config(board); - else - this.clear(); - break; + case 0x48: + mem.hi = value; + //BUG.info('Expansion.store8() board %d done.', board + 1); + ++board; + if (board <= MAX_EXPANSION_BOARDS) + this.config(board); + else + this.clear(); + break; - case 0x4a: - mem.lo = value; - break; + case 0x4a: + mem.lo = value; + break; - case 0x4c: - //BUG.info('Expansion.store8() board %d faild.', board + 1); - ++board; - if (board <= MAX_EXPANSION_BOARDS) - this.config(board); - else - this.clear(); - break; - } - } + case 0x4c: + //BUG.info('Expansion.store8() board %d faild.', board + 1); + ++board; + if (board <= MAX_EXPANSION_BOARDS) + this.config(board); + else + this.clear(); + break; + } + }; this.config = function(board) { var info = boards[board].info(); diff --git a/sae/input.js b/sae/input.js index 9035c55..ca95075 100644 --- a/sae/input.js +++ b/sae/input.js @@ -19,55 +19,55 @@ function Mouse() { var lx = -1; var ly = -1; - this.reset = function() { - this.button = [0, 0, 0]; - cx = cy = 0; - lx = ly = -1; - } + this.reset = function () { + this.button = [0, 0, 0]; + cx = cy = 0; + lx = ly = -1; + }; this.mousedown = function (e) { - e = e || window.event; - if (!e) return; + e = e || window.event; + if (!e) return; - this.button[e.button] = true; - } + this.button[e.button] = true; + }; this.mouseup = function (e) { - e = e || window.event; - if (!e) return; + e = e || window.event; + if (!e) return; - this.button[e.button] = false; - } + this.button[e.button] = false; + }; this.mouseover = function (e) { - //AMIGA.video.hideCursor(1); - this.mousemove(e); - lx = cx; - ly = cy; - } + //AMIGA.video.hideCursor(1); + this.mousemove(e); + lx = cx; + ly = cy; + }; this.mouseout = function (e) { - //AMIGA.video.hideCursor(0); - this.mouseup(e); - } + //AMIGA.video.hideCursor(0); + this.mouseup(e); + }; this.mousemove = function (e) { - e = e || window.event; - if (!e || !AMIGA.video) return; + e = e || window.event; + if (!e || !AMIGA.video) return; - if (e.pageX || e.pageY) { - cx = e.pageX; - cy = e.pageY; - } else if (e.clientX || e.clientY) { - cx = e.clientX; - cy = e.clientY; - } - if (lx == -1) { - lx = cx; - ly = cy; - } - //BUG.info('USER() mousemove %d %d', cx, cy); - } + if (e.pageX || e.pageY) { + cx = e.pageX; + cy = e.pageY; + } else if (e.clientX || e.clientY) { + cx = e.clientX; + cy = e.clientY; + } + if (lx == -1) { + lx = cx; + ly = cy; + } + //BUG.info('USER() mousemove %d %d', cx, cy); + }; this.update = function() { if (lx != -1) { @@ -97,13 +97,11 @@ function Joystick(type) { this.button = [false, false, false]; this.state = [false, false, false, false]; this.dir = 0; - var x = 0; - var y = 0; - this.reset = function() { - this.button = [false, false, false]; - this.state = [false, false, false, false]; - } + this.reset = function () { + this.button = [false, false, false]; + this.state = [false, false, false, false]; + }; this.update = function() { var u = this.state[1]; @@ -144,7 +142,7 @@ function Keyboard() { const RAWKEY_0 = 0x0A; const RAWKEY_MINUS = 0x0B; const RAWKEY_EQUAL = 0x0C; - const RAWKEY_BACKSLASH = 0x0D; + //const RAWKEY_BACKSLASH = 0x0D; const RAWKEY_KP_0 = 0x0F; const RAWKEY_Q = 0x10; const RAWKEY_W = 0x11; @@ -194,7 +192,7 @@ function Keyboard() { const RAWKEY_SPACE = 0x40; const RAWKEY_BACKSPACE = 0x41; const RAWKEY_TAB = 0x42; - const RAWKEY_KP_ENTER = 0x43; + //const RAWKEY_KP_ENTER = 0x43; const RAWKEY_RETURN = 0x44; const RAWKEY_ESCAPE = 0x45; const RAWKEY_DELETE = 0x46; @@ -226,7 +224,7 @@ function Keyboard() { const RAWKEY_CAPSLOCK = 0x62; const RAWKEY_CONTROL = 0x63; const RAWKEY_LALT = 0x64; - const RAWKEY_RALT = 0x65; + //const RAWKEY_RALT = 0x65; const RAWKEY_LAMIGA = 0x66; const RAWKEY_RAMIGA = 0x67; /*const RAWKEY_SCRLOCK = 0x6B; @@ -247,9 +245,9 @@ function Keyboard() { const RAWKEY_NM_WHEEL_LEFT = 0x7C; const RAWKEY_NM_WHEEL_RIGHT = 0x7D; const RAWKEY_NM_BUTTON_FOURTH = 0x7E;*/ - const RAWKEY_BAD_CODE = 0xF9; + /*const RAWKEY_BAD_CODE = 0xF9; const RAWKEY_BUFFER_OVERFLOW = 0xFA; - const RAWKEY_SELFTEST_FAILED = 0xFC; + const RAWKEY_SELFTEST_FAILED = 0xFC;*/ const RAWKEY_INIT_POWER_UP = 0xFD; const RAWKEY_TERM_POWER_UP = 0xFE; @@ -486,214 +484,313 @@ function Keyboard() { function _onkeydown(e) { AMIGA.input.keyboard.handleKey(e, true); } function _onkeyup(e) { AMIGA.input.keyboard.handleKey(e, false); } - this.setup = function() { - /*document.onkeydown = function (e) { - AMIGA.input.keyboard.keydownup(e, true); - } - document.onkeyup = function (e) { - AMIGA.input.keyboard.keydownup(e, false); - }*/ - window.document.addEventListener('keydown', _onkeydown, false); - window.document.addEventListener('keyup', _onkeyup, false); - } + this.setup = function () { + /*document.onkeydown = function (e) { + AMIGA.input.keyboard.keydownup(e, true); + } + document.onkeyup = function (e) { + AMIGA.input.keyboard.keydownup(e, false); + }*/ + window.document.addEventListener('keydown', _onkeydown, false); + window.document.addEventListener('keyup', _onkeyup, false); + }; - this.cleanup = function() { - //BUG.info('Keyboard.cleanup()'); - //document.onkeydown = null; - //document.onkeyup = null; - window.document.removeEventListener('keydown', _onkeydown, false); - window.document.removeEventListener('keyup', _onkeyup, false); - } + this.cleanup = function () { + //BUG.info('Keyboard.cleanup()'); + //document.onkeydown = null; + //document.onkeyup = null; + window.document.removeEventListener('keydown', _onkeydown, false); + window.document.removeEventListener('keyup', _onkeyup, false); + }; - this.reset = function() { - for (var i = 0; i < MAXKEYS; i++) keyState[i] = false; - state = 0; - code = 0; - first = last = 0; - hsynccnt = 0; - this.lostsynccnt = 0; - } + this.reset = function () { + for (var i = 0; i < MAXKEYS; i++) keyState[i] = false; + state = 0; + code = 0; + first = last = 0; + hsynccnt = 0; + this.lostsynccnt = 0; + }; - this.keysAvail = function() { - return first != last; - } + this.keysAvail = function () { + return first != last; + }; - this.nextKey = function() { - //assert (first != last); - var key = keyBuf[last]; - if (++last == KEYBUFSIZE) last = 0; - return key; - } + this.nextKey = function () { + //assert (first != last); + var key = keyBuf[last]; + if (++last == KEYBUFSIZE) last = 0; + return key; + }; this.recordKey = function (kc) { - var next = first + 1; + var next = first + 1; - if (next == KEYBUFSIZE) next = 0; - if (next == last) { - BUG.info('Keyboard() buffer overrun!'); - return false; - } - keyBuf[first] = kc; - first = next; - return true; - } + if (next == KEYBUFSIZE) next = 0; + if (next == last) { + BUG.info('Keyboard() buffer overrun!'); + return false; + } + keyBuf[first] = kc; + first = next; + return true; + }; - this.processKey = function (code, down) { - /* Caps-lock */ - if (code == 20) { - if (down) { - capsLock = !capsLock; - if (!capsLock) return; - } else { - if (capsLock) return; - } - } - - /* joystick emul */ - if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { - var l,u,r,d,f1,f2; - switch (AMIGA.config.ports[0].move) { - case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; } - case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; } - case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; } - } - f1 = AMIGA.config.ports[0].fire[0]; - f2 = AMIGA.config.ports[0].fire[1]; - switch (code) { - case f1: { AMIGA.input.joystick[0].button[0] = down; break; } - case f2: { AMIGA.input.joystick[0].button[1] = down; break; } - case l: { AMIGA.input.joystick[0].state[0] = down; if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false; break; } - case u: { AMIGA.input.joystick[0].state[1] = down; if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false; break; } - case r: { AMIGA.input.joystick[0].state[2] = down; if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false; break; } - case d: { AMIGA.input.joystick[0].state[3] = down; if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false; break; } - } - } - if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { - var l,u,r,d,f1,f2; - switch (AMIGA.config.ports[1].move) { - case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; } - case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; } - case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; } - } - f1 = AMIGA.config.ports[1].fire[0]; - f2 = AMIGA.config.ports[1].fire[1]; - switch (code) { - case f1: { AMIGA.input.joystick[1].button[0] = down; break; } - case f2: { AMIGA.input.joystick[1].button[1] = down; break; } - case l: { AMIGA.input.joystick[1].state[0] = down; if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false; break; } - case u: { AMIGA.input.joystick[1].state[1] = down; if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false; break; } - case r: { AMIGA.input.joystick[1].state[2] = down; if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false; break; } - case d: { AMIGA.input.joystick[1].state[3] = down; if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false; break; } - } - } - - if (!AMIGA.config.keyboard.enabled) - return; + this.processKey = function (code, down) { + /* Caps-lock */ + if (code == 20) { + if (down) { + capsLock = !capsLock; + if (!capsLock) return; + } else { + if (capsLock) return; + } + } - /* map shift-keys (team17 pinball games) */ - if (AMIGA.config.keyboard.mapShift) { - switch (code) { - case 37: { //left arrow - var rawkey = RAWKEY_LSHIFT; - if (!down) { - this.recordKey((rawkey << 1) | 1); - } else { - this.recordKey(rawkey << 1); - } - //break; - return; - } - case 39: { //right arrow - var rawkey = RAWKEY_RSHIFT; - if (!down) { - this.recordKey((rawkey << 1) | 1); - } else { - this.recordKey(rawkey << 1); - } - //break; - return; - } - } - } + /* joystick emul */ + if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { + var l, u, r, d, f1, f2; + switch (AMIGA.config.ports[0].move) { + case SAEV_Config_Ports_Move_Arrows: + { + l = 37; + u = 38; + r = 39; + d = 40; + break; + } + case SAEV_Config_Ports_Move_Numpad: + { + l = 100; + u = 104; + r = 102; + d = 101; + break; + } + case SAEV_Config_Ports_Move_WASD: + { + l = 65; + u = 87; + r = 68; + d = 83; + break; + } + } + f1 = AMIGA.config.ports[0].fire[0]; + f2 = AMIGA.config.ports[0].fire[1]; + switch (code) { + case f1: + { + AMIGA.input.joystick[0].button[0] = down; + break; + } + case f2: + { + AMIGA.input.joystick[0].button[1] = down; + break; + } + case l: + { + AMIGA.input.joystick[0].state[0] = down; + if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false; + break; + } + case u: + { + AMIGA.input.joystick[0].state[1] = down; + if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false; + break; + } + case r: + { + AMIGA.input.joystick[0].state[2] = down; + if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false; + break; + } + case d: + { + AMIGA.input.joystick[0].state[3] = down; + if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false; + break; + } + } + } + if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { + var l, u, r, d, f1, f2; + switch (AMIGA.config.ports[1].move) { + case SAEV_Config_Ports_Move_Arrows: + { + l = 37; + u = 38; + r = 39; + d = 40; + break; + } + case SAEV_Config_Ports_Move_Numpad: + { + l = 100; + u = 104; + r = 102; + d = 101; + break; + } + case SAEV_Config_Ports_Move_WASD: + { + l = 65; + u = 87; + r = 68; + d = 83; + break; + } + } + f1 = AMIGA.config.ports[1].fire[0]; + f2 = AMIGA.config.ports[1].fire[1]; + switch (code) { + case f1: + { + AMIGA.input.joystick[1].button[0] = down; + break; + } + case f2: + { + AMIGA.input.joystick[1].button[1] = down; + break; + } + case l: + { + AMIGA.input.joystick[1].state[0] = down; + if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false; + break; + } + case u: + { + AMIGA.input.joystick[1].state[1] = down; + if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false; + break; + } + case r: + { + AMIGA.input.joystick[1].state[2] = down; + if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false; + break; + } + case d: + { + AMIGA.input.joystick[1].state[3] = down; + if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false; + break; + } + } + } - var rawkey = false; - if (BrowserDetect.browser == 'Firefox') { - if (typeof(mozKeyCodeMap[code]) != 'undefined') - rawkey = mozKeyCodeMap[code]; - } else { - if (typeof(defKeyCodeMap[code]) != 'undefined') - rawkey = defKeyCodeMap[code]; - } - //BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey); + if (!AMIGA.config.keyboard.enabled) + return; - if (rawkey !== false) { - if (down) - this.recordKey(rawkey << 1); - else - this.recordKey((rawkey << 1) | 1); - } - } + /* map shift-keys (team17 pinball games) */ + if (AMIGA.config.keyboard.mapShift) { + switch (code) { + case 37: + { //left arrow + if (!down) { + this.recordKey((RAWKEY_LSHIFT << 1) | 1); + } else { + this.recordKey(RAWKEY_LSHIFT << 1); + } + //break; + return; + } + case 39: + { //right arrow + if (!down) { + this.recordKey((RAWKEY_RSHIFT << 1) | 1); + } else { + this.recordKey(RAWKEY_RSHIFT << 1); + } + //break; + return; + } + } + } + + var rawkey = false; + if (BrowserDetect.browser == 'Firefox') { + if (typeof(mozKeyCodeMap[code]) != 'undefined') + rawkey = mozKeyCodeMap[code]; + } else { + if (typeof(defKeyCodeMap[code]) != 'undefined') + rawkey = defKeyCodeMap[code]; + } + //BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey); + + if (rawkey !== false) { + if (down) + this.recordKey(rawkey << 1); + else + this.recordKey((rawkey << 1) | 1); + } + }; this.handleKey = function (e, down) { - e = e || window.event; - var code = e.which ? e.which : e.keyCode; + e = e || window.event; + var code = e.which ? e.which : e.keyCode; - if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12 - e.preventDefault(); - - //BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0); + if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12 + e.preventDefault(); - /* Ctrl-Alt fix */ - if (!down && code == 17 && keyState[18]) { - keyState[18] = false; - this.processKey(18, keyState[18]); - } - - var oldstate = keyState[code]; - if (down && !keyState[code]) { - keyState[code] = true; - } - else if (!down) { - keyState[code] = false; - } - if (keyState[code] != oldstate) { - this.processKey(code, keyState[code]); - } - } + //BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0); + + /* Ctrl-Alt fix */ + if (!down && code == 17 && keyState[18]) { + keyState[18] = false; + this.processKey(18, keyState[18]); + } + + var oldstate = keyState[code]; + if (down && !keyState[code]) { + keyState[code] = true; + } + else if (!down) { + keyState[code] = false; + } + if (keyState[code] != oldstate) { + this.processKey(code, keyState[code]); + } + }; this.setCode = function (keycode) { - code = ~((keycode << 1) | (keycode >> 7)) & 0xff; - } + code = ~((keycode << 1) | (keycode >> 7)) & 0xff; + }; - this.keyReq = function() { - this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; /* 8 frames * 8 bits */ + this.keyReq = function () { + this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; + /* 8 frames * 8 bits */ - //AMIGA.cia.setICR(CIA_A, 8, code); - AMIGA.cia.SetICRA(8, code); - } + //AMIGA.cia.setICR(CIA_A, 8, code); + AMIGA.cia.SetICRA(8, code); + }; - this.hsync = function() { - if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) { - switch (state) { - case 0: - code = 0; - state++; - break; - case 1: - this.setCode(RAWKEY_INIT_POWER_UP); - state++; - break; - case 2: - this.setCode(RAWKEY_TERM_POWER_UP); - state++; - break; - case 3: - code = ~this.nextKey() & 0xff; - break; - } - this.keyReq(); - } - } + this.hsync = function () { + if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) { + switch (state) { + case 0: + code = 0; + state++; + break; + case 1: + this.setCode(RAWKEY_INIT_POWER_UP); + state++; + break; + case 2: + this.setCode(RAWKEY_TERM_POWER_UP); + state++; + break; + case 3: + code = ~this.nextKey() & 0xff; + break; + } + this.keyReq(); + } + }; this.vsync = function() { if (this.lostsynccnt > 0) { @@ -719,82 +816,82 @@ function Input() { count: 0 }; - this.setup = function() { - this.keyboard.setup(); - } + this.setup = function () { + this.keyboard.setup(); + }; - this.cleanup = function() { - this.keyboard.cleanup(); - } + this.cleanup = function () { + this.keyboard.cleanup(); + }; - this.reset = function() { - this.mouse.reset(); - this.joystick[0].reset(); - this.joystick[1].reset(); - this.keyboard.reset(); - potgo.data = 0; - potgo.count = 0; - } + this.reset = function () { + this.mouse.reset(); + this.joystick[0].reset(); + this.joystick[1].reset(); + this.keyboard.reset(); + potgo.data = 0; + potgo.count = 0; + }; this.POTGO = function (v) { - //BUG.info('Input.POTGO() $%04x', v); - potgo.data = v; - } + //BUG.info('Input.POTGO() $%04x', v); + potgo.data = v; + }; - this.POTGOR = function() { - var v = (potgo.data | (potgo.data << 1)) & 0xaa00; - v |= v >> 1; + this.POTGOR = function () { + var v = (potgo.data | (potgo.data << 1)) & 0xaa00; + v |= v >> 1; - if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { - if (this.mouse.button[2]) v &= 0xfbff; - if (this.mouse.button[1]) v &= 0xfeff; - } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { - if (this.joystick[0].button[1]) v &= 0xfbff; - if (this.joystick[0].button[2]) v &= 0xfeff; - } - if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { - if (this.joystick[1].button[1]) v &= 0xbfff; - if (this.joystick[1].button[2]) v &= 0xefff; - } - //BUG.info('Input.POTGOR() $%04x', v); - return v; - } + if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { + if (this.mouse.button[2]) v &= 0xfbff; + if (this.mouse.button[1]) v &= 0xfeff; + } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { + if (this.joystick[0].button[1]) v &= 0xfbff; + if (this.joystick[0].button[2]) v &= 0xfeff; + } + if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { + if (this.joystick[1].button[1]) v &= 0xbfff; + if (this.joystick[1].button[2]) v &= 0xefff; + } + //BUG.info('Input.POTGOR() $%04x', v); + return v; + }; - this.POT0DAT = function() { - if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { - if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff); - if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff; - } - //BUG.info('Input.POT0DAT() $%04x', v); - return potgo.count; - } + this.POT0DAT = function () { + if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { + if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff); + if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff; + } + //BUG.info('Input.POT0DAT() $%04x', v); + return potgo.count; + }; - this.POT1DAT = function() { - //BUG.info('Input.POT1DAT() NOT IMPLEMENTED'); - return 0xffff; - } + this.POT1DAT = function () { + //BUG.info('Input.POT1DAT() NOT IMPLEMENTED'); + return 0xffff; + }; - this.JOY0DAT = function() { - if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { - this.mouse.update(); - return this.mouse.pos; - } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { - this.joystick[0].update(); - return this.joystick[0].dir; - } - return 0xffff; - } + this.JOY0DAT = function () { + if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { + this.mouse.update(); + return this.mouse.pos; + } else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) { + this.joystick[0].update(); + return this.joystick[0].dir; + } + return 0xffff; + }; - this.JOY1DAT = function() { - if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) { - this.mouse.update(); - return this.mouse.pos; - } else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { - this.joystick[1].update(); - return this.joystick[1].dir; - } - return 0xffff; - } + this.JOY1DAT = function () { + if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) { + this.mouse.update(); + return this.mouse.pos; + } else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) { + this.joystick[1].update(); + return this.joystick[1].dir; + } + return 0xffff; + }; this.JOYTEST = function (v) { //BUG.info('Input.JOYTEST() $%04x', v); diff --git a/sae/memory.js b/sae/memory.js index 343b325..de3ad47 100644 --- a/sae/memory.js +++ b/sae/memory.js @@ -40,8 +40,8 @@ function Memory() { align: 0, data: null, lower: 0, - upper: 0, - }; + upper: 0 + }; this.slow = { enabled: false, size: 0, @@ -91,11 +91,11 @@ function Memory() { lower: 0x00E80000, upper: 0x00E90000 }; - this.aros = { + /*this.aros = { cached: false, rom: '', ext: '' - }; + };*/ function getChipSize(v) { switch (v) { @@ -154,396 +154,403 @@ function Memory() { } }*/ - this.setup = function() { - this.chip.size = getChipSize(AMIGA.config.ram.chip.size); - this.chip.align = this.chip.size >>> 1; - this.chip.data = new Uint16Array(this.chip.align); for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0; - this.chip.lower = 0; - this.chip.upper = this.chip.size; + this.setup = function () { + this.chip.size = getChipSize(AMIGA.config.ram.chip.size); + this.chip.align = this.chip.size >>> 1; + this.chip.data = new Uint16Array(this.chip.align); + for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0; + this.chip.lower = 0; + this.chip.upper = this.chip.size; - if (AMIGA.config.ram.slow.size) { - this.slow.enabled = true; - this.slow.size = getSlowSize(AMIGA.config.ram.slow.size); - this.slow.align = this.slow.size >>> 1; - this.slow.data = new Uint16Array(this.slow.align); for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0; - this.slow.upper = this.slow.lower + this.slow.size; - } else { - this.slow.enabled = false; - this.slow.size = 0; - this.slow.align = 0; - this.slow.data = null; - this.slow.upper = 0; - } - if (AMIGA.config.ram.fast.size) { - this.fast.enabled = true; - this.fast.size = getFastSize(AMIGA.config.ram.fast.size); - this.fast.align = this.fast.size >>> 1; - this.fast.data = new Uint16Array(this.fast.align); for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0; - this.fast.upper = this.fast.lower + this.fast.size; - } else { - this.fast.enabled = false; - this.fast.size = 0; - this.fast.align = 0; - this.fast.data = null; - this.fast.upper = 0; - } - BUG.info('Memory.init() chip %d, slow %d, fast %d', this.chip.size >>> 10, this.slow.size >>> 10, this.fast.size >>> 10); + if (AMIGA.config.ram.slow.size) { + this.slow.enabled = true; + this.slow.size = getSlowSize(AMIGA.config.ram.slow.size); + this.slow.align = this.slow.size >>> 1; + this.slow.data = new Uint16Array(this.slow.align); + for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0; + this.slow.upper = this.slow.lower + this.slow.size; + } else { + this.slow.enabled = false; + this.slow.size = 0; + this.slow.align = 0; + this.slow.data = null; + this.slow.upper = 0; + } + if (AMIGA.config.ram.fast.size) { + this.fast.enabled = true; + this.fast.size = getFastSize(AMIGA.config.ram.fast.size); + this.fast.align = this.fast.size >>> 1; + this.fast.data = new Uint16Array(this.fast.align); + for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0; + this.fast.upper = this.fast.lower + this.fast.size; + } else { + this.fast.enabled = false; + this.fast.size = 0; + this.fast.align = 0; + this.fast.data = null; + this.fast.upper = 0; + } + BUG.info('Memory.init() chip %d, slow %d, fast %d', this.chip.size >>> 10, this.slow.size >>> 10, this.fast.size >>> 10); - this.rom.size = getROMSize(AMIGA.config.rom.size); - this.rom.align = this.rom.size >>> 1; - this.rom.data = new Uint16Array(this.rom.align); for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0; - - this.res_d8.data = new Uint16Array(this.res_d8.align); for (var i = 0; i < this.res_d8.align; i++) this.res_d8.data[i] = 0; - this.res_e0.data = new Uint16Array(this.res_e0.align); for (var i = 0; i < this.res_e0.align; i++) this.res_e0.data[i] = 0; - this.res_f0.data = new Uint16Array(this.res_f0.align); for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0; - - this.copy_rom(AMIGA.config.rom.data); + this.rom.size = getROMSize(AMIGA.config.rom.size); + this.rom.align = this.rom.size >>> 1; + this.rom.data = new Uint16Array(this.rom.align); + for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0; - if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) { - if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0) - this.copy_e0(AMIGA.config.ext.data); - else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0) - this.copy_f0(AMIGA.config.ext.data); - } - //this.mirror_rom_to_chipram(); + this.res_d8.data = new Uint16Array(this.res_d8.align); + for (var i = 0; i < this.res_d8.align; i++) this.res_d8.data[i] = 0; + this.res_e0.data = new Uint16Array(this.res_e0.align); + for (var i = 0; i < this.res_e0.align; i++) this.res_e0.data[i] = 0; + this.res_f0.data = new Uint16Array(this.res_f0.align); + for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0; - /*if (AMIGA.config.rom.mode == 1) { - if (!this.aros.cached) { - BUG.info('Memory.setup() AROS-ROM is not cached, downloading...'); - AMIGA.loading += 2; - loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) { - AMIGA.mem.aros.cached = true; - AMIGA.mem.aros.rom = data; - AMIGA.mem.copy_rom(data); - AMIGA.loading--; - }); - loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) { - AMIGA.mem.aros.cached = true; - AMIGA.mem.aros.ext = data; - AMIGA.mem.copy_e0(data); - AMIGA.loading--; - }); - } else { - BUG.info('Memory.setup() AROS-ROM is cached, download skipped.'); - this.copy_rom(this.aros.rom); - this.copy_e0(this.aros.ext); - } - } else { - AMIGA.loading++; - loadLocal('cfg_rom_name', function(event) { - AMIGA.mem.copy_rom(event.target.result); - AMIGA.loading--; - }); - if (AMIGA.config.ext.size > 0) { - AMIGA.loading++; - loadLocal('cfg_ext_name', function(event) { - if (AMIGA.config.ext.addr == 0xe00000) - AMIGA.mem.copy_e0(event.target.result); - else - AMIGA.mem.copy_f0(event.target.result); + this.copy_rom(AMIGA.config.rom.data); - AMIGA.loading--; - }); - } - }*/ - } + if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) { + if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0) + this.copy_e0(AMIGA.config.ext.data); + else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0) + this.copy_f0(AMIGA.config.ext.data); + } + //this.mirror_rom_to_chipram(); + + /*if (AMIGA.config.rom.mode == 1) { + if (!this.aros.cached) { + BUG.info('Memory.setup() AROS-ROM is not cached, downloading...'); + AMIGA.loading += 2; + loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) { + AMIGA.mem.aros.cached = true; + AMIGA.mem.aros.rom = data; + AMIGA.mem.copy_rom(data); + AMIGA.loading--; + }); + loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) { + AMIGA.mem.aros.cached = true; + AMIGA.mem.aros.ext = data; + AMIGA.mem.copy_e0(data); + AMIGA.loading--; + }); + } else { + BUG.info('Memory.setup() AROS-ROM is cached, download skipped.'); + this.copy_rom(this.aros.rom); + this.copy_e0(this.aros.ext); + } + } else { + AMIGA.loading++; + loadLocal('cfg_rom_name', function(event) { + AMIGA.mem.copy_rom(event.target.result); + AMIGA.loading--; + }); + if (AMIGA.config.ext.size > 0) { + AMIGA.loading++; + loadLocal('cfg_ext_name', function(event) { + if (AMIGA.config.ext.addr == 0xe00000) + AMIGA.mem.copy_e0(event.target.result); + else + AMIGA.mem.copy_f0(event.target.result); + + AMIGA.loading--; + }); + } + }*/ + }; this.load8 = function (addr) { - //BUG.info('Memory.load8() addr $%08x', addr); + //BUG.info('Memory.load8() addr $%08x', addr); - if (addr >= 0x000000 && addr < this.chip.size) { - return (addr & 1) ? (this.chip.data[addr >>> 1] & 0xff) : (this.chip.data[addr >>> 1] >> 8); - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) { - return (addr & 1) ? (this.slow.data[(addr - this.slow.lower) >>> 1] & 0xff) : (this.slow.data[(addr - this.slow.lower) >>> 1] >> 8); - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) { - return (addr & 1) ? (this.fast.data[(addr - this.fast.lower) >>> 1] & 0xff) : (this.fast.data[(addr - this.fast.lower) >>> 1] >> 8); - } - else if (addr >= this.rom.lower && addr < this.rom.upper) { - return (addr & 1) ? (this.rom.data[(addr - this.rom.lower) >>> 1] & 0xff) : (this.rom.data[(addr - this.rom.lower) >>> 1] >> 8); - } - else if (addr >= 0xdff000 && addr < 0xe00000) { - return AMIGA.custom.load8(addr); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01) { - return AMIGA.cia.load8(addr); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02) { - return AMIGA.cia.load8(addr); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000) { - return AMIGA.rtc.load8(addr); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { - return (addr & 1) ? (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] & 0xff) : (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] >> 8); - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) { - return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8); - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { - return (addr & 1) ? (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] & 0xff) : (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] >> 8); - } - else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { - return AMIGA.expansion.load8(addr); - } - //else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr); + if (addr >= 0x000000 && addr < this.chip.size) { + return (addr & 1) ? (this.chip.data[addr >>> 1] & 0xff) : (this.chip.data[addr >>> 1] >> 8); + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) { + return (addr & 1) ? (this.slow.data[(addr - this.slow.lower) >>> 1] & 0xff) : (this.slow.data[(addr - this.slow.lower) >>> 1] >> 8); + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) { + return (addr & 1) ? (this.fast.data[(addr - this.fast.lower) >>> 1] & 0xff) : (this.fast.data[(addr - this.fast.lower) >>> 1] >> 8); + } + else if (addr >= this.rom.lower && addr < this.rom.upper) { + return (addr & 1) ? (this.rom.data[(addr - this.rom.lower) >>> 1] & 0xff) : (this.rom.data[(addr - this.rom.lower) >>> 1] >> 8); + } + else if (addr >= 0xdff000 && addr < 0xe00000) { + return AMIGA.custom.load8(addr); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01) { + return AMIGA.cia.load8(addr); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02) { + return AMIGA.cia.load8(addr); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000) { + return AMIGA.rtc.load8(addr); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { + return (addr & 1) ? (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] & 0xff) : (this.res_e0.data[(addr - this.res_e0.lower) >>> 1] >> 8); + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) { + return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8); + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { + return (addr & 1) ? (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] & 0xff) : (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] >> 8); + } + else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { + return AMIGA.expansion.load8(addr); + } + //else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr); - return NULL8; - } + return NULL8; + }; this.load16 = function (addr) { - //BUG.info('Memory.load16() addr $%08x', addr); + //BUG.info('Memory.load16() addr $%08x', addr); - if (addr >= 0 && addr < this.chip.size - 1) { - return this.chip.data[addr >>> 1]; - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { - return this.slow.data[(addr - this.slow.lower) >>> 1]; - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { - return this.fast.data[(addr - this.fast.lower) >>> 1]; - } - else if (addr >= this.rom.lower && addr < this.rom.upper - 1) { - return this.rom.data[(addr - this.rom.lower) >>> 1]; - } - else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { - return AMIGA.custom.load16(addr); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { - return AMIGA.cia.load16(addr); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { - return AMIGA.cia.load16(addr); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { - return AMIGA.rtc.load16(addr); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { - return this.res_e0.data[(addr - this.res_e0.lower) >>> 1]; - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) { - return this.res_f0.data[(addr - this.res_f0.lower) >>> 1]; - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { - return this.res_d8.data[(addr - this.res_d8.lower) >>> 1]; - } - //else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr); + if (addr >= 0 && addr < this.chip.size - 1) { + return this.chip.data[addr >>> 1]; + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { + return this.slow.data[(addr - this.slow.lower) >>> 1]; + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { + return this.fast.data[(addr - this.fast.lower) >>> 1]; + } + else if (addr >= this.rom.lower && addr < this.rom.upper - 1) { + return this.rom.data[(addr - this.rom.lower) >>> 1]; + } + else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { + return AMIGA.custom.load16(addr); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { + return AMIGA.cia.load16(addr); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { + return AMIGA.cia.load16(addr); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { + return AMIGA.rtc.load16(addr); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { + return this.res_e0.data[(addr - this.res_e0.lower) >>> 1]; + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) { + return this.res_f0.data[(addr - this.res_f0.lower) >>> 1]; + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { + return this.res_d8.data[(addr - this.res_d8.lower) >>> 1]; + } + //else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr); - return NULL16; - } + return NULL16; + }; this.load32 = function (addr) { - //BUG.info('Memory.load32() addr $%08x', addr); + //BUG.info('Memory.load32() addr $%08x', addr); - if (addr >= 0 && addr < this.chip.size - 3) { - addr >>>= 1; - return ((this.chip.data[addr] << 16) | this.chip.data[addr + 1]) >>> 0; - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) { - addr = (addr - this.slow.lower) >>> 1; - return ((this.slow.data[addr] << 16) | this.slow.data[addr + 1]) >>> 0; - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) { - addr = (addr - this.fast.lower) >>> 1; - return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0; - } - else if (addr >= this.rom.lower && addr < this.rom.upper - 3) { - addr = (addr - this.rom.lower) >>> 1; - return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0; - } - else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { - return AMIGA.custom.load32(addr); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { - return AMIGA.cia.load32(addr); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { - return AMIGA.cia.load32(addr); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { - return AMIGA.rtc.load32(addr); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { - addr = (addr - this.res_e0.lower) >>> 1; - return ((this.res_e0.data[addr] << 16) | this.res_e0.data[addr + 1]) >>> 0; - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) { - addr = (addr - this.res_f0.lower) >>> 1; - return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0; - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { - addr = (addr - this.res_d8.lower) >>> 1; - return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0; - } - //else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr); + if (addr >= 0 && addr < this.chip.size - 3) { + addr >>>= 1; + return ((this.chip.data[addr] << 16) | this.chip.data[addr + 1]) >>> 0; + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) { + addr = (addr - this.slow.lower) >>> 1; + return ((this.slow.data[addr] << 16) | this.slow.data[addr + 1]) >>> 0; + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) { + addr = (addr - this.fast.lower) >>> 1; + return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0; + } + else if (addr >= this.rom.lower && addr < this.rom.upper - 3) { + addr = (addr - this.rom.lower) >>> 1; + return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0; + } + else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { + return AMIGA.custom.load32(addr); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { + return AMIGA.cia.load32(addr); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { + return AMIGA.cia.load32(addr); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { + return AMIGA.rtc.load32(addr); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { + addr = (addr - this.res_e0.lower) >>> 1; + return ((this.res_e0.data[addr] << 16) | this.res_e0.data[addr + 1]) >>> 0; + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) { + addr = (addr - this.res_f0.lower) >>> 1; + return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0; + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { + addr = (addr - this.res_d8.lower) >>> 1; + return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0; + } + //else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr); - return NULL32; - } + return NULL32; + }; this.store8 = function (addr, value) { - //BUG.info('Memory.store8() addr $%08x, val $%02x', addr, value); + //BUG.info('Memory.store8() addr $%08x, val $%02x', addr, value); - if (addr >= 0 && addr < this.chip.size) { - if (addr & 1) { - addr >>>= 1; - this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value; - } else { - addr >>>= 1; - this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff); - } - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) { - if (addr & 1) { - addr = (addr - this.slow.lower) >>> 1; - this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value; - } else { - addr = (addr - this.slow.lower) >>> 1; - this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff); - } - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) { - if (addr & 1) { - addr = (addr - this.fast.lower) >>> 1; - this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value; - } else { - addr = (addr - this.fast.lower) >>> 1; - this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff); - } - } - else if (addr >= 0xdff000 && addr < 0xe00000) { - AMIGA.custom.store8(addr, value); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01) { - AMIGA.cia.store8(addr, value); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02) { - AMIGA.cia.store8(addr, value); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000) { - AMIGA.rtc.store8(addr, value); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { - if (addr & 1) { - addr = (addr - this.res_e0.lower) >>> 1; - this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value; - } else { - addr = (addr - this.res_e0.lower) >>> 1; - this.res_e0.data[addr] = (value << 8) | (this.res_e0.data[addr] & 0x00ff); - } - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) { - if (addr & 1) { - addr = (addr - this.res_f0.lower) >>> 1; - this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value; - } else { - addr = (addr - this.res_f0.lower) >>> 1; - this.res_f0.data[addr] = (value << 8) | (this.res_f0.data[addr] & 0x00ff); - } - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { - if (addr & 1) { - addr = (addr - this.res_d8.lower) >>> 1; - this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value; - } else { - addr = (addr - this.res_d8.lower) >>> 1; - this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff); - } - } - else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { - AMIGA.expansion.store8(addr, value); - } - //else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value); - } + if (addr >= 0 && addr < this.chip.size) { + if (addr & 1) { + addr >>>= 1; + this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value; + } else { + addr >>>= 1; + this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff); + } + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) { + if (addr & 1) { + addr = (addr - this.slow.lower) >>> 1; + this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value; + } else { + addr = (addr - this.slow.lower) >>> 1; + this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff); + } + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) { + if (addr & 1) { + addr = (addr - this.fast.lower) >>> 1; + this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value; + } else { + addr = (addr - this.fast.lower) >>> 1; + this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff); + } + } + else if (addr >= 0xdff000 && addr < 0xe00000) { + AMIGA.custom.store8(addr, value); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01) { + AMIGA.cia.store8(addr, value); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02) { + AMIGA.cia.store8(addr, value); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000) { + AMIGA.rtc.store8(addr, value); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { + if (addr & 1) { + addr = (addr - this.res_e0.lower) >>> 1; + this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value; + } else { + addr = (addr - this.res_e0.lower) >>> 1; + this.res_e0.data[addr] = (value << 8) | (this.res_e0.data[addr] & 0x00ff); + } + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) { + if (addr & 1) { + addr = (addr - this.res_f0.lower) >>> 1; + this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value; + } else { + addr = (addr - this.res_f0.lower) >>> 1; + this.res_f0.data[addr] = (value << 8) | (this.res_f0.data[addr] & 0x00ff); + } + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { + if (addr & 1) { + addr = (addr - this.res_d8.lower) >>> 1; + this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value; + } else { + addr = (addr - this.res_d8.lower) >>> 1; + this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff); + } + } + else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { + AMIGA.expansion.store8(addr, value); + } + //else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value); + }; this.store16 = function (addr, value) { - //BUG.info('Memory.store16() addr $%08x, val $%04x', addr, value); + //BUG.info('Memory.store16() addr $%08x, val $%04x', addr, value); - if (addr >= 0 && addr < this.chip.size - 1) { - this.chip.data[addr >>> 1] = value; - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { - this.slow.data[(addr - this.slow.lower) >>> 1] = value; - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { - this.fast.data[(addr - this.fast.lower) >>> 1] = value; - } - else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { - AMIGA.custom.store16(addr, value); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { - AMIGA.cia.store16(addr, value); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { - AMIGA.cia.store16(addr, value); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { - AMIGA.rtc.store16(addr, value); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { - this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value; - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) { - this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value; - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { - this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value; - } - //else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value); - } + if (addr >= 0 && addr < this.chip.size - 1) { + this.chip.data[addr >>> 1] = value; + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { + this.slow.data[(addr - this.slow.lower) >>> 1] = value; + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { + this.fast.data[(addr - this.fast.lower) >>> 1] = value; + } + else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { + AMIGA.custom.store16(addr, value); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { + AMIGA.cia.store16(addr, value); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { + AMIGA.cia.store16(addr, value); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { + AMIGA.rtc.store16(addr, value); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { + this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value; + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) { + this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value; + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { + this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value; + } + //else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value); + }; this.store32 = function (addr, value) { - //BUG.info('Memory.store32() addr $%08x, val $%08x', addr, value); + //BUG.info('Memory.store32() addr $%08x, val $%08x', addr, value); - if (addr >= 0 && addr < this.chip.size - 3) { - addr >>>= 1; - this.chip.data[addr] = value >>> 16; - this.chip.data[addr + 1] = value & 0xffff; - } - else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) { - addr = (addr - this.slow.lower) >>> 1; - this.slow.data[addr] = value >>> 16; - this.slow.data[addr + 1] = value & 0xffff; - } - else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) { - addr = (addr - this.fast.lower) >>> 1; - this.fast.data[addr] = value >>> 16; - this.fast.data[addr + 1] = value & 0xffff; - } - else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { - AMIGA.custom.store32(addr, value); - } - else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { - AMIGA.cia.store32(addr, value); - } - else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { - AMIGA.cia.store32(addr, value); - } - else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { - AMIGA.rtc.store32(addr, value); - } - else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { - addr = (addr - this.res_e0.lower) >>> 1; - this.res_e0.data[addr] = value >>> 16; - this.res_e0.data[addr + 1] = value & 0xffff; - } - else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) { - addr = (addr - this.res_f0.lower) >>> 1; - this.res_f0.data[addr] = value >>> 16; - this.res_f0.data[addr + 1] = value & 0xffff; - } - else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { - addr = (addr - this.res_d8.lower) >>> 1; - this.res_d8.data[addr] = value >>> 16; - this.res_d8.data[addr + 1] = value & 0xffff; - } - //else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value); - } + if (addr >= 0 && addr < this.chip.size - 3) { + addr >>>= 1; + this.chip.data[addr] = value >>> 16; + this.chip.data[addr + 1] = value & 0xffff; + } + else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) { + addr = (addr - this.slow.lower) >>> 1; + this.slow.data[addr] = value >>> 16; + this.slow.data[addr + 1] = value & 0xffff; + } + else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) { + addr = (addr - this.fast.lower) >>> 1; + this.fast.data[addr] = value >>> 16; + this.fast.data[addr + 1] = value & 0xffff; + } + else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { + AMIGA.custom.store32(addr, value); + } + else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { + AMIGA.cia.store32(addr, value); + } + else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { + AMIGA.cia.store32(addr, value); + } + else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { + AMIGA.rtc.store32(addr, value); + } + else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { + addr = (addr - this.res_e0.lower) >>> 1; + this.res_e0.data[addr] = value >>> 16; + this.res_e0.data[addr + 1] = value & 0xffff; + } + else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) { + addr = (addr - this.res_f0.lower) >>> 1; + this.res_f0.data[addr] = value >>> 16; + this.res_f0.data[addr + 1] = value & 0xffff; + } + else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { + addr = (addr - this.res_d8.lower) >>> 1; + this.res_d8.data[addr] = value >>> 16; + this.res_d8.data[addr + 1] = value & 0xffff; + } + //else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value); + }; - this.check16_chip = function (addr, size) { - return (addr >= 0 && addr + size < this.chip.size - 1); - } - /*this.load16_chip = function (addr) { + /*this.check16_chip = function (addr, size) { + return (addr >= 0 && addr + size < this.chip.size - 1); + };*/ + /*this.load16_chip = function (addr) { if (this.check16_chip(addr, 1)) { var v = this.chip.data[addr >>> 1]; AMIGA.custom.last_value = v; @@ -572,82 +579,77 @@ function Memory() { AMIGA.custom.last_value = 0xffff; }*/ - this.copy_rom = function(data) { - //BUG.info('copyrom() size %d', data.length); - //BUG.info('copyrom() crc32 $%08x', crc32(data)); - - if (data.length == 0x80000) { - /*var lo = crc32(data.substr(0, 0x40000)); - var hi = crc32(data.substr(0x40000, 0x80000)); - if (lo != hi) { - BUG.info('copyrom() lo crc32 $%08x', lo); - BUG.info('copyrom() hi crc32 $%08x', hi); - }*/ - for (var i = 0; i < data.length; i++) { - var v = data.charCodeAt(i) & 0xff; - if (i & 1) { - var j = i >>> 1; - this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; - } else { - var j = i >>> 1; - this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); - } - } - this.rom.lower = 0xf80000; - } - else if (data.length == 0x40000) { - for (var i = 0; i < data.length; i++) { - var v = data.charCodeAt(i) & 0xff; - if (i & 1) { - var j = i >>> 1; - this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; - this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v; - } else { - var j = i >>> 1; - this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); - this.rom.data[0x20000 + j] = (v << 8) | (this.rom.data[0x20000 + j] & 0x00ff); - } - } - this.rom.lower = 0xfc0000; - } - } + this.copy_rom = function (data) { + //BUG.info('copyrom() size %d', data.length); + //BUG.info('copyrom() crc32 $%08x', crc32(data)); + + if (data.length == 0x80000) { + /*var lo = crc32(data.substr(0, 0x40000)); + var hi = crc32(data.substr(0x40000, 0x80000)); + if (lo != hi) { + BUG.info('copyrom() lo crc32 $%08x', lo); + BUG.info('copyrom() hi crc32 $%08x', hi); + }*/ + for (var i = 0; i < data.length; i++) { + var v = data.charCodeAt(i) & 0xff; + if (i & 1) { + var j = i >>> 1; + this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; + } else { + var j = i >>> 1; + this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); + } + } + this.rom.lower = 0xf80000; + } + else if (data.length == 0x40000) { + for (var i = 0; i < data.length; i++) { + var v = data.charCodeAt(i) & 0xff; + if (i & 1) { + var j = i >>> 1; + this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; + this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v; + } else { + var j = i >>> 1; + this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); + this.rom.data[0x20000 + j] = (v << 8) | (this.rom.data[0x20000 + j] & 0x00ff); + } + } + this.rom.lower = 0xfc0000; + } + }; - this.copy_e0 = function(data) { - if (data.length <= 0x80000) { - for (var i = 0; i < data.length; i++) { - var v = data.charCodeAt(i) & 0xff; - if (i & 1) { - var j = i >>> 1; - this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v; - } else { - var j = i >>> 1; - this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff); - } - } - } - } - this.copy_f0 = function(data) { - if (data.length <= 0x80000) { - for (var i = 0; i < data.length; i++) { - var v = data.charCodeAt(i) & 0xff; - if (i & 1) { - var j = i >>> 1; - this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v; - } else { - var j = i >>> 1; - this.res_f0.data[j] = (v << 8) | (this.res_f0.data[j] & 0x00ff); - } - } - } - } + this.copy_e0 = function (data) { + if (data.length <= 0x80000) { + for (var i = 0; i < data.length; i++) { + var v = data.charCodeAt(i) & 0xff; + if (i & 1) { + var j = i >>> 1; + this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v; + } else { + var j = i >>> 1; + this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff); + } + } + } + }; + this.copy_f0 = function (data) { + if (data.length <= 0x80000) { + for (var i = 0; i < data.length; i++) { + var v = data.charCodeAt(i) & 0xff; + if (i & 1) { + var j = i >>> 1; + this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v; + } else { + var j = i >>> 1; + this.res_f0.data[j] = (v << 8) | (this.res_f0.data[j] & 0x00ff); + } + } + } + }; - this.mirror_rom_to_chipram = function() { + /*this.mirror_rom_to_chipram = function() { for (var i = 0; i < this.rom.size; i++) this.chip.data[i] = this.rom.data[i]; - - /*if (this.ext.size > 0) { - for (var i = 0; i < this.ext.size; i++) - this.chip.data[this.rom.size + i] = this.ext.data[i]; - }*/ - } + }*/ } \ No newline at end of file diff --git a/sae/playfield.js b/sae/playfield.js index c826ee3..3b205af 100644 --- a/sae/playfield.js +++ b/sae/playfield.js @@ -8,13 +8,13 @@ * *************************************************************************** * Notes: -* - Portet from WinUAE 2.5.0 +* - Ported from WinUAE 2.5.0 * - AGA support is commented out. * **************************************************************************/ function Playfield() { - function decision() { + function Decision() { this.plfleft = 0; this.plfright = 0; this.plflinelen = 0; @@ -33,25 +33,25 @@ function Playfield() { this.ham_seen = false; this.ham_at_start = false; - 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; - } + 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; + }; this.set = function(src) { this.plfleft = src.plfleft; @@ -74,7 +74,7 @@ function Playfield() { } } - function color_entry() { + function ColorEntry() { this.color_regs_ecs = new Uint16Array(32); //#ifndef AGA this.acolors = new Uint32Array(32); @@ -85,22 +85,22 @@ function Playfield() { this.borderblank = false; } - function color_change() { + function ColorChange() { 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.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() { + function DrawInfo() { this.first_sprite_entry = 0; this.last_sprite_entry = 0; this.first_color_change = 0; @@ -109,7 +109,7 @@ function Playfield() { this.nr_sprites = 0; } - function vidbuffer() { + 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 */ @@ -127,16 +127,16 @@ function Playfield() { /* 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.xoffset = 0; /* superhires pixels from left edge */ + //this.yoffset = 0; /* lines from top edge */ this.inxoffset = 0; /* positive if sync positioning */ - this.inyoffset = 0; + //this.inyoffset = 0; } /*---------------------------------*/ /* drawing */ - const dblpfofs = [0, 2, 4, 8, 16, 32, 64, 128]; + //const dblpfofs = [0, 2, 4, 8, 16, 32, 64, 128]; //DELETE var dblpf_ms1 = new Uint8Array(256); var dblpf_ms2 = new Uint8Array(256); @@ -162,33 +162,33 @@ function Playfield() { var line_decisions = []; for (var i = 0; i < 2 * (MAXVPOS + 2) + 1; i++) - line_decisions[i] = new decision(); + 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(); + color_tables[i][j] = new ColorEntry(); } 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(); + color_changes[i][j] = new ColorChange(); } 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(); + line_drawinfo[i][j] = new DrawInfo(); } var gfxvidinfo = { maxblocklines:0, - drawbuffer: new vidbuffer(), + 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 */ + ychange: 0 /* how many interlaced lines in one line in buffer */ }; var xlinebuffer = new Uint32Array(MAX_PIXELS_PER_LINE); @@ -200,13 +200,13 @@ function Playfield() { 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 colors_for_drawing = new ColorEntry(); + var current_colors = new ColorEntry(); var xcolors = new Uint32Array(4096); for (var i = 0; i < xcolors.length; i++) xcolors[i] = 0; - var thisline_decision = new decision(); + var thisline_decision = new Decision(); var thisline_changed = 0; var amiga2aspect_line_map = null; @@ -259,7 +259,7 @@ function Playfield() { var dp_for_drawing = null; var dip_for_drawing = null; var hposblank = 0; - var bplxor = 0; + //var bplxor = 0; var playfield_start = 0, playfield_end = 0; var real_playfield_start = 0, real_playfield_end = 0; @@ -295,7 +295,7 @@ function Playfield() { /*---------------------------------*/ /* sprites */ - function sprite() { + function Sprite() { this.pt = 0; this.xpos = 0; this.vstart = 0; @@ -311,7 +311,7 @@ function Playfield() { this.xpos = 0; this.vstart = 0; this.vstop = 0; - this.dblscan = 0; + //this.dblscan = 0; this.armed = 0; this.dmastate = 0; this.dmacycle = 0; @@ -319,14 +319,14 @@ function Playfield() { } } - function sprite_entry() { + function SpriteEntry() { this.pos = 0; this.max = 0; this.first_pixel = 0; this.has_attached = false; } - function spritepixelsbuf() { + function SpritePixelsBuf() { this.attach = 0; this.stdata = 0; this.data = 0; @@ -350,7 +350,7 @@ function Playfield() { var spr = []; for (var i = 0; i < MAX_SPRITES; i++) - spr[i] = new sprite(); + spr[i] = new Sprite(); /*union sps_union { uae_u8 bytes[MAX_SPR_PIXELS * 2]; @@ -365,12 +365,12 @@ function Playfield() { 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(); + sprite_entries[i][j] = new SpriteEntry(); } var spritepixels = []; for (var i = 0; i < MAX_PIXELS_PER_LINE; i++) - spritepixels[i] = new spritepixelsbuf(); + spritepixels[i] = new SpritePixelsBuf(); var sprctl = new Uint16Array(MAX_SPRITES); var sprpos = new Uint16Array(MAX_SPRITES); @@ -463,9 +463,9 @@ function Playfield() { 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); - } + 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; @@ -498,7 +498,7 @@ function Playfield() { } } - var scandoubled_line = 0; + //var scandoubled_line = 0; var doublescan = 0; var interlace_seen = 0; var interlace_changed = 0; @@ -510,10 +510,17 @@ function Playfield() { 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; + 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; @@ -643,9 +650,9 @@ function Playfield() { /* common */ /*-----------------------------------------------------------------------*/ - function RES_SHIFT(res) { + /*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); @@ -668,42 +675,39 @@ function Playfield() { return real_bitplane_number[fetchmode][res][planes]; } - this.nodraw = function() { - return this.framecnt != 0; - } + this.nodraw = function () { + return this.framecnt != 0; + }; - this.doflickerfix = function() { - return AMIGA.config.video.vresolution && doublescan < 0 && this.vpos < MAXVPOS; - } + 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.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_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; + /* vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely */ + return vp == this.maxvpos + this.lof_store || vp == this.maxvpos + this.lof_store + 1 || vpc >= MAXVPOS; + }; - 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_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; - } + this.is_last_line = function () { + return this.vpos + 1 == this.maxvpos + this.lof_store; + }; /*-----------------------------------------------------------------------*/ /* drawing */ @@ -732,63 +736,60 @@ function Playfield() { } } - 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; - } + this.recreate_aspect_maps = function () { + var i, h = gfxvidinfo.drawbuffer.height_allocated; + if (h == 0) + return; - if (native2amiga_line_map) native2amiga_line_map = null; - if (amiga2aspect_line_map) amiga2aspect_line_map = null; + linedbld = linedbl = AMIGA.config.video.vresolution; + if (doublescan > 0 && interlace_seen <= 0) { + linedbl = 0; + linedbld = 1; + } - 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; + amiga2aspect_line_map = new Int32Array((MAXVPOS + 1) * 2 + 1); + native2amiga_line_map = new Int32Array(h); - if (AMIGA.config.video.ycenter) { - extra_y_adjust = (h - (this.maxvpos_nom << linedbl)) >> 1; - if (extra_y_adjust < 0) - extra_y_adjust = 0; - } + 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; - for (i = 0; i < h; i++) - native2amiga_line_map[i] = -1; + 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 = 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; - } + for (i = 0; i < h; i++) + native2amiga_line_map[i] = -1; - gfxvidinfo.xchange = 1 << (RES_MAX - AMIGA.config.video.hresolution); - gfxvidinfo.ychange = linedbl ? 1 : 2; + 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; + } - 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); - } + 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); + }; /*---------------------------------*/ @@ -842,32 +843,32 @@ function Playfield() { return (x >> lores_shift) + DISPLAY_LEFT_SHIFT - DIW_DDF_OFFSET; } - function coord_native_to_amiga_x(x) { + /*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; - } + }*/ function res_shift_from_window(x) { return res_shift >= 0 ? x >> res_shift : x << -res_shift; } - function res_shift_from_amiga(x) { + /*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; - } + 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); @@ -900,14 +901,14 @@ function Playfield() { } }*/ - 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; + 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); - } + AMIGA.video.drawline(lineno, xlinebuffer, linetoscr_x_adjust_bytes >> 2); + }; /*this.do_flush_screen = function(vb, start, stop) { if (gfxvidinfo.maxblocklines != 0 && first_block_line != NO_BLOCK) @@ -954,146 +955,146 @@ function Playfield() { 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); + 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(); + 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; + } + 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; + }; - bpldualpf = (dp_for_drawing.bplcon0 & 0x400) == 0x400; - bpldualpfpri = (dp_for_drawing.bplcon2 & 0x40) == 0x40; + this.center_image = function () { + var prev_x_adjust = visible_left_border; + var prev_y_adjust = thisframe_y_adjust; + var tmp; -/*#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*/ - } + 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); - this.pfield_expand_dp_bplconx = function(regno, v) { - if (regno == 0xffff) { - //hposblank = 1; //FIXME - return; - } - 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; + /* 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 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 (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); - /* 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; - } - } + linetoscr_x_adjust_bytes = visible_left_border * gfxvidinfo.drawbuffer.pixbytes; - 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; + visible_right_border = visible_left_border + w; + if (visible_right_border > max_diwlastword()) + visible_right_border = max_diwlastword(); - visible_right_border = visible_left_border + w; - if (visible_right_border > max_diwlastword()) - visible_right_border = max_diwlastword(); + 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); - 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); + 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; - 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; + 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; - 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; + if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust) + frame_redraw_necessary |= (interlace_seen > 0 && linedbl) ? 2 : 1; - 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; - 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; - } + 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; + }; /*---------------------------------*/ @@ -1101,95 +1102,95 @@ function Playfield() { 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.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; + 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; + 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); + 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; + 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 (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); - } - } + 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); + } + }; /*---------------------------------*/ @@ -1265,9 +1266,9 @@ function Playfield() { function fill_line2(startpos, len) { //console.log('fill_line2', startpos, len); - var shift = 0; + /*var shift = 0; if (gfxvidinfo.drawbuffer.pixbytes == 2) shift = 1; - if (gfxvidinfo.drawbuffer.pixbytes == 4) shift = 2; + if (gfxvidinfo.drawbuffer.pixbytes == 4) shift = 2;*/ var nints = len;// >> (2 - shift); var nrem = nints & 7; @@ -1330,131 +1331,128 @@ function Playfield() { /*---------------------------------*/ - 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; + 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); + 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; + linetoscr_diw_start = dp_for_drawing.diwfirstword; + linetoscr_diw_end = dp_for_drawing.diwlastword; - 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; + res_shift = lores_shift - bplres; - playfield_start = linetoscr_diw_start; - playfield_end = linetoscr_diw_end; + 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; - 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); + playfield_start = linetoscr_diw_start; + playfield_end = linetoscr_diw_end; - 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*/ + 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 (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; - } - } - } + 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) { + 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; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1467,7 +1465,7 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; spix++; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1482,7 +1480,7 @@ function Playfield() { dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; spix++; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1494,7 +1492,7 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[spix_val]; spix++; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } @@ -1503,19 +1501,16 @@ function Playfield() { function linetoscr_32_stretch1(spix, dpix, stoppos) { //uae_u32 *buf = (uae_u32 *) xlinebuffer; - var buf = xlinebuffer; - - if (dp_for_drawing.ham_seen) { + 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; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1528,8 +1523,8 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; spix++; out_val = dpix_val; - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1544,8 +1539,8 @@ function Playfield() { 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; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1557,8 +1552,8 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[spix_val]; spix++; out_val = dpix_val; - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } return spix; @@ -1566,18 +1561,15 @@ function Playfield() { function linetoscr_32_shrink1(spix, dpix, stoppos) { //uae_u32 *buf = (uae_u32 *) xlinebuffer; - var buf = xlinebuffer; - - if (dp_for_drawing.ham_seen) { + 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; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1590,7 +1582,7 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[lookup[spix_val]]; spix += 2; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1605,7 +1597,7 @@ function Playfield() { dpix_val = xcolors[(colors_for_drawing.color_regs_ecs[spix_val - 32] >> 1) & 0x777]; spix += 2; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1617,7 +1609,7 @@ function Playfield() { dpix_val = colors_for_drawing.acolors[spix_val]; spix += 2; out_val = dpix_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } return spix; @@ -1626,13 +1618,11 @@ function Playfield() { function linetoscr_32_spr(spix, dpix, stoppos) { //uae_u32 *buf = (uae_u32 *) xlinebuffer; - var buf = xlinebuffer; - var sprcol; + var sprcol; if (dp_for_drawing.ham_seen) { while (dpix < stoppos) { var sprpix_val; - var spix_val; var dpix_val; var out_val; @@ -1643,11 +1633,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1665,11 +1654,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 1, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1689,11 +1677,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1710,11 +1697,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } @@ -1723,13 +1709,11 @@ function Playfield() { function linetoscr_32_stretch1_spr(spix, dpix, stoppos) { //uae_u32 *buf = (uae_u32 *) xlinebuffer; - var buf = xlinebuffer; - var sprcol; + var sprcol; if (dp_for_drawing.ham_seen) { while (dpix < stoppos) { var sprpix_val; - var spix_val; var dpix_val; var out_val; @@ -1740,12 +1724,11 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1763,12 +1746,11 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 1, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1788,12 +1770,11 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1810,12 +1791,11 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } return spix; @@ -1823,13 +1803,11 @@ function Playfield() { function linetoscr_32_shrink1_spr(spix, dpix, stoppos) { //var *buf = (var *) xlinebuffer; - var buf = xlinebuffer; - var sprcol; + var sprcol; if (dp_for_drawing.ham_seen) { while (dpix < stoppos) { var sprpix_val; - var spix_val; var dpix_val; var out_val; @@ -1840,11 +1818,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bpldualpf) { var lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; @@ -1862,11 +1839,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 1, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else if (bplehb) { while (dpix < stoppos) { @@ -1886,11 +1862,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } else { while (dpix < stoppos) { @@ -1907,11 +1882,10 @@ function Playfield() { if (spritepixels[dpix].data) { sprcol = render_sprites (dpix, 0, sprpix_val, 0); if (sprcol) { - var spcol = colors_for_drawing.acolors[sprcol]; - out_val = spcol; + out_val = colors_for_drawing.acolors[sprcol]; } } - buf[dpix++] = out_val; + xlinebuffer[dpix++] = out_val; } } @@ -2209,415 +2183,464 @@ function Playfield() { } //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); + 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; - 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); + while (wordcount-- > 0) { + d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = 0; - 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); + 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 ^ (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;*/ - } - } + 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_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; + 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]; + 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]); + for (var i = 0; i < apixels.length; i++) apixels[i] = 0; //memset (apixels, 0, sizeof apixels); + //var oxor = bplxor; + //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; + } + }; - 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.init_drawing_frame = function () { + this.init_hardware_for_drawing_frame(); - this.adjust_drawing_colors(dp_for_drawing.ctable, dp_for_drawing.ham_seen || bplehb || ecsshres); + /*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;*/ - 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(); + var maxline = ((this.maxvpos_nom + 1) << linedbl) + 2; - 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); + 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); + } - this.do_flush_line(vb, gfx_ypos); - if (do_double) - this.do_flush_line(vb, follow_ypos); - } else if (border == 1) { - var dosprites = 0; + last_drawn_line = 0; + first_drawn_line = 0x7fff; - this.adjust_drawing_colors(dp_for_drawing.ctable, false); + first_block_line = last_block_line = NO_BLOCK; + if (frame_redraw_necessary) + frame_redraw_necessary--; -/*#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(); + this.center_image(); - 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; + thisframe_first_drawn_line = -1; + thisframe_last_drawn_line = -1; - 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; - } + drawing_color_matches = -1; + }; - this.finish_drawing_frame = function() { - var vb = gfxvidinfo.drawbuffer; + 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; + 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); + 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.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.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_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.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.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.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.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.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.setup_drawing = function () { + setup_drawing_tables(); + this.allocsoftbuffer(gfxvidinfo.drawbuffer, 0, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_DEPTH); + }; - this.cleanup_drawing = function() {} + 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; - } + 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 */ @@ -2662,7 +2685,7 @@ function Playfield() { } function render_sprites(pos, dualpf, apixel, aga) { - if (!DO_SPRITES) return; //FIXME + if (!DO_SPRITES) return 0; //FIXME var spb = spritepixels[pos]; var v = spb.data; var shift_lookup = dualpf ? (bpldualpfpri ? dblpf_ms2 : dblpf_ms1) : dblpf_ms; @@ -2744,301 +2767,303 @@ function Playfield() { } /* 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; + this.do_playfield_collisions = function () { + var ddf_left = thisline_decision.plfleft * 2 << bplcon0_res; + 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; + 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; - } + 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 << bplcon0_res) - 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); + 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 ddf_left = thisline_decision.plfleft * 2 << bplcon0_res; + 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; - } + 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; + 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; + 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; + for (var j = minpos; j < maxpos; j++) { + var sprpix = spixels[e.first_pixel + j - e.pos] & collision_mask; - if (sprpix == 0) - continue; + 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; + var match = 1; + var offs = ((j << bplcon0_res) >> 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; + 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; - }*/ - } + 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; + this.record_sprite_1 = function (sprxp, buf, datab, num, dbl, mask, do_collisions, collision_mask) { + var j = 0; - if ((sprxp >= sprite_minx && sprxp < sprite_maxx) || (bplcon3 & 2)) - col = (datab & 3) << (2 * num); + while (datab) { + var col = 0; + var coltmp = 0; - //if (sprxp == sprite_minx || sprxp == sprite_maxx - 1) col ^= Math.floor(Math.random() * 0xffffffff); + if ((sprxp >= sprite_minx && sprxp < sprite_maxx) || (bplcon3 & 2)) + col = (datab & 3) << (2 * num); - 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 = (*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; - if (do_collisions) { - coltmp &= collision_mask; - if (coltmp) { - var shrunk_tmp = sprite_ab_merge[coltmp & 255] | (sprite_ab_merge[coltmp >> 8] << 2); - clxdat |= sprclx[shrunk_tmp]; - } - } - } - } + //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 = (*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; + if (do_collisions) { + coltmp &= collision_mask; + if (coltmp) { + var shrunk_tmp = sprite_ab_merge[coltmp & 255] | (sprite_ab_merge[coltmp >> 8] << 2); + 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.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; - 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; - } + //var data = 0, datb = 0; + var this_sprite_entry = next_sprite_entry; + var num2 = 0; - if (sprxp < e.pos) - Fatal(333, 'sprxp < e->pos'); + 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; - 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; + /* 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; + } - collision_mask = clxmask[clxcon >> 12]; - word_offs = e.first_pixel + sprxp - e.pos; + if (sprxp < e.pos) + Fatal(333, '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; - } - } + 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; @@ -3046,9 +3071,9 @@ function Playfield() { function tospritexddf(ddf) { return (ddf << 1) << sprite_buffer_res; } - function fromspritexdiw(ddf) { + /*function fromspritexdiw(ddf) { return coord_hw_to_window_x(ddf >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); - } + }*/ function calcsprite() { sprite_maxx = 0x7fff; @@ -3081,115 +3106,115 @@ function Playfield() { nrs[j] = num; } - this.decide_sprites = function(hpos) { - if (!DO_SPRITES) return; //FIXME - var nrs = [], posns = []; - var point = hpos * 2 - 3; - var width = sprite_width; - var sscanmask = 0x100 << sprite_buffer_res; - var gotdata = 0; - var count, i; + this.decide_sprites = function (hpos) { + if (!DO_SPRITES) return; //FIXME + var nrs = [], posns = []; + var point = hpos * 2 - 3; + //var width = sprite_width; + var sscanmask = 0x100 << sprite_buffer_res; + //var gotdata = 0; + var count, i; - if (thisline_decision.plfleft < 0 && !(bplcon3 & 2)) - return; + if (thisline_decision.plfleft < 0 && !(bplcon3 & 2)) + return; - if (this.nodraw() || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) - return; + if (this.nodraw() || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) + return; - this.decide_diw(hpos); - this.decide_line(hpos); + this.decide_diw(hpos); + this.decide_line(hpos); - calcsprite(); + calcsprite(); - for (i = 0; i < MAX_SPRITES * 2; i++) - nrs[i] = posns[i] = 0; + 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; + 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 (!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 (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 (i = 0; i < count; i++) { - 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; + 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 (i = 0; i < count; i++) { + 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 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*/ - } + /* 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; + + /* 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; - }*/ - } + 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; @@ -3207,164 +3232,166 @@ function Playfield() { return data; } - this.do_sprites_1 = function(num, cycle, hpos) { - var s = spr[num]; - var isdma = AMIGA.dmaen(DMAF_SPREN) || ((num & 1) && spr[num & ~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 && 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; - } -#endif*/ + 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; + } + #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 >= 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 (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 && !s.dmacycle) - return; /* Superfrog intro flashing bee fix */ + if (!isdma) + return; + if (cycle && !s.dmacycle) + return; + /* Superfrog intro flashing bee fix */ - var dma = hpos < plfstrt_sprite || diwstate != DIW_WAITING_STOP; - var posctl = 0; + var dma = hpos < plfstrt_sprite || diwstate != DIW_WAITING_STOP; + var posctl = 0; - if (this.vpos == s.vstop || this.vpos == sprite_vblank_endline) { - s.dmastate = 0; - posctl = 1; - if (dma) { - 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_1(data, num, hpos); - s.dmacycle = 1; - } else { - 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 (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_1(data, num, hpos); - s.dmacycle = 1; - } else { - 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*/ - } - } + if (this.vpos == s.vstop || this.vpos == sprite_vblank_endline) { + s.dmastate = 0; + posctl = 1; + if (dma) { + 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); + break; + 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_1(data, num, hpos); + s.dmacycle = 1; + } else { + 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 (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_1(data, num, hpos); + s.dmacycle = 1; + } else { + 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.do_sprites = function(hpos) { - if (!DO_SPRITES) return; //FIXME - if (this.vpos < sprite_vblank_endline) - return; + this.do_sprites = function (hpos) { + if (!DO_SPRITES) return; //FIXME + if (this.vpos < sprite_vblank_endline) + return; - if (this.doflickerfix() && interlace_seen && (next_lineno & 1)) - return; + if (this.doflickerfix() && interlace_seen && (next_lineno & 1)) + return; - if (!CUSTOM_SIMPLE) { - var minspr = last_sprite_hpos + 1; - var maxspr = hpos; + if (!CUSTOM_SIMPLE) { + var minspr = last_sprite_hpos + 1; + var maxspr = hpos; - if (minspr >= maxspr || last_sprite_hpos == hpos) - return; + 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 (maxspr >= SPR0_HPOS + MAX_SPRITES * 4) + maxspr = SPR0_HPOS + MAX_SPRITES * 4 - 1; + if (minspr < SPR0_HPOS) + minspr = SPR0_HPOS; - if (minspr == maxspr) - return; + 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); - } - } - } + 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) { @@ -3400,146 +3427,159 @@ function Playfield() { } } - this.sprstartstop = function(s) { - if (this.vpos == s.vstart) - s.dmastate = 1; - if (this.vpos == s.vstop) - s.dmastate = 0; - } + this.sprstartstop = function (s) { + if (this.vpos == s.vstart) + s.dmastate = 1; + if (this.vpos == s.vstop) + s.dmastate = 0; + }; - this.CLXCON = function(v) { - clxcon = v; - clxcon_bpl_enable = (v >> 6) & 63; - clxcon_bpl_match = v & 63; - } + 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.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 = clxdat | 0x8000; - clxdat = 0; - return v; - } + this.CLXDAT = function () { + var v = clxdat | 0x8000; + clxdat = 0; + return v; + }; - this.SPRxCTLPOS = function(num) { - var sprxp; - var s = spr[num]; + this.SPRxCTLPOS = function (num) { + var sprxp; + var s = spr[num]; - 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 -#endif*/ - if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) { - sprxp |= ((sprctl[num] >> 3) & 2) >> (RES_MAX - sprite_buffer_res); - } - 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.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 + #endif*/ + if (AMIGA.config.chipset.mask & CSMASK_ECS_DENISE) { + sprxp |= ((sprctl[num] >> 3) & 2) >> (RES_MAX - sprite_buffer_res); + } + 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.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.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.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.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.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.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.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); } + 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); + }; - 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; - } - //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.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; + } + //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.setup_sprites = function () { + if (!sprinit) { + sprinit = true; + setup_sprite_tables(); + } + }; - this.cleanup_sprites = function() {} + 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); + 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); - } + 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); + }; /*-----------------------------------------------------------------------*/ /* playfield */ /*-----------------------------------------------------------------------*/ - function debug_cycle_diagram() { + /*function debug_cycle_diagram() { var fm, res, planes, cycle, v; var aa, txt = ''; @@ -3559,7 +3599,7 @@ function Playfield() { } } BUG.info(txt); - } + }*/ function create_cycle_diagram_table() { var fm, res, cycle, planes, rplanes, v; @@ -3764,11 +3804,11 @@ function Playfield() { /*#ifdef AGA if (aga_mode) //copy acolors and color_regs_aga - memcpy (dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32); + memcpy (dst->acolors, src->acolors, sizeof(struct ColorEntry) - 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)); + //memcpy (dst.color_regs_ecs, src.color_regs_ecs, sizeof(struct ColorEntry)); for (var i = 0; i < 32; i++) { dst.acolors[i] = src.acolors[i]; @@ -3785,479 +3825,477 @@ function Playfield() { /*---------------------------------*/ - 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; + 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 (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; - } - } + 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; - 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); - } + 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.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); + this.decide_diw(hpos); + this.decide_line(hpos); - if (thisline_decision.ctable < 0) - this.remember_ctable(); + 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); - } + 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; + 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; - } + 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.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; + 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()); - } + AMIGA.events.calc_vsynctimebase(this.vblank_hz); - this.compute_framesync = function() { - var islace = interlace_seen ? 1 : 0; - var isntsc = (beamcon0 & 0x20) ? 0 : 1; - var found = false; + 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()); + }; - interlace_changed = 0; - gfxvidinfo.drawbuffer.inxoffset = -1; - gfxvidinfo.drawbuffer.inyoffset = -1; + this.compute_framesync = function () { + var islace = interlace_seen ? 1 : 0; + var isntsc = (beamcon0 & 0x20) ? 0 : 1; - if (beamcon0 & 0x80) { - var res = GET_RES_AGNUS(bplcon0); - var vres = islace ? 1 : 0; - var res2, vres2; + interlace_changed = 0; + gfxvidinfo.drawbuffer.inxoffset = -1; + gfxvidinfo.drawbuffer.inyoffset = -1; - res2 = AMIGA.config.video.hresolution; - if (doublescan > 0) - res2++; - if (res2 > RES_MAX) - res2 = RES_MAX; + if (beamcon0 & 0x80) { + //var res = GET_RES_AGNUS(bplcon0); + //var vres = islace ? 1 : 0; + var res2, vres2; - vres2 = AMIGA.config.video.vresolution; - if (doublescan > 0 && !islace) - vres2--; + res2 = AMIGA.config.video.hresolution; + if (doublescan > 0) + res2++; + if (res2 > RES_MAX) + res2 = RES_MAX; - if (vres2 < 0) - vres2 = 0; - if (vres2 > VRES_QUAD) - vres2 = VRES_QUAD; + vres2 = AMIGA.config.video.vresolution; + if (doublescan > 0 && !islace) + vres2--; - var start = this.hbstrt; - var stop = this.hbstop; + if (vres2 < 0) + vres2 = 0; + if (vres2 > VRES_QUAD) + vres2 = VRES_QUAD; - 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; + var start = this.hbstrt; + var stop = this.hbstop; - gfxvidinfo.drawbuffer.extrawidth = 0; - gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; + 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.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; - } + gfxvidinfo.drawbuffer.extrawidth = 0; + gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; - 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; + 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.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; + 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; - gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.inheight; + 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; - if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width_allocated) - gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width_allocated; + gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.inwidth; + gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.inheight; - if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height_allocated) - gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height_allocated; + if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width_allocated) + gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width_allocated; - //if (target_graphics_buffer_update()) this.reset_drawing(); + if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height_allocated) + gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height_allocated; - 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 - ); - } + //if (target_graphics_buffer_update()) this.reset_drawing(); - this.init_hz = function(fullinit) { - var isntsc, islace; - var odbl = doublescan, omaxvpos = this.maxvpos; - var ovblank = this.vblank_hz; - var hzc = 0; + for (var i = 0; i < 2 * (MAXVPOS + 2) + 1; i++) //memset (line_decisions, 0, sizeof line_decisions); + line_decisions[i].clr(); - if (fullinit) - this.vpos_count = 0; + this.compute_vsynctime(); - this.vpos_count_diff = this.vpos_count; + 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 + ); + }; - 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.init_hz = function (fullinit) { + var isntsc, islace; + var odbl = doublescan, omaxvpos = this.maxvpos; + var hzc = 0; - 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; - } + if (fullinit) + this.vpos_count = 0; - 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(); + this.vpos_count_diff = this.vpos_count; - if (hzc) { - interlace_seen = islace; - this.reset_drawing(); - } + 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_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.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.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.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; - 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); - } - } + 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; + 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; + 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 (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))); - 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); - } + bplcon0_d = v & ~0x80; - 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 (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); + }; -/*#if SPRBORDER - v |= 1; -#endif*/ - if (bplcon0 == v) - return; + 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 (!this.issyncstopped()) { - vpos_previous = this.vpos; - hpos_previous = hpos; - } + /*#if SPRBORDER + v |= 1; + #endif*/ + if (bplcon0 == v) + return; - if ((bplcon0 & 4) != (v & 4)) - this.checklacecount((v & 4) != 0); + if (!this.issyncstopped()) { + vpos_previous = this.vpos; + hpos_previous = hpos; + } - bplcon0 = v; + if ((bplcon0 & 4) != (v & 4)) + this.checklacecount((v & 4) != 0); - this.bpldmainitdelay(hpos); + bplcon0 = v; - if (thisline_decision.plfleft < 0) - this.BPLCON0_Denise(hpos, v, true); - } + this.bpldmainitdelay(hpos); - 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; - } + if (thisline_decision.plfleft < 0) + this.BPLCON0_Denise(hpos, v, true); + }; - 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.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.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); - } + 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) { @@ -4273,250 +4311,250 @@ function Playfield() { 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.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.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; + 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; - } + // 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; + 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; + 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; + 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); - } + 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.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.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.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.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.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.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.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; + 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; + 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; + 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 (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 (cval == current_colors.color_regs_aga[colreg]) + return; - if (colreg == 0) - this.checkautoscalecol0 (); + 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); + //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; + } 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) { + 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*/ - } + 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 @@ -4529,1639 +4567,1678 @@ function Playfield() { this.GETHPOS = function() { return this.islightpentriggered() ? hpos_lpen : (this.issyncstopped() ? hpos_previous : this.hpos()); }*/ - 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.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(); + }; 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.VPOSR = function () { + var vp = this.GETVPOS(); + var hp = this.GETHPOS(); + //var vp = this.vpos; + //var hp = this.hpos(); + var csbit = 0; - if (hp + HPOS_OFFSET >= this.maxhpos) { - vp++; - if (vp >= this.maxvpos + this.lof_store) - vp = 0; - } - vp = (vp >> 8) & 7; + 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.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; + 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; - } + //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; + 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; + 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.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.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(); + 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; + 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; - } + 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; + 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); - } - } - } + 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.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.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); + 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; - } + 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; - break; - case 1: - case 2: - fetchmode = 1; - break; - case 3: - fetchmode = 2; - break; - } - 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 = 1 << fm_maxplane_shift; - fetch_modulo_cycle = fetchunit - fetchstart; - curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit]; - this.estimate_last_fetch_cycle(hpos); - bpldmasetuphpos = -1; - bpldmasetupphase = 0; - ddf_change = this.vpos; - } + this.setup_fmodes = function (hpos) { + switch (fmode & 3) { + case 0: + fetchmode = 0; + break; + case 1: + case 2: + fetchmode = 1; + break; + case 3: + fetchmode = 2; + break; + } + 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 = 1 << fm_maxplane_shift; + fetch_modulo_cycle = fetchunit - fetchstart; + curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit]; + this.estimate_last_fetch_cycle(hpos); + bpldmasetuphpos = -1; + bpldmasetupphase = 0; + 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.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.maybe_check = function(hpos) { - if (bpldmasetuphpos > 0 && hpos >= bpldmasetuphpos) - this.maybe_setup_fmodes(hpos); - } + this.maybe_check = function (hpos) { + if (bpldmasetuphpos > 0 && hpos >= bpldmasetuphpos) + this.maybe_setup_fmodes(hpos); + }; - this.compute_delay_offset = function() { - delayoffset = (16 << fetchmode) - (((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1); - } + 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; + 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); - } + 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.compute_toscr_delay = function(hpos, con1) { - this.update_denise(hpos); - this.compute_toscr_delay_1(con1); - } + 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.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.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; - } - } + 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.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.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.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; + 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.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(); - } - } + 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_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; + 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; + 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_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_changed = 0; + 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; + + 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('ColorChange 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; + } + }; - prev_drawinfo = line_drawinfo[current_change_set]; - curr_drawinfo = line_drawinfo[current_change_set ^ 1]; - current_change_set ^= 1; + this.get_equ_vblank_endline = function () { + return equ_vblank_endline + (equ_vblank_toggle ? (this.lof_current ? 1 : 0) : 0); + }; - color_src_match = color_dest_match = -1; + 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; - curr_sprite_entries[0].first_pixel = current_change_set * MAX_SPR_PIXELS; - next_sprite_forced = 1; - } + hdiw &= 511; + for (; ;) { + var lhdiw = hdiw; + if (last_hdiw > lhdiw) + lhdiw = 512; - 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; - } - } + 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.get_equ_vblank_endline = function() { - return equ_vblank_endline + (equ_vblank_toggle ? (this.lof_current ? 1 : 0) : 0); - } + this.reset_bpl_vars = function (hpos) { + out_nbits = 0; + out_offs = 0; + toscr_nbits = 0; + thisline_decision.bplres = bplcon0_res; + }; - 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; + this.start_bpl_dma = function (hpos, hstart) { + if (first_bpl_vpos < 0) + first_bpl_vpos = this.vpos; - hdiw &= 511; - for (;;) { - var lhdiw = hdiw; - if (last_hdiw > lhdiw) - lhdiw = 512; + 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; - 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; - } + ddfstate = DIW_WAITING_STOP; + this.compute_toscr_delay(last_fetch_hpos, bplcon1); - this.start_bpl_dma = function(hpos, hstart) { - if (first_bpl_vpos < 0) - first_bpl_vpos = this.vpos; + 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; + }; - 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; + 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; - ddfstate = DIW_WAITING_STOP; - this.compute_toscr_delay(last_fetch_hpos, bplcon1); + this.start_bpl_dma(hpos, hpos); + }; - 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.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; - 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); - } + 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); - 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; - } + 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; + this.toscr_2_ecs = function (nbits) { + 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; - } - } + for (i = 0; i < toscr_nr_planes2; i += 2) { + outword[i] <<= nbits; + outword[i] |= (todisplay[i][0] >> (16 - nbits + toscr_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 + toscr_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_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.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; + 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; + 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); + 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); - } + 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.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.beginning_of_plane_block = function (hpos, fm) { + var oleft = thisline_decision.plfleft; - this.flush_display(fm); + 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*/ + 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); + 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); - } + bplcon1t2 = bplcon1t; + bplcon1t = bplcon1; + if (bplcon1_hpos != hpos || oleft < 0) + bplcon1t2 = bplcon1t; - 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); - } + 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; + 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; + 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 (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; - } + 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; + 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 (dma) { + bplpt[plane] += nwords * 2; + bplptx[plane] += nwords * 2; + } - //if (real_pt == 0) /* @@@ Don't do this, fall back on chipmem_wget instead. */ - //return; + //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; + while (nwords > 0) { + var bits_left = 32 - tmp_nbits; + var t; - shiftbuffer |= fetchval; + shiftbuffer |= fetchval; - t = (shiftbuffer >>> delay) & 0xFFFF; + 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; - } + 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.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; + 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; - } + if (dma && toscr_nr_planes > 0) + fetch_state = FETCH_WAS_PLANE0; + }; - this.add_modulos = function() { - var m1, m2; + 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; - } + 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; - } - } + 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.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; - 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; + 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; - 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); + bplpt[nr] += mod; + bplptx[nr] += mod; + } + } else { + if (nr < MAX_PLANES) //FIX for illegal memory access if not #ifdef AGA + fetched[nr] = bplxdat[nr]; + } + }; - 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; - } + 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; - fetch_cycle++; - toscr_nbits += (2 << toscr_res); + 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; + 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); + }; - 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.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.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.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.update_fetch_x = function(until, fm) { - if (this.nodraw()) - return; + this.estimate_last_fetch_cycle = function (hpos) { + var fetchunit = fetchunits[fetchmode * 4 + bplcon0_res]; - var pos = last_fetch_hpos; - this.update_toscr_planes(); + 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); - 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]; + 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; - 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; - } - } + 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; - } + 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*/ + /*#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(); + 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; + this.lof_changed = 0; - AMIGA.copper.COPJMP(1, 1); + AMIGA.copper.COPJMP(1, 1); - this.init_hardware_frame(); - } + 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]; + 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; + 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; + 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; + 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++; - } - } + // 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 ColorChange)); + 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]; + } + }; - 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 = 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.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.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 = 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(); + 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; - } + 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.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.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.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(); + 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); + 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(); + notice_new_xcolors(); - this.setup_drawing(); - this.setup_sprites(); - } + this.setup_drawing(); + this.setup_sprites(); + }; - this.cleanup = function() { - this.cleanup_sprites(); - this.cleanup_drawing(); - } + this.cleanup = function () { + this.cleanup_sprites(); + this.cleanup_drawing(); + }; this.reset = function() { /*lightpen_active = -1; @@ -6184,7 +6261,7 @@ function Playfield() { #endif*/ } - this.clxdat = 0; + clxdat = 0; /* Clear the armed flags of all sprites. */ for (var i = 0; i < MAX_SPRITES; i++) spr[i].clr(); @@ -6202,7 +6279,7 @@ function Playfield() { this.CLXCON(0); this.CLXCON2(0); this.setup_fmodes(0); - sprite_width = GET_SPRITEWIDTH(fmode); + //sprite_width = GET_SPRITEWIDTH(fmode); beamcon0 = new_beamcon0 = AMIGA.config.video.ntsc ? 0x00 : 0x20; this.lof_store = this.lof_current = 1; diff --git a/sae/rtc.js b/sae/rtc.js index 45e841d..2114439 100644 --- a/sae/rtc.js +++ b/sae/rtc.js @@ -18,171 +18,215 @@ function RTC() { var rtc_memory = null; var rtc_alarm = null; - this.read = function() { - /*struct zfile *f; - f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL); - if (f) { - zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f); - zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); - zfile_fclose (f); - }*/ - } - this.write = function() { - /*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL); - if (!f) { - f = zfile_fopen (currprefs.flashfile, L"wb", 0); - if (f) { - zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); - zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); - zfile_fclose (f); - } - return; - } - zfile_fseek (f, 0, SEEK_END); - if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) { - zfile_fseek (f, 0, SEEK_SET); - zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); - zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); - } - zfile_fclose (f);*/ - } + this.read = function () { + /*struct zfile *f; + f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL); + if (f) { + zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f); + zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); + zfile_fclose (f); + }*/ + }; + this.write = function () { + /*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL); + if (!f) { + f = zfile_fopen (currprefs.flashfile, L"wb", 0); + if (f) { + zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); + zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); + zfile_fclose (f); + } + return; + } + zfile_fseek (f, 0, SEEK_END); + if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) { + zfile_fseek (f, 0, SEEK_SET); + zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); + zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); + } + zfile_fclose (f);*/ + }; - this.setup = function() { - BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A')); + this.setup = function () { + BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A')); - if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { - clock_control_d = 0x1; - clock_control_e = 0; - clock_control_f = 0x4; /* 24/12 */ - } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { - clock_control_d = 0x4; /* Timer EN */ - clock_control_e = 0; - clock_control_f = 0; + if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { + clock_control_d = 0x1; + clock_control_e = 0; + clock_control_f = 0x4; + /* 24/12 */ + } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { + clock_control_d = 0x4; + /* Timer EN */ + clock_control_e = 0; + clock_control_f = 0; - rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE); - rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE); + rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE); + rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE); - for (var i = 0; i < RF5C01A_RAM_SIZE; i++) - rtc_memory[i] = rtc_alarm[i] = 0; + for (var i = 0; i < RF5C01A_RAM_SIZE; i++) + rtc_memory[i] = rtc_alarm[i] = 0; - this.read(); - } - } + this.read(); + } + }; this.load8 = function (addr) { - addr &= 0x3f; - if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) { - if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) - return 0xff; //regs.irc >> 8; - return 0; - } - var t = new Date(); + addr &= 0x3f; + if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) { + if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) + return 0xff; //regs.irc >> 8; + return 0; + } + var t = new Date(); - addr >>= 2; - if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { - switch (addr) { - case 0x0: return t.getSeconds() % 10; - case 0x1: return Math.floor(t.getSeconds() / 10); - case 0x2: return t.getMinutes() % 10; - case 0x3: return Math.floor(t.getMinutes() / 10); - case 0x4: return t.getHours() % 10; - case 0x5: return Math.floor(t.getHours() / 10); - case 0x6: return t.getDate() % 10; - case 0x7: return Math.floor(t.getDate() / 10); - case 0x8: return (t.getMonth() + 1) % 10; - case 0x9: return Math.floor((t.getMonth() + 1) / 10); - case 0xA: return (t.getFullYear() - 1900) % 10; - case 0xB: return Math.floor((t.getFullYear() - 1900) / 10); - case 0xC: return t.getDay(); - case 0xD: return clock_control_d; - case 0xE: return clock_control_e; - case 0xF: return clock_control_f; - } - } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { - var bank = clock_control_d & 3; + addr >>= 2; + if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { + switch (addr) { + case 0x0: + return t.getSeconds() % 10; + case 0x1: + return Math.floor(t.getSeconds() / 10); + case 0x2: + return t.getMinutes() % 10; + case 0x3: + return Math.floor(t.getMinutes() / 10); + case 0x4: + return t.getHours() % 10; + case 0x5: + return Math.floor(t.getHours() / 10); + case 0x6: + return t.getDate() % 10; + case 0x7: + return Math.floor(t.getDate() / 10); + case 0x8: + return (t.getMonth() + 1) % 10; + case 0x9: + return Math.floor((t.getMonth() + 1) / 10); + case 0xA: + return (t.getFullYear() - 1900) % 10; + case 0xB: + return Math.floor((t.getFullYear() - 1900) / 10); + case 0xC: + return t.getDay(); + case 0xD: + return clock_control_d; + case 0xE: + return clock_control_e; + case 0xF: + return clock_control_f; + } + } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { + var bank = clock_control_d & 3; - if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f; - if (bank == 1 && addr < 0x0d) return rtc_alarm[addr]; + if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f; + if (bank == 1 && addr < 0x0d) return rtc_alarm[addr]; - switch (addr) { - case 0x0: return t.getSeconds() % 10; - case 0x1: return Math.floor(t.getSeconds() / 10); - case 0x2: return t.getMinutes() % 10; - case 0x3: return Math.floor(t.getMinutes() / 10); - case 0x4: return t.getHours() % 10; - case 0x5: return Math.floor(t.getHours() / 10); - case 0x6: return t.getDate() % 10; - case 0x7: return Math.floor(t.getDate() / 10); - case 0x8: return (t.getMonth() + 1) % 10; - case 0x9: return Math.floor((t.getMonth() + 1) / 10); - case 0xA: return (t.getFullYear() - 1900) % 10; - case 0xB: return Math.floor((t.getFullYear() - 1900) / 10); - case 0xC: return t.getDay(); - case 0xD: return clock_control_d; - /* E and F = write-only */ - } - } - return 0; - } + switch (addr) { + case 0x0: + return t.getSeconds() % 10; + case 0x1: + return Math.floor(t.getSeconds() / 10); + case 0x2: + return t.getMinutes() % 10; + case 0x3: + return Math.floor(t.getMinutes() / 10); + case 0x4: + return t.getHours() % 10; + case 0x5: + return Math.floor(t.getHours() / 10); + case 0x6: + return t.getDate() % 10; + case 0x7: + return Math.floor(t.getDate() / 10); + case 0x8: + return (t.getMonth() + 1) % 10; + case 0x9: + return Math.floor((t.getMonth() + 1) / 10); + case 0xA: + return (t.getFullYear() - 1900) % 10; + case 0xB: + return Math.floor((t.getFullYear() - 1900) / 10); + case 0xC: + return t.getDay(); + case 0xD: + return clock_control_d; + /* E and F = write-only */ + } + } + return 0; + }; this.load16 = function (addr) { - return (this.load8(addr) << 8) | this.load8(addr + 1); - } + return (this.load8(addr) << 8) | this.load8(addr + 1); + }; this.load32 = function (addr) { - return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0; - } + return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0; + }; this.store8 = function (addr, value) { - addr &= 0x3f; - if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return; + addr &= 0x3f; + if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return; - addr >>= 2; - value &= 0x0f; - if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { - switch (addr) { - case 0xD: clock_control_d = value & (1 | 8); break; - case 0xE: clock_control_e = value; break; - case 0xF: clock_control_f = value; break; - } - } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { - var bank = clock_control_d & 3; + addr >>= 2; + value &= 0x0f; + if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { + switch (addr) { + case 0xD: + clock_control_d = value & (1 | 8); + break; + case 0xE: + clock_control_e = value; + break; + case 0xF: + clock_control_f = value; + break; + } + } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { + var bank = clock_control_d & 3; - if (bank >= 2 && addr < 0x0d) { - rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f); - rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4); - - var ov = rtc_memory[addr]; - if (rtc_memory[addr] != value) this.write(); - return; - } - if (bank == 1 && addr < 0x0d) { - rtc_alarm[addr] = value; - rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0; - rtc_alarm[3] &= ~0x8; - rtc_alarm[5] &= ~0xc; - rtc_alarm[6] &= ~0x8; - rtc_alarm[8] &= ~0xc; - rtc_alarm[10] &= ~0xe; - rtc_alarm[11] &= ~0xc; + if (bank >= 2 && addr < 0x0d) { + rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f); + rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4); - var ov = rtc_alarm[addr]; - if (rtc_alarm[addr] != value) this.write(); - return; - } - switch (addr) { - case 0xD: clock_control_d = value; break; - case 0xE: clock_control_e = value; break; - case 0xF: clock_control_f = value; break; - } - } + //var ov = rtc_memory[addr]; + if (rtc_memory[addr] != value) this.write(); + return; + } + if (bank == 1 && addr < 0x0d) { + rtc_alarm[addr] = value; + rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0; + rtc_alarm[3] &= ~0x8; + rtc_alarm[5] &= ~0xc; + rtc_alarm[6] &= ~0x8; + rtc_alarm[8] &= ~0xc; + rtc_alarm[10] &= ~0xe; + rtc_alarm[11] &= ~0xc; - } + //var ov = rtc_alarm[addr]; + if (rtc_alarm[addr] != value) this.write(); + return; + } + switch (addr) { + case 0xD: + clock_control_d = value; + break; + case 0xE: + clock_control_e = value; + break; + case 0xF: + clock_control_f = value; + break; + } + } + + }; this.store16 = function (addr, value) { - this.store8(addr, (value >> 8) & 0xff); - this.store8(addr + 1, value & 0xff); - } + this.store8(addr, (value >> 8) & 0xff); + this.store8(addr + 1, value & 0xff); + }; this.store32 = function (addr, value) { this.store16(addr, (value >>> 16) & 0xffff); diff --git a/sae/serial.js b/sae/serial.js index e898e1e..e472117 100644 --- a/sae/serial.js +++ b/sae/serial.js @@ -14,69 +14,65 @@ function Serial() var pos = 0, dtr = false; var serper = 0, serdat = 0x2000; - this.reset = function() - { - this.flushBuffer(); - - pos = 0; - dtr = false; - serper = 0; - serdat = 0x2000; - } + this.reset = function () { + this.flushBuffer(); + + pos = 0; + dtr = false; + serper = 0; + serdat = 0x2000; + }; - this.flushBuffer = function() - { - if (pos > 0) { - var str = '' - for (var i = 0; i < pos; i++) { - /*if (buf[i] == 13) - str += '
    '; - else if (buf[i] == 9) - str += '   '; - else*/ - str += String.fromCharCode(buf[i]); - } - pos = 0; - BUG.col = 3; - BUG.info(str); - BUG.col = 1; - } - } + this.flushBuffer = function () { + if (pos > 0) { + var str = ''; + for (var i = 0; i < pos; i++) { + /*if (buf[i] == 13) + str += '
    '; + else if (buf[i] == 9) + str += '   '; + else*/ + str += String.fromCharCode(buf[i]); + } + pos = 0; + BUG.col = 3; + BUG.info(str); + BUG.col = 1; + } + }; - this.readStatus = function() - { - //ciabpra |= 0x20; //Push up Carrier Detect line - //ciabpra |= 0x08; //DSR ON - return 0; - } + this.readStatus = function () { + //ciabpra |= 0x20; //Push up Carrier Detect line + //ciabpra |= 0x08; //DSR ON + return 0; + }; - this.writeStatus = function(old, nw) - { - if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true; - if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false; - //if ((old & 0x40) != (nw & 0x40)) BUG.info('RTS %s.', (nw & 0x40) == 0x40 ? 'set' : 'clr'); - //if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr'); - return nw; - } + this.writeStatus = function (old, nw) { + if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true; + if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false; + //if ((old & 0x40) != (nw & 0x40)) BUG.info('RTS %s.', (nw & 0x40) == 0x40 ? 'set' : 'clr'); + //if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr'); + return nw; + }; - this.SERPER = function(v) - { - if (serper != v) - serper = v; - } + this.SERPER = function (v) { + if (serper != v) + serper = v; + }; - this.SERDAT = function(v) - { - //BUG.info('SERDAT $%04x', v); + this.SERDAT = function (v) { + //BUG.info('SERDAT $%04x', v); - if (AMIGA.config.serial.enabled) { - buf[pos++] = v & 0xff; - if (pos == 1024) - this.flushBuffer(); - } - serdat |= 0x2000; /* Set TBE in the SERDATR ... */ - AMIGA.intreq |= 1; /* ... and in INTREQ register */ - } + if (AMIGA.config.serial.enabled) { + buf[pos++] = v & 0xff; + if (pos == 1024) + this.flushBuffer(); + } + serdat |= 0x2000; + /* Set TBE in the SERDATR ... */ + AMIGA.intreq |= 1; + /* ... and in INTREQ register */ + }; this.SERDATR = function() { diff --git a/sae/utils.js b/sae/utils.js index d3db3f3..7ea6b91 100644 --- a/sae/utils.js +++ b/sae/utils.js @@ -10,18 +10,18 @@ /* moving average algorithm */ -function mavg(size) { +function MAvg(size) { this.values = new Array(size); this.size = size; this.usage = 0; this.offset = 0; this.average = 0; - this.clr = function() { - this.usage = 0; - this.offset = 0; - this.average = 0; - } + this.clr = function () { + this.usage = 0; + this.offset = 0; + this.average = 0; + }; this.set = function(newval) { if (this.usage < this.size) { @@ -92,131 +92,127 @@ function mavg(size) { */ sprintfWrapper = { - init: function () { - if (typeof arguments == "undefined") { - return null; - } - if (arguments.length < 1) { - return null; - } - if (typeof arguments[0] != "string") { - return null; - } - if (typeof RegExp == "undefined") { - return null; - } + init: function () { + if (typeof arguments == "undefined") { + return null; + } + if (arguments.length < 1) { + return null; + } + if (typeof arguments[0] != "string") { + return null; + } + if (typeof RegExp == "undefined") { + return null; + } - var string = arguments[0]; - var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g); - var matches = new Array(); - var strings = new Array(); - var convCount = 0; - var stringPosStart = 0; - var stringPosEnd = 0; - var matchPosEnd = 0; - var newString = ''; - var match = null; + var string = arguments[0]; + var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g); + var matches = []; + var strings = []; + var convCount = 0; + var stringPosStart = 0; + var stringPosEnd = 0; + var matchPosEnd = 0; + var newString = ''; + var match; - while (match = exp.exec(string)) { - if (match[9]) { - convCount += 1; - } + while (match = exp.exec(string)) { + if (match[9]) { + convCount += 1; + } - stringPosStart = matchPosEnd; - stringPosEnd = exp.lastIndex - match[0].length; - strings[strings.length] = string.substring(stringPosStart, stringPosEnd); + stringPosStart = matchPosEnd; + stringPosEnd = exp.lastIndex - match[0].length; + strings[strings.length] = string.substring(stringPosStart, stringPosEnd); - matchPosEnd = exp.lastIndex; - matches[matches.length] = { - match: match[0], - left: match[3] ? true : false, - sign: match[4] || '', - pad: match[5] || ' ', - min: match[6] || 0, - precision: match[8], - code: match[9] || '%', - negative: parseInt(arguments[convCount]) < 0 ? true : false, - argument: String(arguments[convCount]) - }; - } - strings[strings.length] = string.substring(matchPosEnd); + matchPosEnd = exp.lastIndex; + matches[matches.length] = { + match: match[0], + left: match[3] ? true : false, + sign: match[4] || '', + pad: match[5] || ' ', + min: match[6] || 0, + precision: match[8], + code: match[9] || '%', + negative: !!(parseInt(arguments[convCount]) < 0), + argument: String(arguments[convCount]) + }; + } + strings[strings.length] = string.substring(matchPosEnd); - if (matches.length == 0) { - return string; - } - if ((arguments.length - 1) < convCount) { - return null; - } + if (matches.length == 0) { + return string; + } + if ((arguments.length - 1) < convCount) { + return null; + } - var code = null; - var match = null; - var i = null; + for (var i = 0; i < matches.length; i++) { + var substitution; - for (i = 0; i < matches.length; i++) { + if (matches[i].code == '%') { + substitution = '%' + } else if (matches[i].code == 'b') { + matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2)); + substitution = sprintfWrapper.convert(matches[i], true); + } else if (matches[i].code == 'c') { + matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument))))); + substitution = sprintfWrapper.convert(matches[i], true); + } else if (matches[i].code == 'd') { + matches[i].argument = String(Math.abs(parseInt(matches[i].argument))); + substitution = sprintfWrapper.convert(matches[i]); + } else if (matches[i].code == 'f') { + matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6)); + substitution = sprintfWrapper.convert(matches[i]); + } else if (matches[i].code == 'o') { + matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8)); + substitution = sprintfWrapper.convert(matches[i]); + } else if (matches[i].code == 's') { + matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length); + substitution = sprintfWrapper.convert(matches[i], true); + } else if (matches[i].code == 'x') { + matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); + substitution = sprintfWrapper.convert(matches[i]); + } else if (matches[i].code == 'X') { + matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); + substitution = sprintfWrapper.convert(matches[i]).toUpperCase(); + } else { + substitution = matches[i].match; + } + newString += strings[i]; + newString += substitution; - if (matches[i].code == '%') { - substitution = '%' - } else if (matches[i].code == 'b') { - matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2)); - substitution = sprintfWrapper.convert(matches[i], true); - } else if (matches[i].code == 'c') { - matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument))))); - substitution = sprintfWrapper.convert(matches[i], true); - } else if (matches[i].code == 'd') { - matches[i].argument = String(Math.abs(parseInt(matches[i].argument))); - substitution = sprintfWrapper.convert(matches[i]); - } else if (matches[i].code == 'f') { - matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6)); - substitution = sprintfWrapper.convert(matches[i]); - } else if (matches[i].code == 'o') { - matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8)); - substitution = sprintfWrapper.convert(matches[i]); - } else if (matches[i].code == 's') { - matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length) - substitution = sprintfWrapper.convert(matches[i], true); - } else if (matches[i].code == 'x') { - matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); - substitution = sprintfWrapper.convert(matches[i]); - } else if (matches[i].code == 'X') { - matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); - substitution = sprintfWrapper.convert(matches[i]).toUpperCase(); - } else { - substitution = matches[i].match; - } + } + newString += strings[i]; - newString += strings[i]; - newString += substitution; + return newString; - } - newString += strings[i]; + }, - return newString; - - }, - - convert: function (match, nosign) { - if (nosign) { - match.sign = ''; - } else { - match.sign = match.negative ? '-' : match.sign; - } - var l = match.min - match.argument.length + 1 - match.sign.length; - var pad = new Array(l < 0 ? 0 : l).join(match.pad); - if (!match.left) { - if (match.pad == "0" || nosign) { - return match.sign + pad + match.argument; - } else { - return pad + match.sign + match.argument; - } - } else { - if (match.pad == "0" || nosign) { - return match.sign + match.argument + pad.replace(/0/g, ' '); - } else { - return match.sign + match.argument + pad; - } - } - } -} + convert: function (match, nosign) { + if (nosign) { + match.sign = ''; + } else { + match.sign = match.negative ? '-' : match.sign; + } + var l = match.min - match.argument.length + 1 - match.sign.length; + var pad = new Array(l < 0 ? 0 : l).join(match.pad); + if (!match.left) { + if (match.pad == "0" || nosign) { + return match.sign + pad + match.argument; + } else { + return pad + match.sign + match.argument; + } + } else { + if (match.pad == "0" || nosign) { + return match.sign + match.argument + pad.replace(/0/g, ' '); + } else { + return match.sign + match.argument + pad; + } + } + } +}; sprintf = sprintfWrapper.init; @@ -240,10 +236,11 @@ var BrowserDetect = { if (dataString.indexOf(data[i].subString) != -1) return data[i].identity; } else if (dataProp) return data[i].identity; } + return ''; }, searchVersion: function (dataString) { var index = dataString.indexOf(this.versionSearchString); - if (index == -1) return; + if (index == -1) return 0.0; return parseFloat(dataString.substring(index + this.versionSearchString.length + 1)); }, dataBrowser: [{ @@ -323,7 +320,7 @@ BrowserDetect.init(); /*-----------------------------------------------------------------------*/ -function dump(obj) { +/*function dump(obj) { var out = ''; if (obj) { for (var i in obj) { @@ -333,7 +330,7 @@ function dump(obj) { out = 'undefined'; alert(out); -} +}*/ /*-----------------------------------------------------------------------*/ @@ -396,25 +393,25 @@ function loadRemote(file, crc, callback) { /*-----------------------------------------------------------------------*/ function Debug() { - this.col = 1; + //this.col = 1; this.on = 1; this.say = function (str) { - if (this.on) { - /*var e = document.createElement('span'); - e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484'); - e.innerHTML = buf; - this.debug.appendChild(e); - this.debug.appendChild(document.createElement('br')); - this.debug.scrollTop = this.debug.scrollHeight;*/ - - console.log(str); - /*console.info(str); - console.warn(str); - console.error(str); - console.assert(str);*/ - } - } + if (this.on) { + /*var e = document.createElement('span'); + e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484'); + e.innerHTML = buf; + this.debug.appendChild(e); + this.debug.appendChild(document.createElement('br')); + this.debug.scrollTop = this.debug.scrollHeight;*/ + + console.log(str); + /*console.info(str); + console.warn(str); + console.error(str); + console.assert(str);*/ + } + }; this.info = function () { if (this.on) { @@ -426,56 +423,56 @@ function Debug() { /*-----------------------------------------------------------------------*/ -function Uint64(hi, lo) { +/*function Uint64(hi, lo) { this.hi = hi; this.lo = lo; - this.or = function(v) { - this.hi = (this.hi | v.hi) >>> 0; - this.lo = (this.lo | v.lo) >>> 0; - } + this.or = function (v) { + this.hi = (this.hi | v.hi) >>> 0; + this.lo = (this.lo | v.lo) >>> 0; + }; - this.lshift = function(n) { - if (n) { - if (n < 32) { - var m = Math.pow(2, n) - 1; - var t = this.lo & m; - this.hi = ((this.hi << n) | t) >>> 0; - this.lo = (this.lo << n) >>> 0; + this.lshift = function (n) { + if (n) { + if (n < 32) { + var m = Math.pow(2, n) - 1; + var t = this.lo & m; + this.hi = ((this.hi << n) | t) >>> 0; + this.lo = (this.lo << n) >>> 0; - //BUG.info('lshift %d %x', n, m, t); - } else { - var t = this.lo; - this.hi = (t << (n-32)) >>> 0; - this.lo = 0; + //BUG.info('lshift %d %x', n, m, t); + } else { + var t = this.lo; + this.hi = (t << (n - 32)) >>> 0; + this.lo = 0; - //BUG.info('lshift %d %x', n, t); - } - } - } + //BUG.info('lshift %d %x', n, t); + } + } + }; - this.rshift = function(n) { - if (n) { - if (n < 32) { - var m = Math.pow(2, n) - 1; - var t = this.hi & m; - this.hi = (this.hi >>> n) >>> 0; - this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0; + this.rshift = function (n) { + if (n) { + if (n < 32) { + var m = Math.pow(2, n) - 1; + var t = this.hi & m; + this.hi = (this.hi >>> n) >>> 0; + this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0; - //BUG.info('rshift %d %x %x', n, m, t); - } else { - var t = this.hi; - this.hi = 0; - this.lo = (t >>> (n-32)) >>> 0; + //BUG.info('rshift %d %x %x', n, m, t); + } else { + var t = this.hi; + this.hi = 0; + this.lo = (t >>> (n - 32)) >>> 0; - //BUG.info('rshift %d %x %x', n, t); - } - } - } + //BUG.info('rshift %d %x %x', n, t); + } + } + }; this.print = function() { BUG.info('$%08x%08x', this.hi, this.lo); } -} +}*/ diff --git a/sae/video.js b/sae/video.js index 00124bc..73b254c 100644 --- a/sae/video.js +++ b/sae/video.js @@ -60,7 +60,6 @@ function Vide0() { this.available |= SAEI_Video_Canvas2D; test2 = null; } - test = null; } test = document.createElement('canvas'); if (test && test.getContext) { @@ -143,92 +142,104 @@ function Vide0() { ctx.colorMask(true, true, true, false); } - this.setup = function() { - if (!AMIGA.config.video.enabled) return; - if (open) this.cleanup(); + this.setup = function () { + if (!AMIGA.config.video.enabled) return; + if (open) this.cleanup(); - div = document.getElementById(AMIGA.config.video.id); - if (!div) - Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: '+AMIGA.config.video.id+')'); + div = document.getElementById(AMIGA.config.video.id); + if (!div) + Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: ' + AMIGA.config.video.id + ')'); - scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false; - width = VIDEO_WIDTH << (scale ? 1 : 0); - height = VIDEO_HEIGHT << (scale ? 1 : 0); - size = width * height; - //BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal'); + scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false; + width = VIDEO_WIDTH << (scale ? 1 : 0); + height = VIDEO_HEIGHT << (scale ? 1 : 0); + size = width * height; + //BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal'); - if (this.available & SAEI_Video_Canvas2D) { - canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - canvas.oncontextmenu = function() { return false; } - if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { - canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); } - canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); } - canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); } - canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); } - canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); } - } - if (this.available & SAEI_Video_WebGL) { - ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams); - initGL(); - pixels = new Uint16Array(size); - for (var i = 0; i < size; i++) pixels[i] = 0; - - this.drawpixel = drawpixel_gl; - this.drawline = drawline_gl; - this.render = render_gl; - this.show = show_gl; - } else { - ctx = canvas.getContext('2d'); - imagedata = ctx.createImageData(width, height); - pixels = imagedata.data; - - this.drawpixel = drawpixel_2d; - this.drawline = drawline_2d; - this.render = render_2d; - this.show = show_2d; - } - } else { - if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?')) - Fatal(SAEE_Video_Canvas_Not_Supported, null); - else - AMIGA.config.video.enabled = false; - } - - video = document.createElement('div'); - video.style.width = width + 'px'; - video.style.height = height + 'px'; - video.style.margin = 'auto'; - video.style.webkitTouchCallout = 'none'; - video.style.webkitUserSelect = 'none'; - video.style.khtmlUserSelect = 'none'; - video.style.mozUserSelect = 'none'; - video.style.msUserSelect = 'none'; - video.style.userSelect = 'none'; - if (AMIGA.config.video.enabled) - video.appendChild(canvas); + if (this.available & SAEI_Video_Canvas2D) { + canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + canvas.oncontextmenu = function () { + return false; + }; + if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { + canvas.onmousedown = function (e) { + AMIGA.input.mouse.mousedown(e); + }; + canvas.onmouseup = function (e) { + AMIGA.input.mouse.mouseup(e); + }; + canvas.onmouseover = function (e) { + AMIGA.input.mouse.mouseover(e); + }; + canvas.onmouseout = function (e) { + AMIGA.input.mouse.mouseout(e); + }; + canvas.onmousemove = function (e) { + AMIGA.input.mouse.mousemove(e); + } + } + if (this.available & SAEI_Video_WebGL) { + ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams); + initGL(); + pixels = new Uint16Array(size); + for (var i = 0; i < size; i++) pixels[i] = 0; - div.appendChild(video); - open = true; - } + //this.drawpixel = drawpixel_gl; + this.drawline = drawline_gl; + this.render = render_gl; + this.show = show_gl; + } else { + ctx = canvas.getContext('2d'); + imagedata = ctx.createImageData(width, height); + pixels = imagedata.data; - this.cleanup = function() { - if (open) { - div.removeChild(video); - canvas = null; - imagedata = null; - pixels = null; - video = null; - open = false; - } - } + //this.drawpixel = drawpixel_2d; + this.drawline = drawline_2d; + this.render = render_2d; + this.show = show_2d; + } + } else { + if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?')) + Fatal(SAEE_Video_Canvas_Not_Supported, null); + else + AMIGA.config.video.enabled = false; + } + + video = document.createElement('div'); + video.style.width = width + 'px'; + video.style.height = height + 'px'; + video.style.margin = 'auto'; + video.style.webkitTouchCallout = 'none'; + video.style.webkitUserSelect = 'none'; + video.style.khtmlUserSelect = 'none'; + video.style.mozUserSelect = 'none'; + video.style.msUserSelect = 'none'; + video.style.userSelect = 'none'; + if (AMIGA.config.video.enabled) + video.appendChild(canvas); + + div.appendChild(video); + open = true; + }; + + this.cleanup = function () { + if (open) { + div.removeChild(video); + canvas = null; + imagedata = null; + pixels = null; + video = null; + open = false; + } + }; /*---------------------------------*/ - this.hideCursor = function(hide) { - canvas.style.cursor = hide ? 'none' : 'auto'; - } + /*this.hideCursor = function (hide) { + canvas.style.cursor = hide ? 'none' : 'auto'; + };*/ /*this.clear_pixels = function () { for (var i = 0; i < size; i++) @@ -238,9 +249,9 @@ function Vide0() { /*---------------------------------*/ /* Canvas 2D */ - function drawpixel_2d(x, y, rgb) { + /*function drawpixel_2d(x, y, rgb) { pixels[y * width + x] = rgb; - } + }*/ function drawline_2d(y, data, offs) { var yoffs = (y * width) << 2; @@ -261,9 +272,9 @@ function Vide0() { /*---------------------------------*/ /* WebGL */ - function drawpixel_gl(x, y, rgb) { + /*function drawpixel_gl(x, y, rgb) { pixels[y * width + x] = rgb; - } + }*/ function drawline_gl(y, data, offs) { var yoffs = y * width;
Game -
Demo -