                                                      
/BI-DIRECTIONAL PDP-7 DECTAPE SUBROUTINES
/ASSUMES STANDARD 400 (OCTAL) WORD BLOCKS
/LMH    JANUARY 21, 1966
/DISMIS MUST BE DEFINED AS JMP TO DISMISS INTERRUPT ROUTINE

/PDP-7 DEC-TAPE SEARCH SUBROUTINE

MMWR=707504
MMLC=707604
MMSE=707644
MMRS=707612
MMDF=707501
MMBF=707601
MMEF=707541
MMRD=707512
SKP7=703341
ASC=705502
EPI=700044
DBR=705601
LEM=707704
EEM=707702
EMIR=707742


/LEAVE IN SEARCH REVERSE MODE, START REVERSE
MMSCHR,	LAW 41		/SEARCH FWD
	DAC MMWA3	/SET CURRENT DIRECTION
	CLA
	JMP MMSCH8

/LEAVE IN SEARCH REVERSE MODE, START FORWARD
MMSRF,	LAW 61		/SEARCH REVERSE
	JMP MMSCHR+1
                                                                                                       

/LEAVE IN SEARCH FORWARD MODE, START REVERSE
MMSFR,	LAW 41		/SEARCH FORWARD
	SKP


/LEAVE IN SEARCH FORWARD MODE, START FORWARD
MMSCH0,	LAW 61		/SEARCH REVERSE, USED AS CONSTANT
	DAC MMWA3	/SET CURRENT DIRECTION
	LAM		/LOAD -0, USED AS CONSTANT
MMSCH8,	DAC MMSBK
	TAD (1)
	DAC MMSFK
	LAW MMERS	/SET UP INTERRUPT RETURN
	DAC MMERR
	LAW MMDATS
	DAC MMDATA
	LAC MMBLKM	/PICK UP BLOCK NUMBER
	ADD MMEK
	SMA
	JMP MMSCH5	/FORMAT ERROR
	LAM -7
	DAC MMSUM	/CHG OF DIRECTION COUNTER


/35 MILLISECOND SELECT DELAY LOOP
MMWAIT,	MMRS
	AND (400)	/SAVE CONTROL TYPE ONLY
	SZA
	JMP MMSCH9	/NO DELAY FOR NEW DRIVES
	LAC MMCHK1+1	/PICK UP SELECT
	SAD MMSEL	/PREVIOUS SELECT
	JMP MMSCH9+1	/SAME SELECT
	DAC MMSEL	/SAVE SELECT
MMW2,	CLA		/USED AS CONSTANT
	MMSE		/SELECT UNIT ZERO
	LAM DECIMAL -5000+1 OCTAL
	DAC MMBLF	/TEMPORARY STORAGE AREA
	ISZ I .-1	/7 MICROSECONDS PER LOOP
	JMP .-1		/COUNT 35 MILLISECONDS
                                                                                                       
MMSCH9,	LAC MMCHK1+1	/UNIT SELECTION
	MMSE
	LAC (NOP)
	DAC MMSAVE
	LAC MMAPII	/DECTAPE ON API INDICATOR
	SZA		/DO ION IF NOT ON API
	JMP MMAPI	/TURN ON API
	ION

MMTURN,	ISZ MMSUM
	SKP
	JMP MMERX2-1	/NOT FOUND
	LAC MMWA3	/CURRENT SELECT
	XOR (20)		/COMPLEMENT DIRECTION
	MMLC		/SEARCH IN CORRECT DIRECTION
	DAC MMWA3	/SAVE SELECTION
	SAD MMSCH0	/LAW 61
	JMP MMREV	/SET UP REVERSE CONSTANTS
	LAC MMCK3	/SMA, SET TO CONTINUE IN FORWARD DIRECTION
	DAC MMSCH2
	LAC MMBLKM
	TAD MMSFK
	DAC MMWA2	/BLOCK TO LOOK FOR IN THIS DIRECTION
	DZM M#MDONE
MMSAVE,	NOP		/OR DISMIS
	LAC MMRD3B+1	/DISMIS
	DAC MMSAVE
	ISZ MMWA		/INDEX POINTER
	EMIR
	JMP I MMWA	/RETURN TO MAIN PROGRAM
