home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a011 / 2.ddi / BC7XBTRV.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-05-16  |  9.1 KB  |  378 lines

  1.     .XLIST
  2.     PAGE    60,132
  3.     TITLE    Btrieve Record Manager, Copyright (c) 1982 SoftCraft, Inc.
  4.     SUBTTL    QB6XBTRV - Interface to MS Quick Basic 6.0
  5.     PAGE
  6.     .LIST
  7. ;-----------------------------------------------------------------
  8. ;BC7XBTRV
  9. ;    This routine interfaces between compiled Microsoft Basic 7.0 programs
  10. ;    and Btrieve on PC-DOS machines.
  11. ;
  12. ;    Calling Procedure from basic for far data pointers:
  13. ;     CALL BTRVFAR(FUNCTION, STATUS, POSITION BLOCK, DATA BUFFER OFFSET,
  14. ;           DATA BUFFER SEGMENT, DATALEN, KEY.VALUE, KEY.NUMBER)
  15. ;    where
  16. ;        FUNCTION - function number for request
  17. ;        STATUS - return status from request
  18. ;        POSITION.BLOCK - 128 byte data area for FCB and positioning
  19. ;        DATA BUFFER OFFSET - offset of data buffer
  20. ;        DATA BUFFER SEGMENT - segment address of data buffer
  21. ;        DATALEN - length of user data buffer
  22. ;        KEY.VALUE - string pointer to key buffer
  23. ;        KEY.NUMBER - key number to be processed
  24. ;-----------------------------------------------------------------
  25. ;
  26.     PUBLIC    BTRVFAR
  27. ;
  28. INCLUDE OS.INC                   ;include file to determine OS
  29. extrn StringAddress: far           ;for bc7
  30. extrn StringLength: far            ;for bc7
  31. ;
  32. ;
  33. PARM_OFF  = 20
  34. ;
  35. FUNCTION   = PARM_OFF + 14
  36. STATUS       = PARM_OFF + 12
  37. POS_BLK    = PARM_OFF + 10
  38. FILE_OFF   = PARM_OFF + 8
  39. FILE_SEG   = PARM_OFF + 6
  40. DATALEN    = PARM_OFF + 4
  41. KEY_BUFFER = PARM_OFF + 2
  42. KEY_NUM    = PARM_OFF
  43. ;
  44. ;
  45. ;    Define offsets within POSITION BLOCK where FCB,
  46. ;    and currency information are found
  47. ;
  48. FCB      = 0
  49. CUR      = 38
  50. ;
  51. BAS_ID        EQU    0CCCCH    ;Act like COBOL application
  52. VAR_ID        EQU    06176H    ;VARIABLE data length ID
  53. BTR_ERR     EQU    20    ;Return status when Btrieve not initialized
  54. POS_LEN_ERR    EQU    23    ;Invalid position length status
  55. ;
  56. BTR_INT     EQU    07BH
  57. BTR2_INT    EQU    02FH
  58. BTR_OFFSET    EQU    033H
  59. MULTI_FUNCTION    EQU    0ABH
  60. ERR_VECTOR    EQU 0090H    ;Abs vector offset for fatal error handling
  61. SAVE_VECTOR    EQU 051AH    ;Abs vector where DOS error handler is saved
  62. ;
  63. _DATAX    SEGMENT  PUBLIC 'DATA'
  64.     ASSUME     DS:_DATAX
  65. USER_BUF_ADDR    DD    ?    ;callers data buffer offset
  66. USER_BUF_LEN    DW    ?    ;length of callers data buffer
  67. USER_CUR_ADDR    DD    ?    ;callers currency info offset
  68. USER_FCB_ADDR    DD    ?    ;disk FCB for current request
  69. USER_FUNCTION    DW    ?    ;requested function
  70. USER_KEY_ADDR    DD    ?    ;callers key buffer offset
  71. USER_KEY_LENGTH DB    ?    ;length of key buffer
  72. USER_KEY_NUMBER DB    ?    ;key of reference for request
  73. USER_STAT_ADDR    DD    ?    ;callers status word offset
  74. XFACE_ID    DW    ?    ;language identifier
  75. SAV_VECTOR    DW    0    ;Temp vector save area
  76. PROCID        DW    0    ;Process id used by BMulti
  77. MULTI        DW    0
  78. VSET        DW    0
  79. SAVEDS        DW    0    ;Save user's DS
  80. _DATAX        ENDS
  81. ;
  82. ;
  83. IF    OS2
  84. EXTRN    BTRCALL:FAR
  85. ENDIF
  86. ;
  87. XFACE    SEGMENT  PUBLIC 'CODE'
  88.     ASSUME CS:XFACE
  89. ;
  90. ;******************************************************************************
  91. ;
  92. ; BTRVFAR ()
  93. ;
  94. ; Interface for Btrieve using short buffer address
  95. ;
  96. ;******************************************************************************
  97. BTRVFAR  PROC     FAR
  98. ;
  99.     PUSH    AX
  100.     PUSH    DS
  101.     MOV    AX, SEG _DATAX
  102.     MOV    DS,AX
  103.     POP    AX
  104.     MOV    SAVEDS,AX
  105.     POP    AX
  106. BAS_02:
  107. ;
  108. ;    save callers segment and establish current segments
  109. ;
  110. BAS_03:
  111.     PUSH    AX
  112.     PUSH    BX
  113.     PUSH    CX
  114.     PUSH    DX
  115.     PUSH    DI
  116.     PUSH    SI
  117.     PUSH    ES            ;save callers segment registers
  118. ;    PUSH    DS
  119.     PUSH    BP
  120. ;    PUSH    DS            ;ES := users DS
  121. ;    POP    ES
  122.     MOV    AX,SAVEDS
  123.     MOV    ES,AX
  124.     MOV    BP,SP            ;set base parm list
  125. ;
  126. ;
  127. ;    ensure Btrieve has been initialized
  128. ;
  129. ;    PUSH    DS
  130.     XOR    BX,BX                   ;Clear BX
  131.     MOV    DI,WORD PTR ES:ERR_VECTOR[BX]  ;Save BASIC's disk error
  132.     MOV    SI,WORD PTR ES:ERR_VECTOR+2[BX];  vector
  133.     MOV    CX,WORD PTR ES:SAVE_VECTOR[BX] ;Make DOS handle fatal
  134.     MOV    WORD PTR ES:ERR_VECTOR[BX],CX  ;  disk errors
  135.     MOV    CX,WORD PTR ES:SAVE_VECTOR[BX]+2
  136.     MOV    WORD PTR ES:ERR_VECTOR+2[BX],CX
  137. ;    POP    DS
  138. IFE    OS2
  139.     PUSH    ES
  140.     MOV    AX,3500H + BTR_INT
  141.     INT    21H
  142.     CMP    BX,BTR_OFFSET        ;Has Btrieve been initialized?
  143.     POP    ES
  144.     JE    BAS_10            ;  Yes
  145.     MOV    BX,[BP]+STATUS        ;BX = status offset
  146.     PUSH    ES
  147.     MOV    ES,SAVEDS        ; Get user'd(Basic's) data seg
  148.     MOV    WORD PTR ES:[BX],BTR_ERR   ;Set return status
  149.     POP    ES
  150.     JMP    BAS_15            ;Skip interrupt since invalid
  151. ENDIF
  152. BAS_10:
  153.     MOV    SAV_VECTOR,DI        ;Save BASIC's disk error vector
  154.     PUSH    SI
  155. ;
  156. ;
  157. ;
  158. IFE    OS2
  159.     CMP    VSET,0
  160.     JNE    BAS_11
  161.     INC    VSET
  162.     MOV    AX,3000H
  163.     INT    21H
  164.     CMP    AL,3
  165.     JB    BAS_11
  166.     MOV    AX,MULTI_FUNCTION * 256
  167.     INT    BTR2_INT
  168.     CMP    AL,'M'
  169.     JNE    BAS_11
  170.     INC    MULTI
  171. ENDIF
  172. BAS_11:
  173. ;
  174. ;    get function parameters
  175. ;
  176.     MOV    SI,[BP]+FUNCTION    ;get function address
  177.     MOV    CX,ES:[SI]        ;get function number
  178.     MOV    USER_FUNCTION,CX
  179. ;
  180. ;    get address of callers status word from parameter
  181. ;
  182.     MOV    CX,[BP]+STATUS        ;get address of status word
  183.     MOV    WORD PTR USER_STAT_ADDR,CX
  184.     MOV    WORD PTR USER_STAT_ADDR+2,ES
  185. ;
  186. ;    get FCB and currency block from position block
  187. ;
  188.     push    ds            ;Save our Data Segment
  189.  
  190. ;Compile with /Fs and use intrface Btrvfar, posblk is in the far heap
  191. ;The following code upto label BAS_03N: use MS Basic v7.0 Language Reference
  192. ;P369 Code example as reference
  193.  
  194.     mov    bx,[BP]+POS_BLK     ;no - get the string descriptor
  195.     push    es            ;let ds ->user's(Basic's) data seg
  196.     pop    ds            ;2 basic calls need its data seg
  197.     push    bx            ;pass the descriptor to StringLen
  198.     call    StringLength        ;ax contains the string length when return
  199.     cmp    al,128            ;Is posblk >= 128 byte?
  200.     jb    BAS_05            ;No, return error
  201.     push    bx            ;pass the descriptor to StringAddress
  202.     call    StringAddress        ;far addr return as dx:ax
  203.     mov    es,dx            ;es => segment of posblk
  204.     mov    bx,ax            ;bx => offset of posblk, must use bx here
  205.     jmp    short BAS_06F        ;to accomdate the existing code
  206.  
  207. ; Compile without /Fs and use intrface Btrv
  208. ;
  209. ;    Posblk is too short
  210. BAS_05:
  211.     pop    ds            ;clear the stack, ds was pushed on stack
  212.     mov    es, SAVEDS        ;put user's Data seg in es since we might have changed it
  213.     LES    BX,USER_STAT_ADDR    ;BX = status offset
  214.     MOV    WORD PTR ES:[BX],POS_LEN_ERR  ;Report invalid position block len
  215.     JMP    BAS_13
  216.  
  217. BAS_06F:                ;added for bc7
  218.     pop    ds            ;restore DS to our DataSeg
  219.                     ;needs to be here so we will pop ds
  220.                     ;regardless where we jump from
  221.     LEA    AX,[BX]+FCB        ;get diskette file block addr
  222.     MOV    WORD PTR USER_FCB_ADDR,AX
  223.     MOV    WORD PTR USER_FCB_ADDR+2,ES
  224.     LEA    AX,[BX]+CUR        ;get currency block addr
  225.     MOV    WORD PTR USER_CUR_ADDR,AX
  226.     MOV    WORD PTR USER_CUR_ADDR+2,ES
  227.     mov    es,SAVEDS        ;restore es to user's(Basic's) DataSeg
  228. ;
  229. ;    get data buffer address and length
  230. ;
  231.     MOV    BX,[BP]+FILE_OFF     ;get data buffer addr
  232.     MOV    AX,ES:[BX]
  233.  
  234.     MOV    WORD PTR USER_BUF_ADDR,AX ; file buffer offset
  235.  
  236.     MOV    BX,[BP]+FILE_SEG     ;get data buffer segment addr
  237.     MOV    AX,ES:[BX]
  238.  
  239.     MOV    WORD PTR USER_BUF_ADDR+2,AX ; storing segment addr in block
  240.     MOV    BX,[BP]+DATALEN
  241.     MOV    AX,ES:[BX]        ;get length of data buffer
  242.     MOV    USER_BUF_LEN,AX     ;store length
  243. ;
  244. ;    get callers key buffer address and length
  245. ;
  246.     MOV    BX,[BP]+KEY_BUFFER    ;get key buffer descriptor addr
  247.  
  248.     push    ds            ;Save our DataSeg
  249.     push    es            ;Let ds->user's(Basic's) DataSeg
  250.     pop    ds            ;
  251.     push    bx            ;pass the key_buf's descrpitor
  252.     call    StringAddress        ;to the basic call, far addr ->dx:ax
  253.     pop    ds            ;Restore our DataSeg in ds
  254.     mov    es,SAVEDS        ;Restore user's(Basic) DataSeg in es
  255.     MOV    WORD PTR USER_KEY_ADDR,AX      ;ax -> offset Key_buf
  256.     MOV    WORD PTR USER_KEY_ADDR+2,DX    ;dx -> seg    Key_buf
  257.     MOV    DX,255            ;set key len = 255
  258.     MOV    USER_KEY_LENGTH,DL    ;Set the Key_len to 255
  259.  
  260. ;
  261. ;    get key number parameter
  262. ;
  263.     MOV    SI,[BP]+KEY_NUM     ;get key number address
  264.     MOV    CX,ES:[SI]        ;get key number
  265.     MOV    USER_KEY_NUMBER,CL
  266. ;
  267. ;    set language and go process request
  268. ;
  269.     MOV    XFACE_ID,VAR_ID     ;get BASIC id
  270.     PUSH    ES            ;save user's ES
  271.     LEA    DX,USER_BUF_ADDR    ;DX => user parms
  272. ;
  273. ;
  274. ;
  275. IFE    OS2
  276.     CMP    MULTI,0
  277.     JE    NOT_MULTI
  278. MAKE_CALL:
  279. ;
  280. ;    Set information needed by BMulti
  281. ;
  282.     XOR    AX,AX
  283.     INC    AX
  284.     MOV    BX,PROCID
  285.     OR    BX,BX
  286.     JE    CALL_MULTI
  287.     INC    AX
  288. CALL_MULTI:
  289.     MOV    AH,MULTI_FUNCTION
  290.     INT    BTR2_INT
  291.     CMP    AL,0
  292.     JE    DONE_CALL
  293.     MOV    AX,200H
  294.     INT    7FH
  295.     JMP    SHORT MAKE_CALL
  296. DONE_CALL:
  297.     CMP    PROCID,0
  298.     JNE    BAS_12
  299.     MOV    PROCID,BX
  300.     JMP    BAS_12
  301. NOT_MULTI:
  302.     INT    BTR_INT         ;process request
  303. ELSE
  304. ;
  305. ;
  306.     MOV    CX,USER_FUNCTION       ;push parameters for OS/2 call
  307.     PUSH    CX            ;and make call to Btrieve DLL
  308.     LES    CX,USER_FCB_ADDR
  309.     PUSH    ES
  310.     PUSH    CX
  311.     LES    CX,USER_BUF_ADDR
  312.     PUSH    ES
  313.     PUSH    CX
  314.     PUSH    DS
  315.     POP    ES
  316.     LEA    CX,USER_BUF_LEN
  317.     PUSH    DS
  318.     PUSH    CX
  319.     LES    CX,USER_KEY_ADDR
  320.     PUSH    ES
  321.     PUSH    CX
  322.     XOR    CX,CX
  323.     MOV    CL,USER_KEY_LENGTH
  324.     PUSH    CX
  325.     MOV    CL,USER_KEY_NUMBER
  326.     PUSH    CX
  327. ;
  328.     CALL    BTRCALL
  329.     PUSH    ES
  330.     LES    SI,USER_STAT_ADDR    ;get address of status word
  331.     MOV    ES:[SI],AX        ;Get Btrieve status
  332.     POP    ES            ;restore ES register
  333. ENDIF
  334. ;
  335. ;
  336. BAS_12:                 ;restore user's ES
  337.     POP    ES
  338.     MOV    AX,USER_BUF_LEN
  339.     MOV    BX,[BP]+DATALEN
  340.     MOV    ES:[BX],AX
  341.     PUSH    ES
  342.     LES    SI,USER_STAT_ADDR    ;get address of status word
  343.     MOV    AX,ES:[SI]        ;Get Btrieve status
  344.     POP    ES            ;restore ES register
  345. ;
  346. ;
  347. BAS_13:
  348.     POP    SI            ;Retrieve BASIC's disk error vector
  349.     MOV    DI,SAV_VECTOR
  350. BAS_15:
  351. ;    PUSH    DS
  352.     XOR    BX,BX            ;Clear BX
  353.     MOV    WORD PTR ES:ERR_VECTOR[BX],DI  ;Restore BASIC's disk error
  354.     MOV    WORD PTR ES:ERR_VECTOR+2[BX],SI;  vector
  355. ;    POP    DS
  356. BAS_20:
  357. ;
  358. ;    restore callers stack and segment before returning
  359. ;
  360.     POP    BP
  361. ;    POP    DS
  362.     MOV    AX, SAVEDS
  363.     MOV    DS,AX
  364.     POP    ES
  365.     POP    SI
  366.     POP    DI
  367.     POP    DX
  368.     POP    CX
  369.     POP    BX
  370.     POP    AX
  371.     CLD                ;clear the direction flag for BASIC
  372.     RET    16            ;no - long version uses 8 parameters
  373. ;
  374. BTRVFAR    ENDP
  375. XFACE    ENDS
  376.     END
  377. 
  378.