	.TITLE	RANCOM
/ 
/ 
/                   FIRST PRINTING, FEBRUARY 1974
/ 
/ THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO 
/ CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED
/ AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
/ DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPON-
/ SIBILITY FOR ANY ERRORS THAT MAY APPEAR IN THIS
/ DOCUMENT.
/ 
/ THE SOFTWARE DESCRIBED IN THIS DOCUMENT IS FUR-
/ NISHED TO THE PURCHASER UNDER A LICENSE FOR USE ON
/ A SINGLE COMPUTER SYSTEM AND CAN BE COPIED (WITH
/ INCLUSION OF DIGITAL'S COPYRIGHT NOTICE) ONLY FOR 
/ USE IN SUCH SYSTEM, EXCEPT AS MAY OTHERWISE BE PRO-
/ VIDED IN WRITING BY DIGITAL.
/ 
/ DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY
/ FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIP-
/ MENT THAT IS NOT SUPPLIED BY DIGITAL.
/ 
/ COPYRIGHT (C) 1974, BY DIGITAL EQUIPMENT CORPORATION
/ 
/ 
        .EJECT
/
/COPYRIGHT 1971,1973, DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
/
/EDIT #014  13 DEC 73  *TAM*REF*WAD*
/
/PACKAGE OF RANDOM ACCESS ROUTINES COMMON
/    TO RBCDIO AND RBINIO
/
/ROY FOLK,W.A. DESIMONE,M. HEBENSTREIT
/
/ASSEMBLE PARAMETERS:
/
/DEFINE RSX FOR RSX SYSTEMS.
/NO PARAMETERS FOR DOS15 SYSTEMS.
/
/  INTERNAL GLOBALS--
	.GLOBL	.RCDNM		/RCD. NUM.
	.GLOBL	.INRRW		/INIT. RANDOM RD./WR.
	.GLOBL	.FNPTR		/PTR. TO HDR. WD. 0 OF RCD.
	.GLOBL	.RIO		/RANDOM I/O
	.GLOBL	.ADAVR		/ADDR. OF ASSOC. VAR.
	.GLOBL	.LRFLG		/LAST RCD. FLG.
	.GLOBL	.MDSW		/MODE SW.: =0 (BIN); =2 (ASCII)
	.GLOBL	RANCOM
RANCOM=.
/  EXTERNAL GLOBALS--
	.GLOBL	.FH		/R/W FLG (FIOPS)
	.GLOBL	.FM		/WDS. PER RCD. (FIOPS)
	.GLOBL	.FN		/ADDR. OF FIRST WD OF L.B. (FIOPS)
	.GLOBL	.ER		/ERROR (OTSER)
	.GLOBL	.PRMTB		/PARAM. TABLE ADDR. (DEFINE)
	.GLOBL	.ENDTB		/ADDR. AFTER LAST IN PARAM. TABLE (DEFINE)
/CONSTANTS
S00001	000001
S00002	000002
S00003	000003
S00004	000004
S00005	000005
S00020	20
S00077	000077
S00177	000177
S00377	000377
S04000	004000
S01777	1777
V77777	377777
W00000	400000
/WORKING STORAGE
SLOT	0			/SLOT NUMBER
TBPTR	0			/TABLE POINTER
RCDSBL	0			/NUM. OF RCDS. PER BLOCK
RCDSFL	0			/RECORDS PER FILE
BLKNUM	0			/BLOCK NUM.
RCINDX	0			/RELATIVE NUM. OF RCD. IN LAST BLOCK
NGINDX	0			/NEGATIVE RCINDX MINUS ONE
TOTAL	0			/TEMP STORAGE FOR CHECKSUM
WDCNT	0			/TEMP STORAGE FOR DATA WDS. IN RECORD
	.IFDEF RSX
PLATTER	0			/TEMP STORE FOR UNIT AND PLATTER
	.ENDC
PRSRCD	0			/WD. PRS. PER RCD.
.RCDNM	0
.FNPTR	0
.ADAVR	0
.LRFLG	0
.MDSW	0
MDPRM	0			/MODE PARAMETER
BLKRCD	0		/BLKS. PER RCD. - ALWAYS =1 FOR ASCII
TEMP	0
IDADRS	0		/ADDR. OF I.D. WD. IN BIN. RCD.
LBLRC	0		/LAST BLK. OF RCD. FLG. - =0: NOT LAST BLK.
STFM	0		/STORE .FM - WDS. PER LAST BLK. OF RCD.
	.EJECT
/INITIALIZE RANDOM READ OR RANDOM WRITE
/CALLING SEQUENCE --
/	JMS	.INRRW
/	(AC HOLDS ADDRESS OF SLOT NUMBER
.INRRW	0
/GET AND TEST SLOT NUM.
	DAC	SLOT
	SMA
	JMP	AB
	LAC*	SLOT		/TRANSFER VECTOR - GO ONE MORE
	DAC	SLOT		    /LEVEL OF INDIRECT
AB	LAC*	SLOT
	SMA!SZA
	JMP	CD
	JMS*	.ER		/ERROR IF SLOT NUM. ZERO
	10			    /OR NEGATIVE
CD	AND	S00077
	DAC	SLOT
	.IFDEF	RSX
	ISZ	XFAFL		/SET FIRST ACCESS FLAG.
	.ENDC
/CHK. RCD. NUM. .GT. 0, .LE. 377777
	LAC	.RCDNM
	RCL
	SNL!SZA			/SKP IF 0 OR MINUS
	JMP	A1
	JMS*	.ER
	24			/ILL. RCD. NUM
/
A1	LAC	.FN
	TAD	S00002
	DAC	IDADRS		/ADDR. OF I.D.WD.
	JMS	FPTENT		/FIND .PRMTB ENTRY
/EXTRACT FILE PARAMETERS FROM .PRMTB ENTRY
/  FIRST WORD
	LAC*	TBPTR
	RTR
	RTR
	RTR
	AND	S01777		/1777
	DAC	BLKRCD		/BLKS. PER RCD.
/  SECOND WORD
	ISZ	TBPTR		/SECOND WORD OF .PRMTB ENTRY
	LAC*	TBPTR
	AND	S00077
	DAC	RCDSBL		/RCDS. PER BLOCK
	LAC*	TBPTR
	DZM	MDPRM
	SPA			/SKIP IF BIT #0=1 (BINARY MODE)
	ISZ	MDPRM		/ASCII - SET MDPRM=1
	RTR
	RTR
	RTR
	AND	S00177
	DAC	PRSRCD		/WORD PAIRS PER RECORD
	TAD	PRSRCD
	DAC*	.FM		/WORDS PER RECORD
	DAC	STFM
	LAC	MDPRM
	RCL			/NOW =2 IF ASCII; =0 IF BINARY
	SAD	.MDSW
	JMP	GON
	JMS*	.ER
	25			/MODE DIFFERENT FROM MODE OF DEFINITION
/  THIRD WORD
GON	ISZ	TBPTR		/THIRD WORD OF .PRMTB ENTRY
	LAC*	TBPTR
	AND	V77777		/377777
	DAC	RCDSFL		/RECORDS PER FILE
	CMA
	TAD	.RCDNM		/RCDNM - RCDSFL - 1
	SPA			/
	JMP	EF		/NEG.: OK
	SPA!SNA			/IF =0, THEN RCDNUM IS 1 .GT. RCDSFL
	JMP	GON1		    /AND THIS IS EOF 'RECORD'
	JMS*	.ER
	24			/RCD. NUM. TOO LARGE
GON1	LAC	S00005		/MUST SIMULATE EOF ERROR FOR 'END'
	JMS*	.ER		    /COMPON. OF R/W STATEMENT
	11
/  FOURTH WORD
EF	ISZ	TBPTR		/FOURTH WORD OF .PRMTB ENTRY
	LAC*	TBPTR
	DAC	.ADAVR		/ADDR. OF ASSOC. VAR.
	DZM	BLKNUM
	LAC	.RCDNM		/SET ASSOC. VAR. TO PRESENT RCD. NUM.
	DAC*	.ADAVR		/IT WILL BE INCREMENTED LATER
/INTEGER DIVIDE TO DETERMINE NUM. OF REQUIRED BLOCK
/  OR MULTIPLY IF RCD. LENGTH  .GT. 1 BLK.
	LAC	RCDSBL
	SZA			/SKP IF BLKRCD .GT. 1
	JMP	DIVD		/DIVISION METHOD NEC.
	LAC	.RCDNM
	CMA
	TAD	S00002		/-(.RCDNM-1)
	SNA
	JMP	MUL2		/AC=0 IF RCD. NUM.=1
	DAC	TEMP
	CLA
MUL1	TAD	BLKRCD
	ISZ	TEMP
	JMP	MUL1		/MORE
MUL2	TAD	S00001		/FIRST BLK. OF REQUIRED RCD.
	DAC	BLKNUM
	LAC	S00001
	DAC	RCINDX		/ONLY RCD. IN BLK. IS FIRST ONE
	LAC	.FN		/FIRST WD. OF BUFFER
	DAC	.FNPTR
	JMP	IRW
DIVD	LAC	.RCDNM
	CMA
	TAD	S00001
AGN	TAD	RCDSBL		/RCSBLK - RCDNUM
	SZA!SMA
	JMP	DUN		/IF POS., DONE
	ISZ	BLKNUM		/IF 0 OR NEG., GO AGAIN
	JMP	AGN
DUN	CMA
	TAD	S00001
	TAD	RCDSBL
	SZA			/IF REMAINDER .GT. 0, INCREM. BLKNUM
	ISZ	BLKNUM
	SNA
	TAD	RCDSBL		/SET INDEX TO LAST RCD. IF REMAIN.=0
	DAC	RCINDX
/SET .FNPTR TO POINT TO DESIRED RECORD IN BLOCK
	CMA
	TAD	S00001
	DAC	NGINDX
	LAC	.FN
	SKP
ADDWDS	TAD*	.FM		/WDS. PER RCD.
	ISZ	NGINDX
	JMP	ADDWDS
	DAC	.FNPTR
/
	.IFDEF	RSX
IRW	LAC	BLKNUM		/BLK. #
	JMS	RTRNWT		/GET OR PUT REL 256 WORD BLK.
	DZM	.LRFLG		/CLR. LAST RECORD FLAG.
	JMP*	.INRRW
	.ENDC
	.IFUND	RSX
IRW	JMS	INIRTN		/INIT. RTRAN AND .WAIT CAL'S
	LAC	BLKNUM
	JMS	RTRNWT		/.RTRAN IN 1ST BLOCK
	DZM	.LRFLG		/CLR. LAST RCD. FLG.
	JMS	SZCHK		/SIZE CHECK
	JMP*	.INRRW
	.ENDC
	.EJECT
/FIND .PRMTB ENTRY
/CALLING SEQUENCE
/	JMS	FPTENT
/ON RETURN, TBPTR (TABLE POINTER) HOLDS ADDR.,
/  IN .PRMTB, OF WORD 0 OF PROPER ENTRY
FPTENT	0
	LAC	.PRMTB
NXTENT	DAC	TBPTR
	LAC*	TBPTR		/CONTENTS OF WD. 0 OF ENTRY
	SPA			/BIT 0=0 IF NOT ACTIVE
	JMP	ACTFIL		/'ACTIVE FILE'
INCPTR	LAC	TBPTR		/CHECK WD. 0 OF NEXT
	.IFUND	RSX
	TAD	S00004		    /ENTRY
	.ENDC
	.IFDEF	RSX
	AAC	+6		/ENTRY
	.ENDC
	SAD	.ENDTB		/IF END OF .PRMTB IS
	JMP	ERR2		    /REACHED, ERROR
	JMP	NXTENT
ACTFIL	AND	S00077		/SLOT NUM. IN LAST 9 BITS
	SAD	SLOT
	JMP*	FPTENT		/RTN. WITH CORRECT TBPTR
	JMP	INCPTR
ERR2	JMS*	.ER
	21			/UNDEFINED FILE
	.EJECT
	.IFUND	RSX
/INIT. .RTRAN AND .WAIT
/CALLING SEQUENCE --
/	JMS	INIRTN
INIRTN	0
	LAC	SLOT
	DAC	WLC0		/.WAIT LOC 0
	XOR	S04000
	DAC	RLC0		/.RTRAN LOC 0
	LAC	.FN
	AND	V77777
	DAC	RLC3		/.RTRAN LOC 3
	JMP*	INIRTN
	.EJECT
/
/.RTRAN, THEN .WAIT
/CALLING SEQUENCE --
/	JMS	RTRNWT
/	(AC HAS BIT 0 = 0 IN
/		     = 1 OUT
/	BITS 1-17= BLKNUM)
RTRNWT	0
	DAC	RLC2		/.RTRAN LOC 2
RLC0	CAL	0		/.RTRAN CAL+4000+.DAT
	2
RLC2	XX			/I/O AND BLK. NUM.
RLC3	XX			/FIOPS BUFFER ADDRESS
	0
	-376			/WORD CNT. FOR DISK
WLC0	CAL	0
	12
	LAC	RLC3	
	SMA			/SKP IF BIT #0 =1 (PARITY ERROR)
	JMP*	RTRNWT
	LAC	S00020
	JMS*	.ER
	11
	.EJECT
/SIZE CHECK
/  CHECK NUM. OF WDS. IN RCD. AGAINST RCD. SIZE
/  AS INDICATED IN .PRMTB
/CALLING SEQUENCE --
/	JMS	SZCHK
SZCHK	0
	LAC	RCDSBL
	SZA			/SKP IF BIN. W/ .GT. 1 BLKRCD
	JMP	SZ1
	LAC*	IDADRS		/GET I.D. WD.
	SPA			/SKP IF NOT LAST BLK.
	JMP	SZ1
	DZM	LBLRC		/NOT LAST BLK. IN RCD.
	LAC	S00177
	DAC	TEMP
	TAD	TEMP
	DAC*	.FM		/376(8) WDS. IN THIS BLK.
	JMP	SZ2
SZ1	ISZ	LBLRC		/LAST BLK. OF RCD
	LAC	STFM		/WDS. IN LAST BLK.
	DAC*	.FM
	LAC	PRSRCD		/PRS. IN LAST BLK.
	DAC	TEMP
SZ2	LAC*	.FNPTR
	RTR
	RTR
	RTR
	RTR
	RAR
	AND	S00377		/MASK OFF WD. PR. CNT.
	SAD	TEMP
	JMP*	SZCHK
	JMS*	.ER		/WRONG SIZE ERROR
	23
	JMP*	SZCHK
	.EJECT
	.ENDC
	.IFDEF	RSX
/SUBROUTINE TO GET OR PUT A 256(10) WORD BLOCK OF RF DISK.
/UPON ENTRY, THE AC CONTAINS A 17-BIT RELATIVE BLOCK NO.(RELATIVE
/TO  BEGINNING OF DIRECT ACCESS FILE UNDER PROCESS.).  BIT 0 OF AC
/=1 FOR PUT, =0 FOR GET.
/
RTRNWT	0
	DAC	XT1		/SAVE.
	LAC	XFAFL		/FIRST ACC. FOR F4 I/O STATEMENT.
	DZM	XFAFL		/REINIT.
	SNA
	JMP	XBYP1		/NO.  BASE INFO. ALREADY SETUP.
	ISZ	TBPTR		/YES.  5TH WORD OF .PRTMB ENTRY.
	LAC*	TBPTR		/UNIT #(0-2),DEV.CODE(3-8),PLATTER#(9-17)
	SWHA			/RIGHT ADJUST DEVICE CODE
	AND	(77)		/MASK  OUT DEVICE CODE
	DAC	GPCPB4		/PUT INTO LAST WORD OF CPB
	SWHA			/FORM MASK TO GET UNIT NUMBER AND 
	XOR*	TBPTR		/NUMBER FROM THIS .PRMTB ENTRY
	DAC	GPCTB0		/GET/PUT CTB.
	DAC	PLATTER		/SAVE UNIT AND PLATTER FOR LATER
	ISZ	TBPTR		/6TH WORD OF .PRMTB ENTRY.
	LAC*	TBPTR		/BASE ADDRESS OF FILE (0-777777).
	DAC	XBFA		/SAVE BASE FILE ADDRESS.
	LAC	.FN		/FIOPS BUFFER ADDRESS.
	DAC	GPCTB2		/GET/PUT CTB.
XBYP1	LAC	XT1		/RESTOER ENTRY AC.
	SPA!CLA			/GET OR PUT?  (NEG. = PUT)
	TAD	(100)		/GET
	TAD	(13000)		/PUT, MULTI-DISK FORM
	DAC	XGPCAL		/SET CPB FUNCT. CODE.
	LAC	XT1		/GET REL. BLOCK NO.
	AND	(377777)	/MASK OFF SIGN BIT.
	AAC	-1		/REL. BLK. NO. - 1 AS ONE FACTOR.
	CLL			/FOR MUL INSTR.
	MUL
	400			/BLK. SIZE (256(10)).
	LACQ			/POS. RESULT GUARANTEED.
	TAD	XBFA		/ADD BASE FILE ADDR.
	DAC	GPCTB1		/NOT GUARANTEED L.E. 2**18 - 1.
	SZL			/IF OVERFLOW, BUMP HIGHER ORDER WORD
	ISZ	GPCTB0
	CAL	XGPCAL		/GET/PUT I/O REQ.
	CAL	XWFCAL		/WAITFOR REQ.
	LAC	PLATTER		/RESTORE THE PLATTER AND UNIT
	DAC	GPCTB0
	LAC	GPEV		/CHK. EV FOR DISK ERRORS.
	DZM	GPEV		/REINIT.
	SMA			/ERRORS?
	JMP*	RTRNWT		/NO.  EXIT.
	AND	(130000)	/YES.  CHK. RF. STATUS FOR PARITY OR
				/WRITE CHK. ERRORS.
	SNA
	JMP	XERR20		/NO.  OTHER I/O ERRORS.
	LAC	S00020		/YES.  FOR END= OR ERR= EXITS.
	JMS*	.ER
	11
XERR20	JMS*	.ER
	20			/.OTS 20.
	.EJECT
/
/GET-PUT CPB AND CTB (FOR RF DISK ONLY).
/
XGPCAL	XX			/FUNCT. CODE (13000=GET,13100=PUT)
GPCPB1	GPEV			/EV.
GPCPB2	1			/LUN 1 ALWAYS. (TIED TO RF.)
GPCPB3	GPCTB0			/CTB. ADDR.
GPCPB4	0			/DEVICE CODE -2=RF,3=RP,24=RK
GPCTB0	0			/UNIT NUMBER;DSK. PLATTER #.
GPCTB1	0			/STARTING DISK ADDR. (0-777777).
GPCTB2	0			/STARTING CORE ADDR.
GPCTB3	400			/LENGTH OF TRANS.  (256(10) WORDDS).
/
/WAITFOR CPB.
/
XWFCAL	20
	GPEV
/
/TEMPS.
/
RECA	0			/RECORD ADDRESS.
GPEV	0			/GET/PUT EV.
XT1	0			/TEMP.
XBFA	0			/BASE FILE ADDR.
XFAFL	0			/FIRST ACCESS FLAG.
	.ENDC
	.EJECT
/RANDOM I/O
/WHEN CALLED BY I/O CLEANUP ROUTINE --
/    INSERT CHKSUM AND HDR. WD. 0 FOR LAST RCD. AND
/    .RTRAN OUT
/WHEN CALLED BY END-OF-RECORD ROUTINES --
/    OUTPUT (IF WRITE) AND SET PTRS TO NEW RCD.
/CALLING SEQUENCE --
/	JMS	.RIO
.RIO	0
	LAC*	.FH
	SNA			/SKP IF WRITE
	JMP	RIO1		/READ - JMP OVER OUTPUT
/ASSEMBLE HDR. WD. 0 AND INSERT INTO BUFFER
	LAC*	.FM		/WDS. PER RCD.
	CLL!RTL
	RTL
	RTL
	RTL			/NOW HAVE PRS. PER RCD. IN PROPER SPOT
	XOR	.MDSW		/MODE SW.: =0,BIN; =2, ASCII
	DAC*	.FNPTR		/PTS. TO WD. 0
/CALCULATE CHECKSUM
	DAC	TOTAL		/TEMP STORAGE FOR CHECKSUM
	LAC*	.FM		/WDS. PER RCD.
	CMA
	TAD	S00003
	DAC	WDCNT		/CNTR. FOR DATA WDS. IN RCD.
	ISZ	.FNPTR
	ISZ	.FNPTR		/POINTS TO FIRST DATA WORD
	LAC	TOTAL
RIO2	TAD*	.FNPTR
	ISZ	.FNPTR
	ISZ	WDCNT		/SKIP IF ALL WDS. ADDED
	JMP	RIO2
	CMA			/CHECKSUM IS 2'S COMPLEMENT
	TAD	S00001		    /OF SUM
	DAC	TOTAL		/FINAL CHECKSUM
	LAC*	.FM
	CMA
	TAD	S00002
	TAD	.FNPTR		/SET. FNPTR TO CHECKSUM WD.
	DAC	.FNPTR
	LAC	TOTAL
	DAC*	.FNPTR		/PUT IN CHECKSUM
	LAW	-1
	TAD	.FNPTR
	DAC	.FNPTR		/RESET FNPTR TO WD. 0 OF RECORD
/TEST FOR LAST RECORD
	LAC	.LRFLG		/LAST RECORD FLG
	SNA
	JMP	RIO1
	LAC	BLKNUM
	XOR	W00000
	JMS	RTRNWT
	JMP*	.RIO
/CHECK FOR .RCDNM TOO LARGE
RIO1	LAC	LBLRC
	SNA			/SKP IF LAST BLK.
	JMP	RIO7
	ISZ	.RCDNM
	ISZ*	.ADAVR
	LAC	.RCDNM
	CMA
	TAD	S00001
	TAD	RCDSFL		/RCDSFL-RCDNM
	SMA			/SKP IF TOO LARGE
	JMP	RIO3		/RCDNM OK
	LAC*	.FH		/R/W FLG
	SNA			/SKP IF WRITE
	JMP	ERR1		/READ
	LAC	BLKNUM		/WRITE - MUST .RTRAN
	XOR	W00000		    /OUT LAST RCOS. WRITTEN
	JMS	RTRNWT
ERR1	LAC	S00005		/THIS IS A SIMULATION OF DETECTION
	JMS*	.ER		    /OF EOF HEADER - SIGNALS OTS
	11			    /  FOR 'END' RTN.
/INCREMENT RCINDX AND BRING IN NEW BLOCK
/  IF NECESSARY
RIO3	ISZ	RCINDX
	LAC	RCINDX
	CMA
	TAD	S00001
	TAD	RCDSBL		/RCSBLK-RCINDX
	SMA			/SKIP IF INDEX TOO LARGE
	JMP	RIO4		/NXT. RCD IN SAME BLOCK
RIO7	LAC*	.FH
	SNA			/SKP IF WRITE
	JMP	RIO5		/READ
	LAC	BLKNUM		/WRITE - OUTPUT BLK
	XOR	W00000
	JMS	RTRNWT
RIO5	ISZ	BLKNUM
	LAC	BLKNUM
	JMS	RTRNWT		/.RTRAN NXT. BLK. IN
	DZM	RCINDX
	ISZ	RCINDX		/SET UP FOR ACCESS
	LAC	.FN		    /OF FIRST RCD. OF
	DAC	.FNPTR		    /  NEW BLOCK
	JMP	RIO6
RIO4	LAC*	.FM		/IF NXT RCD IN SAME BLK.,
	TAD	.FNPTR		    /SET FNPTR TO WD. 0
	DAC	.FNPTR		    /  OF NEW RCD.
	.IFUND	RSX
RIO6	JMS	SZCHK
	JMP*	.RIO
	.ENDC
	.IFDEF	RSX
RIO6	JMP*	.RIO
	.ENDC
	.END
