www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/04/03/20:06:04

Message-ID: <38E8E68C.88C17E8B@hotmail.com>
From: Andrew Hakman <hakmana AT hotmail DOT com>
X-Mailer: Mozilla 4.7 [en] (WinNT; I)
X-Accept-Language: en
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Page Fault with IPX Library and 387 Emulation
References: <Pine DOT SUN DOT 3 DOT 91 DOT 1000403110847 DOT 26246M-100000 AT is>
Lines: 1101
Date: Mon, 03 Apr 2000 18:44:42 GMT
NNTP-Posting-Host: 142.13.16.203
X-Trace: typhoon.mbnet.mb.ca 954787482 142.13.16.203 (Mon, 03 Apr 2000 13:44:42 CDT)
NNTP-Posting-Date: Mon, 03 Apr 2000 13:44:42 CDT
Organization: MBnet Networking Inc.
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

This is a multi-part message in MIME format.
--------------C5BC7093B02ED95AD7EBD19E
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi!

Thanks for the help. I sort of understand what you mean (just beginning to
learn assembly - just finished implementing a "teaching" asember language
with only 4 registers and 1000 memory locations in DJGPP for discrete
structures and programming course I'm taking), but can't seem to find
anything related in the code. Would you be kind enough to look at it for me
(the source isn't TOO big and I re-spaced and reindented it so it is actually
readable!!) I see some of the other registers like es etc. but can't find any
mention of ds.

If you could do this for me, that would be awesome!
Thanks so much
Andrew Hakman

Eli Zaretskii wrote:

> On Mon, 3 Apr 2000, Andrew Hakman wrote:
>
> > Now that I got 387 emulation working, I get the following page fault
> > (only when the program is run on a computer that requires 387 emulation
> > - run the exact same exe on a 486 and it runs great!):
> >
> > Page Fault cr2=10000002 in RMCB at eip=0; flags=3006 eax=0 ebx=4f ecx=0
> > edx=34868 esi=3ebbc edi=34808 ebp=7 esp=c4044 cs=2b ds=b7 es=b7 fs=b7
> > gs=b7 ss=b7 error=0004
>
> The cr2 value is the address where the Page Fault happened.  It means
> that the program tried to dereference a NULL pointer (value of 2 instead
> of zero, actually).
>
> Since this happens only under emulation, I suspect that the IPX library
> uses the DS selector inside some interrupt handler.  The problem with
> that is that the FP emulator works by triggering an exception, which it
> does by invalidating the DS selector.  So any interrupt handler should
> use the alias selector stored in the __djgpp_ds_alias variable instead
> of DS.  The alias selector points to the same memory, but it is always
> valid.

--------------C5BC7093B02ED95AD7EBD19E
Content-Type: text/plain; charset=us-ascii;
 name="DOSBUFF.C"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="DOSBUFF.C"

#include "dosbuff.h"
#include <dpmi.h>
#include <go32.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>

unsigned short segment_of_dos_buffer, offset_of_dos_buffer;
unsigned long address_of_dos_buffer;
unsigned long linear_address_of_dos_buffer;

unsigned short segment_of_dos_buffer_two, offset_of_dos_buffer_two;
unsigned long address_of_dos_buffer_two;
unsigned long linear_address_of_dos_buffer_two;

unsigned short segment_of_ecb_send_buffer, offset_of_ecb_send_buffer;
unsigned long address_of_ecb_send_buffer;
unsigned long linear_address_of_ecb_send_buffer;

unsigned short segment_of_ecb_recieve_buffer, offset_of_ecb_recieve_buffer;
unsigned long address_of_ecb_recieve_buffer;
unsigned long linear_address_of_ecb_recieve_buffer;

unsigned short segment_of_send_buffer, offset_of_send_buffer;
unsigned long address_of_send_buffer;
unsigned long linear_address_of_send_buffer;

unsigned short segment_of_recieve_buffer, offset_of_recieve_buffer;
unsigned long address_of_recieve_buffer;
unsigned long linear_address_of_recieve_buffer;


void Allocate_Dos_Buffers( void )
{
  _go32_dpmi_seginfo info;
  unsigned int address, page; /* Address is linear */
  unsigned int new_segment, new_offset;

  info.size = (DOS_BUFFER_SIZE + 15) / 16;
     
  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */

  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_dos_buffer = new_segment;
  offset_of_dos_buffer  = new_offset;

  linear_address_of_dos_buffer = address;
  address_of_dos_buffer = ((unsigned long)new_segment << 16) | new_offset;
     

  /* Do the same for buffer two */
  memset (&info, 0, sizeof(info));

  info.size = (DOS_BUFFER_SIZE + 15) / 16;
     
  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */
     
  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_dos_buffer_two = new_segment;
  offset_of_dos_buffer_two  = new_offset;

  linear_address_of_dos_buffer_two = address;
  address_of_dos_buffer_two = ((unsigned long)new_segment << 16) | new_offset;


  /* Do the same for send buffer */
  info.size = (DOS_BUFFER_SIZE + 15) / 16;

  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */
     
  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_send_buffer = new_segment;
  offset_of_send_buffer  = new_offset;

  linear_address_of_send_buffer = address;
  address_of_send_buffer = ((unsigned long)new_segment << 16) | new_offset;


  /* Do the same for recieve buffer */
  info.size = (DOS_BUFFER_SIZE + 15) / 16;

  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */
     
  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_recieve_buffer = new_segment;
  offset_of_recieve_buffer  = new_offset;
  linear_address_of_recieve_buffer = address;
  address_of_recieve_buffer = ((unsigned long)new_segment << 16) | new_offset;

  /* Do the same for ecb send buffer */
  info.size = (DOS_BUFFER_SIZE + 15) / 16;
  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */
     
  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_ecb_send_buffer = new_segment;
  offset_of_ecb_send_buffer  = new_offset;

  linear_address_of_ecb_send_buffer = address;
  address_of_ecb_send_buffer = ((unsigned long)new_segment << 16) | new_offset;
  
  /* Do the same for recieve buffer */
  info.size = (DOS_BUFFER_SIZE + 15) / 16;
     
  if (_go32_dpmi_allocate_dos_memory(&info))
  {
    printf("ERROR Allocate dos buffer Alloc failed \n");
    exit(0);
  }

  /* What is the 20 bit address? */
  address = info.rm_segment << 4;
  /* Does it cross a 64K boundary? */
     
  page = address & 0xffff;
  if ((page + DOS_BUFFER_TEST) > 0xffff)
    address = (address - page) + 0x10000;
         
  new_segment = address / 16;
  new_offset  = address % 16;

  segment_of_ecb_recieve_buffer = new_segment;
  offset_of_ecb_recieve_buffer  = new_offset;

  linear_address_of_ecb_recieve_buffer = address;
  address_of_ecb_recieve_buffer = ((unsigned long)new_segment << 16) | new_offset;
}

void Copy_Into_Dos_Buffer (void *block, short length)
{
  dosmemput (block, length, linear_address_of_dos_buffer);
}
    
void Copy_From_Dos_Buffer (void *block, short length)
{
  dosmemget (linear_address_of_dos_buffer, length, block);
}

void Copy_Into_Dos_Buffer_Two (void *block, short length)
{
  dosmemput (block, length, linear_address_of_dos_buffer_two);
}
    
void Copy_From_Dos_Buffer_Two (void *block, short length)
{
  dosmemget (linear_address_of_dos_buffer_two, length, block);
}


void Copy_Into_Send_Buffer (void *block, short length)
{
  dosmemput (block, length, linear_address_of_send_buffer);
}
    
void Copy_From_Send_Buffer (void *block, short length)
{
  dosmemget (linear_address_of_send_buffer, length, block);
}

void Copy_Into_Recieve_Buffer (void *block, short length)
{
  dosmemput (block, length, linear_address_of_recieve_buffer);
}
    
void Copy_From_Recieve_Buffer (void *block, short length)
{
  dosmemget (linear_address_of_recieve_buffer, length, block);
}

void Copy_Into_Ecb_Send_Buffer (void *block, short length)
{
  dosmemput (block, length, linear_address_of_ecb_send_buffer);
}
    
void Copy_From_Ecb_Send_Buffer (void *block, short length)
{
  dosmemget (linear_address_of_ecb_send_buffer, length, block);
}

void Copy_Into_Ecb_Recieve_Buffer (void *block, short length)
{
  dosmemput (block, length, linear_address_of_ecb_recieve_buffer);
}
    
void Copy_From_Ecb_Recieve_Buffer (void *block, short length)
{
  dosmemget (linear_address_of_ecb_recieve_buffer, length, block);
}

void Test_Dos_Buffers (void)
{
  int i;
  unsigned char buffer1[100], buffer2[100];

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Dos_Buffer (buffer1, 100);
  Copy_From_Dos_Buffer (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Dos_Buffer_Two (buffer1, 100);
  Copy_From_Dos_Buffer_Two (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Send_Buffer (buffer1, 100);
  Copy_From_Send_Buffer (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Recieve_Buffer (buffer1, 100);
  Copy_From_Recieve_Buffer (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Ecb_Send_Buffer (buffer1, 100);
  Copy_From_Ecb_Send_Buffer (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

  for (i = 0; i < 100; i++)
  {
    buffer1[i] = i;
    buffer2[i] = 0;
  }

  Copy_Into_Ecb_Recieve_Buffer (buffer1, 100);
  Copy_From_Ecb_Recieve_Buffer (buffer2, 100);

  for (i = 0; i < 100; i++)
    printf("%d \n", buffer2[i]);

}

unsigned long Make_Far_Pointer (unsigned short segment, unsigned short offset)
{
  unsigned long temp;
  temp = ((unsigned long)segment << 16) | offset;
  return(temp);
}




--------------C5BC7093B02ED95AD7EBD19E
Content-Type: text/plain; charset=us-ascii;
 name="jonipx.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="jonipx.h"

#ifndef JONIPX_H
#define JONIPX_H

#include <dos.h> /* For delay */

#define MY_SOCKET 0x869C /* Socket used by these routines */
#define MAX_PACKETS_IN_BUFFER 100

/* Amount we delay between sending packets */
#define IPX_DELAY                        3

#define WAITING_FOR_NODES_PACKET         10
#define PLAYER_NUMBER_ASSIGNMENT_PACKET  11
#define HERE_I_AM_PACKET                 12
#define GAME_INIT_PACKET                 13
#define BIG_ASS_GAME_INFO_PACKET         14

#define READY_PACKET                     15  /* Indicates we are ready to move on */

#define SERVER_INPUT_TABLE_PACKET        16
#define CLIENT_INPUT_TABLE_PACKET        17
#define WAITING_FOR_INPUT_TABLE_PACKET   18

#define TEAM_REQUEST_PACKET              19
#define TEAM_ASSIGNMENT_PACKET           20
#define WAITING_FOR_TEAM_REQUEST_PACKET  21


#define PLAYER_INFO_PACKET               22
#define CYLINDER_FILENAME_PACKET         23

#define TERMINATE_IPX_CONNECTION_PACKET  24
#define END_IPX_GAME_PACKET              25


#define TRUE  1
#define FALSE 0


typedef unsigned char boolean;

typedef unsigned char net_type[4];
typedef unsigned char node_address_type[6];

typedef char string_type[80];

typedef unsigned short address_type[2];

typedef struct 
{
  net_type          net           __attribute__((packed));  /* Network address */
  node_address_type node_address  __attribute__((packed));  /* Node address */
  unsigned short    socket        __attribute__((packed));  /* Big endian socket number */
} net_address_type;

typedef struct
{
  net_type           net          __attribute__((packed)); /* My network address */
  node_address_type  node_address __attribute__((packed)); /* My node address */
} local_address_type;

typedef struct
{
  address_type      link              __attribute__((packed)); /* Pointer to next ECB */
  unsigned long     ESR               __attribute__((packed)); /* Event service routine 00000000h if none */
  unsigned char     in_use            __attribute__((packed)); /* In use flag */
  unsigned char     complete          __attribute__((packed)); /* Completing flag */
  unsigned short    socket            __attribute__((packed)); /* Big endian socket number */
  unsigned char     IPX_work[4]       __attribute__((packed)); /* IPX work space */
  unsigned char     D_work[12]        __attribute__((packed)); /* Driver work space */
  node_address_type immediate_address __attribute__((packed)); /* Immediate local node address */
  unsigned short    fragment_count    __attribute__((packed)); /* Fragment count */
  unsigned long     fragment_data     __attribute__((packed)); /* Pointer to data fragment */
  unsigned short    fragment_size     __attribute__((packed)); /* Size of data fragment */
} ECB_type;

typedef struct
{
  unsigned short   checksum          __attribute__((packed));   /* Big endian checksum */
  unsigned short   length            __attribute__((packed));   /* Big endian length in bytes */
  unsigned char    transport_control __attribute__((packed));   /* Transport control */
  unsigned char    packet_type       __attribute__((packed));   /* Packet type */
  net_address_type destination       __attribute__((packed));   /* Destination network address */
  net_address_type source            __attribute__((packed));   /* Source network address */
} IPX_header_type;


/* Used internally */
typedef struct
{
  ECB_type        ecb         __attribute__((packed));
  IPX_header_type ipx_header  __attribute__((packed));
  string_type     string      __attribute__((packed));
  double          data1       __attribute__((packed));
  double          data2       __attribute__((packed));
  double          data3       __attribute__((packed));
} packet_type;


/* Generally the user will use this for packets */
typedef struct
{
  double data1;
  double data2;
  double data3;
  string_type string;
  node_address_type source_node;
} game_packet_type;



/* This is used by the pop_packet routines...packets are placed here
   by a callback whenever a packet is recieved by the driver */
typedef struct
{
  game_packet_type    packets[MAX_PACKETS_IN_BUFFER]; /* Array of packets */
  unsigned short      buffer_start; /* The last packet we read */
  unsigned short      buffer_pos;   /* The most recent packet */
} packet_buffer_type;

int Compare_Nodes (node_address_type node_one, node_address_type node_two);
unsigned short Endian_Swap (unsigned short old_short);
int IPX_Open_Socket (unsigned char longetivity, unsigned short *socket_number);
void IPX_Close_Socket (unsigned short *socket_number);
void Get_Local_Address();
void IPX_Send_Packet (ECB_type *ecb);
int IPX_Listen_For_Packet (ECB_type *ecb);
void Im_Idle ();
void Init_Send_Packet (ECB_type *ecb, IPX_header_type *ipx_header, unsigned short size, unsigned short sock);
void Init_Recieve_Packet (ECB_type *ecb, IPX_header_type *ipx_header, unsigned short size, unsigned short sock);
int Init_IPX (void);
//int Jon_Get_Packet (string_type string, double data1, double data2, double data3, node_address_type source_node);


/* These are the functions you will most likely use */

int Init_Jonipx ();
void Close_Jonipx ();
int Packet_Ready ();
int Pop_Packet (game_packet_type *packet);
int Jon_Send_Packet (string_type string, int length, double data1, double data2, double data3, node_address_type dest_node);

/*                                                  */


#endif



--------------C5BC7093B02ED95AD7EBD19E
Content-Type: text/plain; charset=us-ascii;
 name="jonipx.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="jonipx.c"

//carnival overture
#include "jonipx.h"
#include "dosbuff.h"
#include <dpmi.h>
#include <go32.h>
#include <string.h>
#include <dpmi.h>
#include <stdio.h>
#include <stdlib.h> 

/* These are from dosbuff.c...should be done differently!!!! */

extern unsigned short segment_of_dos_buffer, offset_of_dos_buffer;
extern unsigned long address_of_dos_buffer;
extern unsigned long linear_address_of_dos_buffer;

extern unsigned short segment_of_dos_buffer_two, offset_of_dos_buffer_two;
extern unsigned long address_of_dos_buffer_two;
extern unsigned long linear_address_of_dos_buffer_two;

extern unsigned short segment_of_ecb_send_buffer, offset_of_ecb_send_buffer;
extern unsigned long address_of_ecb_send_buffer;
extern unsigned long linear_address_of_ecb_send_buffer;

extern unsigned short segment_of_ecb_recieve_buffer, offset_of_ecb_recieve_buffer;
extern unsigned long address_of_ecb_recieve_buffer;
extern unsigned long linear_address_of_ecb_recieve_buffer;

extern unsigned short segment_of_send_buffer, offset_of_send_buffer;
extern unsigned long address_of_send_buffer;
extern unsigned long linear_address_of_send_buffer;

extern unsigned short segment_of_recieve_buffer, offset_of_recieve_buffer;
extern unsigned long address_of_recieve_buffer;
extern unsigned long linear_address_of_recieve_buffer;

/* End of EXTERNS */

/* Globals */

/* If this is ever true...connection should be terminated
   set in pop_packet */
boolean terminate_connection = FALSE;

local_address_type local_address;

unsigned short socket = MY_SOCKET;
packet_type send_packet, recieve_packet;

unsigned long  address_of_callback;
unsigned short segment_of_callback;
unsigned short offset_of_callback;

_go32_dpmi_registers callback_regs;
_go32_dpmi_seginfo   callback_info;

unsigned long recieve_count = 0;

packet_buffer_type packet_buffer;

/* End of Globals */


/* This function should get called every time a packet is revieved */
void Packet_Recieve_Callback (_go32_dpmi_registers *callback_regs)
{
  int i;

  callback_regs->d.eax = 4; /* Doing this cuz I saw it in the dox */
  recieve_count++;

  /* This should copy the packet into the recieve buffer */
  IPX_Listen_For_Packet (&recieve_packet.ecb);
     
  /* Copy packet from recieve buffer into ipx header and buffer */
  Copy_From_Recieve_Buffer (&recieve_packet.ipx_header, sizeof (IPX_header_type) + sizeof (string_type) + (sizeof(double)*3));

  /* Ignore all packets from ourselves */
  if (!Compare_Nodes (local_address.node_address, recieve_packet.ipx_header.source.node_address))
  {
    /* Copy from there into the packet buffer, we skip the header */
    for (i=0; i < sizeof(string_type); i++)
    {
      packet_buffer.packets[packet_buffer.buffer_pos].string[i] = recieve_packet.string[i];
    }
    packet_buffer.packets[packet_buffer.buffer_pos].data1=recieve_packet.data1;
    packet_buffer.packets[packet_buffer.buffer_pos].data2=recieve_packet.data2;
    packet_buffer.packets[packet_buffer.buffer_pos].data3=recieve_packet.data3;

    for (i = 0; i < sizeof(node_address_type); i++)
      packet_buffer.packets[packet_buffer.buffer_pos].source_node[i] = recieve_packet.ipx_header.source.node_address[i];
	packet_buffer.buffer_pos++;

    if (packet_buffer.buffer_pos >= MAX_PACKETS_IN_BUFFER)
     packet_buffer.buffer_pos = 0;
  }
}


void Allocate_Recieve_Callback (void)
{
  memset (&callback_info, 0, sizeof(_go32_dpmi_seginfo));
  memset (&callback_regs, 0, sizeof(_go32_dpmi_registers));

  callback_info.pm_offset = (unsigned int)Packet_Recieve_Callback;

  _go32_dpmi_allocate_real_mode_callback_retf (&callback_info, &callback_regs);

  segment_of_callback = callback_info.rm_segment;
  offset_of_callback  = callback_info.rm_offset;
  address_of_callback = Make_Far_Pointer (segment_of_callback, offset_of_callback);
}


/* Return 1 if the nodes are the same, 0 if they are not */
int Compare_Nodes( node_address_type node_one, node_address_type node_two )
{
  int i;
  for( i = 0; i < sizeof(node_address_type); i++)
    if( node_one[i] != node_two[i] )
      return(0);
  return(1);
}


unsigned short Endian_Swap (unsigned short old_short)
{
  unsigned short temp_short;
  unsigned short swap_short;
  unsigned char  *char_ptr;
  unsigned char  *char_ptr_two;

  temp_short = old_short;

  char_ptr = (unsigned char *)&temp_short;
  char_ptr_two = (unsigned char *)&swap_short;

  char_ptr_two[0] = char_ptr[1];
  char_ptr_two[1] = char_ptr[0];
     
  return(swap_short);
}


int Init_IPX ()
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.ax = 0x7A00;
  _go32_dpmi_simulate_int (0x2f, &r);

  if (r.h.al != 255)
  {
    /* printf("Error in installing IPX %x \n", r.h.al ); */
    return(0);
  }
     
  Get_Local_Address();
  return(1);
}


void Get_Local_Address()
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));
  memset (&local_address, 0, sizeof(local_address));

  r.x.bx = 0x0009; /* Subfunction 0x0009, get internetwork address */
  r.x.es = segment_of_dos_buffer;
  r.x.si = offset_of_dos_buffer;

  Copy_Into_Dos_Buffer (&local_address, sizeof(local_address));
  _go32_dpmi_simulate_int (0x7a, &r);
  Copy_From_Dos_Buffer (&local_address, sizeof(local_address));

  /* printf("net  %x %x %x %x \n", local_address.net[0], local_address.net[1],local_address.net[2],local_address.net[3] );
  printf("node %x %x %x %x %x %x \n", local_address.node_address[0], local_address.node_address[1],local_address.node_address[2],local_address.node_address[3],local_address.node_address[4],local_address.node_address[5] );*/
}

/*
   Open a socket... 
   longetivity   == 0x00 for open till close or terminate
                 == 0xff for open till close use for tsr
   socket_number == 0 for dynamic allocation
                 == anything else
   returns  0x0  == success
            0xfe == socket table full  
            0xff == socket already open
*/
int IPX_Open_Socket (unsigned char longetivity, unsigned short *socket_number)
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.bx = 0x0000;      /* Function open socket till close or terminate? */
  r.h.al = longetivity;

  r.x.dx = Endian_Swap (*socket_number);

  /* Call the interrupt */
  _go32_dpmi_simulate_int (0x7A, &r);
     
  if (*socket_number == 0x0000)
  *socket_number = Endian_Swap (r.x.dx);

  return (r.h.al);
}


void IPX_Close_Socket (unsigned short *socket_number)
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.bx = 0x0001;
  r.x.dx = Endian_Swap (*socket_number);

  _go32_dpmi_simulate_int (0x7A, &r);
}


