1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Added getters for the IRQ and DRQ lines plus a delegate to receive changes; adjusted code so that the two lines signal.

This commit is contained in:
Thomas Harte 2016-11-21 13:21:49 +08:00
parent 4ec042fad1
commit d4a1961378
2 changed files with 53 additions and 15 deletions

View File

@ -19,7 +19,10 @@ WD1770::WD1770() :
delay_time_(0), delay_time_(0),
index_hole_count_target_(-1), index_hole_count_target_(-1),
is_awaiting_marker_value_(false), is_awaiting_marker_value_(false),
is_reading_data_(false) is_reading_data_(false),
interrupt_request_line_(false),
data_request_line_(false),
delegate_(nullptr)
{ {
set_is_double_density(false); set_is_double_density(false);
posit_event(Event::Command); posit_event(Event::Command);
@ -55,10 +58,10 @@ uint8_t WD1770::get_register(int address)
{ {
switch(address&3) switch(address&3)
{ {
default: return status_; default: return status_ | (data_request_line_ ? Flag::DataRequest : 0);
case 1: return track_; case 1: return track_;
case 2: return sector_; case 2: return sector_;
case 3: status_ &= ~Flag::DataRequest; return data_; case 3: set_data_request(false); return data_;
} }
} }
@ -220,7 +223,7 @@ void WD1770::process_index_hole()
if(!distance_into_section_ && latest_token_.type == Token::ID) {is_reading_data_ = true; distance_into_section_++; } \ if(!distance_into_section_ && latest_token_.type == Token::ID) {is_reading_data_ = true; distance_into_section_++; } \
else if(distance_into_section_ && distance_into_section_ < 7 && latest_token_.type == Token::Byte) \ else if(distance_into_section_ && distance_into_section_ < 7 && latest_token_.type == Token::Byte) \
{ \ { \
header[distance_into_section_ - 1] = latest_token_.byte_value; \ header_[distance_into_section_ - 1] = latest_token_.byte_value; \
distance_into_section_++; \ distance_into_section_++; \
} \ } \
} }
@ -262,8 +265,9 @@ void WD1770::posit_event(Event new_event_type)
*/ */
begin_type_1: begin_type_1:
// Set initial flags, skip spin-up if possible. // Set initial flags, skip spin-up if possible.
status_ &= ~(Flag::DataRequest | Flag::DataRequest | Flag::SeekError); status_ &= ~Flag::SeekError;
set_interrupt_request(false); set_interrupt_request(false);
set_data_request(false);
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.
@ -338,7 +342,7 @@ void WD1770::posit_event(Event new_event_type)
{ {
is_reading_data_ = false; is_reading_data_ = false;
// TODO: CRC check // TODO: CRC check
if(header[0] == track_) if(header_[0] == track_)
{ {
printf("Reached track %d\n", track_); printf("Reached track %d\n", track_);
status_ &= ~Flag::CRCError; status_ &= ~Flag::CRCError;
@ -355,8 +359,9 @@ void WD1770::posit_event(Event new_event_type)
Type 2 entry point. Type 2 entry point.
*/ */
begin_type_2: begin_type_2:
status_ &= ~(Flag::DataRequest | Flag::LostData | Flag::RecordNotFound | Flag::WriteProtect | Flag::RecordType); status_ &= ~(Flag::LostData | Flag::RecordNotFound | Flag::WriteProtect | Flag::RecordType);
set_interrupt_request(false); set_interrupt_request(false);
set_data_request(false);
distance_into_section_ = 0; distance_into_section_ = 0;
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type2_delay; if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type2_delay;
@ -389,7 +394,7 @@ void WD1770::posit_event(Event new_event_type)
if(distance_into_section_ == 7) if(distance_into_section_ == 7)
{ {
is_reading_data_ = false; is_reading_data_ = false;
if(header[0] == track_ && header[2] == sector_) if(header_[0] == track_ && header_[2] == sector_)
{ {
// TODO: test CRC // TODO: test CRC
goto type2_read_or_write_data; goto type2_read_or_write_data;
@ -418,11 +423,11 @@ void WD1770::posit_event(Event new_event_type)
type2_read_byte: type2_read_byte:
WAIT_FOR_EVENT(Event::Token); WAIT_FOR_EVENT(Event::Token);
if(latest_token_.type != Token::Byte) goto type2_read_byte; if(latest_token_.type != Token::Byte) goto type2_read_byte;
if(status_ & Flag::DataRequest) status_ |= Flag::LostData; if(data_request_line_) status_ |= Flag::LostData;
data_ = latest_token_.byte_value; data_ = latest_token_.byte_value;
status_ |= Flag::DataRequest; set_data_request(true);
distance_into_section_++; distance_into_section_++;
if(distance_into_section_ == 128 << header[3]) if(distance_into_section_ == 128 << header_[3])
{ {
distance_into_section_ = 0; distance_into_section_ = 0;
goto type2_check_crc; goto type2_check_crc;
@ -432,7 +437,7 @@ void WD1770::posit_event(Event new_event_type)
type2_check_crc: type2_check_crc:
WAIT_FOR_EVENT(Event::Token); WAIT_FOR_EVENT(Event::Token);
if(latest_token_.type != Token::Byte) goto type2_read_byte; if(latest_token_.type != Token::Byte) goto type2_read_byte;
header[distance_into_section_] = latest_token_.byte_value; header_[distance_into_section_] = latest_token_.byte_value;
distance_into_section_++; distance_into_section_++;
if(distance_into_section_ == 2) if(distance_into_section_ == 2)
{ {
@ -458,3 +463,21 @@ void WD1770::posit_event(Event new_event_type)
END_SECTION() END_SECTION()
} }
void WD1770::set_interrupt_request(bool interrupt_request)
{
if(interrupt_request_line_ != interrupt_request)
{
interrupt_request_line_ = interrupt_request;
if(delegate_) delegate_->wd1770_did_change_interrupt_request_status(this);
}
}
void WD1770::set_data_request(bool data_request)
{
if(data_request_line_ != data_request)
{
data_request_line_ = data_request;
if(delegate_) delegate_->wd1770_did_change_data_request_status(this);
}
}

View File

@ -38,6 +38,15 @@ class WD1770: public Storage::Disk::Controller {
Busy = 0x01 Busy = 0x01
}; };
inline bool get_interrupt_request_line() { return interrupt_request_line_; }
inline bool get_data_request_line() { return data_request_line_; }
class Delegate {
public:
virtual void wd1770_did_change_interrupt_request_status(WD1770 *wd1770) = 0;
virtual void wd1770_did_change_data_request_status(WD1770 *wd1770) = 0;
};
inline void set_delegate(Delegate *delegate) { delegate_ = delegate; }
private: private:
uint8_t status_; uint8_t status_;
uint8_t track_; uint8_t track_;
@ -52,7 +61,8 @@ class WD1770: public Storage::Disk::Controller {
bool is_awaiting_marker_value_; bool is_awaiting_marker_value_;
int step_direction_; int step_direction_;
void set_interrupt_request(bool interrupt_request) {} void set_interrupt_request(bool interrupt_request);
void set_data_request(bool interrupt_request);
// Tokeniser // Tokeniser
bool is_reading_data_; bool is_reading_data_;
@ -80,9 +90,14 @@ class WD1770: public Storage::Disk::Controller {
int delay_time_; int delay_time_;
// ID buffer // ID buffer
uint8_t header[6]; uint8_t header_[6];
// // output line statuses
bool interrupt_request_line_;
bool data_request_line_;
Delegate *delegate_;
// Storage::Disk::Controller
virtual void process_input_bit(int value, unsigned int cycles_since_index_hole); virtual void process_input_bit(int value, unsigned int cycles_since_index_hole);
virtual void process_index_hole(); virtual void process_index_hole();
}; };