|
|
| version 1.8, 2004/08/09 04:47:53 | version 1.15, 2005/02/04 06:42:11 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "dosio.h" | #include "dosio.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | |
| #include "fddfile.h" | #include "fddfile.h" |
| #include "fdd_d88.h" | #include "fdd_d88.h" |
| #include "fdd_mtr.h" | #include "fdd_mtr.h" |
| // static D88_HEADER d88head[4]; | enum { |
| static _D88SEC cursec; | D88BUFSIZE = 0x4000 |
| 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 | |
| typedef struct { | typedef struct { |
| BYTE mode; | FDDFILE fdd; |
| BYTE flag; | UINT8 media; |
| WORD cnt; | UINT8 write; |
| WORD size; | UINT8 padding[2]; |
| WORD ptr; | UINT track; |
| WORD top; | long fptr; |
| WORD gap; | UINT size; |
| BYTE sector; | UINT sectors; |
| WORD lostdatacnt; | UINT8 buf[D88BUFSIZE]; |
| BYTE maxsector; | } _D88TRK, *D88TRK; |
| 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]; | |
| static _D88TRK d88trk; | |
| //---------------------------------------------------------------------- | |
| static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) { | static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) { |
| Line 83 static UINT32 nexttrackptr(FDDFILE fdd, | Line 39 static UINT32 nexttrackptr(FDDFILE fdd, |
| return(last); | return(last); |
| } | } |
| static BRESULT trackflush(D88TRK trk) { | |
| static int curdataflush(void) { | |
| FDDFILE fdd; | FDDFILE fdd; |
| FILEH fh; | FILEH fh; |
| int ret = 0; | |
| if ((!curfp) || (!cursize)) { | fdd = trk->fdd; |
| return(-1); | trk->fdd = NULL; |
| } | if ((fdd == NULL) || (trk->size == 0) || (!trk->write)) { |
| if (!curwrite) { | goto dtfd_exit; |
| return(0); | |
| } | } |
| curwrite = 0; | |
| fdd = fddfile + curdrv; | |
| fh = file_open(fdd->fname); | fh = file_open(fdd->fname); |
| if (fh == FILEH_INVALID) { | if (fh == FILEH_INVALID) { |
| return(-1); | goto dtfd_err1; |
| } | } |
| if ((file_seek(fh, curfp, FSEEK_SET) != curfp) || | if ((file_seek(fh, trk->fptr, FSEEK_SET) != trk->fptr) || |
| (file_write(fh, D88_BUF, cursize) != cursize)) { | (file_write(fh, trk->buf, trk->size) != trk->size)) { |
| ret = -1; | goto dtfd_err2; |
| } | } |
| if (file_close(fh)) { | file_close(fh); |
| ret = -1; | trk->write = FALSE; |
| } | |
| return(ret); | |
| } | |
| dtfd_exit: | |
| return(SUCCESS); | |
| static DWORD read_d88track(REG8 drv, UINT track, REG8 media) { | dtfd_err2: |
| file_close(fh); | |
| FDDFILE fdd; | dtfd_err1: |
| FILEH hdr; | return(FAILURE); |
| } | |
| curdataflush(); | static D88TRK trackread(D88TRK trk, FDDFILE fdd, REG8 media, UINT track) { |
| curdrv = drv; | |
| curtrk = track; | |
| curtype = media; | |
| cursct = (UINT)-1; | |
| curwrite = 0; | |
| curtrkerr = 0; | |
| crcnum = 0; | |
| crcerror = 0; | |
| fdd = fddfile + drv; | FILEH fh; |
| if ((drv < 0) || (drv > 3) || (track > 163) || | UINT32 fptr; |
| (media != (fdd->inf.d88.head.fd_type >> 4)) || | UINT size; |
| ((curfp = fdd->inf.d88.ptr[track]) == 0) || | const _D88SEC *sec; |
| ((cursize = nexttrackptr(fdd, curfp, | UINT rem; |
| fdd->inf.d88.fd_size) - curfp) > 0x4000)) { | UINT maxsectors; |
| goto readd88_err; | UINT sectors; |
| } | UINT secsize; |
| if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { | trackflush(trk); |
| goto readd88_err; | if (media != (REG8)((fdd->inf.d88.head.fd_type >> 4))) { |
| goto dtrd_err1; | |
| } | } |
| if (file_seek(hdr, curfp, FSEEK_SET) != curfp) { | if (track >= 164) { |
| file_close(hdr); | goto dtrd_err1; |
| goto readd88_err; | |
| } | } |
| if (file_read(hdr, D88_BUF, cursize) != cursize) { | fptr = fdd->inf.d88.ptr[track]; |
| file_close(hdr); | if (fptr == 0) { |
| goto readd88_err; | goto dtrd_err1; |
| } | } |
| if (file_close(hdr)) { | size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr; |
| goto readd88_err; | if (size > D88BUFSIZE) { |
| size = D88BUFSIZE; | |
| } | } |
| return(TRUE); | fh = file_open_rb(fdd->fname); |
| if (fh == FILEH_INVALID) { | |
| readd88_err: | goto dtrd_err1; |
| curfp = 0; | } |
| cursize = 0; | if ((file_seek(fh, (long)fptr, FSEEK_SET) != (long)fptr) || |
| curtrkerr = 1; | (file_read(fh, trk->buf, size) != size)) { |
| return(FALSE); | 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++; | |
| } | |
| trk->sectors = sectors; | |
| return(trk); | |
| dtrd_err2: | |
| file_close(fh); | |
| static int seeksector(REG8 drv, UINT track, UINT r) { | dtrd_err1: |
| return(NULL); | |
| } | |
| static int lastflag = FALSE; | static void drvflush(FDDFILE fdd) { |
| const _D88SEC *p; | D88TRK trk; |
| UINT sec; | |
| UINT sectors; | |
| UINT secsize; | |
| if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.s.media)) { | trk = &d88trk; |
| read_d88track(drv, track, fdc.s.media); | if (trk->fdd == fdd) { |
| } | trackflush(trk); |
| 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); | |
| } | } |
| static void drvflush(REG8 drv) { | static D88TRK trackseek(FDDFILE fdd, REG8 media, UINT track) { |
| if (curdrv == drv) { | D88TRK trk; |
| curdataflush(); | |
| curdrv = (REG8)-1; | trk = &d88trk; |
| curtrk = (UINT)-1; | if ((trk->fdd != fdd) || (trk->media != media) || (trk->track != track)) { |
| cursct = (UINT)-1; | trk = trackread(trk, fdd, media, track); |
| } | } |
| return(trk); | |
| } | } |
| static D88SEC sectorseek(const _D88TRK *trk, REG8 r) { | |
| 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); | |
| } | |
| return(NULL); | |
| } | |
| //********************************************************************** | |
| BRESULT fddd88_crc(FDDFILE fdd) { | // ---- |
| UINT track; | static BRESULT fileappend(FILEH fh, UINT32 ptr, UINT size) { |
| const _D88SEC *p; | |
| UINT sec; | |
| UINT sectors; | |
| UINT secsize; | |
| track = (fdc.c << 1) + fdc.h; | UINT filesize; |
| if (track >= 164) { | UINT r; |
| goto crcerror_d88; | UINT8 work[0x400]; |
| } | |
| seeksector(fdc.drv, track, fdc.r); | filesize = file_getsize(fh); |
| if (curtrkerr) { | if (filesize < ptr) { |
| goto crcerror_d88; | return(FAILURE); |
| } | } |
| p = (D88SEC)D88_BUF; | filesize -= ptr; |
| for (sec=0; sec<crcnum;) { | while(filesize) { |
| sectors = LOADINTELWORD(p->sectors); | r = min(filesize, sizeof(work)); |
| secsize = LOADINTELWORD(p->size); | filesize -= r; |
| sec++; | file_seek(fh, ptr + filesize, FSEEK_SET); |
| if (sec >= sectors) { | r = file_read(fh, work, r); |
| goto crcerror_d88; | file_seek(fh, ptr + filesize + size, FSEEK_SET); |
| } | file_write(fh, work, r); |
| p = (D88SEC)(((UINT8 *)(p + 1)) + secsize); | |
| } | |
| fdc.s.buffer[0] = p->c; | |
| fdc.s.buffer[1] = p->h; | |
| fdc.s.buffer[2] = p->r; | |
| fdc.s.buffer[3] = p->n; | |
| fdc.s.buffer[4] = 0; | |
| fdc.s.buffer[5] = 0; | |
| fdc.s.bufsize = 6; | |
| fdc.rreg = p->c; // メルヘンヴェール | |
| crcnum++; | |
| if (p->stat) { | |
| crcerror = TRUE; | |
| } | |
| else { | |
| crcerror = FALSE; | |
| } | } |
| return(SUCCESS); | return(SUCCESS); |
| crcerror_d88: | |
| crcerror = TRUE; | |
| (void)fdd; | |
| return(FAILURE); | |
| } | } |
| static BRESULT writetrack(FDDFILE fdd, REG8 media, UINT track, | |
| UINT8 *buf, UINT size) { | |
| BYTE fdd_stat_d88(void) { | FILEH fh; |
| UINT i; | |
| UINT32 curptr; // fpointer; | |
| UINT32 nextptr; // endpointer; | |
| UINT cursize; | |
| UINT addsize; | |
| UINT32 cur; | |
| UINT8 ptr[D88_TRACKMAX][4]; | |
| FDDFILE fdd; | if ((track >= D88_TRACKMAX) || (size == 0)) { |
| BYTE type; | return(FAILURE); |
| 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) { | fh = file_open(fdd->fname); |
| ans |= 0x20; // RECODE TYPE / WRITE FAULT | if (fh == FILEH_INVALID) { |
| } | return(FAILURE); |
| } | } |
| if (type == 1 || type == 2) { | curptr = fdd->inf.d88.ptr[track]; |
| if ((trk > 163) || (!seekable)) { | if (curptr == 0) { |
| ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND | for (i=track; i>0;) { // 新規トラック |
| } | curptr = fdd->inf.d88.ptr[--i]; |
| if ((!(ans & 0xf0)) && fdc.r && (cursec.stat)) { | if (curptr) { |
| ans |= 0x08; // CRC ERROR | break; |
| } | |
| } | } |
| } | if (curptr) { // ヒットした |
| if (cmd == 0x0c) { | curptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size); |
| if (curtrkerr) { | |
| ans |= 0x10; | |
| } | } |
| if (crcerror) { | else { |
| ans |= 0x08; // CRC ERROR | curptr = D88_HEADERSIZE; |
| } | } |
| nextptr = curptr; | |
| } | } |
| if (type == 1 || type == 4) { | else { // トラックデータは既にある |
| if (type == 1) { // ver0.25 | nextptr = nexttrackptr(fdd, curptr, fdd->inf.d88.fd_size); |
| ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1) | |
| if (!fdc.c) { // TRACK00 | |
| ans |= 0x04; | |
| } | |
| } | |
| if (++hole < 8) { // ver0.25 | |
| ans |= 0x02; // INDEX | |
| } | |
| } | } |
| else if (!(ans & 0xf0)) { | cursize = nextptr - curptr; |
| if ((type != 4) && (FDDMTR_BUSY)) { | if (size > cursize) { |
| ans |= 0x01; | addsize = size - cursize; |
| } | fileappend(fh, curptr, addsize); |
| if (type == 2) { | fdd->inf.d88.fd_size += addsize; |
| UINT secsize = LOADINTELWORD(cursec.size); | for (i=0; i<D88_TRACKMAX; i++) { |
| if ((UINT)fdc.off < secsize) { | cur = fdd->inf.d88.ptr[i]; |
| ans |= 0x03; // DATA REQUEST / BUSY | if ((cur) && (cur >= curptr)) { |
| fdd->inf.d88.ptr[i] = cur + addsize; | |
| } | } |
| } | } |
| 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); | STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size); |
| fdd->inf.d88.ptr[track] = curptr; | |
| for (i=0; i<D88_TRACKMAX; i++) { | |
| STOREINTELDWORD(ptr[i], fdd->inf.d88.ptr[i]); | |
| } | |
| 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]; | |
| } | |
| } | |
| void fdd_write_d88(void) { | static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) { |
| if ((fdd_stat_d88() & 0xf3) == 3) { | if (trackseek(fdd, media, track) != NULL) { |
| curdata[fdc.off] = fdc.data; | return(0x00); |
| curwrite = 1; | } |
| else { | |
| return(FDDSTAT_SEEKERR); | |
| } | } |
| } | } |
| BYTE fdd_incoff_d88(void) { | static REG8 fddd88_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc, |
| UINT8 *ptr, UINT *size) { | |
| REG8 cmd; | const _D88TRK *trk; |
| UINT trk; | const _D88SEC *sec; |
| UINT secsize; | UINT secsize; |
| REG8 ret; | |
| cmd = (REG8)(fdc.cmd >> 4); | TRACEOUT(("d88 read %d:%.2x", track, sc)); |
| trk = (fdc.c << 1) + fdc.h; | trk = trackseek(fdd, media, track); |
| seeksector(fdc.drv, trk, fdc.r); | if (trk == NULL) { |
| fdc.off++; | goto fd8r_err; |
| secsize = LOADINTELWORD(cursec.size); | } |
| if ((UINT)fdc.off < secsize) { | sec = sectorseek(trk, sc); |
| return(0); | 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); | |
| } | } |
| fdc.off = secsize; | *size = secsize; |
| if ((cmd == 0x09) || (cmd == 0x0b)) { | return(ret); |
| fdc.rreg = fdc.r + 1; // ver0.25 | |
| if (seeksector(fdc.drv, trk, fdc.rreg)) { | |
| fdc.r++; | |
| fdc.off = 0; | |
| return(0); | |
| } | |
| } | |
| return(1); | |
| } | |
| // --------------------------------------------------------------------------- | 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) { | |
| FDDFILE fdd; | D88TRK trk; |
| D88SEC sec; | |
| UINT secsize; | |
| fdd = fddfile + fdc.drv; | TRACEOUT(("d88 write %d:%.2x", track, sc)); |
| if (fdc.s.media != (fdd->inf.d88.head.fd_type >> 4)) { | trk = trackseek(fdd, media, track); |
| tao = WID_ERR; | if (trk == NULL) { |
| } | goto fd8w_err; |
| if (fdc.s.media == DISKTYPE_2D) { | |
| tao = WID_2D; | |
| } | } |
| else if (fdc.s.media == DISKTYPE_2HD) { | sec = sectorseek(trk, sc); |
| tao = WID_2HD; | if (sec == NULL) { |
| goto fd8w_err; | |
| } | } |
| else { | secsize = LOADINTELWORD(sec->size); |
| tao = WID_ERR; | size = min(size, secsize); |
| if (size) { | |
| CopyMemory(sec + 1, ptr, size); | |
| trk->write = TRUE; | |
| } | } |
| return(0x00); | |
| fd8w_err: | |
| return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); | |
| } | } |
| static int fileappend(FILEH hdl, FDDFILE fdd, | static REG8 fddd88_wrtrk(FDDFILE fdd, REG8 media, UINT track, REG8 sc, |
| UINT32 ptr, long last, long apsize) { | const UINT8 *ptr, UINT size) { |
| long length; | UINT pos; |
| UINT size; | UINT i; |
| UINT rsize; | UINT datsize; |
| UINT t; | D88SEC dst; |
| BYTE tmp[0x400]; | |
| UINT32 cur; | |
| length = last - ptr; | trackflush(&d88trk); |
| if (length <= 0) { // 書き換える必要なし | |
| return(0); | // データ作る |
| ZeroMemory(d88trk.buf, sizeof(d88trk.buf)); | |
| pos = 0; | |
| for (i=0; i<sc; i++) { | |
| dst = (D88SEC)(d88trk.buf + pos); | |
| datsize = LOADINTELWORD(((TAOSEC *)ptr)->size); | |
| 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; | |
| } | } |
| while(length) { | if (writetrack(fdd, media, track, d88trk.buf, pos) != SUCCESS) { |
| if (length >= (long)(sizeof(tmp))) { | goto fd8wt_err; |
| size = sizeof(tmp); | |
| } | |
| else { | |
| size = length; | |
| } | |
| length -= size; | |
| file_seek(hdl, ptr + length, FSEEK_SET); | |
| rsize = file_read(hdl, tmp, size); | |
| file_seek(hdl, ptr + length + apsize, FSEEK_SET); | |
| file_write(hdl, tmp, rsize); | |
| } | |
| for (t=0; t<164; t++) { | |
| cur = fdd->inf.d88.ptr[t]; | |
| if ((cur) && (cur >= ptr)) { | |
| fdd->inf.d88.ptr[t] = cur + apsize; | |
| } | |
| } | } |
| return(0); | return(0); |
| fd8wt_err: | |
| return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); | |
| } | } |
| static void endoftrack(void) { | static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num, |
| UINT8 *ptr) { | |
| FDDFILE fdd; | const _D88TRK *trk; |
| FILEH hdr; | const _D88SEC *sec; |
| int i; | UINT sectors; |
| UINT trk; | UINT size; |
| long fpointer; | |
| long endpointer; | |
| long lastpointer; | |
| long trksize; | |
| long apsize; | |
| D88SEC p; | |
| UINT secsize; | |
| UINT8 ptr[D88_TRACKMAX][4]; | |
| if (!tao.sector) { | trk = trackseek(fdd, media, track); |
| tao.flag = 4; | if (trk == NULL) { |
| return; | return(FDDSTAT_RECNFND); |
| } | } |
| tao.flag = 0; | sec = (D88SEC)trk->buf; |
| sectors = trk->sectors; | |
| curdataflush(); // write cache flush & | if (num >= sectors) { |
| curdrv = (REG8)-1; // use D88_BUF[] for temp | return(FDDSTAT_RECNFND); |
| } | |
| fdd = fddfile + fdc.drv; | while(num) { |
| trk = (fdc.c << 1) + fdc.h; | num--; |
| size = LOADINTELWORD(sec->size); | |
| p = (D88SEC)TAO_BUF; | size += sizeof(_D88SEC); |
| for (i=0; i<(int)tao.sector; i++) { | sec = (D88SEC)(((UINT8 *)sec) + size); |
| STOREINTELWORD(p->sectors, tao.sector); | } |
| secsize = LOADINTELWORD(p->size); | ptr[0] = sec->c; |
| p = (D88SEC)(((UINT8 *)(p + 1)) + secsize); | ptr[1] = sec->h; |
| } | ptr[2] = sec->r; |
| ptr[3] = sec->n; | |
| if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { | ptr[4] = 0; |
| return; | ptr[5] = 0; |
| } | // fdc.s.rreg = sec->c; // メルヘンヴェール |
| lastpointer = file_seek(hdr, 0, 2); | if (sec->stat) { |
| fpointer = fdd->inf.d88.ptr[trk]; | return(FDDSTAT_CRCERR); |
| if (fpointer == 0) { | |
| for (i=trk; i>=0; i--) { // 新規トラック | |
| fpointer = fdd->inf.d88.ptr[i]; | |
| if (fpointer) { | |
| break; | |
| } | |
| } | |
| if (fpointer) { // ヒットした | |
| fpointer = nexttrackptr(fdd, fpointer, lastpointer); | |
| } | |
| else { | |
| fpointer = D88_HEADERSIZE; | |
| } | |
| endpointer = fpointer; | |
| } | |
| else { // トラックデータは既にある | |
| endpointer = nexttrackptr(fdd, fpointer, lastpointer); | |
| } | |
| trksize = endpointer - fpointer; | |
| if ((apsize = (long)tao.size - trksize) > 0) { | |
| // 書き込むデータのほーが大きい | |
| fileappend(hdr, fdd, endpointer, lastpointer, apsize); | |
| fdd->inf.d88.fd_size += apsize; | |
| } | } |
| STOREINTELDWORD(fdd->inf.d88.head.fd_size, fdd->inf.d88.fd_size); | return(0x00); |
| fdd->inf.d88.ptr[trk] = fpointer; | } |
| for (i=0; i<D88_TRACKMAX; i++) { | |
| STOREINTELDWORD(ptr[i], fdd->inf.d88.ptr[i]); | |
| } | |
| file_seek(hdr, 0, FSEEK_SET); | |
| file_write(hdr, &fdd->inf.d88.head, sizeof(fdd->inf.d88.head)); | |
| file_write(hdr, ptr, sizeof(ptr)); | |
| file_seek(hdr, fpointer, FSEEK_SET); | |
| file_write(hdr, TAO_BUF, tao.size); | |
| file_close(hdr); | |
| } | |
| void fdd_wtao_d88(BYTE data) { | |
| D88SEC p; | |
| 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 defined(SUPPORT_DISKEXT) |
| if (data == TAO_CMD_IAM) { | static UINT32 fddd88_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) { |
| 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; | |
| p = (D88SEC)(TAO_BUF + tao.top); | |
| p->del_flg = 1; | |
| } | |
| break; | |
| case TAO_MODE_ID: | const _D88TRK *trk; |
| if ((data == TAO_CMD_IAM) && (!tao.ptr)) { | const _D88SEC *sec; |
| break; | UINT sectors; |
| } | UINT num; |
| else if (tao.ptr < 4) { | UINT size; |
| 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 | trk = trackseek(fdd, media, track); |
| if ((!tao.ptr) && | if (trk == NULL) { |
| ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) { | return(0); |
| break; | } |
| } | sec = (D88SEC)trk->buf; |
| else if (data == TAO_CMD_CRC) { // nで判定した方が無難か? | sectors = trk->sectors; |
| tao.mode = TAO_ENDOFDATA; | num = 0; |
| p = (D88SEC)(TAO_BUF + tao.top); | while(num < sectors) { |
| STOREINTELWORD(p->size, tao.ptr); | if (sec->r == sc) { |
| if (tao.sector++ > tao.maxsector) { | |
| tao.flag = 4; | |
| } | |
| } | |
| else { | |
| TAO_BUF[tao.size++] = data; | |
| tao.ptr++; | |
| } | |
| break; | break; |
| } | |
| size = LOADINTELWORD(sec->size); | |
| size += sizeof(_D88SEC); | |
| sec = (D88SEC)(((UINT8 *)sec) + size); | |
| num++; | |
| } | } |
| return((UINT32)(sectors << 16) + num); | |
| } | } |
| #endif | |
| // ---- | // ---- |
| BRESULT fddd88_eject(FDDFILE fdd, REG8 drv) { | BRESULT fddd88_set(FDDFILE fdd, const OEMCHAR *fname) { |
| 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; | 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 700 BRESULT fddd88_set(FDDFILE fdd, REG8 drv | Line 488 BRESULT fddd88_set(FDDFILE fdd, REG8 drv |
| } | } |
| fdd->type = DISKTYPE_D88; | fdd->type = DISKTYPE_D88; |
| fdd->protect = (UINT8)(attr & 1); | fdd->protect = (UINT8)(attr & 1); |
| (void)drv; | 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); | return(SUCCESS); |
| fdst_err: | fdst_err: |
| return(FAILURE); | return(FAILURE); |
| } | } |
| void fddd88_eject(FDDFILE fdd) { | |
| drvflush(fdd); | |
| } | |