home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1986-06-09 | 5.5 KB | 182 lines |
- IMPLEMENTATION MODULE ModXBTRV;
- FROM SYSTEM IMPORT ADDRESS,WORD,BYTE,CODE,SWI,SETREG,GETREG,ADR,
- AX,BX,DX,DS;
- (* *)
- (* Module Name: ModXBTRV.MOD *)
- (* *)
- (* Description: This is the Btrieve Version 4.0 interface for *)
- (* LogiTech Modula-2/86. This routine sets up the *)
- (* parameter block expected by Btrieve, and issues *)
- (* interrupt 7B. *)
- (* *)
- (* Synopsis: STAT := BTRV (OP, POS, DATA, DATALEN, KBUF,KEY) *)
- (* *)
- (* where *)
- (* OP is an integer *)
- (* POS is the address to a 128 byte array, *)
- (* DATA is the address to a data structure *)
- (* DATALEN is a cardinal *)
- (* KBUF is the address to a data structure *)
- (* and KEY is an integer. *)
- (* *)
- (* Returns: Btrieve status code (see Appendix B of the Btrieve Manual). *)
-
- VAR
-
- (* ProcId is used for communicating with the Multi Tasking Version of *)
- (* Btrieve. It contains the process id returned from BMulti and should *)
- (* not be changed once it has been set. *)
- (* *)
-
- ProcId: INTEGER;
- Vset: BOOLEAN;
- Wait: BOOLEAN;
- Multi: BOOLEAN;
-
- PROCEDURE BTRV (OP: CARDINAL; POS, DATA: ADDRESS; VAR DATALEN: CARDINAL;
- KBUF: ADDRESS; KEY: INTEGER): INTEGER;
- CONST
- Mod2ID = 1111H; (* Modula-2 Language id*)
- VarId = 6176H; (*id for variable length records -'va'*)
- MultiFunction = 0ABH * 256;
- MultiLoad = MultiFunction + 4DH;
-
- TYPE
- BtrParms = RECORD
- UserBufAddr: ADDRESS; (*data buffer address*)
- UserBufLen: CARDINAL; (*data buffer length*)
- UserCurAddr: ADDRESS; (*currency block address*)
- UserFCBAddr: ADDRESS; (*file control block address*)
- UserFunction: CARDINAL; (*Btrieve operation*)
- UserKeyAddr: ADDRESS; (*key buffer address*)
- UserKeyLength: CHAR; (*key buffer length*)
- UserKeyNumber: BYTE; (*key number*)
- UserStatAddr: ADDRESS; (*return status address*)
- XFACEID: INTEGER; (*language interface id*)
- END;
- VAR
- Stat: INTEGER; (*Btrieve status code*)
- XDATA: BtrParms; (*Btrieve parameter block*)
- A: ADDRESS;
- w: WORD;
- rAX: CARDINAL;
- I: CARDINAL;
- iBYTE: BYTE;
- TempAX:INTEGER;
- TempId:INTEGER;
- Done: BOOLEAN;
-
- BEGIN
- Done := FALSE;
-
- SETREG (AX,357BH);
- CODE (06H); (* push ES *)
- SWI (021H);
- CODE (07H); (* pop ES *)
- GETREG (BX, I);
-
- IF (I # 0033H) THEN
- Stat := 20;
- ELSE
- IF NOT Vset THEN
- Vset := TRUE; (*Set flag indicating we know what version we have*)
- SETREG (AX,3000H);
- CODE (06H); (* push ES *)
- SWI (021H);
- CODE (07H); (* pop ES *)
- GETREG (AX, I);
- iBYTE := VAL(BYTE, I);
- IF (ORD(iBYTE) >= 3) THEN
- SETREG (AX, MultiFunction);
- SWI (02FH);
- GETREG (AX, I);
- IF (I = MultiLoad) THEN
- Multi := TRUE; (*Multi user version*)
- ELSE
- Multi := FALSE;
- END;
- ELSE
- Multi := FALSE;
- END;
- END;
- WITH XDATA DO
- UserBufAddr := DATA; (*set data buffer address*)
- UserBufLen := DATALEN; (*use caller's value*)
- UserFCBAddr := POS; (*set FCB address*)
- UserCurAddr.SEGMENT := UserFCBAddr.SEGMENT; (*set cur segment*)
- UserCurAddr.OFFSET := UserFCBAddr.OFFSET+38; (*set cur offset*)
- UserFunction := OP; (*set Btrieve operation code*)
- UserKeyAddr := KBUF; (*set key buffer address*)
- UserKeyLength := CHR(255); (*assume its large enough*)
- UserKeyNumber := VAL (BYTE,KEY); (*set key number*)
- UserStatAddr := ADR (Stat); (*set Status address*)
- XFACEID := VarId; (*set language id*)
- END;
-
- A := ADR (XDATA);
-
- IF (NOT Multi) THEN
- CODE (1EH); (* push DS *)
- CODE (16H); (* push SS *)
- CODE (06H); (* push ES *)
- CODE (55H); (* push BP *)
- SETREG (DX,A.OFFSET);
- SETREG (DS,A.SEGMENT);
- SWI (07BH);
- CODE (5DH); (* pop BP *)
- CODE (07H); (* pop ES *)
- CODE (17H); (* pop SS *)
- CODE (1FH); (* pop DS *)
- ELSE
-
- (* Set up parameters expected by BMulti *)
-
- IF (ProcId # 0) THEN (* already have a process id? *)
- rAX := 2; (* yes, let BMulti know *)
- ELSE
- rAX := 1; (* assume no process id *)
- END;
- rAX := rAX + MultiFunction;
-
- (* *)
- (* Make call to the Btrieve Record Manager. *)
- (* *)
- REPEAT
- CODE (1EH); (* push DS *)
- CODE (16H); (* push SS *)
- CODE (06H); (* push ES *)
- CODE (55H); (* push BP *)
- SETREG (AX,rAX);
- SETREG (BX,ProcId);
- SETREG (DX,A.OFFSET);
- SETREG (DS,A.SEGMENT);
-
- SWI (02FH);
-
- CODE (5DH); (* pop BP *)
- CODE (07H); (* pop ES *)
- CODE (17H); (* pop SS *)
- CODE (1FH); (* pop DS *)
- GETREG (AX, I);
- GETREG (BX,TempId);
- IF (I # 0) THEN
- SETREG (AX, 0200H);
- SWI (07FH);
- END;
- UNTIL (I = 0);
- IF (ProcId = 0) THEN
- ProcId := TempId;
- END;
- END;
- DATALEN := XDATA.UserBufLen; (*retrieve return data length*)
- END;
- RETURN Stat;
- END BTRV;
-
- BEGIN
- ProcId := 0;
- Vset := FALSE;
- Wait := FALSE;
- Multi := FALSE;
- END ModXBTRV.