.SBTTL RP04 CONSOLE SELECTION, 5-AUG-75 $RP: TTISDO ;GET RP04 SELECTION DIGIT CMP R0,#7 ;MUST BE 0 TO 7 BLE 1$ JMP $CMDE 1$: MOV R0,RPUNIT ;SAVE MOV #1,DEVTYP ;SET RP04 MODE RPLOAD ;INIT & LOAD PACK BCS $RPERR 2$: JMP $KONSL .SBTTL RP04 FILE DIRECTORY LOOKUP RPFIL: RPFILE BCS 1$ JMP DTRPLD 1$: JMP $NONXF $RPFILE:CLR RPEOF ;CLEAR END-OF-FILE ASCR50 ;CONVERT FILE.EXT TO RAD50 NAMBF NAMRAD BCC 1$ $PMSG ;NAME.EXT ERR $$NAM BR $RPERX 1$: MOV #NAMRAD,R0 MOV #FILDSB,R1 RPLKUP ;LOOK UP FILE IN DIRECTORY BCC 3$ CMP #-24,R0 BNE $RPERR EXITERR 3$: EXIT ;RP04 ERROR REPORTER $RPERR: PUSH R0 PMSG POP R0 NEG R0 MOV R0,R1 PNTOCS ;PRINT ERROR STATUS WORD PNTCI ", DEC R1 SL R1,1 MOV RPERTB(R1),R0 PNTAL ;PRINT ERROR REASON $RPERX: JMP $CNTLC RPERTB: RPER1 RPER2 RPER3 RPER4 RPER5 RPER6 RPER7 RPER10 RPER11 RPER12 RPER13 RPER14 RPER15 RPER16 RPER17 RPER20 RPER21 RPER22 RPER23 RPER24 RPER25 ;RP04 ERROR MESSAGES RPER1: .ASCIZ %UNIT #% RPER2: .ASCIZ %UNAVAIL% RPER4: RPER5: RPER3: .ASCIZ %DRV INIT% RPER6: .ASCIZ %HOME BLK RD% RPER7: .ASCIZ %NO HOME BLK% RPER10: .ASCIZ %FILE SYS NAME% RPER11: .ASCIZ %NO INDEX% RPER12: .ASCIZ %NO DIR FILE% RPER13: .ASCIZ %PAST EOF% RPER20: RPER14: .ASCIZ %POS% RPER15: .ASCIZ %READ ERR% RPER16: .ASCIZ %ALLOC CNG% RPER17: .ASCIZ %BUFSIZ% RPER21: .ASCIZ %INSUFF ALLOC% RPER22: .ASCIZ %DIR REWRT% RPER23: .ASCIZ %DATA WRT% RPER24: .ASCIZ %EOF% RPER25: .ASCIZ %RAD50% .EVEN .SBTTL RP04 FILE RENAME ;COMMAND IS: ; RENM:FILE.EXT FILE1.EXT $RE: TTICHR CMPB #'N,R0 BNE 1$ TTICHR CMPB #'M,R0 BEQ 2$ 1$: JMP $CMDER 2$: TTITRM NAMEXT ;SETUP CURRENT FILE NAME.EXT RPFILE ;FIND AND SETUP FILE BCC 4$ JMP $NONXF 4$: NAMEXT ;SETUP NEW FILE NAME.EXT ASCR50 ;CONVERT NEW FILE.EXT TO RAD50 NAMBF NAMRAD BCS 1$ ;NAME.EXT ERROR MOV #WRTBAK,R5 ;POINTER TO WRITE-BACK INFO TO R5 MOV (R5)+,R4 ;GET CORE ADDRESS OF FILE DESCRIPTOR MOV #NAMRAD,R3 MOV (R3)+,(R4)+ ;TRANSFER NEW RAD50 FILE NAME.EXT MOV (R3)+,(R4)+ ;TO CURRENT FILE DESCRIPTOR BLOCK MOV (R3),(R4) MOV (R5)+,CYLNDR MOV (R5)+,TRKSCT RPWRIT ;REWRITE DIRECTORY BLOCK BCC 3$ MOV #-22,R0 RPERROR 3$: JMP $CONSL .SBTTL ASCR50 ASCII TO RAD50 CONVERSION ROUTINE ;CALL: ; ASCR50 ; ASCII ADDRESS ; RAD50 ADDRESS ;NINE BYTES OF ASCII INPUT ;THREE WORDS OF RAD50 OUTPUT $ASCR50:ADD #4,12(SP) ;RETURN OVER TRAILING PARAMETERS PUSH R0 MOV $EMADR,R5 MOV (R5)+,R1 ;SETUP ASCII ADDRESS MOV (R5),R4 ;SETUP RAD50 STORAGE ADDRESS MOV #066600,R3 1$: CLR (R4) ;RESULT WORD 2$: MOV #30$,R0 ;SETUP SCAN TABLE 3$: MOVB (R0)+,R2 ;PUT CONVERSION IN R2 BEQ 20$ ;IF END OF TABLE, ERROR CMPB (R1),(R0)+ ;COMPARE ASCII CHAR BLO 20$ ;IF LESS THAN TABLE ENTRY, ERROR CMPB (R1),(R0)+ BHI 3$ ;LOOP, HAVEN'T FOUND YET MOVB (R1)+,R0 ;FOUND, ASCII CHAR TO R0 ADD R2,R0 ;CONVERT ASL (R4) ASL (R4) ASL (R4) ADD (R4),R0 ASL (R4) ASL (R4) ADD R0,(R4) ASL R3 ;SHIFT RAD50 WORD COUNTER BMI 2$ ;NOT DONE WITH THIS RAD50 YET BEQ 10$ ;IF 0, ALL DONE TST (R4)+ ;STEP TO NEXT RAD50 WORD BR 1$ ;GO DO NEXT 10$: POP R0 EXIT 20$: POP R0 EXITERR 30$: .BYTE -40,' ,' ;SPACE .BYTE -11,'$,'$ ;DOLLAR SIGN .BYTE -22,'.,'. ;PERIOD .BYTE -22,'0,'9 ;DIGITS .BYTE -100,'A,'Z ;UPPER CASE LETTERS .ENABL LC .BYTE -140,'a,'z ;LOWER CASE LETTERS .BYTE 0 ;INDICATE THE END OF THE TABLE .EVEN .SBTTL RPLOAD RP04 LOAD PACK (READ HOME BLOCK) ROUTINE $RPLOAD:RPINIT ;INITIALIZE RP04 BCS 10$ MOV #-6,R5 CLR CYLNDR MOV #1,TRKSCT MOV #DVBUF,BUFADR MOV #BLKSIZ,BUFSIZ MOV #-BLKSIZ,WRDCNT RPREAD ;READ HOME BLOCK BCS 9$ ;-6 ERROR DEC R5 ;SAVE INFORMATION ABOUT THE INDEX FILE & FILE DIRECTORY MOV #DVBUF+<^D105*2>,R1 MOV #RPIXCY,R2 1$: MOV (R1)+,(R2)+ CMP R1,#DVBUF+<^D111*2> BLO 1$ ;CHECK THAT THIS IS REALLY THE HOME BLOCK CMP DVBUF,#105755 ;LAST 16 BITS OF "HOM" IN SIXBIT BNE 9$ ;-7, BRANCH IF NOT HOM BLOCK DEC R5 ;CHECK THAT THIS PACK CONTAINS OUR FILE SYSTEM (KLFEDDCS) MOV #DVBUF+<^D98*2>,R1 MOV #FSNAME,R2 2$: CMP (R1)+,(R2)+ BNE 9$ ;-10, BRANCH IF FILE SYSTEM NAME IS INCORRECT CMP R1,#DVBUF+<^D104*2> BLO 2$ DEC R5 TST RPIXCY ;DOES INDEX FILE EXIST? BLE 9$ ;-11, BRANCH IF INDEX FILE DOES NOT EXIST DEC R5 TST RPFDCY ;DOES FILE DIRECTORY EXIST? BLE 9$ ;-12, BRANCH IF FILE DIRECTORY DOES NOT EXIST EXIT ;INDICATE SUCCESS 9$: MOV R5,R0 ;PUT ERROR CODE IN R0 10$: SETFLG ;INDICATE FAILURE RPUNIT 11$: EXITERR FSNAME: .ASCII /KLFEDDCS / ;FILE SYSTEM NAME .SBTTL RPFIND FIND FILE IN RP04 DIRECTORY ;R0 = POINTER TO FILE NAME IN RAD50 ;R1 = POINTER TO RETURN STORE BLOCK ; CORE ADR OF FILE DESCRIPTOR BLOCK ; CYLINDER NUMBER ; TRACK/SECTOR NUMBER $RPFIND:MOV R0,R4 ;SAVE FILE NAME POINTER MOV R1,R5 ;SAVE RETURN POINTER MOV #DVBUF,BUFADR MOV #-BLKSIZ,WRDCNT MOV #BLKSIZ,BUFSIZ MOV #FILDSB,R3 ;SETUP FILE DESCRIPTOR POINTER MOV #RPFDCY,R2 ;SETUP DIRECTORY START MOV (R2)+,4*2(R3) MOV (R2)+,5*2(R3) MOV (R2),R0 ;CHANGE DIR BLOCK COUNT TO SHIFTL ;WORD COUNT 8. MOV R0,9.*2(R3) CLR 8.*2(R3) MOV R3,R2 ADD #FDESIZ*2,R2 CLR (R2)+ ;CLEAR CURRENT POSITION CLR (R2) 1$: MOV R3,R0 RPRDFL ;READ DIRECTORY DATA BLOCK BCS 4$ ;ERROR MOV (R0)+,R2 ;DATA BUFFER POSITION MOV (R0),R1 ;BYTE COUNT 2$: CMP (R2),(R4) ;COMPARE DIRECTORY ENTRY BNE 3$ ;AND REQUESTED FILE CMP 1*2(R2),1*2(R4) BNE 3$ CMP 2*2(R2),2*2(R4) BNE 3$ ;NOT THIS ENTRY MOV R2,(R5)+ ;RETURN CORE ADDRESS OF DESCRIPTOR BLOCK MOV CYLNDR,(R5)+ ;RETURN CYLINDER NUMBER MOV TRKSCT,(R5)+ ;RETURN TRACK/SECTOR NUMBERS EXIT ;"SUCCESS" RETURN 3$: ADD #FDESIZ*2,R2 ;FINISHED THIS DIRECTORY BLOCK ? SUB #FDESIZ*2,R1 BHI 2$ ;NO BR 1$ ;YES, GO READ NEXT 4$: CMP #1,R0 ;EOF ? BNE 5$ ;NO, RETURN ERROR CODE MOV #-24,R0 ;YES, RETURN EOF CODE 5$: EXITERR .SBTTL RPLKUP RP04 FILE DIRECTORY LOOKUP ROUTINE ;R0/ POINTER TO FILENAME IN RAD50 ;R1/ STORE ADDRESS FOR FILE DESCRIPTOR ;FILE DESCRIPTOR BLOCK ; 0/ FILENAME ; 1/ " ; 2/ FILE EXT ; 3/ CREATION DATE ; 4/ PHYSICAL BLOCK NUMBER ; 5/ " ; 6/ NUMBER OF WORDS ALLOCATED ; 7/ " ; 8/ NUMBER OF WORDS WRITTEN ; 9/ " ; 10/ PDP-11 LOAD ADDRESS ; 11/ PDP-11 START ADDRESS ; 12/ FILE TYPE & FILE STATUS ; 13/ CHECKSUM ; 14/ 0 ; 15/ 0 ; 16/ CURRENT POSITION ; 17/ " $RPLKUP:MOV R1,R5 ;SAVE FILE DESCRIPTOR POINTER MOV #WRTBAK,R1 RPFIND ;FIND FILE BCS 2$ ;NOT THERE MOV #FDESIZ,R2 ;TRANSFER FILE INFO MOV (R1),R1 1$: MOV (R1)+,(R5)+ ;TO FILE DESCRIPTOR BLOCK DEC R2 BNE 1$ CLR (R5)+ ;SET CURRENT POSITION AT ZERO CLR (R5)+ EXIT 2$: EXITERR .SBTTL RPRDFL READ A FILE (ON THE RP04) ;R0 = POINTER TO FILE DESCRIPTOR $RPRDFL:MOV R0,R2 ;SETUP FILE DESCRIPTOR POINTER MOV R2,R4 ADD #^D16*2,R4 ;R4 POINTS TO CURRENT POSITION BLOCK MOV BUFSIZ,R3 ;BUFFER SIZE TO R3 MOV ^D8*2(R2),R0 ;R0 = M.S. NUMBER OF WORDS WRITTEN MOV ^D9*2(R2),R1 ;R1 = L.S. NUMBER OF WORDS WRITTEN SUB 2(R4),R1 ;R1 = L.S. NUMBER OF WORDS REMAINING SBC R0 ;PROPAGATE THE "BORROW" SUB (R4),R0 ;R0 = M.S. NUMBER OF WORDS REMAINING BLT 40$ ;BRANCH IF PAST EOF (ERROR) BGT 10$ ;BRANCH IF MORE THAN 2**16 WORDS REMAIN TST R1 ;NOW LOOK AT L.S. # OF WORDS REMAINING BEQ 60$ ;BRANCH IF AT EOF CMP R1,R3 ;COMPARE REMAINING WORDS WITH "BUFSIZ" BHI 10$ ;BRANCH IF REMAINING WORDS IS LARGER MOV R1,R3 ;REMAINING WORDS IS SMALLER (OR EQUAL) BR 15$ ;AVIOD TRUNCATING THE BUFFER SIZE 10$: BIC #BLKSIZ-1,R3 ;TRUNCATE TO A MULTIPLE OF THE BLOCK SIZE 15$: BIT #BLKSIZ-1,2(R4) ;IS CURRENT POSITION A MULTIPLE OF BLOCK SIZE? BNE 50$ ;BRANCH IF NOT A MULTIPLE OF BLOCK SIZE MOV 4*2(R2),CYLNDR ;CYLINDER NUMBER OF START OF FILE MOV 5*2(R2),TRKSCT ;TRACK,SECTOR OF START OF FILE MOV (R4),R2 ;R2 = M.S. CURRENT POSITION SWAB R2 BISB 3(R4),R2 MOV R2,OFFSET RPADDR ;COMPUTE BLOCK # TO BE READ NEG R3 MOV R3,WRDCNT ;SETUP WORD COUNT NEG R3 RPREAD ;READ FILE DATA BLOCK BCS 70$ ;READ ERROR ADD R3,2(R4) ;UPDATE L.S. CURRENT POSITION ADC (R4) ;PROPAGATE CARRY INTO M.S. CURRENT POSITION ASL R3 ;CONVERT WORDS READ TO BYTES 75$: MOV R3,$RPINFO+2 ;AND STORE AS BYTE COUNT ARGUMENT MOV BUFADR,$RPINFO ;STORE BUFFER ADDRESS MOV #$RPINFO,R0 EXIT 40$: MOV #-13,R0 ;WE SEEM TO BE PAST THE EOF BR 30$ 50$: MOV #-14,R0 ;WE WERE POSITIONED AT A NON-MULTIPLE OF BLKSIZ BR 30$ 60$: MOV #1,R0 ;WE WERE ALREADY AT EOF BR 30$ 70$: MOV #-15,R0 ;INDICATE THAT NO DATA WAS READ 30$: EXITERR .SBTTL RPWRFL WRITE A FILE (ON THE RP04) ;R0 = POINTER TO FILE DESCRIPTOR ;BUFADR = ADDRESS OF BUFFER ;BUFSIZ = NUMBER OF WORDS TO BE WRITTEN ;RPEOF = BIT15=0, DON'T WRITE EOF; BIT15=1, WRITE EOF $RPWRFL:MOV R0,R2 MOV ^D16*2(R2),R0 ;R0 = M.S. CURRENT POSITION MOV ^D17*2(R2),R1 ;R1 = L.S. CURRENT POSITION MOV BUFSIZ,R3 BEQ 70$ ;BRANCH IF THE WORD COUNT IS ZERO TST RPEOF ;WRITING AN EOF ? BMI 1$ ;YES BIT #BLKSIZ-1,R3 ;IS BUFSIZ A MULTIPLE OF BLKSIZ? BNE RPWER1 ;BRANCH IF IT IS NOT A MULTIPLE 1$: BIT #BLKSIZ-1,R1 ;IS THE CURRENT POSITION A MULTIPLE? BNE RPWER2 ;BRANCH IF IT IS NOT A MULTIPLE MOV R0,R4 ;R4 = M.S. CURRENT POSITION ADD R3,R1 ;R1 = L.S. NEW POSITION ADC R0 ;R0 = M.S. NEW POSITION CMP ^D6*2(R2),R0 ;COMPARE WITH WORDS ALLOCATED BGT 5$ ;BRANCH IF MORE WORDS ALLOCATED BLT RPWER3 ;BRANCH IF NOT ENOUGH WORDS ALLOCATED CMP ^D7*2(R2),R1 ;ITS CLOSE, LOOK FURTHER BLO RPWER3 ;BRANCH IF NOT ENOUGH WORDS ALLOCATED 5$: SWAB R4 BISB <^D17*2>+1(R2),R4 MOV R4,OFFSET MOV ^D4*2(R2),CYLNDR ;CYLINDER NUMBER MOV ^D5*2(R2),TRKSCT ;TRACK/SECTOR NUMBERS RPADDR NEG R3 MOV R3,WRDCNT NEG R3 RPWRIT ;WRITE DATA BLOCK BCS RPWER5 ADD R3,^D17*2(R2) ;COMPUTE NEW CURRENT POSITION ADC ^D16*2(R2) ;PROPAGATE CARRY MOV ^D17*2(R2),^D9*2(R2) ;SET EOF AT CURRENT POSITION MOV ^D16*2(R2),^D8*2(R2) ;(M.S. ALSO) 70$: TST RPEOF ;ARE WE WRITING AN EOF BPL RPWEX ;NO MOV R2,R0 MOV #WRTBAK,R1 MOV #DVBUF,BUFADR MOV #-BLKSIZ,WRDCNT MOV #BLKSIZ,BUFSIZ MOV 2(R1),CYLNDR ;SETUP SAME DIRECTORY BLOCK MOV 4(R1),TRKSCT RPREAD ;READ CURRENT FILE DIRECTORY BLOCK BCS RPWER4 MOV (R1)+,R3 CMP ^D6*2(R2),^D6*2(R3) BNE RPWER0 ;BRANCH IF ALLOCATION IS DIFFERENT CMP ^D7*2(R2),^D7*2(R3) BNE RPWER0 ;BRANCH IF ALLOCATION IS DIFFERENT MOV #FDESIZ,R4 71$: MOV (R2)+,(R3)+ DEC R4 BNE 71$ MOV (R1)+,CYLNDR MOV (R1)+,TRKSCT RPWRIT ;REWRITE DIRECTORY BCS RPWER4 RPWEX: EXIT ;SUCCESSFUL COMPLETION WITH NO EOF RPWER0: MOV #-16,R0 ;ATTEMPT TO CHANGE FILE'S ALLOCATION BR RPWERX RPWER1: MOV #-17,R0 ;BUFSIZ IS NOT A MULTIPLE OF BLOCK SIZE BR RPWERX RPWER2: MOV #-20,R0 ;CURRENT POS. IS NOT A MULTIPLE OF BLOCK SIZE BR RPWERX RPWER3: MOV #-21,R0 ;INSUFFICIENT ALLOCATION TO COMPLETE THIS WRITE BR RPWERX RPWER4: MOV #-22,R0 ;DIRECTORY REWRITE FAILURE BR RPWERX RPWER5: MOV #-23,R0 ;DATA BLOCK WRITE FAILURE RPWERX: EXITERR .SBTTL RPINIT STORES UNIT NUMBER & TRIES TO SET VOLUME VALID $RPINIT:MOV #-1,R0 MOV RPUNIT,R2 ;CHECK RP04 UNIT # BIT #^C7,R2 BNE 2$ ;-1 ERROR, BAD DEC R0 MOV RPRH11,R1 MOV #RPCLR,RPCS2(R1) ;CLEAR RP04 MOV R2,RPCS2(R1) ;SELECT BIT #RPDVA,(R1) ;IS DRIVE AVAILABLE ? BEQ 2$ ;-2 ERROR, NO DEC R0 MOV RPDS(R1),R2 ;READ STATUS COM R2 BIC #^C,R2 BNE 2$ ;-3 ERROR, DRIVE ERROR DEC R0 MOV #RPPRST,(R1) ;SET READ-IN PRESET 1$: TSTB (R1) ;WAIT FOR CONTROLLER READY BPL 1$ BIT #,(R1) BNE 2$ ;-4 ERROR, DRIVE ERROR DEC R0 BIT #,RPDS(R1) BNE 2$ ;-5 ERROR, DRIVE ERROR 3$: EXIT 2$: BIS #100000,RPUNIT ;ERROR, FORCE RESELECT EXITERR .SBTTL RPBASE RETURN RP04 PARAMETER BLOCK BASE ADDRESS $RPBASE:MOV #FILDSB,R0 EXIT .SBTTL RPREAD & RPWRIT, RP04 READ & WRITE I/O ROUTINES $RPWRIT:MOV #RPWTFN,R5 ;SETUP WRITE FUNCTION CLR R4 BR RPFUNC $RPREAD:MOV #RPRDFN,R5 ;SETUP READ FUNCTION MOV #10.,R4 ;10 RETRIES RPFUNC: JSR PC,$PTTYC TST RPUNIT ;VALID UNIT ? BMI 2$ ;NO MOV RPRH11,R1 5$: MOV RPUNIT,RPCS2(R1) ;SELECT DRIVE BIT #RPDVA,(R1) ;IS DRIVE AVAILABLE ? BEQ 2$ ;NO MOV RPDS(R1),R2 ;CHECK DRIVE STATUS COM R2 BIC #^C,R2 BNE 2$ ;ERROR MOV CYLNDR,RPDC(R1) ;START DRIVE OPERATION MOV TRKSCT,RPDA(R1) MOV BUFADR,RPBA(R1) MOV WRDCNT,RPWC(R1) MOV R5,(R1) 1$: BIT #,(R1) BEQ 1$ ;WAIT FOR COMPLETION OR ERROR BIT #,(R1) BNE 2$ ;ERROR BIT #,RPCS2(R1) BNE 4$ ;ERROR 3$: EXIT ;COMPLETED 2$: EXITERR 4$: DEC R4 ;RETRY READ ERRORS, 10 TIMES BLE 2$ ;HARD ERROR MOV #RPCLR,RPCS2(R1) ;CLEAR RP04 BR 5$ ;TRY AGAIN .SBTTL RPADDR ADDS OFFSET TO AN RP04 PHYSICAL ADDRESS $RPADDR:MOV CYLNDR,R0 ;SETUP INITIAL VALUES MOV TRKSCT,R1 MOV OFFSET,R2 MOVB R1,R3 ;COMPUTE NEW POSITION CLRB R1 SWAB R1 ADD R3,R2 1$: BPL 2$ DEC R0 ADD #^D19*^D20,R2 BR 1$ 2$: SUB #^D19*^D20,R2 BLT 3$ INC R0 BR 2$ 3$: ADD #^D19*^D20,R2 4$: SUB #^D20,R2 BLT 5$ INC R1 BR 4$ 5$: ADD #^D20,R2 6$: SUB #^D19,R1 BLT 7$ INC R0 BR 6$ 7$: ADD #^D19,R1 SWAB R1 BISB R2,R1 MOV R0,CYLNDR ;RETURN NEW POSITION MOV R1,TRKSCT EXIT