/RD5A.PA NON-SYSTEM HANDLER
/

/ COPYRIGHT  (C) 1982 BY DIGITAL EQUIPMENT CORPORATION

/ 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 responsibility
/ for any errors that may appear in this document.

/ The software described in this document is furnished 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 provided in writing by DIGITAL.

/ Digital Equipment Corporation assumes no responsibility for the use
/ or reliability of its software on equipment that is not supplied by
/ DIGITAL.



/29-NOV-82
/13-AUG-84	REMOVED CTRL C CHECK
/
/	VER 002
/
/THE RD51 CONTROLLER FOR THE DECMATE II OPERATES ON BLOCK NUMBERS, IT
/PERFORMS ANY NECESSARY MAPPING TO CYLINDER, SURFACE AND SECTOR WITHIN A
/LOGICAL VOLUME.
/AS OS8 IS LIMITED TO 4096 BLOCKS, THIS IS THE LIMIT USED IN THIS HANDLER.
/TWO LOGICAL VOLUMES (RD50 = UNIT 0, RD51 = UNIT 1) ARE SUPPORTED.
/
/
	DEVCOD=700	/RD51 DEVICE CODE
/
/
RDSR=6001+DEVCOD	/SKIP ON DATA TRANSFER REQ. CLEAR IF SET
RDSC=6002+DEVCOD	/SEND COMMAND TO RD CONTROLLER
RDSD=6003+DEVCOD	/SKIP ON COMMAND DONE, CLEAR FLAG IF SET
RDTD=6004+DEVCOD	/TRANSFER DATA TO-FROM RD<->AC
			/DIRECTION DETERMINED BY COMMAND IN PROGRESS
RDWE=6005+DEVCOD	/SET-CLEAR INTERRUPT ENABLE WITH AC<11>
RDSE=6006+DEVCOD	/SKIP ON ERROR, CLEAR FLAG IF SET
/
/
/SOME DEFINITIONS
/
	MINUS3=CLA CLL CMA RTL
	AC4000=CLA CLL CML RAR
/
	EJECT
/
/TO READ OR WRITE FROM A VOLUME OF THE RD51 IT IS FIRST NECESSARY TO
/REQUEST THAT THE CONTROLLER "MOUNT" THE VOLUME. "VOLUME" IS EQUIVALENT
/TO THE OS78 "UNIT" AND IS ALLOCATED (BY MEANS TBD) WITHIN SOME BUILD PROCESS
/THAT EXISTS AS AN RD51 STANDALAONE UTILITY.
/
/THE COMMAND TO MOUNT_A_VOLUME IS :
/
/		ISSUE : RDSC WITH AC=0  /IOT "SEND_COMMAND"
/
/THEN SEND 13(DECIMAL) WORDS TO IDENTIFY THE VOLUME
/
/WORDS ARE AS FOLLOWS :-
/
/	WORD 1 		BIT 4 - ALLOW READ_ACCESSES (ALWAYS TRUE)
/			    5 - ALLOW WRITE_ACCESSES (ALWAYS TRUE)
/			    6 - DRIVE 0/1 (ALWAYS 0)
/			    7 - UNUSED
/			 8:11 - VOLUME NUMBER BY WHICH READ AND WRITE
/				ACCESSES WILL BE MADE AFTER MOUNT COMPLETE
/
/	WORD 2		 4:11 - FIRST CHARACTER OF VOLUME NAME
/	     3- 9	 4:11 - SECOND ->EIGHTH CHARACTER OF VOLUME NAME
/	WORD 10		 4:11 - FIRST CHARACTER OF VOLUME PASSWORD
/	     11 - 13	 4:11 - SECOND -> FOURTH CHARACTERS OF VOLUME PASSWORD
/
/
/THE VOLUME NUMBERS ARE 0 (UNIT/VOLUME 0) AND 1 (UNIT/VOLUME 1)
/
/THE VOLUME NAMES ARE "OS8....."   [. STANDS FOR "SPACE", CODE 240]
/                 AND "OS8A...."
/ALL CHARACTERS ARE "PAL-8 COMPATIBLE", I.E CODE+200
/
/THE PASSWORD FOR BOTH VOLUMES IS "0000" (260;260;260;260)
/
/HAVING MOUNTED THE VOLUME, THE ONLY COMMANDS AVAILABLE THROUGH THIS HANDLER
/ARE 		: READ_A_BLOCK : PERFORMED AS READ THEN EMPTY BUFFER
/    		: WRITE_A_BLOCK: PERFORMED AS FILL BUFFER THEN WRITE
/
/FOR BOTH OF THESE AN INITIAL SET_VOLUME_AND_BLOCK COMMAND IS ISSUED
/
/THE FORM OF THIS COMMAND IS :-   RDSC WITH AC=0001  /IOT "SEND_COMMAND"
/
/FOLLOWED BY SENDING THREE WORDS :-
/		WORD #1 - AC<8:11> VOLUME # (1 - 15), DEFINED
/				   IN THE MOUNT COMMAND
/		WORD #2 - AC<00:11> LOW ORDER BLOCK NUMBER
/		WORD #3 - AC<04:11> HIGH ORDER BLOCK NUMBER
/
/AS THE SIZE OF EACH VOLUME IS LIMITED BY OS78 TO A 12-BIT BLOCK NUMBER
/THE LOW ORDER BLOCK NUMBER ABOVE IS THE BLOCK NUMBER WITHIN A VOLUME
/THE HIGH ORDER BLOCK NUMBER  CAN BE ONLY 0 (VOLUME 0), OR 1 (VOLUME 1)
	EJECT
