| version 1.1.1.1, 2003/10/16 17:57:52 | version 1.12, 2004/05/07 11:42:29 | 
| Line 4 | Line 4 | 
 |  |  | 
 |  |  | 
 | #include        "compiler.h" | #include        "compiler.h" | 
| #include        "dosio.h" | #include        "cpucore.h" | 
| #include        "i286.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 42  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 55  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(); |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | 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); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | // ---------------------------------------------------------------------- | // ---------------------------------------------------------------------- | 
 |  |  | 
| 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 467  static void FDC_ReadID(void) {       // | Line 467  static void FDC_ReadID(void) {       // | 
 |  |  | 
 | 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; | 
 | } | } | 
 | } | } | 
| Line 543  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 586  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 618  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 657  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 673  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 702  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; | if (((port >> 4) ^ fdc.chgreg) & 1) { | 
|  | return(0xff); | 
| (void)port; | } | 
 | return(0x40); | return(0x40); | 
 | } | } | 
 |  |  | 
 |  |  | 
| static void IOOUTCALL fdc_oca(UINT port, BYTE dat) { | static void IOOUTCALL fdc_obe(UINT port, REG8 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; |  | 
| return(fdc.status); |  | 
| } |  | 
|  |  | 
| static BYTE IOINPCALL fdc_ica(UINT port) { |  | 
|  |  | 
| BYTE    ret; |  | 
|  |  | 
| CTRL_FDMEDIA = DISKTYPE_2DD; |  | 
| 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 817  static const IOOUT fdco90[4] = { | Line 815  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); | 
 | } | } |