1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-09 06:29:33 +00:00

Starts to add a disk controller.

This commit is contained in:
Thomas Harte 2021-10-04 16:45:05 -07:00
parent b3f0ca39ed
commit 674941abdf
2 changed files with 96 additions and 43 deletions

View File

@ -33,20 +33,16 @@ template <DMAFlag... Flags> struct DMAMask: Mask<DMAFlag, Flags...> {};
} }
Chipset::Chipset(MemoryMap &map, int input_clock_rate) : Chipset::Chipset(MemoryMap &map, int input_clock_rate) :
cia_a_handler_(map),
cia_a(cia_a_handler_),
cia_b(cia_b_handler_),
blitter_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1), blitter_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1),
bitplanes_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1), bitplanes_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1),
copper_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1), copper_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1),
drives_{ disk_controller_(Cycles(input_clock_rate)),
{input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY},
{input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY},
{input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY},
{input_clock_rate, 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY}
},
disk_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1), disk_(*this, reinterpret_cast<uint16_t *>(map.chip_ram.data()), map.chip_ram.size() >> 1),
crt_(908, 4, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4) { crt_(908, 4, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4),
cia_a_handler_(map, disk_controller_),
cia_b_handler_(disk_controller_),
cia_a(cia_a_handler_),
cia_b(cia_b_handler_) {
} }
Chipset::Changes Chipset::run_for(HalfCycles length) { Chipset::Changes Chipset::run_for(HalfCycles length) {
@ -920,14 +916,14 @@ Outputs::Display::DisplayType Chipset::get_display_type() const {
return crt_.get_display_type(); return crt_.get_display_type();
} }
// MARK: - CIA Handlers. // MARK: - CIA A.
Chipset::CIAAHandler::CIAAHandler(MemoryMap &map) : map_(map) {} Chipset::CIAAHandler::CIAAHandler(MemoryMap &map, DiskController &controller) : map_(map), controller_(controller) {}
void Chipset::CIAAHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) { void Chipset::CIAAHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) {
if(port) { if(port) {
// Parallel port output. // Parallel port output.
LOG("TODO: parallel output " << PADHEX(2) << +value); LOG("TODO: parallel output " << PADHEX(2) << +value);
} else { } else {
// b7: /FIR1 // b7: /FIR1
// b6: /FIR0 // b6: /FIR0
@ -965,6 +961,10 @@ void Chipset::CIAAHandler::set_activity_observer(Activity::Observer *observer) {
} }
} }
// MARK: - CIA B.
Chipset::CIABHandler::CIABHandler(DiskController &controller) : controller_(controller) {}
void Chipset::CIABHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) { void Chipset::CIABHandler::set_port_output(MOS::MOS6526::Port port, uint8_t value) {
if(port) { if(port) {
// Serial port control. // Serial port control.
@ -990,11 +990,43 @@ void Chipset::CIABHandler::set_port_output(MOS::MOS6526::Port port, uint8_t valu
// b2: /SIDE // b2: /SIDE
// b1: DIR // b1: DIR
// b0: /STEP // b0: /STEP
LOG("TODO: Stepping, etc; " << PADHEX(2) << +value); LOG("TODO: Stepping, etc; " << PADHEX(2) << +value);
controller_.set_drive((value >> 3) & 0xf);
// "[The MTR] signal is nonstandard on the Amiga system.
// Each drive will latch the motor signal at the time its
// select signal turns on." — The Hardware Reference Manual.
previous_select_ = value;
} }
} }
uint8_t Chipset::CIABHandler::get_port_input(MOS::MOS6526::Port) { uint8_t Chipset::CIABHandler::get_port_input(MOS::MOS6526::Port port) {
LOG("Unexpected input for CIA B "); LOG("Unexpected input for CIA B ");
return 0xff; if(port) {
return 0xff;
} else {
return previous_select_;
}
}
// MARK: - Disk Controller.
Chipset::DiskController::DiskController(Cycles clock_rate) :
Storage::Disk::Controller(clock_rate) {
// Add four drives.
for(int c = 0; c < 4; c++) {
emplace_drive(clock_rate.as<int>(), 300, 2, Storage::Disk::Drive::ReadyType::ShugartRDY);
}
}
void Chipset::DiskController::process_input_bit(int value) {
// TODO:
(void)value;
}
void Chipset::DiskController::process_index_hole() {
// TODO: does the Amiga care?
} }

View File

@ -16,6 +16,7 @@
#include "../../Components/6526/6526.hpp" #include "../../Components/6526/6526.hpp"
#include "../../Outputs/CRT/CRT.hpp" #include "../../Outputs/CRT/CRT.hpp"
#include "../../Processors/68000/68000.hpp" #include "../../Processors/68000/68000.hpp"
#include "../../Storage/Disk/Controller/DiskController.hpp"
#include "../../Storage/Disk/Drive.hpp" #include "../../Storage/Disk/Drive.hpp"
#include "Blitter.hpp" #include "Blitter.hpp"
@ -100,31 +101,6 @@ class Chipset {
cia_a_handler_.set_activity_observer(observer); cia_a_handler_.set_activity_observer(observer);
} }
private:
class CIAAHandler: public MOS::MOS6526::PortHandler {
public:
CIAAHandler(MemoryMap &map);
void set_port_output(MOS::MOS6526::Port port, uint8_t value);
uint8_t get_port_input(MOS::MOS6526::Port port);
void set_activity_observer(Activity::Observer *observer);
private:
MemoryMap &map_;
Activity::Observer *observer_ = nullptr;
inline static const std::string led_name = "Power";
} cia_a_handler_;
struct CIABHandler: public MOS::MOS6526::PortHandler {
void set_port_output(MOS::MOS6526::Port port, uint8_t value);
uint8_t get_port_input(MOS::MOS6526::Port);
} cia_b_handler_;
public:
// CIAs are provided for direct access; it's up to the caller properly
// to distinguish relevant accesses.
MOS::MOS6526::MOS6526<CIAAHandler, MOS::MOS6526::Personality::P8250> cia_a;
MOS::MOS6526::MOS6526<CIABHandler, MOS::MOS6526::Personality::P8250> cia_b;
private: private:
friend class DMADeviceBase; friend class DMADeviceBase;
@ -242,7 +218,19 @@ class Chipset {
// MARK: - Disk drives. // MARK: - Disk drives.
Storage::Disk::Drive drives_[4]; class DiskController: private Storage::Disk::Controller {
public:
DiskController(Cycles clock_rate);
void set_drive(int index_mask) {
Storage::Disk::Controller::set_drive(index_mask);
}
private:
void process_input_bit(int value) final;
void process_index_hole() final;
} disk_controller_;
class DiskDMA: public DMADevice<1> { class DiskDMA: public DMADevice<1> {
public: public:
@ -271,6 +259,39 @@ class Chipset {
Outputs::CRT::CRT crt_; Outputs::CRT::CRT crt_;
uint16_t palette_[32]{}; uint16_t palette_[32]{};
uint16_t swizzled_palette_[32]{}; uint16_t swizzled_palette_[32]{};
// MARK: - CIAs
private:
class CIAAHandler: public MOS::MOS6526::PortHandler {
public:
CIAAHandler(MemoryMap &map, DiskController &controller);
void set_port_output(MOS::MOS6526::Port port, uint8_t value);
uint8_t get_port_input(MOS::MOS6526::Port port);
void set_activity_observer(Activity::Observer *observer);
private:
MemoryMap &map_;
DiskController &controller_;
Activity::Observer *observer_ = nullptr;
inline static const std::string led_name = "Power";
} cia_a_handler_;
class CIABHandler: public MOS::MOS6526::PortHandler {
public:
CIABHandler(DiskController &controller);
void set_port_output(MOS::MOS6526::Port port, uint8_t value);
uint8_t get_port_input(MOS::MOS6526::Port);
private:
DiskController &controller_;
uint8_t previous_select_ = 0;
} cia_b_handler_;
public:
// CIAs are provided for direct access; it's up to the caller properly
// to distinguish relevant accesses.
MOS::MOS6526::MOS6526<CIAAHandler, MOS::MOS6526::Personality::P8250> cia_a;
MOS::MOS6526::MOS6526<CIABHandler, MOS::MOS6526::Personality::P8250> cia_b;
}; };
} }