clang-format in src/disk/
This commit is contained in:
@@ -29,14 +29,11 @@
|
|||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
|
||||||
int hdc_current;
|
int hdc_current;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_HDC_LOG
|
#ifdef ENABLE_HDC_LOG
|
||||||
int hdc_do_log = ENABLE_HDC_LOG;
|
int hdc_do_log = ENABLE_HDC_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdc_log(const char *fmt, ...)
|
hdc_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -49,13 +46,13 @@ hdc_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define hdc_log(fmt, ...)
|
# define hdc_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
nullhdc_init(const device_t *info)
|
nullhdc_init(const device_t *info)
|
||||||
{
|
{
|
||||||
return(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -66,7 +63,7 @@ nullhdc_close(void *priv)
|
|||||||
static void *
|
static void *
|
||||||
inthdc_init(const device_t *info)
|
inthdc_init(const device_t *info)
|
||||||
{
|
{
|
||||||
return(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -105,7 +102,7 @@ static const device_t hdc_internal_device = {
|
|||||||
static const struct {
|
static const struct {
|
||||||
const device_t *device;
|
const device_t *device;
|
||||||
} controllers[] = {
|
} controllers[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{ &hdc_none_device },
|
{ &hdc_none_device },
|
||||||
{ &hdc_internal_device },
|
{ &hdc_internal_device },
|
||||||
{ &st506_xt_xebec_device },
|
{ &st506_xt_xebec_device },
|
||||||
@@ -133,7 +130,7 @@ static const struct {
|
|||||||
{ &ide_vlb_device },
|
{ &ide_vlb_device },
|
||||||
{ &ide_vlb_2ch_device },
|
{ &ide_vlb_2ch_device },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize the 'hdc_current' value based on configured HDC name. */
|
/* Initialize the 'hdc_current' value based on configured HDC name. */
|
||||||
@@ -146,7 +143,6 @@ hdc_init(void)
|
|||||||
hdd_image_init();
|
hdd_image_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset the HDC, whichever one that is. */
|
/* Reset the HDC, whichever one that is. */
|
||||||
void
|
void
|
||||||
hdc_reset(void)
|
hdc_reset(void)
|
||||||
@@ -165,14 +161,12 @@ hdc_reset(void)
|
|||||||
device_add(&ide_qua_device);
|
device_add(&ide_qua_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
hdc_get_internal_name(int hdc)
|
hdc_get_internal_name(int hdc)
|
||||||
{
|
{
|
||||||
return device_get_internal_name(controllers[hdc].device);
|
return device_get_internal_name(controllers[hdc].device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdc_get_from_internal_name(char *s)
|
hdc_get_from_internal_name(char *s)
|
||||||
{
|
{
|
||||||
@@ -187,36 +181,34 @@ hdc_get_from_internal_name(char *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const device_t *
|
const device_t *
|
||||||
hdc_get_device(int hdc)
|
hdc_get_device(int hdc)
|
||||||
{
|
{
|
||||||
return(controllers[hdc].device);
|
return (controllers[hdc].device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdc_has_config(int hdc)
|
hdc_has_config(int hdc)
|
||||||
{
|
{
|
||||||
const device_t *dev = hdc_get_device(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
|
int
|
||||||
hdc_get_flags(int hdc)
|
hdc_get_flags(int hdc)
|
||||||
{
|
{
|
||||||
return(controllers[hdc].device->flags);
|
return (controllers[hdc].device->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdc_available(int hdc)
|
hdc_available(int hdc)
|
||||||
{
|
{
|
||||||
return(device_available(controllers[hdc].device));
|
return (device_available(controllers[hdc].device));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
|
||||||
#define HDC_TIME 10.0
|
#define HDC_TIME 10.0
|
||||||
#define BIOS_FILE "roms/hdd/esdi_at/62-000279-061.bin"
|
#define BIOS_FILE "roms/hdd/esdi_at/62-000279-061.bin"
|
||||||
|
|
||||||
@@ -71,7 +70,6 @@
|
|||||||
#define CMD_SET_PARAMETERS 0x91
|
#define CMD_SET_PARAMETERS 0x91
|
||||||
#define CMD_READ_PARAMETERS 0xec
|
#define CMD_READ_PARAMETERS 0xec
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int cfg_spt;
|
int cfg_spt;
|
||||||
int cfg_hpc;
|
int cfg_hpc;
|
||||||
@@ -86,7 +84,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
uint8_t error;
|
uint8_t error;
|
||||||
int secount,sector,cylinder,head,cylprecomp;
|
int secount, sector, cylinder, head, cylprecomp;
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
uint8_t fdisk;
|
uint8_t fdisk;
|
||||||
int pos;
|
int pos;
|
||||||
@@ -103,15 +101,12 @@ typedef struct {
|
|||||||
rom_t bios_rom;
|
rom_t bios_rom;
|
||||||
} esdi_t;
|
} esdi_t;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t esdi_read(uint16_t port, void *priv);
|
static uint8_t esdi_read(uint16_t port, void *priv);
|
||||||
static void esdi_write(uint16_t port, uint8_t val, void *priv);
|
static void esdi_write(uint16_t port, uint8_t val, void *priv);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_ESDI_AT_LOG
|
#ifdef ENABLE_ESDI_AT_LOG
|
||||||
int esdi_at_do_log = ENABLE_ESDI_AT_LOG;
|
int esdi_at_do_log = ENABLE_ESDI_AT_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
esdi_at_log(const char *fmt, ...)
|
esdi_at_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -124,10 +119,9 @@ esdi_at_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define esdi_at_log(fmt, ...)
|
# define esdi_at_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
irq_raise(esdi_t *esdi)
|
irq_raise(esdi_t *esdi)
|
||||||
{
|
{
|
||||||
@@ -137,14 +131,12 @@ irq_raise(esdi_t *esdi)
|
|||||||
esdi->irqstat = 1;
|
esdi->irqstat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
irq_lower(esdi_t *esdi)
|
irq_lower(esdi_t *esdi)
|
||||||
{
|
{
|
||||||
picintc(1 << 14);
|
picintc(1 << 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
irq_update(esdi_t *esdi)
|
irq_update(esdi_t *esdi)
|
||||||
{
|
{
|
||||||
@@ -170,7 +162,7 @@ double
|
|||||||
esdi_get_xfer_time(esdi_t *esdi, int size)
|
esdi_get_xfer_time(esdi_t *esdi, int size)
|
||||||
{
|
{
|
||||||
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the sector offset for the current register values. */
|
/* Return the sector offset for the current register values. */
|
||||||
@@ -184,39 +176,36 @@ get_sector(esdi_t *esdi, off64_t *addr)
|
|||||||
|
|
||||||
if (esdi->head > heads) {
|
if (esdi->head > heads) {
|
||||||
esdi_at_log("esdi_get_sector: past end of configured heads\n");
|
esdi_at_log("esdi_get_sector: past end of configured heads\n");
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esdi->sector >= sectors+1) {
|
if (esdi->sector >= sectors + 1) {
|
||||||
esdi_at_log("esdi_get_sector: past end of configured sectors\n");
|
esdi_at_log("esdi_get_sector: past end of configured sectors\n");
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sector = esdi->sector ? esdi->sector : 1;
|
sector = esdi->sector ? esdi->sector : 1;
|
||||||
|
|
||||||
if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) {
|
if (drive->cfg_spt == drive->real_spt && drive->cfg_hpc == drive->real_hpc) {
|
||||||
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) *
|
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors) + (sector - 1);
|
||||||
sectors) + (sector - 1);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* When performing translation, the firmware seems to leave 1
|
* When performing translation, the firmware seems to leave 1
|
||||||
* sector per track inaccessible (spare sector)
|
* sector per track inaccessible (spare sector)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) *
|
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors) + (sector - 1);
|
||||||
sectors) + (sector - 1);
|
|
||||||
|
|
||||||
s = *addr % (drive->real_spt - 1);
|
s = *addr % (drive->real_spt - 1);
|
||||||
h = (*addr / (drive->real_spt - 1)) % drive->real_hpc;
|
h = (*addr / (drive->real_spt - 1)) % drive->real_hpc;
|
||||||
c = (*addr / (drive->real_spt - 1)) / drive->real_hpc;
|
c = (*addr / (drive->real_spt - 1)) / drive->real_hpc;
|
||||||
|
|
||||||
*addr = ((((off64_t)c * drive->real_hpc) + h) * drive->real_spt) + s;
|
*addr = ((((off64_t) c * drive->real_hpc) + h) * drive->real_spt) + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Move to the next sector using CHS addressing. */
|
/* Move to the next sector using CHS addressing. */
|
||||||
static void
|
static void
|
||||||
next_sector(esdi_t *esdi)
|
next_sector(esdi_t *esdi)
|
||||||
@@ -235,11 +224,10 @@ next_sector(esdi_t *esdi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
|
|
||||||
if (port > 0x01f0) {
|
if (port > 0x01f0) {
|
||||||
@@ -261,11 +249,10 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
esdi_write(uint16_t port, uint8_t val, void *priv)
|
esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
double seek_time, xfer_time;
|
double seek_time, xfer_time;
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
|
|
||||||
@@ -317,7 +304,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
esdi->command &= ~0x0f; /*mask off step rate*/
|
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
esdi_set_callback(esdi, 200 * HDC_TIME);
|
esdi_set_callback(esdi, 200 * HDC_TIME);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SEEK:
|
case CMD_SEEK:
|
||||||
@@ -326,7 +313,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
get_sector(esdi, &addr);
|
get_sector(esdi, &addr);
|
||||||
seek_time = hdd_seek_get_time(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, HDD_OP_SEEK, 0, 0.0);
|
seek_time = hdd_seek_get_time(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, HDD_OP_SEEK, 0, 0.0);
|
||||||
esdi_set_callback(esdi, seek_time);
|
esdi_set_callback(esdi, seek_time);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -337,9 +324,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ:
|
case CMD_READ:
|
||||||
case CMD_READ+1:
|
case CMD_READ + 1:
|
||||||
case CMD_READ+2:
|
case CMD_READ + 2:
|
||||||
case CMD_READ+3:
|
case CMD_READ + 3:
|
||||||
esdi->command &= ~0x03;
|
esdi->command &= ~0x03;
|
||||||
if (val & 0x02)
|
if (val & 0x02)
|
||||||
fatal("Read with ECC\n");
|
fatal("Read with ECC\n");
|
||||||
@@ -351,36 +338,36 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1);
|
seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1);
|
||||||
xfer_time = esdi_get_xfer_time(esdi, 1);
|
xfer_time = esdi_get_xfer_time(esdi, 1);
|
||||||
esdi_set_callback(esdi, seek_time + xfer_time);
|
esdi_set_callback(esdi, seek_time + xfer_time);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE:
|
case CMD_WRITE:
|
||||||
case CMD_WRITE+1:
|
case CMD_WRITE + 1:
|
||||||
case CMD_WRITE+2:
|
case CMD_WRITE + 2:
|
||||||
case CMD_WRITE+3:
|
case CMD_WRITE + 3:
|
||||||
esdi->command &= ~0x03;
|
esdi->command &= ~0x03;
|
||||||
if (val & 0x02)
|
if (val & 0x02)
|
||||||
fatal("Write with ECC\n");
|
fatal("Write with ECC\n");
|
||||||
esdi->status = STAT_READY | STAT_DRQ | STAT_DSC;
|
esdi->status = STAT_READY | STAT_DRQ | STAT_DSC;
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
case CMD_VERIFY+1:
|
case CMD_VERIFY + 1:
|
||||||
esdi->command &= ~0x01;
|
esdi->command &= ~0x01;
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
get_sector(esdi, &addr);
|
get_sector(esdi, &addr);
|
||||||
seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1);
|
seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1);
|
||||||
xfer_time = esdi_get_xfer_time(esdi, 1);
|
xfer_time = esdi_get_xfer_time(esdi, 1);
|
||||||
esdi_set_callback(esdi, seek_time + xfer_time);
|
esdi_set_callback(esdi, seek_time + xfer_time);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
esdi->status = STAT_DRQ;
|
esdi->status = STAT_DRQ;
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||||
@@ -391,7 +378,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
|
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
esdi_set_callback(esdi, 200 * HDC_TIME);
|
esdi_set_callback(esdi, 200 * HDC_TIME);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xe0: /*???*/
|
case 0xe0: /*???*/
|
||||||
@@ -429,11 +416,10 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
esdi_readw(uint16_t port, void *priv)
|
esdi_readw(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
|
|
||||||
@@ -448,7 +434,7 @@ esdi_readw(uint16_t port, void *priv)
|
|||||||
esdi->pos += 2;
|
esdi->pos += 2;
|
||||||
|
|
||||||
if (esdi->pos >= 512) {
|
if (esdi->pos >= 512) {
|
||||||
esdi->pos=0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
if (esdi->command == CMD_READ || esdi->command == 0xa0) {
|
if (esdi->command == CMD_READ || esdi->command == 0xa0) {
|
||||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||||
@@ -461,19 +447,18 @@ esdi_readw(uint16_t port, void *priv)
|
|||||||
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
||||||
esdi_set_callback(esdi, seek_time + xfer_time);
|
esdi_set_callback(esdi, seek_time + xfer_time);
|
||||||
} else
|
} else
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(temp);
|
return (temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
esdi_read(uint16_t port, void *priv)
|
esdi_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
uint8_t temp = 0xff;
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
@@ -494,11 +479,11 @@ esdi_read(uint16_t port, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f4: /* cylinder low */
|
case 0x1f4: /* cylinder low */
|
||||||
temp = (uint8_t) (esdi->cylinder&0xff);
|
temp = (uint8_t) (esdi->cylinder & 0xff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f5: /* cylinder high */
|
case 0x1f5: /* cylinder high */
|
||||||
temp = (uint8_t) (esdi->cylinder>>8);
|
temp = (uint8_t) (esdi->cylinder >> 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f6: /* drive/Head */
|
case 0x1f6: /* drive/Head */
|
||||||
@@ -513,20 +498,19 @@ esdi_read(uint16_t port, void *priv)
|
|||||||
|
|
||||||
esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp);
|
esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp);
|
||||||
|
|
||||||
return(temp);
|
return (temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
esdi_callback(void *priv)
|
esdi_callback(void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
double seek_time;
|
double seek_time;
|
||||||
|
|
||||||
if (esdi->reset) {
|
if (esdi->reset) {
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
esdi->error = 1;
|
esdi->error = 1;
|
||||||
esdi->secount = 1;
|
esdi->secount = 1;
|
||||||
esdi->sector = 1;
|
esdi->sector = 1;
|
||||||
@@ -534,7 +518,7 @@ esdi_callback(void *priv)
|
|||||||
esdi->cylinder = 0;
|
esdi->cylinder = 0;
|
||||||
esdi->reset = 0;
|
esdi->reset = 0;
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,96 +526,96 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
switch (esdi->command) {
|
switch (esdi->command) {
|
||||||
case CMD_RESTORE:
|
case CMD_RESTORE:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else {
|
} else {
|
||||||
drive->current_cylinder = 0;
|
drive->current_cylinder = 0;
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
}
|
}
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SEEK:
|
case CMD_SEEK:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else
|
} else
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ:
|
case CMD_READ:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
} else {
|
} else {
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer);
|
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE:
|
case CMD_WRITE:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer);
|
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||||
if (esdi->secount) {
|
if (esdi->secount) {
|
||||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
next_sector(esdi);
|
next_sector(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
} else {
|
} else {
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer);
|
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||||
next_sector(esdi);
|
next_sector(esdi);
|
||||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||||
if (esdi->secount) {
|
if (esdi->secount) {
|
||||||
@@ -640,30 +624,30 @@ esdi_callback(void *priv)
|
|||||||
esdi_set_callback(esdi, seek_time + HDC_TIME);
|
esdi_set_callback(esdi, seek_time + HDC_TIME);
|
||||||
} else {
|
} else {
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
|
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -675,41 +659,41 @@ esdi_callback(void *priv)
|
|||||||
drive = &esdi->drives[esdi->drive_sel];
|
drive = &esdi->drives[esdi->drive_sel];
|
||||||
|
|
||||||
esdi->error = 1; /*no error detected*/
|
esdi->error = 1; /*no error detected*/
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
} else {
|
} else {
|
||||||
drive->cfg_spt = esdi->secount;
|
drive->cfg_spt = esdi->secount;
|
||||||
drive->cfg_hpc = esdi->head+1;
|
drive->cfg_hpc = esdi->head + 1;
|
||||||
|
|
||||||
esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt, drive->cfg_hpc);
|
||||||
|
|
||||||
if (! esdi->secount)
|
if (!esdi->secount)
|
||||||
fatal("WD1007: secount=0\n");
|
fatal("WD1007: secount=0\n");
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_NOP:
|
case CMD_NOP:
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -734,28 +718,28 @@ esdi_callback(void *priv)
|
|||||||
default:
|
default:
|
||||||
esdi_at_log("WD1007: bad read config %02x\n", esdi->cylinder >> 8);
|
esdi_at_log("WD1007: bad read config %02x\n", esdi->cylinder >> 8);
|
||||||
}
|
}
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else {
|
} else {
|
||||||
memset(esdi->buffer, 0x00, 512);
|
memset(esdi->buffer, 0x00, 512);
|
||||||
memset(&esdi->buffer[3], 0xff, 512-6);
|
memset(&esdi->buffer[3], 0xff, 512 - 6);
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||||
}
|
}
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_PARAMETERS:
|
case CMD_READ_PARAMETERS:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
} else {
|
} else {
|
||||||
@@ -783,10 +767,10 @@ esdi_callback(void *priv)
|
|||||||
esdi->buffer[47] = 0; /* sectors per interrupt */
|
esdi->buffer[47] = 0; /* sectors per interrupt */
|
||||||
esdi->buffer[48] = 0; /* can use double word read/write? */
|
esdi->buffer[48] = 0; /* can use double word read/write? */
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -794,21 +778,20 @@ esdi_callback(void *priv)
|
|||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
|
|
||||||
case 0xe8:
|
case 0xe8:
|
||||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn)
|
loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn)
|
||||||
{
|
{
|
||||||
drive_t *drive = &esdi->drives[hdd_num];
|
drive_t *drive = &esdi->drives[hdd_num];
|
||||||
|
|
||||||
if (! hdd_image_load(d)) {
|
if (!hdd_image_load(d)) {
|
||||||
esdi_at_log("WD1007: drive %d not present!\n", d);
|
esdi_at_log("WD1007: drive %d not present!\n", d);
|
||||||
drive->present = 0;
|
drive->present = 0;
|
||||||
return;
|
return;
|
||||||
@@ -823,11 +806,10 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn)
|
|||||||
drive->present = 1;
|
drive->present = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
esdi_rom_write(uint32_t addr, uint8_t val, void *p)
|
esdi_rom_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
rom_t *rom = (rom_t *)p;
|
rom_t *rom = (rom_t *) p;
|
||||||
|
|
||||||
addr &= rom->mask;
|
addr &= rom->mask;
|
||||||
|
|
||||||
@@ -835,7 +817,6 @@ esdi_rom_write(uint32_t addr, uint8_t val, void *p)
|
|||||||
rom->rom[addr] = val;
|
rom->rom[addr] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
wd1007vse1_init(const device_t *info)
|
wd1007vse1_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -845,15 +826,16 @@ wd1007vse1_init(const device_t *info)
|
|||||||
memset(esdi, 0x00, sizeof(esdi_t));
|
memset(esdi, 0x00, sizeof(esdi_t));
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (d=0; d<HDD_NUM; d++) {
|
for (d = 0; d < HDD_NUM; d++) {
|
||||||
if ((hdd[d].bus==HDD_BUS_ESDI) && (hdd[d].esdi_channel<ESDI_NUM)) {
|
if ((hdd[d].bus == HDD_BUS_ESDI) && (hdd[d].esdi_channel < ESDI_NUM)) {
|
||||||
loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn);
|
loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn);
|
||||||
|
|
||||||
if (++c >= ESDI_NUM) break;
|
if (++c >= ESDI_NUM)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esdi->status = STAT_READY|STAT_DSC;
|
esdi->status = STAT_READY | STAT_DSC;
|
||||||
esdi->error = 1;
|
esdi->error = 1;
|
||||||
|
|
||||||
rom_init(&esdi->bios_rom,
|
rom_init(&esdi->bios_rom,
|
||||||
@@ -876,18 +858,17 @@ wd1007vse1_init(const device_t *info)
|
|||||||
|
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
|
|
||||||
return(esdi);
|
return (esdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wd1007vse1_close(void *priv)
|
wd1007vse1_close(void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *) priv;
|
||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
for (d=0; d<2; d++) {
|
for (d = 0; d < 2; d++) {
|
||||||
drive = &esdi->drives[d];
|
drive = &esdi->drives[d];
|
||||||
|
|
||||||
hdd_image_close(drive->hdd_num);
|
hdd_image_close(drive->hdd_num);
|
||||||
@@ -898,11 +879,10 @@ wd1007vse1_close(void *priv)
|
|||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1007vse1_available(void)
|
wd1007vse1_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(BIOS_FILE));
|
return (rom_present(BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
const device_t esdi_at_wd1007vse1_device = {
|
const device_t esdi_at_wd1007vse1_device = {
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ static double
|
|||||||
esdi_mca_get_xfer_time(esdi_t *esdi, int size)
|
esdi_mca_get_xfer_time(esdi_t *esdi, int size)
|
||||||
{
|
{
|
||||||
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
/* 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
|
static void
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
#include <86box/version.h>
|
#include <86box/version.h>
|
||||||
|
|
||||||
|
|
||||||
/* Bits of 'atastat' */
|
/* Bits of 'atastat' */
|
||||||
#define ERR_STAT 0x01 /* Error */
|
#define ERR_STAT 0x01 /* Error */
|
||||||
#define IDX_STAT 0x02 /* Index */
|
#define IDX_STAT 0x02 /* Index */
|
||||||
@@ -110,7 +109,6 @@
|
|||||||
|
|
||||||
#define IDE_TIME 10.0
|
#define IDE_TIME 10.0
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int bit32, cur_dev,
|
int bit32, cur_dev,
|
||||||
irq, inited,
|
irq, inited,
|
||||||
@@ -182,11 +180,9 @@ int ide_ter_enabled = 0, ide_qua_enabled = 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);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_IDE_LOG
|
#ifdef ENABLE_IDE_LOG
|
||||||
int ide_do_log = ENABLE_IDE_LOG;
|
int ide_do_log = ENABLE_IDE_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_log(const char *fmt, ...)
|
ide_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -199,16 +195,15 @@ ide_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define ide_log(fmt, ...)
|
# define ide_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
getstat(ide_t *ide) {
|
getstat(ide_t *ide)
|
||||||
|
{
|
||||||
return ide->atastat;
|
return ide->atastat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ide_t *
|
ide_t *
|
||||||
ide_get_drive(int ch)
|
ide_get_drive(int ch)
|
||||||
{
|
{
|
||||||
@@ -218,7 +213,6 @@ ide_get_drive(int ch)
|
|||||||
return ide_drives[ch];
|
return ide_drives[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
ide_get_xfer_time(ide_t *ide, int size)
|
ide_get_xfer_time(ide_t *ide, int size)
|
||||||
{
|
{
|
||||||
@@ -226,9 +220,9 @@ ide_get_xfer_time(ide_t *ide, int size)
|
|||||||
|
|
||||||
/* We assume that 1 MB = 1000000 B in this case, so we have as
|
/* We assume that 1 MB = 1000000 B in this case, so we have as
|
||||||
many B/us as there are MB/s because 1 s = 1000000 us. */
|
many B/us as there are MB/s because 1 s = 1000000 us. */
|
||||||
switch(ide->mdma_mode & 0x300) {
|
switch (ide->mdma_mode & 0x300) {
|
||||||
case 0x000: /* PIO */
|
case 0x000: /* PIO */
|
||||||
switch(ide->mdma_mode & 0xff) {
|
switch (ide->mdma_mode & 0xff) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
period = (10.0 / 3.0);
|
period = (10.0 / 3.0);
|
||||||
break;
|
break;
|
||||||
@@ -247,7 +241,7 @@ ide_get_xfer_time(ide_t *ide, int size)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x100: /* Single Word DMA */
|
case 0x100: /* Single Word DMA */
|
||||||
switch(ide->mdma_mode & 0xff) {
|
switch (ide->mdma_mode & 0xff) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
period = (25.0 / 12.0);
|
period = (25.0 / 12.0);
|
||||||
break;
|
break;
|
||||||
@@ -260,7 +254,7 @@ ide_get_xfer_time(ide_t *ide, int size)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x200: /* Multiword DMA */
|
case 0x200: /* Multiword DMA */
|
||||||
switch(ide->mdma_mode & 0xff) {
|
switch (ide->mdma_mode & 0xff) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
period = (25.0 / 6.0);
|
period = (25.0 / 6.0);
|
||||||
break;
|
break;
|
||||||
@@ -273,7 +267,7 @@ ide_get_xfer_time(ide_t *ide, int size)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x300: /* Ultra DMA */
|
case 0x300: /* Ultra DMA */
|
||||||
switch(ide->mdma_mode & 0xff) {
|
switch (ide->mdma_mode & 0xff) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
period = (50.0 / 3.0);
|
period = (50.0 / 3.0);
|
||||||
break;
|
break;
|
||||||
@@ -300,7 +294,6 @@ ide_get_xfer_time(ide_t *ide, int size)
|
|||||||
return period * ((double) size); /* multiply by bytes to get period for the entire transfer */
|
return period * ((double) size); /* multiply by bytes to get period for the entire transfer */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
ide_atapi_get_period(uint8_t channel)
|
ide_atapi_get_period(uint8_t channel)
|
||||||
{
|
{
|
||||||
@@ -316,7 +309,6 @@ ide_atapi_get_period(uint8_t channel)
|
|||||||
return ide_get_xfer_time(ide, 1);
|
return ide_get_xfer_time(ide, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_irq_raise(ide_t *ide)
|
ide_irq_raise(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -338,7 +330,6 @@ ide_irq_raise(ide_t *ide)
|
|||||||
ide->service = 1;
|
ide->service = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_irq_lower(ide_t *ide)
|
ide_irq_lower(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -359,7 +350,6 @@ ide_irq_lower(ide_t *ide)
|
|||||||
ide->irqstat = 0;
|
ide->irqstat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_irq_update(ide_t *ide)
|
ide_irq_update(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -386,7 +376,6 @@ ide_irq_update(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a string into a buffer, padding with spaces, and placing characters as
|
* Copy a string into a buffer, padding with spaces, and placing characters as
|
||||||
* if they were packed into 16-bit values, stored little-endian.
|
* if they were packed into 16-bit values, stored little-endian.
|
||||||
@@ -410,7 +399,6 @@ ide_padstr(char *str, const char *src, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a string into a buffer, padding with spaces. Does not add string
|
* Copy a string into a buffer, padding with spaces. Does not add string
|
||||||
* terminator.
|
* terminator.
|
||||||
@@ -420,7 +408,8 @@ ide_padstr(char *str, const char *src, int len)
|
|||||||
* this length will be padded with spaces.
|
* this length will be padded with spaces.
|
||||||
* @param src Source string
|
* @param src Source string
|
||||||
*/
|
*/
|
||||||
void ide_padstr8(uint8_t *buf, int buf_size, const char *src)
|
void
|
||||||
|
ide_padstr8(uint8_t *buf, int buf_size, const char *src)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -432,14 +421,13 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ide_get_max(ide_t *ide, int type)
|
ide_get_max(ide_t *ide, int type)
|
||||||
{
|
{
|
||||||
if (ide->type == IDE_ATAPI)
|
if (ide->type == IDE_ATAPI)
|
||||||
return ide->get_max(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
|
return ide->get_max(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TYPE_PIO: /* PIO */
|
case TYPE_PIO: /* PIO */
|
||||||
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
||||||
return 4;
|
return 4;
|
||||||
@@ -466,14 +454,13 @@ ide_get_max(ide_t *ide, int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ide_get_timings(ide_t *ide, int type)
|
ide_get_timings(ide_t *ide, int type)
|
||||||
{
|
{
|
||||||
if (ide->type == IDE_ATAPI)
|
if (ide->type == IDE_ATAPI)
|
||||||
return ide->get_timings(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
|
return ide->get_timings(!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type);
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TIMINGS_DMA:
|
case TIMINGS_DMA:
|
||||||
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
|
||||||
return 120;
|
return 120;
|
||||||
@@ -492,11 +479,11 @@ ide_get_timings(ide_t *ide, int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command
|
* Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command
|
||||||
*/
|
*/
|
||||||
static void ide_hd_identify(ide_t *ide)
|
static void
|
||||||
|
ide_hd_identify(ide_t *ide)
|
||||||
{
|
{
|
||||||
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
|
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
|
||||||
|
|
||||||
@@ -586,7 +573,6 @@ static void ide_hd_identify(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_identify(ide_t *ide)
|
ide_identify(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -681,7 +667,6 @@ ide_identify(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the sector offset for the current register values
|
* Return the sector offset for the current register values
|
||||||
*/
|
*/
|
||||||
@@ -691,19 +676,17 @@ ide_get_sector(ide_t *ide)
|
|||||||
uint32_t heads, sectors;
|
uint32_t heads, sectors;
|
||||||
|
|
||||||
if (ide->lba)
|
if (ide->lba)
|
||||||
return (off64_t)ide->lba_addr;
|
return (off64_t) ide->lba_addr;
|
||||||
else {
|
else {
|
||||||
heads = ide->cfg_hpc;
|
heads = ide->cfg_hpc;
|
||||||
sectors = ide->cfg_spt;
|
sectors = ide->cfg_spt;
|
||||||
|
|
||||||
uint8_t sector = ide->sector ? ide->sector : 1;
|
uint8_t sector = ide->sector ? ide->sector : 1;
|
||||||
|
|
||||||
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (sector - 1);
|
||||||
sectors) + (sector - 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move to the next sector using CHS addressing
|
* Move to the next sector using CHS addressing
|
||||||
*/
|
*/
|
||||||
@@ -725,11 +708,10 @@ ide_next_sector(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loadhd(ide_t *ide, int d, const char *fn)
|
loadhd(ide_t *ide, int d, const char *fn)
|
||||||
{
|
{
|
||||||
if (! hdd_image_load(d)) {
|
if (!hdd_image_load(d)) {
|
||||||
ide->type = IDE_NONE;
|
ide->type = IDE_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -743,12 +725,11 @@ loadhd(ide_t *ide, int d, const char *fn)
|
|||||||
ide->hdd_num = d;
|
ide->hdd_num = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_signature(ide_t *ide)
|
ide_set_signature(ide_t *ide)
|
||||||
{
|
{
|
||||||
ide->sector=1;
|
ide->sector = 1;
|
||||||
ide->head=0;
|
ide->head = 0;
|
||||||
|
|
||||||
if (ide->type == IDE_ATAPI) {
|
if (ide->type == IDE_ATAPI) {
|
||||||
ide->sc->phase = 1;
|
ide->sc->phase = 1;
|
||||||
@@ -763,7 +744,6 @@ ide_set_signature(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ide_set_features(ide_t *ide)
|
ide_set_features(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -777,7 +757,7 @@ ide_set_features(ide_t *ide)
|
|||||||
|
|
||||||
ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data);
|
ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data);
|
||||||
|
|
||||||
switch(features) {
|
switch (features) {
|
||||||
case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */
|
case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */
|
||||||
ide_log("Transfer mode %02X\n", features_data >> 3);
|
ide_log("Transfer mode %02X\n", features_data >> 3);
|
||||||
|
|
||||||
@@ -851,7 +831,6 @@ ide_set_features(ide_t *ide)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_sector(ide_t *ide, int64_t sector_num)
|
ide_set_sector(ide_t *ide, int64_t sector_num)
|
||||||
{
|
{
|
||||||
@@ -869,7 +848,6 @@ ide_set_sector(ide_t *ide, int64_t sector_num)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_zero(int d)
|
ide_zero(int d)
|
||||||
{
|
{
|
||||||
@@ -889,7 +867,6 @@ ide_zero(int d)
|
|||||||
timer_add(&dev->timer, ide_callback, dev, 0);
|
timer_add(&dev->timer, ide_callback, dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_allocate_buffer(ide_t *dev)
|
ide_allocate_buffer(ide_t *dev)
|
||||||
{
|
{
|
||||||
@@ -898,7 +875,6 @@ ide_allocate_buffer(ide_t *dev)
|
|||||||
memset(dev->buffer, 0, 65536 * sizeof(uint16_t));
|
memset(dev->buffer, 0, 65536 * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_atapi_attach(ide_t *ide)
|
ide_atapi_attach(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -913,7 +889,6 @@ ide_atapi_attach(ide_t *ide)
|
|||||||
ide->cfg_spt = ide->cfg_hpc = 0;
|
ide->cfg_spt = ide->cfg_hpc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_callback(ide_t *ide, double callback)
|
ide_set_callback(ide_t *ide, double callback)
|
||||||
{
|
{
|
||||||
@@ -931,7 +906,6 @@ ide_set_callback(ide_t *ide, double callback)
|
|||||||
timer_on_auto(&ide->timer, callback);
|
timer_on_auto(&ide->timer, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_board_callback(uint8_t board, double callback)
|
ide_set_board_callback(uint8_t board, double callback)
|
||||||
{
|
{
|
||||||
@@ -950,7 +924,6 @@ ide_set_board_callback(uint8_t board, double callback)
|
|||||||
timer_on_auto(&dev->timer, callback);
|
timer_on_auto(&dev->timer, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_atapi_command_bus(ide_t *ide)
|
ide_atapi_command_bus(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -961,13 +934,12 @@ ide_atapi_command_bus(ide_t *ide)
|
|||||||
ide_set_callback(ide, ide->sc->callback);
|
ide_set_callback(ide, ide->sc->callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_atapi_callback(ide_t *ide)
|
ide_atapi_callback(ide_t *ide)
|
||||||
{
|
{
|
||||||
int out, ret = 0;
|
int out, ret = 0;
|
||||||
|
|
||||||
switch(ide->sc->packet_status) {
|
switch (ide->sc->packet_status) {
|
||||||
case PHASE_IDLE:
|
case PHASE_IDLE:
|
||||||
#ifdef ENABLE_IDE_LOG
|
#ifdef ENABLE_IDE_LOG
|
||||||
ide_log("PHASE_IDLE\n");
|
ide_log("PHASE_IDLE\n");
|
||||||
@@ -1053,7 +1025,6 @@ ide_atapi_callback(ide_t *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the general ATAPI PIO request function. */
|
/* This is the general ATAPI PIO request function. */
|
||||||
static void
|
static void
|
||||||
ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||||
@@ -1100,7 +1071,6 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
ide_atapi_packet_read(ide_t *ide, int length)
|
ide_atapi_packet_read(ide_t *ide, int length)
|
||||||
{
|
{
|
||||||
@@ -1123,7 +1093,7 @@ ide_atapi_packet_read(ide_t *ide, int length)
|
|||||||
/* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it,
|
/* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it,
|
||||||
which can happen when issuing media access commands with an allocated length below minimum request length
|
which can happen when issuing media access commands with an allocated length below minimum request length
|
||||||
(which is 1 sector = 2048 bytes). */
|
(which is 1 sector = 2048 bytes). */
|
||||||
switch(length) {
|
switch (length) {
|
||||||
case 1:
|
case 1:
|
||||||
temp = (dev->pos < dev->packet_len) ? dev->temp_buffer[dev->pos] : 0;
|
temp = (dev->pos < dev->packet_len) ? dev->temp_buffer[dev->pos] : 0;
|
||||||
dev->pos++;
|
dev->pos++;
|
||||||
@@ -1153,7 +1123,6 @@ ide_atapi_packet_read(ide_t *ide, int length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_atapi_packet_write(ide_t *ide, uint32_t val, int length)
|
ide_atapi_packet_write(ide_t *ide, uint32_t val, int length)
|
||||||
{
|
{
|
||||||
@@ -1178,7 +1147,7 @@ ide_atapi_packet_write(ide_t *ide, uint32_t val, int length)
|
|||||||
bufferw = (uint16_t *) bufferb;
|
bufferw = (uint16_t *) bufferb;
|
||||||
bufferl = (uint32_t *) bufferb;
|
bufferl = (uint32_t *) bufferb;
|
||||||
|
|
||||||
switch(length) {
|
switch (length) {
|
||||||
case 1:
|
case 1:
|
||||||
bufferb[dev->pos] = val & 0xff;
|
bufferb[dev->pos] = val & 0xff;
|
||||||
dev->pos++;
|
dev->pos++;
|
||||||
@@ -1215,7 +1184,6 @@ ide_atapi_packet_write(ide_t *ide, uint32_t val, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_write_data(ide_t *ide, uint32_t val, int length)
|
ide_write_data(ide_t *ide, uint32_t val, int length)
|
||||||
{
|
{
|
||||||
@@ -1229,7 +1197,7 @@ ide_write_data(ide_t *ide, uint32_t val, int length)
|
|||||||
if (ide->type == IDE_ATAPI)
|
if (ide->type == IDE_ATAPI)
|
||||||
ide_atapi_packet_write(ide, val, length);
|
ide_atapi_packet_write(ide, val, length);
|
||||||
} else {
|
} else {
|
||||||
switch(length) {
|
switch (length) {
|
||||||
case 1:
|
case 1:
|
||||||
idebufferb[ide->pos] = val & 0xff;
|
idebufferb[ide->pos] = val & 0xff;
|
||||||
ide->pos++;
|
ide->pos++;
|
||||||
@@ -1247,13 +1215,13 @@ ide_write_data(ide_t *ide, uint32_t val, int length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ide->pos >= 512) {
|
if (ide->pos >= 512) {
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
ide->atastat = BSY_STAT;
|
ide->atastat = BSY_STAT;
|
||||||
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
|
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
|
||||||
double xfer_time = ide_get_xfer_time(ide, 512);
|
double xfer_time = ide_get_xfer_time(ide, 512);
|
||||||
double wait_time = seek_time + xfer_time;
|
double wait_time = seek_time + xfer_time;
|
||||||
if (ide->command == WIN_WRITE_MULTIPLE) {
|
if (ide->command == WIN_WRITE_MULTIPLE) {
|
||||||
if ((ide->blockcount+1) >= ide->blocksize || ide->secount == 1) {
|
if ((ide->blockcount + 1) >= ide->blocksize || ide->secount == 1) {
|
||||||
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
|
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
|
||||||
ide->pending_delay = 0;
|
ide->pending_delay = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -1267,7 +1235,6 @@ ide_write_data(ide_t *ide, uint32_t val, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_writew(uint16_t addr, uint16_t val, void *priv)
|
ide_writew(uint16_t addr, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -1300,7 +1267,6 @@ ide_writew(uint16_t addr, uint16_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_writel(uint16_t addr, uint32_t val, void *priv)
|
ide_writel(uint16_t addr, uint32_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -1327,7 +1293,8 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
else
|
else
|
||||||
ide_writew(addr + 2, (val >> 16) & 0xffff, priv);
|
ide_writew(addr + 2, (val >> 16) & 0xffff, priv);
|
||||||
break;
|
break;
|
||||||
case 0x6: case 0x7:
|
case 0x6:
|
||||||
|
case 0x7:
|
||||||
ide_writew(addr, val & 0xffff, priv);
|
ide_writew(addr, val & 0xffff, priv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1337,7 +1304,6 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_reset(ide_t *ide)
|
dev_reset(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -1347,7 +1313,6 @@ dev_reset(ide_t *ide)
|
|||||||
ide->stop(ide->sc);
|
ide->stop(ide->sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_write_devctl(uint16_t addr, uint8_t val, void *priv)
|
ide_write_devctl(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -1450,7 +1415,6 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv)
|
|||||||
ide_irq_update(ide);
|
ide_irq_update(ide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -1592,7 +1556,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
ide_other->lba = val & 0x40;
|
ide_other->lba = val & 0x40;
|
||||||
|
|
||||||
ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
|
ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
|
||||||
ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24);
|
ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
|
||||||
|
|
||||||
ide_irq_update(ide);
|
ide_irq_update(ide);
|
||||||
return;
|
return;
|
||||||
@@ -1696,7 +1660,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
ide->sc->pos = 0;
|
ide->sc->pos = 0;
|
||||||
} else {
|
} else {
|
||||||
ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT;
|
ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1713,15 +1677,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
} else
|
} else
|
||||||
ide->atastat = BSY_STAT;
|
ide->atastat = BSY_STAT;
|
||||||
|
|
||||||
if ((ide->type == IDE_HDD) &&
|
if ((ide->type == IDE_HDD) && ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) {
|
||||||
((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) {
|
|
||||||
uint32_t sec_count = ide->secount ? ide->secount : 256;
|
uint32_t sec_count = ide->secount ? ide->secount : 256;
|
||||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||||
double wait_time = seek_time > xfer_time ? seek_time : xfer_time;
|
double wait_time = seek_time > xfer_time ? seek_time : xfer_time;
|
||||||
ide_set_callback(ide, wait_time);
|
ide_set_callback(ide, wait_time);
|
||||||
} else if ((ide->type == IDE_HDD) &&
|
} else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) {
|
||||||
((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) {
|
|
||||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount);
|
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount);
|
||||||
ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2));
|
ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2));
|
||||||
} else if (val == WIN_IDENTIFY)
|
} else if (val == WIN_IDENTIFY)
|
||||||
@@ -1735,7 +1697,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
goto ide_bad_command;
|
goto ide_bad_command;
|
||||||
else {
|
else {
|
||||||
ide->atastat = DRQ_STAT;
|
ide->atastat = DRQ_STAT;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1809,7 +1771,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
} else {
|
} else {
|
||||||
ide->atastat = BSY_STAT;
|
ide->atastat = BSY_STAT;
|
||||||
ide_set_callback(ide, 200.0 * IDE_TIME);
|
ide_set_callback(ide, 200.0 * IDE_TIME);
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1830,7 +1792,6 @@ ide_bad_command:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
ide_read_data(ide_t *ide, int length)
|
ide_read_data(ide_t *ide, int length)
|
||||||
{
|
{
|
||||||
@@ -1913,7 +1874,6 @@ ide_read_data(ide_t *ide, int length)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
ide_status(ide_t *ide, ide_t *ide_other, int ch)
|
ide_status(ide_t *ide, ide_t *ide_other, int ch)
|
||||||
{
|
{
|
||||||
@@ -1931,7 +1891,6 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch)
|
|||||||
return ide->atastat;
|
return ide->atastat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
ide_readb(uint16_t addr, void *priv)
|
ide_readb(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2011,7 +1970,7 @@ ide_readb(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x6: /* Drive/Head */
|
case 0x6: /* Drive/Head */
|
||||||
temp = (uint8_t)(ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
|
temp = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is
|
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is
|
||||||
@@ -2026,7 +1985,6 @@ ide_readb(uint16_t addr, void *priv)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
ide_read_alt_status(uint16_t addr, void *priv)
|
ide_read_alt_status(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2048,7 +2006,6 @@ ide_read_alt_status(uint16_t addr, void *priv)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
ide_readw(uint16_t addr, void *priv)
|
ide_readw(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2078,7 +2035,6 @@ ide_readw(uint16_t addr, void *priv)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
ide_readl(uint16_t addr, void *priv)
|
ide_readl(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2101,7 +2057,8 @@ ide_readl(uint16_t addr, void *priv)
|
|||||||
else
|
else
|
||||||
temp = temp2 | (ide_readw(addr + 2, priv) << 16);
|
temp = temp2 | (ide_readw(addr + 2, priv) << 16);
|
||||||
break;
|
break;
|
||||||
case 0x6: case 0x7:
|
case 0x6:
|
||||||
|
case 0x7:
|
||||||
temp = ide_readw(addr, priv) | 0xffff0000;
|
temp = ide_readw(addr, priv) | 0xffff0000;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -2113,7 +2070,6 @@ ide_readl(uint16_t addr, void *priv)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_board_callback(void *priv)
|
ide_board_callback(void *priv)
|
||||||
{
|
{
|
||||||
@@ -2139,7 +2095,6 @@ ide_board_callback(void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
atapi_error_no_ready(ide_t *ide)
|
atapi_error_no_ready(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -2156,7 +2111,6 @@ atapi_error_no_ready(ide_t *ide)
|
|||||||
ide_irq_raise(ide);
|
ide_irq_raise(ide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_callback(void *priv)
|
ide_callback(void *priv)
|
||||||
{
|
{
|
||||||
@@ -2166,15 +2120,13 @@ ide_callback(void *priv)
|
|||||||
|
|
||||||
ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset, ide->channel);
|
ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset, ide->channel);
|
||||||
|
|
||||||
if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) ||
|
if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) {
|
||||||
((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) {
|
|
||||||
if (ide->type != IDE_HDD) {
|
if (ide->type != IDE_HDD) {
|
||||||
atapi_error_no_ready(ide);
|
atapi_error_no_ready(ide);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) {
|
if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) {
|
||||||
if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) ||
|
if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || !ide->sector || (ide->sector > ide->spt))
|
||||||
!ide->sector || (ide->sector > ide->spt))
|
|
||||||
goto id_not_found;
|
goto id_not_found;
|
||||||
}
|
}
|
||||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||||
@@ -2245,7 +2197,7 @@ ide_callback(void *priv)
|
|||||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer);
|
hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512);
|
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
|
||||||
|
|
||||||
ide->sector_pos++;
|
ide->sector_pos++;
|
||||||
ide->pos = 0;
|
ide->pos = 0;
|
||||||
@@ -2275,7 +2227,7 @@ ide_callback(void *priv)
|
|||||||
ide->sector_pos = 256;
|
ide->sector_pos = 256;
|
||||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
||||||
|
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
|
|
||||||
if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) {
|
if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) {
|
||||||
/* We should not abort - we should simply wait for the host to start DMA. */
|
/* We should not abort - we should simply wait for the host to start DMA. */
|
||||||
@@ -2327,10 +2279,10 @@ ide_callback(void *priv)
|
|||||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer);
|
hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512);
|
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
|
||||||
|
|
||||||
ide->sector_pos++;
|
ide->sector_pos++;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
|
|
||||||
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||||
if (!ide->blockcount)
|
if (!ide->blockcount)
|
||||||
@@ -2351,7 +2303,7 @@ ide_callback(void *priv)
|
|||||||
ide->secount = (ide->secount - 1) & 0xff;
|
ide->secount = (ide->secount - 1) & 0xff;
|
||||||
if (ide->secount) {
|
if (ide->secount) {
|
||||||
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
ide_next_sector(ide);
|
ide_next_sector(ide);
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -2428,7 +2380,7 @@ ide_callback(void *priv)
|
|||||||
ide->secount = (ide->secount - 1) & 0xff;
|
ide->secount = (ide->secount - 1) & 0xff;
|
||||||
if (ide->secount) {
|
if (ide->secount) {
|
||||||
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
ide_next_sector(ide);
|
ide_next_sector(ide);
|
||||||
} else {
|
} else {
|
||||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||||
@@ -2442,7 +2394,7 @@ ide_callback(void *priv)
|
|||||||
goto abort_cmd;
|
goto abort_cmd;
|
||||||
if (!ide->lba && (ide->cfg_spt == 0))
|
if (!ide->lba && (ide->cfg_spt == 0))
|
||||||
goto id_not_found;
|
goto id_not_found;
|
||||||
ide->pos=0;
|
ide->pos = 0;
|
||||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||||
ide_irq_raise(ide);
|
ide_irq_raise(ide);
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
||||||
@@ -2564,7 +2516,6 @@ id_not_found:
|
|||||||
ide_irq_raise(ide);
|
ide_irq_raise(ide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
ide_read_ali_75(void)
|
ide_read_ali_75(void)
|
||||||
{
|
{
|
||||||
@@ -2589,7 +2540,6 @@ ide_read_ali_75(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
ide_read_ali_76(void)
|
ide_read_ali_76(void)
|
||||||
{
|
{
|
||||||
@@ -2618,7 +2568,6 @@ ide_read_ali_76(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_handlers(uint8_t board)
|
ide_set_handlers(uint8_t board)
|
||||||
{
|
{
|
||||||
@@ -2640,7 +2589,6 @@ ide_set_handlers(uint8_t board)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_remove_handlers(uint8_t board)
|
ide_remove_handlers(uint8_t board)
|
||||||
{
|
{
|
||||||
@@ -2662,35 +2610,30 @@ ide_remove_handlers(uint8_t board)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_pri_enable(void)
|
ide_pri_enable(void)
|
||||||
{
|
{
|
||||||
ide_set_handlers(0);
|
ide_set_handlers(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_pri_disable(void)
|
ide_pri_disable(void)
|
||||||
{
|
{
|
||||||
ide_remove_handlers(0);
|
ide_remove_handlers(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_sec_enable(void)
|
ide_sec_enable(void)
|
||||||
{
|
{
|
||||||
ide_set_handlers(1);
|
ide_set_handlers(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_sec_disable(void)
|
ide_sec_disable(void)
|
||||||
{
|
{
|
||||||
ide_remove_handlers(1);
|
ide_remove_handlers(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_base(int board, uint16_t port)
|
ide_set_base(int board, uint16_t port)
|
||||||
{
|
{
|
||||||
@@ -2702,7 +2645,6 @@ ide_set_base(int board, uint16_t port)
|
|||||||
ide_boards[board]->base_main = port;
|
ide_boards[board]->base_main = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_side(int board, uint16_t port)
|
ide_set_side(int board, uint16_t port)
|
||||||
{
|
{
|
||||||
@@ -2714,7 +2656,6 @@ ide_set_side(int board, uint16_t port)
|
|||||||
ide_boards[board]->side_main = port;
|
ide_boards[board]->side_main = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_clear_bus_master(int board)
|
ide_clear_bus_master(int board)
|
||||||
{
|
{
|
||||||
@@ -2724,7 +2665,6 @@ ide_clear_bus_master(int board)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This so drives can be forced to ATA-3 (no DMA) for machines that hide the on-board PCI IDE controller
|
/* This so drives can be forced to ATA-3 (no DMA) for machines that hide the on-board PCI IDE controller
|
||||||
(eg. Packard Bell PB640 and ASUS P/I-P54TP4XE), breaking DMA drivers unless this is done. */
|
(eg. Packard Bell PB640 and ASUS P/I-P54TP4XE), breaking DMA drivers unless this is done. */
|
||||||
extern void
|
extern void
|
||||||
@@ -2732,13 +2672,12 @@ ide_board_set_force_ata3(int board, int force_ata3)
|
|||||||
{
|
{
|
||||||
ide_log("ide_board_set_force_ata3(%i, %i)\n", board, force_ata3);
|
ide_log("ide_board_set_force_ata3(%i, %i)\n", board, force_ata3);
|
||||||
|
|
||||||
if ((ide_boards[board] == NULL)|| !ide_boards[board]->inited)
|
if ((ide_boards[board] == NULL) || !ide_boards[board]->inited)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_boards[board]->force_ata3 = force_ata3;
|
ide_boards[board]->force_ata3 = force_ata3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_board_close(int board)
|
ide_board_close(int board)
|
||||||
{
|
{
|
||||||
@@ -2747,7 +2686,7 @@ 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) || !ide_boards[board]->inited)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_log("IDE: Closing board %i...\n", board);
|
ide_log("IDE: Closing board %i...\n", board);
|
||||||
@@ -2793,7 +2732,6 @@ ide_board_close(int board)
|
|||||||
ide_boards[board] = NULL;
|
ide_boards[board] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_board_setup(int board)
|
ide_board_setup(int board)
|
||||||
{
|
{
|
||||||
@@ -2826,9 +2764,10 @@ ide_board_setup(int board)
|
|||||||
ide_log("Found IDE hard disk on channel %i\n", ch);
|
ide_log("Found IDE hard disk on channel %i\n", ch);
|
||||||
loadhd(ide_drives[ch], d, hdd[d].fn);
|
loadhd(ide_drives[ch], d, hdd[d].fn);
|
||||||
if (ide_drives[ch]->sector_buffer == NULL)
|
if (ide_drives[ch]->sector_buffer == NULL)
|
||||||
ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256*512);
|
ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256 * 512);
|
||||||
memset(ide_drives[ch]->sector_buffer, 0, 256*512);
|
memset(ide_drives[ch]->sector_buffer, 0, 256 * 512);
|
||||||
if (++c >= 2) break;
|
if (++c >= 2)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ide_log("IDE: board %i: done, loaded %d disks.\n", board, c);
|
ide_log("IDE: board %i: done, loaded %d disks.\n", board, c);
|
||||||
@@ -2851,7 +2790,6 @@ ide_board_setup(int board)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_board_init(int board, int irq, int base_main, int side_main, int type)
|
ide_board_init(int board, int irq, int base_main, int side_main, int type)
|
||||||
{
|
{
|
||||||
@@ -2879,7 +2817,6 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type)
|
|||||||
ide_boards[board]->inited = 1;
|
ide_boards[board]->inited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2907,13 +2844,12 @@ ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
ide_ter_init(const device_t *info)
|
ide_ter_init(const device_t *info)
|
||||||
{
|
{
|
||||||
/* Don't claim this channel again if it was already claimed. */
|
/* Don't claim this channel again if it was already claimed. */
|
||||||
if (ide_boards[2])
|
if (ide_boards[2])
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
int irq;
|
int irq;
|
||||||
if (info->local)
|
if (info->local)
|
||||||
@@ -2929,10 +2865,9 @@ ide_ter_init(const device_t *info)
|
|||||||
ide_board_init(2, irq, 0x168, 0x36e, 0);
|
ide_board_init(2, irq, 0x168, 0x36e, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ide_boards[2]);
|
return (ide_boards[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Close a standalone IDE unit. */
|
/* Close a standalone IDE unit. */
|
||||||
static void
|
static void
|
||||||
ide_ter_close(void *priv)
|
ide_ter_close(void *priv)
|
||||||
@@ -2940,13 +2875,12 @@ ide_ter_close(void *priv)
|
|||||||
ide_board_close(2);
|
ide_board_close(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
ide_qua_init(const device_t *info)
|
ide_qua_init(const device_t *info)
|
||||||
{
|
{
|
||||||
/* Don't claim this channel again if it was already claimed. */
|
/* Don't claim this channel again if it was already claimed. */
|
||||||
if (ide_boards[3])
|
if (ide_boards[3])
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
int irq;
|
int irq;
|
||||||
if (info->local)
|
if (info->local)
|
||||||
@@ -2962,10 +2896,9 @@ ide_qua_init(const device_t *info)
|
|||||||
ide_board_init(3, irq, 0x1e8, 0x3ee, 0);
|
ide_board_init(3, irq, 0x1e8, 0x3ee, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ide_boards[3]);
|
return (ide_boards[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Close a standalone IDE unit. */
|
/* Close a standalone IDE unit. */
|
||||||
static void
|
static void
|
||||||
ide_qua_close(void *priv)
|
ide_qua_close(void *priv)
|
||||||
@@ -2973,7 +2906,6 @@ ide_qua_close(void *priv)
|
|||||||
ide_board_close(3);
|
ide_board_close(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ide_xtide_init(void)
|
ide_xtide_init(void)
|
||||||
{
|
{
|
||||||
@@ -2982,14 +2914,12 @@ ide_xtide_init(void)
|
|||||||
return ide_boards[0];
|
return ide_boards[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_xtide_close(void)
|
ide_xtide_close(void)
|
||||||
{
|
{
|
||||||
ide_board_close(0);
|
ide_board_close(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_bus_master(int board,
|
ide_set_bus_master(int board,
|
||||||
int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv),
|
int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv),
|
||||||
@@ -3003,13 +2933,12 @@ ide_set_bus_master(int board,
|
|||||||
ide_bm[board]->priv = priv;
|
ide_bm[board]->priv = priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
ide_init(const device_t *info)
|
ide_init(const device_t *info)
|
||||||
{
|
{
|
||||||
ide_log("Initializing IDE...\n");
|
ide_log("Initializing IDE...\n");
|
||||||
|
|
||||||
switch(info->local) {
|
switch (info->local) {
|
||||||
case 0: /* ISA, single-channel */
|
case 0: /* ISA, single-channel */
|
||||||
case 1: /* ISA, dual-channel */
|
case 1: /* ISA, dual-channel */
|
||||||
case 2: /* VLB, single-channel */
|
case 2: /* VLB, single-channel */
|
||||||
@@ -3023,10 +2952,9 @@ ide_init(const device_t *info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ide_drives);
|
return (ide_drives);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_drive_reset(int d)
|
ide_drive_reset(int d)
|
||||||
{
|
{
|
||||||
@@ -3047,13 +2975,12 @@ ide_drive_reset(int d)
|
|||||||
ide_set_signature(ide_drives[d]);
|
ide_set_signature(ide_drives[d]);
|
||||||
|
|
||||||
if (ide_drives[d]->sector_buffer)
|
if (ide_drives[d]->sector_buffer)
|
||||||
memset(ide_drives[d]->sector_buffer, 0, 256*512);
|
memset(ide_drives[d]->sector_buffer, 0, 256 * 512);
|
||||||
|
|
||||||
if (ide_drives[d]->buffer)
|
if (ide_drives[d]->buffer)
|
||||||
memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t));
|
memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_board_reset(int board)
|
ide_board_reset(int board)
|
||||||
{
|
{
|
||||||
@@ -3070,7 +2997,6 @@ ide_board_reset(int board)
|
|||||||
ide_drive_reset(d);
|
ide_drive_reset(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset a standalone IDE unit. */
|
/* Reset a standalone IDE unit. */
|
||||||
static void
|
static void
|
||||||
ide_reset(void *p)
|
ide_reset(void *p)
|
||||||
@@ -3084,7 +3010,6 @@ ide_reset(void *p)
|
|||||||
ide_board_reset(1);
|
ide_board_reset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Close a standalone IDE unit. */
|
/* Close a standalone IDE unit. */
|
||||||
static void
|
static void
|
||||||
ide_close(void *priv)
|
ide_close(void *priv)
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
#include <86box/mo.h>
|
#include <86box/mo.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t vlb_idx, id,
|
uint8_t vlb_idx, id,
|
||||||
@@ -48,10 +47,8 @@ typedef struct
|
|||||||
irq_pin, irq_line;
|
irq_pin, irq_line;
|
||||||
} cmd640_t;
|
} cmd640_t;
|
||||||
|
|
||||||
|
|
||||||
static int next_id = 0;
|
static int next_id = 0;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_CMD640_LOG
|
#ifdef ENABLE_CMD640_LOG
|
||||||
int cmd640_do_log = ENABLE_CMD640_LOG;
|
int cmd640_do_log = ENABLE_CMD640_LOG;
|
||||||
static void
|
static void
|
||||||
@@ -59,18 +56,16 @@ cmd640_log(const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (cmd640_do_log)
|
if (cmd640_do_log) {
|
||||||
{
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
pclog_ex(fmt, ap);
|
pclog_ex(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define cmd640_log(fmt, ...)
|
# define cmd640_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cmd640_set_irq(int channel, void *priv)
|
cmd640_set_irq(int channel, void *priv)
|
||||||
{
|
{
|
||||||
@@ -103,7 +98,6 @@ cmd640_set_irq(int channel, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_ide_handlers(cmd640_t *dev)
|
cmd640_ide_handlers(cmd640_t *dev)
|
||||||
{
|
{
|
||||||
@@ -145,7 +139,6 @@ cmd640_ide_handlers(cmd640_t *dev)
|
|||||||
ide_sec_enable();
|
ide_sec_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_common_write(int addr, uint8_t val, cmd640_t *dev)
|
cmd640_common_write(int addr, uint8_t val, cmd640_t *dev)
|
||||||
{
|
{
|
||||||
@@ -154,11 +147,15 @@ cmd640_common_write(int addr, uint8_t val, cmd640_t *dev)
|
|||||||
dev->regs[addr] = val;
|
dev->regs[addr] = val;
|
||||||
cmd640_ide_handlers(dev);
|
cmd640_ide_handlers(dev);
|
||||||
break;
|
break;
|
||||||
case 0x52: case 0x54: case 0x56: case 0x58:
|
case 0x52:
|
||||||
|
case 0x54:
|
||||||
|
case 0x56:
|
||||||
|
case 0x58:
|
||||||
case 0x59:
|
case 0x59:
|
||||||
dev->regs[addr] = val;
|
dev->regs[addr] = val;
|
||||||
break;
|
break;
|
||||||
case 0x53: case 0x55:
|
case 0x53:
|
||||||
|
case 0x55:
|
||||||
dev->regs[addr] = val & 0xc0;
|
dev->regs[addr] = val & 0xc0;
|
||||||
break;
|
break;
|
||||||
case 0x57:
|
case 0x57:
|
||||||
@@ -170,7 +167,6 @@ cmd640_common_write(int addr, uint8_t val, cmd640_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv)
|
cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -193,7 +189,6 @@ cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_vlb_writew(uint16_t addr, uint16_t val, void *priv)
|
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);
|
cmd640_vlb_write(addr + 1, val >> 8, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv)
|
cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -209,7 +203,6 @@ cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
cmd640_vlb_writew(addr + 2, val >> 16, priv);
|
cmd640_vlb_writew(addr + 2, val >> 16, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
cmd640_vlb_read(uint16_t addr, void *priv)
|
cmd640_vlb_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -237,7 +230,6 @@ cmd640_vlb_read(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
cmd640_vlb_readw(uint16_t addr, void *priv)
|
cmd640_vlb_readw(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -249,7 +241,6 @@ cmd640_vlb_readw(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
cmd640_vlb_readl(uint16_t addr, void *priv)
|
cmd640_vlb_readl(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -261,7 +252,6 @@ cmd640_vlb_readl(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
|
cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -269,7 +259,8 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
|
|
||||||
cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val);
|
cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val);
|
||||||
|
|
||||||
if (func == 0x00) switch (addr) {
|
if (func == 0x00)
|
||||||
|
switch (addr) {
|
||||||
case 0x04:
|
case 0x04:
|
||||||
dev->regs[addr] = (val & 0x41);
|
dev->regs[addr] = (val & 0x41);
|
||||||
cmd640_ide_handlers(dev);
|
cmd640_ide_handlers(dev);
|
||||||
@@ -339,7 +330,6 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
cmd640_pci_read(int func, int addr, void *priv)
|
cmd640_pci_read(int func, int addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -359,7 +349,6 @@ cmd640_pci_read(int func, int addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_reset(void *priv)
|
cmd640_reset(void *priv)
|
||||||
{
|
{
|
||||||
@@ -367,18 +356,15 @@ cmd640_reset(void *priv)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; i < CDROM_NUM; i++) {
|
for (i = 0; i < CDROM_NUM; i++) {
|
||||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
||||||
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
|
||||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < ZIP_NUM; i++) {
|
for (i = 0; i < ZIP_NUM; i++) {
|
||||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
||||||
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
|
||||||
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MO_NUM; i++) {
|
for (i = 0; i < MO_NUM; i++) {
|
||||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
||||||
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
|
||||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,10 +398,14 @@ cmd640_reset(void *priv)
|
|||||||
|
|
||||||
/* Base addresses (1F0, 3F4, 170, 374) */
|
/* Base addresses (1F0, 3F4, 170, 374) */
|
||||||
if (dev->regs[0x50] & 0x40) {
|
if (dev->regs[0x50] & 0x40) {
|
||||||
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
|
dev->regs[0x10] = 0xf1;
|
||||||
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
|
dev->regs[0x11] = 0x01;
|
||||||
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
|
dev->regs[0x14] = 0xf5;
|
||||||
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
|
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[0x3c] = 0x14; /* IRQ 14 */
|
||||||
@@ -436,7 +426,6 @@ cmd640_reset(void *priv)
|
|||||||
cmd640_ide_handlers(dev);
|
cmd640_ide_handlers(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd640_close(void *priv)
|
cmd640_close(void *priv)
|
||||||
{
|
{
|
||||||
@@ -447,7 +436,6 @@ cmd640_close(void *priv)
|
|||||||
next_id = 0;
|
next_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
cmd640_init(const device_t *info)
|
cmd640_init(const device_t *info)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
#include <86box/mo.h>
|
#include <86box/mo.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t vlb_idx, single_channel,
|
uint8_t vlb_idx, single_channel,
|
||||||
@@ -48,7 +47,6 @@ typedef struct
|
|||||||
sff8038i_t *bm[2];
|
sff8038i_t *bm[2];
|
||||||
} cmd646_t;
|
} cmd646_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_CMD646_LOG
|
#ifdef ENABLE_CMD646_LOG
|
||||||
int cmd646_do_log = ENABLE_CMD646_LOG;
|
int cmd646_do_log = ENABLE_CMD646_LOG;
|
||||||
static void
|
static void
|
||||||
@@ -56,18 +54,16 @@ cmd646_log(const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (cmd646_do_log)
|
if (cmd646_do_log) {
|
||||||
{
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
pclog_ex(fmt, ap);
|
pclog_ex(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define cmd646_log(fmt, ...)
|
# define cmd646_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_set_irq(int channel, void *priv)
|
cmd646_set_irq(int channel, void *priv)
|
||||||
{
|
{
|
||||||
@@ -88,7 +84,6 @@ cmd646_set_irq(int channel, void *priv)
|
|||||||
sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]);
|
sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
||||||
{
|
{
|
||||||
@@ -97,7 +92,6 @@ 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]);
|
return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_ide_handlers(cmd646_t *dev)
|
cmd646_ide_handlers(cmd646_t *dev)
|
||||||
{
|
{
|
||||||
@@ -150,10 +144,8 @@ cmd646_ide_handlers(cmd646_t *dev)
|
|||||||
|
|
||||||
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
|
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
|
||||||
ide_sec_enable();
|
ide_sec_enable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_ide_bm_handlers(cmd646_t *dev)
|
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);
|
sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -171,7 +162,8 @@ 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);
|
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) {
|
if (func == 0x00)
|
||||||
|
switch (addr) {
|
||||||
case 0x04:
|
case 0x04:
|
||||||
dev->regs[addr] = (val & 0x45);
|
dev->regs[addr] = (val & 0x45);
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
@@ -247,11 +239,16 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
dev->regs[addr] = val & 0xc8;
|
dev->regs[addr] = val & 0xc8;
|
||||||
cmd646_ide_handlers(dev);
|
cmd646_ide_handlers(dev);
|
||||||
break;
|
break;
|
||||||
case 0x52: case 0x54: case 0x56: case 0x58:
|
case 0x52:
|
||||||
case 0x59: case 0x5b:
|
case 0x54:
|
||||||
|
case 0x56:
|
||||||
|
case 0x58:
|
||||||
|
case 0x59:
|
||||||
|
case 0x5b:
|
||||||
dev->regs[addr] = val;
|
dev->regs[addr] = val;
|
||||||
break;
|
break;
|
||||||
case 0x53: case 0x55:
|
case 0x53:
|
||||||
|
case 0x55:
|
||||||
dev->regs[addr] = val & 0xc0;
|
dev->regs[addr] = val & 0xc0;
|
||||||
break;
|
break;
|
||||||
case 0x57:
|
case 0x57:
|
||||||
@@ -266,7 +263,6 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
cmd646_pci_read(int func, int addr, void *priv)
|
cmd646_pci_read(int func, int addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -291,7 +287,6 @@ cmd646_pci_read(int func, int addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_reset(void *priv)
|
cmd646_reset(void *priv)
|
||||||
{
|
{
|
||||||
@@ -299,18 +294,15 @@ cmd646_reset(void *priv)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; i < CDROM_NUM; i++) {
|
for (i = 0; i < CDROM_NUM; i++) {
|
||||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
||||||
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
|
||||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < ZIP_NUM; i++) {
|
for (i = 0; i < ZIP_NUM; i++) {
|
||||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
||||||
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
|
||||||
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MO_NUM; i++) {
|
for (i = 0; i < MO_NUM; i++) {
|
||||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
||||||
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
|
||||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,10 +327,14 @@ cmd646_reset(void *priv)
|
|||||||
If 0, they return 0 and are read-only 8 */
|
If 0, they return 0 and are read-only 8 */
|
||||||
|
|
||||||
/* Base addresses (1F0, 3F4, 170, 374) */
|
/* Base addresses (1F0, 3F4, 170, 374) */
|
||||||
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
|
dev->regs[0x10] = 0xf1;
|
||||||
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
|
dev->regs[0x11] = 0x01;
|
||||||
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
|
dev->regs[0x14] = 0xf5;
|
||||||
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
|
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[0x20] = 0x01;
|
||||||
@@ -361,7 +357,6 @@ cmd646_reset(void *priv)
|
|||||||
cmd646_ide_bm_handlers(dev);
|
cmd646_ide_bm_handlers(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd646_close(void *priv)
|
cmd646_close(void *priv)
|
||||||
{
|
{
|
||||||
@@ -370,7 +365,6 @@ cmd646_close(void *priv)
|
|||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
cmd646_init(const device_t *info)
|
cmd646_init(const device_t *info)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t tries,
|
uint8_t tries,
|
||||||
@@ -37,10 +36,8 @@ typedef struct
|
|||||||
regs[19];
|
regs[19];
|
||||||
} opti611_t;
|
} opti611_t;
|
||||||
|
|
||||||
|
|
||||||
static void opti611_ide_handler(opti611_t *dev);
|
static void opti611_ide_handler(opti611_t *dev);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
|
opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -74,7 +71,6 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_cfg_writew(uint16_t addr, uint16_t val, void *priv)
|
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);
|
opti611_cfg_write(addr + 1, val >> 8, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv)
|
opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -90,7 +85,6 @@ opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
opti611_cfg_writew(addr + 2, val >> 16, priv);
|
opti611_cfg_writew(addr + 2, val >> 16, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
opti611_cfg_read(uint16_t addr, void *priv)
|
opti611_cfg_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -109,7 +103,10 @@ opti611_cfg_read(uint16_t addr, void *priv)
|
|||||||
if (ret & 0x80)
|
if (ret & 0x80)
|
||||||
ret |= (dev->regs[addr] & 0x7f);
|
ret |= (dev->regs[addr] & 0x7f);
|
||||||
break;
|
break;
|
||||||
case 0x0003: case 0x0004: case 0x0005: case 0x0006:
|
case 0x0003:
|
||||||
|
case 0x0004:
|
||||||
|
case 0x0005:
|
||||||
|
case 0x0006:
|
||||||
ret = dev->regs[addr];
|
ret = dev->regs[addr];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -117,7 +114,6 @@ opti611_cfg_read(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
opti611_cfg_readw(uint16_t addr, void *priv)
|
opti611_cfg_readw(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -129,7 +125,6 @@ opti611_cfg_readw(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
opti611_cfg_readl(uint16_t addr, void *priv)
|
opti611_cfg_readl(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -141,7 +136,6 @@ opti611_cfg_readl(uint16_t addr, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_ide_write(uint16_t addr, uint8_t val, void *priv)
|
opti611_ide_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -158,7 +152,6 @@ opti611_ide_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_ide_writew(uint16_t addr, uint16_t val, void *priv)
|
opti611_ide_writew(uint16_t addr, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -175,7 +168,6 @@ opti611_ide_writew(uint16_t addr, uint16_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_ide_writel(uint16_t addr, uint32_t val, void *priv)
|
opti611_ide_writel(uint16_t addr, uint32_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -191,7 +183,6 @@ opti611_ide_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
opti611_ide_read(uint16_t addr, void *priv)
|
opti611_ide_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -210,7 +201,6 @@ opti611_ide_read(uint16_t addr, void *priv)
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
opti611_ide_readw(uint16_t addr, void *priv)
|
opti611_ide_readw(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -237,7 +227,6 @@ opti611_ide_readw(uint16_t addr, void *priv)
|
|||||||
return 0xffff;
|
return 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
opti611_ide_readl(uint16_t addr, void *priv)
|
opti611_ide_readl(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -255,7 +244,6 @@ opti611_ide_readl(uint16_t addr, void *priv)
|
|||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_ide_handler(opti611_t *dev)
|
opti611_ide_handler(opti611_t *dev)
|
||||||
{
|
{
|
||||||
@@ -284,7 +272,6 @@ opti611_ide_handler(opti611_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
opti611_close(void *priv)
|
opti611_close(void *priv)
|
||||||
{
|
{
|
||||||
@@ -293,7 +280,6 @@ opti611_close(void *priv)
|
|||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
opti611_init(const device_t *info)
|
opti611_init(const device_t *info)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,10 +43,8 @@
|
|||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
#include <86box/mo.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);
|
uint8_t sff_bus_master_read(uint16_t port, void *priv);
|
||||||
static uint16_t sff_bus_master_readw(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);
|
static uint32_t sff_bus_master_readl(uint16_t port, void *priv);
|
||||||
@@ -54,11 +52,9 @@ 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_writew(uint16_t port, uint16_t val, void *priv);
|
||||||
static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv);
|
static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_SFF_LOG
|
#ifdef ENABLE_SFF_LOG
|
||||||
int sff_do_log = ENABLE_SFF_LOG;
|
int sff_do_log = ENABLE_SFF_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_log(const char *fmt, ...)
|
sff_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -71,10 +67,9 @@ sff_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define sff_log(fmt, ...)
|
# define sff_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base)
|
sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base)
|
||||||
{
|
{
|
||||||
@@ -96,12 +91,11 @@ sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base)
|
|||||||
dev->base = base;
|
dev->base = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_bus_master_next_addr(sff8038i_t *dev)
|
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, (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 + 4, (uint8_t *) &(dev->count), 4, 4);
|
||||||
sff_log("SFF-8038i Bus master DWORDs: %08X %08X\n", dev->addr, dev->count);
|
sff_log("SFF-8038i Bus master DWORDs: %08X %08X\n", dev->addr, dev->count);
|
||||||
dev->eot = dev->count >> 31;
|
dev->eot = dev->count >> 31;
|
||||||
dev->count &= 0xfffe;
|
dev->count &= 0xfffe;
|
||||||
@@ -111,7 +105,6 @@ sff_bus_master_next_addr(sff8038i_t *dev)
|
|||||||
dev->ptr_cur += 8;
|
dev->ptr_cur += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
|
sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -170,7 +163,6 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
|
sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -196,7 +188,6 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
|
sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -218,7 +209,6 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
sff_bus_master_read(uint16_t port, void *priv)
|
sff_bus_master_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
@@ -255,7 +245,6 @@ sff_bus_master_read(uint16_t port, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
sff_bus_master_readw(uint16_t port, void *priv)
|
sff_bus_master_readw(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
@@ -282,7 +271,6 @@ sff_bus_master_readw(uint16_t port, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
sff_bus_master_readl(uint16_t port, void *priv)
|
sff_bus_master_readl(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
@@ -306,7 +294,6 @@ sff_bus_master_readl(uint16_t port, void *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
||||||
{
|
{
|
||||||
@@ -332,17 +319,17 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi
|
|||||||
if (dev->count <= transfer_length) {
|
if (dev->count <= transfer_length) {
|
||||||
sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
|
sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
|
||||||
if (out)
|
if (out)
|
||||||
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
|
dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4);
|
||||||
else
|
else
|
||||||
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
|
dma_bm_write(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4);
|
||||||
transfer_length -= dev->count;
|
transfer_length -= dev->count;
|
||||||
buffer_pos += dev->count;
|
buffer_pos += dev->count;
|
||||||
} else {
|
} else {
|
||||||
sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
|
sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
|
||||||
if (out)
|
if (out)
|
||||||
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
|
dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), transfer_length, 4);
|
||||||
else
|
else
|
||||||
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
|
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. */
|
/* Increase addr and decrease count so that resumed transfers do not mess up. */
|
||||||
dev->addr += transfer_length;
|
dev->addr += transfer_length;
|
||||||
dev->count -= transfer_length;
|
dev->count -= transfer_length;
|
||||||
@@ -377,7 +364,6 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_bus_master_set_irq(int channel, void *priv)
|
sff_bus_master_set_irq(int channel, void *priv)
|
||||||
{
|
{
|
||||||
@@ -432,7 +418,6 @@ sff_bus_master_set_irq(int channel, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
|
sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
|
||||||
{
|
{
|
||||||
@@ -456,7 +441,6 @@ sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
|
|||||||
ide_sec_disable();
|
ide_sec_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_reset(void *p)
|
sff_reset(void *p)
|
||||||
{
|
{
|
||||||
@@ -467,18 +451,15 @@ sff_reset(void *p)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < CDROM_NUM; i++) {
|
for (i = 0; i < CDROM_NUM; i++) {
|
||||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
||||||
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
|
||||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < ZIP_NUM; i++) {
|
for (i = 0; i < ZIP_NUM; i++) {
|
||||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
||||||
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
|
||||||
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MO_NUM; i++) {
|
for (i = 0; i < MO_NUM; i++) {
|
||||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
||||||
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
|
||||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,28 +467,24 @@ sff_reset(void *p)
|
|||||||
sff_bus_master_set_irq(0x01, p);
|
sff_bus_master_set_irq(0x01, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_set_slot(sff8038i_t *dev, int slot)
|
sff_set_slot(sff8038i_t *dev, int slot)
|
||||||
{
|
{
|
||||||
dev->slot = slot;
|
dev->slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_set_irq_line(sff8038i_t *dev, int irq_line)
|
sff_set_irq_line(sff8038i_t *dev, int irq_line)
|
||||||
{
|
{
|
||||||
dev->irq_line = irq_line;
|
dev->irq_line = irq_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level)
|
sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level)
|
||||||
{
|
{
|
||||||
dev->irq_level[channel] = 0;
|
dev->irq_level[channel] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
|
sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
|
||||||
{
|
{
|
||||||
@@ -539,18 +516,16 @@ sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sff_set_irq_pin(sff8038i_t *dev, int irq_pin)
|
sff_set_irq_pin(sff8038i_t *dev, int irq_pin)
|
||||||
{
|
{
|
||||||
dev->irq_pin = irq_pin;
|
dev->irq_pin = irq_pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sff_close(void *p)
|
sff_close(void *p)
|
||||||
{
|
{
|
||||||
sff8038i_t *dev = (sff8038i_t *)p;
|
sff8038i_t *dev = (sff8038i_t *) p;
|
||||||
|
|
||||||
free(dev);
|
free(dev);
|
||||||
|
|
||||||
@@ -559,9 +534,9 @@ sff_close(void *p)
|
|||||||
next_id = 0;
|
next_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
*sff_init(const device_t *info)
|
*
|
||||||
|
sff_init(const device_t *info)
|
||||||
{
|
{
|
||||||
sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t));
|
sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t));
|
||||||
memset(dev, 0, sizeof(sff8038i_t));
|
memset(dev, 0, sizeof(sff8038i_t));
|
||||||
@@ -584,8 +559,7 @@ static void
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
const device_t sff8038i_device =
|
const device_t sff8038i_device = {
|
||||||
{
|
|
||||||
.name = "SFF-8038i IDE Bus Master",
|
.name = "SFF-8038i IDE Bus Master",
|
||||||
.internal_name = "sff8038i",
|
.internal_name = "sff8038i",
|
||||||
.flags = DEVICE_PCI,
|
.flags = DEVICE_PCI,
|
||||||
|
|||||||
@@ -39,8 +39,7 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
#define MFM_TIME (TIMER_USEC * 10)
|
||||||
#define MFM_TIME (TIMER_USEC*10)
|
|
||||||
|
|
||||||
/*Rough estimate - MFM drives spin at 3600 RPM, with 17 sectors per track,
|
/*Rough estimate - MFM drives spin at 3600 RPM, with 17 sectors per track,
|
||||||
meaning (3600/60)*17 = 1020 sectors per second, or 980us per sector.
|
meaning (3600/60)*17 = 1020 sectors per second, or 980us per sector.
|
||||||
@@ -75,7 +74,6 @@
|
|||||||
#define CMD_DIAGNOSE 0x90
|
#define CMD_DIAGNOSE 0x90
|
||||||
#define CMD_SET_PARAMETERS 0x91
|
#define CMD_SET_PARAMETERS 0x91
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t present, /* drive is present */
|
int8_t present, /* drive is present */
|
||||||
hdd_num, /* drive number in system */
|
hdd_num, /* drive number in system */
|
||||||
@@ -91,7 +89,6 @@ typedef struct {
|
|||||||
int16_t curcyl; /* current track number */
|
int16_t curcyl; /* current track number */
|
||||||
} drive_t;
|
} drive_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t precomp, /* 1: precomp/error register */
|
uint8_t precomp, /* 1: precomp/error register */
|
||||||
error,
|
error,
|
||||||
@@ -116,15 +113,12 @@ typedef struct {
|
|||||||
drive_t drives[MFM_NUM]; /* attached drives */
|
drive_t drives[MFM_NUM]; /* attached drives */
|
||||||
} mfm_t;
|
} mfm_t;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t mfm_read(uint16_t port, void *priv);
|
static uint8_t mfm_read(uint16_t port, void *priv);
|
||||||
static void mfm_write(uint16_t port, uint8_t val, void *priv);
|
static void mfm_write(uint16_t port, uint8_t val, void *priv);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_ST506_AT_LOG
|
#ifdef ENABLE_ST506_AT_LOG
|
||||||
int st506_at_do_log = ENABLE_ST506_AT_LOG;
|
int st506_at_do_log = ENABLE_ST506_AT_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_at_log(const char *fmt, ...)
|
st506_at_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -137,10 +131,9 @@ st506_at_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define st506_at_log(fmt, ...)
|
# define st506_at_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
irq_raise(mfm_t *mfm)
|
irq_raise(mfm_t *mfm)
|
||||||
{
|
{
|
||||||
@@ -150,15 +143,12 @@ irq_raise(mfm_t *mfm)
|
|||||||
mfm->irqstat = 1;
|
mfm->irqstat = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
irq_lower(mfm_t *mfm)
|
irq_lower(mfm_t *mfm)
|
||||||
{
|
{
|
||||||
picintc(1 << 14);
|
picintc(1 << 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irq_update(mfm_t *mfm)
|
irq_update(mfm_t *mfm)
|
||||||
{
|
{
|
||||||
@@ -166,7 +156,6 @@ irq_update(mfm_t *mfm)
|
|||||||
picint(1 << 14);
|
picint(1 << 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the sector offset for the current register values.
|
* Return the sector offset for the current register values.
|
||||||
*
|
*
|
||||||
@@ -184,50 +173,48 @@ get_sector(mfm_t *mfm, off64_t *addr)
|
|||||||
{
|
{
|
||||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||||
|
|
||||||
/* FIXME: See if this is even needed - if the code is present, IBM AT
|
/* FIXME: See if this is even needed - if the code is present, IBM AT
|
||||||
diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */
|
diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */
|
||||||
if (drive->curcyl != mfm->cylinder) {
|
if (drive->curcyl != mfm->cylinder) {
|
||||||
st506_at_log("WD1003(%d) sector: wrong cylinder\n");
|
st506_at_log("WD1003(%d) sector: wrong cylinder\n");
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mfm->head > drive->cfg_hpc) {
|
if (mfm->head > drive->cfg_hpc) {
|
||||||
st506_at_log("WD1003(%d) get_sector: past end of configured heads\n",
|
st506_at_log("WD1003(%d) get_sector: past end of configured heads\n",
|
||||||
mfm->drvsel);
|
mfm->drvsel);
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mfm->sector >= drive->cfg_spt+1) {
|
if (mfm->sector >= drive->cfg_spt + 1) {
|
||||||
st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n",
|
st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n",
|
||||||
mfm->drvsel);
|
mfm->drvsel);
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */
|
/* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */
|
||||||
if (mfm->head > drive->hpc) {
|
if (mfm->head > drive->hpc) {
|
||||||
st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
|
st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mfm->sector >= drive->spt+1) {
|
if (mfm->sector >= drive->spt + 1) {
|
||||||
st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
|
st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
*addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) *
|
*addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * drive->cfg_spt) + (mfm->sector - 1);
|
||||||
drive->cfg_spt) + (mfm->sector - 1);
|
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Move to the next sector using CHS addressing. */
|
/* Move to the next sector using CHS addressing. */
|
||||||
static void
|
static void
|
||||||
next_sector(mfm_t *mfm)
|
next_sector(mfm_t *mfm)
|
||||||
{
|
{
|
||||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||||
|
|
||||||
if (++mfm->sector == (drive->cfg_spt+1)) {
|
if (++mfm->sector == (drive->cfg_spt + 1)) {
|
||||||
mfm->sector = 1;
|
mfm->sector = 1;
|
||||||
if (++mfm->head == drive->cfg_hpc) {
|
if (++mfm->head == drive->cfg_hpc) {
|
||||||
mfm->head = 0;
|
mfm->head = 0;
|
||||||
@@ -238,13 +225,12 @@ next_sector(mfm_t *mfm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mfm_cmd(mfm_t *mfm, uint8_t val)
|
mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||||
{
|
{
|
||||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||||
|
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
/* This happens if sofware polls all drives. */
|
/* This happens if sofware polls all drives. */
|
||||||
st506_at_log("WD1003(%d) command %02x on non-present drive\n",
|
st506_at_log("WD1003(%d) command %02x on non-present drive\n",
|
||||||
mfm->drvsel, val);
|
mfm->drvsel, val);
|
||||||
@@ -265,7 +251,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
mfm->drvsel, drive->steprate);
|
mfm->drvsel, drive->steprate);
|
||||||
drive->curcyl = 0;
|
drive->curcyl = 0;
|
||||||
mfm->cylinder = 0;
|
mfm->cylinder = 0;
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
mfm->command &= 0xf0;
|
mfm->command &= 0xf0;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
@@ -281,11 +267,11 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
mfm->command = val;
|
mfm->command = val;
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case CMD_READ:
|
case CMD_READ:
|
||||||
case CMD_READ+1:
|
case CMD_READ + 1:
|
||||||
case CMD_READ+2:
|
case CMD_READ + 2:
|
||||||
case CMD_READ+3:
|
case CMD_READ + 3:
|
||||||
st506_at_log("WD1003(%d) read, opt=%d\n",
|
st506_at_log("WD1003(%d) read, opt=%d\n",
|
||||||
mfm->drvsel, val&0x03);
|
mfm->drvsel, val & 0x03);
|
||||||
mfm->command &= 0xfc;
|
mfm->command &= 0xfc;
|
||||||
if (val & 2)
|
if (val & 2)
|
||||||
fatal("WD1003: READ with ECC\n");
|
fatal("WD1003: READ with ECC\n");
|
||||||
@@ -294,27 +280,27 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE:
|
case CMD_WRITE:
|
||||||
case CMD_WRITE+1:
|
case CMD_WRITE + 1:
|
||||||
case CMD_WRITE+2:
|
case CMD_WRITE + 2:
|
||||||
case CMD_WRITE+3:
|
case CMD_WRITE + 3:
|
||||||
st506_at_log("WD1003(%d) write, opt=%d\n",
|
st506_at_log("WD1003(%d) write, opt=%d\n",
|
||||||
mfm->drvsel, val & 0x03);
|
mfm->drvsel, val & 0x03);
|
||||||
mfm->command &= 0xfc;
|
mfm->command &= 0xfc;
|
||||||
if (val & 2)
|
if (val & 2)
|
||||||
fatal("WD1003: WRITE with ECC\n");
|
fatal("WD1003: WRITE with ECC\n");
|
||||||
mfm->status = STAT_READY|STAT_DRQ|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DRQ | STAT_DSC;
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
case CMD_VERIFY+1:
|
case CMD_VERIFY + 1:
|
||||||
mfm->command &= 0xfe;
|
mfm->command &= 0xfe;
|
||||||
mfm->status = STAT_BUSY;
|
mfm->status = STAT_BUSY;
|
||||||
timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME);
|
timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
mfm->status = STAT_DRQ|STAT_BUSY;
|
mfm->status = STAT_DRQ | STAT_BUSY;
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -343,7 +329,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
if (drive->cfg_spt == 0) {
|
if (drive->cfg_spt == 0) {
|
||||||
/* Only accept after RESET or DIAG. */
|
/* Only accept after RESET or DIAG. */
|
||||||
drive->cfg_spt = mfm->secount;
|
drive->cfg_spt = mfm->secount;
|
||||||
drive->cfg_hpc = mfm->head+1;
|
drive->cfg_hpc = mfm->head + 1;
|
||||||
st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
|
st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
|
||||||
mfm->drvsel, drive->tracks,
|
mfm->drvsel, drive->tracks,
|
||||||
drive->cfg_spt, drive->cfg_hpc);
|
drive->cfg_spt, drive->cfg_hpc);
|
||||||
@@ -353,7 +339,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
drive->cfg_spt, drive->cfg_hpc);
|
drive->cfg_spt, drive->cfg_hpc);
|
||||||
}
|
}
|
||||||
mfm->command = 0x00;
|
mfm->command = 0x00;
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
mfm->error = 1;
|
mfm->error = 1;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
@@ -367,11 +353,10 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mfm_writew(uint16_t port, uint16_t val, void *priv)
|
mfm_writew(uint16_t port, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
|
|
||||||
if (port > 0x01f0) {
|
if (port > 0x01f0) {
|
||||||
mfm_write(port, val & 0xff, priv);
|
mfm_write(port, val & 0xff, priv);
|
||||||
@@ -389,11 +374,10 @@ mfm_writew(uint16_t port, uint16_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mfm_write(uint16_t port, uint8_t val, void *priv)
|
mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
|
|
||||||
st506_at_log("WD1003 write(%04x, %02x)\n", port, val);
|
st506_at_log("WD1003 write(%04x, %02x)\n", port, val);
|
||||||
|
|
||||||
@@ -426,7 +410,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
mfm->head = val & 0xF;
|
mfm->head = val & 0xF;
|
||||||
mfm->drvsel = (val & 0x10) ? 1 : 0;
|
mfm->drvsel = (val & 0x10) ? 1 : 0;
|
||||||
if (mfm->drives[mfm->drvsel].present)
|
if (mfm->drives[mfm->drvsel].present)
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
else
|
else
|
||||||
mfm->status = 0;
|
mfm->status = 0;
|
||||||
return;
|
return;
|
||||||
@@ -454,11 +438,10 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
mfm_readw(uint16_t port, void *priv)
|
mfm_readw(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
uint16_t ret;
|
uint16_t ret;
|
||||||
|
|
||||||
if (port > 0x01f0) {
|
if (port > 0x01f0) {
|
||||||
@@ -472,7 +455,7 @@ mfm_readw(uint16_t port, void *priv)
|
|||||||
mfm->pos += 2;
|
mfm->pos += 2;
|
||||||
if (mfm->pos >= 512) {
|
if (mfm->pos >= 512) {
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
if (mfm->command == CMD_READ) {
|
if (mfm->command == CMD_READ) {
|
||||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||||
if (mfm->secount) {
|
if (mfm->secount) {
|
||||||
@@ -480,19 +463,18 @@ mfm_readw(uint16_t port, void *priv)
|
|||||||
mfm->status = STAT_BUSY | STAT_READY | STAT_DSC;
|
mfm->status = STAT_BUSY | STAT_READY | STAT_DSC;
|
||||||
timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME);
|
timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME);
|
||||||
} else
|
} else
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
mfm_read(uint16_t port, void *priv)
|
mfm_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
@@ -513,15 +495,15 @@ mfm_read(uint16_t port, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01f4: /* CYlinder low */
|
case 0x01f4: /* CYlinder low */
|
||||||
ret = (uint8_t)(mfm->cylinder&0xff);
|
ret = (uint8_t) (mfm->cylinder & 0xff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01f5: /* Cylinder high */
|
case 0x01f5: /* Cylinder high */
|
||||||
ret = (uint8_t)(mfm->cylinder>>8);
|
ret = (uint8_t) (mfm->cylinder >> 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01f6: /* drive/head */
|
case 0x01f6: /* drive/head */
|
||||||
ret = (uint8_t)(0xa0 | mfm->head | (mfm->drvsel?0x10:0));
|
ret = (uint8_t) (0xa0 | mfm->head | (mfm->drvsel ? 0x10 : 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01f7: /* Status */
|
case 0x01f7: /* Status */
|
||||||
@@ -535,36 +517,34 @@ mfm_read(uint16_t port, void *priv)
|
|||||||
|
|
||||||
st506_at_log("WD1003 read(%04x) = %02x\n", port, ret);
|
st506_at_log("WD1003 read(%04x) = %02x\n", port, ret);
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_seek(mfm_t *mfm)
|
do_seek(mfm_t *mfm)
|
||||||
{
|
{
|
||||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||||
|
|
||||||
st506_at_log("WD1003(%d) seek(%d) max=%d\n",
|
st506_at_log("WD1003(%d) seek(%d) max=%d\n",
|
||||||
mfm->drvsel,mfm->cylinder,drive->tracks);
|
mfm->drvsel, mfm->cylinder, drive->tracks);
|
||||||
|
|
||||||
if (mfm->cylinder < drive->tracks)
|
if (mfm->cylinder < drive->tracks)
|
||||||
drive->curcyl = mfm->cylinder;
|
drive->curcyl = mfm->cylinder;
|
||||||
else
|
else
|
||||||
drive->curcyl = drive->tracks-1;
|
drive->curcyl = drive->tracks - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_callback(void *priv)
|
do_callback(void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
|
|
||||||
if (mfm->reset) {
|
if (mfm->reset) {
|
||||||
st506_at_log("WD1003(%d) reset\n", mfm->drvsel);
|
st506_at_log("WD1003(%d) reset\n", mfm->drvsel);
|
||||||
|
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
mfm->error = 1;
|
mfm->error = 1;
|
||||||
mfm->secount = 1;
|
mfm->secount = 1;
|
||||||
mfm->sector = 1;
|
mfm->sector = 1;
|
||||||
@@ -576,7 +556,7 @@ do_callback(void *priv)
|
|||||||
|
|
||||||
mfm->reset = 0;
|
mfm->reset = 0;
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -586,7 +566,7 @@ do_callback(void *priv)
|
|||||||
st506_at_log("WD1003(%d) seek, step=%d\n",
|
st506_at_log("WD1003(%d) seek, step=%d\n",
|
||||||
mfm->drvsel, drive->steprate);
|
mfm->drvsel, drive->steprate);
|
||||||
do_seek(mfm);
|
do_seek(mfm);
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -596,17 +576,17 @@ do_callback(void *priv)
|
|||||||
do_seek(mfm);
|
do_seek(mfm);
|
||||||
if (get_sector(mfm, &addr)) {
|
if (get_sector(mfm, &addr)) {
|
||||||
mfm->error = ERR_ID_NOT_FOUND;
|
mfm->error = ERR_ID_NOT_FOUND;
|
||||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
mfm->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)mfm->buffer);
|
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||||
|
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
mfm->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
mfm->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE:
|
case CMD_WRITE:
|
||||||
@@ -615,24 +595,24 @@ do_callback(void *priv)
|
|||||||
do_seek(mfm);
|
do_seek(mfm);
|
||||||
if (get_sector(mfm, &addr)) {
|
if (get_sector(mfm, &addr)) {
|
||||||
mfm->error = ERR_ID_NOT_FOUND;
|
mfm->error = ERR_ID_NOT_FOUND;
|
||||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
mfm->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer);
|
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||||
|
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
if (mfm->secount) {
|
if (mfm->secount) {
|
||||||
/* More sectors to do.. */
|
/* More sectors to do.. */
|
||||||
mfm->status |= STAT_DRQ;
|
mfm->status |= STAT_DRQ;
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
next_sector(mfm);
|
next_sector(mfm);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||||
} else
|
} else
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
@@ -640,9 +620,9 @@ do_callback(void *priv)
|
|||||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||||
do_seek(mfm);
|
do_seek(mfm);
|
||||||
mfm->pos = 0;
|
mfm->pos = 0;
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
@@ -651,16 +631,16 @@ do_callback(void *priv)
|
|||||||
do_seek(mfm);
|
do_seek(mfm);
|
||||||
if (get_sector(mfm, &addr)) {
|
if (get_sector(mfm, &addr)) {
|
||||||
mfm->error = ERR_ID_NOT_FOUND;
|
mfm->error = ERR_ID_NOT_FOUND;
|
||||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
mfm->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd_image_zero(drive->hdd_num, addr, mfm->secount);
|
hdd_image_zero(drive->hdd_num, addr, mfm->secount);
|
||||||
|
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DIAGNOSE:
|
case CMD_DIAGNOSE:
|
||||||
@@ -673,27 +653,26 @@ do_callback(void *priv)
|
|||||||
|
|
||||||
drive->steprate = 0x0f;
|
drive->steprate = 0x0f;
|
||||||
mfm->error = 1;
|
mfm->error = 1;
|
||||||
mfm->status = STAT_READY|STAT_DSC;
|
mfm->status = STAT_READY | STAT_DSC;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
st506_at_log("WD1003(%d) callback on unknown command %02x\n",
|
st506_at_log("WD1003(%d) callback on unknown command %02x\n",
|
||||||
mfm->drvsel, mfm->command);
|
mfm->drvsel, mfm->command);
|
||||||
mfm->status = STAT_READY|STAT_ERR|STAT_DSC;
|
mfm->status = STAT_READY | STAT_ERR | STAT_DSC;
|
||||||
mfm->error = ERR_ABRT;
|
mfm->error = ERR_ABRT;
|
||||||
irq_raise(mfm);
|
irq_raise(mfm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loadhd(mfm_t *mfm, int c, int d, const char *fn)
|
loadhd(mfm_t *mfm, int c, int d, const char *fn)
|
||||||
{
|
{
|
||||||
drive_t *drive = &mfm->drives[c];
|
drive_t *drive = &mfm->drives[c];
|
||||||
|
|
||||||
if (! hdd_image_load(d)) {
|
if (!hdd_image_load(d)) {
|
||||||
drive->present = 0;
|
drive->present = 0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -706,7 +685,6 @@ loadhd(mfm_t *mfm, int c, int d, const char *fn)
|
|||||||
drive->present = 1;
|
drive->present = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
mfm_init(const device_t *info)
|
mfm_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -718,18 +696,19 @@ mfm_init(const device_t *info)
|
|||||||
memset(mfm, 0x00, sizeof(mfm_t));
|
memset(mfm, 0x00, sizeof(mfm_t));
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (d=0; d<HDD_NUM; d++) {
|
for (d = 0; d < HDD_NUM; d++) {
|
||||||
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
|
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
|
||||||
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
|
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
|
||||||
|
|
||||||
st506_at_log("WD1003(%d): (%s) geometry %d/%d/%d\n", c, hdd[d].fn,
|
st506_at_log("WD1003(%d): (%s) geometry %d/%d/%d\n", c, hdd[d].fn,
|
||||||
(int)hdd[d].tracks, (int)hdd[d].hpc, (int)hdd[d].spt);
|
(int) hdd[d].tracks, (int) hdd[d].hpc, (int) hdd[d].spt);
|
||||||
|
|
||||||
if (++c >= MFM_NUM) break;
|
if (++c >= MFM_NUM)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mfm->status = STAT_READY|STAT_DSC; /* drive is ready */
|
mfm->status = STAT_READY | STAT_DSC; /* drive is ready */
|
||||||
mfm->error = 1; /* no errors */
|
mfm->error = 1; /* no errors */
|
||||||
|
|
||||||
io_sethandler(0x01f0, 1,
|
io_sethandler(0x01f0, 1,
|
||||||
@@ -741,19 +720,18 @@ mfm_init(const device_t *info)
|
|||||||
|
|
||||||
timer_add(&mfm->callback_timer, do_callback, mfm, 0);
|
timer_add(&mfm->callback_timer, do_callback, mfm, 0);
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
|
|
||||||
return(mfm);
|
return (mfm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mfm_close(void *priv)
|
mfm_close(void *priv)
|
||||||
{
|
{
|
||||||
mfm_t *mfm = (mfm_t *)priv;
|
mfm_t *mfm = (mfm_t *) priv;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
for (d=0; d<2; d++) {
|
for (d = 0; d < 2; d++) {
|
||||||
drive_t *drive = &mfm->drives[d];
|
drive_t *drive = &mfm->drives[d];
|
||||||
|
|
||||||
hdd_image_close(drive->hdd_num);
|
hdd_image_close(drive->hdd_num);
|
||||||
@@ -761,7 +739,7 @@ mfm_close(void *priv)
|
|||||||
|
|
||||||
free(mfm);
|
free(mfm);
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const device_t st506_at_wd1003_device = {
|
const device_t st506_at_wd1003_device = {
|
||||||
|
|||||||
@@ -87,7 +87,6 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
|
||||||
#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin"
|
#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin"
|
||||||
#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin"
|
#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin"
|
||||||
#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin"
|
#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin"
|
||||||
@@ -101,7 +100,6 @@
|
|||||||
#define WD1004_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
#define WD1004_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
||||||
#define WD1004A_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
#define WD1004A_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
|
||||||
|
|
||||||
|
|
||||||
#define ST506_TIME (250 * TIMER_USEC)
|
#define ST506_TIME (250 * TIMER_USEC)
|
||||||
#define ST506_TIME_MS (1000 * TIMER_USEC)
|
#define ST506_TIME_MS (1000 * TIMER_USEC)
|
||||||
|
|
||||||
@@ -110,7 +108,6 @@
|
|||||||
#define MFM_SECTORS 17
|
#define MFM_SECTORS 17
|
||||||
#define RLL_SECTORS 26
|
#define RLL_SECTORS 26
|
||||||
|
|
||||||
|
|
||||||
/* Status register. */
|
/* Status register. */
|
||||||
#define STAT_REQ 0x01 /* controller ready */
|
#define STAT_REQ 0x01 /* controller ready */
|
||||||
#define STAT_IO 0x02 /* input, data to host */
|
#define STAT_IO 0x02 /* input, data to host */
|
||||||
@@ -127,10 +124,10 @@
|
|||||||
#define ERR_BV 0x80
|
#define ERR_BV 0x80
|
||||||
#define ERR_TYPE_MASK 0x30
|
#define ERR_TYPE_MASK 0x30
|
||||||
#define ERR_TYPE_SHIFT 4
|
#define ERR_TYPE_SHIFT 4
|
||||||
# define ERR_TYPE_DRIVE 0x00
|
#define ERR_TYPE_DRIVE 0x00
|
||||||
# define ERR_TYPE_CONTROLLER 0x01
|
#define ERR_TYPE_CONTROLLER 0x01
|
||||||
# define ERR_TYPE_COMMAND 0x02
|
#define ERR_TYPE_COMMAND 0x02
|
||||||
# define ERR_TYPE_MISC 0x03
|
#define ERR_TYPE_MISC 0x03
|
||||||
|
|
||||||
/* No, um, errors.. */
|
/* No, um, errors.. */
|
||||||
#define ERR_NONE 0x00
|
#define ERR_NONE 0x00
|
||||||
@@ -215,7 +212,6 @@ enum {
|
|||||||
STATE_DONE
|
STATE_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t present;
|
int8_t present;
|
||||||
uint8_t hdd_num;
|
uint8_t hdd_num;
|
||||||
@@ -234,7 +230,6 @@ typedef struct {
|
|||||||
uint16_t cfg_cyl;
|
uint16_t cfg_cyl;
|
||||||
} drive_t;
|
} drive_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t type; /* controller type */
|
uint8_t type; /* controller type */
|
||||||
|
|
||||||
@@ -264,7 +259,7 @@ typedef struct {
|
|||||||
head,
|
head,
|
||||||
cylinder,
|
cylinder,
|
||||||
count;
|
count;
|
||||||
uint8_t compl; /* current request completion code */
|
uint8_t compl ; /* current request completion code */
|
||||||
|
|
||||||
int buff_pos, /* pointers to the RAM buffer */
|
int buff_pos, /* pointers to the RAM buffer */
|
||||||
buff_cnt;
|
buff_cnt;
|
||||||
@@ -274,7 +269,6 @@ typedef struct {
|
|||||||
uint8_t buff[SECTOR_SIZE + 4]; /* sector buffer RAM (+ ECC bytes) */
|
uint8_t buff[SECTOR_SIZE + 4]; /* sector buffer RAM (+ ECC bytes) */
|
||||||
} hdc_t;
|
} hdc_t;
|
||||||
|
|
||||||
|
|
||||||
/* Supported drives table for the Xebec controller. */
|
/* Supported drives table for the Xebec controller. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t tracks;
|
uint16_t tracks;
|
||||||
@@ -283,17 +277,15 @@ typedef struct {
|
|||||||
} hd_type_t;
|
} hd_type_t;
|
||||||
|
|
||||||
hd_type_t hd_types[4] = {
|
hd_type_t hd_types[4] = {
|
||||||
{ 306, 4, MFM_SECTORS }, /* type 0 */
|
{306, 4, MFM_SECTORS}, /* type 0 */
|
||||||
{ 612, 4, MFM_SECTORS }, /* type 16 */
|
{ 612, 4, MFM_SECTORS}, /* type 16 */
|
||||||
{ 615, 4, MFM_SECTORS }, /* type 2 */
|
{ 615, 4, MFM_SECTORS}, /* type 2 */
|
||||||
{ 306, 8, MFM_SECTORS } /* type 13 */
|
{ 306, 8, MFM_SECTORS} /* type 13 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_ST506_XT_LOG
|
#ifdef ENABLE_ST506_XT_LOG
|
||||||
int st506_xt_do_log = ENABLE_ST506_XT_LOG;
|
int st506_xt_do_log = ENABLE_ST506_XT_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_xt_log(const char *fmt, ...)
|
st506_xt_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -306,10 +298,9 @@ st506_xt_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define st506_xt_log(fmt, ...)
|
# define st506_xt_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_complete(hdc_t *dev)
|
st506_complete(hdc_t *dev)
|
||||||
{
|
{
|
||||||
@@ -325,7 +316,6 @@ st506_complete(hdc_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_error(hdc_t *dev, uint8_t err)
|
st506_error(hdc_t *dev, uint8_t err)
|
||||||
{
|
{
|
||||||
@@ -333,21 +323,20 @@ st506_error(hdc_t *dev, uint8_t err)
|
|||||||
dev->error = err;
|
dev->error = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
||||||
{
|
{
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
/* No need to log this. */
|
/* No need to log this. */
|
||||||
dev->error = dev->nr_err;
|
dev->error = dev->nr_err;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (drive->cylinder != dev->cylinder) {
|
if (drive->cylinder != dev->cylinder) {
|
||||||
#ifdef ENABLE_ST506_XT_LOG
|
# ifdef ENABLE_ST506_XT_LOG
|
||||||
st506_xt_log("ST506: get_sector: wrong cylinder\n");
|
st506_xt_log("ST506: get_sector: wrong cylinder\n");
|
||||||
#endif
|
# endif
|
||||||
dev->error = ERR_ILLEGAL_ADDR;
|
dev->error = ERR_ILLEGAL_ADDR;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@@ -358,22 +347,21 @@ get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
|||||||
st506_xt_log("ST506: get_sector: past end of configured heads\n");
|
st506_xt_log("ST506: get_sector: past end of configured heads\n");
|
||||||
#endif
|
#endif
|
||||||
dev->error = ERR_ILLEGAL_ADDR;
|
dev->error = ERR_ILLEGAL_ADDR;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (dev->sector >= drive->cfg_spt) {
|
if (dev->sector >= drive->cfg_spt) {
|
||||||
#ifdef ENABLE_ST506_XT_LOG
|
#ifdef ENABLE_ST506_XT_LOG
|
||||||
st506_xt_log("ST506: get_sector: past end of configured sectors\n");
|
st506_xt_log("ST506: get_sector: past end of configured sectors\n");
|
||||||
#endif
|
#endif
|
||||||
dev->error = ERR_ILLEGAL_ADDR;
|
dev->error = ERR_ILLEGAL_ADDR;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
*addr = ((((off64_t)dev->cylinder * drive->cfg_hpc) + dev->head) * drive->cfg_spt) + dev->sector;
|
*addr = ((((off64_t) dev->cylinder * drive->cfg_hpc) + dev->head) * drive->cfg_spt) + dev->sector;
|
||||||
|
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
next_sector(hdc_t *dev, drive_t *drive)
|
next_sector(hdc_t *dev, drive_t *drive)
|
||||||
{
|
{
|
||||||
@@ -394,7 +382,6 @@ next_sector(hdc_t *dev, drive_t *drive)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Extract the CHS info from a command block. */
|
/* Extract the CHS info from a command block. */
|
||||||
static int
|
static int
|
||||||
get_chs(hdc_t *dev, drive_t *drive)
|
get_chs(hdc_t *dev, drive_t *drive)
|
||||||
@@ -419,19 +406,18 @@ get_chs(hdc_t *dev, drive_t *drive)
|
|||||||
* result in an ERR_ILLEGAL_ADDR. --FvK
|
* result in an ERR_ILLEGAL_ADDR. --FvK
|
||||||
*/
|
*/
|
||||||
drive->cylinder = drive->cfg_cyl - 1;
|
drive->cylinder = drive->cfg_cyl - 1;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
drive->cylinder = dev->cylinder;
|
drive->cylinder = dev->cylinder;
|
||||||
|
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_callback(void *priv)
|
st506_callback(void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
uint32_t capac;
|
uint32_t capac;
|
||||||
@@ -451,7 +437,7 @@ st506_callback(void *priv)
|
|||||||
case CMD_TEST_DRIVE_READY:
|
case CMD_TEST_DRIVE_READY:
|
||||||
st506_xt_log("ST506: TEST_READY(%i) = %i\n",
|
st506_xt_log("ST506: TEST_READY(%i) = %i\n",
|
||||||
dev->drive_sel, drive->present);
|
dev->drive_sel, drive->present);
|
||||||
if (! drive->present)
|
if (!drive->present)
|
||||||
st506_error(dev, dev->nr_err);
|
st506_error(dev, dev->nr_err);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
break;
|
break;
|
||||||
@@ -461,7 +447,7 @@ st506_callback(void *priv)
|
|||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
st506_xt_log("ST506: RECALIBRATE(%i) [%i]\n",
|
st506_xt_log("ST506: RECALIBRATE(%i) [%i]\n",
|
||||||
dev->drive_sel, drive->present);
|
dev->drive_sel, drive->present);
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
st506_error(dev, dev->nr_err);
|
st506_error(dev, dev->nr_err);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
break;
|
break;
|
||||||
@@ -494,10 +480,8 @@ st506_callback(void *priv)
|
|||||||
dev->error = 0;
|
dev->error = 0;
|
||||||
|
|
||||||
/* Give address of last operation. */
|
/* Give address of last operation. */
|
||||||
dev->buff[1] = (dev->drive_sel ? 0x20 : 0) |
|
dev->buff[1] = (dev->drive_sel ? 0x20 : 0) | dev->head;
|
||||||
dev->head;
|
dev->buff[2] = ((dev->cylinder & 0x0300) >> 2) | dev->sector;
|
||||||
dev->buff[2] = ((dev->cylinder & 0x0300) >> 2) |
|
|
||||||
dev->sector;
|
|
||||||
dev->buff[3] = (dev->cylinder & 0xff);
|
dev->buff[3] = (dev->cylinder & 0xff);
|
||||||
|
|
||||||
dev->status = STAT_BSY | STAT_IO | STAT_REQ;
|
dev->status = STAT_BSY | STAT_IO | STAT_REQ;
|
||||||
@@ -513,7 +497,7 @@ st506_callback(void *priv)
|
|||||||
case CMD_FORMAT_DRIVE:
|
case CMD_FORMAT_DRIVE:
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: FORMAT_DRIVE(%i) interleave=%i\n",
|
st506_xt_log("ST506: FORMAT_DRIVE(%i) interleave=%i\n",
|
||||||
dev->drive_sel, dev->command[4]);
|
dev->drive_sel, dev->command[4]);
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||||
@@ -522,7 +506,7 @@ st506_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_DATA: /* wrong, but works */
|
case STATE_SEND_DATA: /* wrong, but works */
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
@@ -549,7 +533,7 @@ st506_callback(void *priv)
|
|||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: VERIFY(%i, %i/%i/%i, %i)\n",
|
st506_xt_log("ST506: VERIFY(%i, %i/%i/%i, %i)\n",
|
||||||
dev->drive_sel, dev->cylinder,
|
dev->drive_sel, dev->cylinder,
|
||||||
dev->head, dev->sector, dev->count);
|
dev->head, dev->sector, dev->count);
|
||||||
@@ -564,7 +548,7 @@ st506_callback(void *priv)
|
|||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
@@ -588,7 +572,7 @@ st506_callback(void *priv)
|
|||||||
case CMD_FORMAT_BAD_TRACK:
|
case CMD_FORMAT_BAD_TRACK:
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n",
|
st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n",
|
||||||
(dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "",
|
(dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "",
|
||||||
dev->drive_sel, dev->cylinder, dev->head);
|
dev->drive_sel, dev->cylinder, dev->head);
|
||||||
@@ -598,7 +582,7 @@ st506_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_DATA: /* wrong, but works */
|
case STATE_SEND_DATA: /* wrong, but works */
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
@@ -633,13 +617,13 @@ st506_callback(void *priv)
|
|||||||
#endif
|
#endif
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: READ%s(%i, %i/%i/%i, %i)\n",
|
st506_xt_log("ST506: READ%s(%i, %i/%i/%i, %i)\n",
|
||||||
(dev->command[0] == CMD_READ_LONG) ? "_LONG" : "",
|
(dev->command[0] == CMD_READ_LONG) ? "_LONG" : "",
|
||||||
dev->drive_sel, dev->cylinder,
|
dev->drive_sel, dev->cylinder,
|
||||||
dev->head, dev->sector, dev->count);
|
dev->head, dev->sector, dev->count);
|
||||||
|
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
return;
|
return;
|
||||||
@@ -648,7 +632,7 @@ st506_callback(void *priv)
|
|||||||
|
|
||||||
/* Read data from the image. */
|
/* Read data from the image. */
|
||||||
hdd_image_read(drive->hdd_num, addr, 1,
|
hdd_image_read(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->buff);
|
(uint8_t *) dev->buff);
|
||||||
|
|
||||||
/* Set up the data transfer. */
|
/* Set up the data transfer. */
|
||||||
dev->buff_pos = 0;
|
dev->buff_pos = 0;
|
||||||
@@ -689,7 +673,7 @@ st506_callback(void *priv)
|
|||||||
|
|
||||||
next_sector(dev, drive);
|
next_sector(dev, drive);
|
||||||
|
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
@@ -698,7 +682,7 @@ st506_callback(void *priv)
|
|||||||
|
|
||||||
/* Read data from the image. */
|
/* Read data from the image. */
|
||||||
hdd_image_read(drive->hdd_num, addr, 1,
|
hdd_image_read(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->buff);
|
(uint8_t *) dev->buff);
|
||||||
|
|
||||||
/* Set up the data transfer. */
|
/* Set up the data transfer. */
|
||||||
dev->buff_pos = 0;
|
dev->buff_pos = 0;
|
||||||
@@ -729,13 +713,13 @@ st506_callback(void *priv)
|
|||||||
#endif
|
#endif
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: WRITE%s(%i, %i/%i/%i, %i)\n",
|
st506_xt_log("ST506: WRITE%s(%i, %i/%i/%i, %i)\n",
|
||||||
(dev->command[0] == CMD_WRITE_LONG) ? "_LONG" : "",
|
(dev->command[0] == CMD_WRITE_LONG) ? "_LONG" : "",
|
||||||
dev->drive_sel, dev->cylinder,
|
dev->drive_sel, dev->cylinder,
|
||||||
dev->head, dev->sector, dev->count);
|
dev->head, dev->sector, dev->count);
|
||||||
|
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
st506_error(dev, ERR_BAD_PARAMETER);
|
st506_error(dev, ERR_BAD_PARAMETER);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
return;
|
return;
|
||||||
@@ -776,7 +760,7 @@ st506_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_RECEIVED_DATA:
|
case STATE_RECEIVED_DATA:
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
st506_error(dev, dev->error);
|
st506_error(dev, dev->error);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
@@ -785,7 +769,7 @@ st506_callback(void *priv)
|
|||||||
|
|
||||||
/* Write data to image. */
|
/* Write data to image. */
|
||||||
hdd_image_write(drive->hdd_num, addr, 1,
|
hdd_image_write(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->buff);
|
(uint8_t *) dev->buff);
|
||||||
|
|
||||||
if (--dev->count == 0) {
|
if (--dev->count == 0) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
@@ -813,7 +797,7 @@ st506_callback(void *priv)
|
|||||||
val = get_chs(dev, drive);
|
val = get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: SEEK(%i, %i) [%i]\n",
|
st506_xt_log("ST506: SEEK(%i, %i) [%i]\n",
|
||||||
dev->drive_sel, drive->cylinder, val);
|
dev->drive_sel, drive->cylinder, val);
|
||||||
if (! val)
|
if (!val)
|
||||||
st506_error(dev, ERR_SEEK_ERROR);
|
st506_error(dev, ERR_SEEK_ERROR);
|
||||||
} else
|
} else
|
||||||
st506_error(dev, dev->nr_err);
|
st506_error(dev, dev->nr_err);
|
||||||
@@ -941,7 +925,8 @@ st506_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_INQUIRY_ST11:
|
case CMD_INQUIRY_ST11:
|
||||||
if (dev->type == 11 || dev->type == 12) switch (dev->state) {
|
if (dev->type == 11 || dev->type == 12)
|
||||||
|
switch (dev->state) {
|
||||||
case STATE_START_COMMAND:
|
case STATE_START_COMMAND:
|
||||||
st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type);
|
st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type);
|
||||||
dev->buff_pos = 0;
|
dev->buff_pos = 0;
|
||||||
@@ -957,7 +942,8 @@ st506_callback(void *priv)
|
|||||||
case STATE_SENT_DATA:
|
case STATE_SENT_DATA:
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
st506_error(dev, ERR_BAD_COMMAND);
|
st506_error(dev, ERR_BAD_COMMAND);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
}
|
}
|
||||||
@@ -992,12 +978,12 @@ st506_callback(void *priv)
|
|||||||
* and our sector buffer contains the magic data
|
* and our sector buffer contains the magic data
|
||||||
* (see above) we need to write to it.
|
* (see above) we need to write to it.
|
||||||
*/
|
*/
|
||||||
(void)get_chs(dev, drive);
|
(void) get_chs(dev, drive);
|
||||||
st506_xt_log("ST506: WRITE BUFFER (%i, %i/%i/%i, %i)\n",
|
st506_xt_log("ST506: WRITE BUFFER (%i, %i/%i/%i, %i)\n",
|
||||||
dev->drive_sel, dev->cylinder,
|
dev->drive_sel, dev->cylinder,
|
||||||
dev->head, dev->sector, dev->count);
|
dev->head, dev->sector, dev->count);
|
||||||
|
|
||||||
if (! get_sector(dev, drive, &addr)) {
|
if (!get_sector(dev, drive, &addr)) {
|
||||||
st506_error(dev, ERR_BAD_PARAMETER);
|
st506_error(dev, ERR_BAD_PARAMETER);
|
||||||
st506_complete(dev);
|
st506_complete(dev);
|
||||||
return;
|
return;
|
||||||
@@ -1007,7 +993,7 @@ st506_callback(void *priv)
|
|||||||
|
|
||||||
/* Write data to image. */
|
/* Write data to image. */
|
||||||
hdd_image_write(drive->hdd_num, addr, 1,
|
hdd_image_write(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->buff);
|
(uint8_t *) dev->buff);
|
||||||
|
|
||||||
if (--dev->count == 0) {
|
if (--dev->count == 0) {
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||||
@@ -1098,12 +1084,11 @@ st506_callback(void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read from one of the registers. */
|
/* Read from one of the registers. */
|
||||||
static uint8_t
|
static uint8_t
|
||||||
st506_read(uint16_t port, void *priv)
|
st506_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
switch (port & 3) {
|
switch (port & 3) {
|
||||||
@@ -1111,7 +1096,7 @@ st506_read(uint16_t port, void *priv)
|
|||||||
dev->status &= ~STAT_IRQ;
|
dev->status &= ~STAT_IRQ;
|
||||||
switch (dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_COMPLETION_BYTE:
|
case STATE_COMPLETION_BYTE:
|
||||||
ret = dev->compl;
|
ret = dev->compl ;
|
||||||
dev->status = 0x00;
|
dev->status = 0x00;
|
||||||
dev->state = STATE_IDLE;
|
dev->state = STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
@@ -1141,15 +1126,14 @@ st506_read(uint16_t port, void *priv)
|
|||||||
}
|
}
|
||||||
st506_xt_log("ST506: read(%04x) = %02x\n", port, ret);
|
st506_xt_log("ST506: read(%04x) = %02x\n", port, ret);
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write to one of the registers. */
|
/* Write to one of the registers. */
|
||||||
static void
|
static void
|
||||||
st506_write(uint16_t port, uint8_t val, void *priv)
|
st506_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
|
|
||||||
st506_xt_log("ST506: write(%04x, %02x)\n", port, val);
|
st506_xt_log("ST506: write(%04x, %02x)\n", port, val);
|
||||||
switch (port & 3) {
|
switch (port & 3) {
|
||||||
@@ -1207,12 +1191,11 @@ st506_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write to ROM (or scratchpad RAM.) */
|
/* Write to ROM (or scratchpad RAM.) */
|
||||||
static void
|
static void
|
||||||
mem_write(uint32_t addr, uint8_t val, void *priv)
|
mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
uint32_t ptr, mask = 0;
|
uint32_t ptr, mask = 0;
|
||||||
|
|
||||||
/* Ignore accesses to anything below the configured address,
|
/* Ignore accesses to anything below the configured address,
|
||||||
@@ -1222,7 +1205,7 @@ mem_write(uint32_t addr, uint8_t val, void *priv)
|
|||||||
|
|
||||||
addr -= dev->bios_addr;
|
addr -= dev->bios_addr;
|
||||||
|
|
||||||
switch(dev->type) {
|
switch (dev->type) {
|
||||||
case 11: /* ST-11M */
|
case 11: /* ST-11M */
|
||||||
case 12: /* ST-11R */
|
case 12: /* ST-11R */
|
||||||
mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */
|
mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */
|
||||||
@@ -1235,16 +1218,14 @@ mem_write(uint32_t addr, uint8_t val, void *priv)
|
|||||||
addr &= dev->bios_rom.mask;
|
addr &= dev->bios_rom.mask;
|
||||||
|
|
||||||
ptr = (dev->bios_rom.mask & mask) - dev->bios_ram;
|
ptr = (dev->bios_rom.mask & mask) - dev->bios_ram;
|
||||||
if (mask && ((addr & mask) > ptr) &&
|
if (mask && ((addr & mask) > ptr) && ((addr & mask) <= (ptr + dev->bios_ram)))
|
||||||
((addr & mask) <= (ptr + dev->bios_ram)))
|
|
||||||
dev->scratch[addr & (dev->bios_ram - 1)] = val;
|
dev->scratch[addr & (dev->bios_ram - 1)] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
mem_read(uint32_t addr, void *priv)
|
mem_read(uint32_t addr, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
uint32_t ptr, mask = 0;
|
uint32_t ptr, mask = 0;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
@@ -1255,7 +1236,7 @@ mem_read(uint32_t addr, void *priv)
|
|||||||
|
|
||||||
addr -= dev->bios_addr;
|
addr -= dev->bios_addr;
|
||||||
|
|
||||||
switch(dev->type) {
|
switch (dev->type) {
|
||||||
case 0: /* Xebec */
|
case 0: /* Xebec */
|
||||||
if (addr >= 0x001000) {
|
if (addr >= 0x001000) {
|
||||||
#ifdef ENABLE_ST506_XT_LOG
|
#ifdef ENABLE_ST506_XT_LOG
|
||||||
@@ -1287,16 +1268,14 @@ mem_read(uint32_t addr, void *priv)
|
|||||||
addr = addr & dev->bios_rom.mask;
|
addr = addr & dev->bios_rom.mask;
|
||||||
|
|
||||||
ptr = (dev->bios_rom.mask & mask) - dev->bios_ram;
|
ptr = (dev->bios_rom.mask & mask) - dev->bios_ram;
|
||||||
if (mask && ((addr & mask) > ptr) &&
|
if (mask && ((addr & mask) > ptr) && ((addr & mask) <= (ptr + dev->bios_ram)))
|
||||||
((addr & mask) <= (ptr + dev->bios_ram)))
|
|
||||||
ret = dev->scratch[addr & (dev->bios_ram - 1)];
|
ret = dev->scratch[addr & (dev->bios_ram - 1)];
|
||||||
else
|
else
|
||||||
ret = dev->bios_rom.rom[addr];
|
ret = dev->bios_rom.rom[addr];
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up and load the ROM BIOS for this controller.
|
* Set up and load the ROM BIOS for this controller.
|
||||||
*
|
*
|
||||||
@@ -1326,16 +1305,16 @@ loadrom(hdc_t *dev, const char *fn)
|
|||||||
memset(&dev->bios_rom, 0x00, sizeof(rom_t));
|
memset(&dev->bios_rom, 0x00, sizeof(rom_t));
|
||||||
|
|
||||||
/* Manually load and process the ROM image. */
|
/* Manually load and process the ROM image. */
|
||||||
(void)fseek(fp, 0L, SEEK_END);
|
(void) fseek(fp, 0L, SEEK_END);
|
||||||
size = ftell(fp);
|
size = ftell(fp);
|
||||||
(void)fseek(fp, 0L, SEEK_SET);
|
(void) fseek(fp, 0L, SEEK_SET);
|
||||||
|
|
||||||
/* Load the ROM data. */
|
/* Load the ROM data. */
|
||||||
dev->bios_rom.rom = (uint8_t *)malloc(size);
|
dev->bios_rom.rom = (uint8_t *) malloc(size);
|
||||||
memset(dev->bios_rom.rom, 0xff, size);
|
memset(dev->bios_rom.rom, 0xff, size);
|
||||||
if (fread(dev->bios_rom.rom, 1, size, fp) != size)
|
if (fread(dev->bios_rom.rom, 1, size, fp) != size)
|
||||||
fatal("ST-506 XT loadrom(): Error reading data\n");
|
fatal("ST-506 XT loadrom(): Error reading data\n");
|
||||||
(void)fclose(fp);
|
(void) fclose(fp);
|
||||||
|
|
||||||
/* Set up an address mask for this memory. */
|
/* Set up an address mask for this memory. */
|
||||||
dev->bios_size = size;
|
dev->bios_size = size;
|
||||||
@@ -1343,17 +1322,16 @@ loadrom(hdc_t *dev, const char *fn)
|
|||||||
|
|
||||||
/* Map this system into the memory map. */
|
/* Map this system into the memory map. */
|
||||||
mem_mapping_add(&dev->bios_rom.mapping, dev->bios_addr, size,
|
mem_mapping_add(&dev->bios_rom.mapping, dev->bios_addr, size,
|
||||||
mem_read,NULL,NULL, mem_write,NULL,NULL,
|
mem_read, NULL, NULL, mem_write, NULL, NULL,
|
||||||
dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, dev);
|
dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loadhd(hdc_t *dev, int c, int d, const char *fn)
|
loadhd(hdc_t *dev, int c, int d, const char *fn)
|
||||||
{
|
{
|
||||||
drive_t *drive = &dev->drives[c];
|
drive_t *drive = &dev->drives[c];
|
||||||
|
|
||||||
if (! hdd_image_load(d)) {
|
if (!hdd_image_load(d)) {
|
||||||
drive->present = 0;
|
drive->present = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1376,15 +1354,14 @@ loadhd(hdc_t *dev, int c, int d, const char *fn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
drive->spt = (uint8_t)hdd[d].spt;
|
drive->spt = (uint8_t) hdd[d].spt;
|
||||||
drive->hpc = (uint8_t)hdd[d].hpc;
|
drive->hpc = (uint8_t) hdd[d].hpc;
|
||||||
drive->tracks = (uint16_t)hdd[d].tracks;
|
drive->tracks = (uint16_t) hdd[d].tracks;
|
||||||
|
|
||||||
drive->hdd_num = d;
|
drive->hdd_num = d;
|
||||||
drive->present = 1;
|
drive->present = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the "drive type" switches for the IBM Xebec controller. */
|
/* Set the "drive type" switches for the IBM Xebec controller. */
|
||||||
static void
|
static void
|
||||||
set_switches(hdc_t *dev)
|
set_switches(hdc_t *dev)
|
||||||
@@ -1397,12 +1374,11 @@ set_switches(hdc_t *dev)
|
|||||||
for (d = 0; d < MFM_NUM; d++) {
|
for (d = 0; d < MFM_NUM; d++) {
|
||||||
drive = &dev->drives[d];
|
drive = &dev->drives[d];
|
||||||
|
|
||||||
if (! drive->present) continue;
|
if (!drive->present)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (c = 0; c < 4; c++) {
|
for (c = 0; c < 4; c++) {
|
||||||
if ((drive->spt == hd_types[c].spt) &&
|
if ((drive->spt == hd_types[c].spt) && (drive->hpc == hd_types[c].hpc) && (drive->tracks == hd_types[c].tracks)) {
|
||||||
(drive->hpc == hd_types[c].hpc) &&
|
|
||||||
(drive->tracks == hd_types[c].tracks)) {
|
|
||||||
dev->switches |= (c << (d ? 0 : 2));
|
dev->switches |= (c << (d ? 0 : 2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1419,7 +1395,6 @@ set_switches(hdc_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
st506_init(const device_t *info)
|
st506_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -1427,7 +1402,7 @@ st506_init(const device_t *info)
|
|||||||
hdc_t *dev;
|
hdc_t *dev;
|
||||||
int i, c;
|
int i, c;
|
||||||
|
|
||||||
dev = (hdc_t *)malloc(sizeof(hdc_t));
|
dev = (hdc_t *) malloc(sizeof(hdc_t));
|
||||||
memset(dev, 0x00, sizeof(hdc_t));
|
memset(dev, 0x00, sizeof(hdc_t));
|
||||||
dev->type = info->local & 255;
|
dev->type = info->local & 255;
|
||||||
|
|
||||||
@@ -1439,7 +1414,7 @@ st506_init(const device_t *info)
|
|||||||
dev->bios_addr = 0xc8000;
|
dev->bios_addr = 0xc8000;
|
||||||
dev->nr_err = ERR_NOT_READY;
|
dev->nr_err = ERR_NOT_READY;
|
||||||
|
|
||||||
switch(dev->type) {
|
switch (dev->type) {
|
||||||
case 0: /* Xebec (MFM) */
|
case 0: /* Xebec (MFM) */
|
||||||
fn = XEBEC_BIOS_FILE;
|
fn = XEBEC_BIOS_FILE;
|
||||||
break;
|
break;
|
||||||
@@ -1517,13 +1492,13 @@ st506_init(const device_t *info)
|
|||||||
|
|
||||||
/* Set up the I/O region. */
|
/* Set up the I/O region. */
|
||||||
io_sethandler(dev->base, 4,
|
io_sethandler(dev->base, 4,
|
||||||
st506_read,NULL,NULL, st506_write,NULL,NULL, dev);
|
st506_read, NULL, NULL, st506_write, NULL, NULL, dev);
|
||||||
|
|
||||||
/* Add the timer. */
|
/* Add the timer. */
|
||||||
timer_add(&dev->timer, st506_callback, dev, 0);
|
timer_add(&dev->timer, st506_callback, dev, 0);
|
||||||
|
|
||||||
st506_xt_log("ST506: %s (I/O=%03X, IRQ=%i, DMA=%i, BIOS @0x%06lX, size %lu)\n",
|
st506_xt_log("ST506: %s (I/O=%03X, IRQ=%i, DMA=%i, BIOS @0x%06lX, size %lu)\n",
|
||||||
info->name,dev->base,dev->irq,dev->dma, dev->bios_addr,dev->bios_size);
|
info->name, dev->base, dev->irq, dev->dma, dev->bios_addr, dev->bios_size);
|
||||||
|
|
||||||
/* Load any drives configured for us. */
|
/* Load any drives configured for us. */
|
||||||
#ifdef ENABLE_ST506_XT_LOG
|
#ifdef ENABLE_ST506_XT_LOG
|
||||||
@@ -1535,7 +1510,8 @@ st506_init(const device_t *info)
|
|||||||
hdd[i].fn, hdd[i].mfm_channel);
|
hdd[i].fn, hdd[i].mfm_channel);
|
||||||
loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn);
|
loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn);
|
||||||
|
|
||||||
if (++c > MFM_NUM) break;
|
if (++c > MFM_NUM)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
st506_xt_log("ST506: %i disks loaded.\n", c);
|
st506_xt_log("ST506: %i disks loaded.\n", c);
|
||||||
@@ -1551,14 +1527,13 @@ st506_init(const device_t *info)
|
|||||||
dev->drives[c].cfg_spt = dev->drives[c].spt;
|
dev->drives[c].cfg_spt = dev->drives[c].spt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(dev);
|
return (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st506_close(void *priv)
|
st506_close(void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
@@ -1576,60 +1551,58 @@ st506_close(void *priv)
|
|||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xebec_available(void)
|
xebec_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(XEBEC_BIOS_FILE));
|
return (rom_present(XEBEC_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dtc5150x_available(void)
|
dtc5150x_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(DTC_BIOS_FILE));
|
return (rom_present(DTC_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
st11_m_available(void)
|
st11_m_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ST11_BIOS_FILE_OLD) && rom_present(ST11_BIOS_FILE_NEW));
|
return (rom_present(ST11_BIOS_FILE_OLD) && rom_present(ST11_BIOS_FILE_NEW));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
st11_r_available(void)
|
st11_r_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ST11_BIOS_FILE_OLD) && rom_present(ST11_BIOS_FILE_NEW));
|
return (rom_present(ST11_BIOS_FILE_OLD) && rom_present(ST11_BIOS_FILE_NEW));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1002a_wx1_available(void)
|
wd1002a_wx1_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD1002A_WX1_BIOS_FILE));
|
return (rom_present(WD1002A_WX1_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1002a_27x_available(void)
|
wd1002a_27x_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD1002A_27X_BIOS_FILE));
|
return (rom_present(WD1002A_27X_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1004a_wx1_available(void)
|
wd1004a_wx1_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD1004A_WX1_BIOS_FILE));
|
return (rom_present(WD1004A_WX1_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1004_27x_available(void)
|
wd1004_27x_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD1004_27X_BIOS_FILE));
|
return (rom_present(WD1004_27X_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wd1004a_27x_available(void)
|
wd1004a_27x_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD1004A_27X_BIOS_FILE));
|
return (rom_present(WD1004A_27X_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|||||||
@@ -104,12 +104,10 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
#define HDC_TIME (50 * TIMER_USEC)
|
||||||
#define HDC_TIME (50*TIMER_USEC)
|
|
||||||
|
|
||||||
#define WD_BIOS_FILE "roms/hdd/xta/idexywd2.bin"
|
#define WD_BIOS_FILE "roms/hdd/xta/idexywd2.bin"
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STATE_IDLE = 0,
|
STATE_IDLE = 0,
|
||||||
STATE_RECV,
|
STATE_RECV,
|
||||||
@@ -121,18 +119,17 @@ enum {
|
|||||||
STATE_COMPL
|
STATE_COMPL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Command values. */
|
/* Command values. */
|
||||||
#define CMD_TEST_READY 0x00
|
#define CMD_TEST_READY 0x00
|
||||||
#define CMD_RECALIBRATE 0x01
|
#define CMD_RECALIBRATE 0x01
|
||||||
/* unused 0x02 */
|
/* unused 0x02 */
|
||||||
#define CMD_READ_SENSE 0x03
|
#define CMD_READ_SENSE 0x03
|
||||||
#define CMD_FORMAT_DRIVE 0x04
|
#define CMD_FORMAT_DRIVE 0x04
|
||||||
#define CMD_READ_VERIFY 0x05
|
#define CMD_READ_VERIFY 0x05
|
||||||
#define CMD_FORMAT_TRACK 0x06
|
#define CMD_FORMAT_TRACK 0x06
|
||||||
#define CMD_FORMAT_BAD_TRACK 0x07
|
#define CMD_FORMAT_BAD_TRACK 0x07
|
||||||
#define CMD_READ_SECTORS 0x08
|
#define CMD_READ_SECTORS 0x08
|
||||||
/* unused 0x09 */
|
/* unused 0x09 */
|
||||||
#define CMD_WRITE_SECTORS 0x0a
|
#define CMD_WRITE_SECTORS 0x0a
|
||||||
#define CMD_SEEK 0x0b
|
#define CMD_SEEK 0x0b
|
||||||
#define CMD_SET_DRIVE_PARAMS 0x0c
|
#define CMD_SET_DRIVE_PARAMS 0x0c
|
||||||
@@ -140,8 +137,8 @@ enum {
|
|||||||
#define CMD_READ_SECTOR_BUFFER 0x0e
|
#define CMD_READ_SECTOR_BUFFER 0x0e
|
||||||
#define CMD_WRITE_SECTOR_BUFFER 0x0f
|
#define CMD_WRITE_SECTOR_BUFFER 0x0f
|
||||||
#define CMD_RAM_DIAGS 0xe0
|
#define CMD_RAM_DIAGS 0xe0
|
||||||
/* unused 0xe1 */
|
/* unused 0xe1 */
|
||||||
/* unused 0xe2 */
|
/* unused 0xe2 */
|
||||||
#define CMD_DRIVE_DIAGS 0xe3
|
#define CMD_DRIVE_DIAGS 0xe3
|
||||||
#define CMD_CTRL_DIAGS 0xe4
|
#define CMD_CTRL_DIAGS 0xe4
|
||||||
#define CMD_READ_LONG 0xe5
|
#define CMD_READ_LONG 0xe5
|
||||||
@@ -184,18 +181,17 @@ enum {
|
|||||||
#define IRQ_ENA 0x02
|
#define IRQ_ENA 0x02
|
||||||
#define DMA_ENA 0x01
|
#define DMA_ENA 0x01
|
||||||
|
|
||||||
|
|
||||||
/* The device control block (6 bytes) */
|
/* The device control block (6 bytes) */
|
||||||
#pragma pack(push,1)
|
#pragma pack(push, 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cmd; /* [7:5] class, [4:0] opcode */
|
uint8_t cmd; /* [7:5] class, [4:0] opcode */
|
||||||
|
|
||||||
uint8_t head :5, /* [4:0] head number */
|
uint8_t head : 5, /* [4:0] head number */
|
||||||
drvsel :1, /* [5] drive select */
|
drvsel : 1, /* [5] drive select */
|
||||||
mbz :2; /* [7:6] 00 */
|
mbz : 2; /* [7:6] 00 */
|
||||||
|
|
||||||
uint8_t sector :6, /* [5:0] sector number 0-63 */
|
uint8_t sector : 6, /* [5:0] sector number 0-63 */
|
||||||
cyl_high :2; /* [7:6] cylinder [9:8] bits */
|
cyl_high : 2; /* [7:6] cylinder [9:8] bits */
|
||||||
|
|
||||||
uint8_t cyl_low; /* [7:0] cylinder [7:0] bits */
|
uint8_t cyl_low; /* [7:0] cylinder [7:0] bits */
|
||||||
|
|
||||||
@@ -206,7 +202,7 @@ typedef struct {
|
|||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/* The (configured) Drive Parameters. */
|
/* The (configured) Drive Parameters. */
|
||||||
#pragma pack(push,1)
|
#pragma pack(push, 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cyl_high; /* (MSB) number of cylinders */
|
uint8_t cyl_high; /* (MSB) number of cylinders */
|
||||||
uint8_t cyl_low; /* (LSB) number of cylinders */
|
uint8_t cyl_low; /* (LSB) number of cylinders */
|
||||||
@@ -237,7 +233,6 @@ typedef struct {
|
|||||||
uint16_t cfg_tracks;
|
uint16_t cfg_tracks;
|
||||||
} drive_t;
|
} drive_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name; /* controller name */
|
const char *name; /* controller name */
|
||||||
|
|
||||||
@@ -276,11 +271,9 @@ typedef struct {
|
|||||||
uint8_t sector_buf[512]; /* sector buffer */
|
uint8_t sector_buf[512]; /* sector buffer */
|
||||||
} hdc_t;
|
} hdc_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_XTA_LOG
|
#ifdef ENABLE_XTA_LOG
|
||||||
int xta_do_log = ENABLE_XTA_LOG;
|
int xta_do_log = ENABLE_XTA_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xta_log(const char *fmt, ...)
|
xta_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -293,14 +286,13 @@ xta_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define xta_log(fmt, ...)
|
# define xta_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_intr(hdc_t *dev)
|
set_intr(hdc_t *dev)
|
||||||
{
|
{
|
||||||
dev->status = STAT_REQ|STAT_CD|STAT_IO|STAT_BSY;
|
dev->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY;
|
||||||
dev->state = STATE_COMPL;
|
dev->state = STATE_COMPL;
|
||||||
|
|
||||||
if (dev->intr & IRQ_ENA) {
|
if (dev->intr & IRQ_ENA) {
|
||||||
@@ -309,7 +301,6 @@ set_intr(hdc_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the logical (block) address of a CHS triplet. */
|
/* Get the logical (block) address of a CHS triplet. */
|
||||||
static int
|
static int
|
||||||
get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
||||||
@@ -318,29 +309,27 @@ get_sector(hdc_t *dev, drive_t *drive, off64_t *addr)
|
|||||||
xta_log("%s: get_sector: wrong cylinder %d/%d\n",
|
xta_log("%s: get_sector: wrong cylinder %d/%d\n",
|
||||||
dev->name, drive->cur_cyl, dev->track);
|
dev->name, drive->cur_cyl, dev->track);
|
||||||
dev->sense = ERR_ILLADDR;
|
dev->sense = ERR_ILLADDR;
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->head >= drive->hpc) {
|
if (dev->head >= drive->hpc) {
|
||||||
xta_log("%s: get_sector: past end of heads\n", dev->name);
|
xta_log("%s: get_sector: past end of heads\n", dev->name);
|
||||||
dev->sense = ERR_ILLADDR;
|
dev->sense = ERR_ILLADDR;
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->sector >= drive->spt) {
|
if (dev->sector >= drive->spt) {
|
||||||
xta_log("%s: get_sector: past end of sectors\n", dev->name);
|
xta_log("%s: get_sector: past end of sectors\n", dev->name);
|
||||||
dev->sense = ERR_ILLADDR;
|
dev->sense = ERR_ILLADDR;
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate logical address (block number) of desired sector. */
|
/* Calculate logical address (block number) of desired sector. */
|
||||||
*addr = ((((off64_t) dev->track*drive->hpc) + \
|
*addr = ((((off64_t) dev->track * drive->hpc) + dev->head) * drive->spt) + dev->sector;
|
||||||
dev->head)*drive->spt) + dev->sector;
|
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
next_sector(hdc_t *dev, drive_t *drive)
|
next_sector(hdc_t *dev, drive_t *drive)
|
||||||
{
|
{
|
||||||
@@ -371,7 +360,6 @@ xta_set_callback(hdc_t *dev, uint64_t callback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Perform the seek operation. */
|
/* Perform the seek operation. */
|
||||||
static void
|
static void
|
||||||
do_seek(hdc_t *dev, drive_t *drive, int cyl)
|
do_seek(hdc_t *dev, drive_t *drive, int cyl)
|
||||||
@@ -384,7 +372,6 @@ do_seek(hdc_t *dev, drive_t *drive, int cyl)
|
|||||||
drive->cur_cyl = dev->track;
|
drive->cur_cyl = dev->track;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Format a track or an entire drive. */
|
/* Format a track or an entire drive. */
|
||||||
static void
|
static void
|
||||||
do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb)
|
do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb)
|
||||||
@@ -415,7 +402,7 @@ do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb)
|
|||||||
dev->sector = 0;
|
dev->sector = 0;
|
||||||
|
|
||||||
/* Activate the status icon. */
|
/* Activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
|
||||||
|
|
||||||
do_fmt:
|
do_fmt:
|
||||||
/*
|
/*
|
||||||
@@ -434,31 +421,32 @@ do_fmt:
|
|||||||
dev->sector = s;
|
dev->sector = s;
|
||||||
|
|
||||||
/* Get address of sector to write. */
|
/* Get address of sector to write. */
|
||||||
if (get_sector(dev, drive, &addr)) break;
|
if (get_sector(dev, drive, &addr))
|
||||||
|
break;
|
||||||
|
|
||||||
/* Write the block to the image. */
|
/* Write the block to the image. */
|
||||||
hdd_image_write(drive->hdd_num, addr, 1,
|
hdd_image_write(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->sector_buf);
|
(uint8_t *) dev->sector_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One more track done. */
|
/* One more track done. */
|
||||||
if (++start_cyl == end_cyl) break;
|
if (++start_cyl == end_cyl)
|
||||||
|
break;
|
||||||
|
|
||||||
/* This saves us a LOT of code. */
|
/* This saves us a LOT of code. */
|
||||||
goto do_fmt;
|
goto do_fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* De-activate the status icon. */
|
/* De-activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Execute the DCB we just received. */
|
/* Execute the DCB we just received. */
|
||||||
static void
|
static void
|
||||||
hdc_callback(void *priv)
|
hdc_callback(void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
dcb_t *dcb = &dev->dcb;
|
dcb_t *dcb = &dev->dcb;
|
||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
dprm_t *params;
|
dprm_t *params;
|
||||||
@@ -475,7 +463,7 @@ hdc_callback(void *priv)
|
|||||||
|
|
||||||
switch (dcb->cmd) {
|
switch (dcb->cmd) {
|
||||||
case CMD_TEST_READY:
|
case CMD_TEST_READY:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
dev->sense = ERR_NOTRDY;
|
dev->sense = ERR_NOTRDY;
|
||||||
}
|
}
|
||||||
@@ -483,7 +471,7 @@ hdc_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_RECALIBRATE:
|
case CMD_RECALIBRATE:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
dev->sense = ERR_NOTRDY;
|
dev->sense = ERR_NOTRDY;
|
||||||
} else {
|
} else {
|
||||||
@@ -493,15 +481,14 @@ hdc_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_SENSE:
|
case CMD_READ_SENSE:
|
||||||
switch(dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
dev->buf_idx = 0;
|
dev->buf_idx = 0;
|
||||||
dev->buf_len = 4;
|
dev->buf_len = 4;
|
||||||
dev->buf_ptr = dev->data;
|
dev->buf_ptr = dev->data;
|
||||||
dev->buf_ptr[0] = dev->sense;
|
dev->buf_ptr[0] = dev->sense;
|
||||||
dev->buf_ptr[1] = dcb->drvsel ? 0x20 : 0x00;
|
dev->buf_ptr[1] = dcb->drvsel ? 0x20 : 0x00;
|
||||||
dev->buf_ptr[2] = (drive->cur_cyl >> 2) | \
|
dev->buf_ptr[2] = (drive->cur_cyl >> 2) | (dev->sector & 0x3f);
|
||||||
(dev->sector & 0x3f);
|
|
||||||
dev->buf_ptr[3] = (drive->cur_cyl & 0xff);
|
dev->buf_ptr[3] = (drive->cur_cyl & 0xff);
|
||||||
dev->sense = ERR_NOERROR;
|
dev->sense = ERR_NOERROR;
|
||||||
dev->status |= (STAT_IO | STAT_REQ);
|
dev->status |= (STAT_IO | STAT_REQ);
|
||||||
@@ -518,7 +505,7 @@ hdc_callback(void *priv)
|
|||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
|
|
||||||
case CMD_READ_SECTORS:
|
case CMD_READ_SECTORS:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
dev->sense = ERR_NOTRDY;
|
dev->sense = ERR_NOTRDY;
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
@@ -529,12 +516,12 @@ hdc_callback(void *priv)
|
|||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
/* Seek to cylinder. */
|
/* Seek to cylinder. */
|
||||||
do_seek(dev, drive,
|
do_seek(dev, drive,
|
||||||
(dcb->cyl_low|(dcb->cyl_high<<8)));
|
(dcb->cyl_low | (dcb->cyl_high << 8)));
|
||||||
dev->head = dcb->head;
|
dev->head = dcb->head;
|
||||||
dev->sector = dcb->sector;
|
dev->sector = dcb->sector;
|
||||||
|
|
||||||
/* Get sector count; count=0 means 256. */
|
/* Get sector count; count=0 means 256. */
|
||||||
dev->count = (int)dcb->count;
|
dev->count = (int) dcb->count;
|
||||||
if (dev->count == 0)
|
if (dev->count == 0)
|
||||||
dev->count = 256;
|
dev->count = 256;
|
||||||
dev->buf_len = 512;
|
dev->buf_len = 512;
|
||||||
@@ -544,12 +531,12 @@ hdc_callback(void *priv)
|
|||||||
|
|
||||||
case STATE_SEND:
|
case STATE_SEND:
|
||||||
/* Activate the status icon. */
|
/* Activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
|
||||||
do_send:
|
do_send:
|
||||||
/* Get address of sector to load. */
|
/* Get address of sector to load. */
|
||||||
if (get_sector(dev, drive, &addr)) {
|
if (get_sector(dev, drive, &addr)) {
|
||||||
/* De-activate the status icon. */
|
/* De-activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
return;
|
return;
|
||||||
@@ -557,7 +544,7 @@ do_send:
|
|||||||
|
|
||||||
/* Read the block from the image. */
|
/* Read the block from the image. */
|
||||||
hdd_image_read(drive->hdd_num, addr, 1,
|
hdd_image_read(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->sector_buf);
|
(uint8_t *) dev->sector_buf);
|
||||||
|
|
||||||
/* Ready to transfer the data out. */
|
/* Ready to transfer the data out. */
|
||||||
dev->state = STATE_SDATA;
|
dev->state = STATE_SDATA;
|
||||||
@@ -583,7 +570,7 @@ do_send:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SDATA:
|
case STATE_SDATA:
|
||||||
if (! no_data) {
|
if (!no_data) {
|
||||||
/* Perform DMA. */
|
/* Perform DMA. */
|
||||||
while (dev->buf_idx < dev->buf_len) {
|
while (dev->buf_idx < dev->buf_len) {
|
||||||
val = dma_channel_write(dev->dma,
|
val = dma_channel_write(dev->dma,
|
||||||
@@ -591,7 +578,7 @@ do_send:
|
|||||||
if (val == DMA_NODATA) {
|
if (val == DMA_NODATA) {
|
||||||
xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len);
|
xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len);
|
||||||
|
|
||||||
dev->status |= (STAT_CD | STAT_IO| STAT_REQ);
|
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
|
||||||
xta_set_callback(dev, HDC_TIME);
|
xta_set_callback(dev, HDC_TIME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -607,7 +594,7 @@ do_send:
|
|||||||
dev->buf_idx = 0;
|
dev->buf_idx = 0;
|
||||||
if (--dev->count == 0) {
|
if (--dev->count == 0) {
|
||||||
/* De-activate the status icon. */
|
/* De-activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||||
|
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
return;
|
return;
|
||||||
@@ -623,7 +610,7 @@ do_send:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE_SECTORS:
|
case CMD_WRITE_SECTORS:
|
||||||
if (! drive->present) {
|
if (!drive->present) {
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
dev->sense = ERR_NOTRDY;
|
dev->sense = ERR_NOTRDY;
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
@@ -634,12 +621,12 @@ do_send:
|
|||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
/* Seek to cylinder. */
|
/* Seek to cylinder. */
|
||||||
do_seek(dev, drive,
|
do_seek(dev, drive,
|
||||||
(dcb->cyl_low|(dcb->cyl_high<<8)));
|
(dcb->cyl_low | (dcb->cyl_high << 8)));
|
||||||
dev->head = dcb->head;
|
dev->head = dcb->head;
|
||||||
dev->sector = dcb->sector;
|
dev->sector = dcb->sector;
|
||||||
|
|
||||||
/* Get sector count; count=0 means 256. */
|
/* Get sector count; count=0 means 256. */
|
||||||
dev->count = (int)dev->dcb.count;
|
dev->count = (int) dev->dcb.count;
|
||||||
if (dev->count == 0)
|
if (dev->count == 0)
|
||||||
dev->count = 256;
|
dev->count = 256;
|
||||||
dev->buf_len = 512;
|
dev->buf_len = 512;
|
||||||
@@ -649,7 +636,7 @@ do_send:
|
|||||||
|
|
||||||
case STATE_RECV:
|
case STATE_RECV:
|
||||||
/* Activate the status icon. */
|
/* Activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
|
||||||
do_recv:
|
do_recv:
|
||||||
/* Ready to transfer the data in. */
|
/* Ready to transfer the data in. */
|
||||||
dev->state = STATE_RDATA;
|
dev->state = STATE_RDATA;
|
||||||
@@ -666,7 +653,7 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_RDATA:
|
case STATE_RDATA:
|
||||||
if (! no_data) {
|
if (!no_data) {
|
||||||
/* Perform DMA. */
|
/* Perform DMA. */
|
||||||
dev->status = STAT_BSY;
|
dev->status = STAT_BSY;
|
||||||
while (dev->buf_idx < dev->buf_len) {
|
while (dev->buf_idx < dev->buf_len) {
|
||||||
@@ -690,14 +677,14 @@ do_recv:
|
|||||||
|
|
||||||
case STATE_RDONE:
|
case STATE_RDONE:
|
||||||
/* Copy from data to sector if PIO. */
|
/* Copy from data to sector if PIO. */
|
||||||
if (! (dev->intr & DMA_ENA))
|
if (!(dev->intr & DMA_ENA))
|
||||||
memcpy(dev->sector_buf, dev->data,
|
memcpy(dev->sector_buf, dev->data,
|
||||||
dev->buf_len);
|
dev->buf_len);
|
||||||
|
|
||||||
/* Get address of sector to write. */
|
/* Get address of sector to write. */
|
||||||
if (get_sector(dev, drive, &addr)) {
|
if (get_sector(dev, drive, &addr)) {
|
||||||
/* De-activate the status icon. */
|
/* De-activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||||
|
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
@@ -706,12 +693,12 @@ do_recv:
|
|||||||
|
|
||||||
/* Write the block to the image. */
|
/* Write the block to the image. */
|
||||||
hdd_image_write(drive->hdd_num, addr, 1,
|
hdd_image_write(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)dev->sector_buf);
|
(uint8_t *) dev->sector_buf);
|
||||||
|
|
||||||
dev->buf_idx = 0;
|
dev->buf_idx = 0;
|
||||||
if (--dev->count == 0) {
|
if (--dev->count == 0) {
|
||||||
/* De-activate the status icon. */
|
/* De-activate the status icon. */
|
||||||
ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0);
|
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||||
|
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
return;
|
return;
|
||||||
@@ -754,19 +741,18 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_DRIVE_PARAMS:
|
case CMD_SET_DRIVE_PARAMS:
|
||||||
switch(dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
dev->state = STATE_RDATA;
|
dev->state = STATE_RDATA;
|
||||||
dev->buf_idx = 0;
|
dev->buf_idx = 0;
|
||||||
dev->buf_len = sizeof(dprm_t);
|
dev->buf_len = sizeof(dprm_t);
|
||||||
dev->buf_ptr = (uint8_t *)dev->data;
|
dev->buf_ptr = (uint8_t *) dev->data;
|
||||||
dev->status |= STAT_REQ;
|
dev->status |= STAT_REQ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_RDONE:
|
case STATE_RDONE:
|
||||||
params = (dprm_t *)dev->data;
|
params = (dprm_t *) dev->data;
|
||||||
drive->tracks =
|
drive->tracks = (params->cyl_high << 8) | params->cyl_low;
|
||||||
(params->cyl_high << 8) | params->cyl_low;
|
|
||||||
drive->hpc = params->heads;
|
drive->hpc = params->heads;
|
||||||
drive->spt = 17 /*hardcoded*/;
|
drive->spt = 17 /*hardcoded*/;
|
||||||
dev->status &= ~STAT_REQ;
|
dev->status &= ~STAT_REQ;
|
||||||
@@ -811,7 +797,7 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_RDONE:
|
case STATE_RDONE:
|
||||||
if (! (dev->intr & DMA_ENA))
|
if (!(dev->intr & DMA_ENA))
|
||||||
memcpy(dev->sector_buf,
|
memcpy(dev->sector_buf,
|
||||||
dev->data, dev->buf_len);
|
dev->data, dev->buf_len);
|
||||||
set_intr(dev);
|
set_intr(dev);
|
||||||
@@ -820,7 +806,7 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_RAM_DIAGS:
|
case CMD_RAM_DIAGS:
|
||||||
switch(dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
dev->state = STATE_RDONE;
|
dev->state = STATE_RDONE;
|
||||||
xta_set_callback(dev, 5 * HDC_TIME);
|
xta_set_callback(dev, 5 * HDC_TIME);
|
||||||
@@ -833,7 +819,7 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DRIVE_DIAGS:
|
case CMD_DRIVE_DIAGS:
|
||||||
switch(dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
if (drive->present) {
|
if (drive->present) {
|
||||||
dev->state = STATE_RDONE;
|
dev->state = STATE_RDONE;
|
||||||
@@ -852,7 +838,7 @@ do_recv:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_CTRL_DIAGS:
|
case CMD_CTRL_DIAGS:
|
||||||
switch(dev->state) {
|
switch (dev->state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
dev->state = STATE_RDONE;
|
dev->state = STATE_RDONE;
|
||||||
xta_set_callback(dev, 10 * HDC_TIME);
|
xta_set_callback(dev, 10 * HDC_TIME);
|
||||||
@@ -872,12 +858,11 @@ do_recv:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read one of the controller registers. */
|
/* Read one of the controller registers. */
|
||||||
static uint8_t
|
static uint8_t
|
||||||
hdc_read(uint16_t port, void *priv)
|
hdc_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
switch (port & 7) {
|
switch (port & 7) {
|
||||||
@@ -901,7 +886,7 @@ hdc_read(uint16_t port, void *priv)
|
|||||||
xta_set_callback(dev, HDC_TIME);
|
xta_set_callback(dev, HDC_TIME);
|
||||||
}
|
}
|
||||||
} else if (dev->state == STATE_COMPL) {
|
} else if (dev->state == STATE_COMPL) {
|
||||||
xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp);
|
xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp);
|
||||||
ret = dev->comp;
|
ret = dev->comp;
|
||||||
dev->status = 0x00;
|
dev->status = 0x00;
|
||||||
dev->state = STATE_IDLE;
|
dev->state = STATE_IDLE;
|
||||||
@@ -917,20 +902,19 @@ xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->com
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write to one of the controller registers. */
|
/* Write to one of the controller registers. */
|
||||||
static void
|
static void
|
||||||
hdc_write(uint16_t port, uint8_t val, void *priv)
|
hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
|
|
||||||
switch (port & 7) {
|
switch (port & 7) {
|
||||||
case 0: /* DATA register */
|
case 0: /* DATA register */
|
||||||
if (dev->state == STATE_RDATA) {
|
if (dev->state == STATE_RDATA) {
|
||||||
if (! (dev->status & STAT_REQ)) {
|
if (!(dev->status & STAT_REQ)) {
|
||||||
xta_log("%s: not ready for command/data!\n", dev->name);
|
xta_log("%s: not ready for command/data!\n", dev->name);
|
||||||
dev->comp |= COMP_ERR;
|
dev->comp |= COMP_ERR;
|
||||||
dev->sense = ERR_ILLCMD;
|
dev->sense = ERR_ILLCMD;
|
||||||
@@ -968,26 +952,24 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
/* Reset the DCB buffer. */
|
/* Reset the DCB buffer. */
|
||||||
dev->buf_idx = 0;
|
dev->buf_idx = 0;
|
||||||
dev->buf_len = sizeof(dcb_t);
|
dev->buf_len = sizeof(dcb_t);
|
||||||
dev->buf_ptr = (uint8_t *)&dev->dcb;
|
dev->buf_ptr = (uint8_t *) &dev->dcb;
|
||||||
dev->state = STATE_RDATA;
|
dev->state = STATE_RDATA;
|
||||||
dev->status = (STAT_BSY | STAT_CD | STAT_REQ);
|
dev->status = (STAT_BSY | STAT_CD | STAT_REQ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* DMA/IRQ intr register */
|
case 3: /* DMA/IRQ intr register */
|
||||||
//xta_log("%s: WriteMASK(%02X)\n", dev->name, val);
|
// xta_log("%s: WriteMASK(%02X)\n", dev->name, val);
|
||||||
dev->intr = val;
|
dev->intr = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xta_available(void)
|
xta_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(WD_BIOS_FILE));
|
return (rom_present(WD_BIOS_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xta_init(const device_t *info)
|
xta_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -1003,7 +985,7 @@ xta_init(const device_t *info)
|
|||||||
dev->type = info->local;
|
dev->type = info->local;
|
||||||
|
|
||||||
/* Do per-controller-type setup. */
|
/* Do per-controller-type setup. */
|
||||||
switch(dev->type) {
|
switch (dev->type) {
|
||||||
case 0: /* WDXT-150, with BIOS */
|
case 0: /* WDXT-150, with BIOS */
|
||||||
dev->name = "WDXT-150";
|
dev->name = "WDXT-150";
|
||||||
dev->base = device_get_config_hex16("base");
|
dev->base = device_get_config_hex16("base");
|
||||||
@@ -1034,7 +1016,7 @@ xta_init(const device_t *info)
|
|||||||
if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) {
|
if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) {
|
||||||
drive = &dev->drives[hdd[i].xta_channel];
|
drive = &dev->drives[hdd[i].xta_channel];
|
||||||
|
|
||||||
if (! hdd_image_load(i)) {
|
if (!hdd_image_load(i)) {
|
||||||
drive->present = 0;
|
drive->present = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1043,9 +1025,9 @@ xta_init(const device_t *info)
|
|||||||
drive->present = 1;
|
drive->present = 1;
|
||||||
|
|
||||||
/* These are the "hardware" parameters (from the image.) */
|
/* These are the "hardware" parameters (from the image.) */
|
||||||
drive->cfg_spt = (uint8_t)(hdd[i].spt & 0xff);
|
drive->cfg_spt = (uint8_t) (hdd[i].spt & 0xff);
|
||||||
drive->cfg_hpc = (uint8_t)(hdd[i].hpc & 0xff);
|
drive->cfg_hpc = (uint8_t) (hdd[i].hpc & 0xff);
|
||||||
drive->cfg_tracks = (uint16_t)hdd[i].tracks;
|
drive->cfg_tracks = (uint16_t) hdd[i].tracks;
|
||||||
|
|
||||||
/* Use them as "configured" parameters until overwritten. */
|
/* Use them as "configured" parameters until overwritten. */
|
||||||
drive->spt = drive->cfg_spt;
|
drive->spt = drive->cfg_spt;
|
||||||
@@ -1056,13 +1038,14 @@ xta_init(const device_t *info)
|
|||||||
dev->name, hdd[i].xta_channel, drive->tracks,
|
dev->name, hdd[i].xta_channel, drive->tracks,
|
||||||
drive->hpc, drive->spt, i);
|
drive->hpc, drive->spt, i);
|
||||||
|
|
||||||
if (++c > max) break;
|
if (++c > max)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable the I/O block. */
|
/* Enable the I/O block. */
|
||||||
io_sethandler(dev->base, 4,
|
io_sethandler(dev->base, 4,
|
||||||
hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev);
|
hdc_read, NULL, NULL, hdc_write, NULL, NULL, dev);
|
||||||
|
|
||||||
/* Load BIOS if it has one. */
|
/* Load BIOS if it has one. */
|
||||||
if (dev->rom_addr != 0x000000) {
|
if (dev->rom_addr != 0x000000) {
|
||||||
@@ -1073,20 +1056,19 @@ xta_init(const device_t *info)
|
|||||||
/* Create a timer for command delays. */
|
/* Create a timer for command delays. */
|
||||||
timer_add(&dev->timer, hdc_callback, dev, 0);
|
timer_add(&dev->timer, hdc_callback, dev, 0);
|
||||||
|
|
||||||
return(dev);
|
return (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xta_close(void *priv)
|
xta_close(void *priv)
|
||||||
{
|
{
|
||||||
hdc_t *dev = (hdc_t *)priv;
|
hdc_t *dev = (hdc_t *) priv;
|
||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
/* Remove the I/O handler. */
|
/* Remove the I/O handler. */
|
||||||
io_removehandler(dev->base, 4,
|
io_removehandler(dev->base, 4,
|
||||||
hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev);
|
hdc_read, NULL, NULL, hdc_write, NULL, NULL, dev);
|
||||||
|
|
||||||
/* Close all disks and their images. */
|
/* Close all disks and their images. */
|
||||||
for (d = 0; d < XTA_NUM; d++) {
|
for (d = 0; d < XTA_NUM; d++) {
|
||||||
@@ -1100,7 +1082,7 @@ xta_close(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const device_config_t wdxt150_config[] = {
|
static const device_config_t wdxt150_config[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{
|
{
|
||||||
.name = "base",
|
.name = "base",
|
||||||
.description = "Address",
|
.description = "Address",
|
||||||
|
|||||||
@@ -44,25 +44,22 @@
|
|||||||
#include <86box/hdc.h>
|
#include <86box/hdc.h>
|
||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
|
|
||||||
|
|
||||||
#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin"
|
#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin"
|
||||||
#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin"
|
#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin"
|
||||||
#define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.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_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin"
|
||||||
#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin"
|
#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *ide_board;
|
void *ide_board;
|
||||||
uint8_t data_high;
|
uint8_t data_high;
|
||||||
rom_t bios_rom;
|
rom_t bios_rom;
|
||||||
} xtide_t;
|
} xtide_t;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xtide_write(uint16_t port, uint8_t val, void *priv)
|
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) {
|
switch (port & 0xf) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
@@ -89,11 +86,10 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
xtide_read(uint16_t port, void *priv)
|
xtide_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
xtide_t *xtide = (xtide_t *)priv;
|
xtide_t *xtide = (xtide_t *) priv;
|
||||||
uint16_t tempw = 0xffff;
|
uint16_t tempw = 0xffff;
|
||||||
|
|
||||||
switch (port & 0xf) {
|
switch (port & 0xf) {
|
||||||
@@ -124,10 +120,9 @@ xtide_read(uint16_t port, void *priv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(tempw & 0xff);
|
return (tempw & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xtide_init(const device_t *info)
|
xtide_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -144,17 +139,15 @@ xtide_init(const device_t *info)
|
|||||||
xtide_read, NULL, NULL,
|
xtide_read, NULL, NULL,
|
||||||
xtide_write, NULL, NULL, xtide);
|
xtide_write, NULL, NULL, xtide);
|
||||||
|
|
||||||
return(xtide);
|
return (xtide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtide_available(void)
|
xtide_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ROM_PATH_XT));
|
return (rom_present(ROM_PATH_XT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xtide_at_init(const device_t *info)
|
xtide_at_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -172,24 +165,21 @@ xtide_at_init(const device_t *info)
|
|||||||
|
|
||||||
device_add(&ide_isa_2ch_device);
|
device_add(&ide_isa_2ch_device);
|
||||||
|
|
||||||
return(xtide);
|
return (xtide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtide_at_available(void)
|
xtide_at_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ROM_PATH_AT));
|
return (rom_present(ROM_PATH_AT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtide_at_386_available(void)
|
xtide_at_386_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ROM_PATH_AT_386));
|
return (rom_present(ROM_PATH_AT_386));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xtide_acculogic_init(const device_t *info)
|
xtide_acculogic_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -206,28 +196,25 @@ xtide_acculogic_init(const device_t *info)
|
|||||||
xtide_read, NULL, NULL,
|
xtide_read, NULL, NULL,
|
||||||
xtide_write, NULL, NULL, xtide);
|
xtide_write, NULL, NULL, xtide);
|
||||||
|
|
||||||
return(xtide);
|
return (xtide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtide_acculogic_available(void)
|
xtide_acculogic_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ROM_PATH_PS2));
|
return (rom_present(ROM_PATH_PS2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xtide_close(void *priv)
|
xtide_close(void *priv)
|
||||||
{
|
{
|
||||||
xtide_t *xtide = (xtide_t *)priv;
|
xtide_t *xtide = (xtide_t *) priv;
|
||||||
|
|
||||||
free(xtide);
|
free(xtide);
|
||||||
|
|
||||||
ide_xtide_close();
|
ide_xtide_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
xtide_at_ps2_init(const device_t *info)
|
xtide_at_ps2_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -240,21 +227,19 @@ xtide_at_ps2_init(const device_t *info)
|
|||||||
|
|
||||||
device_add(&ide_isa_2ch_device);
|
device_add(&ide_isa_2ch_device);
|
||||||
|
|
||||||
return(xtide);
|
return (xtide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtide_at_ps2_available(void)
|
xtide_at_ps2_available(void)
|
||||||
{
|
{
|
||||||
return(rom_present(ROM_PATH_PS2AT));
|
return (rom_present(ROM_PATH_PS2AT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xtide_at_close(void *priv)
|
xtide_at_close(void *priv)
|
||||||
{
|
{
|
||||||
xtide_t *xtide = (xtide_t *)priv;
|
xtide_t *xtide = (xtide_t *) priv;
|
||||||
|
|
||||||
free(xtide);
|
free(xtide);
|
||||||
}
|
}
|
||||||
|
|||||||
155
src/disk/hdd.c
155
src/disk/hdd.c
@@ -31,80 +31,76 @@
|
|||||||
#include <86box/video.h>
|
#include <86box/video.h>
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
|
||||||
#define HDD_OVERHEAD_TIME 50.0
|
#define HDD_OVERHEAD_TIME 50.0
|
||||||
|
|
||||||
|
|
||||||
hard_disk_t hdd[HDD_NUM];
|
hard_disk_t hdd[HDD_NUM];
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_init(void)
|
hdd_init(void)
|
||||||
{
|
{
|
||||||
/* Clear all global data. */
|
/* Clear all global data. */
|
||||||
memset(hdd, 0x00, sizeof(hdd));
|
memset(hdd, 0x00, sizeof(hdd));
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_string_to_bus(char *str, int cdrom)
|
hdd_string_to_bus(char *str, int cdrom)
|
||||||
{
|
{
|
||||||
if (! strcmp(str, "none"))
|
if (!strcmp(str, "none"))
|
||||||
return(HDD_BUS_DISABLED);
|
return (HDD_BUS_DISABLED);
|
||||||
|
|
||||||
if (! strcmp(str, "mfm") || ! strcmp(str, "rll")) {
|
if (!strcmp(str, "mfm") || !strcmp(str, "rll")) {
|
||||||
if (cdrom) {
|
if (cdrom) {
|
||||||
no_cdrom:
|
no_cdrom:
|
||||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099);
|
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(HDD_BUS_MFM);
|
return (HDD_BUS_MFM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: delete 'rll' in a year or so.. --FvK */
|
/* FIXME: delete 'rll' in a year or so.. --FvK */
|
||||||
if (!strcmp(str, "esdi") || !strcmp(str, "rll")) {
|
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"))
|
if (!strcmp(str, "ide_pio_only"))
|
||||||
return(HDD_BUS_IDE);
|
return (HDD_BUS_IDE);
|
||||||
|
|
||||||
if (! strcmp(str, "ide"))
|
if (!strcmp(str, "ide"))
|
||||||
return(HDD_BUS_IDE);
|
return (HDD_BUS_IDE);
|
||||||
|
|
||||||
if (! strcmp(str, "atapi_pio_only"))
|
if (!strcmp(str, "atapi_pio_only"))
|
||||||
return(HDD_BUS_ATAPI);
|
return (HDD_BUS_ATAPI);
|
||||||
|
|
||||||
if (! strcmp(str, "atapi"))
|
if (!strcmp(str, "atapi"))
|
||||||
return(HDD_BUS_ATAPI);
|
return (HDD_BUS_ATAPI);
|
||||||
|
|
||||||
if (! strcmp(str, "eide"))
|
if (!strcmp(str, "eide"))
|
||||||
return(HDD_BUS_IDE);
|
return (HDD_BUS_IDE);
|
||||||
|
|
||||||
if (! strcmp(str, "xta"))
|
if (!strcmp(str, "xta"))
|
||||||
return(HDD_BUS_XTA);
|
return (HDD_BUS_XTA);
|
||||||
|
|
||||||
if (! strcmp(str, "atide"))
|
if (!strcmp(str, "atide"))
|
||||||
return(HDD_BUS_IDE);
|
return (HDD_BUS_IDE);
|
||||||
|
|
||||||
if (! strcmp(str, "ide_pio_and_dma"))
|
if (!strcmp(str, "ide_pio_and_dma"))
|
||||||
return(HDD_BUS_IDE);
|
return (HDD_BUS_IDE);
|
||||||
|
|
||||||
if (! strcmp(str, "atapi_pio_and_dma"))
|
if (!strcmp(str, "atapi_pio_and_dma"))
|
||||||
return(HDD_BUS_ATAPI);
|
return (HDD_BUS_ATAPI);
|
||||||
|
|
||||||
if (! strcmp(str, "scsi"))
|
if (!strcmp(str, "scsi"))
|
||||||
return(HDD_BUS_SCSI);
|
return (HDD_BUS_SCSI);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
hdd_bus_to_string(int bus, int cdrom)
|
hdd_bus_to_string(int bus, int cdrom)
|
||||||
{
|
{
|
||||||
@@ -140,26 +136,24 @@ hdd_bus_to_string(int bus, int cdrom)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(s);
|
return (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_is_valid(int c)
|
hdd_is_valid(int c)
|
||||||
{
|
{
|
||||||
if (hdd[c].bus == HDD_BUS_DISABLED)
|
if (hdd[c].bus == HDD_BUS_DISABLED)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
if (strlen(hdd[c].fn) == 0)
|
if (strlen(hdd[c].fn) == 0)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0))
|
if ((hdd[c].tracks == 0) || (hdd[c].hpc == 0) || (hdd[c].spt == 0))
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
return(1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time)
|
hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time)
|
||||||
{
|
{
|
||||||
@@ -173,13 +167,15 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double continuous_times[2][2] = { { hdd->head_switch_usec, hdd->cyl_switch_usec },
|
double continuous_times[2][2] = {
|
||||||
{ zone->sector_time_usec, zone->sector_time_usec } };
|
{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 };
|
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_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track);
|
||||||
uint32_t new_cylinder = new_track / hdd->phy_heads;
|
uint32_t new_cylinder = new_track / hdd->phy_heads;
|
||||||
uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder);
|
uint32_t cylinder_diff = abs((int) hdd->cur_cylinder - (int) new_cylinder);
|
||||||
|
|
||||||
bool sequential = dst_addr == hdd->cur_addr + 1;
|
bool sequential = dst_addr == hdd->cur_addr + 1;
|
||||||
continuous = continuous && sequential;
|
continuous = continuous && sequential;
|
||||||
@@ -191,8 +187,7 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_
|
|||||||
if (!cylinder_diff)
|
if (!cylinder_diff)
|
||||||
seek_time = times[operation != HDD_OP_SEEK];
|
seek_time = times[operation != HDD_OP_SEEK];
|
||||||
else {
|
else {
|
||||||
seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl) +
|
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);
|
||||||
((operation != HDD_OP_SEEK) * hdd->avg_rotation_lat_usec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +200,6 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_
|
|||||||
return seek_time;
|
return seek_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdd_readahead_update(hard_disk_t *hdd)
|
hdd_readahead_update(hard_disk_t *hdd)
|
||||||
{
|
{
|
||||||
@@ -219,7 +213,7 @@ hdd_readahead_update(hard_disk_t *hdd)
|
|||||||
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_cycles = tsc - cache->ra_start_time;
|
||||||
elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
|
elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0;
|
||||||
/* Do not overwrite data not yet read by host */
|
/* Do not overwrite data not yet read by host */
|
||||||
max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
|
max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
|
||||||
|
|
||||||
@@ -240,7 +234,6 @@ hdd_readahead_update(hard_disk_t *hdd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
hdd_writecache_flush(hard_disk_t *hdd)
|
hdd_writecache_flush(hard_disk_t *hdd)
|
||||||
{
|
{
|
||||||
@@ -255,7 +248,6 @@ hdd_writecache_flush(hard_disk_t *hdd)
|
|||||||
return seek_time;
|
return seek_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdd_writecache_update(hard_disk_t *hdd)
|
hdd_writecache_update(hard_disk_t *hdd)
|
||||||
{
|
{
|
||||||
@@ -264,7 +256,7 @@ hdd_writecache_update(hard_disk_t *hdd)
|
|||||||
|
|
||||||
if (hdd->cache.write_pending) {
|
if (hdd->cache.write_pending) {
|
||||||
elapsed_cycles = tsc - hdd->cache.write_start_time;
|
elapsed_cycles = tsc - hdd->cache.write_start_time;
|
||||||
elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
|
elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0;
|
||||||
seek_time = 0.0;
|
seek_time = 0.0;
|
||||||
|
|
||||||
while (hdd->cache.write_pending) {
|
while (hdd->cache.write_pending) {
|
||||||
@@ -278,7 +270,6 @@ hdd_writecache_update(hard_disk_t *hdd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
||||||
{
|
{
|
||||||
@@ -313,12 +304,11 @@ hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return seek_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double
|
double
|
||||||
hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
||||||
{
|
{
|
||||||
@@ -384,12 +374,11 @@ update_lru:
|
|||||||
|
|
||||||
cache->ra_ongoing = 1;
|
cache->ra_ongoing = 1;
|
||||||
cache->ra_segment = active_seg->id;
|
cache->ra_segment = active_seg->id;
|
||||||
cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
|
cache->ra_start_time = tsc + (uint32_t) (seek_time * cpuclock / 1000000.0);
|
||||||
|
|
||||||
return seek_time;
|
return seek_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdd_cache_init(hard_disk_t *hdd)
|
hdd_cache_init(hard_disk_t *hdd)
|
||||||
{
|
{
|
||||||
@@ -409,20 +398,19 @@ hdd_cache_init(hard_disk_t *hdd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdd_zones_init(hard_disk_t *hdd)
|
hdd_zones_init(hard_disk_t *hdd)
|
||||||
{
|
{
|
||||||
uint32_t lba = 0, track = 0;
|
uint32_t lba = 0, track = 0;
|
||||||
uint32_t i, tracks;
|
uint32_t i, tracks;
|
||||||
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
|
double revolution_usec = 60.0 / (double) hdd->rpm * 1000000.0;
|
||||||
hdd_zone_t *zone;
|
hdd_zone_t *zone;
|
||||||
|
|
||||||
for (i = 0; i < hdd->num_zones; i++) {
|
for (i = 0; i < hdd->num_zones; i++) {
|
||||||
zone = &hdd->zones[i];
|
zone = &hdd->zones[i];
|
||||||
zone->start_sector = lba;
|
zone->start_sector = lba;
|
||||||
zone->start_track = track;
|
zone->start_track = track;
|
||||||
zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track;
|
zone->sector_time_usec = revolution_usec / (double) zone->sectors_per_track;
|
||||||
tracks = zone->cylinders * hdd->phy_heads;
|
tracks = zone->cylinders * hdd->phy_heads;
|
||||||
lba += tracks * zone->sectors_per_track;
|
lba += tracks * zone->sectors_per_track;
|
||||||
zone->end_sector = lba - 1;
|
zone->end_sector = lba - 1;
|
||||||
@@ -430,61 +418,49 @@ hdd_zones_init(hard_disk_t *hdd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static hdd_preset_t hdd_speed_presets[] = {
|
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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.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,
|
{ .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 },
|
||||||
.full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_preset_get_num()
|
hdd_preset_get_num()
|
||||||
{
|
{
|
||||||
return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t);
|
return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
hdd_preset_getname(int preset)
|
hdd_preset_getname(int preset)
|
||||||
{
|
{
|
||||||
return (char *)hdd_speed_presets[preset].name;
|
return (char *) hdd_speed_presets[preset].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
hdd_preset_get_internal_name(int preset)
|
hdd_preset_get_internal_name(int preset)
|
||||||
{
|
{
|
||||||
return (char *)hdd_speed_presets[preset].internal_name;
|
return (char *) hdd_speed_presets[preset].internal_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_preset_get_from_internal_name(char *s)
|
hdd_preset_get_from_internal_name(char *s)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
for (int i = 0; i < (sizeof(hdd_speed_presets) / sizeof(hdd_preset_t)); i++) {
|
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;
|
return c;
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
@@ -492,7 +468,6 @@ hdd_preset_get_from_internal_name(char *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_preset_apply(int hdd_id)
|
hdd_preset_apply(int hdd_id)
|
||||||
{
|
{
|
||||||
@@ -517,7 +492,7 @@ hdd_preset_apply(int hdd_id)
|
|||||||
hd->phy_heads = preset->heads;
|
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->avg_rotation_lat_usec = revolution_usec / 2;
|
||||||
hd->full_stroke_usec = preset->full_stroke_ms * 1000;
|
hd->full_stroke_usec = preset->full_stroke_ms * 1000;
|
||||||
hd->head_switch_usec = preset->track_seek_ms * 1000;
|
hd->head_switch_usec = preset->track_seek_ms * 1000;
|
||||||
@@ -528,20 +503,20 @@ hdd_preset_apply(int hdd_id)
|
|||||||
hd->num_zones = preset->zones;
|
hd->num_zones = preset->zones;
|
||||||
|
|
||||||
disk_sectors = hd->tracks * hd->hpc * hd->spt;
|
disk_sectors = hd->tracks * hd->hpc * hd->spt;
|
||||||
sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hd->phy_heads);
|
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);
|
cylinders = (uint32_t) ceil((double) sectors_per_surface / (double) preset->avg_spt);
|
||||||
hd->phy_cyl = cylinders;
|
hd->phy_cyl = cylinders;
|
||||||
cylinders_per_zone = cylinders / preset->zones;
|
cylinders_per_zone = cylinders / preset->zones;
|
||||||
|
|
||||||
for (i = 0; i < preset->zones; i++) {
|
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) {
|
if (i < preset->zones - 1) {
|
||||||
/* Function for realistic zone sector density */
|
/* Function for realistic zone sector density */
|
||||||
double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48;
|
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);
|
spt = (uint32_t) ceil((double) preset->avg_spt * spt_percent / 100);
|
||||||
} else
|
} else
|
||||||
spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads));
|
spt = (uint32_t) ceil((double) (disk_sectors - total_sectors) / (double) (cylinders_per_zone * preset->heads));
|
||||||
|
|
||||||
zone_sectors = spt * cylinders_per_zone * preset->heads;
|
zone_sectors = spt * cylinders_per_zone * preset->heads;
|
||||||
total_sectors += zone_sectors;
|
total_sectors += zone_sectors;
|
||||||
|
|||||||
@@ -42,14 +42,13 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */
|
FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */
|
||||||
MVHDMeta* vhd; /* Used for HDD_IMAGE_VHD. */
|
MVHDMeta *vhd; /* Used for HDD_IMAGE_VHD. */
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
uint32_t pos, last_sector;
|
uint32_t pos, last_sector;
|
||||||
uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */
|
uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */
|
||||||
uint8_t loaded;
|
uint8_t loaded;
|
||||||
} hdd_image_t;
|
} hdd_image_t;
|
||||||
|
|
||||||
|
|
||||||
hdd_image_t hdd_images[HDD_NUM];
|
hdd_image_t hdd_images[HDD_NUM];
|
||||||
|
|
||||||
static char empty_sector[512];
|
static char empty_sector[512];
|
||||||
@@ -58,7 +57,6 @@ static char *empty_sector_1mb;
|
|||||||
#ifdef ENABLE_HDD_IMAGE_LOG
|
#ifdef ENABLE_HDD_IMAGE_LOG
|
||||||
int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG;
|
int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hdd_image_log(const char *fmt, ...)
|
hdd_image_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -71,19 +69,18 @@ hdd_image_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define hdd_image_log(fmt, ...)
|
# define hdd_image_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
image_is_hdi(const char *s)
|
image_is_hdi(const char *s)
|
||||||
{
|
{
|
||||||
if (! strcasecmp(path_get_extension((char *) s), "HDI"))
|
if (!strcasecmp(path_get_extension((char *) s), "HDI"))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
image_is_hdx(const char *s, int check_signature)
|
image_is_hdx(const char *s, int check_signature)
|
||||||
{
|
{
|
||||||
@@ -91,7 +88,7 @@ image_is_hdx(const char *s, int check_signature)
|
|||||||
uint64_t filelen;
|
uint64_t filelen;
|
||||||
uint64_t signature;
|
uint64_t signature;
|
||||||
|
|
||||||
if (! strcasecmp(path_get_extension((char *) s), "HDX")) {
|
if (!strcasecmp(path_get_extension((char *) s), "HDX")) {
|
||||||
if (check_signature) {
|
if (check_signature) {
|
||||||
f = plat_fopen(s, "rb");
|
f = plat_fopen(s, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
@@ -119,13 +116,12 @@ image_is_hdx(const char *s, int check_signature)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
image_is_vhd(const char *s, int check_signature)
|
image_is_vhd(const char *s, int check_signature)
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE *f;
|
||||||
|
|
||||||
if (! strcasecmp(path_get_extension((char *) s), "VHD")) {
|
if (!strcasecmp(path_get_extension((char *) s), "VHD")) {
|
||||||
if (check_signature) {
|
if (check_signature) {
|
||||||
f = plat_fopen(s, "rb");
|
f = plat_fopen(s, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
@@ -157,7 +153,7 @@ hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size)
|
|||||||
} else {
|
} else {
|
||||||
spt = 17;
|
spt = 17;
|
||||||
cth = (uint32_t) (ts / spt);
|
cth = (uint32_t) (ts / spt);
|
||||||
heads = (cth +1023) / 1024;
|
heads = (cth + 1023) / 1024;
|
||||||
if (heads < 4)
|
if (heads < 4)
|
||||||
heads = 4;
|
heads = 4;
|
||||||
if ((cth >= (heads * 1024)) || (heads > 16)) {
|
if ((cth >= (heads * 1024)) || (heads > 16)) {
|
||||||
@@ -177,7 +173,6 @@ hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size)
|
|||||||
*s = spt;
|
*s = spt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
||||||
{
|
{
|
||||||
@@ -225,7 +220,6 @@ prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_init(void)
|
hdd_image_init(void)
|
||||||
{
|
{
|
||||||
@@ -255,15 +249,13 @@ hdd_image_load(int id)
|
|||||||
path_normalize(fn);
|
path_normalize(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hdd_images[id].base = 0;
|
hdd_images[id].base = 0;
|
||||||
|
|
||||||
if (hdd_images[id].loaded) {
|
if (hdd_images[id].loaded) {
|
||||||
if (hdd_images[id].file) {
|
if (hdd_images[id].file) {
|
||||||
fclose(hdd_images[id].file);
|
fclose(hdd_images[id].file);
|
||||||
hdd_images[id].file = NULL;
|
hdd_images[id].file = NULL;
|
||||||
}
|
} else if (hdd_images[id].vhd) {
|
||||||
else if (hdd_images[id].vhd) {
|
|
||||||
mvhd_close(hdd_images[id].vhd);
|
mvhd_close(hdd_images[id].vhd);
|
||||||
hdd_images[id].vhd = NULL;
|
hdd_images[id].vhd = NULL;
|
||||||
}
|
}
|
||||||
@@ -303,9 +295,7 @@ hdd_image_load(int id)
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (image_is_hdi(fn)) {
|
if (image_is_hdi(fn)) {
|
||||||
full_size = ((uint64_t) hdd[id].spt) *
|
full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
hdd_images[id].base = 0x1000;
|
hdd_images[id].base = 0x1000;
|
||||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||||
@@ -319,9 +309,7 @@ hdd_image_load(int id)
|
|||||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||||
hdd_images[id].type = HDD_IMAGE_HDI;
|
hdd_images[id].type = HDD_IMAGE_HDI;
|
||||||
} else if (is_hdx[0]) {
|
} else if (is_hdx[0]) {
|
||||||
full_size = ((uint64_t) hdd[id].spt) *
|
full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
hdd_images[id].base = 0x28;
|
hdd_images[id].base = 0x28;
|
||||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||||
@@ -338,9 +326,7 @@ hdd_image_load(int id)
|
|||||||
geometry.cyl = hdd[id].tracks;
|
geometry.cyl = hdd[id].tracks;
|
||||||
geometry.heads = hdd[id].hpc;
|
geometry.heads = hdd[id].hpc;
|
||||||
geometry.spt = hdd[id].spt;
|
geometry.spt = hdd[id].spt;
|
||||||
full_size = ((uint64_t) hdd[id].spt) *
|
full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
hdd_images[id].last_sector = (full_size >> 9LL) - 1;
|
hdd_images[id].last_sector = (full_size >> 9LL) - 1;
|
||||||
|
|
||||||
hdd_images[id].vhd = mvhd_create_fixed(fn, geometry, &vhd_error, NULL);
|
hdd_images[id].vhd = mvhd_create_fixed(fn, geometry, &vhd_error, NULL);
|
||||||
@@ -355,9 +341,7 @@ hdd_image_load(int id)
|
|||||||
hdd_images[id].last_sector = 0;
|
hdd_images[id].last_sector = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = full_size = ((uint64_t) hdd[id].spt) *
|
s = full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
|
|
||||||
ret = prepare_new_hard_disk(id, full_size);
|
ret = prepare_new_hard_disk(id, full_size);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -431,23 +415,20 @@ hdd_image_load(int id)
|
|||||||
} else if (is_vhd[1]) {
|
} else if (is_vhd[1]) {
|
||||||
fclose(hdd_images[id].file);
|
fclose(hdd_images[id].file);
|
||||||
hdd_images[id].file = NULL;
|
hdd_images[id].file = NULL;
|
||||||
hdd_images[id].vhd = mvhd_open(fn, (bool)0, &vhd_error);
|
hdd_images[id].vhd = mvhd_open(fn, (bool) 0, &vhd_error);
|
||||||
if (hdd_images[id].vhd == NULL) {
|
if (hdd_images[id].vhd == NULL) {
|
||||||
if (vhd_error == MVHD_ERR_FILE)
|
if (vhd_error == MVHD_ERR_FILE)
|
||||||
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, strerror(mvhd_errno));
|
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, strerror(mvhd_errno));
|
||||||
else
|
else
|
||||||
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, mvhd_strerr(vhd_error));
|
fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, mvhd_strerr(vhd_error));
|
||||||
}
|
} else if (vhd_error == MVHD_ERR_TIMESTAMP) {
|
||||||
else if (vhd_error == MVHD_ERR_TIMESTAMP) {
|
|
||||||
fatal("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn);
|
fatal("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdd[id].tracks = hdd_images[id].vhd->footer.geom.cyl;
|
hdd[id].tracks = hdd_images[id].vhd->footer.geom.cyl;
|
||||||
hdd[id].hpc = hdd_images[id].vhd->footer.geom.heads;
|
hdd[id].hpc = hdd_images[id].vhd->footer.geom.heads;
|
||||||
hdd[id].spt = hdd_images[id].vhd->footer.geom.spt;
|
hdd[id].spt = hdd_images[id].vhd->footer.geom.spt;
|
||||||
full_size = ((uint64_t) hdd[id].spt) *
|
full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
hdd_images[id].type = HDD_IMAGE_VHD;
|
hdd_images[id].type = HDD_IMAGE_VHD;
|
||||||
/* If we're here, this means there is a valid VHD footer in the
|
/* If we're here, this means there is a valid VHD footer in the
|
||||||
image, which means that by definition, all valid sectors
|
image, which means that by definition, all valid sectors
|
||||||
@@ -456,9 +437,7 @@ hdd_image_load(int id)
|
|||||||
hdd_images[id].loaded = 1;
|
hdd_images[id].loaded = 1;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
full_size = ((uint64_t) hdd[id].spt) *
|
full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL;
|
||||||
((uint64_t) hdd[id].hpc) *
|
|
||||||
((uint64_t) hdd[id].tracks) << 9LL;
|
|
||||||
hdd_images[id].type = HDD_IMAGE_RAW;
|
hdd_images[id].type = HDD_IMAGE_RAW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,12 +456,11 @@ hdd_image_load(int id)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_seek(uint8_t id, uint32_t sector)
|
hdd_image_seek(uint8_t id, uint32_t sector)
|
||||||
{
|
{
|
||||||
off64_t addr = sector;
|
off64_t addr = sector;
|
||||||
addr = (uint64_t)sector << 9LL;
|
addr = (uint64_t) sector << 9LL;
|
||||||
|
|
||||||
hdd_images[id].pos = sector;
|
hdd_images[id].pos = sector;
|
||||||
if (hdd_images[id].type != HDD_IMAGE_VHD) {
|
if (hdd_images[id].type != HDD_IMAGE_VHD) {
|
||||||
@@ -491,7 +469,6 @@ hdd_image_seek(uint8_t id, uint32_t sector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
@@ -502,7 +479,7 @@ hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
|
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||||
} else {
|
} else {
|
||||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||||
fatal("Hard disk image %i: Read error during seek\n", id);
|
fatal("Hard disk image %i: Read error during seek\n", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -512,21 +489,18 @@ hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
hdd_image_get_last_sector(uint8_t id)
|
hdd_image_get_last_sector(uint8_t id)
|
||||||
{
|
{
|
||||||
return hdd_images[id].last_sector;
|
return hdd_images[id].last_sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
hdd_sectors(uint8_t id)
|
hdd_sectors(uint8_t id)
|
||||||
{
|
{
|
||||||
return hdd_image_get_last_sector(id) - 1;
|
return hdd_image_get_last_sector(id) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
@@ -543,7 +517,6 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
@@ -554,7 +527,7 @@ hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
|
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||||
} else {
|
} else {
|
||||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||||
fatal("Hard disk image %i: Write error during seek\n", id);
|
fatal("Hard disk image %i: Write error during seek\n", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -564,7 +537,6 @@ hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
@@ -581,7 +553,6 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||||
{
|
{
|
||||||
@@ -593,7 +564,7 @@ hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
|||||||
|
|
||||||
memset(empty_sector, 0, 512);
|
memset(empty_sector, 0, 512);
|
||||||
|
|
||||||
if (fseeko64(hdd_images[id].file, ((uint64_t)(sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||||
fatal("Hard disk image %i: Zero error during seek\n", id);
|
fatal("Hard disk image %i: Zero error during seek\n", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -608,7 +579,6 @@ hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||||
{
|
{
|
||||||
@@ -625,21 +595,18 @@ hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
hdd_image_get_pos(uint8_t id)
|
hdd_image_get_pos(uint8_t id)
|
||||||
{
|
{
|
||||||
return hdd_images[id].pos;
|
return hdd_images[id].pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
hdd_image_get_type(uint8_t id)
|
hdd_image_get_type(uint8_t id)
|
||||||
{
|
{
|
||||||
return hdd_images[id].type;
|
return hdd_images[id].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_unload(uint8_t id, int fn_preserve)
|
hdd_image_unload(uint8_t id, int fn_preserve)
|
||||||
{
|
{
|
||||||
@@ -665,7 +632,6 @@ hdd_image_unload(uint8_t id, int fn_preserve)
|
|||||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hdd_image_close(uint8_t id)
|
hdd_image_close(uint8_t id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
#include <86box/hdd.h>
|
#include <86box/hdd.h>
|
||||||
|
|
||||||
|
|
||||||
unsigned int hdd_table[128][3] = {
|
unsigned int hdd_table[128][3] = {
|
||||||
|
// clang-format off
|
||||||
{ 306, 4, 17 }, /* 0 - 7 */
|
{ 306, 4, 17 }, /* 0 - 7 */
|
||||||
{ 615, 2, 17 },
|
{ 615, 2, 17 },
|
||||||
{ 306, 4, 26 },
|
{ 306, 4, 26 },
|
||||||
@@ -170,4 +170,5 @@ unsigned int hdd_table[128][3] = {
|
|||||||
{ 1120, 16, 59 },
|
{ 1120, 16, 59 },
|
||||||
{ 1054, 16, 63 },
|
{ 1054, 16, 63 },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|||||||
139
src/disk/mo.c
139
src/disk/mo.c
@@ -43,18 +43,16 @@
|
|||||||
#include <86box/version.h>
|
#include <86box/version.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <io.h>
|
# include <io.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mo_drive_t mo_drives[MO_NUM];
|
mo_drive_t mo_drives[MO_NUM];
|
||||||
|
|
||||||
|
|
||||||
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
||||||
const uint8_t mo_command_flags[0x100] =
|
const uint8_t mo_command_flags[0x100] = {
|
||||||
{
|
|
||||||
IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */
|
IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */
|
||||||
IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */
|
IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */
|
||||||
0,
|
0,
|
||||||
@@ -122,8 +120,8 @@ const uint8_t mo_command_flags[0x100] =
|
|||||||
|
|
||||||
static uint64_t mo_mode_sense_page_flags = (GPMODEP_ALL_PAGES);
|
static uint64_t mo_mode_sense_page_flags = (GPMODEP_ALL_PAGES);
|
||||||
|
|
||||||
|
|
||||||
static const mode_sense_pages_t mo_mode_sense_pages_default =
|
static const mode_sense_pages_t mo_mode_sense_pages_default =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@@ -174,8 +172,10 @@ static const mode_sense_pages_t mo_mode_sense_pages_default =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t mo_mode_sense_pages_default_scsi =
|
static const mode_sense_pages_t mo_mode_sense_pages_default_scsi =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@@ -226,9 +226,10 @@ static const mode_sense_pages_t mo_mode_sense_pages_default_scsi =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t mo_mode_sense_pages_changeable =
|
static const mode_sense_pages_t mo_mode_sense_pages_changeable =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@@ -279,16 +280,14 @@ static const mode_sense_pages_t mo_mode_sense_pages_changeable =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static void mo_command_complete(mo_t *dev);
|
static void mo_command_complete(mo_t *dev);
|
||||||
static void mo_init(mo_t *dev);
|
static void mo_init(mo_t *dev);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_MO_LOG
|
#ifdef ENABLE_MO_LOG
|
||||||
int mo_do_log = ENABLE_MO_LOG;
|
int mo_do_log = ENABLE_MO_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_log(const char *fmt, ...)
|
mo_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -301,10 +300,9 @@ mo_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define mo_log(fmt, ...)
|
# define mo_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
find_mo_for_channel(uint8_t channel)
|
find_mo_for_channel(uint8_t channel)
|
||||||
{
|
{
|
||||||
@@ -317,7 +315,6 @@ find_mo_for_channel(uint8_t channel)
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_load_abort(mo_t *dev)
|
mo_load_abort(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -330,17 +327,15 @@ mo_load_abort(mo_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
image_is_mdi(const char *s)
|
image_is_mdi(const char *s)
|
||||||
{
|
{
|
||||||
if (! strcasecmp(path_get_extension((char *) s), "MDI"))
|
if (!strcasecmp(path_get_extension((char *) s), "MDI"))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mo_load(mo_t *dev, char *fn)
|
mo_load(mo_t *dev, char *fn)
|
||||||
{
|
{
|
||||||
@@ -391,7 +386,6 @@ mo_load(mo_t *dev, char *fn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_disk_reload(mo_t *dev)
|
mo_disk_reload(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -406,7 +400,6 @@ mo_disk_reload(mo_t *dev)
|
|||||||
dev->unit_attention = 1;
|
dev->unit_attention = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_disk_unload(mo_t *dev)
|
mo_disk_unload(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -416,7 +409,6 @@ mo_disk_unload(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_disk_close(mo_t *dev)
|
mo_disk_close(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -430,7 +422,6 @@ mo_disk_close(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_set_callback(mo_t *dev)
|
mo_set_callback(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -438,7 +429,6 @@ mo_set_callback(mo_t *dev)
|
|||||||
ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback);
|
ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_init(mo_t *dev)
|
mo_init(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -464,21 +454,18 @@ mo_init(mo_t *dev)
|
|||||||
mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0;
|
mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_supports_pio(mo_t *dev)
|
mo_supports_pio(mo_t *dev)
|
||||||
{
|
{
|
||||||
return (dev->drv->bus_mode & 1);
|
return (dev->drv->bus_mode & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_supports_dma(mo_t *dev)
|
mo_supports_dma(mo_t *dev)
|
||||||
{
|
{
|
||||||
return (dev->drv->bus_mode & 2);
|
return (dev->drv->bus_mode & 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns: 0 for none, 1 for PIO, 2 for DMA. */
|
/* Returns: 0 for none, 1 for PIO, 2 for DMA. */
|
||||||
static int
|
static int
|
||||||
mo_current_mode(mo_t *dev)
|
mo_current_mode(mo_t *dev)
|
||||||
@@ -499,7 +486,6 @@ mo_current_mode(mo_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
|
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
|
||||||
int
|
int
|
||||||
mo_atapi_phase_to_scsi(mo_t *dev)
|
mo_atapi_phase_to_scsi(mo_t *dev)
|
||||||
@@ -525,7 +511,6 @@ mo_atapi_phase_to_scsi(mo_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_mode_sense_load(mo_t *dev)
|
mo_mode_sense_load(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -550,7 +535,6 @@ mo_mode_sense_load(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_mode_sense_save(mo_t *dev)
|
mo_mode_sense_save(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -569,7 +553,6 @@ mo_mode_sense_save(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*SCSI Mode Sense 6/10*/
|
/*SCSI Mode Sense 6/10*/
|
||||||
static uint8_t
|
static uint8_t
|
||||||
mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
||||||
@@ -593,7 +576,6 @@ mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
||||||
{
|
{
|
||||||
@@ -613,11 +595,11 @@ mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block
|
|||||||
buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff);
|
||||||
buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff);
|
||||||
buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff);
|
||||||
buf[pos++] = ( dev->drv->medium_size & 0xff);
|
buf[pos++] = (dev->drv->medium_size & 0xff);
|
||||||
buf[pos++] = 0; /* Reserved. */
|
buf[pos++] = 0; /* Reserved. */
|
||||||
buf[pos++] = 0;
|
buf[pos++] = 0;
|
||||||
buf[pos++] = ((dev->drv->sector_size >> 8) & 0xff);
|
buf[pos++] = ((dev->drv->sector_size >> 8) & 0xff);
|
||||||
buf[pos++] = ( dev->drv->sector_size & 0xff);
|
buf[pos++] = (dev->drv->sector_size & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x40; i++) {
|
for (i = 0; i < 0x40; i++) {
|
||||||
@@ -636,7 +618,6 @@ mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_update_request_length(mo_t *dev, int len, int block_len)
|
mo_update_request_length(mo_t *dev, int len, int block_len)
|
||||||
{
|
{
|
||||||
@@ -692,7 +673,6 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
mo_bus_speed(mo_t *dev)
|
mo_bus_speed(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -713,7 +693,6 @@ mo_bus_speed(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_common(mo_t *dev)
|
mo_command_common(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -738,7 +717,6 @@ mo_command_common(mo_t *dev)
|
|||||||
mo_set_callback(dev);
|
mo_set_callback(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_complete(mo_t *dev)
|
mo_command_complete(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -747,7 +725,6 @@ mo_command_complete(mo_t *dev)
|
|||||||
mo_command_common(dev);
|
mo_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_read(mo_t *dev)
|
mo_command_read(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -755,7 +732,6 @@ mo_command_read(mo_t *dev)
|
|||||||
mo_command_common(dev);
|
mo_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_read_dma(mo_t *dev)
|
mo_command_read_dma(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -763,7 +739,6 @@ mo_command_read_dma(mo_t *dev)
|
|||||||
mo_command_common(dev);
|
mo_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_write(mo_t *dev)
|
mo_command_write(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -771,7 +746,6 @@ mo_command_write(mo_t *dev)
|
|||||||
mo_command_common(dev);
|
mo_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_write_dma(mo_t *dev)
|
mo_command_write_dma(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -779,7 +753,6 @@ mo_command_write_dma(mo_t *dev)
|
|||||||
mo_command_common(dev);
|
mo_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* id = Current MO device ID;
|
/* id = Current MO device ID;
|
||||||
len = Total transfer length;
|
len = Total transfer length;
|
||||||
block_len = Length of a single block (why does it matter?!);
|
block_len = Length of a single block (why does it matter?!);
|
||||||
@@ -822,14 +795,12 @@ mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int dir
|
|||||||
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
|
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_sense_clear(mo_t *dev, int command)
|
mo_sense_clear(mo_t *dev, int command)
|
||||||
{
|
{
|
||||||
mo_sense_key = mo_asc = mo_ascq = 0;
|
mo_sense_key = mo_asc = mo_ascq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_set_phase(mo_t *dev, uint8_t phase)
|
mo_set_phase(mo_t *dev, uint8_t phase)
|
||||||
{
|
{
|
||||||
@@ -842,7 +813,6 @@ mo_set_phase(mo_t *dev, uint8_t phase)
|
|||||||
scsi_devices[scsi_bus][scsi_id].phase = phase;
|
scsi_devices[scsi_bus][scsi_id].phase = phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_cmd_error(mo_t *dev)
|
mo_cmd_error(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -860,7 +830,6 @@ mo_cmd_error(mo_t *dev)
|
|||||||
mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq);
|
mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_unit_attention(mo_t *dev)
|
mo_unit_attention(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -878,7 +847,6 @@ mo_unit_attention(mo_t *dev)
|
|||||||
mo_log("MO %i: UNIT ATTENTION\n", dev->id);
|
mo_log("MO %i: UNIT ATTENTION\n", dev->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_buf_alloc(mo_t *dev, uint32_t len)
|
mo_buf_alloc(mo_t *dev, uint32_t len)
|
||||||
{
|
{
|
||||||
@@ -887,7 +855,6 @@ mo_buf_alloc(mo_t *dev, uint32_t len)
|
|||||||
dev->buffer = (uint8_t *) malloc(len);
|
dev->buffer = (uint8_t *) malloc(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_buf_free(mo_t *dev)
|
mo_buf_free(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -898,7 +865,6 @@ mo_buf_free(mo_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_bus_master_error(scsi_common_t *sc)
|
mo_bus_master_error(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -909,7 +875,6 @@ mo_bus_master_error(scsi_common_t *sc)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_not_ready(mo_t *dev)
|
mo_not_ready(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -919,7 +884,6 @@ mo_not_ready(mo_t *dev)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_write_protected(mo_t *dev)
|
mo_write_protected(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -929,7 +893,6 @@ mo_write_protected(mo_t *dev)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_invalid_lun(mo_t *dev)
|
mo_invalid_lun(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -939,7 +902,6 @@ mo_invalid_lun(mo_t *dev)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_illegal_opcode(mo_t *dev)
|
mo_illegal_opcode(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -949,7 +911,6 @@ mo_illegal_opcode(mo_t *dev)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_lba_out_of_range(mo_t *dev)
|
mo_lba_out_of_range(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -959,7 +920,6 @@ mo_lba_out_of_range(mo_t *dev)
|
|||||||
mo_cmd_error(dev);
|
mo_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_invalid_field(mo_t *dev)
|
mo_invalid_field(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -970,7 +930,6 @@ mo_invalid_field(mo_t *dev)
|
|||||||
dev->status = 0x53;
|
dev->status = 0x53;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_invalid_field_pl(mo_t *dev)
|
mo_invalid_field_pl(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -981,7 +940,6 @@ mo_invalid_field_pl(mo_t *dev)
|
|||||||
dev->status = 0x53;
|
dev->status = 0x53;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out)
|
mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out)
|
||||||
{
|
{
|
||||||
@@ -1027,7 +985,6 @@ mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_insert(mo_t *dev)
|
mo_insert(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1051,35 +1008,35 @@ mo_format(mo_t *dev)
|
|||||||
LARGE_INTEGER liSize;
|
LARGE_INTEGER liSize;
|
||||||
|
|
||||||
fd = _fileno(dev->drv->f);
|
fd = _fileno(dev->drv->f);
|
||||||
fh = (HANDLE)_get_osfhandle(fd);
|
fh = (HANDLE) _get_osfhandle(fd);
|
||||||
|
|
||||||
liSize.QuadPart = 0;
|
liSize.QuadPart = 0;
|
||||||
|
|
||||||
ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN);
|
ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
if(!ret) {
|
if (!ret) {
|
||||||
mo_log("MO %i: Failed seek to start of image file\n", dev->id);
|
mo_log("MO %i: Failed seek to start of image file\n", dev->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int)SetEndOfFile(fh);
|
ret = (int) SetEndOfFile(fh);
|
||||||
|
|
||||||
if(!ret) {
|
if (!ret) {
|
||||||
mo_log("MO %i: Failed to truncate image file to 0\n", dev->id);
|
mo_log("MO %i: Failed to truncate image file to 0\n", dev->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
liSize.QuadPart = size;
|
liSize.QuadPart = size;
|
||||||
ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN);
|
ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
if(!ret) {
|
if (!ret) {
|
||||||
mo_log("MO %i: Failed seek to end of image file\n", dev->id);
|
mo_log("MO %i: Failed seek to end of image file\n", dev->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int)SetEndOfFile(fh);
|
ret = (int) SetEndOfFile(fh);
|
||||||
|
|
||||||
if(!ret) {
|
if (!ret) {
|
||||||
mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size);
|
mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1088,14 +1045,14 @@ mo_format(mo_t *dev)
|
|||||||
|
|
||||||
ret = ftruncate(fd, 0);
|
ret = ftruncate(fd, 0);
|
||||||
|
|
||||||
if(ret) {
|
if (ret) {
|
||||||
mo_log("MO %i: Failed to truncate image file to 0\n", dev->id);
|
mo_log("MO %i: Failed to truncate image file to 0\n", dev->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ftruncate(fd, size);
|
ret = ftruncate(fd, size);
|
||||||
|
|
||||||
if(ret) {
|
if (ret) {
|
||||||
mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size);
|
mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1064,7 @@ mo_erase(mo_t *dev)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! dev->sector_len) {
|
if (!dev->sector_len) {
|
||||||
mo_command_complete(dev);
|
mo_command_complete(dev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1149,7 +1106,6 @@ mo_sense_code_ok(mo_t *dev)
|
|||||||
mo_ascq = 0;
|
mo_ascq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
|
mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
|
||||||
{
|
{
|
||||||
@@ -1226,7 +1182,6 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_seek(mo_t *dev, uint32_t pos)
|
mo_seek(mo_t *dev, uint32_t pos)
|
||||||
{
|
{
|
||||||
@@ -1234,7 +1189,6 @@ mo_seek(mo_t *dev, uint32_t pos)
|
|||||||
dev->sector_pos = pos;
|
dev->sector_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_rezero(mo_t *dev)
|
mo_rezero(mo_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1242,7 +1196,6 @@ mo_rezero(mo_t *dev)
|
|||||||
mo_seek(dev, 0);
|
mo_seek(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_reset(scsi_common_t *sc)
|
mo_reset(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -1259,7 +1212,6 @@ mo_reset(scsi_common_t *sc)
|
|||||||
dev->cur_lun = SCSI_LUN_USE_CDB;
|
dev->cur_lun = SCSI_LUN_USE_CDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
||||||
{
|
{
|
||||||
@@ -1295,7 +1247,6 @@ mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
|||||||
mo_sense_clear(dev, GPCMD_REQUEST_SENSE);
|
mo_sense_clear(dev, GPCMD_REQUEST_SENSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length)
|
mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length)
|
||||||
{
|
{
|
||||||
@@ -1316,7 +1267,6 @@ mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_leng
|
|||||||
mo_request_sense(dev, buffer, alloc_length, 0);
|
mo_request_sense(dev, buffer, alloc_length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len)
|
mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len)
|
||||||
{
|
{
|
||||||
@@ -1331,7 +1281,6 @@ mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command(scsi_common_t *sc, uint8_t *cdb)
|
mo_command(scsi_common_t *sc, uint8_t *cdb)
|
||||||
{
|
{
|
||||||
@@ -1453,7 +1402,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
mo_set_phase(dev, SCSI_PHASE_DATA_IN);
|
mo_set_phase(dev, SCSI_PHASE_DATA_IN);
|
||||||
alloc_length = dev->drv->sector_size;
|
alloc_length = dev->drv->sector_size;
|
||||||
|
|
||||||
switch(cdb[0]) {
|
switch (cdb[0]) {
|
||||||
case GPCMD_READ_6:
|
case GPCMD_READ_6:
|
||||||
dev->sector_len = cdb[4];
|
dev->sector_len = cdb[4];
|
||||||
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
|
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
|
||||||
@@ -1566,8 +1515,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dev->sector_pos >= dev->drv->medium_size)/* ||
|
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
|
||||||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) {
|
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
|
||||||
|
) {
|
||||||
mo_lba_out_of_range(dev);
|
mo_lba_out_of_range(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1638,8 +1588,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
} else {
|
} else {
|
||||||
len = mo_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc);
|
len = mo_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc);
|
||||||
len = MIN(len, alloc_length);
|
len = MIN(len, alloc_length);
|
||||||
dev->buffer[0]=(len - 2) >> 8;
|
dev->buffer[0] = (len - 2) >> 8;
|
||||||
dev->buffer[1]=(len - 2) & 255;
|
dev->buffer[1] = (len - 2) & 255;
|
||||||
dev->buffer[2] = 0;
|
dev->buffer[2] = 0;
|
||||||
if (block_desc) {
|
if (block_desc) {
|
||||||
dev->buffer[6] = 0;
|
dev->buffer[6] = 0;
|
||||||
@@ -1677,7 +1627,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
case GPCMD_START_STOP_UNIT:
|
case GPCMD_START_STOP_UNIT:
|
||||||
mo_set_phase(dev, SCSI_PHASE_STATUS);
|
mo_set_phase(dev, SCSI_PHASE_STATUS);
|
||||||
|
|
||||||
switch(cdb[4] & 3) {
|
switch (cdb[4] & 3) {
|
||||||
case 0: /* Stop the disk. */
|
case 0: /* Stop the disk. */
|
||||||
break;
|
break;
|
||||||
case 1: /* Start the disk and read the TOC. */
|
case 1: /* Start the disk and read the TOC. */
|
||||||
@@ -1769,7 +1719,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev->buffer[size_idx] = idx - preamble_len;
|
dev->buffer[size_idx] = idx - preamble_len;
|
||||||
len=idx;
|
len = idx;
|
||||||
|
|
||||||
len = MIN(len, max_len);
|
len = MIN(len, max_len);
|
||||||
mo_set_buf_len(dev, BufLen, &len);
|
mo_set_buf_len(dev, BufLen, &len);
|
||||||
@@ -1786,7 +1736,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
case GPCMD_SEEK_10:
|
case GPCMD_SEEK_10:
|
||||||
mo_set_phase(dev, SCSI_PHASE_STATUS);
|
mo_set_phase(dev, SCSI_PHASE_STATUS);
|
||||||
|
|
||||||
switch(cdb[0]) {
|
switch (cdb[0]) {
|
||||||
case GPCMD_SEEK_6:
|
case GPCMD_SEEK_6:
|
||||||
pos = (cdb[2] << 8) | cdb[3];
|
pos = (cdb[2] << 8) | cdb[3];
|
||||||
break;
|
break;
|
||||||
@@ -1889,7 +1839,6 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
mo_buf_free(dev);
|
mo_buf_free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_command_stop(scsi_common_t *sc)
|
mo_command_stop(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -1899,7 +1848,6 @@ mo_command_stop(scsi_common_t *sc)
|
|||||||
mo_buf_free(dev);
|
mo_buf_free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The command second phase function, needed for Mode Select. */
|
/* The command second phase function, needed for Mode Select. */
|
||||||
static uint8_t
|
static uint8_t
|
||||||
mo_phase_data_out(scsi_common_t *sc)
|
mo_phase_data_out(scsi_common_t *sc)
|
||||||
@@ -1918,7 +1866,7 @@ mo_phase_data_out(scsi_common_t *sc)
|
|||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
switch(dev->current_cdb[0]) {
|
switch (dev->current_cdb[0]) {
|
||||||
case GPCMD_VERIFY_6:
|
case GPCMD_VERIFY_6:
|
||||||
case GPCMD_VERIFY_10:
|
case GPCMD_VERIFY_10:
|
||||||
case GPCMD_VERIFY_12:
|
case GPCMD_VERIFY_12:
|
||||||
@@ -1958,7 +1906,7 @@ mo_phase_data_out(scsi_common_t *sc)
|
|||||||
|
|
||||||
pos = hdr_len + block_desc_len;
|
pos = hdr_len + block_desc_len;
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
if (pos >= param_list_len) {
|
if (pos >= param_list_len) {
|
||||||
mo_log("MO %i: Buffer has only block descriptor\n", dev->id);
|
mo_log("MO %i: Buffer has only block descriptor\n", dev->id);
|
||||||
break;
|
break;
|
||||||
@@ -2010,7 +1958,6 @@ mo_phase_data_out(scsi_common_t *sc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Peform a master init on the entire module. */
|
/* Peform a master init on the entire module. */
|
||||||
void
|
void
|
||||||
mo_global_init(void)
|
mo_global_init(void)
|
||||||
@@ -2019,13 +1966,12 @@ mo_global_init(void)
|
|||||||
memset(mo_drives, 0x00, sizeof(mo_drives));
|
memset(mo_drives, 0x00, sizeof(mo_drives));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_get_max(int ide_has_dma, int type)
|
mo_get_max(int ide_has_dma, int type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TYPE_PIO:
|
case TYPE_PIO:
|
||||||
ret = ide_has_dma ? 3 : 0;
|
ret = ide_has_dma ? 3 : 0;
|
||||||
break;
|
break;
|
||||||
@@ -2044,13 +1990,12 @@ mo_get_max(int ide_has_dma, int type)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mo_get_timings(int ide_has_dma, int type)
|
mo_get_timings(int ide_has_dma, int type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TIMINGS_DMA:
|
case TIMINGS_DMA:
|
||||||
ret = ide_has_dma ? 0x96 : 0;
|
ret = ide_has_dma ? 0x96 : 0;
|
||||||
break;
|
break;
|
||||||
@@ -2073,7 +2018,7 @@ mo_do_identify(ide_t *ide, int ide_has_dma)
|
|||||||
{
|
{
|
||||||
char model[40];
|
char model[40];
|
||||||
|
|
||||||
mo_t* mo = (mo_t*) ide->sc;
|
mo_t *mo = (mo_t *) ide->sc;
|
||||||
|
|
||||||
memset(model, 0, 40);
|
memset(model, 0, 40);
|
||||||
|
|
||||||
@@ -2093,7 +2038,6 @@ mo_do_identify(ide_t *ide, int ide_has_dma)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_identify(ide_t *ide, int ide_has_dma)
|
mo_identify(ide_t *ide, int ide_has_dma)
|
||||||
{
|
{
|
||||||
@@ -2104,7 +2048,6 @@ mo_identify(ide_t *ide, int ide_has_dma)
|
|||||||
mo_do_identify(ide, ide_has_dma);
|
mo_do_identify(ide, ide_has_dma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mo_drive_reset(int c)
|
mo_drive_reset(int c)
|
||||||
{
|
{
|
||||||
@@ -2159,7 +2102,6 @@ mo_drive_reset(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_hard_reset(void)
|
mo_hard_reset(void)
|
||||||
{
|
{
|
||||||
@@ -2210,7 +2152,6 @@ mo_hard_reset(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mo_close(void)
|
mo_close(void)
|
||||||
{
|
{
|
||||||
|
|||||||
130
src/disk/zip.c
130
src/disk/zip.c
@@ -36,13 +36,10 @@
|
|||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
|
|
||||||
|
|
||||||
zip_drive_t zip_drives[ZIP_NUM];
|
zip_drive_t zip_drives[ZIP_NUM];
|
||||||
|
|
||||||
|
|
||||||
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
||||||
const uint8_t zip_command_flags[0x100] =
|
const uint8_t zip_command_flags[0x100] = {
|
||||||
{
|
|
||||||
IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */
|
IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */
|
||||||
IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */
|
IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */
|
||||||
0,
|
0,
|
||||||
@@ -111,18 +108,11 @@ const uint8_t zip_command_flags[0x100] =
|
|||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE |
|
static uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_IOMEGA_PAGE | GPMODEP_ALL_PAGES);
|
||||||
GPMODEP_DISCONNECT_PAGE |
|
static uint64_t zip_250_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_FLEXIBLE_DISK_PAGE | GPMODEP_CACHING_PAGE | GPMODEP_IOMEGA_PAGE | GPMODEP_ALL_PAGES);
|
||||||
GPMODEP_IOMEGA_PAGE |
|
|
||||||
GPMODEP_ALL_PAGES);
|
|
||||||
static uint64_t zip_250_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE |
|
|
||||||
GPMODEP_FLEXIBLE_DISK_PAGE |
|
|
||||||
GPMODEP_CACHING_PAGE |
|
|
||||||
GPMODEP_IOMEGA_PAGE |
|
|
||||||
GPMODEP_ALL_PAGES);
|
|
||||||
|
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_mode_sense_pages_default =
|
static const mode_sense_pages_t zip_mode_sense_pages_default =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 },
|
{ GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 },
|
||||||
@@ -173,8 +163,10 @@ static const mode_sense_pages_t zip_mode_sense_pages_default =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_250_mode_sense_pages_default =
|
static const mode_sense_pages_t zip_250_mode_sense_pages_default =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 },
|
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 },
|
||||||
@@ -224,8 +216,10 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_default =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_mode_sense_pages_default_scsi =
|
static const mode_sense_pages_t zip_mode_sense_pages_default_scsi =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 },
|
{ GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 },
|
||||||
@@ -276,8 +270,10 @@ static const mode_sense_pages_t zip_mode_sense_pages_default_scsi =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi =
|
static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 },
|
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 },
|
||||||
@@ -328,8 +324,10 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_mode_sense_pages_changeable =
|
static const mode_sense_pages_t zip_mode_sense_pages_changeable =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
@@ -381,8 +379,10 @@ static const mode_sense_pages_t zip_mode_sense_pages_changeable =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static const mode_sense_pages_t zip_250_mode_sense_pages_changeable =
|
static const mode_sense_pages_t zip_250_mode_sense_pages_changeable =
|
||||||
|
// clang-format off
|
||||||
{ {
|
{ {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xFF, 0xFF, 0, 0, 0, 0 },
|
{ GPMODE_R_W_ERROR_PAGE, 0x06, 0xFF, 0xFF, 0, 0, 0, 0 },
|
||||||
@@ -433,16 +433,14 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable =
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff }
|
{ GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff }
|
||||||
} };
|
} };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
static void zip_command_complete(zip_t *dev);
|
static void zip_command_complete(zip_t *dev);
|
||||||
static void zip_init(zip_t *dev);
|
static void zip_init(zip_t *dev);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_ZIP_LOG
|
#ifdef ENABLE_ZIP_LOG
|
||||||
int zip_do_log = ENABLE_ZIP_LOG;
|
int zip_do_log = ENABLE_ZIP_LOG;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_log(const char *fmt, ...)
|
zip_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -455,10 +453,9 @@ zip_log(const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define zip_log(fmt, ...)
|
# define zip_log(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
find_zip_for_channel(uint8_t channel)
|
find_zip_for_channel(uint8_t channel)
|
||||||
{
|
{
|
||||||
@@ -471,7 +468,6 @@ find_zip_for_channel(uint8_t channel)
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_load_abort(zip_t *dev)
|
zip_load_abort(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -483,7 +479,6 @@ zip_load_abort(zip_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
zip_load(zip_t *dev, char *fn)
|
zip_load(zip_t *dev, char *fn)
|
||||||
{
|
{
|
||||||
@@ -535,7 +530,6 @@ zip_load(zip_t *dev, char *fn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_disk_reload(zip_t *dev)
|
zip_disk_reload(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -550,7 +544,6 @@ zip_disk_reload(zip_t *dev)
|
|||||||
dev->unit_attention = 1;
|
dev->unit_attention = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_disk_unload(zip_t *dev)
|
zip_disk_unload(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -560,7 +553,6 @@ zip_disk_unload(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_disk_close(zip_t *dev)
|
zip_disk_close(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -574,7 +566,6 @@ zip_disk_close(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_set_callback(zip_t *dev)
|
zip_set_callback(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -582,7 +573,6 @@ zip_set_callback(zip_t *dev)
|
|||||||
ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback);
|
ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_init(zip_t *dev)
|
zip_init(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -608,21 +598,18 @@ zip_init(zip_t *dev)
|
|||||||
zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0;
|
zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_supports_pio(zip_t *dev)
|
zip_supports_pio(zip_t *dev)
|
||||||
{
|
{
|
||||||
return (dev->drv->bus_mode & 1);
|
return (dev->drv->bus_mode & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_supports_dma(zip_t *dev)
|
zip_supports_dma(zip_t *dev)
|
||||||
{
|
{
|
||||||
return (dev->drv->bus_mode & 2);
|
return (dev->drv->bus_mode & 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns: 0 for none, 1 for PIO, 2 for DMA. */
|
/* Returns: 0 for none, 1 for PIO, 2 for DMA. */
|
||||||
static int
|
static int
|
||||||
zip_current_mode(zip_t *dev)
|
zip_current_mode(zip_t *dev)
|
||||||
@@ -643,7 +630,6 @@ zip_current_mode(zip_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
|
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
|
||||||
int
|
int
|
||||||
zip_atapi_phase_to_scsi(zip_t *dev)
|
zip_atapi_phase_to_scsi(zip_t *dev)
|
||||||
@@ -669,7 +655,6 @@ zip_atapi_phase_to_scsi(zip_t *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_mode_sense_load(zip_t *dev)
|
zip_mode_sense_load(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -701,7 +686,6 @@ zip_mode_sense_load(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_mode_sense_save(zip_t *dev)
|
zip_mode_sense_save(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -720,7 +704,6 @@ zip_mode_sense_save(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*SCSI Mode Sense 6/10*/
|
/*SCSI Mode Sense 6/10*/
|
||||||
static uint8_t
|
static uint8_t
|
||||||
zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
||||||
@@ -758,7 +741,6 @@ zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
||||||
{
|
{
|
||||||
@@ -781,7 +763,7 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t blo
|
|||||||
buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff);
|
||||||
buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff);
|
||||||
buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff);
|
buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff);
|
||||||
buf[pos++] = ( dev->drv->medium_size & 0xff);
|
buf[pos++] = (dev->drv->medium_size & 0xff);
|
||||||
buf[pos++] = 0; /* Reserved. */
|
buf[pos++] = 0; /* Reserved. */
|
||||||
buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */
|
buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */
|
||||||
buf[pos++] = 2;
|
buf[pos++] = 2;
|
||||||
@@ -804,7 +786,6 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t blo
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_update_request_length(zip_t *dev, int len, int block_len)
|
zip_update_request_length(zip_t *dev, int len, int block_len)
|
||||||
{
|
{
|
||||||
@@ -860,7 +841,6 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
zip_bus_speed(zip_t *dev)
|
zip_bus_speed(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -881,7 +861,6 @@ zip_bus_speed(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_common(zip_t *dev)
|
zip_command_common(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -906,7 +885,6 @@ zip_command_common(zip_t *dev)
|
|||||||
zip_set_callback(dev);
|
zip_set_callback(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_complete(zip_t *dev)
|
zip_command_complete(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -915,7 +893,6 @@ zip_command_complete(zip_t *dev)
|
|||||||
zip_command_common(dev);
|
zip_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_read(zip_t *dev)
|
zip_command_read(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -923,7 +900,6 @@ zip_command_read(zip_t *dev)
|
|||||||
zip_command_common(dev);
|
zip_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_read_dma(zip_t *dev)
|
zip_command_read_dma(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -931,7 +907,6 @@ zip_command_read_dma(zip_t *dev)
|
|||||||
zip_command_common(dev);
|
zip_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_write(zip_t *dev)
|
zip_command_write(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -939,7 +914,6 @@ zip_command_write(zip_t *dev)
|
|||||||
zip_command_common(dev);
|
zip_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_write_dma(zip_t *dev)
|
zip_command_write_dma(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -947,7 +921,6 @@ zip_command_write_dma(zip_t *dev)
|
|||||||
zip_command_common(dev);
|
zip_command_common(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* id = Current ZIP device ID;
|
/* id = Current ZIP device ID;
|
||||||
len = Total transfer length;
|
len = Total transfer length;
|
||||||
block_len = Length of a single block (why does it matter?!);
|
block_len = Length of a single block (why does it matter?!);
|
||||||
@@ -990,14 +963,12 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d
|
|||||||
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
|
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_sense_clear(zip_t *dev, int command)
|
zip_sense_clear(zip_t *dev, int command)
|
||||||
{
|
{
|
||||||
zip_sense_key = zip_asc = zip_ascq = 0;
|
zip_sense_key = zip_asc = zip_ascq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_set_phase(zip_t *dev, uint8_t phase)
|
zip_set_phase(zip_t *dev, uint8_t phase)
|
||||||
{
|
{
|
||||||
@@ -1010,7 +981,6 @@ zip_set_phase(zip_t *dev, uint8_t phase)
|
|||||||
scsi_devices[scsi_bus][scsi_id].phase = phase;
|
scsi_devices[scsi_bus][scsi_id].phase = phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_cmd_error(zip_t *dev)
|
zip_cmd_error(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1028,7 +998,6 @@ zip_cmd_error(zip_t *dev)
|
|||||||
zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq);
|
zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_unit_attention(zip_t *dev)
|
zip_unit_attention(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1046,7 +1015,6 @@ zip_unit_attention(zip_t *dev)
|
|||||||
zip_log("ZIP %i: UNIT ATTENTION\n", dev->id);
|
zip_log("ZIP %i: UNIT ATTENTION\n", dev->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_buf_alloc(zip_t *dev, uint32_t len)
|
zip_buf_alloc(zip_t *dev, uint32_t len)
|
||||||
{
|
{
|
||||||
@@ -1055,7 +1023,6 @@ zip_buf_alloc(zip_t *dev, uint32_t len)
|
|||||||
dev->buffer = (uint8_t *) malloc(len);
|
dev->buffer = (uint8_t *) malloc(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_buf_free(zip_t *dev)
|
zip_buf_free(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1066,7 +1033,6 @@ zip_buf_free(zip_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_bus_master_error(scsi_common_t *sc)
|
zip_bus_master_error(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -1077,7 +1043,6 @@ zip_bus_master_error(scsi_common_t *sc)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_not_ready(zip_t *dev)
|
zip_not_ready(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1087,7 +1052,6 @@ zip_not_ready(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_write_protected(zip_t *dev)
|
zip_write_protected(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1097,7 +1061,6 @@ zip_write_protected(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_invalid_lun(zip_t *dev)
|
zip_invalid_lun(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1107,7 +1070,6 @@ zip_invalid_lun(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_illegal_opcode(zip_t *dev)
|
zip_illegal_opcode(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1117,7 +1079,6 @@ zip_illegal_opcode(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_lba_out_of_range(zip_t *dev)
|
zip_lba_out_of_range(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1127,7 +1088,6 @@ zip_lba_out_of_range(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_invalid_field(zip_t *dev)
|
zip_invalid_field(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1138,7 +1098,6 @@ zip_invalid_field(zip_t *dev)
|
|||||||
dev->status = 0x53;
|
dev->status = 0x53;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_invalid_field_pl(zip_t *dev)
|
zip_invalid_field_pl(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1149,7 +1108,6 @@ zip_invalid_field_pl(zip_t *dev)
|
|||||||
dev->status = 0x53;
|
dev->status = 0x53;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_data_phase_error(zip_t *dev)
|
zip_data_phase_error(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1159,7 +1117,6 @@ zip_data_phase_error(zip_t *dev)
|
|||||||
zip_cmd_error(dev);
|
zip_cmd_error(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out)
|
zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out)
|
||||||
{
|
{
|
||||||
@@ -1205,14 +1162,12 @@ zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_insert(zip_t *dev)
|
zip_insert(zip_t *dev)
|
||||||
{
|
{
|
||||||
dev->unit_attention = 1;
|
dev->unit_attention = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*SCSI Sense Initialization*/
|
/*SCSI Sense Initialization*/
|
||||||
void
|
void
|
||||||
zip_sense_code_ok(zip_t *dev)
|
zip_sense_code_ok(zip_t *dev)
|
||||||
@@ -1222,7 +1177,6 @@ zip_sense_code_ok(zip_t *dev)
|
|||||||
zip_ascq = 0;
|
zip_ascq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
|
zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
|
||||||
{
|
{
|
||||||
@@ -1299,7 +1253,6 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_seek(zip_t *dev, uint32_t pos)
|
zip_seek(zip_t *dev, uint32_t pos)
|
||||||
{
|
{
|
||||||
@@ -1307,7 +1260,6 @@ zip_seek(zip_t *dev, uint32_t pos)
|
|||||||
dev->sector_pos = pos;
|
dev->sector_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_rezero(zip_t *dev)
|
zip_rezero(zip_t *dev)
|
||||||
{
|
{
|
||||||
@@ -1315,7 +1267,6 @@ zip_rezero(zip_t *dev)
|
|||||||
zip_seek(dev, 0);
|
zip_seek(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_reset(scsi_common_t *sc)
|
zip_reset(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -1332,7 +1283,6 @@ zip_reset(scsi_common_t *sc)
|
|||||||
dev->cur_lun = SCSI_LUN_USE_CDB;
|
dev->cur_lun = SCSI_LUN_USE_CDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
||||||
{
|
{
|
||||||
@@ -1368,7 +1318,6 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
|||||||
zip_sense_clear(dev, GPCMD_REQUEST_SENSE);
|
zip_sense_clear(dev, GPCMD_REQUEST_SENSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length)
|
zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length)
|
||||||
{
|
{
|
||||||
@@ -1389,7 +1338,6 @@ zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_len
|
|||||||
zip_request_sense(dev, buffer, alloc_length, 0);
|
zip_request_sense(dev, buffer, alloc_length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len)
|
zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len)
|
||||||
{
|
{
|
||||||
@@ -1404,7 +1352,6 @@ zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command(scsi_common_t *sc, uint8_t *cdb)
|
zip_command(scsi_common_t *sc, uint8_t *cdb)
|
||||||
{
|
{
|
||||||
@@ -1553,7 +1500,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
zip_set_phase(dev, SCSI_PHASE_DATA_IN);
|
zip_set_phase(dev, SCSI_PHASE_DATA_IN);
|
||||||
alloc_length = 512;
|
alloc_length = 512;
|
||||||
|
|
||||||
switch(cdb[0]) {
|
switch (cdb[0]) {
|
||||||
case GPCMD_READ_6:
|
case GPCMD_READ_6:
|
||||||
dev->sector_len = cdb[4];
|
dev->sector_len = cdb[4];
|
||||||
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
|
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
|
||||||
@@ -1631,7 +1578,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cdb[0]) {
|
switch (cdb[0]) {
|
||||||
case GPCMD_VERIFY_6:
|
case GPCMD_VERIFY_6:
|
||||||
case GPCMD_WRITE_6:
|
case GPCMD_WRITE_6:
|
||||||
dev->sector_len = cdb[4];
|
dev->sector_len = cdb[4];
|
||||||
@@ -1654,8 +1601,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dev->sector_pos >= dev->drv->medium_size)/* ||
|
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
|
||||||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) {
|
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
|
||||||
|
) {
|
||||||
zip_lba_out_of_range(dev);
|
zip_lba_out_of_range(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1706,8 +1654,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
dev->sector_len = (cdb[7] << 8) | cdb[8];
|
dev->sector_len = (cdb[7] << 8) | cdb[8];
|
||||||
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
|
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
|
||||||
|
|
||||||
if ((dev->sector_pos >= dev->drv->medium_size)/* ||
|
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
|
||||||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) {
|
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
|
||||||
|
) {
|
||||||
zip_lba_out_of_range(dev);
|
zip_lba_out_of_range(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1775,8 +1724,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
} else {
|
} else {
|
||||||
len = zip_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc);
|
len = zip_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc);
|
||||||
len = MIN(len, alloc_length);
|
len = MIN(len, alloc_length);
|
||||||
dev->buffer[0]=(len - 2) >> 8;
|
dev->buffer[0] = (len - 2) >> 8;
|
||||||
dev->buffer[1]=(len - 2) & 255;
|
dev->buffer[1] = (len - 2) & 255;
|
||||||
dev->buffer[2] = 0;
|
dev->buffer[2] = 0;
|
||||||
if (block_desc) {
|
if (block_desc) {
|
||||||
dev->buffer[6] = 0;
|
dev->buffer[6] = 0;
|
||||||
@@ -1814,7 +1763,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
case GPCMD_START_STOP_UNIT:
|
case GPCMD_START_STOP_UNIT:
|
||||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||||
|
|
||||||
switch(cdb[4] & 3) {
|
switch (cdb[4] & 3) {
|
||||||
case 0: /* Stop the disc. */
|
case 0: /* Stop the disc. */
|
||||||
zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */
|
zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */
|
||||||
break;
|
break;
|
||||||
@@ -1936,7 +1885,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
|||||||
|
|
||||||
atapi_out:
|
atapi_out:
|
||||||
dev->buffer[size_idx] = idx - preamble_len;
|
dev->buffer[size_idx] = idx - preamble_len;
|
||||||
len=idx;
|
len = idx;
|
||||||
|
|
||||||
len = MIN(len, max_len);
|
len = MIN(len, max_len);
|
||||||
zip_set_buf_len(dev, BufLen, &len);
|
zip_set_buf_len(dev, BufLen, &len);
|
||||||
@@ -1953,7 +1902,7 @@ atapi_out:
|
|||||||
case GPCMD_SEEK_10:
|
case GPCMD_SEEK_10:
|
||||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||||
|
|
||||||
switch(cdb[0]) {
|
switch (cdb[0]) {
|
||||||
case GPCMD_SEEK_6:
|
case GPCMD_SEEK_6:
|
||||||
pos = (cdb[2] << 8) | cdb[3];
|
pos = (cdb[2] << 8) | cdb[3];
|
||||||
break;
|
break;
|
||||||
@@ -2069,7 +2018,6 @@ atapi_out:
|
|||||||
zip_buf_free(dev);
|
zip_buf_free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_command_stop(scsi_common_t *sc)
|
zip_command_stop(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
@@ -2079,7 +2027,6 @@ zip_command_stop(scsi_common_t *sc)
|
|||||||
zip_buf_free(dev);
|
zip_buf_free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The command second phase function, needed for Mode Select. */
|
/* The command second phase function, needed for Mode Select. */
|
||||||
static uint8_t
|
static uint8_t
|
||||||
zip_phase_data_out(scsi_common_t *sc)
|
zip_phase_data_out(scsi_common_t *sc)
|
||||||
@@ -2101,7 +2048,7 @@ zip_phase_data_out(scsi_common_t *sc)
|
|||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
switch(dev->current_cdb[0]) {
|
switch (dev->current_cdb[0]) {
|
||||||
case GPCMD_VERIFY_6:
|
case GPCMD_VERIFY_6:
|
||||||
case GPCMD_VERIFY_10:
|
case GPCMD_VERIFY_10:
|
||||||
case GPCMD_VERIFY_12:
|
case GPCMD_VERIFY_12:
|
||||||
@@ -2173,7 +2120,7 @@ zip_phase_data_out(scsi_common_t *sc)
|
|||||||
|
|
||||||
pos = hdr_len + block_desc_len;
|
pos = hdr_len + block_desc_len;
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
if (pos >= param_list_len) {
|
if (pos >= param_list_len) {
|
||||||
zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id);
|
zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id);
|
||||||
break;
|
break;
|
||||||
@@ -2225,7 +2172,6 @@ zip_phase_data_out(scsi_common_t *sc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Peform a master init on the entire module. */
|
/* Peform a master init on the entire module. */
|
||||||
void
|
void
|
||||||
zip_global_init(void)
|
zip_global_init(void)
|
||||||
@@ -2234,13 +2180,12 @@ zip_global_init(void)
|
|||||||
memset(zip_drives, 0x00, sizeof(zip_drives));
|
memset(zip_drives, 0x00, sizeof(zip_drives));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_get_max(int ide_has_dma, int type)
|
zip_get_max(int ide_has_dma, int type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TYPE_PIO:
|
case TYPE_PIO:
|
||||||
ret = ide_has_dma ? 3 : 0;
|
ret = ide_has_dma ? 3 : 0;
|
||||||
break;
|
break;
|
||||||
@@ -2259,13 +2204,12 @@ zip_get_max(int ide_has_dma, int type)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_get_timings(int ide_has_dma, int type)
|
zip_get_timings(int ide_has_dma, int type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case TIMINGS_DMA:
|
case TIMINGS_DMA:
|
||||||
ret = ide_has_dma ? 0x96 : 0;
|
ret = ide_has_dma ? 0x96 : 0;
|
||||||
break;
|
break;
|
||||||
@@ -2283,7 +2227,6 @@ zip_get_timings(int ide_has_dma, int type)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_100_identify(ide_t *ide)
|
zip_100_identify(ide_t *ide)
|
||||||
{
|
{
|
||||||
@@ -2291,7 +2234,6 @@ zip_100_identify(ide_t *ide)
|
|||||||
ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */
|
ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_250_identify(ide_t *ide, int ide_has_dma)
|
zip_250_identify(ide_t *ide, int ide_has_dma)
|
||||||
{
|
{
|
||||||
@@ -2304,7 +2246,6 @@ zip_250_identify(ide_t *ide, int ide_has_dma)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_identify(ide_t *ide, int ide_has_dma)
|
zip_identify(ide_t *ide, int ide_has_dma)
|
||||||
{
|
{
|
||||||
@@ -2327,7 +2268,6 @@ zip_identify(ide_t *ide, int ide_has_dma)
|
|||||||
zip_100_identify(ide);
|
zip_100_identify(ide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_drive_reset(int c)
|
zip_drive_reset(int c)
|
||||||
{
|
{
|
||||||
@@ -2382,7 +2322,6 @@ zip_drive_reset(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_hard_reset(void)
|
zip_hard_reset(void)
|
||||||
{
|
{
|
||||||
@@ -2433,7 +2372,6 @@ zip_hard_reset(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zip_close(void)
|
zip_close(void)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user