--- xmil/io/fdc.c 2005/02/04 06:42:11 1.21 +++ xmil/io/fdc.c 2009/03/23 15:02:25 1.24 @@ -36,7 +36,7 @@ static const UINT8 fdctype[] = { FDCCTYPE_CMD3}; -// write track +/* write track */ #if !defined(CONST_DISKIMAGE) enum { @@ -84,7 +84,7 @@ static REG8 wrtrkstart(FDC *f) { return(0); } -static void wrtrkdata(FDC *f, UINT8 data) { +static void wrtrkdata(FDC *f, REG8 data) { TAOSEC *t; REG8 n; @@ -183,7 +183,7 @@ static void wrtrkdata(FDC *f, UINT8 data } break; - case TAO_MODE_DATA: // DATA WRITE + case TAO_MODE_DATA: /* DATA WRITE */ if ((f->s.wt_ptr == 0) && ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) { break; @@ -217,13 +217,13 @@ wtd_err: #endif -// ---- +/* ---- */ void neitem_fdcbusy(UINT id) { fdc.s.busy = 0; if (fdc.s.bufdir) { -// TRACEOUT(("dma ready!")); + /* TRACEOUT(("dma ready!")); */ dmac_sendready(TRUE); } (void)id; @@ -297,7 +297,7 @@ static SINT32 motorwait(const FDC *f) { curclock -= f->s.motorclock[f->s.drv]; if (curclock < (SINT32)pccore.realclock) { nextclock = pccore.realclock - curclock; -// TRACEOUT(("motor starting busy %d", nextclock)); + /* TRACEOUT(("motor starting busy %d", nextclock)); */ return(nextclock); } } @@ -436,8 +436,8 @@ static REG8 type2cmd(FDC *f, REG8 sc) { if (nextclock < 0) { nextclock += f->s.loopclock; } -// TRACEOUT(("wait clock -> %d [%d/%d]", nextclock, -// LOW16(secinfo), LOW16(secinfo >> 16))); + /* TRACEOUT(("wait clock -> %d [%d/%d]", nextclock, + LOW16(secinfo), LOW16(secinfo >> 16))); */ clock += nextclock; } #endif @@ -479,7 +479,7 @@ static REG8 crccmd(FDC *f) { track = (f->s.c << 1) + f->s.h; 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); if (stat & FDDSTAT_RECNFND) { f->s.crcnum = 0; @@ -512,7 +512,7 @@ static void fdcenddata(FDC *f) { r = TRUE; } if ((f->s.cmd & 0x20) && (f->s.bufwrite)) { - stat = type2flash(&fdc); + stat = type2flash(f); if (stat & (FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT)) { r = FALSE; } @@ -531,247 +531,310 @@ 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; - 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) - setbusy(&fdc, 200); - ZeroMemory(fdc.s.buffer, 0x1a00); - fdc.s.bufpos = 0; - fdc.s.bufsize = 0x1a00; - fdc.s.bufdir = FDCDIR_IN; - fdc.s.stat = 0; + setbusy(f, 200); + ZeroMemory(f->s.buffer, 0x1a00); + f->s.bufpos = 0; + f->s.bufsize = 0x1a00; + f->s.bufdir = FDCDIR_IN; + f->s.stat = 0; #else - fdc.s.stat = FDDSTAT_SEEKERR; + f->s.stat = FDDSTAT_SEEKERR; #endif - break; + break; - case 0x0f: // ライトトラック + case 0x0f: /* ライトトラック */ #if !defined(CONST_DISKIMAGE) - setbusy(&fdc, 200); - fdc.s.stat = wrtrkstart(&fdc); + setbusy(f, 200); + f->s.stat = wrtrkstart(f); #else - fdc.s.stat = FDDSTAT_LOSTDATA; + f->s.stat = FDDSTAT_LOSTDATA; #endif - break; - } break; + } +} - case 1: // トラック - fdc.s.creg = value; - break; +static void IOOUTCALL fdc_o0ff9(FDC *f, REG8 value) { - case 2: // セクタ - fddmtr_waitsec(value); - fdc.s.r = value; - fdc.s.rreg = value; - break; + /* トラック */ + f->s.creg = value; +} + +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 (fdc.s.motor) { - if (fdc.s.bufdir == FDCDIR_OUT) { - fdc.s.bufwrite = TRUE; - fdc.s.curtime = 0; - fdc.s.buffer[fdc.s.bufpos] = value; - if (!fdc.s.busy) { - fdc.s.bufpos++; - if (fdc.s.bufpos >= fdc.s.bufsize) { - fdcenddata(&fdc); - } - } - } - else if (fdc.s.bufdir == FDCDIR_TAO) { - wrtrkdata(&fdc, value); + if (f->s.motor) { + if (f->s.bufdir == FDCDIR_OUT) { + f->s.bufwrite = TRUE; + f->s.curtime = 0; + f->s.buffer[f->s.bufpos] = value; + if (!f->s.busy) { + f->s.bufpos++; + if (f->s.bufpos >= f->s.bufsize) { + fdcenddata(f); } } + } + else if (f->s.bufdir == FDCDIR_TAO) { + wrtrkdata(f, value); + } + } #endif - break; +} - case 4: // ドライブ・サイド - fdc.s.ctbl[fdc.s.drv] = fdc.s.c; - fdc.s.c = fdc.s.ctbl[value & 0x03]; - fdc.s.motor = (UINT8)(value & 0x80); - fdc.s.drv = (UINT8)(value & 0x03); - fdc.s.h = (UINT8)((value >> 4) & 1); - fdc.s.cmd = 0; // T&E SORCERIAN - fdc.s.ctype = 0; - fdc.s.stat = 0; - - fddmtr_drvset(); - if (!fdc.s.motor) { - fdc.s.r = 0; // SACOM TELENET - fdc.s.rreg = 0; - } +static void IOOUTCALL fdc_o0ffc(FDC *f, REG8 value) { + + /* ドライブ・サイド */ + f->s.ctbl[f->s.drv] = f->s.c; + f->s.c = f->s.ctbl[value & 0x03]; + f->s.motor = (UINT8)(value & 0x80); + f->s.drv = (UINT8)(value & 0x03); + f->s.h = (UINT8)((value >> 4) & 1); + f->s.cmd = 0; /* T&E SORCERIAN */ + f->s.ctype = 0; + f->s.stat = 0; + + fddmtr_drvset(); + if (!f->s.motor) { + f->s.r = 0; /* SACOM TELENET */ + f->s.rreg = 0; + } #if defined(SUPPORT_MOTORRISEUP) - setmotor(&fdc, value); + setmotor(f, value); #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 (fdc.s.bufdir >= FDCDIR_IN) { // YsII - fdc.s.curtime++; - if (fdc.s.curtime >= 8) { - fdc.s.curtime = 0; - fdc.s.stat |= FDDSTAT_LOSTDATA; - fdc.s.bufpos++; - if (fdc.s.bufpos >= fdc.s.bufsize) { - fdcenddata(&fdc); - } - } + if (f->s.bufdir >= FDCDIR_IN) { /* YsII */ + f->s.curtime++; + if (f->s.curtime >= 8) { + f->s.curtime = 0; + f->s.stat |= FDDSTAT_LOSTDATA; + f->s.bufpos++; + if (f->s.bufpos >= f->s.bufsize) { + fdcenddata(f); } + } + } #endif - ret = getstat(&fdc); + ret = getstat(f); #if 1 - if (!(ret & 0x02)) { - dmac_sendready(FALSE); - } + if (!(ret & 0x02)) { + dmac_sendready(FALSE); + } #endif -// TRACEOUT(("ret->%.2x", ret)); - return(ret); + /* TRACEOUT(("ret->%.2x", 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: // トラック -TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.creg)); - return(fdc.s.creg); +static REG8 IOINPCALL fdc_i0ffa(FDC *f) { - case 2: // セクタ -TRACEOUT(("fdc inp %.4x,%.2x", port, fdc.s.rreg)); - return(fdc.s.rreg); + /* セクタ */ + TRACEOUT(("fdc inp %.4x,%.2x", 0x0ffa, f->s.rreg)); + return(f->s.rreg); +} + +static REG8 IOINPCALL fdc_i0ffb(FDC *f) { - case 3: // データ - if (fdc.s.motor) { - if (fdc.s.bufdir == FDCDIR_IN) { - fdc.s.curtime = 0; + /* データ */ + if (f->s.motor) { + if (f->s.bufdir == FDCDIR_IN) { + f->s.curtime = 0; #if !defined(CONST_DISKIMAGE) - fdc.s.data = fdc.s.buffer[fdc.s.bufpos]; + f->s.data = f->s.buffer[f->s.bufpos]; #else - fdc.s.data = fdc.e.buffer[fdc.s.bufpos]; + f->s.data = f->e.buffer[f->s.bufpos]; #endif -// TRACEOUT(("read %.2x - %.2x [%.4x]", fdc.s.bufpos, fdc.s.data, Z80_PC)); - if (!fdc.s.busy) { - fdc.s.bufpos++; - if (fdc.s.bufpos >= fdc.s.bufsize) { - fdcenddata(&fdc); - } - } + if (!f->s.busy) { + f->s.bufpos++; + if (f->s.bufpos >= f->s.bufsize) { + fdcenddata(f); } } - return(fdc.s.data); + /* TRACEOUT(("read %.2x - %.2x [%.4x]", f->s.bufpos, f->s.data, Z80_PC)); */ + } + } + return(f->s.data); +} - case 4: // FM - case 5: // MFM - return(0x00); +static REG8 IOINPCALL fdc_i0ffc(FDC *f) { - case 6: // 1.6M - fdc.s.media = DISKTYPE_2HD; - break; + /* FM */ + return(0x00); +} - case 7: // 500K/1M - fdc.s.media = DISKTYPE_2D; - break; - } +static REG8 IOINPCALL fdc_i0ffd(FDC *f) { + + /* 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); } -// ---- +/* 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) {