clang-format in src/disk/

This commit is contained in:
Jasmine Iwanek
2022-09-18 17:13:50 -04:00
parent 9a3cabbe85
commit 696f6f7e2f
17 changed files with 8516 additions and 8938 deletions

View File

@@ -29,33 +29,30 @@
#include <86box/hdc_ide.h>
#include <86box/hdd.h>
int hdc_current;
int hdc_current;
#ifdef ENABLE_HDC_LOG
int hdc_do_log = ENABLE_HDC_LOG;
static void
hdc_log(const char *fmt, ...)
{
va_list ap;
if (hdc_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define hdc_log(fmt, ...)
# define hdc_log(fmt, ...)
#endif
static void *
nullhdc_init(const device_t *info)
{
return(NULL);
return (NULL);
}
static void
@@ -66,7 +63,7 @@ nullhdc_close(void *priv)
static void *
inthdc_init(const device_t *info)
{
return(NULL);
return (NULL);
}
static void
@@ -75,37 +72,37 @@ inthdc_close(void *priv)
}
static const device_t hdc_none_device = {
.name = "None",
.name = "None",
.internal_name = "none",
.flags = 0,
.local = 0,
.init = nullhdc_init,
.close = nullhdc_close,
.reset = NULL,
.flags = 0,
.local = 0,
.init = nullhdc_init,
.close = nullhdc_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
static const device_t hdc_internal_device = {
.name = "Internal",
.name = "Internal",
.internal_name = "internal",
.flags = 0,
.local = 0,
.init = inthdc_init,
.close = inthdc_close,
.reset = NULL,
.flags = 0,
.local = 0,
.init = inthdc_init,
.close = inthdc_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
static const struct {
const device_t *device;
const device_t *device;
} controllers[] = {
// clang-format off
// clang-format off
{ &hdc_none_device },
{ &hdc_internal_device },
{ &st506_xt_xebec_device },
@@ -133,7 +130,7 @@ static const struct {
{ &ide_vlb_device },
{ &ide_vlb_2ch_device },
{ NULL }
// clang-format on
// clang-format on
};
/* Initialize the 'hdc_current' value based on configured HDC name. */
@@ -146,77 +143,72 @@ hdc_init(void)
hdd_image_init();
}
/* Reset the HDC, whichever one that is. */
void
hdc_reset(void)
{
hdc_log("HDC: reset(current=%d, internal=%d)\n",
hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
/* If we have a valid controller, add its device. */
if (hdc_current > 1)
device_add(controllers[hdc_current].device);
device_add(controllers[hdc_current].device);
/* Now, add the tertiary and/or quaternary IDE controllers. */
if (ide_ter_enabled)
device_add(&ide_ter_device);
device_add(&ide_ter_device);
if (ide_qua_enabled)
device_add(&ide_qua_device);
device_add(&ide_qua_device);
}
char *
hdc_get_internal_name(int hdc)
{
return device_get_internal_name(controllers[hdc].device);
}
int
hdc_get_from_internal_name(char *s)
{
int c = 0;
while (controllers[c].device != NULL) {
if (!strcmp((char *) controllers[c].device->internal_name, s))
return c;
c++;
if (!strcmp((char *) controllers[c].device->internal_name, s))
return c;
c++;
}
return 0;
}
const device_t *
hdc_get_device(int hdc)
{
return(controllers[hdc].device);
return (controllers[hdc].device);
}
int
hdc_has_config(int hdc)
{
const device_t *dev = hdc_get_device(hdc);
if (dev == NULL) return(0);
if (dev == NULL)
return (0);
if (!device_has_config(dev)) return(0);
if (!device_has_config(dev))
return (0);
return(1);
return (1);
}
int
hdc_get_flags(int hdc)
{
return(controllers[hdc].device->flags);
return (controllers[hdc].device->flags);
}
int
hdc_available(int hdc)
{
return(device_available(controllers[hdc].device));
return (device_available(controllers[hdc].device));
}

File diff suppressed because it is too large Load Diff

View File

@@ -243,7 +243,7 @@ static double
esdi_mca_get_xfer_time(esdi_t *esdi, int size)
{
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
return (3125.0 / 8.0) * (double)size;
return (3125.0 / 8.0) * (double) size;
}
static void
@@ -352,7 +352,7 @@ esdi_callback(void *priv)
esdi_t *dev = (esdi_t *) priv;
drive_t *drive;
int val;
double cmd_time = 0.0;
double cmd_time = 0.0;
esdi_mca_set_callback(dev, 0);
@@ -525,7 +525,7 @@ esdi_callback(void *priv)
switch (dev->cmd_state) {
case 0:
dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff;
dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff;
dev->sector_count = dev->cmd_data[1];
if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) {

File diff suppressed because it is too large Load Diff

View File

@@ -37,20 +37,17 @@
#include <86box/zip.h>
#include <86box/mo.h>
typedef struct
{
uint8_t vlb_idx, id,
in_cfg, single_channel,
pci, regs[256];
uint32_t local;
int slot, irq_mode[2],
irq_pin, irq_line;
uint8_t vlb_idx, id,
in_cfg, single_channel,
pci, regs[256];
uint32_t local;
int slot, irq_mode[2],
irq_pin, irq_line;
} cmd640_t;
static int next_id = 0;
static int next_id = 0;
#ifdef ENABLE_CMD640_LOG
int cmd640_do_log = ENABLE_CMD640_LOG;
@@ -59,51 +56,48 @@ cmd640_log(const char *fmt, ...)
{
va_list ap;
if (cmd640_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (cmd640_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define cmd640_log(fmt, ...)
# define cmd640_log(fmt, ...)
#endif
void
cmd640_set_irq(int channel, void *priv)
{
cmd640_t *dev = (cmd640_t *) priv;
int irq = !!(channel & 0x40);
int irq = !!(channel & 0x40);
if (channel & 0x01) {
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
dev->regs[0x57] &= ~0x10;
dev->regs[0x57] |= (channel >> 2);
}
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
dev->regs[0x57] &= ~0x10;
dev->regs[0x57] |= (channel >> 2);
}
} else {
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
dev->regs[0x50] &= ~0x04;
dev->regs[0x50] |= (channel >> 4);
}
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
dev->regs[0x50] &= ~0x04;
dev->regs[0x50] |= (channel >> 4);
}
}
channel &= 0x01;
if (irq) {
if (dev->irq_mode[channel] == 1)
pci_set_irq(dev->slot, dev->irq_pin);
else
picint(1 << (14 + channel));
if (dev->irq_mode[channel] == 1)
pci_set_irq(dev->slot, dev->irq_pin);
else
picint(1 << (14 + channel));
} else {
if (dev->irq_mode[channel] == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
else
picintc(1 << (14 + channel));
if (dev->irq_mode[channel] == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
else
picintc(1 << (14 + channel));
}
}
static void
cmd640_ide_handlers(cmd640_t *dev)
{
@@ -112,65 +106,67 @@ cmd640_ide_handlers(cmd640_t *dev)
ide_pri_disable();
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
} else {
main = 0x1f0;
side = 0x3f6;
main = 0x1f0;
side = 0x3f6;
}
ide_set_base(0, main);
ide_set_side(0, side);
if (dev->regs[0x04] & 0x01)
ide_pri_enable();
ide_pri_enable();
if (dev->single_channel)
return;
return;
ide_sec_disable();
if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
} else {
main = 0x170;
side = 0x376;
main = 0x170;
side = 0x376;
}
ide_set_base(1, main);
ide_set_side(1, side);
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
ide_sec_enable();
ide_sec_enable();
}
static void
cmd640_common_write(int addr, uint8_t val, cmd640_t *dev)
{
switch (addr) {
case 0x51:
dev->regs[addr] = val;
cmd640_ide_handlers(dev);
break;
case 0x52: case 0x54: case 0x56: case 0x58:
case 0x59:
dev->regs[addr] = val;
break;
case 0x53: case 0x55:
dev->regs[addr] = val & 0xc0;
break;
case 0x57:
dev->regs[addr] = val & 0xdc;
break;
case 0x5b: /* Undocumented register that Linux attempts to use! */
dev->regs[addr] = val;
break;
case 0x51:
dev->regs[addr] = val;
cmd640_ide_handlers(dev);
break;
case 0x52:
case 0x54:
case 0x56:
case 0x58:
case 0x59:
dev->regs[addr] = val;
break;
case 0x53:
case 0x55:
dev->regs[addr] = val & 0xc0;
break;
case 0x57:
dev->regs[addr] = val & 0xdc;
break;
case 0x5b: /* Undocumented register that Linux attempts to use! */
dev->regs[addr] = val;
break;
}
}
static void
cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv)
{
@@ -179,21 +175,20 @@ cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv)
addr &= 0x00ff;
switch (addr) {
case 0x0078:
if (dev->in_cfg)
dev->vlb_idx = val;
else if ((dev->regs[0x50] & 0x80) && (val == dev->id))
dev->in_cfg = 1;
break;
case 0x007c:
cmd640_common_write(dev->vlb_idx, val, dev);
if (dev->regs[0x50] & 0x80)
dev->in_cfg = 0;
break;
case 0x0078:
if (dev->in_cfg)
dev->vlb_idx = val;
else if ((dev->regs[0x50] & 0x80) && (val == dev->id))
dev->in_cfg = 1;
break;
case 0x007c:
cmd640_common_write(dev->vlb_idx, val, dev);
if (dev->regs[0x50] & 0x80)
dev->in_cfg = 0;
break;
}
}
static void
cmd640_vlb_writew(uint16_t addr, uint16_t val, void *priv)
{
@@ -201,7 +196,6 @@ cmd640_vlb_writew(uint16_t addr, uint16_t val, void *priv)
cmd640_vlb_write(addr + 1, val >> 8, priv);
}
static void
cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv)
{
@@ -209,35 +203,33 @@ cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv)
cmd640_vlb_writew(addr + 2, val >> 16, priv);
}
static uint8_t
cmd640_vlb_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
uint8_t ret = 0xff;
cmd640_t *dev = (cmd640_t *) priv;
addr &= 0x00ff;
switch (addr) {
case 0x0078:
if (dev->in_cfg)
ret = dev->vlb_idx;
break;
case 0x007c:
ret = dev->regs[dev->vlb_idx];
if (dev->vlb_idx == 0x50)
dev->regs[0x50] &= ~0x04;
else if (dev->vlb_idx == 0x57)
dev->regs[0x57] &= ~0x10;
if (dev->regs[0x50] & 0x80)
dev->in_cfg = 0;
break;
case 0x0078:
if (dev->in_cfg)
ret = dev->vlb_idx;
break;
case 0x007c:
ret = dev->regs[dev->vlb_idx];
if (dev->vlb_idx == 0x50)
dev->regs[0x50] &= ~0x04;
else if (dev->vlb_idx == 0x57)
dev->regs[0x57] &= ~0x10;
if (dev->regs[0x50] & 0x80)
dev->in_cfg = 0;
break;
}
return ret;
}
static uint16_t
cmd640_vlb_readw(uint16_t addr, void *priv)
{
@@ -249,7 +241,6 @@ cmd640_vlb_readw(uint16_t addr, void *priv)
return ret;
}
static uint32_t
cmd640_vlb_readl(uint16_t addr, void *priv)
{
@@ -261,7 +252,6 @@ cmd640_vlb_readl(uint16_t addr, void *priv)
return ret;
}
static void
cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
{
@@ -269,89 +259,89 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val);
if (func == 0x00) switch (addr) {
case 0x04:
dev->regs[addr] = (val & 0x41);
cmd640_ide_handlers(dev);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0x80);
break;
case 0x09:
if ((dev->regs[addr] & 0x0a) == 0x0a) {
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
dev->irq_mode[0] = !!(val & 0x01);
dev->irq_mode[1] = !!(val & 0x04);
cmd640_ide_handlers(dev);
}
break;
case 0x10:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = (val & 0xf8) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x11:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x11] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x14:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x14] = (val & 0xfc) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x15:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x15] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x18:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x18] = (val & 0xf8) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x19:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x19] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x1c:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1c] = (val & 0xfc) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x1d:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1d] = val;
cmd640_ide_handlers(dev);
}
break;
default:
cmd640_common_write(addr, val, dev);
break;
}
if (func == 0x00)
switch (addr) {
case 0x04:
dev->regs[addr] = (val & 0x41);
cmd640_ide_handlers(dev);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0x80);
break;
case 0x09:
if ((dev->regs[addr] & 0x0a) == 0x0a) {
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
dev->irq_mode[0] = !!(val & 0x01);
dev->irq_mode[1] = !!(val & 0x04);
cmd640_ide_handlers(dev);
}
break;
case 0x10:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = (val & 0xf8) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x11:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x11] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x14:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x14] = (val & 0xfc) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x15:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x15] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x18:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x18] = (val & 0xf8) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x19:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x19] = val;
cmd640_ide_handlers(dev);
}
break;
case 0x1c:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1c] = (val & 0xfc) | 1;
cmd640_ide_handlers(dev);
}
break;
case 0x1d:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1d] = val;
cmd640_ide_handlers(dev);
}
break;
default:
cmd640_common_write(addr, val, dev);
break;
}
}
static uint8_t
cmd640_pci_read(int func, int addr, void *priv)
{
cmd640_t *dev = (cmd640_t *) priv;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
if (func == 0x00) {
ret = dev->regs[addr];
if (addr == 0x50)
dev->regs[0x50] &= ~0x04;
else if (addr == 0x57)
dev->regs[0x57] &= ~0x10;
ret = dev->regs[addr];
if (addr == 0x50)
dev->regs[0x50] &= ~0x04;
else if (addr == 0x57)
dev->regs[0x57] &= ~0x10;
}
cmd640_log("cmd640_pci_read(%i, %02X, %02X)\n", func, addr, ret);
@@ -359,84 +349,83 @@ cmd640_pci_read(int func, int addr, void *priv)
return ret;
}
static void
cmd640_reset(void *priv)
{
cmd640_t *dev = (cmd640_t *) priv;
int i = 0;
int i = 0;
for (i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
}
for (i = 0; i < ZIP_NUM; i++) {
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
cmd640_set_irq(0x00, priv);
cmd640_set_irq(0x01, priv);
memset(dev->regs, 0x00, sizeof(dev->regs));
dev->regs[0x50] = 0x02; /* Revision 02 */
dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */
dev->regs[0x50] = 0x02; /* Revision 02 */
dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */
dev->regs[0x59] = 0x40;
if (dev->pci) {
cmd640_log("dev->local = %08X\n", dev->local);
if ((dev->local & 0xffff) == 0x0a) {
dev->regs[0x50] |= 0x40; /* Enable Base address register R/W;
If 0, they return 0 and are read-only 8 */
}
cmd640_log("dev->local = %08X\n", dev->local);
if ((dev->local & 0xffff) == 0x0a) {
dev->regs[0x50] |= 0x40; /* Enable Base address register R/W;
If 0, they return 0 and are read-only 8 */
}
dev->regs[0x00] = 0x95; /* CMD */
dev->regs[0x01] = 0x10;
dev->regs[0x02] = 0x40; /* PCI-0640B */
dev->regs[0x03] = 0x06;
dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
dev->regs[0x08] = 0x02; /* Revision 02 */
dev->regs[0x09] = dev->local; /* Programming interface */
dev->regs[0x0a] = 0x01; /* IDE controller */
dev->regs[0x0b] = 0x01; /* Mass storage controller */
dev->regs[0x00] = 0x95; /* CMD */
dev->regs[0x01] = 0x10;
dev->regs[0x02] = 0x40; /* PCI-0640B */
dev->regs[0x03] = 0x06;
dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
dev->regs[0x08] = 0x02; /* Revision 02 */
dev->regs[0x09] = dev->local; /* Programming interface */
dev->regs[0x0a] = 0x01; /* IDE controller */
dev->regs[0x0b] = 0x01; /* Mass storage controller */
/* Base addresses (1F0, 3F4, 170, 374) */
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
}
/* Base addresses (1F0, 3F4, 170, 374) */
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = 0xf1;
dev->regs[0x11] = 0x01;
dev->regs[0x14] = 0xf5;
dev->regs[0x15] = 0x03;
dev->regs[0x18] = 0x71;
dev->regs[0x19] = 0x01;
dev->regs[0x1c] = 0x75;
dev->regs[0x1d] = 0x03;
}
dev->regs[0x3c] = 0x14; /* IRQ 14 */
dev->regs[0x3d] = 0x01; /* INTA */
dev->regs[0x3c] = 0x14; /* IRQ 14 */
dev->regs[0x3d] = 0x01; /* INTA */
dev->irq_mode[0] = dev->irq_mode[1] = 0;
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
dev->irq_mode[0] = dev->irq_mode[1] = 0;
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
} else {
if ((dev->local & 0xffff) == 0x0078)
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
if ((dev->local & 0xffff) == 0x0078)
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
/* If bit 7 is 1, then device ID has to be written on port x78h before
accessing the configuration registers */
dev->in_cfg = 1; /* Configuration registers are accessible */
/* If bit 7 is 1, then device ID has to be written on port x78h before
accessing the configuration registers */
dev->in_cfg = 1; /* Configuration registers are accessible */
}
cmd640_ide_handlers(dev);
}
static void
cmd640_close(void *priv)
{
@@ -447,7 +436,6 @@ cmd640_close(void *priv)
next_id = 0;
}
static void *
cmd640_init(const device_t *info)
{
@@ -456,30 +444,30 @@ cmd640_init(const device_t *info)
dev->id = next_id | 0x60;
dev->pci = !!(info->flags & DEVICE_PCI);
dev->pci = !!(info->flags & DEVICE_PCI);
dev->local = info->local;
if (info->flags & DEVICE_PCI) {
device_add(&ide_pci_2ch_device);
device_add(&ide_pci_2ch_device);
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
/* The CMD PCI-0640B IDE controller has no DMA capability,
so set our devices IDE devices to force ATA-3 (no DMA). */
ide_board_set_force_ata3(0, 1);
ide_board_set_force_ata3(1, 1);
/* The CMD PCI-0640B IDE controller has no DMA capability,
so set our devices IDE devices to force ATA-3 (no DMA). */
ide_board_set_force_ata3(0, 1);
ide_board_set_force_ata3(1, 1);
// ide_pri_disable();
// ide_pri_disable();
} else if (info->flags & DEVICE_VLB) {
device_add(&ide_vlb_2ch_device);
device_add(&ide_vlb_2ch_device);
io_sethandler(info->local & 0xffff, 0x0008,
cmd640_vlb_read, cmd640_vlb_readw, cmd640_vlb_readl,
cmd640_vlb_write, cmd640_vlb_writew, cmd640_vlb_writel,
dev);
io_sethandler(info->local & 0xffff, 0x0008,
cmd640_vlb_read, cmd640_vlb_readw, cmd640_vlb_readl,
cmd640_vlb_write, cmd640_vlb_writew, cmd640_vlb_writel,
dev);
}
dev->single_channel = !!(info->local & 0x20000);
@@ -492,71 +480,71 @@ cmd640_init(const device_t *info)
}
const device_t ide_cmd640_vlb_device = {
.name = "CMD PCI-0640B VLB",
.name = "CMD PCI-0640B VLB",
.internal_name = "ide_cmd640_vlb",
.flags = DEVICE_VLB,
.local = 0x0078,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.flags = DEVICE_VLB,
.local = 0x0078,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_vlb_178_device = {
.name = "CMD PCI-0640B VLB (Port 178h)",
.name = "CMD PCI-0640B VLB (Port 178h)",
.internal_name = "ide_cmd640_vlb_178",
.flags = DEVICE_VLB,
.local = 0x0178,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.flags = DEVICE_VLB,
.local = 0x0178,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_pci_device = {
.name = "CMD PCI-0640B PCI",
.name = "CMD PCI-0640B PCI",
.internal_name = "ide_cmd640_pci",
.flags = DEVICE_PCI,
.local = 0x0a,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.flags = DEVICE_PCI,
.local = 0x0a,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_pci_legacy_only_device = {
.name = "CMD PCI-0640B PCI (Legacy Mode Only)",
.name = "CMD PCI-0640B PCI (Legacy Mode Only)",
.internal_name = "ide_cmd640_pci_legacy_only",
.flags = DEVICE_PCI,
.local = 0x00,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.flags = DEVICE_PCI,
.local = 0x00,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_pci_single_channel_device = {
.name = "CMD PCI-0640B PCI",
.name = "CMD PCI-0640B PCI",
.internal_name = "ide_cmd640_pci_single_channel",
.flags = DEVICE_PCI,
.local = 0x2000a,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
.flags = DEVICE_PCI,
.local = 0x2000a,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -37,18 +37,16 @@
#include <86box/zip.h>
#include <86box/mo.h>
typedef struct
{
uint8_t vlb_idx, single_channel,
in_cfg, regs[256];
uint32_t local;
int slot, irq_mode[2],
irq_pin;
sff8038i_t *bm[2];
uint8_t vlb_idx, single_channel,
in_cfg, regs[256];
uint32_t local;
int slot, irq_mode[2],
irq_pin;
sff8038i_t *bm[2];
} cmd646_t;
#ifdef ENABLE_CMD646_LOG
int cmd646_do_log = ENABLE_CMD646_LOG;
static void
@@ -56,39 +54,36 @@ cmd646_log(const char *fmt, ...)
{
va_list ap;
if (cmd646_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (cmd646_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define cmd646_log(fmt, ...)
# define cmd646_log(fmt, ...)
#endif
static void
cmd646_set_irq(int channel, void *priv)
{
cmd646_t *dev = (cmd646_t *) priv;
if (channel & 0x01) {
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
dev->regs[0x57] &= ~0x10;
dev->regs[0x57] |= (channel >> 2);
}
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
dev->regs[0x57] &= ~0x10;
dev->regs[0x57] |= (channel >> 2);
}
} else {
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
dev->regs[0x50] &= ~0x04;
dev->regs[0x50] |= (channel >> 4);
}
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
dev->regs[0x50] &= ~0x04;
dev->regs[0x50] |= (channel >> 4);
}
}
sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]);
}
static int
cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
{
@@ -97,63 +92,60 @@ cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out,
return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]);
}
static void
cmd646_ide_handlers(cmd646_t *dev)
{
uint16_t main, side;
int irq_mode[2] = { 0, 0 };
int irq_mode[2] = { 0, 0 };
ide_pri_disable();
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
} else {
main = 0x1f0;
side = 0x3f6;
main = 0x1f0;
side = 0x3f6;
}
ide_set_base(0, main);
ide_set_side(0, side);
if (dev->regs[0x09] & 0x01)
irq_mode[0] = 1;
irq_mode[0] = 1;
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
if (dev->regs[0x04] & 0x01)
ide_pri_enable();
ide_pri_enable();
if (dev->single_channel)
return;
return;
ide_sec_disable();
if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
} else {
main = 0x170;
side = 0x376;
main = 0x170;
side = 0x376;
}
ide_set_base(1, main);
ide_set_side(1, side);
if (dev->regs[0x09] & 0x04)
irq_mode[1] = 1;
irq_mode[1] = 1;
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
ide_sec_enable();
ide_sec_enable();
}
static void
cmd646_ide_bm_handlers(cmd646_t *dev)
{
@@ -163,7 +155,6 @@ cmd646_ide_bm_handlers(cmd646_t *dev)
sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8);
}
static void
cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
{
@@ -171,119 +162,124 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val);
if (func == 0x00) switch (addr) {
case 0x04:
dev->regs[addr] = (val & 0x45);
cmd646_ide_handlers(dev);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0xb1);
break;
case 0x09:
if ((dev->regs[addr] & 0x0a) == 0x0a) {
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
dev->irq_mode[0] = !!(val & 0x01);
dev->irq_mode[1] = !!(val & 0x04);
cmd646_ide_handlers(dev);
}
break;
case 0x10:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = (val & 0xf8) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x11:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x11] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x14:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x14] = (val & 0xfc) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x15:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x15] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x18:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x18] = (val & 0xf8) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x19:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x19] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x1c:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1c] = (val & 0xfc) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x1d:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1d] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x20:
dev->regs[0x20] = (val & 0xf0) | 1;
cmd646_ide_bm_handlers(dev);
break;
case 0x21:
dev->regs[0x21] = val;
cmd646_ide_bm_handlers(dev);
break;
case 0x51:
dev->regs[addr] = val & 0xc8;
cmd646_ide_handlers(dev);
break;
case 0x52: case 0x54: case 0x56: case 0x58:
case 0x59: case 0x5b:
dev->regs[addr] = val;
break;
case 0x53: case 0x55:
dev->regs[addr] = val & 0xc0;
break;
case 0x57:
dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc);
break;
case 0x70 ... 0x77:
sff_bus_master_write(addr & 0x0f, val, dev->bm[0]);
break;
case 0x78 ... 0x7f:
sff_bus_master_write(addr & 0x0f, val, dev->bm[1]);
break;
}
if (func == 0x00)
switch (addr) {
case 0x04:
dev->regs[addr] = (val & 0x45);
cmd646_ide_handlers(dev);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0xb1);
break;
case 0x09:
if ((dev->regs[addr] & 0x0a) == 0x0a) {
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
dev->irq_mode[0] = !!(val & 0x01);
dev->irq_mode[1] = !!(val & 0x04);
cmd646_ide_handlers(dev);
}
break;
case 0x10:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x10] = (val & 0xf8) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x11:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x11] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x14:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x14] = (val & 0xfc) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x15:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x15] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x18:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x18] = (val & 0xf8) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x19:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x19] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x1c:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1c] = (val & 0xfc) | 1;
cmd646_ide_handlers(dev);
}
break;
case 0x1d:
if (dev->regs[0x50] & 0x40) {
dev->regs[0x1d] = val;
cmd646_ide_handlers(dev);
}
break;
case 0x20:
dev->regs[0x20] = (val & 0xf0) | 1;
cmd646_ide_bm_handlers(dev);
break;
case 0x21:
dev->regs[0x21] = val;
cmd646_ide_bm_handlers(dev);
break;
case 0x51:
dev->regs[addr] = val & 0xc8;
cmd646_ide_handlers(dev);
break;
case 0x52:
case 0x54:
case 0x56:
case 0x58:
case 0x59:
case 0x5b:
dev->regs[addr] = val;
break;
case 0x53:
case 0x55:
dev->regs[addr] = val & 0xc0;
break;
case 0x57:
dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc);
break;
case 0x70 ... 0x77:
sff_bus_master_write(addr & 0x0f, val, dev->bm[0]);
break;
case 0x78 ... 0x7f:
sff_bus_master_write(addr & 0x0f, val, dev->bm[1]);
break;
}
}
static uint8_t
cmd646_pci_read(int func, int addr, void *priv)
{
cmd646_t *dev = (cmd646_t *) priv;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
if (func == 0x00) {
ret = dev->regs[addr];
ret = dev->regs[addr];
if (addr == 0x50)
dev->regs[0x50] &= ~0x04;
else if (addr == 0x57)
dev->regs[0x57] &= ~0x10;
else if ((addr >= 0x70) && (addr <= 0x77))
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
else if ((addr >= 0x78) && (addr <= 0x7f))
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
if (addr == 0x50)
dev->regs[0x50] &= ~0x04;
else if (addr == 0x57)
dev->regs[0x57] &= ~0x10;
else if ((addr >= 0x70) && (addr <= 0x77))
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
else if ((addr >= 0x78) && (addr <= 0x7f))
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
}
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret);
@@ -291,77 +287,76 @@ cmd646_pci_read(int func, int addr, void *priv)
return ret;
}
static void
cmd646_reset(void *priv)
{
cmd646_t *dev = (cmd646_t *) priv;
int i = 0;
int i = 0;
for (i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
}
for (i = 0; i < ZIP_NUM; i++) {
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
cmd646_set_irq(0x00, priv);
cmd646_set_irq(0x01, priv);
memset(dev->regs, 0x00, sizeof(dev->regs));
dev->regs[0x00] = 0x95; /* CMD */
dev->regs[0x00] = 0x95; /* CMD */
dev->regs[0x01] = 0x10;
dev->regs[0x02] = 0x46; /* PCI-0646 */
dev->regs[0x02] = 0x46; /* PCI-0646 */
dev->regs[0x03] = 0x06;
dev->regs[0x04] = 0x00;
dev->regs[0x06] = 0x80;
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
dev->regs[0x09] = dev->local; /* Programming interface */
dev->regs[0x0a] = 0x01; /* IDE controller */
dev->regs[0x0b] = 0x01; /* Mass storage controller */
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
dev->regs[0x09] = dev->local; /* Programming interface */
dev->regs[0x0a] = 0x01; /* IDE controller */
dev->regs[0x0b] = 0x01; /* Mass storage controller */
if ((dev->local & 0xffff) == 0x8a) {
dev->regs[0x50] = 0x40; /* Enable Base address register R/W;
If 0, they return 0 and are read-only 8 */
dev->regs[0x50] = 0x40; /* Enable Base address register R/W;
If 0, they return 0 and are read-only 8 */
/* Base addresses (1F0, 3F4, 170, 374) */
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
/* Base addresses (1F0, 3F4, 170, 374) */
dev->regs[0x10] = 0xf1;
dev->regs[0x11] = 0x01;
dev->regs[0x14] = 0xf5;
dev->regs[0x15] = 0x03;
dev->regs[0x18] = 0x71;
dev->regs[0x19] = 0x01;
dev->regs[0x1c] = 0x75;
dev->regs[0x1d] = 0x03;
}
dev->regs[0x20] = 0x01;
dev->regs[0x3c] = 0x0e; /* IRQ 14 */
dev->regs[0x3d] = 0x01; /* INTA */
dev->regs[0x3e] = 0x02; /* Min_Gnt */
dev->regs[0x3f] = 0x04; /* Max_Iat */
dev->regs[0x3c] = 0x0e; /* IRQ 14 */
dev->regs[0x3d] = 0x01; /* INTA */
dev->regs[0x3e] = 0x02; /* Min_Gnt */
dev->regs[0x3f] = 0x04; /* Max_Iat */
if (!dev->single_channel)
dev->regs[0x51] = 0x08;
dev->regs[0x51] = 0x08;
dev->regs[0x57] = 0x0c;
dev->regs[0x59] = 0x40;
dev->irq_mode[0] = dev->irq_mode[1] = 0;
dev->irq_pin = PCI_INTA;
dev->irq_pin = PCI_INTA;
cmd646_ide_handlers(dev);
cmd646_ide_bm_handlers(dev);
}
static void
cmd646_close(void *priv)
{
@@ -370,7 +365,6 @@ cmd646_close(void *priv)
free(dev);
}
static void *
cmd646_init(const device_t *info)
{
@@ -387,18 +381,18 @@ cmd646_init(const device_t *info)
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
if (!dev->single_channel)
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev);
if (!dev->single_channel)
ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev);
ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
if (!dev->single_channel) {
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
}
cmd646_reset(dev);
@@ -407,43 +401,43 @@ cmd646_init(const device_t *info)
}
const device_t ide_cmd646_device = {
.name = "CMD PCI-0646",
.name = "CMD PCI-0646",
.internal_name = "ide_cmd646",
.flags = DEVICE_PCI,
.local = 0x8a,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
.flags = DEVICE_PCI,
.local = 0x8a,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd646_legacy_only_device = {
.name = "CMD PCI-0646 (Legacy Mode Only)",
.name = "CMD PCI-0646 (Legacy Mode Only)",
.internal_name = "ide_cmd646_legacy_only",
.flags = DEVICE_PCI,
.local = 0x80,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
.flags = DEVICE_PCI,
.local = 0x80,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd646_single_channel_device = {
.name = "CMD PCI-0646",
.name = "CMD PCI-0646",
.internal_name = "ide_cmd646_single_channel",
.flags = DEVICE_PCI,
.local = 0x2008a,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
.flags = DEVICE_PCI,
.local = 0x2008a,
.init = cmd646_init,
.close = cmd646_close,
.reset = cmd646_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -29,17 +29,14 @@
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
typedef struct
{
uint8_t tries,
in_cfg, cfg_locked,
regs[19];
uint8_t tries,
in_cfg, cfg_locked,
regs[19];
} opti611_t;
static void opti611_ide_handler(opti611_t *dev);
static void opti611_ide_handler(opti611_t *dev);
static void
opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
@@ -49,32 +46,31 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
addr &= 0x0007;
switch (addr) {
case 0x0000:
case 0x0001:
dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr] = val;
break;
case 0x0002:
dev->regs[0x12] = (val & 0xc1) | 0x02;
if (val & 0xc0) {
if (val & 0x40)
dev->cfg_locked = 1;
dev->in_cfg = 0;
opti611_ide_handler(dev);
}
break;
case 0x0003:
dev->regs[0x03] = (val & 0xdf);
break;
case 0x0005:
dev->regs[0x05] = (dev->regs[0x05] & 0x78) | (val & 0x87);
break;
case 0x0006:
dev->regs[0x06] = val;
break;
case 0x0000:
case 0x0001:
dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr] = val;
break;
case 0x0002:
dev->regs[0x12] = (val & 0xc1) | 0x02;
if (val & 0xc0) {
if (val & 0x40)
dev->cfg_locked = 1;
dev->in_cfg = 0;
opti611_ide_handler(dev);
}
break;
case 0x0003:
dev->regs[0x03] = (val & 0xdf);
break;
case 0x0005:
dev->regs[0x05] = (dev->regs[0x05] & 0x78) | (val & 0x87);
break;
case 0x0006:
dev->regs[0x06] = val;
break;
}
}
static void
opti611_cfg_writew(uint16_t addr, uint16_t val, void *priv)
{
@@ -82,7 +78,6 @@ opti611_cfg_writew(uint16_t addr, uint16_t val, void *priv)
opti611_cfg_write(addr + 1, val >> 8, priv);
}
static void
opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv)
{
@@ -90,34 +85,35 @@ opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv)
opti611_cfg_writew(addr + 2, val >> 16, priv);
}
static uint8_t
opti611_cfg_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
uint8_t ret = 0xff;
opti611_t *dev = (opti611_t *) priv;
addr &= 0x0007;
switch (addr) {
case 0x0000:
case 0x0001:
ret = dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr];
break;
case 0x0002:
ret = ((!!in_smm) << 7);
if (ret & 0x80)
ret |= (dev->regs[addr] & 0x7f);
break;
case 0x0003: case 0x0004: case 0x0005: case 0x0006:
ret = dev->regs[addr];
break;
case 0x0000:
case 0x0001:
ret = dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr];
break;
case 0x0002:
ret = ((!!in_smm) << 7);
if (ret & 0x80)
ret |= (dev->regs[addr] & 0x7f);
break;
case 0x0003:
case 0x0004:
case 0x0005:
case 0x0006:
ret = dev->regs[addr];
break;
}
return ret;
}
static uint16_t
opti611_cfg_readw(uint16_t addr, void *priv)
{
@@ -129,7 +125,6 @@ opti611_cfg_readw(uint16_t addr, void *priv)
return ret;
}
static uint32_t
opti611_cfg_readl(uint16_t addr, void *priv)
{
@@ -141,7 +136,6 @@ opti611_cfg_readl(uint16_t addr, void *priv)
return ret;
}
static void
opti611_ide_write(uint16_t addr, uint8_t val, void *priv)
{
@@ -152,13 +146,12 @@ opti611_ide_write(uint16_t addr, uint8_t val, void *priv)
uint8_t smibe = (addr & 0x0003);
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = val;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = val;
}
}
static void
opti611_ide_writew(uint16_t addr, uint16_t val, void *priv)
{
@@ -169,13 +162,12 @@ opti611_ide_writew(uint16_t addr, uint16_t val, void *priv)
uint8_t smibe = (addr & 0x0002) | 0x0001;
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
}
}
static void
opti611_ide_writel(uint16_t addr, uint32_t val, void *priv)
{
@@ -185,13 +177,12 @@ opti611_ide_writel(uint16_t addr, uint32_t val, void *priv)
uint8_t smia2 = (!!(addr & 0x0004)) << 4;
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | 0x0003;
dev->regs[0x04] = 0x00;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | 0x0003;
dev->regs[0x04] = 0x00;
}
}
static uint8_t
opti611_ide_read(uint16_t addr, void *priv)
{
@@ -202,15 +193,14 @@ opti611_ide_read(uint16_t addr, void *priv)
uint8_t smibe = (addr & 0x0003);
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
}
return 0xff;
}
static uint16_t
opti611_ide_readw(uint16_t addr, void *priv)
{
@@ -221,23 +211,22 @@ opti611_ide_readw(uint16_t addr, void *priv)
uint8_t smibe = (addr & 0x0002) | 0x0001;
if ((addr & 0x0007) == 0x0001) {
dev->tries = (dev->tries + 1) & 0x01;
if ((dev->tries == 0x00) && !dev->cfg_locked) {
dev->in_cfg = 1;
opti611_ide_handler(dev);
}
dev->tries = (dev->tries + 1) & 0x01;
if ((dev->tries == 0x00) && !dev->cfg_locked) {
dev->in_cfg = 1;
opti611_ide_handler(dev);
}
}
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | smibe;
dev->regs[0x04] = 0x00;
}
return 0xffff;
}
static uint32_t
opti611_ide_readl(uint16_t addr, void *priv)
{
@@ -247,44 +236,42 @@ opti611_ide_readl(uint16_t addr, void *priv)
uint8_t smia2 = (!!(addr & 0x0004)) << 4;
if (dev->regs[0x03] & 0x02) {
smi_raise();
dev->regs[0x02] = smia9 | smia2 | 0x0003;
dev->regs[0x04] = 0x00;
smi_raise();
dev->regs[0x02] = smia9 | smia2 | 0x0003;
dev->regs[0x04] = 0x00;
}
return 0xffffffff;
}
static void
opti611_ide_handler(opti611_t *dev)
{
ide_pri_disable();
io_removehandler(0x01f0, 0x0007,
opti611_ide_read, opti611_ide_readw, opti611_ide_readl,
opti611_ide_write, opti611_ide_writew, opti611_ide_writel,
dev);
opti611_ide_read, opti611_ide_readw, opti611_ide_readl,
opti611_ide_write, opti611_ide_writew, opti611_ide_writel,
dev);
io_removehandler(0x01f0, 0x0007,
opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl,
opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel,
dev);
opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl,
opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel,
dev);
if (dev->in_cfg && !dev->cfg_locked) {
io_sethandler(0x01f0, 0x0007,
opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl,
opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel,
dev);
io_sethandler(0x01f0, 0x0007,
opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl,
opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel,
dev);
} else {
if (dev->regs[0x03] & 0x01)
ide_pri_enable();
io_sethandler(0x01f0, 0x0007,
opti611_ide_read, opti611_ide_readw, opti611_ide_readl,
opti611_ide_write, opti611_ide_writew, opti611_ide_writel,
dev);
if (dev->regs[0x03] & 0x01)
ide_pri_enable();
io_sethandler(0x01f0, 0x0007,
opti611_ide_read, opti611_ide_readw, opti611_ide_readl,
opti611_ide_write, opti611_ide_writew, opti611_ide_writel,
dev);
}
}
static void
opti611_close(void *priv)
{
@@ -293,7 +280,6 @@ opti611_close(void *priv)
free(dev);
}
static void *
opti611_init(const device_t *info)
{
@@ -312,15 +298,15 @@ opti611_init(const device_t *info)
}
const device_t ide_opti611_vlb_device = {
.name = "OPTi 82C611/82C611A VLB",
.name = "OPTi 82C611/82C611A VLB",
.internal_name = "ide_opti611_vlb",
.flags = DEVICE_VLB,
.local = 0,
.init = opti611_init,
.close = opti611_close,
.reset = NULL,
.flags = DEVICE_VLB,
.local = 0,
.init = opti611_init,
.close = opti611_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -43,75 +43,68 @@
#include <86box/zip.h>
#include <86box/mo.h>
static int next_id = 0;
static int next_id = 0;
uint8_t sff_bus_master_read(uint16_t port, void *priv);
static uint16_t sff_bus_master_readw(uint16_t port, void *priv);
static uint32_t sff_bus_master_readl(uint16_t port, void *priv);
void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv);
static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv);
uint8_t sff_bus_master_read(uint16_t port, void *priv);
static uint16_t sff_bus_master_readw(uint16_t port, void *priv);
static uint32_t sff_bus_master_readl(uint16_t port, void *priv);
void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv);
static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv);
#ifdef ENABLE_SFF_LOG
int sff_do_log = ENABLE_SFF_LOG;
static void
sff_log(const char *fmt, ...)
{
va_list ap;
if (sff_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define sff_log(fmt, ...)
# define sff_log(fmt, ...)
#endif
void
sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base)
{
if (dev->base != 0x0000) {
io_removehandler(dev->base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
io_removehandler(dev->base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
}
if (enabled && (base != 0x0000)) {
io_sethandler(base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
io_sethandler(base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
}
dev->enabled = enabled;
dev->base = base;
dev->base = base;
}
static void
sff_bus_master_next_addr(sff8038i_t *dev)
{
dma_bm_read(dev->ptr_cur, (uint8_t *)&(dev->addr), 4, 4);
dma_bm_read(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4, 4);
dma_bm_read(dev->ptr_cur, (uint8_t *) &(dev->addr), 4, 4);
dma_bm_read(dev->ptr_cur + 4, (uint8_t *) &(dev->count), 4, 4);
sff_log("SFF-8038i Bus master DWORDs: %08X %08X\n", dev->addr, dev->count);
dev->eot = dev->count >> 31;
dev->count &= 0xfffe;
if (!dev->count)
dev->count = 65536;
dev->count = 65536;
dev->addr &= 0xfffffffe;
dev->ptr_cur += 8;
}
void
sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
{
@@ -123,54 +116,53 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
sff_log("SFF-8038i Bus master BYTE write: %04X %02X\n", port, val);
switch (port & 7) {
case 0:
sff_log("sff Cmd : val = %02X, old = %02X\n", val, dev->command);
if ((val & 1) && !(dev->command & 1)) { /*Start*/
sff_log("sff Bus Master start on channel %i\n", channel);
dev->ptr_cur = dev->ptr;
sff_bus_master_next_addr(dev);
dev->status |= 1;
}
if (!(val & 1) && (dev->command & 1)) { /*Stop*/
sff_log("sff Bus Master stop on channel %i\n", channel);
dev->status &= ~1;
}
case 0:
sff_log("sff Cmd : val = %02X, old = %02X\n", val, dev->command);
if ((val & 1) && !(dev->command & 1)) { /*Start*/
sff_log("sff Bus Master start on channel %i\n", channel);
dev->ptr_cur = dev->ptr;
sff_bus_master_next_addr(dev);
dev->status |= 1;
}
if (!(val & 1) && (dev->command & 1)) { /*Stop*/
sff_log("sff Bus Master stop on channel %i\n", channel);
dev->status &= ~1;
}
dev->command = val;
break;
case 1:
dev->dma_mode = val & 0x03;
break;
case 2:
sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status);
dev->status &= 0x07;
dev->status |= (val & 0x60);
if (val & 0x04)
dev->status &= ~0x04;
if (val & 0x02)
dev->status &= ~0x02;
break;
case 4:
dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val;
break;
case 5:
dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8);
dev->ptr %= (mem_size * 1024);
break;
case 6:
dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16);
dev->ptr %= (mem_size * 1024);
break;
case 7:
dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24);
dev->ptr %= (mem_size * 1024);
break;
dev->command = val;
break;
case 1:
dev->dma_mode = val & 0x03;
break;
case 2:
sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status);
dev->status &= 0x07;
dev->status |= (val & 0x60);
if (val & 0x04)
dev->status &= ~0x04;
if (val & 0x02)
dev->status &= ~0x02;
break;
case 4:
dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val;
break;
case 5:
dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8);
dev->ptr %= (mem_size * 1024);
break;
case 6:
dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16);
dev->ptr %= (mem_size * 1024);
break;
case 7:
dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24);
dev->ptr %= (mem_size * 1024);
break;
}
}
static void
sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
{
@@ -179,24 +171,23 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
sff_log("SFF-8038i Bus master WORD write: %04X %04X\n", port, val);
switch (port & 7) {
case 0:
case 1:
case 2:
sff_bus_master_write(port, val & 0xff, priv);
break;
case 4:
dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val & 0xff;
break;
case 6:
dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16);
dev->ptr %= (mem_size * 1024);
break;
case 0:
case 1:
case 2:
sff_bus_master_write(port, val & 0xff, priv);
break;
case 4:
dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val & 0xff;
break;
case 6:
dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16);
dev->ptr %= (mem_size * 1024);
break;
}
}
static void
sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
{
@@ -205,20 +196,19 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
sff_log("SFF-8038i Bus master DWORD write: %04X %08X\n", port, val);
switch (port & 7) {
case 0:
case 1:
case 2:
sff_bus_master_write(port, val & 0xff, priv);
break;
case 4:
dev->ptr = (val & 0xfffffffc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val & 0xff;
break;
case 0:
case 1:
case 2:
sff_bus_master_write(port, val & 0xff, priv);
break;
case 4:
dev->ptr = (val & 0xfffffffc);
dev->ptr %= (mem_size * 1024);
dev->ptr0 = val & 0xff;
break;
}
}
uint8_t
sff_bus_master_read(uint16_t port, void *priv)
{
@@ -227,27 +217,27 @@ sff_bus_master_read(uint16_t port, void *priv)
uint8_t ret = 0xff;
switch (port & 7) {
case 0:
ret = dev->command;
break;
case 1:
ret = dev->dma_mode & 0x03;
break;
case 2:
ret = dev->status & 0x67;
break;
case 4:
ret = dev->ptr0;
break;
case 5:
ret = dev->ptr >> 8;
break;
case 6:
ret = dev->ptr >> 16;
break;
case 7:
ret = dev->ptr >> 24;
break;
case 0:
ret = dev->command;
break;
case 1:
ret = dev->dma_mode & 0x03;
break;
case 2:
ret = dev->status & 0x67;
break;
case 4:
ret = dev->ptr0;
break;
case 5:
ret = dev->ptr >> 8;
break;
case 6:
ret = dev->ptr >> 16;
break;
case 7:
ret = dev->ptr >> 24;
break;
}
sff_log("SFF-8038i Bus master BYTE read : %04X %02X\n", port, ret);
@@ -255,7 +245,6 @@ sff_bus_master_read(uint16_t port, void *priv)
return ret;
}
static uint16_t
sff_bus_master_readw(uint16_t port, void *priv)
{
@@ -264,17 +253,17 @@ sff_bus_master_readw(uint16_t port, void *priv)
uint16_t ret = 0xffff;
switch (port & 7) {
case 0:
case 1:
case 2:
ret = (uint16_t) sff_bus_master_read(port, priv);
break;
case 4:
ret = dev->ptr0 | (dev->ptr & 0xff00);
break;
case 6:
ret = dev->ptr >> 16;
break;
case 0:
case 1:
case 2:
ret = (uint16_t) sff_bus_master_read(port, priv);
break;
case 4:
ret = dev->ptr0 | (dev->ptr & 0xff00);
break;
case 6:
ret = dev->ptr >> 16;
break;
}
sff_log("SFF-8038i Bus master WORD read : %04X %04X\n", port, ret);
@@ -282,7 +271,6 @@ sff_bus_master_readw(uint16_t port, void *priv)
return ret;
}
static uint32_t
sff_bus_master_readl(uint16_t port, void *priv)
{
@@ -291,14 +279,14 @@ sff_bus_master_readl(uint16_t port, void *priv)
uint32_t ret = 0xffffffff;
switch (port & 7) {
case 0:
case 1:
case 2:
ret = (uint32_t) sff_bus_master_read(port, priv);
break;
case 4:
ret = dev->ptr0 | (dev->ptr & 0xffffff00);
break;
case 0:
case 1:
case 2:
ret = (uint32_t) sff_bus_master_read(port, priv);
break;
case 4:
ret = dev->ptr0 | (dev->ptr & 0xffffff00);
break;
}
sff_log("sff Bus master DWORD read : %04X %08X\n", port, ret);
@@ -306,7 +294,6 @@ sff_bus_master_readl(uint16_t port, void *priv)
return ret;
}
int
sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
{
@@ -322,141 +309,138 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi
#endif
if (!(dev->status & 1)) {
sff_log("DMA disabled\n");
return 2; /*DMA disabled*/
sff_log("DMA disabled\n");
return 2; /*DMA disabled*/
}
sff_log("SFF-8038i Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length);
while (1) {
if (dev->count <= transfer_length) {
sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
if (out)
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
else
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
transfer_length -= dev->count;
buffer_pos += dev->count;
} else {
sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
if (out)
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
else
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
/* Increase addr and decrease count so that resumed transfers do not mess up. */
dev->addr += transfer_length;
dev->count -= transfer_length;
transfer_length = 0;
force_end = 1;
}
if (dev->count <= transfer_length) {
sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
if (out)
dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4);
else
dma_bm_write(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4);
transfer_length -= dev->count;
buffer_pos += dev->count;
} else {
sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
if (out)
dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), transfer_length, 4);
else
dma_bm_write(dev->addr, (uint8_t *) (data + buffer_pos), transfer_length, 4);
/* Increase addr and decrease count so that resumed transfers do not mess up. */
dev->addr += transfer_length;
dev->count -= transfer_length;
transfer_length = 0;
force_end = 1;
}
if (force_end) {
sff_log("Total transfer length smaller than sum of all blocks, partial block\n");
dev->status &= ~2;
return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */
} else {
if (!transfer_length && !dev->eot) {
sff_log("Total transfer length smaller than sum of all blocks, full block\n");
dev->status &= ~2;
return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */
} else if (transfer_length && dev->eot) {
sff_log("Total transfer length greater than sum of all blocks\n");
dev->status |= 2;
return 0; /* There is data left to transfer but we have reached EOT - return with error. */
} else if (dev->eot) {
sff_log("Regular EOT\n");
dev->status &= ~3;
return 1; /* We have regularly reached EOT - clear status and break. */
} else {
/* We have more to transfer and there are blocks left, get next block. */
sff_bus_master_next_addr(dev);
}
}
if (force_end) {
sff_log("Total transfer length smaller than sum of all blocks, partial block\n");
dev->status &= ~2;
return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */
} else {
if (!transfer_length && !dev->eot) {
sff_log("Total transfer length smaller than sum of all blocks, full block\n");
dev->status &= ~2;
return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */
} else if (transfer_length && dev->eot) {
sff_log("Total transfer length greater than sum of all blocks\n");
dev->status |= 2;
return 0; /* There is data left to transfer but we have reached EOT - return with error. */
} else if (dev->eot) {
sff_log("Regular EOT\n");
dev->status &= ~3;
return 1; /* We have regularly reached EOT - clear status and break. */
} else {
/* We have more to transfer and there are blocks left, get next block. */
sff_bus_master_next_addr(dev);
}
}
}
return 1;
}
void
sff_bus_master_set_irq(int channel, void *priv)
{
sff8038i_t *dev = (sff8038i_t *) priv;
uint8_t irq = !!(channel & 0x40);
uint8_t irq = !!(channel & 0x40);
if (!(dev->status & 0x04) || (channel & 0x40)) {
dev->status &= ~0x04;
dev->status |= (channel >> 4);
dev->status &= ~0x04;
dev->status |= (channel >> 4);
}
channel &= 0x01;
switch (dev->irq_mode[channel]) {
case 0:
default:
/* Legacy IRQ mode. */
if (irq)
picint(1 << (14 + channel));
else
picintc(1 << (14 + channel));
break;
case 1:
/* Native PCI IRQ mode with interrupt pin. */
if (irq)
pci_set_irq(dev->slot, dev->irq_pin);
else
pci_clear_irq(dev->slot, dev->irq_pin);
break;
case 2:
case 5:
/* MIRQ 0 or 1. */
if (irq)
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
else
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
break;
case 3:
/* Native PCI IRQ mode with specified interrupt line. */
if (irq)
picintlevel(1 << dev->irq_line);
else
picintc(1 << dev->irq_line);
break;
case 4:
/* ALi Aladdin Native PCI INTAJ mode. */
if (irq)
pci_set_mirq(channel + 2, dev->irq_level[channel]);
else
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
break;
case 0:
default:
/* Legacy IRQ mode. */
if (irq)
picint(1 << (14 + channel));
else
picintc(1 << (14 + channel));
break;
case 1:
/* Native PCI IRQ mode with interrupt pin. */
if (irq)
pci_set_irq(dev->slot, dev->irq_pin);
else
pci_clear_irq(dev->slot, dev->irq_pin);
break;
case 2:
case 5:
/* MIRQ 0 or 1. */
if (irq)
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
else
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
break;
case 3:
/* Native PCI IRQ mode with specified interrupt line. */
if (irq)
picintlevel(1 << dev->irq_line);
else
picintc(1 << dev->irq_line);
break;
case 4:
/* ALi Aladdin Native PCI INTAJ mode. */
if (irq)
pci_set_mirq(channel + 2, dev->irq_level[channel]);
else
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
break;
}
}
void
sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
{
if (dev->enabled) {
io_removehandler(old_base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
io_removehandler(old_base, 0x08,
sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl,
sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel,
dev);
dev->enabled = 0;
dev->enabled = 0;
}
dev->command = 0x00;
dev->status = 0x00;
dev->status = 0x00;
dev->ptr = dev->ptr_cur = 0x00000000;
dev->addr = 0x00000000;
dev->ptr0 = 0x00;
dev->addr = 0x00000000;
dev->ptr0 = 0x00;
dev->count = dev->eot = 0x00000000;
ide_pri_disable();
ide_sec_disable();
}
static void
sff_reset(void *p)
{
@@ -467,116 +451,107 @@ sff_reset(void *p)
#endif
for (i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
}
for (i = 0; i < ZIP_NUM; i++) {
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
sff_bus_master_set_irq(0x00, p);
sff_bus_master_set_irq(0x01, p);
}
void
sff_set_slot(sff8038i_t *dev, int slot)
{
dev->slot = slot;
}
void
sff_set_irq_line(sff8038i_t *dev, int irq_line)
{
dev->irq_line = irq_line;
}
void
sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level)
{
dev->irq_level[channel] = 0;
}
void
sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
{
dev->irq_mode[channel] = irq_mode;
switch (dev->irq_mode[channel]) {
case 0:
default:
/* Legacy IRQ mode. */
sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel);
break;
case 1:
/* Native PCI IRQ mode with interrupt pin. */
sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin);
break;
case 2:
case 5:
/* MIRQ 0 or 1. */
sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1);
break;
case 3:
/* Native PCI IRQ mode with specified interrupt line. */
sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line);
break;
case 4:
/* ALi Aladdin Native PCI INTAJ mode. */
sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel);
break;
case 0:
default:
/* Legacy IRQ mode. */
sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel);
break;
case 1:
/* Native PCI IRQ mode with interrupt pin. */
sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin);
break;
case 2:
case 5:
/* MIRQ 0 or 1. */
sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1);
break;
case 3:
/* Native PCI IRQ mode with specified interrupt line. */
sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line);
break;
case 4:
/* ALi Aladdin Native PCI INTAJ mode. */
sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel);
break;
}
}
void
sff_set_irq_pin(sff8038i_t *dev, int irq_pin)
{
dev->irq_pin = irq_pin;
}
static void
sff_close(void *p)
{
sff8038i_t *dev = (sff8038i_t *)p;
sff8038i_t *dev = (sff8038i_t *) p;
free(dev);
next_id--;
if (next_id < 0)
next_id = 0;
next_id = 0;
}
static void
*sff_init(const device_t *info)
*
sff_init(const device_t *info)
{
sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t));
memset(dev, 0, sizeof(sff8038i_t));
/* Make sure to only add IDE once. */
if (next_id == 0)
device_add(&ide_pci_2ch_device);
device_add(&ide_pci_2ch_device);
ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev);
dev->slot = 7;
dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */
dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
dev->slot = 7;
dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */
dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
dev->irq_level[0] = dev->irq_level[1] = 0;
next_id++;
@@ -584,17 +559,16 @@ static void
return dev;
}
const device_t sff8038i_device =
{
.name = "SFF-8038i IDE Bus Master",
const device_t sff8038i_device = {
.name = "SFF-8038i IDE Bus Master",
.internal_name = "sff8038i",
.flags = DEVICE_PCI,
.local = 0,
.init = sff_init,
.close = sff_close,
.reset = sff_reset,
.flags = DEVICE_PCI,
.local = 0,
.init = sff_init,
.close = sff_close,
.reset = sff_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -44,90 +44,85 @@
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin"
#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin"
#define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN"
#define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin"
#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin"
#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin"
#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin"
#define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN"
#define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin"
#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin"
typedef struct {
void *ide_board;
uint8_t data_high;
rom_t bios_rom;
void *ide_board;
uint8_t data_high;
rom_t bios_rom;
} xtide_t;
static void
xtide_write(uint16_t port, uint8_t val, void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
xtide_t *xtide = (xtide_t *) priv;
switch (port & 0xf) {
case 0x0:
ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board);
return;
case 0x0:
ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board);
return;
case 0x1:
case 0x2:
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
ide_writeb((port & 0xf), val, xtide->ide_board);
return;
case 0x1:
case 0x2:
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
ide_writeb((port & 0xf), val, xtide->ide_board);
return;
case 0x8:
xtide->data_high = val;
return;
case 0x8:
xtide->data_high = val;
return;
case 0xe:
ide_write_devctl(0x0, val, xtide->ide_board);
return;
case 0xe:
ide_write_devctl(0x0, val, xtide->ide_board);
return;
}
}
static uint8_t
xtide_read(uint16_t port, void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
xtide_t *xtide = (xtide_t *) priv;
uint16_t tempw = 0xffff;
switch (port & 0xf) {
case 0x0:
tempw = ide_readw(0x0, xtide->ide_board);
xtide->data_high = tempw >> 8;
break;
case 0x0:
tempw = ide_readw(0x0, xtide->ide_board);
xtide->data_high = tempw >> 8;
break;
case 0x1:
case 0x2:
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
tempw = ide_readb((port & 0xf), xtide->ide_board);
break;
case 0x1:
case 0x2:
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
tempw = ide_readb((port & 0xf), xtide->ide_board);
break;
case 0x8:
tempw = xtide->data_high;
break;
case 0x8:
tempw = xtide->data_high;
break;
case 0xe:
tempw = ide_read_alt_status(0x0, xtide->ide_board);
break;
case 0xe:
tempw = ide_read_alt_status(0x0, xtide->ide_board);
break;
default:
break;
default:
break;
}
return(tempw & 0xff);
return (tempw & 0xff);
}
static void *
xtide_init(const device_t *info)
{
@@ -136,25 +131,23 @@ xtide_init(const device_t *info)
memset(xtide, 0x00, sizeof(xtide_t));
rom_init(&xtide->bios_rom, ROM_PATH_XT,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
xtide->ide_board = ide_xtide_init();
io_sethandler(0x0300, 16,
xtide_read, NULL, NULL,
xtide_write, NULL, NULL, xtide);
xtide_read, NULL, NULL,
xtide_write, NULL, NULL, xtide);
return(xtide);
return (xtide);
}
static int
xtide_available(void)
{
return(rom_present(ROM_PATH_XT));
return (rom_present(ROM_PATH_XT));
}
static void *
xtide_at_init(const device_t *info)
{
@@ -163,33 +156,30 @@ xtide_at_init(const device_t *info)
memset(xtide, 0x00, sizeof(xtide_t));
if (info->local == 1) {
rom_init(&xtide->bios_rom, ROM_PATH_AT_386,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&xtide->bios_rom, ROM_PATH_AT_386,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
} else {
rom_init(&xtide->bios_rom, ROM_PATH_AT,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&xtide->bios_rom, ROM_PATH_AT,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
}
device_add(&ide_isa_2ch_device);
return(xtide);
return (xtide);
}
static int
xtide_at_available(void)
{
return(rom_present(ROM_PATH_AT));
return (rom_present(ROM_PATH_AT));
}
static int
xtide_at_386_available(void)
{
return(rom_present(ROM_PATH_AT_386));
return (rom_present(ROM_PATH_AT_386));
}
static void *
xtide_acculogic_init(const device_t *info)
{
@@ -198,36 +188,33 @@ xtide_acculogic_init(const device_t *info)
memset(xtide, 0x00, sizeof(xtide_t));
rom_init(&xtide->bios_rom, ROM_PATH_PS2,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
xtide->ide_board = ide_xtide_init();
io_sethandler(0x0360, 16,
xtide_read, NULL, NULL,
xtide_write, NULL, NULL, xtide);
xtide_read, NULL, NULL,
xtide_write, NULL, NULL, xtide);
return(xtide);
return (xtide);
}
static int
xtide_acculogic_available(void)
{
return(rom_present(ROM_PATH_PS2));
return (rom_present(ROM_PATH_PS2));
}
static void
xtide_close(void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
xtide_t *xtide = (xtide_t *) priv;
free(xtide);
ide_xtide_close();
}
static void *
xtide_at_ps2_init(const device_t *info)
{
@@ -236,95 +223,93 @@ xtide_at_ps2_init(const device_t *info)
memset(xtide, 0x00, sizeof(xtide_t));
rom_init(&xtide->bios_rom, ROM_PATH_PS2AT,
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
device_add(&ide_isa_2ch_device);
return(xtide);
return (xtide);
}
static int
xtide_at_ps2_available(void)
{
return(rom_present(ROM_PATH_PS2AT));
return (rom_present(ROM_PATH_PS2AT));
}
static void
xtide_at_close(void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
xtide_t *xtide = (xtide_t *) priv;
free(xtide);
}
const device_t xtide_device = {
.name = "PC/XT XTIDE",
.name = "PC/XT XTIDE",
.internal_name = "xtide",
.flags = DEVICE_ISA,
.local = 0,
.init = xtide_init,
.close = xtide_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = 0,
.init = xtide_init,
.close = xtide_close,
.reset = NULL,
{ .available = xtide_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t xtide_at_device = {
.name = "PC/AT XTIDE",
.name = "PC/AT XTIDE",
.internal_name = "xtide_at",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0,
.init = xtide_at_init,
.close = xtide_at_close,
.reset = NULL,
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0,
.init = xtide_at_init,
.close = xtide_at_close,
.reset = NULL,
{ .available = xtide_at_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t xtide_at_386_device = {
.name = "PC/AT XTIDE (386)",
.name = "PC/AT XTIDE (386)",
.internal_name = "xtide_at_386",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 1,
.init = xtide_at_init,
.close = xtide_at_close,
.reset = NULL,
.flags = DEVICE_ISA | DEVICE_AT,
.local = 1,
.init = xtide_at_init,
.close = xtide_at_close,
.reset = NULL,
{ .available = xtide_at_386_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t xtide_acculogic_device = {
.name = "Acculogic XT IDE",
.name = "Acculogic XT IDE",
.internal_name = "xtide_acculogic",
.flags = DEVICE_ISA,
.local = 0,
.init = xtide_acculogic_init,
.close = xtide_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = 0,
.init = xtide_acculogic_init,
.close = xtide_close,
.reset = NULL,
{ .available = xtide_acculogic_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t xtide_at_ps2_device = {
.name = "PS/2 AT XTIDE (1.1.5)",
.name = "PS/2 AT XTIDE (1.1.5)",
.internal_name = "xtide_at_ps2",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0,
.init = xtide_at_ps2_init,
.close = xtide_at_close,
.reset = NULL,
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0,
.init = xtide_at_ps2_init,
.close = xtide_at_close,
.reset = NULL,
{ .available = xtide_at_ps2_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -31,12 +31,9 @@
#include <86box/video.h>
#include "cpu.h"
#define HDD_OVERHEAD_TIME 50.0
hard_disk_t hdd[HDD_NUM];
hard_disk_t hdd[HDD_NUM];
int
hdd_init(void)
@@ -44,122 +41,119 @@ hdd_init(void)
/* Clear all global data. */
memset(hdd, 0x00, sizeof(hdd));
return(0);
return (0);
}
int
hdd_string_to_bus(char *str, int cdrom)
{
if (! strcmp(str, "none"))
return(HDD_BUS_DISABLED);
if (!strcmp(str, "none"))
return (HDD_BUS_DISABLED);
if (! strcmp(str, "mfm") || ! strcmp(str, "rll")) {
if (cdrom) {
if (!strcmp(str, "mfm") || !strcmp(str, "rll")) {
if (cdrom) {
no_cdrom:
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099);
return(0);
}
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099);
return (0);
}
return(HDD_BUS_MFM);
return (HDD_BUS_MFM);
}
/* FIXME: delete 'rll' in a year or so.. --FvK */
if (!strcmp(str, "esdi") || !strcmp(str, "rll")) {
if (cdrom) goto no_cdrom;
if (cdrom)
goto no_cdrom;
return(HDD_BUS_ESDI);
return (HDD_BUS_ESDI);
}
if (! strcmp(str, "ide_pio_only"))
return(HDD_BUS_IDE);
if (!strcmp(str, "ide_pio_only"))
return (HDD_BUS_IDE);
if (! strcmp(str, "ide"))
return(HDD_BUS_IDE);
if (!strcmp(str, "ide"))
return (HDD_BUS_IDE);
if (! strcmp(str, "atapi_pio_only"))
return(HDD_BUS_ATAPI);
if (!strcmp(str, "atapi_pio_only"))
return (HDD_BUS_ATAPI);
if (! strcmp(str, "atapi"))
return(HDD_BUS_ATAPI);
if (!strcmp(str, "atapi"))
return (HDD_BUS_ATAPI);
if (! strcmp(str, "eide"))
return(HDD_BUS_IDE);
if (!strcmp(str, "eide"))
return (HDD_BUS_IDE);
if (! strcmp(str, "xta"))
return(HDD_BUS_XTA);
if (!strcmp(str, "xta"))
return (HDD_BUS_XTA);
if (! strcmp(str, "atide"))
return(HDD_BUS_IDE);
if (!strcmp(str, "atide"))
return (HDD_BUS_IDE);
if (! strcmp(str, "ide_pio_and_dma"))
return(HDD_BUS_IDE);
if (!strcmp(str, "ide_pio_and_dma"))
return (HDD_BUS_IDE);
if (! strcmp(str, "atapi_pio_and_dma"))
return(HDD_BUS_ATAPI);
if (!strcmp(str, "atapi_pio_and_dma"))
return (HDD_BUS_ATAPI);
if (! strcmp(str, "scsi"))
return(HDD_BUS_SCSI);
if (!strcmp(str, "scsi"))
return (HDD_BUS_SCSI);
return(0);
return (0);
}
char *
hdd_bus_to_string(int bus, int cdrom)
{
char *s = "none";
switch (bus) {
case HDD_BUS_DISABLED:
default:
break;
case HDD_BUS_DISABLED:
default:
break;
case HDD_BUS_MFM:
s = "mfm";
break;
case HDD_BUS_MFM:
s = "mfm";
break;
case HDD_BUS_XTA:
s = "xta";
break;
case HDD_BUS_XTA:
s = "xta";
break;
case HDD_BUS_ESDI:
s = "esdi";
break;
case HDD_BUS_ESDI:
s = "esdi";
break;
case HDD_BUS_IDE:
s = "ide";
break;
case HDD_BUS_IDE:
s = "ide";
break;
case HDD_BUS_ATAPI:
s = "atapi";
break;
case HDD_BUS_ATAPI:
s = "atapi";
break;
case HDD_BUS_SCSI:
s = "scsi";
break;
case HDD_BUS_SCSI:
s = "scsi";
break;
}
return(s);
return (s);
}
int
hdd_is_valid(int c)
{
if (hdd[c].bus == HDD_BUS_DISABLED)
return(0);
return (0);
if (strlen(hdd[c].fn) == 0)
return(0);
return (0);
if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0))
return(0);
if ((hdd[c].tracks == 0) || (hdd[c].hpc == 0) || (hdd[c].spt == 0))
return (0);
return(1);
return (1);
}
double
hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time)
{
@@ -168,121 +162,118 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_
hdd_zone_t *zone = NULL;
for (int i = 0; i < hdd->num_zones; i++) {
zone = &hdd->zones[i];
if (zone->end_sector >= dst_addr)
break;
zone = &hdd->zones[i];
if (zone->end_sector >= dst_addr)
break;
}
double continuous_times[2][2] = { { hdd->head_switch_usec, hdd->cyl_switch_usec },
{ zone->sector_time_usec, zone->sector_time_usec } };
double continuous_times[2][2] = {
{hdd->head_switch_usec, hdd->cyl_switch_usec },
{ zone->sector_time_usec, zone->sector_time_usec}
};
double times[2] = { HDD_OVERHEAD_TIME, hdd->avg_rotation_lat_usec };
uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track);
uint32_t new_cylinder = new_track / hdd->phy_heads;
uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder);
uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track);
uint32_t new_cylinder = new_track / hdd->phy_heads;
uint32_t cylinder_diff = abs((int) hdd->cur_cylinder - (int) new_cylinder);
bool sequential = dst_addr == hdd->cur_addr + 1;
continuous = continuous && sequential;
continuous = continuous && sequential;
double seek_time = 0.0;
if (continuous)
seek_time = continuous_times[new_track == hdd->cur_track][!!cylinder_diff];
seek_time = continuous_times[new_track == hdd->cur_track][!!cylinder_diff];
else {
if (!cylinder_diff)
seek_time = times[operation != HDD_OP_SEEK];
else {
seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl) +
((operation != HDD_OP_SEEK) * hdd->avg_rotation_lat_usec);
}
if (!cylinder_diff)
seek_time = times[operation != HDD_OP_SEEK];
else {
seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double) cylinder_diff / (double) hdd->phy_cyl) + ((operation != HDD_OP_SEEK) * hdd->avg_rotation_lat_usec);
}
}
if (!max_seek_time || seek_time <= max_seek_time) {
hdd->cur_addr = dst_addr;
hdd->cur_track = new_track;
hdd->cur_cylinder = new_cylinder;
hdd->cur_addr = dst_addr;
hdd->cur_track = new_track;
hdd->cur_cylinder = new_cylinder;
}
return seek_time;
}
static void
hdd_readahead_update(hard_disk_t *hdd)
{
uint64_t elapsed_cycles;
double elapsed_us, seek_time;
double elapsed_us, seek_time;
uint32_t max_read_ahead, i;
uint32_t space_needed;
hdd_cache_t *cache = &hdd->cache;
if (cache->ra_ongoing) {
hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment];
hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment];
elapsed_cycles = tsc - cache->ra_start_time;
elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
/* Do not overwrite data not yet read by host */
max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
elapsed_cycles = tsc - cache->ra_start_time;
elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0;
/* Do not overwrite data not yet read by host */
max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
seek_time = 0.0;
seek_time = 0.0;
for (i = 0; i < max_read_ahead; i++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
for (i = 0; i < max_read_ahead; i++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
segment->ra_addr++;
}
segment->ra_addr++;
}
if (segment->ra_addr > segment->lba_addr + cache->segment_size) {
space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
if (segment->ra_addr > segment->lba_addr + cache->segment_size) {
space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
}
}
static double
hdd_writecache_flush(hard_disk_t *hdd)
{
double seek_time = 0.0;
while (hdd->cache.write_pending) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
hdd->cache.write_pending--;
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
hdd->cache.write_pending--;
}
return seek_time;
}
static void
hdd_writecache_update(hard_disk_t *hdd)
{
uint64_t elapsed_cycles;
double elapsed_us, seek_time;
double elapsed_us, seek_time;
if (hdd->cache.write_pending) {
elapsed_cycles = tsc - hdd->cache.write_start_time;
elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
seek_time = 0.0;
elapsed_cycles = tsc - hdd->cache.write_start_time;
elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0;
seek_time = 0.0;
while (hdd->cache.write_pending) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
while (hdd->cache.write_pending) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
hdd->cache.write_addr++;
hdd->cache.write_pending--;
}
hdd->cache.write_addr++;
hdd->cache.write_pending--;
}
}
}
double
hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
{
double seek_time = 0.0;
double seek_time = 0.0;
uint32_t flush_needed;
if (!hdd->speed_preset)
@@ -294,31 +285,30 @@ hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
hdd->cache.ra_ongoing = 0;
if (hdd->cache.write_pending && (addr != (hdd->cache.write_addr + hdd->cache.write_pending))) {
/* New request is not sequential to existing cache, need to flush it */
seek_time += hdd_writecache_flush(hdd);
/* New request is not sequential to existing cache, need to flush it */
seek_time += hdd_writecache_flush(hdd);
}
if (!hdd->cache.write_pending) {
/* Cache is empty */
hdd->cache.write_addr = addr;
/* Cache is empty */
hdd->cache.write_addr = addr;
}
hdd->cache.write_pending += len;
if (hdd->cache.write_pending > hdd->cache.write_size) {
/* If request is bigger than free cache, flush some data first */
flush_needed = hdd->cache.write_pending - hdd->cache.write_size;
for (uint32_t i = 0; i < flush_needed; i++) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
}
/* If request is bigger than free cache, flush some data first */
flush_needed = hdd->cache.write_pending - hdd->cache.write_size;
for (uint32_t i = 0; i < flush_needed; i++) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
}
}
hdd->cache.write_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
hdd->cache.write_start_time = tsc + (uint32_t) (seek_time * cpuclock / 1000000.0);
return seek_time;
}
double
hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
{
@@ -332,159 +322,145 @@ hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
seek_time += hdd_writecache_flush(hdd);
hdd_cache_t *cache = &hdd->cache;
hdd_cache_t *cache = &hdd->cache;
hdd_cache_seg_t *active_seg = &cache->segments[0];
for (uint32_t i = 0; i < cache->num_segments; i++) {
hdd_cache_seg_t *segment = &cache->segments[i];
if (!segment->valid) {
active_seg = segment;
continue;
}
hdd_cache_seg_t *segment = &cache->segments[i];
if (!segment->valid) {
active_seg = segment;
continue;
}
if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) {
/* Cache HIT */
segment->host_addr = addr;
active_seg = segment;
if (addr + len > segment->ra_addr) {
uint32_t need_read = (addr + len) - segment->ra_addr;
for (uint32_t j = 0; j < need_read; j++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0);
segment->ra_addr++;
}
}
if (addr + len > segment->lba_addr + cache->segment_size) {
/* Need to erase some previously cached data */
uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
goto update_lru;
} else {
if (segment->lru > active_seg->lru)
active_seg = segment;
}
if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) {
/* Cache HIT */
segment->host_addr = addr;
active_seg = segment;
if (addr + len > segment->ra_addr) {
uint32_t need_read = (addr + len) - segment->ra_addr;
for (uint32_t j = 0; j < need_read; j++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0);
segment->ra_addr++;
}
}
if (addr + len > segment->lba_addr + cache->segment_size) {
/* Need to erase some previously cached data */
uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
goto update_lru;
} else {
if (segment->lru > active_seg->lru)
active_seg = segment;
}
}
/* Cache MISS */
active_seg->lba_addr = addr;
active_seg->valid = 1;
active_seg->lba_addr = addr;
active_seg->valid = 1;
active_seg->host_addr = addr;
active_seg->ra_addr = addr;
active_seg->ra_addr = addr;
for (uint32_t i = 0; i < len; i++) {
seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0);
active_seg->ra_addr++;
seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0);
active_seg->ra_addr++;
}
update_lru:
for (uint32_t i = 0; i < cache->num_segments; i++)
cache->segments[i].lru++;
cache->segments[i].lru++;
active_seg->lru = 0;
cache->ra_ongoing = 1;
cache->ra_segment = active_seg->id;
cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
cache->ra_ongoing = 1;
cache->ra_segment = active_seg->id;
cache->ra_start_time = tsc + (uint32_t) (seek_time * cpuclock / 1000000.0);
return seek_time;
}
static void
hdd_cache_init(hard_disk_t *hdd)
{
hdd_cache_t *cache = &hdd->cache;
uint32_t i;
uint32_t i;
cache->ra_segment = 0;
cache->ra_ongoing = 0;
cache->ra_segment = 0;
cache->ra_ongoing = 0;
cache->ra_start_time = 0;
for (i = 0; i < cache->num_segments; i++) {
cache->segments[i].valid = 0;
cache->segments[i].lru = 0;
cache->segments[i].id = i;
cache->segments[i].ra_addr = 0;
cache->segments[i].host_addr = 0;
cache->segments[i].valid = 0;
cache->segments[i].lru = 0;
cache->segments[i].id = i;
cache->segments[i].ra_addr = 0;
cache->segments[i].host_addr = 0;
}
}
static void
hdd_zones_init(hard_disk_t *hdd)
{
uint32_t lba = 0, track = 0;
uint32_t i, tracks;
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
uint32_t lba = 0, track = 0;
uint32_t i, tracks;
double revolution_usec = 60.0 / (double) hdd->rpm * 1000000.0;
hdd_zone_t *zone;
for (i = 0; i < hdd->num_zones; i++) {
zone = &hdd->zones[i];
zone->start_sector = lba;
zone->start_track = track;
zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track;
tracks = zone->cylinders * hdd->phy_heads;
lba += tracks * zone->sectors_per_track;
zone->end_sector = lba - 1;
track += tracks - 1;
zone = &hdd->zones[i];
zone->start_sector = lba;
zone->start_track = track;
zone->sector_time_usec = revolution_usec / (double) zone->sectors_per_track;
tracks = zone->cylinders * hdd->phy_heads;
lba += tracks * zone->sectors_per_track;
zone->end_sector = lba - 1;
track += tracks - 1;
}
}
static hdd_preset_t hdd_speed_presets[] = {
{ .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{.name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32},
{ .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500,
.full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600,
.full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500,
.full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
{ .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
{ .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400,
.full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400,
.full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
{ .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
{ .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400,
.full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200,
.full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
};
int
hdd_preset_get_num()
{
return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t);
}
char *
hdd_preset_getname(int preset)
{
return (char *)hdd_speed_presets[preset].name;
return (char *) hdd_speed_presets[preset].name;
}
char *
hdd_preset_get_internal_name(int preset)
{
return (char *)hdd_speed_presets[preset].internal_name;
return (char *) hdd_speed_presets[preset].internal_name;
}
int
hdd_preset_get_from_internal_name(char *s)
{
int c = 0;
for (int i = 0; i < (sizeof(hdd_speed_presets) / sizeof(hdd_preset_t)); i++) {
if (!strcmp((char *)hdd_speed_presets[c].internal_name, s))
if (!strcmp((char *) hdd_speed_presets[c].internal_name, s))
return c;
c++;
}
@@ -492,18 +468,17 @@ hdd_preset_get_from_internal_name(char *s)
return 0;
}
void
hdd_preset_apply(int hdd_id)
{
hard_disk_t *hd = &hdd[hdd_id];
double revolution_usec, zone_percent;
uint32_t disk_sectors, sectors_per_surface, cylinders, cylinders_per_zone;
uint32_t total_sectors = 0, i;
uint32_t spt, zone_sectors;
double revolution_usec, zone_percent;
uint32_t disk_sectors, sectors_per_surface, cylinders, cylinders_per_zone;
uint32_t total_sectors = 0, i;
uint32_t spt, zone_sectors;
if (hd->speed_preset >= hdd_preset_get_num())
hd->speed_preset = 0;
hd->speed_preset = 0;
hdd_preset_t *preset = &hdd_speed_presets[hd->speed_preset];
@@ -512,42 +487,42 @@ hdd_preset_apply(int hdd_id)
hd->max_multiple_block = preset->max_multiple;
if (!hd->speed_preset)
return;
return;
hd->phy_heads = preset->heads;
hd->rpm = preset->rpm;
hd->rpm = preset->rpm;
revolution_usec = 60.0 / (double)hd->rpm * 1000000.0;
revolution_usec = 60.0 / (double) hd->rpm * 1000000.0;
hd->avg_rotation_lat_usec = revolution_usec / 2;
hd->full_stroke_usec = preset->full_stroke_ms * 1000;
hd->head_switch_usec = preset->track_seek_ms * 1000;
hd->cyl_switch_usec = preset->track_seek_ms * 1000;
hd->full_stroke_usec = preset->full_stroke_ms * 1000;
hd->head_switch_usec = preset->track_seek_ms * 1000;
hd->cyl_switch_usec = preset->track_seek_ms * 1000;
hd->cache.write_size = 64;
hd->num_zones = preset->zones;
disk_sectors = hd->tracks * hd->hpc * hd->spt;
sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hd->phy_heads);
cylinders = (uint32_t)ceil((double)sectors_per_surface / (double)preset->avg_spt);
hd->phy_cyl = cylinders;
cylinders_per_zone = cylinders / preset->zones;
disk_sectors = hd->tracks * hd->hpc * hd->spt;
sectors_per_surface = (uint32_t) ceil((double) disk_sectors / (double) hd->phy_heads);
cylinders = (uint32_t) ceil((double) sectors_per_surface / (double) preset->avg_spt);
hd->phy_cyl = cylinders;
cylinders_per_zone = cylinders / preset->zones;
for (i = 0; i < preset->zones; i++) {
zone_percent = i * 100 / (double)preset->zones;
zone_percent = i * 100 / (double) preset->zones;
if (i < preset->zones - 1) {
/* Function for realistic zone sector density */
double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48;
spt = (uint32_t)ceil((double)preset->avg_spt * spt_percent / 100);
} else
spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads));
if (i < preset->zones - 1) {
/* Function for realistic zone sector density */
double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48;
spt = (uint32_t) ceil((double) preset->avg_spt * spt_percent / 100);
} else
spt = (uint32_t) ceil((double) (disk_sectors - total_sectors) / (double) (cylinders_per_zone * preset->heads));
zone_sectors = spt * cylinders_per_zone * preset->heads;
total_sectors += zone_sectors;
zone_sectors = spt * cylinders_per_zone * preset->heads;
total_sectors += zone_sectors;
hd->zones[i].cylinders = cylinders_per_zone;
hd->zones[i].sectors_per_track = spt;
hd->zones[i].cylinders = cylinders_per_zone;
hd->zones[i].sectors_per_track = spt;
}
hdd_zones_init(hd);

File diff suppressed because it is too large Load Diff

View File

@@ -25,8 +25,8 @@
#include <86box/86box.h>
#include <86box/hdd.h>
unsigned int hdd_table[128][3] = {
// clang-format off
{ 306, 4, 17 }, /* 0 - 7 */
{ 615, 2, 17 },
{ 306, 4, 26 },
@@ -170,4 +170,5 @@ unsigned int hdd_table[128][3] = {
{ 1120, 16, 59 },
{ 1054, 16, 63 },
{ 0, 0, 0 }
// clang-format on
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff