.MCALL .MODULE .MODULE FMTDM,VERSION=02,COMMENT=,IDENT=NO ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; ; AUTHOR: JONATHAN P. HARRIS 5-DEC-77 V01-00 ; ; MODIFIED: BARBARA DOERRE 7-NOV-78 V01-01 ; MACROS MODIFIED AND ADDED TO SUPPORT VERIFIFICATION FUNCTIONALITY AND ; TO OVERLAY FORMAT ROUTINES ; 1)MODIFIED DEVIC$ AND ENTRY$ MACROS ; 2)ADDED LDPT$ MACRO ; ; ; THIS MODULE IS A PREFIX FILE FOR ASSEMBLY OF THE FORMAT ROOT ; AND OVERLAYS. IT PROVIDES MACROS NEEDED TO SPECIFY OPTIONS ; AND CREATE TABLES AND ENTRY POINTS. ; TO ADDED A DEVICE: ; 1) INVOKE DEVIC$ MACRO IN MODULE FMTDEV.MAC FOR THE DEVICE ; 2) CREATE A FILE FMTXX.MAC (XX=DEVICE MNEMONIC) CONTAINING THE FOLLOWING ; IN THE SPECIFIED ORDER ; A. MACRO PREFIX FILE ; B. INVOKE LDPT$ MACRO FOR DEVICE ; C. DEVICE CHECK ROUTINE ; D. INVOKE OPTN$ MACRO (OPTIONAL) ; E. INVOKE ENTRY$ MACRO ; F. FORMAT ROUTINE (IF ONE EXISTS) ;- .SBTTL (MACRO PREFIX FILE) ;+ ; DEVIC$ - USED TO SET UP EACH FORMATTING OVERLAY ; ; THIS MACRO CREATES THE DEVICE TABLE ENTRY FOR THE DEVICE. ; IT SHOULD BE PLACED IN THE FMTDEV.MAC MODULE. ; A ROUTINE FOR DEVICE XX WILL HAVE DEVICE TABLE ENTRIES CREATED ; FOR IT. ; ; THE MACRO HAS THREE PARAMETERS, THE TWO LETTER DEVICE MNEMONIC, ; THE DEVICE ID NUMBER AS RETURNED BY .DSTATUS, AND FMTRT, A 'Y' OR 'N' ; TO INDICATE WHETHER A FORMATTING ROUTINE EXISTS FOR THIS DEVICE. ; ; **THIS MACRO IS NOT TO BE INVOKED IN THE ROOT OR FORMAT OVERLAYS** ; ; TO INVOKE IT, TYPE: ; ; DEVIC$ XX,IDNUM,FMTRT ; ; WHERE XX IS THE DEVICE MNEMONIC, IDNUM IS THE .DSTATUS NUMBER ; AND FMTRT IS A 'Y' OR 'N' TO INDICATE WHETHER A FORMAT ROUTINE ; EXISTS FOR THIS DEVICE. ; ; EXAMPLES: ; DEVIC$ RK,0,Y ;DOES SETUP FOR RK05 ; DEVIC$ DM,23,Y ;DOES SETUP FOR RK06/7 ; DEVIC$ DX,22,N ;DOES SETUP FOR RX01 ;- ; ; SYMBOLIC DEFINITIONS FOR DEVICE TABLE ; ;SYMBOL MEANING ;------ ------- ;OFFSETS INTO DEVICE TABLE ENTRY: RADNAM=0 ; RAD50 DEVICE NAME DEVTYP=2 ; .DSTATUS DEVICE ID NUMBER ASCNAM=4 ; ASCII DEVICE NAME OPVAL=6 ; POINTER TO LIST OF VALID OPTIONS LOADPT=8. ; LOAD ENTRY POINT ENTRY=10. ; ENTRY POINT TO ROUTINE END=12. ; END POINT OF ROUTINE ;BD1+ DEVCHK=14. ; DEVICE CHECK ROUTINE ENTRY POINT CHAR=16. ; DEVICE CHARACTERISTICS RTDVSZ=1 ; SPFUN RETURNS DEVICE SIZE SPFIO=2 ; SPFUN READS/WRITES BFSZP1=4 ; BUFFER SIZE PLUS 1 FOR R/W ;BD1- DVENSZ=18. ;SIZE OF EACH ENTRY IN DEVICE TABLE ; .MACRO DEVIC$ NAME,IDNUM,FMTRT,CHARDV .PSECT $DV,RO,D,GBL .GLOBL $'NAME'TAB,$'NAME'END,$'NAME'DCK,NAME'LD .IIF IDN Y,FMTRT .GLOBL $'NAME'FMT .RAD50 /NAME/ .WORD IDNUM .ASCII /NAME/ .WORD $'NAME'TAB .WORD NAME'LD .IF IDN Y,FMTRT .WORD $'NAME'FMT .IFF .WORD 0 .ENDC .WORD $'NAME'END .WORD $'NAME'DCK .WORD CHARDV .PSECT .ENDM ;+ ; LDPT$ - THIS MACRO CREATES THE NECESSARY LOAD POINTS AND POINTERS ; TO THE LIST OF OPTIONS FOR THE DEVICE. ; A DEVICE WILL HAVE THE FOLLOWING CREATED FOR IT: ; 1) POINTER TO LIST OF VALID OPTIONS FOR THIS DEVICE ; 2) LOAD POINT FOR OVERLAY ; 3) DEVICE CHECK ROUTINE ENTRY POINT ; 4) PATCH SPACE ; ; A SHORT DEVICE CHECK ROUTINE SHOULD FOLLOW ; A CALL TO THIS MACRO OF THE FORM: ; IF (DEVICE NOT READY OR WRITE LOCKED) THEN SEC ; ELSE CLC ; THE UNIT NUMBER OF THE DEVICE TO BE TESTED IS PASSED IN R1. ; ; **THIS MACRO IS NOT TO BE USED IN THE ROOT** ; ; ; TO INVOKE IT, TYPE: ; ; LDPT$ NAME ; ; WHERE 'NAME' IS THE TWO LETTER DEVICE MNEMONIC. ; ; EXAMPLES: LDPT$ RK ;FOR RK05 ; LDPT$ DM ;FOR RK06/07 ; ;- .MACRO LDPT$ NAME .PSECT PATCH,RW,I .BLKW 32. .PSECT $OP,RW,D,GBL $'NAME'TAB:: .PSECT DATA,RW,D .PSECT PUREDATA,RO,D .PSECT NAME,I,RW NAME'LD:: RTS PC .PSECT NAME'END,RO,D $'NAME'END:: .PSECT NAME,I,RW $'NAME'DCK:: .ENDM ;+ ; OPTN$ - USED TO GENERATE THE 8 BYTE OPTION TABLE ENTRY THAT DEFINES AN OPTION. ; ; THIS MACRO ALLOWS EACH FORMATTING ROUTINE TO SPECIFY THE OPTIONS ; IT WILL NEED. THE OPTIONS SO SPECIFIED BECOME KNOWN TO THE ROOT ; AT LINK TIME, THUS THERE IS NO NEED TO MODIFY THE ROOT TO ADD AN ; OPTION TO THE PROGRAM. ; ; THERE CAN BE ANY NUMBER OF OPTIONS IN THE TABLE. THE TABLE IS ; TERMINATED WITH A .WORD 0 (AUTOMATICALLY HANDLED BY ENTRY$ MACRO). ; TO USE THE MACRO WITHIN A FORMATTING ROUTINE, PLACE IT AT THE ; BEGINNING OF THE ROUTINE IMMEDIATELY FOLLOWING THE DEVIC$ CALL. ; WITHIN THE ROOT, PLACE THE MACRO FOLLOWING EXISTING INVOCATIONS OF OPTN$. ; THE MACRO HAS TWO PARAMETERS: OPTION, THE ASCII OPTION, AND ; ACCEPT, A 'Y' OR 'N' TO INDICATE WHETHER THE OPTION WILL ACCEPT ; A VALUE. ; ; TO ACCESS THE INFORMATION IN THE TABLE, THE FOLLOWING SYMBOLS ARE ; PROVIDED WITH EACH OPTION '?': ; GIV.? = 1 IF USER SPECIFIED THAT OPTION WITH A VALUE, ; = 0 IF USER DIDN'T SPECIFY OPTION ; = -1 IF USER SPECIFIED OPTION WITHOUT A VALUE ; VAL.? VALUE GIVEN WITH OPTION ? (IF A VALUE WAS GIVEN) ; (ONLY PROVIDED IF OPTION ACCEPTS A VALUE) ; ; TO INVOKE OPTN$, TYPE ; ; OPTN$ OPTION,ACCEPT ; ; EXAMPLES: ; OPTN$ S,Y - SETS UP OPTION "S" THAT ACCEPTS A VALUE ; OPTN$ Q,N - SETS UP OPTION "Q" WHICH DOES NOT ACCEPT ; A VALUE ; ; ; EACH ENTRY CONSISTS OF: ; ; +--------+--------+ ; ! VALLOW ! OPTION ! ; +--------+--------+ ; ! RES. ! GIVEN ! ; +--------+--------+ ; ! VALUE ! ; +--------+--------+ ; ; WHERE: ; OPTION (1 BYTE) IS THE ASCII OPTION ; VALLOW (1 BYTE) IS: ; 1 - IF OPTION WILL ACCEPT A VALUE ; 0 - IF NOT ; GIVEN (1 BYTE) IS: ; 1 - IF OPTION SPECIFIED WITH A VALUE ; 0 - IF OPTION NOT SPECIFIED ; -1 - IF OPTION SPECIFIED WITHOUT A VALUE ; RES. (1 BYTE) IS RESERVED FOR FUTURE USE ; VALUE (1 WORD) IS THE VALUE GIVEN WITH OPTION ( IF ALLOWED) ;- ; ; SYMBOLIC DEFINITONS FOR OPTION TABLE ; ;SYMBOL MEANING ;----- ------- OPT=0 ;OFFSETS INTO AN OPTION ENTRY: ASCII OPTION VALLOW=1 ; ALLOW A VALUE? GIVEN=2 ; OPTION GIVEN? VALUE=4 ; VALUE GIVEN OPENSZ=6 ;SIZE OF EACH OPTION TABLE ENTRY IN BYTES ; .MACRO OPTN$ OP,ACCEPT .PSECT $OP,RW,D,GBL .BYTE ''OP .IF IDN Y,ACCEPT .BYTE 1 .IFF .BYTE 0 .IFTF GIV.'OP: .BYTE 0 .BYTE 0 .IFT VAL.'OP: .WORD 0 .IFF .WORD 0 .ENDC .PSECT .ENDM ;+ ; ENTRY$ - THIS MACRO CREATES THE NECESSARY ENTRY POINT AND .PSECT ; FOR THE FORMATTING ROUTINE.IT ALSO CLOSES OFF THE OPTION TABLE ; WITH A 0. ; ; **THIS MACRO IS NOT TO BE USED IN THE ROOT** ; ; TO INVOKE IT, TYPE: ; ; ENTRY$ NAME ; ; WHERE 'NAME' IS THE TWO LETTER DEVICE MNEMONIC. ; ; EXAMPLES: ENTRY$ RK ;FOR RK05 ; ENTRY$ DM ;FOR RK06/07 ; ;- .MACRO ENTRY$ NAME .PSECT $OP,RW,D,GBL .WORD 0 .PSECT NAME,I,RW $'NAME'FMT:: .ENDM .SBTTL RK06/07 FORMATTING ROUTINE ;+ ; COPYRIGHT (c) 1989 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ; TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ; CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ; ; AUTHOR: BARBARA J. DOERRE 8-JUNE-78 V01.00 ; ; MODIFIED: ; ; V01.01 06-AUG-79 ADDED $ERROR MACRO FOR SUPPORT OF ; -MBG- USER PROGRAM ERROR STATUS BYTE (53) ;MG1 ; ; X05.00 14-SEP-82 GET CSR FROM HANDLER ; -CA- ELDM == 1 ; ; THIS MODULE WILL FORMAT RK06/07 DISKS ;- ;+ ; ; FMTDM - THIS MODULE FORMATS RK06/07 DISKS ; ; VERSION X05.00 ; ;- .SBTTL SYMBOLS .MCALL .PRINT, .SETTO ; LOCAL SYMBOLS ; ; SYMBOL FUNCTION ; ------ -------- .IIF NDF DM$CSR, DM$CSR==177440 ;BASE LOCATION OF DEVICE REGISTERS RKCS1 = 0 ;OFFSET OF CONTROL AND STATUS REGISTER RKWC = 2 ; WORD COUNT REGISTER RKBA = 4 ; BUS ADDRESS REGISTER RKDA = 6 ; DISK ADDRESS REGISTER RKCS2 = 10 ; CONTROL AND STATUS REGISTER RKDS = 12 ; DRIVER STATUS REGISTER RKER = 14 ; ERROR REGISTER RKASOF = 16 ; ATTN SUMMARY & OFFSET REGISTER RKDC = 20 ; DESIRED CYLINDER REGISTER CYL06 = 410. ;MAX CYLINDER FOR RK06 CYL07 = 814. ;MAX CYLINDER FOR RK07 ; CONTROL AND STATUS BITS ;RKCS1 CERR = 100000 ;COMBINED ERROR DTC = 20000 ;DRIVE TO CONTROLLER PARITY ERROR CTO = 4000 ;CONTROLLER TIME OUT CDT = 2000 ;CONTROLLER DRIVE TYPE RDY = 200 ;CONTROLLER READY ;RKCS2 BAI = 20 ;BUS ADDRESS INCREMENT INHIBIT SCLR = 40 ;SUBSYSTEM CLEAR UFE = 400 ;UNIT FIELD ERROR MDS = 1000 ;MULTIPLE DRIVE SELECT PGE = 2000 ;PROGRAMMING ERROR NEM = 4000 ;NON-EXISTENT MEMORY NED = 10000 ;NON-EXISTENT DRIVE UPE = 20000 ;UNIBUS PARITY ERROR WCE = 40000 ;WRITE CHECK ERROR DLT = 100000 ;DATA LATE ERROR FATAL2 = UFE!PGE!MDS!NEM!NED!UPE!DLT ;RKDS DRA = 1 ;DRIVE AVAILABLE VV = 100 ;VOLUME VALID DRDY = 200 ;DRIVE READY DDT = 400 ;DISK DRIVE TYPE WRL = 4000 ;WRITE LOCK SVAL = 100000 ;STATUS VALID ;RKER ILF = 1 ;ILLEGAL FUNCTION SKI = 2 ;SEEK INCOMPLETE NXF = 4 ;NON-EXECUTABLE FUNCTION DRPAR = 10 ;CONTROL-TO-DRIVE PARITY ERROR FMTE = 20 ;FORMAT ERROR DTYE = 40 ;DRIVE TYPE ERROR ECH = 100 ;ERROR CORRECTION HARD BSE = 200 ;BAD SECT0R ERROR HVRC = 400 ;HEADER VERTICAL REDUNDANCY CHECK COE = 1000 ;CYLINDER OVERFLOW ERROR IDAE = 2000 ;INVALID DISK ADDRESS ERROR WLE = 4000 ;WRITE LOCK ERROR DTE = 10000 ;DRIVE TIMING ERROR OPI = 20000 ;OPERATION INCOMPLETE UNS = 40000 ;DRIVE UNSAFE DCK = 100000 ;DATA CHECK FATAL1 = UNS!DTE!WLE!DTYE!FMTE!NXF!ILF!COE!IDAE ;FUNCTIONS WCHECK = 31 ;WRITE CHECK WHEAD = 27 ;WRITE HEADER WDATA = 23 ;WRITE DATA RDATA = 21 ;READ DATA SEEK = 17 ;SEEK CYLINDER RECAL = 13 ;RECALIBRATION DRCLR = 5 ;DRIVE CLEAR PACK = 3 ;PACK ACKNOWLEDGE SELDRV = 1 ;SELECT DRIVE ; INPUT STATUS BITS NOCHK = 1 ;NO ERROR CHECK AFTER FUNCTION PERFORMED INHINC = 2 ;INHIBIT INCREMENT ; ERROR REPORTING MACRO .GLOBL $SERR1, $SERR2, $SERR3, $CNVRT, $SVRG, $RSTRG .GLOBL PREMSG ;MG1+ .IRPC X, .GLOBL ERR$$'X .ENDR .MACRO $ERROR ADDR,CODE MOV #ERR$$'CODE',R0 MOV ADDR,-(SP) CALL PREMSG .ENDM ;MG1- .SBTTL ** RK06/07 FORMATTER MAIN ROUTINE ** .GLOBL NONCSR ; ROOT INTERFACE ; ; LDPT$ DM ;SETUP DEVICE LOAD POINT AND ; OPTION TABLE MOV NONCSR,CSR1DM ;GET ADR OF CSR ;CA5+ MOV CSR1DM,R5 ;R5 ALWAYS POINTS AT THE DM CSR MOV #SELDRV,FUNC ;SELECT DRIVE FUNCTION MOV R1,UNIT ;STORE THE UNIT CLR CS1 ;CLEAR THE STATUS WORD MOV #NOCHK,ISTAT ;NO ERROR CHECKING CALL DSKIO ;PERFORM THE FUNCTION MOV RKDS(R5),R0 ;GET THE DRIVE STATUS REGISTER BIC #DDT!VV,R0 ;DON'T WORRY ABOUT DRIVE TYPE CMP #SVAL!DRDY!DRA,R0 ;CHECK FOR GOOD DRIVE STATUS BEQ 2$ ;IF EQ - WE'RE OK SEC ;INDICATE WRITE LOCK 2$: RETURN ; ; FORMAT ROUTINE ENTRY POINT ; ENTRY$ DM ;ENTRY POINT MOV CSR1DM,R5 ;R5 ALWAYS POINTS AT THE DM CSR MOV SP,ABFMT ;SAVE RETURN FOR ABORT MOV R1,UNIT ;SAVE THE DEVICE UNIT NUMBER CALL INIT ;INITIALIZE THE DEVICE AND PARAMETERS BCS EXIT ;IF CS FATAL ERROR - ABORT FORMATTING CALL RMBSF ;READ MANUFACTURERS BAD SECTOR FILE BCS EXIT ;IF CS FATAL ERROR - ABORT FORMATTING CLR CYL ;BEGIN AT BEGINNING : CYLINDER 0 CLR TRK ; TRACK 0 CLR SEC ; SECTOR 0 1$: CALL BLDHDR ;BUILD HEADERS FOR A TRACK CALL WRTHDR ;WRITE HEADERS FOR A TRACK CALL WRTDAT ;WRITE DATA FOR A TRACK CALL WRTCHK ;WRITE CHECK A TRACK CALL TSTUP ;TEST AND UPDATE DISK PARAMETERS BCC 1$ ;IF CC THEN MORE TRACKS TO FORMAT CALL SWBDSC ;WRITE SOFTWARE BAD SECTOR FILE CALL REPORT ;REPORT BAD SECTOR TABLES CLC ;INDICATE SUCCESS RETURN EXIT: MOV ABFMT,SP ;RESET THE STACK TO ENTRY POINT SEC ;INDICATE ERROR RETURN .SBTTL INITIALIZE DEVICE AND PARAMETERS ;+ ; ;INIT - INITIALIZE DEVICE AND PARAMETERS ; ; 1. ALLOCATE BUFFER SPACE ; 2. DETERMINE DRIVE TYPE ; 3. INITIALIZE PARAMETERS ; 4. INITIALIZE DEVICE ; 5. DETERMINE IF DEVICE IS READY ; ; RO,R1 DESTROYED ; ;- INIT: MOV R2,R1 ;COPY THE FREE AREA POINTER ADD #2204,R1 ;ADD SIZE OF BUFFERING SPACE NEEDED .SETTOP R1 ;PUT IN THE REQUEST CMP R0,R1 ;DID WE GET IT BHIS 1$ ;IF HIS YES CONTINUE $ERROR #$SERR3,F ;'?INSUFFICIENT MEMORY' ;MG1 BR 4$ ;IT'S A FATAL ERROR 1$: MOV R2,MBSFB ;ADDRESS OF THE MANUFACTURER'S BUFFER ADD #1000,R2 ; FOR BAD BLOCKS - 256. WORDS MOV R2,SBSFB ;ADDRESS OF THE SOFTWARE BUFFER FOR ADD #1000,R2 ; BAD BLOCKS MOV R2,HDRBUF ;ADDRESS OF THE FORMAT HEADER BUFFER MOV #SELDRV,FUNC ;STORE SELECT DRIVE FUNCTION CLR CS1 ;CLEAR RK06/07 STATUS WORD MOV #NOCHK,ISTAT ;NO ERROR CHECK CALL DSKIO ;PERFORM THE FUNCTION MOV #CYL06,MAXCYL ;ASSUME IT'S RK06 BIT #DDT,RKDS(R5) ;CHECK IF IT IS RK06/07 ? BEQ 2$ ;IF EQ IT IS RK06 BIS #CDT,CS1 ;INDICATE IT IS RK07 MOV #CYL07,MAXCYL ;GET CORRECT CYLINDER SIZE FOR RK07 2$: MOV #256.,R0 ;256 WORDS TO INIT SOFTWARE ; BAD BLOCK TABLE MOV SBSFB,R1 ;GET START OF BUFFER 3$: MOV #177777,(R1)+ ;INIT ALL LOCATIONS DEC R0 ;DONE ? BNE 3$ ;IF NE NO MOV #PACK,FUNC ;STORE PACK ACKNOWLEDGE FUNCTION CALL DSKIO ;PERFORM THE FUNCTION MOV RKDS(R5),R0 ;GET THE DRIVE STATUS REGISTER BIC #DDT,R0 ;DON'T WORRY ABOUT DRIVE TYPE CMP #SVAL!DRDY!VV!DRA,R0 ;CHECK FOR GOOD DRIVE STATUS BEQ 5$ ;IF EQ GOOD $ERROR #$SERR1,F ;'?DRIVE NOT READY' ;MG1 4$: SEC ;INDICATE ERROR 5$: RETURN ;EXIT .SBTTL READ MANUFACTURER'S BAD SECTOR FILE ;+ ; ; RMBSF - READ THE MANUFACTURER'S BAD SECTOR FILE(MBSF) ; ; THIS ROUTINE WILL READ THE MBSF LOCATED ON THE LAST ; CYLINDER, LAST TRACK, SECTOR 0,2,4,6, OR 8. AT LEAST ONE SECTOR MUST ; CONTAIN A VALID MBSF OR ERROR MESSAGES ARE OUTPUT. ; ; INPUTS : MAXCYL,MAXTRK,MBSSZ ARE PRESET ; ; OUTPUTS: MBSFB = BUFFER CONTAIN A VALID MBSF ; ; IF C = 0 SUCCESSFUL READ OF MBSF ; IF C = 1 UNSUCCESSFUL READ OF MBSF ;RO,R1 DESTROYED ; ;- RMBSF: MOV #256.,WDCNT ;SET NUMBER OF WORDS IN ONE SECTOR MOV MAXCYL,CYL ;GET THE DISK ADDRESS OF MBSF MOV MAXTRK,TRK ;LAST TRACK CLR SEC ;SEC 0 MOV MBSFB,IOBUF ;GET ADDRESS TO STORE THE FILE CLR ISTAT ;CLEAR STATUS WORD MOV #RDATA,FUNC ;SET READ FUNCTION MOV MBSSZ,R1 ;GET NUMBER OF BLOCKS IN MBSF 1$: CALL DSKIO ;READ THE MBSF BCC 2$ ;IF CC SUCCESSFUL READ ADD #2,SEC ;TRY NEXT USABLE SECTOR DEC R1 ;MORE MBSF AVAILABLE ? BNE 1$ ;IF NE YES $ERROR #MSG1,F ;'?ERROR READING...' ;MG1 BR 5$ ;ERROR EXIT 2$: MOV MBSFB,R1 ;GET ADDRESS OF MAN. BAD BUFFER TST (R1)+ ;IS SERIAL NUMBER NON-ZERO ? BNE 4$ ;IF NE YES TST (R1) ;MAYBE ? BNE 4$ ;IF NE YES 3$: $ERROR #MSG2,F ;'?MANUFACTURER'S BAD BLOCK...' ;MG1 BR 5$ ;ERROR EXIT 4$: CMP (R1)+,(R1)+ ;POINT TO THE ALIGNMENT DISK FLAG MOV (R1),R0 ;GET THE FLAG BEQ 6$ ;IF EQ IT IS GOOD INC R0 ;IS IT ALL 1'S ? BNE 3$ ;IF NE IT'S CORRUPT $ERROR #MSG3,U ;'?DISK IS AN ALIGNMENT...' ;MG1 5$: SEC ;INDICATE ERROR BR 7$ ;RETURN 6$: CLC ;SHOW SUCCESSFUL 7$: RETURN .SBTTL BUILD A TRACK OF HEADERS ;+ ; ;BLDHDR - BUILD A TRACK OF HEADERS FOR RK06/07. THE GOOD SECTOR FLAG, ; BIT 15 OF THE SECOND HEADER WORD, IS RESET IF THE SECTOR IS ; LISTED IN MANUFACTURER'S BAD SECTOR FILE. ; ; INPUTS : CYL,TRK,SEC ; ; OUTPUTS : HDRBUF - BUFFER OF HEADERS FOR A TRACK ; ;R0-R4 DESTROYED ; ;- BLDHDR: MOV HDRBUF,R4 ;GET THE ADDRESS OF THE HEADER BUFFER MOV CYL,R1 ;GET CYLINDER MOV TRK,R2 ; TRACK MOV SEC,R3 ; SECTOR 1$: MOV R1,(R4)+ ;MOVE WORD #1 MOV R2,R0 ;START TO FORM WORD #2 SWAB R0 ;POSITION TRACK ADDRESS ASR R0 ;... INTO BITS 7-5 ASR R0 ;... ASR R0 ;... BIS R3,R0 ;INCLUDE SECTOR ADDRESS BIS #140000,R0 ;MERGE GOOD SECTOR FLAG MOV R0,(R4)+ ;STORE WORD #2 MOV R0,-(SP) ;START TO FORM WORD #3 MOV R1,-(SP) ; BIC (SP),2(SP) ;THIS FORMS THE CHECK WORD BIC R0,(SP) ; BIS (SP)+,(SP) ;CHECK WORD = WORD #1 XOR WORD #2 MOV (SP)+,(R4)+ ;STORE CHECK WORD AS WORD #3 INC R3 ;INCREMENT THE SECTOR CMP R3,MAXSEC ;ENTIRE TRACK DONE ? BLOS 1$ ;IF LOS NO ;RESET THE BAD SECTOR FLAGS IF SECTOR IS IN MBSF MOV MBSFB,R1 ;GET THE MBSF BUFFER ADDRESS CMP (R1)+,(R1)+ ;POINT TO START OF THE ENTRIES(MBSF+4) 2$: CALL SMBSF ;SEARCH MBSF BCS 3$ ;IF CS MBSF EXHAUSTED MOVB 2(R1),R4 ;GET SECTOR NUMBER MOV R4,R2 ;COPY IT ASL R2 ;MULTIPLY IT X2 ASL R2 ; X4 ADD R4,R2 ; X5 ADD R4,R2 ; X6 ADD HDRBUF,R2 ;MAKE IT A VALID ADDRESS TST (R2)+ ;POINT TO SECOND WORD IN THE HEADER BIC #100000,(R2)+ ;RESET BIT 15 - BAD SECTOR ENTRY BIC #100000,(R2) ;CHANGE THE CHECK WORD BIT 15 BR 2$ ;CONTINUE SEARCH 3$: RETURN .SBTTL WRITE A TRACK OF HEADERS ;+ ; ; WRTHDR - WRITE A TRACK OF HEADERS. ANY ERRORS ENCOUNTERED ARE RETRIED ; 8 TIMES. IF ERROR PERSISTS - FORMATTING IS ABORTED, THE DISK IS ; NOT FORMATTABLE. ; ; INPUTS : HDRBUF - BUFFER OF HEADERS TO BE WRITTEN ; ;- WRTHDR: MOV #10,RETCNT ;8 RETRIES ALLOWED CLR SEC ;START AT SECTOR 0 1$: CLR ISTAT ;CLEAR STATUS BITS MOV #WHEAD,FUNC ;SET THE WRITE HEADER FUNCTION MOV HDRBUF,IOBUF ;SET THE WRITE BUFFER ADDRESS MOV #66.,WDCNT ;SET THE WORD COUNT CALL DSKIO ;WRITE A TRACK OF HEADERS BCC 2$ ;IF CC NO ERRORS DEC RETCNT ;ANY RETRIES LEFT? BNE 1$ ;IF NE YES $ERROR #MSG4,F ;'?ERROR WRITING HEADERS...' ;MG1 JMP EXIT ;ABORT FORMAT 2$: RETURN .SBTTL WRITE DATA TO A TRACK ;+ ; ;WRDAT - THIS ROUTINE WRITES 256 WORDS TO EACH SECTOR OF A TRACK. ; IF THE WRITE FAILS, THE SECTOR WHICH CAUSED THE FAILURE IS RETRIED 8 ; TIMES. IF ERROR PERSISTS THE SECTOR IS MARKED BAD,LISTED IN ; THE SOFTWARE BAD BLOCK FILE, NEW HEADERS ARE WRITTEN AND DATA WRITING ; CONTINUES. IF THE SECTOR HAS BEEN MARKED BAD AND AN ERROR OCCURS, ; THE LOCATION OF THE BAD SECTOR IS OUTPUT AND FORMATTING IS ABORTED ; ; INPUTS: CYL,TRK - CYLINDER AND TRACK TO BE WRITTEN ; ;R0 DESTROYED ; ;- WRTDAT: CLR SEC ;START WITH SECTOR ZERO MOV #WDATA,FUNC ;SET THE WRITE DATA FUNCTION MOV #^D<256.*22.>,WDCNT ;SET THE WORD COUNT FOR A TRACK MOV #DATBUF,IOBUF ;SET THE ADDRESS OF THE WRITE BUFFER MOV #INHINC,ISTAT ;INHIBIT THE BUS ADDRESS INCREMENT 1$: CALL DSKIO ;PERFORM THE FUNCTION BCC 30$ ;IF CC NO ERRORS EXIT MOV #10,RETCNT ;8 RETRIES PER SECTOR MOV RKWC(R5),R0 ;GET THE REMAINING WORD COUNT BIC #377,R0 ;CLEAR THE PARTIAL COUNT ADD #400,R0 ;BUMP TO THE NEXT SECTOR MOV R0,TMPWC ;STORE WORD COUNT FOR LATER MOV RKDA(R5),R0 ;GET THE DISK ADDRESS REGISTER BIC #177740,R0 ;MASK THE BAD SECTOR MOV R0,SEC ;STORE THE SECTOR FOR LATER BIT #BSE,RKER(R5) ;CHECK IF BAD SECTOR ERROR BNE 20$ ;IF NE YES - WRITE REMAINDER OF TRACK MOV #400,WDCNT ;SET WORD COUNT FOR ONE SECTOR 5$: CALL DSKIO ;WRITE TO THAT SECTOR BCC 20$ ;IF CC NO ERRORS CONTINUE DEC RETCNT ;CHECK IF RETRIES LEFT ? BNE 5$ ;IF NE, YES CALL BADSEC ;CHECK IF SECTOR MARKED BAD BCS 10$ ;IF CS YES CALL WRTHDR ;REWRITE THE HEADERS BR WRTDAT ;CONTINUE THE VERIFICATION SEQUENCE 10$: BIT #HVRC,RKER(R5) ;HEADER CHECK ERROR ? BNE 20$ ;IF NE YES, CONTINUE $ERROR #MSG6,F ;'?BAD SECTOR...' ;MG1 JMP EXIT ;EXIT QUICKLY ;WRITE THE REMAINDER OF TRACK AFTER THE TROUBLESOME SECTOR 20$: INC SEC ;INCREMENT THE SECTOR NUMBER CMP SEC,MAXSEC ;ALL SECTORS DONE ? BGT 30$ ;IF GT, YES MOV TMPWC,WDCNT ;SET THE REMAINING TRACK WORD COUNT NEG WDCNT ;PASS THE POSITIVE WORD COUNT BR 1$ ;GO SET UP AND PERFORM THE WRITE 30$: RETURN .SBTTL WRITE CHECK A TRACK ;+ ; ;WRTCHK - THIS ROUTINE READS AND CHECKS THE DATA PREVIOUSLY WRITTEN ; TO THE TRACK. IF AN ERROR IS ENCOUNTERED THE SECTOR IN ERROR IS RETRIED ; 8 TIMES. IF THE ERROR PERSISTS THE SECTOR IS MARKED BAD, INSERTED ; IN SOFTWARE BAD BLOCK TABLE,THE HEADERS ARE REWRITTEN, THE DATA ; IS REWRITTEN, AND WRITE CHECK REINITIATED. IF THE SECTOR IS MARKED ; BAD AND AN ERROR IS DETECTED THE LOCATION OF THE BAD SECTOR IS ; OUTPUT AND FORMATTING IS ABORTED. ; ; INPUTS : CYL,TRK = LOCATION OF THE TRACK TO BE WRITTEN ; ;R0 DESTROYED ; ;- WRTCHK: CLR SEC ;START WITH SECTOR 0 MOV #WCHECK,FUNC ;SET THE WRITE CHECK FUNCTION MOV #^D<256.*22.>,WDCNT ;SET THE WORD COUNT FOR A TRACK MOV #INHINC,ISTAT ;INHIBIT BUS ADDRESS INCREMENT 1$: CALL DSKIO ;PERFORM THE FUNCTION BCC 30$ ;IF CC NO ERROR MOV #10,RETCNT ;8 RETRIES PER SECTOR MOV RKWC(R5),TMPWC ;STORE THE WORD COUNT BIC #377,TMPWC ;CLEAR THE PARTIAL COUNT MOV RKDA(R5),R0 ;GET THE DISK ADDRESS REGISTER BIC #177740,R0 ;MASK THE BAD SECTOR MOV R0,SEC ;STORE THE SECTOR FOR LATER BIT #BSE,RKER(R5) ;CHECK IF BAD SECTOR ERROR BNE 25$ ;IF NE YES BIT #OPI!HVRC,RKER(R5) ;HEADER ERROR OR ; OPERATION INCOMPLETE ? BNE 12$ ;IF NE YES BIT #DCK,RKER(R5) ;DATA CHECK ERROR ? BEQ 10$ ;IF EQ NO SUB #400,TMPWC ;CORRECT THE WORD COUNT 10$: DEC R0 ;BACK UP A SECTOR BPL 12$ ;IF PL OK MOV MAXSEC,R0 ;ELSE GET THE LAST SECTOR 12$: MOV R0,SEC ;STORE THE SECTOR NUMBER MOV #400,WDCNT ;SET THE WORD COUNT FOR 1 SECTOR 13$: CALL DSKIO ;WRITE CHECK ON THAT SECTOR BCC 25$ ;IF CC NO ERRORS - CONTINUE DEC RETCNT ;CHECK IF ANY RETRIES LEFT ? BNE 13$ ;IF NE YES - RETRY CALL BADSEC ;SECTOR MARKED BAD ? BCS 15$ ;IF CS YES CALL WRTHDR ;REWRITE THE HEADERS FOR THAT TRACK CALL WRTDAT ;REWRITE THE DATA BR WRTCHK ;RESTART THE WRITE CHECK 15$: BIT #HVRC,RKER(R5) ;HEADER CHECK ERROR ? BNE 25$ ;IF NE YES CONTINUE $ERROR #MSG6,F ;'?BAD SECTOR...' ;MG1 JMP EXIT ;EXIT QUICKLY ;WRITE CHECK THE REMAINDER OF THE TRACK AFTER THE TROUBLESOME SECTOR 25$: INC SEC ;BUMP THE SECTOR NUMBER CMP SEC,MAXSEC ;CHECK IF ALL SECTORS DONE ? BGT 30$ ;IF GT YES ADD #400,TMPWC ;FIX WORD COUNT MOV TMPWC,WDCNT ;SET WORD COUNT NEG WDCNT ;PASS POSITIVE COUNT BR 1$ ;GO TO IT 30$: RETURN .SBTTL TEST AND UPDATE DISK PARAMETERS ;+ ; ; TSTUP - TEST FOR END OF DISK AND UPDATE DISK PARAMETERS ; ; INPUTS: CYL = CURRENT CYLINDER NUMBER ; TRK = CURRENT TRACK NUMBER ; SEC = CURRENT SECTOR NUMBER ; ;OUTPUTS: IF C=1 UPDATED PARAMETERS EXCEED DISK LIMITS ; IF C=0 UPDATED PARAMETERS ARE STILL VALID ; SEC IS SET TO ZERO ; ;- TSTUP: CLR SEC ;START WITH SECTOR ZERO INC TRK ;UPDATE TRACK NUMBER 1$: CMP MAXCYL,CYL ;ON THE LAST CYLINDER ? BNE 2$ ;IF NE NO CMP MAXTRK,TRK ;LAST TRACK ? BEQ 5$ ;IF EQ YES 2$: CMP TRK,MAXTRK ;IS TRACK NUMBER EXCEEDED? BLE 4$ ;IF LE NO CLR TRK ;RESET TRACK NUMBER INC CYL ;UPDATE CYLINDER NUMBER CMP CYL,MAXCYL ;IS CYLINDER NUMBER EXCEEDED ? BGT 5$ ;IF GT YES 4$: CLC ;INDICATE VALID PARAMETERS RETURN 5$: SEC ;INDICATE PARAMETERS EXCEEDED RETURN .SBTTL WRITE SOFTWARE BAD SECTOR FILE ;+ ; ;SWBDSC - OUTPUT THE SOFTWARE BAD SECTOR FILE TO SECTORS ; 10,12,14,16,18,20 OF THE LAST CYLINDER,TRACK. ; ; INPUTS : SBSFB = SOFTWARE BAD SECTOR FILE TO BE WRITTEN ; MAXCYL,MAXTRK = MAX NUMBER OF CYLINDERS AND TRACKS ON DEVICE ; ;- SWBDSC: MOV #4,R0 ;COPY 1ST 4 WORDS (MBSFB --> SBSFB) MOV MBSFB,R1 ;GET ADDRESS OF MBSFB MOV SBSFB,R2 ;GET ADDRESS OF SBSFB 1$: MOV (R1)+,(R2)+ ;COPY IT DEC R0 ;ALL DONE YET BNE 1$ ;NOPE MOV #WDATA,FUNC ;SET THE WRITE DATA FUNCTION CLR ISTAT ;CLEAR STATUS FLAGS MOV #400,WDCNT ;BLOCK OF DATA MOV SBSFB,IOBUF ;SET ADDRESS OF THE SBSF MOV MAXCYL,CYL ;GET THE LAST CYLINDER MOV MAXTRK,TRK ;GET THE LAST TRACK MOV #10.,SEC ;START WILTH SECTOR 10 MOV #6,R1 ;6 SECTORS TO BE WRITTEN 4$: MOV #10,RETCNT ;8 RETRIES PER SECTOR 5$: CALL DSKIO ;PERFORM THE WRITE BCC 10$ ;IF CC SUCCESSFUL DEC RETCNT ;CHECK IF RETRIES LEFT ? BNE 5$ ;IF NE YES $ERROR #MSG8,F ;'?ERROR WRITING SOFTWARE BAD...' ;MG1 CALL MSGLOC ;INDICATE LOCATION 10$: ADD #2,SEC ;CONTINUE WITH NEXT SECTOR DEC R1 ;CHECK IF MORE SECTORS TO DO BNE 4$ ;IF NE YES RETURN .SBTTL REPORT BAD SECTORS ;+ ; ;REPORT - OUT LISTING OF BAD BLOCKS FROM THE MANUFACTURER'S BAD SECTOR ; FILE AND FROM THE SOFTWARE BAD SECTOR FILE. ; ; INPUTS : MBSFB = MANUFACTURER'S BAD SECTOR FILE ; SBSFB = SOFTWARE BAD SECTOR FILE ; ;R0 DESTROYED ; ;- REPORT: .PRINT #MSGMAN ;MANUFACTURER'S BAD SECTOR FILE MOV MBSFB,R0 ;PASS ADDRESS OF THE BAD SECTOR BUFFER CALL OUTTBL ;OUTPUT THE TABLE .PRINT #MSGSOF ;SOFTWARE BAD SECTOR FILE MOV SBSFB,R0 ;PASS ADDRESS OF BAD SECTOR BUFFER CALL OUTTBL ;OUTPUT THE ENTRIES RETURN OUTTBL: ADD #10,R0 ;POINT TO THE START OF THE ENTRIES MOV R0,-(SP) ;PUT IT ON THE STACK ADD #1000-10,(SP) ;COMPUTE THE END OF THE TABLE 1$: CMP (R0),#-1 ;END OF ENTRIES BEQ 2$ ;IF EQ YES MOV (R0)+,CYL ;GET THE FIRST WORD BIC #100000,CYL ;MASK THE CYLINDER MOVB (R0),SEC ;GET THE SECTOR MOV (R0)+,TRK ;GET THE SECOND WORD BIC #140377,TRK ;MASK TRACK SWAB TRK ;GET TRACK CALL MSGLOC ;OUTPUT THE LOCATION CMP R0,(SP) ;END OF TABLE ? BLO 1$ ;IF LO NO 2$: TST (SP)+ ;PRUNE THE STACK RETURN .SBTTL RK06/07 FORMATTING SUBROUTINES ;+ ; ;DSKIO - I/O TO DISK CONTROLLER ; ; 1. SETS UP DEVICE REGISTERS ; 2. PERFORMS SPECIFIED FUNCTION ; 3. HANDLES ERRORS ; ; INPUTS : FUNC = FUNCTION TO BE PERFORMED ; IOBUF = I/O BUFFER ADDRESS ; WDCNT = WORD COUNT (POSITIVE) ; CYL = CYLINDER ; TRK = TRACK ; SEC = SECTOR ; CS1 = CONTROL AND STATUS BITS ; ISTAT = INPUT STATUS SELECTION BITS ; BIT 0 = 1 (NO ERROR CHECKING) ; BIT 1 = 1 (INHIBIT BUS ADDRESS INCREMENT) ; ;OUTPUTS : IF C = 0 SUCCESSFUL FUNCTION PERFORMED ; IF C = 1 DATA ERROR OCCURRED ; NOTE : IF DEVICE ERROR OCCURS THIS ROUTINE PRINTS ; MESSAGE AND ABORTS FORMATTING ;R0 DESTROYED ; ;- DSKIO: MOV #3,RETERR ;3 RETRIES ON SOFT ERRORS 1$: MOV #SCLR,RKCS2(R5) ;PERFORM SUBSYTEM CLEAR ; DETERMINE THE CLASS OF FUNCTION TO BE PERFORMED CMP #RDATA,FUNC ;CHECK IF IT'S TRANSFER FUNCTION BGT 4$ ;IF GT NO ITS DRIVE COMMAND ; SET UP THE DEVICE REGISTERS MOV IOBUF,RKBA(R5) ;LOAD THE BUS ADDRESS REGISTER MOV WDCNT,RKWC(R5) ;LOAD THE WORD COUNT REGISTER NEG RKWC(R5) ;RKWC IS 2'S COMPLEMENT OF WORD COUNT MOV CYL,RKDC(R5) ;LOAD THE DISK CYLINDER REGISTER MOV TRK,R0 ;GET THE TRACK NUMBER SWAB R0 ; INTO BITS 10-8 BIS SEC,R0 ;SECTOR INTO BITS 4-0 MOV R0,RKDA(R5) ;LOAD THE DISK ADDRESS REGISTER 4$: MOV UNIT,R0 ;GET THE UNIT NUMBER BIT #INHINC,ISTAT ;CHECK IF INCREMENT INHIBIT BEQ 5$ ;IF EQ NO BIS #BAI,R0 ;SET BUS ADDRESS INCREMENT INHIBIT 5$: MOV R0,RKCS2(R5) ;STORE CONTROL AND STATUS REGISTER 2 MOV CS1,R0 ;GET TEMP CONTROL AND STATUS REGISTER BIS FUNC,R0 ;PUT THE FUNCTION IN BITS 4-0 ; PERFORM THE FUNCTION MOV R0,(R5) ;PERFORM THE FUNCTION 10$: BIT #RDY!CERR,(R5) ;WAIT FOR READY OR ERROR BEQ 10$ ;IF EQ CONTINUE TO WAIT BIT #NOCHK,ISTAT ;ANY ERROR CHECKING TO BE PERFORMED BEQ 11$ ;IF EQ YES CLC ;CLEAR CARRY BR 30$ ;RETURN 11$: BIT #CERR,(R5) ;ANY ERRORS? BNE 12$ ;IF NE YES CLC ;INDICATE SUCESS BR 30$ ;RETURN ; ; ERROR HANDLER ; ; 1. CHECK IF FATAL DEVICE ERROR ; 12$: BIT #FATAL1,RKER(R5) ;FATAL ERROR ? BNE 20$ ;IF NE YES BIT #FATAL2,RKCS2(R5) ;FATAL ERROR ? BNE 20$ ;IF NE YES ; 2. CHECK IF DATA ERROR OCCURRED BIT #BSE!HVRC!DCK!OPI,RKER(R5) ;DATA ERROR ? BNE 25$ ;IF NE YES BIT #WCE,RKCS2(R5) ;DATA ERROR BNE 25$ ;IF NE YES ; 3. THEN IT MUST BE A SOFT ERROR - RETRY DEC RETERR ;DECREMENT THE SOFT ERROR RETRY COUNT BEQ 20$ ;IF EQ - RUN OUT OF RETRIES - ABORT BIT #SKI,RKER(R5) ;CHECK IF RECALIBRATION REQUIRED BEQ 16$ ;IF EQ NO MOV CS1,R0 ;GET CONTROL AND STATUS INFO BIS #RECAL,R0 ;INSERT RECALIBRATION FUNCTION ; INTO BITS 4-0 MOV R0,(R5) ;PERFORM THE FUNCTION 15$: BIT #CERR!RDY,(R5) ;CHECK IF DONE BEQ 15$ ;IF EQ CONTINUE TO WAIT BIT #CERR,(R5) ;ANY ERROR ? BNE 20$ ;IF NE YES, ABORT 16$: BR 1$ ;RETRY THIS FUNCTION 20$: $ERROR #$SERR2,F ;'?DEVICE ERROR...' ;MG1 JMP EXIT ;ABORT FORMATTING 25$: SEC ;INDICATE ERROR 30$: RETURN ;+ ; ; SMBSF - SEARCH THE MANUFACTURERER'S BAD SECTOR FILE ; ; THIS ROUTINE WILL SEARCH THE MBSF FOR A MATCH. IF ONE IS FOUND, THE ; ADDRESS OF THE ENTRY IS RETURNED. ; ; ; INPUTS: R1 = ADDRESS OF LAST MBSF ENTRY SEARCHED (INITIALLY MBSF+4) ; CYL AND TRK ARE PRESET ; ; OUTPUTS: IF C=0 R1= ADDRESS OF MBSF ENTRY FOUND ; ENTRY FOUND ; IF C=1 R1 = DESTROYED ; MBSF EXHAUSTED ; ;- SMBSF: CMP (R1)+,(R1)+ ;POINT TO THE NEXT ENTRY CMP (R1),#-1 ;MBSF EXHAUSTED ? BEQ 3$ ;IF EQ YES BIC #170000,(R1) ;CLEAR ANY FLAG BITS CMP (R1),CYL ;CYLINDER NUMBERS MATCH ? BNE 2$ ;IF NE NO MOV 2(R1),-(SP) ;SAVE FLAGS,SECTOR,+ TRACK BIC #140377,(SP) ;ISOLATE THE TRACK NUMBER SWAB (SP) ;POSITION IT CMP (SP)+,TRK ;TRACK NUMBERS MATCH ? BNE 2$ ;IF NE NO CLC ;SHOW ENTRY WAS FOUND BR 4$ ;EXIT 2$: MOV MBSFB,-(SP) ;COMPUTE THE END OF THE BUFFER ADD #774,(SP) CMP R1,(SP)+ ;IS MBSF EXHAUSTED ? BLO SMBSF ;IF LO NO 3$: SEC ;SHOW MBSF EXHAUSTED 4$: RETURN ;EXIT ;+ ; ;BADSEC - CHECKS IF A SECTOR HAS BEEN MARKED BAD. IF MARKED BAD CARRY ; BIT IS SET, ELSE THE SECTOR IS MARKED BAD AND INSERTED IN ; SOFTWARE BAD SECTOR FILE. ; ; INPUTS : SEC = SECTOR TO BE CHECKED ; ; OUTPUTS : IF C = 0 SECTOR JUST MARKED BAD AND INSERTED IN SBSF ; IF C = 1 SECTOR WAS MARKED BAD ON ENTRY ; ; R0,R1,R2 DESTROYED ; ;- BADSEC: MOV SEC,R1 ;GET THE SECTOR NUMBER MOV R1,R2 ;COPY IT ASL R1 ;MULTIPLY X2 ASL R1 ; X4 ADD R2,R1 ; X5 ADD R2,R1 ; X6 ADD HDRBUF,R1 ;MAKE IT VALID ADDRESS TST (R1)+ ;POINT TO SECOND WORD IN THE HEADER MOV (R1),R2 ;GET THE SECOND WORD BIC #37777,R2 ;ISOLATE GOOD SECTOR FLAGS CMP #140000,R2 ;CHECK IF SECTOR MARK GOOD ? BNE 3$ ;IF NE NO ; THE GOOD SECTOR FLAGS SHALL NOW BE RESET BIC #40000,(R1) ;RESET GOOD SECTOR FLAG (SOFTWARE) BIC #40000,2(R1) ;FIX UP WORD 3 OF HEADER MOV SBSFB,R0 ;GET THE 1ST ENTRY ADD #10,R0 1$: CMP (R0)+,#-1 ;CHECK IF EMPTY ENTRY ? BEQ 2$ ;IF EQ YES TST (R0)+ ;POINT PAST SECOND WORD OF ENTRY CMP R0,HDRBUF ;END OF TABLE ? BLO 1$ ;NOPE $ERROR #MSG7,U ;'?TOO MANY BAD BLOCKS...' ;MG1 JMP EXIT ;ABORT FORMATTING 2$: TST -(R0) ;BACK UP TO FREE ENTRY MOV CYL,(R0)+ ;STORE THE 1ST WORD OF ENTRY MOV TRK,R1 ;PUT TRACK IN BITS 15-8 SWAB R1 BIS SEC,R1 ;PUT SECTOR IN BITS 7-0 MOV R1,(R0) ;STORE THE 2ND WORD CLC ;INDICATE SUCCESS BR 4$ ;RETURN 3$: SEC ;INDICATE ALREADY BAD 4$: RETURN ;+ ; ; MSGLOC - OUTPUT THE CURRENT DISK ADDRESS AS OCTAL 6 DIGIT BLOCK NUMBER ; ; INPUTS : CYL,TRK,SEC = CURRENT DISK ADDRESS ; ;NO REGISTERS DESTROYED ; ;- MSGLOC: JSR R5,$SVRG ;SAVE REGISTERS R0-R5 CALL CVTLBN ;CONVERT TO LOGICAL BLOCK NUMBER MOV R0,R1 ;COPY BLOCK NUMBER CLR R5 ;DON'T SUPPRESS LEADING ZER0S MOV #CHRBUF,R0 ;SET THE CHARACTER OUTPUT BUFFER CALL $CNVRT ;CONVERT WORD, DON'T SUPPRESS ; LEADING ZEROS CLRB (R0) ;CLOSE OFF THE CHARACTER STRING .PRINT #CHRBUF ;PRINT THE NUMBER JSR R5,$RSTRG ;RESTORE RO - R5 RETURN ; ; CVTLBN - CONVERT TO LOGICAL BLOCK NUMBER ; CVTLBN: MOV CYL,R0 ;CYLINDER X TRACKS/CYLINDER MOV MAXTRK,R1 INC R1 ;R1=TRACKS/CYLINDER CALL MULT ADD TRK,R0 ; + TRACK MOV MAXSEC,R1 ; X SECTORS/TRACK INC R1 ;R1=SECTORS/TRACK CALL MULT ADD SEC,R0 ; + SECTOR RETURN ; ; MULT - R0 * R1 = R0 ; R1 ASSUMED >0 ON ENTRY AND DESTROYED ON EXIT ; MULT: MOV R0,-(SP) ;SAVE MULTIPLIER CLR R0 ;ZERO THE RESULT 1$: ADD (SP),R0 ;ADD IN MULTIPLIER DEC R1 ;DECREMENT MULTIPLICAND BNE 1$ ;IF MORE CONTINUE TST (SP)+ ;FIX THE STACK RETURN .SBTTL DMFMT DATA AREA .PSECT PUREDATA,RO,D CSR1DM::.WORD DM$CSR ;PATCH THIS WORD IF PROBLEM DATBUF: .WORD 052525 ;DATA PATTERN .ENABL LC .NLIST BEX MSG1: .ASCIZ /Error reading manufacturer's bad sector file/ MSG2: .ASCIZ /Manufacturer's bad sector file corrupt/ MSG3: .ASCIZ /Disk is an alignment cartridge/ MSG4: .ASCIZ /Error writing headers/ MSG6: .ASCIZ /Bad sector/ MSG7: .ASCIZ /Too many bad blocks/ MSG8: .ASCIZ /Error writing software bad block file/ MSGMAN: .ASCIZ /MANUFACTURER'S BAD BLOCK TABLE/ MSGSOF: .ASCIZ /SOFTWARE BAD BLOCK TABLE/ .EVEN .LIST BEX .DSABL LC .PSECT DATA,RW,D MAXCYL: .WORD 0 ;MAX CYLINDER MAXTRK: .WORD 2. ;MAX TRACK MAXSEC: .WORD 21. ;MAX SECTOR MBSSZ: .WORD 5. ;SIZE OF MBSF MBSFB: .WORD 0 ;MBSF BUFFER ADDRESS SBSFB: .WORD 0 ;SBSF BUFFER ADDRESS HDRBUF: .WORD 0 ;HEADER BUFFER ADDRESS CYL: .WORD 0 ;CURRENT CYLINDER TRK: .WORD 0 ;CURRENT TRACK SEC: .WORD 0 ;CURRENT SECTOR FUNC: .WORD 0 ;FUNCTION TO PERFORM CS1: .WORD 0 ;CONTROL AND STATUS TEMP REG 1 WDCNT: .WORD 0 ;NUMBER OF WORDS TO TRANSFER IOBUF: .WORD 0 ;ADDRESS OF I/0 BUFFER UNIT: .WORD 0 ;DEVICE UNIT NUMBER ISTAT: .WORD 0 ;INPUT STATUS TO DSKIO RETCNT: .WORD 0 ;RETRY COUNT RETERR: .WORD 0 ;SOFT ERROR RETRY COUNT ABFMT: .WORD 0 ;ABORT ADDRESS TMPWC: .WORD 0 ;TEMPORARY WORD COUNT DURING RETRIES CHRBUF: .BLKW 4 ;CHARACTER OUTPUT BUFFER .END