/RX NON-SYSTEM HANDLER, GENERAL CONTROLLER TYPE
/FLOPPY DISK HANDLER FOR OS/8. RX78C.PA
/***NOT FOR USE WITH VT278. ONLY VT78 ***
/
/
/
/
/
/
/
/
/COPYRIGHT  (C)  1978 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.
/
/
/
/
/
/
/
/
/
/
/
/  THIS HANDLER IS SPECIFICALLY FOR A SECOND PAIR OF DRIVES ON A VT78!!
/
/DEFINITIONS OF RX8/E IOT'S

RXVER=	"N&77

DEVCOD=	750	/DEVICECODE

LCD=	6001+DEVCOD	/LOAD COMMAND REGISTER
XDR=	6002+DEVCOD	/TRANSFER DATA REGISTER
STR=	6003+DEVCOD	/SKIP ON TRANSFER REQUEST FLAG, CLEAR FLAG
SER=	6004+DEVCOD	/SKIP ON ERROR FLAG, CLEAR FLAG
SDN=	6005+DEVCOD	/SKIP ON DONE FLAG, CLEAR FLAG
INTR=	6006+DEVCOD	/INTERRUPT ENABLE/DISABLE
INIT=	6007+DEVCOD	/INITIALIZE CONTROLLER AND RECALIBRATE DRIVES


/NOTES ON THIS HANDLER:

/THIS HANDLER READS AND WRITES THE DISK IN "12-BIT" MODE, IN WHICH
/ONLY 6 BITS OF EVERY 8-BIT BYTE ARE USED. AN RX01 CARTRIDGE
/CONTAINS 494 OS/8 BLOCKS UNDER THIS METHOD

/TO MAXIMIZE SPEED ON THE DEVICE, THE HANDLER READS AND WRITES RX01 DATA
/ON A TRACK WITH A TWO-WAY INTERLEAVE - I.E. RECORDS 1-26 ON A TRACK
/ARE WRITTEN IN THE SEQUENCE:
/  1,3,5,7,9,11,13,15,17,19,21,23,25,2,4,6,8,10,12,14,16,18,20,22,24,26

/DOUBLE DENSITY MEDIA ARE WRITTEN IN A THREE WAY INTERLEAVE
/  1,4,7,10,13,16,19,22,25,2,5,8,11,14,17,20,23,26,3,6,9,12,15,18,21,24

/TRACK-SECTOR COMPUTATION IS DONE I/O TO/FROM THE SILO

AC4000=CLL CLA CML RAR		/SET AC TO 4000
AC7776=CLL CLA CMA RAL		/SET AC TO 7776
AC0002=CLL CLA CML RTL		/SET AC TO 0002
AC7775=CLL CLA CMA RTL		/SET AC TO 7775
/
/BUILD DATA
	*0
/
	-2		/TWO ENTRY POINTS
	DEVICE	RX0B	/DEVICE GROUP NAME
	DEVICE	RXA2	/ENTRY POINT NAME
	4320		/CODE FOR MULTI-RX
	RXA2&177+4000	/ENTRY POINT OFFSET
	0
	0
	DEVICE	RX0B	/DEVICE GROUP NAME
	DEVICE	RXA3	/ENTRY POINT NAME
	4320		/THIS WAS CHANGED FROM 4270 - ASSIGNED TO CASSETTE
	RXA3&177+4000	/ENTRY POINT OFFSET
	0
	0
	*200
/
/
/  INIT CODE
/
POINT,	HLT		/ADDR OF SECOND PAGE AT INIT TIME
UNIT,	JMS I	POINT	/GO TO SECOND PAGE TO INIT
/
/  LIST OF VECTORS TO SECOND PAGE
/
LQUO,	QUO-.		/LQUO MUST LEAD OFF LIST
LRETRY,	RETRY-.
LREC,	REC-.
LSIZE,	SIZE-.
LREMD,	REMD-.
LFN,	FN-.
LDENSW,	DENSW-.
LSELCT,	SELECT-.
LENTRY,	ENTRY-.
VCOUNT=LQUO-.		/FALLS THRU TO WHICH, HERE IS VECTOR COUNT
/
/  COME HERE FROM ZOO
/
/  PROCESS ENTRY POINT, DEVICE TYPE
/
WHICH,	CLA IAC		/SELECT SECOND PAIR IF DRIVES
	JMS I	LSELCT
	AC7775		/SET RETRY COUNTER
	DCA I	LRETRY
	TAD I	ZOO	/GET UNIT NUMBER*20+402
	DCA	UNIT	/HOLD FOR LATER
	ISZ	ZOO	/MOVE TO TYPE CODE
	TAD I	ZOO	/HAS THIS DRIVE BEED INIT'ED
L7700,	SMA CLA		/SKIP IF NO
	JMP	NORMAL	/GO TO NORMAL PATH
RSTART,	TAD	UNIT	/PICK UP UNIT BIT, DOUBLE DENSITY +2
	TAD	L10	/MAKE A READ STATUS CODE
	SDN
	JMP	.-1
	LCD
	JMP	BOUNCE	/HOP OVER ENTRY POINTS
/
/
/
	IFZERO	.&177-34&4000	<_ERROR_>
/
/  ENTRY POINTS ARE AT 33, 37
/
	*.&7600+33
/
RXA2,	0
	JMS	ZOO	/COMMON ENTRY ROUTINE
	402		/UNIT 0, 402 FOR CONVENIENCE
	-1		/MINUS SAYS STILL HAVE TO INIT IT;
/			/SINGLE=0, DOUBLE=20, QUAD=22
RXA3,	0
	JMS	ZOO
L422,	422		/20 SAYS UNIT 1, 402 FOR CONVENIENCE
DOOR,	JMP	WHICH	/INIT TIME LITERAL (MUST BE MINUS)
/			/GETS SAME TYPE CODE AS OTHER ENTRY POINT
/
/  REST OF SET UP CODE
/
BOUNCE,	SDN
	JMP	.-1
	XDR		/GET STATUS WORD
	AND	L32	/KEEP DENSITY ERROR; DOUBLE; QUAD
	TAD	L10	/SINGLE=10;SING/DOUB=40;DOUB=20;QUAD=22
	AND	L422	/SINGLE=0;SING/DOUB=0;DOUB=20;QUAD=22
	DCA I	ZOO	/PLACE TYPE CODE, THREE LOC.'S AFTER ENTRY POINT
	SER		/CLEAR ERROR FLAG
L10,	10		/MAY SKIP
	TAD	L416	/SET DONE FLAG AGAIN
	LCD
NORMAL,	TAD I	ZOO	/FETCH BACK TYPE CODE
	SZA CLA		/SKIP IF A SINGLE DENSITY
	TAD	L7700	/DOUBLE
	TAD	L7700	/SINGLE=7700, DOUBLE=7600
	DCA I	LDENSW	/PLACE FOR LOOP CONTROL
	TAD I	ZOO
	CLL RTR		/PUT QUAD BIT TO LINK
	SNA CLA		/SKIP IF DOUBLE OR QUAD
	TAD	L1734	/SINGLE
	TAD	L4110	/D&Q=4110, S=6044
	SNL		/SKIP ON QUAD, IT'S OK RIGHT NOW
	CLL CML RAR	/SINGLE AND DOUBLE DIVIDE BY 2
	DCA I	LSIZE	/S=7022, D=6044, Q=4110
	TAD I	LDENSW	/7700 IF SINGLE, 7600 IF DOUBLE
	CLL CMA RTL	/375 IF SINGLE, 775 IF DOUBLE
	AND	UNIT	/VOILA, 400*DOUBLE  +  20*UNIT
	DCA I	LFN	/PLACE INTO FUNCTION CONTROL WORD
	AC7775		/BACK UP ZOO TO FETCH CALLING ADDR
	TAD	ZOO
	DCA	T1	/HOLD TEMPORARY
	TAD I	T1	/HERE IS CALLING ADDR
CLLFLD,	HLT		/PUT CDF TO CALLING FIELD HERE
	JMS I	LENTRY	/GO TO SECOND PAGE, LEAVING POINTER TO DIVSUB
/
/  DIVSUB SUBROUTINE !!MUST!! FOLLOW IMMEDIATELY
/
/
/  DIVSUB
/
/  CALL TO SET UP TRACK, SECTOR, FROM OVERALL SECTOR #
/  ALSO, SET UNIT WITH HEAD COMMAND IF WE ARE ON TO SECOND SIDE
/
/  CALL WITH AC <0 IF IT IS REALLY AN ERROR RETRY
/  CALL WITH AC >=0 IF CALL TO DIVSUB
/
DIVSUB,	0
	CDF	0	/AND DATA FIELD MUST BE TO HERE
	SPA CLA		/SKIP IF REALLY A DIVIDE REQUEST
	JMP	RSTART	/NO, IT WAS AN ERROR RETRY!!
	DCA I	LQUO	/CLEAR DIVIDE QUOTIENT
	TAD I	ZOO	/IS IT A TWO HEADER
	RTR		/PUT QUAD BIT TO LINK
	SNL CLA		/SKIP IF YES
	JMP	SHUNT	/NO, GO DO DIVIDE
	TAD I	LREC	/WHICH RECORD ARE WE WORKING ON
	TAD	LM3670	/NUMBER OF SECTORS ON FIRST SIDE
	SZL CLA		/SKIP IF SECOND SIDED IT
	JMP	SHUNT	/NO, JUST REGULAR
	TAD I	LFN	/FORCE HEAD BIT ON
	AND	L422	/KEEP DOUBLE, UNIT, READ-WRITE
	TAD	L1000	/ADD IN SECOND SIDE
	DCA I	LFN
	TAD	LM3670	/BUT DECREASE RECORD NUMBER
SHUNT,	TAD I	LREC	/THIS FOR TRACK-SECTOR
DIVLOO,	ISZ I	LQUO	/MAIN DIIVIDIE LOOP
	TAD	LM32	/DIVIDE BY 26 TO GET TRACK
	SMA		/SKIP IF DONE
	JMP	DIVLOO
	TAD	L32	/REMAINDER 0-25
	DCA	T1	/HOLD IT IN TEMPORARY
	TAD I	ZOO	/SINGLE DENSITY
	SZA CLA		/SKIP IF YES
	TAD 	T1	/MULTIPLY BY THREE FOR DOUBLE
	TAD 	T1	/AND BY TWO FOR SINGLE
	TAD 	T1
	CLL IAC		/LINK CLEAR FOR FINAL TEST; +1 TO START AT 1 NOT 0
	TAD	LM32	/DIVIDE BY 26 TO GET SECTOR
	SMA SZA		/SKIP IF DONE
	JMP	.-2
	TAD	L32	/RESTORE POSITIVE VALUE TO BE SECTOR
	DCA I	LREMD	/WHEW, BUT WATCH IT, A FINAL CORRECTION COMING!
	RAL		/IF LINK=0 AND SINGLE: 2,4,6,8,10,12,14,16... SERIES
	TAD I	ZOO	/BUT WE HAVE 1,3,5,7,9,11,13,15... SO WE MUST INCREMENT!
	SNA CLA		/SKIP IF SOME OTHER CASE
	ISZ I	LREMD	/NOW HAVE IT 2,4,6,8,10,12,14,16...
	JMP I	DIVSUB	/OUT
/
/
L416,	416	/SOME LITERALS
L32,	32
L1000,	1000
LM32,	-32
L1734,	1734
L4110,
LM3670,	-3670
/
/
/
	*.&7600+167	/FORCE TO END OF PAGE
/  ZOO  SUBROUTINE
/
/  TO SET UP ENTRY POINT PROCESSING, AND INIT CODE
/
ZOO,	0		/ADDR OF 'HIT' ENTRY POINT +2 COMES HERE
	CLA		/FOR SAFETY
	RDF		/SAVE CALLERS FIELD SETTING
	TAD	LCDF0	/ADD IN CDF 0
	DCA	CLLFLD	/RESET WHEN GOING TO I/O SUB
LCDF0,	CDF 0		/DATA FIELD HERE FOR INDIRECTS
CLOSE,	TAD	DOOR	/CLOSE DOOR TO ONCE ONLY CODE (JMP WHICH
T1,	DCA	CLOSE	/USE ONCE-ONLY FOR TEMPORARY LOCATION
	JMS	POINT	/LEAVE ADDR OF SECOND PAGE
/
/
/  VARIABLES, ALSO INIT CODE LIVES HERE
/
/
BUF,	0		/POINTER TO CALLER'S BUFFER
RETRY,	0		/RETRY COUNT
SIZE,	0		/SIZE OF DEVICE
SYS,	0		/POINTER TO CALL
QUO,	0		/DIVIDE QUOTIENT, WHICH IS TRACK NUMBER
REC,	0		/SECTOR NUMBER OF FLOPPY
BC,	0		/CONTROL COUNT, WORDS TO TRANSFER
FN,	0		/0 FOR WRITE; 2 FOR READ; HEAD, DENSITY, UNIT
DENSW,	0		/7700 IF SINGLE DENSITY, 7600 IF DOUBLE DENSITY
ENTRY,	0		/ENTRY POINT, LEAVE ADDR OF DIVSUB HERE
/
	IFNZRO	.&177-10&4000	<_ERROR>	/ENOUGH ROOM FOR INIT?
/
	*.&7600
/
/  INIT TIME:  FILL VECTOR TABLE
/
THERE,	0		/FILLED BY JMS, POINTS TO VECTOR
ILOOP,	TAD	THERE	/POINTER IS ALSO OFFSET!
	TAD I	THERE	/MAKING VECTOR
	DCA I	THERE
	ISZ	THERE	/MOVE TO NEXT VECTOR
	ISZ	LDCMD	/CONTROL COUNT ON THIS PAGE
	JMP	ILOOP
	JMP I	THERE	/BACK TO FIRST PAGE
/
/  IO SUBROUTINE
/
/  ENTRY POINT AT END OF LAST LISTING PAGE
/
/
	*ENTRY+1	/RESUME RUNTIME CODE
/
	DCA	SYS	/POINTER TO ARG'S, EXIT
	RDF		/DATA FIELD OF USER CALL
	TAD	(CDF CIF 0	/MAKE CDF CIF TO CALLER'S FIELD
	DCA	EXFLD	/SET UP FOR CALL
	AC4000		/SET LINK=0, AC=4000
	TAD I	SYS	/CARRY READ-WRITE BIT TO LINK
	AND	L70	/KEEP FIELD FOR BUFFER
	TAD	LLCDF0	/MAKE CDF TO BUFFER FIELD
	DCA	BUFCDF	/PLACE INTO I/O LOOP
	CML RTL		/MAKE FUNCTION CODE, 0=WRITE, 2=READ
	TAD	FN	/START-UP CODE HAS SET HEAD, DENSITY, UNIT ETC.
	DCA	FN
	TAD I	SYS	/MAKE LOOP CONTROL COUNT
	RAL
	AND	L7600
	CIA		/0 FOR WHOLE FIELD
	DCA	BC	/MINUS TOTAL NUMBER OF WORDS
	ISZ	SYS	/NEXT
	TAD I	SYS	/IS BUFFER ADDRESS
	DCA	BUF
	ISZ	SYS	/NEXT
	TAD	L175	/CARRY WITH DENSW IF SINGLE DENSITY
	TAD	DENSW	/BLOCK # TO SECTOR #
	SMA CLA		/SKIP IF DOUBLE, MULTIPLY BY 2
	TAD I	SYS	/SINGLE, MULTIPLY BY FOUR
	SMA		/SKIP ON ILLEGAL NEGATIVE BLOCK #, FORCE LINK ON LATER
	TAD I	SYS
	ISZ	SYS	/MOVE POINTER TO ERROR EXIT
	CLL RAL
	DCA	REC	/SAVE SECTOR NUMBER
	SZL		/SKIP IF LEGAL BLOCK #
	JMP	ERREX	/FORCE SIZING OF DISK TO RETURN SIZE IN AC
	JMS I	ENTRY	/CALL DIVISION SUBROUTINE OTHER PAGE
	TAD	FN	/SPLIT READ AND WRITE
	RTR		/READ-WRITE BIT TO LINK
	SZL CLA		/WRITE SKIPS
	JMP	STREAD	/READ GOES TO START IN MIDDLE OF LOOP
/			/WRITE FALLS THRU TO NEXT LISTING PAGE
/WRITE FALLS THRU TO THIS LOOP
/
/  TOP OF MAIN LOOP
/
TOP,	TAD	FN	/SET SILO TO LOAD-UNLOAD
	JMS	LDCMD	/COMMAND TO CONTROLLER
	TAD	DENSW	/MAKE SILO LOOP COUNT, S=7700, D=7600
	DCA	FLPWC	/LDCMD ENTRY SAFE TEMPORARY
BUFCDF,	HLT		/CDF TO BUFFER FIELD PLACED HERE
TRLOOP,	TAD I	BUF	/IN CASE WRITE, FETCH A WORD
	STR		/SKIP IF READY TO PASS DATA
	JMP	.-1	/NO
	XDR		/TO OR FROM AC
	DCA I	BUF	/PLACE WORD FOR READ, WRITE REPLACES SAME
	ISZ	BUF	/MOVE BUFFER POINTER, (MAY SKIP)
REMD,	0		/DIVIDE REMAINDER, WHICH IS SECTOR NUMBER
	ISZ	FLPWC	/DONE YET
	JMP	TRLOOP
	TAD	DENSW	/ADDING 77 (SINGLE) 177 (DOUBLE)
	CMA		/ONCE WE CMA, THAT IS
	TAD	BC	/LOOP CONTROL TO FINISH READ
	SNA
	JMP	OKEX	/OK, DONE
	DCA	BC	/REPLACE AND KEEP GOING
/
/  MIDDLE OF MAIN LOOP
/
STREAD,	CLA CLL IAC RTL	/KNOWN TO BE A 78, SO THIS WORKS! FOR LITERAL 4
	TAD	FN	/TURNING SILO COMMAND INTO READ-WRITE COMMAND
	JMS	LDCMD	/I/O COMMAND TO CONTROLLER
	TAD	REMD	/PRECOMPUTED SECTOR #
	STR
	JMP	.-1
	XDR
L7600,	7600		/CLEAR AC, AND IS LITERAL
	TAD	QUO	/TRACK #
	STR
	JMP	.-1
	XDR		/TRACK # IS ALWAYS NON0 !!
	ISZ	REC	/MOVE TO NEXT RECORD NUMBER
	JMS I	ENTRY	/DO TRACK SECTOR FOR NEXT OPERATION
	TAD	LL16	/WAIT FOR OPERATION TO COMPLETE
	JMS	LDCMD
	ISZ	BC	/CHECK FOR WRITE EXIT
	JMP	TOP	/STILL MORE
OKEX,	ISZ	SYS	/KICK TO OK EXIT
SELBAK,	DCA	REC	/TEMPORARY TO HOLD AC
	JMS	SELECT	/AC NOW 0 TO FORCE SELECT OF FIRST PAIR
	TAD	REC	/RETURN WITH (POSSIBLE) AC VALUE
EXFLD,	HLT		/CDF CIF TO CALLER
	JMP I	SYS	/OUT
/
/
/  LDCMD  SUBROUTINE
/
/  CHECK FOR CONTROL C, LOAD A COMMAND
/
FLPWC=.                 /ENTRY POINT A TEMPORARY
LDCMD,  VCOUNT          /INIT COUNTER
        DCA     TRANS   /SAVE COMMAND
LLCDF0, CDF     0       /DATA FIELD HERE IN CASE CONTROL C TO MONITOR
TSTTT,  KSF             /SKIP IF A TTY CHARACTER HAS HAPPENED
        JMP     TSTSD   /NOPE, GO CHECK RX CONTROLLER READY
        TAD     L7600   /FORCE TOP BITS TO BE 1 TO ELIMINATE 3,203
        KRS             /AMBIGUITY ON TEST
        TAD     L175    /IS IT A CONTROL C
        SNA CLA         /SKIP IF NOT
        JMP     MONEX   /GO EXIT TO MONITOR
TSTSD,  SDN             /IS RX CONTROLLER READY
        JMP     TSTTT   /NOPE, GO CHECK TTY
        TAD     TRANS   /GET BACK COMMAND
        LCD             /TO CONTROLLER
        SER             /SKIP IF AN ERROR
        JMP I   LDCMD
        AC4000          /ERROR CODE FOR HARD ERROR
        SKP             /SKIP OVER SIZING ENTRY
ERREX,  TAD     SIZE    /PUT NEGATIVE SIZE IN AC
        ISZ     RETRY   /TRY THREE TIMES?
        JMS I   ENTRY   /NO, AC NEGATIVE SAYS RETRY NOT DIVIDE!!
        JMP     SELBAK  /SELECT BACK TO FIRST PAIR
/
MONEX,  JMS     SELECT  /AC=0, SELECT FIRST PAIR
        JMP I   L7600   /BACK
/
/
/
/  SELECT ROUTINE
/
TRANS,                  /TEMPORARY FOR LDCMD TO SAVE COMMAND
SELECT, 0
        6750            /CONTENTS OF AC11 SAYS WHICH PAIR
        SER             /CLEAR POSSIBLE ERRANT FLAGS
L70,    70              /SAFE NO-OP
        SDN
L175,   175
        STR
LL16,   16
        CLA             /PERHAPS NOT NECESSARY
        TAD     LL16    /SET DONE FLAG AGAIN
        LCD
        JMP I   SELECT
/
        PAGE
/
