From: "Glynne Casteel" Newsgroups: comp.os.msdos.djgpp Subject: Re: Anyone use Btrieve with DJGPP? Date: Fri, 16 Jan 1998 21:56:46 -0700 Organization: Netcom Lines: 162 Message-ID: <69pdrr$11p@sjx-ixn11.ix.netcom.com> References: <34be3ba4 DOT 87807333 AT news DOT mci2000 DOT com> NNTP-Posting-Host: den-co34-18.ix.netcom.com To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk Bryce wrote in message <34be3ba4 DOT 87807333 AT news DOT mci2000 DOT com>... >Hi, > We've got a 16 bit DOS kit for Btrieve and I was just wondering if >there is any way possible that I could use it with DJGPP. I've got >asm source for communicating with btrieve but it appears that it would >not be compatible since it is appears to be addressing 16 bit >registers using segment and offset. Is this so? > >Anyone done anything like this? > >Does the 32bit exteneder kill this idea? > >Thanks for any help. Once you install the Btrieve TSR or DLL on your workstation, I believe all you have to do is generate a DOS interrupt 0x7B. Sometimes, Btrieve is hooked to another interrupt, but I can't recall which one (there is a command-line tool that comes with Btrieve that can tell you). Here is some C source that I found several years ago that will help (it may need to be modified to work with DJGPP): /*************************************************************************** * * * This is a small fast interface I use for BASIC PDS 7.0 near strings and * C/C++ in medium model. It handles the position blocks in the interface * thus freeing near memory and reducing the amount of data passed on the stack. * I have been using it for 2 years now and it seend abount 20% faster than the * standard version. Any comments readily recieved. * * * MicroSoft Basic Interface to the Btrieve Record Manager * * For Use with Basic PDS 7.xx NEAR STRINGS * Also C in medium model. * * (c) Clifford Wetherall 1993 * CIS: 100433,3363 * **************************************************************************** / #include #include #define BTR_ERR 20 // record manager not started #define BTR_INT 0x7B // Btrieve interrupt vector #define BTR_VECTOR BTR_INT * 4 // offset for interrupt #define BTR_OFFSET 0x33 // Btrieve offset within segment #define VARIABLE_ID 0x6176 // id for variable length records - 'va' #define MAX_POS_BLOCKS 13 // Maximum position block to store static char cVSet= 0; // flag set to true if checked version static char far ppBlock[MAX_POS_BLOCKS][128]; static char far pBlockUsed[MAX_POS_BLOCKS]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //static char far ppBlock[6][128]; //static char far pBlockUsed[6]= {0, 0, 0, 0, 0, 0}; int far pascal BTRV( int *pnOp, int *pnPosBlock, unsigned int *puBuffer, int *pnDataLen, unsigned int *puKey, int *pnKeyNumber ) { union REGS sRegs; struct SREGS sSregs; struct BTRIEVE_PARMS // structure passed to Btrieve Record Manager { char *pcBufferOffset; // callers data buffer offset int nBufferSeg; // callers data buffer segment int nBufferLen; // length of data buffer char *pcCurrentOffset; // user position block offset int nCurrentSeg; // user position block segment char *pcFcbOffset; // offset of disk FCB int nFcbSeg; // segment of disk FCB int nFxn; // requested function char *pcKeyOffset; // offset of user's key buffer int nKeySeg; // segment of user's key buffer unsigned char ucKeyLen; // length of user's key buffer char cKeyNumber; // key of reference for request int *pnStatusOffset; // offset of status word int nStatusSeg; // segment of status word int nLanguageID; // language identifier } sXData; int nRc= 0; // status of Btrieve call int i; int nActualPosBlock= pnPosBlock[0]; char pcTempBuffer[128]; // If open on an already open posblock return OK if( pnOp[0] == 0 ) { if( pBlockUsed[nActualPosBlock] ) return( nRc ); } // Check to see that the Btrieve Record Manager has been started. if( !cVSet ) // if we don't know version of Btrieve yet { cVSet= 1; // check dos version sRegs.x.ax= 0x3000; int86x( 0x21, &sRegs, &sRegs, &sSregs ); } // Read segment registers and initialize segment part of addresses to // user's data segment. segread( &sSregs ); sXData.nBufferSeg= sXData.nCurrentSeg= sXData.nFcbSeg= sXData.nKeySeg= sXData.nStatusSeg= sSregs.ss; // Move user parameters to sXData, the block where Btrieve expects them. _fmemcpy( pcTempBuffer, ppBlock[nActualPosBlock], 128 ); sXData.nFxn= pnOp[0]; sXData.pnStatusOffset= &nRc; sXData.pcFcbOffset= &pcTempBuffer[0]; sXData.pcCurrentOffset= &pcTempBuffer[38]; sXData.pcBufferOffset= (unsigned char *)puBuffer[0]; sXData.nBufferLen= pnDataLen[0]; sXData.pcKeyOffset= (unsigned char *)puKey[0]; sXData.ucKeyLen= 255; // use max since we don't know sXData.cKeyNumber= pnKeyNumber[0]; sXData.nLanguageID= VARIABLE_ID; // Make call to the Btrieve Record Manager. sRegs.x.dx= (int)&sXData; // parameter block is expected to be in DX sSregs.ds= sSregs.ss; int86x( BTR_INT, &sRegs, &sRegs, &sSregs ); pnDataLen[0]= sXData.nBufferLen; _fmemcpy( ppBlock[nActualPosBlock], pcTempBuffer, 128 ); switch( pnOp[0] ) { case 0: pBlockUsed[nActualPosBlock]= 1; break; case 1: pBlockUsed[nActualPosBlock]= 0; break; case 28: for( i= 0; i < 14; i++) pBlockUsed[i]= 0; break; default: break; } return( nRc ); } /*********************************/ int main( int nArgc, char *pszArgv[] ) { int i, nRc; int nOp, nPosBlock, nDataLen, nKeyNumber; unsigned puBuffer[200], uKey; nOp= nPosBlock= nDataLen= nKeyNumber= uKey= 1; for( i=0 ; i<=sizeof(puBuffer)/sizeof(puBuffer[0]) ; i++ ) { puBuffer[i]= 5*(i+1); } nRc= BTRV( &nOp, &nPosBlock, puBuffer, &nDataLen, &uKey, &nKeyNumber ); return( nRc ); }