MMREV,	LAC MMCK2	/SPA, SET TO CONTINUE IN REVERSE DIRECTION
	DAC MMSCH2
	LAC MMBLKM
	TAD MMSBK
	JMP MMSAVE-2
                                                                                                       
/INSTRUCTIONS FOR AUTOMATIC PRIORITY INTERRUPT
MMAPI,	LAC MMAPIC	/DECTAPE CHANNEL NUMBER
	EPI		/ENABLE API
	ASC		/ENABLE DECTAPE CHANNEL
	JMP MMTURN

/ROUTINES TO ANSWER INTERRUPT SEQUENCE
MMERS,	MMRS
	AND (40000)	/CHECK EOT BIT
	SZA
	JMP MMTURN	/EOT, TURN AROUND
	LAW 300		/NON-EOT ERROR DURING SEARCH
	JMP MMERX2
MMDATS,	MMRD
	DAC I M#MWA1
	SAD MMWA2
	JMP MMSCH3
	CMA
	ADD MMWA2
MMSCH2,	SMA		/OR SPA FOR REVERSE
	JMP MMSAVE-1	/KEEP GOING
	JMP MMTURN	/TURN AROUND
MMSCH3,	SAD MMBLKM
	JMP I MMCHK	/EXIT TO READ OR WRITE ROUTINES
	JMP MMTURN
MMSCH5,	LAW 100
	JMP MMERX2	/FORMAT ERROR
MMEK,	DECIMAL -576 OCTAL


/ERROR LOOP
	LAW 200		/NOT FOUND
MMERX2,	DAC MMBLF	/STORAGE AREA
	MMRS
	DAC MMRSA
	JMS MMROLL	/ADD ROLL CONSTANT
	LAC MMERRX
	AND (20000)
	SZA		/JMP
	EMIR		/JMP I
	CLC
	DAC MMDONE
	LAC MMBLF	/STORAGE AREA
	MMLC
MMERRX,	JMP .
	HLT		/ERROR EXIT WAS NOT A JMP INSTRUCTION
                                                                                                       
MMSEL,	0		/SAVE SELECTION
MMERR,	0		/ERROR RETURN
MMDATA,	0		/DATA RETURN
MMBLF,	0		/BLOCK FLAG RETURN
MMAPIC,	10000		/NORMAL DECTAPE CHANNEL=3
MMWAX,	3		/POSITION OF UNIT 1
	3		/POSITION OF UNIT 2
	3		/POSITION OF UNIT 3
	3		/POSITION OF UNIT 4
	3		/POSITION OF UNIT 5
	3		/POSITION OF UNIT 6
	3		/POSITION OF UNIT 7
	3		/POSITION OF UNIT 10


/INTERLOCK LOOP, HANGS UP MAIN PROGRAM UNTIL GO=0
MMITLK,	0		/USED FOR MMSUM
	LEM		/LEAVE EXTEND MODE
	MMRS		/GET STATUS
	AND (4000)	/CHECK GO BIT
	SZA		/NOT GOING?
	JMP .-3		/WAIT
	JMP I MMITLK	/SYSTEM AVAILABLE

/LOOP TO ADD ROLL CONSTANT TO CURRENT ADDRESS
MMROLL,	0		/USED AS WORK AREA, MMSBK
	LAC MMWA3	/LAST SEARCH COMMAND
	AND (20)		/SAVE DIRECTION BIT
	SZA		/GOING FORWARD
	LAM -5		/TO CREATE LAM -2
	ADD (3)		/ROLL CONSTANT
	TAD I MMWA1	/ADD CURRENT LOCATION
	DAC I MMWA1	/STORE CURRENT LOCATION
	JMP I MMROLL
                                                                                                       

