Memory fixes, cleanup.

This commit is contained in:
Will Scullin 2017-08-20 10:46:10 -07:00
parent dc146bf630
commit 0343497abc
19 changed files with 2054 additions and 189 deletions

View File

@ -48,9 +48,8 @@
<script type="text/javascript" src="js/prefs.js"></script>
<script type="text/javascript" src="js/ram.js"></script>
<script type="text/javascript" src="js/langcard.js"></script>
<script type="text/javascript" src="js/fpbasic.js"></script>
<script type="text/javascript" src="js/apple2char.js"></script>
<script type="text/javascript" src="js/applesoft/decompiler.js"></script>
<script type="text/javascript" src="js/intbasic/decompiler.js"></script>
<script type="text/javascript" src="js/canvas2.js"></script>
<script type="text/javascript" src="js/apple2io.js"></script>
<script type="text/javascript" src="js/parallel.js"></script>
@ -59,6 +58,10 @@
<script type="text/javascript" src="js/thunderclock.js"></script>
<script type="text/javascript" src="js/cpu6502.js"></script>
<script type="text/javascript" src="js/base64.js"></script>
<script type="text/javascript" src="js/roms/fpbasic.js"></script>
<script type="text/javascript" src="js/roms/intbasic.js"></script>
<script type="text/javascript" src="js/roms/original.js"></script>
<script type="text/javascript" src="js/roms/apple2_char.js"></script>
<script type="text/javascript" src="js/ui/audio.js"></script>
<script type="text/javascript" src="js/ui/keyboard2.js"></script>
<script type="text/javascript" src="js/ui/gamepad.js"></script>

View File

@ -48,12 +48,9 @@
<script type="text/javascript" src="js/prefs.js"></script>
<script type="text/javascript" src="js/ram.js"></script>
<script type="text/javascript" src="js/mmu.js"></script>
<script type="text/javascript" src="js/apple2e.js"></script>
<script type="text/javascript" src="js/apple2e-enhanced.js"></script>
<script type="text/javascript" src="js/apple2echar.js"></script>
<script type="text/javascript" src="js/applesoft/decompiler.js"></script>
<script type="text/javascript" src="js/intbasic/decompiler.js"></script>
<script type="text/javascript" src="js/canvas2e.js"></script>
<script type="text/javascript" src="js/slot3.js"></script>
<script type="text/javascript" src="js/apple2io.js"></script>
<script type="text/javascript" src="js/parallel.js"></script>
<script type="text/javascript" src="js/disk2.js"></script>
@ -61,6 +58,9 @@
<script type="text/javascript" src="js/thunderclock.js"></script>
<script type="text/javascript" src="js/cpu6502.js"></script>
<script type="text/javascript" src="js/base64.js"></script>
<script type="text/javascript" src="js/roms/apple2e.js"></script>
<script type="text/javascript" src="js/roms/apple2enh.js"></script>
<script type="text/javascript" src="js/roms/apple2e_char.js"></script>
<script type="text/javascript" src="js/ui/audio.js"></script>
<script type="text/javascript" src="js/ui/keyboard2e.js"></script>
<script type="text/javascript" src="js/ui/gamepad.js"></script>
@ -116,16 +116,18 @@
</div>
<div style="clear: both"></div>
</div>
<div class="inset">
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
<input type="button" value="Pause" onclick="pauseRun(this)" />
<input type="button" value="Reset" onclick="reset()" />
<div style="float: right">
<input type="button" onclick="window.open('about.html','_html')"
name="About" value="About">
<input type="button" onclick="$('#options').dialog('open')"
name="Options" value="Options">
<div style="position: relative">
<div id="controls" class="inset">
<div id="khz" onclick="showFPS = !showFPS">0KHz</div>
<input type="button" value="Pause" onclick="pauseRun(this)" />
<div style="float: right">
<input type="button" onclick="window.open('about.html','_html')"
name="About" value="About">
<input type="button" onclick="$('#options').dialog('open')"
name="Options" value="Options">
</div>
</div>
<input id="reset" type="button" value="Reset" onclick="reset()" />
</div>
<div class="inset">
<div id="keyboard"></div>

View File

@ -173,12 +173,12 @@ canvas {
}
/*
@media screen and (min-device-width:1120px) {
:-webkit-full-screen {
:-webkit-full-screen {
background: #000;
}
:-moz-full-screen .overscan {
border: 0px none !important;
border: 0px none !important;
width: 1120px;
height: 768px;
margin: auto;
@ -251,6 +251,33 @@ canvas {
height: 300px;
}
.apple2e #controls {
width: calc(100% - 70px)
}
.apple2e #reset {
position: absolute;
right: 0; top: 0;
background: #44372C;
border: 3px outset #66594E;
border-radius: 3px;
color: white;
font: 9px Helvetica;
height: 42px;
padding: 0;
width: 42px;
}
.apple2e #reset:hover {
background: #44372C;
border: 3px outset #66594E;
}
.apple2e #reset:active {
background: #22150A;
border: 5px outset #44372C;
}
#keyboard .row {
display: block;
margin: 0px;

View File

@ -33,6 +33,7 @@ function Apple2IO(cpu, callbacks)
var _phase = -1;
var _sample = [];
var _sampleTime = 0;
var _didAudio = false;
var _high = 0.5;
var _low = -0.5;
@ -104,9 +105,10 @@ function Apple2IO(cpu, callbacks)
_sample.push(phase);
if (_sample.length >= _sample_size) {
if (_audioListener) {
_audioListener(_sample);
_audioListener(_didAudio ? _sample : []);
}
_sample = [];
_didAudio = false;
}
}
}
@ -230,6 +232,7 @@ function Apple2IO(cpu, callbacks)
break;
case LOC.SPEAKER:
_phase = -_phase;
_didAudio = true;
_tick();
break;
case LOC.STROBE:
@ -303,6 +306,11 @@ function Apple2IO(cpu, callbacks)
}
*/
}
if (val !== undefined) {
result = undefined;
}
return result;
}

View File

@ -9,7 +9,6 @@
* implied warranty.
*/
/*jshint browser:true */
/*globals allocMemPages: false, debug: false,
base64_encode: false, base64_decode: false,
enhanced: false */

View File

@ -246,6 +246,9 @@ function CPU6502(options)
* Read functions
*/
function readImplied() {
}
// #$00
function readImmediate() {
return readBytePC();
@ -378,19 +381,23 @@ function CPU6502(options)
return readWordPC();
}
// $0000
// ($0000) (6502)
function readAddrAbsoluteIndirectBug() {
return indirectBug(readWordPC());
}
// ($0000)
// ($0000) (65C02)
function readAddrAbsoluteIndirect() {
return readWord(readWordPC());
}
// $0000,X
function readAddrAbsoluteX() {
return (readWordPC() + xr) & 0xffff;
var addr = readWordPC();
if (!is65C02) {
readByte(addr);
}
return (addr + xr) & 0xffff;
}
// $(0000,X)
@ -705,7 +712,8 @@ function CPU6502(options)
}
/* No-Op */
function nop() {
function nop(readAddrFn) {
readAddrFn();
}
var ops = {
@ -933,11 +941,12 @@ function CPU6502(options)
0x28: ['PLP', plp, null, modes.implied, 4],
// JMP
0x4C: ['JMP', jmp,
readAddrAbsolute, modes.absolute, 3],
0x6C: ['JMP', jmp,
readAddrAbsoluteIndirectBug, modes.absoluteIndirect, 5],
0x4C: [
'JMP', jmp, readAddrAbsolute, modes.absolute, 3
],
0x6C: [
'JMP', jmp, readAddrAbsoluteIndirectBug, modes.absoluteIndirect, 5
],
// JSR
0x20: ['JSR', jsr, readAddrAbsolute, modes.absolute, 6],
@ -969,7 +978,7 @@ function CPU6502(options)
0xB8: ['CLV', clr, flags.V, modes.implied, 2],
// NOP
0xea: ['NOP', nop, null, modes.implied, 2],
0xea: ['NOP', nop, readImplied, modes.implied, 2],
// BRK
0x00: ['BRK', brk, readImmediate, modes.immediate, 7]
@ -998,13 +1007,31 @@ function CPU6502(options)
0x89: ['BIT', bitI, readImmediate, modes.immediate, 2],
// JMP absolute indirect indexed
0x6C: ['JMP', jmp, readAddrAbsoluteIndirect,
modes.absoluteIndirect, 6],
0x7C: ['JMP', jmp, readAddrAbsoluteXIndirect,
modes.absoluteXIndirect, 6],
0x6C: [
'JMP', jmp, readAddrAbsoluteIndirect, modes.absoluteIndirect, 6
],
0x7C: [
'JMP', jmp, readAddrAbsoluteXIndirect, modes.absoluteXIndirect, 6
],
// BRA
0x80: ['BRA', brc, 0, modes.relative, 3],
0x80: ['BRA', brc, 0, modes.relative, 2],
// NOP
0x02: ['NOP', nop, readImmediate, modes.immediate, 2],
0x22: ['NOP', nop, readImmediate, modes.immediate, 2],
0x42: ['NOP', nop, readImmediate, modes.immediate, 2],
0x44: ['NOP', nop, readImmediate, modes.immediate, 3],
0x54: ['NOP', nop, readImmediate, modes.immediate, 4],
0x62: ['NOP', nop, readImmediate, modes.immediate, 2],
0x82: ['NOP', nop, readImmediate, modes.immediate, 2],
0xC2: ['NOP', nop, readImmediate, modes.immediate, 2],
0xD4: ['NOP', nop, readImmediate, modes.immediate, 4],
0xE2: ['NOP', nop, readImmediate, modes.immediate, 2],
0xF4: ['NOP', nop, readImmediate, modes.immediate, 4],
0x5C: ['NOP', nop, readAbsolute, modes.absolute, 8],
0xDC: ['NOP', nop, readAbsolute, modes.absolute, 4],
0xFC: ['NOP', nop, readAbsolute, modes.absolute, 4],
// PHX
0xDA: ['PHX', phx, null, modes.implied, 3],
@ -1013,10 +1040,10 @@ function CPU6502(options)
0x5A: ['PHY', phy, null, modes.implied, 3],
// PLX
0xFA: ['PLX', plx, null, modes.implied, 3],
0xFA: ['PLX', plx, null, modes.implied, 4],
// PLY
0x7A: ['PLY', ply, null, modes.implied, 3],
0x7A: ['PLY', ply, null, modes.implied, 4],
// STZ
0x64: ['STZ', stz, writeZeroPage, modes.zeroPage, 3],
@ -1048,19 +1075,26 @@ function CPU6502(options)
var unk;
if (is65C02) {
unk = ['NOP (' + toHex(b) + ')', function() {
debug('Unknown OpCode: ' + toHex(b) + ' at ' + toHex(pc - 1, 4));
}, null, modes.implied, 2];
unk = [
'NOP',
nop,
readImplied,
modes.implied,
2
];
} else {
unk = ['???',
function() {
/*
unk = [
'???',
function() {
/*
debug('Unknown OpCode: ' + toHex(b) +
' at ' + toHex(pc - 1, 4));
*/
},
null, modes.implied,
1];
*/
},
readImplied,
modes.implied,
1
];
}
ops[b] = unk;
return unk;

193
js/intbasic/decompiler.js Normal file
View File

