|
|
| version 1.3, 2003/10/21 11:22:05 | version 1.15, 2004/08/03 10:11:37 |
|---|---|
| Line 4 | Line 4 |
| #include "compiler.h" | #include "compiler.h" |
| #include "cpucore.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "fddfile.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, 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}; | 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0}; |
| #define FDC_FORCEREADY (1) | #define FDC_FORCEREADY (1) |
| #define FDC_MAXDRIVE 2 | |
| #define FDC_DELAYERROR7 | #define FDC_DELAYERROR7 |
| void fdc_interrupt(void) { | |
| fdc.intreq = TRUE; | void fdc_intwait(NEVENTITEM item) { |
| if (CTRL_FDMEDIA == DISKTYPE_2HD) { | |
| pic_setirq(0x0b); | if (item->flag & NEVENT_SETEVENT) { |
| } | fdc.intreq = TRUE; |
| else { | if (fdc.chgreg & 1) { |
| pic_setirq(0x0a); | 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) { | static void fdc_interruptreset(void) { |
| Line 40 static BOOL fdc_isfdcinterrupt(void) { | Line 51 static BOOL fdc_isfdcinterrupt(void) { |
| return(fdc.intreq); | return(fdc.intreq); |
| } | } |
| BYTE DMACCALL fdc_dmafunc(BYTE func) { | REG8 DMACCALL fdc_dmafunc(REG8 func) { |
| // TRACEOUT(("fdc_dmafunc = %d", func)); | |
| switch(func) { | switch(func) { |
| case DMAEXT_START: | case DMAEXT_START: |
| return(1); | return(1); |
| Line 53 BYTE DMACCALL fdc_dmafunc(BYTE func) { | Line 65 BYTE DMACCALL fdc_dmafunc(BYTE func) { |
| return(0); | return(0); |
| } | } |
| static void fdc_dmaready(BYTE enable) { | static void fdc_dmaready(REG8 enable) { |
| if (CTRL_FDMEDIA == DISKTYPE_2HD) { | if (fdc.chgreg & 1) { |
| dmac.dmach[DMA_2HD].ready = enable; | dmac.dmach[FDC_DMACH2HD].ready = enable; |
| } | } |
| else { | else { |
| dmac.dmach[DMA_2DD].ready = enable; | dmac.dmach[FDC_DMACH2DD].ready = enable; |
| } | } |
| } | } |
| void fdcbusy_error7(NEVENTITEM item) { | |
| if (item->flag & NEVENT_SETEVENT) { | |
| if (fdc.event == FDCEVENT_BUSY) { | |
| fdcsend_error7(); | |
| } | |
| } | |
| } | |
| #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 | |
| // ---------------------------------------------------------------------- | // ---------------------------------------------------------------------- |
| Line 143 static void fdc_timeoutset(void) { | Line 136 static void fdc_timeoutset(void) { |
| static BOOL FDC_DriveCheck(BYTE protectcheck) { | static BOOL FDC_DriveCheck(BOOL protectcheck) { |
| if (!fddfile[fdc.us].fname[0]) { | if (!fddfile[fdc.us].fname[0]) { |
| fdc.stat[fdc.us] = FDCRLT_IC0 | FDCRLT_NR | (fdc.hd << 2) | fdc.us; | fdc.stat[fdc.us] = FDCRLT_IC0 | FDCRLT_NR | (fdc.hd << 2) | fdc.us; |
| Line 245 static void FDC_SenseDeviceStatus(void) | Line 238 static void FDC_SenseDeviceStatus(void) |
| get_hdus(); | get_hdus(); |
| fdc.buf[0] = (fdc.hd << 2) | fdc.us; | fdc.buf[0] = (fdc.hd << 2) | fdc.us; |
| fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; | fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; |
| if (fdc.us < FDC_MAXDRIVE) { | if (fdc.equip & (1 << fdc.us)) { |
| fdc.buf[0] |= 0x20; | fdc.buf[0] |= 0x08; |
| if (!fddfile[fdc.us].fname[0]) { | |
| fdc.buf[0] |= 0x08; | |
| } | |
| else if (fddfile[fdc.us].protect) { | |
| fdc.buf[0] |= 0x40; | |
| } | |
| if (!fdc.treg[fdc.us]) { | if (!fdc.treg[fdc.us]) { |
| fdc.buf[0] |= 0x10; | fdc.buf[0] |= 0x10; |
| } | } |
| if (fddfile[fdc.us].fname[0]) { | |
| fdc.buf[0] |= 0x20; | |
| } | |
| if (fddfile[fdc.us].protect) { | |
| fdc.buf[0] |= 0x40; | |
| } | |
| } | } |
| else { | else { |
| fdc.buf[0] |= 0x80; | fdc.buf[0] |= 0x80; |
| } | } |
| // TRACEOUT(("FDC_SenseDeviceStatus %.2x", fdc.buf[0])); | |
| fdc.event = FDCEVENT_BUFSEND; | fdc.event = FDCEVENT_BUFSEND; |
| fdc.bufcnt = 1; | fdc.bufcnt = 1; |
| fdc.bufp = 0; | fdc.bufp = 0; |
| Line 352 static void readsector(void) { | Line 346 static void readsector(void) { |
| fdcsend_error7(); | fdcsend_error7(); |
| return; | return; |
| } | } |
| fdc.event = FDCEVENT_BUFSEND2; | fdc.event = FDCEVENT_BUFSEND2; |
| fdc.bufp = 0; | fdc.bufp = 0; |
| #if 1 // ver0.27 ?? | #if 1 // ver0.27 ?? |
| Line 407 static void FDC_Recalibrate(void) { | Line 402 static void FDC_Recalibrate(void) { |
| fdc.ncn = 0; | fdc.ncn = 0; |
| fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; | fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; |
| fdc.stat[fdc.us] |= FDCRLT_SE; | 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; | fdc.stat[fdc.us] |= FDCRLT_NR | FDCRLT_IC0; |
| } | } |
| else if (!fddfile[fdc.us].fname[0]) { | |
| fdc.stat[fdc.us] |= FDCRLT_NR; | |
| } | |
| else { | else { |
| fdd_seek(); | fdd_seek(); |
| } | } |
| Line 436 static void FDC_SenceintStatus(void) { | Line 434 static void FDC_SenceintStatus(void) { |
| fdc.buf[1] = fdc.treg[fdc.us]; | fdc.buf[1] = fdc.treg[fdc.us]; |
| fdc.bufcnt = 2; | fdc.bufcnt = 2; |
| fdc.stat[fdc.us] = 0; | fdc.stat[fdc.us] = 0; |
| // TRACEOUT(("fdc stat - %d [%.2x]", fdc.us, fdc.buf[0])); | |
| } | } |
| else { | else { |
| for (; i<4; i++) { | for (; i<4; i++) { |
| Line 444 static void FDC_SenceintStatus(void) { | Line 443 static void FDC_SenceintStatus(void) { |
| fdc.buf[1] = fdc.treg[i]; | fdc.buf[1] = fdc.treg[i]; |
| fdc.bufcnt = 2; | fdc.bufcnt = 2; |
| fdc.stat[i] = 0; | fdc.stat[i] = 0; |
| // TRACEOUT(("fdc stat - %d [%.2x]", i, fdc.buf[0])); | |
| break; | break; |
| } | } |
| } | } |
| Line 453 static void FDC_SenceintStatus(void) { | Line 453 static void FDC_SenceintStatus(void) { |
| break; | break; |
| } | } |
| } | } |
| if (i>=4) { | if (i >= 4) { |
| fdc_interruptreset(); | fdc_interruptreset(); |
| } | } |
| } | } |
| Line 463 static void FDC_SenceintStatus(void) { | Line 463 static void FDC_SenceintStatus(void) { |
| } | } |
| } | } |
| #if 0 // for test.. | |
| static void FDC_ReadID(void) { // cmd: 0a | static void FDC_ReadID(void) { // cmd: 0a |
| switch(fdc.event) { | switch(fdc.event) { |
| case FDCEVENT_CMDRECV: | case FDCEVENT_CMDRECV: |
| fdc.mf = fdc.cmd & 0x40; | |
| get_hdus(); | get_hdus(); |
| if (fdd_readid() == SUCCESS) { | |
| fdcsend_success7(); | |
| } | |
| else { | |
| fdc.stat[fdc.us] = fdc.us | (fdc.hd << 2) | | |
| FDCRLT_IC0 | FDCRLT_MA; | |
| fdcsend_error7(); | |
| } | |
| break; | break; |
| } | } |
| } | } |
| #endif | |
| static void FDC_WriteID(void) { // cmd: 0d | static void FDC_WriteID(void) { // cmd: 0d |
| Line 545 static void FDC_Seek(void) { // cm | Line 552 static void FDC_Seek(void) { // cm |
| fdc.ncn = fdc.cmds[1]; | fdc.ncn = fdc.cmds[1]; |
| fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; | fdc.stat[fdc.us] = (fdc.hd << 2) | fdc.us; |
| fdc.stat[fdc.us] |= FDCRLT_SE; | 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; | fdc.stat[fdc.us] |= FDCRLT_NR | FDCRLT_IC0; |
| } | } |
| else { | else { |
| Line 588 static const FDCOPE FDC_Ope[0x20] = { | Line 596 static const FDCOPE FDC_Ope[0x20] = { |
| FDC_Recalibrate, | FDC_Recalibrate, |
| FDC_SenceintStatus, | FDC_SenceintStatus, |
| FDC_WriteData, | FDC_WriteData, |
| FDC_Invalid, // FDC_ReadID, | FDC_ReadID, |
| FDC_Invalid, | FDC_Invalid, |
| FDC_ReadData, | FDC_ReadData, |
| FDC_WriteID, | FDC_WriteID, |
| Line 620 static void fdcstatusreset(void) { | Line 628 static void fdcstatusreset(void) { |
| fdc.status = FDCSTAT_RQM; | 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) { | // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) == FDCSTAT_RQM) { |
| switch(fdc.event) { | switch(fdc.event) { |
| Line 659 void DMACCALL fdc_DataRegWrite(BYTE data | Line 667 void DMACCALL fdc_DataRegWrite(BYTE data |
| // } | // } |
| } | } |
| REG8 DMACCALL fdc_dataread(void) { | |
| BYTE DMACCALL fdc_DataRegRead(void) { | |
| // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) | // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) |
| // == (FDCSTAT_RQM | FDCSTAT_DIO)) { | // == (FDCSTAT_RQM | FDCSTAT_DIO)) { |
| Line 675 BYTE DMACCALL fdc_DataRegRead(void) { | Line 682 BYTE DMACCALL fdc_DataRegRead(void) { |
| case FDCEVENT_BUFSEND2: | case FDCEVENT_BUFSEND2: |
| if (fdc.bufcnt) { | if (fdc.bufcnt) { |
| // TRACE_("read data", fdc.bufp); | |
| fdc.lastdata = fdc.buf[fdc.bufp++]; | fdc.lastdata = fdc.buf[fdc.bufp++]; |
| fdc.bufcnt--; | fdc.bufcnt--; |
| } | } |
| Line 704 BYTE DMACCALL fdc_DataRegRead(void) { | Line 710 BYTE DMACCALL fdc_DataRegRead(void) { |
| // ---- I/O | // ---- I/O |
| static void IOOUTCALL fdc_o92(UINT port, BYTE dat) { | static void IOOUTCALL fdc_o92(UINT port, REG8 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) { | 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) { |
| 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) { | if ((fdc.ctrlreg ^ dat) & 0x10) { |
| fdcstatusreset(); | fdcstatusreset(); |
| fdc_dmaready(0); | fdc_dmaready(0); |
| dmac_check(); | dmac_check(); |
| } | } |
| fdc.ctrlreg = dat; | fdc.ctrlreg = dat; |
| (void)port; | |
| } | } |
| static BYTE IOINPCALL fdc_i90(UINT port) { | static REG8 IOINPCALL fdc_i90(UINT port) { |
| 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); | 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)) | if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) |
| == (FDCSTAT_RQM | FDCSTAT_DIO)) { | == (FDCSTAT_RQM | FDCSTAT_DIO)) { |
| ret = fdc_DataRegRead(); | ret = fdc_dataread(); |
| } | } |
| else { | else { |
| ret = fdc.lastdata; | ret = fdc.lastdata; |
| } | } |
| (void)port; | // TRACEOUT(("fdc in %.2x %.2x [%.4x:%.4x]", port, ret, CPU_CS, CPU_IP)); |
| return(ret); | return(ret); |
| } | } |
| static BYTE IOINPCALL fdc_i94(UINT port) { | static REG8 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; | |
| (void)port; | if (((port >> 4) ^ fdc.chgreg) & 1) { |
| return(fdc.status); | 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; | static void IOOUTCALL fdc_obe(UINT port, REG8 dat) { |
| ret = fdc_DataRegRead(); | |
| fdc.chgreg = dat; | |
| if (fdc.chgreg & 2) { | |
| CTRL_FDMEDIA = DISKTYPE_2HD; | |
| } | |
| else { | |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| } | |
| (void)port; | (void)port; |
| return(ret); | |
| } | } |
| static BYTE IOINPCALL fdc_icc(UINT port) { | static REG8 IOINPCALL fdc_ibe(UINT port) { |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| (void)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.reg144 = dat; |
| if (dat & 0x10) { | |
| fdc.chgreg = dat; | fdc.rpm[(dat >> 5) & 3] = dat & 1; |
| } | |
| (void)port; | (void)port; |
| } | } |
| static BYTE IOINPCALL fdc_ibe(UINT port) { | static REG8 IOINPCALL fdc_i4be(UINT port) { |
| (void)port; | (void)port; |
| return((fdc.chgreg & 3) | 8); | return(fdc.rpm[(fdc.reg144 >> 5) & 3] | 0xf0); |
| } | } |
| Line 819 static const IOOUT fdco90[4] = { | Line 820 static const IOOUT fdco90[4] = { |
| NULL, fdc_o92, fdc_o94, NULL}; | NULL, fdc_o92, fdc_o94, NULL}; |
| static const IOINP fdci90[4] = { | static const IOINP fdci90[4] = { |
| fdc_i90, fdc_i92, fdc_i94, NULL}; | 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 IOOUT fdcobe[1] = {fdc_obe}; |
| static const IOINP fdcibe[1] = {fdc_ibe}; | static const IOINP fdcibe[1] = {fdc_ibe}; |
| void fdc_reset(void) { | void fdc_reset(void) { |
| ZeroMemory(&fdc, sizeof(fdc)); | ZeroMemory(&fdc, sizeof(fdc)); |
| fdc.equip = np2cfg.fddequip; | |
| #if defined(SUPPORT_PC9821) | |
| fdc.support144 = 1; | |
| #else | |
| fdc.support144 = np2cfg.usefd144; | |
| #endif | |
| fdcstatusreset(); | fdcstatusreset(); |
| dmac_attach(DMADEV_2HD, FDC_DMACH2HD); | |
| dmac_attach(DMADEV_2DD, FDC_DMACH2DD); | |
| CTRL_FDMEDIA = DISKTYPE_2HD; | CTRL_FDMEDIA = DISKTYPE_2HD; |
| fdc.chgreg = 3; | |
| } | } |
| void fdc_bind(void) { | void fdc_bind(void) { |
| iocore_attachcmnoutex(0x0090, 0x00f9, fdco90, 4); | iocore_attachcmnoutex(0x0090, 0x00f9, fdco90, 4); |
| iocore_attachcmninpex(0x0090, 0x00f9, fdci90, 4); | iocore_attachcmninpex(0x0090, 0x00f9, fdci90, 4); |
| iocore_attachcmnoutex(0x00c8, 0x00f9, fdcoc8, 4); | iocore_attachcmnoutex(0x00c8, 0x00f9, fdco90, 4); |
| iocore_attachcmninpex(0x00c8, 0x00f9, fdcic8, 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_attachsysoutex(0x00be, 0x0cff, fdcobe, 1); |
| iocore_attachsysinpex(0x00be, 0x0cff, fdcibe, 1); | iocore_attachsysinpex(0x00be, 0x0cff, fdcibe, 1); |
| } | } |