1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-22 14:30:29 +00:00

With debugging hooks still on display, makes first attempt at dynamic analysis.

This commit is contained in:
Thomas Harte 2018-02-01 07:53:52 -05:00
parent c12aaea747
commit 4e720d57b2
16 changed files with 108 additions and 19 deletions

View File

@ -14,6 +14,12 @@ MultiCRTMachine::MultiCRTMachine(const std::vector<std::unique_ptr<::Machine::Dy
machines_(machines) {}
void MultiCRTMachine::setup_output(float aspect_ratio) {
// auto reverse_iterator = machines_.rbegin();
// while(reverse_iterator != machines_.rend()) {
// CRTMachine::Machine *crt_machine = (*reverse_iterator)->crt_machine();
// if(crt_machine) crt_machine->setup_output(aspect_ratio);
// reverse_iterator++;
// }
for(const auto &machine: machines_) {
CRTMachine::Machine *crt_machine = machine->crt_machine();
if(crt_machine) crt_machine->setup_output(aspect_ratio);
@ -43,7 +49,7 @@ void MultiCRTMachine::run_for(const Cycles cycles) {
if(crt_machine) crt_machine->run_for(cycles);
}
// TODO: announce an opportunity potentially to reorder the list of machines.
if(delegate_) delegate_->multi_crt_did_run_machines();
}
double MultiCRTMachine::get_clock_rate() {
@ -57,6 +63,10 @@ bool MultiCRTMachine::get_clock_is_unlimited() {
return crt_machine ? crt_machine->get_clock_is_unlimited() : false;
}
void MultiCRTMachine::did_change_machine_order() {
// TODO
}
void MultiCRTMachine::set_delegate(::CRTMachine::Machine::Delegate *delegate) {
// TODO
}

View File

@ -34,8 +34,18 @@ struct MultiCRTMachine: public ::CRTMachine::Machine, public ::CRTMachine::Machi
void machine_did_change_clock_rate(Machine *machine) override;
void machine_did_change_clock_is_unlimited(Machine *machine) override;
void did_change_machine_order();
struct Delegate {
virtual void multi_crt_did_run_machines() = 0;
};
void set_delegate(Delegate *delegate) {
delegate_ = delegate;
}
private:
const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines_;
Delegate *delegate_ = nullptr;
};
}

View File

@ -13,7 +13,9 @@ using namespace Analyser::Dynamic;
MultiMachine::MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines) :
machines_(std::move(machines)),
configuration_target_(machines_),
crt_machine_(machines_) {}
crt_machine_(machines_) {
crt_machine_.set_delegate(this);
}
ConfigurationTarget::Machine *MultiMachine::configuration_target() {
return &configuration_target_;
@ -38,3 +40,23 @@ Configurable::Device *MultiMachine::configurable_device() {
Utility::TypeRecipient *MultiMachine::type_recipient() {
return nullptr;
}
void MultiMachine::multi_crt_did_run_machines() {
DynamicMachine *front = machines_.front().get();
// for(const auto &machine: machines_) {
// CRTMachine::Machine *crt = machine->crt_machine();
// printf("%0.2f ", crt->get_confidence());
// crt->print_type();
// printf("; ");
// }
// printf("\n");
std::stable_sort(machines_.begin(), machines_.end(), [] (const auto &lhs, const auto &rhs){
CRTMachine::Machine *lhs_crt = lhs->crt_machine();
CRTMachine::Machine *rhs_crt = rhs->crt_machine();
return lhs_crt->get_confidence() > rhs_crt->get_confidence();
});
if(machines_.front().get() != front) {
crt_machine_.did_change_machine_order();
}
}

View File

@ -32,7 +32,7 @@ namespace Dynamic {
If confidence for any machine becomes disproportionately low compared to
the others in the set, that machine is removed from the array.
*/
class MultiMachine: public ::Machine::DynamicMachine {
class MultiMachine: public ::Machine::DynamicMachine, public MultiCRTMachine::Delegate {
public:
MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines);
@ -43,6 +43,8 @@ class MultiMachine: public ::Machine::DynamicMachine {
Configurable::Device *configurable_device() override;
Utility::TypeRecipient *type_recipient() override;
void multi_crt_did_run_machines() override;
private:
std::vector<std::unique_ptr<DynamicMachine>> machines_;

View File

@ -44,6 +44,10 @@ class Machine: public ROMMachine::Machine {
/// Runs the machine for @c cycles.
virtual void run_for(const Cycles cycles) = 0;
/// @returns The confidence that this machine is running content it understands.
virtual float get_confidence() { return 0.5f; }
virtual void print_type() {}
// TODO: sever the clock-rate stuff.
virtual double get_clock_rate() {
return clock_rate_;

View File

@ -19,7 +19,7 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler {
ASCII16kbROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(slot) {}
void write(uint16_t address, uint8_t value) {
void write(uint16_t address, uint8_t value) override {
switch(address >> 11) {
default:
confidence_counter_.add_miss();
@ -35,6 +35,10 @@ class ASCII16kbROMSlotHandler: public ROMSlotHandler {
}
}
virtual void print_type() override {
printf("A16");
}
private:
MSX::MemoryMap &map_;
int slot_;

View File

@ -19,7 +19,7 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler {
ASCII8kbROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(slot) {}
void write(uint16_t address, uint8_t value) {
void write(uint16_t address, uint8_t value) override {
switch(address >> 11) {
default:
confidence_counter_.add_miss();
@ -43,6 +43,10 @@ class ASCII8kbROMSlotHandler: public ROMSlotHandler {
}
}
virtual void print_type() override {
printf("A8");
}
private:
MSX::MemoryMap &map_;
int slot_;

View File

@ -19,7 +19,7 @@ class KonamiROMSlotHandler: public ROMSlotHandler {
KonamiROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(slot) {}
void write(uint16_t address, uint8_t value) {
void write(uint16_t address, uint8_t value) override {
switch(address >> 13) {
default:
confidence_counter_.add_miss();
@ -39,6 +39,9 @@ class KonamiROMSlotHandler: public ROMSlotHandler {
}
}
virtual void print_type() override {
printf("K");
}
private:
MSX::MemoryMap &map_;
int slot_;

View File

@ -67,6 +67,10 @@ class KonamiWithSCCROMSlotHandler: public ROMSlotHandler {
return 0xff;
}
virtual void print_type() override {
printf("KSCC");
}
private:
MSX::MemoryMap &map_;
int slot_;

View File

@ -155,9 +155,18 @@ class ConcreteMachine:
void run_for(const Cycles cycles) override {
z80_.run_for(cycles);
}
float get_confidence() override {
if(memory_slots_[1].handler) {
printf("%0.2f\n", memory_slots_[1].handler->get_confidence());
return memory_slots_[1].handler->get_confidence();
}
return 0.5f;
}
void print_type() override {
if(memory_slots_[1].handler) {
memory_slots_[1].handler->print_type();
}
}

View File

@ -69,6 +69,9 @@ class ROMSlotHandler {
return confidence_counter_.get_confidence();
}
virtual void print_type() {
}
protected:
Analyser::Dynamic::ConfidenceCounter confidence_counter_;
};

View File

@ -232,8 +232,7 @@ class CRT {
inline void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty) {
{
std::lock_guard<std::mutex> function_guard(function_mutex_);
for(std::function<void(void)> function : enqueued_openGL_functions_)
{
for(std::function<void(void)> function : enqueued_openGL_functions_) {
function();
}
enqueued_openGL_functions_.clear();

View File

@ -107,6 +107,12 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
glDeleteSync(fence_);
}
// make sure everything is bound
composite_texture_->bind_texture();
separated_texture_->bind_texture();
filtered_texture_->bind_texture();
if(work_texture_) work_texture_->bind_texture();
// make sure there's a target to draw to
if(!framebuffer_ || static_cast<unsigned int>(framebuffer_->get_height()) != output_height || static_cast<unsigned int>(framebuffer_->get_width()) != output_width) {
std::unique_ptr<OpenGL::TextureTarget> new_framebuffer(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit, GL_LINEAR));
@ -131,6 +137,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
// upload new source pixels, if any
glActiveTexture(source_data_texture_unit);
texture_builder.bind();
texture_builder.submit();
// buffer usage restart from 0 for the next time around

View File

@ -52,16 +52,11 @@ struct DefaultBookender: public TextureBuilder::Bookender {
}
TextureBuilder::TextureBuilder(std::size_t bytes_per_pixel, GLenum texture_unit) :
bytes_per_pixel_(bytes_per_pixel) {
bytes_per_pixel_(bytes_per_pixel), texture_unit_(texture_unit) {
image_.resize(bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight);
glGenTextures(1, &texture_name_);
glActiveTexture(texture_unit);
glBindTexture(GL_TEXTURE_2D, texture_name_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
bind();
glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr);
set_bookender(nullptr);
@ -71,6 +66,15 @@ TextureBuilder::~TextureBuilder() {
glDeleteTextures(1, &texture_name_);
}
void TextureBuilder::bind() {
glActiveTexture(texture_unit_);
glBindTexture(GL_TEXTURE_2D, texture_name_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
inline uint8_t *TextureBuilder::pointer_to_location(uint16_t x, uint16_t y) {
return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_];
}

View File

@ -114,9 +114,13 @@ class TextureBuilder {
/// Supply nullptr to engage the default bookender.
void set_bookender(std::unique_ptr<Bookender> bookender);
/// Binds this texture to the unit supplied at instantiation.
void bind();
private:
// the buffer size
// the buffer size and target unit
std::size_t bytes_per_pixel_;
GLenum texture_unit_;
// the buffer
std::vector<uint8_t> image_;

View File

@ -26,8 +26,7 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit,
while(expanded_height_ < height) expanded_height_ <<= 1;
glGenTextures(1, &texture_);
glActiveTexture(texture_unit);
glBindTexture(GL_TEXTURE_2D, texture_);
bind_texture();
std::vector<uint8_t> blank_buffer(static_cast<size_t>(expanded_width_ * expanded_height_ * 4), 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(expanded_width_), static_cast<GLsizei>(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, blank_buffer.data());
@ -53,6 +52,7 @@ void TextureTarget::bind_framebuffer() {
}
void TextureTarget::bind_texture() {
glActiveTexture(texture_unit_);
glBindTexture(GL_TEXTURE_2D, texture_);
}