	.TITLE		LOADTABLE

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to load internal program tables from CSG Table Files.          ;;
;;    (Default CSG table file is "REMOTE$TABLES:REMTAB.DAT")                ;;
;;                                                                          ;;
;;   Calling Sequence (from a COBOL program):                               ;;
;;                                                                          ;;
;;        CALL "LOADTABLE" USING                                            ;;
;;                                                                          ;;
;;             BY DESCRIPTOR <Table File Name>                              ;;
;;                           <Table Name>                                   ;;
;;             BY REFERENCE  <Table Address>                                ;;
;;                           <Entry Size>                                   ;;
;;                           <Table Size>                                   ;;
;;                           <Entry Count>                                  ;;
;;             .                                                            ;;
;;             .                                                            ;;
;;             .                                                            ;;
;;                                                                          ;;
;;         GIVING <Return Status>.                                          ;;
;;                                                                          ;;
;;        <Table File Name> contains the name of the file in which the      ;;
;;                          tables to be loaded are located.                ;;
;;                                                                          ;;
;;        <Table Name> contains the name of the table to be loaded.         ;;
;;                                                                          ;;
;;        <Table Address> is the address of the data structure to           ;;
;;                        recieve the loaded table.                         ;;
;;                                                                          ;;
;;        <Entry Size> contains the number of bytes per table entry.        ;;
;;                                                                          ;;
;;        <Table Size> contains the maximum number of entries that          ;;
;;                     can be loaded.                                       ;;
;;                                                                          ;;
;;        <Entry Count> will contain the number of entries that were        ;;
;;                      actually loaded by the routine.                     ;;
;;                                                                          ;;
;;        <Return Status> will contain the return status of the routine.    ;;
;;                                                                          ;;
;;        <Entry Size>, <Table Size> and <Entry Count> must be defined      ;;
;;         as VAX Word items, PICTURE 9(1) - 9(4), USAGE IS COMP.           ;;
;;                                                                          ;;
;;        <Return Status> must be defined as a Signed Vax Longword item,    ;;
;;         PICTURE S9(9), USAGE IS COMP.                                    ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   File Access Block (FAB)                                                ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FABBLK:	$FAB,-					; File Access Block
		FAC = GET,-			; File Access type is Input
		ORG = REL,-			; Organization is Relative
		RFM = VAR,-			; Record length is variable
		DNM = <REMOTE$TABLES:REMTAB.DAT> ; Default file spec

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Record Access Block (RAB)                                              ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RABBLK:	$RAB,-					; Record Access Block
		FAB = FABBLK,-			; Access of FAB
		RAC = KEY,-			; Access Mode is Random
		KSZ = 4,-			; Key is longword Record No.
		KBF = TABKEY,-			; Address of Record No.
		UBF = RECBUF,-			; Record Buffer Address
		USZ = 405			; Record Size

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Other file related structures                                          ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DEFNAM:	.ASCII		/REMOTE$TABLES:REMTAB.DAT/ ; Default table file name
DEFSIZ:	.BYTE		DEFSIZ-DEFNAM		; Default table file name size
TABKEY:	.LONG		0			; Relative Key
RECBUF:	.BLKB		405			; Record Buffer
RECPTR:	.LONG		4			; Size of Record Number
	.ADDRESS	RECBUF+13		; Address of Record Number
ENTPTR:	.LONG		4			; Size of Entry Count
	.ADDRESS	RECBUF+18		; Address of Entry Count
TABCNT:	.BLKL		1			; Number of tables to load
REMAIN:	.BLKL		1			; Remainder - old/new format?
OFFSET:	.BLKL		1			; Offset to repeating params
TABLIT:	.ASCII		"/TABLE"		; Table definition identifier

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Table load parameters                                                  ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TBLADR:	.BLKL		50			; Table Addresses
TBLSIZ:	.BLKW		50			; Bytes per table entry
TBLMAX:	.BLKW		50			; Maximum number of entries
TBLCTR:	.BLKL		50			; Address of table count var.
TBLREC:	.BLKL		50			; Next record to GET
TBLENT:	.BLKL		50			; Number of entries in table

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   1) Initialization.                                                     ;;
;;      o  Clear internal tables                                            ;;
;;      o  Determine call format - old or new                               ;;
;;         .  Old format uses default table file - REMOTE$TABLES:REMTAB.DAT ;;
;;         .  New format passes table name as first argument                ;;
;;                                                                          ;;
;;   1) Open the table file and connect.                                    ;;
;;                                                                          ;;
;;   2) Parse calling parameters against header and build load tables.      ;;
;;                                                                          ;;
;;   3) Load the requested tables.                                          ;;
;;                                                                          ;;
;;   4) Close the table file and return.                                    ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.ENTRY		LOADTABLE,-		; LOADTABLE Entry
			^M<R2,R3,R4,R5,R6,R7,R8>

	CLRL		TABKEY			; Initialize table key

	MOVL		#0,R5			; Initialize table index
ZAP:	CLRL		TBLADR[R5]		; Clear next table segment
	ACBL		#249,#1,R5,ZAP		; Loop until all cleared

	MOVAL		DEFNAM,FABBLK+FAB$L_FNA	; Move file name addr to FAB
	MOVB		DEFSIZ,FABBLK+FAB$B_FNS	; Move size of file name string
	MOVL		#4,OFFSET		; Default offset - old format

	MOVL		0(AP),R5		; Get number of parameters
	MOVL		#0,R6			; Clear other half of quad div
	EDIV		#5,R5,TABCNT,REMAIN	; Get number of tables to load

	CMPL		REMAIN,#0		; Old or new format?
	BEQL		OLD			; Old - Use default table file

	MOVL		#8,OFFSET		; New format - increase offset
	MOVL		AP,R5			; Get parameter pointer
	ADDL2		#4,R5			; Point to table file name param
	MOVL		0(R5),R7		; Get address of descriptor
	MOVL		4(R7),FABBLK+FAB$L_FNA	; Move file name addr to FAB
	CVTLB		0(R7),FABBLK+FAB$B_FNS	; Move size of file name string

OLD:	$OPEN		FAB = FABBLK		; Open Table File
	BLBC		R0,LEXIT		; Quit if error

	$CONNECT	RAB = RABBLK		; Connect to RAB Block
	BLBC		R0,LEXIT		; Quit if error

	JSB		FINIT			; Initialize table counts

	JSB		GETTAB			; Get tables to load
	BLBC		R0,LEXIT		; Quit if error

	JSB		LODTAB			; Load the tables
	BLBC		R0,LEXIT		; Quit if error

	$CLOSE		FAB = FABBLK		; Close Table File
	BLBC		R0,LEXIT		; Quit if error

LDONE:	MOVL		#1, R0			; Set Good Return Status

LEXIT:	RET					; Return to caller

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to initialize table counts to -1 to indicate failure status    ;;
;;   so that if by some chance the table doesn't get loaded the caller      ;;
;;   will know about it.                                                    ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FINIT:	MOVL		AP,R5			; Get Parameter pointer
	ADDL2		OFFSET,R5		; Point to first parameter
	CLRL		R6			; Init table counter
	
FLOOP:	INCL		R6			; Increment table counter
	CMPL		R6,TABCNT		; Compare with number of tables
	BGTR		FDONE			; Branch if out of tables

	ADDL2		#16,R5			; Point to table count address
	MOVW		#-1,@(R5)		; Init table count to failure

	ADDL2		#4,R5			; Point to next table
	BRW		FLOOP			; Next table

FDONE:	RSB					; Return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to look at passed parameters and file header records           ;;
;;    and get information for the requested tables.                         ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GETTAB:	INCL		TABKEY			; Increment Table Key

	JSB		READIT			; Read the record
	BLBC		R0,GEXIT		; Quit if error

	CMPC3		#6,RECBUF,TABLIT	; Is it a /TABLE rec?
	BNEQ		GDONE			; No, exit

	MOVL		AP,R5			; Get Parameter pointer
	ADDL2		OFFSET,R5		; Point to first parameter
	CLRL		R6			; Init table counter
	
GLOOP:	INCL		R6			; Increment table counter
	CMPL		R6,TABCNT		; Compare with number of tables
	BGTR		GETTAB			; Branch if out of tables

	MOVL		0(R5),R7
	CMPC5		#5,RECBUF+7,#^X20,0(R7),@4(R7)
						; Do we need this table?
	BEQL		GKEEP			; Branch if yes

	ADDL2		#20,R5			; Next Table Entry
	BRB		GLOOP			; Continue until found or end

GDONE:	MOVL		#1,R0			; Set Good Return Status

GEXIT:	RSB					; Return

GKEEP:	ADDL2		#4,R5			; Point to address of table
	MOVL		(R5),TBLADR[R6]		; Save address of table
	ADDL2		#4,R5			; Point to entry size address
	CVTLW		@(R5),TBLSIZ[R6]	; Save entry size
	ADDL2		#4,R5			; Point to max. entries address
	CVTLW		@(R5),TBLMAX[R6]	; Save max. entries
	ADDL2		#4,R5			; Point to table count address
	MOVL		(R5),TBLCTR[R6]		; Save table count address

	PUSHL		#0			; No flags
	PUSHL		#4			; Convert to word
	PUSHAL		TBLREC[R6]		; Where to put result
	PUSHAQ		RECPTR			; Pointer to Record Number
	CALLS		#4, G^OTS$CVT_TI_L	; Convert

	PUSHL		#0			; No flags
	PUSHL		#4			; Convert to word
	PUSHAL		TBLENT[R6]		; Where to put result
	PUSHAQ		ENTPTR			; Pointer to Entry Count
	CALLS		#4, G^OTS$CVT_TI_L	; Convert

	BRW		GETTAB			; Next record

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to load tables using tables built from header records.         ;;
;;                                                                          ;;
;;   TBLADR - Addresses of tables to load.                                  ;;
;;   TBLSIZ - Number of bytes per entry for each table.                     ;;
;;   TBLMAX - Maximum number of entries to load for each table.             ;;
;;   TBLCTR - Address of the counter for the number of entries loaded.      ;;
;;   TBLREC - Starting record number in the file for each table.            ;;
;;   TBLENT - Number of entries that exist in each table.                   ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LODTAB:	CLRL		R6			; Reset table index

LDLOOP:	INCL		R6			; Next table
	CMPL		TBLADR[R6],#0		; End of table?
	BEQL		LDDONE			; Branch if yes

	MOVL		TBLCTR[R6],R7		; Get address of counter
	CLRW		(R7)			; Init counter
	JSB		DOLOAD			; Load the table
	BLBC		R0,LDEXIT		; Quit if error

	BRB		LDLOOP			; Loop until all loaded

LDDONE:	MOVL		#1,R0			; Set Good Return Status

LDEXIT:	RSB					; Return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to read a record from the table file.                          ;;
;;                                                                          ;;
;;   TABKEY has record number to read.                                      ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

READIT:	$GET		RAB = RABBLK		; Get next record
	BLBC		R0,REXIT		; Quit if error

REXIT:	RSB					; Return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                          ;;
;;   Routine to load entries for a table.                                   ;;
;;                                                                          ;;
;;   R6 has index to table parameters for the table to be loaded.           ;;
;;                                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DOLOAD:	MOVL		TBLREC[R6],TABKEY	; Get record number
	JSB		READIT			; Go read record
	BLBC		R0,DOEXIT		; Quit if error

	SUBW		#5,RABBLK+RAB$W_RSZ	; Adjust record size

	MOVL		TBLADR[R6],R8		; Get table address

	MOVC5		RABBLK+RAB$W_RSZ,-	; Move characters from record
			RECBUF+5,-		; to next table entry
			#^X20,-			; Pad with spaces
			TBLSIZ[R6],-
			(R8)

	INCW		(R7)			; Increment table counter
	INCL		TBLREC[R6]		; Next record
	CVTWL		TBLSIZ[R6],R8		; Get size per entry
	ADDL		R8,TBLADR[R6]		; Point to next entry
	DECL		TBLENT[R6]		; Decrement entry count

	CMPL		TBLENT[R6],#0		; All entries loaded?
	BEQL		DODONE			; Branch if yes

	CMPW		(R7),TBLMAX[R6]		; Enough loaded?
	BGEQ		DODONE			; Branch if yes

	BRW		DOLOAD			; Go get next entry

DODONE:	MOVL		#1,R0			; Set Good Return Status

DOEXIT:	RSB					; Return

	.END