@ -0,0 +1,193 @@
/*exported IntBasicDump */
/*globals debug: false */
function IntBasicDump(mem)
{
var _mem = mem;
var LETTERS =
' ' +
' !"#$%&\'()*+,-./0123456789:;<=>?' +
'@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' +
'`abcdefghijklmnopqrstuvwxyz{|}~ ';
var TOKENS = {
0x02: '_',
0x03: ':',
0x04: 'LOAD',
0x05: 'SAVE',
0x06: 'CON',
0x07: 'RUN',
0x08: 'RUN',
0x09: 'DEL',
0x0A: ',',
0x0B: 'NEW',
0x0C: 'CLR',
0x0D: 'AUTO',
0x0E: ',',
0x0F: 'MAN',
0x10: 'HIMEM:',
0x11: 'LOMEM:',
0x12: '+',
0x13: '-',
0x14: '*',
0x15: '/',
0x16: '=',
0x17: '#',
0x18: '>=',
0x19: '>',
0x1A: '<=',
0x1B: '<>',
0x1C: '<',
0x1D: 'AND',
0x1E: 'OR',
0x1F: 'MOD',
0x20: '^',
0x21: '+',
0x22: '(',
0x23: ',',
0x24: 'THEN',
0x25: 'THEN',
0x26: ',',
0x27: ',',
0x28: '\'',
0x29: '\'',
0x2A: '(',
0x2B: '!',
0x2C: '!',
0x2D: '(',
0x2E: 'PEEK',
0x2F: 'RND',
0x30: 'SGN',
0x31: 'ABS',
0x32: 'PDL',
0x33: 'RNDX',
0x34: '(',
0x35: '+',
0x36: '-',
0x37: 'NOT',
0x38: '(',
0x39: '=',
0x3A: '#',
0x3B: 'LEN(',
0x3C: 'ASC(',
0x3D: 'SCRN(',
0x3E: ',',
0x3F: '(',
0x40: '$',
0x41: '$',
0x42: '(',
0x43: ',',
0x44: ',',
0x45: ';',
0x46: ';',
0x47: ';',
0x48: ',',
0x49: ',',
0x4A: ',',
0x4B: 'TEXT',
0x4C: 'GR',
0x4D: 'CALL',
0x4E: 'DIM',
0x4F: 'DIM',
0x50: 'TAB',
0x51: 'END',
0x52: 'INPUT',
0x53: 'INPUT',
0x54: 'INPUT',
0x55: 'FOR',
0x56: '=',
0x57: 'TO',
0x58: 'STEP',
0x59: 'NEXT',
0x5A: ',',
0x5B: 'RETURN',
0x5C: 'GOSUB',
0x5D: 'REM',
0x5E: 'LET',
0x5F: 'GOTO',
0x60: 'IF',
0x61: 'PRINT',
0x62: 'PRINT',
0x63: 'PRINT',
0x64: 'POKE',
0x65: ',',
0x66: 'COLOR=',
0x67: 'PLOT',
0x68: ',',
0x69: 'HLIN',
0x6A: ',',
0x6B: 'AT',
0x6C: 'VLIN',
0x6E: 'AT',
0x6F: 'VTAB',
0x70: '=',
0x71: '=',
0x72: ')',
0x73: ')',
0x74: 'LIST',
0x76: 'LIST',
0x77: 'POP',
0x78: 'NODSP',
0x79: 'NODSP',
0x7A: 'NOTRACE',
0x7B: 'DSP',
0x7C: 'DSP',
0x7D: 'TRACE',
0x7E: 'PR#',
0x7F: 'IN#'
};
function readByte(addr) {
var page = addr >> 8,
off = addr & 0xff;
return _mem.read(page, off);
}
function readWord(addr) {
var lsb, msb;
lsb = readByte(addr, debug);
msb = readByte(addr + 1, debug);
return (msb << 8) | lsb;
}
return {
toString: function () {
var str = '';
var addr = readWord(0xca); // Start
var himem = readWord(0x4c);
do {
/*var len = */readByte(addr++);
var lineno = readWord(addr);
addr += 2;
str += lineno;
str += ' ';
var val = 0;
do {
val = readByte(addr++);
if (val >= 0xB0 && val <= 0xB9) {
str += readWord(addr);
addr += 2;
}
else if (val < 0x80 && val > 0x01) {
var t = TOKENS[val];
if (t.length > 1)
str += ' ';
str += t;
if (t.length > 1)
str += ' ';
}
else if (val > 0x80)
str += LETTERS[val - 0x80];
} while (val != 0x01);
str += '\n';
} while (addr < himem);
return str;
}
};
}

