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