update 0.8.3

This commit is contained in:
Rupert Hausberger 2015-03-22 19:15:45 +01:00
commit 2276cd4df8
25 changed files with 9847 additions and 9836 deletions

1
ga.js
View file

@ -10,3 +10,4 @@ _gaq.push(['_trackPageview']);
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 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); var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})(); })();

99
gpl.htm
View file

@ -4,7 +4,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GNU General Public License v2.0 - GNU Project - Free Software Foundation (FSF)</title> <title>GNU General Public License v2.0 - GNU Project - Free Software Foundation (FSF)</title>
<link rel="alternate" type="application/rdf+xml" <link rel="alternate" type="application/rdf+xml"
href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.rdf"> href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.rdf">
</head> </head>
<body> <body>
<h3><a id="SEC1">GNU GENERAL PUBLIC LICENSE</a></h3> <h3><a id="SEC1">GNU GENERAL PUBLIC LICENSE</a></h3>
@ -138,33 +138,33 @@ above, provided that you also meet all of these conditions:
<dl> <dl>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>a)</strong> <strong>a)</strong>
You must cause the modified files to carry prominent notices You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change. stating that you changed the files and the date of any change.
</dd> </dd>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>b)</strong> <strong>b)</strong>
You must cause any work that you distribute or publish, that in You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License. parties under the terms of this License.
</dd> </dd>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>c)</strong> <strong>c)</strong>
If the modified program normally reads commands interactively If the modified program normally reads commands interactively
when run, you must cause it, when started running for such when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
</dd> </dd>
</dl> </dl>
<p> <p>
@ -205,31 +205,31 @@ Sections 1 and 2 above provided that you also do one of the following:
<dl> <dl>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>a)</strong> <strong>a)</strong>
Accompany it with the complete corresponding machine-readable Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or, 1 and 2 above on a medium customarily used for software interchange; or,
</dd> </dd>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>b)</strong> <strong>b)</strong>
Accompany it with a written offer, valid for at least three Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or, customarily used for software interchange; or,
</dd> </dd>
<dt></dt> <dt></dt>
<dd> <dd>
<strong>c)</strong> <strong>c)</strong>
Accompany it with the information you received as to the offer Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such received the program in object code or executable form with such
an offer, in accord with Subsection b above.) an offer, in accord with Subsection b above.)
</dd> </dd>
</dl> </dl>
<p> <p>
@ -484,3 +484,4 @@ instead of this License.
</p> </p>
</body></html> </body></html>

View file

@ -204,3 +204,4 @@ div.float_item {
div.float_clear { div.float_clear {
clear: both; clear: both;
}*/ }*/

View file

@ -80,7 +80,7 @@
<tr> <tr>
<td class="armsb"><label for="cfg_game">Game</label></td> <td class="armsb"><label for="cfg_game">Game</label></td>
<td> <td>
<select id="cfg_game" size="1" onchange="preSelect(1)"> <select id="cfg_game" size="1" onchange="preSelect(1)">
<option value="0">- select -</option> <option value="0">- select -</option>
</select> </select>
</td> </td>
@ -88,7 +88,7 @@
<tr> <tr>
<td class="armsb"><label for="cfg_demo">Demo</label></td> <td class="armsb"><label for="cfg_demo">Demo</label></td>
<td> <td>
<select id="cfg_demo" size="1" onchange="preSelect(2)"> <select id="cfg_demo" size="1" onchange="preSelect(2)">
<option value="0">- select -</option> <option value="0">- select -</option>
</select> </select>
</td> </td>
@ -373,18 +373,6 @@
<option value="2">On (best)</option> <option value="2">On (best)</option>
</select> </select>
</td> </td>
<td class="arm">Samplerate:</td>
<td>
<select id="cfg_audio_rate" size="1">
<option value="1">11025</option>
<option value="2">22050</option>
<option value="3">44100</option>
<option value="4">48000</option>
</select>
Hz
</td>
</tr>
<tr>
<td class="arm">Channels:</td> <td class="arm">Channels:</td>
<td> <td>
<select id="cfg_audio_channels" size="1"> <select id="cfg_audio_channels" size="1">
@ -608,7 +596,7 @@
<div style="height:6px"></div> <div style="height:6px"></div>
<div id="foot" class="foot" style="line-height:14px"> <div id="foot" class="foot" style="line-height:14px">
<span class="gray">2012-2015 Rupert Hausberger</span> | <span class="gray">2012-2015 Rupert Hausberger</span> |
<span class="gray">ver 0.8.2</span> | <span class="gray">ver 0.8.3</span> |
<a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">Source-code</a> | <a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">Source-code</a> |
<a target="_blank" href="readme.htm">Description</a> <a target="_blank" href="readme.htm">Description</a>
</div> </div>

161
index.js
View file

@ -76,7 +76,7 @@ const db = [
], ],
['9 Fingers', 'Spaceballs', '1993', ['9 Fingers', 'Spaceballs', '1993',
['9 Fingers (Disk 1).adf', ['9 Fingers (Disk 1).adf',
'9 Fingers (Disk 2).adf',false,false], [false, true], '9 Fingers (Disk 2).adf',false,false], [false, false],
[true, 16, 17, false], [], [], false [true, 16, 17, false], [], [], false
], ],
['Alpha and Omega', 'Pure Metal Coders', '1991', ['Alpha and Omega', 'Pure Metal Coders', '1991',
@ -96,10 +96,10 @@ const db = [
['Elysium.adf',false,false,false], [false, true], ['Elysium.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [], false [true, 16, 17, false], [], [], false
], ],
['Ecliptica', 'TRSI', '1991', /*crash ['Ecliptica', 'TRSI', '1991',
['Ecliptica.adf',false,false,false], [false, true], ['Ecliptica.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [], false [true, 16, 17, false], [], [], false
], ],*/
['Enigma', 'Phenomena', '1991', ['Enigma', 'Phenomena', '1991',
['Enigma.adf',false,false,false], [false, true], ['Enigma.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [], false [true, 16, 17, false], [], [], false
@ -175,11 +175,12 @@ var dbNum = 0;
const aros_rom_file = 'aros-amiga-m68k-rom.bin'; const aros_rom_file = 'aros-amiga-m68k-rom.bin';
const aros_rom_url = 'http://'+window.location.hostname+'/db/'+aros_rom_file; const aros_rom_url = 'http://'+window.location.hostname+'/db/'+aros_rom_file;
const aros_rom_size = 0x80000; const aros_rom_size = 0x80000;
const aros_rom_crc = 0x48dfadd; //0xea48b4d1 const aros_rom_crc = 0xbe091f38; //0x48dfadd; //0xea48b4d1
const aros_ext_file = 'aros-amiga-m68k-ext.bin'; const aros_ext_file = 'aros-amiga-m68k-ext.bin';
const aros_ext_url = 'http://'+window.location.hostname+'/db/'+aros_ext_file; const aros_ext_url = 'http://'+window.location.hostname+'/db/'+aros_ext_file;
const aros_ext_size = 0x80000; const aros_ext_size = 0x80000;
const aros_ext_crc = 0xaaf211d6; //0x60871435 const aros_ext_crc = 0x3f3fdce0; //0xaaf211d6; //0x60871435
var mode = 0; var mode = 0;
var paused = false; var paused = false;
@ -205,41 +206,41 @@ function Cache() {
var disks = []; var disks = [];
this.loadRom = function (num) { this.loadRom = function (num) {
if (roms[num]) { if (roms[num]) {
console.log('loadRom.loadRom() %d is cached', num); console.log('loadRom.loadRom() %d is cached', num);
return roms[num]; return roms[num];
} }
console.log('loadRom.loadRom() downloading %d', num); console.log('loadRom.loadRom() downloading %d', num);
var url, size, crc; var url, size, crc;
switch (num) { switch (num) {
case 0: case 0:
url = aros_rom_url; url = aros_rom_url;
size = aros_rom_size; size = aros_rom_size;
crc = aros_rom_crc; crc = aros_rom_crc;
break; break;
case 1: case 1:
url = aros_ext_url; url = aros_ext_url;
size = aros_ext_size; size = aros_ext_size;
crc = aros_ext_crc; crc = aros_ext_crc;
break; break;
} }
var data = loadRemoteSync(url); var data = loadRemoteSync(url);
if (typeof(data) == 'number') { if (typeof(data) == 'number') {
alert('Can\'t download ' + url + ' (http status: ' + data + ')'); alert('Can\'t download ' + url + ' (http status: ' + data + ')');
} else { } else {
if (data.length == size) { if (data.length == size) {
//console.log(dechex(crc32(data))); //console.log(dechex(crc32(data)));
if (crc32(data) == crc) { if (crc32(data) == crc) {
roms[num] = data; roms[num] = data;
return data; return data;
} else } else
alert('Wrong checksum for ' + url + ' (is $' + dechex(crc32(data)) + ', should $' + dechex(crc) + ')\n\nFlush the browser-cache with "Ctrl+Shift+Del" and press F5 to reload...'); alert('Wrong checksum for ' + url + ' (is $' + dechex(crc32(data)) + ', should $' + dechex(crc) + ')\n\nFlush the browser-cache with "Ctrl+Shift+Del" and press F5 to reload...');
} else } else
alert('Wrong file-length for ' + url + ' (' + size + ')'); alert('Wrong file-length for ' + url + ' (' + size + ')');
} }
return null; return null;
}; };
this.loadDisk = function(url) { this.loadDisk = function(url) {
for (var i = 0; i < disks.length; i++) { for (var i = 0; i < disks.length; i++) {
@ -364,22 +365,22 @@ function disabled(id, d) {
/*function toggleFullScreen() { /*function toggleFullScreen() {
if ((document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method if ((document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method
(!document.mozFullScreenElement && !document.webkitFullScreenElement)) { // current working methods (!document.mozFullScreenElement && !document.webkitFullScreenElement)) { // current working methods
if (document.documentElement.requestFullScreen) { if (document.documentElement.requestFullScreen) {
document.documentElement.requestFullScreen(); document.documentElement.requestFullScreen();
} else if (document.documentElement.mozRequestFullScreen) { } else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen(); document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) { } else if (document.documentElement.webkitRequestFullScreen) {
document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
} }
} else { } else {
if (document.cancelFullScreen) { if (document.cancelFullScreen) {
document.cancelFullScreen(); document.cancelFullScreen();
} else if (document.mozCancelFullScreen) { } else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen(); document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) { } else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen(); document.webkitCancelFullScreen();
} }
} }
}*/ }*/
@ -400,19 +401,19 @@ function loadLocal(e, callback) {
req.open('GET', url, true); req.open('GET', url, true);
req.overrideMimeType('text\/plain; charset=x-user-defined'); req.overrideMimeType('text\/plain; charset=x-user-defined');
req.onreadystatechange = function (e) { req.onreadystatechange = function (e) {
if (req.readyState == 4) { if (req.readyState == 4) {
if (req.status == 200) { if (req.status == 200) {
if (req.responseText.length == size) { if (req.responseText.length == size) {
if (crc === false || crc32(req.responseText) == crc) if (crc === false || crc32(req.responseText) == crc)
callback(0, req.responseText); callback(0, req.responseText);
else else
callback(1, crc32(req.responseText)); callback(1, crc32(req.responseText));
} else } else
callback(2, req.responseText.length); callback(2, req.responseText.length);
} else } else
callback(3, req.status); callback(3, req.status);
} }
}; };
req.send(null); req.send(null);
}*/ }*/
function loadRemoteSync(url) { function loadRemoteSync(url) {
@ -599,7 +600,6 @@ function getSimpleConfig() {
if (config.audio.enabled) { if (config.audio.enabled) {
config.audio.mode = SAEV_Config_Audio_Mode_Play_Best; config.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
config.audio.channels = SAEV_Config_Audio_Channels_Stereo; config.audio.channels = SAEV_Config_Audio_Channels_Stereo;
config.audio.rate = SAEV_Config_Audio_Rate_44100;
} }
/*if (info.audio == 0) { /*if (info.audio == 0) {
config.audio.enabled = false; config.audio.enabled = false;
@ -713,7 +713,7 @@ function fireButtonName(fire) {
case 145: return 'Scroll lock'; case 145: return 'Scroll lock';
case 49: return '1'; case 49: return '1';
case 50: return '2'; case 50: return '2';
default: return 'ERROR'; default: return 'ERROR';
} }
} }
@ -823,12 +823,6 @@ function setConfig() {
case SAEV_Config_Audio_Channels_Mono: document.getElementById('cfg_audio_channels')[0].selected = true; break; case SAEV_Config_Audio_Channels_Mono: document.getElementById('cfg_audio_channels')[0].selected = true; break;
case SAEV_Config_Audio_Channels_Stereo: document.getElementById('cfg_audio_channels')[1].selected = true; break; case SAEV_Config_Audio_Channels_Stereo: document.getElementById('cfg_audio_channels')[1].selected = true; break;
} }
switch (config.audio.rate) {
case SAEV_Config_Audio_Rate_11025: document.getElementById('cfg_audio_rate')[0].selected = true; break;
case SAEV_Config_Audio_Rate_22050: document.getElementById('cfg_audio_rate')[1].selected = true; break;
case SAEV_Config_Audio_Rate_44100: document.getElementById('cfg_audio_rate')[2].selected = true; break;
case SAEV_Config_Audio_Rate_48000: document.getElementById('cfg_audio_rate')[3].selected = true; break;
}
document.getElementById('cfg_audio_filter').checked = config.audio.filter != 0; document.getElementById('cfg_audio_filter').checked = config.audio.filter != 0;
styleDisplayTable('cfg_audio_grp', config.audio.enabled); styleDisplayTable('cfg_audio_grp', config.audio.enabled);
@ -880,7 +874,7 @@ function getMask(type) {
case SAEV_Config_Chipset_Type_OCS: return SAEV_Config_Chipset_Mask_OCS; 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_AGNUS: return SAEV_Config_Chipset_Mask_ECS_AGNUS;
case SAEV_Config_Chipset_Type_ECS_DENISE: return SAEV_Config_Chipset_Mask_ECS_DENISE; case SAEV_Config_Chipset_Type_ECS_DENISE: return SAEV_Config_Chipset_Mask_ECS_DENISE;
default: return SAEV_Config_Chipset_Mask_OCS; default: return SAEV_Config_Chipset_Mask_OCS;
} }
} }
@ -925,8 +919,6 @@ function getConfig() {
config.audio.mode = parseInt(getSelectValue(e)); config.audio.mode = parseInt(getSelectValue(e));
e = document.getElementById('cfg_audio_channels'); e = document.getElementById('cfg_audio_channels');
config.audio.channels = parseInt(getSelectValue(e)); config.audio.channels = parseInt(getSelectValue(e));
e = document.getElementById('cfg_audio_rate');
config.audio.rate = parseInt(getSelectValue(e));
config.audio.filter = document.getElementById('cfg_audio_filter').checked ? true : false; config.audio.filter = document.getElementById('cfg_audio_filter').checked ? true : false;
} }
@ -1101,8 +1093,8 @@ function stop() {
var e = document.getElementById('status_pr'); var e = document.getElementById('status_pr');
e.value = 'pause'; e.value = 'pause';
e.onclick = function () { e.onclick = function () {
pause(1); pause(1);
}; };
paused = false; paused = false;
} }
if (dskchg) if (dskchg)
@ -1129,8 +1121,8 @@ function pause(p) {
var e = document.getElementById('status_pr'); var e = document.getElementById('status_pr');
e.innerHTML = p ? 'Resume' : 'Pause'; e.innerHTML = p ? 'Resume' : 'Pause';
e.onclick = function () { e.onclick = function () {
pause(1 - p); pause(1 - p);
}; };
paused = p; paused = p;
@ -1249,7 +1241,7 @@ function romAROS() {
styleDisplayInline('cfg_ext_remove', 1); styleDisplayInline('cfg_ext_remove', 1);
styleDisplayTableRow('cfg_ext_addr_grp', 1); styleDisplayTableRow('cfg_ext_addr_grp', 1);
disabled('cfg_rom_aros', 0); disabled('cfg_rom_aros', 0);
return true; return true;
} }
function romSelect() { function romSelect() {
@ -1481,7 +1473,7 @@ function dskchgInsert() {
if (!dskchg) return; if (!dskchg) return;
var n = getSelectValue(document.getElementById('cfg_dskchg_unit')); var n = getSelectValue(document.getElementById('cfg_dskchg_unit'));
var e = document.getElementById('cfg_dskchg_file').files[0]; var e = document.getElementById('cfg_dskchg_file').files[0];
var ok = true; //false; var ok = true; //false;
if (!e) return; if (!e) return;
/*if (e.size == 0xDC000) { /*if (e.size == 0xDC000) {
@ -1539,3 +1531,4 @@ function dskchgSelect() {
}); });
} }
} }

View file

@ -78,7 +78,7 @@
<ul> <ul>
<li><span class="fwb">Written and ported by</span> <li><span class="fwb">Written and ported by</span>
<ul> <ul>
<li>Rupert Hausberger &lt;<a href="mailto:rupert_hausberger@gmx.net">rupert_hausberger@gmx.net</a>&gt; (<a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=ZJA3YVT6EP55A">donate</a>)</li> <li>Rupert Hausberger &lt;<a href="mailto:rupert_hausberger@gmx.net">rupert_hausberger@gmx.net</a>&gt;</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -99,7 +99,7 @@
<ul> <ul>
<li><span class="fwb">Thanks</span> <li><span class="fwb">Thanks</span>
<ul> <ul>
<li><a target="_blank" href="http://www.amigaemulator.org">Bernd Schmidt</a></li> <!--<li><a target="_blank" href="http://www.amigaemulator.org">Bernd Schmidt</a></li>-->
<li><a target="_blank" href="http://winuae.net">WinUAE team</a></li> <li><a target="_blank" href="http://winuae.net">WinUAE team</a></li>
<li><a target="_blank" href="http://aros.org">AROS team</a></li> <li><a target="_blank" href="http://aros.org">AROS team</a></li>
</ul> </ul>
@ -117,6 +117,31 @@
<ul> <ul>
<li><span class="fwb">History</span> <li><span class="fwb">History</span>
<ul> <ul>
<li><span class="fwb">0.8.3 (22.03.2015)</span>
<ul>
<li>Audio
<ul>
<li>Fixed a heavy bug i added myself around v0.6-0.7 on the seek for other bugs. Big thanks to 'Ralf Sommer'.</li>
<li>Dropped usage of the ring-buffer and wrote a new and faster queue-buffer.</li>
<li>The audio-data is now first sampled at 15.65KHz and then resampled to<br />
the rate of the soundcard. This does reduce internal CPU-usage.</li>
<li>Removed 'Audio/Samplerate' in the GUI, because it's no longer used.<br />
</ul>
</li>
<li>Events
<ul>
<li>Fixed a bug in combination with frameskip.</li>
<li>Frameskip is now disabled by default.</li>
</ul>
</li>
<li>Common
<ul>
<li>Updated AROS-ROMs to actual version SVN50213.</li>
</ul>
</li>
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.8.2 (10.01.2015)</span> <li><span class="fwb">0.8.2 (10.01.2015)</span>
<ul> <ul>
<li>Audio <li>Audio

View file

@ -52,57 +52,57 @@ function Amiga() {
/*---------------------------------*/ /*---------------------------------*/
this.setup = function () { this.setup = function () {
this.mem.setup(); this.mem.setup();
this.expansion.setup(); this.expansion.setup();
this.events.setup(); this.events.setup();
this.playfield.setup(); this.playfield.setup();
this.video.setup(); this.video.setup();
this.cia.setup(); this.cia.setup();
this.rtc.setup(); this.rtc.setup();
this.input.setup(); this.input.setup();
this.disk.setup(); this.disk.setup();
this.audio.setup(); this.audio.setup();
this.custom.setup(); this.custom.setup();
this.cpu.setup(); this.cpu.setup();
}; };
this.cleanup = function () { this.cleanup = function () {
this.audio.cleanup(); this.audio.cleanup();
this.video.cleanup(); this.video.cleanup();
this.playfield.cleanup(); this.playfield.cleanup();
this.input.cleanup(); this.input.cleanup();
}; };
this.reset = function () { this.reset = function () {
BUG.info('Amiga.reset()'); BUG.info('Amiga.reset()');
this.delay = 0; this.delay = 0;
this.spcflags = 0; this.spcflags = 0;
//this.loading = 0; //this.loading = 0;
this.intena = 0; this.intena = 0;
this.intreq = 0; this.intreq = 0;
this.dmacon = 0; this.dmacon = 0;
this.adkcon = 0; this.adkcon = 0;
this.expansion.reset(); this.expansion.reset();
this.events.reset(); this.events.reset();
this.playfield.reset(); this.playfield.reset();
this.cia.reset(); this.cia.reset();
this.disk.reset(); this.disk.reset();
this.input.reset(); this.input.reset();
this.serial.reset(); this.serial.reset();
this.blitter.reset(); this.blitter.reset();
this.copper.reset(); this.copper.reset();
this.audio.reset(); this.audio.reset();
this.custom.reset(); this.custom.reset();
this.cpu.reset(this.mem.rom.lower); this.cpu.reset(this.mem.rom.lower);
}; };
this.dump = function () { this.dump = function () {
this.cpu.dump(); this.cpu.dump();
//this.cia.dump(); //this.cia.dump();
}; };
/*---------------------------------*/ /*---------------------------------*/
@ -122,27 +122,27 @@ function Amiga() {
this.start = function () { this.start = function () {
if (this.state == ST_STOP) { if (this.state == ST_STOP) {
this.setup(); this.setup();
this.reset(); this.reset();
this.state = ST_CYCLE; this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0); setTimeout('AMIGA.cycle()', 0);
} }
}; };
this.stop = function () { this.stop = function () {
if (this.state != ST_STOP) { if (this.state != ST_STOP) {
this.state = ST_STOP; this.state = ST_STOP;
this.cleanup(); this.cleanup();
} }
}; };
this.pause = function (state) { this.pause = function (state) {
if (this.state != ST_STOP) { if (this.state != ST_STOP) {
this.state = state ? ST_PAUSE : ST_CYCLE; this.state = state ? ST_PAUSE : ST_CYCLE;
this.audio.pauseResume(state); this.audio.pauseResume(state);
} }
}; };
/*this.insert = function(unit, name, data) { /*this.insert = function(unit, name, data) {
//this.disk.insert_data(unit, data); //this.disk.insert_data(unit, data);
@ -161,192 +161,192 @@ function Amiga() {
*/ */
this.insert = function (unit) { this.insert = function (unit) {
if (this.state != ST_STOP) if (this.state != ST_STOP)
this.disk.insert(unit); this.disk.insert(unit);
}; };
this.eject = function (unit) { this.eject = function (unit) {
if (this.state != ST_STOP) if (this.state != ST_STOP)
this.disk.eject(unit); this.disk.eject(unit);
}; };
/*---------------------------------*/ /*---------------------------------*/
/* mainloop */ /* mainloop */
this.cycle = function () { this.cycle = function () {
try { try {
this.cpu.cycle(); this.cpu.cycle();
} catch (e) { } catch (e) {
if (e instanceof VSync) { if (e instanceof VSync) {
//console.log(e.error, e.message); //console.log(e.error, e.message);
this.state = ST_IDLE; this.state = ST_IDLE;
} else if (e instanceof FatalError) { } else if (e instanceof FatalError) {
this.state = ST_STOP; this.state = ST_STOP;
this.stop(); this.stop();
this.config.hooks.error(e.error, e.message); this.config.hooks.error(e.error, e.message);
} else /* normal exception */ { } else /* normal exception */ {
this.state = ST_STOP; this.state = ST_STOP;
this.stop(); this.stop();
console.log(e); console.log(e);
} }
} }
if (this.state == ST_IDLE) { if (this.state == ST_IDLE) {
this.state = ST_CYCLE; this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', this.delay); setTimeout('AMIGA.cycle()', this.delay);
} }
else if (this.state == ST_PAUSE) else if (this.state == ST_PAUSE)
AMIGA.cyclePause(); AMIGA.cyclePause();
else else
AMIGA.cycleExit(); AMIGA.cycleExit();
}; };
this.cyclePause = function () { this.cyclePause = function () {
if (this.state == ST_CYCLE) if (this.state == ST_CYCLE)
setTimeout('AMIGA.cycle()', 0); setTimeout('AMIGA.cycle()', 0);
else if (this.state == ST_PAUSE) else if (this.state == ST_PAUSE)
setTimeout('AMIGA.cyclePause()', 500); setTimeout('AMIGA.cyclePause()', 500);
else else
AMIGA.cycleExit(); AMIGA.cycleExit();
}; };
this.cycleExit = function () { this.cycleExit = function () {
this.dump(); this.dump();
//this.cia.dump(); //this.cia.dump();
}; };
/*---------------------------------*/ /*---------------------------------*/
this.dmaen = function (dmamask) { 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.DMACONR = function (hpos) {
this.playfield.decide_line(hpos); this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos); this.playfield.decide_fetch(hpos);
this.dmacon &= ~(0x4000 | 0x2000); this.dmacon &= ~(0x4000 | 0x2000);
var iz = this.blitter.getIntZero(); var iz = this.blitter.getIntZero();
this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0)); this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0));
return this.dmacon; return this.dmacon;
}; };
this.DMACON = function (v, hpos) { this.DMACON = function (v, hpos) {
var oldcon = this.dmacon; var oldcon = this.dmacon;
this.playfield.decide_line(hpos); this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos); this.playfield.decide_fetch(hpos);
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.dmacon |= v & ~INTF_SETCLR; this.dmacon |= v & ~INTF_SETCLR;
else else
this.dmacon &= ~v; this.dmacon &= ~v;
this.dmacon &= 0x1fff; this.dmacon &= 0x1fff;
var changed = this.dmacon ^ oldcon; var changed = this.dmacon ^ oldcon;
var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0; var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0;
var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0; var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0;
if (oldcop != newcop) { if (oldcop != newcop) {
if (newcop && !oldcop) { if (newcop && !oldcop) {
this.copper.compute_spcflag_copper(this.events.hpos()); this.copper.compute_spcflag_copper(this.events.hpos());
} else if (!newcop) { } else if (!newcop) {
this.copper.enabled_thisline = false; this.copper.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
} }
} }
if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done) if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done)
set_special(SPCFLAG_BLTNASTY); set_special(SPCFLAG_BLTNASTY);
if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init) if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init)
this.blitter.setState(BLT_work); this.blitter.setState(BLT_work);
if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN))
clr_special(SPCFLAG_BLTNASTY); clr_special(SPCFLAG_BLTNASTY);
if (changed & (DMAF_DMAEN | 0x0f)) if (changed & (DMAF_DMAEN | 0x0f))
this.audio.state_machine(); this.audio.state_machine();
if (changed & (DMAF_DMAEN | DMAF_BPLEN)) { if (changed & (DMAF_DMAEN | DMAF_BPLEN)) {
this.playfield.update_ddf_change(); this.playfield.update_ddf_change();
if (this.dmaen(DMAF_BPLEN)) if (this.dmaen(DMAF_BPLEN))
this.playfield.maybe_start_bpl_dma(hpos); this.playfield.maybe_start_bpl_dma(hpos);
} }
this.events.schedule(); this.events.schedule();
}; };
/*---------------------------------*/ /*---------------------------------*/
this.ADKCONR = function () { this.ADKCONR = function () {
return this.adkcon; return this.adkcon;
}; };
this.ADKCON = function (v, hpos) { this.ADKCON = function (v, hpos) {
if (this.config.audio.enabled) if (this.config.audio.enabled)
this.audio.update(); this.audio.update();
this.disk.update(hpos); this.disk.update(hpos);
this.disk.update_adkcon(v); this.disk.update_adkcon(v);
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.adkcon |= v & ~INTF_SETCLR; this.adkcon |= v & ~INTF_SETCLR;
else else
this.adkcon &= ~v; this.adkcon &= ~v;
this.audio.update_adkmasks(); this.audio.update_adkmasks();
}; };
/*---------------------------------*/ /*---------------------------------*/
this.INTENAR = function () { this.INTENAR = function () {
return this.intena; return this.intena;
}; };
this.INTENA = function (v) { this.INTENA = function (v) {
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.intena |= v & ~INTF_SETCLR; this.intena |= v & ~INTF_SETCLR;
else else
this.intena &= ~v; this.intena &= ~v;
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.doint(); this.doint();
}; };
/*---------------------------------*/ /*---------------------------------*/
this.INTREQR = function () { this.INTREQR = function () {
return this.intreq; return this.intreq;
}; };
this.INTREQ_0 = function (v) { this.INTREQ_0 = function (v) {
var old = this.intreq; var old = this.intreq;
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.intreq |= v & ~INTF_SETCLR; this.intreq |= v & ~INTF_SETCLR;
else else
this.intreq &= ~v; this.intreq &= ~v;
if ((v & INTF_SETCLR) && this.intreq != old) if ((v & INTF_SETCLR) && this.intreq != old)
this.doint(); this.doint();
}; };
this.INTREQ = function (v) { this.INTREQ = function (v) {
this.INTREQ_0(v); this.INTREQ_0(v);
this.cia.rethink(); this.cia.rethink();
}; };
/*---------------------------------*/ /*---------------------------------*/
this.intlev = function () { this.intlev = function () {
var imask = this.intreq & this.intena; var imask = this.intreq & this.intena;
if (imask && (this.intena & INTF_INTEN)) { if (imask && (this.intena & INTF_INTEN)) {
if (imask & 0x2000) return 6; if (imask & 0x2000) return 6;
if (imask & 0x1800) return 5; if (imask & 0x1800) return 5;
if (imask & 0x0780) return 4; if (imask & 0x0780) return 4;
if (imask & 0x0070) return 3; if (imask & 0x0070) return 3;
if (imask & 0x0008) return 2; if (imask & 0x0008) return 2;
if (imask & 0x0007) return 1; if (imask & 0x0007) return 1;
} }
return -1; return -1;
}; };
this.doint = function() { this.doint = function() {
if (AMIGA.config.cpu.compatible) if (AMIGA.config.cpu.compatible)
@ -421,5 +421,6 @@ function SAE(x) {
} }
//return SAEE_None; //return SAEE_None;
//return { error:SAEE_None, message:'' }; //return { error:SAEE_None, message:'' };
return 0; return 0;
} }

