| version 1.22, 2005/02/13 22:27:53 | version 1.24, 2009/03/23 15:02:25 | 
| Line 36  static const UINT8 fdctype[] = { | Line 36  static const UINT8 fdctype[] = { | 
 | FDCCTYPE_CMD3}; | FDCCTYPE_CMD3}; | 
 |  |  | 
 |  |  | 
| // write track | /* write track */ | 
 |  |  | 
 | #if !defined(CONST_DISKIMAGE) | #if !defined(CONST_DISKIMAGE) | 
 | enum { | enum { | 
| Line 183  static void wrtrkdata(FDC *f, REG8 data) | Line 183  static void wrtrkdata(FDC *f, REG8 data) | 
 | } | } | 
 | break; | break; | 
 |  |  | 
| case TAO_MODE_DATA:                                             // DATA WRITE | case TAO_MODE_DATA:                                             /* DATA WRITE */ | 
 | if ((f->s.wt_ptr == 0) && | if ((f->s.wt_ptr == 0) && | 
 | ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) { | ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) { | 
 | break; | break; | 
| Line 217  wtd_err: | Line 217  wtd_err: | 
 | #endif | #endif | 
 |  |  | 
 |  |  | 
| // ---- | /* ---- */ | 
 |  |  | 
 | void neitem_fdcbusy(UINT id) { | void neitem_fdcbusy(UINT id) { | 
 |  |  | 
 | fdc.s.busy = 0; | fdc.s.busy = 0; | 
 | if (fdc.s.bufdir) { | if (fdc.s.bufdir) { | 
| //              TRACEOUT(("dma ready!")); | /* TRACEOUT(("dma ready!")); */ | 
 | dmac_sendready(TRUE); | dmac_sendready(TRUE); | 
 | } | } | 
 | (void)id; | (void)id; | 
| Line 297  static SINT32 motorwait(const FDC *f) { | Line 297  static SINT32 motorwait(const FDC *f) { | 
 | curclock -= f->s.motorclock[f->s.drv]; | curclock -= f->s.motorclock[f->s.drv]; | 
 | if (curclock < (SINT32)pccore.realclock) { | if (curclock < (SINT32)pccore.realclock) { | 
 | nextclock = pccore.realclock - curclock; | nextclock = pccore.realclock - curclock; | 
| //                      TRACEOUT(("motor starting busy %d", nextclock)); | /* TRACEOUT(("motor starting busy %d", nextclock)); */ | 
 | return(nextclock); | return(nextclock); | 
 | } | } | 
 | } | } | 
| Line 436  static REG8 type2cmd(FDC *f, REG8 sc) { | Line 436  static REG8 type2cmd(FDC *f, REG8 sc) { | 
 | if (nextclock < 0) { | if (nextclock < 0) { | 
 | nextclock += f->s.loopclock; | nextclock += f->s.loopclock; | 
 | } | } | 
| //              TRACEOUT(("wait clock -> %d [%d/%d]", nextclock, | /* TRACEOUT(("wait clock -> %d [%d/%d]", nextclock, | 
| //                                                                      LOW16(secinfo), LOW16(secinfo >> 16))); | LOW16(secinfo), LOW16(secinfo >> 16))); */ | 
 | clock += nextclock; | clock += nextclock; | 
 | } | } | 
 | #endif | #endif | 
| Line 479  static REG8 crccmd(FDC *f) { | Line 479  static REG8 crccmd(FDC *f) { | 
 |  |  | 
 | track = (f->s.c << 1) + f->s.h; | track = (f->s.c << 1) + f->s.h; | 
 | fdd = fddfile + f->s.drv; | fdd = fddfile + f->s.drv; | 
| // TRACEOUT(("fdd->crc %d %d %d", f->s.drv, track, f->s.crcnum)); | /* TRACEOUT(("fdd->crc %d %d %d", f->s.drv, track, f->s.crcnum)); */ | 
 | stat = fdd->crc(fdd, f->s.media, track, f->s.crcnum, crcbuf); | stat = fdd->crc(fdd, f->s.media, track, f->s.crcnum, crcbuf); | 
 | if (stat & FDDSTAT_RECNFND) { | if (stat & FDDSTAT_RECNFND) { | 
 | f->s.crcnum = 0; | f->s.crcnum = 0; | 
| 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); | 
|  | } | 
|  | if (f->s.bufdir != FDCDIR_NONE) { | 
|  | f->s.bufdir = FDCDIR_NONE; | 
|  | dmac_sendready(FALSE); | 
 | } | } | 
 | TRACEOUT(("fdc %.4x,%.2x [%.4x]", port, value, Z80_PC)); |  | 
 | switch(port & 7) { |  | 
 | case 0:                                                                 // コマンド |  | 
 | if (fdc.s.bufwrite) { |  | 
 | fdc.s.stat = type2flash(&fdc); |  | 
 | } |  | 
 | if (fdc.s.bufdir != FDCDIR_NONE) { |  | 
 | fdc.s.bufdir = FDCDIR_NONE; |  | 
 | dmac_sendready(FALSE); |  | 
 | } |  | 
 |  |  | 
 | fdc.s.cmd = value; |  | 
 | cmd = (REG8)(value >> 4); |  | 
 | fdc.s.ctype = fdctype[cmd]; |  | 
 | //                      TRACEOUT(("fdc cmd: %.2x", value)); |  | 
 | // リストアコマンドにおいて |  | 
 | //  マリオは コマンド発行後にbusyを見張る |  | 
 | //  逆にソーサリアンとかは busyだとエラーになる… |  | 
 | // 条件は何? |  | 
 | setbusy(&fdc, 20); |  | 
 | switch(cmd) { |  | 
 | 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:                                                              // リードトラック | f->s.cmd = value; | 
|  | cmd = (REG8)(value >> 4); | 
|  | f->s.ctype = fdctype[cmd]; | 
|  | /* 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; | 
|  |  | 
|  | case 0x08:                                                              /* リードデータ */ | 
|  | case 0x09: | 
|  | case 0x0a:                                                              /* ライトデータ */ | 
|  | case 0x0b: | 
|  | f->s.stat = type2cmd(f, f->s.r); | 
|  | break; | 
|  |  | 
|  | case 0xc:                                                               /* リードアドレス */ | 
|  | setbusy(f, 200); | 
|  | f->s.stat = crccmd(f); | 
|  | break; | 
|  |  | 
|  | 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) { | 
|  |  | 
|  | /* セクタ */ | 
|  | fddmtr_waitsec(value); | 
|  | f->s.r = value; | 
|  | f->s.rreg = value; | 
|  | } | 
|  |  | 
|  | static void IOOUTCALL fdc_o0ffb(FDC *f, REG8 value) { | 
 |  |  | 
| case 3:                                                                 // データ | /* データ */ | 
| fdc.s.data = 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); | 
|  | } | 
 |  |  | 
| case 1:                                                                 // トラック | static REG8 IOINPCALL fdc_i0ffa(FDC *f) { | 
| TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.creg)); |  | 
| return(fdc.s.creg); |  | 
 |  |  | 
| case 2:                                                                 // セクタ | /* セクタ */ | 
| TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.rreg)); | TRACEOUT(("fdc inp %.4x,%.2x", 0x0ffa, f->s.rreg)); | 
| return(fdc.s.rreg); | return(f->s.rreg); | 
|  | } | 
|  |  | 
|  | static REG8 IOINPCALL fdc_i0ffb(FDC *f) { | 
 |  |  | 
| case 3:                                                                 // データ | /* データ */ | 
| if (fdc.s.motor) { | if (f->s.motor) { | 
| if (fdc.s.bufdir == FDCDIR_IN) { | if (f->s.bufdir == FDCDIR_IN) { | 
| fdc.s.curtime = 0; | f->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 | 
| // TRACEOUT(("read %.2x - %.2x [%.4x]", fdc.s.bufpos, fdc.s.data, Z80_PC)); | if (!f->s.busy) { | 
| if (!fdc.s.busy) { | f->s.bufpos++; | 
| fdc.s.bufpos++; | if (f->s.bufpos >= f->s.bufsize) { | 
| if (fdc.s.bufpos >= fdc.s.bufsize) { | fdcenddata(f); | 
| fdcenddata(&fdc); |  | 
| } |  | 
| } |  | 
 | } | } | 
 | } | } | 
| 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); | 
|  | } | 
|  |  | 
|  | static REG8 IOINPCALL fdc_i0fff(FDC *f) { | 
|  |  | 
|  | /* 500K/1M */ | 
|  | f->s.media = DISKTYPE_2D; | 
 | return(0xff); | 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 */ | 
 |  |  | 
 | void fdc_reset(void) { | void fdc_reset(void) { | 
 |  |  |