.TITLE RPCHECK .IDENT /MRHV01/ .SBTTL INTRO PAGE .LIST MEB ; ;THIS PROGRAM IS DESIGNED TO CHECK OUT THE CONDITION OF THE SURFACE OF ;AN AMPEX DM980 DRIVE, OR A FUJUTSU DRIVE EMULATING AN RM03 DRIVE ;IT WILL: ; ;1 READ THE ENTIRE DISK IN 32. BLOCK INCREMENTS (ONE FULL SURFACE CYLINDER) ; ;2 MONITOR AED REGISTER RPM1 TO SEE IF THE ERROR CORRECTION POLYNOMIAL ; WAS USED DURING THE READ AND REPORT IT AS A "SOFT" ERROR (AED ONLY) ; ;3 MONITOR THE IOSTATUS RETURN TO SEE IF THE READ FAILED ALTOGETHER AND ; REPORT THIS AS A "HARD" ERROR ; ;4 IF ERROR OCCURS, RETRY 1 BLOCK AT A TIME ; ;5 SAVE RPM1 CONTENTS AT START AND RESET AT THE END SO WE CAN CHECK OUT ; FAILING DISKS WITHOUT SCARING THE SYSTEM MANAGER (AED ONLY) ; ;NOTE NOTE NOTE ; ; PROGRAM USES LUN 2 FOR READS, IT IS ASSIGNED AT TKB TIME TO SY: ; ; ;DEFINE SOME NEEDED VARIABLES ; RPM1=176726 READSZ=32.*1000 ;NUMBER OF BYTES IN 32. BLOCKS LASTSZ=16.*1000 ;LAST AED READ IS ONLY 16. BLOCKS READ1=1000 ;NUMBER OF BYTES IN 1 BLOCK ; ; .MCALL QIOW$,DIR$,EXIT$S,GMCR$,GLUN$ .PAGE .SBTTL THE CODE ; ;FIRST SET THINGS UP ; START: DIR$ #GETMCR ;SO WE RECALL THE CALLER DIR$ #GETDEV ;SEE WHAT DRIVE WE^RE WORKING ON CMP DEVICE,#"DP ;IF NOT AN AED BNE 111$ ;SKIP RPM1 SAVE, ETC SUB #80.,BLOCKL ;ADJUST BLOCK LOW FOR AED MOV RPM1,RPM1SV ;SAVE CONTENTS OF RPM1 111$: MOV #0,REAQIO+Q.IOPL+6 ;START AT BLOCK # 0 MOV #0,REAQIO+Q.IOPL+10 REGO: MOV RPM1,R5 ;REMEMBER RPM1 IN R5 CMP DEVICE,#"DP ;IS THIS AED DRIVE ? BNE 111$ ;SKIP IF NOT CMP BLOCKH,REAQIO+Q.IOPL+6 ;ARE WE AT END ? BNE 111$ ;SKIP IF NOT CMP LBLOCK,REAQIO+Q.IOPL+10 BNE 111$ ;SKIP IF NOT MOV #LASTSZ,REAQIO+Q.IOPL+2 ;FOR AED, MAKE LAST READ HALF SIZE 111$: DIR$ #REAQIO ;DO DISK READ TSTB IOSB ;DID READ GO OK BPL READOK ;BR IF OK JSR PC,HARDNG ;ELSE REPORT ERROR JSR PC,RETRY ;AND RETRY 1 BLOCK AT A TIME READOK: CMP RPM1,R5 ;HAS RPM1 CHANGED ? BEQ SOFTOK ;NO SKIP IT CMP DEVICE,#"DP ;ARE WE CHECKING AED ? BNE 111$ ;SKIP IF NOT JSR PC,SOFTNG ;YES, REPORT IT 111$: JSR PC,RETRY ;AND TRY 1 BLOCK AT A TIME SOFTOK: ADD #32.,REAQIO+Q.IOPL+10 ;BUMP READ BY 32 BLOCKS ADC REAQIO+Q.IOPL+6 ;ADD CARRY TO UPPER WORD OF BLOCK # CMP BLOCKH,REAQIO+Q.IOPL+6 ;ARE WE AT END ? BNE REGO CMP BLOCKL,REAQIO+Q.IOPL+10 ;OF DISK BHI REGO CMP DEVICE,#"DP ;ARE WE WORKING WITH AED ? BNE 111$ ;IF NOT, DON'T RESTORE RPM1 MOV RPM1SV,RPM1 ;RESTORE RPM1 ORIGINAL CONTENTS 111$: MOV #DONE,ERRQIO+Q.IOPL MOV #DONELN,ERRQIO+Q.IOPL+2 DIR$ #ERRQIO ;REPORT IT CLR R0 ;CLEAR HEAD COUNTER LOOP: MOVB HEADCT(R0),R1 ;GET ERROR COUNT FOR HEAD BIC #177400,R1 ;CLEAR POSSIBLE SIGN EXTEND CMP R1,#70. ;GREATER THAN 70 ERRORS ? BLE 1$ ;NO MOV #71.,R1 ;YES, LIMIT TO 71 1$: ADD #7,R1 ;ADD LENGTH OF "HEAD N " MOV #HISTO,ERRQIO+Q.IOPL ;FILL IN START OF MESSAGE MOV R1,ERRQIO+Q.IOPL+2 ;AND LENGTH DIR$ #ERRQIO ;DO ONE LINE OF HISTOGRAM INCB HISTO1 ;INC HEAD # IN OUTPUT LINE INC R0 ;GO TO NEXT HEAD CMP R0,#4 ;PAST LAST HEAD BLE LOOP ;NO EXIT$S ;YES, EXIT SYSTEM .PAGE .SBTTL SUBROUTINES .SBTTL REPORT HARD ERROR ; ;SUB TO REPORT HARD ERROR ; HARDNG: MOV #HARDP1,R0 ;POINT TO BUFFER MOV REAQIO+Q.IOPL+6,R1 ;GET HIGH PART OF BLOCK NUMBER CLR R2 ;INDICATE 0 SUPPRESSION JSR PC,$CBOMG ;CONVERT NUMBER MOVB #',,(R0)+ ;PUT IN A COMMA MOV REAQIO+Q.IOPL+10,R1 ;GET LOW PART OF BLOCK NUMBER INC R2 ;MAKE THIS 6 DIGITS JSR PC,$CBOMG ;CONVERT IT MOV #HARDP2,R0 ;POINT TO BUFFER MOV RPM1,R1 ;GET RPM1 CONTENTS JSR PC,$CBOMG ;CONVERT IT MOV REAQIO+Q.IOPL+6,R2 ;GET BLOCK NUMBER AGAIN MOV REAQIO+Q.IOPL+10,R3 ;IN DOUBLE REGISTER DIV #240,R2 ;DIVIDE BY NUMBER OF BLOCKS/CYLINDER MOV R2,R1 ;GET QUOTIENT (CYL NUMBER) MOV #1,R2 ;INDICATE NO SUPRESS 0'S MOV #HARDP3,R0 ;POINT TO BUFFER JSR PC,$CBOMG ;CONVERT CYL CLR R2 ;CLEAR UPPER REG DIV #32.,R2 ;CONVERT TO SURFACE, CYL MOV R2,R1 ;QUOTIENT IS SURFACE # INCB HEADCT(R1) ;COUNT ERROR FOR THIS HEAD MOV #1,R2 ;NO SUPRESSION MOV #HARDP4,R0 JSR PC,$CBOMG ;CONVERT SURFACE # MOV R3,R1 ;NOW GET SECTOR # MOV #HARDP5,R0 JSR PC,$CBOMG MOV #HARDER,ERRQIO+Q.IOPL ;FILL IN MESSAGE START IN DPB MOV #HARDLN,ERRQIO+Q.IOPL+2 ;AND LENGTH DIR$ #ERRQIO ;AND REPORT ERROR RTS PC ;AND RETURN .PAGE .SBTTL REPORT SOFT ERROR ; ;SUB TO REPORT SOFT ERROR ; SOFTNG: MOV #SOFTP1,R0 ;POINT TO BUFFER MOV REAQIO+Q.IOPL+6,R1 ;GET HIGH PART OF BLOCK NUMBER CLR R2 ;INDICATE 0 SUPPRESSION JSR PC,$CBOMG ;CONVERT NUMBER MOVB #',,(R0)+ ;PUT IN A COMMA MOV REAQIO+Q.IOPL+10,R1 ;GET LOW PART OF BLOCK NUMBER INC R2 ;MAKE THIS 6 DIGITS JSR PC,$CBOMG ;CONVERT IT MOV #SOFTP2,R0 ;POINT TO BUFFER MOV RPM1,R1 ;GET RPM1 CONTENTS JSR PC,$CBOMG ;CONVERT IT MOV REAQIO+Q.IOPL+6,R2 ;GET BLOCK NUMBER AGAIN MOV REAQIO+Q.IOPL+10,R3 ;IN DOUBLE REGISTER DIV #240,R2 ;DIVIDE BY NUMBER OF BLOCKS/CYLINDER MOV R2,R1 ;GET QUOTIENT (CYL NUMBER) MOV #1,R2 ;INDICATE NO SUPRESS 0'S MOV #SOFTP3,R0 ;POINT TO BUFFER JSR PC,$CBOMG ;CONVERT CYL CLR R2 ;CLEAR UPPER REG DIV #32.,R2 ;CONVERT TO SURFACE, CYL MOV R2,R1 ;QUOTIENT IS SURFACE # INCB HEADCT(R1) ;COUNT ERROR FOR THIS HEAD MOV #1,R2 ;NO SUPRESSION MOV #SOFTP4,R0 JSR PC,$CBOMG ;CONVERT SURFACE # MOV R3,R1 ;NOW GET SECTOR # MOV #SOFTP5,R0 JSR PC,$CBOMG MOV #SOFTER,ERRQIO+Q.IOPL ;FILL IN MESSAGE START IN DPB MOV #SOFTLN,ERRQIO+Q.IOPL+2 ;AND LENGTH DIR$ #ERRQIO ;AND REPORT ERROR RTS PC ;AND RETURN .PAGE .SBTTL RETRY 1 BLOCK AT A TIME ; ;SUB TO RETRY 1 BLOCK AT A TIME ; RETRY: MOV #READ1,REAQIO+Q.IOPL+2 ;CHANGE TO 1 BLOCK READ MOV REAQIO+Q.IOPL+10,-(SP) ;SAVE BLOCK NUMBERS MOV REAQIO+Q.IOPL+6,-(SP) MOV #32.,R4 ;SET UP LOOP COUNT 11$: MOV RPM1,R5 ;REMEMBER RPM1 COUNT DIR$ #REAQIO ;DO DISK READ TSTB IOSB ;DID READ GO OK BPL 1$ ;BR IF OK JSR PC,HARDNG ;ELSE REPORT ERROR 1$: CMP RPM1,R5 ;HAS RPM1 CHANGED ? BEQ 2$ ;NO SKIP IT JSR PC,SOFTNG ;YES, REPORT IT 2$: INC REAQIO+Q.IOPL+10 ;BUMP READ BY 1 BLOCK ADC REAQIO+Q.IOPL+6 ;ADD CARRY TO UPPER BLOCK NUMBER SOB R4,11$ ;DO IT FOR 32. BLOCKS MOV #READSZ,REAQIO+Q.IOPL+2 ;RESET SIZE TO 32. BLOCKS MOV (SP)+,REAQIO+Q.IOPL+6 ;RESTORE DISK BLOCK NUMBERS MOV (SP)+,REAQIO+Q.IOPL+10 RTS PC ;AND RETURN .PAGE .SBTTL DATA AREAS ; ;QIO FOR MESSAGES TO TI ; ERRQIO: QIOW$ IO.WVB,5,1,,,,<0,0,40> ; ;NOW POSSIBLE MESSAGES ; SOFTER: .ASCII /SOFT ERR AT BL# / SOFTP1: .ASCII /N,NNNNNN RPM1=/ SOFTP2: .ASCII /NNNNNN CYL=/ SOFTP3: .ASCII /NNNNNN SURF=/ SOFTP4: .ASCII /NNNNNN SECT=/ SOFTP5: .ASCII /NNNNNN/ SOFTLN=.-SOFTER ; HARDER: .ASCII /HARD ERR AT BL# / HARDP1: .ASCII /N,NNNNNN RPM1=/ HARDP2: .ASCII /NNNNNN CYL=/ HARDP3: .ASCII /NNNNNN SURF=/ HARDP4: .ASCII /NNNNNN SECT=/ HARDP5: .ASCII /NNNNNN/ HARDLN=.-HARDER ; DONE: .ASCII /READ CHECK FINISHED, RPM1 ORIGINAL CONTENTS RESTORED/ DONELN=.-DONE .EVEN HISTO: .ASCII /HEAD / HISTO1: .ASCII /0 1234567891123456789212345678931234567894123456789/ .ASCII /512345678961234567897*/ .EVEN ; ;NOW THE DISK READ QIO ; REAQIO: QIOW$ IO.RLB,2,1,,IOSB,, ; IOSB: .WORD 0,0 ;RETURNED STATUS ; HEADCT: .BYTE 0,0,0,0,0,0 ;STORE HEAD COUNT OF ERRORS HERE ; GETMCR: GMCR$ ;GET MCR DPB GETDEV: GLUN$ 2,DEVICE ;GET LUN DPB DEVICE: .BLKW 6 ;GET LUN BUFFER ; ;MISC VARIABLES ; RPM1SV: .WORD 0 ;SAVE CONTENTS OF RPM1 HERE BLOCKH: .WORD 2 ;HIGH ORDER MAX BLOCK # BLOCKL: .WORD 1140 ;LOW ORDER MAX BLOCK # LBLOCK: .WORD 1000 ;LOW ORDER MAX BLOCK # FOR LAST AED READ READBF: .BLKB READSZ ;BUFFER FOR READING 32. BLOCKS .END START