/*
BankedMemoryEntry.java
(c) 2008-2016 Edward Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.engine.memory;
import java.io.IOException;
import java.io.PrintWriter;
import ejs.base.properties.IProperty;
import ejs.base.settings.ISettingSection;
import ejs.base.settings.Logging;
import v9t9.common.client.ISettingsHandler;
import v9t9.common.cpu.ICpu;
import v9t9.common.events.IEventNotifier;
import v9t9.common.memory.IMemory;
import v9t9.common.memory.IMemoryDomain;
/**
* Banked memory exposes different contents based on the
* current bank. The concrete implementation reacts to
* bank changes via {@link #doSwitchBank(int)} and may override
* other MemoryEntry methods accordingly.
* @author ejs
*
*/
public abstract class BankedMemoryEntry extends MemoryEntry {
private int currentBankIndex;
protected int bankCount;
private IProperty dumpFullInstructions;
/**
* Only use when reconstructing
*/
public BankedMemoryEntry() {
}
public BankedMemoryEntry(
ISettingsHandler settings,
IMemory memory,
String name,
IMemoryDomain domain,
int addr,
int size,
int bankCount) {
super(name, domain, addr, size, null);
this.dumpFullInstructions = settings.get(ICpu.settingDumpFullInstructions);
this.memory = memory;
this.currentBankIndex = -1;
this.bankCount = bankCount;
}
/* (non-Javadoc)
* @see v9t9.engine.memory.MemoryEntry#reset()
*/
@Override
public void reset() {
super.reset();
selectBank(0);
}
@Override
public void onMap() {
super.onMap();
if (currentBankIndex < 0)
currentBankIndex = 0;
doSelectBank(currentBankIndex);
}
public boolean selectBank(int bank) {
bank %= bankCount;
if (currentBankIndex != bank) {
doSelectBank(bank);
return true;
}
return false;
}
protected void doSelectBank(int bank) {
PrintWriter pw = Logging.getLog(dumpFullInstructions);
if (pw != null)
pw.println("Switching to bank " + bank);
doSwitchBank(bank);
currentBankIndex = bank;
getMemory().notifyListenersOfLogicalChange(this);
currentBankIndex = bank;
}
abstract protected void doSwitchBank(int bank);
public int getCurrentBank() {
return currentBankIndex;
}
public int getBankCount() {
return bankCount;
}
public int getBankSize() {
return getSize();
}
@Override
public void saveState(ISettingSection section) {
super.saveState(section);
section.put("CurrentBankIndex", currentBankIndex);
doSaveBankEntries(section.addSection("Banks"));
}
/* (non-Javadoc)
* @see v9t9.engine.memory.MemoryEntry#loadMemory(v9t9.common.events.IEventNotifier, ejs.base.settings.ISettingSection)
*/
@Override
public void loadMemory(IEventNotifier notifier, ISettingSection section) throws IOException {
super.loadMemory(notifier, section);
doLoadBankEntries(notifier, section.getSection("Banks"));
selectBank(section.getInt("CurrentBankIndex"));
}
abstract protected void doSaveBankEntries(ISettingSection section);
abstract protected void doLoadBankEntries(IEventNotifier notifier, ISettingSection section);
@Override
protected void saveMemoryContents(ISettingSection section) {
// do this per-bank
}
@Override
protected void loadMemoryContents(ISettingSection section) {
// do this per-bank
}
@Override
public String getUniqueName() {
return super.getUniqueName() + " #" + currentBankIndex + "";
}
}