/COMMON ROUTINE FOR PICKING UP CONSTANTS AND SEARCHING
/PICK UP PARAMETERS
MMCHK,	0
	XCT I MMWA	/BLOCK NUMBER
	AND (7777)
	DAC MMBLKM	/SAVE BLOCK NUMBER
	ISZ MMWA		/INDEX POINTER TO ERROR RETURN
	LAC I MMWA	/ERROR RETURN
	DAC MMERRX	/IN SEARCH EXIT
	ISZ MMWA		/INDEX POINTER TO UNIT
	LAC I MMWA	/UNIT
	AND (170000)	/KEEP UNIT ONLY
	DAC MMCHK1+1	/IN CALLING SEQUENCE
	RCL		/CLEAR AND ROTATE LINK
	RTL		/PUT UNIT NUMBER IN L.O.POSITION
	RTL
	RTL
	ADD (MMWAX-1)
	DAC MMWA1	/ADDRESS OF POSITION POINTER
			/FOR THIS UNIT
	ISZ MMWA		/INDEX POINTER TO STARTING ADDRESS
	LAC I MMWA	/STARTING ADDRESS
	AND (77777)	/15 BIT ADDRESS
	DAC MMADDR	/LOCATION POINTER
	ISZ MMWA		/INDEX POINTER TO ENDING ADDRESS

/CALCULATE NUMBER OF DATA AND FILLER WORDS
	LAC I MMWA	/FINAL ADDRESS
	AND (77777)	/15 BIT ADDRESS
	CMA
	ADD MMADDR	/STARTING ADDRESS
	SMA
	JMP MMSCH5	/ILLEGAL FORMAT
	DAC MMWDC	/-NO. OF DATA WORDS+1
	AND (377)	/LOW ORDER 8 BITS
	XOR (777400)	/MAKE NUMBER NEGATIVE
	TAD (377)
	CMA
	DAC MM2CN	/-NO OF FILLER WORDS+1
	LAM -1
	DAC MMFILC	/SECTION COUNTER
                                                                                                       

/CALCULATE THE DIRECTION TO SEARCH
	LAC MM#BLKM	/BLOCK DESIRED
	SNA
	JMP MMSCH5	/BLOCK 0, FORMAT ERROR
	CMA
	ADD I MMWA1	/CURRENT POSITION
MMCK2,	SPA		/CURRENT POSITION HIGHER THAN DESIRED BLOCK
	JMP MMGF		/SEARCH AND TRANSFER DATA FORWARD
	DAC MMWA5	/DISTANCE TO START BLOCK
	LAC MM#WDC	/-NUMBER OF DATA WORDS+1
	CMA!CLL		/NUMBER OF DATA WORDS-1
	AND (777400)	/KEEP NUMBER OF BLOCKS-1
	RTR		/DIVIDE BY 400 OCTAL
	RTR
	RTR
	RTR

	ADD MMBLKM	/STARTING BLOCK
	DAC MMWA7	/LAST BLOCK
	CMA
	ADD I MMWA1	/CURRENT POSITION
MMCK3,	SMA		/CURRENT POSITION IS WITHIN TRANSFER SECTION
	JMP MMGR2	/SEARCH AND TRANSFER DATA IN REVERSE
	ADD MMWA5	/DISTANCE TO START BLOCK
	SMA		/START IN REVERSE, TRANSFER DATA FORWARD
	JMP MMGR		/START FWD, TRANSFER DATA IN REVERSE

/START IN REVERSE, TRANSFER DATA FORWARD
	LAW MMSFR
	SKP

/START AND TRANSFER DATA FORWARD
MMGF,	LAW MMSCH0
	DAC MMWA5	/SET UP SEARCH ENTRANCE
	LAC (1)
	DAC MMDK		/FOR INCREMENTING ADDRESS
MMGF2,	LAC (DAC I MMADDR)	/SET READ ROUTINE
	DAC MMRD3
	LAC (LAC I MMADDR)	/SET WRITE ROUTINE
	DAC MMWR3+1
                                                                                                       
/START SEARCH
MMCHK1,	JMP I MMWA5	/TO SEARCH
	0		/UNIT AND WORK AREA MMWA2


/START FORWARD, TRANSFER DATA IN REVERSE
MMGR,	LAW MMSRF
	SKP

