| version 1.3, 2004/08/09 04:47:53 | version 1.7, 2004/08/11 12:08:16 | 
| Line 3 | Line 3 | 
 | #include        "z80core.h" | #include        "z80core.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 |  | #include        "nevent.h" | 
 | #include        "fddfile.h" | #include        "fddfile.h" | 
 | #include        "fdd_2d.h" | #include        "fdd_2d.h" | 
 | #include        "fdd_d88.h" | #include        "fdd_d88.h" | 
 | #include        "fdd_mtr.h" | #include        "fdd_mtr.h" | 
 |  |  | 
 |  |  | 
 | BYTE            FDC_c[4]; |  | 
 | BYTE            driveset = 0; |  | 
 | BYTE            fdcdummyread = 0; |  | 
 | WORD            readdiag = 0; |  | 
 |  |  | 
 | static const UINT8 fdctype[] = {1,1,1,1,1,1,1,1,2,2,2,2,3,4,3,3}; | static const UINT8 fdctype[] = {1,1,1,1,1,1,1,1,2,2,2,2,3,4,3,3}; | 
 |  |  | 
 |  |  | 
| static BYTE fdd_stat(void) { | void nvitem_fdcbusy(UINT id) { | 
 |  |  | 
| FDDFILE fdd; | fdc.s.busy = FALSE; | 
|  | if (fdc.s.bufdir) { | 
|  | TRACEOUT(("dma ready!")); | 
|  | dma.DMA_REDY = 0; | 
|  | } | 
|  | } | 
 |  |  | 
| fdd = fddfile + fdc.drv; | static void setbusy(UINT clock) { | 
| switch(fdd->type) { |  | 
| case DISKTYPE_NOTREADY: |  | 
| return(0); |  | 
 |  |  | 
| case DISKTYPE_BETA: | fdc.s.busy = TRUE; | 
| return(fdd_stat_2d()); | nevent_set(NEVENT_FDC, clock, nvitem_fdcbusy, NEVENT_ABSOLUTE); | 
|  | } | 
|  |  | 
|  | static REG8 getstat(void) { | 
|  |  | 
|  | FDDFILE fdd; | 
|  | REG8    cmd; | 
|  | REG8    type; | 
|  | REG8    ret; | 
 |  |  | 
| case DISKTYPE_D88: | fdd = fddfile + fdc.s.drv; | 
| default: | cmd = (REG8)(fdc.s.cmd >> 4); | 
| return(fdd_stat_d88()); | type = fdc.s.type; | 
|  | if (fdd->type == DISKTYPE_NOTREADY) { | 
|  | ret = FDDSTAT_NOTREADY; | 
 | } | } | 
| return(0); | else if (type != 0) { | 
|  | ret = fdc.s.stat; | 
|  | } | 
|  | else { | 
|  | ret = 0; | 
|  | } | 
|  | if ((type == 1) && (fdc.s.c == 0)) { | 
|  | ret |= FDDSTAT_TRACK00; | 
|  | } | 
|  | if ((type == 0) || (type == 1) || (type == 4) || | 
|  | (cmd == 0x0a) || (cmd == 0x0b) || (cmd == 0x0f)) { | 
|  | if (fdd->protect) { | 
|  | ret |= FDDSTAT_WRITEP; | 
|  | } | 
|  | } | 
|  | if ((type == 1) || (type == 4)) { | 
|  | fdc.s.hole++; | 
|  | if (fdc.s.hole < 8) { | 
|  | ret |= FDDSTAT_INDEX; | 
|  | } | 
|  | } | 
|  | else if (!(ret & 0xf0)) { | 
|  | if (FDDMTR_BUSY) { | 
|  | ret |= FDDSTAT_BUSY; | 
|  | } | 
|  | if (fdc.s.bufdir) { | 
|  | ret |= FDDSTAT_DRQ | FDDSTAT_BUSY; | 
|  | } | 
|  | else if (cmd == 0x0f) { | 
|  | ret |= FDDSTAT_LOSTDATA; | 
|  | } | 
|  | } | 
|  | return(ret); | 
 | } | } | 
 |  |  | 
 |  | static void seekcmd(void) { | 
 |  |  | 
| /*********************************************************************** | FDDFILE fdd; | 
| FDC (X1から見るI/Oに相当する関数) | UINT    track; | 
| ***********************************************************************/ |  | 
 |  |  | 
| static int inc_off(void) { | fdc.s.crcnum = 0; | 
|  | fdc.s.creg = fdc.s.c; | 
|  | fdd = fddfile + fdc.s.drv; | 
|  | track = (fdc.s.c << 1) + fdc.s.h; | 
|  | fdc.s.stat = fdd->seek(fdd, fdc.s.media, track) | FDDSTAT_HEADENG; | 
|  | FDDMTR_MOVE; | 
|  | } | 
 |  |  | 
| BYTE    ret; | static REG8 type2cmd(REG8 sc) { | 
| FDDFILE fdd; |  | 
 |  |  | 
| if (!fdc.motor) { | REG8    dir; | 
| return(0); | UINT    track; | 
|  | UINT8   *p; | 
|  | FDDFILE fdd; | 
|  | UINT    size; | 
|  | REG8    stat; | 
|  |  | 
|  | track = (fdc.s.c << 1) + fdc.s.h; | 
|  | if (!(fdc.s.cmd & 0x20)) { | 
|  | p = fdc.s.buffer; | 
|  | dir = FDCDIR_IN; | 
|  | } | 
|  | else { | 
|  | p = NULL; | 
|  | dir = FDCDIR_OUT; | 
 | } | } | 
| if (fdcdummyread) { | size = sizeof(fdc.s.buffer); | 
| fdcdummyread--; | fdd = fddfile + fdc.s.drv; | 
| return(0); | TRACEOUT(("read %.2x %d %d", fdc.s.drv, track, sc)); | 
|  | stat = fdd->read(fdd, fdc.s.media, track, sc, p, &size); | 
|  | if (stat & FDDSTAT_RECNFND) { | 
|  | size = 0; | 
|  | dir = FDCDIR_NONE; | 
|  | } | 
|  | else if (dir == FDCDIR_OUT) { | 
|  | if (size) { | 
|  | ZeroMemory(fdc.s.buffer, size); | 
|  | } | 
|  | stat = stat & (~FDDSTAT_RECTYPE); | 
|  | } | 
|  | fdc.s.bufmedia = fdc.s.media; | 
|  | fdc.s.bufunit = fdc.s.drv; | 
|  | fdc.s.buftrack = track; | 
|  | fdc.s.bufsc = sc; | 
|  | fdc.s.bufwrite = FALSE; | 
|  | fdc.s.bufdir = dir; | 
|  | fdc.s.bufmark = fdc.s.cmd & 1; | 
|  | fdc.s.bufpos = 0; | 
|  | fdc.s.bufsize = size; | 
|  | return(stat); | 
|  | } | 
|  |  | 
|  | static REG8 type2flash(void) { | 
|  |  | 
|  | FDDFILE fdd; | 
|  |  | 
|  | fdc.s.bufwrite = FALSE; | 
|  | fdd = fddfile + fdc.s.bufunit; | 
|  | if (fdd->protect) { | 
|  | return(FDDSTAT_WRITEFAULT); | 
|  | } | 
|  | return(fdd->write(fdd, fdc.s.bufmedia, fdc.s.buftrack, | 
|  | fdc.s.bufsc, fdc.s.buffer, fdc.s.bufpos)); | 
|  | } | 
|  |  | 
|  | static REG8 crccmd(void) { | 
|  |  | 
|  | UINT    track; | 
|  | FDDFILE fdd; | 
|  | REG8    stat; | 
|  |  | 
|  | track = (fdc.s.c << 1) + fdc.s.h; | 
|  | fdd = fddfile + fdc.s.drv; | 
|  | stat = fdd->crc(fdd, fdc.s.media, track, fdc.s.crcnum, fdc.s.buffer); | 
|  | if (stat & FDDSTAT_RECNFND) { | 
|  | fdc.s.crcnum = 0; | 
|  | stat = fdd->crc(fdd, fdc.s.media, track, 0, fdc.s.buffer); | 
|  | } | 
|  | if (!(stat & FDDSTAT_RECNFND)) { | 
|  | fdc.s.bufdir = FDCDIR_IN; | 
|  | fdc.s.bufsize = 6; | 
|  | fdc.s.rreg = fdc.s.buffer[0]; | 
 | } | } | 
 | else { | else { | 
| fdd = fddfile + fdc.drv; | fdc.s.bufdir = FDCDIR_NONE; | 
| switch(fdd->type) { | fdc.s.bufsize = 0; | 
| case DISKTYPE_NOTREADY: | } | 
| return(0); | fdc.s.bufwrite = FALSE; | 
|  | return(stat); | 
|  | } | 
 |  |  | 
| case DISKTYPE_BETA: | static void bufposinc(void) { | 
| ret = fdd_incoff_2d(); |  | 
| break; |  | 
 |  |  | 
| case DISKTYPE_D88: | BRESULT r; | 
| default: | REG8    stat; | 
| ret = fdd_incoff_d88(); |  | 
| break; | if (fdc.s.busy) { | 
|  | return; | 
|  | } | 
|  | fdc.s.bufpos++; | 
|  | if (fdc.s.bufpos >= fdc.s.bufsize) { | 
|  | r = FALSE; | 
|  | if (fdc.s.type == 2) { | 
|  | stat = 0; | 
|  | if (fdc.s.cmd & 0x10) { | 
|  | r = TRUE; | 
|  | } | 
|  | if ((fdc.s.cmd & 0x20) && (fdc.s.bufwrite)) { | 
|  | stat = type2flash(); | 
|  | if (stat & (FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT)) { | 
|  | r = FALSE; | 
|  | } | 
|  | fdc.s.stat = stat; | 
|  | } | 
|  | if (r) { | 
|  | fdc.s.rreg = fdc.s.r + 1; | 
|  | stat = type2cmd(fdc.s.rreg); | 
|  | if (!(stat & FDDSTAT_RECNFND)) { | 
|  | fdc.s.r = fdc.s.r + 1; | 
|  | fdc.s.stat = stat; | 
|  | } | 
|  | else { | 
|  | r = FALSE; | 
|  | } | 
|  | } | 
 | } | } | 
| if (ret) { | if (!r) { | 
| dma.DMA_REDY = 8;       // <- DMA ノ レディシンゴウ ヲ クリア | dma.DMA_REDY = 8; | 
|  | fdc.s.bufdir = FDCDIR_NONE; | 
 | } | } | 
 | } | } | 
 | return(ret); |  | 
 | } | } | 
 |  |  | 
 | void IOOUTCALL fdc_o(UINT port, REG8 value) { | void IOOUTCALL fdc_o(UINT port, REG8 value) { | 
| Line 82  void IOOUTCALL fdc_o(UINT port, REG8 val | Line 221  void IOOUTCALL fdc_o(UINT port, REG8 val | 
 | if ((port & (~7)) != 0x0ff8) { | if ((port & (~7)) != 0x0ff8) { | 
 | return; | return; | 
 | } | } | 
 |  | TRACEOUT(("fdc %.4x,%.2x [%.4x]", port, value, Z80_PC)); | 
 | port &= 0xf; | port &= 0xf; | 
 | if (port == 8) {                                                // コマンド | if (port == 8) {                                                // コマンド | 
| driveset = 0; | fdc.s.cmd = value; | 
| fdc.cmd = value; |  | 
 | cmd = (REG8)(value >> 4); | cmd = (REG8)(value >> 4); | 
| fdc.type = fdctype[cmd]; | fdc.s.type = fdctype[cmd]; | 
| fdc.skip = 2; | TRACEOUT(("fdc cmd: %.2x", value)); | 
|  | if (fdc.s.bufwrite) { | 
|  | fdc.s.stat = type2flash(); | 
|  | } | 
|  | fdc.s.bufdir = FDCDIR_NONE; | 
|  | setbusy(20); | 
 | switch(cmd) { | switch(cmd) { | 
 | case 0x00:                                                              // リストア | case 0x00:                                                              // リストア | 
 | if (value & 8) {                                        // LAYDOCK | if (value & 8) {                                        // LAYDOCK | 
| fdc.skip = 0; | setbusy(0); | 
| fdc.busyclock = 20;                             // ver0.25 (now testing) | } | 
| fdc.busystart = h_cntbase + h_cnt; | fdc.s.motor = 0x80;                                     // モーターOn? | 
| } | fdc.s.c = 0; | 
| fdc.motor = 0x80;                                       // モーターOn? | fdc.s.step = 1; | 
| fdc.c = 0; | fdc.s.r = 0;                                            // デゼニワールド | 
| fdc.treg = 0; | seekcmd(); | 
| FDDMTR_MOVE; | fdc.s.rreg = 0; | 
| fdc.step = 1; |  | 
| #if 1                                                                                           // ver0.25 |  | 
| fdc.r = 0;                                                      // デゼニワールド |  | 
| fdc.rreg = 0; |  | 
| #endif |  | 
 | break; | break; | 
 |  |  | 
 | case 0x01:                                                              // シーク | case 0x01:                                                              // シーク | 
| fdc.motor = 0x80;                                       // モーターOn | fdc.s.motor = 0x80;                                     // モーターOn | 
| fdc.step = (char)((fdc.c<=fdc.data)?1:-1); | fdc.s.step = (SINT8)((fdc.s.c<=fdc.s.data)?1:-1); | 
| #if 0                                                                                           // スタクル             // ver0.50 | fdc.s.c = fdc.s.data; | 
| fdc.rreg = fdc.r = 0; | seekcmd(); | 
| #endif |  | 
| fdc.c = fdc.data; |  | 
| fdc.treg = fdc.data; |  | 
| FDDMTR_MOVE; |  | 
 | break; | break; | 
 |  |  | 
 | case 0x02:                                                              // ステップ | case 0x02:                                                              // ステップ | 
 | case 0x03: | case 0x03: | 
| if (fdc.motor) { | if (fdc.s.motor) { | 
| fdc.c += fdc.step; | fdc.s.c += fdc.s.step; | 
 | if (cmd & 1) { | if (cmd & 1) { | 
| FDDMTR_MOVE; | seekcmd(); | 
| fdc.treg = fdc.c; |  | 
 | } | } | 
 | } | } | 
 | break; | break; | 
 |  |  | 
 | case 0x04:                                                              // ステップイン | case 0x04:                                                              // ステップイン | 
 | case 0x05: | case 0x05: | 
| if (fdc.motor) { | if (fdc.s.motor) { | 
| fdc.step = 1; | fdc.s.step = 1; | 
| fdc.c++; | fdc.s.c++; | 
 | if (cmd & 1) { | if (cmd & 1) { | 
| FDDMTR_MOVE; | seekcmd(); | 
| fdc.treg = fdc.c; |  | 
 | } | } | 
 | } | } | 
 | break; | break; | 
 |  |  | 
 | case 0x06:                                                              // ステップアウト | case 0x06:                                                              // ステップアウト | 
 | case 0x07: | case 0x07: | 
| if (fdc.motor) { | if (fdc.s.motor) { | 
| fdc.step = -1; | fdc.s.step = -1; | 
| fdc.c--; | fdc.s.c--; | 
 | if (cmd & 1) { | if (cmd & 1) { | 
| FDDMTR_MOVE; | seekcmd(); | 
| fdc.treg = fdc.c; |  | 
 | } | } | 
 | } | } | 
 | break; | break; | 
| Line 157  void IOOUTCALL fdc_o(UINT port, REG8 val | Line 289  void IOOUTCALL fdc_o(UINT port, REG8 val | 
 | case 0x09: | case 0x09: | 
 | case 0x0a:                                                              // ライトデータ | case 0x0a:                                                              // ライトデータ | 
 | case 0x0b: | case 0x0b: | 
| fdc.off = 0; | setbusy(500); | 
| fdcdummyread = 2; | fdc.s.stat = type2cmd(fdc.s.r); | 
| if (fdc.motor) { |  | 
| if (dma.DMA_ENBL) { |  | 
| dma.DMA_REDY = 0; |  | 
| //                                              fdc.skip = 0;                   // DMAで割り込みを監視する事! |  | 
| } |  | 
| } |  | 
 | break; | break; | 
 |  |  | 
 | case 0xc:                                                               // リードアドレス | case 0xc:                                                               // リードアドレス | 
| fdc.s.bufpos = 0; | setbusy(200); | 
| fdc.s.bufsize = 0; | fdc.s.stat = crccmd(); | 
| fdcdummyread = 2; |  | 
| if (fdc.motor) {                                                                        // ver0.25 |  | 
| if (dma.DMA_ENBL) { |  | 
| dma.DMA_REDY = 0; |  | 
| } |  | 
| } |  | 
| { |  | 
| FDDFILE fdd = fddfile + fdc.drv; |  | 
| switch(fdd->type) { |  | 
| case DISKTYPE_BETA: |  | 
| fdd2d_crc(fdd); |  | 
| break; |  | 
|  |  | 
| case DISKTYPE_D88: |  | 
| default: |  | 
| fddd88_crc(fdd); |  | 
| break; |  | 
| } |  | 
| } |  | 
 | break; | break; | 
 |  |  | 
 | case 0x0d:                                                              // フォースインタラプト | case 0x0d:                                                              // フォースインタラプト | 
| fdcdummyread = 0;                                       // 必要ない? | setbusy(0);                                                     // 必要ない? | 
| fdc.skip = 0;                                           // 000330 | //                              fdc.s.skip = 0;                                         // 000330 | 
 | dma.DMA_REDY = 8;                                       // ver0.25 | dma.DMA_REDY = 8;                                       // ver0.25 | 
 | break; | break; | 
 |  |  | 
 | case 0x0e:                                                              // リードトラック | case 0x0e:                                                              // リードトラック | 
| readdiag = 0; | setbusy(200); | 
|  | ZeroMemory(fdc.s.buffer, 0x1a00); | 
|  | fdc.s.bufpos = 0; | 
|  | fdc.s.bufsize = 0x1a00; | 
|  | fdc.s.bufdir = FDCDIR_IN; | 
 | break; | break; | 
 |  |  | 
 | case 0x0f:                                                              // ライトトラック | case 0x0f:                                                              // ライトトラック | 
 |  | #if 0 | 
 | { | { | 
| FDDFILE fdd = fddfile + fdc.drv; | FDDFILE fdd = fddfile + fdc.s.drv; | 
 | switch(fdd->type) { | switch(fdd->type) { | 
 | case DISKTYPE_NOTREADY: | case DISKTYPE_NOTREADY: | 
 | case DISKTYPE_BETA: | case DISKTYPE_BETA: | 
| Line 211  void IOOUTCALL fdc_o(UINT port, REG8 val | Line 323  void IOOUTCALL fdc_o(UINT port, REG8 val | 
 |  |  | 
 | case DISKTYPE_D88: | case DISKTYPE_D88: | 
 | default: | default: | 
| if (fdc.motor) {                                                // ver0.25 | if (fdc.s.motor) {                                              // ver0.25 | 
 | init_tao_d88(); | init_tao_d88(); | 
 | if (dma.DMA_ENBL) { | if (dma.DMA_ENBL) { | 
 | dma.DMA_REDY = 0; | dma.DMA_REDY = 0; | 
| Line 220  void IOOUTCALL fdc_o(UINT port, REG8 val | Line 332  void IOOUTCALL fdc_o(UINT port, REG8 val | 
 | break; | break; | 
 | } | } | 
 | } | } | 
 |  | #endif | 
 | break; | break; | 
 | } | } | 
 | } | } | 
 | else { | else { | 
| cmd = (REG8)(fdc.cmd >> 4); | cmd = (REG8)(fdc.s.cmd >> 4); | 
 | switch(port) { | switch(port) { | 
 | case 0x09:                                                              // トラック | case 0x09:                                                              // トラック | 
| fdc.treg = value; | fdc.s.c = value; | 
 | break; | break; | 
 |  |  | 
 | case 0x0a:                                                              // セクタ | case 0x0a:                                                              // セクタ | 
 | FDDMTR_WAITSEC(value); | FDDMTR_WAITSEC(value); | 
| fdc.r = value; | fdc.s.r = value; | 
| fdc.rreg = value; | fdc.s.rreg = value; | 
 | break; | break; | 
 |  |  | 
 | case 0x0b:                                                              // データ | case 0x0b:                                                              // データ | 
| fdc.data = value; | fdc.s.data = value; | 
| if ((cmd == 0x0a) || (cmd == 0x0b)) { | if ((fdc.s.motor) && (fdc.s.bufdir == FDCDIR_OUT)) { | 
| FDDFILE fdd = fddfile + fdc.drv; | fdc.s.buffer[fdc.s.bufpos] = value; | 
| switch(fdd->type) { | fdc.s.bufwrite = TRUE; | 
| case DISKTYPE_NOTREADY: | bufposinc(); | 
| break; |  | 
|  |  | 
| case DISKTYPE_BETA: |  | 
| fdd_write_2d(); |  | 
| break; |  | 
|  |  | 
| case DISKTYPE_D88: |  | 
| default: |  | 
| fdd_write_d88(); |  | 
| break; |  | 
| } |  | 
| inc_off(); |  | 
 | } | } | 
 |  | #if 0 | 
 | else if (cmd == 0x0f) {                         // TRACK WRITE | else if (cmd == 0x0f) {                         // TRACK WRITE | 
| FDDFILE fdd = fddfile + fdc.drv; | FDDFILE fdd = fddfile + fdc.s.drv; | 
 | switch(fdd->type) { | switch(fdd->type) { | 
 | case DISKTYPE_NOTREADY: | case DISKTYPE_NOTREADY: | 
 | case DISKTYPE_BETA: | case DISKTYPE_BETA: | 
| Line 268  void IOOUTCALL fdc_o(UINT port, REG8 val | Line 370  void IOOUTCALL fdc_o(UINT port, REG8 val | 
 | break; | break; | 
 | } | } | 
 | } | } | 
 |  | #endif | 
 | break; | break; | 
 |  |  | 
 | case 0x0c:                                                              // ドライブ・サイド | case 0x0c:                                                              // ドライブ・サイド | 
| driveset = 1; | fdc.s.ctbl[fdc.s.drv] = fdc.s.c; | 
| FDC_c[fdc.drv] = fdc.c; | fdc.s.c = fdc.s.ctbl[value & 0x03]; | 
| fdc.c = FDC_c[value & 0x03];                    // XTAL !!! | fdc.s.motor = (UINT8)(value & 0x80); | 
| fdc.motor = (UINT8)(value & 0x80); | fdc.s.drv = (UINT8)(value & 0x03); | 
| fdc.drv = (UINT8)(value & 0x03); | fdc.s.h = (UINT8)((value >> 4) & 1); | 
| fdc.h = (UINT8)((value >> 4) & 1); | fdc.s.cmd = 0;                                                  // T&E SORCERIAN | 
|  | fdc.s.type = 0; | 
| fdc.cmd = 0;                                                    // T&E SORCERIAN |  | 
| //                              fdc.data = 0;                                                   // 影の伝説 |  | 
| fdc.type = 0; |  | 
 |  |  | 
 | FDDMTR_DRVSET; | FDDMTR_DRVSET; | 
| if (!fdc.motor) { | if (!fdc.s.motor) { | 
| fdc.r = 0;                                                      // SACOM TELENET | fdc.s.r = 0;                                            // SACOM TELENET | 
| fdc.rreg = 0; | fdc.s.rreg = 0; | 
| #if 0                                                                                                   // XTAL |  | 
| fdc.c = 0; |  | 
| fdc.step = 1; |  | 
| #endif |  | 
 | } | } | 
 | break; | break; | 
 | } | } | 
| Line 301  REG8 IOINPCALL fdc_i(UINT port) { | Line 397  REG8 IOINPCALL fdc_i(UINT port) { | 
 | static  BYTE    timeoutwait; | static  BYTE    timeoutwait; | 
 | static  BYTE    last_r; | static  BYTE    last_r; | 
 | static  short   last_off; | static  short   last_off; | 
| BYTE    ans; | REG8    cmd; | 
| REG8    cmd; | REG8    ret; | 
 |  |  | 
 | if ((port & (~7)) != 0x0ff8) { | if ((port & (~7)) != 0x0ff8) { | 
 | return(0xff); | return(0xff); | 
 | } | } | 
| cmd = (REG8)(fdc.cmd >> 4); | cmd = (REG8)(fdc.s.cmd >> 4); | 
 | if ((port &= 0xf) != 8) { | if ((port &= 0xf) != 8) { | 
 | last_r = -1; | last_r = -1; | 
 | last_off = -1; | last_off = -1; | 
| Line 315  static short last_off; | Line 411  static short last_off; | 
 | } | } | 
 | switch(port) { | switch(port) { | 
 | case 0x8:       // ステータス | case 0x8:       // ステータス | 
| ans = 0; | ret = fdc.s.busy; | 
| fdcdummyread = 0; | if (ret) { | 
| if (fdc.skip) { | return(ret); | 
| fdc.skip--; |  | 
| return(0x01); |  | 
| } |  | 
| if (fdc.busyclock) {                                    // ver0.25 |  | 
| if (((h_cntbase + h_cnt) - fdc.busystart) < fdc.busyclock) { |  | 
| return(0x01); |  | 
| } |  | 
| fdc.busyclock = 0; |  | 
| } |  | 
| { |  | 
| FDDFILE fdd = fddfile + fdc.drv; |  | 
| if (fdd->type == DISKTYPE_NOTREADY) { |  | 
| if (fdc.type == 1 && fdc.c == 0) {      // ドライブチェック !!! |  | 
| return(0x84);                                   // ←接続されてる時だけ |  | 
| } |  | 
| return(0x80); |  | 
 | } | } | 
| } | #if 0 | 
| if (fdc.type == 2) { | if (fdc.s.type == 2) { | 
| if (last_r == fdc.r && last_off == fdc.off && | if (last_r == _fdc.r && last_off == fdc.off && | 
 | !(--timeoutwait)) { | !(--timeoutwait)) { | 
 | inc_off(); | inc_off(); | 
 | timeoutwait = 4; | timeoutwait = 4; | 
 | } | } | 
| last_r = fdc.r; | last_r = _fdc.r; | 
 | last_off = fdc.off; | last_off = fdc.off; | 
 | }                                                       // Read Write時のみの変化でいい筈 | }                                                       // Read Write時のみの変化でいい筈 | 
 | if (!((ans = fdd_stat()) & 2)) { |  | 
 | dma.DMA_REDY = 8;                               // <- DMA ノ レディシンゴウ ヲ クリア |  | 
 | } |  | 
 | #if 1 |  | 
 | if (driveset) {                                 // 0xffcを叩いた直後だったら |  | 
 | ans &= 0xc4; |  | 
 | } |  | 
 | #endif | #endif | 
| return(ans); | ret = getstat(); | 
|  | if (!(ret & 0x02)) { | 
|  | dma.DMA_REDY = 8; | 
|  | } | 
|  | return(ret); | 
 |  |  | 
| case 0x9:                                                       // トラック | case 0x9:                                                       // トラック | 
| return(fdc.treg); | return(fdc.s.creg); | 
 |  |  | 
| case 0xa:                                                       // セクタ | case 0xa:                                                       // セクタ | 
| return(fdc.rreg);                               // ver0.25 | return(fdc.s.rreg); | 
 |  |  | 
 | case 0xb:                                                       // データ | case 0xb:                                                       // データ | 
| if (fdc.motor) { | if (fdc.s.motor) { | 
| if ((cmd == 0x08) || (cmd == 0x09)) {   // リード・データ | if (fdc.s.bufdir == FDCDIR_IN) { | 
| FDDFILE fdd; | fdc.s.data = fdc.s.buffer[fdc.s.bufpos]; | 
| fdd = fddfile + fdc.drv; | TRACEOUT(("sector read %.2x (%.2x) [%.4x]", fdc.s.data, fdc.s.bufpos, Z80_PC)); | 
| switch(fdd->type) { | bufposinc(); | 
| case DISKTYPE_NOTREADY: |  | 
| break; |  | 
|  |  | 
| case DISKTYPE_BETA: |  | 
| fdd_read_2d(); |  | 
| break; |  | 
|  |  | 
| case DISKTYPE_D88: |  | 
| default: |  | 
| fdd_read_d88();         // WOODY POCO !!! |  | 
| break; |  | 
| } |  | 
| inc_off(); |  | 
| } |  | 
| else if (cmd == 0x0c) {                 // リード・アドレス |  | 
| if (fdc.s.bufpos < 6) { |  | 
| fdc.data = fdc.s.buffer[fdc.s.bufpos]; |  | 
| if (fdcdummyread) { |  | 
| fdcdummyread--; |  | 
| } |  | 
| else { |  | 
| fdc.s.bufpos++; |  | 
| } |  | 
| } |  | 
| } |  | 
| else if (cmd == 0x0e) {                                                         // ver0.25 |  | 
| fdc.data = 0; |  | 
| readdiag++; |  | 
 | } | } | 
 | } | } | 
| return(fdc.data);                                       // WOODY POCO !!! | return(fdc.s.data);                                     // WOODY POCO !!! | 
 |  |  | 
 | //              case 0xc:                                                               // FM | //              case 0xc:                                                               // FM | 
 | //              case 0xd:                                                               // MFM | //              case 0xd:                                                               // MFM | 
| Line 421  void fdc_reset(void) { | Line 470  void fdc_reset(void) { | 
 |  |  | 
 | FDDMTR_INIT; | FDDMTR_INIT; | 
 | ZeroMemory(&fdc, sizeof(fdc)); | ZeroMemory(&fdc, sizeof(fdc)); | 
| fdc.step = 1; | fdc.s.step = 1; | 
| ZeroMemory(FDC_c, 4); |  | 
 | } | } | 
 |  |  |