void IPX_Send_Packet (ECB_type *ecb)
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.bx = 0x0003; /* Function 3 is send packet? */
  r.x.es = segment_of_ecb_send_buffer;
  r.x.si = offset_of_ecb_send_buffer;

  Copy_Into_Ecb_Send_Buffer (ecb, sizeof(ECB_type));
  _go32_dpmi_simulate_int (0x7a, &r);
  Copy_From_Ecb_Send_Buffer (ecb, sizeof(ECB_type));
}


int IPX_Listen_For_Packet (ECB_type *ecb)
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.bx = 0x0004; /* Subfunction 4 is listen for packet? */
  r.x.es = segment_of_ecb_recieve_buffer;
  r.x.si = offset_of_ecb_recieve_buffer;

  _go32_dpmi_simulate_int (0x7A, &r);
  Copy_From_Ecb_Recieve_Buffer (ecb, sizeof(ECB_type));
    
  return(r.h.al);
}


/* Tell driver we are idle */
void Im_Idle( void )
{
  _go32_dpmi_registers r;

  /* Clear out the registers */
  memset (&r, 0, sizeof(r));

  r.x.bx = 0x000A;

  _go32_dpmi_simulate_int (0x7A, &r);
}


/* Initialize all the basic shizit we need to send packets...store the
   pointer to memory where we will put packets */
