File: DISCNS.PA of Tape: OS8/OS8-V40/v40-9
(Source file text) 

/OS/8 RX01 DEVICE DRIVER (BYTE MODE)		C.E.S.D.

/THIS IS A NON-SYSTEM DEVICE DRIVER FOR THE RX01 DISKS
/THAT DRIVES THE RX8 FLOPPY DISKS IN BYTE MODE, UTILIZING
/TRACK 0, YEILDING SUBSTANTIALLY MORE STORAGE ON THE FLOPPY DISK:

/A NON-SYSTEM DISCETTE WILL HOLD 667 OS/8 BLOCKS

/FURTHERMORE, A SECTOR INTERLACE FACTOR OF TWO IS STILL MAINTAINED
/WHICH MEANS THAT THE EFFECTIVE SPEED OF THE I/O TRANSFER IS
/ALSO INCREASED.

/COPYRIGHT (C) 1976, BY: DEWAR INFORMATION SYSTEMS CORPORATION

/THIS SOFTWARE IS FURNISHED TO THE PURCHASER UNDER A LICENSE
/FOR USE ONLY ON COMPUTERS AT PURCHASER'S PLACE OF BUSINESS AND CAN
/BE COPIED (WITH INCLUSION OF DISC'S COPYRIGHT NOTICE) ONLY FOR USE
/IN SUCH SYSTEMS, EXCEPT AS MAY BE OTHERWISE PROVIDED FOR IN WRITING
/BY DISC.

/NOTE: THIS HANDLER USES TRACK ZERO.  TO SKIP TRACK ZERO, CHANGE THE
/INSTRUCTION AT THE TAG 'TRACK0' TO READ 'CLA IAC'

/BUG WITH FULL FIELD TRANSFERS FIXED BY J.V.Z.  VERSION B (9-AUG-78)


/IN ORDER TO ZERO THE DIRECTORY OF A DEVICE, THE FOLLOWING CHANGE
/MUST BE MADE TO THE OS/8 PIP.SV PROGRAM:

/	.GET SYS PIP
/	.ODT
/	13660/XXXX 6545			-# OF LAST BLOCK ON DEVICE
/	^C
/	.SAVE SYS PIP
/
/	HEADER BLOCK DEFINITION

	PAGE 0
	-2		/TWO HANDLERS, R0: AND R1:

DEVICE	RX8		/GROUP NAME FOR HANDLER
DEVICE	R0		/DEVICE NAME
	4600		/FILE-STRUCTURED, DEVICE TYPE 60
	4001		/TWO-PAGE HANDLER, ENTRY POINT AT 1
	0		/THIS WORD IS ALWAYS ZERO
	0		/(ZERO SINCE NOT A SYSTEM HANDLER)

DEVICE	RX8		/ALL THE SAME AS THE ABOVE
DEVICE	R1		/EXCEPT THE NAME IS DIFFERENT
	4600
	4006		/AND THE ENTRY POINT IS AT LOCATION 6
	ZBLOCK 2

/	DEFINE I/O INSTRUCTION CODES

RX8=	75^10		/DEFINE DEVICE ADDRESS
LCD=	 1		/LOAD COMMAND REGISTER
XDR=	 2		/TRANSFER DATA
STR=	 3		/SKIP ON TRANSFER FLAG UP, CLEAR FLAG
SER=	 4		/SKIP ON ERRORR
SDN=	 5		/SKIP ON DONE FLAG, CLEAR DONE FLAG
INIT=	 7		/GENERATE INITIAALIZE PULSE

	PAGE
/	FIRST PAGE OF I/O HANDLER

P3700,	3700		/CONSTANT

/	ENTER BELOW FOR 'R0' DRIVER

DRIVE,			/DRIVE INFORMATION SHARES CELL
RX8A,	2		/VERSION ID
P7600,	7600		/CONSTANT, ALSO CLEARS AC (GROUP 2 'CLA')
	TAD RX8A	/GET CALLING ADDRESS
	DCA RX8B	/SIMULATE CALL TO 'R1' DRIVER
	JMP IF		/OFF TO SET UNIT ZERO

/	ENTER HERE FOR THE 'R1' DRIVER

RX8B,	2		/VERSION NO.
	CLA		/ENSURE AC IS CLEAR
	TAD P20		/SET DRIVE NUMBER TO DRIVE 1
IF,	TAD P104	/SET BYTE MODE, DEFAULT TO WRITE FUNCTION
	DCA DRIVE	/MERGE HERE TO SET NUMBER TO DRIVE ZERO
	RDF		/GET CALLING FIELD
	TAD PCDI	/BUILD 'CDI' RETURN INSTRUCTION
	DCA REXIT	/STORE FOR RETURN
	RDF		/SET AGAIN FOR LOOPING ON ERROR
	TAD PCDF	/BUILD CDF TO CALLER'S FIELD
	DCA AGAIN	/AND STORE IT
D0,	JMS TEMP	/INITIALIZE FIRST TIME THROUGH, ZAPPED LATER
RETDO,	STA CLL RTL	/SET FOR THREE RETRIES ON ERROR
	DCA REPEAT

/	MERGE BACK HERE WITH MINUS 3 IN THE AC TO REPEAT AFTER AN
/	ERROR;  THIS ALLOWS ALL THE ARGUMENTS TO BE RECONSTITUTED

AGAIN,	HLT		/SET 'CDF' TO CALLER'S FIELD NOW
	TAD RX8B	/RESET ARGUMENT POINTER IF NECESSARY
	DCA RX8B	/...

/	GET WORD COUNT FOR THE TRANSFER

	TAD I RX8B	/GET FUNCTION WORD
	AND P3700	/ISOLATE RECORD COUNT
	SNA		/ZERO?
	STL RAR		/SET UP FOR FULL FIELD
	CIA		/NEGATE AND SET AS
	DCA WC		/WORD COUNT (DIVIDED BY TWO)

/	GET MEMORY FIELD FOR DATA TRANSFER, ALSO SET/CLEAR LINK AT
/	THIS POINT TO INDICATE WHETHER WE ARE READING OR WRITING

	CLA STL RAR	/PREPARE TO SET/CLEAR LINK BASED ON FUNCTION
	TAD I RX8B	/ADD IN FUNCTION WORD (LINK=1 NOW FOR WRITE)
	AND P70		/ISOLATE THE MEMORY FIELD
	TAD PCDF	/BUILD 'CDF' INSTRUCTION TO THAT FIELD
	DCA SETFLD	/STORE MEMORY FIELD NOW
	ISZ RX8B	/STEP TO NEXT ARGUMENT
	TAD I RX8B	/GET BUFFER ADDRESS FOR TRANSFER
	DCA BUF		/AND SAVE IT

	ISZ RX8B	/STEP TO NEXT ARGUMENT (BLOCK NUMBER)
	TAD I RX8B	/TIMES THREE TO GET LOGICAL SECTOR NUMBER
	TAD I RX8B	/...
	TAD I RX8B	/...
PCDI,	CDF CIF 0	/ONLY 'CDF' USED, 'CIF' DOES NO HARM HERE
	DCA I XSECTOR	/SAVE SECTOR NUMBER ONTO PAGE 2

	ISZ RX8B	/STEP POINTER NOW TO THE ERROR RETURN ADDRESS
SETFLD,	PBAD-TEMP	/SET TO BUFFER MEMORY FIELD NOW

/	LINK HAS NOT CHANGED; IT INDICATES WHETHER WE ARE
/	GOING TO READ OR WRITE

	SZL		/SKIP IF READ
	JMP WRITE	/ELSE OFF TO WRITE
/	RX8 READ CIRCUIT
/	HERE FOR READ OPERATION, FIRST JOB IS TO READ IN THE SECTOR

	TAD DRIVE	/PASS OVER THE DRIVE INFORMATION TOO
	JMS I XREAD	/SET UP FOR READING

/	LOOP HERE READING THREE BYTES AT A TIME AND PACKING THEM UP
/	INTO MEMORY, TWO WORDS AT A TIME.  THE BYTES ARE PACKED AND
/	UNPACKED INTO MEMORY IN OS8 FORMAT SINCE THIS IS ABOUT AS
/	EFFICIENT AS ANY OTHER WAY.

IB,	JMS I XGETB	/GET FIRST BYTE
	DCA PSAVE	/TEMP SAVE
	JMS I XGETB	/GET SECOND BYTE
	DCA BYT2	/SAVE IT
	JMS I XGETB	/GET THIRD BYTE
	CLL RTL		/SHIFT HALF WAY
	DCA TEMP	/AND COPY TO TEMPORARY
	TAD TEMP
	RTL		/CONTINUE SHIFT
	AND P7400	/ISOLATE HIGH NIBBLE
	TAD PSAVE	/MERGE IN FIRST BYTE
	DCA I BUF	/AND STORE IT
	ISZ BUF		/STEP BUFFER POINTER
P7400,	7400		/INSTRUCTION CONSTANT AND ALSO GROUP 2 'NOP'
	TAD TEMP	/REGET SHIFTED BYTE AGAIN
	BSW		/SHIFT UP TO LEFTMOST NIBBLE
	AND P7400	/ISOLATE THE NIBBLE
	TAD BYT2	/MERGE IN SECOND BYTE
	DCA I BUF	/STORE INTO THE BUFFER
	ISZ BUF		/STEP POINTER
P104,	104		/CONSTANT, ALSO PROTECTS 'ISZ'

	ISZ WC		/MORE WORDS TO TRANSFER?
	JMP IB		/YES - CONTINUE NOW

/	NASTY PROBLEM, IF WE ARE ONLY READING 1 OS/8 RECORD, WE WILL
/	END UP IN THE MIDDLE OF THE SECTOR WITH THE DONE FLAG DOWN
/	WITHOUT DETAILS ON THE RX01 I DON'T SEE ANY CLEAN WAY OF
/	OVERCOMING THIS PROBLEM WITHOUT FLUSHING OUT THE BUFFER.
/	APPARENTLY FORCING A DUMMY NOP COMMAND DOES NOT WORK

	JMS I XFLUSH	/FLUSH OUT REMAINDER OF BUFFER IF ANY

/	HERE TO EXIT FROM HANDLER

	ISZ RX8B	/STEP TO NORMAL RETURN
REXIT,	HLT		/RETURN 'CDI' INSTRUCTION STORED HERE
	JMP I RX8B	/RETURN NOW

/	HERE ON ERROR

BAD,	ISZ REPEAT	/TRIED THREE TIMES YET?
	JMP AGAIN	/NOT YET, DO IT ALL FROM THE TOP
	JMP REXIT	/FATAL ERROR - RETURN TO CALL NOW
/	RX8 WRITE CIRCUIT

/	HERE TO WRITE SECTORS TO THE FLOPPY DISK BUFFER
/	NOTE THAT 'DRIVE' ALREADY HAS FUNCTION CODE 4 BUILT IN
/	NOTE ALSO THAT LINK IS ALWAYS 1 ON ENTRY HERE

WRITE,	TAD DRIVE	/PASS DRIVE NUMBER OVER TO PAGE 2
	JMS I XDWRITE	/SET FUNCTION, BUT DON'T WRITE (LINK=1)

/	LOOP HERE TO WRITE BYTES TO THE BUFFER

WRLOOP,	TAD I BUF	/GET FIRST BYTE
	JMS I XPUTB	/SEND IT
	CLL RTR		/SHIFT OVER
	DCA TEMP	/AND SAVE IT
	ISZ BUF		/STEP BUFFER POINTER
P70,	70		/CONSTANT, PROTECTS 'ISZ'

	TAD I BUF	/GET THE SECOND BYTE
	JMS I XPUTB	/STORE IT
	CLL BSW		/SHIFT OVER
	TAD TEMP	/MERGE IN HIGH NIBBLE
	RTR		/SHIFT DOWN TO RIGHT JUSTIFY
	JMS I XPUTB	/INSERT INTO BUFFER
	ISZ BUF		/STEP POINTER AGAIN
P20,	20		/CONSTANT, PROTECTS 'ISZ'
	ISZ WC		/MORE WORDS TO TRANSFER?
	JMP WRLOOP	/YES - CONTINUE HERE

/	MUST CALL 'FLUSH' TO ENSURE THAT WE END ON A SECTOR BOUNDARY
/	IN CASE WE ARE ONLY WRITING HALF AN OS/8 BLOCK

	JMS I XFLUSH	/IF 1/2 BLOCK, FILL REST OF SECTOR WITH ZEROES

/	HERE AT END, MAKE FINAL CALL TO WRITE OUT THE LAST SECTOR

	TAD DRIVE	/WE MUST PASS DRIVE INFORMATION AGAIN
	JMS I XXSECT	/WRITE OUT THE LAST SECTOR NOW
	JMP REXIT-1	/QUIT NOW - ALL DONE
/	RELOCATABLE SECTION HERE

PBAD,	BAD-RETDO	/(THIS IS ON CURRENT PAGE)

XGETB,	GETB-RETDO	/THESE ARE ALL ON THE FOLLOWING PAGE
XREAD,	READ-RETDO
XPUTB,	PUTB-RETDO
XDWRITE,DWRITE-RETDO
XERROR,	ERROR-RETDO
XSECTOR,SECTOR-RETDO
XXSECT,	XSECT-RETDO
XFLUSH,	FLUSH-RETDO

/	HERE FOR THE ONCE-ONLY INITIALIZATION CODE
/	NOTE THAT VARIBLE STORAGE OVERLAYS THIS SECTION

TEMP,	0		/ADDRESS SAVED HERE BECAUSE OF 'JMS'
REPEAT,	TAD TEMP	/LOOP HERE TO MODIFY ADDRESSES
P1,	TAD PBAD	/##INSTRUCTION MODIFIED##
P2,	DCA PBAD	/##INSTRUCTION MODIFIED##
WC,	ISZ P1		/STEP ADDRESSES IN INSTRUCTIONS
BUF,	ISZ P2		/AS ABOVE
BYT2,	ISZ SETFLD	/DONE?
PSAVE,	JMP REPEAT	/LOOP FOR NEXT

/	HERE WHEN DONE, JUST SET UP ERROR RETURN FROM SECOND PAGE

IDONE,	TAD PBAD	/GET ERROR ADDRESS FOR THIS PAGE
PCDF,	CDF 0		/(HANDLER ALWAYS IN FIELD 0)
	DCA I XERROR	/STORE FOR SECOND PAGE USAGE
	DCA D0		/DON'T INITIALIZE AGAIN NOW
	JMP RETDO	/OK - LOAD UP THE ARGUMENTS NOW

	PAGE
/	SECTOR BUFFER I/O ROUTINE
/	HERE TO READ OR WRITE THE SECTOR TO/FROM THE DISK

/	CALL:
/		AC=4		/6 FOR READ, 4 FOR WRITE
/		JMS XSECT	/CALL ROUTINE
/		(RETURN)	/RETURN - NO ERRORS

XSECT,	0
	JMS LCMND	/SET THAT FUNCTION NOW

/	NOW COMPUTE THE ACTUAL PHYSICAL TRACK AND SECTOR ADDRESSES
/	FROM THE LOGICAL SECTOR NUMBER
/	WE CANNOT AFFORD TO BE SLOPPY HERE, BECAUSE OF CRITICAL
/	TIMING IN BYTE MODE.  WE THEREFORE USE A SPECIAL HIGH-SPEED
/	DIVIDE ROUTINE WHICH ASSURES THE CALCULATION IN A MINIMUM
/	AMOUNT OF TIME

	TAD TADDIV	/SET INSTRUCTION UP IN ROUTINE
	DCA DVLOOP+1
	TAD SECTOR	/COPY SECTOR OVER
	DCA TEMP3	/...
	CLL		/CLEAR LINK FOR DIVIDE LOOP

/	LOOP HERE TO DO THE FAST DIVIDE

DVLOOP,	DCA TRACK	/ZERO/UPDATE TRACK NUMBER
	TAD DIVT	/##INSTRUCTION MODIFIED##
	SNA		/TEST FOR SENTINEL ON TABLE
	JMP VDONE	/OK - ALL DONE HERE

	TAD TEMP3	/COMPARE WITH REMAINDER LEFT
	SZL		/SKIP IF SUBTRACT FAILED
	DCA TEMP3	/SUCCESSFUL - UPDATE RESULT
	CLA		/IGNORE AC (IN CASE UNSUCCESSFUL)
	TAD TRACK	/GET PARTIAL RESULT
	RAL		/SHIFT OVER
	ISZ DVLOOP+1	/STEP ADDRESS PART OF INSTRUCTION ABOVE
	JMP DVLOOP	/AND LOOP

/	PARTITION VALUES FOR THE DIVIDE

	DECIMAL
DIVT,	-26^64
	-26^32
	-26^16
	-26^8
	-26^4
	-26^2
	-26^1
	0
	OCTAL

TADDIV,	TAD DIVT	/INSTRUCTION CONSTANT HERE
/	LITTLE SUBROUTINE TO SET DRIVE INFORMATION

DWRITE,	0
	DCA XDRIVE	/SAVE THE DRIVE NUMBER (IN CASE FROM PAGE 1)
	TAD XDRIVE	/REGET
	SNL		/IF LINK=1, DON'T WRITE
	JMS XSECT	/OK, WRITE THE BUFFER
	CLA CLL IAC BSW	/SET FUNCTION TO FILL BUFFER
	JMS LCMND	/...
	TAD M129	/RESET BUFFER COUNTER
	DCA BCOUNT	/...
	JMP I DWRITE	/RETURN TO CALL


/	HERE TO PUT BYTES INTO THE SECTOR BUFFER

PUTB,	0
	ISZ BCOUNT	/IS SECTOR BUFFER NOW FULL?
	JMP PUTB2	/NOT YET - CONTINUE

	DCA FLUSH	/YES FULL, SAVE CURRENT BYTE
	CLL		/CLEAR LINK TO FORCE WRITE OF SECTOR
	TAD XDRIVE	/DRIVE WAS SET FIRST TIME THROUGH (LINK=0)
	JMS DWRITE	/WRITE OUT THE SECTOR
	TAD FLUSH	/REGET THE BYTE TO STORE
	JMP PUTB+1	/LOOP BACK NOW

PUTB2,	IOT RX8 STR	/READY TO RECEIVE THE BYTE YET?
	JMP PUTB2	/NOT YET - SO WAIT
	IOT RX8 XDR	/TRANSFER THE DATA BYTE
	AND X7400	/JUST RETURN BITS 0-3 IN THE AC
	JMP I PUTB

/	SUBROUTINE TO LOAD THE COMMAND BUFFER.  THE 'DONE' FLAG MUST
/	BE SET (OR MUST BE IN A POSITION WHERE IT WILL BECOME SET)

LCMND,	0
	IOT RX8 SDN	/WAIT FOR DONE FLAG TO COME UP
	JMP .-1		/WAIT FOR IT
	IOT RX8 LCD	/LOAD THE COMMAND UP NOW
	JMP I LCMND	/RETURN NOW TO CALL
/	HERE TO SETUP FOR READ OPERATION
/	NOTE THAT FUNCTION CODE ALREADY HAS 4 BUILT IN, SO WE ONLY
/	HAVE TO ADD 2 TO GET THE FUNCTION COE OF 6

READ,	0
	SZA		/SKIP IF SECOND TIME THRU (ALREADY HAVE DRIVE)
	DCA XDRIVE	/SAVE DRIVE INFORMATION ON THIS PAGE
	CLA CLL IAC RAL	/FUNCTION CODE 6 FOR READ TO BUFFER
	TAD XDRIVE	/RETRIEVE DRIVE INFORMATION
	JMS XSECT	/READ THAT NOW
	TAD M129	/SET COUNT FOR BUFFER
	DCA BCOUNT	/...
	TAD P102	/FUNCTION IS READ BUFFER, BYTE MODE
	JMS LCMND	/LOAD THAT COMMAND NOW
	JMP I READ	/RETURN NOW

/	SUBROUTINE TO GET NEXT BYTE OUT OF THE BUFFER

GETB,	0
	ISZ BCOUNT	/READ 128 BYTES ALREADY?
	JMP .+3		/NOT YET

	JMS READ	/READ NEXT SECTOR
	JMP GETB+1	/CONTINUE

	IOT RX8 STR	/SKIP ON TRANSFER FLAG UP
	JMP .-1		/NOT UP - WAIT FOR IT
	IOT RX8 XDR	/READ A DATA BYTE
	JMP I GETB	/AND RETURN IT IN THE AC

/	HERE AT END OF OPERATION.  IF WE ARE NOT AT THE END OF THE
/	SECTOR BUFFER, JUST KEEP CALLING 'GETB' UNTIL ALL BYTES ARE
/	FLUSHED OUT.  THIS ENSURES THAT RX01 IS RE-INITIALIZED PRO-
/	PERLY AND THAT THE DONE FLAG COMES UP.  THERE MUST BE A BETTER
/	WAY OF DOING THIS, BUT THERE IS ROOM HERE FOR THE FUNCTION.
/	NOTE THAT THIS IS DONE FOR BOTH READ AND WRITE OPERATIONS.

FLUSH,	0
	CLA CLL IAC	/CLEAR AC TWO
	TAD BCOUNT	/TEST FOR COUNT WITH VALUE OF -1
	SNA CLA		/SKIP IF NOT AT END
	JMP I FLUSH	/ALL DONE HERE
	JMS GETB	/FLUSH OUT ANOUTHER BYTE
	JMP FLUSH+1	/AND LOOP TILL BUFFER CLEAR
/	NOW COMPUTE ACTUAL PHYSICAL SECTOR BY CONVERTING LOGICAL
/	SECTOR OFFSET TO PHYSICAL SECTOR BASED ON SECTOR INTERLACE
/	FACTOR OF TWO

/	CALCULATION IS:

/	(SECTOR.MOD.13)*3 + (SECTOR/13) + 1

VDONE,	DCA TEMP2	/SET SECTOR ADDRESS TO ZERO
	TAD TEMP3	/GET LOGICAL SECTOR OFFSET TO TRACK

/	LOOP HERE TO COMPUTE ACTUAL PHYSICAL SECTOR ADDRESS

CLOOP,	TAD M13		/FIRST DIVIDE BY 13
	ISZ TEMP2	/COUNT THE SUBTRACTIONS HERE
	SMA		/TEST FOR END OF DIVIDE
	JMP CLOOP	/NOT DONE YET SO LOOP ON IT
	TAD P13		/SAVE RESULT MODULO 13
	CLL RAL		/MULTIPLY BY TWO (SECTOR INTERLACE FACTOR)
	TAD TEMP2	/ADD IN SECTOR/13 + 1
	IOT RX8 STR	/WAIT FOR CONTROLLER READY
	JMP .-1		/...
	IOT RX8 XDR	/LOAD IT NOW

/	CHANGE THE INSTRUCTION BELOW TO 'CLA IAC' TO SKIP TRACK ZERO
/	COMPLETELY

TRACK0,	CLA		/(XDR DOES NOT CLEAR AC)
	TAD TRACK	/GET PHYSICAL TRACK NUMBER
	IOT RX8 STR	/WAIT ON CONTROLLER AGAIN
	JMP .-1
	IOT RX8 XDR	/TRANSFER THE TRACK NUMBER NOW
	CLA		/MUST CLEAR AC AGAIN

/	NOW WAIT FOR OPERATION TO COMPLETE

	IOT RX8 SDN	/WAIT FOR IT
	JMP .-1		/...

/EXECUTE DUMMY INSTRUCTION NOW TO FORCE DONE FLAG TO COME UP AGAIN

	TAD P10		/THIS IS A 'NOP' INSTRUCTION TO CONTROLLER
	IOT RX8 LCD	/EXECUTE DIRECTLY (SINCE DONE FLAG IS DOWN)
	ISZ SECTOR	/UPDATE CURRENT LOGICAL SECTOR NUMBER

	IOT RX8 SER	/SKIP ON ANY ERRORS
	JMP I XSECT	/RETURN - ALL DONE HERE

/	HERE ON ERROR.  JUST INITIALIZE AND TRY AGAIN FROM THE TOP

	IOT RX8 INIT	/RE-INITIALIZE THE DISK NOW
	CLA CLL CMA RTL	/SET AC NOW IN CASE RECOVERABLE, NON-RECOVERABLE
	JMP I ERROR	/RETURN NOW
TEMP2,	0
TEMP3,	0
SAVE,	0
X7400,	7400
XDRIVE,	0
BCOUNT,	0
SECTOR,	0
TRACK,	0
M13,	-15
P13,	+15
P10,	10
M129,	-201
P102,	102
ERROR,	0		/WILL POINT TO 'BAD' AFTER INITIALIZE DONE

	PAGE		/MUST NOT BE UP TO HERE
	$