File diff suppressed because it is too large Load diff

View file

@ -129,10 +129,10 @@ function Blitter() {
/*---------------------------------*/ /*---------------------------------*/
this.reset = function () { this.reset = function () {
bltstate = BLT_done; bltstate = BLT_done;
blit_interrupt = true; blit_interrupt = true;
blit_stuck = 0; 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('PT A=%08X B=%08X C=%08X D=%08X', bltapt, bltbpt, bltcpt, bltdpt);
@ -2010,7 +2010,7 @@ function Blitter() {
case 0xfd: return (~c) | (b) | (a); case 0xfd: return (~c) | (b) | (a);
case 0xfe: return (c) | (b) | (a); case 0xfe: return (c) | (b) | (a);
case 0xff: return 0xffff; case 0xff: return 0xffff;
default: return 0; default: return 0;
} }
} }
@ -2400,22 +2400,22 @@ function Blitter() {
/*---------------------------------*/ /*---------------------------------*/
this.handler = function (data) { this.handler = function (data) {
if (!AMIGA.dmaen(DMAF_BLTEN)) { if (!AMIGA.dmaen(DMAF_BLTEN)) {
AMIGA.events.newevent(EV2_BLITTER, 10, 0); AMIGA.events.newevent(EV2_BLITTER, 10, 0);
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate) if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
return; return;
BUG.info('blitter_handler() force-unstuck!'); BUG.info('blitter_handler() force-unstuck!');
} }
blit_stuck = 0; blit_stuck = 0;
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) { if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
//console.log('Blitter.handler () slowdown', blit_slowdown); //console.log('Blitter.handler () slowdown', blit_slowdown);
AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0); AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
blit_slowdown = -1; blit_slowdown = -1;
return; return;
} }
blitter_do(); blitter_do();
}; };
var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0; var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0;
//var freezes = 10; //var freezes = 10;
@ -2609,228 +2609,229 @@ function Blitter() {
var warned2 = 10; var warned2 = 10;
this.maybe_blit = function (hpos, hack) { this.maybe_blit = function (hpos, hack) {
if (bltstate == BLT_done) if (bltstate == BLT_done)
return; return;
if (AMIGA.dmaen(DMAF_BLTEN)) { if (AMIGA.dmaen(DMAF_BLTEN)) {
var doit = false; var doit = false;
if (AMIGA.config.blitter.waiting == 3) { // always if (AMIGA.config.blitter.waiting == 3) { // always
doit = true; doit = true;
} else if (AMIGA.config.blitter.waiting == 2) { // no idle } else if (AMIGA.config.blitter.waiting == 2) { // no idle
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true; doit = true;
} else if (AMIGA.config.blitter.waiting == 1) { // automatic } else if (AMIGA.config.blitter.waiting == 1) { // automatic
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY)) if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true; doit = true;
else if (AMIGA.config.cpu.speed < 0) else if (AMIGA.config.cpu.speed < 0)
doit = true; doit = true;
} }
if (doit) { if (doit) {
if (waitingblits()) if (waitingblits())
return; return;
} }
} }
if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) { if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) {
warned2--; warned2--;
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter); BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
} }
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles) if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
return; return;
AMIGA.blitter.handler(0); AMIGA.blitter.handler(0);
}; };
this.blitnasty = function () { this.blitnasty = function () {
if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN)) if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
return 0; return 0;
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0]) if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
return 0; return 0;
var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV); var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
var ccnt = 0; var ccnt = 0;
while (blit_last_cycle < cycles) { while (blit_last_cycle < cycles) {
if (!channel_state(blit_last_cycle++)) if (!channel_state(blit_last_cycle++))
ccnt++; ccnt++;
} }
return ccnt; return ccnt;
}; };
/*---------------------------------*/ /*---------------------------------*/
var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0; var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0;
this.slowdown = function () { this.slowdown = function () {
var data = AMIGA.playfield.getData(); var data = AMIGA.playfield.getData();
var ddfstrt = data[0]; var ddfstrt = data[0];
var ddfstop = data[1]; var ddfstop = data[1];
var totalcycles = data[2]; var totalcycles = data[2];
var freecycles = data[3]; var freecycles = data[3];
if (!totalcycles || ddfstrt < 0 || ddfstop < 0) if (!totalcycles || ddfstrt < 0 || ddfstop < 0)
return; return;
if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) {
var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles); var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles);
var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles); var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles);
var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]); var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]);
oddfstrt = ddfstrt; oddfstrt = ddfstrt;
oddfstop = ddfstop; oddfstop = ddfstop;
ototal = totalcycles; ototal = totalcycles;
ofree = freecycles; ofree = freecycles;
slow = 0; slow = 0;
if (dmacycles > freelinecycles) if (dmacycles > freelinecycles)
slow = dmacycles - freelinecycles; slow = dmacycles - freelinecycles;
} }
if (blit_slowdown < 0 || blitline) if (blit_slowdown < 0 || blitline)
return; return;
blit_slowdown += slow; blit_slowdown += slow;
}; };
/*---------------------------------*/ /*---------------------------------*/
this.BLTADAT = function (hpos, v) { this.BLTADAT = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
blt_info.bltadat = v; blt_info.bltadat = v;
}; };
this.BLTBDAT = function (hpos, v) { this.BLTBDAT = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
if (bltcon1 & 2) if (bltcon1 & 2)
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff; blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
else else
blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff; blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff;
blt_info.bltbdat = v; blt_info.bltbdat = v;
}; };
this.BLTCDAT = function (hpos, v) { this.BLTCDAT = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
blt_info.bltcdat = v; blt_info.bltcdat = v;
reset_blit(0); reset_blit(0);
}; };
this.BLTAMOD = function (hpos, v) { this.BLTAMOD = function (hpos, v) {
this.maybe_blit(hpos, 1); this.maybe_blit(hpos, 1);
blt_info.bltamod = castWord(v & 0xfffe); blt_info.bltamod = castWord(v & 0xfffe);
reset_blit(0); reset_blit(0);
}; };
this.BLTBMOD = function (hpos, v) { this.BLTBMOD = function (hpos, v) {
this.maybe_blit(hpos, 1); this.maybe_blit(hpos, 1);
blt_info.bltbmod = castWord(v & 0xfffe); blt_info.bltbmod = castWord(v & 0xfffe);
reset_blit(0); reset_blit(0);
}; };
this.BLTCMOD = function (hpos, v) { this.BLTCMOD = function (hpos, v) {
this.maybe_blit(hpos, 1); this.maybe_blit(hpos, 1);
blt_info.bltcmod = castWord(v & 0xfffe); blt_info.bltcmod = castWord(v & 0xfffe);
reset_blit(0); reset_blit(0);
}; };
this.BLTDMOD = function (hpos, v) { this.BLTDMOD = function (hpos, v) {
this.maybe_blit(hpos, 1); this.maybe_blit(hpos, 1);
blt_info.bltdmod = castWord(v & 0xfffe); blt_info.bltdmod = castWord(v & 0xfffe);
reset_blit(0); reset_blit(0);
}; };
this.BLTCON0 = function (hpos, v) { this.BLTCON0 = function (hpos, v) {
this.maybe_blit(hpos, 2); this.maybe_blit(hpos, 2);
bltcon0 = v; bltcon0 = v;
reset_blit(1); reset_blit(1);
}; };
this.BLTCON0L = function (hpos, v) { this.BLTCON0L = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 2); this.maybe_blit(hpos, 2);
bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
reset_blit(1); reset_blit(1);
}; };
this.BLTCON1 = function (hpos, v) { this.BLTCON1 = function (hpos, v) {
this.maybe_blit(hpos, 2); this.maybe_blit(hpos, 2);
bltcon1 = v; bltcon1 = v;
reset_blit(2); reset_blit(2);
}; };
this.BLTAFWM = function (hpos, v) { this.BLTAFWM = function (hpos, v) {
this.maybe_blit(hpos, 2); this.maybe_blit(hpos, 2);
blt_info.bltafwm = v; blt_info.bltafwm = v;
reset_blit(0); reset_blit(0);
}; };
this.BLTALWM = function (hpos, v) { this.BLTALWM = function (hpos, v) {
this.maybe_blit(hpos, 2); this.maybe_blit(hpos, 2);
blt_info.bltalwm = v; blt_info.bltalwm = v;
reset_blit(0); reset_blit(0);
}; };
this.BLTAPTH = function (hpos, v) { this.BLTAPTH = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0;
}; };
this.BLTAPTL = function (hpos, v) { this.BLTAPTL = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0;
}; };
this.BLTBPTH = function (hpos, v) { this.BLTBPTH = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0;
}; };
this.BLTBPTL = function (hpos, v) { this.BLTBPTL = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0;
}; };
this.BLTCPTH = function (hpos, v) { this.BLTCPTH = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0;
}; };
this.BLTCPTL = function (hpos, v) { this.BLTCPTL = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0;
}; };
this.BLTDPTH = function (hpos, v) { this.BLTDPTH = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0;
}; };
this.BLTDPTL = function (hpos, v) { this.BLTDPTL = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0; bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0;
}; };
this.BLTSIZE = function (hpos, v) { this.BLTSIZE = function (hpos, v) {
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
blt_info.vblitsize = v >> 6; blt_info.vblitsize = v >> 6;
blt_info.hblitsize = v & 0x3F; blt_info.hblitsize = v & 0x3F;
if (!blt_info.vblitsize) if (!blt_info.vblitsize)
blt_info.vblitsize = 1024; blt_info.vblitsize = 1024;
if (!blt_info.hblitsize) if (!blt_info.hblitsize)
blt_info.hblitsize = 64; blt_info.hblitsize = 64;
do_blitter(hpos, AMIGA.copper.access); do_blitter(hpos, AMIGA.copper.access);
}; };
this.BLTSIZV = function (hpos, v) { this.BLTSIZV = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
blt_info.vblitsize = v & 0x7FFF; blt_info.vblitsize = v & 0x7FFF;
}; };
this.BLTSIZH = function (hpos, v) { this.BLTSIZH = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return; if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0); this.maybe_blit(hpos, 0);
blt_info.hblitsize = v & 0x7FF; blt_info.hblitsize = v & 0x7FF;
if (!blt_info.vblitsize) if (!blt_info.vblitsize)
blt_info.vblitsize = 0x8000; blt_info.vblitsize = 0x8000;
if (!blt_info.hblitsize) if (!blt_info.hblitsize)
blt_info.hblitsize = 0x0800; blt_info.hblitsize = 0x0800;
do_blitter(hpos, AMIGA.copper.access); do_blitter(hpos, AMIGA.copper.access);
}; };
/*---------------------------------*/ /*---------------------------------*/
this.getState = function () { this.getState = function () {
return bltstate; return bltstate;
}; };
this.setState = function (s) { this.setState = function (s) {
bltstate = s; bltstate = s;
}; };
this.getIntZero = function() { this.getIntZero = function() {
return [blit_interrupt, blt_info.blitzero]; return [blit_interrupt, blt_info.blitzero];
} }
} }

