diff --git a/js/apple2io.js b/js/apple2io.js index 7638332..eeec620 100644 --- a/js/apple2io.js +++ b/js/apple2io.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -92,8 +92,7 @@ function Apple2IO(cpu, callbacks) PDLTRIG: 0x70, // trigger paddles BANK: 0x73, // Back switched RAM card bank SETIOUDIS:0x7E, // Enable double hires - CLRIOUDIS:0x7F, // Disable double hires - RDDHIRES: 0x7F // Read double hires status + CLRIOUDIS:0x7F // Disable double hires }; function _debug() { @@ -422,8 +421,14 @@ function Apple2IO(cpu, callbacks) } }, - getState: function apple2io_getState() { return {}; }, - setState: function apple2io_setState() { }, + getState: function apple2io_getState() { + return { + annunciators: _annunciators[0] + }; + }, + setState: function apple2io_setState(state) { + _annunciators = state.annunciators; + }, setSlot: function apple2io_setSlot(slot, card) { _slot[slot] = card; diff --git a/js/canvas.js b/js/canvas.js index 2db0b49..0ecd407 100644 --- a/js/canvas.js +++ b/js/canvas.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/cards/disk2.js b/js/cards/disk2.js index a96343f..2b58798 100644 --- a/js/cards/disk2.js +++ b/js/cards/disk2.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -752,11 +752,10 @@ function DiskII(io, slot, callbacks) on: _on, drive: _drive }; - _drives.forEach(function (drive, idx) { - var _drive = result.drives[idx] = getDriveState(drive); - callbacks.driveLight(idx, _drive.on); - callbacks.dirty(idx, _drive.dirty); + _drives.forEach(function(drive, idx) { + result.drives[idx] = getDriveState(drive); }); + return result; }, setState: function disk2_setState(state) { @@ -778,6 +777,8 @@ function DiskII(io, slot, callbacks) } state.drives.forEach(function(drive, idx) { _drives[idx] = setDriveState(drive); + callbacks.driveLight(idx, _drive.on); + callbacks.dirty(idx, _drive.dirty); }); _skip = state.skip; _latch = state.latch; diff --git a/js/cards/langcard.js b/js/cards/langcard.js index 7cde01e..3d7ad5a 100644 --- a/js/cards/langcard.js +++ b/js/cards/langcard.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -83,6 +83,24 @@ function LanguageCard(io, slot, rom) { _READWRBSR1: 0x8f }; + function _updateBanks() { + if (_readbsr) { + _read1 = _bsr2 ? _bank2 : _bank1; + _read2 = _ram; + } else { + _read1 = _rom; + _read2 = _rom; + } + + if (_writebsr) { + _write1 = _bsr2 ? _bank2 : _bank1; + _write2 = _ram; + } else { + _write1 = rom; + _write2 = rom; + } + } + function _access(off, val) { var readMode = val === undefined; var result = 0; @@ -173,21 +191,7 @@ function LanguageCard(io, slot, rom) { break; } - if (_readbsr) { - _read1 = _bsr2 ? _bank2 : _bank1; - _read2 = _ram; - } else { - _read1 = _rom; - _read2 = _rom; - } - - if (_writebsr) { - _write1 = _bsr2 ? _bank2 : _bank1; - _write2 = _ram; - } else { - _write1 = rom; - _write2 = rom; - } + _updateBanks(); return result; } @@ -224,6 +228,7 @@ function LanguageCard(io, slot, rom) { writebsr: _writebsr, bsr2: _bsr2, prewrite: _prewrite, + ram: _ram.getState(), bank1: _bank1.getState(), bank2: _bank2.getState() }; @@ -232,10 +237,11 @@ function LanguageCard(io, slot, rom) { _readbsr = state.readbsr; _writebsr = state.writebsr; _bsr2 = state.bsr2; + _prewrite = state.prewrite; + _ram.setState(state.ram); _bank1.setState(state.bank1); _bank2.setState(state.bank2); - _access(-1); - _prewrite = state.prewrite; + _updateBanks(); } }; } diff --git a/js/cards/parallel.js b/js/cards/parallel.js index 78ec950..9aa13a0 100644 --- a/js/cards/parallel.js +++ b/js/cards/parallel.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/cards/ramfactor.js b/js/cards/ramfactor.js index a00a474..26ed312 100644 --- a/js/cards/ramfactor.js +++ b/js/cards/ramfactor.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/cards/thunderclock.js b/js/cards/thunderclock.js index 55a6483..a52ce46 100644 --- a/js/cards/thunderclock.js +++ b/js/cards/thunderclock.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/copyright.js b/js/copyright.js index f485e5c..f04d079 100644 --- a/js/copyright.js +++ b/js/copyright.js @@ -1,5 +1,5 @@ /*! - * Copyright 2010-2016 Will Scullin + * Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/cpu6502.js b/js/cpu6502.js index 38fc55e..5bcc7ce 100644 --- a/js/cpu6502.js +++ b/js/cpu6502.js @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 Will Scullin + * Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/main2.js b/js/main2.js index 0292525..0795f49 100644 --- a/js/main2.js +++ b/js/main2.js @@ -6,7 +6,7 @@ apple2_charset: false, apple2j_charset: false, pigfont_charset: false, apple2lc_charset: false, Apple2IO: false - LoresPage: false, HiresPage: false, VideoModes: false + LoresPage: false, HiresPage: false, VideoModes: false, KeyBoard: false, Parallel: false, Videoterm: false, @@ -17,18 +17,19 @@ Thunderclock: false, Prefs: false, disk_index: false, - initAudio: false, enableSound: false, + Audio: false, initGamepad: false, processGamepad: false, gamepad: false, ApplesoftDump: false, SYMBOLS: false, multiScreen: true */ /* exported openLoad, openSave, doDelete, selectCategory, selectDisk, clickDisk, + multiScreen, updateJoystick, pauseRun, step, + toggleSound, restoreState, saveState, dumpProgram, PageDebug, - multiScreen, enhanced */ @@ -357,33 +358,6 @@ function openManage() { } var prefs = new Prefs(); -var runTimer = null; -var cpu = new CPU6502(); - -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 romVersion = prefs.readPref('computer_type2'); var enhanced = false; var rom; @@ -411,6 +385,33 @@ default: rom = new Apple2ROM(); } +var runTimer = null; +var cpu = new CPU6502(); + +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, false, context1); var gr2 = new LoresPage(2, char_rom, false, context2); var hgr = new HiresPage(1, context3); @@ -427,6 +428,7 @@ var dumper = new ApplesoftDump(cpu); var drivelights = new DriveLights(); var io = new Apple2IO(cpu, vm); var keyboard = new KeyBoard(io); +var audio = new Audio(io); var lc = new LanguageCard(io, 0, rom); var parallel = new Parallel(io, 1, new Printer()); var slinky = new RAMFactor(io, 2, 1024 * 1024); @@ -474,11 +476,8 @@ function updateKHz() { lastFrames = renderedFrames; } -/* Audio Handling */ -initAudio(io); - function updateSound() { - enableSound($('#enable_sound').attr('checked')); + audio.enable($('#enable_sound').attr('checked')); } function dumpDisk(drive) { @@ -848,6 +847,10 @@ function _keydown(evt) { } } else if (evt.keyCode === 114) { // F3 io.keyDown(0x1b); + } else if (evt.keyCode === 117) { // F6 Quick Save + saveState(); + } else if (evt.keyCode === 120) { // F9 Quick Restore + restoreState(); } else if (evt.keyCode == 16) { // Shift keyboard.shiftKey(true); } else if (evt.keyCode == 17) { // Control @@ -870,8 +873,8 @@ function updateScreen() { var green = $('#green_screen').prop('checked'); var scanlines = $('#show_scanlines').prop('checked'); - vm.scanlines(scanlines); vm.green(green); + vm.scanlines(scanlines); } var disableMouseJoystick = false; @@ -991,7 +994,6 @@ $(function() { autoOpen: false, modal: true, width: 320, - height: 400, buttons: {'Close': cancel } }); $('#load').dialog({ @@ -1012,12 +1014,6 @@ $(function() { width: 320, buttons: {'Close': cancel } }); - $('#local_save').dialog({ - autoOpen: false, - modal: true, - width: 530, - buttons: {'OK': cancel } - }); $('#http_load').dialog({ autoOpen: false, modal: true, diff --git a/js/main2e.js b/js/main2e.js index c8481f9..814973e 100644 --- a/js/main2e.js +++ b/js/main2e.js @@ -1,4 +1,4 @@ -/* globals debug: false, gup: false, hup: false, toHex: false +/* globals debug: false, gup: false, hup: false, toHex: false, CPU6502: false, Apple2eROM: false, Apple2eEnhancedROM: false, apple2e_charset: false, rmfont_charset: false, @@ -14,7 +14,7 @@ Thunderclock: false, Prefs: false, disk_index: false, - initAudio: false, enableSound: false, + Audio: false, initGamepad: false, processGamepad: false, gamepad: false, ApplesoftDump: false, SYMBOLS: false, multiScreen: true @@ -24,8 +24,10 @@ multiScreen, updateJoystick, pauseRun, step, + toggleSound, restoreState, saveState, - dumpProgram, PageDebug + dumpProgram, PageDebug, + enhanced */ var kHz = 1023; @@ -412,6 +414,7 @@ var dumper = new ApplesoftDump(cpu); var drivelights = new DriveLights(); var io = new Apple2IO(cpu, vm); var keyboard = new KeyBoard(io, true); +var audio = new Audio(io); var mmu = new MMU(cpu, vm, gr, gr2, hgr, hgr2, io, rom); @@ -450,11 +453,8 @@ function updateKHz() { lastFrames = renderedFrames; } -/* Audio Handling */ -initAudio(io); - function updateSound() { - enableSound($('#enable_sound').attr('checked')); + audio.enable($('#enable_sound').attr('checked')); } function dumpDisk(drive) { @@ -812,6 +812,10 @@ function _keydown(evt) { } } else if (evt.keyCode === 114) { // F3 io.keyDown(0x1b); + } else if (evt.keyCode === 117) { // F6 Quick Save + saveState(); + } else if (evt.keyCode === 120) { // F9 Quick Restore + restoreState(); } else if (evt.keyCode == 16) { // Shift keyboard.shiftKey(true); } else if (evt.keyCode == 17) { // Control @@ -966,7 +970,6 @@ $(function() { autoOpen: false, modal: true, width: 320, - height: 400, buttons: {'Close': cancel } }); $('#load').dialog({ diff --git a/js/mmu.js b/js/mmu.js index ce7a064..7c212d5 100644 --- a/js/mmu.js +++ b/js/mmu.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -671,20 +671,22 @@ function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom) }, getState: function() { return { + bank1: _bank1, readbsr: _readbsr, writebsr: _writebsr, - bank1: _bank1, prewrite: _prewrite, intcxrom: _intcxrom, slot3rom: _slot3rom, intc8rom: _intc8rom, + auxRamRead: _auxRamRead, auxRamWrite: _auxRamWrite, altzp: _altzp, _80store: _80store, page2: _page2, + hires: _hires, mem00_01: [mem00_01[0].getState(), mem00_01[1].getState()], mem02_03: [mem02_03[0].getState(), mem02_03[1].getState()], @@ -701,16 +703,19 @@ function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom) _readbsr = state.readbsr; _writebsr = state.writebsr; _bank1 = state.bank1; + _prewrite = state.prewrite; _intcxrom = state.intcxrom; _slot3rom = state.slot3rom; _intc8rom = state.intc8rom; + _auxRamRead = state.auxRamRead; _auxRamWrite = state.auxRamWrite; _altzp = state.altzp; _80store = state._80store; _page2 = state.page2; + _hires = state.hires; mem00_01[0].setState(state.mem00_01[0]); mem00_01[1].setState(state.mem00_01[1]); @@ -727,8 +732,7 @@ function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom) memE0_FF[0].setState(state.memE0_FF[0]); memE0_FF[1].setState(state.memE0_FF[1]); - _access(-1); - _prewrite = state.prewrite; + _updateBanks(); } }; } diff --git a/js/prefs.js b/js/prefs.js index e17faa4..161c319 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/ram.js b/js/ram.js index a6e2f01..a97fed7 100644 --- a/js/ram.js +++ b/js/ram.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/ui/audio.js b/js/ui/audio.js index 7cc0ea3..968071f 100644 --- a/js/ui/audio.js +++ b/js/ui/audio.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -10,68 +10,72 @@ */ /*globals debug: false */ -/*exported enableSound, initAudio */ +/*exported Audio */ /* * Audio Handling */ -var sound = true; -var _samples = []; +function Audio(io) { + var sound = true; + var _samples = []; -var audioContext; -var AudioContext = window.AudioContext || window.webkitAudioContext; -var audioNode; + var audioContext; + var AudioContext = window.AudioContext || window.webkitAudioContext; + var audioNode; -if (AudioContext) { - audioContext = new AudioContext(); - audioNode = audioContext.createScriptProcessor(4096, 1, 1); + if (AudioContext) { + audioContext = new AudioContext(); + audioNode = audioContext.createScriptProcessor(4096, 1, 1); - audioNode.onaudioprocess = function(event) { - var data = event.outputBuffer.getChannelData(0); - var sample = _samples.shift(); - var idx = 0; + audioNode.onaudioprocess = function(event) { + var data = event.outputBuffer.getChannelData(0); + var sample = _samples.shift(); + var idx = 0; - var len = data.length; - if (sample) { - len = Math.min(sample.length, len); - for (; idx < len; idx++) { - data[idx] = sample[idx]; - } - } - - for (; idx < data.length; idx++) { - data[idx] = 0.0; - } - }; - - /* - // Create and specify parameters for the low-pass filter. - var filter = audioContext.createBiquadFilter(); - filter.type = 'lowpass'; - filter.frequency.value = 11000; - filter.connect(audioContext.destination); - audioNode.connect(filter); - */ - - audioNode.connect(audioContext.destination); -} - -function initAudio(io) { - if (audioContext) { - debug('Using Webkit Audio'); - io.sampleRate(audioContext.sampleRate); - io.addSampleListener(function(sample) { - if (sound) { - _samples.push(sample); - while (_samples.length > 5) { - _samples.shift(); + var len = data.length; + if (sample) { + len = Math.min(sample.length, len); + for (; idx < len; idx++) { + data[idx] = sample[idx]; } } - }); - } -} -function enableSound(enable) { - sound = enable; + for (; idx < data.length; idx++) { + data[idx] = 0.0; + } + }; + + audioNode.connect(audioContext.destination); + } + + function _initAudio(io) { + if (audioContext) { + debug('Using Webkit Audio'); + io.sampleRate(audioContext.sampleRate); + io.addSampleListener(function(sample) { + if (sound) { + _samples.push(sample); + while (_samples.length > 5) { + _samples.shift(); + } + } + }); + } + } + + _initAudio(io); + + return { + start: function () { + if (audioContext) { + _samples = []; + audioContext.resume(); + } + }, + + enable: function(enable) { + sound = enable; + } + }; } diff --git a/js/ui/copyright.js b/js/ui/copyright.js index f485e5c..f04d079 100644 --- a/js/ui/copyright.js +++ b/js/ui/copyright.js @@ -1,5 +1,5 @@ /*! - * Copyright 2010-2016 Will Scullin + * Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/ui/gamepad.js b/js/ui/gamepad.js index 4ab2219..5c05536 100644 --- a/js/ui/gamepad.js +++ b/js/ui/gamepad.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js index 0369a28..3baa7cc 100644 --- a/js/ui/keyboard.js +++ b/js/ui/keyboard.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/js/ui/printer.js b/js/ui/printer.js index e322e10..b0ed2b1 100644 --- a/js/ui/printer.js +++ b/js/ui/printer.js @@ -1,7 +1,10 @@ +/*globals debug: false */ /*exported Printer */ function Printer() { var _printer = null; + var _linebuffer = ''; + return { putChar: function(val) { if (!_printer || _printer.closed) { @@ -13,8 +16,8 @@ function Printer() { window.focus(); } } + var c = String.fromCharCode(val & 0x7f); if (_printer) { - var c = String.fromCharCode(val & 0x7f); if (c == '\r') { _printer.document.write('
'); } else if (c == ' ') { @@ -22,6 +25,13 @@ function Printer() { } else { _printer.document.write(c); } + } else { + if (c == '\r') { + debug(_linebuffer); + _linebuffer = ''; + } else if (c == ' ') { + _linebuffer += c; + } } } }; diff --git a/js/util.js b/js/util.js index 64490a6..91c7929 100644 --- a/js/util.js +++ b/js/util.js @@ -1,4 +1,4 @@ -/* Copyright 2010-2016 Will Scullin +/* Copyright 2010-2017 Will Scullin * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -78,7 +78,7 @@ function toBinary(v) { // From http://www.netlobo.com/url_query_string_javascript.html function gup( name ) { - name = name.replace(/[\[]/,'\\[').replace(/[\]]/,'\\]'); + name = name.replace(/[[]/,'\\[').replace(/[\]]/,'\\]'); var regexS = '[\\?&]'+name+'=([^&#]*)'; var regex = new RegExp( regexS ); var results = regex.exec( window.location.href );