import Apple2IO from './apple2io';
import ApplesoftDump from './applesoft/decompiler';
import { HiresPage, LoresPage, VideoModes } from './canvas';
import CPU6502 from './cpu6502';
import MMU from './mmu';
import Prefs from './prefs';
import { debug, gup, hup } from './util';
import Audio from './ui/audio';
import { gamepad, configGamepad, initGamepad, processGamepad } from './ui/gamepad';
import KeyBoard from './ui/keyboard';
import Printer from './ui/printer';
import Tape from './ui/tape';
import DiskII from './cards/disk2';
import Parallel from './cards/parallel';
import RAMFactor from './cards/ramfactor';
import Thunderclock from './cards/thunderclock';
import apple2e_charset from './roms/apple2e_char';
import apple2enh_charset from './roms/apple2enh_char';
import rmfont_charset from './roms/rmfont_char';
import Apple2eROM from './roms/apple2e';
import Apple2eEnhancedROM from './roms/apple2enh';
import SYMBOLS from './symbols';
var kHz = 1023;
var focused = false;
var startTime = Date.now();
var lastCycles = 0;
var renderedFrames = 0, lastFrames = 0;
var paused = false;
var hashtag;
var DEBUG = false;
var TRACE = false;
var MAX_TRACE = 256;
var trace = [];
/*
* Page viewer
*/
/*
function PageDebug(page)
{
var _page = page;
function _init() {
var r, c;
var row = $('
').appendTo('#page' + toHex(_page));
$('
\\
').appendTo(row);
for (c = 0; c < 16; c++) {
$('
' + toHex(c) + '
').appendTo(row);
}
for (r = 0; r < 16; r++) {
row = $('
').appendTo('#page' + toHex(_page));
$('
' + toHex(r * 16) + '
').appendTo(row);
for (c = 0; c < 16; c++) {
$('
--
').appendTo(row).attr('id', 'page' + toHex(_page) + '-' + toHex(r * 16 + c));
}
}
}
_init();
return {
start: function() { return _page; },
end: function() { return _page; },
read: null,
write: function(page, off, val) {
$('#page' + toHex(page) + '-' + toHex(off)).text(toHex(val));
}
};
}
*/
var disk_categories = {'Local Saves': []};
var disk_sets = {};
var disk_cur_name = [];
var disk_cur_cat = [];
function DriveLights()
{
return {
driveLight: function(drive, on) {
$('#disk' + drive).css('background-image',
on ? 'url(css/red-on-16.png)' :
'url(css/red-off-16.png)');
},
dirty: function() {
// $('#disksave' + drive).button('option', 'disabled', !dirty);
},
label: function(drive, label) {
if (label) {
$('#disklabel' + drive).text(label);
}
return $('#disklabel' + drive).text();
},
getState: function() {
return {
disks: [
this.label(1),
this.label(2)
]
};
},
setState: function(state) {
if (state && state.disks) {
this.label(1, state.disks[0].label);
this.label(2, state.disks[1].label);
}
}
};
}
var DISK_TYPES = ['dsk','d13','do','po','raw','nib','2mg'];
var TAPE_TYPES = ['wav','aiff','aif','mp3','m4a'];
var _currentDrive = 1;
window.openLoad = function(drive, event)
{
_currentDrive = parseInt(drive, 10);
if (event.metaKey) {
openLoadHTTP(drive);
} else {
if (disk_cur_cat[drive]) {
$('#category_select').val(disk_cur_cat[drive]).change();
}
$('#load').dialog('open');
}
};
window.openSave = function(drive, event)
{
_currentDrive = parseInt(drive, 10);
var mimetype = 'application/octet-stream';
var data = disk2.getBinary(drive);
var a = $('#local_save_link');
var blob = new Blob([data], { 'type': mimetype });
a.attr('href', window.URL.createObjectURL(blob));
a.attr('download', drivelights.label(drive) + '.dsk');
if (event.metaKey) {
dumpDisk(drive);
} else {
$('#save_name').val(drivelights.label(drive));
$('#save').dialog('open');
}
};
window.handleDragOver = function(drive, event) {
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
};
window.handleDragEnd = function(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();
}
};
window.handleDrop = function(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;
function loadAjax(drive, url) {
loading = true;
$('#loading').dialog('open');
$.ajax({
url: url,
dataType: 'json',
modifiedSince: true,
error: function(xhr, status, error) {
alert(error || status);
$('#loading').dialog('close');
loading = false;
},
success: function(data) {
if (data.type == 'binary') {
loadBinary(drive, data);
} else if ($.inArray(data.type, DISK_TYPES) >= 0) {
loadDisk(drive, data);
}
initGamepad(data.gamepad);
$('#loading').dialog('close');
loading = false;
}
});
}
function doLoad() {
var urls = $('#disk_select').val(), url;
if (urls && urls.length) {
if (typeof(urls) == 'string') {
url = urls;
} else {
url = urls[0];
}
}
var files = $('#local_file').prop('files');
if (files.length == 1) {
doLoadLocal(_currentDrive, files[0]);
} else if (url) {
var filename;
$('#load').dialog('close');
if (url.substr(0,6) == 'local:') {
filename = url.substr(6);
if (filename == '__manage') {
openManage();
} else {
loadLocalStorage(_currentDrive, filename);
}
} else {
var r1 = /json\/disks\/(.*).json$/.exec(url);
if (r1) {
filename = r1[1];
} else {
filename = url;
}
var parts = document.location.hash.split('|');
parts[_currentDrive - 1] = filename;
document.location.hash = parts.join('|');
loadAjax(_currentDrive, url);
}
}
}
function doSave() {
var name = $('#save_name').val();
saveLocalStorage(_currentDrive, name);
$('#save').dialog('close');
}
window.doDelete = function(name) {
if (window.confirm('Delete ' + name + '?')) {
deleteLocalStorage(name);
}
};
function doLoadLocal(drive, file) {
var parts = file.name.split('.');
var ext = parts[parts.length - 1].toLowerCase();
if ($.inArray(ext, DISK_TYPES) >= 0) {
doLoadLocalDisk(drive, file);
} else if ($.inArray(ext, TAPE_TYPES) >= 0) {
tape.doLoadLocalTape(file, function() {
$('#load').dialog('close');
});
} else {
window.alert('Unknown file type: ' + ext);
$('#load').dialog('close');
}
}
function doLoadLocalDisk(drive, file) {
var fileReader = new FileReader();
fileReader.onload = function() {
var parts = file.name.split('.');
var ext = parts.pop().toLowerCase();
var name = parts.join('.');
if (disk2.setBinary(drive, name, ext, this.result)) {
drivelights.label(drive, name);
$('#load').dialog('close');
initGamepad();
}
};
fileReader.readAsArrayBuffer(file);
}
function doLoadHTTP(drive, _url) {
var url = _url || $('#http_url').val();
if (url) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.responseType = 'arraybuffer';
req.onload = function() {
var urlParts = url.split('/');
var file = urlParts.pop();
var fileParts = file.split('.');
var ext = fileParts.pop().toLowerCase();
var name = decodeURIComponent(fileParts.join('.'));
if (disk2.setBinary(drive, name, ext, req.response)) {
drivelights.label(drive, name);
$('#http_load').dialog('close');
initGamepad();
}
};
req.send(null);
}
}
function openLoadHTTP(drive) {
_currentDrive = parseInt(drive, 10);
$('#http_load').dialog('open');
}
function openManage() {
$('#manage').dialog('open');
}
var prefs = new Prefs();
var romVersion = prefs.readPref('computer_type2e');
var enhanced = false;
var multiScreen = false;
var rom;
var char_rom = apple2e_charset;
switch (romVersion) {
case 'apple2e':
rom = new Apple2eROM();
break;
case 'apple2rm':
rom = new Apple2eEnhancedROM();
char_rom = rmfont_charset;
enhanced = true;
break;
default:
rom = new Apple2eEnhancedROM();
char_rom =apple2enh_charset;
enhanced = true;
}
var runTimer = null;
var cpu = new CPU6502({'65C02': enhanced});
var context1, context2, context3, context4;
var canvas1 = document.getElementById('screen');
var canvas2 = document.getElementById('screen2');
var canvas3 = document.getElementById('screen3');
var canvas4 = document.getElementById('screen4');
context1 = canvas1.getContext('2d');
if (canvas4) {
multiScreen = true;
context2 = canvas2.getContext('2d');
context3 = canvas3.getContext('2d');
context4 = canvas4.getContext('2d');
} else if (canvas2) {
multiScreen = true;
context2 = context1;
context3 = canvas2.getContext('2d');
context4 = context3;
} else {
context2 = context1;
context3 = context1;
context4 = context1;
}
var gr = new LoresPage(1, char_rom, true, context1);
var gr2 = new LoresPage(2, char_rom, true, context2);
var hgr = new HiresPage(1, context3);
var hgr2 = new HiresPage(2, context4);
var vm = new VideoModes(gr, hgr, gr2, hgr2, true);
vm.enhanced(enhanced);
vm.multiScreen(multiScreen);
var dumper = new ApplesoftDump(cpu);
var drivelights = new DriveLights();
var io = new Apple2IO(cpu, vm);
var keyboard = new KeyBoard(cpu, io, true);
var audio = new Audio(io);
var tape = new Tape(io);
var printer = new Printer($('#printer .paper'));
var mmu = new MMU(cpu, vm, gr, gr2, hgr, hgr2, io, rom);
cpu.addPageHandler(mmu);
var parallel = new Parallel(io, 1, printer);
var slinky = new RAMFactor(io, 2, 1024 * 1024);
var disk2 = new DiskII(io, 6, drivelights);
var clock = new Thunderclock(io, 7);
io.setSlot(1, parallel);
io.setSlot(2, slinky);
io.setSlot(6, disk2);
io.setSlot(7, clock);
window.showFPS = false;
function updateKHz() {
var now = Date.now();
var ms = now - startTime;
var cycles = cpu.cycles();
var delta;
if (window.showFPS) {
delta = renderedFrames - lastFrames;
var fps = parseInt(delta/(ms/1000), 10);
$('#khz').text( fps + 'fps');
} else {
delta = cycles - lastCycles;
var khz = parseInt(delta/ms);
$('#khz').text( khz + 'KHz');
}
startTime = now;
lastCycles = cycles;
lastFrames = renderedFrames;
}
window.updateSound = function() {
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) {
var wind = window.open('', '_blank');
wind.document.title = drivelights.label(drive);
wind.document.write('