mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-09 05:25:01 +00:00
Made a faulty but hopefully creditable attempt to demarcate an Oric frame.
This commit is contained in:
@@ -45,6 +45,11 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Machine::synchronise()
|
||||||
|
{
|
||||||
|
update_video();
|
||||||
|
}
|
||||||
|
|
||||||
void Machine::update_video()
|
void Machine::update_video()
|
||||||
{
|
{
|
||||||
_videoOutput->run_for_cycles(_cycles_since_video_update);
|
_videoOutput->run_for_cycles(_cycles_since_video_update);
|
||||||
@@ -53,21 +58,10 @@ void Machine::update_video()
|
|||||||
|
|
||||||
void Machine::setup_output(float aspect_ratio)
|
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.reset(new VideoOutput(_ram));
|
||||||
_videoOutput->set_crt(_crt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Machine::close_output()
|
void Machine::close_output()
|
||||||
{
|
{
|
||||||
|
_videoOutput.reset();
|
||||||
}
|
}
|
||||||
|
@@ -38,12 +38,12 @@ class Machine:
|
|||||||
|
|
||||||
// to satisfy CPU6502::Processor
|
// to satisfy CPU6502::Processor
|
||||||
unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value);
|
unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value);
|
||||||
void synchronise() { update_video(); }
|
void synchronise();
|
||||||
|
|
||||||
// to satisfy CRTMachine::Machine
|
// to satisfy CRTMachine::Machine
|
||||||
virtual void setup_output(float aspect_ratio);
|
virtual void setup_output(float aspect_ratio);
|
||||||
virtual void close_output();
|
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 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); }
|
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();
|
inline void update_video();
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
std::shared_ptr<Outputs::CRT::CRT> _crt;
|
|
||||||
std::unique_ptr<VideoOutput> _videoOutput;
|
std::unique_ptr<VideoOutput> _videoOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -10,14 +10,61 @@
|
|||||||
|
|
||||||
using namespace Oric;
|
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)
|
void VideoOutput::run_for_cycles(int number_of_cycles)
|
||||||
{
|
{
|
||||||
|
// Vertical: 0–39: pixels; otherwise blank; 48–53 sync
|
||||||
|
// Horizontal: 0–223: pixels; otherwise blank; 256–259 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,11 +16,25 @@ namespace Oric {
|
|||||||
class VideoOutput {
|
class VideoOutput {
|
||||||
public:
|
public:
|
||||||
VideoOutput(uint8_t *memory);
|
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);
|
void run_for_cycles(int number_of_cycles);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t *_ram;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user