update 0.8.1

This commit is contained in:
Rupert Hausberger 2013-07-07 16:53:47 +02:00
commit dd3bb23b86
24 changed files with 10461 additions and 9746 deletions

12
ga.js Normal file
View file

@ -0,0 +1,12 @@
/* google analytics */
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-37232052-1']);
_gaq.push(['_setDomainName', 'scriptedamigaemulator.net']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

View file

@ -41,7 +41,7 @@ body {
left:0;
margin:0;
padding:0;
font-family:verdana;
font-family:verdana,serif;
font-size:small;
background-color:#fff;
}
@ -81,7 +81,7 @@ body {
background-color:#fcfcfc;
}
.config_simple_hof {
width:480px;
width:380px;
margin:auto;
padding:10px;
border:1px solid #ccc;
@ -114,7 +114,6 @@ body {
width:auto;
}
#config select {
border:0;
border:1px solid #ccc;
}
#config .button {
@ -195,7 +194,7 @@ body {
vertical-align:top;
}
div.float_box {
/*div.float_box {
overflow: hidden;
width: 100%;
}
@ -204,4 +203,4 @@ div.float_item {
}
div.float_clear {
clear: both;
}
}*/

View file

@ -47,22 +47,11 @@
<h3>Welcome!</h3>
This site is the homepage of the project <a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">SAE</a>,
an <i>experimental</i> <a target="_blank" href="http://en.wikipedia.org/wiki/Amiga">Amiga</a> emulator in pure JavaScript and HTML5.<br />
SAE is based on <a target="_blank" href="http://winuae.net')">WinUAE</a> and does use the <a href="javascript:openNewTab('http://aros.org">AROS</a>-kickstart replacement.
For more details, please see the <a target="_blank" href="readme.htm">description</a>.<br />
SAE is based on <a target="_blank" href="http://winuae.net">WinUAE</a> and does use the <a target="_blank" href="http://aros.org">AROS</a>-kickstart replacement.
For more details, please see the <a target="_blank" href="readme.htm">description</a>.<br />
<br />
Below you find a collection of pre-installed games and demos to play and test. Press the 'Config'-button to use your own roms or file-images, with advanced options.<br />
<br />
<span style="font-size:x-small;color:orange">
Update 22.01.2013: The new game-database is now online. It's quite empty yet and will be filled with freeware and public-domain titles.<br />
<br />
</span>
<span class="info">
<span class="fwb">Your game or demo online</span><br />
If you want to have your game or demo on this site, please <a href="mailto:rupert_hausberger@gmx.net">contact</a> me.
It would be published under a free license, with a link to your homepage and would be free to play for everyone.
This is a non-profit site and an open-source project.<br />
<br />
</span>
<br />
<div class="config_simple_hof">
<!--<div class="acm">
<span class="fwb">Browser</span>
@ -89,17 +78,17 @@
</div>-->
<table>
<tr>
<td class="armsb">Game</td>
<td class="armsb"><label for="cfg_game">Game</label></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>
</select>
</td>
</tr>
<tr>
<td class="armsb">Demo</td>
<td class="armsb"><label for="cfg_demo">Demo</label></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>
</select>
</td>
@ -154,7 +143,14 @@
<button class="sbutton" id="cfg_simple_start" onclick="simpleStart()">Play</button>
<button class="button" onclick="switchCfg(1)">Config</button>
</div>
</div>
</div>
<br />
<span class="info">
<span class="fwb">Your game or demo online</span><br />
If you want to have your game or demo on this site, please contact me.
It would be published under a free license, with a link to your homepage and would be free to play for everyone.
This is a non-profit site and an open-source project.
</span>
</div>
<div id="config_advanced">
<div class="acm"><button class="button" onclick="switchCfg(0)">Back</button></div>
@ -533,7 +529,7 @@
<input id="cfg_ports_1_enabled" type="checkbox" onchange="portUpdate(1)" />
Enabled
<span id="cfg_ports_1_grp">
<select id="cfg_ports_1" size="1" onchange="portsUpdate(1)">
<select id="cfg_ports_1" size="1">
<option value="3">Joystick 1</option>
</select>
Move
@ -670,7 +666,7 @@
<div style="height:10px"></div>
<div id="myVideo"></div>
</div>
</body>
</html>

210
index.js
View file

@ -14,15 +14,45 @@
const URL_TEAM_HOI = '<a href="javascript:openNewTab(\'http://www.sevensheaven.nl\')">Team Hoi</a>';
const URL_RETROGURU = '<a href="javascript:openNewTab(\'http://www.retroguru.com\')">retroguru</a>';
const URL_LOEWENSTEIN = '<a href="javascript:openNewTab(\'http://www.richard-loewenstein.de\')">Richard Löwenstein</a>';
const db = [
/* name company year [disks] [change, turbo] [en,f1,f2,map] load [keys] immediate */
[
['Air Ace II', ['SEUCK', '-', 'Public Domain'], '1989',
['Air Ace II.adf', false, false, false], [false, true],
[true, 16, 17, false], ['...takes very long.'], [], false
],
['Asteroids', ['Vertical Developments', '-', 'Public Domain'], '1979',
['Asteroids.adf', false, false, false], [false, true],
[true, 16, 17, false], [], [], false
],
['Crazy Sue', ['Jumpshoe, Hironymous', '-', 'Public Domain'], '1991',
['Crazy Sue.adf', false, false, false], [false, true],
[true, 16, 17, false], ['...can take some time.'], [], false
],
['Deluxe Galaga 2.4', ['Edgar Vigdal', '-', 'Freeware'], '1994',
['Deluxe Galaga.adf', false, false, false], [false, true],
[true, 16, 17, false], [], [], false
],
['Hoi', [URL_TEAM_HOI, 'Hollyware', 'Freeware'], '1992',
['Hoi (Disk 1).adf',
'Hoi (Disk 2).adf', false, false], [true, true],
[true, 16, 17, false], ['Press the LMB to skip the intro and insert the 2nd disk manually.'], [], false
[true, 16, 17, false], ['Press the LMB to skip the intro and insert the 2nd disk manually.<br /><br />'+
'<span title="After the disk-change, place the \'LVL\'-pointer in the far lower right of the green quarter screen. The bottom \'L\' must be positioned in the corner precisely. Click the LMB, then shift the \'LVL\' pointer to the absolute top left of the screen (as far as it can be moved in that direction). Click the LMB again. Any of the first four levels may now be selected for game play. Press the F4 key during game play for twelve lives. Note: Level 5 can only be accessed by completing level 4.">Cheat (move mouse-over)</span>'], [], false
],
['Norse Gods', [URL_LOEWENSTEIN, '-', 'Freeware'], '1991',
['Norse Gods.adf', false, false, false], [false, true],
[true, 16, 17, false], [], [], false
],
['Pollymorf', ['Andrew Campbell', '-', 'Public Domain'], '1993',
['Pollymorf.adf', false, false, false], [false, true],
[true, 16, 17, false], ['...takes some time, just wait.'], [], false
],
/*['Rectum', ['Mathias Olsson', '-', 'Freeware'], '1992',
['Rectum.adf', false, false, false], [false, true],
[true, 16, 17, false], ['Press the LMB to skip the intro...'], [], false
],*/
['Sqrxz', [URL_RETROGURU, '-', 'Freeware'], '2012',
['sqrxz.adf', false, false, false], [false, true],
[true, 16, 17, false], ['The color-stripes are normal, just wait...'], [], false
@ -31,6 +61,14 @@ const db = [
['sqrxz2.adf', false, false, false], [false, true],
[true, 16, 17, false], ['After the start, click the RMB for the trainer menu.<br />The color-stripes are normal, just wait...'], [], false
],
['Super Obliteration', ['David Papworth', '-', 'Freeware'], '1993',
['Super Obliteration.adf', false, false, false], [false, true],
[true, 16, 17, false], [], [], false
],
['Tanx', ['Robertz Gaz', '-', 'Public Domain'], '1991',
['Tanx.adf', false, false, false], [false, true],
[true, 16, 17, false], [], [], false
]
],
[
['242', 'Virtual Dreams', '1992',
@ -78,6 +116,10 @@ const db = [
[true, 16, 17, false],
['Insert the 2nd disk manually and<br />click the RMB when done.'], [], true
],
['HipHop Hater', 'Mathias Olsson', '1991',
['HipHop Hater.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [], false
],
['Ice', 'Silents', '1991',
['Ice.adf',false,false,false], [false, true],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [], false
@ -134,12 +176,12 @@ var dbNum = 0;
const aros_rom_file = 'aros-amiga-m68k-rom.bin';
const aros_rom_url = 'http://'+window.location.hostname+'/db/'+aros_rom_file;
const aros_rom_size = 0x80000;
const aros_rom_crc = 0xea48b4d1; //0xfc4635e1;
const aros_rom_crc = 0x48dfadd; //0xea48b4d1
const aros_ext_file = 'aros-amiga-m68k-ext.bin';
const aros_ext_url = 'http://'+window.location.hostname+'/db/'+aros_ext_file;
const aros_ext_size = 0x80000;
const aros_ext_crc = 0x60871435; //0xc612f82e;
const aros_ext_crc = 0xaaf211d6; //0x60871435
var mode = 0;
var paused = false;
var dskchg = false;
@ -163,42 +205,42 @@ function Cache() {
var roms = [null,null];
var disks = [];
this.loadRom = function(num) {
if (roms[num]) {
console.log('loadRom.loadRom() %d is cached', num);
return roms[num];
}
console.log('loadRom.loadRom() downloading %d', num);
var url, size, crc;
switch (num) {
case 0:
url = aros_rom_url;
size = aros_rom_size;
crc = aros_rom_crc;
break;
case 1:
url = aros_ext_url;
size = aros_ext_size;
crc = aros_ext_crc;
break;
}
var data = loadRemoteSync(url);
if (typeof(data) == 'number') {
alert('Can\'t download '+url+' (http status: '+data+')');
} else {
if (data.length == size) {
//console.log(dechex(crc32(data)));
if (crc32(data) == crc) {
roms[num] = data;
return data;
} else
alert('Wrong checksum for '+url+' (is $'+dechex(crc32(data))+', should $'+dechex(crc)+')');
} else
alert('Wrong file-length for '+url+' ('+size+')');
}
return null;
}
this.loadRom = function (num) {
if (roms[num]) {
console.log('loadRom.loadRom() %d is cached', num);
return roms[num];
}
console.log('loadRom.loadRom() downloading %d', num);
var url, size, crc;
switch (num) {
case 0:
url = aros_rom_url;
size = aros_rom_size;
crc = aros_rom_crc;
break;
case 1:
url = aros_ext_url;
size = aros_ext_size;
crc = aros_ext_crc;
break;
}
var data = loadRemoteSync(url);
if (typeof(data) == 'number') {
alert('Can\'t download ' + url + ' (http status: ' + data + ')');
} else {
if (data.length == size) {
//console.log(dechex(crc32(data)));
if (crc32(data) == crc) {
roms[num] = data;
return data;
} else
alert('Wrong checksum for ' + url + ' (is $' + dechex(crc32(data)) + ', should $' + dechex(crc) + ')');
} else
alert('Wrong file-length for ' + url + ' (' + size + ')');
}
return null;
};
this.loadDisk = function(url) {
for (var i = 0; i < disks.length; i++) {
@ -230,7 +272,7 @@ function Cache() {
/*-----------------------------------------------------------------------*/
/* utils */
function dump(obj) {
/*function dump(obj) {
var out = '';
if (obj) {
for (var i in obj) {
@ -238,10 +280,7 @@ function dump(obj) {
}
}
alert(out);
/*var pre = document.createElement('pre');
pre.innerHTML = out;
document.body.appendChild(pre);*/
}
}*/
function crc32(str, crc) {
@ -289,11 +328,6 @@ function crc32(str, crc) {
return crc < 0 ? crc + 0x100000000 : crc;
}
function openNewTab(url) {
window.open(url, '_blank');
window.focus();
}
function getSelectValue(e) {
for (var i = 0; i < e.length; i++) {
if (e[i].selected) return e[i].value;
@ -329,7 +363,7 @@ function disabled(id, d) {
document.getElementById(id).disabled = d ? 'disabled' : '';
}
function toggleFullScreen() {
/*function toggleFullScreen() {
if ((document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method
(!document.mozFullScreenElement && !document.webkitFullScreenElement)) { // current working methods
if (document.documentElement.requestFullScreen) {
@ -348,40 +382,40 @@ function toggleFullScreen() {
document.webkitCancelFullScreen();
}
}
}
}*/
function loadLocalId(id, callback) {
/*function loadLocalId(id, callback) {
var e = document.getElementById(id).files[0];
var reader = new FileReader();
reader.onload = callback;
reader.readAsBinaryString(e);
}
}*/
function loadLocal(e, callback) {
var reader = new FileReader();
reader.onload = callback;
reader.readAsBinaryString(e);
}
function loadRemote(url, size, crc, callback) {
/*function loadRemote(url, size, crc, callback) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.overrideMimeType('text\/plain; charset=x-user-defined');
req.onreadystatechange = function(e) {
if (req.readyState == 4) {
if (req.status == 200) {
if (req.responseText.length == size) {
if (crc === false || crc32(req.responseText) == crc)
callback(0, req.responseText);
else
callback(1, crc32(req.responseText));
} else
callback(2, req.responseText.length);
} else
callback(3, req.status);
}
}
req.onreadystatechange = function (e) {
if (req.readyState == 4) {
if (req.status == 200) {
if (req.responseText.length == size) {
if (crc === false || crc32(req.responseText) == crc)
callback(0, req.responseText);
else
callback(1, crc32(req.responseText));
} else
callback(2, req.responseText.length);
} else
callback(3, req.status);
}
};
req.send(null);
}
}*/
function loadRemoteSync(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
@ -539,7 +573,7 @@ function getSimpleConfig() {
config.chipset.mask = SAEV_Config_Chipset_Mask_OCS;
config.chipset.agnus_dip = false; /* A1000 */
config.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None;
config.chipset.collision_level = (item !== null && item[0] == 'Deluxe Galaga 2.4') ? SAEV_Config_Chipset_ColLevel_Sprite_Playfield : SAEV_Config_Chipset_ColLevel_None;
config.blitter.immediate = (item !== null && item[8]) ? true : false;
config.blitter.waiting = config.blitter.immediate ? 0 : 1;
@ -680,6 +714,7 @@ function fireButtonName(fire) {
case 145: return 'Scroll lock';
case 49: return '1';
case 50: return '2';
default: return 'ERROR';
}
}
@ -721,8 +756,8 @@ function setConfig() {
e = document.getElementById('cfg_chipset_type');
switch (config.chipset.mask) {
case SAEV_Config_Chipset_Mask_OCS: e[0].selected = true; break
case SAEV_Config_Chipset_Mask_ECS_AGNUS: e[1].selected = true; break
case SAEV_Config_Chipset_Mask_OCS: e[0].selected = true; break;
case SAEV_Config_Chipset_Mask_ECS_AGNUS: e[1].selected = true; break;
case SAEV_Config_Chipset_Mask_ECS_DENISE: e[2].selected = true; break
}
document.getElementById('cfg_chipset_cl_enabled').checked = config.chipset.collision_level != SAEV_Config_Chipset_ColLevel_None;
@ -809,7 +844,6 @@ function setConfig() {
styleDisplayBlock('cfg_keyborad_grp', config.keyboard.enabled != 0);
document.getElementById('cfg_ports_0_enabled').checked = config.ports[0].type != SAEV_Config_Ports_Type_None;
e = document.getElementById('cfg_ports_0');
switch (config.ports[0].type) {
case SAEV_Config_Ports_Type_Mouse: document.getElementById('cfg_ports_0')[0].selected = true; break;
case SAEV_Config_Ports_Type_Joy0: document.getElementById('cfg_ports_0')[1].selected = true; break;
@ -824,8 +858,7 @@ function setConfig() {
styleDisplayInline('cfg_ports_0_grp', config.ports[0].type != SAEV_Config_Ports_Type_None);
styleDisplayInline('cfg_ports_0_grp2', config.ports[0].type == SAEV_Config_Ports_Type_Joy0);
e = document.getElementById('cfg_ports_1_enabled').checked = config.ports[1].type != SAEV_Config_Ports_Type_None;
e = document.getElementById('cfg_ports_1');
document.getElementById('cfg_ports_1_enabled').checked = config.ports[1].type != SAEV_Config_Ports_Type_None;
switch (config.ports[1].type) {
case SAEV_Config_Ports_Type_Joy1: document.getElementById('cfg_ports_1')[0].selected = true; break;
}
@ -838,7 +871,7 @@ function setConfig() {
setFireButton('cfg_ports_1_fire_2', config.ports[1].fire[1]);
styleDisplayInline('cfg_ports_1_grp', config.ports[1].type == SAEV_Config_Ports_Type_Joy1);
e = document.getElementById('cfg_serial_enabled').checked = config.serial.enabled != 0;
document.getElementById('cfg_serial_enabled').checked = config.serial.enabled != 0;
styleDisplayInline('dskchg_grp', 1);
}
@ -848,6 +881,7 @@ function getMask(type) {
case SAEV_Config_Chipset_Type_OCS: return SAEV_Config_Chipset_Mask_OCS;
case SAEV_Config_Chipset_Type_ECS_AGNUS: return SAEV_Config_Chipset_Mask_ECS_AGNUS;
case SAEV_Config_Chipset_Type_ECS_DENISE: return SAEV_Config_Chipset_Mask_ECS_DENISE;
default: return SAEV_Config_Chipset_Mask_OCS;
}
}
@ -1059,7 +1093,9 @@ function stop() {
if (paused) {
var e = document.getElementById('status_pr');
e.value = 'pause';
e.onclick = function() { pause(1); }
e.onclick = function () {
pause(1);
};
paused = false;
}
if (dskchg)
@ -1078,14 +1114,16 @@ function stop() {
document.body.style.backgroundColor = '#fff';
}
function reset(p) {
function reset() {
SAE({cmd:'reset'});
}
function pause(p) {
var e = document.getElementById('status_pr');
e.innerHTML = p ? 'Resume' : 'Pause';
e.onclick = function() { pause(1 - p); }
e.onclick = function () {
pause(1 - p);
};
paused = p;
@ -1203,7 +1241,8 @@ function romAROS() {
document.getElementById('cfg_ext_addr')[0].selected = true;
styleDisplayInline('cfg_ext_remove', 1);
styleDisplayTableRow('cfg_ext_addr_grp', 1);
disabled('cfg_rom_aros', 0);
disabled('cfg_rom_aros', 0);
return true;
}
function romSelect() {
@ -1273,7 +1312,7 @@ function floppyUpdate(n) {
function floppyInsert(n) {
var e = document.getElementById('cfg_df'+n+'_file').files[0];
var ok = false;
var ok = true; //false;
if (!e) return;
/*if (e.size == 0xDC000) {
@ -1290,7 +1329,7 @@ function floppyInsert(n) {
} else
alert('Invalid diskimage-size, 880 or 1460 kb.');
*/
ok = true;
if (ok)
loadLocal(e, function (event) {
config.floppy.drive[n].name = e.name;
@ -1435,7 +1474,7 @@ function dskchgInsert() {
if (!dskchg) return;
var n = getSelectValue(document.getElementById('cfg_dskchg_unit'));
var e = document.getElementById('cfg_dskchg_file').files[0];
var ok = false;
var ok = true; //false;
if (!e) return;
/*if (e.size == 0xDC000) {
@ -1450,8 +1489,7 @@ function dskchgInsert() {
alert('DF'+n+' is configured as DD-drive (880kb), but you selected a HD-diskimage (1760kb).');
} else
alert('Invalid diskimage-size, 880 or 1460 kb.');
*/
ok = true;
*/
if (ok) {
loadLocal(e, function (event) {
dskchgClose();

View file

@ -5,12 +5,6 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="icon" type="image/x-icon" href="http://scriptedamigaemulator.net/favicon.ico" />
<link rel="stylesheet" type="text/css" href="index.css" />
<script type="text/javascript">
function openNewTab(url) {
window.open(url, '_blank');
window.focus();
}
</script>
</head>
<body>
<div class="head">
@ -101,39 +95,39 @@
<ul>
<li><span class="fwb">Written and ported by</span>
<ul>
<li>Rupert Hausberger &lt;<a href="mailto:rupert_hausberger@gmx.net">rupert_hausberger@gmx.net</a>&gt; (<a href="javascript:openNewTab('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; (<a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=ZJA3YVT6EP55A">donate</a>)</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Source-code</span>
<ul>
<li><a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">github.com/naTmeg/ScriptedAmigaEmulator</a></li>
<li><a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">github.com/naTmeg/ScriptedAmigaEmulator</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">License</span>
<ul>
<li><a href="javascript:openNewTab('gpl.htm')">GPL</a></li>
<li><a target="_blank" href="gpl.htm">GPL</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Thanks</span>
<ul>
<li><a href="javascript:openNewTab('http://www.amigaemulator.org')">Bernd Schmidt</a></li>
<li><a href="javascript:openNewTab('http://winuae.net')">WinUAE team</a></li>
<li><a href="javascript:openNewTab('http://aros.org')">AROS team</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://aros.org">AROS team</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Some stats</span>
<ul>
<li>The first public version had ~13.000 lines of code, currently ~23.500</li>
<li>About 5 months development time for the first version.</li>
<li>About the half of the first version was written from scratch, the rest was ported from WinUAE.</li>
<li>About 5 months development time for the first public version. (0.5)</li>
<li>About the half of the first version was written from scratch, the rest was ported from various UAE-sources.</li>
<li>The first version had ~13.000 lines of code, currently ~23.500, most new code is ported from WinUAE.</li>
</ul>
</li>
</ul>
@ -284,7 +278,7 @@
<ul>
<li>Chaned the project-name from 'Janus' to 'SAE' (Scripted Amiga Emulator).<br />
This step is necessary because i did'nt enough research before the initial release.<br />
There is already a project with that name in it. (<a href="javascript:openNewTab('http://janus-uae.sourceforge.net')">janus-uae</a>)
There is already a project with that name in it. (<a target="_blank" href="http://janus-uae.sourceforge.net">janus-uae</a>)
I'm sorry for that, that was kinda stupid :)</li>
<li>Separated the GUI form the core and rewrote most of it.</li>
<li>Simplified the whole code. This means, that functions are called faster.</li>

View file

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

File diff suppressed because it is too large Load diff

View file

@ -52,8 +52,8 @@ function Blitter() {
[0 ] /* F */
];
const blit_cycle_diagram_line = [4, 0,3,5,4, 0,3,5,4];
const blit_cycle_diagram_finald = [2, 0,4, 0,4];
const blit_cycle_diagram_finalld = [2, 0,0, 0,0];
//const blit_cycle_diagram_finald = [2, 0,4, 0,4];
//const blit_cycle_diagram_finalld = [2, 0,0, 0,0];
var blit_filltable = [];
var blit_masktable = [];
@ -84,8 +84,7 @@ function Blitter() {
var blinea = 0, blineb = 0;
var blitline = 0, blitfc = 0, blitfill = 0, blitife = 0, blitsing = 0, blitdesc = 0;
var blitonedot = 0, blitsign = 0, blitlinepixel = 0;
var ddat1 = 0, ddat2 = 0;
var ddat1use = 0, ddat2use = 0;
var last_blitter_hpos = 0;
@ -101,7 +100,7 @@ function Blitter() {
//function build_blitfilltable()
{
var blit_masktable = new Uint16Array(BLITTER_MAX_WORDS);
blit_masktable = new Uint16Array(BLITTER_MAX_WORDS);
for (var i = 0; i < BLITTER_MAX_WORDS; i++)
blit_masktable[i] = 0xffff;
@ -130,18 +129,18 @@ function Blitter() {
/*---------------------------------*/
this.reset = function() {
bltstate = BLT_done;
blit_interrupt = true;
blit_stuck = 0;
}
this.reset = function () {
bltstate = BLT_done;
blit_interrupt = true;
blit_stuck = 0;
};
function blitter_dump() {
/*function blitter_dump() {
BUG.info('PT A=%08X B=%08X C=%08X D=%08X', bltapt, bltbpt, bltcpt, bltdpt);
BUG.info('CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X', bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat);
//BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff);
BUG.info('AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X', blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod, blt_info.bltbmod, blt_info.bltcmod, blt_info.bltdmod);
}
}*/
function castWord(v) {
return (v & 0x8000) ? (v - 0x10000) : v;
@ -167,7 +166,7 @@ function Blitter() {
return diag[1 + diag[0] + cycles];
}
function channel_pos(cycles) {
/*function channel_pos(cycles) {
if (cycles < 0)
return 0;
var diag = get_ch();
@ -176,7 +175,7 @@ function Blitter() {
cycles -= diag[0];
cycles %= diag[0];
return cycles;
}
}*/
function blitter_interrupt() {
if (blit_interrupt)
@ -2012,6 +2011,7 @@ function Blitter() {
case 0xfd: return (~c) | (b) | (a);
case 0xfe: return (c) | (b) | (a);
case 0xff: return 0xffff;
default: return 0;
}
}
@ -2217,7 +2217,7 @@ function Blitter() {
if (bltcon0 & 0x200) {
if (AMIGA.dmaen(DMAF_BLTEN))
//blt_info.bltcdat = AMIGA.mem.load16_chip(bltcpt);
blt_info.bltcdat = dat = AMIGA.mem.chip.data[bltcpt >>> 1];
blt_info.bltcdat = AMIGA.mem.chip.data[bltcpt >>> 1];
}
bltstate = BLT_work;
}
@ -2382,7 +2382,7 @@ function Blitter() {
if (blt_info.vblitsize <= 0)
bltstate = BLT_done;
} while (bltstate != BLT_done);
bltapt_line = null;
//bltapt_line = null;
bltdpt = bltcpt;
} else {
if (blitdesc)
@ -2400,26 +2400,26 @@ function Blitter() {
/*---------------------------------*/
this.handler = function(data) {
if (!AMIGA.dmaen(DMAF_BLTEN)) {
AMIGA.events.newevent(EV2_BLITTER, 10, 0);
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
return;
this.handler = function (data) {
if (!AMIGA.dmaen(DMAF_BLTEN)) {
AMIGA.events.newevent(EV2_BLITTER, 10, 0);
if (++blit_stuck < 20000 || !AMIGA.config.blitter.immediate)
return;
BUG.info('blitter_handler() force-unstuck!');
}
blit_stuck = 0;
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
//console.log('Blitter.handler () slowdown', blit_slowdown);
AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
blit_slowdown = -1;
return;
}
blitter_do();
}
BUG.info('blitter_handler() force-unstuck!');
}
blit_stuck = 0;
if (blit_slowdown > 0 && !AMIGA.config.blitter.immediate) {
//console.log('Blitter.handler () slowdown', blit_slowdown);
AMIGA.events.newevent(EV2_BLITTER, blit_slowdown, 0);
blit_slowdown = -1;
return;
}
blitter_do();
};
var changetable = new Uint8Array(32 * 32); for (var i = 0; i < changetable.length; i++) changetable[i] = 0;
var freezes = 10;
//var freezes = 10;
function blit_bltset(con) {
if (con & 2) {
blitdesc = bltcon1 & 2;
@ -2518,9 +2518,8 @@ function Blitter() {
warned1--;
BUG.info('waiting_blits detected');
}
if (bltstate == BLT_done)
return true;
return false;
return bltstate == BLT_done;
}
function do_blitter(hpos, copper) {
@ -2533,17 +2532,12 @@ function Blitter() {
cleanstart = 1;
}
bltstate = BLT_done;
blt_info.blitzero = 1;
preva = 0;
prevb = 0;
blt_info.got_cycle = 0;
blit_firstline_cycles = blit_first_cycle = AMIGA.events.currcycle;
blit_last_cycle = 0;
last_blitter_hpos = hpos + 1;
blit_cyclecounter = 0;
blit_bltset(1 | 2);
ddat1use = ddat2use = 0;
@ -2615,164 +2609,228 @@ function Blitter() {
}
var warned2 = 10;
this.maybe_blit = function(hpos, hack) {
if (bltstate == BLT_done)
return;
this.maybe_blit = function (hpos, hack) {
if (bltstate == BLT_done)
return;
if (AMIGA.dmaen(DMAF_BLTEN)) {
var doit = false;
if (AMIGA.config.blitter.waiting == 3) { // always
doit = true;
} else if (AMIGA.config.blitter.waiting == 2) { // no idle
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true;
} else if (AMIGA.config.blitter.waiting == 1) { // automatic
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true;
else if (AMIGA.config.cpu.speed < 0)
doit = true;
}
if (doit) {
if (waitingblits())
return;
}
}
if (AMIGA.dmaen(DMAF_BLTEN)) {
var doit = false;
if (AMIGA.config.blitter.waiting == 3) { // always
doit = true;
} else if (AMIGA.config.blitter.waiting == 2) { // no idle
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true;
} else if (AMIGA.config.blitter.waiting == 1) { // automatic
if (blit_dmacount == blit_diag[0] && (AMIGA.spcflags & SPCFLAG_BLTNASTY))
doit = true;
else if (AMIGA.config.cpu.speed < 0)
doit = true;
}
if (doit) {
if (waitingblits())
return;
}
}
if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) {
warned2--;
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
}
if (warned2 && AMIGA.dmaen(DMAF_BLTEN) && blt_info.got_cycle) {
warned2--;
BUG.info('maybe_blit() program does not wait for blitter tc=%d', blit_cyclecounter);
}
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
return;
if (hack == 1 && AMIGA.events.currcycle < blit_firstline_cycles)
return;
AMIGA.blitter.handler(0);
}
AMIGA.blitter.handler(0);
};
this.blitnasty = function() {
if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
return 0;
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
return 0;
this.blitnasty = function () {
if (bltstate == BLT_done || !AMIGA.dmaen(DMAF_BLTEN))
return 0;
if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[0])
return 0;
var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
var ccnt = 0;
while (blit_last_cycle < cycles) {
if (!channel_state(blit_last_cycle++))
ccnt++;
}
return ccnt;
}
var cycles = Math.floor((AMIGA.events.currcycle - blit_first_cycle) * CYCLE_UNIT_INV);
var ccnt = 0;
while (blit_last_cycle < cycles) {
if (!channel_state(blit_last_cycle++))
ccnt++;
}
return ccnt;
};
/*---------------------------------*/
var oddfstrt = 0, oddfstop = 0, ototal = 0, ofree = 0, slow = 0;
this.slowdown = function() {
var data = AMIGA.playfield.getData();
var ddfstrt = data[0];
var ddfstop = data[1];
var totalcycles = data[2];
var freecycles = data[3];
this.slowdown = function () {
var data = AMIGA.playfield.getData();
var ddfstrt = data[0];
var ddfstop = data[1];
var totalcycles = data[2];
var freecycles = data[3];
if (!totalcycles || ddfstrt < 0 || ddfstop < 0)
return;
if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) {
var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles);
var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles);
var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]);
oddfstrt = ddfstrt;
oddfstop = ddfstop;
ototal = totalcycles;
ofree = freecycles;
slow = 0;
if (dmacycles > freelinecycles)
slow = dmacycles - freelinecycles;
}
if (blit_slowdown < 0 || blitline)
return;
blit_slowdown += slow;
}
if (!totalcycles || ddfstrt < 0 || ddfstop < 0)
return;
if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) {
var linecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles);
var freelinecycles = Math.floor(((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles);
var dmacycles = Math.floor((linecycles * blit_dmacount) / blit_diag[0]);
oddfstrt = ddfstrt;
oddfstop = ddfstop;
ototal = totalcycles;
ofree = freecycles;
slow = 0;
if (dmacycles > freelinecycles)
slow = dmacycles - freelinecycles;
}
if (blit_slowdown < 0 || blitline)
return;
blit_slowdown += slow;
};
/*---------------------------------*/
this.BLTADAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltadat = v; }
this.BLTBDAT = function(hpos, v) {
this.maybe_blit(hpos, 0);
if (bltcon1 & 2)
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
else
blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff;
this.BLTADAT = function (hpos, v) {
this.maybe_blit(hpos, 0);
blt_info.bltadat = v;
};
this.BLTBDAT = function (hpos, v) {
this.maybe_blit(hpos, 0);
if (bltcon1 & 2)
blt_info.bltbhold = (v << (bltcon1 >> 12)) & 0xffff;
else
blt_info.bltbhold = (v >> (bltcon1 >> 12)) & 0xffff;
blt_info.bltbdat = v;
}
this.BLTCDAT = function(hpos, v) { this.maybe_blit(hpos, 0); blt_info.bltcdat = v; reset_blit(0); }
blt_info.bltbdat = v;
};
this.BLTCDAT = function (hpos, v) {
this.maybe_blit(hpos, 0);
blt_info.bltcdat = v;
reset_blit(0);
};
this.BLTAMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltamod = castWord(v & 0xfffe); reset_blit(0); }
this.BLTBMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltbmod = castWord(v & 0xfffe); reset_blit(0); }
this.BLTCMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltcmod = castWord(v & 0xfffe); reset_blit(0); }
this.BLTDMOD = function(hpos, v) { this.maybe_blit(hpos, 1); blt_info.bltdmod = castWord(v & 0xfffe); reset_blit(0); }
this.BLTAMOD = function (hpos, v) {
this.maybe_blit(hpos, 1);
blt_info.bltamod = castWord(v & 0xfffe);
reset_blit(0);
};
this.BLTBMOD = function (hpos, v) {
this.maybe_blit(hpos, 1);
blt_info.bltbmod = castWord(v & 0xfffe);
reset_blit(0);
};
this.BLTCMOD = function (hpos, v) {
this.maybe_blit(hpos, 1);
blt_info.bltcmod = castWord(v & 0xfffe);
reset_blit(0);
};
this.BLTDMOD = function (hpos, v) {
this.maybe_blit(hpos, 1);
blt_info.bltdmod = castWord(v & 0xfffe);
reset_blit(0);
};
this.BLTCON0 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon0 = v; reset_blit(1); }
this.BLTCON0L = function( hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
reset_blit(1);
}
this.BLTCON1 = function(hpos, v) { this.maybe_blit(hpos, 2); bltcon1 = v; reset_blit(2); }
this.BLTCON0 = function (hpos, v) {
this.maybe_blit(hpos, 2);
bltcon0 = v;
reset_blit(1);
};
this.BLTCON0L = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 2);
bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF);
reset_blit(1);
};
this.BLTCON1 = function (hpos, v) {
this.maybe_blit(hpos, 2);
bltcon1 = v;
reset_blit(2);
};
this.BLTAFWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltafwm = v; reset_blit(0); }
this.BLTALWM = function(hpos, v) { this.maybe_blit(hpos, 2); blt_info.bltalwm = v; reset_blit(0); }
this.BLTAFWM = function (hpos, v) {
this.maybe_blit(hpos, 2);
blt_info.bltafwm = v;
reset_blit(0);
};
this.BLTALWM = function (hpos, v) {
this.maybe_blit(hpos, 2);
blt_info.bltalwm = v;
reset_blit(0);
};
this.BLTAPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0; }
this.BLTAPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0; }
this.BLTBPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0; }
this.BLTBPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
this.BLTCPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0; }
this.BLTCPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
this.BLTDPTH = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0; }
this.BLTDPTL = function(hpos, v) { this.maybe_blit(hpos, 0); bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0; }
this.BLTAPTH = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltapt = ((bltapt & 0xffff) | (v << 16)) >>> 0;
};
this.BLTAPTL = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltapt = ((bltapt & ~0xffff) | (v & 0xfffe)) >>> 0;
};
this.BLTBPTH = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltbpt = ((bltbpt & 0xffff) | (v << 16)) >>> 0;
};
this.BLTBPTL = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltbpt = ((bltbpt & ~0xffff) | (v & 0xfffe)) >>> 0;
};
this.BLTCPTH = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltcpt = ((bltcpt & 0xffff) | (v << 16)) >>> 0;
};
this.BLTCPTL = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltcpt = ((bltcpt & ~0xffff) | (v & 0xfffe)) >>> 0;
};
this.BLTDPTH = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltdpt = ((bltdpt & 0xffff) | (v << 16)) >>> 0;
};
this.BLTDPTL = function (hpos, v) {
this.maybe_blit(hpos, 0);
bltdpt = ((bltdpt & ~0xffff) | (v & 0xfffe)) >>> 0;
};
this.BLTSIZE = function(hpos, v) {
this.maybe_blit(hpos, 0);
this.BLTSIZE = function (hpos, v) {
this.maybe_blit(hpos, 0);
blt_info.vblitsize = v >> 6;
blt_info.hblitsize = v & 0x3F;
if (!blt_info.vblitsize)
blt_info.vblitsize = 1024;
if (!blt_info.hblitsize)
blt_info.hblitsize = 64;
do_blitter(hpos, AMIGA.copper.access);
}
blt_info.vblitsize = v >> 6;
blt_info.hblitsize = v & 0x3F;
if (!blt_info.vblitsize)
blt_info.vblitsize = 1024;
if (!blt_info.hblitsize)
blt_info.hblitsize = 64;
this.BLTSIZV = function(hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0);
blt_info.vblitsize = v & 0x7FFF;
}
do_blitter(hpos, AMIGA.copper.access);
};
this.BLTSIZH = function(hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0);
blt_info.hblitsize = v & 0x7FF;
if (!blt_info.vblitsize)
blt_info.vblitsize = 0x8000;
if (!blt_info.hblitsize)
blt_info.hblitsize = 0x0800;
do_blitter(hpos, AMIGA.copper.access);
}
this.BLTSIZV = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0);
blt_info.vblitsize = v & 0x7FFF;
};
this.BLTSIZH = function (hpos, v) {
if (!(AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)) return;
this.maybe_blit(hpos, 0);
blt_info.hblitsize = v & 0x7FF;
if (!blt_info.vblitsize)
blt_info.vblitsize = 0x8000;
if (!blt_info.hblitsize)
blt_info.hblitsize = 0x0800;
do_blitter(hpos, AMIGA.copper.access);
};
/*---------------------------------*/
this.getState = function() {
return bltstate;
}
this.setState = function(s) {
bltstate = s;
}
this.getState = function () {
return bltstate;
};
this.setState = function (s) {
bltstate = s;
};
this.getIntZero = function() {
return [blit_interrupt, blt_info.blitzero];
}

View file

@ -11,13 +11,13 @@
*
**************************************************************************/
const CIAA_DEBUG_R = 0;
/*const CIAA_DEBUG_R = 0;
const CIAA_DEBUG_W = 0;
const CIAB_DEBUG_R = 0;
const CIAB_DEBUG_W = 0;
const DONGLE_DEBUG = 0;
const KB_DEBUG = 0;
const CLOCK_DEBUG = 0;
const CLOCK_DEBUG = 0;*/
const TOD_HACK = 1;
@ -54,7 +54,7 @@ function CIA() {
var div10 = 0;
//var kbstate = 0, kblostsynccnt = 0, kbcode = 0;
var serbits = 0;
//var serbits = 0;
var warned = 10;
//var rtc_delayed_write = 0;
@ -101,23 +101,23 @@ function CIA() {
}
}
this.SetICRA = function(icr, sdr) {
ciaaicr |= icr;
ciaasdr = sdr;
RethinkICRA();
}
this.SetICRA = function (icr, sdr) {
ciaaicr |= icr;
ciaasdr = sdr;
RethinkICRA();
};
this.SetICRB = function(icr, sdr) {
ciabicr |= icr;
if (sdr !== null)
ciabsdr = sdr;
RethinkICRB();
}
this.SetICRB = function (icr, sdr) {
ciabicr |= icr;
if (sdr !== null)
ciabsdr = sdr;
RethinkICRB();
};
this.rethink = function() {
RethinkICRA();
RethinkICRB();
}
this.rethink = function () {
RethinkICRA();
RethinkICRB();
};
/* Figure out how many CIA timer cycles have passed for each timer since the last call of CIA_calctimers. */
function compute_passed_time() {
@ -343,10 +343,10 @@ function CIA() {
AMIGA.events.schedule();
}
this.handler = function() {
CIA_update();
CIA_calctimers();
}
this.handler = function () {
CIA_update();
CIA_calctimers();
};
/*this.diskindex = function() {
ciabicr |= 0x10;
@ -476,41 +476,41 @@ function CIA() {
//this.hsync_prehandler = function() {}
this.hsync_posthandler = function(dotod) {
if (ciabtodon && dotod) {
ciabtod++;
ciabtod &= 0xFFFFFF;
ciab_checkalarm(1);
}
if (AMIGA.config.cia.tod_hack && ciaatodon)
do_tod_hack(dotod);
this.hsync_posthandler = function (dotod) {
if (ciabtodon && dotod) {
ciabtod++;
ciabtod &= 0xFFFFFF;
ciab_checkalarm(1);
}
if (AMIGA.config.cia.tod_hack && ciaatodon)
do_tod_hack(dotod);
/*if (resetwarning_phase) {
resetwarning_check ();
while (keys_available ())
get_next_key ();
} else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
switch (kbstate) {
case 0:
kbcode = 0;
kbstate++;
break;
case 1:
setcode(AK_INIT_POWERUP);
kbstate++;
break;
case 2:
setcode(AK_TERM_POWERUP);
kbstate++;
break;
case 3:
kbcode = ~get_next_key();
break;
}
keyreq();
}*/
AMIGA.input.keyboard.hsync();
}
/*if (resetwarning_phase) {
resetwarning_check ();
while (keys_available ())
get_next_key ();
} else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
switch (kbstate) {
case 0:
kbcode = 0;
kbstate++;
break;
case 1:
setcode(AK_INIT_POWERUP);
kbstate++;
break;
case 2:
setcode(AK_TERM_POWERUP);
kbstate++;
break;
case 3:
kbcode = ~get_next_key();
break;
}
keyreq();
}*/
AMIGA.input.keyboard.hsync();
};
function calc_led(old_led) {
var c = AMIGA.events.currcycle;
@ -560,43 +560,43 @@ function CIA() {
led_cycles_off = 0;
}
this.vsync_prehandler = function() {
/*if (rtc_delayed_write < 0) {
rtc_delayed_write = 50;
} else if (rtc_delayed_write > 0) {
rtc_delayed_write--;
if (rtc_delayed_write == 0)
write_battclock ();
}*/
led_vsync();
this.handler();
/*if (kblostsynccnt > 0) {
kblostsynccnt -= maxvpos;
if (kblostsynccnt <= 0) {
kblostsynccnt = 0;
keyreq ();
write_log (_T('lostsync\n'));
}
}*/
AMIGA.input.keyboard.vsync();
}
this.vsync_prehandler = function () {
/*if (rtc_delayed_write < 0) {
rtc_delayed_write = 50;
} else if (rtc_delayed_write > 0) {
rtc_delayed_write--;
if (rtc_delayed_write == 0)
write_battclock ();
}*/
led_vsync();
this.handler();
/*if (kblostsynccnt > 0) {
kblostsynccnt -= maxvpos;
if (kblostsynccnt <= 0) {
kblostsynccnt = 0;
keyreq ();
write_log (_T('lostsync\n'));
}
}*/
AMIGA.input.keyboard.vsync();
};
this.vsync_posthandler = function(dotod) {
//if (heartbeat_cnt > 0) heartbeat_cnt--;
if (TOD_HACK) {
if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1)
return;
}
if (ciaatodon && dotod) {
ciaatod++;
ciaatod &= 0xFFFFFF;
ciaa_checkalarm (1);
}
/*if (vpos == 0) {
write_log ('%d', vsync_counter);
this.dump();
}*/
}
this.vsync_posthandler = function (dotod) {
//if (heartbeat_cnt > 0) heartbeat_cnt--;
if (TOD_HACK) {
if (AMIGA.config.cia.tod_hack && tod_hack_enabled == 1)
return;
}
if (ciaatodon && dotod) {
ciaatod++;
ciaatod &= 0xFFFFFF;
ciaa_checkalarm(1);
}
/*if (vpos == 0) {
write_log ('%d', vsync_counter);
this.dump();
}*/
};
function bfe001_change() {
var v = ciaapra;
@ -782,7 +782,7 @@ function CIA() {
}
return tmp;
case 1:
if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0));
//if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD100 R %02X %s\n'), ciabprb, debuginfo(0));
tmp = ciabprb;
//tmp = dongle_cia_read(1, reg, tmp);
if (ciabcrb & 2) {
@ -790,14 +790,14 @@ function CIA() {
if (ciabcrb & 4)
pb7 = ciabcrb & 1;
tmp &= ~0x80;
tmp |= pb7 ? 0x80 : 00;
tmp |= pb7 ? 0x80 : 0;
}
if (ciabcra & 2) {
var pb6 = 0;
if (ciabcra & 4)
pb6 = ciabcra & 1;
tmp &= ~0x40;
tmp |= pb6 ? 0x40 : 00;
tmp |= pb6 ? 0x40 : 0;
}
return tmp;
case 2:
@ -993,7 +993,7 @@ function CIA() {
//if ((addr >= 8 && addr <= 10) || CIAB_DEBUG_W > 1) write_log (_T('W_CIAB: bfd%x00 %02X %08X\n'), reg, val, M68K_GETPC);
switch (reg) {
case 0:
if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0));
//if (DONGLE_DEBUG && notinrom()) write_log (_T('BFD000 W %02X %s\n'), val, debuginfo(0));
//dongle_cia_write (1, reg, val);
ciabpra = val;
//if (currprefs.use_serial)
@ -1117,52 +1117,59 @@ function CIA() {
}
}
this.setup = function() {}
this.setup = function () {
};
this.reset = function() {
if (TOD_HACK) {
tod_hack_tv = 0;
tod_hack_tod = 0;
tod_hack_enabled = 0;
if (AMIGA.config.cia.tod_hack)
tod_hack_enabled = TOD_HACK_TIME;
}
//kblostsynccnt = 0;
//serbits = 0;
//oldcd32mute = 1;
oldled = true;
//resetwarning_phase = resetwarning_timer = 0;
//heartbeat_cnt = 0;
this.reset = function () {
if (TOD_HACK) {
tod_hack_tv = 0;
tod_hack_tod = 0;
tod_hack_enabled = 0;
if (AMIGA.config.cia.tod_hack)
tod_hack_enabled = TOD_HACK_TIME;
}
//kblostsynccnt = 0;
//serbits = 0;
//oldcd32mute = 1;
oldled = true;
//resetwarning_phase = resetwarning_timer = 0;
//heartbeat_cnt = 0;
//oldovl = true;
//kbstate = 0;
ciaatlatch = ciabtlatch = 0;
ciaapra = 0; ciaadra = 0;
ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
ciaaalarm = ciabalarm = 0;
ciabpra = 0x8C; ciabdra = 0;
div10 = 0;
ciaasdr_cnt = 0; ciaasdr = 0;
ciabsdr_cnt = 0; ciabsdr = 0;
ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
CIA_calctimers();
AMIGA.disk.select_set(ciabprb);
//oldovl = true;
//kbstate = 0;
ciaatlatch = ciabtlatch = 0;
ciaapra = 0;
ciaadra = 0;
ciaatod = ciabtod = 0;
ciaatodon = ciabtodon = 0;
ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4;
/* outmode = toggle; */
ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
ciaaalarm = ciabalarm = 0;
ciabpra = 0x8C;
ciabdra = 0;
div10 = 0;
ciaasdr_cnt = 0;
ciaasdr = 0;
ciabsdr_cnt = 0;
ciabsdr = 0;
ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
//map_overlay (0);
//if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */
}
CIA_calctimers();
AMIGA.disk.select_set(ciabprb);
this.dump = function() {
BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV);
BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV);
}
//map_overlay (0);
//if (currprefs.use_serial) serial_dtr_off (); NI /* Drop DTR at reset */
};
this.dump = function () {
BUG.info('A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CYC=%.1f', ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', AMIGA.events.currcycle * CYCLE_UNIT_INV);
BUG.info('B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)', ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
BUG.info('TOD %06x (%06x) ALARM %06x %s%s CLK=%.1f', ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 * CYCLE_UNIT_INV);
};
// Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected
// Old Gary based Amigas enable both CIAs in this situation
@ -1203,115 +1210,117 @@ function CIA() {
return mask == 0xe000 || mask == 0xd000;
}
this.load8 = function(addr) {
var r = (addr & 0xf00) >> 8;
var v = 0xff;
this.load8 = function (addr) {
var r = (addr & 0xf00) >> 8;
var v = 0xff;
if (!isgaylenocia(addr))
return v;
if (!isgaylenocia(addr))
return v;
cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
if (!issinglecia())
v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
break;
case 1:
v = (addr & 1) ? 0xff : ReadCIAB(r);
break;
case 2:
v = (addr & 1) ? ReadCIAA(r) : 0xff;
break;
case 3: {
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
if (warned > 0) {
BUG.info('cia_bget: unknown CIA address %x', addr);
warned--;
}
break;
}
}
cia_wait_post(v);
return v;
}
cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
if (!issinglecia())
v = (addr & 1) ? ReadCIAA(r) : ReadCIAB(r);
break;
case 1:
v = (addr & 1) ? 0xff : ReadCIAB(r);
break;
case 2:
v = (addr & 1) ? ReadCIAA(r) : 0xff;
break;
case 3:
{
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8;
if (warned > 0) {
BUG.info('cia_bget: unknown CIA address %x', addr);
warned--;
}
break;
}
}
cia_wait_post(v);
return v;
};
this.load16 = function(addr) {
var r = (addr & 0xf00) >> 8;
var v = 0xffff;
this.load16 = function (addr) {
var r = (addr & 0xf00) >> 8;
var v = 0xffff;
if (!isgaylenocia(addr))
return v;
if (!isgaylenocia(addr))
return v;
cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
if (!issinglecia())
v = (ReadCIAB(r) << 8) | ReadCIAA(r);
break;
case 1:
v = (ReadCIAB(r) << 8) | 0xff;
break;
case 2:
v = (0xff << 8) | ReadCIAA(r);
break;
case 3: {
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
if (warned > 0) {
BUG.info('cia_wget: unknown CIA address %x', addr);
warned--;
}
break;
}
}
cia_wait_post(v);
return v;
}
cia_wait_pre();
switch ((addr >> 12) & 3) {
case 0:
if (!issinglecia())
v = (ReadCIAB(r) << 8) | ReadCIAA(r);
break;
case 1:
v = (ReadCIAB(r) << 8) | 0xff;
break;
case 2:
v = (0xff << 8) | ReadCIAA(r);
break;
case 3:
{
//if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) v = regs.irc;
if (warned > 0) {
BUG.info('cia_wget: unknown CIA address %x', addr);
warned--;
}
break;
}
}
cia_wait_post(v);
return v;
};
this.load32 = function(addr) {
var v = this.load16(addr) << 16;
v |= this.load16(addr + 2);
return v >>> 0;
}
this.load32 = function (addr) {
var v = this.load16(addr) << 16;
v |= this.load16(addr + 2);
return v >>> 0;
};
this.store8 = function (addr, value) {
var r = (addr & 0xf00) >> 8;
var r = (addr & 0xf00) >> 8;
if (!isgaylenocia(addr))
return;
if (!isgaylenocia(addr))
return;
cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0)
WriteCIAB(r, value);
if ((addr & 0x1000) == 0)
WriteCIAA(r, value);
if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_bput: unknown CIA address %x %x', addr, value);
warned--;
}
}
cia_wait_post(value);
}
cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0)
WriteCIAB(r, value);
if ((addr & 0x1000) == 0)
WriteCIAA(r, value);
if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_bput: unknown CIA address %x %x', addr, value);
warned--;
}
}
cia_wait_post(value);
};
this.store16 = function (addr, value) {
var r = (addr & 0xf00) >> 8;
var r = (addr & 0xf00) >> 8;
if (!isgaylenocia(addr))
return;
if (!isgaylenocia(addr))
return;
cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0)
WriteCIAB(r, value >> 8);
if ((addr & 0x1000) == 0)
WriteCIAA(r, value & 0xff);
if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_wput: unknown CIA address %x %x', addr, value);
warned--;
}
}
cia_wait_post(value);
}
cia_wait_pre();
if (!issinglecia() || (addr & 0x3000) != 0) {
if ((addr & 0x2000) == 0)
WriteCIAB(r, value >> 8);
if ((addr & 0x1000) == 0)
WriteCIAA(r, value & 0xff);
if (((addr & 0x3000) == 0x3000) && warned > 0) {
BUG.info('cia_wput: unknown CIA address %x %x', addr, value);
warned--;
}
}
cia_wait_post(value);
};
this.store32 = function (addr, value) {
this.store16(addr, value >> 16);

View file

@ -34,11 +34,11 @@ function Config() {
size: 0
},
slow: {
size: 0,
},
size: 0
},
fast: {
size: 0,
}
size: 0
}
};
this.rom = {
size: 0,
@ -177,7 +177,7 @@ function Config() {
c.video.scanlines = 0 ? true : false;
c.video.extrawidth = 0;
c.video.xcenter = 0;
c.video.ycenter = 0
c.video.ycenter = 0;
c.audio.enabled = true;
//c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
@ -203,11 +203,16 @@ function Config() {
c.cia.tod = 0;
c.cia.tod_hack = true;
c.hooks.error = function(err, msg) {}
c.hooks.power_led = function(on) {}
c.hooks.floppy_motor = function(unit, on) {}
c.hooks.floppy_step = function(unit, cyl) {}
c.hooks.fps = function(fps) {}
c.hooks.error = function (err, msg) {
};
c.hooks.power_led = function (on) {
};
c.hooks.floppy_motor = function (unit, on) {
};
c.hooks.floppy_step = function (unit, cyl) {
};
c.hooks.fps = function (fps) {
};
c.hooks.cpu = function(usage) {}
}
configSetDefaults(this);

View file

@ -10,20 +10,14 @@
const SAEV_Version = 0;
const SAEV_Revision = 8;
const SAEV_Revision_Sub = 0;
/*-----------------------------------------------------------------------*/
const SAEV_Null = null;
const SAEV_True = true;
const SAEV_False = false;
const SAEV_Revision_Sub = 1;
/*-----------------------------------------------------------------------*/
/* info */
const SAEI_Audio_Webkit = 1;
const SAEI_Audio_Mozilla = 2;
const SAEI_Audio_Default = 1;
const SAEI_Audio_Webkit = 2;
const SAEI_Audio_Mozilla = 4;
const SAEI_Video_Canvas2D = 1;
const SAEI_Video_WebGL = 2;
@ -83,7 +77,7 @@ const SAEV_Config_EXT_Size_None = 0;
const SAEV_Config_EXT_Size_256K = 1;
const SAEV_Config_EXT_Size_512K = 2;
const SAEV_Config_EXT_Addr_A0 = 1;
//const SAEV_Config_EXT_Addr_A0 = 1;
const SAEV_Config_EXT_Addr_E0 = 2;
const SAEV_Config_EXT_Addr_F0 = 3;
@ -138,7 +132,7 @@ const SAEV_Config_RTC_Type_RF5C01A = 2;
/*-----------------------------------------------------------------------*/
/* erros */
const SAEE_None = 0;
//const SAEE_None = 0;
const SAEE_CPU_Internal = 1;
const SAEE_CPU_68020_Required = 2;
@ -148,32 +142,25 @@ const SAEE_Disk_File_Too_Big = 3;
const SAEE_Video_Shader_Error = 4;
const SAEE_Video_ID_Not_Found = 5;
const SAEE_Video_Canvas_Not_Supported = 6;
const SAEE_Video_WebGL_Not_Avail = 7;
//const SAEE_Video_WebGL_Not_Avail = 7;
const SAEE_Audio_WebAudio_Not_Avail = 8;
/*-----------------------------------------------------------------------*/
/* methods */
const SAEM_Init = 1;
/*const SAEM_Init = 1;
const SAEM_Start = 2;
const SAEM_Stop = 3;
const SAEM_Pause = 4;
const SAEM_Reset = 5;
const SAEM_Insert = 6;
const SAEM_Eject = 7;
const SAEM_Eject = 7;*/
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* debug */
var BUG = null;
/*-----------------------------------------------------------------------*/
/* amiga */
var AMIGA = null;
const ST_STOP = 0;
const ST_CYCLE = 1;
const ST_PAUSE = 2;
@ -251,8 +238,6 @@ const DMAF_BZERO = 1 << 13;
const DMAF_BBUSY = 1 << 14;
const DMAF_SETCLR = 1 << 15;
const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT;
/*-----------------------------------------------------------------------*/
/* blitter */
@ -301,7 +286,7 @@ const EQU_ENDLINE_NTSC = 10;
const CSMASK_ECS_AGNUS = 1;
const CSMASK_ECS_DENISE = 2;
const CSMASK_AGA = 4;
const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA);
//const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA);
const CHIPSET_CLOCK_PAL = 3546895;
const CHIPSET_CLOCK_NTSC = 3579545;
@ -338,7 +323,7 @@ const HARD_DDF_START = 0x18;
const MAX_PLANES = 6; /* 8 = AGA */
const AMIGA_WIDTH_MAX = 752 / 2;
const AMIGA_HEIGHT_MAX = 574 / 2;
//const AMIGA_HEIGHT_MAX = 574 / 2;
const DIW_DDF_OFFSET = 1;
const HBLANK_OFFSET = 9;
@ -366,13 +351,13 @@ const COLOR_CHANGE_BRDBLANK = 0x80000000;
const BPLCON_DENISE_DELAY = 1;
const SPRITE_DEBUG = 0;
const SPRITE_DEBUG_MINY = 0x0;
const SPRITE_DEBUG_MAXY = 0x100;
const SPR0_HPOS = 0x15;
const MAX_SPRITES = 8;
//const SPRITE_DEBUG = 0;
//const SPRITE_DEBUG_MINY = 0x0;
//const SPRITE_DEBUG_MAXY = 0x100;
//const AUTOSCALE_SPRITES = 1;
//const SPRBORDER = 0;
const SPR0_HPOS = 0x15;
const MAX_SPRITES = 8;
const MAX_PIXELS_PER_LINE = 1760;
@ -382,8 +367,6 @@ const MAX_REG_CHANGE = ((MAXVPOS + 1) * 2 * MAXHPOS);
const MAX_STOP = 30000;
const NO_BLOCK = -3;
const FRAMES_UNTIL_RES_SWITCH = 1;
const MAX_WORDS_PER_LINE = 100;
const DO_SPRITES = 1;

View file

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

View file

@ -40,7 +40,7 @@ function CPU() {
const ccNames = ['T', 'F', 'HI', 'LS', 'CC', 'CS', 'NE', 'EQ', 'VC', 'VS', 'PL', 'MI', 'GE', 'LT', 'GT', 'LE'];
/* Effective Address */
function effAddr(m, r) {
function EffAddr(m, r) {
this.m = m; /* Mode M_ */
this.t = 0; /* Type T_ */
this.r = r; /* Register An/Dn */
@ -49,31 +49,31 @@ function CPU() {
}
/* Instruction Condition */
function iCon(cc, dp, dr) {
function ICon(cc, dp, dr) {
this.cc = cc; /* Condition Code */
this.dp = dp; /* Displacement */
this.dr = dr; /* Data Register for DBcc */
}
/* Instruction Paramenter */
function iPar() {
this.z; /* size B,W,L */
function IPar() {
this.z = 0; /* size B,W,L */
/* Filled on demand
this.s = new effAddr();
this.d = new effAddr();
this.c = new iCon();
this.s = new EffAddr();
this.d = new EffAddr();
this.c = new ICon();
this.ms = 0;
this.mz = 0;
this.cyc = 0;*/
}
/* Instruction Definition */
function iDef() {
this.op; /* OP-code */
this.pr; /* Privileged */
this.mn; /* Mnemonic */
this.f; /* Function */
this.p = new iPar();
function IDef() {
this.op = 0; /* OP-code */
//this.pr = false; /* Privileged */
this.mn = ''; /* Mnemonic */
this.f = null; /* Function */
this.p = new IPar();
}
/* Exception 2/3 error */
@ -118,31 +118,31 @@ function CPU() {
/*-----------------------------------------------------------------------*/
this.setup = function() {
if (iTab === null) {
BUG.say('cpu.setup() no instruction table, generating...');
if (!mkiTab())
Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table');
} else
BUG.say('cpu.setup() instruction table is cached');
}
this.setup = function () {
if (iTab === null) {
BUG.say('cpu.setup() no instruction table, generating...');
if (!mkiTab())
Fatal(SAEE_CPU_Internal, 'cpu.setup() error generating function table');
} else
BUG.say('cpu.setup() instruction table is cached');
};
this.reset = function (addr) {
for (var i = 0; i < 8; i++)
regs.d[i] = regs.a[i] = 0;
for (var i = 0; i < 8; i++)
regs.d[i] = regs.a[i] = 0;
regs.t = false;
regs.s = true;
regs.intmask = 7;
regs.x = regs.n = regs.z = regs.v = regs.c = false;
regs.usp = 0;
regs.isp = 0;
regs.a[7] = AMIGA.mem.load32(addr);
regs.pc = AMIGA.mem.load32(addr + 4);
regs.stopped = false;
regs.t = false;
regs.s = true;
regs.intmask = 7;
regs.x = regs.n = regs.z = regs.v = regs.c = false;
regs.usp = 0;
regs.isp = 0;
regs.a[7] = AMIGA.mem.load32(addr);
regs.pc = AMIGA.mem.load32(addr + 4);
regs.stopped = false;
BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc));
}
BUG.say(sprintf('cpu.reset() addr 0x%08x, A7 0x%08x, PC 0x%08x', addr, regs.a[7], regs.pc));
};
/*-----------------------------------------------------------------------*/
@ -154,6 +154,7 @@ function CPU() {
case 4: return 'L';
default:
Fatal(SAEE_CPU_Internal, 'cpu.szChr() invalid size');
return '';
}
}
@ -203,6 +204,7 @@ function CPU() {
case 4: return r > 0xffffffff ? r - 0x100000000 : r;
default:
Fatal(SAEE_CPU_Internal, 'cpu.addAuto() invalid size');
return 0;
}
}
function sub32(a, b) {
@ -217,6 +219,7 @@ function CPU() {
case 4: return r < 0 ? r + 0x100000000 : r;
default:
Fatal(SAEE_CPU_Internal, 'cpu.subAuto() invalid size');
return 0;
}
}
@ -241,9 +244,10 @@ function CPU() {
//var scale = 1 << ((ext & 0x600) >> 9); if (scale != 1) alert('exII() scale '+scale);
function exII(base) {
var ext = nextIWord();
if (ext & 0x100)
Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)');
else {
if (ext & 0x100) {
Fatal(SAEE_CPU_68020_Required, 'cpu.exII() Full extension index (not a 68000 program)');
return 0;
} else {
var disp = extByte(ext & 0xff);
var r = (ext & 0x7000) >> 12;
var reg = (ext & 0x8000) ? regs.a[r] : regs.d[r];
@ -394,6 +398,7 @@ function CPU() {
case 4: return regs.d[ea.a];
default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RD invalid size');
return 0;
}
}
case T_RA: {
@ -402,6 +407,7 @@ function CPU() {
case 4: return regs.a[ea.a];
default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_RA invalid size');
return 0;
}
}
case T_AD: {
@ -427,12 +433,14 @@ function CPU() {
case 4: return AMIGA.mem.load32(ea.a);
default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() T_AD invalid size');
return 0;
}
}
case T_IM:
return ea.a;
default:
Fatal(SAEE_CPU_Internal, 'cpu.ldEA() invalid type (' + ea.t + ')');
return 0;
}
}
@ -501,6 +509,7 @@ function CPU() {
case 15: return regs.z || (regs.n != regs.v); //LE
default:
Fatal(SAEE_CPU_Internal, 'cpu.ccTrue() invalid condition code (' + cc + ')');
return false;
}
}
@ -698,7 +707,7 @@ function CPU() {
function I_PEA(p) {
var sea = exEA(p.s, p.z);
var dea = exEA(new effAddr(M_ripr, 7), p.z);
var dea = exEA(new EffAddr(M_ripr, 7), p.z);
stEA(dea, p.z, sea.a);
//ccna
return p.cyc;
@ -710,7 +719,7 @@ function CPU() {
var dea = exEA(p.d, p.z);
var dp = ldEA(dea, p.z); if (p.z == 2) dp = extWord(dp);
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.a[An]);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.a[An]);
regs.a[An] = regs.a[7];
regs.a[7] = add32(regs.a[7], dp);
//ccna
@ -726,7 +735,7 @@ function CPU() {
var sea = exEA(p.s, p.z);
var An = sea.a;
regs.a[7] = regs.a[An];
regs.a[An] = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
regs.a[An] = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
//ccna
//BUG.say(sprintf('I_UNLK.%s A%d', szChr(p.z), An));
return p.cyc;
@ -987,7 +996,7 @@ function CPU() {
function I_CLR(p) {
var dea = exEA(p.d, p.z);
var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
//var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
stEA(dea, p.z, 0);
regs.n = false;
@ -1812,7 +1821,7 @@ function CPU() {
var cyc;
if (!ccTrue(cc)) {
var ea = exEA(new effAddr(M_rdd, p.c.dr), p.z);
var ea = exEA(new EffAddr(M_rdd, p.c.dr), p.z);
var dr = ldEA(ea, p.z);
if (dr--) {
@ -1833,7 +1842,7 @@ function CPU() {
//var cc = p.s.r;
var cc = p.c.cc;
var dea = exEA(p.d, p.z);
var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
//var foo = ldEA(dea, p.z); /* In the MC68000 and MC68008 a memory location is read before it is cleared. */
var isTrue = ccTrue(cc);
stEA(dea, p.z, isTrue ? 0xff : 0);
//ccna
@ -1868,7 +1877,7 @@ function CPU() {
//else if (dp == 255) Fatal(SAEE_CPU_68020_Required, 'cpu.I_BSR() Full extension index detected (not a 68000 programm)');
else pc = add32(regs.pc, extByte(dp));
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
setPC(pc);
//ccna
return p.cycTaken;
@ -1884,7 +1893,7 @@ function CPU() {
function I_JSR(p) {
var dea = exEA(p.d, p.z);
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
setPC(dea.a);
//ccna
//BUG.say(sprintf('I_JSR $%08x', dea.a));
@ -1892,8 +1901,8 @@ function CPU() {
}
function I_RTR(p) {
var ccr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2) & 0xff;
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
var ccr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2) & 0xff;
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
setCCR(ccr);
setPC(pc);
//BUG.say(sprintf('I_RTR crr $%04x pc $%08x', crr, pc));
@ -1901,7 +1910,7 @@ function CPU() {
}
function I_RTS(p) {
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
//BUG.say(sprintf('I_RTS() regs.pc $%08x newpc $%08x', regs.pc, pc));
setPC(pc);
//ccna
@ -2039,7 +2048,7 @@ function CPU() {
function I_MOVE_SR2(p) {
var sr = getSR();
var dea = exEA(p.d, p.z);
var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */
//var foo = ldEA(dea, p.z); /* Memory destination is read before it is written to. */
stEA(dea, p.z, sr);
//ccna
//BUG.say(sprintf('I_MOVE_SR2.%s sr $%04x', szChr(p.z), sr));
@ -2144,8 +2153,8 @@ function CPU() {
function I_RTE(p) {
if (regs.s) {
var sr = ldEA(exEA(new effAddr(M_ripo, 7), 2), 2);
var pc = ldEA(exEA(new effAddr(M_ripo, 7), 4), 4);
var sr = ldEA(exEA(new EffAddr(M_ripo, 7), 2), 2);
var pc = ldEA(exEA(new EffAddr(M_ripo, 7), 4), 4);
setSR(sr);
//BUG.say(sprintf('I_RTE sr $%04x newpc $%08x oldpc $%08x', sr, pc, regs.pc));
setPC(pc);
@ -2239,11 +2248,12 @@ function CPU() {
case M_absl: return z == 4 ? [16,4,0] : [12,3,0];
case M_imm:
case M_list: return z == 4 ? [ 8,2,0] : [ 4,1,0];
}
default: return [0,0,0];
}
}
function mkN(op, mn, cyc) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
@ -2254,14 +2264,14 @@ function CPU() {
}
function mkS(op, mn, z, s, r, cyc, add) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
i.f = null;
i.p = {};
i.p.z = z;
i.p.s = new effAddr(s, r);
i.p.s = new EffAddr(s, r);
i.p.s.c = mkCyc(z, s);
i.p.cyc = cyc;
if (add) i.p.cyc[0] += i.p.s.c[0];
@ -2271,14 +2281,14 @@ function CPU() {
}
function mkD(op, mn, z, d, r, cyc, add) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
i.f = null;
i.p = {};
i.p.z = z;
i.p.d = new effAddr(d, r);
i.p.d = new EffAddr(d, r);
i.p.d.c = mkCyc(z, d);
i.p.cyc = cyc;
if (add) i.p.cyc[0] += i.p.d.c[0];
@ -2288,7 +2298,7 @@ function CPU() {
}
function mkSD(op, mn, z, sm, sr, dm, dr, cyc, sa, da) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
@ -2297,8 +2307,8 @@ function CPU() {
i.p.z = z;
i.p.ms = z == 1 ? 0x80 : (z == 2 ? 0x8000 : 0x80000000);
i.p.mz = z == 1 ? 0xff : (z == 2 ? 0xffff : 0xffffffff);
i.p.s = new effAddr(sm, sr);
i.p.d = new effAddr(dm, dr);
i.p.s = new EffAddr(sm, sr);
i.p.d = new EffAddr(dm, dr);
i.p.s.c = mkCyc(z, sm);
i.p.d.c = mkCyc(z, dm);
i.p.cyc = cyc;
@ -2312,28 +2322,28 @@ function CPU() {
}
function mkC(op, mn, sz, cc, dp, dr, cycTaken, cyc) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
i.f = null;
i.p = {};
i.p.z = sz;
i.p.c = new iCon(cc, dp, dr);
i.p.c = new ICon(cc, dp, dr);
if (cycTaken !== null) i.p.cycTaken = cycTaken;
if (cyc !== null) i.p.cyc = cyc;
return i;
}
function mkDBcc(op, mn, sz, cc, dp, dr, cycTrue, cycFalseTaken, cycFalse) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
i.f = null;
i.p = {};
i.p.z = sz;
i.p.c = new iCon(cc, dp, dr);
i.p.c = new ICon(cc, dp, dr);
i.p.cycTrue = cycTrue;
i.p.cycFalseTaken = cycFalseTaken;
i.p.cycFalse = cycFalse;
@ -2341,15 +2351,15 @@ function CPU() {
}
function mkCD(op, mn, z, cc, dp, dr, m, r, cycTrue, cycFalse, add) {
var i = new iDef();
var i = new IDef();
i.op = op;
i.pr = false;
i.mn = mn;
i.f = null;
i.p = {};
i.p.z = z;
i.p.c = new iCon(cc, dp, dr);
i.p.d = new effAddr(m, r);
i.p.c = new ICon(cc, dp, dr);
i.p.d = new EffAddr(m, r);
i.p.d.c = mkCyc(z, m);
i.p.cycTrue = cycTrue;
i.p.cycFalse = cycFalse;
@ -2395,7 +2405,7 @@ function CPU() {
iTab = new Array(0x10000);
for (op = 0; op < 0x10000; op++) {
iTab[op] = new iDef();
iTab[op] = new IDef();
iTab[op].op = -1;
iTab[op].pr = false;
iTab[op].mn = 'ILLEGAL';
@ -3590,7 +3600,7 @@ function CPU() {
op = (275 << 6) | ea[0];
if (iTab[op].op === -1) {
iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
iTab[op] = mkS(op, 'MOVE_2CCR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd);
iTab[op].f = I_MOVE_2CCR;
cnt++;
} else {
@ -3632,7 +3642,7 @@ function CPU() {
op = (283 << 6) | ea[0];
if (iTab[op].op === -1) {
iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] == M_rdd ? false : true);
iTab[op] = mkS(op, 'MOVE_2SR', 2, ea[1], ea[2], [12,1,0], ea[1] != M_rdd);
iTab[op].pr = true;
iTab[op].f = I_MOVE_2SR;
cnt++;
@ -4668,29 +4678,29 @@ function CPU() {
}
this.diss = function (offset, limit) {
var pc = offset === null ? regs.pc : offset;
var cnt = 0;
var pc = offset === null ? regs.pc : offset;
var cnt = 0;
while (cnt++ < limit) {
var o = '';
while (cnt++ < limit) {
var o = '';
o += sprintf('$%08x: ', pc);
for (var i = 0; i < 5; i++)
o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2));
o += sprintf('$%08x: ', pc);
for (var i = 0; i < 5; i++)
o += sprintf('$%04x ', AMIGA.mem.load16(pc + i * 2));
var op = AMIGA.mem.load16(pc);
pc += 2;
var op = AMIGA.mem.load16(pc);
pc += 2;
var ip = printI(iTab[op], pc);
o += ip[0];
pc = ip[1];
var ip = printI(iTab[op], pc);
o += ip[0];
pc = ip[1];
BUG.say(o);
}
}
this.dissFault = function (limit) {
this.diss(fault.pc, limit);
}
BUG.say(o);
}
};
/*this.dissFault = function (limit) {
this.diss(fault.pc, limit);
};*/
/*function nextIWordData(data, pc) {
return (data[pc] << 8) | data[pc + 1];
@ -4866,37 +4876,37 @@ function CPU() {
return getName(AMIGA.mem.load32(task + 10));
}
this.getThisTaskName = function() {
var tn = '';
/* Extract current task-name form SysBase */
var sysBase = AMIGA.mem.load32(4);
if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) {
var thisTask = AMIGA.mem.load32(sysBase + 276);
if (thisTask)
tn = getTaskName(thisTask);
}
return tn;
}
this.getThisTaskName = function () {
var tn = '';
/* Extract current task-name form SysBase */
var sysBase = AMIGA.mem.load32(4);
if (sysBase == 0x000676 || sysBase == 0xc00276 || sysBase == 0xc00a88 || sysBase == 0xc00560) {
var thisTask = AMIGA.mem.load32(sysBase + 276);
if (thisTask)
tn = getTaskName(thisTask);
}
return tn;
};
this.dump = function() {
var i, out = '', tn = 1 ? this.getThisTaskName() : '';
this.dump = function () {
var i, out = '', tn = 1 ? this.getThisTaskName() : '';
for (i = 0; i < 8; i++) {
out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>';
}
//out += '<br/>';
out += "\n";
for (i = 0; i < 8; i++) {
out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>';
}
//out += '<br/>';
out += "\n";
out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp);
out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn);
out += "\n";
out += "\n";
BUG.say(out);
}
for (i = 0; i < 8; i++) {
out += sprintf('D%d $%08x ', i, regs.d[i]); //if ((i & 3) == 3) out += '<br/>';
}
//out += '<br/>';
out += "\n";
for (i = 0; i < 8; i++) {
out += sprintf('A%d $%08x ', i, regs.a[i]); //if ((i & 3) == 3) out += '<br/>';
}
//out += '<br/>';
out += "\n";
out += sprintf('PC $%08x USP $%08x ISP $%08x ', regs.pc, regs.usp, regs.isp);
out += sprintf('T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d, LTASK=%s', regs.t ? 1 : 0, regs.s ? 1 : 0, regs.x ? 1 : 0, regs.n ? 1 : 0, regs.z ? 1 : 0, regs.v ? 1 : 0, regs.c ? 1 : 0, regs.intmask, tn);
out += "\n";
out += "\n";
BUG.say(out);
};
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
@ -5025,7 +5035,7 @@ function CPU() {
regs.t = 0;
}
function exception_cycles(n) {
/*function exception_cycles(n) {
var c;
if (n < 16)
switch (n) {
@ -5051,7 +5061,7 @@ function CPU() {
c = [4,0,0];
}
return c;
}
}*/
function exception(n) {
//BUG.say(sprintf('cpu.exception() nr %d', n));
@ -5076,8 +5086,8 @@ function CPU() {
if (n == 2) {
BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0));
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
} else if (n == 3) {
BUG.say(sprintf('cpu.exception() %d, regs.pc $%08x, fault.pc $%08x, fault.op $%04x, fault.ad $%08x, fault.ia %d', n, regs.pc, fault.pc, fault.op, fault.ad, fault.ia ? 1 : 0));
@ -5085,14 +5095,14 @@ function CPU() {
var wa = 0;
var cd = (wa ? 0 : 16) | (olds ? 4 : 0) | (ia ? 2 : 1);
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.pc);
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, fault.op);
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, fault.ad);
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, cd);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.pc);
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, fault.op);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, fault.ad);
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, cd);
} else {
stEA(exEA(new effAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new effAddr(M_ripr, 7), 2), 2, sr);
stEA(exEA(new EffAddr(M_ripr, 7), 4), 4, regs.pc);
stEA(exEA(new EffAddr(M_ripr, 7), 2), 2, sr);
}
var pc = AMIGA.mem.load32(n * 4);
@ -5113,14 +5123,14 @@ function CPU() {
regs.pc = pc;
exception_trace(n);
return exception_cycles(n);
return [4,0,0];//exception_cycles(n);
}
function exception2(ad) {
/*function exception2(ad) {
fault.ad = ad;
fault.ia = 0;
throw new Exception23(2);
}
}*/
function exception3(ad, ia) {
fault.ad = ad;
@ -5139,19 +5149,13 @@ function CPU() {
AMIGA.doint();
}
function trace() {
if (regs.t) {
clr_special(SPCFLAG_TRACE);
set_special(SPCFLAG_DOTRACE);
}
}
function cycle_spc(cycles) {
if (AMIGA.spcflags & SPCFLAG_COPPER)
AMIGA.copper.cycle();
while ((AMIGA.spcflags & SPCFLAG_BLTNASTY) && AMIGA.dmaen(DMAF_BLTEN) && cycles > 0) {
var c = AMIGA.blitter.blitnasty();
//console.log('nasty', cycles, c);
if (c > 0) {
cycles -= c * CYCLE_UNIT * 2;
if (cycles < CYCLE_UNIT)
@ -5166,6 +5170,7 @@ function CPU() {
if (AMIGA.spcflags & SPCFLAG_DOTRACE)
exception(9);
if (AMIGA.spcflags & SPCFLAG_TRAP) {
clr_special(SPCFLAG_TRAP);
exception(3);
@ -5183,21 +5188,26 @@ function CPU() {
if (intr > 0 && intr > regs.intmask)
interrupt(intr);
}
/*if (AMIGA.spcflags & SPCFLAG_BRK) {
clr_special(SPCFLAG_BRK);
//if (AMIGA.spcflags & SPCFLAG_BRK) {
if (AMIGA.state != ST_CYCLE) {
//clr_special(SPCFLAG_BRK);
clr_special(SPCFLAG_STOP);
regs.stopped = false;
return true;
}*/
}
}
if (AMIGA.spcflags & SPCFLAG_TRACE)
trace();
if (AMIGA.spcflags & SPCFLAG_TRACE) {
if (regs.t) {
clr_special(SPCFLAG_TRACE);
set_special(SPCFLAG_DOTRACE);
}
}
if (AMIGA.spcflags & SPCFLAG_INT) {
clr_special(SPCFLAG_INT | SPCFLAG_DOINT);
var intr = AMIGA.intlev();
if (intr > 0 && (intr > regs.intmask || intr == 7))
if (intr > 0 && intr > regs.intmask)
interrupt(intr);
}
if (AMIGA.spcflags & SPCFLAG_DOINT) {

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

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

View file

@ -19,55 +19,55 @@ function Mouse() {
var lx = -1;
var ly = -1;
this.reset = function() {
this.button = [0, 0, 0];
cx = cy = 0;
lx = ly = -1;
}
this.reset = function () {
this.button = [0, 0, 0];
cx = cy = 0;
lx = ly = -1;
};
this.mousedown = function (e) {
e = e || window.event;
if (!e) return;
e = e || window.event;
if (!e) return;
this.button[e.button] = true;
}
this.button[e.button] = true;
};
this.mouseup = function (e) {
e = e || window.event;
if (!e) return;
e = e || window.event;
if (!e) return;
this.button[e.button] = false;
}
this.button[e.button] = false;
};
this.mouseover = function (e) {
//AMIGA.video.hideCursor(1);
this.mousemove(e);
lx = cx;
ly = cy;
}
//AMIGA.video.hideCursor(1);
this.mousemove(e);
lx = cx;
ly = cy;
};
this.mouseout = function (e) {
//AMIGA.video.hideCursor(0);
this.mouseup(e);
}
//AMIGA.video.hideCursor(0);
this.mouseup(e);
};
this.mousemove = function (e) {
e = e || window.event;
if (!e || !AMIGA.video) return;
e = e || window.event;
if (!e || !AMIGA.video) return;
if (e.pageX || e.pageY) {
cx = e.pageX;
cy = e.pageY;
} else if (e.clientX || e.clientY) {
cx = e.clientX;
cy = e.clientY;
}
if (lx == -1) {
lx = cx;
ly = cy;
}
//BUG.info('USER() mousemove %d %d', cx, cy);
}
if (e.pageX || e.pageY) {
cx = e.pageX;
cy = e.pageY;
} else if (e.clientX || e.clientY) {
cx = e.clientX;
cy = e.clientY;
}
if (lx == -1) {
lx = cx;
ly = cy;
}
//BUG.info('USER() mousemove %d %d', cx, cy);
};
this.update = function() {
if (lx != -1) {
@ -97,13 +97,11 @@ function Joystick(type) {
this.button = [false, false, false];
this.state = [false, false, false, false];
this.dir = 0;
var x = 0;
var y = 0;
this.reset = function() {
this.button = [false, false, false];
this.state = [false, false, false, false];
}
this.reset = function () {
this.button = [false, false, false];
this.state = [false, false, false, false];
};
this.update = function() {
var u = this.state[1];
@ -144,7 +142,7 @@ function Keyboard() {
const RAWKEY_0 = 0x0A;
const RAWKEY_MINUS = 0x0B;
const RAWKEY_EQUAL = 0x0C;
const RAWKEY_BACKSLASH = 0x0D;
//const RAWKEY_BACKSLASH = 0x0D;
const RAWKEY_KP_0 = 0x0F;
const RAWKEY_Q = 0x10;
const RAWKEY_W = 0x11;
@ -194,7 +192,7 @@ function Keyboard() {
const RAWKEY_SPACE = 0x40;
const RAWKEY_BACKSPACE = 0x41;
const RAWKEY_TAB = 0x42;
const RAWKEY_KP_ENTER = 0x43;
//const RAWKEY_KP_ENTER = 0x43;
const RAWKEY_RETURN = 0x44;
const RAWKEY_ESCAPE = 0x45;
const RAWKEY_DELETE = 0x46;
@ -226,7 +224,7 @@ function Keyboard() {
const RAWKEY_CAPSLOCK = 0x62;
const RAWKEY_CONTROL = 0x63;
const RAWKEY_LALT = 0x64;
const RAWKEY_RALT = 0x65;
//const RAWKEY_RALT = 0x65;
const RAWKEY_LAMIGA = 0x66;
const RAWKEY_RAMIGA = 0x67;
/*const RAWKEY_SCRLOCK = 0x6B;
@ -247,9 +245,9 @@ function Keyboard() {
const RAWKEY_NM_WHEEL_LEFT = 0x7C;
const RAWKEY_NM_WHEEL_RIGHT = 0x7D;
const RAWKEY_NM_BUTTON_FOURTH = 0x7E;*/
const RAWKEY_BAD_CODE = 0xF9;
/*const RAWKEY_BAD_CODE = 0xF9;
const RAWKEY_BUFFER_OVERFLOW = 0xFA;
const RAWKEY_SELFTEST_FAILED = 0xFC;
const RAWKEY_SELFTEST_FAILED = 0xFC;*/
const RAWKEY_INIT_POWER_UP = 0xFD;
const RAWKEY_TERM_POWER_UP = 0xFE;
@ -486,214 +484,313 @@ function Keyboard() {
function _onkeydown(e) { AMIGA.input.keyboard.handleKey(e, true); }
function _onkeyup(e) { AMIGA.input.keyboard.handleKey(e, false); }
this.setup = function() {
/*document.onkeydown = function (e) {
AMIGA.input.keyboard.keydownup(e, true);
}
document.onkeyup = function (e) {
AMIGA.input.keyboard.keydownup(e, false);
}*/
window.document.addEventListener('keydown', _onkeydown, false);
window.document.addEventListener('keyup', _onkeyup, false);
}
this.setup = function () {
/*document.onkeydown = function (e) {
AMIGA.input.keyboard.keydownup(e, true);
}
document.onkeyup = function (e) {
AMIGA.input.keyboard.keydownup(e, false);
}*/
window.document.addEventListener('keydown', _onkeydown, false);
window.document.addEventListener('keyup', _onkeyup, false);
};
this.cleanup = function() {
//BUG.info('Keyboard.cleanup()');
//document.onkeydown = null;
//document.onkeyup = null;
window.document.removeEventListener('keydown', _onkeydown, false);
window.document.removeEventListener('keyup', _onkeyup, false);
}
this.cleanup = function () {
//BUG.info('Keyboard.cleanup()');
//document.onkeydown = null;
//document.onkeyup = null;
window.document.removeEventListener('keydown', _onkeydown, false);
window.document.removeEventListener('keyup', _onkeyup, false);
};
this.reset = function() {
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
state = 0;
code = 0;
first = last = 0;
hsynccnt = 0;
this.lostsynccnt = 0;
}
this.reset = function () {
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
state = 0;
code = 0;
first = last = 0;
hsynccnt = 0;
this.lostsynccnt = 0;
};
this.keysAvail = function() {
return first != last;
}
this.keysAvail = function () {
return first != last;
};
this.nextKey = function() {
//assert (first != last);
var key = keyBuf[last];
if (++last == KEYBUFSIZE) last = 0;
return key;
}
this.nextKey = function () {
//assert (first != last);
var key = keyBuf[last];
if (++last == KEYBUFSIZE) last = 0;
return key;
};
this.recordKey = function (kc) {
var next = first + 1;
var next = first + 1;
if (next == KEYBUFSIZE) next = 0;
if (next == last) {
BUG.info('Keyboard() buffer overrun!');
return false;
}
keyBuf[first] = kc;
first = next;
return true;
}
if (next == KEYBUFSIZE) next = 0;
if (next == last) {
BUG.info('Keyboard() buffer overrun!');
return false;
}
keyBuf[first] = kc;
first = next;
return true;
};
this.processKey = function (code, down) {
/* Caps-lock */
if (code == 20) {
if (down) {
capsLock = !capsLock;
if (!capsLock) return;
} else {
if (capsLock) return;
}
}
/* joystick emul */
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
var l,u,r,d,f1,f2;
switch (AMIGA.config.ports[0].move) {
case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; }
case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; }
case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; }
}
f1 = AMIGA.config.ports[0].fire[0];
f2 = AMIGA.config.ports[0].fire[1];
switch (code) {
case f1: { AMIGA.input.joystick[0].button[0] = down; break; }
case f2: { AMIGA.input.joystick[0].button[1] = down; break; }
case l: { AMIGA.input.joystick[0].state[0] = down; if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false; break; }
case u: { AMIGA.input.joystick[0].state[1] = down; if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false; break; }
case r: { AMIGA.input.joystick[0].state[2] = down; if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false; break; }
case d: { AMIGA.input.joystick[0].state[3] = down; if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false; break; }
}
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
var l,u,r,d,f1,f2;
switch (AMIGA.config.ports[1].move) {
case SAEV_Config_Ports_Move_Arrows: { l = 37; u = 38; r = 39; d = 40; break; }
case SAEV_Config_Ports_Move_Numpad: { l = 100; u = 104; r = 102; d = 101; break; }
case SAEV_Config_Ports_Move_WASD: { l = 65; u = 87; r = 68; d = 83; break; }
}
f1 = AMIGA.config.ports[1].fire[0];
f2 = AMIGA.config.ports[1].fire[1];
switch (code) {
case f1: { AMIGA.input.joystick[1].button[0] = down; break; }
case f2: { AMIGA.input.joystick[1].button[1] = down; break; }
case l: { AMIGA.input.joystick[1].state[0] = down; if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false; break; }
case u: { AMIGA.input.joystick[1].state[1] = down; if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false; break; }
case r: { AMIGA.input.joystick[1].state[2] = down; if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false; break; }
case d: { AMIGA.input.joystick[1].state[3] = down; if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false; break; }
}
}
if (!AMIGA.config.keyboard.enabled)
return;
this.processKey = function (code, down) {
/* Caps-lock */
if (code == 20) {
if (down) {
capsLock = !capsLock;
if (!capsLock) return;
} else {
if (capsLock) return;
}
}
/* map shift-keys (team17 pinball games) */
if (AMIGA.config.keyboard.mapShift) {
switch (code) {
case 37: { //left arrow
var rawkey = RAWKEY_LSHIFT;
if (!down) {
this.recordKey((rawkey << 1) | 1);
} else {
this.recordKey(rawkey << 1);
}
//break;
return;
}
case 39: { //right arrow
var rawkey = RAWKEY_RSHIFT;
if (!down) {
this.recordKey((rawkey << 1) | 1);
} else {
this.recordKey(rawkey << 1);
}
//break;
return;
}
}
}
/* joystick emul */
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
var l, u, r, d, f1, f2;
switch (AMIGA.config.ports[0].move) {
case SAEV_Config_Ports_Move_Arrows:
{
l = 37;
u = 38;
r = 39;
d = 40;
break;
}
case SAEV_Config_Ports_Move_Numpad:
{
l = 100;
u = 104;
r = 102;
d = 101;
break;
}
case SAEV_Config_Ports_Move_WASD:
{
l = 65;
u = 87;
r = 68;
d = 83;
break;
}
}
f1 = AMIGA.config.ports[0].fire[0];
f2 = AMIGA.config.ports[0].fire[1];
switch (code) {
case f1:
{
AMIGA.input.joystick[0].button[0] = down;
break;
}
case f2:
{
AMIGA.input.joystick[0].button[1] = down;
break;
}
case l:
{
AMIGA.input.joystick[0].state[0] = down;
if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false;
break;
}
case u:
{
AMIGA.input.joystick[0].state[1] = down;
if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false;
break;
}
case r:
{
AMIGA.input.joystick[0].state[2] = down;
if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false;
break;
}
case d:
{
AMIGA.input.joystick[0].state[3] = down;
if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false;
break;
}
}
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
var l, u, r, d, f1, f2;
switch (AMIGA.config.ports[1].move) {
case SAEV_Config_Ports_Move_Arrows:
{
l = 37;
u = 38;
r = 39;
d = 40;
break;
}
case SAEV_Config_Ports_Move_Numpad:
{
l = 100;
u = 104;
r = 102;
d = 101;
break;
}
case SAEV_Config_Ports_Move_WASD:
{
l = 65;
u = 87;
r = 68;
d = 83;
break;
}
}
f1 = AMIGA.config.ports[1].fire[0];
f2 = AMIGA.config.ports[1].fire[1];
switch (code) {
case f1:
{
AMIGA.input.joystick[1].button[0] = down;
break;
}
case f2:
{
AMIGA.input.joystick[1].button[1] = down;
break;
}
case l:
{
AMIGA.input.joystick[1].state[0] = down;
if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false;
break;
}
case u:
{
AMIGA.input.joystick[1].state[1] = down;
if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false;
break;
}
case r:
{
AMIGA.input.joystick[1].state[2] = down;
if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false;
break;
}
case d:
{
AMIGA.input.joystick[1].state[3] = down;
if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false;
break;
}
}
}
var rawkey = false;
if (BrowserDetect.browser == 'Firefox') {
if (typeof(mozKeyCodeMap[code]) != 'undefined')
rawkey = mozKeyCodeMap[code];
} else {
if (typeof(defKeyCodeMap[code]) != 'undefined')
rawkey = defKeyCodeMap[code];
}
//BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey);
if (!AMIGA.config.keyboard.enabled)
return;
if (rawkey !== false) {
if (down)
this.recordKey(rawkey << 1);
else
this.recordKey((rawkey << 1) | 1);
}
}
/* map shift-keys (team17 pinball games) */
if (AMIGA.config.keyboard.mapShift) {
switch (code) {
case 37:
{ //left arrow
if (!down) {
this.recordKey((RAWKEY_LSHIFT << 1) | 1);
} else {
this.recordKey(RAWKEY_LSHIFT << 1);
}
//break;
return;
}
case 39:
{ //right arrow
if (!down) {
this.recordKey((RAWKEY_RSHIFT << 1) | 1);
} else {
this.recordKey(RAWKEY_RSHIFT << 1);
}
//break;
return;
}
}
}
var rawkey = false;
if (BrowserDetect.browser == 'Firefox') {
if (typeof(mozKeyCodeMap[code]) != 'undefined')
rawkey = mozKeyCodeMap[code];
} else {
if (typeof(defKeyCodeMap[code]) != 'undefined')
rawkey = defKeyCodeMap[code];
}
//BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey);
if (rawkey !== false) {
if (down)
this.recordKey(rawkey << 1);
else
this.recordKey((rawkey << 1) | 1);
}
};
this.handleKey = function (e, down) {
e = e || window.event;
var code = e.which ? e.which : e.keyCode;
e = e || window.event;
var code = e.which ? e.which : e.keyCode;
if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12
e.preventDefault();
//BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0);
if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12
e.preventDefault();
/* Ctrl-Alt fix */
if (!down && code == 17 && keyState[18]) {
keyState[18] = false;
this.processKey(18, keyState[18]);
}
var oldstate = keyState[code];
if (down && !keyState[code]) {
keyState[code] = true;
}
else if (!down) {
keyState[code] = false;
}
if (keyState[code] != oldstate) {
this.processKey(code, keyState[code]);
}
}
//BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0);
/* Ctrl-Alt fix */
if (!down && code == 17 && keyState[18]) {
keyState[18] = false;
this.processKey(18, keyState[18]);
}
var oldstate = keyState[code];
if (down && !keyState[code]) {
keyState[code] = true;
}
else if (!down) {
keyState[code] = false;
}
if (keyState[code] != oldstate) {
this.processKey(code, keyState[code]);
}
};
this.setCode = function (keycode) {
code = ~((keycode << 1) | (keycode >> 7)) & 0xff;
}
code = ~((keycode << 1) | (keycode >> 7)) & 0xff;
};
this.keyReq = function() {
this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; /* 8 frames * 8 bits */
this.keyReq = function () {
this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8;
/* 8 frames * 8 bits */
//AMIGA.cia.setICR(CIA_A, 8, code);
AMIGA.cia.SetICRA(8, code);
}
//AMIGA.cia.setICR(CIA_A, 8, code);
AMIGA.cia.SetICRA(8, code);
};
this.hsync = function() {
if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) {
switch (state) {
case 0:
code = 0;
state++;
break;
case 1:
this.setCode(RAWKEY_INIT_POWER_UP);
state++;
break;
case 2:
this.setCode(RAWKEY_TERM_POWER_UP);
state++;
break;
case 3:
code = ~this.nextKey() & 0xff;
break;
}
this.keyReq();
}
}
this.hsync = function () {
if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) {
switch (state) {
case 0:
code = 0;
state++;
break;
case 1:
this.setCode(RAWKEY_INIT_POWER_UP);
state++;
break;
case 2:
this.setCode(RAWKEY_TERM_POWER_UP);
state++;
break;
case 3:
code = ~this.nextKey() & 0xff;
break;
}
this.keyReq();
}
};
this.vsync = function() {
if (this.lostsynccnt > 0) {
@ -719,82 +816,82 @@ function Input() {
count: 0
};
this.setup = function() {
this.keyboard.setup();
}
this.setup = function () {
this.keyboard.setup();
};
this.cleanup = function() {
this.keyboard.cleanup();
}
this.cleanup = function () {
this.keyboard.cleanup();
};
this.reset = function() {
this.mouse.reset();
this.joystick[0].reset();
this.joystick[1].reset();
this.keyboard.reset();
potgo.data = 0;
potgo.count = 0;
}
this.reset = function () {
this.mouse.reset();
this.joystick[0].reset();
this.joystick[1].reset();
this.keyboard.reset();
potgo.data = 0;
potgo.count = 0;
};
this.POTGO = function (v) {
//BUG.info('Input.POTGO() $%04x', v);
potgo.data = v;
}
//BUG.info('Input.POTGO() $%04x', v);
potgo.data = v;
};
this.POTGOR = function() {
var v = (potgo.data | (potgo.data << 1)) & 0xaa00;
v |= v >> 1;
this.POTGOR = function () {
var v = (potgo.data | (potgo.data << 1)) & 0xaa00;
v |= v >> 1;
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) v &= 0xfbff;
if (this.mouse.button[1]) v &= 0xfeff;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
if (this.joystick[0].button[1]) v &= 0xfbff;
if (this.joystick[0].button[2]) v &= 0xfeff;
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
if (this.joystick[1].button[1]) v &= 0xbfff;
if (this.joystick[1].button[2]) v &= 0xefff;
}
//BUG.info('Input.POTGOR() $%04x', v);
return v;
}
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) v &= 0xfbff;
if (this.mouse.button[1]) v &= 0xfeff;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
if (this.joystick[0].button[1]) v &= 0xfbff;
if (this.joystick[0].button[2]) v &= 0xfeff;
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
if (this.joystick[1].button[1]) v &= 0xbfff;
if (this.joystick[1].button[2]) v &= 0xefff;
}
//BUG.info('Input.POTGOR() $%04x', v);
return v;
};
this.POT0DAT = function() {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff);
if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff;
}
//BUG.info('Input.POT0DAT() $%04x', v);
return potgo.count;
}
this.POT0DAT = function () {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff);
if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff;
}
//BUG.info('Input.POT0DAT() $%04x', v);
return potgo.count;
};
this.POT1DAT = function() {
//BUG.info('Input.POT1DAT() NOT IMPLEMENTED');
return 0xffff;
}
this.POT1DAT = function () {
//BUG.info('Input.POT1DAT() NOT IMPLEMENTED');
return 0xffff;
};
this.JOY0DAT = function() {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
this.joystick[0].update();
return this.joystick[0].dir;
}
return 0xffff;
}
this.JOY0DAT = function () {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
this.joystick[0].update();
return this.joystick[0].dir;
}
return 0xffff;
};
this.JOY1DAT = function() {
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
this.joystick[1].update();
return this.joystick[1].dir;
}
return 0xffff;
}
this.JOY1DAT = function () {
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
this.joystick[1].update();
return this.joystick[1].dir;
}
return 0xffff;
};
this.JOYTEST = function (v) {
//BUG.info('Input.JOYTEST() $%04x', v);

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -10,18 +10,18 @@
/* moving average algorithm */
function mavg(size) {
function MAvg(size) {
this.values = new Array(size);
this.size = size;
this.usage = 0;
this.offset = 0;
this.average = 0;
this.clr = function() {
this.usage = 0;
this.offset = 0;
this.average = 0;
}
this.clr = function () {
this.usage = 0;
this.offset = 0;
this.average = 0;
};
this.set = function(newval) {
if (this.usage < this.size) {
@ -92,131 +92,127 @@ function mavg(size) {
*/
sprintfWrapper = {
init: function () {
if (typeof arguments == "undefined") {
return null;
}
if (arguments.length < 1) {
return null;
}
if (typeof arguments[0] != "string") {
return null;
}
if (typeof RegExp == "undefined") {
return null;
}
init: function () {
if (typeof arguments == "undefined") {
return null;
}
if (arguments.length < 1) {
return null;
}
if (typeof arguments[0] != "string") {
return null;
}
if (typeof RegExp == "undefined") {
return null;
}
var string = arguments[0];
var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
var matches = new Array();
var strings = new Array();
var convCount = 0;
var stringPosStart = 0;
var stringPosEnd = 0;
var matchPosEnd = 0;
var newString = '';
var match = null;
var string = arguments[0];
var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
var matches = [];
var strings = [];
var convCount = 0;
var stringPosStart = 0;
var stringPosEnd = 0;
var matchPosEnd = 0;
var newString = '';
var match;
while (match = exp.exec(string)) {
if (match[9]) {
convCount += 1;
}
while (match = exp.exec(string)) {
if (match[9]) {
convCount += 1;
}
stringPosStart = matchPosEnd;
stringPosEnd = exp.lastIndex - match[0].length;
strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
stringPosStart = matchPosEnd;
stringPosEnd = exp.lastIndex - match[0].length;
strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
matchPosEnd = exp.lastIndex;
matches[matches.length] = {
match: match[0],
left: match[3] ? true : false,
sign: match[4] || '',
pad: match[5] || ' ',
min: match[6] || 0,
precision: match[8],
code: match[9] || '%',
negative: parseInt(arguments[convCount]) < 0 ? true : false,
argument: String(arguments[convCount])
};
}
strings[strings.length] = string.substring(matchPosEnd);
matchPosEnd = exp.lastIndex;
matches[matches.length] = {
match: match[0],
left: match[3] ? true : false,
sign: match[4] || '',
pad: match[5] || ' ',
min: match[6] || 0,
precision: match[8],
code: match[9] || '%',
negative: !!(parseInt(arguments[convCount]) < 0),
argument: String(arguments[convCount])
};
}
strings[strings.length] = string.substring(matchPosEnd);
if (matches.length == 0) {
return string;
}
if ((arguments.length - 1) < convCount) {
return null;
}
if (matches.length == 0) {
return string;
}
if ((arguments.length - 1) < convCount) {
return null;
}
var code = null;
var match = null;
var i = null;
for (var i = 0; i < matches.length; i++) {
var substitution;
for (i = 0; i < matches.length; i++) {
if (matches[i].code == '%') {
substitution = '%'
} else if (matches[i].code == 'b') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'c') {
matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'd') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'f') {
matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'o') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 's') {
matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'x') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'X') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
} else {
substitution = matches[i].match;
}
newString += strings[i];
newString += substitution;
if (matches[i].code == '%') {
substitution = '%'
} else if (matches[i].code == 'b') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'c') {
matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'd') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'f') {
matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'o') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 's') {
matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
substitution = sprintfWrapper.convert(matches[i], true);
} else if (matches[i].code == 'x') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]);
} else if (matches[i].code == 'X') {
matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
} else {
substitution = matches[i].match;
}
}
newString += strings[i];
newString += strings[i];
newString += substitution;
return newString;
}
newString += strings[i];
},
return newString;
},
convert: function (match, nosign) {
if (nosign) {
match.sign = '';
} else {
match.sign = match.negative ? '-' : match.sign;
}
var l = match.min - match.argument.length + 1 - match.sign.length;
var pad = new Array(l < 0 ? 0 : l).join(match.pad);
if (!match.left) {
if (match.pad == "0" || nosign) {
return match.sign + pad + match.argument;
} else {
return pad + match.sign + match.argument;
}
} else {
if (match.pad == "0" || nosign) {
return match.sign + match.argument + pad.replace(/0/g, ' ');
} else {
return match.sign + match.argument + pad;
}
}
}
}
convert: function (match, nosign) {
if (nosign) {
match.sign = '';
} else {
match.sign = match.negative ? '-' : match.sign;
}
var l = match.min - match.argument.length + 1 - match.sign.length;
var pad = new Array(l < 0 ? 0 : l).join(match.pad);
if (!match.left) {
if (match.pad == "0" || nosign) {
return match.sign + pad + match.argument;
} else {
return pad + match.sign + match.argument;
}
} else {
if (match.pad == "0" || nosign) {
return match.sign + match.argument + pad.replace(/0/g, ' ');
} else {
return match.sign + match.argument + pad;
}
}
}
};
sprintf = sprintfWrapper.init;
@ -240,10 +236,11 @@ var BrowserDetect = {
if (dataString.indexOf(data[i].subString) != -1) return data[i].identity;
} else if (dataProp) return data[i].identity;
}
return '';
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
if (index == -1) return 0.0;
return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
},
dataBrowser: [{
@ -323,7 +320,7 @@ BrowserDetect.init();
/*-----------------------------------------------------------------------*/
function dump(obj) {
/*function dump(obj) {
var out = '';
if (obj) {
for (var i in obj) {
@ -333,7 +330,7 @@ function dump(obj) {
out = 'undefined';
alert(out);
}
}*/
/*-----------------------------------------------------------------------*/
@ -396,25 +393,25 @@ function loadRemote(file, crc, callback) {
/*-----------------------------------------------------------------------*/
function Debug() {
this.col = 1;
//this.col = 1;
this.on = 1;
this.say = function (str) {
if (this.on) {
/*var e = document.createElement('span');
e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484');
e.innerHTML = buf;
this.debug.appendChild(e);
this.debug.appendChild(document.createElement('br'));
this.debug.scrollTop = this.debug.scrollHeight;*/
console.log(str);
/*console.info(str);
console.warn(str);
console.error(str);
console.assert(str);*/
}
}
if (this.on) {
/*var e = document.createElement('span');
e.style.color = this.col == 1 ? '#888' : (this.col == 2 ? '#448' : '#484');
e.innerHTML = buf;
this.debug.appendChild(e);
this.debug.appendChild(document.createElement('br'));
this.debug.scrollTop = this.debug.scrollHeight;*/
console.log(str);
/*console.info(str);
console.warn(str);
console.error(str);
console.assert(str);*/
}
};
this.info = function () {
if (this.on) {
@ -426,56 +423,56 @@ function Debug() {
/*-----------------------------------------------------------------------*/
function Uint64(hi, lo) {
/*function Uint64(hi, lo) {
this.hi = hi;
this.lo = lo;
this.or = function(v) {
this.hi = (this.hi | v.hi) >>> 0;
this.lo = (this.lo | v.lo) >>> 0;
}
this.or = function (v) {
this.hi = (this.hi | v.hi) >>> 0;
this.lo = (this.lo | v.lo) >>> 0;
};
this.lshift = function(n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.lo & m;
this.hi = ((this.hi << n) | t) >>> 0;
this.lo = (this.lo << n) >>> 0;
this.lshift = function (n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.lo & m;
this.hi = ((this.hi << n) | t) >>> 0;
this.lo = (this.lo << n) >>> 0;
//BUG.info('lshift %d %x', n, m, t);
} else {
var t = this.lo;
this.hi = (t << (n-32)) >>> 0;
this.lo = 0;
//BUG.info('lshift %d %x', n, m, t);
} else {
var t = this.lo;
this.hi = (t << (n - 32)) >>> 0;
this.lo = 0;
//BUG.info('lshift %d %x', n, t);
}
}
}
//BUG.info('lshift %d %x', n, t);
}
}
};
this.rshift = function(n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.hi & m;
this.hi = (this.hi >>> n) >>> 0;
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
this.rshift = function (n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.hi & m;
this.hi = (this.hi >>> n) >>> 0;
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
//BUG.info('rshift %d %x %x', n, m, t);
} else {
var t = this.hi;
this.hi = 0;
this.lo = (t >>> (n-32)) >>> 0;
//BUG.info('rshift %d %x %x', n, m, t);
} else {
var t = this.hi;
this.hi = 0;
this.lo = (t >>> (n - 32)) >>> 0;
//BUG.info('rshift %d %x %x', n, t);
}
}
}
//BUG.info('rshift %d %x %x', n, t);
}
}
};
this.print = function() {
BUG.info('$%08x%08x', this.hi, this.lo);
}
}
}*/

View file

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