|
|
| version 1.2, 2004/08/02 11:48:13 | version 1.9, 2004/08/17 09:35:09 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "dosio.h" | #include "dosio.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "x1_io.h" | |
| #include "x1_fdc.h" | |
| #include "fddfile.h" | #include "fddfile.h" |
| #include "fdd_2d.h" | |
| #include "fdd_mtr.h" | #include "fdd_mtr.h" |
| extern BYTE WRITEPT[]; | static const _XDFINFO supportxdf[] = { |
| extern BYTE DISKNUM[]; | {0, 80, 16, 1, DISKTYPE_2D}, |
| static WORD sec_now[4] = {0, 0, 0, 0}; | {0, 154, 26, 1, DISKTYPE_2HD}}; |
| static BYTE sec_write[4] = {0, 0, 0, 0}; | |
| static BYTE sec_data[4][256]; | |
| 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; | |
| BYTE type, cmnd; | long pos; |
| BYTE ans = 0; | BRESULT b; |
| // NOT READY | |
| if (DISKNUM[fdc.drv] != DRV_FMT2D) { | |
| return(0x80); | |
| } | |
| type = fdc.type; | |
| cmnd = (BYTE)(fdc.cmnd >> 4); | |
| if (type == 0 || type == 1 || type == 4 || // !!! | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| cmnd == 0x0a || cmnd == 0x0b || cmnd == 0x0f) { | (sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| if (WRITEPT[fdc.drv]) { // WRITE PROTECT | return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); |
| ans |= 0x40; | |
| } | |
| } | } |
| if ((type == 1 || type == 2) && | fh = file_open(fdd->fname); |
| ((fdc.c >= 40) || (fdc.h > 1) || (fdc.r > 16) || (fdc.media))) { | if (fh == FILEH_INVALID) { |
| ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND | goto fd2w_err; |
| } | |
| if (type == 1 || type == 4) { | |
| if (type == 1) { | |
| 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 (cmnd == 0x0f) { | goto fd2w_err; |
| ans |= 0x04; // error! | |
| } | |
| } | } |
| return(ans); | return(0x00); |
| } | |
| //********************************************************************** | |
| void fdd_read_2d(void) { | |
| if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) { | fd2w_err: |
| fdc.data = sec_data[fdc.drv][fdc.off]; | return(FDDSTAT_WRITEFAULT); |
| } | |
| } | } |
| 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) | |
| return(0x00); | |
| } | } |
| BYTE fdd_incoff_2d(void) { | #if defined(SUPPORT_DISKEXT) |
| static UINT32 fdd2d_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) { | |
| BYTE cmnd; | UINT32 ret; |
| if (++fdc.off < 256) { | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks)) { |
| return(0); | return(0); |
| } | } |
| cmnd = (BYTE)(fdc.cmnd >> 4); | if ((sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| if (cmnd == 0x09 || cmnd == 0x0b) { | ret = fdd->inf.xdf.sectors; |
| 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 << fdd->inf.xdf.sectors) + ret); |
| return(1); | |
| } | } |
| #endif | |
| // ---- | // ---- |
| BRESULT fdd2d_eject(REG8 drv) { | BRESULT fdd2d_set(FDDFILE fdd, const OEMCHAR *fname) { |
| FDDFILE fdd; | short attr; |
| FILEH fh; | FILEH fh; |
| long seekp; | UINT fdsize; |
| BRESULT ret = 0; | const _XDFINFO *xdf; |
| const _XDFINFO *xdfterm; | |
| UINT size; | |
| fdd = fddfile + drv; | attr = file_attr(fname); |
| while(1) { | if (attr & 0x18) { |
| if ((!sec_write[drv]) || (sec_now[drv] == -1)) { | return(FAILURE); |
| break; | } |
| } | fh = file_open(fname); |
| seekp = (long)sec_now[drv] << 8; | if (fh == FILEH_INVALID) { |
| fh = file_open(fdd->fname); | return(FAILURE); |
| if (fh == FILEH_INVALID) { | } |
| ret = 1; | fdsize = file_getsize(fh); |
| break; | file_close(fh); |
| } | |
| if ((file_seek(fh, seekp, FSEEK_SET) != seekp) || | xdf = supportxdf; |
| (file_write(fh, sec_data[drv], 256) != 256)) { | xdfterm = supportxdf + NELEMENTS(supportxdf); |
| ret = 1; | while(xdf < xdfterm) { |
| } | size = xdf->tracks; |
| if (file_close(fh)) { | size *= xdf->sectors; |
| ret = 1; | 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); | |
| } | } |
| break; | xdf++; |
| } | } |
| fdd->fname[0] = '\0'; | return(FAILURE); |
| DISKNUM[drv] = 0; | |
| sec_now[drv] = -1; | |
| sec_write[drv] = 0; | |
| return(ret); | |
| } | } |
| BRESULT fdd2d_set(REG8 drv, const OEMCHAR *fname) { | void fdd2d_eject(FDDFILE fdd) { |
| FDDFILE fdd; | |
| short attr; | |
| fdd = fddfile + drv; | (void)fdd; |
| attr = file_attr(fname); | |
| if (attr & 0x18) { | |
| return(FAILURE); | |
| } | |
| DISKNUM[drv] = DRV_FMT2D; | |
| file_cpyname(fdd->fname, fname, NELEMENTS(fdd->fname)); | |
| WRITEPT[drv] = (BYTE)(attr & 1); | |
| sec_now[drv] = -1; | |
| sec_write[drv] = 0; | |
| return(SUCCESS); | |
| } | } |