1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Made a faulty but hopefully creditable attempt to demarcate an Oric frame.

This commit is contained in:
Thomas Harte 2016-10-12 21:29:21 -04:00
parent 8c8a71107e
commit 304f0999cd
4 changed files with 72 additions and 18 deletions

View File

@ -45,6 +45,11 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
return 1;
}
void Machine::synchronise()
{
update_video();
}
void Machine::update_video()
{
_videoOutput->run_for_cycles(_cycles_since_video_update);
@ -53,21 +58,10 @@ void Machine::update_video()
void Machine::setup_output(float aspect_ratio)
{
// TODO: this is a copy and paste from the Electron; correct.
_crt.reset(new Outputs::CRT::CRT(256, 8, Outputs::CRT::DisplayType::PAL50, 1));
_crt->set_rgb_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)"
"{"
"uint texValue = texture(sampler, coordinate).r;"
"texValue >>= 4 - (int(icoordinate.x * 8) & 4);"
"return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));"
"}");
_videoOutput.reset(new VideoOutput(_ram));
_videoOutput->set_crt(_crt);
}
void Machine::close_output()
{
_videoOutput.reset();
}

View File

@ -38,12 +38,12 @@ class Machine:
// to satisfy CPU6502::Processor
unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value);
void synchronise() { update_video(); }
void synchronise();
// to satisfy CRTMachine::Machine
virtual void setup_output(float aspect_ratio);
virtual void close_output();
virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; }
virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _videoOutput->get_crt(); }
virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return nullptr; }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
@ -54,7 +54,6 @@ class Machine:
inline void update_video();
// Outputs
std::shared_ptr<Outputs::CRT::CRT> _crt;
std::unique_ptr<VideoOutput> _videoOutput;
};

View File

@ -10,14 +10,61 @@
using namespace Oric;
VideoOutput::VideoOutput(uint8_t *memory) : _ram(memory)
VideoOutput::VideoOutput(uint8_t *memory) :
_ram(memory),
_frame_counter(0), _counter(0),
_state(Sync), _cycles_in_state(0)
{
_crt.reset(new Outputs::CRT::CRT(384, 6, Outputs::CRT::DisplayType::PAL50, 1));
// TODO: this is a copy and paste from the Electron; factor out.
_crt->set_rgb_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)"
"{"
"uint texValue = texture(sampler, coordinate).r;"
"texValue >>= 4 - (int(icoordinate.x * 8) & 4);"
"return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));"
"}");
}
void VideoOutput::set_crt(std::shared_ptr<Outputs::CRT::CRT> crt)
std::shared_ptr<Outputs::CRT::CRT> VideoOutput::get_crt()
{
return _crt;
}
void VideoOutput::run_for_cycles(int number_of_cycles)
{
// Vertical: 039: pixels; otherwise blank; 4853 sync
// Horizontal: 0223: pixels; otherwise blank; 256259 sync
while(number_of_cycles--)
{
_counter = (_counter + 1)%(312 * 64); // TODO: NTSC
State new_state = Blank;
if((_counter & 63) >= 48 && (_counter & 63) <= 53) new_state = Sync;
else if(_counter >= 256*312 && _counter <= 259*312) new_state = Sync;
else if(_counter < 224 && ((_counter&63) < 40)) new_state = Pixels;
if(_state != new_state)
{
switch(_state)
{
case Sync: _crt->output_sync(_cycles_in_state * 6); break;
case Blank: _crt->output_blank(_cycles_in_state * 6); break;
case Pixels: _crt->output_data(_cycles_in_state * 6, 2); break;
}
_state = new_state;
_cycles_in_state = 0;
if(_state == Pixels) _pixel_target = _crt->allocate_write_area(120);
}
else _cycles_in_state++;
if(new_state == Pixels) {
_pixel_target[0] = 0x70;
_pixel_target[1] = 0x14;
_pixel_target[2] = 0x23;
_pixel_target += 3;
}
}
}

View File

@ -16,11 +16,25 @@ namespace Oric {
class VideoOutput {
public:
VideoOutput(uint8_t *memory);
void set_crt(std::shared_ptr<Outputs::CRT::CRT> crt);
std::shared_ptr<Outputs::CRT::CRT> get_crt();
void run_for_cycles(int number_of_cycles);
private:
uint8_t *_ram;
std::shared_ptr<Outputs::CRT::CRT> _crt;
// Counters
int _counter, _frame_counter;
// Output state
enum State {
Blank, Sync, Pixels
} _state;
unsigned int _cycles_in_state;
uint8_t *_pixel_target;
// Registers
uint8_t _ink, _style, _paper;
};
}