From 91fae86e7320d55ed81299f059dc500a0e3f589a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 15 Jan 2020 23:15:39 -0500 Subject: [PATCH] Factors out paging, implements a bit more of the BD500. That is, enough seemingly fully to work, if I force the drive to report ready. --- Machines/Oric/BD500.cpp | 90 ++++++++++++++++--- Machines/Oric/BD500.hpp | 2 + Machines/Oric/DiskController.hpp | 10 +++ Machines/Oric/Jasmin.cpp | 8 -- Machines/Oric/Jasmin.hpp | 5 -- Machines/Oric/Microdisc.cpp | 8 +- Machines/Oric/Oric.cpp | 8 +- .../xcschemes/Clock Signal.xcscheme | 2 +- 8 files changed, 99 insertions(+), 34 deletions(-) diff --git a/Machines/Oric/BD500.cpp b/Machines/Oric/BD500.cpp index fc5d6d210..2a719f14e 100644 --- a/Machines/Oric/BD500.cpp +++ b/Machines/Oric/BD500.cpp @@ -11,39 +11,107 @@ using namespace Oric; BD500::BD500() : DiskController(P1793, 9000000) { - set_paged_item(PagedItem::DiskROM); + disable_basic_rom_ = true; + select_paged_item(); set_is_double_density(true); } void BD500::write(int address, uint8_t value) { - switch(address) { - case 0x0320: case 0x0321: case 0x0322: case 0x0323: - WD::WD1770::write(address, value); - break; + access(address); - default: - printf("Write to %04x?\n", address); - break; + if(address >= 0x0320 && address <= 0x0323) { + if(address == 0x320) printf("Command %02x\n", value); + WD::WD1770::write(address, value); } } uint8_t BD500::read(int address) { + access(address); + switch(address) { + default: return 0xff; + case 0x0320: case 0x0321: case 0x0322: case 0x0323: return WD::WD1770::read(address); case 0x312: return (get_data_request_line() ? 0x80 : 0x00) | (get_interrupt_request_line() ? 0x40 : 0x00); + } +} + +void BD500::access(int address) { + // Determine whether to perform a command. + switch(address) { + case 0x0320: case 0x0321: case 0x0322: case 0x0323: case 0x0312: + return; + + case 0x310: enable_overlay_ram_ = true; break; + case 0x313: enable_overlay_ram_ = false; break; + case 0x317: disable_basic_rom_ = false; break; // Could be 0x311. default: - printf("Read from %04x?\n", address); + printf("Switch %04x???\n", address); break; } - return 0xff; + select_paged_item(); } +/* + The following was used when trying to find appropriate soft switch locations. It is preserved + as the values I have above are unlikely to be wholly correct and further research might be + desirable. + +void BD500::access(int address) { + // 0,1,4,5,10,11 -> 64kb Atmos + // 2,3,9 -> 56kb Atmos. + // Broken: 6, 7, 8 + + int order = 5; + int commands[4]; + std::vector available_commands = {0, 1, 2, 3}; + const int modulos[] = {6, 2, 1, 1}; + + for(int c = 0; c < 4; ++c) { + const int index = order / modulos[c]; + commands[c] = available_commands[size_t(index)]; + available_commands.erase(available_commands.begin() + index); + order %= modulos[c]; + } + + + // Determine whether to perform a command. + int index = -1; + switch(address) { + case 0x0320: case 0x0321: case 0x0322: case 0x0323: case 0x0312: + return; + + case 0x310: index = 0; break; + case 0x313: index = 1; break; + case 0x314: index = 2; break; + case 0x317: index = 3; break; + + default: + printf("Switch %04x???\n", address); + break; + } + + select_paged_item(); + + if(index >= 0) { + switch(commands[index]) { + case 0: enable_overlay_ram_ = true; break; // +RAM + case 1: disable_basic_rom_ = false; break; // -rom + case 2: disable_basic_rom_ = true; break; // +rom + case 3: enable_overlay_ram_ = false; break; // -RAM + + } + select_paged_item(); + } +} +*/ + void BD500::set_head_load_request(bool head_load) { - // Turn all motors on or off, and load the head instantly. + // Turn all motors on or off; if off then unload the head instantly. is_loading_head_ |= head_load; for(auto &drive : drives_) { if(drive) drive->set_motor_on(head_load); diff --git a/Machines/Oric/BD500.hpp b/Machines/Oric/BD500.hpp index 52c501258..ff0cdeea0 100644 --- a/Machines/Oric/BD500.hpp +++ b/Machines/Oric/BD500.hpp @@ -30,6 +30,8 @@ class BD500: public DiskController { private: void set_head_load_request(bool head_load) final; bool is_loading_head_ = false; + + void access(int address); }; }; diff --git a/Machines/Oric/DiskController.hpp b/Machines/Oric/DiskController.hpp index f76db889f..06dd4cec2 100644 --- a/Machines/Oric/DiskController.hpp +++ b/Machines/Oric/DiskController.hpp @@ -62,6 +62,16 @@ class DiskController: public WD::WD1770 { } Delegate *delegate_ = nullptr; + bool enable_overlay_ram_ = false; + bool disable_basic_rom_ = false; + void select_paged_item() { + PagedItem item = PagedItem::RAM; + if(!enable_overlay_ram_) { + item = disable_basic_rom_ ? PagedItem::DiskROM : PagedItem::BASIC; + } + set_paged_item(item); + } + private: PagedItem paged_item_ = PagedItem::DiskROM; int clock_rate_; diff --git a/Machines/Oric/Jasmin.cpp b/Machines/Oric/Jasmin.cpp index ec6017068..3a3a5675d 100644 --- a/Machines/Oric/Jasmin.cpp +++ b/Machines/Oric/Jasmin.cpp @@ -53,14 +53,6 @@ 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_); diff --git a/Machines/Oric/Jasmin.hpp b/Machines/Oric/Jasmin.hpp index eaaa8a383..5717c4ab4 100644 --- a/Machines/Oric/Jasmin.hpp +++ b/Machines/Oric/Jasmin.hpp @@ -25,13 +25,8 @@ class Jasmin: public DiskController { void write(int address, uint8_t value); private: - 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(); }; }; diff --git a/Machines/Oric/Microdisc.cpp b/Machines/Oric/Microdisc.cpp index ef4245a55..7b538751c 100644 --- a/Machines/Oric/Microdisc.cpp +++ b/Machines/Oric/Microdisc.cpp @@ -63,11 +63,9 @@ void Microdisc::set_control_register(uint8_t control, uint8_t changes) { // b7: EPROM select (0 = select) // b1: ROM disable (0 = disable) if(changes & 0x82) { - PagedItem item = PagedItem::RAM; - if(!(control & 0x80)) { - item = (control & 0x02) ? PagedItem::BASIC : PagedItem::DiskROM; - } - set_paged_item(item); + enable_overlay_ram_ = control & 0x80; + disable_basic_rom_ = !(control & 0x02); + select_paged_item(); } } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 5016c76c7..2e6edd152 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -504,10 +504,10 @@ template class Co switch(disk_interface) { default: break; case DiskInterface::BD500: - bd500_.run_for(Cycles(8)); + bd500_.run_for(Cycles(9)); // i.e. effective clock rate of 9Mhz. break; case DiskInterface::Jasmin: - jasmin_.run_for(Cycles(8)); + jasmin_.run_for(Cycles(8));; // i.e. effective clock rate of 8Mhz. // Jasmin autostart hack: wait for a period, then trigger a reset, having forced // the Jasmin to page its ROM in first. I assume the latter being what the Jasmin's @@ -520,12 +520,12 @@ template class Co } break; case DiskInterface::Microdisc: - microdisc_.run_for(Cycles(8)); + microdisc_.run_for(Cycles(8));; // i.e. effective clock rate of 8Mhz. break; case DiskInterface::Pravetz: if(diskii_clocking_preference_ == ClockingHint::Preference::RealTime) { diskii_.set_data_input(*value); - diskii_.run_for(Cycles(2)); + diskii_.run_for(Cycles(2));; // i.e. effective clock rate of 2Mhz. } else { cycles_since_diskii_update_ += Cycles(2); } diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 1465a4f62..47f9c7286 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -67,7 +67,7 @@