From: "A.Appleyard" To: DJGPP AT DELORIE DOT COM Date: Tue, 2 Apr 1996 15:46:27 GMT Subject: Odd happenings with an interrupt Message-ID: <1DC6EB3C23@fs2.mt.umist.ac.uk> This is a comparative listing of 2 Gnu C++ programs. They both call the interrupt "AX=4F01, int10" to get full information about the screen mode CX. Of these programs, B works, but A always divide-overflows in the interrupt routine and exits to DOS leaving the stack pointers in a mess so that (unless I re-boot at once) the next program call jams the computer solid. What on earth's going on!?!?!? I have a 486 with DOS 6.22, and djgpp v1. AB #include AB #include AB #include AB #include AB #include AB #include AB /*-----*/ AB #define uns unsigned B #define reg register A AB #define pk __attribute__((packed)) B typedef uns long ul; B typedef uns short us; A B typedef uns char byte; A A #define byte unsigned char AB #define Regs _go32_dpmi_registers AB Regs R; AB #define Int int86dpmi B /*-----*//* with thanks to Eli Zaretski */ A /*-----*/ AB /* Simulate a software interrupt from protected mode. Like int86() but calls AB DPMI services and so doesn't need DOS extender, only a DPMI server. */ AB int int86dpmi(int intno) {REGS r,s; Regs S; S=R; AB S.x.ss=S.x.sp=0; /* DPMI server is to provide stack for interrupt call */ AB S.x.flags=0; /* he likeliest forgot to zero the flags */ AB /* I replaced the call of _go32_dpmi_simulate_int() by a copy of its body here*/ AB r.h.bl=intno; r.h.bh=0; r.x.cx=0; r.x.di=(int)&S; AB if(intno==0x21 && S.x.ax==0x4b00) { /* call a child process */ AB r.x.ax=0xff0a; int86(0x21,&r,&s);} AB else {r.x.ax=0x0300; int86(0x31,&r,&s);} B R=S; return R.d.eax;} B /*-----*/ B #define SEL _go32_info_block.selector_for_linear_memory B #define TBaddr _go32_info_block.linear_address_of_transfer_buffer B #define segoff(x,y,z) ((x)=(z)>>4,(y)=(z)&15) A R=S; return R.x.ax;} A A A A AB /*-----*//* conventional memory:- */ AB class c_mem {public: _go32_dpmi_seginfo x; AB inline c_mem(int nbytes){x.size=nbytes; _go32_dpmi_allocate_dos_memory(&x);}; AB inline segof(uns short&s,uns short&o){s=x.rm_segment; o=x.rm_offset;}; AB inline ~c_mem(){_go32_dpmi_free_dos_memory(&x);};}; B /* typedef struct {uns long size, pm_offset; B uns short pm_selector, rm_offset, rm_segment;} _go32_dpmi_seginfo; */; A /* typedef struct { u_long size, pm_offset; A u_short pm_selector, rm_offset, rm_segment; } _go32_dpmi_seginfo; */ AB /*-----*//* structure of the buffer returned by `AX=4f01, int10' */ AB typedef struct modeinfo {short modeattr pk; byte waattr,wbattr pk; AB short wgran,wsize,waseg,wbseg pk; long farwposfn pk; AB short bytesperline,wide,high pk; AB byte cwide,chigh,nplanes,bitsperpixel,nbanks,memmod,banksize,npages,res1, AB redsize,redpos,greensize,greenpos,bluesize,bluepos,ressize,respos,dircolor pk; AB void pr(FILE*F){fprintf(F," %4d %3d %3d %4d %4d %04x %04x %08lx \ AB %4d %4d %4d %3d %3d %3d %3d %3d %4s %3d %3d %3d \ AB %3d %3d %3d %3d %3d %3d %3d %3d %3d\n", AB modeattr,waattr,wbattr,wgran,wsize,(uns short)waseg,(uns short)wbseg, AB farwposfn,bytesperline,wide,high,cwide,chigh,nplanes,bitsperpixel,nbanks, AB ((char*[]){"text","cga","hgc","16cl","pkpx","s256","dirc","yuv"})[memmod], AB banksize,npages,res1,redsize,redpos,greensize,greenpos,bluesize,bluepos, AB ressize,respos,dircolor);}; AB }; B /*-----*/ B FILE*M; B /*-----*/ B void minfo(int mode){c_mem buf(256); modeinfo m; A int getinfo(modeinfo&M,int mode) {c_mem buf(256); int i=1; modeinfo m; AB R.x.ax=0x4f01; R.x.cx=mode; buf.segof(R.x.es,R.x.di); Int(0x10); B if((R.x.ax&255)!=0x4f) return; B dosmemget(buf.x.rm_segment*16+buf.x.rm_offset,40,&m); B if(!(m.modeattr&1)) return; B fprintf(M,"%3x:",mode); m.pr(M);} A if((R.x.ax&255)!=0x4f) i=0; else if(R.x.ax&0xff00) i=0; A else dosmemget(buf.x.rm_segment*16+buf.x.rm_offset,sizeof(modeinfo),&m); A M=m; return i&&(M.modeattr&1);}; A modeinfo M; AB /*-----*/ B main(){M=fopen("t$$modes","w"); int i; for(i=0;i<128;i++) minfo(i); B fclose(M);} A main(){int i,mode; A for(i=0;i<256;i++) if(getinfo(M,i)) printf("mode %04x exists\n",i); A FILE*F=fopen("t$qaz","w"); printf("mode?"); scanf("%x",&mode); A fclose(F);}