State save/restore work, updated audio class.

This commit is contained in:
Will Scullin 2017-12-02 20:45:02 -08:00
parent bd173c47fe
commit de4f1fc2d8
20 changed files with 178 additions and 149 deletions

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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;

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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;

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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();
}
};
}

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,5 +1,5 @@
/*!
* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -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,

View File

@ -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({

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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();
}
};
}

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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;
}
};
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that

View File

@ -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('<br /></span>');
} 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;
}
}
}
};

View File

@ -1,4 +1,4 @@
/* Copyright 2010-2016 Will Scullin <scullin@scullinsteel.com>
/* Copyright 2010-2017 Will Scullin <scullin@scullinsteel.com>
*
* 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 );