Fixed SCSI/ATAPI hard disk timings and IDE hard disk recalibrate command timing.
This commit is contained in:
@@ -1515,8 +1515,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
ide->sc->callback = 100.0 * IDE_TIME;
|
||||
ide_set_callback(ide, 100.0 * IDE_TIME);
|
||||
} else {
|
||||
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num],
|
||||
ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0);
|
||||
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ?
|
||||
ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0);
|
||||
ide_set_callback(ide, seek_time);
|
||||
}
|
||||
break;
|
||||
@@ -2062,8 +2062,6 @@ ide_callback(void *priv)
|
||||
switch (ide->command) {
|
||||
case WIN_SEEK ... 0x7F:
|
||||
chk_chs = !ide->lba;
|
||||
fallthrough;
|
||||
case WIN_RECAL ... 0x1F:
|
||||
if (ide->type == IDE_ATAPI)
|
||||
atapi_error_no_ready(ide);
|
||||
else {
|
||||
@@ -2077,6 +2075,15 @@ ide_callback(void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case WIN_RECAL ... 0x1F:
|
||||
if (ide->type == IDE_ATAPI)
|
||||
atapi_error_no_ready(ide);
|
||||
else {
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Initialize the Task File Registers as follows:
|
||||
Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h,
|
||||
Cylinder Low = 14h, Cylinder High = EBh and Drive/Head = 00h. */
|
||||
|
@@ -448,4 +448,7 @@ extern void scsi_device_init(void);
|
||||
extern void scsi_reset(void);
|
||||
extern uint8_t scsi_get_bus(void);
|
||||
|
||||
extern void scsi_bus_set_speed(uint8_t bus, double speed);
|
||||
extern double scsi_bus_get_speed(uint8_t bus);
|
||||
|
||||
#endif /*SCSI_DEVICE_H*/
|
||||
|
@@ -42,7 +42,8 @@
|
||||
#include <86box/scsi_pcscsi.h>
|
||||
#include <86box/scsi_spock.h>
|
||||
|
||||
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 };
|
||||
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0, 0, 0 };
|
||||
double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 };
|
||||
|
||||
static uint8_t next_scsi_bus = 0;
|
||||
|
||||
@@ -183,3 +184,15 @@ scsi_card_init(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scsi_bus_set_speed(uint8_t bus, double speed)
|
||||
{
|
||||
scsi_bus_speed[bus] = speed;
|
||||
}
|
||||
|
||||
double
|
||||
scsi_bus_get_speed(uint8_t bus)
|
||||
{
|
||||
return scsi_bus_speed[bus];
|
||||
}
|
||||
|
@@ -1101,6 +1101,8 @@ aha_init(const device_t *info)
|
||||
break;
|
||||
}
|
||||
|
||||
scsi_bus_set_speed(dev->bus, dev->ha_bps);
|
||||
|
||||
/* Initialize ROM BIOS if needed. */
|
||||
aha_setbios(dev);
|
||||
|
||||
|
@@ -1706,9 +1706,10 @@ buslogic_init(const device_t *info)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) {
|
||||
scsi_bus_set_speed(dev->bus, dev->ha_bps);
|
||||
|
||||
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI))
|
||||
x54x_io_set(dev, dev->Base, 4);
|
||||
}
|
||||
|
||||
memset(bl->AutoSCSIROM, 0xff, 32768);
|
||||
|
||||
|
@@ -12,11 +12,13 @@
|
||||
*
|
||||
* Copyright 2017-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
@@ -433,8 +435,6 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
dev->tf->pos = 0;
|
||||
dev->callback = 0;
|
||||
|
||||
scsi_disk_log("SCSI HD %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed);
|
||||
|
||||
if (dev->packet_status == PHASE_COMPLETE) {
|
||||
switch (dev->current_cdb[0]) {
|
||||
case GPCMD_VERIFY_6:
|
||||
@@ -447,12 +447,12 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
case GPCMD_WRITE_AND_VERIFY_12:
|
||||
case GPCMD_WRITE_SAME_10:
|
||||
/* Seek time is in us. */
|
||||
period = hdd_timing_write(dev->drv, dev->sector_pos, 1);
|
||||
period = hdd_timing_write(dev->drv, dev->sector_pos, dev->packet_len >> 9);
|
||||
scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n",
|
||||
dev->id, (uint64_t) period);
|
||||
dev->callback += period;
|
||||
/* Account for seek time. */
|
||||
bytes_per_second = scsi_disk_bus_speed(dev);
|
||||
bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4);
|
||||
|
||||
period = 1000000.0 / bytes_per_second;
|
||||
scsi_disk_log("SCSI HD %i: Byte transfer period: %" PRIu64 " us\n", dev->id,
|
||||
@@ -472,7 +472,8 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
case 0x0b:
|
||||
case 0x2b:
|
||||
/* Seek time is in us. */
|
||||
period = hdd_timing_write(dev->drv, dev->sector_pos, 1);
|
||||
period = hdd_seek_get_time(dev->drv, (dev->current_cdb[0] == GPCMD_REZERO_UNIT) ?
|
||||
0 : dev->sector_pos, HDD_OP_SEEK, 0, 0.0);
|
||||
scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n",
|
||||
dev->id, (uint64_t) period);
|
||||
dev->callback += period;
|
||||
@@ -482,15 +483,14 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
case 0x28:
|
||||
case 0xa8:
|
||||
/* Seek time is in us. */
|
||||
period = hdd_timing_write(dev->drv, dev->sector_pos, 1);
|
||||
period = hdd_timing_read(dev->drv, dev->sector_pos, dev->packet_len >> 9);
|
||||
scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n",
|
||||
dev->id, (uint64_t) period);
|
||||
dev->callback += period;
|
||||
fallthrough;
|
||||
case 0x25:
|
||||
/* Account for seek time. */
|
||||
bytes_per_second = scsi_disk_bus_speed(dev);
|
||||
bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4);
|
||||
break;
|
||||
case 0x25:
|
||||
default:
|
||||
bytes_per_second = scsi_disk_bus_speed(dev);
|
||||
if (bytes_per_second == 0.0) {
|
||||
@@ -1684,6 +1684,8 @@ scsi_disk_hard_reset(void)
|
||||
|
||||
valid = 1;
|
||||
|
||||
hdd_preset_apply(c);
|
||||
|
||||
if (!hdd[c].priv)
|
||||
hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t));
|
||||
|
||||
@@ -1710,17 +1712,19 @@ scsi_disk_hard_reset(void)
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any SCSI disk whose image fails to load. */
|
||||
if (!hdd_image_load(c))
|
||||
continue;
|
||||
|
||||
/* ATAPI hard disk, attach to the IDE bus. */
|
||||
id = ide_get_drive(hdd[c].ide_channel);
|
||||
/* If the IDE channel is initialized, we attach to it,
|
||||
otherwise, we do nothing - it's going to be a drive
|
||||
that's not attached to anything. */
|
||||
if (id) {
|
||||
if (!hdd_image_load(c))
|
||||
continue;
|
||||
|
||||
valid = 1;
|
||||
|
||||
hdd_preset_apply(c);
|
||||
|
||||
if (!hdd[c].priv)
|
||||
hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t));
|
||||
|
||||
|
@@ -1658,6 +1658,8 @@ ncr_init(const device_t *info)
|
||||
}
|
||||
timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0);
|
||||
|
||||
scsi_bus_set_speed(ncr_dev->bus, 5000000.0);
|
||||
|
||||
return ncr_dev;
|
||||
}
|
||||
|
||||
|
@@ -2623,6 +2623,8 @@ ncr53c8xx_init(const device_t *info)
|
||||
|
||||
timer_add(&dev->timer, ncr53c8xx_callback, dev, 0);
|
||||
|
||||
scsi_bus_set_speed(dev->bus, 10000000.0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
@@ -1870,6 +1870,8 @@ dc390_init(UNUSED(const device_t *info))
|
||||
|
||||
timer_add(&dev->timer, esp_callback, dev, 0);
|
||||
|
||||
scsi_bus_set_speed(dev->bus, 10000000.0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -2040,6 +2042,8 @@ ncr53c90_mca_init(UNUSED(const device_t *info))
|
||||
|
||||
timer_add(&dev->timer, esp_callback, dev, 0);
|
||||
|
||||
scsi_bus_set_speed(dev->bus, 5000000.0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
@@ -1164,15 +1164,18 @@ spock_init(const device_t *info)
|
||||
scsi->cmd_timer = SPOCK_TIME * 50;
|
||||
scsi->status = STATUS_BUSY;
|
||||
|
||||
for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++) {
|
||||
for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++)
|
||||
scsi->dev_id[c].phys_id = -1;
|
||||
}
|
||||
|
||||
scsi->dev_id[SCSI_ID_MAX - 1].phys_id = scsi->adapter_id;
|
||||
|
||||
timer_add(&scsi->callback_timer, spock_callback, scsi, 1);
|
||||
scsi->callback_timer.period = 10.0;
|
||||
timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC)));
|
||||
|
||||
timer_set_delay_u64(&scsi->callback_timer,
|
||||
(uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC)));
|
||||
|
||||
scsi_bus_set_speed(scsi->bus, 5000000.0);
|
||||
|
||||
return scsi;
|
||||
}
|
||||
|
Reference in New Issue
Block a user