mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
Memory fixes, cleanup.
This commit is contained in:
parent
dc146bf630
commit
0343497abc
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
* implied warranty.
|
||||
*/
|
||||
|
||||
/*jshint browser:true */
|
||||
/*globals allocMemPages: false, debug: false,
|
||||
base64_encode: false, base64_decode: false,
|
||||
enhanced: false */
|
||||
|
@ -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
193
js/intbasic/decompiler.js
Normal 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;
|
||||
}
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
90
js/main2.js
90
js/main2.js
@ -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();
|
||||
|
82
js/main2e.js
82
js/main2e.js
@ -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();
|
||||
|
93
js/mmu.js
93
js/mmu.js
@ -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
1559
js/roms/original.js
Normal file
File diff suppressed because it is too large
Load Diff
32
js/slot3.js
32
js/slot3.js
@ -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() {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user