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

425
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:link { color:#24c; text-decoration:none; }
a:visited { color:#2040c0; text-decoration:none; } a:visited { color:#24c; text-decoration:none; }
a:hover { color:#2040c0; text-decoration:underline; } a:hover { color:#24c; 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; }
body { body {
top:0; top:0;
left:0; left:0;
margin:0; margin:0;
padding:0; padding:0;
font-family:verdana,serif; font-family:Verdana;
font-size:small; font-size:13px;
background-color:#fff; 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 { .noscript {
margin:auto; margin:auto;
padding:4px; padding:4px;
font-size:17px;
font-weight:bold; font-weight:bold;
font-size:medium;
text-align:center; text-align:center;
color:red; color:red;
} }
.hr {
width:100%;
border-top:1px solid #ccc;
}
.head { .head {
width:100%; width:100%;
margin:auto; margin:auto;
@ -69,123 +112,195 @@ body {
.foot { .foot {
width:100%; width:100%;
margin:auto; margin:auto;
font-size:11px;
text-align:center; text-align:center;
font-size:x-small;
} }
#config_simple { .linehoriz {
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 {
width:100%; width:100%;
line-height:20px; border-top:1px solid #bbb;
} }
#config .tl { .text {
border-top:1px solid #ccc; 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 { #myVideo {
width:auto; margin:auto;
} }
/*---------------------------------*/
#config select { #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 { #config .button {
width:100px; width:75px;
border:1px solid #ccc; border-left:1px solid #fff;
background-color:#fff; border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
} }
#config .button:hover { #config .button:hover {
background-color:#eee; background-color:#e8e8e8;
} }
#config .sbutton { #config .sbutton {
width:100px; width:100px;
padding:2px; padding:2px;
font-weight:bold; border-left:1px solid #fff;
border:1px solid #ccc; border-top:1px solid #fff;
background-color:#fff; border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f8f8f8;
} }
#config .sbutton:hover { #config .sbutton:hover {
background-color:#eee; background-color:#e8e8e8;
} }
#cfg_demo, #cfg_game {
width:100%; #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 { #emul {
display:none; display:none;
} }
#status { #emul button {
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 {
width:64px; width:64px;
font-size:x-small; font-size:11px;
font-weight:bold;
color:#888; color:#888;
border:1px solid #888; border:1px solid #888;
background-color:#000; background-color:#000;
} }
.dbutton:hover { #emul button:hover {
color:#ccc; color:#ccc;
border:1px solid #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 { .readme {
width:1004px; width:1080px;
margin:auto; margin:auto;
padding:10px; padding:10px;
border:1px solid #ccc; border-left:1px solid #fff;
background-color:#fcfcfc; border-top:1px solid #fff;
border-right:1px solid #bbb;
border-bottom:1px solid #bbb;
background-color:#f0f0f0;
} }
.readme table { .readme table {
width:100%; width:100%;
@ -193,15 +308,57 @@ body {
.readme table td { .readme table td {
vertical-align:top; vertical-align:top;
} }
.readme li {
/*div.float_box { padding:1px;
overflow: hidden;
width: 100%;
} }
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;
}

2397
index.htm

File diff suppressed because it is too large Load diff

3782
index.js

File diff suppressed because it is too large Load diff

1249
readme.htm

File diff suppressed because it is too large Load diff

View file

@ -1,426 +1,582 @@
/************************************************************************** /*-------------------------------------------------------------------------
* SAE - Scripted Amiga Emulator | SAE - Scripted Amiga Emulator
* | https://github.com/naTmeg/ScriptedAmigaEmulator
* 2012-2015 Rupert Hausberger |
* | Copyright (C) 2012-2016 Rupert Hausberger
* https://github.com/naTmeg/ScriptedAmigaEmulator |
* | 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; } const SAEC_Version = 0;
function clr_special(x) { AMIGA.spcflags &= ~x; } 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();
this.state = ST_STOP; /*---------------------------------*/
this.delay = 0; /* errors */
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 () { function SAEO_Error(err, msg) {
this.mem.setup(); this.err = err;
this.expansion.setup(); this.msg = msg;
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);
}
} }
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 SAER = null;
var AMIGA = null;
function SAE(x) { /*---------------------------------*/
try { /* global constants */
switch (x.cmd) {
case 'init':
BUG = new Debug();
BUG.info('API.init() SEA %d.%d.%d', SAEV_Version, SAEV_Revision, SAEV_Revision_Sub);
AMIGA = new Amiga(); const SAEC_spcflag_STOP = 2;
//return AMIGA.config; const SAEC_spcflag_COPPER = 4;
break; const SAEC_spcflag_INT = 8;
case 'reset': const SAEC_spcflag_BRK = 16;
BUG.info('API.reset()'); //const SAEC_spcflag_UAEINT = 32;
AMIGA.reset(); const SAEC_spcflag_TRACE = 64;
break; const SAEC_spcflag_DOTRACE = 128;
case 'start': const SAEC_spcflag_DOINT = 256;
BUG.info('API.start()'); const SAEC_spcflag_BLTNASTY = 512;
AMIGA.start(); //const SAEC_spcflag_EXEC = 1024;
break; //const SAEC_spcflag_ACTION_REPLAY = 2048;
case 'stop': //const SAEC_spcflag_TRAP = 4096; /* enforcer-hack */
BUG.info('API.stop()'); const SAEC_spcflag_MODE_CHANGE = 8192;
AMIGA.stop(); const SAEC_spcflag_CHECK = 32768;
break;
case 'pause': const SAEC_command_Quit = 1;
BUG.info('API.pause() %d', x.state); const SAEC_command_Reset = 2;
AMIGA.pause(x.state); const SAEC_command_KeyboardReset = 3;
break; const SAEC_command_HardReset = 4;
/*case 'insert': const SAEC_command_Pause = 5;
BUG.info('API.insert() DF%d, name "%s", length %d', x.unit, x.name, x.data.length); const SAEC_command_Resume = 6;
AMIGA.insert(x.unit, x.name, x.data);
break;*/ /*---------------------------------*/
case 'insert':
BUG.info('API.insert() DF%d', x.unit); const SAEC_Info_Brower_ID_Unknown = 0;
AMIGA.insert(x.unit); const SAEC_Info_Brower_ID_Chrome = 1;
break; const SAEC_Info_Brower_ID_Safari = 2;
case 'eject': const SAEC_Info_Brower_ID_Opera = 3;
BUG.info('API.eject() DF%d', x.unit); const SAEC_Info_Brower_ID_Firefox = 4;
AMIGA.eject(x.unit); const SAEC_Info_Brower_ID_InternetExplorer = 5;
break;
case 'getInfo': const SAEC_info = (function() {
BUG.info('API.getInfo()'); var info = {
return AMIGA.info; browser: {
case 'getConfig': id: SAEC_Info_Brower_ID_Unknown,
BUG.info('API.getConfig()'); name: "Unknown",
return AMIGA.config; plat: "Unknown",
/*case 'setConfig': lang: "en"
BUG.info('API.setConfig() size '+x.data.ext.size); },
AMIGA.config = x.data; memory: {
break;*/ maxSize: 0
} },
} catch (e) { audio: {
if (e instanceof FatalError) { webAudio: false
AMIGA.stop(); },
//return { error:e.error, message:e.message }; video: {
AMIGA.config.hooks.error(e.error, e.message); canvas: false,
} else webGL: false
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; else if (navigator.userAgent.indexOf("Safari") > -1) {
//return { error:SAEE_None, message:'' }; info.browser.id = SAEC_Info_Brower_ID_Safari;
return 0; 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

1500
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

14059
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

File diff suppressed because it is too large Load diff

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 | SAE - Scripted Amiga Emulator
* | https://github.com/naTmeg/ScriptedAmigaEmulator
* 2012-2015 Rupert Hausberger |
* | Copyright (C) 2012-2016 Rupert Hausberger
* https://github.com/naTmeg/ScriptedAmigaEmulator |
* | 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; const RF5C01A_RAM_SIZE = 16;
var clock_control_d;
var clock_control_e;
var clock_control_f;
var rtc_memory = null; var rtc_memory = null;
var rtc_alarm = 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 () { function localtime(t) {
BUG.info('RTC.setup() type ' + (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B ? 'MSM6242B' : 'RF5C01A')); 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_d = 0x1;
clock_control_e = 0; clock_control_e = 0;
clock_control_f = 0x4; clock_control_f = 0x4; /* 24/12 */
/* 24/12 */ rtc_memory = null;
} else if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_RF5C01A) { rtc_alarm = null;
clock_control_d = 0x4; } else if (SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_RF5C01A) { /* RF5C01A */
/* Timer EN */ clock_control_d = 0x8; /* Timer EN */
clock_control_e = 0; clock_control_e = 0;
clock_control_f = 0; clock_control_f = 0;
rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE); rtc_memory = new Uint8Array(RF5C01A_RAM_SIZE);
rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE); rtc_alarm = new Uint8Array(RF5C01A_RAM_SIZE);
for (var i = 0; i < RF5C01A_RAM_SIZE; i++) for (var i = 0; i < RF5C01A_RAM_SIZE; i++)
rtc_memory[i] = rtc_alarm[i] = 0; rtc_memory[i] = rtc_alarm[i] = 0;
this.read(); 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; addr &= 0x3f;
if ((addr & 3) == 2 || (addr & 3) == 0 || AMIGA.config.rtc.type == SAEV_Config_RTC_Type_None) { if ((addr & 3) == 2 || (addr & 3) == 0 || SAEV_config.chipset.rtc.type == SAEC_Config_RTC_Type_None)
if (AMIGA.config.cpu.model == 68000 && AMIGA.config.cpu.compatible) return SAER.memory.dummyGet(addr, 1, false, 0);
return 0xff; //regs.irc >> 8;
return 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; function put16(addr, value) {
if (AMIGA.config.rtc.type == SAEV_Config_RTC_Type_MSM6242B) { if ((addr & 0xffff) >= 0x8000 && SAEV_config.chipset.fatGaryRev >= 0) {
switch (addr) { SAER.memory.dummyPut(addr, 2, value);
case 0x0: return;
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 */
}
} }
return 0; put8(addr, value >> 8);
}; put8(addr + 1, value & 0xff);
}
this.load16 = function (addr) { function put8(addr, value) {
return (this.load8(addr) << 8) | this.load8(addr + 1); 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; 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; addr >>= 2;
value &= 0x0f; 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) { switch (addr) {
case 0xD: case 0xD: clock_control_d = value & (1|8); break;
clock_control_d = value & (1 | 8); case 0xE: clock_control_e = value; break;
break; case 0xF: clock_control_f = value; 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; var bank = clock_control_d & 3;
/* memory access */
if (bank >= 2 && addr < 0x0d) { if (bank >= 2 && addr < 0x0d) {
var ov = rtc_memory[addr];
rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f); rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4); rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
if (rtc_memory[addr] != ov) SAEV_RTC_delayed_write = -1;
//var ov = rtc_memory[addr];
if (rtc_memory[addr] != value) this.write();
return; return;
} }
/* alarm */
if (bank == 1 && addr < 0x0d) { 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[addr] = value;
rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0; rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
rtc_alarm[3] &= ~0x8; rtc_alarm[3] &= ~0x8;
@ -202,34 +309,25 @@ function RTC() {
rtc_alarm[8] &= ~0xc; rtc_alarm[8] &= ~0xc;
rtc_alarm[10] &= ~0xe; rtc_alarm[10] &= ~0xe;
rtc_alarm[11] &= ~0xc; rtc_alarm[11] &= ~0xc;
if (rtc_alarm[addr] != ov) SAEV_RTC_delayed_write = -1;
//var ov = rtc_alarm[addr];
if (rtc_alarm[addr] != value) this.write();
return; return;
} }
if (RTC_DEBUG) SAEF_log("rtc.put8(0x%X, 0x%x)", addr, value);
switch (addr) { switch (addr) {
case 0xD: case 0xD: clock_control_d = value; break;
clock_control_d = value; case 0xE: clock_control_e = value; break;
break; case 0xF: clock_control_f = value; break;
case 0xE:
clock_control_e = value;
break;
case 0xF:
clock_control_f = value;
break;
} }
} }
SAEV_RTC_delayed_write = -1;
};
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_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 | SAE - Scripted Amiga Emulator
* | https://github.com/naTmeg/ScriptedAmigaEmulator
* 2012-2015 Rupert Hausberger |
* | Copyright (C) 2012-2016 Rupert Hausberger
* https://github.com/naTmeg/ScriptedAmigaEmulator |
* | 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() function SAEO_Serial() {
{ const WARN_SERIAL = true;
var buf = new Uint8Array(1024); const DEBUG_SERIAL = 0; /* 0,1,2,3 */
var pos = 0, dtr = false;
var serper = 0, serdat = 0x2000;
this.reset = function () { var inbuf = new Uint8Array(1024);
this.flushBuffer(); 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; 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; serper = 0;
serdat = 0x2000; 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