IDE and CMD-64x fixes, including IDE initialization improvements and CMD-648 option ROM support.
This commit is contained in:
@@ -1449,6 +1449,8 @@ pc_reset_hard_init(void)
|
|||||||
scsi_reset();
|
scsi_reset();
|
||||||
scsi_device_init();
|
scsi_device_init();
|
||||||
|
|
||||||
|
ide_hard_reset();
|
||||||
|
|
||||||
/* Initialize the actual machine and its basic modules. */
|
/* Initialize the actual machine and its basic modules. */
|
||||||
machine_init();
|
machine_init();
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ static uint8_t ide_qua_pnp_rom[] = {
|
|||||||
0x79, 0x00
|
0x79, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
ide_t *ide_drives[IDE_NUM];
|
ide_t *ide_drives[IDE_NUM] = { 0 };
|
||||||
|
|
||||||
static void ide_atapi_callback(ide_t *ide);
|
static void ide_atapi_callback(ide_t *ide);
|
||||||
static void ide_callback(void *priv);
|
static void ide_callback(void *priv);
|
||||||
@@ -2826,20 +2826,23 @@ ide_board_close(int board)
|
|||||||
|
|
||||||
ide_log("ide_board_close(%i)\n", board);
|
ide_log("ide_board_close(%i)\n", board);
|
||||||
|
|
||||||
if ((ide_boards[board] == NULL) || !ide_boards[board]->inited)
|
if (ide_boards[board] == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_log("IDE: Closing board %i...\n", board);
|
ide_log("IDE: Closing board %i...\n", board);
|
||||||
|
|
||||||
timer_stop(&ide_boards[board]->timer);
|
if (ide_boards[board]->inited) {
|
||||||
|
timer_stop(&ide_boards[board]->timer);
|
||||||
|
|
||||||
ide_clear_bus_master(board);
|
ide_clear_bus_master(board);
|
||||||
|
}
|
||||||
|
|
||||||
/* Close hard disk image files (if previously open) */
|
/* Close hard disk image files (if previously open) */
|
||||||
for (uint8_t d = 0; d < 2; d++) {
|
for (uint8_t d = 0; d < 2; d++) {
|
||||||
c = (board << 1) + d;
|
c = (board << 1) + d;
|
||||||
|
|
||||||
ide_boards[board]->ide[d] = NULL;
|
if (ide_boards[board]->inited)
|
||||||
|
ide_boards[board]->ide[d] = NULL;
|
||||||
|
|
||||||
dev = ide_drives[c];
|
dev = ide_drives[c];
|
||||||
|
|
||||||
@@ -3263,6 +3266,16 @@ ide_close(UNUSED(void *priv))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ide_hard_reset(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < IDE_BUS_MAX; i++)
|
||||||
|
ide_boards[i] = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < IDE_NUM; i++)
|
||||||
|
ide_drives[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
mcide_mca_read(const int port, void *priv)
|
mcide_mca_read(const int port, void *priv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,19 +35,22 @@
|
|||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
#include <86box/hdc_ide_sff8038i.h>
|
#include <86box/hdc_ide_sff8038i.h>
|
||||||
#include <86box/rdisk.h>
|
#include <86box/rdisk.h>
|
||||||
|
#include <86box/rom.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
#include <86box/scsi_disk.h>
|
#include <86box/scsi_disk.h>
|
||||||
#include <86box/mo.h>
|
#include <86box/mo.h>
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
|
||||||
#define CMD_TYPE_646 0x000000
|
#define CMD_TYPE_646 0x000000
|
||||||
#define CMD_TYPE_648 0x100000
|
#define CMD_TYPE_648 0x100000
|
||||||
|
|
||||||
#define CMD648_JP7 0x200000 /* Reload subsystem ID on reset. */
|
#define CMD648_JP7 0x200000 /* Reload subsystem ID on reset. */
|
||||||
#define CMD648_RAID 0x400000
|
#define CMD648_RAID 0x400000
|
||||||
|
|
||||||
#define CMD64X_ONBOARD 0x800000
|
#define CMD64X_ONBOARD 0x800000
|
||||||
|
|
||||||
|
#define CMD648_BIOS_FILE "roms/hdd/ide/648_1910.bin"
|
||||||
|
|
||||||
typedef struct cmd646_t {
|
typedef struct cmd646_t {
|
||||||
uint8_t vlb_idx;
|
uint8_t vlb_idx;
|
||||||
@@ -58,11 +61,15 @@ typedef struct cmd646_t {
|
|||||||
uint8_t regs[256];
|
uint8_t regs[256];
|
||||||
|
|
||||||
uint32_t local;
|
uint32_t local;
|
||||||
|
uint32_t rom_addr;
|
||||||
|
|
||||||
int irq_pin;
|
int irq_pin;
|
||||||
|
int has_bios;
|
||||||
|
|
||||||
int irq_mode[2];
|
int irq_mode[2];
|
||||||
|
|
||||||
|
rom_t bios_rom;
|
||||||
|
|
||||||
sff8038i_t *bm[2];
|
sff8038i_t *bm[2];
|
||||||
} cmd646_t;
|
} cmd646_t;
|
||||||
|
|
||||||
@@ -251,19 +258,47 @@ cmd646_bm_read(uint16_t port, uint8_t val, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd646_bios_handler(cmd646_t *dev)
|
||||||
|
{
|
||||||
|
if ((dev->local & CMD_TYPE_648) && dev->has_bios) {
|
||||||
|
uint32_t *addr = (uint32_t *) &(dev->regs[0x30]);
|
||||||
|
|
||||||
|
*addr &= 0xffffc001;
|
||||||
|
dev->rom_addr = *addr & 0xfffffff0;
|
||||||
|
|
||||||
|
cmd646_log("ROM address now: %08X\n", dev->rom_addr);
|
||||||
|
|
||||||
|
if ((dev->regs[0x04] & 0x02) && (*addr & 0x00000001))
|
||||||
|
mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr, 0x00004000);
|
||||||
|
else
|
||||||
|
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
cmd646_t *dev = (cmd646_t *) priv;
|
cmd646_t *dev = (cmd646_t *) priv;
|
||||||
|
int reg50 = dev->regs[0x50];
|
||||||
|
|
||||||
|
if ((dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04) && (dev->regs[0x0b] == 0x01))
|
||||||
|
reg50 |= 0x40;
|
||||||
|
|
||||||
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val);
|
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val);
|
||||||
|
|
||||||
if (func == 0x00)
|
if (func == 0x00)
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x04:
|
case 0x04:
|
||||||
dev->regs[addr] = (val & 0x45);
|
if (dev->has_bios)
|
||||||
|
dev->regs[addr] = (val & 0x47);
|
||||||
|
else
|
||||||
|
dev->regs[addr] = (val & 0x45);
|
||||||
|
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
cmd646_ide_bm_handlers(dev);
|
cmd646_ide_bm_handlers(dev);
|
||||||
|
|
||||||
|
cmd646_bios_handler(dev);
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07:
|
||||||
dev->regs[addr] &= ~(val & 0xb1);
|
dev->regs[addr] &= ~(val & 0xb1);
|
||||||
@@ -272,7 +307,6 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
if (!(dev->local & CMD_TYPE_648) ||
|
if (!(dev->local & CMD_TYPE_648) ||
|
||||||
((dev->regs[0x0a] == 0x01) && (dev->regs[0x0b] == 0x01))) {
|
((dev->regs[0x0a] == 0x01) && (dev->regs[0x0b] == 0x01))) {
|
||||||
if ((dev->regs[addr] & 0x0a) == 0x0a) {
|
if ((dev->regs[addr] & 0x0a) == 0x0a) {
|
||||||
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
|
|
||||||
dev->regs[addr] = (dev->regs[addr] & 0x8a) | (val & 0x05);
|
dev->regs[addr] = (dev->regs[addr] & 0x8a) | (val & 0x05);
|
||||||
dev->irq_mode[0] = !!(val & 0x01);
|
dev->irq_mode[0] = !!(val & 0x01);
|
||||||
dev->irq_mode[1] = !!(val & 0x04);
|
dev->irq_mode[1] = !!(val & 0x04);
|
||||||
@@ -287,49 +321,49 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x10] = (val & 0xf8) | 1;
|
dev->regs[0x10] = (val & 0xf8) | 1;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x11] = val;
|
dev->regs[0x11] = val;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x14] = (val & 0xfc) | 1;
|
dev->regs[0x14] = (val & 0xfc) | 1;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x15:
|
case 0x15:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x15] = val;
|
dev->regs[0x15] = val;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case 0x18:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x18] = (val & 0xf8) | 1;
|
dev->regs[0x18] = (val & 0xf8) | 1;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x19:
|
case 0x19:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x19] = val;
|
dev->regs[0x19] = val;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x1c] = (val & 0xfc) | 1;
|
dev->regs[0x1c] = (val & 0xfc) | 1;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (reg50 & 0x40) {
|
||||||
dev->regs[0x1d] = val;
|
dev->regs[0x1d] = val;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
@@ -347,6 +381,12 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
if (dev->local & CMD_TYPE_648)
|
if (dev->local & CMD_TYPE_648)
|
||||||
dev->regs[(addr & 0x0f) | 0x20] = val;
|
dev->regs[(addr & 0x0f) | 0x20] = val;
|
||||||
break;
|
break;
|
||||||
|
case 0x30 ... 0x33:
|
||||||
|
if ((dev->local & CMD_TYPE_648) && dev->has_bios) {
|
||||||
|
dev->regs[addr] = val;
|
||||||
|
cmd646_bios_handler(dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x3c:
|
case 0x3c:
|
||||||
dev->regs[0x3c] = val;
|
dev->regs[0x3c] = val;
|
||||||
break;
|
break;
|
||||||
@@ -422,7 +462,9 @@ cmd646_pci_read(int func, int addr, void *priv)
|
|||||||
if (func == 0x00) {
|
if (func == 0x00) {
|
||||||
ret = dev->regs[addr];
|
ret = dev->regs[addr];
|
||||||
|
|
||||||
if (addr == 0x50)
|
if ((addr == 0x09) && (dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04))
|
||||||
|
ret = 0x00;
|
||||||
|
else if (addr == 0x50)
|
||||||
dev->regs[0x50] &= ~0x04;
|
dev->regs[0x50] &= ~0x04;
|
||||||
else if (addr == 0x57)
|
else if (addr == 0x57)
|
||||||
dev->regs[0x57] &= ~0x10;
|
dev->regs[0x57] &= ~0x10;
|
||||||
@@ -495,11 +537,16 @@ cmd646_reset(void *priv)
|
|||||||
dev->regs[0x04] = 0x00;
|
dev->regs[0x04] = 0x00;
|
||||||
dev->regs[0x06] = 0x80;
|
dev->regs[0x06] = 0x80;
|
||||||
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
|
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
|
||||||
dev->regs[0x09] = dev->local; /* Programming interface */
|
if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) {
|
||||||
if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID))
|
dev->regs[0x09] = 0x00; /* Programming interface */
|
||||||
dev->regs[0x0a] = 0x04; /* RAID controller */
|
dev->regs[0x0a] = 0x04; /* RAID controller */
|
||||||
else
|
|
||||||
|
dev->regs[0x50] = 0x40; /* Enable Base address register R/W;
|
||||||
|
If 0, they return 0 and are read-only 8 */
|
||||||
|
} else {
|
||||||
|
dev->regs[0x09] = dev->local; /* Programming interface */
|
||||||
dev->regs[0x0a] = 0x01; /* IDE controller */
|
dev->regs[0x0a] = 0x01; /* IDE controller */
|
||||||
|
}
|
||||||
dev->regs[0x0b] = 0x01; /* Mass storage controller */
|
dev->regs[0x0b] = 0x01; /* Mass storage controller */
|
||||||
|
|
||||||
if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_JP7))
|
if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_JP7))
|
||||||
@@ -565,6 +612,8 @@ cmd646_reset(void *priv)
|
|||||||
|
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
cmd646_ide_bm_handlers(dev);
|
cmd646_ide_bm_handlers(dev);
|
||||||
|
|
||||||
|
cmd646_bios_handler(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -617,6 +666,14 @@ cmd646_init(const device_t *info)
|
|||||||
if (dev->local & CMD_TYPE_648) {
|
if (dev->local & CMD_TYPE_648) {
|
||||||
sff_set_ven_handlers(dev->bm[0], cmd646_bm_write, cmd646_bm_read, dev);
|
sff_set_ven_handlers(dev->bm[0], cmd646_bm_write, cmd646_bm_read, dev);
|
||||||
sff_set_ven_handlers(dev->bm[1], cmd646_bm_write, cmd646_bm_read, dev);
|
sff_set_ven_handlers(dev->bm[1], cmd646_bm_write, cmd646_bm_read, dev);
|
||||||
|
|
||||||
|
dev->has_bios = device_get_config_int("bios");
|
||||||
|
|
||||||
|
if (dev->has_bios) {
|
||||||
|
rom_init(&dev->bios_rom, CMD648_BIOS_FILE,
|
||||||
|
0x000c8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||||
|
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd646_reset(dev);
|
cmd646_reset(dev);
|
||||||
@@ -628,6 +685,22 @@ cmd646_init(const device_t *info)
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const device_config_t cmd648_config[] = {
|
||||||
|
{
|
||||||
|
.name = "bios",
|
||||||
|
.description = "Enable BIOS",
|
||||||
|
.type = CONFIG_BINARY,
|
||||||
|
.default_string = NULL,
|
||||||
|
.default_int = 0,
|
||||||
|
.file_filter = NULL,
|
||||||
|
.spinner = { 0 },
|
||||||
|
.selection = { { 0 } },
|
||||||
|
.bios = { { 0 } }
|
||||||
|
},
|
||||||
|
{ .name = "", .description = "", .type = CONFIG_END }
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
const device_t ide_cmd646_device = {
|
const device_t ide_cmd646_device = {
|
||||||
.name = "CMD PCI-0646",
|
.name = "CMD PCI-0646",
|
||||||
.internal_name = "ide_cmd646",
|
.internal_name = "ide_cmd646",
|
||||||
@@ -695,7 +768,7 @@ const device_t ide_cmd648_ter_qua_device = {
|
|||||||
.available = NULL,
|
.available = NULL,
|
||||||
.speed_changed = NULL,
|
.speed_changed = NULL,
|
||||||
.force_redraw = NULL,
|
.force_redraw = NULL,
|
||||||
.config = NULL
|
.config = cmd648_config
|
||||||
};
|
};
|
||||||
|
|
||||||
const device_t ide_cmd648_ter_qua_onboard_device = {
|
const device_t ide_cmd648_ter_qua_onboard_device = {
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
|
|||||||
extern uint8_t ide_read_ali_75(void);
|
extern uint8_t ide_read_ali_75(void);
|
||||||
extern uint8_t ide_read_ali_76(void);
|
extern uint8_t ide_read_ali_76(void);
|
||||||
|
|
||||||
|
extern void ide_hard_reset(void);
|
||||||
|
|
||||||
/* Legacy #define's. */
|
/* Legacy #define's. */
|
||||||
#define ide_irq_raise(ide) ide_irq(ide, 1, 1)
|
#define ide_irq_raise(ide) ide_irq(ide, 1, 1)
|
||||||
#define ide_irq_lower(ide) ide_irq(ide, 0, 1)
|
#define ide_irq_lower(ide) ide_irq(ide, 0, 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user