|
|
| version 1.4, 2004/08/08 09:12:06 | version 1.8, 2004/08/15 14:56:15 |
|---|---|
| Line 7 | Line 7 |
| #include "fdd_mtr.h" | #include "fdd_mtr.h" |
| static WORD sec_now[4] = {0, 0, 0, 0}; | static const _XDFINFO supportxdf[] = { |
| static BYTE sec_write[4] = {0, 0, 0, 0}; | {0, 80, 16, 1, DISKTYPE_2D}, |
| static BYTE sec_data[4][256]; | {0, 154, 26, 1, DISKTYPE_2HD}}; |
| static BYTE hole = 0; | |
| BYTE changesector2d(void) { | static REG8 fdd2d_seek(FDDFILE fdd, REG8 media, UINT track) { |
| FDDFILE fdd; | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks)) { |
| FILEH fh; | return(FDDSTAT_SEEKERR); |
| WORD sec; | |
| long seekp; | |
| short drv = fdc.drv; | |
| if (fdc.media) { | |
| return(1); | |
| } | |
| fdd = fddfile + drv; | |
| sec = (WORD)(((fdc.c) << 5) + (fdc.h << 4) + fdc.r - 1); | |
| if (sec_now[drv] == sec) { | |
| return(0); | |
| } | |
| fh = file_open(fdd->fname); | |
| if (fh == FILEH_INVALID) { | |
| sec_now[drv] = -1; | |
| return(1); | |
| } | } |
| if ((sec_write[drv]) && (sec_now[drv] != -1)) { | return(0x00); |
| seekp = (long)sec_now[drv] << 8; | |
| if ((file_seek(fh, seekp, FSEEK_SET) != seekp) || | |
| (file_write(fh, sec_data[drv], 256) != 256)) { | |
| file_close(fh); | |
| sec_now[drv] = -1; | |
| return(1); | |
| } | |
| } | |
| sec_write[drv] = 0; | |
| sec_now[drv] = sec; | |
| seekp = (long)sec << 8; | |
| if ((file_seek(fh, seekp, FSEEK_SET) != seekp) || | |
| (file_read(fh, sec_data[drv], 256) != 256)) { | |
| file_close(fh); | |
| sec_now[drv] = -1; | |
| return(1); | |
| } | |
| file_close(fh); | |
| return(0); | |
| } | } |
| static REG8 fdd2d_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc, | |
| UINT8 *ptr, UINT *size) { | |
| UINT secsize; | |
| UINT rsize; | |
| FILEH fh; | |
| long pos; | |
| BRESULT b; | |
| if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || | |
| (sc == 0) || (sc > fdd->inf.xdf.sectors)) { | |
| goto fd2r_err; | |
| } | |
| secsize = 1 << (7 + fdd->inf.xdf.n); | |
| rsize = min(secsize, *size); | |
| if (ptr) { | |
| fh = file_open_rb(fdd->fname); | |
| if (fh == FILEH_INVALID) { | |
| goto fd2r_err; | |
| } | |
| pos = ((track * fdd->inf.xdf.sectors) + (sc - 1)) * secsize; | |
| pos += fdd->inf.xdf.headersize; | |
| b = (file_seek(fh, pos, FSEEK_SET) != pos) || | |
| (file_read(fh, ptr, rsize) != rsize); | |
| file_close(fh); | |
| if (b) { | |
| goto fd2r_err; | |
| } | |
| } | |
| *size = rsize; | |
| return(0x00); | |
| //********************************************************************** | fd2r_err: |
| return(FDDSTAT_RECNFND); | |
| short fdd_crc_2d(void) { | |
| fdc.crc_dat[0] = fdc.c; | |
| fdc.crc_dat[1] = fdc.h; | |
| fdc.crc_dat[2] = fdc.r; | |
| fdc.crc_dat[3] = 1; | |
| fdc.crc_dat[4] = 0; // CRC(Lo) | |
| fdc.crc_dat[5] = 0; // CRC(Hi) | |
| fdc.rreg = fdc.c; // ??? メルヘンヴェール | |
| return(0); | |
| } | } |
| static REG8 fdd2d_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc, | |
| const UINT8 *ptr, UINT size) { | |
| BYTE fdd_stat_2d(void) { | UINT secsize; |
| FILEH fh; | |
| FDDFILE fdd; | long pos; |
| REG8 cmd; | BRESULT b; |
| BYTE type; | |
| BYTE ans = 0; | |
| fdd = fddfile + fdc.drv; | |
| // NOT READY | |
| if (fdd->type != DISKTYPE_BETA) { | |
| return(0x80); | |
| } | |
| type = fdc.type; | |
| cmd = (REG8)(fdc.cmd >> 4); | |
| if (type == 0 || type == 1 || type == 4 || // !!! | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) { | (sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| if (fdd->protect) { // WRITE PROTECT | return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); |
| ans |= 0x40; | |
| } | |
| } | |
| if ((type == 1 || type == 2) && | |
| ((fdc.c >= 40) || (fdc.h > 1) || (fdc.r > 16) || (fdc.media))) { | |
| ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND | |
| } | } |
| fh = file_open(fdd->fname); | |
| if (type == 1 || type == 4) { | if (fh == FILEH_INVALID) { |
| if (type == 1) { | goto fd2w_err; |
| ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1) | |
| if (fdc.c == 0) { | |
| ans |= 0x04; // TRACK00 | |
| } | |
| } | |
| if (++hole < 8) { | |
| ans |= 0x02; // INDEX | |
| } | |
| } | } |
| else if (!(ans & 0xf0)) { | secsize = 1 << (7 + fdd->inf.xdf.n); |
| if (FDDMTR_BUSY) { | pos = ((track * fdd->inf.xdf.sectors) + (sc - 1)) * secsize; |
| ans |= 0x01; | size = min(size, secsize); |
| } | b = (file_seek(fh, pos, FSEEK_SET) != pos) || |
| if ((type == 2) && (fdc.r) && (fdc.off < 256)) { | (file_write(fh, ptr, size) != size); |
| ans |= 0x03; // DATA REQUEST / BUSY | file_close(fh); |
| } | if (b) { |
| else if (cmd == 0x0f) { | goto fd2w_err; |
| ans |= 0x04; // error! | |
| } | |
| } | } |
| return(ans); | return(0x00); |
| } | |
| //********************************************************************** | fd2w_err: |
| return(FDDSTAT_WRITEFAULT); | |
| void fdd_read_2d(void) { | |
| if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) { | |
| fdc.data = sec_data[fdc.drv][fdc.off]; | |
| } | |
| } | } |
| static REG8 fdd2d_crc(FDDFILE fdd, REG8 media, UINT track, UINT num, | |
| UINT8 *ptr) { | |
| void fdd_write_2d(void) { | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| (num >= fdd->inf.xdf.sectors)) { | |
| if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) { | return(FDDSTAT_RECNFND); |
| sec_data[fdc.drv][fdc.off] = fdc.data; | |
| sec_write[fdc.drv] = 1; | |
| } | } |
| ptr[0] = (UINT8)(track >> 1); | |
| ptr[1] = (UINT8)(track & 1); | |
| ptr[2] = (UINT8)(num + 1); | |
| ptr[3] = fdd->inf.xdf.n; | |
| ptr[4] = 0; // CRC(Lo) | |
| ptr[5] = 0; // CRC(Hi) | |
| // fdc.s.rreg = fdc.s.c; // メルヘンヴェール | |
| return(0x00); | |
| } | } |
| BYTE fdd_incoff_2d(void) { | #if defined(SUPPORT_DISKEXT) |
| static UINT32 fdd2d_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) { | |
| REG8 cmd; | UINT32 ret; |
| if (++fdc.off < 256) { | if ((media != 0) || (track >= 80)) { |
| return(0); | return(0); |
| } | } |
| cmd = (REG8)(fdc.cmd >> 4); | if ((sc == 0) || (sc > 16)) { |
| if ((cmd == 0x09) || (cmd == 0x0b)) { | ret = 16; |
| if (fdc.r < 16) { | } |
| fdc.r++; | else { |
| fdc.rreg++; | ret = sc; |
| fdc.off = 0; | |
| return(0); | |
| } | |
| fdc.rreg = fdc.r + 1; | |
| } | } |
| fdc.off = 256; | return((16 << 16) + ret); |
| return(1); | |
| } | } |
| #endif | |
| // ---- | // ---- |
| BRESULT fdd2d_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) { | BRESULT fdd2d_set(FDDFILE fdd, const OEMCHAR *fname) { |
| short attr; | short attr; |
| FILEH fh; | |
| UINT fdsize; | |
| const _XDFINFO *xdf; | |
| const _XDFINFO *xdfterm; | |
| UINT size; | |
| attr = file_attr(fname); | attr = file_attr(fname); |
| if (attr & 0x18) { | if (attr & 0x18) { |
| return(FAILURE); | return(FAILURE); |
| } | } |
| file_cpyname(fdd->fname, fname, NELEMENTS(fdd->fname)); | fh = file_open(fname); |
| fdd->type = DISKTYPE_BETA; | if (fh == FILEH_INVALID) { |
| fdd->protect = (UINT8)(attr & 1); | return(FAILURE); |
| sec_now[drv] = -1; | } |
| sec_write[drv] = 0; | fdsize = file_getsize(fh); |
| return(SUCCESS); | file_close(fh); |
| } | |
| BRESULT fdd2d_eject(FDDFILE fdd, REG8 drv) { | |
| FILEH fh; | |
| long seekp; | |
| BRESULT ret = 0; | |
| while(1) { | xdf = supportxdf; |
| if ((!sec_write[drv]) || (sec_now[drv] == -1)) { | xdfterm = supportxdf + NELEMENTS(supportxdf); |
| break; | while(xdf < xdfterm) { |
| size = xdf->tracks; | |
| size *= xdf->sectors; | |
| size <<= (7 + xdf->n); | |
| if (size == fdsize) { | |
| file_cpyname(fdd->fname, fname, sizeof(fdd->fname)); | |
| fdd->type = DISKTYPE_BETA; | |
| fdd->protect = (UINT8)(attr & 1); | |
| fdd->seek = fdd2d_seek; | |
| fdd->read = fdd2d_read; | |
| fdd->write = fdd2d_write; | |
| fdd->crc = fdd2d_crc; | |
| #if defined(SUPPORT_DISKEXT) | |
| fdd->sec = fdd2d_sec; | |
| #endif | |
| fdd->inf.xdf = *xdf; | |
| return(SUCCESS); | |
| } | } |
| seekp = (long)sec_now[drv] << 8; | xdf++; |
| fh = file_open(fdd->fname); | |
| if (fh == FILEH_INVALID) { | |
| ret = 1; | |
| break; | |
| } | |
| if ((file_seek(fh, seekp, FSEEK_SET) != seekp) || | |
| (file_write(fh, sec_data[drv], 256) != 256)) { | |
| ret = 1; | |
| } | |
| if (file_close(fh)) { | |
| ret = 1; | |
| } | |
| break; | |
| } | } |
| fdd->fname[0] = '\0'; | return(FAILURE); |
| fdd->type = DISKTYPE_NOTREADY; | } |
| sec_now[drv] = -1; | |
| sec_write[drv] = 0; | void fdd2d_eject(FDDFILE fdd) { |
| return(ret); | |
| (void)fdd; | |
| } | } |