2018-04-24 05:11:31 +00:00
|
|
|
//
|
|
|
|
// DiskII.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 23/04/2018.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2018 Thomas Harte. All rights reserved.
|
2018-04-24 05:11:31 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#include "DiskIICard.hpp"
|
|
|
|
|
2019-05-03 22:14:10 +00:00
|
|
|
using namespace Apple::II;
|
2018-04-24 05:11:31 +00:00
|
|
|
|
2021-06-04 01:55:59 +00:00
|
|
|
ROM::Request DiskIICard::rom_request(bool is_16_sector) {
|
|
|
|
if(is_16_sector) {
|
|
|
|
return ROM::Request(ROM::Name::DiskIIBoot16Sector) && ROM::Request(ROM::Name::DiskIIStateMachine16Sector);
|
|
|
|
} else {
|
|
|
|
/* TODO: once the DiskII knows how to decode common images of the 13-sector state machine, use that instead of the 16-sector. */
|
|
|
|
return ROM::Request(ROM::Name::DiskIIBoot13Sector) && ROM::Request(ROM::Name::DiskIIStateMachine16Sector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DiskIICard::DiskIICard(ROM::Map &map, bool is_16_sector) : diskii_(2045454) {
|
2019-07-23 02:15:44 +00:00
|
|
|
std::vector<std::unique_ptr<std::vector<uint8_t>>> roms;
|
2021-06-04 01:55:59 +00:00
|
|
|
ROM::Map::iterator state_machine, boot;
|
2019-07-23 02:15:44 +00:00
|
|
|
if(is_16_sector) {
|
2021-06-04 01:55:59 +00:00
|
|
|
state_machine = map.find(ROM::Name::DiskIIStateMachine16Sector);
|
|
|
|
boot = map.find(ROM::Name::DiskIIBoot16Sector);
|
2019-07-23 02:15:44 +00:00
|
|
|
} else {
|
2021-06-04 01:55:59 +00:00
|
|
|
// TODO: see above re: 13-sector state machine.
|
|
|
|
state_machine = map.find(ROM::Name::DiskIIStateMachine16Sector);
|
|
|
|
boot = map.find(ROM::Name::DiskIIBoot13Sector);
|
2019-07-23 02:15:44 +00:00
|
|
|
}
|
2021-06-04 01:55:59 +00:00
|
|
|
|
|
|
|
if(state_machine == map.end() || boot == map.end()) {
|
2019-07-23 03:07:23 +00:00
|
|
|
throw ROMMachine::Error::MissingROMs;
|
|
|
|
}
|
|
|
|
|
2021-06-04 01:55:59 +00:00
|
|
|
boot_ = std::move(boot->second);
|
|
|
|
diskii_.set_state_machine(state_machine->second);
|
2018-05-22 00:54:53 +00:00
|
|
|
set_select_constraints(None);
|
2018-05-28 03:17:06 +00:00
|
|
|
diskii_.set_clocking_hint_observer(this);
|
2018-04-24 05:11:31 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 00:54:53 +00:00
|
|
|
void DiskIICard::perform_bus_operation(Select select, bool is_read, uint16_t address, uint8_t *value) {
|
|
|
|
diskii_.set_data_input(*value);
|
|
|
|
switch(select) {
|
|
|
|
default: break;
|
2024-02-15 15:29:30 +00:00
|
|
|
case Device: {
|
2018-05-22 00:54:53 +00:00
|
|
|
const int disk_value = diskii_.read_address(address);
|
|
|
|
if(is_read) {
|
|
|
|
if(disk_value != diskii_.DidNotLoad)
|
2020-05-10 03:00:39 +00:00
|
|
|
*value = uint8_t(disk_value);
|
2018-05-22 00:54:53 +00:00
|
|
|
}
|
|
|
|
} break;
|
2024-02-15 15:29:30 +00:00
|
|
|
case IO:
|
2018-05-22 00:54:53 +00:00
|
|
|
if(is_read) *value = boot_[address & 0xff];
|
|
|
|
break;
|
2018-04-24 05:11:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-30 04:37:06 +00:00
|
|
|
void DiskIICard::run_for(Cycles cycles, int) {
|
2018-05-28 03:17:06 +00:00
|
|
|
if(diskii_clocking_preference_ == ClockingHint::Preference::None) return;
|
2019-10-30 02:36:29 +00:00
|
|
|
diskii_.run_for(Cycles(cycles.as_integral() * 2));
|
2018-04-24 05:11:31 +00:00
|
|
|
}
|
2018-04-25 02:44:45 +00:00
|
|
|
|
|
|
|
void DiskIICard::set_disk(const std::shared_ptr<Storage::Disk::Disk> &disk, int drive) {
|
|
|
|
diskii_.set_disk(disk, drive);
|
|
|
|
}
|
2018-05-11 02:17:13 +00:00
|
|
|
|
|
|
|
void DiskIICard::set_activity_observer(Activity::Observer *observer) {
|
|
|
|
diskii_.set_activity_observer(observer);
|
|
|
|
}
|
2018-05-22 23:51:39 +00:00
|
|
|
|
2020-05-30 04:37:06 +00:00
|
|
|
void DiskIICard::set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference preference) {
|
2018-05-28 03:17:06 +00:00
|
|
|
diskii_clocking_preference_ = preference;
|
2024-02-15 15:29:30 +00:00
|
|
|
set_select_constraints((preference != ClockingHint::Preference::RealTime) ? (Device | IO) : None);
|
2018-05-22 23:51:39 +00:00
|
|
|
}
|
2018-06-09 16:51:53 +00:00
|
|
|
|
|
|
|
Storage::Disk::Drive &DiskIICard::get_drive(int drive) {
|
|
|
|
return diskii_.get_drive(drive);
|
|
|
|
}
|