1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Adds command termination upon drive becoming unready, and copies head and drive selection into ST0.

This commit is contained in:
Thomas Harte 2017-09-15 20:26:41 -04:00
parent b835cb73e2
commit 35fe4d50d4
2 changed files with 21 additions and 5 deletions

View File

@ -26,7 +26,7 @@ using namespace Intel::i8272;
#define SetBusy() (main_status_ |= 0x10)
#define ResetBusy() (main_status_ &= ~0x10)
#define Busy() (main_status_ & 0x10)
#define IsBusy() (main_status_ & 0x10)
#define SetAbnormalTermination() (status_[0] |= 0x40)
#define SetInvalidCommand() (status_[0] |= 0x80)
@ -34,6 +34,7 @@ using namespace Intel::i8272;
#define SetSeekEnd() (status_[0] |= 0x20)
#define SetEquipmentCheck() (status_[0] |= 0x10)
#define SetNotReady() (status_[0] |= 0x08)
#define SetSide2() (status_[0] |= 0x04)
#define SetEndOfCylinder() (status_[1] |= 0x80)
#define SetDataError() (status_[1] |= 0x20)
@ -158,6 +159,11 @@ void i8272::run_for(Cycles cycles) {
}
}
// check for busy plus ready disabled
if(is_executing_ && !get_drive().get_is_ready()) {
posit_event((int)Event8272::NoLongerReady);
}
is_sleeping_ = !delay_time_ && !drives_seeking_ && !head_timers_running_;
if(is_sleeping_) update_sleep_observer();
}
@ -230,6 +236,7 @@ uint8_t i8272::get_register(int address) {
#define SET_DRIVE_HEAD_MFM() \
active_drive_ = command_[1]&3; \
active_head_ = (command_[1] >> 2)&1; \
status_[0] = (command_[1]&7); \
select_drive(active_drive_); \
get_drive().set_head((unsigned int)active_head_); \
set_is_double_density(command_[0] & 0x40);
@ -263,6 +270,10 @@ uint8_t i8272::get_register(int address) {
void i8272::posit_event(int event_type) {
if(event_type == (int)Event::IndexHole) index_hole_count_++;
if(event_type == (int)Event8272::NoLongerReady) {
SetNotReady();
goto abort;
}
if(!(interesting_event_mask_ & event_type)) return;
interesting_event_mask_ &= ~event_type;
@ -332,6 +343,7 @@ void i8272::posit_event(int event_type) {
}
// Establishes the drive and head being addressed, and whether in double density mode; populates the internal
// cylinder, head, sector and size registers from the command stream.
is_executing_ = true;
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
LOAD_HEAD();
@ -811,6 +823,7 @@ void i8272::posit_event(int event_type) {
// Sets abnormal termination of the current command and proceeds to an ST0, ST1, ST2, C, H, R, N result phase.
abort:
end_writing();
SetAbnormalTermination();
goto post_st012chrn;
@ -839,6 +852,7 @@ void i8272::posit_event(int event_type) {
printf("\n");
// Set ready to send data to the processor, no longer in non-DMA execution phase.
is_executing_ = false;
ResetNonDMAExecution();
SetDataRequest();
SetDataDirectionToProcessor();

View File

@ -65,6 +65,7 @@ class i8272: public Storage::Disk::MFMController {
CommandByte = (1 << 3),
Timer = (1 << 4),
ResultEmpty = (1 << 5),
NoLongerReady = (1 << 6)
};
void posit_event(int type);
int interesting_event_mask_;
@ -107,10 +108,11 @@ class i8272: public Storage::Disk::MFMController {
bool seek_is_satisfied(int drive);
// User-supplied parameters; as per the specify command.
int step_rate_time_;
int head_unload_time_;
int head_load_time_;
bool dma_mode_;
int step_rate_time_ = 1;
int head_unload_time_ = 1;
int head_load_time_ = 1;
bool dma_mode_ = false;
bool is_executing_ = false;
// A count of head unload timers currently running.
int head_timers_running_;