Diff for /np2/cbus/ideio.c between versions 1.4 and 1.15

version 1.4, 2004/08/04 15:04:51 version 1.15, 2007/11/03 00:00:19
Line 11 Line 11
 #include        "ideio.h"  #include        "ideio.h"
 #include        "atapicmd.h"  #include        "atapicmd.h"
 #include        "sxsi.h"  #include        "sxsi.h"
   #include        "sound.h"
 #include        "idebios.res"  #include        "idebios.res"
   
   
Line 33  static IDEDEV getidedev(void) { Line 34  static IDEDEV getidedev(void) {
 static IDEDRV getidedrv(void) {  static IDEDRV getidedrv(void) {
   
         IDEDEV  dev;          IDEDEV  dev;
           IDEDRV  drv;
   
         dev = getidedev();          dev = getidedev();
         if (dev) {          if (dev) {
                 return(dev->drv + dev->drivesel);                  drv = dev->drv + dev->drivesel;
         }                  if (drv->device != IDETYPE_NONE) {
         else {                          return(drv);
                 return(NULL);                  }
         }          }
           return(NULL);
 }  }
   
 static const char serial[] = "824919341192        ";  static const char serial[] = "824919341192        ";
 static const char firm[] = "A5U.1200";  static const char firm[] = "A5U.1200";
 static const char model[] = "QUANTUM FIREBALL CR                     ";  static const char model[] = "QUANTUM FIREBALL CR                     ";
   
 static BOOL setidentify(IDEDRV drv) {  static const char cdrom_serial[] = "1.0                 ";
   static const char cdrom_firm[]   = "        ";
   static const char cdrom_model[]  = "NEC CD-ROM DRIVE                        ";
   
   static BRESULT setidentify(IDEDRV drv) {
   
         SXSIDEV sxsi;          SXSIDEV sxsi;
         UINT16  tmp[256];          UINT16  tmp[256];
         BYTE    *p;          UINT8   *p;
         UINT    i;          UINT    i;
         UINT32  size;          UINT32  size;
   
         sxsi = sxsi_getptr(drv->sxsidrv);          sxsi = sxsi_getptr(drv->sxsidrv);
         if ((sxsi == NULL) || (sxsi->fname[0] == '\0')) {          if ((sxsi == NULL) || (!(sxsi->flag & SXSIFLAG_READY))) {
                 return(FAILURE);                  return(FAILURE);
         }          }
   
         ZeroMemory(tmp, sizeof(tmp));          ZeroMemory(tmp, sizeof(tmp));
         // とりあえず使ってる部分だけ          // とりあえず使ってる部分だけ
         tmp[0] = 0x0040;          if (drv->device == IDETYPE_HDD) {
         tmp[1] = sxsi->cylinders;                  tmp[0] = 0x0040;                // non removable device
         tmp[3] = sxsi->surfaces;                  tmp[1] = sxsi->cylinders;
         tmp[4] = sxsi->sectors * 512;                  tmp[3] = sxsi->surfaces;
         tmp[6] = sxsi->sectors;                  tmp[4] = sxsi->sectors * 512;
         for (i=0; i<10; i++) {                  tmp[6] = sxsi->sectors;
                 tmp[10+i] = (serial[i*2] << 8) + serial[i*2+1];                  for (i=0; i<10; i++) {
         }                          tmp[10+i] = (serial[i*2] << 8) + serial[i*2+1];
         tmp[22] = 4;                  }
         for (i=0; i<4; i++) {                  tmp[22] = 4;
                 tmp[23+i] = (firm[i*2] << 8) + firm[i*2+1];                  for (i=0; i<4; i++) {
         }                          tmp[23+i] = (firm[i*2] << 8) + firm[i*2+1];
         for (i=0; i<20; i++) {                  }
                 tmp[27+i] = (model[i*2] << 8) + model[i*2+1];                  for (i=0; i<20; i++) {
                           tmp[27+i] = (model[i*2] << 8) + model[i*2+1];
                   }
   #if IDEIO_MULTIPLE_MAX > 0
                   tmp[47] = 0x8000 | IDEIO_MULTIPLE_MAX;  // multiple
   #endif
                   tmp[49] = 0x0200;               // support LBA
                   tmp[51] = 0x0200;
                   tmp[53] = 0x0001;
                   tmp[54] = sxsi->cylinders;
                   tmp[55] = sxsi->surfaces;
                   tmp[56] = sxsi->sectors;
                   size = sxsi->cylinders * sxsi->surfaces * sxsi->sectors;
                   tmp[57] = (UINT16)size;
                   tmp[58] = (UINT16)(size >> 16);
   #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] = 0x0000;               // no support multiword DMA
   
                   tmp[80] = 0x0006;               // only support ATA-1/2
                   tmp[81] = 0;
                   tmp[82] = 0x0200;               // support DEVICE RESET
           }
           else if (drv->device == IDETYPE_CDROM) {
                   tmp[0] = 0x8580;                // ATAPI,CD-ROM,removable,12bytes PACKET
                   for (i=0; i<10; i++) {
                           tmp[10+i] = (cdrom_serial[i*2] << 8) + cdrom_serial[i*2+1];
                   }
                   for (i=0; i<4; i++) {
                           tmp[23+i] = (cdrom_firm[i*2] << 8) + cdrom_firm[i*2+1];
                   }
                   for (i=0; i<20; i++) {
                           tmp[27+i] = (cdrom_model[i*2] << 8) + cdrom_model[i*2+1];
                   }
                   tmp[49] = 0x0200;               // support LBA
                   tmp[53] = 0x0001;
                   tmp[63] = 0x0000;               // no support multiword DMA
                   tmp[80] = 0x000e;               // only support ATA-1/2
                   tmp[82] = 0x0210;               // support PACKET/DEVICE RESET
                   tmp[126] = 0x0000;              // ATAPI byte count
         }          }
         tmp[47] = 0x00;                         // multiple  
         tmp[49] = 0x0000;                       // LBA(1 << 9)  
         tmp[51] = 0x0200;  
         tmp[53] = 0x0001;  
         tmp[54] = sxsi->cylinders;  
         tmp[55] = sxsi->surfaces;  
         tmp[56] = sxsi->sectors;  
         size = sxsi->cylinders * sxsi->surfaces * sxsi->sectors;  
         tmp[57] = (UINT16)size;  
         tmp[58] = (UINT16)(size >> 16);  
 //      tmp[59] = 0;  
         tmp[60] = (UINT16)size;  
         tmp[61] = (UINT16)(size >> 16);  
         tmp[63] = 0;                            // multi word DMA  
   
         tmp[80] = 0x0006;                       // support ATA-1/2  
         tmp[81] = 0;  
   
         p = drv->buf;          p = drv->buf;
         for (i=0; i<256; i++) {          for (i=0; i<256; i++) {
                 p[0] = (BYTE)tmp[i];                  p[0] = (UINT8)tmp[i];
                 p[1] = (BYTE)(tmp[i] >> 8);                  p[1] = (UINT8)(tmp[i] >> 8);
                 p += 2;                  p += 2;
         }          }
         drv->bufdir = IDEDIR_IN;          drv->bufdir = IDEDIR_IN;
           drv->buftc = IDETC_TRANSFEREND;
         drv->bufpos = 0;          drv->bufpos = 0;
         drv->bufsize = 512;          drv->bufsize = 512;
         return(SUCCESS);          return(SUCCESS);
Line 118  static void setintr(IDEDRV drv) { Line 151  static void setintr(IDEDRV drv) {
   
 static void cmdabort(IDEDRV drv) {  static void cmdabort(IDEDRV drv) {
   
           TRACEOUT(("ideio: cmdabort()"));
         drv->status = IDESTAT_DRDY | IDESTAT_ERR;          drv->status = IDESTAT_DRDY | IDESTAT_ERR;
         drv->error = IDEERR_ABRT;          drv->error = IDEERR_ABRT;
         setintr(drv);          setintr(drv);
 }  }
   
   static void drvreset(IDEDRV drv) {
   
           if (drv->device == IDETYPE_CDROM) {
                   drv->hd = 0x10;
                   drv->sc = 0x01;
                   drv->sn = 0x01;
                   drv->cy = 0xeb14;
                   drv->status = 0;
           }
           else {
                   drv->hd = 0x00;
                   drv->sc = 0x01;
                   drv->sn = 0x01;
                   drv->cy = 0x0000;
                   drv->status = IDESTAT_DRDY;
           }
   }
   
 static void panic(const char *str, ...) {  static void panic(const char *str, ...) {
   
         char    buf[2048];          char    buf[2048];
Line 155  static void incsec(IDEDRV drv) { Line 207  static void incsec(IDEDRV drv) {
                 drv->cy++;                  drv->cy++;
         }          }
         else {          else {
                 TRACEOUT(("ideio: incsec() LBA mode?"));  
                 drv->sn++;                  drv->sn++;
                 if (drv->sn) {                  if (drv->sn) {
                         return;                          return;
Line 168  static void incsec(IDEDRV drv) { Line 219  static void incsec(IDEDRV drv) {
         }          }
 }  }
   
 static long getcursec(const _IDEDRV *drv) {  static long getcursec(const IDEDRV drv) {
   
         long    ret;          long    ret;
   
Line 180  static long getcursec(const _IDEDRV *drv Line 231  static long getcursec(const _IDEDRV *drv
                 ret += (drv->sn - 1);                  ret += (drv->sn - 1);
         }          }
         else {          else {
                 TRACEOUT(("ideio: getcursec() LBA mode?"));  
                 ret = drv->sn;                  ret = drv->sn;
                 ret |= (drv->cy << 8);                  ret |= (drv->cy << 8);
                 ret |= (drv->hd << 24);                  ret |= (drv->hd << 24);
Line 192  static void readsec(IDEDRV drv) { Line 242  static void readsec(IDEDRV drv) {
   
         long    sec;          long    sec;
   
         if (!drv->device) {          if (drv->device != IDETYPE_HDD) {
                 goto read_err;                  goto read_err;
         }          }
         sec = getcursec(drv);          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)) {          if (sxsi_read(drv->sxsidrv, sec, drv->buf, 512)) {
                 TRACEOUT(("read error!"));                  TRACEOUT(("read error!"));
                 goto read_err;                  goto read_err;
         }          }
         drv->bufdir = IDEDIR_IN;          drv->bufdir = IDEDIR_IN;
           drv->buftc = IDETC_TRANSFEREND;
         drv->bufpos = 0;          drv->bufpos = 0;
         drv->bufsize = 512;          drv->bufsize = 512;
   
         drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;          if ((drv->mulcnt & (drv->multhr - 1)) == 0) {
         drv->error = 0;                  drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;
         setintr(drv);                  drv->error = 0;
                   setintr(drv);
           }
           drv->mulcnt++;
         return;          return;
   
 read_err:  read_err:
         cmdabort(drv);          cmdabort(drv);
 }  }
   
   static void writesec(IDEDRV drv) {
   
           if (drv->device == IDETYPE_NONE) {
                   goto write_err;
           }
   
           drv->bufdir = IDEDIR_OUT;
           drv->buftc = IDETC_TRANSFEREND;
           drv->bufpos = 0;
           drv->bufsize = 512;
   
           if ((drv->mulcnt & (drv->multhr - 1)) == 0) {
                   drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;
                   drv->error = 0;
                   setintr(drv);
           }
           return;
   
   write_err:
           cmdabort(drv);
   }
   
   
 // ----  // ----
   
Line 251  static void IOOUTCALL ideio_o642(UINT po Line 328  static void IOOUTCALL ideio_o642(UINT po
                 drv->wp = dat;                  drv->wp = dat;
                 TRACEOUT(("ideio set WP %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio set WP %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o644(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o644(UINT port, REG8 dat) {
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 drv->sc = dat;                  drv->sc = dat;
                 TRACEOUT(("ideio set SC %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio set SC %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o646(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o646(UINT port, REG8 dat) {
Line 273  static void IOOUTCALL ideio_o646(UINT po Line 353  static void IOOUTCALL ideio_o646(UINT po
                 drv->sn = dat;                  drv->sn = dat;
                 TRACEOUT(("ideio set SN %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio set SN %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o648(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o648(UINT port, REG8 dat) {
Line 285  static void IOOUTCALL ideio_o648(UINT po Line 366  static void IOOUTCALL ideio_o648(UINT po
                 drv->cy |= dat;                  drv->cy |= dat;
                 TRACEOUT(("ideio set CYL %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio set CYL %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o64a(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o64a(UINT port, REG8 dat) {
Line 297  static void IOOUTCALL ideio_o64a(UINT po Line 379  static void IOOUTCALL ideio_o64a(UINT po
                 drv->cy |= dat << 8;                  drv->cy |= dat << 8;
                 TRACEOUT(("ideio set CYH %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio set CYH %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o64c(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o64c(UINT port, REG8 dat) {
Line 318  static void IOOUTCALL ideio_o64c(UINT po Line 401  static void IOOUTCALL ideio_o64c(UINT po
         dev->drv[drvnum].dr = dat & 0xf0;          dev->drv[drvnum].dr = dat & 0xf0;
         dev->drv[drvnum].hd = dat & 0x0f;          dev->drv[drvnum].hd = dat & 0x0f;
         TRACEOUT(("ideio set DRHD %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));          TRACEOUT(("ideio set DRHD %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o64e(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o64e(UINT port, REG8 dat) {
   
         IDEDRV  drv;          IDEDRV  drv, d;
           IDEDEV  dev;
           int             i;
   
           // 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) {
                           for (i = 0; i < 2; i++) {
                                   d = dev->drv + i;
                                   drvreset(d);
                                   d->error = 0x01;
                                   if (dev->drv[i].device == IDETYPE_NONE) {
                                           d->error = 0x00;
                                   }
                                   if (i == 0) {
                                           if (dev->drv[1].device == IDETYPE_NONE) {
                                                   d->error |= 0x80;
                                           }
                                   }
                           }
                   }
                   return;
           }
   
         drv = getidedrv();          drv = getidedrv();
         if (drv == NULL) {          if (drv == NULL) {
Line 331  static void IOOUTCALL ideio_o64e(UINT po Line 440  static void IOOUTCALL ideio_o64e(UINT po
         drv->cmd = dat;          drv->cmd = dat;
         TRACEOUT(("ideio set cmd %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));          TRACEOUT(("ideio set cmd %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
         switch(dat) {          switch(dat) {
                 case 0x08:              // atapi reset                  case 0x08:              // device reset
                         if (drv->device == IDETYPE_CDROM) {                          TRACEOUT(("ideio: device reset"));
                                 drv->hd = 0;                          drvreset(drv);
                                 drv->sc = 1;                          drv->error = 0x01;
                                 drv->sn = 1;                          dev = getidedev();
                                 drv->cy = 0xeb14;                          if (dev) {
                                 drv->status = 0;                                  if (dev->drv[dev->drivesel].device == IDETYPE_NONE) {
                                 drv->error = 0;                                          drv->error = 0x00;
                                   }
                                   if (dev->drivesel == 0) {
                                           if (dev->drv[1].device == IDETYPE_NONE) {
                                                   drv->error |= 0x80;
                                           }
                                   }
                         }                          }
                           setintr(drv);
                         break;                          break;
   
                 case 0x10:              // calibrate                  case 0x10: case 0x11: case 0x12: case 0x13:     // recalibrate
 //              case 0x11: case 0x12: case 0x13: case 0x14: case 0x15:                  case 0x14: case 0x15: case 0x16: case 0x17:
 //              case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a:                  case 0x18: case 0x19: case 0x1a: case 0x1b:
 //              case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:                  case 0x1c: case 0x1d: case 0x1e: case 0x1f:
                         if (drv->device) {                          TRACEOUT(("ideio: recalibrate"));
                           if (drv->device == IDETYPE_HDD) {
                                   drv->hd = 0x00;
                                   drv->sc = 0x00;
                                   drv->cy = 0x0000;
                                   if (!(drv->dr & IDEDEV_LBA)) {
                                           drv->sn = 0x01;
                                   }
                                   else {
                                           drv->sn = 0x00;
                                   }
                                 drv->status = IDESTAT_DRDY | IDESTAT_DSC;                                  drv->status = IDESTAT_DRDY | IDESTAT_DSC;
                                 drv->error = 0;                                  drv->error = 0;
                                   setintr(drv);
                         }                          }
                         else {                          else {
                                 drv->status = IDESTAT_DRDY | IDESTAT_ERR;                                  cmdabort(drv);
                                 drv->error = IDEERR_TR0;  
                         }                          }
                         setintr(drv);  
                         break;                          break;
   
                 case 0x20:              // read (with retry)                  case 0x20:              // read (with retry)
                 case 0x21:              // read                  case 0x21:              // read
                         readsec(drv);                          TRACEOUT(("ideio: read sector"));
                           if (drv->device == IDETYPE_HDD) {
                                   drv->mulcnt = 0;
                                   drv->multhr = 1;
                                   readsec(drv);
                           }
                           else {
                                   cmdabort(drv);
                           }
                           break;
   
                   case 0x30:              // write (with retry)
                   case 0x31:              // write
                           TRACEOUT(("ideio: write sector"));
                           if (drv->device == IDETYPE_HDD) {
                                   drv->mulcnt = 0;
                                   drv->multhr = 1;
                                   writesec(drv);
                           }
                           else {
                                   cmdabort(drv);
                           }
                         break;                          break;
   
                 case 0x91:              // set parameters                  case 0x91:              // set parameters
                         TRACEOUT(("ideio: set parameters dh=%x sec=%x",                          TRACEOUT(("ideio: set parameters dh=%x sec=%x",
                                                                                         drv->dr | drv->hd, drv->sc));                                                                                          drv->dr | drv->hd, drv->sc));
                         if (drv->device) {                          if (drv->device == IDETYPE_HDD) {
                                 drv->surfaces = drv->hd + 1;                                  drv->surfaces = drv->hd + 1;
                                 drv->sectors = drv->sc;                                  drv->sectors = drv->sc;
                                 drv->status &= ~(IDESTAT_BSY | IDESTAT_DRQ | IDESTAT_ERR);                                  drv->status &= ~(IDESTAT_BSY | IDESTAT_DRQ | IDESTAT_ERR);
Line 378  static void IOOUTCALL ideio_o64e(UINT po Line 524  static void IOOUTCALL ideio_o64e(UINT po
                         break;                          break;
   
                 case 0xa0:              // send packet                  case 0xa0:              // send packet
                           TRACEOUT(("ideio: packet"));
                         if (drv->device == IDETYPE_CDROM) {                          if (drv->device == IDETYPE_CDROM) {
                                 drv->status &= ~(IDESTAT_BSY | IDESTAT_DWF | IDESTAT_ERR);                                  drv->sc &= ~(IDEINTR_REL | IDEINTR_IO);
                                   drv->sc |= IDEINTR_CD;
                                   drv->status &= ~(IDESTAT_BSY | IDESTAT_DMRD | IDESTAT_SERV | IDESTAT_CHK);
                                 drv->status |= IDESTAT_DRQ;                                  drv->status |= IDESTAT_DRQ;
                                 drv->error = 0;                                  drv->error = 0;
                                 drv->bufpos = 0;                                  drv->bufpos = 0;
                                 drv->bufsize = 12;                                  drv->bufsize = 12;
                                 drv->bufdir = IDEDIR_OUT;                                  drv->bufdir = IDEDIR_OUT;
                                   drv->buftc = IDETC_TRANSFEREND;
                                   break;
                           }
                           cmdabort(drv);
                           break;
   
                   case 0xa1:              // identify packet device
                           TRACEOUT(("ideio: identify packet device"));
                           if (drv->device == IDETYPE_CDROM && setidentify(drv) == SUCCESS) {
                                   drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;
                                   drv->error = 0;
                                   setintr(drv);
                         }                          }
                         else {                          else {
                                 cmdabort(drv);                                  cmdabort(drv);
                         }                          }
                         break;                          break;
                           break;
   
                   case 0xc4:              // read multiple
                           TRACEOUT(("ideio: read multiple"));
   #if IDEIO_MULTIPLE_MAX > 0
                           if (drv->device == IDETYPE_HDD) {
                                   drv->mulcnt = 0;
                                   drv->multhr = drv->mulmode;
                                   readsec(drv);
                                   break;
                           }
   #endif
                           cmdabort(drv);
                           break;
   
                 case 0xa1:              // identify                  case 0xc5:              // write multiple
                 case 0xec:              // identify                          TRACEOUT(("ideio: write multiple"));
                         TRACEOUT(("ideio: identify"));  #if IDEIO_MULTIPLE_MAX > 0
                         if (setidentify(drv) == SUCCESS) {                          if (drv->device == IDETYPE_HDD) {
                                   drv->mulcnt = 0;
                                   drv->multhr = drv->mulmode;
                                   writesec(drv);
                                   break;
                           }
   #endif
                           cmdabort(drv);
                           break;
   
                   case 0xc6:              // set multiple mode
                           TRACEOUT(("ideio: set multiple mode"));
                           if (drv->device == IDETYPE_HDD) {
                                   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;
                                   }
                           }
                           else {
                                   cmdabort(drv);
                           }
                           break;
   
                   case 0xe7:              // flush cache
                           TRACEOUT(("ideio: flush cache"));
                           drv->status = IDESTAT_DRDY;
                           drv->error = 0;
                           setintr(drv);
                           break;
   
                   case 0xec:              // identify device
                           TRACEOUT(("ideio: identify device"));
                           if (drv->device == IDETYPE_HDD && setidentify(drv) == SUCCESS) {
                                 drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;                                  drv->status = IDESTAT_DRDY | IDESTAT_DSC | IDESTAT_DRQ;
                                 drv->error = 0;                                  drv->error = 0;
                                 setintr(drv);                                  setintr(drv);
Line 404  static void IOOUTCALL ideio_o64e(UINT po Line 621  static void IOOUTCALL ideio_o64e(UINT po
                         }                          }
                         break;                          break;
   
                   case 0xef:              // set features
                           TRACEOUT(("ideio: set features reg = %.2x", drv->wp));
                           cmdabort(drv);
                           break;
   
                 default:                  default:
                         panic("command:%.2x", dat);                          panic("ideio: unknown command %.2x", dat);
                         break;                          break;
         }          }
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o74c(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o74c(UINT port, REG8 dat) {
Line 430  static void IOOUTCALL ideio_o74c(UINT po Line 653  static void IOOUTCALL ideio_o74c(UINT po
                         dev->drv[1].error = 0;                          dev->drv[1].error = 0;
                 }                  }
                 else {                  else {
                         if (dev->drv[0].device) {                          drvreset(&dev->drv[0]);
                           if (dev->drv[0].device == IDETYPE_HDD) {
                                 dev->drv[0].status = IDESTAT_DRDY | IDESTAT_DSC;                                  dev->drv[0].status = IDESTAT_DRDY | IDESTAT_DSC;
                                 dev->drv[0].error = IDEERR_AMNF;                                  dev->drv[0].error = IDEERR_AMNF;
                         }                          }
                         if (dev->drv[1].device) {                          drvreset(&dev->drv[1]);
                           if (dev->drv[1].device == IDETYPE_HDD) {
                                 dev->drv[1].status = IDESTAT_DRDY | IDESTAT_DSC;                                  dev->drv[1].status = IDESTAT_DRDY | IDESTAT_DSC;
                                 dev->drv[1].error = IDEERR_AMNF;                                  dev->drv[1].error = IDEERR_AMNF;
                         }                          }
                 }                  }
         }          }
         TRACEOUT(("ideio interrupt %sable", (dat & IDECTRL_NIEN) ? "di" : "en"));          TRACEOUT(("ideio interrupt %sable", (dat & IDECTRL_NIEN) ? "dis" : "en"));
         TRACEOUT(("ideio devctrl %.4x,%.2x [%.4x:%.8x]", port, dat, CPU_CS, CPU_EIP));          TRACEOUT(("ideio devctrl %.2x [%.4x:%.8x]", dat, CPU_CS, CPU_EIP));
           (void)port;
 }  }
   
 static void IOOUTCALL ideio_o74e(UINT port, REG8 dat) {  static void IOOUTCALL ideio_o74e(UINT port, REG8 dat) {
   
         TRACEOUT(("ideio %.4x,%.2x [%.4x:%.8x]", port, dat, CPU_CS, CPU_EIP));          TRACEOUT(("ideio %.4x,%.2x [%.4x:%.8x]", port, dat, CPU_CS, CPU_EIP));
           (void)port;
           (void)dat;
 }  }
   
   
Line 456  static REG8 IOINPCALL ideio_i642(UINT po Line 684  static REG8 IOINPCALL ideio_i642(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 drv->status &= ~IDESTAT_ERR;                  drv->status &= ~IDESTAT_ERR;
Line 472  static REG8 IOINPCALL ideio_i644(UINT po Line 702  static REG8 IOINPCALL ideio_i644(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio get SC %.2x [%.4x:%.8x]", drv->sc, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio get SC %.2x [%.4x:%.8x]", drv->sc, CPU_CS, CPU_EIP));
Line 486  static REG8 IOINPCALL ideio_i646(UINT po Line 718  static REG8 IOINPCALL ideio_i646(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio get SN %.2x [%.4x:%.8x]", drv->sn, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio get SN %.2x [%.4x:%.8x]", drv->sn, CPU_CS, CPU_EIP));
Line 500  static REG8 IOINPCALL ideio_i648(UINT po Line 734  static REG8 IOINPCALL ideio_i648(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio get CYL %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio get CYL %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP));
Line 514  static REG8 IOINPCALL ideio_i64a(UINT po Line 750  static REG8 IOINPCALL ideio_i64a(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio get CYH %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP));                  TRACEOUT(("ideio get CYH %.4x [%.4x:%.8x]", drv->cy, CPU_CS, CPU_EIP));
Line 529  static REG8 IOINPCALL ideio_i64c(UINT po Line 767  static REG8 IOINPCALL ideio_i64c(UINT po
         IDEDRV  drv;          IDEDRV  drv;
         REG8    ret;          REG8    ret;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 ret = drv->dr | drv->hd;                  ret = drv->dr | drv->hd;
Line 544  static REG8 IOINPCALL ideio_i64e(UINT po Line 784  static REG8 IOINPCALL ideio_i64e(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio status %.2x [%.4x:%.8x]",                  TRACEOUT(("ideio status %.2x [%.4x:%.8x]",
Line 563  static REG8 IOINPCALL ideio_i74c(UINT po Line 805  static REG8 IOINPCALL ideio_i74c(UINT po
   
         IDEDRV  drv;          IDEDRV  drv;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv) {          if (drv) {
                 TRACEOUT(("ideio alt status %.2x [%.4x:%.8x]",                  TRACEOUT(("ideio alt status %.2x [%.4x:%.8x]",
Line 581  void IOOUTCALL ideio_w16(UINT port, REG1 Line 825  void IOOUTCALL ideio_w16(UINT port, REG1
   
         IDEDRV  drv;          IDEDRV  drv;
         BYTE    *p;          BYTE    *p;
           long    sec;
   
         drv = getidedrv();          drv = getidedrv();
         if ((drv != NULL) &&          if ((drv != NULL) &&
Line 588  void IOOUTCALL ideio_w16(UINT port, REG1 Line 833  void IOOUTCALL ideio_w16(UINT port, REG1
                 p = drv->buf + drv->bufpos;                  p = drv->buf + drv->bufpos;
                 p[0] = (BYTE)value;                  p[0] = (BYTE)value;
                 p[1] = (BYTE)(value >> 8);                  p[1] = (BYTE)(value >> 8);
                 TRACEOUT(("ide-data send %4x (%.4x) [%.4x:%.8x]",                  TRACEOUT(("ide-data send %.4x (%.4x) [%.4x:%.8x]",
                                                                                 value, drv->bufpos, CPU_CS, CPU_EIP));                                                                                  value, drv->bufpos, CPU_CS, CPU_EIP));
                 drv->bufpos += 2;                  drv->bufpos += 2;
                 if (drv->bufpos >= drv->bufsize) {                  if (drv->bufpos >= drv->bufsize) {
                         drv->status &= ~IDESTAT_DRQ;                          drv->status &= ~IDESTAT_DRQ;
                         switch(drv->cmd) {                          switch(drv->cmd) {
                                   case 0x30:
                                   case 0x31:
                                   case 0xc5:
                                           sec = getcursec(drv);
                                           TRACEOUT(("writesec->drv %d sec %x cnt %d thr %d",
                                                                   drv->sxsidrv, sec, drv->mulcnt, drv->multhr));
                                           if (sxsi_write(drv->sxsidrv, sec, drv->buf, drv->bufsize)) {
                                                   TRACEOUT(("write error!"));
                                                   cmdabort(drv);
                                                   break;
                                           }
                                           drv->mulcnt++;
                                           incsec(drv);
                                           drv->sc--;
                                           if (drv->sc) {
                                                   writesec(drv);
                                           }
                                           break;
   
                                 case 0xa0:                                  case 0xa0:
                                           TRACEOUT(("ideio: execute atapi packet command"));
                                         atapicmd_a0(drv);                                          atapicmd_a0(drv);
                                         break;                                          break;
                         }                          }
                 }                  }
         }          }
           (void)port;
 }  }
   
 REG16 IOINPCALL ideio_r16(UINT port) {  REG16 IOINPCALL ideio_r16(UINT port) {
   
         IDEDRV  drv;          IDEDRV  drv;
         REG16   ret;          REG16   ret;
         BYTE    *p;          UINT8   *p;
   
           (void)port;
   
         drv = getidedrv();          drv = getidedrv();
         if (drv == NULL) {          if (drv == NULL) {
Line 616  REG16 IOINPCALL ideio_r16(UINT port) { Line 884  REG16 IOINPCALL ideio_r16(UINT port) {
         if ((drv->status & IDESTAT_DRQ) && (drv->bufdir == IDEDIR_IN)) {          if ((drv->status & IDESTAT_DRQ) && (drv->bufdir == IDEDIR_IN)) {
                 p = drv->buf + drv->bufpos;                  p = drv->buf + drv->bufpos;
                 ret = p[0] + (p[1] << 8);                  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));                                                                                  ret, drv->bufpos, CPU_CS, CPU_EIP));
                 drv->bufpos += 2;                  drv->bufpos += 2;
                 if (drv->bufpos >= drv->bufsize) {                  if (drv->bufpos >= drv->bufsize) {
Line 624  REG16 IOINPCALL ideio_r16(UINT port) { Line 892  REG16 IOINPCALL ideio_r16(UINT port) {
                         switch(drv->cmd) {                          switch(drv->cmd) {
                                 case 0x20:                                  case 0x20:
                                 case 0x21:                                  case 0x21:
                                   case 0xc4:
                                         incsec(drv);                                          incsec(drv);
                                         drv->sc--;                                          drv->sc--;
                                         if (drv->sc) {                                          if (drv->sc) {
Line 632  REG16 IOINPCALL ideio_r16(UINT port) { Line 901  REG16 IOINPCALL ideio_r16(UINT port) {
                                         break;                                          break;
   
                                 case 0xa0:                                  case 0xa0:
                                           if (drv->buftc == IDETC_ATAPIREAD) {
                                                   atapi_dataread(drv);
                                                   break;
                                           }
                                         drv->sc = IDEINTR_IO | IDEINTR_CD;                                          drv->sc = IDEINTR_IO | IDEINTR_CD;
                                         drv->status &= ~(IDESTAT_BSY | IDESTAT_DRQ | IDESTAT_ERR);                                          drv->status &= ~(IDESTAT_BSY | IDESTAT_SERV | IDESTAT_CHK);
                                         drv->status |= IDESTAT_DRDY;                                          drv->status |= IDESTAT_DRDY;
                                         drv->error = 0;                                          drv->error = 0;
                                         setintr(drv);                                          setintr(drv);
Line 647  REG16 IOINPCALL ideio_r16(UINT port) { Line 920  REG16 IOINPCALL ideio_r16(UINT port) {
   
 // ----  // ----
   
   #if 1
   static BRESULT SOUNDCALL playdevaudio(IDEDRV drv, SINT32 *pcm, UINT count) {
   
           SXSIDEV sxsi;
           UINT    r;
   const UINT8     *ptr;
           SINT    sampl;
           SINT    sampr;
   
           sxsi = sxsi_getptr(drv->sxsidrv);
           if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) ||
                   (!(sxsi->flag & SXSIFLAG_READY))) {
                   drv->daflag = 0x14;
                   return(FAILURE);
           }
           while(count) {
                   r = min(count, drv->dabufrem);
                   if (r) {
                           count -= r;
                           ptr = drv->dabuf + 2352 - (drv->dabufrem * 4);
                           drv->dabufrem -= r;
                           do {
                                   sampl = ((SINT8)ptr[1] << 8) + ptr[0];
                                   sampr = ((SINT8)ptr[3] << 8) + ptr[2];
                                   pcm[0] += sampl;
                                   pcm[1] += sampr;
                                   ptr += 4;
                                   pcm += 2;
                           } while(--r);
                   }
                   if (count == 0) {
                           break;
                   }
                   if (drv->dalength == 0) {
                           drv->daflag = 0x13;
                           return(FAILURE);
                   }
                   if (sxsicd_readraw(sxsi, drv->dacurpos, drv->dabuf) != SUCCESS) {
                           drv->daflag = 0x14;
                           return(FAILURE);
                   }
                   drv->dalength--;
                   drv->dacurpos++;
                   drv->dabufrem = sizeof(drv->dabuf) / 4;
           }
           return(SUCCESS);
   }
   
   static void SOUNDCALL playaudio(void *hdl, SINT32 *pcm, UINT count) {
   
           UINT    bit;
           IDEDRV  drv;
   
           bit = ideio.daplaying;
           if (!bit) {
                   return;
           }
           if (bit & 4) {
                   drv = ideio.dev[1].drv + 0;
                   if (playdevaudio(drv, pcm, count) != SUCCESS) {
                           bit = bit & (~4);
                   }
           }
           ideio.daplaying = bit;
   }
   #endif
   
   // ----
   
 static void devinit(IDEDRV drv, REG8 sxsidrv) {  static void devinit(IDEDRV drv, REG8 sxsidrv) {
   
         SXSIDEV sxsi;          SXSIDEV sxsi;
   
         ZeroMemory(drv, sizeof(_IDEDRV));          ZeroMemory(drv, sizeof(_IDEDRV));
           drv->sxsidrv = sxsidrv;
         sxsi = sxsi_getptr(sxsidrv);          sxsi = sxsi_getptr(sxsidrv);
         if ((sxsi != NULL) && (sxsi->fname[0] != '\0')) {          if ((sxsi != NULL) &&
                 drv->sxsidrv = sxsidrv;                  (sxsi->devtype == SXSIDEV_HDD) && (sxsi->flag & SXSIFLAG_READY)) {
                 drv->status = IDESTAT_DRDY | IDESTAT_DSC;                  drv->status = IDESTAT_DRDY | IDESTAT_DSC;
                 drv->error = IDEERR_AMNF;                  drv->error = IDEERR_AMNF;
                 drv->device = IDETYPE_HDD;                  drv->device = IDETYPE_HDD;
                 drv->surfaces = sxsi->surfaces;                  drv->surfaces = sxsi->surfaces;
                 drv->sectors = sxsi->sectors;                  drv->sectors = sxsi->sectors;
                   drv->mulmode = IDEIO_MULTIPLE_MAX;
           }
           else if ((sxsi != NULL) && (sxsi->devtype == SXSIDEV_CDROM)) {
                   drv->device = IDETYPE_CDROM;
                   drvreset(drv);
                   drv->error = 0;
                   drv->media = IDEIO_MEDIA_EJECTABLE;
                   if (sxsi->flag & SXSIFLAG_READY) {
                           drv->media |= (IDEIO_MEDIA_CHANGED|IDEIO_MEDIA_LOADED);
                   }
                   drv->daflag = 0x15;
         }          }
         else {          else {
                 drv->status = IDESTAT_ERR;                  drv->status = IDESTAT_ERR;
                 drv->error = IDEERR_TR0;                  drv->error = IDEERR_TR0;
                   drv->device = IDETYPE_NONE;
         }          }
 }  }
   
 void ideio_reset(void) {  void ideio_reset(const NP2CFG *pConfig) {
   
         REG8    i;          REG8    i;
         IDEDRV  drv;          IDEDRV  drv;
Line 678  void ideio_reset(void) { Line 1033  void ideio_reset(void) {
                 devinit(drv, i);                  devinit(drv, i);
         }          }
   
 #if 0           // CD-ROM test  
         drv = ideio.dev[1].drv;  
         drv->hd = 0;  
         drv->sc = 1;  
         drv->sn = 1;  
         drv->cy = 0xeb14;  
         drv->status = 0;  
         drv->error = 0;  
         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));          CopyMemory(mem + 0xd0000, idebios, sizeof(idebios));
         TRACEOUT(("use simulate ide.rom"));          TRACEOUT(("use simulate ide.rom"));
   
           (void)pConfig;
 }  }
   
 void ideio_bind(void) {  void ideio_bind(void) {
   
         if (pccore.hddif & PCHDD_IDE) {          if (pccore.hddif & PCHDD_IDE) {
   #if 1
                   sound_streamregist(NULL, (SOUNDCB)playaudio);
   #endif
                 iocore_attachout(0x0430, ideio_o430);                  iocore_attachout(0x0430, ideio_o430);
                 iocore_attachout(0x0432, ideio_o430);                  iocore_attachout(0x0432, ideio_o430);
                 iocore_attachinp(0x0430, ideio_i430);                  iocore_attachinp(0x0430, ideio_i430);
Line 733  void ideio_bind(void) { Line 1070  void ideio_bind(void) {
                 iocore_attachinp(0x074c, ideio_i74c);                  iocore_attachinp(0x074c, ideio_i74c);
         }          }
 }  }
 #endif  
   void ideio_notify(REG8 sxsidrv, UINT action) {
   
           SXSIDEV sxsi;
           IDEDRV  drv;
           REG8 i;
   
           sxsi = sxsi_getptr(sxsidrv);
           if ((sxsi == NULL)
            || (!(sxsi->flag & SXSIFLAG_READY))
            || (sxsi->devtype != SXSIDEV_CDROM)) {
                   return;
           }
   
           for (i=0; i<4; i++) {
                   drv = ideio.dev[i >> 1].drv + (i & 1);
                   if ((drv != NULL) && (drv->sxsidrv == sxsidrv)) {
                           goto do_notify;
                   }
           }
           return;
   
   do_notify:
           switch(action) {
                   case 1:
                           drv->media |= (IDEIO_MEDIA_CHANGED|IDEIO_MEDIA_LOADED);
                           if (sxsi->mediatype & SXSIMEDIA_DATA)
                                   drv->media |= IDEIO_MEDIA_DATA;
                           if (sxsi->mediatype & SXSIMEDIA_AUDIO)
                                   drv->media |= IDEIO_MEDIA_AUDIO;
                           break;
   
                   case 0:
                           drv->media &= ~(IDEIO_MEDIA_LOADED|IDEIO_MEDIA_COMBINE);
                           break;
           }
   }
   
   #endif  /* SUPPORT_IDEIO */
   

Removed from v.1.4  
changed lines
  Added in v.1.15


RetroPC.NET-CVS <cvs@retropc.net>