|
|
| version 1.9, 2004/08/10 08:28:48 | version 1.12, 2004/08/17 09:35:09 |
|---|---|
| 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 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 421 static BYTE D88_BUF[0x4000]; | Line 453 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; |