diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 7ba9a0f1e..0f2bc8599 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -29,33 +29,30 @@ #include <86box/hdc_ide.h> #include <86box/hdd.h> - -int hdc_current; - +int hdc_current; #ifdef ENABLE_HDC_LOG int hdc_do_log = ENABLE_HDC_LOG; - static void hdc_log(const char *fmt, ...) { va_list ap; if (hdc_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define hdc_log(fmt, ...) +# define hdc_log(fmt, ...) #endif static void * nullhdc_init(const device_t *info) { - return(NULL); + return (NULL); } static void @@ -66,7 +63,7 @@ nullhdc_close(void *priv) static void * inthdc_init(const device_t *info) { - return(NULL); + return (NULL); } static void @@ -75,37 +72,37 @@ inthdc_close(void *priv) } static const device_t hdc_none_device = { - .name = "None", + .name = "None", .internal_name = "none", - .flags = 0, - .local = 0, - .init = nullhdc_init, - .close = nullhdc_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = nullhdc_init, + .close = nullhdc_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; static const device_t hdc_internal_device = { - .name = "Internal", + .name = "Internal", .internal_name = "internal", - .flags = 0, - .local = 0, - .init = inthdc_init, - .close = inthdc_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = inthdc_init, + .close = inthdc_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; static const struct { - const device_t *device; + const device_t *device; } controllers[] = { -// clang-format off + // clang-format off { &hdc_none_device }, { &hdc_internal_device }, { &st506_xt_xebec_device }, @@ -133,7 +130,7 @@ static const struct { { &ide_vlb_device }, { &ide_vlb_2ch_device }, { NULL } -// clang-format on + // clang-format on }; /* Initialize the 'hdc_current' value based on configured HDC name. */ @@ -146,77 +143,72 @@ hdc_init(void) hdd_image_init(); } - /* Reset the HDC, whichever one that is. */ void hdc_reset(void) { hdc_log("HDC: reset(current=%d, internal=%d)\n", - hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0); + hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0); /* If we have a valid controller, add its device. */ if (hdc_current > 1) - device_add(controllers[hdc_current].device); + device_add(controllers[hdc_current].device); /* Now, add the tertiary and/or quaternary IDE controllers. */ if (ide_ter_enabled) - device_add(&ide_ter_device); + device_add(&ide_ter_device); if (ide_qua_enabled) - device_add(&ide_qua_device); + device_add(&ide_qua_device); } - char * hdc_get_internal_name(int hdc) { return device_get_internal_name(controllers[hdc].device); } - int hdc_get_from_internal_name(char *s) { int c = 0; while (controllers[c].device != NULL) { - if (!strcmp((char *) controllers[c].device->internal_name, s)) - return c; - c++; + if (!strcmp((char *) controllers[c].device->internal_name, s)) + return c; + c++; } return 0; } - const device_t * hdc_get_device(int hdc) { - return(controllers[hdc].device); + return (controllers[hdc].device); } - int hdc_has_config(int hdc) { const device_t *dev = hdc_get_device(hdc); - if (dev == NULL) return(0); + if (dev == NULL) + return (0); - if (!device_has_config(dev)) return(0); + if (!device_has_config(dev)) + return (0); - return(1); + return (1); } - int hdc_get_flags(int hdc) { - return(controllers[hdc].device->flags); + return (controllers[hdc].device->flags); } - int hdc_available(int hdc) { - return(device_available(controllers[hdc].device)); + return (device_available(controllers[hdc].device)); } diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 59d8308a8..c37d4782a 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -40,116 +40,108 @@ #include <86box/hdc.h> #include <86box/hdd.h> +#define HDC_TIME 10.0 +#define BIOS_FILE "roms/hdd/esdi_at/62-000279-061.bin" -#define HDC_TIME 10.0 -#define BIOS_FILE "roms/hdd/esdi_at/62-000279-061.bin" +#define STAT_ERR 0x01 +#define STAT_INDEX 0x02 +#define STAT_CORRECTED_DATA 0x04 +#define STAT_DRQ 0x08 /* Data request */ +#define STAT_DSC 0x10 +#define STAT_SEEK_COMPLETE 0x20 +#define STAT_READY 0x40 +#define STAT_BUSY 0x80 -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_CORRECTED_DATA 0x04 -#define STAT_DRQ 0x08 /* Data request */ -#define STAT_DSC 0x10 -#define STAT_SEEK_COMPLETE 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 - -#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ -#define ERR_TR000 0x02 /* track 0 not found */ -#define ERR_ABRT 0x04 /* command aborted */ -#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ -#define ERR_DATA_CRC 0x40 /* data CRC error */ -#define ERR_BAD_BLOCK 0x80 /* bad block detected */ - -#define CMD_NOP 0x00 -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 -#define CMD_READ_PARAMETERS 0xec +#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ +#define ERR_TR000 0x02 /* track 0 not found */ +#define ERR_ABRT 0x04 /* command aborted */ +#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ +#define ERR_DATA_CRC 0x40 /* data CRC error */ +#define ERR_BAD_BLOCK 0x80 /* bad block detected */ +#define CMD_NOP 0x00 +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 +#define CMD_READ_PARAMETERS 0xec typedef struct { - int cfg_spt; - int cfg_hpc; - int current_cylinder; - int real_spt; - int real_hpc; - int real_tracks; - int present; - int hdd_num; + int cfg_spt; + int cfg_hpc; + int current_cylinder; + int real_spt; + int real_hpc; + int real_tracks; + int present; + int hdd_num; } drive_t; typedef struct { - uint8_t status; - uint8_t error; - int secount,sector,cylinder,head,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; + uint8_t status; + uint8_t error; + int secount, sector, cylinder, head, cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; - int drive_sel; - int reset; - uint16_t buffer[256]; - int irqstat; + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - drive_t drives[2]; + drive_t drives[2]; - rom_t bios_rom; + rom_t bios_rom; } esdi_t; - -static uint8_t esdi_read(uint16_t port, void *priv); -static void esdi_write(uint16_t port, uint8_t val, void *priv); - +static uint8_t esdi_read(uint16_t port, void *priv); +static void esdi_write(uint16_t port, uint8_t val, void *priv); #ifdef ENABLE_ESDI_AT_LOG int esdi_at_do_log = ENABLE_ESDI_AT_LOG; - static void esdi_at_log(const char *fmt, ...) { va_list ap; if (esdi_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define esdi_at_log(fmt, ...) +# define esdi_at_log(fmt, ...) #endif - static __inline void irq_raise(esdi_t *esdi) { if (!(esdi->fdisk & 2)) - picint(1 << 14); + picint(1 << 14); esdi->irqstat = 1; } - static __inline void irq_lower(esdi_t *esdi) { picintc(1 << 14); } - static __inline void irq_update(esdi_t *esdi) { if (esdi->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); + picint(1 << 14); } static void @@ -170,53 +162,50 @@ double esdi_get_xfer_time(esdi_t *esdi, int size) { /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - return (3125.0 / 8.0) * (double)size; + return (3125.0 / 8.0) * (double) size; } /* Return the sector offset for the current register values. */ static int get_sector(esdi_t *esdi, off64_t *addr) { - drive_t *drive = &esdi->drives[esdi->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; - int c, h, s, sector; + drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + int c, h, s, sector; if (esdi->head > heads) { - esdi_at_log("esdi_get_sector: past end of configured heads\n"); - return(1); + esdi_at_log("esdi_get_sector: past end of configured heads\n"); + return (1); } - if (esdi->sector >= sectors+1) { - esdi_at_log("esdi_get_sector: past end of configured sectors\n"); - return(1); + if (esdi->sector >= sectors + 1) { + esdi_at_log("esdi_get_sector: past end of configured sectors\n"); + return (1); } sector = esdi->sector ? esdi->sector : 1; - if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) { - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (sector - 1); + if (drive->cfg_spt == drive->real_spt && drive->cfg_hpc == drive->real_hpc) { + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors) + (sector - 1); } else { - /* - * When performing translation, the firmware seems to leave 1 - * sector per track inaccessible (spare sector) - */ + /* + * When performing translation, the firmware seems to leave 1 + * sector per track inaccessible (spare sector) + */ - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (sector - 1); + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * sectors) + (sector - 1); - s = *addr % (drive->real_spt - 1); - h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; - c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; + s = *addr % (drive->real_spt - 1); + h = (*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. */ static void next_sector(esdi_t *esdi) @@ -225,617 +214,609 @@ next_sector(esdi_t *esdi) esdi->sector++; if (esdi->sector == (drive->cfg_spt + 1)) { - esdi->sector = 1; - if (++esdi->head == drive->cfg_hpc) { - esdi->head = 0; - esdi->cylinder++; - if (drive->current_cylinder < drive->real_tracks) - drive->current_cylinder++; - } + esdi->sector = 1; + if (++esdi->head == drive->cfg_hpc) { + esdi->head = 0; + esdi->cylinder++; + if (drive->current_cylinder < drive->real_tracks) + drive->current_cylinder++; + } } } - static void 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; if (port > 0x01f0) { - esdi_write(port, val & 0xff, priv); - if (port != 0x01f7) - esdi_write(port + 1, (val >> 8) & 0xff, priv); + esdi_write(port, val & 0xff, priv); + if (port != 0x01f7) + esdi_write(port + 1, (val >> 8) & 0xff, priv); } else { - esdi->buffer[esdi->pos >> 1] = val; - esdi->pos += 2; + esdi->buffer[esdi->pos >> 1] = val; + esdi->pos += 2; - if (esdi->pos >= 512) { - esdi->pos = 0; - esdi->status = STAT_BUSY; - get_sector(esdi, &addr); - double seek_time = hdd_timing_write(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); - double xfer_time = esdi_get_xfer_time(esdi, 1); - esdi_set_callback(esdi, seek_time + xfer_time); - } + if (esdi->pos >= 512) { + esdi->pos = 0; + esdi->status = STAT_BUSY; + get_sector(esdi, &addr); + double seek_time = hdd_timing_write(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); + double xfer_time = esdi_get_xfer_time(esdi, 1); + esdi_set_callback(esdi, seek_time + xfer_time); + } } } - static void esdi_write(uint16_t port, uint8_t val, void *priv) { - esdi_t *esdi = (esdi_t *)priv; - double seek_time, xfer_time; + esdi_t *esdi = (esdi_t *) priv; + double seek_time, xfer_time; off64_t addr; esdi_at_log("WD1007 write(%04x, %02x)\n", port, val); switch (port) { - case 0x1f0: /* data */ - esdi_writew(port, val | (val << 8), priv); - return; + case 0x1f0: /* data */ + esdi_writew(port, val | (val << 8), priv); + return; - case 0x1f1: /* write precompensation */ - esdi->cylprecomp = val; - return; + case 0x1f1: /* write precompensation */ + esdi->cylprecomp = val; + return; - case 0x1f2: /* sector count */ - esdi->secount = val; - return; + case 0x1f2: /* sector count */ + esdi->secount = val; + return; - case 0x1f3: /* sector */ - esdi->sector = val; - return; + case 0x1f3: /* sector */ + esdi->sector = val; + return; - case 0x1f4: /* cylinder low */ - esdi->cylinder = (esdi->cylinder & 0xFF00) | val; - return; + case 0x1f4: /* cylinder low */ + esdi->cylinder = (esdi->cylinder & 0xFF00) | val; + return; - case 0x1f5: /* cylinder high */ - esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); - return; + case 0x1f5: /* cylinder high */ + esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); + return; - case 0x1f6: /* drive/Head */ - esdi->head = val & 0xF; - esdi->drive_sel = (val & 0x10) ? 1 : 0; - if (esdi->drives[esdi->drive_sel].present) - esdi->status = STAT_READY | STAT_DSC; - else - esdi->status = 0; - return; + case 0x1f6: /* drive/Head */ + esdi->head = val & 0xF; + esdi->drive_sel = (val & 0x10) ? 1 : 0; + if (esdi->drives[esdi->drive_sel].present) + esdi->status = STAT_READY | STAT_DSC; + else + esdi->status = 0; + return; - case 0x1f7: /* command register */ - irq_lower(esdi); - esdi->command = val; - esdi->error = 0; + case 0x1f7: /* command register */ + irq_lower(esdi); + esdi->command = val; + esdi->error = 0; - esdi_at_log("WD1007: command %02x\n", val & 0xf0); + esdi_at_log("WD1007: command %02x\n", val & 0xf0); - switch (val & 0xf0) { - case CMD_RESTORE: - esdi->command &= ~0x0f; /*mask off step rate*/ - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + switch (val & 0xf0) { + case CMD_RESTORE: + esdi->command &= ~0x0f; /*mask off step rate*/ + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 200 * HDC_TIME); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case CMD_SEEK: - esdi->command &= ~0x0f; /*mask off step rate*/ - esdi->status = STAT_BUSY; - 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); - esdi_set_callback(esdi, seek_time); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case CMD_SEEK: + esdi->command &= ~0x0f; /*mask off step rate*/ + esdi->status = STAT_BUSY; + 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); + esdi_set_callback(esdi, seek_time); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - default: - switch (val) { - case CMD_NOP: - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); - break; + default: + switch (val) { + case CMD_NOP: + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 200 * HDC_TIME); + break; - case CMD_READ: - case CMD_READ+1: - case CMD_READ+2: - case CMD_READ+3: - esdi->command &= ~0x03; - if (val & 0x02) - fatal("Read with ECC\n"); - /*FALLTHROUGH*/ + case CMD_READ: + case CMD_READ + 1: + case CMD_READ + 2: + case CMD_READ + 3: + esdi->command &= ~0x03; + if (val & 0x02) + fatal("Read with ECC\n"); + /*FALLTHROUGH*/ - case 0xa0: - esdi->status = STAT_BUSY; - get_sector(esdi, &addr); - seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); - xfer_time = esdi_get_xfer_time(esdi, 1); - esdi_set_callback(esdi, seek_time + xfer_time); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case 0xa0: + esdi->status = STAT_BUSY; + get_sector(esdi, &addr); + seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); + xfer_time = esdi_get_xfer_time(esdi, 1); + esdi_set_callback(esdi, seek_time + xfer_time); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case CMD_WRITE: - case CMD_WRITE+1: - case CMD_WRITE+2: - case CMD_WRITE+3: - esdi->command &= ~0x03; - if (val & 0x02) - fatal("Write with ECC\n"); - esdi->status = STAT_READY | STAT_DRQ | STAT_DSC; - esdi->pos = 0; - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case CMD_WRITE: + case CMD_WRITE + 1: + case CMD_WRITE + 2: + case CMD_WRITE + 3: + esdi->command &= ~0x03; + if (val & 0x02) + fatal("Write with ECC\n"); + esdi->status = STAT_READY | STAT_DRQ | STAT_DSC; + esdi->pos = 0; + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case CMD_VERIFY: - case CMD_VERIFY+1: - esdi->command &= ~0x01; - esdi->status = STAT_BUSY; - get_sector(esdi, &addr); - seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); - xfer_time = esdi_get_xfer_time(esdi, 1); - esdi_set_callback(esdi, seek_time + xfer_time); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case CMD_VERIFY: + case CMD_VERIFY + 1: + esdi->command &= ~0x01; + esdi->status = STAT_BUSY; + get_sector(esdi, &addr); + seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); + xfer_time = esdi_get_xfer_time(esdi, 1); + esdi_set_callback(esdi, seek_time + xfer_time); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case CMD_FORMAT: - esdi->status = STAT_DRQ; - esdi->pos = 0; - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case CMD_FORMAT: + esdi->status = STAT_DRQ; + esdi->pos = 0; + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 30 * HDC_TIME); - break; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 30 * HDC_TIME); + break; - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - break; + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 200 * HDC_TIME); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; - case 0xe0: /*???*/ - case CMD_READ_PARAMETERS: - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); - break; + case 0xe0: /*???*/ + case CMD_READ_PARAMETERS: + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 200 * HDC_TIME); + break; - default: - esdi_at_log("WD1007: bad command %02X\n", val); - /*FALLTHROUGH*/ - case 0xe8: /*???*/ - esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); - break; - } - } - break; + default: + esdi_at_log("WD1007: bad command %02X\n", val); + /*FALLTHROUGH*/ + case 0xe8: /*???*/ + esdi->status = STAT_BUSY; + esdi_set_callback(esdi, 200 * HDC_TIME); + break; + } + } + break; - case 0x3f6: /* Device control */ - if ((esdi->fdisk & 0x04) && !(val & 0x04)) { - esdi_set_callback(esdi, 500 * HDC_TIME); - esdi->reset = 1; - esdi->status = STAT_BUSY; - } + case 0x3f6: /* Device control */ + if ((esdi->fdisk & 0x04) && !(val & 0x04)) { + esdi_set_callback(esdi, 500 * HDC_TIME); + esdi->reset = 1; + esdi->status = STAT_BUSY; + } - if (val & 0x04) { - /* Drive held in reset. */ - esdi_set_callback(esdi, 0); - esdi->status = STAT_BUSY; - } - esdi->fdisk = val; - irq_update(esdi); - break; - } + if (val & 0x04) { + /* Drive held in reset. */ + esdi_set_callback(esdi, 0); + esdi->status = STAT_BUSY; + } + esdi->fdisk = val; + irq_update(esdi); + break; + } } - static uint16_t esdi_readw(uint16_t port, void *priv) { - esdi_t *esdi = (esdi_t *)priv; + esdi_t *esdi = (esdi_t *) priv; uint16_t temp; - off64_t addr; + off64_t addr; if (port > 0x01f0) { - temp = esdi_read(port, priv); - if (port == 0x01f7) - temp |= 0xff00; - else - temp |= (esdi_read(port + 1, priv) << 8); + temp = esdi_read(port, priv); + if (port == 0x01f7) + temp |= 0xff00; + else + temp |= (esdi_read(port + 1, priv) << 8); } else { - temp = esdi->buffer[esdi->pos >> 1]; - esdi->pos += 2; + temp = esdi->buffer[esdi->pos >> 1]; + esdi->pos += 2; - if (esdi->pos >= 512) { - esdi->pos=0; - esdi->status = STAT_READY | STAT_DSC; - if (esdi->command == CMD_READ || esdi->command == 0xa0) { - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - next_sector(esdi); - esdi->status = STAT_BUSY; - get_sector(esdi, &addr); - double seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); - double xfer_time = esdi_get_xfer_time(esdi, 1); - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - esdi_set_callback(esdi, seek_time + xfer_time); - } else - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - } - } + if (esdi->pos >= 512) { + esdi->pos = 0; + esdi->status = STAT_READY | STAT_DSC; + if (esdi->command == CMD_READ || esdi->command == 0xa0) { + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + next_sector(esdi); + esdi->status = STAT_BUSY; + get_sector(esdi, &addr); + double seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); + double xfer_time = esdi_get_xfer_time(esdi, 1); + /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ + esdi_set_callback(esdi, seek_time + xfer_time); + } else + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + } + } } - return(temp); + return (temp); } - static uint8_t esdi_read(uint16_t port, void *priv) { - esdi_t *esdi = (esdi_t *)priv; + esdi_t *esdi = (esdi_t *) priv; uint8_t temp = 0xff; switch (port) { - case 0x1f0: /* data */ - temp = esdi_readw(port, esdi) & 0xff; - break; + case 0x1f0: /* data */ + temp = esdi_readw(port, esdi) & 0xff; + break; - case 0x1f1: /* error */ - temp = esdi->error; - break; + case 0x1f1: /* error */ + temp = esdi->error; + break; - case 0x1f2: /* sector count */ - temp = esdi->secount; - break; + case 0x1f2: /* sector count */ + temp = esdi->secount; + break; - case 0x1f3: /* sector */ - temp = esdi->sector; - break; + case 0x1f3: /* sector */ + temp = esdi->sector; + break; - case 0x1f4: /* cylinder low */ - temp = (uint8_t) (esdi->cylinder&0xff); - break; + case 0x1f4: /* cylinder low */ + temp = (uint8_t) (esdi->cylinder & 0xff); + break; - case 0x1f5: /* cylinder high */ - temp = (uint8_t) (esdi->cylinder>>8); - break; + case 0x1f5: /* cylinder high */ + temp = (uint8_t) (esdi->cylinder >> 8); + break; - case 0x1f6: /* drive/Head */ - temp = (uint8_t) (esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); - break; + case 0x1f6: /* drive/Head */ + temp = (uint8_t) (esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); + break; - case 0x1f7: /* status */ - irq_lower(esdi); - temp = esdi->status; - break; + case 0x1f7: /* status */ + irq_lower(esdi); + temp = esdi->status; + break; } esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp); - return(temp); + return (temp); } - static void esdi_callback(void *priv) { - esdi_t *esdi = (esdi_t *)priv; + esdi_t *esdi = (esdi_t *) priv; drive_t *drive = &esdi->drives[esdi->drive_sel]; - off64_t addr; - double seek_time; + off64_t addr; + double seek_time; if (esdi->reset) { - esdi->status = STAT_READY|STAT_DSC; - esdi->error = 1; - esdi->secount = 1; - esdi->sector = 1; - esdi->head = 0; - esdi->cylinder = 0; - esdi->reset = 0; + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; + esdi->secount = 1; + esdi->sector = 1; + esdi->head = 0; + esdi->cylinder = 0; + esdi->reset = 0; - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - return; + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + return; } esdi_at_log("WD1007: command %02x on drive %i\n", esdi->command, esdi->drive_sel); switch (esdi->command) { - case CMD_RESTORE: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else { - drive->current_cylinder = 0; - esdi->status = STAT_READY|STAT_DSC; - } - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case CMD_RESTORE: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + drive->current_cylinder = 0; + esdi->status = STAT_READY | STAT_DSC; + } + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - case CMD_SEEK: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case CMD_SEEK: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - case CMD_READ: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - } else { - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } + case CMD_READ: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer); - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); - } - break; + hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + irq_raise(esdi); + } + break; - case CMD_WRITE: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; - } else { - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; - } + case CMD_WRITE: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } - hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer); - irq_raise(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - esdi->pos = 0; - next_sector(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - } else { - esdi->status = STAT_READY|STAT_DSC; - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - } - } - break; + hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + irq_raise(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + esdi->pos = 0; + next_sector(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + } else { + esdi->status = STAT_READY | STAT_DSC; + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + } + } + break; - case CMD_VERIFY: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; - } else { - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; - } + case CMD_VERIFY: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - next_sector(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - get_sector(esdi, &addr); - seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); - esdi_set_callback(esdi, seek_time + HDC_TIME); - } else { - esdi->pos = 0; - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - } - } - break; + hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + next_sector(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + get_sector(esdi, &addr); + seek_time = hdd_timing_read(&hdd[esdi->drives[esdi->drive_sel].hdd_num], addr, 1); + esdi_set_callback(esdi, seek_time + HDC_TIME); + } else { + esdi->pos = 0; + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + } + } + break; - case CMD_FORMAT: - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } else { - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } + case CMD_FORMAT: + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } - hdd_image_zero(drive->hdd_num, addr, esdi->secount); - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - } - break; + hdd_image_zero(drive->hdd_num, addr, esdi->secount); + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + } + break; - case CMD_DIAGNOSE: - /* This is basically controller diagnostics - it resets drive select to 0, - and resets error and status to ready, DSC, and no error detected. */ - esdi->drive_sel = 0; - drive = &esdi->drives[esdi->drive_sel]; + case CMD_DIAGNOSE: + /* This is basically controller diagnostics - it resets drive select to 0, + and resets error and status to ready, DSC, and no error detected. */ + esdi->drive_sel = 0; + drive = &esdi->drives[esdi->drive_sel]; - esdi->error = 1; /*no error detected*/ - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + esdi->error = 1; /*no error detected*/ + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - } else { - drive->cfg_spt = esdi->secount; - drive->cfg_hpc = esdi->head+1; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + } else { + drive->cfg_spt = esdi->secount; + 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) - fatal("WD1007: secount=0\n"); - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - } - break; + if (!esdi->secount) + fatal("WD1007: secount=0\n"); + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + } + break; - case CMD_NOP: - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case CMD_NOP: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - case 0xe0: - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - break; - } else { - switch (esdi->cylinder >> 8) { - case 0x31: - esdi->cylinder = drive->real_tracks; - break; + case 0xe0: + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } else { + switch (esdi->cylinder >> 8) { + case 0x31: + esdi->cylinder = drive->real_tracks; + break; - case 0x33: - esdi->cylinder = drive->real_hpc; - break; + case 0x33: + esdi->cylinder = drive->real_hpc; + break; - case 0x35: - esdi->cylinder = 0x200; - break; + case 0x35: + esdi->cylinder = 0x200; + break; - case 0x36: - esdi->cylinder = drive->real_spt; - break; + case 0x36: + esdi->cylinder = drive->real_spt; + break; - default: - esdi_at_log("WD1007: bad read config %02x\n", esdi->cylinder >> 8); - } - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - } - break; + default: + esdi_at_log("WD1007: bad read config %02x\n", esdi->cylinder >> 8); + } + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + } + break; - case 0xa0: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - } else { - memset(esdi->buffer, 0x00, 512); - memset(&esdi->buffer[3], 0xff, 512-6); - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - } - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case 0xa0: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + memset(esdi->buffer, 0x00, 512); + memset(&esdi->buffer[3], 0xff, 512 - 6); + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + } + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - case CMD_READ_PARAMETERS: - if (! drive->present) { - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - } else { - memset(esdi->buffer, 0x00, 512); - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->real_hpc; /* number of heads */ - esdi->buffer[4] = 600; /* number of unformatted bytes/sector */ - esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/track */ - esdi->buffer[6] = drive->real_spt; /* number of sectors */ - esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - esdi->buffer[8] = 0; /* minimum bytes in postamble */ - esdi->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ - esdi->buffer[27] = 'W' | ('D' << 8); - esdi->buffer[28] = '1' | ('0' << 8); - esdi->buffer[29] = '0' | ('7' << 8); - esdi->buffer[30] = 'V' | ('-' << 8); - esdi->buffer[31] = 'S' | ('E' << 8); - esdi->buffer[32] = '1'; - esdi->buffer[47] = 0; /* sectors per interrupt */ - esdi->buffer[48] = 0; /* can use double word read/write? */ - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); - } - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case CMD_READ_PARAMETERS: + if (!drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + } else { + memset(esdi->buffer, 0x00, 512); + esdi->buffer[0] = 0x44; /* general configuration */ + esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ + esdi->buffer[2] = 0; /* number of removable cylinders */ + esdi->buffer[3] = drive->real_hpc; /* number of heads */ + esdi->buffer[4] = 600; /* number of unformatted bytes/sector */ + esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/track */ + esdi->buffer[6] = drive->real_spt; /* number of sectors */ + esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ + esdi->buffer[8] = 0; /* minimum bytes in postamble */ + esdi->buffer[9] = 0; /* number of words of vendor status */ + /* controller info */ + esdi->buffer[20] = 2; /* controller type */ + esdi->buffer[21] = 1; /* sector buffer size, in sectors */ + esdi->buffer[22] = 0; /* ecc bytes appended */ + esdi->buffer[27] = 'W' | ('D' << 8); + esdi->buffer[28] = '1' | ('0' << 8); + esdi->buffer[29] = '0' | ('7' << 8); + esdi->buffer[30] = 'V' | ('-' << 8); + esdi->buffer[31] = 'S' | ('E' << 8); + esdi->buffer[32] = '1'; + esdi->buffer[47] = 0; /* sectors per interrupt */ + esdi->buffer[48] = 0; /* can use double word read/write? */ + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + irq_raise(esdi); + } + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; - default: - esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command); - /*FALLTHROUGH*/ + default: + esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command); + /*FALLTHROUGH*/ - case 0xe8: - esdi->status = STAT_READY|STAT_ERR|STAT_DSC; - esdi->error = ERR_ABRT; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - break; + case 0xe8: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; } } - static void loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn) { drive_t *drive = &esdi->drives[hdd_num]; - if (! hdd_image_load(d)) { - esdi_at_log("WD1007: drive %d not present!\n", d); - drive->present = 0; - return; + if (!hdd_image_load(d)) { + esdi_at_log("WD1007: drive %d not present!\n", d); + drive->present = 0; + return; } hdd_preset_apply(d); drive->cfg_spt = drive->real_spt = hdd[d].spt; drive->cfg_hpc = drive->real_hpc = hdd[d].hpc; - drive->real_tracks = hdd[d].tracks; - drive->hdd_num = d; - drive->present = 1; + drive->real_tracks = hdd[d].tracks; + drive->hdd_num = d; + drive->present = 1; } - static void 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; if (addr >= 0x1f00 && addr < 0x2000) - rom->rom[addr] = val; + rom->rom[addr] = val; } - static void * wd1007vse1_init(const device_t *info) { @@ -845,52 +826,52 @@ wd1007vse1_init(const device_t *info) memset(esdi, 0x00, sizeof(esdi_t)); c = 0; - for (d=0; d= ESDI_NUM) break; - } + if (++c >= ESDI_NUM) + break; + } } - esdi->status = STAT_READY|STAT_DSC; - esdi->error = 1; + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; rom_init(&esdi->bios_rom, - BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_set_handler(&esdi->bios_rom.mapping, - rom_read, rom_readw, rom_readl, - esdi_rom_write, NULL, NULL); + rom_read, rom_readw, rom_readl, + esdi_rom_write, NULL, NULL); io_sethandler(0x01f0, 1, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, esdi); + esdi_read, esdi_readw, NULL, + esdi_write, esdi_writew, NULL, esdi); io_sethandler(0x01f1, 7, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, esdi); + esdi_read, esdi_readw, NULL, + esdi_write, esdi_writew, NULL, esdi); io_sethandler(0x03f6, 1, NULL, NULL, NULL, - esdi_write, NULL, NULL, esdi); + esdi_write, NULL, NULL, esdi); timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); - return(esdi); + return (esdi); } - static void wd1007vse1_close(void *priv) { - esdi_t *esdi = (esdi_t *)priv; + esdi_t *esdi = (esdi_t *) priv; drive_t *drive; - int d; + int d; - for (d=0; d<2; d++) { - drive = &esdi->drives[d]; + for (d = 0; d < 2; d++) { + drive = &esdi->drives[d]; - hdd_image_close(drive->hdd_num); + hdd_image_close(drive->hdd_num); } free(esdi); @@ -898,23 +879,22 @@ wd1007vse1_close(void *priv) ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } - static int wd1007vse1_available(void) { - return(rom_present(BIOS_FILE)); + return (rom_present(BIOS_FILE)); } const device_t esdi_at_wd1007vse1_device = { - .name = "Western Digital WD1007V-SE1 (ESDI)", + .name = "Western Digital WD1007V-SE1 (ESDI)", .internal_name = "esdi_at", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = wd1007vse1_init, - .close = wd1007vse1_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = wd1007vse1_init, + .close = wd1007vse1_close, + .reset = NULL, { .available = wd1007vse1_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 6f6b77723..e5e96e364 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -243,7 +243,7 @@ static double esdi_mca_get_xfer_time(esdi_t *esdi, int size) { /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - return (3125.0 / 8.0) * (double)size; + return (3125.0 / 8.0) * (double) size; } static void @@ -352,7 +352,7 @@ esdi_callback(void *priv) esdi_t *dev = (esdi_t *) priv; drive_t *drive; int val; - double cmd_time = 0.0; + double cmd_time = 0.0; esdi_mca_set_callback(dev, 0); @@ -525,7 +525,7 @@ esdi_callback(void *priv) switch (dev->cmd_state) { case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; dev->sector_count = dev->cmd_data[1]; if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index b49e2e926..7bf834a37 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -46,179 +46,173 @@ #include <86box/zip.h> #include <86box/version.h> - /* Bits of 'atastat' */ -#define ERR_STAT 0x01 /* Error */ -#define IDX_STAT 0x02 /* Index */ -#define CORR_STAT 0x04 /* Corrected data */ -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 /* Drive seek complete */ -#define SERVICE_STAT 0x10 /* ATAPI service */ -#define DWF_STAT 0x20 /* Drive write fault */ -#define DRDY_STAT 0x40 /* Ready */ -#define BSY_STAT 0x80 /* Busy */ +#define ERR_STAT 0x01 /* Error */ +#define IDX_STAT 0x02 /* Index */ +#define CORR_STAT 0x04 /* Corrected data */ +#define DRQ_STAT 0x08 /* Data request */ +#define DSC_STAT 0x10 /* Drive seek complete */ +#define SERVICE_STAT 0x10 /* ATAPI service */ +#define DWF_STAT 0x20 /* Drive write fault */ +#define DRDY_STAT 0x40 /* Ready */ +#define BSY_STAT 0x80 /* Busy */ /* Bits of 'error' */ -#define AMNF_ERR 0x01 /* Address mark not found */ -#define TK0NF_ERR 0x02 /* Track 0 not found */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ -#define IDNF_ERR 0x10 /* Sector ID not found */ -#define MC_ERR 0x20 /* Media change */ -#define UNC_ERR 0x40 /* Uncorrectable data error */ -#define BBK_ERR 0x80 /* Bad block mark detected */ +#define AMNF_ERR 0x01 /* Address mark not found */ +#define TK0NF_ERR 0x02 /* Track 0 not found */ +#define ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* Media change request */ +#define IDNF_ERR 0x10 /* Sector ID not found */ +#define MC_ERR 0x20 /* Media change */ +#define UNC_ERR 0x40 /* Uncorrectable data error */ +#define BBK_ERR 0x80 /* Bad block mark detected */ /* ATA Commands */ -#define WIN_NOP 0x00 -#define WIN_SRST 0x08 /* ATAPI Device Reset */ -#define WIN_RECAL 0x10 -#define WIN_READ 0x20 /* 28-Bit Read */ -#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry */ -#define WIN_WRITE 0x30 /* 28-Bit Write */ -#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write - no retry */ -#define WIN_VERIFY 0x40 /* 28-Bit Verify */ -#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ -#define WIN_FORMAT 0x50 -#define WIN_SEEK 0x70 -#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ -#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 +#define WIN_NOP 0x00 +#define WIN_SRST 0x08 /* ATAPI Device Reset */ +#define WIN_RECAL 0x10 +#define WIN_READ 0x20 /* 28-Bit Read */ +#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry */ +#define WIN_WRITE 0x30 /* 28-Bit Write */ +#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write - no retry */ +#define WIN_VERIFY 0x40 /* 28-Bit Verify */ +#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ +#define WIN_FORMAT 0x50 +#define WIN_SEEK 0x70 +#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ +#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ +#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ +#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ +#define WIN_READ_MULTIPLE 0xC4 +#define WIN_WRITE_MULTIPLE 0xC5 +#define WIN_SET_MULTIPLE_MODE 0xC6 +#define WIN_READ_DMA 0xC8 +#define WIN_READ_DMA_ALT 0xC9 +#define WIN_WRITE_DMA 0xCA +#define WIN_WRITE_DMA_ALT 0xCB +#define WIN_STANDBYNOW1 0xE0 +#define WIN_IDLENOW1 0xE1 +#define WIN_SETIDLE1 0xE3 +#define WIN_CHECKPOWERMODE1 0xE5 +#define WIN_SLEEP1 0xE6 +#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xEF +#define WIN_READ_NATIVE_MAX 0xF8 -#define FEATURE_SET_TRANSFER_MODE 0x03 -#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d -#define FEATURE_ENABLE_IRQ_SERVICE 0x5e -#define FEATURE_DISABLE_REVERT 0x66 -#define FEATURE_ENABLE_REVERT 0xcc -#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd -#define FEATURE_DISABLE_IRQ_SERVICE 0xde - -#define IDE_TIME 10.0 +#define FEATURE_SET_TRANSFER_MODE 0x03 +#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d +#define FEATURE_ENABLE_IRQ_SERVICE 0x5e +#define FEATURE_DISABLE_REVERT 0x66 +#define FEATURE_ENABLE_REVERT 0xcc +#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd +#define FEATURE_DISABLE_IRQ_SERVICE 0xde +#define IDE_TIME 10.0 typedef struct { - int bit32, cur_dev, - irq, inited, - diag, force_ata3; - uint16_t base_main, side_main; - pc_timer_t timer; - ide_t *ide[2]; + int bit32, cur_dev, + irq, inited, + diag, force_ata3; + uint16_t base_main, side_main; + pc_timer_t timer; + ide_t *ide[2]; } ide_board_t; typedef struct { - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); - void (*set_irq)(int channel, void *priv); - void *priv; + int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); + void (*set_irq)(int channel, void *priv); + void *priv; } ide_bm_t; -static ide_board_t *ide_boards[4] = { NULL, NULL, NULL, NULL }; -static ide_bm_t *ide_bm[4] = { NULL, NULL, NULL, NULL }; +static ide_board_t *ide_boards[4] = { NULL, NULL, NULL, NULL }; +static ide_bm_t *ide_bm[4] = { NULL, NULL, NULL, NULL }; static uint8_t ide_ter_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ + 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ + 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x22, 0x00, 0x04, /* IRQ 10 */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x30, /* start dependent functions, acceptable */ + 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x30, /* start dependent functions, acceptable */ + 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x38, /* end dependent functions */ 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ }; static uint8_t ide_qua_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ + 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ + 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ + 0x31, 0x00, /* start dependent functions, preferred */ + 0x22, 0x00, 0x08, /* IRQ 11 */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x30, /* start dependent functions, acceptable */ + 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x30, /* start dependent functions, acceptable */ + 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x38, /* end dependent functions */ 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ }; -ide_t *ide_drives[IDE_NUM]; -int ide_ter_enabled = 0, ide_qua_enabled = 0; - -static void ide_atapi_callback(ide_t *ide); -static void ide_callback(void *priv); +ide_t *ide_drives[IDE_NUM]; +int ide_ter_enabled = 0, ide_qua_enabled = 0; +static void ide_atapi_callback(ide_t *ide); +static void ide_callback(void *priv); #ifdef ENABLE_IDE_LOG int ide_do_log = ENABLE_IDE_LOG; - static void ide_log(const char *fmt, ...) { va_list ap; if (ide_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ide_log(fmt, ...) +# define ide_log(fmt, ...) #endif - uint8_t -getstat(ide_t *ide) { +getstat(ide_t *ide) +{ return ide->atastat; } - ide_t * ide_get_drive(int ch) { if (ch >= 8) - return NULL; + return NULL; return ide_drives[ch]; } - double ide_get_xfer_time(ide_t *ide, int size) { @@ -226,81 +220,80 @@ ide_get_xfer_time(ide_t *ide, int size) /* 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. */ - switch(ide->mdma_mode & 0x300) { - case 0x000: /* PIO */ - switch(ide->mdma_mode & 0xff) { - case 0x01: - period = (10.0 / 3.0); - break; - case 0x02: - period = (20.0 / 3.83); - break; - case 0x04: - period = (25.0 / 3.0); - break; - case 0x08: - period = (100.0 / 9.0); - break; - case 0x10: - period = (50.0 / 3.0); - break; - } - break; - case 0x100: /* Single Word DMA */ - switch(ide->mdma_mode & 0xff) { - case 0x01: - period = (25.0 / 12.0); - break; - case 0x02: - period = (25.0 / 6.0); - break; - case 0x04: - period = (25.0 / 3.0); - break; - } - break; - case 0x200: /* Multiword DMA */ - switch(ide->mdma_mode & 0xff) { - case 0x01: - period = (25.0 / 6.0); - break; - case 0x02: - period = (40.0 / 3.0); - break; - case 0x04: - period = (50.0 / 3.0); - break; - } - break; - case 0x300: /* Ultra DMA */ - switch(ide->mdma_mode & 0xff) { - case 0x01: - period = (50.0 / 3.0); - break; - case 0x02: - period = 25.0; - break; - case 0x04: - period = (100.0 / 3.0); - break; - case 0x08: - period = (400.0 / 9.0); - break; - case 0x10: - period = (200.0 / 3.0); - break; - case 0x20: - period = 100.0; - break; - } - break; + switch (ide->mdma_mode & 0x300) { + case 0x000: /* PIO */ + switch (ide->mdma_mode & 0xff) { + case 0x01: + period = (10.0 / 3.0); + break; + case 0x02: + period = (20.0 / 3.83); + break; + case 0x04: + period = (25.0 / 3.0); + break; + case 0x08: + period = (100.0 / 9.0); + break; + case 0x10: + period = (50.0 / 3.0); + break; + } + break; + case 0x100: /* Single Word DMA */ + switch (ide->mdma_mode & 0xff) { + case 0x01: + period = (25.0 / 12.0); + break; + case 0x02: + period = (25.0 / 6.0); + break; + case 0x04: + period = (25.0 / 3.0); + break; + } + break; + case 0x200: /* Multiword DMA */ + switch (ide->mdma_mode & 0xff) { + case 0x01: + period = (25.0 / 6.0); + break; + case 0x02: + period = (40.0 / 3.0); + break; + case 0x04: + period = (50.0 / 3.0); + break; + } + break; + case 0x300: /* Ultra DMA */ + switch (ide->mdma_mode & 0xff) { + case 0x01: + period = (50.0 / 3.0); + break; + case 0x02: + period = 25.0; + break; + case 0x04: + period = (100.0 / 3.0); + break; + case 0x08: + period = (400.0 / 9.0); + break; + case 0x10: + period = (200.0 / 3.0); + break; + case 0x20: + period = 100.0; + break; + } + break; } - period = (1.0 / period); /* get us for 1 byte */ - return period * ((double) size); /* multiply by bytes to get period for the entire transfer */ + period = (1.0 / period); /* get us for 1 byte */ + return period * ((double) size); /* multiply by bytes to get period for the entire transfer */ } - double ide_atapi_get_period(uint8_t channel) { @@ -309,84 +302,80 @@ ide_atapi_get_period(uint8_t channel) ide_log("ide_atapi_get_period(%i)\n", channel); if (!ide) { - ide_log("Get period failed\n"); - return -1.0; + ide_log("Get period failed\n"); + return -1.0; } return ide_get_xfer_time(ide, 1); } - void ide_irq_raise(ide_t *ide) { if (!ide_boards[ide->board]) - return; + return; /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ ide_log("IDE %i: IRQ raise\n", ide->board); if (!(ide->fdisk & 2) && ide->selected) { - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picint(1 << ide_boards[ide->board]->irq); + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) + ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + else if (ide_boards[ide->board]->irq != -1) + picint(1 << ide_boards[ide->board]->irq); } ide->irqstat = 1; ide->service = 1; } - void ide_irq_lower(ide_t *ide) { if (!ide_boards[ide->board]) - return; + return; /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ // ide_log("IDE %i: IRQ lower\n", ide->board); if (ide->irqstat && ide->selected) { - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picintc(1 << ide_boards[ide->board]->irq); + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + else if (ide_boards[ide->board]->irq != -1) + picintc(1 << ide_boards[ide->board]->irq); } ide->irqstat = 0; } - static void ide_irq_update(ide_t *ide) { if (!ide_boards[ide->board]) - return; + return; /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ if (!(ide->fdisk & 2) && ide->irqstat) { - ide_log("IDE %i: IRQ update raise\n", ide->board); - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - } else if (ide_boards[ide->board]->irq != -1) { - picintc(1 << ide_boards[ide->board]->irq); - picint(1 << ide_boards[ide->board]->irq); - } + ide_log("IDE %i: IRQ update raise\n", ide->board); + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + } else if (ide_boards[ide->board]->irq != -1) { + picintc(1 << ide_boards[ide->board]->irq); + picint(1 << ide_boards[ide->board]->irq); + } } else if ((ide->fdisk & 2) || !ide->irqstat) { - ide_log("IDE %i: IRQ update lower\n", ide->board); - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picintc(1 << ide_boards[ide->board]->irq); + ide_log("IDE %i: IRQ update lower\n", ide->board); + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + else if (ide_boards[ide->board]->irq != -1) + picintc(1 << ide_boards[ide->board]->irq); } } - /** * Copy a string into a buffer, padding with spaces, and placing characters as * if they were packed into 16-bit values, stored little-endian. @@ -402,15 +391,14 @@ ide_padstr(char *str, const char *src, int len) int i, v; for (i = 0; i < len; i++) { - if (*src != '\0') - v = *src++; - else - v = ' '; - str[i ^ 1] = v; + if (*src != '\0') + v = *src++; + else + v = ' '; + str[i ^ 1] = v; } } - /** * Copy a string into a buffer, padding with spaces. Does not add string * terminator. @@ -420,83 +408,82 @@ ide_padstr(char *str, const char *src, int len) * this length will be padded with spaces. * @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; for (i = 0; i < buf_size; i++) { - if (*src != '\0') - buf[i] = *src++; - else - buf[i] = ' '; + if (*src != '\0') + buf[i] = *src++; + else + buf[i] = ' '; } } - static int ide_get_max(ide_t *ide, int type) { 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) { - case TYPE_PIO: /* PIO */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 4; + switch (type) { + case TYPE_PIO: /* PIO */ + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 4; - return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ - case TYPE_SDMA: /* SDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 2; + return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ + case TYPE_SDMA: /* SDMA */ + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 2; - return -1; - case TYPE_MDMA: /* MDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 2; + return -1; + case TYPE_MDMA: /* MDMA */ + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 2; - return -1; - case TYPE_UDMA: /* UDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 5; + return -1; + case TYPE_UDMA: /* UDMA */ + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 5; - return -1; - default: - fatal("Unknown transfer type: %i\n", type); - return -1; + return -1; + default: + fatal("Unknown transfer type: %i\n", type); + return -1; } } - static int ide_get_timings(ide_t *ide, int type) { 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) { - case TIMINGS_DMA: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; + switch (type) { + case TIMINGS_DMA: + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 120; - return 0; - case TIMINGS_PIO: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; + return 0; + case TIMINGS_PIO: + if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) + return 120; - return 0; - case TIMINGS_PIO_FC: - return 0; - default: - fatal("Unknown transfer type: %i\n", type); - return 0; + return 0; + case TIMINGS_PIO_FC: + return 0; + default: + fatal("Unknown transfer type: %i\n", type); + return 0; } } - /** * 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 }; @@ -509,88 +496,87 @@ static void ide_hd_identify(ide_t *ide) d_spt = ide->spt; if (ide->hpc <= 16) { - /* HPC <= 16, report as needed. */ - d_tracks = ide->tracks; - d_hpc = ide->hpc; + /* HPC <= 16, report as needed. */ + d_tracks = ide->tracks; + d_hpc = ide->hpc; } else { - /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; + /* HPC > 16, convert to 16 HPC. */ + d_hpc = 16; + d_tracks = (ide->tracks * ide->hpc) / 16; } /* Specify default CHS translation */ if (full_size <= 16514064) { - ide->buffer[1] = d_tracks; /* Tracks in default CHS translation. */ - ide->buffer[3] = d_hpc; /* Heads in default CHS translation. */ - ide->buffer[6] = d_spt; /* Heads in default CHS translation. */ + ide->buffer[1] = d_tracks; /* Tracks in default CHS translation. */ + ide->buffer[3] = d_hpc; /* Heads in default CHS translation. */ + ide->buffer[6] = d_spt; /* Heads in default CHS translation. */ } else { - ide->buffer[1] = 16383; /* Tracks in default CHS translation. */ - ide->buffer[3] = 16; /* Heads in default CHS translation. */ - ide->buffer[6] = 63; /* Heads in default CHS translation. */ + ide->buffer[1] = 16383; /* Tracks in default CHS translation. */ + ide->buffer[3] = 16; /* Heads in default CHS translation. */ + ide->buffer[6] = 63; /* Heads in default CHS translation. */ } ide_log("Default CHS translation: %i, %i, %i\n", ide->buffer[1], ide->buffer[3], ide->buffer[6]); - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[0] = (1 << 6); /*Fixed drive*/ - ide->buffer[20] = 3; /*Buffer type*/ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ + ide->buffer[0] = (1 << 6); /*Fixed drive*/ + ide->buffer[20] = 3; /*Buffer type*/ ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; /*Buffer size*/ - ide->buffer[50] = 0x4000; /* Capabilities */ + ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if ((ide->tracks >= 1024) || (ide->hpc > 16) || (ide->spt > 63)) { - ide->buffer[49] = (1 << 9); - ide_log("LBA supported\n"); + ide->buffer[49] = (1 << 9); + ide_log("LBA supported\n"); - ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (full_size >> 16) & 0x0FFF; - ide_log("Full size: %" PRIu64 "\n", full_size); + ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = (full_size >> 16) & 0x0FFF; + ide_log("Full size: %" PRIu64 "\n", full_size); /* - Bit 0 = The fields reported in words 54-58 are valid; - Bit 1 = The fields reported in words 64-70 are valid; - Bit 2 = The fields reported in word 88 are valid. */ - ide->buffer[53] = 1; + Bit 0 = The fields reported in words 54-58 are valid; + Bit 1 = The fields reported in words 64-70 are valid; + Bit 2 = The fields reported in word 88 are valid. */ + ide->buffer[53] = 1; - if (ide->cfg_spt != 0) { - ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; - ide->buffer[55] = ide->cfg_hpc; - ide->buffer[56] = ide->cfg_spt; - } else { - if (full_size <= 16514064) { - ide->buffer[54] = d_tracks; - ide->buffer[55] = d_hpc; - ide->buffer[56] = d_spt; - } else { - ide->buffer[54] = 16383; - ide->buffer[55] = 16; - ide->buffer[56] = 63; - } - } + if (ide->cfg_spt != 0) { + ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; + ide->buffer[55] = ide->cfg_hpc; + ide->buffer[56] = ide->cfg_spt; + } else { + if (full_size <= 16514064) { + ide->buffer[54] = d_tracks; + ide->buffer[55] = d_hpc; + ide->buffer[56] = d_spt; + } else { + ide->buffer[54] = 16383; + ide->buffer[55] = 16; + ide->buffer[56] = 63; + } + } - full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * ((uint64_t) ide->buffer[56]); + full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * ((uint64_t) ide->buffer[56]); - ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[58] = (full_size >> 16) & 0x0FFF; + ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[58] = (full_size >> 16) & 0x0FFF; - ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); + ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); } - ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/ + ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) { - ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ - ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ + ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ + ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ } else { - ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ + ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ } } - static void ide_identify(ide_t *ide) { - int d, i, max_pio, max_sdma, max_mdma, max_udma; + int d, i, max_pio, max_sdma, max_mdma, max_udma; ide_t *ide_other = ide_drives[ide->channel ^ 1]; ide_log("IDE IDENTIFY or IDENTIFY PACKET DEVICE on board %i (channel %i)\n", ide->board, ide->channel); @@ -598,90 +584,89 @@ ide_identify(ide_t *ide) memset(ide->buffer, 0, 512); if (ide->type == IDE_ATAPI) - ide->identify(ide, !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)); + ide->identify(ide, !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)); else if (ide->type != IDE_NONE) - ide_hd_identify(ide); + ide_hd_identify(ide); else { - fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); - return; + fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); + return; } - max_pio = ide_get_max(ide, TYPE_PIO); + max_pio = ide_get_max(ide, TYPE_PIO); max_sdma = ide_get_max(ide, TYPE_SDMA); max_mdma = ide_get_max(ide, TYPE_MDMA); max_udma = ide_get_max(ide, TYPE_UDMA); ide_log("IDE %i: max_pio = %i, max_sdma = %i, max_mdma = %i, max_udma = %i\n", - ide->channel, max_pio, max_sdma, max_mdma, max_udma); + ide->channel, max_pio, max_sdma, max_mdma, max_udma); if (ide_boards[ide->board]->bit32) - ide->buffer[48] |= 1; /*Dword transfers supported*/ + ide->buffer[48] |= 1; /*Dword transfers supported*/ ide->buffer[51] = ide_get_timings(ide, TIMINGS_PIO); ide->buffer[53] &= 0xfff9; ide->buffer[52] = ide->buffer[62] = ide->buffer[63] = ide->buffer[64] = 0x0000; ide->buffer[65] = ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); ide->buffer[67] = ide->buffer[68] = 0x0000; - ide->buffer[88] = 0x0000; + ide->buffer[88] = 0x0000; if (max_pio >= 3) { - ide->buffer[53] |= 0x0002; - ide->buffer[67] = ide_get_timings(ide, TIMINGS_PIO); - ide->buffer[68] = ide_get_timings(ide, TIMINGS_PIO_FC); - for (i = 3; i <= max_pio; i++) - ide->buffer[64] |= (1 << (i - 3)); + ide->buffer[53] |= 0x0002; + ide->buffer[67] = ide_get_timings(ide, TIMINGS_PIO); + ide->buffer[68] = ide_get_timings(ide, TIMINGS_PIO_FC); + for (i = 3; i <= max_pio; i++) + ide->buffer[64] |= (1 << (i - 3)); } if (max_sdma != -1) { - for (i = 0; i <= max_sdma; i++) - ide->buffer[62] |= (1 << i); + for (i = 0; i <= max_sdma; i++) + ide->buffer[62] |= (1 << i); } if (max_mdma != -1) { - for (i = 0; i <= max_mdma; i++) - ide->buffer[63] |= (1 << i); + for (i = 0; i <= max_mdma; i++) + ide->buffer[63] |= (1 << i); } if (max_udma != -1) { - ide->buffer[53] |= 0x0004; - for (i = 0; i <= max_udma; i++) - ide->buffer[88] |= (1 << i); - if (max_udma >= 4) - ide->buffer[93] = 0x6000; /* Drive reports 80-conductor cable */ + ide->buffer[53] |= 0x0004; + for (i = 0; i <= max_udma; i++) + ide->buffer[88] |= (1 << i); + if (max_udma >= 4) + ide->buffer[93] = 0x6000; /* Drive reports 80-conductor cable */ - if (ide->channel & 1) - ide->buffer[93] |= 0x0b00; - else { - ide->buffer[93] |= 0x000b; - /* PDIAG- is assered by device 1, so the bit should be 1 if there's a device 1, - so it should be |= 0x001b if device 1 is present. */ - if (ide_other != NULL) - ide->buffer[93] |= 0x0010; - } + if (ide->channel & 1) + ide->buffer[93] |= 0x0b00; + else { + ide->buffer[93] |= 0x000b; + /* PDIAG- is assered by device 1, so the bit should be 1 if there's a device 1, + so it should be |= 0x001b if device 1 is present. */ + if (ide_other != NULL) + ide->buffer[93] |= 0x0010; + } } if ((max_sdma != -1) || (max_mdma != -1) || (max_udma != -1)) { - ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = ide_get_timings(ide, TIMINGS_DMA); + ide->buffer[49] |= 0x100; /* DMA supported */ + ide->buffer[52] = ide_get_timings(ide, TIMINGS_DMA); } if ((max_mdma != -1) || (max_udma != -1)) { - ide->buffer[65] = ide_get_timings(ide, TIMINGS_DMA); - ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); + ide->buffer[65] = ide_get_timings(ide, TIMINGS_DMA); + ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); } if (ide->mdma_mode != -1) { - d = (ide->mdma_mode & 0xff); - d <<= 8; - if ((ide->mdma_mode & 0x300) == 0x000) { - if ((ide->mdma_mode & 0xff) >= 3) - ide->buffer[64] |= d; - } else if ((ide->mdma_mode & 0x300) == 0x100) - ide->buffer[62] |= d; - else if ((ide->mdma_mode & 0x300) == 0x200) - ide->buffer[63] |= d; - else if ((ide->mdma_mode & 0x300) == 0x300) - ide->buffer[88] |= d; - ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); + d = (ide->mdma_mode & 0xff); + d <<= 8; + if ((ide->mdma_mode & 0x300) == 0x000) { + if ((ide->mdma_mode & 0xff) >= 3) + ide->buffer[64] |= d; + } else if ((ide->mdma_mode & 0x300) == 0x100) + ide->buffer[62] |= d; + else if ((ide->mdma_mode & 0x300) == 0x200) + ide->buffer[63] |= d; + else if ((ide->mdma_mode & 0x300) == 0x300) + ide->buffer[88] |= d; + ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } } - /* * Return the sector offset for the current register values */ @@ -691,19 +676,17 @@ ide_get_sector(ide_t *ide) uint32_t heads, sectors; if (ide->lba) - return (off64_t)ide->lba_addr; + return (off64_t) ide->lba_addr; else { - heads = ide->cfg_hpc; - sectors = ide->cfg_spt; + heads = ide->cfg_hpc; + 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) * - sectors) + (sector - 1); + return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (sector - 1); } } - /** * Move to the next sector using CHS addressing */ @@ -711,227 +694,218 @@ static void ide_next_sector(ide_t *ide) { if (ide->lba) - ide->lba_addr++; + ide->lba_addr++; else { - ide->sector++; - if (ide->sector == (ide->cfg_spt + 1)) { - ide->sector = 1; - ide->head++; - if (ide->head == ide->cfg_hpc) { - ide->head = 0; - ide->cylinder++; - } - } + ide->sector++; + if (ide->sector == (ide->cfg_spt + 1)) { + ide->sector = 1; + ide->head++; + if (ide->head == ide->cfg_hpc) { + ide->head = 0; + ide->cylinder++; + } + } } } - static void loadhd(ide_t *ide, int d, const char *fn) { - if (! hdd_image_load(d)) { - ide->type = IDE_NONE; - return; + if (!hdd_image_load(d)) { + ide->type = IDE_NONE; + return; } hdd_preset_apply(d); ide->spt = ide->cfg_spt = hdd[d].spt; ide->hpc = ide->cfg_hpc = hdd[d].hpc; - ide->tracks = hdd[d].tracks; - ide->type = IDE_HDD; - ide->hdd_num = d; + ide->tracks = hdd[d].tracks; + ide->type = IDE_HDD; + ide->hdd_num = d; } - void ide_set_signature(ide_t *ide) { - ide->sector=1; - ide->head=0; + ide->sector = 1; + ide->head = 0; if (ide->type == IDE_ATAPI) { - ide->sc->phase = 1; - ide->sc->request_length = 0xEB14; - ide->secount = ide->sc->phase; - ide->cylinder = ide->sc->request_length; + ide->sc->phase = 1; + ide->sc->request_length = 0xEB14; + ide->secount = ide->sc->phase; + ide->cylinder = ide->sc->request_length; } else { - ide->secount = 1; - ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF); - if (ide->type == IDE_HDD) - ide->drive = 0; + ide->secount = 1; + ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF); + if (ide->type == IDE_HDD) + ide->drive = 0; } } - static int ide_set_features(ide_t *ide) { uint8_t features, features_data; - int mode, submode, max; + int mode, submode, max; - features = ide->cylprecomp; + features = ide->cylprecomp; features_data = ide->secount; ide_log("Features code %02X\n", features); ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data); - switch(features) { - case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */ - ide_log("Transfer mode %02X\n", features_data >> 3); + switch (features) { + case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */ + ide_log("Transfer mode %02X\n", features_data >> 3); - mode = (features_data >> 3); - submode = features_data & 7; + mode = (features_data >> 3); + submode = features_data & 7; - switch (mode) { - case 0x00: /* PIO default */ - if (submode != 0) - return 0; - max = ide_get_max(ide, TYPE_PIO); - ide->mdma_mode = (1 << max); - ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; + switch (mode) { + case 0x00: /* PIO default */ + if (submode != 0) + return 0; + max = ide_get_max(ide, TYPE_PIO); + ide->mdma_mode = (1 << max); + ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + break; - case 0x01: /* PIO mode */ - max = ide_get_max(ide, TYPE_PIO); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode); - ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; + case 0x01: /* PIO mode */ + max = ide_get_max(ide, TYPE_PIO); + if (submode > max) + return 0; + ide->mdma_mode = (1 << submode); + ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + break; - case 0x02: /* Singleword DMA mode */ - max = ide_get_max(ide, TYPE_SDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x100; - ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; + case 0x02: /* Singleword DMA mode */ + max = ide_get_max(ide, TYPE_SDMA); + if (submode > max) + return 0; + ide->mdma_mode = (1 << submode) | 0x100; + ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + break; - case 0x04: /* Multiword DMA mode */ - max = ide_get_max(ide, TYPE_MDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x200; - ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; + case 0x04: /* Multiword DMA mode */ + max = ide_get_max(ide, TYPE_MDMA); + if (submode > max) + return 0; + ide->mdma_mode = (1 << submode) | 0x200; + ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + break; - case 0x08: /* Ultra DMA mode */ - max = ide_get_max(ide, TYPE_UDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x300; - ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; + case 0x08: /* Ultra DMA mode */ + max = ide_get_max(ide, TYPE_UDMA); + if (submode > max) + return 0; + ide->mdma_mode = (1 << submode) | 0x300; + ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + break; - default: - return 0; - } - break; + default: + return 0; + } + break; - case FEATURE_ENABLE_IRQ_OVERLAPPED: - case FEATURE_ENABLE_IRQ_SERVICE: - case FEATURE_DISABLE_IRQ_OVERLAPPED: - case FEATURE_DISABLE_IRQ_SERVICE: - max = ide_get_max(ide, TYPE_MDMA); - if (max == -1) - return 0; - else - return 1; + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + max = ide_get_max(ide, TYPE_MDMA); + if (max == -1) + return 0; + else + return 1; - case FEATURE_DISABLE_REVERT: /* Disable reverting to power on defaults. */ - case FEATURE_ENABLE_REVERT: /* Enable reverting to power on defaults. */ - return 1; + case FEATURE_DISABLE_REVERT: /* Disable reverting to power on defaults. */ + case FEATURE_ENABLE_REVERT: /* Enable reverting to power on defaults. */ + return 1; - default: - return 0; + default: + return 0; } return 1; } - void ide_set_sector(ide_t *ide, int64_t sector_num) { unsigned int cyl, r; if (ide->lba) { - ide->head = (sector_num >> 24); - ide->cylinder = (sector_num >> 8); - ide->sector = (sector_num); + ide->head = (sector_num >> 24); + ide->cylinder = (sector_num >> 8); + ide->sector = (sector_num); } else { - cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - ide->cylinder = cyl; - ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); - ide->sector = (r % hdd[ide->hdd_num].spt) + 1; + cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + ide->cylinder = cyl; + ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); + ide->sector = (r % hdd[ide->hdd_num].spt) + 1; } } - static void ide_zero(int d) { ide_t *dev; if (ide_drives[d] == NULL) - ide_drives[d] = (ide_t *) malloc(sizeof(ide_t)); + ide_drives[d] = (ide_t *) malloc(sizeof(ide_t)); memset(ide_drives[d], 0, sizeof(ide_t)); - dev = ide_drives[d]; - dev->channel = d; - dev->type = IDE_NONE; - dev->hdd_num = -1; - dev->atastat = DRDY_STAT | DSC_STAT; - dev->service = 0; - dev->board = d >> 1; - dev->selected = !(d & 1); + dev = ide_drives[d]; + dev->channel = d; + dev->type = IDE_NONE; + dev->hdd_num = -1; + dev->atastat = DRDY_STAT | DSC_STAT; + dev->service = 0; + dev->board = d >> 1; + dev->selected = !(d & 1); ide_boards[dev->board]->ide[d & 1] = dev; timer_add(&dev->timer, ide_callback, dev, 0); } - void ide_allocate_buffer(ide_t *dev) { if (dev->buffer == NULL) - dev->buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); + dev->buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); memset(dev->buffer, 0, 65536 * sizeof(uint16_t)); } - void ide_atapi_attach(ide_t *ide) { if (ide->type != IDE_NONE) - return; + return; ide->type = IDE_ATAPI; ide_allocate_buffer(ide); ide_set_signature(ide); ide->mdma_mode = (1 << ide->get_max(ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board], TYPE_PIO)); - ide->error = 1; + ide->error = 1; ide->cfg_spt = ide->cfg_hpc = 0; } - void ide_set_callback(ide_t *ide, double callback) { if (!ide) { - ide_log("ide_set_callback(NULL): Set callback failed\n"); - return; + ide_log("ide_set_callback(NULL): Set callback failed\n"); + return; } ide_log("ide_set_callback(%i)\n", ide->channel); if (callback == 0.0) - timer_stop(&ide->timer); + timer_stop(&ide->timer); else - timer_on_auto(&ide->timer, callback); + timer_on_auto(&ide->timer, callback); } - void ide_set_board_callback(uint8_t board, double callback) { @@ -940,120 +914,117 @@ ide_set_board_callback(uint8_t board, double callback) ide_log("ide_set_board_callback(%i)\n", board); if (!dev) { - ide_log("Set board callback failed\n"); - return; + ide_log("Set board callback failed\n"); + return; } if (callback == 0.0) - timer_stop(&dev->timer); + timer_stop(&dev->timer); else - timer_on_auto(&dev->timer, callback); + timer_on_auto(&dev->timer, callback); } - static void ide_atapi_command_bus(ide_t *ide) { - ide->sc->status = BUSY_STAT; - ide->sc->phase = 1; - ide->sc->pos = 0; + ide->sc->status = BUSY_STAT; + ide->sc->phase = 1; + ide->sc->pos = 0; ide->sc->callback = 1.0 * IDE_TIME; ide_set_callback(ide, ide->sc->callback); } - static void ide_atapi_callback(ide_t *ide) { int out, ret = 0; - switch(ide->sc->packet_status) { - case PHASE_IDLE: + switch (ide->sc->packet_status) { + case PHASE_IDLE: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_IDLE\n"); + ide_log("PHASE_IDLE\n"); #endif - ide->sc->pos = 0; - ide->sc->phase = 1; - ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); - return; - case PHASE_COMMAND: + ide->sc->pos = 0; + ide->sc->phase = 1; + ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); + return; + case PHASE_COMMAND: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_COMMAND\n"); + ide_log("PHASE_COMMAND\n"); #endif - ide->sc->status = BUSY_STAT | (ide->sc->status & ERR_STAT); - if (ide->packet_command) { - ide->packet_command(ide->sc, ide->sc->atapi_cdb); - if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) - ide_atapi_callback(ide); - } - return; - case PHASE_COMPLETE: + ide->sc->status = BUSY_STAT | (ide->sc->status & ERR_STAT); + if (ide->packet_command) { + ide->packet_command(ide->sc, ide->sc->atapi_cdb); + if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); + } + return; + case PHASE_COMPLETE: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_COMPLETE\n"); + ide_log("PHASE_COMPLETE\n"); #endif - ide->sc->status = READY_STAT; - ide->sc->phase = 3; - ide->sc->packet_status = PHASE_NONE; - ide_irq_raise(ide); - return; - case PHASE_DATA_IN: - case PHASE_DATA_OUT: + ide->sc->status = READY_STAT; + ide->sc->phase = 3; + ide->sc->packet_status = PHASE_NONE; + ide_irq_raise(ide); + return; + case PHASE_DATA_IN: + case PHASE_DATA_OUT: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_DATA_IN or PHASE_DATA_OUT\n"); + ide_log("PHASE_DATA_IN or PHASE_DATA_OUT\n"); #endif - ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); - ide->sc->phase = !(ide->sc->packet_status & 0x01) << 1; - ide_irq_raise(ide); - return; - case PHASE_DATA_IN_DMA: - case PHASE_DATA_OUT_DMA: + ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); + ide->sc->phase = !(ide->sc->packet_status & 0x01) << 1; + ide_irq_raise(ide); + return; + case PHASE_DATA_IN_DMA: + case PHASE_DATA_OUT_DMA: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_DATA_IN_DMA or PHASE_DATA_OUT_DMA\n"); + ide_log("PHASE_DATA_IN_DMA or PHASE_DATA_OUT_DMA\n"); #endif - out = (ide->sc->packet_status & 0x01); + out = (ide->sc->packet_status & 0x01); - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - ret = ide_bm[ide->board]->dma(ide->board, - ide->sc->temp_buffer, ide->sc->packet_len, - out, ide_bm[ide->board]->priv); - } else { - /* DMA command without a bus master. */ - if (ide->bus_master_error) - ide->bus_master_error(ide->sc); - return; - } + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { + ret = ide_bm[ide->board]->dma(ide->board, + ide->sc->temp_buffer, ide->sc->packet_len, + out, ide_bm[ide->board]->priv); + } else { + /* DMA command without a bus master. */ + if (ide->bus_master_error) + ide->bus_master_error(ide->sc); + return; + } - if (ret == 0) { - if (ide->bus_master_error) - ide->bus_master_error(ide->sc); - } else if (ret == 1) { - if (out && ide->phase_data_out) - ret = ide->phase_data_out(ide->sc); - else if (!out && ide->command_stop) - ide->command_stop(ide->sc); + if (ret == 0) { + if (ide->bus_master_error) + ide->bus_master_error(ide->sc); + } else if (ret == 1) { + if (out && ide->phase_data_out) + ret = ide->phase_data_out(ide->sc); + else if (!out && ide->command_stop) + ide->command_stop(ide->sc); - if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) - ide_atapi_callback(ide); - } else if (ret == 2) - ide_atapi_command_bus(ide); + if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); + } else if (ret == 2) + ide_atapi_command_bus(ide); - return; - case PHASE_ERROR: + return; + case PHASE_ERROR: #ifdef ENABLE_IDE_LOG - ide_log("PHASE_ERROR\n"); + ide_log("PHASE_ERROR\n"); #endif - ide->sc->status = READY_STAT | ERR_STAT; - ide->sc->phase = 3; - ide->sc->packet_status = PHASE_NONE; - ide_irq_raise(ide); - return; - default: - ide_log("PHASE_UNKNOWN %02X\n", ide->sc->packet_status); - return; + ide->sc->status = READY_STAT | ERR_STAT; + ide->sc->phase = 3; + ide->sc->packet_status = PHASE_NONE; + ide_irq_raise(ide); + return; + default: + ide_log("PHASE_UNKNOWN %02X\n", ide->sc->packet_status); + return; } } - /* This is the general ATAPI PIO request function. */ static void ide_atapi_pio_request(ide_t *ide, uint8_t out) @@ -1065,42 +1036,41 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) dev->status = BSY_STAT; if (dev->pos >= dev->packet_len) { - ide_log("%i bytes %s, command done\n", dev->pos, out ? "written" : "read"); + ide_log("%i bytes %s, command done\n", dev->pos, out ? "written" : "read"); - dev->pos = dev->request_pos = 0; - if (out && ide->phase_data_out) - ide->phase_data_out(dev); - else if (!out && ide->command_stop) - ide->command_stop(dev); + dev->pos = dev->request_pos = 0; + if (out && ide->phase_data_out) + ide->phase_data_out(dev); + else if (!out && ide->command_stop) + ide->command_stop(dev); - if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) - ide_atapi_callback(ide); + if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); } else { - ide_log("%i bytes %s, %i bytes are still left\n", dev->pos, - out ? "written" : "read", dev->packet_len - dev->pos); + ide_log("%i bytes %s, %i bytes are still left\n", dev->pos, + out ? "written" : "read", dev->packet_len - dev->pos); - /* If less than (packet length) bytes are remaining, update packet length - accordingly. */ - if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) { - dev->max_transfer_len = dev->packet_len - dev->pos; - /* Also update the request length so the host knows how many bytes to transfer. */ - dev->request_length = dev->max_transfer_len; + /* If less than (packet length) bytes are remaining, update packet length + accordingly. */ + if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) { + dev->max_transfer_len = dev->packet_len - dev->pos; + /* Also update the request length so the host knows how many bytes to transfer. */ + dev->request_length = dev->max_transfer_len; } - ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, - dev->max_transfer_len); + ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, + dev->max_transfer_len); - dev->packet_status = PHASE_DATA_IN | out; + dev->packet_status = PHASE_DATA_IN | out; - dev->status = BSY_STAT; - dev->phase = 1; - ide_atapi_callback(ide); - ide_set_callback(ide, 0.0); + dev->status = BSY_STAT; + dev->phase = 1; + ide_atapi_callback(ide); + ide_set_callback(ide, 0.0); - dev->request_pos = 0; + dev->request_pos = 0; } } - static uint32_t ide_atapi_packet_read(ide_t *ide, int length) { @@ -1112,10 +1082,10 @@ ide_atapi_packet_read(ide_t *ide, int length) uint32_t temp = 0; if (!dev || !dev->temp_buffer || (dev->packet_status != PHASE_DATA_IN)) - return 0; + return 0; if (dev->packet_status == PHASE_DATA_IN) - ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); + ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); bufferw = (uint16_t *) dev->temp_buffer; bufferl = (uint32_t *) dev->temp_buffer; @@ -1123,160 +1093,157 @@ 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, which can happen when issuing media access commands with an allocated length below minimum request length (which is 1 sector = 2048 bytes). */ - switch(length) { - case 1: - temp = (dev->pos < dev->packet_len) ? dev->temp_buffer[dev->pos] : 0; - dev->pos++; - dev->request_pos++; - break; - case 2: - temp = (dev->pos < dev->packet_len) ? bufferw[dev->pos >> 1] : 0; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - temp = (dev->pos < dev->packet_len) ? bufferl[dev->pos >> 2] : 0; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return 0; + switch (length) { + case 1: + temp = (dev->pos < dev->packet_len) ? dev->temp_buffer[dev->pos] : 0; + dev->pos++; + dev->request_pos++; + break; + case 2: + temp = (dev->pos < dev->packet_len) ? bufferw[dev->pos >> 1] : 0; + dev->pos += 2; + dev->request_pos += 2; + break; + case 4: + temp = (dev->pos < dev->packet_len) ? bufferl[dev->pos >> 2] : 0; + dev->pos += 4; + dev->request_pos += 4; + break; + default: + return 0; } if (dev->packet_status == PHASE_DATA_IN) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - ide_atapi_pio_request(ide, 0); - } - return temp; + if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { + /* Time for a DRQ. */ + ide_atapi_pio_request(ide, 0); + } + return temp; } else - return 0; + return 0; } - static void ide_atapi_packet_write(ide_t *ide, uint32_t val, int length) { scsi_common_t *dev = ide->sc; - uint8_t *bufferb; + uint8_t *bufferb; uint16_t *bufferw; uint32_t *bufferl; if (!dev) - return; + return; if (dev->packet_status == PHASE_IDLE) - bufferb = dev->atapi_cdb; + bufferb = dev->atapi_cdb; else { - if (dev->temp_buffer) - bufferb = dev->temp_buffer; - else - return; + if (dev->temp_buffer) + bufferb = dev->temp_buffer; + else + return; } bufferw = (uint16_t *) bufferb; bufferl = (uint32_t *) bufferb; - switch(length) { - case 1: - bufferb[dev->pos] = val & 0xff; - dev->pos++; - dev->request_pos++; - break; - case 2: - bufferw[dev->pos >> 1] = val & 0xffff; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - bufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; + switch (length) { + case 1: + bufferb[dev->pos] = val & 0xff; + dev->pos++; + dev->request_pos++; + break; + case 2: + bufferw[dev->pos >> 1] = val & 0xffff; + dev->pos += 2; + dev->request_pos += 2; + break; + case 4: + bufferl[dev->pos >> 2] = val; + dev->pos += 4; + dev->request_pos += 4; + break; + default: + return; } if (dev->packet_status == PHASE_DATA_OUT) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - ide_atapi_pio_request(ide, 1); - } - return; + if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { + /* Time for a DRQ. */ + ide_atapi_pio_request(ide, 1); + } + return; } else if (dev->packet_status == PHASE_IDLE) { - if (dev->pos >= 12) { - dev->pos = 0; - dev->status = BSY_STAT; - dev->packet_status = PHASE_COMMAND; - ide_atapi_callback(ide); - } - return; + if (dev->pos >= 12) { + dev->pos = 0; + dev->status = BSY_STAT; + dev->packet_status = PHASE_COMMAND; + ide_atapi_callback(ide); + } + return; } } - void ide_write_data(ide_t *ide, uint32_t val, int length) { - uint8_t *idebufferb = (uint8_t *) ide->buffer; + uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; uint32_t *idebufferl = (uint32_t *) ide->buffer; if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; + ide->pos = 0; - if (ide->type == IDE_ATAPI) - ide_atapi_packet_write(ide, val, length); + if (ide->type == IDE_ATAPI) + ide_atapi_packet_write(ide, val, length); } else { - switch(length) { - case 1: - idebufferb[ide->pos] = val & 0xff; - ide->pos++; - break; - case 2: - idebufferw[ide->pos >> 1] = val & 0xffff; - ide->pos += 2; - break; - case 4: - idebufferl[ide->pos >> 2] = val; - ide->pos += 4; - break; - default: - return; - } + switch (length) { + case 1: + idebufferb[ide->pos] = val & 0xff; + ide->pos++; + break; + case 2: + idebufferw[ide->pos >> 1] = val & 0xffff; + ide->pos += 2; + break; + case 4: + idebufferl[ide->pos >> 2] = val; + ide->pos += 4; + break; + default: + return; + } - if (ide->pos >= 512) { - ide->pos=0; - ide->atastat = BSY_STAT; - 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 wait_time = seek_time + xfer_time; - if (ide->command == WIN_WRITE_MULTIPLE) { - if ((ide->blockcount+1) >= ide->blocksize || ide->secount == 1) { - ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); - ide->pending_delay = 0; - } else { - ide->pending_delay += wait_time; - ide_callback(ide); - } - } else { - ide_set_callback(ide, wait_time); - } - } + if (ide->pos >= 512) { + ide->pos = 0; + ide->atastat = BSY_STAT; + 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 wait_time = seek_time + xfer_time; + if (ide->command == WIN_WRITE_MULTIPLE) { + if ((ide->blockcount + 1) >= ide->blocksize || ide->secount == 1) { + ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); + ide->pending_delay = 0; + } else { + ide->pending_delay += wait_time; + ide_callback(ide); + } + } else { + ide_set_callback(ide, wait_time); + } + } } } - void ide_writew(uint16_t addr, uint16_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; - int ch; + int ch; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; ide_log("ide_writew %04X %04X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); @@ -1284,32 +1251,31 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) addr &= 0x7; if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; + return; switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val, 2); - break; - case 0x7: - ide_writeb(addr, val & 0xff, priv); - break; - default: - ide_writeb(addr, val & 0xff, priv); - ide_writeb(addr + 1, (val >> 8) & 0xff, priv); - break; + case 0x0: /* Data */ + ide_write_data(ide, val, 2); + break; + case 0x7: + ide_writeb(addr, val & 0xff, priv); + break; + default: + ide_writeb(addr, val & 0xff, priv); + ide_writeb(addr + 1, (val >> 8) & 0xff, priv); + break; } } - static void ide_writel(uint16_t addr, uint32_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; - int ch; + int ch; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; ide_log("ide_writel %04X %08X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); @@ -1317,150 +1283,148 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) addr &= 0x7; if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; + return; switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val & 0xffff, 2); - if (dev->bit32) - ide_write_data(ide, val >> 16, 2); - else - ide_writew(addr + 2, (val >> 16) & 0xffff, priv); - break; - case 0x6: case 0x7: - ide_writew(addr, val & 0xffff, priv); - break; - default: - ide_writew(addr, val & 0xffff, priv); - ide_writew(addr + 2, (val >> 16) & 0xffff, priv); - break; + case 0x0: /* Data */ + ide_write_data(ide, val & 0xffff, 2); + if (dev->bit32) + ide_write_data(ide, val >> 16, 2); + else + ide_writew(addr + 2, (val >> 16) & 0xffff, priv); + break; + case 0x6: + case 0x7: + ide_writew(addr, val & 0xffff, priv); + break; + default: + ide_writew(addr, val & 0xffff, priv); + ide_writew(addr + 2, (val >> 16) & 0xffff, priv); + break; } } - static void dev_reset(ide_t *ide) { ide_set_signature(ide); if ((ide->type == IDE_ATAPI) && ide->stop) - ide->stop(ide->sc); + ide->stop(ide->sc); } - void ide_write_devctl(uint16_t addr, uint8_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; - ide_t *ide, *ide_other; - int ch; + ide_t *ide, *ide_other; + int ch; uint8_t old; - ch = dev->cur_dev; - ide = ide_drives[ch]; + ch = dev->cur_dev; + ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; ide_log("ide_write_devctl %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); if ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)) - return; + return; dev->diag = 0; if ((val & 4) && !(ide->fdisk & 4)) { - /* Reset toggled from 0 to 1, initiate reset procedure. */ - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.0; - ide_set_callback(ide, 0.0); - ide_set_callback(ide_other, 0.0); + /* Reset toggled from 0 to 1, initiate reset procedure. */ + if (ide->type == IDE_ATAPI) + ide->sc->callback = 0.0; + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); - /* We must set set the status to busy in reset mode or - some 286 and 386 machines error out. */ - if (!(ch & 1)) { - if (ide->type != IDE_NONE) { - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } - } + /* We must set set the status to busy in reset mode or + some 286 and 386 machines error out. */ + if (!(ch & 1)) { + if (ide->type != IDE_NONE) { + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } + } - if (ide_other->type != IDE_NONE) { - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } - } - } + if (ide_other->type != IDE_NONE) { + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + } + } } else if (!(val & 4) && (ide->fdisk & 4)) { - /* Reset toggled from 1 to 0. */ - if (!(ch & 1)) { - /* Currently active device is 0, use the device 0 reset protocol. */ - /* Device 0. */ - dev_reset(ide); - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } + /* Reset toggled from 1 to 0. */ + if (!(ch & 1)) { + /* Currently active device is 0, use the device 0 reset protocol. */ + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } - /* Device 1. */ - dev_reset(ide_other); - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } - /* Fire the timer. */ - dev->diag = 0; - ide->reset = 1; - ide_set_callback(ide, 0.0); - ide_set_callback(ide_other, 0.0); - ide_set_board_callback(ide->board, 1000.4); /* 1 ms + 400 ns, per the specification */ - } else { - /* Currently active device is 1, simply reset the status and the active device. */ - dev_reset(ide); - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - } - dev->cur_dev &= ~1; - ch = dev->cur_dev; + /* Fire the timer. */ + dev->diag = 0; + ide->reset = 1; + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 1000.4); /* 1 ms + 400 ns, per the specification */ + } else { + /* Currently active device is 1, simply reset the status and the active device. */ + dev_reset(ide); + ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + } + dev->cur_dev &= ~1; + ch = dev->cur_dev; - ide = ide_drives[ch]; - ide->selected = 1; + ide = ide_drives[ch]; + ide->selected = 1; - ide_other = ide_drives[ch ^ 1]; - ide_other->selected = 0; - } + ide_other = ide_drives[ch ^ 1]; + ide_other->selected = 0; + } } - old = ide->fdisk; + old = ide->fdisk; ide->fdisk = ide_other->fdisk = val; if (!(val & 0x02) && (old & 0x02) && ide->irqstat) - ide_irq_update(ide); + ide_irq_update(ide); } - void ide_writeb(uint16_t addr, uint8_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; ide_t *ide, *ide_other; - int ch; + int ch; - ch = dev->cur_dev; - ide = ide_drives[ch]; + ch = dev->cur_dev; + ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; ide_log("ide_write %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); @@ -1468,565 +1432,559 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) addr &= 0x7; if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; + return; switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val | (val << 8), 2); - return; + case 0x0: /* Data */ + ide_write_data(ide, val | (val << 8), 2); + return; - /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ - case 0x1: /* Features */ - if (ide->type == IDE_ATAPI) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - ide->sc->features = val; - } - ide->cylprecomp = val; + /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ + case 0x1: /* Features */ + if (ide->type == IDE_ATAPI) { + ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); + ide->sc->features = val; + } + ide->cylprecomp = val; - if (ide_other->type == IDE_ATAPI) - ide_other->sc->features = val; - ide_other->cylprecomp = val; - return; + if (ide_other->type == IDE_ATAPI) + ide_other->sc->features = val; + ide_other->cylprecomp = val; + return; - case 0x2: /* Sector count */ - if (ide->type == IDE_ATAPI) { - ide_log("Sector count write: %i\n", val); - ide->sc->phase = val; - } - ide->secount = val; + case 0x2: /* Sector count */ + if (ide->type == IDE_ATAPI) { + ide_log("Sector count write: %i\n", val); + ide->sc->phase = val; + } + ide->secount = val; - if (ide_other->type == IDE_ATAPI) { - ide_log("Other sector count write: %i\n", val); - ide_other->sc->phase = val; - } - ide_other->secount = val; - return; + if (ide_other->type == IDE_ATAPI) { + ide_log("Other sector count write: %i\n", val); + ide_other->sc->phase = val; + } + ide_other->secount = val; + return; - case 0x3: /* Sector */ - ide->sector = val; - ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; - ide_other->sector = val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; - return; + case 0x3: /* Sector */ + ide->sector = val; + ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; + ide_other->sector = val; + ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; + return; - case 0x4: /* Cylinder low */ - if (ide->type == IDE_ATAPI) { - ide->sc->request_length &= 0xFF00; - ide->sc->request_length |= val; - } - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); + case 0x4: /* Cylinder low */ + if (ide->type == IDE_ATAPI) { + ide->sc->request_length &= 0xFF00; + ide->sc->request_length |= val; + } + ide->cylinder = (ide->cylinder & 0xFF00) | val; + ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF00; - ide_other->sc->request_length |= val; - } - ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); - return; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->request_length &= 0xFF00; + ide_other->sc->request_length |= val; + } + ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; + ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); + return; - case 0x5: /* Cylinder high */ - if (ide->type == IDE_ATAPI) { - ide->sc->request_length &= 0xFF; - ide->sc->request_length |= (val << 8); - } - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); + case 0x5: /* Cylinder high */ + if (ide->type == IDE_ATAPI) { + ide->sc->request_length &= 0xFF; + ide->sc->request_length |= (val << 8); + } + ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); + ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF; - ide_other->sc->request_length |= (val << 8); - } - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->request_length &= 0xFF; + ide_other->sc->request_length |= (val << 8); + } + ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); + ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); + return; - case 0x6: /* Drive/Head */ - if (ch != ((val >> 4) & 1) + (ide->board << 1)) { - ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); - ch = ide_boards[ide->board]->cur_dev; + case 0x6: /* Drive/Head */ + if (ch != ((val >> 4) & 1) + (ide->board << 1)) { + ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); + ch = ide_boards[ide->board]->cur_dev; - ide = ide_drives[ch]; - ide->selected = 1; + ide = ide_drives[ch]; + ide->selected = 1; - ide_other = ide_drives[ch ^ 1]; - ide_other->selected = 0; + ide_other = ide_drives[ch ^ 1]; + ide_other->selected = 0; - if (ide->reset || ide_other->reset) { - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - ide->reset = ide_other->reset = 0; + if (ide->reset || ide_other->reset) { + ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; + ide->error = ide_other->error = 1; + ide->secount = ide_other->secount = 1; + ide->sector = ide_other->sector = 1; + ide->head = ide_other->head = 0; + ide->cylinder = ide_other->cylinder = 0; + ide->reset = ide_other->reset = 0; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - ide->sc->phase = 1; - ide->sc->request_length = 0xEB14; - ide->sc->callback = 0.0; - ide->cylinder = 0xEB14; - } + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + ide->sc->phase = 1; + ide->sc->request_length = 0xEB14; + ide->sc->callback = 0.0; + ide->cylinder = 0xEB14; + } - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = DRDY_STAT | DSC_STAT; - ide_other->sc->error = 1; - ide_other->sc->phase = 1; - ide_other->sc->request_length = 0xEB14; - ide_other->sc->callback = 0.0; - ide_other->cylinder = 0xEB14; - } + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = DRDY_STAT | DSC_STAT; + ide_other->sc->error = 1; + ide_other->sc->phase = 1; + ide_other->sc->request_length = 0xEB14; + ide_other->sc->callback = 0.0; + ide_other->cylinder = 0xEB14; + } - ide_set_callback(ide, 0.0); - ide_set_callback(ide_other, 0.0); - ide_set_board_callback(ide->board, 0.0); - return; - } - } + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 0.0); + return; + } + } - ide->head = val & 0xF; - ide->lba = val & 0x40; - ide_other->head = val & 0xF; - ide_other->lba = val & 0x40; + ide->head = val & 0xF; + ide->lba = val & 0x40; + ide_other->head = val & 0xF; + ide_other->lba = val & 0x40; - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->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_irq_update(ide); - return; + ide_irq_update(ide); + return; - case 0x7: /* Command register */ - if (ide->type == IDE_NONE) - return; + case 0x7: /* Command register */ + if (ide->type == IDE_NONE) + return; - ide_irq_lower(ide); - ide->command = val; + ide_irq_lower(ide); + ide->command = val; - ide->error = 0; - if (ide->type == IDE_ATAPI) - ide->sc->error = 0; + ide->error = 0; + if (ide->type == IDE_ATAPI) + ide->sc->error = 0; - if (((val >= WIN_RECAL) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT; - else - ide->atastat = READY_STAT | BSY_STAT; + if (((val >= WIN_RECAL) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { + if (ide->type == IDE_ATAPI) + ide->sc->status = DRDY_STAT; + else + ide->atastat = READY_STAT | BSY_STAT; - if (ide->type == IDE_ATAPI) { - ide->sc->callback = 100.0 * IDE_TIME; - ide_set_callback(ide, 100.0 * IDE_TIME); - } else { - double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0); - ide_set_callback(ide, seek_time); - } - return; - } + if (ide->type == IDE_ATAPI) { + ide->sc->callback = 100.0 * IDE_TIME; + ide_set_callback(ide, 100.0 * IDE_TIME); + } else { + double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } + return; + } - switch (val) { - case WIN_SRST: /* ATAPI Device Reset */ - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->callback = 100.0 * IDE_TIME; - } else - ide->atastat = DRDY_STAT; + switch (val) { + case WIN_SRST: /* ATAPI Device Reset */ + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->callback = 100.0 * IDE_TIME; + } else + ide->atastat = DRDY_STAT; - ide_set_callback(ide, 100.0 * IDE_TIME); - return; + ide_set_callback(ide, 100.0 * IDE_TIME); + return; - case WIN_READ_MULTIPLE: - /* Fatal removed in accordance with the official ATAPI reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - ide->blockcount = 0; - /*FALLTHROUGH*/ + case WIN_READ_MULTIPLE: + /* Fatal removed in accordance with the official ATAPI reference: + If the Read Multiple command is attempted before the Set Multiple Mode + command has been executed or when Read Multiple commands are + disabled, the Read Multiple operation is rejected with an Aborted Com- + mand error. */ + ide->blockcount = 0; + /*FALLTHROUGH*/ - case WIN_READ: - case WIN_READ_NORETRY: - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->callback = 200.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; + case WIN_READ: + case WIN_READ_NORETRY: + case WIN_READ_DMA: + case WIN_READ_DMA_ALT: + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->callback = 200.0 * IDE_TIME; + } else + ide->atastat = BSY_STAT; - if (ide->type == IDE_HDD) { - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - uint32_t sec_count; - double wait_time; - if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - // TODO make DMA timing more accurate - sec_count = ide->secount ? ide->secount : 256; - 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); - wait_time = seek_time > xfer_time ? seek_time : xfer_time; - } else if (val == WIN_READ_MULTIPLE) { - sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; - 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); - wait_time = seek_time + xfer_time; - } else { - sec_count = 1; - 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); - wait_time = seek_time + xfer_time; - } - ide_set_callback(ide, wait_time); - } else - ide_set_callback(ide, 200.0 * IDE_TIME); - ide->do_initial_read = 1; - return; + if (ide->type == IDE_HDD) { + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + uint32_t sec_count; + double wait_time; + if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { + // TODO make DMA timing more accurate + sec_count = ide->secount ? ide->secount : 256; + 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); + wait_time = seek_time > xfer_time ? seek_time : xfer_time; + } else if (val == WIN_READ_MULTIPLE) { + sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; + 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); + wait_time = seek_time + xfer_time; + } else { + sec_count = 1; + 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); + wait_time = seek_time + xfer_time; + } + ide_set_callback(ide, wait_time); + } else + ide_set_callback(ide, 200.0 * IDE_TIME); + ide->do_initial_read = 1; + return; - case WIN_WRITE_MULTIPLE: - /* Fatal removed for the same reason as for WIN_READ_MULTIPLE. */ - ide->blockcount = 0; - /* Turn on the activity indicator *here* so that it gets turned on - less times. */ - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - /*FALLTHROUGH*/ + case WIN_WRITE_MULTIPLE: + /* Fatal removed for the same reason as for WIN_READ_MULTIPLE. */ + ide->blockcount = 0; + /* Turn on the activity indicator *here* so that it gets turned on + less times. */ + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + /*FALLTHROUGH*/ - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->sc->pos = 0; - } else { - ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->pos=0; - } - return; + case WIN_WRITE: + case WIN_WRITE_NORETRY: + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRQ_STAT | DSC_STAT | DRDY_STAT; + ide->sc->pos = 0; + } else { + ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; + ide->pos = 0; + } + return; - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - case WIN_IDENTIFY: /* Identify Device */ - case WIN_SET_FEATURES: /* Set Features */ - case WIN_READ_NATIVE_MAX: - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->callback = 200.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; + case WIN_WRITE_DMA: + case WIN_WRITE_DMA_ALT: + case WIN_VERIFY: + case WIN_VERIFY_ONCE: + case WIN_IDENTIFY: /* Identify Device */ + case WIN_SET_FEATURES: /* Set Features */ + case WIN_READ_NATIVE_MAX: + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->callback = 200.0 * IDE_TIME; + } else + ide->atastat = BSY_STAT; - if ((ide->type == IDE_HDD) && - ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { - 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 xfer_time = ide_get_xfer_time(ide, 512 * sec_count); - double wait_time = seek_time > xfer_time ? seek_time : xfer_time; - ide_set_callback(ide, wait_time); - } else if ((ide->type == IDE_HDD) && - ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { - 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)); - } else if (val == WIN_IDENTIFY) - ide_callback(ide); - else - ide_set_callback(ide, 200.0 * IDE_TIME); - return; + if ((ide->type == IDE_HDD) && ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { + 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 xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + double wait_time = seek_time > xfer_time ? seek_time : xfer_time; + ide_set_callback(ide, wait_time); + } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { + 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)); + } else if (val == WIN_IDENTIFY) + ide_callback(ide); + else + ide_set_callback(ide, 200.0 * IDE_TIME); + return; - case WIN_FORMAT: - if (ide->type == IDE_ATAPI) - goto ide_bad_command; - else { - ide->atastat = DRQ_STAT; - ide->pos=0; - } - return; + case WIN_FORMAT: + if (ide->type == IDE_ATAPI) + goto ide_bad_command; + else { + ide->atastat = DRQ_STAT; + ide->pos = 0; + } + return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->callback = 30.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; + case WIN_SPECIFY: /* Initialize Drive Parameters */ + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->callback = 30.0 * IDE_TIME; + } else + ide->atastat = BSY_STAT; - ide_set_callback(ide, 30.0 * IDE_TIME); - return; + ide_set_callback(ide, 30.0 * IDE_TIME); + return; - case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - dev->cur_dev &= ~1; - ide = ide_drives[ch & ~1]; - ide->selected = 1; - ide_other = ide_drives[ch | 1]; - ide_other->selected = 0; + case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ + dev->cur_dev &= ~1; + ide = ide_drives[ch & ~1]; + ide->selected = 1; + ide_other = ide_drives[ch | 1]; + ide_other->selected = 0; - /* Device 0. */ - dev_reset(ide); - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } - /* Device 1. */ - dev_reset(ide_other); - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } - /* Fire the timer. */ - dev->diag = 1; - ide->reset = 1; - ide_set_callback(ide, 0.0); - ide_set_callback(ide_other, 0.0); - ide_set_board_callback(ide->board, 200.0 * IDE_TIME); - return; + /* Fire the timer. */ + dev->diag = 1; + ide->reset = 1; + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 200.0 * IDE_TIME); + return; - case WIN_PIDENTIFY: /* Identify Packet Device */ - case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: /* Idle */ - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide->type == IDE_ATAPI) - ide->sc->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - ide_callback(ide); - return; + case WIN_PIDENTIFY: /* Identify Packet Device */ + case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ + case WIN_NOP: + case WIN_STANDBYNOW1: + case WIN_IDLENOW1: + case WIN_SETIDLE1: /* Idle */ + case WIN_CHECKPOWERMODE1: + case WIN_SLEEP1: + if (ide->type == IDE_ATAPI) + ide->sc->status = BSY_STAT; + else + ide->atastat = BSY_STAT; + ide_callback(ide); + return; - case WIN_PACKETCMD: /* ATAPI Packet */ - /* Skip the command callback wait, and process immediately. */ - if (ide->type == IDE_ATAPI) { - ide->sc->packet_status = PHASE_IDLE; - ide->sc->pos = 0; - ide->sc->phase = 1; - ide->sc->status = DRDY_STAT | DRQ_STAT; - if (ide->interrupt_drq) - ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ - } else { - ide->atastat = BSY_STAT; - ide_set_callback(ide, 200.0 * IDE_TIME); - ide->pos=0; - } - return; + case WIN_PACKETCMD: /* ATAPI Packet */ + /* Skip the command callback wait, and process immediately. */ + if (ide->type == IDE_ATAPI) { + ide->sc->packet_status = PHASE_IDLE; + ide->sc->pos = 0; + ide->sc->phase = 1; + ide->sc->status = DRDY_STAT | DRQ_STAT; + if (ide->interrupt_drq) + ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ + } else { + ide->atastat = BSY_STAT; + ide_set_callback(ide, 200.0 * IDE_TIME); + ide->pos = 0; + } + return; - case 0xF0: - default: + case 0xF0: + default: ide_bad_command: - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - } - ide_irq_raise(ide); - return; - } - return; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->sc->error = ABRT_ERR; + } else { + ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + } + ide_irq_raise(ide); + return; + } + return; } } - static uint32_t ide_read_data(ide_t *ide, int length) { uint32_t temp = 0; if (!ide->buffer) { - switch (length) { - case 1: - return 0xff; - case 2: - return 0xffff; - case 4: - return 0xffffffff; - default: - return 0; - } + switch (length) { + case 1: + return 0xff; + case 2: + return 0xffff; + case 4: + return 0xffffffff; + default: + return 0; + } } - uint8_t *idebufferb = (uint8_t *) ide->buffer; + uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; uint32_t *idebufferl = (uint32_t *) ide->buffer; if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - if (ide->type == IDE_ATAPI) - temp = ide_atapi_packet_read(ide, length); - else { - ide_log("Drive not ATAPI (position: %i)\n", ide->pos); - return 0; - } + ide->pos = 0; + if (ide->type == IDE_ATAPI) + temp = ide_atapi_packet_read(ide, length); + else { + ide_log("Drive not ATAPI (position: %i)\n", ide->pos); + return 0; + } } else { - switch (length) { - case 1: - temp = idebufferb[ide->pos]; - ide->pos++; - break; - case 2: - temp = idebufferw[ide->pos >> 1]; - ide->pos += 2; - break; - case 4: - temp = idebufferl[ide->pos >> 2]; - ide->pos += 4; - break; - default: - return 0; - } + switch (length) { + case 1: + temp = idebufferb[ide->pos]; + ide->pos++; + break; + case 2: + temp = idebufferw[ide->pos >> 1]; + ide->pos += 2; + break; + case 4: + temp = idebufferl[ide->pos >> 2]; + ide->pos += 4; + break; + default: + return 0; + } } if ((ide->pos >= 512) && (ide->command != WIN_PACKETCMD)) { - ide->pos = 0; - ide->atastat = DRDY_STAT | DSC_STAT; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->packet_status = PHASE_IDLE; - } - if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || (ide->command == WIN_READ_MULTIPLE)) { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; - if (ide->command == WIN_READ_MULTIPLE) { - if (!ide->blockcount) { - uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; - 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); - ide_set_callback(ide, seek_time + xfer_time); - } else { - ide_callback(ide); - } - } else { - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - ide_set_callback(ide, seek_time + xfer_time); - } - } else - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } + ide->pos = 0; + ide->atastat = DRDY_STAT | DSC_STAT; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->packet_status = PHASE_IDLE; + } + if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || (ide->command == WIN_READ_MULTIPLE)) { + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide_next_sector(ide); + ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; + if (ide->command == WIN_READ_MULTIPLE) { + if (!ide->blockcount) { + uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; + 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); + ide_set_callback(ide, seek_time + xfer_time); + } else { + ide_callback(ide); + } + } else { + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + double xfer_time = ide_get_xfer_time(ide, 512); + ide_set_callback(ide, seek_time + xfer_time); + } + } else + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } } return temp; } - static uint8_t ide_status(ide_t *ide, ide_t *ide_other, int ch) { if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1))) #ifdef STATUS_BIT_7_PULLDOWN - return 0x7F; /* Bit 7 pulled down, all other bits pulled up, per the spec. */ + return 0x7F; /* Bit 7 pulled down, all other bits pulled up, per the spec. */ #else - return 0xFF; + return 0xFF; #endif else if ((ide->type == IDE_NONE) && (ch & 1)) - return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */ + return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */ else if (ide->type == IDE_ATAPI) - return (ide->sc->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + return (ide->sc->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); else - return ide->atastat; + return ide->atastat; } - uint8_t ide_readb(uint16_t addr, void *priv) { ide_board_t *dev = (ide_board_t *) priv; - int ch; + int ch; ide_t *ide; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; - uint8_t temp = 0xff; + uint8_t temp = 0xff; uint16_t tempw; addr |= 0x90; addr &= 0xFFF7; switch (addr & 0x7) { - case 0x0: /* Data */ - tempw = ide_read_data(ide, 2); - temp = tempw & 0xff; - break; + case 0x0: /* Data */ + tempw = ide_read_data(ide, 2); + temp = tempw & 0xff; + break; - /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), - Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), - and Bit 0 = ILI (illegal length indication). */ - case 0x1: /* Error */ - if (ide->type == IDE_NONE) - temp = 0; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->error; - else - temp = ide->error; - break; + /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), + Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), + and Bit 0 = ILI (illegal length indication). */ + case 0x1: /* Error */ + if (ide->type == IDE_NONE) + temp = 0; + else if (ide->type == IDE_ATAPI) + temp = ide->sc->error; + else + temp = ide->error; + break; - /* For ATAPI: - Bit 0: Command or Data: - Data if clear, Command if set; - Bit 1: I/OB - Direction: - To device if set; - From device if clear. - IO DRQ CoD - 0 1 1 Ready to accept command packet - 1 1 1 Message - ready to send message to host - 1 1 0 Data to host - 0 1 0 Data from host - 1 0 1 Status. */ - case 0x2: /* Sector count */ - if (ide->type == IDE_ATAPI) - temp = ide->sc->phase; - else if (ide->type != IDE_NONE) - temp = ide->secount; - break; + /* For ATAPI: + Bit 0: Command or Data: + Data if clear, Command if set; + Bit 1: I/OB + Direction: + To device if set; + From device if clear. + IO DRQ CoD + 0 1 1 Ready to accept command packet + 1 1 1 Message - ready to send message to host + 1 1 0 Data to host + 0 1 0 Data from host + 1 0 1 Status. */ + case 0x2: /* Sector count */ + if (ide->type == IDE_ATAPI) + temp = ide->sc->phase; + else if (ide->type != IDE_NONE) + temp = ide->secount; + break; - case 0x3: /* Sector */ - if (ide->type != IDE_NONE) - temp = (uint8_t) ide->sector; - break; + case 0x3: /* Sector */ + if (ide->type != IDE_NONE) + temp = (uint8_t) ide->sector; + break; - case 0x4: /* Cylinder low */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->request_length & 0xff; - else - temp = ide->cylinder & 0xff; - break; + case 0x4: /* Cylinder low */ + if (ide->type == IDE_NONE) + temp = 0xFF; + else if (ide->type == IDE_ATAPI) + temp = ide->sc->request_length & 0xff; + else + temp = ide->cylinder & 0xff; + break; - case 0x5: /* Cylinder high */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->request_length >> 8; - else - temp = ide->cylinder >> 8; - break; + case 0x5: /* Cylinder high */ + if (ide->type == IDE_NONE) + temp = 0xFF; + else if (ide->type == IDE_ATAPI) + temp = ide->sc->request_length >> 8; + else + temp = ide->cylinder >> 8; + break; - case 0x6: /* Drive/Head */ - temp = (uint8_t)(ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); - break; + case 0x6: /* Drive/Head */ + temp = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); + break; - /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is - DF (drive fault). */ - case 0x7: /* Status */ - ide_irq_lower(ide); - temp = ide_status(ide, ide_drives[ch ^ 1], ch); - break; + /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is + DF (drive fault). */ + case 0x7: /* Status */ + ide_irq_lower(ide); + temp = ide_status(ide, ide_drives[ch ^ 1], ch); + break; } ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, temp); return temp; } - uint8_t ide_read_alt_status(uint16_t addr, void *priv) { @@ -2035,9 +1993,9 @@ ide_read_alt_status(uint16_t addr, void *priv) ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; - int ch; + int ch; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; /* Per the Seagate ATA-3 specification: @@ -2048,7 +2006,6 @@ ide_read_alt_status(uint16_t addr, void *priv) return temp; } - uint16_t ide_readw(uint16_t addr, void *priv) { @@ -2057,28 +2014,27 @@ ide_readw(uint16_t addr, void *priv) ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; - int ch; + int ch; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; switch (addr & 0x7) { - case 0x0: /* Data */ - temp = ide_read_data(ide, 2); - break; - case 0x7: - temp = ide_readb(addr, priv) | 0xff00; - break; - default: - temp = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); - break; + case 0x0: /* Data */ + temp = ide_read_data(ide, 2); + break; + case 0x7: + temp = ide_readb(addr, priv) | 0xff00; + break; + default: + temp = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); + break; } ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); return temp; } - static uint32_t ide_readl(uint16_t addr, void *priv) { @@ -2088,75 +2044,73 @@ ide_readl(uint16_t addr, void *priv) ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; - int ch; + int ch; - ch = dev->cur_dev; + ch = dev->cur_dev; ide = ide_drives[ch]; switch (addr & 0x7) { - case 0x0: /* Data */ - temp2 = ide_read_data(ide, 2); - if (dev->bit32) - temp = temp2 | (ide_read_data(ide, 2) << 16); - else - temp = temp2 | (ide_readw(addr + 2, priv) << 16); - break; - case 0x6: case 0x7: - temp = ide_readw(addr, priv) | 0xffff0000; - break; - default: - temp = ide_readw(addr, priv) | (ide_readw(addr + 2, priv) << 16); - break; + case 0x0: /* Data */ + temp2 = ide_read_data(ide, 2); + if (dev->bit32) + temp = temp2 | (ide_read_data(ide, 2) << 16); + else + temp = temp2 | (ide_readw(addr + 2, priv) << 16); + break; + case 0x6: + case 0x7: + temp = ide_readw(addr, priv) | 0xffff0000; + break; + default: + temp = ide_readw(addr, priv) | (ide_readw(addr + 2, priv) << 16); + break; } ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, temp); return temp; } - static void ide_board_callback(void *priv) { - ide_board_t *dev = (ide_board_t *) priv; + ide_board_t *dev = (ide_board_t *) priv; #ifdef ENABLE_IDE_LOG - ide_log("CALLBACK RESET\n"); + ide_log("CALLBACK RESET\n"); #endif - dev->ide[0]->atastat = DRDY_STAT | DSC_STAT; - if (dev->ide[0]->type == IDE_ATAPI) - dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; + dev->ide[0]->atastat = DRDY_STAT | DSC_STAT; + if (dev->ide[0]->type == IDE_ATAPI) + dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; dev->ide[1]->atastat = DRDY_STAT | DSC_STAT; if (dev->ide[1]->type == IDE_ATAPI) - dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; + dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; dev->cur_dev &= ~1; if (dev->diag) { - dev->diag = 0; - ide_irq_raise(dev->ide[0]); + dev->diag = 0; + ide_irq_raise(dev->ide[0]); } } - static void atapi_error_no_ready(ide_t *ide) { ide->command = 0; if (ide->type == IDE_ATAPI) { - ide->sc->status = ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - ide->sc->pos = 0; + ide->sc->status = ERR_STAT | DSC_STAT; + ide->sc->error = ABRT_ERR; + ide->sc->pos = 0; } else { - ide->atastat = ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; + ide->atastat = ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + ide->pos = 0; } ide_irq_raise(ide); } - static void ide_callback(void *priv) { @@ -2166,565 +2120,551 @@ ide_callback(void *priv) ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset, ide->channel); - if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || - ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { - if (ide->type != IDE_HDD) { - atapi_error_no_ready(ide); - return; - } - if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) { - if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || - !ide->sector || (ide->sector > ide->spt)) - goto id_not_found; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { + if (ide->type != IDE_HDD) { + atapi_error_no_ready(ide); + return; + } + if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) { + if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || !ide->sector || (ide->sector > ide->spt)) + goto id_not_found; + } + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; } switch (ide->command) { - /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, - Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ + /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, + Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ case WIN_SRST: /*ATAPI Device Reset */ - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = 1; - ide->sector = 1; + ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; /*Device passed*/ + ide->secount = 1; + ide->sector = 1; - ide_set_signature(ide); + ide_set_signature(ide); - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - if (ide->device_reset) - ide->device_reset(ide->sc); - } - ide_irq_raise(ide); - if (ide->type == IDE_ATAPI) - ide->service = 0; - return; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + if (ide->device_reset) + ide->device_reset(ide->sc); + } + ide_irq_raise(ide); + if (ide->type == IDE_ATAPI) + ide->service = 0; + return; - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; - else - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_NOP: + case WIN_STANDBYNOW1: + case WIN_IDLENOW1: + case WIN_SETIDLE1: + if (ide->type == IDE_ATAPI) + ide->sc->status = DRDY_STAT | DSC_STAT; + else + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide->type == IDE_ATAPI) { - ide->sc->phase = 0xFF; - ide->sc->status = DRDY_STAT | DSC_STAT; - } - ide->secount = 0xFF; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_CHECKPOWERMODE1: + case WIN_SLEEP1: + if (ide->type == IDE_ATAPI) { + ide->sc->phase = 0xFF; + ide->sc->status = DRDY_STAT | DSC_STAT; + } + ide->secount = 0xFF; + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_READ: - case WIN_READ_NORETRY: - if (ide->type == IDE_ATAPI) { - ide_set_signature(ide); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; + case WIN_READ: + case WIN_READ_NORETRY: + if (ide->type == IDE_ATAPI) { + ide_set_signature(ide); + goto abort_cmd; + } + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + if (ide->secount) + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + else + 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->pos = 0; + ide->sector_pos++; + ide->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); + ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + return; - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { - ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) { - ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } + case WIN_READ_DMA: + case WIN_READ_DMA_ALT: + if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { + ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); + goto abort_cmd; + } + if (!ide->lba && (ide->cfg_spt == 0)) { + ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); + goto id_not_found; + } - ide->sector_pos = 0; - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); + ide->sector_pos = 0; + if (ide->secount) + ide->sector_pos = ide->secount; + else + ide->sector_pos = 256; + 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) { - /* We should not abort - we should simply wait for the host to start DMA. */ - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - 0, ide_bm[ide->board]->priv); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide, 6.0 * IDE_TIME); - return; - } else if (ret == 1) { - /*DMA successful*/ - ide_log("IDE %i: DMA read successful\n", ide->channel); + 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. */ + ret = ide_bm[ide->board]->dma(ide->board, + ide->sector_buffer, ide->sector_pos * 512, + 0, ide_bm[ide->board]->priv); + if (ret == 2) { + /* Bus master DMA disabled, simply wait for the host to enable DMA. */ + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_set_callback(ide, 6.0 * IDE_TIME); + return; + } else if (ret == 1) { + /*DMA successful*/ + ide_log("IDE %i: DMA read successful\n", ide->channel); - ide->atastat = DRDY_STAT | DSC_STAT; + ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } else { - /* Bus master DMAS error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } - } else { - ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } - return; + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } else { + /* Bus master DMAS error, abort the command. */ + ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); + goto abort_cmd; + } + } else { + ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); + goto abort_cmd; + } + return; - case WIN_READ_MULTIPLE: - /* According to the official ATA reference: + case WIN_READ_MULTIPLE: + /* According to the official ATA reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - if ((ide->type == IDE_ATAPI) || !ide->blocksize) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; + If the Read Multiple command is attempted before the Set Multiple Mode + command has been executed or when Read Multiple commands are + disabled, the Read Multiple operation is rejected with an Aborted Com- + mand error. */ + if ((ide->type == IDE_ATAPI) || !ide->blocksize) + goto abort_cmd; + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + if (ide->secount) + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + else + 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->pos=0; + ide->sector_pos++; + ide->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - if (!ide->blockcount) - ide_irq_raise(ide); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize) - ide->blockcount = 0; - return; + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + if (!ide->blockcount) + ide_irq_raise(ide); + ide->blockcount++; + if (ide->blockcount >= ide->blocksize) + ide->blockcount = 0; + return; - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide_irq_raise(ide); - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; + case WIN_WRITE: + case WIN_WRITE_NORETRY: + if (ide->type == IDE_ATAPI) + goto abort_cmd; + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ide_irq_raise(ide); + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->pos = 0; + ide_next_sector(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + } else { + ide->atastat = DRDY_STAT | DSC_STAT; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } + return; - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { - ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) { - ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } + case WIN_WRITE_DMA: + case WIN_WRITE_DMA_ALT: + if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { + ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); + goto abort_cmd; + } + if (!ide->lba && (ide->cfg_spt == 0)) { + ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); + goto id_not_found; + } - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; + if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { + if (ide->secount) + ide->sector_pos = ide->secount; + else + ide->sector_pos = 256; - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - 1, ide_bm[ide->board]->priv); + ret = ide_bm[ide->board]->dma(ide->board, + ide->sector_buffer, ide->sector_pos * 512, + 1, ide_bm[ide->board]->priv); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide, 6.0 * IDE_TIME); - return; - } else if (ret == 1) { - /*DMA successful*/ - ide_log("IDE %i: DMA write successful\n", ide->channel); + if (ret == 2) { + /* Bus master DMA disabled, simply wait for the host to enable DMA. */ + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_set_callback(ide, 6.0 * IDE_TIME); + return; + } else if (ret == 1) { + /*DMA successful*/ + ide_log("IDE %i: DMA write successful\n", ide->channel); - hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); + hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - ide->atastat = DRDY_STAT | DSC_STAT; + ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } else { - /* Bus master DMA error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } - } else { - ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } else { + /* Bus master DMA error, abort the command. */ + ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); + goto abort_cmd; + } + } else { + ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); + goto abort_cmd; + } - return; + return; - case WIN_WRITE_MULTIPLE: - /* According to the official ATA reference: + case WIN_WRITE_MULTIPLE: + /* According to the official ATA reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - if ((ide->type == IDE_ATAPI) || !ide->blocksize) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize || ide->secount == 1) { - ide->blockcount = 0; - ide_irq_raise(ide); - } - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; + If the Read Multiple command is attempted before the Set Multiple Mode + command has been executed or when Read Multiple commands are + disabled, the Read Multiple operation is rejected with an Aborted Com- + mand error. */ + if ((ide->type == IDE_ATAPI) || !ide->blocksize) + goto abort_cmd; + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ide->blockcount++; + if (ide->blockcount >= ide->blocksize || ide->secount == 1) { + ide->blockcount = 0; + ide_irq_raise(ide); + } + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->pos = 0; + ide_next_sector(ide); + } else { + ide->atastat = DRDY_STAT | DSC_STAT; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } + return; - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - ide->pos=0; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + case WIN_VERIFY: + case WIN_VERIFY_ONCE: + if (ide->type == IDE_ATAPI) + goto abort_cmd; + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; + ide->pos = 0; + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + return; - case WIN_FORMAT: - if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); + case WIN_FORMAT: + if (ide->type == IDE_ATAPI) + goto abort_cmd; + if (!ide->lba && (ide->cfg_spt == 0)) + goto id_not_found; + hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - ide->cfg_spt = ide->secount; - ide->cfg_hpc = ide->head + 1; - } - ide->command = 0x00; - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - return; + case WIN_SPECIFY: /* Initialize Drive Parameters */ + if (ide->type == IDE_ATAPI) + goto abort_cmd; + if (ide->cfg_spt == 0) { + /* Only accept after RESET or DIAG. */ + ide->cfg_spt = ide->secount; + ide->cfg_hpc = ide->head + 1; + } + ide->command = 0x00; + ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + ide_irq_raise(ide); + return; - case WIN_PIDENTIFY: /* Identify Packet Device */ - if (ide->type == IDE_ATAPI) { - ide_identify(ide); - ide->pos = 0; - ide->sc->phase = 2; - ide->sc->pos = 0; - ide->sc->error = 0; - ide->sc->status = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } - goto abort_cmd; + case WIN_PIDENTIFY: /* Identify Packet Device */ + if (ide->type == IDE_ATAPI) { + ide_identify(ide); + ide->pos = 0; + ide->sc->phase = 2; + ide->sc->pos = 0; + ide->sc->error = 0; + ide->sc->status = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; + } + goto abort_cmd; - case WIN_SET_MULTIPLE_MODE: - if (ide->type == IDE_ATAPI) - goto abort_cmd; - ide->blocksize = ide->secount; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_SET_MULTIPLE_MODE: + if (ide->type == IDE_ATAPI) + goto abort_cmd; + ide->blocksize = ide->secount; + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_SET_FEATURES: - if ((ide->type == IDE_NONE) || !ide_set_features(ide)) - goto abort_cmd; + case WIN_SET_FEATURES: + if ((ide->type == IDE_NONE) || !ide_set_features(ide)) + goto abort_cmd; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->pos = 0; - } + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->pos = 0; + } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_READ_NATIVE_MAX: - if (ide->type != IDE_HDD) - goto abort_cmd; - snum = hdd[ide->hdd_num].spt; - snum *= hdd[ide->hdd_num].hpc; - snum *= hdd[ide->hdd_num].tracks; - ide_set_sector(ide, snum - 1); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_READ_NATIVE_MAX: + if (ide->type != IDE_HDD) + goto abort_cmd; + snum = hdd[ide->hdd_num].spt; + snum *= hdd[ide->hdd_num].hpc; + snum *= hdd[ide->hdd_num].tracks; + ide_set_sector(ide, snum - 1); + ide->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_IDENTIFY: /* Identify Device */ - if (ide->type != IDE_HDD) { - ide_set_signature(ide); - goto abort_cmd; - } else { - ide_identify(ide); - ide->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; + case WIN_IDENTIFY: /* Identify Device */ + if (ide->type != IDE_HDD) { + ide_set_signature(ide); + goto abort_cmd; + } else { + ide_identify(ide); + ide->pos = 0; + ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + } + return; - case WIN_PACKETCMD: /* ATAPI Packet */ - if (ide->type != IDE_ATAPI) - goto abort_cmd; + case WIN_PACKETCMD: /* ATAPI Packet */ + if (ide->type != IDE_ATAPI) + goto abort_cmd; - ide_atapi_callback(ide); - return; + ide_atapi_callback(ide); + return; - case 0xFF: - goto abort_cmd; + case 0xFF: + goto abort_cmd; } abort_cmd: ide->command = 0; if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - ide->sc->pos = 0; + ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->sc->error = ABRT_ERR; + ide->sc->pos = 0; } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; + ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + ide->pos = 0; } ide_irq_raise(ide); return; id_not_found: ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = IDNF_ERR; - ide->pos = 0; + ide->error = IDNF_ERR; + ide->pos = 0; ide_irq_raise(ide); } - uint8_t ide_read_ali_75(void) { - ide_t *ide0, *ide1; - int ch0, ch1; + ide_t *ide0, *ide1; + int ch0, ch1; uint8_t ret = 0x00; - ch0 = ide_boards[0]->cur_dev; - ch1 = ide_boards[1]->cur_dev; + ch0 = ide_boards[0]->cur_dev; + ch1 = ide_boards[1]->cur_dev; ide0 = ide_drives[ch0]; ide1 = ide_drives[ch1]; if (ch1) - ret |= 0x08; + ret |= 0x08; if (ch0) - ret |= 0x04; + ret |= 0x04; if (ide1->irqstat) - ret |= 0x02; + ret |= 0x02; if (ide0->irqstat) - ret |= 0x01; + ret |= 0x01; return ret; } - uint8_t ide_read_ali_76(void) { - ide_t *ide0, *ide1; - int ch0, ch1; + ide_t *ide0, *ide1; + int ch0, ch1; uint8_t ret = 0x00; - ch0 = ide_boards[0]->cur_dev; - ch1 = ide_boards[1]->cur_dev; + ch0 = ide_boards[0]->cur_dev; + ch1 = ide_boards[1]->cur_dev; ide0 = ide_drives[ch0]; ide1 = ide_drives[ch1]; if (ide1->atastat & BSY_STAT) - ret |= 0x40; + ret |= 0x40; if (ide1->atastat & DRQ_STAT) - ret |= 0x20; + ret |= 0x20; if (ide1->atastat & ERR_STAT) - ret |= 0x10; + ret |= 0x10; if (ide0->atastat & BSY_STAT) - ret |= 0x04; + ret |= 0x04; if (ide0->atastat & DRQ_STAT) - ret |= 0x02; + ret |= 0x02; if (ide0->atastat & ERR_STAT) - ret |= 0x01; + ret |= 0x01; return ret; } - void ide_set_handlers(uint8_t board) { if (ide_boards[board] == NULL) - return; + return; if (ide_boards[board]->base_main) { - io_sethandler(ide_boards[board]->base_main, 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); + io_sethandler(ide_boards[board]->base_main, 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); } if (ide_boards[board]->side_main) { - io_sethandler(ide_boards[board]->side_main, 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); + io_sethandler(ide_boards[board]->side_main, 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[board]); } } - void ide_remove_handlers(uint8_t board) { if (ide_boards[board] == NULL) - return; + return; if (ide_boards[board]->base_main) { - io_removehandler(ide_boards[board]->base_main, 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); + io_removehandler(ide_boards[board]->base_main, 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); } if (ide_boards[board]->side_main) { - io_removehandler(ide_boards[board]->side_main, 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); + io_removehandler(ide_boards[board]->side_main, 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[board]); } } - void ide_pri_enable(void) { ide_set_handlers(0); } - void ide_pri_disable(void) { ide_remove_handlers(0); } - void ide_sec_enable(void) { ide_set_handlers(1); } - void ide_sec_disable(void) { ide_remove_handlers(1); } - void ide_set_base(int board, uint16_t port) { ide_log("ide_set_base(%i, %04X)\n", board, port); if (ide_boards[board] == NULL) - return; + return; ide_boards[board]->base_main = port; } - void ide_set_side(int board, uint16_t port) { ide_log("ide_set_side(%i, %04X)\n", board, port); if (ide_boards[board] == NULL) - return; + return; ide_boards[board]->side_main = port; } - static void ide_clear_bus_master(int board) { if (ide_bm[board]) { - free(ide_bm[board]); - ide_bm[board] = NULL; + free(ide_bm[board]); + ide_bm[board] = NULL; } } - /* 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. */ extern void @@ -2732,23 +2672,22 @@ ide_board_set_force_ata3(int board, int force_ata3) { ide_log("ide_board_set_force_ata3(%i, %i)\n", board, force_ata3); - if ((ide_boards[board] == NULL)|| !ide_boards[board]->inited) - return; + if ((ide_boards[board] == NULL) || !ide_boards[board]->inited) + return; ide_boards[board]->force_ata3 = force_ata3; } - static void ide_board_close(int board) { ide_t *dev; - int c, d; + int c, d; ide_log("ide_board_close(%i)\n", board); - if ((ide_boards[board] == NULL)|| !ide_boards[board]->inited) - return; + if ((ide_boards[board] == NULL) || !ide_boards[board]->inited) + return; ide_log("IDE: Closing board %i...\n", board); @@ -2758,116 +2697,115 @@ ide_board_close(int board) /* Close hard disk image files (if previously open) */ for (d = 0; d < 2; d++) { - c = (board << 1) + d; + c = (board << 1) + d; - ide_boards[board]->ide[d] = NULL; + ide_boards[board]->ide[d] = NULL; - dev = ide_drives[c]; + dev = ide_drives[c]; - if (dev == NULL) - continue; + if (dev == NULL) + continue; - if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) - hdd_image_close(dev->hdd_num); + if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) + hdd_image_close(dev->hdd_num); - if (dev->type == IDE_ATAPI) - dev->sc->status = DRDY_STAT | DSC_STAT; + if (dev->type == IDE_ATAPI) + dev->sc->status = DRDY_STAT | DSC_STAT; - if (dev->buffer) { - free(dev->buffer); - dev->buffer = NULL; - } + if (dev->buffer) { + free(dev->buffer); + dev->buffer = NULL; + } - if (dev->sector_buffer) { - free(dev->sector_buffer); - dev->buffer = NULL; - } + if (dev->sector_buffer) { + free(dev->sector_buffer); + dev->buffer = NULL; + } - if (dev) { - free(dev); - ide_drives[c] = NULL; - } + if (dev) { + free(dev); + ide_drives[c] = NULL; + } } free(ide_boards[board]); ide_boards[board] = NULL; } - static void ide_board_setup(int board) { ide_t *dev; - int c, d; - int ch, is_ide, valid_ch; - int min_ch, max_ch; + int c, d; + int ch, is_ide, valid_ch; + int min_ch, max_ch; min_ch = (board << 1); max_ch = min_ch + 1; ide_log("IDE: board %i: loading disks...\n", board); for (d = 0; d < 2; d++) { - c = (board << 1) + d; - ide_zero(c); + c = (board << 1) + d; + ide_zero(c); } c = 0; for (d = 0; d < HDD_NUM; d++) { - is_ide = (hdd[d].bus == HDD_BUS_IDE); - ch = hdd[d].ide_channel; + is_ide = (hdd[d].bus == HDD_BUS_IDE); + ch = hdd[d].ide_channel; - if (board == 4) { - valid_ch = ((ch >= 0) && (ch <= 1)); - ch |= 8; - } else - valid_ch = ((ch >= min_ch) && (ch <= max_ch)); + if (board == 4) { + valid_ch = ((ch >= 0) && (ch <= 1)); + ch |= 8; + } else + valid_ch = ((ch >= min_ch) && (ch <= max_ch)); - if (is_ide && valid_ch) { - ide_log("Found IDE hard disk on channel %i\n", ch); - loadhd(ide_drives[ch], d, hdd[d].fn); - if (ide_drives[ch]->sector_buffer == NULL) - ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256*512); - memset(ide_drives[ch]->sector_buffer, 0, 256*512); - if (++c >= 2) break; - } + if (is_ide && valid_ch) { + ide_log("Found IDE hard disk on channel %i\n", ch); + loadhd(ide_drives[ch], d, hdd[d].fn); + if (ide_drives[ch]->sector_buffer == NULL) + ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256 * 512); + memset(ide_drives[ch]->sector_buffer, 0, 256 * 512); + if (++c >= 2) + break; + } } ide_log("IDE: board %i: done, loaded %d disks.\n", board, c); for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; + c = (board << 1) + d; + dev = ide_drives[c]; - if (dev->type == IDE_NONE) - continue; + if (dev->type == IDE_NONE) + continue; - ide_allocate_buffer(dev); + ide_allocate_buffer(dev); - ide_set_signature(dev); + ide_set_signature(dev); - dev->mdma_mode = (1 << ide_get_max(dev, TYPE_PIO)); - dev->error = 1; - if (dev->type != IDE_HDD) - dev->cfg_spt = dev->cfg_hpc = 0; + dev->mdma_mode = (1 << ide_get_max(dev, TYPE_PIO)); + dev->error = 1; + if (dev->type != IDE_HDD) + dev->cfg_spt = dev->cfg_hpc = 0; } } - static void ide_board_init(int board, int irq, int base_main, int side_main, int type) { ide_log("ide_board_init(%i, %i, %04X, %04X, %i)\n", board, irq, base_main, side_main, type); if ((ide_boards[board] != NULL) && ide_boards[board]->inited) - return; + return; ide_log("IDE: Initializing board %i...\n", board); ide_boards[board] = (ide_board_t *) malloc(sizeof(ide_board_t)); memset(ide_boards[board], 0, sizeof(ide_board_t)); - ide_boards[board]->irq = irq; + ide_boards[board]->irq = irq; ide_boards[board]->cur_dev = board << 1; if (type & 6) - ide_boards[board]->bit32 = 1; + ide_boards[board]->bit32 = 1; ide_boards[board]->base_main = base_main; ide_boards[board]->side_main = side_main; ide_set_handlers(board); @@ -2879,60 +2817,57 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_boards[board]->inited = 1; } - void ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { intptr_t board = (intptr_t) priv; if (ld) - return; + return; if (ide_boards[board]->base_main || ide_boards[board]->side_main) { - ide_remove_handlers(board); - ide_boards[board]->base_main = ide_boards[board]->side_main = 0; + ide_remove_handlers(board); + ide_boards[board]->base_main = ide_boards[board]->side_main = 0; } ide_boards[board]->irq = -1; if (config->activate) { - ide_boards[board]->base_main = (config->io[0].base != ISAPNP_IO_DISABLED) ? config->io[0].base : 0x0000; - ide_boards[board]->side_main = (config->io[1].base != ISAPNP_IO_DISABLED) ? config->io[1].base : 0x0000; + ide_boards[board]->base_main = (config->io[0].base != ISAPNP_IO_DISABLED) ? config->io[0].base : 0x0000; + ide_boards[board]->side_main = (config->io[1].base != ISAPNP_IO_DISABLED) ? config->io[1].base : 0x0000; - if (ide_boards[board]->base_main && ide_boards[board]->side_main) - ide_set_handlers(board); + if (ide_boards[board]->base_main && ide_boards[board]->side_main) + ide_set_handlers(board); - if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) - ide_boards[board]->irq = config->irq[0].irq; + if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) + ide_boards[board]->irq = config->irq[0].irq; } } - static void * ide_ter_init(const device_t *info) { /* Don't claim this channel again if it was already claimed. */ if (ide_boards[2]) - return(NULL); + return (NULL); int irq; if (info->local) - irq = -2; + irq = -2; else - irq = device_get_config_int("irq"); + irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(2, -1, 0, 0, 0); - if (irq == -1) - isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); + ide_board_init(2, -1, 0, 0, 0); + if (irq == -1) + isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); } else { - 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. */ static void ide_ter_close(void *priv) @@ -2940,32 +2875,30 @@ ide_ter_close(void *priv) ide_board_close(2); } - static void * ide_qua_init(const device_t *info) { /* Don't claim this channel again if it was already claimed. */ if (ide_boards[3]) - return(NULL); + return (NULL); int irq; if (info->local) - irq = -2; + irq = -2; else - irq = device_get_config_int("irq"); + irq = device_get_config_int("irq"); if (irq < 0) { - ide_board_init(3, -1, 0, 0, 0); - if (irq == -1) - isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); + ide_board_init(3, -1, 0, 0, 0); + if (irq == -1) + isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); } else { - 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. */ static void ide_qua_close(void *priv) @@ -2973,7 +2906,6 @@ ide_qua_close(void *priv) ide_board_close(3); } - void * ide_xtide_init(void) { @@ -2982,78 +2914,73 @@ ide_xtide_init(void) return ide_boards[0]; } - void ide_xtide_close(void) { ide_board_close(0); } - void ide_set_bus_master(int board, - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), - void (*set_irq)(int channel, void *priv), void *priv) + int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), + void (*set_irq)(int channel, void *priv), void *priv) { if (ide_bm[board] == NULL) - ide_bm[board] = (ide_bm_t *) malloc(sizeof(ide_bm_t)); + ide_bm[board] = (ide_bm_t *) malloc(sizeof(ide_bm_t)); - ide_bm[board]->dma = dma; + ide_bm[board]->dma = dma; ide_bm[board]->set_irq = set_irq; - ide_bm[board]->priv = priv; + ide_bm[board]->priv = priv; } - static void * ide_init(const device_t *info) { ide_log("Initializing IDE...\n"); - switch(info->local) { - case 0: /* ISA, single-channel */ - case 1: /* ISA, dual-channel */ - case 2: /* VLB, single-channel */ - case 3: /* VLB, dual-channel */ - case 4: /* PCI, single-channel */ - case 5: /* PCI, dual-channel */ - ide_board_init(0, 14, 0x1f0, 0x3f6, info->local); + switch (info->local) { + case 0: /* ISA, single-channel */ + case 1: /* ISA, dual-channel */ + case 2: /* VLB, single-channel */ + case 3: /* VLB, dual-channel */ + case 4: /* PCI, single-channel */ + case 5: /* PCI, dual-channel */ + ide_board_init(0, 14, 0x1f0, 0x3f6, info->local); - if (info->local & 1) - ide_board_init(1, 15, 0x170, 0x376, info->local); - break; + if (info->local & 1) + ide_board_init(1, 15, 0x170, 0x376, info->local); + break; } - return(ide_drives); + return (ide_drives); } - static void ide_drive_reset(int d) { ide_log("Resetting IDE drive %i...\n", d); - ide_drives[d]->channel = d; - ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; - ide_drives[d]->service = 0; - ide_drives[d]->board = d >> 1; + ide_drives[d]->channel = d; + ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; + ide_drives[d]->service = 0; + ide_drives[d]->board = d >> 1; ide_drives[d]->selected = !(d & 1); timer_stop(&ide_drives[d]->timer); if (ide_boards[d >> 1]) { - ide_boards[d >> 1]->cur_dev = d & ~1; - timer_stop(&ide_boards[d >> 1]->timer); + ide_boards[d >> 1]->cur_dev = d & ~1; + timer_stop(&ide_boards[d >> 1]->timer); } ide_set_signature(ide_drives[d]); 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) - memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t)); + memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t)); } - static void ide_board_reset(int board) { @@ -3067,10 +2994,9 @@ ide_board_reset(int board) max = min + 2; for (d = min; d < max; d++) - ide_drive_reset(d); + ide_drive_reset(d); } - /* Reset a standalone IDE unit. */ static void ide_reset(void *p) @@ -3078,13 +3004,12 @@ ide_reset(void *p) ide_log("Resetting IDE...\n"); if (ide_boards[0] != NULL) - ide_board_reset(0); + ide_board_reset(0); if (ide_boards[1] != NULL) - ide_board_reset(1); + ide_board_reset(1); } - /* Close a standalone IDE unit. */ static void ide_close(void *priv) @@ -3092,98 +3017,98 @@ ide_close(void *priv) ide_log("Closing IDE...\n"); if (ide_boards[0] != NULL) { - ide_board_close(0); - ide_boards[0] = NULL; + ide_board_close(0); + ide_boards[0] = NULL; } if (ide_boards[1] != NULL) { - ide_board_close(1); - ide_boards[1] = NULL; + ide_board_close(1); + ide_boards[1] = NULL; } } const device_t ide_isa_device = { - .name = "ISA PC/AT IDE Controller", + .name = "ISA PC/AT IDE Controller", .internal_name = "ide_isa", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_isa_2ch_device = { - .name = "ISA PC/AT IDE Controller (Dual-Channel)", + .name = "ISA PC/AT IDE Controller (Dual-Channel)", .internal_name = "ide_isa_2ch", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_vlb_device = { - .name = "VLB IDE Controller", + .name = "VLB IDE Controller", .internal_name = "ide_vlb", - .flags = DEVICE_VLB | DEVICE_AT, - .local = 2, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_VLB | DEVICE_AT, + .local = 2, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_vlb_2ch_device = { - .name = "VLB IDE Controller (Dual-Channel)", + .name = "VLB IDE Controller (Dual-Channel)", .internal_name = "ide_vlb_2ch", - .flags = DEVICE_VLB | DEVICE_AT, - .local = 3, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_VLB | DEVICE_AT, + .local = 3, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_pci_device = { - .name = "PCI IDE Controller", + .name = "PCI IDE Controller", .internal_name = "ide_pci", - .flags = DEVICE_PCI | DEVICE_AT, - .local = 4, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_PCI | DEVICE_AT, + .local = 4, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_pci_2ch_device = { - .name = "PCI IDE Controller (Dual-Channel)", + .name = "PCI IDE Controller (Dual-Channel)", .internal_name = "ide_pci_2ch", - .flags = DEVICE_PCI | DEVICE_AT, - .local = 5, - .init = ide_init, - .close = ide_close, - .reset = ide_reset, + .flags = DEVICE_PCI | DEVICE_AT, + .local = 5, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; // clang-format off @@ -3241,57 +3166,57 @@ static const device_config_t ide_qua_config[] = { // clang-format on const device_t ide_ter_device = { - .name = "Tertiary IDE Controller", + .name = "Tertiary IDE Controller", .internal_name = "ide_ter", - .flags = DEVICE_AT, - .local = 0, - .init = ide_ter_init, - .close = ide_ter_close, - .reset = NULL, + .flags = DEVICE_AT, + .local = 0, + .init = ide_ter_init, + .close = ide_ter_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ide_ter_config + .force_redraw = NULL, + .config = ide_ter_config }; const device_t ide_ter_pnp_device = { - .name = "Tertiary IDE Controller (Plug and Play only)", + .name = "Tertiary IDE Controller (Plug and Play only)", .internal_name = "ide_ter_pnp", - .flags = DEVICE_AT, - .local = 1, - .init = ide_ter_init, - .close = ide_ter_close, - .reset = NULL, + .flags = DEVICE_AT, + .local = 1, + .init = ide_ter_init, + .close = ide_ter_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_qua_device = { - .name = "Quaternary IDE Controller", + .name = "Quaternary IDE Controller", .internal_name = "ide_qua", - .flags = DEVICE_AT, - .local = 0, - .init = ide_qua_init, - .close = ide_qua_close, - .reset = NULL, + .flags = DEVICE_AT, + .local = 0, + .init = ide_qua_init, + .close = ide_qua_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ide_qua_config + .force_redraw = NULL, + .config = ide_qua_config }; const device_t ide_qua_pnp_device = { - .name = "Quaternary IDE Controller (Plug and Play only)", + .name = "Quaternary IDE Controller (Plug and Play only)", .internal_name = "ide_qua_pnp", - .flags = DEVICE_AT, - .local = 1, - .init = ide_qua_init, - .close = ide_qua_close, - .reset = NULL, + .flags = DEVICE_AT, + .local = 1, + .init = ide_qua_init, + .close = ide_qua_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = ide_qua_config + .force_redraw = NULL, + .config = ide_qua_config }; diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 79c6e4f97..4cd323a88 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -37,20 +37,17 @@ #include <86box/zip.h> #include <86box/mo.h> - typedef struct { - uint8_t vlb_idx, id, - in_cfg, single_channel, - pci, regs[256]; - uint32_t local; - int slot, irq_mode[2], - irq_pin, irq_line; + uint8_t vlb_idx, id, + in_cfg, single_channel, + pci, regs[256]; + uint32_t local; + int slot, irq_mode[2], + irq_pin, irq_line; } cmd640_t; - -static int next_id = 0; - +static int next_id = 0; #ifdef ENABLE_CMD640_LOG int cmd640_do_log = ENABLE_CMD640_LOG; @@ -59,51 +56,48 @@ cmd640_log(const char *fmt, ...) { va_list ap; - if (cmd640_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + if (cmd640_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define cmd640_log(fmt, ...) +# define cmd640_log(fmt, ...) #endif - void cmd640_set_irq(int channel, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - int irq = !!(channel & 0x40); + int irq = !!(channel & 0x40); if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } } channel &= 0x01; if (irq) { - if (dev->irq_mode[channel] == 1) - pci_set_irq(dev->slot, dev->irq_pin); - else - picint(1 << (14 + channel)); + if (dev->irq_mode[channel] == 1) + pci_set_irq(dev->slot, dev->irq_pin); + else + picint(1 << (14 + channel)); } else { - if (dev->irq_mode[channel] == 1) - pci_clear_irq(dev->slot, dev->irq_pin); - else - picintc(1 << (14 + channel)); + if (dev->irq_mode[channel] == 1) + pci_clear_irq(dev->slot, dev->irq_pin); + else + picintc(1 << (14 + channel)); } } - static void cmd640_ide_handlers(cmd640_t *dev) { @@ -112,65 +106,67 @@ cmd640_ide_handlers(cmd640_t *dev) ide_pri_disable(); if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); - side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; + main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); + side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; } else { - main = 0x1f0; - side = 0x3f6; + main = 0x1f0; + side = 0x3f6; } ide_set_base(0, main); ide_set_side(0, side); if (dev->regs[0x04] & 0x01) - ide_pri_enable(); + ide_pri_enable(); if (dev->single_channel) - return; + return; ide_sec_disable(); if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); - side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; + main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); + side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; } else { - main = 0x170; - side = 0x376; + main = 0x170; + side = 0x376; } ide_set_base(1, main); ide_set_side(1, side); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) - ide_sec_enable(); + ide_sec_enable(); } - static void cmd640_common_write(int addr, uint8_t val, cmd640_t *dev) { switch (addr) { - case 0x51: - dev->regs[addr] = val; - cmd640_ide_handlers(dev); - break; - case 0x52: case 0x54: case 0x56: case 0x58: - case 0x59: - dev->regs[addr] = val; - break; - case 0x53: case 0x55: - dev->regs[addr] = val & 0xc0; - break; - case 0x57: - dev->regs[addr] = val & 0xdc; - break; - case 0x5b: /* Undocumented register that Linux attempts to use! */ - dev->regs[addr] = val; - break; + case 0x51: + dev->regs[addr] = val; + cmd640_ide_handlers(dev); + break; + case 0x52: + case 0x54: + case 0x56: + case 0x58: + case 0x59: + dev->regs[addr] = val; + break; + case 0x53: + case 0x55: + dev->regs[addr] = val & 0xc0; + break; + case 0x57: + dev->regs[addr] = val & 0xdc; + break; + case 0x5b: /* Undocumented register that Linux attempts to use! */ + dev->regs[addr] = val; + break; } } - static void cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv) { @@ -179,21 +175,20 @@ cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv) addr &= 0x00ff; switch (addr) { - case 0x0078: - if (dev->in_cfg) - dev->vlb_idx = val; - else if ((dev->regs[0x50] & 0x80) && (val == dev->id)) - dev->in_cfg = 1; - break; - case 0x007c: - cmd640_common_write(dev->vlb_idx, val, dev); - if (dev->regs[0x50] & 0x80) - dev->in_cfg = 0; - break; + case 0x0078: + if (dev->in_cfg) + dev->vlb_idx = val; + else if ((dev->regs[0x50] & 0x80) && (val == dev->id)) + dev->in_cfg = 1; + break; + case 0x007c: + cmd640_common_write(dev->vlb_idx, val, dev); + if (dev->regs[0x50] & 0x80) + dev->in_cfg = 0; + break; } } - static void cmd640_vlb_writew(uint16_t addr, uint16_t val, void *priv) { @@ -201,7 +196,6 @@ cmd640_vlb_writew(uint16_t addr, uint16_t val, void *priv) cmd640_vlb_write(addr + 1, val >> 8, priv); } - static void cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv) { @@ -209,35 +203,33 @@ cmd640_vlb_writel(uint16_t addr, uint32_t val, void *priv) cmd640_vlb_writew(addr + 2, val >> 16, priv); } - static uint8_t cmd640_vlb_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; cmd640_t *dev = (cmd640_t *) priv; addr &= 0x00ff; switch (addr) { - case 0x0078: - if (dev->in_cfg) - ret = dev->vlb_idx; - break; - case 0x007c: - ret = dev->regs[dev->vlb_idx]; - if (dev->vlb_idx == 0x50) - dev->regs[0x50] &= ~0x04; - else if (dev->vlb_idx == 0x57) - dev->regs[0x57] &= ~0x10; - if (dev->regs[0x50] & 0x80) - dev->in_cfg = 0; - break; + case 0x0078: + if (dev->in_cfg) + ret = dev->vlb_idx; + break; + case 0x007c: + ret = dev->regs[dev->vlb_idx]; + if (dev->vlb_idx == 0x50) + dev->regs[0x50] &= ~0x04; + else if (dev->vlb_idx == 0x57) + dev->regs[0x57] &= ~0x10; + if (dev->regs[0x50] & 0x80) + dev->in_cfg = 0; + break; } return ret; } - static uint16_t cmd640_vlb_readw(uint16_t addr, void *priv) { @@ -249,7 +241,6 @@ cmd640_vlb_readw(uint16_t addr, void *priv) return ret; } - static uint32_t cmd640_vlb_readl(uint16_t addr, void *priv) { @@ -261,7 +252,6 @@ cmd640_vlb_readl(uint16_t addr, void *priv) return ret; } - static void cmd640_pci_write(int func, int addr, uint8_t val, void *priv) { @@ -269,89 +259,89 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv) cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val); - if (func == 0x00) switch (addr) { - case 0x04: - dev->regs[addr] = (val & 0x41); - cmd640_ide_handlers(dev); - break; - case 0x07: - dev->regs[addr] &= ~(val & 0x80); - break; - case 0x09: - if ((dev->regs[addr] & 0x0a) == 0x0a) { - dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); - dev->irq_mode[0] = !!(val & 0x01); - dev->irq_mode[1] = !!(val & 0x04); - cmd640_ide_handlers(dev); - } - break; - case 0x10: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x10] = (val & 0xf8) | 1; - cmd640_ide_handlers(dev); - } - break; - case 0x11: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x11] = val; - cmd640_ide_handlers(dev); - } - break; - case 0x14: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x14] = (val & 0xfc) | 1; - cmd640_ide_handlers(dev); - } - break; - case 0x15: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x15] = val; - cmd640_ide_handlers(dev); - } - break; - case 0x18: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x18] = (val & 0xf8) | 1; - cmd640_ide_handlers(dev); - } - break; - case 0x19: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x19] = val; - cmd640_ide_handlers(dev); - } - break; - case 0x1c: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x1c] = (val & 0xfc) | 1; - cmd640_ide_handlers(dev); - } - break; - case 0x1d: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x1d] = val; - cmd640_ide_handlers(dev); - } - break; - default: - cmd640_common_write(addr, val, dev); - break; - } + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x41); + cmd640_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + break; + case 0x09: + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + cmd640_ide_handlers(dev); + } + break; + case 0x10: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = (val & 0xf8) | 1; + cmd640_ide_handlers(dev); + } + break; + case 0x11: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x11] = val; + cmd640_ide_handlers(dev); + } + break; + case 0x14: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x14] = (val & 0xfc) | 1; + cmd640_ide_handlers(dev); + } + break; + case 0x15: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x15] = val; + cmd640_ide_handlers(dev); + } + break; + case 0x18: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x18] = (val & 0xf8) | 1; + cmd640_ide_handlers(dev); + } + break; + case 0x19: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x19] = val; + cmd640_ide_handlers(dev); + } + break; + case 0x1c: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1c] = (val & 0xfc) | 1; + cmd640_ide_handlers(dev); + } + break; + case 0x1d: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1d] = val; + cmd640_ide_handlers(dev); + } + break; + default: + cmd640_common_write(addr, val, dev); + break; + } } - static uint8_t cmd640_pci_read(int func, int addr, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0xff; if (func == 0x00) { - ret = dev->regs[addr]; - if (addr == 0x50) - dev->regs[0x50] &= ~0x04; - else if (addr == 0x57) - dev->regs[0x57] &= ~0x10; + ret = dev->regs[addr]; + if (addr == 0x50) + dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; } cmd640_log("cmd640_pci_read(%i, %02X, %02X)\n", func, addr, ret); @@ -359,84 +349,83 @@ cmd640_pci_read(int func, int addr, void *priv) return ret; } - static void cmd640_reset(void *priv) { cmd640_t *dev = (cmd640_t *) priv; - int i = 0; + int i = 0; for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && - (cdrom[i].ide_channel < 4) && cdrom[i].priv) - scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && - (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); } - for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && - (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) - mo_reset((scsi_common_t *) mo_drives[i].priv); - } cmd640_set_irq(0x00, priv); cmd640_set_irq(0x01, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); - dev->regs[0x50] = 0x02; /* Revision 02 */ - dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + dev->regs[0x50] = 0x02; /* Revision 02 */ + dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ dev->regs[0x59] = 0x40; if (dev->pci) { - cmd640_log("dev->local = %08X\n", dev->local); - if ((dev->local & 0xffff) == 0x0a) { - dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; - If 0, they return 0 and are read-only 8 */ - } + cmd640_log("dev->local = %08X\n", dev->local); + if ((dev->local & 0xffff) == 0x0a) { + dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + } - dev->regs[0x00] = 0x95; /* CMD */ - dev->regs[0x01] = 0x10; - dev->regs[0x02] = 0x40; /* PCI-0640B */ - dev->regs[0x03] = 0x06; - dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ - dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ - dev->regs[0x08] = 0x02; /* Revision 02 */ - dev->regs[0x09] = dev->local; /* Programming interface */ - dev->regs[0x0a] = 0x01; /* IDE controller */ - dev->regs[0x0b] = 0x01; /* Mass storage controller */ + dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x40; /* PCI-0640B */ + dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* Revision 02 */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ - /* Base addresses (1F0, 3F4, 170, 374) */ - if (dev->regs[0x50] & 0x40) { - dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; - dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; - dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; - dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; - } + /* Base addresses (1F0, 3F4, 170, 374) */ + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = 0xf1; + dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; + dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; + dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; + dev->regs[0x1d] = 0x03; + } - dev->regs[0x3c] = 0x14; /* IRQ 14 */ - dev->regs[0x3d] = 0x01; /* INTA */ + dev->regs[0x3c] = 0x14; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ - dev->irq_mode[0] = dev->irq_mode[1] = 0; - dev->irq_pin = PCI_INTA; - dev->irq_line = 14; + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + dev->irq_line = 14; } else { - if ((dev->local & 0xffff) == 0x0078) - dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ + if ((dev->local & 0xffff) == 0x0078) + dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ - /* If bit 7 is 1, then device ID has to be written on port x78h before - accessing the configuration registers */ - dev->in_cfg = 1; /* Configuration registers are accessible */ + /* If bit 7 is 1, then device ID has to be written on port x78h before + accessing the configuration registers */ + dev->in_cfg = 1; /* Configuration registers are accessible */ } cmd640_ide_handlers(dev); } - static void cmd640_close(void *priv) { @@ -447,7 +436,6 @@ cmd640_close(void *priv) next_id = 0; } - static void * cmd640_init(const device_t *info) { @@ -456,30 +444,30 @@ cmd640_init(const device_t *info) dev->id = next_id | 0x60; - dev->pci = !!(info->flags & DEVICE_PCI); + dev->pci = !!(info->flags & DEVICE_PCI); dev->local = info->local; if (info->flags & DEVICE_PCI) { - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_2ch_device); - dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); + dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); - ide_set_bus_master(0, NULL, cmd640_set_irq, dev); - ide_set_bus_master(1, NULL, cmd640_set_irq, dev); + ide_set_bus_master(0, NULL, cmd640_set_irq, dev); + ide_set_bus_master(1, NULL, cmd640_set_irq, dev); - /* The CMD PCI-0640B IDE controller has no DMA capability, - so set our devices IDE devices to force ATA-3 (no DMA). */ - ide_board_set_force_ata3(0, 1); - ide_board_set_force_ata3(1, 1); + /* The CMD PCI-0640B IDE controller has no DMA capability, + so set our devices IDE devices to force ATA-3 (no DMA). */ + ide_board_set_force_ata3(0, 1); + ide_board_set_force_ata3(1, 1); - // ide_pri_disable(); + // ide_pri_disable(); } else if (info->flags & DEVICE_VLB) { - device_add(&ide_vlb_2ch_device); + device_add(&ide_vlb_2ch_device); - io_sethandler(info->local & 0xffff, 0x0008, - cmd640_vlb_read, cmd640_vlb_readw, cmd640_vlb_readl, - cmd640_vlb_write, cmd640_vlb_writew, cmd640_vlb_writel, - dev); + io_sethandler(info->local & 0xffff, 0x0008, + cmd640_vlb_read, cmd640_vlb_readw, cmd640_vlb_readl, + cmd640_vlb_write, cmd640_vlb_writew, cmd640_vlb_writel, + dev); } dev->single_channel = !!(info->local & 0x20000); @@ -492,71 +480,71 @@ cmd640_init(const device_t *info) } const device_t ide_cmd640_vlb_device = { - .name = "CMD PCI-0640B VLB", + .name = "CMD PCI-0640B VLB", .internal_name = "ide_cmd640_vlb", - .flags = DEVICE_VLB, - .local = 0x0078, - .init = cmd640_init, - .close = cmd640_close, - .reset = cmd640_reset, + .flags = DEVICE_VLB, + .local = 0x0078, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd640_vlb_178_device = { - .name = "CMD PCI-0640B VLB (Port 178h)", + .name = "CMD PCI-0640B VLB (Port 178h)", .internal_name = "ide_cmd640_vlb_178", - .flags = DEVICE_VLB, - .local = 0x0178, - .init = cmd640_init, - .close = cmd640_close, - .reset = cmd640_reset, + .flags = DEVICE_VLB, + .local = 0x0178, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd640_pci_device = { - .name = "CMD PCI-0640B PCI", + .name = "CMD PCI-0640B PCI", .internal_name = "ide_cmd640_pci", - .flags = DEVICE_PCI, - .local = 0x0a, - .init = cmd640_init, - .close = cmd640_close, - .reset = cmd640_reset, + .flags = DEVICE_PCI, + .local = 0x0a, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd640_pci_legacy_only_device = { - .name = "CMD PCI-0640B PCI (Legacy Mode Only)", + .name = "CMD PCI-0640B PCI (Legacy Mode Only)", .internal_name = "ide_cmd640_pci_legacy_only", - .flags = DEVICE_PCI, - .local = 0x00, - .init = cmd640_init, - .close = cmd640_close, - .reset = cmd640_reset, + .flags = DEVICE_PCI, + .local = 0x00, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd640_pci_single_channel_device = { - .name = "CMD PCI-0640B PCI", + .name = "CMD PCI-0640B PCI", .internal_name = "ide_cmd640_pci_single_channel", - .flags = DEVICE_PCI, - .local = 0x2000a, - .init = cmd640_init, - .close = cmd640_close, - .reset = cmd640_reset, + .flags = DEVICE_PCI, + .local = 0x2000a, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index da721f3b6..d03474af5 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -37,18 +37,16 @@ #include <86box/zip.h> #include <86box/mo.h> - typedef struct { - uint8_t vlb_idx, single_channel, - in_cfg, regs[256]; - uint32_t local; - int slot, irq_mode[2], - irq_pin; - sff8038i_t *bm[2]; + uint8_t vlb_idx, single_channel, + in_cfg, regs[256]; + uint32_t local; + int slot, irq_mode[2], + irq_pin; + sff8038i_t *bm[2]; } cmd646_t; - #ifdef ENABLE_CMD646_LOG int cmd646_do_log = ENABLE_CMD646_LOG; static void @@ -56,39 +54,36 @@ cmd646_log(const char *fmt, ...) { va_list ap; - if (cmd646_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + if (cmd646_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define cmd646_log(fmt, ...) +# define cmd646_log(fmt, ...) #endif - static void cmd646_set_irq(int channel, void *priv) { cmd646_t *dev = (cmd646_t *) priv; if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } } sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); } - static int cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) { @@ -97,63 +92,60 @@ cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); } - static void cmd646_ide_handlers(cmd646_t *dev) { uint16_t main, side; - int irq_mode[2] = { 0, 0 }; + int irq_mode[2] = { 0, 0 }; ide_pri_disable(); if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); - side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; + main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); + side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; } else { - main = 0x1f0; - side = 0x3f6; + main = 0x1f0; + side = 0x3f6; } ide_set_base(0, main); ide_set_side(0, side); if (dev->regs[0x09] & 0x01) - irq_mode[0] = 1; + irq_mode[0] = 1; sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); if (dev->regs[0x04] & 0x01) - ide_pri_enable(); + ide_pri_enable(); if (dev->single_channel) - return; + return; ide_sec_disable(); if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); - side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; + main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); + side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; } else { - main = 0x170; - side = 0x376; + main = 0x170; + side = 0x376; } ide_set_base(1, main); ide_set_side(1, side); if (dev->regs[0x09] & 0x04) - irq_mode[1] = 1; + irq_mode[1] = 1; sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) - ide_sec_enable(); - + ide_sec_enable(); } - static void cmd646_ide_bm_handlers(cmd646_t *dev) { @@ -163,7 +155,6 @@ cmd646_ide_bm_handlers(cmd646_t *dev) sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); } - static void cmd646_pci_write(int func, int addr, uint8_t val, void *priv) { @@ -171,119 +162,124 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); - if (func == 0x00) switch (addr) { - case 0x04: - dev->regs[addr] = (val & 0x45); - cmd646_ide_handlers(dev); - break; - case 0x07: - dev->regs[addr] &= ~(val & 0xb1); - break; - case 0x09: - if ((dev->regs[addr] & 0x0a) == 0x0a) { - dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); - dev->irq_mode[0] = !!(val & 0x01); - dev->irq_mode[1] = !!(val & 0x04); - cmd646_ide_handlers(dev); - } - break; - case 0x10: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x10] = (val & 0xf8) | 1; - cmd646_ide_handlers(dev); - } - break; - case 0x11: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x11] = val; - cmd646_ide_handlers(dev); - } - break; - case 0x14: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x14] = (val & 0xfc) | 1; - cmd646_ide_handlers(dev); - } - break; - case 0x15: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x15] = val; - cmd646_ide_handlers(dev); - } - break; - case 0x18: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x18] = (val & 0xf8) | 1; - cmd646_ide_handlers(dev); - } - break; - case 0x19: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x19] = val; - cmd646_ide_handlers(dev); - } - break; - case 0x1c: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x1c] = (val & 0xfc) | 1; - cmd646_ide_handlers(dev); - } - break; - case 0x1d: - if (dev->regs[0x50] & 0x40) { - dev->regs[0x1d] = val; - cmd646_ide_handlers(dev); - } - break; - case 0x20: - dev->regs[0x20] = (val & 0xf0) | 1; - cmd646_ide_bm_handlers(dev); - break; - case 0x21: - dev->regs[0x21] = val; - cmd646_ide_bm_handlers(dev); - break; - case 0x51: - dev->regs[addr] = val & 0xc8; - cmd646_ide_handlers(dev); - break; - case 0x52: case 0x54: case 0x56: case 0x58: - case 0x59: case 0x5b: - dev->regs[addr] = val; - break; - case 0x53: case 0x55: - dev->regs[addr] = val & 0xc0; - break; - case 0x57: - dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc); - break; - case 0x70 ... 0x77: - sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); - break; - case 0x78 ... 0x7f: - sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); - break; - } + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x45); + cmd646_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0xb1); + break; + case 0x09: + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + cmd646_ide_handlers(dev); + } + break; + case 0x10: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x11: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x11] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x14: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x14] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x15: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x15] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x18: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x18] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x19: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x19] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x1c: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1c] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x1d: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1d] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x20: + dev->regs[0x20] = (val & 0xf0) | 1; + cmd646_ide_bm_handlers(dev); + break; + case 0x21: + dev->regs[0x21] = val; + cmd646_ide_bm_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0xc8; + cmd646_ide_handlers(dev); + break; + case 0x52: + case 0x54: + case 0x56: + case 0x58: + case 0x59: + case 0x5b: + dev->regs[addr] = val; + break; + case 0x53: + case 0x55: + dev->regs[addr] = val & 0xc0; + break; + case 0x57: + dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc); + break; + case 0x70 ... 0x77: + sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); + break; + case 0x78 ... 0x7f: + sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); + break; + } } - static uint8_t cmd646_pci_read(int func, int addr, void *priv) { cmd646_t *dev = (cmd646_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0xff; if (func == 0x00) { - ret = dev->regs[addr]; + ret = dev->regs[addr]; - if (addr == 0x50) - dev->regs[0x50] &= ~0x04; - else if (addr == 0x57) - dev->regs[0x57] &= ~0x10; - else if ((addr >= 0x70) && (addr <= 0x77)) - ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); - else if ((addr >= 0x78) && (addr <= 0x7f)) - ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + if (addr == 0x50) + dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; + else if ((addr >= 0x70) && (addr <= 0x77)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + else if ((addr >= 0x78) && (addr <= 0x7f)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); } cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret); @@ -291,77 +287,76 @@ cmd646_pci_read(int func, int addr, void *priv) return ret; } - static void cmd646_reset(void *priv) { cmd646_t *dev = (cmd646_t *) priv; - int i = 0; + int i = 0; for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && - (cdrom[i].ide_channel < 4) && cdrom[i].priv) - scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && - (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); } - for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && - (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) - mo_reset((scsi_common_t *) mo_drives[i].priv); - } cmd646_set_irq(0x00, priv); cmd646_set_irq(0x01, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); - dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x00] = 0x95; /* CMD */ dev->regs[0x01] = 0x10; - dev->regs[0x02] = 0x46; /* PCI-0646 */ + dev->regs[0x02] = 0x46; /* PCI-0646 */ dev->regs[0x03] = 0x06; dev->regs[0x04] = 0x00; dev->regs[0x06] = 0x80; - dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ - dev->regs[0x09] = dev->local; /* Programming interface */ - dev->regs[0x0a] = 0x01; /* IDE controller */ - dev->regs[0x0b] = 0x01; /* Mass storage controller */ + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ if ((dev->local & 0xffff) == 0x8a) { - dev->regs[0x50] = 0x40; /* Enable Base address register R/W; - If 0, they return 0 and are read-only 8 */ + dev->regs[0x50] = 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ - /* Base addresses (1F0, 3F4, 170, 374) */ - dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; - dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; - dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; - dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; + /* Base addresses (1F0, 3F4, 170, 374) */ + dev->regs[0x10] = 0xf1; + dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; + dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; + dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; + dev->regs[0x1d] = 0x03; } dev->regs[0x20] = 0x01; - dev->regs[0x3c] = 0x0e; /* IRQ 14 */ - dev->regs[0x3d] = 0x01; /* INTA */ - dev->regs[0x3e] = 0x02; /* Min_Gnt */ - dev->regs[0x3f] = 0x04; /* Max_Iat */ + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + dev->regs[0x3e] = 0x02; /* Min_Gnt */ + dev->regs[0x3f] = 0x04; /* Max_Iat */ if (!dev->single_channel) - dev->regs[0x51] = 0x08; + dev->regs[0x51] = 0x08; dev->regs[0x57] = 0x0c; dev->regs[0x59] = 0x40; dev->irq_mode[0] = dev->irq_mode[1] = 0; - dev->irq_pin = PCI_INTA; + dev->irq_pin = PCI_INTA; cmd646_ide_handlers(dev); cmd646_ide_bm_handlers(dev); } - static void cmd646_close(void *priv) { @@ -370,7 +365,6 @@ cmd646_close(void *priv) free(dev); } - static void * cmd646_init(const device_t *info) { @@ -387,18 +381,18 @@ cmd646_init(const device_t *info) dev->bm[0] = device_add_inst(&sff8038i_device, 1); if (!dev->single_channel) - dev->bm[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); if (!dev->single_channel) - ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); sff_set_irq_mode(dev->bm[0], 0, 0); sff_set_irq_mode(dev->bm[0], 1, 0); if (!dev->single_channel) { - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[1], 1, 0); } cmd646_reset(dev); @@ -407,43 +401,43 @@ cmd646_init(const device_t *info) } const device_t ide_cmd646_device = { - .name = "CMD PCI-0646", + .name = "CMD PCI-0646", .internal_name = "ide_cmd646", - .flags = DEVICE_PCI, - .local = 0x8a, - .init = cmd646_init, - .close = cmd646_close, - .reset = cmd646_reset, + .flags = DEVICE_PCI, + .local = 0x8a, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd646_legacy_only_device = { - .name = "CMD PCI-0646 (Legacy Mode Only)", + .name = "CMD PCI-0646 (Legacy Mode Only)", .internal_name = "ide_cmd646_legacy_only", - .flags = DEVICE_PCI, - .local = 0x80, - .init = cmd646_init, - .close = cmd646_close, - .reset = cmd646_reset, + .flags = DEVICE_PCI, + .local = 0x80, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ide_cmd646_single_channel_device = { - .name = "CMD PCI-0646", + .name = "CMD PCI-0646", .internal_name = "ide_cmd646_single_channel", - .flags = DEVICE_PCI, - .local = 0x2008a, - .init = cmd646_init, - .close = cmd646_close, - .reset = cmd646_reset, + .flags = DEVICE_PCI, + .local = 0x2008a, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_ide_opti611.c b/src/disk/hdc_ide_opti611.c index 9a6bd9cd4..d01f422bc 100644 --- a/src/disk/hdc_ide_opti611.c +++ b/src/disk/hdc_ide_opti611.c @@ -29,17 +29,14 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> - typedef struct { - uint8_t tries, - in_cfg, cfg_locked, - regs[19]; + uint8_t tries, + in_cfg, cfg_locked, + regs[19]; } opti611_t; - -static void opti611_ide_handler(opti611_t *dev); - +static void opti611_ide_handler(opti611_t *dev); static void opti611_cfg_write(uint16_t addr, uint8_t val, void *priv) @@ -49,32 +46,31 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv) addr &= 0x0007; switch (addr) { - case 0x0000: - case 0x0001: - dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr] = val; - break; - case 0x0002: - dev->regs[0x12] = (val & 0xc1) | 0x02; - if (val & 0xc0) { - if (val & 0x40) - dev->cfg_locked = 1; - dev->in_cfg = 0; - opti611_ide_handler(dev); - } - break; - case 0x0003: - dev->regs[0x03] = (val & 0xdf); - break; - case 0x0005: - dev->regs[0x05] = (dev->regs[0x05] & 0x78) | (val & 0x87); - break; - case 0x0006: - dev->regs[0x06] = val; - break; + case 0x0000: + case 0x0001: + dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr] = val; + break; + case 0x0002: + dev->regs[0x12] = (val & 0xc1) | 0x02; + if (val & 0xc0) { + if (val & 0x40) + dev->cfg_locked = 1; + dev->in_cfg = 0; + opti611_ide_handler(dev); + } + break; + case 0x0003: + dev->regs[0x03] = (val & 0xdf); + break; + case 0x0005: + dev->regs[0x05] = (dev->regs[0x05] & 0x78) | (val & 0x87); + break; + case 0x0006: + dev->regs[0x06] = val; + break; } } - static void opti611_cfg_writew(uint16_t addr, uint16_t val, void *priv) { @@ -82,7 +78,6 @@ opti611_cfg_writew(uint16_t addr, uint16_t val, void *priv) opti611_cfg_write(addr + 1, val >> 8, priv); } - static void opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv) { @@ -90,34 +85,35 @@ opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv) opti611_cfg_writew(addr + 2, val >> 16, priv); } - static uint8_t opti611_cfg_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; opti611_t *dev = (opti611_t *) priv; addr &= 0x0007; switch (addr) { - case 0x0000: - case 0x0001: - ret = dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr]; - break; - case 0x0002: - ret = ((!!in_smm) << 7); - if (ret & 0x80) - ret |= (dev->regs[addr] & 0x7f); - break; - case 0x0003: case 0x0004: case 0x0005: case 0x0006: - ret = dev->regs[addr]; - break; + case 0x0000: + case 0x0001: + ret = dev->regs[((dev->regs[0x06] & 0x01) << 4) + addr]; + break; + case 0x0002: + ret = ((!!in_smm) << 7); + if (ret & 0x80) + ret |= (dev->regs[addr] & 0x7f); + break; + case 0x0003: + case 0x0004: + case 0x0005: + case 0x0006: + ret = dev->regs[addr]; + break; } return ret; } - static uint16_t opti611_cfg_readw(uint16_t addr, void *priv) { @@ -129,7 +125,6 @@ opti611_cfg_readw(uint16_t addr, void *priv) return ret; } - static uint32_t opti611_cfg_readl(uint16_t addr, void *priv) { @@ -141,7 +136,6 @@ opti611_cfg_readl(uint16_t addr, void *priv) return ret; } - static void opti611_ide_write(uint16_t addr, uint8_t val, void *priv) { @@ -152,13 +146,12 @@ opti611_ide_write(uint16_t addr, uint8_t val, void *priv) uint8_t smibe = (addr & 0x0003); if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | smibe; - dev->regs[0x04] = val; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | smibe; + dev->regs[0x04] = val; } } - static void opti611_ide_writew(uint16_t addr, uint16_t val, void *priv) { @@ -169,13 +162,12 @@ opti611_ide_writew(uint16_t addr, uint16_t val, void *priv) uint8_t smibe = (addr & 0x0002) | 0x0001; if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | smibe; - dev->regs[0x04] = 0x00; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | smibe; + dev->regs[0x04] = 0x00; } } - static void opti611_ide_writel(uint16_t addr, uint32_t val, void *priv) { @@ -185,13 +177,12 @@ opti611_ide_writel(uint16_t addr, uint32_t val, void *priv) uint8_t smia2 = (!!(addr & 0x0004)) << 4; if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | 0x0003; - dev->regs[0x04] = 0x00; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | 0x0003; + dev->regs[0x04] = 0x00; } } - static uint8_t opti611_ide_read(uint16_t addr, void *priv) { @@ -202,15 +193,14 @@ opti611_ide_read(uint16_t addr, void *priv) uint8_t smibe = (addr & 0x0003); if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | smibe; - dev->regs[0x04] = 0x00; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | smibe; + dev->regs[0x04] = 0x00; } return 0xff; } - static uint16_t opti611_ide_readw(uint16_t addr, void *priv) { @@ -221,23 +211,22 @@ opti611_ide_readw(uint16_t addr, void *priv) uint8_t smibe = (addr & 0x0002) | 0x0001; if ((addr & 0x0007) == 0x0001) { - dev->tries = (dev->tries + 1) & 0x01; - if ((dev->tries == 0x00) && !dev->cfg_locked) { - dev->in_cfg = 1; - opti611_ide_handler(dev); - } + dev->tries = (dev->tries + 1) & 0x01; + if ((dev->tries == 0x00) && !dev->cfg_locked) { + dev->in_cfg = 1; + opti611_ide_handler(dev); + } } if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | smibe; - dev->regs[0x04] = 0x00; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | smibe; + dev->regs[0x04] = 0x00; } return 0xffff; } - static uint32_t opti611_ide_readl(uint16_t addr, void *priv) { @@ -247,44 +236,42 @@ opti611_ide_readl(uint16_t addr, void *priv) uint8_t smia2 = (!!(addr & 0x0004)) << 4; if (dev->regs[0x03] & 0x02) { - smi_raise(); - dev->regs[0x02] = smia9 | smia2 | 0x0003; - dev->regs[0x04] = 0x00; + smi_raise(); + dev->regs[0x02] = smia9 | smia2 | 0x0003; + dev->regs[0x04] = 0x00; } return 0xffffffff; } - static void opti611_ide_handler(opti611_t *dev) { ide_pri_disable(); io_removehandler(0x01f0, 0x0007, - opti611_ide_read, opti611_ide_readw, opti611_ide_readl, - opti611_ide_write, opti611_ide_writew, opti611_ide_writel, - dev); + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); io_removehandler(0x01f0, 0x0007, - opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, - opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, - dev); + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); if (dev->in_cfg && !dev->cfg_locked) { - io_sethandler(0x01f0, 0x0007, - opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, - opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, - dev); + io_sethandler(0x01f0, 0x0007, + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); } else { - if (dev->regs[0x03] & 0x01) - ide_pri_enable(); - io_sethandler(0x01f0, 0x0007, - opti611_ide_read, opti611_ide_readw, opti611_ide_readl, - opti611_ide_write, opti611_ide_writew, opti611_ide_writel, - dev); + if (dev->regs[0x03] & 0x01) + ide_pri_enable(); + io_sethandler(0x01f0, 0x0007, + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); } } - static void opti611_close(void *priv) { @@ -293,7 +280,6 @@ opti611_close(void *priv) free(dev); } - static void * opti611_init(const device_t *info) { @@ -312,15 +298,15 @@ opti611_init(const device_t *info) } const device_t ide_opti611_vlb_device = { - .name = "OPTi 82C611/82C611A VLB", + .name = "OPTi 82C611/82C611A VLB", .internal_name = "ide_opti611_vlb", - .flags = DEVICE_VLB, - .local = 0, - .init = opti611_init, - .close = opti611_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = 0, + .init = opti611_init, + .close = opti611_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index f15cc6dcb..5ce71325e 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -43,75 +43,68 @@ #include <86box/zip.h> #include <86box/mo.h> +static int next_id = 0; -static int next_id = 0; - - -uint8_t sff_bus_master_read(uint16_t port, void *priv); -static uint16_t sff_bus_master_readw(uint16_t port, void *priv); -static uint32_t sff_bus_master_readl(uint16_t port, void *priv); -void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); -static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv); -static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv); - +uint8_t sff_bus_master_read(uint16_t port, void *priv); +static uint16_t sff_bus_master_readw(uint16_t port, void *priv); +static uint32_t sff_bus_master_readl(uint16_t port, void *priv); +void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); +static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv); +static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv); #ifdef ENABLE_SFF_LOG int sff_do_log = ENABLE_SFF_LOG; - static void sff_log(const char *fmt, ...) { va_list ap; if (sff_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sff_log(fmt, ...) +# define sff_log(fmt, ...) #endif - void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base) { if (dev->base != 0x0000) { - io_removehandler(dev->base, 0x08, - sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, - sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, - dev); + io_removehandler(dev->base, 0x08, + sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, + sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, + dev); } if (enabled && (base != 0x0000)) { - io_sethandler(base, 0x08, - sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, - sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, - dev); + io_sethandler(base, 0x08, + sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, + sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, + dev); } dev->enabled = enabled; - dev->base = base; + dev->base = base; } - static void sff_bus_master_next_addr(sff8038i_t *dev) { - dma_bm_read(dev->ptr_cur, (uint8_t *)&(dev->addr), 4, 4); - dma_bm_read(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4, 4); + dma_bm_read(dev->ptr_cur, (uint8_t *) &(dev->addr), 4, 4); + dma_bm_read(dev->ptr_cur + 4, (uint8_t *) &(dev->count), 4, 4); sff_log("SFF-8038i Bus master DWORDs: %08X %08X\n", dev->addr, dev->count); dev->eot = dev->count >> 31; dev->count &= 0xfffe; if (!dev->count) - dev->count = 65536; + dev->count = 65536; dev->addr &= 0xfffffffe; dev->ptr_cur += 8; } - void sff_bus_master_write(uint16_t port, uint8_t val, void *priv) { @@ -123,54 +116,53 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv) sff_log("SFF-8038i Bus master BYTE write: %04X %02X\n", port, val); switch (port & 7) { - case 0: - sff_log("sff Cmd : val = %02X, old = %02X\n", val, dev->command); - if ((val & 1) && !(dev->command & 1)) { /*Start*/ - sff_log("sff Bus Master start on channel %i\n", channel); - dev->ptr_cur = dev->ptr; - sff_bus_master_next_addr(dev); - dev->status |= 1; - } - if (!(val & 1) && (dev->command & 1)) { /*Stop*/ - sff_log("sff Bus Master stop on channel %i\n", channel); - dev->status &= ~1; - } + case 0: + sff_log("sff Cmd : val = %02X, old = %02X\n", val, dev->command); + if ((val & 1) && !(dev->command & 1)) { /*Start*/ + sff_log("sff Bus Master start on channel %i\n", channel); + dev->ptr_cur = dev->ptr; + sff_bus_master_next_addr(dev); + dev->status |= 1; + } + if (!(val & 1) && (dev->command & 1)) { /*Stop*/ + sff_log("sff Bus Master stop on channel %i\n", channel); + dev->status &= ~1; + } - dev->command = val; - break; - case 1: - dev->dma_mode = val & 0x03; - break; - case 2: - sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status); - dev->status &= 0x07; - dev->status |= (val & 0x60); - if (val & 0x04) - dev->status &= ~0x04; - if (val & 0x02) - dev->status &= ~0x02; - break; - case 4: - dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val; - break; - case 5: - dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8); - dev->ptr %= (mem_size * 1024); - break; - case 6: - dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; - case 7: - dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); - dev->ptr %= (mem_size * 1024); - break; + dev->command = val; + break; + case 1: + dev->dma_mode = val & 0x03; + break; + case 2: + sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status); + dev->status &= 0x07; + dev->status |= (val & 0x60); + if (val & 0x04) + dev->status &= ~0x04; + if (val & 0x02) + dev->status &= ~0x02; + break; + case 4: + dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val; + break; + case 5: + dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8); + dev->ptr %= (mem_size * 1024); + break; + case 6: + dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16); + dev->ptr %= (mem_size * 1024); + break; + case 7: + dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); + dev->ptr %= (mem_size * 1024); + break; } } - static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv) { @@ -179,24 +171,23 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv) sff_log("SFF-8038i Bus master WORD write: %04X %04X\n", port, val); switch (port & 7) { - case 0: - case 1: - case 2: - sff_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; - case 6: - dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; + case 0: + case 1: + case 2: + sff_bus_master_write(port, val & 0xff, priv); + break; + case 4: + dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val & 0xff; + break; + case 6: + dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); + dev->ptr %= (mem_size * 1024); + break; } } - static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) { @@ -205,20 +196,19 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) sff_log("SFF-8038i Bus master DWORD write: %04X %08X\n", port, val); switch (port & 7) { - case 0: - case 1: - case 2: - sff_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (val & 0xfffffffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; + case 0: + case 1: + case 2: + sff_bus_master_write(port, val & 0xff, priv); + break; + case 4: + dev->ptr = (val & 0xfffffffc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val & 0xff; + break; } } - uint8_t sff_bus_master_read(uint16_t port, void *priv) { @@ -227,27 +217,27 @@ sff_bus_master_read(uint16_t port, void *priv) uint8_t ret = 0xff; switch (port & 7) { - case 0: - ret = dev->command; - break; - case 1: - ret = dev->dma_mode & 0x03; - break; - case 2: - ret = dev->status & 0x67; - break; - case 4: - ret = dev->ptr0; - break; - case 5: - ret = dev->ptr >> 8; - break; - case 6: - ret = dev->ptr >> 16; - break; - case 7: - ret = dev->ptr >> 24; - break; + case 0: + ret = dev->command; + break; + case 1: + ret = dev->dma_mode & 0x03; + break; + case 2: + ret = dev->status & 0x67; + break; + case 4: + ret = dev->ptr0; + break; + case 5: + ret = dev->ptr >> 8; + break; + case 6: + ret = dev->ptr >> 16; + break; + case 7: + ret = dev->ptr >> 24; + break; } sff_log("SFF-8038i Bus master BYTE read : %04X %02X\n", port, ret); @@ -255,7 +245,6 @@ sff_bus_master_read(uint16_t port, void *priv) return ret; } - static uint16_t sff_bus_master_readw(uint16_t port, void *priv) { @@ -264,17 +253,17 @@ sff_bus_master_readw(uint16_t port, void *priv) uint16_t ret = 0xffff; switch (port & 7) { - case 0: - case 1: - case 2: - ret = (uint16_t) sff_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xff00); - break; - case 6: - ret = dev->ptr >> 16; - break; + case 0: + case 1: + case 2: + ret = (uint16_t) sff_bus_master_read(port, priv); + break; + case 4: + ret = dev->ptr0 | (dev->ptr & 0xff00); + break; + case 6: + ret = dev->ptr >> 16; + break; } sff_log("SFF-8038i Bus master WORD read : %04X %04X\n", port, ret); @@ -282,7 +271,6 @@ sff_bus_master_readw(uint16_t port, void *priv) return ret; } - static uint32_t sff_bus_master_readl(uint16_t port, void *priv) { @@ -291,14 +279,14 @@ sff_bus_master_readl(uint16_t port, void *priv) uint32_t ret = 0xffffffff; switch (port & 7) { - case 0: - case 1: - case 2: - ret = (uint32_t) sff_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xffffff00); - break; + case 0: + case 1: + case 2: + ret = (uint32_t) sff_bus_master_read(port, priv); + break; + case 4: + ret = dev->ptr0 | (dev->ptr & 0xffffff00); + break; } sff_log("sff Bus master DWORD read : %04X %08X\n", port, ret); @@ -306,7 +294,6 @@ sff_bus_master_readl(uint16_t port, void *priv) return ret; } - int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) { @@ -322,141 +309,138 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi #endif if (!(dev->status & 1)) { - sff_log("DMA disabled\n"); - return 2; /*DMA disabled*/ + sff_log("DMA disabled\n"); + return 2; /*DMA disabled*/ } sff_log("SFF-8038i Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length); while (1) { - if (dev->count <= transfer_length) { - sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr); - if (out) - dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4); - else - dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4); - transfer_length -= dev->count; - buffer_pos += dev->count; - } else { - sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr); - if (out) - dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4); - else - dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4); - /* Increase addr and decrease count so that resumed transfers do not mess up. */ - dev->addr += transfer_length; - dev->count -= transfer_length; - transfer_length = 0; - force_end = 1; - } + if (dev->count <= transfer_length) { + sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr); + if (out) + dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4); + else + dma_bm_write(dev->addr, (uint8_t *) (data + buffer_pos), dev->count, 4); + transfer_length -= dev->count; + buffer_pos += dev->count; + } else { + sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr); + if (out) + dma_bm_read(dev->addr, (uint8_t *) (data + buffer_pos), transfer_length, 4); + else + dma_bm_write(dev->addr, (uint8_t *) (data + buffer_pos), transfer_length, 4); + /* Increase addr and decrease count so that resumed transfers do not mess up. */ + dev->addr += transfer_length; + dev->count -= transfer_length; + transfer_length = 0; + force_end = 1; + } - if (force_end) { - sff_log("Total transfer length smaller than sum of all blocks, partial block\n"); - dev->status &= ~2; - return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */ - } else { - if (!transfer_length && !dev->eot) { - sff_log("Total transfer length smaller than sum of all blocks, full block\n"); - dev->status &= ~2; - return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */ - } else if (transfer_length && dev->eot) { - sff_log("Total transfer length greater than sum of all blocks\n"); - dev->status |= 2; - return 0; /* There is data left to transfer but we have reached EOT - return with error. */ - } else if (dev->eot) { - sff_log("Regular EOT\n"); - dev->status &= ~3; - return 1; /* We have regularly reached EOT - clear status and break. */ - } else { - /* We have more to transfer and there are blocks left, get next block. */ - sff_bus_master_next_addr(dev); - } - } + if (force_end) { + sff_log("Total transfer length smaller than sum of all blocks, partial block\n"); + dev->status &= ~2; + return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */ + } else { + if (!transfer_length && !dev->eot) { + sff_log("Total transfer length smaller than sum of all blocks, full block\n"); + dev->status &= ~2; + return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */ + } else if (transfer_length && dev->eot) { + sff_log("Total transfer length greater than sum of all blocks\n"); + dev->status |= 2; + return 0; /* There is data left to transfer but we have reached EOT - return with error. */ + } else if (dev->eot) { + sff_log("Regular EOT\n"); + dev->status &= ~3; + return 1; /* We have regularly reached EOT - clear status and break. */ + } else { + /* We have more to transfer and there are blocks left, get next block. */ + sff_bus_master_next_addr(dev); + } + } } return 1; } - void sff_bus_master_set_irq(int channel, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; - uint8_t irq = !!(channel & 0x40); + uint8_t irq = !!(channel & 0x40); if (!(dev->status & 0x04) || (channel & 0x40)) { - dev->status &= ~0x04; - dev->status |= (channel >> 4); + dev->status &= ~0x04; + dev->status |= (channel >> 4); } channel &= 0x01; switch (dev->irq_mode[channel]) { - case 0: - default: - /* Legacy IRQ mode. */ - if (irq) - picint(1 << (14 + channel)); - else - picintc(1 << (14 + channel)); - break; - case 1: - /* Native PCI IRQ mode with interrupt pin. */ - if (irq) - pci_set_irq(dev->slot, dev->irq_pin); - else - pci_clear_irq(dev->slot, dev->irq_pin); - break; - case 2: - case 5: - /* MIRQ 0 or 1. */ - if (irq) - pci_set_mirq(dev->irq_mode[channel] & 1, 0); - else - pci_clear_mirq(dev->irq_mode[channel] & 1, 0); - break; - case 3: - /* Native PCI IRQ mode with specified interrupt line. */ - if (irq) - picintlevel(1 << dev->irq_line); - else - picintc(1 << dev->irq_line); - break; - case 4: - /* ALi Aladdin Native PCI INTAJ mode. */ - if (irq) - pci_set_mirq(channel + 2, dev->irq_level[channel]); - else - pci_clear_mirq(channel + 2, dev->irq_level[channel]); - break; + case 0: + default: + /* Legacy IRQ mode. */ + if (irq) + picint(1 << (14 + channel)); + else + picintc(1 << (14 + channel)); + break; + case 1: + /* Native PCI IRQ mode with interrupt pin. */ + if (irq) + pci_set_irq(dev->slot, dev->irq_pin); + else + pci_clear_irq(dev->slot, dev->irq_pin); + break; + case 2: + case 5: + /* MIRQ 0 or 1. */ + if (irq) + pci_set_mirq(dev->irq_mode[channel] & 1, 0); + else + pci_clear_mirq(dev->irq_mode[channel] & 1, 0); + break; + case 3: + /* Native PCI IRQ mode with specified interrupt line. */ + if (irq) + picintlevel(1 << dev->irq_line); + else + picintc(1 << dev->irq_line); + break; + case 4: + /* ALi Aladdin Native PCI INTAJ mode. */ + if (irq) + pci_set_mirq(channel + 2, dev->irq_level[channel]); + else + pci_clear_mirq(channel + 2, dev->irq_level[channel]); + break; } } - void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base) { if (dev->enabled) { - io_removehandler(old_base, 0x08, - sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, - sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, - dev); + io_removehandler(old_base, 0x08, + sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, + sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, + dev); - dev->enabled = 0; + dev->enabled = 0; } dev->command = 0x00; - dev->status = 0x00; + dev->status = 0x00; dev->ptr = dev->ptr_cur = 0x00000000; - dev->addr = 0x00000000; - dev->ptr0 = 0x00; + dev->addr = 0x00000000; + dev->ptr0 = 0x00; dev->count = dev->eot = 0x00000000; ide_pri_disable(); ide_sec_disable(); } - static void sff_reset(void *p) { @@ -467,116 +451,107 @@ sff_reset(void *p) #endif for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && - (cdrom[i].ide_channel < 4) && cdrom[i].priv) - scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && - (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); } - for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && - (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) - mo_reset((scsi_common_t *) mo_drives[i].priv); - } sff_bus_master_set_irq(0x00, p); sff_bus_master_set_irq(0x01, p); } - void sff_set_slot(sff8038i_t *dev, int slot) { dev->slot = slot; } - void sff_set_irq_line(sff8038i_t *dev, int irq_line) { dev->irq_line = irq_line; } - void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level) { dev->irq_level[channel] = 0; } - void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode) { dev->irq_mode[channel] = irq_mode; switch (dev->irq_mode[channel]) { - case 0: - default: - /* Legacy IRQ mode. */ - sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); - break; - case 1: - /* Native PCI IRQ mode with interrupt pin. */ - sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin); - break; - case 2: - case 5: - /* MIRQ 0 or 1. */ - sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1); - break; - case 3: - /* Native PCI IRQ mode with specified interrupt line. */ - sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line); - break; - case 4: - /* ALi Aladdin Native PCI INTAJ mode. */ - sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel); - break; + case 0: + default: + /* Legacy IRQ mode. */ + sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); + break; + case 1: + /* Native PCI IRQ mode with interrupt pin. */ + sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin); + break; + case 2: + case 5: + /* MIRQ 0 or 1. */ + sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1); + break; + case 3: + /* Native PCI IRQ mode with specified interrupt line. */ + sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line); + break; + case 4: + /* ALi Aladdin Native PCI INTAJ mode. */ + sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel); + break; } } - void sff_set_irq_pin(sff8038i_t *dev, int irq_pin) { dev->irq_pin = irq_pin; } - static void sff_close(void *p) { - sff8038i_t *dev = (sff8038i_t *)p; + sff8038i_t *dev = (sff8038i_t *) p; free(dev); next_id--; if (next_id < 0) - next_id = 0; + next_id = 0; } - static void -*sff_init(const device_t *info) + * + sff_init(const device_t *info) { sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t)); memset(dev, 0, sizeof(sff8038i_t)); /* Make sure to only add IDE once. */ if (next_id == 0) - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_2ch_device); ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev); - dev->slot = 7; - dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ - dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ - dev->irq_pin = PCI_INTA; - dev->irq_line = 14; + dev->slot = 7; + dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ + dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ + dev->irq_pin = PCI_INTA; + dev->irq_line = 14; dev->irq_level[0] = dev->irq_level[1] = 0; next_id++; @@ -584,17 +559,16 @@ static void return dev; } -const device_t sff8038i_device = -{ - .name = "SFF-8038i IDE Bus Master", +const device_t sff8038i_device = { + .name = "SFF-8038i IDE Bus Master", .internal_name = "sff8038i", - .flags = DEVICE_PCI, - .local = 0, - .init = sff_init, - .close = sff_close, - .reset = sff_reset, + .flags = DEVICE_PCI, + .local = 0, + .init = sff_init, + .close = sff_close, + .reset = sff_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index aff35bc76..1d6b618b5 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -39,8 +39,7 @@ #include <86box/hdc.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, meaning (3600/60)*17 = 1020 sectors per second, or 980us per sector. @@ -48,125 +47,115 @@ This is required for OS/2 on slow 286 systems, as the hard drive formatter will crash with 'internal processing error' if write sector interrupts are too close in time*/ -#define SECTOR_TIME (TIMER_USEC * 980) +#define SECTOR_TIME (TIMER_USEC * 980) -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_ECC 0x04 -#define STAT_DRQ 0x08 /* data request */ -#define STAT_DSC 0x10 -#define STAT_WRFLT 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 +#define STAT_ERR 0x01 +#define STAT_INDEX 0x02 +#define STAT_ECC 0x04 +#define STAT_DRQ 0x08 /* data request */ +#define STAT_DSC 0x10 +#define STAT_WRFLT 0x20 +#define STAT_READY 0x40 +#define STAT_BUSY 0x80 -#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ -#define ERR_TR000 0x02 /* track 0 not found */ -#define ERR_ABRT 0x04 /* command aborted */ -#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ -#define ERR_DATA_CRC 0x40 /* data CRC error */ -#define ERR_BAD_BLOCK 0x80 /* bad block detected */ - -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 +#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ +#define ERR_TR000 0x02 /* track 0 not found */ +#define ERR_ABRT 0x04 /* command aborted */ +#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ +#define ERR_DATA_CRC 0x40 /* data CRC error */ +#define ERR_BAD_BLOCK 0x80 /* bad block detected */ +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 typedef struct { - int8_t present, /* drive is present */ - hdd_num, /* drive number in system */ - steprate, /* current servo step rate */ - spt, /* physical #sectors per track */ - hpc, /* physical #heads per cylinder */ - pad; - int16_t tracks; /* physical #tracks per cylinder */ + int8_t present, /* drive is present */ + hdd_num, /* drive number in system */ + steprate, /* current servo step rate */ + spt, /* physical #sectors per track */ + hpc, /* physical #heads per cylinder */ + pad; + int16_t tracks; /* physical #tracks per cylinder */ - int8_t cfg_spt, /* configured #sectors per track */ - cfg_hpc; /* configured #heads per track */ + int8_t cfg_spt, /* configured #sectors per track */ + cfg_hpc; /* configured #heads per track */ - int16_t curcyl; /* current track number */ + int16_t curcyl; /* current track number */ } drive_t; - typedef struct { - uint8_t precomp, /* 1: precomp/error register */ - error, - secount, /* 2: sector count register */ - sector, /* 3: sector number */ - head, /* 6: head number + drive select */ - command, /* 7: command/status */ - status, - fdisk; /* 8: control register */ - uint16_t cylinder; /* 4/5: cylinder LOW and HIGH */ + uint8_t precomp, /* 1: precomp/error register */ + error, + secount, /* 2: sector count register */ + sector, /* 3: sector number */ + head, /* 6: head number + drive select */ + command, /* 7: command/status */ + status, + fdisk; /* 8: control register */ + uint16_t cylinder; /* 4/5: cylinder LOW and HIGH */ - int8_t reset, /* controller in reset */ - irqstat, /* current IRQ status */ - drvsel, /* current selected drive */ - pad; + int8_t reset, /* controller in reset */ + irqstat, /* current IRQ status */ + drvsel, /* current selected drive */ + pad; - int pos; /* offset within data buffer */ - pc_timer_t callback_timer; /* callback delay timer */ + int pos; /* offset within data buffer */ + pc_timer_t callback_timer; /* callback delay timer */ - uint16_t buffer[256]; /* data buffer (16b wide) */ + uint16_t buffer[256]; /* data buffer (16b wide) */ - drive_t drives[MFM_NUM]; /* attached drives */ + drive_t drives[MFM_NUM]; /* attached drives */ } mfm_t; - -static uint8_t mfm_read(uint16_t port, void *priv); -static void mfm_write(uint16_t port, uint8_t val, void *priv); - +static uint8_t mfm_read(uint16_t port, void *priv); +static void mfm_write(uint16_t port, uint8_t val, void *priv); #ifdef ENABLE_ST506_AT_LOG int st506_at_do_log = ENABLE_ST506_AT_LOG; - static void st506_at_log(const char *fmt, ...) { va_list ap; if (st506_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define st506_at_log(fmt, ...) +# define st506_at_log(fmt, ...) #endif - static inline void irq_raise(mfm_t *mfm) { if (!(mfm->fdisk & 2)) - picint(1 << 14); + picint(1 << 14); mfm->irqstat = 1; } - static inline void irq_lower(mfm_t *mfm) { picintc(1 << 14); } - - static void irq_update(mfm_t *mfm) { if (mfm->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(mfm->fdisk & 2)) - picint(1 << 14); + picint(1 << 14); } - /* * Return the sector offset for the current register values. * @@ -184,596 +173,585 @@ get_sector(mfm_t *mfm, off64_t *addr) { drive_t *drive = &mfm->drives[mfm->drvsel]; -/* FIXME: See if this is even needed - if the code is present, IBM AT - diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ + /* FIXME: See if this is even needed - if the code is present, IBM AT + diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ if (drive->curcyl != mfm->cylinder) { - st506_at_log("WD1003(%d) sector: wrong cylinder\n"); - return(1); + st506_at_log("WD1003(%d) sector: wrong cylinder\n"); + return (1); } if (mfm->head > drive->cfg_hpc) { - st506_at_log("WD1003(%d) get_sector: past end of configured heads\n", - mfm->drvsel); - return(1); + st506_at_log("WD1003(%d) get_sector: past end of configured heads\n", + mfm->drvsel); + return (1); } - if (mfm->sector >= drive->cfg_spt+1) { - st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n", - mfm->drvsel); - return(1); + if (mfm->sector >= drive->cfg_spt + 1) { + st506_at_log("WD1003(%d) get_sector: past end of configured sectors\n", + mfm->drvsel); + return (1); } /* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */ if (mfm->head > drive->hpc) { - st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); - return(1); + st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); + return (1); } - if (mfm->sector >= drive->spt+1) { - st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); - return(1); + if (mfm->sector >= drive->spt + 1) { + st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); + return (1); } - *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * - drive->cfg_spt) + (mfm->sector - 1); + *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * drive->cfg_spt) + (mfm->sector - 1); - return(0); + return (0); } - /* Move to the next sector using CHS addressing. */ static void next_sector(mfm_t *mfm) { drive_t *drive = &mfm->drives[mfm->drvsel]; - if (++mfm->sector == (drive->cfg_spt+1)) { - mfm->sector = 1; - if (++mfm->head == drive->cfg_hpc) { - mfm->head = 0; - mfm->cylinder++; - if (drive->curcyl < drive->tracks) - drive->curcyl++; - } + if (++mfm->sector == (drive->cfg_spt + 1)) { + mfm->sector = 1; + if (++mfm->head == drive->cfg_hpc) { + mfm->head = 0; + mfm->cylinder++; + if (drive->curcyl < drive->tracks) + drive->curcyl++; + } } } - static void mfm_cmd(mfm_t *mfm, uint8_t val) { drive_t *drive = &mfm->drives[mfm->drvsel]; - if (! drive->present) { - /* This happens if sofware polls all drives. */ - st506_at_log("WD1003(%d) command %02x on non-present drive\n", - mfm->drvsel, val); - mfm->command = 0xff; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - return; + if (!drive->present) { + /* This happens if sofware polls all drives. */ + st506_at_log("WD1003(%d) command %02x on non-present drive\n", + mfm->drvsel, val); + mfm->command = 0xff; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + return; } irq_lower(mfm); mfm->command = val; - mfm->error = 0; + mfm->error = 0; switch (val & 0xf0) { - case CMD_RESTORE: - drive->steprate = (val & 0x0f); - st506_at_log("WD1003(%d) restore, step=%d\n", - mfm->drvsel, drive->steprate); - drive->curcyl = 0; - mfm->cylinder = 0; - mfm->status = STAT_READY|STAT_DSC; - mfm->command &= 0xf0; - irq_raise(mfm); - break; + case CMD_RESTORE: + drive->steprate = (val & 0x0f); + st506_at_log("WD1003(%d) restore, step=%d\n", + mfm->drvsel, drive->steprate); + drive->curcyl = 0; + mfm->cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + mfm->command &= 0xf0; + irq_raise(mfm); + break; - case CMD_SEEK: - drive->steprate = (val & 0x0f); - mfm->command &= 0xf0; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - break; + case CMD_SEEK: + drive->steprate = (val & 0x0f); + mfm->command &= 0xf0; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + break; - default: - mfm->command = val; - switch (val) { - case CMD_READ: - case CMD_READ+1: - case CMD_READ+2: - case CMD_READ+3: - st506_at_log("WD1003(%d) read, opt=%d\n", - mfm->drvsel, val&0x03); - mfm->command &= 0xfc; - if (val & 2) - fatal("WD1003: READ with ECC\n"); - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - break; + default: + mfm->command = val; + switch (val) { + case CMD_READ: + case CMD_READ + 1: + case CMD_READ + 2: + case CMD_READ + 3: + st506_at_log("WD1003(%d) read, opt=%d\n", + mfm->drvsel, val & 0x03); + mfm->command &= 0xfc; + if (val & 2) + fatal("WD1003: READ with ECC\n"); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + break; - case CMD_WRITE: - case CMD_WRITE+1: - case CMD_WRITE+2: - case CMD_WRITE+3: - st506_at_log("WD1003(%d) write, opt=%d\n", - mfm->drvsel, val & 0x03); - mfm->command &= 0xfc; - if (val & 2) - fatal("WD1003: WRITE with ECC\n"); - mfm->status = STAT_READY|STAT_DRQ|STAT_DSC; - mfm->pos = 0; - break; + case CMD_WRITE: + case CMD_WRITE + 1: + case CMD_WRITE + 2: + case CMD_WRITE + 3: + st506_at_log("WD1003(%d) write, opt=%d\n", + mfm->drvsel, val & 0x03); + mfm->command &= 0xfc; + if (val & 2) + fatal("WD1003: WRITE with ECC\n"); + mfm->status = STAT_READY | STAT_DRQ | STAT_DSC; + mfm->pos = 0; + break; - case CMD_VERIFY: - case CMD_VERIFY+1: - mfm->command &= 0xfe; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - break; + case CMD_VERIFY: + case CMD_VERIFY + 1: + mfm->command &= 0xfe; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + break; - case CMD_FORMAT: - mfm->status = STAT_DRQ|STAT_BUSY; - mfm->pos = 0; - break; + case CMD_FORMAT: + mfm->status = STAT_DRQ | STAT_BUSY; + mfm->pos = 0; + break; - case CMD_DIAGNOSE: - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - break; + case CMD_DIAGNOSE: + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + break; - case CMD_SET_PARAMETERS: - /* - * NOTE: - * - * We currently just set these parameters, and - * never bother to check if they "fit within" - * the actual parameters, as determined by the - * image loader. - * - * The difference in parameters is OK, and - * occurs when the BIOS or operating system - * decides to use a different translation - * scheme, but either way, it SHOULD always - * fit within the actual parameters! - * - * We SHOULD check that here!! --FvK - */ - if (drive->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head+1; - st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } else { - st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", - mfm->drvsel, drive->tracks, - drive->cfg_spt, drive->cfg_hpc); - } - mfm->command = 0x00; - mfm->status = STAT_READY|STAT_DSC; - mfm->error = 1; - irq_raise(mfm); - break; + case CMD_SET_PARAMETERS: + /* + * NOTE: + * + * We currently just set these parameters, and + * never bother to check if they "fit within" + * the actual parameters, as determined by the + * image loader. + * + * The difference in parameters is OK, and + * occurs when the BIOS or operating system + * decides to use a different translation + * scheme, but either way, it SHOULD always + * fit within the actual parameters! + * + * We SHOULD check that here!! --FvK + */ + if (drive->cfg_spt == 0) { + /* Only accept after RESET or DIAG. */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head + 1; + st506_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } else { + st506_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n", + mfm->drvsel, drive->tracks, + drive->cfg_spt, drive->cfg_hpc); + } + mfm->command = 0x00; + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + irq_raise(mfm); + break; - default: - st506_at_log("WD1003: bad command %02X\n", val); - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); - break; - } + default: + st506_at_log("WD1003: bad command %02X\n", val); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); + break; + } } } - static void 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) { - mfm_write(port, val & 0xff, priv); - if (port != 0x01f7) - mfm_write(port + 1, (val >> 8) & 0xff, priv); + mfm_write(port, val & 0xff, priv); + if (port != 0x01f7) + mfm_write(port + 1, (val >> 8) & 0xff, priv); } else { - mfm->buffer[mfm->pos >> 1] = val; - mfm->pos += 2; + mfm->buffer[mfm->pos >> 1] = val; + mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); - } + if (mfm->pos >= 512) { + mfm->pos = 0; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } } } - static void 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); switch (port) { - case 0x01f0: /* data */ - mfm_writew(port, val | (val << 8), priv); - return; + case 0x01f0: /* data */ + mfm_writew(port, val | (val << 8), priv); + return; - case 0x01f1: /* write precompenstation */ - mfm->precomp = val; - return; + case 0x01f1: /* write precompenstation */ + mfm->precomp = val; + return; - case 0x01f2: /* sector count */ - mfm->secount = val; - return; + case 0x01f2: /* sector count */ + mfm->secount = val; + return; - case 0x01f3: /* sector */ - mfm->sector = val; - return; + case 0x01f3: /* sector */ + mfm->sector = val; + return; - case 0x01f4: /* cylinder low */ - mfm->cylinder = (mfm->cylinder & 0xff00) | val; - return; + case 0x01f4: /* cylinder low */ + mfm->cylinder = (mfm->cylinder & 0xff00) | val; + return; - case 0x01f5: /* cylinder high */ - mfm->cylinder = (mfm->cylinder & 0xff) | (val << 8); - return; + case 0x01f5: /* cylinder high */ + mfm->cylinder = (mfm->cylinder & 0xff) | (val << 8); + return; - case 0x01f6: /* drive/head */ - mfm->head = val & 0xF; - mfm->drvsel = (val & 0x10) ? 1 : 0; - if (mfm->drives[mfm->drvsel].present) - mfm->status = STAT_READY|STAT_DSC; - else - mfm->status = 0; - return; + case 0x01f6: /* drive/head */ + mfm->head = val & 0xF; + mfm->drvsel = (val & 0x10) ? 1 : 0; + if (mfm->drives[mfm->drvsel].present) + mfm->status = STAT_READY | STAT_DSC; + else + mfm->status = 0; + return; - case 0x01f7: /* command register */ - mfm_cmd(mfm, val); - break; + case 0x01f7: /* command register */ + mfm_cmd(mfm, val); + break; - case 0x03f6: /* device control */ - val &= 0x0f; - if ((mfm->fdisk & 0x04) && !(val & 0x04)) { - timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); - mfm->reset = 1; - mfm->status = STAT_BUSY; - } + case 0x03f6: /* device control */ + val &= 0x0f; + if ((mfm->fdisk & 0x04) && !(val & 0x04)) { + timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); + mfm->reset = 1; + mfm->status = STAT_BUSY; + } - if (val & 0x04) { - /* Drive held in reset. */ - timer_disable(&mfm->callback_timer); - mfm->status = STAT_BUSY; - } - mfm->fdisk = val; - irq_update(mfm); - break; + if (val & 0x04) { + /* Drive held in reset. */ + timer_disable(&mfm->callback_timer); + mfm->status = STAT_BUSY; + } + mfm->fdisk = val; + irq_update(mfm); + break; } } - static uint16_t mfm_readw(uint16_t port, void *priv) { - mfm_t *mfm = (mfm_t *)priv; + mfm_t *mfm = (mfm_t *) priv; uint16_t ret; if (port > 0x01f0) { - ret = mfm_read(port, priv); - if (port == 0x01f7) - ret |= 0xff00; - else - ret |= (mfm_read(port + 1, priv) << 8); + ret = mfm_read(port, priv); + if (port == 0x01f7) + ret |= 0xff00; + else + ret |= (mfm_read(port + 1, priv) << 8); } else { - ret = mfm->buffer[mfm->pos >> 1]; - mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - if (mfm->command == CMD_READ) { - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - next_sector(mfm); - mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); - } else - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - } - } + ret = mfm->buffer[mfm->pos >> 1]; + mfm->pos += 2; + if (mfm->pos >= 512) { + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; + if (mfm->command == CMD_READ) { + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) { + next_sector(mfm); + mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } else + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + } + } } - return(ret); + return (ret); } - static uint8_t mfm_read(uint16_t port, void *priv) { - mfm_t *mfm = (mfm_t *)priv; + mfm_t *mfm = (mfm_t *) priv; uint8_t ret = 0xff; switch (port) { - case 0x01f0: /* data */ - ret = mfm_readw(port, mfm) & 0xff; - break; + case 0x01f0: /* data */ + ret = mfm_readw(port, mfm) & 0xff; + break; - case 0x01f1: /* error */ - ret = mfm->error; - break; + case 0x01f1: /* error */ + ret = mfm->error; + break; - case 0x01f2: /* sector count */ - ret = mfm->secount; - break; + case 0x01f2: /* sector count */ + ret = mfm->secount; + break; - case 0x01f3: /* sector */ - ret = mfm->sector; - break; + case 0x01f3: /* sector */ + ret = mfm->sector; + break; - case 0x01f4: /* CYlinder low */ - ret = (uint8_t)(mfm->cylinder&0xff); - break; + case 0x01f4: /* CYlinder low */ + ret = (uint8_t) (mfm->cylinder & 0xff); + break; - case 0x01f5: /* Cylinder high */ - ret = (uint8_t)(mfm->cylinder>>8); - break; + case 0x01f5: /* Cylinder high */ + ret = (uint8_t) (mfm->cylinder >> 8); + break; - case 0x01f6: /* drive/head */ - ret = (uint8_t)(0xa0 | mfm->head | (mfm->drvsel?0x10:0)); - break; + case 0x01f6: /* drive/head */ + ret = (uint8_t) (0xa0 | mfm->head | (mfm->drvsel ? 0x10 : 0)); + break; - case 0x01f7: /* Status */ - irq_lower(mfm); - ret = mfm->status; - break; + case 0x01f7: /* Status */ + irq_lower(mfm); + ret = mfm->status; + break; - default: - break; + default: + break; } st506_at_log("WD1003 read(%04x) = %02x\n", port, ret); - return(ret); + return (ret); } - static void do_seek(mfm_t *mfm) { drive_t *drive = &mfm->drives[mfm->drvsel]; 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) - drive->curcyl = mfm->cylinder; - else - drive->curcyl = drive->tracks-1; + drive->curcyl = mfm->cylinder; + else + drive->curcyl = drive->tracks - 1; } - static void do_callback(void *priv) { - mfm_t *mfm = (mfm_t *)priv; + mfm_t *mfm = (mfm_t *) priv; drive_t *drive = &mfm->drives[mfm->drvsel]; - off64_t addr; + off64_t addr; 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->error = 1; - mfm->secount = 1; - mfm->sector = 1; - mfm->head = 0; - mfm->cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + mfm->secount = 1; + mfm->sector = 1; + mfm->head = 0; + mfm->cylinder = 0; - drive->steprate = 0x0f; /* default steprate */ - drive->cfg_spt = 0; /* need new parameters */ + drive->steprate = 0x0f; /* default steprate */ + drive->cfg_spt = 0; /* need new parameters */ - 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; } switch (mfm->command) { - case CMD_SEEK: - st506_at_log("WD1003(%d) seek, step=%d\n", - mfm->drvsel, drive->steprate); - do_seek(mfm); - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; + case CMD_SEEK: + st506_at_log("WD1003(%d) seek, step=%d\n", + mfm->drvsel, drive->steprate); + do_seek(mfm); + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + break; - case CMD_READ: - st506_at_log("WD1003(%d) read(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } + case CMD_READ: + st506_at_log("WD1003(%d) read(%d,%d,%d)\n", + mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); + do_seek(mfm); + if (get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(mfm); + 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->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; + mfm->pos = 0; + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; + irq_raise(mfm); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + break; - case CMD_WRITE: - st506_at_log("WD1003(%d) write(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } + case CMD_WRITE: + st506_at_log("WD1003(%d) write(%d,%d,%d)\n", + mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); + do_seek(mfm); + if (get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(mfm); + break; + } - hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer); - irq_raise(mfm); - mfm->secount = (mfm->secount - 1) & 0xff; + hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer); + irq_raise(mfm); + mfm->secount = (mfm->secount - 1) & 0xff; - mfm->status = STAT_READY|STAT_DSC; - if (mfm->secount) { - /* More sectors to do.. */ - mfm->status |= STAT_DRQ; - mfm->pos = 0; - next_sector(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - } else - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - break; + mfm->status = STAT_READY | STAT_DSC; + if (mfm->secount) { + /* More sectors to do.. */ + mfm->status |= STAT_DRQ; + mfm->pos = 0; + next_sector(mfm); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + } else + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + break; - case CMD_VERIFY: - st506_at_log("WD1003(%d) verify(%d,%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); - do_seek(mfm); - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; + case CMD_VERIFY: + st506_at_log("WD1003(%d) verify(%d,%d,%d)\n", + mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector); + do_seek(mfm); + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + break; - case CMD_FORMAT: - st506_at_log("WD1003(%d) format(%d,%d)\n", - mfm->drvsel, mfm->cylinder, mfm->head); - do_seek(mfm); - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } + case CMD_FORMAT: + st506_at_log("WD1003(%d) format(%d,%d)\n", + mfm->drvsel, mfm->cylinder, mfm->head); + do_seek(mfm); + if (get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(mfm); + 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; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + break; - case CMD_DIAGNOSE: - st506_at_log("WD1003(%d) diag\n", mfm->drvsel); + case CMD_DIAGNOSE: + st506_at_log("WD1003(%d) diag\n", mfm->drvsel); - /* This is basically controller diagnostics - it resets drive select to 0, - and resets error and status to ready, DSC, and no error detected. */ - mfm->drvsel = 0; - drive = &mfm->drives[mfm->drvsel]; + /* This is basically controller diagnostics - it resets drive select to 0, + and resets error and status to ready, DSC, and no error detected. */ + mfm->drvsel = 0; + drive = &mfm->drives[mfm->drvsel]; - drive->steprate = 0x0f; - mfm->error = 1; - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; + drive->steprate = 0x0f; + mfm->error = 1; + mfm->status = STAT_READY | STAT_DSC; + irq_raise(mfm); + break; - default: - st506_at_log("WD1003(%d) callback on unknown command %02x\n", - mfm->drvsel, mfm->command); - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; + default: + st506_at_log("WD1003(%d) callback on unknown command %02x\n", + mfm->drvsel, mfm->command); + mfm->status = STAT_READY | STAT_ERR | STAT_DSC; + mfm->error = ERR_ABRT; + irq_raise(mfm); + break; } } - static void loadhd(mfm_t *mfm, int c, int d, const char *fn) { drive_t *drive = &mfm->drives[c]; - if (! hdd_image_load(d)) { - drive->present = 0; + if (!hdd_image_load(d)) { + drive->present = 0; - return; + return; } - drive->spt = hdd[d].spt; - drive->hpc = hdd[d].hpc; - drive->tracks = hdd[d].tracks; + drive->spt = hdd[d].spt; + drive->hpc = hdd[d].hpc; + drive->tracks = hdd[d].tracks; drive->hdd_num = d; drive->present = 1; } - static void * mfm_init(const device_t *info) { mfm_t *mfm; - int c, d; + int c, d; st506_at_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n"); mfm = malloc(sizeof(mfm_t)); memset(mfm, 0x00, sizeof(mfm_t)); c = 0; - for (d=0; d= MFM_NUM) break; - } + if (++c >= MFM_NUM) + break; + } } - mfm->status = STAT_READY|STAT_DSC; /* drive is ready */ - mfm->error = 1; /* no errors */ + mfm->status = STAT_READY | STAT_DSC; /* drive is ready */ + mfm->error = 1; /* no errors */ io_sethandler(0x01f0, 1, - mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); + mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); io_sethandler(0x01f1, 7, - mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); + mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); io_sethandler(0x03f6, 1, - NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); + NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); 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 mfm_close(void *priv) { - mfm_t *mfm = (mfm_t *)priv; - int d; + mfm_t *mfm = (mfm_t *) priv; + int d; - for (d=0; d<2; d++) { - drive_t *drive = &mfm->drives[d]; + for (d = 0; d < 2; d++) { + drive_t *drive = &mfm->drives[d]; - hdd_image_close(drive->hdd_num); + hdd_image_close(drive->hdd_num); } 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 = { - .name = "WD1003 AT MFM/RLL Controller", + .name = "WD1003 AT MFM/RLL Controller", .internal_name = "st506_at", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = mfm_init, - .close = mfm_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = mfm_init, + .close = mfm_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index e8c43fdc1..cedeb1220 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -87,121 +87,118 @@ #include <86box/hdc.h> #include <86box/hdd.h> - -#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.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_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" -#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.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_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" +#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ -#define WD1002A_27X_BIOS_FILE "roms/hdd/st506/wd1002a_27x-62-000094-032.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 WD1002A_27X_BIOS_FILE "roms/hdd/st506/wd1002a_27x-62-000094-032.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 ST506_TIME (250 * TIMER_USEC) -#define ST506_TIME_MS (1000 * TIMER_USEC) +#define ST506_TIME (250 * TIMER_USEC) +#define ST506_TIME_MS (1000 * TIMER_USEC) /* MFM and RLL use different sectors/track. */ -#define SECTOR_SIZE 512 -#define MFM_SECTORS 17 -#define RLL_SECTORS 26 - +#define SECTOR_SIZE 512 +#define MFM_SECTORS 17 +#define RLL_SECTORS 26 /* Status register. */ -#define STAT_REQ 0x01 /* controller ready */ -#define STAT_IO 0x02 /* input, data to host */ -#define STAT_CD 0x04 /* command mode (else data) */ -#define STAT_BSY 0x08 /* controller is busy */ -#define STAT_DRQ 0x10 /* controller needs DMA */ -#define STAT_IRQ 0x20 /* interrupt, we have info */ +#define STAT_REQ 0x01 /* controller ready */ +#define STAT_IO 0x02 /* input, data to host */ +#define STAT_CD 0x04 /* command mode (else data) */ +#define STAT_BSY 0x08 /* controller is busy */ +#define STAT_DRQ 0x10 /* controller needs DMA */ +#define STAT_IRQ 0x20 /* interrupt, we have info */ /* DMA/IRQ enable register. */ -#define DMA_ENA 0x01 /* DMA operation enabled */ -#define IRQ_ENA 0x02 /* IRQ operation enabled */ +#define DMA_ENA 0x01 /* DMA operation enabled */ +#define IRQ_ENA 0x02 /* IRQ operation enabled */ /* Error codes in sense report. */ -#define ERR_BV 0x80 -#define ERR_TYPE_MASK 0x30 -#define ERR_TYPE_SHIFT 4 -# define ERR_TYPE_DRIVE 0x00 -# define ERR_TYPE_CONTROLLER 0x01 -# define ERR_TYPE_COMMAND 0x02 -# define ERR_TYPE_MISC 0x03 +#define ERR_BV 0x80 +#define ERR_TYPE_MASK 0x30 +#define ERR_TYPE_SHIFT 4 +#define ERR_TYPE_DRIVE 0x00 +#define ERR_TYPE_CONTROLLER 0x01 +#define ERR_TYPE_COMMAND 0x02 +#define ERR_TYPE_MISC 0x03 /* No, um, errors.. */ -#define ERR_NONE 0x00 +#define ERR_NONE 0x00 /* Group 0: drive errors. */ -#define ERR_NO_SEEK 0x02 /* no seek_complete */ -#define ERR_WR_FAULT 0x03 /* write fault */ -#define ERR_NOT_READY 0x04 /* drive not ready */ -#define ERR_NO_TRACK0 0x06 /* track 0 not found */ -#define ERR_STILL_SEEKING 0x08 /* drive is still seeking */ -#define ERR_NOT_AVAILABLE 0x09 /* drive not available */ +#define ERR_NO_SEEK 0x02 /* no seek_complete */ +#define ERR_WR_FAULT 0x03 /* write fault */ +#define ERR_NOT_READY 0x04 /* drive not ready */ +#define ERR_NO_TRACK0 0x06 /* track 0 not found */ +#define ERR_STILL_SEEKING 0x08 /* drive is still seeking */ +#define ERR_NOT_AVAILABLE 0x09 /* drive not available */ /* Group 1: controller errors. */ -#define ERR_ID_FAULT 0x10 /* could not read ID field */ -#define ERR_UNC_ERR 0x11 /* uncorrectable data */ -#define ERR_SECTOR_ADDR 0x12 /* sector address */ -#define ERR_DATA_ADDR 0x13 /* data mark not found */ -#define ERR_TARGET_SECTOR 0x14 /* target sector not found */ -#define ERR_SEEK_ERROR 0x15 /* seek error- cyl not found */ -#define ERR_CORR_ERR 0x18 /* correctable data */ -#define ERR_BAD_TRACK 0x19 /* track is flagged as bad */ -#define ERR_ALT_TRACK_FLAGGED 0x1c /* alt trk not flagged as alt */ -#define ERR_ALT_TRACK_ACCESS 0x1e /* illegal access to alt trk */ -#define ERR_NO_RECOVERY 0x1f /* recovery mode not avail */ +#define ERR_ID_FAULT 0x10 /* could not read ID field */ +#define ERR_UNC_ERR 0x11 /* uncorrectable data */ +#define ERR_SECTOR_ADDR 0x12 /* sector address */ +#define ERR_DATA_ADDR 0x13 /* data mark not found */ +#define ERR_TARGET_SECTOR 0x14 /* target sector not found */ +#define ERR_SEEK_ERROR 0x15 /* seek error- cyl not found */ +#define ERR_CORR_ERR 0x18 /* correctable data */ +#define ERR_BAD_TRACK 0x19 /* track is flagged as bad */ +#define ERR_ALT_TRACK_FLAGGED 0x1c /* alt trk not flagged as alt */ +#define ERR_ALT_TRACK_ACCESS 0x1e /* illegal access to alt trk */ +#define ERR_NO_RECOVERY 0x1f /* recovery mode not avail */ /* Group 2: command errors. */ -#define ERR_BAD_COMMAND 0x20 /* invalid command */ -#define ERR_ILLEGAL_ADDR 0x21 /* address beyond disk size */ -#define ERR_BAD_PARAMETER 0x22 /* invalid command parameter */ +#define ERR_BAD_COMMAND 0x20 /* invalid command */ +#define ERR_ILLEGAL_ADDR 0x21 /* address beyond disk size */ +#define ERR_BAD_PARAMETER 0x22 /* invalid command parameter */ /* Group 3: misc errors. */ -#define ERR_BAD_RAM 0x30 /* controller has bad RAM */ -#define ERR_BAD_ROM 0x31 /* ROM failed checksum test */ -#define ERR_CRC_FAIL 0x32 /* CRC circuit failed test */ +#define ERR_BAD_RAM 0x30 /* controller has bad RAM */ +#define ERR_BAD_ROM 0x31 /* ROM failed checksum test */ +#define ERR_CRC_FAIL 0x32 /* CRC circuit failed test */ /* Controller commands. */ -#define CMD_TEST_DRIVE_READY 0x00 -#define CMD_RECALIBRATE 0x01 +#define CMD_TEST_DRIVE_READY 0x00 +#define CMD_RECALIBRATE 0x01 /* reserved 0x02 */ -#define CMD_STATUS 0x03 -#define CMD_FORMAT_DRIVE 0x04 -#define CMD_VERIFY 0x05 -#define CMD_FORMAT_TRACK 0x06 -#define CMD_FORMAT_BAD_TRACK 0x07 -#define CMD_READ 0x08 -#define CMD_REASSIGN 0x09 -#define CMD_WRITE 0x0a -#define CMD_SEEK 0x0b -#define CMD_SPECIFY 0x0c -#define CMD_READ_ECC_BURST_LEN 0x0d -#define CMD_READ_BUFFER 0x0e -#define CMD_WRITE_BUFFER 0x0f -#define CMD_ALT_TRACK 0x11 -#define CMD_INQUIRY_ST11 0x12 /* ST-11 BIOS */ -#define CMD_RAM_DIAGNOSTIC 0xe0 +#define CMD_STATUS 0x03 +#define CMD_FORMAT_DRIVE 0x04 +#define CMD_VERIFY 0x05 +#define CMD_FORMAT_TRACK 0x06 +#define CMD_FORMAT_BAD_TRACK 0x07 +#define CMD_READ 0x08 +#define CMD_REASSIGN 0x09 +#define CMD_WRITE 0x0a +#define CMD_SEEK 0x0b +#define CMD_SPECIFY 0x0c +#define CMD_READ_ECC_BURST_LEN 0x0d +#define CMD_READ_BUFFER 0x0e +#define CMD_WRITE_BUFFER 0x0f +#define CMD_ALT_TRACK 0x11 +#define CMD_INQUIRY_ST11 0x12 /* ST-11 BIOS */ +#define CMD_RAM_DIAGNOSTIC 0xe0 /* reserved 0xe1 */ /* reserved 0xe2 */ -#define CMD_DRIVE_DIAGNOSTIC 0xe3 -#define CMD_CTRLR_DIAGNOSTIC 0xe4 -#define CMD_READ_LONG 0xe5 -#define CMD_WRITE_LONG 0xe6 +#define CMD_DRIVE_DIAGNOSTIC 0xe3 +#define CMD_CTRLR_DIAGNOSTIC 0xe4 +#define CMD_READ_LONG 0xe5 +#define CMD_WRITE_LONG 0xe6 -#define CMD_FORMAT_ST11 0xf6 /* ST-11 BIOS */ -#define CMD_GET_GEOMETRY_ST11 0xf8 /* ST-11 BIOS */ -#define CMD_SET_GEOMETRY_ST11 0xfa /* ST-11 BIOS */ -#define CMD_WRITE_GEOMETRY_ST11 0xfc /* ST-11 BIOS 2.0 */ +#define CMD_FORMAT_ST11 0xf6 /* ST-11 BIOS */ +#define CMD_GET_GEOMETRY_ST11 0xf8 /* ST-11 BIOS */ +#define CMD_SET_GEOMETRY_ST11 0xfa /* ST-11 BIOS */ +#define CMD_WRITE_GEOMETRY_ST11 0xfc /* ST-11 BIOS 2.0 */ -#define CMD_GET_DRIVE_PARAMS_DTC 0xfb /* DTC */ -#define CMD_SET_STEP_RATE_DTC 0xfc /* DTC */ -#define CMD_SET_GEOMETRY_DTC 0xfe /* DTC */ -#define CMD_GET_GEOMETRY_DTC 0xff /* DTC */ +#define CMD_GET_DRIVE_PARAMS_DTC 0xfb /* DTC */ +#define CMD_SET_STEP_RATE_DTC 0xfc /* DTC */ +#define CMD_SET_GEOMETRY_DTC 0xfe /* DTC */ +#define CMD_GET_GEOMETRY_DTC 0xff /* DTC */ enum { STATE_IDLE, @@ -215,117 +212,110 @@ enum { STATE_DONE }; - typedef struct { - int8_t present; - uint8_t hdd_num; + int8_t present; + uint8_t hdd_num; - uint8_t interleave; /* default interleave */ - char pad; + uint8_t interleave; /* default interleave */ + char pad; - uint16_t cylinder; /* current cylinder */ + uint16_t cylinder; /* current cylinder */ - uint8_t spt, /* physical parameters */ - hpc; - uint16_t tracks; + uint8_t spt, /* physical parameters */ + hpc; + uint16_t tracks; - uint8_t cfg_spt, /* configured parameters */ - cfg_hpc; - uint16_t cfg_cyl; + uint8_t cfg_spt, /* configured parameters */ + cfg_hpc; + uint16_t cfg_cyl; } drive_t; - typedef struct { - uint8_t type; /* controller type */ + uint8_t type; /* controller type */ - uint8_t spt; /* sectors-per-track for controller */ + uint8_t spt; /* sectors-per-track for controller */ - uint16_t base; /* controller configuration */ - int8_t irq, - dma; - uint8_t switches; - uint8_t misc; - uint8_t nr_err, err_bv, cur_sec, pad; - uint32_t bios_addr, - bios_size, - bios_ram; - rom_t bios_rom; + uint16_t base; /* controller configuration */ + int8_t irq, + dma; + uint8_t switches; + uint8_t misc; + uint8_t nr_err, err_bv, cur_sec, pad; + uint32_t bios_addr, + bios_size, + bios_ram; + rom_t bios_rom; - int state; /* operational data */ - uint8_t irq_dma; - uint8_t error; - uint8_t status; - int8_t cyl_off; /* for ST-11, cylinder0 offset */ - pc_timer_t timer; + int state; /* operational data */ + uint8_t irq_dma; + uint8_t error; + uint8_t status; + int8_t cyl_off; /* for ST-11, cylinder0 offset */ + pc_timer_t timer; - uint8_t command[6]; /* current command request */ - int drive_sel; - int sector, - head, - cylinder, - count; - uint8_t compl; /* current request completion code */ + uint8_t command[6]; /* current command request */ + int drive_sel; + int sector, + head, + cylinder, + count; + uint8_t compl ; /* current request completion code */ - int buff_pos, /* pointers to the RAM buffer */ - buff_cnt; + int buff_pos, /* pointers to the RAM buffer */ + buff_cnt; - drive_t drives[MFM_NUM]; /* the attached drives */ - uint8_t scratch[64]; /* ST-11 scratchpad RAM */ - uint8_t buff[SECTOR_SIZE + 4]; /* sector buffer RAM (+ ECC bytes) */ + drive_t drives[MFM_NUM]; /* the attached drives */ + uint8_t scratch[64]; /* ST-11 scratchpad RAM */ + uint8_t buff[SECTOR_SIZE + 4]; /* sector buffer RAM (+ ECC bytes) */ } hdc_t; - /* Supported drives table for the Xebec controller. */ typedef struct { - uint16_t tracks; - uint8_t hpc; - uint8_t spt; + uint16_t tracks; + uint8_t hpc; + uint8_t spt; } hd_type_t; hd_type_t hd_types[4] = { - { 306, 4, MFM_SECTORS }, /* type 0 */ - { 612, 4, MFM_SECTORS }, /* type 16 */ - { 615, 4, MFM_SECTORS }, /* type 2 */ - { 306, 8, MFM_SECTORS } /* type 13 */ + {306, 4, MFM_SECTORS}, /* type 0 */ + { 612, 4, MFM_SECTORS}, /* type 16 */ + { 615, 4, MFM_SECTORS}, /* type 2 */ + { 306, 8, MFM_SECTORS} /* type 13 */ }; - #ifdef ENABLE_ST506_XT_LOG int st506_xt_do_log = ENABLE_ST506_XT_LOG; - static void st506_xt_log(const char *fmt, ...) { va_list ap; if (st506_xt_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define st506_xt_log(fmt, ...) +# define st506_xt_log(fmt, ...) #endif - static void st506_complete(hdc_t *dev) { dev->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; - dev->state = STATE_COMPLETION_BYTE; + dev->state = STATE_COMPLETION_BYTE; if (dev->irq_dma & DMA_ENA) - dma_set_drq(dev->dma, 0); + dma_set_drq(dev->dma, 0); if (dev->irq_dma & IRQ_ENA) { - dev->status |= STAT_IRQ; - picint(1 << dev->irq); + dev->status |= STAT_IRQ; + picint(1 << dev->irq); } } - static void st506_error(hdc_t *dev, uint8_t err) { @@ -333,21 +323,20 @@ st506_error(hdc_t *dev, uint8_t err) dev->error = err; } - static int get_sector(hdc_t *dev, drive_t *drive, off64_t *addr) { - if (! drive->present) { - /* No need to log this. */ - dev->error = dev->nr_err; - return(0); + if (!drive->present) { + /* No need to log this. */ + dev->error = dev->nr_err; + return (0); } #if 0 if (drive->cylinder != dev->cylinder) { -#ifdef ENABLE_ST506_XT_LOG +# ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: get_sector: wrong cylinder\n"); -#endif +# endif dev->error = ERR_ILLEGAL_ADDR; return(0); } @@ -355,46 +344,44 @@ get_sector(hdc_t *dev, drive_t *drive, off64_t *addr) if (dev->head >= drive->cfg_hpc) { #ifdef ENABLE_ST506_XT_LOG - 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 - dev->error = ERR_ILLEGAL_ADDR; - return(0); + dev->error = ERR_ILLEGAL_ADDR; + return (0); } if (dev->sector >= drive->cfg_spt) { #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 - dev->error = ERR_ILLEGAL_ADDR; - return(0); + dev->error = ERR_ILLEGAL_ADDR; + 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 next_sector(hdc_t *dev, drive_t *drive) { if (++dev->sector >= drive->cfg_spt) { - dev->sector = 0; - if (++dev->head >= drive->cfg_hpc) { - dev->head = 0; - if (++drive->cylinder >= drive->cfg_cyl) { - /* - * This really is an error, we cannot move - * past the end of the drive, which should - * result in an ERR_ILLEGAL_ADDR. --FvK - */ - drive->cylinder = drive->cfg_cyl - 1; - } else - dev->cylinder++; - } + dev->sector = 0; + if (++dev->head >= drive->cfg_hpc) { + dev->head = 0; + if (++drive->cylinder >= drive->cfg_cyl) { + /* + * This really is an error, we cannot move + * past the end of the drive, which should + * result in an ERR_ILLEGAL_ADDR. --FvK + */ + drive->cylinder = drive->cfg_cyl - 1; + } else + dev->cylinder++; + } } } - /* Extract the CHS info from a command block. */ static int get_chs(hdc_t *dev, drive_t *drive) @@ -404,899 +391,891 @@ get_chs(hdc_t *dev, drive_t *drive) dev->head = dev->command[1] & 0x1f; /* 6 bits are used for the sector number even on the IBM PC controller. */ dev->sector = dev->command[2] & 0x3f; - dev->count = dev->command[4]; + dev->count = dev->command[4]; if (((dev->type == 11) || (dev->type == 12)) && (dev->command[0] >= 0xf0)) - dev->cylinder = 0; + dev->cylinder = 0; else { - dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); - dev->cylinder += dev->cyl_off; /* for ST-11 */ + dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); + dev->cylinder += dev->cyl_off; /* for ST-11 */ } if (dev->cylinder >= drive->cfg_cyl) { - /* - * This really is an error, we cannot move - * past the end of the drive, which should - * result in an ERR_ILLEGAL_ADDR. --FvK - */ - drive->cylinder = drive->cfg_cyl - 1; - return(0); + /* + * This really is an error, we cannot move + * past the end of the drive, which should + * result in an ERR_ILLEGAL_ADDR. --FvK + */ + drive->cylinder = drive->cfg_cyl - 1; + return (0); } drive->cylinder = dev->cylinder; - return(1); + return (1); } - static void st506_callback(void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; drive_t *drive; - off64_t addr; + off64_t addr; uint32_t capac; - int val; + int val; /* Get the drive info. Note that the API supports up to 8 drives! */ dev->drive_sel = (dev->command[1] >> 5) & 0x07; - drive = &dev->drives[dev->drive_sel]; + drive = &dev->drives[dev->drive_sel]; /* Preset the completion byte to "No error" and the selected drive. */ dev->compl = (dev->drive_sel << 5) | ERR_NONE; if (dev->command[0] != 3) - dev->err_bv = 0x00; + dev->err_bv = 0x00; switch (dev->command[0]) { - case CMD_TEST_DRIVE_READY: - st506_xt_log("ST506: TEST_READY(%i) = %i\n", - dev->drive_sel, drive->present); - if (! drive->present) - st506_error(dev, dev->nr_err); - st506_complete(dev); - break; + case CMD_TEST_DRIVE_READY: + st506_xt_log("ST506: TEST_READY(%i) = %i\n", + dev->drive_sel, drive->present); + if (!drive->present) + st506_error(dev, dev->nr_err); + st506_complete(dev); + break; - case CMD_RECALIBRATE: - switch (dev->state) { - case STATE_START_COMMAND: - st506_xt_log("ST506: RECALIBRATE(%i) [%i]\n", - dev->drive_sel, drive->present); - if (! drive->present) { - st506_error(dev, dev->nr_err); - st506_complete(dev); - break; - } + case CMD_RECALIBRATE: + switch (dev->state) { + case STATE_START_COMMAND: + st506_xt_log("ST506: RECALIBRATE(%i) [%i]\n", + dev->drive_sel, drive->present); + if (!drive->present) { + st506_error(dev, dev->nr_err); + st506_complete(dev); + break; + } - /* Wait 20msec. */ - timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); + /* Wait 20msec. */ + timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); - dev->cylinder = dev->cyl_off; - drive->cylinder = dev->cylinder; - dev->state = STATE_DONE; + dev->cylinder = dev->cyl_off; + drive->cylinder = dev->cylinder; + dev->state = STATE_DONE; - break; + break; - case STATE_DONE: - st506_complete(dev); - break; - } - break; + case STATE_DONE: + st506_complete(dev); + break; + } + break; - case CMD_STATUS: - switch (dev->state) { - case STATE_START_COMMAND: + case CMD_STATUS: + switch (dev->state) { + case STATE_START_COMMAND: #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: STATUS\n"); + st506_xt_log("ST506: STATUS\n"); #endif - dev->buff_pos = 0; - dev->buff_cnt = 4; - dev->buff[0] = dev->err_bv | dev->error; - dev->error = 0; + dev->buff_pos = 0; + dev->buff_cnt = 4; + dev->buff[0] = dev->err_bv | dev->error; + dev->error = 0; - /* Give address of last operation. */ - dev->buff[1] = (dev->drive_sel ? 0x20 : 0) | - dev->head; - dev->buff[2] = ((dev->cylinder & 0x0300) >> 2) | - dev->sector; - dev->buff[3] = (dev->cylinder & 0xff); + /* Give address of last operation. */ + dev->buff[1] = (dev->drive_sel ? 0x20 : 0) | dev->head; + dev->buff[2] = ((dev->cylinder & 0x0300) >> 2) | dev->sector; + dev->buff[3] = (dev->cylinder & 0xff); - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - dev->state = STATE_SEND_DATA; - break; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + dev->state = STATE_SEND_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + break; - case CMD_FORMAT_DRIVE: - switch (dev->state) { - case STATE_START_COMMAND: - (void)get_chs(dev, drive); - st506_xt_log("ST506: FORMAT_DRIVE(%i) interleave=%i\n", - dev->drive_sel, dev->command[4]); - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_SEND_DATA; - break; + case CMD_FORMAT_DRIVE: + switch (dev->state) { + case STATE_START_COMMAND: + (void) get_chs(dev, drive); + st506_xt_log("ST506: FORMAT_DRIVE(%i) interleave=%i\n", + dev->drive_sel, dev->command[4]); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_SEND_DATA; + break; - case STATE_SEND_DATA: /* wrong, but works */ - if (! get_sector(dev, drive, &addr)) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_error(dev, dev->error); - st506_complete(dev); - return; - } + case STATE_SEND_DATA: /* wrong, but works */ + if (!get_sector(dev, drive, &addr)) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_error(dev, dev->error); + st506_complete(dev); + return; + } - /* FIXME: should be drive->capac, not ->spt */ - capac = (drive->tracks - 1) * drive->hpc * drive->spt; - hdd_image_zero(drive->hdd_num, addr, capac); + /* FIXME: should be drive->capac, not ->spt */ + capac = (drive->tracks - 1) * drive->hpc * drive->spt; + hdd_image_zero(drive->hdd_num, addr, capac); - /* Wait 20msec per cylinder. */ - timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); + /* Wait 20msec per cylinder. */ + timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); - dev->state = STATE_SENT_DATA; - break; + dev->state = STATE_SENT_DATA; + break; - case STATE_SENT_DATA: - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + break; + } + break; - case CMD_VERIFY: - switch (dev->state) { - case STATE_START_COMMAND: - (void)get_chs(dev, drive); - st506_xt_log("ST506: VERIFY(%i, %i/%i/%i, %i)\n", - dev->drive_sel, dev->cylinder, - dev->head, dev->sector, dev->count); - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_SEND_DATA; - break; + case CMD_VERIFY: + switch (dev->state) { + case STATE_START_COMMAND: + (void) get_chs(dev, drive); + st506_xt_log("ST506: VERIFY(%i, %i/%i/%i, %i)\n", + dev->drive_sel, dev->cylinder, + dev->head, dev->sector, dev->count); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_SEND_DATA; + break; - case STATE_SEND_DATA: - if (dev->count-- == 0) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - } + case STATE_SEND_DATA: + if (dev->count-- == 0) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + } - if (! get_sector(dev, drive, &addr)) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_error(dev, dev->error); - st506_complete(dev); - return; - } + if (!get_sector(dev, drive, &addr)) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_error(dev, dev->error); + st506_complete(dev); + return; + } - next_sector(dev, drive); + next_sector(dev, drive); - timer_advance_u64(&dev->timer, ST506_TIME); - break; - } - break; + timer_advance_u64(&dev->timer, ST506_TIME); + break; + } + break; - case CMD_FORMAT_ST11: /* This is really "Format cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); - break; - } - case CMD_FORMAT_TRACK: - case CMD_FORMAT_BAD_TRACK: - switch (dev->state) { - case STATE_START_COMMAND: - (void)get_chs(dev, drive); - st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n", - (dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "", - dev->drive_sel, dev->cylinder, dev->head); - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_SEND_DATA; - break; + case CMD_FORMAT_ST11: /* This is really "Format cylinder 0" */ + if ((dev->type < 11) || (dev->type > 12)) { + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); + break; + } + case CMD_FORMAT_TRACK: + case CMD_FORMAT_BAD_TRACK: + switch (dev->state) { + case STATE_START_COMMAND: + (void) get_chs(dev, drive); + st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n", + (dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "", + dev->drive_sel, dev->cylinder, dev->head); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_SEND_DATA; + break; - case STATE_SEND_DATA: /* wrong, but works */ - if (! get_sector(dev, drive, &addr)) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_error(dev, dev->error); - st506_complete(dev); - return; - } + case STATE_SEND_DATA: /* wrong, but works */ + if (!get_sector(dev, drive, &addr)) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_error(dev, dev->error); + st506_complete(dev); + return; + } - hdd_image_zero(drive->hdd_num, - addr, drive->cfg_spt); + hdd_image_zero(drive->hdd_num, + addr, drive->cfg_spt); - /* Wait 20 msec per cylinder. */ - timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); + /* Wait 20 msec per cylinder. */ + timer_advance_u64(&dev->timer, ST506_TIME_MS * 20); - dev->state = STATE_SENT_DATA; - break; + dev->state = STATE_SENT_DATA; + break; - case STATE_SENT_DATA: - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + break; + } + break; - case CMD_GET_GEOMETRY_ST11: /* "Get geometry" is really "Read cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); - break; - } - case CMD_READ: + case CMD_GET_GEOMETRY_ST11: /* "Get geometry" is really "Read cylinder 0" */ + if ((dev->type < 11) || (dev->type > 12)) { + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); + break; + } + case CMD_READ: #if 0 case CMD_READ_LONG: #endif - switch (dev->state) { - case STATE_START_COMMAND: - (void)get_chs(dev, drive); - st506_xt_log("ST506: READ%s(%i, %i/%i/%i, %i)\n", - (dev->command[0] == CMD_READ_LONG) ? "_LONG" : "", - dev->drive_sel, dev->cylinder, - dev->head, dev->sector, dev->count); + switch (dev->state) { + case STATE_START_COMMAND: + (void) get_chs(dev, drive); + st506_xt_log("ST506: READ%s(%i, %i/%i/%i, %i)\n", + (dev->command[0] == CMD_READ_LONG) ? "_LONG" : "", + dev->drive_sel, dev->cylinder, + dev->head, dev->sector, dev->count); - if (! get_sector(dev, drive, &addr)) { - st506_error(dev, dev->error); - st506_complete(dev); - return; - } - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + if (!get_sector(dev, drive, &addr)) { + st506_error(dev, dev->error); + st506_complete(dev); + return; + } + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - /* Read data from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)dev->buff); + /* Read data from the image. */ + hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff); - /* Set up the data transfer. */ - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - if (dev->command[0] == CMD_READ_LONG) - dev->buff_cnt += 4; - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_SEND_DATA; - break; + /* Set up the data transfer. */ + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + if (dev->command[0] == CMD_READ_LONG) + dev->buff_cnt += 4; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_SEND_DATA; + break; - case STATE_SEND_DATA: - for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { - val = dma_channel_write(dev->dma, dev->buff[dev->buff_pos]); - if (val == DMA_NODATA) { + case STATE_SEND_DATA: + for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { + val = dma_channel_write(dev->dma, dev->buff[dev->buff_pos]); + if (val == DMA_NODATA) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: CMD_READ out of data!\n"); + st506_xt_log("ST506: CMD_READ out of data!\n"); #endif - st506_error(dev, ERR_NO_RECOVERY); - st506_complete(dev); - return; - } - } - dma_set_drq(dev->dma, 0); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_SENT_DATA; - break; + st506_error(dev, ERR_NO_RECOVERY); + st506_complete(dev); + return; + } + } + dma_set_drq(dev->dma, 0); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_SENT_DATA; + break; - case STATE_SENT_DATA: - if (--dev->count == 0) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - break; - } + case STATE_SENT_DATA: + if (--dev->count == 0) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + break; + } - next_sector(dev, drive); + next_sector(dev, drive); - if (! get_sector(dev, drive, &addr)) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_error(dev, dev->error); - st506_complete(dev); - return; - } + if (!get_sector(dev, drive, &addr)) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_error(dev, dev->error); + st506_complete(dev); + return; + } - /* Read data from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)dev->buff); + /* Read data from the image. */ + hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff); - /* Set up the data transfer. */ - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_SEND_DATA; - break; - } - break; + /* Set up the data transfer. */ + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_SEND_DATA; + break; + } + break; - case CMD_SET_GEOMETRY_ST11: /* "Set geometry" is really "Write cylinder 0" */ - if (dev->type == 1) { - /* DTC sends this... */ - st506_complete(dev); - break; - } else if ((dev->type < 11) || (dev->type > 12)) { - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); - break; - } - case CMD_WRITE: + case CMD_SET_GEOMETRY_ST11: /* "Set geometry" is really "Write cylinder 0" */ + if (dev->type == 1) { + /* DTC sends this... */ + st506_complete(dev); + break; + } else if ((dev->type < 11) || (dev->type > 12)) { + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); + break; + } + case CMD_WRITE: #if 0 case CMD_WRITE_LONG: #endif - switch (dev->state) { - case STATE_START_COMMAND: - (void)get_chs(dev, drive); - st506_xt_log("ST506: WRITE%s(%i, %i/%i/%i, %i)\n", - (dev->command[0] == CMD_WRITE_LONG) ? "_LONG" : "", - dev->drive_sel, dev->cylinder, - dev->head, dev->sector, dev->count); + switch (dev->state) { + case STATE_START_COMMAND: + (void) get_chs(dev, drive); + st506_xt_log("ST506: WRITE%s(%i, %i/%i/%i, %i)\n", + (dev->command[0] == CMD_WRITE_LONG) ? "_LONG" : "", + dev->drive_sel, dev->cylinder, + dev->head, dev->sector, dev->count); - if (! get_sector(dev, drive, &addr)) { - st506_error(dev, ERR_BAD_PARAMETER); - st506_complete(dev); - return; - } + if (!get_sector(dev, drive, &addr)) { + st506_error(dev, ERR_BAD_PARAMETER); + st506_complete(dev); + return; + } - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - /* Set up the data transfer. */ - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - if (dev->command[0] == CMD_WRITE_LONG) - dev->buff_cnt += 4; - dev->status = STAT_BSY | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_RECEIVE_DATA; - break; + /* Set up the data transfer. */ + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + if (dev->command[0] == CMD_WRITE_LONG) + dev->buff_cnt += 4; + dev->status = STAT_BSY | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_RECEIVE_DATA; + break; - case STATE_RECEIVE_DATA: - for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { + case STATE_RECEIVE_DATA: + for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { + val = dma_channel_read(dev->dma); + if (val == DMA_NODATA) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: CMD_WRITE out of data!\n"); + st506_xt_log("ST506: CMD_WRITE out of data!\n"); #endif - st506_error(dev, ERR_NO_RECOVERY); - st506_complete(dev); - return; - } - dev->buff[dev->buff_pos] = val & 0xff; - } + st506_error(dev, ERR_NO_RECOVERY); + st506_complete(dev); + return; + } + dev->buff[dev->buff_pos] = val & 0xff; + } - dma_set_drq(dev->dma, 0); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_RECEIVED_DATA; - break; + dma_set_drq(dev->dma, 0); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_RECEIVED_DATA; + break; - case STATE_RECEIVED_DATA: - if (! get_sector(dev, drive, &addr)) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_error(dev, dev->error); - st506_complete(dev); - return; - } + case STATE_RECEIVED_DATA: + if (!get_sector(dev, drive, &addr)) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_error(dev, dev->error); + st506_complete(dev); + return; + } - /* Write data to image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->buff); + /* Write data to image. */ + hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff); - if (--dev->count == 0) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - break; - } + if (--dev->count == 0) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + break; + } - next_sector(dev, drive); + next_sector(dev, drive); - /* Set up the data transfer. */ - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - dev->status = STAT_BSY | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_RECEIVE_DATA; - break; - } - break; + /* Set up the data transfer. */ + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + dev->status = STAT_BSY | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_RECEIVE_DATA; + break; + } + break; - case CMD_SEEK: - if (drive->present) { - val = get_chs(dev, drive); - st506_xt_log("ST506: SEEK(%i, %i) [%i]\n", - dev->drive_sel, drive->cylinder, val); - if (! val) - st506_error(dev, ERR_SEEK_ERROR); - } else - st506_error(dev, dev->nr_err); - st506_complete(dev); - break; + case CMD_SEEK: + if (drive->present) { + val = get_chs(dev, drive); + st506_xt_log("ST506: SEEK(%i, %i) [%i]\n", + dev->drive_sel, drive->cylinder, val); + if (!val) + st506_error(dev, ERR_SEEK_ERROR); + } else + st506_error(dev, dev->nr_err); + st506_complete(dev); + break; - case CMD_SPECIFY: - switch (dev->state) { - case STATE_START_COMMAND: - dev->buff_pos = 0; - dev->buff_cnt = 8; - dev->status = STAT_BSY | STAT_REQ; - dev->state = STATE_RECEIVE_DATA; - break; + case CMD_SPECIFY: + switch (dev->state) { + case STATE_START_COMMAND: + dev->buff_pos = 0; + dev->buff_cnt = 8; + dev->status = STAT_BSY | STAT_REQ; + dev->state = STATE_RECEIVE_DATA; + break; - case STATE_RECEIVED_DATA: - drive->cfg_cyl = dev->buff[1] | (dev->buff[0] << 8); - drive->cfg_hpc = dev->buff[2]; - /* For a 615/4/26 we get 666/2/31 geometry. */ - st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n", - dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - st506_complete(dev); - break; - } - break; + case STATE_RECEIVED_DATA: + drive->cfg_cyl = dev->buff[1] | (dev->buff[0] << 8); + drive->cfg_hpc = dev->buff[2]; + /* For a 615/4/26 we get 666/2/31 geometry. */ + st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n", + dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc); + st506_complete(dev); + break; + } + break; - case CMD_READ_ECC_BURST_LEN: - switch (dev->state) { - case STATE_START_COMMAND: + case CMD_READ_ECC_BURST_LEN: + switch (dev->state) { + case STATE_START_COMMAND: #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: READ_ECC_BURST_LEN\n"); + st506_xt_log("ST506: READ_ECC_BURST_LEN\n"); #endif - dev->buff_pos = 0; - dev->buff_cnt = 1; - dev->buff[0] = 0; /* 0 bits */ - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - dev->state = STATE_SEND_DATA; - break; + dev->buff_pos = 0; + dev->buff_cnt = 1; + dev->buff[0] = 0; /* 0 bits */ + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + dev->state = STATE_SEND_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + break; - case CMD_READ_BUFFER: - switch (dev->state) { - case STATE_START_COMMAND: - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - st506_xt_log("ST506: READ_BUFFER (%i)\n", - dev->buff_cnt); + case CMD_READ_BUFFER: + switch (dev->state) { + case STATE_START_COMMAND: + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + st506_xt_log("ST506: READ_BUFFER (%i)\n", + dev->buff_cnt); - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_SEND_DATA; - break; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_SEND_DATA; + break; - case STATE_SEND_DATA: - for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { - val = dma_channel_write(dev->dma, dev->buff[dev->buff_pos]); - if (val == DMA_NODATA) { + case STATE_SEND_DATA: + for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { + val = dma_channel_write(dev->dma, dev->buff[dev->buff_pos]); + if (val == DMA_NODATA) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: CMD_READ_BUFFER out of data!\n"); + st506_xt_log("ST506: CMD_READ_BUFFER out of data!\n"); #endif - st506_error(dev, ERR_NO_RECOVERY); - st506_complete(dev); - return; - } - } + st506_error(dev, ERR_NO_RECOVERY); + st506_complete(dev); + return; + } + } - dma_set_drq(dev->dma, 0); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_SENT_DATA; - break; + dma_set_drq(dev->dma, 0); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_SENT_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + break; - case CMD_WRITE_BUFFER: - switch (dev->state) { - case STATE_START_COMMAND: - dev->buff_pos = 0; - dev->buff_cnt = SECTOR_SIZE; - st506_xt_log("ST506: WRITE_BUFFER (%i)\n", - dev->buff_cnt); + case CMD_WRITE_BUFFER: + switch (dev->state) { + case STATE_START_COMMAND: + dev->buff_pos = 0; + dev->buff_cnt = SECTOR_SIZE; + st506_xt_log("ST506: WRITE_BUFFER (%i)\n", + dev->buff_cnt); - dev->status = STAT_BSY | STAT_REQ; - if (dev->irq_dma & DMA_ENA) { - timer_advance_u64(&dev->timer, ST506_TIME); - dma_set_drq(dev->dma, 1); - } - dev->state = STATE_RECEIVE_DATA; - break; + dev->status = STAT_BSY | STAT_REQ; + if (dev->irq_dma & DMA_ENA) { + timer_advance_u64(&dev->timer, ST506_TIME); + dma_set_drq(dev->dma, 1); + } + dev->state = STATE_RECEIVE_DATA; + break; - case STATE_RECEIVE_DATA: - for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { + case STATE_RECEIVE_DATA: + for (; dev->buff_pos < dev->buff_cnt; dev->buff_pos++) { + val = dma_channel_read(dev->dma); + if (val == DMA_NODATA) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: CMD_WRITE_BUFFER out of data!\n"); + st506_xt_log("ST506: CMD_WRITE_BUFFER out of data!\n"); #endif - st506_error(dev, ERR_NO_RECOVERY); - st506_complete(dev); - return; - } - dev->buff[dev->buff_pos] = val & 0xff; - } + st506_error(dev, ERR_NO_RECOVERY); + st506_complete(dev); + return; + } + dev->buff[dev->buff_pos] = val & 0xff; + } - dma_set_drq(dev->dma, 0); - timer_advance_u64(&dev->timer, ST506_TIME); - dev->state = STATE_RECEIVED_DATA; - break; + dma_set_drq(dev->dma, 0); + timer_advance_u64(&dev->timer, ST506_TIME); + dev->state = STATE_RECEIVED_DATA; + break; - case STATE_RECEIVED_DATA: - st506_complete(dev); - break; - } - break; + case STATE_RECEIVED_DATA: + st506_complete(dev); + break; + } + break; - case CMD_INQUIRY_ST11: - if (dev->type == 11 || dev->type == 12) switch (dev->state) { - case STATE_START_COMMAND: - st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type); - dev->buff_pos = 0; - dev->buff_cnt = 2; - dev->buff[0] = 0x80; /* "ST-11" */ - if (dev->spt == 17) - dev->buff[0] |= 0x40; /* MFM */ - dev->buff[1] = dev->misc; /* revision */ - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - dev->state = STATE_SEND_DATA; - break; + case CMD_INQUIRY_ST11: + if (dev->type == 11 || dev->type == 12) + switch (dev->state) { + case STATE_START_COMMAND: + st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type); + dev->buff_pos = 0; + dev->buff_cnt = 2; + dev->buff[0] = 0x80; /* "ST-11" */ + if (dev->spt == 17) + dev->buff[0] |= 0x40; /* MFM */ + dev->buff[1] = dev->misc; /* revision */ + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + dev->state = STATE_SEND_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } else { - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + else { + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); + } + break; - case CMD_RAM_DIAGNOSTIC: + case CMD_RAM_DIAGNOSTIC: #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: RAM_DIAG\n"); + st506_xt_log("ST506: RAM_DIAG\n"); #endif - st506_complete(dev); - break; + st506_complete(dev); + break; - case CMD_CTRLR_DIAGNOSTIC: + case CMD_CTRLR_DIAGNOSTIC: #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: CTRLR_DIAG\n"); + st506_xt_log("ST506: CTRLR_DIAG\n"); #endif - st506_complete(dev); - break; + st506_complete(dev); + break; - case CMD_SET_STEP_RATE_DTC: - if (dev->type == 1) { - /* For DTC, we are done. */ - st506_complete(dev); - } else if (dev->type == 11 || dev->type == 12) { - /* - * For Seagate ST-11, this is WriteGeometry. - * - * This writes the contents of the buffer to track 0. - * - * By the time this command is sent, it will have - * formatted the first track, so it should be good, - * and our sector buffer contains the magic data - * (see above) we need to write to it. - */ - (void)get_chs(dev, drive); - st506_xt_log("ST506: WRITE BUFFER (%i, %i/%i/%i, %i)\n", - dev->drive_sel, dev->cylinder, - dev->head, dev->sector, dev->count); + case CMD_SET_STEP_RATE_DTC: + if (dev->type == 1) { + /* For DTC, we are done. */ + st506_complete(dev); + } else if (dev->type == 11 || dev->type == 12) { + /* + * For Seagate ST-11, this is WriteGeometry. + * + * This writes the contents of the buffer to track 0. + * + * By the time this command is sent, it will have + * formatted the first track, so it should be good, + * and our sector buffer contains the magic data + * (see above) we need to write to it. + */ + (void) get_chs(dev, drive); + st506_xt_log("ST506: WRITE BUFFER (%i, %i/%i/%i, %i)\n", + dev->drive_sel, dev->cylinder, + dev->head, dev->sector, dev->count); - if (! get_sector(dev, drive, &addr)) { - st506_error(dev, ERR_BAD_PARAMETER); - st506_complete(dev); - return; - } + if (!get_sector(dev, drive, &addr)) { + st506_error(dev, ERR_BAD_PARAMETER); + st506_complete(dev); + return; + } - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); - /* Write data to image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->buff); + /* Write data to image. */ + hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff); - if (--dev->count == 0) { - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - st506_complete(dev); - break; - } + if (--dev->count == 0) { + ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); + st506_complete(dev); + break; + } - next_sector(dev, drive); - timer_advance_u64(&dev->timer, ST506_TIME); - break; - } else { - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); - } - break; + next_sector(dev, drive); + timer_advance_u64(&dev->timer, ST506_TIME); + break; + } else { + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); + } + break; - case CMD_GET_DRIVE_PARAMS_DTC: - switch (dev->state) { - case STATE_START_COMMAND: - dev->buff_pos = 0; - dev->buff_cnt = 4; - memset(dev->buff, 0x00, dev->buff_cnt); - dev->buff[0] = drive->tracks & 0xff; - dev->buff[1] = ((drive->tracks >> 2) & 0xc0) | dev->spt; - dev->buff[2] = drive->hpc - 1; - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - dev->state = STATE_SEND_DATA; - break; + case CMD_GET_DRIVE_PARAMS_DTC: + switch (dev->state) { + case STATE_START_COMMAND: + dev->buff_pos = 0; + dev->buff_cnt = 4; + memset(dev->buff, 0x00, dev->buff_cnt); + dev->buff[0] = drive->tracks & 0xff; + dev->buff[1] = ((drive->tracks >> 2) & 0xc0) | dev->spt; + dev->buff[2] = drive->hpc - 1; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + dev->state = STATE_SEND_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + break; - case CMD_SET_GEOMETRY_DTC: - switch (dev->state) { - case STATE_START_COMMAND: - val = dev->command[1] & 0x01; - st506_xt_log("ST506: DTC_GET_GEOMETRY(%i) %i\n", - dev->drive_sel, val); - dev->buff_pos = 0; - dev->buff_cnt = 16; - dev->status = STAT_BSY | STAT_REQ; - dev->state = STATE_RECEIVE_DATA; - break; + case CMD_SET_GEOMETRY_DTC: + switch (dev->state) { + case STATE_START_COMMAND: + val = dev->command[1] & 0x01; + st506_xt_log("ST506: DTC_GET_GEOMETRY(%i) %i\n", + dev->drive_sel, val); + dev->buff_pos = 0; + dev->buff_cnt = 16; + dev->status = STAT_BSY | STAT_REQ; + dev->state = STATE_RECEIVE_DATA; + break; - case STATE_RECEIVED_DATA: - /* FIXME: ignore the results. */ - st506_complete(dev); - break; - } - break; + case STATE_RECEIVED_DATA: + /* FIXME: ignore the results. */ + st506_complete(dev); + break; + } + break; - case CMD_GET_GEOMETRY_DTC: - switch (dev->state) { - case STATE_START_COMMAND: - val = dev->command[1] & 0x01; - st506_xt_log("ST506: DTC_GET_GEOMETRY(%i) %i\n", - dev->drive_sel, val); - dev->buff_pos = 0; - dev->buff_cnt = 16; - memset(dev->buff, 0x00, dev->buff_cnt); - dev->buff[4] = drive->tracks & 0xff; - dev->buff[5] = (drive->tracks >> 8) & 0xff; - dev->buff[10] = drive->hpc; - dev->status = STAT_BSY | STAT_IO | STAT_REQ; - dev->state = STATE_SEND_DATA; - break; + case CMD_GET_GEOMETRY_DTC: + switch (dev->state) { + case STATE_START_COMMAND: + val = dev->command[1] & 0x01; + st506_xt_log("ST506: DTC_GET_GEOMETRY(%i) %i\n", + dev->drive_sel, val); + dev->buff_pos = 0; + dev->buff_cnt = 16; + memset(dev->buff, 0x00, dev->buff_cnt); + dev->buff[4] = drive->tracks & 0xff; + dev->buff[5] = (drive->tracks >> 8) & 0xff; + dev->buff[10] = drive->hpc; + dev->status = STAT_BSY | STAT_IO | STAT_REQ; + dev->state = STATE_SEND_DATA; + break; - case STATE_SENT_DATA: - st506_complete(dev); - break; - } - break; + case STATE_SENT_DATA: + st506_complete(dev); + break; + } + break; - default: - if (dev->command[0] == CMD_WRITE_GEOMETRY_ST11) - fatal("CMD_WRITE_GEOMETRY_ST11\n"); + default: + if (dev->command[0] == CMD_WRITE_GEOMETRY_ST11) + fatal("CMD_WRITE_GEOMETRY_ST11\n"); #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: unknown command:\n"); + st506_xt_log("ST506: unknown command:\n"); #endif - st506_xt_log("ST506: %02x %02x %02x %02x %02x %02x\n", - dev->command[0], dev->command[1], dev->command[2], - dev->command[3], dev->command[4], dev->command[5]); - st506_error(dev, ERR_BAD_COMMAND); - st506_complete(dev); + st506_xt_log("ST506: %02x %02x %02x %02x %02x %02x\n", + dev->command[0], dev->command[1], dev->command[2], + dev->command[3], dev->command[4], dev->command[5]); + st506_error(dev, ERR_BAD_COMMAND); + st506_complete(dev); } } - /* Read from one of the registers. */ static uint8_t st506_read(uint16_t port, void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; uint8_t ret = 0xff; switch (port & 3) { - case 0: /* read data */ - dev->status &= ~STAT_IRQ; - switch (dev->state) { - case STATE_COMPLETION_BYTE: - ret = dev->compl; - dev->status = 0x00; - dev->state = STATE_IDLE; - break; + case 0: /* read data */ + dev->status &= ~STAT_IRQ; + switch (dev->state) { + case STATE_COMPLETION_BYTE: + ret = dev->compl ; + dev->status = 0x00; + dev->state = STATE_IDLE; + break; - case STATE_SEND_DATA: - ret = dev->buff[dev->buff_pos++]; - if (dev->buff_pos == dev->buff_cnt) { - dev->buff_pos = 0; - dev->buff_cnt = 0; - dev->status = STAT_BSY; - dev->state = STATE_SENT_DATA; - timer_set_delay_u64(&dev->timer, ST506_TIME); - } - break; - } - break; + case STATE_SEND_DATA: + ret = dev->buff[dev->buff_pos++]; + if (dev->buff_pos == dev->buff_cnt) { + dev->buff_pos = 0; + dev->buff_cnt = 0; + dev->status = STAT_BSY; + dev->state = STATE_SENT_DATA; + timer_set_delay_u64(&dev->timer, ST506_TIME); + } + break; + } + break; - case 1: /* read status */ - ret = dev->status; - if ((dev->irq_dma & DMA_ENA) && dma_get_drq(dev->dma)) - ret |= STAT_DRQ; - break; + case 1: /* read status */ + ret = dev->status; + if ((dev->irq_dma & DMA_ENA) && dma_get_drq(dev->dma)) + ret |= STAT_DRQ; + break; - case 2: /* read option jumpers */ - ret = dev->switches; - break; + case 2: /* read option jumpers */ + ret = dev->switches; + break; } st506_xt_log("ST506: read(%04x) = %02x\n", port, ret); - return(ret); + return (ret); } - /* Write to one of the registers. */ static void 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); switch (port & 3) { - case 0: /* write data */ - switch (dev->state) { - case STATE_RECEIVE_COMMAND: /* command data */ - /* Write directly to the command buffer to avoid overwriting - the data buffer. */ - dev->command[dev->buff_pos++] = val; - if (dev->buff_pos == dev->buff_cnt) { - /* We have a new command. */ - dev->buff_pos = 0; - dev->buff_cnt = 0; - dev->status = STAT_BSY; - dev->state = STATE_START_COMMAND; - timer_set_delay_u64(&dev->timer, ST506_TIME); - } - break; + case 0: /* write data */ + switch (dev->state) { + case STATE_RECEIVE_COMMAND: /* command data */ + /* Write directly to the command buffer to avoid overwriting + the data buffer. */ + dev->command[dev->buff_pos++] = val; + if (dev->buff_pos == dev->buff_cnt) { + /* We have a new command. */ + dev->buff_pos = 0; + dev->buff_cnt = 0; + dev->status = STAT_BSY; + dev->state = STATE_START_COMMAND; + timer_set_delay_u64(&dev->timer, ST506_TIME); + } + break; - case STATE_RECEIVE_DATA: /* data */ - dev->buff[dev->buff_pos++] = val; - if (dev->buff_pos == dev->buff_cnt) { - dev->buff_pos = 0; - dev->buff_cnt = 0; - dev->status = STAT_BSY; - dev->state = STATE_RECEIVED_DATA; - timer_set_delay_u64(&dev->timer, ST506_TIME); - } - break; - } - break; + case STATE_RECEIVE_DATA: /* data */ + dev->buff[dev->buff_pos++] = val; + if (dev->buff_pos == dev->buff_cnt) { + dev->buff_pos = 0; + dev->buff_cnt = 0; + dev->status = STAT_BSY; + dev->state = STATE_RECEIVED_DATA; + timer_set_delay_u64(&dev->timer, ST506_TIME); + } + break; + } + break; - case 1: /* controller reset */ - dev->status = 0x00; - break; + case 1: /* controller reset */ + dev->status = 0x00; + break; - case 2: /* generate controller-select-pulse */ - dev->status = STAT_BSY | STAT_CD | STAT_REQ; - dev->buff_pos = 0; - dev->buff_cnt = sizeof(dev->command); - dev->state = STATE_RECEIVE_COMMAND; - break; + case 2: /* generate controller-select-pulse */ + dev->status = STAT_BSY | STAT_CD | STAT_REQ; + dev->buff_pos = 0; + dev->buff_cnt = sizeof(dev->command); + dev->state = STATE_RECEIVE_COMMAND; + break; - case 3: /* DMA/IRQ enable register */ - dev->irq_dma = val; + case 3: /* DMA/IRQ enable register */ + dev->irq_dma = val; - if (!(dev->irq_dma & DMA_ENA)) - dma_set_drq(dev->dma, 0); + if (!(dev->irq_dma & DMA_ENA)) + dma_set_drq(dev->dma, 0); - if (!(dev->irq_dma & IRQ_ENA)) { - dev->status &= ~STAT_IRQ; - picintc(1 << dev->irq); - } - break; + if (!(dev->irq_dma & IRQ_ENA)) { + dev->status &= ~STAT_IRQ; + picintc(1 << dev->irq); + } + break; } } - /* Write to ROM (or scratchpad RAM.) */ static void 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; /* Ignore accesses to anything below the configured address, needed because of the emulator's 4k mapping granularity. */ if (addr < dev->bios_addr) - return; + return; addr -= dev->bios_addr; - switch(dev->type) { - case 11: /* ST-11M */ - case 12: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ - break; + switch (dev->type) { + case 11: /* ST-11M */ + case 12: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + break; - default: - break; + default: + break; } addr &= dev->bios_rom.mask; ptr = (dev->bios_rom.mask & mask) - dev->bios_ram; - if (mask && ((addr & mask) > ptr) && - ((addr & mask) <= (ptr + dev->bios_ram))) - dev->scratch[addr & (dev->bios_ram - 1)] = val; + if (mask && ((addr & mask) > ptr) && ((addr & mask) <= (ptr + dev->bios_ram))) + dev->scratch[addr & (dev->bios_ram - 1)] = val; } - static uint8_t mem_read(uint32_t addr, void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; uint32_t ptr, mask = 0; - uint8_t ret = 0xff; + uint8_t ret = 0xff; /* Ignore accesses to anything below the configured address, needed because of the emulator's 4k mapping granularity. */ if (addr < dev->bios_addr) - return 0xff; + return 0xff; addr -= dev->bios_addr; - switch(dev->type) { - case 0: /* Xebec */ - if (addr >= 0x001000) { + switch (dev->type) { + case 0: /* Xebec */ + if (addr >= 0x001000) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: Xebec ROM access(0x%06lx)\n", addr); + st506_xt_log("ST506: Xebec ROM access(0x%06lx)\n", addr); #endif - return 0xff; - } - break; + return 0xff; + } + break; - case 1: /* DTC */ - default: - if (addr >= 0x002000) { + case 1: /* DTC */ + default: + if (addr >= 0x002000) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: DTC-5150X ROM access(0x%06lx)\n", addr); + st506_xt_log("ST506: DTC-5150X ROM access(0x%06lx)\n", addr); #endif - return 0xff; - } - break; + return 0xff; + } + break; - case 11: /* ST-11M */ - case 12: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ - break; + case 11: /* ST-11M */ + case 12: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + break; - /* default: - break; */ + /* default: + break; */ } addr = addr & dev->bios_rom.mask; ptr = (dev->bios_rom.mask & mask) - dev->bios_ram; - if (mask && ((addr & mask) > ptr) && - ((addr & mask) <= (ptr + dev->bios_ram))) - ret = dev->scratch[addr & (dev->bios_ram - 1)]; + if (mask && ((addr & mask) > ptr) && ((addr & mask) <= (ptr + dev->bios_ram))) + ret = dev->scratch[addr & (dev->bios_ram - 1)]; 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. * @@ -1308,208 +1287,204 @@ static void loadrom(hdc_t *dev, const char *fn) { uint32_t size; - FILE *fp; + FILE *fp; if (fn == NULL) { #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: NULL BIOS ROM file pointer!\n"); + st506_xt_log("ST506: NULL BIOS ROM file pointer!\n"); #endif - return; + return; } if ((fp = rom_fopen((char *) fn, "rb")) == NULL) { - st506_xt_log("ST506: BIOS ROM '%s' not found!\n", fn); - return; + st506_xt_log("ST506: BIOS ROM '%s' not found!\n", fn); + return; } /* Initialize the ROM entry. */ memset(&dev->bios_rom, 0x00, sizeof(rom_t)); /* Manually load and process the ROM image. */ - (void)fseek(fp, 0L, SEEK_END); + (void) fseek(fp, 0L, SEEK_END); size = ftell(fp); - (void)fseek(fp, 0L, SEEK_SET); + (void) fseek(fp, 0L, SEEK_SET); /* 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); if (fread(dev->bios_rom.rom, 1, size, fp) != size) - fatal("ST-506 XT loadrom(): Error reading data\n"); - (void)fclose(fp); + fatal("ST-506 XT loadrom(): Error reading data\n"); + (void) fclose(fp); /* Set up an address mask for this memory. */ - dev->bios_size = size; + dev->bios_size = size; dev->bios_rom.mask = (size - 1); /* Map this system into the memory map. */ mem_mapping_add(&dev->bios_rom.mapping, dev->bios_addr, size, - mem_read,NULL,NULL, mem_write,NULL,NULL, - dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, dev); + mem_read, NULL, NULL, mem_write, NULL, NULL, + dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, dev); } - static void loadhd(hdc_t *dev, int c, int d, const char *fn) { drive_t *drive = &dev->drives[c]; - if (! hdd_image_load(d)) { - drive->present = 0; - return; + if (!hdd_image_load(d)) { + drive->present = 0; + return; } /* Make sure we can do this. */ /* Allow 31 sectors per track on RLL controllers, for the ST225R, which is 667/2/31. */ if ((hdd[d].spt != dev->spt) && (hdd[d].spt != 31) && (dev->spt != 26)) { - /* - * Uh-oh, MFM/RLL mismatch. - * - * Although this would be no issue in the code itself, - * most of the BIOSes were hardwired to whatever their - * native SPT setting was, so, do not allow this here. - */ - st506_xt_log("ST506: drive%i: MFM/RLL mismatch (%i/%i)\n", - c, hdd[d].spt, dev->spt); - hdd_image_close(d); - drive->present = 0; - return; + /* + * Uh-oh, MFM/RLL mismatch. + * + * Although this would be no issue in the code itself, + * most of the BIOSes were hardwired to whatever their + * native SPT setting was, so, do not allow this here. + */ + st506_xt_log("ST506: drive%i: MFM/RLL mismatch (%i/%i)\n", + c, hdd[d].spt, dev->spt); + hdd_image_close(d); + drive->present = 0; + return; } - drive->spt = (uint8_t)hdd[d].spt; - drive->hpc = (uint8_t)hdd[d].hpc; - drive->tracks = (uint16_t)hdd[d].tracks; + drive->spt = (uint8_t) hdd[d].spt; + drive->hpc = (uint8_t) hdd[d].hpc; + drive->tracks = (uint16_t) hdd[d].tracks; drive->hdd_num = d; drive->present = 1; } - /* Set the "drive type" switches for the IBM Xebec controller. */ static void set_switches(hdc_t *dev) { drive_t *drive; - int c, d; + int c, d; dev->switches = 0x00; 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++) { - if ((drive->spt == hd_types[c].spt) && - (drive->hpc == hd_types[c].hpc) && - (drive->tracks == hd_types[c].tracks)) { - dev->switches |= (c << (d ? 0 : 2)); - break; - } - } + for (c = 0; c < 4; c++) { + if ((drive->spt == hd_types[c].spt) && (drive->hpc == hd_types[c].hpc) && (drive->tracks == hd_types[c].tracks)) { + dev->switches |= (c << (d ? 0 : 2)); + break; + } + } #ifdef ENABLE_ST506_XT_LOG - st506_xt_log("ST506: "); - if (c == 4) - st506_xt_log("*WARNING* drive%i unsupported", d); - else - st506_xt_log("drive%i is type %i", d, c); - st506_xt_log(" (%i/%i/%i)\n", drive->tracks, drive->hpc, drive->spt); + st506_xt_log("ST506: "); + if (c == 4) + st506_xt_log("*WARNING* drive%i unsupported", d); + else + st506_xt_log("drive%i is type %i", d, c); + st506_xt_log(" (%i/%i/%i)\n", drive->tracks, drive->hpc, drive->spt); #endif } } - static void * st506_init(const device_t *info) { - char *fn = NULL; + char *fn = NULL; 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)); dev->type = info->local & 255; /* Set defaults for the controller. */ - dev->spt = MFM_SECTORS; - dev->base = 0x0320; - dev->irq = 5; - dev->dma = 3; + dev->spt = MFM_SECTORS; + dev->base = 0x0320; + dev->irq = 5; + dev->dma = 3; dev->bios_addr = 0xc8000; - dev->nr_err = ERR_NOT_READY; + dev->nr_err = ERR_NOT_READY; - switch(dev->type) { - case 0: /* Xebec (MFM) */ - fn = XEBEC_BIOS_FILE; - break; + switch (dev->type) { + case 0: /* Xebec (MFM) */ + fn = XEBEC_BIOS_FILE; + break; - case 1: /* DTC5150 (MFM) */ - fn = DTC_BIOS_FILE; - dev->switches = 0xff; - break; + case 1: /* DTC5150 (MFM) */ + fn = DTC_BIOS_FILE; + dev->switches = 0xff; + break; - case 12: /* Seagate ST-11R (RLL) */ - dev->spt = RLL_SECTORS; - /*FALLTHROUGH*/ + case 12: /* Seagate ST-11R (RLL) */ + dev->spt = RLL_SECTORS; + /*FALLTHROUGH*/ - case 11: /* Seagate ST-11M (MFM) */ - dev->nr_err = ERR_NOT_AVAILABLE; - dev->switches = 0x01; /* fixed */ - dev->misc = device_get_config_int("revision"); - switch (dev->misc) { - case 5: /* v1.7 */ - fn = ST11_BIOS_FILE_OLD; - break; + case 11: /* Seagate ST-11M (MFM) */ + dev->nr_err = ERR_NOT_AVAILABLE; + dev->switches = 0x01; /* fixed */ + dev->misc = device_get_config_int("revision"); + switch (dev->misc) { + case 5: /* v1.7 */ + fn = ST11_BIOS_FILE_OLD; + break; - case 19: /* v2.0 */ - fn = ST11_BIOS_FILE_NEW; - break; - } - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bios_addr = device_get_config_hex20("bios_addr"); - dev->bios_ram = 64; /* scratch RAM size */ + case 19: /* v2.0 */ + fn = ST11_BIOS_FILE_NEW; + break; + } + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + dev->bios_addr = device_get_config_hex20("bios_addr"); + dev->bios_ram = 64; /* scratch RAM size */ - /* - * Industrial Madness Alert. - * - * With the ST-11 controller, Seagate decided to act - * like they owned the industry, and reserved the - * first cylinder of a drive for the controller. So, - * when the host accessed cylinder 0, that would be - * the actual cylinder 1 on the drive, and so on. - */ - dev->cyl_off = 1; - break; + /* + * Industrial Madness Alert. + * + * With the ST-11 controller, Seagate decided to act + * like they owned the industry, and reserved the + * first cylinder of a drive for the controller. So, + * when the host accessed cylinder 0, that would be + * the actual cylinder 1 on the drive, and so on. + */ + dev->cyl_off = 1; + break; - case 21: /* Western Digital WD1002A-WX1 (MFM) */ - dev->nr_err = ERR_NOT_AVAILABLE; - fn = WD1002A_WX1_BIOS_FILE; - /* The switches are read in reverse: 0 = closed, 1 = open. - Both open means MFM, 17 sectors per track. */ - dev->switches = 0x30; /* autobios */ - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - if (dev->irq == 2) - dev->switches |= 0x40; - dev->bios_addr = device_get_config_hex20("bios_addr"); - break; + case 21: /* Western Digital WD1002A-WX1 (MFM) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1002A_WX1_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both open means MFM, 17 sectors per track. */ + dev->switches = 0x30; /* autobios */ + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; - case 22: /* Western Digital WD1002A-27X (RLL) */ - dev->nr_err = ERR_NOT_AVAILABLE; - fn = WD1002A_27X_BIOS_FILE; - /* The switches are read in reverse: 0 = closed, 1 = open. - Both closed means translate 26 sectors per track to 17, - SW6 closed, SW5 open means 26 sectors per track. */ - dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ - dev->spt = RLL_SECTORS; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - if (dev->irq == 2) - dev->switches |= 0x40; - dev->bios_addr = device_get_config_hex20("bios_addr"); - break; + case 22: /* Western Digital WD1002A-27X (RLL) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1002A_27X_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both closed means translate 26 sectors per track to 17, + SW6 closed, SW5 open means 26 sectors per track. */ + dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ + dev->spt = RLL_SECTORS; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; } /* Load the ROM BIOS. */ @@ -1517,119 +1492,117 @@ st506_init(const device_t *info) /* Set up the I/O region. */ 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. */ 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", - 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. */ #ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: looking for disks...\n"); #endif for (c = 0, i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) { - st506_xt_log("ST506: disk '%s' on channel %i\n", - hdd[i].fn, hdd[i].mfm_channel); - loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn); + if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) { + st506_xt_log("ST506: disk '%s' on channel %i\n", + hdd[i].fn, hdd[i].mfm_channel); + 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); /* For the Xebec, set the switches now. */ if (dev->type == 0) - set_switches(dev); + set_switches(dev); /* Initial "active" drive parameters. */ for (c = 0; c < MFM_NUM; c++) { - dev->drives[c].cfg_cyl = dev->drives[c].tracks; - dev->drives[c].cfg_hpc = dev->drives[c].hpc; - dev->drives[c].cfg_spt = dev->drives[c].spt; + dev->drives[c].cfg_cyl = dev->drives[c].tracks; + dev->drives[c].cfg_hpc = dev->drives[c].hpc; + dev->drives[c].cfg_spt = dev->drives[c].spt; } - return(dev); + return (dev); } - static void st506_close(void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; drive_t *drive; - int d; + int d; for (d = 0; d < MFM_NUM; d++) { - drive = &dev->drives[d]; + drive = &dev->drives[d]; - hdd_image_close(drive->hdd_num); + hdd_image_close(drive->hdd_num); } if (dev->bios_rom.rom != NULL) { - free(dev->bios_rom.rom); - dev->bios_rom.rom = NULL; + free(dev->bios_rom.rom); + dev->bios_rom.rom = NULL; } free(dev); } - static int xebec_available(void) { - return(rom_present(XEBEC_BIOS_FILE)); + return (rom_present(XEBEC_BIOS_FILE)); } - static int dtc5150x_available(void) { - return(rom_present(DTC_BIOS_FILE)); + return (rom_present(DTC_BIOS_FILE)); } static int 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 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 wd1002a_wx1_available(void) { - return(rom_present(WD1002A_WX1_BIOS_FILE)); + return (rom_present(WD1002A_WX1_BIOS_FILE)); } static int wd1002a_27x_available(void) { - return(rom_present(WD1002A_27X_BIOS_FILE)); + return (rom_present(WD1002A_27X_BIOS_FILE)); } static int wd1004a_wx1_available(void) { - return(rom_present(WD1004A_WX1_BIOS_FILE)); + return (rom_present(WD1004A_WX1_BIOS_FILE)); } static int wd1004_27x_available(void) { - return(rom_present(WD1004_27X_BIOS_FILE)); + return (rom_present(WD1004_27X_BIOS_FILE)); } static int wd1004a_27x_available(void) { - return(rom_present(WD1004A_27X_BIOS_FILE)); + return (rom_present(WD1004A_27X_BIOS_FILE)); } // clang-format off @@ -1939,127 +1912,127 @@ static const device_config_t wd1004_rll_config[] = { // clang-format on const device_t st506_xt_xebec_device = { - .name = "IBM PC Fixed Disk Adapter (MFM)", + .name = "IBM PC Fixed Disk Adapter (MFM)", .internal_name = "st506_xt", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 0, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 0, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = xebec_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t st506_xt_dtc5150x_device = { - .name = "DTC 5150X MFM Fixed Disk Adapter", + .name = "DTC 5150X MFM Fixed Disk Adapter", .internal_name = "st506_xt_dtc5150x", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 1, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 1, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = dtc5150x_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = dtc_config + .force_redraw = NULL, + .config = dtc_config }; const device_t st506_xt_st11_m_device = { - .name = "ST-11M MFM Fixed Disk Adapter", + .name = "ST-11M MFM Fixed Disk Adapter", .internal_name = "st506_xt_st11_m", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 11, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 11, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = st11_m_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = st11_config + .force_redraw = NULL, + .config = st11_config }; const device_t st506_xt_st11_r_device = { - .name = "ST-11R RLL Fixed Disk Adapter", + .name = "ST-11R RLL Fixed Disk Adapter", .internal_name = "st506_xt_st11_r", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 12, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 12, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = st11_r_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = st11_config + .force_redraw = NULL, + .config = st11_config }; const device_t st506_xt_wd1002a_wx1_device = { - .name = "WD1002A-WX1 MFM Fixed Disk Adapter", + .name = "WD1002A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_wx1", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 21, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = wd1002a_wx1_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = wd_config + .force_redraw = NULL, + .config = wd_config }; const device_t st506_xt_wd1002a_27x_device = { - .name = "WD1002A-27X RLL Fixed Disk Adapter", + .name = "WD1002A-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_27x", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 22, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = wd1002a_27x_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = wd_rll_config + .force_redraw = NULL, + .config = wd_rll_config }; const device_t st506_xt_wd1004a_wx1_device = { - .name = "WD1004A-WX1 MFM Fixed Disk Adapter", + .name = "WD1004A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_wx1", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 21, + .init = st506_init, + .close = st506_close, + .reset = NULL, { wd1004a_wx1_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = wd1004a_config + .force_redraw = NULL, + .config = wd1004a_config }; const device_t st506_xt_wd1004_27x_device = { - .name = "WD1004-27X RLL Fixed Disk Adapter", + .name = "WD1004-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004_27x", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 22, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = wd1004_27x_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = wd1004_rll_config + .force_redraw = NULL, + .config = wd1004_rll_config }; const device_t st506_xt_wd1004a_27x_device = { - .name = "WD1004a-27X RLL Fixed Disk Adapter", + .name = "WD1004a-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_27x", - .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, - .init = st506_init, - .close = st506_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 22, + .init = st506_init, + .close = st506_close, + .reset = NULL, { .available = wd1004a_27x_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = wd_rll_config + .force_redraw = NULL, + .config = wd_rll_config }; diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index 28990bbdb..a0ae17bcb 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -104,11 +104,9 @@ #include <86box/hdc.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 { STATE_IDLE = 0, @@ -121,237 +119,228 @@ enum { STATE_COMPL }; - /* Command values. */ -#define CMD_TEST_READY 0x00 -#define CMD_RECALIBRATE 0x01 - /* unused 0x02 */ -#define CMD_READ_SENSE 0x03 -#define CMD_FORMAT_DRIVE 0x04 -#define CMD_READ_VERIFY 0x05 -#define CMD_FORMAT_TRACK 0x06 -#define CMD_FORMAT_BAD_TRACK 0x07 -#define CMD_READ_SECTORS 0x08 - /* unused 0x09 */ -#define CMD_WRITE_SECTORS 0x0a -#define CMD_SEEK 0x0b -#define CMD_SET_DRIVE_PARAMS 0x0c -#define CMD_READ_ECC_BURST 0x0d -#define CMD_READ_SECTOR_BUFFER 0x0e -#define CMD_WRITE_SECTOR_BUFFER 0x0f -#define CMD_RAM_DIAGS 0xe0 - /* unused 0xe1 */ - /* unused 0xe2 */ -#define CMD_DRIVE_DIAGS 0xe3 -#define CMD_CTRL_DIAGS 0xe4 -#define CMD_READ_LONG 0xe5 -#define CMD_WRITE_LONG 0xe6 +#define CMD_TEST_READY 0x00 +#define CMD_RECALIBRATE 0x01 +/* unused 0x02 */ +#define CMD_READ_SENSE 0x03 +#define CMD_FORMAT_DRIVE 0x04 +#define CMD_READ_VERIFY 0x05 +#define CMD_FORMAT_TRACK 0x06 +#define CMD_FORMAT_BAD_TRACK 0x07 +#define CMD_READ_SECTORS 0x08 +/* unused 0x09 */ +#define CMD_WRITE_SECTORS 0x0a +#define CMD_SEEK 0x0b +#define CMD_SET_DRIVE_PARAMS 0x0c +#define CMD_READ_ECC_BURST 0x0d +#define CMD_READ_SECTOR_BUFFER 0x0e +#define CMD_WRITE_SECTOR_BUFFER 0x0f +#define CMD_RAM_DIAGS 0xe0 +/* unused 0xe1 */ +/* unused 0xe2 */ +#define CMD_DRIVE_DIAGS 0xe3 +#define CMD_CTRL_DIAGS 0xe4 +#define CMD_READ_LONG 0xe5 +#define CMD_WRITE_LONG 0xe6 /* Status register (reg 1) values. */ -#define STAT_REQ 0x01 /* controller needs data transfer */ -#define STAT_IO 0x02 /* direction of transfer (TO bus) */ -#define STAT_CD 0x04 /* transfer of Command or Data */ -#define STAT_BSY 0x08 /* controller is busy */ -#define STAT_DRQ 0x10 /* DMA requested */ -#define STAT_IRQ 0x20 /* interrupt requested */ -#define STAT_DCB 0x80 /* not seen by driver */ +#define STAT_REQ 0x01 /* controller needs data transfer */ +#define STAT_IO 0x02 /* direction of transfer (TO bus) */ +#define STAT_CD 0x04 /* transfer of Command or Data */ +#define STAT_BSY 0x08 /* controller is busy */ +#define STAT_DRQ 0x10 /* DMA requested */ +#define STAT_IRQ 0x20 /* interrupt requested */ +#define STAT_DCB 0x80 /* not seen by driver */ /* Sense Error codes. */ -#define ERR_NOERROR 0x00 /* no error detected */ -#define ERR_NOINDEX 0x01 /* drive did not detect IDX pulse */ -#define ERR_NOSEEK 0x02 /* drive did not complete SEEK */ -#define ERR_WRFAULT 0x03 /* write fault during last cmd */ -#define ERR_NOTRDY 0x04 /* drive did not go READY after cmd */ -#define ERR_NOTRK000 0x06 /* drive did not see TRK0 signal */ -#define ERR_LONGSEEK 0x08 /* long seek in progress */ -#define ERR_IDREAD 0x10 /* ECC error during ID field */ -#define ERR_DATA 0x11 /* uncorrectable ECC err in data */ -#define ERR_NOMARK 0x12 /* no address mark detected */ -#define ERR_NOSECT 0x14 /* sector not found */ -#define ERR_SEEK 0x15 /* seek error */ -#define ERR_ECCDATA 0x18 /* ECC corrected data */ -#define ERR_BADTRK 0x19 /* bad track detected */ -#define ERR_ILLCMD 0x20 /* invalid command received */ -#define ERR_ILLADDR 0x21 /* invalid disk address received */ -#define ERR_BADRAM 0x30 /* bad RAM in sector data buffer */ -#define ERR_BADROM 0x31 /* bad checksum in ROM test */ -#define ERR_BADECC 0x32 /* ECC polynomial generator bad */ +#define ERR_NOERROR 0x00 /* no error detected */ +#define ERR_NOINDEX 0x01 /* drive did not detect IDX pulse */ +#define ERR_NOSEEK 0x02 /* drive did not complete SEEK */ +#define ERR_WRFAULT 0x03 /* write fault during last cmd */ +#define ERR_NOTRDY 0x04 /* drive did not go READY after cmd */ +#define ERR_NOTRK000 0x06 /* drive did not see TRK0 signal */ +#define ERR_LONGSEEK 0x08 /* long seek in progress */ +#define ERR_IDREAD 0x10 /* ECC error during ID field */ +#define ERR_DATA 0x11 /* uncorrectable ECC err in data */ +#define ERR_NOMARK 0x12 /* no address mark detected */ +#define ERR_NOSECT 0x14 /* sector not found */ +#define ERR_SEEK 0x15 /* seek error */ +#define ERR_ECCDATA 0x18 /* ECC corrected data */ +#define ERR_BADTRK 0x19 /* bad track detected */ +#define ERR_ILLCMD 0x20 /* invalid command received */ +#define ERR_ILLADDR 0x21 /* invalid disk address received */ +#define ERR_BADRAM 0x30 /* bad RAM in sector data buffer */ +#define ERR_BADROM 0x31 /* bad checksum in ROM test */ +#define ERR_BADECC 0x32 /* ECC polynomial generator bad */ /* Completion Byte fields. */ -#define COMP_DRIVE 0x20 -#define COMP_ERR 0x02 - -#define IRQ_ENA 0x02 -#define DMA_ENA 0x01 +#define COMP_DRIVE 0x20 +#define COMP_ERR 0x02 +#define IRQ_ENA 0x02 +#define DMA_ENA 0x01 /* The device control block (6 bytes) */ -#pragma pack(push,1) +#pragma pack(push, 1) 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 */ - drvsel :1, /* [5] drive select */ - mbz :2; /* [7:6] 00 */ + uint8_t head : 5, /* [4:0] head number */ + drvsel : 1, /* [5] drive select */ + mbz : 2; /* [7:6] 00 */ - uint8_t sector :6, /* [5:0] sector number 0-63 */ - cyl_high :2; /* [7:6] cylinder [9:8] bits */ + uint8_t sector : 6, /* [5:0] sector number 0-63 */ + 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 */ - uint8_t count; /* [7:0] blk count / interleave */ + uint8_t count; /* [7:0] blk count / interleave */ - uint8_t ctrl; /* [7:0] control field */ + uint8_t ctrl; /* [7:0] control field */ } dcb_t; #pragma pack(pop) /* The (configured) Drive Parameters. */ -#pragma pack(push,1) +#pragma pack(push, 1) typedef struct { - uint8_t cyl_high; /* (MSB) number of cylinders */ - uint8_t cyl_low; /* (LSB) number of cylinders */ - uint8_t heads; /* number of heads per cylinder */ - uint8_t rwc_high; /* (MSB) reduced write current cylinder */ - uint8_t rwc_low; /* (LSB) reduced write current cylinder */ - uint8_t wp_high; /* (MSB) write precompensation cylinder */ - uint8_t wp_low; /* (LSB) write precompensation cylinder */ - uint8_t maxecc; /* max ECC data burst length */ + uint8_t cyl_high; /* (MSB) number of cylinders */ + uint8_t cyl_low; /* (LSB) number of cylinders */ + uint8_t heads; /* number of heads per cylinder */ + uint8_t rwc_high; /* (MSB) reduced write current cylinder */ + uint8_t rwc_low; /* (LSB) reduced write current cylinder */ + uint8_t wp_high; /* (MSB) write precompensation cylinder */ + uint8_t wp_low; /* (LSB) write precompensation cylinder */ + uint8_t maxecc; /* max ECC data burst length */ } dprm_t; #pragma pack(pop) /* Define an attached drive. */ typedef struct { - int8_t id, /* drive ID on bus */ - present, /* drive is present */ - hdd_num, /* index to global disk table */ - type; /* drive type ID */ + int8_t id, /* drive ID on bus */ + present, /* drive is present */ + hdd_num, /* index to global disk table */ + type; /* drive type ID */ - uint16_t cur_cyl; /* last known position of heads */ + uint16_t cur_cyl; /* last known position of heads */ - uint8_t spt, /* active drive parameters */ - hpc; - uint16_t tracks; + uint8_t spt, /* active drive parameters */ + hpc; + uint16_t tracks; - uint8_t cfg_spt, /* configured drive parameters */ - cfg_hpc; - uint16_t cfg_tracks; + uint8_t cfg_spt, /* configured drive parameters */ + cfg_hpc; + uint16_t cfg_tracks; } drive_t; - typedef struct { - const char *name; /* controller name */ + const char *name; /* controller name */ - uint16_t base; /* controller base I/O address */ - int8_t irq; /* controller IRQ channel */ - int8_t dma; /* controller DMA channel */ - int8_t type; /* controller type ID */ + uint16_t base; /* controller base I/O address */ + int8_t irq; /* controller IRQ channel */ + int8_t dma; /* controller DMA channel */ + int8_t type; /* controller type ID */ - uint32_t rom_addr; /* address where ROM is */ - rom_t bios_rom; /* descriptor for the BIOS */ + uint32_t rom_addr; /* address where ROM is */ + rom_t bios_rom; /* descriptor for the BIOS */ /* Controller state. */ - int8_t state; /* controller state */ - uint8_t sense; /* current SENSE ERROR value */ - uint8_t status; /* current operational status */ - uint8_t intr; - uint64_t callback; - pc_timer_t timer; + int8_t state; /* controller state */ + uint8_t sense; /* current SENSE ERROR value */ + uint8_t status; /* current operational status */ + uint8_t intr; + uint64_t callback; + pc_timer_t timer; /* Data transfer. */ - int16_t buf_idx, /* buffer index and pointer */ - buf_len; - uint8_t *buf_ptr; + int16_t buf_idx, /* buffer index and pointer */ + buf_len; + uint8_t *buf_ptr; /* Current operation parameters. */ - dcb_t dcb; /* device control block */ - uint16_t track; /* requested track# */ - uint8_t head, /* requested head# */ - sector, /* requested sector# */ - comp; /* operation completion byte */ - int count; /* requested sector count */ + dcb_t dcb; /* device control block */ + uint16_t track; /* requested track# */ + uint8_t head, /* requested head# */ + sector, /* requested sector# */ + comp; /* operation completion byte */ + int count; /* requested sector count */ - drive_t drives[XTA_NUM]; /* the attached drive(s) */ + drive_t drives[XTA_NUM]; /* the attached drive(s) */ - uint8_t data[512]; /* data buffer */ - uint8_t sector_buf[512]; /* sector buffer */ + uint8_t data[512]; /* data buffer */ + uint8_t sector_buf[512]; /* sector buffer */ } hdc_t; - #ifdef ENABLE_XTA_LOG int xta_do_log = ENABLE_XTA_LOG; - static void xta_log(const char *fmt, ...) { va_list ap; if (xta_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define xta_log(fmt, ...) +# define xta_log(fmt, ...) #endif - static void set_intr(hdc_t *dev) { - dev->status = STAT_REQ|STAT_CD|STAT_IO|STAT_BSY; - dev->state = STATE_COMPL; + dev->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; + dev->state = STATE_COMPL; if (dev->intr & IRQ_ENA) { - dev->status |= STAT_IRQ; - picint(1 << dev->irq); + dev->status |= STAT_IRQ; + picint(1 << dev->irq); } } - /* Get the logical (block) address of a CHS triplet. */ static int get_sector(hdc_t *dev, drive_t *drive, off64_t *addr) { if (drive->cur_cyl != dev->track) { - xta_log("%s: get_sector: wrong cylinder %d/%d\n", - dev->name, drive->cur_cyl, dev->track); - dev->sense = ERR_ILLADDR; - return(1); + xta_log("%s: get_sector: wrong cylinder %d/%d\n", + dev->name, drive->cur_cyl, dev->track); + dev->sense = ERR_ILLADDR; + return (1); } if (dev->head >= drive->hpc) { - xta_log("%s: get_sector: past end of heads\n", dev->name); - dev->sense = ERR_ILLADDR; - return(1); + xta_log("%s: get_sector: past end of heads\n", dev->name); + dev->sense = ERR_ILLADDR; + return (1); } if (dev->sector >= drive->spt) { - xta_log("%s: get_sector: past end of sectors\n", dev->name); - dev->sense = ERR_ILLADDR; - return(1); + xta_log("%s: get_sector: past end of sectors\n", dev->name); + dev->sense = ERR_ILLADDR; + return (1); } /* Calculate logical address (block number) of desired sector. */ - *addr = ((((off64_t) dev->track*drive->hpc) + \ - dev->head)*drive->spt) + dev->sector; + *addr = ((((off64_t) dev->track * drive->hpc) + dev->head) * drive->spt) + dev->sector; - return(0); + return (0); } - static void next_sector(hdc_t *dev, drive_t *drive) { if (++dev->sector >= drive->spt) { - dev->sector = 0; - if (++dev->head >= drive->hpc) { - dev->head = 0; - dev->track++; - if (++drive->cur_cyl >= drive->tracks) - drive->cur_cyl = (drive->tracks - 1); - } + dev->sector = 0; + if (++dev->head >= drive->hpc) { + dev->head = 0; + dev->track++; + if (++drive->cur_cyl >= drive->tracks) + drive->cur_cyl = (drive->tracks - 1); + } } } @@ -359,19 +348,18 @@ static void xta_set_callback(hdc_t *dev, uint64_t callback) { if (!dev) { - return; + return; } if (callback) { - dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_disable(&dev->timer); - } + dev->callback = callback; + timer_set_delay_u64(&dev->timer, dev->callback); + } else { + dev->callback = 0; + timer_disable(&dev->timer); + } } - /* Perform the seek operation. */ static void do_seek(hdc_t *dev, drive_t *drive, int cyl) @@ -379,623 +367,617 @@ do_seek(hdc_t *dev, drive_t *drive, int cyl) dev->track = cyl; if (dev->track >= drive->tracks) - drive->cur_cyl = (drive->tracks - 1); - else - drive->cur_cyl = dev->track; + drive->cur_cyl = (drive->tracks - 1); + else + drive->cur_cyl = dev->track; } - /* Format a track or an entire drive. */ static void do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb) { - int start_cyl, end_cyl; - int start_hd, end_hd; + int start_cyl, end_cyl; + int start_hd, end_hd; off64_t addr; - int h, s; + int h, s; /* Get the parameters from the DCB. */ if (dcb->cmd == CMD_FORMAT_DRIVE) { - start_cyl = 0; - start_hd = 0; - end_cyl = drive->tracks; - end_hd = drive->hpc; + start_cyl = 0; + start_hd = 0; + end_cyl = drive->tracks; + end_hd = drive->hpc; } else { - start_cyl = (dcb->cyl_low | (dcb->cyl_high << 8)); - start_hd = dcb->head; - end_cyl = start_cyl + 1; - end_hd = start_hd + 1; + start_cyl = (dcb->cyl_low | (dcb->cyl_high << 8)); + start_hd = dcb->head; + end_cyl = start_cyl + 1; + end_hd = start_hd + 1; } switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, start_cyl); - dev->head = dcb->head; - dev->sector = 0; + case STATE_IDLE: + /* Seek to cylinder. */ + do_seek(dev, drive, start_cyl); + dev->head = dcb->head; + dev->sector = 0; - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); + /* Activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1); do_fmt: - /* - * For now, we don't use the interleave factor (in - * dcb->count), although we should one day use an - * image format that can handle it.. - * - * That said, we have been given a sector_buf of - * data to fill the sectors with, so we will use - * that at least. - */ - for (h = start_hd; h < end_hd; h++) { - for (s = 0; s < drive->spt; s++) { - /* Set the sector we need to write. */ - dev->head = h; - dev->sector = s; + /* + * For now, we don't use the interleave factor (in + * dcb->count), although we should one day use an + * image format that can handle it.. + * + * That said, we have been given a sector_buf of + * data to fill the sectors with, so we will use + * that at least. + */ + for (h = start_hd; h < end_hd; h++) { + for (s = 0; s < drive->spt; s++) { + /* Set the sector we need to write. */ + dev->head = h; + dev->sector = s; - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) break; + /* Get address of sector to write. */ + if (get_sector(dev, drive, &addr)) + break; - /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); - } - } + /* Write the block to the image. */ + hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf); + } + } - /* One more track done. */ - if (++start_cyl == end_cyl) break; + /* One more track done. */ + if (++start_cyl == end_cyl) + break; - /* This saves us a LOT of code. */ - goto do_fmt; + /* This saves us a LOT of code. */ + goto do_fmt; } /* 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. */ static void hdc_callback(void *priv) { - hdc_t *dev = (hdc_t *)priv; - dcb_t *dcb = &dev->dcb; + hdc_t *dev = (hdc_t *) priv; + dcb_t *dcb = &dev->dcb; drive_t *drive; - dprm_t *params; - off64_t addr; - int no_data = 0; - int val; + dprm_t *params; + off64_t addr; + int no_data = 0; + int val; /* Cancel timer. */ xta_set_callback(dev, 0); - drive = &dev->drives[dcb->drvsel]; + drive = &dev->drives[dcb->drvsel]; dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00; dev->status |= STAT_DCB; switch (dcb->cmd) { - case CMD_TEST_READY: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; + case CMD_TEST_READY: + if (!drive->present) { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + } + set_intr(dev); + break; - case CMD_RECALIBRATE: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } else { - dev->track = drive->cur_cyl = 0; - } - set_intr(dev); - break; + case CMD_RECALIBRATE: + if (!drive->present) { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + } else { + dev->track = drive->cur_cyl = 0; + } + set_intr(dev); + break; - case CMD_READ_SENSE: - switch(dev->state) { - case STATE_IDLE: - dev->buf_idx = 0; - dev->buf_len = 4; - dev->buf_ptr = dev->data; - dev->buf_ptr[0] = dev->sense; - dev->buf_ptr[1] = dcb->drvsel ? 0x20 : 0x00; - dev->buf_ptr[2] = (drive->cur_cyl >> 2) | \ - (dev->sector & 0x3f); - dev->buf_ptr[3] = (drive->cur_cyl & 0xff); - dev->sense = ERR_NOERROR; - dev->status |= (STAT_IO | STAT_REQ); - dev->state = STATE_SDATA; - break; + case CMD_READ_SENSE: + switch (dev->state) { + case STATE_IDLE: + dev->buf_idx = 0; + dev->buf_len = 4; + dev->buf_ptr = dev->data; + dev->buf_ptr[0] = dev->sense; + dev->buf_ptr[1] = dcb->drvsel ? 0x20 : 0x00; + dev->buf_ptr[2] = (drive->cur_cyl >> 2) | (dev->sector & 0x3f); + dev->buf_ptr[3] = (drive->cur_cyl & 0xff); + dev->sense = ERR_NOERROR; + dev->status |= (STAT_IO | STAT_REQ); + dev->state = STATE_SDATA; + break; - case STATE_SDONE: - set_intr(dev); - } - break; + case STATE_SDONE: + set_intr(dev); + } + break; - case CMD_READ_VERIFY: - no_data = 1; - /*FALLTHROUGH*/ + case CMD_READ_VERIFY: + no_data = 1; + /*FALLTHROUGH*/ - case CMD_READ_SECTORS: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - break; - } + case CMD_READ_SECTORS: + if (!drive->present) { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + set_intr(dev); + break; + } - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, - (dcb->cyl_low|(dcb->cyl_high<<8))); - dev->head = dcb->head; - dev->sector = dcb->sector; + switch (dev->state) { + case STATE_IDLE: + /* Seek to cylinder. */ + do_seek(dev, drive, + (dcb->cyl_low | (dcb->cyl_high << 8))); + dev->head = dcb->head; + dev->sector = dcb->sector; - /* Get sector count; count=0 means 256. */ - dev->count = (int)dcb->count; - if (dev->count == 0) - dev->count = 256; - dev->buf_len = 512; + /* Get sector count; count=0 means 256. */ + dev->count = (int) dcb->count; + if (dev->count == 0) + dev->count = 256; + dev->buf_len = 512; - dev->state = STATE_SEND; - /*FALLTHROUGH*/ + dev->state = STATE_SEND; + /*FALLTHROUGH*/ - case STATE_SEND: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); + case STATE_SEND: + /* Activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1); do_send: - /* Get address of sector to load. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); - dev->comp |= COMP_ERR; - set_intr(dev); - return; - } + /* Get address of sector to load. */ + if (get_sector(dev, drive, &addr)) { + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); + dev->comp |= COMP_ERR; + set_intr(dev); + return; + } - /* Read the block from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); + /* Read the block from the image. */ + hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf); - /* Ready to transfer the data out. */ - dev->state = STATE_SDATA; - dev->buf_idx = 0; - if (no_data) { - /* Delay a bit, no actual transfer. */ - xta_set_callback(dev, HDC_TIME); - } else { - if (dev->intr & DMA_ENA) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); - } else { - /* Copy from sector to data. */ - memcpy(dev->data, - dev->sector_buf, - dev->buf_len); - dev->buf_ptr = dev->data; + /* Ready to transfer the data out. */ + dev->state = STATE_SDATA; + dev->buf_idx = 0; + if (no_data) { + /* Delay a bit, no actual transfer. */ + xta_set_callback(dev, HDC_TIME); + } else { + if (dev->intr & DMA_ENA) { + /* DMA enabled. */ + dev->buf_ptr = dev->sector_buf; + xta_set_callback(dev, HDC_TIME); + } else { + /* Copy from sector to data. */ + memcpy(dev->data, + dev->sector_buf, + dev->buf_len); + dev->buf_ptr = dev->data; - dev->status |= (STAT_IO | STAT_REQ); - } - } - break; + dev->status |= (STAT_IO | STAT_REQ); + } + } + break; - case STATE_SDATA: - if (! no_data) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_write(dev->dma, - *dev->buf_ptr); - 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); + case STATE_SDATA: + if (!no_data) { + /* Perform DMA. */ + while (dev->buf_idx < dev->buf_len) { + val = dma_channel_write(dev->dma, + *dev->buf_ptr); + 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); - dev->status |= (STAT_CD | STAT_IO| STAT_REQ); - xta_set_callback(dev, HDC_TIME); - return; - } - dev->buf_ptr++; - dev->buf_idx++; - } - } - xta_set_callback(dev, HDC_TIME); - dev->state = STATE_SDONE; - break; + dev->status |= (STAT_CD | STAT_IO | STAT_REQ); + xta_set_callback(dev, HDC_TIME); + return; + } + dev->buf_ptr++; + dev->buf_idx++; + } + } + xta_set_callback(dev, HDC_TIME); + dev->state = STATE_SDONE; + break; - case STATE_SDONE: - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); + case STATE_SDONE: + dev->buf_idx = 0; + if (--dev->count == 0) { + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); - set_intr(dev); - return; - } + set_intr(dev); + return; + } - /* Addvance to next sector. */ - next_sector(dev, drive); + /* Addvance to next sector. */ + next_sector(dev, drive); - /* This saves us a LOT of code. */ - dev->state = STATE_SEND; - goto do_send; - } - break; + /* This saves us a LOT of code. */ + dev->state = STATE_SEND; + goto do_send; + } + break; - case CMD_WRITE_SECTORS: - if (! drive->present) { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - break; - } + case CMD_WRITE_SECTORS: + if (!drive->present) { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + set_intr(dev); + break; + } - switch (dev->state) { - case STATE_IDLE: - /* Seek to cylinder. */ - do_seek(dev, drive, - (dcb->cyl_low|(dcb->cyl_high<<8))); - dev->head = dcb->head; - dev->sector = dcb->sector; + switch (dev->state) { + case STATE_IDLE: + /* Seek to cylinder. */ + do_seek(dev, drive, + (dcb->cyl_low | (dcb->cyl_high << 8))); + dev->head = dcb->head; + dev->sector = dcb->sector; - /* Get sector count; count=0 means 256. */ - dev->count = (int)dev->dcb.count; - if (dev->count == 0) - dev->count = 256; - dev->buf_len = 512; + /* Get sector count; count=0 means 256. */ + dev->count = (int) dev->dcb.count; + if (dev->count == 0) + dev->count = 256; + dev->buf_len = 512; - dev->state = STATE_RECV; - /*FALLTHROUGH*/ + dev->state = STATE_RECV; + /*FALLTHROUGH*/ - case STATE_RECV: - /* Activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 1); + case STATE_RECV: + /* Activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1); do_recv: - /* Ready to transfer the data in. */ - dev->state = STATE_RDATA; - dev->buf_idx = 0; - if (dev->intr & DMA_ENA) { - /* DMA enabled. */ - dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); - } else { - /* No DMA, do PIO. */ - dev->buf_ptr = dev->data; - dev->status |= STAT_REQ; - } - break; + /* Ready to transfer the data in. */ + dev->state = STATE_RDATA; + dev->buf_idx = 0; + if (dev->intr & DMA_ENA) { + /* DMA enabled. */ + dev->buf_ptr = dev->sector_buf; + xta_set_callback(dev, HDC_TIME); + } else { + /* No DMA, do PIO. */ + dev->buf_ptr = dev->data; + dev->status |= STAT_REQ; + } + break; - case STATE_RDATA: - if (! no_data) { - /* Perform DMA. */ - dev->status = STAT_BSY; - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - xta_log("%s: CMD_WRITE_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); + case STATE_RDATA: + if (!no_data) { + /* Perform DMA. */ + dev->status = STAT_BSY; + while (dev->buf_idx < dev->buf_len) { + val = dma_channel_read(dev->dma); + if (val == DMA_NODATA) { + xta_log("%s: CMD_WRITE_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); - xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name); - dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); - return; - } + xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name); + dev->status |= (STAT_CD | STAT_IO | STAT_REQ); + xta_set_callback(dev, HDC_TIME); + return; + } - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); - } - break; + dev->buf_ptr[dev->buf_idx] = (val & 0xff); + dev->buf_idx++; + } + dev->state = STATE_RDONE; + xta_set_callback(dev, HDC_TIME); + } + break; - case STATE_RDONE: - /* Copy from data to sector if PIO. */ - if (! (dev->intr & DMA_ENA)) - memcpy(dev->sector_buf, dev->data, - dev->buf_len); + case STATE_RDONE: + /* Copy from data to sector if PIO. */ + if (!(dev->intr & DMA_ENA)) + memcpy(dev->sector_buf, dev->data, + dev->buf_len); - /* Get address of sector to write. */ - if (get_sector(dev, drive, &addr)) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); + /* Get address of sector to write. */ + if (get_sector(dev, drive, &addr)) { + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); - dev->comp |= COMP_ERR; - set_intr(dev); - return; - } + dev->comp |= COMP_ERR; + set_intr(dev); + return; + } - /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)dev->sector_buf); + /* Write the block to the image. */ + hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf); - dev->buf_idx = 0; - if (--dev->count == 0) { - /* De-activate the status icon. */ - ui_sb_update_icon(SB_HDD|HDD_BUS_XTA, 0); + dev->buf_idx = 0; + if (--dev->count == 0) { + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); - set_intr(dev); - return; - } + set_intr(dev); + return; + } - /* Advance to next sector. */ - next_sector(dev, drive); + /* Advance to next sector. */ + next_sector(dev, drive); - /* This saves us a LOT of code. */ - dev->state = STATE_RECV; - goto do_recv; - } - break; + /* This saves us a LOT of code. */ + dev->state = STATE_RECV; + goto do_recv; + } + break; - case CMD_FORMAT_DRIVE: - case CMD_FORMAT_TRACK: - if (drive->present) { - do_format(dev, drive, dcb); - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; + case CMD_FORMAT_DRIVE: + case CMD_FORMAT_TRACK: + if (drive->present) { + do_format(dev, drive, dcb); + } else { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + } + set_intr(dev); + break; - case CMD_SEEK: - /* Seek to cylinder. */ - val = (dcb->cyl_low | (dcb->cyl_high << 8)); - if (drive->present) { - do_seek(dev, drive, val); - if (val != drive->cur_cyl) { - dev->comp |= COMP_ERR; - dev->sense = ERR_SEEK; - } - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - } - set_intr(dev); - break; + case CMD_SEEK: + /* Seek to cylinder. */ + val = (dcb->cyl_low | (dcb->cyl_high << 8)); + if (drive->present) { + do_seek(dev, drive, val); + if (val != drive->cur_cyl) { + dev->comp |= COMP_ERR; + dev->sense = ERR_SEEK; + } + } else { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + } + set_intr(dev); + break; - case CMD_SET_DRIVE_PARAMS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDATA; - dev->buf_idx = 0; - dev->buf_len = sizeof(dprm_t); - dev->buf_ptr = (uint8_t *)dev->data; - dev->status |= STAT_REQ; - break; + case CMD_SET_DRIVE_PARAMS: + switch (dev->state) { + case STATE_IDLE: + dev->state = STATE_RDATA; + dev->buf_idx = 0; + dev->buf_len = sizeof(dprm_t); + dev->buf_ptr = (uint8_t *) dev->data; + dev->status |= STAT_REQ; + break; - case STATE_RDONE: - params = (dprm_t *)dev->data; - drive->tracks = - (params->cyl_high << 8) | params->cyl_low; - drive->hpc = params->heads; - drive->spt = 17 /*hardcoded*/; - dev->status &= ~STAT_REQ; - set_intr(dev); - break; - } - break; + case STATE_RDONE: + params = (dprm_t *) dev->data; + drive->tracks = (params->cyl_high << 8) | params->cyl_low; + drive->hpc = params->heads; + drive->spt = 17 /*hardcoded*/; + dev->status &= ~STAT_REQ; + set_intr(dev); + break; + } + break; - case CMD_WRITE_SECTOR_BUFFER: - switch (dev->state) { - case STATE_IDLE: - dev->buf_idx = 0; - dev->buf_len = 512; - dev->state = STATE_RDATA; - if (dev->intr & DMA_ENA) { - dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); - } else { - dev->buf_ptr = dev->data; - dev->status |= STAT_REQ; - } - break; + case CMD_WRITE_SECTOR_BUFFER: + switch (dev->state) { + case STATE_IDLE: + dev->buf_idx = 0; + dev->buf_len = 512; + dev->state = STATE_RDATA; + if (dev->intr & DMA_ENA) { + dev->buf_ptr = dev->sector_buf; + xta_set_callback(dev, HDC_TIME); + } else { + dev->buf_ptr = dev->data; + dev->status |= STAT_REQ; + } + break; - case STATE_RDATA: - if (dev->intr & DMA_ENA) { - /* Perform DMA. */ - while (dev->buf_idx < dev->buf_len) { - val = dma_channel_read(dev->dma); - if (val == DMA_NODATA) { - xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name); - dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); - return; - } + case STATE_RDATA: + if (dev->intr & DMA_ENA) { + /* Perform DMA. */ + while (dev->buf_idx < dev->buf_len) { + val = dma_channel_read(dev->dma); + if (val == DMA_NODATA) { + xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name); + dev->status |= (STAT_CD | STAT_IO | STAT_REQ); + xta_set_callback(dev, HDC_TIME); + return; + } - dev->buf_ptr[dev->buf_idx] = (val & 0xff); - dev->buf_idx++; - } - dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); - } - break; + dev->buf_ptr[dev->buf_idx] = (val & 0xff); + dev->buf_idx++; + } + dev->state = STATE_RDONE; + xta_set_callback(dev, HDC_TIME); + } + break; - case STATE_RDONE: - if (! (dev->intr & DMA_ENA)) - memcpy(dev->sector_buf, - dev->data, dev->buf_len); - set_intr(dev); - break; - } - break; + case STATE_RDONE: + if (!(dev->intr & DMA_ENA)) + memcpy(dev->sector_buf, + dev->data, dev->buf_len); + set_intr(dev); + break; + } + break; - case CMD_RAM_DIAGS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); - break; + case CMD_RAM_DIAGS: + switch (dev->state) { + case STATE_IDLE: + dev->state = STATE_RDONE; + xta_set_callback(dev, 5 * HDC_TIME); + break; - case STATE_RDONE: - set_intr(dev); - break; - } - break; + case STATE_RDONE: + set_intr(dev); + break; + } + break; - case CMD_DRIVE_DIAGS: - switch(dev->state) { - case STATE_IDLE: - if (drive->present) { - dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); - } else { - dev->comp |= COMP_ERR; - dev->sense = ERR_NOTRDY; - set_intr(dev); - } - break; + case CMD_DRIVE_DIAGS: + switch (dev->state) { + case STATE_IDLE: + if (drive->present) { + dev->state = STATE_RDONE; + xta_set_callback(dev, 5 * HDC_TIME); + } else { + dev->comp |= COMP_ERR; + dev->sense = ERR_NOTRDY; + set_intr(dev); + } + break; - case STATE_RDONE: - set_intr(dev); - break; - } - break; + case STATE_RDONE: + set_intr(dev); + break; + } + break; - case CMD_CTRL_DIAGS: - switch(dev->state) { - case STATE_IDLE: - dev->state = STATE_RDONE; - xta_set_callback(dev, 10 * HDC_TIME); - break; + case CMD_CTRL_DIAGS: + switch (dev->state) { + case STATE_IDLE: + dev->state = STATE_RDONE; + xta_set_callback(dev, 10 * HDC_TIME); + break; - case STATE_RDONE: - set_intr(dev); - break; - } - break; + case STATE_RDONE: + set_intr(dev); + break; + } + break; - default: - xta_log("%s: unknown command - %02x\n", dev->name, dcb->cmd); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - set_intr(dev); + default: + xta_log("%s: unknown command - %02x\n", dev->name, dcb->cmd); + dev->comp |= COMP_ERR; + dev->sense = ERR_ILLCMD; + set_intr(dev); } } - /* Read one of the controller registers. */ static uint8_t hdc_read(uint16_t port, void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; uint8_t ret = 0xff; switch (port & 7) { - case 0: /* DATA register */ - dev->status &= ~STAT_IRQ; + case 0: /* DATA register */ + dev->status &= ~STAT_IRQ; - if (dev->state == STATE_SDATA) { - if (dev->buf_idx > dev->buf_len) { - xta_log("%s: read with empty buffer!\n", - dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } + if (dev->state == STATE_SDATA) { + if (dev->buf_idx > dev->buf_len) { + xta_log("%s: read with empty buffer!\n", + dev->name); + dev->comp |= COMP_ERR; + dev->sense = ERR_ILLCMD; + break; + } - ret = dev->buf_ptr[dev->buf_idx]; - if (++dev->buf_idx == dev->buf_len) { - /* All data sent. */ - dev->status &= ~STAT_REQ; - dev->state = STATE_SDONE; - xta_set_callback(dev, HDC_TIME); - } - } else if (dev->state == STATE_COMPL) { -xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp); - ret = dev->comp; - dev->status = 0x00; - dev->state = STATE_IDLE; - } - break; + ret = dev->buf_ptr[dev->buf_idx]; + if (++dev->buf_idx == dev->buf_len) { + /* All data sent. */ + dev->status &= ~STAT_REQ; + dev->state = STATE_SDONE; + xta_set_callback(dev, HDC_TIME); + } + } else if (dev->state == STATE_COMPL) { + xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp); + ret = dev->comp; + dev->status = 0x00; + dev->state = STATE_IDLE; + } + break; - case 1: /* STATUS register */ - ret = (dev->status & ~STAT_DCB); - break; + case 1: /* STATUS register */ + ret = (dev->status & ~STAT_DCB); + break; - case 2: /* "read option jumpers" */ - ret = 0xff; /* all switches off */ - break; + case 2: /* "read option jumpers" */ + ret = 0xff; /* all switches off */ + break; } - return(ret); + return (ret); } - /* Write to one of the controller registers. */ static void 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) { - case 0: /* DATA register */ - if (dev->state == STATE_RDATA) { - if (! (dev->status & STAT_REQ)) { - xta_log("%s: not ready for command/data!\n", dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } + case 0: /* DATA register */ + if (dev->state == STATE_RDATA) { + if (!(dev->status & STAT_REQ)) { + xta_log("%s: not ready for command/data!\n", dev->name); + dev->comp |= COMP_ERR; + dev->sense = ERR_ILLCMD; + break; + } - if (dev->buf_idx >= dev->buf_len) { - xta_log("%s: write with full buffer!\n", dev->name); - dev->comp |= COMP_ERR; - dev->sense = ERR_ILLCMD; - break; - } + if (dev->buf_idx >= dev->buf_len) { + xta_log("%s: write with full buffer!\n", dev->name); + dev->comp |= COMP_ERR; + dev->sense = ERR_ILLCMD; + break; + } - /* Store the data into the buffer. */ - dev->buf_ptr[dev->buf_idx] = val; - if (++dev->buf_idx == dev->buf_len) { - /* We got all the data we need. */ - dev->status &= ~STAT_REQ; - if (dev->status & STAT_DCB) - dev->state = STATE_RDONE; - else - dev->state = STATE_IDLE; - dev->status &= ~STAT_CD; - xta_set_callback(dev, HDC_TIME); - } - } - break; + /* Store the data into the buffer. */ + dev->buf_ptr[dev->buf_idx] = val; + if (++dev->buf_idx == dev->buf_len) { + /* We got all the data we need. */ + dev->status &= ~STAT_REQ; + if (dev->status & STAT_DCB) + dev->state = STATE_RDONE; + else + dev->state = STATE_IDLE; + dev->status &= ~STAT_CD; + xta_set_callback(dev, HDC_TIME); + } + } + break; - case 1: /* RESET register */ - dev->sense = 0x00; - dev->state = STATE_IDLE; - break; + case 1: /* RESET register */ + dev->sense = 0x00; + dev->state = STATE_IDLE; + break; - case 2: /* "controller-select" */ - /* Reset the DCB buffer. */ - dev->buf_idx = 0; - dev->buf_len = sizeof(dcb_t); - dev->buf_ptr = (uint8_t *)&dev->dcb; - dev->state = STATE_RDATA; - dev->status = (STAT_BSY | STAT_CD | STAT_REQ); - break; + case 2: /* "controller-select" */ + /* Reset the DCB buffer. */ + dev->buf_idx = 0; + dev->buf_len = sizeof(dcb_t); + dev->buf_ptr = (uint8_t *) &dev->dcb; + dev->state = STATE_RDATA; + dev->status = (STAT_BSY | STAT_CD | STAT_REQ); + break; - case 3: /* DMA/IRQ intr register */ -//xta_log("%s: WriteMASK(%02X)\n", dev->name, val); - dev->intr = val; - break; + case 3: /* DMA/IRQ intr register */ + // xta_log("%s: WriteMASK(%02X)\n", dev->name, val); + dev->intr = val; + break; } } - static int xta_available(void) { - return(rom_present(WD_BIOS_FILE)); + return (rom_present(WD_BIOS_FILE)); } - static void * xta_init(const device_t *info) { drive_t *drive; - char *fn = NULL; - hdc_t *dev; - int c, i; - int max = XTA_NUM; + char *fn = NULL; + hdc_t *dev; + int c, i; + int max = XTA_NUM; /* Allocate and initialize device block. */ dev = malloc(sizeof(hdc_t)); @@ -1003,96 +985,96 @@ xta_init(const device_t *info) dev->type = info->local; /* Do per-controller-type setup. */ - switch(dev->type) { - case 0: /* WDXT-150, with BIOS */ - dev->name = "WDXT-150"; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->rom_addr = device_get_config_hex20("bios_addr"); - dev->dma = 3; - fn = WD_BIOS_FILE; - max = 1; - break; + switch (dev->type) { + case 0: /* WDXT-150, with BIOS */ + dev->name = "WDXT-150"; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + dev->rom_addr = device_get_config_hex20("bios_addr"); + dev->dma = 3; + fn = WD_BIOS_FILE; + max = 1; + break; - case 1: /* EuroPC */ - dev->name = "HD20"; - dev->base = 0x0320; - dev->irq = 5; - dev->dma = 3; - break; + case 1: /* EuroPC */ + dev->name = "HD20"; + dev->base = 0x0320; + dev->irq = 5; + dev->dma = 3; + break; } xta_log("%s: initializing (I/O=%04X, IRQ=%d, DMA=%d", - dev->name, dev->base, dev->irq, dev->dma); + dev->name, dev->base, dev->irq, dev->dma); if (dev->rom_addr != 0x000000) - xta_log(", BIOS=%06X", dev->rom_addr); + xta_log(", BIOS=%06X", dev->rom_addr); xta_log(")\n"); /* Load any disks for this device class. */ c = 0; for (i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { - drive = &dev->drives[hdd[i].xta_channel]; + if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { + drive = &dev->drives[hdd[i].xta_channel]; - if (! hdd_image_load(i)) { - drive->present = 0; - continue; - } - drive->id = c; - drive->hdd_num = i; - drive->present = 1; + if (!hdd_image_load(i)) { + drive->present = 0; + continue; + } + drive->id = c; + drive->hdd_num = i; + drive->present = 1; - /* These are the "hardware" parameters (from the image.) */ - drive->cfg_spt = (uint8_t)(hdd[i].spt & 0xff); - drive->cfg_hpc = (uint8_t)(hdd[i].hpc & 0xff); - drive->cfg_tracks = (uint16_t)hdd[i].tracks; + /* These are the "hardware" parameters (from the image.) */ + drive->cfg_spt = (uint8_t) (hdd[i].spt & 0xff); + drive->cfg_hpc = (uint8_t) (hdd[i].hpc & 0xff); + drive->cfg_tracks = (uint16_t) hdd[i].tracks; - /* Use them as "configured" parameters until overwritten. */ - drive->spt = drive->cfg_spt; - drive->hpc = drive->cfg_hpc; - drive->tracks = drive->cfg_tracks; + /* Use them as "configured" parameters until overwritten. */ + drive->spt = drive->cfg_spt; + drive->hpc = drive->cfg_hpc; + drive->tracks = drive->cfg_tracks; - xta_log("%s: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n", - dev->name, hdd[i].xta_channel, drive->tracks, - drive->hpc, drive->spt, i); + xta_log("%s: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n", + dev->name, hdd[i].xta_channel, drive->tracks, + drive->hpc, drive->spt, i); - if (++c > max) break; - } + if (++c > max) + break; + } } /* Enable the I/O block. */ 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. */ if (dev->rom_addr != 0x000000) { - rom_init(&dev->bios_rom, fn, - dev->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } + rom_init(&dev->bios_rom, fn, + dev->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + } /* Create a timer for command delays. */ timer_add(&dev->timer, hdc_callback, dev, 0); - return(dev); + return (dev); } - static void xta_close(void *priv) { - hdc_t *dev = (hdc_t *)priv; + hdc_t *dev = (hdc_t *) priv; drive_t *drive; - int d; + int d; /* Remove the I/O handler. */ 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. */ for (d = 0; d < XTA_NUM; d++) { - drive = &dev->drives[d]; + drive = &dev->drives[d]; - hdd_image_close(drive->hdd_num); + hdd_image_close(drive->hdd_num); } /* Release the device. */ @@ -1100,7 +1082,7 @@ xta_close(void *priv) } static const device_config_t wdxt150_config[] = { -// clang-format off + // clang-format off { .name = "base", .description = "Address", diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 34805db2b..f623d82f5 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -44,90 +44,85 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> - -#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin" -#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin" -#define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN" -#define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin" -#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" - +#define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin" +#define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin" +#define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN" +#define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin" +#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" typedef struct { - void *ide_board; - uint8_t data_high; - rom_t bios_rom; + void *ide_board; + uint8_t data_high; + rom_t bios_rom; } xtide_t; - static void xtide_write(uint16_t port, uint8_t val, void *priv) { - xtide_t *xtide = (xtide_t *)priv; + xtide_t *xtide = (xtide_t *) priv; switch (port & 0xf) { - case 0x0: - ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board); - return; + case 0x0: + ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board); + return; - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - ide_writeb((port & 0xf), val, xtide->ide_board); - return; + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + ide_writeb((port & 0xf), val, xtide->ide_board); + return; - case 0x8: - xtide->data_high = val; - return; + case 0x8: + xtide->data_high = val; + return; - case 0xe: - ide_write_devctl(0x0, val, xtide->ide_board); - return; + case 0xe: + ide_write_devctl(0x0, val, xtide->ide_board); + return; } } - static uint8_t xtide_read(uint16_t port, void *priv) { - xtide_t *xtide = (xtide_t *)priv; + xtide_t *xtide = (xtide_t *) priv; uint16_t tempw = 0xffff; switch (port & 0xf) { - case 0x0: - tempw = ide_readw(0x0, xtide->ide_board); - xtide->data_high = tempw >> 8; - break; + case 0x0: + tempw = ide_readw(0x0, xtide->ide_board); + xtide->data_high = tempw >> 8; + break; - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - tempw = ide_readb((port & 0xf), xtide->ide_board); - break; + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + tempw = ide_readb((port & 0xf), xtide->ide_board); + break; - case 0x8: - tempw = xtide->data_high; - break; + case 0x8: + tempw = xtide->data_high; + break; - case 0xe: - tempw = ide_read_alt_status(0x0, xtide->ide_board); - break; + case 0xe: + tempw = ide_read_alt_status(0x0, xtide->ide_board); + break; - default: - break; + default: + break; } - return(tempw & 0xff); + return (tempw & 0xff); } - static void * xtide_init(const device_t *info) { @@ -136,25 +131,23 @@ xtide_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); rom_init(&xtide->bios_rom, ROM_PATH_XT, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); xtide->ide_board = ide_xtide_init(); io_sethandler(0x0300, 16, - xtide_read, NULL, NULL, - xtide_write, NULL, NULL, xtide); + xtide_read, NULL, NULL, + xtide_write, NULL, NULL, xtide); - return(xtide); + return (xtide); } - static int xtide_available(void) { - return(rom_present(ROM_PATH_XT)); + return (rom_present(ROM_PATH_XT)); } - static void * xtide_at_init(const device_t *info) { @@ -163,33 +156,30 @@ xtide_at_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); if (info->local == 1) { - rom_init(&xtide->bios_rom, ROM_PATH_AT_386, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, ROM_PATH_AT_386, + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); } else { - rom_init(&xtide->bios_rom, ROM_PATH_AT, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, ROM_PATH_AT, + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); } device_add(&ide_isa_2ch_device); - return(xtide); + return (xtide); } - static int xtide_at_available(void) { - return(rom_present(ROM_PATH_AT)); + return (rom_present(ROM_PATH_AT)); } - static int xtide_at_386_available(void) { - return(rom_present(ROM_PATH_AT_386)); + return (rom_present(ROM_PATH_AT_386)); } - static void * xtide_acculogic_init(const device_t *info) { @@ -198,36 +188,33 @@ xtide_acculogic_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); rom_init(&xtide->bios_rom, ROM_PATH_PS2, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); xtide->ide_board = ide_xtide_init(); io_sethandler(0x0360, 16, - xtide_read, NULL, NULL, - xtide_write, NULL, NULL, xtide); + xtide_read, NULL, NULL, + xtide_write, NULL, NULL, xtide); - return(xtide); + return (xtide); } - static int xtide_acculogic_available(void) { - return(rom_present(ROM_PATH_PS2)); + return (rom_present(ROM_PATH_PS2)); } - static void xtide_close(void *priv) { - xtide_t *xtide = (xtide_t *)priv; + xtide_t *xtide = (xtide_t *) priv; free(xtide); ide_xtide_close(); } - static void * xtide_at_ps2_init(const device_t *info) { @@ -236,95 +223,93 @@ xtide_at_ps2_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); rom_init(&xtide->bios_rom, ROM_PATH_PS2AT, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); device_add(&ide_isa_2ch_device); - return(xtide); + return (xtide); } - static int xtide_at_ps2_available(void) { - return(rom_present(ROM_PATH_PS2AT)); + return (rom_present(ROM_PATH_PS2AT)); } - static void xtide_at_close(void *priv) { - xtide_t *xtide = (xtide_t *)priv; + xtide_t *xtide = (xtide_t *) priv; free(xtide); } const device_t xtide_device = { - .name = "PC/XT XTIDE", + .name = "PC/XT XTIDE", .internal_name = "xtide", - .flags = DEVICE_ISA, - .local = 0, - .init = xtide_init, - .close = xtide_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = xtide_init, + .close = xtide_close, + .reset = NULL, { .available = xtide_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t xtide_at_device = { - .name = "PC/AT XTIDE", + .name = "PC/AT XTIDE", .internal_name = "xtide_at", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = xtide_at_init, - .close = xtide_at_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = xtide_at_init, + .close = xtide_at_close, + .reset = NULL, { .available = xtide_at_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t xtide_at_386_device = { - .name = "PC/AT XTIDE (386)", + .name = "PC/AT XTIDE (386)", .internal_name = "xtide_at_386", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, - .init = xtide_at_init, - .close = xtide_at_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = xtide_at_init, + .close = xtide_at_close, + .reset = NULL, { .available = xtide_at_386_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t xtide_acculogic_device = { - .name = "Acculogic XT IDE", + .name = "Acculogic XT IDE", .internal_name = "xtide_acculogic", - .flags = DEVICE_ISA, - .local = 0, - .init = xtide_acculogic_init, - .close = xtide_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = xtide_acculogic_init, + .close = xtide_close, + .reset = NULL, { .available = xtide_acculogic_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t xtide_at_ps2_device = { - .name = "PS/2 AT XTIDE (1.1.5)", + .name = "PS/2 AT XTIDE (1.1.5)", .internal_name = "xtide_at_ps2", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = xtide_at_ps2_init, - .close = xtide_at_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = xtide_at_ps2_init, + .close = xtide_at_close, + .reset = NULL, { .available = xtide_at_ps2_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdd.c b/src/disk/hdd.c index d2f77a1ab..2ba59eb93 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -31,12 +31,9 @@ #include <86box/video.h> #include "cpu.h" - #define HDD_OVERHEAD_TIME 50.0 - -hard_disk_t hdd[HDD_NUM]; - +hard_disk_t hdd[HDD_NUM]; int hdd_init(void) @@ -44,122 +41,119 @@ hdd_init(void) /* Clear all global data. */ memset(hdd, 0x00, sizeof(hdd)); - return(0); + return (0); } - int hdd_string_to_bus(char *str, int cdrom) { - if (! strcmp(str, "none")) - return(HDD_BUS_DISABLED); + if (!strcmp(str, "none")) + return (HDD_BUS_DISABLED); - if (! strcmp(str, "mfm") || ! strcmp(str, "rll")) { - if (cdrom) { + if (!strcmp(str, "mfm") || !strcmp(str, "rll")) { + if (cdrom) { no_cdrom: - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099); - return(0); - } + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099); + return (0); + } - return(HDD_BUS_MFM); + return (HDD_BUS_MFM); } /* FIXME: delete 'rll' in a year or so.. --FvK */ if (!strcmp(str, "esdi") || !strcmp(str, "rll")) { - if (cdrom) goto no_cdrom; + if (cdrom) + goto no_cdrom; - return(HDD_BUS_ESDI); + return (HDD_BUS_ESDI); } - if (! strcmp(str, "ide_pio_only")) - return(HDD_BUS_IDE); + if (!strcmp(str, "ide_pio_only")) + return (HDD_BUS_IDE); - if (! strcmp(str, "ide")) - return(HDD_BUS_IDE); + if (!strcmp(str, "ide")) + return (HDD_BUS_IDE); - if (! strcmp(str, "atapi_pio_only")) - return(HDD_BUS_ATAPI); + if (!strcmp(str, "atapi_pio_only")) + return (HDD_BUS_ATAPI); - if (! strcmp(str, "atapi")) - return(HDD_BUS_ATAPI); + if (!strcmp(str, "atapi")) + return (HDD_BUS_ATAPI); - if (! strcmp(str, "eide")) - return(HDD_BUS_IDE); + if (!strcmp(str, "eide")) + return (HDD_BUS_IDE); - if (! strcmp(str, "xta")) - return(HDD_BUS_XTA); + if (!strcmp(str, "xta")) + return (HDD_BUS_XTA); - if (! strcmp(str, "atide")) - return(HDD_BUS_IDE); + if (!strcmp(str, "atide")) + return (HDD_BUS_IDE); - if (! strcmp(str, "ide_pio_and_dma")) - return(HDD_BUS_IDE); + if (!strcmp(str, "ide_pio_and_dma")) + return (HDD_BUS_IDE); - if (! strcmp(str, "atapi_pio_and_dma")) - return(HDD_BUS_ATAPI); + if (!strcmp(str, "atapi_pio_and_dma")) + return (HDD_BUS_ATAPI); - if (! strcmp(str, "scsi")) - return(HDD_BUS_SCSI); + if (!strcmp(str, "scsi")) + return (HDD_BUS_SCSI); - return(0); + return (0); } - char * hdd_bus_to_string(int bus, int cdrom) { char *s = "none"; switch (bus) { - case HDD_BUS_DISABLED: - default: - break; + case HDD_BUS_DISABLED: + default: + break; - case HDD_BUS_MFM: - s = "mfm"; - break; + case HDD_BUS_MFM: + s = "mfm"; + break; - case HDD_BUS_XTA: - s = "xta"; - break; + case HDD_BUS_XTA: + s = "xta"; + break; - case HDD_BUS_ESDI: - s = "esdi"; - break; + case HDD_BUS_ESDI: + s = "esdi"; + break; - case HDD_BUS_IDE: - s = "ide"; - break; + case HDD_BUS_IDE: + s = "ide"; + break; - case HDD_BUS_ATAPI: - s = "atapi"; - break; + case HDD_BUS_ATAPI: + s = "atapi"; + break; - case HDD_BUS_SCSI: - s = "scsi"; - break; + case HDD_BUS_SCSI: + s = "scsi"; + break; } - return(s); + return (s); } - int hdd_is_valid(int c) { if (hdd[c].bus == HDD_BUS_DISABLED) - return(0); + return (0); if (strlen(hdd[c].fn) == 0) - return(0); + return (0); - if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0)) - return(0); + if ((hdd[c].tracks == 0) || (hdd[c].hpc == 0) || (hdd[c].spt == 0)) + return (0); - return(1); + return (1); } - double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time) { @@ -168,121 +162,118 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_ hdd_zone_t *zone = NULL; for (int i = 0; i < hdd->num_zones; i++) { - zone = &hdd->zones[i]; - if (zone->end_sector >= dst_addr) - break; + zone = &hdd->zones[i]; + if (zone->end_sector >= dst_addr) + break; } - double continuous_times[2][2] = { { hdd->head_switch_usec, hdd->cyl_switch_usec }, - { zone->sector_time_usec, zone->sector_time_usec } }; + double continuous_times[2][2] = { + {hdd->head_switch_usec, hdd->cyl_switch_usec }, + { zone->sector_time_usec, zone->sector_time_usec} + }; double times[2] = { HDD_OVERHEAD_TIME, hdd->avg_rotation_lat_usec }; - uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track); - uint32_t new_cylinder = new_track / hdd->phy_heads; - uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder); + uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track); + uint32_t new_cylinder = new_track / hdd->phy_heads; + uint32_t cylinder_diff = abs((int) hdd->cur_cylinder - (int) new_cylinder); bool sequential = dst_addr == hdd->cur_addr + 1; - continuous = continuous && sequential; + continuous = continuous && sequential; double seek_time = 0.0; if (continuous) - seek_time = continuous_times[new_track == hdd->cur_track][!!cylinder_diff]; + seek_time = continuous_times[new_track == hdd->cur_track][!!cylinder_diff]; else { - if (!cylinder_diff) - seek_time = times[operation != HDD_OP_SEEK]; - else { - seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl) + - ((operation != HDD_OP_SEEK) * hdd->avg_rotation_lat_usec); - } + if (!cylinder_diff) + seek_time = times[operation != HDD_OP_SEEK]; + else { + seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double) cylinder_diff / (double) hdd->phy_cyl) + ((operation != HDD_OP_SEEK) * hdd->avg_rotation_lat_usec); + } } if (!max_seek_time || seek_time <= max_seek_time) { - hdd->cur_addr = dst_addr; - hdd->cur_track = new_track; - hdd->cur_cylinder = new_cylinder; + hdd->cur_addr = dst_addr; + hdd->cur_track = new_track; + hdd->cur_cylinder = new_cylinder; } return seek_time; } - static void hdd_readahead_update(hard_disk_t *hdd) { uint64_t elapsed_cycles; - double elapsed_us, seek_time; + double elapsed_us, seek_time; uint32_t max_read_ahead, i; uint32_t space_needed; hdd_cache_t *cache = &hdd->cache; if (cache->ra_ongoing) { - hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment]; + hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment]; - elapsed_cycles = tsc - cache->ra_start_time; - elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0; - /* Do not overwrite data not yet read by host */ - max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr; + elapsed_cycles = tsc - cache->ra_start_time; + elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0; + /* Do not overwrite data not yet read by host */ + max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr; - seek_time = 0.0; + seek_time = 0.0; - for (i = 0; i < max_read_ahead; i++) { - seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time); - if (seek_time > elapsed_us) - break; + for (i = 0; i < max_read_ahead; i++) { + seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time); + if (seek_time > elapsed_us) + break; - segment->ra_addr++; - } + segment->ra_addr++; + } - if (segment->ra_addr > segment->lba_addr + cache->segment_size) { - space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size); - segment->lba_addr += space_needed; - } + if (segment->ra_addr > segment->lba_addr + cache->segment_size) { + space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size); + segment->lba_addr += space_needed; + } } } - static double hdd_writecache_flush(hard_disk_t *hdd) { double seek_time = 0.0; while (hdd->cache.write_pending) { - seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); - hdd->cache.write_addr++; - hdd->cache.write_pending--; + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); + hdd->cache.write_addr++; + hdd->cache.write_pending--; } return seek_time; } - static void hdd_writecache_update(hard_disk_t *hdd) { uint64_t elapsed_cycles; - double elapsed_us, seek_time; + double elapsed_us, seek_time; if (hdd->cache.write_pending) { - elapsed_cycles = tsc - hdd->cache.write_start_time; - elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0; - seek_time = 0.0; + elapsed_cycles = tsc - hdd->cache.write_start_time; + elapsed_us = (double) elapsed_cycles / cpuclock * 1000000.0; + seek_time = 0.0; - while (hdd->cache.write_pending) { - seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time); - if (seek_time > elapsed_us) - break; + while (hdd->cache.write_pending) { + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time); + if (seek_time > elapsed_us) + break; - hdd->cache.write_addr++; - hdd->cache.write_pending--; - } + hdd->cache.write_addr++; + hdd->cache.write_pending--; + } } } - double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len) { - double seek_time = 0.0; + double seek_time = 0.0; uint32_t flush_needed; if (!hdd->speed_preset) @@ -294,31 +285,30 @@ hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len) hdd->cache.ra_ongoing = 0; if (hdd->cache.write_pending && (addr != (hdd->cache.write_addr + hdd->cache.write_pending))) { - /* New request is not sequential to existing cache, need to flush it */ - seek_time += hdd_writecache_flush(hdd); + /* New request is not sequential to existing cache, need to flush it */ + seek_time += hdd_writecache_flush(hdd); } if (!hdd->cache.write_pending) { - /* Cache is empty */ - hdd->cache.write_addr = addr; + /* Cache is empty */ + hdd->cache.write_addr = addr; } hdd->cache.write_pending += len; if (hdd->cache.write_pending > hdd->cache.write_size) { - /* If request is bigger than free cache, flush some data first */ - flush_needed = hdd->cache.write_pending - hdd->cache.write_size; - for (uint32_t i = 0; i < flush_needed; i++) { - seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); - hdd->cache.write_addr++; - } + /* If request is bigger than free cache, flush some data first */ + flush_needed = hdd->cache.write_pending - hdd->cache.write_size; + for (uint32_t i = 0; i < flush_needed; i++) { + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); + hdd->cache.write_addr++; + } } - hdd->cache.write_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0); + hdd->cache.write_start_time = tsc + (uint32_t) (seek_time * cpuclock / 1000000.0); return seek_time; } - double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len) { @@ -332,159 +322,145 @@ hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len) seek_time += hdd_writecache_flush(hdd); - hdd_cache_t *cache = &hdd->cache; + hdd_cache_t *cache = &hdd->cache; hdd_cache_seg_t *active_seg = &cache->segments[0]; for (uint32_t i = 0; i < cache->num_segments; i++) { - hdd_cache_seg_t *segment = &cache->segments[i]; - if (!segment->valid) { - active_seg = segment; - continue; - } + hdd_cache_seg_t *segment = &cache->segments[i]; + if (!segment->valid) { + active_seg = segment; + continue; + } - if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) { - /* Cache HIT */ - segment->host_addr = addr; - active_seg = segment; - if (addr + len > segment->ra_addr) { - uint32_t need_read = (addr + len) - segment->ra_addr; - for (uint32_t j = 0; j < need_read; j++) { - seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0); - segment->ra_addr++; - } - } - if (addr + len > segment->lba_addr + cache->segment_size) { - /* Need to erase some previously cached data */ - uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size); - segment->lba_addr += space_needed; - } - goto update_lru; - } else { - if (segment->lru > active_seg->lru) - active_seg = segment; - } + if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) { + /* Cache HIT */ + segment->host_addr = addr; + active_seg = segment; + if (addr + len > segment->ra_addr) { + uint32_t need_read = (addr + len) - segment->ra_addr; + for (uint32_t j = 0; j < need_read; j++) { + seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0); + segment->ra_addr++; + } + } + if (addr + len > segment->lba_addr + cache->segment_size) { + /* Need to erase some previously cached data */ + uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size); + segment->lba_addr += space_needed; + } + goto update_lru; + } else { + if (segment->lru > active_seg->lru) + active_seg = segment; + } } /* Cache MISS */ - active_seg->lba_addr = addr; - active_seg->valid = 1; + active_seg->lba_addr = addr; + active_seg->valid = 1; active_seg->host_addr = addr; - active_seg->ra_addr = addr; + active_seg->ra_addr = addr; for (uint32_t i = 0; i < len; i++) { - seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0); - active_seg->ra_addr++; + seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0); + active_seg->ra_addr++; } update_lru: for (uint32_t i = 0; i < cache->num_segments; i++) - cache->segments[i].lru++; + cache->segments[i].lru++; active_seg->lru = 0; - cache->ra_ongoing = 1; - cache->ra_segment = active_seg->id; - cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0); + cache->ra_ongoing = 1; + cache->ra_segment = active_seg->id; + cache->ra_start_time = tsc + (uint32_t) (seek_time * cpuclock / 1000000.0); return seek_time; } - static void hdd_cache_init(hard_disk_t *hdd) { hdd_cache_t *cache = &hdd->cache; - uint32_t i; + uint32_t i; - cache->ra_segment = 0; - cache->ra_ongoing = 0; + cache->ra_segment = 0; + cache->ra_ongoing = 0; cache->ra_start_time = 0; for (i = 0; i < cache->num_segments; i++) { - cache->segments[i].valid = 0; - cache->segments[i].lru = 0; - cache->segments[i].id = i; - cache->segments[i].ra_addr = 0; - cache->segments[i].host_addr = 0; + cache->segments[i].valid = 0; + cache->segments[i].lru = 0; + cache->segments[i].id = i; + cache->segments[i].ra_addr = 0; + cache->segments[i].host_addr = 0; } } - static void hdd_zones_init(hard_disk_t *hdd) { - uint32_t lba = 0, track = 0; - uint32_t i, tracks; - double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0; + uint32_t lba = 0, track = 0; + uint32_t i, tracks; + double revolution_usec = 60.0 / (double) hdd->rpm * 1000000.0; hdd_zone_t *zone; for (i = 0; i < hdd->num_zones; i++) { - zone = &hdd->zones[i]; - zone->start_sector = lba; - zone->start_track = track; - zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track; - tracks = zone->cylinders * hdd->phy_heads; - lba += tracks * zone->sectors_per_track; - zone->end_sector = lba - 1; - track += tracks - 1; + zone = &hdd->zones[i]; + zone->start_sector = lba; + zone->start_track = track; + zone->sector_time_usec = revolution_usec / (double) zone->sectors_per_track; + tracks = zone->cylinders * hdd->phy_heads; + lba += tracks * zone->sectors_per_track; + zone->end_sector = lba - 1; + track += tracks - 1; } } - static hdd_preset_t hdd_speed_presets[] = { - { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + {.name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32}, - { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, - .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, - .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, - .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, - { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, - .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, - .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, - { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, - .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, - .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, }; - int hdd_preset_get_num() { return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t); } - char * hdd_preset_getname(int preset) { - return (char *)hdd_speed_presets[preset].name; + return (char *) hdd_speed_presets[preset].name; } - char * hdd_preset_get_internal_name(int preset) { - return (char *)hdd_speed_presets[preset].internal_name; + return (char *) hdd_speed_presets[preset].internal_name; } - int hdd_preset_get_from_internal_name(char *s) { int c = 0; for (int i = 0; i < (sizeof(hdd_speed_presets) / sizeof(hdd_preset_t)); i++) { - if (!strcmp((char *)hdd_speed_presets[c].internal_name, s)) + if (!strcmp((char *) hdd_speed_presets[c].internal_name, s)) return c; c++; } @@ -492,18 +468,17 @@ hdd_preset_get_from_internal_name(char *s) return 0; } - void hdd_preset_apply(int hdd_id) { hard_disk_t *hd = &hdd[hdd_id]; - double revolution_usec, zone_percent; - uint32_t disk_sectors, sectors_per_surface, cylinders, cylinders_per_zone; - uint32_t total_sectors = 0, i; - uint32_t spt, zone_sectors; + double revolution_usec, zone_percent; + uint32_t disk_sectors, sectors_per_surface, cylinders, cylinders_per_zone; + uint32_t total_sectors = 0, i; + uint32_t spt, zone_sectors; if (hd->speed_preset >= hdd_preset_get_num()) - hd->speed_preset = 0; + hd->speed_preset = 0; hdd_preset_t *preset = &hdd_speed_presets[hd->speed_preset]; @@ -512,42 +487,42 @@ hdd_preset_apply(int hdd_id) hd->max_multiple_block = preset->max_multiple; if (!hd->speed_preset) - return; + return; hd->phy_heads = preset->heads; - hd->rpm = preset->rpm; + hd->rpm = preset->rpm; - revolution_usec = 60.0 / (double)hd->rpm * 1000000.0; + revolution_usec = 60.0 / (double) hd->rpm * 1000000.0; hd->avg_rotation_lat_usec = revolution_usec / 2; - hd->full_stroke_usec = preset->full_stroke_ms * 1000; - hd->head_switch_usec = preset->track_seek_ms * 1000; - hd->cyl_switch_usec = preset->track_seek_ms * 1000; + hd->full_stroke_usec = preset->full_stroke_ms * 1000; + hd->head_switch_usec = preset->track_seek_ms * 1000; + hd->cyl_switch_usec = preset->track_seek_ms * 1000; hd->cache.write_size = 64; hd->num_zones = preset->zones; - disk_sectors = hd->tracks * hd->hpc * hd->spt; - sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hd->phy_heads); - cylinders = (uint32_t)ceil((double)sectors_per_surface / (double)preset->avg_spt); - hd->phy_cyl = cylinders; - cylinders_per_zone = cylinders / preset->zones; + disk_sectors = hd->tracks * hd->hpc * hd->spt; + sectors_per_surface = (uint32_t) ceil((double) disk_sectors / (double) hd->phy_heads); + cylinders = (uint32_t) ceil((double) sectors_per_surface / (double) preset->avg_spt); + hd->phy_cyl = cylinders; + cylinders_per_zone = cylinders / preset->zones; for (i = 0; i < preset->zones; i++) { - zone_percent = i * 100 / (double)preset->zones; + zone_percent = i * 100 / (double) preset->zones; - if (i < preset->zones - 1) { - /* Function for realistic zone sector density */ - double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48; - spt = (uint32_t)ceil((double)preset->avg_spt * spt_percent / 100); - } else - spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads)); + if (i < preset->zones - 1) { + /* Function for realistic zone sector density */ + double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48; + spt = (uint32_t) ceil((double) preset->avg_spt * spt_percent / 100); + } else + spt = (uint32_t) ceil((double) (disk_sectors - total_sectors) / (double) (cylinders_per_zone * preset->heads)); - zone_sectors = spt * cylinders_per_zone * preset->heads; - total_sectors += zone_sectors; + zone_sectors = spt * cylinders_per_zone * preset->heads; + total_sectors += zone_sectors; - hd->zones[i].cylinders = cylinders_per_zone; - hd->zones[i].sectors_per_track = spt; + hd->zones[i].cylinders = cylinders_per_zone; + hd->zones[i].sectors_per_track = spt; } hdd_zones_init(hd); diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index a775ce7c9..7100acdd6 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -41,647 +41,613 @@ typedef struct { - FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */ - MVHDMeta* vhd; /* Used for HDD_IMAGE_VHD. */ - uint32_t base; - uint32_t pos, last_sector; - uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */ - uint8_t loaded; + FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */ + MVHDMeta *vhd; /* Used for HDD_IMAGE_VHD. */ + uint32_t base; + uint32_t pos, last_sector; + uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */ + uint8_t loaded; } hdd_image_t; - hdd_image_t hdd_images[HDD_NUM]; -static char empty_sector[512]; +static char empty_sector[512]; static char *empty_sector_1mb; #ifdef ENABLE_HDD_IMAGE_LOG int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG; - static void hdd_image_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (hdd_image_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (hdd_image_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define hdd_image_log(fmt, ...) +# define hdd_image_log(fmt, ...) #endif int image_is_hdi(const char *s) { - if (! strcasecmp(path_get_extension((char *) s), "HDI")) - return 1; - else - return 0; + if (!strcasecmp(path_get_extension((char *) s), "HDI")) + return 1; + else + return 0; } - int image_is_hdx(const char *s, int check_signature) { - FILE *f; - uint64_t filelen; - uint64_t signature; + FILE *f; + uint64_t filelen; + uint64_t signature; - if (! strcasecmp(path_get_extension((char *) s), "HDX")) { - if (check_signature) { - f = plat_fopen(s, "rb"); - if (!f) - return 0; - if (fseeko64(f, 0, SEEK_END)) - fatal("image_is_hdx(): Error while seeking"); - filelen = ftello64(f); - if (fseeko64(f, 0, SEEK_SET)) - fatal("image_is_hdx(): Error while seeking"); - if (filelen < 44) { - if (f != NULL) - fclose(f); - return 0; - } - if (fread(&signature, 1, 8, f) != 8) - fatal("image_is_hdx(): Error reading signature\n"); - fclose(f); - if (signature == 0xD778A82044445459ll) - return 1; - else - return 0; - } else - return 1; - } else - return 0; + if (!strcasecmp(path_get_extension((char *) s), "HDX")) { + if (check_signature) { + f = plat_fopen(s, "rb"); + if (!f) + return 0; + if (fseeko64(f, 0, SEEK_END)) + fatal("image_is_hdx(): Error while seeking"); + filelen = ftello64(f); + if (fseeko64(f, 0, SEEK_SET)) + fatal("image_is_hdx(): Error while seeking"); + if (filelen < 44) { + if (f != NULL) + fclose(f); + return 0; + } + if (fread(&signature, 1, 8, f) != 8) + fatal("image_is_hdx(): Error reading signature\n"); + fclose(f); + if (signature == 0xD778A82044445459ll) + return 1; + else + return 0; + } else + return 1; + } else + return 0; } - int image_is_vhd(const char *s, int check_signature) { - FILE* f; + FILE *f; - if (! strcasecmp(path_get_extension((char *) s), "VHD")) { - if (check_signature) { - f = plat_fopen(s, "rb"); - if (!f) - return 0; + if (!strcasecmp(path_get_extension((char *) s), "VHD")) { + if (check_signature) { + f = plat_fopen(s, "rb"); + if (!f) + return 0; - bool is_vhd = mvhd_file_is_vhd(f); - fclose(f); - return is_vhd ? 1 : 0; - } else - return 1; - } else - return 0; + bool is_vhd = mvhd_file_is_vhd(f); + fclose(f); + return is_vhd ? 1 : 0; + } else + return 1; + } else + return 0; } void hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size) { - /* Calculate the geometry from size (in MB), using the algorithm provided in - "Virtual Hard Disk Image Format Specification, Appendix: CHS Calculation" */ - uint64_t ts = ((uint64_t) size) << 11LL; - uint32_t spt, heads, cyl, cth; - if (ts > 65535 * 16 * 255) - ts = 65535 * 16 * 255; + /* Calculate the geometry from size (in MB), using the algorithm provided in + "Virtual Hard Disk Image Format Specification, Appendix: CHS Calculation" */ + uint64_t ts = ((uint64_t) size) << 11LL; + uint32_t spt, heads, cyl, cth; + if (ts > 65535 * 16 * 255) + ts = 65535 * 16 * 255; - if (ts >= 65535 * 16 * 63) { - spt = 255; - heads = 16; - cth = (uint32_t) (ts / spt); - } else { - spt = 17; - cth = (uint32_t) (ts / spt); - heads = (cth +1023) / 1024; - if (heads < 4) - heads = 4; - if ((cth >= (heads * 1024)) || (heads > 16)) { - spt = 31; - heads = 16; - cth = (uint32_t) (ts / spt); - } - if (cth >= (heads * 1024)) { - spt = 63; - heads = 16; - cth = (uint32_t) (ts / spt); - } - } - cyl = cth / heads; - *c = cyl; - *h = heads; - *s = spt; + if (ts >= 65535 * 16 * 63) { + spt = 255; + heads = 16; + cth = (uint32_t) (ts / spt); + } else { + spt = 17; + cth = (uint32_t) (ts / spt); + heads = (cth + 1023) / 1024; + if (heads < 4) + heads = 4; + if ((cth >= (heads * 1024)) || (heads > 16)) { + spt = 31; + heads = 16; + cth = (uint32_t) (ts / spt); + } + if (cth >= (heads * 1024)) { + spt = 63; + heads = 16; + cth = (uint32_t) (ts / spt); + } + } + cyl = cth / heads; + *c = cyl; + *h = heads; + *s = spt; } - static int prepare_new_hard_disk(uint8_t id, uint64_t full_size) { - uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); + uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); - uint32_t size; - uint32_t t, i; + uint32_t size; + uint32_t t, i; - t = (uint32_t) (target_size >> 20); /* Amount of 1 MB blocks. */ - size = (uint32_t) (target_size & 0xfffff); /* 1 MB mask. */ + t = (uint32_t) (target_size >> 20); /* Amount of 1 MB blocks. */ + size = (uint32_t) (target_size & 0xfffff); /* 1 MB mask. */ - empty_sector_1mb = (char *) malloc(1048576); - memset(empty_sector_1mb, 0, 1048576); + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); - /* Temporarily switch off suppression of seen messages so that the - progress gets displayed. */ - pclog_toggle_suppr(); - pclog("Writing image sectors: ["); + /* Temporarily switch off suppression of seen messages so that the + progress gets displayed. */ + pclog_toggle_suppr(); + pclog("Writing image sectors: ["); - /* First, write all the 1 MB blocks. */ - if (t > 0) { - for (i = 0; i < t; i++) { - fseek(hdd_images[id].file, 0, SEEK_END); - fwrite(empty_sector_1mb, 1, 1048576, hdd_images[id].file); - pclog("#"); - } - } + /* First, write all the 1 MB blocks. */ + if (t > 0) { + for (i = 0; i < t; i++) { + fseek(hdd_images[id].file, 0, SEEK_END); + fwrite(empty_sector_1mb, 1, 1048576, hdd_images[id].file); + pclog("#"); + } + } - /* Then, write the remainder. */ - if (size > 0) { - fseek(hdd_images[id].file, 0, SEEK_END); - fwrite(empty_sector_1mb, 1, size, hdd_images[id].file); - pclog("#"); - } - pclog("]\n"); - /* Switch the suppression of seen messages back on. */ - pclog_toggle_suppr(); + /* Then, write the remainder. */ + if (size > 0) { + fseek(hdd_images[id].file, 0, SEEK_END); + fwrite(empty_sector_1mb, 1, size, hdd_images[id].file); + pclog("#"); + } + pclog("]\n"); + /* Switch the suppression of seen messages back on. */ + pclog_toggle_suppr(); - free(empty_sector_1mb); + free(empty_sector_1mb); - hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; + hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; - hdd_images[id].loaded = 1; + hdd_images[id].loaded = 1; - return 1; + return 1; } - void hdd_image_init(void) { - int i; + int i; - for (i = 0; i < HDD_NUM; i++) - memset(&hdd_images[i], 0, sizeof(hdd_image_t)); + for (i = 0; i < HDD_NUM; i++) + memset(&hdd_images[i], 0, sizeof(hdd_image_t)); } int hdd_image_load(int id) { - uint32_t sector_size = 512; - uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459ll; - uint64_t full_size = 0; - uint64_t spt = 0, hpc = 0, tracks = 0; - int c, ret; - uint64_t s = 0; - char *fn = hdd[id].fn; - int is_hdx[2] = { 0, 0 }; - int is_vhd[2] = { 0, 0 }; - int vhd_error = 0; + uint32_t sector_size = 512; + uint32_t zero = 0; + uint64_t signature = 0xD778A82044445459ll; + uint64_t full_size = 0; + uint64_t spt = 0, hpc = 0, tracks = 0; + int c, ret; + uint64_t s = 0; + char *fn = hdd[id].fn; + int is_hdx[2] = { 0, 0 }; + int is_vhd[2] = { 0, 0 }; + int vhd_error = 0; - memset(empty_sector, 0, sizeof(empty_sector)); - if (fn) { - path_normalize(fn); - } + memset(empty_sector, 0, sizeof(empty_sector)); + if (fn) { + path_normalize(fn); + } + hdd_images[id].base = 0; - hdd_images[id].base = 0; + if (hdd_images[id].loaded) { + if (hdd_images[id].file) { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } else if (hdd_images[id].vhd) { + mvhd_close(hdd_images[id].vhd); + hdd_images[id].vhd = NULL; + } + hdd_images[id].loaded = 0; + } - if (hdd_images[id].loaded) { - if (hdd_images[id].file) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } - else if (hdd_images[id].vhd) { - mvhd_close(hdd_images[id].vhd); - hdd_images[id].vhd = NULL; - } - hdd_images[id].loaded = 0; - } + is_hdx[0] = image_is_hdx(fn, 0); + is_hdx[1] = image_is_hdx(fn, 1); - is_hdx[0] = image_is_hdx(fn, 0); - is_hdx[1] = image_is_hdx(fn, 1); + is_vhd[0] = image_is_vhd(fn, 0); + is_vhd[1] = image_is_vhd(fn, 1); - is_vhd[0] = image_is_vhd(fn, 0); - is_vhd[1] = image_is_vhd(fn, 1); + hdd_images[id].pos = 0; - hdd_images[id].pos = 0; + /* Try to open existing hard disk image */ + if (fn[0] == '.') { + hdd_image_log("File name starts with .\n"); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } + hdd_images[id].file = plat_fopen(fn, "rb+"); + if (hdd_images[id].file == NULL) { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) { + /* Failed because it does not exist, + so try to create new file */ + if (hdd[id].wp) { + hdd_image_log("A write-protected image must exist\n"); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } - /* Try to open existing hard disk image */ - if (fn[0] == '.') { - hdd_image_log("File name starts with .\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - hdd_images[id].file = plat_fopen(fn, "rb+"); - if (hdd_images[id].file == NULL) { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) { - /* Failed because it does not exist, - so try to create new file */ - if (hdd[id].wp) { - hdd_image_log("A write-protected image must exist\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } + hdd_images[id].file = plat_fopen(fn, "wb+"); + if (hdd_images[id].file == NULL) { + hdd_image_log("Unable to open image\n"); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } else { + if (image_is_hdi(fn)) { + full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; + hdd_images[id].base = 0x1000; + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file); + fwrite(&full_size, 1, 4, hdd_images[id].file); + fwrite(§or_size, 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); + for (c = 0; c < 0x3f8; c++) + fwrite(&zero, 1, 4, hdd_images[id].file); + hdd_images[id].type = HDD_IMAGE_HDI; + } else if (is_hdx[0]) { + full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; + hdd_images[id].base = 0x28; + fwrite(&signature, 1, 8, hdd_images[id].file); + fwrite(&full_size, 1, 8, hdd_images[id].file); + fwrite(§or_size, 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + hdd_images[id].type = HDD_IMAGE_HDX; + } else if (is_vhd[0]) { + fclose(hdd_images[id].file); + MVHDGeom geometry; + geometry.cyl = hdd[id].tracks; + geometry.heads = hdd[id].hpc; + geometry.spt = hdd[id].spt; + full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; + hdd_images[id].last_sector = (full_size >> 9LL) - 1; - hdd_images[id].file = plat_fopen(fn, "wb+"); - if (hdd_images[id].file == NULL) { - hdd_image_log("Unable to open image\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } else { - if (image_is_hdi(fn)) { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].base = 0x1000; - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file); - fwrite(&full_size, 1, 4, hdd_images[id].file); - fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); - for (c = 0; c < 0x3f8; c++) - fwrite(&zero, 1, 4, hdd_images[id].file); - hdd_images[id].type = HDD_IMAGE_HDI; - } else if (is_hdx[0]) { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].base = 0x28; - fwrite(&signature, 1, 8, hdd_images[id].file); - fwrite(&full_size, 1, 8, hdd_images[id].file); - fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - fwrite(&zero, 1, 4, hdd_images[id].file); - hdd_images[id].type = HDD_IMAGE_HDX; - } else if (is_vhd[0]) { - fclose(hdd_images[id].file); - MVHDGeom geometry; - geometry.cyl = hdd[id].tracks; - geometry.heads = hdd[id].hpc; - geometry.spt = hdd[id].spt; - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].last_sector = (full_size >> 9LL) - 1; + hdd_images[id].vhd = mvhd_create_fixed(fn, geometry, &vhd_error, NULL); + if (hdd_images[id].vhd == NULL) + fatal("hdd_image_load(): VHD: Could not create VHD : %s\n", mvhd_strerr(vhd_error)); - hdd_images[id].vhd = mvhd_create_fixed(fn, geometry, &vhd_error, NULL); - if (hdd_images[id].vhd == NULL) - fatal("hdd_image_load(): VHD: Could not create VHD : %s\n", mvhd_strerr(vhd_error)); + hdd_images[id].type = HDD_IMAGE_VHD; + return 1; + } else { + hdd_images[id].type = HDD_IMAGE_RAW; + } + hdd_images[id].last_sector = 0; + } - hdd_images[id].type = HDD_IMAGE_VHD; - return 1; - } else { - hdd_images[id].type = HDD_IMAGE_RAW; - } - hdd_images[id].last_sector = 0; - } + s = full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; - s = full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; + ret = prepare_new_hard_disk(id, full_size); + return ret; + } else { + /* Failed for another reason */ + hdd_image_log("Failed for another reason\n"); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } + } else { + if (image_is_hdi(fn)) { + if (fseeko64(hdd_images[id].file, 0x8, SEEK_SET) == -1) + fatal("hdd_image_load(): HDI: Error seeking to offset 0x8\n"); + if (fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading base offset\n"); + if (fseeko64(hdd_images[id].file, 0xC, SEEK_SET) == -1) + fatal("hdd_image_load(): HDI: Error seeking to offest 0xC\n"); + full_size = 0LL; + if (fread(&full_size, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading full size\n"); + if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1) + fatal("hdd_image_load(): HDI: Error seeking to offset 0x10\n"); + if (fread(§or_size, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading sector size\n"); + if (sector_size != 512) { + /* Sector size is not 512 */ + hdd_image_log("HDI: Sector size is not 512\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } + if (fread(&spt, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); + if (fread(&hpc, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n"); + if (fread(&tracks, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading number of tracks\n"); + hdd[id].spt = spt; + hdd[id].hpc = hpc; + hdd[id].tracks = tracks; + hdd_images[id].type = HDD_IMAGE_HDI; + } else if (is_hdx[1]) { + hdd_images[id].base = 0x28; + if (fseeko64(hdd_images[id].file, 8, SEEK_SET) == -1) + fatal("hdd_image_load(): HDX: Error seeking to offset 0x8\n"); + if (fread(&full_size, 1, 8, hdd_images[id].file) != 8) + fatal("hdd_image_load(): HDX: Error reading full size\n"); + if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1) + fatal("hdd_image_load(): HDX: Error seeking to offset 0x10\n"); + if (fread(§or_size, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDX: Error reading sector size\n"); + if (sector_size != 512) { + /* Sector size is not 512 */ + hdd_image_log("HDX: Sector size is not 512\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } + if (fread(&spt, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); + if (fread(&hpc, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n"); + if (fread(&tracks, 1, 4, hdd_images[id].file) != 4) + fatal("hdd_image_load(): HDX: Error reading number of tracks\n"); + hdd[id].spt = spt; + hdd[id].hpc = hpc; + hdd[id].tracks = tracks; + hdd_images[id].type = HDD_IMAGE_HDX; + } else if (is_vhd[1]) { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + hdd_images[id].vhd = mvhd_open(fn, (bool) 0, &vhd_error); + if (hdd_images[id].vhd == NULL) { + if (vhd_error == MVHD_ERR_FILE) + fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, strerror(mvhd_errno)); + else + fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, mvhd_strerr(vhd_error)); + } else if (vhd_error == MVHD_ERR_TIMESTAMP) { + fatal("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn); + } - ret = prepare_new_hard_disk(id, full_size); - return ret; - } else { - /* Failed for another reason */ - hdd_image_log("Failed for another reason\n"); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - } else { - if (image_is_hdi(fn)) { - if (fseeko64(hdd_images[id].file, 0x8, SEEK_SET) == -1) - fatal("hdd_image_load(): HDI: Error seeking to offset 0x8\n"); - if (fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading base offset\n"); - if (fseeko64(hdd_images[id].file, 0xC, SEEK_SET) == -1) - fatal("hdd_image_load(): HDI: Error seeking to offest 0xC\n"); - full_size = 0LL; - if (fread(&full_size, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading full size\n"); - if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1) - fatal("hdd_image_load(): HDI: Error seeking to offset 0x10\n"); - if (fread(§or_size, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading sector size\n"); - if (sector_size != 512) { - /* Sector size is not 512 */ - hdd_image_log("HDI: Sector size is not 512\n"); - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - if (fread(&spt, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); - if (fread(&hpc, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n"); - if (fread(&tracks, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading number of tracks\n"); - hdd[id].spt = spt; - hdd[id].hpc = hpc; - hdd[id].tracks = tracks; - hdd_images[id].type = HDD_IMAGE_HDI; - } else if (is_hdx[1]) { - hdd_images[id].base = 0x28; - if (fseeko64(hdd_images[id].file, 8, SEEK_SET) == -1) - fatal("hdd_image_load(): HDX: Error seeking to offset 0x8\n"); - if (fread(&full_size, 1, 8, hdd_images[id].file) != 8) - fatal("hdd_image_load(): HDX: Error reading full size\n"); - if (fseeko64(hdd_images[id].file, 0x10, SEEK_SET) == -1) - fatal("hdd_image_load(): HDX: Error seeking to offset 0x10\n"); - if (fread(§or_size, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDX: Error reading sector size\n"); - if (sector_size != 512) { - /* Sector size is not 512 */ - hdd_image_log("HDX: Sector size is not 512\n"); - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; - } - if (fread(&spt, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); - if (fread(&hpc, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDI: Error reading heads per cylinder\n"); - if (fread(&tracks, 1, 4, hdd_images[id].file) != 4) - fatal("hdd_image_load(): HDX: Error reading number of tracks\n"); - hdd[id].spt = spt; - hdd[id].hpc = hpc; - hdd[id].tracks = tracks; - hdd_images[id].type = HDD_IMAGE_HDX; - } else if (is_vhd[1]) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - hdd_images[id].vhd = mvhd_open(fn, (bool)0, &vhd_error); - if (hdd_images[id].vhd == NULL) { - if (vhd_error == MVHD_ERR_FILE) - fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, strerror(mvhd_errno)); - else - fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, mvhd_strerr(vhd_error)); - } - else if (vhd_error == MVHD_ERR_TIMESTAMP) { - 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].hpc = hdd_images[id].vhd->footer.geom.heads; + hdd[id].spt = hdd_images[id].vhd->footer.geom.spt; + full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; + hdd_images[id].type = HDD_IMAGE_VHD; + /* If we're here, this means there is a valid VHD footer in the + image, which means that by definition, all valid sectors + are there. */ + hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; + hdd_images[id].loaded = 1; + return 1; + } else { + full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; + hdd_images[id].type = HDD_IMAGE_RAW; + } + } - hdd[id].tracks = hdd_images[id].vhd->footer.geom.cyl; - hdd[id].hpc = hdd_images[id].vhd->footer.geom.heads; - hdd[id].spt = hdd_images[id].vhd->footer.geom.spt; - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].type = HDD_IMAGE_VHD; - /* If we're here, this means there is a valid VHD footer in the - image, which means that by definition, all valid sectors - are there. */ - hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; - hdd_images[id].loaded = 1; - return 1; - } else { - full_size = ((uint64_t) hdd[id].spt) * - ((uint64_t) hdd[id].hpc) * - ((uint64_t) hdd[id].tracks) << 9LL; - hdd_images[id].type = HDD_IMAGE_RAW; - } - } + if (fseeko64(hdd_images[id].file, 0, SEEK_END) == -1) + fatal("hdd_image_load(): Error seeking to the end of file\n"); + s = ftello64(hdd_images[id].file); + if (s < (full_size + hdd_images[id].base)) + ret = prepare_new_hard_disk(id, full_size); + else { + hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; + hdd_images[id].loaded = 1; + ret = 1; + } - if (fseeko64(hdd_images[id].file, 0, SEEK_END) == -1) - fatal("hdd_image_load(): Error seeking to the end of file\n"); - s = ftello64(hdd_images[id].file); - if (s < (full_size + hdd_images[id].base)) - ret = prepare_new_hard_disk(id, full_size); - else { - hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; - hdd_images[id].loaded = 1; - ret = 1; - } - - return ret; + return ret; } - void hdd_image_seek(uint8_t id, uint32_t sector) { - off64_t addr = sector; - addr = (uint64_t)sector << 9LL; + off64_t addr = sector; + addr = (uint64_t) sector << 9LL; - hdd_images[id].pos = sector; - if (hdd_images[id].type != HDD_IMAGE_VHD) { - if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1) - fatal("hdd_image_seek(): Error seeking\n"); - } + hdd_images[id].pos = sector; + if (hdd_images[id].type != HDD_IMAGE_VHD) { + if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1) + fatal("hdd_image_seek(): Error seeking\n"); + } } - void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { - int non_transferred_sectors; - size_t num_read; + int non_transferred_sectors; + size_t num_read; - if (hdd_images[id].type == HDD_IMAGE_VHD) { - non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer); - hdd_images[id].pos = sector + count - non_transferred_sectors - 1; - } else { - 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); - return; - } + if (hdd_images[id].type == HDD_IMAGE_VHD) { + non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer); + hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + } else { + 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); + return; + } - num_read = fread(buffer, 512, count, hdd_images[id].file); - hdd_images[id].pos = sector + num_read; - } + num_read = fread(buffer, 512, count, hdd_images[id].file); + hdd_images[id].pos = sector + num_read; + } } - uint32_t hdd_image_get_last_sector(uint8_t id) { - return hdd_images[id].last_sector; + return hdd_images[id].last_sector; } - uint32_t hdd_sectors(uint8_t id) { - return hdd_image_get_last_sector(id) - 1; + return hdd_image_get_last_sector(id) - 1; } - int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); + uint32_t transfer_sectors = count; + uint32_t sectors = hdd_sectors(id); - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; + if ((sectors - sector) < transfer_sectors) + transfer_sectors = sectors - sector; - hdd_image_read(id, sector, transfer_sectors, buffer); + hdd_image_read(id, sector, transfer_sectors, buffer); - if (count != transfer_sectors) - return 1; - return 0; + if (count != transfer_sectors) + return 1; + return 0; } - void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { - int non_transferred_sectors; - size_t num_write; + int non_transferred_sectors; + size_t num_write; - if (hdd_images[id].type == HDD_IMAGE_VHD) { - non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer); - hdd_images[id].pos = sector + count - non_transferred_sectors - 1; - } else { - 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); - return; - } + if (hdd_images[id].type == HDD_IMAGE_VHD) { + non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer); + hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + } else { + 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); + return; + } - num_write = fwrite(buffer, 512, count, hdd_images[id].file); - hdd_images[id].pos = sector + num_write; - } + num_write = fwrite(buffer, 512, count, hdd_images[id].file); + hdd_images[id].pos = sector + num_write; + } } - int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); + uint32_t transfer_sectors = count; + uint32_t sectors = hdd_sectors(id); - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; + if ((sectors - sector) < transfer_sectors) + transfer_sectors = sectors - sector; - hdd_image_write(id, sector, transfer_sectors, buffer); + hdd_image_write(id, sector, transfer_sectors, buffer); - if (count != transfer_sectors) - return 1; - return 0; + if (count != transfer_sectors) + return 1; + return 0; } - void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count) { - if (hdd_images[id].type == HDD_IMAGE_VHD) { - int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count); - hdd_images[id].pos = sector + count - non_transferred_sectors - 1; - } else { - uint32_t i = 0; + if (hdd_images[id].type == HDD_IMAGE_VHD) { + int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count); + hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + } else { + uint32_t i = 0; - 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) { - fatal("Hard disk image %i: Zero error during seek\n", id); - return; - } + 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); + return; + } - for (i = 0; i < count; i++) { - if (feof(hdd_images[id].file)) - break; + for (i = 0; i < count; i++) { + if (feof(hdd_images[id].file)) + break; - hdd_images[id].pos = sector + i; - fwrite(empty_sector, 512, 1, hdd_images[id].file); - } - } + hdd_images[id].pos = sector + i; + fwrite(empty_sector, 512, 1, hdd_images[id].file); + } + } } - int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count) { - uint32_t transfer_sectors = count; - uint32_t sectors = hdd_sectors(id); + uint32_t transfer_sectors = count; + uint32_t sectors = hdd_sectors(id); - if ((sectors - sector) < transfer_sectors) - transfer_sectors = sectors - sector; + if ((sectors - sector) < transfer_sectors) + transfer_sectors = sectors - sector; - hdd_image_zero(id, sector, transfer_sectors); + hdd_image_zero(id, sector, transfer_sectors); - if (count != transfer_sectors) - return 1; - return 0; + if (count != transfer_sectors) + return 1; + return 0; } - uint32_t hdd_image_get_pos(uint8_t id) { - return hdd_images[id].pos; + return hdd_images[id].pos; } - uint8_t hdd_image_get_type(uint8_t id) { - return hdd_images[id].type; + return hdd_images[id].type; } - void hdd_image_unload(uint8_t id, int fn_preserve) { - if (strlen(hdd[id].fn) == 0) - return; + if (strlen(hdd[id].fn) == 0) + return; - if (hdd_images[id].loaded) { - if (hdd_images[id].file != NULL) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } else if (hdd_images[id].vhd != NULL) { - mvhd_close(hdd_images[id].vhd); - hdd_images[id].vhd = NULL; - } - hdd_images[id].loaded = 0; - } + if (hdd_images[id].loaded) { + if (hdd_images[id].file != NULL) { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } else if (hdd_images[id].vhd != NULL) { + mvhd_close(hdd_images[id].vhd); + hdd_images[id].vhd = NULL; + } + hdd_images[id].loaded = 0; + } - hdd_images[id].last_sector = -1; + hdd_images[id].last_sector = -1; - memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn)); - if (fn_preserve) - strcpy(hdd[id].prev_fn, hdd[id].fn); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn)); + if (fn_preserve) + strcpy(hdd[id].prev_fn, hdd[id].fn); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); } - void hdd_image_close(uint8_t id) { - hdd_image_log("hdd_image_close(%i)\n", id); + hdd_image_log("hdd_image_close(%i)\n", id); - if (!hdd_images[id].loaded) - return; + if (!hdd_images[id].loaded) + return; - if (hdd_images[id].file != NULL) { - fclose(hdd_images[id].file); - hdd_images[id].file = NULL; - } else if (hdd_images[id].vhd != NULL) { - mvhd_close(hdd_images[id].vhd); - hdd_images[id].vhd = NULL; - } + if (hdd_images[id].file != NULL) { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } else if (hdd_images[id].vhd != NULL) { + mvhd_close(hdd_images[id].vhd); + hdd_images[id].vhd = NULL; + } - memset(&hdd_images[id], 0, sizeof(hdd_image_t)); - hdd_images[id].loaded = 0; + memset(&hdd_images[id], 0, sizeof(hdd_image_t)); + hdd_images[id].loaded = 0; } diff --git a/src/disk/hdd_table.c b/src/disk/hdd_table.c index a851782f3..ae03e91a8 100644 --- a/src/disk/hdd_table.c +++ b/src/disk/hdd_table.c @@ -25,8 +25,8 @@ #include <86box/86box.h> #include <86box/hdd.h> - unsigned int hdd_table[128][3] = { + // clang-format off { 306, 4, 17 }, /* 0 - 7 */ { 615, 2, 17 }, { 306, 4, 26 }, @@ -170,4 +170,5 @@ unsigned int hdd_table[128][3] = { { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } +// clang-format on }; diff --git a/src/disk/mo.c b/src/disk/mo.c index 18e49b2d7..fdcb30099 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -43,74 +43,72 @@ #include <86box/version.h> #ifdef _WIN32 -#include -#include +# include +# include #else -#include +# include #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. */ -const uint8_t mo_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ +const uint8_t mo_command_flags[0x100] = { + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + IMPLEMENTED | CHECK_READY, /* 0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ + IMPLEMENTED, /* 0x15 */ + IMPLEMENTED | SCSI_ONLY, /* 0x16 */ + IMPLEMENTED | SCSI_ONLY, /* 0x17 */ 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ + IMPLEMENTED, /* 0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2C */ + IMPLEMENTED | CHECK_READY, /* 0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2C */ 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + IMPLEMENTED | CHECK_READY, /* 0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ 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, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ + IMPLEMENTED, /* 0x55 */ 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ + IMPLEMENTED, /* 0x5A */ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ + IMPLEMENTED | CHECK_READY, /* 0xAA */ 0, - IMPLEMENTED | CHECK_READY | NONDATA, /* 0xAC */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0xAC */ 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + IMPLEMENTED | CHECK_READY, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 const mode_sense_pages_t mo_mode_sense_pages_default = + // clang-format off { { { 0, 0 }, { 0, 0 }, @@ -174,8 +172,10 @@ static const mode_sense_pages_t mo_mode_sense_pages_default = { 0, 0 }, { 0, 0 } } }; +// clang-format on static const mode_sense_pages_t mo_mode_sense_pages_default_scsi = + // clang-format off { { { 0, 0 }, { 0, 0 }, @@ -226,9 +226,10 @@ static const mode_sense_pages_t mo_mode_sense_pages_default_scsi = { 0, 0 }, { 0, 0 } } }; - +// clang-format on static const mode_sense_pages_t mo_mode_sense_pages_changeable = + // clang-format off { { { 0, 0 }, { 0, 0 }, @@ -279,326 +280,307 @@ static const mode_sense_pages_t mo_mode_sense_pages_changeable = { 0, 0 }, { 0, 0 } } }; +// clang-format on - -static void mo_command_complete(mo_t *dev); -static void mo_init(mo_t *dev); - +static void mo_command_complete(mo_t *dev); +static void mo_init(mo_t *dev); #ifdef ENABLE_MO_LOG int mo_do_log = ENABLE_MO_LOG; - static void mo_log(const char *fmt, ...) { va_list ap; if (mo_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define mo_log(fmt, ...) +# define mo_log(fmt, ...) #endif - int find_mo_for_channel(uint8_t channel) { uint8_t i = 0; for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel == channel)) - return i; + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel == channel)) + return i; } return 0xff; } - static int mo_load_abort(mo_t *dev) { if (dev->drv->f) - fclose(dev->drv->f); - dev->drv->f = NULL; + fclose(dev->drv->f); + dev->drv->f = NULL; dev->drv->medium_size = 0; dev->drv->sector_size = 0; - mo_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ + mo_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; } - int image_is_mdi(const char *s) { - if (! strcasecmp(path_get_extension((char *) s), "MDI")) - return 1; + if (!strcasecmp(path_get_extension((char *) s), "MDI")) + return 1; else - return 0; + return 0; } - int mo_load(mo_t *dev, char *fn) { - int is_mdi; - uint32_t size = 0; + int is_mdi; + uint32_t size = 0; unsigned int i, found = 0; is_mdi = image_is_mdi(fn); dev->drv->f = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); if (!dev->drv->f) { - if (!dev->drv->read_only) { - dev->drv->f = plat_fopen(fn, "rb"); - if (dev->drv->f) - dev->drv->read_only = 1; - else - return mo_load_abort(dev); - } else - return mo_load_abort(dev); + if (!dev->drv->read_only) { + dev->drv->f = plat_fopen(fn, "rb"); + if (dev->drv->f) + dev->drv->read_only = 1; + else + return mo_load_abort(dev); + } else + return mo_load_abort(dev); } fseek(dev->drv->f, 0, SEEK_END); size = (uint32_t) ftell(dev->drv->f); if (is_mdi) { - /* This is a MDI image. */ - size -= 0x1000LL; - dev->drv->base = 0x1000; + /* This is a MDI image. */ + size -= 0x1000LL; + dev->drv->base = 0x1000; } for (i = 0; i < KNOWN_MO_TYPES; i++) { - if (size == (mo_types[i].sectors * mo_types[i].bytes_per_sector)) { - found = 1; - dev->drv->medium_size = mo_types[i].sectors; - dev->drv->sector_size = mo_types[i].bytes_per_sector; - break; - } + if (size == (mo_types[i].sectors * mo_types[i].bytes_per_sector)) { + found = 1; + dev->drv->medium_size = mo_types[i].sectors; + dev->drv->sector_size = mo_types[i].bytes_per_sector; + break; + } } if (!found) - return mo_load_abort(dev); + return mo_load_abort(dev); if (fseek(dev->drv->f, dev->drv->base, SEEK_SET) == -1) - fatal("mo_load(): Error seeking to the beginning of the file\n"); + fatal("mo_load(): Error seeking to the beginning of the file\n"); strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); return 1; } - void mo_disk_reload(mo_t *dev) { int ret = 0; if (strlen(dev->drv->prev_image_path) == 0) - return; + return; else - ret = mo_load(dev, dev->drv->prev_image_path); + ret = mo_load(dev, dev->drv->prev_image_path); if (ret) - dev->unit_attention = 1; + dev->unit_attention = 1; } - void mo_disk_unload(mo_t *dev) { if (dev->drv->f) { - fclose(dev->drv->f); - dev->drv->f = NULL; + fclose(dev->drv->f); + dev->drv->f = NULL; } } - void mo_disk_close(mo_t *dev) { if (dev->drv->f) { - mo_disk_unload(dev); + mo_disk_unload(dev); - memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); - memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); + memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); + memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); - dev->drv->medium_size = 0; + dev->drv->medium_size = 0; } } - static void mo_set_callback(mo_t *dev) { if (dev->drv->bus_type != MO_BUS_SCSI) - ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } - static void mo_init(mo_t *dev) { if (dev->id >= MO_NUM) - return; + return; dev->requested_blocks = 1; - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->drv->bus_mode = 0; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + dev->drv->bus_mode = 0; if (dev->drv->bus_type >= MO_BUS_ATAPI) - dev->drv->bus_mode |= 2; + dev->drv->bus_mode |= 2; if (dev->drv->bus_type < MO_BUS_SCSI) - dev->drv->bus_mode |= 1; + dev->drv->bus_mode |= 1; mo_log("MO %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); if (dev->drv->bus_type < MO_BUS_SCSI) { - dev->phase = 1; - dev->request_length = 0xEB14; + dev->phase = 1; + dev->request_length = 0xEB14; } - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; dev->packet_status = PHASE_NONE; mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0; } - static int mo_supports_pio(mo_t *dev) { return (dev->drv->bus_mode & 1); } - static int mo_supports_dma(mo_t *dev) { return (dev->drv->bus_mode & 2); } - /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int mo_current_mode(mo_t *dev) { if (!mo_supports_pio(dev) && !mo_supports_dma(dev)) - return 0; + return 0; if (mo_supports_pio(dev) && !mo_supports_dma(dev)) { - mo_log("MO %i: Drive does not support DMA, setting to PIO\n", dev->id); - return 1; + mo_log("MO %i: Drive does not support DMA, setting to PIO\n", dev->id); + return 1; } if (!mo_supports_pio(dev) && mo_supports_dma(dev)) - return 2; + return 2; if (mo_supports_pio(dev) && mo_supports_dma(dev)) { - mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); - return (dev->features & 1) ? 2 : 1; + mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); + return (dev->features & 1) ? 2 : 1; } return 0; } - /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int mo_atapi_phase_to_scsi(mo_t *dev) { if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } + switch (dev->phase & 3) { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 7; + } } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + if ((dev->phase & 3) == 3) + return 3; + else + return 4; } return 0; } - static void mo_mode_sense_load(mo_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (mo_drives[dev->id].bus_type == MO_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); else - memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default, sizeof(mode_sense_pages_t)); memset(file_name, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) - sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "rb"); if (f) { - /* Nothing to read, not used by MO. */ - fclose(f); + /* Nothing to read, not used by MO. */ + fclose(f); } } - static void mo_mode_sense_save(mo_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(file_name, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) - sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "wb"); if (f) { - /* Nothing to write, not used by MO. */ - fclose(f); + /* Nothing to write, not used by MO. */ + fclose(f); } } - /*SCSI Mode Sense 6/10*/ static uint8_t mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - return mo_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->bus_type == MO_BUS_SCSI) - return mo_mode_sense_pages_default_scsi.pages[page][pos]; - else - return mo_mode_sense_pages_default.pages[page][pos]; - break; + case 0: + case 3: + return dev->ms_pages_saved.pages[page][pos]; + break; + case 1: + return mo_mode_sense_pages_changeable.pages[page][pos]; + break; + case 2: + if (dev->drv->bus_type == MO_BUS_SCSI) + return mo_mode_sense_pages_default_scsi.pages[page][pos]; + else + return mo_mode_sense_pages_default.pages[page][pos]; + break; } return 0; } - static uint32_t mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) { uint64_t pf; - uint8_t page_control = (page >> 6) & 3; + uint8_t page_control = (page >> 6) & 3; pf = mo_mode_sense_page_flags; @@ -610,33 +592,32 @@ mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block page &= 0x3f; if (block_descriptor_len) { - buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); - buf[pos++] = ( dev->drv->medium_size & 0xff); - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; - buf[pos++] = ((dev->drv->sector_size >> 8) & 0xff); - buf[pos++] = ( dev->drv->sector_size & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); + buf[pos++] = (dev->drv->medium_size & 0xff); + buf[pos++] = 0; /* Reserved. */ + buf[pos++] = 0; + buf[pos++] = ((dev->drv->sector_size >> 8) & 0xff); + buf[pos++] = (dev->drv->sector_size & 0xff); } for (i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { - if (pf & (1LL << ((uint64_t) page))) { - buf[pos++] = mo_mode_sense_read(dev, page_control, i, 0); - msplen = mo_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - mo_log("MO %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = mo_mode_sense_read(dev, page_control, i, 2 + j); - } - } + if (pf & (1LL << ((uint64_t) page))) { + buf[pos++] = mo_mode_sense_read(dev, page_control, i, 0); + msplen = mo_mode_sense_read(dev, page_control, i, 1); + buf[pos++] = msplen; + mo_log("MO %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + for (j = 0; j < msplen; j++) + buf[pos++] = mo_mode_sense_read(dev, page_control, i, 2 + j); + } + } } return pos; } - static void mo_update_request_length(mo_t *dev, int len, int block_len) { @@ -646,99 +627,96 @@ mo_update_request_length(mo_t *dev, int len, int block_len) /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { - case 0x08: - case 0x0a: - case 0x28: - case 0x2a: - case 0xa8: - case 0xaa: - /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; + case 0x08: + case 0x0a: + case 0x28: + case 0x2a: + case 0xa8: + case 0xaa: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; + /* Make sure total length is not bigger than sum of the lengths of + all the requested blocks. */ + bt = (dev->requested_blocks * block_len); + if (len > bt) + len = bt; - min_len = block_len; + min_len = block_len; - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - /*FALLTHROUGH*/ - default: - dev->packet_len = len; - break; + if (len <= block_len) { + /* Total length is less or equal to block length. */ + if (dev->max_transfer_len < block_len) { + /* Transfer a minimum of (block size) bytes. */ + dev->max_transfer_len = block_len; + dev->packet_len = block_len; + break; + } + } + /*FALLTHROUGH*/ + default: + dev->packet_len = len; + break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; + dev->max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; + dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->request_length = dev->max_transfer_len; return; } - static double mo_bus_speed(mo_t *dev) { double ret = -1.0; if (dev && dev->drv && (dev->drv->bus_type == MO_BUS_SCSI)) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return 0.0; + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; } else { - if (dev && dev->drv) - ret = ide_atapi_get_period(dev->drv->ide_channel); - if (ret == -1.0) { - if (dev) - dev->callback = -1.0; - return 0.0; - } else - return ret * 1000000.0; + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + if (dev) + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; } } - static void mo_command_common(mo_t *dev) { double bytes_per_second, period; dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; + dev->phase = 1; + dev->pos = 0; if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0.0; + dev->callback = 0.0; else { - if (dev->drv->bus_type == MO_BUS_SCSI) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return; - } else - bytes_per_second = mo_bus_speed(dev); + if (dev->drv->bus_type == MO_BUS_SCSI) { + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return; + } else + bytes_per_second = mo_bus_speed(dev); - period = 1000000.0 / bytes_per_second; - dev->callback = period * (double) (dev->packet_len); + period = 1000000.0 / bytes_per_second; + dev->callback = period * (double) (dev->packet_len); } mo_set_callback(dev); } - static void mo_command_complete(mo_t *dev) { @@ -747,7 +725,6 @@ mo_command_complete(mo_t *dev) mo_command_common(dev); } - static void mo_command_read(mo_t *dev) { @@ -755,7 +732,6 @@ mo_command_read(mo_t *dev) mo_command_common(dev); } - static void mo_command_read_dma(mo_t *dev) { @@ -763,7 +739,6 @@ mo_command_read_dma(mo_t *dev) mo_command_common(dev); } - static void mo_command_write(mo_t *dev) { @@ -771,7 +746,6 @@ mo_command_write(mo_t *dev) mo_command_common(dev); } - static void mo_command_write_dma(mo_t *dev) { @@ -779,7 +753,6 @@ mo_command_write_dma(mo_t *dev) mo_command_common(dev); } - /* id = Current MO device ID; len = Total transfer length; block_len = Length of a single block (why does it matter?!); @@ -789,116 +762,109 @@ static void mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int direction) { mo_log("MO %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); dev->pos = 0; if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; + if (alloc_len < len) + len = alloc_len; } if ((len == 0) || (mo_current_mode(dev) == 0)) { - if (dev->drv->bus_type != MO_BUS_SCSI) - dev->packet_len = 0; + if (dev->drv->bus_type != MO_BUS_SCSI) + dev->packet_len = 0; - mo_command_complete(dev); + mo_command_complete(dev); } else { - if (mo_current_mode(dev) == 2) { - if (dev->drv->bus_type != MO_BUS_SCSI) - dev->packet_len = alloc_len; + if (mo_current_mode(dev) == 2) { + if (dev->drv->bus_type != MO_BUS_SCSI) + dev->packet_len = alloc_len; - if (direction == 0) - mo_command_read_dma(dev); - else - mo_command_write_dma(dev); - } else { - mo_update_request_length(dev, len, block_len); - if (direction == 0) - mo_command_read(dev); - else - mo_command_write(dev); - } + if (direction == 0) + mo_command_read_dma(dev); + else + mo_command_write_dma(dev); + } else { + mo_update_request_length(dev, len, block_len); + if (direction == 0) + mo_command_read(dev); + else + mo_command_write(dev); + } } mo_log("MO %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - 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 mo_sense_clear(mo_t *dev, int command) { mo_sense_key = mo_asc = mo_ascq = 0; } - static void mo_set_phase(mo_t *dev, uint8_t phase) { uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type != MO_BUS_SCSI) - return; + return; scsi_devices[scsi_bus][scsi_id].phase = phase; } - static void mo_cmd_error(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); dev->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * MO_TIME; + dev->callback = 50.0 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); 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 mo_unit_attention(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * MO_TIME; + dev->callback = 50.0 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); mo_log("MO %i: UNIT ATTENTION\n", dev->id); } - static void mo_buf_alloc(mo_t *dev, uint32_t len) { mo_log("MO %i: Allocated buffer length: %i\n", dev->id, len); if (!dev->buffer) - dev->buffer = (uint8_t *) malloc(len); + dev->buffer = (uint8_t *) malloc(len); } - static void mo_buf_free(mo_t *dev) { if (dev->buffer) { - mo_log("MO %i: Freeing buffer...\n", dev->id); - free(dev->buffer); - dev->buffer = NULL; + mo_log("MO %i: Freeing buffer...\n", dev->id); + free(dev->buffer); + dev->buffer = NULL; } } - static void mo_bus_master_error(scsi_common_t *sc) { @@ -909,79 +875,71 @@ mo_bus_master_error(scsi_common_t *sc) mo_cmd_error(dev); } - static void mo_not_ready(mo_t *dev) { mo_sense_key = SENSE_NOT_READY; - mo_asc = ASC_MEDIUM_NOT_PRESENT; - mo_ascq = 0; + mo_asc = ASC_MEDIUM_NOT_PRESENT; + mo_ascq = 0; mo_cmd_error(dev); } - static void mo_write_protected(mo_t *dev) { mo_sense_key = SENSE_UNIT_ATTENTION; - mo_asc = ASC_WRITE_PROTECTED; - mo_ascq = 0; + mo_asc = ASC_WRITE_PROTECTED; + mo_ascq = 0; mo_cmd_error(dev); } - static void mo_invalid_lun(mo_t *dev) { mo_sense_key = SENSE_ILLEGAL_REQUEST; - mo_asc = ASC_INV_LUN; - mo_ascq = 0; + mo_asc = ASC_INV_LUN; + mo_ascq = 0; mo_cmd_error(dev); } - static void mo_illegal_opcode(mo_t *dev) { mo_sense_key = SENSE_ILLEGAL_REQUEST; - mo_asc = ASC_ILLEGAL_OPCODE; - mo_ascq = 0; + mo_asc = ASC_ILLEGAL_OPCODE; + mo_ascq = 0; mo_cmd_error(dev); } - static void mo_lba_out_of_range(mo_t *dev) { mo_sense_key = SENSE_ILLEGAL_REQUEST; - mo_asc = ASC_LBA_OUT_OF_RANGE; - mo_ascq = 0; + mo_asc = ASC_LBA_OUT_OF_RANGE; + mo_ascq = 0; mo_cmd_error(dev); } - static void mo_invalid_field(mo_t *dev) { mo_sense_key = SENSE_ILLEGAL_REQUEST; - mo_asc = ASC_INV_FIELD_IN_CMD_PACKET; - mo_ascq = 0; + mo_asc = ASC_INV_FIELD_IN_CMD_PACKET; + mo_ascq = 0; mo_cmd_error(dev); dev->status = 0x53; } - static void mo_invalid_field_pl(mo_t *dev) { mo_sense_key = SENSE_ILLEGAL_REQUEST; - mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - mo_ascq = 0; + mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + mo_ascq = 0; mo_cmd_error(dev); dev->status = 0x53; } - static int mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out) { @@ -989,34 +947,34 @@ mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out) int i; if (!dev->sector_len) { - mo_command_complete(dev); - return -1; + mo_command_complete(dev); + return -1; } mo_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); if (dev->sector_pos >= dev->drv->medium_size) { - mo_log("MO %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); - mo_lba_out_of_range(dev); - return 0; + mo_log("MO %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); + mo_lba_out_of_range(dev); + return 0; } *len = dev->requested_blocks * dev->drv->sector_size; for (i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) - break; + if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) + break; - if (feof(dev->drv->f)) - break; + if (feof(dev->drv->f)) + break; - if (out) { - if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) - fatal("mo_blocks(): Error writing data\n"); - } else { - if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) - fatal("mo_blocks(): Error reading data\n"); - } + if (out) { + if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) + fatal("mo_blocks(): Error writing data\n"); + } else { + if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) + fatal("mo_blocks(): Error reading data\n"); + } } mo_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); @@ -1027,7 +985,6 @@ mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out) return 1; } - void mo_insert(mo_t *dev) { @@ -1038,8 +995,8 @@ void mo_format(mo_t *dev) { long size; - int ret; - int fd; + int ret; + int fd; mo_log("MO %i: Formatting media...\n", dev->id); @@ -1047,57 +1004,57 @@ mo_format(mo_t *dev) size = ftell(dev->drv->f); #ifdef _WIN32 - HANDLE fh; + HANDLE fh; LARGE_INTEGER liSize; fd = _fileno(dev->drv->f); - fh = (HANDLE)_get_osfhandle(fd); + fh = (HANDLE) _get_osfhandle(fd); liSize.QuadPart = 0; - ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); + ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if(!ret) { - mo_log("MO %i: Failed seek to start of image file\n", dev->id); - return; + if (!ret) { + mo_log("MO %i: Failed seek to start of image file\n", dev->id); + return; } - ret = (int)SetEndOfFile(fh); + ret = (int) SetEndOfFile(fh); - if(!ret) { - mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); - return; + if (!ret) { + mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); + return; } liSize.QuadPart = size; - ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); + ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if(!ret) { - mo_log("MO %i: Failed seek to end of image file\n", dev->id); - return; + if (!ret) { + mo_log("MO %i: Failed seek to end of image file\n", dev->id); + return; } - ret = (int)SetEndOfFile(fh); + ret = (int) SetEndOfFile(fh); - if(!ret) { - mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size); - return; + if (!ret) { + mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size); + return; } #else fd = fileno(dev->drv->f); ret = ftruncate(fd, 0); - if(ret) { - mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); - return; + if (ret) { + mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); + return; } ret = ftruncate(fd, size); - if(ret) { - mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size); - return; + if (ret) { + mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size); + return; } #endif } @@ -1107,17 +1064,17 @@ mo_erase(mo_t *dev) { int i; - if (! dev->sector_len) { - mo_command_complete(dev); - return -1; + if (!dev->sector_len) { + mo_command_complete(dev); + return -1; } mo_log("MO %i: Erasing %i blocks starting from %i...\n", dev->id, dev->sector_len, dev->sector_pos); if (dev->sector_pos >= dev->drv->medium_size) { - mo_log("MO %i: Trying to erase beyond the end of disk\n", dev->id); - mo_lba_out_of_range(dev); - return 0; + mo_log("MO %i: Trying to erase beyond the end of disk\n", dev->id); + mo_lba_out_of_range(dev); + return 0; } mo_buf_alloc(dev, dev->drv->sector_size); @@ -1126,10 +1083,10 @@ mo_erase(mo_t *dev) fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), SEEK_SET); for (i = 0; i < dev->requested_blocks; i++) { - if (feof(dev->drv->f)) - break; + if (feof(dev->drv->f)) + break; - fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->f); + fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->f); } mo_log("MO %i: Erased %i bytes of blocks...\n", dev->id, i * dev->drv->sector_size); @@ -1145,42 +1102,41 @@ void mo_sense_code_ok(mo_t *dev) { mo_sense_key = SENSE_NONE; - mo_asc = 0; - mo_ascq = 0; + mo_asc = 0; + mo_ascq = 0; } - static int mo_pre_execution_check(mo_t *dev, uint8_t *cdb) { int ready = 0; if (dev->drv->bus_type == MO_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); - mo_invalid_lun(dev); - return 0; - } + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { + mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); + mo_invalid_lun(dev); + return 0; + } } if (!(mo_command_flags[cdb[0]] & IMPLEMENTED)) { - mo_log("MO %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == MO_BUS_SCSI) ? "SCSI" : "ATAPI"); + mo_log("MO %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], + (dev->drv->bus_type == MO_BUS_SCSI) ? "SCSI" : "ATAPI"); - mo_illegal_opcode(dev); - return 0; + mo_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type < MO_BUS_SCSI) && (mo_command_flags[cdb[0]] & SCSI_ONLY)) { - mo_log("MO %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - mo_illegal_opcode(dev); - return 0; + mo_log("MO %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); + mo_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type == MO_BUS_SCSI) && (mo_command_flags[cdb[0]] & ATAPI_ONLY)) { - mo_log("MO %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - mo_illegal_opcode(dev); - return 0; + mo_log("MO %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); + mo_illegal_opcode(dev); + return 0; } ready = (dev->drv->f != NULL); @@ -1189,36 +1145,36 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) UNIT ATTENTION condition present, as we only use it to mark disc changes. */ if (!ready && dev->unit_attention) - dev->unit_attention = 0; + dev->unit_attention = 0; /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(mo_command_flags[cdb[0]] & ALLOW_UA)) { - /* mo_log("MO %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention = 2; - mo_log("MO %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); - mo_unit_attention(dev); - return 0; - } + /* Only increment the unit attention phase if the command can not pass through it. */ + if (!(mo_command_flags[cdb[0]] & ALLOW_UA)) { + /* mo_log("MO %i: Unit attention now 2\n", dev->id); */ + dev->unit_attention = 2; + mo_log("MO %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); + mo_unit_attention(dev); + return 0; + } } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* mo_log("MO %i: Unit attention now 0\n", dev->id); */ - dev->unit_attention = 0; - } + if (cdb[0] != GPCMD_REQUEST_SENSE) { + /* mo_log("MO %i: Unit attention now 0\n", dev->id); */ + dev->unit_attention = 0; + } } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - mo_sense_clear(dev, cdb[0]); + mo_sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ if ((mo_command_flags[cdb[0]] & CHECK_READY) && !ready) { - mo_log("MO %i: Not ready (%02X)\n", dev->id, cdb[0]); - mo_not_ready(dev); - return 0; + mo_log("MO %i: Not ready (%02X)\n", dev->id, cdb[0]); + mo_not_ready(dev); + return 0; } mo_log("MO %i: Continuing with command %02X\n", dev->id, cdb[0]); @@ -1226,15 +1182,13 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) return 1; } - static void mo_seek(mo_t *dev, uint32_t pos) { /* mo_log("MO %i: Seek %08X\n", dev->id, pos); */ - dev->sector_pos = pos; + dev->sector_pos = pos; } - static void mo_rezero(mo_t *dev) { @@ -1242,73 +1196,70 @@ mo_rezero(mo_t *dev) mo_seek(dev, 0); } - void mo_reset(scsi_common_t *sc) { mo_t *dev = (mo_t *) sc; mo_rezero(dev); - dev->status = 0; + dev->status = 0; dev->callback = 0.0; mo_set_callback(dev); - dev->phase = 1; + dev->phase = 1; dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; + dev->packet_status = PHASE_NONE; dev->unit_attention = 0; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->cur_lun = SCSI_LUN_USE_CDB; } - static void mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = mo_sense_key; - buffer[2] = mo_asc; - buffer[3] = mo_ascq; - } + memset(buffer, 0, alloc_length); + if (!desc) + memcpy(buffer, dev->sense, alloc_length); + else { + buffer[1] = mo_sense_key; + buffer[2] = mo_asc; + buffer[3] = mo_ascq; + } } buffer[0] = desc ? 0x72 : 0x70; if (dev->unit_attention && (mo_sense_key == 0)) { - buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; - buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[desc ? 3 : 13] = 0; + buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; + buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[desc ? 3 : 13] = 0; } mo_log("MO %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; + /* If the last remaining sense is unit attention, clear + that condition. */ + dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ mo_sense_clear(dev, GPCMD_REQUEST_SENSE); } - static void mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { - mo_t *dev = (mo_t *) sc; - int ready = 0; + mo_t *dev = (mo_t *) sc; + int ready = 0; ready = (dev->drv->f != NULL); if (!ready && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ @@ -1316,48 +1267,46 @@ mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_leng mo_request_sense(dev, buffer, alloc_length, 0); } - static void mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == MO_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - mo_log("MO %i: Actual transfer length: %i\n", dev->id, *BufLen); + if (*BufLen == -1) + *BufLen = *src_len; + else { + *BufLen = MIN(*src_len, *BufLen); + *src_len = *BufLen; + } + mo_log("MO %i: Actual transfer length: %i\n", dev->id, *BufLen); } } - static void mo_command(scsi_common_t *sc, uint8_t *cdb) { - mo_t *dev = (mo_t *) sc; - int pos = 0, block_desc = 0; - int ret; - int32_t len, max_len; - int32_t alloc_length; - int size_idx, idx = 0; + mo_t *dev = (mo_t *) sc; + int pos = 0, block_desc = 0; + int ret; + int32_t len, max_len; + int32_t alloc_length; + int size_idx, idx = 0; unsigned preamble_len; - char device_identify[9] = { '8', '6', 'B', '_', 'M', 'O', '0', '0', 0 }; - int32_t blen = 0; + char device_identify[9] = { '8', '6', 'B', '_', 'M', 'O', '0', '0', 0 }; + int32_t blen = 0; int32_t *BufLen; uint32_t previous_pos = 0; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == MO_BUS_SCSI) { - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->status &= ~ERR_STAT; } else { - BufLen = &blen; - dev->error = 0; + BufLen = &blen; + dev->error = 0; } - dev->packet_len = 0; + dev->packet_len = 0; dev->request_pos = 0; device_identify[7] = dev->id + 0x30; @@ -1365,13 +1314,13 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention); - mo_log("MO %i: Request length: %04X\n", dev->id, dev->request_length); + mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", + dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention); + mo_log("MO %i: Request length: %04X\n", dev->id, dev->request_length); - mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); + mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11]); } dev->sector_len = 0; @@ -1380,516 +1329,516 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (mo_pre_execution_check(dev, cdb) == 0) - return; + return; switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - mo_invalid_field(dev); - return; - } - /*FALLTHROUGH*/ - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - - case GPCMD_FORMAT_UNIT: - if (dev->drv->read_only) { - mo_write_protected(dev); - return; - } - - mo_format(dev); - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - mo_seek(dev, 0); - mo_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - - if (!max_len) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - break; - } - - mo_buf_alloc(dev, 256); - mo_set_buf_len(dev, BufLen, &max_len); - len = (cdb[1] & 1) ? 8 : 18; - mo_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); - mo_data_command_finish(dev, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[8] << 8) | cdb[9]; - - mo_buf_alloc(dev, 8); - mo_set_buf_len(dev, BufLen, &len); - - memset(dev->buffer, 0, 8); - dev->buffer[5] = 1; - - mo_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = dev->drv->sector_size; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - if (dev->sector_len == 0) - dev->sector_len = 256; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - } - - if (!dev->sector_len) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - /* mo_log("MO %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - mo_buf_alloc(dev, dev->packet_len); - - ret = mo_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - mo_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - mo_data_command_finish(dev, alloc_length, dev->drv->sector_size, alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_MO | dev->id, 1); - else - ui_sb_update_icon(SB_MO | dev->id, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - /* Data and blank verification cannot be set at the same time */ - if ((cdb[1] & 2) && (cdb[1] & 4)) { - mo_invalid_field(dev); - return; - } - if (!(cdb[1] & 2) || (cdb[1] & 4)) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - } - /*TODO: Implement*/ - mo_invalid_field(dev); - return; - - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - mo_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = dev->drv->sector_size; - - if (dev->drv->read_only) { - mo_write_protected(dev); - return; - } - - switch (cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((dev->sector_pos >= dev->drv->medium_size)/* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) { - mo_lba_out_of_range(dev); - return; - } - - if (!dev->sector_len) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - /* mo_log("MO %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - mo_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - mo_data_command_finish(dev, dev->packet_len, dev->drv->sector_size, dev->packet_len, 1); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_MO | dev->id, 1); - else - ui_sb_update_icon(SB_MO | dev->id, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->drv->bus_type == MO_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - mo_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - mo_buf_alloc(dev, 65536); - } - - if (!(mo_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - mo_invalid_field(dev); - mo_buf_free(dev); - return; - } - - memset(dev->buffer, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = mo_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = len - 1; - dev->buffer[1] = 0; - if (block_desc) - dev->buffer[3] = 8; - } else { - len = mo_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0]=(len - 2) >> 8; - dev->buffer[1]=(len - 2) & 255; - dev->buffer[2] = 0; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; - } - } - - mo_set_buf_len(dev, BufLen, &len); - - mo_log("MO %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - mo_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - mo_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - mo_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - mo_buf_alloc(dev, 65536); - } - - mo_set_buf_len(dev, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - mo_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_START_STOP_UNIT: - mo_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disk. */ - break; - case 1: /* Start the disk and read the TOC. */ - break; - case 2: /* Eject the disk if possible. */ - mo_eject(dev->id); - break; - case 3: /* Load the disk (close tray). */ - mo_reload(dev->id); - break; - } - - mo_command_complete(dev); - break; - - case GPCMD_INQUIRY: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - mo_buf_alloc(dev, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - dev->buffer[idx++] = 7; /*Optical disk*/ - dev->buffer[idx++] = cdb[2]; - dev->buffer[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 0x80; - break; - case 0x80: /*Unit serial number page*/ - dev->buffer[idx++] = strlen("VCM!10") + 1; - ide_padstr8(dev->buffer + idx, 20, "VCM!10"); /* Serial */ - idx += strlen("VCM!10"); - break; - default: - mo_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - mo_invalid_field(dev); - mo_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ - else - dev->buffer[0] = 0x07; /*Optical disk*/ - dev->buffer[1] = 0x80; /*Removable*/ - dev->buffer[2] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - dev->buffer[3] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x21; - // dev->buffer[4] = 31; - dev->buffer[4] = 0; - if (dev->drv->bus_type == MO_BUS_SCSI) { - dev->buffer[6] = 1; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } - dev->buffer[7] |= 0x02; - - if (dev->drv->type > 0) { - ide_padstr8(dev->buffer + 8, 8, mo_drive_types[dev->drv->type].vendor); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, mo_drive_types[dev->drv->type].model); /* Product */ - ide_padstr8(dev->buffer + 32, 4, mo_drive_types[dev->drv->type].revision); /* Revision */ - } else { - ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ - } - idx = 36; - - if (max_len == 96) { - dev->buffer[4] = 91; - idx = 96; - } else if (max_len == 128) { - dev->buffer[4] = 0x75; - idx = 128; - } - } - - dev->buffer[size_idx] = idx - preamble_len; - len=idx; - - len = MIN(len, max_len); - mo_set_buf_len(dev, BufLen, &len); - - mo_data_command_finish(dev, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - mo_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - } - mo_seek(dev, pos); - mo_command_complete(dev); - break; - - case GPCMD_READ_CDROM_CAPACITY: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - - mo_buf_alloc(dev, 8); - - max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(dev->buffer, 0, 8); - dev->buffer[0] = (max_len >> 24) & 0xff; - dev->buffer[1] = (max_len >> 16) & 0xff; - dev->buffer[2] = (max_len >> 8) & 0xff; - dev->buffer[3] = max_len & 0xff; - dev->buffer[6] = (dev->drv->sector_size >> 8) & 0xff; - dev->buffer[7] = dev->drv->sector_size & 0xff; - len = 8; - - mo_set_buf_len(dev, BufLen, &len); - - mo_data_command_finish(dev, len, len, len, 0); - break; - - case GPCMD_ERASE_10: - case GPCMD_ERASE_12: - /*Relative address*/ - if ((cdb[1] & 1)) - previous_pos = dev->sector_pos; - - switch (cdb[0]) { - case GPCMD_ERASE_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - break; - case GPCMD_ERASE_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - break; - } - - /*Erase all remaining sectors*/ - if ((cdb[1] & 4)) { - /* Cannot have a sector number when erase all*/ - if (dev->sector_len) { - mo_invalid_field(dev); - return; - } - mo_format(dev); - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - } - - switch (cdb[0]) { - case GPCMD_ERASE_10: - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - case GPCMD_ERASE_12: - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - dev->sector_pos += previous_pos; - - mo_erase(dev); - mo_set_phase(dev, SCSI_PHASE_STATUS); - mo_command_complete(dev); - break; - - /*Never seen media that supports generations but it's interesting to know if any implementation calls this commmand*/ - case GPCMD_READ_GENERATION: - mo_set_phase(dev, SCSI_PHASE_DATA_IN); - - mo_buf_alloc(dev, 4); - len = 4; - - dev->buffer[0] = 0; - dev->buffer[1] = 0; - dev->buffer[2] = 0; - dev->buffer[3] = 0; - - mo_set_buf_len(dev, BufLen, &len); - mo_data_command_finish(dev, len, len, len, 0); - break; - - default: - mo_illegal_opcode(dev); - break; + case GPCMD_SEND_DIAGNOSTIC: + if (!(cdb[1] & (1 << 2))) { + mo_invalid_field(dev); + return; + } + /*FALLTHROUGH*/ + case GPCMD_SCSI_RESERVE: + case GPCMD_SCSI_RELEASE: + case GPCMD_TEST_UNIT_READY: + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + + case GPCMD_FORMAT_UNIT: + if (dev->drv->read_only) { + mo_write_protected(dev); + return; + } + + mo_format(dev); + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + + case GPCMD_REZERO_UNIT: + dev->sector_pos = dev->sector_len = 0; + mo_seek(dev, 0); + mo_set_phase(dev, SCSI_PHASE_STATUS); + break; + + case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + max_len = cdb[4]; + + if (!max_len) { + mo_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * MO_TIME; + mo_set_callback(dev); + break; + } + + mo_buf_alloc(dev, 256); + mo_set_buf_len(dev, BufLen, &max_len); + len = (cdb[1] & 1) ? 8 : 18; + mo_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); + mo_data_command_finish(dev, len, len, cdb[4], 0); + break; + + case GPCMD_MECHANISM_STATUS: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + len = (cdb[8] << 8) | cdb[9]; + + mo_buf_alloc(dev, 8); + mo_set_buf_len(dev, BufLen, &len); + + memset(dev->buffer, 0, 8); + dev->buffer[5] = 1; + + mo_data_command_finish(dev, 8, 8, len, 0); + break; + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = dev->drv->sector_size; + + switch (cdb[0]) { + case GPCMD_READ_6: + dev->sector_len = cdb[4]; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + if (dev->sector_len == 0) + dev->sector_len = 256; + mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_READ_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_READ_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + } + + if (!dev->sector_len) { + mo_set_phase(dev, SCSI_PHASE_STATUS); + /* mo_log("MO %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * MO_TIME; + mo_set_callback(dev); + break; + } + + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT + matter anyway, this step should be identical and only the way the read dat is + transferred to the host should be different. */ + + dev->packet_len = max_len * alloc_length; + mo_buf_alloc(dev, dev->packet_len); + + ret = mo_blocks(dev, &alloc_length, 1, 0); + if (ret <= 0) { + mo_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * MO_TIME; + mo_set_callback(dev); + mo_buf_free(dev); + return; + } + + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + mo_data_command_finish(dev, alloc_length, dev->drv->sector_size, alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_MO | dev->id, 1); + else + ui_sb_update_icon(SB_MO | dev->id, 0); + return; + + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + /* Data and blank verification cannot be set at the same time */ + if ((cdb[1] & 2) && (cdb[1] & 4)) { + mo_invalid_field(dev); + return; + } + if (!(cdb[1] & 2) || (cdb[1] & 4)) { + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + } + /*TODO: Implement*/ + mo_invalid_field(dev); + return; + + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + mo_set_phase(dev, SCSI_PHASE_DATA_OUT); + alloc_length = dev->drv->sector_size; + + if (dev->drv->read_only) { + mo_write_protected(dev); + return; + } + + switch (cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_WRITE_6: + dev->sector_len = cdb[4]; + if (dev->sector_len == 0) + dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + break; + case GPCMD_VERIFY_10: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_VERIFY_12: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + if ((dev->sector_pos >= dev->drv->medium_size) /* || + ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ + ) { + mo_lba_out_of_range(dev); + return; + } + + if (!dev->sector_len) { + mo_set_phase(dev, SCSI_PHASE_STATUS); + /* mo_log("MO %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * MO_TIME; + mo_set_callback(dev); + break; + } + + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT + matter anyway, this step should be identical and only the way the read dat is + transferred to the host should be different. */ + + dev->packet_len = max_len * alloc_length; + mo_buf_alloc(dev, dev->packet_len); + + dev->requested_blocks = max_len; + dev->packet_len = max_len << 9; + + mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + mo_data_command_finish(dev, dev->packet_len, dev->drv->sector_size, dev->packet_len, 1); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_MO | dev->id, 1); + else + ui_sb_update_icon(SB_MO | dev->id, 0); + return; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + + if (dev->drv->bus_type == MO_BUS_SCSI) + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + else + block_desc = 0; + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = cdb[4]; + mo_buf_alloc(dev, 256); + } else { + len = (cdb[8] | (cdb[7] << 8)); + mo_buf_alloc(dev, 65536); + } + + if (!(mo_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + mo_invalid_field(dev); + mo_buf_free(dev); + return; + } + + memset(dev->buffer, 0, len); + alloc_length = len; + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = mo_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = len - 1; + dev->buffer[1] = 0; + if (block_desc) + dev->buffer[3] = 8; + } else { + len = mo_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = (len - 2) >> 8; + dev->buffer[1] = (len - 2) & 255; + dev->buffer[2] = 0; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } + } + + mo_set_buf_len(dev, BufLen, &len); + + mo_log("MO %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + + mo_data_command_finish(dev, len, len, alloc_length, 0); + return; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + mo_set_phase(dev, SCSI_PHASE_DATA_OUT); + + if (cdb[0] == GPCMD_MODE_SELECT_6) { + len = cdb[4]; + mo_buf_alloc(dev, 256); + } else { + len = (cdb[7] << 8) | cdb[8]; + mo_buf_alloc(dev, 65536); + } + + mo_set_buf_len(dev, BufLen, &len); + + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; + + mo_data_command_finish(dev, len, len, len, 1); + return; + + case GPCMD_START_STOP_UNIT: + mo_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[4] & 3) { + case 0: /* Stop the disk. */ + break; + case 1: /* Start the disk and read the TOC. */ + break; + case 2: /* Eject the disk if possible. */ + mo_eject(dev->id); + break; + case 3: /* Load the disk (close tray). */ + mo_reload(dev->id); + break; + } + + mo_command_complete(dev); + break; + + case GPCMD_INQUIRY: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; + + mo_buf_alloc(dev, 65536); + + if (cdb[1] & 1) { + preamble_len = 4; + size_idx = 3; + + dev->buffer[idx++] = 7; /*Optical disk*/ + dev->buffer[idx++] = cdb[2]; + dev->buffer[idx++] = 0; + + idx++; + + switch (cdb[2]) { + case 0x00: + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x80; + break; + case 0x80: /*Unit serial number page*/ + dev->buffer[idx++] = strlen("VCM!10") + 1; + ide_padstr8(dev->buffer + idx, 20, "VCM!10"); /* Serial */ + idx += strlen("VCM!10"); + break; + default: + mo_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + mo_invalid_field(dev); + mo_buf_free(dev); + return; + } + } else { + preamble_len = 5; + size_idx = 4; + + memset(dev->buffer, 0, 8); + if (cdb[1] & 0xe0) + dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + else + dev->buffer[0] = 0x07; /*Optical disk*/ + dev->buffer[1] = 0x80; /*Removable*/ + dev->buffer[2] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + dev->buffer[3] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x21; + // dev->buffer[4] = 31; + dev->buffer[4] = 0; + if (dev->drv->bus_type == MO_BUS_SCSI) { + dev->buffer[6] = 1; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ + } + dev->buffer[7] |= 0x02; + + if (dev->drv->type > 0) { + ide_padstr8(dev->buffer + 8, 8, mo_drive_types[dev->drv->type].vendor); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, mo_drive_types[dev->drv->type].model); /* Product */ + ide_padstr8(dev->buffer + 32, 4, mo_drive_types[dev->drv->type].revision); /* Revision */ + } else { + ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ + ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ + } + idx = 36; + + if (max_len == 96) { + dev->buffer[4] = 91; + idx = 96; + } else if (max_len == 128) { + dev->buffer[4] = 0x75; + idx = 128; + } + } + + dev->buffer[size_idx] = idx - preamble_len; + len = idx; + + len = MIN(len, max_len); + mo_set_buf_len(dev, BufLen, &len); + + mo_data_command_finish(dev, len, len, max_len, 0); + break; + + case GPCMD_PREVENT_REMOVAL: + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + mo_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[0]) { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + } + mo_seek(dev, pos); + mo_command_complete(dev); + break; + + case GPCMD_READ_CDROM_CAPACITY: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + + mo_buf_alloc(dev, 8); + + max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ + memset(dev->buffer, 0, 8); + dev->buffer[0] = (max_len >> 24) & 0xff; + dev->buffer[1] = (max_len >> 16) & 0xff; + dev->buffer[2] = (max_len >> 8) & 0xff; + dev->buffer[3] = max_len & 0xff; + dev->buffer[6] = (dev->drv->sector_size >> 8) & 0xff; + dev->buffer[7] = dev->drv->sector_size & 0xff; + len = 8; + + mo_set_buf_len(dev, BufLen, &len); + + mo_data_command_finish(dev, len, len, len, 0); + break; + + case GPCMD_ERASE_10: + case GPCMD_ERASE_12: + /*Relative address*/ + if ((cdb[1] & 1)) + previous_pos = dev->sector_pos; + + switch (cdb[0]) { + case GPCMD_ERASE_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_ERASE_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + break; + } + + /*Erase all remaining sectors*/ + if ((cdb[1] & 4)) { + /* Cannot have a sector number when erase all*/ + if (dev->sector_len) { + mo_invalid_field(dev); + return; + } + mo_format(dev); + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + } + + switch (cdb[0]) { + case GPCMD_ERASE_10: + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + case GPCMD_ERASE_12: + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + dev->sector_pos += previous_pos; + + mo_erase(dev); + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_command_complete(dev); + break; + + /*Never seen media that supports generations but it's interesting to know if any implementation calls this commmand*/ + case GPCMD_READ_GENERATION: + mo_set_phase(dev, SCSI_PHASE_DATA_IN); + + mo_buf_alloc(dev, 4); + len = 4; + + dev->buffer[0] = 0; + dev->buffer[1] = 0; + dev->buffer[2] = 0; + dev->buffer[3] = 0; + + mo_set_buf_len(dev, BufLen, &len); + mo_data_command_finish(dev, len, len, len, 0); + break; + + default: + mo_illegal_opcode(dev); + break; } /* mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ if (mo_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - mo_buf_free(dev); + mo_buf_free(dev); } - static void mo_command_stop(scsi_common_t *sc) { @@ -1899,7 +1848,6 @@ mo_command_stop(scsi_common_t *sc) mo_buf_free(dev); } - /* The command second phase function, needed for Mode Select. */ static uint8_t mo_phase_data_out(scsi_common_t *sc) @@ -1918,99 +1866,98 @@ mo_phase_data_out(scsi_common_t *sc) int len = 0; - switch(dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if (dev->requested_blocks > 0) - mo_blocks(dev, &len, 1, 1); - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { - hdr_len = 8; - param_list_len = dev->current_cdb[7]; - param_list_len <<= 8; - param_list_len |= dev->current_cdb[8]; - } else { - hdr_len = 4; - param_list_len = dev->current_cdb[4]; - } + switch (dev->current_cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + break; + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + if (dev->requested_blocks > 0) + mo_blocks(dev, &len, 1, 1); + break; + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { + hdr_len = 8; + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { + hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } - if (dev->drv->bus_type == MO_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = dev->buffer[2]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[3]; - } else { - block_desc_len = dev->buffer[6]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[7]; - } - } else - block_desc_len = 0; + if (dev->drv->bus_type == MO_BUS_SCSI) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = dev->buffer[2]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[3]; + } else { + block_desc_len = dev->buffer[6]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[7]; + } + } else + block_desc_len = 0; - pos = hdr_len + block_desc_len; + pos = hdr_len + block_desc_len; - while(1) { - if (pos >= param_list_len) { - mo_log("MO %i: Buffer has only block descriptor\n", dev->id); - break; - } + while (1) { + if (pos >= param_list_len) { + mo_log("MO %i: Buffer has only block descriptor\n", dev->id); + break; + } - page = dev->buffer[pos] & 0x3F; - page_len = dev->buffer[pos + 1]; + page = dev->buffer[pos] & 0x3F; + page_len = dev->buffer[pos + 1]; - pos += 2; + pos += 2; - if (!(mo_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = mo_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; - } - } - } + if (!(mo_mode_sense_page_flags & (1LL << ((uint64_t) page)))) + error |= 1; + else { + for (i = 0; i < page_len; i++) { + ch = mo_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else + error |= 1; + } + } + } - pos += page_len; + pos += page_len; - if (dev->drv->bus_type == MO_BUS_SCSI) - val = mo_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = mo_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - mo_mode_sense_save(dev); + if (dev->drv->bus_type == MO_BUS_SCSI) + val = mo_mode_sense_pages_default_scsi.pages[page][0] & 0x80; + else + val = mo_mode_sense_pages_default.pages[page][0] & 0x80; + if (dev->do_page_save && val) + mo_mode_sense_save(dev); - if (pos >= dev->total_length) - break; - } + if (pos >= dev->total_length) + break; + } - if (error) { - mo_buf_free(dev); - mo_invalid_field_pl(dev); - return 0; - } - break; + if (error) { + mo_buf_free(dev); + mo_invalid_field_pl(dev); + return 0; + } + break; } mo_command_stop((scsi_common_t *) dev); return 1; } - /* Peform a master init on the entire module. */ void mo_global_init(void) @@ -2019,50 +1966,48 @@ mo_global_init(void) memset(mo_drives, 0x00, sizeof(mo_drives)); } - static int mo_get_max(int ide_has_dma, int type) { int ret; - switch(type) { - case TYPE_PIO: - ret = ide_has_dma ? 3 : 0; - break; - case TYPE_SDMA: - default: - ret = -1; - break; - case TYPE_MDMA: - ret = ide_has_dma ? 1 : -1; - break; - case TYPE_UDMA: - ret = ide_has_dma ? 5 : -1; - break; + switch (type) { + case TYPE_PIO: + ret = ide_has_dma ? 3 : 0; + break; + case TYPE_SDMA: + default: + ret = -1; + break; + case TYPE_MDMA: + ret = ide_has_dma ? 1 : -1; + break; + case TYPE_UDMA: + ret = ide_has_dma ? 5 : -1; + break; } return ret; } - static int mo_get_timings(int ide_has_dma, int type) { int ret; - switch(type) { - case TIMINGS_DMA: - ret = ide_has_dma ? 0x96 : 0; - break; - case TIMINGS_PIO: - ret = ide_has_dma ? 0xb4 : 0; - break; - case TIMINGS_PIO_FC: - ret = ide_has_dma ? 0xb4 : 0; - break; - default: - ret = 0; - break; + switch (type) { + case TIMINGS_DMA: + ret = ide_has_dma ? 0x96 : 0; + break; + case TIMINGS_PIO: + ret = ide_has_dma ? 0xb4 : 0; + break; + case TIMINGS_PIO_FC: + ret = ide_has_dma ? 0xb4 : 0; + break; + default: + ret = 0; + break; } return ret; @@ -2073,166 +2018,162 @@ mo_do_identify(ide_t *ide, int ide_has_dma) { char model[40]; - mo_t* mo = (mo_t*) ide->sc; + mo_t *mo = (mo_t *) ide->sc; memset(model, 0, 40); if (mo_drives[mo->id].type > 0) { - snprintf(model, 40, "%s %s", mo_drive_types[mo_drives[mo->id].type].vendor, mo_drive_types[mo_drives[mo->id].type].model); - ide_padstr((char *) (ide->buffer + 23), mo_drive_types[mo_drives[mo->id].type].revision, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ + snprintf(model, 40, "%s %s", mo_drive_types[mo_drives[mo->id].type].vendor, mo_drive_types[mo_drives[mo->id].type].model); + ide_padstr((char *) (ide->buffer + 23), mo_drive_types[mo_drives[mo->id].type].revision, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ } else { - snprintf(model, 40, "%s %s%02i", EMU_NAME, "86B_MO", mo->id); - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ + snprintf(model, 40, "%s %s%02i", EMU_NAME, "86B_MO", mo->id); + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ } if (ide_has_dma) { - ide->buffer[80] = 0x70; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6*/ - ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ + ide->buffer[80] = 0x70; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6*/ + ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ } } - static void mo_identify(ide_t *ide, int ide_has_dma) { - ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide->buffer[49] = 0x200; /* LBA supported */ + ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ mo_do_identify(ide, ide_has_dma); } - static void mo_drive_reset(int c) { - mo_t *dev; + mo_t *dev; scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; + ide_t *id; + uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; if (!mo_drives[c].priv) { - mo_drives[c].priv = (mo_t *) malloc(sizeof(mo_t)); - memset(mo_drives[c].priv, 0, sizeof(mo_t)); + mo_drives[c].priv = (mo_t *) malloc(sizeof(mo_t)); + memset(mo_drives[c].priv, 0, sizeof(mo_t)); } dev = (mo_t *) mo_drives[c].priv; - dev->id = c; + dev->id = c; dev->cur_lun = SCSI_LUN_USE_CDB; if (mo_drives[c].bus_type == MO_BUS_SCSI) { - /* SCSI MO, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + /* SCSI MO, attach to the SCSI bus. */ + sd = &scsi_devices[scsi_bus][scsi_id]; - sd->sc = (scsi_common_t *) dev; - sd->command = mo_command; - sd->request_sense = mo_request_sense_for_scsi; - sd->reset = mo_reset; - sd->phase_data_out = mo_phase_data_out; - sd->command_stop = mo_command_stop; - sd->type = SCSI_REMOVABLE_DISK; + sd->sc = (scsi_common_t *) dev; + sd->command = mo_command; + sd->request_sense = mo_request_sense_for_scsi; + sd->reset = mo_reset; + sd->phase_data_out = mo_phase_data_out; + sd->command_stop = mo_command_stop; + sd->type = SCSI_REMOVABLE_DISK; } else if (mo_drives[c].bus_type == MO_BUS_ATAPI) { - /* ATAPI MO, attach to the IDE bus. */ - id = ide_get_drive(mo_drives[c].ide_channel); - /* If the IDE channel is initialized, we attach to it, - otherwise, we do nothing - it's going to be a drive - that's not attached to anything. */ - if (id) { - id->sc = (scsi_common_t *) dev; - id->get_max = mo_get_max; - id->get_timings = mo_get_timings; - id->identify = mo_identify; - id->stop = NULL; - id->packet_command = mo_command; - id->device_reset = mo_reset; - id->phase_data_out = mo_phase_data_out; - id->command_stop = mo_command_stop; - id->bus_master_error = mo_bus_master_error; - id->interrupt_drq = 1; + /* ATAPI MO, attach to the IDE bus. */ + id = ide_get_drive(mo_drives[c].ide_channel); + /* If the IDE channel is initialized, we attach to it, + otherwise, we do nothing - it's going to be a drive + that's not attached to anything. */ + if (id) { + id->sc = (scsi_common_t *) dev; + id->get_max = mo_get_max; + id->get_timings = mo_get_timings; + id->identify = mo_identify; + id->stop = NULL; + id->packet_command = mo_command; + id->device_reset = mo_reset; + id->phase_data_out = mo_phase_data_out; + id->command_stop = mo_command_stop; + id->bus_master_error = mo_bus_master_error; + id->interrupt_drq = 1; - ide_atapi_attach(id); - } + ide_atapi_attach(id); + } } } - void mo_hard_reset(void) { - mo_t *dev; - int c; + mo_t *dev; + int c; uint8_t scsi_id, scsi_bus; for (c = 0; c < MO_NUM; c++) { - if ((mo_drives[c].bus_type == MO_BUS_ATAPI) || (mo_drives[c].bus_type == MO_BUS_SCSI)) { - mo_log("MO hard_reset drive=%d\n", c); + if ((mo_drives[c].bus_type == MO_BUS_ATAPI) || (mo_drives[c].bus_type == MO_BUS_SCSI)) { + mo_log("MO hard_reset drive=%d\n", c); - if (mo_drives[c].bus_type == MO_BUS_SCSI) { - scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = mo_drives[c].scsi_device_id & 0x0f; + if (mo_drives[c].bus_type == MO_BUS_SCSI) { + scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + scsi_id = mo_drives[c].scsi_device_id & 0x0f; - /* Make sure to ignore any SCSI MO drive that has an out of range SCSI Bus. */ - if (scsi_bus >= SCSI_BUS_MAX) - continue; + /* Make sure to ignore any SCSI MO drive that has an out of range SCSI Bus. */ + if (scsi_bus >= SCSI_BUS_MAX) + continue; - /* Make sure to ignore any SCSI MO drive that has an out of range ID. */ - if (scsi_id >= SCSI_ID_MAX) - continue; - } + /* Make sure to ignore any SCSI MO drive that has an out of range ID. */ + if (scsi_id >= SCSI_ID_MAX) + continue; + } - /* Make sure to ignore any ATAPI MO drive that has an out of range IDE channel. */ - if ((mo_drives[c].bus_type == MO_BUS_ATAPI) && (mo_drives[c].ide_channel > 7)) - continue; + /* Make sure to ignore any ATAPI MO drive that has an out of range IDE channel. */ + if ((mo_drives[c].bus_type == MO_BUS_ATAPI) && (mo_drives[c].ide_channel > 7)) + continue; - mo_drive_reset(c); + mo_drive_reset(c); - dev = (mo_t *) mo_drives[c].priv; + dev = (mo_t *) mo_drives[c].priv; - dev->id = c; - dev->drv = &mo_drives[c]; + dev->id = c; + dev->drv = &mo_drives[c]; - mo_init(dev); + mo_init(dev); - if (strlen(mo_drives[c].image_path)) - mo_load(dev, mo_drives[c].image_path); + if (strlen(mo_drives[c].image_path)) + mo_load(dev, mo_drives[c].image_path); - mo_mode_sense_load(dev); + mo_mode_sense_load(dev); - if (mo_drives[c].bus_type == MO_BUS_SCSI) - mo_log("SCSI MO drive %i attached to SCSI ID %i\n", c, mo_drives[c].scsi_device_id); - else if (mo_drives[c].bus_type == MO_BUS_ATAPI) - mo_log("ATAPI MO drive %i attached to IDE channel %i\n", c, mo_drives[c].ide_channel); - } + if (mo_drives[c].bus_type == MO_BUS_SCSI) + mo_log("SCSI MO drive %i attached to SCSI ID %i\n", c, mo_drives[c].scsi_device_id); + else if (mo_drives[c].bus_type == MO_BUS_ATAPI) + mo_log("ATAPI MO drive %i attached to IDE channel %i\n", c, mo_drives[c].ide_channel); + } } } - void mo_close(void) { - mo_t *dev; - int c; + mo_t *dev; + int c; uint8_t scsi_id, scsi_bus; for (c = 0; c < MO_NUM; c++) { - if (mo_drives[c].bus_type == MO_BUS_SCSI) { - scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = mo_drives[c].scsi_device_id & 0x0f; + if (mo_drives[c].bus_type == MO_BUS_SCSI) { + scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + scsi_id = mo_drives[c].scsi_device_id & 0x0f; - memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); - } + memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); + } - dev = (mo_t *) mo_drives[c].priv; + dev = (mo_t *) mo_drives[c].priv; - if (dev) { - mo_disk_unload(dev); + if (dev) { + mo_disk_unload(dev); - free(dev); - mo_drives[c].priv = NULL; - } + free(dev); + mo_drives[c].priv = NULL; + } } } diff --git a/src/disk/zip.c b/src/disk/zip.c index a4e124fee..4c2492c1b 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -36,74 +36,71 @@ #include <86box/hdc_ide.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. */ -const uint8_t zip_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ +const uint8_t zip_command_flags[0x100] = { + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ 0, - IMPLEMENTED, /* 0x06 */ + IMPLEMENTED, /* 0x06 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - IMPLEMENTED, /* 0x0C */ - IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ + IMPLEMENTED | CHECK_READY, /* 0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + IMPLEMENTED, /* 0x0C */ + IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ + IMPLEMENTED, /* 0x15 */ + IMPLEMENTED | SCSI_ONLY, /* 0x16 */ + IMPLEMENTED | SCSI_ONLY, /* 0x17 */ 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ + IMPLEMENTED, /* 0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ 0, 0, 0, 0, - IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ + IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + IMPLEMENTED | CHECK_READY, /* 0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + IMPLEMENTED | CHECK_READY, /* 0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x41 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ + IMPLEMENTED, /* 0x55 */ 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ + IMPLEMENTED, /* 0x5A */ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ + IMPLEMENTED | CHECK_READY, /* 0xAA */ 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + IMPLEMENTED | CHECK_READY, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ + IMPLEMENTED, /* 0xBD */ 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, 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 }; -static uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | - GPMODEP_DISCONNECT_PAGE | - 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 uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | 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 = + // clang-format off { { { 0, 0 }, { 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 }, { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } } }; +// clang-format on static const mode_sense_pages_t zip_250_mode_sense_pages_default = + // clang-format off { { { 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 }, { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } } }; +// clang-format on static const mode_sense_pages_t zip_mode_sense_pages_default_scsi = + // clang-format off { { { 0, 0 }, { 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 }, { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } } }; +// clang-format on static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi = + // clang-format off { { { 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 }, { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } } }; +// clang-format on static const mode_sense_pages_t zip_mode_sense_pages_changeable = + // clang-format off { { { 0, 0 }, @@ -381,8 +379,10 @@ static const mode_sense_pages_t zip_mode_sense_pages_changeable = { 0, 0 }, { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } } }; +// clang-format on static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = + // clang-format off { { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 0x06, 0xFF, 0xFF, 0, 0, 0, 0 }, @@ -433,57 +433,52 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = { 0, 0 }, { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } } }; +// clang-format on - -static void zip_command_complete(zip_t *dev); -static void zip_init(zip_t *dev); - +static void zip_command_complete(zip_t *dev); +static void zip_init(zip_t *dev); #ifdef ENABLE_ZIP_LOG int zip_do_log = ENABLE_ZIP_LOG; - static void zip_log(const char *fmt, ...) { va_list ap; if (zip_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define zip_log(fmt, ...) +# define zip_log(fmt, ...) #endif - int find_zip_for_channel(uint8_t channel) { uint8_t i = 0; for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel == channel)) - return i; + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel == channel)) + return i; } return 0xff; } - static int zip_load_abort(zip_t *dev) { if (dev->drv->f) - fclose(dev->drv->f); - dev->drv->f = NULL; + fclose(dev->drv->f); + dev->drv->f = NULL; dev->drv->medium_size = 0; - zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ + zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; } - int zip_load(zip_t *dev, char *fn) { @@ -491,284 +486,271 @@ zip_load(zip_t *dev, char *fn) dev->drv->f = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); if (!dev->drv->f) { - if (!dev->drv->read_only) { - dev->drv->f = plat_fopen(fn, "rb"); - if (dev->drv->f) - dev->drv->read_only = 1; - else - return zip_load_abort(dev); - } else - return zip_load_abort(dev); + if (!dev->drv->read_only) { + dev->drv->f = plat_fopen(fn, "rb"); + if (dev->drv->f) + dev->drv->read_only = 1; + else + return zip_load_abort(dev); + } else + return zip_load_abort(dev); } fseek(dev->drv->f, 0, SEEK_END); size = ftell(dev->drv->f); if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { - /* This is a ZDI image. */ - size -= 0x1000; - dev->drv->base = 0x1000; + /* This is a ZDI image. */ + size -= 0x1000; + dev->drv->base = 0x1000; } else - dev->drv->base = 0; + dev->drv->base = 0; if (dev->drv->is_250) { - if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", - ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - return zip_load_abort(dev); - } + if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { + zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", + ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); + return zip_load_abort(dev); + } } else { - if (size != (ZIP_SECTORS << 9)) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", - ZIP_SECTORS << 9); - return zip_load_abort(dev); - } + if (size != (ZIP_SECTORS << 9)) { + zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", + ZIP_SECTORS << 9); + return zip_load_abort(dev); + } } dev->drv->medium_size = size >> 9; if (fseek(dev->drv->f, dev->drv->base, SEEK_SET) == -1) - fatal("zip_load(): Error seeking to the beginning of the file\n"); + fatal("zip_load(): Error seeking to the beginning of the file\n"); strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); return 1; } - void zip_disk_reload(zip_t *dev) { int ret = 0; if (strlen(dev->drv->prev_image_path) == 0) - return; + return; else - ret = zip_load(dev, dev->drv->prev_image_path); + ret = zip_load(dev, dev->drv->prev_image_path); if (ret) - dev->unit_attention = 1; + dev->unit_attention = 1; } - void zip_disk_unload(zip_t *dev) { if (dev->drv->f) { - fclose(dev->drv->f); - dev->drv->f = NULL; + fclose(dev->drv->f); + dev->drv->f = NULL; } } - void zip_disk_close(zip_t *dev) { if (dev->drv->f) { - zip_disk_unload(dev); + zip_disk_unload(dev); - memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); - memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); + memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); + memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); - dev->drv->medium_size = 0; + dev->drv->medium_size = 0; } } - static void zip_set_callback(zip_t *dev) { if (dev->drv->bus_type != ZIP_BUS_SCSI) - ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } - static void zip_init(zip_t *dev) { if (dev->id >= ZIP_NUM) - return; + return; dev->requested_blocks = 1; - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->drv->bus_mode = 0; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + dev->drv->bus_mode = 0; if (dev->drv->bus_type >= ZIP_BUS_ATAPI) - dev->drv->bus_mode |= 2; + dev->drv->bus_mode |= 2; if (dev->drv->bus_type < ZIP_BUS_SCSI) - dev->drv->bus_mode |= 1; + dev->drv->bus_mode |= 1; zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); if (dev->drv->bus_type < ZIP_BUS_SCSI) { - dev->phase = 1; - dev->request_length = 0xEB14; + dev->phase = 1; + dev->request_length = 0xEB14; } - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; dev->packet_status = PHASE_NONE; zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; } - static int zip_supports_pio(zip_t *dev) { return (dev->drv->bus_mode & 1); } - static int zip_supports_dma(zip_t *dev) { return (dev->drv->bus_mode & 2); } - /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int zip_current_mode(zip_t *dev) { if (!zip_supports_pio(dev) && !zip_supports_dma(dev)) - return 0; + return 0; if (zip_supports_pio(dev) && !zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", dev->id); - return 1; + zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", dev->id); + return 1; } if (!zip_supports_pio(dev) && zip_supports_dma(dev)) - return 2; + return 2; if (zip_supports_pio(dev) && zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); - return (dev->features & 1) ? 2 : 1; + zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); + return (dev->features & 1) ? 2 : 1; } return 0; } - /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int zip_atapi_phase_to_scsi(zip_t *dev) { if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } + switch (dev->phase & 3) { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 7; + } } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + if ((dev->phase & 3) == 3) + return 3; + else + return 4; } return 0; } - static void zip_mode_sense_load(zip_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (dev->drv->is_250) { - if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); - else - memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) + memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + else + memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default, sizeof(mode_sense_pages_t)); } else { - if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); - else - memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) + memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + else + memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default, sizeof(mode_sense_pages_t)); } memset(file_name, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "rb"); if (f) { - /* Nothing to read, not used by ZIP. */ - fclose(f); + /* Nothing to read, not used by ZIP. */ + fclose(f); } } - static void zip_mode_sense_save(zip_t *dev) { FILE *f; - char file_name[512]; + char file_name[512]; memset(file_name, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); + sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), "wb"); if (f) { - /* Nothing to write, not used by ZIP. */ - fclose(f); + /* Nothing to write, not used by ZIP. */ + fclose(f); } } - /*SCSI Mode Sense 6/10*/ static uint8_t zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { - case 0: - case 3: - if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) - return 0x60; - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - if (dev->drv->is_250) - return zip_250_mode_sense_pages_changeable.pages[page][pos]; - else - return zip_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->is_250) { - if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) - return 0x60; - if (dev->drv->bus_type == ZIP_BUS_SCSI) - return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_250_mode_sense_pages_default.pages[page][pos]; - } else { - if (dev->drv->bus_type == ZIP_BUS_SCSI) - return zip_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_mode_sense_pages_default.pages[page][pos]; - } - break; + case 0: + case 3: + if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) + return 0x60; + return dev->ms_pages_saved.pages[page][pos]; + break; + case 1: + if (dev->drv->is_250) + return zip_250_mode_sense_pages_changeable.pages[page][pos]; + else + return zip_mode_sense_pages_changeable.pages[page][pos]; + break; + case 2: + if (dev->drv->is_250) { + if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) + return 0x60; + if (dev->drv->bus_type == ZIP_BUS_SCSI) + return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; + else + return zip_250_mode_sense_pages_default.pages[page][pos]; + } else { + if (dev->drv->bus_type == ZIP_BUS_SCSI) + return zip_mode_sense_pages_default_scsi.pages[page][pos]; + else + return zip_mode_sense_pages_default.pages[page][pos]; + } + break; } return 0; } - static uint32_t zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) { uint64_t pf; - uint8_t page_control = (page >> 6) & 3; + uint8_t page_control = (page >> 6) & 3; if (dev->drv->is_250) - pf = zip_250_mode_sense_page_flags; + pf = zip_250_mode_sense_page_flags; else - pf = zip_mode_sense_page_flags; + pf = zip_mode_sense_page_flags; int i = 0; int j = 0; @@ -778,33 +760,32 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t blo page &= 0x3f; if (block_descriptor_len) { - buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); - buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); - buf[pos++] = ( dev->drv->medium_size & 0xff); - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; + buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); + buf[pos++] = (dev->drv->medium_size & 0xff); + buf[pos++] = 0; /* Reserved. */ + buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ + buf[pos++] = 2; + buf[pos++] = 0; } for (i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { - if (pf & (1LL << ((uint64_t) page))) { - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0); - msplen = zip_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 2 + j); - } - } + if (pf & (1LL << ((uint64_t) page))) { + buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0); + msplen = zip_mode_sense_read(dev, page_control, i, 1); + buf[pos++] = msplen; + zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + for (j = 0; j < msplen; j++) + buf[pos++] = zip_mode_sense_read(dev, page_control, i, 2 + j); + } + } } return pos; } - static void zip_update_request_length(zip_t *dev, int len, int block_len) { @@ -814,99 +795,96 @@ zip_update_request_length(zip_t *dev, int len, int block_len) /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { - case 0x08: - case 0x0a: - case 0x28: - case 0x2a: - case 0xa8: - case 0xaa: - /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; + case 0x08: + case 0x0a: + case 0x28: + case 0x2a: + case 0xa8: + case 0xaa: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; + /* Make sure total length is not bigger than sum of the lengths of + all the requested blocks. */ + bt = (dev->requested_blocks * block_len); + if (len > bt) + len = bt; - min_len = block_len; + min_len = block_len; - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - /*FALLTHROUGH*/ - default: - dev->packet_len = len; - break; + if (len <= block_len) { + /* Total length is less or equal to block length. */ + if (dev->max_transfer_len < block_len) { + /* Transfer a minimum of (block size) bytes. */ + dev->max_transfer_len = block_len; + dev->packet_len = block_len; + break; + } + } + /*FALLTHROUGH*/ + default: + dev->packet_len = len; + break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; + dev->max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; + dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->request_length = dev->max_transfer_len; return; } - static double zip_bus_speed(zip_t *dev) { double ret = -1.0; if (dev && dev->drv && (dev->drv->bus_type == ZIP_BUS_SCSI)) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return 0.0; + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; } else { - if (dev && dev->drv) - ret = ide_atapi_get_period(dev->drv->ide_channel); - if (ret == -1.0) { - if (dev) - dev->callback = -1.0; - return 0.0; - } else - return ret * 1000000.0; + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + if (dev) + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; } } - static void zip_command_common(zip_t *dev) { double bytes_per_second, period; dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; + dev->phase = 1; + dev->pos = 0; if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0.0; + dev->callback = 0.0; else { - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return; - } else - bytes_per_second = zip_bus_speed(dev); + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return; + } else + bytes_per_second = zip_bus_speed(dev); - period = 1000000.0 / bytes_per_second; - dev->callback = period * (double) (dev->packet_len); + period = 1000000.0 / bytes_per_second; + dev->callback = period * (double) (dev->packet_len); } zip_set_callback(dev); } - static void zip_command_complete(zip_t *dev) { @@ -915,7 +893,6 @@ zip_command_complete(zip_t *dev) zip_command_common(dev); } - static void zip_command_read(zip_t *dev) { @@ -923,7 +900,6 @@ zip_command_read(zip_t *dev) zip_command_common(dev); } - static void zip_command_read_dma(zip_t *dev) { @@ -931,7 +907,6 @@ zip_command_read_dma(zip_t *dev) zip_command_common(dev); } - static void zip_command_write(zip_t *dev) { @@ -939,7 +914,6 @@ zip_command_write(zip_t *dev) zip_command_common(dev); } - static void zip_command_write_dma(zip_t *dev) { @@ -947,7 +921,6 @@ zip_command_write_dma(zip_t *dev) zip_command_common(dev); } - /* id = Current ZIP device ID; len = Total transfer length; block_len = Length of a single block (why does it matter?!); @@ -957,116 +930,109 @@ static void zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction) { zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); dev->pos = 0; if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; + if (alloc_len < len) + len = alloc_len; } if ((len == 0) || (zip_current_mode(dev) == 0)) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) - dev->packet_len = 0; + if (dev->drv->bus_type != ZIP_BUS_SCSI) + dev->packet_len = 0; - zip_command_complete(dev); + zip_command_complete(dev); } else { - if (zip_current_mode(dev) == 2) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) - dev->packet_len = alloc_len; + if (zip_current_mode(dev) == 2) { + if (dev->drv->bus_type != ZIP_BUS_SCSI) + dev->packet_len = alloc_len; - if (direction == 0) - zip_command_read_dma(dev); - else - zip_command_write_dma(dev); - } else { - zip_update_request_length(dev, len, block_len); - if (direction == 0) - zip_command_read(dev); - else - zip_command_write(dev); - } + if (direction == 0) + zip_command_read_dma(dev); + else + zip_command_write_dma(dev); + } else { + zip_update_request_length(dev, len, block_len); + if (direction == 0) + zip_command_read(dev); + else + zip_command_write(dev); + } } zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - 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 zip_sense_clear(zip_t *dev, int command) { zip_sense_key = zip_asc = zip_ascq = 0; } - static void zip_set_phase(zip_t *dev, uint8_t phase) { uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type != ZIP_BUS_SCSI) - return; + return; scsi_devices[scsi_bus][scsi_id].phase = phase; } - static void zip_cmd_error(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * ZIP_TIME; + dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); ui_sb_update_icon(SB_ZIP | dev->id, 0); 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 zip_unit_attention(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * ZIP_TIME; + dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); ui_sb_update_icon(SB_ZIP | dev->id, 0); zip_log("ZIP %i: UNIT ATTENTION\n", dev->id); } - static void zip_buf_alloc(zip_t *dev, uint32_t len) { zip_log("ZIP %i: Allocated buffer length: %i\n", dev->id, len); if (!dev->buffer) - dev->buffer = (uint8_t *) malloc(len); + dev->buffer = (uint8_t *) malloc(len); } - static void zip_buf_free(zip_t *dev) { if (dev->buffer) { - zip_log("ZIP %i: Freeing buffer...\n", dev->id); - free(dev->buffer); - dev->buffer = NULL; + zip_log("ZIP %i: Freeing buffer...\n", dev->id); + free(dev->buffer); + dev->buffer = NULL; } } - static void zip_bus_master_error(scsi_common_t *sc) { @@ -1077,89 +1043,80 @@ zip_bus_master_error(scsi_common_t *sc) zip_cmd_error(dev); } - static void zip_not_ready(zip_t *dev) { zip_sense_key = SENSE_NOT_READY; - zip_asc = ASC_MEDIUM_NOT_PRESENT; - zip_ascq = 0; + zip_asc = ASC_MEDIUM_NOT_PRESENT; + zip_ascq = 0; zip_cmd_error(dev); } - static void zip_write_protected(zip_t *dev) { zip_sense_key = SENSE_UNIT_ATTENTION; - zip_asc = ASC_WRITE_PROTECTED; - zip_ascq = 0; + zip_asc = ASC_WRITE_PROTECTED; + zip_ascq = 0; zip_cmd_error(dev); } - static void zip_invalid_lun(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_LUN; - zip_ascq = 0; + zip_asc = ASC_INV_LUN; + zip_ascq = 0; zip_cmd_error(dev); } - static void zip_illegal_opcode(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_ILLEGAL_OPCODE; - zip_ascq = 0; + zip_asc = ASC_ILLEGAL_OPCODE; + zip_ascq = 0; zip_cmd_error(dev); } - static void zip_lba_out_of_range(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_LBA_OUT_OF_RANGE; - zip_ascq = 0; + zip_asc = ASC_LBA_OUT_OF_RANGE; + zip_ascq = 0; zip_cmd_error(dev); } - static void zip_invalid_field(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; - zip_ascq = 0; + zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; + zip_ascq = 0; zip_cmd_error(dev); dev->status = 0x53; } - static void zip_invalid_field_pl(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - zip_ascq = 0; + zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + zip_ascq = 0; zip_cmd_error(dev); dev->status = 0x53; } - static void zip_data_phase_error(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_DATA_PHASE_ERROR; - zip_ascq = 0; + zip_asc = ASC_DATA_PHASE_ERROR; + zip_ascq = 0; zip_cmd_error(dev); } - static int zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out) { @@ -1167,34 +1124,34 @@ zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out) int i; if (!dev->sector_len) { - zip_command_complete(dev); - return -1; + zip_command_complete(dev); + return -1; } zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); if (dev->sector_pos >= dev->drv->medium_size) { - zip_log("ZIP %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); - zip_lba_out_of_range(dev); - return 0; + zip_log("ZIP %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); + zip_lba_out_of_range(dev); + return 0; } *len = dev->requested_blocks << 9; for (i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) - break; + if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) + break; - if (feof(dev->drv->f)) - break; + if (feof(dev->drv->f)) + break; - if (out) { - if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) - fatal("zip_blocks(): Error writing data\n"); - } else { - if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) - fatal("zip_blocks(): Error reading data\n"); - } + if (out) { + if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) + fatal("zip_blocks(): Error writing data\n"); + } else { + if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) + fatal("zip_blocks(): Error reading data\n"); + } } zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); @@ -1205,55 +1162,52 @@ zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out) return 1; } - void zip_insert(zip_t *dev) { dev->unit_attention = 1; } - /*SCSI Sense Initialization*/ void zip_sense_code_ok(zip_t *dev) { zip_sense_key = SENSE_NONE; - zip_asc = 0; - zip_ascq = 0; + zip_asc = 0; + zip_ascq = 0; } - static int zip_pre_execution_check(zip_t *dev, uint8_t *cdb) { int ready = 0; if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); - zip_invalid_lun(dev); - return 0; - } + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { + zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); + zip_invalid_lun(dev); + return 0; + } } if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); + zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], + (dev->drv->bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); - zip_illegal_opcode(dev); - return 0; + zip_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); - return 0; + zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); + zip_illegal_opcode(dev); + return 0; } if ((dev->drv->bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); - return 0; + zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); + zip_illegal_opcode(dev); + return 0; } ready = (dev->drv->f != NULL); @@ -1262,36 +1216,36 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) UNIT ATTENTION condition present, as we only use it to mark disc changes. */ if (!ready && dev->unit_attention) - dev->unit_attention = 0; + dev->unit_attention = 0; /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - /* zip_log("ZIP %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention = 2; - zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); - zip_unit_attention(dev); - return 0; - } + /* Only increment the unit attention phase if the command can not pass through it. */ + if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { + /* zip_log("ZIP %i: Unit attention now 2\n", dev->id); */ + dev->unit_attention = 2; + zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); + zip_unit_attention(dev); + return 0; + } } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* zip_log("ZIP %i: Unit attention now 0\n", dev->id); */ - dev->unit_attention = 0; - } + if (cdb[0] != GPCMD_REQUEST_SENSE) { + /* zip_log("ZIP %i: Unit attention now 0\n", dev->id); */ + dev->unit_attention = 0; + } } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - zip_sense_clear(dev, cdb[0]); + zip_sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) { - zip_log("ZIP %i: Not ready (%02X)\n", dev->id, cdb[0]); - zip_not_ready(dev); - return 0; + zip_log("ZIP %i: Not ready (%02X)\n", dev->id, cdb[0]); + zip_not_ready(dev); + return 0; } zip_log("ZIP %i: Continuing with command %02X\n", dev->id, cdb[0]); @@ -1299,15 +1253,13 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) return 1; } - static void zip_seek(zip_t *dev, uint32_t pos) { /* zip_log("ZIP %i: Seek %08X\n", dev->id, pos); */ - dev->sector_pos = pos; + dev->sector_pos = pos; } - static void zip_rezero(zip_t *dev) { @@ -1315,73 +1267,70 @@ zip_rezero(zip_t *dev) zip_seek(dev, 0); } - void zip_reset(scsi_common_t *sc) { zip_t *dev = (zip_t *) sc; zip_rezero(dev); - dev->status = 0; + dev->status = 0; dev->callback = 0.0; zip_set_callback(dev); - dev->phase = 1; + dev->phase = 1; dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; + dev->packet_status = PHASE_NONE; dev->unit_attention = 0; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->cur_lun = SCSI_LUN_USE_CDB; } - static void zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = zip_sense_key; - buffer[2] = zip_asc; - buffer[3] = zip_ascq; - } + memset(buffer, 0, alloc_length); + if (!desc) + memcpy(buffer, dev->sense, alloc_length); + else { + buffer[1] = zip_sense_key; + buffer[2] = zip_asc; + buffer[3] = zip_ascq; + } } buffer[0] = desc ? 0x72 : 0x70; if (dev->unit_attention && (zip_sense_key == 0)) { - buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; - buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[desc ? 3 : 13] = 0; + buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; + buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[desc ? 3 : 13] = 0; } zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; + /* If the last remaining sense is unit attention, clear + that condition. */ + dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ zip_sense_clear(dev, GPCMD_REQUEST_SENSE); } - static void zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { - zip_t *dev = (zip_t *) sc; - int ready = 0; + zip_t *dev = (zip_t *) sc; + int ready = 0; ready = (dev->drv->f != NULL); if (!ready && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ @@ -1389,59 +1338,57 @@ zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_len zip_request_sense(dev, buffer, alloc_length, 0); } - static void zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - zip_log("ZIP %i: Actual transfer length: %i\n", dev->id, *BufLen); + if (*BufLen == -1) + *BufLen = *src_len; + else { + *BufLen = MIN(*src_len, *BufLen); + *src_len = *BufLen; + } + zip_log("ZIP %i: Actual transfer length: %i\n", dev->id, *BufLen); } } - static void zip_command(scsi_common_t *sc, uint8_t *cdb) { - zip_t *dev = (zip_t *) sc; - int pos = 0, block_desc = 0; - int ret; - int32_t len, max_len; - int32_t alloc_length; + zip_t *dev = (zip_t *) sc; + int pos = 0, block_desc = 0; + int ret; + int32_t len, max_len; + int32_t alloc_length; uint32_t i = 0; - int size_idx, idx = 0; + int size_idx, idx = 0; unsigned preamble_len; - int32_t blen = 0; + int32_t blen = 0; int32_t *BufLen; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == ZIP_BUS_SCSI) { - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->status &= ~ERR_STAT; } else { - BufLen = &blen; - dev->error = 0; + BufLen = &blen; + dev->error = 0; } - dev->packet_len = 0; + dev->packet_len = 0; dev->request_pos = 0; memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length); + zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", + dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); + zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length); - zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); + zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + cdb[8], cdb[9], cdb[10], cdb[11]); } dev->sector_len = 0; @@ -1450,626 +1397,627 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ if (zip_pre_execution_check(dev, cdb) == 0) - return; + return; switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(dev); - return; - } - /*FALLTHROUGH*/ - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - - case GPCMD_FORMAT_UNIT: - if (dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - - case GPCMD_IOMEGA_SENSE: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); - memset(dev->buffer, 0, 256); - if (cdb[2] == 1) { - /* This page is related to disk health status - setting - this page to 0 makes disk health read as "marginal". */ - dev->buffer[0] = 0x58; - dev->buffer[1] = 0x00; - for (i = 0x00; i < 0x58; i++) - dev->buffer[i + 0x02] = 0xff; - } else if (cdb[2] == 2) { - dev->buffer[0] = 0x3d; - dev->buffer[1] = 0x00; - for (i = 0x00; i < 0x13; i++) - dev->buffer[i + 0x02] = 0x00; - dev->buffer[0x15] = 0x00; - if (dev->drv->read_only) - dev->buffer[0x15] |= 0x02; - for (i = 0x00; i < 0x27; i++) - dev->buffer[i + 0x16] = 0x00; - } else { - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - zip_data_command_finish(dev, 18, 18, cdb[4], 0); - break; - - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - zip_seek(dev, 0); - zip_set_phase(dev, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - - if (!max_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - break; - } - - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); - len = (cdb[1] & 1) ? 8 : 18; - zip_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); - zip_data_command_finish(dev, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - len = (cdb[8] << 8) | cdb[9]; - - zip_buf_alloc(dev, 8); - zip_set_buf_len(dev, BufLen, &len); - - memset(dev->buffer, 0, 8); - dev->buffer[5] = 1; - - zip_data_command_finish(dev, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = 512; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - ret = zip_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - zip_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = 512; - - if (dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - switch(cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((dev->sector_pos >= dev->drv->medium_size)/* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) { - zip_lba_out_of_range(dev); - return; - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_WRITE_SAME_10: - alloc_length = 512; - - if ((cdb[1] & 6) == 6) { - zip_invalid_field(dev); - return; - } - - if (dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - if ((dev->sector_pos >= dev->drv->medium_size)/* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/) { - zip_lba_out_of_range(dev); - return; - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - break; - } - - zip_buf_alloc(dev, alloc_length); - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - max_len = 1; - dev->requested_blocks = 1; - - dev->packet_len = alloc_length; - - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - - zip_data_command_finish(dev, 512, 512, alloc_length, 1); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - - if (dev->drv->bus_type == ZIP_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - zip_buf_alloc(dev, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - zip_buf_alloc(dev, 65536); - } - - if (!(zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - - memset(dev->buffer, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = len - 1; - dev->buffer[1] = 0; - if (block_desc) - dev->buffer[3] = 8; - } else { - len = zip_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0]=(len - 2) >> 8; - dev->buffer[1]=(len - 2) & 255; - dev->buffer[2] = 0; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; - } - } - - zip_set_buf_len(dev, BufLen, &len); - - zip_log("ZIP %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - zip_data_command_finish(dev, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - zip_buf_alloc(dev, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(dev, 65536); - } - - zip_set_buf_len(dev, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - zip_data_command_finish(dev, len, len, len, 1); - return; - - case GPCMD_START_STOP_UNIT: - zip_set_phase(dev, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disc. */ - zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ - break; - case 1: /* Start the disc and read the TOC. */ - break; - case 2: /* Eject the disc if possible. */ - /* zip_eject(dev->id); */ - break; - case 3: /* Load the disc (close tray). */ - zip_reload(dev->id); - break; - } - - zip_command_complete(dev); - break; - - case GPCMD_INQUIRY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - zip_buf_alloc(dev, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - dev->buffer[idx++] = 0; - dev->buffer[idx++] = cdb[2]; - dev->buffer[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - zip_data_phase_error(dev); - zip_buf_free(dev); - return; - } - - dev->buffer[idx++] = 0x02; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 20; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - dev->buffer[idx++] = 0x02; - dev->buffer[idx++] = 0x01; - dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 68; - ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); /* Vendor */ - idx += 8; - if (dev->drv->is_250) - ide_padstr8(dev->buffer + idx, 40, "ZIP 250 "); /* Product */ - else - ide_padstr8(dev->buffer + idx, 40, "ZIP 100 "); /* Product */ - idx += 40; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ - else - dev->buffer[0] = 0x00; /*Hard disk*/ - dev->buffer[1] = 0x80; /*Removable*/ - dev->buffer[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - dev->buffer[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - // dev->buffer[4] = 31; - dev->buffer[4] = 0; - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - dev->buffer[6] = 1; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } - dev->buffer[7] |= 0x02; - - ide_padstr8(dev->buffer + 8, 8, "IOMEGA "); /* Vendor */ - if (dev->drv->is_250) { - ide_padstr8(dev->buffer + 16, 16, "ZIP 250 "); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "42.S"); /* Revision */ - if (max_len >= 44) - ide_padstr8(dev->buffer + 36, 8, "08/08/01"); /* Date? */ - if (max_len >= 122) - ide_padstr8(dev->buffer + 96, 26, "(c) Copyright IOMEGA 2000 "); /* Copyright string */ - } else { - ide_padstr8(dev->buffer + 16, 16, "ZIP 100 "); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "E.08"); /* Revision */ - } - idx = 36; - - if (max_len == 96) { - dev->buffer[4] = 91; - idx = 96; - } else if (max_len == 128) { - dev->buffer[4] = 0x75; - idx = 128; - } - } + case GPCMD_SEND_DIAGNOSTIC: + if (!(cdb[1] & (1 << 2))) { + zip_invalid_field(dev); + return; + } + /*FALLTHROUGH*/ + case GPCMD_SCSI_RESERVE: + case GPCMD_SCSI_RELEASE: + case GPCMD_TEST_UNIT_READY: + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); + break; + + case GPCMD_FORMAT_UNIT: + if (dev->drv->read_only) { + zip_write_protected(dev); + return; + } + + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); + break; + + case GPCMD_IOMEGA_SENSE: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + max_len = cdb[4]; + zip_buf_alloc(dev, 256); + zip_set_buf_len(dev, BufLen, &max_len); + memset(dev->buffer, 0, 256); + if (cdb[2] == 1) { + /* This page is related to disk health status - setting + this page to 0 makes disk health read as "marginal". */ + dev->buffer[0] = 0x58; + dev->buffer[1] = 0x00; + for (i = 0x00; i < 0x58; i++) + dev->buffer[i + 0x02] = 0xff; + } else if (cdb[2] == 2) { + dev->buffer[0] = 0x3d; + dev->buffer[1] = 0x00; + for (i = 0x00; i < 0x13; i++) + dev->buffer[i + 0x02] = 0x00; + dev->buffer[0x15] = 0x00; + if (dev->drv->read_only) + dev->buffer[0x15] |= 0x02; + for (i = 0x00; i < 0x27; i++) + dev->buffer[i + 0x16] = 0x00; + } else { + zip_invalid_field(dev); + zip_buf_free(dev); + return; + } + zip_data_command_finish(dev, 18, 18, cdb[4], 0); + break; + + case GPCMD_REZERO_UNIT: + dev->sector_pos = dev->sector_len = 0; + zip_seek(dev, 0); + zip_set_phase(dev, SCSI_PHASE_STATUS); + break; + + case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + max_len = cdb[4]; + + if (!max_len) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + break; + } + + zip_buf_alloc(dev, 256); + zip_set_buf_len(dev, BufLen, &max_len); + len = (cdb[1] & 1) ? 8 : 18; + zip_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); + zip_data_command_finish(dev, len, len, cdb[4], 0); + break; + + case GPCMD_MECHANISM_STATUS: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + len = (cdb[8] << 8) | cdb[9]; + + zip_buf_alloc(dev, 8); + zip_set_buf_len(dev, BufLen, &len); + + memset(dev->buffer, 0, 8); + dev->buffer[5] = 1; + + zip_data_command_finish(dev, 8, 8, len, 0); + break; + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = 512; + + switch (cdb[0]) { + case GPCMD_READ_6: + dev->sector_len = cdb[4]; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_READ_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_READ_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + if (!dev->sector_len) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + break; + } + + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT + matter anyway, this step should be identical and only the way the read dat is + transferred to the host should be different. */ + + dev->packet_len = max_len * alloc_length; + zip_buf_alloc(dev, dev->packet_len); + + ret = zip_blocks(dev, &alloc_length, 1, 0); + if (ret <= 0) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + zip_buf_free(dev); + return; + } + + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_ZIP | dev->id, 1); + else + ui_sb_update_icon(SB_ZIP | dev->id, 0); + return; + + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + if (!(cdb[1] & 2)) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); + break; + } + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + alloc_length = 512; + + if (dev->drv->read_only) { + zip_write_protected(dev); + return; + } + + switch (cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_WRITE_6: + dev->sector_len = cdb[4]; + if (dev->sector_len == 0) + dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + break; + case GPCMD_VERIFY_10: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + break; + case GPCMD_VERIFY_12: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + if ((dev->sector_pos >= dev->drv->medium_size) /* || + ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ + ) { + zip_lba_out_of_range(dev); + return; + } + + if (!dev->sector_len) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + break; + } + + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT + matter anyway, this step should be identical and only the way the read dat is + transferred to the host should be different. */ + + dev->packet_len = max_len * alloc_length; + zip_buf_alloc(dev, dev->packet_len); + + dev->requested_blocks = max_len; + dev->packet_len = max_len << 9; + + zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_ZIP | dev->id, 1); + else + ui_sb_update_icon(SB_ZIP | dev->id, 0); + return; + + case GPCMD_WRITE_SAME_10: + alloc_length = 512; + + if ((cdb[1] & 6) == 6) { + zip_invalid_field(dev); + return; + } + + if (dev->drv->read_only) { + zip_write_protected(dev); + return; + } + + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + if ((dev->sector_pos >= dev->drv->medium_size) /* || + ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ + ) { + zip_lba_out_of_range(dev); + return; + } + + if (!dev->sector_len) { + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + break; + } + + zip_buf_alloc(dev, alloc_length); + zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + max_len = 1; + dev->requested_blocks = 1; + + dev->packet_len = alloc_length; + + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + + zip_data_command_finish(dev, 512, 512, alloc_length, 1); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_ZIP | dev->id, 1); + else + ui_sb_update_icon(SB_ZIP | dev->id, 0); + return; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + + if (dev->drv->bus_type == ZIP_BUS_SCSI) + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + else + block_desc = 0; + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = cdb[4]; + zip_buf_alloc(dev, 256); + } else { + len = (cdb[8] | (cdb[7] << 8)); + zip_buf_alloc(dev, 65536); + } + + if (!(zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + zip_invalid_field(dev); + zip_buf_free(dev); + return; + } + + memset(dev->buffer, 0, len); + alloc_length = len; + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = zip_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = len - 1; + dev->buffer[1] = 0; + if (block_desc) + dev->buffer[3] = 8; + } else { + len = zip_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = (len - 2) >> 8; + dev->buffer[1] = (len - 2) & 255; + dev->buffer[2] = 0; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } + } + + zip_set_buf_len(dev, BufLen, &len); + + zip_log("ZIP %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + + zip_data_command_finish(dev, len, len, alloc_length, 0); + return; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + + if (cdb[0] == GPCMD_MODE_SELECT_6) { + len = cdb[4]; + zip_buf_alloc(dev, 256); + } else { + len = (cdb[7] << 8) | cdb[8]; + zip_buf_alloc(dev, 65536); + } + + zip_set_buf_len(dev, BufLen, &len); + + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; + + zip_data_command_finish(dev, len, len, len, 1); + return; + + case GPCMD_START_STOP_UNIT: + zip_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[4] & 3) { + case 0: /* Stop the disc. */ + zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ + break; + case 1: /* Start the disc and read the TOC. */ + break; + case 2: /* Eject the disc if possible. */ + /* zip_eject(dev->id); */ + break; + case 3: /* Load the disc (close tray). */ + zip_reload(dev->id); + break; + } + + zip_command_complete(dev); + break; + + case GPCMD_INQUIRY: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; + + zip_buf_alloc(dev, 65536); + + if (cdb[1] & 1) { + preamble_len = 4; + size_idx = 3; + + dev->buffer[idx++] = 0; + dev->buffer[idx++] = cdb[2]; + dev->buffer[idx++] = 0; + + idx++; + + switch (cdb[2]) { + case 0x00: + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x83; + break; + case 0x83: + if (idx + 24 > max_len) { + zip_data_phase_error(dev); + zip_buf_free(dev); + return; + } + + dev->buffer[idx++] = 0x02; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 20; + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > cdb[4]) + goto atapi_out; + dev->buffer[idx++] = 0x02; + dev->buffer[idx++] = 0x01; + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 68; + ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); /* Vendor */ + idx += 8; + if (dev->drv->is_250) + ide_padstr8(dev->buffer + idx, 40, "ZIP 250 "); /* Product */ + else + ide_padstr8(dev->buffer + idx, 40, "ZIP 100 "); /* Product */ + idx += 40; + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + default: + zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + zip_invalid_field(dev); + zip_buf_free(dev); + return; + } + } else { + preamble_len = 5; + size_idx = 4; + + memset(dev->buffer, 0, 8); + if (cdb[1] & 0xe0) + dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + else + dev->buffer[0] = 0x00; /*Hard disk*/ + dev->buffer[1] = 0x80; /*Removable*/ + dev->buffer[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + dev->buffer[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; + // dev->buffer[4] = 31; + dev->buffer[4] = 0; + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + dev->buffer[6] = 1; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ + } + dev->buffer[7] |= 0x02; + + ide_padstr8(dev->buffer + 8, 8, "IOMEGA "); /* Vendor */ + if (dev->drv->is_250) { + ide_padstr8(dev->buffer + 16, 16, "ZIP 250 "); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "42.S"); /* Revision */ + if (max_len >= 44) + ide_padstr8(dev->buffer + 36, 8, "08/08/01"); /* Date? */ + if (max_len >= 122) + ide_padstr8(dev->buffer + 96, 26, "(c) Copyright IOMEGA 2000 "); /* Copyright string */ + } else { + ide_padstr8(dev->buffer + 16, 16, "ZIP 100 "); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "E.08"); /* Revision */ + } + idx = 36; + + if (max_len == 96) { + dev->buffer[4] = 91; + idx = 96; + } else if (max_len == 128) { + dev->buffer[4] = 0x75; + idx = 128; + } + } atapi_out: - dev->buffer[size_idx] = idx - preamble_len; - len=idx; + dev->buffer[size_idx] = idx - preamble_len; + len = idx; - len = MIN(len, max_len); - zip_set_buf_len(dev, BufLen, &len); + len = MIN(len, max_len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, max_len, 0); - break; + zip_data_command_finish(dev, len, len, max_len, 0); + break; - case GPCMD_PREVENT_REMOVAL: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); - break; + case GPCMD_PREVENT_REMOVAL: + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); + break; - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - zip_set_phase(dev, SCSI_PHASE_STATUS); + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + zip_set_phase(dev, SCSI_PHASE_STATUS); - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - } - zip_seek(dev, pos); - zip_command_complete(dev); - break; + switch (cdb[0]) { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + break; + } + zip_seek(dev, pos); + zip_command_complete(dev); + break; - case GPCMD_READ_CDROM_CAPACITY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + case GPCMD_READ_CDROM_CAPACITY: + zip_set_phase(dev, SCSI_PHASE_DATA_IN); - zip_buf_alloc(dev, 8); + zip_buf_alloc(dev, 8); - max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(dev->buffer, 0, 8); - dev->buffer[0] = (max_len >> 24) & 0xff; - dev->buffer[1] = (max_len >> 16) & 0xff; - dev->buffer[2] = (max_len >> 8) & 0xff; - dev->buffer[3] = max_len & 0xff; - dev->buffer[6] = 2; /* 512 = 0x0200 */ - len = 8; + max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ + memset(dev->buffer, 0, 8); + dev->buffer[0] = (max_len >> 24) & 0xff; + dev->buffer[1] = (max_len >> 16) & 0xff; + dev->buffer[2] = (max_len >> 8) & 0xff; + dev->buffer[3] = max_len & 0xff; + dev->buffer[6] = 2; /* 512 = 0x0200 */ + len = 8; - zip_set_buf_len(dev, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, len, 0); - break; + zip_data_command_finish(dev, len, len, len, 0); + break; - case GPCMD_IOMEGA_EJECT: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_eject(dev->id); - zip_command_complete(dev); - break; + case GPCMD_IOMEGA_EJECT: + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_eject(dev->id); + zip_command_complete(dev); + break; - case GPCMD_READ_FORMAT_CAPACITIES: - len = (cdb[7] << 8) | cdb[8]; + case GPCMD_READ_FORMAT_CAPACITIES: + len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(dev, len); - memset(dev->buffer, 0, len); + zip_buf_alloc(dev, len); + memset(dev->buffer, 0, len); - pos = 0; + pos = 0; - /* List header */ - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; - if (dev->drv->f != NULL) - dev->buffer[pos++] = 16; - else - dev->buffer[pos++] = 8; + /* List header */ + dev->buffer[pos++] = 0; + dev->buffer[pos++] = 0; + dev->buffer[pos++] = 0; + if (dev->drv->f != NULL) + dev->buffer[pos++] = 16; + else + dev->buffer[pos++] = 8; - /* Current/Maximum capacity header */ - if (dev->drv->is_250) { - /* ZIP 250 also supports ZIP 100 media, so if the medium is inserted, - we return the inserted medium's size, otherwise, the ZIP 250 size. */ - if (dev->drv->f != NULL) { - dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; - dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; - dev->buffer[pos++] = (dev->drv->medium_size >> 8) & 0xff; - dev->buffer[pos++] = dev->drv->medium_size & 0xff; - dev->buffer[pos++] = 2; /* Current medium capacity */ - } else { - dev->buffer[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; - dev->buffer[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; - dev->buffer[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; - dev->buffer[pos++] = ZIP_250_SECTORS & 0xff; - dev->buffer[pos++] = 3; /* Maximum medium capacity */ - } - } else { - /* ZIP 100 only supports ZIP 100 media as well, so we always return - the ZIP 100 size. */ - dev->buffer[pos++] = (ZIP_SECTORS >> 24) & 0xff; - dev->buffer[pos++] = (ZIP_SECTORS >> 16) & 0xff; - dev->buffer[pos++] = (ZIP_SECTORS >> 8) & 0xff; - dev->buffer[pos++] = ZIP_SECTORS & 0xff; - if (dev->drv->f != NULL) - dev->buffer[pos++] = 2; - else - dev->buffer[pos++] = 3; - } + /* Current/Maximum capacity header */ + if (dev->drv->is_250) { + /* ZIP 250 also supports ZIP 100 media, so if the medium is inserted, + we return the inserted medium's size, otherwise, the ZIP 250 size. */ + if (dev->drv->f != NULL) { + dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; + dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; + dev->buffer[pos++] = (dev->drv->medium_size >> 8) & 0xff; + dev->buffer[pos++] = dev->drv->medium_size & 0xff; + dev->buffer[pos++] = 2; /* Current medium capacity */ + } else { + dev->buffer[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; + dev->buffer[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; + dev->buffer[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; + dev->buffer[pos++] = ZIP_250_SECTORS & 0xff; + dev->buffer[pos++] = 3; /* Maximum medium capacity */ + } + } else { + /* ZIP 100 only supports ZIP 100 media as well, so we always return + the ZIP 100 size. */ + dev->buffer[pos++] = (ZIP_SECTORS >> 24) & 0xff; + dev->buffer[pos++] = (ZIP_SECTORS >> 16) & 0xff; + dev->buffer[pos++] = (ZIP_SECTORS >> 8) & 0xff; + dev->buffer[pos++] = ZIP_SECTORS & 0xff; + if (dev->drv->f != NULL) + dev->buffer[pos++] = 2; + else + dev->buffer[pos++] = 3; + } - dev->buffer[pos++] = 512 >> 16; - dev->buffer[pos++] = 512 >> 8; - dev->buffer[pos++] = 512 & 0xff; + dev->buffer[pos++] = 512 >> 16; + dev->buffer[pos++] = 512 >> 8; + dev->buffer[pos++] = 512 & 0xff; - if (dev->drv->f != NULL) { - /* Formattable capacity descriptor */ - dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; - dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; - dev->buffer[pos++] = (dev->drv->medium_size >> 8) & 0xff; - dev->buffer[pos++] = dev->drv->medium_size & 0xff; - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 512 >> 16; - dev->buffer[pos++] = 512 >> 8; - dev->buffer[pos++] = 512 & 0xff; - } + if (dev->drv->f != NULL) { + /* Formattable capacity descriptor */ + dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; + dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; + dev->buffer[pos++] = (dev->drv->medium_size >> 8) & 0xff; + dev->buffer[pos++] = dev->drv->medium_size & 0xff; + dev->buffer[pos++] = 0; + dev->buffer[pos++] = 512 >> 16; + dev->buffer[pos++] = 512 >> 8; + dev->buffer[pos++] = 512 & 0xff; + } - zip_set_buf_len(dev, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, len, 0); - break; + zip_data_command_finish(dev, len, len, len, 0); + break; - default: - zip_illegal_opcode(dev); - break; + default: + zip_illegal_opcode(dev); + break; } /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - zip_buf_free(dev); + zip_buf_free(dev); } - static void zip_command_stop(scsi_common_t *sc) { @@ -2079,7 +2027,6 @@ zip_command_stop(scsi_common_t *sc) zip_buf_free(dev); } - /* The command second phase function, needed for Mode Select. */ static uint8_t zip_phase_data_out(scsi_common_t *sc) @@ -2101,131 +2048,130 @@ zip_phase_data_out(scsi_common_t *sc) int len = 0; - switch(dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if (dev->requested_blocks > 0) - zip_blocks(dev, &len, 1, 1); - break; - case GPCMD_WRITE_SAME_10: - if (!dev->current_cdb[7] && !dev->current_cdb[8]) { - last_to_write = (dev->drv->medium_size - 1); - } else - last_to_write = dev->sector_pos + dev->sector_len - 1; + switch (dev->current_cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + break; + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + if (dev->requested_blocks > 0) + zip_blocks(dev, &len, 1, 1); + break; + case GPCMD_WRITE_SAME_10: + if (!dev->current_cdb[7] && !dev->current_cdb[8]) { + last_to_write = (dev->drv->medium_size - 1); + } else + last_to_write = dev->sector_pos + dev->sector_len - 1; - for (i = dev->sector_pos; i <= last_to_write; i++) { - if (dev->current_cdb[1] & 2) { - dev->buffer[0] = (i >> 24) & 0xff; - dev->buffer[1] = (i >> 16) & 0xff; - dev->buffer[2] = (i >> 8) & 0xff; - dev->buffer[3] = i & 0xff; - } else if (dev->current_cdb[1] & 4) { - /* CHS are 96,1,2048 (ZIP 100) and 239,1,2048 (ZIP 250) */ - s = (i % 2048); - h = ((i - s) / 2048) % 1; - c = ((i - s) / 2048) / 1; - dev->buffer[0] = (c >> 16) & 0xff; - dev->buffer[1] = (c >> 8) & 0xff; - dev->buffer[2] = c & 0xff; - dev->buffer[3] = h & 0xff; - dev->buffer[4] = (s >> 24) & 0xff; - dev->buffer[5] = (s >> 16) & 0xff; - dev->buffer[6] = (s >> 8) & 0xff; - dev->buffer[7] = s & 0xff; - } - if (fseek(dev->drv->f, dev->drv->base + (i << 9), SEEK_SET) == -1) - fatal("zip_phase_data_out(): Error seeking\n"); - if (fwrite(dev->buffer, 1, 512, dev->drv->f) != 512) - fatal("zip_phase_data_out(): Error writing data\n"); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { - hdr_len = 8; - param_list_len = dev->current_cdb[7]; - param_list_len <<= 8; - param_list_len |= dev->current_cdb[8]; - } else { - hdr_len = 4; - param_list_len = dev->current_cdb[4]; - } + for (i = dev->sector_pos; i <= last_to_write; i++) { + if (dev->current_cdb[1] & 2) { + dev->buffer[0] = (i >> 24) & 0xff; + dev->buffer[1] = (i >> 16) & 0xff; + dev->buffer[2] = (i >> 8) & 0xff; + dev->buffer[3] = i & 0xff; + } else if (dev->current_cdb[1] & 4) { + /* CHS are 96,1,2048 (ZIP 100) and 239,1,2048 (ZIP 250) */ + s = (i % 2048); + h = ((i - s) / 2048) % 1; + c = ((i - s) / 2048) / 1; + dev->buffer[0] = (c >> 16) & 0xff; + dev->buffer[1] = (c >> 8) & 0xff; + dev->buffer[2] = c & 0xff; + dev->buffer[3] = h & 0xff; + dev->buffer[4] = (s >> 24) & 0xff; + dev->buffer[5] = (s >> 16) & 0xff; + dev->buffer[6] = (s >> 8) & 0xff; + dev->buffer[7] = s & 0xff; + } + if (fseek(dev->drv->f, dev->drv->base + (i << 9), SEEK_SET) == -1) + fatal("zip_phase_data_out(): Error seeking\n"); + if (fwrite(dev->buffer, 1, 512, dev->drv->f) != 512) + fatal("zip_phase_data_out(): Error writing data\n"); + } + break; + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { + hdr_len = 8; + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { + hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } - if (dev->drv->bus_type == ZIP_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = dev->buffer[2]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[3]; - } else { - block_desc_len = dev->buffer[6]; - block_desc_len <<= 8; - block_desc_len |= dev->buffer[7]; - } - } else - block_desc_len = 0; + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = dev->buffer[2]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[3]; + } else { + block_desc_len = dev->buffer[6]; + block_desc_len <<= 8; + block_desc_len |= dev->buffer[7]; + } + } else + block_desc_len = 0; - pos = hdr_len + block_desc_len; + pos = hdr_len + block_desc_len; - while(1) { - if (pos >= param_list_len) { - zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id); - break; - } + while (1) { + if (pos >= param_list_len) { + zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id); + break; + } - page = dev->buffer[pos] & 0x3F; - page_len = dev->buffer[pos + 1]; + page = dev->buffer[pos] & 0x3F; + page_len = dev->buffer[pos + 1]; - pos += 2; + pos += 2; - if (!(zip_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; - } - } - } + if (!(zip_mode_sense_page_flags & (1LL << ((uint64_t) page)))) + error |= 1; + else { + for (i = 0; i < page_len; i++) { + ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else + error |= 1; + } + } + } - pos += page_len; + pos += page_len; - if (dev->drv->bus_type == ZIP_BUS_SCSI) - val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = zip_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - zip_mode_sense_save(dev); + if (dev->drv->bus_type == ZIP_BUS_SCSI) + val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; + else + val = zip_mode_sense_pages_default.pages[page][0] & 0x80; + if (dev->do_page_save && val) + zip_mode_sense_save(dev); - if (pos >= dev->total_length) - break; - } + if (pos >= dev->total_length) + break; + } - if (error) { - zip_buf_free(dev); - zip_invalid_field_pl(dev); - return 0; - } - break; + if (error) { + zip_buf_free(dev); + zip_invalid_field_pl(dev); + return 0; + } + break; } zip_command_stop((scsi_common_t *) dev); return 1; } - /* Peform a master init on the entire module. */ void zip_global_init(void) @@ -2234,77 +2180,72 @@ zip_global_init(void) memset(zip_drives, 0x00, sizeof(zip_drives)); } - static int zip_get_max(int ide_has_dma, int type) { int ret; - switch(type) { - case TYPE_PIO: - ret = ide_has_dma ? 3 : 0; - break; - case TYPE_SDMA: - default: - ret = -1; - break; - case TYPE_MDMA: - ret = ide_has_dma ? 1 : -1; - break; - case TYPE_UDMA: - ret = ide_has_dma ? 5 : -1; - break; + switch (type) { + case TYPE_PIO: + ret = ide_has_dma ? 3 : 0; + break; + case TYPE_SDMA: + default: + ret = -1; + break; + case TYPE_MDMA: + ret = ide_has_dma ? 1 : -1; + break; + case TYPE_UDMA: + ret = ide_has_dma ? 5 : -1; + break; } return ret; } - static int zip_get_timings(int ide_has_dma, int type) { int ret; - switch(type) { - case TIMINGS_DMA: - ret = ide_has_dma ? 0x96 : 0; - break; - case TIMINGS_PIO: - ret = ide_has_dma ? 0xb4 : 0; - break; - case TIMINGS_PIO_FC: - ret = ide_has_dma ? 0xb4 : 0; - break; - default: - ret = 0; - break; + switch (type) { + case TIMINGS_DMA: + ret = ide_has_dma ? 0x96 : 0; + break; + case TIMINGS_PIO: + ret = ide_has_dma ? 0xb4 : 0; + break; + case TIMINGS_PIO_FC: + ret = ide_has_dma ? 0xb4 : 0; + break; + default: + ret = 0; + break; } return ret; } - static void zip_100_identify(ide_t *ide) { - ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ } - static void zip_250_identify(ide_t *ide, int ide_has_dma) { - ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */ if (ide_has_dma) { - ide->buffer[80] = 0x70; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6*/ - ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ + ide->buffer[80] = 0x70; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6*/ + ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ } } - static void zip_identify(ide_t *ide, int ide_has_dma) { @@ -2318,144 +2259,141 @@ zip_identify(ide_t *ide, int ide_has_dma) as a LS-120. */ ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + ide->buffer[49] = 0x200; /* LBA supported */ + ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ if (zip_drives[zip->id].is_250) - zip_250_identify(ide, ide_has_dma); + zip_250_identify(ide, ide_has_dma); else - zip_100_identify(ide); + zip_100_identify(ide); } - static void zip_drive_reset(int c) { - zip_t *dev; + zip_t *dev; scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; + ide_t *id; + uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; if (!zip_drives[c].priv) { - zip_drives[c].priv = (zip_t *) malloc(sizeof(zip_t)); - memset(zip_drives[c].priv, 0, sizeof(zip_t)); + zip_drives[c].priv = (zip_t *) malloc(sizeof(zip_t)); + memset(zip_drives[c].priv, 0, sizeof(zip_t)); } dev = (zip_t *) zip_drives[c].priv; - dev->id = c; + dev->id = c; dev->cur_lun = SCSI_LUN_USE_CDB; if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - /* SCSI ZIP, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + /* SCSI ZIP, attach to the SCSI bus. */ + sd = &scsi_devices[scsi_bus][scsi_id]; - sd->sc = (scsi_common_t *) dev; - sd->command = zip_command; - sd->request_sense = zip_request_sense_for_scsi; - sd->reset = zip_reset; - sd->phase_data_out = zip_phase_data_out; - sd->command_stop = zip_command_stop; - sd->type = SCSI_REMOVABLE_DISK; + sd->sc = (scsi_common_t *) dev; + sd->command = zip_command; + sd->request_sense = zip_request_sense_for_scsi; + sd->reset = zip_reset; + sd->phase_data_out = zip_phase_data_out; + sd->command_stop = zip_command_stop; + sd->type = SCSI_REMOVABLE_DISK; } else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) { - /* ATAPI CD-ROM, attach to the IDE bus. */ - id = ide_get_drive(zip_drives[c].ide_channel); - /* If the IDE channel is initialized, we attach to it, - otherwise, we do nothing - it's going to be a drive - that's not attached to anything. */ - if (id) { - id->sc = (scsi_common_t *) dev; - id->get_max = zip_get_max; - id->get_timings = zip_get_timings; - id->identify = zip_identify; - id->stop = NULL; - id->packet_command = zip_command; - id->device_reset = zip_reset; - id->phase_data_out = zip_phase_data_out; - id->command_stop = zip_command_stop; - id->bus_master_error = zip_bus_master_error; - id->interrupt_drq = 1; + /* ATAPI CD-ROM, attach to the IDE bus. */ + id = ide_get_drive(zip_drives[c].ide_channel); + /* If the IDE channel is initialized, we attach to it, + otherwise, we do nothing - it's going to be a drive + that's not attached to anything. */ + if (id) { + id->sc = (scsi_common_t *) dev; + id->get_max = zip_get_max; + id->get_timings = zip_get_timings; + id->identify = zip_identify; + id->stop = NULL; + id->packet_command = zip_command; + id->device_reset = zip_reset; + id->phase_data_out = zip_phase_data_out; + id->command_stop = zip_command_stop; + id->bus_master_error = zip_bus_master_error; + id->interrupt_drq = 1; - ide_atapi_attach(id); - } + ide_atapi_attach(id); + } } } - void zip_hard_reset(void) { - zip_t *dev; - int c; + zip_t *dev; + int c; uint8_t scsi_id, scsi_bus; for (c = 0; c < ZIP_NUM; c++) { - if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) || (zip_drives[c].bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP hard_reset drive=%d\n", c); + if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) || (zip_drives[c].bus_type == ZIP_BUS_SCSI)) { + zip_log("ZIP hard_reset drive=%d\n", c); - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = zip_drives[c].scsi_device_id & 0x0f; + if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; + scsi_id = zip_drives[c].scsi_device_id & 0x0f; - /* Make sure to ignore any SCSI ZIP drive that has an out of range SCSI bus. */ - if (scsi_bus >= SCSI_BUS_MAX) - continue; + /* Make sure to ignore any SCSI ZIP drive that has an out of range SCSI bus. */ + if (scsi_bus >= SCSI_BUS_MAX) + continue; - /* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */ - if (scsi_id >= SCSI_ID_MAX) - continue; - } + /* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */ + if (scsi_id >= SCSI_ID_MAX) + continue; + } - /* Make sure to ignore any ATAPI ZIP drive that has an out of range IDE channel. */ - if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].ide_channel > 7)) - continue; + /* Make sure to ignore any ATAPI ZIP drive that has an out of range IDE channel. */ + if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].ide_channel > 7)) + continue; - zip_drive_reset(c); + zip_drive_reset(c); - dev = (zip_t *) zip_drives[c].priv; + dev = (zip_t *) zip_drives[c].priv; - dev->id = c; - dev->drv = &zip_drives[c]; + dev->id = c; + dev->drv = &zip_drives[c]; - zip_init(dev); + zip_init(dev); - if (strlen(zip_drives[c].image_path)) - zip_load(dev, zip_drives[c].image_path); + if (strlen(zip_drives[c].image_path)) + zip_load(dev, zip_drives[c].image_path); - zip_mode_sense_load(dev); + zip_mode_sense_load(dev); - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) - zip_log("SCSI ZIP drive %i attached to SCSI ID %i\n", c, zip_drives[c].scsi_device_id); - else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) - zip_log("ATAPI ZIP drive %i attached to IDE channel %i\n", c, zip_drives[c].ide_channel); - } + if (zip_drives[c].bus_type == ZIP_BUS_SCSI) + zip_log("SCSI ZIP drive %i attached to SCSI ID %i\n", c, zip_drives[c].scsi_device_id); + else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) + zip_log("ATAPI ZIP drive %i attached to IDE channel %i\n", c, zip_drives[c].ide_channel); + } } } - void zip_close(void) { - zip_t *dev; - int c; + zip_t *dev; + int c; uint8_t scsi_bus, scsi_id; for (c = 0; c < ZIP_NUM; c++) { - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = zip_drives[c].scsi_device_id & 0x0f; + if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; + scsi_id = zip_drives[c].scsi_device_id & 0x0f; - memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); - } + memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); + } - dev = (zip_t *) zip_drives[c].priv; + dev = (zip_t *) zip_drives[c].priv; - if (dev) { - zip_disk_unload(dev); + if (dev) { + zip_disk_unload(dev); - free(dev); - zip_drives[c].priv = NULL; - } + free(dev); + zip_drives[c].priv = NULL; + } } }