#include #include #define Uses_EPP #include /*** SMC Routines */ SMC::SMC() { key = 0; port = 0; chipFound = findChip(); } SMC::~SMC() { } int SMC::foundSMC() { return chipFound; } int SMC::findChip() { unsigned chipId; for ( port = 0; port < SMCnPorts; port++ ) { for ( key = 0; key < SMCnKeys; key++ ) { chipId = read(0x0d); if ( (chipId & 0xF0) == 0x60 ) return chipId; } } return 0; } unsigned SMC::read(unsigned addr) { unsigned temp; disable(); outp(SMCkPorts[port], SMCkeys[key]); outp(SMCkPorts[port], SMCkeys[key]); outp(SMCaPorts[port], addr); temp = inp(SMCdPorts[port]); outp(SMCkPorts[port], SMCendKey); enable(); return temp; } void SMC::write(unsigned addr, unsigned data) { unsigned temp; disable(); outp(SMCkPorts[port], SMCkeys[key]); outp(SMCkPorts[port], SMCkeys[key]); outp(SMCaPorts[port], addr); outp(SMCdPorts[port], data); outp(SMCkPorts[port], SMCendKey); enable(); } int SMC::checkMode() { unsigned cr1 = read(1); unsigned cr4 = read(4); if ( (cr1 & 8) ) return SPPmode; switch ( (cr4 & 3) ) { case 1: // EPP mode if ( (cr4 & 0x40) ) return EPPmodeV17;else return EPPmodeV19; case 2: // ECP mode return ECPmode; case 3: // ECP + EPP mode if ( (cr4 & 0x40) ) return ECPEPPmodeV17;else return ECPEPPmodeV19; case 0: // BPP mode default: break; } return BPPmode; } void SMC::setMode(int mode) { unsigned cr1 = read(1); unsigned cr4 = read(4); switch ( mode ) { case 1: // BPP mode write(1, (cr1 & 0xF7)); write(4, (cr4 & 0xFC)); break; case 2: // EPP V1.7 mode write(1, (cr1 & 0xF7)); write(4, ((cr4 & 0xFC) | 0x41)); break; case 3: // EPP V1.9 mode write(1, (cr1 & 0xF7)); write(4, ((cr4 & 0xBC) | 1)); break; case 4: // ECP mode write(1, (cr1 & 0xF7)); write(4, ((cr4 & 0xFC) | 2)); break; case 5: // ECP + EPP V1.7 mode write(1, (cr1 & 0xF7)); write(4, ((cr4 & 0xFC) | 0x43)); break; case 6: // ECP + EPP V1.9 mode write(1, (cr1 & 0xF7)); write(4, ((cr4 & 0xBC) | 3)); break; case 0: // SPP mode default: write(1, (cr1 | 8)); write(4, (cr4 & 0xFC)); } } unsigned SMC::baseAddress() { if ( chipFound == 0x68 || chipFound == 0x69 ) { unsigned base = read(0x23) << 2; return base; } else { unsigned bases[4] = {0x3FF, 0x3BC, 0x378, 0x278}; int iport = read(1) & 3; return bases[iport]; } } /*** Winbond Routines */ Winbond::Winbond() { key = 0; port = 0; chipId = findChip(); chipFound = (chipId == 0xFF) ? FALSE : TRUE; } Winbond::~Winbond() { } int Winbond::foundWinbond() { return chipFound; } int Winbond::chipNumber() { return chipId; } int Winbond::findChip() { unsigned id; for ( port = 0; port < nWinbondPorts; port++ ) for ( key = 0; key < nWinbondKeys; key++ ) { id = read(0x09) & 0x0F; for ( int i = 0; i < nWinbondChips; i++ ) if ( id == WinbondIds[i] ) return i; } return 0xFF; } unsigned Winbond::read(unsigned addr) { unsigned temp; disable(); outp(kWinbondPorts[port], WinbondKeys[port][key]); if ( port > 0 ) outp(kWinbondPorts[port], WinbondKeys[port][key]); outp(aWinbondPorts[port], addr); temp = inp(dWinbondPorts[port]); outp(kWinbondPorts[port], WinbondEndKey); enable(); return temp; } void Winbond::write(unsigned addr, unsigned data) { unsigned temp; disable(); outp(kWinbondPorts[port], WinbondKeys[port][key]); if ( port > 0 ) outp(kWinbondPorts[port], WinbondKeys[port][key]); outp(aWinbondPorts[port], addr); outp(dWinbondPorts[port], data); outp(kWinbondPorts[port], WinbondEndKey); enable(); } int Winbond::checkMode() { unsigned cr0 = read(0); unsigned cr9 = read(9); unsigned cr3 = read(3); unsigned mode = ((cr0 >> 2) & 3) + ((cr9 & 0x80) >> 5); unsigned ver = (cr3 >> 5) & 1; unsigned spp = (cr3 >> 7) & 1; switch ( mode ) { case 1: // Extension FDD return ExtFDDmode; case 2: // Extension Adapter return ExtADPmode; case 3: // Extension 2FDD return Ext2FDDmode; case 4: // Joy Stick return JoystickMode; case 5: // EPP if ( ver ) return EPPmodeV17; else return EPPmodeV19; case 6: // ECP return ECPmode; case 7: // ECP + EPP if ( ver ) return ECPEPPmodeV17;else return ECPEPPmodeV19; case 0: // SPP or BPP default: if ( spp ) return SPPmode;else return BPPmode; } } void Winbond::setMode(int mode) { unsigned cr0 = read(0); unsigned cr9 = read(9); unsigned cr3 = read(3); switch ( mode ) { case 1: // BPP mode write(9, (cr9 & 0x7F)); write(0, (cr0 & 0xF3)); write(3, (cr3 & 0x7F)); break; case 2: // EPP V1.7 mode write(3, ((cr3 & 0x7F) | 0x20)); write(9, (cr9 | 0x80)); write(0, ((cr0 & 0xF3) | 4)); break; case 3: // EPP V1.9 mode write(3, (cr3 & 0x5F)); write(9, (cr9 | 0x80)); write(0, ((cr0 & 0xF3) | 4)); break; case 4: // ECP mode write(3, (cr3 & 0x7F)); write(9, (cr9 | 0x80)); write(0, ((cr0 & 0xF3) | 8)); break; case 5: // ECP + EPP V1.7 mode write(3, ((cr3 & 0x7F) | 0x20)); write(9, (cr9 | 0x80)); write(0, ((cr0 & 0xF3) | 0x0C)); break; case 6: // ECP + EPP V1.9 mode write(3, (cr3 & 0x5F)); write(9, (cr9 | 0x80)); write(0, ((cr0 & 0xF3) | 0x0C)); break; case 0: // SPP mode default: write(9, (cr9 & 0x7F)); write(0, (cr0 & 0xF3)); write(3, (cr3 | 0x80)); } } unsigned Winbond::baseAddress() { if ( chipId < 2 ) { unsigned bases[4] = {0x3BC, 0x278, 0x378, 0x3FF}; int iport = (read(1) >> 4) & 3; return bases[iport]; } else if ( chipId == 2 ) { unsigned base = read(0x23) << 2; return base; } return 0x3FF; }