1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-27 01:29:31 +00:00

Makes the Microdisc also a DiskController, and simplifies delegate interface.

This commit is contained in:
Thomas Harte 2020-01-14 22:53:27 -05:00
parent 5dd8c677f1
commit 6b84ae3095
6 changed files with 54 additions and 80 deletions

View File

@ -25,33 +25,30 @@ class DiskController: public WD::WD1770 {
drives_[drive]->set_disk(disk);
}
enum PagingFlags {
/// Indicates that overlay RAM is enabled, implying no ROM is visible.
OverlayRAMEnable = (1 << 0),
/// Indicates that the BASIC ROM is disabled, implying that the disk
/// controller's ROM fills its space.
BASICDisable = (1 << 1)
enum class PagedItem {
DiskROM,
BASIC,
RAM
};
struct Delegate: public WD1770::Delegate {
virtual void disk_controller_did_change_paging_flags(DiskController *controller) = 0;
virtual void disk_controller_did_change_paged_item(DiskController *controller) = 0;
};
inline void set_delegate(Delegate *delegate) {
delegate_ = delegate;
WD1770::set_delegate(delegate);
if(delegate) delegate->disk_controller_did_change_paging_flags(this);
if(delegate) delegate->disk_controller_did_change_paged_item(this);
}
inline int get_paging_flags() {
return paging_flags_;
inline PagedItem get_paged_item() {
return paged_item_;
}
protected:
inline void set_paging_flags(int new_flags) {
if(paging_flags_ == new_flags) return;
paging_flags_ = new_flags;
inline void set_paged_item(PagedItem item) {
if(paged_item_ == item) return;
paged_item_ = item;
if(delegate_) {
delegate_->disk_controller_did_change_paging_flags(this);
delegate_->disk_controller_did_change_paged_item(this);
}
}
@ -63,10 +60,10 @@ class DiskController: public WD::WD1770 {
set_drive(drives_[selected_drive_]);
}
}
Delegate *delegate_ = nullptr;
private:
int paging_flags_ = 0;
Delegate *delegate_ = nullptr;
PagedItem paged_item_ = PagedItem::DiskROM;
int clock_rate_;
};

View File

@ -14,6 +14,7 @@ using namespace Oric;
// the only difference is stepping rates, and it says 1770 on the schematic I'm looking at.
Jasmin::Jasmin() : DiskController(P1770, 8000000) {
set_is_double_density(true);
select_paged_item();
}
void Jasmin::write(int address, uint8_t value) {
@ -31,12 +32,14 @@ void Jasmin::write(int address, uint8_t value) {
case 0x3fa: {
// If b0, enable overlay RAM.
set_paging_flags((get_paging_flags() & BASICDisable) | ((value & 1) ? OverlayRAMEnable : 0));
enable_overlay_ram_ = value & 1;
select_paged_item();
} break;
case 0x3fb:
// If b0, disable BASIC ROM.
set_paging_flags((get_paging_flags() & OverlayRAMEnable) | ((value & 1) ? BASICDisable : 0));
disable_basic_rom_ = value & 1;
select_paged_item();
break;
case 0x3fc: case 0x3fd: case 0x3fe: case 0x3ff: {
@ -50,6 +53,14 @@ void Jasmin::write(int address, uint8_t value) {
}
}
void Jasmin::select_paged_item() {
PagedItem item = PagedItem::RAM;
if(!enable_overlay_ram_) {
item = disable_basic_rom_ ? PagedItem::DiskROM : PagedItem::BASIC;
}
set_paged_item(item);
}
void Jasmin::set_motor_on(bool on) {
motor_on_ = on;
if(drives_[selected_drive_]) drives_[selected_drive_]->set_motor_on(motor_on_);

View File

@ -28,6 +28,10 @@ class Jasmin: public DiskController {
void set_motor_on(bool on) final;
bool motor_on_ = false;
bool enable_overlay_ram_ = false;
bool disable_basic_rom_ = false;
void select_paged_item();
};
};

View File

@ -18,20 +18,10 @@ namespace {
const Cycles::IntType head_load_request_counter_target = 7653333;
}
Microdisc::Microdisc() : WD1770(P1793) {
Microdisc::Microdisc() : DiskController(P1793, 8000000) {
set_control_register(last_control_, 0xff);
}
void Microdisc::set_disk(std::shared_ptr<Storage::Disk::Disk> disk, int d) {
const size_t drive = size_t(d);
if(!drives_[drive]) {
drives_[drive] = std::make_unique<Storage::Disk::Drive>(8000000, 300, 2);
if(drive == selected_drive_) set_drive(drives_[drive]);
drives_[drive]->set_activity_observer(observer_, drive_name(drive), false);
}
drives_[drive]->set_disk(disk);
}
void Microdisc::set_control_register(uint8_t control) {
const uint8_t changes = last_control_ ^ control;
last_control_ = control;
@ -73,8 +63,11 @@ void Microdisc::set_control_register(uint8_t control, uint8_t changes) {
// b7: EPROM select (0 = select)
// b1: ROM disable (0 = disable)
if(changes & 0x82) {
paging_flags_ = ((control & 0x02) ? 0 : BASICDisable) | ((control & 0x80) ? MicrodiscDisable : 0);
if(delegate_) delegate_->microdisc_did_change_paging_flags(this);
PagedItem item = PagedItem::RAM;
if(!(control & 0x80)) {
item = (control & 0x02) ? PagedItem::BASIC : PagedItem::DiskROM;
}
set_paged_item(item);
}
}
@ -121,10 +114,6 @@ void Microdisc::run_for(const Cycles cycles) {
WD::WD1770::run_for(cycles);
}
bool Microdisc::get_drive_is_ready() {
return true;
}
void Microdisc::set_activity_observer(Activity::Observer *observer) {
observer_ = observer;
if(observer) {

View File

@ -17,11 +17,10 @@
namespace Oric {
class Microdisc: public WD::WD1770 {
class Microdisc: public DiskController {
public:
Microdisc();
void set_disk(std::shared_ptr<Storage::Disk::Disk> disk, int drive);
void set_control_register(uint8_t control);
uint8_t get_interrupt_request_register();
uint8_t get_data_request_register();
@ -30,39 +29,18 @@ class Microdisc: public WD::WD1770 {
void run_for(const Cycles cycles);
enum PagingFlags {
/// Indicates that the BASIC ROM should be disabled; if this is set then either
/// the Microdisc ROM or overlay RAM will be visible. If it is not set, BASIC
/// should be visible.
BASICDisable = (1 << 0),
/// Indicates that the Microdisc ROM is disabled. If BASIC is disabled and the Microdisc
/// is also disabled, overlay RAM should be visible.
MicrodiscDisable = (1 << 1)
};
class Delegate: public WD1770::Delegate {
public:
virtual void microdisc_did_change_paging_flags(Microdisc *microdisc) = 0;
};
inline void set_delegate(Delegate *delegate) { delegate_ = delegate; WD1770::set_delegate(delegate); }
inline int get_paging_flags() { return paging_flags_; }
void set_activity_observer(Activity::Observer *observer);
private:
void set_control_register(uint8_t control, uint8_t changes);
void set_head_load_request(bool head_load) override;
bool get_drive_is_ready();
void set_head_load_request(bool head_load) final;
std::array<std::shared_ptr<Storage::Disk::Drive>, 4> drives_;
size_t selected_drive_;
void set_control_register(uint8_t control, uint8_t changes);
uint8_t last_control_ = 0;
bool irq_enable_ = false;
int paging_flags_ = BASICDisable;
Cycles::IntType head_load_request_counter_ = -1;
bool head_load_request_ = false;
Delegate *delegate_ = nullptr;
uint8_t last_control_ = 0;
Activity::Observer *observer_ = nullptr;
std::string drive_name(size_t index);

View File

@ -223,7 +223,6 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
public MOS::MOS6522::IRQDelegatePortHandler::Delegate,
public Utility::TypeRecipient,
public Storage::Tape::BinaryTapePlayer::Delegate,
public Microdisc::Delegate,
public DiskController::Delegate,
public ClockingHint::Observer,
public Activity::Source,
@ -321,13 +320,15 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
switch(target.disk_interface) {
default: break;
case DiskInterface::Microdisc:
microdisc_did_change_paging_flags(&microdisc_);
microdisc_.set_delegate(this);
case DiskInterface::BD500:
// jasmin_.set_delegate(this);
break;
case DiskInterface::Jasmin:
jasmin_.set_delegate(this);
break;
case DiskInterface::Microdisc:
microdisc_.set_delegate(this);
break;
}
if(!target.loading_command.empty()) {
@ -573,7 +574,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
}
// for Microdisc::Delegate
void microdisc_did_change_paging_flags(class Microdisc *microdisc) final {
/* void microdisc_did_change_paging_flags(class Microdisc *microdisc) final {
const int flags = microdisc->get_paging_flags();
if(!(flags&Microdisc::PagingFlags::BASICDisable)) {
ram_top_ = basic_visible_ram_top_;
@ -586,27 +587,21 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
paged_rom_ = disk_rom_.data();
}
}
}
}*/
// DiskController::Delegate
void disk_controller_did_change_paging_flags(DiskController *controller) final {
const int flags = controller->get_paging_flags();
switch(flags) {
// BASIC enabled, overlay disabled.
void disk_controller_did_change_paged_item(DiskController *controller) final {
switch(controller->get_paged_item()) {
default:
ram_top_ = basic_visible_ram_top_;
paged_rom_ = rom_.data();
break;
// Overlay RAM enabled, with or without BASIC.
case DiskController::OverlayRAMEnable:
case DiskController::OverlayRAMEnable | DiskController::BASICDisable:
case DiskController::PagedItem::RAM:
ram_top_ = basic_invisible_ram_top_;
break;
// BASIC disabled, overlay disabled.
case DiskController::BASICDisable:
case DiskController::PagedItem::DiskROM:
ram_top_ = uint16_t(0xffff - disk_rom_.size());
paged_rom_ = disk_rom_.data();
break;