From: "Don Duttweiler" Newsgroups: comp.os.msdos.djgpp Subject: Two real address in __dpmi_int call Lines: 159 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1106 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Message-ID: Date: Wed, 3 Sep 2003 09:44:40 -0700 NNTP-Posting-Host: 68.7.59.216 X-Complaints-To: abuse AT cox DOT net X-Trace: fed1read01 1062607479 68.7.59.216 (Wed, 03 Sep 2003 12:44:39 EDT) NNTP-Posting-Date: Wed, 03 Sep 2003 12:44:39 EDT Organization: Cox Communications To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com I can not get the extended BIOS read interrupt (function 0x42 under interrupt 0x13) to work under DJGPP. This interrupt is a bit more of a mess than usual because two real-mode addresses are involved. One is the usual offset and segment of a structure passed to the interrupt via __dpmi_regs. But for this interrupt, this structure itself contains an offset and segment for a buffer that is used for storing what is read from disk. My basic approach for this has been to use one region of __tb for passing the structure to the real mode interrupt and another region of __tb for the disk read buffer. It doesn't work. Whether executing from a DOS box or executing in DOS mode, the program hangs on the call to __dpmi_int. Two program listings are below. The one titled realmode.c I compile with Microsoft C 6.0 (a 16 bit compiler) and it runs fine. (The interrupt itself does require a newer BIOS with LBA extensions.) The one titled dpmimode.c is my translation of realmode.c to a protected mode program to compile under DJGPP. As noted above it hangs on the call to __dpmi_int. I've tried zeroing some of the unused registers in __dpmi_regs as suggested in section 18.3 of the FAQ. That doesn't seem to make any difference. I've also tried using __dpmi_allocate_dos_memory to get some real-mode memory for the read buffer, but that also doesn't seem to help. I'm running Win 98 SE and compiling with GCC 3.0.2, but doubt that is of any consequence for this. Does anyone have any ideas on how to fix things? Thanks. Don Duttweiler duttweilerATstanfordalumniDOTorg ******** realmode.c ********************************************************* #include #include #include #include #include int main(int argc,char** argv) { char far * buffer; union REGS inregs, outregs; struct SREGS segregs; unsigned char mysize; int drive; #pragma pack(1) struct { unsigned char mysize; unsigned char reserved; unsigned short blockCount; unsigned short bufAdrOffset; unsigned short bufAdrSeg; unsigned long lbaLow; unsigned long lbaHigh; } bufAdr, far *pbufAdr; #pragma pack() if(argc!=1) { fprintf(stderr,"Unexpected count: %d in %s",argc,argv[0]); exit(1); } mysize = sizeof(bufAdr); if(mysize != 16) { fprintf(stderr,"Unexpected size: %d",mysize); exit(1); } buffer = _fmalloc(512); drive = 128; bufAdr.mysize = mysize; bufAdr.blockCount = 1; bufAdr.bufAdrOffset = FP_OFF(buffer); bufAdr.bufAdrSeg = FP_SEG(buffer); bufAdr.lbaLow = 0; bufAdr.lbaHigh = 0; pbufAdr = &bufAdr; inregs.h.ah = 0x42; inregs.h.dl = (char)drive; inregs.x.si = FP_OFF(pbufAdr); segregs.ds = FP_SEG(pbufAdr); int86x(0x13, &inregs, &outregs, &segregs); if((outregs.x.cflag == 0) && (outregs.h.ah == 0)) { printf("Good execution\n"); } else { printf("Bad execution\n"); } return 0; } ******** dpmimode.c ********************************************************** #include #include #include #include #include #include #include int main(int argc,char **argv) { __dpmi_regs dreg; char* buffer; int cflag,drive; unsigned char mysize; struct { unsigned char mysize; unsigned char reserved; unsigned short blockCount; unsigned short bufAdrOffset; unsigned short bufAdrSeg; unsigned long lbaLow; unsigned long lbaHigh; } __attribute__ ((packed)) bufAdr; if(argc!=1) { fprintf(stderr,"Unexpected count %d in %s",argc,argv[0]); exit(1); } mysize = sizeof(bufAdr); if(mysize != 16) { fprintf(stderr,"Unexpected size: %d",mysize); exit(1); } buffer = malloc(512); drive = 128; bufAdr.mysize = mysize; bufAdr.blockCount = 1; bufAdr.bufAdr.fset = __tb & 0x0F; bufAdr.bufAdrSeg = (__tb + 1024) >> 4; bufAdr.lbaLow = 0; bufAdr.lbaHigh = 0; dreg.h.ah = 0x42; dreg.h.dl = (char)drive; dreg.x.si = __tb & 0x0F; dreg.x.ds = __tb >> 4; dosmemput(&bufAdr,mysize,__tb); printf("Calling __dpmi_int\n"); fflush(stdout); __dpmi_int(0x13,&dreg); printf("Returned __dpmi_int\n"); fflush(stdout); cflag = dreg.x.flags & 0x01; if((cflag == 0) && (dreg.h.ah == 0)) { printf("Good execution\n"); } else { printf("Bad execution\n"); } dosmemget(__tb+1024,512,buffer); return 0; }