Diff for /np2/fdd/sxsi.c between versions 1.5 and 1.15

version 1.5, 2003/11/07 18:31:24 version 1.15, 2005/02/12 12:40:39
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
   #include        "strres.h"
 #include        "dosio.h"  #include        "dosio.h"
 #include        "sysmng.h"  #include        "sysmng.h"
 #include        "i286.h"  #include        "cpucore.h"
 #include        "pccore.h"  #include        "pccore.h"
 #include        "sxsi.h"  #include        "sxsi.h"
   
   
 typedef struct {  const char sig_vhd[8] = "VHD1.00";
         char    vhd[3];  const char sig_nhd[15] = "T98HDDIMAGE.R0";
         char    ver[4];  
         char    delimita;  
         char    comment[128];  
         BYTE    padding[4];  
         BYTE    mbsize[2];  
         BYTE    sectorsize[2];  
         BYTE    sectors;  
         BYTE    surfaces;  
         BYTE    tracks[2];  
         BYTE    totals[4];  
 } V98SCSIHDR;  
   
 typedef struct {  
         BYTE    tracks[2];  
 } THDHDR;  
   
 typedef struct {  
         BYTE    dummy[8];  
         BYTE    headersize[4];  
         BYTE    filesize[4];  
         BYTE    sectorsize[4];  
         BYTE    sectors[4];  
         BYTE    surfaces[4];  
         BYTE    tracks[4];  
 } HDIHDR;  
   
 static const _SXSIHDD defsasi = {615*33*8, 615, 256, 33, 8,  
                                                                                         HDDTYPE_SASI, 256, 0, {0x00}};  
 static const _SXSIHDD defscsi = {40*16*32*8, 40*16, 256, 32, 8,  
                                                                                         HDDTYPE_SCSI, 220, 0, {0x00}};  
   
   const SASIHDD sasihdd[7] = {
         _SXSIHDD        sxsi_hd[4];                                  {33, 4, 153},                   // 5MB
                                   {33, 4, 310},                   // 10MB
                                   {33, 6, 310},                   // 15MB
                                   {33, 8, 310},                   // 20MB
                                   {33, 4, 615},                   // 20MB (not used!)
                                   {33, 6, 615},                   // 30MB
                                   {33, 8, 615}};                  // 40MB
   
   #if 0
   static const _SXSIDEV defide = {615*33*8, 615, 256, 33, 8,
                                                                   SXSITYPE_IDE | SXSITYPE_HDD, 256, 0, {0x00}};
   static const _SXSIDEV defscsi = {40*16*32*8, 40*16, 256, 32, 8,
                                                                   SXSITYPE_SCSI | SXSITYPE_HDD, 220, 0, {0x00}};
   #endif
   
   
           _SXSIDEV        sxsi_dev[SASIHDD_MAX + SCSIHDD_MAX];
   
   
   // SASI規格HDDかチェック
   static void sasihddcheck(SXSIDEV sxsi) {
   
   const SASIHDD   *sasi;
           UINT            i;
   
           sasi = sasihdd;
           for (i=0; i<NELEMENTS(sasihdd); i++, sasi++) {
                   if ((sxsi->size == 256) &&
                           (sxsi->sectors == sasi->sectors) &&
                           (sxsi->surfaces == sasi->surfaces) &&
                           (sxsi->cylinders == sasi->cylinders)) {
                           sxsi->type = (UINT16)(SXSITYPE_SASI + (i << 8) + SXSITYPE_HDD);
                           break;
                   }
           }
   }
   
   
 // ----  // ----