void Init_Send_Packet (ECB_type *ecb, IPX_header_type *ipx_header, unsigned short size, unsigned short sock)
{
  int i;

  memset (ipx_header, 0, sizeof (IPX_header_type));
  memset (ecb, 0, sizeof (ECB_type));
    
  ecb->socket           = Endian_Swap (sock);   /* Big endian socket number */
  ecb->fragment_count   = 1;                     /* Fragment count?? */
  ecb->ESR              = NULL;

  /* Pointer to data fragment(ipx header) */
  ecb->fragment_data = address_of_send_buffer;
     
  ecb->fragment_size = sizeof (IPX_header_type) + size;
     
  for (i=0; i < 6; i++)
    ecb->immediate_address[i] = 0xff; /* Broadcast */
    
  ipx_header->checksum    = 0xffff; /* No checksum */
  ipx_header->packet_type = 0;    /* Packet exchange packet */
     
  for (i=0; i < 4; i++ )
    ipx_header->destination.net[i] = local_address.net[i]; /* Send to this network */

  for (i=0; i < 6; i++)
    ipx_header->destination.node_address[i] = 0xff; /* Send to everybody! */

  /* USE A DEFINE FOR THE WRITE SOCKET!!! */
  ipx_header->destination.socket = Endian_Swap (sock); /* Send to my socket */
     
  for (i=0; i < 4; i++)
    ipx_header->source.net[i] = local_address.net[i];

  for (i=0; i < 6; i++)
    ipx_header->source.node_address[i] = local_address.node_address[i]; /* From me */

  ipx_header->source.socket = Endian_Swap (sock);  /* From my socket */
}


