home *** CD-ROM | disk | FTP | other *** search
- .XLIST
- PAGE 60,132
- TITLE Btrieve Record Manager, Copyright (c) 1982 SoftCraft, Inc.
- SUBTTL QB6XBTRV - Interface to MS Quick Basic 6.0
- PAGE
- .LIST
- ;-----------------------------------------------------------------
- ;BC7XBTRV
- ; This routine interfaces between compiled Microsoft Basic 7.0 programs
- ; and Btrieve on PC-DOS machines.
- ;
- ; Calling Procedure from basic for far data pointers:
- ; CALL BTRVFAR(FUNCTION, STATUS, POSITION BLOCK, DATA BUFFER OFFSET,
- ; DATA BUFFER SEGMENT, DATALEN, KEY.VALUE, KEY.NUMBER)
- ; where
- ; FUNCTION - function number for request
- ; STATUS - return status from request
- ; POSITION.BLOCK - 128 byte data area for FCB and positioning
- ; DATA BUFFER OFFSET - offset of data buffer
- ; DATA BUFFER SEGMENT - segment address of data buffer
- ; DATALEN - length of user data buffer
- ; KEY.VALUE - string pointer to key buffer
- ; KEY.NUMBER - key number to be processed
- ;-----------------------------------------------------------------
- ;
- PUBLIC BTRVFAR
- ;
- INCLUDE OS.INC ;include file to determine OS
- extrn StringAddress: far ;for bc7
- extrn StringLength: far ;for bc7
- ;
- ;
- PARM_OFF = 20
- ;
- FUNCTION = PARM_OFF + 14
- STATUS = PARM_OFF + 12
- POS_BLK = PARM_OFF + 10
- FILE_OFF = PARM_OFF + 8
- FILE_SEG = PARM_OFF + 6
- DATALEN = PARM_OFF + 4
- KEY_BUFFER = PARM_OFF + 2
- KEY_NUM = PARM_OFF
- ;
- ;
- ; Define offsets within POSITION BLOCK where FCB,
- ; and currency information are found
- ;
- FCB = 0
- CUR = 38
- ;
- BAS_ID EQU 0CCCCH ;Act like COBOL application
- VAR_ID EQU 06176H ;VARIABLE data length ID
- BTR_ERR EQU 20 ;Return status when Btrieve not initialized
- POS_LEN_ERR EQU 23 ;Invalid position length status
- ;
- BTR_INT EQU 07BH
- BTR2_INT EQU 02FH
- BTR_OFFSET EQU 033H
- MULTI_FUNCTION EQU 0ABH
- ERR_VECTOR EQU 0090H ;Abs vector offset for fatal error handling
- SAVE_VECTOR EQU 051AH ;Abs vector where DOS error handler is saved
- ;
- _DATAX SEGMENT PUBLIC 'DATA'
- ASSUME DS:_DATAX
- USER_BUF_ADDR DD ? ;callers data buffer offset
- USER_BUF_LEN DW ? ;length of callers data buffer
- USER_CUR_ADDR DD ? ;callers currency info offset
- USER_FCB_ADDR DD ? ;disk FCB for current request
- USER_FUNCTION DW ? ;requested function
- USER_KEY_ADDR DD ? ;callers key buffer offset
- USER_KEY_LENGTH DB ? ;length of key buffer
- USER_KEY_NUMBER DB ? ;key of reference for request
- USER_STAT_ADDR DD ? ;callers status word offset
- XFACE_ID DW ? ;language identifier
- SAV_VECTOR DW 0 ;Temp vector save area
- PROCID DW 0 ;Process id used by BMulti
- MULTI DW 0
- VSET DW 0
- SAVEDS DW 0 ;Save user's DS
- _DATAX ENDS
- ;
- ;
- IF OS2
- EXTRN BTRCALL:FAR
- ENDIF
- ;
- XFACE SEGMENT PUBLIC 'CODE'
- ASSUME CS:XFACE
- ;
- ;******************************************************************************
- ;
- ; BTRVFAR ()
- ;
- ; Interface for Btrieve using short buffer address
- ;
- ;******************************************************************************
- BTRVFAR PROC FAR
- ;
- PUSH AX
- PUSH DS
- MOV AX, SEG _DATAX
- MOV DS,AX
- POP AX
- MOV SAVEDS,AX
- POP AX
- BAS_02:
- ;
- ; save callers segment and establish current segments
- ;
- BAS_03:
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- PUSH ES ;save callers segment registers
- ; PUSH DS
- PUSH BP
- ; PUSH DS ;ES := users DS
- ; POP ES
- MOV AX,SAVEDS
- MOV ES,AX
- MOV BP,SP ;set base parm list
- ;
- ;
- ; ensure Btrieve has been initialized
- ;
- ; PUSH DS
- XOR BX,BX ;Clear BX
- MOV DI,WORD PTR ES:ERR_VECTOR[BX] ;Save BASIC's disk error
- MOV SI,WORD PTR ES:ERR_VECTOR+2[BX]; vector
- MOV CX,WORD PTR ES:SAVE_VECTOR[BX] ;Make DOS handle fatal
- MOV WORD PTR ES:ERR_VECTOR[BX],CX ; disk errors
- MOV CX,WORD PTR ES:SAVE_VECTOR[BX]+2
- MOV WORD PTR ES:ERR_VECTOR+2[BX],CX
- ; POP DS
- IFE OS2
- PUSH ES
- MOV AX,3500H + BTR_INT
- INT 21H
- CMP BX,BTR_OFFSET ;Has Btrieve been initialized?
- POP ES
- JE BAS_10 ; Yes
- MOV BX,[BP]+STATUS ;BX = status offset
- PUSH ES
- MOV ES,SAVEDS ; Get user'd(Basic's) data seg
- MOV WORD PTR ES:[BX],BTR_ERR ;Set return status
- POP ES
- JMP BAS_15 ;Skip interrupt since invalid
- ENDIF
- BAS_10:
- MOV SAV_VECTOR,DI ;Save BASIC's disk error vector
- PUSH SI
- ;
- ;
- ;
- IFE OS2
- CMP VSET,0
- JNE BAS_11
- INC VSET
- MOV AX,3000H
- INT 21H
- CMP AL,3
- JB BAS_11
- MOV AX,MULTI_FUNCTION * 256
- INT BTR2_INT
- CMP AL,'M'
- JNE BAS_11
- INC MULTI
- ENDIF
- BAS_11:
- ;
- ; get function parameters
- ;
- MOV SI,[BP]+FUNCTION ;get function address
- MOV CX,ES:[SI] ;get function number
- MOV USER_FUNCTION,CX
- ;
- ; get address of callers status word from parameter
- ;
- MOV CX,[BP]+STATUS ;get address of status word
- MOV WORD PTR USER_STAT_ADDR,CX
- MOV WORD PTR USER_STAT_ADDR+2,ES
- ;
- ; get FCB and currency block from position block
- ;
- push ds ;Save our Data Segment
-
- ;Compile with /Fs and use intrface Btrvfar, posblk is in the far heap
- ;The following code upto label BAS_03N: use MS Basic v7.0 Language Reference
- ;P369 Code example as reference
-
- mov bx,[BP]+POS_BLK ;no - get the string descriptor
- push es ;let ds ->user's(Basic's) data seg
- pop ds ;2 basic calls need its data seg
- push bx ;pass the descriptor to StringLen
- call StringLength ;ax contains the string length when return
- cmp al,128 ;Is posblk >= 128 byte?
- jb BAS_05 ;No, return error
- push bx ;pass the descriptor to StringAddress
- call StringAddress ;far addr return as dx:ax
- mov es,dx ;es => segment of posblk
- mov bx,ax ;bx => offset of posblk, must use bx here
- jmp short BAS_06F ;to accomdate the existing code
-
- ; Compile without /Fs and use intrface Btrv
- ;
- ; Posblk is too short
- BAS_05:
- pop ds ;clear the stack, ds was pushed on stack
- mov es, SAVEDS ;put user's Data seg in es since we might have changed it
- LES BX,USER_STAT_ADDR ;BX = status offset
- MOV WORD PTR ES:[BX],POS_LEN_ERR ;Report invalid position block len
- JMP BAS_13
-
- BAS_06F: ;added for bc7
- pop ds ;restore DS to our DataSeg
- ;needs to be here so we will pop ds
- ;regardless where we jump from
- LEA AX,[BX]+FCB ;get diskette file block addr
- MOV WORD PTR USER_FCB_ADDR,AX
- MOV WORD PTR USER_FCB_ADDR+2,ES
- LEA AX,[BX]+CUR ;get currency block addr
- MOV WORD PTR USER_CUR_ADDR,AX
- MOV WORD PTR USER_CUR_ADDR+2,ES
- mov es,SAVEDS ;restore es to user's(Basic's) DataSeg
- ;
- ; get data buffer address and length
- ;
- MOV BX,[BP]+FILE_OFF ;get data buffer addr
- MOV AX,ES:[BX]
-
- MOV WORD PTR USER_BUF_ADDR,AX ; file buffer offset
-
- MOV BX,[BP]+FILE_SEG ;get data buffer segment addr
- MOV AX,ES:[BX]
-
- MOV WORD PTR USER_BUF_ADDR+2,AX ; storing segment addr in block
- MOV BX,[BP]+DATALEN
- MOV AX,ES:[BX] ;get length of data buffer
- MOV USER_BUF_LEN,AX ;store length
- ;
- ; get callers key buffer address and length
- ;
- MOV BX,[BP]+KEY_BUFFER ;get key buffer descriptor addr
-
- push ds ;Save our DataSeg
- push es ;Let ds->user's(Basic's) DataSeg
- pop ds ;
- push bx ;pass the key_buf's descrpitor
- call StringAddress ;to the basic call, far addr ->dx:ax
- pop ds ;Restore our DataSeg in ds
- mov es,SAVEDS ;Restore user's(Basic) DataSeg in es
- MOV WORD PTR USER_KEY_ADDR,AX ;ax -> offset Key_buf
- MOV WORD PTR USER_KEY_ADDR+2,DX ;dx -> seg Key_buf
- MOV DX,255 ;set key len = 255
- MOV USER_KEY_LENGTH,DL ;Set the Key_len to 255
-
- ;
- ; get key number parameter
- ;
- MOV SI,[BP]+KEY_NUM ;get key number address
- MOV CX,ES:[SI] ;get key number
- MOV USER_KEY_NUMBER,CL
- ;
- ; set language and go process request
- ;
- MOV XFACE_ID,VAR_ID ;get BASIC id
- PUSH ES ;save user's ES
- LEA DX,USER_BUF_ADDR ;DX => user parms
- ;
- ;
- ;
- IFE OS2
- CMP MULTI,0
- JE NOT_MULTI
- MAKE_CALL:
- ;
- ; Set information needed by BMulti
- ;
- XOR AX,AX
- INC AX
- MOV BX,PROCID
- OR BX,BX
- JE CALL_MULTI
- INC AX
- CALL_MULTI:
- MOV AH,MULTI_FUNCTION
- INT BTR2_INT
- CMP AL,0
- JE DONE_CALL
- MOV AX,200H
- INT 7FH
- JMP SHORT MAKE_CALL
- DONE_CALL:
- CMP PROCID,0
- JNE BAS_12
- MOV PROCID,BX
- JMP BAS_12
- NOT_MULTI:
- INT BTR_INT ;process request
- ELSE
- ;
- ;
- MOV CX,USER_FUNCTION ;push parameters for OS/2 call
- PUSH CX ;and make call to Btrieve DLL
- LES CX,USER_FCB_ADDR
- PUSH ES
- PUSH CX
- LES CX,USER_BUF_ADDR
- PUSH ES
- PUSH CX
- PUSH DS
- POP ES
- LEA CX,USER_BUF_LEN
- PUSH DS
- PUSH CX
- LES CX,USER_KEY_ADDR
- PUSH ES
- PUSH CX
- XOR CX,CX
- MOV CL,USER_KEY_LENGTH
- PUSH CX
- MOV CL,USER_KEY_NUMBER
- PUSH CX
- ;
- CALL BTRCALL
- PUSH ES
- LES SI,USER_STAT_ADDR ;get address of status word
- MOV ES:[SI],AX ;Get Btrieve status
- POP ES ;restore ES register
- ENDIF
- ;
- ;
- BAS_12: ;restore user's ES
- POP ES
- MOV AX,USER_BUF_LEN
- MOV BX,[BP]+DATALEN
- MOV ES:[BX],AX
- PUSH ES
- LES SI,USER_STAT_ADDR ;get address of status word
- MOV AX,ES:[SI] ;Get Btrieve status
- POP ES ;restore ES register
- ;
- ;
- BAS_13:
- POP SI ;Retrieve BASIC's disk error vector
- MOV DI,SAV_VECTOR
- BAS_15:
- ; PUSH DS
- XOR BX,BX ;Clear BX
- MOV WORD PTR ES:ERR_VECTOR[BX],DI ;Restore BASIC's disk error
- MOV WORD PTR ES:ERR_VECTOR+2[BX],SI; vector
- ; POP DS
- BAS_20:
- ;
- ; restore callers stack and segment before returning
- ;
- POP BP
- ; POP DS
- MOV AX, SAVEDS
- MOV DS,AX
- POP ES
- POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- POP AX
- CLD ;clear the direction flag for BASIC
- RET 16 ;no - long version uses 8 parameters
- ;
- BTRVFAR ENDP
- XFACE ENDS
- END
-