View file

@ -101,22 +101,22 @@ function CIA() {
} }
this.SetICRA = function (icr, sdr) { this.SetICRA = function (icr, sdr) {
ciaaicr |= icr; ciaaicr |= icr;
ciaasdr = sdr; ciaasdr = sdr;
RethinkICRA(); RethinkICRA();
}; };
this.SetICRB = function (icr, sdr) { this.SetICRB = function (icr, sdr) {
ciabicr |= icr; ciabicr |= icr;
if (sdr !== null) if (sdr !== null)
ciabsdr = sdr; ciabsdr = sdr;
RethinkICRB(); RethinkICRB();
}; };
this.rethink = function () { this.rethink = function () {
RethinkICRA(); RethinkICRA();
RethinkICRB(); RethinkICRB();
}; };
/* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */ /* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */
function compute_passed_time() { function compute_passed_time() {
@ -343,9 +343,9 @@ function CIA() {
} }
this.handler = function () { this.handler = function () {
CIA_update(); CIA_update();
CIA_calctimers(); CIA_calctimers();
}; };
/*this.diskindex = function() { /*this.diskindex = function() {
ciabicr |= 0x10; ciabicr |= 0x10;
@ -476,40 +476,40 @@ function CIA() {
//this.hsync_prehandler = function() {} //this.hsync_prehandler = function() {}
this.hsync_posthandler = function (dotod) { this.hsync_posthandler = function (dotod) {
if (ciabtodon && dotod) { if (ciabtodon && dotod) {
ciabtod++; ciabtod++;
ciabtod &= 0xFFFFFF; ciabtod &= 0xFFFFFF;
ciab_checkalarm(1); ciab_checkalarm(1);
} }
if (AMIGA.config.cia.tod_hack && ciaatodon) if (AMIGA.config.cia.tod_hack && ciaatodon)
do_tod_hack(dotod); do_tod_hack(dotod);
/*if (resetwarning_phase) { /*if (resetwarning_phase) {
resetwarning_check (); resetwarning_check ();
while (keys_available ()) while (keys_available ())
get_next_key (); get_next_key ();
} else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) { } else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
switch (kbstate) { switch (kbstate) {
case 0: case 0:
kbcode = 0; kbcode = 0;
kbstate++; kbstate++;
break; break;
case 1: case 1:
setcode(AK_INIT_POWERUP); setcode(AK_INIT_POWERUP);
kbstate++; kbstate++;
break; break;
case 2: case 2:
setcode(AK_TERM_POWERUP); setcode(AK_TERM_POWERUP);
kbstate++; kbstate++;
break; break;
case 3: case 3:
kbcode = ~get_next_key(); kbcode = ~get_next_key();
break; break;
} }
keyreq(); keyreq();
}*/ }*/
AMIGA.input.keyboard.hsync(); AMIGA.input.keyboard.hsync();
}; };
function calc_led(old_led) { function calc_led(old_led) {
var c = AMIGA.events.currcycle; var c = AMIGA.events.currcycle;
@ -560,42 +560,42 @@ function CIA() {
} }
this.vsync_prehandler = function () { this.vsync_prehandler = function () {
/*if (rtc_delayed_write < 0) { /*if (rtc_delayed_write < 0) {
rtc_delayed_write = 50; rtc_delayed_write = 50;
} else if (rtc_delayed_write > 0) { } else if (rtc_delayed_write > 0) {
rtc_delayed_write--; rtc_delayed_write--;
if (rtc_delayed_write == 0) if (rtc_delayed_write == 0)
write_battclock (); write_battclock ();
}*/ }*/
led_vsync(); led_vsync();
this.handler(); this.handler();
/*if (kblostsynccnt > 0) { /*if (kblostsynccnt > 0) {
kblostsynccnt -= maxvpos; kblostsynccnt -= maxvpos;
if (kblostsynccnt <= 0) { if (kblostsynccnt <= 0) {
kblostsynccnt = 0; kblostsynccnt = 0;
keyreq (); keyreq ();
write_log (_T('lostsync\n')); write_log (_T('lostsync\n'));
} }
}*/ }*/
AMIGA.input.keyboard.vsync(); AMIGA.input.keyboard.vsync();
}; };
this.vsync_posthandler = function (dotod) { this.vsync_posthandler = function (dotod) {
//if (heartbeat_cnt > 0) heartbeat_cnt--; //if (heartbeat_cnt > 0) heartbeat_cnt--;
if (TOD_HACK) { if (TOD_HACK) {
if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1) if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1)
return; return;
} }
if (ciaatodon && dotod) { if (ciaatodon && dotod) {
ciaatod++; ciaatod++;
ciaatod &= 0xFFFFFF; ciaatod &= 0xFFFFFF;
ciaa_checkalarm(1); ciaa_checkalarm(1);
} }
/*if (vpos == 0) { /*if (vpos == 0) {
write_log ('%d', vsync_counter); write_log ('%d', vsync_counter);
this.dump(); this.dump();
}*/ }*/
}; };
function bfe001_change() { function bfe001_change() {
var v = ciaapra; var v = ciaapra;
@ -1117,58 +1117,58 @@ function CIA() {
} }
this.setup = function () { this.setup = function () {
}; };
this.reset = function () { this.reset = function () {
if (TOD_HACK) { if (TOD_HACK) {
tod_hack_tv = 0; tod_hack_tv = 0;
tod_hack_tod = 0; tod_hack_tod = 0;
tod_hack_enabled = 0; tod_hack_enabled = 0;
if (AMIGA.config.cia.tod_hack) if (AMIGA.config.cia.tod_hack)
tod_hack_enabled = TOD_HACK_TIME; tod_hack_enabled = TOD_HACK_TIME;
} }
//kblostsynccnt = 0; //kblostsynccnt = 0;
//serbits = 0; //serbits = 0;
//oldcd32mute = 1; //oldcd32mute = 1;
oldled = true; oldled = true;
//resetwarning_phase = resetwarning_timer = 0; //resetwarning_phase = resetwarning_timer = 0;
//heartbeat_cnt = 0; //heartbeat_cnt = 0;
//oldovl = true; //oldovl = true;
//kbstate = 0; //kbstate = 0;
ciaatlatch = ciabtlatch = 0; ciaatlatch = ciabtlatch = 0;
ciaapra = 0; ciaapra = 0;
ciaadra = 0; ciaadra = 0;
ciaatod = ciabtod = 0; ciaatod = ciabtod = 0;
ciaatodon = ciabtodon = 0; ciaatodon = ciabtodon = 0;
ciaaicr = ciabicr = ciaaimask = ciabimask = 0; ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4;
/* outmode = toggle; */ /* outmode = toggle; */
ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF; ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
ciaaalarm = ciabalarm = 0; ciaaalarm = ciabalarm = 0;
ciabpra = 0x8C; ciabpra = 0x8C;
ciabdra = 0; ciabdra = 0;
div10 = 0; div10 = 0;
ciaasdr_cnt = 0; ciaasdr_cnt = 0;
ciaasdr = 0; ciaasdr = 0;
ciabsdr_cnt = 0; ciabsdr_cnt = 0;
ciabsdr = 0; ciabsdr = 0;
ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0; ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
CIA_calctimers(); CIA_calctimers();
AMIGA.disk.select_set(ciabprb); AMIGA.disk.select_set(ciabprb);
//map_overlay (0); //map_overlay (0);
//if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */ //if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */
}; };
this.dump = function () { 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('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('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('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); 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 // 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 // Old Gary based Amigas enable both CIAs in this situation
@ -1210,119 +1210,120 @@ function CIA() {
} }
this.load8 = function (addr) { this.load8 = function (addr) {
var r = (addr & 0xf00) >> 8; var r = (addr & 0xf00) >> 8;
var v = 0xff; var v = 0xff;
if (!isgaylenocia(addr)) if (!isgaylenocia(addr))
return v; return v;
cia_wait_pre(); cia_wait_pre();
switch ((addr >> 12) & 3) { switch ((addr >> 12) & 3) {
case 0: case 0:
if (!issinglecia()) if (!issinglecia())
v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r); v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
break; break;
case 1: case 1:
v = (addr & 1) ? 0xff : ReadCIAB(r); v = (addr & 1) ? 0xff : ReadCIAB(r);
break; break;
case 2: case 2:
v = (addr & 1) ? ReadCIAA(r) : 0xff; v = (addr & 1) ? ReadCIAA(r) : 0xff;
break; break;
case 3: case 3:
{ {
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8; //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
if (warned > 0) { if (warned > 0) {
BUG.info('cia_bget: unknown CIA address %x', addr); BUG.info('cia_bget: unknown CIA address %x', addr);
warned--; warned--;
} }
break; break;
} }
} }
cia_wait_post(v); cia_wait_post(v);
return v; return v;
}; };
this.load16 = function (addr) { this.load16 = function (addr) {
var r = (addr & 0xf00) >> 8; var r = (addr & 0xf00) >> 8;
var v = 0xffff; var v = 0xffff;
if (!isgaylenocia(addr)) if (!isgaylenocia(addr))
return v; return v;
cia_wait_pre(); cia_wait_pre();
switch ((addr >> 12) & 3) { switch ((addr >> 12) & 3) {
case 0: case 0:
if (!issinglecia()) if (!issinglecia())
v = (ReadCIAB(r) << 8) | ReadCIAA(r); v = (ReadCIAB(r) << 8) | ReadCIAA(r);
break; break;
case 1: case 1:
v = (ReadCIAB(r) << 8) | 0xff; v = (ReadCIAB(r) << 8) | 0xff;
break; break;
case 2: case 2:
v = (0xff << 8) | ReadCIAA(r); v = (0xff << 8) | ReadCIAA(r);
break; break;
case 3: case 3:
{ {
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc; //if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
if (warned > 0) { if (warned > 0) {
BUG.info('cia_wget: unknown CIA address %x', addr); BUG.info('cia_wget: unknown CIA address %x', addr);
warned--; warned--;
} }
break; break;
} }
} }
cia_wait_post(v); cia_wait_post(v);
return v; return v;
}; };
this.load32 = function (addr) { this.load32 = function (addr) {
var v = this.load16(addr) << 16; var v = this.load16(addr) << 16;
v |= this.load16(addr + 2); v |= this.load16(addr + 2);
return v >>> 0; return v >>> 0;
}; };
this.store8 = function (addr, value) { this.store8 = function (addr, value) {
var r = (addr & 0xf00) >> 8; var r = (addr & 0xf00) >> 8;
if (!isgaylenocia(addr)) if (!isgaylenocia(addr))
return; return;
cia_wait_pre(); cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) { if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0) if ((addr & 0x2000) == 0)
WriteCIAB(r, value); WriteCIAB(r, value);
if ((addr & 0x1000) == 0) if ((addr & 0x1000) == 0)
WriteCIAA(r, value); WriteCIAA(r, value);
if (((addr & 0x3000) == 0x3000) && warned > 0) { if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_bput: unknown CIA address %x %x', addr, value); BUG.info('cia_bput: unknown CIA address %x %x', addr, value);
warned--; warned--;
} }
} }
cia_wait_post(value); cia_wait_post(value);
}; };
this.store16 = function (addr, value) { this.store16 = function (addr, value) {
var r = (addr & 0xf00) >> 8; var r = (addr & 0xf00) >> 8;
if (!isgaylenocia(addr)) if (!isgaylenocia(addr))
return; return;
cia_wait_pre(); cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) { if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0) if ((addr & 0x2000) == 0)
WriteCIAB(r, value >> 8); WriteCIAB(r, value >> 8);
if ((addr & 0x1000) == 0) if ((addr & 0x1000) == 0)
WriteCIAA(r, value & 0xff); WriteCIAA(r, value & 0xff);
if (((addr & 0x3000) == 0x3000) && warned > 0) { if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_wput: unknown CIA address %x %x', addr, value); BUG.info('cia_wput: unknown CIA address %x %x', addr, value);
warned--; warned--;
} }
} }
cia_wait_post(value); cia_wait_post(value);
}; };
this.store32 = function (addr, value) { this.store32 = function (addr, value) {
this.store16(addr, value >> 16); this.store16(addr, value >> 16);
this.store16(addr + 2, value & 0xffff); this.store16(addr + 2, value & 0xffff);
} }
} }