/* Initialize all the basic shizit we need to recieve packets...store the
   pointer to memory where we will put packets */
void Init_Recieve_Packet (ECB_type *ecb, IPX_header_type *ipx_header, unsigned short size, unsigned short sock)
{
  int error_code;

  memset (ecb, 0, sizeof (ECB_type));
  memset (ipx_header, 0, sizeof (IPX_header_type));

  ecb->in_use           = 0x1D;  /* ?? */
  ecb->socket           = Endian_Swap (sock);
  ecb->fragment_count   = 1;

  /* Set a real mode callback for my ESR function */
  Allocate_Recieve_Callback();

  ecb->ESR              = address_of_callback;
  ecb->fragment_data    = address_of_recieve_buffer;
  ecb->fragment_size    = sizeof (IPX_header_type) + size;

  Copy_Into_Recieve_Buffer (ipx_header, sizeof (IPX_header_type) + size);
  Copy_Into_Ecb_Recieve_Buffer (ecb, sizeof(ECB_type));

  if ((error_code = IPX_Listen_For_Packet(ecb)) == 0xFF)
  {
    /* printf("Error in listen for packet function (in init recieve) 0x%x \n", error_code); */
    exit(0);
  }
  Copy_From_Recieve_Buffer (ipx_header, sizeof (IPX_header_type) + size);
}


