/* Copyright (C) Magna Carta Software, Inc. 1990. All Rights Reserved INS8250.C -- Routines specific to the National Semiconductor INS8250 family. */ #include #if (defined(MSC) || defined(__WATCOMC__) || defined(__HIGHC__)) #include #endif /* MSC v6.0A bugs force sub-optimization of this file To see the problem, try $(C_OPT) instead of $(C_OPTR) in large model */ #if defined(MSC) #pragma optimize("e", off) #endif /* ISAUART -- Attempt to recognize the UART type when it is a member of the INS8250 family. Return value: EOF -- not recognized; 0 -- INS8250/INS8250-B; 1 -- INS8250A/NS16450; 2 -- NS16550; 3 -- NS16550A; */ short isauart(WORD addr) { short old_reg, new_reg; short ret = 0; /* assume an INS8250/B */ /* CHECK FOR A MEMBER OF THE INS8250 FAMILY BY PUTTING IT INTO LOOPBACK */ old_reg = inp(addr+4); /* save MCR */ outp(addr+4, old_reg | 0X10); /* set loopback on */ inp(addr+6); /* reset delta status */ outp(addr+4, inp(addr+4) | 1); /* set DTR HIGH */ if (!(inp(addr+6) & 0X20)) { ret = -1; /* DSR not HIGH so not recognized */ outp(addr+4, old_reg); /* restore MCR */ } else { outp(addr+4, inp(addr+4) & ~1); /* set DTR LOW */ if ((inp(addr+6) & 0X20)) { ret = -1; /* DSR not LOW so not recognized */ outp(addr+4, old_reg); /* restore MCR */ } else { outp(addr+4, old_reg); /* restore MCR */ /* READ THE SCRATCH REGISTER */ old_reg = (short) inp(addr+7); outp(addr+7, ~old_reg); if (((~old_reg) & 0XFF) == inp(addr+7)) { ret = 1; outp(addr+7, old_reg); } if (ret) { /* THE UART IS 16450 COMPATIBLE -- CHECK FOR 16550x */ old_reg = inp(addr+2); if (old_reg & 0X30) ret = -1; if (ret != -1) { outp(addr+2, 0X1); /* turn on FIFOs */ new_reg = inp(addr+2); if (new_reg & 0XC0) ret = (new_reg >> 6) & 0XFF; } } } } return (ret); }