1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Centralised the 8272's actions of setting the non-DMA execution flag, picking the drive and head and loading the head for accessing commands, and switched error flag if read ID doesn't find anything.

This commit is contained in:
Thomas Harte 2017-08-15 21:49:10 -04:00
parent d12c834f9c
commit aefbafa18d
2 changed files with 29 additions and 28 deletions

View File

@ -293,23 +293,38 @@ void i8272::posit_event(int event_type) {
// If this is not clearly a command that's safe to carry out in parallel to a seek, end all seeks. // If this is not clearly a command that's safe to carry out in parallel to a seek, end all seeks.
switch(command_[0] & 0x1f) { switch(command_[0] & 0x1f) {
case CommandSpecify: case CommandReadData:
case CommandSenseDriveStatus: case CommandReadDeletedData:
case CommandSenseInterruptStatus: case CommandWriteData:
case CommandRecalibrate: case CommandWriteDeletedData:
case CommandSeek: case CommandReadTrack:
case CommandReadID:
case CommandFormatTrack:
case CommandScanLow:
case CommandScanLowOrEqual:
case CommandScanHighOrEqual:
is_access_command_ = true;
break; break;
default: default:
for(int c = 0; c < 4; c++) { is_access_command_ = false;
if(drives_[c].phase == Drive::Seeking) {
drives_[c].phase = Drive::NotSeeking;
drives_seeking_--;
}
}
break; break;
} }
if(is_access_command_) {
for(int c = 0; c < 4; c++) {
if(drives_[c].phase == Drive::Seeking) {
drives_[c].phase = Drive::NotSeeking;
drives_seeking_--;
}
}
// 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.
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
LOAD_HEAD();
}
// Jump to the proper place. // Jump to the proper place.
switch(command_[0] & 0x1f) { switch(command_[0] & 0x1f) {
case CommandReadData: case CommandReadData:
@ -342,9 +357,6 @@ void i8272::posit_event(int event_type) {
// and searches for a sector that meets those criteria. If one is found, inspects the instruction in use and // and searches for a sector that meets those criteria. If one is found, inspects the instruction in use and
// jumps to an appropriate handler. // jumps to an appropriate handler.
read_write_find_header: read_write_find_header:
// 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.
LOAD_HEAD();
// Sets a maximum index hole limit of 2 then performs a find header/read header loop, continuing either until // Sets a maximum index hole limit of 2 then performs a find header/read header loop, continuing either until
// the index hole limit is breached or a sector is found with a cylinder, head, sector and size equal to the // the index hole limit is breached or a sector is found with a cylinder, head, sector and size equal to the
@ -390,8 +402,6 @@ void i8272::posit_event(int event_type) {
// Performs the read data or read deleted data command. // Performs the read data or read deleted data command.
read_data: read_data:
printf("Read [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]); printf("Read [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]);
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
read_next_data: read_next_data:
goto read_write_find_header; goto read_write_find_header;
@ -475,8 +485,6 @@ void i8272::posit_event(int event_type) {
write_data: write_data:
printf("Write [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]); printf("Write [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]);
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
if(drives_[active_drive_].drive->get_is_read_only()) { if(drives_[active_drive_].drive->get_is_read_only()) {
SetNotWriteable(); SetNotWriteable();
@ -528,9 +536,7 @@ void i8272::posit_event(int event_type) {
// Performs the read ID command. // Performs the read ID command.
read_id: read_id:
// Establishes the drive and head being addressed, and whether in double density mode. // Establishes the drive and head being addressed, and whether in double density mode.
printf("Read ID\n"); printf("Read ID [%02x %02x]\n", command_[0], command_[1]);
SET_DRIVE_HEAD_MFM();
LOAD_HEAD();
// Sets a maximum index hole limit of 2 then waits either until it finds a header mark or sees too many index holes. // Sets a maximum index hole limit of 2 then waits either until it finds a header mark or sees too many index holes.
// If a header mark is found, reads in the following bytes that produce a header. Otherwise branches to data not found. // If a header mark is found, reads in the following bytes that produce a header. Otherwise branches to data not found.
@ -538,7 +544,7 @@ void i8272::posit_event(int event_type) {
read_id_find_next_sector: read_id_find_next_sector:
FIND_HEADER(); FIND_HEADER();
if(!index_hole_limit_) { if(!index_hole_limit_) {
SetNoData(); SetMissingAddressMark();
goto abort; goto abort;
} }
READ_HEADER(); READ_HEADER();
@ -554,8 +560,6 @@ void i8272::posit_event(int event_type) {
// Performs read track. // Performs read track.
read_track: read_track:
printf("Read track [%02x %02x %02x %02x]\n", command_[2], command_[3], command_[4], command_[5]); printf("Read track [%02x %02x %02x %02x]\n", command_[2], command_[3], command_[4], command_[5]);
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
// Wait for the index hole. // Wait for the index hole.
WAIT_FOR_EVENT(Event::IndexHole); WAIT_FOR_EVENT(Event::IndexHole);
@ -597,15 +601,11 @@ void i8272::posit_event(int event_type) {
// Performs format [/write] track. // Performs format [/write] track.
format_track: format_track:
printf("Format track\n"); printf("Format track\n");
if(!dma_mode_) SetNonDMAExecution();
SET_DRIVE_HEAD_MFM();
if(drives_[active_drive_].drive->get_is_read_only()) { if(drives_[active_drive_].drive->get_is_read_only()) {
SetNotWriteable(); SetNotWriteable();
goto abort; goto abort;
} }
LOAD_HEAD();
// Wait for the index hole. // Wait for the index hole.
WAIT_FOR_EVENT(Event::IndexHole); WAIT_FOR_EVENT(Event::IndexHole);
index_hole_count_ = 0; index_hole_count_ = 0;

View File

@ -66,6 +66,7 @@ class i8272: public Storage::Disk::MFMController {
void posit_event(int type); void posit_event(int type);
int interesting_event_mask_; int interesting_event_mask_;
int resume_point_; int resume_point_;
bool is_access_command_;
// The counter used for ::Timer events. // The counter used for ::Timer events.
int delay_time_; int delay_time_;