mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-06 10:38:16 +00:00
Adds capture and forwarding of border colour.
This commit is contained in:
parent
2bbf8bc9fa
commit
fd271d920b
@ -11,6 +11,7 @@
|
||||
|
||||
#include "../../../Reflection/Struct.hpp"
|
||||
#include "../../../Processors/Z80/State/State.hpp"
|
||||
#include "Video.hpp"
|
||||
|
||||
namespace Sinclair {
|
||||
namespace ZXSpectrum {
|
||||
@ -18,11 +19,13 @@ namespace ZXSpectrum {
|
||||
|
||||
struct State: public Reflection::StructImpl<State> {
|
||||
CPU::Z80::State z80;
|
||||
Video::State video;
|
||||
std::vector<uint8_t> ram;
|
||||
|
||||
State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(z80);
|
||||
DeclareField(video);
|
||||
DeclareField(ram);
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,15 @@
|
||||
#include "../../../Outputs/CRT/CRT.hpp"
|
||||
#include "../../../ClockReceiver/ClockReceiver.hpp"
|
||||
|
||||
#include "../../../Reflection/Struct.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Sinclair {
|
||||
namespace ZXSpectrum {
|
||||
namespace Video {
|
||||
|
||||
enum class VideoTiming {
|
||||
enum class Timing {
|
||||
FortyEightK,
|
||||
OneTwoEightK,
|
||||
Plus3,
|
||||
@ -47,7 +50,7 @@ enum class VideoTiming {
|
||||
|
||||
*/
|
||||
|
||||
template <VideoTiming timing> class Video {
|
||||
template <Timing timing> class Video {
|
||||
private:
|
||||
struct Timings {
|
||||
// Number of cycles per line. Will be 224 or 228.
|
||||
@ -78,17 +81,17 @@ template <VideoTiming timing> class Video {
|
||||
};
|
||||
|
||||
static constexpr Timings get_timings() {
|
||||
if constexpr (timing == VideoTiming::Plus3) {
|
||||
if constexpr (timing == Timing::Plus3) {
|
||||
constexpr int delays[] = {1, 0, 7, 6, 5, 4, 3, 2};
|
||||
return Timings(228, 311, 6, 129, 14361, delays);
|
||||
}
|
||||
|
||||
if constexpr (timing == VideoTiming::OneTwoEightK) {
|
||||
if constexpr (timing == Timing::OneTwoEightK) {
|
||||
constexpr int delays[] = {6, 5, 4, 3, 2, 1, 0, 0};
|
||||
return Timings(228, 311, 4, 128, 14361, delays);
|
||||
}
|
||||
|
||||
if constexpr (timing == VideoTiming::FortyEightK) {
|
||||
if constexpr (timing == Timing::FortyEightK) {
|
||||
constexpr int delays[] = {6, 5, 4, 3, 2, 1, 0, 0};
|
||||
return Timings(224, 312, 4, 128, 14335, delays);
|
||||
}
|
||||
@ -103,7 +106,7 @@ template <VideoTiming timing> class Video {
|
||||
|
||||
constexpr int sync_line = (timings.interrupt_time / timings.cycles_per_line) + 1;
|
||||
|
||||
constexpr int sync_position = (timing == VideoTiming::FortyEightK) ? 164 * 2 : 166 * 2;
|
||||
constexpr int sync_position = (timing == Timing::FortyEightK) ? 164 * 2 : 166 * 2;
|
||||
constexpr int sync_length = 17 * 2;
|
||||
constexpr int burst_position = sync_position + 40;
|
||||
constexpr int burst_length = 17;
|
||||
@ -220,7 +223,7 @@ template <VideoTiming timing> class Video {
|
||||
if(offset >= burst_position && offset < burst_position+burst_length && end_offset > offset) {
|
||||
const int burst_duration = std::min(burst_position + burst_length, end_offset) - offset;
|
||||
|
||||
if constexpr (timing >= VideoTiming::OneTwoEightK) {
|
||||
if constexpr (timing >= Timing::OneTwoEightK) {
|
||||
crt_.output_colour_burst(burst_duration, 116, is_alternate_line_);
|
||||
// The colour burst phase above is an empirical guess. I need to research further.
|
||||
} else {
|
||||
@ -248,7 +251,7 @@ template <VideoTiming timing> class Video {
|
||||
}
|
||||
|
||||
static constexpr int half_cycles_per_line() {
|
||||
if constexpr (timing == VideoTiming::FortyEightK) {
|
||||
if constexpr (timing == Timing::FortyEightK) {
|
||||
// TODO: determine real figure here, if one exists.
|
||||
// The source I'm looking at now suggests that the theoretical
|
||||
// ideal of 224*2 ignores the real-life effects of separate
|
||||
@ -328,7 +331,7 @@ template <VideoTiming timing> class Video {
|
||||
*/
|
||||
uint8_t get_floating_value() const {
|
||||
constexpr auto timings = get_timings();
|
||||
const uint8_t out_of_bounds = (timing == VideoTiming::Plus3) ? last_contended_access_ : 0xff;
|
||||
const uint8_t out_of_bounds = (timing == Timing::Plus3) ? last_contended_access_ : 0xff;
|
||||
|
||||
const int line = time_into_frame_ / timings.cycles_per_line;
|
||||
if(line >= 192) {
|
||||
@ -342,7 +345,7 @@ template <VideoTiming timing> class Video {
|
||||
|
||||
// The +2a and +3 always return the low bit as set.
|
||||
const uint8_t value = last_fetches_[(time_into_line >> 1) & 3];
|
||||
if constexpr (timing == VideoTiming::Plus3) {
|
||||
if constexpr (timing == Timing::Plus3) {
|
||||
return value | 1;
|
||||
}
|
||||
return value;
|
||||
@ -354,7 +357,7 @@ template <VideoTiming timing> class Video {
|
||||
bus is accessed when the gate array isn't currently reading.
|
||||
*/
|
||||
void set_last_contended_area_access([[maybe_unused]] uint8_t value) {
|
||||
if constexpr (timing == VideoTiming::Plus3) {
|
||||
if constexpr (timing == Timing::Plus3) {
|
||||
last_contended_access_ = value | 1;
|
||||
}
|
||||
}
|
||||
@ -408,6 +411,17 @@ template <VideoTiming timing> class Video {
|
||||
#undef RGB
|
||||
};
|
||||
|
||||
struct State: public Reflection::StructImpl<State> {
|
||||
uint8_t border_colour;
|
||||
|
||||
State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(border_colour);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,10 +775,10 @@ template<Model model> class ConcreteMachine:
|
||||
// MARK: - Video.
|
||||
using VideoType =
|
||||
std::conditional_t<
|
||||
model <= Model::FortyEightK, Video<VideoTiming::FortyEightK>,
|
||||
model <= Model::FortyEightK, Video::Video<Video::Timing::FortyEightK>,
|
||||
std::conditional_t<
|
||||
model <= Model::Plus2, Video<VideoTiming::OneTwoEightK>,
|
||||
Video<VideoTiming::Plus3>
|
||||
model <= Model::Plus2, Video::Video<Video::Timing::OneTwoEightK>,
|
||||
Video::Video<Video::Timing::Plus3>
|
||||
>
|
||||
>;
|
||||
JustInTimeActor<VideoType> video_;
|
||||
|
@ -64,8 +64,7 @@ std::unique_ptr<Analyser::Static::Target> SNA::load(const std::string &file_name
|
||||
state->z80.registers.interrupt_mode = file.get8();
|
||||
|
||||
// 1A border colour
|
||||
const uint8_t border_colour = file.get8();
|
||||
(void)border_colour; // TODO.
|
||||
state->video.border_colour = file.get8();
|
||||
|
||||
// 1B– 48kb RAM contents
|
||||
state->ram = file.read(48*1024);
|
||||
|
Loading…
x
Reference in New Issue
Block a user