xref: /freebsd/contrib/libpcap/msdos/pktdrvr.c (revision b00ab7548b418624b6719ab8a2e8aaeade767a70)
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, &reg);
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, &reg);
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 (&reg);
329*b00ab754SHans Petter Selasky   r.x.edi = FP_OFF (&reg);
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*)&reg);
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