Google
 

Trailing-Edge - PDP-10 Archives - cuspbinsrc_2of2_bb-fp63b-sb - 10,7/rms10/rmssrc/rmsfil.b36
There are 6 other files named rmsfil.b36 in the archive. Click here to see a list.

MODULE FILES =

BEGIN

GLOBAL BIND	FILEV = 1^24 + 0^18 + 8;	!EDIT DATE: 23-DEC-76

%([
FUNCTION:	THIS MODULE CONTAINS ALL ROUTINES WHICH CREATE
		AND PROCESS THE PROLOGUE BLOCKS WITHIN AN RMS-20
		FILE.

AUTHOR:	S. BLOUNT

THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.

!COPYRIGHT (C) 1977, 1979 BY DIGITAL EQUIPMENT CORPORATION



**********	TABLE OF CONTENTS	**************




	ROUTINE			FUNCTION
	=======			========

	SETPLOG			CREATE A FILE PROLOGUE BLOCK

	IDXFILEPROLOG		CREATE THE INDEXED FILE PROLOGUE

	DOAREABLOCKS		CREATE THE AREA DESCRIPTORS (INDEXED FILE ONLY)

	DOKEYBLOCKS		CREATE THE INDEX DESCRIPTORS (INDEXED FILE ONLY)

	GETIDB			LOCATE AN INDEX DESCRIPTOR BLOCK




REVISION HISTORY:

EDIT	DATE		WHO		PURPOSE
====	====		===		========

1	7-15		SEB		ADD GETIDB
2	SEP-2-76	SEB		ADD > 16 KEY DESCRIPTORS
3	29-SEP-76	SEB		ADD AREADESCSIZE COMPUTATION
4	7-NOV-76	SEB		TAKE OUT ADBAID
5	7-NOV-76	SEB		FIX NXTBKT TO BE IN PAGES
6	16-DEC-76	SEB		ADD REQUIRE BUFFER.REQ
7	23-DEC-76	SEB		MAKE BKS=0 INTO BKS=1

*************************************************
*						*
*		NEW REVISION HISTORY		*
*						*
*************************************************

****************** Start RMS-10 V1.1 *********************
********************* TOPS-10 ONLY ***********************

PRODUCT	MODULE	 SPR
 EDIT	 EDIT	 QAR		DESCRIPTION
======	======	=====		===========

 100	  8	Dev		Make declarations for routine names
				be EXTERNAL ROUTINE so RMS will compile 
				under BLISS V4 (RMT, 10/22/85).


	***** END OF REVISION HISTORY *****




])%



	%([ FORWARD DECLARATIONS ])%


	%([ EXTERNAL DECLARATIONS ])%

	EXTERNAL ROUTINE
	    CRASH,		! INTERNAL ERROR PROCESSOR
	    GPAGE,
	    PPAGE,
	    DUMP;		! DEBUGGING ROUTINE

	%([ ERROR MESSAGES REFERENCED IN THIS MODULE ])%

	EXTERNAL
!	    MSGPG0,		! FILE PROLOGUE EXTENDS PAST PAGE 0
	    MSGINPUT;	! BAD INPUT VALUES




REQUIRE 'RMSREQ';
EXTDECLARATIONS;


! SETPLOG
! =======

! THIS ROUTINE CREATES A FILE PROLOGUE IN FREE CORE
!	WHEN A RMS-20 FILE IS INITIALLY CREATED.
!	THE PROLOGUE DOES NOT INCLUDE THE END-BLOCK.
!	THE PROLOGUE IS NOT WRITTEN OUT TO THE FILE
!	UNTIL AFTER THE $CREATE IS DETERMINED TO
!	HAVE BEEN SUCCESSFUL.
!	THE FILE PROLOGUE IS ALWAYS WRITTEN AT THE ADDRESS
!	CONTAINED IN THE GLOBAL VARIABLE "FPT".
!

! INPUT:
!	<NONE>

! OUTPUT:
!	<NONE>

!
! IMPLICIT INPUTS:
!
!	FPT =	ADDRESS OF THE FILE PROLOGUE IN CORE
!
! NOTES:
!
!	1.	ALL FIELDS IN THE FILE PROLOGUE WHICH ARE COMMON
!		FOR ALL FILE ORGANIZATIONS ARE INTIALIZED BY THIS
!		ROUTINE. FIELDS WHICH ARE USED ONLY FOR INDEXED
!		FILES (AREA, ADBOFFSET, KEYS, IDBOFFSET ), ARE SET
!		UP BY THE CORRESPONDING ROUTINE (DOAREABLOCKS OR
!		DOKEYBLOCKS) WHEN THE REST OF THE PROLOGUE STRUCTURES
!		ARE CREATED.  ALL RESERVED FIELDS IN THIS BLOCK
!		ARE AUTOMATICALLY ZEROED BECAUSE THE PAGE ON WHICH
!		THIS PAGE IS BEING CREATED IS A NEW FILE PAGE.

GLOBAL ROUTINE SETPLOG  =
BEGIN
LOCAL
    TEMP,
    ENDPTR;

MAP
    ENDPTR:	POINTER;

	TRACE ( 'SETPLOG' );
	FPT [ BLOCKTYPE ] = FPBLOCK;		! SET FILE CODE
	FPT [ BLOCKLENGTH ] = FPTSIZE;		! AND SIZE
	FPT [ FPTRFM ] = .FAB [ FABRFM ];	! RECORD FORMAT
	FPT [ FPTBSZ ] = .FAB [ FABBSZ ];	! BYTE-SIZE
	FPT [ FPTBKS ] = .FAB [ FABBKS ];	! USE BUCKET SIZE IN FAB
	FPT [ FPTORG ] = .FAB [ FABORG ];	! ORGANIZATION
	FPT [ FPTRAT ] = .FAB [ FABRAT ];	! ATTRIBUTES
	FPT [ FPTMRS ] = .FAB [ FABMRS ];	! MAX REC SIZE
	FPT [ FPTMRN ] = .FAB [ FABMRN ];	! MAX FILE SIZE

	%([ **NOTE THAT THE NXTBKT FIELD IN THE PROLOGUE IS SET
	   BY DOKEYBLOCKS, WHEN EACH INDEX DESCRIPTOR BLOCK IS
	   INITIALLY CREATED. ])%


	%([ THE OTHER FIELDS ARE ALREADY CLEAR BECAUSE THIS
	   IS A NEW FILE PAGE ])%



	%([ SET UP THE END BLOCK FOR SEQUENTIAL/RELATIVE FILES ])%

	ENDPTR = .FPT + .FPT [ BLOCKLENGTH ];	! ADJUST NEW POINTER

	ENDPTR [ WHOLEWORD ] = ENDBLOCK ^ LEFTLSH + ENDBLOCKSIZE;


	GOODRETURN

END; %( OF SETPLOG ROUTINE )%




! IDXFILEPROLOG
! ==============

! THIS ROUTINE IS USED TO CREATE ALL BLOCKS WITHIN
!	THE FILE PROLOGUE WHICH ARE UNIQUE TO
!	INDEXED FILES.  THIS ROUTINE CREATES THE
!	FOLLOWING BLOCKS:
!		1)  AREA DESCRIPTORS
!		2)  INDEX DESCRIPTORS

! INPUT:
!	<NONE>

! OUTPUT:
!	TRUE:	OK
!	FALSE:	ERROR
!		NO FREE PAGES FOUND FOR MULTI-PAGE PROLOGUE

! IMPLICIT INPUTS:
!
!	PLOGPAGE	PAGE NUMBER OF FREE PAGE WHICH CONTAINS
!			THE FIRST PAGE OF THE FILE PROLOGUE.
!
! ROUTINES CALLED:
!	DOKEYBLOCKS
!	DOAREABLOCKS

 GLOBAL ROUTINE IDXFILEPROLOG  =
 BEGIN
 
 EXTERNAL ROUTINE
    DOKEYBLOCKS,
    DOAREABLOCKS;
 LOCAL
    WINDOWNUMBER,			! PAGE NUMBER OF FILE WINDOW
    FILEPAGENUMBER;			! NUMBER OF THE FILE PROLOGUE PAGE
 
 EXTERNAL
    PLOGPAGE;		! TEMP WINDOW WHICH HOLDS PROLOGUE
 
 

	TRACE ('INDXFILEPROLOG');

	%([ SET UP THE PAGE NUMBER OF THE CURRENT PROLOGUE ])%

	FILEPAGENUMBER = ZERO;			! ALWAYS START ON PAGE 0
	WINDOWNUMBER = .PLOGPAGE;		! FIND WHERE PROLOGUE IS


	%([ CREATE THE AREA DESCRIPTORS ])%
	CALDOAREABLOCKS (	RLCI ( WINDOWNUMBER ),
				RLCI ( FILEPAGENUMBER ));


	%([ CREATE ALL INDEX DESCRIPTOR BLOCKS ])%

	RETURN CALLDOKEYBLOCKS (LCI ( WINDOWNUMBER ),
				LCI ( FILEPAGENUMBER ))

 END;

! DOAREABLOCKS
! ============

! THIS ROUTINE CREATES THE AREA DESCRIPTORS IN THE
!	PROLOGUE OF AN INDEXED FILE.

! INPUT:
!	WINDOWNUMBER	PAGE NUMBER WHERE PROLOGUE IS CURRENTLY MAPPED
!	FILEPAGENUMBER	FILE PAGE # OF THE FILE PROLOGUE ( ALWAYS 0 )

! OUTPUT:
!	<NONE>

! GLOBALS USED:
!	<NONE>

 GLOBAL ROUTINE DOAREABLOCKS ( WINDOWNUMBER, FILEPAGENUMBER ):NOVALUE =
 BEGIN
 	ARGUMENT	(WINDOWNUMBER,REFERENCE);	! PROCESS WINDOW NUMBER
 	ARGUMENT	(FILEPAGENUMBER,REFERENCE);	! PAGE # OF PROLOGUE
 
 REGISTER
    MOVINGPTR,					! TEMPORARY POINTER VARIABLE
    ADBPTR,						! PTR TO AREA DESCRIPTOR
    AREAINDEX,					! INDEX FOR ADB
    PROLOGPTR,					! PTR TO FILE PROLOGUE
    DEFALTBKZ,					! DEFAULT SIZE OF THE BUCKET
    AREACOUNT;					! COUNT OF AREA DESCRIPTORS
 LOCAL
    XABPTR;						! POINTER TO USER XAB
 
 MAP
    PROLOGPTR:	POINTER,
    MOVINGPTR:	POINTER,
    ADBPTR:	POINTER,
    XABPTR:	POINTER;
 


	TRACE ( 'DOAREABLOCKS' );

	%([ SET UP SOME POINTERS ])%

	PROLOGPTR = .WINDOWNUMBER ^ P2W;		! PTR TO WINDOW
	ADBPTR = .PROLOGPTR [ BLOCKLENGTH ] + .PROLOGPTR;	

	%([ CREATE A NULL HEADER FOR THIS BLOCK ])%

	ADBPTR [ WHOLEWORD ] = ( ADBCODE ^ BLKTYPELSH );
	AREACOUNT = 1;					! START OFF WITH 1 AREA


	%([ CREATE THE DEFAULT AREA ])%

	DEFALTBKZ = .FAB [ FABBKS ];			! SET UP DEFAULT BUCKET SIZE
	IF .DEFALTBKZ IS ZERO THEN DEFALTBKZ = DEFBUCKETSIZE;	! SET UP DEFAULT
	ADBPTR [ .AREACOUNT, ADBBKZ ] = .DEFALTBKZ;		! STORE BKZ IN FIRST ADB
	%(NOTE THAT THE AREA ID IS ALREADY 0 SO WE DONT HAVE TO SET IT)%


	%([ CREATE AN ENTRY FOR EACH ADB ])%

	XABPTR = .FAB [ FABXAB ];			! GET FIRST XAB
	UNTIL .XABPTR IS ZERO
	DO

		BEGIN
		IF .XABPTR [ XABCOD ] IS CODAREA		! DO ONLY FOR AREA ALLOCATION XAB'S
		THEN
			BEGIN
			AREAINDEX = ( .AREACOUNT * AREADESCSIZE ) + 1;
			AREACOUNT = .AREACOUNT + 1;		! BUMP THE NUMBER OF AREAS
			IF ( ADBPTR [ .AREAINDEX, ADBBKZ ] = .XABPTR [ XABBKZ ])
				IS ZERO
			THEN	%( WE MUST USE THE DEFAULT BUCKET SIZE )%
				ADBPTR [ .AREAINDEX, ADBBKZ ] = .DEFALTBKZ
		
			END;	%( OF WHILE XABCOD IS CODAREA )%

		%([ FETCH ADDRESS OF NEXT XAB IN CHAIN ])%
	
		XABPTR = .XABPTR [ XABNXT ]		! ADVANCE XAB

		END; %(OF UNTIL XABPTR IS ZERO)%

	%([ FILL IN THE LENGTH OF THE ADB IN THE BLOCK HEADER ])%

	ADBPTR [ BLOCKLENGTH ] = (.AREACOUNT * AREADESCSIZE ) + 1;	! PLUS 1 FOR THE HEADER


	%([ FILL IN SOME PROLOGUE INFO ABOUT THE ADB ])%

	PROLOGPTR [ FPTAREAS ] = .AREACOUNT;		! FILL IN NUMBER OF AREAS
	PROLOGPTR [ FPTADB ] = .ADBPTR;			! AND ADDRESS OF ADB OFFSET
	RETURN						! NO STATUS RETURN

 END;	%( OF DOAREABLOCKS )%



! DOKEYBLOCKS
! ===========

! THIS ROUTINE CREATES THE INDEX DESCRIPTORS WHICH ARE PUT
!	IN THE PROLOGUE OF AN INDEXED FILE.  
!	EACH INDEX DESCRIPTOR CONTAINS ALL INFORMATION WHICH
!	IS REQUIRED BY RMS-20 TO PROCESS A RECORD
!	ACCORDING TO THE PARTICULAR KEY.
!
!	THE CHAIN OF INDEX DESCRIPTORS BEGINS IMMEDIATELY FOLLOWING
!	THE AREA DESCRIPTORS IN THE FILE PROLOGUE. EACH IDB IS
!	LINKED TO THE NEXT ONE.

! INPUT:
!	PROCESS PAGE INTO WHICH FILE PROLOGUE IS MAPPED
!	FILE PAGE # OF THE FILE PROLOGUE

! OUTPUT:
!	TRUE:	OK
!	FALSE:	ERROR
!		NO FREE PAGES LEFT FOR MULTI-PAGE PROLOGUE

! GLOBALS USED:
!	<NONE>


 GLOBAL ROUTINE DOKEYBLOCKS ( WINDOWNUMBER, FILEPAGENUMBER ) =
 BEGIN
 	ARGUMENT	(WINDOWNUMBER,VALUE);	! PROCESS PAGE #
 	ARGUMENT	(FILEPAGENUMBER,VALUE);	! PAGE # OF PROLOGUE
 
 EXTERNAL ROUTINE
    MAKEIDB;

 LOCAL
    MULTIPAGEFLAG,
    XABPTR,
    PROLOGPTR,
    IDBPTR,
    LASTIDBPTR;
 
 MAP
    PROLOGPTR:	POINTER,
    IDBPTR:	POINTER,
    XABPTR:	POINTER,
    LASTIDBPTR:	POINTER;

LOCAL	IDBCOUNT;
LOCAL	IDBLEN;				!# OF WDS IN AN IDB
 

	TRACE ( 'DOKEYBLOCKS' );

	%([ ASSUME THAT THIS IS A ONE-PAGE PROLOGUE ])%

	MULTIPAGEFLAG = FALSE;

	%([ SET UP SOME POINTERS ])%

	PROLOGPTR = .WINDOWNUMBER ^ P2W;
	IDBPTR = .PROLOGPTR [BLOCKLENGTH] + .PROLOGPTR;	!HOP OVER FILE DATA
	IDBLEN = .IDBPTR [ BLOCKLENGTH ] + .IDBPTR;	!HOP OVER AREA BLKS
	IDBPTR = .IDBLEN;				!OTHWISE BLISS CLOBS IT
	LOOKAT ( '	ADDR OF IDB: ',IDBPTR );

	%([ MAKE FILE PROLOGUE POINT HERE ])%

	PROLOGPTR [ FPTIDB ] = .IDBPTR;			! FILL IN PROLOGUE
	IDBCOUNT = ZERO;				! CLEAR KEY COUNTER
	LASTIDBPTR = ZERO;				! SHOW THIS IS FIRST

	%([ WE WILL NOW SCAN THE XAB CHAIN ])%

	XABPTR = .FAB [ FABXAB ];			! GET CHAIN ADDRESS
	UNTIL .XABPTR  IS ZERO		! SCAN FOR KEY XAB'S
	DO
		BEGIN

		%([ CHECK IF THIS IS A KEY XAB ])%

		IF .XABPTR [ XABCOD ] IS CODKEY
		THEN
			BEGIN
			%([ CREATE AN INDEX DESCRIPTOR BLOCK ])%

			CALLMAKEIDB (	%(PTR TO IDB)%	LPT ( PROLOGPTR ),
					%(INDEX DESC)%	LPT ( IDBPTR ),
					%(XAB)%		LPT ( XABPTR ));

			%([ MAKE THIS IDB POINT TO WHERE THE NEXT ONE
			   IS LIKELY TO GO ])%

			IDBLEN = .IDBPTR [BLOCKLENGTH];	!GET AN IDB'S LEN
			IDBPTR [ IDBNXT ] = ( .FILEPAGENUMBER ^ P2W )
				+ ( (.IDBPTR + .IDBLEN) AND  OFSETMASK );
			LASTIDBPTR = .IDBPTR;		!SAVE FOR POSSIB ALT IDBNXT
			INC ( IDBPTR, .IDBLEN);		!PT AT NEXT 1

			%([ IS THERE ROOM FOR ONE MORE IDB ON THIS PAGE? ])%

			IF ( ( .IDBPTR + .IDBLEN ) ^W2P )
					ISNT			!DOES END GO TO NEXT P?
				( .WINDOWNUMBER )
			THEN	%(YES, WE WILL OVERLAP ONTO THE NEXT PAGE)%
				BEGIN
				INC ( FILEPAGENUMBER, 1 );	! GOTO NEXT PAGE
				LASTIDBPTR [ IDBNXT ] = .FILEPAGENUMBER ^ P2W;
				%([ DO WE NEED A NEW PAGE? ])%

				IF .MULTIPAGEFLAG IS FALSE
				THEN
					BEGIN
					MULTIPAGEFLAG = TRUE;
					RTRACE(%STRING('	ALLOCATING EXTRA PLOG PAGE...',%CHAR(13),%CHAR(10)));
					IF (WINDOWNUMBER = CALLGPAGE ( PCI ( 1 ) )) IS FALSE
					THEN RETURN FALSE
				END %(OF IF WE NEED NEW PAGE)%
				ELSE	$CALL	(PAGOUT,	!FLUSH PREV PG
					%(JFN)%		.FST[FSTJFN],
					%(TO)%		.FILEPAGENUMBER-1,
					%(FROM)%	.WINDOWNUMBER,
					%(COUNT)%	1);

				%([ NOW, MAP THE NEXT PAGE INTO OUR WINDOW ])%
				$CALL	(PAGIN,
						%(JFN)%		.FST[FSTJFN],
						%(FROM)%	.FILEPAGENUMBER,
						%(TO)%		.WINDOWNUMBER,
						%(ACCESS)%	AXUPD,
						%(COUNT)%	1);
				IDBPTR = .WINDOWNUMBER ^ P2W;
			END; %(OF IF WE WENT OVER TO NEXT PAGE)%

			IDBCOUNT = .IDBCOUNT + 1		! BUMP COUNT
		END; %(OF IF THIS IS A KEY XAB)%

		%([ FETCH THE NEXT XAB IN THE CHAIN ])%

		XABPTR = .XABPTR [ XABNXT ]			! GO TO NEXT XAB
		
	END;	%( OF WHILE .XABPTR ISNT ZERO )%

	%([ CLEAR THE NEXT POINTER IN THE LAST IDB WE MADE ])%

	IF .LASTIDBPTR ISNT ZERO THEN LASTIDBPTR [ IDBNXT ] = ZERO;

	%([ DID WE ALLOCATE AN EXTRA PAGE FOR THE PROLOGUE ])%

	IF .MULTIPAGEFLAG
	THEN BEGIN
		$CALL	(PAGOUT,
				%(JFN)%		.FST[FSTJFN],
				%(TO)%	.FILEPAGENUMBER,
				%(FROM)%	.WINDOWNUMBER,
				%(COUNT)%	1);
		CALLPPAGE ( VCI ( WINDOWNUMBER ), PCI ( 1 ), PCI ( TRUE ))
	END;


	%([ WE NOW HAVE CREATED ALL INDEX DESCRIPTORS.
	   WE MUST STORE THE KEY COUNT
	   IN THE FILE PROLOGUE ])%

	PROLOGPTR [ FPTKEYS ] = .IDBCOUNT;
	LOOKAT ( '# OF IDB-S:', IDBCOUNT );

	%([ ALSO, RE-SET THE NXTBKT FIELD IF WE HAD A MULTI-PAGE
	   PROLOGUE ])%

	PROLOGPTR [ FPTNXTBKT ] = ( .FILEPAGENUMBER + 1 ) ;
	SIZEOFFILE = .PROLOGPTR [FPTNXTBKT] ^ P2W; ![%46] DENOTE PROL IN FILE
	$CALL (ADJEOF, .FST[FSTJFN], .SIZEOFFILE, FALSE);
						![%46] SET IN CASE $CONN NEV DONE
	RETURN TRUE

 END;	%( OF DOKEYBLOCKS )%



! MAKEIDB
! =======

! THIS ROUTINE CREATES A SINGLE INDEX DESCRIPTOR
!	IN THE PROLOGUE OF AN INDEXED FILE.  EACH
!	DESCRIPTOR COMPLETELY DESCRIBES THE CHARACTERISTICS
!	OF A PARTICULAR RECORD KEY.  EACH XAB WHICH
!	IS USED TO CREATE THESE DESCRIPTORS HAS ALREADY
!	BEEN CHECKED FOR ERRORS.
!	THE GENERAL STRUCTURE OF AN INDEX DESCRIPTOR IS:
!
!		HEADER ( 1 WORD )
!		GENERATED INFORMATION ( FIXED-LENGTH )
!		USER XAB ( VARIABLE LENGTH )
!		KEY NAME ( 6 WORDS )
!
!	THE FOLLOWING FIELDS ARE SET UP BY THIS ROUTINE:
!		BLOCKTYPE
!		BLOCKLENGTH
!		LEVELS ( ASSUMED TO BE 0 BECAUSE THIS IS A NEW PAGE )
!		ALL FIELDS WHICH ARE FETCHED FROM THE XAB
!		KEY-NAME
!
!	THE FOLLOWING FIELDS ARE <NOT> SET UP BY THIS ROUTINE AND
!	ARE LISTED WITH A DESCRIPTION OF WHO SETS THEM UP:
!		ROOT		WHEN THE ROOT IS INITIALLY ALLOCATED
!		NXTIDB		WHEN THE NEXT IDB IS CREATED (BY DOKEYBLOCKS)


! INPUT:
!	POINTER TO START OF FILE PROLOGUE
!	POINTER TO PLACE TO WRITE IDB
!	POINTER TO USER XAB

! OUTPUT:
!	<NO STATUS RETURNED>
!

 GLOBAL ROUTINE MAKEIDB ( PROLOGPTR, IDBPTR, XABPTR ):NOVALUE =
 BEGIN
 	ARGUMENT (PROLOGPTR,BASEADD);		 	! PROLOG ADDRESS
 	ARGUMENT (IDBPTR,BASEADD);			! OUR ADDRESS
 	ARGUMENT (XABPTR,BASEADD);			! XAB
 
 REGISTER
    MOVINGPTR,
    SIZEOFXAB,
    TEMPAC;	
 
 MAP
    PROLOGPTR:	POINTER,
    IDBPTR:	POINTER,
    XABPTR:	POINTER,
    MOVINGPTR:	POINTER;
 
 LOCAL
    TEMP;
 
 MAP
    TEMPAC:	FORMAT;

	TRACE ( 'MAKEIDB' );

	%([ SET THE SIZE OF THIS XAB ])%

	SIZEOFXAB = .XABPTR [ BLOCKLENGTH ];

	%([ FILL IN HEADER OF IDB ])%

	IDBPTR [ BLOCKHEADER ] = ( IDBCODE ^ BLKTYPELSH ) + .SIZEOFXAB + IDBSIZE;

	%([ WE WILL NOW MOVE THE ENTIRE USER'S
	XAB INTO THIS BLOCK.  NOTE THAT WE
	ASSUME THAT ALL FIELDS ARE INITIALLY ZERO
	(SINCE THIS IS A VIRGIN FILE PAGE).
	THEREFORE, WE DONT HAVE TO CLEAR ANY FIELDS ])%

	MOVINGPTR = .IDBPTR + IDBXABOFFSET;		! POINT TO XAB

	%([ MOVE THE ENTIRE XAB INTO THE FILE IDB ])%

	MOVEWORDS	( %( FROM )%	.XABPTR,
			  %( TO )%	.MOVINGPTR,
			  %( SIZE )%	.SIZEOFXAB );
	XABPTR = .MOVINGPTR;				! RESET THE POINTER TO THE NEW XAB POSITION

	%([ WE HAVE NOW MOVED THE XAB IN.  WE
	   MUST CHECK IF THERE IS A KEY-KAME
	   AND, IF SO, MOVE IT TO THIS ADB ])%

	IF ( TEMPAC = .XABPTR [ XABKNM ] ) ISNT ZERO
	THEN
		MOVEWORDS	( %( FROM )%	.TEMPAC,
				  %( TO )%	.MOVINGPTR + .SIZEOFXAB,
				  %( SIZE )%	KEYNAMESIZE );



	%([ LETS SEE IT ])%

	%IF DBUG %THEN
 	CALLDUMPIDB ( BPT ( IDBPTR ) );
 	ENDDEBUG;
	%FI

	RETURN

 END;	%( OF MAKEIDB )%


! GETIDB
! ======

! ROUTINE TO LOCATE AN INDEX DESCRIPTOR BLOCK IN THE PROLOGUE
!	OF AN INDEXED FILE. THIS ROUTINE ASSUMES THAT THE GLOBAL
!	"KDB" IS SET TO POINT TO THE CURRENT KEY DESCRIPTOR BLOCK.
!	THIS ROUTINE WILL LOCATE THE ASSOCIATED INDEX DESCRIPTOR
!	AND RETURN A POINTER TO IT. IT IS THE CALLER'S RESPONSIBILITY
!	TO FLUSH THE BUCKET DESCRIPTOR WHICH IS RETURNED.

! NOTES:
!
!	1.	LOCKING IS <<NEVER>> DONE FOR THE FILE PROLOGUE

! INPUT:
!	BKTDESC		ADDRESS OF CALLER'S BUCKET DESCRIPTOR


! OUTPUT:
!	FALSE:		ERROR
!	NOT FALSE:	ADDRESS IN CORE OF INDEX DESCRIPTOR

! ROUTINES CALLED:
!	GPAGE


 GLOBAL ROUTINE GETIDB ( BKTDESC ) =
 BEGIN
 	ARGUMENT	(BKTDESC,BASEADD);		! BUCKET DESCRIPTOR
 
 MAP
    BKTDESC:	POINTER;
 EXTERNAL ROUTINE
    GETBKT;			! GET A BUCKET
 LOCAL
    FILEBUCKET:	FORMAT;		! BUCKET NUMBER OF THE INDEX DESCRIPTOR
 
 REGISTER
    FILEADDRESS,		! ADDRESS OF THE IDB
    IDBPTR:	POINTER;
 

	TRACE ( 'GETIDB' );
	CHECKEXACTCOUNT;

	%([ FETCH THE ADDRESS OF THE INDEX DESCRIPTOR ON DISK ])%

	FILEADDRESS = .KDB [ KDBIDBADDR ];		! GET ADDRESS
	FILEBUCKET = ( .FILEADDRESS ^ W2P ) ^ P2B;	! CONVERT TO BUCKET NUMBER

	%([ GET THE BUCKET WHICH CONTAINS THIS IDB ])%

	IF CALLGETBKT (	%(BKT #)%		LCI ( FILEBUCKET ),
			%(BKZ)%		PCI ( 1 ),
			%(LOCK FLAG)%	PCI ( FALSE ),
			%(BKT DESC)%	BPT ( BKTDESC ) ) IS FALSE

	%([ DID ANYTHING HAPPEN? ])%

	THEN RETURN FALSE;			! RETURN FALSE ON ERROR

	%([ FORM A IN-CORE POINTER TO THE INDEX DESCRIPTOR ])%

	IDBPTR = ( .BKTDESC [ BKDBKTADR ] ) OR ( .FILEADDRESS AND OFSETMASK );

	RETURN .IDBPTR

 END; %(OF GETIDB)%
END
ELUDOM