mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Returns the Apple II to submitting video.
This commit is contained in:
parent
8a699b6072
commit
a47de9a884
@ -63,12 +63,12 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
|
||||
CPU::MOS6502::Processor<(model == Analyser::Static::AppleII::Target::Model::EnhancedIIe) ? CPU::MOS6502::Personality::PSynertek65C02 : CPU::MOS6502::Personality::P6502, ConcreteMachine, false> m6502_;
|
||||
VideoBusHandler video_bus_handler_;
|
||||
std::unique_ptr<AppleII::Video::Video<VideoBusHandler, is_iie()>> video_;
|
||||
AppleII::Video::Video<VideoBusHandler, is_iie()> video_;
|
||||
int cycles_into_current_line_ = 0;
|
||||
Cycles cycles_since_video_update_;
|
||||
|
||||
void update_video() {
|
||||
video_->run_for(cycles_since_video_update_.flush());
|
||||
video_.run_for(cycles_since_video_update_.flush());
|
||||
}
|
||||
static const int audio_divider = 8;
|
||||
void update_audio() {
|
||||
@ -84,7 +84,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
|
||||
uint8_t ram_[65536], aux_ram_[65536];
|
||||
std::vector<uint8_t> rom_;
|
||||
std::vector<uint8_t> character_rom_;
|
||||
// std::vector<uint8_t> character_rom_;
|
||||
uint8_t keyboard_input_ = 0x00;
|
||||
bool key_is_down_ = false;
|
||||
|
||||
@ -234,13 +234,13 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
read_auxiliary_memory_ ? &aux_ram_[0x0200] : &ram_[0x0200],
|
||||
write_auxiliary_memory_ ? &aux_ram_[0x0200] : &ram_[0x0200]);
|
||||
|
||||
if(video_ && video_->get_80_store()) {
|
||||
bool use_aux_ram = video_->get_page2();
|
||||
if(video_.get_80_store()) {
|
||||
bool use_aux_ram = video_.get_page2();
|
||||
page(0x04, 0x08,
|
||||
use_aux_ram ? &aux_ram_[0x0400] : &ram_[0x0400],
|
||||
use_aux_ram ? &aux_ram_[0x0400] : &ram_[0x0400]);
|
||||
|
||||
if(video_->get_high_resolution()) {
|
||||
if(video_.get_high_resolution()) {
|
||||
page(0x20, 0x40,
|
||||
use_aux_ram ? &aux_ram_[0x2000] : &ram_[0x2000],
|
||||
use_aux_ram ? &aux_ram_[0x2000] : &ram_[0x2000]);
|
||||
@ -309,6 +309,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
ConcreteMachine(const Analyser::Static::AppleII::Target &target, const ROMMachine::ROMFetcher &rom_fetcher):
|
||||
m6502_(*this),
|
||||
video_bus_handler_(ram_, aux_ram_),
|
||||
video_(video_bus_handler_),
|
||||
audio_toggle_(audio_queue_),
|
||||
speaker_(audio_toggle_) {
|
||||
// The system's master clock rate.
|
||||
@ -371,7 +372,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
rom_.erase(rom_.begin(), rom_.end() - static_cast<off_t>(rom_size));
|
||||
}
|
||||
|
||||
character_rom_ = std::move(*roms[0]);
|
||||
video_.set_character_rom(*roms[0]);
|
||||
|
||||
if(target.disk_controller != Target::DiskController::None) {
|
||||
// Apple recommended slot 6 for the (first) Disk II.
|
||||
@ -397,18 +398,9 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
}
|
||||
|
||||
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
|
||||
video_.reset(new AppleII::Video::Video<VideoBusHandler, is_iie()>(video_bus_handler_));
|
||||
video_->set_character_rom(character_rom_);
|
||||
video_.set_scan_target(scan_target);
|
||||
}
|
||||
|
||||
// void close_output() override {
|
||||
// video_.reset();
|
||||
// }
|
||||
//
|
||||
// Outputs::CRT::CRT *get_crt() override {
|
||||
// return video_->get_crt();
|
||||
// }
|
||||
|
||||
Outputs::Speaker::Speaker *get_speaker() override {
|
||||
return &speaker_;
|
||||
}
|
||||
@ -463,7 +455,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
// actor, but this will actually be the result most of the time so it's not
|
||||
// too terrible.
|
||||
if(isReadOperation(operation) && address != 0xc000) {
|
||||
*value = video_->get_last_read_value(cycles_since_video_update_);
|
||||
*value = video_.get_last_read_value(cycles_since_video_update_);
|
||||
}
|
||||
|
||||
switch(address) {
|
||||
@ -523,18 +515,18 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
case 0xc015: IIeSwitchRead(internal_CX_rom_); break;
|
||||
case 0xc016: IIeSwitchRead(alternative_zero_page_); break;
|
||||
case 0xc017: IIeSwitchRead(slot_C3_rom_); break;
|
||||
case 0xc018: IIeSwitchRead(video_->get_80_store()); break;
|
||||
case 0xc019: IIeSwitchRead(video_->get_is_vertical_blank(cycles_since_video_update_)); break;
|
||||
case 0xc01a: IIeSwitchRead(video_->get_text()); break;
|
||||
case 0xc01b: IIeSwitchRead(video_->get_mixed()); break;
|
||||
case 0xc01c: IIeSwitchRead(video_->get_page2()); break;
|
||||
case 0xc01d: IIeSwitchRead(video_->get_high_resolution()); break;
|
||||
case 0xc01e: IIeSwitchRead(video_->get_alternative_character_set()); break;
|
||||
case 0xc01f: IIeSwitchRead(video_->get_80_columns()); break;
|
||||
case 0xc018: IIeSwitchRead(video_.get_80_store()); break;
|
||||
case 0xc019: IIeSwitchRead(video_.get_is_vertical_blank(cycles_since_video_update_)); break;
|
||||
case 0xc01a: IIeSwitchRead(video_.get_text()); break;
|
||||
case 0xc01b: IIeSwitchRead(video_.get_mixed()); break;
|
||||
case 0xc01c: IIeSwitchRead(video_.get_page2()); break;
|
||||
case 0xc01d: IIeSwitchRead(video_.get_high_resolution()); break;
|
||||
case 0xc01e: IIeSwitchRead(video_.get_alternative_character_set()); break;
|
||||
case 0xc01f: IIeSwitchRead(video_.get_80_columns()); break;
|
||||
#undef IIeSwitchRead
|
||||
|
||||
case 0xc07f:
|
||||
if(is_iie()) *value = (*value & 0x7f) | (video_->get_annunciator_3() ? 0x80 : 0x00);
|
||||
if(is_iie()) *value = (*value & 0x7f) | (video_.get_annunciator_3() ? 0x80 : 0x00);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -546,7 +538,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
case 0xc000:
|
||||
case 0xc001:
|
||||
update_video();
|
||||
video_->set_80_store(!!(address&1));
|
||||
video_.set_80_store(!!(address&1));
|
||||
set_main_paging();
|
||||
break;
|
||||
|
||||
@ -586,13 +578,13 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
case 0xc00c:
|
||||
case 0xc00d:
|
||||
update_video();
|
||||
video_->set_80_columns(!!(address&1));
|
||||
video_.set_80_columns(!!(address&1));
|
||||
break;
|
||||
|
||||
case 0xc00e:
|
||||
case 0xc00f:
|
||||
update_video();
|
||||
video_->set_alternative_character_set(!!(address&1));
|
||||
video_.set_alternative_character_set(!!(address&1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -615,20 +607,20 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
case 0xc050:
|
||||
case 0xc051:
|
||||
update_video();
|
||||
video_->set_text(!!(address&1));
|
||||
video_.set_text(!!(address&1));
|
||||
break;
|
||||
case 0xc052: update_video(); video_->set_mixed(false); break;
|
||||
case 0xc053: update_video(); video_->set_mixed(true); break;
|
||||
case 0xc052: update_video(); video_.set_mixed(false); break;
|
||||
case 0xc053: update_video(); video_.set_mixed(true); break;
|
||||
case 0xc054:
|
||||
case 0xc055:
|
||||
update_video();
|
||||
video_->set_page2(!!(address&1));
|
||||
video_.set_page2(!!(address&1));
|
||||
set_main_paging();
|
||||
break;
|
||||
case 0xc056:
|
||||
case 0xc057:
|
||||
update_video();
|
||||
video_->set_high_resolution(!!(address&1));
|
||||
video_.set_high_resolution(!!(address&1));
|
||||
set_main_paging();
|
||||
break;
|
||||
|
||||
@ -636,7 +628,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
case 0xc05f:
|
||||
if(is_iie()) {
|
||||
update_video();
|
||||
video_->set_annunciator_3(!(address&1));
|
||||
video_.set_annunciator_3(!(address&1));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
using namespace AppleII::Video;
|
||||
|
||||
VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
|
||||
// crt_(new Outputs::CRT::CRT(910, 1, Outputs::Display::Type::NTSC60, 1)),
|
||||
crt_(910, 1, Outputs::Display::Type::NTSC60, Outputs::Display::InputDataType::Luminance1),
|
||||
is_iie_(is_iie),
|
||||
deferrer_(std::move(target)) {
|
||||
|
||||
@ -25,8 +25,8 @@ VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
|
||||
|
||||
// Show only the centre 75% of the TV frame.
|
||||
// crt_->set_video_signal(Outputs::Display::VideoSignal::Composite);
|
||||
crt_->set_visible_area(Outputs::Display::Rect(0.118f, 0.122f, 0.77f, 0.77f));
|
||||
crt_->set_immediate_default_phase(0.0f);
|
||||
crt_.set_visible_area(Outputs::Display::Rect(0.118f, 0.122f, 0.77f, 0.77f));
|
||||
crt_.set_immediate_default_phase(0.0f);
|
||||
|
||||
character_zones[0].xor_mask = 0;
|
||||
character_zones[0].address_mask = 0x3f;
|
||||
@ -46,8 +46,8 @@ VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
|
||||
}
|
||||
}
|
||||
|
||||
Outputs::CRT::CRT *VideoBase::get_crt() {
|
||||
return crt_.get();
|
||||
void VideoBase::set_scan_target(Outputs::Display::ScanTarget *scan_target) {
|
||||
crt_.set_scan_target(scan_target);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -36,8 +36,8 @@ class VideoBase {
|
||||
public:
|
||||
VideoBase(bool is_iie, std::function<void(Cycles)> &&target);
|
||||
|
||||
/// @returns The CRT this video feed is feeding.
|
||||
Outputs::CRT::CRT *get_crt();
|
||||
/// Sets the scan target.
|
||||
void set_scan_target(Outputs::Display::ScanTarget *scan_target);
|
||||
|
||||
/*
|
||||
Descriptions for the setters below are taken verbatim from
|
||||
@ -146,7 +146,7 @@ class VideoBase {
|
||||
void set_character_rom(const std::vector<uint8_t> &);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Outputs::CRT::CRT> crt_;
|
||||
Outputs::CRT::CRT crt_;
|
||||
|
||||
// State affecting output video stream generation.
|
||||
uint8_t *pixel_pointer_ = nullptr;
|
||||
@ -351,14 +351,14 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
const int blank_end = std::min(first_sync_column, ending_column);
|
||||
if(blank_end > blank_start) {
|
||||
if(blank_start > column_) {
|
||||
crt_->output_sync((blank_start - column_) * 14);
|
||||
crt_.output_sync((blank_start - column_) * 14);
|
||||
}
|
||||
crt_->output_blank((blank_end - blank_start) * 14);
|
||||
crt_.output_blank((blank_end - blank_start) * 14);
|
||||
if(blank_end < ending_column) {
|
||||
crt_->output_sync((ending_column - blank_end) * 14);
|
||||
crt_.output_sync((ending_column - blank_end) * 14);
|
||||
}
|
||||
} else {
|
||||
crt_->output_sync((cycles_this_line) * 14);
|
||||
crt_.output_sync((cycles_this_line) * 14);
|
||||
}
|
||||
} else {
|
||||
const GraphicsMode line_mode = graphics_mode(row_);
|
||||
@ -402,7 +402,7 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
// remain where they would naturally be but auxiliary
|
||||
// graphics appear to the left of that.
|
||||
if(!column_) {
|
||||
pixel_pointer_ = crt_->begin_data(568);
|
||||
pixel_pointer_ = crt_.begin_data(568);
|
||||
graphics_carry_ = 0;
|
||||
was_double_ = true;
|
||||
}
|
||||
@ -499,13 +499,13 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
pixel_pointer_[567] = 0;
|
||||
}
|
||||
|
||||
crt_->output_data(568, 568);
|
||||
crt_.output_data(568, 568);
|
||||
pixel_pointer_ = nullptr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(column_ < 40 && ending_column >= 40) {
|
||||
crt_->output_blank(568);
|
||||
crt_.output_blank(568);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,11 +515,11 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
*/
|
||||
|
||||
if(column_ < first_sync_column && ending_column >= first_sync_column) {
|
||||
crt_->output_blank((first_sync_column - 41)*14 - 1);
|
||||
crt_.output_blank((first_sync_column - 41)*14 - 1);
|
||||
}
|
||||
|
||||
if(column_ < (first_sync_column + sync_length) && ending_column >= (first_sync_column + sync_length)) {
|
||||
crt_->output_sync(sync_length*14);
|
||||
crt_.output_sync(sync_length*14);
|
||||
}
|
||||
|
||||
int second_blank_start;
|
||||
@ -527,7 +527,7 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
const int colour_burst_start = std::max(first_sync_column + sync_length + 1, column_);
|
||||
const int colour_burst_end = std::min(first_sync_column + sync_length + 4, ending_column);
|
||||
if(colour_burst_end > colour_burst_start) {
|
||||
crt_->output_colour_burst((colour_burst_end - colour_burst_start) * 14, 192);
|
||||
crt_.output_colour_burst((colour_burst_end - colour_burst_start) * 14, 192);
|
||||
}
|
||||
|
||||
second_blank_start = std::max(first_sync_column + sync_length + 3, column_);
|
||||
@ -536,7 +536,7 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
}
|
||||
|
||||
if(ending_column > second_blank_start) {
|
||||
crt_->output_blank((ending_column - second_blank_start) * 14);
|
||||
crt_.output_blank((ending_column - second_blank_start) * 14);
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,7 +551,7 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
||||
|
||||
// Add an extra half a colour cycle of blank; this isn't counted in the run_for
|
||||
// count explicitly but is promised.
|
||||
crt_->output_blank(2);
|
||||
crt_.output_blank(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user