View file

@ -34,10 +34,10 @@ function Config() {
}, },
slow: { slow: {
size: 0 size: 0
}, },
fast: { fast: {
size: 0 size: 0
} }
}; };
this.rom = { this.rom = {
size: 0, size: 0,
@ -86,7 +86,6 @@ function Config() {
enabled: false, enabled: false,
mode:0, mode:0,
channels: 0, channels: 0,
rate: 0,
filter: false filter: false
}; };
this.ports = [{ this.ports = [{
@ -169,7 +168,7 @@ function Config() {
c.video.enabled = true; c.video.enabled = true;
c.video.scale = false; c.video.scale = false;
c.video.ntsc = false; c.video.ntsc = false;
c.video.framerate = 2; c.video.framerate = 1; //2
c.video.hresolution = 1 ? RES_HIRES : RES_LORES; c.video.hresolution = 1 ? RES_HIRES : RES_LORES;
c.video.vresolution = 1 ? VRES_DOUBLE : VRES_NONDOUBLE; c.video.vresolution = 1 ? VRES_DOUBLE : VRES_NONDOUBLE;
c.video.scandoubler = 0 ? true : false; c.video.scandoubler = 0 ? true : false;
@ -182,7 +181,6 @@ function Config() {
//c.audio.mode = SAEV_Config_Audio_Mode_Play_Best; //c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
c.audio.mode = SAEV_Config_Audio_Mode_Play; c.audio.mode = SAEV_Config_Audio_Mode_Play;
c.audio.channels = SAEV_Config_Audio_Channels_Stereo; c.audio.channels = SAEV_Config_Audio_Channels_Stereo;
c.audio.rate = SAEV_Config_Audio_Rate_44100;
c.audio.filter = false; c.audio.filter = false;
c.ports[0].type = SAEV_Config_Ports_Type_Mouse; c.ports[0].type = SAEV_Config_Ports_Type_Mouse;
@ -203,16 +201,17 @@ function Config() {
c.cia.tod_hack = true; c.cia.tod_hack = true;
c.hooks.error = function (err, msg) { c.hooks.error = function (err, msg) {
}; };
c.hooks.power_led = function (on) { c.hooks.power_led = function (on) {
}; };
c.hooks.floppy_motor = function (unit, on) { c.hooks.floppy_motor = function (unit, on) {
}; };
c.hooks.floppy_step = function (unit, cyl) { c.hooks.floppy_step = function (unit, cyl) {
}; };
c.hooks.fps = function (fps) { c.hooks.fps = function (fps) {
}; };
c.hooks.cpu = function(usage) {} c.hooks.cpu = function(usage) {}
} }
configSetDefaults(this); configSetDefaults(this);
} }

View file

@ -99,11 +99,6 @@ const SAEV_Config_Audio_Mode_Play_Best = 2;
const SAEV_Config_Audio_Channels_Mono = 1; const SAEV_Config_Audio_Channels_Mono = 1;
const SAEV_Config_Audio_Channels_Stereo = 2; const SAEV_Config_Audio_Channels_Stereo = 2;
const SAEV_Config_Audio_Rate_11025 = 1;
const SAEV_Config_Audio_Rate_22050 = 2;
const SAEV_Config_Audio_Rate_44100 = 3;
const SAEV_Config_Audio_Rate_48000 = 4;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* input */ /* input */
@ -368,3 +363,4 @@ const MAX_WORDS_PER_LINE = 100;
const DO_SPRITES = 1; const DO_SPRITES = 1;
const FAST_COLORS = 0; const FAST_COLORS = 0;

View file

@ -72,68 +72,68 @@ function Copper() {
}; };
this.reset = function () { this.reset = function () {
this.copcon = 0; this.copcon = 0;
cop_state.state = COP_stop; cop_state.state = COP_stop;
}; };
this.reset2 = function () { this.reset2 = function () {
cop_state.hpos = 0; cop_state.hpos = 0;
cop_state.last_write = 0; cop_state.last_write = 0;
this.compute_spcflag_copper(AMIGA.playfield.maxhpos); this.compute_spcflag_copper(AMIGA.playfield.maxhpos);
}; };
this.COPCON = function (v) { this.COPCON = function (v) {
this.copcon = v; this.copcon = v;
}; };
this.COP1LCH = function (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.COP1LCL = function (v) {
this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0; this.cop1lc = ((this.cop1lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
}; };
this.COP2LCH = function (v) { 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.COP2LCL = function (v) {
this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0; this.cop2lc = ((this.cop2lc & 0xffff0000) | (v & 0xfffe)) >>> 0;
}; };
this.COPJMP = function (num, vblank) { 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)) //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); //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); clr_special(SPCFLAG_COPPER);
cop_state.ignore_next = 0; cop_state.ignore_next = 0;
if (!oldstrobe) if (!oldstrobe)
cop_state.state_prev = cop_state.state; cop_state.state_prev = cop_state.state;
if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank) if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank)
cop_state.state = COP_strobe_delay1x; cop_state.state = COP_strobe_delay1x;
else else
cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra); cop_state.state = vblank ? COP_start_delay : (this.access ? COP_strobe_delay1 : COP_strobe_extra);
//BUG.info('COPJMP(%d) %d', num, cop_state.state); //BUG.info('COPJMP(%d) %d', num, cop_state.state);
cop_state.vpos = AMIGA.playfield.vpos; cop_state.vpos = AMIGA.playfield.vpos;
cop_state.hpos = AMIGA.playfield.hpos() & ~1; cop_state.hpos = AMIGA.playfield.hpos() & ~1;
cop_state.strobe = num; cop_state.strobe = num;
this.enabled_thisline = false; this.enabled_thisline = false;
if (0) { if (0) {
this.immediate_copper(num); this.immediate_copper(num);
return; return;
} }
if (AMIGA.dmaen(DMAF_COPEN)) if (AMIGA.dmaen(DMAF_COPEN))
this.compute_spcflag_copper(AMIGA.playfield.hpos()); this.compute_spcflag_copper(AMIGA.playfield.hpos());
else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) { else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) {
/* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */ /* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */
cop_state.state = COP_stop; cop_state.state = COP_stop;
//BUG.info('COPJMP(%d) COP_stop'); //BUG.info('COPJMP(%d) COP_stop');
} }
}; };
/*function get_copper_address(copno) { /*function get_copper_address(copno) {
switch (copno) { switch (copno) {
@ -145,451 +145,451 @@ function Copper() {
}*/ }*/
this.test_copper_dangerous = function (address) { this.test_copper_dangerous = function (address) {
var addr = address & 0x1fe; var addr = address & 0x1fe;
if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) { if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
cop_state.state = COP_stop; cop_state.state = COP_stop;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
return true; return true;
} }
return false; return false;
}; };
this.immediate_copper = function (num) { this.immediate_copper = function (num) {
var pos = 0; var pos = 0;
var oldpos = 0; var oldpos = 0;
cop_state.state = COP_stop; cop_state.state = COP_stop;
cop_state.vpos = AMIGA.playfield.vpos; cop_state.vpos = AMIGA.playfield.vpos;
cop_state.hpos = AMIGA.playfield.hpos() & ~1; cop_state.hpos = AMIGA.playfield.hpos() & ~1;
cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc; cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc;
while (pos < (AMIGA.playfield.maxvpos << 5)) { while (pos < (AMIGA.playfield.maxvpos << 5)) {
if (oldpos > pos) if (oldpos > pos)
pos = oldpos; pos = oldpos;
if (!AMIGA.dmaen(DMAF_COPEN)) if (!AMIGA.dmaen(DMAF_COPEN))
break; break;
if (cop_state.ip >= AMIGA.mem.chip.size) if (cop_state.ip >= AMIGA.mem.chip.size)
break; break;
pos++; pos++;
oldpos = pos; oldpos = pos;
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2); //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2);
cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1]; cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1];
cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1]; cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1];
AMIGA.custom.last_value = cop_state.i2; AMIGA.custom.last_value = cop_state.i2;
cop_state.ip += 4; cop_state.ip += 4;
if (!(cop_state.i1 & 1)) { // move if (!(cop_state.i1 & 1)) { // move
cop_state.i1 &= 0x1fe; cop_state.i1 &= 0x1fe;
if (cop_state.i1 == 0x88) { if (cop_state.i1 == 0x88) {
cop_state.ip = this.cop1lc; cop_state.ip = this.cop1lc;
continue; continue;
} }
if (cop_state.i1 == 0x8a) { if (cop_state.i1 == 0x8a) {
cop_state.ip = this.cop2lc; cop_state.ip = this.cop2lc;
continue; continue;
} }
if (this.test_copper_dangerous(cop_state.i1)) if (this.test_copper_dangerous(cop_state.i1))
break; break;
AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0); AMIGA.custom.store16_real(0, cop_state.i1, cop_state.i2, 0);
} else { // wait or skip } else { // wait or skip
if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff)) if ((cop_state.i1 >> 8) > ((pos >> 5) & 0xff))
pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3); pos = (((pos >> 5) & 0x100) | ((cop_state.i1 >> 8)) << 5) | ((cop_state.i1 & 0xff) >> 3);
if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe) if (cop_state.i1 >= 0xffdf && cop_state.i2 == 0xfffe)
break; break;
} }
} }
cop_state.state = COP_stop; cop_state.state = COP_stop;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
}; };
this.copper_cant_read = function (hpos, alloc) { this.copper_cant_read = function (hpos, alloc) {
//BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos); //BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos);
if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot
return 1; return 1;
if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) { if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) {
return -1; return -1;
} }
return AMIGA.playfield.is_bitplane_dma(hpos); return AMIGA.playfield.is_bitplane_dma(hpos);
}; };
this.custom_store16_copper = function (hpos, addr, value, noget) { this.custom_store16_copper = function (hpos, addr, value, noget) {
//if (addr == 0x88 || addr == 0x8a) //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); //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); //value = debug_wputpeekdma (0xdff000 + addr, value);
this.access = true; this.access = true;
var v = AMIGA.custom.store16_real(hpos, addr, value, noget); var v = AMIGA.custom.store16_real(hpos, addr, value, noget);
this.access = false; this.access = false;
return v; return v;
}; };
this.dump_copper = function (error, until_hpos) { this.dump_copper = function (error, until_hpos) {
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('%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('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('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');
}; };
this.update = function (until_hpos) { this.update = function (until_hpos) {
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
var c_hpos = cop_state.hpos; 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) { if (cop_state.state == COP_wait && vp < cop_state.vcmp) {
this.dump_copper('error2', until_hpos); this.dump_copper('error2', until_hpos);
this.enabled_thisline = false; this.enabled_thisline = false;
cop_state.state = COP_stop; cop_state.state = COP_stop;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
return; return;
} }
if (until_hpos <= this.last_copper_hpos) if (until_hpos <= this.last_copper_hpos)
return; return;
if (until_hpos > (AMIGA.playfield.maxhpos & ~1)) if (until_hpos > (AMIGA.playfield.maxhpos & ~1))
until_hpos = AMIGA.playfield.maxhpos & ~1; until_hpos = AMIGA.playfield.maxhpos & ~1;
for (; ;) { for (; ;) {
var old_hpos = c_hpos; var old_hpos = c_hpos;
var hp; var hp;
if (c_hpos >= until_hpos) if (c_hpos >= until_hpos)
break; break;
/* So we know about the fetch state. */ /* So we know about the fetch state. */
AMIGA.playfield.decide_line(c_hpos); AMIGA.playfield.decide_line(c_hpos);
AMIGA.playfield.decide_fetch(c_hpos); AMIGA.playfield.decide_fetch(c_hpos);
if (cop_state.movedelay > 0) { if (cop_state.movedelay > 0) {
cop_state.movedelay--; cop_state.movedelay--;
if (cop_state.movedelay == 0) { if (cop_state.movedelay == 0) {
this.custom_store16_copper(c_hpos, cop_state.moveaddr, cop_state.movedata, 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)) if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1))
c_hpos += 1; c_hpos += 1;
else else
c_hpos += 2; c_hpos += 2;
switch (cop_state.state) { switch (cop_state.state) {
case COP_wait_in2: case COP_wait_in2:
{ {
if (this.copper_cant_read(old_hpos, 0)) if (this.copper_cant_read(old_hpos, 0))
continue; continue;
cop_state.state = COP_wait1; cop_state.state = COP_wait1;
break; break;
} }
case COP_skip_in2: case COP_skip_in2:
{ {
if (this.copper_cant_read(old_hpos, 0)) if (this.copper_cant_read(old_hpos, 0))
continue; continue;
cop_state.state = COP_skip1; cop_state.state = COP_skip1;
break; break;
} }
case COP_strobe_extra: case COP_strobe_extra:
{ {
// Wait 1 copper cycle doing nothing // Wait 1 copper cycle doing nothing
cop_state.state = COP_strobe_delay1; cop_state.state = COP_strobe_delay1;
break; break;
} }
case COP_strobe_delay1: case COP_strobe_delay1:
{ {
// First cycle after COPJMP is just like normal first read cycle // First cycle after COPJMP is just like normal first read cycle
// Cycle is used and needs to be free. // Cycle is used and needs to be free.
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.state = COP_strobe_delay2; cop_state.state = COP_strobe_delay2;
cop_state.ip += 2; cop_state.ip += 2;
break; break;
} }
case COP_strobe_delay2: case COP_strobe_delay2:
{ {
// Second cycle after COPJMP. This is the strange one. // Second cycle after COPJMP. This is the strange one.
// This cycle does not need to be free // 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. // But it still gets allocated by copper if it is free = CPU and blitter can't use it.
cop_state.state = COP_read1; cop_state.state = COP_read1;
// Next cycle finally reads from new pointer // Next cycle finally reads from new pointer
if (cop_state.strobe == 1) if (cop_state.strobe == 1)
cop_state.ip = this.cop1lc; cop_state.ip = this.cop1lc;
else else
cop_state.ip = this.cop2lc; cop_state.ip = this.cop2lc;
cop_state.strobe = 0; cop_state.strobe = 0;
break; break;
} }
case COP_strobe_delay1x: case COP_strobe_delay1x:
{ {
// First cycle after COPJMP and Copper was waiting. This is the buggy one. // First cycle after COPJMP and Copper was waiting. This is the buggy one.
// Cycle can be free and copper won't allocate it. // Cycle can be free and copper won't allocate it.
// If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer.. // If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer..
cop_state.state = COP_strobe_delay2x; cop_state.state = COP_strobe_delay2x;
break; break;
} }
case COP_strobe_delay2x: case COP_strobe_delay2x:
{ {
// Second cycle fetches following word and tosses it away. Must be free cycle // Second cycle fetches following word and tosses it away. Must be free cycle
// but is not allocated, blitter or cpu can still use it. // but is not allocated, blitter or cpu can still use it.
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.state = COP_read1; cop_state.state = COP_read1;
// Next cycle finally reads from new pointer // Next cycle finally reads from new pointer
if (cop_state.strobe == 1) if (cop_state.strobe == 1)
cop_state.ip = this.cop1lc; cop_state.ip = this.cop1lc;
else else
cop_state.ip = this.cop2lc; cop_state.ip = this.cop2lc;
cop_state.strobe = 0; cop_state.strobe = 0;
break; break;
} }
case COP_start_delay: case COP_start_delay:
{ {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.state = COP_read1; cop_state.state = COP_read1;
cop_state.ip = this.cop1lc; cop_state.ip = this.cop1lc;
break; break;
} }
case COP_read1: case COP_read1:
{ {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
/* workaround for a bug in kick 1.x */ /* workaround for a bug in kick 1.x */
if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) { if (cop_state.ip == 0x00000004 || cop_state.ip == 0x00000676 || cop_state.ip == 0x00c00276) {
//BUG.info('COP_read1() invalid addr $%08x', cop_state.ip); //BUG.info('COP_read1() invalid addr $%08x', cop_state.ip);
cop_state.state = COP_stop; cop_state.state = COP_stop;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
return; return;
} }
//cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); //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.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
cop_state.ip += 2; cop_state.ip += 2;
cop_state.state = COP_read2; cop_state.state = COP_read2;
break; break;
} }
case COP_read2: case COP_read2:
{ {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
//cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip); //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.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
cop_state.ip += 2; cop_state.ip += 2;
cop_state.saved_i1 = cop_state.i1; cop_state.saved_i1 = cop_state.i1;
cop_state.saved_i2 = cop_state.i2; cop_state.saved_i2 = cop_state.i2;
cop_state.saved_ip = cop_state.ip; cop_state.saved_ip = cop_state.ip;
if (cop_state.i1 & 1) { // WAIT or SKIP if (cop_state.i1 & 1) { // WAIT or SKIP
cop_state.ignore_next = 0; cop_state.ignore_next = 0;
if (cop_state.i2 & 1) if (cop_state.i2 & 1)
cop_state.state = COP_skip_in2; cop_state.state = COP_skip_in2;
else else
cop_state.state = COP_wait_in2; cop_state.state = COP_wait_in2;
} else { // MOVE } else { // MOVE
//uaecptr debugip = cop_state.ip; //uaecptr debugip = cop_state.ip;
var reg = cop_state.i1 & 0x1fe; var reg = cop_state.i1 & 0x1fe;
var data = cop_state.i2; var data = cop_state.i2;
cop_state.state = COP_read1; cop_state.state = COP_read1;
this.test_copper_dangerous(reg); this.test_copper_dangerous(reg);
if (!this.enabled_thisline) { if (!this.enabled_thisline) {
//goto out; // was 'dangerous' register -> copper stopped //goto out; // was 'dangerous' register -> copper stopped
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
this.last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
if (cop_state.ignore_next) if (cop_state.ignore_next)
reg = 0x1fe; reg = 0x1fe;
cop_state.last_write = reg; cop_state.last_write = reg;
cop_state.last_write_hpos = old_hpos; cop_state.last_write_hpos = old_hpos;
if (reg == 0x88) { if (reg == 0x88) {
cop_state.strobe = 1; cop_state.strobe = 1;
cop_state.state = COP_strobe_delay1; cop_state.state = COP_strobe_delay1;
} else if (reg == 0x8a) { } else if (reg == 0x8a) {
cop_state.strobe = 2; cop_state.strobe = 2;
cop_state.state = COP_strobe_delay1; cop_state.state = COP_strobe_delay1;
} else { } else {
/*if (0) { /*if (0) {
AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write); AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write);
AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0); AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0);
}); });
//this.custom_store16_copper(old_hpos, reg, data, 0); //this.custom_store16_copper(old_hpos, reg, data, 0);
} else*/ } else*/
{ {
// FIX: all copper writes happen 1 cycle later than CPU writes // FIX: all copper writes happen 1 cycle later than CPU writes
if (customdelay[reg >> 1]) { if (customdelay[reg >> 1]) {
cop_state.moveaddr = reg; cop_state.moveaddr = reg;
cop_state.movedata = data; cop_state.movedata = data;
cop_state.movedelay = customdelay[cop_state.moveaddr >> 1]; cop_state.movedelay = customdelay[cop_state.moveaddr >> 1];
} else { } else {
var hpos2 = old_hpos; var hpos2 = old_hpos;
this.custom_store16_copper(hpos2, reg, data, 0); this.custom_store16_copper(hpos2, reg, data, 0);
hpos2++; hpos2++;
if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES)
AMIGA.playfield.do_sprites(hpos2); AMIGA.playfield.do_sprites(hpos2);
} }
} }
} }
cop_state.ignore_next = 0; cop_state.ignore_next = 0;
} }
break; break;
} }
case COP_wait1: case COP_wait1:
{ {
/*#if 0 /*#if 0
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break; if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break;
#endif*/ #endif*/
cop_state.state = COP_wait; cop_state.state = COP_wait;
cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; 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.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) { if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) {
cop_state.state = COP_waitforever; cop_state.state = COP_waitforever;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
this.last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
if (vp < cop_state.vcmp) { if (vp < cop_state.vcmp) {
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
this.last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
} }
/* fall through */ /* fall through */
case COP_wait: case COP_wait:
{ {
var ch_comp = c_hpos; var ch_comp = c_hpos;
if (ch_comp & 1) if (ch_comp & 1)
ch_comp = 0; ch_comp = 0;
if (this.copper_cant_read(old_hpos, 0)) if (this.copper_cant_read(old_hpos, 0))
continue; continue;
hp = ch_comp & (cop_state.saved_i2 & 0xfe); hp = ch_comp & (cop_state.saved_i2 & 0xfe);
if (vp == cop_state.vcmp && hp < cop_state.hcmp) if (vp == cop_state.vcmp && hp < cop_state.hcmp)
break; break;
/* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */ /* 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 ((cop_state.saved_i2 & 0x8000) == 0) {
if (AMIGA.blitter.getState() != BLT_done) { if (AMIGA.blitter.getState() != BLT_done) {
//We need to wait for the blitter. //We need to wait for the blitter.
cop_state.state = COP_bltwait; cop_state.state = COP_bltwait;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
this.last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
} }
cop_state.state = COP_read1; cop_state.state = COP_read1;
break; break;
} }
case COP_skip1: case COP_skip1:
{ {
var vcmp, hcmp, vp1, hp1; var vcmp, hcmp, vp1, hp1;
if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1))
break; break;
if (this.copper_cant_read(old_hpos, 0)) if (this.copper_cant_read(old_hpos, 0))
continue; continue;
vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
hp1 = c_hpos & (cop_state.saved_i2 & 0xfe); 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)) 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.ignore_next = 1;
cop_state.state = COP_read1; cop_state.state = COP_read1;
break; break;
} }
} }
} }
//out: //out:
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
this.last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
}; };
this.compute_spcflag_copper = function (hpos) { this.compute_spcflag_copper = function (hpos) {
//BUG.info('compute_spcflag_copper() hpos %d', hpos); //BUG.info('compute_spcflag_copper() hpos %d', hpos);
var wasenabled = this.enabled_thisline; var wasenabled = this.enabled_thisline;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait) if (!AMIGA.dmaen(DMAF_COPEN) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait)
return; return;
if (cop_state.state == COP_wait) { if (cop_state.state == COP_wait) {
var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
if (vp < cop_state.vcmp) if (vp < cop_state.vcmp)
return; return;
} }
// do not use past cycles if starting for the first time in this line // do not use past cycles if starting for the first time in this line
// (write to DMACON for example) hpos+1 for long lines // (write to DMACON for example) hpos+1 for long lines
if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) { if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) {
hpos = (hpos + 2) & ~1; hpos = (hpos + 2) & ~1;
if (hpos > AMIGA.playfield.maxhpos_short) if (hpos > AMIGA.playfield.maxhpos_short)
hpos = AMIGA.playfield.maxhpos_short; hpos = AMIGA.playfield.maxhpos_short;
cop_state.hpos = hpos; cop_state.hpos = hpos;
//BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short); //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, // 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. // COP_strobe_extra is single cycle only and does not need free bus.
// (copper state emulation does not run if DMA is disabled) // (copper state emulation does not run if DMA is disabled)
if (!wasenabled && cop_state.state == COP_strobe_extra) if (!wasenabled && cop_state.state == COP_strobe_extra)
cop_state.state = COP_strobe_delay1; cop_state.state = COP_strobe_delay1;
this.enabled_thisline = true; this.enabled_thisline = true;
set_special(SPCFLAG_COPPER); set_special(SPCFLAG_COPPER);
}; };
this.blitter_done_notify = function (hpos) { this.blitter_done_notify = function (hpos) {
if (cop_state.state != COP_bltwait) if (cop_state.state != COP_bltwait)
return; return;
//BUG.info('blitter_done_notify() hpos %d', hpos); //BUG.info('blitter_done_notify() hpos %d', hpos);
var vp = AMIGA.playfield.vpos; var vp = AMIGA.playfield.vpos;
hpos += 3; hpos += 3;
hpos &= ~1; hpos &= ~1;
if (hpos >= AMIGA.playfield.maxhpos) { if (hpos >= AMIGA.playfield.maxhpos) {
hpos -= AMIGA.playfield.maxhpos; hpos -= AMIGA.playfield.maxhpos;
vp++; vp++;
} }
cop_state.hpos = hpos; cop_state.hpos = hpos;
cop_state.vpos = vp; cop_state.vpos = vp;
cop_state.state = COP_read1; cop_state.state = COP_read1;
if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) { if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) {
this.enabled_thisline = true; this.enabled_thisline = true;
set_special(SPCFLAG_COPPER); set_special(SPCFLAG_COPPER);
} }
}; };
this.cycle = function () { this.cycle = function () {
this.update(AMIGA.playfield.hpos()); this.update(AMIGA.playfield.hpos());
}; };
this.sync_copper_with_cpu = function (hpos, do_schedule) { this.sync_copper_with_cpu = function (hpos, do_schedule) {
/* Need to let the copper advance to the current position. */ /* Need to let the copper advance to the current position. */
if (this.enabled_thisline) if (this.enabled_thisline)
this.update(hpos); this.update(hpos);
}; };
/*this.check = function (n) { /*this.check = function (n) {
if (cop_state.state == COP_wait) { if (cop_state.state == COP_wait) {
@ -601,3 +601,4 @@ function Copper() {
} }
}*/ }*/
} }

View file

@ -118,30 +118,30 @@ function CPU() {
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
this.setup = function () { this.setup = function () {
if (iTab === null) { if (iTab === null) {
BUG.say('cpu.setup() no instruction table, generating...'); BUG.say('cpu.setup() no instruction table, generating...');
if (!mkiTab()) if (!mkiTab())
Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table'); Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table');
} else } else
BUG.say('cpu.setup() instruction table is cached'); BUG.say('cpu.setup() instruction table is cached');
}; };
this.reset = function (addr) { this.reset = function (addr) {
for (var i = 0; i < 8; i++) for (var i = 0; i < 8; i++)
regs.d[i] = regs.a[i] = 0; regs.d[i] = regs.a[i] = 0;
regs.t = false; regs.t = false;
regs.s = true; regs.s = true;
regs.intmask = 7; regs.intmask = 7;
regs.x = regs.n = regs.z = regs.v = regs.c = false; regs.x = regs.n = regs.z = regs.v = regs.c = false;
regs.usp = 0; regs.usp = 0;
regs.isp = 0; regs.isp = 0;
regs.a[7] = AMIGA.mem.load32(addr); regs.a[7] = AMIGA.mem.load32(addr);
regs.pc = AMIGA.mem.load32(addr + 4); regs.pc = AMIGA.mem.load32(addr + 4);
regs.stopped = false; 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));
}; };
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -153,7 +153,7 @@ function CPU() {
case 4: return 'L'; case 4: return 'L';
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.szChr() invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.szChr() invalid size');
return ''; return '';
} }
} }
@ -203,7 +203,7 @@ function CPU() {
case 4: return r > 0xffffffff ? r - 0x100000000 : r; case 4: return r > 0xffffffff ? r - 0x100000000 : r;
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.addAuto() invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.addAuto() invalid size');
return 0; return 0;
} }
} }
function sub32(a, b) { function sub32(a, b) {
@ -218,7 +218,7 @@ function CPU() {
case 4: return r < 0 ? r + 0x100000000 : r; case 4: return r < 0 ? r + 0x100000000 : r;
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.subAuto() invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.subAuto() invalid size');
return 0; return 0;
} }
} }
@ -245,8 +245,8 @@ function CPU() {
var ext = nextIWord(); var ext = nextIWord();
if (ext & 0x100) { if (ext & 0x100) {
Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)'); Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)');
return 0; return 0;
} else { } else {
var disp = extByte(ext & 0xff); var disp = extByte(ext & 0xff);
var r = (ext & 0x7000) >> 12; var r = (ext & 0x7000) >> 12;
var reg = (ext & 0x8000) ? regs.a[r] : regs.d[r]; var reg = (ext & 0x8000) ? regs.a[r] : regs.d[r];
@ -397,7 +397,7 @@ function CPU() {
case 4: return regs.d[ea.a]; case 4: return regs.d[ea.a];
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RD invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RD invalid size');
return 0; return 0;
} }
} }
case T_RA: { case T_RA: {
@ -406,7 +406,7 @@ function CPU() {
case 4: return regs.a[ea.a]; case 4: return regs.a[ea.a];
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RA invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RA invalid size');
return 0; return 0;
} }
} }
case T_AD: { case T_AD: {
@ -432,14 +432,14 @@ function CPU() {
case 4: return AMIGA.mem.load32(ea.a); case 4: return AMIGA.mem.load32(ea.a);
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_AD invalid size'); Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_AD invalid size');
return 0; return 0;
} }
} }
case T_IM: case T_IM:
return ea.a; return ea.a;
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() invalid type (' + ea.t + ')'); Fatal(SAEE_CPU_Internal, 'cpu.ldEA() invalid type (' + ea.t + ')');
return 0; return 0;
} }
} }
@ -508,7 +508,7 @@ function CPU() {
case 15: return regs.z || (regs.n != regs.v); //LE case 15: return regs.z || (regs.n != regs.v); //LE
default: default:
Fatal(SAEE_CPU_Internal, 'cpu.ccTrue() invalid condition code (' + cc + ')'); Fatal(SAEE_CPU_Internal, 'cpu.ccTrue() invalid condition code (' + cc + ')');
return false; return false;
} }
} }
@ -1111,7 +1111,7 @@ function CPU() {
//var oldrem = rem; //var oldrem = rem;
rem = -rem + 0x10000; rem = -rem + 0x10000;
//BUG.say(sprintf('I_DIVU d $%08x oldrem $%08x rem $%08x', d, oldrem, rem)); //BUG.say(sprintf('I_DIVU d $%08x oldrem $%08x rem $%08x', d, oldrem, rem));
} }
regs.v = false; regs.v = false;
regs.z = quo == 0; regs.z = quo == 0;
regs.n = (quo & 0x8000) != 0; regs.n = (quo & 0x8000) != 0;
@ -2247,7 +2247,7 @@ function CPU() {
case M_absl: return z == 4 ? [16,4,0] : [12,3,0]; case M_absl: return z == 4 ? [16,4,0] : [12,3,0];
case M_imm: case M_imm:
case M_list: return z == 4 ? [ 8,2,0] : [ 4,1,0]; case M_list: return z == 4 ? [ 8,2,0] : [ 4,1,0];
default: return [0,0,0]; default: return [0,0,0];
} }
} }
@ -4677,29 +4677,29 @@ function CPU() {
} }
this.diss = function (offset, limit) { this.diss = function (offset, limit) {
var pc = offset === null ? regs.pc : offset; var pc = offset === null ? regs.pc : offset;
var cnt = 0; var cnt = 0;
while (cnt++ < limit) { while (cnt++ < limit) {
var o = ''; var o = '';
o += sprintf('$%08x: ', pc); o += sprintf('$%08x: ', pc);
for (var i = 0; i < 5; i++) for (var i = 0; i < 5; i++)
o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2)); o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2));
var op = AMIGA.mem.load16(pc); var op = AMIGA.mem.load16(pc);
pc += 2; pc += 2;
var ip = printI(iTab[op], pc); var ip = printI(iTab[op], pc);
o += ip[0]; o += ip[0];
pc = ip[1]; pc = ip[1];
BUG.say(o); BUG.say(o);
} }
}; };
/*this.dissFault = function (limit) { /*this.dissFault = function (limit) {
this.diss(fault.pc, limit); this.diss(fault.pc, limit);
};*/ };*/
/*function nextIWordData(data, pc) { /*function nextIWordData(data, pc) {
return (data[pc] << 8) | data[pc + 1]; return (data[pc] << 8) | data[pc + 1];
@ -4876,36 +4876,36 @@ function CPU() {
} }
this.getThisTaskName = function () { this.getThisTaskName = function () {
var tn = ''; var tn = '';
/* Extract current task-name form SysBase */ /* Extract current task-name form SysBase */
var sysBase = AMIGA.mem.load32(4); var sysBase = AMIGA.mem.load32(4);
if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) { if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) {
var thisTask = AMIGA.mem.load32(sysBase + 276); var thisTask = AMIGA.mem.load32(sysBase + 276);
if (thisTask) if (thisTask)
tn = getTaskName(thisTask); tn = getTaskName(thisTask);
} }
return tn; return tn;
}; };
this.dump = function () { this.dump = function () {
var i, out = '', tn = 1 ? this.getThisTaskName() : ''; var i, out = '', tn = 1 ? this.getThisTaskName() : '';
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>'; out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>';
} }
//out += '<br/>'; //out += '<br/>';
out += "\n"; out += "\n";
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>'; out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>';
} }
//out += '<br/>'; //out += '<br/>';
out += "\n"; out += "\n";
out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp); 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 += 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";
out += "\n"; out += "\n";
BUG.say(out); BUG.say(out);
}; };
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -5253,3 +5253,4 @@ function CPU() {
} }
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -80,73 +80,73 @@ function Expansion() {
var board = 0; var board = 0;
this.setup = function () { this.setup = function () {
mem.data = new Uint16Array(0x8000); mem.data = new Uint16Array(0x8000);
boards = []; boards = [];
if (AMIGA.mem.fast.size > 0) if (AMIGA.mem.fast.size > 0)
boards[0] = new Board_A2058(); boards[0] = new Board_A2058();
else else
boards[0] = new Board_Dummy(); boards[0] = new Board_Dummy();
for (var i = 1; i < MAX_EXPANSION_BOARDS; i++) for (var i = 1; i < MAX_EXPANSION_BOARDS; i++)
boards[i] = new Board_Dummy(); boards[i] = new Board_Dummy();
}; };
this.reset = function () { this.reset = function () {
board = 0; board = 0;
this.config(board); this.config(board);
}; };
this.clear = function () { this.clear = function () {
for (var i = 0; i < mem.data.length; i++) for (var i = 0; i < mem.data.length; i++)
mem.data[i] = 0; mem.data[i] = 0;
}; };
this.write = function (addr, value) { this.write = function (addr, value) {
mem.data[(addr >> 1)] = (value & 0xf0) << 8; mem.data[(addr >> 1)] = (value & 0xf0) << 8;
mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12; mem.data[(addr >> 1) + 1] = (value & 0x0f) << 12;
}; };
this.load8 = function (addr) { this.load8 = function (addr) {
addr &= 0xffff; addr &= 0xffff;
var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff; var value = (mem.data[addr >>> 1] >> ((addr & 1) ? 0 : 8)) & 0xff;
if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42) if (addr == 0 || addr == 2 || addr == 0x40 || addr == 0x42)
return value; return value;
return ~value & 0xff; return ~value & 0xff;
}; };
this.store8 = function (addr, value) { this.store8 = function (addr, value) {
switch (addr & 0xff) { switch (addr & 0xff) {
case 0x30: case 0x30:
case 0x32: case 0x32:
mem.hi = 0; mem.hi = 0;
mem.lo = 0; mem.lo = 0;
this.write(0x48, 0x00); this.write(0x48, 0x00);
break; break;
case 0x48: case 0x48:
mem.hi = value; mem.hi = value;
//BUG.info('Expansion.store8() board %d done.', board + 1); //BUG.info('Expansion.store8() board %d done.', board + 1);
++board; ++board;
if (board <= MAX_EXPANSION_BOARDS) if (board <= MAX_EXPANSION_BOARDS)
this.config(board); this.config(board);
else else
this.clear(); this.clear();
break; break;
case 0x4a: case 0x4a:
mem.lo = value; mem.lo = value;
break; break;
case 0x4c: case 0x4c:
//BUG.info('Expansion.store8() board %d faild.', board + 1); //BUG.info('Expansion.store8() board %d faild.', board + 1);
++board; ++board;
if (board <= MAX_EXPANSION_BOARDS) if (board <= MAX_EXPANSION_BOARDS)
this.config(board); this.config(board);
else else
this.clear(); this.clear();
break; break;
} }
}; };
this.config = function(board) { this.config = function(board) {
var info = boards[board].info(); var info = boards[board].info();
@ -174,3 +174,4 @@ function Expansion() {
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,7 @@ function Memory() {
data: null, data: null,
lower: 0, lower: 0,
upper: 0 upper: 0
}; };
this.slow = { this.slow = {
enabled: false, enabled: false,
size: 0, size: 0,
@ -154,402 +154,402 @@ function Memory() {
}*/ }*/
this.setup = function () { this.setup = function () {
this.chip.size = getChipSize(AMIGA.config.ram.chip.size); this.chip.size = getChipSize(AMIGA.config.ram.chip.size);
this.chip.align = this.chip.size >>> 1; this.chip.align = this.chip.size >>> 1;
this.chip.data = new Uint16Array(this.chip.align); this.chip.data = new Uint16Array(this.chip.align);
for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0; for (var i = 0; i < this.chip.align; i++) this.chip.data[i] = 0;
this.chip.lower = 0; this.chip.lower = 0;
this.chip.upper = this.chip.size; this.chip.upper = this.chip.size;
if (AMIGA.config.ram.slow.size) { if (AMIGA.config.ram.slow.size) {
this.slow.enabled = true; this.slow.enabled = true;
this.slow.size = getSlowSize(AMIGA.config.ram.slow.size); this.slow.size = getSlowSize(AMIGA.config.ram.slow.size);
this.slow.align = this.slow.size >>> 1; this.slow.align = this.slow.size >>> 1;
this.slow.data = new Uint16Array(this.slow.align); this.slow.data = new Uint16Array(this.slow.align);
for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0; for (var i = 0; i < this.slow.align; i++) this.slow.data[i] = 0;
this.slow.upper = this.slow.lower + this.slow.size; this.slow.upper = this.slow.lower + this.slow.size;
} else { } else {
this.slow.enabled = false; this.slow.enabled = false;
this.slow.size = 0; this.slow.size = 0;
this.slow.align = 0; this.slow.align = 0;
this.slow.data = null; this.slow.data = null;
this.slow.upper = 0; this.slow.upper = 0;
} }
if (AMIGA.config.ram.fast.size) { if (AMIGA.config.ram.fast.size) {
this.fast.enabled = true; this.fast.enabled = true;
this.fast.size = getFastSize(AMIGA.config.ram.fast.size); this.fast.size = getFastSize(AMIGA.config.ram.fast.size);
this.fast.align = this.fast.size >>> 1; this.fast.align = this.fast.size >>> 1;
this.fast.data = new Uint16Array(this.fast.align); this.fast.data = new Uint16Array(this.fast.align);
for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0; for (var i = 0; i < this.fast.align; i++) this.fast.data[i] = 0;
this.fast.upper = this.fast.lower + this.fast.size; this.fast.upper = this.fast.lower + this.fast.size;
} else { } else {
this.fast.enabled = false; this.fast.enabled = false;
this.fast.size = 0; this.fast.size = 0;
this.fast.align = 0; this.fast.align = 0;
this.fast.data = null; this.fast.data = null;
this.fast.upper = 0; 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); 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.size = getROMSize(AMIGA.config.rom.size);
this.rom.align = this.rom.size >>> 1; this.rom.align = this.rom.size >>> 1;
this.rom.data = new Uint16Array(this.rom.align); this.rom.data = new Uint16Array(this.rom.align);
for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0; for (var i = 0; i < this.rom.align; i++) this.rom.data[i] = 0;
this.res_d8.data = new Uint16Array(this.res_d8.align); 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; 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); 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; 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); 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; for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0;
this.copy_rom(AMIGA.config.rom.data); this.copy_rom(AMIGA.config.rom.data);
if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) { if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) {
if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0) if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0)
this.copy_e0(AMIGA.config.ext.data); this.copy_e0(AMIGA.config.ext.data);
else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0) else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0)
this.copy_f0(AMIGA.config.ext.data); this.copy_f0(AMIGA.config.ext.data);
} }
//this.mirror_rom_to_chipram(); //this.mirror_rom_to_chipram();
/*if (AMIGA.config.rom.mode == 1) { /*if (AMIGA.config.rom.mode == 1) {
if (!this.aros.cached) { if (!this.aros.cached) {
BUG.info('Memory.setup() AROS-ROM is not cached, downloading...'); BUG.info('Memory.setup() AROS-ROM is not cached, downloading...');
AMIGA.loading += 2; AMIGA.loading += 2;
loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) { loadRemote('aros-amiga-m68k-rom.bin', 0xfc4635e1, function(data) {
AMIGA.mem.aros.cached = true; AMIGA.mem.aros.cached = true;
AMIGA.mem.aros.rom = data; AMIGA.mem.aros.rom = data;
AMIGA.mem.copy_rom(data); AMIGA.mem.copy_rom(data);
AMIGA.loading--; AMIGA.loading--;
}); });
loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) { loadRemote('aros-amiga-m68k-ext.bin', 0xc612f82e, function(data) {
AMIGA.mem.aros.cached = true; AMIGA.mem.aros.cached = true;
AMIGA.mem.aros.ext = data; AMIGA.mem.aros.ext = data;
AMIGA.mem.copy_e0(data); AMIGA.mem.copy_e0(data);
AMIGA.loading--; AMIGA.loading--;
}); });
} else { } else {
BUG.info('Memory.setup() AROS-ROM is cached, download skipped.'); BUG.info('Memory.setup() AROS-ROM is cached, download skipped.');
this.copy_rom(this.aros.rom); this.copy_rom(this.aros.rom);
this.copy_e0(this.aros.ext); this.copy_e0(this.aros.ext);
} }
} else { } else {
AMIGA.loading++; AMIGA.loading++;
loadLocal('cfg_rom_name', function(event) { loadLocal('cfg_rom_name', function(event) {
AMIGA.mem.copy_rom(event.target.result); AMIGA.mem.copy_rom(event.target.result);
AMIGA.loading--; AMIGA.loading--;
}); });
if (AMIGA.config.ext.size > 0) { if (AMIGA.config.ext.size > 0) {
AMIGA.loading++; AMIGA.loading++;
loadLocal('cfg_ext_name', function(event) { loadLocal('cfg_ext_name', function(event) {
if (AMIGA.config.ext.addr == 0xe00000) if (AMIGA.config.ext.addr == 0xe00000)
AMIGA.mem.copy_e0(event.target.result); AMIGA.mem.copy_e0(event.target.result);
else else
AMIGA.mem.copy_f0(event.target.result); AMIGA.mem.copy_f0(event.target.result);
AMIGA.loading--; AMIGA.loading--;
}); });
} }
}*/ }*/
}; };
this.load8 = function (addr) { 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) { if (addr >= 0x000000 && addr < this.chip.size) {
return (addr & 1) ? (this.chip.data[addr >>> 1] & 0xff) : (this.chip.data[addr >>> 1] >> 8); 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) { 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); 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) { 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); 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) { 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); 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) { else if (addr >= 0xdff000 && addr < 0xe00000) {
return AMIGA.custom.load8(addr); return AMIGA.custom.load8(addr);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01) { else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
return AMIGA.cia.load8(addr); return AMIGA.cia.load8(addr);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02) { else if (addr >= 0xbfe001 && addr < 0xbfef02) {
return AMIGA.cia.load8(addr); return AMIGA.cia.load8(addr);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000) { else if (addr >= 0xdc0000 && addr < 0xdd0000) {
return AMIGA.rtc.load8(addr); return AMIGA.rtc.load8(addr);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { 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); 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) { 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); 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) { 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); 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) { else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
return AMIGA.expansion.load8(addr); return AMIGA.expansion.load8(addr);
} }
//else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr); //else BUG.info('Memory.load8() ILLEGAL MEMORY ACCESS addr $%08x', addr);
return NULL8; return NULL8;
}; };
this.load16 = function (addr) { 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) { if (addr >= 0 && addr < this.chip.size - 1) {
return this.chip.data[addr >>> 1]; return this.chip.data[addr >>> 1];
} }
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
return this.slow.data[(addr - this.slow.lower) >>> 1]; return this.slow.data[(addr - this.slow.lower) >>> 1];
} }
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
return this.fast.data[(addr - this.fast.lower) >>> 1]; return this.fast.data[(addr - this.fast.lower) >>> 1];
} }
else if (addr >= this.rom.lower && addr < this.rom.upper - 1) { else if (addr >= this.rom.lower && addr < this.rom.upper - 1) {
return this.rom.data[(addr - this.rom.lower) >>> 1]; return this.rom.data[(addr - this.rom.lower) >>> 1];
} }
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
return AMIGA.custom.load16(addr); return AMIGA.custom.load16(addr);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
return AMIGA.cia.load16(addr); return AMIGA.cia.load16(addr);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
return AMIGA.cia.load16(addr); return AMIGA.cia.load16(addr);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
return AMIGA.rtc.load16(addr); return AMIGA.rtc.load16(addr);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
return this.res_e0.data[(addr - this.res_e0.lower) >>> 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) { else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
return this.res_f0.data[(addr - this.res_f0.lower) >>> 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) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
return this.res_d8.data[(addr - this.res_d8.lower) >>> 1]; return this.res_d8.data[(addr - this.res_d8.lower) >>> 1];
} }
//else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr); //else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr);
return NULL16; return NULL16;
}; };
this.load32 = function (addr) { 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) { if (addr >= 0 && addr < this.chip.size - 3) {
addr >>>= 1; addr >>>= 1;
return ((this.chip.data[addr] << 16) | this.chip.data[addr + 1]) >>> 0; 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) { else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
addr = (addr - this.slow.lower) >>> 1; addr = (addr - this.slow.lower) >>> 1;
return ((this.slow.data[addr] << 16) | this.slow.data[addr + 1]) >>> 0; 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) { else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
addr = (addr - this.fast.lower) >>> 1; addr = (addr - this.fast.lower) >>> 1;
return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0; return ((this.fast.data[addr] << 16) | this.fast.data[addr + 1]) >>> 0;
} }
else if (addr >= this.rom.lower && addr < this.rom.upper - 3) { else if (addr >= this.rom.lower && addr < this.rom.upper - 3) {
addr = (addr - this.rom.lower) >>> 1; addr = (addr - this.rom.lower) >>> 1;
return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0; return ((this.rom.data[addr] << 16) | this.rom.data[addr + 1]) >>> 0;
} }
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
return AMIGA.custom.load32(addr); return AMIGA.custom.load32(addr);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
return AMIGA.cia.load32(addr); return AMIGA.cia.load32(addr);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
return AMIGA.cia.load32(addr); return AMIGA.cia.load32(addr);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
return AMIGA.rtc.load32(addr); return AMIGA.rtc.load32(addr);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
addr = (addr - this.res_e0.lower) >>> 1; addr = (addr - this.res_e0.lower) >>> 1;
return ((this.res_e0.data[addr] << 16) | this.res_e0.data[addr + 1]) >>> 0; 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) { else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
addr = (addr - this.res_f0.lower) >>> 1; addr = (addr - this.res_f0.lower) >>> 1;
return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0; 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) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
addr = (addr - this.res_d8.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0; 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); //else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr);
return NULL32; return NULL32;
}; };
this.store8 = function (addr, value) { 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 >= 0 && addr < this.chip.size) {
if (addr & 1) { if (addr & 1) {
addr >>>= 1; addr >>>= 1;
this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value; this.chip.data[addr] = (this.chip.data[addr] & 0xff00) | value;
} else { } else {
addr >>>= 1; addr >>>= 1;
this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff); this.chip.data[addr] = (value << 8) | (this.chip.data[addr] & 0x00ff);
} }
} }
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) { else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.slow.lower) >>> 1; addr = (addr - this.slow.lower) >>> 1;
this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value; this.slow.data[addr] = (this.slow.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.slow.lower) >>> 1; addr = (addr - this.slow.lower) >>> 1;
this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff); this.slow.data[addr] = (value << 8) | (this.slow.data[addr] & 0x00ff);
} }
} }
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) { else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.fast.lower) >>> 1; addr = (addr - this.fast.lower) >>> 1;
this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value; this.fast.data[addr] = (this.fast.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.fast.lower) >>> 1; addr = (addr - this.fast.lower) >>> 1;
this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff); this.fast.data[addr] = (value << 8) | (this.fast.data[addr] & 0x00ff);
} }
} }
else if (addr >= 0xdff000 && addr < 0xe00000) { else if (addr >= 0xdff000 && addr < 0xe00000) {
AMIGA.custom.store8(addr, value); AMIGA.custom.store8(addr, value);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01) { else if (addr >= 0xbfd000 && addr < 0xbfdf01) {
AMIGA.cia.store8(addr, value); AMIGA.cia.store8(addr, value);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02) { else if (addr >= 0xbfe001 && addr < 0xbfef02) {
AMIGA.cia.store8(addr, value); AMIGA.cia.store8(addr, value);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000) { else if (addr >= 0xdc0000 && addr < 0xdd0000) {
AMIGA.rtc.store8(addr, value); AMIGA.rtc.store8(addr, value);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) { else if (addr >= this.res_e0.lower && addr < this.res_e0.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.res_e0.lower) >>> 1; addr = (addr - this.res_e0.lower) >>> 1;
this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value; this.res_e0.data[addr] = (this.res_e0.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.res_e0.lower) >>> 1; addr = (addr - this.res_e0.lower) >>> 1;
this.res_e0.data[addr] = (value << 8) | (this.res_e0.data[addr] & 0x00ff); 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) { else if (addr >= this.res_f0.lower && addr < this.res_f0.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.res_f0.lower) >>> 1; addr = (addr - this.res_f0.lower) >>> 1;
this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value; this.res_f0.data[addr] = (this.res_f0.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.res_f0.lower) >>> 1; addr = (addr - this.res_f0.lower) >>> 1;
this.res_f0.data[addr] = (value << 8) | (this.res_f0.data[addr] & 0x00ff); 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) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.res_d8.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value; this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.res_d8.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff); 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) { else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
AMIGA.expansion.store8(addr, value); AMIGA.expansion.store8(addr, value);
} }
//else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value); //else BUG.info('Memory.store8() ILLEGAL MEMORY ACCESS addr $%08x, val %02x', addr, value);
}; };
this.store16 = function (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) { if (addr >= 0 && addr < this.chip.size - 1) {
this.chip.data[addr >>> 1] = value; this.chip.data[addr >>> 1] = value;
} }
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) { else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 1) {
this.slow.data[(addr - this.slow.lower) >>> 1] = value; this.slow.data[(addr - this.slow.lower) >>> 1] = value;
} }
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) { else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 1) {
this.fast.data[(addr - this.fast.lower) >>> 1] = value; this.fast.data[(addr - this.fast.lower) >>> 1] = value;
} }
else if (addr >= 0xdff000 && addr < 0xe00000 - 1) { else if (addr >= 0xdff000 && addr < 0xe00000 - 1) {
AMIGA.custom.store16(addr, value); AMIGA.custom.store16(addr, value);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) { else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 1) {
AMIGA.cia.store16(addr, value); AMIGA.cia.store16(addr, value);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) { else if (addr >= 0xbfe001 && addr < 0xbfef02 - 1) {
AMIGA.cia.store16(addr, value); AMIGA.cia.store16(addr, value);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) { else if (addr >= 0xdc0000 && addr < 0xdd0000 - 1) {
AMIGA.rtc.store16(addr, value); AMIGA.rtc.store16(addr, value);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) { else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 1) {
this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value; this.res_e0.data[(addr - this.res_e0.lower) >>> 1] = value;
} }
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) { else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 1) {
this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value; this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value;
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value; this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value;
} }
//else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value); //else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value);
}; };
this.store32 = function (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) { if (addr >= 0 && addr < this.chip.size - 3) {
addr >>>= 1; addr >>>= 1;
this.chip.data[addr] = value >>> 16; this.chip.data[addr] = value >>> 16;
this.chip.data[addr + 1] = value & 0xffff; this.chip.data[addr + 1] = value & 0xffff;
} }
else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) { else if (this.slow.enabled && addr >= this.slow.lower && addr < this.slow.upper - 3) {
addr = (addr - this.slow.lower) >>> 1; addr = (addr - this.slow.lower) >>> 1;
this.slow.data[addr] = value >>> 16; this.slow.data[addr] = value >>> 16;
this.slow.data[addr + 1] = value & 0xffff; this.slow.data[addr + 1] = value & 0xffff;
} }
else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) { else if (this.fast.enabled && addr >= this.fast.lower && addr < this.fast.upper - 3) {
addr = (addr - this.fast.lower) >>> 1; addr = (addr - this.fast.lower) >>> 1;
this.fast.data[addr] = value >>> 16; this.fast.data[addr] = value >>> 16;
this.fast.data[addr + 1] = value & 0xffff; this.fast.data[addr + 1] = value & 0xffff;
} }
else if (addr >= 0xdff000 && addr < 0xe00000 - 3) { else if (addr >= 0xdff000 && addr < 0xe00000 - 3) {
AMIGA.custom.store32(addr, value); AMIGA.custom.store32(addr, value);
} }
else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) { else if (addr >= 0xbfd000 && addr < 0xbfdf01 - 3) {
AMIGA.cia.store32(addr, value); AMIGA.cia.store32(addr, value);
} }
else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) { else if (addr >= 0xbfe001 && addr < 0xbfef02 - 3) {
AMIGA.cia.store32(addr, value); AMIGA.cia.store32(addr, value);
} }
else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) { else if (addr >= 0xdc0000 && addr < 0xdd0000 - 3) {
AMIGA.rtc.store32(addr, value); AMIGA.rtc.store32(addr, value);
} }
else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) { else if (addr >= this.res_e0.lower && addr < this.res_e0.upper - 3) {
addr = (addr - this.res_e0.lower) >>> 1; addr = (addr - this.res_e0.lower) >>> 1;
this.res_e0.data[addr] = value >>> 16; this.res_e0.data[addr] = value >>> 16;
this.res_e0.data[addr + 1] = value & 0xffff; this.res_e0.data[addr + 1] = value & 0xffff;
} }
else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) { else if (addr >= this.res_f0.lower && addr < this.res_f0.upper - 3) {
addr = (addr - this.res_f0.lower) >>> 1; addr = (addr - this.res_f0.lower) >>> 1;
this.res_f0.data[addr] = value >>> 16; this.res_f0.data[addr] = value >>> 16;
this.res_f0.data[addr + 1] = value & 0xffff; this.res_f0.data[addr + 1] = value & 0xffff;
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
addr = (addr - this.res_d8.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d8.data[addr] = value >>> 16; this.res_d8.data[addr] = value >>> 16;
this.res_d8.data[addr + 1] = value & 0xffff; 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); //else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value);
}; };
/*this.check16_chip = function (addr, size) { /*this.check16_chip = function (addr, size) {
return (addr >= 0 && addr + size < this.chip.size - 1); return (addr >= 0 && addr + size < this.chip.size - 1);
};*/ };*/
/*this.load16_chip = function (addr) { /*this.load16_chip = function (addr) {
if (this.check16_chip(addr, 1)) { if (this.check16_chip(addr, 1)) {
var v = this.chip.data[addr >>> 1]; var v = this.chip.data[addr >>> 1];
AMIGA.custom.last_value = v; AMIGA.custom.last_value = v;
@ -579,76 +579,77 @@ function Memory() {
}*/ }*/
this.copy_rom = function (data) { this.copy_rom = function (data) {
//BUG.info('copyrom() size %d', data.length); //BUG.info('copyrom() size %d', data.length);
//BUG.info('copyrom() crc32 $%08x', crc32(data)); //BUG.info('copyrom() crc32 $%08x', crc32(data));
if (data.length == 0x80000) { if (data.length == 0x80000) {
/*var lo = crc32(data.substr(0, 0x40000)); /*var lo = crc32(data.substr(0, 0x40000));
var hi = crc32(data.substr(0x40000, 0x80000)); var hi = crc32(data.substr(0x40000, 0x80000));
if (lo != hi) { if (lo != hi) {
BUG.info('copyrom() lo crc32 $%08x', lo); BUG.info('copyrom() lo crc32 $%08x', lo);
BUG.info('copyrom() hi crc32 $%08x', hi); BUG.info('copyrom() hi crc32 $%08x', hi);
}*/ }*/
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var v = data.charCodeAt(i) & 0xff; var v = data.charCodeAt(i) & 0xff;
if (i & 1) { if (i & 1) {
var j = i >>> 1; var j = i >>> 1;
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
} else { } else {
var j = i >>> 1; var j = i >>> 1;
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff);
} }
} }
this.rom.lower = 0xf80000; this.rom.lower = 0xf80000;
} }
else if (data.length == 0x40000) { else if (data.length == 0x40000) {
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var v = data.charCodeAt(i) & 0xff; var v = data.charCodeAt(i) & 0xff;
if (i & 1) { if (i & 1) {
var j = i >>> 1; var j = i >>> 1;
this.rom.data[j] = (this.rom.data[j] & 0xff00) | v; this.rom.data[j] = (this.rom.data[j] & 0xff00) | v;
this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v; this.rom.data[0x20000 + j] = (this.rom.data[0x20000 + j] & 0xff00) | v;
} else { } else {
var j = i >>> 1; var j = i >>> 1;
this.rom.data[j] = (v << 8) | (this.rom.data[j] & 0x00ff); 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.data[0x20000 + j] = (v << 8) | (this.rom.data[0x20000 + j] & 0x00ff);
} }
} }
this.rom.lower = 0xfc0000; this.rom.lower = 0xfc0000;
} }
}; };
this.copy_e0 = function (data) { this.copy_e0 = function (data) {
if (data.length <= 0x80000) { if (data.length <= 0x80000) {
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var v = data.charCodeAt(i) & 0xff; var v = data.charCodeAt(i) & 0xff;
if (i & 1) { if (i & 1) {
var j = i >>> 1; var j = i >>> 1;
this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v; this.res_e0.data[j] = (this.res_e0.data[j] & 0xff00) | v;
} else { } else {
var j = i >>> 1; var j = i >>> 1;
this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff); this.res_e0.data[j] = (v << 8) | (this.res_e0.data[j] & 0x00ff);
} }
} }
} }
}; };
this.copy_f0 = function (data) { this.copy_f0 = function (data) {
if (data.length <= 0x80000) { if (data.length <= 0x80000) {
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var v = data.charCodeAt(i) & 0xff; var v = data.charCodeAt(i) & 0xff;
if (i & 1) { if (i & 1) {
var j = i >>> 1; var j = i >>> 1;
this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v; this.res_f0.data[j] = (this.res_f0.data[j] & 0xff00) | v;
} else { } else {
var j = i >>> 1; var j = i >>> 1;
this.res_f0.data[j] = (v << 8) | (this.res_f0.data[j] & 0x00ff); 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++) for (var i = 0; i < this.rom.size; i++)
this.chip.data[i] = this.rom.data[i]; this.chip.data[i] = this.rom.data[i];
}*/ }*/
} }

File diff suppressed because it is too large Load diff

View file

@ -18,217 +18,218 @@ function RTC() {
var rtc_alarm = null; var rtc_alarm = null;
this.read = function () { this.read = function () {
/*struct zfile *f; /*struct zfile *f;
f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL); f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
if (f) { if (f) {
zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f); zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
zfile_fclose (f); zfile_fclose (f);
}*/ }*/
}; };
this.write = function () { this.write = function () {
/*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL); /*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
if (!f) { if (!f) {
f = zfile_fopen (currprefs.flashfile, L"wb", 0); f = zfile_fopen (currprefs.flashfile, L"wb", 0);
if (f) { if (f) {
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
zfile_fclose (f); zfile_fclose (f);
} }
return; return;
} }
zfile_fseek (f, 0, SEEK_END); zfile_fseek (f, 0, SEEK_END);
if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) { if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) {
zfile_fseek (f, 0, SEEK_SET); zfile_fseek (f, 0, SEEK_SET);
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f); zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f); zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
} }
zfile_fclose (f);*/ zfile_fclose (f);*/
}; };
this.setup = function () { this.setup = function () {
BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A')); 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) { if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
clock_control_d = 0x1; clock_control_d = 0x1;
clock_control_e = 0; clock_control_e = 0;
clock_control_f = 0x4; clock_control_f = 0x4;
/* 24/12 */ /* 24/12 */
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
clock_control_d = 0x4; clock_control_d = 0x4;
/* Timer EN */ /* Timer EN */
clock_control_e = 0; clock_control_e = 0;
clock_control_f = 0; clock_control_f = 0;
rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE); rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE);
rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE); rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE);
for (var i = 0; i < RF5C01A_RAM_SIZE; i++) for (var i = 0; i < RF5C01A_RAM_SIZE; i++)
rtc_memory[i] = rtc_alarm[i] = 0; rtc_memory[i] = rtc_alarm[i] = 0;
this.read(); this.read();
} }
}; };
this.load8 = function (addr) { this.load8 = function (addr) {
addr &= 0x3f; addr &= 0x3f;
if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) { 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) if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible)
return 0xff; //regs.irc >> 8; return 0xff; //regs.irc >> 8;
return 0; return 0;
} }
var t = new Date(); var t = new Date();
addr >>= 2; addr >>= 2;
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
switch (addr) { switch (addr) {
case 0x0: case 0x0:
return t.getSeconds() % 10; return t.getSeconds() % 10;
case 0x1: case 0x1:
return Math.floor(t.getSeconds() / 10); return Math.floor(t.getSeconds() / 10);
case 0x2: case 0x2:
return t.getMinutes() % 10; return t.getMinutes() % 10;
case 0x3: case 0x3:
return Math.floor(t.getMinutes() / 10); return Math.floor(t.getMinutes() / 10);
case 0x4: case 0x4:
return t.getHours() % 10; return t.getHours() % 10;
case 0x5: case 0x5:
return Math.floor(t.getHours() / 10); return Math.floor(t.getHours() / 10);
case 0x6: case 0x6:
return t.getDate() % 10; return t.getDate() % 10;
case 0x7: case 0x7:
return Math.floor(t.getDate() / 10); return Math.floor(t.getDate() / 10);
case 0x8: case 0x8:
return (t.getMonth() + 1) % 10; return (t.getMonth() + 1) % 10;
case 0x9: case 0x9:
return Math.floor((t.getMonth() + 1) / 10); return Math.floor((t.getMonth() + 1) / 10);
case 0xA: case 0xA:
return (t.getFullYear() - 1900) % 10; return (t.getFullYear() - 1900) % 10;
case 0xB: case 0xB:
return Math.floor((t.getFullYear() - 1900) / 10); return Math.floor((t.getFullYear() - 1900) / 10);
case 0xC: case 0xC:
return t.getDay(); return t.getDay();
case 0xD: case 0xD:
return clock_control_d; return clock_control_d;
case 0xE: case 0xE:
return clock_control_e; return clock_control_e;
case 0xF: case 0xF:
return clock_control_f; return clock_control_f;
} }
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
var bank = clock_control_d & 3; var bank = clock_control_d & 3;
if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f; 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 == 1 && addr < 0x0d) return rtc_alarm[addr];
switch (addr) { switch (addr) {
case 0x0: case 0x0:
return t.getSeconds() % 10; return t.getSeconds() % 10;
case 0x1: case 0x1:
return Math.floor(t.getSeconds() / 10); return Math.floor(t.getSeconds() / 10);
case 0x2: case 0x2:
return t.getMinutes() % 10; return t.getMinutes() % 10;
case 0x3: case 0x3:
return Math.floor(t.getMinutes() / 10); return Math.floor(t.getMinutes() / 10);
case 0x4: case 0x4:
return t.getHours() % 10; return t.getHours() % 10;
case 0x5: case 0x5:
return Math.floor(t.getHours() / 10); return Math.floor(t.getHours() / 10);
case 0x6: case 0x6:
return t.getDate() % 10; return t.getDate() % 10;
case 0x7: case 0x7:
return Math.floor(t.getDate() / 10); return Math.floor(t.getDate() / 10);
case 0x8: case 0x8:
return (t.getMonth() + 1) % 10; return (t.getMonth() + 1) % 10;
case 0x9: case 0x9:
return Math.floor((t.getMonth() + 1) / 10); return Math.floor((t.getMonth() + 1) / 10);
case 0xA: case 0xA:
return (t.getFullYear() - 1900) % 10; return (t.getFullYear() - 1900) % 10;
case 0xB: case 0xB:
return Math.floor((t.getFullYear() - 1900) / 10); return Math.floor((t.getFullYear() - 1900) / 10);
case 0xC: case 0xC:
return t.getDay(); return t.getDay();
case 0xD: case 0xD:
return clock_control_d; return clock_control_d;
/* E and F = write-only */ /* E and F = write-only */
} }
} }
return 0; return 0;
}; };
this.load16 = function (addr) { 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) { 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) { this.store8 = function (addr, value) {
addr &= 0x3f; addr &= 0x3f;
if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return; if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return;
addr >>= 2; addr >>= 2;
value &= 0x0f; value &= 0x0f;
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
switch (addr) { switch (addr) {
case 0xD: case 0xD:
clock_control_d = value & (1 | 8); clock_control_d = value & (1 | 8);
break; break;
case 0xE: case 0xE:
clock_control_e = value; clock_control_e = value;
break; break;
case 0xF: case 0xF:
clock_control_f = value; clock_control_f = value;
break; break;
} }
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { } else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
var bank = clock_control_d & 3; var bank = clock_control_d & 3;
if (bank >= 2 && addr < 0x0d) { if (bank >= 2 && addr < 0x0d) {
rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f); rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4); rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
//var ov = rtc_memory[addr]; //var ov = rtc_memory[addr];
if (rtc_memory[addr] != value) this.write(); if (rtc_memory[addr] != value) this.write();
return; return;
} }
if (bank == 1 && addr < 0x0d) { if (bank == 1 && addr < 0x0d) {
rtc_alarm[addr] = value; rtc_alarm[addr] = value;
rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0; rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
rtc_alarm[3] &= ~0x8; rtc_alarm[3] &= ~0x8;
rtc_alarm[5] &= ~0xc; rtc_alarm[5] &= ~0xc;
rtc_alarm[6] &= ~0x8; rtc_alarm[6] &= ~0x8;
rtc_alarm[8] &= ~0xc; rtc_alarm[8] &= ~0xc;
rtc_alarm[10] &= ~0xe; rtc_alarm[10] &= ~0xe;
rtc_alarm[11] &= ~0xc; rtc_alarm[11] &= ~0xc;
//var ov = rtc_alarm[addr]; //var ov = rtc_alarm[addr];
if (rtc_alarm[addr] != value) this.write(); if (rtc_alarm[addr] != value) this.write();
return; return;
} }
switch (addr) { switch (addr) {
case 0xD: case 0xD:
clock_control_d = value; clock_control_d = value;
break; break;
case 0xE: case 0xE:
clock_control_e = value; clock_control_e = value;
break; break;
case 0xF: case 0xF:
clock_control_f = value; clock_control_f = value;
break; break;
} }
} }
}; };
this.store16 = function (addr, value) { this.store16 = function (addr, value) {
this.store8(addr, (value >> 8) & 0xff); this.store8(addr, (value >> 8) & 0xff);
this.store8(addr + 1, value & 0xff); this.store8(addr + 1, value & 0xff);
}; };
this.store32 = function (addr, value) { this.store32 = function (addr, value) {
this.store16(addr, (value >>> 16) & 0xffff); this.store16(addr, (value >>> 16) & 0xffff);
this.store16(addr + 2, value & 0xffff); this.store16(addr + 2, value & 0xffff);
} }
} }

