update 0.8.0

This commit is contained in:
Rupert Hausberger 2013-01-16 19:00:33 +01:00
commit eda41a625b
20 changed files with 9833 additions and 4280 deletions

View file

@ -5,11 +5,13 @@ a:hover { color:#2040c0; text-decoration:underline; }
.alt { text-align:left; vertical-align:top; } .alt { text-align:left; vertical-align:top; }
.alm { text-align:left; vertical-align:middle; } .alm { text-align:left; vertical-align:middle; }
.almsg { text-align:left; vertical-align:middle; font-size:x-small; color:gray; }
.alb { text-align:left; vertical-align:bottom; } .alb { text-align:left; vertical-align:bottom; }
.act { text-align:center; vertical-align:top; } .act { text-align:center; vertical-align:top; }
.acm { text-align:center; vertical-align:middle; } .acm { text-align:center; vertical-align:middle; }
.acmsb { text-align:center; vertical-align:middle; font-size:x-small; font-weight:bold; } .acmsb { text-align:center; vertical-align:middle; font-size:x-small; font-weight:bold; }
.acmsg { text-align:center; vertical-align:middle; font-size:x-small; color:gray; }
.acb { text-align:center; vertical-align:bottom; } .acb { text-align:center; vertical-align:bottom; }
.art { text-align:right; vertical-align:top; } .art { text-align:right; vertical-align:top; }
@ -17,6 +19,7 @@ a:hover { color:#2040c0; text-decoration:underline; }
.armb { text-align:right; vertical-align:middle; font-weight:bold; } .armb { text-align:right; vertical-align:middle; font-weight:bold; }
.arms { text-align:right; vertical-align:middle; font-size:x-small; } .arms { text-align:right; vertical-align:middle; font-size:x-small; }
.armsb { text-align:right; vertical-align:middle; font-size:x-small; font-weight:bold; } .armsb { text-align:right; vertical-align:middle; font-size:x-small; font-weight:bold; }
.armsg { text-align:right; vertical-align:middle; font-size:x-small; color:gray; }
.arb { text-align:right; vertical-align:bottom; } .arb { text-align:right; vertical-align:bottom; }
.fsxs { font-size:x-small; } .fsxs { font-size:x-small; }
@ -61,7 +64,6 @@ body {
width:100%; width:100%;
margin:auto; margin:auto;
text-align:center; text-align:center;
background-color:#f8f8f8;
} }
.foot { .foot {
@ -71,18 +73,16 @@ body {
font-size:x-small; font-size:x-small;
} }
#config { #xconfig {
width:800px; width:400px;
margin:auto; margin:auto;
background-color:#fcfcfc; background-color:#fcfcfc;
} }
#config_simple { #config_simple {
width:760px; width:380px;
padding:20px; margin:auto;
border:1px solid #ccc;
} }
.config_simple_hof { .config_simple_hof {
width:50%;
margin:auto; margin:auto;
padding:10px; padding:10px;
border:1px solid #ccc; border:1px solid #ccc;
@ -93,9 +93,11 @@ body {
} }
#config_advanced { #config_advanced {
width:760px; width:780px;
padding:20px; margin:auto;
padding:10px;
border:1px solid #ccc; border:1px solid #ccc;
background-color:#f8f8f8;
display:none; display:none;
} }
#config_advanced table { #config_advanced table {
@ -185,7 +187,7 @@ body {
margin:auto; margin:auto;
padding:10px; padding:10px;
border:1px solid #ccc; border:1px solid #ccc;
background-color:#fcfcfc; background-color:#f8f8f8;
} }
.readme table { .readme table {
width:100%; width:100%;

208
index.htm
View file

@ -6,7 +6,7 @@
<meta name="author" content="Rupert Hausberger" /> <meta name="author" content="Rupert Hausberger" />
<meta name="publisher" content="Rupert Hausberger" /> <meta name="publisher" content="Rupert Hausberger" />
<meta name="description" content="Experimental Amiga Classic Emulator in Javascript" /> <meta name="description" content="Experimental Amiga Classic Emulator in Javascript" />
<meta name="keywords" content="SAE,Javascript,HTML5,Amiga,AmigaOS,Emulator,Online" /> <meta name="keywords" content="SAE,Javascript,Scripted,Script,HTML5,Amiga,AmigaOS,Emulator,Online" />
<meta name="robots" content="index,nofollow" /> <meta name="robots" content="index,nofollow" />
<link rel="icon" type="image/x-icon" href="http://scriptedamigaemulator.net/favicon.ico" /> <link rel="icon" type="image/x-icon" href="http://scriptedamigaemulator.net/favicon.ico" />
<link rel="stylesheet" type="text/css" href="index.css" /> <link rel="stylesheet" type="text/css" href="index.css" />
@ -30,37 +30,46 @@
<script type="text/javascript" src="sae/cpu.js"></script> <script type="text/javascript" src="sae/cpu.js"></script>
<script type="text/javascript" src="sae/amiga.js"></script> <script type="text/javascript" src="sae/amiga.js"></script>
<script type="text/javascript" src="index.js"></script> <script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="ga.js"></script> <script type="text/javascript" src="ga.js"></script>
</head> </head>
<body onload="init()"> <body onload="init()">
<div id="base"> <div id="base">
<div id="head" class="head"> <div id="head" class="head">
<div style="height:8px"></div>
<img src="images/logo.png" alt="Scripted Amiga Emulator" />
<noscript> <noscript>
<div class="noscript">This site does require javascript, obviously :)</div> <div class="noscript">This site does require javascript, obviously :)</div>
</noscript> </noscript>
<div class="hr"></div> <div style="height:8px"></div>
</div> <img src="images/logo.png" alt="Scripted Amiga Emulator" />
<div class="acmsg" style="line-height:16px">
<div style="height:20px"></div> <i>Experimental</i> <a href="javascript:openNewTab('http://en.wikipedia.org/wiki/Amiga')">Amiga</a> emulator in pure JavaScript and HTML5<br />
based on <a href="javascript:openNewTab('http://www.amigaemulator.org')">UAE</a>/<a href="javascript:openNewTab('http://winuae.net')">WinUAE</a>,
<div id="config"> powered by <a href="javascript:openNewTab('http://aros.org')">AROS</a>
<div id="config_simple"> </div>
<div class="arm"> </div>
<button class="button" onclick="switchCfg(1)">Advanced</button> <div style="height:8px"></div>
</div> <div id="config">
<div style="line-height:20px"> <div id="config_simple">
<h3>Welcome!</h3>
This site is a demonstration of the '<a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">SAE</a>' project,
an experimental <a href="javascript:openNewTab('http://en.wikipedia.org/wiki/Amiga')">Amiga</a> emulator in pure javascript and HTML5.<br />
For details, please refer to the <a href="javascript:openNewTab('readme.htm')">readme</a> file.<br /><br />
Below you find a small collection of games and demos to play...<br />
<span class="info">(Use Google Chrome for best results)</span>
</div>
<div style="height:20px"></div>
<div class="config_simple_hof"> <div class="config_simple_hof">
<div class="acm">
<span class="fwb">Browser</span>
</div>
<table>
<tr>
<td class="arms">Supported video-modes:</td>
<td><span id="info_video">-</span></td>
</tr>
<tr>
<td class="arms">Supported audio-modes:</td>
<td><span id="info_audio">-</span></td>
</tr>
<tr>
<td class="arms">SAE-Version:</td>
<td><span id="info_version">-</span></td>
</tr>
</table>
<div style="height:10px"></div>
<div class="hr"></div>
<div style="height:10px"></div>
<div class="acm"> <div class="acm">
<span class="fwb">Hall of fame</span> <span class="fwb">Hall of fame</span>
</div> </div>
@ -82,13 +91,17 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="arms">Audio</td> <td class="arms">Audio/Video</td>
<td><input id="cfg_audio_enabled_1" type="checkbox" checked="checked" /></td> <td><input id="cfg_audio_enabled_1" type="checkbox" checked="checked" /><input id="cfg_video_enabled_1" type="checkbox" checked="checked" /></td>
</tr>
<tr>
<td class="arms">Frameskip</td>
<td><input id="cfg_video_skip_1" type="checkbox" checked="checked" /><span class="info">(25 instead of 50 fps)</span></td>
</tr> </tr>
<tr> <tr>
<td class="arms">Scale 4x</td> <td class="arms">Extra scale</td>
<td><input id="cfg_video_scale_1" type="checkbox" /><span class="info">(1140 x 1152, press F11 for fullscreen)</span></td> <td><input id="cfg_video_scale_1" type="checkbox" /><span class="info">(double video-size via hardware)</span></td>
</tr> </tr>
</table> </table>
<div class="hr"></div> <div class="hr"></div>
<table id="cfg_info"> <table id="cfg_info">
@ -116,28 +129,43 @@
<div style="height:10px"></div> <div style="height:10px"></div>
<div class="acm"> <div class="acm">
<button class="sbutton" id="cfg_simple_start" onclick="simpleStart()">Play</button> <button class="sbutton" id="cfg_simple_start" onclick="simpleStart()">Play</button>
<button class="button" onclick="switchCfg(1)">Config</button>
</div> </div>
</div> </div>
</div> </div>
<div id="config_advanced"> <div id="config_advanced">
<div class="arm"> <div class="acm"><button class="button" onclick="switchCfg(0)">Back</button></div>
<button class="button" onclick="switchCfg(0)">Simple</button>
</div>
<table> <table>
<tr> <tr>
<td class="armsb">CPU</td> <td class="armsb">CPU</td>
<td class="bl"> <td class="bl">
<table class="wauto"> Speed
<tr> <select id="cfg_cpu_speed" size="1">
<td class="arm">Speed:</td> <option value="0">Original</option>
<td> <option value="-1">Maximum</option>
<select id="cfg_cpu_speed" size="1"> </select>
<option value="0">Original</option> </td>
<option value="-1">Maximum</option> </tr>
</select> <tr>
</td> <td class="armsb">Chipset</td>
</tr> <td class="bl">
</table> Type
<select id="cfg_chipset_type" size="1">
<option value="1">Original Chip Set (OCS Agnus)</option>
<option value="2">Enhanced Chip Set (ECS Agnus only)</option>
<option value="3">Enhanced Chip Set (ECS Agnus, ECS Denise)</option>
</select><br />
<input id="cfg_chipset_cl_enabled" type="checkbox" onchange="spritesUpdate()" />Collisions
<span id="cfg_chipset_cl_grp">
<select id="cfg_chipset_cl" size="1">
<option value="1">Sprites only</option>
<option value="2">Sprites & Playfield (recommended)</option>
<option value="3">Full</option>
</select>
</span><br />
<input id="cfg_video_ntsc" type="checkbox" />NTSC<br />
<input id="cfg_chipset_agnus_dip" type="checkbox" />A1000 OCS Agnus (8361/8367)<br />
<input id="cfg_blitter_immediate" type="checkbox" />Blit immediate
</td> </td>
</tr> </tr>
<tr> <tr>
@ -309,14 +337,13 @@
<option value="500">5x</option> <option value="500">5x</option>
<option value="1000">10x</option> <option value="1000">10x</option>
</select> </select>
<span class="gray"> ('Turbo' mode is fastest, but not very compatible)</span> <span class="gray"> ('Turbo' mode is fastest, but not always compatible. All other modes are very slow)</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="armsb">Audio</td> <td class="armsb">Audio</td>
<td class="bl"> <td class="bl">
<input id="cfg_audio_enabled" type="checkbox" onchange="audioUpdate()" /> <input id="cfg_audio_enabled" type="checkbox" onchange="audioUpdate()" />Enabled
Enabled
<table id="cfg_audio_grp" class="wauto"> <table id="cfg_audio_grp" class="wauto">
<tr> <tr>
<td class="arm">Mode:</td> <td class="arm">Mode:</td>
@ -327,17 +354,6 @@
<option value="2">On (best)</option> <option value="2">On (best)</option>
</select> </select>
</td> </td>
</tr>
<tr>
<td class="arm">Channels:</td>
<td>
<select id="cfg_audio_channels" size="1">
<option value="1">1 - Mono</option>
<option value="2">2 - Stereo</option>
</select>
</td>
</tr>
<tr>
<td class="arm">Samplerate:</td> <td class="arm">Samplerate:</td>
<td> <td>
<select id="cfg_audio_rate" size="1"> <select id="cfg_audio_rate" size="1">
@ -349,36 +365,45 @@
Hz Hz
</td> </td>
</tr> </tr>
<tr>
<td class="arm">Channels:</td>
<td>
<select id="cfg_audio_channels" size="1">
<option value="1">1 - Mono</option>
<option value="2">2 - Stereo</option>
</select>
</td>
<td class="arm">Lowpass-filter:</td>
<td><input id="cfg_audio_filter" type="checkbox" /></td>
</tr>
</table> </table>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="armsb">Video</td> <td class="armsb">Video</td>
<td class="bl"> <td class="bl">
<input id="cfg_video_enabled" type="checkbox" onchange="videoUpdate()" /> <input id="cfg_video_enabled" type="checkbox" onchange="videoUpdate()" />Enabled
Enabled <div id="cfg_video_grp">
<div id="cfg_video_grp"> <!--Driver
<input id="cfg_chipset_cl_enabled" type="checkbox" onchange="spritesUpdate()" /> <select id="cfg_video_mode" size="1">
Sprite collisions <option value="1">Canvas 2D</option>
<span id="cfg_chipset_cl_grp"> <option value="2">WebGL</option>
<select id="cfg_chipset_cl" size="1"> </select><br />
<option value="1">Sprite/Sprite</option> H-Resolution
<option value="2">Sprite/Sprite + Sprite/Playfield</option> <select id="cfg_video_hres" size="1">
</select> <option value="0">320 pixel (Lores)</option>
</span> <option value="1">640 pixel (Hires)</option>
<br /> <option value="2">1280 pixel (SuperHires, ECS)</option>
<input id="cfg_video_scale" type="checkbox" /> </select><br />
Scale 4x <span class="gray">(1440 x 1152)</span> V-Resolution
<br /> <select id="cfg_video_vres" size="1">
<input id="cfg_video_ntsc" type="checkbox" /> <option value="0">200/256 pixel (Normal)</option>
NTSC <option value="1">400/512 pixel (Double)</option>
<br /> <option value="2">400/512 pixel (Scanlines)</option>
<input id="cfg_video_skip" type="checkbox" /> </select><br />-->
Frameskip<span class="gray"> (if the emulation is too slow, up to 4 frames will be skipped)</span> <input id="cfg_video_skip" type="checkbox" />Frameskip <span class="gray">(25 instead of 50 fps)</span><br />
<!--<br /> <input id="cfg_video_scale" type="checkbox" />Extra scale <span class="gray">(double video-size via hardware)</span>
<input id="cfg_video_drop" type="checkbox" /> </div>
Framedrop<span class="gray"> (if the emulation is too fast, a (unprecise) delay is initiated)</span>-->
</div>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -559,15 +584,14 @@
<div class="acm"> <div class="acm">
<button class="sbutton" id="cfg_start" onclick="advandedStart()">Start</button> <button class="sbutton" id="cfg_start" onclick="advandedStart()">Start</button>
</div> </div>
</div> </div>
</div> </div>
<div style="height:6px"></div>
<div style="height:10px"></div> <div id="foot" class="foot" style="line-height:14px">
<div id="foot" class="foot"> <span class="gray">2012-2013 Rupert Hausberger</span> |
<span class="gray">&#169;2012-2013 Rupert Hausberger</span> | <a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">Source-code</a> |
<a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">Source</a> | <a href="javascript:openNewTab('readme.htm')">Description</a>
<a href="javascript:openNewTab('readme.htm')">Readme</a> </div>
</div>
</div> </div>
<div id="emul"> <div id="emul">

412
index.js
View file

