|
|
| version 1.7, 2004/01/22 01:10:04 | version 1.11, 2004/04/14 16:35:53 |
|---|---|
| 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" |
| Line 19 static const UINT8 FDCCMD_TABLE[32] = { | Line 20 static const UINT8 FDCCMD_TABLE[32] = { |
| #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 46 static BOOL fdc_isfdcinterrupt(void) { | Line 53 static BOOL fdc_isfdcinterrupt(void) { |
| REG8 DMACCALL fdc_dmafunc(REG8 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 59 REG8 DMACCALL fdc_dmafunc(REG8 func) { | Line 67 REG8 DMACCALL fdc_dmafunc(REG8 func) { |
| static void fdc_dmaready(REG8 enable) { | static void fdc_dmaready(REG8 enable) { |
| if (CTRL_FDMEDIA == DISKTYPE_2HD) { | if (fdc.chgreg & 1) { |
| dmac.dmach[FDC_DMACH2HD].ready = enable; | dmac.dmach[FDC_DMACH2HD].ready = enable; |
| } | } |
| else { | else { |
| Line 67 static void fdc_dmaready(REG8 enable) { | Line 75 static void fdc_dmaready(REG8 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 249 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 412 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 441 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 449 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 458 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 557 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 686 REG8 DMACCALL fdc_dataread(void) { | Line 682 REG8 DMACCALL fdc_dataread(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 717 REG8 DMACCALL fdc_dataread(void) { | Line 712 REG8 DMACCALL fdc_dataread(void) { |
| static void IOOUTCALL fdc_o92(UINT port, REG8 dat) { | static void IOOUTCALL fdc_o92(UINT port, REG8 dat) { |
| // TRACEOUT(("fdc out %x %x", port, dat)); | // TRACEOUT(("fdc out %.2x %.2x [%.4x:%.4x]", port, dat, CPU_CS, CPU_IP)); |
| CTRL_FDMEDIA = DISKTYPE_2HD; | |
| 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_datawrite(dat); | fdc_datawrite(dat); |
| } | } |
| (void)port; | |
| } | } |
| static void IOOUTCALL fdc_o94(UINT port, REG8 dat) { | static void IOOUTCALL fdc_o94(UINT port, REG8 dat) { |
| // TRACEOUT(("fdc out %x %x", port, dat)); | // TRACEOUT(("fdc out %.2x %.2x [%.4x:%.4x]", port, dat, CPU_CS, CPU_IP)); |
| CTRL_FDMEDIA = DISKTYPE_2HD; | |
| 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 REG8 IOINPCALL fdc_i90(UINT port) { | static REG8 IOINPCALL fdc_i90(UINT port) { |
| // TRACEOUT(("fdc in %x %x", port, fdc.status)); | // TRACEOUT(("fdc in %.2x %.2x [%.4x:%.4x]", port, fdc.status, |
| CTRL_FDMEDIA = DISKTYPE_2HD; | // CPU_CS, CPU_IP)); |
| (void)port; | if (((port >> 4) ^ fdc.chgreg) & 1) { |
| return(0xff); | |
| } | |
| return(fdc.status); | return(fdc.status); |
| } | } |
| Line 751 static REG8 IOINPCALL fdc_i92(UINT port) | Line 752 static REG8 IOINPCALL fdc_i92(UINT port) |
| REG8 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_dataread(); | ret = fdc_dataread(); |
| Line 759 static REG8 IOINPCALL fdc_i92(UINT port) | Line 762 static REG8 IOINPCALL fdc_i92(UINT port) |
| else { | else { |
| ret = fdc.lastdata; | ret = fdc.lastdata; |
| } | } |
| (void)port; | // TRACEOUT(("fdc in %.2x %.2x [%.4x:%.4x]", port, ret, CPU_CS, CPU_IP)); |
| // TRACEOUT(("fdc in %x %x", port, ret)); | |
| return(ret); | return(ret); |
| } | } |
| static REG8 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, REG8 dat) { | static void IOOUTCALL fdc_obe(UINT port, REG8 dat) { |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| fdc_datawrite(dat); | |
| (void)port; | |
| } | |
| static void IOOUTCALL fdc_occ(UINT port, REG8 dat) { | |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| fdc.ctrlreg = dat; | |
| (void)port; | |
| } | |
| static REG8 IOINPCALL fdc_ic8(UINT port) { | |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| (void)port; | |
| return(fdc.status); | |
| } | |
| static REG8 IOINPCALL fdc_ica(UINT port) { | |
| REG8 ret; | |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| ret = fdc_dataread(); | |
| fdc.chgreg = dat; | |
| if (fdc.chgreg & 2) { | |
| CTRL_FDMEDIA = DISKTYPE_2HD; | |
| } | |
| else { | |
| CTRL_FDMEDIA = DISKTYPE_2DD; | |
| } | |
| (void)port; | (void)port; |
| return(ret); | |
| } | } |
| static REG8 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, REG8 dat) { | fdc.reg144 = dat; |
| if (dat & 0x10) { | |
| fdc.chgreg = dat; | fdc.rpm[(dat >> 5) & 3] = dat & 1; |
| } | |
| (void)port; | (void)port; |
| } | } |
| static REG8 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 834 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; |
| dmac_attach(DMADEV_FDD, FDC_DMACH2HD); | fdc.chgreg = 3; |
| dmac_attach(DMADEV_FDD, FDC_DMACH2DD); | |
| } | } |
| 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); |
| } | } |