File IO.PA (PAL assembler source file)

Directory of image this file is from
This file as a plain text file

TITLE	MTA	VERSION OF 30 JUN 74
	IFDEF MTA.BLOCKS <
	IFZERO ALPHA1.SYS&100 <LIST NOPAGES>/THE /F SWITCH
	IFNZRO ALPHA3.SYS&2000 <
	LIST OFF
	>
	BEGIN MTA
	IFNDEF CORDMP.MTA <
	CORDMP=0
	>
	IFREQ RANDOM <
	REQUEST MTA RECORD
	>
	IFREQ WEOI <
	REQUEST MTA RECORD
	>
	IFNDEF WC'.MTA <
	WC'=0
	>
	IFNDEF CA'.MTA <
	CA'=0
	>
	IFNDEF UNIT'.MTA <
	UNIT'=0
	>
	IFNDEF FIELD'.MTA <
	FIELD'=0
	>
	IFNDEF RETRY.MTA <
	RETRY=10
	>
	IFREQ MOVEF <
	REQUEST MTA FILE
	>
	IFREQ SKIPF,MOVEF <
	REQUEST MTA RECORD,SKIPR
	>
	ORGZERO
	IFNEG .-20 <
	*20
	> /SKIP THE AUTO-INDEX REGISTERS.
MTDO	=JMS I .
	MTDO$
UNIT,	UNIT'.MTA	/MAGTAPE UNIT TO BE USED.
	IFREQ WRITE,READ <
FIELD,	FIELD'.MTA	/MEMORY FIELD FOR TRANSFER.
CA,	CA'.MTA		/CORE ADDRESS-1 OF TRANSFER.
WC,	-WC'.MTA	/WORD COUNT FOR TRANSFER.
	>
	IFREQ READ <
READ	=JMS I .
	READ$
	>
	IFREQ WRITE <
WRITE	=JMS I .
	WRITE$
	>
	IFREQ LOCK <
LOCK,	0
	>		/LOCK FLAG: CAN BE USED TO LOCK A RECORD INTO CORE.
	IFREQ RECORD <
RECORD,	0
	>		/RECORD MAGTAPE CURRENTLY POSITIONED BEFORE (FROM 0 UP).
	IFREQ FILE <
FILE,	0
	>		/CURRENT FILE (FROM 0 UP).
	IFREQ SKIPF <
SKIPF	=JMS I .
	SKIPF$
	ELSE
	IFREQ MOVEF <
MOVEF	=JMS I .
	MOVEF$
	>
	>
	IFREQ SKIPR <
SKIPR	=JMS I .
	SKIPR$
	>
	IFREQ REWIND <
REWIND	=JMS I .
	RWIND$
	>
	IFREQ WEOI <
WEOI	=JMS I .
	WEOI$
	>