int Init_Jonipx ()
{
  int temp_int;
  int i;

  if (!Init_IPX())
  {
    /* printf("No IPX driver detected! \n"); */
    return(0);
  }

  /* printf("Opening socket at %x!! \n", socket); */

  /* longetivity == 0x00 for open till close or terminate , 0xff for open till close */
  if ((temp_int = IPX_Open_Socket (0x00, &socket)))
  {
    /* printf("Error 0x%x opening socket \n", temp_int ); */
    return(0);
  }

  for (i = 0; i < sizeof (string_type); i++)
    send_packet.string[i] = '\0';
  send_packet.data1=0.0;
  send_packet.data2=0.0;
  send_packet.data3=0.0;
  Init_Send_Packet (&send_packet.ecb, &send_packet.ipx_header, sizeof (string_type) + (sizeof(double)*3), socket);

  Copy_Into_Send_Buffer (&send_packet.ipx_header, sizeof (IPX_header_type));
  Copy_Into_Ecb_Send_Buffer (&send_packet.ecb, sizeof (ECB_type));

  Init_Recieve_Packet (&recieve_packet.ecb, &recieve_packet.ipx_header, sizeof (string_type) + (sizeof(double)*3), socket);

  packet_buffer.buffer_pos = 0;
  packet_buffer.buffer_start = 0;

  return(1);
}


