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:
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_;
|
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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
|
@ -89,6 +89,9 @@ class ConcreteMachine:
|
|||||||
const auto ®ion = MemoryMapRegion(memory_, address);
|
const auto ®ion = 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)) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user