Diff for /xmil/fdd/fdd_d88.c between versions 1.2 and 1.9

version 1.2, 2004/08/02 11:48:13 version 1.9, 2004/08/10 08:28:48
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
 #include        "dosio.h"  #include        "dosio.h"
 #include        "pccore.h"  #include        "pccore.h"
 #include        "x1_io.h"  
 #include        "x1_fdc.h"  
 #include        "fdd_mtr.h"  
 #include        "fdd_d88.h"  
 #include        "fddfile.h"  #include        "fddfile.h"
   #include        "fdd_d88.h"
   #include        "fdd_mtr.h"
   
   
   enum {
           D88BUFSIZE              = 0x4000
   };
   
   typedef struct {
           FDDFILE fdd;
           UINT8   media;
           UINT8   write;
           UINT8   padding[2];
           UINT    track;
           long    fptr;
           UINT    size;
           UINT8   buf[D88BUFSIZE];
   } _D88TRK, *D88TRK;
   
   static  _D88TRK         d88trk;
   
   
   static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) {
   
           UINT    t;
           UINT32  cur;
   
 static  D88_HEADER      d88head[4];          for (t=0; t<164; t++) {
 static  D88_SECTOR      cursec;                  cur = fdd->inf.d88.ptr[t];
 static  short           curdrv = -1;                  if ((cur > fptr) && (cur < last)) {
 static  WORD            curtrk = -1;                          last = cur;
                   }
           }
           return(last);
   }
   
   static BRESULT trackflush(D88TRK trk) {
   
           FDDFILE fdd;
           FILEH   fh;
   
           fdd = trk->fdd;
           trk->fdd = NULL;
           if ((fdd == NULL) || (trk->size == 0) || (!trk->write)) {
                   goto dtfd_exit;
           }
           fh = file_open(fdd->fname);
           if (fh == FILEH_INVALID) {
                   goto dtfd_err1;
           }
           if ((file_seek(fh, trk->fptr, FSEEK_SET) != trk->fptr) ||
                   (file_write(fh, trk->buf, trk->size) != trk->size)) {
                   goto dtfd_err2;
           }
           file_close(fh);
           trk->write = FALSE;
   
   dtfd_exit:
           return(SUCCESS);
   
   dtfd_err2:
           file_close(fh);
   
   dtfd_err1:
           return(FAILURE);
   }
   
   static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) {
   
           FILEH   fh;
           UINT32  fptr;
           UINT32  size;
   
           trackflush(trk);
           if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) {
                   goto dtrd_err1;
           }
           if (track >= 164) {
                   goto dtrd_err1;
           }
           fptr = fdd->inf.d88.ptr[track];
           if (fptr == 0) {
                   goto dtrd_err1;
           }
           size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr;
           if (size > D88BUFSIZE) {
                   size = D88BUFSIZE;
           }
           fh = file_open_rb(fdd->fname);
           if (fh == FILEH_INVALID) {
                   goto dtrd_err1;
           }
           if ((file_seek(fh, (long)fptr, FSEEK_SET) != (long)fptr) ||
                   (file_read(fh, trk->buf, size) != size)) {
                   goto dtrd_err2;
           }
           file_close(fh);
   
           trk->fdd = fdd;
           trk->media = media;
           trk->write = FALSE;
           trk->track = track;
           trk->fptr = fptr;
           trk->size = size;
           return(trk);
   
   dtrd_err2:
           file_close(fh);
   
   dtrd_err1:
           return(NULL);
   }
   
   static void drvflush(FDDFILE fdd) {
   
           D88TRK  trk;
   
           trk = &d88trk;
           if (trk->fdd == fdd) {
                   trackflush(trk);
           }
   }
   
   static D88TRK trackseek(FDDFILE fdd, REG8 media, UINT track) {
   
           D88TRK  trk;
   
           trk = &d88trk;
           if ((trk->fdd != fdd) || (trk->media != media) || (trk->track != track)) {
                   trk = trackread(trk, fdd, media, track);
           }
           return(trk);
   }
   
   static D88SEC sectorseek(const _D88TRK *trk, REG8 r) {
   
   const _D88SEC   *sec;
           UINT            rem;
           UINT            secnum;
           UINT            sectors;
           UINT            size;
   
           sec = (D88SEC)trk->buf;
           rem = trk->size;
           sectors = LOADINTELWORD(sec->sectors);
           if (sectors) {
                   secnum = 0;
                   do {
                           size = LOADINTELWORD(sec->size);
                           size += sizeof(_D88SEC);
                           if (rem < size) {
                                   break;
                           }
                           if (sec->r == r) {
                                   return((D88SEC)sec);
                           }
                           secnum++;
                           sectors = LOADINTELWORD(sec->sectors);
                           if (secnum >= sectors) {
                                   break;
                           }
                           sec = (D88SEC)(((UINT8 *)sec) + size);
                   } while(secnum < 40);
           }
           return(NULL);
   }
   
   
   // ----
   
   static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) {
   
           if (trackseek(fdd, media, track) != NULL) {
                   return(0x00);
           }
           else {
                   return(FDDSTAT_SEEKERR);
           }
   }
   
   static REG8 fddd88_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
                                                                                                   UINT8 *ptr, UINT *size) {
   
   const _D88TRK   *trk;
   const _D88SEC   *sec;
           UINT            secsize;
           REG8            ret;
   
           TRACEOUT(("d88 read %d:%.2x", track, sc));
           trk = trackseek(fdd, media, track);
           if (trk == NULL) {
                   goto fd8r_err;
           }
           sec = sectorseek(trk, sc);
           if (sec == NULL) {
                   goto fd8r_err;
           }
           ret = 0x00;
           if (sec->del_flg) {
                   ret |= FDDSTAT_RECTYPE;
           }
           if (sec->stat) {
                   ret |= FDDSTAT_CRCERR;
           }
           secsize = LOADINTELWORD(sec->size);
           secsize = min(secsize, *size);
           if ((ptr) && (secsize)) {
                   CopyMemory(ptr, sec + 1, secsize);
           }
           *size = secsize;
           return(ret);
   
   fd8r_err:
           return(FDDSTAT_RECNFND);
   }
   
   static REG8 fddd88_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
                                                                                                   const UINT8 *ptr, UINT size) {
   
           D88TRK  trk;
           D88SEC  sec;
           UINT    secsize;
   
           TRACEOUT(("d88 write %d:%.2x", track, sc));
           trk = trackseek(fdd, media, track);
           if (trk == NULL) {
                   goto fd8w_err;
           }
           sec = sectorseek(trk, sc);
           if (sec == NULL) {
                   goto fd8w_err;
           }
           secsize = LOADINTELWORD(sec->size);
           size = min(size, secsize);
           if (size) {
                   CopyMemory(sec + 1, ptr, size);
                   trk->write = TRUE;
           }
           return(0x00);
   
   fd8w_err:
           return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
   }
   
   static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,
                                                                                                   UINT8 *ptr) {
   
   const _D88TRK   *trk;
   const _D88SEC   *sec;
           UINT            secnum;
           UINT            rem;
           UINT            size;
           UINT            sectors;
   
           trk = trackseek(fdd, media, track);
           if (trk == NULL) {
                   return(FDDSTAT_RECNFND);
           }
           sec = (D88SEC)trk->buf;
           sectors = LOADINTELWORD(sec->sectors);
           if (sectors == 0) {
                   return(FDDSTAT_RECNFND);
           }
           secnum = 0;
           rem = trk->size;
           while(1) {
                   size = LOADINTELWORD(sec->size);
                   size += sizeof(_D88SEC);
                   if (rem < size) {
                           return(FDDSTAT_RECNFND);
                   }
                   if (num == secnum) {
                           break;
                   }
                   secnum++;
                   sectors = LOADINTELWORD(sec->sectors);
                   if (secnum >= sectors) {
                           return(FDDSTAT_RECNFND);
                   }
                   sec = (D88SEC)(((UINT8 *)sec) + size);
           }
           ptr[0] = sec->c;
           ptr[1] = sec->h;
           ptr[2] = sec->r;
           ptr[3] = sec->n;
           ptr[4] = 0;
           ptr[5] = 0;
   //      fdc.s.rreg = sec->c;                                                            // メルヘンヴェール
           if (sec->stat) {
                   return(FDDSTAT_CRCERR);
           }
           return(0x00);
   }
   
   
   // ----
   
   BRESULT fddd88_set(FDDFILE fdd, const OEMCHAR *fname) {
   
           short   attr;
           FILEH   fh;
           BOOL    r;
           UINT8   ptr[D88_TRACKMAX][4];
           UINT    i;
   
           attr = file_attr(fname);
           if (attr & 0x18) {
                   goto fdst_err;
           }
           fh = file_open_rb(fname);
           if (fh == FILEH_INVALID) {
                   goto fdst_err;
           }
           r = (file_read(fh, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head))
                                                                                           != sizeof(fdd->inf.d88.head)) ||
                   (file_read(fh, ptr, sizeof(ptr)) != sizeof(ptr));
           file_close(fh);
           if (r) {
                   goto fdst_err;
           }
           fdd->inf.d88.fd_size = LOADINTELDWORD(fdd->inf.d88.head.fd_size);
           for (i=0; i<D88_TRACKMAX; i++) {
                   fdd->inf.d88.ptr[i] = LOADINTELDWORD(ptr[i]);
           }
           if (fdd->inf.d88.head.protect & 0x10) {
                   attr |= 1;
           }
           fdd->type = DISKTYPE_D88;
           fdd->protect = (UINT8)(attr & 1);
           fdd->seek = fddd88_seek;
           fdd->read = fddd88_read;
           fdd->write = fddd88_write;
           fdd->crc = fddd88_crc;
           return(SUCCESS);
   
   fdst_err:
           return(FAILURE);
   }
   
   void fddd88_eject(FDDFILE fdd) {
   
           drvflush(fdd);
   }
   
   
   
   
   
   
   
   
   
   
   
   
   // ---------------------------------------------------------------------------
   
   #if 0
   // ----
   
   static  _D88SEC         cursec;
   static  REG8            curdrv = (REG8)-1;
   static  UINT            curtrk = (UINT)-1;
 static  BYTE            curtype = 0;  static  BYTE            curtype = 0;
 static  WORD            cursct = -1;  static  UINT            cursct = (UINT)-1;
 static  long            curfp = 0;  static  long            curfp = 0;
 static  DWORD           cursize = 0;  static  UINT            cursize = 0;
 static  BYTE            curwrite = 0;  static  BYTE            curwrite = 0;
 static  BYTE            curtrkerr = 0;  static  BYTE            curtrkerr = 0;
 static  BYTE            hole = 0;  static  BYTE            hole = 0;
 static  BYTE            *curdata;  static  BYTE            *curdata;
 static  WORD            crcnum = 0;  // static       UINT            crcnum = 0;
 static  BYTE            crcerror = FALSE;  // static       BYTE            crcerror = FALSE;
   
 extern  BYTE            WRITEPT[];  
 extern  BYTE            DISKNUM[];  
   
 extern  WORD            readdiag;  extern  WORD            readdiag;
   
