1
0
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:
Thomas Harte 2018-11-14 22:04:57 -05:00
parent 8a699b6072
commit a47de9a884
3 changed files with 48 additions and 56 deletions

View File

@ -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;

View File

@ -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);
}
/*

View File

@ -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);
}
}
}