Diff for /xmil/io/fdc.c between versions 1.23 and 1.24

version 1.23, 2008/06/02 20:07:31 version 1.24, 2009/03/23 15:02:25
Line 512  static void fdcenddata(FDC *f) { Line 512  static void fdcenddata(FDC *f) {
                         r = TRUE;                          r = TRUE;
                 }                  }
                 if ((f->s.cmd & 0x20) && (f->s.bufwrite)) {                  if ((f->s.cmd & 0x20) && (f->s.bufwrite)) {
                         stat = type2flash(&fdc);                          stat = type2flash(f);
                         if (stat & (FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT)) {                          if (stat & (FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT)) {
                                 r = FALSE;                                  r = FALSE;
                         }                          }
Line 531  static void fdcenddata(FDC *f) { Line 531  static void fdcenddata(FDC *f) {
         }          }
 }  }
   
 void IOOUTCALL fdc_o(UINT port, REG8 value) {  
   
   /* IO-Sub */
   
   static void IOOUTCALL fdc_o0ff8(FDC *f, REG8 value) {
   
         REG8    cmd;          REG8    cmd;
   
         if ((port & (~7)) != 0x0ff8) {          /* コマンド */
                 return;          if (f->s.bufwrite) {
                   f->s.stat = type2flash(f);
         }          }
         TRACEOUT(("fdc %.4x,%.2x [%.4x]", port, value, Z80_PC));          if (f->s.bufdir != FDCDIR_NONE) {
         switch(port & 7) {                  f->s.bufdir = FDCDIR_NONE;
                 case 0:                                                                 /* コマンド */                  dmac_sendready(FALSE);
                         if (fdc.s.bufwrite) {          }
                                 fdc.s.stat = type2flash(&fdc);  
                         }          f->s.cmd = value;
                         if (fdc.s.bufdir != FDCDIR_NONE) {          cmd = (REG8)(value >> 4);
                                 fdc.s.bufdir = FDCDIR_NONE;          f->s.ctype = fdctype[cmd];
                                 dmac_sendready(FALSE);          /* TRACEOUT(("fdc cmd: %.2x", value)); */
           /* リストアコマンドにおいて
            *  マリオは コマンド発行後にbusyを見張る
            *  逆にソーサリアンとかは busyだとエラーになる…
            * 条件は何?
            */
           setbusy(f, 20);
           switch(cmd) {
                   case 0x00:                                                              /* リストア */
                           f->s.motor = 0x80;                                      /* モーターOn? */
                           f->s.c = 0;
                           f->s.step = 1;
                           f->s.r = 0;                                                     /* デゼニワールド */
                           seekcmd(f);
                           f->s.rreg = 0;
                           break;
   
                   case 0x01:                                                              /* シーク */
                           f->s.motor = 0x80;                                      /* モーターOn */
                           f->s.step = (SINT8)((f->s.c<=f->s.data)?1:-1);
                           f->s.c = f->s.data;
                           seekcmd(f);
                           break;
   
                   case 0x02:                                                              /* ステップ */
                   case 0x03:
                   case 0x04:                                                              /* ステップイン */
                   case 0x05:
                   case 0x06:                                                              /* ステップアウト */
                   case 0x07:
                           f->s.stat = FDDSTAT_HEADENG;
                           if (f->s.motor) {
                                   if (cmd & 0x04) {
                                           f->s.step = (cmd & 0x02)?-1:1;
                                   }
                                   f->s.c += f->s.step;
                                   if (cmd & 1) {
                                           seekcmd(f);
                                   }
                         }                          }
                           break;
   
                         fdc.s.cmd = value;                  case 0x08:                                                              /* リードデータ */
                         cmd = (REG8)(value >> 4);                  case 0x09:
                         fdc.s.ctype = fdctype[cmd];                  case 0x0a:                                                              /* ライトデータ */
                         /* TRACEOUT(("fdc cmd: %.2x", value)); */                  case 0x0b:
                         /* リストアコマンドにおいて                          f->s.stat = type2cmd(f, f->s.r);
                          *  マリオは コマンド発行後にbusyを見張る                          break;
                          *  逆にソーサリアンとかは busyだとエラーになる…  
                          * 条件は何?                  case 0xc:                                                               /* リードアドレス */
                          */                          setbusy(f, 200);
                         setbusy(&fdc, 20);                          f->s.stat = crccmd(f);
                         switch(cmd) {                          break;
                                 case 0x00:                                                              /* リストア */  
                                         fdc.s.motor = 0x80;                                     /* モーターOn? */  
                                         fdc.s.c = 0;  
                                         fdc.s.step = 1;  
                                         fdc.s.r = 0;                                            /* デゼニワールド */  
                                         seekcmd(&fdc);  
                                         fdc.s.rreg = 0;  
                                         break;  
   
                                 case 0x01:                                                              /* シーク */  
                                         fdc.s.motor = 0x80;                                     /* モーターOn */  
                                         fdc.s.step = (SINT8)((fdc.s.c<=fdc.s.data)?1:-1);  
                                         fdc.s.c = fdc.s.data;  
                                         seekcmd(&fdc);  
                                         break;  
   
                                 case 0x02:                                                              /* ステップ */  
                                 case 0x03:  
                                 case 0x04:                                                              /* ステップイン */  
                                 case 0x05:  
                                 case 0x06:                                                              /* ステップアウト */  
                                 case 0x07:  
                                         fdc.s.stat = FDDSTAT_HEADENG;  
                                         if (fdc.s.motor) {  
                                                 if (cmd & 0x04) {  
                                                         fdc.s.step = (cmd & 0x02)?-1:1;  
                                                 }  
                                                 fdc.s.c += fdc.s.step;  
                                                 if (cmd & 1) {  
                                                         seekcmd(&fdc);  
                                                 }  
                                         }  
                                         break;  
   
                                 case 0x08:                                                              /* リードデータ */  
                                 case 0x09:  
                                 case 0x0a:                                                              /* ライトデータ */  
                                 case 0x0b:  
                                         fdc.s.stat = type2cmd(&fdc, fdc.s.r);  
                                         break;  
   
                                 case 0xc:                                                               /* リードアドレス */  
                                         setbusy(&fdc, 200);  
                                         fdc.s.stat = crccmd(&fdc);  
                                         break;  
   
                                 case 0x0d:                                                              /* フォースインタラプト */  
                                         setbusy(&fdc, 0);                                       /* 必要ない? */  
                                         /* fdc.s.skip = 0; */                           /* 000330 */  
                                         fdc.s.stat = 0;  
                                         dmac_sendready(FALSE);  
                                         break;  
   
                                 case 0x0e:                                                              /* リードトラック */                  case 0x0d:                                                              /* フォースインタラプト */
                           setbusy(f, 0);                                          /* 必要ない? */
                           /* f->s.skip = 0; */                            /* 000330 */
                           f->s.stat = 0;
                           dmac_sendready(FALSE);
                           break;
   
                   case 0x0e:                                                              /* リードトラック */
 #if !defined(CONST_DISKIMAGE)  #if !defined(CONST_DISKIMAGE)
                                         setbusy(&fdc, 200);                          setbusy(f, 200);
                                         ZeroMemory(fdc.s.buffer, 0x1a00);                          ZeroMemory(f->s.buffer, 0x1a00);
                                         fdc.s.bufpos = 0;                          f->s.bufpos = 0;
                                         fdc.s.bufsize = 0x1a00;                          f->s.bufsize = 0x1a00;
                                         fdc.s.bufdir = FDCDIR_IN;                          f->s.bufdir = FDCDIR_IN;
                                         fdc.s.stat = 0;                          f->s.stat = 0;
 #else  #else
                                         fdc.s.stat = FDDSTAT_SEEKERR;                          f->s.stat = FDDSTAT_SEEKERR;
 #endif  #endif
                                         break;                          break;
   
                                 case 0x0f:                                                              /* ライトトラック */                  case 0x0f:                                                              /* ライトトラック */
 #if !defined(CONST_DISKIMAGE)  #if !defined(CONST_DISKIMAGE)
                                         setbusy(&fdc, 200);                          setbusy(f, 200);
                                         fdc.s.stat = wrtrkstart(&fdc);                          f->s.stat = wrtrkstart(f);
 #else  #else
                                         fdc.s.stat = FDDSTAT_LOSTDATA;                          f->s.stat = FDDSTAT_LOSTDATA;
 #endif  #endif
                                         break;  
                         }  
                         break;                          break;
           }
   }
   
                 case 1:                                                                 /* トラック */  static void IOOUTCALL fdc_o0ff9(FDC *f, REG8 value) {
                         fdc.s.creg = value;  
                         break;  
   
                 case 2:                                                                 /* セクタ */          /* トラック */
                         fddmtr_waitsec(value);          f->s.creg = value;
                         fdc.s.r = value;  }
                         fdc.s.rreg = value;  
                         break;  static void IOOUTCALL fdc_o0ffa(FDC *f, REG8 value) {
   
                 case 3:                                                                 /* データ */          /* セクタ */
                         fdc.s.data = value;          fddmtr_waitsec(value);
           f->s.r = value;
           f->s.rreg = value;
   }
   
   static void IOOUTCALL fdc_o0ffb(FDC *f, REG8 value) {
   
           /* データ */
           f->s.data = value;
 #if !defined(CONST_DISKIMAGE)  #if !defined(CONST_DISKIMAGE)
                         if (fdc.s.motor) {          if (f->s.motor) {
                                 if (fdc.s.bufdir == FDCDIR_OUT) {                  if (f->s.bufdir == FDCDIR_OUT) {
                                         fdc.s.bufwrite = TRUE;                          f->s.bufwrite = TRUE;
                                         fdc.s.curtime = 0;                          f->s.curtime = 0;
                                         fdc.s.buffer[fdc.s.bufpos] = value;                          f->s.buffer[f->s.bufpos] = value;
                                         if (!fdc.s.busy) {                          if (!f->s.busy) {
                                                 fdc.s.bufpos++;                                  f->s.bufpos++;
                                                 if (fdc.s.bufpos >= fdc.s.bufsize) {                                  if (f->s.bufpos >= f->s.bufsize) {
                                                         fdcenddata(&fdc);                                          fdcenddata(f);
                                                 }  
                                         }  
                                 }  
                                 else if (fdc.s.bufdir == FDCDIR_TAO) {  
                                         wrtrkdata(&fdc, value);  
                                 }                                  }
                         }                          }
                   }
                   else if (f->s.bufdir == FDCDIR_TAO) {
                           wrtrkdata(f, value);
                   }
           }
 #endif  #endif
                         break;  }
   
                 case 4:                                                                 /* ドライブ・サイド */  static void IOOUTCALL fdc_o0ffc(FDC *f, REG8 value) {
                         fdc.s.ctbl[fdc.s.drv] = fdc.s.c;  
                         fdc.s.c = fdc.s.ctbl[value & 0x03];          /* ドライブ・サイド */
                         fdc.s.motor = (UINT8)(value & 0x80);          f->s.ctbl[f->s.drv] = f->s.c;
                         fdc.s.drv = (UINT8)(value & 0x03);          f->s.c = f->s.ctbl[value & 0x03];
                         fdc.s.h = (UINT8)((value >> 4) & 1);          f->s.motor = (UINT8)(value & 0x80);
                         fdc.s.cmd = 0;                                                  /* T&E SORCERIAN */          f->s.drv = (UINT8)(value & 0x03);
                         fdc.s.ctype = 0;          f->s.h = (UINT8)((value >> 4) & 1);
                         fdc.s.stat = 0;          f->s.cmd = 0;                                                   /* T&E SORCERIAN */
           f->s.ctype = 0;
                         fddmtr_drvset();          f->s.stat = 0;
                         if (!fdc.s.motor) {  
                                 fdc.s.r = 0;                                            /* SACOM TELENET */          fddmtr_drvset();
                                 fdc.s.rreg = 0;          if (!f->s.motor) {
                         }                  f->s.r = 0;                                             /* SACOM TELENET */
                   f->s.rreg = 0;
           }
 #if defined(SUPPORT_MOTORRISEUP)  #if defined(SUPPORT_MOTORRISEUP)
                         setmotor(&fdc, value);          setmotor(f, value);
 #endif  #endif
                         break;  
         }  
 }  }
   
 REG8 IOINPCALL fdc_i(UINT port) {  static void IOOUTCALL fdc_o0(FDC *f, REG8 value) {
   }
   
         REG8    ret;  static REG8 IOINPCALL fdc_i0ff8(FDC *f) {
   
         /* TRACEOUT(("fdc inp %.4x", port)); */          REG8    ret;
   
         if ((port & (~7)) != 0x0ff8) {          /* ステータス */
                 return(0xff);          ret = f->s.busy;
           if (ret) {
                   return(ret);
         }          }
         switch(port & 7) {  
                 case 0:                                                                         /* ステータス */  
                         ret = fdc.s.busy;  
                         if (ret) {  
                                 return(ret);  
                         }  
 #if 1  #if 1
                         if (fdc.s.bufdir >= FDCDIR_IN) {                /* YsII */          if (f->s.bufdir >= FDCDIR_IN) {         /* YsII */
                                 fdc.s.curtime++;                  f->s.curtime++;
                                 if (fdc.s.curtime >= 8) {                  if (f->s.curtime >= 8) {
                                         fdc.s.curtime = 0;                          f->s.curtime = 0;
                                         fdc.s.stat |= FDDSTAT_LOSTDATA;                          f->s.stat |= FDDSTAT_LOSTDATA;
                                         fdc.s.bufpos++;                          f->s.bufpos++;
                                         if (fdc.s.bufpos >= fdc.s.bufsize) {                          if (f->s.bufpos >= f->s.bufsize) {
                                                 fdcenddata(&fdc);                                  fdcenddata(f);
                                         }  
                                 }  
                         }                          }
                   }
           }
 #endif  #endif
                         ret = getstat(&fdc);          ret = getstat(f);
 #if 1  #if 1
                         if (!(ret & 0x02)) {          if (!(ret & 0x02)) {
                                 dmac_sendready(FALSE);                  dmac_sendready(FALSE);
                         }          }
 #endif  #endif
                         /* TRACEOUT(("ret->%.2x", ret)); */          /* TRACEOUT(("ret->%.2x", ret)); */
                         return(ret);          return(ret);
   }
   
   static REG8 IOINPCALL fdc_i0ff9(FDC *f) {
   
           /* トラック */
           TRACEOUT(("fdc inp %.4x,%.2x", 0x0ff9, f->s.creg));
           return(f->s.creg);
   }
   
   static REG8 IOINPCALL fdc_i0ffa(FDC *f) {
   
           /* セクタ */
           TRACEOUT(("fdc inp %.4x,%.2x", 0x0ffa, f->s.rreg));
           return(f->s.rreg);
   }
   
   static REG8 IOINPCALL fdc_i0ffb(FDC *f) {
   
                 case 1:                                                                 /* トラック */          /* データ */
 TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.creg));          if (f->s.motor) {
                         return(fdc.s.creg);                  if (f->s.bufdir == FDCDIR_IN) {
                           f->s.curtime = 0;
                 case 2:                                                                 /* セクタ */  
 TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.rreg));  
                         return(fdc.s.rreg);  
   
                 case 3:                                                                 /* データ */  
                         if (fdc.s.motor) {  
                                 if (fdc.s.bufdir == FDCDIR_IN) {  
                                         fdc.s.curtime = 0;  
 #if !defined(CONST_DISKIMAGE)  #if !defined(CONST_DISKIMAGE)
                                         fdc.s.data = fdc.s.buffer[fdc.s.bufpos];                          f->s.data = f->s.buffer[f->s.bufpos];
 #else  #else
                                         fdc.s.data = fdc.e.buffer[fdc.s.bufpos];                          f->s.data = f->e.buffer[f->s.bufpos];
 #endif  #endif
                                         if (!fdc.s.busy) {                          if (!f->s.busy) {
                                                 fdc.s.bufpos++;                                  f->s.bufpos++;
                                                 if (fdc.s.bufpos >= fdc.s.bufsize) {                                  if (f->s.bufpos >= f->s.bufsize) {
                                                         fdcenddata(&fdc);                                          fdcenddata(f);
                                                 }  
                                         }  
                                         /* TRACEOUT(("read %.2x - %.2x [%.4x]", fdc.s.bufpos, fdc.s.data, Z80_PC)); */  
                                 }                                  }
                         }                          }
                         return(fdc.s.data);                          /* TRACEOUT(("read %.2x - %.2x [%.4x]", f->s.bufpos, f->s.data, Z80_PC)); */
                   }
           }
           return(f->s.data);
   }
   
                 case 4:                                                                 /* FM */  static REG8 IOINPCALL fdc_i0ffc(FDC *f) {
                 case 5:                                                                 /* MFM */  
                         return(0x00);  
   
                 case 6:                                                                 /* 1.6M */          /* FM */
                         fdc.s.media = DISKTYPE_2HD;          return(0x00);
                         break;  }
   
                 case 7:                                                                 /* 500K/1M */  static REG8 IOINPCALL fdc_i0ffd(FDC *f) {
                         fdc.s.media = DISKTYPE_2D;  
                         break;          /* MFM */
         }          return(0x00);
   }
   
   static REG8 IOINPCALL fdc_i0ffe(FDC *f) {
   
           /* 1.6M */
           f->s.media = DISKTYPE_2HD;
         return(0xff);          return(0xff);
 }  }
   
   static REG8 IOINPCALL fdc_i0fff(FDC *f) {
   
           /* 500K/1M */
           f->s.media = DISKTYPE_2D;
           return(0xff);
   }
   
   
   /* IO */
   
   typedef void (IOINPCALL * FNFDCOUT)(FDC *f, REG8 value);
   static const FNFDCOUT s_fnOut[] =
   {
           fdc_o0ff8,      fdc_o0ff9,      fdc_o0ffa,      fdc_o0ffb,
           fdc_o0ffc,      fdc_o0,         fdc_o0,         fdc_o0,
   };
   
   typedef REG8 (IOINPCALL * FNFDCINP)(FDC *f);
   static const FNFDCINP s_fnInp[] =
   {
           fdc_i0ff8,      fdc_i0ff9,      fdc_i0ffa,      fdc_i0ffb,
           fdc_i0ffc,      fdc_i0ffd,      fdc_i0ffe,      fdc_i0fff,
   };
   
   void IOINPCALL fdc_o(UINT port, REG8 value)
   {
           if ((port & (~7)) != 0x0ff8)
           {
                   return;
           }
   
           /* TRACEOUT(("fdc out %.4x,%.2x", port, value)); */
           (s_fnOut[port & 7])(&fdc, value);
   }
   
   REG8 IOINPCALL fdc_i(UINT uPort)
   {
           if ((uPort & (~7)) != 0x0ff8)
           {
                   return 0xff;
           }
   
           /* TRACEOUT(("fdc inp %.4x", port)); */
           return (s_fnInp[uPort & 7])(&fdc);
   }
   
   
 /* reset */  /* reset */
   

Removed from v.1.23  
changed lines
  Added in v.1.24


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