mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Exposes much of the auxiliary and language card stuff to the IIgs bus.
This commit is contained in:
parent
885fae1534
commit
94a6da6b7d
@ -163,19 +163,32 @@ template <typename Machine> class AuxiliaryMemorySwitches {
|
||||
}
|
||||
}
|
||||
|
||||
const MainState &main_state() {
|
||||
/// Provides part of the IIgs interface.
|
||||
void set_state(uint8_t value) {
|
||||
switches_.alternative_zero_page = value & 0x80;
|
||||
switches_.video_page_2 = value & 0x40;
|
||||
switches_.read_auxiliary_memory = value & 0x20;
|
||||
switches_.write_auxiliary_memory = value & 0x10;
|
||||
switches_.internal_CX_rom = value & 0x01;
|
||||
|
||||
set_main_paging();
|
||||
set_zero_page_paging();
|
||||
set_card_paging();
|
||||
}
|
||||
|
||||
const MainState &main_state() const {
|
||||
return main_state_;
|
||||
}
|
||||
|
||||
const CardState &card_state() {
|
||||
const CardState &card_state() const {
|
||||
return card_state_;
|
||||
}
|
||||
|
||||
const ZeroState zero_state() {
|
||||
const ZeroState zero_state() const {
|
||||
return switches_.alternative_zero_page;
|
||||
}
|
||||
|
||||
const SwitchState switches() {
|
||||
const SwitchState switches() const {
|
||||
return switches_;
|
||||
}
|
||||
|
||||
|
@ -73,10 +73,22 @@ template <typename Machine> class LanguageCardSwitches {
|
||||
}
|
||||
|
||||
/// Provides read-only access to the current language card switch state.
|
||||
const State &state() {
|
||||
const State &state() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
/// Provides relevant parts of the IIgs interface.
|
||||
void set_state(uint8_t value) {
|
||||
const auto previous_state = state_;
|
||||
|
||||
state_.read = value & 0x08;
|
||||
state_.bank1 = value & 0x04;
|
||||
|
||||
if(previous_state != state_) {
|
||||
machine_.set_language_card_paging();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Machine &machine_;
|
||||
State state_;
|
||||
|
@ -89,6 +89,9 @@ class ConcreteMachine:
|
||||
const auto ®ion = MemoryMapRegion(memory_, address);
|
||||
|
||||
if(region.flags & MemoryMap::Region::IsIO) {
|
||||
// Ensure classic auxiliary and language card accesses have effect.
|
||||
memory_.access(uint16_t(address), isReadOperation(operation));
|
||||
|
||||
switch(address & 0xffff) {
|
||||
|
||||
// New video register.
|
||||
@ -102,6 +105,15 @@ class ConcreteMachine:
|
||||
}
|
||||
break;
|
||||
|
||||
// Shadow register.
|
||||
case 0xc035:
|
||||
if(isReadOperation(operation)) {
|
||||
*value = memory_.get_shadow_register();
|
||||
} else {
|
||||
memory_.set_shadow_register(*value);
|
||||
}
|
||||
break;
|
||||
|
||||
// Speed register.
|
||||
case 0xc036:
|
||||
if(isReadOperation(operation)) {
|
||||
@ -113,10 +125,48 @@ class ConcreteMachine:
|
||||
}
|
||||
break;
|
||||
|
||||
// [Memory] State register.
|
||||
case 0xc068:
|
||||
if(isReadOperation(operation)) {
|
||||
*value = memory_.get_state_register();
|
||||
} else {
|
||||
memory_.set_state_register(*value);
|
||||
}
|
||||
break;
|
||||
|
||||
// Various independent memory switch reads [TODO: does the IIe-style keyboard the low seven?].
|
||||
#define SwitchRead(s) *value = memory_.s ? 0x80 : 0x00
|
||||
#define LanguageRead(s) SwitchRead(language_card_switches().state().s)
|
||||
#define AuxiliaryRead(s) SwitchRead(auxiliary_switches().switches().s)
|
||||
case 0xc011: LanguageRead(bank1); break;
|
||||
case 0xc012: LanguageRead(read); break;
|
||||
case 0xc013: AuxiliaryRead(read_auxiliary_memory); break;
|
||||
case 0xc014: AuxiliaryRead(write_auxiliary_memory); break;
|
||||
case 0xc015: AuxiliaryRead(internal_CX_rom); break;
|
||||
case 0xc016: AuxiliaryRead(alternative_zero_page); break;
|
||||
case 0xc017: AuxiliaryRead(slot_C3_rom); break;
|
||||
#undef AuxiliaryRead
|
||||
#undef LanguageRead
|
||||
#undef SwitchRead
|
||||
|
||||
// These were all dealt with by the call to memory_.access.
|
||||
// TODO: subject to read data? Does vapour lock apply?
|
||||
case 0xc000: case 0xc001: case 0xc002: case 0xc003: case 0xc004: case 0xc005:
|
||||
case 0xc006: case 0xc007: case 0xc008: case 0xc009: case 0xc00a: case 0xc00b:
|
||||
case 0xc054: case 0xc055: case 0xc056: case 0xc057:
|
||||
break;
|
||||
|
||||
default:
|
||||
if(address < 0xc100) {
|
||||
// TODO: all other IO accesses.
|
||||
printf("Unhandled IO: %04x\n", address);
|
||||
assert(false);
|
||||
} else {
|
||||
// Card IO. Not implemented!
|
||||
if(isReadOperation(operation)) {
|
||||
*value = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(isReadOperation(operation)) {
|
||||
|
@ -180,7 +180,7 @@ class MemoryMap {
|
||||
set_shadowing();
|
||||
}
|
||||
|
||||
// MARK: - Live bus access notifications.
|
||||
// MARK: - Live bus access notifications and register access.
|
||||
|
||||
void set_shadow_register(uint8_t value) {
|
||||
const uint8_t diff = value ^ shadow_register_;
|
||||
@ -196,6 +196,10 @@ class MemoryMap {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t get_shadow_register() const {
|
||||
return shadow_register_;
|
||||
}
|
||||
|
||||
void set_speed_register(uint8_t value) {
|
||||
const uint8_t diff = value ^ speed_register_;
|
||||
speed_register_ = value;
|
||||
@ -204,16 +208,45 @@ class MemoryMap {
|
||||
}
|
||||
}
|
||||
|
||||
void set_state_register(uint8_t value) {
|
||||
auxiliary_switches_.set_state(value);
|
||||
language_card_.set_state(value);
|
||||
}
|
||||
|
||||
uint8_t get_state_register() const {
|
||||
const auto auxiliary_switches = auxiliary_switches_.switches();
|
||||
const auto language_state = language_card_.state();
|
||||
|
||||
return
|
||||
(auxiliary_switches.alternative_zero_page ? 0x80 : 0x00) |
|
||||
(auxiliary_switches.video_page_2 ? 0x40 : 0x00) |
|
||||
(auxiliary_switches.read_auxiliary_memory ? 0x20 : 0x00) |
|
||||
(auxiliary_switches.write_auxiliary_memory ? 0x10 : 0x00) |
|
||||
(language_state.read ? 0x08 : 0x00) |
|
||||
(language_state.bank1 ? 0x04 : 0x00) |
|
||||
(auxiliary_switches.internal_CX_rom ? 0x01 : 0x00);
|
||||
}
|
||||
|
||||
void access(uint16_t address, bool is_read) {
|
||||
auxiliary_switches_.access(address, is_read);
|
||||
if(address &0xfff0 == 0xc080) language_card_.access(address, is_read);
|
||||
if((address & 0xfff0) == 0xc080) language_card_.access(address, is_read);
|
||||
}
|
||||
|
||||
using AuxiliaryMemorySwitches = Apple::II::AuxiliaryMemorySwitches<MemoryMap>;
|
||||
const AuxiliaryMemorySwitches &auxiliary_switches() const {
|
||||
return auxiliary_switches_;
|
||||
}
|
||||
|
||||
using LanguageCardSwitches = Apple::II::LanguageCardSwitches<MemoryMap>;
|
||||
const LanguageCardSwitches &language_card_switches() const {
|
||||
return language_card_;
|
||||
}
|
||||
|
||||
private:
|
||||
Apple::II::AuxiliaryMemorySwitches<MemoryMap> auxiliary_switches_;
|
||||
Apple::II::LanguageCardSwitches<MemoryMap> language_card_;
|
||||
friend Apple::II::AuxiliaryMemorySwitches<MemoryMap>;
|
||||
friend Apple::II::LanguageCardSwitches<MemoryMap>;
|
||||
AuxiliaryMemorySwitches auxiliary_switches_;
|
||||
LanguageCardSwitches language_card_;
|
||||
friend AuxiliaryMemorySwitches;
|
||||
friend LanguageCardSwitches;
|
||||
|
||||
uint8_t shadow_register_ = 0x08;
|
||||
uint8_t speed_register_ = 0x00;
|
||||
|
Loading…
Reference in New Issue
Block a user