View File

@ -84,6 +84,7 @@ function LanguageCard(io, slot, rom) {
};
function _access(off, val) {
var readMode = val === undefined;
var result = 0;
switch (off) {
case LOC.READBSR2: // 0xC080
@ -97,9 +98,11 @@ function LanguageCard(io, slot, rom) {
case LOC.WRITEBSR2: // 0xC081
case LOC._WRITEBSR2: // 0xC085
_readbsr = false;
_writebsr = _prewrite;
if (readMode) {
_writebsr = _prewrite;
}
_bsr2 = true;
_prewrite = true;
_prewrite = readMode;
_debug('Bank 2 Write');
break;
case LOC.OFFBSR2: // 0xC082
@ -113,9 +116,11 @@ function LanguageCard(io, slot, rom) {
case LOC.READWRBSR2: // 0xC083
case LOC._READWRBSR2: // 0xC087
_readbsr = true;
_writebsr = _prewrite;
if (readMode) {
_writebsr = _prewrite;
}
_bsr2 = true;
_prewrite = true;
_prewrite = readMode;
_debug('Bank 2 Read/Write');
break;
@ -130,9 +135,11 @@ function LanguageCard(io, slot, rom) {
case LOC.WRITEBSR1: // 0xC089
case LOC._WRITEBSR1: // 0xC08D
_readbsr = false;
_writebsr = _prewrite;
if (readMode) {
_writebsr = _prewrite;
}
_bsr2 = false;
_prewrite = true;
_prewrite = readMode;
_debug('Bank 1 Write');
break;
case LOC.OFFBSR1: // 0xC08A
@ -146,9 +153,11 @@ function LanguageCard(io, slot, rom) {
case LOC.READWRBSR1: // 0xC08B
case LOC._READWRBSR1: // 0xC08F
_readbsr = true;
_writebsr = _prewrite;
if (readMode) {
_writebsr = _prewrite;
}
_bsr2 = false;
_prewrite = true;
_prewrite = readMode;
_debug('Bank 1 Read/Write');
break;
@ -164,10 +173,6 @@ function LanguageCard(io, slot, rom) {
break;
}
if (val !== undefined) {
_prewrite = false;
}
if (_readbsr) {
_read1 = _bsr2 ? _bank2 : _bank1;
_read2 = _ram;

View File

@ -680,18 +680,24 @@ function updateLocalStorage() {
$('#manage').empty();
names.forEach(function(name) {
cat.push({'category': 'Local Saves',
'name': name,
'filename': 'local:' + name});
$('#manage').append('<span class="local_save">' +
name +
' <a href="#" onclick="doDelete(\'' +
name +
'\')">Delete</a><br /></span>');
cat.push({
'category': 'Local Saves',
'name': name,
'filename': 'local:' + name}
);
$('#manage').append(
'<span class="local_save">' +
name +
' <a href="#" onclick="doDelete(\'' +
name +
'\')">Delete</a><br /></span>'
);
});
cat.push({
'category': 'Local Saves',
'name': 'Manage Saves...',
'filename': 'local:__manage'
});
cat.push({'category': 'Local Saves',
'name': 'Manage Saves...',
'filename': 'local:__manage'});
}
function saveLocalStorage(drive, name) {
@ -928,31 +934,43 @@ $(function() {
var cancel = function() { $(this).dialog('close'); };
$('#loading').dialog({ autoOpen: false, modal: true });
$('#options').dialog({ autoOpen: false,
modal: true,
width: 320,
height: 400,
buttons: {'Close': cancel }});
$('#load').dialog({ autoOpen: false,
modal: true,
width: 540,
buttons: {'Cancel': cancel, 'Load': doLoad }});
$('#save').dialog({ autoOpen: false,
modal: true,
width: 320,
buttons: {'Cancel': cancel, 'Save': doSave }});
$('#manage').dialog({ autoOpen: false,
modal: true,
width: 320,
buttons: {'Close': cancel }});
$('#local_save').dialog({ autoOpen: false,
modal: true,
width: 530,
buttons: {'OK': cancel }});
$('#http_load').dialog({ autoOpen: false,
modal: true,
width: 530,
buttons: {'Cancel': cancel, 'OK': doLoadHTTP }});
$('#options').dialog({
autoOpen: false,
modal: true,
width: 320,
height: 400,
buttons: {'Close': cancel }
});
$('#load').dialog({
autoOpen: false,
modal: true,
width: 540,
buttons: {'Cancel': cancel, 'Load': doLoad }
});
$('#save').dialog({
autoOpen: false,
modal: true,
width: 320,
buttons: {'Cancel': cancel, 'Save': doSave }
});
$('#manage').dialog({
autoOpen: false,
modal: true,
width: 320,
buttons: {'Close': cancel }
});
$('#local_save').dialog({
autoOpen: false,
modal: true,
width: 530,
buttons: {'OK': cancel }
});
$('#http_load').dialog({
autoOpen: false,
modal: true,
width: 530,
buttons: {'Cancel': cancel, 'OK': doLoadHTTP }
});
if (window.localStorage !== undefined) {
$('.disksave').show();

View File

@ -371,7 +371,7 @@ var drivelights = new DriveLights();
var io = new Apple2IO(cpu, vm);
var keyboard = new KeyBoard2e(io);
var mmu = new MMU(cpu, gr, gr2, hgr, hgr2, io, rom);
var mmu = new MMU(cpu, vm, gr, gr2, hgr, hgr2, io, rom);
cpu.addPageHandler(mmu);
@ -662,18 +662,24 @@ function updateLocalStorage() {
$('#manage').empty();
names.forEach(function(name) {
cat.push({'category': 'Local Saves',
'name': name,
'filename': 'local:' + name});
$('#manage').append('<span class="local_save">' +
name +
' <a href="#" onclick="doDelete(\'' +
name +
'\')">Delete</a><br /></span>');
cat.push({
'category': 'Local Saves',
'name': name,
'filename': 'local:' + name
});
$('#manage').append(
'<span class="local_save">' +
name +
' <a href="#" onclick="doDelete(\'' +
name +
'\')">Delete</a><br /></span>'
);
});
cat.push({
'category': 'Local Saves',
'name': 'Manage Saves...',
'filename': 'local:__manage'
});
cat.push({'category': 'Local Saves',
'name': 'Manage Saves...',
'filename': 'local:__manage'});
}
function saveLocalStorage(drive, name) {
@ -919,27 +925,37 @@ $(function() {
var cancel = function() { $(this).dialog('close'); };
$('#loading').dialog({ autoOpen: false, modal: true });
$('#options').dialog({ autoOpen: false,
modal: true,
width: 320,
height: 400,
buttons: {'Close': cancel }});
$('#load').dialog({ autoOpen: false,
modal: true,
width: 540,
buttons: {'Cancel': cancel, 'Load': doLoad }});
$('#save').dialog({ autoOpen: false,
modal: true,
width: 320,
buttons: {'Cancel': cancel, 'Save': doSave }});
$('#manage').dialog({ autoOpen: false,
modal: true,
width: 320,
buttons: {'Close': cancel }});
$('#http_load').dialog({ autoOpen: false,
modal: true,
width: 530,
buttons: {'Cancel': cancel, 'OK': doLoadHTTP }});
$('#options').dialog({
autoOpen: false,
modal: true,
width: 320,
height: 400,
buttons: {'Close': cancel }
});
$('#load').dialog({
autoOpen: false,
modal: true,
width: 540,
buttons: {'Cancel': cancel, 'Load': doLoad }
});
$('#save').dialog({
autoOpen: false,
modal: true,
width: 320,
buttons: {'Cancel': cancel, 'Save': doSave }
});
$('#manage').dialog({
autoOpen: false,
modal: true,
width: 320,
buttons: {'Close': cancel }
});
$('#http_load').dialog({
autoOpen: false,
modal: true,
width: 530,
buttons: {'Cancel': cancel, 'OK': doLoadHTTP }
});
if (window.localStorage !== undefined) {
$('.disksave').show();

View File

@ -11,11 +11,10 @@
/*exported MMU */
/*globals debug: false, toHex: false
hiresMode: false,
RAM: false
*/
function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
function MMU(cpu, vm, lores1, lores2, hires1, hires2, io, rom)
{
'use strict';
@ -34,6 +33,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
// Auxilliary ROM
var _intcxrom;
var _slot3rom;
var _intc8rom;
// Auxilliary RAM
var _auxRamRead;
@ -41,8 +41,9 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
var _altzp;
// Video
var _80store = false;
var _80store;
var _page2;
var _hires;
var _vbEnd = 0;
@ -81,8 +82,10 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_80STORE: 0x18,
VERTBLANK: 0x19,
PAGE1: 0x54, // select text/graphics page1 main/aux
PAGE2: 0x55, // select text/graphics page2 main/aux
PAGE1: 0x54, // select text/graphics page1 main/aux
PAGE2: 0x55, // select text/graphics page2 main/aux
RESET_HIRES: 0x56,
SET_HIRES: 0x57,
// Bank 2
READBSR2: 0x80,
@ -121,12 +124,15 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_intcxrom = false;
_slot3rom = false;
_intc8rom = false;
_80store = false;
_page2 = false;
_hires = false;
}
function _debug() {
/*eslint no-console: 0*/
// console.debug.apply(this, arguments);
}
@ -168,6 +174,14 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
function AuxRom() {
return {
read: function(page, off) {
if (page == 0xc3) {
_intc8rom = true;
_updateBanks();
}
if (page == 0xcf && off == 0xff) {
_intc8rom = false;
_updateBanks();
}
return rom.read(page, off);
},
write: function() {}
@ -194,8 +208,6 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
];
var memE0_FF = [rom, new RAM(0xE0,0xFF), new RAM(0xE0,0xFF)];
io.setSlot(3, auxRom);
/*
* Initialize read/write banks
*/
@ -299,7 +311,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_readPages[idx] = _pages[idx][1];
_writePages[idx] = _pages[idx][1];
}
if (hiresMode) {
if (_hires) {
for (idx = 0x20; idx < 0x40; idx++) {
_readPages[idx] = _pages[idx][1];
_writePages[idx] = _pages[idx][1];
@ -310,7 +322,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_readPages[idx] = _pages[idx][0];
_writePages[idx] = _pages[idx][0];
}
if (hiresMode) {
if (_hires) {
for (idx = 0x20; idx < 0x40; idx++) {
_readPages[idx] = _pages[idx][0];
_writePages[idx] = _pages[idx][0];
@ -327,6 +339,14 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
for (idx = 0xc1; idx < 0xd0; idx++) {
_readPages[idx] = _pages[idx][0];
}
if (!_slot3rom) {
_readPages[0xc3] = _pages[0xc3][1];
}
if (_intc8rom) {
for (idx = 0xc8; idx < 0xd0; idx++) {
_readPages[idx] = _pages[idx][1];
}
}
}
if (_altzp) {
@ -386,6 +406,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
function _access(off, val) {
var result;
var readMode = val === undefined;
switch (off) {
// Apple //e memory management
@ -438,6 +459,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
case LOC.INTCXROMOFF:
if (val !== undefined) {
_intcxrom = false;
_intc8rom = false;
_debug('Int CX ROM Off');
}
break;
@ -459,13 +481,13 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_debug('Alt ZP On');
}
break;
case LOC.SLOTC3ROMOFF:
if (typeof val != 'undefined') {
case LOC.SLOTC3ROMOFF: // 0x0A
if (val !== undefined) {
_slot3rom = false;
_debug('Slot 3 ROM Off');
}
break;
case LOC.SLOTC3ROMON:
case LOC.SLOTC3ROMON: // 0x0B
if (val !== undefined) {
_slot3rom = true;
_debug('Slot 3 ROM On');
@ -475,18 +497,30 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
// Graphics Switches
case LOC.PAGE1:
if (_80store) {
_page2 = false;
} else {
_page2 = false;
if (!_80store) {
result = io.ioSwitch(off, val);
}
_debug('Page 2 off');
break;
case LOC.PAGE2:
if (_80store) {
_page2 = true;
} else {
_page2 = true;
if (!_80store) {
result = io.ioSwitch(off, val);
}
_debug('Page 2 on');
break;
case LOC.RESET_HIRES:
_hires = false;
result = io.ioSwitch(off, val);
_debug('Hires off');
break;
case LOC.SET_HIRES:
_hires = true;
result = io.ioSwitch(off, val);
_debug('Hires on');
break;
// Language Card Switches
@ -503,8 +537,8 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
case LOC._WRITEBSR2: // 0xC085
_bank1 = false;
_readbsr = false;
_writebsr = _prewrite;
_prewrite = true;
if (readMode) { _writebsr = _prewrite; }
_prewrite = readMode;
// _debug('Bank 2 Write');
break;
case LOC.OFFBSR2: // 0xC082
@ -519,8 +553,8 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
case LOC._READWRBSR2: // 0xC087
_bank1 = false;
_readbsr = true;
_writebsr = _prewrite;
_prewrite = true;
if (readMode) { _writebsr = _prewrite; }
_prewrite = readMode;
// _debug('Bank 2 Read/Write');
break;
case LOC.READBSR1: // 0xC088
@ -535,8 +569,8 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
case LOC._WRITEBSR1: // 0xC08D
_bank1 = true;
_readbsr = false;
_writebsr = _prewrite;
_prewrite = true;
if (readMode) { _writebsr = _prewrite; }
_prewrite = readMode;
// _debug('Bank 1 Write');
break;
case LOC.OFFBSR1: // 0xC08A
@ -551,8 +585,8 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
case LOC._READWRBSR1: // 0xC08F
_bank1 = true;
_readbsr = true;
_writebsr = _prewrite;
_prewrite = true;
if (readMode) { _writebsr = _prewrite; }
_prewrite = readMode;
//_debug('Bank 1 Read/Write');
break;
@ -600,10 +634,6 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
break;
}
if (val !== undefined) {
_prewrite = false;
}
if (result !== undefined)
return result;
@ -625,6 +655,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
debug('reset');
_initSwitches();
_updateBanks();
vm.reset();
io.reset();
},
read: function mmu_read(page, off, debug) {
@ -645,6 +676,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
intcxrom: _intcxrom,
slot3rom: _slot3rom,
intc8rom: _intc8rom,
auxRamRead: _auxRamRead,
auxRamWrite: _auxRamWrite,
altzp: _altzp,
@ -670,6 +702,7 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom)
_intcxrom = state.intcxrom;
_slot3rom = state.slot3rom;
_intc8rom = state.intc8rom;
_auxRamRead = state.auxRamRead;
_auxRamWrite = state.auxRamWrite;
_altzp = state.altzp;

1559
js/roms/original.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
/* Copyright 2010-2016 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
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation. No representations are made about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*/
/*exported Slot3 */
function Slot3(io, slot, rom)
{
'use strict';
return {
start: function slot3_start() {
return 0xc3;
},
end: function slot3_end() {
return 0xc3;
},
read: function slot3_read(page, off) {
return rom.read(page, off);
},
write: function slot3_write() {
}
};
}