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