Message-ID: <38E8E68C.88C17E8B@hotmail.com> From: Andrew Hakman 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: Content-Type: multipart/mixed; boundary="------------C5BC7093B02ED95AD7EBD19E" 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 #include #include #include #include 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 /* 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 #include #include #include #include #include /* 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--