--- xmil/fdd/fdd_d88.c 2004/08/10 08:28:48 1.9 +++ xmil/fdd/fdd_d88.c 2004/08/18 08:08:13 1.13 @@ -18,6 +18,7 @@ typedef struct { UINT track; long fptr; UINT size; + UINT sectors; UINT8 buf[D88BUFSIZE]; } _D88TRK, *D88TRK; @@ -71,9 +72,14 @@ dtfd_err1: static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { - FILEH fh; - UINT32 fptr; - UINT32 size; + FILEH fh; + UINT32 fptr; + UINT size; +const _D88SEC *sec; + UINT rem; + UINT maxsectors; + UINT sectors; + UINT secsize; trackflush(trk); if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) { @@ -106,6 +112,27 @@ static D88TRK trackread(D88TRK trk, FDDF trk->track = track; trk->fptr = fptr; 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); dtrd_err2: @@ -139,32 +166,19 @@ static D88TRK trackseek(FDDFILE fdd, REG static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { const _D88SEC *sec; - UINT rem; - UINT secnum; UINT sectors; UINT size; sec = (D88SEC)trk->buf; - rem = trk->size; - sectors = LOADINTELWORD(sec->sectors); - if (sectors) { - secnum = 0; - do { - size = LOADINTELWORD(sec->size); - size += sizeof(_D88SEC); - if (rem < size) { - break; - } - if (sec->r == r) { - return((D88SEC)sec); - } - secnum++; - sectors = LOADINTELWORD(sec->sectors); - if (secnum >= sectors) { - break; - } - sec = (D88SEC)(((UINT8 *)sec) + size); - } while(secnum < 40); + sectors = trk->sectors; + while(sectors) { + sectors--; + if (sec->r == r) { + return((D88SEC)sec); + } + size = LOADINTELWORD(sec->size); + size += sizeof(_D88SEC); + sec = (D88SEC)(((UINT8 *)sec) + size); } return(NULL); } @@ -251,36 +265,22 @@ static REG8 fddd88_crc(FDDFILE fdd, REG8 const _D88TRK *trk; const _D88SEC *sec; - UINT secnum; - UINT rem; - UINT size; UINT sectors; + UINT size; trk = trackseek(fdd, media, track); if (trk == NULL) { return(FDDSTAT_RECNFND); } sec = (D88SEC)trk->buf; - sectors = LOADINTELWORD(sec->sectors); - if (sectors == 0) { + sectors = trk->sectors; + if (num >= sectors) { return(FDDSTAT_RECNFND); } - secnum = 0; - rem = trk->size; - while(1) { + while(num) { + num--; size = LOADINTELWORD(sec->size); 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); } ptr[0] = sec->c; @@ -296,6 +296,35 @@ const _D88SEC *sec; 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 + // ---- @@ -335,6 +364,9 @@ BRESULT fddd88_set(FDDFILE fdd, const OE fdd->read = fddd88_read; fdd->write = fddd88_write; fdd->crc = fddd88_crc; +#if defined(SUPPORT_DISKEXT) + fdd->sec = fddd88_sec; +#endif return(SUCCESS); fdst_err: @@ -378,23 +410,6 @@ static BYTE *curdata; 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 { BYTE mode; @@ -421,279 +436,8 @@ static BYTE D88_BUF[0x4000]; 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) { FDDFILE fdd;