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

version 1.9, 2004/08/10 08:28:48 version 1.15, 2005/02/04 06:42:11
Line 18  typedef struct { Line 18  typedef struct {
         UINT    track;          UINT    track;
         long    fptr;          long    fptr;
         UINT    size;          UINT    size;
           UINT    sectors;
         UINT8   buf[D88BUFSIZE];          UINT8   buf[D88BUFSIZE];
 } _D88TRK, *D88TRK;  } _D88TRK, *D88TRK;
   
Line 71  dtfd_err1: Line 72  dtfd_err1:
   
 static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) {  static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) {
   
         FILEH   fh;          FILEH           fh;
         UINT32  fptr;          UINT32          fptr;
         UINT32  size;          UINT            size;
   const _D88SEC   *sec;
           UINT            rem;
           UINT            maxsectors;
           UINT            sectors;
           UINT            secsize;
   
         trackflush(trk);          trackflush(trk);
         if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) {          if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) {
Line 106  static D88TRK trackread(D88TRK trk, FDDF Line 112  static D88TRK trackread(D88TRK trk, FDDF
         trk->track = track;          trk->track = track;
         trk->fptr = fptr;          trk->fptr = fptr;
         trk->size = size;          trk->size = size;
   
           // セクタ数チェック
           sec = (D88SEC)trk->buf;
           rem = size;
           maxsectors = 0;
           if (rem >= sizeof(_D88SEC)) {
                   maxsectors = LOADINTELWORD(sec->sectors);
           }
           sectors = 0;
           while(sectors < maxsectors) {
                   secsize = LOADINTELWORD(sec->size);
                   secsize += sizeof(_D88SEC);
                   if (rem < secsize) {
                           break;
                   }
                   rem -= secsize;
                   maxsectors = LOADINTELWORD(sec->sectors);
                   sec = (D88SEC)(((UINT8 *)sec) + secsize);
                   sectors++;
           }
           trk->sectors = sectors;
         return(trk);          return(trk);
   
 dtrd_err2:  dtrd_err2:
Line 139  static D88TRK trackseek(FDDFILE fdd, REG Line 166  static D88TRK trackseek(FDDFILE fdd, REG
 static D88SEC sectorseek(const _D88TRK *trk, REG8 r) {  static D88SEC sectorseek(const _D88TRK *trk, REG8 r) {
   
 const _D88SEC   *sec;  const _D88SEC   *sec;
         UINT            rem;  
         UINT            secnum;  
         UINT            sectors;          UINT            sectors;
         UINT            size;          UINT            size;
   
         sec = (D88SEC)trk->buf;          sec = (D88SEC)trk->buf;
         rem = trk->size;          sectors = trk->sectors;
         sectors = LOADINTELWORD(sec->sectors);          while(sectors) {
         if (sectors) {                  sectors--;
                 secnum = 0;                  if (sec->r == r) {
                 do {                          return((D88SEC)sec);
                         size = LOADINTELWORD(sec->size);                  }
                         size += sizeof(_D88SEC);                  size = LOADINTELWORD(sec->size);
                         if (rem < size) {                  size += sizeof(_D88SEC);
                   sec = (D88SEC)(((UINT8 *)sec) + size);
           }
           return(NULL);
   }
   
   
   // ----
   
   static BRESULT fileappend(FILEH fh, UINT32 ptr, UINT size) {
   
           UINT    filesize;
           UINT    r;
           UINT8   work[0x400];
   
           filesize = file_getsize(fh);
           if (filesize < ptr) {
                   return(FAILURE);
           }
           filesize -= ptr;
           while(filesize) {
                   r = min(filesize, sizeof(work));
                   filesize -= r;
                   file_seek(fh, ptr + filesize, FSEEK_SET);
                   r = file_read(fh, work, r);
                   file_seek(fh, ptr + filesize + size, FSEEK_SET);
                   file_write(fh, work, r);
           }
           return(SUCCESS);
   }
   
   static BRESULT writetrack(FDDFILE fdd, REG8 media, UINT track,
                                                                                                           UINT8 *buf, UINT size) {
   
           FILEH   fh;
           UINT    i;
           UINT32  curptr;                         // fpointer;
           UINT32  nextptr;                        // endpointer;
           UINT    cursize;
           UINT    addsize;
           UINT32  cur;
           UINT8   ptr[D88_TRACKMAX][4];
   
           if ((track >= D88_TRACKMAX) || (size == 0)) {
                   return(FAILURE);
           }
   
           fh = file_open(fdd->fname);
           if (fh == FILEH_INVALID) {
                   return(FAILURE);
           }
           curptr = fdd->inf.d88.ptr[track];
           if (curptr == 0) {
                   for (i=track; i>0;) {                                   // 新規トラック
                           curptr = fdd->inf.d88.ptr[--i];
                           if (curptr) {
                                 break;                                  break;
                         }                          }
                         if (sec->r == r) {                  }
                                 return((D88SEC)sec);                  if (curptr) {                                                           // ヒットした
                         }                          curptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size);
                         secnum++;                  }
                         sectors = LOADINTELWORD(sec->sectors);                  else {
                         if (secnum >= sectors) {                          curptr = D88_HEADERSIZE;
                                 break;                  }
                   nextptr = curptr;
           }
           else {                                                                          // トラックデータは既にある
                   nextptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size);
           }
           cursize = nextptr - curptr;
           if (size > cursize) {
                   addsize = size - cursize;
                   fileappend(fh, curptr, addsize);
                   fdd->inf.d88.fd_size += addsize;
                   for (i=0; i<D88_TRACKMAX; i++) {
                           cur = fdd->inf.d88.ptr[i];
                           if ((cur) && (cur >= curptr)) {
                                   fdd->inf.d88.ptr[i] = cur + addsize;
                         }                          }
                         sec = (D88SEC)(((UINT8 *)sec) + size);                  }
                 } while(secnum < 40);  
         }          }
         return(NULL);          STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size);
           fdd->inf.d88.ptr[track] = curptr;
           for (i=0; i<D88_TRACKMAX; i++) {
                   STOREINTELDWORD(ptr[i], fdd->inf.d88.ptr[i]);
           }
           file_seek(fh, 0, FSEEK_SET);
           file_write(fh, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head));
           file_write(fh, ptr, sizeof(ptr));
           file_seek(fh, curptr, FSEEK_SET);
           file_write(fh, buf, size);
           file_close(fh);
           return(SUCCESS);
 }  }
   
   
Line 246  fd8w_err: Line 350  fd8w_err:
         return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);          return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
 }  }
   
   static REG8 fddd88_wrtrk(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
                                                                                                   const UINT8 *ptr, UINT size) {
   
           UINT    pos;
           UINT    i;
           UINT    datsize;
           D88SEC  dst;
   
           trackflush(&d88trk);
   
           // データ作る
           ZeroMemory(d88trk.buf, sizeof(d88trk.buf));
           pos = 0;
           for (i=0; i<sc; i++) {
                   dst = (D88SEC)(d88trk.buf + pos);
                   datsize = LOADINTELWORD(((TAOSEC *)ptr)->size);
                   pos += sizeof(_D88SEC) + datsize;
                   if (pos > D88BUFSIZE) {
                           goto fd8wt_err;
                   }
                   dst->c = ((TAOSEC *)ptr)->c;
                   dst->h = ((TAOSEC *)ptr)->h;
                   dst->r = ((TAOSEC *)ptr)->r;
                   dst->n = ((TAOSEC *)ptr)->n;
                   dst->sectors[0] = sc;
                   STOREINTELWORD(dst->size, datsize);
                   CopyMemory((dst + 1), ptr + sizeof(TAOSEC), datsize);
                   ptr += sizeof(TAOSEC) + datsize;
           }
           if (writetrack(fdd, media, track, d88trk.buf, pos) != SUCCESS) {
                   goto fd8wt_err;
           }
           return(0);
   
   fd8wt_err:
           return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
   }
   
 static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,  static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,
                                                                                                 UINT8 *ptr) {                                                                                                  UINT8 *ptr) {
   
 const _D88TRK   *trk;  const _D88TRK   *trk;
 const _D88SEC   *sec;  const _D88SEC   *sec;
         UINT            secnum;  
         UINT            rem;  
         UINT            size;  
         UINT            sectors;          UINT            sectors;
           UINT            size;
   
         trk = trackseek(fdd, media, track);          trk = trackseek(fdd, media, track);
         if (trk == NULL) {          if (trk == NULL) {
                 return(FDDSTAT_RECNFND);                  return(FDDSTAT_RECNFND);
         }          }
         sec = (D88SEC)trk->buf;          sec = (D88SEC)trk->buf;
         sectors = LOADINTELWORD(sec->sectors);          sectors = trk->sectors;
         if (sectors == 0) {          if (num >= sectors) {
                 return(FDDSTAT_RECNFND);                  return(FDDSTAT_RECNFND);
         }          }
         secnum = 0;          while(num) {
         rem = trk->size;                  num--;
         while(1) {  
                 size = LOADINTELWORD(sec->size);                  size = LOADINTELWORD(sec->size);
                 size += sizeof(_D88SEC);                  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);                  sec = (D88SEC)(((UINT8 *)sec) + size);
         }          }
         ptr[0] = sec->c;          ptr[0] = sec->c;
