|
|
| version 1.1, 2004/08/01 05:31:30 | version 1.3, 2004/08/02 13:38:46 |
|---|---|
| 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 "iocore.h" |
| #include "x1_fdc.h" | |
| #include "fdd_mtr.h" | |
| #include "fdd_d88.h" | |
| #include "fddfile.h" | #include "fddfile.h" |
| #include "fdd_d88.h" | |
| #include "fdd_mtr.h" | |
| static D88_HEADER d88head[4]; | static D88_HEADER d88head[4]; |
| Line 23 static BYTE *curdata; | Line 22 static BYTE *curdata; |
| static WORD crcnum = 0; | static WORD crcnum = 0; |
| static BYTE crcerror = FALSE; | static BYTE crcerror = FALSE; |
| extern BYTE WRITEPT[]; | |
| extern BYTE DISKNUM[]; | |
| extern WORD readdiag; | extern WORD readdiag; |
| #define TAO_MODE_GAP 0x4e | #define TAO_MODE_GAP 0x4e |
| Line 73 static BYTE TAO_BUF[0x3000]; | Line 69 static BYTE TAO_BUF[0x3000]; |
| //---------------------------------------------------------------------- | //---------------------------------------------------------------------- |
| DWORD nexttrackp(D88_HEADER *head, DWORD fptr, DWORD last) { | static UINT32 nexttrackp(D88_HEADER *head, UINT32 fptr, UINT32 last) { |
| int t; | UINT t; |
| DWORD ret; | const DWORD *trkp; |
| DWORD *trkp; | UINT32 cur; |
| ret = last; | |
| trkp = (DWORD *)head->trackp; | trkp = (DWORD *)head->trackp; |
| for (t=0; t<164; t++, trkp++) { | for (t=0; t<164; t++) { |
| if ((*trkp > fptr) && (*trkp < ret)) { | cur = trkp[t]; |
| ret = *trkp; | if ((cur > fptr) && (cur < last)) { |
| last = cur; | |
| } | } |
| } | } |
| return(ret); | return(last); |
| } | } |
| Line 170 readd88_err: | Line 166 readd88_err: |
| int seeksector(short drv, WORD track, WORD sector) { | static int seeksector(short drv, WORD track, WORD sector) { |
| static int lastflag = FALSE; | static int lastflag = FALSE; |
| BYTE *p; | BYTE *p; |
| WORD sec; | WORD sec; |
| if ((curdrv != drv) || (curtrk != track) || (curtype != FDC.media)) { | if ((curdrv != drv) || (curtrk != track) || (curtype != fdc.media)) { |
| read_d88track(drv, track, FDC.media); | read_d88track(drv, track, fdc.media); |
| } | } |
| if (curtrkerr) { | if (curtrkerr) { |
| cursct = sector; | cursct = sector; |
| Line 225 void drvflush(short drv) { | Line 221 void drvflush(short drv) { |
| } | } |
| //********************************************************************** | |
| BRESULT fdd_eject_d88(REG8 drv) { | |
| FDDFILE fdd; | |
| drvflush(drv); | |
| fdd = fddfile + drv; | |
| ZeroMemory(&d88head[drv], sizeof(D88_HEADER)); | |
| fdd->fname[0] = '\0'; | |
| DISKNUM[drv] = 0; | |
| return(0); | |
| } | |
| BRESULT fdd_set_d88(REG8 drv, const OEMCHAR *fname) { | |
| FDDFILE fdd; | |
| WORD attr; | |
| FILEH hdr; | |
| short rsize; | |
| fdd_eject_d88(drv); | |
| fdd = fddfile + drv; | |
| if ((drv < 0 || drv > 3) || | |
| ((attr = file_attr(fname)) & 0x18)) { // エラー・ディレクトリ・ラベル | |
| return(1); | |
| } | |
| if ((hdr = file_open(fname)) == FILEH_INVALID) { | |
| return(1); | |
| } | |
| rsize = file_read(hdr, &d88head[drv], sizeof(D88_HEADER)); | |
| file_close(hdr); | |
| if (rsize != sizeof(D88_HEADER)) { | |
| fdd_eject_d88(drv); | |
| return(1); | |
| } | |
| if (attr & 1) { | |
| d88head[drv].protect |= (WORD)0x10; | |
| } | |
| milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname)); | |
| DISKNUM[drv] = 1; | |
| return(0); | |
| } | |
| //********************************************************************** | //********************************************************************** |
| Line 278 short fdd_crc_d88(void) { | Line 231 short fdd_crc_d88(void) { |
| BYTE *p; | BYTE *p; |
| WORD sec; | WORD sec; |
| ZeroMemory(FDC.crc_dat, 6); | ZeroMemory(fdc.crc_dat, 6); |
| if ((track = (WORD)(FDC.c << 1) + (WORD)FDC.h) > 163) { | if ((track = (WORD)(fdc.c << 1) + (WORD)fdc.h) > 163) { |
| goto crcerror_d88; | goto crcerror_d88; |
| } | } |
| seeksector(FDC.drv, track, FDC.r); | seeksector(fdc.drv, track, fdc.r); |
| if (curtrkerr) { | if (curtrkerr) { |
| goto crcerror_d88; | goto crcerror_d88; |
| } | } |
| Line 294 short fdd_crc_d88(void) { | Line 247 short fdd_crc_d88(void) { |
| p += ((D88_SECTOR *)p)->size; | p += ((D88_SECTOR *)p)->size; |
| p += sizeof(D88_SECTOR); | p += sizeof(D88_SECTOR); |
| } | } |
| *(long *)FDC.crc_dat = *(long *)p; | *(long *)fdc.crc_dat = *(long *)p; |
| FDC.rreg = ((D88_SECTOR *)p)->c; // ??? メルヘンヴェール | fdc.rreg = ((D88_SECTOR *)p)->c; // ??? メルヘンヴェール |
| crcnum++; | crcnum++; |
| if (((D88_SECTOR *)p)->stat) { | if (((D88_SECTOR *)p)->stat) { |
| crcerror = TRUE; | crcerror = TRUE; |
| Line 313 crcerror_d88:; | Line 266 crcerror_d88:; |
| BYTE fdd_stat_d88(void) { | BYTE fdd_stat_d88(void) { |
| BYTE type, cmnd; | FDDFILE fdd; |
| BYTE type; | |
| REG8 cmd; | |
| BYTE ans = 0; | BYTE ans = 0; |
| int seekable; | int seekable; |
| WORD trk; | WORD trk; |
| if (DISKNUM[FDC.drv] == DRV_EMPTY) { | fdd = fddfile + fdc.drv; |
| if (fdd->type != DISKTYPE_D88) { | |
| return(0x80); // NOT READY | return(0x80); // NOT READY |
| } | } |
| type = FDC.type; | type = fdc.type; |
| cmnd = (BYTE)(FDC.cmnd >> 4); | cmd = (REG8)(fdc.cmd >> 4); |
| trk = (FDC.c << 1) + (WORD)FDC.h; | trk = (fdc.c << 1) + (WORD)fdc.h; |
| seekable = seeksector(FDC.drv, trk, FDC.r); | seekable = seeksector(fdc.drv, trk, fdc.r); |
| if (!FDC.r) { | if (!fdc.r) { |
| seekable = TRUE; | seekable = TRUE; |
| } | } |
| if (type == 0 || type == 1 || type == 4 || | if (type == 0 || type == 1 || type == 4 || |
| cmnd == 0x0a || cmnd == 0x0b || cmnd == 0x0f) { | cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) { |
| if (d88head[FDC.drv].protect & 0x10) { // WRITE PROTECT | if (fdd->protect) { // WRITE PROTECT |
| ans |= 0x40; | ans |= 0x40; |
| } | } |
| } | } |
| if (type == 2 || cmnd == 0x0f) { | if (type == 2 || cmd == 0x0f) { |
| if (FDC.r && cursec.del_flg) { | if (fdc.r && cursec.del_flg) { |
| ans |= 0x20; // RECODE TYPE / WRITE FAULT | ans |= 0x20; // RECODE TYPE / WRITE FAULT |
| } | } |
| } | } |
| Line 344 BYTE fdd_stat_d88(void) { | Line 300 BYTE fdd_stat_d88(void) { |
| if ((trk > 163) || (!seekable)) { | if ((trk > 163) || (!seekable)) { |
| ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND | ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND |
| } | } |
| if ((!(ans & 0xf0)) && FDC.r && (cursec.stat)) { | if ((!(ans & 0xf0)) && fdc.r && (cursec.stat)) { |
| ans |= 0x08; // CRC ERROR | ans |= 0x08; // CRC ERROR |
| } | } |
| } | } |
| if (cmnd == 0x0c) { | if (cmd == 0x0c) { |
| if (curtrkerr) { | if (curtrkerr) { |
| ans |= 0x10; | ans |= 0x10; |
| } | } |
| Line 359 BYTE fdd_stat_d88(void) { | Line 315 BYTE fdd_stat_d88(void) { |
| if (type == 1 || type == 4) { | if (type == 1 || type == 4) { |
| if (type == 1) { // ver0.25 | if (type == 1) { // ver0.25 |
| ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1) | ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1) |
| if (!FDC.c) { // TRACK00 | if (!fdc.c) { // TRACK00 |
| ans |= 0x04; | ans |= 0x04; |
| } | } |
| } | } |
| Line 371 BYTE fdd_stat_d88(void) { | Line 327 BYTE fdd_stat_d88(void) { |
| if ((type != 4) && (FDDMTR_BUSY)) { | if ((type != 4) && (FDDMTR_BUSY)) { |
| ans |= 0x01; | ans |= 0x01; |
| } | } |
| if ((type == 2) && ((WORD)FDC.off < cursec.size)) { | if ((type == 2) && ((WORD)fdc.off < cursec.size)) { |
| ans |= 0x03; // DATA REQUEST / BUSY | ans |= 0x03; // DATA REQUEST / BUSY |
| } | } |
| else if ((cmnd == 0x0e) && (readdiag < 0x1a00)) { | else if ((cmd == 0x0e) && (readdiag < 0x1a00)) { |
| ans |= 0x03; | ans |= 0x03; |
| } | } |
| else if ((cmnd == 0x0c) && (FDC.crc_off < 6)) { // ver0.25 | else if ((cmd == 0x0c) && (fdc.crc_off < 6)) { // ver0.25 |
| ans |= 0x03; | ans |= 0x03; |
| } | } |
| else if (cmnd == 0x0f) { | else if (cmd == 0x0f) { |
| if (tao.flag == 3) { | if (tao.flag == 3) { |
| if (++tao.lostdatacnt > LOSTDATA_COUNT) { | if (++tao.lostdatacnt > LOSTDATA_COUNT) { |
| tao.flag = 4; | tao.flag = 4; |
| Line 392 BYTE fdd_stat_d88(void) { | Line 348 BYTE fdd_stat_d88(void) { |
| return(ans); | return(ans); |
| } | } |
| //********************************************************************** | //********************************************************************** |
| void fdd_read_d88(void) { | void fdd_read_d88(void) { |
| // POCO:読めなかったらレジスタを変更させない | // POCO:読めなかったらレジスタを変更させない |
| if ((fdd_stat_d88() & 0xf3) == 3) { | if ((fdd_stat_d88() & 0xf3) == 3) { |
| FDC.data = curdata[FDC.off]; | fdc.data = curdata[fdc.off]; |
| #if 0 //def TRACE | |
| { | |
| char buf[256]; | |
| wsprintf(buf, "%3d %2d %02x -> %04x/%04x", | |
| (FDC.c << 1) + FDC.h, FDC.r, FDC.off, R.HL.W, | |
| dma.CNT_B.w); | |
| TRACE_(buf, FDC.data); | |
| } | |
| #endif | |
| } | } |
| } | } |
| Line 414 void fdd_read_d88(void) { | Line 363 void fdd_read_d88(void) { |
| void fdd_write_d88(void) { | void fdd_write_d88(void) { |
| if ((fdd_stat_d88() & 0xf3) == 3) { | if ((fdd_stat_d88() & 0xf3) == 3) { |
| curdata[FDC.off] = FDC.data; | curdata[fdc.off] = fdc.data; |
| curwrite = 1; | curwrite = 1; |
| } | } |
| } | } |
| Line 422 void fdd_write_d88(void) { | Line 371 void fdd_write_d88(void) { |
| BYTE fdd_incoff_d88(void) { | BYTE fdd_incoff_d88(void) { |
| BYTE cmnd; | REG8 cmd; |
| WORD trk; | WORD trk; |
| cmnd = (BYTE)(FDC.cmnd >> 4); | cmd = (REG8)(fdc.cmd >> 4); |
| trk = (FDC.c << 1) + (WORD)FDC.h; | trk = (fdc.c << 1) + (WORD)fdc.h; |
| seeksector(FDC.drv, trk, FDC.r); | seeksector(fdc.drv, trk, fdc.r); |
| if ((WORD)(++FDC.off) < cursec.size) { | if ((WORD)(++fdc.off) < cursec.size) { |
| return(0); | return(0); |
| } | } |
| FDC.off = cursec.size; | fdc.off = cursec.size; |
| if (cmnd == 0x09 || cmnd == 0x0b) { | if ((cmd == 0x09) || (cmd == 0x0b)) { |
| FDC.rreg = FDC.r + 1; // ver0.25 | fdc.rreg = fdc.r + 1; // ver0.25 |
| if (seeksector(FDC.drv, trk, FDC.rreg)) { | if (seeksector(fdc.drv, trk, fdc.rreg)) { |
| FDC.r++; | fdc.r++; |
| FDC.off = 0; | fdc.off = 0; |
| return(0); | return(0); |
| } | } |
| } | } |
| Line 447 BYTE fdd_incoff_d88(void) { | Line 396 BYTE fdd_incoff_d88(void) { |
| void init_tao_d88(void) { | void init_tao_d88(void) { |
| if ((FDC.media == 0) && (d88head[FDC.drv].fd_type != 0x20)) { | if ((fdc.media == 0) && (d88head[fdc.drv].fd_type != 0x20)) { |
| tao = WID_2D; | tao = WID_2D; |
| } | } |
| else if ((FDC.media == 1) && (d88head[FDC.drv].fd_type == 0x20)) { | else if ((fdc.media == 1) && (d88head[fdc.drv].fd_type == 0x20)) { |
| tao = WID_2HD; | tao = WID_2HD; |
| } | } |
| else { | else { |
| Line 458 void init_tao_d88(void) { | Line 407 void init_tao_d88(void) { |
| } | } |
| } | } |
| int fileappend(FILEH hdr, D88_HEADER *head, | int fileappend(FILEH hdr, D88_HEADER *head, |
| long ptr, long last, long apsize) { | long ptr, long last, long apsize) { |
| Line 519 void endoftrack(void) { | Line 467 void endoftrack(void) { |
| curdataflush(); // write cache flush & | curdataflush(); // write cache flush & |
| curdrv = -1; // use D88_BUF[] for temp | curdrv = -1; // use D88_BUF[] for temp |
| head = &d88head[FDC.drv]; | head = &d88head[fdc.drv]; |
| trk = (FDC.c << 1) + (WORD)FDC.h; | trk = (fdc.c << 1) + (WORD)fdc.h; |
| ptr = 0; | ptr = 0; |
| for (i=0; i<(int)tao.sector; i++) { | for (i=0; i<(int)tao.sector; i++) { |
| Line 528 void endoftrack(void) { | Line 476 void endoftrack(void) { |
| ptr += ((D88_SECTOR *)&TAO_BUF[ptr])->size + 16; | ptr += ((D88_SECTOR *)&TAO_BUF[ptr])->size + 16; |
| } | } |
| fdd = fddfile + FDC.drv; | fdd = fddfile + fdc.drv; |
| if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { | if ((hdr = file_open(fdd->fname)) == FILEH_INVALID) { |
| return; | return; |
| } | } |
| Line 673 void fdd_wtao_d88(BYTE data) { | Line 621 void fdd_wtao_d88(BYTE data) { |
| } | } |
| } | } |
| // ---- | |
| BRESULT fddd88_eject(FDDFILE fdd, REG8 drv) { | |
| drvflush(drv); | |
| ZeroMemory(&d88head[drv], sizeof(D88_HEADER)); | |
| fdd->fname[0] = '\0'; | |
| fdd->type = DISKTYPE_NOTREADY; | |
| return(SUCCESS); | |
| } | |
| BRESULT fddd88_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) { | |
| short attr; | |
| FILEH fh; | |
| UINT rsize; | |
| attr = file_attr(fname); | |
| if (attr & 0x18) { | |
| goto fdst_err; | |
| } | |
| fh = file_open(fname); | |
| if (fh == FILEH_INVALID) { | |
| goto fdst_err; | |
| } | |
| rsize = file_read(fh, &d88head[drv], sizeof(D88_HEADER)); | |
| file_close(fh); | |
| if (rsize != sizeof(D88_HEADER)) { | |
| goto fdst_err; | |
| } | |
| if (d88head[drv].protect & 0x10) { | |
| attr |= 1; | |
| } | |
| milstr_ncpy(fdd->fname, fname, NELEMENTS(fdd->fname)); | |
| fdd->type = DISKTYPE_D88; | |
| fdd->protect = (UINT8)(attr & 1); | |
| return(SUCCESS); | |
| fdst_err: | |
| return(FAILURE); | |
| } | |