Mail Archives: djgpp/1998/01/17/00:16:21
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 <dos.h>
#include <memory.h>
#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 );
}
- Raw text -