/*int Jon_Get_Packet (string_type string, double data1, double data2, double data3, node_address_type source_node)
{
  int i;
  int from_local = 1; /* Is this packet from the local computer? */

  /*Im_Idle();

  Copy_From_Ecb_Recieve_Buffer (&recieve_packet.ecb, sizeof(ECB_type));

  if (recieve_packet.ecb.in_use == 0)
  {
    Copy_From_Recieve_Buffer (&recieve_packet.ipx_header, sizeof (IPX_header_type) + sizeof (string_type) + (sizeof(double)*3));
	/*
    fprintf(stderr,"recieving");
    fprintf(stderr, "%s", recieve_packet.string );
    */
	/*if (IPX_Listen_For_Packet (&recieve_packet.ecb))
    {
      /* printf("Error in loop listening for packets... \n"); */
      /*exit(0);
    }
    Copy_From_Recieve_Buffer (&recieve_packet.ipx_header, sizeof (IPX_header_type) + sizeof (string_type) + (sizeof(double)*3));

    /* Ignore stuff that I sent */
    /*for (i = 0; i < 6; i++)
      if (recieve_packet.ipx_header.source.node_address[i] != local_address.node_address[i])
        from_local = 0;

	/* Copy the source node address of the packet */
    /*for (i = 0; i < 6; i++)
      source_node[i] = recieve_packet.ipx_header.source.node_address[i];

	if (from_local)
	  return(0);

    for (i = 0; i < sizeof(string_type); i++)
      string[i] = recieve_packet.string[i];
	data1=recieve_packet.data1;
	data2=recieve_packet.data2;
	data3=recieve_packet.data3;
	return(1);
  }
  else
  return(0);
}*/


