--- xmil/fdd/fdd_d88.c 2004/08/01 05:31:30 1.1 +++ xmil/fdd/fdd_d88.c 2008/06/02 20:07:31 1.16 @@ -1,675 +1,511 @@ #include "compiler.h" #include "dosio.h" #include "pccore.h" -#include "x1_io.h" -#include "x1_fdc.h" -#include "fdd_mtr.h" -#include "fdd_d88.h" #include "fddfile.h" +#include "fdd_d88.h" +#include "fdd_mtr.h" -static D88_HEADER d88head[4]; -static D88_SECTOR cursec; -static short curdrv = -1; -static WORD curtrk = -1; -static BYTE curtype = 0; -static WORD cursct = -1; -static long curfp = 0; -static DWORD cursize = 0; -static BYTE curwrite = 0; -static BYTE curtrkerr = 0; -static BYTE hole = 0; -static BYTE *curdata; -static WORD crcnum = 0; -static BYTE crcerror = FALSE; - -extern BYTE WRITEPT[]; -extern BYTE DISKNUM[]; - -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]; - - -//---------------------------------------------------------------------- - -DWORD nexttrackp(D88_HEADER *head, DWORD fptr, DWORD last) { - - int t; - DWORD ret; - DWORD *trkp; - - ret = last; - trkp = (DWORD *)head->trackp; - for (t=0; t<164; t++, trkp++) { - if ((*trkp > fptr) && (*trkp < ret)) { - ret = *trkp; + 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) { + + UINT t; + UINT32 cur; + + for (t=0; t<164; t++) { + cur = fdd->inf.d88.ptr[t]; + if ((cur > fptr) && (cur < last)) { + last = cur; } } - return(ret); + return(last); } - -int curdataflush(void) { +static BRESULT trackflush(D88TRK trk) { FDDFILE fdd; FILEH fh; - int ret = 0; - if ((!curfp) || (!cursize)) { - return(-1); - } - if (!curwrite) { - return(0); + fdd = trk->fdd; + trk->fdd = NULL; + if ((fdd == NULL) || (trk->size == 0) || (!trk->write)) { + goto dtfd_exit; } - 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); -DWORD read_d88track(short drv, WORD track, BYTE type) { +dtfd_err2: + file_close(fh); - FDDFILE fdd; - FILEH hdr; +dtfd_err1: + return(FAILURE); +} - curdataflush(); - curdrv = drv; - curtrk = track; - curtype = type; - cursct = -1; - curwrite = 0; - curtrkerr = 0; - crcnum = 0; - crcerror = 0; +static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { - if ((drv < 0) || (drv > 3) || (track > 163) || - ((type == 0) && (d88head[drv].fd_type == 0x20)) || - ((type == 1) && (d88head[drv].fd_type != 0x20)) || - ((curfp = d88head[drv].trackp[track]) == 0) || - ((cursize = nexttrackp(&d88head[drv], curfp, - d88head[drv].fd_size) - curfp) > 0x4000)) { - goto readd88_err; - } + FILEH fh; + UINT32 fptr; + UINT size; +const _D88SEC *sec; + UINT rem; + UINT maxsectors; + UINT sectors; + UINT secsize; - fdd = fddfile + drv; - 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; + trackflush(trk); + if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) { + goto dtrd_err1; } - if (file_read(hdr, D88_BUF, (WORD)cursize) != (WORD)cursize) { - file_close(hdr); - goto readd88_err; + if (track >= 164) { + goto dtrd_err1; } - if (file_close(hdr)) { - goto readd88_err; + fptr = fdd->inf.d88.ptr[track]; + if (fptr == 0) { + goto dtrd_err1; } - return(TRUE); - -readd88_err: - curfp = 0; - cursize = 0; - curtrkerr = 1; - return(FALSE); -} - - - - -int seeksector(short drv, WORD track, WORD sector) { - -static int lastflag = FALSE; - - BYTE *p; - WORD sec; - - if ((curdrv != drv) || (curtrk != track) || (curtype != FDC.media)) { - read_d88track(drv, track, FDC.media); + size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr; + if (size > D88BUFSIZE) { + size = D88BUFSIZE; } - if (curtrkerr) { - cursct = sector; - goto seekerror; + fh = file_open_rb(fdd->fname); + if (fh == FILEH_INVALID) { + goto dtrd_err1; } - if (cursct != sector) { - cursct = sector; - p = D88_BUF; - for (sec=0; sec<40;) { - if ((WORD)((D88_SECTOR *)p)->r == sector) { - memcpy(&cursec, p, sizeof(D88_SECTOR)); - curdata = p + sizeof(D88_SECTOR); - lastflag = TRUE; - break; - } - if (++sec >= ((D88_SECTOR *)p)->sectors) { - goto seekerror; - } - p += ((D88_SECTOR *)p)->size; - p += sizeof(D88_SECTOR); - } - if (sec >= 40) { - goto seekerror; + if ((file_seek(fh, (long)fptr, FSEEK_SET) != (long)fptr) || + (file_read(fh, trk->buf, size) != size)) { + goto dtrd_err2; + } + file_close(fh); + + 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++; } - return(lastflag); + trk->sectors = sectors; + return(trk); -seekerror:; - ZeroMemory(&cursec, sizeof(D88_SECTOR)); - curdata = &D88_BUF[16]; - lastflag = FALSE; - return(FALSE); +dtrd_err2: + file_close(fh); + +dtrd_err1: + return(NULL); } +static void drvflush(FDDFILE fdd) { -void drvflush(short drv) { + D88TRK trk; - if (curdrv == drv) { - curdataflush(); - curdrv = -1; - curtrk = -1; - cursct = -1; + trk = &d88trk; + if (trk->fdd == fdd) { + trackflush(trk); } } +static D88TRK trackseek(FDDFILE fdd, REG8 media, UINT track) { -//********************************************************************** - -BRESULT fdd_eject_d88(REG8 drv) { + D88TRK trk; - FDDFILE fdd; - - drvflush(drv); - fdd = fddfile + drv; - ZeroMemory(&d88head[drv], sizeof(D88_HEADER)); - fdd->fname[0] = '\0'; - DISKNUM[drv] = 0; - return(0); + trk = &d88trk; + if ((trk->fdd != fdd) || (trk->media != media) || (trk->track != track)) { + trk = trackread(trk, fdd, media, track); + } + return(trk); } -BRESULT fdd_set_d88(REG8 drv, const OEMCHAR *fname) { +static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { - FDDFILE fdd; - WORD attr; - FILEH hdr; - short rsize; - - fdd_eject_d88(drv); - fdd = fddfile + drv; - if ((drv < 0 || drv > 3) || - ((attr = file_attr(fname)) & 0x18)) { // エラー・ディレクトリ・ラベル - return(1); - } - if ((hdr = file_open(fname)) == FILEH_INVALID) { - return(1); - } - rsize = file_read(hdr, &d88head[drv], sizeof(D88_HEADER)); - file_close(hdr); - if (rsize != sizeof(D88_HEADER)) { - fdd_eject_d88(drv); - return(1); - } - if (attr & 1) { - d88head[drv].protect |= (WORD)0x10; +const _D88SEC *sec; + UINT sectors; + UINT size; + + 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); } - milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname)); - DISKNUM[drv] = 1; - return(0); + return(NULL); } -//********************************************************************** +/* ---- */ -short fdd_crc_d88(void) { +static BRESULT fileappend(FILEH fh, UINT32 ptr, UINT size) { - WORD track; - BYTE *p; - WORD sec; - - ZeroMemory(FDC.crc_dat, 6); - if ((track = (WORD)(FDC.c << 1) + (WORD)FDC.h) > 163) { - goto crcerror_d88; - } - seeksector(FDC.drv, track, FDC.r); - if (curtrkerr) { - goto crcerror_d88; - } - p = D88_BUF; - for (sec=0; sec= ((D88_SECTOR *)p)->sectors) { - goto crcerror_d88; - } - p += ((D88_SECTOR *)p)->size; - p += sizeof(D88_SECTOR); + UINT filesize; + UINT r; + UINT8 work[0x400]; + + filesize = file_getsize(fh); + if (filesize < ptr) { + return(FAILURE); } - *(long *)FDC.crc_dat = *(long *)p; - FDC.rreg = ((D88_SECTOR *)p)->c; // ??? メルヘンヴェール - crcnum++; - if (((D88_SECTOR *)p)->stat) { - crcerror = TRUE; + filesize -= ptr; + while(filesize) { + r = min(filesize, sizeof(work)); + filesize -= r; + file_seek(fh, ptr + filesize, FSEEK_SET); + r = file_read(fh, work, r); + file_seek(fh, ptr + filesize + size, FSEEK_SET); + file_write(fh, work, r); } - else { - crcerror = FALSE; - } - return(0); - -crcerror_d88:; - crcerror = TRUE; - return(1); + return(SUCCESS); } +static BRESULT writetrack(FDDFILE fdd, REG8 media, UINT track, + UINT8 *buf, UINT size) { -BYTE fdd_stat_d88(void) { - - BYTE type, cmnd; - BYTE ans = 0; - int seekable; - WORD trk; + FILEH fh; + UINT i; + UINT32 curptr; + UINT32 nextptr; + UINT cursize; + UINT addsize; + UINT32 cur; + UINT8 ptr[D88_TRACKMAX][4]; - if (DISKNUM[FDC.drv] == DRV_EMPTY) { - return(0x80); // NOT READY - } - type = FDC.type; - cmnd = (BYTE)(FDC.cmnd >> 4); - trk = (FDC.c << 1) + (WORD)FDC.h; - seekable = seeksector(FDC.drv, trk, FDC.r); - if (!FDC.r) { - seekable = TRUE; + if ((track >= D88_TRACKMAX) || (size == 0)) { + return(FAILURE); } - if (type == 0 || type == 1 || type == 4 || - cmnd == 0x0a || cmnd == 0x0b || cmnd == 0x0f) { - if (d88head[FDC.drv].protect & 0x10) { // WRITE PROTECT - ans |= 0x40; - } + fh = file_open(fdd->fname); + if (fh == FILEH_INVALID) { + return(FAILURE); } - if (type == 2 || cmnd == 0x0f) { - if (FDC.r && cursec.del_flg) { - ans |= 0x20; // RECODE TYPE / WRITE FAULT + curptr = fdd->inf.d88.ptr[track]; + if (curptr == 0) { + for (i=track; i>0;) { /* 新規トラック */ + curptr = fdd->inf.d88.ptr[--i]; + if (curptr) { + break; + } } - } - if (type == 1 || type == 2) { - if ((trk > 163) || (!seekable)) { - ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND + if (curptr) { /* ヒットした */ + curptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size); } - if ((!(ans & 0xf0)) && FDC.r && (cursec.stat)) { - ans |= 0x08; // CRC ERROR + else { + curptr = D88_HEADERSIZE; } + nextptr = curptr; } - if (cmnd == 0x0c) { - if (curtrkerr) { - ans |= 0x10; - } - if (crcerror) { - ans |= 0x08; // CRC ERROR - } + else { /* トラックデータは既にある */ + nextptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size); } - if (type == 1 || type == 4) { - if (type == 1) { // ver0.25 - ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1) - if (!FDC.c) { // TRACK00 - ans |= 0x04; + cursize = nextptr - curptr; + if (size > cursize) { + addsize = size - cursize; + fileappend(fh, curptr, addsize); + fdd->inf.d88.fd_size += addsize; + for (i=0; iinf.d88.ptr[i]; + if ((cur) && (cur >= curptr)) { + fdd->inf.d88.ptr[i] = cur + addsize; } } - if (++hole < 8) { // ver0.25 - ans |= 0x02; // INDEX - } } - else if (!(ans & 0xf0)) { - if ((type != 4) && (FDDMTR_BUSY)) { - ans |= 0x01; - } - if ((type == 2) && ((WORD)FDC.off < cursec.size)) { - ans |= 0x03; // DATA REQUEST / BUSY - } - else if ((cmnd == 0x0e) && (readdiag < 0x1a00)) { - ans |= 0x03; - } - else if ((cmnd == 0x0c) && (FDC.crc_off < 6)) { // ver0.25 - ans |= 0x03; - } - else if (cmnd == 0x0f) { - if (tao.flag == 3) { - if (++tao.lostdatacnt > LOSTDATA_COUNT) { - tao.flag = 4; - } - } - ans |= tao.flag; - } + STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size); + fdd->inf.d88.ptr[track] = curptr; + for (i=0; iinf.d88.ptr[i]); } - return(ans); + file_seek(fh, 0, FSEEK_SET); + file_write(fh, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head)); + file_write(fh, ptr, sizeof(ptr)); + file_seek(fh, curptr, FSEEK_SET); + file_write(fh, buf, size); + file_close(fh); + return(SUCCESS); } -//********************************************************************** -void fdd_read_d88(void) { - // POCO:読めなかったらレジスタを変更させない - if ((fdd_stat_d88() & 0xf3) == 3) { - FDC.data = curdata[FDC.off]; -#if 0 //def TRACE -{ - char buf[256]; - wsprintf(buf, "%3d %2d %02x -> %04x/%04x", - (FDC.c << 1) + FDC.h, FDC.r, FDC.off, R.HL.W, - dma.CNT_B.w); - TRACE_(buf, FDC.data); -} -#endif - } -} +/* ---- */ +static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) { -void fdd_write_d88(void) { - - if ((fdd_stat_d88() & 0xf3) == 3) { - curdata[FDC.off] = FDC.data; - curwrite = 1; + if (trackseek(fdd, media, track) != NULL) { + return(0x00); + } + else { + return(FDDSTAT_SEEKERR); } } +static REG8 fddd88_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc, + UINT8 *ptr, UINT *size) { -BYTE fdd_incoff_d88(void) { - - BYTE cmnd; - WORD trk; +const _D88TRK *trk; +const _D88SEC *sec; + UINT secsize; + REG8 ret; - cmnd = (BYTE)(FDC.cmnd >> 4); - trk = (FDC.c << 1) + (WORD)FDC.h; - seeksector(FDC.drv, trk, FDC.r); - if ((WORD)(++FDC.off) < cursec.size) { - return(0); + TRACEOUT(("d88 read %d:%.2x", track, sc)); + trk = trackseek(fdd, media, track); + if (trk == NULL) { + goto fd8r_err; } - FDC.off = cursec.size; - if (cmnd == 0x09 || cmnd == 0x0b) { - FDC.rreg = FDC.r + 1; // ver0.25 - if (seeksector(FDC.drv, trk, FDC.rreg)) { - FDC.r++; - FDC.off = 0; - return(0); - } + sec = sectorseek(trk, sc); + if (sec == NULL) { + goto fd8r_err; } - return(1); -} + 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); + } + *size = secsize; + return(ret); -// --------------------------------------------------------------------------- +fd8r_err: + return(FDDSTAT_RECNFND); +} -void init_tao_d88(void) { +static REG8 fddd88_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc, + const UINT8 *ptr, UINT size) { - if ((FDC.media == 0) && (d88head[FDC.drv].fd_type != 0x20)) { - tao = WID_2D; + D88TRK trk; + D88SEC sec; + UINT secsize; + + TRACEOUT(("d88 write %d:%.2x", track, sc)); + trk = trackseek(fdd, media, track); + if (trk == NULL) { + goto fd8w_err; + } + sec = sectorseek(trk, sc); + if (sec == NULL) { + goto fd8w_err; + } + secsize = LOADINTELWORD(sec->size); + size = min(size, secsize); + if (size) { + CopyMemory(sec + 1, ptr, size); + trk->write = TRUE; + } + return(0x00); + +fd8w_err: + return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); +} + +static REG8 fddd88_wrtrk(FDDFILE fdd, REG8 media, UINT track, REG8 sc, + const UINT8 *ptr, UINT size) { + + UINT pos; + UINT i; + UINT datsize; + D88SEC dst; + + trackflush(&d88trk); + + /* データ作る */ + ZeroMemory(d88trk.buf, sizeof(d88trk.buf)); + pos = 0; + for (i=0; isize); + pos += sizeof(_D88SEC) + datsize; + if (pos > D88BUFSIZE) { + goto fd8wt_err; + } + dst->c = ((TAOSEC *)ptr)->c; + dst->h = ((TAOSEC *)ptr)->h; + dst->r = ((TAOSEC *)ptr)->r; + dst->n = ((TAOSEC *)ptr)->n; + dst->sectors[0] = sc; + STOREINTELWORD(dst->size, datsize); + CopyMemory((dst + 1), ptr + sizeof(TAOSEC), datsize); + ptr += sizeof(TAOSEC) + datsize; } - else if ((FDC.media == 1) && (d88head[FDC.drv].fd_type == 0x20)) { - tao = WID_2HD; + if (writetrack(fdd, media, track, d88trk.buf, pos) != SUCCESS) { + goto fd8wt_err; } - else { - tao = WID_ERR; - } -} + return(0); +fd8wt_err: + return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); +} -int fileappend(FILEH hdr, D88_HEADER *head, - long ptr, long last, long apsize) { +static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num, + UINT8 *ptr) { - long length; - WORD size; - WORD rsize; - int t; - long *trkp; +const _D88TRK *trk; +const _D88SEC *sec; + UINT sectors; + UINT size; + + 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; +#if 0 + fdc.s.rreg = sec->c; /* メルヘンヴェール */ +#endif /* 0 */ + if (sec->stat) { + return(FDDSTAT_CRCERR); + } + 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; - if ((length = last - ptr) <= 0) { // 書き換える必要なし + trk = trackseek(fdd, media, track); + if (trk == NULL) { return(0); } - while(length) { - if (length >= 0x4000) { - size = 0x4000; - } - else { - size = (WORD)length; - } - length -= (long)size; - file_seek(hdr, ptr+length, 0); - rsize = file_read(hdr, D88_BUF, size); - file_seek(hdr, ptr+length+apsize, 0); - file_write(hdr, D88_BUF, rsize); - } - - trkp = head->trackp; - for (t=0; t<164; t++, trkp++) { - if ((*trkp) && (*trkp >= ptr)) { - (*trkp) += apsize; + 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(0); + return((UINT32)(sectors << 16) + num); } +#endif +/* ---- */ -void endoftrack(void) { +BRESULT fddd88_set(FDDFILE fdd, const OEMCHAR *fname) { - FDDFILE fdd; - FILEH hdr; - int i; - WORD trk; - D88_HEADER *head; - long fpointer; - long endpointer; - long lastpointer; - long trksize; - int ptr; - long apsize; - - if (!tao.sector) { - tao.flag = 4; - return; - } - tao.flag = 0; - - curdataflush(); // write cache flush & - curdrv = -1; // use D88_BUF[] for temp - - head = &d88head[FDC.drv]; - trk = (FDC.c << 1) + (WORD)FDC.h; - - ptr = 0; - for (i=0; i<(int)tao.sector; i++) { - ((D88_SECTOR *)&TAO_BUF[ptr])->sectors = tao.sector; - ptr += ((D88_SECTOR *)&TAO_BUF[ptr])->size + 16; - } - - fdd = fddfile + FDC.drv; - if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { - return; - } - lastpointer = file_seek(hdr, 0, 2); - if ((fpointer = head->trackp[trk]) == 0) { - fpointer = 0; // 新規トラック - for (i=trk; i>=0; i--) { - if (head->trackp[i]) { - fpointer = head->trackp[i]; - break; - } - } - if (fpointer) { // ヒットした - fpointer = nexttrackp(head, fpointer, lastpointer); - } - else { - fpointer = sizeof(D88_HEADER); - } - endpointer = fpointer; + short attr; + FILEH fh; + BRESULT r; + UINT8 ptr[D88_TRACKMAX][4]; + UINT i; + + attr = file_attr(fname); + if (attr & 0x18) { + goto fdst_err; } - else { // トラックデータは既にある - endpointer = nexttrackp(head, fpointer, lastpointer); + fh = file_open_rb(fname); + if (fh == FILEH_INVALID) { + goto fdst_err; } - trksize = endpointer - fpointer; - if ((apsize = (long)tao.size - trksize) > 0) { - // 書き込むデータのほーが大きい - fileappend(hdr, head, endpointer, lastpointer, apsize); - head->fd_size += apsize; - } - head->trackp[trk] = fpointer; - file_seek(hdr, fpointer, 0); - file_write(hdr, TAO_BUF, tao.size); - file_seek(hdr, 0, 0); - file_write(hdr, head, sizeof(D88_HEADER)); - file_close(hdr); + 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); + fdd->seek = fddd88_seek; + fdd->read = fddd88_read; + fdd->write = fddd88_write; + fdd->wrtrk = fddd88_wrtrk; + fdd->crc = fddd88_crc; +#if defined(SUPPORT_DISKEXT) + fdd->sec = fddd88_sec; +#endif + return(SUCCESS); + +fdst_err: + return(FAILURE); } +void fddd88_eject(FDDFILE fdd) { -void fdd_wtao_d88(BYTE data) { - - if (tao.flag != 3) { - return; - } - tao.lostdatacnt = 0; - if (tao.cnt > tao.maxsize) { - endoftrack(); - return; - } - tao.cnt++; - switch(tao.mode) { - case TAO_ENDOFDATA: - if (data == TAO_MODE_GAP) { - tao.mode = TAO_MODE_GAP; - tao.gap = 0; - } - break; - case TAO_MODE_GAP: - if (data == TAO_MODE_GAP) { - if (tao.gap++ > 256) { - endoftrack(); - } - } - else if (data == TAO_CMD_SYNC) { - tao.mode = TAO_MODE_SYNC; - } -#if 1 // ver0.26 Zeliard - else if (data == 0xf4) { - endoftrack(); - } -#endif - else { - tao.flag = 4; - } - break; - case TAO_MODE_SYNC: -// tao.cnt--; // ver0.26 Zeliard - if (data == TAO_CMD_AM_IN) { - tao.mode = TAO_MODE_AM; - } - else if (data == TAO_CMD_IM_IN) { - tao.mode = TAO_MODE_IM; - } - else if (data) { - tao.flag = 4; - } - break; - case TAO_MODE_IM: - if (data == TAO_CMD_IM) { - tao.mode = TAO_ENDOFDATA; - } - else if (data != TAO_CMD_IM_IN) { - tao.flag = 4; - } - break; - case TAO_MODE_AM: - if (data == TAO_CMD_IAM) { - tao.mode = TAO_MODE_ID; - tao.ptr = 0; - tao.top = tao.size; - } - else if (data == TAO_CMD_DAM) { - tao.mode = TAO_MODE_DATA; - tao.ptr = 0; - } - else if (data == TAO_CMD_DDAM) { - tao.mode = TAO_MODE_DATA; - tao.ptr = 0; - ((D88_SECTOR *)&TAO_BUF[tao.top])->del_flg = 1; - } - break; - case TAO_MODE_ID: - if ((data == TAO_CMD_IAM) && (!tao.ptr)) { - break; - } - else if (tao.ptr < 4) { - TAO_BUF[tao.size++] = data; - tao.ptr++; - } - else if (data == TAO_CMD_CRC) { - tao.mode = TAO_ENDOFDATA; - ZeroMemory(&TAO_BUF[tao.size], 12); - tao.size += 12; - } - break; - case TAO_MODE_DATA: // DATA WRITE - if ((!tao.ptr) && - ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) { - break; - } - else if (data == TAO_CMD_CRC) { // nで判定した方が無難か? - tao.mode = TAO_ENDOFDATA; - ((D88_SECTOR *)&TAO_BUF[tao.top])->size = tao.ptr; - if (tao.sector++ > tao.maxsector) { - tao.flag = 4; - } - } - else { - TAO_BUF[tao.size++] = data; - tao.ptr++; - } - break; - } + drvflush(fdd); }