update 0.9.0

This commit is contained in:
Rupert Hausberger 2016-07-15 19:44:16 +02:00
commit fbf36a4fa5
36 changed files with 65950 additions and 22044 deletions

90
disass.htm Normal file
View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>SAE - Scripted Amiga Emulator</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="index.css" />
<script type="text/javascript" src="sae/prototypes.js"></script>
<script type="text/javascript" src="sae/utils.js"></script>
<script type="text/javascript" src="sae/cpu.js"></script>
<script type="text/javascript" src="sae/disassembler.js"></script>
<script type="text/javascript" src="disass.js"></script>
</head>
<body onload="init()">
<div id="base">
<div id="head" class="head">
<noscript>
<div style="height:20px"></div>
<div class="noscript">JavaScript is disabled or not supported!</div>
<div style="height:20px"></div>
</noscript>
<div style="height:8px"></div>
<img src="images/logo.png" alt="Scripted Amiga Emulator" />
</div>
<div id="disass">
Here you can use the internal disassembler. Code-types are from 68000-68030, no FPU, no MMU.<br />
<span class="info">Note: No files or informations about files are transferred to the internet. Disassembling is done in the browser, using javascript.</span>
<div style="height:10px"></div>
<table>
<tr>
<td class="arm"><span class="label">File</span></td>
<td style="width:100%">
<span class="text"><span id="cfg_filename" class="red">&lt;unset&gt; (required)</span></span>
<input id="cfg_file" type="file" style="position:absolute;left:-10000px;top:-10000px;" onchange="updFile()" />
<button class="button" onclick="document.getElementById('cfg_file').click()">Select</button>
</td>
</tr>
</table>
<div style="height:10px"></div>
<table id="disass_cfg">
<tr>
<td>
Offset&nbsp;&dollar;<input id="cfg_offset" type="text" value="0" maxlength="8" onchange="updOffset()" style="width:80px" />
Limit <input id="cfg_limit" type="text" value="32" maxlength="4" onchange="updLimit()" style="width:40px" />instructions
<button class="button" onclick="updNext(1)">Next</button>
</td>
</tr>
<tr>
<td>
Radix
<select id="cfg_radix" size="1" onchange="updRadix()">
<option value="10">Dec (10)</option>
<option value="16" selected="selected">Hex (16)</option>
</select>
Hex-prefix
<select id="cfg_prefx" size="1" onchange="updPrefx()">
<option value="1" selected="selected">&dollar;</option>
<option value="2">0x</option>
</select>
Hex-width
<select id="cfg_width" size="1" onchange="updWidth()">
<option value="0" selected="selected">Auto</option>
<option value="24">24bit (6 chars)</option>
<option value="32">32bit (8 chars)</option>
</select>
<input id="cfg_reloc" type="checkbox" onchange="updReloc()" checked="checked" />Relocate
</td>
</tr>
<tr>
<td>
Show
<input id="cfg_showAddr" type="checkbox" onchange="updShowAddr()" checked="checked" />Address
<input id="cfg_showCode" type="checkbox" onchange="updShowCode()" checked="checked" />Code/Memory
<input id="cfg_case" type="checkbox" onchange="updCase()" />Upper-case
</td>
</tr>
</table>
<div style="height:10px"></div>
<textarea rows="33" readonly="readonly" id="disass_code"></textarea>
</div>
<div style="height:5px"></div>
<div id="foot" class="foot" style="line-height:14px">
<span class="gray">2012-2016 Rupert Hausberger</span> |
<a target="_blank" href="readme.htm">Description</a> |
<span class="gray">Disassembler</span> |
<a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">Source-code</a>
</div>
</div>
</body>
</html>

202
disass.js Normal file
View file

@ -0,0 +1,202 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: This file does not contain any emulator-code.
-------------------------------------------------------------------------*/
var sda = null; /* SDA instance */
var cfg = null; /* reference to the config-object */
var filesize = 0;
var showAddr = true;
var showCode = true;
var upperCase = false;
var result = [];
/*---------------------------------*/
function isHex(str) {
var str_uc = str.toUpperCase();
for (var i = 0; i < str_uc.length; i++) {
var chr = str_uc.charCodeAt(i);
if (!((chr >= 48 && chr <= 57) || (chr >= 65 && chr <= 70)))
return false;
}
return true;
}
/*---------------------------------*/
function getSelectValue(id) {
var e = document.getElementById(id);
for (var i = 0; i < e.length; i++) {
if (e[i].selected) return e[i].value;
}
return false;
}
/*---------------------------------*/
function loadFile(e, callback) {
var reader = new FileReader();
reader.onload = callback;
reader.readAsBinaryString(e);
}
/*---------------------------------*/
function result2text() {
var i, j, text = "";
for (i = 0; i < result.length; i++) {
var addr = result[i][0];
var code = result[i][1];
var words = result[i][2];
var inst = result[i][3];
if (showAddr)
text += sprintf(upperCase ? "$%06X " : "$%06x ", addr);
if (showCode) {
for (j = 0; j < words; j++) text += sprintf(upperCase ? "%04X " : "%04x ", code[j]);
//for (j = words; j < 5; j++) text += "&nbsp;&nbsp;&nbsp;&nbsp; ";
for (j = words; j < 5; j++) text += " ";
}
text += upperCase ? inst.toUpperCase() : inst;
//text += "<br/>";
text += "\n";
if (addr + words*2 >= filesize) break;
}
return text;
}
/*---------------------------------*/
function init() {
try {
sda = new ScriptedDisAssembler();
cfg = sda.getConfig(); /* reference to config */
//console.log(cfg);
} catch(e) {
throw e;
}
}
function disass() {
try {
result = sda.disassemble();
//console.log(result);
document.getElementById("disass_code").value = result2text();
document.getElementById("disass_cfg").style.display = "table";
document.getElementById("disass_code").style.display = "inline";
} catch(e) {
throw e;
}
}
/*---------------------------------*/
function updFile() {
var e = document.getElementById("cfg_file").files[0];
if (!e) return;
loadFile(e, function (event) {
cfg.code = event.target.result;
cfg.offset = 0;
filesize = event.target.result.length;
var fn = document.getElementById("cfg_filename");
fn.className = "";
fn.innerHTML = e.name;
document.getElementById("cfg_offset").value = "0";
disass();
});
}
function updOffset() {
var offset = document.getElementById("cfg_offset");
if (isHex(offset.value)) {
var newoffset = parseInt(offset.value, 16);
if (newoffset < filesize) {
cfg.offset = newoffset;
disass();
} else {
alert(sprintf("The value at 'Offset' is behing the file-size. (max $%x)", filesize - 1));
offset.focus();
}
} else {
alert("The value at 'Offset' in not a hexadecimal number.");
offset.focus();
}
}
function updLimit() {
var limit = document.getElementById("cfg_limit");
//if (isDec(limit.value)) {
cfg.limit = parseInt(limit.value);
disass();
/*} else {
alert("The value at "Limit" in not a decimal number.");
limit.focus();
}*/
}
function updNext() {
var addr = result[result.length - 1][0];
var words = result[result.length - 1][2];
cfg.offset = addr + words*2;
document.getElementById("cfg_offset").value = sprintf("%x", cfg.offset);
disass();
}
function updRadix() {
cfg.radix = parseInt(getSelectValue("cfg_radix"));
disass();
}
function updPrefx() {
cfg.prefx = parseInt(getSelectValue("cfg_prefx")) == 1 ? "$" : "0x";
disass();
}
function updWidth() {
cfg.width = parseInt(getSelectValue("cfg_width"));
disass();
}
function updCase() {
upperCase = document.getElementById("cfg_case").checked;
disass();
}
function updReloc() {
cfg.reloc = document.getElementById("cfg_reloc").checked;
disass();
}
function updShowAddr() {
showAddr = document.getElementById("cfg_showAddr").checked;
disass();
}
function updShowCode() {
showCode = document.getElementById("cfg_showCode").checked;
disass();
}

BIN
images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

423
index.css
View file

@ -1,65 +1,108 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
-------------------------------------------------------------------------*/
a:link { color:#2040c0; text-decoration:none; }
a:visited { color:#2040c0; text-decoration:none; }
a:hover { color:#2040c0; text-decoration:underline; }
.alt { text-align:left; vertical-align:top; }
.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; }
.act { text-align:center; vertical-align:top; }
.acm { text-align:center; vertical-align:middle; }
.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; }
.art { text-align:right; vertical-align:top; }
.arm { text-align:right; vertical-align:middle; }
.armb { text-align:right; vertical-align:middle; font-weight:bold; }
.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; }
.armsg { text-align:right; vertical-align:middle; font-size:x-small; color:gray; }
.arb { text-align:right; vertical-align:bottom; }
.fsxs { font-size:x-small; }
.fsl { font-size:large; }
.fwb { font-weight:bold; }
.info {
font-size:x-small;
color:gray;
vertical-align:text-top;
}
.gray { color:gray; }
.green { color:green; }
.red { color:red; }
a:link { color:#24c; text-decoration:none; }
a:visited { color:#24c; text-decoration:none; }
a:hover { color:#24c; text-decoration:underline; }
body {
top:0;
left:0;
margin:0;
padding:0;
font-family:verdana,serif;
font-size:small;
background-color:#fff;
font-family:Verdana;
font-size:13px;
background-color:#f8f8f8;
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
table {
white-space:nowrap;
}
td {
text-align:left;
vertical-align:top;
}
textarea {
resize:none;
font-size:13px;
font-family:monospace;
border-left:1px solid #ccc;
border-top:1px solid #ccc;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
}
input[type=text] {
font-size:13px;
border-left:1px solid #ccc;
border-top:1px solid #ccc;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
}
/*---------------------------------*/
.gray { color:gray; }
.green { color:green; }
.orange { color:orange; }
.red { color:red; }
.alt { text-align:left; vertical-align:top; }
.alm { text-align:left; vertical-align:middle; }
.alb { text-align:left; vertical-align:bottom; }
.act { text-align:center; vertical-align:top; }
.acm { text-align:center; vertical-align:middle; }
.acb { text-align:center; vertical-align:bottom; }
.art { text-align:right; vertical-align:top; }
.arm { text-align:right; vertical-align:middle; }
.arb { text-align:right; vertical-align:bottom; }
.label {
font-size:11px;
font-weight:bold;
color:#333;
}
.info {
font-size:11px;
color:dimgray;
}
.warn {
font-size:11px;
color:red;
}
.noscript {
margin:auto;
padding:4px;
font-size:17px;
font-weight:bold;
font-size:medium;
text-align:center;
color:red;
}
.hr {
width:100%;
border-top:1px solid #ccc;
}
.head {
width:100%;
margin:auto;
@ -69,123 +112,195 @@ body {
.foot {
width:100%;
margin:auto;
font-size:11px;
text-align:center;
font-size:x-small;
}
#config_simple {
width:780px;
padding:10px;
margin:auto;
border:1px solid #ccc;
background-color:#fcfcfc;
}
.config_simple_hof {
width:380px;
margin:auto;
padding:10px;
border:1px solid #ccc;
background-color:#f8f8f8;
}
#cfg_info td {
padding:2px;
}
#config_advanced {
width:780px;
margin:auto;
padding:10px;
border:1px solid #ccc;
background-color:#f8f8f8;
display:none;
}
#config_advanced table {
.linehoriz {
width:100%;
line-height:20px;
border-top:1px solid #bbb;
}
#config .tl {
border-top:1px solid #ccc;
.text {
border-left:1px solid #bbb;
border-top:1px solid #bbb;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#fff;
-webkit-touch-callout:text;
-webkit-user-select:text;
-khtml-user-select:text;
-moz-user-select:text;
-ms-user-select:text;
user-select:text;
}
#config .bl {
border-bottom:1px solid #ccc;
}
#config .wauto {
width:auto;
/*---------------------------------*/
#myVideo {
margin:auto;
}
/*---------------------------------*/
#config select {
border:1px solid #ccc;
border-left:2px solid #fff;
border-top:2px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
}
#config .button {
width:100px;
border:1px solid #ccc;
background-color:#fff;
width:75px;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
}
#config .button:hover {
background-color:#eee;
background-color:#e8e8e8;
}
#config .sbutton {
width:100px;
padding:2px;
font-weight:bold;
border:1px solid #ccc;
background-color:#fff;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
}
#config .sbutton:hover {
background-color:#eee;
background-color:#e8e8e8;
}
#cfg_demo, #cfg_game {
#config_database {
width:720px;
padding:10px;
margin:auto;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f0f0f0;
}
#config_database_hof {
width:75%;
margin:auto;
padding:10px;
border-left:1px solid #bbb;
border-top:1px solid #bbb;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#e8e8e8;
}
#config_database_hof .ctrl {
padding:2px;
margin:0;
border-left:1px solid #bbb;
border-top:1px solid #bbb;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#f0f0f0;
}
#config_advanced {
width:720px;
margin:auto;
padding:10px;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f0f0f0;
display:none;
}
#config_advanced table {
width:100%;
}
#config_advanced .menu {
padding:10px;
border-left:1px solid #ccc;
border-top:1px solid #ccc;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#e8e8e8;
}
#config_advanced .menu a:link {
font-size:13px;
color:#000;
text-decoration:none;
}
#config_advanced .menu a:hover {
color:#888;
text-decoration:none;
}
#config_advanced .page {
padding:10px;
border-left:1px solid #ccc;
border-top:1px solid #ccc;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#e8e8e8;
display:none;
}
#cfg_page_video input[type="text"] {
width:60px;
}
/*---------------------------------*/
#emul {
display:none;
}
#status {
width:720px;
margin:auto;
padding:2px;
text-align:center;
font-size:x-small;
color:#888;
background-color:#000;
}
#status table {
margin:auto;
}
#dskchg, #dskchg_simple {
display:none;
width:720px;
margin:auto;
padding:2px;
text-align:center;
font-size:x-small;
color:#888;
background-color:#000;
}
#dskchg, #dskchg_simple table {
margin:auto;
}
.dbutton {
#emul button {
width:64px;
font-size:x-small;
font-size:11px;
font-weight:bold;
color:#888;
border:1px solid #888;
background-color:#000;
}
.dbutton:hover {
#emul button:hover {
color:#ccc;
border:1px solid #ccc;
}
#controls_status {
margin:auto;
color:#888;
font-size:9px;
font-weight:bold;
}
#dskchg_database, #dskchg_advanced {
display:none;
}
#dskchg_database table, #dskchg_advanced table {
margin:auto;
}
#dskchg_database select, #dskchg_advanced select {
font-size:11px;
font-weight:bold;
color:#888;
border:1px solid #888;
background-color:#000;
}
/*---------------------------------*/
.readme {
width:1004px;
width:1080px;
margin:auto;
padding:10px;
border:1px solid #ccc;
background-color:#fcfcfc;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f0f0f0;
}
.readme table {
width:100%;
@ -193,15 +308,57 @@ body {
.readme table td {
vertical-align:top;
}
/*div.float_box {
overflow: hidden;
width: 100%;
.readme li {
padding:1px;
}
div.float_item {
float: left;
}
div.float_clear {
clear: both;
}*/
/*---------------------------------*/
#disass {
width:720px;
padding:10px;
margin:auto;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f0f0f0;
}
#disass select {
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
}
#disass input {
border-left:1px solid #bbb;
border-top:1px solid #bbb;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
}
#disass .button {
width:100px;
border-left:1px solid #fff;
border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
}
#disass .button:hover {
background-color:#e8e8e8;
}
#disass_cfg {
border-left:1px solid #bbb;
border-top:1px solid #bbb;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
background-color:#e8e8e8;
display:none;
}
#disass_code {
width:100%;
display:none;
}

2221
index.htm

File diff suppressed because it is too large Load diff

3696
index.js

File diff suppressed because it is too large Load diff

View file

