--- np2/cbus/ideio.c 2004/08/04 15:04:51 1.4 +++ np2/cbus/ideio.c 2005/03/05 06:02:28 1.10 @@ -33,30 +33,32 @@ static IDEDEV getidedev(void) { static IDEDRV getidedrv(void) { IDEDEV dev; + IDEDRV drv; dev = getidedev(); if (dev) { - return(dev->drv + dev->drivesel); - } - else { - return(NULL); + drv = dev->drv + dev->drivesel; + if (drv->device != IDETYPE_NONE) { + return(drv); + } } + return(NULL); } static const char serial[] = "824919341192 "; static const char firm[] = "A5U.1200"; static const char model[] = "QUANTUM FIREBALL CR "; -static BOOL setidentify(IDEDRV drv) { +static BRESULT setidentify(IDEDRV drv) { SXSIDEV sxsi; UINT16 tmp[256]; - BYTE *p; + UINT8 *p; UINT i; UINT32 size; sxsi = sxsi_getptr(drv->sxsidrv); - if ((sxsi == NULL) || (sxsi->fname[0] == '\0')) { + if ((sxsi == NULL) || (!(sxsi->flag & SXSIFLAG_READY))) { return(FAILURE); } @@ -77,7 +79,9 @@ static BOOL setidentify(IDEDRV drv) { for (i=0; i<20; i++) { tmp[27+i] = (model[i*2] << 8) + model[i*2+1]; } - tmp[47] = 0x00; // multiple +#if IDEIO_MULTIPLE_MAX > 0 + tmp[47] = 0x8000 | IDEIO_MULTIPLE_MAX; // multiple +#endif tmp[49] = 0x0000; // LBA(1 << 9) tmp[51] = 0x0200; tmp[53] = 0x0001; @@ -87,18 +91,21 @@ static BOOL setidentify(IDEDRV drv) { size = sxsi->cylinders * sxsi->surfaces * sxsi->sectors; tmp[57] = (UINT16)size; tmp[58] = (UINT16)(size >> 16); -// tmp[59] = 0; +#if IDEIO_MULTIPLE_MAX > 0 + tmp[59] = 0x0100 | drv->mulmode; // current multiple mode +#endif tmp[60] = (UINT16)size; tmp[61] = (UINT16)(size >> 16); - tmp[63] = 0; // multi word DMA + tmp[63] = 0x0000; // no support multiword DMA - tmp[80] = 0x0006; // support ATA-1/2 + tmp[80] = 0x0006; // only support ATA-1/2 tmp[81] = 0; + tmp[82] = 0x0000; // DEVICE RESET(1 << 9) p = drv->buf; for (i=0; i<256; i++) { - p[0] = (BYTE)tmp[i]; - p[1] = (BYTE)(tmp[i] >> 8); + p[0] = (UINT8)tmp[i]; + p[1] = (UINT8)(tmp[i] >> 8); p += 2; } drv->bufdir = IDEDIR_IN; @@ -118,6 +125,7 @@ static void setintr(IDEDRV drv) { static void cmdabort(IDEDRV drv) { + TRACEOUT(("ideio: cmdabort()")); drv->status = IDESTAT_DRDY | IDESTAT_ERR; drv->error = IDEERR_ABRT; setintr(drv); @@ -168,7 +176,7 @@ static void incsec(IDEDRV drv) { } } -static long getcursec(const _IDEDRV *drv) { +static long getcursec(const IDEDRV drv) { long ret; @@ -196,7 +204,8 @@ static void readsec(IDEDRV drv) { goto read_err; } sec = getcursec(drv); - TRACEOUT(("readsec->drv %d sec %x", drv->sxsidrv, sec)); + TRACEOUT(("readsec->drv %d sec %x cnt %d thr %d", + drv->sxsidrv, sec, drv->mulcnt, drv->multhr)); if (sxsi_read(drv->sxsidrv, sec, drv->buf, 512)) { TRACEOUT(("read error!")); goto read_err; @@ -205,9 +214,12 @@ static void readsec(IDEDRV drv) { drv->bufpos = 0; drv->bufsize = 512; - drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ; - drv->error = 0; - setintr(drv); + if ((drv->mulcnt & (drv->multhr - 1)) == 0) { + drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ; + drv->error = 0; + setintr(drv); + } + drv->mulcnt++; return; read_err: @@ -251,17 +263,20 @@ static void IOOUTCALL ideio_o642(UINT po drv->wp = dat; TRACEOUT(("ideio set WP %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); } + (void)port; } static void IOOUTCALL ideio_o644(UINT port, REG8 dat) { IDEDRV drv; + (void)port; drv = getidedrv(); if (drv) { drv->sc = dat; TRACEOUT(("ideio set SC %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); } + (void)port; } static void IOOUTCALL ideio_o646(UINT port, REG8 dat) { @@ -273,6 +288,7 @@ static void IOOUTCALL ideio_o646(UINT po drv->sn = dat; TRACEOUT(("ideio set SN %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); } + (void)port; } static void IOOUTCALL ideio_o648(UINT port, REG8 dat) { @@ -285,6 +301,7 @@ static void IOOUTCALL ideio_o648(UINT po drv->cy |= dat; TRACEOUT(("ideio set CYL %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); } + (void)port; } static void IOOUTCALL ideio_o64a(UINT port, REG8 dat) { @@ -297,6 +314,7 @@ static void IOOUTCALL ideio_o64a(UINT po drv->cy |= dat << 8; TRACEOUT(("ideio set CYH %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); } + (void)port; } static void IOOUTCALL ideio_o64c(UINT port, REG8 dat) { @@ -318,11 +336,48 @@ static void IOOUTCALL ideio_o64c(UINT po dev->drv[drvnum].dr = dat & 0xf0; dev->drv[drvnum].hd = dat & 0x0f; TRACEOUT(("ideio set DRHD %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); + (void)port; } static void IOOUTCALL ideio_o64e(UINT port, REG8 dat) { IDEDRV drv; + IDEDEV dev; + + // execute device diagnostic + if (dat == 0x90) { + TRACEOUT(("ideio set cmd %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); + TRACEOUT(("ideio: execute device diagnostic")); + dev = getidedev(); + if (dev) { + IDEDRV d; + int i; + + for (i = 0; i < 2; i++) { + d = dev->drv + i; + d->hd = 0x00; + d->sc = 0x01; + d->sn = 0x01; + d->cy = 0x0000; + d->status = IDESTAT_DRDY; + d->error = 0x01; + if (i == 0) { + if (dev->drv[0].device == IDETYPE_NONE) { + d->error = 0x00; + } + if (dev->drv[1].device == IDETYPE_NONE) { + d->error |= 0x80; + } + } + else { + if (dev->drv[1].device == IDETYPE_NONE) { + d->error = 0x00; + } + } + } + } + return; + } drv = getidedrv(); if (drv == NULL) { @@ -331,21 +386,50 @@ static void IOOUTCALL ideio_o64e(UINT po drv->cmd = dat; TRACEOUT(("ideio set cmd %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); switch(dat) { - case 0x08: // atapi reset - if (drv->device == IDETYPE_CDROM) { - drv->hd = 0; - drv->sc = 1; - drv->sn = 1; + case 0x08: // device reset + TRACEOUT(("ideio: device reset")); + if (drv->device == IDETYPE_NONE) { + cmdabort(drv); + break; + } + else if (drv->device == IDETYPE_HDD) { + drv->hd = 0x00; + drv->sc = 0x01; + drv->sn = 0x01; + drv->cy = 0x0000; + } + else if (drv->device == IDETYPE_CDROM) { + drv->hd = 0x10; + drv->sc = 0x01; + drv->sn = 0x01; drv->cy = 0xeb14; - drv->status = 0; - drv->error = 0; } + drv->status = 0x00; + drv->error = 0x01; + dev = getidedev(); + if (dev) { + if (dev->drivesel == 0) { + if (dev->drv[0].device == IDETYPE_NONE) { + drv->error = 0x00; + } + if (dev->drv[1].device == IDETYPE_NONE) { + drv->error |= 0x80; + } + } + else { + if (dev->drv[1].device == IDETYPE_NONE) { + drv->error = 0x00; + } + } + } + setintr(drv); break; case 0x10: // calibrate // case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: // case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: // case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + TRACEOUT(("ideio: calibrate")); if (drv->device) { drv->status = IDESTAT_DRDY | IDESTAT_DSC; drv->error = 0; @@ -359,13 +443,16 @@ static void IOOUTCALL ideio_o64e(UINT po case 0x20: // read (with retry) case 0x21: // read + TRACEOUT(("ideio: read sector")); + drv->mulcnt = 0; + drv->multhr = 1; readsec(drv); break; case 0x91: // set parameters TRACEOUT(("ideio: set parameters dh=%x sec=%x", drv->dr | drv->hd, drv->sc)); - if (drv->device) { + if (drv->device != IDETYPE_NONE) { drv->surfaces = drv->hd + 1; drv->sectors = drv->sc; drv->status &= ~(IDESTAT_BSY | IDESTAT_DRQ | IDESTAT_ERR); @@ -404,10 +491,45 @@ static void IOOUTCALL ideio_o64e(UINT po } break; + case 0xc4: // read multiple +#if IDEIO_MULTIPLE_MAX > 0 + TRACEOUT(("ideio: read multiple")); + drv->mulcnt = 0; + drv->multhr = drv->mulmode; + readsec(drv); +#else + cmdabort(drv); +#endif + break; + + case 0xc6: // set multiple mode + TRACEOUT(("ideio: set multiple mode")); + switch(drv->sc) { +#if IDEIO_MULTIPLE_MAX > 0 + case 2: case 4: case 8: case 16: case 32: case 64: case 128: + if (drv->sc <= IDEIO_MULTIPLE_MAX) { + drv->mulmode = drv->sc; + setintr(drv); + break; + } + /*FALLTHROUGH*/ +#endif + default: + cmdabort(drv); + break; + } + break; + + case 0xef: // set features + TRACEOUT(("ideio: set features reg = %.2x", drv->wp)); + cmdabort(drv); + break; + default: - panic("command:%.2x", dat); + panic("ideio: unknown command %.2x", dat); break; } + (void)port; } static void IOOUTCALL ideio_o74c(UINT port, REG8 dat) { @@ -440,13 +562,16 @@ static void IOOUTCALL ideio_o74c(UINT po } } } - TRACEOUT(("ideio interrupt %sable", (dat & IDECTRL_NIEN) ? "di" : "en")); - TRACEOUT(("ideio devctrl %.4x,%.2x [%.4x:%.8x]", port, dat, CPU_CS, CPU_EIP)); + TRACEOUT(("ideio interrupt %sable", (dat & IDECTRL_NIEN) ? "dis" : "en")); + TRACEOUT(("ideio devctrl %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP)); + (void)port; } static void IOOUTCALL ideio_o74e(UINT port, REG8 dat) { TRACEOUT(("ideio %.4x,%.2x [%.4x:%.8x]", port, dat, CPU_CS, CPU_EIP)); + (void)port; + (void)dat; } @@ -456,6 +581,8 @@ static REG8 IOINPCALL ideio_i642(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { drv->status &= ~IDESTAT_ERR; @@ -472,6 +599,8 @@ static REG8 IOINPCALL ideio_i644(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio get SC %.2x [%.4x:%.8x]", drv->sc, CPU_CS, CPU_EIP)); @@ -486,6 +615,8 @@ static REG8 IOINPCALL ideio_i646(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio get SN %.2x [%.4x:%.8x]", drv->sn, CPU_CS, CPU_EIP)); @@ -500,6 +631,8 @@ static REG8 IOINPCALL ideio_i648(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio get CYL %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP)); @@ -514,6 +647,8 @@ static REG8 IOINPCALL ideio_i64a(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio get CYH %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP)); @@ -529,6 +664,8 @@ static REG8 IOINPCALL ideio_i64c(UINT po IDEDRV drv; REG8 ret; + (void)port; + drv = getidedrv(); if (drv) { ret = drv->dr | drv->hd; @@ -544,6 +681,8 @@ static REG8 IOINPCALL ideio_i64e(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio status %.2x [%.4x:%.8x]", @@ -563,6 +702,8 @@ static REG8 IOINPCALL ideio_i74c(UINT po IDEDRV drv; + (void)port; + drv = getidedrv(); if (drv) { TRACEOUT(("ideio alt status %.2x [%.4x:%.8x]", @@ -580,14 +721,14 @@ static REG8 IOINPCALL ideio_i74c(UINT po void IOOUTCALL ideio_w16(UINT port, REG16 value) { IDEDRV drv; - BYTE *p; + UINT8 *p; drv = getidedrv(); if ((drv != NULL) && (drv->status & IDESTAT_DRQ) && (drv->bufdir == IDEDIR_OUT)) { p = drv->buf + drv->bufpos; - p[0] = (BYTE)value; - p[1] = (BYTE)(value >> 8); + p[0] = (UINT8)value; + p[1] = (UINT8)(value >> 8); TRACEOUT(("ide-data send %4x (%.4x) [%.4x:%.8x]", value, drv->bufpos, CPU_CS, CPU_EIP)); drv->bufpos += 2; @@ -600,13 +741,16 @@ void IOOUTCALL ideio_w16(UINT port, REG1 } } } + (void)port; } REG16 IOINPCALL ideio_r16(UINT port) { IDEDRV drv; REG16 ret; - BYTE *p; + UINT8 *p; + + (void)port; drv = getidedrv(); if (drv == NULL) { @@ -616,7 +760,7 @@ REG16 IOINPCALL ideio_r16(UINT port) { if ((drv->status & IDESTAT_DRQ) && (drv->bufdir == IDEDIR_IN)) { p = drv->buf + drv->bufpos; ret = p[0] + (p[1] << 8); - TRACEOUT(("ide-data recv %4x (%.4x) [%.4x:%.8x]", + TRACEOUT(("ide-data recv %.4x (%.4x) [%.4x:%.8x]", ret, drv->bufpos, CPU_CS, CPU_EIP)); drv->bufpos += 2; if (drv->bufpos >= drv->bufsize) { @@ -624,6 +768,7 @@ REG16 IOINPCALL ideio_r16(UINT port) { switch(drv->cmd) { case 0x20: case 0x21: + case 0xc4: incsec(drv); drv->sc--; if (drv->sc) { @@ -652,18 +797,21 @@ static void devinit(IDEDRV drv, REG8 sxs SXSIDEV sxsi; ZeroMemory(drv, sizeof(_IDEDRV)); + drv->sxsidrv = sxsidrv; sxsi = sxsi_getptr(sxsidrv); - if ((sxsi != NULL) && (sxsi->fname[0] != '\0')) { - drv->sxsidrv = sxsidrv; + if ((sxsi != NULL) && + (sxsi->devtype == SXSIDEV_HDD) && (sxsi->flag & SXSIFLAG_READY)) { drv->status = IDESTAT_DRDY | IDESTAT_DSC; drv->error = IDEERR_AMNF; drv->device = IDETYPE_HDD; drv->surfaces = sxsi->surfaces; drv->sectors = sxsi->sectors; + drv->mulmode = 1; } else { drv->status = IDESTAT_ERR; drv->error = IDEERR_TR0; + drv->device = IDETYPE_NONE; } } @@ -689,18 +837,6 @@ void ideio_reset(void) { drv->device = IDETYPE_CDROM; #endif -#if 0 - ideio.dev[0].drv[0].status = IDE_READY | IDE_SEEKCOMPLETE; - ideio.dev[0].drv[0].error = 1; - ideio.dev[1].drv[0].status = IDE_READY | IDE_SEEKCOMPLETE; - ideio.dev[1].drv[0].error = 1; - - ideio.dev[0].drv[0].sxsidrv = 0x00; - ideio.dev[0].drv[1].sxsidrv = 0x01; - ideio.dev[1].drv[0].sxsidrv = 0x02; - ideio.dev[1].drv[1].sxsidrv = 0x03; -#endif - CopyMemory(mem + 0xd0000, idebios, sizeof(idebios)); TRACEOUT(("use simulate ide.rom")); } @@ -733,5 +869,11 @@ void ideio_bind(void) { iocore_attachinp(0x074c, ideio_i74c); } } -#endif +void ideio_notify(REG8 sxsidrv, UINT action) { + + (void)sxsidrv; + (void)action; +} + +#endif /* SUPPORT_IDEIO */