/********************************************************************* R56_IO.C Route 56 Developer's Toolkit 1995 (C) Copyright Sealevel Systems, Inc., 1995 ********************************************************************** History: 07-19-95 JGY Original module 10-27-95 JGY Updated for Windows (16 bit) support *********************************************************************/ #include #include // for MK_FP macro #include "sstypes.h" #include "z16c32.h" #include "r56_io.h" #ifdef _WINDOWS #include extern WORD _near _My8000h; // Exported by Kernel #define Sel8000h (&_My8000h) extern WORD _near _My9000h; // Exported by Kernel #define Sel9000h (&_My9000h) extern WORD _near _MyA000h; // Exported by Kernel #define SelA000h (&_MyA000h) extern WORD _near _MyB000h; // Exported by Kernel #define SelB000h (&_MyB000h) extern WORD _near _MyC000h; // Exported by Kernel #define SelC000h (&_MyC000h) extern WORD _near _MyD000h; // Exported by Kernel #define SelD000h (&_MyD000h) extern WORD _near _MyE000h; // Exported by Kernel #define SelE000h (&_MyE000h) extern WORD _near _MyF000h; // Exported by Kernel #define SelF000h (&_MyF000h) #endif /******************************************************************* Internal Prototypes *******************************************************************/ VOID DelayR56(VOID); BYTE DecodeMemory(fpR56_INFO fpCard); /******************************************************************* SetR56Interface This routine will set the Route-56 interface (EIA-530, EIA-232, CCITT V.35) Passes: fpCard Returns: 0 - Pass -1 - Failed *******************************************************************/ WORD SetR56Interface(fpR56_INFO fpCard, BYTE bInterface) { WORD MasterPCR; if((bInterface < 0) || (bInterface > 3)) return ((WORD) -1); MasterPCR= IUSCin(fpCard,PCR); MasterPCR = MasterPCR & 0xff0f; if(bInterface == SET_EIA530) MasterPCR = MasterPCR | SELECT_EIA530; else if(bInterface == SET_RS232) MasterPCR = MasterPCR | SELECT_RS232; else if(bInterface == SET_V35) MasterPCR = MasterPCR | SELECT_V35; IUSCout(fpCard,PCR,MasterPCR); return((WORD) 0); } /******************************************************************* SetR56Clock This routine will set the Route-56 clock direction( TXC input or output) Passes: fpCard, TXC_IN (1) or TXC_OUT (2) Returns: 0 - Pass -1 - Failed *******************************************************************/ WORD SetR56Clock (fpR56_INFO fpCard, BYTE bClock) { WORD MasterPCR, wTemp; if((bClock != SET_TXC_INPUT) && (bClock != SET_TXC_OUTPUT)) return ((WORD) -1); MasterPCR= IUSCin(fpCard,PCR); if(bClock == SET_TXC_INPUT) {MasterPCR = MasterPCR & 0xf3ff; MasterPCR = MasterPCR | TXC_INPUT; IUSCout(fpCard,PCR,MasterPCR); wTemp = IUSCin(fpCard, IOCR); wTemp = wTemp & 0xffC7; /*TxC is input*/ IUSCout(fpCard, IOCR, wTemp); } else {MasterPCR = MasterPCR & 0xf3ff; MasterPCR = MasterPCR | TXC_OUTPUT; IUSCout(fpCard,PCR,MasterPCR); wTemp = IUSCin(fpCard, IOCR); wTemp = wTemp & 0xffC7; wTemp = wTemp | 0x0020; /*TxC is output of BRG0*/ IUSCout(fpCard, IOCR, wTemp); } return (0); } /******************************************************************* VerifyR56 This routine will verify the I/O presence of the ROUTE-56 adapter Passes: wIOBASE - I/O base address of the ROUTE-56 Returns: 0 - Address verified -1 - Address NOT verified *******************************************************************/ WORD VerifyR56(fpR56_INFO fpCard) { if(IN(fpCard->wIOAddress) == 0xff) return(0xffff); return(0); } /******************************************************************* ResetIUSC Passes: fpCard - card data struct. Returns: LOWORD (AX) Error Code ER_BADRESET - Reset already (always) ON ER_RESETTO - Reset TimeOut (pending on timeout) HIWORD (DX) Number of I/O Writes until Reset obtained. Notes: This routine assumes that the I/O address has been verified by VerifyR56(). Also note that HIWORD is only valid if LOWORD = NULL (0). *******************************************************************/ DWORD ResetIUSC(fpR56_INFO fpCard) { WORD wCount, wTemp; wTemp = fpCard->wIOAddress + 3; if(((IN(wTemp) & NOT_RESET) != NOT_RESET)) return(ER_BADRESET); /* Is Reset already aserted? */ for( wCount = 0; wCount < 0xfffe; wCount++) {OUT(wTemp, 0x00); if( 0 == (IN(wTemp) & NOT_RESET)) break; } if(wCount==0xffff) return(ER_RESETTO); OUT(wTemp, 0x00); OUT(wTemp, 0x00); OUT(wTemp, 0x00); DelayR56(); DelayR56(); DelayR56(); DelayR56(); DelayR56(); return(0); } /******************************************************************* DelayR56 Simple delay routine. *******************************************************************/ VOID DelayR56(VOID) { INT i; for(i = 0 ; i < 0xfffe; i++) IO_DELAY; } /******************************************************************* InitIUSC Passes: fpCARD - Far pointer to Card Struct Returns: Zero if Init OK Array Register value of resiger that error occured *******************************************************************/ WORD InitIUSC(fpR56_INFO fpCard) { WORD wTemp, wOffset; BYTE bTemp1,bTemp2; LPBYTE fpbInit, fpbMemory; LPWORD fpwMemory,fpwInit; /* Disable Memory Window */ OUT(fpCard->wIOAddress,(~MEM_WIN_ON) & IN(fpCard->wIOAddress)); /*make it go fast and set low address mode*/ OUT(fpCard->wIOAddress + 2,LOADD | EN_16_BIT | ZERO_WS | ISA_IRQ); bTemp1 = DecodeMemory(fpCard); if(bTemp1 == 0xff) return(ER_BADMEMORY); switch(fpCard->IUSCIRQ) { case 3: bTemp2 = SEL_IRQ_3; break; case 4: bTemp2 = SEL_IRQ_4; break; case 9: bTemp2 = SEL_IRQ_9; break; case 10: bTemp2 = SEL_IRQ_10; break; case 11: bTemp2 = SEL_IRQ_11; break; case 12: bTemp2 = SEL_IRQ_12; break; case 15: bTemp2 = SEL_IRQ_15; break; case 0: bTemp2 = SEL_IRQ_NONE; break; default: return(ER_BADIRQ); break; } OUT(fpCard->wIOAddress+1, bTemp1 | bTemp2); /* Turn memory window ON and point to first page*/ OUT(fpCard->wIOAddress,((~IUSC_DISABLE) & (MEM_WIN_ON | IN(fpCard->wIOAddress)))); for(wOffset = 0 ; wOffset < 0xfff; wOffset=wOffset + 2) {if( * (fpCard->InitArray + wOffset) == -1) {OUT(fpCard->wIOAddress, MEM_WIN_OFF | MEM_PAGE_FIRST); return(0); /*Return OK*/ } wTemp = * (fpCard->InitArray + wOffset); /*Get IUSC Register Number*/ fpbInit = (LPBYTE)(fpCard->InitArray + wOffset + 1); fpwInit = (LPWORD)(fpCard->InitArray + wOffset + 1); fpbMemory = (LPBYTE) ((fpCard->MemoryBase) + LOBYTE(wTemp)); fpwMemory = (LPWORD) (fpCard->MemoryBase + LOBYTE(wTemp)); if(writeW == (writeW & wTemp)) /* Mask the upper byte*/ IUSCout(fpCard,LOBYTE(wTemp), *(fpwInit)); if(writeH == (writeW & wTemp)) /* Mask the upper byte*/ IUSCoutb(fpCard,LOBYTE(wTemp+1), *(fpbInit+1)); if(writeL == (writeW & wTemp)) /* Mask the upper byte*/ IUSCoutb(fpCard,LOBYTE(wTemp), *(fpbInit)); if(checkW == (checkW & wTemp)) /* Mask the upper byte*/ if((IUSCin(fpCard,LOBYTE(wTemp))) != *(fpwInit)) return(wTemp); if(checkL == (checkW & wTemp)) /* Mask the upper byte*/ if((IUSCinb(fpCard,LOBYTE(wTemp))) != *(fpbInit)) return(wTemp); if(checkH == (checkW & wTemp)) /* Mask the upper byte*/ if((IUSCinb(fpCard,LOBYTE(wTemp+1))) != *(fpbInit+1)) return(wTemp); } OUT(fpCard->wIOAddress, MEM_WIN_OFF | MEM_PAGE_FIRST); return(wTemp); /*Return Reg number on error*/ } /******************************************************************* DecodeMemory Passes: fpMEM - Memory address Returns: AL = value to OR with other bits to determine Memory Address of 5010 adapter. NOTE: This MUST me done differently in Windows DEF file must import the following: __My8000h = KERNEL.__8000h __My9000h = KERNEL.__9000h __MyA000h = KERNEL.__A000h __MyB000h = KERNEL.__B000h __MyC000h = KERNEL.__C000h __MyD000h = KERNEL.__D000h __MyE000h = KERNEL.__E000h *******************************************************************/ BYTE DecodeMemory(fpR56_INFO fpCard) { // The R56_INFO struct values of TxLinkList and RxLinkList are set to // default values here. They will need to be set to different values // from the application level. #ifndef _WINDOWS // This assumes a real mode address fpCard->TxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase); fpCard->RxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase); return(0x1f & LOBYTE( HIWORD(fpCard->MemoryBase) >> 0x0a)); #endif #ifdef _WINDOWS // This assumes a protected mode address BYTE bReturnValue; WORD wTemp; bReturnValue = (0x1f & LOBYTE( HIWORD(fpCard->MemoryBase) >> 0x0a)); wTemp = HIWORD(fpCard->MemoryBase); switch(wTemp) {case 0x8000: /* Low Address 80000-83FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel8000h, 0x0000)); break; case 0x8400: /* Low Address 84000-87FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel8000h, 0x4000)); break; case 0x8800: /* Low Address 88000-8BFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel8000h, 0x8000)); break; case 0x8C00: /* Low Address 8C000-8FFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel8000h, 0xc000)); break; case 0x9000: /* Low Address 90000-93FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel9000h, 0x0000)); break; case 0x9400: /* Low Address 94000-97FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel9000h, 0x4000)); break; case 0x9800: /* Low Address 98000-9BFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel9000h, 0x8000)); break; case 0x9C00: /* Low Address 9C000-9FFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(Sel9000h, 0xC000)); break; case 0xA000: /* Low Address A0000-A3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelA000h, 0x0000)); break; case 0xA400: /* Low Address A4000-A7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelA000h, 0x4000)); break; case 0xA800: /* Low Address A8000-ABFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelA000h, 0x8000)); break; case 0xAC00: /* Low Address AC000-AFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelA000h, 0xc000)); break; case 0xB000: /* Low Address B0000-B3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelB000h, 0x0000)); break; case 0xB400: /* Low Address B4000-B7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelB000h, 0x4000)); break; case 0xB800: /* Low Address B8000-BBFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelB000h, 0x8000)); break; case 0xBC00: /* Low Address BC000-BFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelB000h, 0xc000)); break; case 0xC000: /* Low Address C0000-C3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelC000h, 0x0000)); break; case 0xC400: /* Low Address C4000-C7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelC000h, 0x4000)); break; case 0xC800: /* Low Address C8000-CBFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelC000h, 0x8000)); break; case 0xCC00: /* Low Address CC000-CFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelC000h, 0xc000)); break; case 0xD000: /* Low Address D0000-D3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelD000h, 0)); break; case 0xD400: /* Low Address D4000-D7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelD000h, 0x4000)); break; case 0xD800: /* Low Address D8000-DBFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelD000h, 0x8000)); break; case 0xDC00: /* Low Address DC000-DFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelD000h, 0xc000)); break; case 0xE000: /* Low Address E0000-E3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelE000h, 0x0000)); break; case 0xE400: /* Low Address E4000-E7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelE000h, 0x4000)); break; case 0xE800: /* Low Address E8000-EBFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelE000h, 0x8000)); break; case 0xEC00: /* Low Address EC000-EFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelE000h, 0xC000)); break; case 0xF000: /* Low Address F0000-F3FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelF000h, 0x0000)); break; case 0xF400: /* Low Address F4000-F7FFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelF000h, 0x4000)); break; case 0xF800: /* Low Address F8000-FBFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelF000h, 0x8000)); break; case 0xFC00: /* Low Address FC000-FFFFF (HIAD=0) */ fpCard->MemoryBase = (LPBYTE)(MAKELP(SelF000h, 0xc000)); break; } fpCard->TxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase); fpCard->RxLinkList = (fpIUSCLINKLISTDMA)(fpCard->MemoryBase); return(bReturnValue); #endif } /******************************************************************* DisableR56 Passes: fpCARD - Far pointer to Card Struct Returns: Nothing *******************************************************************/ VOID DisableR56(fpR56_INFO fpCard) { OUT(fpCard->wIOAddress, 0); /* Turn off Memory Window */ //OUT(fpCard->wIOAddress + 1, SEL_IRQ_NONE); /* Turn off IRQ */ } /******************************************************************* WARNING : Everything below this point can be called at interrupt time and should have stack checking turned off. *******************************************************************/ #pragma check_stack(off) /******************************************************************* ChangeR56Page : This routine will write the lower four bits of the page register while preserving the upper four bits. *******************************************************************/ VOID ChangeR56Page(fpR56_INFO fpCard, BYTE bPage) { OUT(fpCard->wIOAddress, (0xf0 & (IN(fpCard->wIOAddress))) | (0x0f & bPage)); } /******************************************************************* IUSCoutb *******************************************************************/ VOID IUSCoutb(fpR56_INFO fpCard, BYTE bReg, BYTE bValue) { BYTE bOldValue; bOldValue = IN(fpCard->wIOAddress); OUT(fpCard->wIOAddress, (bOldValue | MEM_WIN_ON) & ~IUSC_DISABLE); * (LPBYTE)(fpCard->MemoryBase + bReg) = bValue; OUT(fpCard->wIOAddress, bOldValue); } /******************************************************************* IUSCinb *******************************************************************/ BYTE IUSCinb(fpR56_INFO fpCard, BYTE bReg) { BYTE bOldValue; BYTE bValue; bOldValue = IN(fpCard->wIOAddress); OUT(fpCard->wIOAddress, (bOldValue | MEM_WIN_ON) & ~IUSC_DISABLE); bValue = * (LPBYTE)(fpCard->MemoryBase + bReg); OUT(fpCard->wIOAddress, bOldValue); return(bValue); } /******************************************************************* IUSCout *******************************************************************/ VOID IUSCout(fpR56_INFO fpCard, BYTE bReg, WORD wValue) { BYTE bOldValue; bOldValue = IN(fpCard->wIOAddress); OUT(fpCard->wIOAddress, (bOldValue | MEM_WIN_ON) & ~IUSC_DISABLE); IO_DELAY; * (LPWORD)(fpCard->MemoryBase + bReg) = wValue; OUT(fpCard->wIOAddress, bOldValue); IO_DELAY; } /******************************************************************* IUSCin *******************************************************************/ WORD IUSCin(fpR56_INFO fpCard, BYTE bReg) { BYTE bOldValue; WORD wValue; bOldValue = IN(fpCard->wIOAddress); OUT(fpCard->wIOAddress, (bOldValue | MEM_WIN_ON) & ~IUSC_DISABLE); IO_DELAY; wValue = * (LPWORD)(fpCard->MemoryBase + bReg); IO_DELAY; OUT(fpCard->wIOAddress, bOldValue); return(wValue); } #pragma check_stack()