1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

The Disk II now being its proper speed, withdraws the quickload option.

This commit is contained in:
Thomas Harte 2018-08-03 21:20:21 -04:00
parent 70c4d6b9b3
commit c4f86cc324
3 changed files with 22 additions and 140 deletions

View File

@ -27,27 +27,17 @@
#include "../../Analyser/Static/AppleII/Target.hpp" #include "../../Analyser/Static/AppleII/Target.hpp"
#include "../../ClockReceiver/ForceInline.hpp" #include "../../ClockReceiver/ForceInline.hpp"
#include "../../Configurable/Configurable.hpp"
#include "../../Storage/Disk/Track/TrackSerialiser.hpp"
#include "../../Storage/Disk/Encodings/AppleGCR/SegmentParser.hpp"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <memory> #include <memory>
std::vector<std::unique_ptr<Configurable::Option>> AppleII::get_options() {
std::vector<std::unique_ptr<Configurable::Option>> options;
options.emplace_back(new Configurable::BooleanOption("Accelerate DOS 3.3", "quickload"));
return options;
}
namespace { namespace {
template <bool is_iie> class ConcreteMachine: template <bool is_iie> class ConcreteMachine:
public CRTMachine::Machine, public CRTMachine::Machine,
public MediaTarget::Machine, public MediaTarget::Machine,
public KeyboardMachine::Machine, public KeyboardMachine::Machine,
public Configurable::Device,
public CPU::MOS6502::BusHandler, public CPU::MOS6502::BusHandler,
public Inputs::Keyboard, public Inputs::Keyboard,
public AppleII::Machine, public AppleII::Machine,
@ -256,9 +246,6 @@ template <bool is_iie> class ConcreteMachine:
// MARK - typing // MARK - typing
std::unique_ptr<Utility::StringSerialiser> string_serialiser_; std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
// MARK - quick loading
bool should_load_quickly_ = false;
// MARK - joysticks // MARK - joysticks
class Joystick: public Inputs::ConcreteJoystick { class Joystick: public Inputs::ConcreteJoystick {
public: public:
@ -441,85 +428,6 @@ template <bool is_iie> class ConcreteMachine:
set_card_paging(); set_card_paging();
} }
} }
if(should_load_quickly_) {
// Check for a prima facie entry into RWTS.
if(operation == CPU::MOS6502::BusOperation::ReadOpcode && address == 0xb7b5) {
// Grab the IO control block address for inspection.
uint16_t io_control_block_address =
static_cast<uint16_t>(
(m6502_.get_value_of_register(CPU::MOS6502::Register::A) << 8) |
m6502_.get_value_of_register(CPU::MOS6502::Register::Y)
);
// Verify that this is table type one, for execution on card six,
// against drive 1 or 2, and that the command is either a seek or a sector read.
if(
ram_[io_control_block_address+0x00] == 0x01 &&
ram_[io_control_block_address+0x01] == 0x60 &&
ram_[io_control_block_address+0x02] > 0 && ram_[io_control_block_address+0x02] < 3 &&
ram_[io_control_block_address+0x0c] < 2
) {
const uint8_t iob_track = ram_[io_control_block_address+4];
const uint8_t iob_sector = ram_[io_control_block_address+5];
const uint8_t iob_drive = ram_[io_control_block_address+2] - 1;
// Get the track identified and store the new head position.
auto track = diskii_card()->get_drive(iob_drive).step_to(Storage::Disk::HeadPosition(iob_track));
// DOS 3.3 keeps the current track (unspecified drive) in 0x478; the current track for drive 1 and drive 2
// is also kept in that Disk II card's screen hole.
ram_[0x478] = iob_track;
if(ram_[io_control_block_address+0x02] == 1) {
ram_[0x47e] = iob_track;
} else {
ram_[0x4fe] = iob_track;
}
// Check whether this is a read, not merely a seek.
if(ram_[io_control_block_address+0x0c] == 1) {
// Apple the DOS 3.3 formula to map the requested logical sector to a physical sector.
const int physical_sector = (iob_sector == 15) ? 15 : ((iob_sector * 13) % 15);
// Parse the entire track. TODO: cache these.
auto sector_map = Storage::Encodings::AppleGCR::sectors_from_segment(
Storage::Disk::track_serialisation(*track, Storage::Time(1, 50000)));
bool found_sector = false;
for(const auto &pair: sector_map) {
if(pair.second.address.sector == physical_sector) {
found_sector = true;
// Copy the sector contents to their destination.
uint16_t target = static_cast<uint16_t>(
ram_[io_control_block_address+8] |
(ram_[io_control_block_address+9] << 8)
);
for(size_t c = 0; c < 256; ++c) {
ram_[target] = pair.second.data[c];
++target;
}
// Set no error encountered.
ram_[io_control_block_address + 0xd] = 0;
break;
}
}
if(found_sector) {
// Set no error in the flags register too, and RTS.
m6502_.set_value_of_register(CPU::MOS6502::Register::Flags, m6502_.get_value_of_register(CPU::MOS6502::Register::Flags) & ~1);
*value = 0x60;
}
} else {
// No error encountered; RTS.
m6502_.set_value_of_register(CPU::MOS6502::Register::Flags, m6502_.get_value_of_register(CPU::MOS6502::Register::Flags) & ~1);
*value = 0x60;
}
}
}
}
} else { } else {
// Assume a vapour read unless it turns out otherwise; this is a little // Assume a vapour read unless it turns out otherwise; this is a little
// wasteful but works for now. // wasteful but works for now.
@ -609,11 +517,18 @@ template <bool is_iie> class ConcreteMachine:
// printf("Unknown (?) write to %04x\n", address); // printf("Unknown (?) write to %04x\n", address);
break; break;
case 0xc000:
case 0xc001:
video_->set_80_store(!!(address&1));
set_main_paging();
break;
case 0xc002: case 0xc002:
case 0xc003: case 0xc003:
read_auxiliary_memory_ = !!(address&1); read_auxiliary_memory_ = !!(address&1);
set_main_paging(); set_main_paging();
break; break;
case 0xc004: case 0xc004:
case 0xc005: case 0xc005:
write_auxiliary_memory_ = !!(address&1); write_auxiliary_memory_ = !!(address&1);
@ -625,26 +540,6 @@ template <bool is_iie> class ConcreteMachine:
internal_CX_rom_ = !!(address&1); internal_CX_rom_ = !!(address&1);
set_card_paging(); set_card_paging();
break; break;
case 0xc00a:
case 0xc00b:
slot_C3_rom_ = !!(address&1);
set_card_paging();
break;
case 0xc00e:
case 0xc00f: video_->set_alternative_character_set(!!(address&1)); break;
case 0xc00c:
case 0xc00d: video_->set_80_columns(!!(address&1)); break;
case 0xc000:
case 0xc001:
video_->set_80_store(!!(address&1));
set_main_paging();
break;
case 0xc05e:
case 0xc05f: video_->set_double_high_resolution(!(address&1)); break;
case 0xc008: case 0xc008:
case 0xc009: case 0xc009:
@ -654,6 +549,21 @@ template <bool is_iie> class ConcreteMachine:
set_zero_page_paging(); set_zero_page_paging();
set_language_card_paging(); set_language_card_paging();
break; break;
case 0xc00a:
case 0xc00b:
slot_C3_rom_ = !!(address&1);
set_card_paging();
break;
case 0xc00c:
case 0xc00d: video_->set_80_columns(!!(address&1)); break;
case 0xc00e:
case 0xc00f: video_->set_alternative_character_set(!!(address&1)); break;
case 0xc05e:
case 0xc05f: video_->set_double_high_resolution(!(address&1)); break;
} }
} }
} }
@ -860,30 +770,6 @@ template <bool is_iie> class ConcreteMachine:
} }
} }
// MARK: Options
std::vector<std::unique_ptr<Configurable::Option>> get_options() override {
return AppleII::get_options();
}
void set_selections(const Configurable::SelectionSet &selections_by_option) override {
bool quickload;
if(Configurable::get_quick_load_tape(selections_by_option, quickload)) {
should_load_quickly_ = quickload;
}
}
Configurable::SelectionSet get_accurate_selections() override {
Configurable::SelectionSet selection_set;
Configurable::append_quick_load_tape_selection(selection_set, false);
return selection_set;
}
Configurable::SelectionSet get_user_friendly_selections() override {
Configurable::SelectionSet selection_set;
Configurable::append_quick_load_tape_selection(selection_set, true);
return selection_set;
}
// MARK: JoystickMachine // MARK: JoystickMachine
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override { std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
return joysticks_; return joysticks_;

View File

@ -18,9 +18,6 @@
namespace AppleII { namespace AppleII {
/// @returns The options available for an Apple II.
std::vector<std::unique_ptr<Configurable::Option>> get_options();
class Machine { class Machine {
public: public:
virtual ~Machine(); virtual ~Machine();

View File

@ -130,7 +130,6 @@ std::map<std::string, std::vector<std::unique_ptr<Configurable::Option>>> Machin
std::map<std::string, std::vector<std::unique_ptr<Configurable::Option>>> options; std::map<std::string, std::vector<std::unique_ptr<Configurable::Option>>> options;
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::AmstradCPC), AmstradCPC::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::AmstradCPC), AmstradCPC::get_options()));
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::AppleII), AppleII::get_options()));
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Electron), Electron::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Electron), Electron::get_options()));
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::MSX), MSX::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::MSX), MSX::get_options()));
options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Oric), Oric::get_options())); options.emplace(std::make_pair(LongNameForTargetMachine(Analyser::Machine::Oric), Oric::get_options()));