File: NS.TK of Disk: Disks/MyPDP/m8-blue-rka1-rkb1
(Source file text) 

/NS.TK	31-MAY-80
/NON-SYSTEM DISK DRIVER
/
/CONCEPT: WITH THIS MODULE BLOCK TRANSFER FROM
/	OR TO THE NON-SYSTEM DISK CAN BE DONE IN
/	BOTH FOREGROUND AND BACKGROUND.
/	WHEN 0 BLOCKS ARE SPECIFIED FOR TRANSFER
/	THIS MODULE WILL TRANSFER 20 BLOCKS (4K).
/ERRORS: WHEN TRYING TO READ OR WRITE OUTSIDE THE
/	DISK RANGE, THE ERROR RETURN IS TAKEN.
/	WHEN TIMING,PARITY OR WRITE LOCK ERRORS
/	EXIST, THIS MODULE WILL REPEAT THE REQUEST
/	3 TIMES, AND IF THE ERROR PERSIST,
/	THE ERROR RETURN IS ALSO TAKEN.
/USE:
/	CLL		/ACCESS ONLY A&B RL-DEVICES
/	STL		/ACCESS ONLY 'C' RL-DEVICE
/	CDF FIELD OF DTV
/	TAD (POINTER TO DTV
/AGAIN,	JMS MONITOR
/	   CALL
/	   "X^100+"Y&3777	/XY = SOME DISK
/	JMP AGAIN	/BUSY: TRY AGAIN
/	DCA SLOT	/RETURNS WITH SLOT IN AC
/	.
/	.
/	.
/	JMS MONITOR	/WAIT FOR COMPLETION OR ERROR
/	   WAIT
/SLOT,	   0
/	SZA CLA		/ERROR ?
/	JMP ERROR	/Y
/	.
/	.
/FORMAT OF DATATRANSFER VECTOR:
/DTV,	RLL LLL FFF UUU	/ READ/WRITE;LENGTH(PAGES);FIELD;UNIT
/	BUFFER		/ADDRESS IN CORE
/	BLOCK#
/THE NON-SYSTEM DISK DRIVER TASK
IFDEF NSRK8E <NSRK=1>
IFDEF NSRK08 <NSRK=1>
IFDEF NS3010 <NSSI=1>
IFDEF NS3040 <NSSI=1>
IFDEF NSRL01 <NSLNGT=7761>
IFDEF NSRK   <NSLNGT=6260>
IFDEF NSSI   <NSLNGT=6260>

/TASK HEADER:

	"N^100+"S&3777	/NAME 'NS'
IFNDEF NSRL01 <
	400+1		/2-PAGE, 1 CONNECT >
IFDEF NSRL01 <
	1000+1		/4-PAGE, 1 CONNECT >
NSDEV,	DSK		/DEVICE NUMBER
	NSINT		/INTERRUPT ENTRY-POINT
XNSDO,	NSDO
XNSCDF,	NSCDF
XNSIGN,	NSIGNR
IFNDEF NSRL01 <
XCDTIF,	CDTIF
XNSTMP,	NSTEMP
XNSFUN,	NSFUNC
XNSNEX,	NSNXCT >
IFDEF NSRL01 <
XNSIN0,	NSIN0
XRTRY,	NSRTRY
XDRIVE,	DRIVE
XINV,	INVBBL
XCHK,	CHKBBL >
NONSYS,	0
NS,	SNA		//CLOSE ?
	 JMP NSCLOSE	//
	DCA NONSYS	//SAVE DTV POINTER
	TAD I ZMYCDF	//SAVE DF
	DCA NSFLD	//SAVE FIELD TEMPORARILY
IFDEF NSRL01 <		//GET UNIT C INDICATOR
	SZL		//IS IN LINK
	AC0006		//SET OFFSET FOR 'C'
	DCA NSERST	//TEMP
IFZERO NSRL01-1&2 <	//TEST IF THE TRANSFER IS WITHIN LIMITS
	AC0004		//DRIVES 2 AND 3 NOT ARE NOT
	AND I NONSYS	//IMPLEMENTED
	SZA CLA		//TO SAVE SOME TABLE SPACE
	 JMP NSEROR	//SO DON'T TRY IT ! >>
	TAD NONSYS	//LEAVE 'NONSYS' AT DTV FOR RETRY
	DCA NSSLOT	//USE 'NSSLOT' AS TEMP
	TAD I NSSLOT	//GET FUNCTION WORD
	AND C3700	//
	SNA		//4K TRANSFER ?
	 AC4000		//YES
	BSW		//
	CLL IAC RAR	//ROUND UP TO BLOCKS
	ISZ NSSLOT	//BUMP POINTER TO BLOCK NUMBER
	ISZ NSSLOT	//
	TAD I NSSLOT	//ADD LENGTH OF TRANSFER TO STARTBLOCK
	CLL		/12-BIT NUMBERS!
	TAD (-NSLNGT-1	/COMPARE WITH DISK LENGTH
	SZL CLA		/PAST END OF DISK ?
	 JMP NSEROR	/YES, FATAL ERROR
	JMS MONITOR
	   RESERV RETURN CONTINUE
	DCA NSSLOT	/SAVE SLOT#
	JMS MONITOR	/NOW STOP SYSTEM DRIVER
	   STOP		/TO PREVENT DATA-LATE AND
	   "S^100+"Y&3777	/AND OTHER ERRORS
	   HLT		/HUH, NO SYSTEM HANDLER?
NSSYWT,	JMS MONITOR	/AND ALSO WAIT FOR QUEUE EMPTY
	   PRECEDE	/IF NOT GIVE OTHERS TIME
	CDF 0
	TAD I XSYSCT	/=0 IF QUEUE EMPTY
	CDTOIF
	SZA CLA		/IS IT?
	 JMP NSSYWT	/NO, WAIT
	TAD NSFLD	/TRANSFER DTV PARAMS TO 'NSDO'
	DCA I XNSCDF
IFNDEF NSRL01 <
	TAD MYCDF
	DCA I XCDTIF	/NO CDTOIF IN INTERRUPT >
IFDEF NSRL01 <
	TAD XNSIN0	/INITIALIZE COROUTINE
	DCA IO
	TAD NSERST	/TRANSFER 'C' UNIT >
	IOF
	JMS I XNSDO	/START DISK
	ION
	TAD (-DGNTICK^4	/DON'T HANG THE WHOLE SYSTEM
	JMS MONITOR	/WAIT 4 SECS!! RL01 CAN DELAY UP TO 1 SEC!!
	   WAIT
	   DSK		/WAIT FOR 'DSK' INTERRUPT OVER
	SZA CLA		/ERRORS?
	TAD (HRDERR	/YES, GIVE STATUS
	JMS MONITOR	/NOW RESTART SYSTEM DRIVER
	   RESTRT	/BEFORE IT IS TOO LATE
	   "S^100+"Y&3777
XSYSCT,	SYSCNT		/THE ERROR IS NEVER TAKEN
	JMS MONITOR	/STATUS IN AC
	   SIGNAL HALT CLEAR RELEASE
NSSLOT,	0

NSEROR,	ACM1
NSCLOSE,TAD M1
	JMS MONITOR
	  EXIT RELEASE

NSERST,	0
NSLOG,	0
NSFLD,	0		/TEMP STORAGE FOR FIELD OF DTV
/INTERRUPT PART OF DISK NON-SYSTEM DRIVER
/THE PROGRAM ALLOWS FOR 3 CONSECUTIVE ERRONEOUS DISK-
/TRANSFERS, THEN ISSUES AN ERROR.

IFNDEF NSRL01 <
IFDEF NSRK8E <
	DSKP=6741	/SKIP ON DONE OR ERROR FLAG
	DCLR=6742	/DISK CLEAR
	DLAG=6743	/LOAD DISK ADDRESS AND GO !
	DLCA=6744	/LOAD CURRENT ADDRESS
	DRST=6745	/READ STATUS
	DLDC=6746	/LOAD COMMAND
/	DMAN=6747	(MAINTENANCE INSTRUCTION)
		   >

IFDEF NSSI <	/EQUATES FOR NON-SYSTEM INDUSTRIES CONTROLER
	DSDD=6501	/SKIP ON DONE
	DLCR=DSDD+1	/LOAD CONTROL REGISTER
	DRCR=DLCR+1	/READ CONTROL REGISTER
	DCSR=DRCR+1	/CLEAR STUTUS REGISTER
	DRSR=DCSR+1	/READ STATUS REGISTER
	DLSS=DRSR+1	/LOAD SEEK  ADDRESS AND SEEK
	DRSS=DLSS+1	/READ SEEK STATUS REGISTER
	DSDE=DRSS+2	/SKIP ON DISK ERROR
	DLSR=DSDE+1	/LOAD SECTOR REGISTER
	DSRR=DLSR+1	/READ SECTOR REGISTER
	DLTR=DSRR+1	/LOAD TRACK ADDRES AND READ
	DLTW=DLTR+1	/LOAD TRACK ADDRESS AND WRITE
	DRTR=DLTW+1	/READ TRACK ADDRESS REGISTER
	DWCA=DRTR+1	/INITAIATE WC/CA SEQUENCE >

IFDEF NSRK08 <
	DLDC=6732
	DLCA=6755
	DLWC=6753
	DLDR=6733
	DSKD=6745
	DSKE=6747
	DCLS=6742
	DRDS=6741
	DRDA=6734
	DCLA=6751	/ >
NSNEXT,	JMS I XNSDO	///RETRY OPERATION
NSIN0,	JMS NSWAT	///GET COMPLETION INTERRUPT
IFDEF NSRK8E<
	DRST		///READ STATUS
	CLL RAL		///BIT 0 MUST BE 1, OTHERS ZERO
	SZA		///RIGHT ?
	 JMP NSERR	///NO, WHAT A PITY
	TAD I XNSTMP	///YES,GET OUT
	SNA		///LAST TRANSFER ?
	 JMP NS10	///YES, TRY NEXT IN QUEUE
	JMS I XNSNEX	///QUICKLY INITIATE NEXT TRANSFER
			///AND COMPUTE THE ONE AFTER THAT
	JMP NSIN0	///WAIT FOR NEXT INTERRUPT

NSERR,	RAR
	DCA NSERST	///SAVE ERROR STATUS
NSERR1,	DRST		///
	AND (0401	///GET IMPORTANT ERROR BITS
	SNA CLA		///SERIOUS ERROR ?
	 JMP NSNSER	///NO, TRY AGAIN
	DCLR		///YES, RECALIBRATE
	AC0002
	DCLR		///RECALIBRATE
	JMS NSWAT	///WAIT FOR COMMAND ACCEPTED
	STL IAC RTL	///6 IN AC
	AND I XNSFUN	///GET DRIVE #
	TAD (600	///INTERRUPT ON SEEK DONE
	DLDC
	JMS NSWAT	///WAIT TILL SEEK COMPLETED
	JMP NSERR1	///OK NOW ?
NSNSER,	AC0001		///CLEAR CONTROLLER
	DCLR		/// >

IFDEF NSI <
	DSDE		///DISK ERROR ?
	 JMP NS10	///NO, PROCEED >
IFDEF NSRK08 <
	DSKE		///ERROR FLAG UP ?
	 JMP NS10	///NO, DONE
	DRDS		///YES, SEE WHATS UP
	AND C4		///LETS HOPE FOR TRACK OVERFLOW
	SNA CLA		///IS IT ?
	 JMP NSER	///IT'S NOT...
	TAD I XNSRW	///GET THE READ OR WRITE INSTRUCTION
	DCA NSRW1	///
	DCLS		///CLEAR THE STATUS REGISTER
	DRDA		///READ THE TRACK ADDRESS
	AND (7760	///AND COMPUTE THE NEW
	TAD (20		///TRACK ADDRESS
NSRW1,	HLT		///READ OR WRITE
	JMP NSIN0	///AND WAIT FOR EVENT TO COME
NSER,			/// >
	ISZ NSLOG	///COUNT NUMBER OF ERRORS
	ISZ NSERCNT	///3RD CONSEC. ERROR?
	 JMP NSNEXT	///N;TRY AGAIN
	TAD (HRDERR	///ERROR CODE

/AT THIS POINT A DISK TRANSFER HAS DEFINITELY TERMINATED
NS10,	DCA NSSTAT	///COMPLETION STATUS
	ACM3		///RESET THE ERRORCOUNTER
	DCA NSERCNT	///
	TAD XNSIGN	///SET INT.RETURN TO CLEAR FLAGS
	DCA NSWAT
	TAD NSDEV	///GO GIVE COMPLETION TO MYSELF
	CIF 0
	JMS I ZSOFINT	///YES, AC IS DEVICE NUMBER
NSSTAT,	  0		///COMPLETION STATUS

NSWAT,	NSIGNR		///COROUTINE, INITIAL INTERRUPT ENTRY
	CIF CDF 0
	JMP I ZFSTEXT	///QUICK RETURN

NSINT,			/// HERE GOES THE INTERRUPT !!!
IFDEF NSRF08 <6641	///CLEAR HIGHORDER DISK ADDRESS >
	JMP I NSWAT	///GOT NEXT INTERRUPT
NSIGNR,
IFDEF NSRK8E <DCLR>
IFDEF NSI <
	DCSR		///CLEAR STATUS AND
	DLCR		///CONTROL REGISTER >
IFDEF NSRK08 <
	DCLA		///CLEAR ALL >
	JMS NSWAT
	JMP NSIGNR

NSERCNT,-3	///ERROR COUNTER

	PAGE
/SET UP ALL DISK REGISTERS AND INITIALIZE THE TRANSFER.
/THE PROGRAM DECODES THE DISKTRANSFERVECTOR:
/WORD1: RLL.LLL.FFF.UUU	/READ/WRITE;LENGTH AND FIELD
/WORD2: STARTING ADDRESS  IN CORE
/WORD3: BLOCK NUMBER ON DISK
/THE ROUTINE IS SHARED BY THE INTERRUPT PART OF THE DISK
/DRIVER,BUT NEEDS NOT BE ENTERED WITH 'IOF'. THE DISK BUSY
/FLAG PREVENTS CONCURRENT USE.

YNSWAT,	NSWAT
YREAL,	NSIN0+1
YSLOT,	NSSLOT
YNONS,	NONSYS
NSTEMP,	0		/TEMPORARY

NSDO,	0
	TAD YREAL
	DCA I YNSWAT	/FROM NOW ON DON'T IGNORE INTRP
	TAD I YNONS	/GET DTV NEW EACH TIME
	DCA NSDTV
NSCDF,	HLT		//HERE COMES THE CORRECT CDF
	TAD I NSDTV
IFDEF NSRK8E <
	AND (4076	//MASK WRITE+FIELD+UNIT
	TAD (0400	//INTR. ENABLE
	DCA NSFUNC
	TAD I NSDTV
	AND C3700	//# OF PAGES
	SNA
	AC4000
	BSW		//MINUS NUMBER OF PAGES
	CIA
	DCA NSWC
	TAD I NSDTV
	RAR		//ROTATE UNIT TO LINK
	CLA
	ISZ NSDTV
	TAD I NSDTV	//CORE BUFFER ADDRESS
	DLCA
	ISZ NSDTV
	SZL CLA
	TAD (6260	//B SIDE HAS OFFSET
	CLL
	TAD I NSDTV	//FETCH CALLERS BLOCK #
CDTIF,	HLT		/GETS CDF CUR
	DCA NSSB	/THIS IS THE LOW ORDER START BLOCK
	SZL		/IF NO OVERFLOW,
	 ISZ NSFUNC	/SET H.O.CYLINDER ADDRESS
	TAD NSFUNC
	JMS NSNXCT	/INITIATE TRANSFER AND COMPUTE NEXT FUNCT.
	JMP I NSDO
/INITIALIZE THE TRANSFER AND COMPUTE THE FUNCTION REGISTER
/FOR THE  NEXT TRANSFER.

NSNXCT,	0
	ISZ NSWC	/THIS SKIPS IF ONLY ONE PAGE TO GO
	SKP
	 TAD C100	/SET THE HALF SECTOR BIT
	DLDC		/LOAD FUNCTION WORD REGISTER
	TAD NSSB	/LOAD BLOCK #
	DLAG		/GO...
	ISZ NSWC	/IS THIS THE END ?
	 TAD NSWC	/OR PAST THE END ?
	SMA CLA
	 JMP NSLAST	/YES, WE ARE TROUGH !
	ISZ NSSB	/INCREMENT BLOCK #
	 JMP .+3	/
	ISZ NSFUNC	/CARRY GOES TO FUNCTION WORD
	JMP .+5		/THIS CERTAINLY IS A NEW CYLINDER
	TAD NSSB	/TEST IF STARTBLOCK
	AND C37		/IS FIRST BLOCK OF NEW CYLINDER
	SZA CLA		/IN THAT CASE WE SHOULD TEST HEADER INFO
	 TAD (1000	/SET THE 'ALL' BIT
	TAD NSFUNC
NSLAST,	DCA NSTEMP	/NEW FUNCTION WORD FOR NEXT TRANSFER
	JMP I NSNXCT

NSSB,	0		/STARTING BLOCK
NSFUNC,	0	>	/FUNCTION WORD
IFDEF NSI <
	SPA CLA		///READ OR WRITE ?
	 AC0001		///
	TAD (DLTR	///MAKE READ OR WRITE INSTRUCTION
	DCA NSRW	///AND PUT IT AHEAD
	DCSR		///CLEAR STATUS REGISTER
	DLCR		///SETUP CONTROL REGISTER FOR WC/CA
	CLA		///IS THIS REALY NECCESAIRY
	TAD I NSDTV	///GET FUNCTION WORD AGAIN
	CLL RAL		///# OF WORDS IN BITS 1-4
	AND C7600	///MASK OFF GARBADGE
IFDEF NS3010 <
	SNA		///4K ?
	 ACM1		///DO 4095 WORDS (SORRY) >
	DCA NSWC	///
	TAD I NSDTV	///THE FUNCTION WORD AGAIN
	AND C70		///EXTRACT BUFFER FIELD
	IAC BSW		///MAKE F.1.0.0
	DCA NSCTR	///CONTROL REGISTER FOR TANSFER
	TAD I NSDTV	///FUNCTION WORD
IFDEF NS3010 <
	AND (6		///GET DRIVE NUMBER
	CLL RTR
	RTR		///DD0.000.000.000 >
IFDEF NS3040 <
	AND C4		///FIXED OR REMOVABLE ?
	SZA CLA		///WHICH PLATTER ?
	 AC2000		///SET APPROPRIATE BIT >
	DCA NSDRV	///STORE DRIVE NUMBER FOR LATER
	TAD I NSDTV	///
IFDEF NS3010 <
	CLL RAR		/L/ A/B BIT TO LINK
	CLA		/L/ >
IFDEF NS3040 <
	CLL RTR		///
	SPA CLA		///EVEN OR ODD ?
	 TAD (313	///OFFSET FOR ONE UNIT
	SZL		///
	 TAD (626	///OFFSET FOR TWO UNITS
	TAD NSDRV	///ADD TO TRACK ADDRESS
	DCA NSDRV	/// >
	ISZ NSDTV	/L/BUMP POINTER TO BUFFER ADDRESS
	TAD I NSDTV	/L/
	DCA NSCA	/L/STORE CURRENT ADDRESS
	TAD (NSWC	/L/
	DWCA		/L/INITIATE WC/CA SEQUENCE
	CLA		/L/IS THIS REALY NECESARRY ?
	ISZ NSDTV	/L/BUMP POINTER TO BLOCK NUMBER
	TAD I NSDTV	/L/
	AND C17		/L/EXTRACT SECTOR NUMBER (256 WRD SECTORS!)
	DLSR		/L/LOAD SECTOR REGISTER
	CLA		/L/IS THIS REALY NECCESARY
	TAD NSCTR	/L/GET CONTROL REGISTER FOR TRANSFER
			/L/(I HOPE THE WC/CA SEQ. IS FINISHED NOW )
	DLCR		/L/LOAD CONTROL REGISTER (EMA+INT ENABLE)
	CLA		/L/
	TAD I NSDTV	/L/GET BLOCK NUMBER AGAIN
IFDEF NS3010 <
	RAR		///SIGN-BIT IS A/B NOW !
	AND C7770	///
	SPA		///
	 TAD (7130	///B-SIDE HAS OFFSET OF 6260 BLOCKS
	CLL RTR		/// MAKE TRACK ADDRESS
	RAR		///IN BITS 3-11 >
IFDEF NS3040 <
	CLL RTR		///
	RTR		///
	AND (377	///TRACK ADDRESS >
	TAD NSDRV	///ADD DRIVE NUMBER IN BITS 0-1
NSRW,	HLT		///'READ-OR WRITE INSTRUCTION
	CLA		///IS THIS REALY NECESARY ?
	CDF 0		///RESTORE DATAFIELD
	JMP I NSDO	///RETURN !

NSDRV,	0		/HOLDS DRIVE NUMBER IN BITS 0-1
NSCTR,	0		/HOLD CONTROL REGISTER >
IFDEF NSRK08 <
	CLL RAL		///UNIT #
	AND C7		///
	DCA NSTEMP	///
	TAD I NSDTV	///GET FUNCTION WORD AGAIN
	AND C70		///EXTRACT FIELD BITS
	TAD NSTEMP	///ADD UNIT BITS
	TAD (6000	///ADD DONE ENABLE
	DLDC		///AND LOAD COMMAND WORD
	TAD I NSDTV	///FINALLY WE WANT TO HAVE
	RAL		///THE READ/WRITE BIT AND THE
	AND C7600	///TRANSFER LENGTH
	SZA		///(DON'T SPOIL THE LINK)
	 CIA		///MAKE NEGATIVE WORD COUNT
	DLWC		///AND LOAD THAT IN THE CONTROL
	RTL		///NOW COMPUTE A READ OR WRITE
	TAD (DLDR	///INSTRUCTION
	DCA NSRW	///AND STORE IT AHEAD
	ISZ NSDTV	///BUMP ACCESS POINTER
	ACM1		///CURRENT ADDRESS MUST BE ONE DOWN
	TAD I NSDTV	///
	DLCA		///
	ISZ NSDTV	///NOW ACCESS BLOCK NUMBER
	TAD I NSDTV	///
NSRW,	HLT		///BY THIS TIME IT'S DLDR OR DLDW
	CDTOIF		///RESET DATAFIELD
	JMP I NSDO	///THAT'S IT >
NSWC,	0		/WORDCOUNT
IFDEF NSI <
NSCA,	0		/MUST FOLLOW NSWC IMMEDIATLY !!!! >
NSDTV,	0		/PTR TO DISK TRANSFER VECTOR
	PAGE		/END IFNDEF NSRL01 >
IFDEF NSRL01 <
	RLDC=6600	/CLEAR DEVICE
	RLSD=RLDC+1	/SKIP IF DONE AND CLEAR DONE
	RLMA=RLSD+1	/LOAD MEMORY ADDRESS REGISTER
	RLCA=RLMA+1	/LOAD REGISTER A (SEEK DIFF. REG.)
	RLCB=RLCA+1	/LOAD REGISTER B
	RLSA=RLCB+1	/LOAD SECTOR ADDRESS FROM AC0-5
	RLWC=RLSA+2	/LOAD WORD COUNT REG
	RRER=RLDC+10	/READ ERROR REGISTER
	RRWC=RRER+1	/READ WORD COUNT REGISTER
	RRCA=RRWC+1	/READ REGISTER A
	RRCB=RRCA+1	/READ REGISTER B
	RRSA=RRCB+1	/READ SECTOR ADDRESS
	RRSI=RRSA+1	/READ SILO BYTE IN AC4-11
	RLSE=RRSI+2	/SKIP IF ANY ERROR

IO,	0		///INTERRUPT SERVICE ROUTINE
	TAD I XDRIVE	///
	RLCB		///LOAD FUNCTION
NSIGNR,	CIF CDF 0
	JMP I ZFSTEXT	///WAIT FOR NEXT INTERRUPT

NSINT,
ERRSKP,	NOP		///NOP OR RLSE
	 JMP I IO	///
	RRER		///READ ERROR REGISTER
	DCA NSERST	///SAVE FOR DEBUG
	ISZ NSLOG	///COUNT ERRORS
	ISZ TRYCNT	///
	 JMP I XRTRY	///TRY AGAIN
	AC0004		///(HRDERR) PASS FATAL ERROR
DONE,	DCA NSSTAT	///COMPLETION STATUS
	DCA ERRSKP	///DISABLE ERROR CHECK AS WELL
	CLA IAC		///FUNCTION DRIVE RESET
	JMS IO		///WAIT FOR NEXT INTERRUPT
	TAD XNSIGN	///NOW SET IGNORE RETURN
	DCA IO		///RL MICROPROGRAM GETS LOST ON 'OFF LINE'
	RLDC		///SO CLEAR CONTROLLER TO PREVENT ERROR FLAG ONLY
	TAD NSDEV	///PASS COMPLETION STATUS TO MYSELF
	CIF 0		/
	JMS I ZSOFINT	///
NSSTAT,	   0		///COMPLETION STATUS
NSIN0,	TAD (RLSE	///FIRST RESTORE ERROR CHECKING
	DCA ERRSKP	///
	RRSI		///READ FIRST STATUS BYTE
	BSW		///EXTRACT COVER OPEN BIT
	SPA CLA		///IS THE COVER OPEN INDEED ?
	 JMP I XINV	///YES, WE CERTAINLY WANT A FRESH BBL
	RRSI		///GET SECOND STATUS BYTE
	AND (377-40	///TEST ALL BUT WRITE LOCK
	SNA CLA		///TROUBLE ?
	 JMP I XCHK	///NO, DRIVE IS OK
	JMP I XINV	///YES, GO INVALIDATE BBL

TRYCNT,	0

PAGE
YTHIS,	.
YBLOCK,	BLOCK
YFN,	FN
YOFFS,	OFFSET
YWC,	WC
YSECT,	SECTOR
YTRCK,	TRCK
YMA,	MA
YMAP,	MAPPED
YMAPPT,	MAPPTR
YPGCT,	PGCT
YERRSK,	ERRSKP
YCUR,	CURTRK
YTAB,	DRVTAB
YLST,	ABCLST-1
YTRANS,	TRANS
YLOOP,	MAPLOP
YNONS,	NONSYS

NSDO,	0		/ROUTINE TO START A TRANSFER
	DCA ABC		/SET UNIT C
	TAD I YNONS	/TRANSFER NEW DTV
	DCA NSDTV	/
NSCDF,	CDF		//
	TAD I NSDTV	//GET FUNCTION WORD
	DCA BBLID	//STORE FOR LATER
	TAD BBLID	//
	AND C7		//EXTRACT UNIT BITS
	CLL RAR		//DRIVE+A/B IN LINK
	BSW		//GET DRIVE # IN AC 4-5
	TAD (0400	//ADD INTERRUPT ENABLE BIT
	DCA DRIVE	//THAT'S THE DRIVE WORD
	TAD ABC		//IS 'C' UNIT SET?
	SNA		//YES, MAKE 6+6 OFFSET
	 SZL		//TEST A/B BIT IN LINK, SKIP IF 'A'
	 TAD (6		//IF NOT C!A SET OFFSET FOR 'B'
	DCA ABC		//AND SET A/B/C FLAG
	AC4000		//
	TAD BBLID	//READ/WRITE TO LINK
	AND C70		//EXTRACT FIELD BITS
	SZL		//WRITE ?
	 TAD M1		//MAKE WRITE FUNCTION (=5)
	TAD (6		//MAKE 6/5 FOR READ/WRITE
	DCA IOFN	//
	TAD BBLID	//NOW FOR THE TRANSFER LENGTH
	AND C3700	//EXTRACT LENGTH BITS
	SNA		//4K ?
	 AC4000		//
	BSW		//
	CIA		//
	DCA IOPGCT	//MINUS NUMBER OF PAGES
	ISZ NSDTV	//BUMP POINTER TO BUFFER ADDRESS
	TAD I NSDTV	//
	DCA IOMA	//
	ISZ NSDTV	//BUMP POINTER TO BLOCK #
	TAD I NSDTV	//
	CDTOIF		/RESTORE DATAFIELD
	DCA I YBLOCK	/
	TAD	MYCDF	/GET OUR!! FIELD
	TAD	(6-CDF	/SETUP FOR BBL READ
	DCA I YFN	/000/000/EMA/FUN, 'DRIVE' GETS ADDED
	AC0006		/GET DRIVE BITS
	AND BBLID	/TO COMPUTE INDEX IN DRVTAB
	TAD YTAB	/
	DCA I YCUR	/SET CURRENT TRACK POINTER
	TAD I YCUR	/
	DCA AUTO13	/MAKE POINTER TO BBL POINTER LIST
	TAD I AUTO13	/
	DCA BBLID	/
	TAD ABC		/
	TAD YLST	/MAKE POINTER TO ABCLST
	DCA AUTO13	/
	TAD I AUTO13	/GET TRACK OFFSET FROM ABCLST
	DCA I YOFFS	/
	TAD I AUTO13	/GET WC FOR BBL READ
	DCA I YWC	/STORE AS TENTATIVE WC
	TAD I AUTO13	/GET SECTOR FOR BBL READ
	DCA I YSECT	/
	DCA I YTRCK	/BBL'S ARE ON TRACK 0
	TAD I AUTO13	/GET BBL OFFSET
	TAD BBLID	/
	DCA I YMA	/CA FOR BBLREAD
	TAD YTHIS	/WAS NOT RELOCATED
	TAD I AUTO13	/GET MAPPING ROUTINE ADDRESS
	DCA I YMAP	/
	TAD I AUTO13	/GET OFFSET FOR RUNNING BBL POINTER
	TAD BBLID	/
	DCA I YMAPPT	/
	DCA I YPGCT	/
RAWGO,	DCA I YERRSK	/DISABLE ERROR CHECKING ON STATUS READ
	RLSA		/ZERO SECTOR ADDRESS
	RLCA		/CLEAR A REGISTER
	TAD (1002	/READ STATUS IN BYTE MODE
	TAD DRIVE	/ADD DRIVE AND INTERRUPT ENABLE
	RLCB		/START FUNCTION
	JMP I NSDO	/END OF NSDO ROUTINE
INVBBL,	DCA I BBLID	/YES, INVALIDATE BBL
	TAD BBLID	/FOR UNITS A/B AND
	TAD (41		/
	DCA BBLID	/FOR UNIT C AS WELL
	DCA I BBLID	/
CHKBBL,	TAD I YMA	/
	DCA BBLID	/USE MA TO LOCATE CHECK WORD
	TAD I BBLID	/GET TEST WORD
	TAD (-123	/COMPARE TO ID
	SZA		/SKIP IF OK
	 JMS I YTRANS	/WRONG BBL, READ A FRESH ONE
OKBBL,	TAD IOMA	/COPY USER PARAMETERS TO
	DCA I YMA	/ACTUAL PARAMETERS
	TAD M200	/
	DCA I YWC	/
	TAD IOFN	/
	DCA I YFN	/
	TAD IOPGCT	/
	DCA I YPGCT	/
	JMP I YLOOP

NSDTV,	0
ABC,	0
IOFN,	0
IOPGCT,	0
IOMA,	0
DRIVE,	0
BBLID,	0

	PAGE
ZIO,	IO
ZDONE,	DONE
ZTRY,	TRYCNT

TRANS,	0		///READ/WRITE A SECTOR
	SNA CLA		///IS THIS A BBL READ ?
	 JMP NOTBBL	///NO, PROCEED
	AC2000		///YES, INVALIDATE CURTRK AS WELL
	DCA I CURTRK	///WE JUST DON'T KNOW WHAT HAPPENED...
NOTBBL,	ACM3		///SETUP RETRY COUNT FOR THIS SECTOR
	DCA I ZTRY	///
	TAD TRCK	///MAKE CYLINDER + SURFACE
	CLL RAR		///SURFACE GOES TO LINK
	DCA CYL		///THE CYLINDER REMAINS
	RTR		///GET SURFACE BIT AC1
	DCA SURF	///AND REMEMBER THAT
	JMS TRKCMP	///COMPARE TRCKS, TRANSFER OF SEEK COMPLETE
NSRTRY,	RLDC		///RESET INTERFACE IF NO MATCH
SEEK,	IAC		///RESET CONTROLER FOR SEEK
	JMS I ZIO	///
	TAD (1004	///READ HEADER IN BYTE MODE
	JMS I ZIO	///
	RRSI		///READ FIRST HEADER BYTE
	BSW		///
	AND C3		///GET LOWORDE TRCK BITS FROM HEADER
	DCA I CURTRK	///STORE THEM FOR A MOMENT
	RRSI		///READ SECOND HEADER BYTE
	AND (377	///CLEAN IT UP
	CLL RTL		///MAKE ROOM FOR LOWORDER BITS
	TAD I CURTRK	///ADDIN LOWORDER BITS
	DCA I CURTRK	///THAT IS THE REAL TRCK W'ER AT
	JMS TRKCMP	///TRY AGAIN
	TAD I CURTRK	///NO MATCH, COMPUTE DISTANCE TO GO
	CLL RAR		///
	CIA		///
	TAD CYL		///
	CLL RAL		///SAVE SIGNBIT IN LINK
	SZL		///MAKE DIFFERENCE ABSOLUTE
	 CIA		///
	CML RAR		///AC0=1 FOR INWARD SEEK
	TAD SURF	///ADD SURFACE BIT
	RLCA		///LOAD SEEK REGISTER
	AC0002		///WILL MAKE SEEK FUNCTION
	JMP SEEK	///
MAPLOP,	TAD I MAPPTR	///LOOK AT NEXT BBL ENTRY
	SNA		///END OF LIST ?
	 JMP I MAPPED	///YES, PROCEED
	STL CIA		///NO, COMPARE WITH CURRENT BLOCK
	TAD BLOCK	///
	SZL CLA		///SKIP IF BLOCK LT BBL ENTRY
	 JMP I MAPPED	///W'RE THROUGH
	ISZ MAPPTR	///BUMP MAP POINTER
NXTBLK,	ISZ BLOCK	///SHIFT BLOCK PAST BAD BLOCK
	JMP MAPLOP	///AND GO AROUND AGAIN
	HLT		///OVERFLOW IS CERTAINLY AN ERROR !

TRKCMP,	0		///COMPARE TRCK AND TRANSFER OF OK
	TAD I CURTRK	///THATS THE HARDWARE TRCK AND SURFACE
	CLL CIA		///
	TAD TRCK	///COMPARE TO DESIRED TRCK
	SZA CLA		///MATCH ?
	 JMP I TRKCMP	///NO, RETURN TO SEEK LOOP
	TAD SECTOR	///ON TRCK NOW, DO THE TRANSFER
	BSW		///LOAD SECTOR REGISTER
	RLSA		///
	TAD WC		///LOAD WC
	RLWC		///
	TAD SURF	///
	TAD CYL		///
	RLCA		///
	TAD MA		///GET BUFFER ADDRESS
	RLMA		///AND LOAD CURRENT ADDRESS REGISTER
	TAD FN		///GET FUNCTION
	JMS I ZIO	///AND GO... FINALY...AT...LAST.......
	TAD MA		///UPDATE BUFFER ADDRESS
	TAD C200	///FOR ONE PAGE
	DCA MA		///
	ISZ PGCT	///DONE ALL PAGES ?
	 JMP I TRANS	///NO, RETURN FROM TRANS
	JMP I ZDONE	///YES, END OF REQUEST

CVTAB,	TAD BLOCK	///CONVERT TO TRACK/SECTOR FOR 'AB'
	AND C17		///JUST 4 BITS FOR SECTOR
	CLL RTL		///
	TAD (-27	///
	SPA		///
	 TAD (47	///
	DCA SECTOR	///PHYSICAL SECTOR #
	TAD BLOCK	///
	RTR		///
	RTR		///
	AND (377	///
	TAD OFFSET	///FOR B DEVICE
	JMP DOTRAN	///AND TRANSFER THIS BLOCK
CVTC,	TAD BLOCK	///CONVERT TO TRACK/SECTOR FOR 'C' DEVICE
	AND C3		///
	CLL RTL		///
	DCA SECTOR	///
	TAD BLOCK	///
	RTR		///
	AND (777	///
	TAD OFFSET	///ADD TRACK OFFSET
DOTRAN,	DCA TRCK	///PHYSICAL TRCK
	JMS TRANS	///TRANSFER FIRST SECTOR OF BLOCK
	ISZ SECTOR	///
	ISZ SECTOR	///TWO-WAY INTERLEAVE
	JMS TRANS	///SECOND SECTOR OF BLOCK
	JMP NXTBLK	///GO FOR NEXT BLOCK IF ANY

MAPPTR,	0
BLOCK,	0
SECTOR,	0
OFFSET,	0
TRCK,	0
CURTRK,	0
SURF,	0
CYL,	0
WC,	0
MA,	0
FN,	0
MAPPED,	0
PGCT,	0
	PAGE
/ONE OR TWO PAGE WITH BAD BLOCK DATA FOR THAT DAMN THING.
/DATA TABLE, BAD BLOCK LISTS, ETC.

DRVTAB,	2000		/CURRENT TRACK
	BBL0		/AND BBL FOR DRIVE 0
	2000		/IDEM DRIVE 1
	BBL1		/!WILL BE RELOCATED
IFNZRO NSRL01-1&2 <
	2000		/IDEM DRIVE 2
	BBL2
	2000		/IDEM DRIVE 3
	BBL3		/ >

ABCLST,	0	/TRACK OFFSET AND END OF RELOCATION
	-41	/WC FOR BBL READ
	14	/SECTOR FOR BBL READ
	0	/START OF BBL LIST
	CVTAB-YTHIS	/BLOCK TO TRACK/SECTOR CONVERSION ROUTINE
	1	/OFFSET FOR RUNNING BBL POINTER
	
	400	/TRACK OFFSET FOR 'B'
	-41	/WC FOR BBL READ
	14	/SECTOR FOR BBL READ
	0	/START OF BBL LIST
	CVTAB-YTHIS	/BLOCK TO TRACK/SECTOR CONVERSION ROUTINE
	21	/OFFSET FOR RUNNING BBL POINTER

	1	/TRACK OFFSET
	-21	/WC FOR BBL READ
	16	/SECTOR FOR BBL READ
	41	/OFFSET FOR BBL LIST
	CVTC-YTHIS	/BLOCK TO TRACK/SECTOR CONVERSION ROUTINE
	42	/OFFSET FOR RUNNING BBL POINTER

BBL0,	4321		/INVALID ID
	ZBLOCK 20	/BBL UNIT 0A
	ZBLOCK 20	/BBL UNIT 0B
	4321		/INVALID ID FOR 0C
	ZBLOCK 20	/BBL UNIT 0C
BBL1,	ZBLOCK 62	/SAME ARANGEMENT FOR DRIVE 1
IFNZRO NSRL01-1&2 <
BBL2,	ZBLOCK 62	/SAME ARANGEMENT FOR DRIVE 2
BBL3,	ZBLOCK 62	/SAME ARANGEMENT FOR DRIVE 3 >
	PAGE		/END OF IFDEF NSRL01 >
	$$$