--- xmil/fdd/fdd_d88.c 2004/08/08 12:32:58 1.6 +++ xmil/fdd/fdd_d88.c 2004/08/18 08:08:13 1.13 @@ -1,73 +1,29 @@ #include "compiler.h" #include "dosio.h" #include "pccore.h" -#include "iocore.h" #include "fddfile.h" #include "fdd_d88.h" #include "fdd_mtr.h" -// static D88_HEADER d88head[4]; -static _D88SEC cursec; -static REG8 curdrv = (REG8)-1; -static UINT curtrk = (UINT)-1; -static BYTE curtype = 0; -static UINT cursct = (UINT)-1; -static long curfp = 0; -static UINT cursize = 0; -static BYTE curwrite = 0; -static BYTE curtrkerr = 0; -static BYTE hole = 0; -static BYTE *curdata; -static UINT crcnum = 0; -static BYTE crcerror = FALSE; - -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 +enum { + D88BUFSIZE = 0x4000 +}; typedef struct { - BYTE mode; - BYTE flag; - WORD cnt; - WORD size; - WORD ptr; - WORD top; - WORD gap; - BYTE sector; - WORD lostdatacnt; - BYTE maxsector; - WORD maxsize; -} WID_PARA; - -#define LOSTDATA_COUNT 256 - -static WID_PARA WID_2D = {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 33, 0x1f80}; -static WID_PARA WID_2HD= {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 55, 0x2f80}; -static WID_PARA WID_ERR= {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0x0000}; -static WID_PARA tao = {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0x0000}; - -static BYTE D88_BUF[0x4000]; -static BYTE TAO_BUF[0x3000]; + FDDFILE fdd; + UINT8 media; + UINT8 write; + UINT8 padding[2]; + UINT track; + long fptr; + UINT size; + UINT sectors; + UINT8 buf[D88BUFSIZE]; +} _D88TRK, *D88TRK; +static _D88TRK d88trk; -//---------------------------------------------------------------------- static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) { @@ -83,339 +39,417 @@ static UINT32 nexttrackptr(FDDFILE fdd, return(last); } - -int curdataflush(void) { +static BRESULT trackflush(D88TRK trk) { FDDFILE fdd; FILEH fh; - int ret = 0; - if ((!curfp) || (!cursize)) { - return(-1); + fdd = trk->fdd; + trk->fdd = NULL; + if ((fdd == NULL) || (trk->size == 0) || (!trk->write)) { + goto dtfd_exit; } - if (!curwrite) { - return(0); - } - curwrite = 0; - fdd = fddfile + curdrv; fh = file_open(fdd->fname); if (fh == FILEH_INVALID) { - return(-1); + goto dtfd_err1; } - if ((file_seek(fh, curfp, FSEEK_SET) != curfp) || - (file_write(fh, D88_BUF, cursize) != cursize)) { - ret = -1; + if ((file_seek(fh, trk->fptr, FSEEK_SET) != trk->fptr) || + (file_write(fh, trk->buf, trk->size) != trk->size)) { + goto dtfd_err2; } - if (file_close(fh)) { - ret = -1; - } - return(ret); -} + file_close(fh); + trk->write = FALSE; +dtfd_exit: + return(SUCCESS); -static DWORD read_d88track(REG8 drv, UINT track, BYTE type) { +dtfd_err2: + file_close(fh); - FDDFILE fdd; - FILEH hdr; +dtfd_err1: + return(FAILURE); +} - curdataflush(); - curdrv = drv; - curtrk = track; - curtype = type; - cursct = (UINT)-1; - curwrite = 0; - curtrkerr = 0; - crcnum = 0; - crcerror = 0; - - fdd = fddfile + drv; - if ((drv < 0) || (drv > 3) || (track > 163) || - ((type == 0) && (fdd->inf.d88.head.fd_type == 0x20)) || - ((type == 1) && (fdd->inf.d88.head.fd_type != 0x20)) || - ((curfp = fdd->inf.d88.ptr[track]) == 0) || - ((cursize = nexttrackptr(fdd, curfp, - fdd->inf.d88.fd_size) - curfp) > 0x4000)) { - goto readd88_err; - } +static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { - if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { - goto readd88_err; + 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))) { + goto dtrd_err1; } - if (file_seek(hdr, curfp, FSEEK_SET) != curfp) { - file_close(hdr); - goto readd88_err; + if (track >= 164) { + goto dtrd_err1; + } + fptr = fdd->inf.d88.ptr[track]; + if (fptr == 0) { + goto dtrd_err1; } - if (file_read(hdr, D88_BUF, cursize) != cursize) { - file_close(hdr); - goto readd88_err; + size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr; + if (size > D88BUFSIZE) { + size = D88BUFSIZE; + } + fh = file_open_rb(fdd->fname); + if (fh == FILEH_INVALID) { + goto dtrd_err1; } - if (file_close(hdr)) { - goto readd88_err; + if ((file_seek(fh, (long)fptr, FSEEK_SET) != (long)fptr) || + (file_read(fh, trk->buf, size) != size)) { + goto dtrd_err2; } - return(TRUE); + file_close(fh); -readd88_err: - curfp = 0; - cursize = 0; - curtrkerr = 1; - return(FALSE); -} + trk->fdd = fdd; + trk->media = media; + trk->write = FALSE; + 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: + file_close(fh); +dtrd_err1: + return(NULL); +} +static void drvflush(FDDFILE fdd) { + D88TRK trk; -static int seeksector(REG8 drv, UINT track, UINT r) { + trk = &d88trk; + if (trk->fdd == fdd) { + trackflush(trk); + } +} -static int lastflag = FALSE; +static D88TRK trackseek(FDDFILE fdd, REG8 media, UINT track) { -const _D88SEC *p; - UINT sec; - UINT sectors; - UINT secsize; + D88TRK trk; - if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.media)) { - read_d88track(drv, track, fdc.media); + trk = &d88trk; + if ((trk->fdd != fdd) || (trk->media != media) || (trk->track != track)) { + trk = trackread(trk, fdd, media, track); } - 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); + return(trk); } -static void drvflush(REG8 drv) { +static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { + +const _D88SEC *sec; + UINT sectors; + UINT size; - if (curdrv == drv) { - curdataflush(); - curdrv = (REG8)-1; - curtrk = (UINT)-1; - cursct = (UINT)-1; + sec = (D88SEC)trk->buf; + 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); } +// ---- +static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) { -//********************************************************************** + if (trackseek(fdd, media, track) != NULL) { + return(0x00); + } + else { + return(FDDSTAT_SEEKERR); + } +} -short fdd_crc_d88(void) { +static REG8 fddd88_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc, + UINT8 *ptr, UINT *size) { - UINT track; -const _D88SEC *p; - UINT sec; - UINT sectors; +const _D88TRK *trk; +const _D88SEC *sec; UINT secsize; + REG8 ret; - ZeroMemory(fdc.crc_dat, 6); - track = (fdc.c << 1) + fdc.h; - if (track >= 164) { - goto crcerror_d88; + TRACEOUT(("d88 read %d:%.2x", track, sc)); + trk = trackseek(fdd, media, track); + if (trk == NULL) { + goto fd8r_err; + } + sec = sectorseek(trk, sc); + if (sec == NULL) { + goto fd8r_err; + } + ret = 0x00; + if (sec->del_flg) { + ret |= FDDSTAT_RECTYPE; + } + if (sec->stat) { + ret |= FDDSTAT_CRCERR; + } + secsize = LOADINTELWORD(sec->size); + secsize = min(secsize, *size); + if ((ptr) && (secsize)) { + CopyMemory(ptr, sec + 1, secsize); } - seeksector(fdc.drv, track, fdc.r); - if (curtrkerr) { - goto crcerror_d88; - } - p = (D88SEC)D88_BUF; - for (sec=0; secsectors); - secsize = LOADINTELWORD(p->size); - sec++; - if (sec >= sectors) { - goto crcerror_d88; - } - p = (D88SEC)(((UINT8 *)(p + 1)) + secsize); - } - fdc.rreg = p->c; // メルヘンヴェール - fdc.crc_dat[0] = p->c; - fdc.crc_dat[1] = p->h; - fdc.crc_dat[2] = p->r; - fdc.crc_dat[3] = p->n; - crcnum++; - if (p->stat) { - crcerror = TRUE; - } - else { - crcerror = FALSE; - } - return(0); + *size = secsize; + return(ret); -crcerror_d88:; - crcerror = TRUE; - return(1); +fd8r_err: + return(FDDSTAT_RECNFND); } +static REG8 fddd88_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc, + const UINT8 *ptr, UINT size) { -BYTE fdd_stat_d88(void) { + D88TRK trk; + D88SEC sec; + UINT secsize; - FDDFILE fdd; - BYTE type; - REG8 cmd; - UINT trk; - BYTE ans = 0; - int seekable; - - fdd = fddfile + fdc.drv; - if (fdd->type != DISKTYPE_D88) { - return(0x80); // NOT READY - } - type = fdc.type; - cmd = (REG8)(fdc.cmd >> 4); - trk = (fdc.c << 1) + fdc.h; - seekable = seeksector(fdc.drv, trk, fdc.r); - if (!fdc.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.r && cursec.del_flg) { - ans |= 0x20; // RECODE TYPE / WRITE FAULT - } + TRACEOUT(("d88 write %d:%.2x", track, sc)); + trk = trackseek(fdd, media, track); + if (trk == NULL) { + goto fd8w_err; } - if (type == 1 || type == 2) { - if ((trk > 163) || (!seekable)) { - ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND - } - if ((!(ans & 0xf0)) && fdc.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.c) { // TRACK00 - ans |= 0x04; - } - } - if (++hole < 8) { // ver0.25 - ans |= 0x02; // INDEX - } + sec = sectorseek(trk, sc); + if (sec == NULL) { + goto fd8w_err; } - 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 == 0x0e) && (readdiag < 0x1a00)) { - ans |= 0x03; - } - else if ((cmd == 0x0c) && (fdc.crc_off < 6)) { // ver0.25 - ans |= 0x03; - } - else if (cmd == 0x0f) { - if (tao.flag == 3) { - if (++tao.lostdatacnt > LOSTDATA_COUNT) { - tao.flag = 4; - } - } - ans |= tao.flag; - } + secsize = LOADINTELWORD(sec->size); + size = min(size, secsize); + if (size) { + CopyMemory(sec + 1, ptr, size); + trk->write = TRUE; } - return(ans); + return(0x00); + +fd8w_err: + return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); } +static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num, + UINT8 *ptr) { -//********************************************************************** +const _D88TRK *trk; +const _D88SEC *sec; + UINT sectors; + UINT size; -void fdd_read_d88(void) { - // POCO:読めなかったらレジスタを変更させない - if ((fdd_stat_d88() & 0xf3) == 3) { - fdc.data = curdata[fdc.off]; + trk = trackseek(fdd, media, track); + if (trk == NULL) { + return(FDDSTAT_RECNFND); + } + sec = (D88SEC)trk->buf; + sectors = trk->sectors; + if (num >= sectors) { + return(FDDSTAT_RECNFND); + } + while(num) { + num--; + size = LOADINTELWORD(sec->size); + size += sizeof(_D88SEC); + sec = (D88SEC)(((UINT8 *)sec) + size); + } + ptr[0] = sec->c; + ptr[1] = sec->h; + ptr[2] = sec->r; + ptr[3] = sec->n; + ptr[4] = 0; + ptr[5] = 0; +// fdc.s.rreg = sec->c; // メルヘンヴェール + if (sec->stat) { + return(FDDSTAT_CRCERR); } + return(0x00); } -void fdd_write_d88(void) { +#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; - if ((fdd_stat_d88() & 0xf3) == 3) { - curdata[fdc.off] = fdc.data; - curwrite = 1; + 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 -BYTE fdd_incoff_d88(void) { - REG8 cmd; - UINT trk; - UINT secsize; +// ---- - cmd = (REG8)(fdc.cmd >> 4); - trk = (fdc.c << 1) + fdc.h; - seeksector(fdc.drv, trk, fdc.r); - fdc.off++; - secsize = LOADINTELWORD(cursec.size); - if ((UINT)fdc.off < secsize) { - return(0); +BRESULT fddd88_set(FDDFILE fdd, const OEMCHAR *fname) { + + short attr; + FILEH fh; + BOOL r; + UINT8 ptr[D88_TRACKMAX][4]; + UINT i; + + attr = file_attr(fname); + if (attr & 0x18) { + goto fdst_err; } - fdc.off = secsize; - if ((cmd == 0x09) || (cmd == 0x0b)) { - fdc.rreg = fdc.r + 1; // ver0.25 - if (seeksector(fdc.drv, trk, fdc.rreg)) { - fdc.r++; - fdc.off = 0; - return(0); - } + fh = file_open_rb(fname); + if (fh == FILEH_INVALID) { + goto fdst_err; + } + r = (file_read(fh, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head)) + != sizeof(fdd->inf.d88.head)) || + (file_read(fh, ptr, sizeof(ptr)) != sizeof(ptr)); + file_close(fh); + if (r) { + goto fdst_err; + } + fdd->inf.d88.fd_size = LOADINTELDWORD(fdd->inf.d88.head.fd_size); + for (i=0; iinf.d88.ptr[i] = LOADINTELDWORD(ptr[i]); } - return(1); + if (fdd->inf.d88.head.protect & 0x10) { + attr |= 1; + } + fdd->type = DISKTYPE_D88; + fdd->protect = (UINT8)(attr & 1); + fdd->seek = fddd88_seek; + 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: + return(FAILURE); +} + +void fddd88_eject(FDDFILE fdd) { + + drvflush(fdd); } + + + + + + + + + + // --------------------------------------------------------------------------- +#if 0 +// ---- + +static _D88SEC cursec; +static REG8 curdrv = (REG8)-1; +static UINT curtrk = (UINT)-1; +static BYTE curtype = 0; +static UINT cursct = (UINT)-1; +static long curfp = 0; +static UINT cursize = 0; +static BYTE curwrite = 0; +static BYTE curtrkerr = 0; +static BYTE hole = 0; +static BYTE *curdata; +// static UINT crcnum = 0; +// static BYTE crcerror = FALSE; + +extern WORD readdiag; + + +typedef struct { + BYTE mode; + BYTE flag; + WORD cnt; + WORD size; + WORD ptr; + WORD top; + WORD gap; + BYTE sector; + WORD lostdatacnt; + BYTE maxsector; + WORD maxsize; +} WID_PARA; + +#define LOSTDATA_COUNT 256 + +static WID_PARA WID_2D = {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 33, 0x1f80}; +static WID_PARA WID_2HD= {TAO_ENDOFDATA, 3, 0, 0, 0, 0, 0, 0, 0, 55, 0x2f80}; +static WID_PARA WID_ERR= {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0x0000}; +static WID_PARA tao = {TAO_ENDOFDATA, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0x0000}; + +static BYTE D88_BUF[0x4000]; +static BYTE TAO_BUF[0x3000]; + + +// ---- + void init_tao_d88(void) { FDDFILE fdd; - fdd = fddfile + fdc.drv; - if ((fdc.media == 0) && (fdd->inf.d88.head.fd_type != 0x20)) { + fdd = fddfile + fdc.s.drv; + if (fdc.s.media != (fdd->inf.d88.head.fd_type >> 4)) { + tao = WID_ERR; + } + if (fdc.s.media == DISKTYPE_2D) { tao = WID_2D; } - else if ((fdc.media == 1) && (fdd->inf.d88.head.fd_type == 0x20)) { + else if (fdc.s.media == DISKTYPE_2HD) { tao = WID_2HD; } else { @@ -459,7 +493,7 @@ static int fileappend(FILEH hdl, FDDFILE return(0); } -void endoftrack(void) { +static void endoftrack(void) { FDDFILE fdd; FILEH hdr; @@ -483,8 +517,8 @@ void endoftrack(void) { curdataflush(); // write cache flush & curdrv = (REG8)-1; // use D88_BUF[] for temp - fdd = fddfile + fdc.drv; - trk = (fdc.c << 1) + fdc.h; + fdd = fddfile + fdc.s.drv; + trk = (fdc.s.c << 1) + fdc.s.h; p = (D88SEC)TAO_BUF; for (i=0; i<(int)tao.sector; i++) { @@ -650,55 +684,5 @@ void fdd_wtao_d88(BYTE data) { break; } } - - -// ---- - -BRESULT fddd88_eject(FDDFILE fdd, REG8 drv) { - - drvflush(drv); - ZeroMemory(&fdd->inf.d88, sizeof(fdd->inf.d88)); - fdd->fname[0] = '\0'; - fdd->type = DISKTYPE_NOTREADY; - return(SUCCESS); -} - -BRESULT fddd88_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) { - - short attr; - FILEH fh; - BOOL r; - UINT8 ptr[D88_TRACKMAX][4]; - UINT i; - - attr = file_attr(fname); - if (attr & 0x18) { - goto fdst_err; - } - fh = file_open_rb(fname); - if (fh == FILEH_INVALID) { - goto fdst_err; - } - r = (file_read(fh, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head)) - != sizeof(fdd->inf.d88.head)) || - (file_read(fh, ptr, sizeof(ptr)) != sizeof(ptr)); - file_close(fh); - if (r) { - goto fdst_err; - } - fdd->inf.d88.fd_size = LOADINTELDWORD(fdd->inf.d88.head.fd_size); - for (i=0; iinf.d88.ptr[i] = LOADINTELDWORD(ptr[i]); - } - if (fdd->inf.d88.head.protect & 0x10) { - attr |= 1; - } - fdd->type = DISKTYPE_D88; - fdd->protect = (UINT8)(attr & 1); - milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname)); - return(SUCCESS); - -fdst_err: - return(FAILURE); -} +#endif