Moved seek timing calculation to a separate method
Improved CD-ROM save/restore support TODO: variable seek latency for hard disk
This commit is contained in:
parent
b572e80818
commit
12ce16285c
@ -394,7 +394,7 @@ void bx_hard_drive_c::init(void)
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
|
||||
Bit32u capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.max_lba = capacity - 1;
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.next_lba = capacity - 1;
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.curr_lba = capacity - 1;
|
||||
BX_INFO(("Capacity is %d sectors (%.2f MB)", capacity, (float)capacity / 512.0));
|
||||
} else {
|
||||
BX_INFO(("Could not locate CD-ROM, continuing with media not present"));
|
||||
@ -572,7 +572,7 @@ void bx_hard_drive_c::register_state(void)
|
||||
{
|
||||
unsigned i, j;
|
||||
char cname[4], dname[8];
|
||||
bx_list_c *chan, *drive, *status;
|
||||
bx_list_c *cdrom, *chan, *drive, *status;
|
||||
|
||||
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "hard_drive", "Hard Drive State");
|
||||
for (i=0; i<BX_MAX_ATA_CHANNEL; i++) {
|
||||
@ -585,6 +585,13 @@ void bx_hard_drive_c::register_state(void)
|
||||
if (channels[i].drives[j].hdimage != NULL) {
|
||||
channels[i].drives[j].hdimage->register_state(drive);
|
||||
}
|
||||
if (BX_DRIVE_IS_CD(i, j)) {
|
||||
cdrom = new bx_list_c(drive, "cdrom");
|
||||
new bx_shadow_bool_c(cdrom, "locked", &BX_HD_THIS channels[i].drives[j].cdrom.locked);
|
||||
new bx_shadow_num_c(cdrom, "curr_lba", &BX_HD_THIS channels[i].drives[j].cdrom.curr_lba);
|
||||
new bx_shadow_num_c(cdrom, "next_lba", &BX_HD_THIS channels[i].drives[j].cdrom.next_lba);
|
||||
new bx_shadow_num_c(cdrom, "remaining_blocks", &BX_HD_THIS channels[i].drives[j].cdrom.remaining_blocks);
|
||||
}
|
||||
new bx_shadow_data_c(drive, "buffer", BX_CONTROLLER(i, j).buffer, MAX_MULTIPLE_SECTORS * 512);
|
||||
status = new bx_list_c(drive, "status");
|
||||
new bx_shadow_bool_c(status, "busy", &BX_CONTROLLER(i, j).status.busy);
|
||||
@ -620,7 +627,6 @@ void bx_hard_drive_c::register_state(void)
|
||||
new bx_shadow_num_c(drive, "hob_lcyl", &BX_CONTROLLER(i, j).hob.lcyl, BASE_HEX);
|
||||
new bx_shadow_num_c(drive, "hob_hcyl", &BX_CONTROLLER(i, j).hob.hcyl, BASE_HEX);
|
||||
new bx_shadow_num_c(drive, "num_sectors", &BX_CONTROLLER(i, j).num_sectors, BASE_HEX);
|
||||
new bx_shadow_bool_c(drive, "cdrom_locked", &BX_HD_THIS channels[i].drives[j].cdrom.locked);
|
||||
}
|
||||
}
|
||||
new bx_shadow_num_c(chan, "drive_select", &BX_HD_THIS channels[i].drive_select);
|
||||
@ -914,6 +920,7 @@ Bit32u bx_hard_drive_c::read(Bit32u address, unsigned io_len)
|
||||
BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
|
||||
|
||||
if (!BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks) {
|
||||
BX_SELECTED_DRIVE(channel).cdrom.curr_lba = BX_SELECTED_DRIVE(channel).cdrom.next_lba;
|
||||
BX_DEBUG(("CDROM: last READ block loaded"));
|
||||
} else {
|
||||
BX_DEBUG(("CDROM: READ block loaded (%d remaining)",
|
||||
@ -1601,12 +1608,8 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
transfer_length * controller->buffer_size,
|
||||
transfer_length * controller->buffer_size, 1);
|
||||
BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
|
||||
Bit32u last_lba = BX_SELECTED_DRIVE(channel).cdrom.next_lba;
|
||||
Bit32u max_lba = BX_SELECTED_DRIVE(channel).cdrom.max_lba;
|
||||
float seek_time = 80000.0 * (float)abs(lba - last_lba + 1) / (max_lba + 1);
|
||||
BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
|
||||
bx_pc_system.activate_timer(
|
||||
BX_SELECTED_DRIVE(channel).seek_timer_index, (Bit32u)seek_time, 0);
|
||||
start_seek(channel);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1726,12 +1729,8 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
init_send_atapi_command(channel, atapi_command, transfer_length * 2048,
|
||||
transfer_length * 2048, 1);
|
||||
BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
|
||||
Bit32u last_lba = BX_SELECTED_DRIVE(channel).cdrom.next_lba;
|
||||
Bit32u max_lba = BX_SELECTED_DRIVE(channel).cdrom.max_lba;
|
||||
float seek_time = 80000.0 * (float)abs(lba - last_lba + 1) / (max_lba + 1);
|
||||
BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
|
||||
bx_pc_system.activate_timer(
|
||||
BX_SELECTED_DRIVE(channel).seek_timer_index, (Bit32u)seek_time, 0);
|
||||
start_seek(channel);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1999,8 +1998,7 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
controller->status.drq = 0;
|
||||
controller->status.corrected_data = 0;
|
||||
controller->buffer_index = 0;
|
||||
bx_pc_system.activate_timer(
|
||||
BX_SELECTED_DRIVE(channel).seek_timer_index, 5000, 0);
|
||||
start_seek(channel);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2379,9 +2377,7 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
controller->status.seek_complete = 0;
|
||||
controller->status.drq = 0;
|
||||
controller->status.corrected_data = 0;
|
||||
bx_pc_system.activate_timer(
|
||||
BX_SELECTED_DRIVE(channel).seek_timer_index, 5000, 0);
|
||||
|
||||
start_seek(channel);
|
||||
DEV_ide_bmdma_start_transfer(channel);
|
||||
} else {
|
||||
BX_ERROR(("write cmd 0x%02x (READ DMA) not supported", value));
|
||||
@ -3226,7 +3222,7 @@ bx_bool bx_hard_drive_c::set_cd_media_status(Bit32u handle, bx_bool status)
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
|
||||
Bit32u capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.max_lba = capacity - 1;
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.next_lba = capacity - 1;
|
||||
BX_HD_THIS channels[channel].drives[device].cdrom.curr_lba = capacity - 1;
|
||||
BX_INFO(("Capacity is %d sectors (%.2f MB)", capacity, (float)capacity / 512.0));
|
||||
SIM->get_param_enum("status", base)->set(BX_INSERTED);
|
||||
BX_SELECTED_DRIVE(channel).sense.sense_key = SENSE_UNIT_ATTENTION;
|
||||
@ -3284,6 +3280,9 @@ bx_bool bx_hard_drive_c::bmdma_read_sector(Bit8u channel, Bit8u *buffer, Bit32u
|
||||
}
|
||||
BX_SELECTED_DRIVE(channel).cdrom.next_lba++;
|
||||
BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
|
||||
if (!BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks) {
|
||||
BX_SELECTED_DRIVE(channel).cdrom.curr_lba = BX_SELECTED_DRIVE(channel).cdrom.next_lba;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
memcpy(buffer, controller->buffer, *sector_size);
|
||||
@ -3445,6 +3444,25 @@ void bx_hard_drive_c::lba48_transform(controller_t *controller, bx_bool lba48)
|
||||
}
|
||||
}
|
||||
|
||||
void bx_hard_drive_c::start_seek(Bit8u channel)
|
||||
{
|
||||
float fSeekTime;
|
||||
Bit32u seek_time, new_pos, prev_pos, max_pos;
|
||||
|
||||
if (BX_SELECTED_IS_CD(channel)) {
|
||||
max_pos = BX_SELECTED_DRIVE(channel).cdrom.max_lba;
|
||||
prev_pos = BX_SELECTED_DRIVE(channel).cdrom.curr_lba;
|
||||
new_pos = BX_SELECTED_DRIVE(channel).cdrom.next_lba;
|
||||
fSeekTime = 80000.0 * (float)abs(new_pos - prev_pos + 1) / (max_pos + 1);
|
||||
} else {
|
||||
// TODO: make HD seek latency variable
|
||||
fSeekTime = 5000.0;
|
||||
}
|
||||
seek_time = (fSeekTime > 10.0) ? (Bit32u)fSeekTime : 10;
|
||||
bx_pc_system.activate_timer(
|
||||
BX_SELECTED_DRIVE(channel).seek_timer_index, seek_time, 0);
|
||||
}
|
||||
|
||||
error_recovery_t::error_recovery_t()
|
||||
{
|
||||
if (sizeof(error_recovery_t) != 8) {
|
||||
|
@ -134,6 +134,7 @@ struct cdrom_t
|
||||
bx_bool locked;
|
||||
cdrom_base_c *cd;
|
||||
Bit32u max_lba;
|
||||
Bit32u curr_lba;
|
||||
Bit32u next_lba;
|
||||
int remaining_blocks;
|
||||
struct currentStruct {
|
||||
@ -220,6 +221,7 @@ private:
|
||||
BX_HD_SMF bx_bool ide_read_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size);
|
||||
BX_HD_SMF bx_bool ide_write_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size);
|
||||
BX_HD_SMF void lba48_transform(controller_t *controller, bx_bool lba48);
|
||||
BX_HD_SMF void start_seek(Bit8u channel);
|
||||
|
||||
static Bit64s cdrom_status_handler(bx_param_c *param, int set, Bit64s val);
|
||||
static const char* cdrom_path_handler(bx_param_string_c *param, int set,
|
||||
|
Loading…
Reference in New Issue
Block a user