Line 49  void sxsi_initialize(void) { Line 55  void sxsi_initialize(void) {
   
         UINT    i;          UINT    i;
   
         ZeroMemory(sxsi_hd, sizeof(sxsi_hd));          ZeroMemory(sxsi_dev, sizeof(sxsi_dev));
         for (i=0; i<(sizeof(sxsi_hd)/sizeof(_SXSIHDD)); i++) {          for (i=0; i<NELEMENTS(sxsi_dev); i++) {
                 sxsi_hd[i].fh = (long)FILEH_INVALID;                  sxsi_dev[i].fh = (long)FILEH_INVALID;
         }          }
 }  }
   
 SXSIHDD sxsi_getptr(BYTE drv) {  SXSIDEV sxsi_getptr(REG8 drv) {
   
         UINT    num;          UINT    num;
   
         num = drv & 0x0f;          num = drv & 0x0f;
         if (num >= 2) {          if (!(drv & 0x20)) {                                    // SASI or IDE
                 return(NULL);                  if (num < SASIHDD_MAX) {
                           return(sxsi_dev + num);
                   }
         }          }
         num += (drv & 0x20) >> 4;  #if defined(SUPPORT_SCSI)
         return(sxsi_hd + num);          else {
                   if (num < SCSIHDD_MAX) {                        // SCSI
                           return(sxsi_dev + SASIHDD_MAX + num);
                   }
           }
   #endif
           return(NULL);
 }  }
   
 const char *sxsi_getname(BYTE drv) {  const OEMCHAR *sxsi_getname(REG8 drv) {
   
         SXSIHDD sxsi;          SXSIDEV sxsi;
   
         sxsi = sxsi_getptr(drv);          sxsi = sxsi_getptr(drv);
         if (sxsi) {          if (sxsi) {
Line 78  const char *sxsi_getname(BYTE drv) { Line 92  const char *sxsi_getname(BYTE drv) {
         return(NULL);          return(NULL);
 }  }
   
 BOOL sxsi_hddopen(BYTE drv, const char *file) {  BRESULT sxsi_hddopen(REG8 drv, const OEMCHAR *file) {
   
         SXSIHDD         sxsi;          SXSIDEV         sxsi;
 const char              *ext;  
         FILEH           fh;          FILEH           fh;
         THDHDR          thd;  const OEMCHAR   *ext;
         HDIHDR          hdi;          UINT16          type;
         V98SCSIHDR      v98;          long            totals;
           UINT32          headersize;
           UINT32          surfaces;
           UINT32          cylinders;
           UINT32          sectors;
           UINT32          size;
   
         if ((file == NULL) || (file[0] == '\0')) {          if ((file == NULL) || (file[0] == '\0')) {
                 goto sxsiope_err;                  goto sxsiope_err1;
         }          }
         sxsi = sxsi_getptr(drv);          sxsi = sxsi_getptr(drv);
         if (sxsi == NULL) {          if (sxsi == NULL) {
                 goto sxsiope_err;                  goto sxsiope_err1;
         }          }
         ext = file_getext((char *)file);          fh = file_open(file);
         if ((!file_cmpname(ext, "thd")) && (!(drv & 0x20))) {          if (fh == FILEH_INVALID) {
                 fh = file_open(file);                                                           // T98 HDD (SASI)                  goto sxsiope_err1;
                 if (fh == FILEH_INVALID) {          }
                         goto sxsiope_err;          ext = file_getext(file);
                 }          type = SXSITYPE_HDD;
                 if (file_read(fh, &thd, sizeof(thd)) == sizeof(thd)) {          if ((!file_cmpname(ext, str_thd)) && (!(drv & 0x20))) {
                         *sxsi = defsasi;                  THDHDR thd;                                             // T98 HDD (IDE)
                         sxsi->tracks = LOADINTELWORD(thd.tracks);                  if (file_read(fh, &thd, sizeof(thd)) != sizeof(thd)) {
                         sxsi->totals = sxsi->tracks * sxsi->sectors * sxsi->surfaces;                          goto sxsiope_err2;
                         file_cpyname(sxsi->fname, file, sizeof(sxsi->fname));                  }
                         sxsi->fh = (long)fh;                  headersize = 256;
                         return(SUCCESS);                  surfaces = 8;
                 }                  cylinders = LOADINTELWORD(thd.cylinders);
                 file_close(fh);                  sectors = 33;
         }                  size = 256;
         else if ((!file_cmpname(ext, "hdi")) && (!(drv & 0x20))) {                  totals = cylinders * sectors * surfaces;
                 fh = file_open(file);                           // ANEX86 HDD (SASI) thanx Mamiya          }
                 if (fh == FILEH_INVALID) {          else if ((!file_cmpname(ext, str_nhd)) && (!(drv & 0x20))) {
                         goto sxsiope_err;                  NHDHDR nhd;                                             // T98Next HDD (IDE)
                 }                  if ((file_read(fh, &nhd, sizeof(nhd)) != sizeof(nhd)) ||
                 if (file_read(fh, &hdi, sizeof(hdi)) == sizeof(hdi)) {                          (memcmp(nhd.sig, sig_nhd, 15))) {
                         *sxsi = defsasi;                          goto sxsiope_err2;
                         sxsi->size = LOADINTELWORD(hdi.sectorsize);                  }
                         sxsi->headersize = LOADINTELDWORD(hdi.headersize);                  headersize = LOADINTELDWORD(nhd.headersize);
                         sxsi->tracks = LOADINTELWORD(hdi.tracks);                  surfaces = LOADINTELWORD(nhd.surfaces);
                         sxsi->surfaces = hdi.surfaces[0];                  cylinders = LOADINTELDWORD(nhd.cylinders);
                         sxsi->sectors = hdi.sectors[0];                  sectors = LOADINTELWORD(nhd.sectors);
                         sxsi->totals = sxsi->tracks * sxsi->sectors * sxsi->surfaces;                  size = LOADINTELWORD(nhd.sectorsize);
                         file_cpyname(sxsi->fname, file, sizeof(sxsi->fname));                  totals = cylinders * sectors * surfaces;
                         sxsi->fh = (long)fh;          }
                         return(SUCCESS);          else if ((!file_cmpname(ext, str_hdi)) && (!(drv & 0x20))) {
                 }                  HDIHDR hdi;                                             // ANEX86 HDD (SASI) thanx Mamiya
                 file_close(fh);                  if (file_read(fh, &hdi, sizeof(hdi)) != sizeof(hdi)) {
         }                          goto sxsiope_err2;
         else if ((!file_cmpname(ext, "hdd")) && (drv & 0x20)) {                  }
                 fh = file_open(file);                                           // Virtual98 HDD (SCSI)                  headersize = LOADINTELDWORD(hdi.headersize);
                 if (fh == FILEH_INVALID) {                  surfaces = LOADINTELDWORD(hdi.surfaces);
                         goto sxsiope_err;                  cylinders = LOADINTELDWORD(hdi.cylinders);
                 }                  sectors = LOADINTELDWORD(hdi.sectors);
                 if ((file_read(fh, &v98, sizeof(v98)) == sizeof(v98)) &&                  size = LOADINTELDWORD(hdi.sectorsize);
                         (!memcmp(v98.vhd, "VHD", 3))) {                  totals = cylinders * sectors * surfaces;
                         sxsi = &sxsi_hd[drv+2];          }
                         *sxsi = defscsi;          else if ((!file_cmpname(ext, str_hdd)) && (drv & 0x20)) {
                         sxsi->totals = (SINT32)LOADINTELDWORD(v98.totals);                  VHDHDR vhd;                                             // Virtual98 HDD (SCSI)
                         sxsi->tracks = LOADINTELWORD(v98.tracks);                  if ((file_read(fh, &vhd, sizeof(vhd)) != sizeof(vhd)) ||
                         sxsi->size = LOADINTELWORD(v98.sectorsize);                          (memcmp(vhd.sig, sig_vhd, 5))) {
                         sxsi->sectors = v98.sectors;                          goto sxsiope_err2;
                         sxsi->surfaces = v98.surfaces;                  }
                         file_cpyname(sxsi->fname, file, sizeof(sxsi->fname));                  headersize = sizeof(vhd);
                         sxsi->fh = (long)fh;                  surfaces = vhd.surfaces;
                         return(SUCCESS);                  cylinders = LOADINTELWORD(vhd.cylinders);
                 }                  sectors = vhd.sectors;
                 file_close(fh);                  size = LOADINTELWORD(vhd.sectorsize);
                   totals = (SINT32)LOADINTELDWORD(vhd.totals);
           }
           else {
                   goto sxsiope_err2;
           }
   
           // フォーマット確認〜
           if ((surfaces == 0) || (surfaces >= 256) ||
                   (cylinders == 0) || (cylinders >= 65536) ||
                   (sectors == 0) || (sectors >= 256) ||
                   (size == 0) || ((size & (size - 1)) != 0)) {
                   goto sxsiope_err2;
           }
           if (!(drv & 0x20)) {
                   type |= SXSITYPE_IDE;
           }
           else {
                   type |= SXSITYPE_SCSI;
                   if (!(size & 0x700)) {                  // not 256,512,1024
                           goto sxsiope_err2;
                   }
           }
           sxsi->totals = totals;
           sxsi->cylinders = (UINT16)cylinders;
           sxsi->size = (UINT16)size;
           sxsi->sectors = (UINT8)sectors;
           sxsi->surfaces = (UINT8)surfaces;
           sxsi->type = type;
           sxsi->headersize = headersize;
           sxsi->fh = (long)fh;
           file_cpyname(sxsi->fname, file, NELEMENTS(sxsi->fname));
           if (type == (SXSITYPE_IDE | SXSITYPE_HDD)) {
                   sasihddcheck(sxsi);
         }          }
           return(SUCCESS);
   
 sxsiope_err:  sxsiope_err2:
           file_close(fh);
   
   sxsiope_err1:
         return(FAILURE);          return(FAILURE);
 }  }
   
 void sxsi_open(void) {  void sxsi_open(void) {
   
         int             i;          int             i;
         BYTE    sasi;          REG8    drv;
   
         sxsi_trash();          sxsi_trash();
         sasi = 0;          drv = 0;
         for (i=0; i<2; i++) {          for (i=0; i<2; i++) {
                 if (sxsi_hddopen(sasi, np2cfg.hddfile[i]) == SUCCESS) {                  if (sxsi_hddopen(drv, np2cfg.sasihdd[i]) == SUCCESS) {
                         sasi++;                          drv++;
                   }
           }
   #if defined(SUPPORT_SCSI)
           drv = 0x20;
           for (i=0; i<4; i++) {
                   if (sxsi_hddopen(drv, np2cfg.scsihdd[i]) == SUCCESS) {
                           drv++;
                 }                  }
         }          }
   #endif
 }  }
   
 void sxsi_flash(void) {  void sxsi_flash(void) {
   
         SXSIHDD sxsi;          SXSIDEV sxsi;
         SXSIHDD sxsiterm;          SXSIDEV sxsiterm;
   
         sxsi = sxsi_hd;          sxsi = sxsi_dev;
         sxsiterm = sxsi + (sizeof(sxsi_hd)/sizeof(_SXSIHDD));          sxsiterm = sxsi + NELEMENTS(sxsi_dev);
         while(sxsi < sxsiterm) {          while(sxsi < sxsiterm) {
                 if ((FILEH)sxsi->fh != FILEH_INVALID) {                  if ((FILEH)sxsi->fh != FILEH_INVALID) {
                         file_close((FILEH)sxsi->fh);                          file_close((FILEH)sxsi->fh);
Line 186  void sxsi_flash(void) { Line 249  void sxsi_flash(void) {
   
 void sxsi_trash(void) {  void sxsi_trash(void) {
   
         SXSIHDD sxsi;          SXSIDEV sxsi;
         SXSIHDD sxsiterm;          SXSIDEV sxsiterm;
   
         sxsi = sxsi_hd;          sxsi = sxsi_dev;
         sxsiterm = sxsi + (sizeof(sxsi_hd)/sizeof(_SXSIHDD));          sxsiterm = sxsi + NELEMENTS(sxsi_dev);
         while(sxsi < sxsiterm) {          while(sxsi < sxsiterm) {
                 if ((FILEH)sxsi->fh != FILEH_INVALID) {                  if ((FILEH)sxsi->fh != FILEH_INVALID) {
                         file_close((FILEH)sxsi->fh);                          file_close((FILEH)sxsi->fh);
                         sxsi->fh = (long)FILEH_INVALID;  
                 }                  }
                 sxsi->fname[0] = '\0';                  ZeroMemory(sxsi, sizeof(_SXSIDEV));
                   sxsi->fh = (long)FILEH_INVALID;
                 sxsi++;                  sxsi++;
         }          }
 }  }
   
 static SXSIHDD getdrive(BYTE drv) {  static SXSIDEV getdrive(REG8 drv) {
   
         UINT    num;          SXSIDEV ret;
         SXSIHDD ret;  
   
         num = drv & 0x0f;          ret = sxsi_getptr(drv);
         if (num >= 2) {          if ((ret == NULL) || (ret->fname[0] == '\0')) {
                 return(NULL);  
         }  
         num += (drv & 0x20) >> 4;  
         ret = sxsi_hd + num;  
         if (ret->fname[0] == '\0') {  
                 return(NULL);                  return(NULL);
         }          }
         if ((FILEH)ret->fh == FILEH_INVALID) {          if ((FILEH)ret->fh == FILEH_INVALID) {
Line 226  static SXSIHDD getdrive(BYTE drv) { Line 283  static SXSIHDD getdrive(BYTE drv) {
         return(ret);          return(ret);
 }  }
   
 BYTE sxsi_read(BYTE drv, long pos, BYTE *buf, UINT16 size) {  BOOL sxsi_issasi(void) {
   
           REG8    drv;
           SXSIDEV sxsi;
           BOOL    ret;
           UINT    sxsiif;
   
           ret = FALSE;
           for (drv=0x00; drv<0x04; drv++) {
                   sxsi = sxsi_getptr(drv);
                   if (sxsi) {
                           sxsiif = sxsi->type & SXSITYPE_IFMASK;
                           if (sxsiif == SXSITYPE_SASI) {
                                   ret = TRUE;
                           }
                           else if (sxsiif == SXSITYPE_IDE) {
                                   ret = FALSE;
                                   break;
                           }
                   }
           }
           return(ret);
   }
   
   BOOL sxsi_isscsi(void) {
   
 const _SXSIHDD  *sxsi;          REG8    drv;
           SXSIDEV sxsi;
   
           for (drv=0x20; drv<0x28; drv++) {
                   sxsi = sxsi_getptr(drv);
                   if ((sxsi) && (sxsi->type)) {
                           return(TRUE);
                   }
           }
           return(FALSE);
   }
   
   BOOL sxsi_iside(void) {
   
           REG8    drv;
           SXSIDEV sxsi;
   
           for (drv=0x00; drv<0x04; drv++) {
                   sxsi = sxsi_getptr(drv);
                   if ((sxsi) && (sxsi->type)) {
                           return(TRUE);
                   }
           }
           return(FALSE);
   }
   
   REG8 sxsi_read(REG8 drv, long pos, UINT8 *buf, UINT size) {
   
   const _SXSIDEV  *sxsi;
         long            r;          long            r;
         UINT16          rsize;          UINT            rsize;
   
         sxsi = getdrive(drv);          sxsi = getdrive(drv);
         if (sxsi == NULL) {          if (sxsi == NULL) {
                 return(0x60);                  return(0x60);
         }          }
         pos = pos * sxsi->size + sxsi->headersize;          if ((pos < 0) || (pos >= sxsi->totals)) {
         r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);  
         if (r == -1) {  
                 return(0x40);                  return(0x40);
         }          }
           pos = pos * sxsi->size + sxsi->headersize;
           r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);
         if (pos != r) {          if (pos != r) {
                 return(0xd0);                  return(0xd0);
         }          }
         while(size) {          while(size) {
                 rsize = min(size, sxsi->size);                  rsize = min(size, sxsi->size);
                 I286_REMCLOCK -= rsize;                  CPU_REMCLOCK -= rsize;
                 if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) {                  if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) {
                         return(0xd0);                          return(0xd0);
                 }                  }
Line 256  const _SXSIHDD *sxsi; Line 365  const _SXSIHDD *sxsi;
         return(0x00);          return(0x00);
 }  }
   
 BYTE sxsi_write(BYTE drv, long pos, const BYTE *buf, UINT16 size) {  REG8 sxsi_write(REG8 drv, long pos, const UINT8 *buf, UINT size) {
   
 const _SXSIHDD  *sxsi;  const _SXSIDEV  *sxsi;
         long            r;          long            r;
         UINT16          wsize;          UINT            wsize;
   
         sxsi = getdrive(drv);          sxsi = getdrive(drv);
         if (sxsi == NULL) {          if (sxsi == NULL) {
                 return(0x60);                  return(0x60);
         }          }
         pos = pos * sxsi->size + sxsi->headersize;          if ((pos < 0) || (pos >= sxsi->totals)) {
         r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);  
         if (r == -1) {  
                 return(0x40);                  return(0x40);
         }          }
           pos = pos * sxsi->size + sxsi->headersize;
           r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);
         if (pos != r) {          if (pos != r) {
                 return(0xd0);                  return(0xd0);
         }          }
         while(size) {          while(size) {
                 wsize = min(size, sxsi->size);                  wsize = min(size, sxsi->size);
                 I286_REMCLOCK -= wsize;                  CPU_REMCLOCK -= wsize;
                 if (file_write((FILEH)sxsi->fh, buf, wsize) != wsize) {                  if (file_write((FILEH)sxsi->fh, buf, wsize) != wsize) {
                         return(0x70);                          return(0x70);
                 }                  }
Line 286  const _SXSIHDD *sxsi; Line 395  const _SXSIHDD *sxsi;
         return(0x00);          return(0x00);
 }  }
   
 BYTE sxsi_format(BYTE drv, long pos) {  REG8 sxsi_format(REG8 drv, long pos) {
   
 const _SXSIHDD  *sxsi;  const _SXSIDEV  *sxsi;
         long            r;          long            r;
         UINT16          i;          UINT16          i;
         BYTE            work[256];          UINT8           work[256];
         UINT            size;          UINT            size;
         UINT            wsize;          UINT            wsize;
   
Line 299  const _SXSIHDD *sxsi; Line 408  const _SXSIHDD *sxsi;
         if (sxsi == NULL) {          if (sxsi == NULL) {
                 return(0x60);                  return(0x60);
         }          }
         pos = pos * sxsi->size + sxsi->headersize;          if ((pos < 0) || (pos >= sxsi->totals)) {
         r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);  
         if (r == -1) {  
                 return(0x40);                  return(0x40);
         }          }
           pos = pos * sxsi->size + sxsi->headersize;
           r = file_seek((FILEH)sxsi->fh, pos, FSEEK_SET);
         if (pos != r) {          if (pos != r) {
                 return(0xd0);                  return(0xd0);
         }          }
Line 313  const _SXSIHDD *sxsi; Line 422  const _SXSIHDD *sxsi;
                 while(size) {                  while(size) {
                         wsize = min(size, sizeof(work));                          wsize = min(size, sizeof(work));
                         size -= wsize;                          size -= wsize;
                         I286_REMCLOCK -= wsize;                          CPU_REMCLOCK -= wsize;
                         if (file_write((FILEH)sxsi->fh, work, wsize) != wsize) {                          if (file_write((FILEH)sxsi->fh, work, wsize) != wsize) {
                                 return(0x70);                                  return(0x70);
                         }                          }

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


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