2015-07-19 17:36:27 +00:00
|
|
|
//
|
|
|
|
// CRT.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 19/07/2015.
|
|
|
|
// Copyright © 2015 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef CRT_cpp
|
|
|
|
#define CRT_cpp
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string>
|
2015-07-21 03:18:56 +00:00
|
|
|
#include <vector>
|
2015-07-19 17:36:27 +00:00
|
|
|
|
|
|
|
namespace Outputs {
|
|
|
|
|
|
|
|
class CRT {
|
|
|
|
public:
|
2015-07-21 03:18:56 +00:00
|
|
|
CRT(int cycles_per_line, int height_of_display, int number_of_buffers, ...);
|
2015-07-20 01:21:34 +00:00
|
|
|
~CRT();
|
|
|
|
|
2015-07-19 17:36:27 +00:00
|
|
|
void output_sync(int number_of_cycles);
|
2015-07-21 03:18:56 +00:00
|
|
|
void output_blank(int number_of_cycles);
|
|
|
|
void output_level(int number_of_cycles, const char *type);
|
|
|
|
void output_data(int number_of_cycles, const char *type);
|
2015-07-19 22:32:42 +00:00
|
|
|
|
|
|
|
struct CRTRun {
|
|
|
|
struct Point {
|
2015-07-21 03:18:56 +00:00
|
|
|
float dst_x, dst_y;
|
|
|
|
int src_x, src_y;
|
2015-07-19 22:32:42 +00:00
|
|
|
} start_point, end_point;
|
|
|
|
|
|
|
|
enum Type {
|
2015-07-21 01:43:00 +00:00
|
|
|
Sync, Level, Data, Blank
|
2015-07-19 22:32:42 +00:00
|
|
|
} type;
|
|
|
|
|
2015-07-21 03:18:56 +00:00
|
|
|
const char *data_type;
|
2015-07-19 22:32:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class CRTDelegate {
|
|
|
|
public:
|
2015-07-21 03:18:56 +00:00
|
|
|
virtual void crt_did_start_vertical_retrace_with_runs(CRTRun *runs, int runs_to_draw) = 0;
|
2015-07-19 22:32:42 +00:00
|
|
|
};
|
2015-07-21 03:18:56 +00:00
|
|
|
void set_crt_delegate(CRTDelegate *delegate);
|
2015-07-19 22:32:42 +00:00
|
|
|
|
2015-07-20 01:21:34 +00:00
|
|
|
void allocate_write_area(int required_length);
|
|
|
|
uint8_t *get_write_target_for_buffer(int buffer);
|
|
|
|
|
2015-07-19 22:32:42 +00:00
|
|
|
private:
|
|
|
|
CRTDelegate *_delegate;
|
2015-07-21 03:18:56 +00:00
|
|
|
std::vector<CRTRun> _all_runs;
|
|
|
|
int _run_pointer;
|
2015-07-19 22:32:42 +00:00
|
|
|
|
|
|
|
float _horizontalOffset, _verticalOffset;
|
2015-07-20 01:21:34 +00:00
|
|
|
|
|
|
|
uint8_t **_buffers;
|
|
|
|
int *_bufferSizes;
|
|
|
|
int _numberOfBuffers;
|
|
|
|
|
|
|
|
int _write_allocation_pointer, _write_target_pointer;
|
2015-07-20 03:43:22 +00:00
|
|
|
|
|
|
|
void propose_hsync();
|
|
|
|
void charge_vsync(int number_of_cycles);
|
|
|
|
void drain_vsync(int number_of_cycles);
|
|
|
|
void run_line_for_cycles(int number_of_cycles);
|
|
|
|
void run_hline_for_cycles(int number_of_cycles);
|
|
|
|
void do_hsync();
|
|
|
|
void do_vsync();
|
|
|
|
|
|
|
|
int _cycles_per_line;
|
2015-07-21 03:18:56 +00:00
|
|
|
int _height_of_display;
|
|
|
|
|
|
|
|
int _hsync_counter;
|
2015-07-21 01:43:00 +00:00
|
|
|
|
|
|
|
enum SyncEvent {
|
|
|
|
None,
|
|
|
|
StartHSync, EndHSync,
|
|
|
|
StartVSync, EndVSync
|
|
|
|
};
|
|
|
|
SyncEvent advance_to_next_sync_event(bool hsync_is_requested, bool vsync_is_charging, int cycles_to_run_for, int *cycles_advanced);
|
2015-07-21 03:18:56 +00:00
|
|
|
bool _is_receiving_sync, _did_detect_hsync;
|
2015-07-21 01:43:00 +00:00
|
|
|
int _sync_capacitor_charge_level, _vretrace_counter;
|
|
|
|
int _horizontal_counter, _expected_next_hsync, _hsync_error_window;
|
2015-07-21 03:18:56 +00:00
|
|
|
bool _is_in_hsync;
|
2015-07-21 01:43:00 +00:00
|
|
|
|
2015-07-21 03:18:56 +00:00
|
|
|
void advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_charging, CRTRun::Type type, const char *data_type);
|
2015-07-19 17:36:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* CRT_cpp */
|