From: "A.Appleyard" To: DJGPP AT delorie DOT com Date: Wed, 3 Apr 1996 15:07:00 GMT Subject: Re: Odd happenings with an interrupt Message-ID: <351FFC45EA@fs2.mt.umist.ac.uk> I have gcc-2.6.0 gas-2.3 libg++-2.6.0 1.12.maint2 binutils 2.4 I may have tracked my interrupt funny to its lair:- #include #include #include #include #include #include /*-----*/ #define uns unsigned #define reg register #define pk __attribute__((packed)) typedef uns long ul; typedef uns short us; typedef uns char byte; #define Regs _go32_dpmi_registers Regs R; #define Int int86dpmi /*-----*//* with thanks to Eli Zaretski */ /* Simulate a software interrupt from protected mode. Like int86() but calls DPMI services and so doesn't need DOS extender, only a DPMI server. */ int int86dpmi(int intno) {REGS r,s; Regs S; S=R; S.x.ss=S.x.sp=0; /* DPMI server is to provide stack for interrupt call */ S.x.flags=0; /* he likeliest forgot to zero the flags */ /* I replaced the call of _go32_dpmi_simulate_int() by a copy of its body here*/ r.h.bl=intno; r.h.bh=0; r.x.cx=0; r.x.di=(int)&S; if(intno==0x21 && S.x.ax==0x4b00) { /* call a child process */ r.x.ax=0xff0a; int86(0x21,&r,&s);} else {r.x.ax=0x0300; int86(0x31,&r,&s);} R=S; return R.d.eax;} /*-----*//* conventional memory:- */ class c_mem {public: _go32_dpmi_seginfo x; inline c_mem(int nbytes){x.size=nbytes; _go32_dpmi_allocate_dos_memory(&x);}; inline segof(uns short&s,uns short&o){s=x.rm_segment; o=x.rm_offset;}; inline ~c_mem(){_go32_dpmi_free_dos_memory(&x);};}; /* typedef struct {uns long size, pm_offset; uns short pm_selector, rm_offset, rm_segment;} _go32_dpmi_seginfo; */; /*-----*//* structure of the buffer returned by `AX=4f01, int10' */ typedef struct modeinfo {short modeattr pk; byte waattr,wbattr pk; short wgran,wsize,waseg,wbseg pk; long farwposfn pk; short bytesperline,wide,high pk; byte cwide,chigh,nplanes,bitsperpixel,nbanks,memmod,banksize,npages,res1, redsize,redpos,greensize,greenpos,bluesize,bluepos,ressize,respos,dircolor pk; void pr(FILE*F){fprintf(F," %4d %3d %3d %4d %4d %04x %04x %08lx \ %4d %4d %4d %3d %3d %3d %3d %3d %4s %3d %3d %3d \ %3d %3d %3d %3d %3d %3d %3d %3d %3d\n", modeattr,waattr,wbattr,wgran,wsize,(uns short)waseg,(uns short)wbseg, farwposfn,bytesperline,wide,high,cwide,chigh,nplanes,bitsperpixel,nbanks, ((char*[]){"text","cga","hgc","16cl","pkpx","s256","dirc","yuv"})[memmod], banksize,npages,res1,redsize,redpos,greensize,greenpos,bluesize,bluepos, ressize,respos,dircolor);}; }; /*-----*/ FILE*M; /*-----*/ int getinfo(int mode){c_mem buf(256); modeinfo m; R.x.ax=0x4f01; R.x.cx=mode; buf.segof(R.x.es,R.x.di); Int(0x10); if((R.x.ax&255)!=0x4f) return 0; // if(R.x.ax&0xff00) return 0; dosmemget(buf.x.rm_segment*16+buf.x.rm_offset,40,&m); if(!(m.modeattr&1)) return 0; /* fprintf(M,"%3x:",mode); m.pr(M); */ return 1;} /*-----*/ main(){M=fopen("t$$mode4","w"); int i; for(i=0;i<128;i++) getinfo(i); fclose(M); for(i=0;i<128;i++) if(getinfo(i)) ;//printf("mode %04x exists\n",i); int mode; FILE*F=fopen("t$qaz","w"); printf("mode?"); scanf("%x",&mode); fclose(F);} As quoted, this program fails "Divide error" during the interrupt routine and exits to the DOS prompt leaving the stacks funny. But if I remove `for(i=0;i<128;i++) getinfo(i); fclose(M);', the program runs OK. Each call of the function getinfo should _go32_dpmi_allocate_dos_memory 256 bytes of conventional memory on entry (by the class c_mem constructor), and release it all on exit (by the class c_mem destructor). It seems that doing that too many times in one program run messes up the conventional memory heap. Why is that? Surely getting and then releasing 256 bytes of conventional memory should leave the conventional memory and all pointers to it as they were before?