1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Adds Enterprise composite video option.

While enabling more pixels on the left for RGB mode.
This commit is contained in:
Thomas Harte 2021-07-02 21:42:09 -04:00
parent dc0a82cf9a
commit 7826a26c7b
5 changed files with 66 additions and 4 deletions

View File

@ -64,6 +64,7 @@ namespace Enterprise {
template <bool has_disk_controller> class ConcreteMachine:
public Activity::Source,
public Configurable::Device,
public CPU::Z80::BusHandler,
public Machine,
public MachineTypes::AudioProducer,
@ -591,6 +592,14 @@ template <bool has_disk_controller> class ConcreteMachine:
return nick_.last_valid()->get_scaled_scan_status();
}
void set_display_type(Outputs::Display::DisplayType display_type) final {
nick_.last_valid()->set_display_type(display_type);
}
Outputs::Display::DisplayType get_display_type() const final {
return nick_.last_valid()->get_display_type();
}
// MARK: - AudioProducer
Outputs::Speaker::Speaker *get_speaker() final {
@ -692,6 +701,18 @@ template <bool has_disk_controller> class ConcreteMachine:
exdos_.set_activity_observer(observer);
}
}
// MARK: - Configuration options.
std::unique_ptr<Reflection::Struct> get_options() final {
auto options = std::make_unique<Options>(Configurable::OptionsType::UserFriendly);
options->output = get_video_signal_configurable();
return options;
}
void set_options(const std::unique_ptr<Reflection::Struct> &str) final {
const auto options = dynamic_cast<Options *>(str.get());
set_video_signal_configurable(options->output);
}
};
}

View File

@ -10,16 +10,36 @@
#define Enterprise_hpp
#include "../../Analyser/Static/StaticAnalyser.hpp"
#include "../../Configurable/Configurable.hpp"
#include "../../Configurable/StandardOptions.hpp"
#include "../ROMMachine.hpp"
namespace Enterprise {
/*!
@abstract Represents an Elan Enterprise.
@discussion An instance of Enterprise::Machine represents the current state of an
Elan Enterprise.
*/
class Machine {
public:
virtual ~Machine();
static Machine *Enterprise(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
/// Defines the runtime options available for an Enterprise.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
if(needs_declare()) {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
}
}
};
};
};

View File

@ -51,7 +51,7 @@ Nick::Nick(const uint8_t *ram) :
ram_(ram) {
// Just use RGB for now.
crt_.set_display_type(Outputs::Display::DisplayType::RGB);
set_display_type(Outputs::Display::DisplayType::RGB);
// Crop to the centre 90% of the display.
crt_.set_visible_area(Outputs::Display::Rect(0.05f, 0.05f, 0.9f, 0.9f));
@ -287,7 +287,7 @@ void Nick::run_for(Cycles duration) {
// the start of window 6 to the end of window 10.
//
// The first 8 palette entries also need to be fetched here.
while(window < 10 && window < end_window) {
while(window < first_pixel_window_ && window < end_window) {
if(window == 6) {
set_output_type(OutputType::ColourBurst);
}
@ -303,8 +303,8 @@ void Nick::run_for(Cycles duration) {
add_window(1);
}
if(window >= 10) {
if(window == 10) {
if(window >= first_pixel_window_) {
if(window == first_pixel_window_) {
set_output_type(is_sync_or_pixels_ ? OutputType::Pixels : OutputType::Border);
}
@ -484,6 +484,15 @@ Outputs::Display::ScanStatus Nick::get_scaled_scan_status() const {
return crt_.get_scaled_scan_status();
}
void Nick::set_display_type(Outputs::Display::DisplayType display_type) {
first_pixel_window_ = display_type == Outputs::Display::DisplayType::RGB ? 8 : 10;
crt_.set_display_type(display_type);
}
Outputs::Display::DisplayType Nick::get_display_type() const {
return crt_.get_display_type();
}
// MARK: - Specific pixel outputters.
#define output1bpp(x) \

View File

@ -28,6 +28,7 @@ class Nick {
void set_scan_target(Outputs::Display::ScanTarget *scan_target);
Outputs::Display::ScanStatus get_scaled_scan_status() const;
/// @returns The amount of time until the next potential change in interrupt output.
Cycles get_next_sequence_point() const;
/*!
@ -38,6 +39,12 @@ class Nick {
return interrupt_line_;
}
/// Sets the type of output.
void set_display_type(Outputs::Display::DisplayType);
/// Gets the type of output.
Outputs::Display::DisplayType get_display_type() const;
private:
Outputs::CRT::CRT crt_;
const uint8_t *const ram_;
@ -96,6 +103,10 @@ class Nick {
// Current palette.
uint16_t palette_[16]{};
// The first column with pixels on it; will be either 8 or 10 depending
// on whether the colour burst is meaningful to the current display type.
int first_pixel_window_ = 10;
// Specific outputters.
template <int bpp, bool is_lpixel> void output_pixel(uint16_t *target, int columns) const;
template <int bpp, int index_bits> void output_character(uint16_t *target, int columns) const;

View File

@ -316,6 +316,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
case Analyser::Machine::AtariST: return @"CompositeOptions";
case Analyser::Machine::ColecoVision: return @"CompositeOptions";
case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions";
case Analyser::Machine::Enterprise: return @"CompositeOptions";
case Analyser::Machine::Macintosh: return @"MacintoshOptions";
case Analyser::Machine::MasterSystem: return @"CompositeOptions";
case Analyser::Machine::MSX: return @"QuickLoadCompositeOptions";