Mail Archives: djgpp/1997/03/04/15:04:09
> The snippet as it is shown seems perfectly OK to me. So it probably is
> something else that causes the problems. Can you post a short program
> that uses this snippet and bombs?
ok, i'm not sure i can create a short snippet so i'll edit a long one and try
to make it short ;) the problem might be caused by something unrelated to
the dosmemput part, but it seems strange that the entire program functions
just fine with this commented out. both buffers are sufficient size, yet
it seems to be copying too many bytes or something.
the program calls test_pktdrv and sets everything up correctly. it transmits
the packet correctly. i get a reply correctly. the machine hangs. not correct ;)
the problem appears to be related to doing things with the dos memory as the
errors are non-djgpp related (ie emm errors as opposed to sigsegv problems)
i've marked the 2 most suspect lines with /// !!!'s
regards,
nik
---
#include <dpmi.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <go32.h>
#include <malloc.h>
#include <dos.h>
#include <sys/movedata.h>
#include <sys/nearptr.h>
#include <string.h>
#include <math.h>
#include <conio.h>
#include <crt0.h>
int _crt0_startup_flags = _CRT0_FLAG_NEARPTR | _CRT0_FLAG_NONMOVE_SBRK | _CRT0_FLAG_LOCK_MEMORY;
#include "global.h"
static struct {
unsigned char irq;
unsigned short version;
unsigned char class;
unsigned short type;
unsigned char number;
unsigned char func;
unsigned int error;
unsigned short handle;
unsigned char address[8];
} pktdrv;
static __dpmi_regs callback_regs;
static _go32_dpmi_seginfo callback_info;
static _go32_dpmi_seginfo pktbuf;
static _go32_dpmi_seginfo pktout;
static _go32_dpmi_registers regs;
void pkt_receiver(__dpmi_regs *r)
{
if (callback_regs.x.ax==0) {
if (callback_regs.x.cx>16384L) {
callback_regs.x.es=0;
callback_regs.x.di=0; // frame is >16k! too long so discard
}
else {
callback_regs.x.es=pktbuf.rm_segment;
callback_regs.x.di=0;
// tell them to stick it in our buffer
}
}
}
void send_pkt(unsigned short length)
{
int retries=5;
while (retries--) {
regs.x.ax=0x400;
regs.x.ds=pktout.rm_segment;
regs.x.es=pktout.rm_segment; // buggy drivers need es:
regs.x.si=0;
regs.x.cx=length;
_go32_dpmi_simulate_int(pktdrv.irq,®s);
// !!! after the above line we get a reply (almost instant) hence
// pkt_receiver is called. the machine now hangs, reboots or dies
// due to memory corruption (emm errors etc)
if (!(regs.x.flags & 1)) break;
}
if (regs.x.flags & 1) printf("failed\n");
else printf("sent\n");
}
void ARP()
{
unsigned char arpbuf[64];
.. a packet gets formed in the buffer (snipped)
dosmemput(arpbuf,60,pktout.rm_segment*16);
// !!! THE ABOVE LINE CAUSES THE PROBLEM !!!
send_pkt(60);
}
unsigned short access_type(unsigned char if_class,unsigned short if_type,unsigned char if_number,unsigned int type,un
{
__dpmi_regs r;
// setup callback to pkt_receiver and get dos memory for buffers
callback_info.pm_offset = (unsigned int)pkt_receiver;
_go32_dpmi_allocate_real_mode_callback_retf(&callback_info,&callback_regs);
r.h.al=if_class;
r.h.ah=2;
r.x.bx=if_type;
r.h.dl=if_number;
r.x.cx=typelen;
r.x.es=callback_info.rm_segment;
r.x.di=callback_info.rm_offset;
__dpmi_int(pktdrv.irq,&r);
if (r.x.flags & 1) {
pktdrv.error=r.h.dh;
return(0);
}
pktbuf.size=(16*1024L+15)/16;
_go32_dpmi_allocate_dos_memory(&pktbuf);
pktout.size=(16*1024L+15)/16;
_go32_dpmi_allocate_dos_memory(&pktout);
return(r.x.ax);
}
void test_pktdrv()
{
unsigned long acl;
if (!(pktdrv.handle=access_type(1,0xffff,0,NULL,0))) return;
// set up a callback to receiver function for incoming data
ARP();
for (;;) {
acl=uclock();
while (uclock()-acl<10*UCLOCKS_PER_SEC);
// call ARP() every 10 seconds
ARP();
if (kbhit()!=0) break;
}
}
--
Graham Tootell
nikki AT gameboutique DOT com
- Raw text -