diff --git a/Machines/Thomson/MO5/MO5.cpp b/Machines/Thomson/MO5/MO5.cpp index e3e6eddec..d21fca280 100644 --- a/Machines/Thomson/MO5/MO5.cpp +++ b/Machines/Thomson/MO5/MO5.cpp @@ -119,9 +119,17 @@ struct ConcreteMachine: > static void access(ComponentT &component, CPU::M6809::data_t value) { if constexpr (CPU::M6809::is_read(read_write)) { - value = component.template read
(); + if constexpr (requires { component.operator->(); }) { + value = component->template read
(); + } else { + value = component.template read
(); + } } else { - component.template write
(value); + if constexpr (requires { component.operator->(); }) { + component->template write
(value); + } else { + component.template write
(value); + } } } @@ -191,15 +199,13 @@ struct ConcreteMachine: case 0xa7e4: if(is_mo6) access<0xa7e4, read_write>(memory_, value); else unmapped(); break; - // TODO: try to apply `access` pattern below. - case 0xa7e5: if constexpr (is_mo6) { if(memory_.access_mode() == AccessMode::System) { access<0xa7e5, read_write>(memory_, value); } else { if constexpr (CPU::M6809::is_read(read_write)) { - value = 0; // TODO: MSB of light-pen counter. + access<0xa7e5, read_write>(video_, value); } else { memory_.template write<0xa7e5>(value); } @@ -238,30 +244,14 @@ struct ConcreteMachine: case 0xa7dd: if(is_mo6) { access<0xa7dd, read_write>(memory_, value); - if constexpr (!CPU::M6809::is_read(read_write)) { - video_->set_border_colour(value); - // TODO: top two bits are "Number of display RAM page". - } + access<0xa7dd, read_write>(video_, value); } else { unmapped(); } break; - case 0xa7da: - if constexpr (CPU::M6809::is_read(read_write)) { - value = video_->palette(); - } else { - video_->set_palette(value); - } - break; - - case 0xa7db: - if constexpr (CPU::M6809::is_read(read_write)) { - value = video_->palette_index(); - } else { - video_->set_palette_index(value); - } - break; + case 0xa7da: if(is_mo6) access<0xa7da, read_write>(video_, value); else unmapped(); break; + case 0xa7db: if(is_mo6) access<0xa7da, read_write>(video_, value); else unmapped(); break; default: unmapped(); diff --git a/Machines/Thomson/MO5/Video.hpp b/Machines/Thomson/MO5/Video.hpp index 04d4343ab..fb73f97fd 100644 --- a/Machines/Thomson/MO5/Video.hpp +++ b/Machines/Thomson/MO5/Video.hpp @@ -36,6 +36,50 @@ public: uint8_t palette_index() const; uint8_t palette(); + // MARK: - Address-based access. + + template + uint8_t read() { + switch(address) { + case 0xa7e4: return 0; // TODO: MSB of lightpen counter. + case 0xa7e5: return 0; // TODO: LSB of lightpen counter. + case 0xa7e6: return horizontal_state(); + case 0xa7e7: return vertical_state(); + + case 0xa7da: return palette(); + case 0xa7db: return palette_index(); + + default: break; + } + return 0xff; + } + + template + void write(const uint8_t value) { + switch(address) { + case 0xa7e5: + // TODO: enable (0) or disable (1) video mode access at 0xa7dc. + break; + case 0xa7e7: + // TODO: b5 = 1 => 525-line output; 0 = 625-line output. + break; + + case 0xa7da: set_palette(value); break; + case 0xa7db: set_palette_index(value); break; + case 0xa7dc: + // TODO: + // + // b6, b5: video data organisation + // b4, b3: data frequency + // b2, b1, b0: display mode + break; + case 0xa7dd: set_border_colour(value); break; + + default: + break; + } + } + // MARK: - Standard boilerplate. void set_scan_target(Outputs::Display::ScanTarget *const target) {