; OPERATING INSTRUCTIONS, DSKFIX ; ; DSKFIX IS AN RSX-11D PROGRAM TO PATCH THE SYSTEM DISK ; (OR WHATEVER IS ON LUN 2) BY ABSOLUTE (LOGICAL) BLOCK NUMBER. ; THE TASK MUST EITHER BE BUILT PRIVILEGED, OR THE DISK ; MOUNTED DCF OR FOREIGN TO PERMIT THIS. CONSOLE INPUT WILL BE ; VIA GET MCR COMMAND LINE. THE X COMMAND WILL NOT BE VERY USEFUL ; ON RSX DISKS, BUT IS RETAINED IN CASE THIS IS USED TO ; PATCH DOS DISKS FROM RSX. ; ;TASK BUILD THIS WITH SYSLIB, SINCE ITS CONVERSION ROUTINES WILL ;BE USED FOR CONVERSION BETWEEN ASCII AND RAD50 AND OCTAL AND BINARY. ;?? ; NOTE THAT IT IS NOT POSSIBLE TO PATCH A SINGLE BYTE-- ; ONE MUST PATCH AN ENTIRE WORD AT A TIME. ; .MCALL EXIT$S,CSI$,FSRSZ$,QIO$S,QIOW$S,FDAT$A,FDBDF$ .MCALL NMBLK$,FINIT$,FSRSZ$ FSRSZ$ 3 ;UP TO 3 FILES OPEN AT ONCE .MCALL RCML$ ;RESET COMMAND LINE FACILITY ; ;ASSIGN DISK DESIRED TO LUN 2. ; LUN 1=TI: FOR GCML ; LUN 3=??? ;TASK BUILD (NON-PRIVILEGED VERSION): ; ;PAT/-FP=DSKFIX ;/ ;TASK=...PAT ;;TASK NAME SET FOR CALLING IT "PAT" FROM MCR ;LIBR=SYSRES:RO ;ASG=TI:1:3 ;;1 FOR COMMANDS, 3 FOR OUTPUT ;ASG=SY:2 ;;ASSIGN FOR DSK TO PATCH HERE ;UNITS=3 ;STACK=200 ;PRI=45 ;// ; ; ;FOR PRIVILEGED TASK BUILD (NOT NEEDING SY: MOUNTED DCF) ;JUST ADD /PR SWITCH TO OUTPUT NAME. ; ; ; IN RESPONSE TO ENTER DISK BLOCK # TYPE BLOCK NUMBER IN OCTAL ; OR "E" TO EXIT TO RSX. THE BLOCK WILL BE READ IN AND CAN BE ; DISPLAYED BY THE "L" COMMAND. DISPLAY IS ON DEVICE KB:. ; IN RESPONSE TO "*" TYPE ; ; L TO LIST REFERENCED BLOCK ; S TO SWAP BYTES IN BLOCK ; W TO WRITE THE CURRENTLY REFERENCED BLOCK BACK ONTO DISK ; N TO READ THE NEXT BLOCK ; R TO REREAD THE CURRENT BLOCK (WIPING OUT ALL CHANGES IN THE CURRENT ; BUFFER) ; B TO READ THE PREVIOUS BLOCK ; F FOR FULL-WORD ADDRESSES ; H FOR HALF-WORD (BYTE) ADDRESSES IN BLOCK ; T TO TYPE OUT THE BLOCK AS ASCII TEXT ; X TO READ THE BLOCK REFERENCED IN THE LINK-WORD OF ; THE CURRENT BLOCK ; E TO EXIT TO THE MONITOR ; ; M/000000 WHERE M=THE RELATIVE WORD TO CHANGE IN THE CURRENT ; BLOCK ; M,LLL THE COUNT IS OCTAL BEGINNING WITH 0 ; M;AA ; LLL=THE NEW CONTENTS TO BE PACKED RAD50 BEFORE ; SUBSTITUTION ; AA=NEW CONTENTS TAKEN AS 2 ASCII CHARACTERS ; M: TO DISPLAY THE CONTENTS OF RELATIVE WORD M IN OCTAL, ; RAD50, AND ASCII. THE COUNT IS OCTAL STARTING AT 0. ; THE COUNT MUST BE WITHIN THE LEGAL BLOCK SIZE OF ; THE DISK BEING PATCHED. ; ; D,N TO CHANGE DEFAULT BLOCK NUMBER FOR READ AND WRITE TO N ; WITHOUT CHANGING THE CONTENTS OF THE BUFFER IN CORE. THIS SHOULD ; PERMIT MOVING DATA FROM ONE BLOCK TO ANOTHER. ; A,N TO READ AND LIST BLOCK N (N ABSENT IMPLIES NEXT BLOCK ; C,N TO READ AND LIST ALL BLOCKS UP TO AND INCLUDING BLOCK N. ; (N ABSENT IMPLIES TO END OF DISK.) ; P,N CHANGES THE HIGH-ORDER BLOCK NUMBER FROM THE DISK. ; NO I/O WILL BE DONE, BUT THE BLOCK NUMBER WILL BE COPIED ; FROM THE HIGH-ORDER AND LOW-ORDER BLOCKS TO RELATIVE ; WORDS 400 AND 401 (BYTES 1000 AND 1002) JUST PAST THE I/O BUFFER ; WHERE THE SINGLE-WORD EXAMINING COMMANDS CAN SEE THEM. ; .TITLE DKPEEK .GLOBL DKPEEK .IDENT /V6A.GE/;7/27/76 G. EVERHART ; MODIFIED BY G. EVERHART TO ALSO RUN UNDER RSX11M (V3.1) ;DEFINE "R$$11D" FOR RSX11D VERSION, LEAVE UNDEFINED FOR RSX11M. VERS="06 CR=15 LF=12 HASH='# DWDC=256. MAXBLK=48300. STR: .ASCII $/,;:CADPWLNERBX$ .ASCII /T/ ;TYPE BUFFER .ASCII /FHS/ ;FULL OR HALFWORD ADDRESSES IN NUMBERING ; OR SWAP BYTES ; ;D,NNNNNN WILL RESET BLOCK NUMBER BUT NOT ;ALTER DATA IN CORE. THIS WILL PERMIT MOVING ;BLOCKS TO OTHER PARTS OF THE DISK. ;P WILL SET THE HIGH-ORDER BLOCK NUMBER ; ;WHEN A P,NNNNNN COMMAND IS GIVEN. .BYTE 0 ;END SENTINEL .EVEN BYTFLG: .WORD 0 ;DEFAULT TO FULL-WORD ADDR CONT: 0 MODIF: 0 NOPRT: 0 0 ; DLB: .BYTE 3,12. ;QIOW$ DFCT: .WORD IO.RLB ;INITIALLY A READ .WORD 2 ;LUN 2 .BYTE 3,00 ;FLAG 3, PRI 0 (RSX11M COMPATIBLE) .WORD DT.STT ;STATUS RETURN (2-WORD BLK) .WORD 0 ;NO AST .WORD INBUF ;DATA AREA ADDRESS .WORD DWDC+DWDC ;SIZE IN BYTES .WORD 0 ;NEEDED FOR RSX SOMEHOW .WORD 0 ;HIGH ORDER BLK #--NOT USED HERE DBLKN: .WORD 01000 ;BLK # (LOW ORDER ACTUALLY.) .WORD 0 .WORD 0 .WORD 0 DT.STT: .BLKW 2 ;STATUS RETURN AREA ; ;NOW TRANSFER BLOCK FOR TI: ON LUN 3 FOR TYPE-OUTS OF TEXT ;(USE GCML$ ON INPUT, BUT NEED THIS FOR DISPLAY) TILB: .BYTE 3,12. .WORD IO.WLB .WORD 3 ;LUN 3, WRITE .WORD 9. ;EFN 9 .WORD TT.STT ;STATUS BLK .WORD 0 ;NO AST TIBUF: .WORD 0 ;BUFFER ADDRESS TIWC: .WORD 0 ;LENGTH IN BYTES .WORD 0 .WORD 0 .WORD 0,0,0,0,0 ;RSX11M PADDING... .MCALL FCSBT$ FCSBT$;FCS BIT NAMES .WORD 5015 ;CRLF FOR THE T COMMAND INBUF: .=.+DWDC+DWDC HBCPY: .WORD 0 ;HIGH/ORDER BLOCK # LBCPY: .WORD 0 ;LOW/ORDER BLOCK # 0 0 CSI$ CSBLK: .BLKB C.SIZE .EVEN TT.STT: .MCALL GCMLB$,GCML$ TI.STT: .BLKW 2 CMD: GCMLB$ 2,DKP,,1 ;LUN 1 COMMAND BLK FOR INPUT CONTROL .MCALL GCMLD$ GCMLD$ GETNUM: .ASCII <15><12>/DSKPAT V06--WHAT IS INITIAL OCTAL BLK NO? >/ GETNUL=.-GETNUM .EVEN KBLH: 80.,0,0 .=.+80. CMOBUF: .WORD 0,4,0 CORADR: .WORD 0 ;CORE ADDR DUMP MODE DUMMY BUFHDR .IF NDF,R$$11D ;RSX11M VERSION -- USE GET TASK INFO DIRECTIVE TO SEE WHO IS RUNNING ;THE TASK. THIS DOES NOT CHECK ANY PRIVILEGE BITS -- ONLY THE ACCOUNT. TSKINF: .BLKW 17. .WORD 0,0;SPARE FENCE .MCALL GTSK$S .ENDC DKPEEK: ;THIS TASK IS DANGEROUS!! ;ONLY ALLOW IT TO BE RUN BY PEOPLE WHO ARE ;PRIVILEGED LOGGED INTO PRIVILEGED ACCOUNTS! .IF DF,R$$11D ;RSX11D/IAS ONLY! .IFF ;RSX11M GTSK$S #TSKINF ;RSX11M - GET TASK INFO FOR UIC .IFT ;RSX11D/IAS PRIVILEGE CHECKING. REQUIRES PRIV. BIT AND LOGIN IN ;PRIV. ACCOUNT. MOV .CRTSK,R0 ;GET OUR ATL ADDR MOV A.TI(R0),R0 ;THEN GET OUR PUD ADDR MOVB U.PR(R0),R2 ;GET LOGIN, PRIV BITS BITB #UT.LG,R2 ;WAS USER LOGGED IN? BEQ 101$ ;NO, EXIT NOW WHILE WE CAN BITB #UT.PR,R2 ;IS HE PRIVILEGED THOUGH? BEQ 101$ ;NO, NEVER CAN EXECUTE CMPB #10,U.GC(R0) ;IS HIS GROUP 10 OR LESS? .IFF ;RSX11M PRIVILEGE CHECK IS ONLY ON LOGIN ACCOUNT. CMPB #10,TSKINF+35. ;TEST GROUP CODE FOR 10 OR LESS .ENDC BHIS 100$ ;YES, HE MAY EXECUTE .MCALL EXIT$S ;NOTE THAT AN UNAUTHORIZED USER NEVER EVEN SEES THE PROMPT; DKP ;EXITS QUIETLY AND DOES NOTHING. 101$: EXIT$S ;NO, SCRAM BEFORE HE SCREWS US UP. 100$: FINIT$ ;INIT FCS REGION GCML$ #CMD,#GETNUM,#GETNUL ;ASK HIM FOR BLK NUMBER BCC SETMOR SCRAM: EXIT$S ;EXIT ON A CTL-Z SETMOR: MOV #DWDC,R0 MOV R0,DWCL2+2 ;STASH IN LITERALS ASL R0 ;GET BYTE COUNT MOV R0,DATSIZ ;PREPARE TYPEOUT SIZE MOV #CONT,R0 CLR (R0)+ CLR (R0)+ CLR (R0)+ MOV CMD+G.CMLD+2,R0 ;STRING ADDR MOV CMD+G.CMLD,R1 CMP R1,#2 ;WAS THERE A NUMBER IN REPLY? BLT SCRAM ;ONLY CONTINUE IF HE REPLIES! JSR PC,$COTB ;CONVERT OCTAL BLK # MOV R1,DBLKN ;PUT BLK # IN QIOW$ DPB MOV SP,(PC)+ ;SAVE SP POSITION SPSAVE: .WORD 0 READ: JSR R5,BREAD TST DT.STT ;CHECK ERRORS BMI SCRAM ;JUST EXIT IF ANY OCCUR CLR MODIF BR PAST ;LIST ONLY WHEN TOLD TO. LIST: MOV #KBLH+6,R1 ;DES MOV (PC)+,(R1)+ .BYTE CR,LF MOV (PC)+,(R1)+ .BYTE 'B,'L MOV (PC)+,(R1)+ .BYTE 'K,' ; MOV R1,-(SP) MOV R0,-(SP) MOV R2,-(SP) ;SAVE REGS USED BY SYSRES MOV R1,R0 ;OUTPUT ADDRESS MOV DBLKN,R1 ;BLK # MOV #1,R2 ;LEAVE LEADING 0'S IN JSR PC,$CBOMG ;CONVERT TO ASCII OCTAL MOV (SP)+,R2 MOV (SP)+,R0 MOV (SP)+,R1 ;RESTORE REGS ADD #8.,R1 JSR R5,WRITE ;WRITE BLOCK # MOV #INBUF,R0 ;SRC DWCL2: MOV #DWDC,R2 ;LIMIT NEXT: MOV #KBLH+20,R1 ;DES MOV R3,-(SP) MOV R0,R3 ;GET ADDRESS SUB #INBUF,R3 TST BYTFLG ;ARE WE ADDRESSING IN WORDS OR BYTES? BNE 11$ ;BYTES; R3 IS OK NOW ASR R3 ;WORDS 11$: MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;CONVERT OCTAL TO ASCII MOV #KBLH+10,R0 ;OUTPUT ADR MOV R3,R1 ;NUMBER MOV #1,R2 ;LEAVE IN 0'S JSR PC,$CBOMG ;GET OCTAL MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ;PUT REGS BACK CLR KBLH+10 ;REMOVE 1ST 2 ZEROES MOV #": ,KBLH+16 ;PUT IN COLON TOO. MOV (SP)+,R3 ;RESTORE R3 MOV #4000,R4 NA: ASL R4 BLE NW JSR R5,CONENT DEC R2 BGT NA NW: JSR R5,WRITE TST R2 BGT NEXT NZ: TST CONT BLE PAST CMP DBLKN,CONT BGE PAST-4 INC DBLKN JMP READ CLR CONT PAST: MOV DBLKN,LBCPY ;SAVE BLOCK # MOV DBLKN-2,HBCPY ;FOR USER TO EXAMINE MOV SPSAVE,SP ;KEEP RESETTING STACK SO WE STAY OK JSR R5,KBREAD MOV #STR,R1 ;STRING POINTER CLR -(SP) ;RESERVE CELL FOR ADDR OF NEXT BYTE MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;GET CODE ADDR FROM TYPE-IN JSR PC,$COTB ;R0 ALREADY POINTS AT ASCII CMPB R2,#60 ;CHECK THAT WE GOT A NUMBER BLT 20$ ;NOT # CMPB R2,#67 BGT 20$ ;NOT OCTAL, ANYHOW BR 30$ 20$: DEC R0 ;BACK "LAST CHAR" UP AGAIN 30$: MOV R0,6(SP) ;SAVE ADDR OF NEXT BYTE OF TEXT MOV R1,R3 ;GET RELATIVE WORD IN R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 TST BYTFLG ;USING BYTE ADDRESSES? BNE 10$ ASL R3 10$: BIC #1,R3 ;ENSURE R3 IS EVEN MOV (SP),R2 CMPB (R2),(R1)+ BEQ POCT CMPB (R2),(R1)+ BEQ PRAD CMPB (R2),(R1)+ BEQ PASC CMPB (R2),(R1)+ ;NNN: TO LIST WORD NNN BEQ PDSPL ;NNN=WORD INDEX,OCTAL START AT 0 CMPB (R2),(R1)+ BNE 22$ JMP PNEXT 22$: CMPB (R2),(R1)+ BEQ PADVV CMPB (R2),(R1)+ ;D,N TO CHANGE BLK # AND LEAVE DATA? BEQ PCNTTV ;YUP. GO DO IT. CMPB (R2),(R1)+ ;P,NNNNNN TO SET H/O BLK NUMBER? BEQ PLSTV ;NOTE THAT ALL REQUESTS NEEDING INFORMATION LATER ;IN THE STRING MUST BE ABOVE THIS POINT. TST (SP)+ ;REMOVE EXTRA INFO ON STACK .. NOT NEEDED NOW CMPB (R2),(R1)+ BEQ PWRI CMPB (R2),(R1)+ BEQ LISTV CMPB (R2),(R1)+ BEQ PNXT CMPB (R2),(R1)+ BEQ ENDV CMPB (R2),(R1)+ BEQ READV CMPB (R2),(R1)+ BEQ PBAKV CMPB (R2),(R1)+ BEQ PLNKV CMPB (R2),(R1)+ ;TYPE? BEQ TYPTFV ;YES, GO TO IT CMPB (R2),(R1)+ ;FULLWORD ADDR NUMBERS? BEQ FULSTV ;YES CMPB (R2),(R1)+ ;BYTE ADDR NUMBERS? BEQ HALFTV CMPB (R2),(R1)+ ;SWAP BYTES? BEQ SWABTV ;YES JMP PAST SWABTV: JMP ARYSWB ;SWAP BYTES PCNTTV: JMP PRCNT ;HANDLE BLK # CHANGE PLSTV: JMP PLUSV ;SERVICE P,N REQ LISTV: JMP LIST PADVV: JMP PADV ENDV: JMP END READV: JMP READ PBAKV: JMP PBAK PLNKV: JMP PLNK ;TRANSFER VECTORS TYPTFV: JMP TYPBLK FULSTV: JMP FULLAD HALFTV: JMP HALFAD PDSPL: JMP PDSPLY POCT: INC (SP) ;OVER DELIMITER MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV 6(SP),R0 ;ADDR OF OCTAL ASCII JSR PC,$COTB MOV R1,6(SP) ;PUT CONVERTED # ON STACK MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ;RESTORE REGS LIKE GOOD GUY. PPUT: MOV (SP)+,INBUF(R3) ;MODIFY BUFFER PPUT4: INC MODIF JMP PAST PRAD: INC (SP) MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;SAVE REGS USED MOV 6(SP),R0 ;ASCII ADDR MOV #2,R1 ;PERIOD IS LEGAL RAD50 JSR PC,$CAT5 ;CONVERT IT MOV R1,6(SP) ;PUT ON STACK MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 BR PPUT PASC: INC (SP) MOV (SP)+,R4 MOVB (R4)+,INBUF(R3) MOVB (R4),INBUF+1(R3) BR PPUT4 PNXT: INC DBLKN JMP READ PWRI: JSR R5,BWRIT JMP PAST BREAD: MOV #IO.RLB,DFCT ;SET READ FUNCTION BGO:; CMP DBLKN,#MAXBLK ; BHIS BERR MOV #DLB,-(SP) ;NOW DO THE QIO EMT 377 TST DT.STT ;CHECK RTN STATUS CODE BMI BERR ;NEGATIVE IS AN ERROR CLR (SP) RTS R5 BERR: MOV #1,(SP) ; R5 WILL CONTAIN ERROR CODE RTS R5 BWRIT: MOV #IO.WLB,DFCT ;SET WRITE TST MODIF BEQ BERR-4 BR BGO PWRIB: JMP READ PNEXT: MOV #77777,CONT INC (SP) CMPB @(SP),#CR BEQ PNXT+6 ;O2BIN INC (SP) MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;NOW GET BLK # MOV 6(SP),R0 ;FROM ASCII JSR PC,$COTB CMPB R2,#60 BLT 20$ CMPB R2,#67 ;CHECK # FOUND BGT 20$ BR 30$ 20$: DEC R0 30$: MOV R1,CONT ;SAVE RESULT MOV R0,6(SP) ;ALSO NEXT BYTE MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 JMP READ PADV: INC (SP) CMPB @(SP),#CR BEQ PNXT INC (SP) MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV 6(SP),R0 ;GET ADVANCE BLOCK NUMBER JSR PC,$COTB CMPB R2,#60 BLT 20$ CMPB R2,#67 ;CHECK # FOUND BGT 20$ BR 30$ 20$: DEC R0 30$: MOV R1,DBLKN ;SAVE BLK # IN DPB MOV R0,6(SP) ;AND NEXT BYTE ADDR MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 PBAKM4: PBKM4: JMP READ PBAK: DEC DBLKN ; BGE PBAKM4 ;(USED TO CHECK MAX BLOCK NO, BUT BIG DISKS MADE ; CLR DBLKN ;THE CHECK OBSOLETE...) BR PBAKM4 PLNK: MOV INBUF,DBLKN BR PBAKM4 END: EXIT$S ;THAT'S ALL, FOLKS. PDSPLY: MOV #INBUF,R0 ;DATA TO DISPLAY ADD R3,R0 ;ADDR TO DISPLAY TST (SP)+ ;FORGET WHERE THIS CAME FROM MOV #5015,KBLH+6 ;PUT CRLF IN FIRST MOV #KBLH+10,R1 ;PUT DATA IN KBLH AREA INC R1 JSR R5,CONENT ;CONVERT TO DISPLAY FORMAT (1 WD) JSR R5,WRITE ;TYPE IT JMP PAST ;GET NEXT COMMAND. WRITE: MOVB #CR,(R1)+ MOVB #LF,(R1)+ SUB #KBLH+6,R1 MOV R1,KBLH+4 MOV #KBLH+4,-(SP) JSR R5,TTYM JSR R5,CLEAR RTS R5 CLEAR: MOV #KBLH+6,R4 MOV KBLH,-(SP) ADD R4,(SP) CL: MOVB #' ,(R4)+ CMP R4,(SP) BLT CL TST (SP)+ RTS R5 TTYM: ;CALL PUTS A BUFFER ADDRESS ON STACK AND JSR R5'S MOV R0,-(SP) ;SAVE A WORK REG MOV 4(SP),R0 ;BUFFER ADDR MOV (R0)+,TIWC ;BYTES IN TEXT MOV R0,TIBUF ;ADDRESS TO USE MOV #TILB,-(SP) ;PUSH DPB EMT 377 ;DO QIOW$ MOV (SP)+,R0 ;RESTORE R0 MOV (SP)+,(SP) ;PUSH UP RETURN R5 RTS R5 ;THAT'S IT. RTS R5 ;CONENT CONVERTS A WORD TO OCTAL, RAD50, AND ASCII CONENT:; MOV (R0),-(SP) MOV R0,-(SP) MOV R1,-(SP) ;SAVE REGS MOV R2,-(SP) MOV @R0,R1 ;NUMBER TO CONVERT MOV 2(SP),R0 ;ADDR TO PUT IN MOV #2,R2 ;FLAG JSR PC,$CBOMG ;TO OCTAL FIRST! MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ADD #8.,R1 MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;NOW RAD-UNPACK MOV @R0,R1 ;GET NUMBER MOV 2(SP),R0 ;AND BUFFER ADDR JSR PC,$C5TA ;CONVERT MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ;RESTORE REGISTERS USED ADD #4,R1 MOVB (R0)+,(R1) JSR R5,TSTASC MOVB (R0)+,(R1) JSR R5,TSTASC ADD #2,R1 RTS R5 TSTASC: BICB #200,@R1 ;GUARANTEE THAT ASCII HI BIT IGNORED... CMPB (R1),#40 BLT SB CMPB (R1),#176 BLE CON SB: MOVB #40,(R1) CON: INC R1 RTS R5 KBREAD: GCML$ #CMD ;GET A COMMAND OR TWO BCC 1$ EXIT$S 1$: MOV CMD+G.CMLD+2,R0 ;ADDRESS OF INPUT LINE MOV CMD+G.CMLD,R1 ;LENGTH IN BYTES OF INPUT LINE ; MOV #KBLH+6,R0 ; MOV KBLH+4,R1 RTS R5 ;R0=CORE ADDR,R1=BYTE COUNT FULLAD: CLR BYTFLG JMP PAST HALFAD: MOV #2,BYTFLG;SET BYTE OFFSETS JMP PAST TYPBLK: ;TYPE THE BLOCK IN ASCII!! BR X10$ ;SKIP BUFFER HEADERS, ETC. DUMP IN ASCII VTHDR: .WORD 1,0,1,13 ;VERTICAL TAB TO FLUSH TYPEOUT DATHDR: .WORD 2*DWDC ;BUFFER SIZE .WORD 6 ;UNFORMATTED ASCII DUMP DATSIZ: .WORD 512. ;# CHARS TO WRITE .WORD INBUF ;DATA IN "INBUF" X10$: .IF DF,DMPALL ;IF ALL AT ONCE... MOV #<<2*DWDC>+2>,TIWC ;WRITE 514 BYTES MOV #INBUF-2,TIBUF ;FROM INBUF MOV #TILB,-(SP) ;NOW QIOW$ IT OUT EMT 377 ;(AUTOMATICALLY AWAITS DONE) .IFF MOV R2,-(SP) MOV R3,-(SP) ;FREE A FEW REGS MOV R4,-(SP) MOV #7,R2 ;7 LINES, 80 CHAR EACH (LAST IS 34) MOV #INBUF,R3 ;DATA ADDRESS MOV #INBUF-2,TIBUF ;INITIAL CRLF MOV #2,TIWC MOV #TILB,-(SP) EMT 377 ;SEND OUT... 1$: DEC R2 ;COUNT DOWN... BNE 2$ MOV #32.,TIWC ;SET 32 BYTES ON LAST BR 3$ 2$: MOV #80.,TIWC 3$: MOV R3,TIBUF ;SET DATA ADDRESS MOV #TILB,-(SP) ;PUSH QIO BLK EMT 377 ;EMIT TEXT ADD #80.,R3 ;POINT AT NEXT DATA ; IGNORE ERRORS ON QIO... MOV #INBUF-2,TIBUF MOV #2,TIWC ;TYPE CR,LF MOV #TILB,-(SP) EMT 377 ;CRLF AFTER EACH LINE TST R2 BGT 1$ ;LOOP BACK FOR ALL DATA MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 .ENDC ;VERY LIKELY ONE CAN GENERATE ERRORS THIS WAY; IGNORE THEM. JMP PAST PLUSV: ;SET HIGH-ORDER BLOCK NUMBER. DO NO I/O INC @SP ;PASS + CMPB @(SP),#CR ;CHECK THAT A COMMA IS THERE BNE PLUSV1 ;NO. TEST FOR ALT PLUS2: JMP PAST ;NO COMMA, NO ACTION KIDDO! PLUSV1: CMPB @(SP),#33 ;ALT? BEQ PLUS2 ;YUP. SAME STORY. INC @SP ;WELL, HE MIGHT BE RIGHT. LET IT BY. ;PASS THE COMMA NOW AND GET BINARY NUMBER. MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;SAVE OUR REGS AS USUAL MOV 6(SP),R0 ;ASCII NUMBER JSR PC,$COTB ;CONVERT IT MOV R1,DBLKN-2 ;SET H/O BLK # MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ;PUT BACK REGS USED BR PLUS2 ;GO ON BACK FOR MORE. PRCNT: INC @SP ;PASS COMMA CMPB @(SP),#CR ;IS THERE A COMMA, EVEN? BNE PRCNT1 PRCNTX: EXIT$S ;SCRAM--HE'S DANGEROUS! PRCNT1: CMPB @(SP),#33 ;ALTMODE EITHER? BEQ PRCNTX ;YEAH, GET OUT FAST ;REQUEST IS NOT OBVIOUSLY WRONG--DO IT. INC @SP ;PASS COMMA NOW. (PASSED THE % EARLIER) MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) ;SAVE REGS INC MODIF ;SET BLOCK CHANGED MOV 6(SP),R0 ;GET ASCII ADDRESS JSR PC,$COTB ;CONVERT OCTAL MOV R1,DBLKN ;RESET BLK NUMBER MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 JMP PAST ;GO ON ARYSWB: MOV R0,-(SP) MOV R1,-(SP) ;SAVE REGS MOV #400,R1 ;256 WORDS/BLOCK MOV #INBUF,R0 ;BUFFER TO SWAB ON 1$: SWAB (R0)+ ;SWAP BYTES IN WORD DEC R1 BGT 1$ ;DO WHOLE BLOCK MOV (SP)+,R1 MOV (SP)+,R0 ;FIX REGS JMP PAST ;RETURN .WORD 0,0 MSGTWO: AXST-.-2 .ASCII $DISK READ/WRITE ERROR (PROBABLY NON-EXISTANT BLOCK NUMBER)$ .BYTE CR,LF .EVEN AXST=. .WORD 0,0 AST: 2 .BYTE 52,13 ;* .END DKPEEK