1*b00ab754SHans Petter Selasky /* 2*b00ab754SHans Petter Selasky * File.........: pktdrvr.c 3*b00ab754SHans Petter Selasky * 4*b00ab754SHans Petter Selasky * Responsible..: Gisle Vanem, giva@bgnett.no 5*b00ab754SHans Petter Selasky * 6*b00ab754SHans Petter Selasky * Created......: 26.Sept 1995 7*b00ab754SHans Petter Selasky * 8*b00ab754SHans Petter Selasky * Description..: Packet-driver interface for 16/32-bit C : 9*b00ab754SHans Petter Selasky * Borland C/C++ 3.0+ small/large model 10*b00ab754SHans Petter Selasky * Watcom C/C++ 11+, DOS4GW flat model 11*b00ab754SHans Petter Selasky * Metaware HighC 3.1+ and PharLap 386|DosX 12*b00ab754SHans Petter Selasky * GNU C/C++ 2.7+ and djgpp 2.x extender 13*b00ab754SHans Petter Selasky * 14*b00ab754SHans Petter Selasky * References...: PC/TCP Packet driver Specification. rev 1.09 15*b00ab754SHans Petter Selasky * FTP Software Inc. 16*b00ab754SHans Petter Selasky * 17*b00ab754SHans Petter Selasky */ 18*b00ab754SHans Petter Selasky 19*b00ab754SHans Petter Selasky #include <stdio.h> 20*b00ab754SHans Petter Selasky #include <stdlib.h> 21*b00ab754SHans Petter Selasky #include <string.h> 22*b00ab754SHans Petter Selasky #include <dos.h> 23*b00ab754SHans Petter Selasky 24*b00ab754SHans Petter Selasky #include "pcap-dos.h" 25*b00ab754SHans Petter Selasky #include "pcap-int.h" 26*b00ab754SHans Petter Selasky #include "msdos/pktdrvr.h" 27*b00ab754SHans Petter Selasky 28*b00ab754SHans Petter Selasky #if (DOSX) 29*b00ab754SHans Petter Selasky #define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */ 30*b00ab754SHans Petter Selasky #else 31*b00ab754SHans Petter Selasky #define NUM_RX_BUF 10 32*b00ab754SHans Petter Selasky #endif 33*b00ab754SHans Petter Selasky 34*b00ab754SHans Petter Selasky #define DIM(x) (sizeof((x)) / sizeof(x[0])) 35*b00ab754SHans Petter Selasky #define PUTS(s) do { \ 36*b00ab754SHans Petter Selasky if (!pktInfo.quiet) \ 37*b00ab754SHans Petter Selasky pktInfo.error ? \ 38*b00ab754SHans Petter Selasky printf ("%s: %s\n", s, pktInfo.error) : \ 39*b00ab754SHans Petter Selasky printf ("%s\n", pktInfo.error = s); \ 40*b00ab754SHans Petter Selasky } while (0) 41*b00ab754SHans Petter Selasky 42*b00ab754SHans Petter Selasky #if defined(__HIGHC__) 43*b00ab754SHans Petter Selasky extern UINT _mwenv; 44*b00ab754SHans Petter Selasky 45*b00ab754SHans Petter Selasky #elif defined(__DJGPP__) 46*b00ab754SHans Petter Selasky #include <stddef.h> 47*b00ab754SHans Petter Selasky #include <dpmi.h> 48*b00ab754SHans Petter Selasky #include <go32.h> 49*b00ab754SHans Petter Selasky #include <pc.h> 50*b00ab754SHans Petter Selasky #include <sys/farptr.h> 51*b00ab754SHans Petter Selasky 52*b00ab754SHans Petter Selasky #elif defined(__WATCOMC__) 53*b00ab754SHans Petter Selasky #include <i86.h> 54*b00ab754SHans Petter Selasky #include <stddef.h> 55*b00ab754SHans Petter Selasky extern char _Extender; 56*b00ab754SHans Petter Selasky 57*b00ab754SHans Petter Selasky #else 58*b00ab754SHans Petter Selasky extern void far PktReceiver (void); 59*b00ab754SHans Petter Selasky #endif 60*b00ab754SHans Petter Selasky 61*b00ab754SHans Petter Selasky 62*b00ab754SHans Petter Selasky #if (DOSX & (DJGPP|DOS4GW)) 63*b00ab754SHans Petter Selasky #include <sys/pack_on.h> 64*b00ab754SHans Petter Selasky 65*b00ab754SHans Petter Selasky struct DPMI_regs { 66*b00ab754SHans Petter Selasky DWORD r_di; 67*b00ab754SHans Petter Selasky DWORD r_si; 68*b00ab754SHans Petter Selasky DWORD r_bp; 69*b00ab754SHans Petter Selasky DWORD reserved; 70*b00ab754SHans Petter Selasky DWORD r_bx; 71*b00ab754SHans Petter Selasky DWORD r_dx; 72*b00ab754SHans Petter Selasky DWORD r_cx; 73*b00ab754SHans Petter Selasky DWORD r_ax; 74*b00ab754SHans Petter Selasky WORD r_flags; 75*b00ab754SHans Petter Selasky WORD r_es, r_ds, r_fs, r_gs; 76*b00ab754SHans Petter Selasky WORD r_ip, r_cs, r_sp, r_ss; 77*b00ab754SHans Petter Selasky }; 78*b00ab754SHans Petter Selasky 79*b00ab754SHans Petter Selasky /* Data located in a real-mode segment. This becomes far at runtime 80*b00ab754SHans Petter Selasky */ 81*b00ab754SHans Petter Selasky typedef struct { /* must match data/code in pkt_rx1.s */ 82*b00ab754SHans Petter Selasky WORD _rxOutOfs; 83*b00ab754SHans Petter Selasky WORD _rxInOfs; 84*b00ab754SHans Petter Selasky DWORD _pktDrop; 85*b00ab754SHans Petter Selasky BYTE _pktTemp [20]; 86*b00ab754SHans Petter Selasky TX_ELEMENT _pktTxBuf[1]; 87*b00ab754SHans Petter Selasky RX_ELEMENT _pktRxBuf[NUM_RX_BUF]; 88*b00ab754SHans Petter Selasky WORD _dummy[2]; /* screenSeg,newInOffset */ 89*b00ab754SHans Petter Selasky BYTE _fanChars[4]; 90*b00ab754SHans Petter Selasky WORD _fanIndex; 91*b00ab754SHans Petter Selasky BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */ 92*b00ab754SHans Petter Selasky } PktRealStub; 93*b00ab754SHans Petter Selasky #include <sys/pack_off.h> 94*b00ab754SHans Petter Selasky 95*b00ab754SHans Petter Selasky static BYTE real_stub_array [] = { 96*b00ab754SHans Petter Selasky #include "pkt_stub.inc" /* generated opcode array */ 97*b00ab754SHans Petter Selasky }; 98*b00ab754SHans Petter Selasky 99*b00ab754SHans Petter Selasky #define rxOutOfs offsetof (PktRealStub,_rxOutOfs) 100*b00ab754SHans Petter Selasky #define rxInOfs offsetof (PktRealStub,_rxInOfs) 101*b00ab754SHans Petter Selasky #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip]) 102*b00ab754SHans Petter Selasky #define pktDrop offsetof (PktRealStub,_pktDrop) 103*b00ab754SHans Petter Selasky #define pktTemp offsetof (PktRealStub,_pktTemp) 104*b00ab754SHans Petter Selasky #define pktTxBuf offsetof (PktRealStub,_pktTxBuf) 105*b00ab754SHans Petter Selasky #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0]) 106*b00ab754SHans Petter Selasky #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1]) 107*b00ab754SHans Petter Selasky 108*b00ab754SHans Petter Selasky #else 109*b00ab754SHans Petter Selasky extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */ 110*b00ab754SHans Petter Selasky extern WORD rxInOfs; 111*b00ab754SHans Petter Selasky extern DWORD pktDrop; /* # packets dropped in PktReceiver() */ 112*b00ab754SHans Petter Selasky extern BYTE pktRxEnd; /* marks the end of r-mode code/data */ 113*b00ab754SHans Petter Selasky 114*b00ab754SHans Petter Selasky extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */ 115*b00ab754SHans Petter Selasky extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */ 116*b00ab754SHans Petter Selasky extern char pktTemp[20]; /* PktDrvr temp area */ 117*b00ab754SHans Petter Selasky 118*b00ab754SHans Petter Selasky #define FIRST_RX_BUF (WORD) &pktRxBuf [0] 119*b00ab754SHans Petter Selasky #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1] 120*b00ab754SHans Petter Selasky #endif 121*b00ab754SHans Petter Selasky 122*b00ab754SHans Petter Selasky 123*b00ab754SHans Petter Selasky #ifdef __BORLANDC__ /* Use Borland's inline functions */ 124*b00ab754SHans Petter Selasky #define memcpy __memcpy__ 125*b00ab754SHans Petter Selasky #define memcmp __memcmp__ 126*b00ab754SHans Petter Selasky #define memset __memset__ 127*b00ab754SHans Petter Selasky #endif 128*b00ab754SHans Petter Selasky 129*b00ab754SHans Petter Selasky 130*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 131*b00ab754SHans Petter Selasky extern void PktReceiver (void); /* in pkt_rx0.asm */ 132*b00ab754SHans Petter Selasky static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*); 133*b00ab754SHans Petter Selasky 134*b00ab754SHans Petter Selasky #undef FP_SEG 135*b00ab754SHans Petter Selasky #undef FP_OFF 136*b00ab754SHans Petter Selasky #define FP_OFF(x) ((WORD)(x)) 137*b00ab754SHans Petter Selasky #define FP_SEG(x) ((WORD)(realBase >> 16)) 138*b00ab754SHans Petter Selasky #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o)) 139*b00ab754SHans Petter Selasky #define r_ax eax 140*b00ab754SHans Petter Selasky #define r_bx ebx 141*b00ab754SHans Petter Selasky #define r_dx edx 142*b00ab754SHans Petter Selasky #define r_cx ecx 143*b00ab754SHans Petter Selasky #define r_si esi 144*b00ab754SHans Petter Selasky #define r_di edi 145*b00ab754SHans Petter Selasky #define r_ds ds 146*b00ab754SHans Petter Selasky #define r_es es 147*b00ab754SHans Petter Selasky LOCAL FARPTR protBase; 148*b00ab754SHans Petter Selasky LOCAL REALPTR realBase; 149*b00ab754SHans Petter Selasky LOCAL WORD realSeg; /* DOS para-address of allocated area */ 150*b00ab754SHans Petter Selasky LOCAL SWI_REGS reg; 151*b00ab754SHans Petter Selasky 152*b00ab754SHans Petter Selasky static WORD _far *rxOutOfsFp, *rxInOfsFp; 153*b00ab754SHans Petter Selasky 154*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 155*b00ab754SHans Petter Selasky static _go32_dpmi_seginfo rm_mem; 156*b00ab754SHans Petter Selasky static __dpmi_regs reg; 157*b00ab754SHans Petter Selasky static DWORD realBase; 158*b00ab754SHans Petter Selasky static int para_skip = 0; 159*b00ab754SHans Petter Selasky 160*b00ab754SHans Petter Selasky #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o)) 161*b00ab754SHans Petter Selasky #define r_ax x.ax 162*b00ab754SHans Petter Selasky #define r_bx x.bx 163*b00ab754SHans Petter Selasky #define r_dx x.dx 164*b00ab754SHans Petter Selasky #define r_cx x.cx 165*b00ab754SHans Petter Selasky #define r_si x.si 166*b00ab754SHans Petter Selasky #define r_di x.di 167*b00ab754SHans Petter Selasky #define r_ds x.ds 168*b00ab754SHans Petter Selasky #define r_es x.es 169*b00ab754SHans Petter Selasky 170*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 171*b00ab754SHans Petter Selasky LOCAL struct DPMI_regs reg; 172*b00ab754SHans Petter Selasky LOCAL WORD rm_base_seg, rm_base_sel; 173*b00ab754SHans Petter Selasky LOCAL DWORD realBase; 174*b00ab754SHans Petter Selasky LOCAL int para_skip = 0; 175*b00ab754SHans Petter Selasky 176*b00ab754SHans Petter Selasky LOCAL DWORD dpmi_get_real_vector (int intr); 177*b00ab754SHans Petter Selasky LOCAL WORD dpmi_real_malloc (int size, WORD *selector); 178*b00ab754SHans Petter Selasky LOCAL void dpmi_real_free (WORD selector); 179*b00ab754SHans Petter Selasky #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o)) 180*b00ab754SHans Petter Selasky 181*b00ab754SHans Petter Selasky #else /* real-mode Borland etc. */ 182*b00ab754SHans Petter Selasky static struct { 183*b00ab754SHans Petter Selasky WORD r_ax, r_bx, r_cx, r_dx, r_bp; 184*b00ab754SHans Petter Selasky WORD r_si, r_di, r_ds, r_es, r_flags; 185*b00ab754SHans Petter Selasky } reg; 186*b00ab754SHans Petter Selasky #endif 187*b00ab754SHans Petter Selasky 188*b00ab754SHans Petter Selasky #ifdef __HIGHC__ 189*b00ab754SHans Petter Selasky #pragma Alias (pktDrop, "_pktDrop") 190*b00ab754SHans Petter Selasky #pragma Alias (pktRxBuf, "_pktRxBuf") 191*b00ab754SHans Petter Selasky #pragma Alias (pktTxBuf, "_pktTxBuf") 192*b00ab754SHans Petter Selasky #pragma Alias (pktTemp, "_pktTemp") 193*b00ab754SHans Petter Selasky #pragma Alias (rxOutOfs, "_rxOutOfs") 194*b00ab754SHans Petter Selasky #pragma Alias (rxInOfs, "_rxInOfs") 195*b00ab754SHans Petter Selasky #pragma Alias (pktRxEnd, "_pktRxEnd") 196*b00ab754SHans Petter Selasky #pragma Alias (PktReceiver,"_PktReceiver") 197*b00ab754SHans Petter Selasky #endif 198*b00ab754SHans Petter Selasky 199*b00ab754SHans Petter Selasky 200*b00ab754SHans Petter Selasky PUBLIC PKT_STAT pktStat; /* statistics for packets */ 201*b00ab754SHans Petter Selasky PUBLIC PKT_INFO pktInfo; /* packet-driver information */ 202*b00ab754SHans Petter Selasky 203*b00ab754SHans Petter Selasky PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT; 204*b00ab754SHans Petter Selasky PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 }; 205*b00ab754SHans Petter Selasky PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 }; 206*b00ab754SHans Petter Selasky 207*b00ab754SHans Petter Selasky LOCAL struct { /* internal statistics */ 208*b00ab754SHans Petter Selasky DWORD tooSmall; /* size < ETH_MIN */ 209*b00ab754SHans Petter Selasky DWORD tooLarge; /* size > ETH_MAX */ 210*b00ab754SHans Petter Selasky DWORD badSync; /* count_1 != count_2 */ 211*b00ab754SHans Petter Selasky DWORD wrongHandle; /* upcall to wrong handle */ 212*b00ab754SHans Petter Selasky } intStat; 213*b00ab754SHans Petter Selasky 214*b00ab754SHans Petter Selasky /***************************************************************************/ 215*b00ab754SHans Petter Selasky 216*b00ab754SHans Petter Selasky PUBLIC const char *PktGetErrorStr (int errNum) 217*b00ab754SHans Petter Selasky { 218*b00ab754SHans Petter Selasky static const char *errStr[] = { 219*b00ab754SHans Petter Selasky "", 220*b00ab754SHans Petter Selasky "Invalid handle number", 221*b00ab754SHans Petter Selasky "No interfaces of specified class found", 222*b00ab754SHans Petter Selasky "No interfaces of specified type found", 223*b00ab754SHans Petter Selasky "No interfaces of specified number found", 224*b00ab754SHans Petter Selasky "Bad packet type specified", 225*b00ab754SHans Petter Selasky "Interface does not support multicast", 226*b00ab754SHans Petter Selasky "Packet driver cannot terminate", 227*b00ab754SHans Petter Selasky "Invalid receiver mode specified", 228*b00ab754SHans Petter Selasky "Insufficient memory space", 229*b00ab754SHans Petter Selasky "Type previously accessed, and not released", 230*b00ab754SHans Petter Selasky "Command out of range, or not implemented", 231*b00ab754SHans Petter Selasky "Cannot send packet (usually hardware error)", 232*b00ab754SHans Petter Selasky "Cannot change hardware address ( > 1 handle open)", 233*b00ab754SHans Petter Selasky "Hardware address has bad length or format", 234*b00ab754SHans Petter Selasky "Cannot reset interface (more than 1 handle open)", 235*b00ab754SHans Petter Selasky "Bad Check-sum", 236*b00ab754SHans Petter Selasky "Bad size", 237*b00ab754SHans Petter Selasky "Bad sync" , 238*b00ab754SHans Petter Selasky "Source hit" 239*b00ab754SHans Petter Selasky }; 240*b00ab754SHans Petter Selasky 241*b00ab754SHans Petter Selasky if (errNum < 0 || errNum >= DIM(errStr)) 242*b00ab754SHans Petter Selasky return ("Unknown driver error."); 243*b00ab754SHans Petter Selasky return (errStr [errNum]); 244*b00ab754SHans Petter Selasky } 245*b00ab754SHans Petter Selasky 246*b00ab754SHans Petter Selasky /**************************************************************************/ 247*b00ab754SHans Petter Selasky 248*b00ab754SHans Petter Selasky PUBLIC const char *PktGetClassName (WORD class) 249*b00ab754SHans Petter Selasky { 250*b00ab754SHans Petter Selasky switch (class) 251*b00ab754SHans Petter Selasky { 252*b00ab754SHans Petter Selasky case PD_ETHER: 253*b00ab754SHans Petter Selasky return ("DIX-Ether"); 254*b00ab754SHans Petter Selasky case PD_PRONET10: 255*b00ab754SHans Petter Selasky return ("ProNET-10"); 256*b00ab754SHans Petter Selasky case PD_IEEE8025: 257*b00ab754SHans Petter Selasky return ("IEEE 802.5"); 258*b00ab754SHans Petter Selasky case PD_OMNINET: 259*b00ab754SHans Petter Selasky return ("OmniNet"); 260*b00ab754SHans Petter Selasky case PD_APPLETALK: 261*b00ab754SHans Petter Selasky return ("AppleTalk"); 262*b00ab754SHans Petter Selasky case PD_SLIP: 263*b00ab754SHans Petter Selasky return ("SLIP"); 264*b00ab754SHans Petter Selasky case PD_STARTLAN: 265*b00ab754SHans Petter Selasky return ("StartLAN"); 266*b00ab754SHans Petter Selasky case PD_ARCNET: 267*b00ab754SHans Petter Selasky return ("ArcNet"); 268*b00ab754SHans Petter Selasky case PD_AX25: 269*b00ab754SHans Petter Selasky return ("AX.25"); 270*b00ab754SHans Petter Selasky case PD_KISS: 271*b00ab754SHans Petter Selasky return ("KISS"); 272*b00ab754SHans Petter Selasky case PD_IEEE8023_2: 273*b00ab754SHans Petter Selasky return ("IEEE 802.3 w/802.2 hdr"); 274*b00ab754SHans Petter Selasky case PD_FDDI8022: 275*b00ab754SHans Petter Selasky return ("FDDI w/802.2 hdr"); 276*b00ab754SHans Petter Selasky case PD_X25: 277*b00ab754SHans Petter Selasky return ("X.25"); 278*b00ab754SHans Petter Selasky case PD_LANstar: 279*b00ab754SHans Petter Selasky return ("LANstar"); 280*b00ab754SHans Petter Selasky case PD_PPP: 281*b00ab754SHans Petter Selasky return ("PPP"); 282*b00ab754SHans Petter Selasky default: 283*b00ab754SHans Petter Selasky return ("unknown"); 284*b00ab754SHans Petter Selasky } 285*b00ab754SHans Petter Selasky } 286*b00ab754SHans Petter Selasky 287*b00ab754SHans Petter Selasky /**************************************************************************/ 288*b00ab754SHans Petter Selasky 289*b00ab754SHans Petter Selasky PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode) 290*b00ab754SHans Petter Selasky { 291*b00ab754SHans Petter Selasky static const char *modeStr [] = { 292*b00ab754SHans Petter Selasky "Receiver turned off", 293*b00ab754SHans Petter Selasky "Receive only directly addressed packets", 294*b00ab754SHans Petter Selasky "Receive direct & broadcast packets", 295*b00ab754SHans Petter Selasky "Receive direct,broadcast and limited multicast packets", 296*b00ab754SHans Petter Selasky "Receive direct,broadcast and all multicast packets", 297*b00ab754SHans Petter Selasky "Receive all packets (promiscuouos mode)" 298*b00ab754SHans Petter Selasky }; 299*b00ab754SHans Petter Selasky 300*b00ab754SHans Petter Selasky if (mode > DIM(modeStr)) 301*b00ab754SHans Petter Selasky return ("??"); 302*b00ab754SHans Petter Selasky return (modeStr [mode-1]); 303*b00ab754SHans Petter Selasky } 304*b00ab754SHans Petter Selasky 305*b00ab754SHans Petter Selasky /**************************************************************************/ 306*b00ab754SHans Petter Selasky 307*b00ab754SHans Petter Selasky LOCAL __inline BOOL PktInterrupt (void) 308*b00ab754SHans Petter Selasky { 309*b00ab754SHans Petter Selasky BOOL okay; 310*b00ab754SHans Petter Selasky 311*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 312*b00ab754SHans Petter Selasky _dx_real_int ((UINT)pktInfo.intr, ®); 313*b00ab754SHans Petter Selasky okay = ((reg.flags & 1) == 0); /* OK if carry clear */ 314*b00ab754SHans Petter Selasky 315*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 316*b00ab754SHans Petter Selasky __dpmi_int ((int)pktInfo.intr, ®); 317*b00ab754SHans Petter Selasky okay = ((reg.x.flags & 1) == 0); 318*b00ab754SHans Petter Selasky 319*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 320*b00ab754SHans Petter Selasky union REGS r; 321*b00ab754SHans Petter Selasky struct SREGS s; 322*b00ab754SHans Petter Selasky 323*b00ab754SHans Petter Selasky memset (&r, 0, sizeof(r)); 324*b00ab754SHans Petter Selasky segread (&s); 325*b00ab754SHans Petter Selasky r.w.ax = 0x300; 326*b00ab754SHans Petter Selasky r.x.ebx = pktInfo.intr; 327*b00ab754SHans Petter Selasky r.w.cx = 0; 328*b00ab754SHans Petter Selasky s.es = FP_SEG (®); 329*b00ab754SHans Petter Selasky r.x.edi = FP_OFF (®); 330*b00ab754SHans Petter Selasky reg.r_flags = 0; 331*b00ab754SHans Petter Selasky reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */ 332*b00ab754SHans Petter Selasky 333*b00ab754SHans Petter Selasky int386x (0x31, &r, &r, &s); 334*b00ab754SHans Petter Selasky okay = (!r.w.cflag); 335*b00ab754SHans Petter Selasky 336*b00ab754SHans Petter Selasky #else 337*b00ab754SHans Petter Selasky reg.r_flags = 0; 338*b00ab754SHans Petter Selasky intr (pktInfo.intr, (struct REGPACK*)®); 339*b00ab754SHans Petter Selasky okay = ((reg.r_flags & 1) == 0); 340*b00ab754SHans Petter Selasky #endif 341*b00ab754SHans Petter Selasky 342*b00ab754SHans Petter Selasky if (okay) 343*b00ab754SHans Petter Selasky pktInfo.error = NULL; 344*b00ab754SHans Petter Selasky else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8); 345*b00ab754SHans Petter Selasky return (okay); 346*b00ab754SHans Petter Selasky } 347*b00ab754SHans Petter Selasky 348*b00ab754SHans Petter Selasky /**************************************************************************/ 349*b00ab754SHans Petter Selasky 350*b00ab754SHans Petter Selasky /* 351*b00ab754SHans Petter Selasky * Search for packet driver at interrupt 60h through 80h. If ASCIIZ 352*b00ab754SHans Petter Selasky * string "PKT DRVR" found at offset 3 in the interrupt handler, return 353*b00ab754SHans Petter Selasky * interrupt number, else return zero in pktInfo.intr 354*b00ab754SHans Petter Selasky */ 355*b00ab754SHans Petter Selasky PUBLIC BOOL PktSearchDriver (void) 356*b00ab754SHans Petter Selasky { 357*b00ab754SHans Petter Selasky BYTE intr = 0x20; 358*b00ab754SHans Petter Selasky BOOL found = FALSE; 359*b00ab754SHans Petter Selasky 360*b00ab754SHans Petter Selasky while (!found && intr < 0xFF) 361*b00ab754SHans Petter Selasky { 362*b00ab754SHans Petter Selasky static char str[12]; /* 3 + strlen("PKT DRVR") */ 363*b00ab754SHans Petter Selasky static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */ 364*b00ab754SHans Petter Selasky DWORD rp; /* in interrupt routine */ 365*b00ab754SHans Petter Selasky 366*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 367*b00ab754SHans Petter Selasky _dx_rmiv_get (intr, &rp); 368*b00ab754SHans Petter Selasky ReadRealMem (&str, (REALPTR)rp, sizeof(str)); 369*b00ab754SHans Petter Selasky 370*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 371*b00ab754SHans Petter Selasky __dpmi_raddr realAdr; 372*b00ab754SHans Petter Selasky __dpmi_get_real_mode_interrupt_vector (intr, &realAdr); 373*b00ab754SHans Petter Selasky rp = (realAdr.segment << 4) + realAdr.offset16; 374*b00ab754SHans Petter Selasky dosmemget (rp, sizeof(str), &str); 375*b00ab754SHans Petter Selasky 376*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 377*b00ab754SHans Petter Selasky rp = dpmi_get_real_vector (intr); 378*b00ab754SHans Petter Selasky memcpy (&str, (void*)rp, sizeof(str)); 379*b00ab754SHans Petter Selasky 380*b00ab754SHans Petter Selasky #else 381*b00ab754SHans Petter Selasky _fmemcpy (&str, getvect(intr), sizeof(str)); 382*b00ab754SHans Petter Selasky #endif 383*b00ab754SHans Petter Selasky 384*b00ab754SHans Petter Selasky found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0; 385*b00ab754SHans Petter Selasky intr++; 386*b00ab754SHans Petter Selasky } 387*b00ab754SHans Petter Selasky pktInfo.intr = (found ? intr-1 : 0); 388*b00ab754SHans Petter Selasky return (found); 389*b00ab754SHans Petter Selasky } 390*b00ab754SHans Petter Selasky 391*b00ab754SHans Petter Selasky 392*b00ab754SHans Petter Selasky /**************************************************************************/ 393*b00ab754SHans Petter Selasky 394*b00ab754SHans Petter Selasky static BOOL PktSetAccess (void) 395*b00ab754SHans Petter Selasky { 396*b00ab754SHans Petter Selasky reg.r_ax = 0x0200 + pktInfo.class; 397*b00ab754SHans Petter Selasky reg.r_bx = 0xFFFF; 398*b00ab754SHans Petter Selasky reg.r_dx = 0; 399*b00ab754SHans Petter Selasky reg.r_cx = 0; 400*b00ab754SHans Petter Selasky 401*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 402*b00ab754SHans Petter Selasky reg.ds = 0; 403*b00ab754SHans Petter Selasky reg.esi = 0; 404*b00ab754SHans Petter Selasky reg.es = RP_SEG (realBase); 405*b00ab754SHans Petter Selasky reg.edi = (WORD) &PktReceiver; 406*b00ab754SHans Petter Selasky 407*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 408*b00ab754SHans Petter Selasky reg.x.ds = 0; 409*b00ab754SHans Petter Selasky reg.x.si = 0; 410*b00ab754SHans Petter Selasky reg.x.es = rm_mem.rm_segment; 411*b00ab754SHans Petter Selasky reg.x.di = PktReceiver; 412*b00ab754SHans Petter Selasky 413*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 414*b00ab754SHans Petter Selasky reg.r_ds = 0; 415*b00ab754SHans Petter Selasky reg.r_si = 0; 416*b00ab754SHans Petter Selasky reg.r_es = rm_base_seg; 417*b00ab754SHans Petter Selasky reg.r_di = PktReceiver; 418*b00ab754SHans Petter Selasky 419*b00ab754SHans Petter Selasky #else 420*b00ab754SHans Petter Selasky reg.r_ds = 0; 421*b00ab754SHans Petter Selasky reg.r_si = 0; 422*b00ab754SHans Petter Selasky reg.r_es = FP_SEG (&PktReceiver); 423*b00ab754SHans Petter Selasky reg.r_di = FP_OFF (&PktReceiver); 424*b00ab754SHans Petter Selasky #endif 425*b00ab754SHans Petter Selasky 426*b00ab754SHans Petter Selasky if (!PktInterrupt()) 427*b00ab754SHans Petter Selasky return (FALSE); 428*b00ab754SHans Petter Selasky 429*b00ab754SHans Petter Selasky pktInfo.handle = reg.r_ax; 430*b00ab754SHans Petter Selasky return (TRUE); 431*b00ab754SHans Petter Selasky } 432*b00ab754SHans Petter Selasky 433*b00ab754SHans Petter Selasky /**************************************************************************/ 434*b00ab754SHans Petter Selasky 435*b00ab754SHans Petter Selasky PUBLIC BOOL PktReleaseHandle (WORD handle) 436*b00ab754SHans Petter Selasky { 437*b00ab754SHans Petter Selasky reg.r_ax = 0x0300; 438*b00ab754SHans Petter Selasky reg.r_bx = handle; 439*b00ab754SHans Petter Selasky return PktInterrupt(); 440*b00ab754SHans Petter Selasky } 441*b00ab754SHans Petter Selasky 442*b00ab754SHans Petter Selasky /**************************************************************************/ 443*b00ab754SHans Petter Selasky 444*b00ab754SHans Petter Selasky PUBLIC BOOL PktTransmit (const void *eth, int len) 445*b00ab754SHans Petter Selasky { 446*b00ab754SHans Petter Selasky if (len > ETH_MTU) 447*b00ab754SHans Petter Selasky return (FALSE); 448*b00ab754SHans Petter Selasky 449*b00ab754SHans Petter Selasky reg.r_ax = 0x0400; /* Function 4, send pkt */ 450*b00ab754SHans Petter Selasky reg.r_cx = len; /* total size of frame */ 451*b00ab754SHans Petter Selasky 452*b00ab754SHans Petter Selasky #if (DOSX & DJGPP) 453*b00ab754SHans Petter Selasky dosmemput (eth, len, realBase+pktTxBuf); 454*b00ab754SHans Petter Selasky reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */ 455*b00ab754SHans Petter Selasky reg.x.si = pktTxBuf; /* DOS offset to buffer */ 456*b00ab754SHans Petter Selasky 457*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 458*b00ab754SHans Petter Selasky memcpy ((void*)(realBase+pktTxBuf), eth, len); 459*b00ab754SHans Petter Selasky reg.r_ds = rm_base_seg; 460*b00ab754SHans Petter Selasky reg.r_si = pktTxBuf; 461*b00ab754SHans Petter Selasky 462*b00ab754SHans Petter Selasky #elif (DOSX & PHARLAP) 463*b00ab754SHans Petter Selasky memcpy (&pktTxBuf, eth, len); 464*b00ab754SHans Petter Selasky reg.r_ds = FP_SEG (&pktTxBuf); 465*b00ab754SHans Petter Selasky reg.r_si = FP_OFF (&pktTxBuf); 466*b00ab754SHans Petter Selasky 467*b00ab754SHans Petter Selasky #else 468*b00ab754SHans Petter Selasky reg.r_ds = FP_SEG (eth); 469*b00ab754SHans Petter Selasky reg.r_si = FP_OFF (eth); 470*b00ab754SHans Petter Selasky #endif 471*b00ab754SHans Petter Selasky 472*b00ab754SHans Petter Selasky return PktInterrupt(); 473*b00ab754SHans Petter Selasky } 474*b00ab754SHans Petter Selasky 475*b00ab754SHans Petter Selasky /**************************************************************************/ 476*b00ab754SHans Petter Selasky 477*b00ab754SHans Petter Selasky #if (DOSX & (DJGPP|DOS4GW)) 478*b00ab754SHans Petter Selasky LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx) 479*b00ab754SHans Petter Selasky #else 480*b00ab754SHans Petter Selasky LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx) 481*b00ab754SHans Petter Selasky #endif 482*b00ab754SHans Petter Selasky { 483*b00ab754SHans Petter Selasky WORD count_1, count_2; 484*b00ab754SHans Petter Selasky 485*b00ab754SHans Petter Selasky /* 486*b00ab754SHans Petter Selasky * We got an upcall to the same RMCB with wrong handle. 487*b00ab754SHans Petter Selasky * This can happen if we failed to release handle at program exit 488*b00ab754SHans Petter Selasky */ 489*b00ab754SHans Petter Selasky if (rx->handle != pktInfo.handle) 490*b00ab754SHans Petter Selasky { 491*b00ab754SHans Petter Selasky pktInfo.error = "Wrong handle"; 492*b00ab754SHans Petter Selasky intStat.wrongHandle++; 493*b00ab754SHans Petter Selasky PktReleaseHandle (rx->handle); 494*b00ab754SHans Petter Selasky return (FALSE); 495*b00ab754SHans Petter Selasky } 496*b00ab754SHans Petter Selasky count_1 = rx->firstCount; 497*b00ab754SHans Petter Selasky count_2 = rx->secondCount; 498*b00ab754SHans Petter Selasky 499*b00ab754SHans Petter Selasky if (count_1 != count_2) 500*b00ab754SHans Petter Selasky { 501*b00ab754SHans Petter Selasky pktInfo.error = "Bad sync"; 502*b00ab754SHans Petter Selasky intStat.badSync++; 503*b00ab754SHans Petter Selasky return (FALSE); 504*b00ab754SHans Petter Selasky } 505*b00ab754SHans Petter Selasky if (count_1 > ETH_MAX) 506*b00ab754SHans Petter Selasky { 507*b00ab754SHans Petter Selasky pktInfo.error = "Large esize"; 508*b00ab754SHans Petter Selasky intStat.tooLarge++; 509*b00ab754SHans Petter Selasky return (FALSE); 510*b00ab754SHans Petter Selasky } 511*b00ab754SHans Petter Selasky #if 0 512*b00ab754SHans Petter Selasky if (count_1 < ETH_MIN) 513*b00ab754SHans Petter Selasky { 514*b00ab754SHans Petter Selasky pktInfo.error = "Small esize"; 515*b00ab754SHans Petter Selasky intStat.tooSmall++; 516*b00ab754SHans Petter Selasky return (FALSE); 517*b00ab754SHans Petter Selasky } 518*b00ab754SHans Petter Selasky #endif 519*b00ab754SHans Petter Selasky return (TRUE); 520*b00ab754SHans Petter Selasky } 521*b00ab754SHans Petter Selasky 522*b00ab754SHans Petter Selasky /**************************************************************************/ 523*b00ab754SHans Petter Selasky 524*b00ab754SHans Petter Selasky PUBLIC BOOL PktTerminHandle (WORD handle) 525*b00ab754SHans Petter Selasky { 526*b00ab754SHans Petter Selasky reg.r_ax = 0x0500; 527*b00ab754SHans Petter Selasky reg.r_bx = handle; 528*b00ab754SHans Petter Selasky return PktInterrupt(); 529*b00ab754SHans Petter Selasky } 530*b00ab754SHans Petter Selasky 531*b00ab754SHans Petter Selasky /**************************************************************************/ 532*b00ab754SHans Petter Selasky 533*b00ab754SHans Petter Selasky PUBLIC BOOL PktResetInterface (WORD handle) 534*b00ab754SHans Petter Selasky { 535*b00ab754SHans Petter Selasky reg.r_ax = 0x0700; 536*b00ab754SHans Petter Selasky reg.r_bx = handle; 537*b00ab754SHans Petter Selasky return PktInterrupt(); 538*b00ab754SHans Petter Selasky } 539*b00ab754SHans Petter Selasky 540*b00ab754SHans Petter Selasky /**************************************************************************/ 541*b00ab754SHans Petter Selasky 542*b00ab754SHans Petter Selasky PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode) 543*b00ab754SHans Petter Selasky { 544*b00ab754SHans Petter Selasky if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP) 545*b00ab754SHans Petter Selasky return (TRUE); 546*b00ab754SHans Petter Selasky 547*b00ab754SHans Petter Selasky reg.r_ax = 0x1400; 548*b00ab754SHans Petter Selasky reg.r_bx = pktInfo.handle; 549*b00ab754SHans Petter Selasky reg.r_cx = (WORD)mode; 550*b00ab754SHans Petter Selasky 551*b00ab754SHans Petter Selasky if (!PktInterrupt()) 552*b00ab754SHans Petter Selasky return (FALSE); 553*b00ab754SHans Petter Selasky 554*b00ab754SHans Petter Selasky receiveMode = mode; 555*b00ab754SHans Petter Selasky return (TRUE); 556*b00ab754SHans Petter Selasky } 557*b00ab754SHans Petter Selasky 558*b00ab754SHans Petter Selasky /**************************************************************************/ 559*b00ab754SHans Petter Selasky 560*b00ab754SHans Petter Selasky PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode) 561*b00ab754SHans Petter Selasky { 562*b00ab754SHans Petter Selasky reg.r_ax = 0x1500; 563*b00ab754SHans Petter Selasky reg.r_bx = pktInfo.handle; 564*b00ab754SHans Petter Selasky 565*b00ab754SHans Petter Selasky if (!PktInterrupt()) 566*b00ab754SHans Petter Selasky return (FALSE); 567*b00ab754SHans Petter Selasky 568*b00ab754SHans Petter Selasky *mode = reg.r_ax; 569*b00ab754SHans Petter Selasky return (TRUE); 570*b00ab754SHans Petter Selasky } 571*b00ab754SHans Petter Selasky 572*b00ab754SHans Petter Selasky /**************************************************************************/ 573*b00ab754SHans Petter Selasky 574*b00ab754SHans Petter Selasky static PKT_STAT initialStat; /* statistics at startup */ 575*b00ab754SHans Petter Selasky static BOOL resetStat = FALSE; /* statistics reset ? */ 576*b00ab754SHans Petter Selasky 577*b00ab754SHans Petter Selasky PUBLIC BOOL PktGetStatistics (WORD handle) 578*b00ab754SHans Petter Selasky { 579*b00ab754SHans Petter Selasky reg.r_ax = 0x1800; 580*b00ab754SHans Petter Selasky reg.r_bx = handle; 581*b00ab754SHans Petter Selasky 582*b00ab754SHans Petter Selasky if (!PktInterrupt()) 583*b00ab754SHans Petter Selasky return (FALSE); 584*b00ab754SHans Petter Selasky 585*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 586*b00ab754SHans Petter Selasky ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat)); 587*b00ab754SHans Petter Selasky 588*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 589*b00ab754SHans Petter Selasky dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat); 590*b00ab754SHans Petter Selasky 591*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 592*b00ab754SHans Petter Selasky memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat)); 593*b00ab754SHans Petter Selasky 594*b00ab754SHans Petter Selasky #else 595*b00ab754SHans Petter Selasky _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat)); 596*b00ab754SHans Petter Selasky #endif 597*b00ab754SHans Petter Selasky 598*b00ab754SHans Petter Selasky return (TRUE); 599*b00ab754SHans Petter Selasky } 600*b00ab754SHans Petter Selasky 601*b00ab754SHans Petter Selasky /**************************************************************************/ 602*b00ab754SHans Petter Selasky 603*b00ab754SHans Petter Selasky PUBLIC BOOL PktSessStatistics (WORD handle) 604*b00ab754SHans Petter Selasky { 605*b00ab754SHans Petter Selasky if (!PktGetStatistics(pktInfo.handle)) 606*b00ab754SHans Petter Selasky return (FALSE); 607*b00ab754SHans Petter Selasky 608*b00ab754SHans Petter Selasky if (resetStat) 609*b00ab754SHans Petter Selasky { 610*b00ab754SHans Petter Selasky pktStat.inPackets -= initialStat.inPackets; 611*b00ab754SHans Petter Selasky pktStat.outPackets -= initialStat.outPackets; 612*b00ab754SHans Petter Selasky pktStat.inBytes -= initialStat.inBytes; 613*b00ab754SHans Petter Selasky pktStat.outBytes -= initialStat.outBytes; 614*b00ab754SHans Petter Selasky pktStat.inErrors -= initialStat.inErrors; 615*b00ab754SHans Petter Selasky pktStat.outErrors -= initialStat.outErrors; 616*b00ab754SHans Petter Selasky pktStat.outErrors -= initialStat.outErrors; 617*b00ab754SHans Petter Selasky pktStat.lost -= initialStat.lost; 618*b00ab754SHans Petter Selasky } 619*b00ab754SHans Petter Selasky return (TRUE); 620*b00ab754SHans Petter Selasky } 621*b00ab754SHans Petter Selasky 622*b00ab754SHans Petter Selasky /**************************************************************************/ 623*b00ab754SHans Petter Selasky 624*b00ab754SHans Petter Selasky PUBLIC BOOL PktResetStatistics (WORD handle) 625*b00ab754SHans Petter Selasky { 626*b00ab754SHans Petter Selasky if (!PktGetStatistics(pktInfo.handle)) 627*b00ab754SHans Petter Selasky return (FALSE); 628*b00ab754SHans Petter Selasky 629*b00ab754SHans Petter Selasky memcpy (&initialStat, &pktStat, sizeof(initialStat)); 630*b00ab754SHans Petter Selasky resetStat = TRUE; 631*b00ab754SHans Petter Selasky return (TRUE); 632*b00ab754SHans Petter Selasky } 633*b00ab754SHans Petter Selasky 634*b00ab754SHans Petter Selasky /**************************************************************************/ 635*b00ab754SHans Petter Selasky 636*b00ab754SHans Petter Selasky PUBLIC BOOL PktGetAddress (ETHER *addr) 637*b00ab754SHans Petter Selasky { 638*b00ab754SHans Petter Selasky reg.r_ax = 0x0600; 639*b00ab754SHans Petter Selasky reg.r_bx = pktInfo.handle; 640*b00ab754SHans Petter Selasky reg.r_cx = sizeof (*addr); 641*b00ab754SHans Petter Selasky 642*b00ab754SHans Petter Selasky #if (DOSX & DJGPP) 643*b00ab754SHans Petter Selasky reg.x.es = rm_mem.rm_segment; 644*b00ab754SHans Petter Selasky reg.x.di = pktTemp; 645*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 646*b00ab754SHans Petter Selasky reg.r_es = rm_base_seg; 647*b00ab754SHans Petter Selasky reg.r_di = pktTemp; 648*b00ab754SHans Petter Selasky #else 649*b00ab754SHans Petter Selasky reg.r_es = FP_SEG (&pktTemp); 650*b00ab754SHans Petter Selasky reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */ 651*b00ab754SHans Petter Selasky #endif 652*b00ab754SHans Petter Selasky 653*b00ab754SHans Petter Selasky if (!PktInterrupt()) 654*b00ab754SHans Petter Selasky return (FALSE); 655*b00ab754SHans Petter Selasky 656*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 657*b00ab754SHans Petter Selasky ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr)); 658*b00ab754SHans Petter Selasky 659*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 660*b00ab754SHans Petter Selasky dosmemget (realBase+pktTemp, sizeof(*addr), addr); 661*b00ab754SHans Petter Selasky 662*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 663*b00ab754SHans Petter Selasky memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr)); 664*b00ab754SHans Petter Selasky 665*b00ab754SHans Petter Selasky #else 666*b00ab754SHans Petter Selasky memcpy ((void*)addr, &pktTemp, sizeof(*addr)); 667*b00ab754SHans Petter Selasky #endif 668*b00ab754SHans Petter Selasky 669*b00ab754SHans Petter Selasky return (TRUE); 670*b00ab754SHans Petter Selasky } 671*b00ab754SHans Petter Selasky 672*b00ab754SHans Petter Selasky /**************************************************************************/ 673*b00ab754SHans Petter Selasky 674*b00ab754SHans Petter Selasky PUBLIC BOOL PktSetAddress (const ETHER *addr) 675*b00ab754SHans Petter Selasky { 676*b00ab754SHans Petter Selasky /* copy addr to real-mode scrath area */ 677*b00ab754SHans Petter Selasky 678*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 679*b00ab754SHans Petter Selasky WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr)); 680*b00ab754SHans Petter Selasky 681*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 682*b00ab754SHans Petter Selasky dosmemput (addr, sizeof(*addr), realBase+pktTemp); 683*b00ab754SHans Petter Selasky 684*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 685*b00ab754SHans Petter Selasky memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr)); 686*b00ab754SHans Petter Selasky 687*b00ab754SHans Petter Selasky #else 688*b00ab754SHans Petter Selasky memcpy (&pktTemp, (void*)addr, sizeof(*addr)); 689*b00ab754SHans Petter Selasky #endif 690*b00ab754SHans Petter Selasky 691*b00ab754SHans Petter Selasky reg.r_ax = 0x1900; 692*b00ab754SHans Petter Selasky reg.r_cx = sizeof (*addr); /* address length */ 693*b00ab754SHans Petter Selasky 694*b00ab754SHans Petter Selasky #if (DOSX & DJGPP) 695*b00ab754SHans Petter Selasky reg.x.es = rm_mem.rm_segment; /* DOS offset to param */ 696*b00ab754SHans Petter Selasky reg.x.di = pktTemp; /* DOS segment to param */ 697*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 698*b00ab754SHans Petter Selasky reg.r_es = rm_base_seg; 699*b00ab754SHans Petter Selasky reg.r_di = pktTemp; 700*b00ab754SHans Petter Selasky #else 701*b00ab754SHans Petter Selasky reg.r_es = FP_SEG (&pktTemp); 702*b00ab754SHans Petter Selasky reg.r_di = FP_OFF (&pktTemp); 703*b00ab754SHans Petter Selasky #endif 704*b00ab754SHans Petter Selasky 705*b00ab754SHans Petter Selasky return PktInterrupt(); 706*b00ab754SHans Petter Selasky } 707*b00ab754SHans Petter Selasky 708*b00ab754SHans Petter Selasky /**************************************************************************/ 709*b00ab754SHans Petter Selasky 710*b00ab754SHans Petter Selasky PUBLIC BOOL PktGetDriverInfo (void) 711*b00ab754SHans Petter Selasky { 712*b00ab754SHans Petter Selasky pktInfo.majVer = 0; 713*b00ab754SHans Petter Selasky pktInfo.minVer = 0; 714*b00ab754SHans Petter Selasky memset (&pktInfo.name, 0, sizeof(pktInfo.name)); 715*b00ab754SHans Petter Selasky reg.r_ax = 0x01FF; 716*b00ab754SHans Petter Selasky reg.r_bx = 0; 717*b00ab754SHans Petter Selasky 718*b00ab754SHans Petter Selasky if (!PktInterrupt()) 719*b00ab754SHans Petter Selasky return (FALSE); 720*b00ab754SHans Petter Selasky 721*b00ab754SHans Petter Selasky pktInfo.number = reg.r_cx & 0xFF; 722*b00ab754SHans Petter Selasky pktInfo.class = reg.r_cx >> 8; 723*b00ab754SHans Petter Selasky #if 0 724*b00ab754SHans Petter Selasky pktInfo.minVer = reg.r_bx % 10; 725*b00ab754SHans Petter Selasky pktInfo.majVer = reg.r_bx / 10; 726*b00ab754SHans Petter Selasky #else 727*b00ab754SHans Petter Selasky pktInfo.majVer = reg.r_bx; // !! 728*b00ab754SHans Petter Selasky #endif 729*b00ab754SHans Petter Selasky pktInfo.funcs = reg.r_ax & 0xFF; 730*b00ab754SHans Petter Selasky pktInfo.type = reg.r_dx & 0xFF; 731*b00ab754SHans Petter Selasky 732*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 733*b00ab754SHans Petter Selasky ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name)); 734*b00ab754SHans Petter Selasky 735*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 736*b00ab754SHans Petter Selasky dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name); 737*b00ab754SHans Petter Selasky 738*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 739*b00ab754SHans Petter Selasky memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); 740*b00ab754SHans Petter Selasky 741*b00ab754SHans Petter Selasky #else 742*b00ab754SHans Petter Selasky _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); 743*b00ab754SHans Petter Selasky #endif 744*b00ab754SHans Petter Selasky return (TRUE); 745*b00ab754SHans Petter Selasky } 746*b00ab754SHans Petter Selasky 747*b00ab754SHans Petter Selasky /**************************************************************************/ 748*b00ab754SHans Petter Selasky 749*b00ab754SHans Petter Selasky PUBLIC BOOL PktGetDriverParam (void) 750*b00ab754SHans Petter Selasky { 751*b00ab754SHans Petter Selasky reg.r_ax = 0x0A00; 752*b00ab754SHans Petter Selasky 753*b00ab754SHans Petter Selasky if (!PktInterrupt()) 754*b00ab754SHans Petter Selasky return (FALSE); 755*b00ab754SHans Petter Selasky 756*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 757*b00ab754SHans Petter Selasky ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE); 758*b00ab754SHans Petter Selasky 759*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 760*b00ab754SHans Petter Selasky dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer); 761*b00ab754SHans Petter Selasky 762*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 763*b00ab754SHans Petter Selasky memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE); 764*b00ab754SHans Petter Selasky 765*b00ab754SHans Petter Selasky #else 766*b00ab754SHans Petter Selasky _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE); 767*b00ab754SHans Petter Selasky #endif 768*b00ab754SHans Petter Selasky return (TRUE); 769*b00ab754SHans Petter Selasky } 770*b00ab754SHans Petter Selasky 771*b00ab754SHans Petter Selasky /**************************************************************************/ 772*b00ab754SHans Petter Selasky 773*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 774*b00ab754SHans Petter Selasky PUBLIC int PktReceive (BYTE *buf, int max) 775*b00ab754SHans Petter Selasky { 776*b00ab754SHans Petter Selasky WORD inOfs = *rxInOfsFp; 777*b00ab754SHans Petter Selasky WORD outOfs = *rxOutOfsFp; 778*b00ab754SHans Petter Selasky 779*b00ab754SHans Petter Selasky if (outOfs != inOfs) 780*b00ab754SHans Petter Selasky { 781*b00ab754SHans Petter Selasky RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs); 782*b00ab754SHans Petter Selasky int size, len = max; 783*b00ab754SHans Petter Selasky 784*b00ab754SHans Petter Selasky if (CheckElement(head)) 785*b00ab754SHans Petter Selasky { 786*b00ab754SHans Petter Selasky size = min (head->firstCount, sizeof(RX_ELEMENT)); 787*b00ab754SHans Petter Selasky len = min (size, max); 788*b00ab754SHans Petter Selasky _fmemcpy (buf, &head->destin, len); 789*b00ab754SHans Petter Selasky } 790*b00ab754SHans Petter Selasky else 791*b00ab754SHans Petter Selasky size = -1; 792*b00ab754SHans Petter Selasky 793*b00ab754SHans Petter Selasky outOfs += sizeof (RX_ELEMENT); 794*b00ab754SHans Petter Selasky if (outOfs > LAST_RX_BUF) 795*b00ab754SHans Petter Selasky outOfs = FIRST_RX_BUF; 796*b00ab754SHans Petter Selasky *rxOutOfsFp = outOfs; 797*b00ab754SHans Petter Selasky return (size); 798*b00ab754SHans Petter Selasky } 799*b00ab754SHans Petter Selasky return (0); 800*b00ab754SHans Petter Selasky } 801*b00ab754SHans Petter Selasky 802*b00ab754SHans Petter Selasky PUBLIC void PktQueueBusy (BOOL busy) 803*b00ab754SHans Petter Selasky { 804*b00ab754SHans Petter Selasky *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp; 805*b00ab754SHans Petter Selasky if (*rxOutOfsFp > LAST_RX_BUF) 806*b00ab754SHans Petter Selasky *rxOutOfsFp = FIRST_RX_BUF; 807*b00ab754SHans Petter Selasky *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0; 808*b00ab754SHans Petter Selasky } 809*b00ab754SHans Petter Selasky 810*b00ab754SHans Petter Selasky PUBLIC WORD PktBuffersUsed (void) 811*b00ab754SHans Petter Selasky { 812*b00ab754SHans Petter Selasky WORD inOfs = *rxInOfsFp; 813*b00ab754SHans Petter Selasky WORD outOfs = *rxOutOfsFp; 814*b00ab754SHans Petter Selasky 815*b00ab754SHans Petter Selasky if (inOfs >= outOfs) 816*b00ab754SHans Petter Selasky return (inOfs - outOfs) / sizeof(RX_ELEMENT); 817*b00ab754SHans Petter Selasky return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 818*b00ab754SHans Petter Selasky } 819*b00ab754SHans Petter Selasky 820*b00ab754SHans Petter Selasky PUBLIC DWORD PktRxDropped (void) 821*b00ab754SHans Petter Selasky { 822*b00ab754SHans Petter Selasky return (*(DWORD _far*)(protBase + (WORD)&pktDrop)); 823*b00ab754SHans Petter Selasky } 824*b00ab754SHans Petter Selasky 825*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 826*b00ab754SHans Petter Selasky PUBLIC int PktReceive (BYTE *buf, int max) 827*b00ab754SHans Petter Selasky { 828*b00ab754SHans Petter Selasky WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs); 829*b00ab754SHans Petter Selasky 830*b00ab754SHans Petter Selasky if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs)) 831*b00ab754SHans Petter Selasky { 832*b00ab754SHans Petter Selasky RX_ELEMENT head; 833*b00ab754SHans Petter Selasky int size, len = max; 834*b00ab754SHans Petter Selasky 835*b00ab754SHans Petter Selasky head.firstCount = _farpeekw (_dos_ds, realBase+ofs); 836*b00ab754SHans Petter Selasky head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2); 837*b00ab754SHans Petter Selasky head.handle = _farpeekw (_dos_ds, realBase+ofs+4); 838*b00ab754SHans Petter Selasky 839*b00ab754SHans Petter Selasky if (CheckElement(&head)) 840*b00ab754SHans Petter Selasky { 841*b00ab754SHans Petter Selasky size = min (head.firstCount, sizeof(RX_ELEMENT)); 842*b00ab754SHans Petter Selasky len = min (size, max); 843*b00ab754SHans Petter Selasky dosmemget (realBase+ofs+6, len, buf); 844*b00ab754SHans Petter Selasky } 845*b00ab754SHans Petter Selasky else 846*b00ab754SHans Petter Selasky size = -1; 847*b00ab754SHans Petter Selasky 848*b00ab754SHans Petter Selasky ofs += sizeof (RX_ELEMENT); 849*b00ab754SHans Petter Selasky if (ofs > LAST_RX_BUF) 850*b00ab754SHans Petter Selasky _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 851*b00ab754SHans Petter Selasky else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); 852*b00ab754SHans Petter Selasky return (size); 853*b00ab754SHans Petter Selasky } 854*b00ab754SHans Petter Selasky return (0); 855*b00ab754SHans Petter Selasky } 856*b00ab754SHans Petter Selasky 857*b00ab754SHans Petter Selasky PUBLIC void PktQueueBusy (BOOL busy) 858*b00ab754SHans Petter Selasky { 859*b00ab754SHans Petter Selasky WORD ofs; 860*b00ab754SHans Petter Selasky 861*b00ab754SHans Petter Selasky disable(); 862*b00ab754SHans Petter Selasky ofs = _farpeekw (_dos_ds, realBase+rxInOfs); 863*b00ab754SHans Petter Selasky if (busy) 864*b00ab754SHans Petter Selasky ofs += sizeof (RX_ELEMENT); 865*b00ab754SHans Petter Selasky 866*b00ab754SHans Petter Selasky if (ofs > LAST_RX_BUF) 867*b00ab754SHans Petter Selasky _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 868*b00ab754SHans Petter Selasky else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); 869*b00ab754SHans Petter Selasky _farpokel (_dos_ds, realBase+pktDrop, 0UL); 870*b00ab754SHans Petter Selasky enable(); 871*b00ab754SHans Petter Selasky } 872*b00ab754SHans Petter Selasky 873*b00ab754SHans Petter Selasky PUBLIC WORD PktBuffersUsed (void) 874*b00ab754SHans Petter Selasky { 875*b00ab754SHans Petter Selasky WORD inOfs, outOfs; 876*b00ab754SHans Petter Selasky 877*b00ab754SHans Petter Selasky disable(); 878*b00ab754SHans Petter Selasky inOfs = _farpeekw (_dos_ds, realBase+rxInOfs); 879*b00ab754SHans Petter Selasky outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs); 880*b00ab754SHans Petter Selasky enable(); 881*b00ab754SHans Petter Selasky if (inOfs >= outOfs) 882*b00ab754SHans Petter Selasky return (inOfs - outOfs) / sizeof(RX_ELEMENT); 883*b00ab754SHans Petter Selasky return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 884*b00ab754SHans Petter Selasky } 885*b00ab754SHans Petter Selasky 886*b00ab754SHans Petter Selasky PUBLIC DWORD PktRxDropped (void) 887*b00ab754SHans Petter Selasky { 888*b00ab754SHans Petter Selasky return _farpeekl (_dos_ds, realBase+pktDrop); 889*b00ab754SHans Petter Selasky } 890*b00ab754SHans Petter Selasky 891*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 892*b00ab754SHans Petter Selasky PUBLIC int PktReceive (BYTE *buf, int max) 893*b00ab754SHans Petter Selasky { 894*b00ab754SHans Petter Selasky WORD ofs = *(WORD*) (realBase+rxOutOfs); 895*b00ab754SHans Petter Selasky 896*b00ab754SHans Petter Selasky if (ofs != *(WORD*) (realBase+rxInOfs)) 897*b00ab754SHans Petter Selasky { 898*b00ab754SHans Petter Selasky RX_ELEMENT head; 899*b00ab754SHans Petter Selasky int size, len = max; 900*b00ab754SHans Petter Selasky 901*b00ab754SHans Petter Selasky head.firstCount = *(WORD*) (realBase+ofs); 902*b00ab754SHans Petter Selasky head.secondCount = *(WORD*) (realBase+ofs+2); 903*b00ab754SHans Petter Selasky head.handle = *(WORD*) (realBase+ofs+4); 904*b00ab754SHans Petter Selasky 905*b00ab754SHans Petter Selasky if (CheckElement(&head)) 906*b00ab754SHans Petter Selasky { 907*b00ab754SHans Petter Selasky size = min (head.firstCount, sizeof(RX_ELEMENT)); 908*b00ab754SHans Petter Selasky len = min (size, max); 909*b00ab754SHans Petter Selasky memcpy (buf, (const void*)(realBase+ofs+6), len); 910*b00ab754SHans Petter Selasky } 911*b00ab754SHans Petter Selasky else 912*b00ab754SHans Petter Selasky size = -1; 913*b00ab754SHans Petter Selasky 914*b00ab754SHans Petter Selasky ofs += sizeof (RX_ELEMENT); 915*b00ab754SHans Petter Selasky if (ofs > LAST_RX_BUF) 916*b00ab754SHans Petter Selasky *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 917*b00ab754SHans Petter Selasky else *(WORD*) (realBase+rxOutOfs) = ofs; 918*b00ab754SHans Petter Selasky return (size); 919*b00ab754SHans Petter Selasky } 920*b00ab754SHans Petter Selasky return (0); 921*b00ab754SHans Petter Selasky } 922*b00ab754SHans Petter Selasky 923*b00ab754SHans Petter Selasky PUBLIC void PktQueueBusy (BOOL busy) 924*b00ab754SHans Petter Selasky { 925*b00ab754SHans Petter Selasky WORD ofs; 926*b00ab754SHans Petter Selasky 927*b00ab754SHans Petter Selasky _disable(); 928*b00ab754SHans Petter Selasky ofs = *(WORD*) (realBase+rxInOfs); 929*b00ab754SHans Petter Selasky if (busy) 930*b00ab754SHans Petter Selasky ofs += sizeof (RX_ELEMENT); 931*b00ab754SHans Petter Selasky 932*b00ab754SHans Petter Selasky if (ofs > LAST_RX_BUF) 933*b00ab754SHans Petter Selasky *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 934*b00ab754SHans Petter Selasky else *(WORD*) (realBase+rxOutOfs) = ofs; 935*b00ab754SHans Petter Selasky *(DWORD*) (realBase+pktDrop) = 0UL; 936*b00ab754SHans Petter Selasky _enable(); 937*b00ab754SHans Petter Selasky } 938*b00ab754SHans Petter Selasky 939*b00ab754SHans Petter Selasky PUBLIC WORD PktBuffersUsed (void) 940*b00ab754SHans Petter Selasky { 941*b00ab754SHans Petter Selasky WORD inOfs, outOfs; 942*b00ab754SHans Petter Selasky 943*b00ab754SHans Petter Selasky _disable(); 944*b00ab754SHans Petter Selasky inOfs = *(WORD*) (realBase+rxInOfs); 945*b00ab754SHans Petter Selasky outOfs = *(WORD*) (realBase+rxOutOfs); 946*b00ab754SHans Petter Selasky _enable(); 947*b00ab754SHans Petter Selasky if (inOfs >= outOfs) 948*b00ab754SHans Petter Selasky return (inOfs - outOfs) / sizeof(RX_ELEMENT); 949*b00ab754SHans Petter Selasky return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 950*b00ab754SHans Petter Selasky } 951*b00ab754SHans Petter Selasky 952*b00ab754SHans Petter Selasky PUBLIC DWORD PktRxDropped (void) 953*b00ab754SHans Petter Selasky { 954*b00ab754SHans Petter Selasky return *(DWORD*) (realBase+pktDrop); 955*b00ab754SHans Petter Selasky } 956*b00ab754SHans Petter Selasky 957*b00ab754SHans Petter Selasky #else /* real-mode small/large model */ 958*b00ab754SHans Petter Selasky 959*b00ab754SHans Petter Selasky PUBLIC int PktReceive (BYTE *buf, int max) 960*b00ab754SHans Petter Selasky { 961*b00ab754SHans Petter Selasky if (rxOutOfs != rxInOfs) 962*b00ab754SHans Petter Selasky { 963*b00ab754SHans Petter Selasky RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs); 964*b00ab754SHans Petter Selasky int size, len = max; 965*b00ab754SHans Petter Selasky 966*b00ab754SHans Petter Selasky if (CheckElement(head)) 967*b00ab754SHans Petter Selasky { 968*b00ab754SHans Petter Selasky size = min (head->firstCount, sizeof(RX_ELEMENT)); 969*b00ab754SHans Petter Selasky len = min (size, max); 970*b00ab754SHans Petter Selasky _fmemcpy (buf, &head->destin, len); 971*b00ab754SHans Petter Selasky } 972*b00ab754SHans Petter Selasky else 973*b00ab754SHans Petter Selasky size = -1; 974*b00ab754SHans Petter Selasky 975*b00ab754SHans Petter Selasky rxOutOfs += sizeof (RX_ELEMENT); 976*b00ab754SHans Petter Selasky if (rxOutOfs > LAST_RX_BUF) 977*b00ab754SHans Petter Selasky rxOutOfs = FIRST_RX_BUF; 978*b00ab754SHans Petter Selasky return (size); 979*b00ab754SHans Petter Selasky } 980*b00ab754SHans Petter Selasky return (0); 981*b00ab754SHans Petter Selasky } 982*b00ab754SHans Petter Selasky 983*b00ab754SHans Petter Selasky PUBLIC void PktQueueBusy (BOOL busy) 984*b00ab754SHans Petter Selasky { 985*b00ab754SHans Petter Selasky rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs; 986*b00ab754SHans Petter Selasky if (rxOutOfs > LAST_RX_BUF) 987*b00ab754SHans Petter Selasky rxOutOfs = FIRST_RX_BUF; 988*b00ab754SHans Petter Selasky pktDrop = 0L; 989*b00ab754SHans Petter Selasky } 990*b00ab754SHans Petter Selasky 991*b00ab754SHans Petter Selasky PUBLIC WORD PktBuffersUsed (void) 992*b00ab754SHans Petter Selasky { 993*b00ab754SHans Petter Selasky WORD inOfs = rxInOfs; 994*b00ab754SHans Petter Selasky WORD outOfs = rxOutOfs; 995*b00ab754SHans Petter Selasky 996*b00ab754SHans Petter Selasky if (inOfs >= outOfs) 997*b00ab754SHans Petter Selasky return ((inOfs - outOfs) / sizeof(RX_ELEMENT)); 998*b00ab754SHans Petter Selasky return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 999*b00ab754SHans Petter Selasky } 1000*b00ab754SHans Petter Selasky 1001*b00ab754SHans Petter Selasky PUBLIC DWORD PktRxDropped (void) 1002*b00ab754SHans Petter Selasky { 1003*b00ab754SHans Petter Selasky return (pktDrop); 1004*b00ab754SHans Petter Selasky } 1005*b00ab754SHans Petter Selasky #endif 1006*b00ab754SHans Petter Selasky 1007*b00ab754SHans Petter Selasky /**************************************************************************/ 1008*b00ab754SHans Petter Selasky 1009*b00ab754SHans Petter Selasky LOCAL __inline void PktFreeMem (void) 1010*b00ab754SHans Petter Selasky { 1011*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 1012*b00ab754SHans Petter Selasky if (realSeg) 1013*b00ab754SHans Petter Selasky { 1014*b00ab754SHans Petter Selasky _dx_real_free (realSeg); 1015*b00ab754SHans Petter Selasky realSeg = 0; 1016*b00ab754SHans Petter Selasky } 1017*b00ab754SHans Petter Selasky #elif (DOSX & DJGPP) 1018*b00ab754SHans Petter Selasky if (rm_mem.rm_segment) 1019*b00ab754SHans Petter Selasky { 1020*b00ab754SHans Petter Selasky unsigned ofs; /* clear the DOS-mem to prevent further upcalls */ 1021*b00ab754SHans Petter Selasky 1022*b00ab754SHans Petter Selasky for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4) 1023*b00ab754SHans Petter Selasky _farpokel (_dos_ds, realBase + ofs, 0); 1024*b00ab754SHans Petter Selasky _go32_dpmi_free_dos_memory (&rm_mem); 1025*b00ab754SHans Petter Selasky rm_mem.rm_segment = 0; 1026*b00ab754SHans Petter Selasky } 1027*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 1028*b00ab754SHans Petter Selasky if (rm_base_sel) 1029*b00ab754SHans Petter Selasky { 1030*b00ab754SHans Petter Selasky dpmi_real_free (rm_base_sel); 1031*b00ab754SHans Petter Selasky rm_base_sel = 0; 1032*b00ab754SHans Petter Selasky } 1033*b00ab754SHans Petter Selasky #endif 1034*b00ab754SHans Petter Selasky } 1035*b00ab754SHans Petter Selasky 1036*b00ab754SHans Petter Selasky /**************************************************************************/ 1037*b00ab754SHans Petter Selasky 1038*b00ab754SHans Petter Selasky PUBLIC BOOL PktExitDriver (void) 1039*b00ab754SHans Petter Selasky { 1040*b00ab754SHans Petter Selasky if (pktInfo.handle) 1041*b00ab754SHans Petter Selasky { 1042*b00ab754SHans Petter Selasky if (!PktSetReceiverMode(PDRX_BROADCAST)) 1043*b00ab754SHans Petter Selasky PUTS ("Error restoring receiver mode."); 1044*b00ab754SHans Petter Selasky 1045*b00ab754SHans Petter Selasky if (!PktReleaseHandle(pktInfo.handle)) 1046*b00ab754SHans Petter Selasky PUTS ("Error releasing PKT-DRVR handle."); 1047*b00ab754SHans Petter Selasky 1048*b00ab754SHans Petter Selasky PktFreeMem(); 1049*b00ab754SHans Petter Selasky pktInfo.handle = 0; 1050*b00ab754SHans Petter Selasky } 1051*b00ab754SHans Petter Selasky 1052*b00ab754SHans Petter Selasky if (pcap_pkt_debug >= 1) 1053*b00ab754SHans Petter Selasky printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, " 1054*b00ab754SHans Petter Selasky "wrong-handle %lu\n", 1055*b00ab754SHans Petter Selasky intStat.tooSmall, intStat.tooLarge, 1056*b00ab754SHans Petter Selasky intStat.badSync, intStat.wrongHandle); 1057*b00ab754SHans Petter Selasky return (TRUE); 1058*b00ab754SHans Petter Selasky } 1059*b00ab754SHans Petter Selasky 1060*b00ab754SHans Petter Selasky #if (DOSX & (DJGPP|DOS4GW)) 1061*b00ab754SHans Petter Selasky static void dump_pkt_stub (void) 1062*b00ab754SHans Petter Selasky { 1063*b00ab754SHans Petter Selasky int i; 1064*b00ab754SHans Petter Selasky 1065*b00ab754SHans Petter Selasky fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n", 1066*b00ab754SHans Petter Selasky PktReceiver); 1067*b00ab754SHans Petter Selasky for (i = 0; i < 15; i++) 1068*b00ab754SHans Petter Selasky fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]); 1069*b00ab754SHans Petter Selasky fputs ("\n", stderr); 1070*b00ab754SHans Petter Selasky } 1071*b00ab754SHans Petter Selasky #endif 1072*b00ab754SHans Petter Selasky 1073*b00ab754SHans Petter Selasky /* 1074*b00ab754SHans Petter Selasky * Front end initialization routine 1075*b00ab754SHans Petter Selasky */ 1076*b00ab754SHans Petter Selasky PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode) 1077*b00ab754SHans Petter Selasky { 1078*b00ab754SHans Petter Selasky PKT_RX_MODE rxMode; 1079*b00ab754SHans Petter Selasky BOOL writeInfo = (pcap_pkt_debug >= 3); 1080*b00ab754SHans Petter Selasky 1081*b00ab754SHans Petter Selasky pktInfo.quiet = (pcap_pkt_debug < 3); 1082*b00ab754SHans Petter Selasky 1083*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) && defined(__HIGHC__) 1084*b00ab754SHans Petter Selasky if (_mwenv != 2) 1085*b00ab754SHans Petter Selasky { 1086*b00ab754SHans Petter Selasky fprintf (stderr, "Only Pharlap DOS extender supported.\n"); 1087*b00ab754SHans Petter Selasky return (FALSE); 1088*b00ab754SHans Petter Selasky } 1089*b00ab754SHans Petter Selasky #endif 1090*b00ab754SHans Petter Selasky 1091*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) && defined(__WATCOMC__) 1092*b00ab754SHans Petter Selasky if (_Extender != 1) 1093*b00ab754SHans Petter Selasky { 1094*b00ab754SHans Petter Selasky fprintf (stderr, "Only DOS4GW style extenders supported.\n"); 1095*b00ab754SHans Petter Selasky return (FALSE); 1096*b00ab754SHans Petter Selasky } 1097*b00ab754SHans Petter Selasky #endif 1098*b00ab754SHans Petter Selasky 1099*b00ab754SHans Petter Selasky if (!PktSearchDriver()) 1100*b00ab754SHans Petter Selasky { 1101*b00ab754SHans Petter Selasky PUTS ("Packet driver not found."); 1102*b00ab754SHans Petter Selasky PktFreeMem(); 1103*b00ab754SHans Petter Selasky return (FALSE); 1104*b00ab754SHans Petter Selasky } 1105*b00ab754SHans Petter Selasky 1106*b00ab754SHans Petter Selasky if (!PktGetDriverInfo()) 1107*b00ab754SHans Petter Selasky { 1108*b00ab754SHans Petter Selasky PUTS ("Error getting pkt-drvr information."); 1109*b00ab754SHans Petter Selasky PktFreeMem(); 1110*b00ab754SHans Petter Selasky return (FALSE); 1111*b00ab754SHans Petter Selasky } 1112*b00ab754SHans Petter Selasky 1113*b00ab754SHans Petter Selasky #if (DOSX & PHARLAP) 1114*b00ab754SHans Petter Selasky if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd, 1115*b00ab754SHans Petter Selasky &realBase, &protBase, (USHORT*)&realSeg)) 1116*b00ab754SHans Petter Selasky { 1117*b00ab754SHans Petter Selasky rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs); 1118*b00ab754SHans Petter Selasky rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs); 1119*b00ab754SHans Petter Selasky *rxOutOfsFp = FIRST_RX_BUF; 1120*b00ab754SHans Petter Selasky *rxInOfsFp = FIRST_RX_BUF; 1121*b00ab754SHans Petter Selasky } 1122*b00ab754SHans Petter Selasky else 1123*b00ab754SHans Petter Selasky { 1124*b00ab754SHans Petter Selasky PUTS ("Cannot allocate real-mode stub."); 1125*b00ab754SHans Petter Selasky return (FALSE); 1126*b00ab754SHans Petter Selasky } 1127*b00ab754SHans Petter Selasky 1128*b00ab754SHans Petter Selasky #elif (DOSX & (DJGPP|DOS4GW)) 1129*b00ab754SHans Petter Selasky if (sizeof(real_stub_array) > 0xFFFF) 1130*b00ab754SHans Petter Selasky { 1131*b00ab754SHans Petter Selasky fprintf (stderr, "`real_stub_array[]' too big.\n"); 1132*b00ab754SHans Petter Selasky return (FALSE); 1133*b00ab754SHans Petter Selasky } 1134*b00ab754SHans Petter Selasky #if (DOSX & DJGPP) 1135*b00ab754SHans Petter Selasky rm_mem.size = (sizeof(real_stub_array) + 15) / 16; 1136*b00ab754SHans Petter Selasky 1137*b00ab754SHans Petter Selasky if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0) 1138*b00ab754SHans Petter Selasky { 1139*b00ab754SHans Petter Selasky PUTS ("real-mode init failed."); 1140*b00ab754SHans Petter Selasky return (FALSE); 1141*b00ab754SHans Petter Selasky } 1142*b00ab754SHans Petter Selasky realBase = (rm_mem.rm_segment << 4); 1143*b00ab754SHans Petter Selasky dosmemput (&real_stub_array, sizeof(real_stub_array), realBase); 1144*b00ab754SHans Petter Selasky _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 1145*b00ab754SHans Petter Selasky _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF); 1146*b00ab754SHans Petter Selasky 1147*b00ab754SHans Petter Selasky #elif (DOSX & DOS4GW) 1148*b00ab754SHans Petter Selasky rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel); 1149*b00ab754SHans Petter Selasky if (!rm_base_seg) 1150*b00ab754SHans Petter Selasky { 1151*b00ab754SHans Petter Selasky PUTS ("real-mode init failed."); 1152*b00ab754SHans Petter Selasky return (FALSE); 1153*b00ab754SHans Petter Selasky } 1154*b00ab754SHans Petter Selasky realBase = (rm_base_seg << 4); 1155*b00ab754SHans Petter Selasky memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array)); 1156*b00ab754SHans Petter Selasky *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 1157*b00ab754SHans Petter Selasky *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF; 1158*b00ab754SHans Petter Selasky 1159*b00ab754SHans Petter Selasky #endif 1160*b00ab754SHans Petter Selasky { 1161*b00ab754SHans Petter Selasky int pushf = PktReceiver; 1162*b00ab754SHans Petter Selasky 1163*b00ab754SHans Petter Selasky while (real_stub_array[pushf++] != 0x9C && /* pushf */ 1164*b00ab754SHans Petter Selasky real_stub_array[pushf] != 0xFA) /* cli */ 1165*b00ab754SHans Petter Selasky { 1166*b00ab754SHans Petter Selasky if (++para_skip > 16) 1167*b00ab754SHans Petter Selasky { 1168*b00ab754SHans Petter Selasky fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n"); 1169*b00ab754SHans Petter Selasky para_skip = 0; 1170*b00ab754SHans Petter Selasky dump_pkt_stub(); 1171*b00ab754SHans Petter Selasky return (FALSE); 1172*b00ab754SHans Petter Selasky } 1173*b00ab754SHans Petter Selasky } 1174*b00ab754SHans Petter Selasky if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800) 1175*b00ab754SHans Petter Selasky { 1176*b00ab754SHans Petter Selasky fprintf (stderr, "`real_stub_array[]' is misaligned.\n"); 1177*b00ab754SHans Petter Selasky return (FALSE); 1178*b00ab754SHans Petter Selasky } 1179*b00ab754SHans Petter Selasky } 1180*b00ab754SHans Petter Selasky 1181*b00ab754SHans Petter Selasky if (pcap_pkt_debug > 2) 1182*b00ab754SHans Petter Selasky dump_pkt_stub(); 1183*b00ab754SHans Petter Selasky 1184*b00ab754SHans Petter Selasky #else 1185*b00ab754SHans Petter Selasky rxOutOfs = FIRST_RX_BUF; 1186*b00ab754SHans Petter Selasky rxInOfs = FIRST_RX_BUF; 1187*b00ab754SHans Petter Selasky #endif 1188*b00ab754SHans Petter Selasky 1189*b00ab754SHans Petter Selasky if (!PktSetAccess()) 1190*b00ab754SHans Petter Selasky { 1191*b00ab754SHans Petter Selasky PUTS ("Error setting pkt-drvr access."); 1192*b00ab754SHans Petter Selasky PktFreeMem(); 1193*b00ab754SHans Petter Selasky return (FALSE); 1194*b00ab754SHans Petter Selasky } 1195*b00ab754SHans Petter Selasky 1196*b00ab754SHans Petter Selasky if (!PktGetAddress(&myAddress)) 1197*b00ab754SHans Petter Selasky { 1198*b00ab754SHans Petter Selasky PUTS ("Error fetching adapter address."); 1199*b00ab754SHans Petter Selasky PktFreeMem(); 1200*b00ab754SHans Petter Selasky return (FALSE); 1201*b00ab754SHans Petter Selasky } 1202*b00ab754SHans Petter Selasky 1203*b00ab754SHans Petter Selasky if (!PktSetReceiverMode(mode)) 1204*b00ab754SHans Petter Selasky { 1205*b00ab754SHans Petter Selasky PUTS ("Error setting receiver mode."); 1206*b00ab754SHans Petter Selasky PktFreeMem(); 1207*b00ab754SHans Petter Selasky return (FALSE); 1208*b00ab754SHans Petter Selasky } 1209*b00ab754SHans Petter Selasky 1210*b00ab754SHans Petter Selasky if (!PktGetReceiverMode(&rxMode)) 1211*b00ab754SHans Petter Selasky { 1212*b00ab754SHans Petter Selasky PUTS ("Error getting receiver mode."); 1213*b00ab754SHans Petter Selasky PktFreeMem(); 1214*b00ab754SHans Petter Selasky return (FALSE); 1215*b00ab754SHans Petter Selasky } 1216*b00ab754SHans Petter Selasky 1217*b00ab754SHans Petter Selasky if (writeInfo) 1218*b00ab754SHans Petter Selasky printf ("Pkt-driver information:\n" 1219*b00ab754SHans Petter Selasky " Version : %d.%d\n" 1220*b00ab754SHans Petter Selasky " Name : %.15s\n" 1221*b00ab754SHans Petter Selasky " Class : %u (%s)\n" 1222*b00ab754SHans Petter Selasky " Type : %u\n" 1223*b00ab754SHans Petter Selasky " Number : %u\n" 1224*b00ab754SHans Petter Selasky " Funcs : %u\n" 1225*b00ab754SHans Petter Selasky " Intr : %Xh\n" 1226*b00ab754SHans Petter Selasky " Handle : %u\n" 1227*b00ab754SHans Petter Selasky " Extended : %s\n" 1228*b00ab754SHans Petter Selasky " Hi-perf : %s\n" 1229*b00ab754SHans Petter Selasky " RX mode : %s\n" 1230*b00ab754SHans Petter Selasky " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n", 1231*b00ab754SHans Petter Selasky 1232*b00ab754SHans Petter Selasky pktInfo.majVer, pktInfo.minVer, pktInfo.name, 1233*b00ab754SHans Petter Selasky pktInfo.class, PktGetClassName(pktInfo.class), 1234*b00ab754SHans Petter Selasky pktInfo.type, pktInfo.number, 1235*b00ab754SHans Petter Selasky pktInfo.funcs, pktInfo.intr, pktInfo.handle, 1236*b00ab754SHans Petter Selasky pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No", 1237*b00ab754SHans Petter Selasky pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No", 1238*b00ab754SHans Petter Selasky PktRXmodeStr(rxMode), 1239*b00ab754SHans Petter Selasky myAddress[0], myAddress[1], myAddress[2], 1240*b00ab754SHans Petter Selasky myAddress[3], myAddress[4], myAddress[5]); 1241*b00ab754SHans Petter Selasky 1242*b00ab754SHans Petter Selasky #if defined(DEBUG) && (DOSX & PHARLAP) 1243*b00ab754SHans Petter Selasky if (writeInfo) 1244*b00ab754SHans Petter Selasky { 1245*b00ab754SHans Petter Selasky DWORD rAdr = realBase + (WORD)&PktReceiver; 1246*b00ab754SHans Petter Selasky unsigned sel, ofs; 1247*b00ab754SHans Petter Selasky 1248*b00ab754SHans Petter Selasky printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr)); 1249*b00ab754SHans Petter Selasky printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase)); 1250*b00ab754SHans Petter Selasky 1251*b00ab754SHans Petter Selasky sel = _FP_SEG (protBase); 1252*b00ab754SHans Petter Selasky ofs = _FP_OFF (protBase); 1253*b00ab754SHans Petter Selasky printf ("Protbase = %04X:%08X\n", sel,ofs); 1254*b00ab754SHans Petter Selasky printf ("RealSeg = %04X\n", realSeg); 1255*b00ab754SHans Petter Selasky 1256*b00ab754SHans Petter Selasky sel = _FP_SEG (rxOutOfsFp); 1257*b00ab754SHans Petter Selasky ofs = _FP_OFF (rxOutOfsFp); 1258*b00ab754SHans Petter Selasky printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs); 1259*b00ab754SHans Petter Selasky 1260*b00ab754SHans Petter Selasky sel = _FP_SEG (rxInOfsFp); 1261*b00ab754SHans Petter Selasky ofs = _FP_OFF (rxInOfsFp); 1262*b00ab754SHans Petter Selasky printf ("rxInOfsFp = %04X:%08X\n", sel,ofs); 1263*b00ab754SHans Petter Selasky 1264*b00ab754SHans Petter Selasky printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", 1265*b00ab754SHans Petter Selasky *rxOutOfsFp, *rxInOfsFp); 1266*b00ab754SHans Petter Selasky 1267*b00ab754SHans Petter Selasky PktQueueBusy (TRUE); 1268*b00ab754SHans Petter Selasky printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", 1269*b00ab754SHans Petter Selasky *rxOutOfsFp, *rxInOfsFp); 1270*b00ab754SHans Petter Selasky } 1271*b00ab754SHans Petter Selasky #endif 1272*b00ab754SHans Petter Selasky 1273*b00ab754SHans Petter Selasky memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */ 1274*b00ab754SHans Petter Selasky PktQueueBusy (TRUE); 1275*b00ab754SHans Petter Selasky return (TRUE); 1276*b00ab754SHans Petter Selasky } 1277*b00ab754SHans Petter Selasky 1278*b00ab754SHans Petter Selasky 1279*b00ab754SHans Petter Selasky /* 1280*b00ab754SHans Petter Selasky * DPMI functions only for Watcom + DOS4GW extenders 1281*b00ab754SHans Petter Selasky */ 1282*b00ab754SHans Petter Selasky #if (DOSX & DOS4GW) 1283*b00ab754SHans Petter Selasky LOCAL DWORD dpmi_get_real_vector (int intr) 1284*b00ab754SHans Petter Selasky { 1285*b00ab754SHans Petter Selasky union REGS r; 1286*b00ab754SHans Petter Selasky 1287*b00ab754SHans Petter Selasky r.x.eax = 0x200; 1288*b00ab754SHans Petter Selasky r.x.ebx = (DWORD) intr; 1289*b00ab754SHans Petter Selasky int386 (0x31, &r, &r); 1290*b00ab754SHans Petter Selasky return ((r.w.cx << 4) + r.w.dx); 1291*b00ab754SHans Petter Selasky } 1292*b00ab754SHans Petter Selasky 1293*b00ab754SHans Petter Selasky LOCAL WORD dpmi_real_malloc (int size, WORD *selector) 1294*b00ab754SHans Petter Selasky { 1295*b00ab754SHans Petter Selasky union REGS r; 1296*b00ab754SHans Petter Selasky 1297*b00ab754SHans Petter Selasky r.x.eax = 0x0100; /* DPMI allocate DOS memory */ 1298*b00ab754SHans Petter Selasky r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */ 1299*b00ab754SHans Petter Selasky int386 (0x31, &r, &r); 1300*b00ab754SHans Petter Selasky if (r.w.cflag & 1) 1301*b00ab754SHans Petter Selasky return (0); 1302*b00ab754SHans Petter Selasky 1303*b00ab754SHans Petter Selasky *selector = r.w.dx; 1304*b00ab754SHans Petter Selasky return (r.w.ax); /* Return segment address */ 1305*b00ab754SHans Petter Selasky } 1306*b00ab754SHans Petter Selasky 1307*b00ab754SHans Petter Selasky LOCAL void dpmi_real_free (WORD selector) 1308*b00ab754SHans Petter Selasky { 1309*b00ab754SHans Petter Selasky union REGS r; 1310*b00ab754SHans Petter Selasky 1311*b00ab754SHans Petter Selasky r.x.eax = 0x101; /* DPMI free DOS memory */ 1312*b00ab754SHans Petter Selasky r.x.ebx = selector; /* Selector to free */ 1313*b00ab754SHans Petter Selasky int386 (0x31, &r, &r); 1314*b00ab754SHans Petter Selasky } 1315*b00ab754SHans Petter Selasky #endif 1316*b00ab754SHans Petter Selasky 1317*b00ab754SHans Petter Selasky 1318*b00ab754SHans Petter Selasky #if defined(DOSX) && (DOSX & PHARLAP) 1319*b00ab754SHans Petter Selasky /* 1320*b00ab754SHans Petter Selasky * Description: 1321*b00ab754SHans Petter Selasky * This routine allocates conventional memory for the specified block 1322*b00ab754SHans Petter Selasky * of code (which must be within the first 64K of the protected mode 1323*b00ab754SHans Petter Selasky * program segment) and copies the code to it. 1324*b00ab754SHans Petter Selasky * 1325*b00ab754SHans Petter Selasky * The caller should free up the conventional memory block when it 1326*b00ab754SHans Petter Selasky * is done with the conventional memory. 1327*b00ab754SHans Petter Selasky * 1328*b00ab754SHans Petter Selasky * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER. 1329*b00ab754SHans Petter Selasky * 1330*b00ab754SHans Petter Selasky * Calling arguments: 1331*b00ab754SHans Petter Selasky * start_offs start of real mode code in program segment 1332*b00ab754SHans Petter Selasky * end_offs 1 byte past end of real mode code in program segment 1333*b00ab754SHans Petter Selasky * real_basep returned; real mode ptr to use as a base for the 1334*b00ab754SHans Petter Selasky * real mode code (eg, to get the real mode FAR 1335*b00ab754SHans Petter Selasky * addr of a function foo(), take 1336*b00ab754SHans Petter Selasky * real_basep + (ULONG) foo). 1337*b00ab754SHans Petter Selasky * This pointer is constructed such that 1338*b00ab754SHans Petter Selasky * offsets within the real mode segment are 1339*b00ab754SHans Petter Selasky * the same as the link-time offsets in the 1340*b00ab754SHans Petter Selasky * protected mode program segment 1341*b00ab754SHans Petter Selasky * prot_basep returned; prot mode ptr to use as a base for getting 1342*b00ab754SHans Petter Selasky * to the conventional memory, also constructed 1343*b00ab754SHans Petter Selasky * so that adding the prot mode offset of a 1344*b00ab754SHans Petter Selasky * function or variable to the base gets you a 1345*b00ab754SHans Petter Selasky * ptr to the function or variable in the 1346*b00ab754SHans Petter Selasky * conventional memory block. 1347*b00ab754SHans Petter Selasky * rmem_adrp returned; real mode para addr of allocated 1348*b00ab754SHans Petter Selasky * conventional memory block, to be used to free 1349*b00ab754SHans Petter Selasky * up the conventional memory when done. DO NOT 1350*b00ab754SHans Petter Selasky * USE THIS TO CONSTRUCT A REAL MODE PTR, USE 1351*b00ab754SHans Petter Selasky * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT 1352*b00ab754SHans Petter Selasky * CORRECTLY. 1353*b00ab754SHans Petter Selasky * 1354*b00ab754SHans Petter Selasky * Returned values: 1355*b00ab754SHans Petter Selasky * 0 if error 1356*b00ab754SHans Petter Selasky * 1 if success 1357*b00ab754SHans Petter Selasky */ 1358*b00ab754SHans Petter Selasky int RealCopy (ULONG start_offs, 1359*b00ab754SHans Petter Selasky ULONG end_offs, 1360*b00ab754SHans Petter Selasky REALPTR *real_basep, 1361*b00ab754SHans Petter Selasky FARPTR *prot_basep, 1362*b00ab754SHans Petter Selasky USHORT *rmem_adrp) 1363*b00ab754SHans Petter Selasky { 1364*b00ab754SHans Petter Selasky ULONG rm_base; /* base real mode para addr for accessing */ 1365*b00ab754SHans Petter Selasky /* allocated conventional memory */ 1366*b00ab754SHans Petter Selasky UCHAR *source; /* source pointer for copy */ 1367*b00ab754SHans Petter Selasky FARPTR destin; /* destination pointer for copy */ 1368*b00ab754SHans Petter Selasky ULONG len; /* number of bytes to copy */ 1369*b00ab754SHans Petter Selasky ULONG temp; 1370*b00ab754SHans Petter Selasky USHORT stemp; 1371*b00ab754SHans Petter Selasky 1372*b00ab754SHans Petter Selasky /* First check for valid inputs 1373*b00ab754SHans Petter Selasky */ 1374*b00ab754SHans Petter Selasky if (start_offs >= end_offs || end_offs > 0x10000) 1375*b00ab754SHans Petter Selasky return (FALSE); 1376*b00ab754SHans Petter Selasky 1377*b00ab754SHans Petter Selasky /* Round start_offs down to a paragraph (16-byte) boundary so we can set up 1378*b00ab754SHans Petter Selasky * the real mode pointer easily. Round up end_offs to make sure we allocate 1379*b00ab754SHans Petter Selasky * enough paragraphs 1380*b00ab754SHans Petter Selasky */ 1381*b00ab754SHans Petter Selasky start_offs &= ~15; 1382*b00ab754SHans Petter Selasky end_offs = (15 + (end_offs << 4)) >> 4; 1383*b00ab754SHans Petter Selasky 1384*b00ab754SHans Petter Selasky /* Allocate the conventional memory for our real mode code. Remember to 1385*b00ab754SHans Petter Selasky * round byte count UP to 16-byte paragraph size. We alloc it 1386*b00ab754SHans Petter Selasky * above the DOS data buffer so both the DOS data buffer and the appl 1387*b00ab754SHans Petter Selasky * conventional mem block can still be resized. 1388*b00ab754SHans Petter Selasky * 1389*b00ab754SHans Petter Selasky * First just try to alloc it; if we can't get it, shrink the appl mem 1390*b00ab754SHans Petter Selasky * block down to the minimum, try to alloc the memory again, then grow the 1391*b00ab754SHans Petter Selasky * appl mem block back to the maximum. (Don't try to shrink the DOS data 1392*b00ab754SHans Petter Selasky * buffer to free conventional memory; it wouldn't be good for this routine 1393*b00ab754SHans Petter Selasky * to have the possible side effect of making file I/O run slower.) 1394*b00ab754SHans Petter Selasky */ 1395*b00ab754SHans Petter Selasky len = ((end_offs - start_offs) + 15) >> 4; 1396*b00ab754SHans Petter Selasky if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) 1397*b00ab754SHans Petter Selasky { 1398*b00ab754SHans Petter Selasky if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE) 1399*b00ab754SHans Petter Selasky return (FALSE); 1400*b00ab754SHans Petter Selasky 1401*b00ab754SHans Petter Selasky if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) 1402*b00ab754SHans Petter Selasky *rmem_adrp = 0; 1403*b00ab754SHans Petter Selasky 1404*b00ab754SHans Petter Selasky if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE) 1405*b00ab754SHans Petter Selasky { 1406*b00ab754SHans Petter Selasky if (*rmem_adrp != 0) 1407*b00ab754SHans Petter Selasky _dx_real_free (*rmem_adrp); 1408*b00ab754SHans Petter Selasky return (FALSE); 1409*b00ab754SHans Petter Selasky } 1410*b00ab754SHans Petter Selasky 1411*b00ab754SHans Petter Selasky if (*rmem_adrp == 0) 1412*b00ab754SHans Petter Selasky return (FALSE); 1413*b00ab754SHans Petter Selasky } 1414*b00ab754SHans Petter Selasky 1415*b00ab754SHans Petter Selasky /* Construct real mode & protected mode pointers to access the allocated 1416*b00ab754SHans Petter Selasky * memory. Note we know start_offs is aligned on a paragraph (16-byte) 1417*b00ab754SHans Petter Selasky * boundary, because we rounded it down. 1418*b00ab754SHans Petter Selasky * 1419*b00ab754SHans Petter Selasky * We make the offsets come out rights by backing off the real mode selector 1420*b00ab754SHans Petter Selasky * by start_offs. 1421*b00ab754SHans Petter Selasky */ 1422*b00ab754SHans Petter Selasky rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4); 1423*b00ab754SHans Petter Selasky RP_SET (*real_basep, 0, rm_base); 1424*b00ab754SHans Petter Selasky FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM); 1425*b00ab754SHans Petter Selasky 1426*b00ab754SHans Petter Selasky /* Copy the real mode code/data to the allocated memory 1427*b00ab754SHans Petter Selasky */ 1428*b00ab754SHans Petter Selasky source = (UCHAR *) start_offs; 1429*b00ab754SHans Petter Selasky destin = *prot_basep; 1430*b00ab754SHans Petter Selasky FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep)); 1431*b00ab754SHans Petter Selasky len = end_offs - start_offs; 1432*b00ab754SHans Petter Selasky WriteFarMem (destin, source, len); 1433*b00ab754SHans Petter Selasky 1434*b00ab754SHans Petter Selasky return (TRUE); 1435*b00ab754SHans Petter Selasky } 1436*b00ab754SHans Petter Selasky #endif /* DOSX && (DOSX & PHARLAP) */ 1437