--- np2/io/fdc.c 2003/11/12 00:55:38 1.4 +++ np2/io/fdc.c 2005/02/12 12:40:39 1.17 @@ -4,30 +4,41 @@ #include "compiler.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "fddfile.h" +enum { + FDC_DMACH2HD = 2, + FDC_DMACH2DD = 3 +}; -static const BYTE FDCCMD_TABLE[32] = { +static const UINT8 FDCCMD_TABLE[32] = { 0, 0, 8, 2, 1, 8, 8, 1, 0, 8, 1, 0, 8, 5, 0, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0}; #define FDC_FORCEREADY (1) -#define FDC_MAXDRIVE 2 #define FDC_DELAYERROR7 -void fdc_interrupt(void) { - fdc.intreq = TRUE; - if (CTRL_FDMEDIA == DISKTYPE_2HD) { - pic_setirq(0x0b); - } - else { - pic_setirq(0x0a); +void fdc_intwait(NEVENTITEM item) { + + if (item->flag & NEVENT_SETEVENT) { + fdc.intreq = TRUE; + if (fdc.chgreg & 1) { + pic_setirq(0x0b); + } + else { + pic_setirq(0x0a); + } } - nevent_forceexit(); +} + +void fdc_interrupt(void) { + + nevent_set(NEVENT_FDCINT, 512, fdc_intwait, NEVENT_ABSOLUTE); } static void fdc_interruptreset(void) { @@ -40,8 +51,9 @@ static BOOL fdc_isfdcinterrupt(void) { return(fdc.intreq); } -BYTE DMACCALL fdc_dmafunc(BYTE func) { +REG8 DMACCALL fdc_dmafunc(REG8 func) { +// TRACEOUT(("fdc_dmafunc = %d", func)); switch(func) { case DMAEXT_START: return(1); @@ -53,35 +65,16 @@ BYTE DMACCALL fdc_dmafunc(BYTE func) { return(0); } -static void fdc_dmaready(BYTE enable) { +static void fdc_dmaready(REG8 enable) { - if (CTRL_FDMEDIA == DISKTYPE_2HD) { - dmac.dmach[DMA_2HD].ready = enable; + if (fdc.chgreg & 1) { + dmac.dmach[FDC_DMACH2HD].ready = enable; } else { - dmac.dmach[DMA_2DD].ready = enable; - } -} - -void fdcbusy_error7(NEVENTITEM item) { - - if (item->flag & NEVENT_SETEVENT) { - if (fdc.event == FDCEVENT_BUSY) { - fdcsend_error7(); - } + dmac.dmach[FDC_DMACH2DD].ready = enable; } } -#if 0 // ↑イベントは残しとく... -static void fdcderay_error7(SINT16 ms) { // ver0.27 - - fdc.busy = 1; - fdc.event = FDCEVENT_BUSY; - fdc.status &= ~FDCSTAT_RQM; - nevent_setbyms(NEVENT_FDCBUSY, ms, fdcbusy_error7, NEVENT_ABSOLUTE); -} -#endif - // ---------------------------------------------------------------------- @@ -91,9 +84,9 @@ void fdcsend_error7(void) { fdc.event = FDCEVENT_BUFSEND; fdc.bufp = 0; fdc.bufcnt = 7; - fdc.buf[0] = (BYTE)(fdc.stat[fdc.us] >> 0); - fdc.buf[1] = (BYTE)(fdc.stat[fdc.us] >> 8); - fdc.buf[2] = (BYTE)(fdc.stat[fdc.us] >> 16); + fdc.buf[0] = (UINT8)(fdc.stat[fdc.us] >> 0); + fdc.buf[1] = (UINT8)(fdc.stat[fdc.us] >> 8); + fdc.buf[2] = (UINT8)(fdc.stat[fdc.us] >> 16); fdc.buf[3] = fdc.C; fdc.buf[4] = fdc.H; fdc.buf[5] = fdc.R; @@ -143,7 +136,7 @@ static void fdc_timeoutset(void) { -static BOOL FDC_DriveCheck(BYTE protectcheck) { +static BOOL FDC_DriveCheck(BOOL protectcheck) { if (!fddfile[fdc.us].fname[0]) { fdc.stat[fdc.us] = FDCRLT_IC0 | FDCRLT_NR | (fdc.hd << 2) | fdc.us; @@ -245,21 +238,22 @@ static void FDC_SenseDeviceStatus(void) get_hdus(); fdc.buf[0] = (fdc.hd << 2) | fdc.us; fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; - if (fdc.us < FDC_MAXDRIVE) { - fdc.buf[0] |= 0x20; - if (!fddfile[fdc.us].fname[0]) { - fdc.buf[0] |= 0x08; - } - else if (fddfile[fdc.us].protect) { - fdc.buf[0] |= 0x40; - } + if (fdc.equip & (1 << fdc.us)) { + fdc.buf[0] |= 0x08; if (!fdc.treg[fdc.us]) { fdc.buf[0] |= 0x10; } + if (fddfile[fdc.us].fname[0]) { + fdc.buf[0] |= 0x20; + } + if (fddfile[fdc.us].protect) { + fdc.buf[0] |= 0x40; + } } else { fdc.buf[0] |= 0x80; } +// TRACEOUT(("FDC_SenseDeviceStatus %.2x", fdc.buf[0])); fdc.event = FDCEVENT_BUFSEND; fdc.bufcnt = 1; fdc.bufp = 0; @@ -273,7 +267,7 @@ static void FDC_SenseDeviceStatus(void) } } -static BOOL writesector(void) { +static BRESULT writesector(void) { fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; if (!FDC_DriveCheck(TRUE)) { @@ -408,9 +402,12 @@ static void FDC_Recalibrate(void) { fdc.ncn = 0; fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; fdc.stat[fdc.us] |= FDCRLT_SE; - if ((fdc.us >= FDC_MAXDRIVE) || (!fddfile[fdc.us].fname[0])) { + if (!(fdc.equip & (1 << fdc.us))) { fdc.stat[fdc.us] |= FDCRLT_NR | FDCRLT_IC0; } + else if (!fddfile[fdc.us].fname[0]) { + fdc.stat[fdc.us] |= FDCRLT_NR; + } else { fdd_seek(); } @@ -433,18 +430,20 @@ static void FDC_SenceintStatus(void) { if (fdc_isfdcinterrupt()) { i = 0; if (fdc.stat[fdc.us]) { - fdc.buf[0] = (BYTE)fdc.stat[fdc.us]; + fdc.buf[0] = (UINT8)fdc.stat[fdc.us]; fdc.buf[1] = fdc.treg[fdc.us]; fdc.bufcnt = 2; fdc.stat[fdc.us] = 0; +// TRACEOUT(("fdc stat - %d [%.2x]", fdc.us, fdc.buf[0])); } else { for (; i<4; i++) { if (fdc.stat[i]) { - fdc.buf[0] = (BYTE)fdc.stat[i]; + fdc.buf[0] = (UINT8)fdc.stat[i]; fdc.buf[1] = fdc.treg[i]; fdc.bufcnt = 2; fdc.stat[i] = 0; +// TRACEOUT(("fdc stat - %d [%.2x]", i, fdc.buf[0])); break; } } @@ -454,7 +453,7 @@ static void FDC_SenceintStatus(void) { break; } } - if (i>=4) { + if (i >= 4) { fdc_interruptreset(); } } @@ -553,7 +552,8 @@ static void FDC_Seek(void) { // cm fdc.ncn = fdc.cmds[1]; fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; fdc.stat[fdc.us] |= FDCRLT_SE; - if ((fdc.us >= FDC_MAXDRIVE) || (!fddfile[fdc.us].fname[0])) { + if ((!(fdc.equip & (1 << fdc.us))) || + (!fddfile[fdc.us].fname[0])) { fdc.stat[fdc.us] |= FDCRLT_NR | FDCRLT_IC0; } else { @@ -628,7 +628,7 @@ static void fdcstatusreset(void) { fdc.status = FDCSTAT_RQM; } -void DMACCALL fdc_DataRegWrite(BYTE data) { +void DMACCALL fdc_datawrite(REG8 data) { // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) == FDCSTAT_RQM) { switch(fdc.event) { @@ -667,8 +667,7 @@ void DMACCALL fdc_DataRegWrite(BYTE data // } } - -BYTE DMACCALL fdc_DataRegRead(void) { +REG8 DMACCALL fdc_dataread(void) { // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) // == (FDCSTAT_RQM | FDCSTAT_DIO)) { @@ -683,7 +682,6 @@ BYTE DMACCALL fdc_DataRegRead(void) { case FDCEVENT_BUFSEND2: if (fdc.bufcnt) { -// TRACE_("read data", fdc.bufp); fdc.lastdata = fdc.buf[fdc.bufp++]; fdc.bufcnt--; } @@ -712,116 +710,107 @@ BYTE DMACCALL fdc_DataRegRead(void) { // ---- I/O -static void IOOUTCALL fdc_o92(UINT port, BYTE dat) { +static void IOOUTCALL fdc_o92(UINT port, REG8 dat) { -// TRACEOUT(("fdc out %x %x", port, dat)); - CTRL_FDMEDIA = DISKTYPE_2HD; +// TRACEOUT(("fdc out %.2x %.2x [%.4x:%.4x]", port, dat, CPU_CS, CPU_IP)); + + if (((port >> 4) ^ fdc.chgreg) & 1) { + return; + } if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) == FDCSTAT_RQM) { - fdc_DataRegWrite(dat); + fdc_datawrite(dat); } - (void)port; } -static void IOOUTCALL fdc_o94(UINT port, BYTE dat) { +static void IOOUTCALL fdc_o94(UINT port, REG8 dat) { -// TRACEOUT(("fdc out %x %x", port, dat)); - CTRL_FDMEDIA = DISKTYPE_2HD; +// TRACEOUT(("fdc out %.2x %.2x [%.4x:%.4x]", port, dat, CPU_CS, CPU_IP)); + + if (((port >> 4) ^ fdc.chgreg) & 1) { + return; + } if ((fdc.ctrlreg ^ dat) & 0x10) { fdcstatusreset(); fdc_dmaready(0); dmac_check(); } fdc.ctrlreg = dat; - (void)port; } -static BYTE IOINPCALL fdc_i90(UINT port) { +static REG8 IOINPCALL fdc_i90(UINT port) { -// TRACEOUT(("fdc in %x %x", port, fdc.status)); - CTRL_FDMEDIA = DISKTYPE_2HD; +// TRACEOUT(("fdc in %.2x %.2x [%.4x:%.4x]", port, fdc.status, +// CPU_CS, CPU_IP)); - (void)port; + if (((port >> 4) ^ fdc.chgreg) & 1) { + return(0xff); + } return(fdc.status); } -static BYTE IOINPCALL fdc_i92(UINT port) { +static REG8 IOINPCALL fdc_i92(UINT port) { - BYTE ret; + REG8 ret; - CTRL_FDMEDIA = DISKTYPE_2HD; + if (((port >> 4) ^ fdc.chgreg) & 1) { + return(0xff); + } if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) == (FDCSTAT_RQM | FDCSTAT_DIO)) { - ret = fdc_DataRegRead(); + ret = fdc_dataread(); } else { ret = fdc.lastdata; } - (void)port; -// TRACEOUT(("fdc in %x %x", port, ret)); +// TRACEOUT(("fdc in %.2x %.2x [%.4x:%.4x]", port, ret, CPU_CS, CPU_IP)); return(ret); } -static BYTE IOINPCALL fdc_i94(UINT port) { - - CTRL_FDMEDIA = DISKTYPE_2HD; - - (void)port; - return(0x40); -} - - -static void IOOUTCALL fdc_oca(UINT port, BYTE dat) { - - CTRL_FDMEDIA = DISKTYPE_2DD; - fdc_DataRegWrite(dat); - (void)port; -} - -static void IOOUTCALL fdc_occ(UINT port, BYTE dat) { - - CTRL_FDMEDIA = DISKTYPE_2DD; - fdc.ctrlreg = dat; - (void)port; -} - -static BYTE IOINPCALL fdc_ic8(UINT port) { - - CTRL_FDMEDIA = DISKTYPE_2DD; +static REG8 IOINPCALL fdc_i94(UINT port) { - (void)port; - return(fdc.status); + if (((port >> 4) ^ fdc.chgreg) & 1) { + return(0xff); + } + if (port & 0x10) { // 94 + return(0x40); + } + else { // CC + return(0x70); // readyを立てるるる + } } -static BYTE IOINPCALL fdc_ica(UINT port) { - - BYTE ret; - CTRL_FDMEDIA = DISKTYPE_2DD; - ret = fdc_DataRegRead(); +static void IOOUTCALL fdc_obe(UINT port, REG8 dat) { + fdc.chgreg = dat; + if (fdc.chgreg & 2) { + CTRL_FDMEDIA = DISKTYPE_2HD; + } + else { + CTRL_FDMEDIA = DISKTYPE_2DD; + } (void)port; - return(ret); } -static BYTE IOINPCALL fdc_icc(UINT port) { - - CTRL_FDMEDIA = DISKTYPE_2DD; +static REG8 IOINPCALL fdc_ibe(UINT port) { (void)port; - return(0x74); + return((fdc.chgreg & 3) | 8); } +static void IOOUTCALL fdc_o4be(UINT port, REG8 dat) { -static void IOOUTCALL fdc_obe(UINT port, BYTE dat) { - - fdc.chgreg = dat; + fdc.reg144 = dat; + if (dat & 0x10) { + fdc.rpm[(dat >> 5) & 3] = dat & 1; + } (void)port; } -static BYTE IOINPCALL fdc_ibe(UINT port) { +static REG8 IOINPCALL fdc_i4be(UINT port) { (void)port; - return((fdc.chgreg & 3) | 8); + return(fdc.rpm[(fdc.reg144 >> 5) & 3] | 0xf0); } @@ -831,28 +820,36 @@ static const IOOUT fdco90[4] = { NULL, fdc_o92, fdc_o94, NULL}; static const IOINP fdci90[4] = { fdc_i90, fdc_i92, fdc_i94, NULL}; -static const IOOUT fdcoc8[4] = { - NULL, fdc_oca, fdc_occ, NULL}; -static const IOINP fdcic8[4] = { - fdc_ic8, fdc_ica, fdc_icc, NULL}; - static const IOOUT fdcobe[1] = {fdc_obe}; static const IOINP fdcibe[1] = {fdc_ibe}; void fdc_reset(void) { ZeroMemory(&fdc, sizeof(fdc)); + fdc.equip = np2cfg.fddequip; +#if defined(SUPPORT_PC9821) + fdc.support144 = 1; +#else + fdc.support144 = np2cfg.usefd144; +#endif fdcstatusreset(); + dmac_attach(DMADEV_2HD, FDC_DMACH2HD); + dmac_attach(DMADEV_2DD, FDC_DMACH2DD); CTRL_FDMEDIA = DISKTYPE_2HD; + fdc.chgreg = 3; } void fdc_bind(void) { iocore_attachcmnoutex(0x0090, 0x00f9, fdco90, 4); iocore_attachcmninpex(0x0090, 0x00f9, fdci90, 4); - iocore_attachcmnoutex(0x00c8, 0x00f9, fdcoc8, 4); - iocore_attachcmninpex(0x00c8, 0x00f9, fdcic8, 4); + iocore_attachcmnoutex(0x00c8, 0x00f9, fdco90, 4); + iocore_attachcmninpex(0x00c8, 0x00f9, fdci90, 4); + if (fdc.support144) { + iocore_attachout(0x04be, fdc_o4be); + iocore_attachinp(0x04be, fdc_i4be); + } iocore_attachsysoutex(0x00be, 0x0cff, fdcobe, 1); iocore_attachsysinpex(0x00be, 0x0cff, fdcibe, 1); }