|
|
| version 1.1, 2004/08/01 05:31:30 | 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; | return(0x00); |
| 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)) { | |
| 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); | |
| } | } |
| BRESULT fdd_eject_2d(REG8 drv) { | static REG8 fdd2d_read(FDDFILE fdd, REG8 media, UINT track, REG8 sc, |
| UINT8 *ptr, UINT *size) { | |
| FDDFILE fdd; | UINT secsize; |
| UINT rsize; | |
| FILEH fh; | FILEH fh; |
| long seekp; | long pos; |
| BRESULT ret = 0; | BRESULT b; |
| fdd = fddfile + drv; | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| while(1) { | (sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| if ((!sec_write[drv]) || (sec_now[drv] == -1)) { | goto fd2r_err; |
| break; | } |
| } | secsize = 1 << (7 + fdd->inf.xdf.n); |
| seekp = (long)sec_now[drv] << 8; | rsize = min(secsize, *size); |
| fh = file_open(fdd->fname); | if (ptr) { |
| fh = file_open_rb(fdd->fname); | |
| if (fh == FILEH_INVALID) { | if (fh == FILEH_INVALID) { |
| ret = 1; | goto fd2r_err; |
| break; | |
| } | |
| if ((file_seek(fh, seekp, FSEEK_SET) != seekp) || | |
| (file_write(fh, sec_data[drv], 256) != 256)) { | |
| ret = 1; | |
| } | } |
| if (file_close(fh)) { | pos = ((track * fdd->inf.xdf.sectors) + (sc - 1)) * secsize; |
| ret = 1; | 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; | |
| } | } |
| break; | |
| } | } |
| fdd->fname[0] = '\0'; | *size = rsize; |
| DISKNUM[drv] = 0; | return(0x00); |
| sec_now[drv] = -1; | |
| sec_write[drv] = 0; | |
| return(ret); | |
| } | |
| fd2r_err: | |
| return(FDDSTAT_RECNFND); | |
| } | |
| BRESULT fdd_set_2d(REG8 drv, const OEMCHAR *fname) { | static REG8 fdd2d_write(FDDFILE fdd, REG8 media, UINT track, REG8 sc, |
| const UINT8 *ptr, UINT size) { | |
| FDDFILE fdd; | UINT secsize; |
| WORD attr; | FILEH fh; |
| long pos; | |
| BRESULT b; | |
| fdd_eject_2d(drv); | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| fdd = fddfile + drv; | (sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| if ((drv < 0 || drv > 3) || | return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT); |
| ((attr = file_attr(fname)) & 0x18)) { // エラー・ディレクトリ・ラベル | |
| return(1); | |
| } | } |
| DISKNUM[drv] = DRV_FMT2D; | fh = file_open(fdd->fname); |
| file_cpyname(fdd->fname, fname, NELEMENTS(fdd->fname)); | if (fh == FILEH_INVALID) { |
| WRITEPT[drv] = (BYTE)(attr & 1); | goto fd2w_err; |
| return(0); | } |
| } | secsize = 1 << (7 + fdd->inf.xdf.n); |
| pos = ((track * fdd->inf.xdf.sectors) + (sc - 1)) * secsize; | |
| size = min(size, secsize); | |
| b = (file_seek(fh, pos, FSEEK_SET) != pos) || | |
| (file_write(fh, ptr, size) != size); | |
| file_close(fh); | |
| if (b) { | |
| goto fd2w_err; | |
| } | |
| return(0x00); | |
| //********************************************************************** | fd2w_err: |
| return(FDDSTAT_WRITEFAULT); | |
| } | |
| short fdd_crc_2d(void) { | static REG8 fdd2d_crc(FDDFILE fdd, REG8 media, UINT track, UINT num, |
| UINT8 *ptr) { | |
| FDC.crc_dat[0] = FDC.c; | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) || |
| FDC.crc_dat[1] = FDC.h; | (num >= fdd->inf.xdf.sectors)) { |
| FDC.crc_dat[2] = FDC.r; | return(FDDSTAT_RECNFND); |
| FDC.crc_dat[3] = 1; | } |
| FDC.crc_dat[4] = 0; // CRC(Lo) | ptr[0] = (UINT8)(track >> 1); |
| FDC.crc_dat[5] = 0; // CRC(Hi) | ptr[1] = (UINT8)(track & 1); |
| FDC.rreg = FDC.c; // ??? メルヘンヴェール | ptr[2] = (UINT8)(num + 1); |
| return(0); | ptr[3] = fdd->inf.xdf.n; |
| ptr[4] = 0; // CRC(Lo) | |
| ptr[5] = 0; // CRC(Hi) | |
| return(0x00); | |
| } | } |
| BYTE fdd_stat_2d(void) { | #if defined(SUPPORT_DISKEXT) |
| static UINT32 fdd2d_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) { | |
| BYTE type, cmnd; | UINT32 ret; |
| BYTE ans = 0; | |
| // NOT READY | if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks)) { |
| if (DISKNUM[FDC.drv] != DRV_FMT2D) { | return(0); |
| return(0x80); | |
| } | } |
| type = FDC.type; | if ((sc == 0) || (sc > fdd->inf.xdf.sectors)) { |
| cmnd = (BYTE)(FDC.cmnd >> 4); | ret = fdd->inf.xdf.sectors; |
| if (type == 0 || type == 1 || type == 4 || // !!! | |
| cmnd == 0x0a || cmnd == 0x0b || cmnd == 0x0f) { | |
| if (WRITEPT[FDC.drv]) { // WRITE PROTECT | |
| ans |= 0x40; | |
| } | |
| } | } |
| if ((type == 1 || type == 2) && | else { |
| ((FDC.c >= 40) || (FDC.h > 1) || (FDC.r > 16) || (FDC.media))) { | ret = sc; |
| ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND | |
| } | } |
| return((16 << fdd->inf.xdf.sectors) + ret); | |
| 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)) { | |
| if (FDDMTR_BUSY) { | |
| ans |= 0x01; | |
| } | |
| if ((type == 2) && (FDC.r) && (FDC.off < 256)) { | |
| ans |= 0x03; // DATA REQUEST / BUSY | |
| } | |
| else if (cmnd == 0x0f) { | |
| ans |= 0x04; // error! | |
| } | |
| } | |
| return(ans); | |
| } | } |
| #endif | |
| //********************************************************************** | // ---- |
| void fdd_read_2d(void) { | |
| if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) { | BRESULT fdd2d_set(FDDFILE fdd, const OEMCHAR *fname) { |
| FDC.data = sec_data[FDC.drv][FDC.off]; | |
| } | |
| } | |
| short attr; | |
| FILEH fh; | |
| UINT fdsize; | |
| const _XDFINFO *xdf; | |
| const _XDFINFO *xdfterm; | |
| UINT size; | |
| void fdd_write_2d(void) { | attr = file_attr(fname); |
| if (attr & 0x18) { | |
| return(FAILURE); | |
| } | |
| fh = file_open(fname); | |
| if (fh == FILEH_INVALID) { | |
| return(FAILURE); | |
| } | |
| fdsize = file_getsize(fh); | |
| file_close(fh); | |
| if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) { | xdf = supportxdf; |
| sec_data[FDC.drv][FDC.off] = FDC.data; | xdfterm = supportxdf + NELEMENTS(supportxdf); |
| sec_write[FDC.drv] = 1; | 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); | |
| } | |
| xdf++; | |
| } | } |
| return(FAILURE); | |
| } | } |
| void fdd2d_eject(FDDFILE fdd) { | |
| BYTE fdd_incoff_2d(void) { | (void)fdd; |
| BYTE cmnd; | |
| if (++FDC.off < 256) { | |
| return(0); | |
| } | |
| cmnd = (BYTE)(FDC.cmnd >> 4); | |
| if (cmnd == 0x09 || cmnd == 0x0b) { | |
| if (FDC.r < 16) { | |
| FDC.r++; | |
| FDC.rreg++; | |
| FDC.off = 0; | |
| return(0); | |
| } | |
| FDC.rreg = FDC.r + 1; | |
| } | |
| FDC.off = 256; | |
| return(1); | |
| } | } |