Line 296  const _D88SEC *sec; Line 424  const _D88SEC *sec;
         return(0x00);          return(0x00);
 }  }
   
   #if defined(SUPPORT_DISKEXT)
   static UINT32 fddd88_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) {
   
   const _D88TRK   *trk;
   const _D88SEC   *sec;
           UINT            sectors;
           UINT            num;
           UINT            size;
   
           trk = trackseek(fdd, media, track);
           if (trk == NULL) {
                   return(0);
           }
           sec = (D88SEC)trk->buf;
           sectors = trk->sectors;
           num = 0;
           while(num < sectors) {
                   if (sec->r == sc) {
                           break;
                   }
                   size = LOADINTELWORD(sec->size);
                   size += sizeof(_D88SEC);
                   sec = (D88SEC)(((UINT8 *)sec) + size);
                   num++;
           }
           return((UINT32)(sectors << 16) + num);
   }
   #endif
   
   
 // ----  // ----
   
Line 303  BRESULT fddd88_set(FDDFILE fdd, const OE Line 460  BRESULT fddd88_set(FDDFILE fdd, const OE
   
         short   attr;          short   attr;
         FILEH   fh;          FILEH   fh;
         BOOL    r;          BRESULT r;
         UINT8   ptr[D88_TRACKMAX][4];          UINT8   ptr[D88_TRACKMAX][4];
         UINT    i;          UINT    i;
   
Line 334  BRESULT fddd88_set(FDDFILE fdd, const OE Line 491  BRESULT fddd88_set(FDDFILE fdd, const OE
         fdd->seek = fddd88_seek;          fdd->seek = fddd88_seek;
         fdd->read = fddd88_read;          fdd->read = fddd88_read;
         fdd->write = fddd88_write;          fdd->write = fddd88_write;
           fdd->wrtrk = fddd88_wrtrk;
         fdd->crc = fddd88_crc;          fdd->crc = fddd88_crc;
   #if defined(SUPPORT_DISKEXT)
           fdd->sec = fddd88_sec;
   #endif
         return(SUCCESS);          return(SUCCESS);
   
 fdst_err:  fdst_err:
Line 346  void fddd88_eject(FDDFILE fdd) { Line 507  void fddd88_eject(FDDFILE fdd) {
         drvflush(fdd);          drvflush(fdd);
 }  }
   
   
   
   
   
   
   
   
   
   
   
   
 // ---------------------------------------------------------------------------  
   
 #if 0  
 // ----  
   
 static  _D88SEC         cursec;  
 static  REG8            curdrv = (REG8)-1;  
 static  UINT            curtrk = (UINT)-1;  
 static  BYTE            curtype = 0;  
 static  UINT            cursct = (UINT)-1;  
 static  long            curfp = 0;  
 static  UINT            cursize = 0;  
 static  BYTE            curwrite = 0;  
 static  BYTE            curtrkerr = 0;  
 static  BYTE            hole = 0;  
 static  BYTE            *curdata;  
 // static       UINT            crcnum = 0;  
 // static       BYTE            crcerror = FALSE;  
   
 extern  WORD            readdiag;  
   
 #define         TAO_MODE_GAP    0x4e  
 #define         TAO_MODE_SYNC   0x00  
 #define         TAO_MODE_AM             0xf5  
 #define         TAO_MODE_IM             0xf6  
 #define         TAO_MODE_ID             0xfe  
 #define         TAO_MODE_DATA   0xfb  
 #define         TAO_ENDOFDATA   0xf7  
   
 #define         TAO_CMD_GAP             0x4e  
 #define         TAO_CMD_SYNC    0x00  
 #define         TAO_CMD_IM_IN   0xf6  
 #define         TAO_CMD_IM              0xfc  
 #define         TAO_CMD_AM_IN   0xf5  
 #define         TAO_CMD_IAM             0xfe  
 #define         TAO_CMD_DAM             0xfb  
 #define         TAO_CMD_DDAM    0xf8  
 #define         TAO_CMD_CRC             0xf7  
   
 typedef struct {  
         BYTE    mode;  
         BYTE    flag;  
         WORD    cnt;  
         WORD    size;  
         WORD    ptr;  
         WORD    top;  
         WORD    gap;  
         BYTE    sector;  
         WORD    lostdatacnt;  
         BYTE    maxsector;  
         WORD    maxsize;  
 } WID_PARA;  
   
 #define LOSTDATA_COUNT  256  
   
 static  WID_PARA WID_2D = {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 33, 0x1f80};  
 static  WID_PARA WID_2HD= {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 55, 0x2f80};  
 static  WID_PARA WID_ERR= {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0,  0, 0x0000};  
 static  WID_PARA tao    = {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0,  0, 0x0000};  
   
 static  BYTE            D88_BUF[0x4000];  
 static  BYTE            TAO_BUF[0x3000];  
   
   
 //----------------------------------------------------------------------  
   
   
 static int curdataflush(void) {  
   
         FDDFILE fdd;  
         FILEH   fh;  
         int             ret = 0;  
   
         if ((!curfp) || (!cursize)) {  
                 return(-1);  
         }  
         if (!curwrite) {  
                 return(0);  
         }  
         curwrite = 0;  
         fdd = fddfile + curdrv;  
         fh = file_open(fdd->fname);  
         if (fh == FILEH_INVALID) {  
                 return(-1);  
         }  
         if ((file_seek(fh, curfp, FSEEK_SET) != curfp) ||  
                 (file_write(fh, D88_BUF, cursize) != cursize)) {  
                 ret = -1;  
         }  
         if (file_close(fh)) {  
                 ret = -1;  
         }  
         return(ret);  
 }  
   
   
 static DWORD read_d88track(REG8 drv, UINT track, REG8 media) {  
   
         FDDFILE fdd;  
         FILEH   hdr;  
   
         curdataflush();  
         curdrv = drv;  
         curtrk = track;  
         curtype = media;  
         cursct = (UINT)-1;  
         curwrite = 0;  
         curtrkerr = 0;  
 //      crcnum = 0;  
         crcerror = 0;  
   
         fdd = fddfile + drv;  
         if ((drv < 0) || (drv > 3) || (track > 163) ||  
                 (media != (fdd->inf.d88.head.fd_type >> 4)) ||  
                 ((curfp = fdd->inf.d88.ptr[track]) == 0) ||  
                 ((cursize = nexttrackptr(fdd, curfp,  
                                                                 fdd->inf.d88.fd_size) - curfp) > 0x4000)) {  
                 goto readd88_err;  
         }  
   
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {  
                 goto readd88_err;  
         }  
         if (file_seek(hdr, curfp, FSEEK_SET) != curfp) {  
                 file_close(hdr);  
                 goto readd88_err;  
         }  
         if (file_read(hdr, D88_BUF, cursize) != cursize) {  
                 file_close(hdr);  
                 goto readd88_err;  
         }  
         if (file_close(hdr)) {  
                 goto readd88_err;  
         }  
         return(TRUE);  
   
 readd88_err:  
         curfp = 0;  
         cursize = 0;  
         curtrkerr = 1;  
         return(FALSE);  
 }  
   
   
   
   
 static int seeksector(REG8 drv, UINT track, UINT r) {  
   
 static  int             lastflag = FALSE;  
   
 const _D88SEC   *p;  
         UINT            sec;  
         UINT            sectors;  
         UINT            secsize;  
   
         if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.s.media)) {  
                 read_d88track(drv, track, fdc.s.media);  
         }  
         if (curtrkerr) {  
                 cursct = r;  
                 goto seekerror;  
         }  
         if (cursct != r) {  
                 cursct = r;  
                 p = (D88SEC)D88_BUF;  
                 for (sec=0; sec<40; ) {  
                         sectors = LOADINTELWORD(p->sectors);  
                         secsize = LOADINTELWORD(p->size);  
                         if (p->r == r) {  
                                 CopyMemory(&cursec, p, sizeof(_D88SEC));  
                                 curdata = (UINT8 *)(p + 1);  
                                 lastflag = TRUE;  
                                 break;  
                         }  
                         sec++;  
                         if (sec >= sectors) {  
                                 goto seekerror;  
                         }  
                         p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);  
                 }  
                 if (sec >= 40) {  
                         goto seekerror;  
                 }  
         }  
         return(lastflag);  
   
 seekerror:;  
         ZeroMemory(&cursec, sizeof(_D88SEC));  
         curdata = &D88_BUF[16];  
         lastflag = FALSE;  
         return(FALSE);  
 }  
   
   
 // ----  
   
   
   
   
 //**********************************************************************  
   
   
   
 BYTE fdd_stat_d88(void) {  
   
         FDDFILE         fdd;  
         BYTE            type;  
         REG8            cmd;  
         UINT            trk;  
         BYTE            ans = 0;  
         int                     seekable;  
   
         fdd = fddfile + fdc.s.drv;  
         if (fdd->type != DISKTYPE_D88) {  
                 return(0x80);                                           // NOT READY  
         }  
         cmd = (REG8)(fdc.s.cmd >> 4);  
         type = fdc.s.type;  
         trk = (fdc.s.c << 1) + fdc.s.h;  
         seekable = seeksector(fdc.s.drv, trk, fdc.s.r);  
         if (!fdc.s.r) {  
                 seekable = TRUE;  
         }  
   
         if (type == 0 || type == 1 || type == 4 ||  
                 cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) {  
                 if (fdd->protect) {                                     // WRITE PROTECT  
                         ans |= 0x40;  
                 }  
         }  
         if (type == 2 || cmd == 0x0f) {  
                 if (fdc.s.r && cursec.del_flg) {  
                         ans |= 0x20;                                    // RECODE TYPE / WRITE FAULT  
                 }  
         }  
         if (type == 1 || type == 2) {  
                 if ((trk > 163) || (!seekable)) {  
                         ans |= 0x10;                                    // SEEK ERROR / RECORD NOT FOUND  
                 }  
                 if ((!(ans & 0xf0)) && fdc.s.r && (cursec.stat)) {  
                         ans |= 0x08;                                    // CRC ERROR  
                 }  
         }  
         if (cmd == 0x0c) {  
                 if (curtrkerr) {  
                         ans |= 0x10;  
                 }  
                 if (crcerror) {  
                         ans |= 0x08;                                    // CRC ERROR  
                 }  
         }  
         if (type == 1 || type == 4) {  
                 if (type == 1) {                                        // ver0.25  
                         ans |= 0x20;                                    // HEAD ENGAGED (X1 デハ ツネニ 1)  
                         if (!fdc.s.c) {                                 // TRACK00  
                                 ans |= 0x04;  
                         }  
                 }  
                 if (++hole < 8) {                                       // ver0.25  
                         ans |= 0x02;                                    // INDEX  
                 }  
         }  
         else if (!(ans & 0xf0)) {  
                 if ((type != 4) && (FDDMTR_BUSY)) {  
                         ans |= 0x01;  
                 }  
                 if (type == 2) {  
                         UINT secsize = LOADINTELWORD(cursec.size);  
                         if ((UINT)fdc.off < secsize) {  
                                 ans |= 0x03;                                    // DATA REQUEST / BUSY  
                         }  
                 }  
                 else if ((cmd == 0x0c) && (fdc.s.bufpos < 6)) {  
                         ans |= 0x03;  
                 }  
                 else if ((cmd == 0x0e) && (readdiag < 0x1a00)) {  
                         ans |= 0x03;  
                 }  
                 else if (cmd == 0x0f) {  
                         if (tao.flag == 3) {  
                                 if (++tao.lostdatacnt > LOSTDATA_COUNT) {  
                                         tao.flag = 4;  
                                 }  
                         }  
                         ans |= tao.flag;  
                 }  
         }  
         return(ans);  
 }  
   
   
 //**********************************************************************  
   
 void fdd_read_d88(void) {  
                                                 // POCO:読めなかったらレジスタを変更させない  
         if ((fdd_stat_d88() & 0xf3) == 3) {  
                 fdc.s.data = curdata[fdc.off];  
         }  
 }  
   
 void fdd_write_d88(void) {  
   
         if ((fdd_stat_d88() & 0xf3) == 3) {  
                 curdata[fdc.off] = fdc.s.data;  
                 curwrite = 1;  
         }  
 }  
   
 BYTE fdd_incoff_d88(void) {  
   
         REG8    cmd;  
         UINT    trk;  
         UINT    secsize;  
   
         cmd = (REG8)(fdc.s.cmd >> 4);  
         trk = (fdc.s.c << 1) + fdc.s.h;  
         seeksector(fdc.s.drv, trk, fdc.s.r);  
         fdc.off++;  
         secsize = LOADINTELWORD(cursec.size);  
         if ((UINT)fdc.off < secsize) {  
                 return(0);  
         }  
         fdc.off = secsize;  
         if ((cmd == 0x09) || (cmd == 0x0b)) {  
                 fdc.s.rreg = fdc.s.r + 1;                                               // ver0.25  
                 if (seeksector(fdc.s.drv, trk, fdc.s.rreg)) {  
                         fdc.s.r++;  
                         fdc.off = 0;  
                         return(0);  
                 }  
         }  
         return(1);  
 }  
   
   
 // ---------------------------------------------------------------------------  
   
 void init_tao_d88(void) {  
   
         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;  
         }  
         else if (fdc.s.media == DISKTYPE_2HD) {  
                 tao = WID_2HD;  
         }  
         else {  
                 tao = WID_ERR;  
         }  
 }  
   
 static int fileappend(FILEH hdl, FDDFILE fdd,  
                                                                         UINT32 ptr, long last, long apsize) {  
   
         long    length;  
         UINT    size;  
         UINT    rsize;  
         UINT    t;  
         BYTE    tmp[0x400];  
         UINT32  cur;  
   
         length = last - ptr;  
         if (length <= 0) {                                                      // 書き換える必要なし  
                 return(0);  
         }  
         while(length) {  
                 if (length >= (long)(sizeof(tmp))) {  
                         size = sizeof(tmp);  
                 }  
                 else {  
                         size = length;  
                 }  
                 length -= size;  
                 file_seek(hdl, ptr + length, FSEEK_SET);  
                 rsize = file_read(hdl, tmp, size);  
                 file_seek(hdl, ptr + length + apsize, FSEEK_SET);  
                 file_write(hdl, tmp, rsize);  
         }  
         for (t=0; t<164; t++) {  
                 cur = fdd->inf.d88.ptr[t];  
                 if ((cur) && (cur >= ptr)) {  
                         fdd->inf.d88.ptr[t] = cur + apsize;  
                 }  
         }  
         return(0);  
 }  
   
 static void endoftrack(void) {  
   
         FDDFILE fdd;  
         FILEH   hdr;  
         int             i;  
         UINT    trk;  
         long    fpointer;  
         long    endpointer;  
         long    lastpointer;  
         long    trksize;  
         long    apsize;  
         D88SEC  p;  
         UINT    secsize;  
         UINT8   ptr[D88_TRACKMAX][4];  
   
         if (!tao.sector) {  
                 tao.flag = 4;  
                 return;  
         }  
         tao.flag = 0;  
   
         curdataflush();                                         // write cache flush &  
         curdrv = (REG8)-1;                                      // use D88_BUF[] for temp  
   
         fdd = fddfile + fdc.s.drv;  
         trk = (fdc.s.c << 1) + fdc.s.h;  
   
         p = (D88SEC)TAO_BUF;  
         for (i=0; i<(int)tao.sector; i++) {  
                 STOREINTELWORD(p->sectors, tao.sector);  
                 secsize = LOADINTELWORD(p->size);  
                 p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);  
         }  
   
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {  
                 return;  
         }  
         lastpointer = file_seek(hdr, 0, 2);  
         fpointer = fdd->inf.d88.ptr[trk];  
         if (fpointer == 0) {  
                 for (i=trk; i>=0; i--) {                                        // 新規トラック  
                         fpointer = fdd->inf.d88.ptr[i];  
                         if (fpointer) {  
                                 break;  
                         }  
                 }  
                 if (fpointer) {                                                         // ヒットした  
                         fpointer = nexttrackptr(fdd, fpointer, lastpointer);  
                 }  
                 else {  
                         fpointer = D88_HEADERSIZE;  
                 }  
                 endpointer = fpointer;  
         }  
         else {                                                                          // トラックデータは既にある  
                 endpointer = nexttrackptr(fdd, fpointer, lastpointer);  
         }  
         trksize = endpointer - fpointer;  
         if ((apsize = (long)tao.size - trksize) > 0) {  
                                                                 // 書き込むデータのほーが大きい  
                 fileappend(hdr, fdd, endpointer, lastpointer, apsize);  
                 fdd->inf.d88.fd_size += apsize;  
         }  
         STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size);  
         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_close(hdr);  
 }  
   
 void fdd_wtao_d88(BYTE data) {  
   
         D88SEC  p;  
   
         if (tao.flag != 3) {  
                 return;  
         }  
         tao.lostdatacnt = 0;  
         if (tao.cnt > tao.maxsize) {  
                 endoftrack();  
                 return;  
         }  
         tao.cnt++;  
         switch(tao.mode) {  
                 case TAO_ENDOFDATA:  
                         if (data == TAO_MODE_GAP) {  
                                 tao.mode = TAO_MODE_GAP;  
                                 tao.gap = 0;  
                         }  
                         break;  
   
                 case TAO_MODE_GAP:  
                         if (data == TAO_MODE_GAP) {  
                                 if (tao.gap++ > 256) {  
                                         endoftrack();  
                                 }  
                         }  
                         else if (data == TAO_CMD_SYNC) {  
                                 tao.mode = TAO_MODE_SYNC;  
                         }  
 #if 1                                                                                           // ver0.26 Zeliard  
                         else if (data == 0xf4) {  
                                 endoftrack();  
                         }  
 #endif  
                         else {  
                                 tao.flag = 4;  
                         }  
                         break;  
   
                 case TAO_MODE_SYNC:  
 //                      tao.cnt--;                                                              // ver0.26 Zeliard  
                         if (data == TAO_CMD_AM_IN) {  
                                 tao.mode = TAO_MODE_AM;  
                         }  
                         else if (data == TAO_CMD_IM_IN) {  
                                 tao.mode = TAO_MODE_IM;  
                         }  
                         else if (data) {  
                                 tao.flag = 4;  
                         }  
                         break;  
   
                 case TAO_MODE_IM:  
                         if (data == TAO_CMD_IM) {  
                                 tao.mode = TAO_ENDOFDATA;  
                         }  
                         else if (data != TAO_CMD_IM_IN) {  
                                 tao.flag = 4;  
                         }  
                         break;  
   
                 case TAO_MODE_AM:  
                         if (data == TAO_CMD_IAM) {  
                                 tao.mode = TAO_MODE_ID;  
                                 tao.ptr = 0;  
                                 tao.top = tao.size;  
                         }  
                         else if (data == TAO_CMD_DAM) {  
                                 tao.mode = TAO_MODE_DATA;  
                                 tao.ptr = 0;  
                         }  
                         else if (data == TAO_CMD_DDAM) {  
                                 tao.mode = TAO_MODE_DATA;  
                                 tao.ptr = 0;  
                                 p = (D88SEC)(TAO_BUF + tao.top);  
                                 p->del_flg = 1;  
                         }  
                         break;  
   
                 case TAO_MODE_ID:  
                         if ((data == TAO_CMD_IAM) && (!tao.ptr)) {  
                                 break;  
                         }  
                         else if (tao.ptr < 4) {  
                                 TAO_BUF[tao.size++] = data;  
                                 tao.ptr++;  
                         }  
                         else if (data == TAO_CMD_CRC) {  
                                 tao.mode = TAO_ENDOFDATA;  
                                 ZeroMemory(TAO_BUF + tao.size, 12);  
                                 tao.size += 12;  
                         }  
                         break;  
   
                 case TAO_MODE_DATA:                                             // DATA WRITE  
                         if ((!tao.ptr) &&  
                                 ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) {  
                                 break;  
                         }  
                         else if (data == TAO_CMD_CRC) {                 // nで判定した方が無難か?  
                                 tao.mode = TAO_ENDOFDATA;  
                                 p = (D88SEC)(TAO_BUF + tao.top);  
                                 STOREINTELWORD(p->size, tao.ptr);  
                                 if (tao.sector++ > tao.maxsector) {  
                                         tao.flag = 4;  
                                 }  
                         }  
                         else {  
                                 TAO_BUF[tao.size++] = data;  
                                 tao.ptr++;  
                         }  
                         break;  
         }  
 }  
 #endif  
   

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


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