mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-16 05:27:43 +00:00
Added shift-break as a better way to boot suitable disks. Continued attempting to clean the 1770.
This commit is contained in:
@@ -16,7 +16,8 @@ WD1770::WD1770() :
|
|||||||
status_(0),
|
status_(0),
|
||||||
interesting_event_mask_(Event::Command),
|
interesting_event_mask_(Event::Command),
|
||||||
resume_point_(0),
|
resume_point_(0),
|
||||||
delay_time_(0)
|
delay_time_(0),
|
||||||
|
index_hole_count_target_(-1)
|
||||||
{
|
{
|
||||||
set_is_double_density(false);
|
set_is_double_density(false);
|
||||||
posit_event(Event::Command);
|
posit_event(Event::Command);
|
||||||
@@ -136,9 +137,14 @@ void WD1770::process_index_hole()
|
|||||||
{
|
{
|
||||||
index_hole_count_++;
|
index_hole_count_++;
|
||||||
posit_event(Event::IndexHole);
|
posit_event(Event::IndexHole);
|
||||||
|
if(index_hole_count_target_ == index_hole_count_)
|
||||||
|
{
|
||||||
|
posit_event(Event::IndexHoleTarget);
|
||||||
|
index_hole_count_target_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// motor power-down
|
// motor power-down
|
||||||
// if(index_hole_count_ == 9 && !(status_&Flag::Busy)) status_ &= ~Flag::MotorOn;
|
if(index_hole_count_ == 9 && !(status_&Flag::Busy)) status_ &= ~Flag::MotorOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// +------+----------+-------------------------+
|
// +------+----------+-------------------------+
|
||||||
@@ -174,6 +180,16 @@ void WD1770::process_index_hole()
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CONCATENATE(x, y) x ## y
|
||||||
|
#define INDIRECT_CONCATENATE(x, y) TOKENPASTE(x, y)
|
||||||
|
#define LINE_LABEL INDIRECT_CONCATENATE(label, __LINE__)
|
||||||
|
|
||||||
|
#define SPIN_UP() \
|
||||||
|
status_ |= Flag::MotorOn; \
|
||||||
|
index_hole_count_ = 0; \
|
||||||
|
index_hole_count_target_ = 6; \
|
||||||
|
WAIT_FOR_EVENT(Event::IndexHoleTarget);
|
||||||
|
|
||||||
void WD1770::posit_event(Event new_event_type)
|
void WD1770::posit_event(Event new_event_type)
|
||||||
{
|
{
|
||||||
if(!(interesting_event_mask_ & (int)new_event_type)) return;
|
if(!(interesting_event_mask_ & (int)new_event_type)) return;
|
||||||
@@ -204,13 +220,7 @@ void WD1770::posit_event(Event new_event_type)
|
|||||||
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type1_type;
|
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type1_type;
|
||||||
|
|
||||||
// Perform spin up.
|
// Perform spin up.
|
||||||
status_ |= Flag::MotorOn;
|
SPIN_UP();
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
status_ |= Flag::SpinUp;
|
status_ |= Flag::SpinUp;
|
||||||
|
|
||||||
test_type1_type:
|
test_type1_type:
|
||||||
@@ -301,13 +311,7 @@ void WD1770::posit_event(Event new_event_type)
|
|||||||
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type2_delay;
|
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type2_delay;
|
||||||
|
|
||||||
// Perform spin up.
|
// Perform spin up.
|
||||||
status_ |= Flag::MotorOn;
|
SPIN_UP();
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
WAIT_FOR_EVENT(Event::IndexHole);
|
|
||||||
|
|
||||||
test_type2_delay:
|
test_type2_delay:
|
||||||
index_hole_count_ = 0;
|
index_hole_count_ = 0;
|
||||||
|
@@ -46,6 +46,7 @@ class WD1770: public Storage::Disk::Drive {
|
|||||||
uint8_t command_;
|
uint8_t command_;
|
||||||
|
|
||||||
int index_hole_count_;
|
int index_hole_count_;
|
||||||
|
int index_hole_count_target_;
|
||||||
int bits_since_token_;
|
int bits_since_token_;
|
||||||
int distance_into_section_;
|
int distance_into_section_;
|
||||||
|
|
||||||
@@ -64,10 +65,12 @@ class WD1770: public Storage::Disk::Drive {
|
|||||||
|
|
||||||
// Events
|
// Events
|
||||||
enum Event: int {
|
enum Event: int {
|
||||||
Command = (1 << 0),
|
Command = (1 << 0), // Indicates receipt of a new command.
|
||||||
Token = (1 << 1),
|
Token = (1 << 1), // Indicates recognition of a new token in the flux stream. Interrogate latest_token_ for details.
|
||||||
IndexHole = (1 << 2),
|
IndexHole = (1 << 2), // Indicates the passing of a physical index hole.
|
||||||
Timer = (1 << 3)
|
|
||||||
|
Timer = (1 << 3), // Indicates that the delay_time_-powered timer has timed out.
|
||||||
|
IndexHoleTarget = (1 << 4) // Indicates that index_hole_count_ has reached index_hole_count_target_.
|
||||||
};
|
};
|
||||||
void posit_event(Event type);
|
void posit_event(Event type);
|
||||||
int interesting_event_mask_;
|
int interesting_event_mask_;
|
||||||
|
@@ -304,6 +304,11 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
|
|||||||
case 0xfc04: case 0xfc05: case 0xfc06: case 0xfc07:
|
case 0xfc04: case 0xfc05: case 0xfc06: case 0xfc07:
|
||||||
if(_wd1770 && (address&0x00f0) == 0x00c0)
|
if(_wd1770 && (address&0x00f0) == 0x00c0)
|
||||||
{
|
{
|
||||||
|
if(is_holding_shift_)
|
||||||
|
{
|
||||||
|
is_holding_shift_ = false;
|
||||||
|
set_key_state(KeyShift, false);
|
||||||
|
}
|
||||||
if(isReadOperation(operation))
|
if(isReadOperation(operation))
|
||||||
*value = _wd1770->get_register(address);
|
*value = _wd1770->get_register(address);
|
||||||
else
|
else
|
||||||
@@ -516,6 +521,11 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target)
|
|||||||
{
|
{
|
||||||
set_typer_for_string(target.loadingCommand.c_str());
|
set_typer_for_string(target.loadingCommand.c_str());
|
||||||
}
|
}
|
||||||
|
if(target.acorn.should_hold_shift)
|
||||||
|
{
|
||||||
|
set_key_state(KeyShift, true);
|
||||||
|
is_holding_shift_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Machine::set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable)
|
void Machine::set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable)
|
||||||
|
@@ -233,6 +233,7 @@ class Machine:
|
|||||||
|
|
||||||
// Disk
|
// Disk
|
||||||
std::unique_ptr<WD::WD1770> _wd1770;
|
std::unique_ptr<WD::WD1770> _wd1770;
|
||||||
|
bool is_holding_shift_;
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
std::shared_ptr<Outputs::CRT::CRT> _crt;
|
std::shared_ptr<Outputs::CRT::CRT> _crt;
|
||||||
|
@@ -16,7 +16,7 @@ using namespace StaticAnalyser::Acorn;
|
|||||||
|
|
||||||
class FMParser: public Storage::Disk::Drive {
|
class FMParser: public Storage::Disk::Drive {
|
||||||
public:
|
public:
|
||||||
FMParser() :
|
FMParser(bool is_mfm) :
|
||||||
Storage::Disk::Drive(4000000, 1, 300),
|
Storage::Disk::Drive(4000000, 1, 300),
|
||||||
crc_generator_(0x1021, 0xffff),
|
crc_generator_(0x1021, 0xffff),
|
||||||
shift_register_(0), track_(0)
|
shift_register_(0), track_(0)
|
||||||
@@ -26,7 +26,7 @@ class FMParser: public Storage::Disk::Drive {
|
|||||||
|
|
||||||
Storage::Time bit_length;
|
Storage::Time bit_length;
|
||||||
bit_length.length = 1;
|
bit_length.length = 1;
|
||||||
bit_length.clock_rate = 250000; // i.e. 250 kbps (including clocks)
|
bit_length.clock_rate = is_mfm ? 500000 : 250000; // i.e. 250 kbps (including clocks)
|
||||||
set_expected_bit_length(bit_length);
|
set_expected_bit_length(bit_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
|
|||||||
{
|
{
|
||||||
// c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format
|
// c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format
|
||||||
std::unique_ptr<Catalogue> catalogue(new Catalogue);
|
std::unique_ptr<Catalogue> catalogue(new Catalogue);
|
||||||
FMParser parser;
|
FMParser parser(false);
|
||||||
parser.set_disk(disk);
|
parser.set_disk(disk);
|
||||||
|
|
||||||
std::shared_ptr<Storage::Encodings::MFM::Sector> names = parser.get_sector(0, 0);
|
std::shared_ptr<Storage::Encodings::MFM::Sector> names = parser.get_sector(0, 0);
|
||||||
@@ -218,3 +218,13 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
|
|||||||
|
|
||||||
return catalogue;
|
return catalogue;
|
||||||
}
|
}
|
||||||
|
std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetADFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk)
|
||||||
|
{
|
||||||
|
std::unique_ptr<Catalogue> catalogue(new Catalogue);
|
||||||
|
FMParser parser(true);
|
||||||
|
parser.set_disk(disk);
|
||||||
|
|
||||||
|
std::shared_ptr<Storage::Encodings::MFM::Sector> directory = parser.get_sector(0, 2);
|
||||||
|
|
||||||
|
return catalogue;
|
||||||
|
}
|
||||||
|
@@ -116,22 +116,17 @@ void StaticAnalyser::Acorn::AddTargets(
|
|||||||
if(disks.size() > 0)
|
if(disks.size() > 0)
|
||||||
{
|
{
|
||||||
std::shared_ptr<Storage::Disk::Disk> disk = disks.front();
|
std::shared_ptr<Storage::Disk::Disk> disk = disks.front();
|
||||||
std::unique_ptr<Catalogue> dfs_catalogue = GetDFSCatalogue(disk);
|
std::unique_ptr<Catalogue> catalogue = GetDFSCatalogue(disk);
|
||||||
if(dfs_catalogue)
|
if(catalogue == nullptr) catalogue = GetADFSCatalogue(disk);
|
||||||
|
if(catalogue)
|
||||||
{
|
{
|
||||||
target.disks = disks;
|
target.disks = disks;
|
||||||
target.acorn.has_dfs = true;
|
target.acorn.has_dfs = true;
|
||||||
|
|
||||||
// TODO: can't I just press shift?
|
switch(catalogue->bootOption)
|
||||||
switch(dfs_catalogue->bootOption)
|
|
||||||
{
|
{
|
||||||
default: target.loadingCommand = "*CAT\n"; break;
|
case Catalogue::BootOption::None: target.loadingCommand = "*CAT\n"; break;
|
||||||
case Catalogue::BootOption::LoadBOOT:
|
default: target.acorn.should_hold_shift = true; break;
|
||||||
target.loadingCommand = "*LOAD !BOOT\n"; break;
|
|
||||||
case Catalogue::BootOption::RunBOOT:
|
|
||||||
target.loadingCommand = "*RUN !BOOT\n"; break;
|
|
||||||
case Catalogue::BootOption::ExecBOOT:
|
|
||||||
target.loadingCommand = "*EXEC !BOOT\n"; break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,6 +46,7 @@ struct Target {
|
|||||||
struct {
|
struct {
|
||||||
bool has_adfs;
|
bool has_adfs;
|
||||||
bool has_dfs;
|
bool has_dfs;
|
||||||
|
bool should_hold_shift;
|
||||||
} acorn;
|
} acorn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user