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

version 1.4, 2004/08/04 15:18:26 version 1.15, 2005/02/04 06:42:11
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
 #include        "dosio.h"  #include        "dosio.h"
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  
 #include        "fddfile.h"  #include        "fddfile.h"
 #include        "fdd_d88.h"  #include        "fdd_d88.h"
 #include        "fdd_mtr.h"  #include        "fdd_mtr.h"
   
   
 static  D88_HEADER      d88head[4];  enum {
 static  _D88SEC         cursec;          D88BUFSIZE              = 0x4000
 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 {  typedef struct {
         BYTE    mode;          FDDFILE fdd;
         BYTE    flag;          UINT8   media;
         WORD    cnt;          UINT8   write;
         WORD    size;          UINT8   padding[2];
         WORD    ptr;          UINT    track;
         WORD    top;          long    fptr;
         WORD    gap;          UINT    size;
         BYTE    sector;          UINT    sectors;
         WORD    lostdatacnt;          UINT8   buf[D88BUFSIZE];
         BYTE    maxsector;  } _D88TRK, *D88TRK;
         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  _D88TRK         d88trk;
   
 //----------------------------------------------------------------------  
   
 static UINT32 nexttrackp(D88_HEADER *head, UINT32 fptr, UINT32 last) {  static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) {
   
         UINT    t;          UINT    t;
 const DWORD     *trkp;  
         UINT32  cur;          UINT32  cur;
   
         trkp = (DWORD *)head->trackp;  
         for (t=0; t<164; t++) {          for (t=0; t<164; t++) {
                 cur = trkp[t];                  cur = fdd->inf.d88.ptr[t];
                 if ((cur > fptr) && (cur < last)) {                  if ((cur > fptr) && (cur < last)) {
                         last = cur;                          last = cur;
                 }                  }
Line 85  const DWORD *trkp; Line 39  const DWORD *trkp;
         return(last);          return(last);
 }  }
   
   static BRESULT trackflush(D88TRK trk) {
 int curdataflush(void) {  
   
         FDDFILE fdd;          FDDFILE fdd;
         FILEH   fh;          FILEH   fh;
         int             ret = 0;  
   
         if ((!curfp) || (!cursize)) {          fdd = trk->fdd;
                 return(-1);          trk->fdd = NULL;
           if ((fdd == NULL) || (trk->size == 0) || (!trk->write)) {
                   goto dtfd_exit;
         }          }
         if (!curwrite) {  
                 return(0);  
         }  
         curwrite = 0;  
         fdd = fddfile + curdrv;  
         fh = file_open(fdd->fname);          fh = file_open(fdd->fname);
         if (fh == FILEH_INVALID) {          if (fh == FILEH_INVALID) {
                 return(-1);                  goto dtfd_err1;
         }  
         if ((file_seek(fh, curfp, FSEEK_SET) != curfp) ||  
                 (file_write(fh, D88_BUF, cursize) != cursize)) {  
                 ret = -1;  
         }          }
         if (file_close(fh)) {          if ((file_seek(fh, trk->fptr, FSEEK_SET) != trk->fptr) ||
                 ret = -1;                  (file_write(fh, trk->buf, trk->size) != trk->size)) {
                   goto dtfd_err2;
         }          }
         return(ret);          file_close(fh);
 }          trk->write = FALSE;
   
   dtfd_exit:
           return(SUCCESS);
   
 static DWORD read_d88track(REG8 drv, UINT track, BYTE type) {  dtfd_err2:
           file_close(fh);
   
         FDDFILE fdd;  dtfd_err1:
         FILEH   hdr;          return(FAILURE);
   }
   
         curdataflush();  static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) {
         curdrv = drv;  
         curtrk = track;  
         curtype = type;  
         cursct = (UINT)-1;  
         curwrite = 0;  
         curtrkerr = 0;  
         crcnum = 0;  
         crcerror = 0;  
   
         if ((drv < 0) || (drv > 3) || (track > 163) ||          FILEH           fh;
                 ((type == 0) && (d88head[drv].fd_type == 0x20)) ||          UINT32          fptr;
                 ((type == 1) && (d88head[drv].fd_type != 0x20)) ||          UINT            size;
                 ((curfp = d88head[drv].trackp[track]) == 0) ||  const _D88SEC   *sec;
                 ((cursize = nexttrackp(&d88head[drv], curfp,          UINT            rem;
                                                                 d88head[drv].fd_size) - curfp) > 0x4000)) {          UINT            maxsectors;
                 goto readd88_err;          UINT            sectors;
         }          UINT            secsize;
   
         fdd = fddfile + drv;          trackflush(trk);
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {          if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) {
                 goto readd88_err;                  goto dtrd_err1;
         }          }
         if (file_seek(hdr, curfp, FSEEK_SET) != curfp) {          if (track >= 164) {
                 file_close(hdr);                  goto dtrd_err1;
                 goto readd88_err;  
         }          }
         if (file_read(hdr, D88_BUF, cursize) != cursize) {          fptr = fdd->inf.d88.ptr[track];
                 file_close(hdr);          if (fptr == 0) {
                 goto readd88_err;                  goto dtrd_err1;
         }          }
         if (file_close(hdr)) {          size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr;
                 goto readd88_err;          if (size > D88BUFSIZE) {
                   size = D88BUFSIZE;
         }          }
         return(TRUE);          fh = file_open_rb(fdd->fname);
           if (fh == FILEH_INVALID) {
 readd88_err:                  goto dtrd_err1;
         curfp = 0;          }
         cursize = 0;          if ((file_seek(fh, (long)fptr, FSEEK_SET) != (long)fptr) ||
         curtrkerr = 1;                  (file_read(fh, trk->buf, size) != size)) {
         return(FALSE);                  goto dtrd_err2;
 }          }
           file_close(fh);
   
           trk->fdd = fdd;
           trk->media = media;
           trk->write = FALSE;
           trk->track = track;
           trk->fptr = fptr;
           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);
   
   dtrd_err2:
           file_close(fh);
   
 static int seeksector(REG8 drv, UINT track, UINT r) {  dtrd_err1:
           return(NULL);
   }
   
 static  int             lastflag = FALSE;  static void drvflush(FDDFILE fdd) {
   
 const _D88SEC   *p;          D88TRK  trk;
         UINT            sec;  
         UINT            sectors;  
         UINT            secsize;  
   
         if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.media)) {          trk = &d88trk;
                 read_d88track(drv, track, fdc.media);          if (trk->fdd == fdd) {
                   trackflush(trk);
         }          }
         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);  
 }  }
   
 static void drvflush(REG8 drv) {  static D88TRK trackseek(FDDFILE fdd, REG8 media, UINT track) {
   
           D88TRK  trk;
   
         if (curdrv == drv) {          trk = &d88trk;
                 curdataflush();          if ((trk->fdd != fdd) || (trk->media != media) || (trk->track != track)) {
                 curdrv = (REG8)-1;                  trk = trackread(trk, fdd, media, track);
                 curtrk = (UINT)-1;  
                 cursct = (UINT)-1;  
         }          }
           return(trk);
 }  }
   
   static D88SEC sectorseek(const _D88TRK *trk, REG8 r) {
   
   const _D88SEC   *sec;
           UINT            sectors;
           UINT            size;
   
           sec = (D88SEC)trk->buf;
           sectors = trk->sectors;
           while(sectors) {
                   sectors--;
                   if (sec->r == r) {
                           return((D88SEC)sec);
                   }
                   size = LOADINTELWORD(sec->size);
                   size += sizeof(_D88SEC);
                   sec = (D88SEC)(((UINT8 *)sec) + size);
           }
           return(NULL);
   }
   
 //**********************************************************************  
   
 short fdd_crc_d88(void) {  // ----
   
         UINT            track;  static BRESULT fileappend(FILEH fh, UINT32 ptr, UINT size) {
 const _D88SEC   *p;  
         UINT            sec;  
         UINT            sectors;  
         UINT            secsize;  
   
         ZeroMemory(fdc.crc_dat, 6);          UINT    filesize;
         track = (fdc.c << 1) + fdc.h;          UINT    r;
         if (track >= 164) {          UINT8   work[0x400];
                 goto crcerror_d88;  
         }          filesize = file_getsize(fh);
         seeksector(fdc.drv, track, fdc.r);          if (filesize < ptr) {
         if (curtrkerr) {                  return(FAILURE);
                 goto crcerror_d88;          }
         }          filesize -= ptr;
         p = (D88SEC)D88_BUF;          while(filesize) {
         for (sec=0; sec<crcnum;) {                  r = min(filesize, sizeof(work));
                 sectors = LOADINTELWORD(p->sectors);                  filesize -= r;
                 secsize = LOADINTELWORD(p->size);                  file_seek(fh, ptr + filesize, FSEEK_SET);
                 sec++;                  r = file_read(fh, work, r);
                 if (sec >= sectors) {                  file_seek(fh, ptr + filesize + size, FSEEK_SET);
                         goto crcerror_d88;                  file_write(fh, work, r);
                 }  
                 p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);  
         }          }
         fdc.rreg = p->c;                                                                // メルヘンヴェール          return(SUCCESS);
         fdc.crc_dat[0] = p->c;  
         fdc.crc_dat[1] = p->h;  
         fdc.crc_dat[2] = p->r;  
         fdc.crc_dat[3] = p->n;  
         crcnum++;  
         if (p->stat) {  
                 crcerror = TRUE;  
         }  
         else {  
                 crcerror = FALSE;  
         }  
         return(0);  
   
 crcerror_d88:;  
         crcerror = TRUE;  
         return(1);  
 }  }
   
   static BRESULT writetrack(FDDFILE fdd, REG8 media, UINT track,
                                                                                                           UINT8 *buf, UINT size) {
   
 BYTE fdd_stat_d88(void) {          FILEH   fh;
           UINT    i;
         FDDFILE         fdd;          UINT32  curptr;                         // fpointer;
         BYTE            type;          UINT32  nextptr;                        // endpointer;
         REG8            cmd;          UINT    cursize;
         UINT            trk;          UINT    addsize;
         BYTE            ans = 0;          UINT32  cur;
         int                     seekable;          UINT8   ptr[D88_TRACKMAX][4];
   
         fdd = fddfile + fdc.drv;          if ((track >= D88_TRACKMAX) || (size == 0)) {
         if (fdd->type != DISKTYPE_D88) {                  return(FAILURE);
                 return(0x80);                                           // NOT READY  
         }  
         type = fdc.type;  
         cmd = (REG8)(fdc.cmd >> 4);  
         trk = (fdc.c << 1) + fdc.h;  
         seekable = seeksector(fdc.drv, trk, fdc.r);  
         if (!fdc.r) {  
                 seekable = TRUE;  
         }          }
   
         if (type == 0 || type == 1 || type == 4 ||          fh = file_open(fdd->fname);
                 cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) {          if (fh == FILEH_INVALID) {
                 if (fdd->protect) {                                     // WRITE PROTECT                  return(FAILURE);
                         ans |= 0x40;  
                 }  
         }  
         if (type == 2 || cmd == 0x0f) {  
                 if (fdc.r && cursec.del_flg) {  
                         ans |= 0x20;                                    // RECODE TYPE / WRITE FAULT  
                 }  
         }          }
         if (type == 1 || type == 2) {          curptr = fdd->inf.d88.ptr[track];
                 if ((trk > 163) || (!seekable)) {          if (curptr == 0) {
                         ans |= 0x10;                                    // SEEK ERROR / RECORD NOT FOUND                  for (i=track; i>0;) {                                   // 新規トラック
                 }                          curptr = fdd->inf.d88.ptr[--i];
                 if ((!(ans & 0xf0)) && fdc.r && (cursec.stat)) {                          if (curptr) {
                         ans |= 0x08;                                    // CRC ERROR                                  break;
                           }
                 }                  }
         }                  if (curptr) {                                                           // ヒットした
         if (cmd == 0x0c) {                          curptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size);
                 if (curtrkerr) {  
                         ans |= 0x10;  
                 }                  }
                 if (crcerror) {                  else {
                         ans |= 0x08;                                    // CRC ERROR                          curptr = D88_HEADERSIZE;
                 }                  }
                   nextptr = curptr;
         }          }
         if (type == 1 || type == 4) {          else {                                                                          // トラックデータは既にある
                 if (type == 1) {                                        // ver0.25                  nextptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size);
                         ans |= 0x20;                                    // HEAD ENGAGED (X1 デハ ツネニ 1)  
                         if (!fdc.c) {                                   // TRACK00  
                                 ans |= 0x04;  
                         }  
                 }  
                 if (++hole < 8) {                                       // ver0.25  
                         ans |= 0x02;                                    // INDEX  
                 }  
         }          }
         else if (!(ans & 0xf0)) {          cursize = nextptr - curptr;
                 if ((type != 4) && (FDDMTR_BUSY)) {          if (size > cursize) {
                         ans |= 0x01;                  addsize = size - cursize;
                 }                  fileappend(fh, curptr, addsize);
                 if (type == 2) {                  fdd->inf.d88.fd_size += addsize;
                         UINT secsize = LOADINTELWORD(cursec.size);                  for (i=0; i<D88_TRACKMAX; i++) {
                         if ((UINT)fdc.off < secsize) {                          cur = fdd->inf.d88.ptr[i];
                                 ans |= 0x03;                                    // DATA REQUEST / BUSY                          if ((cur) && (cur >= curptr)) {
                                   fdd->inf.d88.ptr[i] = cur + addsize;
                         }                          }
                 }                  }
                 else if ((cmd == 0x0e) && (readdiag < 0x1a00)) {  
                         ans |= 0x03;  
                 }  
                 else if ((cmd == 0x0c) && (fdc.crc_off < 6)) {          // ver0.25  
                         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.data = curdata[fdc.off];  
         }          }
           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);
 }  }
   
 void fdd_write_d88(void) {  
   
         if ((fdd_stat_d88() & 0xf3) == 3) {  // ----
                 curdata[fdc.off] = fdc.data;  
                 curwrite = 1;  
         }  
 }  
   
 BYTE fdd_incoff_d88(void) {  
   
         REG8    cmd;  static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) {
         UINT    trk;  
         UINT    secsize;  
   
         cmd = (REG8)(fdc.cmd >> 4);          if (trackseek(fdd, media, track) != NULL) {
         trk = (fdc.c << 1) + fdc.h;                  return(0x00);
         seeksector(fdc.drv, trk, fdc.r);  
         fdc.off++;  
         secsize = LOADINTELWORD(cursec.size);  
         if ((UINT)fdc.off < secsize) {  
                 return(0);  
         }          }
         fdc.off = secsize;          else {
         if ((cmd == 0x09) || (cmd == 0x0b)) {                  return(FDDSTAT_SEEKERR);
                 fdc.rreg = fdc.r + 1;                                           // ver0.25  
                 if (seeksector(fdc.drv, trk, fdc.rreg)) {  
                         fdc.r++;  
                         fdc.off = 0;  
                         return(0);  
                 }  
         }          }
         return(1);  
 }  }
   
   static REG8 fddd88_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
                                                                                                   UINT8 *ptr, UINT *size) {
   
 // ---------------------------------------------------------------------------  const _D88TRK   *trk;
   const _D88SEC   *sec;
 void init_tao_d88(void) {          UINT            secsize;
           REG8            ret;
   
         if ((fdc.media == 0) && (d88head[fdc.drv].fd_type != 0x20)) {          TRACEOUT(("d88 read %d:%.2x", track, sc));
                 tao = WID_2D;          trk = trackseek(fdd, media, track);
         }          if (trk == NULL) {
         else if ((fdc.media == 1) && (d88head[fdc.drv].fd_type == 0x20)) {                  goto fd8r_err;
                 tao = WID_2HD;          }
         }          sec = sectorseek(trk, sc);
         else {          if (sec == NULL) {
                 tao = WID_ERR;                  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);
 }  }
   
 int fileappend(FILEH hdr, D88_HEADER *head,  static REG8 fddd88_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
                                                                         long ptr, long last, long apsize) {                                                                                                  const UINT8 *ptr, UINT size) {
   
         long    length;          D88TRK  trk;
         WORD    size;          D88SEC  sec;
         WORD    rsize;          UINT    secsize;
         int             t;  
         long    *trkp;  
   
         if ((length = last - ptr) <= 0) {                       // 書き換える必要なし          TRACEOUT(("d88 write %d:%.2x", track, sc));
                 return(0);          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_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;
         }          }
         while(length) {          if (writetrack(fdd, media, track, d88trk.buf, pos) != SUCCESS) {
                 if (length >= 0x4000) {                  goto fd8wt_err;
                         size = 0x4000;  
                 }  
                 else {  
                         size = (WORD)length;  
                 }  
                 length -= (long)size;  
                 file_seek(hdr, ptr+length, 0);  
                 rsize = file_read(hdr, D88_BUF, size);  
                 file_seek(hdr, ptr+length+apsize, 0);  
                 file_write(hdr, D88_BUF, rsize);  
         }  
   
         trkp = head->trackp;  
         for (t=0; t<164; t++, trkp++) {  
                 if ((*trkp) && (*trkp >= ptr)) {  
                         (*trkp) += apsize;  
                 }  
         }          }
         return(0);          return(0);
 }  
   
   
   fd8wt_err:
           return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
   }
   
 void endoftrack(void) {  static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,
                                                                                                   UINT8 *ptr) {
   
         FDDFILE         fdd;  const _D88TRK   *trk;
         FILEH           hdr;  const _D88SEC   *sec;
         int                     i;          UINT            sectors;
         WORD            trk;          UINT            size;
         D88_HEADER      *head;  
         long            fpointer;  
         long            endpointer;  
         long            lastpointer;  
         long            trksize;  
         long            apsize;  
         D88SEC          p;  
         UINT            secsize;  
   
         if (!tao.sector) {          trk = trackseek(fdd, media, track);
                 tao.flag = 4;          if (trk == NULL) {
                 return;                  return(FDDSTAT_RECNFND);
         }          }
         tao.flag = 0;          sec = (D88SEC)trk->buf;
           sectors = trk->sectors;
         curdataflush();                                         // write cache flush &          if (num >= sectors) {
         curdrv = (REG8)-1;                                      // use D88_BUF[] for temp                  return(FDDSTAT_RECNFND);
           }
         head = &d88head[fdc.drv];          while(num) {
         trk = (fdc.c << 1) + fdc.h;                  num--;
                   size = LOADINTELWORD(sec->size);
         p = (D88SEC)TAO_BUF;                  size += sizeof(_D88SEC);
         for (i=0; i<(int)tao.sector; i++) {                  sec = (D88SEC)(((UINT8 *)sec) + size);
                 STOREINTELWORD(p->sectors, tao.sector);          }
                 secsize = LOADINTELWORD(p->size);          ptr[0] = sec->c;
                 p = (D88SEC)(((UINT8 *)(p + 1)) + secsize);          ptr[1] = sec->h;
         }          ptr[2] = sec->r;
           ptr[3] = sec->n;
         fdd = fddfile + fdc.drv;          ptr[4] = 0;
         if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) {          ptr[5] = 0;
                 return;  //      fdc.s.rreg = sec->c;                                                            // メルヘンヴェール
         }          if (sec->stat) {
         lastpointer = file_seek(hdr, 0, 2);                  return(FDDSTAT_CRCERR);
         if ((fpointer = head->trackp[trk]) == 0) {  
                 fpointer = 0;                                                           // 新規トラック  
                 for (i=trk; i>=0; i--) {  
                         if (head->trackp[i]) {  
                                 fpointer = head->trackp[i];  
                                 break;  
                         }  
                 }  
                 if (fpointer) {                                                         // ヒットした  
                         fpointer = nexttrackp(head, fpointer, lastpointer);  
                 }  
                 else {  
                         fpointer = sizeof(D88_HEADER);  
                 }  
                 endpointer = fpointer;  
         }          }
         else {                                                                          // トラックデータは既にある          return(0x00);
                 endpointer = nexttrackp(head, fpointer, lastpointer);  
         }  
         trksize = endpointer - fpointer;  
         if ((apsize = (long)tao.size - trksize) > 0) {  
                                                                 // 書き込むデータのほーが大きい  
                 fileappend(hdr, head, endpointer, lastpointer, apsize);  
                 head->fd_size += apsize;  
         }  
         head->trackp[trk] = fpointer;  
         file_seek(hdr, fpointer, 0);  
         file_write(hdr, TAO_BUF, tao.size);  
         file_seek(hdr, 0, 0);  
         file_write(hdr, head, sizeof(D88_HEADER));  
         file_close(hdr);  
 }  }
   
   #if defined(SUPPORT_DISKEXT)
   static UINT32 fddd88_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) {
   
 void fdd_wtao_d88(BYTE data) {  const _D88TRK   *trk;
   const _D88SEC   *sec;
         D88SEC  p;          UINT            sectors;
           UINT            num;
           UINT            size;
   
         if (tao.flag != 3) {          trk = trackseek(fdd, media, track);
                 return;          if (trk == NULL) {
         }                  return(0);
         tao.lostdatacnt = 0;  
         if (tao.cnt > tao.maxsize) {  
                 endoftrack();  
                 return;  
         }          }
         tao.cnt++;          sec = (D88SEC)trk->buf;
         switch(tao.mode) {          sectors = trk->sectors;
                 case TAO_ENDOFDATA:          num = 0;
                         if (data == TAO_MODE_GAP) {          while(num < sectors) {
                                 tao.mode = TAO_MODE_GAP;                  if (sec->r == sc) {
                                 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;                          break;
                   }
                   size = LOADINTELWORD(sec->size);
                   size += sizeof(_D88SEC);
                   sec = (D88SEC)(((UINT8 *)sec) + size);
                   num++;
         }          }
           return((UINT32)(sectors << 16) + num);
 }  }
   #endif
   
   
 // ----  // ----
   
 BRESULT fddd88_eject(FDDFILE fdd, REG8 drv) {  BRESULT fddd88_set(FDDFILE fdd, const OEMCHAR *fname) {
   
         drvflush(drv);  
         ZeroMemory(&d88head[drv], sizeof(D88_HEADER));  
         fdd->fname[0] = '\0';  
         fdd->type = DISKTYPE_NOTREADY;  
         return(SUCCESS);  
 }  
   
 BRESULT fddd88_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) {  
   
         short   attr;          short   attr;
         FILEH   fh;          FILEH   fh;
         UINT    rsize;          BRESULT r;
           UINT8   ptr[D88_TRACKMAX][4];
           UINT    i;
   
         attr = file_attr(fname);          attr = file_attr(fname);
         if (attr & 0x18) {          if (attr & 0x18) {
                 goto fdst_err;                  goto fdst_err;
         }          }
         fh = file_open(fname);          fh = file_open_rb(fname);
         if (fh == FILEH_INVALID) {          if (fh == FILEH_INVALID) {
                 goto fdst_err;                  goto fdst_err;
         }          }
         rsize = file_read(fh, &d88head[drv], sizeof(D88_HEADER));          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);          file_close(fh);
         if (rsize != sizeof(D88_HEADER)) {          if (r) {
                 goto fdst_err;                  goto fdst_err;
         }          }
         if (d88head[drv].protect & 0x10) {          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;                  attr |= 1;
         }          }
         milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname));  
         fdd->type = DISKTYPE_D88;          fdd->type = DISKTYPE_D88;
         fdd->protect = (UINT8)(attr & 1);          fdd->protect = (UINT8)(attr & 1);
           fdd->seek = fddd88_seek;
           fdd->read = fddd88_read;
           fdd->write = fddd88_write;
           fdd->wrtrk = fddd88_wrtrk;
           fdd->crc = fddd88_crc;
   #if defined(SUPPORT_DISKEXT)
           fdd->sec = fddd88_sec;
   #endif
         return(SUCCESS);          return(SUCCESS);
   
 fdst_err:  fdst_err:
         return(FAILURE);          return(FAILURE);
 }  }
   
   void fddd88_eject(FDDFILE fdd) {
   
           drvflush(fdd);
   }
   

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


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