View file

@ -14,64 +14,64 @@ function Serial()
var serper = 0, serdat = 0x2000; var serper = 0, serdat = 0x2000;
this.reset = function () { this.reset = function () {
this.flushBuffer(); this.flushBuffer();
pos = 0; pos = 0;
dtr = false; dtr = false;
serper = 0; serper = 0;
serdat = 0x2000; serdat = 0x2000;
}; };
this.flushBuffer = function () { this.flushBuffer = function () {
if (pos > 0) { if (pos > 0) {
var str = ''; var str = '';
for (var i = 0; i < pos; i++) { for (var i = 0; i < pos; i++) {
/*if (buf[i] == 13) /*if (buf[i] == 13)
str += '<br/>'; str += '<br/>';
else if (buf[i] == 9) else if (buf[i] == 9)
str += '&nbsp;&nbsp;&nbsp;'; str += '&nbsp;&nbsp;&nbsp;';
else*/ else*/
str += String.fromCharCode(buf[i]); str += String.fromCharCode(buf[i]);
} }
pos = 0; pos = 0;
BUG.col = 3; BUG.col = 3;
BUG.info(str); BUG.info(str);
BUG.col = 1; BUG.col = 1;
} }
}; };
this.readStatus = function () { this.readStatus = function () {
//ciabpra |= 0x20; //Push up Carrier Detect line //ciabpra |= 0x20; //Push up Carrier Detect line
//ciabpra |= 0x08; //DSR ON //ciabpra |= 0x08; //DSR ON
return 0; return 0;
}; };
this.writeStatus = function (old, nw) { this.writeStatus = function (old, nw) {
if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true; if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true;
if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false; 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 & 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'); //if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr');
return nw; return nw;
}; };
this.SERPER = function (v) { this.SERPER = function (v) {
if (serper != v) if (serper != v)
serper = v; serper = v;
}; };
this.SERDAT = function (v) { this.SERDAT = function (v) {
//BUG.info('SERDAT $%04x', v); //BUG.info('SERDAT $%04x', v);
if (AMIGA.config.serial.enabled) { if (AMIGA.config.serial.enabled) {
buf[pos++] = v & 0xff; buf[pos++] = v & 0xff;
if (pos == 1024) if (pos == 1024)
this.flushBuffer(); this.flushBuffer();
} }
serdat |= 0x2000; serdat |= 0x2000;
/* Set TBE in the SERDATR ... */ /* Set TBE in the SERDATR ... */
AMIGA.intreq |= 1; AMIGA.intreq |= 1;
/* ... and in INTREQ register */ /* ... and in INTREQ register */
}; };
this.SERDATR = function() this.SERDATR = function()
{ {
@ -79,3 +79,4 @@ function Serial()
return serdat; return serdat;
} }
} }