int Jon_Send_Packet (string_type string, int length, double data1, double data2, double data3, node_address_type dest_node)
{
  int i;
  Im_Idle();
  Copy_From_Ecb_Send_Buffer (&send_packet.ecb, sizeof(ECB_type));
  for (i = 0; i < 6; i++)
    send_packet.ecb.immediate_address[i] = dest_node[i]; /* 0xff; */ /* Broadcast */
  for( i = 0; i < 6; i++ )
    send_packet.ipx_header.destination.node_address[i] = dest_node[i]; /* 0xff; */ /* Broadcast */
  for (i = 0; i < length; i++)
    send_packet.string[i] = string[i];
  send_packet.data1=data1;
  send_packet.data2=data2;
  send_packet.data3=data3;
  Copy_Into_Send_Buffer (&send_packet.ipx_header, sizeof (IPX_header_type) + sizeof (string_type) + (sizeof(double)*3));
  IPX_Send_Packet (&send_packet.ecb);
  Im_Idle(); /* HACK?? */
  delay (IPX_DELAY);
  return(1);
}


void Close_Jonipx (void)
{
  /* printf("Closing socket \n"); */
  IPX_Close_Socket (&socket);
}


/* Is there a packet ready in the packet buffer? */
int Packet_Ready (void)
{
  if (packet_buffer.buffer_start != packet_buffer.buffer_pos)
    return(1);
  else
    return(0);
}


