mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
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.
This commit is contained in:
parent
f5c194386c
commit
91fae86e73
@ -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<int> 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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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_;
|
||||
|
@ -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_);
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,10 +504,10 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
enableASanStackUseAfterReturn = "YES"
|
||||
|
Loading…
Reference in New Issue
Block a user