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