True up with website.
* Drag and drop support. * Re-enable audio in newer Chrome, Safari * Minimal Printer * Video dirty regions
This commit is contained in:
parent
868923d550
commit
b8261252e3
101
apple2js.html
101
apple2js.html
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html><!-- -*- mode: HTML; indent-tabs-mode: nil -*- -->
|
<!DOCTYPE html>
|
||||||
<!--
|
<!--
|
||||||
Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
|
Copyright 2010-2019 Will Scullin <scullin@scullinsteel.com>
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this software and its
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
documentation for any purpose is hereby granted without fee, provided that
|
documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<title>Apple ][js - An Apple 2 Emulator in JavaScript</title>
|
<title>Apple ][js - An Apple 2 Emulator in JavaScript</title>
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
<meta name="viewport" content="width=640, height=device-height, user-scalable=no" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-title" content="Apple ][js">
|
<meta name="apple-mobile-web-app-title" content="Apple ][js">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
<link rel="apple-touch-icon" href="img/webapp-iphone.png" />
|
<link rel="apple-touch-icon" href="img/webapp-iphone.png" />
|
||||||
<link rel="apple-touch-icon" size="72x72" href="img/webapp-ipad.png" />
|
<link rel="apple-touch-icon" size="72x72" href="img/webapp-ipad.png" />
|
||||||
<link rel="shortcut icon" href="logoicon.png" />
|
<link rel="shortcut icon" href="img/logoicon.png" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/apple2.css" />
|
<link rel="stylesheet" type="text/css" href="css/apple2.css" />
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
href="http://code.jquery.com/ui/1.10.3/themes/mint-choc/jquery-ui.css" />
|
href="http://code.jquery.com/ui/1.10.3/themes/mint-choc/jquery-ui.css" />
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.2/css/all.css" />
|
||||||
|
|
||||||
<meta property="og:title" content="Apple ][js" />
|
<meta property="og:title" content="Apple ][js" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
|
@ -73,10 +74,16 @@
|
||||||
<script type="text/javascript" src="json/disks/index.js"></script>
|
<script type="text/javascript" src="json/disks/index.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="apple2"
|
||||||
<div style="margin: auto; width: 604px">
|
ondragover="handleDragOver(0, event)"
|
||||||
|
ondrop="handleDrop(0, event)"
|
||||||
|
ondragend="handleDragEnd(0, event)">
|
||||||
|
<div id="fb-root"></div>
|
||||||
|
<div style="margin: auto; width: 614px">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<a href="http://www.w3.org/html/logo/"><img src="http://www.w3.org/html/logo/badge/html5-badge-h-solo.png" width="63" height="64" alt="HTML5 Powered" title="HTML5 Powered" style="float: right"></a>
|
<a href="//www.w3.org/html/logo/" target="_blank">
|
||||||
|
<img src="//www.w3.org/html/logo/badge/html5-badge-h-solo.png" style="float: right" />
|
||||||
|
</a>
|
||||||
<a href="about.html" target="_blank">
|
<a href="about.html" target="_blank">
|
||||||
<img src="img/badge.png" id="badge" />
|
<img src="img/badge.png" id="badge" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -88,43 +95,60 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inset">
|
<div class="inset">
|
||||||
<div style="float: left; width: 50%">
|
<div style="float: left; width: 50%"
|
||||||
|
ondragover="handleDragOver(1, event)"
|
||||||
|
ondrop="handleDrop(1, event)"
|
||||||
|
ondragend="handleDragEnd(2, event)">
|
||||||
|
<button id="diskload1" class="diskload" title="Load Disk"
|
||||||
|
onclick="openLoad(1, event);">
|
||||||
|
<i class="fas fa-folder-open"></i>
|
||||||
|
</button>
|
||||||
|
<button id="disksave1" class="disksave" title="Save Disk"
|
||||||
|
onclick="openSave(1, event);">
|
||||||
|
<i class="fas fa-save"></i>
|
||||||
|
</button>
|
||||||
<div class="disk" id="disk1"> </div>
|
<div class="disk" id="disk1"> </div>
|
||||||
<span id="disklabel1" class="disklabel">Disk 1</span>
|
<span id="disklabel1" class="disklabel">Disk 1</span>
|
||||||
<button id="diskload1" class="diskload" value="Load"
|
|
||||||
onclick="openLoad(1, event);">
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button id="disksave1" class="disksave" value="Save"
|
|
||||||
onclick="openSave(1, event);">
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="float: left; width: 50%">
|
<div style="float: left; width: 50%"
|
||||||
|
ondragover="handleDragOver(2, event)"
|
||||||
|
ondrop="handleDrop(2, event)"
|
||||||
|
ondragend="handleDragEnd(2, event)">
|
||||||
|
<button id="diskload2" class="diskload" title="Load Disk"
|
||||||
|
onclick="openLoad(2, event);">
|
||||||
|
<i class="fas fa-folder-open"></i>
|
||||||
|
</button>
|
||||||
|
<button id="disksave2" class="disksave" title="Save Disk"
|
||||||
|
onclick="openSave(2, event);">
|
||||||
|
<i class="fas fa-save"></i>
|
||||||
|
</button>
|
||||||
<div class="disk" id="disk2"> </div>
|
<div class="disk" id="disk2"> </div>
|
||||||
<span id="disklabel2" class="disklabel">Disk 2</span>
|
<span id="disklabel2" class="disklabel">Disk 2</span>
|
||||||
<button id="diskload2" class="diskload" value="Load"
|
|
||||||
onclick="openLoad(2, event);">
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button id="disksave2" class="disksave" value="Save"
|
|
||||||
onclick="openSave(2, event);">
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="clear: both"></div>
|
<div style="clear: both"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inset">
|
<div class="inset">
|
||||||
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
|
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
|
||||||
<input type="button" value="Pause" onclick="pauseRun(this)" />
|
<button id="pause-run" onclick="pauseRun()" title="Pause/Run">
|
||||||
|
<i class="fas fa-pause"></i>
|
||||||
|
</button>
|
||||||
|
<button id="toggle-sound" onclick="toggleSound()" title="Toggle Sound">
|
||||||
|
<i class="fas fa-volume-off"></i>
|
||||||
|
</button>
|
||||||
|
<button id="toggle-printer" onclick="$('#printer').dialog('open')" title="Toggle Printer">
|
||||||
|
<i class="fas fa-print"></i>
|
||||||
|
</button>
|
||||||
<div style="float: right">
|
<div style="float: right">
|
||||||
<input type="button" onclick="window.open('about.html','_html')"
|
<a class="button" href="about.html" target="_blank" title="About">
|
||||||
name="About" value="About">
|
<i class="fas fa-info"></i>
|
||||||
<input type="button" onclick="$('#options').dialog('open')"
|
</a>
|
||||||
name="Options" value="Options">
|
<button onclick="$('#options').dialog('open')" title="Options">
|
||||||
|
<i class="fas fa-cog"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inset">
|
<div class="inset">
|
||||||
|
<div style="margin: 0 10px">
|
||||||
<div id="keyboard"></div>
|
<div id="keyboard"></div>
|
||||||
<div id="textarea" style="display: none">
|
<div id="textarea" style="display: none">
|
||||||
<button onclick="io.keyDown(0x1b)">
|
<button onclick="io.keyDown(0x1b)">
|
||||||
|
@ -158,7 +182,7 @@
|
||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
<div id="options" title="Options" style="display: none">
|
<div id="options" title="Options" style="display: none">
|
||||||
<h3>CPU</h3>
|
<h3>Type</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<select id="computer_type2" value="apple2plus" onchange="updateCPU()">
|
<select id="computer_type2" value="apple2plus" onchange="updateCPU()">
|
||||||
|
@ -166,10 +190,13 @@
|
||||||
<option value="apple2">Autostart Apple ][</option>
|
<option value="apple2">Autostart Apple ][</option>
|
||||||
<option value="original">Apple ][</option>
|
<option value="original">Apple ][</option>
|
||||||
</select>
|
</select>
|
||||||
<label for="computer_type2">
|
|
||||||
Type
|
|
||||||
</label>
|
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<i>* Reload page to take effect</i>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>CPU</h3>
|
||||||
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="accelerator_toggle" onclick="updateCPU()"/>
|
<input type="checkbox" id="accelerator_toggle" onclick="updateCPU()"/>
|
||||||
<label for="accelerator_toggle">
|
<label for="accelerator_toggle">
|
||||||
|
@ -279,6 +306,10 @@
|
||||||
<input type="file" id="local_file" />
|
<input type="file" id="local_file" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="js/main2.js"></script>
|
<div id="printer" title="Printer" style="display: none">
|
||||||
|
<div class="paper">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="js/main2.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
105
apple2jse.html
105
apple2jse.html
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE html><!-- -*- mode: HTML; indent-tabs-mode: nil -*- -->
|
<!DOCTYPE html>
|
||||||
<!--
|
<!--
|
||||||
Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
|
Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<title>Apple //jse - An Apple //e Emulator in JavaScript</title>
|
<title>Apple //jse - An Apple //e Emulator in JavaScript</title>
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no" />
|
<meta name="viewport" content="width=640 user-scalable=0" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-title" content="Apple //jse">
|
<meta name="apple-mobile-web-app-title" content="Apple //jse">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
<link rel="apple-touch-icon" href="img/webapp-iphone.png" />
|
<link rel="apple-touch-icon" href="img/webapp-iphone.png" />
|
||||||
<link rel="apple-touch-icon" size="72x72" href="img/webapp-ipad.png" />
|
<link rel="apple-touch-icon" size="72x72" href="img/webapp-ipad.png" />
|
||||||
<link rel="shortcut icon" href="logoicon.png" />
|
<link rel="shortcut icon" href="img/logoicon.png" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/apple2.css" />
|
<link rel="stylesheet" type="text/css" href="css/apple2.css" />
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
href="http://code.jquery.com/ui/1.10.3/themes/mint-choc/jquery-ui.css" />
|
href="http://code.jquery.com/ui/1.10.3/themes/mint-choc/jquery-ui.css" />
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.2/css/all.css" />
|
||||||
|
|
||||||
<meta property="og:title" content="Apple //js" />
|
<meta property="og:title" content="Apple //js" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
|
@ -72,12 +73,17 @@
|
||||||
<script type="text/javascript" src="json/disks/index.js"></script>
|
<script type="text/javascript" src="json/disks/index.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="apple2e">
|
<body class="apple2e"
|
||||||
<div style="margin: auto; width: 604px">
|
ondragover="handleDragOver(0, event)"
|
||||||
|
ondrop="handleDrop(0, event)"
|
||||||
|
ondragend="handleDragEnd(0, event)">
|
||||||
|
<div class="outer">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<a href="http://www.w3.org/html/logo/"><img src="http://www.w3.org/html/logo/badge/html5-badge-h-solo.png" width="63" height="64" alt="HTML5 Powered" title="HTML5 Powered" style="float: right"></a>
|
<a href="//www.w3.org/html/logo/" target="_blank">
|
||||||
|
<img src="//www.w3.org/html/logo/badge/html5-badge-h-solo.png" style="float: right" />
|
||||||
|
</a>
|
||||||
<a href="about.html" target="_blank">
|
<a href="about.html" target="_blank">
|
||||||
<img src="img/badge.png" id="badge" />
|
<img src="img/badge2e.png" id="badge" />
|
||||||
</a>
|
</a>
|
||||||
<h1 id="subtitle">An Apple //e Emulator in JavaScript</h1>
|
<h1 id="subtitle">An Apple //e Emulator in JavaScript</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -89,44 +95,62 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inset">
|
<div class="inset">
|
||||||
<div style="float: left; width: 50%">
|
<div style="float: left; width: 50%"
|
||||||
|
ondragover="handleDragOver(1, event)"
|
||||||
|
ondrop="handleDrop(1, event)"
|
||||||
|
ondragend="handleDragEnd(1, event)">
|
||||||
|
<button id="diskload1" class="diskload" title="Load Disk"
|
||||||
|
onclick="openLoad(1, event);">
|
||||||
|
<i class="fas fa-folder-open"></i>
|
||||||
|
</button>
|
||||||
|
<button id="disksave1" class="disksave" title="Save Disk"
|
||||||
|
onclick="openSave(1, event);">
|
||||||
|
<i class="fas fa-save"></i>
|
||||||
|
</button>
|
||||||
<div class="disk" id="disk1"> </div>
|
<div class="disk" id="disk1"> </div>
|
||||||
<span id="disklabel1" class="disklabel">Disk 1</span>
|
<span id="disklabel1" class="disklabel">Disk 1</span>
|
||||||
<button id="diskload1" class="diskload" value="Load"
|
|
||||||
onclick="openLoad(1, event);">
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button id="disksave1" class="disksave" value="Save"
|
|
||||||
onclick="openSave(1, event);">
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="float: left; width: 50%">
|
<div style="float: left; width: 50%"
|
||||||
|
ondragover="handleDragOver(2, event)"
|
||||||
|
ondrop="handleDrop(2, event)"
|
||||||
|
ondragend="handleDragEnd(2, event)">
|
||||||
|
<button id="diskload2" class="diskload" title="Load Disk"
|
||||||
|
onclick="openLoad(2, event);">
|
||||||
|
<i class="fas fa-folder-open"></i>
|
||||||
|
</button>
|
||||||
|
<button id="disksave2" class="disksave" title="Save Disk"
|
||||||
|
onclick="openSave(2, event);">
|
||||||
|
<i class="fas fa-save"></i>
|
||||||
|
</button>
|
||||||
<div class="disk" id="disk2"> </div>
|
<div class="disk" id="disk2"> </div>
|
||||||
<span id="disklabel2" class="disklabel">Disk 2</span>
|
<span id="disklabel2" class="disklabel">Disk 2</span>
|
||||||
<button id="diskload2" class="diskload" value="Load"
|
|
||||||
onclick="openLoad(2, event);">
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button id="disksave2" class="disksave" value="Save"
|
|
||||||
onclick="openSave(2, event);">
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="clear: both"></div>
|
<div style="clear: both"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="position: relative">
|
<div style="position: relative">
|
||||||
<div id="controls" class="inset">
|
<div id="controls" class="inset">
|
||||||
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
|
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
|
||||||
<input type="button" value="Pause" onclick="pauseRun(this)" />
|
<button id="pause-run" onclick="pauseRun()">
|
||||||
|
<i class="fas fa-pause"></i>
|
||||||
|
</button>
|
||||||
|
<button id="toggle-sound" onclick="toggleSound()">
|
||||||
|
<i class="fas fa-volume-off"></i>
|
||||||
|
</button>
|
||||||
|
<button id="toggle-printer" onclick="$('#printer').dialog('open')" title="Toggle Printer">
|
||||||
|
<i class="fas fa-print"></i>
|
||||||
|
</button>
|
||||||
<div style="float: right">
|
<div style="float: right">
|
||||||
<input type="button" onclick="window.open('about.html','_html')"
|
<a class="button" href="about.html" target="_blank" title="About">
|
||||||
name="About" value="About">
|
<i class="fas fa-info"></i>
|
||||||
<input type="button" onclick="$('#options').dialog('open')"
|
</a>
|
||||||
name="Options" value="Options">
|
<button onclick="$('#options').dialog('open')">
|
||||||
|
<i class="fas fa-cog"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input id="reset" type="button" value="Reset" onclick="reset()" />
|
<input id="reset" type="button" value="Reset"
|
||||||
|
onclick="keyboard.reset(event)"
|
||||||
|
oncontextmenu="keyboard.reset(event)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inset">
|
<div class="inset">
|
||||||
<div id="keyboard"></div>
|
<div id="keyboard"></div>
|
||||||
|
@ -136,17 +160,20 @@
|
||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
<div id="options" title="Options" style="display: none">
|
<div id="options" title="Options" style="display: none">
|
||||||
<h3>CPU</h3>
|
<h3>Type</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<select id="computer_type2e" value="apple2enh" onchange="updateCPU()">
|
<select id="computer_type2e" value="apple2enh" onchange="updateCPU()">
|
||||||
<option value="apple2enh">Enhanced Apple //e</option>
|
<option value="apple2enh">Enhanced Apple //e</option>
|
||||||
<option value="apple2e">Apple //e</option>
|
<option value="apple2e">Apple //e</option>
|
||||||
</select>
|
</select>
|
||||||
<label for="computer_type2e">
|
|
||||||
Type
|
|
||||||
</label>
|
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<i>* Reload page to take effect</i>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>CPU</h3>
|
||||||
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input type="checkbox" id="accelerator_toggle" onclick="updateCPU()"/>
|
<input type="checkbox" id="accelerator_toggle" onclick="updateCPU()"/>
|
||||||
<label for="accelerator_toggle">
|
<label for="accelerator_toggle">
|
||||||
|
@ -229,7 +256,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="manage" title="Manage Disks" style="display: none">
|
<div id="manage" title="Manage Disks" style="display: none">
|
||||||
</div>
|
</div>
|
||||||
<div id="http_load" title="Load URL">
|
<div id="http_load" title="Load URL" style="display: none">
|
||||||
<form action="#">
|
<form action="#">
|
||||||
<input type="text" id="http_url" style="width: 500px"/>
|
<input type="text" id="http_url" style="width: 500px"/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -256,6 +283,10 @@
|
||||||
<input type="file" id="local_file" />
|
<input type="file" id="local_file" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="js/main2e.js"></script>
|
<div id="printer" title="Printer" style="display: none">
|
||||||
|
<div class="paper">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="js/main2e.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 838 B |
|
@ -120,25 +120,25 @@ function Apple2IO(cpu, callbacks)
|
||||||
var delta = now - _trigger;
|
var delta = now - _trigger;
|
||||||
switch (off) {
|
switch (off) {
|
||||||
case LOC.CLR80VID:
|
case LOC.CLR80VID:
|
||||||
if ('_80col' in callbacks && val !== undefined) {
|
if (callbacks._80col && val !== undefined) {
|
||||||
_debug('80 Column Mode off');
|
_debug('80 Column Mode off');
|
||||||
callbacks._80col(false);
|
callbacks._80col(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.SET80VID:
|
case LOC.SET80VID:
|
||||||
if ('_80col' in callbacks && val !== undefined) {
|
if (callbacks._80col && val !== undefined) {
|
||||||
_debug('80 Column Mode on');
|
_debug('80 Column Mode on');
|
||||||
callbacks._80col(true);
|
callbacks._80col(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.CLRALTCH:
|
case LOC.CLRALTCH:
|
||||||
if ('altchar' in callbacks && val !== undefined) {
|
if (callbacks.altchar && val !== undefined) {
|
||||||
_debug('Alt Char off');
|
_debug('Alt Char off');
|
||||||
callbacks.altchar(false);
|
callbacks.altchar(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.SETALTCH:
|
case LOC.SETALTCH:
|
||||||
if ('altchar' in callbacks && val !== undefined) {
|
if (callbacks.altchar && val !== undefined) {
|
||||||
_debug('Alt Char on');
|
_debug('Alt Char on');
|
||||||
callbacks.altchar(true);
|
callbacks.altchar(true);
|
||||||
}
|
}
|
||||||
|
@ -174,27 +174,27 @@ function Apple2IO(cpu, callbacks)
|
||||||
callbacks.page(2);
|
callbacks.page(2);
|
||||||
break;
|
break;
|
||||||
case LOC.RDTEXT:
|
case LOC.RDTEXT:
|
||||||
if ('isText' in callbacks)
|
if (callbacks.isText)
|
||||||
result = callbacks.isText() ? 0x80 : 0x0;
|
result = callbacks.isText() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.RDMIXED:
|
case LOC.RDMIXED:
|
||||||
if ('isMixed' in callbacks)
|
if (callbacks.isText)
|
||||||
result = callbacks.isMixed() ? 0x80 : 0x0;
|
result = callbacks.isText() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.RDPAGE2:
|
case LOC.RDPAGE2:
|
||||||
if ('isPage2' in callbacks)
|
if (callbacks.isPage2)
|
||||||
result = callbacks.isPage2() ? 0x80 : 0x0;
|
result = callbacks.isPage2() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.RDHIRES:
|
case LOC.RDHIRES:
|
||||||
if ('isHires' in callbacks)
|
if (callbacks.isHires)
|
||||||
result = callbacks.isHires() ? 0x80 : 0x0;
|
result = callbacks.isHires() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.RD80VID:
|
case LOC.RD80VID:
|
||||||
if ('is80Col' in callbacks)
|
if (callbacks.is80Col)
|
||||||
result = callbacks.is80Col() ? 0x80 : 0x0;
|
result = callbacks.is80Col() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.RDALTCH:
|
case LOC.RDALTCH:
|
||||||
if ('isAltChar' in callbacks)
|
if (callbacks.isAltChar)
|
||||||
result = callbacks.isAltChar() ? 0x80 : 0x0;
|
result = callbacks.isAltChar() ? 0x80 : 0x0;
|
||||||
break;
|
break;
|
||||||
case LOC.SETAN0:
|
case LOC.SETAN0:
|
||||||
|
@ -212,7 +212,7 @@ function Apple2IO(cpu, callbacks)
|
||||||
case LOC.SETAN3:
|
case LOC.SETAN3:
|
||||||
_debug('Annunciator 3 on');
|
_debug('Annunciator 3 on');
|
||||||
_annunciators[3] = true;
|
_annunciators[3] = true;
|
||||||
if ('doublehires' in callbacks) callbacks.doublehires(false);
|
if (callbacks.doublehires) callbacks.doublehires(false);
|
||||||
break;
|
break;
|
||||||
case LOC.CLRAN0:
|
case LOC.CLRAN0:
|
||||||
_debug('Annunciator 0 off');
|
_debug('Annunciator 0 off');
|
||||||
|
@ -229,7 +229,7 @@ function Apple2IO(cpu, callbacks)
|
||||||
case LOC.CLRAN3:
|
case LOC.CLRAN3:
|
||||||
_debug('Annunciator 3 off');
|
_debug('Annunciator 3 off');
|
||||||
_annunciators[3] = false;
|
_annunciators[3] = false;
|
||||||
if ('doublehires' in callbacks) callbacks.doublehires(true);
|
if (callbacks.doublehires) callbacks.doublehires(true);
|
||||||
break;
|
break;
|
||||||
case LOC.SPEAKER:
|
case LOC.SPEAKER:
|
||||||
_phase = -_phase;
|
_phase = -_phase;
|
||||||
|
@ -275,12 +275,11 @@ function Apple2IO(cpu, callbacks)
|
||||||
_trigger = cpu.cycles();
|
_trigger = cpu.cycles();
|
||||||
break;
|
break;
|
||||||
case LOC.RDDHIRES:
|
case LOC.RDDHIRES:
|
||||||
if ('isDoubleHires' in callbacks) {
|
if (callbacks.isDoubleHires) {
|
||||||
result = callbacks.isDoubleHires() ? 0x80 : 0x0;
|
result = callbacks.isDoubleHires() ? 0x80 : 0x0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.TAPEIN:
|
case LOC.TAPEIN:
|
||||||
// var flipped = false;
|
|
||||||
if (_tapeOffset == -1) {
|
if (_tapeOffset == -1) {
|
||||||
_tapeOffset = 0;
|
_tapeOffset = 0;
|
||||||
_tapeNext = now;
|
_tapeNext = now;
|
||||||
|
@ -339,6 +338,7 @@ function Apple2IO(cpu, callbacks)
|
||||||
card.reset();
|
card.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
callbacks.reset();
|
||||||
},
|
},
|
||||||
|
|
||||||
read: function apple2io_read(page, off) {
|
read: function apple2io_read(page, off) {
|
||||||
|
@ -472,8 +472,13 @@ function Apple2IO(cpu, callbacks)
|
||||||
_cycles_per_sample = _hz / _rate;
|
_cycles_per_sample = _hz / _rate;
|
||||||
},
|
},
|
||||||
|
|
||||||
sampleTick: function sampleTick() {
|
tick: function tick() {
|
||||||
_tick();
|
_tick();
|
||||||
|
for (var idx = 0; idx < 8; idx++) {
|
||||||
|
if (_slot[idx] && _slot[idx].tick) {
|
||||||
|
_slot[idx].tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addSampleListener: function addSampleListener(cb) {
|
addSampleListener: function addSampleListener(cb) {
|
||||||
|
@ -482,6 +487,10 @@ function Apple2IO(cpu, callbacks)
|
||||||
|
|
||||||
annunciator: function annunciator(idx) {
|
annunciator: function annunciator(idx) {
|
||||||
return _annunciators[idx];
|
return _annunciators[idx];
|
||||||
|
},
|
||||||
|
|
||||||
|
cycles: function apple2io_cycles() {
|
||||||
|
return cpu.cycles();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
94
js/canvas.js
94
js/canvas.js
|
@ -66,6 +66,12 @@ function LoresPage(page, charset, e, context)
|
||||||
var _refreshing = false;
|
var _refreshing = false;
|
||||||
var _greenMode = false;
|
var _greenMode = false;
|
||||||
var _blink = false;
|
var _blink = false;
|
||||||
|
var _dirty = {
|
||||||
|
top: 385,
|
||||||
|
bottom: -1,
|
||||||
|
left: 561,
|
||||||
|
right: -1
|
||||||
|
};
|
||||||
|
|
||||||
var _green = [0x00,0xff,0x80];
|
var _green = [0x00,0xff,0x80];
|
||||||
|
|
||||||
|
@ -204,6 +210,15 @@ function LoresPage(page, charset, e, context)
|
||||||
|
|
||||||
var data = _imageData.data;
|
var data = _imageData.data;
|
||||||
if ((row < 24) && (col < 40)) {
|
if ((row < 24) && (col < 40)) {
|
||||||
|
var y = row * 16;
|
||||||
|
if (y < _dirty.top) { _dirty.top = y; }
|
||||||
|
y += 16;
|
||||||
|
if (y > _dirty.bottom) { _dirty.bottom = y; }
|
||||||
|
var x = col * 14;
|
||||||
|
if (x < _dirty.left) { _dirty.left = x; }
|
||||||
|
x += 14;
|
||||||
|
if (x > _dirty.right) { _dirty.right = x; }
|
||||||
|
|
||||||
var color;
|
var color;
|
||||||
if (textMode || hiresMode || (mixedMode && row > 19)) {
|
if (textMode || hiresMode || (mixedMode && row > 19)) {
|
||||||
var inverse;
|
var inverse;
|
||||||
|
@ -400,11 +415,26 @@ function LoresPage(page, charset, e, context)
|
||||||
this.refresh();
|
this.refresh();
|
||||||
},
|
},
|
||||||
blit: function(mixed) {
|
blit: function(mixed) {
|
||||||
|
if (_dirty.top === 385) { return false; }
|
||||||
|
var top = _dirty.top;
|
||||||
|
var bottom = _dirty.bottom;
|
||||||
|
var left = _dirty.left;
|
||||||
|
var right = _dirty.right;
|
||||||
|
|
||||||
if (mixed) {
|
if (mixed) {
|
||||||
context.putImageData(_imageData, 0, 0, 0, 320, 560, 64);
|
if (bottom < 320) { return false; }
|
||||||
} else {
|
if (top < 320) { top = 320; }
|
||||||
context.putImageData(_imageData, 0, 0, 0, 0, 560, 384);
|
|
||||||
}
|
}
|
||||||
|
context.putImageData(
|
||||||
|
_imageData, 0, 0, left, top, right - left, bottom - top
|
||||||
|
);
|
||||||
|
_dirty = {
|
||||||
|
top: 385,
|
||||||
|
bottom: -1,
|
||||||
|
left: 561,
|
||||||
|
right: -1
|
||||||
|
};
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -455,6 +485,12 @@ function HiresPage(page, context)
|
||||||
|
|
||||||
var _page = page;
|
var _page = page;
|
||||||
var _imageData;
|
var _imageData;
|
||||||
|
var _dirty = {
|
||||||
|
top: 385,
|
||||||
|
bottom: -1,
|
||||||
|
left: 561,
|
||||||
|
right: -1
|
||||||
|
};
|
||||||
|
|
||||||
var r4 = [
|
var r4 = [
|
||||||
0, // Black
|
0, // Black
|
||||||
|
@ -627,6 +663,15 @@ function HiresPage(page, context)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var y = rowa * 16 + rowb * 2;
|
||||||
|
if (y < _dirty.top) { _dirty.top = y; }
|
||||||
|
y += 2;
|
||||||
|
if (y > _dirty.bottom) { _dirty.bottom = y; }
|
||||||
|
var x = col * 14;
|
||||||
|
if (x < _dirty.left) { _dirty.left = x; }
|
||||||
|
x += 14;
|
||||||
|
if (x > _dirty.right) { _dirty.right = x; }
|
||||||
|
|
||||||
dy = rowa * 16 + rowb * 2;
|
dy = rowa * 16 + rowb * 2;
|
||||||
var bz, b0, b1, b2, b3, b4, c, hb;
|
var bz, b0, b1, b2, b3, b4, c, hb;
|
||||||
if (doubleHiresMode) {
|
if (doubleHiresMode) {
|
||||||
|
@ -813,11 +858,26 @@ function HiresPage(page, context)
|
||||||
this.refresh();
|
this.refresh();
|
||||||
},
|
},
|
||||||
blit: function(mixed) {
|
blit: function(mixed) {
|
||||||
|
if (_dirty.top === 385) { return false; }
|
||||||
|
var top = _dirty.top;
|
||||||
|
var bottom = _dirty.bottom;
|
||||||
|
var left = _dirty.left;
|
||||||
|
var right = _dirty.right;
|
||||||
|
|
||||||
if (mixed) {
|
if (mixed) {
|
||||||
context.putImageData(_imageData, 0, 0, 0, 0, 560, 320);
|
if (top > 320) { return false; }
|
||||||
} else {
|
if (bottom > 320) { bottom = 320; }
|
||||||
context.putImageData(_imageData, 0, 0, 0, 0, 560, 384);
|
|
||||||
}
|
}
|
||||||
|
context.putImageData(
|
||||||
|
_imageData, 0, 0, left, top, right - left, bottom - top
|
||||||
|
);
|
||||||
|
_dirty = {
|
||||||
|
top: 385,
|
||||||
|
bottom: -1,
|
||||||
|
left: 561,
|
||||||
|
right: -1
|
||||||
|
};
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
return this._start();
|
return this._start();
|
||||||
|
@ -986,7 +1046,11 @@ function VideoModes(gr, hgr, gr2, hgr2, e) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
page: function(pageNo) {
|
page: function(pageNo) {
|
||||||
|
var old = pageMode;
|
||||||
pageMode = pageNo;
|
pageMode = pageNo;
|
||||||
|
if (old != pageNo) {
|
||||||
|
_refresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
isText: function() {
|
isText: function() {
|
||||||
return textMode;
|
return textMode;
|
||||||
|
@ -1007,23 +1071,25 @@ function VideoModes(gr, hgr, gr2, hgr2, e) {
|
||||||
return altCharMode;
|
return altCharMode;
|
||||||
},
|
},
|
||||||
blit: function() {
|
blit: function() {
|
||||||
|
var blitted = false;
|
||||||
if (multiScreen) {
|
if (multiScreen) {
|
||||||
_grs[0].blit();
|
blitted = _grs[0].blit() || blitted;
|
||||||
_grs[1].blit();
|
blitted = _grs[1].blit() || blitted;
|
||||||
_hgrs[0].blit();
|
blitted = _hgrs[0].blit() || blitted;
|
||||||
_hgrs[1].blit();
|
blitted = _hgrs[1].blit() || blitted;
|
||||||
} else {
|
} else {
|
||||||
if (hiresMode && !textMode) {
|
if (hiresMode && !textMode) {
|
||||||
if (mixedMode) {
|
if (mixedMode) {
|
||||||
_grs[pageMode - 1].blit(true);
|
blitted = _grs[pageMode - 1].blit(true) || blitted;
|
||||||
_hgrs[pageMode - 1].blit(true);
|
blitted = _hgrs[pageMode - 1].blit(true) || blitted;
|
||||||
} else {
|
} else {
|
||||||
_hgrs[pageMode - 1].blit();
|
blitted = _hgrs[pageMode - 1].blit();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_grs[pageMode - 1].blit();
|
blitted = _grs[pageMode - 1].blit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return blitted;
|
||||||
},
|
},
|
||||||
getState: function() {
|
getState: function() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -59,12 +59,14 @@ function Parallel(io, slot, cbs) {
|
||||||
];
|
];
|
||||||
|
|
||||||
function _access(off, val) {
|
function _access(off, val) {
|
||||||
switch (off) {
|
switch (off & 0x8f) {
|
||||||
case LOC.IOREG:
|
case LOC.IOREG:
|
||||||
if (val && 'putChar' in cbs) {
|
if (cbs.putChar && val) {
|
||||||
cbs.putChar(val);
|
cbs.putChar(val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
debug('Parallel card unknown softswitch', off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -463,6 +463,7 @@ function Videoterm(io, slot, context) {
|
||||||
var _bank = 0;
|
var _bank = 0;
|
||||||
var _buffer = allocMemPages(8);
|
var _buffer = allocMemPages(8);
|
||||||
var _imageData;
|
var _imageData;
|
||||||
|
var _dirty = false;
|
||||||
|
|
||||||
var _black = [0x00, 0x00, 0x00];
|
var _black = [0x00, 0x00, 0x00];
|
||||||
var _white = [0xff, 0xff, 0xff];
|
var _white = [0xff, 0xff, 0xff];
|
||||||
|
@ -500,6 +501,7 @@ function Videoterm(io, slot, context) {
|
||||||
var color;
|
var color;
|
||||||
|
|
||||||
if (row < 25) {
|
if (row < 25) {
|
||||||
|
_dirty = true;
|
||||||
for (var idx = 0; idx < 8; idx++) {
|
for (var idx = 0; idx < 8; idx++) {
|
||||||
var cdata = VIDEO_ROM[c + idx];
|
var cdata = VIDEO_ROM[c + idx];
|
||||||
for (var jdx = 0; jdx < 7; jdx++) {
|
for (var jdx = 0; jdx < 7; jdx++) {
|
||||||
|
@ -543,6 +545,7 @@ function Videoterm(io, slot, context) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_blink || (blinkmode === CURSOR_MODES.SOLID)) {
|
if (_blink || (blinkmode === CURSOR_MODES.SOLID)) {
|
||||||
|
_dirty = true;
|
||||||
for (var idx = 0; idx < 8; idx++) {
|
for (var idx = 0; idx < 8; idx++) {
|
||||||
var color = _white;
|
var color = _white;
|
||||||
if (idx >= (_regs[REGS.CURSOR_UPPER] & 0x1f) &&
|
if (idx >= (_regs[REGS.CURSOR_UPPER] & 0x1f) &&
|
||||||
|
@ -641,7 +644,12 @@ function Videoterm(io, slot, context) {
|
||||||
_refresh();
|
_refresh();
|
||||||
_shouldRefresh = false;
|
_shouldRefresh = false;
|
||||||
}
|
}
|
||||||
|
if (_dirty) {
|
||||||
context.putImageData(_imageData, 0, 0);
|
context.putImageData(_imageData, 0, 0);
|
||||||
|
_dirty = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*!
|
/*!
|
||||||
* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
|
* Copyright 2010-2019 Will Scullin <scullin@scullinsteel.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
|
129
js/main2.js
129
js/main2.js
|
@ -23,7 +23,7 @@
|
||||||
ApplesoftDump: false, SYMBOLS: false,
|
ApplesoftDump: false, SYMBOLS: false,
|
||||||
multiScreen: true
|
multiScreen: true
|
||||||
*/
|
*/
|
||||||
/* exported openLoad, openSave, doDelete,
|
/* exported openLoad, openSave, doDelete, handleDragOver, handleDragEnd, handleDrop,
|
||||||
selectCategory, selectDisk, clickDisk,
|
selectCategory, selectDisk, clickDisk,
|
||||||
multiScreen,
|
multiScreen,
|
||||||
updateJoystick,
|
updateJoystick,
|
||||||
|
@ -94,12 +94,9 @@ function DriveLights()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
driveLight: function(drive, on) {
|
driveLight: function(drive, on) {
|
||||||
$('#disk' + drive).css(
|
$('#disk' + drive).css('background-image',
|
||||||
'background-image',
|
on ? 'url(css/red-on-16.png)' :
|
||||||
on ?
|
'url(css/red-off-16.png)');
|
||||||
'url(css/red-on-16.png)' :
|
|
||||||
'url(css/red-off-16.png)'
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
dirty: function() {
|
dirty: function() {
|
||||||
// $('#disksave' + drive).button('option', 'disabled', !dirty);
|
// $('#disksave' + drive).button('option', 'disabled', !dirty);
|
||||||
|
@ -165,6 +162,54 @@ function openSave(drive, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDragOver(drive, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragEnd(drive, event) {
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.items) {
|
||||||
|
for (var i = 0; i < dt.items.length; i++) {
|
||||||
|
dt.items.remove(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.dataTransfer.clearData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDrop(drive, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if (drive < 1) {
|
||||||
|
if (!disk2.getMetadata(1)) {
|
||||||
|
drive = 1;
|
||||||
|
} else if (!disk2.getMetadata(2)) {
|
||||||
|
drive = 2;
|
||||||
|
} else {
|
||||||
|
drive = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.files.length == 1) {
|
||||||
|
doLoadLocal(drive, dt.files[0]);
|
||||||
|
} else if (dt.files.length == 2) {
|
||||||
|
doLoadLocal(1, dt.files[0]);
|
||||||
|
doLoadLocal(2, dt.files[1]);
|
||||||
|
} else {
|
||||||
|
for (var idx = 0; idx < dt.items.length; idx++) {
|
||||||
|
if (dt.items[idx].type === 'text/uri-list') {
|
||||||
|
dt.items[idx].getAsString(function(url) {
|
||||||
|
var parts = document.location.hash.split('|');
|
||||||
|
parts[drive - 1] = url;
|
||||||
|
document.location.hash = parts.join('|');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var loading = false;
|
var loading = false;
|
||||||
|
|
||||||
function loadAjax(drive, url) {
|
function loadAjax(drive, url) {
|
||||||
|
@ -378,8 +423,10 @@ var io = new Apple2IO(cpu, vm);
|
||||||
var keyboard = new KeyBoard(io);
|
var keyboard = new KeyBoard(io);
|
||||||
var audio = new Audio(io);
|
var audio = new Audio(io);
|
||||||
var tape = new Tape(io);
|
var tape = new Tape(io);
|
||||||
|
var printer = new Printer($('#printer .paper'));
|
||||||
|
|
||||||
var lc = new LanguageCard(io, 0, rom);
|
var lc = new LanguageCard(io, 0, rom);
|
||||||
var parallel = new Parallel(io, 1, new Printer());
|
var parallel = new Parallel(io, 1, printer);
|
||||||
var slinky = new RAMFactor(io, 2, 1024 * 1024);
|
var slinky = new RAMFactor(io, 2, 1024 * 1024);
|
||||||
var videoterm = new Videoterm(io, 3, context1);
|
var videoterm = new Videoterm(io, 3, context1);
|
||||||
var disk2 = new DiskII(io, 6, drivelights);
|
var disk2 = new DiskII(io, 6, drivelights);
|
||||||
|
@ -426,7 +473,14 @@ function updateKHz() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSound() {
|
function updateSound() {
|
||||||
audio.enable($('#enable_sound').attr('checked'));
|
var on = $('#enable_sound').prop('checked');
|
||||||
|
var label = $('#toggle-sound i');
|
||||||
|
audio.enable(on);
|
||||||
|
if (on) {
|
||||||
|
label.removeClass('fa-volume-off').addClass('fa-volume-up');
|
||||||
|
} else {
|
||||||
|
label.removeClass('fa-volume-up').addClass('fa-volume-off');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dumpDisk(drive) {
|
function dumpDisk(drive) {
|
||||||
|
@ -492,7 +546,6 @@ function run(pc) {
|
||||||
var now, last = Date.now();
|
var now, last = Date.now();
|
||||||
var runFn = function() {
|
var runFn = function() {
|
||||||
now = Date.now();
|
now = Date.now();
|
||||||
renderedFrames++;
|
|
||||||
|
|
||||||
var step = (now - last) * kHz, stepMax = kHz * ival;
|
var step = (now - last) * kHz, stepMax = kHz * ival;
|
||||||
last = now;
|
last = now;
|
||||||
|
@ -528,11 +581,15 @@ function run(pc) {
|
||||||
if (multiScreen) {
|
if (multiScreen) {
|
||||||
vm.blit();
|
vm.blit();
|
||||||
}
|
}
|
||||||
videoterm.blit();
|
if (videoterm.blit()) {
|
||||||
} else {
|
renderedFrames++;
|
||||||
vm.blit();
|
|
||||||
}
|
}
|
||||||
io.sampleTick();
|
} else {
|
||||||
|
if (vm.blit()) {
|
||||||
|
renderedFrames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
processGamepad(io);
|
processGamepad(io);
|
||||||
|
@ -691,8 +748,8 @@ function updateLocalStorage() {
|
||||||
cat.push({
|
cat.push({
|
||||||
'category': 'Local Saves',
|
'category': 'Local Saves',
|
||||||
'name': name,
|
'name': name,
|
||||||
'filename': 'local:' + name}
|
'filename': 'local:' + name
|
||||||
);
|
});
|
||||||
$('#manage').append(
|
$('#manage').append(
|
||||||
'<span class="local_save">' +
|
'<span class="local_save">' +
|
||||||
name +
|
name +
|
||||||
|
@ -864,17 +921,24 @@ function _mousemove(evt) {
|
||||||
io.paddle(1, flipY ? 1 - y : y);
|
io.paddle(1, flipY ? 1 - y : y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pauseRun(b) {
|
function pauseRun() {
|
||||||
|
var label = $('#pause-run i');
|
||||||
if (paused) {
|
if (paused) {
|
||||||
run();
|
run();
|
||||||
b.value = 'Pause';
|
label.removeClass('fa-play').addClass('fa-pause');
|
||||||
} else {
|
} else {
|
||||||
stop();
|
stop();
|
||||||
b.value = 'Run';
|
label.removeClass('fa-pause').addClass('fa-play');
|
||||||
}
|
}
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleSound() {
|
||||||
|
var enableSound = $('#enable_sound');
|
||||||
|
enableSound.prop('checked', !enableSound.prop('checked'));
|
||||||
|
updateSound();
|
||||||
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
hashtag = document.location.hash;
|
hashtag = document.location.hash;
|
||||||
|
|
||||||
|
@ -890,10 +954,13 @@ $(function() {
|
||||||
* Input Handling
|
* Input Handling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$(window).keydown(_keydown);
|
$(window)
|
||||||
$(window).keyup(_keyup);
|
.keydown(_keydown)
|
||||||
|
.keyup(_keyup)
|
||||||
|
.mousedown(function() { audio.autoStart(); });
|
||||||
|
|
||||||
$('canvas').mousedown(function(evt) {
|
$('canvas')
|
||||||
|
.mousedown(function(evt) {
|
||||||
if (!gamepad) {
|
if (!gamepad) {
|
||||||
io.buttonDown(evt.which == 1 ? 0 : 1);
|
io.buttonDown(evt.which == 1 ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
@ -908,10 +975,11 @@ $(function() {
|
||||||
|
|
||||||
$('body').mousemove(_mousemove);
|
$('body').mousemove(_mousemove);
|
||||||
|
|
||||||
$('input,textarea').focus(function() { focused = true; })
|
$('input,textarea')
|
||||||
|
.focus(function() { focused = true; })
|
||||||
.blur(function() { focused = false; });
|
.blur(function() { focused = false; });
|
||||||
|
|
||||||
keyboard.create($('#keyboard'));
|
keyboard.create('#keyboard');
|
||||||
|
|
||||||
if (prefs.havePrefs()) {
|
if (prefs.havePrefs()) {
|
||||||
$('#options input[type=checkbox]').each(function() {
|
$('#options input[type=checkbox]').each(function() {
|
||||||
|
@ -931,7 +999,6 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
run();
|
|
||||||
setInterval(updateKHz, 1000);
|
setInterval(updateKHz, 1000);
|
||||||
updateSound();
|
updateSound();
|
||||||
updateScreen();
|
updateScreen();
|
||||||
|
@ -963,6 +1030,16 @@ $(function() {
|
||||||
width: 320,
|
width: 320,
|
||||||
buttons: {'Close': cancel }
|
buttons: {'Close': cancel }
|
||||||
});
|
});
|
||||||
|
$('#printer').dialog({
|
||||||
|
autoOpen: false,
|
||||||
|
modal: true,
|
||||||
|
resizeable: false,
|
||||||
|
width: 570,
|
||||||
|
buttons: {
|
||||||
|
'Clear': printer.clear,
|
||||||
|
'Close': cancel
|
||||||
|
}
|
||||||
|
});
|
||||||
$('#http_load').dialog({
|
$('#http_load').dialog({
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
modal: true,
|
modal: true,
|
||||||
|
@ -1025,4 +1102,6 @@ $(function() {
|
||||||
}).keyup(function() {
|
}).keyup(function() {
|
||||||
focused = $('#buffering').prop('checked');
|
focused = $('#buffering').prop('checked');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
run();
|
||||||
});
|
});
|
||||||
|
|
99
js/main2e.js
99
js/main2e.js
|
@ -20,7 +20,7 @@
|
||||||
ApplesoftDump: false, SYMBOLS: false,
|
ApplesoftDump: false, SYMBOLS: false,
|
||||||
multiScreen: true
|
multiScreen: true
|
||||||
*/
|
*/
|
||||||
/* exported openLoad, openSave, doDelete,
|
/* exported openLoad, openSave, doDelete, handleDragOver, handleDragEnd, handleDrop,
|
||||||
selectCategory, selectDisk, clickDisk,
|
selectCategory, selectDisk, clickDisk,
|
||||||
multiScreen,
|
multiScreen,
|
||||||
updateJoystick,
|
updateJoystick,
|
||||||
|
@ -159,6 +159,44 @@ function openSave(drive, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDragOver(drive, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragEnd(drive, event) {
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.items) {
|
||||||
|
for (var i = 0; i < dt.items.length; i++) {
|
||||||
|
dt.items.remove(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.dataTransfer.clearData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDrop(drive, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if (drive < 1) {
|
||||||
|
if (!disk2.getMetadata(1)) {
|
||||||
|
drive = 1;
|
||||||
|
} else if (!disk2.getMetadata(2)) {
|
||||||
|
drive = 2;
|
||||||
|
} else {
|
||||||
|
drive = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.files.length == 1) {
|
||||||
|
doLoadLocal(drive, dt.files[0]);
|
||||||
|
} else if (dt.files.length == 2) {
|
||||||
|
doLoadLocal(1, dt.files[0]);
|
||||||
|
doLoadLocal(2, dt.files[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var loading = false;
|
var loading = false;
|
||||||
|
|
||||||
function loadAjax(drive, url) {
|
function loadAjax(drive, url) {
|
||||||
|
@ -320,7 +358,6 @@ default:
|
||||||
}
|
}
|
||||||
|
|
||||||
var runTimer = null;
|
var runTimer = null;
|
||||||
|
|
||||||
var cpu = new CPU6502({'65C02': enhanced});
|
var cpu = new CPU6502({'65C02': enhanced});
|
||||||
|
|
||||||
var context1, context2, context3, context4;
|
var context1, context2, context3, context4;
|
||||||
|
@ -360,12 +397,13 @@ var io = new Apple2IO(cpu, vm);
|
||||||
var keyboard = new KeyBoard(io, true);
|
var keyboard = new KeyBoard(io, true);
|
||||||
var audio = new Audio(io);
|
var audio = new Audio(io);
|
||||||
var tape = new Tape(io);
|
var tape = new Tape(io);
|
||||||
|
var printer = new Printer($('#printer .paper'));
|
||||||
|
|
||||||
var mmu = new MMU(cpu, vm, gr, gr2, hgr, hgr2, io, rom);
|
var mmu = new MMU(cpu, vm, gr, gr2, hgr, hgr2, io, rom);
|
||||||
|
|
||||||
cpu.addPageHandler(mmu);
|
cpu.addPageHandler(mmu);
|
||||||
|
|
||||||
var parallel = new Parallel(io, 1, new Printer());
|
var parallel = new Parallel(io, 1, printer);
|
||||||
var slinky = new RAMFactor(io, 2, 1024 * 1024);
|
var slinky = new RAMFactor(io, 2, 1024 * 1024);
|
||||||
var disk2 = new DiskII(io, 6, drivelights);
|
var disk2 = new DiskII(io, 6, drivelights);
|
||||||
var clock = new Thunderclock(io, 7);
|
var clock = new Thunderclock(io, 7);
|
||||||
|
@ -399,7 +437,14 @@ function updateKHz() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSound() {
|
function updateSound() {
|
||||||
audio.enable($('#enable_sound').attr('checked'));
|
var on = $('#enable_sound').prop('checked');
|
||||||
|
var label = $('#toggle-sound i');
|
||||||
|
audio.enable(on);
|
||||||
|
if (on) {
|
||||||
|
label.removeClass('fa-volume-off').addClass('fa-volume-up');
|
||||||
|
} else {
|
||||||
|
label.removeClass('fa-volume-up').addClass('fa-volume-off');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dumpDisk(drive) {
|
function dumpDisk(drive) {
|
||||||
|
@ -499,7 +544,7 @@ function run(pc) {
|
||||||
cpu.stepCycles(step);
|
cpu.stepCycles(step);
|
||||||
}
|
}
|
||||||
vm.blit();
|
vm.blit();
|
||||||
io.sampleTick();
|
io.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
processGamepad(io);
|
processGamepad(io);
|
||||||
|
@ -726,6 +771,8 @@ function processHash(hash) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function _keydown(evt) {
|
function _keydown(evt) {
|
||||||
|
audio.autoStart();
|
||||||
|
|
||||||
if (!focused) {
|
if (!focused) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
|
@ -842,17 +889,24 @@ function _mousemove(evt) {
|
||||||
io.paddle(1, flipY ? 1 - y : y);
|
io.paddle(1, flipY ? 1 - y : y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pauseRun(b) {
|
function pauseRun() {
|
||||||
|
var label = $('#pause-run i');
|
||||||
if (paused) {
|
if (paused) {
|
||||||
run();
|
run();
|
||||||
b.value = 'Pause';
|
label.removeClass('fa-play').addClass('fa-pause');
|
||||||
} else {
|
} else {
|
||||||
stop();
|
stop();
|
||||||
b.value = 'Run';
|
label.removeClass('fa-pause').addClass('fa-play');
|
||||||
}
|
}
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleSound() {
|
||||||
|
var enableSound = $('#enable_sound');
|
||||||
|
enableSound.prop('checked', !enableSound.prop('checked'));
|
||||||
|
updateSound();
|
||||||
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
hashtag = document.location.hash;
|
hashtag = document.location.hash;
|
||||||
|
|
||||||
|
@ -868,10 +922,13 @@ $(function() {
|
||||||
* Input Handling
|
* Input Handling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$(window).keydown(_keydown);
|
$(window)
|
||||||
$(window).keyup(_keyup);
|
.keydown(_keydown)
|
||||||
|
.keyup(_keyup)
|
||||||
|
.mousedown(function() { audio.autoStart(); });
|
||||||
|
|
||||||
$('canvas').mousedown(function(evt) {
|
$('canvas')
|
||||||
|
.mousedown(function(evt) {
|
||||||
if (!gamepad) {
|
if (!gamepad) {
|
||||||
io.buttonDown(evt.which == 1 ? 0 : 1);
|
io.buttonDown(evt.which == 1 ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
@ -886,13 +943,11 @@ $(function() {
|
||||||
|
|
||||||
$('body').mousemove(_mousemove);
|
$('body').mousemove(_mousemove);
|
||||||
|
|
||||||
$('body > div').hover(function() { focused = false; },
|
$('input,textarea')
|
||||||
function() { focused = true; });
|
.focus(function() { focused = true; })
|
||||||
|
|
||||||
$('input,textarea').focus(function() { focused = true; })
|
|
||||||
.blur(function() { focused = false; });
|
.blur(function() { focused = false; });
|
||||||
|
|
||||||
keyboard.create($('#keyboard'));
|
keyboard.create('#keyboard');
|
||||||
|
|
||||||
if (prefs.havePrefs()) {
|
if (prefs.havePrefs()) {
|
||||||
$('#options input[type=checkbox]').each(function() {
|
$('#options input[type=checkbox]').each(function() {
|
||||||
|
@ -912,7 +967,6 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
run();
|
|
||||||
setInterval(updateKHz, 1000);
|
setInterval(updateKHz, 1000);
|
||||||
updateSound();
|
updateSound();
|
||||||
updateScreen();
|
updateScreen();
|
||||||
|
@ -944,6 +998,16 @@ $(function() {
|
||||||
width: 320,
|
width: 320,
|
||||||
buttons: {'Close': cancel }
|
buttons: {'Close': cancel }
|
||||||
});
|
});
|
||||||
|
$('#printer').dialog({
|
||||||
|
autoOpen: false,
|
||||||
|
modal: true,
|
||||||
|
resizeable: false,
|
||||||
|
width: 570,
|
||||||
|
buttons: {
|
||||||
|
'Clear': printer.clear,
|
||||||
|
'Close': cancel
|
||||||
|
}
|
||||||
|
});
|
||||||
$('#http_load').dialog({
|
$('#http_load').dialog({
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
modal: true,
|
modal: true,
|
||||||
|
@ -993,4 +1057,5 @@ $(function() {
|
||||||
$('body').addClass('standalone');
|
$('body').addClass('standalone');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,6 +23,7 @@ function Audio(io) {
|
||||||
var audioContext;
|
var audioContext;
|
||||||
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||||
var audioNode;
|
var audioNode;
|
||||||
|
var started = false;
|
||||||
|
|
||||||
if (AudioContext) {
|
if (AudioContext) {
|
||||||
audioContext = new AudioContext();
|
audioContext = new AudioContext();
|
||||||
|
@ -67,6 +68,14 @@ function Audio(io) {
|
||||||
_initAudio(io);
|
_initAudio(io);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
autoStart: function () {
|
||||||
|
if (audioContext && !started) {
|
||||||
|
_samples = [];
|
||||||
|
audioContext.resume();
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
start: function () {
|
start: function () {
|
||||||
if (audioContext) {
|
if (audioContext) {
|
||||||
_samples = [];
|
_samples = [];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*!
|
/*!
|
||||||
* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
|
* Copyright 2010-2019 Will Scullin <scullin@scullinsteel.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
|
|
@ -278,7 +278,14 @@ function KeyBoard(io, e) {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
create: function keyboard_create(kb) {
|
reset: function keyboard_reset(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
reset();
|
||||||
|
},
|
||||||
|
|
||||||
|
create: function keyboard_create(el) {
|
||||||
|
var kb = $(el);
|
||||||
var x, y, row, key, key1, key2, label, label1, label2, self = this;
|
var x, y, row, key, key1, key2, label, label1, label2, self = this;
|
||||||
|
|
||||||
kb.disableSelection();
|
kb.disableSelection();
|
||||||
|
@ -295,6 +302,7 @@ function KeyBoard(io, e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _mousedown(ev) {
|
function _mousedown(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
$(this).addClass('pressed');
|
$(this).addClass('pressed');
|
||||||
var key = $(ev.currentTarget).data(shifted ? 'key2' : 'key1');
|
var key = $(ev.currentTarget).data(shifted ? 'key2' : 'key1');
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
|
|
@ -1,38 +1,46 @@
|
||||||
/*globals debug: false */
|
|
||||||
/*exported Printer */
|
/*exported Printer */
|
||||||
|
|
||||||
function Printer() {
|
function Printer(paper) {
|
||||||
var _printer = null;
|
var _lineBuffer;
|
||||||
var _linebuffer = '';
|
var _line;
|
||||||
|
|
||||||
|
function newLine() {
|
||||||
|
_line = $('<div>').addClass('line').text(_lineBuffer);
|
||||||
|
paper.append(_line);
|
||||||
|
_lineBuffer = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
newLine();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
putChar: function(val) {
|
putChar: function(val) {
|
||||||
if (!_printer || _printer.closed) {
|
var ascii = val & 0x7f;
|
||||||
_printer = window.open('', '_blank','toolbar=0,location=0');
|
var visible = val >= 0x20;
|
||||||
if (_printer) {
|
var c = String.fromCharCode(ascii);
|
||||||
_printer.document.title = 'Printer';
|
|
||||||
_printer.document.write('<div style="font: 12px courier">');
|
|
||||||
_printer.document.write('<span>');
|
|
||||||
window.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var c = String.fromCharCode(val & 0x7f);
|
|
||||||
if (_printer) {
|
|
||||||
if (c == '\r') {
|
if (c == '\r') {
|
||||||
_printer.document.write('<br /></span>');
|
newLine();
|
||||||
} else if (c == ' ') {
|
_lineBuffer = '';
|
||||||
_printer.document.write(' ');
|
} else if (c == '\t') {
|
||||||
|
_lineBuffer += ' ';
|
||||||
|
} else if (c == '\010') {
|
||||||
|
_lineBuffer = _lineBuffer.slice(0, -1);
|
||||||
} else {
|
} else {
|
||||||
_printer.document.write(c);
|
if (visible) {
|
||||||
}
|
_lineBuffer += c;
|
||||||
} else {
|
|
||||||
if (c == '\r') {
|
|
||||||
debug(_linebuffer);
|
|
||||||
_linebuffer = '';
|
|
||||||
} else if (c == ' ') {
|
|
||||||
_linebuffer += c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_line.text(_lineBuffer);
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function() {
|
||||||
|
_lineBuffer = '';
|
||||||
|
paper.empty();
|
||||||
|
newLine();
|
||||||
|
},
|
||||||
|
|
||||||
|
hasPrintout: function() {
|
||||||
|
return paper.text().length();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
13
js/util.js
13
js/util.js
|
@ -24,15 +24,26 @@ var hex_digits = '0123456789ABCDEF';
|
||||||
var bin_digits = '01';
|
var bin_digits = '01';
|
||||||
|
|
||||||
function allocMem(size) {
|
function allocMem(size) {
|
||||||
|
function garbage() {
|
||||||
|
return (Math.random() * 0x100) & 0xff;
|
||||||
|
}
|
||||||
var result;
|
var result;
|
||||||
if (window.Uint8Array) {
|
if (window.Uint8Array) {
|
||||||
result = new Uint8Array(size);
|
result = new Uint8Array(size);
|
||||||
} else {
|
} else {
|
||||||
result = new Array(size);
|
result = new Array(size);
|
||||||
}
|
}
|
||||||
for (var idx = 0; idx < size; idx++) {
|
var idx;
|
||||||
|
for (idx = 0; idx < size; idx++) {
|
||||||
result[idx] = (idx & 0x02) ? 0x00 : 0xff;
|
result[idx] = (idx & 0x02) ? 0x00 : 0xff;
|
||||||
}
|
}
|
||||||
|
// Borrowed from AppleWin (https://github.com/AppleWin/AppleWin)
|
||||||
|
for(idx = 0; idx < size; idx += 0x200 ) {
|
||||||
|
result[idx + 0x28] = garbage();
|
||||||
|
result[idx + 0x29] = garbage();
|
||||||
|
result[idx + 0x68] = garbage();
|
||||||
|
result[idx + 0x69] = garbage();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue