mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
Makes the Microdisc also a DiskController, and simplifies delegate interface.
This commit is contained in:
parent
5dd8c677f1
commit
6b84ae3095
@ -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_;
|
||||
|
||||
};
|
||||
|
@ -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_);
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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(µdisc_);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user