@ -13,219 +13,242 @@
**************************************************************************/ **************************************************************************/
const db = [ const db = [
/* name company year [disks] change [en,f1,f2,map] load [keys] */ /* name company year [disks] [change, turbo] [en,f1,f2,map] load [keys] immediate */
[ [
['Agony', 'Psygnosis', '1992', ['Agony', 'Psygnosis', '1992',
['Agony (Disk 1).adf', ['Agony (Disk 1).adf',
'Agony (Disk 2).adf', 'Agony (Disk 2).adf',
'Agony (Disk 3).adf', 'Agony (Disk 3).adf',
false], false, false], [false, true],
[true, 16, 17, false], [true, 16, 17, false],
['Press the LMB to skip the intro.'], [['Weapon menu', 'Space']] ['Press the LMB to skip the intro.'], [['Weapon menu', 'Space']], false
], ],
['Alien Breed', 'Team 17', '1991', ['Alien Breed', 'Team 17', '1991',
['Alien Breed (Disk 1).adf', ['Alien Breed (Disk 1).adf',
'Alien Breed (Disk 2).adf', 'Alien Breed (Disk 2).adf',
false, false], true, false, false], [true, true],
[true, 16, 17, false], [true, 16, 17, false],
['Insert the 2nd disk manualy and HOLD the fire button.'], [['Show map', 'M']] ['Insert the 2nd disk manualy and HOLD the fire button.'], [['Show map', 'M']], false
],
['Alien Breed II - The Horror Continues', 'Team 17', '1993',
['Alien Breed II - The Horror Continues (Disk 1).adf',
'Alien Breed II - The Horror Continues (Disk 2).adf',
'Alien Breed II - The Horror Continues (Disk 3).adf', false], [false, false],
[true, 16, 17, false],
['Press the LMB to skip the intro.'], [['Show map', 'M']], false
], ],
['Alien Breed - Tower Assault', 'Team 17', '1994', ['Alien Breed - Tower Assault', 'Team 17', '1994',
['Alien Breed - Tower Assault (Disk 1).adf', ['Alien Breed - Tower Assault (Disk 1).adf',
'Alien Breed - Tower Assault (Disk 2).adf', 'Alien Breed - Tower Assault (Disk 2).adf',
'Alien Breed - Tower Assault (Disk 3).adf', 'Alien Breed - Tower Assault (Disk 3).adf',
'Alien Breed - Tower Assault (Disk 4).adf'], false, 'Alien Breed - Tower Assault (Disk 4).adf'], [false, true],
[true, 8, 17, false], [true, 8, 17, false],
['Press ESC to skip the intro.'], [['Show map', 'M']] ['Press ESC to skip the intro.'], [['Show map', 'M']], false
], ],
['Another World', 'Delphine - U.S. Gold', '1991', /*['Another World', 'Delphine - U.S. Gold', '1991',
['Another World (Disk 1).adf', ['Another World (Disk 1).adf',
'Another World (Disk 2).adf', 'Another World (Disk 2).adf',
false, false], false, false, false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], ['Select 2x OK when asked.'], [], true
], ],*/
['Blood Money', 'DMA Design', '1989', ['Blood Money', 'DMA Design', '1989',
['Blood Money (Disk 1).adf', ['Blood Money (Disk 1).adf',
'Blood Money (Disk 2).adf', 'Blood Money (Disk 2).adf',
false, false], true, false, false], [true, false],
[true, 16, 17, false], [true, 16, 17, false],
['Press the LMB until the main-nemu<br />and insert the 2nd disk manualy.'], [] ['Press the LMB until the main-nemu<br />and insert the 2nd disk manualy.'], [], false
], ],
['Body Blows Galactic', 'Team 17', '1993', ['Body Blows Galactic', 'Team 17', '1993',
['Body Blows Galactic (Disk 1).adf', ['Body Blows Galactic (Disk 1).adf',
'Body Blows Galactic (Disk 2).adf', 'Body Blows Galactic (Disk 2).adf',
'Body Blows Galactic (Disk 3).adf', 'Body Blows Galactic (Disk 3).adf',
false], false, false], [false, false],
[true, 16, 17, false], ['Press the LMB to skip the intro.'], [] [true, 16, 17, false], ['Press the LMB to skip the intro.'], [], false
], ],
['Dyna Blaster', 'Ubi Soft', '1992', /*['Dyna Blaster', 'Ubi Soft', '1992',
['Dyna Blaster.adf', ['Dyna Blaster.adf',
false, false, false], false, false, false, false], [false, false],
[true, 16, 17, false], ['Press the LMB to skip the intro.'], [] [true, 16, 17, false], ['Press the LMB to skip the intro.'], [], false
],*/
['Lemmings', 'Psygnosis', '1991',
['Lemmings (Disk 1).adf',
'Lemmings (Disk 2).adf',
false, false], [false, true],
[false, 0, 0, false], [], [['with','Mouse']], false
], ],
['Lotus Turbo Challenge 2', 'Gremlin', '1991', ['Lotus Turbo Challenge 2', 'Gremlin', '1991',
['Lotus Turbo Challenge 2.adf', ['Lotus Turbo Challenge 2.adf',
false, false, false], false, false, false, false], [false, true],
[true, 16, 17, false], ['Press the LMB to skip the intro.'], [] [true, 16, 17, false], ['Press the LMB to skip the intro.'], [], false
],
['Pac-Mania', 'Grandslam', '1988',
['Pac-Mania.adf',
false, false, false], [false, true],
[true, 16, 17, false], [], [], false
], ],
['Pinball Dreams', 'DICE', '1992', ['Pinball Dreams', 'DICE', '1992',
['Pinball Dreams (Disk 1).adf', ['Pinball Dreams (Disk 1).adf',
'Pinball Dreams (Disk 2).adf', 'Pinball Dreams (Disk 2).adf',
false, false], false, false, false], [false, true],
[false, 0, 0, true], [], [['Select table','F1-F4'],['Start game','F1-F8'],['Shoot Ball','Down-Arrow'],['Flip','L/R-Arrows'],['Shake table','Space'],['Change table','ESC and then y/z'],['En/Disable music','M']] [false, 0, 0, true], [], [['Select table','F1-F4'],['Start game','F1-F8'],['Shoot Ball','Down-Arrow'],['Flip','L/R-Arrows'],['Shake table','Space'],['Change table','ESC and then y/z'],['En/Disable music','M']], false
], ],
/*['Pinball Fantasies', 'DICE', '1992', ['Pinball Fantasies', 'DICE', '1992',
['Pinball Fantasies (Disk 1).adf', ['Pinball Fantasies (Disk 1).adf',
'Pinball Fantasies (Disk 2).adf',
'Pinball Fantasies (Disk 3).adf', 'Pinball Fantasies (Disk 3).adf',
false, false], true, false], [true, true],
[false, 0, 0, true], [false, 0, 0, true],
['When asked to remove write protection from disk, press the LMB.'], ['When asked to remove write protection from disk, press the LMB.'],
[['Select table','F1-F4'],['Start game','F1-F8'],['Shoot Ball','Down-Arrow'],['Flip','L/R-Arrows'],['Shake table','Space'],['Change table','ESC and then y/z'],['En/Disable music','M']] [['Select table','F1-F4'],['Start game','F1-F8'],['Shoot Ball','Down-Arrow'],['Flip','L/R-Arrows'],['Shake table','Space'],['Change table','ESC and then y/z'],['En/Disable music','M']], false
],*/ ],
['Prince of Persia', 'Domark', '1991', ['Prince of Persia', 'Domark', '1991',
['Prince of Persia.adf', ['Prince of Persia.adf',
false, false, false], false, false, false, false], [false, true],
[true, 16, 17, false], ['Press the LMB to skip the intro.'], [] [true, 16, 17, false], ['Press the LMB to skip the intro.'], [], false
], ],
['Project-X - Special Edition 93', 'Team 17', '1993', ['Project-X - Special Edition 93', 'Team 17', '1993',
['Project-X - Special Edition 93 (Disk 1).adf', ['Project-X - Special Edition 93 (Disk 1).adf',
'Project-X - Special Edition 93 (Disk 2).adf', 'Project-X - Special Edition 93 (Disk 2).adf',
'Project-X - Special Edition 93 (Disk 3).adf', 'Project-X - Special Edition 93 (Disk 3).adf',
false], false, false], [false, true],
[true, 16, 17, false], [true, 16, 17, false],
['Press the LMB to skip the intro.'], [['Select weapon', 'Space (not in trainer mode)']] ['Press the LMB to skip the intro.'], [['Select weapon', 'Space (not in trainer mode)']], false
], ],
['Rick Dangerous', 'Firebird', '1989', ['Rick Dangerous', 'Firebird', '1989',
['Rick Dangerous.adf', ['Rick Dangerous.adf',
false, false, false], false, false, false, false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Shadow of the Beast II', 'Reflections', '1990', ['Shadow of the Beast II', 'Reflections', '1990',
['Shadow of the Beast II (Disk 1).adf', ['Shadow of the Beast II (Disk 1).adf',
'Shadow of the Beast II (Disk 2).adf', 'Shadow of the Beast II (Disk 2).adf',
'Shadow of the Beast II (Disk 3).adf', 'Shadow of the Beast II (Disk 3).adf',
false], true, false], [true, true],
[true, 16, 17, false], [true, 16, 17, false],
['Change the disks manualy when asked.'], [] ['Change the disks manualy when asked.'], [], false
], ],
['Superfrog', 'Team 17', '1993', ['Superfrog', 'Team 17', '1993',
['Superfrog (Disk 1).adf', ['Superfrog (Disk 1).adf',
'Superfrog (Disk 2).adf', 'Superfrog (Disk 2).adf',
'Superfrog (Disk 3).adf', 'Superfrog (Disk 3).adf',
'Superfrog (Disk 4).adf'], true, 'Superfrog (Disk 4).adf'], [true, false],
[true, 16, 17, false], [true, 16, 17, false],
['Change the disks manualy when asked.'], [] ['Change the disks manualy when asked.'], [], false
], ],
/*['Terminator 2 - Judgment Day', 'Ocean', '1991', ['Terminator 2 - Judgment Day', 'Ocean', '1991',
['Terminator 2 - Judgment Day (Disk 1).adf', ['Terminator 2 - Judgment Day (Disk 1).adf',
'Terminator 2 - Judgment Day (Disk 2).adf', 'Terminator 2 - Judgment Day (Disk 2).adf',
false, false], true, false, false], [true, false],
[true, 16, 17, false], [true, 16, 17, false],
['Press the LMB to skip the intro<br />and insert the 2nd disk manualy.'], [] ['Press the LMB to skip the intro<br />and insert the 2nd disk manualy.'], [], true
],*/ ],
['Turrican II - The Final Fight', 'Rainbow Arts', '1991', ['Turrican II - The Final Fight', 'Rainbow Arts', '1991',
['Turrican II - The Final Fight (Disk 1).adf', ['Turrican II - The Final Fight (Disk 1).adf',
'Turrican II - The Final Fight (Disk 2).adf', 'Turrican II - The Final Fight (Disk 2).adf',
false, false], false, false, false], [false, true],
[true, 16, 17, false], [], [['Fire-beam','Hold Fire 1'],['Roll on floor', 'Down-arrow + Fire 1'],['Bomb', 'Fire 2'],['Super-Bomb', 'Fire 1 + Fire 2']] [true, 16, 17, false], [], [['Fire-beam','Hold Fire 1'],['Roll on floor', 'Down-arrow + Fire 1'],['Bomb', 'Fire 2'],['Super-Bomb', 'Fire 1 + Fire 2']], false
], ],
['Wings of Death', 'Thalion', '1990', ['Wings of Death', 'Thalion', '1990',
['Wings of Death (Disk 1).adf', ['Wings of Death (Disk 1).adf',
'Wings of Death (Disk 2).adf', 'Wings of Death (Disk 2).adf',
false, false], true, false, false], [true, true],
[true, 16, 17, false], [true, 16, 17, false],
['Press the LMB until the main-nemu<br />and insert the 2nd disk manualy.'], [] ['Press the LMB until the main-menu<br />and insert the 2nd disk manualy.'], [], false
], ],
], ],
[ [
['242', 'Virtual Dreams', '1992', ['242', 'Virtual Dreams', '1992',
['242.adf',false,false,false], false, ['242.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['9 Fingers', 'Spaceballs', '1993', ['9 Fingers', 'Spaceballs', '1993',
['9 Fingers (Disk 1).adf', ['9 Fingers (Disk 1).adf',
'9 Fingers (Disk 2).adf',false,false], false, '9 Fingers (Disk 2).adf',false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Alpha and Omega', 'Pure Metal Coders', '1991', ['Alpha and Omega', 'Pure Metal Coders', '1991',
['Alpha and Omega.adf', ['Alpha and Omega.adf',
false,false,false], true, false,false,false], [false, false],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Copper Master', 'Angels', '1990', ['Copper Master', 'Angels', '1990',
['Copper Master.adf',false,false,false], false, ['Copper Master.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Deja Vu', 'Anarchy', '1992', ['Deja Vu', 'Anarchy', '1992',
['Deja Vu.adf',false,false,false], false, ['Deja Vu.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Elysium', 'Sanity', '1991', ['Elysium', 'Sanity', '1991',
['Elysium.adf',false,false,false], false, ['Elysium.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Ecliptica', 'TRSI', '1991', ['Ecliptica', 'TRSI', '1991',
['Ecliptica.adf',false,false,false], false, ['Ecliptica.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Enigma', 'Phenomena', '1991', ['Enigma', 'Phenomena', '1991',
['Enigma.adf',false,false,false], false, ['Enigma.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Global Trash', 'Silents', '1992', ['Global Trash', 'Silents', '1992',
['Global Trash.adf',false,false,false], false, ['Global Trash.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Hardwired', 'Crionics, Silents', '1992', ['Hardwired', 'Crionics, Silents', '1992',
['Hardwired (Disk 1).adf', ['Hardwired (Disk 1).adf',
'Hardwired (Disk 2).adf', 'Hardwired (Disk 2).adf',
false,false], true, false,false], [true, true],
[true, 16, 17, false], [true, 16, 17, false],
['Insert the 2nd disk manualy,<br />click RMB when done.'], [] ['Insert the 2nd disk manualy,<br />click RMB when done.'], [], true
], ],
['Ice', 'Silents', '1991', ['Ice', 'Silents', '1991',
['Ice.adf',false,false,false], false, ['Ice.adf',false,false,false], [false, true],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [] [true, 16, 17, false], ['Press LMB at the intro-screen'], [], false
], ],
['Lost World', 'Balance DK', '1992', ['Lost World', 'Balance DK', '1992',
['Lost World.adf',false,false,false], false, ['Lost World.adf',false,false,false], [false, true],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [] [true, 16, 17, false], ['Press LMB at the intro-screen'], [], false
], ],
['Mental Hangover', 'Scoopex', '1992', ['Mental Hangover', 'Scoopex', '1992',
['Mental Hangover.adf',false,false,false], false, ['Mental Hangover.adf',false,false,false], [false, true],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [] [true, 16, 17, false], [], [], false
], ],
['Multica', 'Andromeda', '1992', ['Multica', 'Andromeda', '1992',
['Multica.adf',false,false,false], false, ['Multica.adf',false,false,false], [false, true],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [] [true, 16, 17, false], ['Press LMB at the intro-screen'], [], false
], ],
['Project-X (demo rolling)', 'Team 17', '1992', ['Project-X (demo rolling)', 'Team 17', '1992',
['Project-X (demo-rolling).adf',false,false,false], false, ['Project-X (demo-rolling).adf',false,false,false], [false, true],
[true, 16, 17, false], [], [['Skip level','Fire']] [true, 16, 17, false], [], [['Skip level','Fire']], false
], ],
['Rampage', 'TEK', '1994', ['Rampage', 'TEK', '1994',
['Rampage.adf',false,false,false], false, ['Rampage.adf',false,false,false], [false, false],
[true, 16, 17, false], ['Press LMB at the intro-screen'], [] [true, 16, 17, false], ['Press LMB at the intro-screen'], [], false
], ],
['State of the Art', 'Spaceballs', '1992', ['State of the Art', 'Spaceballs', '1992',
['State of the Art.adf',false,false,false], false, ['State of the Art.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Static Chaos', 'Silents', '1992', ['Static Chaos', 'Silents', '1992',
['Static Chaos.adf',false,false,false], false, ['Static Chaos.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
],
['Technological Death', 'Mad Elks', '1993',
['Technological Death.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [], true
], ],
['Total Destruction', 'Crionics', '1990', ['Total Destruction', 'Crionics', '1990',
['Total Destruction.adf',false,false,false], false, ['Total Destruction.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['Wayfarer', 'Spaceballs', '1992', ['Wayfarer', 'Spaceballs', '1992',
['Wayfarer.adf',false,false,false], false, ['Wayfarer.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
['World of Commodore', 'Sanity', '1992', ['World of Commodore', 'Sanity', '1992',
['World of Commodore.adf',false,false,false], false, ['World of Commodore.adf',false,false,false], [false, true],
[true, 16, 17, false], [], [] [true, 16, 17, false], [], [], false
], ],
] ]
]; ];
@ -247,11 +270,18 @@ var dskchg = false;
var dskchgList = []; var dskchgList = [];
var cache = null; var cache = null;
var info = null;
var config = null; var config = null;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
function dechex(dec) { return dec.toString(16); } function urldecode(url) {
return decodeURIComponent(url.replace(/\+/g, ' '));
}
function dechex(dec) {
return dec.toString(16);
}
function Cache() { function Cache() {
var roms = [null,null]; var roms = [null,null];
@ -488,6 +518,32 @@ function loadRemoteSync(url) {
/* simple config */ /* simple config */
function setSimpleConfig() { function setSimpleConfig() {
//document.getElementById('info_name').innerHTML = info.browser_name+' '+info.browser_version+' ('+info.os+')';
var e = document.getElementById('info_video');
if (info.video) {
var t = '';
if (info.video & SAEI_Video_WebGL) t += 'WebGL, ';
if (info.video & SAEI_Video_Canvas2D) t += 'Canvas, ';
e.innerHTML = t.substr(0, t.length - 2);
e.style.color = (info.video & SAEI_Video_WebGL) ? 'green' : 'orange';
} else {
e.innerHTML = 'None';
e.style.color = 'orange';
}
e = document.getElementById('info_audio');
if (info.audio) {
var t = '';
if (info.audio & SAEI_Audio_Webkit) t += 'Webkit, ';
if (info.audio & SAEI_Audio_Mozilla) t += 'Mozilla, ';
e.innerHTML = t.substr(0, t.length - 2);
e.style.color = 'green';
} else {
e.innerHTML = 'None';
e.style.color = 'orange';
}
e = document.getElementById('info_version').innerHTML = info.version;
var s = document.getElementById('cfg_game'); var s = document.getElementById('cfg_game');
if (s.length == 1) { if (s.length == 1) {
for (var i = 0; i < db[0].length; i++) { for (var i = 0; i < db[0].length; i++) {
@ -507,7 +563,9 @@ function setSimpleConfig() {
} }
} }
styleDisplayBlock('config_simple', 1); styleDisplayBlock('config_simple', 1);
document.getElementById('cfg_audio_enabled_1').checked = true; document.getElementById('cfg_audio_enabled_1').checked = config.audio.enabled;
document.getElementById('cfg_video_enabled_1').checked = config.video.enabled;
document.getElementById('cfg_video_skip_1').checked = config.video.framerate != 1;
document.getElementById('cfg_video_scale_1').checked = false; document.getElementById('cfg_video_scale_1').checked = false;
unselect(document.getElementById('cfg_demo')); unselect(document.getElementById('cfg_demo'));
unselect(document.getElementById('cfg_game')); unselect(document.getElementById('cfg_game'));
@ -519,13 +577,11 @@ function setSimpleConfig() {
function getSimpleFloppy() { function getSimpleFloppy() {
//console.log('loadDisks() %d %d', dbGrp, dbNum); //console.log('loadDisks() %d %d', dbGrp, dbNum);
config.floppy.speed = 1000; /* 1000 percent == x10 */ if (dbNum == 0) { /* nothing selected */
if (dbNum == 0) {
config.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD; config.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD;
config.floppy.drive[0].name = null; config.floppy.drive[0].name = null;
config.floppy.drive[0].data = null; config.floppy.drive[0].data = null;
config.floppy.drive[1].type = SAEV_Config_Floppy_Type_35_DD; config.floppy.drive[1].type = SAEV_Config_Floppy_Type_None;
config.floppy.drive[1].name = null; config.floppy.drive[1].name = null;
config.floppy.drive[1].data = null; config.floppy.drive[1].data = null;
config.floppy.drive[2].type = SAEV_Config_Floppy_Type_None; config.floppy.drive[2].type = SAEV_Config_Floppy_Type_None;
@ -534,6 +590,7 @@ function getSimpleFloppy() {
config.floppy.drive[3].type = SAEV_Config_Floppy_Type_None; config.floppy.drive[3].type = SAEV_Config_Floppy_Type_None;
config.floppy.drive[3].name = null; config.floppy.drive[3].name = null;
config.floppy.drive[3].data = null; config.floppy.drive[3].data = null;
config.floppy.speed = SAEV_Config_Floppy_Speed_Original;
return true; return true;
} }
@ -548,7 +605,7 @@ function getSimpleFloppy() {
dskchgList = []; dskchgList = [];
if (item[4]) { if (item[4][0]) {
var i, filename, url; var i, filename, url;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -594,21 +651,26 @@ function getSimpleFloppy() {
} }
} }
} }
config.floppy.speed = item[4][1] ? SAEV_Config_Floppy_Speed_Turbo : SAEV_Config_Floppy_Speed_Original;
return true; return true;
} }
function getSimpleConfig() { function getSimpleConfig() {
var item = dbNum > 0 ? db[dbGrp - 1][dbNum - 1] : null; var item = dbNum > 0 ? db[dbGrp - 1][dbNum - 1] : null;
var e, num;
config.cpu.speed = SAEV_Config_CPU_Speed_Original; config.cpu.speed = SAEV_Config_CPU_Speed_Original;
//config.cpu.speed = SAEV_Config_Floppy_Speed_Turbo; config.cpu.compatible = true;
//config.chipset.type = SAEV_Config_Chipset_Type_OCS; config.chipset.mask = SAEV_Config_Chipset_Mask_OCS;
config.chipset.colLevel = SAEV_Config_Chipset_ColLevel_None; config.chipset.agnus_dip = false; /* A1000 */
config.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None;
config.blitter.immediate = (item !== null && item[8]) ? true : false;
config.blitter.waiting = config.blitter.immediate ? 0 : 1;
config.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K; config.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K;
config.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K; config.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K;
config.ram.fast.size = SAEV_Config_RAM_Fast_Size_512K; config.ram.fast.size = SAEV_Config_RAM_Fast_Size_1M;
config.rom.name = aros_rom_file; config.rom.name = aros_rom_file;
config.rom.size = SAEV_Config_ROM_Size_512K; config.rom.size = SAEV_Config_ROM_Size_512K;
@ -624,21 +686,22 @@ function getSimpleConfig() {
if (!getSimpleFloppy()) if (!getSimpleFloppy())
return false; return false;
e = document.getElementById('cfg_audio_enabled_1'); config.audio.enabled = document.getElementById('cfg_audio_enabled_1').checked ? true : false;
config.audio.enabled = e.checked ? true : false;
if (config.audio.enabled) { if (config.audio.enabled) {
config.audio.mode = SAEV_Config_Audio_Mode_Play_Best; config.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
config.audio.channels = SAEV_Config_Audio_Channels_Stereo; config.audio.channels = SAEV_Config_Audio_Channels_Stereo;
//config.audio.rate = SAEV_Config_Audio_Rate_48000;
config.audio.rate = SAEV_Config_Audio_Rate_44100; config.audio.rate = SAEV_Config_Audio_Rate_44100;
} }
/*if (info.audio == 0) {
config.audio.enabled = false;
document.getElementById('cfg_audio_enabled_1').checked = config.audio.enabled;
}*/
config.video.enabled = true;
e = document.getElementById('cfg_video_scale_1');
config.video.scale = e.checked ? true : false;
config.video.ntsc = false;
config.video.skip = true;
config.video.id = 'myVideo'; config.video.id = 'myVideo';
config.video.enabled = document.getElementById('cfg_video_enabled_1').checked ? true : false;
config.video.scale = document.getElementById('cfg_video_scale_1').checked ? true : false;
config.video.framerate = document.getElementById('cfg_video_skip_1').checked ? 2 : 1;
config.video.ntsc = false;
config.keyboard.enabled = true; config.keyboard.enabled = true;
config.keyboard.mapShift = (item !== null && item[5][3]) ? true : false; config.keyboard.mapShift = (item !== null && item[5][3]) ? true : false;
@ -667,6 +730,7 @@ function getSimpleConfig() {
config.hooks.floppy_step = hooks_floppy_step; config.hooks.floppy_step = hooks_floppy_step;
config.hooks.fps = hooks_fps; config.hooks.fps = hooks_fps;
config.hooks.cpu = hooks_cpu; config.hooks.cpu = hooks_cpu;
return true; return true;
} }
@ -777,8 +841,24 @@ function setConfig() {
switch (config.cpu.speed) { switch (config.cpu.speed) {
case SAEV_Config_CPU_Speed_Original: e[0].selected = true; break; case SAEV_Config_CPU_Speed_Original: e[0].selected = true; break;
case SAEV_Config_CPU_Speed_Maximum: e[1].selected = true; break; case SAEV_Config_CPU_Speed_Maximum: e[1].selected = true; break;
} }
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_ECS_DENISE: e[2].selected = true; break
}
document.getElementById('cfg_chipset_cl_enabled').checked = config.chipset.collision_level != SAEV_Config_Chipset_ColLevel_None;
switch (config.chipset.collision_level) {
case SAEV_Config_Chipset_ColLevel_Sprite_Sprite: document.getElementById('cfg_chipset_cl')[0].selected = true; break;
case SAEV_Config_Chipset_ColLevel_Sprite_Playfield: document.getElementById('cfg_chipset_cl')[1].selected = true; break;
case SAEV_Config_Chipset_ColLevel_Full: document.getElementById('cfg_chipset_cl')[2].selected = true; break;
}
document.getElementById('cfg_chipset_agnus_dip').checked = config.chipset.agnus_dip != 0;
document.getElementById('cfg_blitter_immediate').checked = config.blitter.immediate != 0;
styleDisplayInline('cfg_chipset_cl_grp', config.chipset.collision_level != SAEV_Config_Chipset_ColLevel_None);
var e = document.getElementById('cfg_mem_chip'); var e = document.getElementById('cfg_mem_chip');
switch (config.ram.chip.size) { switch (config.ram.chip.size) {
case SAEV_Config_RAM_Chip_Size_256K: e[0].selected = true; break; case SAEV_Config_RAM_Chip_Size_256K: e[0].selected = true; break;
@ -839,18 +919,13 @@ function setConfig() {
case SAEV_Config_Audio_Rate_44100: document.getElementById('cfg_audio_rate')[2].selected = true; break; case SAEV_Config_Audio_Rate_44100: document.getElementById('cfg_audio_rate')[2].selected = true; break;
case SAEV_Config_Audio_Rate_48000: document.getElementById('cfg_audio_rate')[3].selected = true; break; case SAEV_Config_Audio_Rate_48000: document.getElementById('cfg_audio_rate')[3].selected = true; break;
} }
document.getElementById('cfg_audio_filter').checked = config.audio.filter != 0;
styleDisplayTable('cfg_audio_grp', config.audio.enabled); styleDisplayTable('cfg_audio_grp', config.audio.enabled);
document.getElementById('cfg_video_enabled').checked = config.video.enabled != 0; document.getElementById('cfg_video_enabled').checked = config.video.enabled != 0;
document.getElementById('cfg_chipset_cl_enabled').checked = config.chipset.colLevel != SAEV_Config_Chipset_ColLevel_None;
switch (config.chipset.colLevel) {
case SAEV_Config_Chipset_ColLevel_Sprite_Sprite: document.getElementById('cfg_chipset_cl')[0].selected = true; break;
case SAEV_Config_Chipset_ColLevel_Sprite_Playfield: document.getElementById('cfg_chipset_cl')[1].selected = true; break;
}
styleDisplayInline('cfg_chipset_cl_grp', config.chipset.colLevel != SAEV_Config_Chipset_ColLevel_None);
document.getElementById('cfg_video_scale').checked = config.video.scale; document.getElementById('cfg_video_scale').checked = config.video.scale;
document.getElementById('cfg_video_ntsc').checked = config.video.ntsc != 0; document.getElementById('cfg_video_ntsc').checked = config.video.ntsc != 0;
document.getElementById('cfg_video_skip').checked = config.video.skip != 0; document.getElementById('cfg_video_skip').checked = config.video.framerate != 1;
styleDisplayBlock('cfg_video_grp', config.video.enabled != 0); styleDisplayBlock('cfg_video_grp', config.video.enabled != 0);
document.getElementById('cfg_keyborad_enabled').checked = config.keyboard.enabled != 0; document.getElementById('cfg_keyborad_enabled').checked = config.keyboard.enabled != 0;
@ -892,21 +967,32 @@ function setConfig() {
styleDisplayInline('dskchg_grp', 1); styleDisplayInline('dskchg_grp', 1);
} }
function getMask(type) {
switch (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;
}
}
function getConfig() { function getConfig() {
var e; var e;
e = document.getElementById('cfg_cpu_speed'); e = document.getElementById('cfg_cpu_speed');
config.cpu.speed = parseInt(getSelectValue(e)); config.cpu.speed = parseInt(getSelectValue(e));
//e = document.getElementById('cfg_chipset_type'); e = document.getElementById('cfg_chipset_type');
//config.chipset.type = parseInt(getSelectValue(e)); config.chipset.mask = getMask(parseInt(getSelectValue(e)));
e = document.getElementById('cfg_chipset_cl_enabled'); e = document.getElementById('cfg_chipset_cl_enabled');
if (e.checked) { if (e.checked) {
e = document.getElementById('cfg_chipset_cl'); e = document.getElementById('cfg_chipset_cl');
config.chipset.colLevel = parseInt(getSelectValue(e)); config.chipset.collision_level = parseInt(getSelectValue(e));
} else } else
config.chipset.colLevel = SAEV_Config_Chipset_ColLevel_None; config.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None;
config.chipset.agnus_dip = document.getElementById('cfg_chipset_agnus_dip').checked ? true : false;
config.blitter.immediate = document.getElementById('cfg_blitter_immediate').checked ? true : false;
config.blitter.waiting = config.blitter.immediate ? 0: 1;
e = document.getElementById('cfg_mem_chip'); e = document.getElementById('cfg_mem_chip');
config.ram.chip.size = parseInt(getSelectValue(e)); config.ram.chip.size = parseInt(getSelectValue(e));
e = document.getElementById('cfg_mem_slow'); e = document.getElementById('cfg_mem_slow');
@ -918,35 +1004,31 @@ function getConfig() {
alert('No Kickstart ROM.'); alert('No Kickstart ROM.');
return false; return false;
} }
e = document.getElementById('cfg_ext_addr');
config.ext.addr = parseInt(getSelectValue(e));
e = document.getElementById('cfg_floppy_speed'); e = document.getElementById('cfg_floppy_speed');
config.floppy.speed = parseInt(getSelectValue(e)); config.floppy.speed = parseInt(getSelectValue(e));
e = document.getElementById('cfg_audio_enabled'); config.audio.enabled = document.getElementById('cfg_audio_enabled').checked ? true : false;
config.audio.enabled = e.checked ? true : false;
if (config.audio.enabled) { if (config.audio.enabled) {
e = document.getElementById('cfg_audio_mode'); e = document.getElementById('cfg_audio_mode');
config.audio.mode = parseInt(getSelectValue(e)); config.audio.mode = parseInt(getSelectValue(e));
e = document.getElementById('cfg_audio_channels'); e = document.getElementById('cfg_audio_channels');
config.audio.channels = parseInt(getSelectValue(e)); config.audio.channels = parseInt(getSelectValue(e));
e = document.getElementById('cfg_audio_rate'); e = document.getElementById('cfg_audio_rate');
config.audio.rate = parseInt(getSelectValue(e)); config.audio.rate = parseInt(getSelectValue(e));
config.audio.filter = document.getElementById('cfg_audio_filter').checked ? true : false;
} }
e = document.getElementById('cfg_video_enabled');
config.video.enabled = e.checked ? true : false;
e = document.getElementById('cfg_video_scale');
config.video.scale = e.checked ? true : false;
e = document.getElementById('cfg_video_ntsc');
config.video.ntsc = e.checked ? true : false;
e = document.getElementById('cfg_video_skip');
config.video.skip = e.checked ? true : false;
config.video.id = 'myVideo'; config.video.id = 'myVideo';
config.video.enabled = document.getElementById('cfg_video_enabled').checked ? true : false;
config.video.scale = document.getElementById('cfg_video_scale').checked ? true : false;
config.video.ntsc = document.getElementById('cfg_video_ntsc').checked ? true : false;
config.video.framerate = document.getElementById('cfg_video_skip').checked ? 2 : 1;
e = document.getElementById('cfg_keyborad_enabled'); config.keyboard.enabled = document.getElementById('cfg_keyborad_enabled').checked ? true : false;
config.keyboard.enabled = e.checked ? true : false; config.keyboard.mapShift = document.getElementById('cfg_keyborad_mapshift').checked ? true : false;
e = document.getElementById('cfg_keyborad_mapshift');
config.keyboard.mapShift = e.checked ? true : false;
e = document.getElementById('cfg_ports_0'); e = document.getElementById('cfg_ports_0');
config.ports[0].type = parseInt(getSelectValue(e)); config.ports[0].type = parseInt(getSelectValue(e));
@ -977,15 +1059,18 @@ function getConfig() {
} }
} }
e = document.getElementById('cfg_serial_enabled'); config.serial.enabled = document.getElementById('cfg_serial_enabled').checked ? true : false;
config.serial.enabled = e.checked ? true : false;
config.hooks.error = hooks_error; config.hooks.error = hooks_error;
config.hooks.power_led = hooks_power_led; config.hooks.power_led = hooks_power_led;
config.hooks.floppy_motor = hooks_floppy_motor; config.hooks.floppy_motor = hooks_floppy_motor;
config.hooks.floppy_step = hooks_floppy_step; config.hooks.floppy_step = hooks_floppy_step;
config.hooks.fps = hooks_fps; config.hooks.fps = hooks_fps;
config.hooks.cpu = hooks_cpu; config.hooks.cpu = hooks_cpu;
if (config.chipset.mask != SAEV_Config_Chipset_Mask_OCS)
config.chipset.agnus_dip = false;
return true; return true;
} }
@ -995,10 +1080,40 @@ function getConfig() {
function init() { function init() {
cache = new Cache(); cache = new Cache();
config = SAE({cmd:'init'}); SAE({cmd:'init'});
//config = SAE({cmd:'getConfig'});
info = SAE({cmd:'getInfo'});
config = SAE({cmd:'getConfig'});
//console.log(info);
//console.log(config); //console.log(config);
setSimpleConfig(); setSimpleConfig();
if (window.location.hash.length > 0) {
var name = urldecode(window.location.hash.substr(1));
var start = false;
for (var i = 0; i < db[0].length; i++) {
if (db[0][i][0] == name) {
document.getElementById('cfg_game')[i+1].selected = true;
preSelect(1);
start = true;
break;
}
}
if (!start) {
for (var i = 0; i < db[1].length; i++) {
if (db[1][i][0] == name) {
document.getElementById('cfg_demo')[i+1].selected = true;
preSelect(2);
start = true;
break;
}
}
}
if (start)
simpleStart();
}
} }
function start() { function start() {
@ -1006,6 +1121,15 @@ function start() {
styleDisplayBlock('base', 0); styleDisplayBlock('base', 0);
styleDisplayBlock('emul', 1); styleDisplayBlock('emul', 1);
if (mode == 0) {
var item = dbNum > 0 ? db[dbGrp - 1][dbNum - 1] : null;
if (item)
window.location.hash = item[0];
else
window.location.hash = '';
} else
window.location.hash = '';
//SAE({cmd:'setConfig',data:config}); //SAE({cmd:'setConfig',data:config});
/*var result = SAE({cmd:'start'}); /*var result = SAE({cmd:'start'});
if (result.error != SAEE_None) { if (result.error != SAEE_None) {
@ -1123,7 +1247,7 @@ function preSelect(grp)
document.getElementById('cfg_info_comp').innerHTML = item[1]; document.getElementById('cfg_info_comp').innerHTML = item[1];
document.getElementById('cfg_info_year').innerHTML = item[2]; document.getElementById('cfg_info_year').innerHTML = item[2];
styleDisplayTable('cfg_info', 1); styleDisplayTable('cfg_info', 1);
styleDisplayInline('dskchg_grp', item[4] ? 1 : 0); styleDisplayInline('dskchg_grp', item[4][0] ? 1 : 0);
if (item[6].length) { if (item[6].length) {
document.getElementById('cfg_info_load').innerHTML = item[6]; document.getElementById('cfg_info_load').innerHTML = item[6];
@ -1245,6 +1369,7 @@ function floppyUpdate(n) {
var e = document.getElementById('cfg_df'+n+'_type'); var e = document.getElementById('cfg_df'+n+'_type');
config.floppy.drive[n].type = parseInt(getSelectValue(e)); config.floppy.drive[n].type = parseInt(getSelectValue(e));
floppyEject(n);
} else { } else {
styleDisplayInline('cfg_df'+n+'_grp', 0); styleDisplayInline('cfg_df'+n+'_grp', 0);
floppyEject(n); floppyEject(n);
@ -1325,7 +1450,8 @@ function portUpdate2() {
function hooks_error(err, msg) { function hooks_error(err, msg) {
stop(); stop();
alert(msg); if (msg !== null)
alert(msg);
} }
function hooks_power_led(on) { function hooks_power_led(on) {

View file

@ -14,14 +14,16 @@
</head> </head>
<body> <body>
<div class="head"> <div class="head">
<div style="height:8px"></div>
<img src="images/logo.png" alt="Scripted Amiga Emulator" />
<noscript> <noscript>
<div class="noscript">This site does require javascript, obviously :)</div> <div class="noscript">This site does require javascript, obviously :)</div>
</noscript> </noscript>
<div class="hr"></div> <div style="height:8px"></div>
</div> <img src="images/logo.png" alt="Scripted Amiga Emulator" />
<div style="height:20px"></div> <div class="acmsg">
<i>Experimental</i> <a href="javascript:openNewTab('http://en.wikipedia.org/wiki/Amiga')">Amiga</a> emulator in pure JavaScript and HTML5
</div>
</div>
<div style="height:8px"></div>
<div class="readme"> <div class="readme">
<table> <table>
<tr> <tr>
@ -32,20 +34,20 @@
<li>A very fast computer</li> <li>A very fast computer</li>
<li>A browser capable of HTML5 with: <li>A browser capable of HTML5 with:
<ul> <ul>
<li>WegGL</li> <li>WegGL or Canvas 2D <span class="gray">(optional)</span></li>
<li>WebAudio</li> <li>WebAudio <span class="gray">(optional)</span></li>
<li>FileReader <span class="gray">(GUI)</span></li>
<li>Typed arrays</li> <li>Typed arrays</li>
<li>FileReader (GUI)</li>
</ul> </ul>
</li> </li>
<li>A ROM: <li>A ROM:
<ul> <ul>
<li>Amiga Kickstart 1.x-2.04 (not included for copyright reasons)</li> <li>Amiga Kickstart 1.0-2.05 <span class="gray">(not included for copyright reasons)</span></li>
<li>AROS Kickstart (included)</li> <li>AROS Kickstart <span class="gray">(included)</span></li>
</ul> </ul>
</li> </li>
<li style="list-style-type:none"><br /></li> <li style="list-style-type:none"><br /></li>
<li>And a bunch of ADF-files to test (optional)</li> <li>And a bunch of ADF-files to test <span class="gray">(optional)</span></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -53,8 +55,8 @@
<td> <td>
<table> <table>
<tr><td colspan="2"><span class="fwb">Supported browsers</span></td></tr> <tr><td colspan="2"><span class="fwb">Supported browsers</span></td></tr>
<tr><td class="armb" style="color:green">Chrome</td><td>Fastest</td></tr> <tr><td class="armb" style="color:green">Chrome</td><td>Very fast</td></tr>
<tr><td class="armb" style="color:green">Firefox</td><td>Medium speed</td></tr> <tr><td class="armb" style="color:orange">Firefox</td><td>Medium speed</td></tr>
<tr><td class="armb" style="color:orange">Opera</td><td>Slow speed, no audio</td></tr> <tr><td class="armb" style="color:orange">Opera</td><td>Slow speed, no audio</td></tr>
<tr><td class="armb" style="color:red">IE</td><td>No support</td></tr> <tr><td class="armb" style="color:red">IE</td><td>No support</td></tr>
<tr><td class="armb">Other</td><td>Untested</td></tr> <tr><td class="armb">Other</td><td>Untested</td></tr>
@ -86,30 +88,17 @@
<li><span class="fwb">Usage/Hints</span> <li><span class="fwb">Usage/Hints</span>
<ul> <ul>
<li>Press F11 for fullscreen. Most browsers support that.</li> <li>Press F11 for fullscreen. Most browsers support that.</li>
<li>If something does crash, try another memory setting or a different ROM. The original kickstart (1.3) work's best.</li> <li>If something does crash, try another memory setting or a different ROM.<br />
The original kickstart (1.3) does work best.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<ul> <ul>
<li><span class="fwb">Known bugs/problems</span> <li><span class="fwb">Known bugs/problems</span>
<ul> <ul>
<li>There may be graphics-errors: <li>Blinking sprites are not shown if "Frameskip" is active.</li>
<ul> <li>There may be short and heavy speed-fluctuations in the beginning of the emulation.</li>
<li>Graphics may be at a wrong position or a wrong color.</li> <li>Left/right shift/alt/ctrl are the same. That's a browser "feature" and can't be fixed.</li>
<li>Fast blinking sprites are not displayed if 'Frameskip' is active.</li>
<li>Copper initiated color-changes within a scanline are not recognized.</li>
<li>The next update (0.8) will deal with this.</li>
</ul>
</li>
<li>Left/right shift/alt/ctrl are the same. That's a browser 'feature' and can't be fixed.</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Missing features</span>
<ul>
<li>User-config</li>
<li>Maybe ECS support</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -121,7 +110,7 @@
</li> </li>
</ul> </ul>
<ul> <ul>
<li><span class="fwb">Source code</span> <li><span class="fwb">Source-code</span>
<ul> <ul>
<li><a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">github.com/naTmeg/ScriptedAmigaEmulator</a></li> <li><a href="javascript:openNewTab('https://github.com/naTmeg/ScriptedAmigaEmulator')">github.com/naTmeg/ScriptedAmigaEmulator</a></li>
</ul> </ul>
@ -130,24 +119,25 @@
<ul> <ul>
<li><span class="fwb">Thanks</span> <li><span class="fwb">Thanks</span>
<ul> <ul>
<li>Bernd Schmidt</li> <li><a href="javascript:openNewTab('http://www.amigaemulator.org')">Bernd Schmidt</a></li>
<li>WinUAE and AROS team.</li> <li><a href="javascript:openNewTab('http://winuae.net')">WinUAE</a> team</li>
<li><a href="javascript:openNewTab('http://aros.org')">AROS</a> team</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<ul> <ul>
<li><span class="fwb">License</span> <li><span class="fwb">License</span>
<ul> <ul>
<li>This is a <b>free</b> project.</li> <li>This is a free project.</li>
<li>You may use the emulator in your own website.</li> <li>You may use the emulator in your own website.</li>
<li>If you use the emulator in your own website, you <b>must</b> provide a link to this homepage.</li> <li>If you use the emulator in your own website, you must provide a link to this homepage.</li>
<li>If you use the emulator in your own website, you <b>must not</b> change the copyright header in the source-files.</li> <li>If you use the emulator in your own website, you must not change the copyright header in the source-files.</li>
<li>Commercial use <b>in any form</b> is prohibited. This includes donations.</li> <li>Commercial use in any form is prohibited. This includes donations.</li>
<li>No warranty expressed or implied. Use at your own risk.</li> <li>No warranty expressed or implied. Use at your own risk.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<div class="hr"></div> <!--<div class="hr"></div>
<table> <table>
<tr><td colspan="3" class="acm"><span class="fwb">Fully working...</span></td></tr> <tr><td colspan="3" class="acm"><span class="fwb">Fully working...</span></td></tr>
<tr> <tr>
@ -158,7 +148,6 @@
<li>Alien Breed</li> <li>Alien Breed</li>
<li>Alien Breed Special Edition 92<span class="fwb"> (0.7)</span></li> <li>Alien Breed Special Edition 92<span class="fwb"> (0.7)</span></li>
<li>Alien Breed Tower Assault<span class="fwb"> (0.6)</span></li> <li>Alien Breed Tower Assault<span class="fwb"> (0.6)</span></li>
<li>Alien Breed II - The horror continues<span class="fwb"> (0.7)</span></li>
<li>Boby Blows Galactic<span class="fwb"> (0.7)</span></li> <li>Boby Blows Galactic<span class="fwb"> (0.7)</span></li>
<li>Agony<span class="fwb"> (0.6.1)</span></li> <li>Agony<span class="fwb"> (0.6.1)</span></li>
<li>Another World</li> <li>Another World</li>
@ -169,7 +158,7 @@
<li>Dynablaster<span class="fwb"> (0.7)</span></li> <li>Dynablaster<span class="fwb"> (0.7)</span></li>
<li>Firepower</li> <li>Firepower</li>
<li>Lotus Turbo Challenge 1/2<span class="fwb"> (0.6)</span></li> <li>Lotus Turbo Challenge 1/2<span class="fwb"> (0.6)</span></li>
<li>NorthPrince of Persia<span class="fwb"> (0.7)</span></li> <li>North'n South<span class="fwb"> (0.7)</span></li>
<li>Pinball Dreams</li> <li>Pinball Dreams</li>
<li>Pinball Fantasies (the demo with 1 desk)</li> <li>Pinball Fantasies (the demo with 1 desk)</li>
<li>Prince of Persia<span class="fwb"> (0.7)</span></li> <li>Prince of Persia<span class="fwb"> (0.7)</span></li>
@ -217,10 +206,66 @@
</tr> </tr>
<tr><td colspan="3" class="acm"><span class="fwb">Note:</span> The lists corresponds to Kickstart 1.3</td></tr> <tr><td colspan="3" class="acm"><span class="fwb">Note:</span> The lists corresponds to Kickstart 1.3</td></tr>
</table> </table>
<div class="hr"></div> <div class="hr"></div>-->
<ul> <ul>
<li><span class="fwb">History</span> <li><span class="fwb">History</span>
<ul> <ul>
<li>0.8.0 (16.01.2013):
<ul>
<li>Display
<ul>
<li>Ported and optimized playfield-code from WinUAE.<br />
This adds ECS and AGA support and fixes graphics-errors.<br />
The AGA part is commented out, because there is no 68020 yet.</li>
<li>Added support for drawing via 'Canvas 2D' if 'WebGL' is not avail.</li>
<li>Added support for auto-driver detection.</li>
</ul>
</li>
<li>Audio
<ul>
<li>While disk access, audio performance is much better now.</li>
<li>Added support for the A500 lowpass-filter. Not enabled by default.</li>
<li>Added support for auto-driver detection.</li>
</ul>
</li>
<li>Memory
<ul>
<li>To gain speed, all memory is now accessed directly and not via functions.<br />
So, don't care for a possible illegal memory access.</li>
<li>Fixed bug, where kickstart 1.2 failed to load.</li>
<li>Fixed incorrect extended-address bug.</li>
</ul>
</li>
<li>CPU
<ul>
<li>Splitted address-types of ADDQ/SUBQ into separate functions for more speed.</li>
<li>Added bus-read/write cycles tables. For internal use only.</li>
</ul>
</li>
<li>CIA
<ul>
<li>I decided to port the latest cia-code from WinUAE while i was trying to find a bug.<br />
Well, the bug is still there. Let's keep the code nevertheless.</li>
</ul>
</li>
<li>GUI
<ul>
<li>Added info box of supported drivers.</li>
<li>Added a 'Chipset'-section and various options.</li>
<li>Packed the main GUI.</li>
</ul>
</li>
<li>Common
<ul>
<li>Added support for easy URL sharing. E.g. to show the Multica-demo to a friend,<br />
one may send the link "http://scriptedamigaemulator.net/#Multica"<br />
and the demo will start immediately. (thanks mrdoob)</li>
<li>Many small optimizations.</li>
</ul>
</li>
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li>0.7.0 (24.12.2012): <li>0.7.0 (24.12.2012):
<ul> <ul>
<li>Common <li>Common
@ -246,7 +291,8 @@
<li>Audio <li>Audio
<ul> <ul>
<li>Added a ring-buffer before output. No more "bagpipe"-like audio.</li> <li>Added a ring-buffer before output. No more "bagpipe"-like audio.</li>
<li>Added a option to just emulate the hardware, but not to play any sound, e.g. "Agony" was not starting, if audio was disabled.</li> <li>Added a option to just emulate the hardware, but not to play any sound,<br />
e.g. "Agony" was not starting, if audio was disabled.</li>
</ul> </ul>
</li> </li>
<li>Display <li>Display

View file

@ -12,6 +12,14 @@ function set_special(x) { AMIGA.spcflags |= x; }
function clr_special(x) { AMIGA.spcflags &= ~x; } function clr_special(x) { AMIGA.spcflags &= ~x; }
function Amiga() { function Amiga() {
this.info = {
version: SAEV_Version+'.'+SAEV_Revision+'.'+SAEV_Revision_Sub,
browser_name: BrowserDetect.browser,
browser_version: BrowserDetect.version,
os: BrowserDetect.OS,
video:0,
audio:0
};
this.config = new Config(); this.config = new Config();
this.mem = new Memory(); this.mem = new Memory();
this.expansion = new Expansion(); this.expansion = new Expansion();
@ -29,35 +37,31 @@ function Amiga() {
this.audio = new Audi0(); this.audio = new Audi0();
this.cpu = new CPU(); this.cpu = new CPU();
this.state = CMD_STOP; this.state = ST_STOP;
this.delay = 0; this.delay = 0;
this.spcflags = 0; this.spcflags = 0;
//this.loading = 0; //this.loading = 0;
this.intena = 0; this.intena = 0;
this.intena_internal = 0;
this.intreq = 0; this.intreq = 0;
this.intreq_internal = 0;
this.dmacon = 0; this.dmacon = 0;
this.adkcon = 0; this.adkcon = 0;
configSetDefaults(this.config); this.info.video = this.video.available;
this.info.audio = this.audio.available;
/*---------------------------------*/ /*---------------------------------*/
this.setup = function() { this.setup = function() {
if (this.config.chipset.type == SAEV_Config_Chipset_Type_OCS)
this.config.chipset.agnus = this.config.video.ntsc ? AGNUS_8370 : AGNUS_8371;
this.mem.setup(); this.mem.setup();
this.expansion.setup(); this.expansion.setup();
this.events.setup(); this.events.setup();
this.playfield.setup();
this.video.setup();
this.cia.setup(); this.cia.setup();
this.rtc.setup(); this.rtc.setup();
this.input.setup(); this.input.setup();
this.disk.setup(); this.disk.setup();
this.playfield.setup();
this.video.setup();
this.audio.setup(); this.audio.setup();
this.custom.setup(); this.custom.setup();
this.cpu.setup(); this.cpu.setup();
@ -72,26 +76,25 @@ function Amiga() {
this.reset = function() { this.reset = function() {
BUG.info('Amiga.reset()'); BUG.info('Amiga.reset()');
this.delay = 0; this.delay = 0;
this.spcflags = 0;
//this.loading = 0; //this.loading = 0;
this.intena = 0; this.intena = 0;
this.intena_internal = 0;
this.intreq = 0; this.intreq = 0;
this.intreq_internal = 0;
this.dmacon = 0; this.dmacon = 0;
this.adkcon = 0; this.adkcon = 0;
this.expansion.reset(); this.expansion.reset();
this.events.reset(); this.events.reset();
this.playfield.reset();
this.cia.reset(); this.cia.reset();
this.disk.reset(); this.disk.reset();
this.input.reset(); this.input.reset();
this.serial.reset(); this.serial.reset();
this.blitter.reset(); this.blitter.reset();
this.copper.reset(); this.copper.reset();
this.playfield.reset();
this.audio.reset(); this.audio.reset();
this.custom.reset(); this.custom.reset();
this.cpu.reset(this.mem.rom.lower); this.cpu.reset(this.mem.rom.lower);
@ -109,7 +112,7 @@ function Amiga() {
setTimeout('AMIGA.waitForStart()', 10); setTimeout('AMIGA.waitForStart()', 10);
else { else {
this.reset(); this.reset();
this.state = CMD_CYCLE; this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0); setTimeout('AMIGA.cycle()', 0);
} }
} }
@ -120,24 +123,24 @@ function Amiga() {
this.start = function() { this.start = function() {
if (this.state == CMD_STOP) { if (this.state == ST_STOP) {
this.setup(); this.setup();
this.reset(); this.reset();
this.state = CMD_CYCLE; this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0); setTimeout('AMIGA.cycle()', 0);
} }
} }
this.stop = function() { this.stop = function() {
if (this.state != CMD_STOP) { if (this.state != ST_STOP) {
this.state = CMD_STOP; this.state = ST_STOP;
this.cleanup(); this.cleanup();
} }
} }
this.pause = function(state) { this.pause = function(state) {
if (this.state != CMD_STOP) { if (this.state != ST_STOP) {
this.state = state ? CMD_PAUSE : CMD_CYCLE; this.state = state ? ST_PAUSE : ST_CYCLE;
this.audio.pauseResume(state); this.audio.pauseResume(state);
} }
} }
@ -159,97 +162,100 @@ function Amiga() {
*/ */
this.insert = function(unit) { this.insert = function(unit) {
if (this.state != CMD_STOP) if (this.state != ST_STOP)
this.disk.insert(unit); this.disk.insert(unit);
} }
this.eject = function(unit) { this.eject = function(unit) {
if (this.state != CMD_STOP) if (this.state != ST_STOP)
this.disk.eject(unit); this.disk.eject(unit);
} }
/*---------------------------------*/ /*---------------------------------*/
/* mainloop */ /* mainloop */
this.cycle = function() { this.cycle = function() {
try { try {
while (this.state == CMD_CYCLE) this.cpu.cycle();
this.cpu.cycle();
} catch (e) { } catch (e) {
if (e instanceof VSync) {
//console.log(e.error, e.message);
this.state = ST_IDLE;
} else
if (e instanceof FatalError) { if (e instanceof FatalError) {
this.state = ST_STOP;
this.stop(); this.stop();
this.config.hooks.error(e.error, e.message); this.config.hooks.error(e.error, e.message);
} else } else /* normal exception */ {
this.state = ST_STOP;
this.stop();
console.log(e); console.log(e);
}
} }
if (this.state == ST_IDLE) {
if (this.state == CMD_IDLE) { this.state = ST_CYCLE;
this.state = CMD_CYCLE;
setTimeout('AMIGA.cycle()', this.delay); setTimeout('AMIGA.cycle()', this.delay);
} }
else if (this.state == CMD_PAUSE) else if (this.state == ST_PAUSE)
setTimeout('AMIGA.cyclePause()', 0); AMIGA.cyclePause();
else else
setTimeout('AMIGA.cycleExit()', 0); AMIGA.cycleExit();
} }
this.cyclePause = function() { this.cyclePause = function() {
if (this.state == CMD_CYCLE) if (this.state == ST_CYCLE)
setTimeout('AMIGA.cycle()', 0); setTimeout('AMIGA.cycle()', 0);
else if (this.state == CMD_PAUSE) else if (this.state == ST_PAUSE)
setTimeout('AMIGA.cyclePause()', 500); setTimeout('AMIGA.cyclePause()', 500);
else else
setTimeout('AMIGA.cycleExit()', 0); AMIGA.cycleExit();
} }
this.cycleExit = function() { this.cycleExit = function() {
this.dump(); this.dump();
//this.cia.dump();
} }
/*---------------------------------*/ /*---------------------------------*/
this.dmaen = function (dmamask) { this.dmaen = function (dmamask) {
return ((this.dmacon & DMAF_DMAEN) && (this.dmacon & dmamask)); return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0);
} }
this.DMACONR = function(hpos) { this.DMACONR = function(hpos) {
this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos);
this.dmacon &= ~(0x4000 | 0x2000); this.dmacon &= ~(0x4000 | 0x2000);
//this.dmacon |= (this.blitter.state == BLT_STOP ? 0 : 0x4000) | (this.blitter.zero ? 0x2000 : 0); //old
//this.dmacon |= ((blit_interrupt || (!blit_interrupt && currprefs.cs_agnusbltbusybug && !blt_info.got_cycle)) ? 0 : 0x4000) | (blt_info.blitzero ? 0x2000 : 0); //new org
var iz = this.blitter.getIntZero(); var iz = this.blitter.getIntZero();
this.dmacon |= (iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0); this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0));
return this.dmacon; return this.dmacon;
} }
this.DMACON = function (v, hpos) { this.DMACON = function (v, hpos) {
var oldcon = this.dmacon; var oldcon = this.dmacon;
this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos);
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.dmacon |= v & ~INTF_SETCLR; this.dmacon |= v & ~INTF_SETCLR;
else else
this.dmacon &= ~v; this.dmacon &= ~v;
this.dmacon &= 0x1fff; this.dmacon &= 0x1fff;
var changed = this.dmacon ^ oldcon; var changed = this.dmacon ^ oldcon;
var oldcop = (oldcon & DMAF_COPEN) && (oldcon & DMAF_DMAEN); var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0;
var newcop = (this.dmacon & DMAF_COPEN) && (this.dmacon & DMAF_DMAEN); var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0;
if (oldcop != newcop) { if (oldcop != newcop) {
if (newcop && !oldcop) { if (newcop && !oldcop) {
this.copper.compute_spcflag_copper(this.events.hpos()); this.copper.compute_spcflag_copper(this.events.hpos());
} else if (!newcop) { } else if (!newcop) {
this.copper.enabled_thisline = false; this.copper.enabled_thisline = false;
clr_special (SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
} }
} }
//if ((this.dmacon & DMAF_COPEN) > (oldcon & DMAF_COPEN))
//this.copper.COPJMP(1, 0);
if ((this.dmacon & DMAF_SPREN) > (oldcon & DMAF_SPREN)) {
for (var i = 0; i < 8; i++)
this.playfield.sprites.sprite[i].dmastate = 1;
}
if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done) if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done)
set_special(SPCFLAG_BLTNASTY); set_special(SPCFLAG_BLTNASTY);
if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init) if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init)
@ -260,12 +266,12 @@ function Amiga() {
if (changed & (DMAF_DMAEN | 0x0f)) if (changed & (DMAF_DMAEN | 0x0f))
this.audio.state_machine(); this.audio.state_machine();
/*if (this.copper.active && !this.events.eventtab[EV_COPPER].active) { if (changed & (DMAF_DMAEN | DMAF_BPLEN)) {
this.events.eventtab[EV_COPPER].active = true; this.playfield.update_ddf_change();
this.events.eventtab[EV_COPPER].oldcycles = this.events.currcycle; if (this.dmaen(DMAF_BPLEN))
this.events.eventtab[EV_COPPER].evtime = 1 * CYCLE_UNIT + this.events.currcycle; this.playfield.maybe_start_bpl_dma(hpos);
this.events.schedule(); }
}*/ this.events.schedule();
} }
/*---------------------------------*/ /*---------------------------------*/
@ -296,27 +302,13 @@ function Amiga() {
} }
this.INTENA = function(v) { this.INTENA = function(v) {
var old = this.intena;
if (v & INTF_SETCLR) if (v & INTF_SETCLR)
this.intena |= v & ~INTF_SETCLR; this.intena |= v & ~INTF_SETCLR;
else else
this.intena &= ~v; this.intena &= ~v;
if (!(v & INTF_SETCLR) && old == this.intena) if (v & INTF_SETCLR)
return; this.doint();
if (AMIGA.config.cpu.exact) {
this.events.event2_newevent_xx(-1, INT_PROCESSING_DELAY, this.intena, function(v) {
//console.log('INTENA()', v);
AMIGA.intena_internal = v;
AMIGA.doint();
});
} else {
this.intena_internal = this.intena;
if (v & INTF_SETCLR)
this.doint();
}
} }
/*---------------------------------*/ /*---------------------------------*/
@ -333,64 +325,36 @@ function Amiga() {
else else
this.intreq &= ~v; this.intreq &= ~v;
if (AMIGA.config.cpu.exact) { if ((v & INTF_SETCLR) && this.intreq != old)
if (old == this.intreq && this.intreq_internal == this.intreq) this.doint();
return;
this.events.event2_newevent_xx(-1, INT_PROCESSING_DELAY, this.intreq, function(v) {
//console.log('INTREQ_0()', v);
AMIGA.intreq_internal = v;
AMIGA.doint();
});
} else {
this.intreq_internal = this.intreq;
if (this.intreq == old)
return;
if (v & INTF_SETCLR)
this.doint();
}
} }
this.INTREQ = function(v) { this.INTREQ = function(v) {
this.INTREQ_0(v); this.INTREQ_0(v);
this.cia.reThink(); this.cia.rethink();
} }
/*---------------------------------*/
this.intlev = function() { this.intlev = function() {
var imask = this.intreq_internal & this.intena_internal; var imask = this.intreq & this.intena;
if (imask && (this.intena_internal & INTF_INTEN)) { if (imask && (this.intena & INTF_INTEN)) {
if (imask & 0x2000) return 6; if (imask & 0x2000) return 6;
if (imask & (0x1000 | 0x0800)) return 5; if (imask & 0x1800) return 5;
if (imask & (0x0400 | 0x0200 | 0x0100 | 0x0080)) return 4; if (imask & 0x0780) return 4;
if (imask & (0x0040 | 0x0020 | 0x0010)) return 3; if (imask & 0x0070) return 3;
if (imask & 0x0008) return 2; if (imask & 0x0008) return 2;
if (imask & (0x0001 | 0x0002 | 0x0004)) return 1; if (imask & 0x0007) return 1;
} }
return -1; return -1;
} }
this.doint = function() { this.doint = function() {
if (AMIGA.config.cpu.exact) {
this.cpu.setIPL(this.intlev());
clr_special(SPCFLAG_INT);
return;
}
if (AMIGA.config.cpu.compatible) if (AMIGA.config.cpu.compatible)
set_special(SPCFLAG_INT); set_special(SPCFLAG_INT);
else else
set_special(SPCFLAG_DOINT); set_special(SPCFLAG_DOINT);
}
this.send_interrupt = function(num, delay) {
if (AMIGA.config.cpu.exact && delay > 0) {
if (!(this.intreq & (1 << num))) {
this.events.event2_newevent_xx(-1, delay, num, function(v) {
AMIGA.INTREQ_0(INTF_SETCLR | (1 << v));
});
}
} else
this.INTREQ_0(INTF_SETCLR | (1 << num));
} }
} }
@ -405,7 +369,8 @@ function SAE(x) {
BUG.info('API.init() SEA %d.%d.%d', SAEV_Version, SAEV_Revision, SAEV_Revision_Sub); BUG.info('API.init() SEA %d.%d.%d', SAEV_Version, SAEV_Revision, SAEV_Revision_Sub);
AMIGA = new Amiga(); AMIGA = new Amiga();
return AMIGA.config; //return AMIGA.config;
break;
case 'reset': case 'reset':
BUG.info('API.reset()'); BUG.info('API.reset()');
AMIGA.reset(); AMIGA.reset();
@ -438,10 +403,13 @@ function SAE(x) {
BUG.info('API.eject() DF%d', x.unit); BUG.info('API.eject() DF%d', x.unit);
AMIGA.eject(x.unit); AMIGA.eject(x.unit);
break; break;
/*case 'getConfig': case 'getInfo':
BUG.info('API.getInfo()');
return AMIGA.info;
case 'getConfig':
BUG.info('API.getConfig()'); BUG.info('API.getConfig()');
return AMIGA.config; return AMIGA.config;
case 'setConfig': /*case 'setConfig':
BUG.info('API.setConfig() size '+x.data.ext.size); BUG.info('API.setConfig() size '+x.data.ext.size);
AMIGA.config = x.data; AMIGA.config = x.data;
break;*/ break;*/

View file

@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger * ©2012 Rupert Hausberger
* Commercial use is prohibited. * Commercial use is prohibited.
* *
***************************************************************************
* Notes: Ported from WinUAE 2.5.0
*
**************************************************************************/ **************************************************************************/
/*const DEBUG_CHANNEL_MASK = 15 /*const DEBUG_CHANNEL_MASK = 15
@ -70,9 +73,7 @@ function Filter() {
} }
this.filter = function(input, state) { this.filter = function(input, state) {
if (!this.on) //if (!this.on) return input;
return input;
var o, fs = filter_state[state]; var o, fs = filter_state[state];
fs.rc1 = filter1_a0 * input + (1 - filter1_a0) * fs.rc1 + DENORMAL_OFFSET; fs.rc1 = filter1_a0 * input + (1 - filter1_a0) * fs.rc1 + DENORMAL_OFFSET;
@ -83,12 +84,11 @@ function Filter() {
fs.rc3 = filter_a0 * no + (1 - filter_a0) * fs.rc3; fs.rc3 = filter_a0 * no + (1 - filter_a0) * fs.rc3;
fs.rc4 = filter_a0 * fs.rc3 + (1 - filter_a0) * fs.rc4; fs.rc4 = filter_a0 * fs.rc3 + (1 - filter_a0) * fs.rc4;
fs.rc5 = filter_a0 * fs.rc4 + (1 - filter_a0) * fs.rc5; fs.rc5 = filter_a0 * fs.rc4 + (1 - filter_a0) * fs.rc5;
o = fs.rc5; o = Math.floor(fs.rc5);
} else } else
o = no; o = Math.floor(no);
if (o > 32767) o = 32767; else if (o < -32768) o = -32768; return o > 32767 ? 32767 : (o < -32768 ? -32768 : o);
return o;
} }
} }
@ -367,6 +367,9 @@ function Channel(num) {
} }
function Audi0() { function Audi0() {
const SAMPLE_BUFFER_SIZE = 8192 >> 0;
this.available = 0;
var channel = null; var channel = null;
var last_cycles = 0; var last_cycles = 0;
@ -410,6 +413,35 @@ function Audi0() {
/*---------------------------------*/ /*---------------------------------*/
//this.init = function()
{
var test;
/*try {
test = new AudioContext();
test = null;
this.available |= SAEI_Audio_Default;
} catch (e) {}*/
try {
test = new webkitAudioContext();
if (test && test.createJavaScriptNode)
this.available |= SAEI_Audio_Webkit;
test = null;
} catch (e) {}
try {
test = new Audio();
if (test && test.mozSetup)
this.available |= SAEI_Audio_Mozilla;
test = null;
} catch (e) {}
//console.log(this.available);
}
/*---------------------------------*/
function getRate(v) { function getRate(v) {
switch (v) { switch (v) {
case SAEV_Config_Audio_Rate_11025: return 11025; case SAEV_Config_Audio_Rate_11025: return 11025;
@ -420,30 +452,29 @@ function Audi0() {
} }
} }
this.recalc_sample_evtime = function() { this.calc_sample_evtime = function(freq, longframe, linetoggle) {
var hpos, lines = 0; var lines = 0.0;
var hpos;
if (AMIGA.config.video.ntsc) { if (linetoggle) {
hpos = 227.5; hpos = AMIGA.playfield.maxhpos_short + 0.5;
lines += 0.5; lines += 0.5;
} else { } else {
var longframe = (AMIGA.playfield.bplcon0 & 4) ? -1 : AMIGA.events.lofStore; hpos = AMIGA.playfield.maxhpos_short + 0.0;
hpos = 227;
if (longframe < 0) if (longframe < 0)
lines += 0.5; lines += 0.5;
else if (longframe > 0) else if (longframe > 0)
lines += 1.0; lines += 1.0;
} }
lines += AMIGA.events.maxvpos; lines += AMIGA.playfield.maxvpos_nom;
scaled_sample_evtime_orig = Math.floor(hpos * lines * freq * CYCLE_UNIT / getRate(AMIGA.config.audio.rate));
scaled_sample_evtime_orig = Math.floor(hpos * lines * AMIGA.events.hz * CYCLE_UNIT / getRate(AMIGA.config.audio.rate));
scaled_sample_evtime = scaled_sample_evtime_orig; scaled_sample_evtime = scaled_sample_evtime_orig;
//sampler_evtime = hpos * lines * AMIGA.events.hz * CYCLE_UNIT; /*#if 0
lines -= AMIGA.playfield.maxvpos_nom;
//scaled_sample_evtime = Math.floor((AMIGA.events.maxhpos * AMIGA.events.maxvpos * AMIGA.events.hz + getRate(AMIGA.config.audio.rate) - 1) / getRate(AMIGA.config.audio.rate)) * CYCLE_UNIT; BUG.info('%d.%d %d.%d %.2f', maxhpos_short, linetoggle ? 5 : 0, maxvpos_nom + (lines == 1.0 ? 1 : 0), lines > 0 && lines < 1 ? 5 : 0, scaled_sample_evtime);
#endif*/
console.log('Audio.recalc_sample_evtime() scaled_sample_evtime %f (%f) | hpos %d, lines %d', scaled_sample_evtime, scaled_sample_evtime * CYCLE_UNIT_INV, hpos, lines); BUG.info('Audio.calc_sample_evtime() scaled_sample_evtime %f (%f) | hpos %d, lines %d', scaled_sample_evtime, scaled_sample_evtime * CYCLE_UNIT_INV, hpos, lines);
} }
this.setup = function() { this.setup = function() {
if (channel === null) { if (channel === null) {
@ -455,53 +486,32 @@ function Audi0() {
return; return;
if (driver.ctx === null) { if (driver.ctx === null) {
if (BrowserDetect.browser == 'Firefox') { if (this.available & SAEI_Audio_Webkit)
try { driver.ctx = new webkitAudioContext();
driver.ctx = new Audio(); else if (this.available & SAEI_Audio_Mozilla)
BUG.info('Audio.setup() using "Audio()"'); driver.ctx = new Audio();
} catch (e) {}
} else {
try {
driver.ctx = new AudioContext();
BUG.info('Audio.setup() using "AudioContext()"');
} catch (e) {
try {
driver.ctx = new webkitAudioContext();
BUG.info('Audio.setup() using "webkitAudioContext()"');
} catch (e) {}
}
}
} }
if (driver.ctx === null) { if (driver.ctx === null) {
if (confirm('Can\'t initialise WebAudio. Continue without audio-playback?')) { if (confirm('Can\'t initialise WebAudio. Continue without audio-playback?')) {
AMIGA.config.audio.mode = SAEV_Config_Audio_Mode_Emul; AMIGA.config.audio.mode = SAEV_Config_Audio_Mode_Emul;
return; return;
} else } else
Fatal(SAEE_Audio_WebAudio_Not_Avail, 'Can\'t initialise WebAudio.'); Fatal(SAEE_Audio_WebAudio_Not_Avail, null);
} }
this.filter.setup(0); this.filter.setup(AMIGA.config.audio.filter); /* A500 lowpass-filter */
this.recalc_sample_evtime(); var hz = AMIGA.config.video.ntsc ? 60 : 50;
this.calc_sample_evtime(hz, 1, AMIGA.config.video.ntsc);
sampleBuffer.size = 8192 >> 0; sampleBuffer.size = SAMPLE_BUFFER_SIZE;
sampleBuffer.realSize = sampleBuffer.size << 1; sampleBuffer.realSize = sampleBuffer.size << 1;
sampleBuffer.data = new Float32Array(sampleBuffer.realSize << (AMIGA.config.audio.channels - 1)); sampleBuffer.data = new Float32Array(sampleBuffer.realSize << (AMIGA.config.audio.channels - 1));
ringBuffer.size = sampleBuffer.size << 1; ringBuffer.size = sampleBuffer.size + (sampleBuffer.size >> 1);
ringBuffer.data = new Float32Array(ringBuffer.size << (AMIGA.config.audio.channels - 1)); ringBuffer.data = new Float32Array(ringBuffer.size << (AMIGA.config.audio.channels - 1));
if (BrowserDetect.browser == 'Firefox') { if (this.available & SAEI_Audio_Webkit) {
driver.ctx.mozSetup(AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
/*driver.moz.currentWritePosition = 0;
driver.moz.prebufferSize = getRate(AMIGA.config.audio.rate) >> 1; //prebuffer 500ms
driver.moz.tail = null;*/
//driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / (getRate(AMIGA.config.audio.rate) / sampleBuffer.size)));
driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / AMIGA.events.hz * (sampleBuffer.size / (getRate(AMIGA.config.audio.rate) / AMIGA.events.hz))));
BUG.info('Audio.setup() enabled mozilla audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
} else {
var inputs = BrowserDetect.browser == 'Safari' ? 1 : 0; var inputs = BrowserDetect.browser == 'Safari' ? 1 : 0;
//if (inputs == 1) BUG.info('Audio.setup() Safari fix enabled.'); //if (inputs == 1) BUG.info('Audio.setup() Safari fix enabled.');
@ -510,32 +520,36 @@ function Audi0() {
driver.def.node.connect(driver.ctx.destination); driver.def.node.connect(driver.ctx.destination);
BUG.info('Audio.setup() enabled webkit audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate)); BUG.info('Audio.setup() enabled webkit audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
} }
else if (this.available & SAEI_Audio_Mozilla) {
driver.ctx.mozSetup(AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
/*driver.moz.currentWritePosition = 0;
driver.moz.prebufferSize = getRate(AMIGA.config.audio.rate) >> 1; //prebuffer 500ms
driver.moz.tail = null;*/
//driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / (getRate(AMIGA.config.audio.rate) / sampleBuffer.size)));
driver.moz.interval = setInterval(mozHandler, Math.floor(1000 / hz * (sampleBuffer.size / (getRate(AMIGA.config.audio.rate) / hz))));
BUG.info('Audio.setup() enabled mozilla audio, channels %d, rate %d', AMIGA.config.audio.channels, getRate(AMIGA.config.audio.rate));
}
} }
this.cleanup = function() { this.cleanup = function() {
if (driver.ctx !== null) { if (driver.ctx !== null) {
if (BrowserDetect.browser == 'Firefox') { if (this.available & SAEI_Audio_Webkit) {
clearInterval(driver.moz.interval);
} else {
driver.def.node.disconnect(0); driver.def.node.disconnect(0);
driver.def.node = null; driver.def.node = null;
} }
else if (this.available & SAEI_Audio_Mozilla) {
clearInterval(driver.moz.interval);
}
} }
} }
this.pauseResume = function(pause) { this.pauseResume = function(pause) {
if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) return; if (!AMIGA.config.audio.enabled || AMIGA.config.audio.mode == SAEV_Config_Audio_Mode_Emul) return;
if (driver.ctx !== null) { if (driver.ctx !== null) {
if (BrowserDetect.browser == 'Firefox') { if (this.available & SAEI_Audio_Webkit) {
if (pause && !driver.paused) {
clearInterval(driver.moz.interval);
driver.paused = true;
} else if (!pause && driver.paused) {
driver.moz.interval = setInterval(mozHandler, 100);
driver.paused = false;
}
} else {
if (driver.def.node) { if (driver.def.node) {
if (pause && !driver.paused) { if (pause && !driver.paused) {
driver.def.node.disconnect(0); driver.def.node.disconnect(0);
@ -546,20 +560,29 @@ function Audi0() {
} }
} }
} }
else if (this.available & SAEI_Audio_Mozilla) {
if (pause && !driver.paused) {
clearInterval(driver.moz.interval);
driver.paused = true;
} else if (!pause && driver.paused) {
driver.moz.interval = setInterval(mozHandler, 100);
driver.paused = false;
}
}
} }
} }
this.reset = function() { this.reset = function() {
for (var i = 0; i < 4; i++) for (var i = 0; i < 4; i++)
channel[i].reset(); channel[i].reset();
last_cycles = AMIGA.events.currcycle; last_cycles = AMIGA.events.currcycle;
next_sample_evtime = scaled_sample_evtime; next_sample_evtime = scaled_sample_evtime;
this.schedule(); this.schedule();
AMIGA.events.schedule(); AMIGA.events.schedule();
work_to_do = 0; work_to_do = 0;
prevcon = -1; prevcon = 0;
sampleBuffer.pos = 0; sampleBuffer.pos = 0;
sampleBuffer.rate.clr(); sampleBuffer.rate.clr();
@ -592,7 +615,7 @@ function Audi0() {
ret = 1; ret = 1;
this.event_reset(); this.event_reset();
} }
work_to_do = 4 * AMIGA.events.maxvpos * 50; work_to_do = 4 * AMIGA.playfield.maxvpos_nom * 50;
return ret; return ret;
} }
@ -716,16 +739,16 @@ function Audi0() {
} }
this.hsync = function() { this.hsync = function() {
//if (!AMIGA.config.audio.enabled) return; /* done in events.hSyncPre() */
if (work_to_do > 0) { if (work_to_do > 0) {
work_to_do--; //work_to_do--;
if (work_to_do == 0) if (--work_to_do == 0)
this.deactivate(); this.deactivate();
} }
this.update(); this.update();
} }
this.vsync = function() { }
/*---------------------------------*/ /*---------------------------------*/
this.AUDxDAT = function(nr, v) { this.AUDxDAT = function(nr, v) {
@ -763,7 +786,7 @@ function Audi0() {
if (per < PERIOD_MIN * CYCLE_UNIT) if (per < PERIOD_MIN * CYCLE_UNIT)
per = PERIOD_MIN * CYCLE_UNIT; per = PERIOD_MIN * CYCLE_UNIT;
if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && !AMIGA.config.cpu.exact && channel[nr].dmaenstore) if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && channel[nr].dmaenstore)
per = PERIOD_MIN_NONCE * CYCLE_UNIT; per = PERIOD_MIN_NONCE * CYCLE_UNIT;
if (channel[nr].per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) { if (channel[nr].per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) {
@ -853,8 +876,10 @@ function Audi0() {
data1 += data2; data1 += data2;
data2 = data0 << 1; data2 = data0 << 1;
data3 = data1 << 1; data3 = data1 << 1;
data2 = this.filter.filter(data2, 0); if (AMIGA.config.audio.filter) {
data3 = this.filter.filter(data3, 1); data2 = this.filter.filter(data2, 0);
data3 = this.filter.filter(data3, 1);
}
if (sampleBuffer.pos < sampleBuffer.realSize) { if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@ -910,8 +935,10 @@ function Audi0() {
data1 += data2; data1 += data2;
data2 = data0 << 1; data2 = data0 << 1;
data3 = data1 << 1; data3 = data1 << 1;
data2 = this.filter.filter(data2, 0); if (AMIGA.config.audio.filter) {
data3 = this.filter.filter(data3, 1); data2 = this.filter.filter(data2, 0);
data3 = this.filter.filter(data3, 1);
}
if (sampleBuffer.pos < sampleBuffer.realSize) { if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@ -921,7 +948,7 @@ function Audi0() {
} else } else
sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5);
} else } else
BUG.info('Audio.sample_handler() audio buffer over-run!'); BUG.info('Audio.sample_handler_crux() audio buffer over-run!');
} }
this.sample_handler_rh = function() { this.sample_handler_rh = function() {
@ -938,23 +965,25 @@ function Audi0() {
var delta, ratio; var delta, ratio;
delta = channel[0].per; delta = channel[0].per;
ratio = ((channel[0].evtime % delta) << 8) / delta; ratio = Math.floor(((channel[0].evtime % delta) << 8) / delta);
data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8; data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
delta = channel[1].per; delta = channel[1].per;
ratio = ((channel[1].evtime % delta) << 8) / delta; ratio = Math.floor(((channel[1].evtime % delta) << 8) / delta);
data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8; data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
delta = channel[2].per; delta = channel[2].per;
ratio = ((channel[2].evtime % delta) << 8) / delta; ratio = Math.floor(((channel[2].evtime % delta) << 8) / delta);
data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8; data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
delta = channel[3].per; delta = channel[3].per;
ratio = ((channel[3].evtime % delta) << 8) / delta; ratio = Math.floor(((channel[3].evtime % delta) << 8) / delta);
data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8; data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
} }
data2 = data0 << 1; data2 = data0 << 1;
data3 = data1 << 1; data3 = data1 << 1;
data2 = this.filter.filter(data2, 0); if (AMIGA.config.audio.filter) {
data3 = this.filter.filter(data3, 1); data2 = this.filter.filter(data2, 0);
data3 = this.filter.filter(data3, 1);
}
if (sampleBuffer.pos < sampleBuffer.realSize) { if (sampleBuffer.pos < sampleBuffer.realSize) {
if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) { if (AMIGA.config.audio.channels == SAEV_Config_Audio_Channels_Stereo) {
@ -964,13 +993,13 @@ function Audi0() {
} else } else
sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5); sampleBuffer.data[sampleBuffer.pos++] = inv32768 * ((data2 + data3) * 0.5);
} else } else
BUG.info('Audio.sample_handler() audio buffer over-run!'); BUG.info('Audio.sample_handler_rh() audio buffer over-run!');
} }
/*---------------------------------*/ /*---------------------------------*/
//var avg = 0, cnt = 0; //var avg = 0, cnt = 0;
function fillRingBuffer() { function fillRingBuffer() {
if (sampleBuffer.pos == 0) return false; if (sampleBuffer.pos == 0) return false;
@ -1042,10 +1071,8 @@ function Audi0() {
ringBuffer.usage = 0; ringBuffer.usage = 0;
} }
} }
//console.log(sampleBuffer.pos, ringBuffer.usage, rate); //console.log(sampleBuffer.pos, ringBuffer.usage, rate);
sampleBuffer.pos = 0; sampleBuffer.pos = 0;
return [playBuffer, rate]; return [playBuffer, rate];
} }

File diff suppressed because it is too large Load diff

1816
sae/cia.js

File diff suppressed because it is too large Load diff

View file

@ -12,23 +12,22 @@ function Config() {
this.init = false; this.init = false;
this.cpu = { this.cpu = {
model: 68000, model: 0,
speed: 0, /* 0 if cpu.exact */ speed: 0,
exact: false, compatible: false
compatible: true
}; };
this.blitter = { this.blitter = {
exact: false, /* do not change */ immediate: false,
immediate: false, /* false if blitter.exact */ waiting: 0
waiting: 1 /* 0 if cpu.exact or blitter.immediate */
}; };
this.chipset = { this.chipset = {
type: 0, mask: 0,
agnus: 0, agnus_dip: 0,
agnus_rev: 0, agnus_rev: 0,
denise: 0, denise_rev: 0,
paula: 0, collision_level: 0,
colLevel: 0 genlock: false,
refreshrate: 0
}; };
this.ram = { this.ram = {
chip: { chip: {
@ -71,17 +70,25 @@ function Config() {
speed:0 speed:0
}; };
this.video = { this.video = {
id: '',
enabled: false, enabled: false,
scale: false, scale: false,
ntsc: false, ntsc: false, //~
skip: false, framerate: 0,
id: '' hresolution: 0,
vresolution: 0,
scandoubler: false,
scanlines: false,
extrawidth: 0,
xcenter: 0,
ycenter: 0
}; };
this.audio = { this.audio = {
enabled: false, enabled: false,
mode:0, mode:0,
channels: 0, channels: 0,
rate: 0 rate: 0,
filter: false
}; };
this.ports = [{ this.ports = [{
type: 0, type: 0,
@ -102,6 +109,10 @@ function Config() {
this.rtc = { this.rtc = {
type: 0 type: 0
}; };
this.cia = {
tod: 0,
tod_hack: 0
};
this.hooks = { this.hooks = {
error: null, error: null,
power_led: null, power_led: null,
@ -110,79 +121,94 @@ function Config() {
fps: null, fps: null,
cpu: null cpu: null
}; };
}
function configSetDefaults(c) { function configSetDefaults(c) {
c.init = true; c.init = true;
c.cpu.speed = SAEV_Config_CPU_Speed_Original; c.cpu.model = 68000;
c.cpu.speed = SAEV_Config_CPU_Speed_Original;
c.cpu.compatible = false;
c.chipset.type = SAEV_Config_Chipset_Type_OCS; //c.chipset.mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
if (c.chipset.type == SAEV_Config_Chipset_Type_OCS) { //c.chipset.mask = CSMASK_ECS_AGNUS;
c.chipset.agnus = c.video.ntsc ? AGNUS_8370 : AGNUS_8371; c.chipset.mask = 0;
c.chipset.agnus_rev = 0; c.chipset.agnus_dip = false; /* A1000 */
c.chipset.denise = DENISE_8362; c.chipset.agnus_rev = -1;
} else if (c.chipset.type == SAEV_Config_Chipset_Type_ECS) { c.chipset.denise_rev = -1;
c.chipset.agnus = AGNUS_8372; c.chipset.collision_level = SAEV_Config_Chipset_ColLevel_None;
c.chipset.agnus_rev = 5; c.chipset.genlock = false;
c.chipset.denise = DENISE_8373; c.chipset.refreshrate = -1;
c.blitter.immediate = 0 ? true : false;
c.blitter.waiting = 1; /* 0 if blitter.immediate */
c.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K;
c.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K;
c.ram.fast.size = SAEV_Config_RAM_Fast_Size_1M;
c.rom.size = SAEV_Config_ROM_Size_None;
c.rom.data = null;
c.ext.addr = SAEV_Config_EXT_Addr_E0;
c.ext.size = SAEV_Config_EXT_Size_None;
c.ext.data = null;
c.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD;
c.floppy.drive[0].name = null;
c.floppy.drive[0].data = null;
c.floppy.drive[1].type = SAEV_Config_Floppy_Type_35_DD;
c.floppy.drive[1].name = null;
c.floppy.drive[1].data = null;
c.floppy.drive[2].type = SAEV_Config_Floppy_Type_None;
c.floppy.drive[2].name = null;
c.floppy.drive[2].data = null;
c.floppy.drive[3].type = SAEV_Config_Floppy_Type_None;
c.floppy.drive[3].name = null;
c.floppy.drive[3].data = null;
c.floppy.speed = SAEV_Config_Floppy_Speed_Original;
c.video.id = 'video';
c.video.enabled = true;
c.video.scale = false;
c.video.ntsc = false;
c.video.framerate = 2;
c.video.hresolution = 1 ? RES_HIRES : RES_LORES;
c.video.vresolution = 1 ? VRES_DOUBLE : VRES_NONDOUBLE;
c.video.scandoubler = 0 ? true : false;
c.video.scanlines = 0 ? true : false;
c.video.extrawidth = 0;
c.video.xcenter = 0;
c.video.ycenter = 0
c.audio.enabled = true;
//c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
c.audio.mode = SAEV_Config_Audio_Mode_Play;
c.audio.channels = SAEV_Config_Audio_Channels_Stereo;
c.audio.rate = SAEV_Config_Audio_Rate_44100;
c.audio.filter = false;
c.ports[0].type = SAEV_Config_Ports_Type_Mouse;
c.ports[0].move = SAEV_Config_Ports_Move_WASD;
c.ports[0].fire[0] = 49;
c.ports[0].fire[1] = 50;
c.ports[1].type = SAEV_Config_Ports_Type_Joy1;
c.ports[1].move = SAEV_Config_Ports_Move_Arrows;
c.ports[1].fire[0] = 16;
c.ports[1].fire[1] = 17;
c.keyboard.enabled = true;
c.keyboard.mapShift = false;
c.rtc.type = 1 ? SAEV_Config_RTC_Type_MSM6242B : SAEV_Config_RTC_Type_RF5C01A;
c.cia.tod = 0;
c.cia.tod_hack = true;
c.hooks.error = function(err, msg) {}
c.hooks.power_led = function(on) {}
c.hooks.floppy_motor = function(unit, on) {}
c.hooks.floppy_step = function(unit, cyl) {}
c.hooks.fps = function(fps) {}
c.hooks.cpu = function(usage) {}
} }
c.chipset.paula = PAULA_8364; configSetDefaults(this);
c.chipset.colLevel = SAEV_Config_Chipset_ColLevel_None;
c.ram.chip.size = SAEV_Config_RAM_Chip_Size_512K;
c.ram.slow.size = SAEV_Config_RAM_Slow_Size_512K;
c.ram.fast.size = SAEV_Config_RAM_Fast_Size_512K;
c.rom.size = SAEV_Config_ROM_Size_None;
c.rom.data = null;
c.ext.addr = SAEV_Config_EXT_Addr_E0;
c.ext.size = SAEV_Config_EXT_Size_None;
c.ext.data = null;
c.floppy.drive[0].type = SAEV_Config_Floppy_Type_35_DD;
c.floppy.drive[0].name = null;
c.floppy.drive[0].data = null;
c.floppy.drive[1].type = SAEV_Config_Floppy_Type_35_DD;
c.floppy.drive[1].name = null;
c.floppy.drive[1].data = null;
c.floppy.drive[2].type = SAEV_Config_Floppy_Type_None;
c.floppy.drive[2].name = null;
c.floppy.drive[2].data = null;
c.floppy.drive[3].type = SAEV_Config_Floppy_Type_None;
c.floppy.drive[3].name = null;
c.floppy.drive[3].data = null;
c.floppy.speed = SAEV_Config_Floppy_Speed_Original;
c.video.enabled = true;
c.video.scale = false;
c.video.ntsc = false;
c.video.skip = true;
c.video.id = 'video';
c.audio.enabled = true;
c.audio.mode = SAEV_Config_Audio_Mode_Play_Best;
c.audio.channels = SAEV_Config_Audio_Channels_Stereo;
c.audio.rate = SAEV_Config_Audio_Rate_44100;
c.ports[0].type = SAEV_Config_Ports_Type_Mouse;
c.ports[0].move = SAEV_Config_Ports_Move_WASD;
c.ports[0].fire[0] = 49;
c.ports[0].fire[1] = 50;
c.ports[1].type = SAEV_Config_Ports_Type_Joy1;
c.ports[1].move = SAEV_Config_Ports_Move_Arrows;
c.ports[1].fire[0] = 16;
c.ports[1].fire[1] = 17;
c.keyboard.enabled = true;
c.keyboard.mapShift = false;
c.rtc.type = 1 ? SAEV_Config_RTC_Type_MSM6242B : SAEV_Config_RTC_Type_RF5C01A;
c.hooks.error = function(err, msg) {}
c.hooks.power_led = function(on) {}
c.hooks.floppy_motor = function(unit, on) {}
c.hooks.floppy_step = function(unit, cyl) {}
c.hooks.fps = function(fps) {}
c.hooks.cpu = function(usage) {}
} }

View file

@ -9,7 +9,7 @@
**************************************************************************/ **************************************************************************/
const SAEV_Version = 0; const SAEV_Version = 0;
const SAEV_Revision = 7; const SAEV_Revision = 8;
const SAEV_Revision_Sub = 0; const SAEV_Revision_Sub = 0;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -19,6 +19,15 @@ const SAEV_Null = null;
const SAEV_True = true; const SAEV_True = true;
const SAEV_False = false; const SAEV_False = false;
/*-----------------------------------------------------------------------*/
/* info */
const SAEI_Audio_Webkit = 1;
const SAEI_Audio_Mozilla = 2;
const SAEI_Video_Canvas2D = 1;
const SAEI_Video_WebGL = 2;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* cpu */ /* cpu */
@ -29,11 +38,18 @@ const SAEV_Config_CPU_Speed_Original = 0;
/* chipset */ /* chipset */
const SAEV_Config_Chipset_Type_OCS = 1; const SAEV_Config_Chipset_Type_OCS = 1;
const SAEV_Config_Chipset_Type_ECS = 2; const SAEV_Config_Chipset_Type_ECS_AGNUS = 2;
const SAEV_Config_Chipset_Type_ECS_DENISE = 3;
const SAEV_Config_Chipset_Mask_OCS = 0;
const SAEV_Config_Chipset_Mask_ECS_AGNUS = 1;
const SAEV_Config_Chipset_Mask_ECS_DENISE = 1 | 2;
const SAEV_Config_Chipset_ColLevel_None = 0; const SAEV_Config_Chipset_ColLevel_None = 0;
const SAEV_Config_Chipset_ColLevel_Sprite_Sprite = 1; const SAEV_Config_Chipset_ColLevel_Sprite_Sprite = 1;
const SAEV_Config_Chipset_ColLevel_Sprite_Playfield = 2; const SAEV_Config_Chipset_ColLevel_Sprite_Playfield = 2;
const SAEV_Config_Chipset_ColLevel_Full = 3;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* ram */ /* ram */
@ -158,10 +174,10 @@ var BUG = null;
var AMIGA = null; var AMIGA = null;
const CMD_STOP = 0; const ST_STOP = 0;
const CMD_CYCLE = 1; const ST_CYCLE = 1;
const CMD_PAUSE = 2; const ST_PAUSE = 2;
const CMD_IDLE = 3; const ST_IDLE = 3;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* events */ /* events */
@ -171,51 +187,18 @@ const EV_AUDIO = 1;
const EV_MISC = 2; const EV_MISC = 2;
const EV_HSYNC = 3; const EV_HSYNC = 3;
const EV_MAX = 4; const EV_MAX = 4;
//const EV_COPPER = ;
//const EV_BLITTER = ;
//const EV_RENDER = ;
const EV2_BLITTER = 0; const EV2_BLITTER = 0;
const EV2_DISK = 1; const EV2_DISK = 1;
const EV2_MISC = 2; const EV2_DMAL = 2;
const EV2_MAX = 12; const EV2_MISC = 3;
const EV2_MAX = 3 + 10;
const CYCLE_UNIT = 512; const CYCLE_UNIT = 512;
const CYCLE_UNIT_INV = 1.0 / CYCLE_UNIT; /* mul is always faster than div */ const CYCLE_UNIT_INV = 1.0 / CYCLE_UNIT; /* mul is always faster than div */
const CYCLE_MAX = 0xffffffff * CYCLE_UNIT; const CYCLE_MAX = 0xffffffff * CYCLE_UNIT;
/*-----------------------------------------------------------------------*/
/* cia */
const CIA_A = 1;
const CIA_B = 2;
const ECLOCK_DATA_CYCLE = 4;
const ECLOCK_WAIT_CYCLE = 6;
const DIV10 = ((ECLOCK_DATA_CYCLE + ECLOCK_WAIT_CYCLE) * CYCLE_UNIT) >> 1;
const CIA_RETHINK_DELAY = (CYCLE_UNIT << 1) + (CYCLE_UNIT >> 1);
/*-----------------------------------------------------------------------*/
/* config */
//OCS
const AGNUS_8361 = 1; /* Amiga 1000 NTSC */
const AGNUS_8367 = 2; /* Amiga 1000 PAL */
const AGNUS_8370 = 3; /* OCS NTSC */
const AGNUS_8371 = 4; /* OCS PAL */
//ECS
const AGNUS_8372 = 5; /* ECS */
//AGA
const AGNUS_8374 = 6; /* AGA */
const DENISE_8362 = 1; /* OCS */
const DENISE_8373 = 2; /* ECS */
const PAULA_8364 = 1;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* cpu */ /* cpu */
@ -227,9 +210,7 @@ const SPCFLAG_TRACE = 64;
const SPCFLAG_DOTRACE = 128; const SPCFLAG_DOTRACE = 128;
const SPCFLAG_DOINT = 256; const SPCFLAG_DOINT = 256;
const SPCFLAG_BLTNASTY = 512; const SPCFLAG_BLTNASTY = 512;
//const SPCFLAG_EXEC = 1024; const SPCFLAG_TRAP = 1024;
//const SPCFLAG_ACTION_REPLAY = 2048;
//const SPCFLAG_TRAP = 4096;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* amiga */ /* amiga */
@ -272,25 +253,9 @@ const DMAF_SETCLR = 1 << 15;
const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT; const INT_PROCESSING_DELAY = 3 * CYCLE_UNIT;
/*-----------------------------------------------------------------------*/
/* copper */
/*const COP_STOP = 0;
const COP_READ = 1;
const COP_MOVE = 2;
const COP_WAIT = 3;
const COP_SKIP = 4;*/
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* blitter */ /* blitter */
/*const BLT_STOP = 0;
const BLT_INIT = 1;
const BLT_READ = 2;
const BLT_WORK = 3;
const BLT_WRITE = 4;
const BLT_NEXT = 5;*/
const BLT_done = 0; const BLT_done = 0;
const BLT_init = 1; const BLT_init = 1;
const BLT_read = 2; const BLT_read = 2;
@ -302,16 +267,124 @@ const BLT_next = 5;
/* video */ /* video */
const VIDEO_WIDTH = 720; /* == 360*2 */ const VIDEO_WIDTH = 720; /* == 360*2 */
const VIDEO_HEIGHT = 576; /* == 288*2 */ const VIDEO_HEIGHT = 568; /* == 284*2 */
const VIDEO_DEPTH = 32;
/*-----------------------------------------------------------------------*/
/* playfield */
const MAX_FRAMESKIP_COUNT = 4;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* audio */ /* audio */
const PERIOD_MIN = 4; const PERIOD_MIN = 4;
const PERIOD_MIN_NONCE = 60; const PERIOD_MIN_NONCE = 60;
const PERIOD_MAX = 0xffffffff; const PERIOD_MAX = 0xffffffff * CYCLE_UNIT;
/*-----------------------------------------------------------------------*/
/* playfield, sprites */
const CUSTOM_SIMPLE = 0;
const SMART_UPDATE = 0;
const MAXHPOS = 227;
const MAXHPOS_PAL = 227;
const MAXHPOS_NTSC = 227;
const MAXVPOS = 312;
const MAXVPOS_PAL = 312;
const MAXVPOS_NTSC = 262;
const VBLANK_ENDLINE_PAL = 26;
const VBLANK_ENDLINE_NTSC = 21;
const VBLANK_SPRITE_PAL = 25;
const VBLANK_SPRITE_NTSC = 20;
const VBLANK_HZ_PAL = 50;
const VBLANK_HZ_NTSC = 60;
const EQU_ENDLINE_PAL = 8;
const EQU_ENDLINE_NTSC = 10;
const CSMASK_ECS_AGNUS = 1;
const CSMASK_ECS_DENISE = 2;
const CSMASK_AGA = 4;
const CSMASK_MASK = (CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA);
const CHIPSET_CLOCK_PAL = 3546895;
const CHIPSET_CLOCK_NTSC = 3579545;
const RES_LORES = 0;
const RES_HIRES = 1;
const RES_SUPERHIRES = 2;
const RES_MAX = 2;
const VRES_NONDOUBLE = 0;
const VRES_DOUBLE = 1;
const VRES_QUAD = 2;
const VRES_MAX = 1;
const DIW_WAITING_START = 0;
const DIW_WAITING_STOP = 1;
const LINE_UNDECIDED = 1;
const LINE_DECIDED = 2;
const LINE_DECIDED_DOUBLE = 3;
const LINE_AS_PREVIOUS = 4;
const LINE_BLACK = 5;
const LINE_REMEMBERED_AS_BLACK = 6;
const LINE_DONE = 7;
const LINE_DONE_AS_PREVIOUS = 8;
const LINE_REMEMBERED_AS_PREVIOUS = 9;
const LOF_TOGGLES_NEEDED = 4;
const NLACE_CNT_NEEDED = 50;
const HARD_DDF_STOP = 0xd4;
const HARD_DDF_START = 0x18;
const MAX_PLANES = 6; /* 8 = AGA */
const AMIGA_WIDTH_MAX = 752 / 2;
const AMIGA_HEIGHT_MAX = 574 / 2;
const DIW_DDF_OFFSET = 1;
const HBLANK_OFFSET = 9;
const DISPLAY_LEFT_SHIFT = 0x38;
const NLN_NORMAL = 0;
const NLN_DOUBLED = 1;
const NLN_UPPER = 2;
const NLN_LOWER = 3;
const NLN_NBLACK = 4;
const PLF_IDLE = 0;
const PLF_START = 1;
const PLF_ACTIVE = 2;
const PLF_PASSED_STOP = 3;
const PLF_PASSED_STOP2 = 4;
const PLF_END = 5;
const FETCH_NOT_STARTED = 0;
const FETCH_STARTED = 1;
const FETCH_WAS_PLANE0 = 2;
const COLOR_TABLE_SIZE = (MAXVPOS + 2) * 2;
const COLOR_CHANGE_BRDBLANK = 0x80000000;
const BPLCON_DENISE_DELAY = 1;
const SPRITE_DEBUG = 0;
const SPRITE_DEBUG_MINY = 0x0;
const SPRITE_DEBUG_MAXY = 0x100;
const SPR0_HPOS = 0x15;
const MAX_SPRITES = 8;
//const AUTOSCALE_SPRITES = 1;
//const SPRBORDER = 0;
const MAX_PIXELS_PER_LINE = 1760;
const MAX_SPR_PIXELS = (((MAXVPOS + 1) * 2 + 1) * MAX_PIXELS_PER_LINE);
const MAX_REG_CHANGE = ((MAXVPOS + 1) * 2 * MAXHPOS);
const MAX_STOP = 30000;
const NO_BLOCK = -3;
const FRAMES_UNTIL_RES_SWITCH = 1;
const MAX_WORDS_PER_LINE = 100;
const DO_SPRITES = 1;
const FAST_COLORS = 0;

View file

@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger * ©2012 Rupert Hausberger
* Commercial use is prohibited. * Commercial use is prohibited.
* *
***************************************************************************
* Notes: Ported from WinUAE 2.5.0
*
**************************************************************************/ **************************************************************************/
//copper_states //copper_states
@ -27,11 +30,31 @@ const COP_strobe_extra = 14;
const COP_start_delay = 15; const COP_start_delay = 15;
function Copper() { function Copper() {
const customdelay = [
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */
0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 0xa0 - 0xde */
/* BPLxPTH/BPLxPTL */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
/* BPLCON0-3,BPLMOD1-2 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
/* SPRxPTH/SPRxPTL */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
/* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/* COLORxx */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* RESERVED */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
];
this.cop1lc = 0; this.cop1lc = 0;
this.cop2lc = 0, this.cop2lc = 0,
this.copcon = 0; this.copcon = 0;
this.enabled_thisline = false; this.enabled_thisline = false;
this.access = false; this.access = false;
this.last_copper_hpos = 0;
var cop_state = { var cop_state = {
/* The current instruction words. */ /* The current instruction words. */
@ -48,8 +71,6 @@ function Copper() {
last_write:0, last_write_hpos:0, last_write:0, last_write_hpos:0,
moveaddr:0, movedata:0, movedelay:0 moveaddr:0, movedata:0, movedelay:0
}; };
var last_copper_hpos = 0;
this.reset = function () { this.reset = function () {
this.copcon = 0; this.copcon = 0;
@ -59,7 +80,7 @@ function Copper() {
this.reset2 = function () { this.reset2 = function () {
cop_state.hpos = 0; cop_state.hpos = 0;
cop_state.last_write = 0; cop_state.last_write = 0;
this.compute_spcflag_copper(AMIGA.events.maxhpos); this.compute_spcflag_copper(AMIGA.playfield.maxhpos);
} }
this.COPCON = function (v) { this.COPCON = function (v) {
@ -96,18 +117,18 @@ function Copper() {
//BUG.info('COPJMP(%d) %d', num, cop_state.state); //BUG.info('COPJMP(%d) %d', num, cop_state.state);
cop_state.vpos = AMIGA.events.vpos; cop_state.vpos = AMIGA.playfield.vpos;
cop_state.hpos = AMIGA.events.hpos() & ~1; cop_state.hpos = AMIGA.playfield.hpos() & ~1;
this.enabled_thisline = false;
cop_state.strobe = num; cop_state.strobe = num;
this.enabled_thisline = false;
if (0) { if (0) {
this.immediate_copper(num); this.immediate_copper(num);
return; return;
} }
if (AMIGA.dmaen(DMAF_COPEN)) if (AMIGA.dmaen(DMAF_COPEN))
this.compute_spcflag_copper(AMIGA.events.hpos()); this.compute_spcflag_copper(AMIGA.playfield.hpos());
else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) { else if (oldstrobe > 0 && oldstrobe != num && cop_state.state_prev == COP_wait) {
/* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */ /* dma disabled, copper idle and accessed both COPxJMPs -> copper stops! */
cop_state.state = COP_stop; cop_state.state = COP_stop;
@ -126,7 +147,7 @@ function Copper() {
this.test_copper_dangerous = function (address) { this.test_copper_dangerous = function (address) {
var addr = address & 0x1fe; var addr = address & 0x1fe;
if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) ? 0 : 0x40) : 0x80)) { if (addr < ((this.copcon & 2) ? ((AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) ? 0 : 0x40) : 0x80)) {
cop_state.state = COP_stop; cop_state.state = COP_stop;
this.enabled_thisline = false; this.enabled_thisline = false;
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
@ -140,11 +161,11 @@ function Copper() {
var oldpos = 0; var oldpos = 0;
cop_state.state = COP_stop; cop_state.state = COP_stop;
cop_state.vpos = AMIGA.events.vpos; cop_state.vpos = AMIGA.playfield.vpos;
cop_state.hpos = AMIGA.events.hpos() & ~1; cop_state.hpos = AMIGA.playfield.hpos() & ~1;
cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc; cop_state.ip = num == 1 ? this.cop1lc : this.cop2lc;
while (pos < (AMIGA.events.maxvpos << 5)) { while (pos < (AMIGA.playfield.maxvpos << 5)) {
if (oldpos > pos) if (oldpos > pos)
pos = oldpos; pos = oldpos;
if (!AMIGA.dmaen(DMAF_COPEN)) if (!AMIGA.dmaen(DMAF_COPEN))
@ -153,8 +174,11 @@ function Copper() {
break; break;
pos++; pos++;
oldpos = pos; oldpos = pos;
cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2); //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip + 2);
cop_state.i1 = AMIGA.mem.chip.data[cop_state.ip >>> 1];
cop_state.i2 = AMIGA.mem.chip.data[(cop_state.ip + 2) >>> 1];
AMIGA.custom.last_value = cop_state.i2;
cop_state.ip += 4; cop_state.ip += 4;
if (!(cop_state.i1 & 1)) { // move if (!(cop_state.i1 & 1)) { // move
cop_state.i1 &= 0x1fe; cop_state.i1 &= 0x1fe;
@ -181,25 +205,18 @@ function Copper() {
} }
this.copper_cant_read = function (hpos, alloc) { this.copper_cant_read = function (hpos, alloc) {
//BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.events.maxhpos); //BUG.info('copper_cant_read2() hpos %d / %d', hpos, AMIGA.playfield.maxhpos);
if (hpos + 1 >= AMIGA.events.maxhpos) // first refresh slot if (hpos + 1 >= AMIGA.playfield.maxhpos) // first refresh slot
return 1; return 1;
if ((hpos == AMIGA.events.maxhpos - 3) && (AMIGA.events.maxhpos & 1) && alloc >= 0) { if ((hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1) && alloc >= 0) {
//if (alloc) alloc_cycle (hpos, CYCLE_COPPER);
return -1; return -1;
} }
return AMIGA.playfield.is_bitplane_dma(hpos); return AMIGA.playfield.is_bitplane_dma(hpos);
} }
/*this.copper_cant_read = function (hpos, alloc) {
var cant = this.copper_cant_read2(hpos, alloc);
//if (cant && debug_dma) record_dma_event (DMA_EVENT_COPPERWANTED, hpos, vpos);
return cant;
}*/
this.custom_store16_copper = function (hpos, addr, value, noget) { this.custom_store16_copper = function (hpos, addr, value, noget) {
//if (addr == 0x88 || addr == 0x8a) //if (addr == 0x88 || addr == 0x8a)
//BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.events.vpos, AMIGA.events.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos); //BUG.info('custom_store16_copper() addr %08x, value %04x | vpos %d hpos %d %d cvcmp %d chcmp %d chpos %d cvpos %d', addr, value, AMIGA.playfield.vpos, AMIGA.playfield.hpos(), hpos, cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos);
//value = debug_wputpeekdma (0xdff000 + addr, value); //value = debug_wputpeekdma (0xdff000 + addr, value);
this.access = true; this.access = true;
var v = AMIGA.custom.store16_real(hpos, addr, value, noget); var v = AMIGA.custom.store16_real(hpos, addr, value, noget);
@ -209,44 +226,17 @@ function Copper() {
this.dump_copper = function (error, until_hpos) { this.dump_copper = function (error, until_hpos) {
BUG.info('\n'); BUG.info('\n');
BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.events.vpos, until_hpos, AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80)); BUG.info('%s: vpos=%d until_hpos=%d vp=%d', error, AMIGA.playfield.vpos, until_hpos, AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80));
BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2); BUG.info('cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04X ci2=%04X', cop_state.vcmp, cop_state.hcmp, cop_state.hpos, cop_state.vpos, cop_state.saved_i1, cop_state.saved_i2);
BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline?1:0); BUG.info('cstate=%d ip=%x SPCFLAGS=%x iscline=%d', cop_state.state, cop_state.ip, AMIGA.spcflags, this.enabled_thisline?1:0);
BUG.info('\n'); BUG.info('\n');
} }
// 'emulate' chip internal delays, not the right place but fast and 99.9% programs this.update = function (until_hpos) {
// use only copper to write BPLCON1 etc.. (exception is HulkaMania/TSP..) var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
// this table should be filled with zeros and done somewhere else..
var customdelay = [
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */
0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 0xa0 - 0xde */
/* BPLxPTH/BPLxPTL */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
/* BPLCON0-3,BPLMOD1-2 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
/* SPRxPTH/SPRxPTL */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
/* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/* COLORxx */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* RESERVED */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
];
/*this.copper_write = function (v) {
this.custom_store16_copper(AMIGA.events.hpos(), v >> 16, v & 0xffff, 0);
}*/
this.update_copper = function (until_hpos) {
var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
var c_hpos = cop_state.hpos; var c_hpos = cop_state.hpos;
//BUG.info('update_copper() until_hpos %d, vp %d', until_hpos, vp); //BUG.info('update() until_hpos %d, vp %d', until_hpos, vp);
if (cop_state.state == COP_wait && vp < cop_state.vcmp) { if (cop_state.state == COP_wait && vp < cop_state.vcmp) {
this.dump_copper('error2', until_hpos); this.dump_copper('error2', until_hpos);
@ -256,11 +246,11 @@ function Copper() {
return; return;
} }
if (until_hpos <= last_copper_hpos) if (until_hpos <= this.last_copper_hpos)
return; return;
if (until_hpos > (AMIGA.events.maxhpos & ~1)) if (until_hpos > (AMIGA.playfield.maxhpos & ~1))
until_hpos = AMIGA.events.maxhpos & ~1; until_hpos = AMIGA.playfield.maxhpos & ~1;
for (;;) { for (;;) {
var old_hpos = c_hpos; var old_hpos = c_hpos;
@ -270,8 +260,8 @@ function Copper() {
break; break;
/* So we know about the fetch state. */ /* So we know about the fetch state. */
//decide_line (c_hpos); AMIGA.playfield.decide_line(c_hpos);
//decide_fetch (c_hpos); AMIGA.playfield.decide_fetch(c_hpos);
if (cop_state.movedelay > 0) { if (cop_state.movedelay > 0) {
cop_state.movedelay--; cop_state.movedelay--;
@ -280,7 +270,7 @@ function Copper() {
} }
} }
if ((c_hpos == AMIGA.events.maxhpos - 3) && (AMIGA.events.maxhpos & 1)) if ((c_hpos == AMIGA.playfield.maxhpos - 3) && (AMIGA.playfield.maxhpos & 1))
c_hpos += 1; c_hpos += 1;
else else
c_hpos += 2; c_hpos += 2;
@ -309,8 +299,6 @@ function Copper() {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.state = COP_strobe_delay2; cop_state.state = COP_strobe_delay2;
//alloc_cycle(old_hpos, CYCLE_COPPER);
//if (debug_dma) record_dma (0x8c, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
cop_state.ip += 2; cop_state.ip += 2;
break; break;
} }
@ -318,10 +306,6 @@ function Copper() {
// Second cycle after COPJMP. This is the strange one. // Second cycle after COPJMP. This is the strange one.
// This cycle does not need to be free // This cycle does not need to be free
// But it still gets allocated by copper if it is free = CPU and blitter can't use it. // But it still gets allocated by copper if it is free = CPU and blitter can't use it.
/*if (this.copper_cant_read(old_hpos, 1)) {
alloc_cycle (old_hpos, CYCLE_COPPER);
if (debug_dma) record_dma (0x1fe, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
}*/
cop_state.state = COP_read1; cop_state.state = COP_read1;
// Next cycle finally reads from new pointer // Next cycle finally reads from new pointer
if (cop_state.strobe == 1) if (cop_state.strobe == 1)
@ -343,8 +327,6 @@ function Copper() {
// but is not allocated, blitter or cpu can still use it. // but is not allocated, blitter or cpu can still use it.
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
//cycle_line[old_hpos] |= CYCLE_COPPER_SPECIAL;
//if (debug_dma) record_dma (0x1fe, AMIGA.mem.load16_chip(cop_state.ip), cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
cop_state.state = COP_read1; cop_state.state = COP_read1;
// Next cycle finally reads from new pointer // Next cycle finally reads from new pointer
if (cop_state.strobe == 1) if (cop_state.strobe == 1)
@ -358,8 +340,6 @@ function Copper() {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.state = COP_read1; cop_state.state = COP_read1;
//alloc_cycle(old_hpos, CYCLE_COPPER);
//if (debug_dma) record_dma (0x1fe, 0, 0xffffffff, old_hpos, vpos, DMARECORD_COPPER);
cop_state.ip = this.cop1lc; cop_state.ip = this.cop1lc;
break; break;
} }
@ -374,9 +354,8 @@ function Copper() {
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
return; return;
} }
cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip); //cop_state.i1 = AMIGA.mem.load16_chip(cop_state.ip);
//alloc_cycle(old_hpos, CYCLE_COPPER); cop_state.i1 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
//if (debug_dma) record_dma (0x8c, cop_state.i1, cop_state.ip, old_hpos, vpos, DMARECORD_COPPER);
cop_state.ip += 2; cop_state.ip += 2;
cop_state.state = COP_read2; cop_state.state = COP_read2;
break; break;
@ -384,8 +363,8 @@ function Copper() {
case COP_read2: { case COP_read2: {
if (this.copper_cant_read(old_hpos, 1)) if (this.copper_cant_read(old_hpos, 1))
continue; continue;
cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip); //cop_state.i2 = AMIGA.mem.load16_chip(cop_state.ip);
//alloc_cycle(old_hpos, CYCLE_COPPER); cop_state.i2 = AMIGA.custom.last_value = AMIGA.mem.chip.data[cop_state.ip >>> 1];
cop_state.ip += 2; cop_state.ip += 2;
cop_state.saved_i1 = cop_state.i1; cop_state.saved_i1 = cop_state.i1;
cop_state.saved_i2 = cop_state.i2; cop_state.saved_i2 = cop_state.i2;
@ -397,18 +376,16 @@ function Copper() {
cop_state.state = COP_skip_in2; cop_state.state = COP_skip_in2;
else else
cop_state.state = COP_wait_in2; cop_state.state = COP_wait_in2;
//if (debug_dma) record_dma (0x8c, cop_state.i2, cop_state.ip - 2, old_hpos, vpos, DMARECORD_COPPER);
} else { // MOVE } else { // MOVE
//uaecptr debugip = cop_state.ip; //uaecptr debugip = cop_state.ip;
var reg = cop_state.i1 & 0x1fe; var reg = cop_state.i1 & 0x1fe;
var data = cop_state.i2; var data = cop_state.i2;
cop_state.state = COP_read1; cop_state.state = COP_read1;
//if (debug_dma) record_dma (reg, data, cop_state.ip - 2, old_hpos, vpos, DMARECORD_COPPER);
this.test_copper_dangerous(reg); this.test_copper_dangerous(reg);
if (!this.enabled_thisline) { if (!this.enabled_thisline) {
//goto out; // was 'dangerous' register -> copper stopped //goto out; // was 'dangerous' register -> copper stopped
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
if (cop_state.ignore_next) if (cop_state.ignore_next)
@ -423,37 +400,41 @@ function Copper() {
cop_state.strobe = 2; cop_state.strobe = 2;
cop_state.state = COP_strobe_delay1; cop_state.state = COP_strobe_delay1;
} else { } else {
/*#if 0 /*if (0) {
event2_newevent2 (1, (reg << 16) | data, copper_write); AMIGA.events.newevent2(1, (reg << 16) | data, function(v) { //copper_write);
#else*/ AMIGA.copper.custom_store16_copper(AMIGA.playfield.hpos(), v >>> 16, v & 0xffff, 0);
// FIX: all copper writes happen 1 cycle later than CPU writes });
if (customdelay[reg >> 1]) { //this.custom_store16_copper(old_hpos, reg, data, 0);
cop_state.moveaddr = reg; } else*/
cop_state.movedata = data; {
cop_state.movedelay = customdelay[cop_state.moveaddr >> 1]; // FIX: all copper writes happen 1 cycle later than CPU writes
} else { if (customdelay[reg >> 1]) {
var hpos2 = old_hpos; cop_state.moveaddr = reg;
this.custom_store16_copper(hpos2, reg, data, 0); cop_state.movedata = data;
hpos2++; cop_state.movedelay = customdelay[cop_state.moveaddr >> 1];
//if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) do_sprites(hpos2); } else {
var hpos2 = old_hpos;
this.custom_store16_copper(hpos2, reg, data, 0);
hpos2++;
if (reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES)
AMIGA.playfield.do_sprites(hpos2);
}
} }
//#endif
} }
//if (debug_copper && !cop_state.ignore_next) record_copper (debugip - 4, old_hpos, vpos);
cop_state.ignore_next = 0; cop_state.ignore_next = 0;
} }
break; break;
} }
case COP_wait1: { case COP_wait1: {
/*#if 0 /*#if 0
if (c_hpos >= (AMIGA.events.maxhpos & ~1) || (c_hpos & 1)) break; if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1)) break;
#endif*/ #endif*/
cop_state.state = COP_wait; cop_state.state = COP_wait;
cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) { if (cop_state.saved_i1 == 0xffff && cop_state.saved_i2 == 0xfffe) {
cop_state.state = COP_waitforever; cop_state.state = COP_waitforever;
@ -461,7 +442,7 @@ function Copper() {
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
if (vp < cop_state.vcmp) { if (vp < cop_state.vcmp) {
@ -469,7 +450,7 @@ function Copper() {
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} }
} }
@ -488,7 +469,6 @@ function Copper() {
/* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */ /* Now we know that the comparisons were successful. We might still have to wait for the blitter though. */
if ((cop_state.saved_i2 & 0x8000) == 0) { if ((cop_state.saved_i2 & 0x8000) == 0) {
//decide_blitter (old_hpos);
if (AMIGA.blitter.getState() != BLT_done) { if (AMIGA.blitter.getState() != BLT_done) {
//We need to wait for the blitter. //We need to wait for the blitter.
cop_state.state = COP_bltwait; cop_state.state = COP_bltwait;
@ -496,20 +476,17 @@ function Copper() {
clr_special(SPCFLAG_COPPER); clr_special(SPCFLAG_COPPER);
//goto out; //goto out;
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
return; return;
} /*else { }
if (debug_dma) record_dma_event (DMA_EVENT_COPPERWAKE, old_hpos, vp);
}*/
} }
//if (debug_copper) record_copper (cop_state.ip - 4, old_hpos, vpos);
cop_state.state = COP_read1; cop_state.state = COP_read1;
break; break;
} }
case COP_skip1: { case COP_skip1: {
var vcmp, hcmp, vp1, hp1; var vcmp, hcmp, vp1, hp1;
if (c_hpos >= (AMIGA.events.maxhpos & ~1) || (c_hpos & 1)) if (c_hpos >= (AMIGA.playfield.maxhpos & ~1) || (c_hpos & 1))
break; break;
if (this.copper_cant_read(old_hpos, 0)) if (this.copper_cant_read(old_hpos, 0))
@ -517,14 +494,13 @@ function Copper() {
vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8;
hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe); hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xfe);
vp1 = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); vp1 = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
hp1 = c_hpos & (cop_state.saved_i2 & 0xfe); hp1 = c_hpos & (cop_state.saved_i2 & 0xfe);
if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done)) if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || AMIGA.blitter.getState() == BLT_done))
cop_state.ignore_next = 1; cop_state.ignore_next = 1;
cop_state.state = COP_read1; cop_state.state = COP_read1;
//if (debug_copper) record_copper (cop_state.ip - 4, old_hpos, vpos);
break; break;
} }
} }
@ -532,7 +508,7 @@ function Copper() {
//out: //out:
cop_state.hpos = c_hpos; cop_state.hpos = c_hpos;
last_copper_hpos = until_hpos; this.last_copper_hpos = until_hpos;
} }
this.compute_spcflag_copper = function (hpos) { this.compute_spcflag_copper = function (hpos) {
@ -545,18 +521,19 @@ function Copper() {
return; return;
if (cop_state.state == COP_wait) { if (cop_state.state == COP_wait) {
var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
if (vp < cop_state.vcmp) if (vp < cop_state.vcmp)
return; return;
} }
// do not use past cycles if starting for the first time in this line // do not use past cycles if starting for the first time in this line
// (write to DMACON for example) hpos+1 for long lines // (write to DMACON for example) hpos+1 for long lines
if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.events.maxhpos) { if (!wasenabled && cop_state.hpos < hpos && hpos < AMIGA.playfield.maxhpos) {
hpos = (hpos + 2) & ~1; hpos = (hpos + 2) & ~1;
if (hpos > 226) if (hpos > AMIGA.playfield.maxhpos_short)
hpos = 226; hpos = AMIGA.playfield.maxhpos_short;
cop_state.hpos = hpos; cop_state.hpos = hpos;
//BUG.info('compute_spcflag_copper() hpos %d %d', hpos, AMIGA.playfield.maxhpos_short);
} }
// if COPJMPx was written while DMA was disabled, advance to next state, // if COPJMPx was written while DMA was disabled, advance to next state,
@ -575,40 +552,39 @@ function Copper() {
//BUG.info('blitter_done_notify() hpos %d', hpos); //BUG.info('blitter_done_notify() hpos %d', hpos);
var vp = AMIGA.events.vpos; var vp = AMIGA.playfield.vpos;
hpos += 3; hpos += 3;
hpos &= ~1; hpos &= ~1;
if (hpos >= AMIGA.events.maxhpos) { if (hpos >= AMIGA.playfield.maxhpos) {
hpos -= AMIGA.events.maxhpos; hpos -= AMIGA.playfield.maxhpos;
vp++; vp++;
} }
cop_state.hpos = hpos; cop_state.hpos = hpos;
cop_state.vpos = vp; cop_state.vpos = vp;
cop_state.state = COP_read1; cop_state.state = COP_read1;
//if (debug_dma) record_dma_event (DMA_EVENT_COPPERWAKE, hpos, vp);
if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.events.vpos) { if (AMIGA.dmaen(DMAF_COPEN) && vp == AMIGA.playfield.vpos) {
this.enabled_thisline = true; this.enabled_thisline = true;
set_special(SPCFLAG_COPPER); set_special(SPCFLAG_COPPER);
} }
} }
this.cycle = function () { this.cycle = function () {
this.update_copper(AMIGA.events.hpos()); this.update(AMIGA.playfield.hpos());
} }
this.sync_copper_with_cpu = function (hpos, do_schedule) { this.sync_copper_with_cpu = function (hpos, do_schedule) {
/* Need to let the copper advance to the current position. */ /* Need to let the copper advance to the current position. */
if (this.enabled_thisline) if (this.enabled_thisline)
this.update_copper(hpos); this.update(hpos);
} }
this.check = function (n) { this.check = function (n) {
if (cop_state.state == COP_wait) { if (cop_state.state == COP_wait) {
var vp = AMIGA.events.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80); var vp = AMIGA.playfield.vpos & (((cop_state.saved_i2 >> 8) & 0x7f) | 0x80);
if (vp < cop_state.vcmp) { if (vp < cop_state.vcmp) {
if (this.enabled_thisline) if (this.enabled_thisline)
BUG.info('COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d', n, vp, AMIGA.events.vpos, cop_state.vcmp, this.enabled_thisline?1:0); BUG.info('COPPER BUG %d: vp=%d vpos=%d vcmp=%d thisline=%d', n, vp, AMIGA.playfield.vpos, cop_state.vcmp, this.enabled_thisline?1:0);
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -24,12 +24,12 @@ function Custom() {
switch (addr & 0x1fe) { switch (addr & 0x1fe) {
case 0x002: v = AMIGA.DMACONR(hpos); break; case 0x002: v = AMIGA.DMACONR(hpos); break;
case 0x004: v = AMIGA.events.VPOSR(); break; case 0x004: v = AMIGA.playfield.VPOSR(); break;
case 0x006: v = AMIGA.events.VHPOSR(); break; case 0x006: v = AMIGA.playfield.VHPOSR(); break;
case 0x00A: v = AMIGA.input.JOY0DAT(); break; case 0x00A: v = AMIGA.input.JOY0DAT(); break;
case 0x00C: v = AMIGA.input.JOY1DAT(); break; case 0x00C: v = AMIGA.input.JOY1DAT(); break;
case 0x00E: v = AMIGA.playfield.sprites.CLXDAT(); break; case 0x00E: v = AMIGA.playfield.CLXDAT(); break;
case 0x010: v = AMIGA.ADKCONR(); break; case 0x010: v = AMIGA.ADKCONR(); break;
case 0x012: v = AMIGA.input.POT0DAT(); break; case 0x012: v = AMIGA.input.POT0DAT(); break;
@ -48,18 +48,18 @@ function Custom() {
break; break;
} }
/*#ifdef AGA /*#ifdef AGA
case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2:
case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
case 0x1BC: case 0x1BE: case 0x1BC: case 0x1BE:
if (AMIGA.config.chipset.type != SAEV_Config_Chipset_Type_AGA) if (!(AMIGA.config.chipset.mask & CSMASK_AGA))
writeonly = true; writeonly = true;
v = COLOR_READ ((addr & 0x3E) / 2); v = COLOR_READ ((addr & 0x3E) >> 1);
break; break;
#endif*/ #endif*/
default: default:
writeonly = true; writeonly = true;
@ -68,22 +68,24 @@ function Custom() {
if (writeonly) { if (writeonly) {
v = this.last_value; v = this.last_value;
if (!noput) { if (!noput) {
var old = this.last_value; var l = 0xffff; //AMIGA.config.cpu.compatible && AMIGA.config.cpu.model == 68000 ? regs.irc : 0xffff;
var l = 0xffff; AMIGA.playfield.decide_line(hpos);
AMIGA.playfield.decide_fetch(hpos);
var r = this.store16_real(hpos, addr, l, 1); var r = this.store16_real(hpos, addr, l, 1);
if (r) { // register don't exist if (r) { /* register don't exist */
if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) { if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS) {
v = l; v = l;
} else { } else {
if ((addr & 0x1fe) == 0) { if ((addr & 0x1fe) == 0) {
/*if (is_cycle_ce()) /*if (is_cycle_ce())
v = this.last_value; v = this.last_value;
else*/ else*/
v = l; v = l;
} }
} }
} else { } else {
if (AMIGA.config.chipset.type == SAEV_Config_Chipset_Type_ECS) if (AMIGA.config.chipset.mask & CSMASK_ECS_AGNUS)
v = 0xffff; v = 0xffff;
else else
v = l; v = l;
@ -98,7 +100,7 @@ function Custom() {
} }
this.load16_2 = function (addr) { this.load16_2 = function (addr) {
var hpos = AMIGA.events.hpos(); var hpos = AMIGA.playfield.hpos();
AMIGA.copper.sync_copper_with_cpu (hpos, 1); AMIGA.copper.sync_copper_with_cpu (hpos, 1);
return this.load16_real(hpos, addr, 0); return this.load16_real(hpos, addr, 0);
@ -129,15 +131,15 @@ function Custom() {
value &= 0xffff; value &= 0xffff;
switch (addr) { switch (addr) {
//case 0x00E: CLXDAT (); break; case 0x00E: AMIGA.playfield.CLXDAT(); break;
case 0x020: AMIGA.disk.DSKPTH(value); break; case 0x020: AMIGA.disk.DSKPTH(value); break;
case 0x022: AMIGA.disk.DSKPTL(value); break; case 0x022: AMIGA.disk.DSKPTL(value); break;
case 0x024: AMIGA.disk.DSKLEN(value, hpos); break; case 0x024: AMIGA.disk.DSKLEN(value, hpos); break;
case 0x026: /* AMIGA.disk.DSKDAT(value). Writing to DMA write registers won't do anything */; break; case 0x026: /* AMIGA.disk.DSKDAT(value). Writing to DMA write registers won't do anything */; break;
case 0x02A: AMIGA.events.VPOSW(value); break; case 0x02A: AMIGA.playfield.VPOSW(value); break;
case 0x02C: AMIGA.events.VHPOSW(value); break; case 0x02C: AMIGA.playfield.VHPOSW(value); break;
case 0x02E: AMIGA.copper.COPCON(value); break; case 0x02E: AMIGA.copper.COPCON(value); break;
case 0x030: AMIGA.serial.SERDAT(value); break; case 0x030: AMIGA.serial.SERDAT(value); break;
case 0x032: AMIGA.serial.SERPER(value); break; case 0x032: AMIGA.serial.SERPER(value); break;
@ -179,13 +181,13 @@ function Custom() {
case 0x088: AMIGA.copper.COPJMP(1, 0); break; case 0x088: AMIGA.copper.COPJMP(1, 0); break;
case 0x08A: AMIGA.copper.COPJMP(2, 0); break; case 0x08A: AMIGA.copper.COPJMP(2, 0); break;
case 0x08E: AMIGA.playfield.DIWSTRT(value); break; case 0x08E: AMIGA.playfield.DIWSTRT(hpos, value); break;
case 0x090: AMIGA.playfield.DIWSTOP(value); break; case 0x090: AMIGA.playfield.DIWSTOP(hpos, value); break;
case 0x092: AMIGA.playfield.DDFSTRT(value); break; case 0x092: AMIGA.playfield.DDFSTRT(hpos, value); break;
case 0x094: AMIGA.playfield.DDFSTOP(value); break; case 0x094: AMIGA.playfield.DDFSTOP(hpos, value); break;
case 0x096: AMIGA.DMACON(value, hpos); break; case 0x096: AMIGA.DMACON(value, hpos); break;
case 0x098: AMIGA.playfield.sprites.CLXCON(value); break; case 0x098: AMIGA.playfield.CLXCON(value); break;
case 0x09A: AMIGA.INTENA(value); break; case 0x09A: AMIGA.INTENA(value); break;
case 0x09C: AMIGA.INTREQ(value); break; case 0x09C: AMIGA.INTREQ(value); break;
case 0x09E: AMIGA.ADKCON(value, hpos); break; case 0x09E: AMIGA.ADKCON(value, hpos); break;
@ -218,40 +220,40 @@ function Custom() {
case 0x0D8: AMIGA.audio.AUDxVOL(3, value); break; case 0x0D8: AMIGA.audio.AUDxVOL(3, value); break;
case 0x0DA: AMIGA.audio.AUDxDAT(3, value); break; case 0x0DA: AMIGA.audio.AUDxDAT(3, value); break;
case 0x0E0: AMIGA.playfield.BPLxPTx(value, 0, 1); break; case 0x0E0: AMIGA.playfield.BPLxPTH(hpos, value, 0); break;
case 0x0E2: AMIGA.playfield.BPLxPTx(value, 0, 0); break; case 0x0E2: AMIGA.playfield.BPLxPTL(hpos, value, 0); break;
case 0x0E4: AMIGA.playfield.BPLxPTx(value, 1, 1); break; case 0x0E4: AMIGA.playfield.BPLxPTH(hpos, value, 1); break;
case 0x0E6: AMIGA.playfield.BPLxPTx(value, 1, 0); break; case 0x0E6: AMIGA.playfield.BPLxPTL(hpos, value, 1); break;
case 0x0E8: AMIGA.playfield.BPLxPTx(value, 2, 1); break; case 0x0E8: AMIGA.playfield.BPLxPTH(hpos, value, 2); break;
case 0x0EA: AMIGA.playfield.BPLxPTx(value, 2, 0); break; case 0x0EA: AMIGA.playfield.BPLxPTL(hpos, value, 2); break;
case 0x0EC: AMIGA.playfield.BPLxPTx(value, 3, 1); break; case 0x0EC: AMIGA.playfield.BPLxPTH(hpos, value, 3); break;
case 0x0EE: AMIGA.playfield.BPLxPTx(value, 3, 0); break; case 0x0EE: AMIGA.playfield.BPLxPTL(hpos, value, 3); break;
case 0x0F0: AMIGA.playfield.BPLxPTx(value, 4, 1); break; case 0x0F0: AMIGA.playfield.BPLxPTH(hpos, value, 4); break;
case 0x0F2: AMIGA.playfield.BPLxPTx(value, 4, 0); break; case 0x0F2: AMIGA.playfield.BPLxPTL(hpos, value, 4); break;
case 0x0F4: AMIGA.playfield.BPLxPTx(value, 5, 1); break; case 0x0F4: AMIGA.playfield.BPLxPTH(hpos, value, 5); break;
case 0x0F6: AMIGA.playfield.BPLxPTx(value, 5, 0); break; case 0x0F6: AMIGA.playfield.BPLxPTL(hpos, value, 5); break;
/*case 0x0F8: AMIGA.playfield.BPLxPTx(value, 6, 1); break; case 0x0F8: AMIGA.playfield.BPLxPTH(hpos, value, 6); break;
case 0x0FA: AMIGA.playfield.BPLxPTx(value, 6, 0); break; case 0x0FA: AMIGA.playfield.BPLxPTL(hpos, value, 6); break;
case 0x0FC: AMIGA.playfield.BPLxPTx(value, 7, 1); break; case 0x0FC: AMIGA.playfield.BPLxPTH(hpos, value, 7); break;
case 0x0FE: AMIGA.playfield.BPLxPTx(value, 7, 0); break;*/ case 0x0FE: AMIGA.playfield.BPLxPTL(hpos, value, 7); break;
case 0x100: AMIGA.playfield.BPLCON0(value); break; case 0x100: AMIGA.playfield.BPLCON0(hpos, value); break;
case 0x102: AMIGA.playfield.BPLCON1(value); break; case 0x102: AMIGA.playfield.BPLCON1(hpos, value); break;
case 0x104: AMIGA.playfield.BPLCON2(value); break; case 0x104: AMIGA.playfield.BPLCON2(hpos, value); break;
//case 0x106: AMIGA.playfield.BPLCON3(value); break; //ECS_DENISE case 0x106: AMIGA.playfield.BPLCON3(hpos, value); break;
case 0x108: AMIGA.playfield.BPL1MOD(value); break; case 0x108: AMIGA.playfield.BPL1MOD(hpos, value); break;
case 0x10A: AMIGA.playfield.BPL2MOD(value); break; case 0x10A: AMIGA.playfield.BPL2MOD(hpos, value); break;
//case 0x10E: AMIGA.playfield.sprites.CLXCON2 (value); break; //AGA //case 0x10E: AMIGA.playfield.CLXCON2(value); break; //AGA
case 0x110: AMIGA.playfield.BPLxDAT(value, 0); break; case 0x110: AMIGA.playfield.BPLxDAT(hpos, value, 0); break;
case 0x112: AMIGA.playfield.BPLxDAT(value, 1); break; case 0x112: AMIGA.playfield.BPLxDAT(hpos, value, 1); break;
case 0x114: AMIGA.playfield.BPLxDAT(value, 2); break; case 0x114: AMIGA.playfield.BPLxDAT(hpos, value, 2); break;
case 0x116: AMIGA.playfield.BPLxDAT(value, 3); break; case 0x116: AMIGA.playfield.BPLxDAT(hpos, value, 3); break;
case 0x118: AMIGA.playfield.BPLxDAT(value, 4); break; case 0x118: AMIGA.playfield.BPLxDAT(hpos, value, 4); break;
case 0x11A: AMIGA.playfield.BPLxDAT(value, 5); break; case 0x11A: AMIGA.playfield.BPLxDAT(hpos, value, 5); break;
//case 0x11C: AMIGA.playfield.BPLxDAT(value, 6); break; case 0x11C: AMIGA.playfield.BPLxDAT(hpos, value, 6); break;
//case 0x11E: AMIGA.playfield.BPLxDAT(value, 7); break; case 0x11E: AMIGA.playfield.BPLxDAT(hpos, value, 7); break;
case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A:
case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196:
@ -259,58 +261,55 @@ function Custom() {
case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE:
case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA:
case 0x1BC: case 0x1BE: case 0x1BC: case 0x1BE:
AMIGA.playfield.COLORxx(value & 0xfff, (addr & 0x3E) >> 1); AMIGA.playfield.COLOR_WRITE(hpos, value & 0xFFF, (addr & 0x3E) >> 1);
break; break;
case 0x120: case 0x124: case 0x128: case 0x12C: case 0x120: case 0x124: case 0x128: case 0x12C:
case 0x130: case 0x134: case 0x138: case 0x13C: case 0x130: case 0x134: case 0x138: case 0x13C:
AMIGA.playfield.sprites.SPRxPTH(value, (addr - 0x120) >> 2); AMIGA.playfield.SPRxPTH(hpos, value, (addr - 0x120) >> 2);
break; break;
case 0x122: case 0x126: case 0x12A: case 0x12E: case 0x122: case 0x126: case 0x12A: case 0x12E:
case 0x132: case 0x136: case 0x13A: case 0x13E: case 0x132: case 0x136: case 0x13A: case 0x13E:
AMIGA.playfield.sprites.SPRxPTL(value, (addr - 0x122) >> 2); AMIGA.playfield.SPRxPTL(hpos, value, (addr - 0x122) >> 2);
break; break;
case 0x140: case 0x148: case 0x150: case 0x158: case 0x140: case 0x148: case 0x150: case 0x158:
case 0x160: case 0x168: case 0x170: case 0x178: case 0x160: case 0x168: case 0x170: case 0x178:
AMIGA.playfield.sprites.SPRxPOS(value, (addr - 0x140) >> 3); AMIGA.playfield.SPRxPOS(hpos, value, (addr - 0x140) >> 3);
break; break;
case 0x142: case 0x14A: case 0x152: case 0x15A: case 0x142: case 0x14A: case 0x152: case 0x15A:
case 0x162: case 0x16A: case 0x172: case 0x17A: case 0x162: case 0x16A: case 0x172: case 0x17A:
AMIGA.playfield.sprites.SPRxCTL(value, (addr - 0x142) >> 3); AMIGA.playfield.SPRxCTL(hpos, value, (addr - 0x142) >> 3);
break; break;
case 0x144: case 0x14C: case 0x154: case 0x15C: case 0x144: case 0x14C: case 0x154: case 0x15C:
case 0x164: case 0x16C: case 0x174: case 0x17C: case 0x164: case 0x16C: case 0x174: case 0x17C:
AMIGA.playfield.sprites.SPRxDATA(value, (addr - 0x144) >> 3); AMIGA.playfield.SPRxDATA(hpos, value, (addr - 0x144) >> 3);
break; break;
case 0x146: case 0x14E: case 0x156: case 0x15E: case 0x146: case 0x14E: case 0x156: case 0x15E:
case 0x166: case 0x16E: case 0x176: case 0x17E: case 0x166: case 0x16E: case 0x176: case 0x17E:
AMIGA.playfield.sprites.SPRxDATB(value, (addr - 0x146) >> 3); AMIGA.playfield.SPRxDATB(hpos, value, (addr - 0x146) >> 3);
break; break;
case 0x36: AMIGA.input.JOYTEST(value); break; case 0x36: AMIGA.input.JOYTEST(value); break;
case 0x5A: AMIGA.blitter.BLTCON0L(hpos, value); break; //ECS case 0x5A: AMIGA.blitter.BLTCON0L(hpos, value); break;
case 0x5C: AMIGA.blitter.BLTSIZV(hpos, value); break; //ECS case 0x5C: AMIGA.blitter.BLTSIZV(hpos, value); break;
case 0x5E: AMIGA.blitter.BLTSIZH(hpos, value); break; //ECS case 0x5E: AMIGA.blitter.BLTSIZH(hpos, value); break;
//case 0x1E4: AMIGA.playfield.DIWHIGH(value); break; //ECS case 0x1E4: AMIGA.playfield.DIWHIGH(hpos, value); break;
//case 0x10C: AMIGA.playfield.BPLCON4(value); break; //AGA //case 0x10C: AMIGA.playfield.BPLCON4(hpos, value); break; //AGA
//#ifndef CUSTOM_SIMPLE case 0x1DC: AMIGA.playfield.BEAMCON0(value); break;
//case 0x1DC: AMIGA.events.BEAMCON0(value); break; case 0x1C0: if (AMIGA.playfield.htotal != value) { AMIGA.playfield.htotal = value; AMIGA.playfield.varsync(); } break;
/*#ifdef ECS_DENISE case 0x1C2: if (AMIGA.playfield.hsstop != value) { AMIGA.playfield.hsstop = value; AMIGA.playfield.varsync(); } break;
case 0x1C0: if (htotal != value) { htotal = value; varsync (); } break; case 0x1C4: if (AMIGA.playfield.hbstrt != value) { AMIGA.playfield.hbstrt = value; AMIGA.playfield.varsync(); } break;
case 0x1C2: if (hsstop != value) { hsstop = value; varsync (); } break; case 0x1C6: if (AMIGA.playfield.hbstop != value) { AMIGA.playfield.hbstop = value; AMIGA.playfield.varsync(); } break;
case 0x1C4: if (hbstrt != value) { hbstrt = value; varsync (); } break; case 0x1C8: if (AMIGA.playfield.vtotal != value) { AMIGA.playfield.vtotal = value; AMIGA.playfield.varsync(); } break;
case 0x1C6: if (hbstop != value) { hbstop = value; varsync (); } break; case 0x1CA: if (AMIGA.playfield.vsstop != value) { AMIGA.playfield.vsstop = value; AMIGA.playfield.varsync(); } break;
case 0x1C8: if (vtotal != value) { vtotal = value; varsync (); } break; case 0x1CC: if (AMIGA.playfield.vbstrt < value || AMIGA.playfield.vbstrt > value + 1) { AMIGA.playfield.vbstrt = value; AMIGA.playfield.varsync(); } break;
case 0x1CA: if (vsstop != value) { vsstop = value; varsync (); } break; case 0x1CE: if (AMIGA.playfield.vbstop < value || AMIGA.playfield.vbstop > value + 1) { AMIGA.playfield.vbstop = value; AMIGA.playfield.varsync(); } break;
case 0x1CC: if (vbstrt < value || vbstrt > value + 1) { vbstrt = value; varsync (); } break; case 0x1DE: if (AMIGA.playfield.hsstrt != value) { AMIGA.playfield.hsstrt = value; AMIGA.playfield.varsync(); } break;
case 0x1CE: if (vbstop < value || vbstop > value + 1) { vbstop = value; varsync (); } break; case 0x1E0: if (AMIGA.playfield.vsstrt != value) { AMIGA.playfield.vsstrt = value; AMIGA.playfield.varsync(); } break;
case 0x1DE: if (hsstrt != value) { hsstrt = value; varsync (); } break; case 0x1E2: if (AMIGA.playfield.hcenter != value) { AMIGA.playfield.hcenter = value; AMIGA.playfield.varsync(); } break;
case 0x1E0: if (vsstrt != value) { vsstrt = value; varsync (); } break;
case 0x1E2: if (hcenter != value) { hcenter = value; varsync (); } break;
endif*/
//endif
//case 0x1FC: FMODE (hpos, value); break; //AGA //case 0x1FC: AMIGA.playfield.FMODE(hpos, value); break; //AGA
//case 0x1FE: FNULL (value); break; //case 0x1FE: FNULL (value); break;
case 0x1FE: break; case 0x1FE: break;
@ -327,7 +326,7 @@ function Custom() {
} }
this.store16 = function (addr, value) { this.store16 = function (addr, value) {
var hpos = AMIGA.events.hpos(); var hpos = AMIGA.playfield.hpos();
AMIGA.copper.sync_copper_with_cpu(hpos, 1); AMIGA.copper.sync_copper_with_cpu(hpos, 1);
if (addr & 1) { if (addr & 1) {
addr &= ~1; addr &= ~1;
@ -339,7 +338,24 @@ function Custom() {
} }
this.store8 = function (addr, value) { this.store8 = function (addr, value) {
this.store16(addr & ~1, ((value << 8) | (value & 0xff)) & 0xffff); var rval;
/*if (AMIGA.config.chipset.mask & CSMASK_AGA) {
if (addr & 1) {
rval = value & 0xff;
} else {
rval = (value << 8) | (value & 0xFF);
}
} else*/
rval = (value << 8) | (value & 0xff);
/*if (AMIGA.config.cpu.model == 68060) {
if (addr & 1)
this.store16(addr & ~1, rval);
else
this.store16(addr, value << 8);
} else*/
this.store16(addr & ~1, rval);
} }
this.store32 = function (addr, value) { this.store32 = function (addr, value) {

View file

@ -6,6 +6,9 @@
* ©2012 Rupert Hausberger * ©2012 Rupert Hausberger
* Commercial use is prohibited. * Commercial use is prohibited.
* *
***************************************************************************
* Notes: Ported from WinUAE 2.5.0
*
**************************************************************************/ **************************************************************************/
const LONGWRITEMODE = 0; const LONGWRITEMODE = 0;
@ -88,7 +91,7 @@ function Drive(number) {
this.cyl = 0; this.cyl = 0;
this.motoroff = true; this.motoroff = true;
this.motordelay = false; /* dskrdy needs some clock cycles before it changes after switching off motor */ this.motordelay = false; /* dskrdy needs some clock cycles before it changes after switching off motor */
this.state = 0; //this.state = 0;
this.wrprot = false; this.wrprot = false;
this.bigmfmbuf = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.bigmfmbuf[i] = 0; this.bigmfmbuf = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.bigmfmbuf[i] = 0;
this.tracktiming = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.tracktiming[i] = 0; this.tracktiming = new Uint16Array(0x4000 * DDHDMULT); for (var i = 0; i < 0x4000 * DDHDMULT; i++) this.tracktiming[i] = 0;
@ -436,7 +439,7 @@ function Drive(number) {
if (AMIGA.config.cpu.model <= 68010 && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Original) { if (AMIGA.config.cpu.model <= 68010 && AMIGA.config.cpu.speed == SAEV_Config_CPU_Speed_Original) {
this.motordelay = true; this.motordelay = true;
AMIGA.events.event2_newevent2(30, this.num, function(v) { AMIGA.disk.motordelay_func(v); }); AMIGA.events.newevent2(30, this.num, function(v) { AMIGA.disk.motordelay_func(v); });
} }
} }
this.motoroff = off; this.motoroff = off;
@ -847,6 +850,7 @@ function Disk() {
AMIGA.config.hooks.floppy_motor(i, false); AMIGA.config.hooks.floppy_motor(i, false);
AMIGA.config.hooks.floppy_step(i, floppy[i].cyl); AMIGA.config.hooks.floppy_step(i, floppy[i].cyl);
} }
this.DSKLEN(0, 0);
for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) { for (var i = 0; i < MAX_FLOPPY_DRIVES; i++) {
this.eject(i); this.eject(i);
this.insert(i); this.insert(i);
@ -1022,9 +1026,8 @@ function Disk() {
var disk_sync_cycle = data >> 8; var disk_sync_cycle = data >> 8;
//BUG.info('Disk.handler() data $%x, flag %d, disk_sync_cycle %d', data, flag, disk_sync_cycle); //BUG.info('Disk.handler() data $%x, flag %d, disk_sync_cycle %d', data, flag, disk_sync_cycle);
//AMIGA.events.eventtab[EV_DISK].active = false; AMIGA.events.remevent(EV2_DISK);
AMIGA.events.event2_remevent(EV2_DISK);
this.update(disk_sync_cycle); this.update(disk_sync_cycle);
if (flag & (DISK_REVOLUTION << 0)) this.fetchnextrevolution(0); if (flag & (DISK_REVOLUTION << 0)) this.fetchnextrevolution(0);
@ -1036,7 +1039,9 @@ function Disk() {
if (flag & DISK_INDEXSYNC) { if (flag & DISK_INDEXSYNC) {
if (!indexdecay) { if (!indexdecay) {
indexdecay = 2; indexdecay = 2;
AMIGA.cia.setICR(CIA_B, 0x10, null); //AMIGA.cia.setICR(CIA_B, 0x10, null);
//AMIGA.cia.diskindex();
AMIGA.cia.SetICRB(0x10, null);
} }
} }
} }
@ -1239,7 +1244,7 @@ function Disk() {
this.doupdate_predict = function(startcycle) { this.doupdate_predict = function(startcycle) {
//BUG.info('Disk.doupdate_predict() startcycle %d', startcycle); //BUG.info('Disk.doupdate_predict() startcycle %d', startcycle);
var finaleventcycle = AMIGA.events.maxhpos << 8; var finaleventcycle = AMIGA.playfield.maxhpos << 8;
var finaleventflag = 0; var finaleventflag = 0;
for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { for (var dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
@ -1252,7 +1257,7 @@ function Disk() {
var tword = word; var tword = word;
var countcycle = startcycle + (floppy[dr].floppybitcounter % floppy[dr].trackspeed); var countcycle = startcycle + (floppy[dr].floppybitcounter % floppy[dr].trackspeed);
var mfmpos = floppy[dr].mfmpos; var mfmpos = floppy[dr].mfmpos;
while (countcycle < (AMIGA.events.maxhpos << 8)) { while (countcycle < (AMIGA.playfield.maxhpos << 8)) {
if (floppy[dr].tracktiming[0]) if (floppy[dr].tracktiming[0])
this.updatetrackspeed(dr, mfmpos); this.updatetrackspeed(dr, mfmpos);
if (dskdmaen != DSKDMA_WRITE || (dskdmaen == DSKDMA_WRITE && !dma_enable)) { if (dskdmaen != DSKDMA_WRITE || (dskdmaen == DSKDMA_WRITE && !dma_enable)) {
@ -1297,18 +1302,8 @@ function Disk() {
} }
} }
if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.events.maxhpos) { if (finaleventflag && (finaleventcycle >>> 8) < AMIGA.playfield.maxhpos)
AMIGA.events.event2_newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag); AMIGA.events.newevent(EV2_DISK, (finaleventcycle - startcycle) >>> 8, ((finaleventcycle >>> 8) << 8) | finaleventflag);
/*var evtime = (finaleventcycle - startcycle) >>> 8;
if (evtime == 0) evtime = 1;
AMIGA.events.eventtab[EV_DISK].active = true;
AMIGA.events.eventtab[EV_DISK].oldcycles = AMIGA.events.currcycle;
AMIGA.events.eventtab[EV_DISK].evtime = AMIGA.events.currcycle + (evtime * CYCLE_UNIT);
AMIGA.events.eventtab[EV_DISK].data = ((finaleventcycle >>> 8) << 8) | finaleventflag;
AMIGA.events.schedule();
*/
}
} }
this.update = function(tohpos) { this.update = function(tohpos) {
@ -1326,7 +1321,7 @@ function Disk() {
return; return;
disk_hpos += cycles; disk_hpos += cycles;
if (disk_hpos >= (AMIGA.events.maxhpos << 8)) if (disk_hpos >= (AMIGA.playfield.maxhpos << 8))
disk_hpos %= (1 << 8); disk_hpos %= (1 << 8);
for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
@ -1429,7 +1424,7 @@ function Disk() {
this.dmafinished(); this.dmafinished();
return; return;
} }
this.update(AMIGA.events.maxhpos); this.update(AMIGA.playfield.maxhpos);
} }
this.update_adkcon = function(v) { this.update_adkcon = function(v) {

File diff suppressed because it is too large Load diff

View file

@ -666,9 +666,10 @@ function Keyboard() {
} }
this.keyReq = function() { this.keyReq = function() {
this.lostsynccnt = 8 * AMIGA.events.maxvpos * 8; /* 8 frames * 8 bits */ this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8; /* 8 frames * 8 bits */
AMIGA.cia.setICR(CIA_A, 8, code); //AMIGA.cia.setICR(CIA_A, 8, code);
AMIGA.cia.SetICRA(8, code);
} }
this.hsync = function() { this.hsync = function() {
@ -696,7 +697,7 @@ function Keyboard() {
this.vsync = function() { this.vsync = function() {
if (this.lostsynccnt > 0) { if (this.lostsynccnt > 0) {
this.lostsynccnt -= AMIGA.events.maxvpos; this.lostsynccnt -= AMIGA.playfield.maxvpos;
if (this.lostsynccnt <= 0) { if (this.lostsynccnt <= 0) {
this.lostsynccnt = 0; this.lostsynccnt = 0;
this.keyReq(); this.keyReq();

View file

@ -197,14 +197,15 @@ function Memory() {
this.res_e0.data = new Uint16Array(this.res_e0.align); for (var i = 0; i < this.res_e0.align; i++) this.res_e0.data[i] = 0; this.res_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.res_f0.data = new Uint16Array(this.res_f0.align); for (var i = 0; i < this.res_f0.align; i++) this.res_f0.data[i] = 0;
AMIGA.mem.copy_rom(AMIGA.config.rom.data); this.copy_rom(AMIGA.config.rom.data);
if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) { if (AMIGA.config.ext.size != SAEV_Config_EXT_Size_None) {
if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0) if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_E0)
AMIGA.mem.copy_e0(AMIGA.config.ext.data); this.copy_e0(AMIGA.config.ext.data);
else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0) else if (AMIGA.config.ext.addr == SAEV_Config_EXT_Addr_F0)
AMIGA.mem.copy_f0(AMIGA.config.ext.data); this.copy_f0(AMIGA.config.ext.data);
} }
//this.mirror_rom_to_chipram();
/*if (AMIGA.config.rom.mode == 1) { /*if (AMIGA.config.rom.mode == 1) {
if (!this.aros.cached) { if (!this.aros.cached) {
@ -281,7 +282,7 @@ function Memory() {
return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8); return (addr & 1) ? (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] & 0xff) : (this.res_f0.data[(addr - this.res_f0.lower) >>> 1] >> 8);
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
return (addr & 1) ? (this.res_d0.data[(addr - this.res_d0.lower) >>> 1] & 0xff) : (this.res_d0.data[(addr - this.res_d0.lower) >>> 1] >> 8); return (addr & 1) ? (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] & 0xff) : (this.res_d8.data[(addr - this.res_d8.lower) >>> 1] >> 8);
} }
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
return AMIGA.expansion.load8(addr); return AMIGA.expansion.load8(addr);
@ -325,7 +326,7 @@ function Memory() {
return this.res_f0.data[(addr - this.res_f0.lower) >>> 1]; return this.res_f0.data[(addr - this.res_f0.lower) >>> 1];
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
return this.res_d0.data[(addr - this.res_d0.lower) >>> 1]; return this.res_d8.data[(addr - this.res_d8.lower) >>> 1];
} }
//else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr); //else BUG.info('Memory.load16() ILLEGAL MEMORY ACCESS addr $%08x', addr);
@ -372,8 +373,8 @@ function Memory() {
return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0; return ((this.res_f0.data[addr] << 16) | this.res_f0.data[addr + 1]) >>> 0;
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
addr = (addr - this.res_d0.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
return ((this.res_d0.data[addr] << 16) | this.res_d0.data[addr + 1]) >>> 0; return ((this.res_d8.data[addr] << 16) | this.res_d8.data[addr + 1]) >>> 0;
} }
//else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr); //else BUG.info('Memory.load32() ILLEGAL MEMORY ACCESS addr $%08x', addr);
@ -442,11 +443,11 @@ function Memory() {
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper) {
if (addr & 1) { if (addr & 1) {
addr = (addr - this.res_d0.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d0.data[addr] = (this.res_d0.data[addr] & 0xff00) | value; this.res_d8.data[addr] = (this.res_d8.data[addr] & 0xff00) | value;
} else { } else {
addr = (addr - this.res_d0.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d0.data[addr] = (value << 8) | (this.res_d0.data[addr] & 0x00ff); this.res_d8.data[addr] = (value << 8) | (this.res_d8.data[addr] & 0x00ff);
} }
} }
else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) { else if (addr >= this.ac_z2.lower && addr < this.ac_z2.upper) {
@ -486,7 +487,7 @@ function Memory() {
this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value; this.res_f0.data[(addr - this.res_f0.lower) >>> 1] = value;
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 1) {
this.res_d0.data[(addr - this.res_d0.lower) >>> 1] = value; this.res_d8.data[(addr - this.res_d8.lower) >>> 1] = value;
} }
//else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value); //else BUG.info('Memory.store16() ILLEGAL MEMORY ACCESS addr $%08x, val %04x', addr, value);
} }
@ -532,9 +533,9 @@ function Memory() {
this.res_f0.data[addr + 1] = value & 0xffff; this.res_f0.data[addr + 1] = value & 0xffff;
} }
else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) { else if (addr >= this.res_d8.lower && addr < this.res_d8.upper - 3) {
addr = (addr - this.res_d0.lower) >>> 1; addr = (addr - this.res_d8.lower) >>> 1;
this.res_d0.data[addr] = value >>> 16; this.res_d8.data[addr] = value >>> 16;
this.res_d0.data[addr + 1] = value & 0xffff; this.res_d8.data[addr + 1] = value & 0xffff;
} }
//else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value); //else if (!(addr & 0xc80000)) BUG.info('Memory.store32() ILLEGAL MEMORY ACCESS addr $%08x, val %08x', addr, value);
} }
@ -555,7 +556,7 @@ function Memory() {
this.chip.data[addr >>> 1] = value; this.chip.data[addr >>> 1] = value;
AMIGA.custom.last_value = value; AMIGA.custom.last_value = value;
} else BUG.info('store16_chip() ILLEGAL MEMORY ACCESS addr %x, value %x', addr, value); } else BUG.info('store16_chip() ILLEGAL MEMORY ACCESS addr %x, value %x', addr, value);
}*/ }
this.load16_chip = function (addr) { this.load16_chip = function (addr) {
if (addr < this.chip.size - 1) if (addr < this.chip.size - 1)
AMIGA.custom.last_value = this.chip.data[addr >>> 1]; AMIGA.custom.last_value = this.chip.data[addr >>> 1];
@ -569,7 +570,7 @@ function Memory() {
this.chip.data[addr >>> 1] = AMIGA.custom.last_value = value; this.chip.data[addr >>> 1] = AMIGA.custom.last_value = value;
else else
AMIGA.custom.last_value = 0xffff; AMIGA.custom.last_value = 0xffff;
} }*/
this.copy_rom = function(data) { this.copy_rom = function(data) {
//BUG.info('copyrom() size %d', data.length); //BUG.info('copyrom() size %d', data.length);
@ -640,13 +641,13 @@ function Memory() {
} }
} }
/*this.mirror_rom_to_chipram = function() { this.mirror_rom_to_chipram = function() {
for (var i = 0; i < this.rom.size; i++) for (var i = 0; i < this.rom.size; i++)
this.chip.data[i] = this.rom.data[i]; this.chip.data[i] = this.rom.data[i];
if (this.ext.size > 0) { /*if (this.ext.size > 0) {
for (var i = 0; i < this.ext.size; i++) for (var i = 0; i < this.ext.size; i++)
this.chip.data[this.rom.size + i] = this.ext.data[i]; this.chip.data[this.rom.size + i] = this.ext.data[i];
} }*/
}*/ }
} }

File diff suppressed because it is too large Load diff

View file

@ -337,6 +337,12 @@ function dump(obj) {
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
function VSync(err, msg) {
this.error = err;
this.message = msg;
}
VSync.prototype = new Error;
function FatalError(err, msg) { function FatalError(err, msg) {
this.error = err; this.error = err;
this.message = msg; this.message = msg;
@ -417,3 +423,59 @@ function Debug() {
} }
} }
} }
/*-----------------------------------------------------------------------*/
function Uint64(hi, lo) {
this.hi = hi;
this.lo = lo;
this.or = function(v) {
this.hi = (this.hi | v.hi) >>> 0;
this.lo = (this.lo | v.lo) >>> 0;
}
this.lshift = function(n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.lo & m;
this.hi = ((this.hi << n) | t) >>> 0;
this.lo = (this.lo << n) >>> 0;
//BUG.info('lshift %d %x', n, m, t);
} else {
var t = this.lo;
this.hi = (t << (n-32)) >>> 0;
this.lo = 0;
//BUG.info('lshift %d %x', n, t);
}
}
}
this.rshift = function(n) {
if (n) {
if (n < 32) {
var m = Math.pow(2, n) - 1;
var t = this.hi & m;
this.hi = (this.hi >>> n) >>> 0;
this.lo = ((t << (32 - n)) | (this.lo >>> n)) >>> 0;
//BUG.info('rshift %d %x %x', n, m, t);
} else {
var t = this.hi;
this.hi = 0;
this.lo = (t >>> (n-32)) >>> 0;
//BUG.info('rshift %d %x %x', n, t);
}
}
}
this.print = function() {
BUG.info('$%08x%08x', this.hi, this.lo);
}
}

View file

@ -34,130 +34,168 @@ function Vide0() {
antialias: false antialias: false
}; };
this.available = 0;
var width = 0; var width = 0;
var height = 0; var height = 0;
var size = 0; var size = 0;
var scale = false;
var pixels = null; var pixels = null;
var div = null; var div = null;
var canvas = null; var canvas = null;
var gl = null; var ctx = null;
var imagedata = null;
var video = null; var video = null;
var open = false; var open = false;
/*---------------------------------*/ /*---------------------------------*/
function getShader(gl, id) { //this.init = function()
{
var test = document.createElement('canvas');
if (test && test.getContext) {
var test2 = test.getContext('2d');
if (test2) {
this.available |= SAEI_Video_Canvas2D;
test2 = null;
}
test = null;
}
test = document.createElement('canvas');
if (test && test.getContext) {
test2 = test.getContext('experimental-webgl', glParams) || test.getContext('webgl', glParams);
if (test2) {
this.available |= SAEI_Video_WebGL;
test2 = null;
}
test = null;
}
//console.log(this.available);
}
/*---------------------------------*/
function getShader(ctx, id) {
var shader, source; var shader, source;
if (id == 'vertex') { if (id == 'vertex') {
shader = gl.createShader(gl.VERTEX_SHADER); shader = ctx.createShader(ctx.VERTEX_SHADER);
source = vertexShader; source = vertexShader;
} else if (id == 'fragment') { } else if (id == 'fragment') {
shader = gl.createShader(gl.FRAGMENT_SHADER); shader = ctx.createShader(ctx.FRAGMENT_SHADER);
source = fragmentShader; source = fragmentShader;
} }
gl.shaderSource(shader, source); ctx.shaderSource(shader, source);
gl.compileShader(shader); ctx.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) if (!ctx.getShaderParameter(shader, ctx.COMPILE_STATUS))
Fatal(SAEE_Video_Shader_Error, gl.getShaderInfoLog(shader)); Fatal(SAEE_Video_Shader_Error, ctx.getShaderInfoLog(shader));
return shader; return shader;
} }
function initGL() { function initGL() {
var vertexShader = getShader(gl, 'vertex'); var vertexShader = getShader(ctx, 'vertex');
var fragmentShader = getShader(gl, 'fragment'); var fragmentShader = getShader(ctx, 'fragment');
var program = gl.createProgram(); var program = ctx.createProgram();
gl.attachShader(program, vertexShader); ctx.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader); ctx.attachShader(program, fragmentShader);
gl.linkProgram(program); ctx.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) if (!ctx.getProgramParameter(program, ctx.LINK_STATUS))
Fatal(SAEE_Video_Shader_Error, 'Can\'t initialise the shaders for WebGL.'); Fatal(SAEE_Video_Shader_Error, 'Can\'t initialise the shaders for WebGL.');
gl.useProgram(program); ctx.useProgram(program);
var positionLocation = gl.getAttribLocation(program, "a_position"); var positionLocation = ctx.getAttribLocation(program, "a_position");
var texCoordLocation = gl.getAttribLocation(program, "a_texCoord"); var texCoordLocation = ctx.getAttribLocation(program, "a_texCoord");
var texCoordBuffer = gl.createBuffer(); var texCoordBuffer = ctx.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); ctx.bindBuffer(ctx.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([
0.0, 0.0, 0.0, 0.0,
1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
1.0, 0.0, 1.0, 0.0,
1.0, 1.0]), gl.STATIC_DRAW); 1.0, 1.0]), ctx.STATIC_DRAW);
gl.enableVertexAttribArray(texCoordLocation); ctx.enableVertexAttribArray(texCoordLocation);
gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0); ctx.vertexAttribPointer(texCoordLocation, 2, ctx.FLOAT, false, 0, 0);
var texture = gl.createTexture(); var texture = ctx.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture); ctx.bindTexture(ctx.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
var resolutionLocation = gl.getUniformLocation(program, "u_resolution"); var resolutionLocation = ctx.getUniformLocation(program, "u_resolution");
gl.uniform2f(resolutionLocation, width, height); ctx.uniform2f(resolutionLocation, width, height);
var buffer = gl.createBuffer(); var buffer = ctx.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(positionLocation); ctx.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); ctx.vertexAttribPointer(positionLocation, 2, ctx.FLOAT, false, 0, 0);
gl.viewport(0, 0, width, height); ctx.viewport(0, 0, width, height);
gl.clearColor(0, 0, 0, 1); ctx.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); ctx.clear(ctx.COLOR_BUFFER_BIT);
gl.colorMask(true, true, true, false); ctx.colorMask(true, true, true, false);
} }
this.setup = function() { this.setup = function() {
if (!AMIGA.config.video.enabled) return; if (!AMIGA.config.video.enabled) return;
if (open) this.cleanup(); if (open) this.cleanup();
width = AMIGA.config.video.scale ? VIDEO_WIDTH << 1 : VIDEO_WIDTH;
height = AMIGA.config.video.scale ? VIDEO_HEIGHT << 1 : VIDEO_WIDTH;
size = width * height;
//BUG.info('Video.init() %d x %d, %s mode', width, height, AMIGA.config.video.ntsc ? 'ntsc' : 'pal');
div = document.getElementById(AMIGA.config.video.id); div = document.getElementById(AMIGA.config.video.id);
if (!div) if (!div)
Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: '+AMIGA.config.video.id+')'); Fatal(SAEE_Video_ID_Not_Found, 'Video DIV-element not found. Check your code. (Malformed-DIV-name: '+AMIGA.config.video.id+')');
if ((canvas = document.createElement('canvas'))) { scale = (this.available & SAEI_Video_WebGL) ? AMIGA.config.video.scale : false;
canvas.width = width; 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.height = height;
} else { canvas.oncontextmenu = function() { return false; }
if (confirm('Can\'t create a CANVAS-element. Continue without video-playback?')) if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
AMIGA.config.video.enabled = false; canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); }
else canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); }
Fatal(SAEE_Video_Canvas_Not_Supported, 'Can\'t create a CANVAS-element. Please update the browser.'); canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); }
} canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); }
if (AMIGA.config.video.enabled) { canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); }
if ((gl = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams))) }
if (this.available & SAEI_Video_WebGL) {
ctx = canvas.getContext('experimental-webgl', glParams) || canvas.getContext('webgl', glParams);
initGL(); 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 else
if (confirm('Can\'t initialise WebGL. Continue without video-playback?')) AMIGA.config.video.enabled = false;
AMIGA.config.video.enabled = false;
else
Fatal(SAEE_Video_WebGL_Not_Avail, 'Can\'t initialise WebGL. Is WebGL enabled in the browser-config?');
} }
if (AMIGA.config.video.enabled) {
pixels = new Uint16Array(size);
for (var i = 0; i < size; i++) pixels[i] = 0;
}
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
canvas.onmousedown = function(e) { AMIGA.input.mouse.mousedown(e); }
canvas.onmouseup = function(e) { AMIGA.input.mouse.mouseup(e); }
canvas.onmouseover = function(e) { AMIGA.input.mouse.mouseover(e); }
canvas.onmouseout = function(e) { AMIGA.input.mouse.mouseout(e); }
canvas.onmousemove = function(e) { AMIGA.input.mouse.mousemove(e); }
}
canvas.oncontextmenu = function() { return false; }
video = document.createElement('div'); video = document.createElement('div');
video.style.width = width + 'px'; video.style.width = width + 'px';
video.style.height = height + 'px'; video.style.height = height + 'px';
@ -168,15 +206,18 @@ function Vide0() {
video.style.mozUserSelect = 'none'; video.style.mozUserSelect = 'none';
video.style.msUserSelect = 'none'; video.style.msUserSelect = 'none';
video.style.userSelect = 'none'; video.style.userSelect = 'none';
video.appendChild(canvas); if (AMIGA.config.video.enabled)
video.appendChild(canvas);
div.appendChild(video); div.appendChild(video);
open = true; open = true;
} }
this.cleanup = function() { this.cleanup = function() {
if (open) { if (open) {
div.removeChild(video); div.removeChild(video);
canvas = null; canvas = null;
imagedata = null;
pixels = null; pixels = null;
video = null; video = null;
open = false; open = false;
@ -189,57 +230,59 @@ function Vide0() {
canvas.style.cursor = hide ? 'none' : 'auto'; canvas.style.cursor = hide ? 'none' : 'auto';
} }
this.clear_pixels = function () { /*this.clear_pixels = function () {
for (var i = 0; i < size; i++) for (var i = 0; i < size; i++)
pixels[i] = 0; pixels[i] = 0;
} }*/
this.drawpixel = function (x, y, rgb) { /*---------------------------------*/
/* Canvas 2D */
function drawpixel_2d(x, y, rgb) {
pixels[y * width + x] = rgb; pixels[y * width + x] = rgb;
} }
this.draw2pixel = function (x, y, rgb) {
var ptr = y * width + x; function drawline_2d(y, data, offs) {
pixels[ptr] = pixels[ptr + 1] = rgb; var yoffs = (y * width) << 2;
} for (var x = 0, d = 0; x < width << 2; x += 4, d++) {
pixels[yoffs + x ] = ((data[offs + d] >> 8) & 0xf) << 4;
this.drawline = function (y, rgb) { pixels[yoffs + x + 1] = ((data[offs + d] >> 4) & 0xf) << 4;
var ptr = y * width; pixels[yoffs + x + 2] = ((data[offs + d] >> 0) & 0xf) << 4;
pixels[yoffs + x + 3] = 255;
for (var i = 0; i < width; i++)
pixels[ptr++] = rgb;
}
this.drawline_from_to = function (x1, x2, y, rgb) {
var ptr = y * width + x1;
for (var i = 0; i < x2 - x1; i++)
pixels[ptr++] = rgb;
}
this.draw = function (rgb, scalex, scaley, colorOnly) {
var r = 0.0625 * (((rgb >> 11) & 31) >> 1);
var g = 0.0625 * (((rgb >> 5) & 63) >> 2);
var b = 0.0625 * ((rgb & 31) >> 1);
gl.viewport(0, 0, width, height);
gl.clearColor(r, g, b, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
if (!colorOnly) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, pixels);
var s = AMIGA.config.video.scale ? 1 : 0;
var x1 = 0;
//var x2 = 0 + (width << (scalex ? (s+1) : s));
var x2 = 0 + (width << s);
var y1 = 0;
var y2 = 0 + (height << (scaley ? (s+1) : s));
//var y2 = 0 + (height << s);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
x1, y1, x2, y1, x1, y2,
x1, y2, x2, y1, x2, y2]), gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
} }
} }
function render_2d() {
ctx.putImageData(imagedata, 0, 0);
}
function show_2d() {}
/*---------------------------------*/
/* WebGL */
function drawpixel_gl(x, y, rgb) {
pixels[y * width + x] = rgb;
}
function drawline_gl(y, data, offs) {
var yoffs = y * width;
for (var x = 0; x < width; x++)
pixels[yoffs + x] = data[offs + x] & 0xffff;
}
function render_gl() {
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGB, width, height, 0, ctx.RGB, ctx.UNSIGNED_SHORT_5_6_5, pixels);
var x1 = 0;
var x2 = width << (scale ? 1 : 0);
var y1 = 0;
var y2 = height << (scale ? 1 : 0);
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]), ctx.STATIC_DRAW);
}
function show_gl() {
ctx.drawArrays(ctx.TRIANGLES, 0, 6);
}
} }