home *** CD-ROM | disk | FTP | other *** search
- .XLIST
- PAGE 60,132
- TITLE Btrieve Record Manager, Copyright (c) 1982 SoftCraft, Inc.
- SUBTTL COBXFACE - Interface to COBOL, Btrieve record manager version 4
- PAGE
- .LIST
- ;-----------------------------------------------------------------
- ;COB_XFACE
- ; This routine interfaces between COBOL programs and
- ; Btrieve assembly routines.
- ;
- ; Calling Procedure from COBOL
- ; CALL 'BTRV' USING FUNCTION, STATUS, POSITION-BLOCK, DATA-RECORD,
- ; DATA-LEN, KEY-VALUE, KEY-NUMBER.
- ; where
- ; FUNCTION - function number for request
- ; STATUS - return status from request
- ; POSITION-BLOCK - 128 byte buffer containing position block
- ; DATA-RECORD - User data buffer
- ; DATA-LEN - Length of the user's data buffer
- ; KEY-VALUE - string pointer to key buffer
- ; KEY-NUMBER - key number to be processed
- ;-----------------------------------------------------------------
- ;
- ;
- ; Define parameter offsets on stack
- ;
- PARM_OFF = 10
- FUNCTION = PARM_OFF + 12
- STATUS = PARM_OFF + 10
- POS_BLK = PARM_OFF + 8
- DATA_REC = PARM_OFF + 6
- DATA_LEN = PARM_OFF + 4
- KEY_BUFFER = PARM_OFF + 2
- KEY_NUM = PARM_OFF
- ;
- ; Define offets within position block where FCB and
- ; currency information are stored.
- ;
- FCB = 0
- CUR = 38
- ;
- VAR_ID EQU 06176H ;Variable record interface id
- BTR_ERR EQU 20 ;Return status when Btrieve not initialized
- BTR_INT EQU 07BH
- BTR2_INT EQU 02FH
- MULTI_FUNCTION EQU 0ABH
- BTR_OFFSET EQU 033H
- BTR_VECTOR EQU BTR_INT * 4 ;Absolute vector offset for interrupt
- CREATE EQU 14 ;Create function call
- STAT EQU 15 ;Stat function call
- CREATE_SUPP EQU 31 ;Create supplemental index call
- ;
- INCLUDE USERSEG.MAC
- ;
- START_CSEG BTRV
- JMP SHORT START
- ;
- 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
- ;
- PROCID DW 0 ;Process Id for use by BMulti
- MULTI DW 0
- VSET DW 0
- ;
- START:
- ;
- ; save callers segment and establish current segments
- ;
- PUSH ES ;save callers segment registers
- PUSH DS
- PUSH BP
- PUSH DS ;ES := users DS
- POP ES
- PUSH CS ;DS used by index routines
- POP DS
- MOV BP,SP ;set base parm list
- ;
- ; ensure Btrieve has been initialized
- ;
- PUSH ES
- PUSH BX
- MOV AX,3500H + BTR_INT
- INT 21H
- CMP BX,BTR_OFFSET ;Has Btrieve been initialized?
- POP BX
- POP ES
- JE BAS_10 ; Yes
- MOV BX,[BP]+STATUS ;BX = status offset
- MOV AX,BTR_ERR
- xchg ah,al
- MOV ES:[BX],AX ;Set return status
- JMP BAS_16 ;Skip interrupt since invalid
- BAS_10:
- CMP VSET,0
- JNE BAS_11
- INC VSET
- PUSH AX
- MOV AX,3000H
- INT 21H
- CMP AL,3
- POP AX
- JB BAS_11
- MOV AX,MULTI_FUNCTION * 256
- INT BTR2_INT
- CMP AL,'M'
- JNE BAS_11
- INC MULTI
- BAS_11:
- ;
- ; get function parameter
- ;
- MOV SI,[BP]+FUNCTION ;get function address
- MOV CX,ES:[SI] ;get function number
- XCHG CL,CH
- 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 position block
- ;
- MOV BX,[BP]+POS_BLK ;BX = address of position block
- 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
- ;
- ; get data buffer
- ;
- MOV BX,[BP]+DATA_REC
- MOV WORD PTR USER_BUF_ADDR,BX
- MOV WORD PTR USER_BUF_ADDR+2,ES
- ;
- ; get data buffer length
- ;
- MOV SI,[BP]+DATA_LEN ;get data length address
- MOV CX,ES:[SI] ;get data length
- XCHG CL,CH
- MOV USER_BUF_LEN,CX
- ;
- ; get callers key buffer address and length
- ;
- MOV BX,[BP]+KEY_BUFFER ;get key buffer addr
- MOV WORD PTR USER_KEY_ADDR,BX
- MOV WORD PTR USER_KEY_ADDR+2,ES
- MOV USER_KEY_LENGTH,255 ;set key length to max
- ;
- ; get key number parameter
- ;
- MOV SI,[BP]+KEY_NUM ;get key number address
- MOV CX,ES:[SI] ;get key number
- MOV USER_KEY_NUMBER,CH
- ;
- ; set language and go process request
- ;
- MOV XFACE_ID,VAR_ID ;get interface id
- LEA DX,USER_BUF_ADDR ;DX => user parms
- CALL PRE_SW
- ;
- ;
- ;
- CMP MULTI,0
- JE NOT_MULTI
- MAKE_CALL:
- XOR AX,AX
- INC AX ;Initialize function setting for BMulti
- MOV BX,PROCID ;Set Process id for BMulti
- OR BX,BX ;Do we need to get a process id?
- JE CALL_MULTI ; Yes, Let BMulti know
- INC AX ;Tell BMulti you have a process id
- 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
- BAS_12:
- CALL POST_SW
- BAS_15:
- ;
- ; restore callers stack and segment before returning
- ;
- MOV CX,USER_BUF_LEN ;data length returned
- XCHG CL,CH
- MOV BX,[BP]+DATA_LEN ;address of data length
- MOV ES:[BX],CX ;set user's data length
- BAS_16:
- MOV BX,[BP]+STATUS ;get users status
- MOV AX,ES:[BX] ; since COBOL reverses bytes
- XCHG AH,AL
- MOV ES:[BX],AX ; new user status
- POP BP
- POP DS
- POP ES
- ;
- ; bytes to pop off stack = number parameters * 2 (including status)
- ;
- RET 14 ;return to caller
- ;
- ;
- ; These routines are used to put the control blocks for CREATE
- ; and STAT into a regular form. Cobol always reverses the high and
- ; low order byte in words.
- ;
- POST_SW PROC NEAR
- CMP USER_FUNCTION,STAT ;if stat function
- JE POST_10 ; do switch
- PRE_SW LABEL NEAR
- CMP USER_FUNCTION,CREATE ;if create function then
- JE POST_10 ; do switch
- CMP USER_FUNCTION,CREATE_SUPP ;if not create supp,
- JNE POST_99 ; skip switch
- POST_10:
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DS
- MOV DX,USER_FUNCTION
- LDS BX,USER_BUF_ADDR ;BX => file structure
- PUSH BX ;save BX for later
- MOV CX,8 ;8 words in the header
- POST_20:
- MOV AX,[BX] ;get word
- XCHG AL,AH ;exchange bytes
- MOV [BX],AX ;replace word as COBOL expects it
- INC BX
- INC BX
- LOOP POST_20
- POP SI ;SI = old BX
- MOV CX,4[SI] ;cx = # keys
- CMP CH,0
- JE POST_25
- XCHG CL,CH
- POST_25:
- CMP CX,24 ;if > max indexex then
- JA POST_90 ; must be a bad specification
- ;
- ; test for any segmented key specs
- ;
- PUSH BX ;BX -> 1st key spec
- SUB BX,16
- SUB AX,AX
- POST_27:
- INC AX
- ADD BX,16
- CMP DX,CREATE
- JNE POST_28
- TEST WORD PTR 4[BX],1000h ;Does this spec have another segment
- JNE POST_27 ; yes
- JMP SHORT POST_29
- POST_28:
- TEST WORD PTR 4[BX],0010h ;Does this spec have another segment
- JNE POST_27 ; yes
- POST_29:
- LOOP POST_27
- POP BX ;BX -> 1st key spec
- MOV CX,AX ;CX = real number of key specs
- ;
- ; now which the total number of key specs
- ;
- MOV AL,8 ;number of words in key spec
- MUL CL
- MOV CX,AX ;CX = number of words in key specs
- POST_30:
- MOV AX,[BX] ;get word
- XCHG AL,AH ;exchange bytes
- MOV [BX],AX ;replace word as COBOL expects it
- INC BX
- INC BX
- LOOP POST_30
- POST_90:
- POP DS
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- POST_99:
- RET
- POST_SW ENDP
- END_CSEG BTRV
- END