Fixed SCSI/ATAPI hard disk timings and IDE hard disk recalibrate command timing.

This commit is contained in:
OBattler
2023-10-30 04:48:29 +01:00
parent ad2c09d275
commit 40d724cf20
10 changed files with 64 additions and 23 deletions

View File

@@ -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. */

View File

@@ -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*/

View File

@@ -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];
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}