/START AND TRANSFER DATA IN REVERSE
MMGR2,	LAW MMSCHR
	DAC MMWA5	/SET UP SEARCH ENTRANCE
	LAM
	DAC MMDK		/TO DECREMENT ADDRESS
	LAC MM2CN	/FILLER COUNTER
	SZA!CMA		/+0 IF THERE ARE NO FILLERS
	ADD (1)
	ADD I MMWA	/ENDING ADDRESS
	DAC MMADDR	/DATA LOCATION POINTER
	LAC MMWA7	/SEARCH FOR LAST BLOCK
	DAC MMBLKM
	LAC MM2CN
	SNA
	JMP MMGR3	/NO FILLERS
	DAC MMWA6	/EXCHANGE MMWDC AND MM2CN
	LAC MMWDC
	DAC MM2CN
	LAC MMWA6
	DAC MMWDC
	LAC (NOP)
	DAC MMRD3	/FOR FILLERS IN RD ROUTINE
	LAC MMW2	/FOR FILLERS IN WRITE ROUTINE, CLA
	JMP MMCHK1-1
MMGR3,	ISZ MMFILC
	JMP MMGF2
                                                                                                       
/DECTAPE SUBROUTINE, READ  PDP-7
/FORMAT	JMS MMRDS
/	LAW B		/OR LAC (B), BLOCK NUMBER
/	JMP X		/ERROR RETURN
/	ZZ0000		/UNIT SELECTION
/	C1		/15-BIT CORE STARTING ADDRESS
/	C2		/15-BIT CORE ENDING ADDRESS, INCLUSIVE
/	MULTI-PROGRAM RETURN

MMRDS,	0
	JMS MMITLK	/CHECK IF SYSTEM IS FREE
	LAC MMRDS
	DAC MMWA		/STORE POINTER TO ARGUMENTS
	JMS MMCHK	/GET ARGUMENTS AND SEARCH

/RETURN FROM SEARCH WITH BLOCK FOUND
	LAW MMRD1	/SET UP INTERRUPT RETURNS
	DAC MMERR
	LAW MMRD4
	DAC MMBLF
MMRD0,	XCT MMWA3	/SEARCH COMMAND
	ADD (1)		/MAKE READ COMMAND
	MMLC
	LAW MMRD1A
	DAC MMDATA
	DZM MMDONE
	DISMIS
MMRD1,	LAW 400		/ERROR FLAG DURING READING
	JMP MMERX2
MMRD1A,	MMRD		/READ REVERSE CHECKSUM
	DAC MMSUM
	LAW MMRD2
	DAC MMDATA
	DISMIS
MMRD2,	MMRD		/READ DATA
	EEM		/ENABLE EXTENDED MEMORY
MMRD3,	DAC I MM#ADDR	/OR NOP
	LEM		/DISABLE EXTENDED MEMORY
	JMS MMRD6	/CALCULATE CHECKSUM
MMRD3A,	ISZ MM#FILC	/SECTION COUNTER
	JMP MMRD5	/SET UP FOR SECTION
	LAC (NOP)
MMRD3B,	DAC MMRD3	/DO NOT STORE REMAINDER OF BLOCK
	DISMIS		/USED AS CONSTANT
                                                                                                       
MMRD4,	MMRD		/READ FORWARD CHECKSUM
	ADD MMSUM
	SAD MMSCH8-1	/-0
	JMP .+3
	LAW 500		/SUM CHECK READING
	JMP MMERX2
	JMS MMBLC	/CHECK NEXT BLOCK NUMBER
	JMP MMRD0	/READ NEXT BLOCK

MMRD5,	LAC MM#2CN	/2ND SECTION COUNTER
	SNA
	JMP MMRD3A	/NO FILLERS
	DAC MMWDC	/SET UP WORD COUNTER
	LAC (DAC I MMADDR)
	SAD MMRD3
	JMP MMRD3B-1	/STORE NOP
	JMP MMRD3B	/STORE DAC INSTRUCTION

