1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-30 22:29:56 +00:00

Adds documentation, ensures the language card signals less noisily.

This commit is contained in:
Thomas Harte 2020-10-23 18:44:47 -04:00
parent 9371a8993f
commit 966241b4cc
2 changed files with 39 additions and 9 deletions

View File

@ -12,6 +12,17 @@
namespace Apple {
namespace II {
/*!
Models the auxiliary memory soft switches, added as of the Apple IIe, which allow access to the auxiliary 64kb of RAM and to
the additional almost-4kb of ROM.
Relevant memory accesses should be fed to this class; it'll call:
* machine.set_main_paging() if anything in the 'main' state changes, i.e. the lower 48kb excluding the zero and stack pages;
* machine.set_card_state() if anything changes with where ROM should appear rather than cards in the $Cxxx range; and
* machine.set_zero_page_paging() if the selection of the lowest two pages of RAM changes.
Implementation observation: as implemented on the IIe, the zero page setting also affects what happens in the language card area.
*/
template <typename Machine> class AuxiliaryMemorySwitches {
public:
static constexpr bool Auxiliary = true;
@ -35,7 +46,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
/// Describes banking state in the range $2000$3FFF.
Region region_20_40;
bool operator != (const MainState &rhs) {
bool operator != (const MainState &rhs) const {
return
base.read != rhs.base.read || base.write != rhs.base.write ||
region_04_08.read != rhs.region_04_08.read || region_04_08.write != rhs.region_04_08.write ||
@ -54,7 +65,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
/// @c true indicates that the built-in ROM should appear from $C800 to $CFFF; @c false indicates that cards should service those accesses.
bool region_C8_D0 = false;
bool operator != (const CardState &rhs) {
bool operator != (const CardState &rhs) const {
return
region_C1_C3 != rhs.region_C1_C3 ||
region_C3 != rhs.region_C3 ||
@ -164,7 +175,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
MainState main_state_;
void set_main_paging() {
MainState previous_state = main_state_;
const auto previous_state = main_state_;
// The two appropriately named switches provide the base case.
main_state_.base.read = switches_.read_auxiliary_memory;
@ -191,7 +202,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
CardState card_state_;
void set_card_paging() {
CardState previous_state = card_state_;
const auto previous_state = card_state_;
// By default apply the CX switch through to $C7FF.
card_state_.region_C1_C3 = card_state_.region_C4_C8 = switches_.internal_CX_rom;

View File

@ -12,6 +12,12 @@
namespace Apple {
namespace II {
/*!
Models the language card soft switches, present on any Apple II with a language card and provided built-in from the IIe onwards.
Relevant memory accesses should be fed to this class; it'll call:
* machine.set_language_card_paging() if the proper mapped state changes.
*/
template <typename Machine> class LanguageCardSwitches {
public:
struct State {
@ -26,14 +32,20 @@ template <typename Machine> class LanguageCardSwitches {
/// @c false indicates that RAM is selected for writing.
bool write = false;
/// Contains the state of the internal pre-write flip flop; it does not directly affect the current memory map.
bool pre_write = false;
bool operator != (const State &rhs) const {
return
bank1 != rhs.bank1 ||
read != rhs.read ||
write != rhs.write;
}
};
LanguageCardSwitches(Machine &machine) : machine_(machine) {}
/// Used by an owner to forward any access to $c08x.
void access(uint16_t address, bool is_read) {
const auto previous_state = state_;
// Quotes below taken from Understanding the Apple II, p. 5-28 and 5-29.
// "A3 controls the 4K bank selection"
@ -44,7 +56,7 @@ template <typename Machine> class LanguageCardSwitches {
state_.read = !(((address&2) >> 1) ^ (address&1));
// "The WRITE ENABLE' flip-flop is reset by an odd read access to the $C08X range when the PRE-WRITE flip-flop is set."
if(state_.pre_write && is_read && (address&1)) state_.write = false;
if(pre_write_ && is_read && (address&1)) state_.write = false;
// "[The WRITE ENABLE' flip-flop] is set by an even access in the $C08X range."
if(!(address&1)) state_.write = true;
@ -52,10 +64,12 @@ template <typename Machine> class LanguageCardSwitches {
// ("Any other type of access causes the WRITE ENABLE' flip-flop to hold its current state.")
// "The PRE-WRITE flip-flop is set by an odd read access in the $C08X range. It is reset by an even access or a write access."
state_.pre_write = is_read ? (address&1) : false;
pre_write_ = is_read ? (address&1) : false;
// Apply whatever the net effect of all that is to the memory map.
machine_.set_language_card_paging();
if(previous_state != state_) {
machine_.set_language_card_paging();
}
}
/// Provides read-only access to the current language card switch state.
@ -66,6 +80,11 @@ template <typename Machine> class LanguageCardSwitches {
private:
Machine &machine_;
State state_;
// This is an additional flip flop contained on the language card, but
// it is one step removed from current banking state, so I've excluded it
// from the State struct.
bool pre_write_ = false;
};
}