| version 1.9, 2004/08/10 08:28:48 | version 1.14, 2004/08/18 15:42:32 | 
| Line 18  typedef struct { | Line 18  typedef struct { | 
 | UINT    track; | UINT    track; | 
 | long    fptr; | long    fptr; | 
 | UINT    size; | UINT    size; | 
 |  | UINT    sectors; | 
 | UINT8   buf[D88BUFSIZE]; | UINT8   buf[D88BUFSIZE]; | 
 | } _D88TRK, *D88TRK; | } _D88TRK, *D88TRK; | 
 |  |  | 
| Line 71  dtfd_err1: | Line 72  dtfd_err1: | 
 |  |  | 
 | static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { | static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { | 
 |  |  | 
| FILEH   fh; | FILEH           fh; | 
| UINT32  fptr; | UINT32          fptr; | 
| UINT32  size; | UINT            size; | 
|  | const _D88SEC   *sec; | 
|  | UINT            rem; | 
|  | UINT            maxsectors; | 
|  | UINT            sectors; | 
|  | UINT            secsize; | 
 |  |  | 
 | trackflush(trk); | trackflush(trk); | 
 | if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) { | if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) { | 
| Line 106  static D88TRK trackread(D88TRK trk, FDDF | Line 112  static D88TRK trackread(D88TRK trk, FDDF | 
 | trk->track = track; | trk->track = track; | 
 | trk->fptr = fptr; | trk->fptr = fptr; | 
 | trk->size = size; | 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); | return(trk); | 
 |  |  | 
 | dtrd_err2: | dtrd_err2: | 
| Line 139  static D88TRK trackseek(FDDFILE fdd, REG | Line 166  static D88TRK trackseek(FDDFILE fdd, REG | 
 | static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { | static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { | 
 |  |  | 
 | const _D88SEC   *sec; | const _D88SEC   *sec; | 
 | UINT            rem; |  | 
 | UINT            secnum; |  | 
 | UINT            sectors; | UINT            sectors; | 
 | UINT            size; | UINT            size; | 
 |  |  | 
 | sec = (D88SEC)trk->buf; | sec = (D88SEC)trk->buf; | 
| rem = trk->size; | sectors = trk->sectors; | 
| sectors = LOADINTELWORD(sec->sectors); | while(sectors) { | 
| if (sectors) { | sectors--; | 
| secnum = 0; | if (sec->r == r) { | 
| do { | return((D88SEC)sec); | 
| size = LOADINTELWORD(sec->size); | } | 
| size += sizeof(_D88SEC); | size = LOADINTELWORD(sec->size); | 
| if (rem < size) { | size += sizeof(_D88SEC); | 
| break; | sec = (D88SEC)(((UINT8 *)sec) + size); | 
| } |  | 
| if (sec->r == r) { |  | 
| return((D88SEC)sec); |  | 
| } |  | 
| secnum++; |  | 
| sectors = LOADINTELWORD(sec->sectors); |  | 
| if (secnum >= sectors) { |  | 
| break; |  | 
| } |  | 
| sec = (D88SEC)(((UINT8 *)sec) + size); |  | 
| } while(secnum < 40); |  | 
 | } | } | 
 | return(NULL); | return(NULL); | 
 | } | } | 
| Line 251  static REG8 fddd88_crc(FDDFILE fdd, REG8 | Line 265  static REG8 fddd88_crc(FDDFILE fdd, REG8 | 
 |  |  | 
 | const _D88TRK   *trk; | const _D88TRK   *trk; | 
 | const _D88SEC   *sec; | const _D88SEC   *sec; | 
 | UINT            secnum; |  | 
 | UINT            rem; |  | 
 | UINT            size; |  | 
 | UINT            sectors; | UINT            sectors; | 
 |  | UINT            size; | 
 |  |  | 
 | trk = trackseek(fdd, media, track); | trk = trackseek(fdd, media, track); | 
 | if (trk == NULL) { | if (trk == NULL) { | 
 | return(FDDSTAT_RECNFND); | return(FDDSTAT_RECNFND); | 
 | } | } | 
 | sec = (D88SEC)trk->buf; | sec = (D88SEC)trk->buf; | 
| sectors = LOADINTELWORD(sec->sectors); | sectors = trk->sectors; | 
| if (sectors == 0) { | if (num >= sectors) { | 
 | return(FDDSTAT_RECNFND); | return(FDDSTAT_RECNFND); | 
 | } | } | 
| secnum = 0; | while(num) { | 
| rem = trk->size; | num--; | 
| while(1) { |  | 
 | size = LOADINTELWORD(sec->size); | size = LOADINTELWORD(sec->size); | 
 | size += sizeof(_D88SEC); | size += sizeof(_D88SEC); | 
 | if (rem < size) { |  | 
 | return(FDDSTAT_RECNFND); |  | 
 | } |  | 
 | if (num == secnum) { |  | 
 | break; |  | 
 | } |  | 
 | secnum++; |  | 
 | sectors = LOADINTELWORD(sec->sectors); |  | 
 | if (secnum >= sectors) { |  | 
 | return(FDDSTAT_RECNFND); |  | 
 | } |  | 
 | sec = (D88SEC)(((UINT8 *)sec) + size); | sec = (D88SEC)(((UINT8 *)sec) + size); | 
 | } | } | 
 | ptr[0] = sec->c; | ptr[0] = sec->c; | 
| Line 296  const _D88SEC *sec; | Line 296  const _D88SEC *sec; | 
 | return(0x00); | return(0x00); | 
 | } | } | 
 |  |  | 
 |  | #if defined(SUPPORT_DISKEXT) | 
 |  | static UINT32 fddd88_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) { | 
 |  |  | 
 |  | const _D88TRK   *trk; | 
 |  | const _D88SEC   *sec; | 
 |  | UINT            sectors; | 
 |  | UINT            num; | 
 |  | UINT            size; | 
 |  |  | 
 |  | trk = trackseek(fdd, media, track); | 
 |  | if (trk == NULL) { | 
 |  | return(0); | 
 |  | } | 
 |  | sec = (D88SEC)trk->buf; | 
 |  | sectors = trk->sectors; | 
 |  | num = 0; | 
 |  | while(num < sectors) { | 
 |  | if (sec->r == sc) { | 
 |  | break; | 
 |  | } | 
 |  | size = LOADINTELWORD(sec->size); | 
 |  | size += sizeof(_D88SEC); | 
 |  | sec = (D88SEC)(((UINT8 *)sec) + size); | 
 |  | num++; | 
 |  | } | 
 |  | return((UINT32)(sectors << 16) + num); | 
 |  | } | 
 |  | #endif | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
| Line 303  BRESULT fddd88_set(FDDFILE fdd, const OE | Line 332  BRESULT fddd88_set(FDDFILE fdd, const OE | 
 |  |  | 
 | short   attr; | short   attr; | 
 | FILEH   fh; | FILEH   fh; | 
| BOOL    r; | BRESULT r; | 
 | UINT8   ptr[D88_TRACKMAX][4]; | UINT8   ptr[D88_TRACKMAX][4]; | 
 | UINT    i; | UINT    i; | 
 |  |  | 
| Line 335  BRESULT fddd88_set(FDDFILE fdd, const OE | Line 364  BRESULT fddd88_set(FDDFILE fdd, const OE | 
 | fdd->read = fddd88_read; | fdd->read = fddd88_read; | 
 | fdd->write = fddd88_write; | fdd->write = fddd88_write; | 
 | fdd->crc = fddd88_crc; | fdd->crc = fddd88_crc; | 
 |  | #if defined(SUPPORT_DISKEXT) | 
 |  | fdd->sec = fddd88_sec; | 
 |  | #endif | 
 | return(SUCCESS); | return(SUCCESS); | 
 |  |  | 
 | fdst_err: | fdst_err: | 
| Line 378  static BYTE  *curdata; | Line 410  static BYTE  *curdata; | 
 |  |  | 
 | extern  WORD            readdiag; | 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; | BYTE    mode; | 
| Line 421  static BYTE  D88_BUF[0x4000]; | Line 436  static BYTE  D88_BUF[0x4000]; | 
 | static  BYTE            TAO_BUF[0x3000]; | static  BYTE            TAO_BUF[0x3000]; | 
 |  |  | 
 |  |  | 
 | //---------------------------------------------------------------------- |  | 
 |  |  | 
 |  |  | 
 | static int curdataflush(void) { |  | 
 |  |  | 
 | FDDFILE fdd; |  | 
 | FILEH   fh; |  | 
 | int             ret = 0; |  | 
 |  |  | 
 | if ((!curfp) || (!cursize)) { |  | 
 | return(-1); |  | 
 | } |  | 
 | if (!curwrite) { |  | 
 | return(0); |  | 
 | } |  | 
 | curwrite = 0; |  | 
 | fdd = fddfile + curdrv; |  | 
 | fh = file_open(fdd->fname); |  | 
 | if (fh == FILEH_INVALID) { |  | 
 | return(-1); |  | 
 | } |  | 
 | if ((file_seek(fh, curfp, FSEEK_SET) != curfp) || |  | 
 | (file_write(fh, D88_BUF, cursize) != cursize)) { |  | 
 | ret = -1; |  | 
 | } |  | 
 | if (file_close(fh)) { |  | 
 | ret = -1; |  | 
 | } |  | 
 | return(ret); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | static DWORD read_d88track(REG8 drv, UINT track, REG8 media) { |  | 
 |  |  | 
 | FDDFILE fdd; |  | 
 | FILEH   hdr; |  | 
 |  |  | 
 | curdataflush(); |  | 
 | curdrv = drv; |  | 
 | curtrk = track; |  | 
 | curtype = media; |  | 
 | cursct = (UINT)-1; |  | 
 | curwrite = 0; |  | 
 | curtrkerr = 0; |  | 
 | //      crcnum = 0; |  | 
 | crcerror = 0; |  | 
 |  |  | 
 | fdd = fddfile + drv; |  | 
 | if ((drv < 0) || (drv > 3) || (track > 163) || |  | 
 | (media != (fdd->inf.d88.head.fd_type >> 4)) || |  | 
 | ((curfp = fdd->inf.d88.ptr[track]) == 0) || |  | 
 | ((cursize = nexttrackptr(fdd, curfp, |  | 
 | fdd->inf.d88.fd_size) - curfp) > 0x4000)) { |  | 
 | goto readd88_err; |  | 
 | } |  | 
 |  |  | 
 | if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { |  | 
 | goto readd88_err; |  | 
 | } |  | 
 | if (file_seek(hdr, curfp, FSEEK_SET) != curfp) { |  | 
 | file_close(hdr); |  | 
 | goto readd88_err; |  | 
 | } |  | 
 | if (file_read(hdr, D88_BUF, cursize) != cursize) { |  | 
 | file_close(hdr); |  | 
 | goto readd88_err; |  | 
 | } |  | 
 | if (file_close(hdr)) { |  | 
 | goto readd88_err; |  | 
 | } |  | 
 | return(TRUE); |  | 
 |  |  | 
 | readd88_err: |  | 
 | curfp = 0; |  | 
 | cursize = 0; |  | 
 | curtrkerr = 1; |  | 
 | return(FALSE); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 |  |  | 
 |  |  | 
 | static int seeksector(REG8 drv, UINT track, UINT r) { |  | 
 |  |  | 
 | static  int             lastflag = FALSE; |  | 
 |  |  | 
 | const _D88SEC   *p; |  | 
 | UINT            sec; |  | 
 | UINT            sectors; |  | 
 | UINT            secsize; |  | 
 |  |  | 
 | if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.s.media)) { |  | 
 | read_d88track(drv, track, fdc.s.media); |  | 
 | } |  | 
 | 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); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
 |  |  | 
 |  |  | 
 |  |  | 
 | //********************************************************************** |  | 
 |  |  | 
 |  |  | 
 |  |  | 
 | BYTE fdd_stat_d88(void) { |  | 
 |  |  | 
 | FDDFILE         fdd; |  | 
 | BYTE            type; |  | 
 | REG8            cmd; |  | 
 | UINT            trk; |  | 
 | BYTE            ans = 0; |  | 
 | int                     seekable; |  | 
 |  |  | 
 | fdd = fddfile + fdc.s.drv; |  | 
 | if (fdd->type != DISKTYPE_D88) { |  | 
 | return(0x80);                                           // NOT READY |  | 
 | } |  | 
 | cmd = (REG8)(fdc.s.cmd >> 4); |  | 
 | type = fdc.s.type; |  | 
 | trk = (fdc.s.c << 1) + fdc.s.h; |  | 
 | seekable = seeksector(fdc.s.drv, trk, fdc.s.r); |  | 
 | if (!fdc.s.r) { |  | 
 | seekable = TRUE; |  | 
 | } |  | 
 |  |  | 
 | if (type == 0 || type == 1 || type == 4 || |  | 
 | cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) { |  | 
 | if (fdd->protect) {                                     // WRITE PROTECT |  | 
 | ans |= 0x40; |  | 
 | } |  | 
 | } |  | 
 | if (type == 2 || cmd == 0x0f) { |  | 
 | if (fdc.s.r && cursec.del_flg) { |  | 
 | ans |= 0x20;                                    // RECODE TYPE / WRITE FAULT |  | 
 | } |  | 
 | } |  | 
 | if (type == 1 || type == 2) { |  | 
 | if ((trk > 163) || (!seekable)) { |  | 
 | ans |= 0x10;                                    // SEEK ERROR / RECORD NOT FOUND |  | 
 | } |  | 
 | if ((!(ans & 0xf0)) && fdc.s.r && (cursec.stat)) { |  | 
 | ans |= 0x08;                                    // CRC ERROR |  | 
 | } |  | 
 | } |  | 
 | if (cmd == 0x0c) { |  | 
 | if (curtrkerr) { |  | 
 | ans |= 0x10; |  | 
 | } |  | 
 | if (crcerror) { |  | 
 | ans |= 0x08;                                    // CRC ERROR |  | 
 | } |  | 
 | } |  | 
 | if (type == 1 || type == 4) { |  | 
 | if (type == 1) {                                        // ver0.25 |  | 
 | ans |= 0x20;                                    // HEAD ENGAGED (X1 デハ ツネニ 1) |  | 
 | if (!fdc.s.c) {                                 // TRACK00 |  | 
 | ans |= 0x04; |  | 
 | } |  | 
 | } |  | 
 | if (++hole < 8) {                                       // ver0.25 |  | 
 | ans |= 0x02;                                    // INDEX |  | 
 | } |  | 
 | } |  | 
 | else if (!(ans & 0xf0)) { |  | 
 | if ((type != 4) && (FDDMTR_BUSY)) { |  | 
 | ans |= 0x01; |  | 
 | } |  | 
 | if (type == 2) { |  | 
 | UINT secsize = LOADINTELWORD(cursec.size); |  | 
 | if ((UINT)fdc.off < secsize) { |  | 
 | ans |= 0x03;                                    // DATA REQUEST / BUSY |  | 
 | } |  | 
 | } |  | 
 | else if ((cmd == 0x0c) && (fdc.s.bufpos < 6)) { |  | 
 | ans |= 0x03; |  | 
 | } |  | 
 | else if ((cmd == 0x0e) && (readdiag < 0x1a00)) { |  | 
 | 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.s.data = curdata[fdc.off]; |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | void fdd_write_d88(void) { |  | 
 |  |  | 
 | if ((fdd_stat_d88() & 0xf3) == 3) { |  | 
 | curdata[fdc.off] = fdc.s.data; |  | 
 | curwrite = 1; |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | BYTE fdd_incoff_d88(void) { |  | 
 |  |  | 
 | REG8    cmd; |  | 
 | UINT    trk; |  | 
 | UINT    secsize; |  | 
 |  |  | 
 | cmd = (REG8)(fdc.s.cmd >> 4); |  | 
 | trk = (fdc.s.c << 1) + fdc.s.h; |  | 
 | seeksector(fdc.s.drv, trk, fdc.s.r); |  | 
 | fdc.off++; |  | 
 | secsize = LOADINTELWORD(cursec.size); |  | 
 | if ((UINT)fdc.off < secsize) { |  | 
 | return(0); |  | 
 | } |  | 
 | fdc.off = secsize; |  | 
 | if ((cmd == 0x09) || (cmd == 0x0b)) { |  | 
 | fdc.s.rreg = fdc.s.r + 1;                                               // ver0.25 |  | 
 | if (seeksector(fdc.s.drv, trk, fdc.s.rreg)) { |  | 
 | fdc.s.r++; |  | 
 | fdc.off = 0; |  | 
 | return(0); |  | 
 | } |  | 
 | } |  | 
 | return(1); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | // --------------------------------------------------------------------------- |  | 
 |  |  | 
 | void init_tao_d88(void) { | void init_tao_d88(void) { | 
 |  |  | 
 | FDDFILE         fdd; | FDDFILE         fdd; |