Line 73  static BYTE  TAO_BUF[0x3000]; Line 423  static BYTE  TAO_BUF[0x3000];
   
 //----------------------------------------------------------------------  //----------------------------------------------------------------------
   
 static UINT32 nexttrackp(D88_HEADER *head, UINT32 fptr, UINT32 last) {  
   
         UINT    t;  
 const DWORD     *trkp;  
         UINT32  cur;  
   
         trkp = (DWORD *)head->trackp;  
         for (t=0; t<164; t++) {  
                 cur = trkp[t];  
                 if ((cur > fptr) && (cur < last)) {  
                         last = cur;  
                 }  
         }  
         return(last);  
 }  
   
   
 int curdataflush(void) {  static int curdataflush(void) {
   
         FDDFILE fdd;          FDDFILE fdd;
         FILEH   fh;          FILEH   fh;
Line 119  int curdataflush(void) { Line 453  int curdataflush(void) {
 }  }
   
   
 DWORD read_d88track(short drv, WORD track, BYTE type) {  static DWORD read_d88track(REG8 drv, UINT track, REG8 media) {
   
         FDDFILE fdd;          FDDFILE fdd;
         FILEH   hdr;          FILEH   hdr;
Line 127  DWORD read_d88track(short drv, WORD trac Line 461  DWORD read_d88track(short drv, WORD trac
         curdataflush();          curdataflush();
         curdrv = drv;          curdrv = drv;
         curtrk = track;          curtrk = track;
         curtype = type;          curtype = media;
         cursct = -1;          cursct = (UINT)-1;
         curwrite = 0;          curwrite = 0;
         curtrkerr = 0;          curtrkerr = 0;
         crcnum = 0;  //      crcnum = 0;
         crcerror = 0;          crcerror = 0;
   
           fdd = fddfile + drv;
         if ((drv < 0) || (drv > 3) || (track > 163) ||          if ((drv < 0) || (drv > 3) || (track > 163) ||
                 ((type == 0) && (d88head[drv].fd_type == 0x20)) ||                  (media != (fdd->inf.d88.head.fd_type >> 4)) ||
                 ((type == 1) && (d88head[drv].fd_type != 0x20)) ||                  ((curfp = fdd->inf.d88.ptr[track]) == 0) ||
                 ((curfp = d88head[drv].trackp[track]) == 0) ||                  ((cursize = nexttrackptr(fdd, curfp,
                 ((cursize = nexttrackp(&d88head[drv], curfp,                                                                  fdd->inf.d88.fd_size) - curfp) > 0x4000)) {
                                                                 d88head[drv].fd_size) - curfp) > 0x4000)) {  
                 goto readd88_err;                  goto readd88_err;
         }          }
   
         fdd = fddfile + drv;  
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {          if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {
                 goto readd88_err;                  goto readd88_err;
         }          }
Line 151  DWORD read_d88track(short drv, WORD trac Line 484  DWORD read_d88track(short drv, WORD trac
                 file_close(hdr);                  file_close(hdr);
                 goto readd88_err;                  goto readd88_err;
         }          }
         if (file_read(hdr, D88_BUF, (WORD)cursize) != (WORD)cursize) {          if (file_read(hdr, D88_BUF, cursize) != cursize) {
                 file_close(hdr);                  file_close(hdr);
                 goto readd88_err;                  goto readd88_err;
         }          }
Line 170  readd88_err: Line 503  readd88_err:
   
   
   
 static int seeksector(short drv, WORD track, WORD sector) {  static int seeksector(REG8 drv, UINT track, UINT r) {
   
 static  int             lastflag = FALSE;  static  int             lastflag = FALSE;
   
         BYTE            *p;  const _D88SEC   *p;
         WORD            sec;          UINT            sec;
           UINT            sectors;
           UINT            secsize;
   
         if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.media)) {          if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.s.media)) {
                 read_d88track(drv, track, fdc.media);                  read_d88track(drv, track, fdc.s.media);
         }          }
         if (curtrkerr) {          if (curtrkerr) {
                 cursct = sector;                  cursct = r;
                 goto seekerror;                  goto seekerror;
         }          }
         if (cursct != sector) {          if (cursct != r) {
                 cursct = sector;                  cursct = r;
                 p = D88_BUF;                  p = (D88SEC)D88_BUF;
                 for (sec=0; sec<40;) {                  for (sec=0; sec<40; ) {
                         if ((WORD)((D88_SECTOR *)p)->r == sector) {                          sectors = LOADINTELWORD(p->sectors);
                                 memcpy(&cursec, p, sizeof(D88_SECTOR));                          secsize = LOADINTELWORD(p->size);
                                 curdata = p + sizeof(D88_SECTOR);                          if (p->r == r) {
                                   CopyMemory(&cursec, p, sizeof(_D88SEC));
                                   curdata = (UINT8 *)(p + 1);
                                 lastflag = TRUE;                                  lastflag = TRUE;
                                 break;                                  break;
                         }                          }
                         if (++sec >= ((D88_SECTOR *)p)->sectors) {                          sec++;
                           if (sec >= sectors) {
                                 goto seekerror;                                  goto seekerror;
                         }                          }
                         p += ((D88_SECTOR *)p)->size;                          p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);
                         p += sizeof(D88_SECTOR);  
                 }                  }
                 if (sec >= 40) {                  if (sec >= 40) {
                         goto seekerror;                          goto seekerror;
Line 207  static int  lastflag = FALSE; Line 544  static int  lastflag = FALSE;
         return(lastflag);          return(lastflag);
   
 seekerror:;  seekerror:;
         ZeroMemory(&cursec, sizeof(D88_SECTOR));          ZeroMemory(&cursec, sizeof(_D88SEC));
         curdata = &D88_BUF[16];          curdata = &D88_BUF[16];
         lastflag = FALSE;          lastflag = FALSE;
         return(FALSE);          return(FALSE);
 }  }
   
   
 void drvflush(short drv) {  // ----
   
         if (curdrv == drv) {  
                 curdataflush();  
                 curdrv = -1;  
                 curtrk = -1;  
                 cursct = -1;  
         }  
 }  
   
   
   
   
 //**********************************************************************  //**********************************************************************
   
 short fdd_crc_d88(void) {  
   
         WORD            track;  
         BYTE            *p;  
         WORD            sec;  
   
         ZeroMemory(fdc.crc_dat, 6);  
         if ((track = (WORD)(fdc.c << 1) + (WORD)fdc.h) > 163) {  
                 goto crcerror_d88;  
         }  
         seeksector(fdc.drv, track, fdc.r);  
         if (curtrkerr) {  
                 goto crcerror_d88;  
         }  
         p = D88_BUF;  
         for (sec=0; sec<crcnum;) {  
                 if (++sec >= ((D88_SECTOR *)p)->sectors) {  
                         goto crcerror_d88;  
                 }  
                 p += ((D88_SECTOR *)p)->size;  
                 p += sizeof(D88_SECTOR);  
         }  
         *(long *)fdc.crc_dat = *(long *)p;  
         fdc.rreg = ((D88_SECTOR *)p)->c;                                // ??? メルヘンヴェール  
         crcnum++;  
         if (((D88_SECTOR *)p)->stat) {  
                 crcerror = TRUE;  
         }  
         else {  
                 crcerror = FALSE;  
         }  
         return(0);  
   
 crcerror_d88:;  
         crcerror = TRUE;  
         return(1);  
 }  
   
   
 BYTE fdd_stat_d88(void) {  BYTE fdd_stat_d88(void) {
   
         BYTE            type, cmnd;          FDDFILE         fdd;
           BYTE            type;
           REG8            cmd;
           UINT            trk;
         BYTE            ans = 0;          BYTE            ans = 0;
         int                     seekable;          int                     seekable;
         WORD            trk;  
   
         if (DISKNUM[fdc.drv] == DRV_EMPTY) {          fdd = fddfile + fdc.s.drv;
           if (fdd->type != DISKTYPE_D88) {
                 return(0x80);                                           // NOT READY                  return(0x80);                                           // NOT READY
         }          }
         type = fdc.type;          cmd = (REG8)(fdc.s.cmd >> 4);
         cmnd = (BYTE)(fdc.cmnd >> 4);          type = fdc.s.type;
         trk = (fdc.c << 1) + (WORD)fdc.h;          trk = (fdc.s.c << 1) + fdc.s.h;
         seekable = seeksector(fdc.drv, trk, fdc.r);          seekable = seeksector(fdc.s.drv, trk, fdc.s.r);
         if (!fdc.r) {          if (!fdc.s.r) {
                 seekable = TRUE;                  seekable = TRUE;
         }          }
   
         if (type == 0 || type == 1 || type == 4 ||          if (type == 0 || type == 1 || type == 4 ||
                 cmnd == 0x0a || cmnd == 0x0b || cmnd == 0x0f) {                  cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) {
                 if (d88head[fdc.drv].protect & 0x10) {  // WRITE PROTECT                  if (fdd->protect) {                                     // WRITE PROTECT
                         ans |= 0x40;                          ans |= 0x40;
                 }                  }
         }          }
         if (type == 2 || cmnd == 0x0f) {          if (type == 2 || cmd == 0x0f) {
                 if (fdc.r && cursec.del_flg) {                  if (fdc.s.r && cursec.del_flg) {
                         ans |= 0x20;                                    // RECODE TYPE / WRITE FAULT                          ans |= 0x20;                                    // RECODE TYPE / WRITE FAULT
                 }                  }
         }          }
Line 301  BYTE fdd_stat_d88(void) { Line 596  BYTE fdd_stat_d88(void) {
                 if ((trk > 163) || (!seekable)) {                  if ((trk > 163) || (!seekable)) {
                         ans |= 0x10;                                    // SEEK ERROR / RECORD NOT FOUND                          ans |= 0x10;                                    // SEEK ERROR / RECORD NOT FOUND
                 }                  }
                 if ((!(ans & 0xf0)) && fdc.r && (cursec.stat)) {                  if ((!(ans & 0xf0)) && fdc.s.r && (cursec.stat)) {
                         ans |= 0x08;                                    // CRC ERROR                          ans |= 0x08;                                    // CRC ERROR
                 }                  }
         }          }
         if (cmnd == 0x0c) {          if (cmd == 0x0c) {
                 if (curtrkerr) {                  if (curtrkerr) {
                         ans |= 0x10;                          ans |= 0x10;
                 }                  }
Line 316  BYTE fdd_stat_d88(void) { Line 611  BYTE fdd_stat_d88(void) {
         if (type == 1 || type == 4) {          if (type == 1 || type == 4) {
                 if (type == 1) {                                        // ver0.25                  if (type == 1) {                                        // ver0.25
                         ans |= 0x20;                                    // HEAD ENGAGED (X1 デハ ツネニ 1)                          ans |= 0x20;                                    // HEAD ENGAGED (X1 デハ ツネニ 1)
                         if (!fdc.c) {                                   // TRACK00                          if (!fdc.s.c) {                                 // TRACK00
                                 ans |= 0x04;                                  ans |= 0x04;
                         }                          }
                 }                  }
Line 328  BYTE fdd_stat_d88(void) { Line 623  BYTE fdd_stat_d88(void) {
                 if ((type != 4) && (FDDMTR_BUSY)) {                  if ((type != 4) && (FDDMTR_BUSY)) {
                         ans |= 0x01;                          ans |= 0x01;
                 }                  }
                 if ((type == 2) && ((WORD)fdc.off < cursec.size)) {                  if (type == 2) {
                         ans |= 0x03;                                    // DATA REQUEST / BUSY                          UINT secsize = LOADINTELWORD(cursec.size);
                           if ((UINT)fdc.off < secsize) {
                                   ans |= 0x03;                                    // DATA REQUEST / BUSY
                           }
                 }                  }
                 else if ((cmnd == 0x0e) && (readdiag < 0x1a00)) {                  else if ((cmd == 0x0c) && (fdc.s.bufpos < 6)) {
                         ans |= 0x03;                          ans |= 0x03;
                 }                  }
                 else if ((cmnd == 0x0c) && (fdc.crc_off < 6)) {         // ver0.25                  else if ((cmd == 0x0e) && (readdiag < 0x1a00)) {
                         ans |= 0x03;                          ans |= 0x03;
                 }                  }
                 else if (cmnd == 0x0f) {                  else if (cmd == 0x0f) {
                         if (tao.flag == 3) {                          if (tao.flag == 3) {
                                 if (++tao.lostdatacnt > LOSTDATA_COUNT) {                                  if (++tao.lostdatacnt > LOSTDATA_COUNT) {
                                         tao.flag = 4;                                          tao.flag = 4;
Line 350  BYTE fdd_stat_d88(void) { Line 648  BYTE fdd_stat_d88(void) {
 }  }
   
   
   
 //**********************************************************************  //**********************************************************************
   
 void fdd_read_d88(void) {  void fdd_read_d88(void) {
                                                 // POCO:読めなかったらレジスタを変更させない                                                  // POCO:読めなかったらレジスタを変更させない
         if ((fdd_stat_d88() & 0xf3) == 3) {          if ((fdd_stat_d88() & 0xf3) == 3) {
                 fdc.data = curdata[fdc.off];                  fdc.s.data = curdata[fdc.off];
         }          }
 }  }
   
   
 void fdd_write_d88(void) {  void fdd_write_d88(void) {
   
         if ((fdd_stat_d88() & 0xf3) == 3) {          if ((fdd_stat_d88() & 0xf3) == 3) {
                 curdata[fdc.off] = fdc.data;                  curdata[fdc.off] = fdc.s.data;
                 curwrite = 1;                  curwrite = 1;
         }          }
 }  }
   
   
 BYTE fdd_incoff_d88(void) {  BYTE fdd_incoff_d88(void) {
   
         BYTE    cmnd;          REG8    cmd;
         WORD    trk;          UINT    trk;
           UINT    secsize;
         cmnd = (BYTE)(fdc.cmnd >> 4);  
         trk = (fdc.c << 1) + (WORD)fdc.h;          cmd = (REG8)(fdc.s.cmd >> 4);
         seeksector(fdc.drv, trk, fdc.r);          trk = (fdc.s.c << 1) + fdc.s.h;
         if ((WORD)(++fdc.off) < cursec.size) {          seeksector(fdc.s.drv, trk, fdc.s.r);
           fdc.off++;
           secsize = LOADINTELWORD(cursec.size);
           if ((UINT)fdc.off < secsize) {
                 return(0);                  return(0);
         }          }
         fdc.off = cursec.size;          fdc.off = secsize;
         if (cmnd == 0x09 || cmnd == 0x0b) {          if ((cmd == 0x09) || (cmd == 0x0b)) {
                 fdc.rreg = fdc.r + 1;                                           // ver0.25                  fdc.s.rreg = fdc.s.r + 1;                                               // ver0.25
                 if (seeksector(fdc.drv, trk, fdc.rreg)) {                  if (seeksector(fdc.s.drv, trk, fdc.s.rreg)) {
                         fdc.r++;                          fdc.s.r++;
                         fdc.off = 0;                          fdc.off = 0;
                         return(0);                          return(0);
                 }                  }
Line 393  BYTE fdd_incoff_d88(void) { Line 691  BYTE fdd_incoff_d88(void) {
         return(1);          return(1);
 }  }
   
   
 // ---------------------------------------------------------------------------  // ---------------------------------------------------------------------------
   
 void init_tao_d88(void) {  void init_tao_d88(void) {
   
         if ((fdc.media == 0) && (d88head[fdc.drv].fd_type != 0x20)) {          FDDFILE         fdd;
   
           fdd = fddfile + fdc.s.drv;
           if (fdc.s.media != (fdd->inf.d88.head.fd_type >> 4)) {
                   tao = WID_ERR;
           }
           if (fdc.s.media == DISKTYPE_2D) {
                 tao = WID_2D;                  tao = WID_2D;
         }          }
         else if ((fdc.media == 1) && (d88head[fdc.drv].fd_type == 0x20)) {          else if (fdc.s.media == DISKTYPE_2HD) {
                 tao = WID_2HD;                  tao = WID_2HD;
         }          }
         else {          else {
Line 408  void init_tao_d88(void) { Line 713  void init_tao_d88(void) {
         }          }
 }  }
   
 int fileappend(FILEH hdr, D88_HEADER *head,  static int fileappend(FILEH hdl, FDDFILE fdd,
                                                                         long ptr, long last, long apsize) {                                                                          UINT32 ptr, long last, long apsize) {
   
         long    length;          long    length;
         WORD    size;          UINT    size;
         WORD    rsize;          UINT    rsize;
         int             t;          UINT    t;
         long    *trkp;          BYTE    tmp[0x400];
           UINT32  cur;
   
         if ((length = last - ptr) <= 0) {                       // 書き換える必要なし          length = last - ptr;
           if (length <= 0) {                                                      // 書き換える必要なし
                 return(0);                  return(0);
         }          }
         while(length) {          while(length) {
                 if (length >= 0x4000) {                  if (length >= (long)(sizeof(tmp))) {
                         size = 0x4000;                          size = sizeof(tmp);
                 }                  }
                 else {                  else {
                         size = (WORD)length;                          size = length;
                 }                  }
                 length -= (long)size;                  length -= size;
                 file_seek(hdr, ptr+length, 0);                  file_seek(hdl, ptr + length, FSEEK_SET);
                 rsize = file_read(hdr, D88_BUF, size);                  rsize = file_read(hdl, tmp, size);
                 file_seek(hdr, ptr+length+apsize, 0);                  file_seek(hdl, ptr + length + apsize, FSEEK_SET);
                 file_write(hdr, D88_BUF, rsize);                  file_write(hdl, tmp, rsize);
         }          }
           for (t=0; t<164; t++) {
         trkp = head->trackp;                  cur = fdd->inf.d88.ptr[t];
         for (t=0; t<164; t++, trkp++) {                  if ((cur) && (cur >= ptr)) {
                 if ((*trkp) && (*trkp >= ptr)) {                          fdd->inf.d88.ptr[t] = cur + apsize;
                         (*trkp) += apsize;  
                 }                  }
         }          }
         return(0);          return(0);
 }  }
   
   static void endoftrack(void) {
   
           FDDFILE fdd;
 void endoftrack(void) {          FILEH   hdr;
           int             i;
         FDDFILE         fdd;          UINT    trk;
         FILEH           hdr;          long    fpointer;
         int                     i;          long    endpointer;
         WORD            trk;          long    lastpointer;
         D88_HEADER      *head;          long    trksize;
         long            fpointer;          long    apsize;
         long            endpointer;          D88SEC  p;
         long            lastpointer;          UINT    secsize;
         long            trksize;          UINT8   ptr[D88_TRACKMAX][4];
         int                     ptr;  
         long            apsize;  
   
         if (!tao.sector) {          if (!tao.sector) {
                 tao.flag = 4;                  tao.flag = 4;
Line 466  void endoftrack(void) { Line 771  void endoftrack(void) {
         tao.flag = 0;          tao.flag = 0;
   
         curdataflush();                                         // write cache flush &          curdataflush();                                         // write cache flush &
         curdrv = -1;                                            // use D88_BUF[] for temp          curdrv = (REG8)-1;                                      // use D88_BUF[] for temp
   
         head = &d88head[fdc.drv];          fdd = fddfile + fdc.s.drv;
         trk = (fdc.c << 1) + (WORD)fdc.h;          trk = (fdc.s.c << 1) + fdc.s.h;
   
         ptr = 0;          p = (D88SEC)TAO_BUF;
         for (i=0; i<(int)tao.sector; i++) {          for (i=0; i<(int)tao.sector; i++) {
                 ((D88_SECTOR *)&TAO_BUF[ptr])->sectors = tao.sector;                  STOREINTELWORD(p->sectors, tao.sector);
                 ptr += ((D88_SECTOR *)&TAO_BUF[ptr])->size + 16;                  secsize = LOADINTELWORD(p->size);
                   p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);
         }          }
   
         fdd = fddfile + fdc.drv;  
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {          if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {
                 return;                  return;
         }          }
         lastpointer = file_seek(hdr, 0, 2);          lastpointer = file_seek(hdr, 0, 2);
         if ((fpointer = head->trackp[trk]) == 0) {          fpointer = fdd->inf.d88.ptr[trk];
                 fpointer = 0;                                                           // 新規トラック          if (fpointer == 0) {
                 for (i=trk; i>=0; i--) {                  for (i=trk; i>=0; i--) {                                        // 新規トラック
                         if (head->trackp[i]) {                          fpointer = fdd->inf.d88.ptr[i];
                                 fpointer = head->trackp[i];                          if (fpointer) {
                                 break;                                  break;
                         }                          }
                 }                  }
                 if (fpointer) {                                                         // ヒットした                  if (fpointer) {                                                         // ヒットした
                         fpointer = nexttrackp(head, fpointer, lastpointer);                          fpointer = nexttrackptr(fdd, fpointer, lastpointer);
                 }                  }
                 else {                  else {
                         fpointer = sizeof(D88_HEADER);                          fpointer = D88_HEADERSIZE;
                 }                  }
                 endpointer = fpointer;                  endpointer = fpointer;
         }          }
         else {                                                                          // トラックデータは既にある          else {                                                                          // トラックデータは既にある
                 endpointer = nexttrackp(head, fpointer, lastpointer);                  endpointer = nexttrackptr(fdd, fpointer, lastpointer);
         }          }
         trksize = endpointer - fpointer;          trksize = endpointer - fpointer;
         if ((apsize = (long)tao.size - trksize) > 0) {          if ((apsize = (long)tao.size - trksize) > 0) {
                                                                 // 書き込むデータのほーが大きい                                                                  // 書き込むデータのほーが大きい
                 fileappend(hdr, head, endpointer, lastpointer, apsize);                  fileappend(hdr, fdd, endpointer, lastpointer, apsize);
                 head->fd_size += apsize;                  fdd->inf.d88.fd_size += apsize;
         }          }
         head->trackp[trk] = fpointer;          STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size);
         file_seek(hdr, fpointer, 0);          fdd->inf.d88.ptr[trk] = fpointer;
           for (i=0; i<D88_TRACKMAX; i++) {
                   STOREINTELDWORD(ptr[i], fdd->inf.d88.ptr[i]);
           }
           file_seek(hdr, 0, FSEEK_SET);
           file_write(hdr, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head));
           file_write(hdr, ptr, sizeof(ptr));
           file_seek(hdr, fpointer, FSEEK_SET);
         file_write(hdr, TAO_BUF, tao.size);          file_write(hdr, TAO_BUF, tao.size);
         file_seek(hdr, 0, 0);  
         file_write(hdr, head, sizeof(D88_HEADER));  
         file_close(hdr);          file_close(hdr);
 }  }
   
   
 void fdd_wtao_d88(BYTE data) {  void fdd_wtao_d88(BYTE data) {
   
           D88SEC  p;
   
         if (tao.flag != 3) {          if (tao.flag != 3) {
                 return;                  return;
         }          }
Line 534  void fdd_wtao_d88(BYTE data) { Line 845  void fdd_wtao_d88(BYTE data) {
                                 tao.gap = 0;                                  tao.gap = 0;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_GAP:                  case TAO_MODE_GAP:
                         if (data == TAO_MODE_GAP) {                          if (data == TAO_MODE_GAP) {
                                 if (tao.gap++ > 256) {                                  if (tao.gap++ > 256) {
Line 552  void fdd_wtao_d88(BYTE data) { Line 864  void fdd_wtao_d88(BYTE data) {
                                 tao.flag = 4;                                  tao.flag = 4;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_SYNC:                  case TAO_MODE_SYNC:
 //                      tao.cnt--;                                                              // ver0.26 Zeliard  //                      tao.cnt--;                                                              // ver0.26 Zeliard
                         if (data == TAO_CMD_AM_IN) {                          if (data == TAO_CMD_AM_IN) {
Line 564  void fdd_wtao_d88(BYTE data) { Line 877  void fdd_wtao_d88(BYTE data) {
                                 tao.flag = 4;                                  tao.flag = 4;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_IM:                  case TAO_MODE_IM:
                         if (data == TAO_CMD_IM) {                          if (data == TAO_CMD_IM) {
                                 tao.mode = TAO_ENDOFDATA;                                  tao.mode = TAO_ENDOFDATA;
Line 572  void fdd_wtao_d88(BYTE data) { Line 886  void fdd_wtao_d88(BYTE data) {
                                 tao.flag = 4;                                  tao.flag = 4;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_AM:                  case TAO_MODE_AM:
                         if (data == TAO_CMD_IAM) {                          if (data == TAO_CMD_IAM) {
                                 tao.mode = TAO_MODE_ID;                                  tao.mode = TAO_MODE_ID;
Line 585  void fdd_wtao_d88(BYTE data) { Line 900  void fdd_wtao_d88(BYTE data) {
                         else if (data == TAO_CMD_DDAM) {                          else if (data == TAO_CMD_DDAM) {
                                 tao.mode = TAO_MODE_DATA;                                  tao.mode = TAO_MODE_DATA;
                                 tao.ptr = 0;                                  tao.ptr = 0;
                                 ((D88_SECTOR *)&TAO_BUF[tao.top])->del_flg = 1;                                  p = (D88SEC)(TAO_BUF + tao.top);
                                   p->del_flg = 1;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_ID:                  case TAO_MODE_ID:
                         if ((data == TAO_CMD_IAM) && (!tao.ptr)) {                          if ((data == TAO_CMD_IAM) && (!tao.ptr)) {
                                 break;                                  break;
Line 598  void fdd_wtao_d88(BYTE data) { Line 915  void fdd_wtao_d88(BYTE data) {
                         }                          }
                         else if (data == TAO_CMD_CRC) {                          else if (data == TAO_CMD_CRC) {
                                 tao.mode = TAO_ENDOFDATA;                                  tao.mode = TAO_ENDOFDATA;
                                 ZeroMemory(&TAO_BUF[tao.size], 12);                                  ZeroMemory(TAO_BUF + tao.size, 12);
                                 tao.size += 12;                                  tao.size += 12;
                         }                          }
                         break;                          break;
   
                 case TAO_MODE_DATA:                                             // DATA WRITE                  case TAO_MODE_DATA:                                             // DATA WRITE
                         if ((!tao.ptr) &&                          if ((!tao.ptr) &&
                                 ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) {                                  ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) {
Line 609  void fdd_wtao_d88(BYTE data) { Line 927  void fdd_wtao_d88(BYTE data) {
                         }                          }
                         else if (data == TAO_CMD_CRC) {                 // nで判定した方が無難か?                          else if (data == TAO_CMD_CRC) {                 // nで判定した方が無難か?
                                 tao.mode = TAO_ENDOFDATA;                                  tao.mode = TAO_ENDOFDATA;
                                 ((D88_SECTOR *)&TAO_BUF[tao.top])->size = tao.ptr;                                  p = (D88SEC)(TAO_BUF + tao.top);
                                   STOREINTELWORD(p->size, tao.ptr);
                                 if (tao.sector++ > tao.maxsector) {                                  if (tao.sector++ > tao.maxsector) {
                                         tao.flag = 4;                                          tao.flag = 4;
                                 }                                  }
Line 621  void fdd_wtao_d88(BYTE data) { Line 940  void fdd_wtao_d88(BYTE data) {
                         break;                          break;
         }          }
 }  }
   #endif
   
 // ----  
   
 BRESULT fddd88_eject(REG8 drv) {  
   
         FDDFILE fdd;  
   
         drvflush(drv);  
         fdd = fddfile + drv;  
         ZeroMemory(&d88head[drv], sizeof(D88_HEADER));  
         fdd->fname[0] = '\0';  
         DISKNUM[drv] = 0;  
         return(SUCCESS);  
 }  
   
 BRESULT fddd88_set(REG8 drv, const OEMCHAR *fname) {  
   
         FDDFILE fdd;  
         short   attr;  
         FILEH   fh;  
         UINT    rsize;  
   
         fdd = fddfile + drv;  
         attr = file_attr(fname);  
         if (attr & 0x18) {  
                 goto fdst_err;  
         }  
         fh = file_open(fname);  
         if (fh == FILEH_INVALID) {  
                 goto fdst_err;  
         }  
         rsize = file_read(fh, &d88head[drv], sizeof(D88_HEADER));  
         file_close(fh);  
         if (rsize != sizeof(D88_HEADER)) {  
                 goto fdst_err;  
         }  
         if (attr & 1) {  
                 d88head[drv].protect |= (WORD)0x10;  
         }  
         milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname));  
         DISKNUM[drv] = 1;  
         return(SUCCESS);  
   
 fdst_err:  
         return(FAILURE);  
 }  
   

Removed from v.1.2  
changed lines
  Added in v.1.9


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