@ -3,121 +3,553 @@
<head>
<title>SAE - Scripted Amiga Emulator</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="icon" type="image/x-icon" href="http://scriptedamigaemulator.net/favicon.ico" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="index.css" />
</head>
<body>
<div class="head">
<noscript>
<div class="noscript">This site does require javascript, obviously :)</div>
</noscript>
<div style="height:8px"></div>
<img src="images/logo.png" alt="Scripted Amiga Emulator" />
</div>
<div class="readme">
<ul>
<li><span class="fwb">Requirements</span>
<li><span class="label">Index</span>
<ul>
<li>A very fast computer</li>
<li>A browser capable of HTML5 with:
<li><a href="readme.htm#goals">Goals</a></li>
<li><a href="readme.htm#requirements">Requirements</a></li>
<li><a href="readme.htm#features">Features</a></li>
<li><a href="readme.htm#limits">Limits</a></li>
<li style="list-style:none"><div style="height:8px"></div></li>
<li><a href="readme.htm#usage">Usage</a></li>
<li><a href="readme.htm#safety">Safety</a></li>
<li><a href="readme.htm#privacy">Privacy</a></li>
<li style="list-style:none"><div style="height:8px"></div></li>
<li><a href="readme.htm#support">Your game or demo</a></li>
<li style="list-style:none"><div style="height:8px"></div></li>
<li><a href="readme.htm#author">Author</a></li>
<li><a href="readme.htm#thanks">Thanks</a></li>
<li><a href="readme.htm#stats">Stats</a></li>
<li style="list-style:none"><div style="height:8px"></div></li>
<li><a href="readme.htm#history">History</a></li>
</ul>
</li>
</ul>
<ul id="goals">
<li><span class="label">Goals</span>
<ul>
<li>Make 'Amiga Classic' Emulation available for browsers.</li>
<li>Browser-plugins or 3rd-party scripts must not be required, just HTML5 and javascript.</li>
<li>Abstraction and API for easy integration to
<ul>
<li>WegGL or Canvas 2D <span class="gray">(optional)</span></li>
<li>WebAudio <span class="gray">(optional)</span></li>
<li>FileReader <span class="gray">(GUI)</span></li>
<li>Typed arrays</li>
<li>play demos, intros or mods.</li>
<li>play games.</li>
<li>or maybe benchmark the browser.</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul id="requirements">
<li><span class="label">Requirements</span>
<ul>
<li>A fast computer in general and a super-computer for (most) AGA-stuff in real-time.</li>
<li>A modern browser capable of HTML5 with:
<ul>
<li>WegGL/Canvas2D- and WebAudio-extensions.</li>
<li>Typed-arrays and FileReader-extension.</li>
<li>The browser should support compilation of javascript-code to native-code. (JIT)</li>
<li>The browser should be able to use multiple cpu-cores on a single thread/tab.</li>
<li>Memory-requirements are between 200MB to 1.5GB depending on configuration and browser.</li>
</ul>
</li>
<li>A ROM:
<ul>
<li>Amiga Kickstart 1.0-2.05 <span class="gray">(not included for copyright reasons)</span></li>
<li>AROS Kickstart <span class="gray">(included)</span></li>
<li>Amiga Kickstart 1.0-3.1 <span class="info">(not included for copyright reasons)</span></li>
<li>AROS Kickstart <span class="info">(included)</span></li>
</ul>
</li>
<li style="list-style-type:none"><br /></li>
<li>And a bunch of ADF-files to test <span class="gray">(optional)</span></li>
<li>A bunch of floppy- or hardfile-images for the advanced-mode.</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Goals</span>
<ul id="features">
<li><span class="label">Features</span> <span class="info">(new = new in latest version 0.9.0)</span>
<ul>
<li>Make Amiga Classic Emulation available for browsers.</li>
<li>Easy integration into websites.</li>
<li>API for control from background, useful e.g. for a demo-player.</li>
<li>Browsers-plugins should not be required, just HTML5 and javascript.</li>
<li>Models
<ul>
<li>A1000/A1000-Velvet <span class="info">(new)</span></li>
<li>A500/A2000</li>
<li>A500+</li>
<li>A600 <span class="info">(new)</span></li>
<li>A1200 <span class="info">(new)</span></li>
<li>A3000 <span class="info">(partial, new)</span></li>
<li>A4000/030 <span class="info">(partial, new)</span></li>
</ul>
</li>
<li>CPUs
<ul>
<li>68000</li>
<li>68010 <span class="info">(new)</span></li>
<li>68020/68030 <span class="info">(new)</span>
<ul>
<li>32-bit support.</li>
<li>Cache support.</li>
<li>Prefetch support.</li>
</ul>
</li>
<li>Variable speeds.</li>
</ul>
</li>
<li>Chipset
<ul>
<li>Original-Chip-Set (OCS)
<ul>
<li>A1000-Agnus (8361 PAL, 8367 NTSC) emulation. <span class="info">(new)</span></li>
</ul>
</li>
<li>Enhanced-Chip-Set (ECS)
<ul>
<li>Partial (Agnus/Denise only) or full emulation. <span class="info">(new)</span></li>
</ul>
</li>
<li>Advanced Graphics Architecture. (AGA) <span class="info">(new)</span></li>
<li>PAL/NTSC-regions.</li>
<li>Sprites-only or full collision-detection.</li>
<li>Full blitter support.</li>
<li>Full copper support.</li>
<li>Full gayle support (A600/A1200) <span class="info">(new)</span>
<ul>
<li>IDE</li>
<li>PCMCIA</li>
</ul>
</li>
<li>Real-Time-Clock (RTC) types
<ul>
<li>MSM6242B</li>
<li>RF5C01A</li>
</ul>
</li>
<li>Complex-Interlace-Adapter (CIA):
<ul>
<li>Different Time-Of-Day (TOD) sources. (Vertical Sync/Power Supply) <span class="info">(new)</span></li>
<li>ROM overlay emulation. (maps ROM from e.g. 0xf80000 to 0x000000 at reset) <span class="info">(new)</span></li>
<li>A1000 Velvet prototype CIA (6526) emulation. <span class="info">(new)</span></li>
</ul>
</li>
</ul>
</li>
<li>RAM
<ul>
<li>256-2048K Chip-ram. (0x000000)</li>
<li>Up to 1536K Slow-/Bogo-ram. (0xC00000)</li>
<li>Up to 64M onboard Fast-ram for A3000/A4000. <span class="info">(new)</span></li>
<li>Up to 8M Zorro2 expansion Fast-ram. (0x200000)</li>
<li>Up to 8M Zorro3 Chip-ram. <span class="info">(new)</span></li>
<li>Up to 1024M (1G) Zorro3 expansion Fast-ram. <span class="info">(new)</span></li>
<li>512K Chip-/512K Bogo-ram to 1024K Chip-ram aliasing. <span class="info">(new)</span></li>
<li>24-/32-bit support. (32-bit memory is required for original A3000/4000-roms and emulation) <span class="info">(new)</span></li>
</ul>
</li>
<li>ROM
<ul>
<li>All kinds of standard and extended kickstart roms.</li>
<li>Support for encrypted Cloanto-roms. (Amiga Forever) <span class="info">(new)</span></li>
<li>Special A1000 kickstart handling. <span class="info">(new)</span></li>
<li>ROM-patcher, which does remove unneeded resident libraries. <span class="info">(new)</span></li>
<li>ROM-mirroring. (mirrors ROM to 0xA80000 or 0xE00000) <span class="info">(new)</span></li>
<li>ShapeShifter-support. <span class="info">(new)</span></li>
<li>AMAX-support. (Mac emulator) <span class="info">(new)</span></li>
<li>ROM-info from internal database. <span class="info">(new)</span></li>
</ul>
</li>
<li>Floppy
<ul>
<li>Supported diskimage-types
<ul>
<li>Standard ADF, read/write (*.adf)</li>
<li>Extended ADF (EXT1/EXT2), read/write (*.adf) <span class="info">(new)</span></li>
<li>PCDOS, read/write (*.img) <span class="info">(new)</span></li>
<li>DMS (DiskMasher), read only (*.dms) <span class="info">(new)</span></li>
<li>SCP (SuperCardPro), read-only (*.scp) <span class="info">(new)</span></li>
<li>EXE, read-only (*.exe) <span class="info">(new)</span></li>
</ul>
</li>
<li>Up to 4 Double-/High-density drives. (DF0-DF3)</li>
<li>Variable drive-speeds. (Original-Turbo).</li>
<li>Drives are write-protectable. <span class="info">(new)</span></li>
<li>Diskimage creation feature. <span class="info">(new)</span></li>
</ul>
</li>
<li>Mount <span class="info">(new)</span>
<ul>
<li>Supported hardfile-types
<ul>
<li>Standard, read/write (*.hdf)</li>
<li>Virtual, read/write (*.vhd)</li>
</ul>
</li>
<li>Up to 4 Onboard-IDE units (IDE0-IDE3) with supported ATA-modes
<ul>
<li>ATA 1</li>
<li>ATA 2</li>
<li>ATA 2 Strict</li>
</ul>
</li>
<li>PCMCIA-slots, configurable as
<ul>
<li>SRAM</li>
<li>HDD</li>
</ul>
</li>
<li>Units are write-protectable.</li>
</ul>
</li>
<li>Video
<ul>
<li>HTML5 WegGL- or Canvas2D-rendering.</li>
<li>2/4 bits-per-pixel modes. <span class="info">(new)</span></li>
<li>Lores-/Hires-/Superhires-types.</li>
<li>Doublescan-types.</li>
<li>Frameskip. (renders every 2nd frame only)</li>
<li>Centering. <span class="info">(new)</span></li>
</ul>
</li>
<li>Audio
<ul>
<li>HTML5 WegAudio-processing.</li>
<li>Samplerates from 11025-48000 Hz.</li>
<li>Mono or Stereo.</li>
<li>Lowpass filter for A500/A1200. <span class="info">(A1200 new)</span></li>
<li>Variable Stereo-channel separation. <span class="info">(new)</span></li>
<li>Different interpolation modes (Anti, RH, Crux) <span class="info">(Anti new)</span></li>
</ul>
</li>
<li>Ports
<ul>
<li>HTML5 mouse-position and buttons import.</li>
<li>HTML5 keyboard import.</li>
<li>Joystick emulation via keyboard.</li>
<li>Mapping of some special keys for pinball-games.</li>
<li>Serial-port. (output to developer-console)</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Possible usage</span>
<ul id="limits">
<li><span class="label">Limits</span>
<ul>
<li>Demo/Intro/Mod-player</li>
<li>Playing games</li>
<li>Browser benchmark</li>
<li>CPUs
<ul>
<li>68000/68010
<ul>
<li>Prefetch is fake.</li>
<li>BKPT is not implemented.</li>
</ul>
</li>
<li>68020
<ul>
<li>CALLM/RTM is not implemented.</li>
<li>Execution-times of instruction and interrupts are not fully correct.</li>
</ul>
</li>
<li>68030
<ul>
<li>MMU is fake.</li>
<li>Execution-times of instruction and interrupts are not fully correct.</li>
</ul>
</li>
<li>Exceptions 2 and 3 are not fully implemented.</li>
<li>Traps are not fully implemented.</li>
</ul>
</li>
<li>Autoconf
<ul>
<li>Zorro2-autoconfig is limited to RAM-devices only.</li>
</ul>
</li>
<li>Floppy
<ul>
<li>No support for compressed floppy-images like ADZ.</li>
<li>No FDI-/IPF-image support.</li>
</ul>
</li>
<li>Mount
<ul>
<li>No onboard-SCSI for the A3000/4000.</li>
<li>No support for compressed hardfile-images like HDZ.</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Usage/Hints</span>
<li style="list-style:none"><div class="linehoriz"></div></li>
</ul>
<ul id="usage">
<li><span class="label">Usage/Hints</span>
<ul>
<li>Press F11 for fullscreen. Most browsers support that.</li>
<li>If something does crash, try another memory setting or a different ROM.<br />
The original kickstart (1.3) does work best.</li>
<li>If something does crash or freeze
<ul>
<li>Try another Amiga-model. A500+ for OCS/ECS and A1200 for AGA does work best.</li>
<li>Use the right rom. Selecting a wrong rom may freeze the emulation. If possible use original kickstart-roms.</li>
<li>If you are using original A3000/4000 kickstart-roms, make sure to enable &quot;32bit address-space&quot; in the CPU-page.</li>
<li>If you are using the AROS kickstart-replacement, you should also give some fast-ram.</li>
<li>Try to enable &quot;Compatible&quot; in the CPU-page.</li>
<li>Try another memory setting or give more memory.</li>
<li>Try to set the floppy-speed back to 1x. Some stuff does not load if &quot;Turbo&quot; is selected.</li>
</ul>
</li>
<li>If hardfiles did not get recognized
<ul>
<li>Select an A600/A1200 at the &quot;Defaults&quot;-page.</li>
<li>Or, go to &quot;Chipset/Features/Manual&quot; and select &quot;Onboard-IDE&quot; or &quot;PCMCIA-slot&quot; manually.</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul id="safety">
<li><span class="label">Safety</span>
<ul>
<li>Whatever you do, you can't harm your computer or change local-files.</li>
<li>Everything is running enclosed in the memory of the browser.</li>
<li>Changes to floppy-/hardfile-images are not stored physically, but to memory only.<br />
Reloading the window/tab (e.g. press F5) does reset all altered floppy-/hardfile-images and configurations.</li>
<li>No Amiga-virus (on floppy-/hardfile-images) can infect your real computer or device.<br />
If you close the window/tab of SAE, all possible viruses will die peacefully.</li>
</ul>
</li>
</ul>
<ul id="privacy">
<li><span class="label">Privacy</span>
<ul>
<li>No files or informations about files, that you are selecting from your computer, are transferred to the internet.<br />
<span class="info">(Note that this may not be the case for other sites, which are using this project.)</span></li>
<li>This site is using google-analytics for visitor-statistics. Other scripts are not used.</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Known bugs/problems</span>
<li style="list-style:none"><div class="linehoriz"></div></li>
</ul>
<ul id="support">
<li><span class="label">Your game or demo</span>
<ul>
<li>Blinking sprites are not shown if "Frameskip" is active.</li>
<li>There may be short and heavy speed-fluctuations in the beginning of the emulation.</li>
<li>Left/right shift/alt/ctrl are the same. That's a browser "feature" and can't be fixed.</li>
<li>If you want to have your game or demo on this site, please contact me.</li>
<li>Your contribution would be published under a free license, with a link to your homepage and would be free to play for everyone.</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Written and ported by</span>
<li style="list-style:none"><div class="linehoriz"></div></li>
</ul>
<ul id="author">
<li><span class="label">Author</span>
<ul>
<li>Rupert Hausberger &lt;<a href="mailto:rupert_hausberger@gmx.net">rupert_hausberger@gmx.net</a>&gt;</li>
<li>Written and ported by: Rupert Hausberger &lt;<a href="mailto:rupert_hausberger@gmx.net">rupert_hausberger@gmx.net</a>&gt;</li>
<li>Source-code: <a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">github.com/naTmeg/ScriptedAmigaEmulator</a></li>
<li>License: <a target="_blank" href="gpl.htm">GPL</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Source-code</span>
<ul id="thanks">
<li><span class="label">Thanks</span>
<ul>
<li><a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">github.com/naTmeg/ScriptedAmigaEmulator</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">License</span>
<ul>
<li><a target="_blank" href="gpl.htm">GPL</a></li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Thanks</span>
<ul>
<!--<li><a target="_blank" href="http://www.amigaemulator.org">Bernd Schmidt</a></li>-->
<li><a target="_blank" href="http://winuae.net">WinUAE team</a></li>
<li><a target="_blank" href="http://winuae.net">WinUAE team</a>, especially Toni Wilen.</li>
<li><a target="_blank" href="http://web.archive.org/web/20130812173347/http://www.amigaemulator.org/">Bernd Schmidt</a>, the father of amiga-emulation.</li>
<li><a target="_blank" href="http://aros.org">AROS team</a></li>
<li>All people who contributed their games. Thanks for your support!</li>
</ul>
</li>
</ul>
<ul id="stats">
<li><span class="label">Stats</span>
<ul>
<li>First public version (0.5)
<ul>
<li>5 months development time.</li>
<li>About the half was written from scratch, the rest was ported from various UAE-sources.</li>
<li>~13.000 lines of code.</li>
</ul>
</li>
<li>Versions (0.6 - 0.8.3)
<ul>
<li>Most code was ported from WinUAE 2.5.0</li>
<li>~33.000 lines of code.</li>
</ul>
</li>
<li>Current version (0.9.0)
<ul>
<li>3 months development time.</li>
<li>~15% was re-written.</li>
<li>~70% was re-ported from WinUAE 3.2.x</li>
<li>~60.000 lines of code.</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><span class="fwb">Some stats</span>
<ul>
<li>About 5 months development time for the first public version. (0.5)</li>
<li>About the half of the first version was written from scratch, the rest was ported from various UAE-sources.</li>
<li>The first version had ~13.000 lines of code, currently ~23.500, most new code is ported from WinUAE.</li>
</ul>
</li>
<li style="list-style:none"><div class="linehoriz"></div></li>
</ul>
<ul>
<li><span class="fwb">History</span>
<ul id="history">
<li><span class="label">History</span>
<ul>
<li><span class="fwb">0.8.3 (22.03.2015)</span>
<li><span class="label">0.9.0 (15.07.2016)</span>
<ul>
<li>CPU
<ul>
<li>Completely rewrote the core.</li>
<li>Added support for the 68010. (5 instructions, 3 registers)</li>
<li>Added support for the 68020. (27 instructions, 2 registers)</li>
<li>Added support for the 68030. (4 instructions)</li>
<li>Exploded each instruction to it's own size-form and sometimes additionally to it's type form.</li>
<li>For faster access, each instruction does now have it's customized parameter-object.</li>
<li>Effective-address access and decoding are now done via 6+1 highspeed function-tables, each 64 entries long.<br />
This does save up to 12 (3*2*2) switch statements per instruction.</li>
<li>Condition-code checking is now done via a 16 entries long function-table instead of a switch-function with 16 entries.</li>
<li>Optimized condition-code calculations.</li>
<li>Fixed/removed DIVU-remainder calculation, also new and faster DIVS.</li>
<li>New and faster versions of ABCD, NBCD, SBCD, ASL, ASR, LSL, LSR, ROL, ROXL, ROR, ROXR.</li>
<li>Fixed MOVEP instruction.</li>
<li>Fixed all 68000/68010 execution-time calculations.</li>
<li>Program-counter calculations are not hardcoded any more.</li>
<li>Ported high-level functions from actual WinUAE.</li>
</ul>
</li>
<li>General
<ul>
<li>Re-ported and optimized the following parts from actual WinUAE:<br />
Audio, Blitter, CIA, Config, Copper, CPU-highlevel, Custom, Disk, Drawing, Events,<br />
Expansion, Filesys, Gayle, Hardfile, IDE, Memory, Roms, Playfield, RTC and Serial</li>
</ul>
</li>
<li>Chipset
<ul>
<li>Custom-chip registers are now accessed via a 256 entries long function-table instead of a switch-function with 256 entries.</li>
<li>Added support for the A1000-Agnus.</li>
</ul>
</li>
<li>CIA
<ul>
<li>Added support for different TOD sources.</li>
<li>Added support for ROM overlay.</li>
<li>Added support for A1000 Velvet prototype.</li>
</ul>
</li>
<li>Blitter
<ul>
<li>Minterms are now calculated via a 256 entries long function-table instead of a switch-function with 256 entries.</li>
</ul>
</li>
<li>RAM
<ul>
<li>Added Zorro3 and 32bit support.</li>
<li>Added support for chip-/bogo-ram aliasing.</li>
<li>Access is now done via function-tables (banks) instead of area-selecting switch-functions.</li>
</ul>
</li>
<li>ROM
<ul>
<li>Added support for encrypted Cloanto-roms. (Amiga Forever)</li>
<li>Added special A1000 kickstart handling.</li>
<li>Added ROM-patcher, which does remove unneeded resident libraries.</li>
<li>Added support for ROM-mirroring.</li>
<li>Added ShapeShifter-support.</li>
<li>Added a ROM-info page.</li>
<li>Updated AROS-ROMs to actual version SVN52764.</li>
</ul>
</li>
<li>Floppy
<ul>
<li>Added 3.5&quot; DD ESCOM and 3.5&quot; DD/HD PC only drive-types.</li>
<li>Added support for the diskspare-format.</li>
<li>Added support for PCDOS-images.</li>
<li>Added support for DMS-images. (DiskMasher)</li>
<li>Added support for SCP-images. (SuperCardPro)</li>
<li>Added support for EXE-images.</li>
<li>Disk can now be inserted from the database.</li>
<li>Drives are now write-protectable.</li>
<li>Added a disk-info page.</li>
</ul>
</li>
<li>Mount
<ul>
<li>Added support for hardfiles. (*.hdf/*.vhd)</li>
<li>Added support for Onboard-IDE (A600/A1200)</li>
<li>Added support for PCMCIA-slots (A600/A1200)</li>
<li>Units are write-protectable.</li>
</ul>
</li>
<li>Playfield
<ul>
<li>Added AGA-support.</li>
<li>Added support for 16 bits-per-pixel (R5G6B5) rendering.</li>
<li>Got rid of an internal temp-buffer. So in WebGL-mode, we render to the texture directly now.</li>
<li>Added options for video-centering.</li>
</ul>
</li>
<li>Video
<ul>
<li>The output-driver is now selectable.</li>
<li>Added support and options for brightness, contrast and gamma.</li>
<li>Added alpha-channel support.</li>
<li>Added line-change indicator. (debug)</li>
</ul>
</li>
<li>Audio
<ul>
<li>Added &quot;Anti&quot;-samplehandler.</li>
<li>Added A1200 lowpass-filter.</li>
<li>Added support for stereo-channel separation.</li>
<li>Rewrote handling of WebAudio-stuff.</li>
</ul>
</li>
<li>Events
<ul>
<li>If supported by the browser, timing-functions does use performance.now() instead of Date.now(),<br />
which increases the precision by the factor of 1000.</li>
<li>Optimized switching between pause/run. Thanks 'majcherek2048'.</li>
</ul>
</li>
<li>Input
<ul>
<li>Added distinction between left/right shift/alt keys. The config-entry &quot;Map L/R-Shift to L/R-Arrows&quot; is gone.</li>
</ul>
</li>
<li>Config
<ul>
<li>Completely reworked the advanced config page.</li>
<li>Changed all SAEV_Config_* to SAEC_Config_* to match the new namespace. Sorry for that :/</li>
<li>Many new options. Not listed here, see sae/config.js for details.</li>
</ul>
</li>
<li>API
<ul>
<li>Deprecated and removed the old API function &quot;SAE()&quot;. We're on javascript, so let's use: (new API)<br />
&quot;var sae = new ScriptedAmigaEmulator(); [...] var error = sae.start(); [...]&quot; See index.js for details.</li>
<li>Reworked error-handling for API-calls. Now an error-code (SAEE_*) is returned on any API-call.</li>
</ul>
</li>
<li>Common
<ul>
<li>Introduced global functions, references, variables and constants for more speed. See sae/amiga.js for details.</li>
<li>Moved all entries from constants.js to their specific place and renamed them to match the new global name-space.</li>
<li>Updated asynchronous file-transfers to latest standards.</li>
<li>Added proper GPL-header to the source-files.</li>
<li>Moved the &quot;Your game and demo...&quot;-section from the main-site to the readme.</li>
<li>Fixed linkage to contributors websites.</li>
<li>Added SAE-specific-links to the info-box in the main-page.</li>
<li>Added an disassembler tool.<br />
&quot;var sda = new ScriptedDisAssembler(); [...] var result = sda.disassemble();&quot; See disass.js for details.</li>
</ul>
</li>
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="label">0.8.3 (22.03.2015)</span>
<ul>
<li>Audio
<ul>
@ -142,7 +574,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.8.2 (10.01.2015)</span>
<li><span class="label">0.8.2 (10.01.2015)</span>
<ul>
<li>Audio
<ul>
@ -163,7 +595,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.8.1 (19.01.2013):</span>
<li><span class="label">0.8.1 (19.01.2013):</span>
<ul>
<li>Common
<ul>
@ -175,7 +607,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.8.0 (16.01.2013):</span>
<li><span class="label">0.8.0 (16.01.2013):</span>
<ul>
<li>Display
<ul>
@ -223,7 +655,7 @@
<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 />
one may send the link &quot;http://scriptedamigaemulator.net/#Multica&quot;<br />
and the demo will start immediately. (thanks mrdoob)</li>
<li>Many small optimizations.</li>
</ul>
@ -231,7 +663,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.7.0 (24.12.2012):</span>
<li><span class="label">0.7.0 (24.12.2012):</span>
<ul>
<li>Common
<ul>
@ -242,22 +674,22 @@
<li>Separated the GUI form the core and rewrote most of it.</li>
<li>Simplified the whole code. This means, that functions are called faster.</li>
<li>Ported new Copper-, Blitter-, Audio-, Disk- and event-handling code from WinUAE 2.5.0</li>
<li>Moved all "beam-functions" to events.js, for faster access.</li>
<li>Added "CPU-usage" to the GUI.</li>
<li>Added "Hall of Fame".</li>
<li>Moved all &quot;beam-functions&quot; to events.js, for faster access.</li>
<li>Added &quot;CPU-usage&quot; to the GUI.</li>
<li>Added &quot;Hall of Fame&quot;.</li>
</ul>
</li>
<li>CPU
<ul>
<li>Added support for exact cycling. The CPU have now 7.09 MHz on PAL and 7.16 MHz on NTSC resp.</li>
<li>Added option for "Original"- and "Maximum"-speed.</li>
<li>Added option for &quot;Original&quot;- and &quot;Maximum&quot;-speed.</li>
</ul>
</li>
<li>Audio
<ul>
<li>Added a ring-buffer before output. No more "bagpipe"-like audio.</li>
<li>Added a ring-buffer before output. No more &quot;bagpipe&quot;-like audio.</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>
e.g. &quot;Agony&quot; was not starting, if audio was disabled.</li>
</ul>
</li>
<li>Display
@ -284,7 +716,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.6.1 (05.11.2012):</span>
<li><span class="label">0.6.1 (05.11.2012):</span>
<ul>
<li>CPU
<ul>
@ -314,7 +746,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.6 (25.10.2012):</span>
<li><span class="label">0.6 (25.10.2012):</span>
<ul>
<li>ROM
<ul>
@ -354,13 +786,13 @@
<ul>
<li>Added missing support for HAM6.</li>
<li>Fixed horizontal and vertical screen-centering.</li>
<li>Fixed screen-draging, almost, read the "Known bugs" section.</li>
<li>Fixed screen-draging, almost, read the &quot;Known bugs&quot; section.</li>
<li>Added better screen-scrolling.</li>
</ul>
</li>
<li>Input
<ul>
<li>Fixed key-mapping to the amiga key-layout, at least in Chrome. Firefox does not like "öäü", it seems.</li>
<li>Fixed key-mapping to the amiga key-layout, at least in Chrome. Firefox does not like &quot;öäü&quot;, it seems.</li>
<li>Added support for individual configurations of joystick-movement and fire-buttons.</li>
<li>Fixed bug, that made the fire 1 button on joystick 0 not working.</li>
<li>Fixed bug in the mouse-movement function, that calculates the wrong coordinates in some cases.</li>
@ -370,7 +802,7 @@
<ul>
<li>Added eject-button in the disk-change requester.</li>
<li>Removed the CPU and OCS/ECS options. They are useless so far.</li>
<li>The "Pause" and "Resume" buttons are once now.</li>
<li>The &quot;Pause&quot; and &quot;Resume&quot; buttons are once now.</li>
<li>Made some options to only apear when selected.</li>
<li>Did some cosmetics.</li>
</ul>
@ -380,7 +812,7 @@
<li>Added support for Zorro2-expansion cards.</li>
<li>Added a more precise event-handling. This makes the audio-output a little smoother.</li>
<li>Changed the ratio of CPU-/Chipset-time from 1:8 to 1:4</li>
<li>Fixed a bug in the RTC. "Year" is now calculated correctly.</li>
<li>Fixed a bug in the RTC. &quot;Year&quot; is now calculated correctly.</li>
<li>Fixed incorrect response of serial.device. Now crashed programms does reset (and show the guru), instead of idle.</li>
<li>Any output on the serial.device is now redirected to the debug-log. (dev only)</li>
<li>Kickstart/Workbench 2.04 and AROS does now work.</li>
@ -390,7 +822,7 @@
</ul>
</li>
<li style="list-style-type:none"><br/></li>
<li><span class="fwb">0.5 (01.09.2012):</span>
<li><span class="label">0.5 (01.09.2012):</span>
<ul>
<li>Initial.</li>
</ul>
@ -399,6 +831,13 @@
</li>
</ul>
</div>
<div style="height:5px"></div>
<div id="foot" class="foot" style="line-height:14px">
<span class="gray">2012-2016 Rupert Hausberger</span> |
<span class="gray">Description</span> |
<a target="_blank" href="disass.htm">Disassembler</a> |
<a target="_blank" href="https://github.com/naTmeg/ScriptedAmigaEmulator">Source-code</a>
</div>
<div style="height:20px"></div>
</body>
</html>

View file

@ -1,426 +1,582 @@
/**************************************************************************
* SAE - Scripted Amiga Emulator
*
* 2012-2015 Rupert Hausberger
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
**************************************************************************/
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Notes on the global-namespace
| -----------------------------
| Global object:
| function SAEO_<name>() {}
|
| Global error constant:
| const SAEE_<object_name>_<name>;
|
| Global constant:
| const SAEC_<object_name>_<name>;
|
| Global variable:
| var SAEV_<object_name>_<name>;
|
| Global function:
| function SAEF_<object_name>_<name>() {}
|
| Global reference (pointer) to another object:
| var SAER_<object_name>_<name>;
|
|
| Tags that may appear in comments (use full-word, case-sensitive text-search)
| --------------------------------
| OWN Own code added.
| ATT Attention, possible source of error or problem.
| FIX Need to be fixed or implemented.
| OPT Need or can be optimized.
| ORG Original code, e.g. something required to be disabled.
| SECT Code section.
-------------------------------------------------------------------------*/
function set_special(x) { AMIGA.spcflags |= x; }
function clr_special(x) { AMIGA.spcflags &= ~x; }
const SAEC_Version = 0;
const SAEC_Revision = 9;
const SAEC_Patch = 0;
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.mem = new Memory();
this.expansion = new Expansion();
this.input = new Input();
this.serial = new Serial();
this.events = new Events();
this.disk = new Disk();
this.cia = new CIA();
this.rtc = new RTC();
this.custom = new Custom();
this.blitter = new Blitter();
this.copper = new Copper();
this.playfield = new Playfield();
this.video = new Vide0();
this.audio = new Audi0();
this.cpu = new CPU();
/*---------------------------------*/
/* errors */
this.state = ST_STOP;
this.delay = 0;
this.spcflags = 0;
//this.loading = 0;
this.intena = 0;
this.intreq = 0;
this.dmacon = 0;
this.adkcon = 0;
this.info.video = this.video.available;
this.info.audio = this.audio.available;
/*---------------------------------*/
this.setup = function () {
this.mem.setup();
this.expansion.setup();
this.events.setup();
this.playfield.setup();
this.video.setup();
this.cia.setup();
this.rtc.setup();
this.input.setup();
this.disk.setup();
this.audio.setup();
this.custom.setup();
this.cpu.setup();
};
this.cleanup = function () {
this.audio.cleanup();
this.video.cleanup();
this.playfield.cleanup();
this.input.cleanup();
};
this.reset = function () {
BUG.info('Amiga.reset()');
this.delay = 0;
this.spcflags = 0;
//this.loading = 0;
this.intena = 0;
this.intreq = 0;
this.dmacon = 0;
this.adkcon = 0;
this.expansion.reset();
this.events.reset();
this.playfield.reset();
this.cia.reset();
this.disk.reset();
this.input.reset();
this.serial.reset();
this.blitter.reset();
this.copper.reset();
this.audio.reset();
this.custom.reset();
this.cpu.reset(this.mem.rom.lower);
};
this.dump = function () {
this.cpu.dump();
//this.cia.dump();
};
/*---------------------------------*/
/*this.waitForStart = function() {
if (this.loading)
setTimeout('AMIGA.waitForStart()', 10);
else {
this.reset();
this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0);
}
}
this.start = function() {
this.setup();
this.waitForStart();
}*/
this.start = function () {
if (this.state == ST_STOP) {
this.setup();
this.reset();
this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', 0);
}
};
this.stop = function () {
if (this.state != ST_STOP) {
this.state = ST_STOP;
this.cleanup();
}
};
this.pause = function (state) {
if (this.state != ST_STOP) {
this.state = state ? ST_PAUSE : ST_CYCLE;
this.audio.pauseResume(state);
}
};
/*this.insert = function(unit, name, data) {
//this.disk.insert_data(unit, data);
this.disk.insert(unit, name, data);
this.config.floppy.drive[unit].name = name;
}
this.eject = function(unit) {
if (this.config.floppy.drive[unit].name) {
this.disk.eject(unit);
//this.disk.eject_data(unit);
this.config.floppy.drive[unit].name = null;
BUG.info('amiga.eject() DF%d ejected', unit);
} else
BUG.info('amiga.eject() DF%d in empty', unit);
}
*/
this.insert = function (unit) {
if (this.state != ST_STOP)
this.disk.insert(unit);
};
this.eject = function (unit) {
if (this.state != ST_STOP)
this.disk.eject(unit);
};
/*---------------------------------*/
/* mainloop */
this.cycle = function () {
try {
this.cpu.cycle();
} catch (e) {
if (e instanceof VSync) {
//console.log(e.error, e.message);
this.state = ST_IDLE;
} else if (e instanceof FatalError) {
this.state = ST_STOP;
this.stop();
this.config.hooks.error(e.error, e.message);
} else /* normal exception */ {
this.state = ST_STOP;
this.stop();
console.log(e);
}
}
if (this.state == ST_IDLE) {
this.state = ST_CYCLE;
setTimeout('AMIGA.cycle()', this.delay);
}
else if (this.state == ST_PAUSE)
AMIGA.cyclePause();
else
AMIGA.cycleExit();
};
this.cyclePause = function () {
if (this.state == ST_CYCLE)
setTimeout('AMIGA.cycle()', 0);
else if (this.state == ST_PAUSE)
setTimeout('AMIGA.cyclePause()', 500);
else
AMIGA.cycleExit();
};
this.cycleExit = function () {
this.dump();
//this.cia.dump();
};
/*---------------------------------*/
this.dmaen = function (dmamask) {
return ((this.dmacon & DMAF_DMAEN) != 0 && (this.dmacon & dmamask) != 0);
};
this.DMACONR = function (hpos) {
this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos);
this.dmacon &= ~(0x4000 | 0x2000);
var iz = this.blitter.getIntZero();
this.dmacon |= ((iz[0] ? 0 : 0x4000) | (iz[1] ? 0x2000 : 0));
return this.dmacon;
};
this.DMACON = function (v, hpos) {
var oldcon = this.dmacon;
this.playfield.decide_line(hpos);
this.playfield.decide_fetch(hpos);
if (v & INTF_SETCLR)
this.dmacon |= v & ~INTF_SETCLR;
else
this.dmacon &= ~v;
this.dmacon &= 0x1fff;
var changed = this.dmacon ^ oldcon;
var oldcop = (oldcon & DMAF_COPEN) != 0 && (oldcon & DMAF_DMAEN) != 0;
var newcop = (this.dmacon & DMAF_COPEN) != 0 && (this.dmacon & DMAF_DMAEN) != 0;
if (oldcop != newcop) {
if (newcop && !oldcop) {
this.copper.compute_spcflag_copper(this.events.hpos());
} else if (!newcop) {
this.copper.enabled_thisline = false;
clr_special(SPCFLAG_COPPER);
}
}
if ((this.dmacon & DMAF_BLTPRI) > (oldcon & DMAF_BLTPRI) && this.blitter.getState() != BLT_done)
set_special(SPCFLAG_BLTNASTY);
if (this.dmaen(DMAF_BLTEN) && this.blitter.getState() == BLT_init)
this.blitter.setState(BLT_work);
if ((this.dmacon & (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN)) != (DMAF_BLTPRI | DMAF_BLTEN | DMAF_DMAEN))
clr_special(SPCFLAG_BLTNASTY);
if (changed & (DMAF_DMAEN | 0x0f))
this.audio.state_machine();
if (changed & (DMAF_DMAEN | DMAF_BPLEN)) {
this.playfield.update_ddf_change();
if (this.dmaen(DMAF_BPLEN))
this.playfield.maybe_start_bpl_dma(hpos);
}
this.events.schedule();
};
/*---------------------------------*/
this.ADKCONR = function () {
return this.adkcon;
};
this.ADKCON = function (v, hpos) {
if (this.config.audio.enabled)
this.audio.update();
this.disk.update(hpos);
this.disk.update_adkcon(v);
if (v & INTF_SETCLR)
this.adkcon |= v & ~INTF_SETCLR;
else
this.adkcon &= ~v;
this.audio.update_adkmasks();
};
/*---------------------------------*/
this.INTENAR = function () {
return this.intena;
};
this.INTENA = function (v) {
if (v & INTF_SETCLR)
this.intena |= v & ~INTF_SETCLR;
else
this.intena &= ~v;
if (v & INTF_SETCLR)
this.doint();
};
/*---------------------------------*/
this.INTREQR = function () {
return this.intreq;
};
this.INTREQ_0 = function (v) {
var old = this.intreq;
if (v & INTF_SETCLR)
this.intreq |= v & ~INTF_SETCLR;
else
this.intreq &= ~v;
if ((v & INTF_SETCLR) && this.intreq != old)
this.doint();
};
this.INTREQ = function (v) {
this.INTREQ_0(v);
this.cia.rethink();
};
/*---------------------------------*/
this.intlev = function () {
var imask = this.intreq & this.intena;
if (imask && (this.intena & INTF_INTEN)) {
if (imask & 0x2000) return 6;
if (imask & 0x1800) return 5;
if (imask & 0x0780) return 4;
if (imask & 0x0070) return 3;
if (imask & 0x0008) return 2;
if (imask & 0x0007) return 1;
}
return -1;
};
this.doint = function() {
if (AMIGA.config.cpu.compatible)
set_special(SPCFLAG_INT);
else
set_special(SPCFLAG_DOINT);
}
function SAEO_Error(err, msg) {
this.err = err;
this.msg = msg;
}
SAEO_Error.prototype = new Error;
const SAEE_None = 0;
const SAEE_AlreadyRunning = 1;
const SAEE_NotRunning = 2;
const SAEE_NoTimer = 3;
const SAEE_NoMemory = 4;
const SAEE_Assert = 5;
const SAEE_Internal = 6;
const SAEE_Config_Invalid = 10;
const SAEE_CPU_Internal = 20;
const SAEE_CPU_Requires68020 = 21;
const SAEE_CPU_Requires680EC20 = 22;
const SAEE_CPU_Requires68030 = 23;
const SAEE_CPU_Requires68040 = 24;
const SAEE_Memory_NoKickstartRom = 30;
const SAEE_Memory_NoExtendedRom = 31;
const SAEE_Memory_RomSize = 32;
const SAEE_Memory_RomKey = 33;
const SAEE_Memory_RomDecode = 34;
const SAEE_Memory_RomChecksum = 35;
const SAEE_Memory_RomUnknown = 36;
const SAEE_Video_ElementNotFound = 40;
const SAEE_Video_RequiresCanvas = 41;
const SAEE_Video_RequiresWegGl = 42;
const SAEE_Video_ComphileShader = 43;
const SAEE_Video_LinkShader = 44;
const SAEE_Audio_RequiresWebAudio = 50;
/*-----------------------------------------------------------------------*/
/* This API will change in the future. */
/* global references */
var BUG = null;
var AMIGA = null;
var SAER = null;
function SAE(x) {
try {
switch (x.cmd) {
case 'init':
BUG = new Debug();
BUG.info('API.init() SEA %d.%d.%d', SAEV_Version, SAEV_Revision, SAEV_Revision_Sub);
/*---------------------------------*/
/* global constants */
AMIGA = new Amiga();
//return AMIGA.config;
break;
case 'reset':
BUG.info('API.reset()');
AMIGA.reset();
break;
case 'start':
BUG.info('API.start()');
AMIGA.start();
break;
case 'stop':
BUG.info('API.stop()');
AMIGA.stop();
break;
case 'pause':
BUG.info('API.pause() %d', x.state);
AMIGA.pause(x.state);
break;
/*case 'insert':
BUG.info('API.insert() DF%d, name "%s", length %d', x.unit, x.name, x.data.length);
AMIGA.insert(x.unit, x.name, x.data);
break;*/
case 'insert':
BUG.info('API.insert() DF%d', x.unit);
AMIGA.insert(x.unit);
break;
case 'eject':
BUG.info('API.eject() DF%d', x.unit);
AMIGA.eject(x.unit);
break;
case 'getInfo':
BUG.info('API.getInfo()');
return AMIGA.info;
case 'getConfig':
BUG.info('API.getConfig()');
return AMIGA.config;
/*case 'setConfig':
BUG.info('API.setConfig() size '+x.data.ext.size);
AMIGA.config = x.data;
break;*/
const SAEC_spcflag_STOP = 2;
const SAEC_spcflag_COPPER = 4;
const SAEC_spcflag_INT = 8;
const SAEC_spcflag_BRK = 16;
//const SAEC_spcflag_UAEINT = 32;
const SAEC_spcflag_TRACE = 64;
const SAEC_spcflag_DOTRACE = 128;
const SAEC_spcflag_DOINT = 256;
const SAEC_spcflag_BLTNASTY = 512;
//const SAEC_spcflag_EXEC = 1024;
//const SAEC_spcflag_ACTION_REPLAY = 2048;
//const SAEC_spcflag_TRAP = 4096; /* enforcer-hack */
const SAEC_spcflag_MODE_CHANGE = 8192;
const SAEC_spcflag_CHECK = 32768;
const SAEC_command_Quit = 1;
const SAEC_command_Reset = 2;
const SAEC_command_KeyboardReset = 3;
const SAEC_command_HardReset = 4;
const SAEC_command_Pause = 5;
const SAEC_command_Resume = 6;
/*---------------------------------*/
const SAEC_Info_Brower_ID_Unknown = 0;
const SAEC_Info_Brower_ID_Chrome = 1;
const SAEC_Info_Brower_ID_Safari = 2;
const SAEC_Info_Brower_ID_Opera = 3;
const SAEC_Info_Brower_ID_Firefox = 4;
const SAEC_Info_Brower_ID_InternetExplorer = 5;
const SAEC_info = (function() {
var info = {
browser: {
id: SAEC_Info_Brower_ID_Unknown,
name: "Unknown",
plat: "Unknown",
lang: "en"
},
memory: {
maxSize: 0
},
audio: {
webAudio: false
},
video: {
canvas: false,
webGL: false
}
} catch (e) {
if (e instanceof FatalError) {
AMIGA.stop();
//return { error:e.error, message:e.message };
AMIGA.config.hooks.error(e.error, e.message);
} else
console.log(e);
};
/* browser */
if (navigator.userAgent.indexOf("Chrome") > -1) {
info.browser.id = SAEC_Info_Brower_ID_Chrome;
info.browser.name = "Google Chrome";
}
//return SAEE_None;
//return { error:SAEE_None, message:'' };
return 0;
else if (navigator.userAgent.indexOf("Safari") > -1) {
info.browser.id = SAEC_Info_Brower_ID_Safari;
info.browser.name = "Apple Safari";
}
else if (navigator.userAgent.indexOf("Opera") > -1) {
info.browser.id = SAEC_Info_Brower_ID_Opera;
info.browser.name = "Opera";
}
else if (navigator.userAgent.indexOf("Firefox") > -1) {
info.browser.id = SAEC_Info_Brower_ID_Firefox;
info.browser.name = "Mozilla Firefox";
}
else if (navigator.userAgent.indexOf("MSIE") > -1) {
info.browser.id = SAEC_Info_Brower_ID_InternetExplorer;
info.browser.name = "Microsoft Internet Explorer";
}
info.browser.plat = navigator.platform;
info.browser.lang = navigator.language;
/* max memory */
if (0) {
var size = 1048576;
while (true) {
try {
var data = new Uint8Array(size);
delete data;
info.memory.maxSize = size;
} catch (e) {
break;
}
size *= 2;
}
} else
info.memory.maxSize = 1073741824; //1G
/* audio */
var audioContext = null;
try {
var audioContextDriver = window.AudioContext || window.webkitAudioContext;
audioContext = new audioContextDriver();
var audioProcessor = audioContext.createScriptProcessor(1024, 2, 2);
info.audio.webAudio = true;
if (audioContext.close) audioContext.close().then(function() {});
audioContext = null;
} catch (e) {
if (audioContext) {
if (audioContext.close) audioContext.close().then(function() {});
audioContext = null;
}
}
/* video */
var canvas = document.createElement("canvas");
if (canvas && canvas.getContext) {
try {
var ctx = canvas.getContext("2d");
var imageData = ctx.createImageData(16, 16);
info.video.canvas = true;
try {
const glParams = {
alpha: false,
depth: true,
stencil: false,
antialias: false,
premultipliedAlpha: false,
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: false
};
ctx = canvas.getContext("webgl", glParams) || canvas.getContext("experimental-webgl", glParams);
info.video.webGL = true;
} catch(e) {}
} catch(e) {}
}
return info;
})();
/*---------------------------------*/
/* global variables */
var SAEV_spcflags = 0;
var SAEV_command = 0;
/*---------------------------------*/
/* global functions */
function SAEF_setSpcFlags(x) { SAEV_spcflags |= x; };
function SAEF_clrSpcFlags(x) { SAEV_spcflags &= ~x; };
/*---------------------------------*/
function SAEF_now() {
return Math.floor(performance.now() * 1000); /* micro-seconds since page-load */
}
function SAEF_sleep(ms) {
var start = performance.now();
while ((performance.now() - start) < ms) {} /* pretty nasty */
}
/*---------------------------------*/
/* debug */
function SAEF_log() {
if (SAEV_config.debug.level >= SAEC_Config_Debug_Level_Log && arguments.length) {
var str = sprintf.apply(this, arguments);
if (console.log) console.log(str);
}
}
function SAEF_info() {
if (SAEV_config.debug.level >= SAEC_Config_Debug_Level_Info && arguments.length) {
var str = sprintf.apply(this, arguments);
if (console.info) console.info(str);
}
}
function SAEF_warn() {
if (SAEV_config.debug.level >= SAEC_Config_Debug_Level_Warn && arguments.length) {
var str = sprintf.apply(this, arguments);
if (console.warn) console.warn(str);
}
}
function SAEF_error() {
if (SAEV_config.debug.level >= SAEC_Config_Debug_Level_Error && arguments.length) {
var str = sprintf.apply(this, arguments);
if (console.error) console.error(str);
}
}
function SAEF_fatal() {
var argumentsArray = Array.prototype.slice.call(arguments);
var err = argumentsArray[0];
var str = sprintf.apply(this, argumentsArray.slice(1));
if (console.error) console.error(str);
throw new SAEO_Error(err, str);
}
function SAEF_assert(cond) {
if (!cond) {
var err = SAEE_Assert;
var str = "Assertion failed. This is a bug in SAE.";
if (console.error) console.error(str);
throw new SAEO_Error(err, str);
}
}
/*---------------------------------*/
function ScriptedAmigaEmulator() {
SAER = this;
this.autoconf = new SAEO_AutoConf();
this.audio = new SAEO_Audio();
this.blitter = new SAEO_Blitter();
this.cia = new SAEO_CIA();
this.config = new SAEO_Configuration();
this.copper = new SAEO_Copper();
this.cpu = new SAEO_CPU();
this.custom = new SAEO_Custom();
this.devices = new SAEO_Devices();
this.disk = new SAEO_Disk();
this.events = new SAEO_Events();
this.expansion = new SAEO_Expansion();
this.filesys = new SAEO_Filesys();
this.gayle = new SAEO_Gayle();
this.gui = new SAEO_GUI();
this.hardfile = new SAEO_Hardfile();
this.ide = new SAEO_IDE();
this.input = new SAEO_Input();
this.m68k = new SAEO_M68K();
this.memory = new SAEO_Memory();
this.playfield = new SAEO_Playfield();
this.roms = new SAEO_Roms();
this.rtc = new SAEO_RTC();
this.serial = new SAEO_Serial();
this.video = new SAEO_Video();
/*---------------------------------*/
this.running = false;
this.paused = false;
/*-----------------------------------------------------------------------*/
this.dump = function () {
this.m68k.dump();
//this.memory.dump();
//this.cia.dump();
};
/*-----------------------------------------------------------------------*/
this.do_start_program = function() {
if (SAEV_command >= 0)
SAEV_command = SAEC_command_Reset;
this.m68k.m68k_go(true);
}
this.do_leave_program = function() {
//sampler_free();
this.video.cleanup();
this.input.cleanup();
this.disk.cleanup();
this.audio.cleanup();
//dump_counts();
this.serial.cleanup();
/*#ifdef CDTV
cdtv_free();
cdtvcr_free();
#endif
#ifdef CD32
akiko_free();
cd32_fmv_free();
#endif*/
//this.gui.cleanup(); //empty
//#ifdef AUTOCONFIG
this.expansion.cleanup();
//#endif
//#ifdef FILESYS
this.filesys.cleanup();
//#endif
this.gayle.cleanup();
/*idecontroller_free();
device_func_reset();
#ifdef WITH_TOCCATA
sndboard_free();
#endif*/
this.memory.cleanup();
//free_shm();
this.autoconf.cleanup();
}
this.start_program = function() {
this.do_start_program();
}
this.leave_program = function() {
this.dump();
this.do_leave_program();
}
this.pause_program = function(p) {
this.audio.pauseResume(p);
this.events.pauseResume(p);
}
/*---------------------------------*/
/* API */
this.getVersion = function(str) {
if (str)
return sprintf("%d.%d.%d", SAEC_Version, SAEC_Revision, SAEC_Patch);
else
return [SAEC_Version, SAEC_Revision, SAEC_Patch];
}
this.getInfo = function() {
return SAEC_info;
}
this.getConfig = function() {
return SAEV_config;
}
this.setDefaults = function() {
return this.config.setDefaults();
}
this.setModel = function(model, config) {
return this.config.setModel(model, config);
}
this.setMountInfoDefaults = function(num) {
var ci = SAEV_config.mount.config[num].ci;
this.filesys.uci_set_defaults(ci, false);
}
this.start = function() {
if (SAER.running) {
SAEF_warn("sae.start() emulation already running");
return SAEE_AlreadyRunning;
}
SAEF_info("sae.start() starting...");
var err;
if ((err = this.config.setup()) != SAEE_None)
return err;
if ((err = this.video.obtain()) != SAEE_None)
return err;
if ((err = this.audio.obtain()) != SAEE_None)
return err;
this.input.setup(); //inputdevice_init();
if ((err = this.gui.setup()) != SAEE_None)
return err;
/*#ifdef PICASSO96
picasso_reset();
#endif*/
//this.config.fixup_prefs(currprefs, true);
//SAEV_config.audio.mode = 0; /* force sound settings change */
this.memory.hardreset(2);
if ((err = this.memory.reset(true)) == SAEE_None)
{
/*#ifdef AUTOCONFIG
native2amiga_install();
#endif*/
this.custom.setup(); //OWN
this.blitter.setup(); //OWN
this.playfield.setup(); //custom_init();
this.serial.setup();
this.disk.setup();
this.events.reset_frame_rate_hack();
if ((err = this.m68k.setup()) == SAEE_None) /* m68k_init() must come after reset_frame_rate_hack() */
{
//this.gui.update(); //empty
if ((err = this.video.setup(true)) == SAEE_None)
{
if ((err = this.audio.setup()) == SAEE_None)
{
this.start_program();
SAEF_info("sae.start() ...done");
return SAEE_None;
}
this.video.cleanup();
}
}
}
this.input.cleanup();
SAEF_error("sae.start() ...error %d", err);
return err;
}
this.stop = function() { //uae_quit()
if (this.running) {
SAEF_info("sae.stop()");
if (SAEV_command != -SAEC_command_Quit)
SAEV_command = -SAEC_command_Quit;
return SAEE_None;
} else {
SAEF_warn("sae.stop() emulation not running");
return SAEE_NotRunning;
}
};
this.reset = function(hardreset, keyboardreset) { //uae_reset(hardreset, keyboardreset)
if (typeof hardreset == "undefined") var hardreset = 1;
if (typeof keyboardreset == "undefined") var keyboardreset = 0;
if (this.running) {
SAEF_info("sae.reset() hard %d, keyboard %d", hardreset, keyboardreset);
if (SAEV_command == 0) {
SAEV_command = -SAEC_command_Reset;
if (keyboardreset)
SAEV_command = -SAEC_command_KeyboardReset;
if (hardreset)
SAEV_command = -SAEC_command_HardReset;
}
return SAEE_None;
} else {
SAEF_warn("sae.reset() emulation not running");
return SAEE_NotRunning;
}
};
this.pause = function(pause) {
if (this.running) {
if (!this.paused && pause) {
SAEF_info("sae.pause() pausing emulation");
SAEV_command = SAEC_command_Pause;
}
else if (this.paused && !pause) {
SAEF_info("sae.pause() resuming emulation");
SAEV_command = SAEC_command_Resume;
}
return SAEE_None;
} else {
SAEF_warn("sae.pause() emulation not running");
return SAEE_NotRunning;
}
};
this.insert = function(unit) {
if (this.running) {
var file = SAEV_config.floppy.drive[unit].file;
this.disk.insert(unit, file);
SAEF_info("sae.insert() unit %d inserted, name '%s', size %d, protected %d", unit, file.name, file.size, file.prot?1:0);
return SAEE_None;
} else {
SAEF_warn("sae.insert() emulation not running");
return SAEE_NotRunning;
}
};
this.eject = function(unit) {
if (this.running) {
this.disk.eject(unit);
SAEF_info("sae.eject() unit %d ejected", unit);
return SAEE_None;
} else {
SAEF_warn("sae.eject() emulation not running");
return SAEE_NotRunning;
}
};
this.getRomInfo = function(ri, file) {
return this.roms.examine(ri, file);
};
this.getDiskInfo = function(di, unit) {
return this.disk.examine(di, unit);
};
this.createDisk = function(unit, name, mode, type, label, ffs, bootable) {
if (!this.disk.create(unit, name, mode, type, label, ffs, bootable))
return SAEE_NoMemory;
return SAEE_None;
};
/*---------------------------------*/
SAEF_info("SAE %d.%d.%d", SAEC_Version, SAEC_Revision, SAEC_Patch);
}

File diff suppressed because it is too large Load diff

727
sae/autoconf.js Normal file
View file

@ -0,0 +1,727 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: ported from WinUAE 3.2.x
-------------------------------------------------------------------------*/
/* global references */
var SAER_AutoConf_bank = null;
/*---------------------------------*/
/* global constants */
const SAEC_AutoConf_RTS = 0x4e75;
//const SAEC_AutoConf_RTE = 0x4e73;
/*---------------------------------*/
/* global variables */
var SAEV_AutoConf_base = 0xf00000; //RTAREA_DEFAULT;
var SAEV_AutoConf_boot_rom_type = 0;
var SAEV_AutoConf_boot_rom_size = 0;
/*---------------------------------*/
function SAEO_AutoConf() {
const RTAREA_DEFAULT = 0xf00000;
const RTAREA_BACKUP = 0xef0000;
const RTAREA_BACKUP_2 = 0xdb0000;
const RTAREA_SIZE = 0x10000;
const RTAREA_TRAPS = 0x3000;
const RTAREA_RTG = 0x3800;
const RTAREA_TRAMPOLINE = 0x3b00;
const RTAREA_DATAREGION = 0xF000;
const RTAREA_FSBOARD = 0xFFEC;
const RTAREA_HEARTBEAT = 0xFFF0;
const RTAREA_TRAPTASK = 0xFFF4;
const RTAREA_EXTERTASK = 0xFFF8;
const RTAREA_INTREQ = 0xFFFC;
const RTAREA_TRAP_DATA = 0x4000;
const RTAREA_TRAP_DATA_SIZE = 0x8000;
const RTAREA_TRAP_DATA_SLOT_SIZE = 0x2000; // 8192
const RTAREA_TRAP_DATA_SECOND = 80;
const RTAREA_TRAP_DATA_TASKWAIT = (RTAREA_TRAP_DATA_SECOND - 4);
const RTAREA_TRAP_DATA_EXTRA = 144;
const RTAREA_TRAP_DATA_EXTRA_SIZE = (RTAREA_TRAP_DATA_SLOT_SIZE - RTAREA_TRAP_DATA_EXTRA);
const RTAREA_TRAP_SEND_DATA = 0xc0000;
const RTAREA_TRAP_SEND_DATA_SIZE = 0x2000;
const RTAREA_TRAP_STATUS = 0xF000;
const RTAREA_TRAP_STATUS_SIZE = 8;
const RTAREA_TRAP_STATUS_SECOND = 4;
const RTAREA_TRAP_SEND_STATUS = 0xF100;
const RTAREA_SYSBASE = 0x3FFC;
const RTAREA_TRAP_DATA_NUM = (RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE);
/* Commonly used autoconfig strings */
//var EXPANSION_explibname = 0, EXPANSION_doslibname = 0, EXPANSION_uaeversion = 0;
//var EXPANSION_uaedevname, EXPANSION_explibbase = 0;
//var EXPANSION_bootcode = 0, EXPANSION_nullfunc = 0;
/* ROM tag area memory access */
//var rtarea_base = RTAREA_DEFAULT; --> SAEV_AutoConf_base
var hardware_trap_event = new Array(RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE); //HANDLE
var rt_trampoline_ptr = 0, trap_entry = 0;
//var hwtrap_waiting = 0; //extern volatile uae_atomic, in traps
var filesystem_state = 0; //extern int
//var uae_boot_rom_type = 0; -> SAEV_AutoConf_boot_rom_type
//var uae_boot_rom_size = 0; -> SAEV_AutoConf_boot_rom_size
var uae_int_requested = 0; //volatile uae_atomic
/*-----------------------------------------------------------------------*/
function check_boot_rom(p) {
var b = RTAREA_DEFAULT;
/*if (currprefs.uaeboard > 1) {
p.type = 2;
return 0x00eb0000; // fixme!
}
p.type = 0;
if (currprefs.boot_rom == 1)
return 0;*/
p.type = 1;
/*if (currprefs.cs_cdtvcd || currprefs.cs_cdtvscsi || currprefs.uae_hide > 1)
b = RTAREA_BACKUP;*/
if (SAEV_config.chipset.mbdmac == 1)// || currprefs.cpuboard_type)
b = RTAREA_BACKUP;
// CSPPC enables MMU at boot and remaps 0xea0000->0xeffff.
/*if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC))
b = RTAREA_BACKUP_2;*/
var ab = SAER_Memory_getBank(RTAREA_DEFAULT);
if (ab !== null) {
if (SAER_Memory_check(RTAREA_DEFAULT, 65536))
b = RTAREA_BACKUP;
}
/*if (nr_directory_units(NULL))
return b;
if (nr_directory_units(&currprefs))
return b;
if (currprefs.socket_emu)
return b;
if (currprefs.uaeserial)
return b;
if (currprefs.scsi == 1) //uaescsi.device
return b;
if (currprefs.sana2)
return b;
if (currprefs.input_tablet > 0)
return b;
if (currprefs.rtgmem_size && currprefs.rtgmem_type < GFXBOARD_HARDWARE)
return b;
if (currprefs.win32_automount_removable)
return b;*/
if (SAEV_config.memory.chipSize > 2 * 1024 * 1024)
return b;
/*if (currprefs.z3chipmem_size)
return b;
if (currprefs.boot_rom >= 3)
return b;
if (currprefs.boot_rom == 2 && b == 0xf00000) {
p.type = -1;
return b;
}*/
p.type = 0;
return 0;
}
this.need_uae_boot_rom = function() {
var p = { type:0 };
var v = check_boot_rom(p);
SAEV_AutoConf_boot_rom_type = p.type;
SAEF_log("autoconf.need_uae_boot_rom() type %d", SAEV_AutoConf_boot_rom_type);
if (!SAEV_AutoConf_base) {
v = 0;
SAEV_AutoConf_boot_rom_type = 0;
}
return v;
}
/*-----------------------------------------------------------------------*/
/*static bool istrapwait(void) {
for (int i = 0; i < RTAREA_TRAP_DATA_NUM; i++) {
uae_u8 *data = rtarea_bank.baseaddr + RTAREA_TRAP_DATA + i * RTAREA_TRAP_DATA_SLOT_SIZE;
uae_u8 *status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + i * RTAREA_TRAP_STATUS_SIZE;
if (get_long_host(data + RTAREA_TRAP_DATA_TASKWAIT) && status[3] && status[2] >= 0x80) {
return true;
}
}
return false;
}*/
this.rethink_traps = function() {
return false;
/*if (currprefs.uaeboard < 2)
return false;
if (istrapwait()) {
atomic_or(&uae_int_requested, 0x4000);
set_special_exter(SPCFLAG_UAEINT);
return true;
}
atomic_and(&uae_int_requested, ~0x4000);
return false;*/
}
/*-----------------------------------------------------------------------*/
const RTAREA_WRITEOFFSET = 0xfff0;
function hwtrap_check_int() {
if (hwtrap_waiting == 0) {
atomic_and(uae_int_requested, ~0x2000);
} else {
atomic_or(uae_int_requested, 0x2000);
set_special_exter(SPCFLAG_UAEINT);
}
}
function rtarea_trap_data(addr) {
if (addr >= RTAREA_TRAP_DATA && addr < RTAREA_TRAP_DATA + RTAREA_TRAP_DATA_SIZE)
return true;
return false;
}
function rtarea_trap_status(addr) {
if (addr >= RTAREA_TRAP_STATUS && addr < RTAREA_TRAP_STATUS + RTAREA_TRAP_DATA_NUM * RTAREA_TRAP_STATUS_SIZE)
return true;
return false;
}
/*---------------------------------*/
function rtarea_get32(addr) {
addr &= 0xFFFF;
return ((rtarea_bank.baseaddr[addr] << 24) | (rtarea_bank.baseaddr[addr + 1] << 16) | (rtarea_bank.baseaddr[addr + 2] << 8) | rtarea_bank.baseaddr[addr + 3]) >>> 0;
}
function rtarea_get16(addr) {
addr &= 0xFFFF;
return (rtarea_bank.baseaddr[addr] << 8) + rtarea_bank.baseaddr[addr + 1];
}
function rtarea_get8(addr) {
addr &= 0xFFFF;
if (rtarea_trap_status(addr)) {
var addr2 = addr - RTAREA_TRAP_STATUS;
var trap_offset = addr2 & (RTAREA_TRAP_STATUS_SIZE - 1);
var trap_slot = Math.floor(addr2 / RTAREA_TRAP_STATUS_SIZE);
if (trap_offset == 0) {
// 0 = busy wait, 1 = Wait()
rtarea_bank.baseaddr[addr] = filesystem_state ? 1 : 0;
}
} else if (addr == RTAREA_INTREQ + 0) {
rtarea_bank.baseaddr[addr] = atomic_bit_test_and_reset(uae_int_requested, 0);
//SAEF_log("autoconf.rtarea_get8() %s", rtarea_bank.baseaddr[addr] ? "+" : "-");
} else if (addr == RTAREA_INTREQ + 1) {
rtarea_bank.baseaddr[addr] = hwtrap_waiting != 0;
} else if (addr == RTAREA_INTREQ + 2) {
/*if (SAER.autoconf.rethink_traps()) //OWN empty
rtarea_bank.baseaddr[addr] = 1;
else*/
rtarea_bank.baseaddr[addr] = 0;
}
hwtrap_check_int();
return rtarea_bank.baseaddr[addr];
}
function rtarea_write(addr) {
if (addr >= RTAREA_WRITEOFFSET)
return true;
if (addr >= RTAREA_SYSBASE && addr < RTAREA_SYSBASE + 4)
return true;
return rtarea_trap_data(addr) || rtarea_trap_status(addr);
}
function rtarea_put8(addr, value) {
addr &= 0xffff;
if (!rtarea_write(addr))
return;
rtarea_bank.baseaddr[addr] = value;
if (!rtarea_trap_status(addr))
return;
addr -= RTAREA_TRAP_STATUS;
var trap_offset = addr & (RTAREA_TRAP_STATUS_SIZE - 1);
var trap_slot = Math.floor(addr / RTAREA_TRAP_STATUS_SIZE);
if (trap_offset == RTAREA_TRAP_STATUS_SECOND + 3) {
var v = value;
if (v != 0xff && v != 0xfe && v != 0x01 && v != 02)
SAEF_log("autoconf.rtarea_put8() TRAP %d (%02x)", trap_slot, v);
if (v == 0xfe)
atomic_dec(hwtrap_waiting);
if (v == 0x01)
atomic_dec(hwtrap_waiting);
if (v == 0x01 || v == 0x02) {
// signal call_hardware_trap_back()
// FIXME: OS specific code!
SetEvent(hardware_trap_event[trap_slot]);
}
}
}
function rtarea_put16(addr, value) {
addr &= 0xffff;
value &= 0xffff;
if (!rtarea_write(addr))
return;
rtarea_put8(addr, value >> 8);
rtarea_put8(addr + 1, value & 0xff);
if (!rtarea_trap_status(addr))
return;
addr -= RTAREA_TRAP_STATUS;
var trap_offset = addr & (RTAREA_TRAP_STATUS_SIZE - 1);
var trap_slot = Math.floor(addr / RTAREA_TRAP_STATUS_SIZE);
if (trap_offset == 0) {
SAEF_log("autoconf.rtarea_put16() TRAP %d (%04x)", trap_slot, value);
call_hardware_trap(rtarea_bank.baseaddr, SAEV_AutoConf_base, trap_slot);
}
}
function rtarea_put32(addr, value) {
addr &= 0xffff;
if (!rtarea_write(addr))
return;
rtarea_bank.baseaddr[addr + 0] = value >>> 24;
rtarea_bank.baseaddr[addr + 1] = (value >>> 16) & 0xff;
rtarea_bank.baseaddr[addr + 2] = (value >>> 8) & 0xff;
rtarea_bank.baseaddr[addr + 3] = value & 0xff;
}
function rtarea_xlate(addr) {
addr &= 0xFFFF;
//return rtarea_bank.baseaddr + addr;
return addr;
}
function rtarea_check(addr, size) {
addr &= 0xFFFF;
return (addr + size) <= 0xFFFF;
}
var rtarea_bank = new SAEO_Memory_addrbank(
rtarea_get32, rtarea_get16, rtarea_get8,
rtarea_put32, rtarea_put16, rtarea_put8,
rtarea_xlate, rtarea_check, null, "rtarea", "UAE Boot ROM",
rtarea_get32, rtarea_get16,
SAEC_Memory_addrbank_flag_ROMIN | SAEC_Memory_addrbank_flag_PPCIOSPACE//, S_READ, S_WRITE
);
SAER_AutoConf_bank = rtarea_bank;
/*-----------------------------------------------------------------------*/
this.reset = function() { //rtarea_reset()
//memset(rtarea_bank.baseaddr + RTAREA_TRAP_DATA, 0, RTAREA_TRAP_DATA_SIZE);
//memset(rtarea_bank.baseaddr + RTAREA_TRAP_STATUS, 0, RTAREA_TRAP_STATUS_SIZE * RTAREA_TRAP_DATA_NUM);
SAEF_memset(rtarea_bank.baseaddr,RTAREA_TRAP_DATA, 0, RTAREA_TRAP_DATA_SIZE);
SAEF_memset(rtarea_bank.baseaddr,RTAREA_TRAP_STATUS, 0, RTAREA_TRAP_STATUS_SIZE * RTAREA_TRAP_DATA_NUM);
}
/*-----------------------------------------------------------------------*/
/* some quick & dirty code to fill in the rt area and save me a lot of scratch paper */
var rt_addr = 0;
var rt_straddr = 0;
function addr(ptr) {
//SAEF_log("autoconf.addr() %08x", ptr + SAEV_AutoConf_base);
//return (uae_u32)ptr + SAEV_AutoConf_base;
return ptr + SAEV_AutoConf_base;
}
this.db = function(data) {
//SAEF_log("autoconf.db() %02x", data);
rtarea_bank.baseaddr[rt_addr++] = data;
}
this.dw = function(data) {
//SAEF_log("autoconf.dw() %04x", data);
rtarea_bank.baseaddr[rt_addr++] = data >> 8;
rtarea_bank.baseaddr[rt_addr++] = data & 0xff;
}
this.dl = function(data) {
//SAEF_log("autoconf.dl() %08x", data);
rtarea_bank.baseaddr[rt_addr++] = data >> 24;
rtarea_bank.baseaddr[rt_addr++] = (data >> 16) & 0xff;
rtarea_bank.baseaddr[rt_addr++] = (data >> 8) & 0xff;
rtarea_bank.baseaddr[rt_addr++] = data & 0xff;
}
/*this.dbg = function(addr) {
addr -= SAEV_AutoConf_base;
return rtarea_bank.baseaddr[addr];
}*/
/* store strings starting at the end of the rt area and working backward. store pointer at current address */
/*uae_u32 ds_ansi (const uae_char *str) {
int len;
if (!str)
return addr (rt_straddr);
len = strlen (str) + 1;
rt_straddr -= len;
strcpy ((uae_char*)rtarea_bank.baseaddr + rt_straddr, str);
return addr (rt_straddr);
}
uae_u32 ds (const TCHAR *str) {
char *s = ua (str);
uae_u32 v = ds_ansi (s);
xfree (s);
return v;
}
uae_u32 ds_bstr_ansi (const uae_char *str) {
int len;
len = strlen (str) + 2;
rt_straddr -= len;
while (rt_straddr & 3)
rt_straddr--;
rtarea_bank.baseaddr[rt_straddr] = len - 2;
strcpy ((uae_char*)rtarea_bank.baseaddr + rt_straddr + 1, str);
return addr (rt_straddr) >> 2;
}*/
this.calltrap = function(n) {
/*if (currprefs.uaeboard > 2) {
this.dw(0x4eb9); // JSR rt_trampoline_ptr
this.dl(rt_trampoline_ptr);
uaecptr a = this.here();
this.org(rt_trampoline_ptr);
this.dw(0x3f3c); // MOVE.W #n,-(SP)
this.dw(n);
this.dw(0x4ef9); // JMP rt_trampoline_entry
this.dl(trap_entry);
this.org(a);
rt_trampoline_ptr += 3 * 2 + 1 * 4;
} else*/
this.dw(0xA000 + n);
}
this.org = function(a) {
if (((a & 0xffff0000) >>> 0 != 0x00f00000) && ((a & 0xffff0000) >>> 0 != SAEV_AutoConf_base))
SAEF_warn("autoconf.org() corrupt address %08X", a);
rt_addr = a & 0xffff;
}
this.here = function() {
return addr(rt_addr);
}
/*this.align = function(b) {
rt_addr = (rt_addr + b - 1) & ~(b - 1);
}*/
/*-----------------------------------------------------------------------*/
function mapped_malloc(ab) {
ab.startmask = ab.start;
try {
//ab.baseaddr = xcalloc(uae_u8, ab.allocated + 4);
ab.baseaddr = new Uint8Array(ab.allocated + 4);
return true;
} catch (e) {
ab.baseaddr = null;
return false;
}
}
function mapped_free(ab) {
//xfree(ab.baseaddr);
ab.baseaddr = null;
}
/*static uae_u32 REGPARAM2 nullfunc (TrapContext *ctx) {
write_log (_T("Null function called\n"));
return 0;
}
static uae_u32 REGPARAM2 getchipmemsize (TrapContext *ctx) {
trap_set_dreg(ctx, 1, z3chipmem_bank.allocated);
trap_set_areg(ctx, 1, z3chipmem_bank.start);
return chipmem_bank.allocated;
}
static uae_u32 REGPARAM2 uae_puts (TrapContext *ctx) {
puts ((char*)get_real_address(trap_get_areg(ctx, 0)));
return 0;
}*/
/* OPT inline ok
function rtarea_init_mem() {
if (SAER.autoconf.need_uae_boot_rom())
rtarea_bank.flags &= ~SAEC_Memory_addrbank_flag_ALLOCINDIRECT;
else
rtarea_bank.flags |= SAEC_Memory_addrbank_flag_ALLOCINDIRECT;
rtarea_bank.allocated = RTAREA_SIZE;
if (!mapped_malloc(rtarea_bank)) {
SAEF_fatal(SAEE_NoMemory, "autoconf.init_mem() memory exhausted");
//abort();
}
}*/
this.setup = function() { //rtarea_init()
rt_straddr = 0xFF00 - 2;
rt_addr = 0;
rt_trampoline_ptr = SAEV_AutoConf_base + RTAREA_TRAMPOLINE;
trap_entry = 0;
this.init_traps();
//rtarea_init_mem();
{
if (this.need_uae_boot_rom())
rtarea_bank.flags &= ~SAEC_Memory_addrbank_flag_ALLOCINDIRECT;
else
rtarea_bank.flags |= SAEC_Memory_addrbank_flag_ALLOCINDIRECT;
rtarea_bank.allocated = RTAREA_SIZE;
if (!mapped_malloc(rtarea_bank)) {
SAEF_fatal(SAEE_NoMemory, "autoconf.init_mem() memory exhausted");
//abort();
}
}
//memset(rtarea_bank.baseaddr, 0, RTAREA_SIZE);
SAEF_memset(rtarea_bank.baseaddr,0, 0, RTAREA_SIZE);
/*var uaever = sprintf("uae-%d.%d.%d", UAEMAJOR, UAEMINOR, UAESUBREV);
var saever = sprintf("sae-%d.%d.%d", SAEC_Version, SAEC_Revision, SAEC_Patch);
EXPANSION_uaeversion = ds(saever);
EXPANSION_explibname = ds("expansion.library");
EXPANSION_doslibname = ds("dos.library");
EXPANSION_uaedevname = ds("uae.device");*/
this.dw(0);
this.dw(0);
/*#ifdef FILESYS
filesys_install_code();
trap_entry = filesys_get_entry(10);
write_log(_T("TRAP_ENTRY = %08x\n"), trap_entry);
for (int i = 0; i < RTAREA_TRAP_DATA_SIZE / RTAREA_TRAP_DATA_SLOT_SIZE; i++) {
hardware_trap_event[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
}
#endif*/
this.define_trap(null, 0, "null"); /* Generic emulator trap */
/*var a = this.here();
// Dummy trap - removing this breaks the filesys emulation.
this.org(SAEV_AutoConf_base + 0xFF00);
this.calltrap(deftrap2(nullfunc, TRAPFLAG_NO_RETVAL, ""));
this.org(SAEV_AutoConf_base + 0xFF80);
this.calltrap(deftrapres(getchipmemsize, TRAPFLAG_DORET, "getchipmemsize"));
this.dw(SAEC_AutoConf_RTS);
this.org(SAEV_AutoConf_base + 0xFF10);
this.calltrap(deftrapres(uae_puts, TRAPFLAG_NO_RETVAL, "uae_puts"));
this.dw(SAEC_AutoConf_RTS);
this.org(a);*/
SAEV_AutoConf_boot_rom_size = this.here() - SAEV_AutoConf_base;
SAEF_log("autoconf.setup() boot_rom_size %d/%d", SAEV_AutoConf_boot_rom_size, RTAREA_TRAPS);
if (SAEV_AutoConf_boot_rom_size >= RTAREA_TRAPS) {
SAEF_fatal(SAEE_NoMemory, "autoconf.setup() RTAREA_TRAPS needs to be increased!");
//abort();
}
/*#ifdef PICASSO96
uaegfx_install_code(SAEV_AutoConf_base + RTAREA_RTG);
#endif*/
this.org(RTAREA_TRAPS | SAEV_AutoConf_base);
this.init_extended_traps();
}
this.cleanup = function() { //rtarea_free()
mapped_free(rtarea_bank);
this.free_traps();
}
this.init = function() { //rtarea_setup()
var base = this.need_uae_boot_rom();
if (base) {
SAEF_log("autoconf.init() RTAREA located at %08X", base);
SAEV_AutoConf_base = base;
}
}
/*-----------------------------------------------------------------------*/
this.makedatatable = function(resid, resname, type, priority, ver, rev) {
var datatable = this.here();
this.dw(0xE000); /* INITBYTE */
this.dw(0x0008); /* LN_TYPE */
this.dw(type << 8);
this.dw(0xE000); /* INITBYTE */
this.dw(0x0009); /* LN_PRI */
this.dw(priority << 8);
this.dw(0xC000); /* INITLONG */
this.dw(0x000A); /* LN_NAME */
this.dl(resname);
this.dw(0xE000); /* INITBYTE */
this.dw(0x000E); /* LIB_FLAGS */
this.dw(0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
this.dw(0xD000); /* INITWORD */
this.dw(0x0014); /* LIB_VERSION */
this.dw(ver);
this.dw(0xD000); /* INITWORD */
this.dw(0x0016); /* LIB_REVISION */
this.dw(rev);
this.dw(0xC000); /* INITLONG */
this.dw(0x0018); /* LIB_IDSTRING */
this.dl(resid);
this.dw(0x0000); /* end of table */
return datatable;
}
/*-----------------------------------------------------------------------*/
/* SECT Traps */
/*-----------------------------------------------------------------------*/
const TRAPFLAG_NO_REGSAVE = 1;
const TRAPFLAG_NO_RETVAL = 2;
const TRAPFLAG_EXTRA_STACK = 4;
const TRAPFLAG_DORET = 8;
const TRAPFLAG_UAERES = 16;
function Trap() {
this.handler = null; /* Handler function to be invoked for this trap */
this.flags = 0; /* Trap attributes */
this.name = ""; /* For debugging purposes */
this.addr = 0;
};
const MAX_TRAPS = 16; //4096;
var trap_count = 1;
var traps = new Array(MAX_TRAPS);
for (var vi = 0; vi < MAX_TRAPS; vi++)
traps[vi] = new Trap();
var hwtrap_waiting = 0; //volatile uae_atomic
const trace_traps = true;
/*-----------------------------------------------------------------------*/
this.find_trap = function(name) {
for (var i = 0; i < trap_count; i++) {
var trap = traps[i];
if ((trap.flags & TRAPFLAG_UAERES) && trap.name.length && trap.name == name)
return trap.addr;
}
return 0;
}
/*
* Define an emulator trap
*
* handler_func = host function that will be invoked to handle this trap
* flags = trap attributes
* name = name for debugging purposes
*
* returns trap number of defined trap
*/
this.define_trap = function(handler_func, flags, name) {
if (trap_count == MAX_TRAPS) {
SAEF_fatal(SAEE_Internal, "define_trap() Ran out of emulator traps. (increase MAX_TRAPS)");
//abort();
//return -1;
} else {
var addr = this.here();
for (var i = 0; i < trap_count; i++) {
if (addr == traps[i].addr)
return i;
}
var trap_num = trap_count++;
var trap = traps[trap_num];
trap.handler = handler_func;
trap.flags = flags;
trap.name = name;
trap.addr = addr;
return trap_num;
}
}
/*
* This function is called by the 68k interpreter to handle an emulator trap.
*
* trap_num = number of trap to invoke
* regs = current 68k state
*/
this.m68k_handle_trap = function(trap_num) {
var trap = traps[trap_num];
var retval = 0;
var has_retval = (trap.flags & TRAPFLAG_NO_RETVAL) == 0;
var implicit_rts = (trap.flags & TRAPFLAG_DORET) != 0;
if (trap.name.length && trace_traps)
SAEF_log("m68k_handle_trap() TRAP '%s'", trap.name);
if (trap_num < trap_count) {
if (trap.flags & TRAPFLAG_EXTRA_STACK) {
/* Handle an extended trap.
* Note: the return value of this trap is passed back to 68k
* space via a separate, dedicated simple trap which the trap
* handler causes to be invoked when it is done.
*/
//trap_HandleExtendedTrap(trap.handler, has_retval); //FIX implement extended-traps
SAEF_fatal(SAEE_Internal, "m68k_handle_trap() Extended-traps are not implemented.");
} else {
/* Handle simple trap */
//retval = (trap.handler)(null);
retval = trap.handler(null);
if (has_retval) {
SAER_CPU_regs.d[0] = retval;
SAEF_log("m68k_handle_trap() D0 = %d", retval);
}
if (implicit_rts) {
//m68k_do_rts(); {
var newpc = SAER_Memory_get32(SAER_CPU_regs.a[7]);
SAER_CPU_setPC(newpc);
SAER_CPU_regs.a[7] += 4;
//}
SAER_CPU_fill_prefetch();
}
}
} else
SAEF_warn("m68k_handle_trap() illegal emulator trap");
}
/*-----------------------------------------------------------------------*/
this.init_traps = function() {
trap_count = 0;
hwtrap_waiting = 0;
}
this.free_traps = function() {
}
this.init_extended_traps = function() {
}
}

File diff suppressed because it is too large Load diff

1494
sae/cia.js

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,366 +0,0 @@
/**************************************************************************
* SAE - Scripted Amiga Emulator
*
* 2012-2015 Rupert Hausberger
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
**************************************************************************/
const SAEV_Version = 0;
const SAEV_Revision = 8;
const SAEV_Revision_Sub = 2;
/*-----------------------------------------------------------------------*/
/* info */
const SAEI_Audio_WebAudio = 1;
const SAEI_Video_Canvas2D = 1;
const SAEI_Video_WebGL = 2;
/*-----------------------------------------------------------------------*/
/* cpu */
const SAEV_Config_CPU_Speed_Maximum = -1;
const SAEV_Config_CPU_Speed_Original = 0;
/*-----------------------------------------------------------------------*/
/* chipset */
const SAEV_Config_Chipset_Type_OCS = 1;
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_Sprite_Sprite = 1;
const SAEV_Config_Chipset_ColLevel_Sprite_Playfield = 2;
const SAEV_Config_Chipset_ColLevel_Full = 3;
/*-----------------------------------------------------------------------*/
/* ram */
const SAEV_Config_RAM_Chip_Size_256K = 1;
const SAEV_Config_RAM_Chip_Size_512K = 2;
const SAEV_Config_RAM_Chip_Size_1M = 3;
const SAEV_Config_RAM_Chip_Size_2M = 4;
const SAEV_Config_RAM_Slow_Size_None = 0;
const SAEV_Config_RAM_Slow_Size_256K = 1;
const SAEV_Config_RAM_Slow_Size_512K = 2;
const SAEV_Config_RAM_Slow_Size_1M = 3;
const SAEV_Config_RAM_Slow_Size_1536K = 4;
const SAEV_Config_RAM_Fast_Size_None = 0;
const SAEV_Config_RAM_Fast_Size_512K = 1;
const SAEV_Config_RAM_Fast_Size_1M = 2;
const SAEV_Config_RAM_Fast_Size_2M = 3;
const SAEV_Config_RAM_Fast_Size_4M = 4;
const SAEV_Config_RAM_Fast_Size_8M = 5;
/*-----------------------------------------------------------------------*/
/* rom, ext */
const SAEV_Config_ROM_Size_None = 0;
const SAEV_Config_ROM_Size_256K = 1;
const SAEV_Config_ROM_Size_512K = 2;
const SAEV_Config_EXT_Size_None = 0;
const SAEV_Config_EXT_Size_256K = 1;
const SAEV_Config_EXT_Size_512K = 2;
//const SAEV_Config_EXT_Addr_A0 = 1;
const SAEV_Config_EXT_Addr_E0 = 2;
const SAEV_Config_EXT_Addr_F0 = 3;
/*-----------------------------------------------------------------------*/
/* disk */
const SAEV_Config_Floppy_Type_None = 0;
const SAEV_Config_Floppy_Type_35_DD = 1;
const SAEV_Config_Floppy_Type_35_HD = 2;
const SAEV_Config_Floppy_Type_525_SD = 3;
const SAEV_Config_Floppy_Speed_Turbo = 0;
const SAEV_Config_Floppy_Speed_Original = 100;
/*-----------------------------------------------------------------------*/
/* audio */
const SAEV_Config_Audio_Mode_Emul = 0;
const SAEV_Config_Audio_Mode_Play = 1;
const SAEV_Config_Audio_Mode_Play_Best = 2;
const SAEV_Config_Audio_Channels_Mono = 1;
const SAEV_Config_Audio_Channels_Stereo = 2;
/*-----------------------------------------------------------------------*/
/* input */
const SAEV_Config_Ports_Type_None = 0;
const SAEV_Config_Ports_Type_Mouse = 1;
const SAEV_Config_Ports_Type_Joy0 = 2;
const SAEV_Config_Ports_Type_Joy1 = 3;
const SAEV_Config_Ports_Move_None = 0;
const SAEV_Config_Ports_Move_Arrows = 1;
const SAEV_Config_Ports_Move_Numpad = 2;
const SAEV_Config_Ports_Move_WASD = 3;
const SAEV_Config_Ports_Fire_None = 0;
/*-----------------------------------------------------------------------*/
/* rtc */
const SAEV_Config_RTC_Type_None = 0;
const SAEV_Config_RTC_Type_MSM6242B = 1;
const SAEV_Config_RTC_Type_RF5C01A = 2;
/*-----------------------------------------------------------------------*/
/* erros */
//const SAEE_None = 0;
const SAEE_CPU_Internal = 1;
const SAEE_CPU_68020_Required = 2;
const SAEE_Disk_File_Too_Big = 3;
const SAEE_Video_Shader_Error = 4;
const SAEE_Video_ID_Not_Found = 5;
const SAEE_Video_Canvas_Not_Supported = 6;
//const SAEE_Video_WebGL_Not_Avail = 7;
const SAEE_Audio_WebAudio_Not_Avail = 8;
/*-----------------------------------------------------------------------*/
/* methods */
/*const SAEM_Init = 1;
const SAEM_Start = 2;
const SAEM_Stop = 3;
const SAEM_Pause = 4;
const SAEM_Reset = 5;
const SAEM_Insert = 6;
const SAEM_Eject = 7;*/
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* amiga */
const ST_STOP = 0;
const ST_CYCLE = 1;
const ST_PAUSE = 2;
const ST_IDLE = 3;
/*-----------------------------------------------------------------------*/
/* events */
const EV_CIA = 0;
const EV_AUDIO = 1;
const EV_MISC = 2;
const EV_HSYNC = 3;
const EV_MAX = 4;
const EV2_BLITTER = 0;
const EV2_DISK = 1;
const EV2_DMAL = 2;
const EV2_MISC = 3;
const EV2_MAX = 3 + 10;
const CYCLE_UNIT = 512;
const CYCLE_UNIT_INV = 1.0 / CYCLE_UNIT; /* mul is always faster than div */
const CYCLE_MAX = 0xffffffff * CYCLE_UNIT;
/*-----------------------------------------------------------------------*/
/* cpu */
const SPCFLAG_STOP = 2;
const SPCFLAG_COPPER = 4;
const SPCFLAG_INT = 8;
//const SPCFLAG_BRK = 16;
const SPCFLAG_TRACE = 64;
const SPCFLAG_DOTRACE = 128;
const SPCFLAG_DOINT = 256;
const SPCFLAG_BLTNASTY = 512;
const SPCFLAG_TRAP = 1024;
/*-----------------------------------------------------------------------*/
/* amiga */
const INTF_TBE = 1 << 0;
const INTF_DSKBLK = 1 << 1;
const INTF_PORTS = 1 << 3;
const INTF_COPER = 1 << 4;
const INTF_VERTB = 1 << 5;
const INTF_BLIT = 1 << 6;
const INTF_AUD0 = 1 << 7;
const INTF_AUD1 = 1 << 8;
const INTF_AUD2 = 1 << 9;
const INTF_AUD3 = 1 << 10;
const INTF_RBF = 1 << 11;
const INTF_DSKSYN = 1 << 12;
const INTF_EXTER = 1 << 13;
const INTF_INTEN = 1 << 14;
const INTF_SETCLR = 1 << 15;
const INT_DSKBLK = INTF_SETCLR | INTF_DSKBLK;
const INT_VERTB = INTF_SETCLR | INTF_VERTB;
const INT_BLIT = INTF_SETCLR | INTF_BLIT;
const INT_DSKSYN = INTF_SETCLR | INTF_DSKSYN;
const DMAF_AUD0EN = 1 << 0;
const DMAF_AUD1EN = 1 << 1;
const DMAF_AUD2EN = 1 << 2;
const DMAF_AUD3EN = 1 << 3;
const DMAF_DSKEN = 1 << 4;
const DMAF_SPREN = 1 << 5;
const DMAF_BLTEN = 1 << 6;
const DMAF_COPEN = 1 << 7;
const DMAF_BPLEN = 1 << 8;
const DMAF_DMAEN = 1 << 9;
const DMAF_BLTPRI = 1 << 10;
const DMAF_BZERO = 1 << 13;
const DMAF_BBUSY = 1 << 14;
const DMAF_SETCLR = 1 << 15;
/*-----------------------------------------------------------------------*/
/* blitter */
const BLT_done = 0;
const BLT_init = 1;
const BLT_read = 2;
const BLT_work = 3;
const BLT_write = 4;
const BLT_next = 5;
/*-----------------------------------------------------------------------*/
/* video */
const VIDEO_WIDTH = 720; /* == 360*2 */
const VIDEO_HEIGHT = 568; /* == 284*2 */
const VIDEO_DEPTH = 32;
/*-----------------------------------------------------------------------*/
/* audio */
const PERIOD_MIN = 4;
const PERIOD_MIN_NONCE = 60;
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 AUTOSCALE_SPRITES = 1;
//const SPRBORDER = 0;
const SPR0_HPOS = 0x15;
const MAX_SPRITES = 8;
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 MAX_WORDS_PER_LINE = 100;
const DO_SPRITES = 1;
const FAST_COLORS = 0;

File diff suppressed because it is too large Load diff

13899
sae/cpu.js

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

58
sae/disassembler.js Normal file
View file

@ -0,0 +1,58 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
-------------------------------------------------------------------------*/
/* errors (copied from amiga.js) */
function SAEO_Error(err, msg) {
this.err = err;
this.msg = msg;
}
SAEO_Error.prototype = new Error;
const SAEE_None = 0;
const SAEE_AlreadyRunning = 1;
const SAEE_NotRunning = 2;
const SAEE_NoTimer = 3;
const SAEE_NoMemory = 4;
const SAEE_Assert = 5;
const SAEE_Internal = 6;
const SAEE_Config_Invalid = 10;
const SAEE_CPU_Internal = 20;
const SAEE_CPU_Requires68020 = 21;
const SAEE_CPU_Requires680EC20 = 22;
const SAEE_CPU_Requires68030 = 23;
const SAEE_CPU_Requires68040 = 24;
/*-----------------------------------------------------------------------*/
function ScriptedDisAssembler() {
this.cpu = new SAEO_CPU();
var err = this.cpu.setup_da(68030);
if (err != SAEE_None)
throw err;
/*---------------------------------*/
this.getConfig = function() {
return this.cpu.getConfig_da();
}
this.disassemble = function() {
return this.cpu.disassemble();
}
}

File diff suppressed because it is too large Load diff

1308
sae/dms.js Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

179
sae/filesys.js Normal file
View file

@ -0,0 +1,179 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: ported from WinUAE 3.2.x
-------------------------------------------------------------------------*/
function SAEO_Filesys() {
this.uci_set_defaults = function(uci, rdb) {
//memset(uci, 0, sizeof(struct uaedev_config_info));
//controller
//if (uci.controller_type == 0)
uci.controller_type = SAEC_Config_Mount_Controller_Type_MB_IDE;
uci.controller_unit = 0; //IDE channel + unit
uci.controller_media_type = 0; // 1 = CF IDE, 0 = normal
uci.unit_feature_level = SAEC_Config_Mount_Controller_Level_ATA_2;
uci.unit_special_flags = 0; //1 = force LBA48
//file
//uci.type = UAEDEV_HDF;
//uci.file.name = "";
//uci.file.size = 0;
//uci.file.data = "";
uci.readonly = false;
//rdb
//drive geometry
uci.blocksize = 512;
uci.cyls = 0; // calculated/corrected highcyl
if (!rdb) {
uci.surfaces = 1;
uci.sectors = 32;
}
//partition
uci.bootable = true;
uci.automount = true;
uci.unit = 0;
uci.flags = 0;
uci.devname = "";
//DosEnvec
uci.sectorsperblock = 1;
if (!rdb)
uci.reserved = 2;
uci.interleave = false;
uci.lowcyl = 0;
uci.highcyl = 0; // zero if detected from size
uci.buffers = 50;
uci.bufmemtype = 1;
uci.maxtransfer = 0x7fffffff;
uci.mask = 0xffffffff;
uci.bootpri = 0;
uci.dostype = 0x444f5301;
//filesystem
uci.filesys = "";
//DeviceNode
uci.stacksize = 4000;
uci.priority = -129;
//uci.device_emu_unit = -1;
}
/*-----------------------------------------------------------------------*/
function allocuci(p, nr, idx, unitnum) {
if (typeof unitnum == "undefined")
unitnum = -1;
var uci = p.mount.config[nr];
if (idx >= 0) {
/*var ui = mountinfo.ui[idx];
ui.configureddrive = 1;*/
uci.configoffset = idx;
uci.unitnum = unitnum;
} else {
uci.configoffset = -1;
uci.unitnum = -1;
}
}
/*---------------------------------*/
function getunittype(uci) {
return "HD" //uci.type == UAEDEV_CD ? "CD" : (uci.type == UAEDEV_TAPE ? "TAPE" : "HD");
}
function ismainboardide() {
return SAEV_config.chipset.ide != 0;
}
/*function isa3000scsi() {
return SAEV_config.chipset.mbdmac == 1;
}
function isa4000tscsi() {
return SAEV_config.chipset.mbdmac == 2;
}
function iscdtvscsi() {
return currprefs.cs_cdtvscsi != 0;
}*/
function add_mainboard_unit_init() {
if (ismainboardide()) {
SAEF_log("filesys.add_mainboard_unit_init() Initializing mainboard IDE");
SAER.gayle.gayle_add_ide_unit(-1, null);
}
/*if (isa3000scsi()) {
SAEF_log("filesys.add_mainboard_unit_init() Initializing A3000 mainboard SCSI");
a3000_add_scsi_unit(-1, null, null);
}
if (isa4000tscsi()) {
SAEF_log("filesys.add_mainboard_unit_init() Initializing A4000T mainboard SCSI");
a4000t_add_scsi_unit(-1, null, null);
}
if (iscdtvscsi()) {
SAEF_log("filesys.add_mainboard_unit_init() Initializing CDTV SCSI expansion");
cdtv_add_scsi_unit(-1, null, null);
}*/
}
function add_ide_unit(type, unit, uci) {
var added = false;
if (type == SAEC_Config_Mount_Controller_Type_MB_IDE) {
if (ismainboardide()) {
SAEF_log("filesys.add_ide_unit() Adding mainboard IDE %s unit %d ('%s')", getunittype(uci), unit, uci.file.name);
SAER.gayle.gayle_add_ide_unit(unit, uci);
added = true;
}
}
return added;
}
function initialize_mountinfo() {
// init all controllers first
add_mainboard_unit_init();
for (var nr = 0; nr < 6; nr++) {
var uci = SAEV_config.mount.config[nr].ci;
var type = uci.controller_type;
var unit = uci.controller_unit;
var added = false;
if (type == 0 || uci.file.size == 0)
continue;
if (type == SAEC_Config_Mount_Controller_Type_MB_IDE)
added = add_ide_unit(type, unit, uci);
else if (type == SAEC_Config_Mount_Controller_Type_PCMCIA_SRAM) {
SAER.gayle.gayle_add_pcmcia_sram_unit(uci);
added = true;
}
else if (type == SAEC_Config_Mount_Controller_Type_PCMCIA_IDE) {
SAER.gayle.gayle_add_pcmcia_ide_unit(uci);
added = true;
}
if (added)
allocuci(SAEV_config, nr, -1);
}
}
function free_mountinfo() {
SAER.gayle.free_units();
}
/*-----------------------------------------------------------------------*/
this.start_threads = function() {} //filesys_start_threads()
this.cleanup = function() { //filesys_cleanup()
free_mountinfo();
}
this.reset = function() { //filesys_reset()
free_mountinfo();
initialize_mountinfo();
}
this.prepare_reset = function() {} //filesys_prepare_reset()
}

1586
sae/gayle.js Normal file

File diff suppressed because it is too large Load diff

1339
sae/hardfile.js Normal file

File diff suppressed because it is too large Load diff

1499
sae/ide.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,21 @@
/**************************************************************************
* SAE - Scripted Amiga Emulator
*
* 2012-2015 Rupert Hausberger
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
**************************************************************************/
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
-------------------------------------------------------------------------*/
function Mouse() {
function SAEO_Mouse() {
this.button = [false, false, false];
this.pos = 0;
@ -18,41 +26,41 @@ function Mouse() {
var lx = -1;
var ly = -1;
this.reset = function () {
this.reset = function() {
this.button = [0, 0, 0];
cx = cy = 0;
lx = ly = -1;
};
this.mousedown = function (e) {
this.mousedown = function(e) {
e = e || window.event;
if (!e) return;
this.button[e.button] = true;
};
this.mouseup = function (e) {
this.mouseup = function(e) {
e = e || window.event;
if (!e) return;
this.button[e.button] = false;
};
this.mouseover = function (e) {
//AMIGA.video.hideCursor(1);
this.mouseover = function(e) {
//SAER.video.hideCursor(1);
this.mousemove(e);
lx = cx;
ly = cy;
};
this.mouseout = function (e) {
//AMIGA.video.hideCursor(0);
this.mouseout = function(e) {
//SAER.video.hideCursor(0);
this.mouseup(e);
};
this.mousemove = function (e) {
this.mousemove = function(e) {
e = e || window.event;
if (!e || !AMIGA.video) return;
if (!e) return;
if (e.pageX || e.pageY) {
cx = e.pageX;
@ -65,7 +73,7 @@ function Mouse() {
lx = cx;
ly = cy;
}
//BUG.info('USER() mousemove %d %d', cx, cy);
//SAEF_log("input.mousemove() %d %d", cx, cy);
};
this.update = function() {
@ -73,6 +81,16 @@ function Mouse() {
var dx = cx - lx;
var dy = cy - ly;
/* not working
var shift = SAEV_config.video.hresolution - SAER.playfield.get_bplcon0_res();
var bplcon = SAER.playfield.get_bplcon0();
var res = (bplcon & 0x40) ? SAEC_Config_Video_HResolution_SuperHiRes : ((bplcon & 0x8000) ? SAEC_Config_Video_HResolution_HiRes : SAEC_Config_Video_HResolution_LoRes);
var shift = SAEV_config.video.hresolution - res;
if (shift) {
dx <<= shift;
dy <<= shift;
}*/
if (dx > 127) dx = 127; else if (dx < -127) dx = -127;
mx += dx;
if (mx > 255) mx -= 256; else if (mx < 0) mx += 256;
@ -87,17 +105,17 @@ function Mouse() {
ly = cy;
this.pos = (my << 8) + mx;
//BUG.info('USER() mousemove %d %d, ps $%04x', mx, my, this.pos);
//SAEF_log("input.update() %d %d %d, ps $%04x", shift, mx, my, this.pos);
}
}
function Joystick(type) {
function SAEO_Joystick(type) {
this.type = type;
this.button = [false, false, false];
this.state = [false, false, false, false];
this.dir = 0;
this.reset = function () {
this.reset = function() {
this.button = [false, false, false];
this.state = [false, false, false, false];
};
@ -127,7 +145,12 @@ function Joystick(type) {
}
}
function Keyboard() {
function SAEO_Keyboard() {
const DOM_KEY_LOCATION_STANDARD = 0x00;
const DOM_KEY_LOCATION_LEFT = 0x01;
const DOM_KEY_LOCATION_RIGHT = 0x02;
const DOM_KEY_LOCATION_NUMPAD = 0x03;
const RAWKEY_TILDE = 0x00;
const RAWKEY_1 = 0x01;
const RAWKEY_2 = 0x02;
@ -191,13 +214,13 @@ function Keyboard() {
const RAWKEY_SPACE = 0x40;
const RAWKEY_BACKSPACE = 0x41;
const RAWKEY_TAB = 0x42;
//const RAWKEY_KP_ENTER = 0x43;
const RAWKEY_KP_ENTER = 0x43;
const RAWKEY_RETURN = 0x44;
const RAWKEY_ESCAPE = 0x45;
const RAWKEY_DELETE = 0x46;
//const RAWKEY_INSERT = 0x47;
//const RAWKEY_PAGEUP = 0x48;
//const RAWKEY_PAGEDOWN = 0x49;
const RAWKEY_INSERT = 0x47;
const RAWKEY_PAGEUP = 0x48;
const RAWKEY_PAGEDOWN = 0x49;
const RAWKEY_KP_MINUS = 0x4A;
//const RAWKEY_F11 = 0x4B;
const RAWKEY_UP = 0x4C;
@ -223,28 +246,29 @@ function Keyboard() {
const RAWKEY_CAPSLOCK = 0x62;
const RAWKEY_CONTROL = 0x63;
const RAWKEY_LALT = 0x64;
//const RAWKEY_RALT = 0x65;
const RAWKEY_RALT = 0x65;
const RAWKEY_LAMIGA = 0x66;
const RAWKEY_RAMIGA = 0x67;
/*const RAWKEY_SCRLOCK = 0x6B;
const RAWKEY_PRTSCREEN = 0x6C;
const RAWKEY_SCRLOCK = 0x6B;
//const RAWKEY_PRTSCREEN = 0x6C;*/
const RAWKEY_NUMLOCK = 0x6D;
const RAWKEY_PAUSE = 0x6E;
const RAWKEY_F12 = 0x6F;
//const RAWKEY_F12 = 0x6F;
const RAWKEY_HOME = 0x70;
const RAWKEY_END = 0x71;
const RAWKEY_MEDIA1 = 0x72;
/*const RAWKEY_MEDIA1 = 0x72;
const RAWKEY_MEDIA2 = 0x73;
const RAWKEY_MEDIA3 = 0x74;
const RAWKEY_MEDIA4 = 0x75;
const RAWKEY_MEDIA5 = 0x76;
const RAWKEY_MEDIA6 = 0x77;
const RAWKEY_NM_WHEEL_UP = 0x7A;
const RAWKEY_MEDIA6 = 0x77;*/
const RAWKEY_RESETWARNING = 0x78;
/*const RAWKEY_NM_WHEEL_UP = 0x7A;
const RAWKEY_NM_WHEEL_DOWN = 0x7B;
const RAWKEY_NM_WHEEL_LEFT = 0x7C;
const RAWKEY_NM_WHEEL_RIGHT = 0x7D;
const RAWKEY_NM_BUTTON_FOURTH = 0x7E;*/
/*const RAWKEY_BAD_CODE = 0xF9;
const RAWKEY_NM_BUTTON_FOURTH = 0x7E;
const RAWKEY_BAD_CODE = 0xF9;
const RAWKEY_BUFFER_OVERFLOW = 0xFA;
const RAWKEY_SELFTEST_FAILED = 0xFC;*/
const RAWKEY_INIT_POWER_UP = 0xFD;
@ -257,19 +281,19 @@ function Keyboard() {
16:RAWKEY_LSHIFT, //shift
17:RAWKEY_CONTROL, //ctrl
18:RAWKEY_LALT, //alt
//19:RAWKEY_PAUSE, //pause/break
19:RAWKEY_PAUSE, //pause/break
20:RAWKEY_CAPSLOCK, //caps lock
27:RAWKEY_ESCAPE, //escape
32:RAWKEY_SPACE, //space
//33:RAWKEY_PAGEUP, //page up
//34:RAWKEY_PAGEDOWN, //page down
//35:RAWKEY_END, //end
//36:RAWKEY_HOME, //home
33:RAWKEY_PAGEUP, //page up
34:RAWKEY_PAGEDOWN, //page down
35:RAWKEY_END, //end
36:RAWKEY_HOME, //home
37:RAWKEY_LEFT, //left arrow
38:RAWKEY_UP, //up arrow
39:RAWKEY_RIGHT, //right arrow
40:RAWKEY_DOWN, //down arrow
//45:RAWKEY_INSERT, //insert
45:RAWKEY_INSERT, //insert
46:RAWKEY_DELETE, //delete
48:RAWKEY_0, //0
49:RAWKEY_1, //1
@ -337,8 +361,8 @@ function Keyboard() {
121:RAWKEY_F10, //f10
//122:RAWKEY_F11, //f11
//123:RAWKEY_F12, //f12
//144:RAWKEY_NUMLOCK, //num lock
//145:RAWKEY_SCRLOCK, //scroll lock
144:RAWKEY_NUMLOCK, //num lock
145:RAWKEY_SCRLOCK, //scroll lock
/*186:RAWKEY_SEMICOLON, //semi-colon
187:RAWKEY_EQUAL, //equal sign
188:RAWKEY_COMMA, //comma
@ -371,19 +395,19 @@ function Keyboard() {
16:RAWKEY_LSHIFT, //shift
17:RAWKEY_CONTROL, //ctrl
18:RAWKEY_LALT, //alt
//19:RAWKEY_PAUSE, //pause/break
19:RAWKEY_PAUSE, //pause/break
20:RAWKEY_CAPSLOCK, //caps lock
27:RAWKEY_ESCAPE, //escape
32:RAWKEY_SPACE, //space
//33:RAWKEY_PAGEUP, //page up
//34:RAWKEY_PAGEDOWN, //page down
//35:RAWKEY_END, //end
//36:RAWKEY_HOME, //home
33:RAWKEY_PAGEUP, //page up
34:RAWKEY_PAGEDOWN, //page down
35:RAWKEY_END, //end
36:RAWKEY_HOME, //home
37:RAWKEY_LEFT, //left arrow
38:RAWKEY_UP, //up arrow
39:RAWKEY_RIGHT, //right arrow
40:RAWKEY_DOWN, //down arrow
//45:RAWKEY_INSERT, //insert
45:RAWKEY_INSERT, //insert
46:RAWKEY_DELETE, //delete
48:RAWKEY_0, //0
49:RAWKEY_1, //1
@ -453,8 +477,8 @@ function Keyboard() {
121:RAWKEY_F10, //f10
//122:RAWKEY_F11, //f11
//123:RAWKEY_F12, //f12
//144:RAWKEY_NUMLOCK, //num lock
//145:RAWKEY_SCRLOCK, //scroll lock
144:RAWKEY_NUMLOCK, //num lock
145:RAWKEY_SCRLOCK, //scroll lock
160:RAWKEY_TILDE,
163:RAWKEY_2B,
171:RAWKEY_RBRACKET,
@ -465,69 +489,69 @@ function Keyboard() {
};
const MAXKEYS = 256;
const KEYBUFSIZE = 512;
const USECAPTURE = false; /* capturing/bubbling phase */
var keyState = new Array(4);
for (var vi = 0; vi < 4; vi++)
keyState[vi] = new Uint8Array(MAXKEYS);
var keyState = new Uint8Array(MAXKEYS);
var keyBuf = new Uint8Array(KEYBUFSIZE);
var state = 0;
var code = 0;
var first = 0, last = 0;
var capsLock = false;
var hsynccnt = 0;
this.lostsynccnt = 0;
//for (var k in KeyEvent) document.writeln('KeyEvent.' + k + ' = ' + KeyEvent[k]+'<br />'); //FF
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
for (var i = 0; i < KEYBUFSIZE; i++) keyBuf[i] = 0;
function keydown(e) { handleKey(e, true); }
function keyup(e) { handleKey(e, false); }
/*function fullscreenchange(e) {
SAEF_log("fullscreenchange()");
}*/
function _onkeydown(e) { AMIGA.input.keyboard.handleKey(e, true); }
function _onkeyup(e) { AMIGA.input.keyboard.handleKey(e, false); }
this.setup = function () {
/*document.onkeydown = function (e) {
AMIGA.input.keyboard.keydownup(e, true);
}
document.onkeyup = function (e) {
AMIGA.input.keyboard.keydownup(e, false);
}*/
window.document.addEventListener('keydown', _onkeydown, false);
window.document.addEventListener('keyup', _onkeyup, false);
this.setup = function() {
if (SAEV_config.keyboard.enabled) {
document.addEventListener("keydown", keydown, USECAPTURE);
document.addEventListener("keyup", keyup, USECAPTURE);
//document.addEventListener("webkitfullscreenchange", fullscreenchange);
}
};
this.cleanup = function () {
//BUG.info('Keyboard.cleanup()');
//document.onkeydown = null;
//document.onkeyup = null;
window.document.removeEventListener('keydown', _onkeydown, false);
window.document.removeEventListener('keyup', _onkeyup, false);
this.cleanup = function() {
if (SAEV_config.keyboard.enabled) {
document.removeEventListener("keydown", keydown, USECAPTURE);
document.removeEventListener("keyup", keyup, USECAPTURE);
//document.removeEventListener("webkitfullscreenchange", fullscreenchange);
}
};
this.reset = function () {
for (var i = 0; i < MAXKEYS; i++) keyState[i] = false;
this.reset = function() {
for (var j = 0; j < keyState.length; j++) {
for (var i = 0; i < keyState[j].length; i++)
keyState[j][i] = 0;
}
state = 0;
code = 0;
first = last = 0;
hsynccnt = 0;
this.lostsynccnt = 0;
};
this.keysAvail = function () {
this.keysAvail = function() {
return first != last;
};
this.nextKey = function () {
//assert (first != last);
this.nextKey = function() {
SAEF_assert(first != last);
var key = keyBuf[last];
if (++last == KEYBUFSIZE) last = 0;
return key;
};
this.recordKey = function (kc) {
function recordKey(kc) {
var next = first + 1;
if (next == KEYBUFSIZE) next = 0;
if (next == last) {
BUG.info('Keyboard() buffer overrun!');
SAEF_warn("imput.recordKey() buffer overrun!");
return false;
}
keyBuf[first] = kc;
@ -535,7 +559,7 @@ function Keyboard() {
return true;
};
this.processKey = function (code, down) {
function processKey(loc, code, down) {
/* Caps-lock */
if (code == 20) {
if (down) {
@ -547,268 +571,184 @@ function Keyboard() {
}
/* joystick emul */
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Joy0) {
var l, u, r, d, f1, f2;
switch (AMIGA.config.ports[0].move) {
case SAEV_Config_Ports_Move_Arrows:
{
switch (SAEV_config.ports[0].move) {
case SAEC_Config_Ports_Move_Arrows:
l = 37;
u = 38;
r = 39;
d = 40;
break;
}
case SAEV_Config_Ports_Move_Numpad:
{
case SAEC_Config_Ports_Move_Numpad:
l = 100;
u = 104;
r = 102;
d = 101;
break;
}
case SAEV_Config_Ports_Move_WASD:
{
case SAEC_Config_Ports_Move_WASD:
l = 65;
u = 87;
r = 68;
d = 83;
break;
}
}
f1 = AMIGA.config.ports[0].fire[0];
f2 = AMIGA.config.ports[0].fire[1];
f1 = SAEV_config.ports[0].fire[0];
f2 = SAEV_config.ports[0].fire[1];
switch (code) {
case f1:
{
AMIGA.input.joystick[0].button[0] = down;
SAER.input.joystick[0].button[0] = down;
break;
}
case f2:
{
AMIGA.input.joystick[0].button[1] = down;
SAER.input.joystick[0].button[1] = down;
break;
case l: {
SAER.input.joystick[0].state[0] = down;
if (down && SAER.input.joystick[0].state[2]) SAER.input.joystick[0].state[2] = false;
break;
}
case l:
{
AMIGA.input.joystick[0].state[0] = down;
if (down && AMIGA.input.joystick[0].state[2]) AMIGA.input.joystick[0].state[2] = false;
case u: {
SAER.input.joystick[0].state[1] = down;
if (down && SAER.input.joystick[0].state[3]) SAER.input.joystick[0].state[3] = false;
break;
}
case u:
{
AMIGA.input.joystick[0].state[1] = down;
if (down && AMIGA.input.joystick[0].state[3]) AMIGA.input.joystick[0].state[3] = false;
case r: {
SAER.input.joystick[0].state[2] = down;
if (down && SAER.input.joystick[0].state[0]) SAER.input.joystick[0].state[0] = false;
break;
}
case r:
{
AMIGA.input.joystick[0].state[2] = down;
if (down && AMIGA.input.joystick[0].state[0]) AMIGA.input.joystick[0].state[0] = false;
break;
}
case d:
{
AMIGA.input.joystick[0].state[3] = down;
if (down && AMIGA.input.joystick[0].state[1]) AMIGA.input.joystick[0].state[1] = false;
case d: {
SAER.input.joystick[0].state[3] = down;
if (down && SAER.input.joystick[0].state[1]) SAER.input.joystick[0].state[1] = false;
break;
}
}
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
if (SAEV_config.ports[1].type == SAEC_Config_Ports_Type_Joy1) {
var l, u, r, d, f1, f2;
switch (AMIGA.config.ports[1].move) {
case SAEV_Config_Ports_Move_Arrows:
{
switch (SAEV_config.ports[1].move) {
case SAEC_Config_Ports_Move_Arrows:
l = 37;
u = 38;
r = 39;
d = 40;
break;
}
case SAEV_Config_Ports_Move_Numpad:
{
case SAEC_Config_Ports_Move_Numpad:
l = 100;
u = 104;
r = 102;
d = 101;
break;
}
case SAEV_Config_Ports_Move_WASD:
{
case SAEC_Config_Ports_Move_WASD:
l = 65;
u = 87;
r = 68;
d = 83;
break;
}
}
f1 = AMIGA.config.ports[1].fire[0];
f2 = AMIGA.config.ports[1].fire[1];
f1 = SAEV_config.ports[1].fire[0];
f2 = SAEV_config.ports[1].fire[1];
switch (code) {
case f1:
{
AMIGA.input.joystick[1].button[0] = down;
SAER.input.joystick[1].button[0] = down;
break;
}
case f2:
{
AMIGA.input.joystick[1].button[1] = down;
SAER.input.joystick[1].button[1] = down;
break;
case l: {
SAER.input.joystick[1].state[0] = down;
if (down && SAER.input.joystick[1].state[2]) SAER.input.joystick[1].state[2] = false;
break;
}
case l:
{
AMIGA.input.joystick[1].state[0] = down;
if (down && AMIGA.input.joystick[1].state[2]) AMIGA.input.joystick[1].state[2] = false;
case u: {
SAER.input.joystick[1].state[1] = down;
if (down && SAER.input.joystick[1].state[3]) SAER.input.joystick[1].state[3] = false;
break;
}
case u:
{
AMIGA.input.joystick[1].state[1] = down;
if (down && AMIGA.input.joystick[1].state[3]) AMIGA.input.joystick[1].state[3] = false;
case r: {
SAER.input.joystick[1].state[2] = down;
if (down && SAER.input.joystick[1].state[0]) SAER.input.joystick[1].state[0] = false;
break;
}
case r:
{
AMIGA.input.joystick[1].state[2] = down;
if (down && AMIGA.input.joystick[1].state[0]) AMIGA.input.joystick[1].state[0] = false;
break;
}
case d:
{
AMIGA.input.joystick[1].state[3] = down;
if (down && AMIGA.input.joystick[1].state[1]) AMIGA.input.joystick[1].state[1] = false;
case d: {
SAER.input.joystick[1].state[3] = down;
if (down && SAER.input.joystick[1].state[1]) SAER.input.joystick[1].state[1] = false;
break;
}
}
}
if (!AMIGA.config.keyboard.enabled)
if (!SAEV_config.keyboard.enabled)
return;
/* map shift-keys (team17 pinball games) */
if (AMIGA.config.keyboard.mapShift) {
switch (code) {
case 37:
{ //left arrow
if (!down) {
this.recordKey((RAWKEY_LSHIFT << 1) | 1);
} else {
this.recordKey(RAWKEY_LSHIFT << 1);
}
//break;
return;
}
case 39:
{ //right arrow
if (!down) {
this.recordKey((RAWKEY_RSHIFT << 1) | 1);
} else {
this.recordKey(RAWKEY_RSHIFT << 1);
}
//break;
return;
}
}
}
var rawkey = false;
if (BrowserDetect.browser == 'Firefox') {
if (typeof(mozKeyCodeMap[code]) != 'undefined')
if (SAEC_info.browser.id == SAEC_Info_Brower_ID_Firefox) {
if (typeof mozKeyCodeMap[code] != "undefined")
rawkey = mozKeyCodeMap[code];
} else {
if (typeof(defKeyCodeMap[code]) != 'undefined')
if (typeof defKeyCodeMap[code] != "undefined")
rawkey = defKeyCodeMap[code];
}
//BUG.info('Keyboard.processKey() code %d $%04x, rawkey $%04x', code, code, rawkey);
if (rawkey !== false) {
switch (rawkey) {
case RAWKEY_LSHIFT: {
if (loc == DOM_KEY_LOCATION_RIGHT) rawkey = RAWKEY_RSHIFT;
break;
}
case RAWKEY_LALT: {
if (loc == DOM_KEY_LOCATION_RIGHT) rawkey = RAWKEY_RALT;
break;
}
/*case RAWKEY_LAMIGA: {
if (loc == DOM_KEY_LOCATION_RIGHT) rawkey = RAWKEY_RAMIGA;
break;
}*/
case RAWKEY_RETURN: {
if (loc == DOM_KEY_LOCATION_NUMPAD) rawkey = RAWKEY_KP_ENTER;
break;
}
}
//if (down) SAEF_log("Keyboard.processKey() loc %d, code %d $%04x, rawkey $%04x", loc, code, code, rawkey);
if (down)
this.recordKey(rawkey << 1);
recordKey(rawkey << 1);
else
this.recordKey((rawkey << 1) | 1);
recordKey((rawkey << 1) | 1);
}
};
this.handleKey = function (e, down) {
function handleKey(e, down) {
e = e || window.event;
var code = e.which ? e.which : e.keyCode;
var code = typeof e.keyCode == "undefined" ? e.which : e.keyCode;
var loc = typeof e.location == "undefined" ? 0 : e.location;
if (AMIGA.config.keyboard.enabled && code != 122 && code != 123) //all but F11 F12
e.preventDefault();
if (code == 122) { //F11
//if (!down) SAER.video.toggle_fullscreen_real(2);
return;
}
if (code == 123) //F12
return;
//BUG.info('Keyboard.handleKey() down %d, code %d, alt %d, shift %d, ctrl %d', down?1:0, code, e.altKey?1:0, e.shiftKey?1:0, e.ctrlKey?1:0);
e.preventDefault();
/* Ctrl-Alt fix */
if (!down && code == 17 && keyState[18]) {
keyState[18] = false;
this.processKey(18, keyState[18]);
}
//SAEF_log("Keyboard.handleKey() down %d, code %d, loc %d, alt %d, shift %d, ctrl %d", down?1:0, code, loc, e.ctrlKey?1:0, e.shiftKey?1:0, e.altKey?1:0, e.metaKey?1:0);
var oldstate = keyState[code];
if (down && !keyState[code]) {
keyState[code] = true;
}
else if (!down) {
keyState[code] = false;
}
if (keyState[code] != oldstate) {
this.processKey(code, keyState[code]);
}
var oldstate = keyState[loc][code];
keyState[loc][code] = down ? 1 : 0;
if (keyState[loc][code] != oldstate)
processKey(loc, code, keyState[loc][code]);
};
this.setCode = function (keycode) {
code = ~((keycode << 1) | (keycode >> 7)) & 0xff;
};
this.keyReq = function () {
this.lostsynccnt = 8 * AMIGA.playfield.maxvpos * 8;
/* 8 frames * 8 bits */
//AMIGA.cia.setICR(CIA_A, 8, code);
AMIGA.cia.SetICRA(8, code);
};
this.hsync = function () {
if ((this.keysAvail() || state < 3) && !this.lostsynccnt && ((++hsynccnt) & 15) == 0) {
switch (state) {
case 0:
code = 0;
state++;
break;
case 1:
this.setCode(RAWKEY_INIT_POWER_UP);
state++;
break;
case 2:
this.setCode(RAWKEY_TERM_POWER_UP);
state++;
break;
case 3:
code = ~this.nextKey() & 0xff;
break;
}
this.keyReq();
}
};
this.vsync = function() {
if (this.lostsynccnt > 0) {
this.lostsynccnt -= AMIGA.playfield.maxvpos;
if (this.lostsynccnt <= 0) {
this.lostsynccnt = 0;
this.keyReq();
//BUG.info('Keyboard() lost sync');
}
}
}
}
function Input() {
this.mouse = new Mouse();
function SAEO_Input() {
this.mouse = new SAEO_Mouse();
this.joystick = new Array(2);
this.joystick[0] = new Joystick(SAEV_Config_Ports_Type_Joy0);
this.joystick[1] = new Joystick(SAEV_Config_Ports_Type_Joy1);
this.keyboard = new Keyboard();
this.joystick[0] = new SAEO_Joystick(SAEC_Config_Ports_Type_Joy0);
this.joystick[1] = new SAEO_Joystick(SAEC_Config_Ports_Type_Joy1);
this.keyboard = new SAEO_Keyboard();
var potgo = {
data: 0,
@ -833,7 +773,7 @@ function Input() {
};
this.POTGO = function (v) {
//BUG.info('Input.POTGO() $%04x', v);
//SAEF_log("Input.POTGO() $%04x", v);
potgo.data = v;
};
@ -841,40 +781,40 @@ function Input() {
var v = (potgo.data | (potgo.data << 1)) & 0xaa00;
v |= v >> 1;
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) v &= 0xfbff;
if (this.mouse.button[1]) v &= 0xfeff;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
} else if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Joy0) {
if (this.joystick[0].button[1]) v &= 0xfbff;
if (this.joystick[0].button[2]) v &= 0xfeff;
}
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
if (SAEV_config.ports[1].type == SAEC_Config_Ports_Type_Joy1) {
if (this.joystick[1].button[1]) v &= 0xbfff;
if (this.joystick[1].button[2]) v &= 0xefff;
}
//BUG.info('Input.POTGOR() $%04x', v);
//SAEF_log("Input.POTGOR() $%04x", v);
return v;
};
this.POT0DAT = function () {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Mouse) {
if (this.mouse.button[2]) potgo.count = (potgo.count & 0xff00) | ((potgo.count + 1) & 0xff);
if (this.mouse.button[1]) potgo.count = (potgo.count + 0x100) & 0xffff;
}
//BUG.info('Input.POT0DAT() $%04x', v);
//SAEF_log("Input.POT0DAT() $%04x", v);
return potgo.count;
};
this.POT1DAT = function () {
//BUG.info('Input.POT1DAT() NOT IMPLEMENTED');
//SAEF_log("Input.POT1DAT() NOT IMPLEMENTED");
return 0xffff;
};
this.JOY0DAT = function () {
if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Mouse) {
if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[0].type == SAEV_Config_Ports_Type_Joy0) {
} else if (SAEV_config.ports[0].type == SAEC_Config_Ports_Type_Joy0) {
this.joystick[0].update();
return this.joystick[0].dir;
}
@ -882,10 +822,10 @@ function Input() {
};
this.JOY1DAT = function () {
if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Mouse) {
if (SAEV_config.ports[1].type == SAEC_Config_Ports_Type_Mouse) {
this.mouse.update();
return this.mouse.pos;
} else if (AMIGA.config.ports[1].type == SAEV_Config_Ports_Type_Joy1) {
} else if (SAEV_config.ports[1].type == SAEC_Config_Ports_Type_Joy1) {
this.joystick[1].update();
return this.joystick[1].dir;
}
@ -893,7 +833,7 @@ function Input() {
};
this.JOYTEST = function (v) {
//BUG.info('Input.JOYTEST() $%04x', v);
//SAEF_log("Input.JOYTEST() $%04x", v);
}
}

519
sae/m68k.js Normal file
View file

@ -0,0 +1,519 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Notes:
| This file consists of two parts: high-level functions, which are ported
| from WinUAE 3.2.x and low-level functions, written from scratch.
-------------------------------------------------------------------------*/
/* global constants */
//const SAEC_CPU_halt_PPC_ONLY = -1;
const SAEC_CPU_halt_BUS_ERROR_DOUBLE_FAULT = 1;
const SAEC_CPU_halt_DOUBLE_FAULT = 2;
const SAEC_CPU_halt_OPCODE_FETCH_FROM_NON_EXISTING_ADDRESS = 3;
//const SAEC_CPU_halt_ACCELERATOR_CPU_FALLBACK = 4;
//const SAEC_CPU_halt_ALL_CPUS_STOPPED = 5;
//const SAEC_CPU_halt_FAKE_DMA = 6;
const SAEC_CPU_halt_AUTOCONFIG_CONFLICT = 7;
//const SAEC_CPU_halt_PCI_CONFLICT = 8;
//const SAEC_CPU_halt_CPU_STUCK = 9;
/*---------------------------------*/
/* global references */
/*---------------------------------*/
/* global variables */
/*---------------------------------*/
function SAEO_M68K() {
var reset_delay = false;
this.halted = 0;
this.stopped = false;
var haltloop_prevvpos = false;
var prevtime = false;
/*-----------------------------------------------------------------------*/
this.setup = function() { //init_m68k()
return SAER.cpu.setup();
}
function m68k_reset(hardreset) { //m68k_reset2
SAEV_spcflags = 0;
SAEF_setSpcFlags(SAEC_spcflag_CHECK);
this.halted = 0;
haltloop_prevvpos = false;
SAER.gui.data.cpu_halted = 0;
SAER.gui.led(SAEC_GUI_LED_CPU, 0, -1);
reset_delay = false;
prevtime = false;
SAER.cpu.reset(hardreset);
//SAER.cpu.diss(regs.pc, 16);
}
this.dump = function() {
//var out = "";
SAER.cpu.dump();
//SAEF_log(out);
}
/*-----------------------------------------------------------------------*/
this.cpureset = function() {
/* RESET hasn"t increased PC yet, 1 word offset */
var ksboot = 0xf80002 - 2;
reset_delay = SAEV_config.cpu.resetDelay;
SAEF_setSpcFlags(SAEC_spcflag_CHECK);
//send_internalevent(INTERNALEVENT_CPURESET);
if (SAEV_config.cpu.compatible && SAEV_config.cpu.model <= SAEC_Config_CPU_Model_68020) {
SAER.playfield.custom_reset(false, false);
return;
}
var pc = SAER_CPU_getPC() + 2;
var bank = SAER_Memory_getBank(pc);
if (bank.check(pc, 2)) {
SAEF_log("cpu.cpureset() PC=%x (%s)...", pc - 2, bank.name);
var ins = SAER_Memory_get16(pc);
SAER.playfield.custom_reset(false, false);
// did memory disappear under us?
if (bank === SAER_Memory_getBank(pc))
return;
// it did
if ((ins & ~7) == 0x4ed0) {
var addr = SAER_CPU_regs.a[ins & 7];
if (addr < 0x80000)
addr += 0xf80000;
SAEF_log("cpu.cpureset() reset/jmp combination at %08x emulated -> %x", pc, addr);
SAER.cpu.setPC_normal(addr - 2);
return;
}
}
SAEF_log("cpu.cpureset() PC=%x (%s), invalid memory -> %x.", pc, bank.name, ksboot + 2);
SAER.playfield.custom_reset(false, false);
SAER.cpu.setPC_normal(ksboot);
}
/*-----------------------------------------------------------------------*/
this.cpu_halt = function(id) {
// id < 0: m68k halted, PPC active.
// id > 0: emulation halted.
if (!this.halted) {
SAEF_log("CPU halted: reason = %d PC=%08x", id, SAER_CPU_getPC());
this.halted = id;
SAER.gui.data.cpu_halted = id;
SAER.gui.led(SAEC_GUI_LED_CPU, 0, -1);
if (id >= 0) {
SAER_CPU_regs.intmask = 7;
SAER_Audio_deactivate();
}
SAEF_setSpcFlags(SAEC_spcflag_CHECK);
}
}
function haltloop() {
while (SAER.m68k.halted) {
//SAEF_log("cpu.haltloop()");
var vpos = SAER.playfield.get_vpos();
if (vpos == 0 && haltloop_prevvpos) {
haltloop_prevvpos = false;
SAEF_sleep(8);
}
if (vpos)
haltloop_prevvpos = true;
SAER.events.do_cycles(8 * SAEC_Events_CYCLE_UNIT);
if (SAEV_spcflags & SAEC_spcflag_COPPER)
SAER.copper.cycle();
if (SAEV_spcflags) {
if ((SAEV_spcflags & (SAEC_spcflag_BRK | SAEC_spcflag_MODE_CHANGE)))
return true;
}
}
return false;
}
/*-----------------------------------------------------------------------*/
var cpu_keyboardreset = false;
var cpu_hardreset = true;
this.is_keyboardreset = function() {
return cpu_keyboardreset;
}
this.is_hardreset = function() {
return cpu_hardreset;
}
this.m68k_pause = function() {
if (SAEV_command == SAEC_command_Pause) {
SAEV_command = 0;
if (!SAER.paused) {
SAEF_log("->pause");
SAER.paused = true;
SAER.pause_program(1);
}
}
else if (SAEV_command == SAEC_command_Resume) {
SAEV_command = 0;
if (SAER.paused) {
SAEF_log("->resume");
SAER.pause_program(0);
SAER.paused = false;
prevtime = false;
}
}
else if (SAEV_command == -SAEC_command_Quit ||
SAEV_command == -SAEC_command_Reset ||
SAEV_command == -SAEC_command_KeyboardReset ||
SAEV_command == -SAEC_command_HardReset
) {
SAEF_log("->stop");
SAER.paused = false;
}
if (SAER.paused)
setTimeout(function() { SAER.m68k.m68k_pause(); }, 500);
else
setTimeout(function() { SAER.m68k.m68k_cycle(0, 0); }, 0);
}
this.m68k_cycle = function(hardboot, startup) {
try {
if (SAEV_command > 0) {
cpu_keyboardreset = SAEV_command == SAEC_command_KeyboardReset;
cpu_hardreset = ((SAEV_command == SAEC_command_HardReset ? 1 : 0) | hardboot) != 0;
if (SAEV_command == SAEC_command_Quit) {
this.m68k_gone();
return;
}
else if (SAEV_command == SAEC_command_Pause) {
this.m68k_pause();
return;
}
SAEV_command = 0;
hardboot = 0;
SAEV_Events_hsync_counter = 0;
SAEV_Events_vsync_counter = 0;
SAEV_Events_currcycle = 0; SAER_Events_eventtab[SAEC_Events_EV_HSYNC].oldcycles = 0;
SAER.playfield.custom_reset(cpu_hardreset, cpu_keyboardreset);
m68k_reset(cpu_hardreset);
if (cpu_hardreset) {
SAER.memory.clear();
SAEF_log("m68k.m68k_cycle() hardreset, memory cleared.");
}
cpu_hardreset = false;
if (SAEV_config.audio.mode == 0)
SAER_Events_eventtab[SAEC_Events_EV_AUDIO].active = false;
SAER.cpu.setPC_normal(SAER_CPU_regs.pc);
//SAER.audio.check_prefs_changed_audio();
//statusline_clear();
}
if (startup) {
SAER.playfield.custom_prepare();
//protect_roms(true);
startup = 0;
}
SAEF_clrSpcFlags(SAEC_spcflag_MODE_CHANGE);
if (this.halted) {
this.cpu_halt(this.halted);
/*if (this.halted < 0) {
haltloop();
//continue;
setTimeout(function() { SAER.m68k.m68k_cycle(hardboot, startup); }, 0);
return;
}*/
}
if (prevtime !== false) // && SAEV_config.cpu.speed >= 0)
SAEV_Events_reflowtime = SAEF_now() - prevtime;
SAER_CPU_run_func();
//if (SAEV_config.cpu.speed >= 0)
prevtime = SAEF_now();
setTimeout(function() { SAER.m68k.m68k_cycle(hardboot, startup); }, 0);
} catch(e) {
this.m68k_gone();
if (e instanceof SAEO_Error) {
if (typeof SAEV_config.hook.log.error === "function")
SAEV_config.hook.log.error(e.err, e.msg);
else
alert(e.msg);
} else
throw e;
}
}
this.m68k_go = function(may_quit) {
var hardboot = 1;
var startup = 1;
//SAEF_info("m68k.m68k_go()");
SAER.events.reset_frame_rate_hack();
SAER.running = true;
//this.m68k_cycle(1, 1);
setTimeout(function() { SAER.m68k.m68k_cycle(hardboot, startup); }, 0);
}
this.m68k_gone = function() {
//SAEF_info("m68k.m68k_gone()");
//protect_roms(false);
SAER.running = false;
SAER.leave_program();
}
/*-----------------------------------------------------------------------*/
this.m68k_setstopped = function() {
this.stopped = true;
/* A traced STOP instruction drops through immediately without actually stopping. */
if ((SAEV_spcflags & SAEC_spcflag_DOTRACE) == 0)
SAEF_setSpcFlags(SAEC_spcflag_STOP);
else
this.m68k_resumestopped();
}
this.m68k_resumestopped = function() {
if (this.stopped) {
this.stopped = false;
SAER_CPU_fill_prefetch();
SAEF_clrSpcFlags(SAEC_spcflag_STOP);
}
}
/*-----------------------------------------------------------------------*/
this.doint = function() {
if (SAEV_config.cpu.compatible && SAEV_config.cpu.model < SAEC_Config_CPU_Model_68020)
SAEF_setSpcFlags(SAEC_spcflag_INT);
else
SAEF_setSpcFlags(SAEC_spcflag_DOINT);
}
this.doint_trace = function(t) { //OWN cpu.setSR()
//this.doint();
if (SAEV_config.cpu.compatible && SAEV_config.cpu.model < SAEC_Config_CPU_Model_68020)
SAEF_setSpcFlags(SAEC_spcflag_INT);
else
SAEF_setSpcFlags(SAEC_spcflag_DOINT);
if (t)
SAEF_setSpcFlags(SAEC_spcflag_TRACE);
else
SAEF_clrSpcFlags(SAEC_spcflag_TRACE);
}
/*-----------------------------------------------------------------------*/
function do_interrupt(nr) {
this.stopped = false;
SAEF_clrSpcFlags (SAEC_spcflag_STOP);
SAEF_assert(nr < 8 && nr >= 0);
for (;;) {
SAER_CPU_exception(nr + 24);
SAER_CPU_regs.intmask = nr;
if (!SAEV_config.cpu.compatible)
break;
nr = SAER.custom.intlev();
if (nr <= 0 || SAER_CPU_regs.intmask >= nr)
break;
}
SAER.m68k.doint();
}
/*this.NMI = function() {
do_interrupt(7);
}*/
//static uaecptr last_trace_ad = 0;
function do_trace() {
if (SAER_CPU_regs.t0 && SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) {
/* should also include TRAP, CHK, SR modification FPcc */
/* probably never used so why bother */
/* We can afford this to be inefficient... */
SAER.cpu.setPC_normal(SAER_CPU_getPC());
SAER_CPU_fill_prefetch();
var opcode = SAER_Memory_get16(SAER_CPU_regs.pc);
if (opcode == 0x4e73 /* RTE */
|| opcode == 0x4e74 /* RTD */
|| opcode == 0x4e75 /* RTS */
|| opcode == 0x4e77 /* RTR */
|| opcode == 0x4e76 /* TRAPV */
|| (opcode & 0xffc0) == 0x4e80 /* JSR */
|| (opcode & 0xffc0) == 0x4ec0 /* JMP */
|| (opcode & 0xff00) == 0x6100 /* BSR */
|| ((opcode & 0xf000) == 0x6000 && ccTab[(opcode >> 8) & 0xf]()) /* Bcc */
|| ((opcode & 0xf0f0) == 0x5050 && !ccTab[(opcode >> 8) & 0xf]() && SAER_CPU_regs.d[opcode & 7] & 0xffff != 0) /* DBcc */
) {
//last_trace_ad = SAER_CPU_getPC();
SAEF_clrSpcFlags(SAEC_spcflag_TRACE);
SAEF_setSpcFlags(SAEC_spcflag_DOTRACE);
}
} else if (SAER_CPU_regs.t1) {
//last_trace_ad = SAER_CPU_getPC();
SAEF_clrSpcFlags(SAEC_spcflag_TRACE);
SAEF_setSpcFlags(SAEC_spcflag_DOTRACE);
}
}
this.do_specialties = function(cycles) {
if (SAEV_spcflags & SAEC_spcflag_MODE_CHANGE)
return true;
if (SAEV_spcflags & SAEC_spcflag_CHECK) {
if (this.halted) {
SAEF_clrSpcFlags(SAEC_spcflag_CHECK);
if (haltloop())
return true;
}
if (reset_delay) {
var vsynccnt = 60;
var vsyncstate = -1;
while (vsynccnt > 0 && SAEV_command == 0) {
SAER.events.do_cycles(8 * SAEC_Events_CYCLE_UNIT);
if (SAEV_spcflags & SAEC_spcflag_COPPER)
SAER.copper.cycle();
if (SAEV_Events_timeframes != vsyncstate) {
vsyncstate = SAEV_Events_timeframes;
vsynccnt--;
}
}
reset_delay = false;
}
SAEF_clrSpcFlags(SAEC_spcflag_CHECK);
}
/*#ifdef ACTION_REPLAY
#ifdef ACTION_REPLAY_HRTMON
if ((SAEV_spcflags & SAEC_spcflag_ACTION_REPLAY) && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
int isinhrt = (SAER_CPU_getPC() >= hrtmem_start && SAER_CPU_getPC() < hrtmem_start + hrtmem_size);
if (hrtmon_flag == ACTION_REPLAY_ACTIVE && !isinhrt)
hrtmon_hide ();
if (hrtmon_flag == ACTION_REPLAY_IDLE && isinhrt)
hrtmon_breakenter ();
if (hrtmon_flag == ACTION_REPLAY_ACTIVATE)
hrtmon_enter ();
}
#endif
if ((SAEV_spcflags & SAEC_spcflag_ACTION_REPLAY) && action_replay_flag != ACTION_REPLAY_INACTIVE) {
if (action_replay_flag == ACTION_REPLAY_ACTIVE && !is_ar_pc_in_rom ())
SAEF_log("PC:%p", SAER_CPU_getPC());
if (action_replay_flag == ACTION_REPLAY_ACTIVATE || action_replay_flag == ACTION_REPLAY_DORESET)
action_replay_enter ();
if ((action_replay_flag == ACTION_REPLAY_HIDE || action_replay_flag == ACTION_REPLAY_ACTIVE) && !is_ar_pc_in_rom ()) {
action_replay_hide ();
SAEF_clrSpcFlags (SAEC_spcflag_ACTION_REPLAY);
}
if (action_replay_flag == ACTION_REPLAY_WAIT_PC) {
SAEF_log("Waiting for PC: %p, current PC= %p", wait_for_pc, SAER_CPU_getPC());
if (SAER_CPU_getPC() == wait_for_pc) {
action_replay_flag = ACTION_REPLAY_ACTIVATE;
}
}
}
#endif*/
if (SAEV_spcflags & SAEC_spcflag_COPPER)
SAER.copper.cycle();
while ((SAEV_spcflags & SAEC_spcflag_BLTNASTY) && SAEF_Custom_dmaen(SAEC_Custom_DMAF_BLTEN) && cycles > 0 && !SAEV_config.chipset.blitter.cycle_exact) {
var c = SAER.blitter.blitnasty();
if (c < 0)
break;
else if (c > 0) {
cycles -= c * SAEC_Events_CYCLE_UNIT * 2;
if (cycles < SAEC_Events_CYCLE_UNIT)
cycles = 0;
} else
c = 4;
SAER.events.do_cycles(c * SAEC_Events_CYCLE_UNIT);
if (SAEV_spcflags & SAEC_spcflag_COPPER)
SAER.copper.cycle();
}
if (SAEV_spcflags & SAEC_spcflag_DOTRACE)
SAER_CPU_exception(9);
/*if (SAEV_spcflags & SAEC_spcflag_TRAP) {
SAEF_clrSpcFlags(SAEC_spcflag_TRAP);
SAER_CPU_exception(3);
}*/
var first = true;
while ((SAEV_spcflags & SAEC_spcflag_STOP) && !(SAEV_spcflags & SAEC_spcflag_BRK)) {
if (!first) SAER.events.do_cycles(4 * SAEC_Events_CYCLE_UNIT);
first = false;
if (SAEV_spcflags & SAEC_spcflag_COPPER)
SAER.copper.cycle();
if (SAEV_spcflags & (SAEC_spcflag_INT | SAEC_spcflag_DOINT)) {
var intr = SAER.custom.intlev();
SAEF_clrSpcFlags(SAEC_spcflag_INT | SAEC_spcflag_DOINT);
if (intr > 0 && intr > SAER_CPU_regs.intmask)
do_interrupt(intr);
}
if (SAEV_spcflags & SAEC_spcflag_MODE_CHANGE) {
this.m68k_resumestopped();
return true;
}
}
if (SAEV_spcflags & SAEC_spcflag_TRACE)
do_trace();
if (SAEV_spcflags & SAEC_spcflag_INT) {
var intr = SAER.custom.intlev();
SAEF_clrSpcFlags(SAEC_spcflag_INT | SAEC_spcflag_DOINT);
if (intr > 0 && (intr > SAER_CPU_regs.intmask || intr == 7))
do_interrupt(intr);
}
if (SAEV_spcflags & SAEC_spcflag_DOINT) {
SAEF_clrSpcFlags(SAEC_spcflag_DOINT);
SAEF_setSpcFlags(SAEC_spcflag_INT);
}
if (SAEV_spcflags & SAEC_spcflag_BRK) {
SAEF_clrSpcFlags(SAEC_spcflag_BRK);
return true; //OWN
}
return false;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

78
sae/prototypes.js vendored Normal file
View file

@ -0,0 +1,78 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
-------------------------------------------------------------------------*/
/* Object */
if (!Object.prototype.clone) {
Object.prototype.clone = function() {
var copy = {}; //this.constructor();
for (var attr in this) {
if (this.hasOwnProperty(attr))
copy[attr] = this[attr];
}
return copy;
};
}
/*-----------------------------------------------------------------------*/
/* Math */
if (!Math.truncate) {
Math.truncate = function(v) {
if (v > 0)
return this.floor(v);
else if (v < 0)
return this.ceil(v);
return 0;
};
}
if (!Math.decimalRandom) {
Math.decimalRandom = function() {
//var l = 0, u = 0xffffffff; return this.floor((this.random() * (u - l + 1)) + l);
return (this.random() * 0xffffffff) >>> 0;
};
}
/*-----------------------------------------------------------------------*/
/* Date/Performance */
if (!Date.now) {
console.warn("This browser does not support 'Date.now()'. Falling back to 'Date.getTime()'...");
/* milliseconds since 1 January 1970 00:00:00 UTC */
Date.now = function() {
return new Date().getTime();
};
}
if (!window.performance) {
console.warn("This browser does not support 'window.performance'. Falling back to 'Date'...");
window.performance = {};
}
if (!performance.timing) {
performance.timing = {
navigationStart: Date.now()
};
}
if (!performance.now) {
if (performance.webkitNow)
performance.now = performance.webkitNow;
else
performance.now = function() {
return Date.now() - this.timing.navigationStart;
};
}

723
sae/roms.js Normal file
View file

@ -0,0 +1,723 @@
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: ported from WinUAE 3.2.x
-------------------------------------------------------------------------*/
/* global constants */
//const SAEC_RomType_SUB_MASK = 0x000000ff;
//const SAEC_RomType_GROUP_MASK = 0x003fff00;
//const SAEC_RomType_MASK = 0x003fffff;
const SAEC_RomType_KICK = 0x00000100;
const SAEC_RomType_KICKCD32 = 0x00000200;
const SAEC_RomType_EXTCD32 = 0x00000400;
const SAEC_RomType_EXTCDTV = 0x00000800;
const SAEC_RomType_KEY = 0x00001000;
//const SAEC_RomType_ARCADIABIOS = 0x00002000;
//const SAEC_RomType_ARCADIAGAME = 0x00004000;
const SAEC_RomType_CD32CART = 0x00008000;
//const SAEC_RomType_SPECIALKICK = 0x00010000;
/*const SAEC_RomType_CPUBOARD 0x00040000
const SAEC_RomType_CB_A3001S1 0x00040001
const SAEC_RomType_CB_APOLLO 0x00040002
const SAEC_RomType_CB_FUSION 0x00040003
const SAEC_RomType_CB_DKB12x0 0x00040004
const SAEC_RomType_CB_WENGINE 0x00040005
const SAEC_RomType_CB_TEKMAGIC 0x00040006
const SAEC_RomType_CB_BLIZ1230 0x00040007
const SAEC_RomType_CB_BLIZ1260 0x00040008
const SAEC_RomType_CB_BLIZ2060 0x00040009
const SAEC_RomType_CB_A26x0 0x0004000a
const SAEC_RomType_CB_CSMK1 0x0004000b
const SAEC_RomType_CB_CSMK2 0x0004000c
const SAEC_RomType_CB_CSMK3 0x0004000d
const SAEC_RomType_CB_CSPPC 0x0004000e
const SAEC_RomType_CB_BLIZPPC 0x0004000f
const SAEC_RomType_CB_GOLEM030 0x00040010
const SAEC_RomType_CB_ACA500 0x00040011
const SAEC_RomType_CB_DBK_WF 0x00040012
const SAEC_RomType_CB_EMATRIX 0x00040013
const SAEC_RomType_CB_SX32PRO 0x00040014
const SAEC_RomType_FREEZER 0x00080000
const SAEC_RomType_AR 0x00080001
const SAEC_RomType_AR2 0x00080002
const SAEC_RomType_HRTMON 0x00080003
const SAEC_RomType_NORDIC 0x00080004
const SAEC_RomType_XPOWER 0x00080005
const SAEC_RomType_SUPERIV 0x00080006
const SAEC_RomType_SCSI 0x00100000
const SAEC_RomType_A2091 0x00100001
const SAEC_RomType_A4091 0x00100002
const SAEC_RomType_BLIZKIT4 0x00100003
const SAEC_RomType_FASTLANE 0x00100004
const SAEC_RomType_OKTAGON 0x00100005
const SAEC_RomType_GVPS1 0x00100006
const SAEC_RomType_GVPS12 0x00100007
const SAEC_RomType_GVPS2 0x00100008*/
const SAEC_RomType_AMAX = 0x00100009;
/*const SAEC_RomType_ALFA 0x0010000a
const SAEC_RomType_ALFAPLUS 0x0010000b
const SAEC_RomType_APOLLO 0x0010000c
const SAEC_RomType_MASOBOSHI 0x0010000d
const SAEC_RomType_SUPRA 0x0010000e
const SAEC_RomType_A2090 0x0010000f
const SAEC_RomType_GOLEM 0x00100010
const SAEC_RomType_STARDRIVE 0x00100011
const SAEC_RomType_KOMMOS 0x00100012
const SAEC_RomType_VECTOR 0x00100013
const SAEC_RomType_ADIDE 0x00100014
const SAEC_RomType_MTEC 0x00100015
const SAEC_RomType_PROTAR 0x00100016
const SAEC_RomType_ADD500 0x00100017
const SAEC_RomType_KRONOS 0x00100018
const SAEC_RomType_ADSCSI 0x00100019
const SAEC_RomType_ROCHARD 0x0010001a
const SAEC_RomType_CLTDSCSI 0x0010001b
const SAEC_RomType_PTNEXUS 0x0010001c
const SAEC_RomType_DATAFLYER 0x0010001d
const SAEC_RomType_SUPRADMA 0x0010001e
const SAEC_RomType_GREX 0x0010001f
const SAEC_RomType_PROMETHEUS 0x00100020
const SAEC_RomType_MEDIATOR 0x00100021
const SAEC_RomType_TECMAR 0x00100022
const SAEC_RomType_XEBEC 0x00100023
const SAEC_RomType_MICROFORGE 0x00100024
const SAEC_RomType_PARADOX 0x00100025
const SAEC_RomType_HDA506 0x00100026
const SAEC_RomType_ALF1 0x00100027
const SAEC_RomType_PROMIGOS 0x00100028
const SAEC_RomType_SYSTEM2000 0x00100029
const SAEC_RomType_A1060 0x0010002a
const SAEC_RomType_A2088 0x0010002b
const SAEC_RomType_A2088T 0x0010002c
const SAEC_RomType_A2286 0x0010002d
const SAEC_RomType_A2386 0x0010002e
const SAEC_RomType_OMTIADAPTER 0x0010002f
const SAEC_RomType_X86_HD 0x00100030
const SAEC_RomType_X86_AT_HD1 0x00100031
const SAEC_RomType_X86_AT_HD2 0x00100032
const SAEC_RomType_X86_XT_IDE 0x00100033
const SAEC_RomType_PICASSOIV 0x00100034
const SAEC_RomType_x86_VGA 0x00100035
const SAEC_RomType_APOLLOHD 0x00100036
const SAEC_RomType_MEVOLUTION 0x00100037
const SAEC_RomType_GOLEMFAST 0x00100038
const SAEC_RomType_PHOENIXB 0x00100039*/
const SAEC_RomType_NOT = 0x00800000;
const SAEC_RomType_QUAD = 0x01000000;
const SAEC_RomType_EVEN = 0x02000000;
const SAEC_RomType_ODD = 0x04000000;
const SAEC_RomType_8BIT = 0x08000000;
const SAEC_RomType_BYTESWAP = 0x10000000;
const SAEC_RomType_CD32 = 0x20000000;
const SAEC_RomType_SCRAMBLED = 0x40000000;
const SAEC_RomType_NONE = 0x80000000;
const SAEC_RomType_ALL_KICK = (SAEC_RomType_KICK | SAEC_RomType_KICKCD32 | SAEC_RomType_CD32) >>> 0;
const SAEC_RomType_ALL_EXT = (SAEC_RomType_EXTCD32 | SAEC_RomType_EXTCDTV) >>> 0;
//const SAEC_RomType_ALL_CART = (SAEC_RomType_AR | SAEC_RomType_HRTMON | SAEC_RomType_NORDIC | SAEC_RomType_XPOWER | SAEC_RomType_CD32CART) >>> 0;
const SAEC_RomType_ALL_CART = (SAEC_RomType_CD32CART) >>> 0;
/*---------------------------------*/
/* global object */
function SAEO_RomInfo() { //struct rominfo
this.name = 0;
this.models = "";
this.ver = 0;
this.rev = 0;
this.subVer = 0;
this.subRev = 0;
this.cpu = 0;
this.cpuExact = false;
this.addressSpace24 = false;
this.cloanto = false;
this.type = 0;
this.partNumber = "";
this.crc32 = 0;
this.checksum = false; /* false = checksum is not available */
this.checksumValid = false; /* false = checksum is not available */
}
/*---------------------------------*/
function SAEO_Roms() {
const K1024 = 1048576;
const K512 = 524288;
const K256 = 262144;
const K128 = 131072;
const K64 = 65536;
function romdata(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p1,p2,p3,p4,p5,q,r) {
this.num = -1;
this.name = a;
this.ver = b;
this.rev = c;
this.subver = d;
this.subrev = e;
this.model = f;
this.size = g; //u32
this.id = h;
this.cpu = i;
this.cloanto = j;
this.type = k;
this.group = l;
this.title = m;
this.partnumber = n;
this.crc32 = o; //u32
this.sha1 = [p1,p2,p3,p4,p5]; //u32
this.configname = typeof q == "undefined" ? "" : q;
this.defaultfilename = typeof r == "undefined" ? "" : r;
}
//const ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) { "X", 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, null, crc32, a, b, c, d, e },
//const ALTROMPN(id,grp,num,size,flags,pn,crc32,a,b,c,d,e) { "X", 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, pn, crc32, a, b, c, d, e },
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p1,p2,p3,p4,p5, q,r
function ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) {
return new romdata("X", 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, "", "", crc32, a, b, c, d, e);
}
function ALTROMPN(id,grp,num,size,flags,pn,crc32,a,b,c,d,e) {
return new romdata("X", 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, "", pn, crc32, a, b, c, d, e);
}
const roms = [
//new romdata("AROS KS ROM (built-in)", 0, 0, 0, 0, "AROS", K512 * 2, 66, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xffffffff, 0, 0, 0, 0, 0, "AROS"),
new romdata("AROS KS ROM (built-in)", 0, 0, 0, 0, "AROS", K512, 66, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xE8A40832, 0, 0, 0, 0, 0, "AROS"),
new romdata("AROS extended ROM (built-in)", 0, 0, 0, 0, "AROS", K512, 66, 0, 0, 0, 0, "", "", 0x5C39D820, 0, 0, 0, 0, 0, "AROS"),
//new romdata("ROM Disabled", 0, 0, 0, 0, "NOROM", 0, 87, 0, 0, SAEC_RomType_NONE, 0, "", "", 0xffffffff, 0, 0, 0, 0, 0, "NOROM"),
//new romdata("Enabled", 0, 0, 0, 0, "ENABLED", 0, 142, 0, 0, SAEC_RomType_NOT, 0, "", "", 0xffffffff, 0, 0, 0, 0, 0, "ENABLED"),
new romdata("Cloanto Amiga Forever ROM key", 0, 0, 0, 0, "", 2069, 0, 0, 1, SAEC_RomType_KEY, 0, "", "", 0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874),
new romdata("Cloanto Amiga Forever 2006 ROM key", 0, 0, 0, 0, "", 750, 48, 0, 1, SAEC_RomType_KEY, 0, "", "", 0xb01c4b56, 0xbba8e5cd,0x118b8d92,0xafed5693,0x5eeb9770,0x2a662d8f),
new romdata("Cloanto Amiga Forever 2010 ROM key", 0, 0, 0, 0, "", 1544, 73, 0, 1, SAEC_RomType_KEY, 0, "", "", 0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4),
new romdata("KS ROM Velvet 23.93", 23, 93, 23, 93, "VELVET", K128, 125, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c),
ALTROMPN(125, 1, 1, 32768, SAEC_RomType_QUAD | SAEC_RomType_EVEN | SAEC_RomType_8BIT, "", 0x1d988ab8, 0xee3988a2,0xb2693334,0x0239d1d9,0xf50d4fb3,0xe0daf3bc),
ALTROMPN(125, 1, 2, 32768, SAEC_RomType_QUAD | SAEC_RomType_ODD | SAEC_RomType_8BIT, "", 0xe466b28f, 0x3e197d69,0xcffa3e1a,0x0c291d57,0xb53f7d1f,0xcb858cf7),
ALTROMPN(125, 1, 3, 32768, SAEC_RomType_QUAD | SAEC_RomType_EVEN | SAEC_RomType_8BIT, "", 0x715988a9, 0x08c36600,0x3948c4c5,0x4216ef8c,0x17ebe16c,0xc91d3b7a),
ALTROMPN(125, 1, 4, 32768, SAEC_RomType_QUAD | SAEC_RomType_ODD | SAEC_RomType_8BIT, "", 0xc4dc7e6a, 0x66b231d0,0x8425c858,0xdfcd36d2,0xd38a0df8,0x518e06a4),
new romdata("KS ROM v1.0 (A1000)(NTSC)", 1, 0, 1, 0, "A1000", K256, 1, 0, 0, SAEC_RomType_KICK, 0, "", "", 0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79),
new romdata("KS ROM v1.1 (A1000)(NTSC)", 1, 1, 31, 34, "A1000", K256, 2, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xd060572a, 0x4192C505,0xD130F446,0xB2ADA6BD,0xC91DAE73,0x0ACAFB4C),
new romdata("KS ROM v1.1 (A1000)(PAL)", 1, 1, 31, 34, "A1000", K256, 3, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xec86dae2, 0x16DF8B5F,0xD524C5A1,0xC7584B24,0x57AC15AF,0xF9E3AD6D),
new romdata("KS ROM v1.2 (A1000)", 1, 2, 33, 166, "A1000", K256, 4, 0, 0, SAEC_RomType_KICK, 0, "", "", 0x9ed783d0, 0x6A7BFB5D,0xBD6B8F17,0x9F03DA84,0xD8D95282,0x67B6273B),
new romdata("KS ROM v1.2 (A500,A1000,A2000)", 1, 2, 33, 180, "A500|A1000|A2000", K256, 5, 0, 0, SAEC_RomType_KICK, 0, "", "315093-01", 0xa6ce1636, 0x11F9E62C,0xF299F721,0x84835B7B,0x2A70A163,0x33FC0D88),
new romdata("KS ROM v1.3 (A500,A1000,A2000)", 1, 3, 34, 5, "A500|A1000|A2000", K256, 6, 0, 0, SAEC_RomType_KICK, 0, "", "315093-02", 0xc4f0f55f, 0x891E9A54,0x7772FE0C,0x6C19B610,0xBAF8BC4E,0xA7FCB785),
new romdata("KS ROM v1.3 (A3000)(SK)", 1, 3, 34, 5, "A3000", K256, 32, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xe0f37258, 0xC39BD909,0x4D4E5F4E,0x28C1411F,0x30869504,0x06062E87),
new romdata("KS ROM v1.4 (A3000)", 1, 4, 36, 16, "A3000", K512, 59, 3, 0, SAEC_RomType_KICK, 0, "", "", 0xbc0ec13f, 0xF76316BF,0x36DFF14B,0x20FA349E,0xD02E4B11,0xDD932B07),
ALTROMPN(59, 1, 1, K256, SAEC_RomType_EVEN, "390629-02", 0x58327536, 0xd1713d7f,0x31474a59,0x48e6d488,0xe3368606,0x1cf3d1e2),
ALTROMPN(59, 1, 2, K256, SAEC_RomType_ODD , "390630-02", 0xfe2f7fb9, 0xc05c9c52,0xd014c66f,0x9019152b,0x3f2a2adc,0x2c678794),
new romdata("KS ROM v2.04 (A500+)", 2, 4, 37, 175, "A500+", K512, 7, 0, 0, SAEC_RomType_KICK, 0, "", "390979-01", 0xc3bdb240, 0xC5839F5C,0xB98A7A89,0x47065C3E,0xD2F14F5F,0x42E334A1),
new romdata("KS ROM v2.05 (A600)", 2, 5, 37, 299, "A600", K512, 8, 0, 0, SAEC_RomType_KICK, 0, "", "391388-01", 0x83028fb5, 0x87508DE8,0x34DC7EB4,0x7359CEDE,0x72D2E3C8,0xA2E5D8DB),
new romdata("KS ROM v2.05 (A600HD)", 2, 5, 37, 300, "A600HD|A600", K512, 9, 0, 0, SAEC_RomType_KICK, 0, "", "391304-01", 0x64466c2a, 0xF72D8914,0x8DAC39C6,0x96E30B10,0x859EBC85,0x9226637B),
new romdata("KS ROM v2.05 (A600HD)", 2, 5, 37, 350, "A600HD|A600", K512, 10, 0, 0, SAEC_RomType_KICK, 0, "", "391304-02", 0x43b0df7b, 0x02843C42,0x53BBD29A,0xBA535B0A,0xA3BD9A85,0x034ECDE4),
new romdata("KS ROM v2.04 (A3000)", 2, 4, 37, 175, "A3000", K512, 71, 8, 0, SAEC_RomType_KICK, 0, "", "", 0x234a7233, 0xd82ebb59,0xafc53540,0xddf2d718,0x7ecf239b,0x7ea91590),
ALTROMPN(71, 1, 1, K256, SAEC_RomType_EVEN, "390629-03", 0xa245dbdf, 0x83bab8e9,0x5d378b55,0xb0c6ae65,0x61385a96,0xf638598f),
ALTROMPN(71, 1, 2, K256, SAEC_RomType_ODD , "390630-03", 0x7db1332b, 0x48f14b31,0x279da675,0x7848df6f,0xeb531881,0x8f8f576c),
new romdata("KS ROM v3.0 (A1200)", 3, 0, 39, 106, "A1200", K512, 11, 0, 0, SAEC_RomType_KICK, 0, "", "", 0x6c9b07d2, 0x70033828,0x182FFFC7,0xED106E53,0x73A8B89D,0xDA76FAA5),
ALTROMPN(11, 1, 1, K256, SAEC_RomType_EVEN, "391523-01", 0xc742a412, 0x999eb81c,0x65dfd07a,0x71ee1931,0x5d99c7eb,0x858ab186),
ALTROMPN(11, 1, 2, K256, SAEC_RomType_ODD , "391524-01", 0xd55c6ec6, 0x3341108d,0x3a402882,0xb5ef9d3b,0x242cbf3c,0x8ab1a3e9),
new romdata("KS ROM v3.0 (A4000)", 3, 0, 39, 106, "A4000", K512, 12, 2 | 4, 0, SAEC_RomType_KICK, 0, "", "", 0x9e6ac152, 0xF0B4E9E2,0x9E12218C,0x2D5BD702,0x0E4E7852,0x97D91FD7),
ALTROMPN(12, 1, 1, K256, SAEC_RomType_EVEN, "391513-02", 0x36f64dd0, 0x196e9f3f,0x9cad934e,0x181c07da,0x33083b1f,0x0a3c702f),
ALTROMPN(12, 1, 2, K256, SAEC_RomType_ODD , "391514-02", 0x17266a55, 0x42fbed34,0x53d1f11c,0xcbde89a9,0x826f2d11,0x75cca5cc),
new romdata("KS ROM v3.1 (A4000)", 3, 1, 40, 70, "A4000", K512, 13, 2 | 4, 0, SAEC_RomType_KICK, 0, "", "", 0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c),
ALTROM(13, 1, 1, K256, SAEC_RomType_EVEN, 0xf9cbecc9, 0x138d8cb4,0x3b8312fe,0x16d69070,0xde607469,0xb3d4078e),
ALTROM(13, 1, 2, K256, SAEC_RomType_ODD , 0xf8248355, 0xc2379547,0x9fae3910,0xc185512c,0xa268b82f,0x1ae4fe05),
new romdata("KS ROM v3.1 (A500,A600,A2000)", 3, 1, 40, 63, "A500|A600|A2000", K512, 14, 0, 0, SAEC_RomType_KICK, 0, "", "", 0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA),
new romdata("KS ROM v3.1 (A1200)", 3, 1, 40, 68, "A1200", K512, 15, 1, 0, SAEC_RomType_KICK, 0, "", "", 0x1483a091, 0xE2154572,0x3FE8374E,0x91342617,0x604F1B3D,0x703094F1),
ALTROMPN(15, 1, 1, K256, SAEC_RomType_EVEN, "391773-01", 0x08dbf275,0xb8800f5f,0x90929810,0x9ea69690,0xb1b8523f,0xa22ddb37),
ALTROMPN(15, 1, 2, K256, SAEC_RomType_ODD , "391774-01", 0x16c07bf8,0x90e331be,0x1970b0e5,0x3f53a9b0,0x390b51b5,0x9b3869c2),
new romdata("KS ROM v3.1 (A3000)", 3, 1, 40, 68, "A3000", K512, 61, 2, 0, SAEC_RomType_KICK, 0, "", "", 0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE),
ALTROM(61, 1, 1, K256, SAEC_RomType_EVEN, 0x286b9a0d, 0x6763a225,0x8ec493f7,0x408cf663,0x110dae9a,0x17803ad1),
ALTROM(61, 1, 2, K256, SAEC_RomType_ODD , 0x0b8cde6a, 0x5f02e97b,0x48ebbba8,0x7d516a56,0xb0400c6f,0xc3434d8d),
new romdata("KS ROM v3.1 (A4000)(Cloanto)", 3, 1, 40, 68, "A4000", K512, 31, 2 | 4, 1, SAEC_RomType_KICK, 0, "", "", 0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9),
new romdata("KS ROM v3.1 (A4000)", 3, 1, 40, 68, "A4000", K512, 16, 2 | 4, 0, SAEC_RomType_KICK, 0, "", "", 0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49),
ALTROM(16, 1, 1, K256, SAEC_RomType_EVEN, 0xb2af34f8, 0x24e52b5e,0xfc020495,0x17387ab7,0xb1a1475f,0xc540350e),
ALTROM(16, 1, 2, K256, SAEC_RomType_ODD , 0xe65636a3, 0x313c7cbd,0xa5779e56,0xf19a41d3,0x4e760f51,0x7626d882),
new romdata("KS ROM v3.1 (A4000T)", 3, 1, 40, 70, "A4000T", K512, 17, 2 | 4, 0, SAEC_RomType_KICK, 0, "", "", 0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21),
ALTROMPN(17, 1, 1, K256, SAEC_RomType_EVEN, "391657-01", 0x0ca94f70, 0xb3806eda,0xcb3362fc,0x16a154ce,0x1eeec5bf,0x5bc24789),
ALTROMPN(17, 1, 2, K256, SAEC_RomType_ODD , "391658-01", 0xdfe03120, 0xcd7a706c,0x431b04d8,0x7814d3a2,0xd8b39710,0x0cf44c0c),
new romdata("KS ROM v3.X (A4000)(Cloanto)", 3, 10, 45, 57, "A4000", K512, 46, 2 | 4, 1, SAEC_RomType_KICK, 0, "", "", 0x3ac99edc, 0x3cbfc9e1,0xfe396360,0x157bd161,0xde74fc90,0x1abee7ec),
new romdata("CD32 KS ROM v3.1", 3, 1, 40, 60, "CD32", K512, 18, 1, 0, SAEC_RomType_KICKCD32, 0, "", "", 0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D),
new romdata("CD32 extended ROM", 3, 1, 40, 60, "CD32", K512, 19, 1, 0, SAEC_RomType_EXTCD32, 0, "", "", 0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F),
//plain CD32 rom
new romdata("CD32 ROM (KS + extended)", 3, 1, 40, 60, "CD32", K1024, 64, 1, 0, SAEC_RomType_KICKCD32 | SAEC_RomType_EXTCD32 | SAEC_RomType_CD32, 0, "", "", 0xf5d4f3c8, 0x9fa14825,0xc40a2475,0xa2eba5cf,0x325bd483,0xc447e7c1),
//real CD32 rom dump 391640-03
ALTROMPN(64, 1, 1, K1024, SAEC_RomType_CD32, "391640-03", 0xa4fbc94a, 0x816ce6c5,0x07787585,0x0c7d4345,0x2230a9ba,0x3a2902db),
new romdata("CD32 Full Motion Video Cartridge ROM", 3, 1, 40, 30, "CD32FMV", K256, 23, 1, 0, SAEC_RomType_CD32CART, 0, "", "", 0xc35c37bf, 0x03ca81c7,0xa7b259cf,0x64bc9582,0x863eca0f,0x6529f435),
new romdata("CD32 Full Motion Video Cartridge ROM", 3, 1, 40, 22, "CD32FMV", K256, 74, 1, 0, SAEC_RomType_CD32CART, 0, "", "391777-01", 0xf11158eb, 0x94e469a7,0x6030dcb2,0x99ebc752,0x0aaeef9d,0xb54284cf),
new romdata("CDTV extended ROM v1.00", 1, 0, 1, 0, "CDTV", K256, 20, 0, 0, SAEC_RomType_EXTCDTV, 0, "", "", 0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE),
ALTROMPN(20, 1, 1, K128, SAEC_RomType_EVEN | SAEC_RomType_8BIT, "252606-01", 0x791cb14b, 0x277a1778,0x92449635,0x3ffe56be,0x68063d2a,0x334360e4),
ALTROMPN(20, 1, 2, K128, SAEC_RomType_ODD | SAEC_RomType_8BIT, "252607-01", 0xaccbbc2e, 0x41b06d16,0x79c6e693,0x3c3378b7,0x626025f7,0x641ebc5c),
new romdata("CDTV extended ROM v2.07", 2, 7, 2, 7, "CDTV", K256, 22, 0, 0, SAEC_RomType_EXTCDTV, 0, "", "", 0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846),
ALTROM(22, 1, 1, K128, SAEC_RomType_EVEN | SAEC_RomType_8BIT, 0x36d73cb8, 0x9574e546,0x4b390697,0xf28f9a43,0x4e604e5e,0xf5e5490a),
ALTROM(22, 1, 2, K128, SAEC_RomType_ODD | SAEC_RomType_8BIT, 0x6e84dce7, 0x01a0679e,0x895a1a0f,0x559c7253,0xf539606b,0xd447b54f),
new romdata("CDTV/A570 extended ROM v2.30", 2, 30, 2, 30, "CDTV", K256, 21, 0, 0, SAEC_RomType_EXTCDTV, 0, "", "391298-01", 0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB),
ALTROM(21, 1, 1, K128, SAEC_RomType_EVEN | SAEC_RomType_8BIT, 0x48e4d74f, 0x54946054,0x2269e410,0x36018402,0xe1f6b855,0xfd89092b),
ALTROM(21, 1, 2, K128, SAEC_RomType_ODD | SAEC_RomType_8BIT, 0x8a54f362, 0x03df800f,0x032046fd,0x892f6e7e,0xec08b76d,0x33981e8c),
new romdata("CDTV-CR extended ROM v3.32", 3, 32, 3, 32, "CDTVCR", K256, 107, 0, 0, SAEC_RomType_EXTCDTV, 0, "", "", 0x581a85cf, 0xd6b8d3f2,0x854eba9b,0x2d514579,0x9529e8b3,0x3b85e0b4),
new romdata("CDTV-CR extended ROM v3.44", 3, 44, 3, 44, "CDTVCR", K256, 108, 0, 0, SAEC_RomType_EXTCDTV, 0, "", "", 0x0b7bd64f, 0x3b160c5a,0xbe79f10a,0xe6924332,0x8004bb9e,0x3162b648),
new romdata("A1000 bootstrap ROM", 0, 0, 0, 0, "A1000", K64, 24, 0, 0, SAEC_RomType_KICK, 0, "", "", 0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7),
ALTROM(24, 1, 1, 8192, 0, 0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6),
ALTROMPN(24, 2, 1, 4096, SAEC_RomType_EVEN | SAEC_RomType_8BIT, "252179-01", 0x42553bc4, 0x8855a97f,0x7a44e3f6,0x2d1c88d9,0x38fee1f4,0xc606af5b),
ALTROMPN(24, 2, 2, 4096, SAEC_RomType_ODD | SAEC_RomType_8BIT, "252180-01", 0x8e5b9a37, 0xd10f1564,0xb99f5ffe,0x108fa042,0x362e877f,0x569de2c3),
/*new romdata("The Diagnostic 2.0 (Logica)", 2, 0, 2, 0, "LOGICA", K512, 72, 0, 0, SAEC_RomType_KICK | SAEC_RomType_SPECIALKICK, 0, "", "", 0x8484f426, 0xba10d161,0x66b2e2d6,0x177c979c,0x99edf846,0x2b21651e),
new romdata("Picasso IV", 7, 4, 7, 4, "PIV", K128, 91, 0, 0, SAEC_RomType_PICASSOIV, 0, "", "", 0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b),
new romdata("A1060 BIOS 2.06", 2, 6, 2, 6, "A1060", 16384, 147, 0, 0, SAEC_RomType_A1060, 0, "", "380619-03", 0x185f2bbd, 0xeba74ad1,0x000a5351,0xa5d99179,0xbf75f831,0xac2d2402),
new romdata("A2088 BIOS 3.4", 3, 4, 3, 4, "A2088", 16384, 148, 0, 0, SAEC_RomType_A2088, 0, "", "380788-04", 0x05552160, 0xd1defdee, 0x1c0eae41, 0x07d81e26, 0x74915cd2, 0x9d352f2e),
new romdata("A2088 BIOS 3.5", 3, 5, 3, 5, "A2088", 16384, 158, 0, 0, SAEC_RomType_A2088, 0, "", "380788-04", 0xf8e1ad83, 0x45a2b7db,0x6e86fe80,0x5cfef63c,0x65c331a7,0x16a6e9e8),
new romdata("A2088 BIOS 3.6.1", 3, 61, 3, 61, "A2088", 16384, 149, 0, 0, SAEC_RomType_A2088, 0, "", "380788-06", 0x5fd93e56, 0xc1b707a8,0xa62907d7,0x5299f10a,0xa60efd1f,0x44514b26),
new romdata("A2088T BIOS 4.10", 4, 10, 4, 11, "A2088T", 32768, 150, 0, 0, SAEC_RomType_A2088T, 0, "", "390657-02", 0x20c5d1a9, 0x08e3fbb7,0x28dfc514,0x24083313,0x373ea7a5,0xa2c3e965),
new romdata("A2088T BIOS 4.11", 4, 11, 4, 11, "A2088T", 32768, 151, 0, 0, SAEC_RomType_A2088T, 0, "", "390547-02", 0x074bc9b0, 0x2a3f56bc,0xe395f203,0x46eb68c4,0xade7153e,0x3e69f892),
new romdata("A2088T BIOS 4.12", 4, 12, 4, 12, "A2088T", 32768, 152, 0, 0, SAEC_RomType_A2088T, 0, "", "390547-03", 0x92447176, 0x582fa254,0x73aa2679,0xefcd41a5,0xbdadf1a2,0x6a87a75f),
new romdata("A2286 BIOS 3.6", 3, 6, 3, 6, "A2286", 32768, 153, 0, 0, SAEC_RomType_A2286, 0, "", "", 0x63d75f70, 0x9f5d6c78,0x656d2fe7,0x36608644,0x771b6d30,0x31083264),
//ALTROMPN(153, 1, 1, 16384, SAEC_RomType_ODD | SAEC_RomType_8BIT, "380682-03", 0xb3f76402, 0xef9ba5f2, 0x2714ad6d, 0xfa5e0aef, 0x2d09ce83, 0x578ee26d)
//ALTROMPN(153, 1, 2, 16384, SAEC_RomType_EVEN | SAEC_RomType_8BIT, "380683-03", 0xab053693, 0x75229d80, 0x443fad78, 0xa298d04b, 0x37c8e6c3, 0x2c1b6df0)
new romdata("A2286 BIOS 4.2", 4, 2, 4, 2, "A2286", 32768, 154, 0, 0, SAEC_RomType_A2286, 0, "", "", 0xd572e205, 0x74fdf0f8,0x325fbc41,0x2b98c72d,0xf5095804,0x831c46b5),
//ALTROMPN(154, 1, 1, 16384, SAEC_RomType_ODD | SAEC_RomType_8BIT, "380682-04", 0xc23dcd55, 0x38dc24b7, 0x14427b15, 0xd5214cc9, 0xb9be0de7, 0x20bd6a34)
//ALTROMPN(154, 1, 2, 16384, SAEC_RomType_EVEN | SAEC_RomType_8BIT, "380683-04", 0xdad80c0b, 0x12fe2916, 0x64f8c412, 0x3877a24e, 0x05837091, 0x44d8acd0)
new romdata("A2386SX BIOS 1.0", 1, 0, 1, 0, "A2386SX", K64, 155, 0, 0, SAEC_RomType_A2386, 0, "", "", 0x37003e0c, 0x2e127e9c,0x8581d30c,0x2e46404b,0x21608e3c,0xe935fa27),
new romdata("Arcadia OnePlay 2.11", 0, 0, 0, 0, "ARCADIA", 0, 49, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia TenPlay 2.11", 0, 0, 0, 0, "ARCADIA", 0, 50, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia TenPlay 2.20", 0, 0, 0, 0, "ARCADIA", 0, 75, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia OnePlay 3.00", 0, 0, 0, 0, "ARCADIA", 0, 51, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia TenPlay 3.11", 0, 0, 0, 0, "ARCADIA", 0, 76, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia TenPlay 4.00", 0, 0, 0, 0, "ARCADIA", 0, 77, 0, 0, SAEC_RomType_ARCADIABIOS, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia SportTime Table Hockey v2.1", 0, 0, 0, 0, "ARCADIA", 0, 33, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia SportTime Bowling v2.1", 0, 0, 0, 0, "ARCADIA", 0, 34, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia World Darts v2.1", 0, 0, 0, 0, "ARCADIA", 0, 35, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Magic Johnson's Fast Break v2.8", 0, 0, 0, 0, "ARCADIA", 0, 36, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Leader Board Golf v2.4", 0, 0, 0, 0, "ARCADIA", 0, 37, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Leader Board Golf", 0, 0, 0, 0, "ARCADIA", 0, 38, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Ninja Mission v2.5", 0, 0, 0, 0, "ARCADIA", 0, 39, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Road Wars v2.3", 0, 0, 0, 0, "ARCADIA", 0, 40, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Sidewinder v2.1", 0, 0, 0, 0, "ARCADIA", 0, 41, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Spot v2.0", 0, 0, 0, 0, "ARCADIA", 0, 42, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Space Ranger v2.0", 0, 0, 0, 0, "ARCADIA", 0, 43, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Xenon v2.3", 0, 0, 0, 0, "ARCADIA", 0, 44, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia World Trophy Soccer v3.0", 0, 0, 0, 0, "ARCADIA", 0, 45, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Blastaball v2.1", 0, 0, 0, 0, "ARCADIA", 0, 78, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Delta Command", 0, 0, 0, 0, "ARCADIA", 0, 79, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Pharaohs Match", 0, 0, 0, 0, "ARCADIA", 0, 80, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia SportTime Table Hockey", 0, 0, 0, 0, "ARCADIA", 0, 81, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia World Darts (bad)", 0, 0, 0, 0, "ARCADIA", 0, 82, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Magic Johnson's Fast Break v2.7", 0, 0, 0, 0, "ARCADIA", 0, 83, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Ninja Mission", 0, 0, 0, 0, "ARCADIA", 0, 84, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Sidewinder", 0, 0, 0, 0, "ARCADIA", 0, 85, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Leader Board Golf v2.5", 0, 0, 0, 0, "ARCADIA", 0, 86, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),
new romdata("Arcadia Aaargh", 0, 0, 0, 0, "ARCADIA", 0, 88, 0, 0, SAEC_RomType_ARCADIAGAME, 0, "", "", 0, 0,0,0,0,0),*/
//OWN
//68000
new romdata("Macintosh 128K", 0,0, 0,0, "128K", K64, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x6D0C8A28, 0,0,0,0,0), //9D86C883AA09F7EF5F086D9E32330EF85F1BC93B
new romdata("Macintosh 512K", 0,0, 0,0, "512K", K64, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0xCF759E0D, 0,0,0,0,0), //5B1CED181B74CECD3834C49C2A4AA1D7FFE944D7
new romdata("Macintosh Plus (version 1)", 0,0, 0,0, "Plus", K128, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x4FA5B399, 0xE0DA7165,0xB92DEE90,0xD8B15224,0x29C03372,0x9FA73FD2),
new romdata("Macintosh Plus (version 2)", 0,0, 0,0, "Plus", K128, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x7CACD18F, 0x73BF2EB2,0x15646E10,0x8DAA0CDD,0x874E6C84,0x3C8CE421),
new romdata("Macintosh Plus (version 3)", 0,0, 0,0, "Plus", K128, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0xB2102E8E, 0x7D2F808A,0x045AA3A1,0xB242764F,0x0E2C7D13,0xE288BF1F),
new romdata("Macintosh SE", 0,0, 0,0, "SE", K256, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x0F7FF80C, 0,0,0,0,0), //58532B7D0D49659FD5228AC334A1B094F0241968
new romdata("Macintosh SE (FDHD)", 0,0, 0,0, "SE", K256, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0xF530CB10, 0,0,0,0,0), //D3670A90273D12E53D86D1228C068CB660B8C9D1
//new romdata("Macintosh Classic (with XO ROMDisk)", 0,0, 0,0, "Classic", K512, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x510D7D38, 0,0,0,0,0), //CCD10904DDC0FB6A1D216B2E9EFFD5EC6CF5A83D
new romdata("Macintosh Classic", 0,0, 0,0, "Classic", K256, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0xB14DDCDE, 0,0,0,0,0), //F710E73E8E0F99D9D0E9E79E71F67A6C3648BF06
//68HC000 16mhz
new romdata("Macintosh Portable", 0,0, 0,0, "Portable",K256, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x497348F8, 0,0,0,0,0), //79B468B33FC53F11E87E2E4B195AAC981BF0C0A6
new romdata("PowerBook 100", 0,0, 0,0, "100", K256, 200, 0, 0, SAEC_RomType_AMAX, 0, "", "", 0x29AC7EE9, 0,0,0,0,0), //7F3ACF40B1F63612DE2314A2E9FCFEAFCA0711FC
//68020 16mhz
new romdata("Macintosh II (version 1)", 0,0, 0,0, "II", K256, 200, 2, 0, SAEC_RomType_AMAX, 0, "", "", 0x8C8B9D03, 0,0,0,0,0), //5C264FE976F1E8495D364947C932A5E8309B4300
new romdata("Macintosh II (version 2)", 0,0, 0,0, "II", K256, 200, 2, 0, SAEC_RomType_AMAX, 0, "", "", 0x4DF6D054, 0,0,0,0,0), //DB6B504744281369794E26BA71A6E385CF6227FA
new romdata("Macintosh LC", 0,0, 0,0, "LC", K512, 200, 2, 0, SAEC_RomType_AMAX, 0, "", "", 0x71681726, 0,0,0,0,0), //6BEF5853AE736F3F06C2B4E79772F65910C3B7D4
];
for (var vi = 0; vi < roms.length; vi++)
roms[vi].num = vi;
/*-----------------------------------------------------------------------*/
this.getromname = function(rd) {
var name = "";
if (rd === null)
return name;
while (rd.group) rd = roms[rd.num - 1];
name += rd.name;
if ((rd.subrev || rd.subver) && rd.subver != rd.ver)
name += sprintf(" rev %d.%d", rd.subver, rd.subrev);
if (rd.size > 0)
name += sprintf(" (%dK)", (rd.size + 1023) >> 10);
if (rd.partnumber && rd.partnumber.length > 0)
name += sprintf(" [%s]", rd.partnumber);
return name;
}
/*-----------------------------------------------------------------------*/
function notcrc32(crc32) {
return crc32 == 0xffffffff || crc32 == 0x00000000;
}
this.getromdatabycrc = function(crc32, allowgroup) {
if (typeof allowgroup == "undefined") allowgroup = false;
var i, l = roms.length;
for (i = 0; i < l; i++) {
if (roms[i].group == 0 && crc32 == roms[i].crc32 && !notcrc32(crc32))
return roms[i];
}
if (allowgroup) {
for (i = 0; i < l; i++) {
if (roms[i].group != 0 && crc32 == roms[i].crc32 && !notcrc32(crc32))
return roms[i];
}
}
return null;
}
/*this.getromdatabycrc = function(crc32) {
return getromdatabycrc(crc32, false);
}*/
/*const SHA1_SIZE = 20;
function cmpsha1(sha1, rd) {
for (var i = 0; i < SHA1_SIZE; i += 4) {
if (((sha1[i] << 24) | (sha1[i + 1] << 16) | (sha1[i + 2] << 8) | (sha1[i + 3] << 0)) >>> 0 != rd.sha1[i >> 2])
return -1;
}
return 0;
}
function checkromdata(sha1, size, mask) {
for (var i = 0; i < roms.length; i++) {
if (roms[i].size >= size) {
if (roms[i].type & mask) {
if (!cmpsha1(sha1, roms[i]))
return roms[i];
}
}
}
return null;
}*/
function checkromdata(crc32, size, mask) {
for (var i = 0; i < roms.length; i++) {
if (!notcrc32(roms[i].crc32) && roms[i].size >= size) {
if (roms[i].type & mask) {
if (crc32 == roms[i].crc32)
return roms[i];
}
}
}
return null;
}
this.getromdatabydata = function(rom, size) {
if (size > 11 && SAEF_CompareArray(rom, SAEF_String2Array("AMIROMTYPE1"), 11) == 0) {
var tmpbuf = new Uint8Array(size);
var tmpsize = size - 11;
tmpbuf.set(rom.subarray(11)); //memcpy (tmpbuf, rom + 11, tmpsize);
if (this.decode_rom(tmpbuf,0, tmpsize, 1, tmpsize) != 0)
return null;
rom = tmpbuf;
size = tmpsize;
}
/*#if 0
if (size > 0x6c + K512 && SAEF_CompareArray(rom, SAEF_String2Array("AMIG"), 4) == 0) {
var tmpbuf = new Uint8Array(size);
var tmpsize = size - 0x6c;
tmpbuf.set(rom.subarray(0x6c)); //memcpy (tmpbuf, rom + 0x6c, tmpsize);
this.decode_rom(tmpbuf,0, tmpsize, 2, tmpsize);
rom = tmpbuf;
size = tmpsize;
}
#endif*/
//var sha1[SHA1_SIZE]; get_sha1(rom, size, sha1); var ret = checkromdata(sha1, size, 0xffffffff);*/
var crc32 = SAEF_crc32(rom,0, size);
var ret = checkromdata(crc32, size, 0xffffffff);
if (ret === null) {
//get_sha1(rom, size >> 1, sha1); ret = checkromdata(sha1, size >> 1, 0xffffffff);
crc32 = SAEF_crc32(rom,0, size >> 1);
ret = checkromdata(crc32, size >> 1, 0xffffffff);
/*if (ret === null) {
var tmp = new Uint8Array(4);
//ignore AR2/3 IO-port range until we have full dump
tmp.set(rom.subarray(0, 4)); //memcpy (tmp, rom, 4);
SAEF_memset(rom,0, 0, 4); //memset (rom, 0, 4);
//get_sha1(rom, size, sha1); ret = checkromdata(sha1, size, SAEC_RomType_AR2);
crc32 = SAEF_crc32(rom,0, size);
ret = checkromdata(crc32, size, SAEC_RomType_AR2);
rom.set(tmp); //memcpy (rom, tmp, 4);
}*/
}
return ret;
}
/*-----------------------------------------------------------------------*/
this.kickstart_fix_checksum = function(mem,memo, size) {
var cksum = 0, prevck = 0;
var i, ch = size == K512 ? 0x7ffe8 : (size == K256 ? 0x3ffe8 : 0x3e);
mem[memo + ch ] = 0;
mem[memo + ch + 1] = 0;
mem[memo + ch + 2] = 0;
mem[memo + ch + 3] = 0;
for (i = 0; i < size; i += 4) {
var data = ((mem[memo + i] << 24) | (mem[memo + i + 1] << 16) | (mem[memo + i + 2] << 8) | mem[memo + i + 3]) >>> 0;
cksum += data; if (cksum > 0xffffffff) cksum -= 0x100000000;
if (cksum < prevck) {
cksum++; if (cksum > 0xffffffff) cksum -= 0x100000000;
}
prevck = cksum;
}
cksum = (cksum ^ 0xffffffff) >>> 0;
mem[memo + ch ] = cksum >>> 24;
mem[memo + ch + 1] = (cksum >>> 16) & 0xff;
mem[memo + ch + 2] = (cksum >>> 8) & 0xff;
mem[memo + ch + 3] = cksum & 0xff;
SAEF_log("roms.kickstart_fix_checksum() %08X", cksum);
}
function kickstart_calc_checksum(mem,memo, size) {
var cksum = 0, prevck = 0;
for (var i = 0; i < size; i += 4) {
var data = ((mem[memo + i] << 24) | (mem[memo + i + 1] << 16) | (mem[memo + i + 2] << 8) | mem[memo + i + 3]) >>> 0;
cksum += data; if (cksum > 0xffffffff) cksum -= 0x100000000;
if (cksum < prevck) {
cksum++; if (cksum > 0xffffffff) cksum -= 0x100000000;
}
prevck = cksum;
}
return cksum;
}
this.kickstart_verify_checksum = function(mem,memo, size) {
var cksum = kickstart_calc_checksum(mem,memo, size);
SAEF_log("roms.kickstart_verify_checksum() %08X", cksum);
return cksum == 0xffffffff;
}
/*-----------------------------------------------------------------------*/
function macintosh_calc_checksum(mem,memo, size) { //OWN
var cksum = 0;
if (size == 0x400000) //Special case: 4MiB ROMs only checksum the first 3 MiB.
size -= 0x100000;
for (var i = 4; i < size; i += 2) {
var data = (mem[memo + i] << 8) | mem[memo + i + 1];
cksum += data; if (cksum > 0xffffffff) cksum -= 0x100000000;
}
return cksum;
}
/*-----------------------------------------------------------------------*/
function decode_cloanto_rom(mem,memo, size, real_size) {
var rk = SAEV_config.memory.romKey;
if (rk.name.length && rk.data.length) {
var keydata = rk.data;
var keysize = rk.data.length;
var cnt, t;
for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) {
mem[memo + cnt] ^= keydata.charCodeAt(t);
if (real_size == cnt + 1)
t = keysize - 1;
}
if ((mem[memo + 2] == 0x4e && mem[memo + 3] == 0xf9) || (mem[memo] == 0x11 && (mem[memo + 1] == 0x11 || mem[memo + 1] == 0x14))) {
//SAEV_Memory_cloantoRom = true;
return 0;
}
/*
//uae_u8 sha1[SHA1_SIZE]; get_sha1(mem, size, sha1); var rd = checkromdata(sha1, size, 0xffffffff);
var crc32 = SAEF_crc32(mem,memo, size);
var rd = checkromdata(crc32, size, 0xffffffff);
if (rd !== null) {
//if (rd.cloanto) SAEV_Memory_cloantoRom = true;
//SAEF_warn("roms.decode_cloanto_rom() invalid/wrong rom-key");
return -1;
}*/
return -1;
}
return -2;
}
function decode_rekick_rom(mem,memo, size, real_size) {
var d1 = 0xdeadfeed, d0;
for (var i = memo; i < memo + (size >> 3); i++) {
d0 = (((mem[i * 8 + 0] << 24) | (mem[i * 8 + 1] << 16) | (mem[i * 8 + 2] << 8) | mem[i * 8 + 3])) >>> 0;
d1 = (d1 ^ d0) >>> 0;
mem[i * 8 + 0] = d1 >>> 24;
mem[i * 8 + 1] = (d1 >>> 16) & 0xff;
mem[i * 8 + 2] = (d1 >>> 8) & 0xff;
mem[i * 8 + 3] = d1 & 0xff;
d1 = (((mem[i * 8 + 4] << 24) | (mem[i * 8 + 5] << 16) | (mem[i * 8 + 6] << 8) | mem[i * 8 + 7])) >>> 0;
d0 = (d0 ^ d1) >>> 0;
mem[i * 8 + 4] = d0 >>> 24;
mem[i * 8 + 5] = (d0 >>> 16) & 0xff;
mem[i * 8 + 6] = (d0 >>> 8) & 0xff;
mem[i * 8 + 7] = d0 & 0xff;
}
return 0;
}
this.decode_rom = function(mem,memo, size, mode, real_size) {
if (mode == 1)
return decode_cloanto_rom(mem,memo, size, real_size);
else if (mode == 2)
return decode_rekick_rom(mem,memo, size, real_size);
return -3;
}
/*-----------------------------------------------------------------------*/
function replaceAll(str, search, replacement) {
return str.split(search).join(replacement);
}
this.examine = function(ri, file) {
var data = SAEF_String2Array(file.data);
var size = file.size;
var cloanto = false;
if (size > 11 && SAEF_CompareArray(data, SAEF_String2Array("AMIROMTYPE1"), 11) == 0) {
var tmpdata = new Uint8Array(size);
var tmpsize = size - 11;
tmpdata.set(data.subarray(11)); //memcpy (tmpdata, data + 11, tmpsize);
var err = this.decode_rom(tmpdata,0, tmpsize, 1, tmpsize);
if (err == -1)
return SAEE_Memory_RomDecode;
if (err == -2)
return SAEE_Memory_RomKey;
data = tmpdata;
size = tmpsize;
cloanto = true;
}
var crc32 = file.crc32;
if (crc32 === false || cloanto) {
crc32 = SAEF_crc32(data,0, size);
if (!cloanto)
file.crc32 = crc32;
}
var rd = checkromdata(crc32, size, 0xffffffff);
if (rd === null)
return SAEE_Memory_RomUnknown;
while (rd.group)
rd = roms[rd.num - 1];
ri.name = rd.name;
if (rd.type & SAEC_RomType_AMAX) {
var ver = data.subarray(0x08, 0x08 + 2);
var rev = data.subarray(0x12, 0x12 + 2);
var sub = data.subarray(0x4c, 0x4c + 2);
ri.ver = (ver[0] << 8) | ver[1];
ri.rev = (rev[0] << 8) | rev[1];
ri.subVer = (sub[0] << 8) | sub[1];
ri.subRev = 0;
} else {
ri.ver = rd.ver;
ri.rev = rd.rev;
ri.subVer = rd.subver;
ri.subRev = rd.subrev;
}
ri.models = replaceAll(rd.model, "|", ", ");
ri.size = rd.size;
//rd.id
if (rd.cpu & 8) { //v2.04 (A3000)
ri.cpu = 68030;
} else if ((rd.cpu & 3) == 3) {
ri.cpu = 68030;
ri.cpuExact = true;
} else if ((rd.cpu & 3) == 2) {
ri.cpu = 68020;
} else if ((rd.cpu & 3) == 1) {
ri.cpu = 68020; //EC
ri.addressSpace24 = true;
} else {
ri.cpu = 68000;
ri.addressSpace24 = true;
}
ri.cloanto = cloanto; //rd.cloanto;
ri.type = rd.type;
//rd.title
ri.partNumber = rd.partnumber;
ri.crc32 = rd.crc32;
//rd.sha1
if (rd.type & (SAEC_RomType_ALL_KICK | SAEC_RomType_ALL_EXT)) {
ri.checksum = kickstart_calc_checksum(data,0, size);
ri.checksumValid = ri.checksum == 0xffffffff;
}
else if (rd.type & SAEC_RomType_AMAX) {
var chk = data.subarray(0, 4);
ri.checksum = macintosh_calc_checksum(data,0, size);
ri.checksumValid = ri.checksum == ((chk[0] << 24) | (chk[1] << 16) | (chk[2] << 8) | chk[3]) >>> 0;
}
else {
ri.checksum = false;
ri.checksumValid = false;
}
return SAEE_None;
}
}

View file

@ -1,199 +1,306 @@
/**************************************************************************
* SAE - Scripted Amiga Emulator
*
* 2012-2015 Rupert Hausberger
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
**************************************************************************/
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: ported from WinUAE 3.2.x
-------------------------------------------------------------------------*/
/* global variables */
var SAEV_RTC_bank = null;
var SAEV_RTC_delayed_write = 0;
/*---------------------------------*/
function SAEO_RTC() {
const RTC_DEBUG = false;
var clock_control_d = 0;
var clock_control_e = 0;
var clock_control_f = 0;
function RTC() {
const RF5C01A_RAM_SIZE = 16;
var clock_control_d;
var clock_control_e;
var clock_control_f;
var rtc_memory = null;
var rtc_alarm = null;
this.read = function () {
/*struct zfile *f;
f = zfile_fopen (currprefs.flashfile, "rb", ZFD_NORMAL);
if (f) {
zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
zfile_fclose (f);
}*/
};
this.write = function () {
/*struct zfile *f = zfile_fopen (currprefs.flashfile, L"rb+", ZFD_NORMAL);
if (!f) {
f = zfile_fopen (currprefs.flashfile, L"wb", 0);
if (f) {
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
zfile_fclose (f);
}
return;
}
zfile_fseek (f, 0, SEEK_END);
if (zfile_ftell (f) <= 2 * RF5C01A_RAM_SIZE) {
zfile_fseek (f, 0, SEEK_SET);
zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
}
zfile_fclose (f);*/
};
/*---------------------------------*/
this.setup = function () {
BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A'));
function localtime(t) {
this.tm_sec = t.getSeconds(); //seconds [0,61]
this.tm_min = t.getMinutes(); //minutes [0,59]
this.tm_hour = t.getHours(); //hour [0,23]
this.tm_mday = t.getDate(); //day of month [1,31]
this.tm_mon = t.getMonth(); //month of year [0,11]
this.tm_year = t.getFullYear() - 1900; //years since 1900
this.tm_wday = t.getDay(); //day of week [0,6] (Sunday = 0)
this.tm_yday = 0; //day of year [0,365]
this.tm_isdst = false; //daylight savings flag
}
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
function getct() {
var d = new Date();
if (SAEV_config.chipset.rtc.adjust) {
var n = d.valueOf();
d.setTime(n + SAEV_config.chipset.rtc.adjust * 1000);
}
return new localtime(d);
}
/*---------------------------------*/
function getclockreg(addr, ct) {
var v = 0;
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B_A2000) { /* MSM6242B */
switch (addr) {
case 0x0: v = ct.tm_sec % 10; break;
case 0x1: v = ct.tm_sec / 10 >>> 0; break;
case 0x2: v = ct.tm_min % 10; break;
case 0x3: v = ct.tm_min / 10 >>> 0; break;
case 0x4: v = ct.tm_hour % 10; break;
case 0x5: {
if (clock_control_f & 4)
v = ct.tm_hour / 10 >>> 0; /* 24h */
else {
v = (ct.tm_hour % 12) / 10 >>> 0; /* 12h */
v |= ct.tm_hour >= 12 ? 4 : 0; /* AM/PM bit */
}
break;
}
case 0x6: v = ct.tm_mday % 10; break;
case 0x7: v = ct.tm_mday / 10 >>> 0; break;
case 0x8: v = (ct.tm_mon + 1) % 10; break;
case 0x9: v = (ct.tm_mon + 1) / 10 >>> 0; break;
case 0xA: v = ct.tm_year % 10; break;
case 0xB: v = ((ct.tm_year / 10) >>> 0) & 0x0f; break;
case 0xC: v = ct.tm_wday; break;
case 0xD: v = clock_control_d; break;
case 0xE: v = clock_control_e; break;
case 0xF: v = clock_control_f; break;
}
} else if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) { /* RF5C01A */
var bank = clock_control_d & 3;
/* memory access */
if (bank >= 2 && addr < 0x0d)
return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
/* alarm */
if (bank == 1 && addr < 0x0d) {
v = rtc_alarm[addr];
if (RTC_DEBUG) SAEF_log("rtc.get8(0x%X, ct) ALARM (0x%x)", addr, v);
return v;
}
switch (addr) {
case 0x0: v = ct.tm_sec % 10; break;
case 0x1: v = ct.tm_sec / 10 >>> 0; break;
case 0x2: v = ct.tm_min % 10; break;
case 0x3: v = ct.tm_min / 10 >>> 0; break;
case 0x4: v = ct.tm_hour % 10; break;
case 0x5: {
if (rtc_alarm[10] & 1)
v = ct.tm_hour / 10 >>> 0; /* 24h */
else {
v = (ct.tm_hour % 12) / 10 >>> 0; /* 12h */
v |= ct.tm_hour >= 12 ? 2 : 0; /* AM/PM bit */
}
break;
}
case 0x6: v = ct.tm_wday; break;
case 0x7: v = ct.tm_mday % 10; break;
case 0x8: v = ct.tm_mday / 10 >>> 0; break;
case 0x9: v = (ct.tm_mon + 1) % 10; break;
case 0xA: v = (ct.tm_mon + 1) / 10 >>> 0; break;
case 0xB: v = (ct.tm_year % 100) % 10; break;
case 0xC: v = (ct.tm_year % 100) / 10 >>> 0; break;
case 0xD: v = clock_control_d; break;
case 0xE: v = 0; break; //E and F = write-only, reads as zero
case 0xF: v = 0; break;
}
}
if (RTC_DEBUG) SAEF_log("rtc.get8(0x%X, ct) (0x%x)", addr, v);
return v;
}
/*---------------------------------*/
function read() { //read_battclock()
//if (SAEV_config.chipset.rtc.file.length)
{
var f = null; //SAEF_ZFile_fopen(SAEV_config.chipset.rtc.file, "rb");
if (f) {
var data = new Uint8Array(16);
SAEF_ZFile_fread(data,0, 16, 1, f);
clock_control_d = data[13];
clock_control_e = data[14];
clock_control_f = data[15];
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) {
SAEF_ZFile_fread(rtc_alarm,0, RF5C01A_RAM_SIZE, 1, f);
SAEF_ZFile_fread(rtc_memory,0, RF5C01A_RAM_SIZE, 1, f);
}
SAEF_ZFile_fclose(f);
}
}
}
this.write = function() { //write_battclock() called from cia.vsync()
if (SAEV_config.chipset.rtc.type != SAEC_Config_RTC_Type_None) {
//if (SAEV_config.chipset.rtc.file.length)
{
var f = null; //SAEF_ZFile_fopen(SAEV_config.chipset.rtc.file, "wb");
if (f) {
var ct = getct();
var data = new Uint8Array(16);
var od = clock_control_d;
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A)
clock_control_d &= ~3;
for (var i = 0; i < 13; i++)
data[i] = getclockreg(i, ct);
clock_control_d = od;
data[i] = clock_control_d;
data[i] = clock_control_e;
data[i] = clock_control_f;
SAEF_ZFile_fwrite(data,0, 16, 1, f);
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) {
SAEF_ZFile_fwrite(rtc_alarm,0, RF5C01A_RAM_SIZE, 1, f);
SAEF_ZFile_fwrite(rtc_memory,0, RF5C01A_RAM_SIZE, 1, f);
}
SAEF_ZFile_fclose(f);
}
}
}
}
/*---------------------------------*/
this.hardreset = function() { //rtc_hardreset()
switch (SAEV_config.chipset.rtc.type) {
case SAEC_Config_RTC_Type_None: type = "none"; break;
case SAEC_Config_RTC_Type_MSM6242B: type = "MSM6242B"; break;
case SAEC_Config_RTC_Type_RF5C01A: type = "RF5C01A"; break;
case SAEC_Config_RTC_Type_MSM6242B_A2000: type = "MSM6242B A2000"; break;
}
SAEF_log("rtc.hardreset() type '%s'", type);
SAEV_RTC_delayed_write = 0;
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B_A2000) { /* MSM6242B */
clock_control_d = 0x1;
clock_control_e = 0;
clock_control_f = 0x4;
/* 24/12 */
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
clock_control_d = 0x4;
/* Timer EN */
clock_control_f = 0x4; /* 24/12 */
rtc_memory = null;
rtc_alarm = null;
} else if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) { /* RF5C01A */
clock_control_d = 0x8; /* Timer EN */
clock_control_e = 0;
clock_control_f = 0;
rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE);
rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE);
for (var i = 0; i < RF5C01A_RAM_SIZE; i++)
rtc_memory[i] = rtc_alarm[i] = 0;
this.read();
rtc_alarm[10] = 1; /* 24H mode */
}
};
SAEV_RTC_bank.name = "Battery backed up clock ("+type+")";
read();
}
/*---------------------------------*/
function get32(addr) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0)
return SAER.memory.dummyGet(addr, 4, false, 0);
return ((get16(addr) << 16) | get16(addr + 2)) >>> 0;
}
function get16(addr) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0)
return SAER.memory.dummyGet(addr, 2, false, 0);
return (get8(addr) << 8) | get8(addr + 1);
}
function get8(addr) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0)
return SAER.memory.dummyGet(addr, 1, false, 0);
/*#ifdef CDTV
if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000)
return cdtv_battram_read(addr);
#endif*/
this.load8 = function (addr) {
addr &= 0x3f;
if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) {
if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible)
return 0xff; //regs.irc >> 8;
return 0;
if ((addr & 3) == 2 || (addr & 3) == 0 || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_None)
return SAER.memory.dummyGet(addr, 1, false, 0);
var ct = getct();
return getclockreg(addr >> 2, ct);
}
function put32(addr, value) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0) {
SAER.memory.dummyPut(addr, 4, value);
return;
}
var t = new Date();
put16(addr, value >>> 16);
put16(addr + 2, value & 0xffff);
}
addr >>= 2;
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
switch (addr) {
case 0x0:
return t.getSeconds() % 10;
case 0x1:
return Math.floor(t.getSeconds() / 10);
case 0x2:
return t.getMinutes() % 10;
case 0x3:
return Math.floor(t.getMinutes() / 10);
case 0x4:
return t.getHours() % 10;
case 0x5:
return Math.floor(t.getHours() / 10);
case 0x6:
return t.getDate() % 10;
case 0x7:
return Math.floor(t.getDate() / 10);
case 0x8:
return (t.getMonth() + 1) % 10;
case 0x9:
return Math.floor((t.getMonth() + 1) / 10);
case 0xA:
return (t.getFullYear() - 1900) % 10;
case 0xB:
return Math.floor((t.getFullYear() - 1900) / 10);
case 0xC:
return t.getDay();
case 0xD:
return clock_control_d;
case 0xE:
return clock_control_e;
case 0xF:
return clock_control_f;
}
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
var bank = clock_control_d & 3;
if (bank >= 2 && addr < 0x0d) return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
if (bank == 1 && addr < 0x0d) return rtc_alarm[addr];
switch (addr) {
case 0x0:
return t.getSeconds() % 10;
case 0x1:
return Math.floor(t.getSeconds() / 10);
case 0x2:
return t.getMinutes() % 10;
case 0x3:
return Math.floor(t.getMinutes() / 10);
case 0x4:
return t.getHours() % 10;
case 0x5:
return Math.floor(t.getHours() / 10);
case 0x6:
return t.getDate() % 10;
case 0x7:
return Math.floor(t.getDate() / 10);
case 0x8:
return (t.getMonth() + 1) % 10;
case 0x9:
return Math.floor((t.getMonth() + 1) / 10);
case 0xA:
return (t.getFullYear() - 1900) % 10;
case 0xB:
return Math.floor((t.getFullYear() - 1900) / 10);
case 0xC:
return t.getDay();
case 0xD:
return clock_control_d;
/* E and F = write-only */
}
function put16(addr, value) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0) {
SAER.memory.dummyPut(addr, 2, value);
return;
}
return 0;
};
put8(addr, value >> 8);
put8(addr + 1, value & 0xff);
}
this.load16 = function (addr) {
return (this.load8(addr) << 8) | this.load8(addr + 1);
};
function put8(addr, value) {
if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0) {
SAER.memory.dummyPut(addr, 1, value);
return;
}
/*#ifdef CDTV
if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000) {
cdtv_battram_write(addr, value);
return;
}
#endif*/
this.load32 = function (addr) {
return ((this.load16(addr) << 16) | this.load16(addr + 2)) >>> 0;
};
this.store8 = function (addr, value) {
addr &= 0x3f;
if ((addr & 1) != 1 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) return;
if ((addr & 1) != 1 || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_None)
return;
addr >>= 2;
value &= 0x0f;
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) {
if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_MSM6242B_A2000) { /* MSM6242B */
if (RTC_DEBUG) SAEF_log("rtc.put8(0x%X, 0x%x)", addr, value);
switch (addr) {
case 0xD:
clock_control_d = value & (1 | 8);
break;
case 0xE:
clock_control_e = value;
break;
case 0xF:
clock_control_f = value;
break;
case 0xD: clock_control_d = value & (1|8); break;
case 0xE: clock_control_e = value; break;
case 0xF: clock_control_f = value; break;
}
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) {
} else if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) { /* RF5C01A */
var bank = clock_control_d & 3;
/* memory access */
if (bank >= 2 && addr < 0x0d) {
var ov = rtc_memory[addr];
rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
//var ov = rtc_memory[addr];
if (rtc_memory[addr] != value) this.write();
if (rtc_memory[addr] != ov) SAEV_RTC_delayed_write = -1;
return;
}
/* alarm */
if (bank == 1 && addr < 0x0d) {
if (RTC_DEBUG) SAEF_log("rtc.put8(0x%X, 0x%x) ALARM", addr, value);
var ov = rtc_alarm[addr];
rtc_alarm[addr] = value;
rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
rtc_alarm[3] &= ~0x8;
@ -202,34 +309,25 @@ function RTC() {
rtc_alarm[8] &= ~0xc;
rtc_alarm[10] &= ~0xe;
rtc_alarm[11] &= ~0xc;
//var ov = rtc_alarm[addr];
if (rtc_alarm[addr] != value) this.write();
if (rtc_alarm[addr] != ov) SAEV_RTC_delayed_write = -1;
return;
}
if (RTC_DEBUG) SAEF_log("rtc.put8(0x%X, 0x%x)", addr, value);
switch (addr) {
case 0xD:
clock_control_d = value;
break;
case 0xE:
clock_control_e = value;
break;
case 0xF:
clock_control_f = value;
break;
case 0xD: clock_control_d = value; break;
case 0xE: clock_control_e = value; break;
case 0xF: clock_control_f = value; break;
}
}
};
this.store16 = function (addr, value) {
this.store8(addr, (value >> 8) & 0xff);
this.store8(addr + 1, value & 0xff);
};
this.store32 = function (addr, value) {
this.store16(addr, (value >>> 16) & 0xffff);
this.store16(addr + 2, value & 0xffff);
SAEV_RTC_delayed_write = -1;
}
}
SAEV_RTC_bank = new SAEO_Memory_addrbank(
get32, get16, get8,
put32, put16, put8,
SAEF_Memory_defaultXLate, SAEF_Memory_defaultCheck, null, null, "Battery backed up clock (none)",
SAEF_Memory_dummyGetInst32, SAEF_Memory_dummyGetInst16,
//SAEC_Memory_addrbank_flag_IO, S_READ, S_WRITE, null, 0x3f, 0xd80000
SAEC_Memory_addrbank_flag_IO, null, 0x3f, 0xd80000
);
}

View file

@ -1,82 +1,302 @@
/**************************************************************************
* SAE - Scripted Amiga Emulator
*
* 2012-2015 Rupert Hausberger
*
* https://github.com/naTmeg/ScriptedAmigaEmulator
*
**************************************************************************/
/*-------------------------------------------------------------------------
| SAE - Scripted Amiga Emulator
| https://github.com/naTmeg/ScriptedAmigaEmulator
|
| Copyright (C) 2012-2016 Rupert Hausberger
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| Note: ported from WinUAE 3.2.x
-------------------------------------------------------------------------*/
function Serial()
{
var buf = new Uint8Array(1024);
var pos = 0, dtr = false;
var serper = 0, serdat = 0x2000;
function SAEO_Serial() {
const WARN_SERIAL = true;
const DEBUG_SERIAL = 0; /* 0,1,2,3 */
this.reset = function () {
this.flushBuffer();
var inbuf = new Uint8Array(1024);
var outbuf = new Uint8Array(1024);
var inptr = 0, inlast = 0, outlast = 0;
pos = 0;
var waitqueue = false;
var dsr = false;
var dtr = false;
//var carrier = false;
var notify = false;
var serdev = false;
var serper = 0, serdat = 0;
/*---------------------------------*/
function open() { //serial_open()
if (serdev)
return;
/*if ((sd = open(currprefs.sername, O_RDWR|O_NONBLOCK|O_BINARY, 0)) < 0) {
SAEF_log("serial.open() Could not open Device %s", currprefs.sername);
return;
}
serdev = true;
if (tcgetattr (sd, &tios) < 0) {
SAEF_log("serial.open() TCGETATTR failed");
return;
}
cfmakeraw(&tios);
#ifndef MODEMTEST
tios.c_cflag &= ~CRTSCTS;
#else
tios.c_cflag |= CRTSCTS;
#endif
if (tcsetattr (sd, TCSADRAIN, &tios) < 0)
SAEF_log("serial.open() TCSETATTR failed");*/
}
function close() { //serial_close()
//if (sd >= 0) close(sd);
serdev = false;
}
/*---------------------------------*/
function read_buffer() {
if (inptr < inlast)
return inbuf[inptr++];
/*if (serdev) {
inlast = read(sd, inbuf, 1024);
inptr = 0;
if (inptr < inlast)
return inbuf[inptr++];
}*/
return false;
}
function flush_buffer() {
if (outlast > 0) { //OWN
var str = "";
for (var i = 0; i < outlast; i++)
str += String.fromCharCode(outbuf[i]);
//SAEF_info(str);
console.log(str);
}
if (serdev) {
/*if (outlast) {
if (sd != 0)
write(sd, outbuf, outlast);
}*/
outlast = 0;
} else {
outlast = 0;
inptr = 0;
inlast = 0;
}
}
/*---------------------------------*/
this.SERPER = function(w) {
var baud, pspeed;
if (!SAEV_config.serial.enabled)
return;
if (serper == w) /* don't set baudrate if it's already ok */
return;
serper = w;
if (WARN_SERIAL && (w & 0x8000)) SAEF_warn("serial.SERPER() 9bit transmission not implemented.");
switch (w & 0x7fff) {
case 0x2e9b:
case 0x2e14: baud = 300; pspeed = 300; break;
case 0x170a:
case 0x0b85: baud = 1200; pspeed = 1200; break;
case 0x05c2:
case 0x05b9: baud = 2400; pspeed = 2400; break;
case 0x02e9:
case 0x02e1: baud = 4800; pspeed = 4800; break;
case 0x0174:
case 0x0170: baud = 9600; pspeed = 9600; break;
case 0x00b9:
case 0x00b8: baud = 19200; pspeed = 19200; break;
case 0x005c:
case 0x005d: baud = 38400; pspeed = 38400; break;
case 0x003d: baud = 57600; pspeed = 57600; break;
case 0x001e: baud = 115200; pspeed = 115200; break;
case 0x000f: baud = 230400; pspeed = 230400; break;
default: {
if (WARN_SERIAL) SAEF_warn("serial.SERPER() unsupported baudrate (0x%04x) %d", w & 0x7fff, ~~(3579546.471 / ((w & 0x7fff) + 1)));
return;
}
}
if (serdev) {
/*if (tcgetattr(sd, &tios) < 0) {
if (WARN_SERIAL) SAEF_warn("serial.SERPER() TCGETATTR failed");
return;
}
if (cfsetispeed(&tios, pspeed) < 0) {
if (WARN_SERIAL) SAEF_warn("serial.SERPER() CFSETISPEED (%d bps) failed", baud);
return;
}
if (cfsetospeed(&tios, pspeed) < 0) {
if (WARN_SERIAL) SAEF_warn("serial.SERPER() CFSETOSPEED (%d bps) failed", baud);
return;
}
if (tcsetattr(sd, TCSADRAIN, &tios) < 0) {
if (WARN_SERIAL) SAEF_warn("serial.SERPER() TCSETATTR failed");
return;
}*/
}
if (DEBUG_SERIAL > 0) SAEF_log("serial.SERPER() baudrate set to %d bit/sec", baud);
}
this.SERDAT = function(w) {
if (!SAEV_config.serial.enabled)
return;
var z = w & 0xff;
if (SAEV_config.serial.demand && !dtr) {
if (!notify) {
if (WARN_SERIAL) SAEF_warn("serial.SERDAT() Your software needs SERIAL ALWAYS to work properly. (disable 'serial.demand' in the config)");
notify = true;
}
return;
} else {
outbuf[outlast++] = z;
if (outlast == outbuf.length)
flush_buffer();
}
if (DEBUG_SERIAL > 2) SAEF_log("serial.SERDAT() wrote 0x%04x", w);
serdat |= 0x2000; /* Set TBE in the SERDATR ... */
SAEV_Custom_intreq |= SAEC_Custom_INTF_TBE; /* ... and in INTREQ register */
return;
}
this.SERDATR = function() {
if (!SAEV_config.serial.enabled)
return 0x2000;
if (DEBUG_SERIAL > 2) SAEF_log("serial.SERDATR() read 0x%04x", serdat);
waitqueue = false;
return serdat;
}
this.SERDATS = function() {
if (!serdev) /* || (serdat & 0x4000)) */
return 0;
if (waitqueue) {
SAEV_Custom_intreq |= SAEC_Custom_INTF_RBF;
return 1;
}
var z;
if ((z = read_buffer()) !== false) {
waitqueue = true;
serdat = 0x4100; /* RBF and STP set! */
serdat |= (z & 0xff);
SAEV_Custom_intreq |= SAEC_Custom_INTF_RBF; /* Set RBF flag (Receive Buffer full) */
if (DEBUG_SERIAL > 1) SAEF_log("serial.SERDATS() received 0x%02x --> serdat 0x%04x", z, serdat);
return 1;
}
return 0;
}
/*---------------------------------*/
this.dtr_on = function() {
if (DEBUG_SERIAL > 0) SAEF_log("serial.dtr_on()");
dtr = true;
if (SAEV_config.serial.demand)
open();
}
this.dtr_off = function() {
if (DEBUG_SERIAL > 0) SAEF_log("serial.dtr_off()");
dtr = false;
if (SAEV_config.serial.demand)
close();
}
this.readstatus = function(ignored) {
var status = 0;
/*ioctl (sd, TIOCMGET, &status);
if (status & TIOCM_CAR) {
if (!carrier) {
ciabpra |= 0x20;
carrier = true;
if (DEBUG_SERIAL > 0) SAEF_log("serial.readstatus() Carrier detect");
}
} else {
if (carrier) {
ciabpra &= ~0x20;
carrier = false;
if (DEBUG_SERIAL > 0) SAEF_log("serial.readstatus() Carrier lost");
}
}
if (status & TIOCM_DSR) {
if (!dsr) {
ciabpra |= 0x08;
dsr = true;
}
} else {
if (dsr) {
ciabpra &= ~0x08;
dsr = false;
}
}*/
return status;
}
this.writestatus = function(old, nw) {
if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) this.dtr_on();
if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) this.dtr_off();
if (DEBUG_SERIAL > 0) {
if ((old & 0x40) != (nw & 0x40)) SAEF_log("serial.writestatus() RTS %s", ((nw & 0x40) == 0x40) ? "set" : "cleared");
if ((old & 0x10) != (nw & 0x10)) SAEF_log("serial.writestatus() CTS %s", ((nw & 0x10) == 0x10) ? "set" : "cleared");
}
return nw;
}
/*---------------------------------*/
this.setup = function() { //serial_init()
if (!SAEV_config.serial.enabled)
return;
if (!SAEV_config.serial.demand)
open();
serdat = 0x2000;
}
this.cleanup = function() { //serial_exit()
close();
dtr = false;
}
this.reset = function() {
inptr = 0, inlast = 0, outlast = 0
waitqueue = false;
dsr = false;
dtr = false;
//carrier = false;
notify = false;
serper = 0;
serdat = 0x2000;
};
this.flushBuffer = function () {
if (pos > 0) {
var str = '';
for (var i = 0; i < pos; i++) {
/*if (buf[i] == 13)
str += '<br/>';
else if (buf[i] == 9)
str += '&nbsp;&nbsp;&nbsp;';
else*/
str += String.fromCharCode(buf[i]);
}
pos = 0;
BUG.col = 3;
BUG.info(str);
BUG.col = 1;
}
};
this.readStatus = function () {
//ciabpra |= 0x20; //Push up Carrier Detect line
//ciabpra |= 0x08; //DSR ON
return 0;
};
this.writeStatus = function (old, nw) {
if ((old & 0x80) == 0x80 && (nw & 0x80) == 0x00) dtr = true;
if ((old & 0x80) == 0x00 && (nw & 0x80) == 0x80) dtr = false;
//if ((old & 0x40) != (nw & 0x40)) BUG.info('RTS %s.', (nw & 0x40) == 0x40 ? 'set' : 'clr');
//if ((old & 0x10) != (nw & 0x10)) BUG.info('CTS %s.', (nw & 0x10) == 0x10 ? 'set' : 'clr');
return nw;
};
this.SERPER = function (v) {
if (serper != v)
serper = v;
};
this.SERDAT = function (v) {
//BUG.info('SERDAT $%04x', v);
if (AMIGA.config.serial.enabled) {
buf[pos++] = v & 0xff;
if (pos == 1024)
this.flushBuffer();
}
serdat |= 0x2000;
/* Set TBE in the SERDATR ... */
AMIGA.intreq |= 1;
/* ... and in INTREQ register */
};
this.SERDATR = function()
{
//BUG.info('SERDATR $%04x', serdat);
return serdat;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff