CMD640 improvements.

This commit is contained in:
OBattler
2023-07-22 21:56:02 +02:00
parent 231e640126
commit 4eb1848ea6
2 changed files with 116 additions and 40 deletions

View File

@@ -41,7 +41,7 @@ typedef struct cmd640_t {
uint8_t vlb_idx; uint8_t vlb_idx;
uint8_t id; uint8_t id;
uint8_t in_cfg; uint8_t in_cfg;
uint8_t single_channel; uint8_t channels;
uint8_t pci, regs[256]; uint8_t pci, regs[256];
uint32_t local; uint32_t local;
int slot; int slot;
@@ -89,6 +89,10 @@ cmd640_set_irq(int channel, void *priv)
} }
channel &= 0x01; channel &= 0x01;
if (!(dev->channels & (1 << channel)))
return;
if (irq) { if (irq) {
if (dev->irq_mode[channel] == 1) if (dev->irq_mode[channel] == 1)
pci_set_irq(dev->slot, dev->irq_pin); pci_set_irq(dev->slot, dev->irq_pin);
@@ -108,40 +112,41 @@ cmd640_ide_handlers(cmd640_t *dev)
uint16_t main; uint16_t main;
uint16_t side; uint16_t side;
ide_pri_disable(); if (dev->channels & 0x01) {
ide_pri_disable();
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
} else { } else {
main = 0x1f0; main = 0x1f0;
side = 0x3f6; side = 0x3f6;
}
ide_set_base(0, main);
ide_set_side(0, side);
if (dev->regs[0x04] & 0x01)
ide_pri_enable();
} }
ide_set_base(0, main); if (dev->channels & 0x02) {
ide_set_side(0, side); ide_sec_disable();
if (dev->regs[0x04] & 0x01) if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
ide_pri_enable(); main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
} else {
main = 0x170;
side = 0x376;
}
if (dev->single_channel) ide_set_base(1, main);
return; ide_set_side(1, side);
ide_sec_disable(); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
ide_sec_enable();
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;
} else {
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();
} }
static void static void
@@ -382,8 +387,11 @@ cmd640_reset(void *priv)
mo_reset((scsi_common_t *) mo_drives[i].priv); mo_reset((scsi_common_t *) mo_drives[i].priv);
} }
cmd640_set_irq(0x00, priv); if (dev->channels & 0x01)
cmd640_set_irq(0x01, priv); cmd640_set_irq(0x00, priv);
if (dev->channels & 0x02)
cmd640_set_irq(0x01, priv);
memset(dev->regs, 0x00, sizeof(dev->regs)); memset(dev->regs, 0x00, sizeof(dev->regs));
@@ -429,6 +437,8 @@ cmd640_reset(void *priv)
dev->irq_pin = PCI_INTA; dev->irq_pin = PCI_INTA;
dev->irq_line = 14; dev->irq_line = 14;
} else { } else {
dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */
if ((dev->local & 0xffff) == 0x0078) if ((dev->local & 0xffff) == 0x0078)
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
@@ -461,18 +471,26 @@ cmd640_init(const device_t *info)
dev->pci = !!(info->flags & DEVICE_PCI); dev->pci = !!(info->flags & DEVICE_PCI);
dev->local = info->local; dev->local = info->local;
dev->channels = ((info->local & 0x60000) >> 17) & 0x03;
if (info->flags & DEVICE_PCI) { 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); if (dev->channels & 0x01)
ide_set_bus_master(1, NULL, cmd640_set_irq, dev); ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
if (dev->channels & 0x02)
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
/* The CMD PCI-0640B IDE controller has no DMA capability, /* The CMD PCI-0640B IDE controller has no DMA capability,
so set our devices IDE devices to force ATA-3 (no DMA). */ so set our devices IDE devices to force ATA-3 (no DMA). */
ide_board_set_force_ata3(0, 1); if (dev->channels & 0x01)
ide_board_set_force_ata3(1, 1); ide_board_set_force_ata3(0, 1);
if (dev->channels & 0x02)
ide_board_set_force_ata3(1, 1);
#if 0 #if 0
ide_pri_disable(); ide_pri_disable();
@@ -486,8 +504,6 @@ cmd640_init(const device_t *info)
dev); dev);
} }
dev->single_channel = !!(info->local & 0x20000);
next_id++; next_id++;
cmd640_reset(dev); cmd640_reset(dev);
@@ -499,7 +515,7 @@ const device_t ide_cmd640_vlb_device = {
.name = "CMD PCI-0640B VLB", .name = "CMD PCI-0640B VLB",
.internal_name = "ide_cmd640_vlb", .internal_name = "ide_cmd640_vlb",
.flags = DEVICE_VLB, .flags = DEVICE_VLB,
.local = 0x0078, .local = 0x60078,
.init = cmd640_init, .init = cmd640_init,
.close = cmd640_close, .close = cmd640_close,
.reset = cmd640_reset, .reset = cmd640_reset,
@@ -513,7 +529,63 @@ 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", .internal_name = "ide_cmd640_vlb_178",
.flags = DEVICE_VLB, .flags = DEVICE_VLB,
.local = 0x0178, .local = 0x60178,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_vlb_pri_device = {
.name = "CMD PCI-0640B VLB",
.internal_name = "ide_cmd640_vlb",
.flags = DEVICE_VLB,
.local = 0x20078,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_vlb_pri_178_device = {
.name = "CMD PCI-0640B VLB (Port 178h)",
.internal_name = "ide_cmd640_vlb_178",
.flags = DEVICE_VLB,
.local = 0x20178,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_vlb_sec_device = {
.name = "CMD PCI-0640B VLB",
.internal_name = "ide_cmd640_vlb",
.flags = DEVICE_VLB,
.local = 0x40078,
.init = cmd640_init,
.close = cmd640_close,
.reset = cmd640_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ide_cmd640_vlb_sec_178_device = {
.name = "CMD PCI-0640B VLB (Port 178h)",
.internal_name = "ide_cmd640_vlb_178",
.flags = DEVICE_VLB,
.local = 0x40178,
.init = cmd640_init, .init = cmd640_init,
.close = cmd640_close, .close = cmd640_close,
.reset = cmd640_reset, .reset = cmd640_reset,
@@ -527,7 +599,7 @@ const device_t ide_cmd640_pci_device = {
.name = "CMD PCI-0640B PCI", .name = "CMD PCI-0640B PCI",
.internal_name = "ide_cmd640_pci", .internal_name = "ide_cmd640_pci",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0x0a, .local = 0x6000a,
.init = cmd640_init, .init = cmd640_init,
.close = cmd640_close, .close = cmd640_close,
.reset = cmd640_reset, .reset = cmd640_reset,
@@ -541,7 +613,7 @@ 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", .internal_name = "ide_cmd640_pci_legacy_only",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0x00, .local = 0x60000,
.init = cmd640_init, .init = cmd640_init,
.close = cmd640_close, .close = cmd640_close,
.reset = cmd640_reset, .reset = cmd640_reset,

View File

@@ -62,6 +62,10 @@ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */
extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */
extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */
extern const device_t ide_cmd640_vlb_pri_device; /* CMD PCI-640B VLB (Only primary channel) */
extern const device_t ide_cmd640_vlb_pri_178_device; /* CMD PCI-640B VLB (Only primary channel) (Port 178h) */
extern const device_t ide_cmd640_vlb_sec_device; /* CMD PCI-640B VLB (Only secondary channel) */
extern const device_t ide_cmd640_vlb_sec_178_device; /* CMD PCI-640B VLB (Only secondary channel) (Port 178h) */
extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */
extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */
extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */