1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-01 11:49:58 +00:00

Exposes much of the auxiliary and language card stuff to the IIgs bus.

This commit is contained in:
Thomas Harte 2020-10-28 21:58:20 -04:00
parent 885fae1534
commit 94a6da6b7d
4 changed files with 122 additions and 14 deletions

View File

@ -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_; return main_state_;
} }
const CardState &card_state() { const CardState &card_state() const {
return card_state_; return card_state_;
} }
const ZeroState zero_state() { const ZeroState zero_state() const {
return switches_.alternative_zero_page; return switches_.alternative_zero_page;
} }
const SwitchState switches() { const SwitchState switches() const {
return switches_; return switches_;
} }

View File

@ -73,10 +73,22 @@ template <typename Machine> class LanguageCardSwitches {
} }
/// Provides read-only access to the current language card switch state. /// Provides read-only access to the current language card switch state.
const State &state() { const State &state() const {
return state_; 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: private:
Machine &machine_; Machine &machine_;
State state_; State state_;

View File

@ -89,6 +89,9 @@ class ConcreteMachine:
const auto &region = MemoryMapRegion(memory_, address); const auto &region = MemoryMapRegion(memory_, address);
if(region.flags & MemoryMap::Region::IsIO) { 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) { switch(address & 0xffff) {
// New video register. // New video register.
@ -102,6 +105,15 @@ class ConcreteMachine:
} }
break; break;
// Shadow register.
case 0xc035:
if(isReadOperation(operation)) {
*value = memory_.get_shadow_register();
} else {
memory_.set_shadow_register(*value);
}
break;
// Speed register. // Speed register.
case 0xc036: case 0xc036:
if(isReadOperation(operation)) { if(isReadOperation(operation)) {
@ -113,10 +125,48 @@ class ConcreteMachine:
} }
break; 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: default:
if(address < 0xc100) {
// TODO: all other IO accesses. // TODO: all other IO accesses.
printf("Unhandled IO: %04x\n", address); printf("Unhandled IO: %04x\n", address);
assert(false); assert(false);
} else {
// Card IO. Not implemented!
if(isReadOperation(operation)) {
*value = 0xff;
}
}
} }
} else { } else {
if(isReadOperation(operation)) { if(isReadOperation(operation)) {

View File

@ -180,7 +180,7 @@ class MemoryMap {
set_shadowing(); set_shadowing();
} }
// MARK: - Live bus access notifications. // MARK: - Live bus access notifications and register access.
void set_shadow_register(uint8_t value) { void set_shadow_register(uint8_t value) {
const uint8_t diff = value ^ shadow_register_; 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) { void set_speed_register(uint8_t value) {
const uint8_t diff = value ^ speed_register_; const uint8_t diff = value ^ speed_register_;
speed_register_ = value; 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) { void access(uint16_t address, bool is_read) {
auxiliary_switches_.access(address, 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: private:
Apple::II::AuxiliaryMemorySwitches<MemoryMap> auxiliary_switches_; AuxiliaryMemorySwitches auxiliary_switches_;
Apple::II::LanguageCardSwitches<MemoryMap> language_card_; LanguageCardSwitches language_card_;
friend Apple::II::AuxiliaryMemorySwitches<MemoryMap>; friend AuxiliaryMemorySwitches;
friend Apple::II::LanguageCardSwitches<MemoryMap>; friend LanguageCardSwitches;
uint8_t shadow_register_ = 0x08; uint8_t shadow_register_ = 0x08;
uint8_t speed_register_ = 0x00; uint8_t speed_register_ = 0x00;