SUBR MTDO$ /UTILITY FOR MAGTAPE ROUTINES. MTSF=6701; MTTR=6721; MTPC=6732; MTLC=6716; MTXL=6734; MTGO=6722; MTRS=6706; MTCM=6714 MTDO$, 0 DCA 7752 /SET WC FOR OPERATION. IFREQ WRITE,READ < TAD CA DCA 7753 /AND CURRENT ADDRESS, FOR READ AND WRITE. > MTPC /CLEAR EVERYTHING; CONTROL IS NOW READY. TAD UNIT MQL SHL;^D 20 /GET UNIT, TAD I MTDO$ /FUNCTION, TAD COMBITS /AND VARIOUS OTHER MTLC /BITS FOR THE COMMAND REGISTER. INTCHK /GOOD PLACE TO CHECK FOR INTERRUPT KEY. MTTR /WAIT FOR SELECTED TRANSPORT TO BECOME READY. JMP .-2 TAD FIELD.MTA /LOAD EXTENDED MEMORY REGISTER. MTXL MTGO /KICK THE THING OFF. WAITMT, INTCHK IFREQ SKIPR < IFREQ BOTCHK </IF A SPACE REVERSE COMMAND IS GIVEN WHEN THE MTRS /DRIVE IS NOT AT BOT, BUT THE DRIVE THEN SPACES TO BOT, AND (1000 /THEN NEITHER MTF OR EF COMES UP: HENCE WE MUST CHECK FOR TAD I MTDO$ /BOT HERE. TAD (-1070 /IF BOT IS ON AND COMMAND IS SPREV, THEN GOTO THE LABEL BOT. SNA CLA JMP I (BOT > > MTSF /LET IT FINISH. JMP WAITMT IFDEF MTEOT < MTRS /MIGHT AS WELL CHECK FOR END-OF-TAPE HERE. AND (40 SZA CLA JMP MTEOT > JMP I MTDO$ COMBITS,CORDMP.MTA_7+403
IFREQ SKIPR < /SKIP RECORDS. SUBR SKIPR$ SKIPR$, 0 SNA JMP SKPRXIT /NOTHING TO SKIP; EASY. IFREQ RECORD < DCA SKPRCT /SAVE NO. OF RECORDS TO SKIP. TAD SKPRCT /UPDATE RECORD NO. BY TENTATIVE NO. TAD RECORD /OF RECORDS TO BE SKIPPED. DCA RECORD TAD SKPRCT > SMA JMP RFWD /SKIP FORWARD. MTDO; 70 /BACK UP NO. OF RECORDS INDICATED. JMS EOFCHK MTDO; 60 /GO FWD OVER EOF. BOT, /CONTROL TRANSFERRED HERE BY MTDO ON BKSP OVER BOT. IFREQ RECORD < DCA RECORD /RECORD WILL BE 0 IF EOF HIT ON BKSP. > JMP I SKIPR$ RFWD, CIA MTDO; 60 /GO FWD NO. OF RECORDS INDICATED. JMS EOFCHK /CHECK FOR EOF. IFREQ RECORD < TAD 7752 /CORRECT RECORD NO. FOR NO. OF RECORDS NOT SKIPPED TAD RECORD /DUE TO EOF. DCA RECORD STA > MTDO; 70 /BACK OVER THE EOF. JMP I SKIPR$ EOFCHK, 0 MTRS AND (100 SNA CLA JMP SKPRXIT /NO EOF: EXIT SKIPR$ NORMALLY. STA /OTHERWISE RETURN WITH AC=-1. JMP I EOFCHK SKPRXIT,ISZ SKIPR$ JMP I SKIPR$ IFREQ RECORD < SKPRCT, 0 > >
IFREQ SKIPR,MOVEF </SKIP FILES OR MOVE TO FILE. SUBR MOVEF$ MOVEF$, SKIPF$, 0 CIA /GET -VE NO. OF FILES TO SKIP. IFREQ MOVEF < TAD FILE > SPA JMP SFWD /SKIP FORWARD. CMA /BACKWARDS: CORRECT COUNT. DCA SKPFCT JMP SREV1 SREV, STA /BACK OVER EOF AT END OF FILE BEFORE MTDO; 70 /BACKING OVER ENTIRE FILE. IFREQ FILE < STA /CORRECT FILE NO. TAD FILE DCA FILE > SREV1, CLA STL RAR /MAX BACKWARDS COUNT FOR SKIPR. SKIPR DCA RECORD /NOW AT BEGINNING OF FILE. ISZ SKPFCT JMP SREV /MORE TO DO. SFEND, IFREQ LOCK < DCA LOCK /MAKE SURE READ DOESN'T THINK ANYTHING'S IN CORE. > ISZ SKIPF$ /TAKE NORMAL EXIT. JMP I SKIPF$ SFWD, DCA SKPFCT /NO. OF FILES TO SKIP FWD. STA CLL RAR /MAX FWDS COUNT FOR SKIPR. SKIPR TAD RECORD /IF THERE WEREN'T ANY RECORDS IN THIS SNA CLA /FILE THEN WE'RE AT EOI. JMP I SKIPF$ STA /FORWARDS OVER THE EOF. MTDO; 60 IFREQ FILE < ISZ FILE /UPDATE FILE NO. > DCA RECORD /NEW FILE HAS RECORD NO. 0. ISZ SKPFCT JMP SFWD+1 /MORE TO DO. IAC /TRY SKIPPING A RECORD; IF WE HIT SKIPR /EOF THEN WE'RE AT EOI. JMP I SKIPF$ IFNDEF RANDOM.MTA < STA /IF WE'RE NOT USING RANDOM ACCESS READ, SKIPR /LEAVE HIM AT THE FIRST RECORD OF THE FILE. > SKPFCT, 0 JMP SFEND /NOT AT EOI: NORMAL EXIT. >
IFREQ READ < /READ A RECORD. SUBR READ$ READ$, 0 IFREQ RANDOM </RANDOM ACCESS READ. CMA /AC WAS RECORD (OF CURRENT FILE) TO BE READ. TAD RECORD IFREQ LOCK < SNA /IS THIS SAME RECORD WE READ LAST TIME? ISZ LOCK /YES: BUT MAKE SURE IT'S STILL THERE. SKP JMP RINCRE /IT'S IN CORE. > CMA /NO. OF RECORDS TO SKIP=RECORD REQUESTED-CURRENT RECORD. SKIPR JMP EOF /END OF FILE. ELSE CLA > TAD (-RETRY.MTA-1/-VE NO. OF RETRIES INCLUDING INITIAL READ. DCA RETRY? JMP .+4 REREAD, STA MTDO;70 /REREAD: BACK OVER THE RECORD. TAD WC /GET THE WORD COUNT AND MTDO;20 /READ THE RECORD. MTRS AND (100 SZA JMP REOF /END OF FILE. MTRS AND (206 /CHECK PARITY, DATA REQ LATE AND BAD TAPE. SNA CLA JMP RDONE /EVERYTHING OK. ISZ RETRY? /ONE OF THE ABOVE ERRORS, JMP REREAD /TRY AGAIN AS MUCH AS HE'LL LET US. IFDEF MTPRTY < IFREQ RECORD < ISZ RECORD > JMP MTPRTY /JUMP TO HIS PARITY ERROR LABEL. > IFREQ PARITY < IFREQ RECORD < ISZ RECORD > JMP PARXIT > RDONE, IFREQ RECORD < ISZ RECORD /KEEP TRACK OF WHERE WE ARE. > RINCRE, ISZ READ$ /NON EOF RETURN. IFREQ PARITY < ISZ READ$ PARXIT, > IFREQ LOCK < STA /IT'S A GOOD RECORD WE JUST READ: LCKEOF, DCA LOCK /LOCK IT INTO CORE. > JMP I READ$ REOF, STA /EOF: BACK UP OVER IT. MTDO; 70 EOF, IFREQ PARITY < ISZ READ$ > IFREQ LOCK < JMP LCKEOF /UNLOCK THINGS; EOF'S ARE NOT NICE. ELSE JMP I READ$ > RETRY?, 0 /RETRY COUNTER. >
IFREQ REWIND < /REWIND MAGTAPE UNIT. SUBR RWIND$ RWIND$, 0 MTDO;0 /NOP TO SET UNIT BITS, WAIT FOR TRANSPORT, TAD (10 /AND CLEAR AC. 6724 /INCLUSIVE OR COMMAND REG TO REWIND COMMAND OF 10. MTPC /KILL FLAGS (REWIND WON'T WORK OTHERWISE). MTLC MTGO /AND EXECUTE IT. CLA IFREQ FILE < DCA FILE > IFREQ RECORD < DCA RECORD > JMP I RWIND$ >
IFREQ WRITE < /WRITE A RECORD. SUBR WRITE$ WRITE$, 0 CLA IFREQ RECORD < ISZ RECORD /WE'RE GOING TO BE ONE MORE RECORD AHEAD. > TAD WC /GET THE WORD COUNT AND WRITE OUT THE MTDO; 40 /RECORD. WRITE1, MTRS AND (206 /CHECK PARITY, DATA REQ LATE AND BAD TAPE. SNA CLA JMP I WRITE$ /ALL OK. STA /NOT QUITE RIGHT: BACKSPACE OVER BAD RECORD. MTDO; 70 TAD WC /REWRITE RECORD, WITH A LONG (3 IN.) IRG FIRST. MTDO; 140 JMP WRITE1 >
IFREQ WEOI < SUBR WEOI$ WEOI$, 0 CLA TAD RECORD /ONLY NEED ONE EOF IF WE'RE AT EOI ALREADY. SNA CLA JMP ATEOF DCA RECORD /WE'RE AT FIRST RECORD OF THIS FILE. IFREQ FILE < ISZ FILE /BUMP FILE NO. AND THEN > JMS EOF$ /WRITE THE TWO FILE MARKS. ATEOF, JMS EOF$ STA MTDO;70 /BACK OVER THE LAST. JMP I WEOI$ EOF$, 0 MTDO; 50 MTRS AND (206 /CHECK PARITY, DATA REQ LATE SNA CLA /AND BAD TAPE. JMP I EOF$ /OK. STA /BACK UP & TRY AGAIN. MTDO; 70 /(EIRG ASSUMED FOR EOF). JMP EOF$+1 > END MTA > IFNZRO ALPHA3.SYS&2000 <LIST ON>
TITLE IO VERSION OF 30 JUN 74 IFNZRO ALPHA3.SYS&2000 < LIST OFF /Z OPTION: TURN LISTING OFF. > BEGIN IO BEGIN SUBR BEGIN UNIV/DEFINE THE EAE SYMBOLS IN UNIV. MUY=7405;DVI=7407;NMI=7411;SHL=7413;ASR=7415;SWP=7521 LSR=7417;MQL=7421;SCA=7441;SCL=7403;MQA=7501 SET PERM MUY DVI NMI SHL ASR SWP LSR MQL SCA SCL MQA: EAE MUY DVI NMI SHL ASR SWP LSR MQL SCA SCL MQA END IFDEF RESTART < REQUEST SUBR READC > IFNDEF READC.SUBR < REQUEST SUBR READC > IFNDEF PRINTC.SUBR < IFNDEF LPRINT.SUBR < REQUEST SUBR PRINTC > > IFREQ READC.SUBR < IFNDEF ECHOR.SUBR < REQUEST SUBR ECHOR > > IFNDEF CTRLC < CTRLC=7600 > IFNZRO CTRLC < REQUEST SUBR READC IFNZRO CTRLC-7600 < CTRLC=7605 > > IFREQ LPRINT.SUBR < IFREQ LPTION.SUBR < *1 /BRANCH TO LINE PRINTER INTERRUPT CHAIN. JMP I .+1;LPTINT.IO > > ORGZERO IFNEG .-20 < *20 /SKIP THE AUTO-INDEX REGISTERS. > IFREQ READC.SUBR < READC =JMS I . READC$.IO > IFREQ PRINTC.SUBR < PRINTC =JMS I . PRINT$.IO > IFREQ LPRINT.SUBR < IFREQ LPTION.SUBR < BEGIN IO FILL, 0 /FILL POINTER FOR LPT BUFFER EMPTY, 0 /EMPTY POINTER. END IO LPTIOF =JMS I . LPTOF$.IO > LPRINT =JMS I . PRTL$.IO IFREQ PRINTC.SUBR <ELSE PRINTC =LPRINT >> IFREQ READS.SUBR < READS =JMS I . READS$.IO > IFREQ READR.SUBR < READR =JMS I . READR$.IO > IFREQ PUNCHC.SUBR < PUNCHC =JMS I . PUNCH$.IO > IFDEF RESTART < INTCHK =JMS I . INTCH$.IO ELSE IFNZRO CTRLC < INTCHK =JMS I . INTCH$.IO ELSE INTCHK =CLA > > IFZERO CHAR-. < BEGIN UNIV CHAR, 0 END > IFNDEF CHAR < BEGIN UNIV CHAR, 0 END > END
IFREQ READS < /READ KEYBOARD STATIC. SUBR READS$ READS$, 0 IFREQ LPTION.SUBR < IOF > CLA KSF JMP I READS$ /RETURN 0 IF FLAG NOT UP; OTHERWISE THE CHARACTER. KRS ISZ READS$ JMP I READS$ > IFREQ READC.SUBR < /READ KEYBOARD TO AC WHEN READY. SUBR READC$ READC$, 0 IFREQ ECHOR < /COMPILE ECHO CODE. IFREQ READS < /IT'S ONE LOCATION SHORTER IF WE USE READS. READS JMP .-1 ELSE IFREQ LPTION.SUBR < IOF > CLA /BUT IT'S NOT ALL THAT BAD WITHOUT IT. KSF JMP .-1 KRS > PRINTC /EITHER WAY, THIS ECHOES IT. ELSE KSF /IF NO ECHO NEEDED, JUST WAIT FOR THE FLAG. JMP .-1 > IFNZRO INTCHK-CLA < /IF WE HAVE A KEYBOARD INTERRUPT CHECK ROUTINE, WE'RE IFREQ ECHOR <ELSE /THERE IS NO IFNREQ, BUT IT CAN BE FAKED. INTCHK > > KRB /FINALLY READ THE CHARACTER. DCA CHAR /SAVE IT IF HE WANTS. TAD CHAR JMP I READC$ >
IFREQ PRINTC.SUBR < /PRINT CHARACTER ON TTY, CLEAR AC. SUBR PRINT$ PRINT$, 0 IFREQ LPTION.SUBR < IOF > TLS TSF JMP .-1 INTCHK JMP I PRINT$ > IFREQ READR < /READ NEXT CHARACTER FROM HIGH SPEED READER. SUBR READR$ /USER HAS TO KICK IT INITIALLY WITH AN RFC. READR$, 0 IFREQ LPTION.SUBR < IOF > INTCHK DCA CHAR /SET TIME OUT COUNTER. RSF JMP TIMCHK /CHECK FOR TIME OUT IF FLAG NOT YET UP. RRB RFC /GOT ONE: READ IT AND MAKE READY FOR THE NEXT. DCA CHAR /SAVE IT IF HE WANTS. TAD CHAR ISZ READR$ /BUMP RETURN INDICATING SUCCESS AND EXIT. JMP I READR$ TIMCHK, ISZ CHAR /TIMED OUT? JMP READR$+3 /NOT YET. JMP I READR$ /HAS, TAKE FIRST RETURN. > /FOR TIMING OUT READER. IFREQ PUNCHC < /PUNCH A CHARACTER; USER MUST INITIALIZE WITH PLS. SUBR PUNCH$ PUNCH$, 0 IFREQ LPTION.SUBR < IOF > PSF JMP .-1 PLS INTCHK JMP I PUNCH$ >
IFREQ LPRINT.SUBR < LSF=6661;LCF=6662;LSP=6665;LLB=6666;MPCD=6644 IFREQ LPTION.SUBR < /LINE PRINTER ROUTINES, USE THE ENTIRE FIELD 3 AS BUFFER. /RUNS ON THE INTERRUPT, THEREFORE THE USER MUST TURN THE /INTERRUPT ON BEFORE USING THE LINE PRINTER. /line printer interrupt routines. IFNDEF LPTFLD <LPTFLD=30> BEGIN SUBR LPTION=LSP.IO END SUBR LPTFLG LPTFLG, -1 LPTOF$, 0 ION STA /set a flag DCA LPTFLG TAD FILL /wait for the buffer to empty CIA TAD EMPTY SZA CLA JMP .-4 /not yet. IOF JMP I LPTOF$ SUBR AC AC, 0 L, 0 OTHER, TCF /A NON-LINEPRINTER INTERRUPT HAS BEEN RECIEVED. IFNZRO CLA-INTCHK < INTCHK > KCC /LET IT PASS. DISMIS, TAD L RAL CLL /RETURN FROM INTERRUPT. TAD AC RMF ION JMP I 0 OUT, STA /set the flag DCA LPTFLG JMP DISMISS LPTINT, DCA AC /SAVE ALL SORTS OF THINGS. RAR DCA L LSF /DID THE LINE PRINTER DO IT? JMP OTHER /NO, T'WAS SOMETHING ELSE. CDF LPTFLD LCF /KILL THE FLAG. AGAIN, TAD FILL /IS THE BUFFER EMPTY? CIA /(IE. FILL=EMPTY?) TAD EMPTY SNA CLA JMP OUT /YES, LEAVE THE BEAST ALONE. TAD I EMPTY /PICK UP A CHARACTER SMA JMP .+4 CIA /IT'S A CONTROL CODE. MPCD SKP CLA LLB /bang it out CLA ISZ EMPTY /BUMP THE POINTER LSF /IS THE FLAG UP AGAIN? JMP DISMISS /THE ISZ MAY(PROBABLY WILL) SKIP JMP AGAIN /IT'S UP, TRY THAT AGAIN. SUBR CHAR' CHAR', 0 PRTL$, 0 ION /turn the interrupt on. DCA CHAR' TAD FILL /IS THE BUFFER FULL? CMA TAD EMPTY SNA CLA JMP .-4 /YES, WAIT FOR IT TO EMPTY. IOF ISZ LPTFLG /buffer empty? JMP .+12 /no, put the character into it. TAD CHAR' SPA /is it a control code? JMP .+4 /yes, do the right thing LLB /spit the character out. CLA JMP .+13 CIA /make the code proper. MPCD JMP .-4 /exeuent DCA LPTFLG /kill the flag CDF LPTFLD TAD CHAR' /STUFF THE CHAR INTO THE BUFFER. DCA I FILL CDF ISZ FILL NOP ION JMP I PRTL$ ELSE SUBR PRTL$ BEGIN SUBR FORGET LPTION,LPTIOF END PRTL$, 0 SMA /CONTROL CODE? JMP .+4 /NO. CIA /YES, MAKE IT PROPER MPCD /ZAP IT OUT SKP LLB / 'TIS NORMAL, SEND IT ON IT'S MERRY (?) WAY. INTCHK LSF JMP .-2 JMP I PRTL$ > >
IFNZRO INTCHK-CLA < /CHECK FOR INTERRUPT CHARACTER TYPED. IFNDEF INTKEY <INTKEY="H-100> SUBR INTCH$ INTCH$, 0 IFREQ READS.SUBR < READS /USE READS IF WE HAVE IT. JMP I INTCH$ /NOTHING, TYPED. ELSE CLA /IF WE DON'T HAVE READS, USE THIS (THE CLA KSF /IS NEEDED TO MAKE IT BEHAVE AS IF READS WAS USED). JMP I INTCH$ KRS > IFNZRO CTRLC < /CTRLC CODE NEEDED. IFDEF RESTART < /RESTART ALSO. TAD (-"C+100 SNA JMP CTRLC /CTRLC TYPED (BACK TO OS/8). TAD ("C-100-INTKEY SZA CLA JMP I INTCH$ KCC /KILL FLAG. IFDEF MTA.BLOCKS < STA DCA 7752 > /KILL MAGTAPE WORD COUNT TO STOP IT. JMP I (RESTART /GO TO USER RESTART ADDRESS. ELSE TAD (-"C+100 /TEST FOR CTRL/C ONLY. SNA CLA JMP CTRLC JMP I INTCH$ > ELSE IFDEF RESTART < TAD (-"INTKEY /TEST FOR USER INTERRUPT KEY ONLY. SZA CLA JMP I INTCH$ KCC /KILL FLAG. IFDEF MTA.BLOCKS < STA DCA 7752 > /KILL MAGTAPE WORD COUNT TO STOP IT. JMP I (RESTART /GO TO USER RESTART ADDRESS. > > > END IO



Feel free to contact me, David Gesswein djg@pdp8online.com with any questions, comments on the web site, or if you have related equipment, documentation, software etc. you are willing to part with.  I am interested in anything PDP-8 related, computers, peripherals used with them, DEC or third party, or documentation. 

PDP-8 Home Page   PDP-8 Site Map   PDP-8 Site Search