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