mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
211 lines
5.3 KiB
JavaScript
211 lines
5.3 KiB
JavaScript
/* Copyright 2010-2019 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.
|
|
*/
|
|
|
|
import RAM from '../ram';
|
|
import { debug } from '../util';
|
|
|
|
export default function LanguageCard(io, rom) {
|
|
var _rom = rom;
|
|
var _bank1 = null;
|
|
var _bank2 = null;
|
|
var _ram = null;
|
|
|
|
var _readbsr = false;
|
|
var _writebsr = false;
|
|
var _bsr2 = false;
|
|
var _prewrite = false;
|
|
|
|
var _read1 = null;
|
|
var _read2 = null;
|
|
|
|
var _write1 = null;
|
|
var _write2 = null;
|
|
|
|
function _init() {
|
|
debug('Language card');
|
|
|
|
_bank1 = new RAM(0xd0, 0xdf);
|
|
_bank2 = new RAM(0xd0, 0xdf);
|
|
_ram = new RAM(0xe0, 0xff);
|
|
|
|
_write1 = _rom;
|
|
_write2 = _rom;
|
|
|
|
_read1 = _rom;
|
|
_read2 = _rom;
|
|
}
|
|
|
|
function _debug() {
|
|
// debug.apply(null, arguments);
|
|
}
|
|
|
|
_init();
|
|
|
|
var LOC = {
|
|
// Bank 2
|
|
READBSR2: 0x80,
|
|
WRITEBSR2: 0x81,
|
|
OFFBSR2: 0x82,
|
|
READWRBSR2: 0x83,
|
|
|
|
// Bank 1
|
|
READBSR1: 0x88,
|
|
WRITEBSR1: 0x89,
|
|
OFFBSR1: 0x8a,
|
|
READWRBSR1: 0x8b,
|
|
};
|
|
|
|
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;
|
|
switch (off & 0x8B) {
|
|
case LOC.READBSR2: // 0xC080
|
|
_readbsr = true;
|
|
_writebsr = false;
|
|
_bsr2 = true;
|
|
_prewrite = false;
|
|
_debug('Bank 2 Read');
|
|
break;
|
|
case LOC.WRITEBSR2: // 0xC081
|
|
_readbsr = false;
|
|
if (readMode) {
|
|
_writebsr = _prewrite;
|
|
}
|
|
_bsr2 = true;
|
|
_prewrite = readMode;
|
|
_debug('Bank 2 Write');
|
|
break;
|
|
case LOC.OFFBSR2: // 0xC082
|
|
_readbsr = false;
|
|
_writebsr = false;
|
|
_bsr2 = true;
|
|
_prewrite = false;
|
|
_debug('Bank 2 Off');
|
|
break;
|
|
case LOC.READWRBSR2: // 0xC083
|
|
_readbsr = true;
|
|
if (readMode) {
|
|
_writebsr = _prewrite;
|
|
}
|
|
_bsr2 = true;
|
|
_prewrite = readMode;
|
|
_debug('Bank 2 Read/Write');
|
|
break;
|
|
|
|
case LOC.READBSR1: // 0xC088
|
|
_readbsr = true;
|
|
_writebsr = false;
|
|
_bsr2 = false;
|
|
_prewrite = false;
|
|
_debug('Bank 1 Read');
|
|
break;
|
|
case LOC.WRITEBSR1: // 0xC089
|
|
_readbsr = false;
|
|
if (readMode) {
|
|
_writebsr = _prewrite;
|
|
}
|
|
_bsr2 = false;
|
|
_prewrite = readMode;
|
|
_debug('Bank 1 Write');
|
|
break;
|
|
case LOC.OFFBSR1: // 0xC08A
|
|
_readbsr = false;
|
|
_writebsr = false;
|
|
_bsr2 = false;
|
|
_prewrite = false;
|
|
_debug('Bank 1 Off');
|
|
break;
|
|
case LOC.READWRBSR1: // 0xC08B
|
|
_readbsr = true;
|
|
if (readMode) {
|
|
_writebsr = _prewrite;
|
|
}
|
|
_bsr2 = false;
|
|
_prewrite = readMode;
|
|
_debug('Bank 1 Read/Write');
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
_updateBanks();
|
|
|
|
return result;
|
|
}
|
|
|
|
return {
|
|
start: function() {
|
|
return 0xd0;
|
|
},
|
|
end: function() {
|
|
return 0xff;
|
|
},
|
|
ioSwitch: function(off, val) {
|
|
return _access(off, val);
|
|
},
|
|
read: function(page, off) {
|
|
var result = 0;
|
|
if (page < 0xe0) {
|
|
result = _read1.read(page, off);
|
|
} else {
|
|
result = _read2.read(page, off);
|
|
}
|
|
return result;
|
|
},
|
|
write: function(page, off, val) {
|
|
if (page < 0xe0) {
|
|
_write1.write(page, off, val);
|
|
} else {
|
|
_write2.write(page, off, val);
|
|
}
|
|
},
|
|
getState: function() {
|
|
return {
|
|
readbsr: _readbsr,
|
|
writebsr: _writebsr,
|
|
bsr2: _bsr2,
|
|
prewrite: _prewrite,
|
|
ram: _ram.getState(),
|
|
bank1: _bank1.getState(),
|
|
bank2: _bank2.getState()
|
|
};
|
|
},
|
|
setState: function(state) {
|
|
_readbsr = state.readbsr;
|
|
_writebsr = state.writebsr;
|
|
_bsr2 = state.bsr2;
|
|
_prewrite = state.prewrite;
|
|
_ram.setState(state.ram);
|
|
_bank1.setState(state.bank1);
|
|
_bank2.setState(state.bank2);
|
|
_updateBanks();
|
|
}
|
|
};
|
|
}
|