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:
parent
8c8a71107e
commit
304f0999cd
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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: 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 {
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user