/* Copy the next available packet into string */
int Pop_Packet (game_packet_type *packet)
{
  int i;

  if (!Packet_Ready())
    return(0);

  for (i=0; i < sizeof(string_type); i++)
    packet->string[i] = packet_buffer.packets[packet_buffer.buffer_start].string[i];

  packet->data1=packet_buffer.packets[packet_buffer.buffer_start].data1;
  packet->data2=packet_buffer.packets[packet_buffer.buffer_start].data2;
  packet->data3=packet_buffer.packets[packet_buffer.buffer_start].data3;

  for (i = 0; i < sizeof(node_address_type); i++)
    packet->source_node[i] = packet_buffer.packets[packet_buffer.buffer_start].source_node[i];

  packet_buffer.buffer_start++;

  if (packet_buffer.buffer_start >= MAX_PACKETS_IN_BUFFER)
    packet_buffer.buffer_start = 0;

  return(1);
}

--------------C5BC7093B02ED95AD7EBD19E
Content-Type: text/plain; charset=us-ascii;
 name="DOSBUFF.H"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="DOSBUFF.H"

#ifndef DOSBUFF_H
#define DOSBUFF_H

#define DOS_BUFFER_SIZE 200 /* 300 bytes */
#define DOS_BUFFER_TEST 100 /* The amount we REALLY need for the dos buffer */

void Allocate_Dos_Buffers (void);
void Copy_Into_Dos_Buffer (void *block, short length);
void Copy_From_Dos_Buffer (void *block, short length);
void Copy_Into_Dos_Buffer_Two (void *block, short length);
void Copy_From_Dos_Buffer_Two (void *block, short length);
void Copy_Into_Send_Buffer (void *block, short length);
void Copy_From_Send_Buffer (void *block, short length);
void Copy_Into_Recieve_Buffer (void *block, short length);
void Copy_From_Recieve_Buffer (void *block, short length);
void Copy_Into_Ecb_Send_Buffer (void *block, short length);
void Copy_From_Ecb_Send_Buffer (void *block, short length);
void Copy_Into_Ecb_Recieve_Buffer (void *block, short length);
void Copy_From_Ecb_Recieve_Buffer (void *block, short length);
void Test_Dos_Buffers (void);
unsigned long Make_Far_Pointer (unsigned short segment, unsigned short offset);

#endif


--------------C5BC7093B02ED95AD7EBD19E--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019