From: nikki AT gameboutique DOT co (nikki) Newsgroups: comp.os.msdos.djgpp Subject: Re: weird dosmemput problem Date: 4 Mar 1997 18:06:57 GMT Organization: GameBoutique Ltd. Message-ID: <5fhoc1$qj1@flex.uunet.pipex.com> References: NNTP-Posting-Host: www.gameboutique.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Lines: 150 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp > 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 #include #include #include #include #include #include #include #include #include #include #include #include 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