clang-format in src/disk/
This commit is contained in:
@@ -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
@@ -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)) {
|
||||
|
3731
src/disk/hdc_ide.c
3731
src/disk/hdc_ide.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
};
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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
1370
src/disk/hdc_xta.c
1370
src/disk/hdc_xta.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
};
|
||||
|
459
src/disk/hdd.c
459
src/disk/hdd.c
@@ -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
@@ -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
|
||||
};
|
||||
|
2247
src/disk/mo.c
2247
src/disk/mo.c
File diff suppressed because it is too large
Load Diff
2470
src/disk/zip.c
2470
src/disk/zip.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user