/
/BUILD BLOCK
/
/

	*0
	-2			/TWO ENTRY POINTS
	DEVICE RD5A		/DEVICE NAME
	DEVICE RD50		/VOLUME (UNIT 0) NAME
	4270			/DEVICE NUMBER
	ENTRY0&177+4000		/FIRST ENTRY POINT
	0
	0
	DEVICE RD5A		/NAME AGAIN
	DEVICE RD51		/OTHER VOLUME (UNIT 1)
	4270
	ENTRY1&177+4000
	0
	0
/
/END OF BUILD BLOCK
/
/THERE ARE TWO ENTRY POINTS, UNIT 0 AT ENTRY0 AND UNIT 1 AT ENTRY1
/IN ALL REFERENCES "UNIT" IS EQUIVALENT TO "VOLUME"
/
/THE FIRST THING ON LOADING THE HANDLER IS TO ESTABLISH THE LINKS FROM
/THE FIRST PAGE TO THE SECOND.THIS ONCE_ONLY CODE AREA ON THE SECOND PAGE
/IS THEN USED FOR VARIABLES
/
	*200
/
TOPAG,	0		/FILLED WITH ADDRESS OF TOP OF NEXT PAGE
			/GETS SETUP TO ADDRESS (ON NEXT PAGE) OF ROUTINE
			/TO MOUNT_VOLUME_AND_BLOCK
BUFCDF,	HLT
	JMS I	TOPAG	/GO TO PAGE 2 TO FIX LINKS
/LIST OF ADDRESSES TO MOVE TO PAGE 2
/
FUNCT,	0		/3 = WRITE, 4 = READ
WORDC,	0
PTR,	0
VOLNUM,	0
BLOCKL,	0
BLOCKH,	0		/ALWAYS ZERO
PAG2,	0		/GETS SETUP TO CONTAIN ADDRESS (ON NEXT PAGE)
			/OF ROUTINE TO READ/WRITE
	TAD	PAG2
	DCA	TOPAG	/ADDRESS OF MOUNT_VOLUME_AND_BLOCK
	TAD	K3	/RETURN HERE AFTER INIT
	DCA	CHGINS	/AND DELETE CALL TO ONCE_ONLY_CODE
	JMP	INITDN	/CONTINUE
/
ENTRY0,	0		/ENTRY FOR UNIT 0
	CLA	CLL
	JMS	MOUNTV	/MOUNT VOLUME
	0		/-1 SIGNIFIES THAT VOLUME NOT YET MOUNTED
/
ENTRY1,	0		/ENTRY FOR UNIT 1
	CLA CLL IAC	/NON-ZERO SAYS UNIT 1 FOR MOUNT COMMAND
	JMS	MOUNTV
	0		/-1 = VOLUME NOT YET MOUNTED
/
/VOLUME MOUNT ROUTINE, NOT REALLY A SUBROUTINE, BUT WE NEED TO PICK UP
/ARGUMENTS FOLLOWING CALL AND TO PRESERVE WHERE USER CALLED FROM. ENTRY IS
/LATER USED AS LINK TO USER CALLING POINT
/
MOUNTV,	0
	DCA	VOLNUM	/SAVE 0 OR 1
	TAD	MOUNTV
	DCA	TEMP1	/FOR NOW, CLEAN UP LATER
	TAD	VOLNUM
	TAD	KRW	/FORM CORRECT MOUNT COMMAND
	DCA	VOLID0
	RDF		/READ USER'S CALLING FIELD
	TAD	KCDF	/FORM CDF USER_FIELD
	DCA	CALFLD
/NOW GET OS CALLING ARGUMENTS
/
	MINUS3		/BACK UP TO USER CALLING ADDRESS+1
	TAD	MOUNTV
	DCA	MOUNTV	/DON'T CARE ABOUT DESTROYING ENTRY
	CDF
	TAD I	MOUNTV
	DCA	MOUNTV
CALFLD,	HLT		/SETUP TO CDF USER_CALLING_FIELD
	AC4000		/STANDARD OS8 ARGUMENT GATHERING
	TAD I	MOUNTV	/FIRST ARGUMENT
	AND	K70	/ISOLATE BUFFER FIELD
	TAD	KCDF	/AND CREATE CDF BUFFER_FIELD
	DCA	BUFCDF
	TAD	K3
	SNL		/LINK CONTAINS READ_WRITE BIT
	CLL	IAC	/CHANGE TO 4 FOR READ
	DCA	FUNCT	/3=WRITE, 4=READ
	CLA CLL CML RTL	/AC=0002
	TAD	CALFLD
	DCA	EXCDIF	/RETURN TO USER_CALLING_FIELD
	TAD I	MOUNTV	/FIRST ARGUMENT AGAIN
	CLL	RAL	/MOVE PAGE COUNT TO AC<0:4>
	AND	KK7600	/AND ISOLATE
	CIA		/AND TURN IT INTO NEGATIVE WORD COUNT
	DCA	WORDC
	ISZ	MOUNTV	/NEXT ARGUMENT
	TAD I	MOUNTV	/GET THE BUFFER ADDRESS
	DCA	PTR	/SAVE IT
	ISZ	MOUNTV
	TAD I	MOUNTV
	DCA	BLOCKL	/STARTING BLOCK NUMBER FOR TRANSFER
	ISZ	MOUNTV	/POINT TO ERROR RETURN
CHGINS,	JMP	LINKPG	/ONCE ONLY CODE TO LINK PAGES, CHANGED TO (AND K3)
INITDN,
KCDF,	CDF		/POINT TO HANDLER FIELD
	TAD I	TEMP1	/GET MOUNT STATUS FOR THIS UNIT
	SMA	CLA	/SKIP IF MOUNT NEEDED
	JMP	MNTED	/ALREADY MOUNTED
	DCA I	TEMP1	/MARK UNIT AS BEING MOUNTED
MOUNT1,	TAD	VOLNUM	/UNIT 0 OR 1 ?
	SZA	CLA	/SKIP IF UNIT 0
	TAD	AMINSP 	/"A" - "SPACE"
	TAD	SPACE	/"SPACE"
	DCA	VOLID4	/FIX VOLUME ID FOR UNIT 0 OR 1
	RDSC		/ISSUE MOUNT COMMAND (=0)
	TAD	FUNCT	/GET FUNCTION TO FAKE OUT TRANSFER ROUTINE
	DCA	TEMP2
	CLL CLA		/MAKE SURE LINK IS CLEAR
	DCA	FUNCT	/CLEAR FUNCTION FOR XFER ROUTINE
	TAD	TEMP1	/GET CURRENT PC OFFSET
	AND	KK7600	/FOR THE ACTUAL APGE VALUE
	TAD	OFP1	/OFFSET TO MOUNT FUNCTION
	JMS I	PAG2	/BACK TO PAGE 2
	NOP		/IGNORE ERROR ON MOUNT AS ONE MAY HAVE BEEN MOUNTED
	TAD	TEMP2
	DCA	FUNCT	/RESTORE THE FUNCTION
/
/
MNTED,	TAD	BUFCDF	/ENTER ROUTINE WITH CDF IN AC
	JMS I	TOPAG	/ENTER TO SET_VOLUME_AND_BLOCK
/
EXIT,	ISZ	MOUNTV	/POINT TO "GOOD" EXIT
EXCDIF,	HLT		/CDIF TO CALLING_FIELD
	JMP I	MOUNTV	/BACK TO CALLER
/
TEMP1,	0
TEMP2,	0
KK7600,	7600
VOLID0,	0		/SET TO (READ-WRITE + VOLUME NUMBER)
VOLID1,	"O&177
VOLID2,	"S&177
VOLID3,	"8&177
VOLID4,	0		/SET BY PARTICULAR ENTRY
VOLID5,	" &177		/SPACE
VOLID6,	" &177		/SPACE
VOLID7,	" &177		/SPACE
VOLID8,	" &177		/SPACE
VOLID9,	"0&177
VOLIDA,	"0&177
VOLIDB,	"0&177
VOLIDC,	"0&177
IDEND,	0		/SHOULDN'T BE NEEDED, BUT ......
/
K3,	3
KRW,	300		/READ_WRITE
K70,	70
SPACE,	40
AMINSP,	"A-" 		/"A" MINUS "SPACE"
OFP1,	VOLID0-200	/OFFSET TO MOUNT COMMAND VALUES
/
/
	*.&7600+177
/
/ ***** THIS INSTRUCTION MUST BE AT ADDRESS 377 *****
/
LINKPG,	JMS	TOPAG	/GET START ADDRESS OF NEXT PAGE FOR LINKING
/
	PAGE
	0
FNPTR,	0
WCPTR,	0
XPTR,	0
XVOLPT,	0
XBLCKL,	0
XBLCKH,	0
TEMP,	0
/
	*.&7600		/GETS US BACK TO TOP OF PAGE
/
/ONCE_ONLY_CODE, GETS RE-USED FOR VARIABLES
/
TOPAG2,	0
	TAD	TOPAG2
	DCA	FNPTR	/POINTER TO FUNCTION WORD ON FIRST PAGE
	ISZ	TOPAG2	
	TAD	TOPAG2
	DCA	WCPTR	/NEXT POINTER
	ISZ	TOPAG2
	TAD	TOPAG2
	DCA	XPTR	/AND THIRD ONE
	ISZ	TOPAG2
	TAD	TOPAG2
	DCA	XVOLPT
	ISZ	TOPAG2
	TAD	TOPAG2
	DCA	XBLCKL	/LOW BLOCK VALUE
	ISZ	TOPAG2
	TAD	TOPAG2
	DCA	XBLCKH	/AND HIGH BLOCK VALUE
	ISZ	TOPAG2	/TO THE NEXT.
	TAD	P2OFF	/OFFSET TO SET_VOLUME_AND_BLOCK
	JMS I	TOPAG2	/BACK TO FIRST PAGE
/
/MAIN TRANSFER LOOP. IF UPON ENTRY THE AC IS NOT ZERO THEN IT IS A COMMAND
/BUFFER VALUE. A DUMMY WORD COUNT IS SET UP SO AS TO NEVER OVERFLOW. IF THE
/AC IS ZERO THEN IT IS A TRANSFER TO OR FROM THE WINCHESTER ITSELF. ENTER WITH
/BUFFER ADDRESS ALLREADY IN BUFPTR AND WORD COUNT IN WDCNT.
/
/


XFER,	0
	SNA		/SKIP IF COMMAND BUFFER STUFF
	JMP	XFER2	/NORMAL TRANSFER. DO THE SETUP ACCORIDNG TO POINTERS
	DCA	BUFPTR	/SAVE THE COMMAND BUFFER POINTER
	CLA IAC		/FAKE OUT THE WORD COUNT SO IT NEVER OVERFLOWS
	DCA	WDCNT	/FAKE WORD COUNT
XFER2,
TSTXFR,	RDSR		/SKIP IF A REQUEST TO TRANSFER DATA
	JMP	TSTDON	/FIGURE-8 LOOP
	TAD	WDCNT	/CHECK WORD COUNT FOR HALF BLOCK CASE
	SNA	CLA	/SKIP IF MORE TO TRANSFER
	JMP	NOXFR	/CONTINUE OPERATION BUT NO DATA INVOLVED
	TAD I	BUFPTR	/GET A WORD
	RDTD		/EITHER SEND OR RECEIVE, DON'T CARE
	SZL		/BUT SKIP IF WRITE SO AS NOT TO ZERO BUFFER
	DCA I	BUFPTR	/READ PUTS DATA IN BUFFER
	ISZ	WDCNT
	NOP		/PUT IN SOME KIND OF CONSTANT LATER THAT WON'T HURT
	ISZ	BUFPTR	/ON TO NEXT
K7600,	7600
	SKP	CLA	/CLA - EVEN MORE SAFETY !
NOXFR,	RDTD		/DUMMY WHEN FINISHING BLOCK (HALF BLOCK CASE)
TSTDON,	RDSD		/DONE ?
	JMP	TSTXFR	/NO, BACK TO FIGURE-8
	RDSE		/CHECK FOR ERROR
	SKP
	JMP I	XFER	/ERROR ON COMMAND
	SZL		/READ OR WRITE ?
	JMP	DONE
WRITE,	CDF	0	/SET UP THE HANDLER FIELD
	TAD I	FNPTR	/WRITE, SO NOW DO ACTUAL BUFFER WRITE
	SNA
	JMP	DONE	/ALL DONE WITH NO ERRROS
	RDSC
	STL		/SET TO FAKE READ EXIT
	JMP	TSTDON	/FIGURE-8 LOOP WILL NEVER HAVE XFR REQUESTS !!
BUFPTR,	0
WDCNT,	0		/TEMPORARY WORDCOUNT
DONE,	ISZ	XFER	/POINT TO GOOD RETURN
	JMP I	XFER
/
/
/ISSUE SET_VOLUME_AND_BLOCK COMMAND TO DISK CONTROLLER
/
SETVBL,	0
	DCA	USRCDF	/SVAE THE BUFFER FIELD
KKCDF,	CDF	0	/HANDLER FIELD TO GET THE PROPER INFORMATION FOR
			/COMMAND TO THE INTERFACE.
	CLA CLL	IAC	/COMMAND=1
	RDSC
	TAD I	FNPTR	/SAVE
	DCA	TEMP
	DCA I	FNPTR	/FAKE OUT TRANSFER ROUTINE NOT DO DO WRITE ON COMMANDS
	CLL CLA		/FAKE OUT TRANSFER TO ALWAYS DO WRITE AT THIS POINT
	TAD	XVOLPT	/POINTER TO LIST
	JMS	XFER
	JMP	VBLERR	/ERROR EXIT
	TAD I	XPTR	/GET CURRENT BUFFER POINTER
	DCA	BUFPTR
	TAD I	WCPTR	/AND CURRENT WORD COUNT
	DCA	WDCNT
	TAD	TEMP
	DCA I	FNPTR
	TAD I	FNPTR	/NOW DECIDE WHAT TO DO
	CLL	RAR	/MOVE "READ" BIT TO LINK
	SNL		/SKIP IF WRITE
	JMP	RDLOOP	/READ FUNCTION
	CLL RAL		/MAKE 2 FOR FILL BUFFER
	JMP	WRTLOP	/GO TO WRITE WITH AC=2 (FILL BUFFER)
RDLOOP,	RAL		/RESTORE READ FUNCTION
	RDSC		/SEND READ COMMAND
RDLP1,	RDSD		/WAIT FOR COMMAND TO COMPLETE
	SKP
	JMP	RDLP2	/DONE - NOW DO THE TRANSFER
	JMP	RDLP1
RDLP2,	RDSE		/SKIP IF ERROR
	SKP
	JMP	VBLERR
	STL		/READ INDICATOR
	TAD	K25	/NOW SEND EMPTY BUFFER COMMAND
WRTLOP,	RDSC		/EITHER EMPTY BUFFER (25) OR FILL BUFFER (2)
USRCDF,	HLT		/CHANGED TO CDF_BUFFER_FIELD
	JMS	XFER
	JMP	VBLERR	/ERROR EXIT
	CDF	0	/HANDLER FIELD
	TAD	WDCNT
	DCA I	WCPTR	/SAVE THE NEW WORD COUNT
	TAD	BUFPTR	/AND THE CURRENT BUFFER ADDRESS
	DCA I	XPTR	/AND SAVE IT
NXTSEC,	TAD I	WCPTR	/ALL WORDS TRANSFERRED ?
	SNA	CLA
	JMP I	SETVBL
	ISZ I	XBLCKL	/POINT TO NEXT BLOCK
K25,	25
	JMP	KKCDF	/REPEAT SET_VOLUME_AND_BLOCK
VBLERR,	ISZ	SETVBL
	JMP I	SETVBL

P2OFF,	SETVBL-XFER

K177,	177
M3,	-3

	$$$$$
	
