Trailing-Edge
-
PDP-10 Archives
-
BB-H311B-RM
-
swskit-utilities/filadr.mac
There are 2 other files named filadr.mac in the archive. Click here to see a list.
TITLE FILADR TYPES OUT ADDRESSES A FILE IS USING
;WRITTEN BY DAVID I. BELL AT DIGITAL IN MARLBORO.
;THIS PROGRAM WILL TYPE OUT THE ADDRESSES OF EACH PAGE OF A FILE
;WHICH IS IN USE, AND ALSO THE PAGES USED BY THE INDEX BLOCKS.
;THE PROGRAM CAN ALSO CORRELATE THE ADDRESSES WITH THE ONES
;RECORDED IN THE BAT BLOCKS. IT ALSO CAN LIST THE ADDRESSES IN
;THE BAT BLOCKS ALONE.
SEARCH MACSYM,MONSYM ;GET SYMBOLS
SALL ;NICE LOOKING MACROS
;ACCUMULATORS:
F=0 ;FLAGS
T1=1 ;TEMPORARY AC'S
T2=2
T3=3
T4=4
I=5 ;AOBJN POINTER FOR SUPER INDEX BLOCK
A=6 ;ADDRESS OF AN INDEX BLOCK IN CORE
U=7 ;LOGICAL UNIT NUMBER IN A STRUCTURE
X=10 ;ONLY FOR LUUO'S USE
P=17 ;STACK
;DEFAULT PARAMETERS:
TXTLEN==^D100 ;SIZE OF COMMAND BUFFERS
PDLSIZ==30 ;SIZE OF PUSHDOWN STACK
MXUNIT==^D20 ;NUMBER OF UNITS WE CAN HANDLE
STGADR==77,,-1 ;MASK FOR DISK ADDRESS IN A WORD
DSKBIT==10,,0 ;BIT SOMETIMES INCLUDED IN DISK ADDRESSES
PAGI=10000 ;ADDRESS OF INDEX BLOCK
PAGSI=11000 ;ADDRESS OF SUPER INDEX BLOCK
BAT==12000 ;ADDRESS TO READ IN FIRST BAT BLOCK
BAT2==12200 ;ADDRESS TO READ IN SECOND BAT BLOCK
DATA=12400 ;FIRST FREE LOCATION
;FLAGS:
FR.BB1==1 ;PRIMARY BAT BLOCK IS BAD
FR.BB2==2 ;SECONDARY BAT BLOCK IS BAD
FR.BBI==4 ;BAT BLOCKS DO NOT AGREE WITH EACH OTHER
FR.ADR==10 ;ADDRESSES ARE TO BE TYPED FOR FILES
;MACROS AND OPDEFS:
OPDEF PJRST [JRST] ;PUSHJ/POPJ
OPDEF TYPE [1B8] ;LUUO TO DO A SOUT
OPDEF OCTOUT [2B8] ;LUUO FOR OCTAL OUTPUT
OPDEF DECOUT [4B8] ;LUUO FOR DECIMAL OUTPUT
DEFINE AA(NAME,DATA),< ;;MACRO FOR COMMAND TABLES
XWD [ASCIZ/NAME/],DATA
>
DEFINE TEXT(STRING),< ;;MACRO FOR ASCIZ TEXT
XLIST
ASCIZ @STRING@
LIST
>
DEFINE ERROR(TEXT),< ;;MACRO FOR ERRORS
JRST [HRROI T1,[ASCIZ/
? TEXT/]
PSOUT
JRST LOSFIN]
>
;DEFINITIONS ASSOCIATED WITH BAT BLOCKS:
;BLOCK NUMBERS:
BATAD1==^D2 ;UNIT ADDRESS OF PRIMARY BAT BLOCK
BATAD2==^D11 ;UNIT ADDRESS OF SECONDARY BAT BLOCK
;OFFSETS IN A BLOCK:
BT.NAM==0 ;NAME OF BLOCK - SIXBIT /BAT/
BT.ADR==1 ;<- FREE WORDS>,,ADDRESS OF FIRST PAIR
BT.MAP==2 ;DATA RECORDED BY MAPPING PROGRAMS
BT.CNT==3 ;NUMBER OF PAIRS ADDED BY MONITOR
BT.FRE==4 ;FIRST PAIR OF WORDS
BT.COD==176 ;SPECIAL CODE - 606060
BT.BLK==177 ;THIS BLOCK NUMBER - 2 OR 11
;FIELDS IN THE WORD BT.MAP:
BT%NBB==777000,,0 ;NUMBER OF BAD BLOCKS FOUND BY MAP PROGRAM
BT%NBR==777,,0 ;NUMBER OF BAD REGIONS FOUND BY PROGRAM
;FIELDS IN FIRST WORD OF EACH PAIR OF ERROR WORDS:
BT%NEW==40000 ;THIS IS A NEW FORMAT PAIR OF WORDS
BT%CNT==777000,,0 ;ONE LESS THAN THE NUMBER OF CONSEQUTIVE
;BAD BLOCKS IN THIS REGION
;FIELDS IN SECOND WORD OF EACH PAIR OF ERROR WORDS:
BT%VER==700000,,0 ;VERSION NUMBER IF BT%NEW IS SET
BT%ADR==777,,-1 ;UNIT ADDRESS OF FIRST BAD BLOCK
;IN THIS REGION
BT%AD2==777777 ;UNIT ADDRESS IF BT%NEW IS OFF
;OTHER DEFINITIONS:
BT$HDR==6 ;NUMBER OF WORDS USED IN HEADERS
BT$COD==606060 ;SPECIAL CODE IN WORD 176
SUBTTL COMMAND SCANNER AND INITIALIZATION
START: MOVEI F,FR.ADR ;SET TO TYPE ADDRESSES BY DEFAULT
MOVE T1,[PUSHJ P,LUUO] ;GET INSTRUCTION
MOVEM T1,.JB41## ;AND SET UP FOR LUUOS
SETZM WIDTH ;CLEAR WIDTH ARGUMENT
MOVEI T1,.FHSLF ;GET READY
RPCAP ;READ MY CAPABILITIES
TXNN T3,SC%WHL+SC%OPR ;CAN I RUN THIS PROGRAM?
JRST NOPOWR ;NO, GO COMPLAIN
REEN: RESET ;CLEAR EVERYTHING
MOVE P,[IOWD PDLSIZ,PDL] ;SET UP A STACK
SETZM JFN ;CLEAR INPUT JFN
SETZM JFNOUT ;CLEAR OUTPUT JFN ALSO
NEWCMD: MOVEI T1,CMDBLK ;POINT TO COMMAND BLOCK
MOVEI T2,[FLDDB. .CMINI] ;INITIALIZATION FUNCTION
PUSHJ P,COMMND ;GO DO IT
MOVEM P,SAVEP ;SAVE STACK FOR REPARSING
NEWPAR: MOVE P,SAVEP ;RESTORE THE STACK
MOVEI T1,CMDBLK ;POINT TO THE COMMAND BLOCK
MOVEI T2,[FLDDB. (.CMKEY,,CMDTAB)] ;POINT TO COMMAND TABLE
PUSHJ P,COMMND ;READ IT
MOVE T2,(T2) ;GET ADDRESS OF ROUTINE
PUSHJ P,(T2) ;CALL IT
SKIPE T1,JFN ;INPUT FILES STILL OPEN?
RLJFN ;YES, CLOSE THEM
SETZM JFN ;AND CLEAR WORD
JRST NEWCMD ;AND GET A NEW COMMAND
;TABLE OF COMMANDS:
CMDTAB: CMDLEN,,CMDLEN ;HEADER
AA ADDRESS,CMDADR ;ADDRESS COMMAND
AA BAT-BLOCKS,CMDBAT ;TYPE OUT THE BAT BLOCKS
AA EXIT,CMDXIT ;EXIT COMMAND
AA FILE,CMDFIL ;GIVE ADDRESSES OF FILE
AA HELP,CMDHLP ;TYPE HELP MESSAGE
AA WIDTH,CMDWID ;SET WIDTH OF OUTPUT
CMDLEN==.-CMDTAB-1 ;NUMBER OF COMMANDS
SUBTTL THE SIMPLE COMMANDS
;EXIT FROM PROGRAM. "EXIT" COMMAND.
CMDXIT: MOVEI T2,[ASCIZ/FROM PROGRAM/] ;GET NOISE
PUSHJ P,NOISE ;EAT NOISE WORDS
PUSHJ P,CONFRM ;THEN CONFIRM THE COMMAND
HALTF ;QUIT FOR NOW
POPJ P, ;RETURN FOR A NEW COMMAND
;SET THE WIDTH OF THE OUTPUT. THE "WIDTH" COMMAND.
CMDWID: MOVEI T2,[ASCIZ/OF OUTPUT IS/] ;GET NOISE
PUSHJ P,NOISE ;DO NOISE
MOVEI T2,[FLDDB. (.CMKEY,,WIDTAB,,<DEFAULT>)] ;GET READY
PUSHJ P,COMMND ;READ KEYWORD
MOVE T4,(T2) ;GET VALUE
PUSHJ P,CONFRM ;CONFIRM THE LINE
HRRZM T4,WIDTH ;SAVE VALUE
POPJ P, ;AND RETURN
WIDTAB: WIDLEN,,WIDLEN ;NUMBER OF ENTRIES
AA DEFAULT,0 ;DEFAULT
AA NARROW,3 ;NARROW
AA WIDE,7 ;WIDE
WIDLEN==.-WIDTAB-1 ;NUMBER OF ENTRIES
;SET MODE OF OUTPUT, WITH OR WITHOUT THE ADDRESSES BEING TYPED.
;THE "ADDRESS" COMMAND.
CMDADR: MOVEI T2,[ASCIZ/LISTING MODE IS/] ;GET NOISE
PUSHJ P,NOISE ;PARSE IT
MOVEI T2,[FLDDB. (.CMKEY,,ADRTAB,,<ON>)] ;GET READY
PUSHJ P,COMMND ;READ KEYWORD
MOVE T4,(T2) ;SAVE ADDRESS OF INSTRUCTION
PUSHJ P,CONFRM ;COMFIRM THE LINE
XCT (T4) ;TURN FLAG ON OR OFF
POPJ P, ;AND RETURN
ADRTAB: ADRLEN,,ADRLEN ;NUMBER OF ENTRIES
AA OFF,[ANDCMI F,FR.ADR] ;ADDRESS LISTING IS OFF
AA ON,[IORI F,FR.ADR] ;ADDRESS LISTING IS ON
ADRLEN==.-ADRTAB-1 ;NUMBER OF KEYWORDS
;THE "HELP" COMMAND.
CMDHLP: PUSHJ P,CONFRM ;CONFIRM THE LINE
HRROI T1,HLPTXT ;POINT TO HELP MESSAGE
PSOUT ;TYPE IT
POPJ P, ;AND RETURN
HLPTXT: TEXT <
This program can either dump out the addresses of the disk which a
file is using, or dump out the addresses which are marked in the BAT
blocks of a structure. Commands are:
ADDRESS arg Set whether or not to type the addresses of the used
pages, or just plus signs. The arg is one of ON or
OFF. The default is ON.
BAT-BLOCKS str Type out information about the BAT blocks on
the indicated structure. The disk addresses pointed
to by the BAT blocks is also listed.
EXIT Leave the program
FILE spec Process the given file spec, making a list of the
addresses the file is using.
HELP Type this message.
WIDTH arg Set how many addresses to print on a line. The
argument is one of WIDE, NARROW, or DEFAULT.
Notes:
1. WHEEL or OPERATOR capability is required to run this program
as it does DSKOPs to read the index blocks.
2. All disk addresses will seem to be at least as large as the
value 10,,000000. This bit can be ignored, it is simply a
flag meaning that the address is a disk address.
3. Numbers in the output followed by a period are decimal numbers,
all other numbers are octal.
4. Any gaps in the output (such as non-printed sections or page
numbers) indicate that an area exists which has no pages in use.
5. Any asterisks indicate that the indicated page is recorded
in the BAT blocks for that structure.
6. Addresses in the BAT blocks are listed as A,B where A is the
address of the start of a bad region, and B is the number
of consequtive bad blocks.
7. The headers for the BAT block typeout mean the following:
UNIT The logical unit within the structure
BLOCKS The number of blocks found to be bad on the unit
REGIONS The number of regions which are bad. This number is
how many entries are made in the BAT block
COUNT The number of regions which were found bad by the
monitor. This will not include regions originally
found by the mapping program
>
SUBTTL COMMAND TO PRINT OUT ADDRESSES A FILE USES
;THIS COMMAND DOES THE MAIN ACTION. WE READ ALL OF THE
;INDEX BLOCKS OF THE FILE, AND OUTPUT THE DISK ADDRESSES OF
;EACH PAGE OF THE FILE, AND ALSO OF THE INDEX BLOCK.
CMDFIL: MOVEI T2,[ASCIZ/TO PROCESS IS/] ;GET NOISE
PUSHJ P,NOISE ;PARSE IT
MOVX T2,GJ%IFG+GJ%OLD ;GET FLAGS
MOVEM T2,JFNBLK ;AND SAVE THEM IN GTJFN BLOCK
MOVEI T2,[FLDDB. (.CMFIL)] ;SET UP
PUSHJ P,COMMND ;READ FILE SPEC
MOVEM T2,JFN ;SAVE THE JFN
MOVEI T2,[ASCIZ/OUTPUT TO/] ;GET NOISE
PUSHJ P,NOISE ;PARSE IT
MOVEI T2,[FLDDB. (.CMOFI,,,,<TTY:>)] ;GET READY
PUSHJ P,COMMND ;READ OUTPUT SPEC
MOVEM T2,JFNOUT ;AND SAVE OUTPUT JFN
PUSHJ P,CONFRM ;CONFIRM THE LINE
PUSHJ P,SETOUT ;SET UP THE OUTPUT JFN FOR WRITING
SETOM JFNBTS ;INITIALIZE GNJFN BITS
FILLOP: PUSHJ P,DOFILE ;GO PROCESS THIS FILE
MOVE T1,JFN ;GET JFN AND FLAG BITS
GNJFN ;ADVANCE TO NEXT FILE
ERJMP FILDON ;ERROR, GO SEE IF DONE
MOVEM T1,JFNBTS ;SAVE THE GNJFN FLAGS
MOVE T1,JFNOUT ;GET OUTPUT JFN
MOVEI T2,14 ;GET A CONTROL-L
BOUT ;AND OUTPUT IT
JRST FILLOP ;AND GO DO IT
FILDON: CAIE T1,GNJFX1 ;ALL DONE?
JRST LOSE ;NO, HE LOSES
SETZM JFN ;GNJFN CLEARED THE JFN
FILCLS: MOVE T1,JFNOUT ;GET OUTPUT JFN
CLOSF ;CLOSE THE FILE
ERJMP LOSE ;FAILED
SETZM JFNOUT ;CLEAR OUTPUT JFN
HRROI T1,CRLF ;GET READY
PSOUT ;TYPE A CRLF TO SAY WE'RE DONE
POPJ P, ;AND RETURN
SUBTTL ROUTINE TO PROCESS A FILE
;HERE TO PROCESS A PARTICULAR FILE.
DOFILE: PUSHJ P,SETIN ;SET UP TO HANDLE THIS FILE
MOVE T1,JFNBTS ;GET BITS FROM GNJFN
TLNE T1,(GN%STR) ;DID STRUCTURE CHANGE?
PUSHJ P,DOBAT ;YES, INITIALIZE BATS FOR THIS STRUCTURE
TYPE [ASCIZ/
Disk addresses for file /] ;OUTPUT STRING
HRRZ T2,JFN ;GET INPUT JFN
MOVE T3,[1B2+1B5+1B8+1B11+1B14+JS%PAF] ;GET FLAGS
JFNS ;TYPE STRING
TYPE CRLF ;THEN TYPE A CRLF
MOVE T1,FDB+.FBCTL ;GET FLAG BITS FOR THIS FILE
TXNE T1,FB%LNG ;IS IT A LONG FILE?
JRST DOLONG ;YES, GO HANDLE IT
MOVE T1,FDB+.FBADR ;NO, GET INDEX BLOCK ADDRESS
MOVEM T1,PAGSI ;SAVE IN A FAKE SUPER INDEX BLOCK
MOVSI I,-1 ;SET UP AOBJN WORD OF 1
JRST SECLOP ;AND JOIN LOOP FOR LONG FILE
DOLONG: MOVE T1,FDB+.FBADR ;GET ADDRESS OF SUPER INDEX BLOCK
MOVEI A,PAGSI ;AND ADDRESS WHERE IT IS READ TO
PUSHJ P,READ ;READ IT IN
PUSHJ P,SCAN ;GET INFORMATION ABOUT IT
PUSHJ P,CHKSUM ;AND ITS CHECKSUM
MOVE T1,JFNOUT ;GET OUTPUT JFN READY
TYPE [ASCIZ/
Super Index Block address: /] ;TYPE TEXT
OCTOUT FDB+.FBADR ;TYPE ADDRESS
MOVE T1,FDB+.FBADR ;GET ADDRESS AGAIN
SETZ T2, ;WANT NO TYPEOUT UNLESS IN BAT BLOCK
PUSHJ P,BADSRC ;LOOK FOR IT
TYPE [ASCIZ/ Sections used: /] ;TYPE MORE
DECOUT PAGTOT ;OUTPUT TOTAL NUMBER OF SECTIONS
TYPE CRLF ;AND THEN A CRLF
AOSE PAGCHK ;SEE IF HAS A CHECKSUM ERROR
TYPE [ASCIZ/Index block has a checksum error
/] ;YES, SAY SO
AOS ALLPAG ;ADD TO NUMBER OF PAGES TOTAL
MOVSI I,-1000 ;SET UP AOBJN POINTER FOR WHOLE PAGE
;HERE TO LOOP OVER ALL WORDS IN A SUPER INDEX BLOCK, TO READ IN
;AND PROCESS EACH REGULAR INDEX BLOCK.
SECLOP: MOVE T1,PAGSI(I) ;GET NEXT POSSIBLE INDEX BLOCK ADDRESS
AND T1,[STGADR] ;IGNORE CHECKSUM PARTS
JUMPE T1,SECNXT ;IF NONE, JUST GO TO NEXT ONE
MOVEM T1,PAGIDX ;SAVE ADDRESS OF INDEX BLOCK
AOS ALLPAG ;ADD TO TOTAL NUMBER OF PAGES FOR FILE
MOVEI A,PAGI ;POINT TO AREA TO READ IT INTO
PUSHJ P,READ ;READ IT IN
PUSHJ P,SCAN ;GET INFORMATION
PUSHJ P,CHKSUM ;AND CHECKSUM
PUSHJ P,LIST ;THEN OUTPUT INFORMATION ON IT
MOVE T1,PAGTOT ;GET TOTAL PAGES DESCRIBED
ADDM T1,ALLPAG ;ADD TO GRAND TOTAL
ADDM T1,ALLDAT ;AND TO DATA PAGE TOTAL
SECNXT: AOBJN I,SECLOP ;LOOP OVER ALL SECTIONS
;HERE WHEN ALL DONE, TO OUTPUT TOTALS AND CLOSE FILES.
MOVE T1,JFNOUT ;GET READY FOR LAST BIT OF OUTPUT
TYPE [ASCIZ/
Total pages used: /] ;MORE TEXT
DECOUT ALLPAG ;OUTPUT NUMBER OF DATA PAGES
TYPE [ASCIZ/ Data pages: /] ;MORE
DECOUT ALLDAT ;OUTPUT NUMBER OF DATA PAGES
TYPE CRLF ;THEN TYPE A CRLF
SKIPN ALLBAD ;ANY BAD BLOCKS?
POPJ P, ;NO, RETURN
TYPE [ASCIZ/Pages listed in the BAT blocks (marked with "*"): /]
DECOUT ALLBAD ;OUTPUT NUMBER
TYPE CRLF ;ANOTHER CRLF
POPJ P, ;THEN RETURN
SUBTTL ROUTINE TO PRINT OUT THE ADDRESSES OF A PAGE TABLE
;CALLED TO PRINT THE ADDRESSES POINTED TO BY THE INDEX BLOCK WHOSE
;ADDRESS IS IN AC A. ALSO PRINTED IS SOME HEADER INFORMATION OF USE.
LIST: TYPE [ASCIZ/
Section: /] ;TYPE SOME TEXT
MOVEI T3,(I) ;GET SECTION NUMBER READY
OCTOUT T3 ;OUTPUT IT
TYPE [ASCIZ/ Index block address: /] ;MORE TEXT
OCTOUT PAGIDX ;OUTPUT PAGE NUMBER
MOVE T1,PAGIDX ;GET ADDRESS AGAIN
SETZ T2, ;NO OUTPUT IF NOT BAD
PUSHJ P,BADSRC ;LOOK FOR IT IN BAD BLOCKS
TYPE [ASCIZ/ Pages in use: /] ;TYPE MORE
DECOUT PAGTOT ;OUTPUT TOTAL NUMBER OF PAGES
TYPE CRLF ;OUTPUT A CRLF
AOSE PAGCHK ;SEE IF CHECKSUM WAS -1
TYPE [ASCIZ/Index block has a checksum error
/] ;IF NOT, TELL HIM
SKIPGE T2,PAGMIN ;ANY PAGES TO BE TYPED?
POPJ P, ;NO, THEN ARE ALL DONE
;HERE TO ACTUALLY LOOP OVER EACH WORD IN THE INDEX BLOCK:
LISTLP: TDNE T2,PAGMSK ;TIME FOR A NEW LINE?
JRST LISTPG ;NO, JUST GO TYPE THE PAGE NUMBER
TYPE CRLF ;START WITH A CRLF
OCTOUT 3,PAGMIN ;PRINT THE PAGE NUMBER
MOVEI T2,"/" ;GET A SLASH
BOUT ;PRINT THAT
TRNN F,FR.ADR ;TYPING ADDRESSES?
TYPE [ASCIZ/ /] ;NO, THEN SPACE OVER SOME
MOVE T2,PAGMIN ;GET PAGE NUMBER AGAIN
LISTPG: ADDI T2,(A) ;POINT INTO INDEX BLOCK
MOVE T4,(T2) ;GET WORD FROM INDEX BLOCK
AND T4,[STGADR] ;KEEP ONLY THE DISK ADDRESS
JUMPE T4,LISTNO ;JUMP IF THERE IS NO ADDRESS
TRNN F,FR.ADR ;TYPING ADDRESSES?
JRST LISTPL ;NO, GO DO OTHER WAY
OCTOUT ^D11,T4 ;YES, DO SO
MOVE T1,T4 ;GET ADDRESS AGAIN
MOVEI T2," " ;GET A SPACE IN CASE IT ISN'T BAD
PUSHJ P,BADSRC ;LOOK FOR ADDRESS IN BAD BLOCK
JRST LISTDN ;AND CONTINUE
LISTPL: MOVE T1,T4 ;GET ADDRESS OF PAGE
MOVEI T2,"+" ;GET A PLUS IN CASE IT IS GOOD PAGE
PUSHJ P,BADSRC ;LOOK FOR THE PAGE
JRST LISTDN ;AND CONTINUE
LISTNO: TRNE F,FR.ADR ;ARE WE TYPING ADDRESSES?
TYPE [ASCIZ/ -- /] ;YES, TYPE SOME DASHES
MOVEI T2,"-" ;GET A DASH READY
TRNN F,FR.ADR ;NOT GIVING THE ADDRESSES?
BOUT ;YES, THEN OUTPUT IT
LISTDN: AOS T2,PAGMIN ;INCREMENT TO NEXT PAGE
CAMG T2,PAGMAX ;DID ALL WE SHOULD YET?
JRST LISTLP ;NO, GO DO MORE
TYPE CRLF ;FINISH WITH A CRLF
POPJ P, ;RETURN
SUBTTL COMMAND TO PRINT THE BAT BLOCKS
;THIS IS THE COMMAND TO LIST THE BAT BLOCKS. THE ADDRESSES OF EACH
;REGION IS TYPED, ALONG WITH USEFUL STATISTICS.
CMDBAT: MOVEI T2,[ASCIZ/OF STRUCTURE/] ;GET READY
PUSHJ P,NOISE ;READ NOISE
MOVEI T2,[FLDDB. (.CMDEV,,,,<PS>)] ;WANT TO INPUT DEVICE
PUSHJ P,COMMND ;DO IT
MOVEM T2,DEVICE ;SAVE THE DEVICE DESIGNATOR
MOVEI T2,[ASCIZ/LISTED TO FILE/] ;GET READY
PUSHJ P,NOISE ;PARSE IT MORE
MOVEI T2,[FLDDB. (.CMOFI,,,,<TTY:>)] ;GET READY
PUSHJ P,COMMND ;READ OUTPUT SPEC
MOVEM T2,JFNOUT ;SAVE THE OUTPUT JFN
PUSHJ P,CONFRM ;THEN CONFIRM THE LINE
MOVE T1,DEVICE ;GET DEVICE DESIGNATOR
DVCHR ;GET INFORMATION ABOUT IT
ERJMP LOSE ;CAN'T
LDB T1,[POINTR T2,DV%TYP] ;GET DEVICE TYPE
CAIE T1,.DVDSK ;IS IT A DISK?
JRST NOTDSK ;NO, COMPLAIN
HRROI T1,STR ;POINT TO STORAGE
MOVE T2,DEVICE ;GET DEVICE DESIGNATOR
DEVST ;CONVERT IT TO A STRING
ERJMP LOSE ;FAILED
PUSHJ P,SETOUT ;GET OUTPUT FILE READY TO WRITE
PUSHJ P,DOBAT ;READ IN ALL BAT BLOCK INFO
TYPE [ASCIZ/
BAT blocks for structure /] ;TYPE SOME TEXT
TYPE STR ;THEN THE STRUCTURE NAME
TYPE [ASCIZ/:
Units in structure: /] ;MORE
DECOUT PACKS ;OUTPUT IT
TYPE [ASCIZ/
Unit Blocks Regions Count Status
/]
SETZ U, ;GET SET FOR LOOP OVER ALL UNITS
;HERE FOR LOOP OVER ALL UNITS IN A STRUCTURE, LISTING THE INFORMATION
;WE KNOW FOR EACH UNIT.
UNITLP: OCTOUT 2,U ;PRINT THE UNIT NUMBER
DECOUT ^D9,UNITBB(U) ;TYPE THE NUMBER OF BAD BLOCKS
DECOUT ^D8,UNITBR(U) ;AND THE NUMBER OF BAD REGIONS
DECOUT ^D8,UNITCT(U) ;AND NUMBER OF MONITOR ADDED REGIONS
TYPE [ASCIZ/ /] ;THEN SPACE OVER
MOVE T1,UNITFL(U) ;GET THE FLAGS FOR THIS STRUCTURE
PUSHJ P,BATSTS ;TYPE THE STATUS
TYPE CRLF ;THEN A CRLF
ADDI U,1 ;MOVE TO NEXT UNIT
CAMGE U,PACKS ;DONE WITH ALL UNITS YET?
JRST UNITLP ;NO, GO DO NEXT ONE
MOVEI I,DATA ;POINT TO FIRST PAIR OF WORDS
CAML I,BADPTR ;ANY ADDRESSES TO TYPE?
JRST FILCLS ;NO, GO CLOSE FILE AND RETURN
TYPE [ASCIZ/
Addresses marked in the BAT blocks:
/] ;TYPE MORE TEXT
SETOM PAGMIN ;AND INITIALIZE A COUNTER
MOVEI T1,3 ;GET MASK TO BE USED
MOVEM T1,PAGMSK ;SET FOR 4 COLUMNS OF OUTPUT
PARLOP: AOS T1,PAGMIN ;INCREMENT COUNTER
TDNN T1,PAGMSK ;IS IT TIME FOR A NEW LINE?
TYPE CRLF ;YES, DO A CRLF FIRST
MOVX T2,DSKBIT ;GET THE BIT READY
IOR T2,0(I) ;ADD IN THE DISK ADDRESS
OCTOUT ^D12,T2 ;THEN TYPE IT
MOVEI T2,"," ;GET A COMMA
BOUT ;TYPE IT
MOVE T2,1(I) ;GET SECOND ADDRESS
SUB T2,0(I) ;SUBTRACT FIRST ADDRESS
ADDI T2,1 ;ADD ONE TO GET SIZE
MOVE T3,[3,,^D8] ;GET READY FOR OUTPUT IN COLUMN OF 3
NOUT ;DO IT
JFCL ;STUPID ERROR
ADDI I,2 ;MOVE POINTER TO NEXT PAIR
CAMGE I,BADPTR ;STILL MORE TO TYPE?
JRST PARLOP ;YES, LOOP MORE
TYPE CRLF ;FINISH WITH A CRLF
JRST FILCLS ;THEN GO CLOSE FILE AND RETURN
SUBTTL ROUTINE TO SET UP INPUT FILE
;CALLED TO MAKE SURE THAT THE INPUT FILE IS A DISK FILE, AND
;TO OBTAIN THE INFORMATION THAT WE WILL NEED LATER.
SETIN: HRRZ T1,JFN ;GET JFN
DVCHR ;READ STATUS BITS
LDB T1,[POINTR T2,DV%TYP] ;GET DEVICE TYPE
CAIE T1,.DVDSK ;MAKE SURE THIS IS A DISK
JRST NOTDSK ;IF NOT, ERROR
HRRZ T1,JFN ;GET JFN
MOVSI T2,.FBLWR+1 ;GET NUMBER OF FDB WORDS
MOVEI T3,FDB ;POINT TO STORAGE
GTFDB ;READ THE FILE'S FDB
ERJMP LOSE ;CAN'T, THEN BOMB
HRROI T1,STR ;POINT TO STORAGE
HRRZ T2,JFN ;GET JFN OF FILE
MOVE T3,[FLD (.JSAOF,JS%DEV)] ;AND FLAGS
JFNS ;STORE DEVICE NAME
SETZ T2, ;GET READY
IDPB T2,T1 ;MAKE SURE IS ASCIZ
HRROI T1,STR ;POINT TO IT AGAIN
STDEV ;GET THE DEVICE DESIGNATOR
ERJMP LOSE ;FAILED
MOVEM T2,DEVICE ;SAVE IT
SETZM ALLPAG ;CLEAR TOTAL NUMBER OF PAGES
SETZM ALLDAT ;AND TOTAL NUMBER OF DATA PAGES
SETZM ALLBAD ;AND NUMBER OF BAD PAGES
POPJ P, ;THEN RETURN
SUBTTL ROUTINE TO SET UP OUTPUT FILE
;CALLED TO OPEN THE OUTPUT FILE FOR WRITING, AND TO DECIDE ON THE
;NUMBER OF COLUMNS IN THE OUTPUT. IF THERE IS NO JFN YET IN USE,
;THEN WE WILL USE THE DEVICE OF TTY:.
SETOUT: MOVE T1,JFNOUT ;GET OUTPUT JFN READY
MOVX T2,OF%WR+7B5 ;SET UP BYTE SIZE AND WRITE ACCESS
OPENF ;OPEN IT
ERJMP LOSE ;FAILED
MOVEI T1,77 ;GET VALUE READY IN CASE NO ADDRESS MODE
TRNE F,FR.ADR ;WANTS NO ADDRESSES?
SKIPE T1,WIDTH ;OR HE SPECIFIED A WIDTH?
JRST SETWID ;YES, GO STORE IT
MOVE T1,JFNOUT ;GET JFN AGAIN
DVCHR ;READ STATUS OF DEVICE
LDB T1,[POINTR T2,DV%TYP] ;GET DEVICE TYPE
CAIE T1,.DVTTY ;IS IT A TTY?
JRST SETBIG ;NO, THEN USE WIDE FORMAT
MOVE T1,JFNOUT ;GET READY
MOVEI T2,.MORLW ;GET READY TO READ WIDTH
MTOPR ;DO IT
CAIGE T3,^D100 ;IS TERMINAL WIDE ENOUGH?
SKIPA T1,[3] ;NO, THEN USE NARROW FORMAT
SETBIG: MOVEI T1,7 ;OTHERWISE USE WIDE FORMAT
SETWID: MOVEM T1,PAGMSK ;SAVE AS MASK TO USE IN OUTPUT ROUTINE
POPJ P, ;RETURN
SUBTTL LUUO HANDLER
;HERE ON AN LUUO, TO TYPE OUT EITHER A STRING OR A DECIMAL OR OCTAL
;NUMBER. EACH OF THESE FUNCTIONS IS A DIFFERENT LUUO. ALL OUTPUT
;GOES TO THE JFN JFNOUT. ERRORS IN THE NUMBER OUTPUT ARE IGNORED.
LUUO: MOVE X,.JBUUO## ;GET THE UUO
TLNN X,(TYPE) ;IS IT THE TYPE LUUO?
JRST LUUO1 ;NO, GO ON
MOVE T1,JFNOUT ;SET UP OUTPUT JFN
HRROI T2,(X) ;POINT TO THE TEXT
SETZ T3, ;WANT TO OUTPUT ALL OF IT
SOUT ;DO SO
POPJ P, ;THEN RETURN
LUUO1: TLNN X,(OCTOUT) ;WANT TO OUTPUT OCTAL NUMBER?
JRST LUUO2 ;NO, WANTS DECIMAL
MOVE T2,(X) ;GET NUMBER TO TYPE
MOVE T1,JFNOUT ;SET UP OUTPUT JFN
LDB T3,[POINT 4,X,12] ;GET COLUMN WIDTH
MOVSI T3,<(NO%LFL)>(T3) ;PUT IN PROPER PLACE
IORI T3,^D8 ;AND INSERT RADIX
NOUT ;TYPE IT
JFCL ;STUPID ERROR
POPJ P, ;THEN RETURN
LUUO2: MOVE T2,(X) ;GET NUMBER TO TYPE
MOVE T1,JFNOUT ;GET OUTPUT JFN READY
LDB T3,[POINT 4,X,12] ;GET COLUMN WIDTH
MOVSI T3,<(NO%LFL)>(T3) ;PUT IN PROPER PLACE
IORI T3,^D10 ;AND INSERT RADIX
NOUT ;OUTPUT IT
JFCL ;STUPID ERROR
MOVEI T2,"." ;GET A PERIOD
BOUT ;OUTPUT IT TO INDICATE DECIMAL NUMBER
CPOPJ: POPJ P, ;THEN RETURN
CRLF: BYTE (7)15,12 ;CRLF TEXT
SUBTTL ROUTINE TO READ IN AN INDEX BLOCK
;SIMPLE SUBROUTINE TO READ AN INDEX BLOCK INTO THE GIVEN ADDRESS.
;THE DISK ADDRESS OF THE INDEX BLOCK IS IN AC T1, AND THE ADDRESS
;TO WRITE THE DATA IS IN AC A. NO RETURN IF AN ERROR ENCOUNTERED.
READ: AND T1,[DOP%RA] ;CLEAR NON-ADDRESS PART
IOR T1,[<FLD (.DOPSR,DOP%AT)>!DOP%SN] ;SET UP REST
MOVEI T3,(A) ;MOVE ADDRESS TO RIGHT AC
MOVEI T2,1000 ;READ IN A WHOLE PAGE, NO FLAGS SET
MOVE T4,DEVICE ;GET DEVICE DESIGNATOR
DSKOP ;READ THE PAGE
ERJMP LOSE ;CAN'T DO IT
POPJ P, ;ALL DONE
SUBTTL ROUTINE TO SCAN INDEX BLOCK TO FIND OUT INFORMATION
;THIS ROUTINE IS CALLED TO OBTAIN THE FIRST AND LAST PAGE NUMBER
;TO BE PRINTED FOR THIS INDEX BLOCK. ALSO OBTAINED IS THE NUMBER
;OF PAGES WHICH ARE USED ACCORDING TO THE INDEX BLOCK. ADDRESS
;OF THE INDEX BLOCK IS IN AC A.
SCAN: SETZM PAGTOT ;CLEAR NUMBER OF PAGES USED
SETOM PAGMIN ;AND INITIALIZE MINIMUM PAGE NUMBER
MOVSI T1,-1000 ;WANT TO SCAN WHOLE PAGE
HRLI A,T1 ;SET UP FOR INDIRECT ADDRESS
MOVE T2,[STGADR] ;GET MASK READY
SCANLP: TDNN T2,@A ;IS THIS PAGE USED?
JRST SCANNX ;NO, GO ON
HRRZM T1,PAGMAX ;YES, SAVE AS HIGHEST PAGE SO FAR
SKIPGE PAGMIN ;ALREADY FOUND LOWEST PAGE?
HRRZM T1,PAGMIN ;NO, THEN SAVE IT
AOS PAGTOT ;BUMP NUMBER OF PAGES TOTAL
SCANNX: AOBJN T1,SCANLP ;LOOP OVER ALL PAGES
MOVE T1,PAGMSK ;GET MASK USED FOR THIS WIDTH
ANDCAM T1,PAGMIN ;ROUND FIRST PAGE DOWN TO NICE VALUE
IORM T1,PAGMAX ;ROUND LAST PAGE UP TO NICE VALUE TOO
POPJ P, ;THEN RETURN
SUBTTL ROUTINE TO CHECKSUM AN INDEX BLOCK
;ROUTINE TO COMPUTE THE CHECKSUM OF AN INDEX BLOCK. THE ADDRESS IN
;OUR CORE OF THE INDEX BLOCK IS SUPPLIED IN AC A. AN INDEX BLOCK
;CONTAINS THE CHECKSUM IN THE FIRST 9 BITS OF THE FIRST 4 WORDS.
;THE RIGHT 24 BITS OF EACH WORD IS THE DISK ADDRESS FOR THAT PAGE.
;ANY REMAINING BITS ARE NOT USED, AND DO NOT TAKE PART IN THE CHECKSUM.
;A GOOD CHECKSUM HAS THE VALUE OF -1. THE COMPUTED CHECKSUM IS
;SAVED IN LOCATION PAGCHK.
CHKSUM: MOVSI T2,-4 ;GET READY FOR A LOOP
HRRI T2,(A) ;OVER THE FIRST FOUR WORDS
MOVE T3,[POINT 9,T1] ;POINT TO PLACE CHECKSUM WILL GO
CHKGET: LDB T4,[POINT 9,(T2),8] ;GET A BYTE OF THE CHECKSUM
IDPB T4,T3 ;STORE IT
AOBJN T2,CHKGET ;DO FOR ALL FOUR WORDS
SETCA T1, ;COMPLEMENT THE CHECKSUM
JCRY0 .+1 ;CLEAR CARRY FLAG
MOVSI T2,-1000 ;GET READY TO LOOP OVER WHOLE PAGE
HRLI A,T2 ;SETUP INDEX FIELD
CHKWRD: MOVE T3,@A ;GET NEXT WORD OF PAGE
AND T3,[EXP STGADR] ;KEEP ONLY THE DISK ADDRESS PART
SKIPN T3 ;IS THERE ANY ADDRESS?
MOVEI T3,(T2) ;NO, THEN USE THE OFFSET INTO THE PAGE
ADD T1,T3 ;ADD RESULT INTO CHECKSUM
JCRY0 [AOJA T1,.+1] ;IF OVERFLOW, WRAP AROUND
AOBJN T2,CHKWRD ;LOOP OVER ALL WORDS IN THE PAGE
MOVEM T1,PAGCHK ;SAVE THE CHECKSUM FOR LATER
POPJ P, ;RETURN
SUBTTL ROUTINE TO COLLECT ALL DATA ON BAD BLOCKS
;THIS ROUTINE DOES ALL GOOD THINGS TO COLLECT A LIST OF THE BAD
;BLOCKS OF A STRUCTURE. IT ALSO COLLECTS THE INFORMATION FOR
;EACH UNIT IN A STRUCTURE. BEFORE CALLING, PUT THE ASCIZ STRUCTURE
;NAME IN LOCATION STR. RETURNS WILL ALL DATA GOTTEN, READY TO
;SEARCH FOR BAD BLOCKS.
DOBAT: PUSHJ P,STRFND ;LOOK FOR ALL UNITS IN STRUCTURE
MOVEI T1,DATA ;POINT TO STORAGE
MOVEM T1,BADPTR ;AND INITIALIZE POINTER
SETZ U, ;GET SET FOR LOOP THROUGH ALL UNITS
DOBATL: PUSHJ P,GETBAT ;READ IN BOTH BATS FOR UNIT
SKIPA ;BOTH WERE BAD, SKIP NEXT STEP
PUSHJ P,SAVBAD ;GET BAD BLOCKS SAVED IN CORE
MOVE T1,BAT+BT.CNT ;GET COUND OF REGIONS MONITOR FOUND
MOVEM T1,UNITCT(U) ;SAVE FOR LATER
MOVEM F,UNITFL(U) ;SAVE FLAGS FOR LATER TOO
MOVE T1,UNITSZ(U) ;GET SIZE OF THIS UNIT
ADDM T1,UNITOF ;ADD TO OFFSET IN ADDRESSES
ADDI U,1 ;MOVE UP A UNIT
CAMGE U,PACKS ;LOOKED AT ALL UNITS YET?
JRST DOBATL ;NO, KEEP LOOPING
POPJ P, ;ALL DONE, RETURN
SUBTTL ROUTINE TO SEARCH FOR A BAD BLOCK
;THIS ROUTINE IS CALLED WITH THE ADDRESS OF A BLOCK IN T1, AND
;A CHARACTER TO BE OUTPUT (NULL IF NONE) IN T2. THE ADDRESS
;GIVEN IS SEARCHED TO SEE IF IT IS LISTED IN THE BAT BLOCKS.
;IF NOT, THE GIVEN CHARACTER IS OUTPUT. IF SO, AN ASTERISK IS
;OUTPUT AND THE COUNT ALLBAD IS BUMPED ONE.
BADSRC: TLZ T1,(DSKBIT) ;CLEAR BIT WHICH MIGHT CONFUSE US
SKIPA T3,[EXP DATA] ;START SEARCH AT TOP
SRCLOP: ADDI T3,2 ;MOVE TO NEXT PAIR OF WORDS
CAML T3,BADPTR ;RAN OUT OF BAD PAIRS?
JRST SRCOK ;YES, NOT A BAD BLOCK THEN
CAML T1,0(T3) ;LESS THAN FIRST OF PAIR?
CAMLE T1,1(T3) ;OR GREATER THAN SECOND OF PAIR?
JRST SRCLOP ;YES, NOT INCLUDED IN THIS PAIR
AOS ALLBAD ;IS A BAD BLOCK, INCREMENT COUNT
MOVEI T2,"*" ;CHANGE CHAR TO AN ASTERISK
SRCOK: MOVE T1,JFNOUT ;GET OUTPUT JFN READY
SKIPE T2 ;SOMETHING TO OUTPUT?
BOUT ;YES, DO IT
POPJ P, ;THEN RETURN
SUBTTL ROUTINE TO SAVE BAD BLOCKS IN CORE
;CALLED AFTER HAVING READ IN A BAT BLOCK, TO INTERPRET THE PAIRS OF
;WORDS IN THE BAT BLOCK, AND TO REMEMBER THE ADDRESSES OF THE BAD
;BLOCKS SO THEY CAN BE EASILY SEARCHED LATER. THE PAIRS OF WORDS
;WE REMEMBER ARE STORE AT LOCATION POINTED TO BY BADPTR. CALLED
;AFTER HAVING READ A BAT BLOCK INTO LOCATION BAT.
SAVBAD: LDB T1,[POINTR BAT+BT.MAP,BT%NBR] ;GET MAPPED REGIONS
ADD T1,BAT+BT.CNT ;ADD REGIONS MONITOR FOUND
JUMPE T1,CPOPJ ;IF NONE, NO ERRORS SO RETURN
CAILE T1,<200-BT$HDR>/2 ;OVERFLOWED?
MOVEI T1,<200-BT$HDR>/2 ;YES, MAKE MAXIMUM
MOVNI T1,(T1) ;MAKE NEGATIVE
MOVSI T1,(T1) ;AND MAKE INTO AOBJN POINTER
HRR T1,BAT+BT.ADR ;GET ADDRESS OF FIRST PAIR
ADDI T1,BAT ;RELOCATE TO DATA IN CORE
MOVX T4,BT%NEW ;GET BIT READY FOR USE
SAVLOP: MOVE T2,1(T1) ;GET ADDRESS OF A REGION
ANDX T2,BT%ADR ;ONLY KEEP THE ADDRESS
TDNN T4,0(T1) ;IS THIS OLD STYLE FORMAT?
ANDX T2,BT%AD2 ;YES, ADDRESS FIELD IS SMALLER
ADD T2,UNITOF ;OFFSET ADDRESS BY PRECEEDING UNITS
MOVEM T2,@BADPTR ;SAVE THE FIRST ADDRESS
AOS BADPTR ;THEN INCREMENT POINTER
LDB T3,[POINTR <(T1)>,BT%CNT] ;GET COUNT-1 OF BAD BLOCKS
ADD T2,T3 ;PRODUCE LAST BLOCK IN THE REGION
MOVEM T2,@BADPTR ;AND SAVE IT TOO
AOS BADPTR ;INCREMENT POINTER AGAIN
ADDI T3,1 ;MAKE NUMBER OF BAD BLOCKS
ADDM T3,UNITBB(U) ;ADD TO TOTAL NUMBER OF BAD BLOCKS
AOS UNITBR(U) ;AND INCREMENT NUMBER OF BAD REGIONS
ADDI T1,1 ;INCREMENT ADDRESS BY 1
AOBJN T1,SAVLOP ;AND CONTINUE WITH NEXT PAIR
POPJ P, ;ALL DONE
SUBTTL ROUTINE TO FIND ALL UNITS OF A STRUCTURE
;THIS ROUTINE IS CALLED TO COLLECT ALL THE INFORMATION NEEDED
;TO PROCESS EACH UNIT IN A STRUCTURE. THE STRUCTURE NAME TO
;BE PROCESSED IS IN THE ADDRESS STR. DATA IS RETURNED IN
;VARIOUS TABLES, AND THE CONSISTANCY OF THE STRUCTURE IS CHECKED.
STRFND: MOVE T1,[ZERUNT,,ZERUNT+1] ;GET READY FOR BIG BLT
SETZM ZERUNT ;TO CLEAR ALL UNIT DATA
BLT T1,ZEREND ;DO IT
SETOM MBLK+.MSRCH ;INITIALIZE MSTR BLOCK
SETOM MBLK+.MSRCT ;BY SETTING ONES TO UNITS
SETOM MBLK+.MSRUN ;CHANNELS AND CONTROLLERS
;HERE TO LOOK AT NEXT UNIT IN THE SYSTEM. IF IT BELONGS TO THE
;DESIRED STRUCTURE, ADD IT TO OUR KNOWLEDGE.
STRNXT: HRROI T1,UNITNM ;GET POINTER TO NAME
MOVEM T1,MBLK+.MSRSA ;AND SAVE IT
SETZM UNITNM ;CLEAR NAME IN CASE NOT UPDATED
SETZM MBLK+.MSRSN ;CLEAR PHYSICAL NAME POINTER
MOVX T1,<.MSRBT+1,,.MSRNU> ;CODE FOR STATUS
MOVEI T2,MBLK ;PLACE TO STORE IT
MSTR ;READ INFO ON NEXT UNIT
ERJMP STRFIN ;ERROR, GO FINISH
MOVE T1,MBLK+.MSRST ;GET STATUS BITS FOR THIS DRIVE
TXNE T1,MS%MNT ;MAKE SURE IT IS IN A STRUCTURE
TXNE T1,MS%OFL ;AND THAT IT IS ON-LINE
JRST STRNXT ;NO, THEN DON'T LOOK AT IT
MOVE T1,[POINT 7,UNITNM] ;GET POINTER TO UNIT ALIAS NAME
MOVE T2,[POINT 7,STR] ;AND DESIRED STRUCTURE
STRCMP: ILDB T3,T1 ;GET NEXT CHAR OF STR UNIT IT IN
ILDB T4,T2 ;AND NEXT CHAR OF WANTED STR
CAME T3,T4 ;DO THEY MATCH?
JRST STRNXT ;NO, DON'T WANT THIS DRIVE
JUMPN T3,STRCMP ;LOOP OVER ALL OF THE NAME
HLRZ T1,MBLK+.MSRNS ;GET LOGICAL UNIT NUMBER
CAIL T1,MXUNIT ;MAKE SURE NOT TOO BIG
ERROR Logical unit number too large for tables
SKIPE UNITSZ(T1) ;MAKE SURE DON'T DUPLICATE ENTRIES
ERROR Duplicate logical unit found in structure
HRRZ T2,MBLK+.MSRNS ;GET NUMBER OF PACKS
SKIPE PACKS ;IGNORE CHECK IF FIRST PACK
CAMN T2,PACKS ;SAME NUMBER OF PACKS AS LAST ONE?
SKIPN T2 ;AND TOTAL PACKS AT LEAST 1?
ERROR Units don't agree in number of packs in structure
MOVEM T2,PACKS ;ALL OK, SAVE NUMBER OF PACKS
MOVE T2,MBLK+.MSRCH ;GET CHANNEL NUMBER
MOVEM T2,UNITCH(T1) ;REMEMBER IT
MOVE T2,MBLK+.MSRUN ;GET UNIT NUMBER
MOVEM T2,UNITUN(T1) ;REMEMBER IT TOO
SKIPN T2,MBLK+.MSRSU ;GET NUMBER OF BLOCKS (SECTORS)
ERROR Unit found with zero sectors
MOVEM T2,UNITSZ(T1) ;SAVE IT TOO
JRST STRNXT ;AND LOOK FOR NEXT UNIT
STRFIN: MOVEI T1,.FHSLF ;GET READY
GETER ;GET THE MOST RECENT ERROR
MOVEI T1,(T2) ;KEEP ONLY THE ERROR HALF
CAIE T1,MSTX18 ;FAIL BECAUSE NO MORE UNITS?
JRST LOSE ;NO, OTHER ERROR.
SKIPN PACKS ;SEE IF ANY PACKS FOUND
ERROR No units found for structure
MOVSI T1,-MXUNIT ;GET READY FOR LOOP OVER ALL UNITS
STRCNT: SKIPE UNITSZ(T1) ;SEE IF WE FOUND THIS LOGICAL UNIT
AOBJN T1,.-1 ;YES, KEEP LOOKING
MOVEI T1,(T1) ;KEEP NUMBER OF UNITS FOUND
CAME T1,PACKS ;FOUND ALL OF THE UNITS?
ERROR Structure is missing some units
POPJ P, ;ALL DONE, RETURN
SUBTTL ROUTINE TO READ IN THE BAT BLOCKS FOR A UNIT
;CALLED WITH THE LOGICAL UNIT NUMBER IN AC U, TO READ BOTH OF
;THE BAT BLOCKS INTO CORE AND VERIFY THAT THEY ARE OK. STATUS OF THE
;UNIT'S BAT BLOCKS RETURNED IN F. SKIP RETURN TAKEN IF AT LEAST ONE
;BAT BLOCK IS GOOD, WITH IT IN LOCATION BAT. NONSKIP RETURN
;TAKEN IF BOTH BATS ARE BAD.
GETBAT: ANDCMI F,FR.BB1+FR.BB2+FR.BBI ;ASSUME BOTH BATS ARE OK
MOVEI T1,BATAD1 ;GET ADDRESS OF PRIMARY BAT
MOVEI T2,BAT ;AND ADDRESS WHERE TO READ IT TO
PUSHJ P,REDBAT ;READ IT IN AND VERIFY IT
IORI F,FR.BB1 ;IS WRONG, REMEMBER THAT
MOVEI T1,BATAD2 ;GET ADDRESS OF SECONDARY BAT BLOCK
MOVEI T2,BAT2 ;AND ADDRESS TO READ IT INTO
PUSHJ P,REDBAT ;READ IT TOO
IORI F,FR.BB2 ;ERROR, REMEMBER IT
XORI F,FR.BB1+FR.BB2 ;COMPLEMENT BITS FOR TEST
TRCN F,FR.BB1+FR.BB2 ;FIX BITS AND SEE IF BOTH ARE BAD
JRST BATZER ;YES, GO ZERO IT
AOS (P) ;AT LEAST ONE IS GOOD, SET FOR SKIP
TRNE F,FR.BB2 ;IS SECOND BAT BLOCK BAD?
POPJ P, ;YES, JUST RETURN
TRNE F,FR.BB1 ;IS FIRST BAT BLOCK BAD?
JRST BATCPY ;YES, COPY GOOD ONE INTO FIRST ONE
MOVSI T1,-177 ;BOTH ARE GOOD, GET READY FOR LOOP
MOVE T2,BAT(T1) ;GET A WORD OF FIRST BAT BLOCK
CAMN T2,BAT2(T1) ;MATCH OTHER ONE?
AOBJN T1,.-2 ;YES, KEEP LOOKING
SKIPGE T1 ;ALL WORDS MATCH?
IORI F,FR.BBI ;NO, REMEMBER THAT THEY DIFFER
POPJ P, ;AND RETURN
BATZER: SETZM BAT ;BOTH ARE BAD, GET READY
SKIPA T1,[BAT,,BAT+1] ;TO ZERO THE JUNK
BATCPY: MOVE T1,[BAT2,,BAT] ;GET SET TO COPY FROM GOOD BLOCK
BLT T1,BAT+177 ;DO THE WORK
POPJ P, ;THEN RETURN
SUBTTL ROUTINE TO READ IN A BAT BLOCK
;THIS ROUTINE TAKES THE BLOCK NUMBER OF A BAD BLOCK IN AC T1,
;AND THE ADDRESS IN CORE TO READ IT INTO IN AC T2, THE UNIT NUMBER
;OF THE DISK IN AC U. SKIP RETURN TAKEN IF THE READ BAT LOOKS
;OK, ERROR RETURN TAKEN IF IT IS BAD.
REDBAT: ANDX T1,DOP%UA ;KEEP ONLY THE ADDRESS
MOVE T4,T1 ;AND SAVE IT FOR LATER
TXO T1,<FLD .DOPPU,DOP%AT> ;PUT IN CODE FOR UNIT ADDRESSING
MOVE T3,UNITCH(U) ;GET CHANNEL NUMBER
DPB T3,[POINTR (T1,DOP%CN)] ;STORE IT
MOVE T3,UNITUN(U) ;GET UNIT NUMBER
DPB T3,[POINTR (T1,DOP%UN)] ;STORE IT TOO
MOVEI T3,(T2) ;POINT TO PLACE TO READ TO
MOVEI T2,200 ;WANT TO READ 1 BLOCK
DSKOP ;DO IT
ERJMP LOSE ;BETTER NOT FAIL
MOVS T1,BT.NAM(T3) ;GET NAME OF THE BAT BLOCK
CAIN T1,'BAT' ;IS IT AS IT SHOULD BE?
CAME T4,BT.BLK(T3) ;AND IS THE BLOCK NUMBER CORRECT?
POPJ P, ;NO, ERROR
MOVE T1,BT.COD(T3) ;GET THE SPECIAL CODE VALUE
HRRZ T2,BT.ADR(T3) ;AND ADDRESS OF FIRST PAIR OF WORDS
CAIN T1,BT$COD ;IS THE CODE CORRECT?
CAIL T2,200 ;AND THE ADDRESS REASONABLE?
POPJ P, ;NO, RETURN
HLRE T1,BT.ADR(T3) ;GET NUMBER OF FREE WORDS
MOVN T1,T1 ;MAKE POSITIVE
SKIPL T1 ;MAKE SURE IT IS REASONABLE
CAILE T1,200 ;IS IT?
POPJ P, ;NO, ERROR
AOS (P) ;BLOCK LOOKS OK, SET FOR SKIP
POPJ P, ;RETURN
SUBTTL ROUTINE TO TYPE STATUS OF THE BAT BLOCKS
;THIS ROUTINE IS USED TO LOOK AT THE STATUS BITS WE FOUND OUT ABOUT
;THE UNIT, AND TO GIVE A SHORT DESCRIPTION OF THE CONDITION OF THE
;BAT BLOCKS. CALLED WITH THE FLAGS WE COMPUTED IN AC T1.
BATSTS: MOVEI T2,[ASCIZ/Both BAT blocks are correct/] ;GET DEFAULT
TRNE T1,FR.BBI ;ARE THEY INCONSISTANT?
MOVEI T2,[ASCIZ/BAT blocks differ from each other/]
TRNE T1,FR.BB1 ;IS FIRST BAT BLOCK BAD?
MOVEI T2,[ASCIZ/Primary BAT block is bad/]
TRNE T1,FR.BB2 ;IS SECONDARY BAT BLOCK BAD?
MOVEI T2,[ASCIZ/Secondary BAT block is bad/]
XORI T1,FR.BB1+FR.BB2 ;GET READY
TRCN T1,FR.BB1+FR.BB2 ;BOTH BAD?
MOVEI T2,[ASCIZ/Both BAT blocks are bad/]
TYPE (T2) ;OUTPUT CORRECT STATUS MESSAGE
POPJ P, ;AND RETURN
SUBTTL ERROR HANDLING ROUTINE
;HERE ON ANY ERROR AT ALL. WE CLOSE UP THE FILES IF THEY WERE
;OPEN, AND RESTART THE PROGRAM.
LOSE: HRROI T1,[ASCIZ/
? /] ;GET PRELIMINARY TEXT
PSOUT ;TYPE IT
MOVEI T1,.PRIOU ;OUTPUT TO TERMINAL
HRLOI T2,.FHSLF ;LAST ERROR IN THIS FORK
SETZ T3, ;ALL OF THE TEXT
ERSTR ;PRINT THE ERROR
JFCL ;FAILED
JFCL ;FAILED
LOSFIN: HRROI T1,[ASCIZ/
/] ;GET FINAL STRING
PSOUT ;TYPE IT TOO
MOVEI T1,.PRIIN ;GET READY
CFIBF ;CLEAR INPUT BUFFER
JRST REEN ;AND START OVER
NOTDSK: HRROI T1,[ASCIZ/
? Device must be a disk/] ;GET STRING
PSOUT ;TYPE IT
JRST LOSFIN ;AND JOIN OTHER CODE
NOPOWR: HRROI T1,[ASCIZ/
? This program can not run without WHEEL or OPERATOR capabilities
/] ;GET STRING
PSOUT ;OUTPUT IT
HALTF ;QUIT
JRST .-1 ;AND STAY THAT WAY
SUBTTL COMMAND JSYS SUBROUTINES
;ANY ERROR IN THESE ROUTINES RESTARTS THE PROGRAM.
;POINTER TO THE COMMAND BLOCK IS IN AC T1.
NOISE: HRROM T2,NOIBLK+.CMDAT ;SAVE AS DATA
MOVEI T2,NOIBLK ;POINT TO BLOCK
JRST COMMND ;AND GO DO COMND JSYS
CONFRM: MOVEI T2,[FLDDB. (.CMCFM)] ;GET CONFIRM FUNCTION
COMMND: COMND ;PARSE THE FUNCTION
ERJMP LOSE ;ERROR, GO COMPLAIN
TXNE T1,CM%NOP ;DID IT PARSE?
JRST LOSE ;NO, COMPLAIN
POPJ P, ;YES, RETURN SUCCESSFULLY
NOIBLK: FLDDB. (.CMNOI) ;BLOCK FOR NOISE FUNCTION
SUBTTL THE DATA AREA
CMDBLK: 0,,NEWPAR ;ADDRESS OF REPARSE ROUTINE
.PRIIN,,.PRIOU ;INPUT,,OUTPUT JFNS
-1,,[ASCIZ/FILADR>/] ;CONTROL-R POINTER
-1,,TXTBUF ;POINTER TO TEXT BUFFER
-1,,TXTBUF ;POINTER TO CURRENT POSITION
TXTLEN ;NUMBER OF CHARS IN BUFFER
0 ;NUMBER OF UNPARSED CHARACTERS
-1,,ATMBUF ;POINTER TO ATOM BUFFER
TXTLEN ;NUMBER OF CHARACTERS IN BUFFER
EXP JFNBLK ;POINTER TO GTJFN BLOCK
JFNBLK: GJ%OLD ;FLAGS,,GENERATION NUMBER
.PRIIN,,.PRIOU ;INPUT,,OUTPUT JFNS
BLOCK 20 ;NO DEFAULTS
XLIST ;DUMP THE LITERALS
LIT
LIST
PDL: BLOCK PDLSIZ ;STACK ROOM
PAGMSK: BLOCK 1 ;MASK USED TO KNOW WHEN TO DO A CRLF
PAGCHK: BLOCK 1 ;CHECKSUM FOR AN INDEX BLOCK
PAGTOT: BLOCK 1 ;NUMBER OF PAGES AN INDEX BLOCK REPRESENTS
PAGIDX: BLOCK 1 ;ADDRESS ON DISK OF INDEX BLOCK
ALLPAG: BLOCK 1 ;TOTAL NUMBER OF PAGES USED IN FILE
ALLDAT: BLOCK 1 ;TOTAL NUMBER OF DATA PAGES IN FILE
ALLBAD: BLOCK 1 ;NUMBER OF BAD PAGES IN A FILE
PAGMIN: BLOCK 1 ;FIRST PAGE TO BE LISTED FOR AN INDEX BLOCK
PAGMAX: BLOCK 1 ;LAST PAGE TO BE LISTED
BADPTR: BLOCK 1 ;POINTER TO THE BAD BLOCK ADDRESSES
ZERUNT==. ;FIRST LOCATION TO ZERO
UNITOF: BLOCK 1 ;ADDRESS OF START OF A UNIT
PACKS: BLOCK 1 ;NUMBER OF PACKS IN A STRUCTURE
MBLK: BLOCK .MSRBT+1 ;STORAGE FOR MSTR JSYS
UNITBB: BLOCK MXUNIT ;NUMBER OF BAD BLOCKS FOUND IN A UNIT
UNITBR: BLOCK MXUNIT ;NUMBER OF BAD REGIONS FOUND IN A UNIT
UNITSZ: BLOCK MXUNIT ;NUMBER OF BLOCKS IN EACH UNIT
UNITCH: BLOCK MXUNIT ;CHANNEL NUMBER UNITS ARE ON
UNITUN: BLOCK MXUNIT ;UNIT NUMBER ON CHANNEL UNIT IS ON
UNITFL: BLOCK MXUNIT ;FLAGS CONCERNING BAT BLOCK
UNITCT: BLOCK MXUNIT ;NUMBER OF MONITOR ADDED PAIRS TO BATS
ZEREND==.-1 ;LAST LOCATION TO ZERO
WIDTH: BLOCK 1 ;THE WIDTH THAT WAS SPECIFIED
FDB: BLOCK .FBLWR+1 ;STORAGE FOR FILE'S FDB
JFN: BLOCK 1 ;JFN OF FILE WE ARE READING
JFNOUT: BLOCK 1 ;OUTPUT JFN
JFNBTS: BLOCK 1 ;BITS RETURNED BY GNJFN
DEVICE: BLOCK 1 ;DEVICE DESIGNATOR FOR A STRUCTURE
STR: BLOCK 10 ;ASCIZ STRING FOR STRUCTURE NAME
UNITNM: BLOCK 10 ;ASCIZ STRING FOR UNIT'S STRUCTURE
SAVEP: BLOCK 1 ;STORAGE OF STACK
TXTBUF: BLOCK TXTLEN/5+1 ;BUFFER FOR COMMAND JSYS
ATMBUF: BLOCK TXTLEN/5+1 ;BUFFER FOR ATOM BUFFER
END START