View file

@ -17,10 +17,10 @@ function MAvg(size) {
this.average = 0; this.average = 0;
this.clr = function () { this.clr = function () {
this.usage = 0; this.usage = 0;
this.offset = 0; this.offset = 0;
this.average = 0; this.average = 0;
}; };
this.set = function(newval) { this.set = function(newval) {
if (this.usage < this.size) { if (this.usage < this.size) {
@ -91,126 +91,126 @@ function MAvg(size) {
*/ */
sprintfWrapper = { sprintfWrapper = {
init: function () { init: function () {
if (typeof arguments == "undefined") { if (typeof arguments == "undefined") {
return null; return null;
} }
if (arguments.length < 1) { if (arguments.length < 1) {
return null; return null;
} }
if (typeof arguments[0] != "string") { if (typeof arguments[0] != "string") {
return null; return null;
} }
if (typeof RegExp == "undefined") { if (typeof RegExp == "undefined") {
return null; return null;
} }
var string = arguments[0]; var string = arguments[0];
var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g); var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
var matches = []; var matches = [];
var strings = []; var strings = [];
var convCount = 0; var convCount = 0;
var stringPosStart = 0; var stringPosStart = 0;
var stringPosEnd = 0; var stringPosEnd = 0;
var matchPosEnd = 0; var matchPosEnd = 0;
var newString = ''; var newString = '';
var match; var match;
while (match = exp.exec(string)) { while (match = exp.exec(string)) {
if (match[9]) { if (match[9]) {
convCount += 1; convCount += 1;
} }
stringPosStart = matchPosEnd; stringPosStart = matchPosEnd;
stringPosEnd = exp.lastIndex - match[0].length; stringPosEnd = exp.lastIndex - match[0].length;
strings[strings.length] = string.substring(stringPosStart, stringPosEnd); strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
matchPosEnd = exp.lastIndex; matchPosEnd = exp.lastIndex;
matches[matches.length] = { matches[matches.length] = {
match: match[0], match: match[0],
left: match[3] ? true : false, left: match[3] ? true : false,
sign: match[4] || '', sign: match[4] || '',
pad: match[5] || ' ', pad: match[5] || ' ',
min: match[6] || 0, min: match[6] || 0,
precision: match[8], precision: match[8],
code: match[9] || '%', code: match[9] || '%',
negative: !!(parseInt(arguments[convCount]) < 0), negative: !!(parseInt(arguments[convCount]) < 0),
argument: String(arguments[convCount]) argument: String(arguments[convCount])
}; };
} }
strings[strings.length] = string.substring(matchPosEnd); strings[strings.length] = string.substring(matchPosEnd);
if (matches.length == 0) { if (matches.length == 0) {
return string; return string;
} }
if ((arguments.length - 1) < convCount) { if ((arguments.length - 1) < convCount) {
return null; return null;
} }
for (var i = 0; i < matches.length; i++) { for (var i = 0; i < matches.length; i++) {
var substitution; var substitution;
if (matches[i].code == '%') { if (matches[i].code == '%') {
substitution = '%' substitution = '%'
} else if (matches[i].code == 'b') { } else if (matches[i].code == 'b') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2)); matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
substitution = sprintfWrapper.convert(matches[i], true); substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'c') { } else if (matches[i].code == 'c') {
matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument))))); matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
substitution = sprintfWrapper.convert(matches[i], true); substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'd') { } else if (matches[i].code == 'd') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument))); matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
substitution = sprintfWrapper.convert(matches[i]); substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'f') { } else if (matches[i].code == 'f') {
matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6)); matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
substitution = sprintfWrapper.convert(matches[i]); substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'o') { } else if (matches[i].code == 'o') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8)); matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
substitution = sprintfWrapper.convert(matches[i]); substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 's') { } else if (matches[i].code == 's') {
matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length); matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
substitution = sprintfWrapper.convert(matches[i], true); substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'x') { } else if (matches[i].code == 'x') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]); substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'X') { } else if (matches[i].code == 'X') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16)); matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]).toUpperCase(); substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
} else { } else {
substitution = matches[i].match; substitution = matches[i].match;
} }
newString += strings[i]; newString += strings[i];
newString += substitution; newString += substitution;
} }
newString += strings[i]; newString += strings[i];
return newString; return newString;
}, },
convert: function (match, nosign) { convert: function (match, nosign) {
if (nosign) { if (nosign) {
match.sign = ''; match.sign = '';
} else { } else {
match.sign = match.negative ? '-' : match.sign; match.sign = match.negative ? '-' : match.sign;
} }
var l = match.min - match.argument.length + 1 - match.sign.length; var l = match.min - match.argument.length + 1 - match.sign.length;
var pad = new Array(l < 0 ? 0 : l).join(match.pad); var pad = new Array(l < 0 ? 0 : l).join(match.pad);
if (!match.left) { if (!match.left) {
if (match.pad == "0" || nosign) { if (match.pad == "0" || nosign) {
return match.sign + pad + match.argument; return match.sign + pad + match.argument;
} else { } else {
return pad + match.sign + match.argument; return pad + match.sign + match.argument;
} }
} else { } else {
if (match.pad == "0" || nosign) { if (match.pad == "0" || nosign) {
return match.sign + match.argument + pad.replace(/0/g, ' '); return match.sign + match.argument + pad.replace(/0/g, ' ');
} else { } else {
return match.sign + match.argument + pad; return match.sign + match.argument + pad;
} }
} }
} }
}; };
sprintf = sprintfWrapper.init; sprintf = sprintfWrapper.init;
@ -235,7 +235,7 @@ var BrowserDetect = {
if (dataString.indexOf(data[i].subString) != -1) return data[i].identity; if (dataString.indexOf(data[i].subString) != -1) return data[i].identity;
} else if (dataProp) return data[i].identity; } else if (dataProp) return data[i].identity;
} }
return ''; return '';
}, },
searchVersion: function (dataString) { searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString); var index = dataString.indexOf(this.versionSearchString);
@ -396,21 +396,21 @@ function Debug() {
this.on = 1; this.on = 1;
this.say = function (str) { this.say = function (str) {
if (this.on) { if (this.on) {
/*var e = document.createElement('span'); /*var e = document.createElement('span');
e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484'); e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484');
e.innerHTML = buf; e.innerHTML = buf;
this.debug.appendChild(e); this.debug.appendChild(e);
this.debug.appendChild(document.createElement('br')); this.debug.appendChild(document.createElement('br'));
this.debug.scrollTop = this.debug.scrollHeight;*/ this.debug.scrollTop = this.debug.scrollHeight;*/
console.log(str); console.log(str);
/*console.info(str); /*console.info(str);
console.warn(str); console.warn(str);
console.error(str); console.error(str);
console.assert(str);*/ console.assert(str);*/
} }
}; };
this.info = function () { this.info = function () {
if (this.on) { if (this.on) {
@ -427,47 +427,47 @@ function Debug() {
this.lo = lo; this.lo = lo;
this.or = function (v) { this.or = function (v) {
this.hi = (this.hi | v.hi) >>> 0; this.hi = (this.hi | v.hi) >>> 0;
this.lo = (this.lo | v.lo) >>> 0; this.lo = (this.lo | v.lo) >>> 0;
}; };
this.lshift = function (n) { this.lshift = function (n) {
if (n) { if (n) {
if (n < 32) { if (n < 32) {
var m = Math.pow(2, n) - 1; var m = Math.pow(2, n) - 1;
var t = this.lo & m; var t = this.lo & m;
this.hi = ((this.hi << n) | t) >>> 0; this.hi = ((this.hi << n) | t) >>> 0;
this.lo = (this.lo << n) >>> 0; this.lo = (this.lo << n) >>> 0;
//BUG.info('lshift %d %x', n, m, t); //BUG.info('lshift %d %x', n, m, t);
} else { } else {
var t = this.lo; var t = this.lo;
this.hi = (t << (n - 32)) >>> 0; this.hi = (t << (n - 32)) >>> 0;
this.lo = 0; this.lo = 0;
//BUG.info('lshift %d %x', n, t); //BUG.info('lshift %d %x', n, t);
} }
} }
}; };
this.rshift = function (n) { this.rshift = function (n) {
if (n) { if (n) {
if (n < 32) { if (n < 32) {
var m = Math.pow(2, n) - 1; var m = Math.pow(2, n) - 1;
var t = this.hi & m; var t = this.hi & m;
this.hi = (this.hi >>> n) >>> 0; this.hi = (this.hi >>> n) >>> 0;
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0; this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
//BUG.info('rshift %d %x %x', n, m, t); //BUG.info('rshift %d %x %x', n, m, t);
} else { } else {
var t = this.hi; var t = this.hi;
this.hi = 0; this.hi = 0;
this.lo = (t >>> (n - 32)) >>> 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() { this.print = function() {
BUG.info('$%08x%08x', this.hi, this.lo); BUG.info('$%08x%08x', this.hi, this.lo);
@ -475,3 +475,4 @@ function Debug() {
}*/ }*/

View file

@ -142,103 +142,103 @@ function Vide0() {
} }
this.setup = function () { this.setup = function () {
if (!AMIGA.config.video.enabled) return; if (!AMIGA.config.video.enabled) return;
if (open) this.cleanup(); if (open) this.cleanup();
div = document.getElementById(AMIGA.config.video.id); div = document.getElementById(AMIGA.config.video.id);
if (!div) if (!div)
Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: ' + AMIGA.config.video.id + ')'); 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; scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false;
width = VIDEO_WIDTH << (scale ? 1 : 0); width = VIDEO_WIDTH << (scale ? 1 : 0);
height = VIDEO_HEIGHT << (scale ? 1 : 0); height = VIDEO_HEIGHT << (scale ? 1 : 0);
size = width * height; size = width * height;
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal'); //BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
if (this.available & SAEI_Video_Canvas2D) { if (this.available & SAEI_Video_Canvas2D) {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
canvas.oncontextmenu = function () { canvas.oncontextmenu = function () {
return false; return false;
}; };
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) { if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
canvas.onmousedown = function (e) { canvas.onmousedown = function (e) {
AMIGA.input.mouse.mousedown(e); AMIGA.input.mouse.mousedown(e);
}; };
canvas.onmouseup = function (e) { canvas.onmouseup = function (e) {
AMIGA.input.mouse.mouseup(e); AMIGA.input.mouse.mouseup(e);
}; };
canvas.onmouseover = function (e) { canvas.onmouseover = function (e) {
AMIGA.input.mouse.mouseover(e); AMIGA.input.mouse.mouseover(e);
}; };
canvas.onmouseout = function (e) { canvas.onmouseout = function (e) {
AMIGA.input.mouse.mouseout(e); AMIGA.input.mouse.mouseout(e);
}; };
canvas.onmousemove = function (e) { canvas.onmousemove = function (e) {
AMIGA.input.mouse.mousemove(e); AMIGA.input.mouse.mousemove(e);
} }
} }
if (this.available & SAEI_Video_WebGL) { if (this.available & SAEI_Video_WebGL) {
ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams); ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams);
initGL(); initGL();
pixels = new Uint16Array(size); pixels = new Uint16Array(size);
for (var i = 0; i < size; i++) pixels[i] = 0; for (var i = 0; i < size; i++) pixels[i] = 0;
//this.drawpixel = drawpixel_gl; //this.drawpixel = drawpixel_gl;
this.drawline = drawline_gl; this.drawline = drawline_gl;
this.render = render_gl; this.render = render_gl;
this.show = show_gl; this.show = show_gl;
} else { } else {
ctx = canvas.getContext('2d'); ctx = canvas.getContext('2d');
imagedata = ctx.createImageData(width, height); imagedata = ctx.createImageData(width, height);
pixels = imagedata.data; pixels = imagedata.data;
//this.drawpixel = drawpixel_2d; //this.drawpixel = drawpixel_2d;
this.drawline = drawline_2d; this.drawline = drawline_2d;
this.render = render_2d; this.render = render_2d;
this.show = show_2d; this.show = show_2d;
} }
} else { } else {
if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?')) if (!confirm('Cant\'t initialise "WebGL" nor "Canvas 2D". Continue without video-playback?'))
Fatal(SAEE_Video_Canvas_Not_Supported, null); Fatal(SAEE_Video_Canvas_Not_Supported, null);
else else
AMIGA.config.video.enabled = false; AMIGA.config.video.enabled = false;
} }
video = document.createElement('div'); video = document.createElement('div');
video.style.width = width + 'px'; video.style.width = width + 'px';
video.style.height = height + 'px'; video.style.height = height + 'px';
video.style.margin = 'auto'; video.style.margin = 'auto';
video.style.webkitTouchCallout = 'none'; video.style.webkitTouchCallout = 'none';
video.style.webkitUserSelect = 'none'; video.style.webkitUserSelect = 'none';
video.style.khtmlUserSelect = 'none'; video.style.khtmlUserSelect = 'none';
video.style.mozUserSelect = 'none'; video.style.mozUserSelect = 'none';
video.style.msUserSelect = 'none'; video.style.msUserSelect = 'none';
video.style.userSelect = 'none'; video.style.userSelect = 'none';
if (AMIGA.config.video.enabled) if (AMIGA.config.video.enabled)
video.appendChild(canvas); video.appendChild(canvas);
div.appendChild(video); div.appendChild(video);
open = true; open = true;
}; };
this.cleanup = function () { this.cleanup = function () {
if (open) { if (open) {
div.removeChild(video); div.removeChild(video);
canvas = null; canvas = null;
imagedata = null; imagedata = null;
pixels = null; pixels = null;
video = null; video = null;
open = false; open = false;
} }
}; };
/*---------------------------------*/ /*---------------------------------*/
/*this.hideCursor = function (hide) { /*this.hideCursor = function (hide) {
canvas.style.cursor = hide ? 'none' : 'auto'; canvas.style.cursor = hide ? 'none' : 'auto';
};*/ };*/
/*this.clear_pixels = function () { /*this.clear_pixels = function () {
for (var i = 0; i < size; i++) for (var i = 0; i < size; i++)
@ -296,3 +296,4 @@ function Vide0() {
ctx.drawArrays(ctx.TRIANGLES, 0, 6); ctx.drawArrays(ctx.TRIANGLES, 0, 6);
} }
} }