1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-07 08:28:57 +00:00
CLK/Machines/Enterprise/Nick.hpp

106 lines
2.5 KiB
C++
Raw Normal View History

2021-06-15 02:19:25 +00:00
//
// Nick.hpp
// Clock Signal
//
// Created by Thomas Harte on 14/06/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Nick_hpp
#define Nick_hpp
#include <cstdint>
#include "../../ClockReceiver/ClockReceiver.hpp"
2021-06-15 03:11:48 +00:00
#include "../../Outputs/CRT/CRT.hpp"
2021-06-15 02:19:25 +00:00
namespace Enterprise {
class Nick {
public:
Nick(const uint8_t *ram);
2021-06-15 03:11:48 +00:00
2021-06-15 02:19:25 +00:00
void write(uint16_t address, uint8_t value);
uint8_t read(uint16_t address);
void run_for(Cycles);
2021-06-15 03:11:48 +00:00
void set_scan_target(Outputs::Display::ScanTarget *scan_target);
Outputs::Display::ScanStatus get_scaled_scan_status() const;
Cycles get_next_sequence_point();
/*!
@returns The current state of the interrupt line @c true for active;
@c false for inactive.
*/
inline bool get_interrupt_line() {
return interrupt_line_;
}
2021-06-15 03:11:48 +00:00
private:
Outputs::CRT::CRT crt_;
const uint8_t *const ram_;
// CPU-provided state.
uint8_t line_parameter_control_ = 0xc0;
uint16_t line_parameter_base_ = 0x0000;
uint16_t border_colour_ = 0;
// Ephemerals, related to current video position.
int horizontal_counter_ = 0;
uint16_t line_parameter_pointer_ = 0x0000;
uint8_t line_parameters_[16];
bool should_reload_line_parameters_ = true;
uint16_t line_data_pointer_[2];
// Current mode line parameters.
uint8_t lines_remaining_ = 0x00;
uint8_t two_colour_mask_ = 0xff;
int left_margin_ = 0, right_margin_ = 0;
const uint16_t *alt_ind_palettes[4];
enum class Mode {
Vsync,
Pixel,
Attr,
CH256,
CH128,
CH64,
Unused,
LPixel,
} mode_ = Mode::Vsync;
enum class State {
Sync,
Border,
Pixels,
Blank,
} state_ = State::Sync;
2021-06-17 00:43:22 +00:00
int bpp_ = 0;
int column_size_ = 0;
bool interrupt_line_ = true;
int line_data_per_column_increments_[2] = {0, 0};
// An accumulator for border output regions.
int border_duration_ = 0;
void flush_border();
2021-06-16 02:03:41 +00:00
// The destination for new pixels.
2021-06-17 00:43:22 +00:00
static constexpr int allocation_size = 80;
static_assert((allocation_size % 16) == 0, "Allocation size must be a multiple of 16");
2021-06-16 02:03:41 +00:00
uint16_t *pixel_pointer_ = nullptr, *allocated_pointer_ = nullptr;
int pixel_duration_ = 0;
void flush_pixels();
2021-06-17 00:43:22 +00:00
// Current palette.
uint16_t palette_[16]{};
// Specific outputters.
2021-06-17 01:16:26 +00:00
template <int bpp, bool is_lpixel> void output_pixel(uint16_t *target, int columns);
template <int bpp, int index_bits> void output_character(uint16_t *target, int columns);
template <int bpp> void output_attributed(uint16_t *target, int columns);
2021-06-15 02:19:25 +00:00
};
}
#endif /* Nick_hpp */