www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/04/02/09:53:37

From: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
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 <stdio.h>
AB #include <std.h>
AB #include <pc.h>
AB #include <dos.h>
AB #include <dpmi.h>
AB #include <go32.h>
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);}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019