/ADD TO CHECKSUM AND INCREMENT OR DECREMENT ADDRESS
MMRD6,	0		/USED AS WORK AREA, MMWA5
	ADD MMSUM	/PREVIOUS CALCULATION
	DAC MMSUM	/STORE NEW RESULT
	LAC MMADDR	/CURRENT ADDRESS
	TAD MMDK		/+1 OR -1
	DAC MMADDR	/NEW ADDRESS
	ISZ MMWDC	/WORD COUNTER
	DISMIS
	JMP I MMRD6	/CHECK FOR FILLERS ETC.

/CHECK NEXT BLOCK MARK NUMBER
MMBLC,	0		/USED AS WORK AREA, MMSFK
	LAW MMBLC2
	DAC MMDATA	/SET DATA FLAG RETURN
	XCT MMWA3	/SEARCH COMMAND
	MMLC
	DISMIS
MMBLC2,	LAC I MMWA1	/CURRENT BLOCK NUMBER
	TAD MM#DK	/+1 OR -1
	DAC I MMWA1	/NEW BLOCK NUMBER
	MMRD
	SAD I MMWA1	/COMPARE TO CORRECT NUMBER
	JMP .+3	
	LAW 700		/BLOCK MARK ERROR
	JMP MMERX2
	LAC MMFILC	/SECTION COUNTER
	SZA
	JMP I MMBLC	/RETURN FOR NEXT BLOCK
	MMLC		/STOP THE TAPE
	JMS MMROLL	/ADD ROLL CONSTANT
	CLC
	DAC MMDONE	/SET DONE SWITCH
	DISMIS
                                                                                                       

/DEC-TAPE WRITE SUBROUTINE, PDP-7
/FORMAT	JMS MMWRS
/	LAW B		/OR LAC (B), BLOCK NUMBER
/	JMP X		/ERROR RETURN
/	ZZ0000		/UNIT SELECTION
/	C1		/15-BIT CORE STARTING ADDRESS
/	C2		/15-BIT ENDING ADDRESS,INCLUSIVE
/	MULTI-PROGRAM RETURN

MMWRS,	0
	JMS MMITLK	/CHECK IF SYSTEM IS FREE
	JMS MMCHK	/PICK UP ARGUMENTS AND SEARCH

/RETURN FROM SEARCH WITH BLOCK FOUND
	LAW MMWR2	/SET UP INTERRUPT RETURNS
	DAC MMERR
	LAW MMWR4
	DAC MMBLF
MMWR1,	LAW MMWR3
	DAC MMDATA
	DZM MMDONE
	CLC
	DAC MMSUM	/START CHECKSUM
	XCT MMWA3	/SEARCH COMMAND
	ADD (2)		/CREATE WRITE COMMAND
	MMLC
	DISMIS
MMWR2,	LAW 600		/ERROR FLAG DURING WRITING
	JMP MMERX2
MMWR3,	EEM		/ENABLE EXTENDED MODE
	LAC I MMADDR	/OR CLA
	LEM		/DISABLE EXTEND MODE
	MMWR
	JMS MMRD6	/CALCULATE CHECKSUM
MMWR3A,	ISZ MMFILC	/SECTION COUNTER
	JMP MMWR6	/SET UP FOR 2ND SECTION
	LAC MMW2		/CLA
                                                                                                       
MMWR3B,	DAC MMWR3+1
	DISMIS
MMWR4,	LAC MMSUM	/WRITE CHECKSUM
	CMA
	MMWR
	JMS MMBLC	/CHECK NEXT BLOCK NUMBER
	JMP MMWR1

MMWR6,	LAC MM2CN
	SNA
	JMP MMWR3A
	DAC MMWDC
	LAC (LAC I MMADDR)
	SAD MMWR3+1
	JMP MMWR3B-1
	JMP MMWR3B

MMWA6=MMSAVE
MMWA5=MMRD6
MMWA3=MMRDS
MMSFK=MMBLC
MMWA2=MMCHK1+1
MMSBK=MMROLL
MMWA=MMWRS
MMSUM=MMITLK
MMWA7=MMSUM
MMRSA=MMERR

START
                                                                                                                                                                                                                                                                         iv|{\Y                                                                                                                                                                                                                                                                                                                                                               Dq|FsY                                                                                                                                                                                               